summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Biggers <ebiggers@google.com>2020-04-03 12:06:10 -0700
committerEric Biggers <ebiggers@google.com>2020-04-07 19:07:25 +0000
commit5578beabe36cc11d2668a0af668ed1ab49124e3a (patch)
treeff049baa31b7d0dca8c639732ca3b0fcc407db37
parent64029e7ca4f4bf40bccdabdb29d324a81afb11d1 (diff)
downloadgoldfish-5578beabe36cc11d2668a0af668ed1ab49124e3a.tar.gz
ANDROID: block: make blk_crypto_start_using_mode() properly check for support
If blk-crypto-fallback is needed but is disabled by kconfig, make blk_crypto_start_using_mode() return an error rather than succeeding. Use ENOPKG, which matches the error code used by fscrypt when crypto API support is missing with fs-layer encryption. Also, if blk-crypto-fallback is needed but the algorithm is missing from the kernel's crypto API, change the error code from ENOENT to ENOPKG. This is needed for VtsKernelEncryptionTest to pass on some devices. Bug: 137270441 Bug: 151100202 Test: 'atest vts_kernel_encryption_test' on Pixel 4 with the inline crypto patches backported, and also on Cuttlefish. Change-Id: Iedf00ca8e48c74a5d4c40b12712f38738a04ef11 Signed-off-by: Eric Biggers <ebiggers@google.com>
-rw-r--r--block/blk-crypto-fallback.c36
-rw-r--r--block/blk-crypto-internal.h9
-rw-r--r--block/blk-crypto.c25
-rw-r--r--include/linux/blk-crypto.h16
4 files changed, 49 insertions, 37 deletions
diff --git a/block/blk-crypto-fallback.c b/block/blk-crypto-fallback.c
index 195b04b5df0d..ba452cbafd44 100644
--- a/block/blk-crypto-fallback.c
+++ b/block/blk-crypto-fallback.c
@@ -487,21 +487,13 @@ out:
return false;
}
-/**
- * blk_crypto_start_using_mode() - Start using a crypto algorithm on a device
- * @mode_num: the blk_crypto_mode we want to allocate ciphers for.
- * @data_unit_size: the data unit size that will be used
- * @q: the request queue for the device
- *
- * Upper layers must call this function to ensure that a the crypto API fallback
- * has transforms for this algorithm, if they become necessary.
- *
- * Return: 0 on success and -err on error.
+/*
+ * Prepare blk-crypto-fallback for the specified crypto mode.
+ * Returns -ENOPKG if the needed crypto API support is missing.
*/
-int blk_crypto_start_using_mode(enum blk_crypto_mode_num mode_num,
- unsigned int data_unit_size,
- struct request_queue *q)
+int blk_crypto_fallback_start_using_mode(enum blk_crypto_mode_num mode_num)
{
+ const char *cipher_str = blk_crypto_modes[mode_num].cipher_str;
struct blk_crypto_keyslot *slotp;
unsigned int i;
int err = 0;
@@ -514,25 +506,20 @@ int blk_crypto_start_using_mode(enum blk_crypto_mode_num mode_num,
if (likely(smp_load_acquire(&tfms_inited[mode_num])))
return 0;
- /*
- * If the keyslot manager of the request queue supports this
- * crypto mode, then we don't need to allocate this mode.
- */
- if (keyslot_manager_crypto_mode_supported(q->ksm, mode_num,
- data_unit_size))
- return 0;
-
mutex_lock(&tfms_init_lock);
if (likely(tfms_inited[mode_num]))
goto out;
for (i = 0; i < blk_crypto_num_keyslots; i++) {
slotp = &blk_crypto_keyslots[i];
- slotp->tfms[mode_num] = crypto_alloc_skcipher(
- blk_crypto_modes[mode_num].cipher_str,
- 0, 0);
+ slotp->tfms[mode_num] = crypto_alloc_skcipher(cipher_str, 0, 0);
if (IS_ERR(slotp->tfms[mode_num])) {
err = PTR_ERR(slotp->tfms[mode_num]);
+ if (err == -ENOENT) {
+ pr_warn_once("Missing crypto API support for \"%s\"\n",
+ cipher_str);
+ err = -ENOPKG;
+ }
slotp->tfms[mode_num] = NULL;
goto out_free_tfms;
}
@@ -558,7 +545,6 @@ out:
mutex_unlock(&tfms_init_lock);
return err;
}
-EXPORT_SYMBOL_GPL(blk_crypto_start_using_mode);
int blk_crypto_fallback_evict_key(const struct blk_crypto_key *key)
{
diff --git a/block/blk-crypto-internal.h b/block/blk-crypto-internal.h
index 40d826b743da..4da998c803f2 100644
--- a/block/blk-crypto-internal.h
+++ b/block/blk-crypto-internal.h
@@ -19,6 +19,8 @@ extern const struct blk_crypto_mode blk_crypto_modes[];
#ifdef CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK
+int blk_crypto_fallback_start_using_mode(enum blk_crypto_mode_num mode_num);
+
int blk_crypto_fallback_submit_bio(struct bio **bio_ptr);
bool blk_crypto_queue_decrypt_bio(struct bio *bio);
@@ -29,6 +31,13 @@ bool bio_crypt_fallback_crypted(const struct bio_crypt_ctx *bc);
#else /* CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK */
+static inline int
+blk_crypto_fallback_start_using_mode(enum blk_crypto_mode_num mode_num)
+{
+ pr_warn_once("crypto API fallback is disabled\n");
+ return -ENOPKG;
+}
+
static inline bool bio_crypt_fallback_crypted(const struct bio_crypt_ctx *bc)
{
return false;
diff --git a/block/blk-crypto.c b/block/blk-crypto.c
index 88df1c0e7e5f..7bf2ff86d277 100644
--- a/block/blk-crypto.c
+++ b/block/blk-crypto.c
@@ -233,6 +233,31 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key,
EXPORT_SYMBOL_GPL(blk_crypto_init_key);
/**
+ * blk_crypto_start_using_mode() - Start using blk-crypto on a device
+ * @crypto_mode: the crypto mode that will be used
+ * @data_unit_size: the data unit size that will be used
+ * @q: the request queue for the device
+ *
+ * Upper layers must call this function to ensure that either the hardware
+ * supports the needed crypto settings, or the crypto API fallback has
+ * transforms for the needed mode allocated and ready to go.
+ *
+ * Return: 0 on success; -ENOPKG if the hardware doesn't support the crypto
+ * settings and blk-crypto-fallback is either disabled or the needed
+ * algorithm is disabled in the crypto API; or another -errno code.
+ */
+int blk_crypto_start_using_mode(enum blk_crypto_mode_num crypto_mode,
+ unsigned int data_unit_size,
+ struct request_queue *q)
+{
+ if (keyslot_manager_crypto_mode_supported(q->ksm, crypto_mode,
+ data_unit_size))
+ return 0;
+ return blk_crypto_fallback_start_using_mode(crypto_mode);
+}
+EXPORT_SYMBOL_GPL(blk_crypto_start_using_mode);
+
+/**
* blk_crypto_evict_key() - Evict a key from any inline encryption hardware
* it may have been programmed into
* @q: The request queue who's keyslot manager this key might have been
diff --git a/include/linux/blk-crypto.h b/include/linux/blk-crypto.h
index 913b367d42bd..3b6cb9f7b888 100644
--- a/include/linux/blk-crypto.h
+++ b/include/linux/blk-crypto.h
@@ -22,6 +22,10 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key,
enum blk_crypto_mode_num crypto_mode,
unsigned int data_unit_size);
+int blk_crypto_start_using_mode(enum blk_crypto_mode_num crypto_mode,
+ unsigned int data_unit_size,
+ struct request_queue *q);
+
int blk_crypto_evict_key(struct request_queue *q,
const struct blk_crypto_key *key);
@@ -41,22 +45,10 @@ static inline bool blk_crypto_endio(struct bio *bio)
#ifdef CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK
-int blk_crypto_start_using_mode(enum blk_crypto_mode_num mode_num,
- unsigned int data_unit_size,
- struct request_queue *q);
-
int blk_crypto_fallback_init(void);
#else /* CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK */
-static inline int
-blk_crypto_start_using_mode(enum blk_crypto_mode_num mode_num,
- unsigned int data_unit_size,
- struct request_queue *q)
-{
- return 0;
-}
-
static inline int blk_crypto_fallback_init(void)
{
return 0;