drivers/md/dm-inlinecrypt.c

Source file repositories/reference/linux-study-clean/drivers/md/dm-inlinecrypt.c

File Facts

System
Linux kernel
Corpus path
drivers/md/dm-inlinecrypt.c
Extension
.c
Size
16023 bytes
Lines
619
Domain
Driver Families
Bucket
drivers/md
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct inlinecrypt_ctx {
	struct dm_dev *dev;
	sector_t start;
	const char *cipher_string;
	unsigned int key_size;
	u64 iv_offset;
	unsigned int sector_size;
	unsigned int sector_bits;
	enum blk_crypto_key_type key_type;
	struct blk_crypto_key key;
	u64 max_dun;
};

static const struct dm_inlinecrypt_cipher *
lookup_cipher(const char *cipher_string)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(dm_inlinecrypt_ciphers); i++) {
		if (strcmp(cipher_string, dm_inlinecrypt_ciphers[i].name) == 0)
			return &dm_inlinecrypt_ciphers[i];
	}
	return NULL;
}

static void inlinecrypt_dtr(struct dm_target *ti)
{
	struct inlinecrypt_ctx *ctx = ti->private;

	if (ctx->dev) {
		if (ctx->key.size)
			blk_crypto_evict_key(ctx->dev->bdev, &ctx->key);
		dm_put_device(ti, ctx->dev);
	}
	kfree_sensitive(ctx->cipher_string);
	kfree_sensitive(ctx);
}

#ifdef CONFIG_KEYS

static bool contains_whitespace(const char *str)
{
	while (*str)
		if (isspace(*str++))
			return true;
	return false;
}

static int set_key_user(struct key *key, char *key_bytes,
			const unsigned int key_bytes_size)
{
	const struct user_key_payload *ukp;

	ukp = user_key_payload_locked(key);
	if (!ukp)
		return -EKEYREVOKED;

	if (key_bytes_size != ukp->datalen)
		return -EINVAL;

	memcpy(key_bytes, ukp->data, key_bytes_size);

	return 0;
}

static int inlinecrypt_get_keyring_key(const char *key_string, u8 *key_bytes,
					const unsigned int key_bytes_size)
{
	char *key_desc;
	int ret;
	struct key_type *type;
	struct key *key;
	int (*set_key)(struct key *key, char *key_bytes,
				   const unsigned int key_bytes_size);

	/*
	 * Reject key_string with whitespace. dm core currently lacks code for
	 * proper whitespace escaping in arguments on DM_TABLE_STATUS path.
	 */
	if (contains_whitespace(key_string)) {
		DMERR("whitespace chars not allowed in key string");
		return -EINVAL;
	}

	/* look for next ':' separating key_type from key_description */
	key_desc = strchr(key_string, ':');
	if (!key_desc || key_desc == key_string || !strlen(key_desc + 1))
		return -EINVAL;

	if (!strncmp(key_string, "logon:", key_desc - key_string + 1)) {

Annotation

Implementation Notes