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