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
20
21static LIST_HEAD(asymmetric_key_parsers);
22static 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 */
41struct 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(error: -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(error: -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(dst: p, src: lookup, count: len);
84 *p = 0;
85
86 pr_debug("Look up: \"%s\"\n", req);
87
88 ref = keyring_search(keyring: make_key_ref(key: keyring, possession: 1),
89 type: &key_type_asymmetric, description: req, recurse: true);
90 if (IS_ERR(ptr: ref))
91 pr_debug("Request for key '%s' err %ld\n", req, PTR_ERR(ref));
92 kfree(objp: req);
93
94 if (IS_ERR(ptr: ref)) {
95 switch (PTR_ERR(ptr: ref)) {
96 /* Hide some search errors */
97 case -EACCES:
98 case -ENOTDIR:
99 case -EAGAIN:
100 return ERR_PTR(error: -ENOKEY);
101 default:
102 return ERR_CAST(ptr: ref);
103 }
104 }
105
106 key = key_ref_to_ptr(key_ref: 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(kid1: id_1, kid2: 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
123reject:
124 key_put(key);
125 return ERR_PTR(error: -EKEYREJECTED);
126}
127EXPORT_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 */
138struct 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(error: -ENOMEM);
149 kid->len = len_1 + len_2;
150 memcpy(to: kid->data, from: val_1, len: len_1);
151 memcpy(to: kid->data + len_1, from: val_2, len: len_2);
152 return kid;
153}
154EXPORT_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 */
161bool 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}
170EXPORT_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 */
178bool 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}
188EXPORT_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 */
196static 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 */
213inline 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(dst: match_id->data, src: id, count: 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 */
225struct 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(error: -EINVAL);
233 asciihexlen = strlen(id);
234 if (asciihexlen & 1)
235 return ERR_PTR(error: -EINVAL);
236
237 match_id = kmalloc(sizeof(struct asymmetric_key_id) + asciihexlen / 2,
238 GFP_KERNEL);
239 if (!match_id)
240 return ERR_PTR(error: -ENOMEM);
241 ret = __asymmetric_key_hex_to_key_id(id, match_id, hexlen: asciihexlen / 2);
242 if (ret < 0) {
243 kfree(objp: match_id);
244 return ERR_PTR(error: -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 */
252static 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 match: asymmetric_key_id_same);
260}
261
262/*
263 * Match asymmetric keys by a partial match on one of the first two IDs.
264 */
265static 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 match: asymmetric_key_id_partial);
273}
274
275/*
276 * Match asymmetric keys by an exact match on the third IDs.
277 */
278static 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 */
301static 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(ptr: match_id))
331 return PTR_ERR(ptr: 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
338default_match:
339 return 0;
340}
341
342/*
343 * Free the preparsed the match criterion.
344 */
345static void asymmetric_key_match_free(struct key_match_data *match_data)
346{
347 kfree(objp: match_data->preparsed);
348}
349
350/*
351 * Describe the asymmetric key
352 */
353static 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, s: key->description);
362
363 if (subtype) {
364 seq_puts(m, s: ": ");
365 subtype->describe(key, m);
366
367 if (kids && kids->id[1]) {
368 kid = kids->id[1];
369 seq_putc(m, c: ' ');
370 n = kid->len;
371 p = kid->data;
372 if (n > 4) {
373 p += n - 4;
374 n = 4;
375 }
376 seq_printf(m, fmt: "%*phN", n, p);
377 }
378
379 seq_puts(m, s: " [");
380 /* put something here to indicate the key's capabilities */
381 seq_putc(m, c: ']');
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 */
392static 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(sem: &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(sem: &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 */
424static 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(objp: kids->id[i]);
431 kfree(objp: kids);
432 }
433}
434
435/*
436 * Clean up the preparse data
437 */
438static 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(module: subtype->owner);
449 }
450 asymmetric_key_free_kids(kids);
451 kfree(objp: prep->description);
452}
453
454/*
455 * dispose of the data dangling from the corpse of a asymmetric key
456 */
457static 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(module: subtype->owner);
472 }
473
474 asymmetric_key_free_kids(kids);
475}
476
477static 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(error: -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 */
497static 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(error: -EINVAL);
504
505 if (strcmp("builtin_trusted", restriction) == 0)
506 return asymmetric_restriction_alloc(
507 check: 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(s: restriction, PAGE_SIZE, GFP_KERNEL);
514 if (!parse_buf)
515 return ERR_PTR(error: -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(s: key_text, base: 0, res: &serial) < 0)
539 goto out;
540
541 if ((serial == 0) && allow_null_key) {
542 key = NULL;
543 } else {
544 key = key_lookup(id: serial);
545 if (IS_ERR(ptr: key)) {
546 ret = ERR_CAST(ptr: key);
547 goto out;
548 }
549 }
550
551 ret = asymmetric_restriction_alloc(check: link_fn, key);
552 if (IS_ERR(ptr: ret))
553 key_put(key);
554 }
555
556out:
557 kfree(objp: parse_buf);
558 return ret;
559}
560
561int 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
585static 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
600struct 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};
614EXPORT_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 */
620int register_asymmetric_key_parser(struct asymmetric_key_parser *parser)
621{
622 struct asymmetric_key_parser *cursor;
623 int ret;
624
625 down_write(sem: &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(new: &parser->link, head: &asymmetric_key_parsers);
637
638 pr_notice("Asymmetric key parser '%s' registered\n", parser->name);
639 ret = 0;
640
641out:
642 up_write(sem: &asymmetric_key_parsers_sem);
643 return ret;
644}
645EXPORT_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 */
651void unregister_asymmetric_key_parser(struct asymmetric_key_parser *parser)
652{
653 down_write(sem: &asymmetric_key_parsers_sem);
654 list_del(entry: &parser->link);
655 up_write(sem: &asymmetric_key_parsers_sem);
656
657 pr_notice("Asymmetric key parser '%s' unregistered\n", parser->name);
658}
659EXPORT_SYMBOL_GPL(unregister_asymmetric_key_parser);
660
661/*
662 * Module stuff
663 */
664static int __init asymmetric_key_init(void)
665{
666 return register_key_type(ktype: &key_type_asymmetric);
667}
668
669static void __exit asymmetric_key_cleanup(void)
670{
671 unregister_key_type(ktype: &key_type_asymmetric);
672}
673
674module_init(asymmetric_key_init);
675module_exit(asymmetric_key_cleanup);
676