drivers/crypto/starfive/jh7110-rsa.c

Source file repositories/reference/linux-study-clean/drivers/crypto/starfive/jh7110-rsa.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/starfive/jh7110-rsa.c
Extension
.c
Size
14440 bytes
Lines
593
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

if (mlen) {
			rctx->csr.pka.v = 0;
			rctx->csr.pka.cln_done = 1;
			rctx->csr.pka.opsize = opsize;
			rctx->csr.pka.exposize = opsize;
			rctx->csr.pka.cmd = CRYPTO_CMD_AERN;
			rctx->csr.pka.start = 1;
			rctx->csr.pka.ie = 1;

			writel(rctx->csr.pka.v, cryp->base + STARFIVE_PKA_CACR_OFFSET);

			if (starfive_pka_wait_done(ctx))
				goto rsa_err;
		}
	}

	for (loop = 0; loop <= opsize; loop++) {
		temp = readl(cryp->base + STARFIVE_PKA_CAAR_OFFSET + 0x4 * loop);
		result[opsize - loop] = temp;
	}

	ret = starfive_rsa_montgomery_form(ctx, result, result, 1, n, key_sz << 3);
	if (ret)
		dev_err_probe(cryp->dev, ret, "Conversion from Montgomery failed");
rsa_err:
	kfree(mta);
	return ret;
}

static int starfive_rsa_start(struct starfive_cryp_ctx *ctx, u8 *result,
			      u8 *de, u8 *n, int key_sz)
{
	return starfive_rsa_cpu_start(ctx, (u32 *)result, de, (u32 *)n, key_sz);
}

static int starfive_rsa_enc_core(struct starfive_cryp_ctx *ctx, int enc)
{
	struct starfive_cryp_dev *cryp = ctx->cryp;
	struct starfive_cryp_request_ctx *rctx = ctx->rctx;
	struct starfive_rsa_key *key = &ctx->rsa_key;
	int ret = 0, shift = 0;

	writel(STARFIVE_RSA_RESET, cryp->base + STARFIVE_PKA_CACR_OFFSET);

	if (!IS_ALIGNED(rctx->total, sizeof(u32))) {
		shift = sizeof(u32) - (rctx->total & 0x3);
		memset(rctx->rsa_data, 0, shift);
	}

	rctx->total = sg_copy_to_buffer(rctx->in_sg, sg_nents(rctx->in_sg),
					rctx->rsa_data + shift, rctx->total);

	if (enc) {
		key->bitlen = key->e_bitlen;
		ret = starfive_rsa_start(ctx, rctx->rsa_data, key->e,
					 key->n, key->key_sz);
	} else {
		key->bitlen = key->d_bitlen;
		ret = starfive_rsa_start(ctx, rctx->rsa_data, key->d,
					 key->n, key->key_sz);
	}

	if (ret)
		goto err_rsa_crypt;

	sg_copy_buffer(rctx->out_sg, sg_nents(rctx->out_sg),
		       rctx->rsa_data, key->key_sz, 0, 0);

err_rsa_crypt:
	writel(STARFIVE_RSA_RESET, cryp->base + STARFIVE_PKA_CACR_OFFSET);
	return ret;
}

static int starfive_rsa_enc(struct akcipher_request *req)
{
	struct crypto_akcipher *tfm = crypto_akcipher_reqtfm(req);
	struct starfive_cryp_ctx *ctx = akcipher_tfm_ctx(tfm);
	struct starfive_cryp_dev *cryp = ctx->cryp;
	struct starfive_rsa_key *key = &ctx->rsa_key;
	struct starfive_cryp_request_ctx *rctx = akcipher_request_ctx(req);
	int ret;

	if (!key->key_sz) {
		akcipher_request_set_tfm(req, ctx->akcipher_fbk);
		ret = crypto_akcipher_encrypt(req);
		akcipher_request_set_tfm(req, tfm);
		return ret;
	}

	if (unlikely(!key->n || !key->e))

Annotation

Implementation Notes