pkey_cca.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * pkey cca specific code
  4. *
  5. * Copyright IBM Corp. 2024
  6. */
  7. #define pr_fmt(fmt) "pkey: " fmt
  8. #include <linux/init.h>
  9. #include <linux/module.h>
  10. #include <linux/cpufeature.h>
  11. #include "zcrypt_ccamisc.h"
  12. #include "pkey_base.h"
  13. MODULE_LICENSE("GPL");
  14. MODULE_AUTHOR("IBM Corporation");
  15. MODULE_DESCRIPTION("s390 protected key CCA handler");
  16. #if IS_MODULE(CONFIG_PKEY_CCA)
  17. static struct ap_device_id pkey_cca_card_ids[] = {
  18. { .dev_type = AP_DEVICE_TYPE_CEX4 },
  19. { .dev_type = AP_DEVICE_TYPE_CEX5 },
  20. { .dev_type = AP_DEVICE_TYPE_CEX6 },
  21. { .dev_type = AP_DEVICE_TYPE_CEX7 },
  22. { .dev_type = AP_DEVICE_TYPE_CEX8 },
  23. { /* end of list */ },
  24. };
  25. MODULE_DEVICE_TABLE(ap, pkey_cca_card_ids);
  26. #endif
  27. /*
  28. * Check key blob for known and supported CCA key.
  29. */
  30. static bool is_cca_key(const u8 *key, u32 keylen)
  31. {
  32. struct keytoken_header *hdr = (struct keytoken_header *)key;
  33. if (keylen < sizeof(*hdr))
  34. return false;
  35. switch (hdr->type) {
  36. case TOKTYPE_CCA_INTERNAL:
  37. switch (hdr->version) {
  38. case TOKVER_CCA_AES:
  39. case TOKVER_CCA_VLSC:
  40. return true;
  41. default:
  42. return false;
  43. }
  44. case TOKTYPE_CCA_INTERNAL_PKA:
  45. return true;
  46. default:
  47. return false;
  48. }
  49. }
  50. static bool is_cca_keytype(enum pkey_key_type key_type)
  51. {
  52. switch (key_type) {
  53. case PKEY_TYPE_CCA_DATA:
  54. case PKEY_TYPE_CCA_CIPHER:
  55. case PKEY_TYPE_CCA_ECC:
  56. return true;
  57. default:
  58. return false;
  59. }
  60. }
  61. static int cca_apqns4key(const u8 *key, u32 keylen, u32 flags,
  62. struct pkey_apqn *apqns, size_t *nr_apqns, u32 pflags)
  63. {
  64. struct keytoken_header *hdr = (struct keytoken_header *)key;
  65. u32 _apqns[MAXAPQNSINLIST], _nr_apqns = ARRAY_SIZE(_apqns);
  66. u32 xflags;
  67. int rc;
  68. xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0;
  69. if (!flags)
  70. flags = PKEY_FLAGS_MATCH_CUR_MKVP | PKEY_FLAGS_MATCH_ALT_MKVP;
  71. if (keylen < sizeof(struct keytoken_header))
  72. return -EINVAL;
  73. zcrypt_wait_api_operational();
  74. if (hdr->type == TOKTYPE_CCA_INTERNAL) {
  75. u64 cur_mkvp = 0, old_mkvp = 0;
  76. int minhwtype = ZCRYPT_CEX3C;
  77. if (hdr->version == TOKVER_CCA_AES) {
  78. struct secaeskeytoken *t = (struct secaeskeytoken *)key;
  79. if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
  80. cur_mkvp = t->mkvp;
  81. if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
  82. old_mkvp = t->mkvp;
  83. } else if (hdr->version == TOKVER_CCA_VLSC) {
  84. struct cipherkeytoken *t = (struct cipherkeytoken *)key;
  85. minhwtype = ZCRYPT_CEX6;
  86. if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
  87. cur_mkvp = t->mkvp0;
  88. if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
  89. old_mkvp = t->mkvp0;
  90. } else {
  91. /* unknown CCA internal token type */
  92. return -EINVAL;
  93. }
  94. rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
  95. minhwtype, AES_MK_SET,
  96. cur_mkvp, old_mkvp, xflags);
  97. if (rc)
  98. goto out;
  99. } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) {
  100. struct eccprivkeytoken *t = (struct eccprivkeytoken *)key;
  101. u64 cur_mkvp = 0, old_mkvp = 0;
  102. if (t->secid == 0x20) {
  103. if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
  104. cur_mkvp = t->mkvp;
  105. if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
  106. old_mkvp = t->mkvp;
  107. } else {
  108. /* unknown CCA internal 2 token type */
  109. return -EINVAL;
  110. }
  111. rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
  112. ZCRYPT_CEX7, APKA_MK_SET,
  113. cur_mkvp, old_mkvp, xflags);
  114. if (rc)
  115. goto out;
  116. } else {
  117. PKEY_DBF_ERR("%s unknown/unsupported blob type %d version %d\n",
  118. __func__, hdr->type, hdr->version);
  119. return -EINVAL;
  120. }
  121. if (apqns) {
  122. if (*nr_apqns < _nr_apqns)
  123. rc = -ENOSPC;
  124. else
  125. memcpy(apqns, _apqns, _nr_apqns * sizeof(u32));
  126. }
  127. *nr_apqns = _nr_apqns;
  128. out:
  129. pr_debug("rc=%d\n", rc);
  130. return rc;
  131. }
  132. static int cca_apqns4type(enum pkey_key_type ktype,
  133. u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags,
  134. struct pkey_apqn *apqns, size_t *nr_apqns,
  135. u32 pflags)
  136. {
  137. u32 _apqns[MAXAPQNSINLIST], _nr_apqns = ARRAY_SIZE(_apqns);
  138. u32 xflags;
  139. int rc;
  140. xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0;
  141. zcrypt_wait_api_operational();
  142. if (ktype == PKEY_TYPE_CCA_DATA || ktype == PKEY_TYPE_CCA_CIPHER) {
  143. u64 cur_mkvp = 0, old_mkvp = 0;
  144. int minhwtype = ZCRYPT_CEX3C;
  145. if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
  146. cur_mkvp = *((u64 *)cur_mkvp);
  147. if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
  148. old_mkvp = *((u64 *)alt_mkvp);
  149. if (ktype == PKEY_TYPE_CCA_CIPHER)
  150. minhwtype = ZCRYPT_CEX6;
  151. rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
  152. minhwtype, AES_MK_SET,
  153. cur_mkvp, old_mkvp, xflags);
  154. if (rc)
  155. goto out;
  156. } else if (ktype == PKEY_TYPE_CCA_ECC) {
  157. u64 cur_mkvp = 0, old_mkvp = 0;
  158. if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
  159. cur_mkvp = *((u64 *)cur_mkvp);
  160. if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
  161. old_mkvp = *((u64 *)alt_mkvp);
  162. rc = cca_findcard2(_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
  163. ZCRYPT_CEX7, APKA_MK_SET,
  164. cur_mkvp, old_mkvp, xflags);
  165. if (rc)
  166. goto out;
  167. } else {
  168. PKEY_DBF_ERR("%s unknown/unsupported key type %d",
  169. __func__, (int)ktype);
  170. return -EINVAL;
  171. }
  172. if (apqns) {
  173. if (*nr_apqns < _nr_apqns)
  174. rc = -ENOSPC;
  175. else
  176. memcpy(apqns, _apqns, _nr_apqns * sizeof(u32));
  177. }
  178. *nr_apqns = _nr_apqns;
  179. out:
  180. pr_debug("rc=%d\n", rc);
  181. return rc;
  182. }
  183. static int cca_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
  184. const u8 *key, u32 keylen,
  185. u8 *protkey, u32 *protkeylen, u32 *protkeytype,
  186. u32 pflags)
  187. {
  188. struct keytoken_header *hdr = (struct keytoken_header *)key;
  189. struct pkey_apqn _apqns[MAXAPQNSINLIST];
  190. u32 xflags;
  191. int i, rc;
  192. xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0;
  193. if (keylen < sizeof(*hdr))
  194. return -EINVAL;
  195. if (hdr->type == TOKTYPE_CCA_INTERNAL &&
  196. hdr->version == TOKVER_CCA_AES) {
  197. /* CCA AES data key */
  198. if (keylen < sizeof(struct secaeskeytoken))
  199. return -EINVAL;
  200. if (cca_check_secaeskeytoken(pkey_dbf_info, 3, key, 0))
  201. return -EINVAL;
  202. } else if (hdr->type == TOKTYPE_CCA_INTERNAL &&
  203. hdr->version == TOKVER_CCA_VLSC) {
  204. /* CCA AES cipher key */
  205. if (keylen < hdr->len)
  206. return -EINVAL;
  207. if (cca_check_secaescipherkey(pkey_dbf_info,
  208. 3, key, 0, 1))
  209. return -EINVAL;
  210. } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) {
  211. /* CCA ECC (private) key */
  212. if (keylen < sizeof(struct eccprivkeytoken))
  213. return -EINVAL;
  214. if (cca_check_sececckeytoken(pkey_dbf_info, 3, key, keylen, 1))
  215. return -EINVAL;
  216. } else {
  217. PKEY_DBF_ERR("%s unknown/unsupported blob type %d version %d\n",
  218. __func__, hdr->type, hdr->version);
  219. return -EINVAL;
  220. }
  221. zcrypt_wait_api_operational();
  222. if (!apqns || (nr_apqns == 1 &&
  223. apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
  224. nr_apqns = MAXAPQNSINLIST;
  225. rc = cca_apqns4key(key, keylen, 0, _apqns, &nr_apqns, pflags);
  226. if (rc)
  227. goto out;
  228. apqns = _apqns;
  229. }
  230. for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
  231. if (hdr->type == TOKTYPE_CCA_INTERNAL &&
  232. hdr->version == TOKVER_CCA_AES) {
  233. rc = cca_sec2protkey(apqns[i].card, apqns[i].domain,
  234. key, protkey,
  235. protkeylen, protkeytype, xflags);
  236. } else if (hdr->type == TOKTYPE_CCA_INTERNAL &&
  237. hdr->version == TOKVER_CCA_VLSC) {
  238. rc = cca_cipher2protkey(apqns[i].card, apqns[i].domain,
  239. key, protkey,
  240. protkeylen, protkeytype, xflags);
  241. } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) {
  242. rc = cca_ecc2protkey(apqns[i].card, apqns[i].domain,
  243. key, protkey,
  244. protkeylen, protkeytype, xflags);
  245. } else {
  246. rc = -EINVAL;
  247. break;
  248. }
  249. }
  250. out:
  251. pr_debug("rc=%d\n", rc);
  252. return rc;
  253. }
  254. /*
  255. * Generate CCA secure key.
  256. * As of now only CCA AES Data or Cipher secure keys are
  257. * supported.
  258. * keytype is one of the PKEY_KEYTYPE_* constants,
  259. * subtype may be 0 or PKEY_TYPE_CCA_DATA or PKEY_TYPE_CCA_CIPHER,
  260. * keybitsize is the bit size of the key (may be 0 for
  261. * keytype PKEY_KEYTYPE_AES_*).
  262. */
  263. static int cca_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
  264. u32 keytype, u32 subtype,
  265. u32 keybitsize, u32 flags,
  266. u8 *keybuf, u32 *keybuflen, u32 *_keyinfo, u32 pflags)
  267. {
  268. struct pkey_apqn _apqns[MAXAPQNSINLIST];
  269. int i, len, rc;
  270. u32 xflags;
  271. xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0;
  272. /* check keytype, subtype, keybitsize */
  273. switch (keytype) {
  274. case PKEY_KEYTYPE_AES_128:
  275. case PKEY_KEYTYPE_AES_192:
  276. case PKEY_KEYTYPE_AES_256:
  277. len = pkey_keytype_aes_to_size(keytype);
  278. if (keybitsize && keybitsize != 8 * len) {
  279. PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
  280. __func__, keybitsize);
  281. return -EINVAL;
  282. }
  283. keybitsize = 8 * len;
  284. switch (subtype) {
  285. case PKEY_TYPE_CCA_DATA:
  286. case PKEY_TYPE_CCA_CIPHER:
  287. break;
  288. default:
  289. PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",
  290. __func__, subtype);
  291. return -EINVAL;
  292. }
  293. break;
  294. default:
  295. PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",
  296. __func__, keytype);
  297. return -EINVAL;
  298. }
  299. zcrypt_wait_api_operational();
  300. if (!apqns || (nr_apqns == 1 &&
  301. apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
  302. nr_apqns = MAXAPQNSINLIST;
  303. rc = cca_apqns4type(subtype, NULL, NULL, 0,
  304. _apqns, &nr_apqns, pflags);
  305. if (rc)
  306. goto out;
  307. apqns = _apqns;
  308. }
  309. for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
  310. if (subtype == PKEY_TYPE_CCA_CIPHER) {
  311. rc = cca_gencipherkey(apqns[i].card, apqns[i].domain,
  312. keybitsize, flags,
  313. keybuf, keybuflen, xflags);
  314. } else {
  315. /* PKEY_TYPE_CCA_DATA */
  316. rc = cca_genseckey(apqns[i].card, apqns[i].domain,
  317. keybitsize, keybuf, xflags);
  318. *keybuflen = (rc ? 0 : SECKEYBLOBSIZE);
  319. }
  320. }
  321. out:
  322. pr_debug("rc=%d\n", rc);
  323. return rc;
  324. }
  325. /*
  326. * Generate CCA secure key with given clear key value.
  327. * As of now only CCA AES Data or Cipher secure keys are
  328. * supported.
  329. * keytype is one of the PKEY_KEYTYPE_* constants,
  330. * subtype may be 0 or PKEY_TYPE_CCA_DATA or PKEY_TYPE_CCA_CIPHER,
  331. * keybitsize is the bit size of the key (may be 0 for
  332. * keytype PKEY_KEYTYPE_AES_*).
  333. */
  334. static int cca_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
  335. u32 keytype, u32 subtype,
  336. u32 keybitsize, u32 flags,
  337. const u8 *clrkey, u32 clrkeylen,
  338. u8 *keybuf, u32 *keybuflen, u32 *_keyinfo, u32 pflags)
  339. {
  340. struct pkey_apqn _apqns[MAXAPQNSINLIST];
  341. int i, len, rc;
  342. u32 xflags;
  343. if (pflags & PKEY_XFLAG_NOCLEARKEY) {
  344. PKEY_DBF_ERR("%s clear key but xflag NOCLEARKEY\n", __func__);
  345. return -EINVAL;
  346. }
  347. xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0;
  348. /* check keytype, subtype, clrkeylen, keybitsize */
  349. switch (keytype) {
  350. case PKEY_KEYTYPE_AES_128:
  351. case PKEY_KEYTYPE_AES_192:
  352. case PKEY_KEYTYPE_AES_256:
  353. len = pkey_keytype_aes_to_size(keytype);
  354. if (keybitsize && keybitsize != 8 * len) {
  355. PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
  356. __func__, keybitsize);
  357. return -EINVAL;
  358. }
  359. keybitsize = 8 * len;
  360. if (clrkeylen != len) {
  361. PKEY_DBF_ERR("%s invalid clear key len %d != %d\n",
  362. __func__, clrkeylen, len);
  363. return -EINVAL;
  364. }
  365. switch (subtype) {
  366. case PKEY_TYPE_CCA_DATA:
  367. case PKEY_TYPE_CCA_CIPHER:
  368. break;
  369. default:
  370. PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",
  371. __func__, subtype);
  372. return -EINVAL;
  373. }
  374. break;
  375. default:
  376. PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",
  377. __func__, keytype);
  378. return -EINVAL;
  379. }
  380. zcrypt_wait_api_operational();
  381. if (!apqns || (nr_apqns == 1 &&
  382. apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
  383. nr_apqns = MAXAPQNSINLIST;
  384. rc = cca_apqns4type(subtype, NULL, NULL, 0,
  385. _apqns, &nr_apqns, pflags);
  386. if (rc)
  387. goto out;
  388. apqns = _apqns;
  389. }
  390. for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
  391. if (subtype == PKEY_TYPE_CCA_CIPHER) {
  392. rc = cca_clr2cipherkey(apqns[i].card, apqns[i].domain,
  393. keybitsize, flags, clrkey,
  394. keybuf, keybuflen, xflags);
  395. } else {
  396. /* PKEY_TYPE_CCA_DATA */
  397. rc = cca_clr2seckey(apqns[i].card, apqns[i].domain,
  398. keybitsize, clrkey, keybuf, xflags);
  399. *keybuflen = (rc ? 0 : SECKEYBLOBSIZE);
  400. }
  401. }
  402. out:
  403. pr_debug("rc=%d\n", rc);
  404. return rc;
  405. }
  406. static int cca_verifykey(const u8 *key, u32 keylen,
  407. u16 *card, u16 *dom,
  408. u32 *keytype, u32 *keybitsize, u32 *flags, u32 pflags)
  409. {
  410. struct keytoken_header *hdr = (struct keytoken_header *)key;
  411. u32 apqns[MAXAPQNSINLIST], nr_apqns = ARRAY_SIZE(apqns);
  412. u32 xflags;
  413. int rc;
  414. xflags = pflags & PKEY_XFLAG_NOMEMALLOC ? ZCRYPT_XFLAG_NOMEMALLOC : 0;
  415. if (keylen < sizeof(*hdr))
  416. return -EINVAL;
  417. zcrypt_wait_api_operational();
  418. if (hdr->type == TOKTYPE_CCA_INTERNAL &&
  419. hdr->version == TOKVER_CCA_AES) {
  420. struct secaeskeytoken *t = (struct secaeskeytoken *)key;
  421. rc = cca_check_secaeskeytoken(pkey_dbf_info, 3, key, 0);
  422. if (rc)
  423. goto out;
  424. *keytype = PKEY_TYPE_CCA_DATA;
  425. *keybitsize = t->bitsize;
  426. rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
  427. ZCRYPT_CEX3C, AES_MK_SET,
  428. t->mkvp, 0, xflags);
  429. if (!rc)
  430. *flags = PKEY_FLAGS_MATCH_CUR_MKVP;
  431. if (rc == -ENODEV) {
  432. nr_apqns = ARRAY_SIZE(apqns);
  433. rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
  434. ZCRYPT_CEX3C, AES_MK_SET,
  435. 0, t->mkvp, xflags);
  436. if (!rc)
  437. *flags = PKEY_FLAGS_MATCH_ALT_MKVP;
  438. }
  439. if (rc)
  440. goto out;
  441. *card = ((struct pkey_apqn *)apqns)->card;
  442. *dom = ((struct pkey_apqn *)apqns)->domain;
  443. } else if (hdr->type == TOKTYPE_CCA_INTERNAL &&
  444. hdr->version == TOKVER_CCA_VLSC) {
  445. struct cipherkeytoken *t = (struct cipherkeytoken *)key;
  446. rc = cca_check_secaescipherkey(pkey_dbf_info, 3, key, 0, 1);
  447. if (rc)
  448. goto out;
  449. *keytype = PKEY_TYPE_CCA_CIPHER;
  450. *keybitsize = PKEY_SIZE_UNKNOWN;
  451. if (!t->plfver && t->wpllen == 512)
  452. *keybitsize = PKEY_SIZE_AES_128;
  453. else if (!t->plfver && t->wpllen == 576)
  454. *keybitsize = PKEY_SIZE_AES_192;
  455. else if (!t->plfver && t->wpllen == 640)
  456. *keybitsize = PKEY_SIZE_AES_256;
  457. rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
  458. ZCRYPT_CEX6, AES_MK_SET,
  459. t->mkvp0, 0, xflags);
  460. if (!rc)
  461. *flags = PKEY_FLAGS_MATCH_CUR_MKVP;
  462. if (rc == -ENODEV) {
  463. nr_apqns = ARRAY_SIZE(apqns);
  464. rc = cca_findcard2(apqns, &nr_apqns, *card, *dom,
  465. ZCRYPT_CEX6, AES_MK_SET,
  466. 0, t->mkvp0, xflags);
  467. if (!rc)
  468. *flags = PKEY_FLAGS_MATCH_ALT_MKVP;
  469. }
  470. if (rc)
  471. goto out;
  472. *card = ((struct pkey_apqn *)apqns)->card;
  473. *dom = ((struct pkey_apqn *)apqns)->domain;
  474. } else {
  475. /* unknown/unsupported key blob */
  476. rc = -EINVAL;
  477. }
  478. out:
  479. pr_debug("rc=%d\n", rc);
  480. return rc;
  481. }
  482. /*
  483. * This function provides an alternate but usually slow way
  484. * to convert a 'clear key token' with AES key material into
  485. * a protected key. This is done via an intermediate step
  486. * which creates a CCA AES DATA secure key first and then
  487. * derives the protected key from this secure key.
  488. */
  489. static int cca_slowpath_key2protkey(const struct pkey_apqn *apqns,
  490. size_t nr_apqns,
  491. const u8 *key, u32 keylen,
  492. u8 *protkey, u32 *protkeylen,
  493. u32 *protkeytype, u32 pflags)
  494. {
  495. const struct keytoken_header *hdr = (const struct keytoken_header *)key;
  496. const struct clearkeytoken *t = (const struct clearkeytoken *)key;
  497. u8 tmpbuf[SECKEYBLOBSIZE]; /* 64 bytes */
  498. u32 tmplen, keysize = 0;
  499. int i, rc;
  500. if (keylen < sizeof(*hdr))
  501. return -EINVAL;
  502. if (hdr->type == TOKTYPE_NON_CCA &&
  503. hdr->version == TOKVER_CLEAR_KEY)
  504. keysize = pkey_keytype_aes_to_size(t->keytype);
  505. if (!keysize || t->len != keysize)
  506. return -EINVAL;
  507. /* try two times in case of failure */
  508. for (i = 0, rc = -ENODEV; i < 2 && rc; i++) {
  509. tmplen = SECKEYBLOBSIZE;
  510. rc = cca_clr2key(NULL, 0, t->keytype, PKEY_TYPE_CCA_DATA,
  511. 8 * keysize, 0, t->clearkey, t->len,
  512. tmpbuf, &tmplen, NULL, pflags);
  513. pr_debug("cca_clr2key()=%d\n", rc);
  514. if (rc)
  515. continue;
  516. rc = cca_key2protkey(NULL, 0, tmpbuf, tmplen,
  517. protkey, protkeylen, protkeytype, pflags);
  518. pr_debug("cca_key2protkey()=%d\n", rc);
  519. }
  520. pr_debug("rc=%d\n", rc);
  521. return rc;
  522. }
  523. static struct pkey_handler cca_handler = {
  524. .module = THIS_MODULE,
  525. .name = "PKEY CCA handler",
  526. .is_supported_key = is_cca_key,
  527. .is_supported_keytype = is_cca_keytype,
  528. .key_to_protkey = cca_key2protkey,
  529. .slowpath_key_to_protkey = cca_slowpath_key2protkey,
  530. .gen_key = cca_gen_key,
  531. .clr_to_key = cca_clr2key,
  532. .verify_key = cca_verifykey,
  533. .apqns_for_key = cca_apqns4key,
  534. .apqns_for_keytype = cca_apqns4type,
  535. };
  536. /*
  537. * Module init
  538. */
  539. static int __init pkey_cca_init(void)
  540. {
  541. /* register this module as pkey handler for all the cca stuff */
  542. return pkey_handler_register(&cca_handler);
  543. }
  544. /*
  545. * Module exit
  546. */
  547. static void __exit pkey_cca_exit(void)
  548. {
  549. /* unregister this module as pkey handler */
  550. pkey_handler_unregister(&cca_handler);
  551. }
  552. module_init(pkey_cca_init);
  553. module_exit(pkey_cca_exit);