pkey_api.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * pkey device driver
  4. *
  5. * Copyright IBM Corp. 2017, 2023
  6. *
  7. * Author(s): Harald Freudenberger
  8. */
  9. #define KMSG_COMPONENT "pkey"
  10. #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
  11. #include <linux/init.h>
  12. #include <linux/miscdevice.h>
  13. #include <linux/slab.h>
  14. #include "zcrypt_api.h"
  15. #include "zcrypt_ccamisc.h"
  16. #include "pkey_base.h"
  17. /*
  18. * Helper functions
  19. */
  20. static int key2protkey(const struct pkey_apqn *apqns, size_t nr_apqns,
  21. const u8 *key, size_t keylen,
  22. u8 *protkey, u32 *protkeylen, u32 *protkeytype)
  23. {
  24. int rc;
  25. /* try the direct way */
  26. rc = pkey_handler_key_to_protkey(apqns, nr_apqns,
  27. key, keylen,
  28. protkey, protkeylen,
  29. protkeytype);
  30. /* if this did not work, try the slowpath way */
  31. if (rc == -ENODEV) {
  32. rc = pkey_handler_slowpath_key_to_protkey(apqns, nr_apqns,
  33. key, keylen,
  34. protkey, protkeylen,
  35. protkeytype);
  36. if (rc)
  37. rc = -ENODEV;
  38. }
  39. pr_debug("rc=%d\n", rc);
  40. return rc;
  41. }
  42. /*
  43. * In-Kernel function: Transform a key blob (of any type) into a protected key
  44. */
  45. int pkey_key2protkey(const u8 *key, u32 keylen,
  46. u8 *protkey, u32 *protkeylen, u32 *protkeytype)
  47. {
  48. int rc;
  49. rc = key2protkey(NULL, 0, key, keylen,
  50. protkey, protkeylen, protkeytype);
  51. if (rc == -ENODEV) {
  52. pkey_handler_request_modules();
  53. rc = key2protkey(NULL, 0, key, keylen,
  54. protkey, protkeylen, protkeytype);
  55. }
  56. return rc;
  57. }
  58. EXPORT_SYMBOL(pkey_key2protkey);
  59. /*
  60. * Ioctl functions
  61. */
  62. static void *_copy_key_from_user(void __user *ukey, size_t keylen)
  63. {
  64. if (!ukey || keylen < MINKEYBLOBBUFSIZE || keylen > KEYBLOBBUFSIZE)
  65. return ERR_PTR(-EINVAL);
  66. return memdup_user(ukey, keylen);
  67. }
  68. static void *_copy_apqns_from_user(void __user *uapqns, size_t nr_apqns)
  69. {
  70. if (!uapqns || nr_apqns == 0)
  71. return NULL;
  72. return memdup_array_user(uapqns, nr_apqns, sizeof(struct pkey_apqn));
  73. }
  74. static int pkey_ioctl_genseck(struct pkey_genseck __user *ugs)
  75. {
  76. struct pkey_genseck kgs;
  77. struct pkey_apqn apqn;
  78. u32 keybuflen;
  79. int rc;
  80. if (copy_from_user(&kgs, ugs, sizeof(kgs)))
  81. return -EFAULT;
  82. apqn.card = kgs.cardnr;
  83. apqn.domain = kgs.domain;
  84. keybuflen = sizeof(kgs.seckey.seckey);
  85. rc = pkey_handler_gen_key(&apqn, 1,
  86. kgs.keytype, PKEY_TYPE_CCA_DATA, 0, 0,
  87. kgs.seckey.seckey, &keybuflen, NULL);
  88. pr_debug("gen_key()=%d\n", rc);
  89. if (!rc && copy_to_user(ugs, &kgs, sizeof(kgs)))
  90. rc = -EFAULT;
  91. memzero_explicit(&kgs, sizeof(kgs));
  92. return rc;
  93. }
  94. static int pkey_ioctl_clr2seck(struct pkey_clr2seck __user *ucs)
  95. {
  96. struct pkey_clr2seck kcs;
  97. struct pkey_apqn apqn;
  98. u32 keybuflen;
  99. int rc;
  100. if (copy_from_user(&kcs, ucs, sizeof(kcs)))
  101. return -EFAULT;
  102. apqn.card = kcs.cardnr;
  103. apqn.domain = kcs.domain;
  104. keybuflen = sizeof(kcs.seckey.seckey);
  105. rc = pkey_handler_clr_to_key(&apqn, 1,
  106. kcs.keytype, PKEY_TYPE_CCA_DATA, 0, 0,
  107. kcs.clrkey.clrkey,
  108. pkey_keytype_aes_to_size(kcs.keytype),
  109. kcs.seckey.seckey, &keybuflen, NULL);
  110. pr_debug("clr_to_key()=%d\n", rc);
  111. if (!rc && copy_to_user(ucs, &kcs, sizeof(kcs)))
  112. rc = -EFAULT;
  113. memzero_explicit(&kcs, sizeof(kcs));
  114. return rc;
  115. }
  116. static int pkey_ioctl_sec2protk(struct pkey_sec2protk __user *usp)
  117. {
  118. struct pkey_sec2protk ksp;
  119. struct pkey_apqn apqn;
  120. int rc;
  121. if (copy_from_user(&ksp, usp, sizeof(ksp)))
  122. return -EFAULT;
  123. apqn.card = ksp.cardnr;
  124. apqn.domain = ksp.domain;
  125. ksp.protkey.len = sizeof(ksp.protkey.protkey);
  126. rc = pkey_handler_key_to_protkey(&apqn, 1,
  127. ksp.seckey.seckey,
  128. sizeof(ksp.seckey.seckey),
  129. ksp.protkey.protkey,
  130. &ksp.protkey.len, &ksp.protkey.type);
  131. pr_debug("key_to_protkey()=%d\n", rc);
  132. if (!rc && copy_to_user(usp, &ksp, sizeof(ksp)))
  133. rc = -EFAULT;
  134. memzero_explicit(&ksp, sizeof(ksp));
  135. return rc;
  136. }
  137. static int pkey_ioctl_clr2protk(struct pkey_clr2protk __user *ucp)
  138. {
  139. struct pkey_clr2protk kcp;
  140. struct clearkeytoken *t;
  141. u32 keylen;
  142. u8 *tmpbuf;
  143. int rc;
  144. if (copy_from_user(&kcp, ucp, sizeof(kcp)))
  145. return -EFAULT;
  146. /* build a 'clear key token' from the clear key value */
  147. keylen = pkey_keytype_aes_to_size(kcp.keytype);
  148. if (!keylen) {
  149. PKEY_DBF_ERR("%s unknown/unsupported keytype %u\n",
  150. __func__, kcp.keytype);
  151. memzero_explicit(&kcp, sizeof(kcp));
  152. return -EINVAL;
  153. }
  154. tmpbuf = kzalloc(sizeof(*t) + keylen, GFP_KERNEL);
  155. if (!tmpbuf) {
  156. memzero_explicit(&kcp, sizeof(kcp));
  157. return -ENOMEM;
  158. }
  159. t = (struct clearkeytoken *)tmpbuf;
  160. t->type = TOKTYPE_NON_CCA;
  161. t->version = TOKVER_CLEAR_KEY;
  162. t->keytype = (keylen - 8) >> 3;
  163. t->len = keylen;
  164. memcpy(t->clearkey, kcp.clrkey.clrkey, keylen);
  165. kcp.protkey.len = sizeof(kcp.protkey.protkey);
  166. rc = key2protkey(NULL, 0,
  167. tmpbuf, sizeof(*t) + keylen,
  168. kcp.protkey.protkey,
  169. &kcp.protkey.len, &kcp.protkey.type);
  170. pr_debug("key2protkey()=%d\n", rc);
  171. kfree_sensitive(tmpbuf);
  172. if (!rc && copy_to_user(ucp, &kcp, sizeof(kcp)))
  173. rc = -EFAULT;
  174. memzero_explicit(&kcp, sizeof(kcp));
  175. return rc;
  176. }
  177. static int pkey_ioctl_findcard(struct pkey_findcard __user *ufc)
  178. {
  179. struct pkey_findcard kfc;
  180. struct pkey_apqn *apqns;
  181. size_t nr_apqns;
  182. int rc;
  183. if (copy_from_user(&kfc, ufc, sizeof(kfc)))
  184. return -EFAULT;
  185. nr_apqns = MAXAPQNSINLIST;
  186. apqns = kmalloc_array(nr_apqns, sizeof(struct pkey_apqn), GFP_KERNEL);
  187. if (!apqns)
  188. return -ENOMEM;
  189. rc = pkey_handler_apqns_for_key(kfc.seckey.seckey,
  190. sizeof(kfc.seckey.seckey),
  191. PKEY_FLAGS_MATCH_CUR_MKVP,
  192. apqns, &nr_apqns);
  193. if (rc == -ENODEV)
  194. rc = pkey_handler_apqns_for_key(kfc.seckey.seckey,
  195. sizeof(kfc.seckey.seckey),
  196. PKEY_FLAGS_MATCH_ALT_MKVP,
  197. apqns, &nr_apqns);
  198. pr_debug("apqns_for_key()=%d\n", rc);
  199. if (rc) {
  200. kfree(apqns);
  201. return rc;
  202. }
  203. kfc.cardnr = apqns[0].card;
  204. kfc.domain = apqns[0].domain;
  205. kfree(apqns);
  206. if (copy_to_user(ufc, &kfc, sizeof(kfc)))
  207. return -EFAULT;
  208. return 0;
  209. }
  210. static int pkey_ioctl_skey2pkey(struct pkey_skey2pkey __user *usp)
  211. {
  212. struct pkey_skey2pkey ksp;
  213. int rc;
  214. if (copy_from_user(&ksp, usp, sizeof(ksp)))
  215. return -EFAULT;
  216. ksp.protkey.len = sizeof(ksp.protkey.protkey);
  217. rc = pkey_handler_key_to_protkey(NULL, 0,
  218. ksp.seckey.seckey,
  219. sizeof(ksp.seckey.seckey),
  220. ksp.protkey.protkey,
  221. &ksp.protkey.len,
  222. &ksp.protkey.type);
  223. pr_debug("key_to_protkey()=%d\n", rc);
  224. if (!rc && copy_to_user(usp, &ksp, sizeof(ksp)))
  225. rc = -EFAULT;
  226. memzero_explicit(&ksp, sizeof(ksp));
  227. return rc;
  228. }
  229. static int pkey_ioctl_verifykey(struct pkey_verifykey __user *uvk)
  230. {
  231. u32 keytype, keybitsize, flags;
  232. struct pkey_verifykey kvk;
  233. int rc;
  234. if (copy_from_user(&kvk, uvk, sizeof(kvk)))
  235. return -EFAULT;
  236. kvk.cardnr = 0xFFFF;
  237. kvk.domain = 0xFFFF;
  238. rc = pkey_handler_verify_key(kvk.seckey.seckey,
  239. sizeof(kvk.seckey.seckey),
  240. &kvk.cardnr, &kvk.domain,
  241. &keytype, &keybitsize, &flags);
  242. pr_debug("verify_key()=%d\n", rc);
  243. if (!rc && keytype != PKEY_TYPE_CCA_DATA)
  244. rc = -EINVAL;
  245. kvk.attributes = PKEY_VERIFY_ATTR_AES;
  246. kvk.keysize = (u16)keybitsize;
  247. if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
  248. kvk.attributes |= PKEY_VERIFY_ATTR_OLD_MKVP;
  249. if (!rc && copy_to_user(uvk, &kvk, sizeof(kvk)))
  250. rc = -EFAULT;
  251. memzero_explicit(&kvk, sizeof(kvk));
  252. return rc;
  253. }
  254. static int pkey_ioctl_genprotk(struct pkey_genprotk __user *ugp)
  255. {
  256. struct pkey_genprotk kgp;
  257. int rc;
  258. if (copy_from_user(&kgp, ugp, sizeof(kgp)))
  259. return -EFAULT;
  260. kgp.protkey.len = sizeof(kgp.protkey.protkey);
  261. rc = pkey_handler_gen_key(NULL, 0, kgp.keytype,
  262. PKEY_TYPE_PROTKEY, 0, 0,
  263. kgp.protkey.protkey, &kgp.protkey.len,
  264. &kgp.protkey.type);
  265. pr_debug("gen_key()=%d\n", rc);
  266. if (!rc && copy_to_user(ugp, &kgp, sizeof(kgp)))
  267. rc = -EFAULT;
  268. memzero_explicit(&kgp, sizeof(kgp));
  269. return rc;
  270. }
  271. static int pkey_ioctl_verifyprotk(struct pkey_verifyprotk __user *uvp)
  272. {
  273. struct pkey_verifyprotk kvp;
  274. struct protaeskeytoken *t;
  275. u32 keytype;
  276. u8 *tmpbuf;
  277. int rc;
  278. if (copy_from_user(&kvp, uvp, sizeof(kvp)))
  279. return -EFAULT;
  280. keytype = pkey_aes_bitsize_to_keytype(8 * kvp.protkey.len);
  281. if (!keytype) {
  282. PKEY_DBF_ERR("%s unknown/unsupported protkey length %u\n",
  283. __func__, kvp.protkey.len);
  284. memzero_explicit(&kvp, sizeof(kvp));
  285. return -EINVAL;
  286. }
  287. /* build a 'protected key token' from the raw protected key */
  288. tmpbuf = kzalloc(sizeof(*t), GFP_KERNEL);
  289. if (!tmpbuf) {
  290. memzero_explicit(&kvp, sizeof(kvp));
  291. return -ENOMEM;
  292. }
  293. t = (struct protaeskeytoken *)tmpbuf;
  294. t->type = TOKTYPE_NON_CCA;
  295. t->version = TOKVER_PROTECTED_KEY;
  296. t->keytype = keytype;
  297. t->len = kvp.protkey.len;
  298. memcpy(t->protkey, kvp.protkey.protkey, kvp.protkey.len);
  299. rc = pkey_handler_verify_key(tmpbuf, sizeof(*t),
  300. NULL, NULL, NULL, NULL, NULL);
  301. pr_debug("verify_key()=%d\n", rc);
  302. kfree_sensitive(tmpbuf);
  303. memzero_explicit(&kvp, sizeof(kvp));
  304. return rc;
  305. }
  306. static int pkey_ioctl_kblob2protk(struct pkey_kblob2pkey __user *utp)
  307. {
  308. struct pkey_kblob2pkey ktp;
  309. u8 *kkey;
  310. int rc;
  311. if (copy_from_user(&ktp, utp, sizeof(ktp)))
  312. return -EFAULT;
  313. kkey = _copy_key_from_user(ktp.key, ktp.keylen);
  314. if (IS_ERR(kkey))
  315. return PTR_ERR(kkey);
  316. ktp.protkey.len = sizeof(ktp.protkey.protkey);
  317. rc = key2protkey(NULL, 0, kkey, ktp.keylen,
  318. ktp.protkey.protkey, &ktp.protkey.len,
  319. &ktp.protkey.type);
  320. pr_debug("key2protkey()=%d\n", rc);
  321. kfree_sensitive(kkey);
  322. if (!rc && copy_to_user(utp, &ktp, sizeof(ktp)))
  323. rc = -EFAULT;
  324. memzero_explicit(&ktp, sizeof(ktp));
  325. return rc;
  326. }
  327. static int pkey_ioctl_genseck2(struct pkey_genseck2 __user *ugs)
  328. {
  329. u32 klen = KEYBLOBBUFSIZE;
  330. struct pkey_genseck2 kgs;
  331. struct pkey_apqn *apqns;
  332. u8 *kkey;
  333. int rc;
  334. u32 u;
  335. if (copy_from_user(&kgs, ugs, sizeof(kgs)))
  336. return -EFAULT;
  337. u = pkey_aes_bitsize_to_keytype(kgs.size);
  338. if (!u) {
  339. PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
  340. __func__, kgs.size);
  341. return -EINVAL;
  342. }
  343. apqns = _copy_apqns_from_user(kgs.apqns, kgs.apqn_entries);
  344. if (IS_ERR(apqns))
  345. return PTR_ERR(apqns);
  346. kkey = kzalloc(klen, GFP_KERNEL);
  347. if (!kkey) {
  348. kfree(apqns);
  349. return -ENOMEM;
  350. }
  351. rc = pkey_handler_gen_key(apqns, kgs.apqn_entries,
  352. u, kgs.type, kgs.size, kgs.keygenflags,
  353. kkey, &klen, NULL);
  354. pr_debug("gen_key()=%d\n", rc);
  355. kfree(apqns);
  356. if (rc) {
  357. kfree_sensitive(kkey);
  358. return rc;
  359. }
  360. if (kgs.key) {
  361. if (kgs.keylen < klen) {
  362. kfree_sensitive(kkey);
  363. return -EINVAL;
  364. }
  365. if (copy_to_user(kgs.key, kkey, klen)) {
  366. kfree_sensitive(kkey);
  367. return -EFAULT;
  368. }
  369. }
  370. kgs.keylen = klen;
  371. if (copy_to_user(ugs, &kgs, sizeof(kgs)))
  372. rc = -EFAULT;
  373. kfree_sensitive(kkey);
  374. return rc;
  375. }
  376. static int pkey_ioctl_clr2seck2(struct pkey_clr2seck2 __user *ucs)
  377. {
  378. u32 klen = KEYBLOBBUFSIZE;
  379. struct pkey_clr2seck2 kcs;
  380. struct pkey_apqn *apqns;
  381. u8 *kkey;
  382. int rc;
  383. u32 u;
  384. if (copy_from_user(&kcs, ucs, sizeof(kcs)))
  385. return -EFAULT;
  386. u = pkey_aes_bitsize_to_keytype(kcs.size);
  387. if (!u) {
  388. PKEY_DBF_ERR("%s unknown/unsupported keybitsize %d\n",
  389. __func__, kcs.size);
  390. memzero_explicit(&kcs, sizeof(kcs));
  391. return -EINVAL;
  392. }
  393. apqns = _copy_apqns_from_user(kcs.apqns, kcs.apqn_entries);
  394. if (IS_ERR(apqns)) {
  395. memzero_explicit(&kcs, sizeof(kcs));
  396. return PTR_ERR(apqns);
  397. }
  398. kkey = kzalloc(klen, GFP_KERNEL);
  399. if (!kkey) {
  400. kfree(apqns);
  401. memzero_explicit(&kcs, sizeof(kcs));
  402. return -ENOMEM;
  403. }
  404. rc = pkey_handler_clr_to_key(apqns, kcs.apqn_entries,
  405. u, kcs.type, kcs.size, kcs.keygenflags,
  406. kcs.clrkey.clrkey, kcs.size / 8,
  407. kkey, &klen, NULL);
  408. pr_debug("clr_to_key()=%d\n", rc);
  409. kfree(apqns);
  410. if (rc) {
  411. kfree_sensitive(kkey);
  412. memzero_explicit(&kcs, sizeof(kcs));
  413. return rc;
  414. }
  415. if (kcs.key) {
  416. if (kcs.keylen < klen) {
  417. kfree_sensitive(kkey);
  418. memzero_explicit(&kcs, sizeof(kcs));
  419. return -EINVAL;
  420. }
  421. if (copy_to_user(kcs.key, kkey, klen)) {
  422. kfree_sensitive(kkey);
  423. memzero_explicit(&kcs, sizeof(kcs));
  424. return -EFAULT;
  425. }
  426. }
  427. kcs.keylen = klen;
  428. if (copy_to_user(ucs, &kcs, sizeof(kcs)))
  429. rc = -EFAULT;
  430. memzero_explicit(&kcs, sizeof(kcs));
  431. kfree_sensitive(kkey);
  432. return rc;
  433. }
  434. static int pkey_ioctl_verifykey2(struct pkey_verifykey2 __user *uvk)
  435. {
  436. struct pkey_verifykey2 kvk;
  437. u8 *kkey;
  438. int rc;
  439. if (copy_from_user(&kvk, uvk, sizeof(kvk)))
  440. return -EFAULT;
  441. kkey = _copy_key_from_user(kvk.key, kvk.keylen);
  442. if (IS_ERR(kkey))
  443. return PTR_ERR(kkey);
  444. rc = pkey_handler_verify_key(kkey, kvk.keylen,
  445. &kvk.cardnr, &kvk.domain,
  446. &kvk.type, &kvk.size, &kvk.flags);
  447. pr_debug("verify_key()=%d\n", rc);
  448. kfree_sensitive(kkey);
  449. if (!rc && copy_to_user(uvk, &kvk, sizeof(kvk)))
  450. return -EFAULT;
  451. return rc;
  452. }
  453. static int pkey_ioctl_kblob2protk2(struct pkey_kblob2pkey2 __user *utp)
  454. {
  455. struct pkey_apqn *apqns = NULL;
  456. struct pkey_kblob2pkey2 ktp;
  457. u8 *kkey;
  458. int rc;
  459. if (copy_from_user(&ktp, utp, sizeof(ktp)))
  460. return -EFAULT;
  461. apqns = _copy_apqns_from_user(ktp.apqns, ktp.apqn_entries);
  462. if (IS_ERR(apqns))
  463. return PTR_ERR(apqns);
  464. kkey = _copy_key_from_user(ktp.key, ktp.keylen);
  465. if (IS_ERR(kkey)) {
  466. kfree(apqns);
  467. return PTR_ERR(kkey);
  468. }
  469. ktp.protkey.len = sizeof(ktp.protkey.protkey);
  470. rc = key2protkey(apqns, ktp.apqn_entries, kkey, ktp.keylen,
  471. ktp.protkey.protkey, &ktp.protkey.len,
  472. &ktp.protkey.type);
  473. pr_debug("key2protkey()=%d\n", rc);
  474. kfree(apqns);
  475. kfree_sensitive(kkey);
  476. if (!rc && copy_to_user(utp, &ktp, sizeof(ktp)))
  477. rc = -EFAULT;
  478. memzero_explicit(&ktp, sizeof(ktp));
  479. return rc;
  480. }
  481. static int pkey_ioctl_apqns4k(struct pkey_apqns4key __user *uak)
  482. {
  483. struct pkey_apqn *apqns = NULL;
  484. struct pkey_apqns4key kak;
  485. size_t nr_apqns, len;
  486. u8 *kkey;
  487. int rc;
  488. if (copy_from_user(&kak, uak, sizeof(kak)))
  489. return -EFAULT;
  490. nr_apqns = kak.apqn_entries;
  491. if (nr_apqns) {
  492. apqns = kmalloc_array(nr_apqns,
  493. sizeof(struct pkey_apqn),
  494. GFP_KERNEL);
  495. if (!apqns)
  496. return -ENOMEM;
  497. }
  498. kkey = _copy_key_from_user(kak.key, kak.keylen);
  499. if (IS_ERR(kkey)) {
  500. kfree(apqns);
  501. return PTR_ERR(kkey);
  502. }
  503. rc = pkey_handler_apqns_for_key(kkey, kak.keylen, kak.flags,
  504. apqns, &nr_apqns);
  505. pr_debug("apqns_for_key()=%d\n", rc);
  506. kfree_sensitive(kkey);
  507. if (rc && rc != -ENOSPC) {
  508. kfree(apqns);
  509. return rc;
  510. }
  511. if (!rc && kak.apqns) {
  512. if (nr_apqns > kak.apqn_entries) {
  513. kfree(apqns);
  514. return -EINVAL;
  515. }
  516. len = nr_apqns * sizeof(struct pkey_apqn);
  517. if (len) {
  518. if (copy_to_user(kak.apqns, apqns, len)) {
  519. kfree(apqns);
  520. return -EFAULT;
  521. }
  522. }
  523. }
  524. kak.apqn_entries = nr_apqns;
  525. if (copy_to_user(uak, &kak, sizeof(kak)))
  526. rc = -EFAULT;
  527. kfree(apqns);
  528. return rc;
  529. }
  530. static int pkey_ioctl_apqns4kt(struct pkey_apqns4keytype __user *uat)
  531. {
  532. struct pkey_apqn *apqns = NULL;
  533. struct pkey_apqns4keytype kat;
  534. size_t nr_apqns, len;
  535. int rc;
  536. if (copy_from_user(&kat, uat, sizeof(kat)))
  537. return -EFAULT;
  538. nr_apqns = kat.apqn_entries;
  539. if (nr_apqns) {
  540. apqns = kmalloc_array(nr_apqns,
  541. sizeof(struct pkey_apqn),
  542. GFP_KERNEL);
  543. if (!apqns)
  544. return -ENOMEM;
  545. }
  546. rc = pkey_handler_apqns_for_keytype(kat.type,
  547. kat.cur_mkvp, kat.alt_mkvp,
  548. kat.flags, apqns, &nr_apqns);
  549. pr_debug("apqns_for_keytype()=%d\n", rc);
  550. if (rc && rc != -ENOSPC) {
  551. kfree(apqns);
  552. return rc;
  553. }
  554. if (!rc && kat.apqns) {
  555. if (nr_apqns > kat.apqn_entries) {
  556. kfree(apqns);
  557. return -EINVAL;
  558. }
  559. len = nr_apqns * sizeof(struct pkey_apqn);
  560. if (len) {
  561. if (copy_to_user(kat.apqns, apqns, len)) {
  562. kfree(apqns);
  563. return -EFAULT;
  564. }
  565. }
  566. }
  567. kat.apqn_entries = nr_apqns;
  568. if (copy_to_user(uat, &kat, sizeof(kat)))
  569. rc = -EFAULT;
  570. kfree(apqns);
  571. return rc;
  572. }
  573. static int pkey_ioctl_kblob2protk3(struct pkey_kblob2pkey3 __user *utp)
  574. {
  575. u32 protkeylen = PROTKEYBLOBBUFSIZE;
  576. struct pkey_apqn *apqns = NULL;
  577. struct pkey_kblob2pkey3 ktp;
  578. u8 *kkey, *protkey;
  579. int rc;
  580. if (copy_from_user(&ktp, utp, sizeof(ktp)))
  581. return -EFAULT;
  582. apqns = _copy_apqns_from_user(ktp.apqns, ktp.apqn_entries);
  583. if (IS_ERR(apqns))
  584. return PTR_ERR(apqns);
  585. kkey = _copy_key_from_user(ktp.key, ktp.keylen);
  586. if (IS_ERR(kkey)) {
  587. kfree(apqns);
  588. return PTR_ERR(kkey);
  589. }
  590. protkey = kmalloc(protkeylen, GFP_KERNEL);
  591. if (!protkey) {
  592. kfree(apqns);
  593. kfree_sensitive(kkey);
  594. return -ENOMEM;
  595. }
  596. rc = key2protkey(apqns, ktp.apqn_entries, kkey, ktp.keylen,
  597. protkey, &protkeylen, &ktp.pkeytype);
  598. pr_debug("key2protkey()=%d\n", rc);
  599. kfree(apqns);
  600. kfree_sensitive(kkey);
  601. if (rc) {
  602. kfree_sensitive(protkey);
  603. return rc;
  604. }
  605. if (ktp.pkey && ktp.pkeylen) {
  606. if (protkeylen > ktp.pkeylen) {
  607. kfree_sensitive(protkey);
  608. return -EINVAL;
  609. }
  610. if (copy_to_user(ktp.pkey, protkey, protkeylen)) {
  611. kfree_sensitive(protkey);
  612. return -EFAULT;
  613. }
  614. }
  615. kfree_sensitive(protkey);
  616. ktp.pkeylen = protkeylen;
  617. if (copy_to_user(utp, &ktp, sizeof(ktp)))
  618. return -EFAULT;
  619. return 0;
  620. }
  621. static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd,
  622. unsigned long arg)
  623. {
  624. int rc;
  625. switch (cmd) {
  626. case PKEY_GENSECK:
  627. rc = pkey_ioctl_genseck((struct pkey_genseck __user *)arg);
  628. break;
  629. case PKEY_CLR2SECK:
  630. rc = pkey_ioctl_clr2seck((struct pkey_clr2seck __user *)arg);
  631. break;
  632. case PKEY_SEC2PROTK:
  633. rc = pkey_ioctl_sec2protk((struct pkey_sec2protk __user *)arg);
  634. break;
  635. case PKEY_CLR2PROTK:
  636. rc = pkey_ioctl_clr2protk((struct pkey_clr2protk __user *)arg);
  637. break;
  638. case PKEY_FINDCARD:
  639. rc = pkey_ioctl_findcard((struct pkey_findcard __user *)arg);
  640. break;
  641. case PKEY_SKEY2PKEY:
  642. rc = pkey_ioctl_skey2pkey((struct pkey_skey2pkey __user *)arg);
  643. break;
  644. case PKEY_VERIFYKEY:
  645. rc = pkey_ioctl_verifykey((struct pkey_verifykey __user *)arg);
  646. break;
  647. case PKEY_GENPROTK:
  648. rc = pkey_ioctl_genprotk((struct pkey_genprotk __user *)arg);
  649. break;
  650. case PKEY_VERIFYPROTK:
  651. rc = pkey_ioctl_verifyprotk((struct pkey_verifyprotk __user *)arg);
  652. break;
  653. case PKEY_KBLOB2PROTK:
  654. rc = pkey_ioctl_kblob2protk((struct pkey_kblob2pkey __user *)arg);
  655. break;
  656. case PKEY_GENSECK2:
  657. rc = pkey_ioctl_genseck2((struct pkey_genseck2 __user *)arg);
  658. break;
  659. case PKEY_CLR2SECK2:
  660. rc = pkey_ioctl_clr2seck2((struct pkey_clr2seck2 __user *)arg);
  661. break;
  662. case PKEY_VERIFYKEY2:
  663. rc = pkey_ioctl_verifykey2((struct pkey_verifykey2 __user *)arg);
  664. break;
  665. case PKEY_KBLOB2PROTK2:
  666. rc = pkey_ioctl_kblob2protk2((struct pkey_kblob2pkey2 __user *)arg);
  667. break;
  668. case PKEY_APQNS4K:
  669. rc = pkey_ioctl_apqns4k((struct pkey_apqns4key __user *)arg);
  670. break;
  671. case PKEY_APQNS4KT:
  672. rc = pkey_ioctl_apqns4kt((struct pkey_apqns4keytype __user *)arg);
  673. break;
  674. case PKEY_KBLOB2PROTK3:
  675. rc = pkey_ioctl_kblob2protk3((struct pkey_kblob2pkey3 __user *)arg);
  676. break;
  677. default:
  678. /* unknown/unsupported ioctl cmd */
  679. return -ENOTTY;
  680. }
  681. return rc;
  682. }
  683. /*
  684. * File io operations
  685. */
  686. static const struct file_operations pkey_fops = {
  687. .owner = THIS_MODULE,
  688. .open = nonseekable_open,
  689. .unlocked_ioctl = pkey_unlocked_ioctl,
  690. };
  691. static struct miscdevice pkey_dev = {
  692. .name = "pkey",
  693. .minor = MISC_DYNAMIC_MINOR,
  694. .mode = 0666,
  695. .fops = &pkey_fops,
  696. .groups = pkey_attr_groups,
  697. };
  698. int __init pkey_api_init(void)
  699. {
  700. /* register as a misc device */
  701. return misc_register(&pkey_dev);
  702. }
  703. void __exit pkey_api_exit(void)
  704. {
  705. misc_deregister(&pkey_dev);
  706. }