1 // Copyright 2019 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.
7 const cacheLineSize = 256
10 // bit mask values from /usr/include/bits/hwcap.h
22 // bitIsSet reports whether the bit at index is set. The bit index
23 // is in big endian order, so bit index 0 is the leftmost bit.
24 func bitIsSet(bits []uint64, index uint) bool {
25 return bits[index/64]&((1<<63)>>(index%64)) != 0
28 // function is the code for the named cryptographic function.
32 // KM{,A,C,CTR} function codes
33 aes128 function = 18 // AES-128
34 aes192 function = 19 // AES-192
35 aes256 function = 20 // AES-256
37 // K{I,L}MD function codes
38 sha1 function = 1 // SHA-1
39 sha256 function = 2 // SHA-256
40 sha512 function = 3 // SHA-512
41 sha3_224 function = 32 // SHA3-224
42 sha3_256 function = 33 // SHA3-256
43 sha3_384 function = 34 // SHA3-384
44 sha3_512 function = 35 // SHA3-512
45 shake128 function = 36 // SHAKE-128
46 shake256 function = 37 // SHAKE-256
48 // KLMD function codes
49 ghash function = 65 // GHASH
52 // queryResult contains the result of a Query function
53 // call. Bits are numbered in big endian order so the
54 // leftmost bit (the MSB) is at index 0.
55 type queryResult struct {
59 // Has reports whether the given functions are present.
60 func (q *queryResult) Has(fns ...function) bool {
62 panic("no function codes provided")
64 for _, f := range fns {
65 if !bitIsSet(q.bits[:], uint(f)) {
72 // facility is a bit index for the named facility.
76 // cryptography facilities
77 msa4 facility = 77 // message-security-assist extension 4
78 msa8 facility = 146 // message-security-assist extension 8
81 // facilityList contains the result of an STFLE call.
82 // Bits are numbered in big endian order so the
83 // leftmost bit (the MSB) is at index 0.
84 type facilityList struct {
88 // Has reports whether the given facilities are present.
89 func (s *facilityList) Has(fs ...facility) bool {
91 panic("no facility bits provided")
93 for _, f := range fs {
94 if !bitIsSet(s.bits[:], uint(f)) {
102 // test HWCAP bit vector
103 has := func(featureMask uint) bool {
104 return hwCap&featureMask == featureMask
108 S390X.HasZARCH = has(hwcap_ZARCH)
111 S390X.HasSTFLE = has(hwcap_STFLE)
112 S390X.HasLDISP = has(hwcap_LDISP)
113 S390X.HasEIMM = has(hwcap_EIMM)
114 S390X.HasETF3EH = has(hwcap_ETF3EH)
115 S390X.HasDFP = has(hwcap_DFP)
116 S390X.HasMSA = has(hwcap_MSA)
117 S390X.HasVX = has(hwcap_VX)
119 S390X.HasVXE = has(hwcap_VXE)
122 // We need implementations of stfle, km and so on
123 // to detect cryptographic features.
124 if !haveAsmFunctions() {
128 // optional cryptographic functions
130 aes := []function{aes128, aes192, aes256}
133 km, kmc := kmQuery(), kmcQuery()
134 S390X.HasAES = km.Has(aes...)
135 S390X.HasAESCBC = kmc.Has(aes...)
137 facilities := stfle()
138 if facilities.Has(msa4) {
139 kmctr := kmctrQuery()
140 S390X.HasAESCTR = kmctr.Has(aes...)
142 if facilities.Has(msa8) {
144 S390X.HasAESGCM = kma.Has(aes...)
148 // compute message digest
149 kimd := kimdQuery() // intermediate (no padding)
150 klmd := klmdQuery() // last (padding)
151 S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1)
152 S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256)
153 S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512)
154 S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist
156 sha3_224, sha3_256, sha3_384, sha3_512,
159 S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...)