Skip to content

Commit 23c22ca

Browse files
jblebrunbradfitz
authored andcommitted
crypto/sha512: fix casting of d.nx in UnmarshalBinary
Fixes #29541 Change-Id: I006915b020b6e710298c32c05e3de77a7f9b54f3 GitHub-Last-Rev: c7a90a4 GitHub-Pull-Request: #29542 Reviewed-on: https://go-review.googlesource.com/c/156277 Run-TryBot: Brad Fitzpatrick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent 0d6a2d5 commit 23c22ca

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

src/crypto/sha512/sha512.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ func (d *digest) UnmarshalBinary(b []byte) error {
191191
b, d.h[7] = consumeUint64(b)
192192
b = b[copy(d.x[:], b):]
193193
b, d.len = consumeUint64(b)
194-
d.nx = int(d.len) % chunk
194+
d.nx = int(d.len % chunk)
195195
return nil
196196
}
197197

src/crypto/sha512/sha512_test.go

+57
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"crypto/rand"
1212
"encoding"
1313
"encoding/hex"
14+
"fmt"
1415
"hash"
1516
"io"
1617
"testing"
@@ -831,6 +832,62 @@ func TestBlockGeneric(t *testing.T) {
831832
}
832833
}
833834

835+
// Tests for unmarshaling hashes that have hashed a large amount of data
836+
// The initial hash generation is omitted from the test, because it takes a long time.
837+
// The test contains some already-generated states, and their expected sums
838+
// Tests a problem that is outlined in Github issue #29541
839+
// The problem is triggered when an amount of data has been hashed for which
840+
// the data length has a 1 in the 32nd bit. When casted to int, this changes
841+
// the sign of the value, and causes the modulus operation to return a
842+
// different result.
843+
type unmarshalTest struct {
844+
state string
845+
sum string
846+
}
847+
848+
var largeUnmarshalTests = []unmarshalTest{
849+
// Data length: 6_565_544_823
850+
unmarshalTest{
851+
state: "sha\aηe\x0f\x0f\xe1r]#\aoJ!.{5B\xe4\x140\x91\xdd\x00a\xe1\xb3E&\xb9\xbb\aJ\x9f^\x9f\x03ͺD\x96H\x80\xb0X\x9d\xdeʸ\f\xf7:\xd5\xe6'\xb9\x93f\xddA\xf0~\xe1\x02\x14\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 !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuv\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\x87VCw",
852+
sum: "12d612357a1dbc74a28883dff79b83e7d2b881ae40d7a67fd7305490bc8a641cd1ce9ece598192080d6e9ac7e75d5988567a58a9812991299eb99a04ecb69523",
853+
},
854+
unmarshalTest{
855+
state: "sha\a2\xd2\xdc\xf5\xd7\xe2\xf9\x97\xaa\xe7}Fϱ\xbc\x8e\xbf\x12h\x83Z\xa1\xc7\xf5p>bfS T\xea\xee\x1e\xa6Z\x9c\xa4ڶ\u0086\bn\xe47\x8fsGs3\xe0\xda\\\x9dqZ\xa5\xf6\xd0kM\xa1\xf2\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 !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuv\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01\xa7VCw",
856+
sum: "94a04b9a901254cd94ca0313557e4be3ab1ca86e920c1f3efdc22d361e9ae12be66bc6d6dc5db79a0a4aa6eca6f293c1e9095bbae127ae405f6c325478343299",
857+
},
858+
}
859+
860+
func safeSum(h hash.Hash) (sum []byte, err error) {
861+
defer func() {
862+
if r := recover(); r != nil {
863+
err = fmt.Errorf("sum panic: %v", r)
864+
}
865+
}()
866+
867+
return h.Sum(nil), nil
868+
}
869+
870+
func TestLargeHashes(t *testing.T) {
871+
for i, test := range largeUnmarshalTests {
872+
873+
h := New()
874+
if err := h.(encoding.BinaryUnmarshaler).UnmarshalBinary([]byte(test.state)); err != nil {
875+
t.Errorf("test %d could not unmarshal: %v", i, err)
876+
continue
877+
}
878+
879+
sum, err := safeSum(h)
880+
if err != nil {
881+
t.Errorf("test %d could not sum: %v", i, err)
882+
continue
883+
}
884+
885+
if fmt.Sprintf("%x", sum) != test.sum {
886+
t.Errorf("test %d sum mismatch: expect %s got %x", i, test.sum, sum)
887+
}
888+
}
889+
}
890+
834891
var bench = New()
835892
var buf = make([]byte, 8192)
836893

0 commit comments

Comments
 (0)