Skip to content

Commit 7ba0c62

Browse files
committed
crypto, internal/cpu: fix s390x AES feature detection and update SHA implementations
Hardware AES support in Go on s390x currently requires ECB, CBC and CTR modes be available. It also requires that either the GHASH or GCM facilities are available. The existing checks missed some of these constraints. While we're here simplify the cpu package on s390x, moving masking code out of assembly and into Go code. Also, update SHA-{1,256,512} implementations to use the cpu package since that is now trivial. Finally I also added a test for internal/cpu on s390x which loads /proc/cpuinfo and checks it against the flags set by internal/cpu. Updates #25822 for changes to vet whitelist. Change-Id: Iac4183f571643209e027f730989c60a811c928eb Reviewed-on: https://go-review.googlesource.com/114397 Run-TryBot: Michael Munday <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent 40fc4bb commit 7ba0c62

15 files changed

+315
-200
lines changed

src/cmd/vet/all/whitelist/s390x.txt

+7
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,10 @@ runtime/memclr_s390x.s: [s390x] memclr_s390x_exrl_xc: function memclr_s390x_exrl
55
runtime/memmove_s390x.s: [s390x] memmove_s390x_exrl_mvc: function memmove_s390x_exrl_mvc missing Go declaration
66
runtime/tls_s390x.s: [s390x] save_g: function save_g missing Go declaration
77
runtime/tls_s390x.s: [s390x] load_g: function load_g missing Go declaration
8+
internal/cpu/cpu_s390x.s: [s390x] stfle: invalid MOVD of ret+0(FP); cpu.facilityList is 32-byte value
9+
internal/cpu/cpu_s390x.s: [s390x] kmQuery: invalid MOVD of ret+0(FP); cpu.queryResult is 16-byte value
10+
internal/cpu/cpu_s390x.s: [s390x] kmcQuery: invalid MOVD of ret+0(FP); cpu.queryResult is 16-byte value
11+
internal/cpu/cpu_s390x.s: [s390x] kmctrQuery: invalid MOVD of ret+0(FP); cpu.queryResult is 16-byte value
12+
internal/cpu/cpu_s390x.s: [s390x] kmaQuery: invalid MOVD of ret+0(FP); cpu.queryResult is 16-byte value
13+
internal/cpu/cpu_s390x.s: [s390x] kimdQuery: invalid MOVD of ret+0(FP); cpu.queryResult is 16-byte value
14+
internal/cpu/cpu_s390x.s: [s390x] klmdQuery: invalid MOVD of ret+0(FP); cpu.queryResult is 16-byte value

src/crypto/aes/cipher_s390x.go

+5-6
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,11 @@ type aesCipherAsm struct {
3131
func cryptBlocks(c code, key, dst, src *byte, length int)
3232

3333
func newCipher(key []byte) (cipher.Block, error) {
34-
// Strictly speaking, this check should be for HasKM.
35-
// The check for HasKMC and HasKMCTR provides compatibility
36-
// with the existing optimized s390x CBC and CTR implementations
37-
// in this package, which already assert that they meet the
38-
// cbcEncAble, cbcDecAble, and ctrAble interfaces
39-
if !(cpu.S390X.HasKM && cpu.S390X.HasKMC && cpu.S390X.HasKMCTR) {
34+
// The aesCipherAsm type implements the cbcEncAble, cbcDecAble,
35+
// ctrAble and gcmAble interfaces. We therefore need to check
36+
// for all the features required to implement these modes.
37+
// Keep in sync with crypto/tls/common.go.
38+
if !(cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR && (cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM)) {
4039
return newCipherGeneric(key)
4140
}
4241

src/crypto/aes/gcm_s390x.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func (c *aesCipherAsm) NewGCM(nonceSize, tagSize int) (cipher.AEAD, error) {
8585
nonceSize: nonceSize,
8686
tagSize: tagSize,
8787
}
88-
if cpu.S390X.HasKMA {
88+
if cpu.S390X.HasAESGCM {
8989
g := gcmKMA{g}
9090
return &g, nil
9191
}

src/crypto/sha1/sha1block_s390x.go

+2-5
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44

55
package sha1
66

7-
// featureCheck reports whether the CPU supports the
8-
// SHA-1 compute intermediate message digest (KIMD)
9-
// function code.
10-
func featureCheck() bool
7+
import "internal/cpu"
118

12-
var useAsm = featureCheck()
9+
var useAsm = cpu.S390X.HasSHA1

src/crypto/sha1/sha1block_s390x.s

+10-24
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,17 @@
44

55
#include "textflag.h"
66

7-
// func featureCheck() bool
8-
TEXT ·featureCheck(SB),NOSPLIT,$16-1
9-
LA tmp-16(SP), R1
10-
XOR R0, R0 // query function code is 0
11-
WORD $0xB93E0006 // KIMD (R6 is ignored)
12-
MOVBZ tmp-16(SP), R4 // get the first byte
13-
AND $0x40, R4 // bit 1 (big endian) for SHA-1
14-
CMPBEQ R4, $0, nosha1
15-
MOVB $1, ret+0(FP)
16-
RET
17-
nosha1:
18-
MOVB $0, ret+0(FP)
19-
RET
20-
217
// func block(dig *digest, p []byte)
22-
TEXT ·block(SB),NOSPLIT,$0-32
23-
MOVBZ ·useAsm(SB), R4
24-
LMG dig+0(FP), R1, R3 // R2 = &p[0], R3 = len(p)
25-
CMPBNE R4, $1, generic
26-
MOVBZ $1, R0 // SHA-1 function code
8+
TEXT ·block(SB), NOSPLIT|NOFRAME, $0-32
9+
MOVBZ ·useAsm(SB), R4
10+
LMG dig+0(FP), R1, R3 // R2 = &p[0], R3 = len(p)
11+
MOVBZ $1, R0 // SHA-1 function code
12+
CMPBEQ R4, $0, generic
13+
2714
loop:
28-
WORD $0xB93E0002 // KIMD R2
29-
BVS loop // continue if interrupted
30-
done:
31-
XOR R0, R0 // restore R0
15+
WORD $0xB93E0002 // KIMD R2
16+
BVS loop // continue if interrupted
3217
RET
18+
3319
generic:
34-
BR ·blockGeneric(SB)
20+
BR ·blockGeneric(SB)

src/crypto/sha256/sha256block_s390x.go

+2-5
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44

55
package sha256
66

7-
// featureCheck reports whether the CPU supports the
8-
// SHA256 compute intermediate message digest (KIMD)
9-
// function code.
10-
func featureCheck() bool
7+
import "internal/cpu"
118

12-
var useAsm = featureCheck()
9+
var useAsm = cpu.S390X.HasSHA256

src/crypto/sha256/sha256block_s390x.s

+10-24
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,17 @@
44

55
#include "textflag.h"
66

7-
// func featureCheck() bool
8-
TEXT ·featureCheck(SB),NOSPLIT,$16-1
9-
LA tmp-16(SP), R1
10-
XOR R0, R0 // query function code is 0
11-
WORD $0xB93E0006 // KIMD (R6 is ignored)
12-
MOVBZ tmp-16(SP), R4 // get the first byte
13-
AND $0x20, R4 // bit 2 (big endian) for SHA256
14-
CMPBEQ R4, $0, nosha256
15-
MOVB $1, ret+0(FP)
16-
RET
17-
nosha256:
18-
MOVB $0, ret+0(FP)
19-
RET
20-
217
// func block(dig *digest, p []byte)
22-
TEXT ·block(SB),NOSPLIT,$0-32
23-
MOVBZ ·useAsm(SB), R4
24-
LMG dig+0(FP), R1, R3 // R2 = &p[0], R3 = len(p)
25-
CMPBNE R4, $1, generic
26-
MOVBZ $2, R0 // SHA256 function code
8+
TEXT ·block(SB), NOSPLIT|NOFRAME, $0-32
9+
MOVBZ ·useAsm(SB), R4
10+
LMG dig+0(FP), R1, R3 // R2 = &p[0], R3 = len(p)
11+
MOVBZ $2, R0 // SHA-256 function code
12+
CMPBEQ R4, $0, generic
13+
2714
loop:
28-
WORD $0xB93E0002 // KIMD R2
29-
BVS loop // continue if interrupted
30-
done:
31-
XOR R0, R0 // restore R0
15+
WORD $0xB93E0002 // KIMD R2
16+
BVS loop // continue if interrupted
3217
RET
18+
3319
generic:
34-
BR ·blockGeneric(SB)
20+
BR ·blockGeneric(SB)

src/crypto/sha512/sha512block_s390x.go

+2-5
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44

55
package sha512
66

7-
// featureCheck reports whether the CPU supports the
8-
// SHA512 compute intermediate message digest (KIMD)
9-
// function code.
10-
func featureCheck() bool
7+
import "internal/cpu"
118

12-
var useAsm = featureCheck()
9+
var useAsm = cpu.S390X.HasSHA512

src/crypto/sha512/sha512block_s390x.s

+10-24
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,17 @@
44

55
#include "textflag.h"
66

7-
// func featureCheck() bool
8-
TEXT ·featureCheck(SB),NOSPLIT,$16-1
9-
LA tmp-16(SP), R1
10-
XOR R0, R0 // query function code is 0
11-
WORD $0xB93E0006 // KIMD (R6 is ignored)
12-
MOVBZ tmp-16(SP), R4 // get the first byte
13-
AND $0x10, R4 // bit 3 (big endian) for SHA512
14-
CMPBEQ R4, $0, nosha512
15-
MOVB $1, ret+0(FP)
16-
RET
17-
nosha512:
18-
MOVB $0, ret+0(FP)
19-
RET
20-
217
// func block(dig *digest, p []byte)
22-
TEXT ·block(SB),NOSPLIT,$0-32
23-
MOVBZ ·useAsm(SB), R4
24-
LMG dig+0(FP), R1, R3 // R2 = &p[0], R3 = len(p)
25-
CMPBNE R4, $1, generic
26-
MOVBZ $3, R0 // SHA512 function code
8+
TEXT ·block(SB), NOSPLIT|NOFRAME, $0-32
9+
MOVBZ ·useAsm(SB), R4
10+
LMG dig+0(FP), R1, R3 // R2 = &p[0], R3 = len(p)
11+
MOVBZ $3, R0 // SHA-512 function code
12+
CMPBEQ R4, $0, generic
13+
2714
loop:
28-
WORD $0xB93E0002 // KIMD R2
29-
BVS loop // continue if interrupted
30-
done:
31-
XOR R0, R0 // restore R0
15+
WORD $0xB93E0002 // KIMD R2
16+
BVS loop // continue if interrupted
3217
RET
18+
3319
generic:
34-
BR ·blockGeneric(SB)
20+
BR ·blockGeneric(SB)

src/crypto/tls/common.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -930,7 +930,8 @@ func initDefaultCipherSuites() {
930930
hasGCMAsmARM64 := false
931931
// hasGCMAsmARM64 := cpu.ARM64.HasAES && cpu.ARM64.HasPMULL
932932

933-
hasGCMAsmS390X := cpu.S390X.HasKM && (cpu.S390X.HasKMA || (cpu.S390X.HasKMCTR && cpu.S390X.HasKIMD))
933+
// Keep in sync with crypto/aes/cipher_s390x.go.
934+
hasGCMAsmS390X := cpu.S390X.HasAES && cpu.S390X.HasAESCBC && cpu.S390X.HasAESCTR && (cpu.S390X.HasGHASH || cpu.S390X.HasAESGCM)
934935

935936
hasGCMAsm := hasGCMAsmAMD64 || hasGCMAsmARM64 || hasGCMAsmS390X
936937

src/internal/cpu/cpu.go

+18-8
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,24 @@ type arm64 struct {
9898
var S390X s390x
9999

100100
type s390x struct {
101-
_ [CacheLineSize]byte
102-
HasVX bool // vector facility. Note: the runtime sets this when it processes auxv records.
103-
HasKM bool // cipher message (KM)
104-
HasKMA bool // cipher message assist (KMA)
105-
HasKMC bool // cipher message with chaining (KMC)
106-
HasKMCTR bool // cipher message with counter (KMCTR)
107-
HasKIMD bool // compute intermediate message digest (KIMD)
108-
_ [CacheLineSize]byte
101+
_ [CacheLineSize]byte
102+
HasZArch bool // z architecture mode is active [mandatory]
103+
HasSTFLE bool // store facility list extended [mandatory]
104+
HasLDisp bool // long (20-bit) displacements [mandatory]
105+
HasEImm bool // 32-bit immediates [mandatory]
106+
HasDFP bool // decimal floating point
107+
HasETF3Enhanced bool // ETF-3 enhanced
108+
HasMSA bool // message security assist (CPACF)
109+
HasAES bool // KM-AES{128,192,256} functions
110+
HasAESCBC bool // KMC-AES{128,192,256} functions
111+
HasAESCTR bool // KMCTR-AES{128,192,256} functions
112+
HasAESGCM bool // KMA-GCM-AES{128,192,256} functions
113+
HasGHASH bool // KIMD-GHASH function
114+
HasSHA1 bool // K{I,L}MD-SHA-1 functions
115+
HasSHA256 bool // K{I,L}MD-SHA-256 functions
116+
HasSHA512 bool // K{I,L}MD-SHA-512 functions
117+
HasVX bool // vector facility. Note: the runtime sets this when it processes auxv records.
118+
_ [CacheLineSize]byte
109119
}
110120

111121
// initialize examines the processor and sets the relevant variables above.

src/internal/cpu/cpu_no_init.go

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// +build !arm64
99
// +build !ppc64
1010
// +build !ppc64le
11+
// +build !s390x
1112

1213
package cpu
1314

0 commit comments

Comments
 (0)