]> Cypherpunks repositories - gostls13.git/commitdiff
crypto/sha256,crypto/sha512: move implementation to crypto/internal/fips
authorFilippo Valsorda <filippo@golang.org>
Thu, 19 Sep 2024 18:04:30 +0000 (20:04 +0200)
committerGopher Robot <gobot@golang.org>
Wed, 23 Oct 2024 15:21:45 +0000 (15:21 +0000)
For #69536

Change-Id: I1efa916e6e9fcddeffa52bc3d23286e6465dae54
Reviewed-on: https://go-review.googlesource.com/c/go/+/615235
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
Reviewed-by: Roland Shoemaker <roland@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
44 files changed:
src/cmd/compile/internal/types2/stdlib_test.go
src/crypto/internal/fips/sha256/_asm/go.mod [moved from src/crypto/sha256/_asm/go.mod with 100% similarity]
src/crypto/internal/fips/sha256/_asm/go.sum [moved from src/crypto/sha256/_asm/go.sum with 100% similarity]
src/crypto/internal/fips/sha256/_asm/sha256block_amd64_asm.go [moved from src/crypto/sha256/_asm/sha256block_amd64_asm.go with 100% similarity]
src/crypto/internal/fips/sha256/_asm/sha256block_amd64_avx2.go [moved from src/crypto/sha256/_asm/sha256block_amd64_avx2.go with 100% similarity]
src/crypto/internal/fips/sha256/_asm/sha256block_amd64_shani.go [moved from src/crypto/sha256/_asm/sha256block_amd64_shani.go with 100% similarity]
src/crypto/internal/fips/sha256/sha256.go [new file with mode: 0644]
src/crypto/internal/fips/sha256/sha256block.go [moved from src/crypto/sha256/sha256block.go with 98% similarity]
src/crypto/internal/fips/sha256/sha256block_386.s [moved from src/crypto/sha256/sha256block_386.s with 100% similarity]
src/crypto/internal/fips/sha256/sha256block_amd64.go [moved from src/crypto/sha256/sha256block_amd64.go with 80% similarity]
src/crypto/internal/fips/sha256/sha256block_amd64.s [moved from src/crypto/sha256/sha256block_amd64.s with 99% similarity]
src/crypto/internal/fips/sha256/sha256block_arm64.go [moved from src/crypto/sha256/sha256block_arm64.go with 85% similarity]
src/crypto/internal/fips/sha256/sha256block_arm64.s [moved from src/crypto/sha256/sha256block_arm64.s with 99% similarity]
src/crypto/internal/fips/sha256/sha256block_asm.go [moved from src/crypto/sha256/sha256block_asm.go with 87% similarity]
src/crypto/internal/fips/sha256/sha256block_loong64.s [moved from src/crypto/sha256/sha256block_loong64.s with 99% similarity]
src/crypto/internal/fips/sha256/sha256block_noasm.go [moved from src/crypto/sha256/sha256block_noasm.go with 89% similarity]
src/crypto/internal/fips/sha256/sha256block_ppc64x.go [moved from src/crypto/sha256/sha256block_ppc64x.go with 91% similarity]
src/crypto/internal/fips/sha256/sha256block_ppc64x.s [moved from src/crypto/sha256/sha256block_ppc64x.s with 99% similarity]
src/crypto/internal/fips/sha256/sha256block_riscv64.s [moved from src/crypto/sha256/sha256block_riscv64.s with 99% similarity]
src/crypto/internal/fips/sha256/sha256block_s390x.go [moved from src/crypto/sha256/sha256block_s390x.go with 88% similarity]
src/crypto/internal/fips/sha256/sha256block_s390x.s [moved from src/crypto/sha256/sha256block_s390x.s with 92% similarity]
src/crypto/internal/fips/sha512/_asm/go.mod [moved from src/crypto/sha512/_asm/go.mod with 100% similarity]
src/crypto/internal/fips/sha512/_asm/go.sum [moved from src/crypto/sha512/_asm/go.sum with 100% similarity]
src/crypto/internal/fips/sha512/_asm/sha512block_amd64_asm.go [moved from src/crypto/sha512/_asm/sha512block_amd64_asm.go with 100% similarity]
src/crypto/internal/fips/sha512/sha512.go [new file with mode: 0644]
src/crypto/internal/fips/sha512/sha512block.go [moved from src/crypto/sha512/sha512block.go with 98% similarity]
src/crypto/internal/fips/sha512/sha512block_amd64.go [moved from src/crypto/sha512/sha512block_amd64.go with 81% similarity]
src/crypto/internal/fips/sha512/sha512block_amd64.s [moved from src/crypto/sha512/sha512block_amd64.s with 99% similarity]
src/crypto/internal/fips/sha512/sha512block_arm64.go [moved from src/crypto/sha512/sha512block_arm64.go with 85% similarity]
src/crypto/internal/fips/sha512/sha512block_arm64.s [moved from src/crypto/sha512/sha512block_arm64.s with 99% similarity]
src/crypto/internal/fips/sha512/sha512block_asm.go [moved from src/crypto/sha512/sha512block_asm.go with 87% similarity]
src/crypto/internal/fips/sha512/sha512block_loong64.s [moved from src/crypto/sha512/sha512block_loong64.s with 99% similarity]
src/crypto/internal/fips/sha512/sha512block_noasm.go [moved from src/crypto/sha512/sha512block_noasm.go with 89% similarity]
src/crypto/internal/fips/sha512/sha512block_ppc64x.go [moved from src/crypto/sha512/sha512block_ppc64x.go with 91% similarity]
src/crypto/internal/fips/sha512/sha512block_ppc64x.s [moved from src/crypto/sha512/sha512block_ppc64x.s with 99% similarity]
src/crypto/internal/fips/sha512/sha512block_riscv64.s [moved from src/crypto/sha512/sha512block_riscv64.s with 99% similarity]
src/crypto/internal/fips/sha512/sha512block_s390x.go [moved from src/crypto/sha512/sha512block_s390x.go with 88% similarity]
src/crypto/internal/fips/sha512/sha512block_s390x.s [moved from src/crypto/sha512/sha512block_s390x.s with 92% similarity]
src/crypto/sha256/sha256.go
src/crypto/sha256/sha256_test.go
src/crypto/sha512/sha512.go
src/crypto/sha512/sha512_test.go
src/go/build/deps_test.go
src/go/types/stdlib_test.go

index 45c692d511134bb197b82961ad13e8f525828424..0c63e5d77c89fbf4a16f36ea9b2bc1f7366123ad 100644 (file)
@@ -17,6 +17,7 @@ import (
        "os"
        "path/filepath"
        "runtime"
+       "slices"
        "strings"
        "sync"
        "testing"
@@ -354,17 +355,6 @@ func TestStdKen(t *testing.T) {
 // Package paths of excluded packages.
 var excluded = map[string]bool{
        "builtin": true,
-
-       // go.dev/issue/46027: some imports are missing for this submodule.
-       "crypto/aes/_asm/gcm":                     true,
-       "crypto/aes/_asm/standard":                true,
-       "crypto/internal/bigmod/_asm":             true,
-       "crypto/internal/edwards25519/field/_asm": true,
-       "crypto/internal/nistec/_asm":             true,
-       "crypto/md5/_asm":                         true,
-       "crypto/sha1/_asm":                        true,
-       "crypto/sha256/_asm":                      true,
-       "crypto/sha512/_asm":                      true,
 }
 
 // printPackageMu synchronizes the printing of type-checked package files in
@@ -447,6 +437,11 @@ func pkgFilenames(dir string, includeTest bool) ([]string, error) {
        if excluded[pkg.ImportPath] {
                return nil, nil
        }
+       if slices.Contains(strings.Split(pkg.ImportPath, "/"), "_asm") {
+               // Submodules where not all dependencies are available.
+               // See go.dev/issue/46027.
+               return nil, nil
+       }
        var filenames []string
        for _, name := range pkg.GoFiles {
                filenames = append(filenames, filepath.Join(pkg.Dir, name))
diff --git a/src/crypto/internal/fips/sha256/sha256.go b/src/crypto/internal/fips/sha256/sha256.go
new file mode 100644 (file)
index 0000000..3765299
--- /dev/null
@@ -0,0 +1,229 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package sha256 implements the SHA-224 and SHA-256 hash algorithms as defined
+// in FIPS 180-4.
+package sha256
+
+import (
+       "errors"
+       "internal/byteorder"
+)
+
+// The size of a SHA-256 checksum in bytes.
+const size = 32
+
+// The size of a SHA-224 checksum in bytes.
+const size224 = 28
+
+// The block size of SHA-256 and SHA-224 in bytes.
+const blockSize = 64
+
+const (
+       chunk     = 64
+       init0     = 0x6A09E667
+       init1     = 0xBB67AE85
+       init2     = 0x3C6EF372
+       init3     = 0xA54FF53A
+       init4     = 0x510E527F
+       init5     = 0x9B05688C
+       init6     = 0x1F83D9AB
+       init7     = 0x5BE0CD19
+       init0_224 = 0xC1059ED8
+       init1_224 = 0x367CD507
+       init2_224 = 0x3070DD17
+       init3_224 = 0xF70E5939
+       init4_224 = 0xFFC00B31
+       init5_224 = 0x68581511
+       init6_224 = 0x64F98FA7
+       init7_224 = 0xBEFA4FA4
+)
+
+// Digest is a SHA-224 or SHA-256 [hash.Hash] implementation.
+type Digest struct {
+       h     [8]uint32
+       x     [chunk]byte
+       nx    int
+       len   uint64
+       is224 bool // mark if this digest is SHA-224
+}
+
+const (
+       magic224      = "sha\x02"
+       magic256      = "sha\x03"
+       marshaledSize = len(magic256) + 8*4 + chunk + 8
+)
+
+func (d *Digest) MarshalBinary() ([]byte, error) {
+       return d.AppendBinary(make([]byte, 0, marshaledSize))
+}
+
+func (d *Digest) AppendBinary(b []byte) ([]byte, error) {
+       if d.is224 {
+               b = append(b, magic224...)
+       } else {
+               b = append(b, magic256...)
+       }
+       b = byteorder.BeAppendUint32(b, d.h[0])
+       b = byteorder.BeAppendUint32(b, d.h[1])
+       b = byteorder.BeAppendUint32(b, d.h[2])
+       b = byteorder.BeAppendUint32(b, d.h[3])
+       b = byteorder.BeAppendUint32(b, d.h[4])
+       b = byteorder.BeAppendUint32(b, d.h[5])
+       b = byteorder.BeAppendUint32(b, d.h[6])
+       b = byteorder.BeAppendUint32(b, d.h[7])
+       b = append(b, d.x[:d.nx]...)
+       b = append(b, make([]byte, len(d.x)-d.nx)...)
+       b = byteorder.BeAppendUint64(b, d.len)
+       return b, nil
+}
+
+func (d *Digest) UnmarshalBinary(b []byte) error {
+       if len(b) < len(magic224) || (d.is224 && string(b[:len(magic224)]) != magic224) || (!d.is224 && string(b[:len(magic256)]) != magic256) {
+               return errors.New("crypto/sha256: invalid hash state identifier")
+       }
+       if len(b) != marshaledSize {
+               return errors.New("crypto/sha256: invalid hash state size")
+       }
+       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, d.len = consumeUint64(b)
+       d.nx = int(d.len % chunk)
+       return nil
+}
+
+func consumeUint64(b []byte) ([]byte, uint64) {
+       return b[8:], byteorder.BeUint64(b)
+}
+
+func consumeUint32(b []byte) ([]byte, uint32) {
+       return b[4:], byteorder.BeUint32(b)
+}
+
+func (d *Digest) Reset() {
+       if !d.is224 {
+               d.h[0] = init0
+               d.h[1] = init1
+               d.h[2] = init2
+               d.h[3] = init3
+               d.h[4] = init4
+               d.h[5] = init5
+               d.h[6] = init6
+               d.h[7] = init7
+       } else {
+               d.h[0] = init0_224
+               d.h[1] = init1_224
+               d.h[2] = init2_224
+               d.h[3] = init3_224
+               d.h[4] = init4_224
+               d.h[5] = init5_224
+               d.h[6] = init6_224
+               d.h[7] = init7_224
+       }
+       d.nx = 0
+       d.len = 0
+}
+
+// New returns a new Digest computing the SHA-256 hash.
+func New() *Digest {
+       d := new(Digest)
+       d.Reset()
+       return d
+}
+
+// New224 returns a new Digest computing the SHA-224 hash.
+func New224() *Digest {
+       d := new(Digest)
+       d.is224 = true
+       d.Reset()
+       return d
+}
+
+func (d *Digest) Size() int {
+       if !d.is224 {
+               return size
+       }
+       return size224
+}
+
+func (d *Digest) BlockSize() int { return blockSize }
+
+func (d *Digest) Write(p []byte) (nn int, err error) {
+       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[:])
+                       d.nx = 0
+               }
+               p = p[n:]
+       }
+       if len(p) >= chunk {
+               n := len(p) &^ (chunk - 1)
+               block(d, p[:n])
+               p = p[n:]
+       }
+       if len(p) > 0 {
+               d.nx = copy(d.x[:], p)
+       }
+       return
+}
+
+func (d *Digest) Sum(in []byte) []byte {
+       // Make a copy of d so that caller can keep writing and summing.
+       d0 := *d
+       hash := d0.checkSum()
+       if d0.is224 {
+               return append(in, hash[:size224]...)
+       }
+       return append(in, hash[:]...)
+}
+
+func (d *Digest) checkSum() [size]byte {
+       len := d.len
+       // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
+       var tmp [64 + 8]byte // padding + length buffer
+       tmp[0] = 0x80
+       var t uint64
+       if len%64 < 56 {
+               t = 56 - len%64
+       } else {
+               t = 64 + 56 - len%64
+       }
+
+       // Length in bits.
+       len <<= 3
+       padlen := tmp[:t+8]
+       byteorder.BePutUint64(padlen[t+0:], len)
+       d.Write(padlen)
+
+       if d.nx != 0 {
+               panic("d.nx != 0")
+       }
+
+       var digest [size]byte
+
+       byteorder.BePutUint32(digest[0:], d.h[0])
+       byteorder.BePutUint32(digest[4:], d.h[1])
+       byteorder.BePutUint32(digest[8:], d.h[2])
+       byteorder.BePutUint32(digest[12:], d.h[3])
+       byteorder.BePutUint32(digest[16:], d.h[4])
+       byteorder.BePutUint32(digest[20:], d.h[5])
+       byteorder.BePutUint32(digest[24:], d.h[6])
+       if !d.is224 {
+               byteorder.BePutUint32(digest[28:], d.h[7])
+       }
+
+       return digest
+}
similarity index 98%
rename from src/crypto/sha256/sha256block.go
rename to src/crypto/internal/fips/sha256/sha256block.go
index bd2f9da93ce847880142bfae645584ee4e09c442..3fbad718640175ef2f5097a5ab1606e4b611da59 100644 (file)
@@ -77,7 +77,7 @@ var _K = []uint32{
        0xc67178f2,
 }
 
-func blockGeneric(dig *digest, p []byte) {
+func blockGeneric(dig *Digest, p []byte) {
        var w [64]uint32
        h0, h1, h2, h3, h4, h5, h6, h7 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7]
        for len(p) >= chunk {
similarity index 80%
rename from src/crypto/sha256/sha256block_amd64.go
rename to src/crypto/internal/fips/sha256/sha256block_amd64.go
index ec3a4870d4e8b2a93a8c154c2e7b9aafb9400cfd..7c19bbb19b38f5c82570bd89667781a6edfa6acf 100644 (file)
@@ -20,15 +20,15 @@ func init() {
 }
 
 //go:noescape
-func blockAMD64(dig *digest, p []byte)
+func blockAMD64(dig *Digest, p []byte)
 
 //go:noescape
-func blockAVX2(dig *digest, p []byte)
+func blockAVX2(dig *Digest, p []byte)
 
 //go:noescape
-func blockSHANI(dig *digest, p []byte)
+func blockSHANI(dig *Digest, p []byte)
 
-func block(dig *digest, p []byte) {
+func block(dig *Digest, p []byte) {
        if useSHANI {
                blockSHANI(dig, p)
        } else if useAVX2 {
similarity index 99%
rename from src/crypto/sha256/sha256block_amd64.s
rename to src/crypto/internal/fips/sha256/sha256block_amd64.s
index d073c5fe3054b0243a80e13abfd84ea3d2fd3928..7d9ed5acea9d71a825395de7cf8bd4d59a54d134 100644 (file)
@@ -4,7 +4,7 @@
 
 #include "textflag.h"
 
-// func blockAMD64(dig *digest, p []byte)
+// func blockAMD64(dig *Digest, p []byte)
 TEXT Â·blockAMD64(SB), $264-32
        MOVQ p_base+8(FP), SI
        MOVQ p_len+16(FP), DX
@@ -3490,7 +3490,7 @@ loop:
 end:
        RET
 
-// func blockAVX2(dig *digest, p []byte)
+// func blockAVX2(dig *Digest, p []byte)
 // Requires: AVX, AVX2, BMI2
 TEXT Â·blockAVX2(SB), $536-32
        MOVQ dig+0(FP), SI
@@ -4772,7 +4772,7 @@ DATA shuff_DC00<>+16(SB)/8, $0xffffffffffffffff
 DATA shuff_DC00<>+24(SB)/8, $0x0b0a090803020100
 GLOBL shuff_DC00<>(SB), RODATA, $32
 
-// func blockSHANI(dig *digest, p []byte)
+// func blockSHANI(dig *Digest, p []byte)
 // Requires: AVX, SHA, SSE2, SSE4.1, SSSE3
 TEXT Â·blockSHANI(SB), $0-32
        MOVQ    dig+0(FP), DI
similarity index 85%
rename from src/crypto/sha256/sha256block_arm64.go
rename to src/crypto/internal/fips/sha256/sha256block_arm64.go
index 6eb1c89a6b6ec7656a63038e8e54809bf6a469c5..c0301aef25227d166df3dcdaa4272067265045fa 100644 (file)
@@ -18,9 +18,9 @@ func init() {
 }
 
 //go:noescape
-func blockSHA2(dig *digest, p []byte)
+func blockSHA2(dig *Digest, p []byte)
 
-func block(dig *digest, p []byte) {
+func block(dig *Digest, p []byte) {
        if useSHA2 {
                blockSHA2(dig, p)
        } else {
similarity index 99%
rename from src/crypto/sha256/sha256block_arm64.s
rename to src/crypto/internal/fips/sha256/sha256block_arm64.s
index f6d19e35c66b67524ae1800a24ce5451f1264ebb..0e63cda99c1d623dee8bb3c29f1581b53fcb0a2a 100644 (file)
@@ -11,7 +11,7 @@
        SHA256H2        V9.S4, V8, V3 \
        VMOV    V2.B16, V8.B16
 
-// func blockSHA2(dig *digest, p []byte)
+// func blockSHA2(dig *Digest, p []byte)
 TEXT Â·blockSHA2(SB),NOSPLIT,$0
        MOVD    dig+0(FP), R0                              // Hash value first address
        MOVD    p_base+8(FP), R1                           // message first address
similarity index 87%
rename from src/crypto/sha256/sha256block_asm.go
rename to src/crypto/internal/fips/sha256/sha256block_asm.go
index 50e9615c5ef49a73a012cc2fbbfee4d5827df681..1b157d744d6ba4e0b8325c0dc90949d8a6ab8f62 100644 (file)
@@ -7,4 +7,4 @@
 package sha256
 
 //go:noescape
-func block(dig *digest, p []byte)
+func block(dig *Digest, p []byte)
similarity index 99%
rename from src/crypto/sha256/sha256block_loong64.s
rename to src/crypto/internal/fips/sha256/sha256block_loong64.s
index 2a2fbe68337a8eec80f635a0b5b81f82cc4478a0..971ad97ab82798bcc1e9b98c3eeb3137c8ab00c3 100644 (file)
 // the frame size used for data expansion is 64 bytes.
 // See the definition of the macro LOAD1 above (4 bytes * 16 entries).
 //
-//func block(dig *digest, p []byte)
+//func block(dig *Digest, p []byte)
 TEXT Â·block(SB),NOSPLIT,$64-32
        MOVV    p_base+8(FP), R5
        MOVV    p_len+16(FP), R6
similarity index 89%
rename from src/crypto/sha256/sha256block_noasm.go
rename to src/crypto/internal/fips/sha256/sha256block_noasm.go
index 8ca8401f65a604ab8d42310f237cffd00677ed91..cc7abf6a382529c02d053baebfe8cfee1dfbde5b 100644 (file)
@@ -6,6 +6,6 @@
 
 package sha256
 
-func block(dig *digest, p []byte) {
+func block(dig *Digest, p []byte) {
        blockGeneric(dig, p)
 }
similarity index 91%
rename from src/crypto/sha256/sha256block_ppc64x.go
rename to src/crypto/internal/fips/sha256/sha256block_ppc64x.go
index 6cc8c2ec5222902763e0f763bfe1d63cb4f04581..1854fdf04a7108c862a134debba01fe4674a8f4a 100644 (file)
@@ -22,9 +22,9 @@ func init() {
 }
 
 //go:noescape
-func blockPOWER(dig *digest, p []byte)
+func blockPOWER(dig *Digest, p []byte)
 
-func block(dig *digest, p []byte) {
+func block(dig *Digest, p []byte) {
        if ppc64sha2 {
                blockPOWER(dig, p)
        } else {
similarity index 99%
rename from src/crypto/sha256/sha256block_ppc64x.s
rename to src/crypto/internal/fips/sha256/sha256block_ppc64x.s
index a5f40ff04a52366c7482cf42f87d9b37824b40bd..b28f80dcfa243498dd223b1ae474d10bc1732282 100644 (file)
@@ -284,7 +284,7 @@ GLOBL Â·kcon(SB), RODATA, $1088
 #define VPERMLE(va,vb,vc,vt)
 #endif
 
-// func blockPOWER(dig *digest, p []byte)
+// func blockPOWER(dig *Digest, p []byte)
 TEXT Â·blockPOWER(SB),0,$0-32
        MOVD    dig+0(FP), CTX
        MOVD    p_base+8(FP), INP
similarity index 99%
rename from src/crypto/sha256/sha256block_riscv64.s
rename to src/crypto/internal/fips/sha256/sha256block_riscv64.s
index f31bfb8d53d1b97e8c2f4a6530d3a463064dbf9d..730ba64abeebee86de2a9ac5f5b6915f8c688419 100644 (file)
 // Note that 64 bytes of stack space is used as a circular buffer
 // for the message schedule (4 bytes * 16 entries).
 //
-// func block(dig *digest, p []byte)
+// func block(dig *Digest, p []byte)
 TEXT Â·block(SB),0,$64-32
        MOV     p_base+8(FP), X29
        MOV     p_len+16(FP), X30
similarity index 88%
rename from src/crypto/sha256/sha256block_s390x.go
rename to src/crypto/internal/fips/sha256/sha256block_s390x.go
index 06bba55117222bdee2938a4620fee08513b4d68a..4cc4713f3adaa81c75fab379442a150480f61ce3 100644 (file)
@@ -20,9 +20,9 @@ func init() {
 }
 
 //go:noescape
-func blockS390X(dig *digest, p []byte)
+func blockS390X(dig *Digest, p []byte)
 
-func block(dig *digest, p []byte) {
+func block(dig *Digest, p []byte) {
        if useSHA256 {
                blockS390X(dig, p)
        } else {
similarity index 92%
rename from src/crypto/sha256/sha256block_s390x.s
rename to src/crypto/internal/fips/sha256/sha256block_s390x.s
index 6372d67738bac7498063b40e75aebda39f2d1fc1..06469d68d65e5ad5cb8942c43a7232d1d7cd1131 100644 (file)
@@ -6,7 +6,7 @@
 
 #include "textflag.h"
 
-// func blockS390X(dig *digest, p []byte)
+// func blockS390X(dig *Digest, p []byte)
 TEXT Â·blockS390X(SB), NOSPLIT|NOFRAME, $0-32
        LMG    dig+0(FP), R1, R3            // R2 = &p[0], R3 = len(p)
        MOVBZ  $2, R0                       // SHA-256 function code
diff --git a/src/crypto/internal/fips/sha512/sha512.go b/src/crypto/internal/fips/sha512/sha512.go
new file mode 100644 (file)
index 0000000..e613fd1
--- /dev/null
@@ -0,0 +1,299 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package sha512 implements the SHA-384, SHA-512, SHA-512/224, and SHA-512/256
+// hash algorithms as defined in FIPS 180-4.
+package sha512
+
+import (
+       "errors"
+       "internal/byteorder"
+)
+
+const (
+       // size512 is the size, in bytes, of a SHA-512 checksum.
+       size512 = 64
+
+       // size224 is the size, in bytes, of a SHA-512/224 checksum.
+       size224 = 28
+
+       // size256 is the size, in bytes, of a SHA-512/256 checksum.
+       size256 = 32
+
+       // size384 is the size, in bytes, of a SHA-384 checksum.
+       size384 = 48
+
+       // blockSize is the block size, in bytes, of the SHA-512/224,
+       // SHA-512/256, SHA-384 and SHA-512 hash functions.
+       blockSize = 128
+)
+
+const (
+       chunk     = 128
+       init0     = 0x6a09e667f3bcc908
+       init1     = 0xbb67ae8584caa73b
+       init2     = 0x3c6ef372fe94f82b
+       init3     = 0xa54ff53a5f1d36f1
+       init4     = 0x510e527fade682d1
+       init5     = 0x9b05688c2b3e6c1f
+       init6     = 0x1f83d9abfb41bd6b
+       init7     = 0x5be0cd19137e2179
+       init0_224 = 0x8c3d37c819544da2
+       init1_224 = 0x73e1996689dcd4d6
+       init2_224 = 0x1dfab7ae32ff9c82
+       init3_224 = 0x679dd514582f9fcf
+       init4_224 = 0x0f6d2b697bd44da8
+       init5_224 = 0x77e36f7304c48942
+       init6_224 = 0x3f9d85a86a1d36c8
+       init7_224 = 0x1112e6ad91d692a1
+       init0_256 = 0x22312194fc2bf72c
+       init1_256 = 0x9f555fa3c84c64c2
+       init2_256 = 0x2393b86b6f53b151
+       init3_256 = 0x963877195940eabd
+       init4_256 = 0x96283ee2a88effe3
+       init5_256 = 0xbe5e1e2553863992
+       init6_256 = 0x2b0199fc2c85b8aa
+       init7_256 = 0x0eb72ddc81c52ca2
+       init0_384 = 0xcbbb9d5dc1059ed8
+       init1_384 = 0x629a292a367cd507
+       init2_384 = 0x9159015a3070dd17
+       init3_384 = 0x152fecd8f70e5939
+       init4_384 = 0x67332667ffc00b31
+       init5_384 = 0x8eb44a8768581511
+       init6_384 = 0xdb0c2e0d64f98fa7
+       init7_384 = 0x47b5481dbefa4fa4
+)
+
+// Digest is a SHA-384, SHA-512, SHA-512/224, or SHA-512/256 [hash.Hash]
+// implementation.
+type Digest struct {
+       h    [8]uint64
+       x    [chunk]byte
+       nx   int
+       len  uint64
+       size int // size224, size256, size384, or size512
+}
+
+func (d *Digest) Reset() {
+       switch d.size {
+       case size384:
+               d.h[0] = init0_384
+               d.h[1] = init1_384
+               d.h[2] = init2_384
+               d.h[3] = init3_384
+               d.h[4] = init4_384
+               d.h[5] = init5_384
+               d.h[6] = init6_384
+               d.h[7] = init7_384
+       case size224:
+               d.h[0] = init0_224
+               d.h[1] = init1_224
+               d.h[2] = init2_224
+               d.h[3] = init3_224
+               d.h[4] = init4_224
+               d.h[5] = init5_224
+               d.h[6] = init6_224
+               d.h[7] = init7_224
+       case size256:
+               d.h[0] = init0_256
+               d.h[1] = init1_256
+               d.h[2] = init2_256
+               d.h[3] = init3_256
+               d.h[4] = init4_256
+               d.h[5] = init5_256
+               d.h[6] = init6_256
+               d.h[7] = init7_256
+       case size512:
+               d.h[0] = init0
+               d.h[1] = init1
+               d.h[2] = init2
+               d.h[3] = init3
+               d.h[4] = init4
+               d.h[5] = init5
+               d.h[6] = init6
+               d.h[7] = init7
+       default:
+               panic("unknown size")
+       }
+       d.nx = 0
+       d.len = 0
+}
+
+const (
+       magic384      = "sha\x04"
+       magic512_224  = "sha\x05"
+       magic512_256  = "sha\x06"
+       magic512      = "sha\x07"
+       marshaledSize = len(magic512) + 8*8 + chunk + 8
+)
+
+func (d *Digest) MarshalBinary() ([]byte, error) {
+       return d.AppendBinary(make([]byte, 0, marshaledSize))
+}
+
+func (d *Digest) AppendBinary(b []byte) ([]byte, error) {
+       switch d.size {
+       case size384:
+               b = append(b, magic384...)
+       case size224:
+               b = append(b, magic512_224...)
+       case size256:
+               b = append(b, magic512_256...)
+       case size512:
+               b = append(b, magic512...)
+       default:
+               panic("unknown size")
+       }
+       b = byteorder.BeAppendUint64(b, d.h[0])
+       b = byteorder.BeAppendUint64(b, d.h[1])
+       b = byteorder.BeAppendUint64(b, d.h[2])
+       b = byteorder.BeAppendUint64(b, d.h[3])
+       b = byteorder.BeAppendUint64(b, d.h[4])
+       b = byteorder.BeAppendUint64(b, d.h[5])
+       b = byteorder.BeAppendUint64(b, d.h[6])
+       b = byteorder.BeAppendUint64(b, d.h[7])
+       b = append(b, d.x[:d.nx]...)
+       b = append(b, make([]byte, len(d.x)-d.nx)...)
+       b = byteorder.BeAppendUint64(b, d.len)
+       return b, nil
+}
+
+func (d *Digest) UnmarshalBinary(b []byte) error {
+       if len(b) < len(magic512) {
+               return errors.New("crypto/sha512: invalid hash state identifier")
+       }
+       switch {
+       case d.size == size384 && string(b[:len(magic384)]) == magic384:
+       case d.size == size224 && string(b[:len(magic512_224)]) == magic512_224:
+       case d.size == size256 && string(b[:len(magic512_256)]) == magic512_256:
+       case d.size == size512 && string(b[:len(magic512)]) == magic512:
+       default:
+               return errors.New("crypto/sha512: invalid hash state identifier")
+       }
+       if len(b) != marshaledSize {
+               return errors.New("crypto/sha512: invalid hash state size")
+       }
+       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, d.len = consumeUint64(b)
+       d.nx = int(d.len % chunk)
+       return nil
+}
+
+func consumeUint64(b []byte) ([]byte, uint64) {
+       return b[8:], byteorder.BeUint64(b)
+}
+
+// New returns a new Digest computing the SHA-512 hash.
+func New() *Digest {
+       d := &Digest{size: size512}
+       d.Reset()
+       return d
+}
+
+// New512_224 returns a new Digest computing the SHA-512/224 hash.
+func New512_224() *Digest {
+       d := &Digest{size: size224}
+       d.Reset()
+       return d
+}
+
+// New512_256 returns a new Digest computing the SHA-512/256 hash.
+func New512_256() *Digest {
+       d := &Digest{size: size256}
+       d.Reset()
+       return d
+}
+
+// New384 returns a new Digest computing the SHA-384 hash.
+func New384() *Digest {
+       d := &Digest{size: size384}
+       d.Reset()
+       return d
+}
+
+func (d *Digest) Size() int {
+       return d.size
+}
+
+func (d *Digest) BlockSize() int { return blockSize }
+
+func (d *Digest) Write(p []byte) (nn int, err error) {
+       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[:])
+                       d.nx = 0
+               }
+               p = p[n:]
+       }
+       if len(p) >= chunk {
+               n := len(p) &^ (chunk - 1)
+               block(d, p[:n])
+               p = p[n:]
+       }
+       if len(p) > 0 {
+               d.nx = copy(d.x[:], p)
+       }
+       return
+}
+
+func (d *Digest) Sum(in []byte) []byte {
+       // Make a copy of d so that caller can keep writing and summing.
+       d0 := new(Digest)
+       *d0 = *d
+       hash := d0.checkSum()
+       return append(in, hash[:d.size]...)
+}
+
+func (d *Digest) checkSum() [size512]byte {
+       // Padding. Add a 1 bit and 0 bits until 112 bytes mod 128.
+       len := d.len
+       var tmp [128 + 16]byte // padding + length buffer
+       tmp[0] = 0x80
+       var t uint64
+       if len%128 < 112 {
+               t = 112 - len%128
+       } else {
+               t = 128 + 112 - len%128
+       }
+
+       // Length in bits.
+       len <<= 3
+       padlen := tmp[:t+16]
+       // Upper 64 bits are always zero, because len variable has type uint64,
+       // and tmp is already zeroed at that index, so we can skip updating it.
+       // byteorder.BePutUint64(padlen[t+0:], 0)
+       byteorder.BePutUint64(padlen[t+8:], len)
+       d.Write(padlen)
+
+       if d.nx != 0 {
+               panic("d.nx != 0")
+       }
+
+       var digest [size512]byte
+       byteorder.BePutUint64(digest[0:], d.h[0])
+       byteorder.BePutUint64(digest[8:], d.h[1])
+       byteorder.BePutUint64(digest[16:], d.h[2])
+       byteorder.BePutUint64(digest[24:], d.h[3])
+       byteorder.BePutUint64(digest[32:], d.h[4])
+       byteorder.BePutUint64(digest[40:], d.h[5])
+       if d.size != size384 {
+               byteorder.BePutUint64(digest[48:], d.h[6])
+               byteorder.BePutUint64(digest[56:], d.h[7])
+       }
+
+       return digest
+}
similarity index 98%
rename from src/crypto/sha512/sha512block.go
rename to src/crypto/internal/fips/sha512/sha512block.go
index 81569c5f84e8964e955b5b5aa24e9f6e696c923d..3c96cc343aaeaef8f2992ae785b6ef6d0bf76c5e 100644 (file)
@@ -93,7 +93,7 @@ var _K = []uint64{
        0x6c44198c4a475817,
 }
 
-func blockGeneric(dig *digest, p []byte) {
+func blockGeneric(dig *Digest, p []byte) {
        var w [80]uint64
        h0, h1, h2, h3, h4, h5, h6, h7 := dig.h[0], dig.h[1], dig.h[2], dig.h[3], dig.h[4], dig.h[5], dig.h[6], dig.h[7]
        for len(p) >= chunk {
similarity index 81%
rename from src/crypto/sha512/sha512block_amd64.go
rename to src/crypto/internal/fips/sha512/sha512block_amd64.go
index 39d14597fd6d79ce241d1c134d8cc75798de11a0..1fec14e229e1ed2a027be1dd5a013de72fdf11ea 100644 (file)
@@ -18,12 +18,12 @@ func init() {
 }
 
 //go:noescape
-func blockAVX2(dig *digest, p []byte)
+func blockAVX2(dig *Digest, p []byte)
 
 //go:noescape
-func blockAMD64(dig *digest, p []byte)
+func blockAMD64(dig *Digest, p []byte)
 
-func block(dig *digest, p []byte) {
+func block(dig *Digest, p []byte) {
        if useAVX2 {
                blockAVX2(dig, p)
        } else {
similarity index 99%
rename from src/crypto/sha512/sha512block_amd64.s
rename to src/crypto/internal/fips/sha512/sha512block_amd64.s
index fdcef222150f641a7fed2a0cc8574fad53b5a85c..ffccdf229feff1f2d03c17393f1df0bbe77f0222 100644 (file)
@@ -4,7 +4,7 @@
 
 #include "textflag.h"
 
-// func blockAMD64(dig *digest, p []byte)
+// func blockAMD64(dig *Digest, p []byte)
 TEXT Â·blockAMD64(SB), $648-32
        MOVQ p_base+8(FP), SI
        MOVQ p_len+16(FP), DX
@@ -4504,7 +4504,7 @@ DATA PSHUFFLE_BYTE_FLIP_MASK<>+16(SB)/8, $0x1011121314151617
 DATA PSHUFFLE_BYTE_FLIP_MASK<>+24(SB)/8, $0x18191a1b1c1d1e1f
 GLOBL PSHUFFLE_BYTE_FLIP_MASK<>(SB), RODATA|NOPTR, $32
 
-// func blockAVX2(dig *digest, p []byte)
+// func blockAVX2(dig *Digest, p []byte)
 // Requires: AVX, AVX2, BMI2
 TEXT Â·blockAVX2(SB), NOSPLIT, $56-32
        MOVQ    dig+0(FP), SI
similarity index 85%
rename from src/crypto/sha512/sha512block_arm64.go
rename to src/crypto/internal/fips/sha512/sha512block_arm64.go
index ea9e8d9a84fdf300b7c04ffad55c7020414323b1..617c646da40c13df7b257856abd2c870c2a118b8 100644 (file)
@@ -18,9 +18,9 @@ func init() {
 }
 
 //go:noescape
-func blockSHA512(dig *digest, p []byte)
+func blockSHA512(dig *Digest, p []byte)
 
-func block(dig *digest, p []byte) {
+func block(dig *Digest, p []byte) {
        if useSHA512 {
                blockSHA512(dig, p)
        } else {
similarity index 99%
rename from src/crypto/sha512/sha512block_arm64.s
rename to src/crypto/internal/fips/sha512/sha512block_arm64.s
index 15242e4bbc7f5a576fc29266820554698823420d..1b192ae0794e417d6862e7ab14f3bf9f2ff8d871 100644 (file)
@@ -40,7 +40,7 @@
        VADD    i3.D2, i1.D2, i4.D2 \
        SHA512H2        i0.D2, i1, i3
 
-// func blockSHA512(dig *digest, p []byte)
+// func blockSHA512(dig *Digest, p []byte)
 TEXT Â·blockSHA512(SB),NOSPLIT,$0
        MOVD    dig+0(FP), R0
        MOVD    p_base+8(FP), R1
similarity index 87%
rename from src/crypto/sha512/sha512block_asm.go
rename to src/crypto/internal/fips/sha512/sha512block_asm.go
index 888804678e43854dff53dc68464f121d319b8801..532345108f8041b1c4ce04f6ddd2cb7a1c486c1e 100644 (file)
@@ -7,4 +7,4 @@
 package sha512
 
 //go:noescape
-func block(dig *digest, p []byte)
+func block(dig *Digest, p []byte)
similarity index 99%
rename from src/crypto/sha512/sha512block_loong64.s
rename to src/crypto/internal/fips/sha512/sha512block_loong64.s
index e508f23c58d8afc9d201788e1f1f450780e07e49..00f686c9f737d1ca69339e40d9aa904d4d91df30 100644 (file)
 // the frame size used for data expansion is 128 bytes.
 // See the definition of the macro LOAD1 above (8 bytes * 16 entries).
 //
-// func block(dig *digest, p []byte)
+// func block(dig *Digest, p []byte)
 TEXT Â·block(SB),NOSPLIT,$128-32
        MOVV    p_len+16(FP), R6
        MOVV    p_base+8(FP), R5
similarity index 89%
rename from src/crypto/sha512/sha512block_noasm.go
rename to src/crypto/internal/fips/sha512/sha512block_noasm.go
index 5d556606ed6ccda60f07e8692ef1a01887e64819..a1051ca2db0de34263470e4fa5c1cf53838685cb 100644 (file)
@@ -6,6 +6,6 @@
 
 package sha512
 
-func block(dig *digest, p []byte) {
+func block(dig *Digest, p []byte) {
        blockGeneric(dig, p)
 }
similarity index 91%
rename from src/crypto/sha512/sha512block_ppc64x.go
rename to src/crypto/internal/fips/sha512/sha512block_ppc64x.go
index 0a87aa9cf21ef6b751fc5b6f02eb6be42093ead2..8e5e7d74a0197bfe05da83c20411be6a27d21cf0 100644 (file)
@@ -22,9 +22,9 @@ func init() {
 }
 
 //go:noescape
-func blockPOWER(dig *digest, p []byte)
+func blockPOWER(dig *Digest, p []byte)
 
-func block(dig *digest, p []byte) {
+func block(dig *Digest, p []byte) {
        if ppc64sha512 {
                blockPOWER(dig, p)
        } else {
similarity index 99%
rename from src/crypto/sha512/sha512block_ppc64x.s
rename to src/crypto/internal/fips/sha512/sha512block_ppc64x.s
index cccce227976366040a95667d1ff8a53c9d56c0df..fd2c47bc7e3b38047ff686ebbb5224b0e1417a2e 100644 (file)
@@ -304,7 +304,7 @@ GLOBL Â·kcon(SB), RODATA, $1312
        VADDUDM         S0, h, h; \
        VADDUDM         s1, xj, xj
 
-// func blockPOWER(dig *digest, p []byte)
+// func blockPOWER(dig *Digest, p []byte)
 TEXT Â·blockPOWER(SB),0,$0-32
        MOVD    dig+0(FP), CTX
        MOVD    p_base+8(FP), INP
similarity index 99%
rename from src/crypto/sha512/sha512block_riscv64.s
rename to src/crypto/internal/fips/sha512/sha512block_riscv64.s
index 7dcb0f80d0ab6538b95ba4bff53d53eb83fbd1d7..0839cf0350643e3f67a70089e6722741ec6b23f0 100644 (file)
        MSGSCHEDULE1(index); \
        SHA512ROUND(index, a, b, c, d, e, f, g, h)
 
-// func block(dig *digest, p []byte)
+// func block(dig *Digest, p []byte)
 TEXT Â·block(SB),0,$128-32
        MOV     p_base+8(FP), X29
        MOV     p_len+16(FP), X30
similarity index 88%
rename from src/crypto/sha512/sha512block_s390x.go
rename to src/crypto/internal/fips/sha512/sha512block_s390x.go
index 6fd4057ab06faf921c90bfbbe466192fbafc42df..eff6b49b5a2677245a93091711ad424edbc68973 100644 (file)
@@ -20,9 +20,9 @@ func init() {
 }
 
 //go:noescape
-func blockS390X(dig *digest, p []byte)
+func blockS390X(dig *Digest, p []byte)
 
-func block(dig *digest, p []byte) {
+func block(dig *Digest, p []byte) {
        if useSHA512 {
                blockS390X(dig, p)
        } else {
similarity index 92%
rename from src/crypto/sha512/sha512block_s390x.s
rename to src/crypto/internal/fips/sha512/sha512block_s390x.s
index bd3cd43967fae071b1e55899a9e61cb7a2920e36..5e943ed11fc4ea5b8c670d4fa09d36fd3d068888 100644 (file)
@@ -6,7 +6,7 @@
 
 #include "textflag.h"
 
-// func blockS390X(dig *digest, p []byte)
+// func blockS390X(dig *Digest, p []byte)
 TEXT Â·blockS390X(SB), NOSPLIT|NOFRAME, $0-32
        LMG    dig+0(FP), R1, R3            // R2 = &p[0], R3 = len(p)
        MOVBZ  $3, R0                       // SHA-512 function code
index 7844f191e16b57ce4edf0fabd91fc80e0687617a..d87c689c9001ad0d3cd5316c77ac87df10b7eb1d 100644 (file)
@@ -9,9 +9,8 @@ package sha256
 import (
        "crypto"
        "crypto/internal/boring"
-       "errors"
+       "crypto/internal/fips/sha256"
        "hash"
-       "internal/byteorder"
 )
 
 func init() {
@@ -28,119 +27,6 @@ const Size224 = 28
 // The blocksize of SHA256 and SHA224 in bytes.
 const BlockSize = 64
 
-const (
-       chunk     = 64
-       init0     = 0x6A09E667
-       init1     = 0xBB67AE85
-       init2     = 0x3C6EF372
-       init3     = 0xA54FF53A
-       init4     = 0x510E527F
-       init5     = 0x9B05688C
-       init6     = 0x1F83D9AB
-       init7     = 0x5BE0CD19
-       init0_224 = 0xC1059ED8
-       init1_224 = 0x367CD507
-       init2_224 = 0x3070DD17
-       init3_224 = 0xF70E5939
-       init4_224 = 0xFFC00B31
-       init5_224 = 0x68581511
-       init6_224 = 0x64F98FA7
-       init7_224 = 0xBEFA4FA4
-)
-
-// digest represents the partial evaluation of a checksum.
-type digest struct {
-       h     [8]uint32
-       x     [chunk]byte
-       nx    int
-       len   uint64
-       is224 bool // mark if this digest is SHA-224
-}
-
-const (
-       magic224      = "sha\x02"
-       magic256      = "sha\x03"
-       marshaledSize = len(magic256) + 8*4 + chunk + 8
-)
-
-func (d *digest) MarshalBinary() ([]byte, error) {
-       return d.AppendBinary(make([]byte, 0, marshaledSize))
-}
-
-func (d *digest) AppendBinary(b []byte) ([]byte, error) {
-       if d.is224 {
-               b = append(b, magic224...)
-       } else {
-               b = append(b, magic256...)
-       }
-       b = byteorder.BeAppendUint32(b, d.h[0])
-       b = byteorder.BeAppendUint32(b, d.h[1])
-       b = byteorder.BeAppendUint32(b, d.h[2])
-       b = byteorder.BeAppendUint32(b, d.h[3])
-       b = byteorder.BeAppendUint32(b, d.h[4])
-       b = byteorder.BeAppendUint32(b, d.h[5])
-       b = byteorder.BeAppendUint32(b, d.h[6])
-       b = byteorder.BeAppendUint32(b, d.h[7])
-       b = append(b, d.x[:d.nx]...)
-       b = append(b, make([]byte, len(d.x)-d.nx)...)
-       b = byteorder.BeAppendUint64(b, d.len)
-       return b, nil
-}
-
-func (d *digest) UnmarshalBinary(b []byte) error {
-       if len(b) < len(magic224) || (d.is224 && string(b[:len(magic224)]) != magic224) || (!d.is224 && string(b[:len(magic256)]) != magic256) {
-               return errors.New("crypto/sha256: invalid hash state identifier")
-       }
-       if len(b) != marshaledSize {
-               return errors.New("crypto/sha256: invalid hash state size")
-       }
-       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, d.len = consumeUint64(b)
-       d.nx = int(d.len % chunk)
-       return nil
-}
-
-func consumeUint64(b []byte) ([]byte, uint64) {
-       return b[8:], byteorder.BeUint64(b)
-}
-
-func consumeUint32(b []byte) ([]byte, uint32) {
-       return b[4:], byteorder.BeUint32(b)
-}
-
-func (d *digest) Reset() {
-       if !d.is224 {
-               d.h[0] = init0
-               d.h[1] = init1
-               d.h[2] = init2
-               d.h[3] = init3
-               d.h[4] = init4
-               d.h[5] = init5
-               d.h[6] = init6
-               d.h[7] = init7
-       } else {
-               d.h[0] = init0_224
-               d.h[1] = init1_224
-               d.h[2] = init2_224
-               d.h[3] = init3_224
-               d.h[4] = init4_224
-               d.h[5] = init5_224
-               d.h[6] = init6_224
-               d.h[7] = init7_224
-       }
-       d.nx = 0
-       d.len = 0
-}
-
 // New returns a new [hash.Hash] computing the SHA256 checksum. The Hash
 // also implements [encoding.BinaryMarshaler], [encoding.BinaryAppender] and
 // [encoding.BinaryUnmarshaler] to marshal and unmarshal the internal
@@ -149,9 +35,7 @@ func New() hash.Hash {
        if boring.Enabled {
                return boring.NewSHA256()
        }
-       d := new(digest)
-       d.Reset()
-       return d
+       return sha256.New()
 }
 
 // New224 returns a new [hash.Hash] computing the SHA224 checksum. The Hash
@@ -162,92 +46,7 @@ func New224() hash.Hash {
        if boring.Enabled {
                return boring.NewSHA224()
        }
-       d := new(digest)
-       d.is224 = true
-       d.Reset()
-       return d
-}
-
-func (d *digest) Size() int {
-       if !d.is224 {
-               return Size
-       }
-       return Size224
-}
-
-func (d *digest) BlockSize() int { return BlockSize }
-
-func (d *digest) Write(p []byte) (nn int, err error) {
-       boring.Unreachable()
-       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[:])
-                       d.nx = 0
-               }
-               p = p[n:]
-       }
-       if len(p) >= chunk {
-               n := len(p) &^ (chunk - 1)
-               block(d, p[:n])
-               p = p[n:]
-       }
-       if len(p) > 0 {
-               d.nx = copy(d.x[:], p)
-       }
-       return
-}
-
-func (d *digest) Sum(in []byte) []byte {
-       boring.Unreachable()
-       // Make a copy of d so that caller can keep writing and summing.
-       d0 := *d
-       hash := d0.checkSum()
-       if d0.is224 {
-               return append(in, hash[:Size224]...)
-       }
-       return append(in, hash[:]...)
-}
-
-func (d *digest) checkSum() [Size]byte {
-       len := d.len
-       // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64.
-       var tmp [64 + 8]byte // padding + length buffer
-       tmp[0] = 0x80
-       var t uint64
-       if len%64 < 56 {
-               t = 56 - len%64
-       } else {
-               t = 64 + 56 - len%64
-       }
-
-       // Length in bits.
-       len <<= 3
-       padlen := tmp[:t+8]
-       byteorder.BePutUint64(padlen[t+0:], len)
-       d.Write(padlen)
-
-       if d.nx != 0 {
-               panic("d.nx != 0")
-       }
-
-       var digest [Size]byte
-
-       byteorder.BePutUint32(digest[0:], d.h[0])
-       byteorder.BePutUint32(digest[4:], d.h[1])
-       byteorder.BePutUint32(digest[8:], d.h[2])
-       byteorder.BePutUint32(digest[12:], d.h[3])
-       byteorder.BePutUint32(digest[16:], d.h[4])
-       byteorder.BePutUint32(digest[20:], d.h[5])
-       byteorder.BePutUint32(digest[24:], d.h[6])
-       if !d.is224 {
-               byteorder.BePutUint32(digest[28:], d.h[7])
-       }
-
-       return digest
+       return sha256.New224()
 }
 
 // Sum256 returns the SHA256 checksum of the data.
@@ -255,10 +54,11 @@ func Sum256(data []byte) [Size]byte {
        if boring.Enabled {
                return boring.SHA256(data)
        }
-       var d digest
-       d.Reset()
-       d.Write(data)
-       return d.checkSum()
+       h := New()
+       h.Write(data)
+       var sum [Size]byte
+       h.Sum(sum[:0])
+       return sum
 }
 
 // Sum224 returns the SHA224 checksum of the data.
@@ -266,11 +66,9 @@ func Sum224(data []byte) [Size224]byte {
        if boring.Enabled {
                return boring.SHA224(data)
        }
-       var d digest
-       d.is224 = true
-       d.Reset()
-       d.Write(data)
-       sum := d.checkSum()
-       ap := (*[Size224]byte)(sum[:])
-       return *ap
+       h := New224()
+       h.Write(data)
+       var sum [Size224]byte
+       h.Sum(sum[:0])
+       return sum
 }
index a7965b67268a08fdd90dc23b44cd38023a9c193f..40be1480dd51d12db06ac3a4f47ad189b676ca43 100644 (file)
@@ -300,16 +300,27 @@ func TestAllocations(t *testing.T) {
        if boring.Enabled {
                t.Skip("BoringCrypto doesn't allocate the same way as stdlib")
        }
-       in := []byte("hello, world!")
-       out := make([]byte, 0, Size)
-       h := New()
-       n := int(testing.AllocsPerRun(10, func() {
-               h.Reset()
-               h.Write(in)
-               out = h.Sum(out[:0])
-       }))
-       if n > 0 {
-               t.Errorf("allocs = %d, want 0", n)
+       if n := testing.AllocsPerRun(10, func() {
+               in := []byte("hello, world!")
+               out := make([]byte, 0, Size)
+
+               {
+                       h := New()
+                       h.Reset()
+                       h.Write(in)
+                       out = h.Sum(out[:0])
+               }
+               {
+                       h := New224()
+                       h.Reset()
+                       h.Write(in)
+                       out = h.Sum(out[:0])
+               }
+
+               Sum256(in)
+               Sum224(in)
+       }); n > 0 {
+               t.Errorf("allocs = %v, want 0", n)
        }
 }
 
index 0e2a34a1e347cf8e178fed3cdc8c480f854dcd31..0a12fde7bc060b7f7a8768048f7fb7ecc260ea58 100644 (file)
@@ -13,9 +13,8 @@ package sha512
 import (
        "crypto"
        "crypto/internal/boring"
-       "errors"
+       "crypto/internal/fips/sha512"
        "hash"
-       "internal/byteorder"
 )
 
 func init() {
@@ -43,167 +42,6 @@ const (
        BlockSize = 128
 )
 
-const (
-       chunk     = 128
-       init0     = 0x6a09e667f3bcc908
-       init1     = 0xbb67ae8584caa73b
-       init2     = 0x3c6ef372fe94f82b
-       init3     = 0xa54ff53a5f1d36f1
-       init4     = 0x510e527fade682d1
-       init5     = 0x9b05688c2b3e6c1f
-       init6     = 0x1f83d9abfb41bd6b
-       init7     = 0x5be0cd19137e2179
-       init0_224 = 0x8c3d37c819544da2
-       init1_224 = 0x73e1996689dcd4d6
-       init2_224 = 0x1dfab7ae32ff9c82
-       init3_224 = 0x679dd514582f9fcf
-       init4_224 = 0x0f6d2b697bd44da8
-       init5_224 = 0x77e36f7304c48942
-       init6_224 = 0x3f9d85a86a1d36c8
-       init7_224 = 0x1112e6ad91d692a1
-       init0_256 = 0x22312194fc2bf72c
-       init1_256 = 0x9f555fa3c84c64c2
-       init2_256 = 0x2393b86b6f53b151
-       init3_256 = 0x963877195940eabd
-       init4_256 = 0x96283ee2a88effe3
-       init5_256 = 0xbe5e1e2553863992
-       init6_256 = 0x2b0199fc2c85b8aa
-       init7_256 = 0x0eb72ddc81c52ca2
-       init0_384 = 0xcbbb9d5dc1059ed8
-       init1_384 = 0x629a292a367cd507
-       init2_384 = 0x9159015a3070dd17
-       init3_384 = 0x152fecd8f70e5939
-       init4_384 = 0x67332667ffc00b31
-       init5_384 = 0x8eb44a8768581511
-       init6_384 = 0xdb0c2e0d64f98fa7
-       init7_384 = 0x47b5481dbefa4fa4
-)
-
-// digest represents the partial evaluation of a checksum.
-type digest struct {
-       h        [8]uint64
-       x        [chunk]byte
-       nx       int
-       len      uint64
-       function crypto.Hash
-}
-
-func (d *digest) Reset() {
-       switch d.function {
-       case crypto.SHA384:
-               d.h[0] = init0_384
-               d.h[1] = init1_384
-               d.h[2] = init2_384
-               d.h[3] = init3_384
-               d.h[4] = init4_384
-               d.h[5] = init5_384
-               d.h[6] = init6_384
-               d.h[7] = init7_384
-       case crypto.SHA512_224:
-               d.h[0] = init0_224
-               d.h[1] = init1_224
-               d.h[2] = init2_224
-               d.h[3] = init3_224
-               d.h[4] = init4_224
-               d.h[5] = init5_224
-               d.h[6] = init6_224
-               d.h[7] = init7_224
-       case crypto.SHA512_256:
-               d.h[0] = init0_256
-               d.h[1] = init1_256
-               d.h[2] = init2_256
-               d.h[3] = init3_256
-               d.h[4] = init4_256
-               d.h[5] = init5_256
-               d.h[6] = init6_256
-               d.h[7] = init7_256
-       default:
-               d.h[0] = init0
-               d.h[1] = init1
-               d.h[2] = init2
-               d.h[3] = init3
-               d.h[4] = init4
-               d.h[5] = init5
-               d.h[6] = init6
-               d.h[7] = init7
-       }
-       d.nx = 0
-       d.len = 0
-}
-
-const (
-       magic384      = "sha\x04"
-       magic512_224  = "sha\x05"
-       magic512_256  = "sha\x06"
-       magic512      = "sha\x07"
-       marshaledSize = len(magic512) + 8*8 + chunk + 8
-)
-
-func (d *digest) MarshalBinary() ([]byte, error) {
-       return d.AppendBinary(make([]byte, 0, marshaledSize))
-}
-
-func (d *digest) AppendBinary(b []byte) ([]byte, error) {
-       switch d.function {
-       case crypto.SHA384:
-               b = append(b, magic384...)
-       case crypto.SHA512_224:
-               b = append(b, magic512_224...)
-       case crypto.SHA512_256:
-               b = append(b, magic512_256...)
-       case crypto.SHA512:
-               b = append(b, magic512...)
-       default:
-               return nil, errors.New("crypto/sha512: invalid hash function")
-       }
-       b = byteorder.BeAppendUint64(b, d.h[0])
-       b = byteorder.BeAppendUint64(b, d.h[1])
-       b = byteorder.BeAppendUint64(b, d.h[2])
-       b = byteorder.BeAppendUint64(b, d.h[3])
-       b = byteorder.BeAppendUint64(b, d.h[4])
-       b = byteorder.BeAppendUint64(b, d.h[5])
-       b = byteorder.BeAppendUint64(b, d.h[6])
-       b = byteorder.BeAppendUint64(b, d.h[7])
-       b = append(b, d.x[:d.nx]...)
-       b = append(b, make([]byte, len(d.x)-d.nx)...)
-       b = byteorder.BeAppendUint64(b, d.len)
-       return b, nil
-}
-
-func (d *digest) UnmarshalBinary(b []byte) error {
-       if len(b) < len(magic512) {
-               return errors.New("crypto/sha512: invalid hash state identifier")
-       }
-       switch {
-       case d.function == crypto.SHA384 && string(b[:len(magic384)]) == magic384:
-       case d.function == crypto.SHA512_224 && string(b[:len(magic512_224)]) == magic512_224:
-       case d.function == crypto.SHA512_256 && string(b[:len(magic512_256)]) == magic512_256:
-       case d.function == crypto.SHA512 && string(b[:len(magic512)]) == magic512:
-       default:
-               return errors.New("crypto/sha512: invalid hash state identifier")
-       }
-       if len(b) != marshaledSize {
-               return errors.New("crypto/sha512: invalid hash state size")
-       }
-       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, d.len = consumeUint64(b)
-       d.nx = int(d.len % chunk)
-       return nil
-}
-
-func consumeUint64(b []byte) ([]byte, uint64) {
-       return b[8:], byteorder.BeUint64(b)
-}
-
 // New returns a new [hash.Hash] computing the SHA-512 checksum. The Hash
 // also implements [encoding.BinaryMarshaler], [encoding.BinaryAppender] and
 // [encoding.BinaryUnmarshaler] to marshal and unmarshal the internal
@@ -212,9 +50,7 @@ func New() hash.Hash {
        if boring.Enabled {
                return boring.NewSHA512()
        }
-       d := &digest{function: crypto.SHA512}
-       d.Reset()
-       return d
+       return sha512.New()
 }
 
 // New512_224 returns a new [hash.Hash] computing the SHA-512/224 checksum. The Hash
@@ -222,9 +58,7 @@ func New() hash.Hash {
 // [encoding.BinaryUnmarshaler] to marshal and unmarshal the internal
 // state of the hash.
 func New512_224() hash.Hash {
-       d := &digest{function: crypto.SHA512_224}
-       d.Reset()
-       return d
+       return sha512.New512_224()
 }
 
 // New512_256 returns a new [hash.Hash] computing the SHA-512/256 checksum. The Hash
@@ -232,9 +66,7 @@ func New512_224() hash.Hash {
 // [encoding.BinaryUnmarshaler] to marshal and unmarshal the internal
 // state of the hash.
 func New512_256() hash.Hash {
-       d := &digest{function: crypto.SHA512_256}
-       d.Reset()
-       return d
+       return sha512.New512_256()
 }
 
 // New384 returns a new [hash.Hash] computing the SHA-384 checksum. The Hash
@@ -245,110 +77,7 @@ func New384() hash.Hash {
        if boring.Enabled {
                return boring.NewSHA384()
        }
-       d := &digest{function: crypto.SHA384}
-       d.Reset()
-       return d
-}
-
-func (d *digest) Size() int {
-       switch d.function {
-       case crypto.SHA512_224:
-               return Size224
-       case crypto.SHA512_256:
-               return Size256
-       case crypto.SHA384:
-               return Size384
-       default:
-               return Size
-       }
-}
-
-func (d *digest) BlockSize() int { return BlockSize }
-
-func (d *digest) Write(p []byte) (nn int, err error) {
-       if d.function != crypto.SHA512_224 && d.function != crypto.SHA512_256 {
-               boring.Unreachable()
-       }
-       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[:])
-                       d.nx = 0
-               }
-               p = p[n:]
-       }
-       if len(p) >= chunk {
-               n := len(p) &^ (chunk - 1)
-               block(d, p[:n])
-               p = p[n:]
-       }
-       if len(p) > 0 {
-               d.nx = copy(d.x[:], p)
-       }
-       return
-}
-
-func (d *digest) Sum(in []byte) []byte {
-       if d.function != crypto.SHA512_224 && d.function != crypto.SHA512_256 {
-               boring.Unreachable()
-       }
-       // Make a copy of d so that caller can keep writing and summing.
-       d0 := new(digest)
-       *d0 = *d
-       hash := d0.checkSum()
-       switch d0.function {
-       case crypto.SHA384:
-               return append(in, hash[:Size384]...)
-       case crypto.SHA512_224:
-               return append(in, hash[:Size224]...)
-       case crypto.SHA512_256:
-               return append(in, hash[:Size256]...)
-       default:
-               return append(in, hash[:]...)
-       }
-}
-
-func (d *digest) checkSum() [Size]byte {
-       // Padding. Add a 1 bit and 0 bits until 112 bytes mod 128.
-       len := d.len
-       var tmp [128 + 16]byte // padding + length buffer
-       tmp[0] = 0x80
-       var t uint64
-       if len%128 < 112 {
-               t = 112 - len%128
-       } else {
-               t = 128 + 112 - len%128
-       }
-
-       // Length in bits.
-       len <<= 3
-       padlen := tmp[:t+16]
-       // Upper 64 bits are always zero, because len variable has type uint64,
-       // and tmp is already zeroed at that index, so we can skip updating it.
-       // byteorder.BePutUint64(padlen[t+0:], 0)
-       byteorder.BePutUint64(padlen[t+8:], len)
-       d.Write(padlen)
-
-       if d.nx != 0 {
-               panic("d.nx != 0")
-       }
-
-       var digest [Size]byte
-       byteorder.BePutUint64(digest[0:], d.h[0])
-       byteorder.BePutUint64(digest[8:], d.h[1])
-       byteorder.BePutUint64(digest[16:], d.h[2])
-       byteorder.BePutUint64(digest[24:], d.h[3])
-       byteorder.BePutUint64(digest[32:], d.h[4])
-       byteorder.BePutUint64(digest[40:], d.h[5])
-       if d.function != crypto.SHA384 {
-               byteorder.BePutUint64(digest[48:], d.h[6])
-               byteorder.BePutUint64(digest[56:], d.h[7])
-       }
-
-       return digest
+       return sha512.New384()
 }
 
 // Sum512 returns the SHA512 checksum of the data.
@@ -356,10 +85,11 @@ func Sum512(data []byte) [Size]byte {
        if boring.Enabled {
                return boring.SHA512(data)
        }
-       d := digest{function: crypto.SHA512}
-       d.Reset()
-       d.Write(data)
-       return d.checkSum()
+       h := New()
+       h.Write(data)
+       var sum [Size]byte
+       h.Sum(sum[:0])
+       return sum
 }
 
 // Sum384 returns the SHA384 checksum of the data.
@@ -367,30 +97,27 @@ func Sum384(data []byte) [Size384]byte {
        if boring.Enabled {
                return boring.SHA384(data)
        }
-       d := digest{function: crypto.SHA384}
-       d.Reset()
-       d.Write(data)
-       sum := d.checkSum()
-       ap := (*[Size384]byte)(sum[:])
-       return *ap
+       h := New384()
+       h.Write(data)
+       var sum [Size384]byte
+       h.Sum(sum[:0])
+       return sum
 }
 
 // Sum512_224 returns the Sum512/224 checksum of the data.
 func Sum512_224(data []byte) [Size224]byte {
-       d := digest{function: crypto.SHA512_224}
-       d.Reset()
-       d.Write(data)
-       sum := d.checkSum()
-       ap := (*[Size224]byte)(sum[:])
-       return *ap
+       h := New512_224()
+       h.Write(data)
+       var sum [Size224]byte
+       h.Sum(sum[:0])
+       return sum
 }
 
 // Sum512_256 returns the Sum512/256 checksum of the data.
 func Sum512_256(data []byte) [Size256]byte {
-       d := digest{function: crypto.SHA512_256}
-       d.Reset()
-       d.Write(data)
-       sum := d.checkSum()
-       ap := (*[Size256]byte)(sum[:])
-       return *ap
+       h := New512_256()
+       h.Write(data)
+       var sum [Size256]byte
+       h.Sum(sum[:0])
+       return sum
 }
index 9c41bdc367e7cf4d685b1c777504f511f2c3b5d4..6e3d9bce1cf09569b1a3ea59b0280f5812b72494 100644 (file)
@@ -905,16 +905,41 @@ func TestAllocations(t *testing.T) {
        if boring.Enabled {
                t.Skip("BoringCrypto doesn't allocate the same way as stdlib")
        }
-       in := []byte("hello, world!")
-       out := make([]byte, 0, Size)
-       h := New()
-       n := int(testing.AllocsPerRun(10, func() {
-               h.Reset()
-               h.Write(in)
-               out = h.Sum(out[:0])
-       }))
-       if n > 0 {
-               t.Errorf("allocs = %d, want 0", n)
+       if n := testing.AllocsPerRun(10, func() {
+               in := []byte("hello, world!")
+               out := make([]byte, 0, Size)
+
+               {
+                       h := New()
+                       h.Reset()
+                       h.Write(in)
+                       out = h.Sum(out[:0])
+               }
+               {
+                       h := New512_224()
+                       h.Reset()
+                       h.Write(in)
+                       out = h.Sum(out[:0])
+               }
+               {
+                       h := New512_256()
+                       h.Reset()
+                       h.Write(in)
+                       out = h.Sum(out[:0])
+               }
+               {
+                       h := New384()
+                       h.Reset()
+                       h.Write(in)
+                       out = h.Sum(out[:0])
+               }
+
+               Sum512(in)
+               Sum384(in)
+               Sum512_224(in)
+               Sum512_256(in)
+       }); n > 0 {
+               t.Errorf("allocs = %v, want 0", n)
        }
 }
 
index 43c3fb5aed36a6e1bf3d650cdbef3a40323f3ca6..01f4f2c3c6d9d82e791e69a6541fe0f345a40123 100644 (file)
@@ -442,16 +442,25 @@ var depsRules = `
        NET, log
        < net/mail;
 
+       NONE < crypto/internal/impl;
+
+       # FIPS is the FIPS 140 module.
+       # It must not depend on external crypto packages.
+       # Internal packages imported by FIPS might need to retain
+       # backwards compatibility with older versions of the module.
+       RUNTIME, crypto/internal/impl
+       < crypto/internal/fips/sha256
+       < crypto/internal/fips/sha512
+       < FIPS;
+
        NONE < crypto/internal/boring/sig, crypto/internal/boring/syso;
        sync/atomic < crypto/internal/boring/bcache, crypto/internal/boring/fipstls;
        crypto/internal/boring/sig, crypto/internal/boring/fipstls < crypto/tls/fipsonly;
 
-       NONE < crypto/internal/impl;
-
        # CRYPTO is core crypto algorithms - no cgo, fmt, net.
+       FIPS,
        crypto/internal/boring/sig,
        crypto/internal/boring/syso,
-       crypto/internal/impl,
        golang.org/x/sys/cpu,
        hash, embed
        < crypto
index 8913c7d2c9602371392b42ebf9b6b2aabe2b3838..3b9b2852c462c6d15120840aa2477fe90f0c1ace 100644 (file)
@@ -20,6 +20,7 @@ import (
        "os"
        "path/filepath"
        "runtime"
+       "slices"
        "strings"
        "sync"
        "testing"
@@ -356,17 +357,6 @@ func TestStdKen(t *testing.T) {
 // Package paths of excluded packages.
 var excluded = map[string]bool{
        "builtin": true,
-
-       // See go.dev/issue/46027: some imports are missing for this submodule.
-       "crypto/aes/_asm/gcm":                     true,
-       "crypto/aes/_asm/standard":                true,
-       "crypto/internal/bigmod/_asm":             true,
-       "crypto/internal/edwards25519/field/_asm": true,
-       "crypto/internal/nistec/_asm":             true,
-       "crypto/md5/_asm":                         true,
-       "crypto/sha1/_asm":                        true,
-       "crypto/sha256/_asm":                      true,
-       "crypto/sha512/_asm":                      true,
 }
 
 // printPackageMu synchronizes the printing of type-checked package files in
@@ -448,6 +438,11 @@ func pkgFilenames(dir string, includeTest bool) ([]string, error) {
        if excluded[pkg.ImportPath] {
                return nil, nil
        }
+       if slices.Contains(strings.Split(pkg.ImportPath, "/"), "_asm") {
+               // Submodules where not all dependencies are available.
+               // See go.dev/issue/46027.
+               return nil, nil
+       }
        var filenames []string
        for _, name := range pkg.GoFiles {
                filenames = append(filenames, filepath.Join(pkg.Dir, name))