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