Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

encrypted-keys: add key format support

This patch introduces a new parameter, called 'format', that defines the
format of data stored by encrypted keys. The 'default' format identifies
encrypted keys containing only the symmetric key, while other formats can
be defined to support additional information. The 'format' parameter is
written in the datablob produced by commands 'keyctl print' or
'keyctl pipe' and is integrity protected by the HMAC.

Signed-off-by: Roberto Sassu <roberto.sassu@polito.it>
Acked-by: Gianluca Ramunno <ramunno@polito.it>
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com>

authored by

Roberto Sassu and committed by
Mimi Zohar
4e561d38 7103dff0

+143 -61
+31 -19
Documentation/security/keys-trusted-encrypted.txt
··· 53 53 should therefore be loaded in as secure a way as possible, preferably early in 54 54 boot. 55 55 56 - Usage: 57 - keyctl add encrypted name "new key-type:master-key-name keylen" ring 58 - keyctl add encrypted name "load hex_blob" ring 59 - keyctl update keyid "update key-type:master-key-name" 56 + The decrypted portion of encrypted keys can contain either a simple symmetric 57 + key or a more complex structure. The format of the more complex structure is 58 + application specific, which is identified by 'format'. 60 59 61 - where 'key-type' is either 'trusted' or 'user'. 60 + Usage: 61 + keyctl add encrypted name "new [format] key-type:master-key-name keylen" 62 + ring 63 + keyctl add encrypted name "load hex_blob" ring 64 + keyctl update keyid "update key-type:master-key-name" 65 + 66 + format:= 'default' 67 + key-type:= 'trusted' | 'user' 68 + 62 69 63 70 Examples of trusted and encrypted key usage: 64 71 ··· 121 114 7ef6a24defe4846104209bf0c3eced7fa1a672ed5b125fc9d8cd88b476a658a4434644ef 122 115 df8ae9a178e9f83ba9f08d10fa47e4226b98b0702f06b3b8 123 116 124 - Create and save an encrypted key "evm" using the above trusted key "kmk": 117 + The initial consumer of trusted keys is EVM, which at boot time needs a high 118 + quality symmetric key for HMAC protection of file metadata. The use of a 119 + trusted key provides strong guarantees that the EVM key has not been 120 + compromised by a user level problem, and when sealed to specific boot PCR 121 + values, protects against boot and offline attacks. Create and save an 122 + encrypted key "evm" using the above trusted key "kmk": 125 123 124 + option 1: omitting 'format' 126 125 $ keyctl add encrypted evm "new trusted:kmk 32" @u 127 126 159771175 128 127 128 + option 2: explicitly defining 'format' as 'default' 129 + $ keyctl add encrypted evm "new default trusted:kmk 32" @u 130 + 159771175 131 + 129 132 $ keyctl print 159771175 130 - trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382dbbc55 131 - be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e024717c64 132 - 5972dcb82ab2dde83376d82b2e3c09ffc 133 + default trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b3 134 + 82dbbc55be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e0 135 + 24717c64 5972dcb82ab2dde83376d82b2e3c09ffc 133 136 134 137 $ keyctl pipe 159771175 > evm.blob 135 138 ··· 149 132 831684262 150 133 151 134 $ keyctl print 831684262 152 - trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b382dbbc55 153 - be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e024717c64 154 - 5972dcb82ab2dde83376d82b2e3c09ffc 135 + default trusted:kmk 32 2375725ad57798846a9bbd240de8906f006e66c03af53b1b3 136 + 82dbbc55be2a44616e4959430436dc4f2a7a9659aa60bb4652aeb2120f149ed197c564e0 137 + 24717c64 5972dcb82ab2dde83376d82b2e3c09ffc 155 138 156 - 157 - The initial consumer of trusted keys is EVM, which at boot time needs a high 158 - quality symmetric key for HMAC protection of file metadata. The use of a 159 - trusted key provides strong guarantees that the EVM key has not been 160 - compromised by a user level problem, and when sealed to specific boot PCR 161 - values, protects against boot and offline attacks. Other uses for trusted and 162 - encrypted keys, such as for disk and file encryption are anticipated. 139 + Other uses for trusted and encrypted keys, such as for disk and file encryption 140 + are anticipated.
+11 -2
include/keys/encrypted-type.h
··· 1 1 /* 2 2 * Copyright (C) 2010 IBM Corporation 3 - * Author: Mimi Zohar <zohar@us.ibm.com> 3 + * Copyright (C) 2010 Politecnico di Torino, Italy 4 + * TORSEC group -- http://security.polito.it 5 + * 6 + * Authors: 7 + * Mimi Zohar <zohar@us.ibm.com> 8 + * Roberto Sassu <roberto.sassu@polito.it> 4 9 * 5 10 * This program is free software; you can redistribute it and/or modify 6 11 * it under the terms of the GNU General Public License as published by ··· 20 15 21 16 struct encrypted_key_payload { 22 17 struct rcu_head rcu; 18 + char *format; /* datablob: format */ 23 19 char *master_desc; /* datablob: master key name */ 24 20 char *datalen; /* datablob: decrypted key length */ 25 21 u8 *iv; /* datablob: iv */ 26 22 u8 *encrypted_data; /* datablob: encrypted data */ 27 23 unsigned short datablob_len; /* length of datablob */ 28 24 unsigned short decrypted_datalen; /* decrypted data length */ 29 - u8 decrypted_data[0]; /* decrypted data + datablob + hmac */ 25 + unsigned short payload_datalen; /* payload data length */ 26 + unsigned short encrypted_key_format; /* encrypted key format */ 27 + u8 *decrypted_data; /* decrypted data */ 28 + u8 payload_data[0]; /* payload data + datablob + hmac */ 30 29 }; 31 30 32 31 extern struct key_type key_type_encrypted;
+101 -40
security/keys/encrypted.c
··· 1 1 /* 2 2 * Copyright (C) 2010 IBM Corporation 3 + * Copyright (C) 2010 Politecnico di Torino, Italy 4 + * TORSEC group -- http://security.polito.it 3 5 * 4 - * Author: 6 + * Authors: 5 7 * Mimi Zohar <zohar@us.ibm.com> 8 + * Roberto Sassu <roberto.sassu@polito.it> 6 9 * 7 10 * This program is free software; you can redistribute it and/or modify 8 11 * it under the terms of the GNU General Public License as published by ··· 40 37 static const char hash_alg[] = "sha256"; 41 38 static const char hmac_alg[] = "hmac(sha256)"; 42 39 static const char blkcipher_alg[] = "cbc(aes)"; 40 + static const char key_format_default[] = "default"; 43 41 static unsigned int ivsize; 44 42 static int blksize; 45 43 ··· 60 56 61 57 enum { 62 58 Opt_err = -1, Opt_new, Opt_load, Opt_update 59 + }; 60 + 61 + enum { 62 + Opt_error = -1, Opt_default 63 + }; 64 + 65 + static const match_table_t key_format_tokens = { 66 + {Opt_default, "default"}, 67 + {Opt_error, NULL} 63 68 }; 64 69 65 70 static const match_table_t key_tokens = { ··· 131 118 * datablob_parse - parse the keyctl data 132 119 * 133 120 * datablob format: 134 - * new <master-key name> <decrypted data length> 135 - * load <master-key name> <decrypted data length> <encrypted iv + data> 121 + * new [<format>] <master-key name> <decrypted data length> 122 + * load [<format>] <master-key name> <decrypted data length> 123 + * <encrypted iv + data> 136 124 * update <new-master-key name> 137 125 * 138 126 * Tokenizes a copy of the keyctl data, returning a pointer to each token, ··· 141 127 * 142 128 * On success returns 0, otherwise -EINVAL. 143 129 */ 144 - static int datablob_parse(char *datablob, char **master_desc, 145 - char **decrypted_datalen, char **hex_encoded_iv) 130 + static int datablob_parse(char *datablob, const char **format, 131 + char **master_desc, char **decrypted_datalen, 132 + char **hex_encoded_iv) 146 133 { 147 134 substring_t args[MAX_OPT_ARGS]; 148 135 int ret = -EINVAL; 149 136 int key_cmd; 150 - char *keyword; 137 + int key_format; 138 + char *p, *keyword; 151 139 152 140 keyword = strsep(&datablob, " \t"); 153 141 if (!keyword) { ··· 158 142 } 159 143 key_cmd = match_token(keyword, key_tokens, args); 160 144 161 - *master_desc = strsep(&datablob, " \t"); 145 + /* Get optional format: default */ 146 + p = strsep(&datablob, " \t"); 147 + if (!p) { 148 + pr_err("encrypted_key: insufficient parameters specified\n"); 149 + return ret; 150 + } 151 + 152 + key_format = match_token(p, key_format_tokens, args); 153 + switch (key_format) { 154 + case Opt_default: 155 + *format = p; 156 + *master_desc = strsep(&datablob, " \t"); 157 + break; 158 + case Opt_error: 159 + *master_desc = p; 160 + break; 161 + } 162 + 162 163 if (!*master_desc) { 163 164 pr_info("encrypted_key: master key parameter is missing\n"); 164 165 goto out; ··· 253 220 ascii_buf[asciiblob_len] = '\0'; 254 221 255 222 /* copy datablob master_desc and datalen strings */ 256 - len = sprintf(ascii_buf, "%s %s ", epayload->master_desc, 257 - epayload->datalen); 223 + len = sprintf(ascii_buf, "%s %s %s ", epayload->format, 224 + epayload->master_desc, epayload->datalen); 258 225 259 226 /* convert the hex encoded iv, encrypted-data and HMAC to ascii */ 260 227 bufp = &ascii_buf[len]; ··· 497 464 if (ret < 0) 498 465 goto out; 499 466 500 - digest = epayload->master_desc + epayload->datablob_len; 467 + digest = epayload->format + epayload->datablob_len; 501 468 ret = calc_hmac(digest, derived_key, sizeof derived_key, 502 - epayload->master_desc, epayload->datablob_len); 469 + epayload->format, epayload->datablob_len); 503 470 if (!ret) 504 471 dump_hmac(NULL, digest, HASH_SIZE); 505 472 out: ··· 508 475 509 476 /* verify HMAC before decrypting encrypted key */ 510 477 static int datablob_hmac_verify(struct encrypted_key_payload *epayload, 511 - const u8 *master_key, size_t master_keylen) 478 + const u8 *format, const u8 *master_key, 479 + size_t master_keylen) 512 480 { 513 481 u8 derived_key[HASH_SIZE]; 514 482 u8 digest[HASH_SIZE]; 515 483 int ret; 484 + char *p; 485 + unsigned short len; 516 486 517 487 ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen); 518 488 if (ret < 0) 519 489 goto out; 520 490 521 - ret = calc_hmac(digest, derived_key, sizeof derived_key, 522 - epayload->master_desc, epayload->datablob_len); 491 + len = epayload->datablob_len; 492 + if (!format) { 493 + p = epayload->master_desc; 494 + len -= strlen(epayload->format) + 1; 495 + } else 496 + p = epayload->format; 497 + 498 + ret = calc_hmac(digest, derived_key, sizeof derived_key, p, len); 523 499 if (ret < 0) 524 500 goto out; 525 - ret = memcmp(digest, epayload->master_desc + epayload->datablob_len, 501 + ret = memcmp(digest, epayload->format + epayload->datablob_len, 526 502 sizeof digest); 527 503 if (ret) { 528 504 ret = -EINVAL; 529 505 dump_hmac("datablob", 530 - epayload->master_desc + epayload->datablob_len, 506 + epayload->format + epayload->datablob_len, 531 507 HASH_SIZE); 532 508 dump_hmac("calc", digest, HASH_SIZE); 533 509 } ··· 581 539 582 540 /* Allocate memory for decrypted key and datablob. */ 583 541 static struct encrypted_key_payload *encrypted_key_alloc(struct key *key, 542 + const char *format, 584 543 const char *master_desc, 585 544 const char *datalen) 586 545 { 587 546 struct encrypted_key_payload *epayload = NULL; 588 547 unsigned short datablob_len; 589 548 unsigned short decrypted_datalen; 549 + unsigned short payload_datalen; 590 550 unsigned int encrypted_datalen; 551 + unsigned int format_len; 591 552 long dlen; 592 553 int ret; 593 554 ··· 598 553 if (ret < 0 || dlen < MIN_DATA_SIZE || dlen > MAX_DATA_SIZE) 599 554 return ERR_PTR(-EINVAL); 600 555 556 + format_len = (!format) ? strlen(key_format_default) : strlen(format); 601 557 decrypted_datalen = dlen; 558 + payload_datalen = decrypted_datalen; 602 559 encrypted_datalen = roundup(decrypted_datalen, blksize); 603 560 604 - datablob_len = strlen(master_desc) + 1 + strlen(datalen) + 1 605 - + ivsize + 1 + encrypted_datalen; 561 + datablob_len = format_len + 1 + strlen(master_desc) + 1 562 + + strlen(datalen) + 1 + ivsize + 1 + encrypted_datalen; 606 563 607 - ret = key_payload_reserve(key, decrypted_datalen + datablob_len 564 + ret = key_payload_reserve(key, payload_datalen + datablob_len 608 565 + HASH_SIZE + 1); 609 566 if (ret < 0) 610 567 return ERR_PTR(ret); 611 568 612 - epayload = kzalloc(sizeof(*epayload) + decrypted_datalen + 569 + epayload = kzalloc(sizeof(*epayload) + payload_datalen + 613 570 datablob_len + HASH_SIZE + 1, GFP_KERNEL); 614 571 if (!epayload) 615 572 return ERR_PTR(-ENOMEM); 616 573 574 + epayload->payload_datalen = payload_datalen; 617 575 epayload->decrypted_datalen = decrypted_datalen; 618 576 epayload->datablob_len = datablob_len; 619 577 return epayload; 620 578 } 621 579 622 580 static int encrypted_key_decrypt(struct encrypted_key_payload *epayload, 623 - const char *hex_encoded_iv) 581 + const char *format, const char *hex_encoded_iv) 624 582 { 625 583 struct key *mkey; 626 584 u8 derived_key[HASH_SIZE]; ··· 644 596 hex2bin(epayload->iv, hex_encoded_iv, ivsize); 645 597 hex2bin(epayload->encrypted_data, hex_encoded_data, encrypted_datalen); 646 598 647 - hmac = epayload->master_desc + epayload->datablob_len; 599 + hmac = epayload->format + epayload->datablob_len; 648 600 hex2bin(hmac, hex_encoded_data + (encrypted_datalen * 2), HASH_SIZE); 649 601 650 602 mkey = request_master_key(epayload, &master_key, &master_keylen); 651 603 if (IS_ERR(mkey)) 652 604 return PTR_ERR(mkey); 653 605 654 - ret = datablob_hmac_verify(epayload, master_key, master_keylen); 606 + ret = datablob_hmac_verify(epayload, format, master_key, master_keylen); 655 607 if (ret < 0) { 656 608 pr_err("encrypted_key: bad hmac (%d)\n", ret); 657 609 goto out; ··· 671 623 } 672 624 673 625 static void __ekey_init(struct encrypted_key_payload *epayload, 674 - const char *master_desc, const char *datalen) 626 + const char *format, const char *master_desc, 627 + const char *datalen) 675 628 { 676 - epayload->master_desc = epayload->decrypted_data 677 - + epayload->decrypted_datalen; 629 + unsigned int format_len; 630 + 631 + format_len = (!format) ? strlen(key_format_default) : strlen(format); 632 + epayload->format = epayload->payload_data + epayload->payload_datalen; 633 + epayload->master_desc = epayload->format + format_len + 1; 678 634 epayload->datalen = epayload->master_desc + strlen(master_desc) + 1; 679 635 epayload->iv = epayload->datalen + strlen(datalen) + 1; 680 636 epayload->encrypted_data = epayload->iv + ivsize + 1; 637 + epayload->decrypted_data = epayload->payload_data; 681 638 639 + if (!format) 640 + memcpy(epayload->format, key_format_default, format_len); 641 + else 642 + memcpy(epayload->format, format, format_len); 682 643 memcpy(epayload->master_desc, master_desc, strlen(master_desc)); 683 644 memcpy(epayload->datalen, datalen, strlen(datalen)); 684 645 } ··· 699 642 * itself. For an old key, decrypt the hex encoded data. 700 643 */ 701 644 static int encrypted_init(struct encrypted_key_payload *epayload, 702 - const char *master_desc, const char *datalen, 703 - const char *hex_encoded_iv) 645 + const char *format, const char *master_desc, 646 + const char *datalen, const char *hex_encoded_iv) 704 647 { 705 648 int ret = 0; 706 649 707 - __ekey_init(epayload, master_desc, datalen); 650 + __ekey_init(epayload, format, master_desc, datalen); 708 651 if (!hex_encoded_iv) { 709 652 get_random_bytes(epayload->iv, ivsize); 710 653 711 654 get_random_bytes(epayload->decrypted_data, 712 655 epayload->decrypted_datalen); 713 656 } else 714 - ret = encrypted_key_decrypt(epayload, hex_encoded_iv); 657 + ret = encrypted_key_decrypt(epayload, format, hex_encoded_iv); 715 658 return ret; 716 659 } 717 660 ··· 728 671 { 729 672 struct encrypted_key_payload *epayload = NULL; 730 673 char *datablob = NULL; 674 + const char *format = NULL; 731 675 char *master_desc = NULL; 732 676 char *decrypted_datalen = NULL; 733 677 char *hex_encoded_iv = NULL; ··· 742 684 return -ENOMEM; 743 685 datablob[datalen] = 0; 744 686 memcpy(datablob, data, datalen); 745 - ret = datablob_parse(datablob, &master_desc, &decrypted_datalen, 746 - &hex_encoded_iv); 687 + ret = datablob_parse(datablob, &format, &master_desc, 688 + &decrypted_datalen, &hex_encoded_iv); 747 689 if (ret < 0) 748 690 goto out; 749 691 750 - epayload = encrypted_key_alloc(key, master_desc, decrypted_datalen); 692 + epayload = encrypted_key_alloc(key, format, master_desc, 693 + decrypted_datalen); 751 694 if (IS_ERR(epayload)) { 752 695 ret = PTR_ERR(epayload); 753 696 goto out; 754 697 } 755 - ret = encrypted_init(epayload, master_desc, decrypted_datalen, 698 + ret = encrypted_init(epayload, format, master_desc, decrypted_datalen, 756 699 hex_encoded_iv); 757 700 if (ret < 0) { 758 701 kfree(epayload); ··· 790 731 struct encrypted_key_payload *new_epayload; 791 732 char *buf; 792 733 char *new_master_desc = NULL; 734 + const char *format = NULL; 793 735 int ret = 0; 794 736 795 737 if (datalen <= 0 || datalen > 32767 || !data) ··· 802 742 803 743 buf[datalen] = 0; 804 744 memcpy(buf, data, datalen); 805 - ret = datablob_parse(buf, &new_master_desc, NULL, NULL); 745 + ret = datablob_parse(buf, &format, &new_master_desc, NULL, NULL); 806 746 if (ret < 0) 807 747 goto out; 808 748 ··· 810 750 if (ret < 0) 811 751 goto out; 812 752 813 - new_epayload = encrypted_key_alloc(key, new_master_desc, 814 - epayload->datalen); 753 + new_epayload = encrypted_key_alloc(key, epayload->format, 754 + new_master_desc, epayload->datalen); 815 755 if (IS_ERR(new_epayload)) { 816 756 ret = PTR_ERR(new_epayload); 817 757 goto out; 818 758 } 819 759 820 - __ekey_init(new_epayload, new_master_desc, epayload->datalen); 760 + __ekey_init(new_epayload, epayload->format, new_master_desc, 761 + epayload->datalen); 821 762 822 763 memcpy(new_epayload->iv, epayload->iv, ivsize); 823 - memcpy(new_epayload->decrypted_data, epayload->decrypted_data, 824 - epayload->decrypted_datalen); 764 + memcpy(new_epayload->payload_data, epayload->payload_data, 765 + epayload->payload_datalen); 825 766 826 767 rcu_assign_pointer(key->payload.data, new_epayload); 827 768 call_rcu(&epayload->rcu, encrypted_rcu_free);