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