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

ecryptfs: Use MD5 library instead of crypto_shash

eCryptfs uses MD5 for a couple unusual purposes: to "mix" the key into
the IVs for file contents encryption (similar to ESSIV), and to prepend
some key-dependent bytes to the plaintext when encrypting filenames
(which is useless since eCryptfs encrypts the filenames with ECB).

Currently, eCryptfs computes these MD5 hashes using the crypto_shash
API. Update it to instead use the MD5 library API. This is simpler and
faster: the library doesn't require memory allocations, can't fail, and
provides direct access to MD5 without overhead such as indirect calls.

To preserve the existing behavior of eCryptfs support being disabled
when the kernel is booted with "fips=1", make ecryptfs_get_tree() check
fips_enabled itself. Previously it relied on crypto_alloc_shash("md5")
failing. I don't know for sure that this is actually needed; e.g., it
could be argued that eCryptfs's use of MD5 isn't for a security purpose
as far as FIPS is concerned. But this preserves the existing behavior.

Tested by verifying that an existing eCryptfs can still be mounted with
a kernel that has this commit, with all the files matching. Also tested
creating a filesystem with this commit and mounting+reading it without.

Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Link: https://patch.msgid.link/20251011200010.193140-1-ebiggers@kernel.org
Acked-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>

authored by

Eric Biggers and committed by
Christian Brauner
0bbb838f 10436adf

+35 -154
+1 -1
fs/ecryptfs/Kconfig
··· 4 4 depends on KEYS && CRYPTO && (ENCRYPTED_KEYS || ENCRYPTED_KEYS=n) 5 5 select CRYPTO_ECB 6 6 select CRYPTO_CBC 7 - select CRYPTO_MD5 7 + select CRYPTO_LIB_MD5 8 8 help 9 9 Encrypted filesystem that operates on the VFS layer. See 10 10 <file:Documentation/filesystems/ecryptfs.rst> to learn more about
+9 -81
fs/ecryptfs/crypto.c
··· 9 9 * Michael C. Thompson <mcthomps@us.ibm.com> 10 10 */ 11 11 12 - #include <crypto/hash.h> 13 12 #include <crypto/skcipher.h> 14 13 #include <linux/fs.h> 15 14 #include <linux/mount.h> ··· 47 48 } 48 49 } 49 50 50 - /** 51 - * ecryptfs_calculate_md5 - calculates the md5 of @src 52 - * @dst: Pointer to 16 bytes of allocated memory 53 - * @crypt_stat: Pointer to crypt_stat struct for the current inode 54 - * @src: Data to be md5'd 55 - * @len: Length of @src 56 - * 57 - * Uses the allocated crypto context that crypt_stat references to 58 - * generate the MD5 sum of the contents of src. 59 - */ 60 - static int ecryptfs_calculate_md5(char *dst, 61 - struct ecryptfs_crypt_stat *crypt_stat, 62 - char *src, int len) 63 - { 64 - int rc = crypto_shash_tfm_digest(crypt_stat->hash_tfm, src, len, dst); 65 - 66 - if (rc) { 67 - printk(KERN_ERR 68 - "%s: Error computing crypto hash; rc = [%d]\n", 69 - __func__, rc); 70 - goto out; 71 - } 72 - out: 73 - return rc; 74 - } 75 - 76 51 static int ecryptfs_crypto_api_algify_cipher_name(char **algified_name, 77 52 char *cipher_name, 78 53 char *chaining_modifier) ··· 77 104 * 78 105 * Generate the initialization vector from the given root IV and page 79 106 * offset. 80 - * 81 - * Returns zero on success; non-zero on error. 82 107 */ 83 - int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat, 84 - loff_t offset) 108 + void ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat, 109 + loff_t offset) 85 110 { 86 - int rc = 0; 87 111 char dst[MD5_DIGEST_SIZE]; 88 112 char src[ECRYPTFS_MAX_IV_BYTES + 16]; 89 113 ··· 99 129 ecryptfs_printk(KERN_DEBUG, "source:\n"); 100 130 ecryptfs_dump_hex(src, (crypt_stat->iv_bytes + 16)); 101 131 } 102 - rc = ecryptfs_calculate_md5(dst, crypt_stat, src, 103 - (crypt_stat->iv_bytes + 16)); 104 - if (rc) { 105 - ecryptfs_printk(KERN_WARNING, "Error attempting to compute " 106 - "MD5 while generating IV for a page\n"); 107 - goto out; 108 - } 132 + md5(src, crypt_stat->iv_bytes + 16, dst); 109 133 memcpy(iv, dst, crypt_stat->iv_bytes); 110 134 if (unlikely(ecryptfs_verbosity > 0)) { 111 135 ecryptfs_printk(KERN_DEBUG, "derived iv:\n"); 112 136 ecryptfs_dump_hex(iv, crypt_stat->iv_bytes); 113 137 } 114 - out: 115 - return rc; 116 138 } 117 139 118 140 /** ··· 113 151 * 114 152 * Initialize the crypt_stat structure. 115 153 */ 116 - int ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) 154 + void ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) 117 155 { 118 - struct crypto_shash *tfm; 119 - int rc; 120 - 121 - tfm = crypto_alloc_shash(ECRYPTFS_DEFAULT_HASH, 0, 0); 122 - if (IS_ERR(tfm)) { 123 - rc = PTR_ERR(tfm); 124 - ecryptfs_printk(KERN_ERR, "Error attempting to " 125 - "allocate crypto context; rc = [%d]\n", 126 - rc); 127 - return rc; 128 - } 129 - 130 156 memset((void *)crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat)); 131 157 INIT_LIST_HEAD(&crypt_stat->keysig_list); 132 158 mutex_init(&crypt_stat->keysig_list_mutex); 133 159 mutex_init(&crypt_stat->cs_mutex); 134 160 mutex_init(&crypt_stat->cs_tfm_mutex); 135 - crypt_stat->hash_tfm = tfm; 136 161 crypt_stat->flags |= ECRYPTFS_STRUCT_INITIALIZED; 137 - 138 - return 0; 139 162 } 140 163 141 164 /** ··· 134 187 struct ecryptfs_key_sig *key_sig, *key_sig_tmp; 135 188 136 189 crypto_free_skcipher(crypt_stat->tfm); 137 - crypto_free_shash(crypt_stat->hash_tfm); 138 190 list_for_each_entry_safe(key_sig, key_sig_tmp, 139 191 &crypt_stat->keysig_list, crypt_stat_list) { 140 192 list_del(&key_sig->crypt_stat_list); ··· 307 361 int rc; 308 362 309 363 extent_base = (((loff_t)page_index) * (PAGE_SIZE / extent_size)); 310 - rc = ecryptfs_derive_iv(extent_iv, crypt_stat, 311 - (extent_base + extent_offset)); 312 - if (rc) { 313 - ecryptfs_printk(KERN_ERR, "Error attempting to derive IV for " 314 - "extent [0x%.16llx]; rc = [%d]\n", 315 - (unsigned long long)(extent_base + extent_offset), rc); 316 - goto out; 317 - } 364 + ecryptfs_derive_iv(extent_iv, crypt_stat, extent_base + extent_offset); 318 365 319 366 sg_init_table(&src_sg, 1); 320 367 sg_init_table(&dst_sg, 1); ··· 548 609 */ 549 610 int ecryptfs_compute_root_iv(struct ecryptfs_crypt_stat *crypt_stat) 550 611 { 551 - int rc = 0; 552 612 char dst[MD5_DIGEST_SIZE]; 553 613 554 614 BUG_ON(crypt_stat->iv_bytes > MD5_DIGEST_SIZE); 555 615 BUG_ON(crypt_stat->iv_bytes <= 0); 556 616 if (!(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { 557 - rc = -EINVAL; 558 617 ecryptfs_printk(KERN_WARNING, "Session key not valid; " 559 618 "cannot generate root IV\n"); 560 - goto out; 561 - } 562 - rc = ecryptfs_calculate_md5(dst, crypt_stat, crypt_stat->key, 563 - crypt_stat->key_size); 564 - if (rc) { 565 - ecryptfs_printk(KERN_WARNING, "Error attempting to compute " 566 - "MD5 while generating root IV\n"); 567 - goto out; 568 - } 569 - memcpy(crypt_stat->root_iv, dst, crypt_stat->iv_bytes); 570 - out: 571 - if (rc) { 572 619 memset(crypt_stat->root_iv, 0, crypt_stat->iv_bytes); 573 620 crypt_stat->flags |= ECRYPTFS_SECURITY_WARNING; 621 + return -EINVAL; 574 622 } 575 - return rc; 623 + md5(crypt_stat->key, crypt_stat->key_size, dst); 624 + memcpy(crypt_stat->root_iv, dst, crypt_stat->iv_bytes); 625 + return 0; 576 626 } 577 627 578 628 static void ecryptfs_generate_new_key(struct ecryptfs_crypt_stat *crypt_stat)
+4 -9
fs/ecryptfs/ecryptfs_kernel.h
··· 14 14 #ifndef ECRYPTFS_KERNEL_H 15 15 #define ECRYPTFS_KERNEL_H 16 16 17 + #include <crypto/md5.h> 17 18 #include <crypto/skcipher.h> 18 19 #include <keys/user-type.h> 19 20 #include <keys/encrypted-type.h> ··· 138 137 + MAGIC_ECRYPTFS_MARKER_SIZE_BYTES) 139 138 #define ECRYPTFS_DEFAULT_CIPHER "aes" 140 139 #define ECRYPTFS_DEFAULT_KEY_BYTES 16 141 - #define ECRYPTFS_DEFAULT_HASH "md5" 142 - #define ECRYPTFS_TAG_70_DIGEST ECRYPTFS_DEFAULT_HASH 143 140 #define ECRYPTFS_TAG_1_PACKET_TYPE 0x01 144 141 #define ECRYPTFS_TAG_3_PACKET_TYPE 0x8C 145 142 #define ECRYPTFS_TAG_11_PACKET_TYPE 0xED ··· 162 163 * ECRYPTFS_MAX_IV_BYTES */ 163 164 #define ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES 16 164 165 #define ECRYPTFS_NON_NULL 0x42 /* A reasonable substitute for NULL */ 165 - #define MD5_DIGEST_SIZE 16 166 - #define ECRYPTFS_TAG_70_DIGEST_SIZE MD5_DIGEST_SIZE 167 166 #define ECRYPTFS_TAG_70_MIN_METADATA_SIZE (1 + ECRYPTFS_MIN_PKT_LEN_SIZE \ 168 167 + ECRYPTFS_SIG_SIZE + 1 + 1) 169 168 #define ECRYPTFS_TAG_70_MAX_METADATA_SIZE (1 + ECRYPTFS_MAX_PKT_LEN_SIZE \ ··· 234 237 unsigned int extent_mask; 235 238 struct ecryptfs_mount_crypt_stat *mount_crypt_stat; 236 239 struct crypto_skcipher *tfm; 237 - struct crypto_shash *hash_tfm; /* Crypto context for generating 238 - * the initialization vectors */ 239 240 unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE + 1]; 240 241 unsigned char key[ECRYPTFS_MAX_KEY_BYTES]; 241 242 unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES]; ··· 553 558 int sg_size); 554 559 int ecryptfs_compute_root_iv(struct ecryptfs_crypt_stat *crypt_stat); 555 560 void ecryptfs_rotate_iv(unsigned char *iv); 556 - int ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat); 561 + void ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat); 557 562 void ecryptfs_destroy_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat); 558 563 void ecryptfs_destroy_mount_crypt_stat( 559 564 struct ecryptfs_mount_crypt_stat *mount_crypt_stat); ··· 688 693 char *data, size_t max_packet_size); 689 694 int ecryptfs_set_f_namelen(long *namelen, long lower_namelen, 690 695 struct ecryptfs_mount_crypt_stat *mount_crypt_stat); 691 - int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat, 692 - loff_t offset); 696 + void ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat, 697 + loff_t offset); 693 698 694 699 extern const struct xattr_handler * const ecryptfs_xattr_handlers[]; 695 700
+2 -5
fs/ecryptfs/inode.c
··· 903 903 struct ecryptfs_crypt_stat *crypt_stat; 904 904 905 905 crypt_stat = &ecryptfs_inode_to_private(d_inode(dentry))->crypt_stat; 906 - if (!(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED)) { 907 - rc = ecryptfs_init_crypt_stat(crypt_stat); 908 - if (rc) 909 - return rc; 910 - } 906 + if (!(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED)) 907 + ecryptfs_init_crypt_stat(crypt_stat); 911 908 inode = d_inode(dentry); 912 909 lower_inode = ecryptfs_inode_to_lower(inode); 913 910 lower_dentry = ecryptfs_dentry_to_lower(dentry);
+11 -54
fs/ecryptfs/keystore.c
··· 11 11 * Trevor S. Highland <trevor.highland@gmail.com> 12 12 */ 13 13 14 - #include <crypto/hash.h> 15 14 #include <crypto/skcipher.h> 16 15 #include <linux/string.h> 17 16 #include <linux/pagemap.h> ··· 600 601 struct crypto_skcipher *skcipher_tfm; 601 602 struct skcipher_request *skcipher_req; 602 603 char iv[ECRYPTFS_MAX_IV_BYTES]; 603 - char hash[ECRYPTFS_TAG_70_DIGEST_SIZE]; 604 - char tmp_hash[ECRYPTFS_TAG_70_DIGEST_SIZE]; 605 - struct crypto_shash *hash_tfm; 606 - struct shash_desc *hash_desc; 604 + char hash[MD5_DIGEST_SIZE]; 607 605 }; 608 606 609 607 /* ··· 737 741 "password tokens\n", __func__); 738 742 goto out_free_unlock; 739 743 } 740 - s->hash_tfm = crypto_alloc_shash(ECRYPTFS_TAG_70_DIGEST, 0, 0); 741 - if (IS_ERR(s->hash_tfm)) { 742 - rc = PTR_ERR(s->hash_tfm); 743 - printk(KERN_ERR "%s: Error attempting to " 744 - "allocate hash crypto context; rc = [%d]\n", 745 - __func__, rc); 746 - goto out_free_unlock; 747 - } 748 744 749 - s->hash_desc = kmalloc(sizeof(*s->hash_desc) + 750 - crypto_shash_descsize(s->hash_tfm), GFP_KERNEL); 751 - if (!s->hash_desc) { 752 - rc = -ENOMEM; 753 - goto out_release_free_unlock; 754 - } 755 - 756 - s->hash_desc->tfm = s->hash_tfm; 757 - 758 - rc = crypto_shash_digest(s->hash_desc, 759 - (u8 *)s->auth_tok->token.password.session_key_encryption_key, 760 - s->auth_tok->token.password.session_key_encryption_key_bytes, 761 - s->hash); 762 - if (rc) { 763 - printk(KERN_ERR 764 - "%s: Error computing crypto hash; rc = [%d]\n", 765 - __func__, rc); 766 - goto out_release_free_unlock; 767 - } 745 + md5(s->auth_tok->token.password.session_key_encryption_key, 746 + s->auth_tok->token.password.session_key_encryption_key_bytes, 747 + s->hash); 768 748 for (s->j = 0; s->j < (s->num_rand_bytes - 1); s->j++) { 769 749 s->block_aligned_filename[s->j] = 770 - s->hash[(s->j % ECRYPTFS_TAG_70_DIGEST_SIZE)]; 771 - if ((s->j % ECRYPTFS_TAG_70_DIGEST_SIZE) 772 - == (ECRYPTFS_TAG_70_DIGEST_SIZE - 1)) { 773 - rc = crypto_shash_digest(s->hash_desc, (u8 *)s->hash, 774 - ECRYPTFS_TAG_70_DIGEST_SIZE, 775 - s->tmp_hash); 776 - if (rc) { 777 - printk(KERN_ERR 778 - "%s: Error computing crypto hash; " 779 - "rc = [%d]\n", __func__, rc); 780 - goto out_release_free_unlock; 781 - } 782 - memcpy(s->hash, s->tmp_hash, 783 - ECRYPTFS_TAG_70_DIGEST_SIZE); 784 - } 750 + s->hash[s->j % MD5_DIGEST_SIZE]; 751 + if ((s->j % MD5_DIGEST_SIZE) == (MD5_DIGEST_SIZE - 1)) 752 + md5(s->hash, MD5_DIGEST_SIZE, s->hash); 785 753 if (s->block_aligned_filename[s->j] == '\0') 786 754 s->block_aligned_filename[s->j] = ECRYPTFS_NON_NULL; 787 755 } ··· 758 798 "convert filename memory to scatterlist; rc = [%d]. " 759 799 "block_aligned_filename_size = [%zd]\n", __func__, rc, 760 800 s->block_aligned_filename_size); 761 - goto out_release_free_unlock; 801 + goto out_free_unlock; 762 802 } 763 803 rc = virt_to_scatterlist(&dest[s->i], s->block_aligned_filename_size, 764 804 s->dst_sg, 2); ··· 767 807 "convert encrypted filename memory to scatterlist; " 768 808 "rc = [%d]. block_aligned_filename_size = [%zd]\n", 769 809 __func__, rc, s->block_aligned_filename_size); 770 - goto out_release_free_unlock; 810 + goto out_free_unlock; 771 811 } 772 812 /* The characters in the first block effectively do the job 773 813 * of the IV here, so we just use 0's for the IV. Note the ··· 785 825 rc, 786 826 s->auth_tok->token.password.session_key_encryption_key, 787 827 mount_crypt_stat->global_default_fn_cipher_key_bytes); 788 - goto out_release_free_unlock; 828 + goto out_free_unlock; 789 829 } 790 830 skcipher_request_set_crypt(s->skcipher_req, s->src_sg, s->dst_sg, 791 831 s->block_aligned_filename_size, s->iv); ··· 793 833 if (rc) { 794 834 printk(KERN_ERR "%s: Error attempting to encrypt filename; " 795 835 "rc = [%d]\n", __func__, rc); 796 - goto out_release_free_unlock; 836 + goto out_free_unlock; 797 837 } 798 838 s->i += s->block_aligned_filename_size; 799 839 (*packet_size) = s->i; 800 840 (*remaining_bytes) -= (*packet_size); 801 - out_release_free_unlock: 802 - crypto_free_shash(s->hash_tfm); 803 841 out_free_unlock: 804 842 kfree_sensitive(s->block_aligned_filename); 805 843 out_unlock: ··· 808 850 key_put(auth_tok_key); 809 851 } 810 852 skcipher_request_free(s->skcipher_req); 811 - kfree_sensitive(s->hash_desc); 812 853 kfree(s); 813 854 return rc; 814 855 }
+7
fs/ecryptfs/main.c
··· 12 12 13 13 #include <linux/dcache.h> 14 14 #include <linux/file.h> 15 + #include <linux/fips.h> 15 16 #include <linux/module.h> 16 17 #include <linux/namei.h> 17 18 #include <linux/skbuff.h> ··· 452 451 rc = ecryptfs_validate_options(fc); 453 452 if (rc) { 454 453 err = "Error validating options"; 454 + goto out; 455 + } 456 + 457 + if (fips_enabled) { 458 + rc = -EINVAL; 459 + err = "eCryptfs support is disabled due to FIPS"; 455 460 goto out; 456 461 } 457 462
+1 -4
fs/ecryptfs/super.c
··· 41 41 inode_info = alloc_inode_sb(sb, ecryptfs_inode_info_cache, GFP_KERNEL); 42 42 if (unlikely(!inode_info)) 43 43 goto out; 44 - if (ecryptfs_init_crypt_stat(&inode_info->crypt_stat)) { 45 - kmem_cache_free(ecryptfs_inode_info_cache, inode_info); 46 - goto out; 47 - } 44 + ecryptfs_init_crypt_stat(&inode_info->crypt_stat); 48 45 mutex_init(&inode_info->lower_file_mutex); 49 46 atomic_set(&inode_info->lower_file_count, 0); 50 47 inode_info->lower_file = NULL;