crypto/sha1: use cryptotest.TestAllImplementations and impl.Register

Not running TryBots on s390x because the new LUCI builder is broken.

Change-Id: I6a6a4656a8d52fa5ace9effa67a88fbfd7d19b04
Reviewed-on: https://go-review.googlesource.com/c/go/+/674915
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
This commit is contained in:
Filippo Valsorda 2025-05-21 14:29:26 +02:00 committed by Gopher Robot
parent 272262750f
commit a731955f0f
8 changed files with 73 additions and 80 deletions

View File

@ -1,34 +0,0 @@
// Copyright 2016 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.
//go:build s390x && !purego
package sha1
import (
"fmt"
"io"
"testing"
)
// Tests the fallback code path in case the optimized asm
// implementation cannot be used.
// See also TestBlockGeneric.
func TestGenericPath(t *testing.T) {
if !useAsm {
t.Skipf("assembly implementation unavailable")
}
useAsm = false
defer func() { useAsm = true }()
c := New()
in := "ΑΒΓΔΕϜΖΗΘΙΚΛΜΝΞΟΠϺϘΡΣΤΥΦΧΨΩ"
gold := "0f58c2bb130f8182375f325c18342215255387e5"
if _, err := io.WriteString(c, in); err != nil {
t.Fatalf("could not write to c: %v", err)
}
out := fmt.Sprintf("%x", c.Sum(nil))
if out != gold {
t.Fatalf("mismatch: got %s, wanted %s", out, gold)
}
}

View File

@ -7,21 +7,24 @@
package sha1_test
import (
"crypto/internal/cryptotest"
"crypto/sha1"
"syscall"
"testing"
)
func TestOutOfBoundsRead(t *testing.T) {
const pageSize = 4 << 10
data, err := syscall.Mmap(0, 0, 2*pageSize, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_ANON|syscall.MAP_PRIVATE)
if err != nil {
panic(err)
}
if err := syscall.Mprotect(data[pageSize:], syscall.PROT_NONE); err != nil {
panic(err)
}
for i := 0; i < pageSize; i++ {
sha1.Sum(data[pageSize-i : pageSize])
}
cryptotest.TestAllImplementations(t, "sha1", func(t *testing.T) {
const pageSize = 4 << 10
data, err := syscall.Mmap(0, 0, 2*pageSize, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_ANON|syscall.MAP_PRIVATE)
if err != nil {
panic(err)
}
if err := syscall.Mprotect(data[pageSize:], syscall.PROT_NONE); err != nil {
panic(err)
}
for i := 0; i < pageSize; i++ {
sha1.Sum(data[pageSize-i : pageSize])
}
})
}

View File

@ -10,7 +10,6 @@ import (
"bytes"
"crypto/internal/boring"
"crypto/internal/cryptotest"
"crypto/rand"
"encoding"
"fmt"
"hash"
@ -60,6 +59,9 @@ var golden = []sha1Test{
}
func TestGolden(t *testing.T) {
cryptotest.TestAllImplementations(t, "sha1", testGolden)
}
func testGolden(t *testing.T) {
for i := 0; i < len(golden); i++ {
g := golden[i]
s := fmt.Sprintf("%x", Sum([]byte(g.in)))
@ -97,6 +99,9 @@ func TestGolden(t *testing.T) {
}
func TestGoldenMarshal(t *testing.T) {
cryptotest.TestAllImplementations(t, "sha1", testGoldenMarshal)
}
func testGoldenMarshal(t *testing.T) {
h := New()
h2 := New()
for _, g := range golden {
@ -156,23 +161,6 @@ func TestBlockSize(t *testing.T) {
}
}
// Tests that blockGeneric (pure Go) and block (in assembly for some architectures) match.
func TestBlockGeneric(t *testing.T) {
if boring.Enabled {
t.Skip("BoringCrypto doesn't expose digest")
}
for i := 1; i < 30; i++ { // arbitrary factor
gen, asm := New().(*digest), New().(*digest)
buf := make([]byte, BlockSize*i)
rand.Read(buf)
blockGeneric(gen, buf)
block(asm, buf)
if *gen != *asm {
t.Errorf("For %#v block and blockGeneric resulted in different states", buf)
}
}
}
// Tests for unmarshaling hashes that have hashed a large amount of data
// The initial hash generation is omitted from the test, because it takes a long time.
// The test contains some already-generated states, and their expected sums
@ -210,8 +198,10 @@ func safeSum(h hash.Hash) (sum []byte, err error) {
}
func TestLargeHashes(t *testing.T) {
cryptotest.TestAllImplementations(t, "sha1", testLargeHashes)
}
func testLargeHashes(t *testing.T) {
for i, test := range largeUnmarshalTests {
h := New()
if err := h.(encoding.BinaryUnmarshaler).UnmarshalBinary([]byte(test.state)); err != nil {
t.Errorf("test %d could not unmarshal: %v", i, err)
@ -246,7 +236,9 @@ func TestAllocations(t *testing.T) {
}
func TestSHA1Hash(t *testing.T) {
cryptotest.TestHash(t, New)
cryptotest.TestAllImplementations(t, "sha1", func(t *testing.T) {
cryptotest.TestHash(t, New)
})
}
func TestExtraMethods(t *testing.T) {

View File

@ -6,7 +6,10 @@
package sha1
import "internal/cpu"
import (
"crypto/internal/impl"
"internal/cpu"
)
//go:noescape
func blockAVX2(dig *digest, p []byte)
@ -17,6 +20,11 @@ func blockSHANI(dig *digest, p []byte)
var useAVX2 = cpu.X86.HasAVX && cpu.X86.HasAVX2 && cpu.X86.HasBMI1 && cpu.X86.HasBMI2
var useSHANI = cpu.X86.HasAVX && cpu.X86.HasSHA && cpu.X86.HasSSE41 && cpu.X86.HasSSSE3
func init() {
impl.Register("sha1", "AVX2", &useAVX2)
impl.Register("sha1", "SHA-NI", &useSHANI)
}
func block(dig *digest, p []byte) {
if useSHANI {
blockSHANI(dig, p)

View File

@ -6,7 +6,16 @@
package sha1
import "internal/cpu"
import (
"crypto/internal/impl"
"internal/cpu"
)
var useSHA1 = cpu.ARM64.HasSHA1
func init() {
impl.Register("sha1", "Armv8.0", &useSHA1)
}
var k = []uint32{
0x5A827999,
@ -19,10 +28,10 @@ var k = []uint32{
func sha1block(h []uint32, p []byte, k []uint32)
func block(dig *digest, p []byte) {
if !cpu.ARM64.HasSHA1 {
blockGeneric(dig, p)
} else {
if useSHA1 {
h := dig.h[:]
sha1block(h, p, k)
} else {
blockGeneric(dig, p)
}
}

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build (386 || arm || loong64 || s390x) && !purego
//go:build (386 || arm || loong64) && !purego
package sha1

View File

@ -6,6 +6,26 @@
package sha1
import "internal/cpu"
import (
"crypto/internal/impl"
"internal/cpu"
)
var useAsm = cpu.S390X.HasSHA1
var useSHA1 = cpu.S390X.HasSHA1
func init() {
// CP Assist for Cryptographic Functions (CPACF)
// https://www.ibm.com/docs/en/zos/3.1.0?topic=icsf-cp-assist-cryptographic-functions-cpacf
impl.Register("sha1", "CPACF", &useSHA1)
}
//go:noescape
func blockS390X(dig *digest, p []byte)
func block(dig *digest, p []byte) {
if useSHA1 {
blockS390X(dig, p)
} else {
blockGeneric(dig, p)
}
}

View File

@ -6,17 +6,12 @@
#include "textflag.h"
// func block(dig *digest, p []byte)
TEXT ·block(SB), NOSPLIT|NOFRAME, $0-32
MOVBZ ·useAsm(SB), R4
// 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 $1, R0 // SHA-1 function code
CMPBEQ R4, $0, generic
loop:
KIMD R0, R2 // compute intermediate message digest (KIMD)
BVS loop // continue if interrupted
RET
generic:
BR ·blockGeneric(SB)