Reviewers: golang-dev_googlegroups.com,
Message:
Hello [email protected] (cc: [email protected]),
I'd like you to review this change to
https://go.googlecode.com/hg/
Description:
crypto/hmac: add Verify function.
It was suggested that it's too easy to use crypto/hmac insecurely and
I think that has some merit. This change adds a Verify function to
make it obvious that MAC values should be compared in constant time.
Please review this at http://codereview.appspot.com/6632044/
Affected files:
M src/pkg/crypto/hmac/hmac.go
M src/pkg/go/build/deps_test.go
Index: src/pkg/crypto/hmac/hmac.go
===================================================================
--- a/src/pkg/crypto/hmac/hmac.go
+++ b/src/pkg/crypto/hmac/hmac.go
@@ -2,13 +2,26 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Package hmac implements the Keyed-Hash Message Authentication Code
(HMAC) as
-// defined in U.S. Federal Information Processing Standards Publication
198.
-// An HMAC is a cryptographic hash that uses a key to sign a message.
-// The receiver verifies the hash by recomputing it using the same key.
+/*
+Package hmac implements the Keyed-Hash Message Authentication Code (HMAC)
as
+defined in U.S. Federal Information Processing Standards Publication 198.
+An HMAC is a cryptographic hash that uses a key to sign a message.
+The receiver verifies the hash by recomputing it using the same key.
+Receivers should be careful to use Verify to compare MACs in order to avoid
+timing side-channels:
+
+ // CheckMAC returns true if messageMAC is a valid HMAC tag for message.
+ func CheckMAC(message, messageMAC, key []byte) bool {
+ mac := hmac.New(sha256.New, key)
+ mac.Write(message)
+ expectedMAC := mac.Sum(nil)
+ return hmac.Verify(messageMAC, expectedMAC)
+ }
+*/
package hmac
import (
+ "crypto/subtle"
"hash"
)
@@ -78,3 +91,11 @@
hm.Reset()
return hm
}
+
+// Verify compares two MACs for equality without leaking timing
information.
+func Verify(a, b []byte) bool {
+ // We don't have to be constant time if the lengths of the MACs are
+ // different as that suggests that a completely different hash function
+ // was used.
+ return len(a) == len(b) && subtle.ConstantTimeCompare(a, b) == 1
+}
Index: src/pkg/go/build/deps_test.go
===================================================================
--- a/src/pkg/go/build/deps_test.go
+++ b/src/pkg/go/build/deps_test.go
@@ -249,18 +249,23 @@
"net/mail": {"L4", "NET", "OS"},
"net/textproto": {"L4", "OS", "net"},
+ // Support libraries for crypto that aren't L2.
+ "CRYPTO-SUPPORT": {
+ "crypto/subtle",
+ },
+
// Core crypto.
"crypto/aes": {"L3"},
"crypto/des": {"L3"},
- "crypto/hmac": {"L3"},
+ "crypto/hmac": {"L3", "CRYPTO-SUPPORT"},
"crypto/md5": {"L3"},
"crypto/rc4": {"L3"},
"crypto/sha1": {"L3"},
"crypto/sha256": {"L3"},
"crypto/sha512": {"L3"},
- "crypto/subtle": {"L3"},
"CRYPTO": {
+ "CRYPTO-SUPPORT",
"crypto/aes",
"crypto/des",
"crypto/hmac",
@@ -269,7 +274,6 @@
"crypto/sha1",
"crypto/sha256",
"crypto/sha512",
- "crypto/subtle",
},
// Random byte, number generation.