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