aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ecryptfs/keystore.c
diff options
context:
space:
mode:
authorMichael Halcrow <mhalcrow@us.ibm.com>2007-10-16 04:27:56 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:43:11 -0400
commitc59becfceea8de57c35a3de5ee45a7bb883cf90a (patch)
tree1e3721371ddf6d37ba08f528a21595a2ace1dd31 /fs/ecryptfs/keystore.c
parent132181796af08273ab9fa835420b9f5f78d70234 (diff)
eCryptfs: fix Tag 3 parsing code
Fix up the Tag 3 parsing code to handle size limits and boundaries more explicitly. Signed-off-by: Michael Halcrow <mhalcrow@us.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ecryptfs/keystore.c')
-rw-r--r--fs/ecryptfs/keystore.c89
1 files changed, 35 insertions, 54 deletions
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index f7debe6961d..72086141a6e 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -643,22 +643,30 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat,
643 643
644 (*packet_size) = 0; 644 (*packet_size) = 0;
645 (*new_auth_tok) = NULL; 645 (*new_auth_tok) = NULL;
646 646 /**
647 /* we check that: 647 *This format is inspired by OpenPGP; see RFC 2440
648 * one byte for the Tag 3 ID flag 648 * packet tag 3
649 * two bytes for the body size 649 *
650 * do not exceed the maximum_packet_size 650 * Tag 3 identifier (1 byte)
651 * Max Tag 3 packet size (max 3 bytes)
652 * Version (1 byte)
653 * Cipher code (1 byte)
654 * S2K specifier (1 byte)
655 * Hash identifier (1 byte)
656 * Salt (ECRYPTFS_SALT_SIZE)
657 * Hash iterations (1 byte)
658 * Encrypted key (arbitrary)
659 *
660 * (ECRYPTFS_SALT_SIZE + 7) minimum packet size
651 */ 661 */
652 if (unlikely((*packet_size) + 3 > max_packet_size)) { 662 if (max_packet_size < (ECRYPTFS_SALT_SIZE + 7)) {
653 ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); 663 printk(KERN_ERR "Max packet size too large\n");
654 rc = -EINVAL; 664 rc = -EINVAL;
655 goto out; 665 goto out;
656 } 666 }
657
658 /* check for Tag 3 identifyer - one byte */
659 if (data[(*packet_size)++] != ECRYPTFS_TAG_3_PACKET_TYPE) { 667 if (data[(*packet_size)++] != ECRYPTFS_TAG_3_PACKET_TYPE) {
660 ecryptfs_printk(KERN_ERR, "Enter w/ first byte != 0x%.2x\n", 668 printk(KERN_ERR "First byte != 0x%.2x; invalid packet\n",
661 ECRYPTFS_TAG_3_PACKET_TYPE); 669 ECRYPTFS_TAG_3_PACKET_TYPE);
662 rc = -EINVAL; 670 rc = -EINVAL;
663 goto out; 671 goto out;
664 } 672 }
@@ -667,56 +675,36 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat,
667 auth_tok_list_item = 675 auth_tok_list_item =
668 kmem_cache_zalloc(ecryptfs_auth_tok_list_item_cache, GFP_KERNEL); 676 kmem_cache_zalloc(ecryptfs_auth_tok_list_item_cache, GFP_KERNEL);
669 if (!auth_tok_list_item) { 677 if (!auth_tok_list_item) {
670 ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); 678 printk(KERN_ERR "Unable to allocate memory\n");
671 rc = -ENOMEM; 679 rc = -ENOMEM;
672 goto out; 680 goto out;
673 } 681 }
674 (*new_auth_tok) = &auth_tok_list_item->auth_tok; 682 (*new_auth_tok) = &auth_tok_list_item->auth_tok;
675 683 if ((rc = parse_packet_length(&data[(*packet_size)], &body_size,
676 /* check for body size - one to two bytes */ 684 &length_size))) {
677 rc = parse_packet_length(&data[(*packet_size)], &body_size, 685 printk(KERN_WARNING "Error parsing packet length; rc = [%d]\n",
678 &length_size); 686 rc);
679 if (rc) {
680 ecryptfs_printk(KERN_WARNING, "Error parsing packet length; "
681 "rc = [%d]\n", rc);
682 goto out_free; 687 goto out_free;
683 } 688 }
684 if (unlikely(body_size < (0x05 + ECRYPTFS_SALT_SIZE))) { 689 if (unlikely(body_size < (ECRYPTFS_SALT_SIZE + 5))) {
685 ecryptfs_printk(KERN_WARNING, "Invalid body size ([%d])\n", 690 printk(KERN_WARNING "Invalid body size ([%d])\n", body_size);
686 body_size);
687 rc = -EINVAL; 691 rc = -EINVAL;
688 goto out_free; 692 goto out_free;
689 } 693 }
690 (*packet_size) += length_size; 694 (*packet_size) += length_size;
691
692 /* now we know the length of the remainting Tag 3 packet size:
693 * 5 fix bytes for: version string, cipher, S2K ID, hash algo,
694 * number of hash iterations
695 * ECRYPTFS_SALT_SIZE bytes for salt
696 * body_size bytes minus the stuff above is the encrypted key size
697 */
698 if (unlikely((*packet_size) + body_size > max_packet_size)) { 695 if (unlikely((*packet_size) + body_size > max_packet_size)) {
699 ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); 696 printk(KERN_ERR "Packet size exceeds max\n");
700 rc = -EINVAL; 697 rc = -EINVAL;
701 goto out_free; 698 goto out_free;
702 } 699 }
703
704 /* There are 5 characters of additional information in the
705 * packet */
706 (*new_auth_tok)->session_key.encrypted_key_size = 700 (*new_auth_tok)->session_key.encrypted_key_size =
707 body_size - (0x05 + ECRYPTFS_SALT_SIZE); 701 (body_size - (ECRYPTFS_SALT_SIZE + 5));
708 ecryptfs_printk(KERN_DEBUG, "Encrypted key size = [%d]\n",
709 (*new_auth_tok)->session_key.encrypted_key_size);
710
711 /* Version 4 (from RFC2440) - one byte */
712 if (unlikely(data[(*packet_size)++] != 0x04)) { 702 if (unlikely(data[(*packet_size)++] != 0x04)) {
713 ecryptfs_printk(KERN_DEBUG, "Unknown version number " 703 printk(KERN_WARNING "Unknown version number [%d]\n",
714 "[%d]\n", data[(*packet_size) - 1]); 704 data[(*packet_size) - 1]);
715 rc = -EINVAL; 705 rc = -EINVAL;
716 goto out_free; 706 goto out_free;
717 } 707 }
718
719 /* cipher - one byte */
720 ecryptfs_cipher_code_to_string(crypt_stat->cipher, 708 ecryptfs_cipher_code_to_string(crypt_stat->cipher,
721 (u16)data[(*packet_size)]); 709 (u16)data[(*packet_size)]);
722 /* A little extra work to differentiate among the AES key 710 /* A little extra work to differentiate among the AES key
@@ -730,33 +718,26 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat,
730 (*new_auth_tok)->session_key.encrypted_key_size; 718 (*new_auth_tok)->session_key.encrypted_key_size;
731 } 719 }
732 ecryptfs_init_crypt_ctx(crypt_stat); 720 ecryptfs_init_crypt_ctx(crypt_stat);
733 /* S2K identifier 3 (from RFC2440) */
734 if (unlikely(data[(*packet_size)++] != 0x03)) { 721 if (unlikely(data[(*packet_size)++] != 0x03)) {
735 ecryptfs_printk(KERN_ERR, "Only S2K ID 3 is currently " 722 printk(KERN_WARNING "Only S2K ID 3 is currently supported\n");
736 "supported\n");
737 rc = -ENOSYS; 723 rc = -ENOSYS;
738 goto out_free; 724 goto out_free;
739 } 725 }
740
741 /* TODO: finish the hash mapping */ 726 /* TODO: finish the hash mapping */
742 /* hash algorithm - one byte */
743 switch (data[(*packet_size)++]) { 727 switch (data[(*packet_size)++]) {
744 case 0x01: /* See RFC2440 for these numbers and their mappings */ 728 case 0x01: /* See RFC2440 for these numbers and their mappings */
745 /* Choose MD5 */ 729 /* Choose MD5 */
746 /* salt - ECRYPTFS_SALT_SIZE bytes */
747 memcpy((*new_auth_tok)->token.password.salt, 730 memcpy((*new_auth_tok)->token.password.salt,
748 &data[(*packet_size)], ECRYPTFS_SALT_SIZE); 731 &data[(*packet_size)], ECRYPTFS_SALT_SIZE);
749 (*packet_size) += ECRYPTFS_SALT_SIZE; 732 (*packet_size) += ECRYPTFS_SALT_SIZE;
750
751 /* This conversion was taken straight from RFC2440 */ 733 /* This conversion was taken straight from RFC2440 */
752 /* number of hash iterations - one byte */
753 (*new_auth_tok)->token.password.hash_iterations = 734 (*new_auth_tok)->token.password.hash_iterations =
754 ((u32) 16 + (data[(*packet_size)] & 15)) 735 ((u32) 16 + (data[(*packet_size)] & 15))
755 << ((data[(*packet_size)] >> 4) + 6); 736 << ((data[(*packet_size)] >> 4) + 6);
756 (*packet_size)++; 737 (*packet_size)++;
757 738 /* Friendly reminder:
758 /* encrypted session key - 739 * (*new_auth_tok)->session_key.encrypted_key_size =
759 * (body_size-5-ECRYPTFS_SALT_SIZE) bytes */ 740 * (body_size - (ECRYPTFS_SALT_SIZE + 5)); */
760 memcpy((*new_auth_tok)->session_key.encrypted_key, 741 memcpy((*new_auth_tok)->session_key.encrypted_key,
761 &data[(*packet_size)], 742 &data[(*packet_size)],
762 (*new_auth_tok)->session_key.encrypted_key_size); 743 (*new_auth_tok)->session_key.encrypted_key_size);
@@ -766,7 +747,7 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat,
766 ~ECRYPTFS_CONTAINS_DECRYPTED_KEY; 747 ~ECRYPTFS_CONTAINS_DECRYPTED_KEY;
767 (*new_auth_tok)->session_key.flags |= 748 (*new_auth_tok)->session_key.flags |=
768 ECRYPTFS_CONTAINS_ENCRYPTED_KEY; 749 ECRYPTFS_CONTAINS_ENCRYPTED_KEY;
769 (*new_auth_tok)->token.password.hash_algo = 0x01; 750 (*new_auth_tok)->token.password.hash_algo = 0x01; /* MD5 */
770 break; 751 break;
771 default: 752 default:
772 ecryptfs_printk(KERN_ERR, "Unsupported hash algorithm: " 753 ecryptfs_printk(KERN_ERR, "Unsupported hash algorithm: "