drivers/crypto/caam/caamprng.c

Source file repositories/reference/linux-study-clean/drivers/crypto/caam/caamprng.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/caam/caamprng.c
Extension
.c
Size
5188 bytes
Lines
242
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 caam_prng_ctx {
	int err;
	struct completion done;
};

struct caam_prng_alg {
	struct rng_alg rng;
	bool registered;
};

static void caam_prng_done(struct device *jrdev, u32 *desc, u32 err,
			  void *context)
{
	struct caam_prng_ctx *jctx = context;

	jctx->err = err ? caam_jr_strstatus(jrdev, err) : 0;

	complete(&jctx->done);
}

static u32 *caam_init_reseed_desc(u32 *desc)
{
	init_job_desc(desc, 0);	/* + 1 cmd_sz */
	/* Generate random bytes: + 1 cmd_sz */
	append_operation(desc, OP_TYPE_CLASS1_ALG | OP_ALG_ALGSEL_RNG |
			OP_ALG_AS_FINALIZE);

	print_hex_dump_debug("prng reseed desc@: ", DUMP_PREFIX_ADDRESS,
			     16, 4, desc, desc_bytes(desc), 1);

	return desc;
}

static u32 *caam_init_prng_desc(u32 *desc, dma_addr_t dst_dma, u32 len)
{
	init_job_desc(desc, 0);	/* + 1 cmd_sz */
	/* Generate random bytes: + 1 cmd_sz */
	append_operation(desc, OP_ALG_ALGSEL_RNG | OP_TYPE_CLASS1_ALG);
	/* Store bytes: + 1 cmd_sz + caam_ptr_sz  */
	append_fifo_store(desc, dst_dma,
			  len, FIFOST_TYPE_RNGSTORE);

	print_hex_dump_debug("prng job desc@: ", DUMP_PREFIX_ADDRESS,
			     16, 4, desc, desc_bytes(desc), 1);

	return desc;
}

static int caam_prng_generate(struct crypto_rng *tfm,
			     const u8 *src, unsigned int slen,
			     u8 *dst, unsigned int dlen)
{
	unsigned int aligned_dlen = ALIGN(dlen, dma_get_cache_alignment());
	struct caam_prng_ctx ctx;
	struct device *jrdev;
	dma_addr_t dst_dma;
	u32 *desc;
	u8 *buf;
	int ret;

	if (aligned_dlen < dlen)
		return -EOVERFLOW;

	buf = kzalloc(aligned_dlen, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	jrdev = caam_jr_alloc();
	ret = PTR_ERR_OR_ZERO(jrdev);
	if (ret) {
		pr_err("Job Ring Device allocation failed\n");
		kfree(buf);
		return ret;
	}

	desc = kzalloc(CAAM_PRNG_MAX_DESC_LEN, GFP_KERNEL);
	if (!desc) {
		ret = -ENOMEM;
		goto out1;
	}

	dst_dma = dma_map_single(jrdev, buf, dlen, DMA_FROM_DEVICE);
	if (dma_mapping_error(jrdev, dst_dma)) {
		dev_err(jrdev, "Failed to map destination buffer memory\n");
		ret = -ENOMEM;
		goto out;
	}

	init_completion(&ctx.done);
	ret = caam_jr_enqueue(jrdev,

Annotation

Implementation Notes