block/blk-crypto-fallback.c
Source file repositories/reference/linux-study-clean/block/blk-crypto-fallback.c
File Facts
- System
- Linux kernel
- Corpus path
block/blk-crypto-fallback.c- Extension
.c- Size
- 20305 bytes
- Lines
- 678
- Domain
- Representative Device Path
- Bucket
- PCIe NVMe Storage Path
- Inferred role
- Representative Device Path: implementation source
- Status
- source implementation candidate
Why This File Exists
Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
crypto/skcipher.hlinux/blk-crypto.hlinux/blk-crypto-profile.hlinux/blkdev.hlinux/crypto.hlinux/mempool.hlinux/module.hlinux/random.hlinux/scatterlist.hblk-cgroup.hblk-crypto-internal.h
Detected Declarations
struct bio_fallback_crypt_ctxfunction blk_crypto_fallback_evict_keyslotfunction blk_crypto_fallback_keyslot_programfunction blk_crypto_fallback_keyslot_evictfunction blk_crypto_fallback_encrypt_endiofunction blk_crypto_fallback_tfmfunction blk_crypto_dun_to_ivfunction __blk_crypto_fallback_encrypt_biofunction blk_crypto_fallback_encrypt_biofunction __blk_crypto_fallback_decrypt_biofunction blk_crypto_fallback_decrypt_biofunction blk_crypto_fallback_decrypt_endiofunction biosfunction blk_crypto_fallback_evict_keyfunction blk_crypto_fallback_initfunction blk_crypto_fallback_start_using_mode
Annotated Snippet
struct bio_fallback_crypt_ctx {
struct bio_crypt_ctx crypt_ctx;
/*
* Copy of the bvec_iter when this bio was submitted.
* We only want to en/decrypt the part of the bio as described by the
* bvec_iter upon submission because bio might be split before being
* resubmitted
*/
struct bvec_iter crypt_iter;
union {
struct {
struct work_struct work;
struct bio *bio;
};
struct {
void *bi_private_orig;
bio_end_io_t *bi_end_io_orig;
};
};
};
static struct kmem_cache *bio_fallback_crypt_ctx_cache;
static mempool_t *bio_fallback_crypt_ctx_pool;
/*
* Allocating a crypto tfm during I/O can deadlock, so we have to preallocate
* all of a mode's tfms when that mode starts being used. Since each mode may
* need all the keyslots at some point, each mode needs its own tfm for each
* keyslot; thus, a keyslot may contain tfms for multiple modes. However, to
* match the behavior of real inline encryption hardware (which only supports a
* single encryption context per keyslot), we only allow one tfm per keyslot to
* be used at a time - the rest of the unused tfms have their keys cleared.
*/
static DEFINE_MUTEX(tfms_init_lock);
static bool tfms_inited[BLK_ENCRYPTION_MODE_MAX];
static struct blk_crypto_fallback_keyslot {
enum blk_crypto_mode_num crypto_mode;
struct crypto_sync_skcipher *tfms[BLK_ENCRYPTION_MODE_MAX];
} *blk_crypto_keyslots;
static struct blk_crypto_profile *blk_crypto_fallback_profile;
static struct workqueue_struct *blk_crypto_wq;
static mempool_t *blk_crypto_bounce_page_pool;
static struct bio_set enc_bio_set;
/*
* This is the key we set when evicting a keyslot. This *should* be the all 0's
* key, but AES-XTS rejects that key, so we use some random bytes instead.
*/
static u8 blank_key[BLK_CRYPTO_MAX_RAW_KEY_SIZE];
static void blk_crypto_fallback_evict_keyslot(unsigned int slot)
{
struct blk_crypto_fallback_keyslot *slotp = &blk_crypto_keyslots[slot];
enum blk_crypto_mode_num crypto_mode = slotp->crypto_mode;
int err;
WARN_ON(slotp->crypto_mode == BLK_ENCRYPTION_MODE_INVALID);
/* Clear the key in the skcipher */
err = crypto_sync_skcipher_setkey(slotp->tfms[crypto_mode], blank_key,
blk_crypto_modes[crypto_mode].keysize);
WARN_ON(err);
slotp->crypto_mode = BLK_ENCRYPTION_MODE_INVALID;
}
static int
blk_crypto_fallback_keyslot_program(struct blk_crypto_profile *profile,
const struct blk_crypto_key *key,
unsigned int slot)
{
struct blk_crypto_fallback_keyslot *slotp = &blk_crypto_keyslots[slot];
const enum blk_crypto_mode_num crypto_mode =
key->crypto_cfg.crypto_mode;
int err;
if (crypto_mode != slotp->crypto_mode &&
slotp->crypto_mode != BLK_ENCRYPTION_MODE_INVALID)
blk_crypto_fallback_evict_keyslot(slot);
slotp->crypto_mode = crypto_mode;
err = crypto_sync_skcipher_setkey(slotp->tfms[crypto_mode], key->bytes,
key->size);
if (err) {
blk_crypto_fallback_evict_keyslot(slot);
return err;
}
return 0;
}
Annotation
- Immediate include surface: `crypto/skcipher.h`, `linux/blk-crypto.h`, `linux/blk-crypto-profile.h`, `linux/blkdev.h`, `linux/crypto.h`, `linux/mempool.h`, `linux/module.h`, `linux/random.h`.
- Detected declarations: `struct bio_fallback_crypt_ctx`, `function blk_crypto_fallback_evict_keyslot`, `function blk_crypto_fallback_keyslot_program`, `function blk_crypto_fallback_keyslot_evict`, `function blk_crypto_fallback_encrypt_endio`, `function blk_crypto_fallback_tfm`, `function blk_crypto_dun_to_iv`, `function __blk_crypto_fallback_encrypt_bio`, `function blk_crypto_fallback_encrypt_bio`, `function __blk_crypto_fallback_decrypt_bio`.
- Atlas domain: Representative Device Path / PCIe NVMe Storage Path.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.