// 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)
{
	struct bio_crypt_ctx *bc = mempool_alloc(bio_crypt_ctx_pool, gfp_mask);

	if (bc)
		bc->hie_ext4 = false;

	return bc;
}
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;
}
