hkdf: forward Extract to the standard library

Change-Id: I82406eb153c53e7cbf167360e472724a6a6a6964
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/769720
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
Reviewed-by: Roland Shoemaker <roland@golang.org>
LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
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 @@
 // 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 @@
 	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 @@
 // 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,