Skip to contentSkip to conversation

ecryptfs: Use MD5 library instead of crypto_shash

PATCH Applied Eric Biggers 3 participants 6 messages Oct 11, 2025 – Oct 21, 2025

Subsystems (3)

v1 of 2 Applied Latest is v2 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 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.

---

I can take this through the libcrypto tree if no one else volunteers. (It looks like eCryptfs doesn't have an active git tree anymore.)

 fs/ecryptfs/Kconfig           |  2 +-
 fs/ecryptfs/crypto.c          | 90 ++++-------------------------------
 fs/ecryptfs/ecryptfs_kernel.h | 13 ++---
 fs/ecryptfs/inode.c           |  7 +--
 fs/ecryptfs/keystore.c        | 65 +++++--------------------
 fs/ecryptfs/main.c            |  7 +++
 fs/ecryptfs/super.c           |  5 +-
 7 files changed, 35 insertions(+), 154 deletions(-)
fs/ecryptfs/Kconfig +1 -1
index 1bdeaa6d57900..c2f4fb41b4e6a 100644
@@ -2,11 +2,11 @@
 config ECRYPT_FS
 	tristate "eCrypt filesystem layer support"
 	depends on KEYS && CRYPTO && (ENCRYPTED_KEYS || ENCRYPTED_KEYS=n)
 	select CRYPTO_ECB
 	select CRYPTO_CBC
-	select CRYPTO_MD5
+	select CRYPTO_LIB_MD5
 	help
 	  Encrypted filesystem that operates on the VFS layer.  See
 	  <file:Documentation/filesystems/ecryptfs.rst> to learn more about
 	  eCryptfs.  Userspace components are required and can be
 	  obtained from <http://ecryptfs.sf.net>.
fs/ecryptfs/crypto.c +9 -81

192 lines not on this page · raw message

fs/ecryptfs/ecryptfs_kernel.h +4 -9
index 9e6ab0b413376..62a2ea7f59eda 100644
@@ -12,10 +12,11 @@
  */
 
 #ifndef ECRYPTFS_KERNEL_H
 #define ECRYPTFS_KERNEL_H
 
+#include <crypto/md5.h>
 #include <crypto/skcipher.h>
 #include <keys/user-type.h>
 #include <keys/encrypted-type.h>
 #include <linux/kernel.h>
 #include <linux/fs.h>
@@ -135,12 +136,10 @@ ecryptfs_get_key_payload_data(struct key *key)
 #define ECRYPTFS_FILE_SIZE_BYTES (sizeof(u64))
 #define ECRYPTFS_SIZE_AND_MARKER_BYTES (ECRYPTFS_FILE_SIZE_BYTES \
 					+ MAGIC_ECRYPTFS_MARKER_SIZE_BYTES)
 #define ECRYPTFS_DEFAULT_CIPHER "aes"
 #define ECRYPTFS_DEFAULT_KEY_BYTES 16
-#define ECRYPTFS_DEFAULT_HASH "md5"
-#define ECRYPTFS_TAG_70_DIGEST ECRYPTFS_DEFAULT_HASH
 #define ECRYPTFS_TAG_1_PACKET_TYPE 0x01
 #define ECRYPTFS_TAG_3_PACKET_TYPE 0x8C
 #define ECRYPTFS_TAG_11_PACKET_TYPE 0xED
 #define ECRYPTFS_TAG_64_PACKET_TYPE 0x40
 #define ECRYPTFS_TAG_65_PACKET_TYPE 0x41
@@ -161,12 +160,10 @@ ecryptfs_get_key_payload_data(struct key *key)
 				     */
 /* Constraint: ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES >=
  * ECRYPTFS_MAX_IV_BYTES */
 #define ECRYPTFS_FILENAME_MIN_RANDOM_PREPEND_BYTES 16
 #define ECRYPTFS_NON_NULL 0x42 /* A reasonable substitute for NULL */
-#define MD5_DIGEST_SIZE 16
-#define ECRYPTFS_TAG_70_DIGEST_SIZE MD5_DIGEST_SIZE
 #define ECRYPTFS_TAG_70_MIN_METADATA_SIZE (1 + ECRYPTFS_MIN_PKT_LEN_SIZE \
 					   + ECRYPTFS_SIG_SIZE + 1 + 1)
 #define ECRYPTFS_TAG_70_MAX_METADATA_SIZE (1 + ECRYPTFS_MAX_PKT_LEN_SIZE \
 					   + ECRYPTFS_SIG_SIZE + 1 + 1)
 #define ECRYPTFS_FEK_ENCRYPTED_FILENAME_PREFIX "ECRYPTFS_FEK_ENCRYPTED."
@@ -235,12 +232,10 @@ struct ecryptfs_crypt_stat {
 	size_t key_size;
 	size_t extent_shift;
 	unsigned int extent_mask;
 	struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
 	struct crypto_skcipher *tfm;
-	struct crypto_shash *hash_tfm; /* Crypto context for generating
-					* the initialization vectors */
 	unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE + 1];
 	unsigned char key[ECRYPTFS_MAX_KEY_BYTES];
 	unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES];
 	struct list_head keysig_list;
 	struct mutex keysig_list_mutex;
@@ -556,11 +551,11 @@ int ecryptfs_encrypt_and_encode_filename(
 void ecryptfs_dump_hex(char *data, int bytes);
 int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
 			int sg_size);
 int ecryptfs_compute_root_iv(struct ecryptfs_crypt_stat *crypt_stat);
 void ecryptfs_rotate_iv(unsigned char *iv);
-int ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat);
+void ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat);
 void ecryptfs_destroy_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat);
 void ecryptfs_destroy_mount_crypt_stat(
 	struct ecryptfs_mount_crypt_stat *mount_crypt_stat);
 int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat);
 int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode);
@@ -691,11 +686,11 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
 			     size_t *packet_size,
 			     struct ecryptfs_mount_crypt_stat *mount_crypt_stat,
 			     char *data, size_t max_packet_size);
 int ecryptfs_set_f_namelen(long *namelen, long lower_namelen,
 			   struct ecryptfs_mount_crypt_stat *mount_crypt_stat);
-int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat,
-		       loff_t offset);
+void ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat,
+			loff_t offset);
 
 extern const struct xattr_handler * const ecryptfs_xattr_handlers[];
 
 #endif /* #ifndef ECRYPTFS_KERNEL_H */
fs/ecryptfs/inode.c +2 -5
index ed1394da8d6bd..bae9011fa62ff 100644
@@ -901,15 +901,12 @@ static int ecryptfs_setattr(struct mnt_idmap *idmap,
 	struct inode *inode;
 	struct inode *lower_inode;
 	struct ecryptfs_crypt_stat *crypt_stat;
 
 	crypt_stat = &ecryptfs_inode_to_private(d_inode(dentry))->crypt_stat;
-	if (!(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED)) {
-		rc = ecryptfs_init_crypt_stat(crypt_stat);
-		if (rc)
-			return rc;
-	}
+	if (!(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED))
+		ecryptfs_init_crypt_stat(crypt_stat);
 	inode = d_inode(dentry);
 	lower_inode = ecryptfs_inode_to_lower(inode);
 	lower_dentry = ecryptfs_dentry_to_lower(dentry);
 	mutex_lock(&crypt_stat->cs_mutex);
 	if (d_is_dir(dentry))
fs/ecryptfs/keystore.c +11 -54

147 lines not on this page · raw message

fs/ecryptfs/main.c +7 -0
index 16ea14dd2c62e..c12dc680f8fe2 100644
@@ -10,10 +10,11 @@
  *              Tyler Hicks <[email protected]>
  */
 
 #include <linux/dcache.h>
 #include <linux/file.h>
+#include <linux/fips.h>
 #include <linux/module.h>
 #include <linux/namei.h>
 #include <linux/skbuff.h>
 #include <linux/pagemap.h>
 #include <linux/key.h>
@@ -452,10 +453,16 @@ static int ecryptfs_get_tree(struct fs_context *fc)
 	if (rc) {
 		err = "Error validating options";
 		goto out;
 	}
 
+	if (fips_enabled) {
+		rc = -EINVAL;
+		err = "eCryptfs support is disabled due to FIPS";
+		goto out;
+	}
+
 	s = sget_fc(fc, NULL, set_anon_super_fc);
 	if (IS_ERR(s)) {
 		rc = PTR_ERR(s);
 		goto out;
 	}
fs/ecryptfs/super.c +1 -4
index e7b7f426fecfb..3bc21d677564d 100644
@@ -39,14 +39,11 @@ static struct inode *ecryptfs_alloc_inode(struct super_block *sb)
 	struct inode *inode = NULL;
 
 	inode_info = alloc_inode_sb(sb, ecryptfs_inode_info_cache, GFP_KERNEL);
 	if (unlikely(!inode_info))
 		goto out;
-	if (ecryptfs_init_crypt_stat(&inode_info->crypt_stat)) {
-		kmem_cache_free(ecryptfs_inode_info_cache, inode_info);
-		goto out;
-	}
+	ecryptfs_init_crypt_stat(&inode_info->crypt_stat);
 	mutex_init(&inode_info->lower_file_mutex);
 	atomic_set(&inode_info->lower_file_count, 0);
 	inode_info->lower_file = NULL;
 	inode = &inode_info->vfs_inode;
 out:

base-commit: 0739473694c4878513031006829f1030ec850bc2

Signature · 1 line
2.51.0
Acked-by on v1 1/1
#1 lore raw
Quoted 28 lines · Eric Biggers

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.

---

I can take this through the libcrypto tree if no one else volunteers. (It looks like eCryptfs doesn't have an active git tree anymore.)

Quoted 9 lines
 fs/ecryptfs/Kconfig           |  2 +-
 fs/ecryptfs/crypto.c          | 90 ++++-------------------------------
 fs/ecryptfs/ecryptfs_kernel.h | 13 ++---
 fs/ecryptfs/inode.c           |  7 +--
 fs/ecryptfs/keystore.c        | 65 +++++--------------------
 fs/ecryptfs/main.c            |  7 +++
 fs/ecryptfs/super.c           |  5 +-
 7 files changed, 35 insertions(+), 154 deletions(-)
maintainer Applied
#2 lore raw
In reply to Eric Biggers
Quoted 11 lines · Eric Biggers

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.

[...]

Applied to the vfs-6.18.misc branch of the vfs/vfs.git tree. Patches in the vfs-6.18.misc branch should appear in linux-next soon.

Please report any outstanding bugs that were missed during review in a new review to the original patch series allowing us to drop it.

It's encouraged to provide Acked-bys and Reviewed-bys even though the patch has now been applied. If possible patch trailers will be updated.

Note that commit hashes shown below are subject to change due to rebase, trailer updates or similar. If in doubt, please check the listed branch.

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
branch: vfs-6.18.misc

[1/1] ecryptfs: Use MD5 library instead of crypto_shash

      https://git.kernel.org/vfs/vfs/c/b5ebe9744540
#3 lore raw
In reply to Eric Biggers
Quoted 21 lines · Eric Biggers

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.

Quoted 5 lines

---

I can take this through the libcrypto tree if no one else volunteers. (It looks like eCryptfs doesn't have an active git tree anymore.)

Thanks, but not need, fixes for orphaned fses (that have valid acks) are taken through a VFS tree.

#4 lore raw
Quoted 22 lines · Christian Brauner
Quoted 21 lines · Eric Biggers

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.

Quoted 8 lines
Quoted 5 lines

---

I can take this through the libcrypto tree if no one else volunteers. (It looks like eCryptfs doesn't have an active git tree anymore.)

Thanks, but not need, fixes for orphaned fses (that have valid acks) are taken through a VFS tree.

Sounds good, thanks!

- Eric

maintainer Applied
#5 lore raw
In reply to Eric Biggers
Quoted 11 lines · Eric Biggers

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.

[...]

Applied to the vfs-6.19.misc branch of the vfs/vfs.git tree. Patches in the vfs-6.19.misc branch should appear in linux-next soon.

Please report any outstanding bugs that were missed during review in a new review to the original patch series allowing us to drop it.

It's encouraged to provide Acked-bys and Reviewed-bys even though the patch has now been applied. If possible patch trailers will be updated.

Note that commit hashes shown below are subject to change due to rebase, trailer updates or similar. If in doubt, please check the listed branch.

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
branch: vfs-6.19.misc

[1/1] ecryptfs: Use MD5 library instead of crypto_shash

      https://git.kernel.org/vfs/vfs/c/7f77fe73421f