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 * @kid_1, @kid_2: The key IDs to compare 156 */ 157 bool asymmetric_key_id_same(const struct asymmetric_key_id *kid1, 158 const struct asymmetric_key_id *kid2) 159 { 160 if (!kid1 || !kid2) 161 return false; 162 if (kid1->len != kid2->len) 163 return false; 164 return memcmp(kid1->data, kid2->data, kid1->len) == 0; 165 } 166 EXPORT_SYMBOL_GPL(asymmetric_key_id_same); 167 168 /** 169 * asymmetric_key_id_partial - Return true if two asymmetric keys IDs 170 * partially match 171 * @kid_1, @kid_2: The key IDs to compare 172 */ 173 bool asymmetric_key_id_partial(const struct asymmetric_key_id *kid1, 174 const struct asymmetric_key_id *kid2) 175 { 176 if (!kid1 || !kid2) 177 return false; 178 if (kid1->len < kid2->len) 179 return false; 180 return memcmp(kid1->data + (kid1->len - kid2->len), 181 kid2->data, kid2->len) == 0; 182 } 183 EXPORT_SYMBOL_GPL(asymmetric_key_id_partial); 184 185 /** 186 * asymmetric_match_key_ids - Search asymmetric key IDs 187 * @kids: The list of key IDs to check 188 * @match_id: The key ID we're looking for 189 * @match: The match function to use 190 */ 191 static bool asymmetric_match_key_ids( 192 const struct asymmetric_key_ids *kids, 193 const struct asymmetric_key_id *match_id, 194 bool (*match)(const struct asymmetric_key_id *kid1, 195 const struct asymmetric_key_id *kid2)) 196 { 197 int i; 198 199 if (!kids || !match_id) 200 return false; 201 for (i = 0; i < ARRAY_SIZE(kids->id); i++) 202 if (match(kids->id[i], match_id)) 203 return true; 204 return false; 205 } 206 207 /* helper function can be called directly with pre-allocated memory */ 208 inline int __asymmetric_key_hex_to_key_id(const char *id, 209 struct asymmetric_key_id *match_id, 210 size_t hexlen) 211 { 212 match_id->len = hexlen; 213 return hex2bin(match_id->data, id, hexlen); 214 } 215 216 /** 217 * asymmetric_key_hex_to_key_id - Convert a hex string into a key ID. 218 * @id: The ID as a hex string. 219 */ 220 struct asymmetric_key_id *asymmetric_key_hex_to_key_id(const char *id) 221 { 222 struct asymmetric_key_id *match_id; 223 size_t asciihexlen; 224 int ret; 225 226 if (!*id) 227 return ERR_PTR(-EINVAL); 228 asciihexlen = strlen(id); 229 if (asciihexlen & 1) 230 return ERR_PTR(-EINVAL); 231 232 match_id = kmalloc(sizeof(struct asymmetric_key_id) + asciihexlen / 2, 233 GFP_KERNEL); 234 if (!match_id) 235 return ERR_PTR(-ENOMEM); 236 ret = __asymmetric_key_hex_to_key_id(id, match_id, asciihexlen / 2); 237 if (ret < 0) { 238 kfree(match_id); 239 return ERR_PTR(-EINVAL); 240 } 241 return match_id; 242 } 243 244 /* 245 * Match asymmetric keys by an exact match on an ID. 246 */ 247 static bool asymmetric_key_cmp(const struct key *key, 248 const struct key_match_data *match_data) 249 { 250 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key); 251 const struct asymmetric_key_id *match_id = match_data->preparsed; 252 253 return asymmetric_match_key_ids(kids, match_id, 254 asymmetric_key_id_same); 255 } 256 257 /* 258 * Match asymmetric keys by a partial match on an IDs. 259 */ 260 static bool asymmetric_key_cmp_partial(const struct key *key, 261 const struct key_match_data *match_data) 262 { 263 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key); 264 const struct asymmetric_key_id *match_id = match_data->preparsed; 265 266 return asymmetric_match_key_ids(kids, match_id, 267 asymmetric_key_id_partial); 268 } 269 270 /* 271 * Preparse the match criterion. If we don't set lookup_type and cmp, 272 * the default will be an exact match on the key description. 273 * 274 * There are some specifiers for matching key IDs rather than by the key 275 * description: 276 * 277 * "id:<id>" - find a key by partial match on any available ID 278 * "ex:<id>" - find a key by exact match on any available ID 279 * 280 * These have to be searched by iteration rather than by direct lookup because 281 * the key is hashed according to its description. 282 */ 283 static int asymmetric_key_match_preparse(struct key_match_data *match_data) 284 { 285 struct asymmetric_key_id *match_id; 286 const char *spec = match_data->raw_data; 287 const char *id; 288 bool (*cmp)(const struct key *, const struct key_match_data *) = 289 asymmetric_key_cmp; 290 291 if (!spec || !*spec) 292 return -EINVAL; 293 if (spec[0] == 'i' && 294 spec[1] == 'd' && 295 spec[2] == ':') { 296 id = spec + 3; 297 cmp = asymmetric_key_cmp_partial; 298 } else if (spec[0] == 'e' && 299 spec[1] == 'x' && 300 spec[2] == ':') { 301 id = spec + 3; 302 } else { 303 goto default_match; 304 } 305 306 match_id = asymmetric_key_hex_to_key_id(id); 307 if (IS_ERR(match_id)) 308 return PTR_ERR(match_id); 309 310 match_data->preparsed = match_id; 311 match_data->cmp = cmp; 312 match_data->lookup_type = KEYRING_SEARCH_LOOKUP_ITERATE; 313 return 0; 314 315 default_match: 316 return 0; 317 } 318 319 /* 320 * Free the preparsed the match criterion. 321 */ 322 static void asymmetric_key_match_free(struct key_match_data *match_data) 323 { 324 kfree(match_data->preparsed); 325 } 326 327 /* 328 * Describe the asymmetric key 329 */ 330 static void asymmetric_key_describe(const struct key *key, struct seq_file *m) 331 { 332 const struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); 333 const struct asymmetric_key_ids *kids = asymmetric_key_ids(key); 334 const struct asymmetric_key_id *kid; 335 const unsigned char *p; 336 int n; 337 338 seq_puts(m, key->description); 339 340 if (subtype) { 341 seq_puts(m, ": "); 342 subtype->describe(key, m); 343 344 if (kids && kids->id[1]) { 345 kid = kids->id[1]; 346 seq_putc(m, ' '); 347 n = kid->len; 348 p = kid->data; 349 if (n > 4) { 350 p += n - 4; 351 n = 4; 352 } 353 seq_printf(m, "%*phN", n, p); 354 } 355 356 seq_puts(m, " ["); 357 /* put something here to indicate the key's capabilities */ 358 seq_putc(m, ']'); 359 } 360 } 361 362 /* 363 * Preparse a asymmetric payload to get format the contents appropriately for the 364 * internal payload to cut down on the number of scans of the data performed. 365 * 366 * We also generate a proposed description from the contents of the key that 367 * can be used to name the key if the user doesn't want to provide one. 368 */ 369 static int asymmetric_key_preparse(struct key_preparsed_payload *prep) 370 { 371 struct asymmetric_key_parser *parser; 372 int ret; 373 374 pr_devel("==>%s()\n", __func__); 375 376 if (prep->datalen == 0) 377 return -EINVAL; 378 379 down_read(&asymmetric_key_parsers_sem); 380 381 ret = -EBADMSG; 382 list_for_each_entry(parser, &asymmetric_key_parsers, link) { 383 pr_debug("Trying parser '%s'\n", parser->name); 384 385 ret = parser->parse(prep); 386 if (ret != -EBADMSG) { 387 pr_debug("Parser recognised the format (ret %d)\n", 388 ret); 389 break; 390 } 391 } 392 393 up_read(&asymmetric_key_parsers_sem); 394 pr_devel("<==%s() = %d\n", __func__, ret); 395 return ret; 396 } 397 398 /* 399 * Clean up the key ID list 400 */ 401 static void asymmetric_key_free_kids(struct asymmetric_key_ids *kids) 402 { 403 int i; 404 405 if (kids) { 406 for (i = 0; i < ARRAY_SIZE(kids->id); i++) 407 kfree(kids->id[i]); 408 kfree(kids); 409 } 410 } 411 412 /* 413 * Clean up the preparse data 414 */ 415 static void asymmetric_key_free_preparse(struct key_preparsed_payload *prep) 416 { 417 struct asymmetric_key_subtype *subtype = prep->payload.data[asym_subtype]; 418 struct asymmetric_key_ids *kids = prep->payload.data[asym_key_ids]; 419 420 pr_devel("==>%s()\n", __func__); 421 422 if (subtype) { 423 subtype->destroy(prep->payload.data[asym_crypto], 424 prep->payload.data[asym_auth]); 425 module_put(subtype->owner); 426 } 427 asymmetric_key_free_kids(kids); 428 kfree(prep->description); 429 } 430 431 /* 432 * dispose of the data dangling from the corpse of a asymmetric key 433 */ 434 static void asymmetric_key_destroy(struct key *key) 435 { 436 struct asymmetric_key_subtype *subtype = asymmetric_key_subtype(key); 437 struct asymmetric_key_ids *kids = key->payload.data[asym_key_ids]; 438 void *data = key->payload.data[asym_crypto]; 439 void *auth = key->payload.data[asym_auth]; 440 441 key->payload.data[asym_crypto] = NULL; 442 key->payload.data[asym_subtype] = NULL; 443 key->payload.data[asym_key_ids] = NULL; 444 key->payload.data[asym_auth] = NULL; 445 446 if (subtype) { 447 subtype->destroy(data, auth); 448 module_put(subtype->owner); 449 } 450 451 asymmetric_key_free_kids(kids); 452 } 453 454 static struct key_restriction *asymmetric_restriction_alloc( 455 key_restrict_link_func_t check, 456 struct key *key) 457 { 458 struct key_restriction *keyres = 459 kzalloc(sizeof(struct key_restriction), GFP_KERNEL); 460 461 if (!keyres) 462 return ERR_PTR(-ENOMEM); 463 464 keyres->check = check; 465 keyres->key = key; 466 keyres->keytype = &key_type_asymmetric; 467 468 return keyres; 469 } 470 471 /* 472 * look up keyring restrict functions for asymmetric keys 473 */ 474 static struct key_restriction *asymmetric_lookup_restriction( 475 const char *restriction) 476 { 477 char *restrict_method; 478 char *parse_buf; 479 char *next; 480 struct key_restriction *ret = ERR_PTR(-EINVAL); 481 482 if (strcmp("builtin_trusted", restriction) == 0) 483 return asymmetric_restriction_alloc( 484 restrict_link_by_builtin_trusted, NULL); 485 486 if (strcmp("builtin_and_secondary_trusted", restriction) == 0) 487 return asymmetric_restriction_alloc( 488 restrict_link_by_builtin_and_secondary_trusted, NULL); 489 490 parse_buf = kstrndup(restriction, PAGE_SIZE, GFP_KERNEL); 491 if (!parse_buf) 492 return ERR_PTR(-ENOMEM); 493 494 next = parse_buf; 495 restrict_method = strsep(&next, ":"); 496 497 if ((strcmp(restrict_method, "key_or_keyring") == 0) && next) { 498 char *key_text; 499 key_serial_t serial; 500 struct key *key; 501 key_restrict_link_func_t link_fn = 502 restrict_link_by_key_or_keyring; 503 bool allow_null_key = false; 504 505 key_text = strsep(&next, ":"); 506 507 if (next) { 508 if (strcmp(next, "chain") != 0) 509 goto out; 510 511 link_fn = restrict_link_by_key_or_keyring_chain; 512 allow_null_key = true; 513 } 514 515 if (kstrtos32(key_text, 0, &serial) < 0) 516 goto out; 517 518 if ((serial == 0) && allow_null_key) { 519 key = NULL; 520 } else { 521 key = key_lookup(serial); 522 if (IS_ERR(key)) { 523 ret = ERR_CAST(key); 524 goto out; 525 } 526 } 527 528 ret = asymmetric_restriction_alloc(link_fn, key); 529 if (IS_ERR(ret)) 530 key_put(key); 531 } 532 533 out: 534 kfree(parse_buf); 535 return ret; 536 } 537 538 int asymmetric_key_eds_op(struct kernel_pkey_params *params, 539 const void *in, void *out) 540 { 541 const struct asymmetric_key_subtype *subtype; 542 struct key *key = params->key; 543 int ret; 544 545 pr_devel("==>%s()\n", __func__); 546 547 if (key->type != &key_type_asymmetric) 548 return -EINVAL; 549 subtype = asymmetric_key_subtype(key); 550 if (!subtype || 551 !key->payload.data[0]) 552 return -EINVAL; 553 if (!subtype->eds_op) 554 return -ENOTSUPP; 555 556 ret = subtype->eds_op(params, in, out); 557 558 pr_devel("<==%s() = %d\n", __func__, ret); 559 return ret; 560 } 561 562 static int asymmetric_key_verify_signature(struct kernel_pkey_params *params, 563 const void *in, const void *in2) 564 { 565 struct public_key_signature sig = { 566 .s_size = params->in2_len, 567 .digest_size = params->in_len, 568 .encoding = params->encoding, 569 .hash_algo = params->hash_algo, 570 .digest = (void *)in, 571 .s = (void *)in2, 572 }; 573 574 return verify_signature(params->key, &sig); 575 } 576 577 struct key_type key_type_asymmetric = { 578 .name = "asymmetric", 579 .preparse = asymmetric_key_preparse, 580 .free_preparse = asymmetric_key_free_preparse, 581 .instantiate = generic_key_instantiate, 582 .match_preparse = asymmetric_key_match_preparse, 583 .match_free = asymmetric_key_match_free, 584 .destroy = asymmetric_key_destroy, 585 .describe = asymmetric_key_describe, 586 .lookup_restriction = asymmetric_lookup_restriction, 587 .asym_query = query_asymmetric_key, 588 .asym_eds_op = asymmetric_key_eds_op, 589 .asym_verify_signature = asymmetric_key_verify_signature, 590 }; 591 EXPORT_SYMBOL_GPL(key_type_asymmetric); 592 593 /** 594 * register_asymmetric_key_parser - Register a asymmetric key blob parser 595 * @parser: The parser to register 596 */ 597 int register_asymmetric_key_parser(struct asymmetric_key_parser *parser) 598 { 599 struct asymmetric_key_parser *cursor; 600 int ret; 601 602 down_write(&asymmetric_key_parsers_sem); 603 604 list_for_each_entry(cursor, &asymmetric_key_parsers, link) { 605 if (strcmp(cursor->name, parser->name) == 0) { 606 pr_err("Asymmetric key parser '%s' already registered\n", 607 parser->name); 608 ret = -EEXIST; 609 goto out; 610 } 611 } 612 613 list_add_tail(&parser->link, &asymmetric_key_parsers); 614 615 pr_notice("Asymmetric key parser '%s' registered\n", parser->name); 616 ret = 0; 617 618 out: 619 up_write(&asymmetric_key_parsers_sem); 620 return ret; 621 } 622 EXPORT_SYMBOL_GPL(register_asymmetric_key_parser); 623 624 /** 625 * unregister_asymmetric_key_parser - Unregister a asymmetric key blob parser 626 * @parser: The parser to unregister 627 */ 628 void unregister_asymmetric_key_parser(struct asymmetric_key_parser *parser) 629 { 630 down_write(&asymmetric_key_parsers_sem); 631 list_del(&parser->link); 632 up_write(&asymmetric_key_parsers_sem); 633 634 pr_notice("Asymmetric key parser '%s' unregistered\n", parser->name); 635 } 636 EXPORT_SYMBOL_GPL(unregister_asymmetric_key_parser); 637 638 /* 639 * Module stuff 640 */ 641 static int __init asymmetric_key_init(void) 642 { 643 return register_key_type(&key_type_asymmetric); 644 } 645 646 static void __exit asymmetric_key_cleanup(void) 647 { 648 unregister_key_type(&key_type_asymmetric); 649 } 650 651 module_init(asymmetric_key_init); 652 module_exit(asymmetric_key_cleanup); 653