arch/arm64/crypto/sm4-ce-glue.c

Source file repositories/reference/linux-study-clean/arch/arm64/crypto/sm4-ce-glue.c

File Facts

System
Linux kernel
Corpus path
arch/arm64/crypto/sm4-ce-glue.c
Extension
.c
Size
18902 bytes
Lines
720
Domain
Architecture Layer
Bucket
arch/arm64
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

struct sm4_xts_ctx {
	struct sm4_ctx key1;
	struct sm4_ctx key2;
};

struct sm4_mac_tfm_ctx {
	struct sm4_ctx key;
	u8 __aligned(8) consts[];
};

struct sm4_mac_desc_ctx {
	u8 digest[SM4_BLOCK_SIZE];
};

static int sm4_setkey(struct crypto_skcipher *tfm, const u8 *key,
		      unsigned int key_len)
{
	struct sm4_ctx *ctx = crypto_skcipher_ctx(tfm);

	if (key_len != SM4_KEY_SIZE)
		return -EINVAL;

	scoped_ksimd()
		sm4_ce_expand_key(key, ctx->rkey_enc, ctx->rkey_dec,
				  crypto_sm4_fk, crypto_sm4_ck);
	return 0;
}

static int sm4_xts_setkey(struct crypto_skcipher *tfm, const u8 *key,
			  unsigned int key_len)
{
	struct sm4_xts_ctx *ctx = crypto_skcipher_ctx(tfm);
	int ret;

	if (key_len != SM4_KEY_SIZE * 2)
		return -EINVAL;

	ret = xts_verify_key(tfm, key, key_len);
	if (ret)
		return ret;

	scoped_ksimd() {
		sm4_ce_expand_key(key, ctx->key1.rkey_enc,
				ctx->key1.rkey_dec, crypto_sm4_fk, crypto_sm4_ck);
		sm4_ce_expand_key(&key[SM4_KEY_SIZE], ctx->key2.rkey_enc,
				ctx->key2.rkey_dec, crypto_sm4_fk, crypto_sm4_ck);
	}

	return 0;
}

static int sm4_ecb_do_crypt(struct skcipher_request *req, const u32 *rkey)
{
	struct skcipher_walk walk;
	unsigned int nbytes;
	int err;

	err = skcipher_walk_virt(&walk, req, false);

	while ((nbytes = walk.nbytes) > 0) {
		const u8 *src = walk.src.virt.addr;
		u8 *dst = walk.dst.virt.addr;
		unsigned int nblks;

		scoped_ksimd() {
			nblks = BYTES2BLKS(nbytes);
			if (nblks) {
				sm4_ce_crypt(rkey, dst, src, nblks);
				nbytes -= nblks * SM4_BLOCK_SIZE;
			}
		}

		err = skcipher_walk_done(&walk, nbytes);
	}

	return err;
}

static int sm4_ecb_encrypt(struct skcipher_request *req)
{
	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
	struct sm4_ctx *ctx = crypto_skcipher_ctx(tfm);

	return sm4_ecb_do_crypt(req, ctx->rkey_enc);
}

static int sm4_ecb_decrypt(struct skcipher_request *req)
{
	struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
	struct sm4_ctx *ctx = crypto_skcipher_ctx(tfm);

Annotation

Implementation Notes