Skip to content

Commit 5073bf3

Browse files
jblebrunbradfitz
authored andcommitted
crypto/sha256: fix casting of d.nx in UnmarshalBinary
Fixes #29517 Change-Id: I7e741d82bb9f8e6ab39b6d9ab37ba6163176a097 GitHub-Last-Rev: 764d0bd GitHub-Pull-Request: #29519 Reviewed-on: https://go-review.googlesource.com/c/156118 Reviewed-by: Brad Fitzpatrick <[email protected]> Run-TryBot: Brad Fitzpatrick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent af43203 commit 5073bf3

File tree

2 files changed

+64
-1
lines changed

2 files changed

+64
-1
lines changed

src/crypto/sha256/sha256.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ func (d *digest) UnmarshalBinary(b []byte) error {
100100
b, d.h[7] = consumeUint32(b)
101101
b = b[copy(d.x[:], b):]
102102
b, d.len = consumeUint64(b)
103-
d.nx = int(d.len) % chunk
103+
d.nx = int(d.len % chunk)
104104
return nil
105105
}
106106

src/crypto/sha256/sha256_test.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,69 @@ func TestBlockGeneric(t *testing.T) {
226226
}
227227
}
228228

229+
// Tests for unmarshaling hashes that have hashed a large amount of data
230+
// The initial hash generation is omitted from the test, because it takes a long time.
231+
// The test contains some already-generated states, and their expected sums
232+
// Tests a problem that is outlined in Github issue #29517
233+
// The problem is triggered when an amount of data has been hashed for which
234+
// the data length has a 1 in the 32nd bit. When casted to int, this changes
235+
// the sign of the value, and causes the modulus operation to return a
236+
// different result.
237+
type unmarshalTest struct {
238+
state string
239+
sum string
240+
}
241+
242+
var largeUnmarshalTests = []unmarshalTest{
243+
// Data length: 7_115_087_207
244+
unmarshalTest{
245+
state: "sha\x03yX\xaf\xb7\x04*\x8f\xaa\x9bx\xc5#\x1f\xeb\x94\xfdz1\xaf\xfb\n\xc93\xcf\x02\v.\xa5\xe4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xa8\x17\x9dg",
246+
sum: "f5e06371f0c115e9968455c8e48a318aba548b9f15676fa41de123f7d1c99c55",
247+
},
248+
249+
// Data length: 7_070_038_086
250+
unmarshalTest{
251+
state: "sha\x03$\x933u\nV\v\xe2\xf7:0!ʳ\xa4\x13\xd3 6\xdcBB\xb5\x19\xcd=\xc1h\xee=\xb4\x9c@ABCDE\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xa5h8F",
252+
sum: "a280b08df5eba060fcd0eb3d29320bbc038afb95781661f91bbfd0a6fc9fdd6e",
253+
},
254+
255+
// Data length: 6_464_878_887
256+
unmarshalTest{
257+
state: "sha\x03\x9f\x12\x87G\xf2\xdf<\x82\xa0\x11/*W\x02&IKWlh\x03\x95\xb1\xab\f\n\xf6Ze\xf9\x1d\x1b\x00\x01\x02\x03\x04\x05\x06\a\b\t\n\v\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !\"#$%&\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x81V9'",
258+
sum: "d2fffb762f105ab71e2d70069346c44c38c4fe183aad8cfcf5a76397c0457806",
259+
},
260+
}
261+
262+
func safeSum(h hash.Hash) (sum []byte, err error) {
263+
defer func() {
264+
if r := recover(); r != nil {
265+
err = fmt.Errorf("sum panic: %v", r)
266+
}
267+
}()
268+
269+
return h.Sum(nil), nil
270+
}
271+
func TestLargeHashes(t *testing.T) {
272+
for i, test := range largeUnmarshalTests {
273+
274+
h := New()
275+
if err := h.(encoding.BinaryUnmarshaler).UnmarshalBinary([]byte(test.state)); err != nil {
276+
t.Errorf("test %d could not unmarshal: %v", i, err)
277+
continue
278+
}
279+
280+
sum, err := safeSum(h)
281+
if err != nil {
282+
t.Errorf("test %d could not sum: %v", i, err)
283+
continue
284+
}
285+
286+
if fmt.Sprintf("%x", sum) != test.sum {
287+
t.Errorf("test %d sum mismatch: expect %s got %x", i, test.sum, sum)
288+
}
289+
}
290+
}
291+
229292
var bench = New()
230293
var buf = make([]byte, 8192)
231294

0 commit comments

Comments
 (0)