diff options
| author | Filippo Valsorda <filippo@golang.org> | 2025-12-09 01:04:16 +0100 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2025-12-10 13:46:00 -0800 |
| commit | b130dab7927741223d40f221e27f3bd351e9cddf (patch) | |
| tree | 23729c2ba8dc5d1747ffc4eb868231ee7fb2bb2c /src/crypto | |
| parent | c39fe18fea16d6bdbd5526a7b7d7b59e84ae0144 (diff) | |
| download | go-b130dab7927741223d40f221e27f3bd351e9cddf.tar.xz | |
crypto/hpke: apply fips140.WithoutEnforcement to ML-KEM+X25519 hybrid
Since it uses an Approved KEM (ML-KEM), the overall hybrid KEM is
Approved, even if X25519 is not.
Updates #70514
Updates #74630
Change-Id: I2bb60c36fcf570baa3c389e2daa3698e6a6a6964
Reviewed-on: https://go-review.googlesource.com/c/go/+/728505
Auto-Submit: Filippo Valsorda <filippo@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Diffstat (limited to 'src/crypto')
| -rw-r--r-- | src/crypto/hpke/pq.go | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/src/crypto/hpke/pq.go b/src/crypto/hpke/pq.go index f2adbef54e..e8dc80fd23 100644 --- a/src/crypto/hpke/pq.go +++ b/src/crypto/hpke/pq.go @@ -8,6 +8,7 @@ import ( "bytes" "crypto" "crypto/ecdh" + "crypto/fips140" "crypto/internal/fips140/drbg" "crypto/internal/rand" "crypto/mlkem" @@ -168,7 +169,10 @@ func (kem *hybridKEM) NewPublicKey(data []byte) (PublicKey, error) { if err != nil { return nil, err } - k, err := kem.curve.NewPublicKey(data[kem.pqEncapsKeySize:]) + var k *ecdh.PublicKey + fips140.WithoutEnforcement(func() { // Hybrid of ML-KEM, which is Approved. + k, err = kem.curve.NewPublicKey(data[kem.pqEncapsKeySize:]) + }) if err != nil { return nil, err } @@ -186,14 +190,20 @@ func (pk *hybridPublicKey) Bytes() []byte { var testingOnlyEncapsulate func() (ss, ct []byte) func (pk *hybridPublicKey) encap() (sharedSecret []byte, encapPub []byte, err error) { - skE, err := pk.t.Curve().GenerateKey(rand.Reader) + var skE *ecdh.PrivateKey + fips140.WithoutEnforcement(func() { // Hybrid of ML-KEM, which is Approved. + skE, err = pk.t.Curve().GenerateKey(rand.Reader) + }) if err != nil { return nil, nil, err } if testingOnlyGenerateKey != nil { skE = testingOnlyGenerateKey() } - ssT, err := skE.ECDH(pk.t) + var ssT []byte + fips140.WithoutEnforcement(func() { + ssT, err = skE.ECDH(pk.t) + }) if err != nil { return nil, nil, err } @@ -259,7 +269,10 @@ func (kem *hybridKEM) NewPrivateKey(priv []byte) (PrivateKey, error) { seedT := make([]byte, kem.curveSeedSize) for { s.Read(seedT) - k, err := kem.curve.NewPrivateKey(seedT) + var k ecdh.KeyExchanger + fips140.WithoutEnforcement(func() { // Hybrid of ML-KEM, which is Approved. + k, err = kem.curve.NewPrivateKey(seedT) + }) if err != nil { continue } @@ -326,11 +339,17 @@ func (k *hybridPrivateKey) decap(enc []byte) ([]byte, error) { if err != nil { return nil, err } - pub, err := k.t.Curve().NewPublicKey(ctT) + var pub *ecdh.PublicKey + fips140.WithoutEnforcement(func() { // Hybrid of ML-KEM, which is Approved. + pub, err = k.t.Curve().NewPublicKey(ctT) + }) if err != nil { return nil, err } - ssT, err := k.t.ECDH(pub) + var ssT []byte + fips140.WithoutEnforcement(func() { + ssT, err = k.t.ECDH(pub) + }) if err != nil { return nil, err } |
