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

Commit 49107cf0 authored by Blagovest Kolenichev's avatar Blagovest Kolenichev
Browse files

Revert "BACKPORT: FROMLIST: Update Inline Encryption from v5 to v6 of patch series"



This reverts commit b7b3af96.

This is a preparation change for merging android-5.4.12 into
msm-5.4 branch. The reverted change is committed already via:

c83b5527 Merge fbe changes from upstream 5.4

Change-Id: I5c9aad30ee41c04e2b77372fc309568aab88d324
Signed-off-by: default avatarBlagovest Kolenichev <bkolenichev@codeaurora.org>
parent 4bbb9606
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -97,7 +97,7 @@ Blk-crypto ensures that:

- The bio's encryption context is programmed into a keyslot in the KSM of the
  request queue that the bio is being submitted to (or the crypto API fallback
  KSM if the request queue doesn't have a KSM), and that the ``bc_ksm``
  KSM if the request queue doesn't have a KSM), and that the ``processing_ksm``
  in the ``bi_crypt_context`` is set to this KSM

- That the bio has its own individual reference to the keyslot in this KSM.
@@ -107,7 +107,7 @@ Blk-crypto ensures that:
  ensuring that the bio has a valid reference to the keyslot when, for e.g., the
  crypto API fallback KSM in blk-crypto performs crypto on the device's behalf.
  The individual references are ensured by increasing the refcount for the
  keyslot in the ``bc_ksm`` when a bio with a programmed encryption
  keyslot in the ``processing_ksm`` when a bio with a programmed encryption
  context is cloned.


@@ -120,7 +120,7 @@ been programmed into any keyslot in any KSM (for e.g. a bio from the FS).
  request queue the bio is being submitted to (and if this KSM does not exist,
  then it will program it into blk-crypto's internal KSM for crypto API
  fallback). The KSM that this encryption context was programmed into is stored
  as the ``bc_ksm`` in the bio's ``bi_crypt_context``.
  as the ``processing_ksm`` in the bio's ``bi_crypt_context``.

**Case 2:** blk-crypto is given a bio whose encryption context has already been
programmed into a keyslot in the *crypto API fallback* KSM.
@@ -138,7 +138,7 @@ KSM).
This way, when a device driver is processing a bio, it can be sure that
the bio's encryption context has been programmed into some KSM (either the
device driver's request queue's KSM, or blk-crypto's crypto API fallback KSM).
It then simply needs to check if the bio's ``bc_ksm`` is the device's
It then simply needs to check if the bio's processing_ksm is the device's
request queue's KSM. If so, then it should proceed with IE. If not, it should
simply do nothing with respect to crypto, because some other KSM (perhaps the
blk-crypto crypto API fallback KSM) is handling the en/decryption.
+4 −11
Original line number Diff line number Diff line
@@ -179,20 +179,13 @@ config BLK_SED_OPAL

config BLK_INLINE_ENCRYPTION
	bool "Enable inline encryption support in block layer"
	help
	  Build the blk-crypto subsystem. Enabling this lets the
	  block layer handle encryption, so users can take
	  advantage of inline encryption hardware if present.

config BLK_INLINE_ENCRYPTION_FALLBACK
	bool "Enable crypto API fallback for blk-crypto"
	depends on BLK_INLINE_ENCRYPTION
	select CRYPTO
	select CRYPTO_BLKCIPHER
	help
	  Enabling this lets the block layer handle inline encryption
	  by falling back to the kernel crypto API when inline
	  encryption hardware is not present.
	  Build the blk-crypto subsystem.
	  Enabling this lets the block layer handle encryption,
	  so users can take advantage of inline encryption
	  hardware if present.

menu "Partition Types"

+0 −1
Original line number Diff line number Diff line
@@ -38,4 +38,3 @@ obj-$(CONFIG_BLK_SED_OPAL) += sed-opal.o
obj-$(CONFIG_BLK_PM)		+= blk-pm.o
obj-$(CONFIG_BLK_INLINE_ENCRYPTION)	+= keyslot-manager.o bio-crypt-ctx.o \
					   blk-crypto.o
obj-$(CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK)	+= blk-crypto-fallback.o
 No newline at end of file
+60 −55
Original line number Diff line number Diff line
@@ -5,43 +5,26 @@

#include <linux/bio.h>
#include <linux/blkdev.h>
#include <linux/keyslot-manager.h>
#include <linux/module.h>
#include <linux/slab.h>

#include "blk-crypto-internal.h"
#include <linux/keyslot-manager.h>

static int num_prealloc_crypt_ctxs = 128;

module_param(num_prealloc_crypt_ctxs, int, 0444);
MODULE_PARM_DESC(num_prealloc_crypt_ctxs,
		"Number of bio crypto contexts to preallocate");

static struct kmem_cache *bio_crypt_ctx_cache;
static mempool_t *bio_crypt_ctx_pool;

int __init bio_crypt_ctx_init(void)
int bio_crypt_ctx_init(void)
{
	size_t i;

	bio_crypt_ctx_cache = KMEM_CACHE(bio_crypt_ctx, 0);
	if (!bio_crypt_ctx_cache)
		return -ENOMEM;

	bio_crypt_ctx_pool = mempool_create_slab_pool(num_prealloc_crypt_ctxs,
	bio_crypt_ctx_pool = mempool_create_slab_pool(
					num_prealloc_crypt_ctxs,
					bio_crypt_ctx_cache);

	if (!bio_crypt_ctx_pool)
		return -ENOMEM;

	/* This is assumed in various places. */
	BUILD_BUG_ON(BLK_ENCRYPTION_MODE_INVALID != 0);

	/* Sanity check that no algorithm exceeds the defined limits. */
	for (i = 0; i < BLK_ENCRYPTION_MODE_MAX; i++) {
		BUG_ON(blk_crypto_modes[i].keysize > BLK_CRYPTO_MAX_KEY_SIZE);
		BUG_ON(blk_crypto_modes[i].ivsize > BLK_CRYPTO_MAX_IV_SIZE);
	}

	return 0;
}

@@ -49,43 +32,51 @@ struct bio_crypt_ctx *bio_crypt_alloc_ctx(gfp_t gfp_mask)
{
	return mempool_alloc(bio_crypt_ctx_pool, gfp_mask);
}
EXPORT_SYMBOL(bio_crypt_alloc_ctx);

void bio_crypt_free_ctx(struct bio *bio)
{
	mempool_free(bio->bi_crypt_context, bio_crypt_ctx_pool);
	bio->bi_crypt_context = NULL;
}
EXPORT_SYMBOL(bio_crypt_free_ctx);

void bio_crypt_clone(struct bio *dst, struct bio *src, gfp_t gfp_mask)
int bio_crypt_clone(struct bio *dst, struct bio *src, gfp_t gfp_mask)
{
	const struct bio_crypt_ctx *src_bc = src->bi_crypt_context;

	/*
	 * If a bio is fallback_crypted, then it will be decrypted when
	 * bio_endio is called. As we only want the data to be decrypted once,
	 * copies of the bio must not have have a crypt context.
	 * If a bio is swhandled, then it will be decrypted when bio_endio
	 * is called. As we only want the data to be decrypted once, copies
	 * of the bio must not have have a crypt context.
	 */
	if (!src_bc || bio_crypt_fallback_crypted(src_bc))
		return;
	if (!bio_has_crypt_ctx(src) || bio_crypt_swhandled(src))
		return 0;

	dst->bi_crypt_context = bio_crypt_alloc_ctx(gfp_mask);
	*dst->bi_crypt_context = *src_bc;
	if (!dst->bi_crypt_context)
		return -ENOMEM;

	*dst->bi_crypt_context = *src->bi_crypt_context;

	if (src_bc->bc_keyslot >= 0)
		keyslot_manager_get_slot(src_bc->bc_ksm, src_bc->bc_keyslot);
	if (bio_crypt_has_keyslot(src))
		keyslot_manager_get_slot(src->bi_crypt_context->processing_ksm,
					 src->bi_crypt_context->keyslot);

	return 0;
}
EXPORT_SYMBOL_GPL(bio_crypt_clone);
EXPORT_SYMBOL(bio_crypt_clone);

bool bio_crypt_should_process(struct request *rq)
bool bio_crypt_should_process(struct bio *bio, struct request_queue *q)
{
	struct bio *bio = rq->bio;
	if (!bio_has_crypt_ctx(bio))
		return false;

	if (!bio || !bio->bi_crypt_context)
	if (q->ksm != bio->bi_crypt_context->processing_ksm)
		return false;

	return rq->q->ksm == bio->bi_crypt_context->bc_ksm;
	WARN_ON(!bio_crypt_has_keyslot(bio));
	return true;
}
EXPORT_SYMBOL_GPL(bio_crypt_should_process);
EXPORT_SYMBOL(bio_crypt_should_process);

/*
 * Checks that two bio crypt contexts are compatible - i.e. that
@@ -96,18 +87,22 @@ bool bio_crypt_ctx_compatible(struct bio *b_1, struct bio *b_2)
	struct bio_crypt_ctx *bc1 = b_1->bi_crypt_context;
	struct bio_crypt_ctx *bc2 = b_2->bi_crypt_context;

	if (bc1 != bc2)
	if (bio_has_crypt_ctx(b_1) != bio_has_crypt_ctx(b_2))
		return false;

	return !bc1 || bc1->bc_key == bc2->bc_key;
	if (!bio_has_crypt_ctx(b_1))
		return true;

	return bc1->keyslot == bc2->keyslot &&
	       bc1->data_unit_size_bits == bc2->data_unit_size_bits;
}

/*
 * Checks that two bio crypt contexts are compatible, and also
 * that their data_unit_nums are continuous (and can hence be merged)
 * in the order b_1 followed by b_2.
 */
bool bio_crypt_ctx_mergeable(struct bio *b_1, unsigned int b1_bytes,
bool bio_crypt_ctx_back_mergeable(struct bio *b_1,
				  unsigned int b1_sectors,
				  struct bio *b_2)
{
	struct bio_crypt_ctx *bc1 = b_1->bi_crypt_context;
@@ -116,25 +111,35 @@ bool bio_crypt_ctx_mergeable(struct bio *b_1, unsigned int b1_bytes,
	if (!bio_crypt_ctx_compatible(b_1, b_2))
		return false;

	return !bc1 || bio_crypt_dun_is_contiguous(bc1, b1_bytes, bc2->bc_dun);
	return !bio_has_crypt_ctx(b_1) ||
		(bc1->data_unit_num +
		(b1_sectors >> (bc1->data_unit_size_bits - 9)) ==
		bc2->data_unit_num);
}

void bio_crypt_ctx_release_keyslot(struct bio_crypt_ctx *bc)
void bio_crypt_ctx_release_keyslot(struct bio *bio)
{
	keyslot_manager_put_slot(bc->bc_ksm, bc->bc_keyslot);
	bc->bc_ksm = NULL;
	bc->bc_keyslot = -1;
	struct bio_crypt_ctx *crypt_ctx = bio->bi_crypt_context;

	keyslot_manager_put_slot(crypt_ctx->processing_ksm, crypt_ctx->keyslot);
	bio->bi_crypt_context->processing_ksm = NULL;
	bio->bi_crypt_context->keyslot = -1;
}

int bio_crypt_ctx_acquire_keyslot(struct bio_crypt_ctx *bc,
				  struct keyslot_manager *ksm)
int bio_crypt_ctx_acquire_keyslot(struct bio *bio, struct keyslot_manager *ksm)
{
	int slot = keyslot_manager_get_slot_for_key(ksm, bc->bc_key);
	int slot;
	enum blk_crypto_mode_num crypto_mode = bio_crypto_mode(bio);

	if (!ksm)
		return -ENOMEM;

	slot = keyslot_manager_get_slot_for_key(ksm,
			bio_crypt_raw_key(bio), crypto_mode,
			1 << bio->bi_crypt_context->data_unit_size_bits);
	if (slot < 0)
		return slot;

	bc->bc_keyslot = slot;
	bc->bc_ksm = ksm;
	bio_crypt_set_keyslot(bio, slot, ksm);
	return 0;
}
+5 −3
Original line number Diff line number Diff line
@@ -234,8 +234,6 @@ struct bio_vec *bvec_alloc(gfp_t gfp_mask, int nr, unsigned long *idx,
void bio_uninit(struct bio *bio)
{
	bio_disassociate_blkg(bio);

	bio_crypt_free_ctx(bio);
}
EXPORT_SYMBOL(bio_uninit);

@@ -244,6 +242,7 @@ static void bio_free(struct bio *bio)
	struct bio_set *bs = bio->bi_pool;
	void *p;

	bio_crypt_free_ctx(bio);
	bio_uninit(bio);

	if (bs) {
@@ -654,7 +653,10 @@ struct bio *bio_clone_fast(struct bio *bio, gfp_t gfp_mask, struct bio_set *bs)

	__bio_clone_fast(b, bio);

	bio_crypt_clone(b, bio, gfp_mask);
	if (bio_crypt_clone(b, bio, gfp_mask) < 0) {
		bio_put(b);
		return NULL;
	}

	if (bio_integrity(bio) &&
	    bio_integrity_clone(b, bio, gfp_mask) < 0) {
Loading