From 29a98c1caf7b37b12a79eee7f839bf2924593c1c Mon Sep 17 00:00:00 2001
From: Eric Biggers <ebiggers@google.com>
Date: Wed, 24 Jul 2019 11:08:00 -0700
Subject: [PATCH] fscrypt: use ENOPKG when crypto API support missing

Return ENOPKG rather than ENOENT when trying to open a file that's
encrypted using algorithms not available in the kernel's crypto API.

This avoids an ambiguity, since ENOENT is also returned when the file
doesn't exist.

Note: this is the same approach I'm taking for fs-verity.

Signed-off-by: Eric Biggers <ebiggers@google.com>
---
 fs/crypto/keyinfo.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c
index b75678587c3a8..2129943002335 100644
--- a/fs/crypto/keyinfo.c
+++ b/fs/crypto/keyinfo.c
@@ -237,13 +237,14 @@ allocate_skcipher_for_mode(struct fscrypt_mode *mode, const u8 *raw_key,
 
 	tfm = crypto_alloc_skcipher(mode->cipher_str, 0, 0);
 	if (IS_ERR(tfm)) {
-		if (PTR_ERR(tfm) == -ENOENT)
+		if (PTR_ERR(tfm) == -ENOENT) {
 			fscrypt_warn(inode,
 				     "Missing crypto API support for %s (API name: \"%s\")",
 				     mode->friendly_name, mode->cipher_str);
-		else
-			fscrypt_err(inode, "Error allocating '%s' transform: %ld",
-				    mode->cipher_str, PTR_ERR(tfm));
+			return ERR_PTR(-ENOPKG);
+		}
+		fscrypt_err(inode, "Error allocating '%s' transform: %ld",
+			    mode->cipher_str, PTR_ERR(tfm));
 		return tfm;
 	}
 	if (unlikely(!mode->logged_impl_name)) {
@@ -389,13 +390,14 @@ static int derive_essiv_salt(const u8 *key, int keysize, u8 *salt)
 
 		tfm = crypto_alloc_shash("sha256", 0, 0);
 		if (IS_ERR(tfm)) {
-			if (PTR_ERR(tfm) == -ENOENT)
+			if (PTR_ERR(tfm) == -ENOENT) {
 				fscrypt_warn(NULL,
 					     "Missing crypto API support for SHA-256");
-			else
-				fscrypt_err(NULL,
-					    "Error allocating SHA-256 transform: %ld",
-					    PTR_ERR(tfm));
+				return -ENOPKG;
+			}
+			fscrypt_err(NULL,
+				    "Error allocating SHA-256 transform: %ld",
+				    PTR_ERR(tfm));
 			return PTR_ERR(tfm);
 		}
 		prev_tfm = cmpxchg(&essiv_hash_tfm, NULL, tfm);
-- 
GitLab