drivers/crypto/nx/nx-sha512.c

Source file repositories/reference/linux-study-clean/drivers/crypto/nx/nx-sha512.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/nx/nx-sha512.c
Extension
.c
Size
7010 bytes
Lines
266
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 sha512_state_be {
	__be64 state[SHA512_DIGEST_SIZE / 8];
	u64 count[2];
};

static int nx_crypto_ctx_sha512_init(struct crypto_shash *tfm)
{
	struct nx_crypto_ctx *nx_ctx = crypto_shash_ctx(tfm);
	int err;

	err = nx_crypto_ctx_sha_init(tfm);
	if (err)
		return err;

	nx_ctx_init(nx_ctx, HCOP_FC_SHA);

	nx_ctx->ap = &nx_ctx->props[NX_PROPS_SHA512];

	NX_CPB_SET_DIGEST_SIZE(nx_ctx->csbcpb, NX_DS_SHA512);

	return 0;
}

static int nx_sha512_init(struct shash_desc *desc)
{
	struct sha512_state_be *sctx = shash_desc_ctx(desc);

	sctx->state[0] = __cpu_to_be64(SHA512_H0);
	sctx->state[1] = __cpu_to_be64(SHA512_H1);
	sctx->state[2] = __cpu_to_be64(SHA512_H2);
	sctx->state[3] = __cpu_to_be64(SHA512_H3);
	sctx->state[4] = __cpu_to_be64(SHA512_H4);
	sctx->state[5] = __cpu_to_be64(SHA512_H5);
	sctx->state[6] = __cpu_to_be64(SHA512_H6);
	sctx->state[7] = __cpu_to_be64(SHA512_H7);
	sctx->count[0] = 0;
	sctx->count[1] = 0;

	return 0;
}

static int nx_sha512_update(struct shash_desc *desc, const u8 *data,
			    unsigned int len)
{
	struct nx_crypto_ctx *nx_ctx = crypto_shash_ctx(desc->tfm);
	struct sha512_state_be *sctx = shash_desc_ctx(desc);
	struct nx_csbcpb *csbcpb = (struct nx_csbcpb *)nx_ctx->csbcpb;
	u64 to_process, leftover, total = len;
	struct nx_sg *out_sg;
	unsigned long irq_flags;
	int rc = 0;
	int data_len;
	u32 max_sg_len;

	spin_lock_irqsave(&nx_ctx->lock, irq_flags);

	memcpy(csbcpb->cpb.sha512.message_digest, sctx->state, SHA512_DIGEST_SIZE);
	NX_CPB_FDM(csbcpb) |= NX_FDM_INTERMEDIATE;
	NX_CPB_FDM(csbcpb) |= NX_FDM_CONTINUATION;

	max_sg_len = min_t(u64, nx_ctx->ap->sglen,
			nx_driver.of.max_sg_len/sizeof(struct nx_sg));
	max_sg_len = min_t(u64, max_sg_len,
			nx_ctx->ap->databytelen/NX_PAGE_SIZE);

	data_len = SHA512_DIGEST_SIZE;
	out_sg = nx_build_sg_list(nx_ctx->out_sg, (u8 *)sctx->state,
				  &data_len, max_sg_len);
	nx_ctx->op.outlen = (nx_ctx->out_sg - out_sg) * sizeof(struct nx_sg);

	if (data_len != SHA512_DIGEST_SIZE) {
		rc = -EINVAL;
		goto out;
	}

	do {
		struct nx_sg *in_sg = nx_ctx->in_sg;

		to_process = total & ~(SHA512_BLOCK_SIZE - 1);

		data_len = to_process;
		in_sg = nx_build_sg_list(in_sg, (u8 *) data,
					 &data_len, max_sg_len);

		nx_ctx->op.inlen = (nx_ctx->in_sg - in_sg) * sizeof(struct nx_sg);

		to_process = data_len;
		leftover = total - to_process;

		/*

Annotation

Implementation Notes