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