drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c

Source file repositories/reference/linux-study-clean/drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/allwinner/sun8i-ce/sun8i-ce-hash.c
Extension
.c
Size
13847 bytes
Lines
487
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 (sg->length % 4) {
			if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG))
				algt->stat_fb_srclen++;

			return true;
		}
		if (!IS_ALIGNED(sg->offset, sizeof(u32))) {
			if (IS_ENABLED(CONFIG_CRYPTO_DEV_SUN8I_CE_DEBUG))
				algt->stat_fb_srcali++;

			return true;
		}
		sg = sg_next(sg);
	}
	return false;
}

int sun8i_ce_hash_digest(struct ahash_request *areq)
{
	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
	struct sun8i_ce_hash_tfm_ctx *ctx = crypto_ahash_ctx(tfm);
	struct sun8i_ce_hash_reqctx *rctx = ahash_request_ctx_dma(areq);
	struct sun8i_ce_dev *ce = ctx->ce;
	struct crypto_engine *engine;
	int e;

	if (sun8i_ce_hash_need_fallback(areq))
		return sun8i_ce_hash_digest_fb(areq);

	e = sun8i_ce_get_engine_number(ce);
	rctx->flow = e;
	engine = ce->chanlist[e].engine;

	return crypto_transfer_hash_request_to_engine(engine, areq);
}

static u64 hash_pad(__le32 *buf, unsigned int bufsize, u64 padi, u64 byte_count, bool le, int bs)
{
	u64 fill, min_fill, j, k;
	__be64 *bebits;
	__le64 *lebits;

	j = padi;
	buf[j++] = cpu_to_le32(0x80);

	if (bs == 64) {
		fill = 64 - (byte_count % 64);
		min_fill = 2 * sizeof(u32) + sizeof(u32);
	} else {
		fill = 128 - (byte_count % 128);
		min_fill = 4 * sizeof(u32) + sizeof(u32);
	}

	if (fill < min_fill)
		fill += bs;

	k = j;
	j += (fill - min_fill) / sizeof(u32);
	if (j * 4 > bufsize) {
		pr_err("%s OVERFLOW %llu\n", __func__, j);
		return 0;
	}
	for (; k < j; k++)
		buf[k] = 0;

	if (le) {
		/* MD5 */
		lebits = (__le64 *)&buf[j];
		*lebits = cpu_to_le64(byte_count << 3);
		j += 2;
	} else {
		if (bs == 64) {
			/* sha1 sha224 sha256 */
			bebits = (__be64 *)&buf[j];
			*bebits = cpu_to_be64(byte_count << 3);
			j += 2;
		} else {
			/* sha384 sha512*/
			bebits = (__be64 *)&buf[j];
			*bebits = cpu_to_be64(byte_count >> 61);
			j += 2;
			bebits = (__be64 *)&buf[j];
			*bebits = cpu_to_be64(byte_count << 3);
			j += 2;
		}
	}
	if (j * 4 > bufsize) {
		pr_err("%s OVERFLOW %llu\n", __func__, j);
		return 0;
	}

Annotation

Implementation Notes