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