aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys/encrypted.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/keys/encrypted.c')
-rw-r--r--security/keys/encrypted.c141
1 files changed, 101 insertions, 40 deletions
diff --git a/security/keys/encrypted.c b/security/keys/encrypted.c
index f36a105de791..89981c987ba7 100644
--- a/security/keys/encrypted.c
+++ b/security/keys/encrypted.c
@@ -1,8 +1,11 @@
1/* 1/*
2 * Copyright (C) 2010 IBM Corporation 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 * Mimi Zohar <zohar@us.ibm.com> 7 * Mimi Zohar <zohar@us.ibm.com>
8 * Roberto Sassu <roberto.sassu@polito.it>
6 * 9 *
7 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
@@ -37,6 +40,7 @@ static const char KEY_USER_PREFIX[] = "user:";
37static const char hash_alg[] = "sha256"; 40static const char hash_alg[] = "sha256";
38static const char hmac_alg[] = "hmac(sha256)"; 41static const char hmac_alg[] = "hmac(sha256)";
39static const char blkcipher_alg[] = "cbc(aes)"; 42static const char blkcipher_alg[] = "cbc(aes)";
43static const char key_format_default[] = "default";
40static unsigned int ivsize; 44static unsigned int ivsize;
41static int blksize; 45static int blksize;
42 46
@@ -58,6 +62,15 @@ enum {
58 Opt_err = -1, Opt_new, Opt_load, Opt_update 62 Opt_err = -1, Opt_new, Opt_load, Opt_update
59}; 63};
60 64
65enum {
66 Opt_error = -1, Opt_default
67};
68
69static const match_table_t key_format_tokens = {
70 {Opt_default, "default"},
71 {Opt_error, NULL}
72};
73
61static const match_table_t key_tokens = { 74static const match_table_t key_tokens = {
62 {Opt_new, "new"}, 75 {Opt_new, "new"},
63 {Opt_load, "load"}, 76 {Opt_load, "load"},
@@ -118,8 +131,9 @@ out:
118 * datablob_parse - parse the keyctl data 131 * datablob_parse - parse the keyctl data
119 * 132 *
120 * datablob format: 133 * datablob format:
121 * new <master-key name> <decrypted data length> 134 * new [<format>] <master-key name> <decrypted data length>
122 * load <master-key name> <decrypted data length> <encrypted iv + data> 135 * load [<format>] <master-key name> <decrypted data length>
136 * <encrypted iv + data>
123 * update <new-master-key name> 137 * update <new-master-key name>
124 * 138 *
125 * Tokenizes a copy of the keyctl data, returning a pointer to each token, 139 * Tokenizes a copy of the keyctl data, returning a pointer to each token,
@@ -127,13 +141,15 @@ out:
127 * 141 *
128 * On success returns 0, otherwise -EINVAL. 142 * On success returns 0, otherwise -EINVAL.
129 */ 143 */
130static int datablob_parse(char *datablob, char **master_desc, 144static int datablob_parse(char *datablob, const char **format,
131 char **decrypted_datalen, char **hex_encoded_iv) 145 char **master_desc, char **decrypted_datalen,
146 char **hex_encoded_iv)
132{ 147{
133 substring_t args[MAX_OPT_ARGS]; 148 substring_t args[MAX_OPT_ARGS];
134 int ret = -EINVAL; 149 int ret = -EINVAL;
135 int key_cmd; 150 int key_cmd;
136 char *keyword; 151 int key_format;
152 char *p, *keyword;
137 153
138 keyword = strsep(&datablob, " \t"); 154 keyword = strsep(&datablob, " \t");
139 if (!keyword) { 155 if (!keyword) {
@@ -142,7 +158,24 @@ static int datablob_parse(char *datablob, char **master_desc,
142 } 158 }
143 key_cmd = match_token(keyword, key_tokens, args); 159 key_cmd = match_token(keyword, key_tokens, args);
144 160
145 *master_desc = strsep(&datablob, " \t"); 161 /* Get optional format: default */
162 p = strsep(&datablob, " \t");
163 if (!p) {
164 pr_err("encrypted_key: insufficient parameters specified\n");
165 return ret;
166 }
167
168 key_format = match_token(p, key_format_tokens, args);
169 switch (key_format) {
170 case Opt_default:
171 *format = p;
172 *master_desc = strsep(&datablob, " \t");
173 break;
174 case Opt_error:
175 *master_desc = p;
176 break;
177 }
178
146 if (!*master_desc) { 179 if (!*master_desc) {
147 pr_info("encrypted_key: master key parameter is missing\n"); 180 pr_info("encrypted_key: master key parameter is missing\n");
148 goto out; 181 goto out;
@@ -220,8 +253,8 @@ static char *datablob_format(struct encrypted_key_payload *epayload,
220 ascii_buf[asciiblob_len] = '\0'; 253 ascii_buf[asciiblob_len] = '\0';
221 254
222 /* copy datablob master_desc and datalen strings */ 255 /* copy datablob master_desc and datalen strings */
223 len = sprintf(ascii_buf, "%s %s ", epayload->master_desc, 256 len = sprintf(ascii_buf, "%s %s %s ", epayload->format,
224 epayload->datalen); 257 epayload->master_desc, epayload->datalen);
225 258
226 /* convert the hex encoded iv, encrypted-data and HMAC to ascii */ 259 /* convert the hex encoded iv, encrypted-data and HMAC to ascii */
227 bufp = &ascii_buf[len]; 260 bufp = &ascii_buf[len];
@@ -464,9 +497,9 @@ static int datablob_hmac_append(struct encrypted_key_payload *epayload,
464 if (ret < 0) 497 if (ret < 0)
465 goto out; 498 goto out;
466 499
467 digest = epayload->master_desc + epayload->datablob_len; 500 digest = epayload->format + epayload->datablob_len;
468 ret = calc_hmac(digest, derived_key, sizeof derived_key, 501 ret = calc_hmac(digest, derived_key, sizeof derived_key,
469 epayload->master_desc, epayload->datablob_len); 502 epayload->format, epayload->datablob_len);
470 if (!ret) 503 if (!ret)
471 dump_hmac(NULL, digest, HASH_SIZE); 504 dump_hmac(NULL, digest, HASH_SIZE);
472out: 505out:
@@ -475,26 +508,35 @@ out:
475 508
476/* verify HMAC before decrypting encrypted key */ 509/* verify HMAC before decrypting encrypted key */
477static int datablob_hmac_verify(struct encrypted_key_payload *epayload, 510static int datablob_hmac_verify(struct encrypted_key_payload *epayload,
478 const u8 *master_key, size_t master_keylen) 511 const u8 *format, const u8 *master_key,
512 size_t master_keylen)
479{ 513{
480 u8 derived_key[HASH_SIZE]; 514 u8 derived_key[HASH_SIZE];
481 u8 digest[HASH_SIZE]; 515 u8 digest[HASH_SIZE];
482 int ret; 516 int ret;
517 char *p;
518 unsigned short len;
483 519
484 ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen); 520 ret = get_derived_key(derived_key, AUTH_KEY, master_key, master_keylen);
485 if (ret < 0) 521 if (ret < 0)
486 goto out; 522 goto out;
487 523
488 ret = calc_hmac(digest, derived_key, sizeof derived_key, 524 len = epayload->datablob_len;
489 epayload->master_desc, epayload->datablob_len); 525 if (!format) {
526 p = epayload->master_desc;
527 len -= strlen(epayload->format) + 1;
528 } else
529 p = epayload->format;
530
531 ret = calc_hmac(digest, derived_key, sizeof derived_key, p, len);
490 if (ret < 0) 532 if (ret < 0)
491 goto out; 533 goto out;
492 ret = memcmp(digest, epayload->master_desc + epayload->datablob_len, 534 ret = memcmp(digest, epayload->format + epayload->datablob_len,
493 sizeof digest); 535 sizeof digest);
494 if (ret) { 536 if (ret) {
495 ret = -EINVAL; 537 ret = -EINVAL;
496 dump_hmac("datablob", 538 dump_hmac("datablob",
497 epayload->master_desc + epayload->datablob_len, 539 epayload->format + epayload->datablob_len,
498 HASH_SIZE); 540 HASH_SIZE);
499 dump_hmac("calc", digest, HASH_SIZE); 541 dump_hmac("calc", digest, HASH_SIZE);
500 } 542 }
@@ -539,13 +581,16 @@ out:
539 581
540/* Allocate memory for decrypted key and datablob. */ 582/* Allocate memory for decrypted key and datablob. */
541static struct encrypted_key_payload *encrypted_key_alloc(struct key *key, 583static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
584 const char *format,
542 const char *master_desc, 585 const char *master_desc,
543 const char *datalen) 586 const char *datalen)
544{ 587{
545 struct encrypted_key_payload *epayload = NULL; 588 struct encrypted_key_payload *epayload = NULL;
546 unsigned short datablob_len; 589 unsigned short datablob_len;
547 unsigned short decrypted_datalen; 590 unsigned short decrypted_datalen;
591 unsigned short payload_datalen;
548 unsigned int encrypted_datalen; 592 unsigned int encrypted_datalen;
593 unsigned int format_len;
549 long dlen; 594 long dlen;
550 int ret; 595 int ret;
551 596
@@ -553,29 +598,32 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
553 if (ret < 0 || dlen < MIN_DATA_SIZE || dlen > MAX_DATA_SIZE) 598 if (ret < 0 || dlen < MIN_DATA_SIZE || dlen > MAX_DATA_SIZE)
554 return ERR_PTR(-EINVAL); 599 return ERR_PTR(-EINVAL);
555 600
601 format_len = (!format) ? strlen(key_format_default) : strlen(format);
556 decrypted_datalen = dlen; 602 decrypted_datalen = dlen;
603 payload_datalen = decrypted_datalen;
557 encrypted_datalen = roundup(decrypted_datalen, blksize); 604 encrypted_datalen = roundup(decrypted_datalen, blksize);
558 605
559 datablob_len = strlen(master_desc) + 1 + strlen(datalen) + 1 606 datablob_len = format_len + 1 + strlen(master_desc) + 1
560 + ivsize + 1 + encrypted_datalen; 607 + strlen(datalen) + 1 + ivsize + 1 + encrypted_datalen;
561 608
562 ret = key_payload_reserve(key, decrypted_datalen + datablob_len 609 ret = key_payload_reserve(key, payload_datalen + datablob_len
563 + HASH_SIZE + 1); 610 + HASH_SIZE + 1);
564 if (ret < 0) 611 if (ret < 0)
565 return ERR_PTR(ret); 612 return ERR_PTR(ret);
566 613
567 epayload = kzalloc(sizeof(*epayload) + decrypted_datalen + 614 epayload = kzalloc(sizeof(*epayload) + payload_datalen +
568 datablob_len + HASH_SIZE + 1, GFP_KERNEL); 615 datablob_len + HASH_SIZE + 1, GFP_KERNEL);
569 if (!epayload) 616 if (!epayload)
570 return ERR_PTR(-ENOMEM); 617 return ERR_PTR(-ENOMEM);
571 618
619 epayload->payload_datalen = payload_datalen;
572 epayload->decrypted_datalen = decrypted_datalen; 620 epayload->decrypted_datalen = decrypted_datalen;
573 epayload->datablob_len = datablob_len; 621 epayload->datablob_len = datablob_len;
574 return epayload; 622 return epayload;
575} 623}
576 624
577static int encrypted_key_decrypt(struct encrypted_key_payload *epayload, 625static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
578 const char *hex_encoded_iv) 626 const char *format, const char *hex_encoded_iv)
579{ 627{
580 struct key *mkey; 628 struct key *mkey;
581 u8 derived_key[HASH_SIZE]; 629 u8 derived_key[HASH_SIZE];
@@ -596,14 +644,14 @@ static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
596 hex2bin(epayload->iv, hex_encoded_iv, ivsize); 644 hex2bin(epayload->iv, hex_encoded_iv, ivsize);
597 hex2bin(epayload->encrypted_data, hex_encoded_data, encrypted_datalen); 645 hex2bin(epayload->encrypted_data, hex_encoded_data, encrypted_datalen);
598 646
599 hmac = epayload->master_desc + epayload->datablob_len; 647 hmac = epayload->format + epayload->datablob_len;
600 hex2bin(hmac, hex_encoded_data + (encrypted_datalen * 2), HASH_SIZE); 648 hex2bin(hmac, hex_encoded_data + (encrypted_datalen * 2), HASH_SIZE);
601 649
602 mkey = request_master_key(epayload, &master_key, &master_keylen); 650 mkey = request_master_key(epayload, &master_key, &master_keylen);
603 if (IS_ERR(mkey)) 651 if (IS_ERR(mkey))
604 return PTR_ERR(mkey); 652 return PTR_ERR(mkey);
605 653
606 ret = datablob_hmac_verify(epayload, master_key, master_keylen); 654 ret = datablob_hmac_verify(epayload, format, master_key, master_keylen);
607 if (ret < 0) { 655 if (ret < 0) {
608 pr_err("encrypted_key: bad hmac (%d)\n", ret); 656 pr_err("encrypted_key: bad hmac (%d)\n", ret);
609 goto out; 657 goto out;
@@ -623,14 +671,23 @@ out:
623} 671}
624 672
625static void __ekey_init(struct encrypted_key_payload *epayload, 673static void __ekey_init(struct encrypted_key_payload *epayload,
626 const char *master_desc, const char *datalen) 674 const char *format, const char *master_desc,
675 const char *datalen)
627{ 676{
628 epayload->master_desc = epayload->decrypted_data 677 unsigned int format_len;
629 + epayload->decrypted_datalen; 678
679 format_len = (!format) ? strlen(key_format_default) : strlen(format);
680 epayload->format = epayload->payload_data + epayload->payload_datalen;
681 epayload->master_desc = epayload->format + format_len + 1;
630 epayload->datalen = epayload->master_desc + strlen(master_desc) + 1; 682 epayload->datalen = epayload->master_desc + strlen(master_desc) + 1;
631 epayload->iv = epayload->datalen + strlen(datalen) + 1; 683 epayload->iv = epayload->datalen + strlen(datalen) + 1;
632 epayload->encrypted_data = epayload->iv + ivsize + 1; 684 epayload->encrypted_data = epayload->iv + ivsize + 1;
685 epayload->decrypted_data = epayload->payload_data;
633 686
687 if (!format)
688 memcpy(epayload->format, key_format_default, format_len);
689 else
690 memcpy(epayload->format, format, format_len);
634 memcpy(epayload->master_desc, master_desc, strlen(master_desc)); 691 memcpy(epayload->master_desc, master_desc, strlen(master_desc));
635 memcpy(epayload->datalen, datalen, strlen(datalen)); 692 memcpy(epayload->datalen, datalen, strlen(datalen));
636} 693}
@@ -642,19 +699,19 @@ static void __ekey_init(struct encrypted_key_payload *epayload,
642 * itself. For an old key, decrypt the hex encoded data. 699 * itself. For an old key, decrypt the hex encoded data.
643 */ 700 */
644static int encrypted_init(struct encrypted_key_payload *epayload, 701static int encrypted_init(struct encrypted_key_payload *epayload,
645 const char *master_desc, const char *datalen, 702 const char *format, const char *master_desc,
646 const char *hex_encoded_iv) 703 const char *datalen, const char *hex_encoded_iv)
647{ 704{
648 int ret = 0; 705 int ret = 0;
649 706
650 __ekey_init(epayload, master_desc, datalen); 707 __ekey_init(epayload, format, master_desc, datalen);
651 if (!hex_encoded_iv) { 708 if (!hex_encoded_iv) {
652 get_random_bytes(epayload->iv, ivsize); 709 get_random_bytes(epayload->iv, ivsize);
653 710
654 get_random_bytes(epayload->decrypted_data, 711 get_random_bytes(epayload->decrypted_data,
655 epayload->decrypted_datalen); 712 epayload->decrypted_datalen);
656 } else 713 } else
657 ret = encrypted_key_decrypt(epayload, hex_encoded_iv); 714 ret = encrypted_key_decrypt(epayload, format, hex_encoded_iv);
658 return ret; 715 return ret;
659} 716}
660 717
@@ -671,6 +728,7 @@ static int encrypted_instantiate(struct key *key, const void *data,
671{ 728{
672 struct encrypted_key_payload *epayload = NULL; 729 struct encrypted_key_payload *epayload = NULL;
673 char *datablob = NULL; 730 char *datablob = NULL;
731 const char *format = NULL;
674 char *master_desc = NULL; 732 char *master_desc = NULL;
675 char *decrypted_datalen = NULL; 733 char *decrypted_datalen = NULL;
676 char *hex_encoded_iv = NULL; 734 char *hex_encoded_iv = NULL;
@@ -684,17 +742,18 @@ static int encrypted_instantiate(struct key *key, const void *data,
684 return -ENOMEM; 742 return -ENOMEM;
685 datablob[datalen] = 0; 743 datablob[datalen] = 0;
686 memcpy(datablob, data, datalen); 744 memcpy(datablob, data, datalen);
687 ret = datablob_parse(datablob, &master_desc, &decrypted_datalen, 745 ret = datablob_parse(datablob, &format, &master_desc,
688 &hex_encoded_iv); 746 &decrypted_datalen, &hex_encoded_iv);
689 if (ret < 0) 747 if (ret < 0)
690 goto out; 748 goto out;
691 749
692 epayload = encrypted_key_alloc(key, master_desc, decrypted_datalen); 750 epayload = encrypted_key_alloc(key, format, master_desc,
751 decrypted_datalen);
693 if (IS_ERR(epayload)) { 752 if (IS_ERR(epayload)) {
694 ret = PTR_ERR(epayload); 753 ret = PTR_ERR(epayload);
695 goto out; 754 goto out;
696 } 755 }
697 ret = encrypted_init(epayload, master_desc, decrypted_datalen, 756 ret = encrypted_init(epayload, format, master_desc, decrypted_datalen,
698 hex_encoded_iv); 757 hex_encoded_iv);
699 if (ret < 0) { 758 if (ret < 0) {
700 kfree(epayload); 759 kfree(epayload);
@@ -731,6 +790,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
731 struct encrypted_key_payload *new_epayload; 790 struct encrypted_key_payload *new_epayload;
732 char *buf; 791 char *buf;
733 char *new_master_desc = NULL; 792 char *new_master_desc = NULL;
793 const char *format = NULL;
734 int ret = 0; 794 int ret = 0;
735 795
736 if (datalen <= 0 || datalen > 32767 || !data) 796 if (datalen <= 0 || datalen > 32767 || !data)
@@ -742,7 +802,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
742 802
743 buf[datalen] = 0; 803 buf[datalen] = 0;
744 memcpy(buf, data, datalen); 804 memcpy(buf, data, datalen);
745 ret = datablob_parse(buf, &new_master_desc, NULL, NULL); 805 ret = datablob_parse(buf, &format, &new_master_desc, NULL, NULL);
746 if (ret < 0) 806 if (ret < 0)
747 goto out; 807 goto out;
748 808
@@ -750,18 +810,19 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
750 if (ret < 0) 810 if (ret < 0)
751 goto out; 811 goto out;
752 812
753 new_epayload = encrypted_key_alloc(key, new_master_desc, 813 new_epayload = encrypted_key_alloc(key, epayload->format,
754 epayload->datalen); 814 new_master_desc, epayload->datalen);
755 if (IS_ERR(new_epayload)) { 815 if (IS_ERR(new_epayload)) {
756 ret = PTR_ERR(new_epayload); 816 ret = PTR_ERR(new_epayload);
757 goto out; 817 goto out;
758 } 818 }
759 819
760 __ekey_init(new_epayload, new_master_desc, epayload->datalen); 820 __ekey_init(new_epayload, epayload->format, new_master_desc,
821 epayload->datalen);
761 822
762 memcpy(new_epayload->iv, epayload->iv, ivsize); 823 memcpy(new_epayload->iv, epayload->iv, ivsize);
763 memcpy(new_epayload->decrypted_data, epayload->decrypted_data, 824 memcpy(new_epayload->payload_data, epayload->payload_data,
764 epayload->decrypted_datalen); 825 epayload->payload_datalen);
765 826
766 rcu_assign_pointer(key->payload.data, new_epayload); 827 rcu_assign_pointer(key->payload.data, new_epayload);
767 call_rcu(&epayload->rcu, encrypted_rcu_free); 828 call_rcu(&epayload->rcu, encrypted_rcu_free);