Skip to content

Commit 2a206c7

Browse files
committed
crypto/hmac: panic if reusing hash.Hash values
Also put Reset in the correct place for the other benchmarks. name old time/op new time/op delta NewWriteSum-8 1.01µs ± 0% 1.01µs ± 1% ~ (p=0.945 n=9+9) name old speed new speed delta NewWriteSum-8 31.7MB/s ± 0% 31.6MB/s ± 1% ~ (p=0.948 n=9+9) name old alloc/op new alloc/op delta NewWriteSum-8 544B ± 0% 544B ± 0% ~ (all equal) name old allocs/op new allocs/op delta NewWriteSum-8 7.00 ± 0% 7.00 ± 0% ~ (all equal) Fixes #41089 Change-Id: I3dae660adbe4993963130bf3c2636bd53899164b Reviewed-on: https://go-review.googlesource.com/c/go/+/261960 Trust: Katie Hockman <katie@golang.org> Trust: Roland Shoemaker <roland@golang.org> Run-TryBot: Katie Hockman <katie@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Filippo Valsorda <filippo@golang.org> Reviewed-by: Roland Shoemaker <roland@golang.org>
1 parent 19f6422 commit 2a206c7

File tree

3 files changed

+46
-1
lines changed

3 files changed

+46
-1
lines changed

doc/go1.16.html

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,14 @@ <h2 id="library">Core library</h2>
181181
TODO
182182
</p>
183183

184+
<h3 id="crypto/hmac"><a href="/pkg/crypto/hmac">crypto/hmac</a></h3>
185+
186+
<p><!-- CL 261960 -->
187+
<a href="/pkg/crypto/hmac/#New">New</a> will now panic if separate calls to
188+
the hash generation function fail to return new values. Previously, the
189+
behavior was undefined and invalid outputs were sometimes generated.
190+
</p>
191+
184192
<h3 id="crypto/tls"><a href="/pkg/crypto/tls">crypto/tls</a></h3>
185193

186194
<p><!-- CL 256897 -->

src/crypto/hmac/hmac.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,28 @@ func (h *hmac) Reset() {
120120
}
121121

122122
// New returns a new HMAC hash using the given hash.Hash type and key.
123+
// New functions like sha256.New from crypto/sha256 can be used as h.
124+
// h must return a new Hash every time it is called.
123125
// Note that unlike other hash implementations in the standard library,
124126
// the returned Hash does not implement encoding.BinaryMarshaler
125127
// or encoding.BinaryUnmarshaler.
126128
func New(h func() hash.Hash, key []byte) hash.Hash {
127129
hm := new(hmac)
128130
hm.outer = h()
129131
hm.inner = h()
132+
unique := true
133+
func() {
134+
defer func() {
135+
// The comparison might panic if the underlying types are not comparable.
136+
_ = recover()
137+
}()
138+
if hm.outer == hm.inner {
139+
unique = false
140+
}
141+
}()
142+
if !unique {
143+
panic("crypto/hmac: hash generation function does not produce unique values")
144+
}
130145
blocksize := hm.inner.BlockSize()
131146
hm.ipad = make([]byte, blocksize)
132147
hm.opad = make([]byte, blocksize)

src/crypto/hmac/hmac_test.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,17 @@ func TestHMAC(t *testing.T) {
556556
}
557557
}
558558

559+
func TestNonUniqueHash(t *testing.T) {
560+
sha := sha256.New()
561+
defer func() {
562+
err := recover()
563+
if err == nil {
564+
t.Error("expected panic when calling New with a non-unique hash generation function")
565+
}
566+
}()
567+
New(func() hash.Hash { return sha }, []byte("bytes"))
568+
}
569+
559570
// justHash implements just the hash.Hash methods and nothing else
560571
type justHash struct {
561572
hash.Hash
@@ -587,8 +598,8 @@ func BenchmarkHMACSHA256_1K(b *testing.B) {
587598
b.SetBytes(int64(len(buf)))
588599
for i := 0; i < b.N; i++ {
589600
h.Write(buf)
590-
h.Reset()
591601
mac := h.Sum(nil)
602+
h.Reset()
592603
buf[0] = mac[0]
593604
}
594605
}
@@ -600,7 +611,18 @@ func BenchmarkHMACSHA256_32(b *testing.B) {
600611
b.SetBytes(int64(len(buf)))
601612
for i := 0; i < b.N; i++ {
602613
h.Write(buf)
614+
mac := h.Sum(nil)
603615
h.Reset()
616+
buf[0] = mac[0]
617+
}
618+
}
619+
620+
func BenchmarkNewWriteSum(b *testing.B) {
621+
buf := make([]byte, 32)
622+
b.SetBytes(int64(len(buf)))
623+
for i := 0; i < b.N; i++ {
624+
h := New(sha256.New, make([]byte, 32))
625+
h.Write(buf)
604626
mac := h.Sum(nil)
605627
buf[0] = mac[0]
606628
}

0 commit comments

Comments
 (0)