0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <keys/asymmetric-subtype.h>
0010 #include <keys/asymmetric-parser.h>
0011 #include <crypto/public_key.h>
0012 #include <linux/seq_file.h>
0013 #include <linux/module.h>
0014 #include <linux/slab.h>
0015 #include <linux/ctype.h>
0016 #include <keys/system_keyring.h>
0017 #include <keys/user-type.h>
0018 #include "asymmetric_keys.h"
0019
0020 MODULE_LICENSE("GPL");
0021
0022 const char *const key_being_used_for[NR__KEY_BEING_USED_FOR] = {
0023 [VERIFYING_MODULE_SIGNATURE] = "mod sig",
0024 [VERIFYING_FIRMWARE_SIGNATURE] = "firmware sig",
0025 [VERIFYING_KEXEC_PE_SIGNATURE] = "kexec PE sig",
0026 [VERIFYING_KEY_SIGNATURE] = "key sig",
0027 [VERIFYING_KEY_SELF_SIGNATURE] = "key self sig",
0028 [VERIFYING_UNSPECIFIED_SIGNATURE] = "unspec sig",
0029 };
0030 EXPORT_SYMBOL_GPL(key_being_used_for);
0031
0032 static LIST_HEAD(asymmetric_key_parsers);
0033 static DECLARE_RWSEM(asymmetric_key_parsers_sem);
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 struct key *find_asymmetric_key(struct key *keyring,
0053 const struct asymmetric_key_id *id_0,
0054 const struct asymmetric_key_id *id_1,
0055 const struct asymmetric_key_id *id_2,
0056 bool partial)
0057 {
0058 struct key *key;
0059 key_ref_t ref;
0060 const char *lookup;
0061 char *req, *p;
0062 int len;
0063
0064 WARN_ON(!id_0 && !id_1 && !id_2);
0065
0066 if (id_0) {
0067 lookup = id_0->data;
0068 len = id_0->len;
0069 } else if (id_1) {
0070 lookup = id_1->data;
0071 len = id_1->len;
0072 } else {
0073 lookup = id_2->data;
0074 len = id_2->len;
0075 }
0076
0077
0078 p = req = kmalloc(2 + 1 + len * 2 + 1, GFP_KERNEL);
0079 if (!req)
0080 return ERR_PTR(-ENOMEM);
0081
0082 if (!id_0 && !id_1) {
0083 *p++ = 'd';
0084 *p++ = 'n';
0085 } else if (partial) {
0086 *p++ = 'i';
0087 *p++ = 'd';
0088 } else {
0089 *p++ = 'e';
0090 *p++ = 'x';
0091 }
0092 *p++ = ':';
0093 p = bin2hex(p, lookup, len);
0094 *p = 0;
0095
0096 pr_debug("Look up: \"%s\"\n", req);
0097
0098 ref = keyring_search(make_key_ref(keyring, 1),
0099 &key_type_asymmetric, req, true);
0100 if (IS_ERR(ref))
0101 pr_debug("Request for key '%s' err %ld\n", req, PTR_ERR(ref));
0102 kfree(req);
0103
0104 if (IS_ERR(ref)) {
0105 switch (PTR_ERR(ref)) {
0106
0107 case -EACCES:
0108 case -ENOTDIR:
0109 case -EAGAIN:
0110 return ERR_PTR(-ENOKEY);
0111 default:
0112 return ERR_CAST(ref);
0113 }
0114 }
0115
0116 key = key_ref_to_ptr(ref);
0117 if (id_0 && id_1) {
0118 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
0119
0120 if (!kids->id[1]) {
0121 pr_debug("First ID matches, but second is missing\n");
0122 goto reject;
0123 }
0124 if (!asymmetric_key_id_same(id_1, kids->id[1])) {
0125 pr_debug("First ID matches, but second does not\n");
0126 goto reject;
0127 }
0128 }
0129
0130 pr_devel("<==%s() = 0 [%x]\n", __func__, key_serial(key));
0131 return key;
0132
0133 reject:
0134 key_put(key);
0135 return ERR_PTR(-EKEYREJECTED);
0136 }
0137 EXPORT_SYMBOL_GPL(find_asymmetric_key);
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148 struct asymmetric_key_id *asymmetric_key_generate_id(const void *val_1,
0149 size_t len_1,
0150 const void *val_2,
0151 size_t len_2)
0152 {
0153 struct asymmetric_key_id *kid;
0154
0155 kid = kmalloc(sizeof(struct asymmetric_key_id) + len_1 + len_2,
0156 GFP_KERNEL);
0157 if (!kid)
0158 return ERR_PTR(-ENOMEM);
0159 kid->len = len_1 + len_2;
0160 memcpy(kid->data, val_1, len_1);
0161 memcpy(kid->data + len_1, val_2, len_2);
0162 return kid;
0163 }
0164 EXPORT_SYMBOL_GPL(asymmetric_key_generate_id);
0165
0166
0167
0168
0169
0170
0171 bool asymmetric_key_id_same(const struct asymmetric_key_id *kid1,
0172 const struct asymmetric_key_id *kid2)
0173 {
0174 if (!kid1 || !kid2)
0175 return false;
0176 if (kid1->len != kid2->len)
0177 return false;
0178 return memcmp(kid1->data, kid2->data, kid1->len) == 0;
0179 }
0180 EXPORT_SYMBOL_GPL(asymmetric_key_id_same);
0181
0182
0183
0184
0185
0186
0187
0188 bool asymmetric_key_id_partial(const struct asymmetric_key_id *kid1,
0189 const struct asymmetric_key_id *kid2)
0190 {
0191 if (!kid1 || !kid2)
0192 return false;
0193 if (kid1->len < kid2->len)
0194 return false;
0195 return memcmp(kid1->data + (kid1->len - kid2->len),
0196 kid2->data, kid2->len) == 0;
0197 }
0198 EXPORT_SYMBOL_GPL(asymmetric_key_id_partial);
0199
0200
0201
0202
0203
0204
0205
0206 static bool asymmetric_match_key_ids(
0207 const struct asymmetric_key_ids *kids,
0208 const struct asymmetric_key_id *match_id,
0209 bool (*match)(const struct asymmetric_key_id *kid1,
0210 const struct asymmetric_key_id *kid2))
0211 {
0212 int i;
0213
0214 if (!kids || !match_id)
0215 return false;
0216 for (i = 0; i < 2; i++)
0217 if (match(kids->id[i], match_id))
0218 return true;
0219 return false;
0220 }
0221
0222
0223 inline int __asymmetric_key_hex_to_key_id(const char *id,
0224 struct asymmetric_key_id *match_id,
0225 size_t hexlen)
0226 {
0227 match_id->len = hexlen;
0228 return hex2bin(match_id->data, id, hexlen);
0229 }
0230
0231
0232
0233
0234
0235 struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id)
0236 {
0237 struct asymmetric_key_id *match_id;
0238 size_t asciihexlen;
0239 int ret;
0240
0241 if (!*id)
0242 return ERR_PTR(-EINVAL);
0243 asciihexlen = strlen(id);
0244 if (asciihexlen & 1)
0245 return ERR_PTR(-EINVAL);
0246
0247 match_id = kmalloc(sizeof(struct asymmetric_key_id) + asciihexlen / 2,
0248 GFP_KERNEL);
0249 if (!match_id)
0250 return ERR_PTR(-ENOMEM);
0251 ret = __asymmetric_key_hex_to_key_id(id, match_id, asciihexlen / 2);
0252 if (ret < 0) {
0253 kfree(match_id);
0254 return ERR_PTR(-EINVAL);
0255 }
0256 return match_id;
0257 }
0258
0259
0260
0261
0262 static bool asymmetric_key_cmp(const struct key *key,
0263 const struct key_match_data *match_data)
0264 {
0265 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
0266 const struct asymmetric_key_id *match_id = match_data->preparsed;
0267
0268 return asymmetric_match_key_ids(kids, match_id,
0269 asymmetric_key_id_same);
0270 }
0271
0272
0273
0274
0275 static bool asymmetric_key_cmp_partial(const struct key *key,
0276 const struct key_match_data *match_data)
0277 {
0278 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
0279 const struct asymmetric_key_id *match_id = match_data->preparsed;
0280
0281 return asymmetric_match_key_ids(kids, match_id,
0282 asymmetric_key_id_partial);
0283 }
0284
0285
0286
0287
0288 static bool asymmetric_key_cmp_name(const struct key *key,
0289 const struct key_match_data *match_data)
0290 {
0291 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
0292 const struct asymmetric_key_id *match_id = match_data->preparsed;
0293
0294 return kids && asymmetric_key_id_same(kids->id[2], match_id);
0295 }
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311 static int asymmetric_key_match_preparse(struct key_match_data *match_data)
0312 {
0313 struct asymmetric_key_id *match_id;
0314 const char *spec = match_data->raw_data;
0315 const char *id;
0316 bool (*cmp)(const struct key *, const struct key_match_data *) =
0317 asymmetric_key_cmp;
0318
0319 if (!spec || !*spec)
0320 return -EINVAL;
0321 if (spec[0] == 'i' &&
0322 spec[1] == 'd' &&
0323 spec[2] == ':') {
0324 id = spec + 3;
0325 cmp = asymmetric_key_cmp_partial;
0326 } else if (spec[0] == 'e' &&
0327 spec[1] == 'x' &&
0328 spec[2] == ':') {
0329 id = spec + 3;
0330 } else if (spec[0] == 'd' &&
0331 spec[1] == 'n' &&
0332 spec[2] == ':') {
0333 id = spec + 3;
0334 cmp = asymmetric_key_cmp_name;
0335 } else {
0336 goto default_match;
0337 }
0338
0339 match_id = asymmetric_key_hex_to_key_id(id);
0340 if (IS_ERR(match_id))
0341 return PTR_ERR(match_id);
0342
0343 match_data->preparsed = match_id;
0344 match_data->cmp = cmp;
0345 match_data->lookup_type = KEYRING_SEARCH_LOOKUP_ITERATE;
0346 return 0;
0347
0348 default_match:
0349 return 0;
0350 }
0351
0352
0353
0354
0355 static void asymmetric_key_match_free(struct key_match_data *match_data)
0356 {
0357 kfree(match_data->preparsed);
0358 }
0359
0360
0361
0362
0363 static void asymmetric_key_describe(const struct key *key, struct seq_file *m)
0364 {
0365 const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);
0366 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key);
0367 const struct asymmetric_key_id *kid;
0368 const unsigned char *p;
0369 int n;
0370
0371 seq_puts(m, key->description);
0372
0373 if (subtype) {
0374 seq_puts(m, ": ");
0375 subtype->describe(key, m);
0376
0377 if (kids && kids->id[1]) {
0378 kid = kids->id[1];
0379 seq_putc(m, ' ');
0380 n = kid->len;
0381 p = kid->data;
0382 if (n > 4) {
0383 p += n - 4;
0384 n = 4;
0385 }
0386 seq_printf(m, "%*phN", n, p);
0387 }
0388
0389 seq_puts(m, " [");
0390
0391 seq_putc(m, ']');
0392 }
0393 }
0394
0395
0396
0397
0398
0399
0400
0401
0402 static int asymmetric_key_preparse(struct key_preparsed_payload *prep)
0403 {
0404 struct asymmetric_key_parser *parser;
0405 int ret;
0406
0407 pr_devel("==>%s()\n", __func__);
0408
0409 if (prep->datalen == 0)
0410 return -EINVAL;
0411
0412 down_read(&asymmetric_key_parsers_sem);
0413
0414 ret = -EBADMSG;
0415 list_for_each_entry(parser, &asymmetric_key_parsers, link) {
0416 pr_debug("Trying parser '%s'\n", parser->name);
0417
0418 ret = parser->parse(prep);
0419 if (ret != -EBADMSG) {
0420 pr_debug("Parser recognised the format (ret %d)\n",
0421 ret);
0422 break;
0423 }
0424 }
0425
0426 up_read(&asymmetric_key_parsers_sem);
0427 pr_devel("<==%s() = %d\n", __func__, ret);
0428 return ret;
0429 }
0430
0431
0432
0433
0434 static void asymmetric_key_free_kids(struct asymmetric_key_ids *kids)
0435 {
0436 int i;
0437
0438 if (kids) {
0439 for (i = 0; i < ARRAY_SIZE(kids->id); i++)
0440 kfree(kids->id[i]);
0441 kfree(kids);
0442 }
0443 }
0444
0445
0446
0447
0448 static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep)
0449 {
0450 struct asymmetric_key_subtype *subtype = prep->payload.data[asym_subtype];
0451 struct asymmetric_key_ids *kids = prep->payload.data[asym_key_ids];
0452
0453 pr_devel("==>%s()\n", __func__);
0454
0455 if (subtype) {
0456 subtype->destroy(prep->payload.data[asym_crypto],
0457 prep->payload.data[asym_auth]);
0458 module_put(subtype->owner);
0459 }
0460 asymmetric_key_free_kids(kids);
0461 kfree(prep->description);
0462 }
0463
0464
0465
0466
0467 static void asymmetric_key_destroy(struct key *key)
0468 {
0469 struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key);
0470 struct asymmetric_key_ids *kids = key->payload.data[asym_key_ids];
0471 void *data = key->payload.data[asym_crypto];
0472 void *auth = key->payload.data[asym_auth];
0473
0474 key->payload.data[asym_crypto] = NULL;
0475 key->payload.data[asym_subtype] = NULL;
0476 key->payload.data[asym_key_ids] = NULL;
0477 key->payload.data[asym_auth] = NULL;
0478
0479 if (subtype) {
0480 subtype->destroy(data, auth);
0481 module_put(subtype->owner);
0482 }
0483
0484 asymmetric_key_free_kids(kids);
0485 }
0486
0487 static struct key_restriction *asymmetric_restriction_alloc(
0488 key_restrict_link_func_t check,
0489 struct key *key)
0490 {
0491 struct key_restriction *keyres =
0492 kzalloc(sizeof(struct key_restriction), GFP_KERNEL);
0493
0494 if (!keyres)
0495 return ERR_PTR(-ENOMEM);
0496
0497 keyres->check = check;
0498 keyres->key = key;
0499 keyres->keytype = &key_type_asymmetric;
0500
0501 return keyres;
0502 }
0503
0504
0505
0506
0507 static struct key_restriction *asymmetric_lookup_restriction(
0508 const char *restriction)
0509 {
0510 char *restrict_method;
0511 char *parse_buf;
0512 char *next;
0513 struct key_restriction *ret = ERR_PTR(-EINVAL);
0514
0515 if (strcmp("builtin_trusted", restriction) == 0)
0516 return asymmetric_restriction_alloc(
0517 restrict_link_by_builtin_trusted, NULL);
0518
0519 if (strcmp("builtin_and_secondary_trusted", restriction) == 0)
0520 return asymmetric_restriction_alloc(
0521 restrict_link_by_builtin_and_secondary_trusted, NULL);
0522
0523 parse_buf = kstrndup(restriction, PAGE_SIZE, GFP_KERNEL);
0524 if (!parse_buf)
0525 return ERR_PTR(-ENOMEM);
0526
0527 next = parse_buf;
0528 restrict_method = strsep(&next, ":");
0529
0530 if ((strcmp(restrict_method, "key_or_keyring") == 0) && next) {
0531 char *key_text;
0532 key_serial_t serial;
0533 struct key *key;
0534 key_restrict_link_func_t link_fn =
0535 restrict_link_by_key_or_keyring;
0536 bool allow_null_key = false;
0537
0538 key_text = strsep(&next, ":");
0539
0540 if (next) {
0541 if (strcmp(next, "chain") != 0)
0542 goto out;
0543
0544 link_fn = restrict_link_by_key_or_keyring_chain;
0545 allow_null_key = true;
0546 }
0547
0548 if (kstrtos32(key_text, 0, &serial) < 0)
0549 goto out;
0550
0551 if ((serial == 0) && allow_null_key) {
0552 key = NULL;
0553 } else {
0554 key = key_lookup(serial);
0555 if (IS_ERR(key)) {
0556 ret = ERR_CAST(key);
0557 goto out;
0558 }
0559 }
0560
0561 ret = asymmetric_restriction_alloc(link_fn, key);
0562 if (IS_ERR(ret))
0563 key_put(key);
0564 }
0565
0566 out:
0567 kfree(parse_buf);
0568 return ret;
0569 }
0570
0571 int asymmetric_key_eds_op(struct kernel_pkey_params *params,
0572 const void *in, void *out)
0573 {
0574 const struct asymmetric_key_subtype *subtype;
0575 struct key *key = params->key;
0576 int ret;
0577
0578 pr_devel("==>%s()\n", __func__);
0579
0580 if (key->type != &key_type_asymmetric)
0581 return -EINVAL;
0582 subtype = asymmetric_key_subtype(key);
0583 if (!subtype ||
0584 !key->payload.data[0])
0585 return -EINVAL;
0586 if (!subtype->eds_op)
0587 return -ENOTSUPP;
0588
0589 ret = subtype->eds_op(params, in, out);
0590
0591 pr_devel("<==%s() = %d\n", __func__, ret);
0592 return ret;
0593 }
0594
0595 static int asymmetric_key_verify_signature(struct kernel_pkey_params *params,
0596 const void *in, const void *in2)
0597 {
0598 struct public_key_signature sig = {
0599 .s_size = params->in2_len,
0600 .digest_size = params->in_len,
0601 .encoding = params->encoding,
0602 .hash_algo = params->hash_algo,
0603 .digest = (void *)in,
0604 .s = (void *)in2,
0605 };
0606
0607 return verify_signature(params->key, &sig);
0608 }
0609
0610 struct key_type key_type_asymmetric = {
0611 .name = "asymmetric",
0612 .preparse = asymmetric_key_preparse,
0613 .free_preparse = asymmetric_key_free_preparse,
0614 .instantiate = generic_key_instantiate,
0615 .match_preparse = asymmetric_key_match_preparse,
0616 .match_free = asymmetric_key_match_free,
0617 .destroy = asymmetric_key_destroy,
0618 .describe = asymmetric_key_describe,
0619 .lookup_restriction = asymmetric_lookup_restriction,
0620 .asym_query = query_asymmetric_key,
0621 .asym_eds_op = asymmetric_key_eds_op,
0622 .asym_verify_signature = asymmetric_key_verify_signature,
0623 };
0624 EXPORT_SYMBOL_GPL(key_type_asymmetric);
0625
0626
0627
0628
0629
0630 int register_asymmetric_key_parser(struct asymmetric_key_parser *parser)
0631 {
0632 struct asymmetric_key_parser *cursor;
0633 int ret;
0634
0635 down_write(&asymmetric_key_parsers_sem);
0636
0637 list_for_each_entry(cursor, &asymmetric_key_parsers, link) {
0638 if (strcmp(cursor->name, parser->name) == 0) {
0639 pr_err("Asymmetric key parser '%s' already registered\n",
0640 parser->name);
0641 ret = -EEXIST;
0642 goto out;
0643 }
0644 }
0645
0646 list_add_tail(&parser->link, &asymmetric_key_parsers);
0647
0648 pr_notice("Asymmetric key parser '%s' registered\n", parser->name);
0649 ret = 0;
0650
0651 out:
0652 up_write(&asymmetric_key_parsers_sem);
0653 return ret;
0654 }
0655 EXPORT_SYMBOL_GPL(register_asymmetric_key_parser);
0656
0657
0658
0659
0660
0661 void unregister_asymmetric_key_parser(struct asymmetric_key_parser *parser)
0662 {
0663 down_write(&asymmetric_key_parsers_sem);
0664 list_del(&parser->link);
0665 up_write(&asymmetric_key_parsers_sem);
0666
0667 pr_notice("Asymmetric key parser '%s' unregistered\n", parser->name);
0668 }
0669 EXPORT_SYMBOL_GPL(unregister_asymmetric_key_parser);
0670
0671
0672
0673
0674 static int __init asymmetric_key_init(void)
0675 {
0676 return register_key_type(&key_type_asymmetric);
0677 }
0678
0679 static void __exit asymmetric_key_cleanup(void)
0680 {
0681 unregister_key_type(&key_type_asymmetric);
0682 }
0683
0684 module_init(asymmetric_key_init);
0685 module_exit(asymmetric_key_cleanup);