Left: | ||
Right: |
LEFT | RIGHT |
---|---|
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 /* | 5 /* |
6 Package hmac implements the Keyed-Hash Message Authentication Code (HMAC) as | 6 Package hmac implements the Keyed-Hash Message Authentication Code (HMAC) as |
7 defined in U.S. Federal Information Processing Standards Publication 198. | 7 defined in U.S. Federal Information Processing Standards Publication 198. |
8 An HMAC is a cryptographic hash that uses a key to sign a message. | 8 An HMAC is a cryptographic hash that uses a key to sign a message. |
9 The receiver verifies the hash by recomputing it using the same key. | 9 The receiver verifies the hash by recomputing it using the same key. |
10 Receivers should be careful to use Verify to compare MACs in order to avoid | 10 |
rsc
2012/10/09 15:43:28
new paragraph here (insert blank line above this o
agl1
2012/10/09 17:15:24
Done.
| |
11 Receivers should be careful to use Equal to compare MACs in order to avoid | |
11 timing side-channels: | 12 timing side-channels: |
12 | 13 |
13 // CheckMAC returns true if messageMAC is a valid HMAC tag for message. | 14 // CheckMAC returns true if messageMAC is a valid HMAC tag for message. |
14 func CheckMAC(message, messageMAC, key []byte) bool { | 15 func CheckMAC(message, messageMAC, key []byte) bool { |
15 mac := hmac.New(sha256.New, key) | 16 mac := hmac.New(sha256.New, key) |
16 mac.Write(message) | 17 mac.Write(message) |
17 expectedMAC := mac.Sum(nil) | 18 expectedMAC := mac.Sum(nil) |
18 » » return hmac.Verify(messageMAC, expectedMAC) | 19 » » return hmac.Equal(messageMAC, expectedMAC) |
19 } | 20 } |
20 */ | 21 */ |
21 package hmac | 22 package hmac |
22 | 23 |
23 import ( | 24 import ( |
24 "crypto/subtle" | 25 "crypto/subtle" |
25 "hash" | 26 "hash" |
26 ) | 27 ) |
27 | 28 |
28 // FIPS 198: | 29 // FIPS 198: |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
63 return h.inner.Write(p) | 64 return h.inner.Write(p) |
64 } | 65 } |
65 | 66 |
66 func (h *hmac) Size() int { return h.size } | 67 func (h *hmac) Size() int { return h.size } |
67 | 68 |
68 func (h *hmac) BlockSize() int { return h.blocksize } | 69 func (h *hmac) BlockSize() int { return h.blocksize } |
69 | 70 |
70 func (h *hmac) Reset() { | 71 func (h *hmac) Reset() { |
71 h.inner.Reset() | 72 h.inner.Reset() |
72 h.tmpPad(0x36) | 73 h.tmpPad(0x36) |
73 » h.inner.Write(h.tmp[0:h.blocksize]) | 74 » h.inner.Write(h.tmp[:h.blocksize]) |
74 } | 75 } |
75 | 76 |
76 // New returns a new HMAC hash using the given hash.Hash type and key. | 77 // New returns a new HMAC hash using the given hash.Hash type and key. |
77 func New(h func() hash.Hash, key []byte) hash.Hash { | 78 func New(h func() hash.Hash, key []byte) hash.Hash { |
78 hm := new(hmac) | 79 hm := new(hmac) |
79 hm.outer = h() | 80 hm.outer = h() |
80 hm.inner = h() | 81 hm.inner = h() |
81 hm.size = hm.inner.Size() | 82 hm.size = hm.inner.Size() |
82 hm.blocksize = hm.inner.BlockSize() | 83 hm.blocksize = hm.inner.BlockSize() |
83 hm.tmp = make([]byte, hm.blocksize+hm.size) | 84 hm.tmp = make([]byte, hm.blocksize+hm.size) |
84 if len(key) > hm.blocksize { | 85 if len(key) > hm.blocksize { |
85 // If key is too big, hash it. | 86 // If key is too big, hash it. |
86 hm.outer.Write(key) | 87 hm.outer.Write(key) |
87 key = hm.outer.Sum(nil) | 88 key = hm.outer.Sum(nil) |
88 } | 89 } |
89 hm.key = make([]byte, len(key)) | 90 hm.key = make([]byte, len(key)) |
90 copy(hm.key, key) | 91 copy(hm.key, key) |
91 hm.Reset() | 92 hm.Reset() |
92 return hm | 93 return hm |
93 } | 94 } |
94 | 95 |
95 // Verify compares two MACs for equality without leaking timing information. | 96 // Equal compares two MACs for equality without leaking timing information. |
rsc
2012/10/09 15:43:28
I'd prefer to use a name that is more clearly bool
agl1
2012/10/09 17:15:24
Yes, that's clearly better. Thanks.
| |
96 func Verify(a, b []byte) bool { | 97 func Equal(mac1, mac2 []byte) bool { |
97 // We don't have to be constant time if the lengths of the MACs are | 98 // We don't have to be constant time if the lengths of the MACs are |
98 // different as that suggests that a completely different hash function | 99 // different as that suggests that a completely different hash function |
99 // was used. | 100 // was used. |
100 » return len(a) == len(b) && subtle.ConstantTimeCompare(a, b) == 1 | 101 » return len(mac1) == len(mac2) && subtle.ConstantTimeCompare(mac1, mac2) == 1 |
101 } | 102 } |
LEFT | RIGHT |