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

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

ANDROID: block: provide key size as input to inline crypto APIs



Currently, blk-crypto uses the algorithm to determine the size of keys.
However, some inline encryption hardware supports protecting keys from
software by wrapping the storage keys with an ephemeral key.  Since
these wrapped keys are not of a fixed size, add the capability to
provide the key size when initializing a blk_crypto_key, and update the
keyslot manager to take size into account when comparing keys.

Bug: 147209885

Change-Id: Ibc2e4807e0a0ec473e72d131e0f20abb3a6033b5
Co-developed-by: default avatarGaurav Kashyap <gaurkash@codeaurora.org>
Signed-off-by: default avatarGaurav Kashyap <gaurkash@codeaurora.org>
Signed-off-by: default avatarBarani Muthukumaran <bmuthuku@codeaurora.org>
Signed-off-by: default avatarEric Biggers <ebiggers@google.com>
parent 4f6a1f4a
Loading
Loading
Loading
Loading
+9763 −9526

File changed.

Preview size limit exceeded, changes collapsed.

+14 −7
Original line number Diff line number Diff line
@@ -171,15 +171,19 @@ bool blk_crypto_endio(struct bio *bio)
/**
 * blk_crypto_init_key() - Prepare a key for use with blk-crypto
 * @blk_key: Pointer to the blk_crypto_key to initialize.
 * @raw_key: Pointer to the raw key.  Must be the correct length for the chosen
 *	     @crypto_mode; see blk_crypto_modes[].
 * @raw_key: Pointer to the raw key.
 * @raw_key_size: Size of raw key.  Must be at least the required size for the
 *                chosen @crypto_mode; see blk_crypto_modes[].  (It's allowed
 *                to be longer than the mode's actual key size, in order to
 *                support inline encryption hardware that accepts wrapped keys.)
 * @crypto_mode: identifier for the encryption algorithm to use
 * @data_unit_size: the data unit size to use for en/decryption
 *
 * Return: The blk_crypto_key that was prepared, or an ERR_PTR() on error.  When
 *	   done using the key, it must be freed with blk_crypto_free_key().
 */
int blk_crypto_init_key(struct blk_crypto_key *blk_key, const u8 *raw_key,
int blk_crypto_init_key(struct blk_crypto_key *blk_key,
			const u8 *raw_key, unsigned int raw_key_size,
			enum blk_crypto_mode_num crypto_mode,
			unsigned int data_unit_size)
{
@@ -191,8 +195,11 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key, const u8 *raw_key,
	if (crypto_mode >= ARRAY_SIZE(blk_crypto_modes))
		return -EINVAL;

	BUILD_BUG_ON(BLK_CRYPTO_MAX_WRAPPED_KEY_SIZE < BLK_CRYPTO_MAX_KEY_SIZE);

	mode = &blk_crypto_modes[crypto_mode];
	if (mode->keysize == 0)
	if (raw_key_size < mode->keysize ||
	    raw_key_size > BLK_CRYPTO_MAX_WRAPPED_KEY_SIZE)
		return -EINVAL;

	if (!is_power_of_2(data_unit_size))
@@ -201,8 +208,8 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key, const u8 *raw_key,
	blk_key->crypto_mode = crypto_mode;
	blk_key->data_unit_size = data_unit_size;
	blk_key->data_unit_size_bits = ilog2(data_unit_size);
	blk_key->size = mode->keysize;
	memcpy(blk_key->raw, raw_key, mode->keysize);
	blk_key->size = raw_key_size;
	memcpy(blk_key->raw, raw_key, raw_key_size);

	/*
	 * The keyslot manager uses the SipHash of the key to implement O(1) key
@@ -210,7 +217,7 @@ int blk_crypto_init_key(struct blk_crypto_key *blk_key, const u8 *raw_key,
	 * precomputed here so that it only needs to be computed once per key.
	 */
	get_random_once(&hash_key, sizeof(hash_key));
	blk_key->hash = siphash(raw_key, mode->keysize, &hash_key);
	blk_key->hash = siphash(raw_key, raw_key_size, &hash_key);

	return 0;
}
+1 −0
Original line number Diff line number Diff line
@@ -168,6 +168,7 @@ static int find_keyslot(struct keyslot_manager *ksm,
	hlist_for_each_entry(slotp, head, hash_node) {
		if (slotp->key.hash == key->hash &&
		    slotp->key.crypto_mode == key->crypto_mode &&
		    slotp->key.size == key->size &&
		    slotp->key.data_unit_size == key->data_unit_size &&
		    !crypto_memneq(slotp->key.raw, key->raw, key->size))
			return slotp - ksm->slots;
+2 −2
Original line number Diff line number Diff line
@@ -74,8 +74,8 @@ int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key,
	else
		sb->s_cop->get_devices(sb, blk_key->devs);

	err = blk_crypto_init_key(&blk_key->base, raw_key, crypto_mode,
				  sb->s_blocksize);
	err = blk_crypto_init_key(&blk_key->base, raw_key, ci->ci_mode->keysize,
				  crypto_mode, sb->s_blocksize);
	if (err) {
		fscrypt_err(inode, "error %d initializing blk-crypto key", err);
		goto fail;
+2 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ enum blk_crypto_mode_num {
#ifdef CONFIG_BLK_INLINE_ENCRYPTION

#define BLK_CRYPTO_MAX_KEY_SIZE		64
#define BLK_CRYPTO_MAX_WRAPPED_KEY_SIZE		128

/**
 * struct blk_crypto_key - an inline encryption key
@@ -41,7 +42,7 @@ struct blk_crypto_key {
	unsigned int data_unit_size_bits;
	unsigned int size;
	unsigned int hash;
	u8 raw[BLK_CRYPTO_MAX_KEY_SIZE];
	u8 raw[BLK_CRYPTO_MAX_WRAPPED_KEY_SIZE];
};

#define BLK_CRYPTO_MAX_IV_SIZE		32
Loading