From cc0e4fc1d49127130b0d00612a2eeed2ab745d40 Mon Sep 17 00:00:00 2001 From: Filippo Valsorda Date: Wed, 22 Apr 2026 12:04:56 +0200 Subject: [PATCH] hkdf: forward Extract to the standard library Change-Id: I82406eb153c53e7cbf167360e472724a6a6a6964 Reviewed-on: https://go-review.googlesource.com/c/crypto/+/769720 Reviewed-by: Daniel McCarney Reviewed-by: Roland Shoemaker LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com Reviewed-by: Carlos Amedee Auto-Submit: Filippo Valsorda --- hkdf/hkdf.go | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/hkdf/hkdf.go b/hkdf/hkdf.go index 3bee662..49f3a55 100644 --- a/hkdf/hkdf.go +++ b/hkdf/hkdf.go @@ -11,6 +11,7 @@ package hkdf import ( + "crypto/hkdf" "crypto/hmac" "errors" "hash" @@ -24,15 +25,19 @@ import ( // Expand invocations and different context values. Most common scenarios, // including the generation of multiple keys, should use New instead. func Extract(hash func() hash.Hash, secret, salt []byte) []byte { - if salt == nil { - salt = make([]byte, hash().Size()) + // Use the stdlib Extract, which disables FIPS 140 enforcement of the HMAC + // key (which in HKDF is the salt). The only possible error is FIPS 140 + // enforcement of the hash, which had to panic under this API anyway. We + // don't use the stdlib Expand, because it switched to returning a []byte + // instead of an io.Reader, and Expand uses the HMAC key as a key. + out, err := hkdf.Extract(hash, secret, salt) + if err != nil { + panic(err) } - extractor := hmac.New(hash, salt) - extractor.Write(secret) - return extractor.Sum(nil) + return out } -type hkdf struct { +type hkdfReader struct { expander hash.Hash size int @@ -43,7 +48,7 @@ type hkdf struct { buf []byte } -func (f *hkdf) Read(p []byte) (int, error) { +func (f *hkdfReader) Read(p []byte) (int, error) { // Check whether enough data can be generated need := len(p) remains := len(f.buf) + int(255-f.counter+1)*f.size @@ -84,7 +89,7 @@ func (f *hkdf) Read(p []byte) (int, error) { // 3.3. Most common scenarios will want to use New instead. func Expand(hash func() hash.Hash, pseudorandomKey, info []byte) io.Reader { expander := hmac.New(hash, pseudorandomKey) - return &hkdf{expander, expander.Size(), info, 1, nil, nil} + return &hkdfReader{expander, expander.Size(), info, 1, nil, nil} } // New returns a Reader, from which keys can be read, using the given hash,