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