diff --git a/builtin/logical/transit/path_keys.go b/builtin/logical/transit/path_keys.go index 8e453ed4eb8..5a3db548e82 100644 --- a/builtin/logical/transit/path_keys.go +++ b/builtin/logical/transit/path_keys.go @@ -61,7 +61,7 @@ func (b *backend) pathKeys() *framework.Path { Description: ` The type of key to create. Currently, "aes128-gcm96" (symmetric), "aes256-gcm96" (symmetric), "ecdsa-p256" (asymmetric), "ecdsa-p384" (asymmetric), "ecdsa-p521" (asymmetric), "ed25519" (asymmetric), "rsa-2048" (asymmetric), "rsa-3072" -(asymmetric), "rsa-4096" (asymmetric), "ml-dsa" (asymmetric) are supported. Defaults to "aes256-gcm96". +(asymmetric), "rsa-4096" (asymmetric), "ml-dsa" (asymmetric), "slh-dsa" (asymmetric) are supported. Defaults to "aes256-gcm96". `, }, @@ -134,7 +134,8 @@ key.`, "parameter_set": { Type: framework.TypeString, Description: `The parameter set to use. Applies to ML-DSA and SLH-DSA key types. -For ML-DSA key types, valid values are 44, 65, or 87.`, +For ML-DSA key types, valid values are 44, 65, or 87. +For SLH-DSA key types, valid values are SLH-DSA-SHA2-128s, SLH-DSA-SHAKE-128s, SLH-DSA-SHA2-128f, SLH-DSA-SHAKE-128f, SLH-DSA-SHA2-192s, SLH-DSA-SHAKE-192s, SLH-DSA-SHA2-192f, SLH-DSA-SHAKE-192f, SLH-DSA-SHA2-256s, SLH-DSA-SHAKE-256s, SLH-DSA-SHA2-256f, SLH-DSA-SHAKE-256f`, }, "hybrid_key_type_pqc": { Type: framework.TypeString, @@ -277,6 +278,27 @@ func (b *backend) pathPolicyWrite(ctx context.Context, req *logical.Request, d * } polReq.ParameterSet = parameterSet + + case "slh-dsa": + polReq.KeyType = keysutil.KeyType_SLH_DSA + parameterSet = strings.ToLower(parameterSet) + switch parameterSet { + case keysutil.ParameterSet_SLH_DSA_SHA2_128S, + keysutil.ParameterSet_SLH_DSA_SHAKE_128S, + keysutil.ParameterSet_SLH_DSA_SHA2_128F, + keysutil.ParameterSet_SLH_DSA_SHAKE_128F, + keysutil.ParameterSet_SLH_DSA_SHA2_192S, + keysutil.ParameterSet_SLH_DSA_SHAKE_192S, + keysutil.ParameterSet_SLH_DSA_SHA2_192F, + keysutil.ParameterSet_SLH_DSA_SHAKE_192F, + keysutil.ParameterSet_SLH_DSA_SHA2_256S, + keysutil.ParameterSet_SLH_DSA_SHAKE_256S, + keysutil.ParameterSet_SLH_DSA_SHA2_256F, + keysutil.ParameterSet_SLH_DSA_SHAKE_256F: + polReq.ParameterSet = parameterSet + default: + return logical.ErrorResponse(fmt.Sprintf("invalid parameter set %s for key type %s", parameterSet, keyType)), logical.ErrInvalidRequest + } default: return logical.ErrorResponse(fmt.Sprintf("unknown key type %v", keyType)), logical.ErrInvalidRequest } @@ -442,7 +464,7 @@ func (b *backend) formatKeyPolicy(p *keysutil.Policy, context []byte) (*logical. } resp.Data["keys"] = retKeys - case keysutil.KeyType_ECDSA_P256, keysutil.KeyType_ECDSA_P384, keysutil.KeyType_ECDSA_P521, keysutil.KeyType_ED25519, keysutil.KeyType_RSA2048, keysutil.KeyType_RSA3072, keysutil.KeyType_RSA4096, keysutil.KeyType_ML_DSA, keysutil.KeyType_HYBRID: + case keysutil.KeyType_ECDSA_P256, keysutil.KeyType_ECDSA_P384, keysutil.KeyType_ECDSA_P521, keysutil.KeyType_ED25519, keysutil.KeyType_RSA2048, keysutil.KeyType_RSA3072, keysutil.KeyType_RSA4096, keysutil.KeyType_ML_DSA, keysutil.KeyType_HYBRID, keysutil.KeyType_SLH_DSA: retKeys := map[string]map[string]interface{}{} for k, v := range p.Keys { key := asymKey{ diff --git a/builtin/logical/transit/path_keys_test.go b/builtin/logical/transit/path_keys_test.go index 7858661b2cd..6ef87c6ba64 100644 --- a/builtin/logical/transit/path_keys_test.go +++ b/builtin/logical/transit/path_keys_test.go @@ -16,6 +16,7 @@ import ( "github.com/hashicorp/vault/builtin/logical/transit" "github.com/hashicorp/vault/helper/constants" vaulthttp "github.com/hashicorp/vault/http" + "github.com/hashicorp/vault/sdk/helper/keysutil" "github.com/hashicorp/vault/sdk/logical" "github.com/hashicorp/vault/vault" ) @@ -294,6 +295,54 @@ func TestTransit_CreateKey(t *testing.T) { creationParams: map[string]interface{}{"type": "hybrid", "parameter_set": "87", "hybrid_key_type_ec": "ecdsa-p521", "hybrid_key_type_pqc": "ml-dsa"}, entOnly: true, }, + "SLH-DSA-SHA2-128s": { + creationParams: map[string]interface{}{"type": "slh-dsa", "parameter_set": keysutil.ParameterSet_SLH_DSA_SHA2_128S}, + entOnly: true, + }, + "SLH-DSA-SHAKE-128s": { + creationParams: map[string]interface{}{"type": "slh-dsa", "parameter_set": keysutil.ParameterSet_SLH_DSA_SHAKE_128S}, + entOnly: true, + }, + "SLH-DSA-SHA2-128f": { + creationParams: map[string]interface{}{"type": "slh-dsa", "parameter_set": keysutil.ParameterSet_SLH_DSA_SHA2_128F}, + entOnly: true, + }, + "SLH-DSA-SHAKE-128f": { + creationParams: map[string]interface{}{"type": "slh-dsa", "parameter_set": keysutil.ParameterSet_SLH_DSA_SHAKE_128F}, + entOnly: true, + }, + "SLH-DSA-SHA2-192s": { + creationParams: map[string]interface{}{"type": "slh-dsa", "parameter_set": keysutil.ParameterSet_SLH_DSA_SHA2_192S}, + entOnly: true, + }, + "SLH-DSA-SHAKE-192s": { + creationParams: map[string]interface{}{"type": "slh-dsa", "parameter_set": keysutil.ParameterSet_SLH_DSA_SHAKE_192S}, + entOnly: true, + }, + "SLH-DSA-SHA2-192f": { + creationParams: map[string]interface{}{"type": "slh-dsa", "parameter_set": keysutil.ParameterSet_SLH_DSA_SHA2_192F}, + entOnly: true, + }, + "SLH-DSA-SHAKE-192f": { + creationParams: map[string]interface{}{"type": "slh-dsa", "parameter_set": keysutil.ParameterSet_SLH_DSA_SHAKE_192F}, + entOnly: true, + }, + "SLH-DSA-SHA2-256s": { + creationParams: map[string]interface{}{"type": "slh-dsa", "parameter_set": keysutil.ParameterSet_SLH_DSA_SHA2_256S}, + entOnly: true, + }, + "SLH-DSA-SHAKE-256s": { + creationParams: map[string]interface{}{"type": "slh-dsa", "parameter_set": keysutil.ParameterSet_SLH_DSA_SHAKE_256S}, + entOnly: true, + }, + "SLH-DSA-SHA2-256f": { + creationParams: map[string]interface{}{"type": "slh-dsa", "parameter_set": keysutil.ParameterSet_SLH_DSA_SHA2_256F}, + entOnly: true, + }, + "SLH-DSA-SHAKE-256f": { + creationParams: map[string]interface{}{"type": "slh-dsa", "parameter_set": keysutil.ParameterSet_SLH_DSA_SHAKE_256F}, + entOnly: true, + }, "bad key type": { creationParams: map[string]interface{}{"type": "fake-key-type"}, shouldError: true, diff --git a/sdk/helper/keysutil/lock_manager.go b/sdk/helper/keysutil/lock_manager.go index 06ae5f78ea5..9f561702513 100644 --- a/sdk/helper/keysutil/lock_manager.go +++ b/sdk/helper/keysutil/lock_manager.go @@ -426,6 +426,12 @@ func (lm *LockManager) GetPolicy(ctx context.Context, req PolicyRequest, rand io return nil, false, fmt.Errorf("key derivation and convergent encryption not supported for keys of type %v", req.KeyType) } + case KeyType_SLH_DSA: + if req.Derived || req.Convergent { + cleanup() + return nil, false, fmt.Errorf("key derivation and convergent encryption not supported for keys of type %v", req.KeyType) + } + default: cleanup() return nil, false, fmt.Errorf("unsupported key type %v", req.KeyType) diff --git a/sdk/helper/keysutil/policy.go b/sdk/helper/keysutil/policy.go index bb07b51f04d..3b5bd414d33 100644 --- a/sdk/helper/keysutil/policy.go +++ b/sdk/helper/keysutil/policy.go @@ -75,13 +75,26 @@ const ( KeyType_ML_DSA KeyType_HYBRID KeyType_AES192_CMAC + KeyType_SLH_DSA // If adding to this list please update allTestKeyTypes in policy_test.go ) const ( - ParameterSet_ML_DSA_44 = "44" - ParameterSet_ML_DSA_65 = "65" - ParameterSet_ML_DSA_87 = "87" + ParameterSet_ML_DSA_44 = "44" + ParameterSet_ML_DSA_65 = "65" + ParameterSet_ML_DSA_87 = "87" + ParameterSet_SLH_DSA_SHA2_128S = "slh-dsa-sha2-128s" + ParameterSet_SLH_DSA_SHAKE_128S = "slh-dsa-shake-128s" + ParameterSet_SLH_DSA_SHA2_128F = "slh-dsa-sha2-128f" + ParameterSet_SLH_DSA_SHAKE_128F = "slh-dsa-shake-128f" + ParameterSet_SLH_DSA_SHA2_192S = "slh-dsa-sha2-192s" + ParameterSet_SLH_DSA_SHAKE_192S = "slh-dsa-shake-192s" + ParameterSet_SLH_DSA_SHA2_192F = "slh-dsa-sha2-192f" + ParameterSet_SLH_DSA_SHAKE_192F = "slh-dsa-shake-192f" + ParameterSet_SLH_DSA_SHA2_256S = "slh-dsa-sha2-256s" + ParameterSet_SLH_DSA_SHAKE_256S = "slh-dsa-shake-256s" + ParameterSet_SLH_DSA_SHA2_256F = "slh-dsa-sha2-256f" + ParameterSet_SLH_DSA_SHAKE_256F = "slh-dsa-shake-256f" ) const ( @@ -191,7 +204,7 @@ func (kt KeyType) DecryptionSupported() bool { func (kt KeyType) SigningSupported() bool { switch kt { - case KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521, KeyType_ED25519, KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096, KeyType_MANAGED_KEY, KeyType_ML_DSA, KeyType_HYBRID: + case KeyType_ECDSA_P256, KeyType_ECDSA_P384, KeyType_ECDSA_P521, KeyType_ED25519, KeyType_RSA2048, KeyType_RSA3072, KeyType_RSA4096, KeyType_MANAGED_KEY, KeyType_ML_DSA, KeyType_HYBRID, KeyType_SLH_DSA: return true } return false @@ -243,7 +256,7 @@ func (kt KeyType) HMACSupported() bool { func (kt KeyType) IsPQC() bool { switch kt { - case KeyType_ML_DSA, KeyType_HYBRID: + case KeyType_ML_DSA, KeyType_HYBRID, KeyType_SLH_DSA: return true default: return false @@ -303,6 +316,8 @@ func (kt KeyType) String() string { return "hybrid" case KeyType_AES192_CMAC: return "aes192-cmac" + case KeyType_SLH_DSA: + return "slh-dsa" } return "[unknown]" diff --git a/sdk/helper/keysutil/policy_test.go b/sdk/helper/keysutil/policy_test.go index 06031405b55..cd980b25620 100644 --- a/sdk/helper/keysutil/policy_test.go +++ b/sdk/helper/keysutil/policy_test.go @@ -37,7 +37,7 @@ var allTestKeyTypes = []KeyType{ KeyType_AES256_GCM96, KeyType_ECDSA_P256, KeyType_ED25519, KeyType_RSA2048, KeyType_RSA4096, KeyType_ChaCha20_Poly1305, KeyType_ECDSA_P384, KeyType_ECDSA_P521, KeyType_AES128_GCM96, KeyType_RSA3072, KeyType_MANAGED_KEY, KeyType_HMAC, KeyType_AES128_CMAC, KeyType_AES256_CMAC, KeyType_ML_DSA, - KeyType_HYBRID, KeyType_AES192_CMAC, + KeyType_HYBRID, KeyType_AES192_CMAC, KeyType_SLH_DSA, } func TestPolicy_KeyTypes(t *testing.T) {