drivers/crypto/inside-secure/safexcel_cipher.c

Source file repositories/reference/linux-study-clean/drivers/crypto/inside-secure/safexcel_cipher.c

File Facts

System
Linux kernel
Corpus path
drivers/crypto/inside-secure/safexcel_cipher.c
Extension
.c
Size
110380 bytes
Lines
3759
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 safexcel_cipher_ctx {
	struct safexcel_context base;
	struct safexcel_crypto_priv *priv;

	u32 mode;
	enum safexcel_cipher_alg alg;
	u8 aead; /* !=0=AEAD, 2=IPSec ESP AEAD, 3=IPsec ESP GMAC */
	u8 xcm;  /* 0=authenc, 1=GCM, 2 reserved for CCM */
	u8 aadskip;
	u8 blocksz;
	u32 ivmask;
	u32 ctrinit;

	__le32 key[16];
	u32 nonce;
	unsigned int key_len, xts;

	/* All the below is AEAD specific */
	u32 hash_alg;
	u32 state_sz;

	struct crypto_aead *fback;
};

struct safexcel_cipher_req {
	enum safexcel_cipher_direction direction;
	/* Number of result descriptors associated to the request */
	unsigned int rdescs;
	bool needs_inv;
	int  nr_src, nr_dst;
};

static int safexcel_skcipher_iv(struct safexcel_cipher_ctx *ctx, u8 *iv,
				struct safexcel_command_desc *cdesc)
{
	if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) {
		cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;
		/* 32 bit nonce */
		cdesc->control_data.token[0] = ctx->nonce;
		/* 64 bit IV part */
		memcpy(&cdesc->control_data.token[1], iv, 8);
		/* 32 bit counter, start at 0 or 1 (big endian!) */
		cdesc->control_data.token[3] =
			(__force u32)cpu_to_be32(ctx->ctrinit);
		return 4;
	}
	if (ctx->alg == SAFEXCEL_CHACHA20) {
		cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;
		/* 96 bit nonce part */
		memcpy(&cdesc->control_data.token[0], &iv[4], 12);
		/* 32 bit counter */
		cdesc->control_data.token[3] = *(u32 *)iv;
		return 4;
	}

	cdesc->control_data.options |= ctx->ivmask;
	memcpy(cdesc->control_data.token, iv, ctx->blocksz);
	return ctx->blocksz / sizeof(u32);
}

static void safexcel_skcipher_token(struct safexcel_cipher_ctx *ctx, u8 *iv,
				    struct safexcel_command_desc *cdesc,
				    struct safexcel_token *atoken,
				    u32 length)
{
	struct safexcel_token *token;
	int ivlen;

	ivlen = safexcel_skcipher_iv(ctx, iv, cdesc);
	if (ivlen == 4) {
		/* No space in cdesc, instruction moves to atoken */
		cdesc->additional_cdata_size = 1;
		token = atoken;
	} else {
		/* Everything fits in cdesc */
		token = (struct safexcel_token *)(cdesc->control_data.token + 2);
		/* Need to pad with NOP */
		eip197_noop_token(&token[1]);
	}

	token->opcode = EIP197_TOKEN_OPCODE_DIRECTION;
	token->packet_length = length;
	token->stat = EIP197_TOKEN_STAT_LAST_PACKET |
		      EIP197_TOKEN_STAT_LAST_HASH;
	token->instructions = EIP197_TOKEN_INS_LAST |
			      EIP197_TOKEN_INS_TYPE_CRYPTO |
			      EIP197_TOKEN_INS_TYPE_OUTPUT;
}

static void safexcel_aead_iv(struct safexcel_cipher_ctx *ctx, u8 *iv,

Annotation

Implementation Notes