mirror of https://github.com/golang/go.git
[dev.boringcrypto] crypto/internal/boring: add MarshalBinary/UnmarshalBinary to hashes
Go 1.10 expects hash.Hash implementations to have these. Make it so. Tested by src/hash/marshal_test.go. Change-Id: I9df366e31fe20e79385d5dbde7060b01b68c54df Reviewed-on: https://go-review.googlesource.com/82139 Reviewed-by: Adam Langley <agl@golang.org>
This commit is contained in:
parent
5379f7847f
commit
3e52f22ece
|
|
@ -12,6 +12,7 @@ package boring
|
||||||
// #include "goboringcrypto.h"
|
// #include "goboringcrypto.h"
|
||||||
import "C"
|
import "C"
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"hash"
|
"hash"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
)
|
)
|
||||||
|
|
@ -28,6 +29,13 @@ type sha1Hash struct {
|
||||||
out [20]byte
|
out [20]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type sha1Ctx struct {
|
||||||
|
h [5]uint32
|
||||||
|
nl, nh uint32
|
||||||
|
x [64]byte
|
||||||
|
nx uint32
|
||||||
|
}
|
||||||
|
|
||||||
func (h *sha1Hash) Reset() { C._goboringcrypto_SHA1_Init(&h.ctx) }
|
func (h *sha1Hash) Reset() { C._goboringcrypto_SHA1_Init(&h.ctx) }
|
||||||
func (h *sha1Hash) Size() int { return 20 }
|
func (h *sha1Hash) Size() int { return 20 }
|
||||||
func (h *sha1Hash) BlockSize() int { return 64 }
|
func (h *sha1Hash) BlockSize() int { return 64 }
|
||||||
|
|
@ -48,6 +56,48 @@ func (h0 *sha1Hash) sum() []byte {
|
||||||
return h.out[:]
|
return h.out[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
sha1Magic = "sha\x01"
|
||||||
|
sha1MarshaledSize = len(sha1Magic) + 5*4 + 64 + 8
|
||||||
|
)
|
||||||
|
|
||||||
|
func (h *sha1Hash) MarshalBinary() ([]byte, error) {
|
||||||
|
d := (*sha1Ctx)(unsafe.Pointer(&h.ctx))
|
||||||
|
b := make([]byte, 0, sha1MarshaledSize)
|
||||||
|
b = append(b, sha1Magic...)
|
||||||
|
b = appendUint32(b, d.h[0])
|
||||||
|
b = appendUint32(b, d.h[1])
|
||||||
|
b = appendUint32(b, d.h[2])
|
||||||
|
b = appendUint32(b, d.h[3])
|
||||||
|
b = appendUint32(b, d.h[4])
|
||||||
|
b = append(b, d.x[:d.nx]...)
|
||||||
|
b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
|
||||||
|
b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29)
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *sha1Hash) UnmarshalBinary(b []byte) error {
|
||||||
|
if len(b) < len(sha1Magic) || string(b[:len(sha1Magic)]) != sha1Magic {
|
||||||
|
return errors.New("crypto/sha1: invalid hash state identifier")
|
||||||
|
}
|
||||||
|
if len(b) != sha1MarshaledSize {
|
||||||
|
return errors.New("crypto/sha1: invalid hash state size")
|
||||||
|
}
|
||||||
|
d := (*sha1Ctx)(unsafe.Pointer(&h.ctx))
|
||||||
|
b = b[len(sha1Magic):]
|
||||||
|
b, d.h[0] = consumeUint32(b)
|
||||||
|
b, d.h[1] = consumeUint32(b)
|
||||||
|
b, d.h[2] = consumeUint32(b)
|
||||||
|
b, d.h[3] = consumeUint32(b)
|
||||||
|
b, d.h[4] = consumeUint32(b)
|
||||||
|
b = b[copy(d.x[:], b):]
|
||||||
|
b, n := consumeUint64(b)
|
||||||
|
d.nl = uint32(n << 3)
|
||||||
|
d.nh = uint32(n >> 29)
|
||||||
|
d.nx = uint32(n) % 64
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// NewSHA224 returns a new SHA224 hash.
|
// NewSHA224 returns a new SHA224 hash.
|
||||||
func NewSHA224() hash.Hash {
|
func NewSHA224() hash.Hash {
|
||||||
h := new(sha224Hash)
|
h := new(sha224Hash)
|
||||||
|
|
@ -112,6 +162,105 @@ func (h0 *sha256Hash) sum() []byte {
|
||||||
return h.out[:]
|
return h.out[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
magic224 = "sha\x02"
|
||||||
|
magic256 = "sha\x03"
|
||||||
|
marshaledSize256 = len(magic256) + 8*4 + 64 + 8
|
||||||
|
)
|
||||||
|
|
||||||
|
type sha256Ctx struct {
|
||||||
|
h [8]uint32
|
||||||
|
nl, nh uint32
|
||||||
|
x [64]byte
|
||||||
|
nx uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *sha224Hash) MarshalBinary() ([]byte, error) {
|
||||||
|
d := (*sha256Ctx)(unsafe.Pointer(&h.ctx))
|
||||||
|
b := make([]byte, 0, marshaledSize256)
|
||||||
|
b = append(b, magic224...)
|
||||||
|
b = appendUint32(b, d.h[0])
|
||||||
|
b = appendUint32(b, d.h[1])
|
||||||
|
b = appendUint32(b, d.h[2])
|
||||||
|
b = appendUint32(b, d.h[3])
|
||||||
|
b = appendUint32(b, d.h[4])
|
||||||
|
b = appendUint32(b, d.h[5])
|
||||||
|
b = appendUint32(b, d.h[6])
|
||||||
|
b = appendUint32(b, d.h[7])
|
||||||
|
b = append(b, d.x[:d.nx]...)
|
||||||
|
b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
|
||||||
|
b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29)
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *sha256Hash) MarshalBinary() ([]byte, error) {
|
||||||
|
d := (*sha256Ctx)(unsafe.Pointer(&h.ctx))
|
||||||
|
b := make([]byte, 0, marshaledSize256)
|
||||||
|
b = append(b, magic256...)
|
||||||
|
b = appendUint32(b, d.h[0])
|
||||||
|
b = appendUint32(b, d.h[1])
|
||||||
|
b = appendUint32(b, d.h[2])
|
||||||
|
b = appendUint32(b, d.h[3])
|
||||||
|
b = appendUint32(b, d.h[4])
|
||||||
|
b = appendUint32(b, d.h[5])
|
||||||
|
b = appendUint32(b, d.h[6])
|
||||||
|
b = appendUint32(b, d.h[7])
|
||||||
|
b = append(b, d.x[:d.nx]...)
|
||||||
|
b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
|
||||||
|
b = appendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29)
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *sha224Hash) UnmarshalBinary(b []byte) error {
|
||||||
|
if len(b) < len(magic224) || string(b[:len(magic224)]) != magic224 {
|
||||||
|
return errors.New("crypto/sha256: invalid hash state identifier")
|
||||||
|
}
|
||||||
|
if len(b) != marshaledSize256 {
|
||||||
|
return errors.New("crypto/sha256: invalid hash state size")
|
||||||
|
}
|
||||||
|
d := (*sha256Ctx)(unsafe.Pointer(&h.ctx))
|
||||||
|
b = b[len(magic224):]
|
||||||
|
b, d.h[0] = consumeUint32(b)
|
||||||
|
b, d.h[1] = consumeUint32(b)
|
||||||
|
b, d.h[2] = consumeUint32(b)
|
||||||
|
b, d.h[3] = consumeUint32(b)
|
||||||
|
b, d.h[4] = consumeUint32(b)
|
||||||
|
b, d.h[5] = consumeUint32(b)
|
||||||
|
b, d.h[6] = consumeUint32(b)
|
||||||
|
b, d.h[7] = consumeUint32(b)
|
||||||
|
b = b[copy(d.x[:], b):]
|
||||||
|
b, n := consumeUint64(b)
|
||||||
|
d.nl = uint32(n << 3)
|
||||||
|
d.nh = uint32(n >> 29)
|
||||||
|
d.nx = uint32(n) % 64
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *sha256Hash) UnmarshalBinary(b []byte) error {
|
||||||
|
if len(b) < len(magic256) || string(b[:len(magic256)]) != magic256 {
|
||||||
|
return errors.New("crypto/sha256: invalid hash state identifier")
|
||||||
|
}
|
||||||
|
if len(b) != marshaledSize256 {
|
||||||
|
return errors.New("crypto/sha256: invalid hash state size")
|
||||||
|
}
|
||||||
|
d := (*sha256Ctx)(unsafe.Pointer(&h.ctx))
|
||||||
|
b = b[len(magic256):]
|
||||||
|
b, d.h[0] = consumeUint32(b)
|
||||||
|
b, d.h[1] = consumeUint32(b)
|
||||||
|
b, d.h[2] = consumeUint32(b)
|
||||||
|
b, d.h[3] = consumeUint32(b)
|
||||||
|
b, d.h[4] = consumeUint32(b)
|
||||||
|
b, d.h[5] = consumeUint32(b)
|
||||||
|
b, d.h[6] = consumeUint32(b)
|
||||||
|
b, d.h[7] = consumeUint32(b)
|
||||||
|
b = b[copy(d.x[:], b):]
|
||||||
|
b, n := consumeUint64(b)
|
||||||
|
d.nl = uint32(n << 3)
|
||||||
|
d.nh = uint32(n >> 29)
|
||||||
|
d.nx = uint32(n) % 64
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// NewSHA384 returns a new SHA384 hash.
|
// NewSHA384 returns a new SHA384 hash.
|
||||||
func NewSHA384() hash.Hash {
|
func NewSHA384() hash.Hash {
|
||||||
h := new(sha384Hash)
|
h := new(sha384Hash)
|
||||||
|
|
@ -175,3 +324,157 @@ func (h0 *sha512Hash) sum() []byte {
|
||||||
}
|
}
|
||||||
return h.out[:]
|
return h.out[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type sha512Ctx struct {
|
||||||
|
h [8]uint64
|
||||||
|
nl, nh uint64
|
||||||
|
x [128]byte
|
||||||
|
nx uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
magic384 = "sha\x04"
|
||||||
|
magic512_224 = "sha\x05"
|
||||||
|
magic512_256 = "sha\x06"
|
||||||
|
magic512 = "sha\x07"
|
||||||
|
marshaledSize512 = len(magic512) + 8*8 + 128 + 8
|
||||||
|
)
|
||||||
|
|
||||||
|
var zero [128]byte
|
||||||
|
|
||||||
|
func (h *sha384Hash) MarshalBinary() ([]byte, error) {
|
||||||
|
d := (*sha512Ctx)(unsafe.Pointer(&h.ctx))
|
||||||
|
b := make([]byte, 0, marshaledSize512)
|
||||||
|
b = append(b, magic384...)
|
||||||
|
b = appendUint64(b, d.h[0])
|
||||||
|
b = appendUint64(b, d.h[1])
|
||||||
|
b = appendUint64(b, d.h[2])
|
||||||
|
b = appendUint64(b, d.h[3])
|
||||||
|
b = appendUint64(b, d.h[4])
|
||||||
|
b = appendUint64(b, d.h[5])
|
||||||
|
b = appendUint64(b, d.h[6])
|
||||||
|
b = appendUint64(b, d.h[7])
|
||||||
|
b = append(b, d.x[:d.nx]...)
|
||||||
|
b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
|
||||||
|
b = appendUint64(b, d.nl>>3|d.nh<<61)
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *sha512Hash) MarshalBinary() ([]byte, error) {
|
||||||
|
d := (*sha512Ctx)(unsafe.Pointer(&h.ctx))
|
||||||
|
b := make([]byte, 0, marshaledSize512)
|
||||||
|
b = append(b, magic512...)
|
||||||
|
b = appendUint64(b, d.h[0])
|
||||||
|
b = appendUint64(b, d.h[1])
|
||||||
|
b = appendUint64(b, d.h[2])
|
||||||
|
b = appendUint64(b, d.h[3])
|
||||||
|
b = appendUint64(b, d.h[4])
|
||||||
|
b = appendUint64(b, d.h[5])
|
||||||
|
b = appendUint64(b, d.h[6])
|
||||||
|
b = appendUint64(b, d.h[7])
|
||||||
|
b = append(b, d.x[:d.nx]...)
|
||||||
|
b = b[:len(b)+len(d.x)-int(d.nx)] // already zero
|
||||||
|
b = appendUint64(b, d.nl>>3|d.nh<<61)
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *sha384Hash) UnmarshalBinary(b []byte) error {
|
||||||
|
if len(b) < len(magic512) {
|
||||||
|
return errors.New("crypto/sha512: invalid hash state identifier")
|
||||||
|
}
|
||||||
|
if string(b[:len(magic384)]) != magic384 {
|
||||||
|
return errors.New("crypto/sha512: invalid hash state identifier")
|
||||||
|
}
|
||||||
|
if len(b) != marshaledSize512 {
|
||||||
|
return errors.New("crypto/sha512: invalid hash state size")
|
||||||
|
}
|
||||||
|
d := (*sha512Ctx)(unsafe.Pointer(&h.ctx))
|
||||||
|
b = b[len(magic512):]
|
||||||
|
b, d.h[0] = consumeUint64(b)
|
||||||
|
b, d.h[1] = consumeUint64(b)
|
||||||
|
b, d.h[2] = consumeUint64(b)
|
||||||
|
b, d.h[3] = consumeUint64(b)
|
||||||
|
b, d.h[4] = consumeUint64(b)
|
||||||
|
b, d.h[5] = consumeUint64(b)
|
||||||
|
b, d.h[6] = consumeUint64(b)
|
||||||
|
b, d.h[7] = consumeUint64(b)
|
||||||
|
b = b[copy(d.x[:], b):]
|
||||||
|
b, n := consumeUint64(b)
|
||||||
|
d.nl = n << 3
|
||||||
|
d.nh = n >> 61
|
||||||
|
d.nx = uint32(n) % 128
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *sha512Hash) UnmarshalBinary(b []byte) error {
|
||||||
|
if len(b) < len(magic512) {
|
||||||
|
return errors.New("crypto/sha512: invalid hash state identifier")
|
||||||
|
}
|
||||||
|
if string(b[:len(magic512)]) != magic512 {
|
||||||
|
return errors.New("crypto/sha512: invalid hash state identifier")
|
||||||
|
}
|
||||||
|
if len(b) != marshaledSize512 {
|
||||||
|
return errors.New("crypto/sha512: invalid hash state size")
|
||||||
|
}
|
||||||
|
d := (*sha512Ctx)(unsafe.Pointer(&h.ctx))
|
||||||
|
b = b[len(magic512):]
|
||||||
|
b, d.h[0] = consumeUint64(b)
|
||||||
|
b, d.h[1] = consumeUint64(b)
|
||||||
|
b, d.h[2] = consumeUint64(b)
|
||||||
|
b, d.h[3] = consumeUint64(b)
|
||||||
|
b, d.h[4] = consumeUint64(b)
|
||||||
|
b, d.h[5] = consumeUint64(b)
|
||||||
|
b, d.h[6] = consumeUint64(b)
|
||||||
|
b, d.h[7] = consumeUint64(b)
|
||||||
|
b = b[copy(d.x[:], b):]
|
||||||
|
b, n := consumeUint64(b)
|
||||||
|
d.nl = n << 3
|
||||||
|
d.nh = n >> 61
|
||||||
|
d.nx = uint32(n) % 128
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendUint64(b []byte, x uint64) []byte {
|
||||||
|
var a [8]byte
|
||||||
|
putUint64(a[:], x)
|
||||||
|
return append(b, a[:]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func appendUint32(b []byte, x uint32) []byte {
|
||||||
|
var a [4]byte
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
func putUint64(x []byte, s uint64) {
|
||||||
|
_ = x[7]
|
||||||
|
x[0] = byte(s >> 56)
|
||||||
|
x[1] = byte(s >> 48)
|
||||||
|
x[2] = byte(s >> 40)
|
||||||
|
x[3] = byte(s >> 32)
|
||||||
|
x[4] = byte(s >> 24)
|
||||||
|
x[5] = byte(s >> 16)
|
||||||
|
x[6] = byte(s >> 8)
|
||||||
|
x[7] = byte(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func putUint32(x []byte, s uint32) {
|
||||||
|
_ = x[3]
|
||||||
|
x[0] = byte(s >> 24)
|
||||||
|
x[1] = byte(s >> 16)
|
||||||
|
x[2] = byte(s >> 8)
|
||||||
|
x[3] = byte(s)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue