These changes integrate new file encryption framework to use new V2 encryption policies. These changes were earlier reverted in 'commit4211691d29("Reverting crypto and incrementalfs changes")', as part of android-4.14.171 merge from Android common kernel. This patch attempts to bring them back post validation. commita9a5450ANDROID: dm: prevent default-key from being enabled without needed hooks commite1a94e6ANDROID: dm: add dm-default-key target for metadata encryption commit commit232fd35ANDROID: dm: enable may_passthrough_inline_crypto on some targets commit53bc059ANDROID: dm: add support for passing through inline crypto support commitaeed6dbANDROID: block: Introduce passthrough keyslot manager commit4f27c8bANDROID: ext4, f2fs: enable direct I/O with inline encryption commitc91db46BACKPORT: FROMLIST: scsi: ufs: add program_key() variant op commitf9a8e4aANDROID: block: export symbols needed for modules to use inline crypto commit75fea5fANDROID: block: fix some inline crypto bugs commit2871f73ANDROID: fscrypt: add support for hardware-wrapped keys commitbb5a657ANDROID: block: add KSM op to derive software secret from wrapped key commitd42ba87ANDROID: block: provide key size as input to inline crypto APIs commit86646ebANDROID: ufshcd-crypto: export cap find API commit83bc20eANDROID: scsi: ufs-qcom: Enable BROKEN_CRYPTO quirk flag commitc266a13ANDROID: scsi: ufs: Add quirk bit for controllers that don't play well with inline crypto commitea09b99ANDROID: cuttlefish_defconfig: Enable blk-crypto fallback commite12563cBACKPORT: FROMLIST: Update Inline Encryption from v5 to v6 of patch series commit8e8f55dANDROID: scsi: ufs: UFS init should not require inline crypto commitdae9899ANDROID: scsi: ufs: UFS crypto variant operations API commita69516dANDROID: cuttlefish_defconfig: enable inline encryption commitb8f7b23BACKPORT: FROMLIST: ext4: add inline encryption support commite64327fBACKPORT: FROMLIST: f2fs: add inline encryption support commita0dc8daBACKPORT: FROMLIST: fscrypt: add inline encryption support commit19c3c62BACKPORT: FROMLIST: scsi: ufs: Add inline encryption support to UFS commitf858a99BACKPORT: FROMLIST: scsi: ufs: UFS crypto API commit011b834BACKPORT: FROMLIST: scsi: ufs: UFS driver v2.1 spec crypto additions commitec0b569BACKPORT: FROMLIST: block: blk-crypto for Inline Encryption commit760b328ANDROID: block: Fix bio_crypt_should_process WARN_ON commit138adbbBACKPORT: FROMLIST: block: Add encryption context to struct bio commit66b5609BACKPORT: FROMLIST: block: Keyslot Manager for Inline Encryption Git-repo: https://android.googlesource.com/kernel/common/+/refs/heads/android-4.14-stable Git-commit:a9a545067aGit-commit:e1a94e6b17Git-commit:232fd353e4Git-commit:53bc059bc6Git-commit:aeed6db424Git-commit:4f27c8b90bGit-commit:c91db466b5Git-commit:f9a8e4a5c5Git-commit:75fea5f605Git-commit:2871f73194Git-commit:bb5a65771aGit-commit:d42ba87e29Git-commit:86646ebb17Git-commit:83bc20ed4bGit-commit:c266a1311eGit-commit:ea09b9954cGit-commit:e12563c18dGit-commit:8e8f55d1a7Git-commit:dae9899044Git-commit:a69516d091Git-commit:b8f7b23674Git-commit:e64327f571Git-commit:a0dc8da519Git-commit:19c3c62836Git-commit:f858a9981aGit-commit:011b8344c3Git-commit:ec0b569b5cGit-commit:760b3283e8Git-commit:138adbbe5eGit-commit:66b5609826Change-Id: I171d90de41185824e0c7515f3a3b43ab88f4e058 Signed-off-by: Neeraj Soni <neersoni@codeaurora.org>
143 lines
3.6 KiB
C
143 lines
3.6 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
/*
|
|
* Copyright 2019 Google LLC
|
|
*/
|
|
|
|
#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"
|
|
|
|
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)
|
|
{
|
|
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_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;
|
|
}
|
|
|
|
struct bio_crypt_ctx *bio_crypt_alloc_ctx(gfp_t gfp_mask)
|
|
{
|
|
return mempool_alloc(bio_crypt_ctx_pool, gfp_mask);
|
|
}
|
|
EXPORT_SYMBOL_GPL(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;
|
|
}
|
|
|
|
void bio_crypt_clone(struct bio *dst, struct bio *src, gfp_t gfp_mask)
|
|
{
|
|
const struct bio_crypt_ctx *src_bc = src->bi_crypt_context;
|
|
|
|
bio_clone_skip_dm_default_key(dst, src);
|
|
|
|
/*
|
|
* 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 (!src_bc || bio_crypt_fallback_crypted(src_bc))
|
|
return;
|
|
|
|
dst->bi_crypt_context = bio_crypt_alloc_ctx(gfp_mask);
|
|
*dst->bi_crypt_context = *src_bc;
|
|
|
|
if (src_bc->bc_keyslot >= 0)
|
|
keyslot_manager_get_slot(src_bc->bc_ksm, src_bc->bc_keyslot);
|
|
}
|
|
EXPORT_SYMBOL_GPL(bio_crypt_clone);
|
|
|
|
bool bio_crypt_should_process(struct request *rq)
|
|
{
|
|
struct bio *bio = rq->bio;
|
|
|
|
if (!bio || !bio->bi_crypt_context)
|
|
return false;
|
|
|
|
return rq->q->ksm == bio->bi_crypt_context->bc_ksm;
|
|
}
|
|
EXPORT_SYMBOL_GPL(bio_crypt_should_process);
|
|
|
|
/*
|
|
* Checks that two bio crypt contexts are compatible - i.e. that
|
|
* they are mergeable except for data_unit_num continuity.
|
|
*/
|
|
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)
|
|
return !bc2;
|
|
return bc2 && bc1->bc_key == bc2->bc_key;
|
|
}
|
|
|
|
/*
|
|
* 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,
|
|
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 (!bio_crypt_ctx_compatible(b_1, b_2))
|
|
return false;
|
|
|
|
return !bc1 || bio_crypt_dun_is_contiguous(bc1, b1_bytes, bc2->bc_dun);
|
|
}
|
|
|
|
void bio_crypt_ctx_release_keyslot(struct bio_crypt_ctx *bc)
|
|
{
|
|
keyslot_manager_put_slot(bc->bc_ksm, bc->bc_keyslot);
|
|
bc->bc_ksm = NULL;
|
|
bc->bc_keyslot = -1;
|
|
}
|
|
|
|
int bio_crypt_ctx_acquire_keyslot(struct bio_crypt_ctx *bc,
|
|
struct keyslot_manager *ksm)
|
|
{
|
|
int slot = keyslot_manager_get_slot_for_key(ksm, bc->bc_key);
|
|
|
|
if (slot < 0)
|
|
return slot;
|
|
|
|
bc->bc_keyslot = slot;
|
|
bc->bc_ksm = ksm;
|
|
return 0;
|
|
}
|