pkey_cca.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * pkey cca specific code
  4. *
  5. * Copyright IBM Corp. 2024
  6. */
  7. #define KMSG_COMPONENT "pkey"
  8. #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
  9. #include <linux/init.h>
  10. #include <linux/module.h>
  11. #include <linux/cpufeature.h>
  12. #include "zcrypt_api.h"
  13. #include "zcrypt_ccamisc.h"
  14. #include "pkey_base.h"
  15. MODULE_LICENSE("GPL");
  16. MODULE_AUTHOR("IBM Corporation");
  17. MODULE_DESCRIPTION("s390 protected key CCA handler");
  18. #if IS_MODULE(CONFIG_PKEY_CCA)
  19. static struct ap_device_id pkey_cca_card_ids[] = {
  20. { .dev_type = AP_DEVICE_TYPE_CEX4 },
  21. { .dev_type = AP_DEVICE_TYPE_CEX5 },
  22. { .dev_type = AP_DEVICE_TYPE_CEX6 },
  23. { .dev_type = AP_DEVICE_TYPE_CEX7 },
  24. { .dev_type = AP_DEVICE_TYPE_CEX8 },
  25. { /* end of list */ },
  26. };
  27. MODULE_DEVICE_TABLE(ap, pkey_cca_card_ids);
  28. #endif
  29. /*
  30. * Check key blob for known and supported CCA key.
  31. */
  32. static bool is_cca_key(const u8 *key, u32 keylen)
  33. {
  34. struct keytoken_header *hdr = (struct keytoken_header *)key;
  35. if (keylen < sizeof(*hdr))
  36. return false;
  37. switch (hdr->type) {
  38. case TOKTYPE_CCA_INTERNAL:
  39. switch (hdr->version) {
  40. case TOKVER_CCA_AES:
  41. case TOKVER_CCA_VLSC:
  42. return true;
  43. default:
  44. return false;
  45. }
  46. case TOKTYPE_CCA_INTERNAL_PKA:
  47. return true;
  48. default:
  49. return false;
  50. }
  51. }
  52. static bool is_cca_keytype(enum pkey_key_type key_type)
  53. {
  54. switch (key_type) {
  55. case PKEY_TYPE_CCA_DATA:
  56. case PKEY_TYPE_CCA_CIPHER:
  57. case PKEY_TYPE_CCA_ECC:
  58. return true;
  59. default:
  60. return false;
  61. }
  62. }
  63. static int cca_apqns4key(const u8 *key, u32 keylen, u32 flags,
  64. struct pkey_apqn *apqns, size_t *nr_apqns)
  65. {
  66. struct keytoken_header *hdr = (struct keytoken_header *)key;
  67. u32 _nr_apqns, *_apqns = NULL;
  68. int rc;
  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, 1);
  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, 1);
  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. kfree(_apqns);
  130. pr_debug("rc=%d\n", rc);
  131. return rc;
  132. }
  133. static int cca_apqns4type(enum pkey_key_type ktype,
  134. u8 cur_mkvp[32], u8 alt_mkvp[32], u32 flags,
  135. struct pkey_apqn *apqns, size_t *nr_apqns)
  136. {
  137. u32 _nr_apqns, *_apqns = NULL;
  138. int rc;
  139. zcrypt_wait_api_operational();
  140. if (ktype == PKEY_TYPE_CCA_DATA || ktype == PKEY_TYPE_CCA_CIPHER) {
  141. u64 cur_mkvp = 0, old_mkvp = 0;
  142. int minhwtype = ZCRYPT_CEX3C;
  143. if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
  144. cur_mkvp = *((u64 *)cur_mkvp);
  145. if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
  146. old_mkvp = *((u64 *)alt_mkvp);
  147. if (ktype == PKEY_TYPE_CCA_CIPHER)
  148. minhwtype = ZCRYPT_CEX6;
  149. rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
  150. minhwtype, AES_MK_SET,
  151. cur_mkvp, old_mkvp, 1);
  152. if (rc)
  153. goto out;
  154. } else if (ktype == PKEY_TYPE_CCA_ECC) {
  155. u64 cur_mkvp = 0, old_mkvp = 0;
  156. if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
  157. cur_mkvp = *((u64 *)cur_mkvp);
  158. if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
  159. old_mkvp = *((u64 *)alt_mkvp);
  160. rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
  161. ZCRYPT_CEX7, APKA_MK_SET,
  162. cur_mkvp, old_mkvp, 1);
  163. if (rc)
  164. goto out;
  165. } else {
  166. PKEY_DBF_ERR("%s unknown/unsupported key type %d",
  167. __func__, (int)ktype);
  168. return -EINVAL;
  169. }
  170. if (apqns) {
  171. if (*nr_apqns < _nr_apqns)
  172. rc = -ENOSPC;
  173. else
  174. memcpy(apqns, _apqns, _nr_apqns * sizeof(u32));
  175. }
  176. *nr_apqns = _nr_apqns;
  177. out:
  178. kfree(_apqns);
  179. pr_debug("rc=%d\n", rc);
  180. return rc;
  181. }
  182. static int cca_key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
  183. const u8 *key, u32 keylen,
  184. u8 *protkey, u32 *protkeylen, u32 *protkeytype)
  185. {
  186. struct keytoken_header *hdr = (struct keytoken_header *)key;
  187. struct pkey_apqn *local_apqns = NULL;
  188. int i, rc;
  189. if (keylen < sizeof(*hdr))
  190. return -EINVAL;
  191. if (hdr->type == TOKTYPE_CCA_INTERNAL &&
  192. hdr->version == TOKVER_CCA_AES) {
  193. /* CCA AES data key */
  194. if (keylen != sizeof(struct secaeskeytoken))
  195. return -EINVAL;
  196. if (cca_check_secaeskeytoken(pkey_dbf_info, 3, key, 0))
  197. return -EINVAL;
  198. } else if (hdr->type == TOKTYPE_CCA_INTERNAL &&
  199. hdr->version == TOKVER_CCA_VLSC) {
  200. /* CCA AES cipher key */
  201. if (keylen < hdr->len || keylen > MAXCCAVLSCTOKENSIZE)
  202. return -EINVAL;
  203. if (cca_check_secaescipherkey(pkey_dbf_info,
  204. 3, key, 0, 1))
  205. return -EINVAL;
  206. } else if (hdr->type == TOKTYPE_CCA_INTERNAL_PKA) {
  207. /* CCA ECC (private) key */
  208. if (keylen < sizeof(struct eccprivkeytoken))
  209. return -EINVAL;
  210. if (cca_check_sececckeytoken(pkey_dbf_info, 3, key, keylen, 1))
  211. return -EINVAL;
  212. } else {
  213. PKEY_DBF_ERR("%s unknown/unsupported blob type %d version %d\n",
  214. __func__, hdr->type, hdr->version);
  215. return -EINVAL;
  216. }
  217. zcrypt_wait_api_operational();
  218. if (!apqns || (nr_apqns == 1 &&
  219. apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
  220. nr_apqns = MAXAPQNSINLIST;
  221. local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
  222. GFP_KERNEL);
  223. if (!local_apqns)
  224. return -ENOMEM;
  225. rc = cca_apqns4key(key, keylen, 0, local_apqns, &nr_apqns);
  226. if (rc)
  227. goto out;
  228. apqns = local_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);
  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);
  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);
  245. } else {
  246. rc = -EINVAL;
  247. break;
  248. }
  249. }
  250. out:
  251. kfree(local_apqns);
  252. pr_debug("rc=%d\n", rc);
  253. return rc;
  254. }
  255. /*
  256. * Generate CCA secure key.
  257. * As of now only CCA AES Data or Cipher secure keys are
  258. * supported.
  259. * keytype is one of the PKEY_KEYTYPE_* constants,
  260. * subtype may be 0 or PKEY_TYPE_CCA_DATA or PKEY_TYPE_CCA_CIPHER,
  261. * keybitsize is the bit size of the key (may be 0 for
  262. * keytype PKEY_KEYTYPE_AES_*).
  263. */
  264. static int cca_gen_key(const struct pkey_apqn *apqns, size_t nr_apqns,
  265. u32 keytype, u32 subtype,
  266. u32 keybitsize, u32 flags,
  267. u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)
  268. {
  269. struct pkey_apqn *local_apqns = NULL;
  270. int i, len, rc;
  271. /* check keytype, subtype, keybitsize */
  272. switch (keytype) {
  273. case PKEY_KEYTYPE_AES_128:
  274. case PKEY_KEYTYPE_AES_192:
  275. case PKEY_KEYTYPE_AES_256:
  276. len = pkey_keytype_aes_to_size(keytype);
  277. if (keybitsize && keybitsize != 8 * len) {
  278. PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
  279. __func__, keybitsize);
  280. return -EINVAL;
  281. }
  282. keybitsize = 8 * len;
  283. switch (subtype) {
  284. case PKEY_TYPE_CCA_DATA:
  285. case PKEY_TYPE_CCA_CIPHER:
  286. break;
  287. default:
  288. PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",
  289. __func__, subtype);
  290. return -EINVAL;
  291. }
  292. break;
  293. default:
  294. PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",
  295. __func__, keytype);
  296. return -EINVAL;
  297. }
  298. zcrypt_wait_api_operational();
  299. if (!apqns || (nr_apqns == 1 &&
  300. apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
  301. nr_apqns = MAXAPQNSINLIST;
  302. local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
  303. GFP_KERNEL);
  304. if (!local_apqns)
  305. return -ENOMEM;
  306. rc = cca_apqns4type(subtype, NULL, NULL, 0,
  307. local_apqns, &nr_apqns);
  308. if (rc)
  309. goto out;
  310. apqns = local_apqns;
  311. }
  312. for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
  313. if (subtype == PKEY_TYPE_CCA_CIPHER) {
  314. rc = cca_gencipherkey(apqns[i].card, apqns[i].domain,
  315. keybitsize, flags,
  316. keybuf, keybuflen);
  317. } else {
  318. /* PKEY_TYPE_CCA_DATA */
  319. rc = cca_genseckey(apqns[i].card, apqns[i].domain,
  320. keybitsize, keybuf);
  321. *keybuflen = (rc ? 0 : SECKEYBLOBSIZE);
  322. }
  323. }
  324. out:
  325. kfree(local_apqns);
  326. pr_debug("rc=%d\n", rc);
  327. return rc;
  328. }
  329. /*
  330. * Generate CCA secure key with given clear key value.
  331. * As of now only CCA AES Data or Cipher secure keys are
  332. * supported.
  333. * keytype is one of the PKEY_KEYTYPE_* constants,
  334. * subtype may be 0 or PKEY_TYPE_CCA_DATA or PKEY_TYPE_CCA_CIPHER,
  335. * keybitsize is the bit size of the key (may be 0 for
  336. * keytype PKEY_KEYTYPE_AES_*).
  337. */
  338. static int cca_clr2key(const struct pkey_apqn *apqns, size_t nr_apqns,
  339. u32 keytype, u32 subtype,
  340. u32 keybitsize, u32 flags,
  341. const u8 *clrkey, u32 clrkeylen,
  342. u8 *keybuf, u32 *keybuflen, u32 *_keyinfo)
  343. {
  344. struct pkey_apqn *local_apqns = NULL;
  345. int i, len, rc;
  346. /* check keytype, subtype, clrkeylen, keybitsize */
  347. switch (keytype) {
  348. case PKEY_KEYTYPE_AES_128:
  349. case PKEY_KEYTYPE_AES_192:
  350. case PKEY_KEYTYPE_AES_256:
  351. len = pkey_keytype_aes_to_size(keytype);
  352. if (keybitsize && keybitsize != 8 * len) {
  353. PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
  354. __func__, keybitsize);
  355. return -EINVAL;
  356. }
  357. keybitsize = 8 * len;
  358. if (clrkeylen != len) {
  359. PKEY_DBF_ERR("%s invalid clear key len %d != %d\n",
  360. __func__, clrkeylen, len);
  361. return -EINVAL;
  362. }
  363. switch (subtype) {
  364. case PKEY_TYPE_CCA_DATA:
  365. case PKEY_TYPE_CCA_CIPHER:
  366. break;
  367. default:
  368. PKEY_DBF_ERR("%s unknown/unsupported subtype %d\n",
  369. __func__, subtype);
  370. return -EINVAL;
  371. }
  372. break;
  373. default:
  374. PKEY_DBF_ERR("%s unknown/unsupported keytype %d\n",
  375. __func__, keytype);
  376. return -EINVAL;
  377. }
  378. zcrypt_wait_api_operational();
  379. if (!apqns || (nr_apqns == 1 &&
  380. apqns[0].card == 0xFFFF && apqns[0].domain == 0xFFFF)) {
  381. nr_apqns = MAXAPQNSINLIST;
  382. local_apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn),
  383. GFP_KERNEL);
  384. if (!local_apqns)
  385. return -ENOMEM;
  386. rc = cca_apqns4type(subtype, NULL, NULL, 0,
  387. local_apqns, &nr_apqns);
  388. if (rc)
  389. goto out;
  390. apqns = local_apqns;
  391. }
  392. for (rc = -ENODEV, i = 0; rc && i < nr_apqns; i++) {
  393. if (subtype == PKEY_TYPE_CCA_CIPHER) {
  394. rc = cca_clr2cipherkey(apqns[i].card, apqns[i].domain,
  395. keybitsize, flags, clrkey,
  396. keybuf, keybuflen);
  397. } else {
  398. /* PKEY_TYPE_CCA_DATA */
  399. rc = cca_clr2seckey(apqns[i].card, apqns[i].domain,
  400. keybitsize, clrkey, keybuf);
  401. *keybuflen = (rc ? 0 : SECKEYBLOBSIZE);
  402. }
  403. }
  404. out:
  405. kfree(local_apqns);
  406. pr_debug("rc=%d\n", rc);
  407. return rc;
  408. }
  409. static int cca_verifykey(const u8 *key, u32 keylen,
  410. u16 *card, u16 *dom,
  411. u32 *keytype, u32 *keybitsize, u32 *flags)
  412. {
  413. struct keytoken_header *hdr = (struct keytoken_header *)key;
  414. u32 nr_apqns, *apqns = NULL;
  415. int rc;
  416. if (keylen < sizeof(*hdr))
  417. return -EINVAL;
  418. zcrypt_wait_api_operational();
  419. if (hdr->type == TOKTYPE_CCA_INTERNAL &&
  420. hdr->version == TOKVER_CCA_AES) {
  421. struct secaeskeytoken *t = (struct secaeskeytoken *)key;
  422. rc = cca_check_secaeskeytoken(pkey_dbf_info, 3, key, 0);
  423. if (rc)
  424. goto out;
  425. *keytype = PKEY_TYPE_CCA_DATA;
  426. *keybitsize = t->bitsize;
  427. rc = cca_findcard2(&apqns, &nr_apqns, *card, *dom,
  428. ZCRYPT_CEX3C, AES_MK_SET,
  429. t->mkvp, 0, 1);
  430. if (!rc)
  431. *flags = PKEY_FLAGS_MATCH_CUR_MKVP;
  432. if (rc == -ENODEV) {
  433. rc = cca_findcard2(&apqns, &nr_apqns, *card, *dom,
  434. ZCRYPT_CEX3C, AES_MK_SET,
  435. 0, t->mkvp, 1);
  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, 1);
  460. if (!rc)
  461. *flags = PKEY_FLAGS_MATCH_CUR_MKVP;
  462. if (rc == -ENODEV) {
  463. rc = cca_findcard2(&apqns, &nr_apqns, *card, *dom,
  464. ZCRYPT_CEX6, AES_MK_SET,
  465. 0, t->mkvp0, 1);
  466. if (!rc)
  467. *flags = PKEY_FLAGS_MATCH_ALT_MKVP;
  468. }
  469. if (rc)
  470. goto out;
  471. *card = ((struct pkey_apqn *)apqns)->card;
  472. *dom = ((struct pkey_apqn *)apqns)->domain;
  473. } else {
  474. /* unknown/unsupported key blob */
  475. rc = -EINVAL;
  476. }
  477. out:
  478. kfree(apqns);
  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)
  494. {
  495. const struct keytoken_header *hdr = (const struct keytoken_header *)key;
  496. const struct clearkeytoken *t = (const struct clearkeytoken *)key;
  497. u32 tmplen, keysize = 0;
  498. u8 *tmpbuf;
  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. /* alloc tmp key buffer */
  508. tmpbuf = kmalloc(SECKEYBLOBSIZE, GFP_ATOMIC);
  509. if (!tmpbuf)
  510. return -ENOMEM;
  511. /* try two times in case of failure */
  512. for (i = 0, rc = -ENODEV; i < 2 && rc; i++) {
  513. tmplen = SECKEYBLOBSIZE;
  514. rc = cca_clr2key(NULL, 0, t->keytype, PKEY_TYPE_CCA_DATA,
  515. 8 * keysize, 0, t->clearkey, t->len,
  516. tmpbuf, &tmplen, NULL);
  517. pr_debug("cca_clr2key()=%d\n", rc);
  518. if (rc)
  519. continue;
  520. rc = cca_key2protkey(NULL, 0, tmpbuf, tmplen,
  521. protkey, protkeylen, protkeytype);
  522. pr_debug("cca_key2protkey()=%d\n", rc);
  523. }
  524. kfree(tmpbuf);
  525. pr_debug("rc=%d\n", rc);
  526. return rc;
  527. }
  528. static struct pkey_handler cca_handler = {
  529. .module = THIS_MODULE,
  530. .name = "PKEY CCA handler",
  531. .is_supported_key = is_cca_key,
  532. .is_supported_keytype = is_cca_keytype,
  533. .key_to_protkey = cca_key2protkey,
  534. .slowpath_key_to_protkey = cca_slowpath_key2protkey,
  535. .gen_key = cca_gen_key,
  536. .clr_to_key = cca_clr2key,
  537. .verify_key = cca_verifykey,
  538. .apqns_for_key = cca_apqns4key,
  539. .apqns_for_keytype = cca_apqns4type,
  540. };
  541. /*
  542. * Module init
  543. */
  544. static int __init pkey_cca_init(void)
  545. {
  546. /* register this module as pkey handler for all the cca stuff */
  547. return pkey_handler_register(&cca_handler);
  548. }
  549. /*
  550. * Module exit
  551. */
  552. static void __exit pkey_cca_exit(void)
  553. {
  554. /* unregister this module as pkey handler */
  555. pkey_handler_unregister(&cca_handler);
  556. }
  557. module_init(pkey_cca_init);
  558. module_exit(pkey_cca_exit);