Source file src/crypto/internal/boring/sha.go

     1  // Copyright 2017 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build boringcrypto && linux && (amd64 || arm64) && !android && !msan
     6  
     7  package boring
     8  
     9  /*
    10  #include "goboringcrypto.h"
    11  
    12  int
    13  _goboringcrypto_gosha1(void *p, size_t n, void *out)
    14  {
    15  	GO_SHA_CTX ctx;
    16  	_goboringcrypto_SHA1_Init(&ctx);
    17  	return _goboringcrypto_SHA1_Update(&ctx, p, n) &&
    18  		_goboringcrypto_SHA1_Final(out, &ctx);
    19  }
    20  
    21  int
    22  _goboringcrypto_gosha224(void *p, size_t n, void *out)
    23  {
    24  	GO_SHA256_CTX ctx;
    25  	_goboringcrypto_SHA224_Init(&ctx);
    26  	return _goboringcrypto_SHA224_Update(&ctx, p, n) &&
    27  		_goboringcrypto_SHA224_Final(out, &ctx);
    28  }
    29  
    30  int
    31  _goboringcrypto_gosha256(void *p, size_t n, void *out)
    32  {
    33  	GO_SHA256_CTX ctx;
    34  	_goboringcrypto_SHA256_Init(&ctx);
    35  	return _goboringcrypto_SHA256_Update(&ctx, p, n) &&
    36  		_goboringcrypto_SHA256_Final(out, &ctx);
    37  }
    38  
    39  int
    40  _goboringcrypto_gosha384(void *p, size_t n, void *out)
    41  {
    42  	GO_SHA512_CTX ctx;
    43  	_goboringcrypto_SHA384_Init(&ctx);
    44  	return _goboringcrypto_SHA384_Update(&ctx, p, n) &&
    45  		_goboringcrypto_SHA384_Final(out, &ctx);
    46  }
    47  
    48  int
    49  _goboringcrypto_gosha512(void *p, size_t n, void *out)
    50  {
    51  	GO_SHA512_CTX ctx;
    52  	_goboringcrypto_SHA512_Init(&ctx);
    53  	return _goboringcrypto_SHA512_Update(&ctx, p, n) &&
    54  		_goboringcrypto_SHA512_Final(out, &ctx);
    55  }
    56  
    57  */
    58  import "C"
    59  import (
    60  	"errors"
    61  	"hash"
    62  	"internal/byteorder"
    63  	"unsafe"
    64  )
    65  
    66  // NOTE: The cgo calls in this file are arranged to avoid marking the parameters as escaping.
    67  // To do that, we call noescape (including via addr).
    68  // We must also make sure that the data pointer arguments have the form unsafe.Pointer(&...)
    69  // so that cgo does not annotate them with cgoCheckPointer calls. If it did that, it might look
    70  // beyond the byte slice and find Go pointers in unprocessed parts of a larger allocation.
    71  // To do both of these simultaneously, the idiom is unsafe.Pointer(&*addr(p)),
    72  // where addr returns the base pointer of p, substituting a non-nil pointer for nil,
    73  // and applying a noescape along the way.
    74  // This is all to preserve compatibility with the allocation behavior of the non-boring implementations.
    75  
    76  func SHA1(p []byte) (sum [20]byte) {
    77  	if C._goboringcrypto_gosha1(unsafe.Pointer(&*addr(p)), C.size_t(len(p)), unsafe.Pointer(&*addr(sum[:]))) == 0 {
    78  		panic("boringcrypto: SHA1 failed")
    79  	}
    80  	return
    81  }
    82  
    83  func SHA224(p []byte) (sum [28]byte) {
    84  	if C._goboringcrypto_gosha224(unsafe.Pointer(&*addr(p)), C.size_t(len(p)), unsafe.Pointer(&*addr(sum[:]))) == 0 {
    85  		panic("boringcrypto: SHA224 failed")
    86  	}
    87  	return
    88  }
    89  
    90  func SHA256(p []byte) (sum [32]byte) {
    91  	if C._goboringcrypto_gosha256(unsafe.Pointer(&*addr(p)), C.size_t(len(p)), unsafe.Pointer(&*addr(sum[:]))) == 0 {
    92  		panic("boringcrypto: SHA256 failed")
    93  	}
    94  	return
    95  }
    96  
    97  func SHA384(p []byte) (sum [48]byte) {
    98  	if C._goboringcrypto_gosha384(unsafe.Pointer(&*addr(p)), C.size_t(len(p)), unsafe.Pointer(&*addr(sum[:]))) == 0 {
    99  		panic("boringcrypto: SHA384 failed")
   100  	}
   101  	return
   102  }
   103  
   104  func SHA512(p []byte) (sum [64]byte) {
   105  	if C._goboringcrypto_gosha512(unsafe.Pointer(&*addr(p)), C.size_t(len(p)), unsafe.Pointer(&*addr(sum[:]))) == 0 {
   106  		panic("boringcrypto: SHA512 failed")
   107  	}
   108  	return
   109  }
   110  
   111  // NewSHA1 returns a new SHA1 hash.
   112  func NewSHA1() hash.Hash {
   113  	h := new(sha1Hash)
   114  	h.Reset()
   115  	return h
   116  }
   117  
   118  type sha1Hash struct {
   119  	ctx C.GO_SHA_CTX
   120  	out [20]byte
   121  }
   122  
   123  type sha1Ctx struct {
   124  	h      [5]uint32
   125  	nl, nh uint32
   126  	x      [64]byte
   127  	nx     uint32
   128  }
   129  
   130  func (h *sha1Hash) noescapeCtx() *C.GO_SHA_CTX {
   131  	return (*C.GO_SHA_CTX)(noescape(unsafe.Pointer(&h.ctx)))
   132  }
   133  
   134  func (h *sha1Hash) Reset() {
   135  	C._goboringcrypto_SHA1_Init(h.noescapeCtx())
   136  }
   137  
   138  func (h *sha1Hash) Size() int             { return 20 }
   139  func (h *sha1Hash) BlockSize() int        { return 64 }
   140  func (h *sha1Hash) Sum(dst []byte) []byte { return h.sum(dst) }
   141  
   142  func (h *sha1Hash) Write(p []byte) (int, error) {
   143  	if len(p) > 0 && C._goboringcrypto_SHA1_Update(h.noescapeCtx(), unsafe.Pointer(&*addr(p)), C.size_t(len(p))) == 0 {
   144  		panic("boringcrypto: SHA1_Update failed")
   145  	}
   146  	return len(p), nil
   147  }
   148  
   149  func (h0 *sha1Hash) sum(dst []byte) []byte {
   150  	h := *h0 // make copy so future Write+Sum is valid
   151  	if C._goboringcrypto_SHA1_Final((*C.uint8_t)(noescape(unsafe.Pointer(&h.out[0]))), h.noescapeCtx()) == 0 {
   152  		panic("boringcrypto: SHA1_Final failed")
   153  	}
   154  	return append(dst, h.out[:]...)
   155  }
   156  
   157  const (
   158  	sha1Magic         = "sha\x01"
   159  	sha1MarshaledSize = len(sha1Magic) + 5*4 + 64 + 8
   160  )
   161  
   162  func (h *sha1Hash) MarshalBinary() ([]byte, error) {
   163  	return h.AppendBinary(make([]byte, 0, sha1MarshaledSize))
   164  }
   165  
   166  func (h *sha1Hash) AppendBinary(b []byte) ([]byte, error) {
   167  	d := (*sha1Ctx)(unsafe.Pointer(&h.ctx))
   168  	b = append(b, sha1Magic...)
   169  	b = byteorder.BeAppendUint32(b, d.h[0])
   170  	b = byteorder.BeAppendUint32(b, d.h[1])
   171  	b = byteorder.BeAppendUint32(b, d.h[2])
   172  	b = byteorder.BeAppendUint32(b, d.h[3])
   173  	b = byteorder.BeAppendUint32(b, d.h[4])
   174  	b = append(b, d.x[:d.nx]...)
   175  	b = append(b, make([]byte, len(d.x)-int(d.nx))...)
   176  	b = byteorder.BeAppendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29)
   177  	return b, nil
   178  }
   179  
   180  func (h *sha1Hash) UnmarshalBinary(b []byte) error {
   181  	if len(b) < len(sha1Magic) || string(b[:len(sha1Magic)]) != sha1Magic {
   182  		return errors.New("crypto/sha1: invalid hash state identifier")
   183  	}
   184  	if len(b) != sha1MarshaledSize {
   185  		return errors.New("crypto/sha1: invalid hash state size")
   186  	}
   187  	d := (*sha1Ctx)(unsafe.Pointer(&h.ctx))
   188  	b = b[len(sha1Magic):]
   189  	b, d.h[0] = consumeUint32(b)
   190  	b, d.h[1] = consumeUint32(b)
   191  	b, d.h[2] = consumeUint32(b)
   192  	b, d.h[3] = consumeUint32(b)
   193  	b, d.h[4] = consumeUint32(b)
   194  	b = b[copy(d.x[:], b):]
   195  	b, n := consumeUint64(b)
   196  	d.nl = uint32(n << 3)
   197  	d.nh = uint32(n >> 29)
   198  	d.nx = uint32(n) % 64
   199  	return nil
   200  }
   201  
   202  // NewSHA224 returns a new SHA224 hash.
   203  func NewSHA224() hash.Hash {
   204  	h := new(sha224Hash)
   205  	h.Reset()
   206  	return h
   207  }
   208  
   209  type sha224Hash struct {
   210  	ctx C.GO_SHA256_CTX
   211  	out [224 / 8]byte
   212  }
   213  
   214  func (h *sha224Hash) noescapeCtx() *C.GO_SHA256_CTX {
   215  	return (*C.GO_SHA256_CTX)(noescape(unsafe.Pointer(&h.ctx)))
   216  }
   217  
   218  func (h *sha224Hash) Reset() {
   219  	C._goboringcrypto_SHA224_Init(h.noescapeCtx())
   220  }
   221  func (h *sha224Hash) Size() int             { return 224 / 8 }
   222  func (h *sha224Hash) BlockSize() int        { return 64 }
   223  func (h *sha224Hash) Sum(dst []byte) []byte { return h.sum(dst) }
   224  
   225  func (h *sha224Hash) Write(p []byte) (int, error) {
   226  	if len(p) > 0 && C._goboringcrypto_SHA224_Update(h.noescapeCtx(), unsafe.Pointer(&*addr(p)), C.size_t(len(p))) == 0 {
   227  		panic("boringcrypto: SHA224_Update failed")
   228  	}
   229  	return len(p), nil
   230  }
   231  
   232  func (h0 *sha224Hash) sum(dst []byte) []byte {
   233  	h := *h0 // make copy so future Write+Sum is valid
   234  	if C._goboringcrypto_SHA224_Final((*C.uint8_t)(noescape(unsafe.Pointer(&h.out[0]))), h.noescapeCtx()) == 0 {
   235  		panic("boringcrypto: SHA224_Final failed")
   236  	}
   237  	return append(dst, h.out[:]...)
   238  }
   239  
   240  // NewSHA256 returns a new SHA256 hash.
   241  func NewSHA256() hash.Hash {
   242  	h := new(sha256Hash)
   243  	h.Reset()
   244  	return h
   245  }
   246  
   247  type sha256Hash struct {
   248  	ctx C.GO_SHA256_CTX
   249  	out [256 / 8]byte
   250  }
   251  
   252  func (h *sha256Hash) noescapeCtx() *C.GO_SHA256_CTX {
   253  	return (*C.GO_SHA256_CTX)(noescape(unsafe.Pointer(&h.ctx)))
   254  }
   255  
   256  func (h *sha256Hash) Reset() {
   257  	C._goboringcrypto_SHA256_Init(h.noescapeCtx())
   258  }
   259  func (h *sha256Hash) Size() int             { return 256 / 8 }
   260  func (h *sha256Hash) BlockSize() int        { return 64 }
   261  func (h *sha256Hash) Sum(dst []byte) []byte { return h.sum(dst) }
   262  
   263  func (h *sha256Hash) Write(p []byte) (int, error) {
   264  	if len(p) > 0 && C._goboringcrypto_SHA256_Update(h.noescapeCtx(), unsafe.Pointer(&*addr(p)), C.size_t(len(p))) == 0 {
   265  		panic("boringcrypto: SHA256_Update failed")
   266  	}
   267  	return len(p), nil
   268  }
   269  
   270  func (h0 *sha256Hash) sum(dst []byte) []byte {
   271  	h := *h0 // make copy so future Write+Sum is valid
   272  	if C._goboringcrypto_SHA256_Final((*C.uint8_t)(noescape(unsafe.Pointer(&h.out[0]))), h.noescapeCtx()) == 0 {
   273  		panic("boringcrypto: SHA256_Final failed")
   274  	}
   275  	return append(dst, h.out[:]...)
   276  }
   277  
   278  const (
   279  	magic224         = "sha\x02"
   280  	magic256         = "sha\x03"
   281  	marshaledSize256 = len(magic256) + 8*4 + 64 + 8
   282  )
   283  
   284  type sha256Ctx struct {
   285  	h      [8]uint32
   286  	nl, nh uint32
   287  	x      [64]byte
   288  	nx     uint32
   289  }
   290  
   291  func (h *sha224Hash) MarshalBinary() ([]byte, error) {
   292  	return h.AppendBinary(make([]byte, 0, marshaledSize256))
   293  }
   294  
   295  func (h *sha224Hash) AppendBinary(b []byte) ([]byte, error) {
   296  	d := (*sha256Ctx)(unsafe.Pointer(&h.ctx))
   297  	b = append(b, magic224...)
   298  	b = byteorder.BeAppendUint32(b, d.h[0])
   299  	b = byteorder.BeAppendUint32(b, d.h[1])
   300  	b = byteorder.BeAppendUint32(b, d.h[2])
   301  	b = byteorder.BeAppendUint32(b, d.h[3])
   302  	b = byteorder.BeAppendUint32(b, d.h[4])
   303  	b = byteorder.BeAppendUint32(b, d.h[5])
   304  	b = byteorder.BeAppendUint32(b, d.h[6])
   305  	b = byteorder.BeAppendUint32(b, d.h[7])
   306  	b = append(b, d.x[:d.nx]...)
   307  	b = append(b, make([]byte, len(d.x)-int(d.nx))...)
   308  	b = byteorder.BeAppendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29)
   309  	return b, nil
   310  }
   311  
   312  func (h *sha256Hash) MarshalBinary() ([]byte, error) {
   313  	return h.AppendBinary(make([]byte, 0, marshaledSize256))
   314  }
   315  
   316  func (h *sha256Hash) AppendBinary(b []byte) ([]byte, error) {
   317  	d := (*sha256Ctx)(unsafe.Pointer(&h.ctx))
   318  	b = append(b, magic256...)
   319  	b = byteorder.BeAppendUint32(b, d.h[0])
   320  	b = byteorder.BeAppendUint32(b, d.h[1])
   321  	b = byteorder.BeAppendUint32(b, d.h[2])
   322  	b = byteorder.BeAppendUint32(b, d.h[3])
   323  	b = byteorder.BeAppendUint32(b, d.h[4])
   324  	b = byteorder.BeAppendUint32(b, d.h[5])
   325  	b = byteorder.BeAppendUint32(b, d.h[6])
   326  	b = byteorder.BeAppendUint32(b, d.h[7])
   327  	b = append(b, d.x[:d.nx]...)
   328  	b = append(b, make([]byte, len(d.x)-int(d.nx))...)
   329  	b = byteorder.BeAppendUint64(b, uint64(d.nl)>>3|uint64(d.nh)<<29)
   330  	return b, nil
   331  }
   332  
   333  func (h *sha224Hash) UnmarshalBinary(b []byte) error {
   334  	if len(b) < len(magic224) || string(b[:len(magic224)]) != magic224 {
   335  		return errors.New("crypto/sha256: invalid hash state identifier")
   336  	}
   337  	if len(b) != marshaledSize256 {
   338  		return errors.New("crypto/sha256: invalid hash state size")
   339  	}
   340  	d := (*sha256Ctx)(unsafe.Pointer(&h.ctx))
   341  	b = b[len(magic224):]
   342  	b, d.h[0] = consumeUint32(b)
   343  	b, d.h[1] = consumeUint32(b)
   344  	b, d.h[2] = consumeUint32(b)
   345  	b, d.h[3] = consumeUint32(b)
   346  	b, d.h[4] = consumeUint32(b)
   347  	b, d.h[5] = consumeUint32(b)
   348  	b, d.h[6] = consumeUint32(b)
   349  	b, d.h[7] = consumeUint32(b)
   350  	b = b[copy(d.x[:], b):]
   351  	b, n := consumeUint64(b)
   352  	d.nl = uint32(n << 3)
   353  	d.nh = uint32(n >> 29)
   354  	d.nx = uint32(n) % 64
   355  	return nil
   356  }
   357  
   358  func (h *sha256Hash) UnmarshalBinary(b []byte) error {
   359  	if len(b) < len(magic256) || string(b[:len(magic256)]) != magic256 {
   360  		return errors.New("crypto/sha256: invalid hash state identifier")
   361  	}
   362  	if len(b) != marshaledSize256 {
   363  		return errors.New("crypto/sha256: invalid hash state size")
   364  	}
   365  	d := (*sha256Ctx)(unsafe.Pointer(&h.ctx))
   366  	b = b[len(magic256):]
   367  	b, d.h[0] = consumeUint32(b)
   368  	b, d.h[1] = consumeUint32(b)
   369  	b, d.h[2] = consumeUint32(b)
   370  	b, d.h[3] = consumeUint32(b)
   371  	b, d.h[4] = consumeUint32(b)
   372  	b, d.h[5] = consumeUint32(b)
   373  	b, d.h[6] = consumeUint32(b)
   374  	b, d.h[7] = consumeUint32(b)
   375  	b = b[copy(d.x[:], b):]
   376  	b, n := consumeUint64(b)
   377  	d.nl = uint32(n << 3)
   378  	d.nh = uint32(n >> 29)
   379  	d.nx = uint32(n) % 64
   380  	return nil
   381  }
   382  
   383  // NewSHA384 returns a new SHA384 hash.
   384  func NewSHA384() hash.Hash {
   385  	h := new(sha384Hash)
   386  	h.Reset()
   387  	return h
   388  }
   389  
   390  type sha384Hash struct {
   391  	ctx C.GO_SHA512_CTX
   392  	out [384 / 8]byte
   393  }
   394  
   395  func (h *sha384Hash) noescapeCtx() *C.GO_SHA512_CTX {
   396  	return (*C.GO_SHA512_CTX)(noescape(unsafe.Pointer(&h.ctx)))
   397  }
   398  
   399  func (h *sha384Hash) Reset() {
   400  	C._goboringcrypto_SHA384_Init(h.noescapeCtx())
   401  }
   402  func (h *sha384Hash) Size() int             { return 384 / 8 }
   403  func (h *sha384Hash) BlockSize() int        { return 128 }
   404  func (h *sha384Hash) Sum(dst []byte) []byte { return h.sum(dst) }
   405  
   406  func (h *sha384Hash) Write(p []byte) (int, error) {
   407  	if len(p) > 0 && C._goboringcrypto_SHA384_Update(h.noescapeCtx(), unsafe.Pointer(&*addr(p)), C.size_t(len(p))) == 0 {
   408  		panic("boringcrypto: SHA384_Update failed")
   409  	}
   410  	return len(p), nil
   411  }
   412  
   413  func (h0 *sha384Hash) sum(dst []byte) []byte {
   414  	h := *h0 // make copy so future Write+Sum is valid
   415  	if C._goboringcrypto_SHA384_Final((*C.uint8_t)(noescape(unsafe.Pointer(&h.out[0]))), h.noescapeCtx()) == 0 {
   416  		panic("boringcrypto: SHA384_Final failed")
   417  	}
   418  	return append(dst, h.out[:]...)
   419  }
   420  
   421  // NewSHA512 returns a new SHA512 hash.
   422  func NewSHA512() hash.Hash {
   423  	h := new(sha512Hash)
   424  	h.Reset()
   425  	return h
   426  }
   427  
   428  type sha512Hash struct {
   429  	ctx C.GO_SHA512_CTX
   430  	out [512 / 8]byte
   431  }
   432  
   433  func (h *sha512Hash) noescapeCtx() *C.GO_SHA512_CTX {
   434  	return (*C.GO_SHA512_CTX)(noescape(unsafe.Pointer(&h.ctx)))
   435  }
   436  
   437  func (h *sha512Hash) Reset() {
   438  	C._goboringcrypto_SHA512_Init(h.noescapeCtx())
   439  }
   440  func (h *sha512Hash) Size() int             { return 512 / 8 }
   441  func (h *sha512Hash) BlockSize() int        { return 128 }
   442  func (h *sha512Hash) Sum(dst []byte) []byte { return h.sum(dst) }
   443  
   444  func (h *sha512Hash) Write(p []byte) (int, error) {
   445  	if len(p) > 0 && C._goboringcrypto_SHA512_Update(h.noescapeCtx(), unsafe.Pointer(&*addr(p)), C.size_t(len(p))) == 0 {
   446  		panic("boringcrypto: SHA512_Update failed")
   447  	}
   448  	return len(p), nil
   449  }
   450  
   451  func (h0 *sha512Hash) sum(dst []byte) []byte {
   452  	h := *h0 // make copy so future Write+Sum is valid
   453  	if C._goboringcrypto_SHA512_Final((*C.uint8_t)(noescape(unsafe.Pointer(&h.out[0]))), h.noescapeCtx()) == 0 {
   454  		panic("boringcrypto: SHA512_Final failed")
   455  	}
   456  	return append(dst, h.out[:]...)
   457  }
   458  
   459  type sha512Ctx struct {
   460  	h      [8]uint64
   461  	nl, nh uint64
   462  	x      [128]byte
   463  	nx     uint32
   464  }
   465  
   466  const (
   467  	magic384         = "sha\x04"
   468  	magic512_224     = "sha\x05"
   469  	magic512_256     = "sha\x06"
   470  	magic512         = "sha\x07"
   471  	marshaledSize512 = len(magic512) + 8*8 + 128 + 8
   472  )
   473  
   474  func (h *sha384Hash) MarshalBinary() ([]byte, error) {
   475  	return h.AppendBinary(make([]byte, 0, marshaledSize512))
   476  }
   477  
   478  func (h *sha384Hash) AppendBinary(b []byte) ([]byte, error) {
   479  	d := (*sha512Ctx)(unsafe.Pointer(&h.ctx))
   480  	b = append(b, magic384...)
   481  	b = byteorder.BeAppendUint64(b, d.h[0])
   482  	b = byteorder.BeAppendUint64(b, d.h[1])
   483  	b = byteorder.BeAppendUint64(b, d.h[2])
   484  	b = byteorder.BeAppendUint64(b, d.h[3])
   485  	b = byteorder.BeAppendUint64(b, d.h[4])
   486  	b = byteorder.BeAppendUint64(b, d.h[5])
   487  	b = byteorder.BeAppendUint64(b, d.h[6])
   488  	b = byteorder.BeAppendUint64(b, d.h[7])
   489  	b = append(b, d.x[:d.nx]...)
   490  	b = append(b, make([]byte, len(d.x)-int(d.nx))...)
   491  	b = byteorder.BeAppendUint64(b, d.nl>>3|d.nh<<61)
   492  	return b, nil
   493  }
   494  
   495  func (h *sha512Hash) MarshalBinary() ([]byte, error) {
   496  	return h.AppendBinary(make([]byte, 0, marshaledSize512))
   497  }
   498  
   499  func (h *sha512Hash) AppendBinary(b []byte) ([]byte, error) {
   500  	d := (*sha512Ctx)(unsafe.Pointer(&h.ctx))
   501  	b = append(b, magic512...)
   502  	b = byteorder.BeAppendUint64(b, d.h[0])
   503  	b = byteorder.BeAppendUint64(b, d.h[1])
   504  	b = byteorder.BeAppendUint64(b, d.h[2])
   505  	b = byteorder.BeAppendUint64(b, d.h[3])
   506  	b = byteorder.BeAppendUint64(b, d.h[4])
   507  	b = byteorder.BeAppendUint64(b, d.h[5])
   508  	b = byteorder.BeAppendUint64(b, d.h[6])
   509  	b = byteorder.BeAppendUint64(b, d.h[7])
   510  	b = append(b, d.x[:d.nx]...)
   511  	b = append(b, make([]byte, len(d.x)-int(d.nx))...)
   512  	b = byteorder.BeAppendUint64(b, d.nl>>3|d.nh<<61)
   513  	return b, nil
   514  }
   515  
   516  func (h *sha384Hash) UnmarshalBinary(b []byte) error {
   517  	if len(b) < len(magic512) {
   518  		return errors.New("crypto/sha512: invalid hash state identifier")
   519  	}
   520  	if string(b[:len(magic384)]) != magic384 {
   521  		return errors.New("crypto/sha512: invalid hash state identifier")
   522  	}
   523  	if len(b) != marshaledSize512 {
   524  		return errors.New("crypto/sha512: invalid hash state size")
   525  	}
   526  	d := (*sha512Ctx)(unsafe.Pointer(&h.ctx))
   527  	b = b[len(magic512):]
   528  	b, d.h[0] = consumeUint64(b)
   529  	b, d.h[1] = consumeUint64(b)
   530  	b, d.h[2] = consumeUint64(b)
   531  	b, d.h[3] = consumeUint64(b)
   532  	b, d.h[4] = consumeUint64(b)
   533  	b, d.h[5] = consumeUint64(b)
   534  	b, d.h[6] = consumeUint64(b)
   535  	b, d.h[7] = consumeUint64(b)
   536  	b = b[copy(d.x[:], b):]
   537  	b, n := consumeUint64(b)
   538  	d.nl = n << 3
   539  	d.nh = n >> 61
   540  	d.nx = uint32(n) % 128
   541  	return nil
   542  }
   543  
   544  func (h *sha512Hash) UnmarshalBinary(b []byte) error {
   545  	if len(b) < len(magic512) {
   546  		return errors.New("crypto/sha512: invalid hash state identifier")
   547  	}
   548  	if string(b[:len(magic512)]) != magic512 {
   549  		return errors.New("crypto/sha512: invalid hash state identifier")
   550  	}
   551  	if len(b) != marshaledSize512 {
   552  		return errors.New("crypto/sha512: invalid hash state size")
   553  	}
   554  	d := (*sha512Ctx)(unsafe.Pointer(&h.ctx))
   555  	b = b[len(magic512):]
   556  	b, d.h[0] = consumeUint64(b)
   557  	b, d.h[1] = consumeUint64(b)
   558  	b, d.h[2] = consumeUint64(b)
   559  	b, d.h[3] = consumeUint64(b)
   560  	b, d.h[4] = consumeUint64(b)
   561  	b, d.h[5] = consumeUint64(b)
   562  	b, d.h[6] = consumeUint64(b)
   563  	b, d.h[7] = consumeUint64(b)
   564  	b = b[copy(d.x[:], b):]
   565  	b, n := consumeUint64(b)
   566  	d.nl = n << 3
   567  	d.nh = n >> 61
   568  	d.nx = uint32(n) % 128
   569  	return nil
   570  }
   571  
   572  func consumeUint64(b []byte) ([]byte, uint64) {
   573  	return b[8:], byteorder.BeUint64(b)
   574  }
   575  
   576  func consumeUint32(b []byte) ([]byte, uint32) {
   577  	return b[4:], byteorder.BeUint32(b)
   578  }
   579  

View as plain text