aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
authorMimi Zohar <zohar@linux.vnet.ibm.com>2010-12-13 16:53:12 -0500
committerJames Morris <jmorris@namei.org>2010-12-15 01:44:32 -0500
commit1f35065a9e2573427ce3fd6c4a40b355c2ddfb92 (patch)
tree9ee6990e21b34dda09efc625a8bca4fa6c4e5d67 /security
parent1bdbb4024c309e470711b434a24fb356fc92edea (diff)
encrypted-keys: verify datablob size before converting to binary
Verify the hex ascii datablob length is correct before converting the IV, encrypted data, and HMAC to binary. Reported-by: David Howells <dhowells@redhat.com> Signed-off-by: Mimi Zohar <zohar@us.ibm.com> Acked-by: David Howells <dhowells@redhat.com> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security')
-rw-r--r--security/keys/encrypted_defined.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/security/keys/encrypted_defined.c b/security/keys/encrypted_defined.c
index 3f4085703e6c..d653e991c694 100644
--- a/security/keys/encrypted_defined.c
+++ b/security/keys/encrypted_defined.c
@@ -129,8 +129,7 @@ out:
129 * On success returns 0, otherwise -EINVAL. 129 * On success returns 0, otherwise -EINVAL.
130 */ 130 */
131static int datablob_parse(char *datablob, char **master_desc, 131static int datablob_parse(char *datablob, char **master_desc,
132 char **decrypted_datalen, char **hex_encoded_iv, 132 char **decrypted_datalen, char **hex_encoded_iv)
133 char **hex_encoded_data)
134{ 133{
135 substring_t args[MAX_OPT_ARGS]; 134 substring_t args[MAX_OPT_ARGS];
136 int ret = -EINVAL; 135 int ret = -EINVAL;
@@ -167,7 +166,6 @@ static int datablob_parse(char *datablob, char **master_desc,
167 *hex_encoded_iv = strsep(&datablob, " \t"); 166 *hex_encoded_iv = strsep(&datablob, " \t");
168 if (!*hex_encoded_iv) 167 if (!*hex_encoded_iv)
169 break; 168 break;
170 *hex_encoded_data = *hex_encoded_iv + (2 * ivsize) + 2;
171 ret = 0; 169 ret = 0;
172 break; 170 break;
173 case Opt_update: 171 case Opt_update:
@@ -558,18 +556,24 @@ static struct encrypted_key_payload *encrypted_key_alloc(struct key *key,
558} 556}
559 557
560static int encrypted_key_decrypt(struct encrypted_key_payload *epayload, 558static int encrypted_key_decrypt(struct encrypted_key_payload *epayload,
561 const char *hex_encoded_iv, 559 const char *hex_encoded_iv)
562 const char *hex_encoded_data)
563{ 560{
564 struct key *mkey; 561 struct key *mkey;
565 u8 derived_key[HASH_SIZE]; 562 u8 derived_key[HASH_SIZE];
566 u8 *master_key; 563 u8 *master_key;
567 u8 *hmac; 564 u8 *hmac;
565 const char *hex_encoded_data;
568 unsigned int master_keylen; 566 unsigned int master_keylen;
569 unsigned int encrypted_datalen; 567 unsigned int encrypted_datalen;
568 size_t asciilen;
570 int ret; 569 int ret;
571 570
572 encrypted_datalen = roundup(epayload->decrypted_datalen, blksize); 571 encrypted_datalen = roundup(epayload->decrypted_datalen, blksize);
572 asciilen = (ivsize + 1 + encrypted_datalen + HASH_SIZE) * 2;
573 if (strlen(hex_encoded_iv) != asciilen)
574 return -EINVAL;
575
576 hex_encoded_data = hex_encoded_iv + (2 * ivsize) + 2;
573 hex2bin(epayload->iv, hex_encoded_iv, ivsize); 577 hex2bin(epayload->iv, hex_encoded_iv, ivsize);
574 hex2bin(epayload->encrypted_data, hex_encoded_data, encrypted_datalen); 578 hex2bin(epayload->encrypted_data, hex_encoded_data, encrypted_datalen);
575 579
@@ -620,20 +624,18 @@ static void __ekey_init(struct encrypted_key_payload *epayload,
620 */ 624 */
621static int encrypted_init(struct encrypted_key_payload *epayload, 625static int encrypted_init(struct encrypted_key_payload *epayload,
622 const char *master_desc, const char *datalen, 626 const char *master_desc, const char *datalen,
623 const char *hex_encoded_iv, 627 const char *hex_encoded_iv)
624 const char *hex_encoded_data)
625{ 628{
626 int ret = 0; 629 int ret = 0;
627 630
628 __ekey_init(epayload, master_desc, datalen); 631 __ekey_init(epayload, master_desc, datalen);
629 if (!hex_encoded_data) { 632 if (!hex_encoded_iv) {
630 get_random_bytes(epayload->iv, ivsize); 633 get_random_bytes(epayload->iv, ivsize);
631 634
632 get_random_bytes(epayload->decrypted_data, 635 get_random_bytes(epayload->decrypted_data,
633 epayload->decrypted_datalen); 636 epayload->decrypted_datalen);
634 } else 637 } else
635 ret = encrypted_key_decrypt(epayload, hex_encoded_iv, 638 ret = encrypted_key_decrypt(epayload, hex_encoded_iv);
636 hex_encoded_data);
637 return ret; 639 return ret;
638} 640}
639 641
@@ -653,7 +655,6 @@ static int encrypted_instantiate(struct key *key, const void *data,
653 char *master_desc = NULL; 655 char *master_desc = NULL;
654 char *decrypted_datalen = NULL; 656 char *decrypted_datalen = NULL;
655 char *hex_encoded_iv = NULL; 657 char *hex_encoded_iv = NULL;
656 char *hex_encoded_data = NULL;
657 int ret; 658 int ret;
658 659
659 if (datalen <= 0 || datalen > 32767 || !data) 660 if (datalen <= 0 || datalen > 32767 || !data)
@@ -665,7 +666,7 @@ static int encrypted_instantiate(struct key *key, const void *data,
665 datablob[datalen] = 0; 666 datablob[datalen] = 0;
666 memcpy(datablob, data, datalen); 667 memcpy(datablob, data, datalen);
667 ret = datablob_parse(datablob, &master_desc, &decrypted_datalen, 668 ret = datablob_parse(datablob, &master_desc, &decrypted_datalen,
668 &hex_encoded_iv, &hex_encoded_data); 669 &hex_encoded_iv);
669 if (ret < 0) 670 if (ret < 0)
670 goto out; 671 goto out;
671 672
@@ -675,7 +676,7 @@ static int encrypted_instantiate(struct key *key, const void *data,
675 goto out; 676 goto out;
676 } 677 }
677 ret = encrypted_init(epayload, master_desc, decrypted_datalen, 678 ret = encrypted_init(epayload, master_desc, decrypted_datalen,
678 hex_encoded_iv, hex_encoded_data); 679 hex_encoded_iv);
679 if (ret < 0) { 680 if (ret < 0) {
680 kfree(epayload); 681 kfree(epayload);
681 goto out; 682 goto out;
@@ -722,7 +723,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
722 723
723 buf[datalen] = 0; 724 buf[datalen] = 0;
724 memcpy(buf, data, datalen); 725 memcpy(buf, data, datalen);
725 ret = datablob_parse(buf, &new_master_desc, NULL, NULL, NULL); 726 ret = datablob_parse(buf, &new_master_desc, NULL, NULL);
726 if (ret < 0) 727 if (ret < 0)
727 goto out; 728 goto out;
728 729