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