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