pkey_api.c 19 KB

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