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>
This commit is contained in:
Eric Biggers 2019-07-24 11:08:00 -07:00
parent a4d14e915b
commit 29a98c1caf

View File

@ -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); tfm = crypto_alloc_skcipher(mode->cipher_str, 0, 0);
if (IS_ERR(tfm)) { if (IS_ERR(tfm)) {
if (PTR_ERR(tfm) == -ENOENT) if (PTR_ERR(tfm) == -ENOENT) {
fscrypt_warn(inode, fscrypt_warn(inode,
"Missing crypto API support for %s (API name: \"%s\")", "Missing crypto API support for %s (API name: \"%s\")",
mode->friendly_name, mode->cipher_str); mode->friendly_name, mode->cipher_str);
else return ERR_PTR(-ENOPKG);
fscrypt_err(inode, "Error allocating '%s' transform: %ld", }
mode->cipher_str, PTR_ERR(tfm)); fscrypt_err(inode, "Error allocating '%s' transform: %ld",
mode->cipher_str, PTR_ERR(tfm));
return tfm; return tfm;
} }
if (unlikely(!mode->logged_impl_name)) { 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); tfm = crypto_alloc_shash("sha256", 0, 0);
if (IS_ERR(tfm)) { if (IS_ERR(tfm)) {
if (PTR_ERR(tfm) == -ENOENT) if (PTR_ERR(tfm) == -ENOENT) {
fscrypt_warn(NULL, fscrypt_warn(NULL,
"Missing crypto API support for SHA-256"); "Missing crypto API support for SHA-256");
else return -ENOPKG;
fscrypt_err(NULL, }
"Error allocating SHA-256 transform: %ld", fscrypt_err(NULL,
PTR_ERR(tfm)); "Error allocating SHA-256 transform: %ld",
PTR_ERR(tfm));
return PTR_ERR(tfm); return PTR_ERR(tfm);
} }
prev_tfm = cmpxchg(&essiv_hash_tfm, NULL, tfm); prev_tfm = cmpxchg(&essiv_hash_tfm, NULL, tfm);