aboutsummaryrefslogtreecommitdiffstats
path: root/security/keys
diff options
context:
space:
mode:
authorRoberto Sassu <roberto.sassu@polito.it>2011-06-27 07:45:42 -0400
committerMimi Zohar <zohar@linux.vnet.ibm.com>2011-06-27 09:10:45 -0400
commit4e561d388feff18e4b798cef6a1a84a2cc7f20c2 (patch)
tree9208588c7d0e5e75766dd2c98e960840fdc8681e /security/keys
parent7103dff0e598cd634767f17a2958302c515700ca (diff)
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>
Diffstat (limited to 'security/keys')
-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);