Source file src/crypto/internal/fips140/entropy/sha384.go

     1  // Copyright 2025 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  package entropy
     6  
     7  import "math/bits"
     8  
     9  // This file includes a SHA-384 implementation to insulate the entropy source
    10  // from any changes in the FIPS 140-3 module's crypto/internal/fips140/sha512
    11  // package. We support 1024-byte inputs for the entropy source, and arbitrary
    12  // length inputs for ACVP testing.
    13  
    14  var initState = [8]uint64{
    15  	0xcbbb9d5dc1059ed8,
    16  	0x629a292a367cd507,
    17  	0x9159015a3070dd17,
    18  	0x152fecd8f70e5939,
    19  	0x67332667ffc00b31,
    20  	0x8eb44a8768581511,
    21  	0xdb0c2e0d64f98fa7,
    22  	0x47b5481dbefa4fa4,
    23  }
    24  
    25  func SHA384(p *[1024]byte) [48]byte {
    26  	h := initState
    27  
    28  	sha384Block(&h, (*[128]byte)(p[0:128]))
    29  	sha384Block(&h, (*[128]byte)(p[128:256]))
    30  	sha384Block(&h, (*[128]byte)(p[256:384]))
    31  	sha384Block(&h, (*[128]byte)(p[384:512]))
    32  	sha384Block(&h, (*[128]byte)(p[512:640]))
    33  	sha384Block(&h, (*[128]byte)(p[640:768]))
    34  	sha384Block(&h, (*[128]byte)(p[768:896]))
    35  	sha384Block(&h, (*[128]byte)(p[896:1024]))
    36  
    37  	var padlen [128]byte
    38  	padlen[0] = 0x80
    39  	bePutUint64(padlen[112+8:], 1024*8)
    40  	sha384Block(&h, &padlen)
    41  
    42  	return digestBytes(&h)
    43  }
    44  
    45  func TestingOnlySHA384(p []byte) [48]byte {
    46  	if len(p) == 1024 {
    47  		return SHA384((*[1024]byte)(p))
    48  	}
    49  
    50  	h := initState
    51  	bitLen := uint64(len(p)) * 8
    52  
    53  	// Process full 128-byte blocks.
    54  	for len(p) >= 128 {
    55  		sha384Block(&h, (*[128]byte)(p[:128]))
    56  		p = p[128:]
    57  	}
    58  
    59  	// Process final block and padding.
    60  	var finalBlock [128]byte
    61  	copy(finalBlock[:], p)
    62  	finalBlock[len(p)] = 0x80
    63  	if len(p) >= 112 {
    64  		sha384Block(&h, &finalBlock)
    65  		finalBlock = [128]byte{}
    66  	}
    67  	bePutUint64(finalBlock[112+8:], bitLen)
    68  	sha384Block(&h, &finalBlock)
    69  
    70  	return digestBytes(&h)
    71  }
    72  
    73  func digestBytes(h *[8]uint64) [48]byte {
    74  	var digest [48]byte
    75  	bePutUint64(digest[0:], h[0])
    76  	bePutUint64(digest[8:], h[1])
    77  	bePutUint64(digest[16:], h[2])
    78  	bePutUint64(digest[24:], h[3])
    79  	bePutUint64(digest[32:], h[4])
    80  	bePutUint64(digest[40:], h[5])
    81  	return digest
    82  }
    83  
    84  var _K = [...]uint64{
    85  	0x428a2f98d728ae22,
    86  	0x7137449123ef65cd,
    87  	0xb5c0fbcfec4d3b2f,
    88  	0xe9b5dba58189dbbc,
    89  	0x3956c25bf348b538,
    90  	0x59f111f1b605d019,
    91  	0x923f82a4af194f9b,
    92  	0xab1c5ed5da6d8118,
    93  	0xd807aa98a3030242,
    94  	0x12835b0145706fbe,
    95  	0x243185be4ee4b28c,
    96  	0x550c7dc3d5ffb4e2,
    97  	0x72be5d74f27b896f,
    98  	0x80deb1fe3b1696b1,
    99  	0x9bdc06a725c71235,
   100  	0xc19bf174cf692694,
   101  	0xe49b69c19ef14ad2,
   102  	0xefbe4786384f25e3,
   103  	0x0fc19dc68b8cd5b5,
   104  	0x240ca1cc77ac9c65,
   105  	0x2de92c6f592b0275,
   106  	0x4a7484aa6ea6e483,
   107  	0x5cb0a9dcbd41fbd4,
   108  	0x76f988da831153b5,
   109  	0x983e5152ee66dfab,
   110  	0xa831c66d2db43210,
   111  	0xb00327c898fb213f,
   112  	0xbf597fc7beef0ee4,
   113  	0xc6e00bf33da88fc2,
   114  	0xd5a79147930aa725,
   115  	0x06ca6351e003826f,
   116  	0x142929670a0e6e70,
   117  	0x27b70a8546d22ffc,
   118  	0x2e1b21385c26c926,
   119  	0x4d2c6dfc5ac42aed,
   120  	0x53380d139d95b3df,
   121  	0x650a73548baf63de,
   122  	0x766a0abb3c77b2a8,
   123  	0x81c2c92e47edaee6,
   124  	0x92722c851482353b,
   125  	0xa2bfe8a14cf10364,
   126  	0xa81a664bbc423001,
   127  	0xc24b8b70d0f89791,
   128  	0xc76c51a30654be30,
   129  	0xd192e819d6ef5218,
   130  	0xd69906245565a910,
   131  	0xf40e35855771202a,
   132  	0x106aa07032bbd1b8,
   133  	0x19a4c116b8d2d0c8,
   134  	0x1e376c085141ab53,
   135  	0x2748774cdf8eeb99,
   136  	0x34b0bcb5e19b48a8,
   137  	0x391c0cb3c5c95a63,
   138  	0x4ed8aa4ae3418acb,
   139  	0x5b9cca4f7763e373,
   140  	0x682e6ff3d6b2b8a3,
   141  	0x748f82ee5defb2fc,
   142  	0x78a5636f43172f60,
   143  	0x84c87814a1f0ab72,
   144  	0x8cc702081a6439ec,
   145  	0x90befffa23631e28,
   146  	0xa4506cebde82bde9,
   147  	0xbef9a3f7b2c67915,
   148  	0xc67178f2e372532b,
   149  	0xca273eceea26619c,
   150  	0xd186b8c721c0c207,
   151  	0xeada7dd6cde0eb1e,
   152  	0xf57d4f7fee6ed178,
   153  	0x06f067aa72176fba,
   154  	0x0a637dc5a2c898a6,
   155  	0x113f9804bef90dae,
   156  	0x1b710b35131c471b,
   157  	0x28db77f523047d84,
   158  	0x32caab7b40c72493,
   159  	0x3c9ebe0a15c9bebc,
   160  	0x431d67c49c100d4c,
   161  	0x4cc5d4becb3e42b6,
   162  	0x597f299cfc657e2a,
   163  	0x5fcb6fab3ad6faec,
   164  	0x6c44198c4a475817,
   165  }
   166  
   167  func sha384Block(dh *[8]uint64, p *[128]byte) {
   168  	var w [80]uint64
   169  	for i := range 80 {
   170  		if i < 16 {
   171  			w[i] = beUint64(p[i*8:])
   172  		} else {
   173  			v1 := w[i-2]
   174  			t1 := bits.RotateLeft64(v1, -19) ^ bits.RotateLeft64(v1, -61) ^ (v1 >> 6)
   175  			v2 := w[i-15]
   176  			t2 := bits.RotateLeft64(v2, -1) ^ bits.RotateLeft64(v2, -8) ^ (v2 >> 7)
   177  
   178  			w[i] = t1 + w[i-7] + t2 + w[i-16]
   179  		}
   180  	}
   181  
   182  	a, b, c, d, e, f, g, h := dh[0], dh[1], dh[2], dh[3], dh[4], dh[5], dh[6], dh[7]
   183  
   184  	for i := range 80 {
   185  		t1 := h + (bits.RotateLeft64(e, -14) ^ bits.RotateLeft64(e, -18) ^
   186  			bits.RotateLeft64(e, -41)) + ((e & f) ^ (^e & g)) + _K[i] + w[i]
   187  		t2 := (bits.RotateLeft64(a, -28) ^ bits.RotateLeft64(a, -34) ^
   188  			bits.RotateLeft64(a, -39)) + ((a & b) ^ (a & c) ^ (b & c))
   189  
   190  		h = g
   191  		g = f
   192  		f = e
   193  		e = d + t1
   194  		d = c
   195  		c = b
   196  		b = a
   197  		a = t1 + t2
   198  	}
   199  
   200  	dh[0] += a
   201  	dh[1] += b
   202  	dh[2] += c
   203  	dh[3] += d
   204  	dh[4] += e
   205  	dh[5] += f
   206  	dh[6] += g
   207  	dh[7] += h
   208  }
   209  
   210  func beUint64(b []byte) uint64 {
   211  	_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
   212  	return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
   213  		uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
   214  }
   215  
   216  func bePutUint64(b []byte, v uint64) {
   217  	_ = b[7] // early bounds check to guarantee safety of writes below
   218  	b[0] = byte(v >> 56)
   219  	b[1] = byte(v >> 48)
   220  	b[2] = byte(v >> 40)
   221  	b[3] = byte(v >> 32)
   222  	b[4] = byte(v >> 24)
   223  	b[5] = byte(v >> 16)
   224  	b[6] = byte(v >> 8)
   225  	b[7] = byte(v)
   226  }
   227  

View as plain text