1 /*
2 * Copyright 2010-2023 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (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
8 */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <setjmp.h>
14 #include <signal.h>
15 #include "internal/cryptlib.h"
16 #include "crypto/ctype.h"
17 #include "s390x_arch.h"
18
19 #if defined(OPENSSL_SYS_LINUX) && !defined(FIPS_MODULE)
20 # include <sys/types.h>
21 # include <sys/stat.h>
22 # include <fcntl.h>
23 # include <asm/zcrypt.h>
24 # include <sys/ioctl.h>
25 # include <unistd.h>
26 #endif
27
28 #if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
29 # if __GLIBC_PREREQ(2, 16)
30 # include <sys/auxv.h>
31 # if defined(HWCAP_S390_STFLE) && defined(HWCAP_S390_VX)
32 # define OSSL_IMPLEMENT_GETAUXVAL
33 # endif
34 # endif
35 #endif
36
37 #define LEN 128
38 #define STR_(S) #S
39 #define STR(S) STR_(S)
40
41 #define TOK_FUNC(NAME) \
42 (sscanf(tok_begin, \
43 " " STR(NAME) " : %" STR(LEN) "[^:] : " \
44 "%" STR(LEN) "s %" STR(LEN) "s ", \
45 tok[0], tok[1], tok[2]) == 2) { \
46 \
47 off = (tok[0][0] == '~') ? 1 : 0; \
48 if (sscanf(tok[0] + off, "%llx", &cap->NAME[0]) != 1) \
49 goto ret; \
50 if (off) \
51 cap->NAME[0] = ~cap->NAME[0]; \
52 \
53 off = (tok[1][0] == '~') ? 1 : 0; \
54 if (sscanf(tok[1] + off, "%llx", &cap->NAME[1]) != 1) \
55 goto ret; \
56 if (off) \
57 cap->NAME[1] = ~cap->NAME[1]; \
58 }
59
60 #define TOK_CPU_ALIAS(NAME, STRUCT_NAME) \
61 (sscanf(tok_begin, \
62 " %" STR(LEN) "s %" STR(LEN) "s ", \
63 tok[0], tok[1]) == 1 \
64 && !strcmp(tok[0], #NAME)) { \
65 memcpy(cap, &STRUCT_NAME, sizeof(*cap)); \
66 }
67
68 #define TOK_CPU(NAME) TOK_CPU_ALIAS(NAME, NAME)
69
70 #ifndef OSSL_IMPLEMENT_GETAUXVAL
71 static sigjmp_buf ill_jmp;
ill_handler(int sig)72 static void ill_handler(int sig)
73 {
74 siglongjmp(ill_jmp, sig);
75 }
76
77 void OPENSSL_vx_probe(void);
78 #endif
79
80 static const char *env;
81 static int parse_env(struct OPENSSL_s390xcap_st *cap, int *cex);
82
83 void OPENSSL_s390x_facilities(void);
84 void OPENSSL_s390x_functions(void);
85
86 struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P;
87
88 #ifdef S390X_MOD_EXP
89 int OPENSSL_s390xcex;
90 int OPENSSL_s390xcex_nodev;
91
92 #if defined(__GNUC__)
93 __attribute__ ((visibility("hidden")))
94 #endif
95 void OPENSSL_s390x_cleanup(void);
96
97 #if defined(__GNUC__)
98 __attribute__ ((visibility("hidden")))
99 #endif
OPENSSL_s390x_cleanup(void)100 void OPENSSL_s390x_cleanup(void)
101 {
102 if (OPENSSL_s390xcex != -1) {
103 (void)close(OPENSSL_s390xcex);
104 OPENSSL_s390xcex = -1;
105 }
106 }
107 #endif
108
109 #if defined(__GNUC__) && defined(__linux)
110 __attribute__ ((visibility("hidden")))
111 #endif
OPENSSL_cpuid_setup(void)112 void OPENSSL_cpuid_setup(void)
113 {
114 struct OPENSSL_s390xcap_st cap;
115 int cex = 1;
116
117 if (OPENSSL_s390xcap_P.stfle[0])
118 return;
119
120 /* set a bit that will not be tested later */
121 OPENSSL_s390xcap_P.stfle[0] |= S390X_CAPBIT(0);
122
123 #if defined(OSSL_IMPLEMENT_GETAUXVAL)
124 {
125 const unsigned long hwcap = getauxval(AT_HWCAP);
126
127 /* protection against missing store-facility-list-extended */
128 if (hwcap & HWCAP_S390_STFLE)
129 OPENSSL_s390x_facilities();
130
131 /* protection against disabled vector facility */
132 if (!(hwcap & HWCAP_S390_VX)) {
133 OPENSSL_s390xcap_P.stfle[2] &= ~(S390X_CAPBIT(S390X_VX)
134 | S390X_CAPBIT(S390X_VXD)
135 | S390X_CAPBIT(S390X_VXE));
136 }
137 }
138 #else
139 {
140 sigset_t oset;
141 struct sigaction ill_act, oact_ill, oact_fpe;
142
143 memset(&ill_act, 0, sizeof(ill_act));
144 ill_act.sa_handler = ill_handler;
145 sigfillset(&ill_act.sa_mask);
146 sigdelset(&ill_act.sa_mask, SIGILL);
147 sigdelset(&ill_act.sa_mask, SIGFPE);
148 sigdelset(&ill_act.sa_mask, SIGTRAP);
149
150 sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
151 sigaction(SIGILL, &ill_act, &oact_ill);
152 sigaction(SIGFPE, &ill_act, &oact_fpe);
153
154 /* protection against missing store-facility-list-extended */
155 if (sigsetjmp(ill_jmp, 1) == 0)
156 OPENSSL_s390x_facilities();
157
158 /* protection against disabled vector facility */
159 if ((OPENSSL_s390xcap_P.stfle[2] & S390X_CAPBIT(S390X_VX))
160 && (sigsetjmp(ill_jmp, 1) == 0)) {
161 OPENSSL_vx_probe();
162 } else {
163 OPENSSL_s390xcap_P.stfle[2] &= ~(S390X_CAPBIT(S390X_VX)
164 | S390X_CAPBIT(S390X_VXD)
165 | S390X_CAPBIT(S390X_VXE));
166 }
167
168 sigaction(SIGFPE, &oact_fpe, NULL);
169 sigaction(SIGILL, &oact_ill, NULL);
170 sigprocmask(SIG_SETMASK, &oset, NULL);
171 }
172 #endif
173
174 env = getenv("OPENSSL_s390xcap");
175 if (env != NULL) {
176 if (!parse_env(&cap, &cex))
177 env = NULL;
178 }
179
180 if (env != NULL) {
181 OPENSSL_s390xcap_P.stfle[0] &= cap.stfle[0];
182 OPENSSL_s390xcap_P.stfle[1] &= cap.stfle[1];
183 OPENSSL_s390xcap_P.stfle[2] &= cap.stfle[2];
184 }
185
186 OPENSSL_s390x_functions(); /* check OPENSSL_s390xcap_P.stfle */
187
188 if (env != NULL) {
189 OPENSSL_s390xcap_P.kimd[0] &= cap.kimd[0];
190 OPENSSL_s390xcap_P.kimd[1] &= cap.kimd[1];
191 OPENSSL_s390xcap_P.klmd[0] &= cap.klmd[0];
192 OPENSSL_s390xcap_P.klmd[1] &= cap.klmd[1];
193 OPENSSL_s390xcap_P.km[0] &= cap.km[0];
194 OPENSSL_s390xcap_P.km[1] &= cap.km[1];
195 OPENSSL_s390xcap_P.kmc[0] &= cap.kmc[0];
196 OPENSSL_s390xcap_P.kmc[1] &= cap.kmc[1];
197 OPENSSL_s390xcap_P.kmac[0] &= cap.kmac[0];
198 OPENSSL_s390xcap_P.kmac[1] &= cap.kmac[1];
199 OPENSSL_s390xcap_P.kmctr[0] &= cap.kmctr[0];
200 OPENSSL_s390xcap_P.kmctr[1] &= cap.kmctr[1];
201 OPENSSL_s390xcap_P.kmo[0] &= cap.kmo[0];
202 OPENSSL_s390xcap_P.kmo[1] &= cap.kmo[1];
203 OPENSSL_s390xcap_P.kmf[0] &= cap.kmf[0];
204 OPENSSL_s390xcap_P.kmf[1] &= cap.kmf[1];
205 OPENSSL_s390xcap_P.prno[0] &= cap.prno[0];
206 OPENSSL_s390xcap_P.prno[1] &= cap.prno[1];
207 OPENSSL_s390xcap_P.kma[0] &= cap.kma[0];
208 OPENSSL_s390xcap_P.kma[1] &= cap.kma[1];
209 OPENSSL_s390xcap_P.pcc[0] &= cap.pcc[0];
210 OPENSSL_s390xcap_P.pcc[1] &= cap.pcc[1];
211 OPENSSL_s390xcap_P.kdsa[0] &= cap.kdsa[0];
212 OPENSSL_s390xcap_P.kdsa[1] &= cap.kdsa[1];
213 }
214
215 #ifdef S390X_MOD_EXP
216 if (cex == 0) {
217 OPENSSL_s390xcex = -1;
218 } else {
219 OPENSSL_s390xcex = open("/dev/z90crypt", O_RDWR | O_CLOEXEC);
220 OPENSSL_atexit(OPENSSL_s390x_cleanup);
221 }
222 OPENSSL_s390xcex_nodev = 0;
223 #endif
224 }
225
parse_env(struct OPENSSL_s390xcap_st * cap,int * cex)226 static int parse_env(struct OPENSSL_s390xcap_st *cap, int *cex)
227 {
228 /*-
229 * CPU model data
230 * (only the STFLE- and QUERY-bits relevant to libcrypto are set)
231 */
232
233 /*-
234 * z900 (2000) - z/Architecture POP SA22-7832-00
235 * Facility detection would fail on real hw (no STFLE).
236 */
237 static const struct OPENSSL_s390xcap_st z900 = {
238 /*.stfle = */{0ULL, 0ULL, 0ULL, 0ULL},
239 /*.kimd = */{0ULL, 0ULL},
240 /*.klmd = */{0ULL, 0ULL},
241 /*.km = */{0ULL, 0ULL},
242 /*.kmc = */{0ULL, 0ULL},
243 /*.kmac = */{0ULL, 0ULL},
244 /*.kmctr = */{0ULL, 0ULL},
245 /*.kmo = */{0ULL, 0ULL},
246 /*.kmf = */{0ULL, 0ULL},
247 /*.prno = */{0ULL, 0ULL},
248 /*.kma = */{0ULL, 0ULL},
249 /*.pcc = */{0ULL, 0ULL},
250 /*.kdsa = */{0ULL, 0ULL},
251 };
252
253 /*-
254 * z990 (2003) - z/Architecture POP SA22-7832-02
255 * Implements MSA. Facility detection would fail on real hw (no STFLE).
256 */
257 static const struct OPENSSL_s390xcap_st z990 = {
258 /*.stfle = */{S390X_CAPBIT(S390X_MSA),
259 0ULL, 0ULL, 0ULL},
260 /*.kimd = */{S390X_CAPBIT(S390X_QUERY)
261 | S390X_CAPBIT(S390X_SHA_1),
262 0ULL},
263 /*.klmd = */{S390X_CAPBIT(S390X_QUERY)
264 | S390X_CAPBIT(S390X_SHA_1),
265 0ULL},
266 /*.km = */{S390X_CAPBIT(S390X_QUERY),
267 0ULL},
268 /*.kmc = */{S390X_CAPBIT(S390X_QUERY),
269 0ULL},
270 /*.kmac = */{S390X_CAPBIT(S390X_QUERY),
271 0ULL},
272 /*.kmctr = */{0ULL, 0ULL},
273 /*.kmo = */{0ULL, 0ULL},
274 /*.kmf = */{0ULL, 0ULL},
275 /*.prno = */{0ULL, 0ULL},
276 /*.kma = */{0ULL, 0ULL},
277 /*.pcc = */{0ULL, 0ULL},
278 /*.kdsa = */{0ULL, 0ULL},
279 };
280
281 /*-
282 * z9 (2005) - z/Architecture POP SA22-7832-04
283 * Implements MSA and MSA1.
284 */
285 static const struct OPENSSL_s390xcap_st z9 = {
286 /*.stfle = */{S390X_CAPBIT(S390X_MSA)
287 | S390X_CAPBIT(S390X_STCKF),
288 0ULL, 0ULL, 0ULL},
289 /*.kimd = */{S390X_CAPBIT(S390X_QUERY)
290 | S390X_CAPBIT(S390X_SHA_1)
291 | S390X_CAPBIT(S390X_SHA_256),
292 0ULL},
293 /*.klmd = */{S390X_CAPBIT(S390X_QUERY)
294 | S390X_CAPBIT(S390X_SHA_1)
295 | S390X_CAPBIT(S390X_SHA_256),
296 0ULL},
297 /*.km = */{S390X_CAPBIT(S390X_QUERY)
298 | S390X_CAPBIT(S390X_AES_128),
299 0ULL},
300 /*.kmc = */{S390X_CAPBIT(S390X_QUERY)
301 | S390X_CAPBIT(S390X_AES_128),
302 0ULL},
303 /*.kmac = */{S390X_CAPBIT(S390X_QUERY),
304 0ULL},
305 /*.kmctr = */{0ULL, 0ULL},
306 /*.kmo = */{0ULL, 0ULL},
307 /*.kmf = */{0ULL, 0ULL},
308 /*.prno = */{0ULL, 0ULL},
309 /*.kma = */{0ULL, 0ULL},
310 /*.pcc = */{0ULL, 0ULL},
311 /*.kdsa = */{0ULL, 0ULL},
312 };
313
314 /*-
315 * z10 (2008) - z/Architecture POP SA22-7832-06
316 * Implements MSA and MSA1-2.
317 */
318 static const struct OPENSSL_s390xcap_st z10 = {
319 /*.stfle = */{S390X_CAPBIT(S390X_MSA)
320 | S390X_CAPBIT(S390X_STCKF),
321 0ULL, 0ULL, 0ULL},
322 /*.kimd = */{S390X_CAPBIT(S390X_QUERY)
323 | S390X_CAPBIT(S390X_SHA_1)
324 | S390X_CAPBIT(S390X_SHA_256)
325 | S390X_CAPBIT(S390X_SHA_512),
326 0ULL},
327 /*.klmd = */{S390X_CAPBIT(S390X_QUERY)
328 | S390X_CAPBIT(S390X_SHA_1)
329 | S390X_CAPBIT(S390X_SHA_256)
330 | S390X_CAPBIT(S390X_SHA_512),
331 0ULL},
332 /*.km = */{S390X_CAPBIT(S390X_QUERY)
333 | S390X_CAPBIT(S390X_AES_128)
334 | S390X_CAPBIT(S390X_AES_192)
335 | S390X_CAPBIT(S390X_AES_256),
336 0ULL},
337 /*.kmc = */{S390X_CAPBIT(S390X_QUERY)
338 | S390X_CAPBIT(S390X_AES_128)
339 | S390X_CAPBIT(S390X_AES_192)
340 | S390X_CAPBIT(S390X_AES_256),
341 0ULL},
342 /*.kmac = */{S390X_CAPBIT(S390X_QUERY),
343 0ULL},
344 /*.kmctr = */{0ULL, 0ULL},
345 /*.kmo = */{0ULL, 0ULL},
346 /*.kmf = */{0ULL, 0ULL},
347 /*.prno = */{0ULL, 0ULL},
348 /*.kma = */{0ULL, 0ULL},
349 /*.pcc = */{0ULL, 0ULL},
350 /*.kdsa = */{0ULL, 0ULL},
351 };
352
353 /*-
354 * z196 (2010) - z/Architecture POP SA22-7832-08
355 * Implements MSA and MSA1-4.
356 */
357 static const struct OPENSSL_s390xcap_st z196 = {
358 /*.stfle = */{S390X_CAPBIT(S390X_MSA)
359 | S390X_CAPBIT(S390X_STCKF),
360 S390X_CAPBIT(S390X_MSA3)
361 | S390X_CAPBIT(S390X_MSA4),
362 0ULL, 0ULL},
363 /*.kimd = */{S390X_CAPBIT(S390X_QUERY)
364 | S390X_CAPBIT(S390X_SHA_1)
365 | S390X_CAPBIT(S390X_SHA_256)
366 | S390X_CAPBIT(S390X_SHA_512),
367 S390X_CAPBIT(S390X_GHASH)},
368 /*.klmd = */{S390X_CAPBIT(S390X_QUERY)
369 | S390X_CAPBIT(S390X_SHA_1)
370 | S390X_CAPBIT(S390X_SHA_256)
371 | S390X_CAPBIT(S390X_SHA_512),
372 0ULL},
373 /*.km = */{S390X_CAPBIT(S390X_QUERY)
374 | S390X_CAPBIT(S390X_AES_128)
375 | S390X_CAPBIT(S390X_AES_192)
376 | S390X_CAPBIT(S390X_AES_256)
377 | S390X_CAPBIT(S390X_XTS_AES_128)
378 | S390X_CAPBIT(S390X_XTS_AES_256),
379 0ULL},
380 /*.kmc = */{S390X_CAPBIT(S390X_QUERY)
381 | S390X_CAPBIT(S390X_AES_128)
382 | S390X_CAPBIT(S390X_AES_192)
383 | S390X_CAPBIT(S390X_AES_256),
384 0ULL},
385 /*.kmac = */{S390X_CAPBIT(S390X_QUERY)
386 | S390X_CAPBIT(S390X_AES_128)
387 | S390X_CAPBIT(S390X_AES_192)
388 | S390X_CAPBIT(S390X_AES_256),
389 0ULL},
390 /*.kmctr = */{S390X_CAPBIT(S390X_QUERY)
391 | S390X_CAPBIT(S390X_AES_128)
392 | S390X_CAPBIT(S390X_AES_192)
393 | S390X_CAPBIT(S390X_AES_256),
394 0ULL},
395 /*.kmo = */{S390X_CAPBIT(S390X_QUERY)
396 | S390X_CAPBIT(S390X_AES_128)
397 | S390X_CAPBIT(S390X_AES_192)
398 | S390X_CAPBIT(S390X_AES_256),
399 0ULL},
400 /*.kmf = */{S390X_CAPBIT(S390X_QUERY)
401 | S390X_CAPBIT(S390X_AES_128)
402 | S390X_CAPBIT(S390X_AES_192)
403 | S390X_CAPBIT(S390X_AES_256),
404 0ULL},
405 /*.prno = */{0ULL, 0ULL},
406 /*.kma = */{0ULL, 0ULL},
407 /*.pcc = */{S390X_CAPBIT(S390X_QUERY),
408 0ULL},
409 /*.kdsa = */{0ULL, 0ULL},
410 };
411
412 /*-
413 * zEC12 (2012) - z/Architecture POP SA22-7832-09
414 * Implements MSA and MSA1-4.
415 */
416 static const struct OPENSSL_s390xcap_st zEC12 = {
417 /*.stfle = */{S390X_CAPBIT(S390X_MSA)
418 | S390X_CAPBIT(S390X_STCKF),
419 S390X_CAPBIT(S390X_MSA3)
420 | S390X_CAPBIT(S390X_MSA4),
421 0ULL, 0ULL},
422 /*.kimd = */{S390X_CAPBIT(S390X_QUERY)
423 | S390X_CAPBIT(S390X_SHA_1)
424 | S390X_CAPBIT(S390X_SHA_256)
425 | S390X_CAPBIT(S390X_SHA_512),
426 S390X_CAPBIT(S390X_GHASH)},
427 /*.klmd = */{S390X_CAPBIT(S390X_QUERY)
428 | S390X_CAPBIT(S390X_SHA_1)
429 | S390X_CAPBIT(S390X_SHA_256)
430 | S390X_CAPBIT(S390X_SHA_512),
431 0ULL},
432 /*.km = */{S390X_CAPBIT(S390X_QUERY)
433 | S390X_CAPBIT(S390X_AES_128)
434 | S390X_CAPBIT(S390X_AES_192)
435 | S390X_CAPBIT(S390X_AES_256)
436 | S390X_CAPBIT(S390X_XTS_AES_128)
437 | S390X_CAPBIT(S390X_XTS_AES_256),
438 0ULL},
439 /*.kmc = */{S390X_CAPBIT(S390X_QUERY)
440 | S390X_CAPBIT(S390X_AES_128)
441 | S390X_CAPBIT(S390X_AES_192)
442 | S390X_CAPBIT(S390X_AES_256),
443 0ULL},
444 /*.kmac = */{S390X_CAPBIT(S390X_QUERY)
445 | S390X_CAPBIT(S390X_AES_128)
446 | S390X_CAPBIT(S390X_AES_192)
447 | S390X_CAPBIT(S390X_AES_256),
448 0ULL},
449 /*.kmctr = */{S390X_CAPBIT(S390X_QUERY)
450 | S390X_CAPBIT(S390X_AES_128)
451 | S390X_CAPBIT(S390X_AES_192)
452 | S390X_CAPBIT(S390X_AES_256),
453 0ULL},
454 /*.kmo = */{S390X_CAPBIT(S390X_QUERY)
455 | S390X_CAPBIT(S390X_AES_128)
456 | S390X_CAPBIT(S390X_AES_192)
457 | S390X_CAPBIT(S390X_AES_256),
458 0ULL},
459 /*.kmf = */{S390X_CAPBIT(S390X_QUERY)
460 | S390X_CAPBIT(S390X_AES_128)
461 | S390X_CAPBIT(S390X_AES_192)
462 | S390X_CAPBIT(S390X_AES_256),
463 0ULL},
464 /*.prno = */{0ULL, 0ULL},
465 /*.kma = */{0ULL, 0ULL},
466 /*.pcc = */{S390X_CAPBIT(S390X_QUERY),
467 0ULL},
468 /*.kdsa = */{0ULL, 0ULL},
469 };
470
471 /*-
472 * z13 (2015) - z/Architecture POP SA22-7832-10
473 * Implements MSA and MSA1-5.
474 */
475 static const struct OPENSSL_s390xcap_st z13 = {
476 /*.stfle = */{S390X_CAPBIT(S390X_MSA)
477 | S390X_CAPBIT(S390X_STCKF)
478 | S390X_CAPBIT(S390X_MSA5),
479 S390X_CAPBIT(S390X_MSA3)
480 | S390X_CAPBIT(S390X_MSA4),
481 S390X_CAPBIT(S390X_VX),
482 0ULL},
483 /*.kimd = */{S390X_CAPBIT(S390X_QUERY)
484 | S390X_CAPBIT(S390X_SHA_1)
485 | S390X_CAPBIT(S390X_SHA_256)
486 | S390X_CAPBIT(S390X_SHA_512),
487 S390X_CAPBIT(S390X_GHASH)},
488 /*.klmd = */{S390X_CAPBIT(S390X_QUERY)
489 | S390X_CAPBIT(S390X_SHA_1)
490 | S390X_CAPBIT(S390X_SHA_256)
491 | S390X_CAPBIT(S390X_SHA_512),
492 0ULL},
493 /*.km = */{S390X_CAPBIT(S390X_QUERY)
494 | S390X_CAPBIT(S390X_AES_128)
495 | S390X_CAPBIT(S390X_AES_192)
496 | S390X_CAPBIT(S390X_AES_256)
497 | S390X_CAPBIT(S390X_XTS_AES_128)
498 | S390X_CAPBIT(S390X_XTS_AES_256),
499 0ULL},
500 /*.kmc = */{S390X_CAPBIT(S390X_QUERY)
501 | S390X_CAPBIT(S390X_AES_128)
502 | S390X_CAPBIT(S390X_AES_192)
503 | S390X_CAPBIT(S390X_AES_256),
504 0ULL},
505 /*.kmac = */{S390X_CAPBIT(S390X_QUERY)
506 | S390X_CAPBIT(S390X_AES_128)
507 | S390X_CAPBIT(S390X_AES_192)
508 | S390X_CAPBIT(S390X_AES_256),
509 0ULL},
510 /*.kmctr = */{S390X_CAPBIT(S390X_QUERY)
511 | S390X_CAPBIT(S390X_AES_128)
512 | S390X_CAPBIT(S390X_AES_192)
513 | S390X_CAPBIT(S390X_AES_256),
514 0ULL},
515 /*.kmo = */{S390X_CAPBIT(S390X_QUERY)
516 | S390X_CAPBIT(S390X_AES_128)
517 | S390X_CAPBIT(S390X_AES_192)
518 | S390X_CAPBIT(S390X_AES_256),
519 0ULL},
520 /*.kmf = */{S390X_CAPBIT(S390X_QUERY)
521 | S390X_CAPBIT(S390X_AES_128)
522 | S390X_CAPBIT(S390X_AES_192)
523 | S390X_CAPBIT(S390X_AES_256),
524 0ULL},
525 /*.prno = */{S390X_CAPBIT(S390X_QUERY)
526 | S390X_CAPBIT(S390X_SHA_512_DRNG),
527 0ULL},
528 /*.kma = */{0ULL, 0ULL},
529 /*.pcc = */{S390X_CAPBIT(S390X_QUERY),
530 0ULL},
531 /*.kdsa = */{0ULL, 0ULL},
532 };
533
534 /*-
535 * z14 (2017) - z/Architecture POP SA22-7832-11
536 * Implements MSA and MSA1-8.
537 */
538 static const struct OPENSSL_s390xcap_st z14 = {
539 /*.stfle = */{S390X_CAPBIT(S390X_MSA)
540 | S390X_CAPBIT(S390X_STCKF)
541 | S390X_CAPBIT(S390X_MSA5),
542 S390X_CAPBIT(S390X_MSA3)
543 | S390X_CAPBIT(S390X_MSA4),
544 S390X_CAPBIT(S390X_VX)
545 | S390X_CAPBIT(S390X_VXD)
546 | S390X_CAPBIT(S390X_VXE)
547 | S390X_CAPBIT(S390X_MSA8),
548 0ULL},
549 /*.kimd = */{S390X_CAPBIT(S390X_QUERY)
550 | S390X_CAPBIT(S390X_SHA_1)
551 | S390X_CAPBIT(S390X_SHA_256)
552 | S390X_CAPBIT(S390X_SHA_512)
553 | S390X_CAPBIT(S390X_SHA3_224)
554 | S390X_CAPBIT(S390X_SHA3_256)
555 | S390X_CAPBIT(S390X_SHA3_384)
556 | S390X_CAPBIT(S390X_SHA3_512)
557 | S390X_CAPBIT(S390X_SHAKE_128)
558 | S390X_CAPBIT(S390X_SHAKE_256),
559 S390X_CAPBIT(S390X_GHASH)},
560 /*.klmd = */{S390X_CAPBIT(S390X_QUERY)
561 | S390X_CAPBIT(S390X_SHA_1)
562 | S390X_CAPBIT(S390X_SHA_256)
563 | S390X_CAPBIT(S390X_SHA_512)
564 | S390X_CAPBIT(S390X_SHA3_224)
565 | S390X_CAPBIT(S390X_SHA3_256)
566 | S390X_CAPBIT(S390X_SHA3_384)
567 | S390X_CAPBIT(S390X_SHA3_512)
568 | S390X_CAPBIT(S390X_SHAKE_128)
569 | S390X_CAPBIT(S390X_SHAKE_256),
570 0ULL},
571 /*.km = */{S390X_CAPBIT(S390X_QUERY)
572 | S390X_CAPBIT(S390X_AES_128)
573 | S390X_CAPBIT(S390X_AES_192)
574 | S390X_CAPBIT(S390X_AES_256)
575 | S390X_CAPBIT(S390X_XTS_AES_128)
576 | S390X_CAPBIT(S390X_XTS_AES_256),
577 0ULL},
578 /*.kmc = */{S390X_CAPBIT(S390X_QUERY)
579 | S390X_CAPBIT(S390X_AES_128)
580 | S390X_CAPBIT(S390X_AES_192)
581 | S390X_CAPBIT(S390X_AES_256),
582 0ULL},
583 /*.kmac = */{S390X_CAPBIT(S390X_QUERY)
584 | S390X_CAPBIT(S390X_AES_128)
585 | S390X_CAPBIT(S390X_AES_192)
586 | S390X_CAPBIT(S390X_AES_256),
587 0ULL},
588 /*.kmctr = */{S390X_CAPBIT(S390X_QUERY)
589 | S390X_CAPBIT(S390X_AES_128)
590 | S390X_CAPBIT(S390X_AES_192)
591 | S390X_CAPBIT(S390X_AES_256),
592 0ULL},
593 /*.kmo = */{S390X_CAPBIT(S390X_QUERY)
594 | S390X_CAPBIT(S390X_AES_128)
595 | S390X_CAPBIT(S390X_AES_192)
596 | S390X_CAPBIT(S390X_AES_256),
597 0ULL},
598 /*.kmf = */{S390X_CAPBIT(S390X_QUERY)
599 | S390X_CAPBIT(S390X_AES_128)
600 | S390X_CAPBIT(S390X_AES_192)
601 | S390X_CAPBIT(S390X_AES_256),
602 0ULL},
603 /*.prno = */{S390X_CAPBIT(S390X_QUERY)
604 | S390X_CAPBIT(S390X_SHA_512_DRNG),
605 S390X_CAPBIT(S390X_TRNG)},
606 /*.kma = */{S390X_CAPBIT(S390X_QUERY)
607 | S390X_CAPBIT(S390X_AES_128)
608 | S390X_CAPBIT(S390X_AES_192)
609 | S390X_CAPBIT(S390X_AES_256),
610 0ULL},
611 /*.pcc = */{S390X_CAPBIT(S390X_QUERY),
612 0ULL},
613 /*.kdsa = */{0ULL, 0ULL},
614 };
615
616 /*-
617 * z15 (2019) - z/Architecture POP SA22-7832-12
618 * Implements MSA and MSA1-9.
619 */
620 static const struct OPENSSL_s390xcap_st z15 = {
621 /*.stfle = */{S390X_CAPBIT(S390X_MSA)
622 | S390X_CAPBIT(S390X_STCKF)
623 | S390X_CAPBIT(S390X_MSA5),
624 S390X_CAPBIT(S390X_MSA3)
625 | S390X_CAPBIT(S390X_MSA4),
626 S390X_CAPBIT(S390X_VX)
627 | S390X_CAPBIT(S390X_VXD)
628 | S390X_CAPBIT(S390X_VXE)
629 | S390X_CAPBIT(S390X_MSA8)
630 | S390X_CAPBIT(S390X_MSA9),
631 0ULL},
632 /*.kimd = */{S390X_CAPBIT(S390X_QUERY)
633 | S390X_CAPBIT(S390X_SHA_1)
634 | S390X_CAPBIT(S390X_SHA_256)
635 | S390X_CAPBIT(S390X_SHA_512)
636 | S390X_CAPBIT(S390X_SHA3_224)
637 | S390X_CAPBIT(S390X_SHA3_256)
638 | S390X_CAPBIT(S390X_SHA3_384)
639 | S390X_CAPBIT(S390X_SHA3_512)
640 | S390X_CAPBIT(S390X_SHAKE_128)
641 | S390X_CAPBIT(S390X_SHAKE_256),
642 S390X_CAPBIT(S390X_GHASH)},
643 /*.klmd = */{S390X_CAPBIT(S390X_QUERY)
644 | S390X_CAPBIT(S390X_SHA_1)
645 | S390X_CAPBIT(S390X_SHA_256)
646 | S390X_CAPBIT(S390X_SHA_512)
647 | S390X_CAPBIT(S390X_SHA3_224)
648 | S390X_CAPBIT(S390X_SHA3_256)
649 | S390X_CAPBIT(S390X_SHA3_384)
650 | S390X_CAPBIT(S390X_SHA3_512)
651 | S390X_CAPBIT(S390X_SHAKE_128)
652 | S390X_CAPBIT(S390X_SHAKE_256),
653 0ULL},
654 /*.km = */{S390X_CAPBIT(S390X_QUERY)
655 | S390X_CAPBIT(S390X_AES_128)
656 | S390X_CAPBIT(S390X_AES_192)
657 | S390X_CAPBIT(S390X_AES_256)
658 | S390X_CAPBIT(S390X_XTS_AES_128)
659 | S390X_CAPBIT(S390X_XTS_AES_256),
660 0ULL},
661 /*.kmc = */{S390X_CAPBIT(S390X_QUERY)
662 | S390X_CAPBIT(S390X_AES_128)
663 | S390X_CAPBIT(S390X_AES_192)
664 | S390X_CAPBIT(S390X_AES_256),
665 0ULL},
666 /*.kmac = */{S390X_CAPBIT(S390X_QUERY)
667 | S390X_CAPBIT(S390X_AES_128)
668 | S390X_CAPBIT(S390X_AES_192)
669 | S390X_CAPBIT(S390X_AES_256),
670 0ULL},
671 /*.kmctr = */{S390X_CAPBIT(S390X_QUERY)
672 | S390X_CAPBIT(S390X_AES_128)
673 | S390X_CAPBIT(S390X_AES_192)
674 | S390X_CAPBIT(S390X_AES_256),
675 0ULL},
676 /*.kmo = */{S390X_CAPBIT(S390X_QUERY)
677 | S390X_CAPBIT(S390X_AES_128)
678 | S390X_CAPBIT(S390X_AES_192)
679 | S390X_CAPBIT(S390X_AES_256),
680 0ULL},
681 /*.kmf = */{S390X_CAPBIT(S390X_QUERY)
682 | S390X_CAPBIT(S390X_AES_128)
683 | S390X_CAPBIT(S390X_AES_192)
684 | S390X_CAPBIT(S390X_AES_256),
685 0ULL},
686 /*.prno = */{S390X_CAPBIT(S390X_QUERY)
687 | S390X_CAPBIT(S390X_SHA_512_DRNG),
688 S390X_CAPBIT(S390X_TRNG)},
689 /*.kma = */{S390X_CAPBIT(S390X_QUERY)
690 | S390X_CAPBIT(S390X_AES_128)
691 | S390X_CAPBIT(S390X_AES_192)
692 | S390X_CAPBIT(S390X_AES_256),
693 0ULL},
694 /*.pcc = */{S390X_CAPBIT(S390X_QUERY),
695 S390X_CAPBIT(S390X_SCALAR_MULTIPLY_P256)
696 | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_P384)
697 | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_P521)
698 | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
699 | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
700 | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519)
701 | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448)},
702 /*.kdsa = */{S390X_CAPBIT(S390X_QUERY)
703 | S390X_CAPBIT(S390X_ECDSA_VERIFY_P256)
704 | S390X_CAPBIT(S390X_ECDSA_VERIFY_P384)
705 | S390X_CAPBIT(S390X_ECDSA_VERIFY_P521)
706 | S390X_CAPBIT(S390X_ECDSA_SIGN_P256)
707 | S390X_CAPBIT(S390X_ECDSA_SIGN_P384)
708 | S390X_CAPBIT(S390X_ECDSA_SIGN_P521)
709 | S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519)
710 | S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448)
711 | S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
712 | S390X_CAPBIT(S390X_EDDSA_SIGN_ED448),
713 0ULL},
714 };
715
716 /*-
717 * z16 (2022) - z/Architecture POP
718 * Implements MSA and MSA1-9 (same as z15, no need to repeat).
719 */
720
721 char *tok_begin, *tok_end, *buff, tok[S390X_STFLE_MAX][LEN + 1];
722 int rc, off, i, n;
723
724 buff = malloc(strlen(env) + 1);
725 if (buff == NULL)
726 return 0;
727
728 rc = 0;
729 memset(cap, ~0, sizeof(*cap));
730 strcpy(buff, env);
731
732 tok_begin = buff + strspn(buff, ";");
733 strtok(tok_begin, ";");
734 tok_end = strtok(NULL, ";");
735
736 while (tok_begin != NULL) {
737 /* stfle token */
738 if ((n = sscanf(tok_begin,
739 " stfle : %" STR(LEN) "[^:] : "
740 "%" STR(LEN) "[^:] : %" STR(LEN) "s ",
741 tok[0], tok[1], tok[2]))) {
742 for (i = 0; i < n; i++) {
743 off = (tok[i][0] == '~') ? 1 : 0;
744 if (sscanf(tok[i] + off, "%llx", &cap->stfle[i]) != 1)
745 goto ret;
746 if (off)
747 cap->stfle[i] = ~cap->stfle[i];
748 }
749 }
750
751 /* query function tokens */
752 else if TOK_FUNC(kimd)
753 else if TOK_FUNC(klmd)
754 else if TOK_FUNC(km)
755 else if TOK_FUNC(kmc)
756 else if TOK_FUNC(kmac)
757 else if TOK_FUNC(kmctr)
758 else if TOK_FUNC(kmo)
759 else if TOK_FUNC(kmf)
760 else if TOK_FUNC(prno)
761 else if TOK_FUNC(kma)
762 else if TOK_FUNC(pcc)
763 else if TOK_FUNC(kdsa)
764
765 /* CPU model tokens */
766 else if TOK_CPU(z900)
767 else if TOK_CPU(z990)
768 else if TOK_CPU(z9)
769 else if TOK_CPU(z10)
770 else if TOK_CPU(z196)
771 else if TOK_CPU(zEC12)
772 else if TOK_CPU(z13)
773 else if TOK_CPU(z14)
774 else if TOK_CPU(z15)
775 else if TOK_CPU_ALIAS(z16, z15)
776
777 /* nocex to deactivate cex support */
778 else if (sscanf(tok_begin, " %" STR(LEN) "s %" STR(LEN) "s ",
779 tok[0], tok[1]) == 1
780 && !strcmp(tok[0], "nocex")) {
781 *cex = 0;
782 }
783
784 /* whitespace(ignored) or invalid tokens */
785 else {
786 while (*tok_begin != '\0') {
787 if (!ossl_isspace(*tok_begin))
788 goto ret;
789 tok_begin++;
790 }
791 }
792
793 tok_begin = tok_end;
794 tok_end = strtok(NULL, ";");
795 }
796
797 rc = 1;
798 ret:
799 free(buff);
800 return rc;
801 }
802