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 @@ -232,6 +232,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 diff --git a/include/linux/blk-crypto.h b/include/linux/blk-crypto.h index 2d871a7a0f5a..2416a0a6e6b3 100644 --- a/include/linux/blk-crypto.h +++ b/include/linux/blk-crypto.h @@ -20,6 +20,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); @@ -39,22 +43,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;