s390xcap.c 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833
  1. /*
  2. * Copyright 2010-2022 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <setjmp.h>
  13. #include <signal.h>
  14. #include "internal/cryptlib.h"
  15. #include "crypto/ctype.h"
  16. #include "s390x_arch.h"
  17. #if defined(OPENSSL_SYS_LINUX) && !defined(FIPS_MODULE)
  18. # include <sys/types.h>
  19. # include <sys/stat.h>
  20. # include <fcntl.h>
  21. # include <asm/zcrypt.h>
  22. # include <sys/ioctl.h>
  23. # include <unistd.h>
  24. #endif
  25. #if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
  26. # if __GLIBC_PREREQ(2, 16)
  27. # include <sys/auxv.h>
  28. # if defined(HWCAP_S390_STFLE) && defined(HWCAP_S390_VX)
  29. # define OSSL_IMPLEMENT_GETAUXVAL
  30. # endif
  31. # endif
  32. #endif
  33. #define LEN 128
  34. #define STR_(S) #S
  35. #define STR(S) STR_(S)
  36. #define TOK_FUNC(NAME) \
  37. (sscanf(tok_begin, \
  38. " " STR(NAME) " : %" STR(LEN) "[^:] : " \
  39. "%" STR(LEN) "s %" STR(LEN) "s ", \
  40. tok[0], tok[1], tok[2]) == 2) { \
  41. \
  42. off = (tok[0][0] == '~') ? 1 : 0; \
  43. if (sscanf(tok[0] + off, "%llx", &cap->NAME[0]) != 1) \
  44. goto ret; \
  45. if (off) \
  46. cap->NAME[0] = ~cap->NAME[0]; \
  47. \
  48. off = (tok[1][0] == '~') ? 1 : 0; \
  49. if (sscanf(tok[1] + off, "%llx", &cap->NAME[1]) != 1) \
  50. goto ret; \
  51. if (off) \
  52. cap->NAME[1] = ~cap->NAME[1]; \
  53. }
  54. #define TOK_CPU(NAME) \
  55. (sscanf(tok_begin, \
  56. " %" STR(LEN) "s %" STR(LEN) "s ", \
  57. tok[0], tok[1]) == 1 \
  58. && !strcmp(tok[0], #NAME)) { \
  59. memcpy(cap, &NAME, sizeof(*cap)); \
  60. }
  61. #ifndef OSSL_IMPLEMENT_GETAUXVAL
  62. static sigjmp_buf ill_jmp;
  63. static void ill_handler(int sig)
  64. {
  65. siglongjmp(ill_jmp, sig);
  66. }
  67. void OPENSSL_vx_probe(void);
  68. #endif
  69. static const char *env;
  70. static int parse_env(struct OPENSSL_s390xcap_st *cap, int *cex);
  71. void OPENSSL_s390x_facilities(void);
  72. void OPENSSL_s390x_functions(void);
  73. struct OPENSSL_s390xcap_st OPENSSL_s390xcap_P;
  74. #ifdef S390X_MOD_EXP
  75. static int probe_cex(void);
  76. int OPENSSL_s390xcex;
  77. #if defined(__GNUC__)
  78. __attribute__ ((visibility("hidden")))
  79. #endif
  80. void OPENSSL_s390x_cleanup(void);
  81. #if defined(__GNUC__)
  82. __attribute__ ((visibility("hidden")))
  83. #endif
  84. void OPENSSL_s390x_cleanup(void)
  85. {
  86. if (OPENSSL_s390xcex != -1) {
  87. (void)close(OPENSSL_s390xcex);
  88. OPENSSL_s390xcex = -1;
  89. }
  90. }
  91. #endif
  92. #if defined(__GNUC__) && defined(__linux)
  93. __attribute__ ((visibility("hidden")))
  94. #endif
  95. void OPENSSL_cpuid_setup(void)
  96. {
  97. struct OPENSSL_s390xcap_st cap;
  98. int cex = 1;
  99. if (OPENSSL_s390xcap_P.stfle[0])
  100. return;
  101. /* set a bit that will not be tested later */
  102. OPENSSL_s390xcap_P.stfle[0] |= S390X_CAPBIT(0);
  103. #if defined(OSSL_IMPLEMENT_GETAUXVAL)
  104. {
  105. const unsigned long hwcap = getauxval(AT_HWCAP);
  106. /* protection against missing store-facility-list-extended */
  107. if (hwcap & HWCAP_S390_STFLE)
  108. OPENSSL_s390x_facilities();
  109. /* protection against disabled vector facility */
  110. if (!(hwcap & HWCAP_S390_VX)) {
  111. OPENSSL_s390xcap_P.stfle[2] &= ~(S390X_CAPBIT(S390X_VX)
  112. | S390X_CAPBIT(S390X_VXD)
  113. | S390X_CAPBIT(S390X_VXE));
  114. }
  115. }
  116. #else
  117. {
  118. sigset_t oset;
  119. struct sigaction ill_act, oact_ill, oact_fpe;
  120. memset(&ill_act, 0, sizeof(ill_act));
  121. ill_act.sa_handler = ill_handler;
  122. sigfillset(&ill_act.sa_mask);
  123. sigdelset(&ill_act.sa_mask, SIGILL);
  124. sigdelset(&ill_act.sa_mask, SIGFPE);
  125. sigdelset(&ill_act.sa_mask, SIGTRAP);
  126. sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
  127. sigaction(SIGILL, &ill_act, &oact_ill);
  128. sigaction(SIGFPE, &ill_act, &oact_fpe);
  129. /* protection against missing store-facility-list-extended */
  130. if (sigsetjmp(ill_jmp, 1) == 0)
  131. OPENSSL_s390x_facilities();
  132. /* protection against disabled vector facility */
  133. if ((OPENSSL_s390xcap_P.stfle[2] & S390X_CAPBIT(S390X_VX))
  134. && (sigsetjmp(ill_jmp, 1) == 0)) {
  135. OPENSSL_vx_probe();
  136. } else {
  137. OPENSSL_s390xcap_P.stfle[2] &= ~(S390X_CAPBIT(S390X_VX)
  138. | S390X_CAPBIT(S390X_VXD)
  139. | S390X_CAPBIT(S390X_VXE));
  140. }
  141. sigaction(SIGFPE, &oact_fpe, NULL);
  142. sigaction(SIGILL, &oact_ill, NULL);
  143. sigprocmask(SIG_SETMASK, &oset, NULL);
  144. }
  145. #endif
  146. env = getenv("OPENSSL_s390xcap");
  147. if (env != NULL) {
  148. if (!parse_env(&cap, &cex))
  149. env = NULL;
  150. }
  151. if (env != NULL) {
  152. OPENSSL_s390xcap_P.stfle[0] &= cap.stfle[0];
  153. OPENSSL_s390xcap_P.stfle[1] &= cap.stfle[1];
  154. OPENSSL_s390xcap_P.stfle[2] &= cap.stfle[2];
  155. }
  156. OPENSSL_s390x_functions(); /* check OPENSSL_s390xcap_P.stfle */
  157. if (env != NULL) {
  158. OPENSSL_s390xcap_P.kimd[0] &= cap.kimd[0];
  159. OPENSSL_s390xcap_P.kimd[1] &= cap.kimd[1];
  160. OPENSSL_s390xcap_P.klmd[0] &= cap.klmd[0];
  161. OPENSSL_s390xcap_P.klmd[1] &= cap.klmd[1];
  162. OPENSSL_s390xcap_P.km[0] &= cap.km[0];
  163. OPENSSL_s390xcap_P.km[1] &= cap.km[1];
  164. OPENSSL_s390xcap_P.kmc[0] &= cap.kmc[0];
  165. OPENSSL_s390xcap_P.kmc[1] &= cap.kmc[1];
  166. OPENSSL_s390xcap_P.kmac[0] &= cap.kmac[0];
  167. OPENSSL_s390xcap_P.kmac[1] &= cap.kmac[1];
  168. OPENSSL_s390xcap_P.kmctr[0] &= cap.kmctr[0];
  169. OPENSSL_s390xcap_P.kmctr[1] &= cap.kmctr[1];
  170. OPENSSL_s390xcap_P.kmo[0] &= cap.kmo[0];
  171. OPENSSL_s390xcap_P.kmo[1] &= cap.kmo[1];
  172. OPENSSL_s390xcap_P.kmf[0] &= cap.kmf[0];
  173. OPENSSL_s390xcap_P.kmf[1] &= cap.kmf[1];
  174. OPENSSL_s390xcap_P.prno[0] &= cap.prno[0];
  175. OPENSSL_s390xcap_P.prno[1] &= cap.prno[1];
  176. OPENSSL_s390xcap_P.kma[0] &= cap.kma[0];
  177. OPENSSL_s390xcap_P.kma[1] &= cap.kma[1];
  178. OPENSSL_s390xcap_P.pcc[0] &= cap.pcc[0];
  179. OPENSSL_s390xcap_P.pcc[1] &= cap.pcc[1];
  180. OPENSSL_s390xcap_P.kdsa[0] &= cap.kdsa[0];
  181. OPENSSL_s390xcap_P.kdsa[1] &= cap.kdsa[1];
  182. }
  183. #ifdef S390X_MOD_EXP
  184. if (cex == 0) {
  185. OPENSSL_s390xcex = -1;
  186. } else {
  187. OPENSSL_s390xcex = open("/dev/z90crypt", O_RDWR | O_CLOEXEC);
  188. if (probe_cex() == 1)
  189. OPENSSL_atexit(OPENSSL_s390x_cleanup);
  190. }
  191. #endif
  192. }
  193. #ifdef S390X_MOD_EXP
  194. static int probe_cex(void)
  195. {
  196. struct ica_rsa_modexpo me;
  197. const unsigned char inval[16] = {
  198. 0,0,0,0,0,0,0,0,
  199. 0,0,0,0,0,0,0,2
  200. };
  201. const unsigned char modulus[16] = {
  202. 0,0,0,0,0,0,0,0,
  203. 0,0,0,0,0,0,0,3
  204. };
  205. unsigned char res[16];
  206. int olderrno;
  207. int rc = 1;
  208. me.inputdata = (unsigned char *)inval;
  209. me.inputdatalength = sizeof(inval);
  210. me.outputdata = (unsigned char *)res;
  211. me.outputdatalength = sizeof(res);
  212. me.b_key = (unsigned char *)inval;
  213. me.n_modulus = (unsigned char *)modulus;
  214. olderrno = errno;
  215. if (ioctl(OPENSSL_s390xcex, ICARSAMODEXPO, &me) == -1) {
  216. (void)close(OPENSSL_s390xcex);
  217. OPENSSL_s390xcex = -1;
  218. rc = 0;
  219. }
  220. errno = olderrno;
  221. return rc;
  222. }
  223. #endif
  224. static int parse_env(struct OPENSSL_s390xcap_st *cap, int *cex)
  225. {
  226. /*-
  227. * CPU model data
  228. * (only the STFLE- and QUERY-bits relevant to libcrypto are set)
  229. */
  230. /*-
  231. * z900 (2000) - z/Architecture POP SA22-7832-00
  232. * Facility detection would fail on real hw (no STFLE).
  233. */
  234. static const struct OPENSSL_s390xcap_st z900 = {
  235. /*.stfle = */{0ULL, 0ULL, 0ULL, 0ULL},
  236. /*.kimd = */{0ULL, 0ULL},
  237. /*.klmd = */{0ULL, 0ULL},
  238. /*.km = */{0ULL, 0ULL},
  239. /*.kmc = */{0ULL, 0ULL},
  240. /*.kmac = */{0ULL, 0ULL},
  241. /*.kmctr = */{0ULL, 0ULL},
  242. /*.kmo = */{0ULL, 0ULL},
  243. /*.kmf = */{0ULL, 0ULL},
  244. /*.prno = */{0ULL, 0ULL},
  245. /*.kma = */{0ULL, 0ULL},
  246. /*.pcc = */{0ULL, 0ULL},
  247. /*.kdsa = */{0ULL, 0ULL},
  248. };
  249. /*-
  250. * z990 (2003) - z/Architecture POP SA22-7832-02
  251. * Implements MSA. Facility detection would fail on real hw (no STFLE).
  252. */
  253. static const struct OPENSSL_s390xcap_st z990 = {
  254. /*.stfle = */{S390X_CAPBIT(S390X_MSA),
  255. 0ULL, 0ULL, 0ULL},
  256. /*.kimd = */{S390X_CAPBIT(S390X_QUERY)
  257. | S390X_CAPBIT(S390X_SHA_1),
  258. 0ULL},
  259. /*.klmd = */{S390X_CAPBIT(S390X_QUERY)
  260. | S390X_CAPBIT(S390X_SHA_1),
  261. 0ULL},
  262. /*.km = */{S390X_CAPBIT(S390X_QUERY),
  263. 0ULL},
  264. /*.kmc = */{S390X_CAPBIT(S390X_QUERY),
  265. 0ULL},
  266. /*.kmac = */{S390X_CAPBIT(S390X_QUERY),
  267. 0ULL},
  268. /*.kmctr = */{0ULL, 0ULL},
  269. /*.kmo = */{0ULL, 0ULL},
  270. /*.kmf = */{0ULL, 0ULL},
  271. /*.prno = */{0ULL, 0ULL},
  272. /*.kma = */{0ULL, 0ULL},
  273. /*.pcc = */{0ULL, 0ULL},
  274. /*.kdsa = */{0ULL, 0ULL},
  275. };
  276. /*-
  277. * z9 (2005) - z/Architecture POP SA22-7832-04
  278. * Implements MSA and MSA1.
  279. */
  280. static const struct OPENSSL_s390xcap_st z9 = {
  281. /*.stfle = */{S390X_CAPBIT(S390X_MSA)
  282. | S390X_CAPBIT(S390X_STCKF),
  283. 0ULL, 0ULL, 0ULL},
  284. /*.kimd = */{S390X_CAPBIT(S390X_QUERY)
  285. | S390X_CAPBIT(S390X_SHA_1)
  286. | S390X_CAPBIT(S390X_SHA_256),
  287. 0ULL},
  288. /*.klmd = */{S390X_CAPBIT(S390X_QUERY)
  289. | S390X_CAPBIT(S390X_SHA_1)
  290. | S390X_CAPBIT(S390X_SHA_256),
  291. 0ULL},
  292. /*.km = */{S390X_CAPBIT(S390X_QUERY)
  293. | S390X_CAPBIT(S390X_AES_128),
  294. 0ULL},
  295. /*.kmc = */{S390X_CAPBIT(S390X_QUERY)
  296. | S390X_CAPBIT(S390X_AES_128),
  297. 0ULL},
  298. /*.kmac = */{S390X_CAPBIT(S390X_QUERY),
  299. 0ULL},
  300. /*.kmctr = */{0ULL, 0ULL},
  301. /*.kmo = */{0ULL, 0ULL},
  302. /*.kmf = */{0ULL, 0ULL},
  303. /*.prno = */{0ULL, 0ULL},
  304. /*.kma = */{0ULL, 0ULL},
  305. /*.pcc = */{0ULL, 0ULL},
  306. /*.kdsa = */{0ULL, 0ULL},
  307. };
  308. /*-
  309. * z10 (2008) - z/Architecture POP SA22-7832-06
  310. * Implements MSA and MSA1-2.
  311. */
  312. static const struct OPENSSL_s390xcap_st z10 = {
  313. /*.stfle = */{S390X_CAPBIT(S390X_MSA)
  314. | S390X_CAPBIT(S390X_STCKF),
  315. 0ULL, 0ULL, 0ULL},
  316. /*.kimd = */{S390X_CAPBIT(S390X_QUERY)
  317. | S390X_CAPBIT(S390X_SHA_1)
  318. | S390X_CAPBIT(S390X_SHA_256)
  319. | S390X_CAPBIT(S390X_SHA_512),
  320. 0ULL},
  321. /*.klmd = */{S390X_CAPBIT(S390X_QUERY)
  322. | S390X_CAPBIT(S390X_SHA_1)
  323. | S390X_CAPBIT(S390X_SHA_256)
  324. | S390X_CAPBIT(S390X_SHA_512),
  325. 0ULL},
  326. /*.km = */{S390X_CAPBIT(S390X_QUERY)
  327. | S390X_CAPBIT(S390X_AES_128)
  328. | S390X_CAPBIT(S390X_AES_192)
  329. | S390X_CAPBIT(S390X_AES_256),
  330. 0ULL},
  331. /*.kmc = */{S390X_CAPBIT(S390X_QUERY)
  332. | S390X_CAPBIT(S390X_AES_128)
  333. | S390X_CAPBIT(S390X_AES_192)
  334. | S390X_CAPBIT(S390X_AES_256),
  335. 0ULL},
  336. /*.kmac = */{S390X_CAPBIT(S390X_QUERY),
  337. 0ULL},
  338. /*.kmctr = */{0ULL, 0ULL},
  339. /*.kmo = */{0ULL, 0ULL},
  340. /*.kmf = */{0ULL, 0ULL},
  341. /*.prno = */{0ULL, 0ULL},
  342. /*.kma = */{0ULL, 0ULL},
  343. /*.pcc = */{0ULL, 0ULL},
  344. /*.kdsa = */{0ULL, 0ULL},
  345. };
  346. /*-
  347. * z196 (2010) - z/Architecture POP SA22-7832-08
  348. * Implements MSA and MSA1-4.
  349. */
  350. static const struct OPENSSL_s390xcap_st z196 = {
  351. /*.stfle = */{S390X_CAPBIT(S390X_MSA)
  352. | S390X_CAPBIT(S390X_STCKF),
  353. S390X_CAPBIT(S390X_MSA3)
  354. | S390X_CAPBIT(S390X_MSA4),
  355. 0ULL, 0ULL},
  356. /*.kimd = */{S390X_CAPBIT(S390X_QUERY)
  357. | S390X_CAPBIT(S390X_SHA_1)
  358. | S390X_CAPBIT(S390X_SHA_256)
  359. | S390X_CAPBIT(S390X_SHA_512),
  360. S390X_CAPBIT(S390X_GHASH)},
  361. /*.klmd = */{S390X_CAPBIT(S390X_QUERY)
  362. | S390X_CAPBIT(S390X_SHA_1)
  363. | S390X_CAPBIT(S390X_SHA_256)
  364. | S390X_CAPBIT(S390X_SHA_512),
  365. 0ULL},
  366. /*.km = */{S390X_CAPBIT(S390X_QUERY)
  367. | S390X_CAPBIT(S390X_AES_128)
  368. | S390X_CAPBIT(S390X_AES_192)
  369. | S390X_CAPBIT(S390X_AES_256)
  370. | S390X_CAPBIT(S390X_XTS_AES_128)
  371. | S390X_CAPBIT(S390X_XTS_AES_256),
  372. 0ULL},
  373. /*.kmc = */{S390X_CAPBIT(S390X_QUERY)
  374. | S390X_CAPBIT(S390X_AES_128)
  375. | S390X_CAPBIT(S390X_AES_192)
  376. | S390X_CAPBIT(S390X_AES_256),
  377. 0ULL},
  378. /*.kmac = */{S390X_CAPBIT(S390X_QUERY)
  379. | S390X_CAPBIT(S390X_AES_128)
  380. | S390X_CAPBIT(S390X_AES_192)
  381. | S390X_CAPBIT(S390X_AES_256),
  382. 0ULL},
  383. /*.kmctr = */{S390X_CAPBIT(S390X_QUERY)
  384. | S390X_CAPBIT(S390X_AES_128)
  385. | S390X_CAPBIT(S390X_AES_192)
  386. | S390X_CAPBIT(S390X_AES_256),
  387. 0ULL},
  388. /*.kmo = */{S390X_CAPBIT(S390X_QUERY)
  389. | S390X_CAPBIT(S390X_AES_128)
  390. | S390X_CAPBIT(S390X_AES_192)
  391. | S390X_CAPBIT(S390X_AES_256),
  392. 0ULL},
  393. /*.kmf = */{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. /*.prno = */{0ULL, 0ULL},
  399. /*.kma = */{0ULL, 0ULL},
  400. /*.pcc = */{S390X_CAPBIT(S390X_QUERY),
  401. 0ULL},
  402. /*.kdsa = */{0ULL, 0ULL},
  403. };
  404. /*-
  405. * zEC12 (2012) - z/Architecture POP SA22-7832-09
  406. * Implements MSA and MSA1-4.
  407. */
  408. static const struct OPENSSL_s390xcap_st zEC12 = {
  409. /*.stfle = */{S390X_CAPBIT(S390X_MSA)
  410. | S390X_CAPBIT(S390X_STCKF),
  411. S390X_CAPBIT(S390X_MSA3)
  412. | S390X_CAPBIT(S390X_MSA4),
  413. 0ULL, 0ULL},
  414. /*.kimd = */{S390X_CAPBIT(S390X_QUERY)
  415. | S390X_CAPBIT(S390X_SHA_1)
  416. | S390X_CAPBIT(S390X_SHA_256)
  417. | S390X_CAPBIT(S390X_SHA_512),
  418. S390X_CAPBIT(S390X_GHASH)},
  419. /*.klmd = */{S390X_CAPBIT(S390X_QUERY)
  420. | S390X_CAPBIT(S390X_SHA_1)
  421. | S390X_CAPBIT(S390X_SHA_256)
  422. | S390X_CAPBIT(S390X_SHA_512),
  423. 0ULL},
  424. /*.km = */{S390X_CAPBIT(S390X_QUERY)
  425. | S390X_CAPBIT(S390X_AES_128)
  426. | S390X_CAPBIT(S390X_AES_192)
  427. | S390X_CAPBIT(S390X_AES_256)
  428. | S390X_CAPBIT(S390X_XTS_AES_128)
  429. | S390X_CAPBIT(S390X_XTS_AES_256),
  430. 0ULL},
  431. /*.kmc = */{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. /*.kmac = */{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. /*.kmctr = */{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. /*.kmo = */{S390X_CAPBIT(S390X_QUERY)
  447. | S390X_CAPBIT(S390X_AES_128)
  448. | S390X_CAPBIT(S390X_AES_192)
  449. | S390X_CAPBIT(S390X_AES_256),
  450. 0ULL},
  451. /*.kmf = */{S390X_CAPBIT(S390X_QUERY)
  452. | S390X_CAPBIT(S390X_AES_128)
  453. | S390X_CAPBIT(S390X_AES_192)
  454. | S390X_CAPBIT(S390X_AES_256),
  455. 0ULL},
  456. /*.prno = */{0ULL, 0ULL},
  457. /*.kma = */{0ULL, 0ULL},
  458. /*.pcc = */{S390X_CAPBIT(S390X_QUERY),
  459. 0ULL},
  460. /*.kdsa = */{0ULL, 0ULL},
  461. };
  462. /*-
  463. * z13 (2015) - z/Architecture POP SA22-7832-10
  464. * Implements MSA and MSA1-5.
  465. */
  466. static const struct OPENSSL_s390xcap_st z13 = {
  467. /*.stfle = */{S390X_CAPBIT(S390X_MSA)
  468. | S390X_CAPBIT(S390X_STCKF)
  469. | S390X_CAPBIT(S390X_MSA5),
  470. S390X_CAPBIT(S390X_MSA3)
  471. | S390X_CAPBIT(S390X_MSA4),
  472. S390X_CAPBIT(S390X_VX),
  473. 0ULL},
  474. /*.kimd = */{S390X_CAPBIT(S390X_QUERY)
  475. | S390X_CAPBIT(S390X_SHA_1)
  476. | S390X_CAPBIT(S390X_SHA_256)
  477. | S390X_CAPBIT(S390X_SHA_512),
  478. S390X_CAPBIT(S390X_GHASH)},
  479. /*.klmd = */{S390X_CAPBIT(S390X_QUERY)
  480. | S390X_CAPBIT(S390X_SHA_1)
  481. | S390X_CAPBIT(S390X_SHA_256)
  482. | S390X_CAPBIT(S390X_SHA_512),
  483. 0ULL},
  484. /*.km = */{S390X_CAPBIT(S390X_QUERY)
  485. | S390X_CAPBIT(S390X_AES_128)
  486. | S390X_CAPBIT(S390X_AES_192)
  487. | S390X_CAPBIT(S390X_AES_256)
  488. | S390X_CAPBIT(S390X_XTS_AES_128)
  489. | S390X_CAPBIT(S390X_XTS_AES_256),
  490. 0ULL},
  491. /*.kmc = */{S390X_CAPBIT(S390X_QUERY)
  492. | S390X_CAPBIT(S390X_AES_128)
  493. | S390X_CAPBIT(S390X_AES_192)
  494. | S390X_CAPBIT(S390X_AES_256),
  495. 0ULL},
  496. /*.kmac = */{S390X_CAPBIT(S390X_QUERY)
  497. | S390X_CAPBIT(S390X_AES_128)
  498. | S390X_CAPBIT(S390X_AES_192)
  499. | S390X_CAPBIT(S390X_AES_256),
  500. 0ULL},
  501. /*.kmctr = */{S390X_CAPBIT(S390X_QUERY)
  502. | S390X_CAPBIT(S390X_AES_128)
  503. | S390X_CAPBIT(S390X_AES_192)
  504. | S390X_CAPBIT(S390X_AES_256),
  505. 0ULL},
  506. /*.kmo = */{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. /*.kmf = */{S390X_CAPBIT(S390X_QUERY)
  512. | S390X_CAPBIT(S390X_AES_128)
  513. | S390X_CAPBIT(S390X_AES_192)
  514. | S390X_CAPBIT(S390X_AES_256),
  515. 0ULL},
  516. /*.prno = */{S390X_CAPBIT(S390X_QUERY)
  517. | S390X_CAPBIT(S390X_SHA_512_DRNG),
  518. 0ULL},
  519. /*.kma = */{0ULL, 0ULL},
  520. /*.pcc = */{S390X_CAPBIT(S390X_QUERY),
  521. 0ULL},
  522. /*.kdsa = */{0ULL, 0ULL},
  523. };
  524. /*-
  525. * z14 (2017) - z/Architecture POP SA22-7832-11
  526. * Implements MSA and MSA1-8.
  527. */
  528. static const struct OPENSSL_s390xcap_st z14 = {
  529. /*.stfle = */{S390X_CAPBIT(S390X_MSA)
  530. | S390X_CAPBIT(S390X_STCKF)
  531. | S390X_CAPBIT(S390X_MSA5),
  532. S390X_CAPBIT(S390X_MSA3)
  533. | S390X_CAPBIT(S390X_MSA4),
  534. S390X_CAPBIT(S390X_VX)
  535. | S390X_CAPBIT(S390X_VXD)
  536. | S390X_CAPBIT(S390X_VXE)
  537. | S390X_CAPBIT(S390X_MSA8),
  538. 0ULL},
  539. /*.kimd = */{S390X_CAPBIT(S390X_QUERY)
  540. | S390X_CAPBIT(S390X_SHA_1)
  541. | S390X_CAPBIT(S390X_SHA_256)
  542. | S390X_CAPBIT(S390X_SHA_512)
  543. | S390X_CAPBIT(S390X_SHA3_224)
  544. | S390X_CAPBIT(S390X_SHA3_256)
  545. | S390X_CAPBIT(S390X_SHA3_384)
  546. | S390X_CAPBIT(S390X_SHA3_512)
  547. | S390X_CAPBIT(S390X_SHAKE_128)
  548. | S390X_CAPBIT(S390X_SHAKE_256),
  549. S390X_CAPBIT(S390X_GHASH)},
  550. /*.klmd = */{S390X_CAPBIT(S390X_QUERY)
  551. | S390X_CAPBIT(S390X_SHA_1)
  552. | S390X_CAPBIT(S390X_SHA_256)
  553. | S390X_CAPBIT(S390X_SHA_512)
  554. | S390X_CAPBIT(S390X_SHA3_224)
  555. | S390X_CAPBIT(S390X_SHA3_256)
  556. | S390X_CAPBIT(S390X_SHA3_384)
  557. | S390X_CAPBIT(S390X_SHA3_512)
  558. | S390X_CAPBIT(S390X_SHAKE_128)
  559. | S390X_CAPBIT(S390X_SHAKE_256),
  560. 0ULL},
  561. /*.km = */{S390X_CAPBIT(S390X_QUERY)
  562. | S390X_CAPBIT(S390X_AES_128)
  563. | S390X_CAPBIT(S390X_AES_192)
  564. | S390X_CAPBIT(S390X_AES_256)
  565. | S390X_CAPBIT(S390X_XTS_AES_128)
  566. | S390X_CAPBIT(S390X_XTS_AES_256),
  567. 0ULL},
  568. /*.kmc = */{S390X_CAPBIT(S390X_QUERY)
  569. | S390X_CAPBIT(S390X_AES_128)
  570. | S390X_CAPBIT(S390X_AES_192)
  571. | S390X_CAPBIT(S390X_AES_256),
  572. 0ULL},
  573. /*.kmac = */{S390X_CAPBIT(S390X_QUERY)
  574. | S390X_CAPBIT(S390X_AES_128)
  575. | S390X_CAPBIT(S390X_AES_192)
  576. | S390X_CAPBIT(S390X_AES_256),
  577. 0ULL},
  578. /*.kmctr = */{S390X_CAPBIT(S390X_QUERY)
  579. | S390X_CAPBIT(S390X_AES_128)
  580. | S390X_CAPBIT(S390X_AES_192)
  581. | S390X_CAPBIT(S390X_AES_256),
  582. 0ULL},
  583. /*.kmo = */{S390X_CAPBIT(S390X_QUERY)
  584. | S390X_CAPBIT(S390X_AES_128)
  585. | S390X_CAPBIT(S390X_AES_192)
  586. | S390X_CAPBIT(S390X_AES_256),
  587. 0ULL},
  588. /*.kmf = */{S390X_CAPBIT(S390X_QUERY)
  589. | S390X_CAPBIT(S390X_AES_128)
  590. | S390X_CAPBIT(S390X_AES_192)
  591. | S390X_CAPBIT(S390X_AES_256),
  592. 0ULL},
  593. /*.prno = */{S390X_CAPBIT(S390X_QUERY)
  594. | S390X_CAPBIT(S390X_SHA_512_DRNG),
  595. S390X_CAPBIT(S390X_TRNG)},
  596. /*.kma = */{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. /*.pcc = */{S390X_CAPBIT(S390X_QUERY),
  602. 0ULL},
  603. /*.kdsa = */{0ULL, 0ULL},
  604. };
  605. /*-
  606. * z15 (2019) - z/Architecture POP SA22-7832-12
  607. * Implements MSA and MSA1-9.
  608. */
  609. static const struct OPENSSL_s390xcap_st z15 = {
  610. /*.stfle = */{S390X_CAPBIT(S390X_MSA)
  611. | S390X_CAPBIT(S390X_STCKF)
  612. | S390X_CAPBIT(S390X_MSA5),
  613. S390X_CAPBIT(S390X_MSA3)
  614. | S390X_CAPBIT(S390X_MSA4),
  615. S390X_CAPBIT(S390X_VX)
  616. | S390X_CAPBIT(S390X_VXD)
  617. | S390X_CAPBIT(S390X_VXE)
  618. | S390X_CAPBIT(S390X_MSA8)
  619. | S390X_CAPBIT(S390X_MSA9),
  620. 0ULL},
  621. /*.kimd = */{S390X_CAPBIT(S390X_QUERY)
  622. | S390X_CAPBIT(S390X_SHA_1)
  623. | S390X_CAPBIT(S390X_SHA_256)
  624. | S390X_CAPBIT(S390X_SHA_512)
  625. | S390X_CAPBIT(S390X_SHA3_224)
  626. | S390X_CAPBIT(S390X_SHA3_256)
  627. | S390X_CAPBIT(S390X_SHA3_384)
  628. | S390X_CAPBIT(S390X_SHA3_512)
  629. | S390X_CAPBIT(S390X_SHAKE_128)
  630. | S390X_CAPBIT(S390X_SHAKE_256),
  631. S390X_CAPBIT(S390X_GHASH)},
  632. /*.klmd = */{S390X_CAPBIT(S390X_QUERY)
  633. | S390X_CAPBIT(S390X_SHA_1)
  634. | S390X_CAPBIT(S390X_SHA_256)
  635. | S390X_CAPBIT(S390X_SHA_512)
  636. | S390X_CAPBIT(S390X_SHA3_224)
  637. | S390X_CAPBIT(S390X_SHA3_256)
  638. | S390X_CAPBIT(S390X_SHA3_384)
  639. | S390X_CAPBIT(S390X_SHA3_512)
  640. | S390X_CAPBIT(S390X_SHAKE_128)
  641. | S390X_CAPBIT(S390X_SHAKE_256),
  642. 0ULL},
  643. /*.km = */{S390X_CAPBIT(S390X_QUERY)
  644. | S390X_CAPBIT(S390X_AES_128)
  645. | S390X_CAPBIT(S390X_AES_192)
  646. | S390X_CAPBIT(S390X_AES_256)
  647. | S390X_CAPBIT(S390X_XTS_AES_128)
  648. | S390X_CAPBIT(S390X_XTS_AES_256),
  649. 0ULL},
  650. /*.kmc = */{S390X_CAPBIT(S390X_QUERY)
  651. | S390X_CAPBIT(S390X_AES_128)
  652. | S390X_CAPBIT(S390X_AES_192)
  653. | S390X_CAPBIT(S390X_AES_256),
  654. 0ULL},
  655. /*.kmac = */{S390X_CAPBIT(S390X_QUERY)
  656. | S390X_CAPBIT(S390X_AES_128)
  657. | S390X_CAPBIT(S390X_AES_192)
  658. | S390X_CAPBIT(S390X_AES_256),
  659. 0ULL},
  660. /*.kmctr = */{S390X_CAPBIT(S390X_QUERY)
  661. | S390X_CAPBIT(S390X_AES_128)
  662. | S390X_CAPBIT(S390X_AES_192)
  663. | S390X_CAPBIT(S390X_AES_256),
  664. 0ULL},
  665. /*.kmo = */{S390X_CAPBIT(S390X_QUERY)
  666. | S390X_CAPBIT(S390X_AES_128)
  667. | S390X_CAPBIT(S390X_AES_192)
  668. | S390X_CAPBIT(S390X_AES_256),
  669. 0ULL},
  670. /*.kmf = */{S390X_CAPBIT(S390X_QUERY)
  671. | S390X_CAPBIT(S390X_AES_128)
  672. | S390X_CAPBIT(S390X_AES_192)
  673. | S390X_CAPBIT(S390X_AES_256),
  674. 0ULL},
  675. /*.prno = */{S390X_CAPBIT(S390X_QUERY)
  676. | S390X_CAPBIT(S390X_SHA_512_DRNG),
  677. S390X_CAPBIT(S390X_TRNG)},
  678. /*.kma = */{S390X_CAPBIT(S390X_QUERY)
  679. | S390X_CAPBIT(S390X_AES_128)
  680. | S390X_CAPBIT(S390X_AES_192)
  681. | S390X_CAPBIT(S390X_AES_256),
  682. 0ULL},
  683. /*.pcc = */{S390X_CAPBIT(S390X_QUERY),
  684. S390X_CAPBIT(S390X_SCALAR_MULTIPLY_P256)
  685. | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_P384)
  686. | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_P521)
  687. | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED25519)
  688. | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_ED448)
  689. | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519)
  690. | S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448)},
  691. /*.kdsa = */{S390X_CAPBIT(S390X_QUERY)
  692. | S390X_CAPBIT(S390X_ECDSA_VERIFY_P256)
  693. | S390X_CAPBIT(S390X_ECDSA_VERIFY_P384)
  694. | S390X_CAPBIT(S390X_ECDSA_VERIFY_P521)
  695. | S390X_CAPBIT(S390X_ECDSA_SIGN_P256)
  696. | S390X_CAPBIT(S390X_ECDSA_SIGN_P384)
  697. | S390X_CAPBIT(S390X_ECDSA_SIGN_P521)
  698. | S390X_CAPBIT(S390X_EDDSA_VERIFY_ED25519)
  699. | S390X_CAPBIT(S390X_EDDSA_VERIFY_ED448)
  700. | S390X_CAPBIT(S390X_EDDSA_SIGN_ED25519)
  701. | S390X_CAPBIT(S390X_EDDSA_SIGN_ED448),
  702. 0ULL},
  703. };
  704. /*-
  705. * z16 (2022) - z/Architecture POP
  706. * Implements MSA and MSA1-9 (same as z15).
  707. */
  708. static const struct OPENSSL_s390xcap_st z16 = z15;
  709. char *tok_begin, *tok_end, *buff, tok[S390X_STFLE_MAX][LEN + 1];
  710. int rc, off, i, n;
  711. buff = malloc(strlen(env) + 1);
  712. if (buff == NULL)
  713. return 0;
  714. rc = 0;
  715. memset(cap, ~0, sizeof(*cap));
  716. strcpy(buff, env);
  717. tok_begin = buff + strspn(buff, ";");
  718. strtok(tok_begin, ";");
  719. tok_end = strtok(NULL, ";");
  720. while (tok_begin != NULL) {
  721. /* stfle token */
  722. if ((n = sscanf(tok_begin,
  723. " stfle : %" STR(LEN) "[^:] : "
  724. "%" STR(LEN) "[^:] : %" STR(LEN) "s ",
  725. tok[0], tok[1], tok[2]))) {
  726. for (i = 0; i < n; i++) {
  727. off = (tok[i][0] == '~') ? 1 : 0;
  728. if (sscanf(tok[i] + off, "%llx", &cap->stfle[i]) != 1)
  729. goto ret;
  730. if (off)
  731. cap->stfle[i] = ~cap->stfle[i];
  732. }
  733. }
  734. /* query function tokens */
  735. else if TOK_FUNC(kimd)
  736. else if TOK_FUNC(klmd)
  737. else if TOK_FUNC(km)
  738. else if TOK_FUNC(kmc)
  739. else if TOK_FUNC(kmac)
  740. else if TOK_FUNC(kmctr)
  741. else if TOK_FUNC(kmo)
  742. else if TOK_FUNC(kmf)
  743. else if TOK_FUNC(prno)
  744. else if TOK_FUNC(kma)
  745. else if TOK_FUNC(pcc)
  746. else if TOK_FUNC(kdsa)
  747. /* CPU model tokens */
  748. else if TOK_CPU(z900)
  749. else if TOK_CPU(z990)
  750. else if TOK_CPU(z9)
  751. else if TOK_CPU(z10)
  752. else if TOK_CPU(z196)
  753. else if TOK_CPU(zEC12)
  754. else if TOK_CPU(z13)
  755. else if TOK_CPU(z14)
  756. else if TOK_CPU(z15)
  757. else if TOK_CPU(z16)
  758. /* nocex to deactivate cex support */
  759. else if (sscanf(tok_begin, " %" STR(LEN) "s %" STR(LEN) "s ",
  760. tok[0], tok[1]) == 1
  761. && !strcmp(tok[0], "nocex")) {
  762. *cex = 0;
  763. }
  764. /* whitespace(ignored) or invalid tokens */
  765. else {
  766. while (*tok_begin != '\0') {
  767. if (!ossl_isspace(*tok_begin))
  768. goto ret;
  769. tok_begin++;
  770. }
  771. }
  772. tok_begin = tok_end;
  773. tok_end = strtok(NULL, ";");
  774. }
  775. rc = 1;
  776. ret:
  777. free(buff);
  778. return rc;
  779. }