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