aboutsummaryrefslogtreecommitdiff
path: root/src/crypto
diff options
context:
space:
mode:
authorFilippo Valsorda <filippo@golang.org>2025-12-09 01:04:16 +0100
committerGopher Robot <gobot@golang.org>2025-12-10 13:46:00 -0800
commitb130dab7927741223d40f221e27f3bd351e9cddf (patch)
tree23729c2ba8dc5d1747ffc4eb868231ee7fb2bb2c /src/crypto
parentc39fe18fea16d6bdbd5526a7b7d7b59e84ae0144 (diff)
downloadgo-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.go31
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
}