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>
This commit is contained in:
Filippo Valsorda 2025-12-09 01:04:16 +01:00 committed by Gopher Robot
parent c39fe18fea
commit b130dab792

View File

@ -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
}