Fix grammar in certificates.txt
[openssl.git] / crypto / s390xcap.c
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;
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 static int probe_cex(void);
90 int OPENSSL_s390xcex;
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
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
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         if (probe_cex() == 1)
221             OPENSSL_atexit(OPENSSL_s390x_cleanup);
222     }
223 #endif
224 }
225
226 #ifdef S390X_MOD_EXP
227 static int probe_cex(void)
228 {
229     struct ica_rsa_modexpo me;
230     const unsigned char inval[16] = {
231         0,0,0,0,0,0,0,0,
232         0,0,0,0,0,0,0,2
233     };
234     const unsigned char modulus[16] = {
235         0,0,0,0,0,0,0,0,
236         0,0,0,0,0,0,0,3
237     };
238     unsigned char res[16];
239     int olderrno;
240     int rc = 1;
241
242     me.inputdata = (unsigned char *)inval;
243     me.inputdatalength = sizeof(inval);
244     me.outputdata = (unsigned char *)res;
245     me.outputdatalength = sizeof(res);
246     me.b_key = (unsigned char *)inval;
247     me.n_modulus = (unsigned char *)modulus;
248     olderrno = errno;
249     if (ioctl(OPENSSL_s390xcex, ICARSAMODEXPO, &me) == -1) {
250         (void)close(OPENSSL_s390xcex);
251         OPENSSL_s390xcex = -1;
252         rc = 0;
253     }
254     errno = olderrno;
255     return rc;
256 }
257 #endif
258
259 static int parse_env(struct OPENSSL_s390xcap_st *cap, int *cex)
260 {
261     /*-
262      * CPU model data
263      * (only the STFLE- and QUERY-bits relevant to libcrypto are set)
264      */
265
266     /*-
267      * z900 (2000) - z/Architecture POP SA22-7832-00
268      * Facility detection would fail on real hw (no STFLE).
269      */
270     static const struct OPENSSL_s390xcap_st z900 = {
271         /*.stfle  = */{0ULL, 0ULL, 0ULL, 0ULL},
272         /*.kimd   = */{0ULL, 0ULL},
273         /*.klmd   = */{0ULL, 0ULL},
274         /*.km     = */{0ULL, 0ULL},
275         /*.kmc    = */{0ULL, 0ULL},
276         /*.kmac   = */{0ULL, 0ULL},
277         /*.kmctr  = */{0ULL, 0ULL},
278         /*.kmo    = */{0ULL, 0ULL},
279         /*.kmf    = */{0ULL, 0ULL},
280         /*.prno   = */{0ULL, 0ULL},
281         /*.kma    = */{0ULL, 0ULL},
282         /*.pcc    = */{0ULL, 0ULL},
283         /*.kdsa   = */{0ULL, 0ULL},
284     };
285
286     /*-
287      * z990 (2003) - z/Architecture POP SA22-7832-02
288      * Implements MSA. Facility detection would fail on real hw (no STFLE).
289      */
290     static const struct OPENSSL_s390xcap_st z990 = {
291         /*.stfle  = */{S390X_CAPBIT(S390X_MSA),
292                        0ULL, 0ULL, 0ULL},
293         /*.kimd   = */{S390X_CAPBIT(S390X_QUERY)
294                        | S390X_CAPBIT(S390X_SHA_1),
295                        0ULL},
296         /*.klmd   = */{S390X_CAPBIT(S390X_QUERY)
297                        | S390X_CAPBIT(S390X_SHA_1),
298                        0ULL},
299         /*.km     = */{S390X_CAPBIT(S390X_QUERY),
300                        0ULL},
301         /*.kmc    = */{S390X_CAPBIT(S390X_QUERY),
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      * z9 (2005) - z/Architecture POP SA22-7832-04
316      * Implements MSA and MSA1.
317      */
318     static const struct OPENSSL_s390xcap_st z9 = {
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                        0ULL},
326         /*.klmd   = */{S390X_CAPBIT(S390X_QUERY)
327                        | S390X_CAPBIT(S390X_SHA_1)
328                        | S390X_CAPBIT(S390X_SHA_256),
329                        0ULL},
330         /*.km     = */{S390X_CAPBIT(S390X_QUERY)
331                        | S390X_CAPBIT(S390X_AES_128),
332                        0ULL},
333         /*.kmc    = */{S390X_CAPBIT(S390X_QUERY)
334                        | S390X_CAPBIT(S390X_AES_128),
335                        0ULL},
336         /*.kmac   = */{S390X_CAPBIT(S390X_QUERY),
337                        0ULL},
338         /*.kmctr  = */{0ULL, 0ULL},
339         /*.kmo    = */{0ULL, 0ULL},
340         /*.kmf    = */{0ULL, 0ULL},
341         /*.prno   = */{0ULL, 0ULL},
342         /*.kma    = */{0ULL, 0ULL},
343         /*.pcc    = */{0ULL, 0ULL},
344         /*.kdsa   = */{0ULL, 0ULL},
345     };
346
347     /*-
348      * z10 (2008) - z/Architecture POP SA22-7832-06
349      * Implements MSA and MSA1-2.
350      */
351     static const struct OPENSSL_s390xcap_st z10 = {
352         /*.stfle  = */{S390X_CAPBIT(S390X_MSA)
353                        | S390X_CAPBIT(S390X_STCKF),
354                        0ULL, 0ULL, 0ULL},
355         /*.kimd   = */{S390X_CAPBIT(S390X_QUERY)
356                        | S390X_CAPBIT(S390X_SHA_1)
357                        | S390X_CAPBIT(S390X_SHA_256)
358                        | S390X_CAPBIT(S390X_SHA_512),
359                        0ULL},
360         /*.klmd   = */{S390X_CAPBIT(S390X_QUERY)
361                        | S390X_CAPBIT(S390X_SHA_1)
362                        | S390X_CAPBIT(S390X_SHA_256)
363                        | S390X_CAPBIT(S390X_SHA_512),
364                        0ULL},
365         /*.km     = */{S390X_CAPBIT(S390X_QUERY)
366                        | S390X_CAPBIT(S390X_AES_128)
367                        | S390X_CAPBIT(S390X_AES_192)
368                        | S390X_CAPBIT(S390X_AES_256),
369                        0ULL},
370         /*.kmc    = */{S390X_CAPBIT(S390X_QUERY)
371                        | S390X_CAPBIT(S390X_AES_128)
372                        | S390X_CAPBIT(S390X_AES_192)
373                        | S390X_CAPBIT(S390X_AES_256),
374                        0ULL},
375         /*.kmac   = */{S390X_CAPBIT(S390X_QUERY),
376                        0ULL},
377         /*.kmctr  = */{0ULL, 0ULL},
378         /*.kmo    = */{0ULL, 0ULL},
379         /*.kmf    = */{0ULL, 0ULL},
380         /*.prno   = */{0ULL, 0ULL},
381         /*.kma    = */{0ULL, 0ULL},
382         /*.pcc    = */{0ULL, 0ULL},
383         /*.kdsa   = */{0ULL, 0ULL},
384     };
385
386     /*-
387      * z196 (2010) - z/Architecture POP SA22-7832-08
388      * Implements MSA and MSA1-4.
389      */
390     static const struct OPENSSL_s390xcap_st z196 = {
391         /*.stfle  = */{S390X_CAPBIT(S390X_MSA)
392                        | S390X_CAPBIT(S390X_STCKF),
393                        S390X_CAPBIT(S390X_MSA3)
394                        | S390X_CAPBIT(S390X_MSA4),
395                        0ULL, 0ULL},
396         /*.kimd   = */{S390X_CAPBIT(S390X_QUERY)
397                        | S390X_CAPBIT(S390X_SHA_1)
398                        | S390X_CAPBIT(S390X_SHA_256)
399                        | S390X_CAPBIT(S390X_SHA_512),
400                        S390X_CAPBIT(S390X_GHASH)},
401         /*.klmd   = */{S390X_CAPBIT(S390X_QUERY)
402                        | S390X_CAPBIT(S390X_SHA_1)
403                        | S390X_CAPBIT(S390X_SHA_256)
404                        | S390X_CAPBIT(S390X_SHA_512),
405                        0ULL},
406         /*.km     = */{S390X_CAPBIT(S390X_QUERY)
407                        | S390X_CAPBIT(S390X_AES_128)
408                        | S390X_CAPBIT(S390X_AES_192)
409                        | S390X_CAPBIT(S390X_AES_256)
410                        | S390X_CAPBIT(S390X_XTS_AES_128)
411                        | S390X_CAPBIT(S390X_XTS_AES_256),
412                        0ULL},
413         /*.kmc    = */{S390X_CAPBIT(S390X_QUERY)
414                        | S390X_CAPBIT(S390X_AES_128)
415                        | S390X_CAPBIT(S390X_AES_192)
416                        | S390X_CAPBIT(S390X_AES_256),
417                        0ULL},
418         /*.kmac   = */{S390X_CAPBIT(S390X_QUERY)
419                        | S390X_CAPBIT(S390X_AES_128)
420                        | S390X_CAPBIT(S390X_AES_192)
421                        | S390X_CAPBIT(S390X_AES_256),
422                        0ULL},
423         /*.kmctr  = */{S390X_CAPBIT(S390X_QUERY)
424                        | S390X_CAPBIT(S390X_AES_128)
425                        | S390X_CAPBIT(S390X_AES_192)
426                        | S390X_CAPBIT(S390X_AES_256),
427                        0ULL},
428         /*.kmo    = */{S390X_CAPBIT(S390X_QUERY)
429                        | S390X_CAPBIT(S390X_AES_128)
430                        | S390X_CAPBIT(S390X_AES_192)
431                        | S390X_CAPBIT(S390X_AES_256),
432                        0ULL},
433         /*.kmf    = */{S390X_CAPBIT(S390X_QUERY)
434                        | S390X_CAPBIT(S390X_AES_128)
435                        | S390X_CAPBIT(S390X_AES_192)
436                        | S390X_CAPBIT(S390X_AES_256),
437                        0ULL},
438         /*.prno   = */{0ULL, 0ULL},
439         /*.kma    = */{0ULL, 0ULL},
440         /*.pcc    = */{S390X_CAPBIT(S390X_QUERY),
441                        0ULL},
442         /*.kdsa   = */{0ULL, 0ULL},
443     };
444
445     /*-
446      * zEC12 (2012) - z/Architecture POP SA22-7832-09
447      * Implements MSA and MSA1-4.
448      */
449     static const struct OPENSSL_s390xcap_st zEC12 = {
450         /*.stfle  = */{S390X_CAPBIT(S390X_MSA)
451                        | S390X_CAPBIT(S390X_STCKF),
452                        S390X_CAPBIT(S390X_MSA3)
453                        | S390X_CAPBIT(S390X_MSA4),
454                        0ULL, 0ULL},
455         /*.kimd   = */{S390X_CAPBIT(S390X_QUERY)
456                        | S390X_CAPBIT(S390X_SHA_1)
457                        | S390X_CAPBIT(S390X_SHA_256)
458                        | S390X_CAPBIT(S390X_SHA_512),
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                        0ULL},
465         /*.km     = */{S390X_CAPBIT(S390X_QUERY)
466                        | S390X_CAPBIT(S390X_AES_128)
467                        | S390X_CAPBIT(S390X_AES_192)
468                        | S390X_CAPBIT(S390X_AES_256)
469                        | S390X_CAPBIT(S390X_XTS_AES_128)
470                        | S390X_CAPBIT(S390X_XTS_AES_256),
471                        0ULL},
472         /*.kmc    = */{S390X_CAPBIT(S390X_QUERY)
473                        | S390X_CAPBIT(S390X_AES_128)
474                        | S390X_CAPBIT(S390X_AES_192)
475                        | S390X_CAPBIT(S390X_AES_256),
476                        0ULL},
477         /*.kmac   = */{S390X_CAPBIT(S390X_QUERY)
478                        | S390X_CAPBIT(S390X_AES_128)
479                        | S390X_CAPBIT(S390X_AES_192)
480                        | S390X_CAPBIT(S390X_AES_256),
481                        0ULL},
482         /*.kmctr  = */{S390X_CAPBIT(S390X_QUERY)
483                        | S390X_CAPBIT(S390X_AES_128)
484                        | S390X_CAPBIT(S390X_AES_192)
485                        | S390X_CAPBIT(S390X_AES_256),
486                        0ULL},
487         /*.kmo    = */{S390X_CAPBIT(S390X_QUERY)
488                        | S390X_CAPBIT(S390X_AES_128)
489                        | S390X_CAPBIT(S390X_AES_192)
490                        | S390X_CAPBIT(S390X_AES_256),
491                        0ULL},
492         /*.kmf    = */{S390X_CAPBIT(S390X_QUERY)
493                        | S390X_CAPBIT(S390X_AES_128)
494                        | S390X_CAPBIT(S390X_AES_192)
495                        | S390X_CAPBIT(S390X_AES_256),
496                        0ULL},
497         /*.prno   = */{0ULL, 0ULL},
498         /*.kma    = */{0ULL, 0ULL},
499         /*.pcc    = */{S390X_CAPBIT(S390X_QUERY),
500                        0ULL},
501         /*.kdsa   = */{0ULL, 0ULL},
502     };
503
504     /*-
505      * z13 (2015) - z/Architecture POP SA22-7832-10
506      * Implements MSA and MSA1-5.
507      */
508     static const struct OPENSSL_s390xcap_st z13 = {
509         /*.stfle  = */{S390X_CAPBIT(S390X_MSA)
510                        | S390X_CAPBIT(S390X_STCKF)
511                        | S390X_CAPBIT(S390X_MSA5),
512                        S390X_CAPBIT(S390X_MSA3)
513                        | S390X_CAPBIT(S390X_MSA4),
514                        S390X_CAPBIT(S390X_VX),
515                        0ULL},
516         /*.kimd   = */{S390X_CAPBIT(S390X_QUERY)
517                        | S390X_CAPBIT(S390X_SHA_1)
518                        | S390X_CAPBIT(S390X_SHA_256)
519                        | S390X_CAPBIT(S390X_SHA_512),
520                        S390X_CAPBIT(S390X_GHASH)},
521         /*.klmd   = */{S390X_CAPBIT(S390X_QUERY)
522                        | S390X_CAPBIT(S390X_SHA_1)
523                        | S390X_CAPBIT(S390X_SHA_256)
524                        | S390X_CAPBIT(S390X_SHA_512),
525                        0ULL},
526         /*.km     = */{S390X_CAPBIT(S390X_QUERY)
527                        | S390X_CAPBIT(S390X_AES_128)
528                        | S390X_CAPBIT(S390X_AES_192)
529                        | S390X_CAPBIT(S390X_AES_256)
530                        | S390X_CAPBIT(S390X_XTS_AES_128)
531                        | S390X_CAPBIT(S390X_XTS_AES_256),
532                        0ULL},
533         /*.kmc    = */{S390X_CAPBIT(S390X_QUERY)
534                        | S390X_CAPBIT(S390X_AES_128)
535                        | S390X_CAPBIT(S390X_AES_192)
536                        | S390X_CAPBIT(S390X_AES_256),
537                        0ULL},
538         /*.kmac   = */{S390X_CAPBIT(S390X_QUERY)
539                        | S390X_CAPBIT(S390X_AES_128)
540                        | S390X_CAPBIT(S390X_AES_192)
541                        | S390X_CAPBIT(S390X_AES_256),
542                        0ULL},
543         /*.kmctr  = */{S390X_CAPBIT(S390X_QUERY)
544                        | S390X_CAPBIT(S390X_AES_128)
545                        | S390X_CAPBIT(S390X_AES_192)
546                        | S390X_CAPBIT(S390X_AES_256),
547                        0ULL},
548         /*.kmo    = */{S390X_CAPBIT(S390X_QUERY)
549                        | S390X_CAPBIT(S390X_AES_128)
550                        | S390X_CAPBIT(S390X_AES_192)
551                        | S390X_CAPBIT(S390X_AES_256),
552                        0ULL},
553         /*.kmf    = */{S390X_CAPBIT(S390X_QUERY)
554                        | S390X_CAPBIT(S390X_AES_128)
555                        | S390X_CAPBIT(S390X_AES_192)
556                        | S390X_CAPBIT(S390X_AES_256),
557                        0ULL},
558         /*.prno   = */{S390X_CAPBIT(S390X_QUERY)
559                        | S390X_CAPBIT(S390X_SHA_512_DRNG),
560                        0ULL},
561         /*.kma    = */{0ULL, 0ULL},
562         /*.pcc    = */{S390X_CAPBIT(S390X_QUERY),
563                        0ULL},
564         /*.kdsa   = */{0ULL, 0ULL},
565     };
566
567     /*-
568      * z14 (2017) - z/Architecture POP SA22-7832-11
569      * Implements MSA and MSA1-8.
570      */
571     static const struct OPENSSL_s390xcap_st z14 = {
572         /*.stfle  = */{S390X_CAPBIT(S390X_MSA)
573                        | S390X_CAPBIT(S390X_STCKF)
574                        | S390X_CAPBIT(S390X_MSA5),
575                        S390X_CAPBIT(S390X_MSA3)
576                        | S390X_CAPBIT(S390X_MSA4),
577                        S390X_CAPBIT(S390X_VX)
578                        | S390X_CAPBIT(S390X_VXD)
579                        | S390X_CAPBIT(S390X_VXE)
580                        | S390X_CAPBIT(S390X_MSA8),
581                        0ULL},
582         /*.kimd   = */{S390X_CAPBIT(S390X_QUERY)
583                        | S390X_CAPBIT(S390X_SHA_1)
584                        | S390X_CAPBIT(S390X_SHA_256)
585                        | S390X_CAPBIT(S390X_SHA_512)
586                        | S390X_CAPBIT(S390X_SHA3_224)
587                        | S390X_CAPBIT(S390X_SHA3_256)
588                        | S390X_CAPBIT(S390X_SHA3_384)
589                        | S390X_CAPBIT(S390X_SHA3_512)
590                        | S390X_CAPBIT(S390X_SHAKE_128)
591                        | S390X_CAPBIT(S390X_SHAKE_256),
592                        S390X_CAPBIT(S390X_GHASH)},
593         /*.klmd   = */{S390X_CAPBIT(S390X_QUERY)
594                        | S390X_CAPBIT(S390X_SHA_1)
595                        | S390X_CAPBIT(S390X_SHA_256)
596                        | S390X_CAPBIT(S390X_SHA_512)
597                        | S390X_CAPBIT(S390X_SHA3_224)
598                        | S390X_CAPBIT(S390X_SHA3_256)
599                        | S390X_CAPBIT(S390X_SHA3_384)
600                        | S390X_CAPBIT(S390X_SHA3_512)
601                        | S390X_CAPBIT(S390X_SHAKE_128)
602                        | S390X_CAPBIT(S390X_SHAKE_256),
603                        0ULL},
604         /*.km     = */{S390X_CAPBIT(S390X_QUERY)
605                        | S390X_CAPBIT(S390X_AES_128)
606                        | S390X_CAPBIT(S390X_AES_192)
607                        | S390X_CAPBIT(S390X_AES_256)
608                        | S390X_CAPBIT(S390X_XTS_AES_128)
609                        | S390X_CAPBIT(S390X_XTS_AES_256),
610                        0ULL},
611         /*.kmc    = */{S390X_CAPBIT(S390X_QUERY)
612                        | S390X_CAPBIT(S390X_AES_128)
613                        | S390X_CAPBIT(S390X_AES_192)
614                        | S390X_CAPBIT(S390X_AES_256),
615                        0ULL},
616         /*.kmac   = */{S390X_CAPBIT(S390X_QUERY)
617                        | S390X_CAPBIT(S390X_AES_128)
618                        | S390X_CAPBIT(S390X_AES_192)
619                        | S390X_CAPBIT(S390X_AES_256),
620                        0ULL},
621         /*.kmctr  = */{S390X_CAPBIT(S390X_QUERY)
622                        | S390X_CAPBIT(S390X_AES_128)
623                        | S390X_CAPBIT(S390X_AES_192)
624                        | S390X_CAPBIT(S390X_AES_256),
625                        0ULL},
626         /*.kmo    = */{S390X_CAPBIT(S390X_QUERY)
627                        | S390X_CAPBIT(S390X_AES_128)
628                        | S390X_CAPBIT(S390X_AES_192)
629                        | S390X_CAPBIT(S390X_AES_256),
630                        0ULL},
631         /*.kmf    = */{S390X_CAPBIT(S390X_QUERY)
632                        | S390X_CAPBIT(S390X_AES_128)
633                        | S390X_CAPBIT(S390X_AES_192)
634                        | S390X_CAPBIT(S390X_AES_256),
635                        0ULL},
636         /*.prno   = */{S390X_CAPBIT(S390X_QUERY)
637                        | S390X_CAPBIT(S390X_SHA_512_DRNG),
638                        S390X_CAPBIT(S390X_TRNG)},
639         /*.kma    = */{S390X_CAPBIT(S390X_QUERY)
640                        | S390X_CAPBIT(S390X_AES_128)
641                        | S390X_CAPBIT(S390X_AES_192)
642                        | S390X_CAPBIT(S390X_AES_256),
643                        0ULL},
644         /*.pcc    = */{S390X_CAPBIT(S390X_QUERY),
645                        0ULL},
646         /*.kdsa   = */{0ULL, 0ULL},
647     };
648
649     /*-
650      * z15 (2019) - z/Architecture POP SA22-7832-12
651      * Implements MSA and MSA1-9.
652      */
653     static const struct OPENSSL_s390xcap_st z15 = {
654         /*.stfle  = */{S390X_CAPBIT(S390X_MSA)
655                        | S390X_CAPBIT(S390X_STCKF)
656                        | S390X_CAPBIT(S390X_MSA5),
657                        S390X_CAPBIT(S390X_MSA3)
658                        | S390X_CAPBIT(S390X_MSA4),
659                        S390X_CAPBIT(S390X_VX)
660                        | S390X_CAPBIT(S390X_VXD)
661                        | S390X_CAPBIT(S390X_VXE)
662                        | S390X_CAPBIT(S390X_MSA8)
663                        | S390X_CAPBIT(S390X_MSA9),
664                        0ULL},
665         /*.kimd   = */{S390X_CAPBIT(S390X_QUERY)
666                        | S390X_CAPBIT(S390X_SHA_1)
667                        | S390X_CAPBIT(S390X_SHA_256)
668                        | S390X_CAPBIT(S390X_SHA_512)
669                        | S390X_CAPBIT(S390X_SHA3_224)
670                        | S390X_CAPBIT(S390X_SHA3_256)
671                        | S390X_CAPBIT(S390X_SHA3_384)
672                        | S390X_CAPBIT(S390X_SHA3_512)
673                        | S390X_CAPBIT(S390X_SHAKE_128)
674                        | S390X_CAPBIT(S390X_SHAKE_256),
675                        S390X_CAPBIT(S390X_GHASH)},
676         /*.klmd   = */{S390X_CAPBIT(S390X_QUERY)
677                        | S390X_CAPBIT(S390X_SHA_1)
678                        | S390X_CAPBIT(S390X_SHA_256)
679                        | S390X_CAPBIT(S390X_SHA_512)
680                        | S390X_CAPBIT(S390X_SHA3_224)
681                        | S390X_CAPBIT(S390X_SHA3_256)
682                        | S390X_CAPBIT(S390X_SHA3_384)
683                        | S390X_CAPBIT(S390X_SHA3_512)
684                        | S390X_CAPBIT(S390X_SHAKE_128)
685                        | S390X_CAPBIT(S390X_SHAKE_256),
686                        0ULL},
687         /*.km     = */{S390X_CAPBIT(S390X_QUERY)
688                        | S390X_CAPBIT(S390X_AES_128)
689                        | S390X_CAPBIT(S390X_AES_192)
690                        | S390X_CAPBIT(S390X_AES_256)
691                        | S390X_CAPBIT(S390X_XTS_AES_128)
692                        | S390X_CAPBIT(S390X_XTS_AES_256),
693                        0ULL},
694         /*.kmc    = */{S390X_CAPBIT(S390X_QUERY)
695                        | S390X_CAPBIT(S390X_AES_128)
696                        | S390X_CAPBIT(S390X_AES_192)
697                        | S390X_CAPBIT(S390X_AES_256),
698                        0ULL},
699         /*.kmac   = */{S390X_CAPBIT(S390X_QUERY)
700                        | S390X_CAPBIT(S390X_AES_128)
701                        | S390X_CAPBIT(S390X_AES_192)
702                        | S390X_CAPBIT(S390X_AES_256),
703                        0ULL},
704         /*.kmctr  = */{S390X_CAPBIT(S390X_QUERY)
705                        | S390X_CAPBIT(S390X_AES_128)
706                        | S390X_CAPBIT(S390X_AES_192)
707                        | S390X_CAPBIT(S390X_AES_256),
708                        0ULL},
709         /*.kmo    = */{S390X_CAPBIT(S390X_QUERY)
710                        | S390X_CAPBIT(S390X_AES_128)
711                        | S390X_CAPBIT(S390X_AES_192)
712                        | S390X_CAPBIT(S390X_AES_256),
713                        0ULL},
714         /*.kmf    = */{S390X_CAPBIT(S390X_QUERY)
715                        | S390X_CAPBIT(S390X_AES_128)
716                        | S390X_CAPBIT(S390X_AES_192)
717                        | S390X_CAPBIT(S390X_AES_256),
718                        0ULL},
719         /*.prno   = */{S390X_CAPBIT(S390X_QUERY)
720                        | S390X_CAPBIT(S390X_SHA_512_DRNG),
721                        S390X_CAPBIT(S390X_TRNG)},
722         /*.kma    = */{S390X_CAPBIT(S390X_QUERY)
723                        | S390X_CAPBIT(S390X_AES_128)
724                        | S390X_CAPBIT(S390X_AES_192)
725                        | S390X_CAPBIT(S390X_AES_256),
726                        0ULL},
727         /*.pcc    = */{S390X_CAPBIT(S390X_QUERY),
728                        S390X_CAPBIT(S390X_SCALAR_MULTIPLY_P256)
729                        | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_P384)
730                        | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_P521)
731                        | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
732                        | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
733                        | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519)
734                        | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448)},
735         /*.kdsa   = */{S390X_CAPBIT(S390X_QUERY)
736                        | S390X_CAPBIT(S390X_ECDSA_VERIFY_P256)
737                        | S390X_CAPBIT(S390X_ECDSA_VERIFY_P384)
738                        | S390X_CAPBIT(S390X_ECDSA_VERIFY_P521)
739                        | S390X_CAPBIT(S390X_ECDSA_SIGN_P256)
740                        | S390X_CAPBIT(S390X_ECDSA_SIGN_P384)
741                        | S390X_CAPBIT(S390X_ECDSA_SIGN_P521)
742                        | S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519)
743                        | S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448)
744                        | S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
745                        | S390X_CAPBIT(S390X_EDDSA_SIGN_ED448),
746                        0ULL},
747     };
748
749     /*-
750      * z16 (2022) - z/Architecture POP
751      * Implements MSA and MSA1-9 (same as z15, no need to repeat).
752      */
753
754     char *tok_begin, *tok_end, *buff, tok[S390X_STFLE_MAX][LEN + 1];
755     int rc, off, i, n;
756
757     buff = malloc(strlen(env) + 1);
758     if (buff == NULL)
759         return 0;
760
761     rc = 0;
762     memset(cap, ~0, sizeof(*cap));
763     strcpy(buff, env);
764
765     tok_begin = buff + strspn(buff, ";");
766     strtok(tok_begin, ";");
767     tok_end = strtok(NULL, ";");
768
769     while (tok_begin != NULL) {
770         /* stfle token */
771         if ((n = sscanf(tok_begin,
772                         " stfle : %" STR(LEN) "[^:] : "
773                         "%" STR(LEN) "[^:] : %" STR(LEN) "s ",
774                         tok[0], tok[1], tok[2]))) {
775             for (i = 0; i < n; i++) {
776                 off = (tok[i][0] == '~') ? 1 : 0;
777                 if (sscanf(tok[i] + off, "%llx", &cap->stfle[i]) != 1)
778                     goto ret;
779                 if (off)
780                     cap->stfle[i] = ~cap->stfle[i];
781             }
782         }
783
784         /* query function tokens */
785         else if TOK_FUNC(kimd)
786         else if TOK_FUNC(klmd)
787         else if TOK_FUNC(km)
788         else if TOK_FUNC(kmc)
789         else if TOK_FUNC(kmac)
790         else if TOK_FUNC(kmctr)
791         else if TOK_FUNC(kmo)
792         else if TOK_FUNC(kmf)
793         else if TOK_FUNC(prno)
794         else if TOK_FUNC(kma)
795         else if TOK_FUNC(pcc)
796         else if TOK_FUNC(kdsa)
797
798         /* CPU model tokens */
799         else if TOK_CPU(z900)
800         else if TOK_CPU(z990)
801         else if TOK_CPU(z9)
802         else if TOK_CPU(z10)
803         else if TOK_CPU(z196)
804         else if TOK_CPU(zEC12)
805         else if TOK_CPU(z13)
806         else if TOK_CPU(z14)
807         else if TOK_CPU(z15)
808         else if TOK_CPU_ALIAS(z16, z15)
809
810         /* nocex to deactivate cex support */
811         else if (sscanf(tok_begin, " %" STR(LEN) "s %" STR(LEN) "s ",
812                         tok[0], tok[1]) == 1
813                 && !strcmp(tok[0], "nocex")) {
814             *cex = 0;
815         }
816
817         /* whitespace(ignored) or invalid tokens */
818         else {
819             while (*tok_begin != '\0') {
820                 if (!ossl_isspace(*tok_begin))
821                     goto ret;
822                 tok_begin++;
823             }
824         }
825
826         tok_begin = tok_end;
827         tok_end = strtok(NULL, ";");
828     }
829
830     rc = 1;
831 ret:
832     free(buff);
833     return rc;
834 }