2 * Copyright 2010-2017 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
15 #include "internal/cryptlib.h"
16 #include "internal/ctype.h"
17 #include "s390x_arch.h"
21 #define STR(S) STR_(S)
23 #define TOK_FUNC(NAME) \
25 " " STR(NAME) " : %" STR(LEN) "[^:] : " \
26 "%" STR(LEN) "s %" STR(LEN) "s ", \
27 tok[0], tok[1], tok[2]) == 2) { \
29 off = (tok[0][0] == '~') ? 1 : 0; \
30 if (sscanf(tok[0] + off, "%llx", &cap->NAME[0]) != 1) \
33 cap->NAME[0] = ~cap->NAME[0]; \
35 off = (tok[1][0] == '~') ? 1 : 0; \
36 if (sscanf(tok[1] + off, "%llx", &cap->NAME[1]) != 1) \
39 cap->NAME[1] = ~cap->NAME[1]; \
42 #define TOK_CPU(NAME) \
44 " %" STR(LEN) "s %" STR(LEN) "s ", \
45 tok[0], tok[1]) == 1 \
46 && !strcmp(tok[0], #NAME)) { \
47 memcpy(cap, &NAME, sizeof(*cap)); \
50 static sigjmp_buf ill_jmp
;
51 static void ill_handler(int sig
)
53 siglongjmp(ill_jmp
, sig
);
56 static const char *env
;
57 static int parse_env(struct OPENSSL_s390xcap_st
*cap
);
59 void OPENSSL_s390x_facilities(void);
60 void OPENSSL_s390x_functions(void);
61 void OPENSSL_vx_probe(void);
63 struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P
;
65 void OPENSSL_cpuid_setup(void)
68 struct sigaction ill_act
, oact
;
69 struct OPENSSL_s390xcap_st cap
;
71 if (OPENSSL_s390xcap_P
.stfle
[0])
74 /* set a bit that will not be tested later */
75 OPENSSL_s390xcap_P
.stfle
[0] |= S390X_CAPBIT(0);
77 env
= getenv("OPENSSL_s390xcap");
83 memset(&ill_act
, 0, sizeof(ill_act
));
84 ill_act
.sa_handler
= ill_handler
;
85 sigfillset(&ill_act
.sa_mask
);
86 sigdelset(&ill_act
.sa_mask
, SIGILL
);
87 sigdelset(&ill_act
.sa_mask
, SIGFPE
);
88 sigdelset(&ill_act
.sa_mask
, SIGTRAP
);
89 sigprocmask(SIG_SETMASK
, &ill_act
.sa_mask
, &oset
);
90 sigaction(SIGILL
, &ill_act
, &oact
);
91 sigaction(SIGFPE
, &ill_act
, &oact
);
93 /* protection against missing store-facility-list-extended */
94 if (sigsetjmp(ill_jmp
, 1) == 0)
95 OPENSSL_s390x_facilities();
98 OPENSSL_s390xcap_P
.stfle
[0] &= cap
.stfle
[0];
99 OPENSSL_s390xcap_P
.stfle
[1] &= cap
.stfle
[1];
100 OPENSSL_s390xcap_P
.stfle
[2] &= cap
.stfle
[2];
103 /* protection against disabled vector facility */
104 if ((OPENSSL_s390xcap_P
.stfle
[2] & S390X_CAPBIT(S390X_VX
))
105 && (sigsetjmp(ill_jmp
, 1) == 0)) {
108 OPENSSL_s390xcap_P
.stfle
[2] &= ~(S390X_CAPBIT(S390X_VX
)
109 | S390X_CAPBIT(S390X_VXD
)
110 | S390X_CAPBIT(S390X_VXE
));
113 sigaction(SIGFPE
, &oact
, NULL
);
114 sigaction(SIGILL
, &oact
, NULL
);
115 sigprocmask(SIG_SETMASK
, &oset
, NULL
);
117 OPENSSL_s390x_functions();
120 OPENSSL_s390xcap_P
.kimd
[0] &= cap
.kimd
[0];
121 OPENSSL_s390xcap_P
.kimd
[1] &= cap
.kimd
[1];
122 OPENSSL_s390xcap_P
.klmd
[0] &= cap
.klmd
[0];
123 OPENSSL_s390xcap_P
.klmd
[1] &= cap
.klmd
[1];
124 OPENSSL_s390xcap_P
.km
[0] &= cap
.km
[0];
125 OPENSSL_s390xcap_P
.km
[1] &= cap
.km
[1];
126 OPENSSL_s390xcap_P
.kmc
[0] &= cap
.kmc
[0];
127 OPENSSL_s390xcap_P
.kmc
[1] &= cap
.kmc
[1];
128 OPENSSL_s390xcap_P
.kmac
[0] &= cap
.kmac
[0];
129 OPENSSL_s390xcap_P
.kmac
[1] &= cap
.kmac
[1];
130 OPENSSL_s390xcap_P
.kmctr
[0] &= cap
.kmctr
[0];
131 OPENSSL_s390xcap_P
.kmctr
[1] &= cap
.kmctr
[1];
132 OPENSSL_s390xcap_P
.kmo
[0] &= cap
.kmo
[0];
133 OPENSSL_s390xcap_P
.kmo
[1] &= cap
.kmo
[1];
134 OPENSSL_s390xcap_P
.kmf
[0] &= cap
.kmf
[0];
135 OPENSSL_s390xcap_P
.kmf
[1] &= cap
.kmf
[1];
136 OPENSSL_s390xcap_P
.prno
[0] &= cap
.prno
[0];
137 OPENSSL_s390xcap_P
.prno
[1] &= cap
.prno
[1];
138 OPENSSL_s390xcap_P
.kma
[0] &= cap
.kma
[0];
139 OPENSSL_s390xcap_P
.kma
[1] &= cap
.kma
[1];
143 static int parse_env(struct OPENSSL_s390xcap_st
*cap
)
147 * (only the STFLE- and QUERY-bits relevant to libcrypto are set)
151 * z900 (2000) - z/Architecture POP SA22-7832-00
152 * Facility detection would fail on real hw (no STFLE).
154 static const struct OPENSSL_s390xcap_st z900
= {
155 .stfle
= {0ULL, 0ULL, 0ULL, 0ULL},
156 .kimd
= {0ULL, 0ULL},
157 .klmd
= {0ULL, 0ULL},
160 .kmac
= {0ULL, 0ULL},
161 .kmctr
= {0ULL, 0ULL},
164 .prno
= {0ULL, 0ULL},
169 * z990 (2003) - z/Architecture POP SA22-7832-02
170 * Implements MSA. Facility detection would fail on real hw (no STFLE).
172 static const struct OPENSSL_s390xcap_st z990
= {
173 .stfle
= {S390X_CAPBIT(S390X_MSA
),
175 .kimd
= {S390X_CAPBIT(S390X_QUERY
)
176 | S390X_CAPBIT(S390X_SHA_1
),
178 .klmd
= {S390X_CAPBIT(S390X_QUERY
)
179 | S390X_CAPBIT(S390X_SHA_1
),
181 .km
= {S390X_CAPBIT(S390X_QUERY
),
183 .kmc
= {S390X_CAPBIT(S390X_QUERY
),
185 .kmac
= {S390X_CAPBIT(S390X_QUERY
),
187 .kmctr
= {0ULL, 0ULL},
190 .prno
= {0ULL, 0ULL},
195 * z9 (2005) - z/Architecture POP SA22-7832-04
196 * Implements MSA and MSA1.
198 static const struct OPENSSL_s390xcap_st z9
= {
199 .stfle
= {S390X_CAPBIT(S390X_MSA
)
200 | S390X_CAPBIT(S390X_STCKF
),
202 .kimd
= {S390X_CAPBIT(S390X_QUERY
)
203 | S390X_CAPBIT(S390X_SHA_1
)
204 | S390X_CAPBIT(S390X_SHA_256
),
206 .klmd
= {S390X_CAPBIT(S390X_QUERY
)
207 | S390X_CAPBIT(S390X_SHA_1
)
208 | S390X_CAPBIT(S390X_SHA_256
),
210 .km
= {S390X_CAPBIT(S390X_QUERY
)
211 | S390X_CAPBIT(S390X_AES_128
),
213 .kmc
= {S390X_CAPBIT(S390X_QUERY
)
214 | S390X_CAPBIT(S390X_AES_128
),
216 .kmac
= {S390X_CAPBIT(S390X_QUERY
),
218 .kmctr
= {0ULL, 0ULL},
221 .prno
= {0ULL, 0ULL},
226 * z10 (2008) - z/Architecture POP SA22-7832-06
227 * Implements MSA and MSA1-2.
229 static const struct OPENSSL_s390xcap_st z10
= {
230 .stfle
= {S390X_CAPBIT(S390X_MSA
)
231 | S390X_CAPBIT(S390X_STCKF
),
233 .kimd
= {S390X_CAPBIT(S390X_QUERY
)
234 | S390X_CAPBIT(S390X_SHA_1
)
235 | S390X_CAPBIT(S390X_SHA_256
)
236 | S390X_CAPBIT(S390X_SHA_512
),
238 .klmd
= {S390X_CAPBIT(S390X_QUERY
)
239 | S390X_CAPBIT(S390X_SHA_1
)
240 | S390X_CAPBIT(S390X_SHA_256
)
241 | S390X_CAPBIT(S390X_SHA_512
),
243 .km
= {S390X_CAPBIT(S390X_QUERY
)
244 | S390X_CAPBIT(S390X_AES_128
)
245 | S390X_CAPBIT(S390X_AES_192
)
246 | S390X_CAPBIT(S390X_AES_256
),
248 .kmc
= {S390X_CAPBIT(S390X_QUERY
)
249 | S390X_CAPBIT(S390X_AES_128
)
250 | S390X_CAPBIT(S390X_AES_192
)
251 | S390X_CAPBIT(S390X_AES_256
),
253 .kmac
= {S390X_CAPBIT(S390X_QUERY
),
255 .kmctr
= {0ULL, 0ULL},
258 .prno
= {0ULL, 0ULL},
263 * z196 (2010) - z/Architecture POP SA22-7832-08
264 * Implements MSA and MSA1-4.
266 static const struct OPENSSL_s390xcap_st z196
= {
267 .stfle
= {S390X_CAPBIT(S390X_MSA
)
268 | S390X_CAPBIT(S390X_STCKF
),
269 S390X_CAPBIT(S390X_MSA3
)
270 | S390X_CAPBIT(S390X_MSA4
),
272 .kimd
= {S390X_CAPBIT(S390X_QUERY
)
273 | S390X_CAPBIT(S390X_SHA_1
)
274 | S390X_CAPBIT(S390X_SHA_256
)
275 | S390X_CAPBIT(S390X_SHA_512
),
276 S390X_CAPBIT(S390X_GHASH
)},
277 .klmd
= {S390X_CAPBIT(S390X_QUERY
)
278 | S390X_CAPBIT(S390X_SHA_1
)
279 | S390X_CAPBIT(S390X_SHA_256
)
280 | S390X_CAPBIT(S390X_SHA_512
),
282 .km
= {S390X_CAPBIT(S390X_QUERY
)
283 | S390X_CAPBIT(S390X_AES_128
)
284 | S390X_CAPBIT(S390X_AES_192
)
285 | S390X_CAPBIT(S390X_AES_256
)
286 | S390X_CAPBIT(S390X_XTS_AES_128
)
287 | S390X_CAPBIT(S390X_XTS_AES_256
),
289 .kmc
= {S390X_CAPBIT(S390X_QUERY
)
290 | S390X_CAPBIT(S390X_AES_128
)
291 | S390X_CAPBIT(S390X_AES_192
)
292 | S390X_CAPBIT(S390X_AES_256
),
294 .kmac
= {S390X_CAPBIT(S390X_QUERY
)
295 | S390X_CAPBIT(S390X_AES_128
)
296 | S390X_CAPBIT(S390X_AES_192
)
297 | S390X_CAPBIT(S390X_AES_256
),
299 .kmctr
= {S390X_CAPBIT(S390X_QUERY
)
300 | S390X_CAPBIT(S390X_AES_128
)
301 | S390X_CAPBIT(S390X_AES_192
)
302 | S390X_CAPBIT(S390X_AES_256
),
304 .kmo
= {S390X_CAPBIT(S390X_QUERY
)
305 | S390X_CAPBIT(S390X_AES_128
)
306 | S390X_CAPBIT(S390X_AES_192
)
307 | S390X_CAPBIT(S390X_AES_256
),
309 .kmf
= {S390X_CAPBIT(S390X_QUERY
)
310 | S390X_CAPBIT(S390X_AES_128
)
311 | S390X_CAPBIT(S390X_AES_192
)
312 | S390X_CAPBIT(S390X_AES_256
),
314 .prno
= {0ULL, 0ULL},
319 * zEC12 (2012) - z/Architecture POP SA22-7832-09
320 * Implements MSA and MSA1-4.
322 static const struct OPENSSL_s390xcap_st zEC12
= {
323 .stfle
= {S390X_CAPBIT(S390X_MSA
)
324 | S390X_CAPBIT(S390X_STCKF
),
325 S390X_CAPBIT(S390X_MSA3
)
326 | S390X_CAPBIT(S390X_MSA4
),
328 .kimd
= {S390X_CAPBIT(S390X_QUERY
)
329 | S390X_CAPBIT(S390X_SHA_1
)
330 | S390X_CAPBIT(S390X_SHA_256
)
331 | S390X_CAPBIT(S390X_SHA_512
),
332 S390X_CAPBIT(S390X_GHASH
)},
333 .klmd
= {S390X_CAPBIT(S390X_QUERY
)
334 | S390X_CAPBIT(S390X_SHA_1
)
335 | S390X_CAPBIT(S390X_SHA_256
)
336 | S390X_CAPBIT(S390X_SHA_512
),
338 .km
= {S390X_CAPBIT(S390X_QUERY
)
339 | S390X_CAPBIT(S390X_AES_128
)
340 | S390X_CAPBIT(S390X_AES_192
)
341 | S390X_CAPBIT(S390X_AES_256
)
342 | S390X_CAPBIT(S390X_XTS_AES_128
)
343 | S390X_CAPBIT(S390X_XTS_AES_256
),
345 .kmc
= {S390X_CAPBIT(S390X_QUERY
)
346 | S390X_CAPBIT(S390X_AES_128
)
347 | S390X_CAPBIT(S390X_AES_192
)
348 | S390X_CAPBIT(S390X_AES_256
),
350 .kmac
= {S390X_CAPBIT(S390X_QUERY
)
351 | S390X_CAPBIT(S390X_AES_128
)
352 | S390X_CAPBIT(S390X_AES_192
)
353 | S390X_CAPBIT(S390X_AES_256
),
355 .kmctr
= {S390X_CAPBIT(S390X_QUERY
)
356 | S390X_CAPBIT(S390X_AES_128
)
357 | S390X_CAPBIT(S390X_AES_192
)
358 | S390X_CAPBIT(S390X_AES_256
),
360 .kmo
= {S390X_CAPBIT(S390X_QUERY
)
361 | S390X_CAPBIT(S390X_AES_128
)
362 | S390X_CAPBIT(S390X_AES_192
)
363 | S390X_CAPBIT(S390X_AES_256
),
365 .kmf
= {S390X_CAPBIT(S390X_QUERY
)
366 | S390X_CAPBIT(S390X_AES_128
)
367 | S390X_CAPBIT(S390X_AES_192
)
368 | S390X_CAPBIT(S390X_AES_256
),
370 .prno
= {0ULL, 0ULL},
375 * z13 (2015) - z/Architecture POP SA22-7832-10
376 * Implements MSA and MSA1-5.
378 static const struct OPENSSL_s390xcap_st z13
= {
379 .stfle
= {S390X_CAPBIT(S390X_MSA
)
380 | S390X_CAPBIT(S390X_STCKF
)
381 | S390X_CAPBIT(S390X_MSA5
),
382 S390X_CAPBIT(S390X_MSA3
)
383 | S390X_CAPBIT(S390X_MSA4
),
384 S390X_CAPBIT(S390X_VX
),
386 .kimd
= {S390X_CAPBIT(S390X_QUERY
)
387 | S390X_CAPBIT(S390X_SHA_1
)
388 | S390X_CAPBIT(S390X_SHA_256
)
389 | S390X_CAPBIT(S390X_SHA_512
),
390 S390X_CAPBIT(S390X_GHASH
)},
391 .klmd
= {S390X_CAPBIT(S390X_QUERY
)
392 | S390X_CAPBIT(S390X_SHA_1
)
393 | S390X_CAPBIT(S390X_SHA_256
)
394 | S390X_CAPBIT(S390X_SHA_512
),
396 .km
= {S390X_CAPBIT(S390X_QUERY
)
397 | S390X_CAPBIT(S390X_AES_128
)
398 | S390X_CAPBIT(S390X_AES_192
)
399 | S390X_CAPBIT(S390X_AES_256
)
400 | S390X_CAPBIT(S390X_XTS_AES_128
)
401 | S390X_CAPBIT(S390X_XTS_AES_256
),
403 .kmc
= {S390X_CAPBIT(S390X_QUERY
)
404 | S390X_CAPBIT(S390X_AES_128
)
405 | S390X_CAPBIT(S390X_AES_192
)
406 | S390X_CAPBIT(S390X_AES_256
),
408 .kmac
= {S390X_CAPBIT(S390X_QUERY
)
409 | S390X_CAPBIT(S390X_AES_128
)
410 | S390X_CAPBIT(S390X_AES_192
)
411 | S390X_CAPBIT(S390X_AES_256
),
413 .kmctr
= {S390X_CAPBIT(S390X_QUERY
)
414 | S390X_CAPBIT(S390X_AES_128
)
415 | S390X_CAPBIT(S390X_AES_192
)
416 | S390X_CAPBIT(S390X_AES_256
),
418 .kmo
= {S390X_CAPBIT(S390X_QUERY
)
419 | S390X_CAPBIT(S390X_AES_128
)
420 | S390X_CAPBIT(S390X_AES_192
)
421 | S390X_CAPBIT(S390X_AES_256
),
423 .kmf
= {S390X_CAPBIT(S390X_QUERY
)
424 | S390X_CAPBIT(S390X_AES_128
)
425 | S390X_CAPBIT(S390X_AES_192
)
426 | S390X_CAPBIT(S390X_AES_256
),
428 .prno
= {S390X_CAPBIT(S390X_QUERY
)
429 | S390X_CAPBIT(S390X_SHA_512_DRNG
),
435 * z14 (2017) - z/Architecture POP SA22-7832-11
436 * Implements MSA and MSA1-8.
438 static const struct OPENSSL_s390xcap_st z14
= {
439 .stfle
= {S390X_CAPBIT(S390X_MSA
)
440 | S390X_CAPBIT(S390X_STCKF
)
441 | S390X_CAPBIT(S390X_MSA5
),
442 S390X_CAPBIT(S390X_MSA3
)
443 | S390X_CAPBIT(S390X_MSA4
),
444 S390X_CAPBIT(S390X_VX
)
445 | S390X_CAPBIT(S390X_VXD
)
446 | S390X_CAPBIT(S390X_VXE
)
447 | S390X_CAPBIT(S390X_MSA8
),
449 .kimd
= {S390X_CAPBIT(S390X_QUERY
)
450 | S390X_CAPBIT(S390X_SHA_1
)
451 | S390X_CAPBIT(S390X_SHA_256
)
452 | S390X_CAPBIT(S390X_SHA_512
)
453 | S390X_CAPBIT(S390X_SHA3_224
)
454 | S390X_CAPBIT(S390X_SHA3_256
)
455 | S390X_CAPBIT(S390X_SHA3_384
)
456 | S390X_CAPBIT(S390X_SHA3_512
)
457 | S390X_CAPBIT(S390X_SHAKE_128
)
458 | S390X_CAPBIT(S390X_SHAKE_256
),
459 S390X_CAPBIT(S390X_GHASH
)},
460 .klmd
= {S390X_CAPBIT(S390X_QUERY
)
461 | S390X_CAPBIT(S390X_SHA_1
)
462 | S390X_CAPBIT(S390X_SHA_256
)
463 | S390X_CAPBIT(S390X_SHA_512
)
464 | S390X_CAPBIT(S390X_SHA3_224
)
465 | S390X_CAPBIT(S390X_SHA3_256
)
466 | S390X_CAPBIT(S390X_SHA3_384
)
467 | S390X_CAPBIT(S390X_SHA3_512
)
468 | S390X_CAPBIT(S390X_SHAKE_128
)
469 | S390X_CAPBIT(S390X_SHAKE_256
),
471 .km
= {S390X_CAPBIT(S390X_QUERY
)
472 | S390X_CAPBIT(S390X_AES_128
)
473 | S390X_CAPBIT(S390X_AES_192
)
474 | S390X_CAPBIT(S390X_AES_256
)
475 | S390X_CAPBIT(S390X_XTS_AES_128
)
476 | S390X_CAPBIT(S390X_XTS_AES_256
),
478 .kmc
= {S390X_CAPBIT(S390X_QUERY
)
479 | S390X_CAPBIT(S390X_AES_128
)
480 | S390X_CAPBIT(S390X_AES_192
)
481 | S390X_CAPBIT(S390X_AES_256
),
483 .kmac
= {S390X_CAPBIT(S390X_QUERY
)
484 | S390X_CAPBIT(S390X_AES_128
)
485 | S390X_CAPBIT(S390X_AES_192
)
486 | S390X_CAPBIT(S390X_AES_256
),
488 .kmctr
= {S390X_CAPBIT(S390X_QUERY
)
489 | S390X_CAPBIT(S390X_AES_128
)
490 | S390X_CAPBIT(S390X_AES_192
)
491 | S390X_CAPBIT(S390X_AES_256
),
493 .kmo
= {S390X_CAPBIT(S390X_QUERY
)
494 | S390X_CAPBIT(S390X_AES_128
)
495 | S390X_CAPBIT(S390X_AES_192
)
496 | S390X_CAPBIT(S390X_AES_256
),
498 .kmf
= {S390X_CAPBIT(S390X_QUERY
)
499 | S390X_CAPBIT(S390X_AES_128
)
500 | S390X_CAPBIT(S390X_AES_192
)
501 | S390X_CAPBIT(S390X_AES_256
),
503 .prno
= {S390X_CAPBIT(S390X_QUERY
)
504 | S390X_CAPBIT(S390X_SHA_512_DRNG
),
505 S390X_CAPBIT(S390X_TRNG
)},
506 .kma
= {S390X_CAPBIT(S390X_QUERY
)
507 | S390X_CAPBIT(S390X_AES_128
)
508 | S390X_CAPBIT(S390X_AES_192
)
509 | S390X_CAPBIT(S390X_AES_256
),
513 char *tok_begin
, *tok_end
, *buff
, tok
[S390X_STFLE_MAX
][LEN
+ 1];
516 buff
= malloc(strlen(env
) + 1);
521 memset(cap
, ~0, sizeof(*cap
));
524 tok_begin
= buff
+ strspn(buff
, ";");
525 strtok(tok_begin
, ";");
526 tok_end
= strtok(NULL
, ";");
528 while (tok_begin
!= NULL
) {
530 if ((n
= sscanf(tok_begin
,
531 " stfle : %" STR(LEN
) "[^:] : "
532 "%" STR(LEN
) "[^:] : %" STR(LEN
) "s ",
533 tok
[0], tok
[1], tok
[2]))) {
534 for (i
= 0; i
< n
; i
++) {
535 off
= (tok
[i
][0] == '~') ? 1 : 0;
536 if (sscanf(tok
[i
] + off
, "%llx", &cap
->stfle
[i
]) != 1)
539 cap
->stfle
[i
] = ~cap
->stfle
[i
];
543 /* query function tokens */
544 else if TOK_FUNC(kimd
)
545 else if TOK_FUNC(klmd
)
547 else if TOK_FUNC(kmc
)
548 else if TOK_FUNC(kmac
)
549 else if TOK_FUNC(kmctr
)
550 else if TOK_FUNC(kmo
)
551 else if TOK_FUNC(kmf
)
552 else if TOK_FUNC(prno
)
553 else if TOK_FUNC(kma
)
555 /* CPU model tokens */
556 else if TOK_CPU(z900
)
557 else if TOK_CPU(z990
)
560 else if TOK_CPU(z196
)
561 else if TOK_CPU(zEC12
)
565 /* whitespace(ignored) or invalid tokens */
567 while (*tok_begin
!= '\0') {
568 if (!ossl_isspace(*tok_begin
))
575 tok_end
= strtok(NULL
, ";");