Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a1423568 authored by Barani Muthukumaran's avatar Barani Muthukumaran Committed by Todd Kjos
Browse files

ANDROID: dm: add support for passing through derive_raw_secret



Update the device-mapper core to support exposing the inline crypto
support of wrapped keys through the device-mapper device.

derive_raw_secret in keyslot manager is used to derive the software
raw secret from the given wrapped keyblob using the underlying blk
device. Given that the raw_secret is the same for a given wrapped
keyblob the call exits when the first underlying blk-device suceeds.

Bug: 147209885

Test: Validated FBE with wrappedkey_v0 when /data is mounted on a
      dm device.

Change-Id: Ia49ed61613607f8b82f2be0615e5b6d2f7533859
Signed-off-by: default avatarBarani Muthukumaran <bmuthuku@codeaurora.org>
parent 3ab19729
Loading
Loading
Loading
Loading
+71 −0
Original line number Diff line number Diff line
@@ -2301,8 +2301,79 @@ static int dm_keyslot_evict(struct keyslot_manager *ksm,
	return args.err;
}

struct dm_derive_raw_secret_args {
	const u8 *wrapped_key;
	unsigned int wrapped_key_size;
	u8 *secret;
	unsigned int secret_size;
	int err;
};

static int dm_derive_raw_secret_callback(struct dm_target *ti,
					 struct dm_dev *dev, sector_t start,
					 sector_t len, void *data)
{
	struct dm_derive_raw_secret_args *args = data;
	struct request_queue *q = dev->bdev->bd_queue;

	if (!args->err)
		return 0;

	if (!q->ksm) {
		args->err = -EOPNOTSUPP;
		return 0;
	}

	args->err = keyslot_manager_derive_raw_secret(q->ksm, args->wrapped_key,
						args->wrapped_key_size,
						args->secret,
						args->secret_size);
	/* Try another device in case this fails. */
	return 0;
}

/*
 * Retrieve the raw_secret from the underlying device. Given that
 * only only one raw_secret can exist for a particular wrappedkey,
 * retrieve it only from the first device that supports derive_raw_secret()
 */
static int dm_derive_raw_secret(struct keyslot_manager *ksm,
				const u8 *wrapped_key,
				unsigned int wrapped_key_size,
				u8 *secret, unsigned int secret_size)
{
	struct mapped_device *md = keyslot_manager_private(ksm);
	struct dm_derive_raw_secret_args args = {
		.wrapped_key = wrapped_key,
		.wrapped_key_size = wrapped_key_size,
		.secret = secret,
		.secret_size = secret_size,
		.err = -EOPNOTSUPP,
	};
	struct dm_table *t;
	int srcu_idx;
	int i;
	struct dm_target *ti;

	t = dm_get_live_table(md, &srcu_idx);
	if (!t)
		return -EOPNOTSUPP;
	for (i = 0; i < dm_table_get_num_targets(t); i++) {
		ti = dm_table_get_target(t, i);
		if (!ti->type->iterate_devices)
			continue;
		ti->type->iterate_devices(ti, dm_derive_raw_secret_callback,
					  &args);
		if (!args.err)
			break;
	}
	dm_put_live_table(md, srcu_idx);
	return args.err;
}

static struct keyslot_mgmt_ll_ops dm_ksm_ll_ops = {
	.keyslot_evict = dm_keyslot_evict,
	.derive_raw_secret = dm_derive_raw_secret,
};

static int dm_init_inline_encryption(struct mapped_device *md)