diff --git a/fs/crypto/fscrypt_private.h b/fs/crypto/fscrypt_private.h
index dec85c4b14a8..6d420c9a85bd 100644
--- a/fs/crypto/fscrypt_private.h
+++ b/fs/crypto/fscrypt_private.h
@@ -49,7 +49,7 @@ struct fscrypt_context_v1 {
 
 	/*
 	 * A unique value used in combination with the master key to derive the
-	 * file's actual encryption key
+	 * file's actual encryption key, using the AES-ECB-based KDF.
 	 */
 	u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE];
 };
@@ -78,7 +78,7 @@ struct fscrypt_context_v2 {
 
 	/*
 	 * A unique value used in combination with the master key to derive the
-	 * file's actual encryption key
+	 * file's actual encryption key, using HKDF-SHA512.
 	 */
 	u8 nonce[FS_KEY_DERIVATION_NONCE_SIZE];
 };
diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c
index c9e7b2b262d2..ec181c4eca56 100644
--- a/fs/crypto/keyinfo.c
+++ b/fs/crypto/keyinfo.c
@@ -44,6 +44,7 @@
  * "key identifier", as that is stored in the clear.)
  */
 #define HKDF_CONTEXT_KEY_IDENTIFIER	1
+#define HKDF_CONTEXT_PER_FILE_KEY	2
 
 /*
  * HKDF consists of two steps:
@@ -213,10 +214,18 @@ static struct crypto_shash *allocate_hmac_tfm(const u8 *master_key, u32 size)
  */
 struct fscrypt_master_key_secret {
 
-	/* Size of the raw key in bytes */
+	/*
+	 * For v2 policy keys: an HMAC transform keyed by the pseudorandom key
+	 * generated by computing HKDF-Extract with the raw master key as the
+	 * input key material.  This is used to efficiently derive the per-inode
+	 * encryption keys using HKDF-Expand later.
+	 */
+	struct crypto_shash	*hmac_tfm;
+
+	/* Size of the raw key in bytes.  Set even if ->raw isn't set. */
 	u32			size;
 
-	/* The raw key */
+	/* For v1 policy keys: the raw key. */
 	u8			raw[FSCRYPT_MAX_KEY_SIZE];
 };
 
@@ -291,6 +300,7 @@ is_master_key_secret_present(const struct fscrypt_master_key_secret *secret)
 
 static void wipe_master_key_secret(struct fscrypt_master_key_secret *secret)
 {
+	crypto_free_shash(secret->hmac_tfm);
 	memzero_explicit(secret, sizeof(*secret));
 }
 
@@ -571,14 +581,17 @@ int fscrypt_ioctl_add_key(struct file *filp, void __user *_uarg)
 		goto out_wipe_secret;
 
 	if (arg.key_spec.type == FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER) {
-		struct crypto_shash *hmac_tfm;
 
-		hmac_tfm = allocate_hmac_tfm(secret.raw, secret.size);
-		if (IS_ERR(hmac_tfm)) {
-			err = PTR_ERR(hmac_tfm);
+		secret.hmac_tfm = allocate_hmac_tfm(secret.raw, secret.size);
+		if (IS_ERR(secret.hmac_tfm)) {
+			err = PTR_ERR(secret.hmac_tfm);
+			secret.hmac_tfm = NULL;
 			goto out_wipe_secret;
 		}
 
+		/* The raw key is no longer needed */
+		memzero_explicit(secret.raw, sizeof(secret.raw));
+
 		/*
 		 * Hash the master key to get the key identifier, then return it
 		 * to userspace.  Specifically, we derive the key identifier
@@ -589,10 +602,9 @@ int fscrypt_ioctl_add_key(struct file *filp, void __user *_uarg)
 		 * rather than two (HKDF-SHA512 and SHA512).  It *maybe* would
 		 * be okay, but cryptographically it would be bad practice.
 		 */
-		err = hkdf_expand(hmac_tfm, HKDF_CONTEXT_KEY_IDENTIFIER,
+		err = hkdf_expand(secret.hmac_tfm, HKDF_CONTEXT_KEY_IDENTIFIER,
 				  NULL, 0, arg.key_spec.identifier,
 				  FSCRYPT_KEY_IDENTIFIER_SIZE);
-		crypto_free_shash(hmac_tfm);
 		if (err)
 			goto out_wipe_secret;
 
@@ -871,8 +883,13 @@ static void derive_crypt_complete(struct crypto_async_request *req, int rc)
 }
 
 /*
- * Key derivation function.  This generates the derived key by encrypting the
- * master key with AES-128-ECB using the nonce as the AES key.
+ * Legacy key derivation function.  This generates the derived key by encrypting
+ * the master key with AES-128-ECB using the nonce as the AES key.  This
+ * provides a unique derived key with sufficient entropy for each inode.
+ * However, it's nonstandard, non-extensible, doesn't evenly distribute the
+ * entropy from the master key, and is trivially reversible: an attacker who
+ * compromises a derived key can "decrypt" it to get back to the master key,
+ * then derive any other key.  For all new code, use HKDF instead.
  *
  * The master key must be at least as long as the derived key.  If the master
  * key is longer, then only the first 'derived_keysize' bytes are used.
@@ -1078,8 +1095,21 @@ static int find_and_derive_key(const struct inode *inode,
 		goto out_release_key;
 	}
 
-	err = derive_key_aes(mk->mk_secret.raw, &ctx->v1,
-			     derived_key, derived_keysize);
+	/*
+	 * Derive the inode's encryption key, given the master key and the nonce
+	 * from the inode's fscrypt_context.  v1 policies used an AES-ECB-based
+	 * KDF (Key Derivation Function).  Newer policies use HKDF-SHA512, which
+	 * fixes a number of problems with the AES-ECB-based KDF.
+	 */
+	if (ctx->v1.version == FSCRYPT_CONTEXT_V1) {
+		err = derive_key_aes(mk->mk_secret.raw, &ctx->v1,
+				     derived_key, derived_keysize);
+	} else {
+		err = hkdf_expand(mk->mk_secret.hmac_tfm,
+				  HKDF_CONTEXT_PER_FILE_KEY,
+				  ctx->v2.nonce, sizeof(ctx->v2.nonce),
+				  derived_key, derived_keysize);
+	}
 	if (err)
 		goto out_release_key;
 
@@ -1275,8 +1305,8 @@ int fscrypt_get_encryption_info(struct inode *inode)
 		goto out;
 
 	/*
-	 * This cannot be a stack buffer because it is passed to the scatterlist
-	 * crypto API as part of key derivation.
+	 * This cannot be a stack buffer because it may be passed to the
+	 * scatterlist crypto API during key derivation.
 	 */
 	res = -ENOMEM;
 	derived_key = kmalloc(FS_MAX_KEY_SIZE, GFP_NOFS);
