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