1
2
3
4
5 package cpu
6
7 const CacheLinePadSize = 256
8
9 var HWCap uint
10
11
12
13 func bitIsSet(bits []uint64, index uint) bool {
14 return bits[index/64]&((1<<63)>>(index%64)) != 0
15 }
16
17
18 type function uint8
19
20 const (
21
22 aes128 function = 18
23 aes192 function = 19
24 aes256 function = 20
25
26
27 sha1 function = 1
28 sha256 function = 2
29 sha512 function = 3
30 sha3_224 function = 32
31 sha3_256 function = 33
32 sha3_384 function = 34
33 sha3_512 function = 35
34 shake128 function = 36
35 shake256 function = 37
36
37
38 ghash function = 65
39 )
40
41 const (
42
43 ecdsaVerifyP256 function = 1
44 ecdsaVerifyP384 function = 2
45 ecdsaVerifyP521 function = 3
46 ecdsaSignP256 function = 9
47 ecdsaSignP384 function = 10
48 ecdsaSignP521 function = 11
49 eddsaVerifyEd25519 function = 32
50 eddsaVerifyEd448 function = 36
51 eddsaSignEd25519 function = 40
52 eddsaSignEd448 function = 44
53 )
54
55
56
57
58 type queryResult struct {
59 bits [2]uint64
60 }
61
62
63 func (q *queryResult) Has(fns ...function) bool {
64 if len(fns) == 0 {
65 panic("no function codes provided")
66 }
67 for _, f := range fns {
68 if !bitIsSet(q.bits[:], uint(f)) {
69 return false
70 }
71 }
72 return true
73 }
74
75
76 type facility uint8
77
78 const (
79
80 zarch facility = 1
81 stflef facility = 7
82 ldisp facility = 18
83 eimm facility = 21
84
85
86 dfp facility = 42
87 etf3eh facility = 30
88
89
90 msa facility = 17
91 msa3 facility = 76
92 msa4 facility = 77
93 msa5 facility = 57
94 msa8 facility = 146
95 msa9 facility = 155
96
97
98 vxe facility = 135
99
100
101
102
103 hwcap_VX = 1 << 11
104 )
105
106
107
108
109 type facilityList struct {
110 bits [4]uint64
111 }
112
113
114 func (s *facilityList) Has(fs ...facility) bool {
115 if len(fs) == 0 {
116 panic("no facility bits provided")
117 }
118 for _, f := range fs {
119 if !bitIsSet(s.bits[:], uint(f)) {
120 return false
121 }
122 }
123 return true
124 }
125
126
127
128 func stfle() facilityList
129 func kmQuery() queryResult
130 func kmcQuery() queryResult
131 func kmctrQuery() queryResult
132 func kmaQuery() queryResult
133 func kimdQuery() queryResult
134 func klmdQuery() queryResult
135 func kdsaQuery() queryResult
136
137 func doinit() {
138 options = []option{
139 {Name: "zarch", Feature: &S390X.HasZARCH},
140 {Name: "stfle", Feature: &S390X.HasSTFLE},
141 {Name: "ldisp", Feature: &S390X.HasLDISP},
142 {Name: "msa", Feature: &S390X.HasMSA},
143 {Name: "eimm", Feature: &S390X.HasEIMM},
144 {Name: "dfp", Feature: &S390X.HasDFP},
145 {Name: "etf3eh", Feature: &S390X.HasETF3EH},
146 {Name: "vx", Feature: &S390X.HasVX},
147 {Name: "vxe", Feature: &S390X.HasVXE},
148 {Name: "kdsa", Feature: &S390X.HasKDSA},
149 }
150
151 aes := []function{aes128, aes192, aes256}
152 facilities := stfle()
153
154 S390X.HasZARCH = facilities.Has(zarch)
155 S390X.HasSTFLE = facilities.Has(stflef)
156 S390X.HasLDISP = facilities.Has(ldisp)
157 S390X.HasEIMM = facilities.Has(eimm)
158 S390X.HasDFP = facilities.Has(dfp)
159 S390X.HasETF3EH = facilities.Has(etf3eh)
160 S390X.HasMSA = facilities.Has(msa)
161
162 if S390X.HasMSA {
163
164 km, kmc := kmQuery(), kmcQuery()
165 S390X.HasAES = km.Has(aes...)
166 S390X.HasAESCBC = kmc.Has(aes...)
167 if facilities.Has(msa4) {
168 kmctr := kmctrQuery()
169 S390X.HasAESCTR = kmctr.Has(aes...)
170 }
171 if facilities.Has(msa8) {
172 kma := kmaQuery()
173 S390X.HasAESGCM = kma.Has(aes...)
174 }
175
176
177 kimd := kimdQuery()
178 klmd := klmdQuery()
179 S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1)
180 S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256)
181 S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512)
182 S390X.HasGHASH = kimd.Has(ghash)
183 sha3 := []function{
184 sha3_224, sha3_256, sha3_384, sha3_512,
185 shake128, shake256,
186 }
187 S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...)
188 S390X.HasKDSA = facilities.Has(msa9)
189 if S390X.HasKDSA {
190 kdsa := kdsaQuery()
191 S390X.HasECDSA = kdsa.Has(ecdsaVerifyP256, ecdsaSignP256, ecdsaVerifyP384, ecdsaSignP384, ecdsaVerifyP521, ecdsaSignP521)
192 S390X.HasEDDSA = kdsa.Has(eddsaVerifyEd25519, eddsaSignEd25519, eddsaVerifyEd448, eddsaSignEd448)
193 }
194 }
195
196 S390X.HasVX = isSet(HWCap, hwcap_VX)
197
198 if S390X.HasVX {
199 S390X.HasVXE = facilities.Has(vxe)
200 }
201 }
202
203 func isSet(hwc uint, value uint) bool {
204 return hwc&value != 0
205 }
206
View as plain text