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

View as plain text