Skip to content

Commit

Permalink
add ce changes for ecdsa hybrid (#29123)
Browse files Browse the repository at this point in the history
  • Loading branch information
rculpepper authored and Monkeychip committed Dec 18, 2024
1 parent c51e1ac commit 37d2c9c
Show file tree
Hide file tree
Showing 5 changed files with 273 additions and 134 deletions.
59 changes: 58 additions & 1 deletion builtin/logical/transit/path_keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,16 @@ key.`,
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.`,
},
"hybrid_key_type_pqc": {
Type: framework.TypeString,
Description: `The key type of the post-quantum key to use for hybrid signature schemes.
Supported types are: ML-DSA.`,
},
"hybrid_key_type_ec": {
Type: framework.TypeString,
Description: `The key type of the elliptic curve key to use for hybrid signature schemes.
Supported types are: ecdsa-p256, ecdsa-p384, ecdsa-p521.`,
},
},

Operations: map[logical.Operation]framework.OperationHandler{
Expand Down Expand Up @@ -184,6 +194,8 @@ func (b *backend) pathPolicyWrite(ctx context.Context, req *logical.Request, d *
managedKeyName := d.Get("managed_key_name").(string)
managedKeyId := d.Get("managed_key_id").(string)
parameterSet := d.Get("parameter_set").(string)
pqcKeyType := d.Get("hybrid_key_type_pqc").(string)
ecKeyType := d.Get("hybrid_key_type_ec").(string)

if autoRotatePeriod != 0 && autoRotatePeriod < time.Hour {
return logical.ErrorResponse("auto rotate period must be 0 to disable or at least an hour"), nil
Expand Down Expand Up @@ -241,6 +253,16 @@ func (b *backend) pathPolicyWrite(ctx context.Context, req *logical.Request, d *
return logical.ErrorResponse(fmt.Sprintf("invalid parameter set %s for key type %s", parameterSet, keyType)), logical.ErrInvalidRequest
}

polReq.ParameterSet = parameterSet
case "hybrid":
polReq.KeyType = keysutil.KeyType_HYBRID

var err error
polReq.HybridConfig, err = getHybridKeyConfig(pqcKeyType, parameterSet, ecKeyType)
if err != nil {
return logical.ErrorResponse(fmt.Sprintf("invalid config for hybrid key: %s", err)), logical.ErrInvalidRequest
}

polReq.ParameterSet = parameterSet
default:
return logical.ErrorResponse(fmt.Sprintf("unknown key type %v", keyType)), logical.ErrInvalidRequest
Expand Down Expand Up @@ -393,6 +415,11 @@ func (b *backend) formatKeyPolicy(p *keysutil.Policy, context []byte) (*logical.
resp.Data["parameter_set"] = p.ParameterSet
}

if p.Type == keysutil.KeyType_HYBRID {
resp.Data["hybrid_key_type_pqc"] = p.HybridConfig.PQCKeyType.String()
resp.Data["hybrid_key_type_ec"] = p.HybridConfig.ECKeyType.String()
}

switch p.Type {
case keysutil.KeyType_AES128_GCM96, keysutil.KeyType_AES256_GCM96, keysutil.KeyType_ChaCha20_Poly1305:
retKeys := map[string]int64{}
Expand All @@ -401,7 +428,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:
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:
retKeys := map[string]map[string]interface{}{}
for k, v := range p.Keys {
key := asymKey{
Expand Down Expand Up @@ -488,6 +515,36 @@ func (b *backend) pathPolicyDelete(ctx context.Context, req *logical.Request, d
return nil, nil
}

func getHybridKeyConfig(pqcKeyType, parameterSet, ecKeyType string) (keysutil.HybridKeyConfig, error) {
config := keysutil.HybridKeyConfig{}

switch pqcKeyType {
case "ml-dsa":
config.PQCKeyType = keysutil.KeyType_ML_DSA

if parameterSet != keysutil.ParameterSet_ML_DSA_44 &&
parameterSet != keysutil.ParameterSet_ML_DSA_65 &&
parameterSet != keysutil.ParameterSet_ML_DSA_87 {
return keysutil.HybridKeyConfig{}, fmt.Errorf("invalid parameter set %s for key type %s", parameterSet, pqcKeyType)
}
default:
return keysutil.HybridKeyConfig{}, fmt.Errorf("invalid PQC key type: %s", pqcKeyType)
}

switch ecKeyType {
case "ecdsa-p256":
config.ECKeyType = keysutil.KeyType_ECDSA_P256
case "ecdsa-p384":
config.ECKeyType = keysutil.KeyType_ECDSA_P384
case "ecdsa-p521":
config.ECKeyType = keysutil.KeyType_ECDSA_P521
default:
return keysutil.HybridKeyConfig{}, fmt.Errorf("invalid key type for hybrid key: %s", ecKeyType)
}

return config, nil
}

const pathPolicyHelpSyn = `Managed named encryption keys`

const pathPolicyHelpDesc = `
Expand Down
36 changes: 36 additions & 0 deletions builtin/logical/transit/path_keys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,42 @@ func TestTransit_CreateKey(t *testing.T) {
creationParams: map[string]interface{}{"type": "ml-dsa", "parameter_set": "87"},
entOnly: true,
},
"Hybrid ML-DSA-44-ECDSA-P256": {
creationParams: map[string]interface{}{"type": "hybrid", "parameter_set": "44", "hybrid_key_type_ec": "ecdsa-p256", "hybrid_key_type_pqc": "ml-dsa"},
entOnly: true,
},
"Hybrid ML-DSA-44-ECDSA-P384": {
creationParams: map[string]interface{}{"type": "hybrid", "parameter_set": "44", "hybrid_key_type_ec": "ecdsa-p384", "hybrid_key_type_pqc": "ml-dsa"},
entOnly: true,
},
"Hybrid ML-DSA-44-ECDSA-P521": {
creationParams: map[string]interface{}{"type": "hybrid", "parameter_set": "44", "hybrid_key_type_ec": "ecdsa-p521", "hybrid_key_type_pqc": "ml-dsa"},
entOnly: true,
},
"Hybrid ML-DSA-65-ECDSA-P256": {
creationParams: map[string]interface{}{"type": "ml-dsa", "parameter_set": "65", "hybrid_key_type_ec": "ecdsa-p256", "hybrid_key_type_pqc": "ml-dsa"},
entOnly: true,
},
"Hybrid ML-DSA-65-ECDSA-P384": {
creationParams: map[string]interface{}{"type": "ml-dsa", "parameter_set": "65", "hybrid_key_type_ec": "ecdsa-p384", "hybrid_key_type_pqc": "ml-dsa"},
entOnly: true,
},
"Hybrid ML-DSA-65-ECDSA-P521": {
creationParams: map[string]interface{}{"type": "ml-dsa", "parameter_set": "65", "hybrid_key_type_ec": "ecdsa-p521", "hybrid_key_type_pqc": "ml-dsa"},
entOnly: true,
},
"Hybrid ML-DSA-87-ECDSA-P256": {
creationParams: map[string]interface{}{"type": "ml-dsa", "parameter_set": "87", "hybrid_key_type_ec": "ecdsa-p256", "hybrid_key_type_pqc": "ml-dsa"},
entOnly: true,
},
"Hybrid ML-DSA-87-ECDSA-P384": {
creationParams: map[string]interface{}{"type": "ml-dsa", "parameter_set": "87", "hybrid_key_type_ec": "ecdsa-p384", "hybrid_key_type_pqc": "ml-dsa"},
entOnly: true,
},
"Hybrid ML-DSA-87-ECDSA-P521": {
creationParams: map[string]interface{}{"type": "ml-dsa", "parameter_set": "87", "hybrid_key_type_ec": "ecdsa-p521", "hybrid_key_type_pqc": "ml-dsa"},
entOnly: true,
},
"bad key type": {
creationParams: map[string]interface{}{"type": "fake-key-type"},
shouldError: true,
Expand Down
15 changes: 15 additions & 0 deletions sdk/helper/keysutil/lock_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ type PolicyRequest struct {

// ParameterSet indicates the parameter set to use with ML-DSA and SLH-DSA keys
ParameterSet string

// HybridConfig contains the key types and parameters for hybrid keys
HybridConfig HybridKeyConfig
}

type HybridKeyConfig struct {
PQCKeyType KeyType
ECKeyType KeyType
}

type LockManager struct {
Expand Down Expand Up @@ -412,6 +420,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_HYBRID:
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)
Expand All @@ -427,6 +441,7 @@ func (lm *LockManager) GetPolicy(ctx context.Context, req PolicyRequest, rand io
AutoRotatePeriod: req.AutoRotatePeriod,
KeySize: req.KeySize,
ParameterSet: req.ParameterSet,
HybridConfig: req.HybridConfig,
}

if req.Derived {
Expand Down
Loading

0 comments on commit 37d2c9c

Please sign in to comment.