diff options
Diffstat (limited to 'libgo/go/crypto/md5/md5.go')
-rw-r--r-- | libgo/go/crypto/md5/md5.go | 100 |
1 files changed, 43 insertions, 57 deletions
diff --git a/libgo/go/crypto/md5/md5.go b/libgo/go/crypto/md5/md5.go index 88d914d22ce..01157840475 100644 --- a/libgo/go/crypto/md5/md5.go +++ b/libgo/go/crypto/md5/md5.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -//go:generate go run gen.go -full -output md5block.go +//go:generate go run gen.go -output md5block.go // Package md5 implements the MD5 hash algorithm as defined in RFC 1321. // @@ -12,6 +12,7 @@ package md5 import ( "crypto" + "encoding/binary" "errors" "hash" ) @@ -27,7 +28,6 @@ const Size = 16 const BlockSize = 64 const ( - chunk = 64 init0 = 0x67452301 init1 = 0xEFCDAB89 init2 = 0x98BADCFE @@ -37,7 +37,7 @@ const ( // digest represents the partial evaluation of a checksum. type digest struct { s [4]uint32 - x [chunk]byte + x [BlockSize]byte nx int len uint64 } @@ -53,7 +53,7 @@ func (d *digest) Reset() { const ( magic = "md5\x01" - marshaledSize = len(magic) + 4*4 + chunk + 8 + marshaledSize = len(magic) + 4*4 + BlockSize + 8 ) func (d *digest) MarshalBinary() ([]byte, error) { @@ -83,45 +83,28 @@ func (d *digest) UnmarshalBinary(b []byte) error { b, d.s[3] = consumeUint32(b) b = b[copy(d.x[:], b):] b, d.len = consumeUint64(b) - d.nx = int(d.len) % chunk + d.nx = int(d.len % BlockSize) return nil } func appendUint64(b []byte, x uint64) []byte { - a := [8]byte{ - byte(x >> 56), - byte(x >> 48), - byte(x >> 40), - byte(x >> 32), - byte(x >> 24), - byte(x >> 16), - byte(x >> 8), - byte(x), - } + var a [8]byte + binary.BigEndian.PutUint64(a[:], x) return append(b, a[:]...) } func appendUint32(b []byte, x uint32) []byte { - a := [4]byte{ - byte(x >> 24), - byte(x >> 16), - byte(x >> 8), - byte(x), - } + var a [4]byte + binary.BigEndian.PutUint32(a[:], x) return append(b, a[:]...) } func consumeUint64(b []byte) ([]byte, uint64) { - _ = b[7] - x := uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | - uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 - return b[8:], x + return b[8:], binary.BigEndian.Uint64(b[0:8]) } func consumeUint32(b []byte) ([]byte, uint32) { - _ = b[3] - x := uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 - return b[4:], x + return b[4:], binary.BigEndian.Uint32(b[0:4]) } // New returns a new hash.Hash computing the MD5 checksum. The Hash also @@ -138,20 +121,31 @@ func (d *digest) Size() int { return Size } func (d *digest) BlockSize() int { return BlockSize } func (d *digest) Write(p []byte) (nn int, err error) { + // Note that we currently call block or blockGeneric + // directly (guarded using haveAsm) because this allows + // escape analysis to see that p and d don't escape. nn = len(p) d.len += uint64(nn) if d.nx > 0 { n := copy(d.x[d.nx:], p) d.nx += n - if d.nx == chunk { - block(d, d.x[:]) + if d.nx == BlockSize { + if haveAsm { + block(d, d.x[:]) + } else { + blockGeneric(d, d.x[:]) + } d.nx = 0 } p = p[n:] } - if len(p) >= chunk { - n := len(p) &^ (chunk - 1) - block(d, p[:n]) + if len(p) >= BlockSize { + n := len(p) &^ (BlockSize - 1) + if haveAsm { + block(d, p[:n]) + } else { + blockGeneric(d, p[:n]) + } p = p[n:] } if len(p) > 0 { @@ -168,35 +162,27 @@ func (d *digest) Sum(in []byte) []byte { } func (d *digest) checkSum() [Size]byte { - // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. - len := d.len - var tmp [64]byte - tmp[0] = 0x80 - if len%64 < 56 { - d.Write(tmp[0 : 56-len%64]) - } else { - d.Write(tmp[0 : 64+56-len%64]) - } - - // Length in bits. - len <<= 3 - for i := uint(0); i < 8; i++ { - tmp[i] = byte(len >> (8 * i)) - } - d.Write(tmp[0:8]) - + // Append 0x80 to the end of the message and then append zeros + // until the length is a multiple of 56 bytes. Finally append + // 8 bytes representing the message length in bits. + // + // 1 byte end marker :: 0-63 padding bytes :: 8 byte length + tmp := [1 + 63 + 8]byte{0x80} + pad := (55 - d.len) % 64 // calculate number of padding bytes + binary.LittleEndian.PutUint64(tmp[1+pad:], d.len<<3) // append length in bits + d.Write(tmp[:1+pad+8]) + + // The previous write ensures that a whole number of + // blocks (i.e. a multiple of 64 bytes) have been hashed. if d.nx != 0 { panic("d.nx != 0") } var digest [Size]byte - for i, s := range d.s { - digest[i*4] = byte(s) - digest[i*4+1] = byte(s >> 8) - digest[i*4+2] = byte(s >> 16) - digest[i*4+3] = byte(s >> 24) - } - + binary.LittleEndian.PutUint32(digest[0:], d.s[0]) + binary.LittleEndian.PutUint32(digest[4:], d.s[1]) + binary.LittleEndian.PutUint32(digest[8:], d.s[2]) + binary.LittleEndian.PutUint32(digest[12:], d.s[3]) return digest } |