asymmetric_type.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /* Asymmetric public-key cryptography key type
  3. *
  4. * See Documentation/crypto/asymmetric-keys.rst
  5. *
  6. * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
  7. * Written by David Howells (dhowells@redhat.com)
  8. */
  9. #include <keys/asymmetric-subtype.h>
  10. #include <keys/asymmetric-parser.h>
  11. #include <crypto/public_key.h>
  12. #include <linux/seq_file.h>
  13. #include <linux/module.h>
  14. #include <linux/slab.h>
  15. #include <linux/ctype.h>
  16. #include <keys/system_keyring.h>
  17. #include <keys/user-type.h>
  18. #include "asymmetric_keys.h"
  19. MODULE_LICENSE("GPL");
  20. const char *const key_being_used_for[NR__KEY_BEING_USED_FOR] = {
  21. [VERIFYING_MODULE_SIGNATURE] = "mod sig",
  22. [VERIFYING_FIRMWARE_SIGNATURE] = "firmware sig",
  23. [VERIFYING_KEXEC_PE_SIGNATURE] = "kexec PE sig",
  24. [VERIFYING_KEY_SIGNATURE] = "key sig",
  25. [VERIFYING_KEY_SELF_SIGNATURE] = "key self sig",
  26. [VERIFYING_UNSPECIFIED_SIGNATURE] = "unspec sig",
  27. };
  28. EXPORT_SYMBOL_GPL(key_being_used_for);
  29. static LIST_HEAD(asymmetric_key_parsers);
  30. static DECLARE_RWSEM(asymmetric_key_parsers_sem);
  31. /**
  32. * find_asymmetric_key - Find a key by ID.
  33. * @keyring: The keys to search.
  34. * @id_0: The first ID to look for or NULL.
  35. * @id_1: The second ID to look for or NULL.
  36. * @partial: Use partial match if true, exact if false.
  37. *
  38. * Find a key in the given keyring by identifier. The preferred identifier is
  39. * the id_0 and the fallback identifier is the id_1. If both are given, the
  40. * lookup is by the former, but the latter must also match.
  41. */
  42. struct key *find_asymmetric_key(struct key *keyring,
  43. const struct asymmetric_key_id *id_0,
  44. const struct asymmetric_key_id *id_1,
  45. bool partial)
  46. {
  47. struct key *key;
  48. key_ref_t ref;
  49. const char *lookup;
  50. char *req, *p;
  51. int len;
  52. BUG_ON(!id_0 && !id_1);
  53. if (id_0) {
  54. lookup = id_0->data;
  55. len = id_0->len;
  56. } else {
  57. lookup = id_1->data;
  58. len = id_1->len;
  59. }
  60. /* Construct an identifier "id:<keyid>". */
  61. p = req = kmalloc(2 + 1 + len * 2 + 1, GFP_KERNEL);
  62. if (!req)
  63. return ERR_PTR(-ENOMEM);
  64. if (partial) {
  65. *p++ = 'i';
  66. *p++ = 'd';
  67. } else {
  68. *p++ = 'e';
  69. *p++ = 'x';
  70. }
  71. *p++ = ':';
  72. p = bin2hex(p, lookup, len);
  73. *p = 0;
  74. pr_debug("Look up: \"%s\"\n", req);
  75. ref = keyring_search(make_key_ref(keyring, 1),
  76. &key_type_asymmetric, req, true);
  77. if (IS_ERR(ref))
  78. pr_debug("Request for key '%s' err %ld\n", req, PTR_ERR(ref));
  79. kfree(req);
  80. if (IS_ERR(ref)) {
  81. switch (PTR_ERR(ref)) {
  82. /* Hide some search errors */
  83. case -EACCES:
  84. case -ENOTDIR:
  85. case -EAGAIN:
  86. return ERR_PTR(-ENOKEY);
  87. default:
  88. return ERR_CAST(ref);
  89. }
  90. }
  91. key = key_ref_to_ptr(ref);
  92. if (id_0 && id_1) {
  93. const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
  94. if (!kids->id[1]) {
  95. pr_debug("First ID matches, but second is missing\n");
  96. goto reject;
  97. }
  98. if (!asymmetric_key_id_same(id_1, kids->id[1])) {
  99. pr_debug("First ID matches, but second does not\n");
  100. goto reject;
  101. }
  102. }
  103. pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key));
  104. return key;
  105. reject:
  106. key_put(key);
  107. return ERR_PTR(-EKEYREJECTED);
  108. }
  109. EXPORT_SYMBOL_GPL(find_asymmetric_key);
  110. /**
  111. * asymmetric_key_generate_id: Construct an asymmetric key ID
  112. * @val_1: First binary blob
  113. * @len_1: Length of first binary blob
  114. * @val_2: Second binary blob
  115. * @len_2: Length of second binary blob
  116. *
  117. * Construct an asymmetric key ID from a pair of binary blobs.
  118. */
  119. struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1,
  120. size_t len_1,
  121. const void *val_2,
  122. size_t len_2)
  123. {
  124. struct asymmetric_key_id *kid;
  125. kid = kmalloc(sizeof(struct asymmetric_key_id) + len_1 + len_2,
  126. GFP_KERNEL);
  127. if (!kid)
  128. return ERR_PTR(-ENOMEM);
  129. kid->len = len_1 + len_2;
  130. memcpy(kid->data, val_1, len_1);
  131. memcpy(kid->data + len_1, val_2, len_2);
  132. return kid;
  133. }
  134. EXPORT_SYMBOL_GPL(asymmetric_key_generate_id);
  135. /**
  136. * asymmetric_key_id_same - Return true if two asymmetric keys IDs are the same.
  137. * @kid_1, @kid_2: The key IDs to compare
  138. */
  139. bool asymmetric_key_id_same(const struct asymmetric_key_id *kid1,
  140. const struct asymmetric_key_id *kid2)
  141. {
  142. if (!kid1 || !kid2)
  143. return false;
  144. if (kid1->len != kid2->len)
  145. return false;
  146. return memcmp(kid1->data, kid2->data, kid1->len) == 0;
  147. }
  148. EXPORT_SYMBOL_GPL(asymmetric_key_id_same);
  149. /**
  150. * asymmetric_key_id_partial - Return true if two asymmetric keys IDs
  151. * partially match
  152. * @kid_1, @kid_2: The key IDs to compare
  153. */
  154. bool asymmetric_key_id_partial(const struct asymmetric_key_id *kid1,
  155. const struct asymmetric_key_id *kid2)
  156. {
  157. if (!kid1 || !kid2)
  158. return false;
  159. if (kid1->len < kid2->len)
  160. return false;
  161. return memcmp(kid1->data + (kid1->len - kid2->len),
  162. kid2->data, kid2->len) == 0;
  163. }
  164. EXPORT_SYMBOL_GPL(asymmetric_key_id_partial);
  165. /**
  166. * asymmetric_match_key_ids - Search asymmetric key IDs
  167. * @kids: The list of key IDs to check
  168. * @match_id: The key ID we're looking for
  169. * @match: The match function to use
  170. */
  171. static bool asymmetric_match_key_ids(
  172. const struct asymmetric_key_ids *kids,
  173. const struct asymmetric_key_id *match_id,
  174. bool (*match)(const struct asymmetric_key_id *kid1,
  175. const struct asymmetric_key_id *kid2))
  176. {
  177. int i;
  178. if (!kids || !match_id)
  179. return false;
  180. for (i = 0; i < ARRAY_SIZE(kids->id); i++)
  181. if (match(kids->id[i], match_id))
  182. return true;
  183. return false;
  184. }
  185. /* helper function can be called directly with pre-allocated memory */
  186. inline int __asymmetric_key_hex_to_key_id(const char *id,
  187. struct asymmetric_key_id *match_id,
  188. size_t hexlen)
  189. {
  190. match_id->len = hexlen;
  191. return hex2bin(match_id->data, id, hexlen);
  192. }
  193. /**
  194. * asymmetric_key_hex_to_key_id - Convert a hex string into a key ID.
  195. * @id: The ID as a hex string.
  196. */
  197. struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id)
  198. {
  199. struct asymmetric_key_id *match_id;
  200. size_t asciihexlen;
  201. int ret;
  202. if (!*id)
  203. return ERR_PTR(-EINVAL);
  204. asciihexlen = strlen(id);
  205. if (asciihexlen & 1)
  206. return ERR_PTR(-EINVAL);
  207. match_id = kmalloc(sizeof(struct asymmetric_key_id) + asciihexlen / 2,
  208. GFP_KERNEL);
  209. if (!match_id)
  210. return ERR_PTR(-ENOMEM);
  211. ret = __asymmetric_key_hex_to_key_id(id, match_id, asciihexlen / 2);
  212. if (ret < 0) {
  213. kfree(match_id);
  214. return ERR_PTR(-EINVAL);
  215. }
  216. return match_id;
  217. }
  218. /*
  219. * Match asymmetric keys by an exact match on an ID.
  220. */
  221. static bool asymmetric_key_cmp(const struct key *key,
  222. const struct key_match_data *match_data)
  223. {
  224. const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
  225. const struct asymmetric_key_id *match_id = match_data->preparsed;
  226. return asymmetric_match_key_ids(kids, match_id,
  227. asymmetric_key_id_same);
  228. }
  229. /*
  230. * Match asymmetric keys by a partial match on an IDs.
  231. */
  232. static bool asymmetric_key_cmp_partial(const struct key *key,
  233. const struct key_match_data *match_data)
  234. {
  235. const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
  236. const struct asymmetric_key_id *match_id = match_data->preparsed;
  237. return asymmetric_match_key_ids(kids, match_id,
  238. asymmetric_key_id_partial);
  239. }
  240. /*
  241. * Preparse the match criterion. If we don't set lookup_type and cmp,
  242. * the default will be an exact match on the key description.
  243. *
  244. * There are some specifiers for matching key IDs rather than by the key
  245. * description:
  246. *
  247. * "id:<id>" - find a key by partial match on any available ID
  248. * "ex:<id>" - find a key by exact match on any available ID
  249. *
  250. * These have to be searched by iteration rather than by direct lookup because
  251. * the key is hashed according to its description.
  252. */
  253. static int asymmetric_key_match_preparse(struct key_match_data *match_data)
  254. {
  255. struct asymmetric_key_id *match_id;
  256. const char *spec = match_data->raw_data;
  257. const char *id;
  258. bool (*cmp)(const struct key *, const struct key_match_data *) =
  259. asymmetric_key_cmp;
  260. if (!spec || !*spec)
  261. return -EINVAL;
  262. if (spec[0] == 'i' &&
  263. spec[1] == 'd' &&
  264. spec[2] == ':') {
  265. id = spec + 3;
  266. cmp = asymmetric_key_cmp_partial;
  267. } else if (spec[0] == 'e' &&
  268. spec[1] == 'x' &&
  269. spec[2] == ':') {
  270. id = spec + 3;
  271. } else {
  272. goto default_match;
  273. }
  274. match_id = asymmetric_key_hex_to_key_id(id);
  275. if (IS_ERR(match_id))
  276. return PTR_ERR(match_id);
  277. match_data->preparsed = match_id;
  278. match_data->cmp = cmp;
  279. match_data->lookup_type = KEYRING_SEARCH_LOOKUP_ITERATE;
  280. return 0;
  281. default_match:
  282. return 0;
  283. }
  284. /*
  285. * Free the preparsed the match criterion.
  286. */
  287. static void asymmetric_key_match_free(struct key_match_data *match_data)
  288. {
  289. kfree(match_data->preparsed);
  290. }
  291. /*
  292. * Describe the asymmetric key
  293. */
  294. static void asymmetric_key_describe(const struct key *key, struct seq_file *m)
  295. {
  296. const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);
  297. const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
  298. const struct asymmetric_key_id *kid;
  299. const unsigned char *p;
  300. int n;
  301. seq_puts(m, key->description);
  302. if (subtype) {
  303. seq_puts(m, ": ");
  304. subtype->describe(key, m);
  305. if (kids && kids->id[1]) {
  306. kid = kids->id[1];
  307. seq_putc(m, ' ');
  308. n = kid->len;
  309. p = kid->data;
  310. if (n > 4) {
  311. p += n - 4;
  312. n = 4;
  313. }
  314. seq_printf(m, "%*phN", n, p);
  315. }
  316. seq_puts(m, " [");
  317. /* put something here to indicate the key's capabilities */
  318. seq_putc(m, ']');
  319. }
  320. }
  321. /*
  322. * Preparse a asymmetric payload to get format the contents appropriately for the
  323. * internal payload to cut down on the number of scans of the data performed.
  324. *
  325. * We also generate a proposed description from the contents of the key that
  326. * can be used to name the key if the user doesn't want to provide one.
  327. */
  328. static int asymmetric_key_preparse(struct key_preparsed_payload *prep)
  329. {
  330. struct asymmetric_key_parser *parser;
  331. int ret;
  332. pr_devel("==>%s()\n", __func__);
  333. if (prep->datalen == 0)
  334. return -EINVAL;
  335. down_read(&asymmetric_key_parsers_sem);
  336. ret = -EBADMSG;
  337. list_for_each_entry(parser, &asymmetric_key_parsers, link) {
  338. pr_debug("Trying parser '%s'\n", parser->name);
  339. ret = parser->parse(prep);
  340. if (ret != -EBADMSG) {
  341. pr_debug("Parser recognised the format (ret %d)\n",
  342. ret);
  343. break;
  344. }
  345. }
  346. up_read(&asymmetric_key_parsers_sem);
  347. pr_devel("<==%s() = %d\n", __func__, ret);
  348. return ret;
  349. }
  350. /*
  351. * Clean up the key ID list
  352. */
  353. static void asymmetric_key_free_kids(struct asymmetric_key_ids *kids)
  354. {
  355. int i;
  356. if (kids) {
  357. for (i = 0; i < ARRAY_SIZE(kids->id); i++)
  358. kfree(kids->id[i]);
  359. kfree(kids);
  360. }
  361. }
  362. /*
  363. * Clean up the preparse data
  364. */
  365. static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep)
  366. {
  367. struct asymmetric_key_subtype *subtype = prep->payload.data[asym_subtype];
  368. struct asymmetric_key_ids *kids = prep->payload.data[asym_key_ids];
  369. pr_devel("==>%s()\n", __func__);
  370. if (subtype) {
  371. subtype->destroy(prep->payload.data[asym_crypto],
  372. prep->payload.data[asym_auth]);
  373. module_put(subtype->owner);
  374. }
  375. asymmetric_key_free_kids(kids);
  376. kfree(prep->description);
  377. }
  378. /*
  379. * dispose of the data dangling from the corpse of a asymmetric key
  380. */
  381. static void asymmetric_key_destroy(struct key *key)
  382. {
  383. struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);
  384. struct asymmetric_key_ids *kids = key->payload.data[asym_key_ids];
  385. void *data = key->payload.data[asym_crypto];
  386. void *auth = key->payload.data[asym_auth];
  387. key->payload.data[asym_crypto] = NULL;
  388. key->payload.data[asym_subtype] = NULL;
  389. key->payload.data[asym_key_ids] = NULL;
  390. key->payload.data[asym_auth] = NULL;
  391. if (subtype) {
  392. subtype->destroy(data, auth);
  393. module_put(subtype->owner);
  394. }
  395. asymmetric_key_free_kids(kids);
  396. }
  397. static struct key_restriction *asymmetric_restriction_alloc(
  398. key_restrict_link_func_t check,
  399. struct key *key)
  400. {
  401. struct key_restriction *keyres =
  402. kzalloc(sizeof(struct key_restriction), GFP_KERNEL);
  403. if (!keyres)
  404. return ERR_PTR(-ENOMEM);
  405. keyres->check = check;
  406. keyres->key = key;
  407. keyres->keytype = &key_type_asymmetric;
  408. return keyres;
  409. }
  410. /*
  411. * look up keyring restrict functions for asymmetric keys
  412. */
  413. static struct key_restriction *asymmetric_lookup_restriction(
  414. const char *restriction)
  415. {
  416. char *restrict_method;
  417. char *parse_buf;
  418. char *next;
  419. struct key_restriction *ret = ERR_PTR(-EINVAL);
  420. if (strcmp("builtin_trusted", restriction) == 0)
  421. return asymmetric_restriction_alloc(
  422. restrict_link_by_builtin_trusted, NULL);
  423. if (strcmp("builtin_and_secondary_trusted", restriction) == 0)
  424. return asymmetric_restriction_alloc(
  425. restrict_link_by_builtin_and_secondary_trusted, NULL);
  426. parse_buf = kstrndup(restriction, PAGE_SIZE, GFP_KERNEL);
  427. if (!parse_buf)
  428. return ERR_PTR(-ENOMEM);
  429. next = parse_buf;
  430. restrict_method = strsep(&next, ":");
  431. if ((strcmp(restrict_method, "key_or_keyring") == 0) && next) {
  432. char *key_text;
  433. key_serial_t serial;
  434. struct key *key;
  435. key_restrict_link_func_t link_fn =
  436. restrict_link_by_key_or_keyring;
  437. bool allow_null_key = false;
  438. key_text = strsep(&next, ":");
  439. if (next) {
  440. if (strcmp(next, "chain") != 0)
  441. goto out;
  442. link_fn = restrict_link_by_key_or_keyring_chain;
  443. allow_null_key = true;
  444. }
  445. if (kstrtos32(key_text, 0, &serial) < 0)
  446. goto out;
  447. if ((serial == 0) && allow_null_key) {
  448. key = NULL;
  449. } else {
  450. key = key_lookup(serial);
  451. if (IS_ERR(key)) {
  452. ret = ERR_CAST(key);
  453. goto out;
  454. }
  455. }
  456. ret = asymmetric_restriction_alloc(link_fn, key);
  457. if (IS_ERR(ret))
  458. key_put(key);
  459. }
  460. out:
  461. kfree(parse_buf);
  462. return ret;
  463. }
  464. int asymmetric_key_eds_op(struct kernel_pkey_params *params,
  465. const void *in, void *out)
  466. {
  467. const struct asymmetric_key_subtype *subtype;
  468. struct key *key = params->key;
  469. int ret;
  470. pr_devel("==>%s()\n", __func__);
  471. if (key->type != &key_type_asymmetric)
  472. return -EINVAL;
  473. subtype = asymmetric_key_subtype(key);
  474. if (!subtype ||
  475. !key->payload.data[0])
  476. return -EINVAL;
  477. if (!subtype->eds_op)
  478. return -ENOTSUPP;
  479. ret = subtype->eds_op(params, in, out);
  480. pr_devel("<==%s() = %d\n", __func__, ret);
  481. return ret;
  482. }
  483. static int asymmetric_key_verify_signature(struct kernel_pkey_params *params,
  484. const void *in, const void *in2)
  485. {
  486. struct public_key_signature sig = {
  487. .s_size = params->in2_len,
  488. .digest_size = params->in_len,
  489. .encoding = params->encoding,
  490. .hash_algo = params->hash_algo,
  491. .digest = (void *)in,
  492. .s = (void *)in2,
  493. };
  494. return verify_signature(params->key, &sig);
  495. }
  496. struct key_type key_type_asymmetric = {
  497. .name = "asymmetric",
  498. .preparse = asymmetric_key_preparse,
  499. .free_preparse = asymmetric_key_free_preparse,
  500. .instantiate = generic_key_instantiate,
  501. .match_preparse = asymmetric_key_match_preparse,
  502. .match_free = asymmetric_key_match_free,
  503. .destroy = asymmetric_key_destroy,
  504. .describe = asymmetric_key_describe,
  505. .lookup_restriction = asymmetric_lookup_restriction,
  506. .asym_query = query_asymmetric_key,
  507. .asym_eds_op = asymmetric_key_eds_op,
  508. .asym_verify_signature = asymmetric_key_verify_signature,
  509. };
  510. EXPORT_SYMBOL_GPL(key_type_asymmetric);
  511. /**
  512. * register_asymmetric_key_parser - Register a asymmetric key blob parser
  513. * @parser: The parser to register
  514. */
  515. int register_asymmetric_key_parser(struct asymmetric_key_parser *parser)
  516. {
  517. struct asymmetric_key_parser *cursor;
  518. int ret;
  519. down_write(&asymmetric_key_parsers_sem);
  520. list_for_each_entry(cursor, &asymmetric_key_parsers, link) {
  521. if (strcmp(cursor->name, parser->name) == 0) {
  522. pr_err("Asymmetric key parser '%s' already registered\n",
  523. parser->name);
  524. ret = -EEXIST;
  525. goto out;
  526. }
  527. }
  528. list_add_tail(&parser->link, &asymmetric_key_parsers);
  529. pr_notice("Asymmetric key parser '%s' registered\n", parser->name);
  530. ret = 0;
  531. out:
  532. up_write(&asymmetric_key_parsers_sem);
  533. return ret;
  534. }
  535. EXPORT_SYMBOL_GPL(register_asymmetric_key_parser);
  536. /**
  537. * unregister_asymmetric_key_parser - Unregister a asymmetric key blob parser
  538. * @parser: The parser to unregister
  539. */
  540. void unregister_asymmetric_key_parser(struct asymmetric_key_parser *parser)
  541. {
  542. down_write(&asymmetric_key_parsers_sem);
  543. list_del(&parser->link);
  544. up_write(&asymmetric_key_parsers_sem);
  545. pr_notice("Asymmetric key parser '%s' unregistered\n", parser->name);
  546. }
  547. EXPORT_SYMBOL_GPL(unregister_asymmetric_key_parser);
  548. /*
  549. * Module stuff
  550. */
  551. static int __init asymmetric_key_init(void)
  552. {
  553. return register_key_type(&key_type_asymmetric);
  554. }
  555. static void __exit asymmetric_key_cleanup(void)
  556. {
  557. unregister_key_type(&key_type_asymmetric);
  558. }
  559. module_init(asymmetric_key_init);
  560. module_exit(asymmetric_key_cleanup);