drivers/crypto/xilinx/zynqmp-sha.c

Source file repositories/reference/linux-study-clean/drivers/crypto/xilinx/zynqmp-sha.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/xilinx/zynqmp-sha.c
Extension
.c
Size
6828 bytes
Lines
259
Domain
Driver Families
Bucket
drivers/crypto
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct zynqmp_sha_drv_ctx {
	struct shash_alg sha3_384;
	struct device *dev;
};

struct zynqmp_sha_tfm_ctx {
	struct device *dev;
	struct crypto_shash *fbk_tfm;
};

static dma_addr_t update_dma_addr, final_dma_addr;
static char *ubuf, *fbuf;

static DEFINE_SPINLOCK(zynqmp_sha_lock);

static int zynqmp_sha_init_tfm(struct crypto_shash *hash)
{
	const char *fallback_driver_name = crypto_shash_alg_name(hash);
	struct zynqmp_sha_tfm_ctx *tfm_ctx = crypto_shash_ctx(hash);
	struct shash_alg *alg = crypto_shash_alg(hash);
	struct crypto_shash *fallback_tfm;
	struct zynqmp_sha_drv_ctx *drv_ctx;

	drv_ctx = container_of(alg, struct zynqmp_sha_drv_ctx, sha3_384);
	tfm_ctx->dev = drv_ctx->dev;

	/* Allocate a fallback and abort if it failed. */
	fallback_tfm = crypto_alloc_shash(fallback_driver_name, 0,
					  CRYPTO_ALG_NEED_FALLBACK);
	if (IS_ERR(fallback_tfm))
		return PTR_ERR(fallback_tfm);

	if (crypto_shash_descsize(hash) <
	    crypto_shash_statesize(tfm_ctx->fbk_tfm)) {
		crypto_free_shash(fallback_tfm);
		return -EINVAL;
	}

	tfm_ctx->fbk_tfm = fallback_tfm;

	return 0;
}

static void zynqmp_sha_exit_tfm(struct crypto_shash *hash)
{
	struct zynqmp_sha_tfm_ctx *tfm_ctx = crypto_shash_ctx(hash);

	crypto_free_shash(tfm_ctx->fbk_tfm);
}

static int zynqmp_sha_continue(struct shash_desc *desc,
			       struct shash_desc *fbdesc, int err)
{
	err = err ?: crypto_shash_export(fbdesc, shash_desc_ctx(desc));
	shash_desc_zero(fbdesc);
	return err;
}

static int zynqmp_sha_init(struct shash_desc *desc)
{
	struct zynqmp_sha_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
	struct crypto_shash *fbtfm = tctx->fbk_tfm;
	SHASH_DESC_ON_STACK(fbdesc, fbtfm);
	int err;

	fbdesc->tfm = fbtfm;
	err = crypto_shash_init(fbdesc);
	return zynqmp_sha_continue(desc, fbdesc, err);
}

static int zynqmp_sha_update(struct shash_desc *desc, const u8 *data, unsigned int length)
{
	struct zynqmp_sha_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
	struct crypto_shash *fbtfm = tctx->fbk_tfm;
	SHASH_DESC_ON_STACK(fbdesc, fbtfm);
	int err;

	fbdesc->tfm = fbtfm;
	err = crypto_shash_import(fbdesc, shash_desc_ctx(desc)) ?:
	      crypto_shash_update(fbdesc, data, length);
	return zynqmp_sha_continue(desc, fbdesc, err);
}

static int zynqmp_sha_finup(struct shash_desc *desc, const u8 *data, unsigned int length, u8 *out)
{
	struct zynqmp_sha_tfm_ctx *tctx = crypto_shash_ctx(desc->tfm);
	struct crypto_shash *fbtfm = tctx->fbk_tfm;
	SHASH_DESC_ON_STACK(fbdesc, fbtfm);

	fbdesc->tfm = fbtfm;

Annotation

Implementation Notes