Rework build: add special cases for AIX
[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     }
141 }
142
143 static int parse_env(struct OPENSSL_s390xcap_st *cap)
144 {
145     /*-
146      * CPU model data
147      * (only the STFLE- and QUERY-bits relevant to libcrypto are set)
148      */
149
150     /*-
151      * z900 (2000) - z/Architecture POP SA22-7832-00
152      * Facility detection would fail on real hw (no STFLE).
153      */
154     static const struct OPENSSL_s390xcap_st z900 = {
155         .stfle  = {0ULL, 0ULL, 0ULL, 0ULL},
156         .kimd   = {0ULL, 0ULL},
157         .klmd   = {0ULL, 0ULL},
158         .km     = {0ULL, 0ULL},
159         .kmc    = {0ULL, 0ULL},
160         .kmac   = {0ULL, 0ULL},
161         .kmctr  = {0ULL, 0ULL},
162         .kmo    = {0ULL, 0ULL},
163         .kmf    = {0ULL, 0ULL},
164         .prno   = {0ULL, 0ULL},
165         .kma    = {0ULL, 0ULL},
166     };
167
168     /*-
169      * z990 (2003) - z/Architecture POP SA22-7832-02
170      * Implements MSA. Facility detection would fail on real hw (no STFLE).
171      */
172     static const struct OPENSSL_s390xcap_st z990 = {
173         .stfle  = {S390X_CAPBIT(S390X_MSA),
174                    0ULL, 0ULL, 0ULL},
175         .kimd   = {S390X_CAPBIT(S390X_QUERY)
176                      | S390X_CAPBIT(S390X_SHA_1),
177                    0ULL},
178         .klmd   = {S390X_CAPBIT(S390X_QUERY)
179                      | S390X_CAPBIT(S390X_SHA_1),
180                    0ULL},
181         .km     = {S390X_CAPBIT(S390X_QUERY),
182                    0ULL},
183         .kmc    = {S390X_CAPBIT(S390X_QUERY),
184                    0ULL},
185         .kmac   = {S390X_CAPBIT(S390X_QUERY),
186                    0ULL},
187         .kmctr  = {0ULL, 0ULL},
188         .kmo    = {0ULL, 0ULL},
189         .kmf    = {0ULL, 0ULL},
190         .prno   = {0ULL, 0ULL},
191         .kma    = {0ULL, 0ULL},
192     };
193
194     /*-
195      * z9 (2005) - z/Architecture POP SA22-7832-04
196      * Implements MSA and MSA1.
197      */
198     static const struct OPENSSL_s390xcap_st z9 = {
199         .stfle  = {S390X_CAPBIT(S390X_MSA)
200                      | S390X_CAPBIT(S390X_STCKF),
201                    0ULL, 0ULL, 0ULL},
202         .kimd   = {S390X_CAPBIT(S390X_QUERY)
203                      | S390X_CAPBIT(S390X_SHA_1)
204                      | S390X_CAPBIT(S390X_SHA_256),
205                    0ULL},
206         .klmd   = {S390X_CAPBIT(S390X_QUERY)
207                      | S390X_CAPBIT(S390X_SHA_1)
208                      | S390X_CAPBIT(S390X_SHA_256),
209                    0ULL},
210         .km     = {S390X_CAPBIT(S390X_QUERY)
211                      | S390X_CAPBIT(S390X_AES_128),
212                    0ULL},
213         .kmc    = {S390X_CAPBIT(S390X_QUERY)
214                      | S390X_CAPBIT(S390X_AES_128),
215                    0ULL},
216         .kmac   = {S390X_CAPBIT(S390X_QUERY),
217                    0ULL},
218         .kmctr  = {0ULL, 0ULL},
219         .kmo    = {0ULL, 0ULL},
220         .kmf    = {0ULL, 0ULL},
221         .prno   = {0ULL, 0ULL},
222         .kma    = {0ULL, 0ULL},
223     };
224
225     /*-
226      * z10 (2008) - z/Architecture POP SA22-7832-06
227      * Implements MSA and MSA1-2.
228      */
229     static const struct OPENSSL_s390xcap_st z10 = {
230         .stfle  = {S390X_CAPBIT(S390X_MSA)
231                      | S390X_CAPBIT(S390X_STCKF),
232                    0ULL, 0ULL, 0ULL},
233         .kimd   = {S390X_CAPBIT(S390X_QUERY)
234                      | S390X_CAPBIT(S390X_SHA_1)
235                      | S390X_CAPBIT(S390X_SHA_256)
236                      | S390X_CAPBIT(S390X_SHA_512),
237                    0ULL},
238         .klmd   = {S390X_CAPBIT(S390X_QUERY)
239                      | S390X_CAPBIT(S390X_SHA_1)
240                      | S390X_CAPBIT(S390X_SHA_256)
241                      | S390X_CAPBIT(S390X_SHA_512),
242                    0ULL},
243         .km     = {S390X_CAPBIT(S390X_QUERY)
244                      | S390X_CAPBIT(S390X_AES_128)
245                      | S390X_CAPBIT(S390X_AES_192)
246                      | S390X_CAPBIT(S390X_AES_256),
247                    0ULL},
248         .kmc    = {S390X_CAPBIT(S390X_QUERY)
249                      | S390X_CAPBIT(S390X_AES_128)
250                      | S390X_CAPBIT(S390X_AES_192)
251                      | S390X_CAPBIT(S390X_AES_256),
252                    0ULL},
253         .kmac   = {S390X_CAPBIT(S390X_QUERY),
254                    0ULL},
255         .kmctr  = {0ULL, 0ULL},
256         .kmo    = {0ULL, 0ULL},
257         .kmf    = {0ULL, 0ULL},
258         .prno   = {0ULL, 0ULL},
259         .kma    = {0ULL, 0ULL},
260     };
261
262     /*-
263      * z196 (2010) - z/Architecture POP SA22-7832-08
264      * Implements MSA and MSA1-4.
265      */
266     static const struct OPENSSL_s390xcap_st z196 = {
267         .stfle  = {S390X_CAPBIT(S390X_MSA)
268                      | S390X_CAPBIT(S390X_STCKF),
269                    S390X_CAPBIT(S390X_MSA3)
270                      | S390X_CAPBIT(S390X_MSA4),
271                    0ULL, 0ULL},
272         .kimd   = {S390X_CAPBIT(S390X_QUERY)
273                      | S390X_CAPBIT(S390X_SHA_1)
274                      | S390X_CAPBIT(S390X_SHA_256)
275                      | S390X_CAPBIT(S390X_SHA_512),
276                    S390X_CAPBIT(S390X_GHASH)},
277         .klmd   = {S390X_CAPBIT(S390X_QUERY)
278                      | S390X_CAPBIT(S390X_SHA_1)
279                      | S390X_CAPBIT(S390X_SHA_256)
280                      | S390X_CAPBIT(S390X_SHA_512),
281                    0ULL},
282         .km     = {S390X_CAPBIT(S390X_QUERY)
283                      | S390X_CAPBIT(S390X_AES_128)
284                      | S390X_CAPBIT(S390X_AES_192)
285                      | S390X_CAPBIT(S390X_AES_256)
286                      | S390X_CAPBIT(S390X_XTS_AES_128)
287                      | S390X_CAPBIT(S390X_XTS_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                      | S390X_CAPBIT(S390X_AES_128)
296                      | S390X_CAPBIT(S390X_AES_192)
297                      | S390X_CAPBIT(S390X_AES_256),
298                    0ULL},
299         .kmctr  = {S390X_CAPBIT(S390X_QUERY)
300                      | S390X_CAPBIT(S390X_AES_128)
301                      | S390X_CAPBIT(S390X_AES_192)
302                      | S390X_CAPBIT(S390X_AES_256),
303                    0ULL},
304         .kmo    = {S390X_CAPBIT(S390X_QUERY)
305                      | S390X_CAPBIT(S390X_AES_128)
306                      | S390X_CAPBIT(S390X_AES_192)
307                      | S390X_CAPBIT(S390X_AES_256),
308                    0ULL},
309         .kmf    = {S390X_CAPBIT(S390X_QUERY)
310                      | S390X_CAPBIT(S390X_AES_128)
311                      | S390X_CAPBIT(S390X_AES_192)
312                      | S390X_CAPBIT(S390X_AES_256),
313                    0ULL},
314         .prno   = {0ULL, 0ULL},
315         .kma    = {0ULL, 0ULL},
316     };
317
318     /*-
319      * zEC12 (2012) - z/Architecture POP SA22-7832-09
320      * Implements MSA and MSA1-4.
321      */
322     static const struct OPENSSL_s390xcap_st zEC12 = {
323         .stfle  = {S390X_CAPBIT(S390X_MSA)
324                      | S390X_CAPBIT(S390X_STCKF),
325                    S390X_CAPBIT(S390X_MSA3)
326                      | S390X_CAPBIT(S390X_MSA4),
327                    0ULL, 0ULL},
328         .kimd   = {S390X_CAPBIT(S390X_QUERY)
329                      | S390X_CAPBIT(S390X_SHA_1)
330                      | S390X_CAPBIT(S390X_SHA_256)
331                      | S390X_CAPBIT(S390X_SHA_512),
332                    S390X_CAPBIT(S390X_GHASH)},
333         .klmd   = {S390X_CAPBIT(S390X_QUERY)
334                      | S390X_CAPBIT(S390X_SHA_1)
335                      | S390X_CAPBIT(S390X_SHA_256)
336                      | S390X_CAPBIT(S390X_SHA_512),
337                    0ULL},
338         .km     = {S390X_CAPBIT(S390X_QUERY)
339                      | S390X_CAPBIT(S390X_AES_128)
340                      | S390X_CAPBIT(S390X_AES_192)
341                      | S390X_CAPBIT(S390X_AES_256)
342                      | S390X_CAPBIT(S390X_XTS_AES_128)
343                      | S390X_CAPBIT(S390X_XTS_AES_256),
344                    0ULL},
345         .kmc    = {S390X_CAPBIT(S390X_QUERY)
346                      | S390X_CAPBIT(S390X_AES_128)
347                      | S390X_CAPBIT(S390X_AES_192)
348                      | S390X_CAPBIT(S390X_AES_256),
349                    0ULL},
350         .kmac   = {S390X_CAPBIT(S390X_QUERY)
351                      | S390X_CAPBIT(S390X_AES_128)
352                      | S390X_CAPBIT(S390X_AES_192)
353                      | S390X_CAPBIT(S390X_AES_256),
354                    0ULL},
355         .kmctr  = {S390X_CAPBIT(S390X_QUERY)
356                      | S390X_CAPBIT(S390X_AES_128)
357                      | S390X_CAPBIT(S390X_AES_192)
358                      | S390X_CAPBIT(S390X_AES_256),
359                    0ULL},
360         .kmo    = {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         .kmf    = {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         .prno   = {0ULL, 0ULL},
371         .kma    = {0ULL, 0ULL},
372     };
373
374     /*-
375      * z13 (2015) - z/Architecture POP SA22-7832-10
376      * Implements MSA and MSA1-5.
377      */
378     static const struct OPENSSL_s390xcap_st z13 = {
379         .stfle  = {S390X_CAPBIT(S390X_MSA)
380                      | S390X_CAPBIT(S390X_STCKF)
381                      | S390X_CAPBIT(S390X_MSA5),
382                    S390X_CAPBIT(S390X_MSA3)
383                      | S390X_CAPBIT(S390X_MSA4),
384                    S390X_CAPBIT(S390X_VX),
385                    0ULL},
386         .kimd   = {S390X_CAPBIT(S390X_QUERY)
387                      | S390X_CAPBIT(S390X_SHA_1)
388                      | S390X_CAPBIT(S390X_SHA_256)
389                      | S390X_CAPBIT(S390X_SHA_512),
390                    S390X_CAPBIT(S390X_GHASH)},
391         .klmd   = {S390X_CAPBIT(S390X_QUERY)
392                      | S390X_CAPBIT(S390X_SHA_1)
393                      | S390X_CAPBIT(S390X_SHA_256)
394                      | S390X_CAPBIT(S390X_SHA_512),
395                    0ULL},
396         .km     = {S390X_CAPBIT(S390X_QUERY)
397                      | S390X_CAPBIT(S390X_AES_128)
398                      | S390X_CAPBIT(S390X_AES_192)
399                      | S390X_CAPBIT(S390X_AES_256)
400                      | S390X_CAPBIT(S390X_XTS_AES_128)
401                      | S390X_CAPBIT(S390X_XTS_AES_256),
402                    0ULL},
403         .kmc    = {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         .kmac   = {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         .kmctr  = {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         .kmo    = {S390X_CAPBIT(S390X_QUERY)
419                      | S390X_CAPBIT(S390X_AES_128)
420                      | S390X_CAPBIT(S390X_AES_192)
421                      | S390X_CAPBIT(S390X_AES_256),
422                    0ULL},
423         .kmf    = {S390X_CAPBIT(S390X_QUERY)
424                      | S390X_CAPBIT(S390X_AES_128)
425                      | S390X_CAPBIT(S390X_AES_192)
426                      | S390X_CAPBIT(S390X_AES_256),
427                    0ULL},
428         .prno   = {S390X_CAPBIT(S390X_QUERY)
429                    | S390X_CAPBIT(S390X_SHA_512_DRNG),
430                    0ULL},
431         .kma    = {0ULL, 0ULL},
432     };
433
434     /*-
435      * z14 (2017) - z/Architecture POP SA22-7832-11
436      * Implements MSA and MSA1-8.
437      */
438     static const struct OPENSSL_s390xcap_st z14 = {
439         .stfle  = {S390X_CAPBIT(S390X_MSA)
440                      | S390X_CAPBIT(S390X_STCKF)
441                      | S390X_CAPBIT(S390X_MSA5),
442                    S390X_CAPBIT(S390X_MSA3)
443                      | S390X_CAPBIT(S390X_MSA4),
444                    S390X_CAPBIT(S390X_VX)
445                      | S390X_CAPBIT(S390X_VXD)
446                      | S390X_CAPBIT(S390X_VXE)
447                      | S390X_CAPBIT(S390X_MSA8),
448                    0ULL},
449         .kimd   = {S390X_CAPBIT(S390X_QUERY)
450                      | S390X_CAPBIT(S390X_SHA_1)
451                      | S390X_CAPBIT(S390X_SHA_256)
452                      | S390X_CAPBIT(S390X_SHA_512)
453                      | S390X_CAPBIT(S390X_SHA3_224)
454                      | S390X_CAPBIT(S390X_SHA3_256)
455                      | S390X_CAPBIT(S390X_SHA3_384)
456                      | S390X_CAPBIT(S390X_SHA3_512)
457                      | S390X_CAPBIT(S390X_SHAKE_128)
458                      | S390X_CAPBIT(S390X_SHAKE_256),
459                    S390X_CAPBIT(S390X_GHASH)},
460         .klmd   = {S390X_CAPBIT(S390X_QUERY)
461                      | S390X_CAPBIT(S390X_SHA_1)
462                      | S390X_CAPBIT(S390X_SHA_256)
463                      | S390X_CAPBIT(S390X_SHA_512)
464                      | S390X_CAPBIT(S390X_SHA3_224)
465                      | S390X_CAPBIT(S390X_SHA3_256)
466                      | S390X_CAPBIT(S390X_SHA3_384)
467                      | S390X_CAPBIT(S390X_SHA3_512)
468                      | S390X_CAPBIT(S390X_SHAKE_128)
469                      | S390X_CAPBIT(S390X_SHAKE_256),
470                    0ULL},
471         .km     = {S390X_CAPBIT(S390X_QUERY)
472                      | S390X_CAPBIT(S390X_AES_128)
473                      | S390X_CAPBIT(S390X_AES_192)
474                      | S390X_CAPBIT(S390X_AES_256)
475                      | S390X_CAPBIT(S390X_XTS_AES_128)
476                      | S390X_CAPBIT(S390X_XTS_AES_256),
477                    0ULL},
478         .kmc    = {S390X_CAPBIT(S390X_QUERY)
479                      | S390X_CAPBIT(S390X_AES_128)
480                      | S390X_CAPBIT(S390X_AES_192)
481                      | S390X_CAPBIT(S390X_AES_256),
482                    0ULL},
483         .kmac   = {S390X_CAPBIT(S390X_QUERY)
484                      | S390X_CAPBIT(S390X_AES_128)
485                      | S390X_CAPBIT(S390X_AES_192)
486                      | S390X_CAPBIT(S390X_AES_256),
487                    0ULL},
488         .kmctr  = {S390X_CAPBIT(S390X_QUERY)
489                      | S390X_CAPBIT(S390X_AES_128)
490                      | S390X_CAPBIT(S390X_AES_192)
491                      | S390X_CAPBIT(S390X_AES_256),
492                    0ULL},
493         .kmo    = {S390X_CAPBIT(S390X_QUERY)
494                      | S390X_CAPBIT(S390X_AES_128)
495                      | S390X_CAPBIT(S390X_AES_192)
496                      | S390X_CAPBIT(S390X_AES_256),
497                    0ULL},
498         .kmf    = {S390X_CAPBIT(S390X_QUERY)
499                      | S390X_CAPBIT(S390X_AES_128)
500                      | S390X_CAPBIT(S390X_AES_192)
501                      | S390X_CAPBIT(S390X_AES_256),
502                    0ULL},
503         .prno   = {S390X_CAPBIT(S390X_QUERY)
504                    | S390X_CAPBIT(S390X_SHA_512_DRNG),
505                    S390X_CAPBIT(S390X_TRNG)},
506         .kma    = {S390X_CAPBIT(S390X_QUERY)
507                      | S390X_CAPBIT(S390X_AES_128)
508                      | S390X_CAPBIT(S390X_AES_192)
509                      | S390X_CAPBIT(S390X_AES_256),
510                    0ULL},
511     };
512
513     char *tok_begin, *tok_end, *buff, tok[S390X_STFLE_MAX][LEN + 1];
514     int rc, off, i, n;
515
516     buff = malloc(strlen(env) + 1);
517     if (buff == NULL)
518         return 0;
519
520     rc = 0;
521     memset(cap, ~0, sizeof(*cap));
522     strcpy(buff, env);
523
524     tok_begin = buff + strspn(buff, ";");
525     strtok(tok_begin, ";");
526     tok_end = strtok(NULL, ";");
527
528     while (tok_begin != NULL) {
529         /* stfle token */
530         if ((n = sscanf(tok_begin,
531                         " stfle : %" STR(LEN) "[^:] : "
532                         "%" STR(LEN) "[^:] : %" STR(LEN) "s ",
533                         tok[0], tok[1], tok[2]))) {
534             for (i = 0; i < n; i++) {
535                 off = (tok[i][0] == '~') ? 1 : 0;
536                 if (sscanf(tok[i] + off, "%llx", &cap->stfle[i]) != 1)
537                     goto ret;
538                 if (off)
539                     cap->stfle[i] = ~cap->stfle[i];
540             }
541         }
542
543         /* query function tokens */
544         else if TOK_FUNC(kimd)
545         else if TOK_FUNC(klmd)
546         else if TOK_FUNC(km)
547         else if TOK_FUNC(kmc)
548         else if TOK_FUNC(kmac)
549         else if TOK_FUNC(kmctr)
550         else if TOK_FUNC(kmo)
551         else if TOK_FUNC(kmf)
552         else if TOK_FUNC(prno)
553         else if TOK_FUNC(kma)
554
555         /* CPU model tokens */
556         else if TOK_CPU(z900)
557         else if TOK_CPU(z990)
558         else if TOK_CPU(z9)
559         else if TOK_CPU(z10)
560         else if TOK_CPU(z196)
561         else if TOK_CPU(zEC12)
562         else if TOK_CPU(z13)
563         else if TOK_CPU(z14)
564
565         /* whitespace(ignored) or invalid tokens */
566         else {
567             while (*tok_begin != '\0') {
568                 if (!ossl_isspace(*tok_begin))
569                     goto ret;
570                 tok_begin++;
571             }
572         }
573
574         tok_begin = tok_end;
575         tok_end = strtok(NULL, ";");
576     }
577
578     rc = 1;
579 ret:
580     free(buff);
581     return rc;
582 }