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