18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2017 Marvell
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Antoine Tenart <antoine.tenart@free-electrons.com>
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include <asm/unaligned.h>
98c2ecf20Sopenharmony_ci#include <linux/device.h>
108c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h>
118c2ecf20Sopenharmony_ci#include <linux/dmapool.h>
128c2ecf20Sopenharmony_ci#include <crypto/aead.h>
138c2ecf20Sopenharmony_ci#include <crypto/aes.h>
148c2ecf20Sopenharmony_ci#include <crypto/authenc.h>
158c2ecf20Sopenharmony_ci#include <crypto/chacha.h>
168c2ecf20Sopenharmony_ci#include <crypto/ctr.h>
178c2ecf20Sopenharmony_ci#include <crypto/internal/des.h>
188c2ecf20Sopenharmony_ci#include <crypto/gcm.h>
198c2ecf20Sopenharmony_ci#include <crypto/ghash.h>
208c2ecf20Sopenharmony_ci#include <crypto/poly1305.h>
218c2ecf20Sopenharmony_ci#include <crypto/sha.h>
228c2ecf20Sopenharmony_ci#include <crypto/sm3.h>
238c2ecf20Sopenharmony_ci#include <crypto/sm4.h>
248c2ecf20Sopenharmony_ci#include <crypto/xts.h>
258c2ecf20Sopenharmony_ci#include <crypto/skcipher.h>
268c2ecf20Sopenharmony_ci#include <crypto/internal/aead.h>
278c2ecf20Sopenharmony_ci#include <crypto/internal/skcipher.h>
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci#include "safexcel.h"
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cienum safexcel_cipher_direction {
328c2ecf20Sopenharmony_ci	SAFEXCEL_ENCRYPT,
338c2ecf20Sopenharmony_ci	SAFEXCEL_DECRYPT,
348c2ecf20Sopenharmony_ci};
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_cienum safexcel_cipher_alg {
378c2ecf20Sopenharmony_ci	SAFEXCEL_DES,
388c2ecf20Sopenharmony_ci	SAFEXCEL_3DES,
398c2ecf20Sopenharmony_ci	SAFEXCEL_AES,
408c2ecf20Sopenharmony_ci	SAFEXCEL_CHACHA20,
418c2ecf20Sopenharmony_ci	SAFEXCEL_SM4,
428c2ecf20Sopenharmony_ci};
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_cistruct safexcel_cipher_ctx {
458c2ecf20Sopenharmony_ci	struct safexcel_context base;
468c2ecf20Sopenharmony_ci	struct safexcel_crypto_priv *priv;
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci	u32 mode;
498c2ecf20Sopenharmony_ci	enum safexcel_cipher_alg alg;
508c2ecf20Sopenharmony_ci	u8 aead; /* !=0=AEAD, 2=IPSec ESP AEAD, 3=IPsec ESP GMAC */
518c2ecf20Sopenharmony_ci	u8 xcm;  /* 0=authenc, 1=GCM, 2 reserved for CCM */
528c2ecf20Sopenharmony_ci	u8 aadskip;
538c2ecf20Sopenharmony_ci	u8 blocksz;
548c2ecf20Sopenharmony_ci	u32 ivmask;
558c2ecf20Sopenharmony_ci	u32 ctrinit;
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci	__le32 key[16];
588c2ecf20Sopenharmony_ci	u32 nonce;
598c2ecf20Sopenharmony_ci	unsigned int key_len, xts;
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci	/* All the below is AEAD specific */
628c2ecf20Sopenharmony_ci	u32 hash_alg;
638c2ecf20Sopenharmony_ci	u32 state_sz;
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	struct crypto_cipher *hkaes;
668c2ecf20Sopenharmony_ci	struct crypto_aead *fback;
678c2ecf20Sopenharmony_ci};
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_cistruct safexcel_cipher_req {
708c2ecf20Sopenharmony_ci	enum safexcel_cipher_direction direction;
718c2ecf20Sopenharmony_ci	/* Number of result descriptors associated to the request */
728c2ecf20Sopenharmony_ci	unsigned int rdescs;
738c2ecf20Sopenharmony_ci	bool needs_inv;
748c2ecf20Sopenharmony_ci	int  nr_src, nr_dst;
758c2ecf20Sopenharmony_ci};
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_cistatic int safexcel_skcipher_iv(struct safexcel_cipher_ctx *ctx, u8 *iv,
788c2ecf20Sopenharmony_ci				struct safexcel_command_desc *cdesc)
798c2ecf20Sopenharmony_ci{
808c2ecf20Sopenharmony_ci	if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) {
818c2ecf20Sopenharmony_ci		cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;
828c2ecf20Sopenharmony_ci		/* 32 bit nonce */
838c2ecf20Sopenharmony_ci		cdesc->control_data.token[0] = ctx->nonce;
848c2ecf20Sopenharmony_ci		/* 64 bit IV part */
858c2ecf20Sopenharmony_ci		memcpy(&cdesc->control_data.token[1], iv, 8);
868c2ecf20Sopenharmony_ci		/* 32 bit counter, start at 0 or 1 (big endian!) */
878c2ecf20Sopenharmony_ci		cdesc->control_data.token[3] =
888c2ecf20Sopenharmony_ci			(__force u32)cpu_to_be32(ctx->ctrinit);
898c2ecf20Sopenharmony_ci		return 4;
908c2ecf20Sopenharmony_ci	}
918c2ecf20Sopenharmony_ci	if (ctx->alg == SAFEXCEL_CHACHA20) {
928c2ecf20Sopenharmony_ci		cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;
938c2ecf20Sopenharmony_ci		/* 96 bit nonce part */
948c2ecf20Sopenharmony_ci		memcpy(&cdesc->control_data.token[0], &iv[4], 12);
958c2ecf20Sopenharmony_ci		/* 32 bit counter */
968c2ecf20Sopenharmony_ci		cdesc->control_data.token[3] = *(u32 *)iv;
978c2ecf20Sopenharmony_ci		return 4;
988c2ecf20Sopenharmony_ci	}
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci	cdesc->control_data.options |= ctx->ivmask;
1018c2ecf20Sopenharmony_ci	memcpy(cdesc->control_data.token, iv, ctx->blocksz);
1028c2ecf20Sopenharmony_ci	return ctx->blocksz / sizeof(u32);
1038c2ecf20Sopenharmony_ci}
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_cistatic void safexcel_skcipher_token(struct safexcel_cipher_ctx *ctx, u8 *iv,
1068c2ecf20Sopenharmony_ci				    struct safexcel_command_desc *cdesc,
1078c2ecf20Sopenharmony_ci				    struct safexcel_token *atoken,
1088c2ecf20Sopenharmony_ci				    u32 length)
1098c2ecf20Sopenharmony_ci{
1108c2ecf20Sopenharmony_ci	struct safexcel_token *token;
1118c2ecf20Sopenharmony_ci	int ivlen;
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci	ivlen = safexcel_skcipher_iv(ctx, iv, cdesc);
1148c2ecf20Sopenharmony_ci	if (ivlen == 4) {
1158c2ecf20Sopenharmony_ci		/* No space in cdesc, instruction moves to atoken */
1168c2ecf20Sopenharmony_ci		cdesc->additional_cdata_size = 1;
1178c2ecf20Sopenharmony_ci		token = atoken;
1188c2ecf20Sopenharmony_ci	} else {
1198c2ecf20Sopenharmony_ci		/* Everything fits in cdesc */
1208c2ecf20Sopenharmony_ci		token = (struct safexcel_token *)(cdesc->control_data.token + 2);
1218c2ecf20Sopenharmony_ci		/* Need to pad with NOP */
1228c2ecf20Sopenharmony_ci		eip197_noop_token(&token[1]);
1238c2ecf20Sopenharmony_ci	}
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci	token->opcode = EIP197_TOKEN_OPCODE_DIRECTION;
1268c2ecf20Sopenharmony_ci	token->packet_length = length;
1278c2ecf20Sopenharmony_ci	token->stat = EIP197_TOKEN_STAT_LAST_PACKET |
1288c2ecf20Sopenharmony_ci		      EIP197_TOKEN_STAT_LAST_HASH;
1298c2ecf20Sopenharmony_ci	token->instructions = EIP197_TOKEN_INS_LAST |
1308c2ecf20Sopenharmony_ci			      EIP197_TOKEN_INS_TYPE_CRYPTO |
1318c2ecf20Sopenharmony_ci			      EIP197_TOKEN_INS_TYPE_OUTPUT;
1328c2ecf20Sopenharmony_ci}
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_cistatic void safexcel_aead_iv(struct safexcel_cipher_ctx *ctx, u8 *iv,
1358c2ecf20Sopenharmony_ci			     struct safexcel_command_desc *cdesc)
1368c2ecf20Sopenharmony_ci{
1378c2ecf20Sopenharmony_ci	if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD ||
1388c2ecf20Sopenharmony_ci	    ctx->aead & EIP197_AEAD_TYPE_IPSEC_ESP) { /* _ESP and _ESP_GMAC */
1398c2ecf20Sopenharmony_ci		/* 32 bit nonce */
1408c2ecf20Sopenharmony_ci		cdesc->control_data.token[0] = ctx->nonce;
1418c2ecf20Sopenharmony_ci		/* 64 bit IV part */
1428c2ecf20Sopenharmony_ci		memcpy(&cdesc->control_data.token[1], iv, 8);
1438c2ecf20Sopenharmony_ci		/* 32 bit counter, start at 0 or 1 (big endian!) */
1448c2ecf20Sopenharmony_ci		cdesc->control_data.token[3] =
1458c2ecf20Sopenharmony_ci			(__force u32)cpu_to_be32(ctx->ctrinit);
1468c2ecf20Sopenharmony_ci		return;
1478c2ecf20Sopenharmony_ci	}
1488c2ecf20Sopenharmony_ci	if (ctx->xcm == EIP197_XCM_MODE_GCM || ctx->alg == SAFEXCEL_CHACHA20) {
1498c2ecf20Sopenharmony_ci		/* 96 bit IV part */
1508c2ecf20Sopenharmony_ci		memcpy(&cdesc->control_data.token[0], iv, 12);
1518c2ecf20Sopenharmony_ci		/* 32 bit counter, start at 0 or 1 (big endian!) */
1528c2ecf20Sopenharmony_ci		cdesc->control_data.token[3] =
1538c2ecf20Sopenharmony_ci			(__force u32)cpu_to_be32(ctx->ctrinit);
1548c2ecf20Sopenharmony_ci		return;
1558c2ecf20Sopenharmony_ci	}
1568c2ecf20Sopenharmony_ci	/* CBC */
1578c2ecf20Sopenharmony_ci	memcpy(cdesc->control_data.token, iv, ctx->blocksz);
1588c2ecf20Sopenharmony_ci}
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_cistatic void safexcel_aead_token(struct safexcel_cipher_ctx *ctx, u8 *iv,
1618c2ecf20Sopenharmony_ci				struct safexcel_command_desc *cdesc,
1628c2ecf20Sopenharmony_ci				struct safexcel_token *atoken,
1638c2ecf20Sopenharmony_ci				enum safexcel_cipher_direction direction,
1648c2ecf20Sopenharmony_ci				u32 cryptlen, u32 assoclen, u32 digestsize)
1658c2ecf20Sopenharmony_ci{
1668c2ecf20Sopenharmony_ci	struct safexcel_token *aadref;
1678c2ecf20Sopenharmony_ci	int atoksize = 2; /* Start with minimum size */
1688c2ecf20Sopenharmony_ci	int assocadj = assoclen - ctx->aadskip, aadalign;
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci	/* Always 4 dwords of embedded IV  for AEAD modes */
1718c2ecf20Sopenharmony_ci	cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_ci	if (direction == SAFEXCEL_DECRYPT)
1748c2ecf20Sopenharmony_ci		cryptlen -= digestsize;
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ci	if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM)) {
1778c2ecf20Sopenharmony_ci		/* Construct IV block B0 for the CBC-MAC */
1788c2ecf20Sopenharmony_ci		u8 *final_iv = (u8 *)cdesc->control_data.token;
1798c2ecf20Sopenharmony_ci		u8 *cbcmaciv = (u8 *)&atoken[1];
1808c2ecf20Sopenharmony_ci		__le32 *aadlen = (__le32 *)&atoken[5];
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci		if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) {
1838c2ecf20Sopenharmony_ci			/* Length + nonce */
1848c2ecf20Sopenharmony_ci			cdesc->control_data.token[0] = ctx->nonce;
1858c2ecf20Sopenharmony_ci			/* Fixup flags byte */
1868c2ecf20Sopenharmony_ci			*(__le32 *)cbcmaciv =
1878c2ecf20Sopenharmony_ci				cpu_to_le32(ctx->nonce |
1888c2ecf20Sopenharmony_ci					    ((assocadj > 0) << 6) |
1898c2ecf20Sopenharmony_ci					    ((digestsize - 2) << 2));
1908c2ecf20Sopenharmony_ci			/* 64 bit IV part */
1918c2ecf20Sopenharmony_ci			memcpy(&cdesc->control_data.token[1], iv, 8);
1928c2ecf20Sopenharmony_ci			memcpy(cbcmaciv + 4, iv, 8);
1938c2ecf20Sopenharmony_ci			/* Start counter at 0 */
1948c2ecf20Sopenharmony_ci			cdesc->control_data.token[3] = 0;
1958c2ecf20Sopenharmony_ci			/* Message length */
1968c2ecf20Sopenharmony_ci			*(__be32 *)(cbcmaciv + 12) = cpu_to_be32(cryptlen);
1978c2ecf20Sopenharmony_ci		} else {
1988c2ecf20Sopenharmony_ci			/* Variable length IV part */
1998c2ecf20Sopenharmony_ci			memcpy(final_iv, iv, 15 - iv[0]);
2008c2ecf20Sopenharmony_ci			memcpy(cbcmaciv, iv, 15 - iv[0]);
2018c2ecf20Sopenharmony_ci			/* Start variable length counter at 0 */
2028c2ecf20Sopenharmony_ci			memset(final_iv + 15 - iv[0], 0, iv[0] + 1);
2038c2ecf20Sopenharmony_ci			memset(cbcmaciv + 15 - iv[0], 0, iv[0] - 1);
2048c2ecf20Sopenharmony_ci			/* fixup flags byte */
2058c2ecf20Sopenharmony_ci			cbcmaciv[0] |= ((assocadj > 0) << 6) |
2068c2ecf20Sopenharmony_ci				       ((digestsize - 2) << 2);
2078c2ecf20Sopenharmony_ci			/* insert lower 2 bytes of message length */
2088c2ecf20Sopenharmony_ci			cbcmaciv[14] = cryptlen >> 8;
2098c2ecf20Sopenharmony_ci			cbcmaciv[15] = cryptlen & 255;
2108c2ecf20Sopenharmony_ci		}
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_ci		atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;
2138c2ecf20Sopenharmony_ci		atoken->packet_length = AES_BLOCK_SIZE +
2148c2ecf20Sopenharmony_ci					((assocadj > 0) << 1);
2158c2ecf20Sopenharmony_ci		atoken->stat = 0;
2168c2ecf20Sopenharmony_ci		atoken->instructions = EIP197_TOKEN_INS_ORIGIN_TOKEN |
2178c2ecf20Sopenharmony_ci				       EIP197_TOKEN_INS_TYPE_HASH;
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_ci		if (likely(assocadj)) {
2208c2ecf20Sopenharmony_ci			*aadlen = cpu_to_le32((assocadj >> 8) |
2218c2ecf20Sopenharmony_ci					      (assocadj & 255) << 8);
2228c2ecf20Sopenharmony_ci			atoken += 6;
2238c2ecf20Sopenharmony_ci			atoksize += 7;
2248c2ecf20Sopenharmony_ci		} else {
2258c2ecf20Sopenharmony_ci			atoken += 5;
2268c2ecf20Sopenharmony_ci			atoksize += 6;
2278c2ecf20Sopenharmony_ci		}
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci		/* Process AAD data */
2308c2ecf20Sopenharmony_ci		aadref = atoken;
2318c2ecf20Sopenharmony_ci		atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION;
2328c2ecf20Sopenharmony_ci		atoken->packet_length = assocadj;
2338c2ecf20Sopenharmony_ci		atoken->stat = 0;
2348c2ecf20Sopenharmony_ci		atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH;
2358c2ecf20Sopenharmony_ci		atoken++;
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_ci		/* For CCM only, align AAD data towards hash engine */
2388c2ecf20Sopenharmony_ci		atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;
2398c2ecf20Sopenharmony_ci		aadalign = (assocadj + 2) & 15;
2408c2ecf20Sopenharmony_ci		atoken->packet_length = assocadj && aadalign ?
2418c2ecf20Sopenharmony_ci						16 - aadalign :
2428c2ecf20Sopenharmony_ci						0;
2438c2ecf20Sopenharmony_ci		if (likely(cryptlen)) {
2448c2ecf20Sopenharmony_ci			atoken->stat = 0;
2458c2ecf20Sopenharmony_ci			atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH;
2468c2ecf20Sopenharmony_ci		} else {
2478c2ecf20Sopenharmony_ci			atoken->stat = EIP197_TOKEN_STAT_LAST_HASH;
2488c2ecf20Sopenharmony_ci			atoken->instructions = EIP197_TOKEN_INS_LAST |
2498c2ecf20Sopenharmony_ci					       EIP197_TOKEN_INS_TYPE_HASH;
2508c2ecf20Sopenharmony_ci		}
2518c2ecf20Sopenharmony_ci	} else {
2528c2ecf20Sopenharmony_ci		safexcel_aead_iv(ctx, iv, cdesc);
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_ci		/* Process AAD data */
2558c2ecf20Sopenharmony_ci		aadref = atoken;
2568c2ecf20Sopenharmony_ci		atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION;
2578c2ecf20Sopenharmony_ci		atoken->packet_length = assocadj;
2588c2ecf20Sopenharmony_ci		atoken->stat = EIP197_TOKEN_STAT_LAST_HASH;
2598c2ecf20Sopenharmony_ci		atoken->instructions = EIP197_TOKEN_INS_LAST |
2608c2ecf20Sopenharmony_ci				       EIP197_TOKEN_INS_TYPE_HASH;
2618c2ecf20Sopenharmony_ci	}
2628c2ecf20Sopenharmony_ci	atoken++;
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ci	if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) {
2658c2ecf20Sopenharmony_ci		/* For ESP mode (and not GMAC), skip over the IV */
2668c2ecf20Sopenharmony_ci		atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION;
2678c2ecf20Sopenharmony_ci		atoken->packet_length = EIP197_AEAD_IPSEC_IV_SIZE;
2688c2ecf20Sopenharmony_ci		atoken->stat = 0;
2698c2ecf20Sopenharmony_ci		atoken->instructions = 0;
2708c2ecf20Sopenharmony_ci		atoken++;
2718c2ecf20Sopenharmony_ci		atoksize++;
2728c2ecf20Sopenharmony_ci	} else if (unlikely(ctx->alg == SAFEXCEL_CHACHA20 &&
2738c2ecf20Sopenharmony_ci			    direction == SAFEXCEL_DECRYPT)) {
2748c2ecf20Sopenharmony_ci		/* Poly-chacha decryption needs a dummy NOP here ... */
2758c2ecf20Sopenharmony_ci		atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;
2768c2ecf20Sopenharmony_ci		atoken->packet_length = 16; /* According to Op Manual */
2778c2ecf20Sopenharmony_ci		atoken->stat = 0;
2788c2ecf20Sopenharmony_ci		atoken->instructions = 0;
2798c2ecf20Sopenharmony_ci		atoken++;
2808c2ecf20Sopenharmony_ci		atoksize++;
2818c2ecf20Sopenharmony_ci	}
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci	if  (ctx->xcm) {
2848c2ecf20Sopenharmony_ci		/* For GCM and CCM, obtain enc(Y0) */
2858c2ecf20Sopenharmony_ci		atoken->opcode = EIP197_TOKEN_OPCODE_INSERT_REMRES;
2868c2ecf20Sopenharmony_ci		atoken->packet_length = 0;
2878c2ecf20Sopenharmony_ci		atoken->stat = 0;
2888c2ecf20Sopenharmony_ci		atoken->instructions = AES_BLOCK_SIZE;
2898c2ecf20Sopenharmony_ci		atoken++;
2908c2ecf20Sopenharmony_ci
2918c2ecf20Sopenharmony_ci		atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;
2928c2ecf20Sopenharmony_ci		atoken->packet_length = AES_BLOCK_SIZE;
2938c2ecf20Sopenharmony_ci		atoken->stat = 0;
2948c2ecf20Sopenharmony_ci		atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT |
2958c2ecf20Sopenharmony_ci				       EIP197_TOKEN_INS_TYPE_CRYPTO;
2968c2ecf20Sopenharmony_ci		atoken++;
2978c2ecf20Sopenharmony_ci		atoksize += 2;
2988c2ecf20Sopenharmony_ci	}
2998c2ecf20Sopenharmony_ci
3008c2ecf20Sopenharmony_ci	if (likely(cryptlen || ctx->alg == SAFEXCEL_CHACHA20)) {
3018c2ecf20Sopenharmony_ci		/* Fixup stat field for AAD direction instruction */
3028c2ecf20Sopenharmony_ci		aadref->stat = 0;
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_ci		/* Process crypto data */
3058c2ecf20Sopenharmony_ci		atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION;
3068c2ecf20Sopenharmony_ci		atoken->packet_length = cryptlen;
3078c2ecf20Sopenharmony_ci
3088c2ecf20Sopenharmony_ci		if (unlikely(ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC)) {
3098c2ecf20Sopenharmony_ci			/* Fixup instruction field for AAD dir instruction */
3108c2ecf20Sopenharmony_ci			aadref->instructions = EIP197_TOKEN_INS_TYPE_HASH;
3118c2ecf20Sopenharmony_ci
3128c2ecf20Sopenharmony_ci			/* Do not send to crypt engine in case of GMAC */
3138c2ecf20Sopenharmony_ci			atoken->instructions = EIP197_TOKEN_INS_LAST |
3148c2ecf20Sopenharmony_ci					       EIP197_TOKEN_INS_TYPE_HASH |
3158c2ecf20Sopenharmony_ci					       EIP197_TOKEN_INS_TYPE_OUTPUT;
3168c2ecf20Sopenharmony_ci		} else {
3178c2ecf20Sopenharmony_ci			atoken->instructions = EIP197_TOKEN_INS_LAST |
3188c2ecf20Sopenharmony_ci					       EIP197_TOKEN_INS_TYPE_CRYPTO |
3198c2ecf20Sopenharmony_ci					       EIP197_TOKEN_INS_TYPE_HASH |
3208c2ecf20Sopenharmony_ci					       EIP197_TOKEN_INS_TYPE_OUTPUT;
3218c2ecf20Sopenharmony_ci		}
3228c2ecf20Sopenharmony_ci
3238c2ecf20Sopenharmony_ci		cryptlen &= 15;
3248c2ecf20Sopenharmony_ci		if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM && cryptlen)) {
3258c2ecf20Sopenharmony_ci			atoken->stat = 0;
3268c2ecf20Sopenharmony_ci			/* For CCM only, pad crypto data to the hash engine */
3278c2ecf20Sopenharmony_ci			atoken++;
3288c2ecf20Sopenharmony_ci			atoksize++;
3298c2ecf20Sopenharmony_ci			atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;
3308c2ecf20Sopenharmony_ci			atoken->packet_length = 16 - cryptlen;
3318c2ecf20Sopenharmony_ci			atoken->stat = EIP197_TOKEN_STAT_LAST_HASH;
3328c2ecf20Sopenharmony_ci			atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH;
3338c2ecf20Sopenharmony_ci		} else {
3348c2ecf20Sopenharmony_ci			atoken->stat = EIP197_TOKEN_STAT_LAST_HASH;
3358c2ecf20Sopenharmony_ci		}
3368c2ecf20Sopenharmony_ci		atoken++;
3378c2ecf20Sopenharmony_ci		atoksize++;
3388c2ecf20Sopenharmony_ci	}
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_ci	if (direction == SAFEXCEL_ENCRYPT) {
3418c2ecf20Sopenharmony_ci		/* Append ICV */
3428c2ecf20Sopenharmony_ci		atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;
3438c2ecf20Sopenharmony_ci		atoken->packet_length = digestsize;
3448c2ecf20Sopenharmony_ci		atoken->stat = EIP197_TOKEN_STAT_LAST_HASH |
3458c2ecf20Sopenharmony_ci			       EIP197_TOKEN_STAT_LAST_PACKET;
3468c2ecf20Sopenharmony_ci		atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT |
3478c2ecf20Sopenharmony_ci				       EIP197_TOKEN_INS_INSERT_HASH_DIGEST;
3488c2ecf20Sopenharmony_ci	} else {
3498c2ecf20Sopenharmony_ci		/* Extract ICV */
3508c2ecf20Sopenharmony_ci		atoken->opcode = EIP197_TOKEN_OPCODE_RETRIEVE;
3518c2ecf20Sopenharmony_ci		atoken->packet_length = digestsize;
3528c2ecf20Sopenharmony_ci		atoken->stat = EIP197_TOKEN_STAT_LAST_HASH |
3538c2ecf20Sopenharmony_ci			       EIP197_TOKEN_STAT_LAST_PACKET;
3548c2ecf20Sopenharmony_ci		atoken->instructions = EIP197_TOKEN_INS_INSERT_HASH_DIGEST;
3558c2ecf20Sopenharmony_ci		atoken++;
3568c2ecf20Sopenharmony_ci		atoksize++;
3578c2ecf20Sopenharmony_ci
3588c2ecf20Sopenharmony_ci		/* Verify ICV */
3598c2ecf20Sopenharmony_ci		atoken->opcode = EIP197_TOKEN_OPCODE_VERIFY;
3608c2ecf20Sopenharmony_ci		atoken->packet_length = digestsize |
3618c2ecf20Sopenharmony_ci					EIP197_TOKEN_HASH_RESULT_VERIFY;
3628c2ecf20Sopenharmony_ci		atoken->stat = EIP197_TOKEN_STAT_LAST_HASH |
3638c2ecf20Sopenharmony_ci			       EIP197_TOKEN_STAT_LAST_PACKET;
3648c2ecf20Sopenharmony_ci		atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT;
3658c2ecf20Sopenharmony_ci	}
3668c2ecf20Sopenharmony_ci
3678c2ecf20Sopenharmony_ci	/* Fixup length of the token in the command descriptor */
3688c2ecf20Sopenharmony_ci	cdesc->additional_cdata_size = atoksize;
3698c2ecf20Sopenharmony_ci}
3708c2ecf20Sopenharmony_ci
3718c2ecf20Sopenharmony_cistatic int safexcel_skcipher_aes_setkey(struct crypto_skcipher *ctfm,
3728c2ecf20Sopenharmony_ci					const u8 *key, unsigned int len)
3738c2ecf20Sopenharmony_ci{
3748c2ecf20Sopenharmony_ci	struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);
3758c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
3768c2ecf20Sopenharmony_ci	struct safexcel_crypto_priv *priv = ctx->base.priv;
3778c2ecf20Sopenharmony_ci	struct crypto_aes_ctx aes;
3788c2ecf20Sopenharmony_ci	int ret, i;
3798c2ecf20Sopenharmony_ci
3808c2ecf20Sopenharmony_ci	ret = aes_expandkey(&aes, key, len);
3818c2ecf20Sopenharmony_ci	if (ret)
3828c2ecf20Sopenharmony_ci		return ret;
3838c2ecf20Sopenharmony_ci
3848c2ecf20Sopenharmony_ci	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
3858c2ecf20Sopenharmony_ci		for (i = 0; i < len / sizeof(u32); i++) {
3868c2ecf20Sopenharmony_ci			if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {
3878c2ecf20Sopenharmony_ci				ctx->base.needs_inv = true;
3888c2ecf20Sopenharmony_ci				break;
3898c2ecf20Sopenharmony_ci			}
3908c2ecf20Sopenharmony_ci		}
3918c2ecf20Sopenharmony_ci	}
3928c2ecf20Sopenharmony_ci
3938c2ecf20Sopenharmony_ci	for (i = 0; i < len / sizeof(u32); i++)
3948c2ecf20Sopenharmony_ci		ctx->key[i] = cpu_to_le32(aes.key_enc[i]);
3958c2ecf20Sopenharmony_ci
3968c2ecf20Sopenharmony_ci	ctx->key_len = len;
3978c2ecf20Sopenharmony_ci
3988c2ecf20Sopenharmony_ci	memzero_explicit(&aes, sizeof(aes));
3998c2ecf20Sopenharmony_ci	return 0;
4008c2ecf20Sopenharmony_ci}
4018c2ecf20Sopenharmony_ci
4028c2ecf20Sopenharmony_cistatic int safexcel_aead_setkey(struct crypto_aead *ctfm, const u8 *key,
4038c2ecf20Sopenharmony_ci				unsigned int len)
4048c2ecf20Sopenharmony_ci{
4058c2ecf20Sopenharmony_ci	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);
4068c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
4078c2ecf20Sopenharmony_ci	struct safexcel_crypto_priv *priv = ctx->base.priv;
4088c2ecf20Sopenharmony_ci	struct crypto_authenc_keys keys;
4098c2ecf20Sopenharmony_ci	struct crypto_aes_ctx aes;
4108c2ecf20Sopenharmony_ci	int err = -EINVAL, i;
4118c2ecf20Sopenharmony_ci	const char *alg;
4128c2ecf20Sopenharmony_ci
4138c2ecf20Sopenharmony_ci	if (unlikely(crypto_authenc_extractkeys(&keys, key, len)))
4148c2ecf20Sopenharmony_ci		goto badkey;
4158c2ecf20Sopenharmony_ci
4168c2ecf20Sopenharmony_ci	if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) {
4178c2ecf20Sopenharmony_ci		/* Must have at least space for the nonce here */
4188c2ecf20Sopenharmony_ci		if (unlikely(keys.enckeylen < CTR_RFC3686_NONCE_SIZE))
4198c2ecf20Sopenharmony_ci			goto badkey;
4208c2ecf20Sopenharmony_ci		/* last 4 bytes of key are the nonce! */
4218c2ecf20Sopenharmony_ci		ctx->nonce = *(u32 *)(keys.enckey + keys.enckeylen -
4228c2ecf20Sopenharmony_ci				      CTR_RFC3686_NONCE_SIZE);
4238c2ecf20Sopenharmony_ci		/* exclude the nonce here */
4248c2ecf20Sopenharmony_ci		keys.enckeylen -= CTR_RFC3686_NONCE_SIZE;
4258c2ecf20Sopenharmony_ci	}
4268c2ecf20Sopenharmony_ci
4278c2ecf20Sopenharmony_ci	/* Encryption key */
4288c2ecf20Sopenharmony_ci	switch (ctx->alg) {
4298c2ecf20Sopenharmony_ci	case SAFEXCEL_DES:
4308c2ecf20Sopenharmony_ci		err = verify_aead_des_key(ctfm, keys.enckey, keys.enckeylen);
4318c2ecf20Sopenharmony_ci		if (unlikely(err))
4328c2ecf20Sopenharmony_ci			goto badkey;
4338c2ecf20Sopenharmony_ci		break;
4348c2ecf20Sopenharmony_ci	case SAFEXCEL_3DES:
4358c2ecf20Sopenharmony_ci		err = verify_aead_des3_key(ctfm, keys.enckey, keys.enckeylen);
4368c2ecf20Sopenharmony_ci		if (unlikely(err))
4378c2ecf20Sopenharmony_ci			goto badkey;
4388c2ecf20Sopenharmony_ci		break;
4398c2ecf20Sopenharmony_ci	case SAFEXCEL_AES:
4408c2ecf20Sopenharmony_ci		err = aes_expandkey(&aes, keys.enckey, keys.enckeylen);
4418c2ecf20Sopenharmony_ci		if (unlikely(err))
4428c2ecf20Sopenharmony_ci			goto badkey;
4438c2ecf20Sopenharmony_ci		break;
4448c2ecf20Sopenharmony_ci	case SAFEXCEL_SM4:
4458c2ecf20Sopenharmony_ci		if (unlikely(keys.enckeylen != SM4_KEY_SIZE))
4468c2ecf20Sopenharmony_ci			goto badkey;
4478c2ecf20Sopenharmony_ci		break;
4488c2ecf20Sopenharmony_ci	default:
4498c2ecf20Sopenharmony_ci		dev_err(priv->dev, "aead: unsupported cipher algorithm\n");
4508c2ecf20Sopenharmony_ci		goto badkey;
4518c2ecf20Sopenharmony_ci	}
4528c2ecf20Sopenharmony_ci
4538c2ecf20Sopenharmony_ci	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
4548c2ecf20Sopenharmony_ci		for (i = 0; i < keys.enckeylen / sizeof(u32); i++) {
4558c2ecf20Sopenharmony_ci			if (le32_to_cpu(ctx->key[i]) !=
4568c2ecf20Sopenharmony_ci			    ((u32 *)keys.enckey)[i]) {
4578c2ecf20Sopenharmony_ci				ctx->base.needs_inv = true;
4588c2ecf20Sopenharmony_ci				break;
4598c2ecf20Sopenharmony_ci			}
4608c2ecf20Sopenharmony_ci		}
4618c2ecf20Sopenharmony_ci	}
4628c2ecf20Sopenharmony_ci
4638c2ecf20Sopenharmony_ci	/* Auth key */
4648c2ecf20Sopenharmony_ci	switch (ctx->hash_alg) {
4658c2ecf20Sopenharmony_ci	case CONTEXT_CONTROL_CRYPTO_ALG_SHA1:
4668c2ecf20Sopenharmony_ci		alg = "safexcel-sha1";
4678c2ecf20Sopenharmony_ci		break;
4688c2ecf20Sopenharmony_ci	case CONTEXT_CONTROL_CRYPTO_ALG_SHA224:
4698c2ecf20Sopenharmony_ci		alg = "safexcel-sha224";
4708c2ecf20Sopenharmony_ci		break;
4718c2ecf20Sopenharmony_ci	case CONTEXT_CONTROL_CRYPTO_ALG_SHA256:
4728c2ecf20Sopenharmony_ci		alg = "safexcel-sha256";
4738c2ecf20Sopenharmony_ci		break;
4748c2ecf20Sopenharmony_ci	case CONTEXT_CONTROL_CRYPTO_ALG_SHA384:
4758c2ecf20Sopenharmony_ci		alg = "safexcel-sha384";
4768c2ecf20Sopenharmony_ci		break;
4778c2ecf20Sopenharmony_ci	case CONTEXT_CONTROL_CRYPTO_ALG_SHA512:
4788c2ecf20Sopenharmony_ci		alg = "safexcel-sha512";
4798c2ecf20Sopenharmony_ci		break;
4808c2ecf20Sopenharmony_ci	case CONTEXT_CONTROL_CRYPTO_ALG_SM3:
4818c2ecf20Sopenharmony_ci		alg = "safexcel-sm3";
4828c2ecf20Sopenharmony_ci		break;
4838c2ecf20Sopenharmony_ci	default:
4848c2ecf20Sopenharmony_ci		dev_err(priv->dev, "aead: unsupported hash algorithm\n");
4858c2ecf20Sopenharmony_ci		goto badkey;
4868c2ecf20Sopenharmony_ci	}
4878c2ecf20Sopenharmony_ci
4888c2ecf20Sopenharmony_ci	if (safexcel_hmac_setkey(&ctx->base, keys.authkey, keys.authkeylen,
4898c2ecf20Sopenharmony_ci				 alg, ctx->state_sz))
4908c2ecf20Sopenharmony_ci		goto badkey;
4918c2ecf20Sopenharmony_ci
4928c2ecf20Sopenharmony_ci	/* Now copy the keys into the context */
4938c2ecf20Sopenharmony_ci	for (i = 0; i < keys.enckeylen / sizeof(u32); i++)
4948c2ecf20Sopenharmony_ci		ctx->key[i] = cpu_to_le32(((u32 *)keys.enckey)[i]);
4958c2ecf20Sopenharmony_ci	ctx->key_len = keys.enckeylen;
4968c2ecf20Sopenharmony_ci
4978c2ecf20Sopenharmony_ci	memzero_explicit(&keys, sizeof(keys));
4988c2ecf20Sopenharmony_ci	return 0;
4998c2ecf20Sopenharmony_ci
5008c2ecf20Sopenharmony_cibadkey:
5018c2ecf20Sopenharmony_ci	memzero_explicit(&keys, sizeof(keys));
5028c2ecf20Sopenharmony_ci	return err;
5038c2ecf20Sopenharmony_ci}
5048c2ecf20Sopenharmony_ci
5058c2ecf20Sopenharmony_cistatic int safexcel_context_control(struct safexcel_cipher_ctx *ctx,
5068c2ecf20Sopenharmony_ci				    struct crypto_async_request *async,
5078c2ecf20Sopenharmony_ci				    struct safexcel_cipher_req *sreq,
5088c2ecf20Sopenharmony_ci				    struct safexcel_command_desc *cdesc)
5098c2ecf20Sopenharmony_ci{
5108c2ecf20Sopenharmony_ci	struct safexcel_crypto_priv *priv = ctx->base.priv;
5118c2ecf20Sopenharmony_ci	int ctrl_size = ctx->key_len / sizeof(u32);
5128c2ecf20Sopenharmony_ci
5138c2ecf20Sopenharmony_ci	cdesc->control_data.control1 = ctx->mode;
5148c2ecf20Sopenharmony_ci
5158c2ecf20Sopenharmony_ci	if (ctx->aead) {
5168c2ecf20Sopenharmony_ci		/* Take in account the ipad+opad digests */
5178c2ecf20Sopenharmony_ci		if (ctx->xcm) {
5188c2ecf20Sopenharmony_ci			ctrl_size += ctx->state_sz / sizeof(u32);
5198c2ecf20Sopenharmony_ci			cdesc->control_data.control0 =
5208c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_KEY_EN |
5218c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_DIGEST_XCM |
5228c2ecf20Sopenharmony_ci				ctx->hash_alg |
5238c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_SIZE(ctrl_size);
5248c2ecf20Sopenharmony_ci		} else if (ctx->alg == SAFEXCEL_CHACHA20) {
5258c2ecf20Sopenharmony_ci			/* Chacha20-Poly1305 */
5268c2ecf20Sopenharmony_ci			cdesc->control_data.control0 =
5278c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_KEY_EN |
5288c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20 |
5298c2ecf20Sopenharmony_ci				(sreq->direction == SAFEXCEL_ENCRYPT ?
5308c2ecf20Sopenharmony_ci					CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT :
5318c2ecf20Sopenharmony_ci					CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN) |
5328c2ecf20Sopenharmony_ci				ctx->hash_alg |
5338c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_SIZE(ctrl_size);
5348c2ecf20Sopenharmony_ci			return 0;
5358c2ecf20Sopenharmony_ci		} else {
5368c2ecf20Sopenharmony_ci			ctrl_size += ctx->state_sz / sizeof(u32) * 2;
5378c2ecf20Sopenharmony_ci			cdesc->control_data.control0 =
5388c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_KEY_EN |
5398c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_DIGEST_HMAC |
5408c2ecf20Sopenharmony_ci				ctx->hash_alg |
5418c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_SIZE(ctrl_size);
5428c2ecf20Sopenharmony_ci		}
5438c2ecf20Sopenharmony_ci
5448c2ecf20Sopenharmony_ci		if (sreq->direction == SAFEXCEL_ENCRYPT &&
5458c2ecf20Sopenharmony_ci		    (ctx->xcm == EIP197_XCM_MODE_CCM ||
5468c2ecf20Sopenharmony_ci		     ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC))
5478c2ecf20Sopenharmony_ci			cdesc->control_data.control0 |=
5488c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_TYPE_HASH_ENCRYPT_OUT;
5498c2ecf20Sopenharmony_ci		else if (sreq->direction == SAFEXCEL_ENCRYPT)
5508c2ecf20Sopenharmony_ci			cdesc->control_data.control0 |=
5518c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT;
5528c2ecf20Sopenharmony_ci		else if (ctx->xcm == EIP197_XCM_MODE_CCM)
5538c2ecf20Sopenharmony_ci			cdesc->control_data.control0 |=
5548c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_TYPE_DECRYPT_HASH_IN;
5558c2ecf20Sopenharmony_ci		else
5568c2ecf20Sopenharmony_ci			cdesc->control_data.control0 |=
5578c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN;
5588c2ecf20Sopenharmony_ci	} else {
5598c2ecf20Sopenharmony_ci		if (sreq->direction == SAFEXCEL_ENCRYPT)
5608c2ecf20Sopenharmony_ci			cdesc->control_data.control0 =
5618c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_TYPE_CRYPTO_OUT |
5628c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_KEY_EN |
5638c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_SIZE(ctrl_size);
5648c2ecf20Sopenharmony_ci		else
5658c2ecf20Sopenharmony_ci			cdesc->control_data.control0 =
5668c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_TYPE_CRYPTO_IN |
5678c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_KEY_EN |
5688c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_SIZE(ctrl_size);
5698c2ecf20Sopenharmony_ci	}
5708c2ecf20Sopenharmony_ci
5718c2ecf20Sopenharmony_ci	if (ctx->alg == SAFEXCEL_DES) {
5728c2ecf20Sopenharmony_ci		cdesc->control_data.control0 |=
5738c2ecf20Sopenharmony_ci			CONTEXT_CONTROL_CRYPTO_ALG_DES;
5748c2ecf20Sopenharmony_ci	} else if (ctx->alg == SAFEXCEL_3DES) {
5758c2ecf20Sopenharmony_ci		cdesc->control_data.control0 |=
5768c2ecf20Sopenharmony_ci			CONTEXT_CONTROL_CRYPTO_ALG_3DES;
5778c2ecf20Sopenharmony_ci	} else if (ctx->alg == SAFEXCEL_AES) {
5788c2ecf20Sopenharmony_ci		switch (ctx->key_len >> ctx->xts) {
5798c2ecf20Sopenharmony_ci		case AES_KEYSIZE_128:
5808c2ecf20Sopenharmony_ci			cdesc->control_data.control0 |=
5818c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_CRYPTO_ALG_AES128;
5828c2ecf20Sopenharmony_ci			break;
5838c2ecf20Sopenharmony_ci		case AES_KEYSIZE_192:
5848c2ecf20Sopenharmony_ci			cdesc->control_data.control0 |=
5858c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_CRYPTO_ALG_AES192;
5868c2ecf20Sopenharmony_ci			break;
5878c2ecf20Sopenharmony_ci		case AES_KEYSIZE_256:
5888c2ecf20Sopenharmony_ci			cdesc->control_data.control0 |=
5898c2ecf20Sopenharmony_ci				CONTEXT_CONTROL_CRYPTO_ALG_AES256;
5908c2ecf20Sopenharmony_ci			break;
5918c2ecf20Sopenharmony_ci		default:
5928c2ecf20Sopenharmony_ci			dev_err(priv->dev, "aes keysize not supported: %u\n",
5938c2ecf20Sopenharmony_ci				ctx->key_len >> ctx->xts);
5948c2ecf20Sopenharmony_ci			return -EINVAL;
5958c2ecf20Sopenharmony_ci		}
5968c2ecf20Sopenharmony_ci	} else if (ctx->alg == SAFEXCEL_CHACHA20) {
5978c2ecf20Sopenharmony_ci		cdesc->control_data.control0 |=
5988c2ecf20Sopenharmony_ci			CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20;
5998c2ecf20Sopenharmony_ci	} else if (ctx->alg == SAFEXCEL_SM4) {
6008c2ecf20Sopenharmony_ci		cdesc->control_data.control0 |=
6018c2ecf20Sopenharmony_ci			CONTEXT_CONTROL_CRYPTO_ALG_SM4;
6028c2ecf20Sopenharmony_ci	}
6038c2ecf20Sopenharmony_ci
6048c2ecf20Sopenharmony_ci	return 0;
6058c2ecf20Sopenharmony_ci}
6068c2ecf20Sopenharmony_ci
6078c2ecf20Sopenharmony_cistatic int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int ring,
6088c2ecf20Sopenharmony_ci				      struct crypto_async_request *async,
6098c2ecf20Sopenharmony_ci				      struct scatterlist *src,
6108c2ecf20Sopenharmony_ci				      struct scatterlist *dst,
6118c2ecf20Sopenharmony_ci				      unsigned int cryptlen,
6128c2ecf20Sopenharmony_ci				      struct safexcel_cipher_req *sreq,
6138c2ecf20Sopenharmony_ci				      bool *should_complete, int *ret)
6148c2ecf20Sopenharmony_ci{
6158c2ecf20Sopenharmony_ci	struct skcipher_request *areq = skcipher_request_cast(async);
6168c2ecf20Sopenharmony_ci	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(areq);
6178c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(skcipher);
6188c2ecf20Sopenharmony_ci	struct safexcel_result_desc *rdesc;
6198c2ecf20Sopenharmony_ci	int ndesc = 0;
6208c2ecf20Sopenharmony_ci
6218c2ecf20Sopenharmony_ci	*ret = 0;
6228c2ecf20Sopenharmony_ci
6238c2ecf20Sopenharmony_ci	if (unlikely(!sreq->rdescs))
6248c2ecf20Sopenharmony_ci		return 0;
6258c2ecf20Sopenharmony_ci
6268c2ecf20Sopenharmony_ci	while (sreq->rdescs--) {
6278c2ecf20Sopenharmony_ci		rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr);
6288c2ecf20Sopenharmony_ci		if (IS_ERR(rdesc)) {
6298c2ecf20Sopenharmony_ci			dev_err(priv->dev,
6308c2ecf20Sopenharmony_ci				"cipher: result: could not retrieve the result descriptor\n");
6318c2ecf20Sopenharmony_ci			*ret = PTR_ERR(rdesc);
6328c2ecf20Sopenharmony_ci			break;
6338c2ecf20Sopenharmony_ci		}
6348c2ecf20Sopenharmony_ci
6358c2ecf20Sopenharmony_ci		if (likely(!*ret))
6368c2ecf20Sopenharmony_ci			*ret = safexcel_rdesc_check_errors(priv, rdesc);
6378c2ecf20Sopenharmony_ci
6388c2ecf20Sopenharmony_ci		ndesc++;
6398c2ecf20Sopenharmony_ci	}
6408c2ecf20Sopenharmony_ci
6418c2ecf20Sopenharmony_ci	safexcel_complete(priv, ring);
6428c2ecf20Sopenharmony_ci
6438c2ecf20Sopenharmony_ci	if (src == dst) {
6448c2ecf20Sopenharmony_ci		dma_unmap_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL);
6458c2ecf20Sopenharmony_ci	} else {
6468c2ecf20Sopenharmony_ci		dma_unmap_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE);
6478c2ecf20Sopenharmony_ci		dma_unmap_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE);
6488c2ecf20Sopenharmony_ci	}
6498c2ecf20Sopenharmony_ci
6508c2ecf20Sopenharmony_ci	/*
6518c2ecf20Sopenharmony_ci	 * Update IV in req from last crypto output word for CBC modes
6528c2ecf20Sopenharmony_ci	 */
6538c2ecf20Sopenharmony_ci	if ((!ctx->aead) && (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) &&
6548c2ecf20Sopenharmony_ci	    (sreq->direction == SAFEXCEL_ENCRYPT)) {
6558c2ecf20Sopenharmony_ci		/* For encrypt take the last output word */
6568c2ecf20Sopenharmony_ci		sg_pcopy_to_buffer(dst, sreq->nr_dst, areq->iv,
6578c2ecf20Sopenharmony_ci				   crypto_skcipher_ivsize(skcipher),
6588c2ecf20Sopenharmony_ci				   (cryptlen -
6598c2ecf20Sopenharmony_ci				    crypto_skcipher_ivsize(skcipher)));
6608c2ecf20Sopenharmony_ci	}
6618c2ecf20Sopenharmony_ci
6628c2ecf20Sopenharmony_ci	*should_complete = true;
6638c2ecf20Sopenharmony_ci
6648c2ecf20Sopenharmony_ci	return ndesc;
6658c2ecf20Sopenharmony_ci}
6668c2ecf20Sopenharmony_ci
6678c2ecf20Sopenharmony_cistatic int safexcel_send_req(struct crypto_async_request *base, int ring,
6688c2ecf20Sopenharmony_ci			     struct safexcel_cipher_req *sreq,
6698c2ecf20Sopenharmony_ci			     struct scatterlist *src, struct scatterlist *dst,
6708c2ecf20Sopenharmony_ci			     unsigned int cryptlen, unsigned int assoclen,
6718c2ecf20Sopenharmony_ci			     unsigned int digestsize, u8 *iv, int *commands,
6728c2ecf20Sopenharmony_ci			     int *results)
6738c2ecf20Sopenharmony_ci{
6748c2ecf20Sopenharmony_ci	struct skcipher_request *areq = skcipher_request_cast(base);
6758c2ecf20Sopenharmony_ci	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(areq);
6768c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm);
6778c2ecf20Sopenharmony_ci	struct safexcel_crypto_priv *priv = ctx->base.priv;
6788c2ecf20Sopenharmony_ci	struct safexcel_command_desc *cdesc;
6798c2ecf20Sopenharmony_ci	struct safexcel_command_desc *first_cdesc = NULL;
6808c2ecf20Sopenharmony_ci	struct safexcel_result_desc *rdesc, *first_rdesc = NULL;
6818c2ecf20Sopenharmony_ci	struct scatterlist *sg;
6828c2ecf20Sopenharmony_ci	unsigned int totlen;
6838c2ecf20Sopenharmony_ci	unsigned int totlen_src = cryptlen + assoclen;
6848c2ecf20Sopenharmony_ci	unsigned int totlen_dst = totlen_src;
6858c2ecf20Sopenharmony_ci	struct safexcel_token *atoken;
6868c2ecf20Sopenharmony_ci	int n_cdesc = 0, n_rdesc = 0;
6878c2ecf20Sopenharmony_ci	int queued, i, ret = 0;
6888c2ecf20Sopenharmony_ci	bool first = true;
6898c2ecf20Sopenharmony_ci
6908c2ecf20Sopenharmony_ci	sreq->nr_src = sg_nents_for_len(src, totlen_src);
6918c2ecf20Sopenharmony_ci
6928c2ecf20Sopenharmony_ci	if (ctx->aead) {
6938c2ecf20Sopenharmony_ci		/*
6948c2ecf20Sopenharmony_ci		 * AEAD has auth tag appended to output for encrypt and
6958c2ecf20Sopenharmony_ci		 * removed from the output for decrypt!
6968c2ecf20Sopenharmony_ci		 */
6978c2ecf20Sopenharmony_ci		if (sreq->direction == SAFEXCEL_DECRYPT)
6988c2ecf20Sopenharmony_ci			totlen_dst -= digestsize;
6998c2ecf20Sopenharmony_ci		else
7008c2ecf20Sopenharmony_ci			totlen_dst += digestsize;
7018c2ecf20Sopenharmony_ci
7028c2ecf20Sopenharmony_ci		memcpy(ctx->base.ctxr->data + ctx->key_len / sizeof(u32),
7038c2ecf20Sopenharmony_ci		       &ctx->base.ipad, ctx->state_sz);
7048c2ecf20Sopenharmony_ci		if (!ctx->xcm)
7058c2ecf20Sopenharmony_ci			memcpy(ctx->base.ctxr->data + (ctx->key_len +
7068c2ecf20Sopenharmony_ci			       ctx->state_sz) / sizeof(u32), &ctx->base.opad,
7078c2ecf20Sopenharmony_ci			       ctx->state_sz);
7088c2ecf20Sopenharmony_ci	} else if ((ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) &&
7098c2ecf20Sopenharmony_ci		   (sreq->direction == SAFEXCEL_DECRYPT)) {
7108c2ecf20Sopenharmony_ci		/*
7118c2ecf20Sopenharmony_ci		 * Save IV from last crypto input word for CBC modes in decrypt
7128c2ecf20Sopenharmony_ci		 * direction. Need to do this first in case of inplace operation
7138c2ecf20Sopenharmony_ci		 * as it will be overwritten.
7148c2ecf20Sopenharmony_ci		 */
7158c2ecf20Sopenharmony_ci		sg_pcopy_to_buffer(src, sreq->nr_src, areq->iv,
7168c2ecf20Sopenharmony_ci				   crypto_skcipher_ivsize(skcipher),
7178c2ecf20Sopenharmony_ci				   (totlen_src -
7188c2ecf20Sopenharmony_ci				    crypto_skcipher_ivsize(skcipher)));
7198c2ecf20Sopenharmony_ci	}
7208c2ecf20Sopenharmony_ci
7218c2ecf20Sopenharmony_ci	sreq->nr_dst = sg_nents_for_len(dst, totlen_dst);
7228c2ecf20Sopenharmony_ci
7238c2ecf20Sopenharmony_ci	/*
7248c2ecf20Sopenharmony_ci	 * Remember actual input length, source buffer length may be
7258c2ecf20Sopenharmony_ci	 * updated in case of inline operation below.
7268c2ecf20Sopenharmony_ci	 */
7278c2ecf20Sopenharmony_ci	totlen = totlen_src;
7288c2ecf20Sopenharmony_ci	queued = totlen_src;
7298c2ecf20Sopenharmony_ci
7308c2ecf20Sopenharmony_ci	if (src == dst) {
7318c2ecf20Sopenharmony_ci		sreq->nr_src = max(sreq->nr_src, sreq->nr_dst);
7328c2ecf20Sopenharmony_ci		sreq->nr_dst = sreq->nr_src;
7338c2ecf20Sopenharmony_ci		if (unlikely((totlen_src || totlen_dst) &&
7348c2ecf20Sopenharmony_ci		    (sreq->nr_src <= 0))) {
7358c2ecf20Sopenharmony_ci			dev_err(priv->dev, "In-place buffer not large enough (need %d bytes)!",
7368c2ecf20Sopenharmony_ci				max(totlen_src, totlen_dst));
7378c2ecf20Sopenharmony_ci			return -EINVAL;
7388c2ecf20Sopenharmony_ci		}
7398c2ecf20Sopenharmony_ci		dma_map_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL);
7408c2ecf20Sopenharmony_ci	} else {
7418c2ecf20Sopenharmony_ci		if (unlikely(totlen_src && (sreq->nr_src <= 0))) {
7428c2ecf20Sopenharmony_ci			dev_err(priv->dev, "Source buffer not large enough (need %d bytes)!",
7438c2ecf20Sopenharmony_ci				totlen_src);
7448c2ecf20Sopenharmony_ci			return -EINVAL;
7458c2ecf20Sopenharmony_ci		}
7468c2ecf20Sopenharmony_ci		dma_map_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE);
7478c2ecf20Sopenharmony_ci
7488c2ecf20Sopenharmony_ci		if (unlikely(totlen_dst && (sreq->nr_dst <= 0))) {
7498c2ecf20Sopenharmony_ci			dev_err(priv->dev, "Dest buffer not large enough (need %d bytes)!",
7508c2ecf20Sopenharmony_ci				totlen_dst);
7518c2ecf20Sopenharmony_ci			dma_unmap_sg(priv->dev, src, sreq->nr_src,
7528c2ecf20Sopenharmony_ci				     DMA_TO_DEVICE);
7538c2ecf20Sopenharmony_ci			return -EINVAL;
7548c2ecf20Sopenharmony_ci		}
7558c2ecf20Sopenharmony_ci		dma_map_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE);
7568c2ecf20Sopenharmony_ci	}
7578c2ecf20Sopenharmony_ci
7588c2ecf20Sopenharmony_ci	memcpy(ctx->base.ctxr->data, ctx->key, ctx->key_len);
7598c2ecf20Sopenharmony_ci
7608c2ecf20Sopenharmony_ci	if (!totlen) {
7618c2ecf20Sopenharmony_ci		/*
7628c2ecf20Sopenharmony_ci		 * The EIP97 cannot deal with zero length input packets!
7638c2ecf20Sopenharmony_ci		 * So stuff a dummy command descriptor indicating a 1 byte
7648c2ecf20Sopenharmony_ci		 * (dummy) input packet, using the context record as source.
7658c2ecf20Sopenharmony_ci		 */
7668c2ecf20Sopenharmony_ci		first_cdesc = safexcel_add_cdesc(priv, ring,
7678c2ecf20Sopenharmony_ci						 1, 1, ctx->base.ctxr_dma,
7688c2ecf20Sopenharmony_ci						 1, 1, ctx->base.ctxr_dma,
7698c2ecf20Sopenharmony_ci						 &atoken);
7708c2ecf20Sopenharmony_ci		if (IS_ERR(first_cdesc)) {
7718c2ecf20Sopenharmony_ci			/* No space left in the command descriptor ring */
7728c2ecf20Sopenharmony_ci			ret = PTR_ERR(first_cdesc);
7738c2ecf20Sopenharmony_ci			goto cdesc_rollback;
7748c2ecf20Sopenharmony_ci		}
7758c2ecf20Sopenharmony_ci		n_cdesc = 1;
7768c2ecf20Sopenharmony_ci		goto skip_cdesc;
7778c2ecf20Sopenharmony_ci	}
7788c2ecf20Sopenharmony_ci
7798c2ecf20Sopenharmony_ci	/* command descriptors */
7808c2ecf20Sopenharmony_ci	for_each_sg(src, sg, sreq->nr_src, i) {
7818c2ecf20Sopenharmony_ci		int len = sg_dma_len(sg);
7828c2ecf20Sopenharmony_ci
7838c2ecf20Sopenharmony_ci		/* Do not overflow the request */
7848c2ecf20Sopenharmony_ci		if (queued < len)
7858c2ecf20Sopenharmony_ci			len = queued;
7868c2ecf20Sopenharmony_ci
7878c2ecf20Sopenharmony_ci		cdesc = safexcel_add_cdesc(priv, ring, !n_cdesc,
7888c2ecf20Sopenharmony_ci					   !(queued - len),
7898c2ecf20Sopenharmony_ci					   sg_dma_address(sg), len, totlen,
7908c2ecf20Sopenharmony_ci					   ctx->base.ctxr_dma, &atoken);
7918c2ecf20Sopenharmony_ci		if (IS_ERR(cdesc)) {
7928c2ecf20Sopenharmony_ci			/* No space left in the command descriptor ring */
7938c2ecf20Sopenharmony_ci			ret = PTR_ERR(cdesc);
7948c2ecf20Sopenharmony_ci			goto cdesc_rollback;
7958c2ecf20Sopenharmony_ci		}
7968c2ecf20Sopenharmony_ci
7978c2ecf20Sopenharmony_ci		if (!n_cdesc)
7988c2ecf20Sopenharmony_ci			first_cdesc = cdesc;
7998c2ecf20Sopenharmony_ci
8008c2ecf20Sopenharmony_ci		n_cdesc++;
8018c2ecf20Sopenharmony_ci		queued -= len;
8028c2ecf20Sopenharmony_ci		if (!queued)
8038c2ecf20Sopenharmony_ci			break;
8048c2ecf20Sopenharmony_ci	}
8058c2ecf20Sopenharmony_ciskip_cdesc:
8068c2ecf20Sopenharmony_ci	/* Add context control words and token to first command descriptor */
8078c2ecf20Sopenharmony_ci	safexcel_context_control(ctx, base, sreq, first_cdesc);
8088c2ecf20Sopenharmony_ci	if (ctx->aead)
8098c2ecf20Sopenharmony_ci		safexcel_aead_token(ctx, iv, first_cdesc, atoken,
8108c2ecf20Sopenharmony_ci				    sreq->direction, cryptlen,
8118c2ecf20Sopenharmony_ci				    assoclen, digestsize);
8128c2ecf20Sopenharmony_ci	else
8138c2ecf20Sopenharmony_ci		safexcel_skcipher_token(ctx, iv, first_cdesc, atoken,
8148c2ecf20Sopenharmony_ci					cryptlen);
8158c2ecf20Sopenharmony_ci
8168c2ecf20Sopenharmony_ci	/* result descriptors */
8178c2ecf20Sopenharmony_ci	for_each_sg(dst, sg, sreq->nr_dst, i) {
8188c2ecf20Sopenharmony_ci		bool last = (i == sreq->nr_dst - 1);
8198c2ecf20Sopenharmony_ci		u32 len = sg_dma_len(sg);
8208c2ecf20Sopenharmony_ci
8218c2ecf20Sopenharmony_ci		/* only allow the part of the buffer we know we need */
8228c2ecf20Sopenharmony_ci		if (len > totlen_dst)
8238c2ecf20Sopenharmony_ci			len = totlen_dst;
8248c2ecf20Sopenharmony_ci		if (unlikely(!len))
8258c2ecf20Sopenharmony_ci			break;
8268c2ecf20Sopenharmony_ci		totlen_dst -= len;
8278c2ecf20Sopenharmony_ci
8288c2ecf20Sopenharmony_ci		/* skip over AAD space in buffer - not written */
8298c2ecf20Sopenharmony_ci		if (assoclen) {
8308c2ecf20Sopenharmony_ci			if (assoclen >= len) {
8318c2ecf20Sopenharmony_ci				assoclen -= len;
8328c2ecf20Sopenharmony_ci				continue;
8338c2ecf20Sopenharmony_ci			}
8348c2ecf20Sopenharmony_ci			rdesc = safexcel_add_rdesc(priv, ring, first, last,
8358c2ecf20Sopenharmony_ci						   sg_dma_address(sg) +
8368c2ecf20Sopenharmony_ci						   assoclen,
8378c2ecf20Sopenharmony_ci						   len - assoclen);
8388c2ecf20Sopenharmony_ci			assoclen = 0;
8398c2ecf20Sopenharmony_ci		} else {
8408c2ecf20Sopenharmony_ci			rdesc = safexcel_add_rdesc(priv, ring, first, last,
8418c2ecf20Sopenharmony_ci						   sg_dma_address(sg),
8428c2ecf20Sopenharmony_ci						   len);
8438c2ecf20Sopenharmony_ci		}
8448c2ecf20Sopenharmony_ci		if (IS_ERR(rdesc)) {
8458c2ecf20Sopenharmony_ci			/* No space left in the result descriptor ring */
8468c2ecf20Sopenharmony_ci			ret = PTR_ERR(rdesc);
8478c2ecf20Sopenharmony_ci			goto rdesc_rollback;
8488c2ecf20Sopenharmony_ci		}
8498c2ecf20Sopenharmony_ci		if (first) {
8508c2ecf20Sopenharmony_ci			first_rdesc = rdesc;
8518c2ecf20Sopenharmony_ci			first = false;
8528c2ecf20Sopenharmony_ci		}
8538c2ecf20Sopenharmony_ci		n_rdesc++;
8548c2ecf20Sopenharmony_ci	}
8558c2ecf20Sopenharmony_ci
8568c2ecf20Sopenharmony_ci	if (unlikely(first)) {
8578c2ecf20Sopenharmony_ci		/*
8588c2ecf20Sopenharmony_ci		 * Special case: AEAD decrypt with only AAD data.
8598c2ecf20Sopenharmony_ci		 * In this case there is NO output data from the engine,
8608c2ecf20Sopenharmony_ci		 * but the engine still needs a result descriptor!
8618c2ecf20Sopenharmony_ci		 * Create a dummy one just for catching the result token.
8628c2ecf20Sopenharmony_ci		 */
8638c2ecf20Sopenharmony_ci		rdesc = safexcel_add_rdesc(priv, ring, true, true, 0, 0);
8648c2ecf20Sopenharmony_ci		if (IS_ERR(rdesc)) {
8658c2ecf20Sopenharmony_ci			/* No space left in the result descriptor ring */
8668c2ecf20Sopenharmony_ci			ret = PTR_ERR(rdesc);
8678c2ecf20Sopenharmony_ci			goto rdesc_rollback;
8688c2ecf20Sopenharmony_ci		}
8698c2ecf20Sopenharmony_ci		first_rdesc = rdesc;
8708c2ecf20Sopenharmony_ci		n_rdesc = 1;
8718c2ecf20Sopenharmony_ci	}
8728c2ecf20Sopenharmony_ci
8738c2ecf20Sopenharmony_ci	safexcel_rdr_req_set(priv, ring, first_rdesc, base);
8748c2ecf20Sopenharmony_ci
8758c2ecf20Sopenharmony_ci	*commands = n_cdesc;
8768c2ecf20Sopenharmony_ci	*results = n_rdesc;
8778c2ecf20Sopenharmony_ci	return 0;
8788c2ecf20Sopenharmony_ci
8798c2ecf20Sopenharmony_cirdesc_rollback:
8808c2ecf20Sopenharmony_ci	for (i = 0; i < n_rdesc; i++)
8818c2ecf20Sopenharmony_ci		safexcel_ring_rollback_wptr(priv, &priv->ring[ring].rdr);
8828c2ecf20Sopenharmony_cicdesc_rollback:
8838c2ecf20Sopenharmony_ci	for (i = 0; i < n_cdesc; i++)
8848c2ecf20Sopenharmony_ci		safexcel_ring_rollback_wptr(priv, &priv->ring[ring].cdr);
8858c2ecf20Sopenharmony_ci
8868c2ecf20Sopenharmony_ci	if (src == dst) {
8878c2ecf20Sopenharmony_ci		dma_unmap_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL);
8888c2ecf20Sopenharmony_ci	} else {
8898c2ecf20Sopenharmony_ci		dma_unmap_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE);
8908c2ecf20Sopenharmony_ci		dma_unmap_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE);
8918c2ecf20Sopenharmony_ci	}
8928c2ecf20Sopenharmony_ci
8938c2ecf20Sopenharmony_ci	return ret;
8948c2ecf20Sopenharmony_ci}
8958c2ecf20Sopenharmony_ci
8968c2ecf20Sopenharmony_cistatic int safexcel_handle_inv_result(struct safexcel_crypto_priv *priv,
8978c2ecf20Sopenharmony_ci				      int ring,
8988c2ecf20Sopenharmony_ci				      struct crypto_async_request *base,
8998c2ecf20Sopenharmony_ci				      struct safexcel_cipher_req *sreq,
9008c2ecf20Sopenharmony_ci				      bool *should_complete, int *ret)
9018c2ecf20Sopenharmony_ci{
9028c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm);
9038c2ecf20Sopenharmony_ci	struct safexcel_result_desc *rdesc;
9048c2ecf20Sopenharmony_ci	int ndesc = 0, enq_ret;
9058c2ecf20Sopenharmony_ci
9068c2ecf20Sopenharmony_ci	*ret = 0;
9078c2ecf20Sopenharmony_ci
9088c2ecf20Sopenharmony_ci	if (unlikely(!sreq->rdescs))
9098c2ecf20Sopenharmony_ci		return 0;
9108c2ecf20Sopenharmony_ci
9118c2ecf20Sopenharmony_ci	while (sreq->rdescs--) {
9128c2ecf20Sopenharmony_ci		rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr);
9138c2ecf20Sopenharmony_ci		if (IS_ERR(rdesc)) {
9148c2ecf20Sopenharmony_ci			dev_err(priv->dev,
9158c2ecf20Sopenharmony_ci				"cipher: invalidate: could not retrieve the result descriptor\n");
9168c2ecf20Sopenharmony_ci			*ret = PTR_ERR(rdesc);
9178c2ecf20Sopenharmony_ci			break;
9188c2ecf20Sopenharmony_ci		}
9198c2ecf20Sopenharmony_ci
9208c2ecf20Sopenharmony_ci		if (likely(!*ret))
9218c2ecf20Sopenharmony_ci			*ret = safexcel_rdesc_check_errors(priv, rdesc);
9228c2ecf20Sopenharmony_ci
9238c2ecf20Sopenharmony_ci		ndesc++;
9248c2ecf20Sopenharmony_ci	}
9258c2ecf20Sopenharmony_ci
9268c2ecf20Sopenharmony_ci	safexcel_complete(priv, ring);
9278c2ecf20Sopenharmony_ci
9288c2ecf20Sopenharmony_ci	if (ctx->base.exit_inv) {
9298c2ecf20Sopenharmony_ci		dma_pool_free(priv->context_pool, ctx->base.ctxr,
9308c2ecf20Sopenharmony_ci			      ctx->base.ctxr_dma);
9318c2ecf20Sopenharmony_ci
9328c2ecf20Sopenharmony_ci		*should_complete = true;
9338c2ecf20Sopenharmony_ci
9348c2ecf20Sopenharmony_ci		return ndesc;
9358c2ecf20Sopenharmony_ci	}
9368c2ecf20Sopenharmony_ci
9378c2ecf20Sopenharmony_ci	ring = safexcel_select_ring(priv);
9388c2ecf20Sopenharmony_ci	ctx->base.ring = ring;
9398c2ecf20Sopenharmony_ci
9408c2ecf20Sopenharmony_ci	spin_lock_bh(&priv->ring[ring].queue_lock);
9418c2ecf20Sopenharmony_ci	enq_ret = crypto_enqueue_request(&priv->ring[ring].queue, base);
9428c2ecf20Sopenharmony_ci	spin_unlock_bh(&priv->ring[ring].queue_lock);
9438c2ecf20Sopenharmony_ci
9448c2ecf20Sopenharmony_ci	if (enq_ret != -EINPROGRESS)
9458c2ecf20Sopenharmony_ci		*ret = enq_ret;
9468c2ecf20Sopenharmony_ci
9478c2ecf20Sopenharmony_ci	queue_work(priv->ring[ring].workqueue,
9488c2ecf20Sopenharmony_ci		   &priv->ring[ring].work_data.work);
9498c2ecf20Sopenharmony_ci
9508c2ecf20Sopenharmony_ci	*should_complete = false;
9518c2ecf20Sopenharmony_ci
9528c2ecf20Sopenharmony_ci	return ndesc;
9538c2ecf20Sopenharmony_ci}
9548c2ecf20Sopenharmony_ci
9558c2ecf20Sopenharmony_cistatic int safexcel_skcipher_handle_result(struct safexcel_crypto_priv *priv,
9568c2ecf20Sopenharmony_ci					   int ring,
9578c2ecf20Sopenharmony_ci					   struct crypto_async_request *async,
9588c2ecf20Sopenharmony_ci					   bool *should_complete, int *ret)
9598c2ecf20Sopenharmony_ci{
9608c2ecf20Sopenharmony_ci	struct skcipher_request *req = skcipher_request_cast(async);
9618c2ecf20Sopenharmony_ci	struct safexcel_cipher_req *sreq = skcipher_request_ctx(req);
9628c2ecf20Sopenharmony_ci	int err;
9638c2ecf20Sopenharmony_ci
9648c2ecf20Sopenharmony_ci	if (sreq->needs_inv) {
9658c2ecf20Sopenharmony_ci		sreq->needs_inv = false;
9668c2ecf20Sopenharmony_ci		err = safexcel_handle_inv_result(priv, ring, async, sreq,
9678c2ecf20Sopenharmony_ci						 should_complete, ret);
9688c2ecf20Sopenharmony_ci	} else {
9698c2ecf20Sopenharmony_ci		err = safexcel_handle_req_result(priv, ring, async, req->src,
9708c2ecf20Sopenharmony_ci						 req->dst, req->cryptlen, sreq,
9718c2ecf20Sopenharmony_ci						 should_complete, ret);
9728c2ecf20Sopenharmony_ci	}
9738c2ecf20Sopenharmony_ci
9748c2ecf20Sopenharmony_ci	return err;
9758c2ecf20Sopenharmony_ci}
9768c2ecf20Sopenharmony_ci
9778c2ecf20Sopenharmony_cistatic int safexcel_aead_handle_result(struct safexcel_crypto_priv *priv,
9788c2ecf20Sopenharmony_ci				       int ring,
9798c2ecf20Sopenharmony_ci				       struct crypto_async_request *async,
9808c2ecf20Sopenharmony_ci				       bool *should_complete, int *ret)
9818c2ecf20Sopenharmony_ci{
9828c2ecf20Sopenharmony_ci	struct aead_request *req = aead_request_cast(async);
9838c2ecf20Sopenharmony_ci	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
9848c2ecf20Sopenharmony_ci	struct safexcel_cipher_req *sreq = aead_request_ctx(req);
9858c2ecf20Sopenharmony_ci	int err;
9868c2ecf20Sopenharmony_ci
9878c2ecf20Sopenharmony_ci	if (sreq->needs_inv) {
9888c2ecf20Sopenharmony_ci		sreq->needs_inv = false;
9898c2ecf20Sopenharmony_ci		err = safexcel_handle_inv_result(priv, ring, async, sreq,
9908c2ecf20Sopenharmony_ci						 should_complete, ret);
9918c2ecf20Sopenharmony_ci	} else {
9928c2ecf20Sopenharmony_ci		err = safexcel_handle_req_result(priv, ring, async, req->src,
9938c2ecf20Sopenharmony_ci						 req->dst,
9948c2ecf20Sopenharmony_ci						 req->cryptlen + crypto_aead_authsize(tfm),
9958c2ecf20Sopenharmony_ci						 sreq, should_complete, ret);
9968c2ecf20Sopenharmony_ci	}
9978c2ecf20Sopenharmony_ci
9988c2ecf20Sopenharmony_ci	return err;
9998c2ecf20Sopenharmony_ci}
10008c2ecf20Sopenharmony_ci
10018c2ecf20Sopenharmony_cistatic int safexcel_cipher_send_inv(struct crypto_async_request *base,
10028c2ecf20Sopenharmony_ci				    int ring, int *commands, int *results)
10038c2ecf20Sopenharmony_ci{
10048c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm);
10058c2ecf20Sopenharmony_ci	struct safexcel_crypto_priv *priv = ctx->base.priv;
10068c2ecf20Sopenharmony_ci	int ret;
10078c2ecf20Sopenharmony_ci
10088c2ecf20Sopenharmony_ci	ret = safexcel_invalidate_cache(base, priv, ctx->base.ctxr_dma, ring);
10098c2ecf20Sopenharmony_ci	if (unlikely(ret))
10108c2ecf20Sopenharmony_ci		return ret;
10118c2ecf20Sopenharmony_ci
10128c2ecf20Sopenharmony_ci	*commands = 1;
10138c2ecf20Sopenharmony_ci	*results = 1;
10148c2ecf20Sopenharmony_ci
10158c2ecf20Sopenharmony_ci	return 0;
10168c2ecf20Sopenharmony_ci}
10178c2ecf20Sopenharmony_ci
10188c2ecf20Sopenharmony_cistatic int safexcel_skcipher_send(struct crypto_async_request *async, int ring,
10198c2ecf20Sopenharmony_ci				  int *commands, int *results)
10208c2ecf20Sopenharmony_ci{
10218c2ecf20Sopenharmony_ci	struct skcipher_request *req = skcipher_request_cast(async);
10228c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
10238c2ecf20Sopenharmony_ci	struct safexcel_cipher_req *sreq = skcipher_request_ctx(req);
10248c2ecf20Sopenharmony_ci	struct safexcel_crypto_priv *priv = ctx->base.priv;
10258c2ecf20Sopenharmony_ci	int ret;
10268c2ecf20Sopenharmony_ci
10278c2ecf20Sopenharmony_ci	BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && sreq->needs_inv);
10288c2ecf20Sopenharmony_ci
10298c2ecf20Sopenharmony_ci	if (sreq->needs_inv) {
10308c2ecf20Sopenharmony_ci		ret = safexcel_cipher_send_inv(async, ring, commands, results);
10318c2ecf20Sopenharmony_ci	} else {
10328c2ecf20Sopenharmony_ci		struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
10338c2ecf20Sopenharmony_ci		u8 input_iv[AES_BLOCK_SIZE];
10348c2ecf20Sopenharmony_ci
10358c2ecf20Sopenharmony_ci		/*
10368c2ecf20Sopenharmony_ci		 * Save input IV in case of CBC decrypt mode
10378c2ecf20Sopenharmony_ci		 * Will be overwritten with output IV prior to use!
10388c2ecf20Sopenharmony_ci		 */
10398c2ecf20Sopenharmony_ci		memcpy(input_iv, req->iv, crypto_skcipher_ivsize(skcipher));
10408c2ecf20Sopenharmony_ci
10418c2ecf20Sopenharmony_ci		ret = safexcel_send_req(async, ring, sreq, req->src,
10428c2ecf20Sopenharmony_ci					req->dst, req->cryptlen, 0, 0, input_iv,
10438c2ecf20Sopenharmony_ci					commands, results);
10448c2ecf20Sopenharmony_ci	}
10458c2ecf20Sopenharmony_ci
10468c2ecf20Sopenharmony_ci	sreq->rdescs = *results;
10478c2ecf20Sopenharmony_ci	return ret;
10488c2ecf20Sopenharmony_ci}
10498c2ecf20Sopenharmony_ci
10508c2ecf20Sopenharmony_cistatic int safexcel_aead_send(struct crypto_async_request *async, int ring,
10518c2ecf20Sopenharmony_ci			      int *commands, int *results)
10528c2ecf20Sopenharmony_ci{
10538c2ecf20Sopenharmony_ci	struct aead_request *req = aead_request_cast(async);
10548c2ecf20Sopenharmony_ci	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
10558c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
10568c2ecf20Sopenharmony_ci	struct safexcel_cipher_req *sreq = aead_request_ctx(req);
10578c2ecf20Sopenharmony_ci	struct safexcel_crypto_priv *priv = ctx->base.priv;
10588c2ecf20Sopenharmony_ci	int ret;
10598c2ecf20Sopenharmony_ci
10608c2ecf20Sopenharmony_ci	BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && sreq->needs_inv);
10618c2ecf20Sopenharmony_ci
10628c2ecf20Sopenharmony_ci	if (sreq->needs_inv)
10638c2ecf20Sopenharmony_ci		ret = safexcel_cipher_send_inv(async, ring, commands, results);
10648c2ecf20Sopenharmony_ci	else
10658c2ecf20Sopenharmony_ci		ret = safexcel_send_req(async, ring, sreq, req->src, req->dst,
10668c2ecf20Sopenharmony_ci					req->cryptlen, req->assoclen,
10678c2ecf20Sopenharmony_ci					crypto_aead_authsize(tfm), req->iv,
10688c2ecf20Sopenharmony_ci					commands, results);
10698c2ecf20Sopenharmony_ci	sreq->rdescs = *results;
10708c2ecf20Sopenharmony_ci	return ret;
10718c2ecf20Sopenharmony_ci}
10728c2ecf20Sopenharmony_ci
10738c2ecf20Sopenharmony_cistatic int safexcel_cipher_exit_inv(struct crypto_tfm *tfm,
10748c2ecf20Sopenharmony_ci				    struct crypto_async_request *base,
10758c2ecf20Sopenharmony_ci				    struct safexcel_cipher_req *sreq,
10768c2ecf20Sopenharmony_ci				    struct safexcel_inv_result *result)
10778c2ecf20Sopenharmony_ci{
10788c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
10798c2ecf20Sopenharmony_ci	struct safexcel_crypto_priv *priv = ctx->base.priv;
10808c2ecf20Sopenharmony_ci	int ring = ctx->base.ring;
10818c2ecf20Sopenharmony_ci
10828c2ecf20Sopenharmony_ci	init_completion(&result->completion);
10838c2ecf20Sopenharmony_ci
10848c2ecf20Sopenharmony_ci	ctx = crypto_tfm_ctx(base->tfm);
10858c2ecf20Sopenharmony_ci	ctx->base.exit_inv = true;
10868c2ecf20Sopenharmony_ci	sreq->needs_inv = true;
10878c2ecf20Sopenharmony_ci
10888c2ecf20Sopenharmony_ci	spin_lock_bh(&priv->ring[ring].queue_lock);
10898c2ecf20Sopenharmony_ci	crypto_enqueue_request(&priv->ring[ring].queue, base);
10908c2ecf20Sopenharmony_ci	spin_unlock_bh(&priv->ring[ring].queue_lock);
10918c2ecf20Sopenharmony_ci
10928c2ecf20Sopenharmony_ci	queue_work(priv->ring[ring].workqueue,
10938c2ecf20Sopenharmony_ci		   &priv->ring[ring].work_data.work);
10948c2ecf20Sopenharmony_ci
10958c2ecf20Sopenharmony_ci	wait_for_completion(&result->completion);
10968c2ecf20Sopenharmony_ci
10978c2ecf20Sopenharmony_ci	if (result->error) {
10988c2ecf20Sopenharmony_ci		dev_warn(priv->dev,
10998c2ecf20Sopenharmony_ci			"cipher: sync: invalidate: completion error %d\n",
11008c2ecf20Sopenharmony_ci			 result->error);
11018c2ecf20Sopenharmony_ci		return result->error;
11028c2ecf20Sopenharmony_ci	}
11038c2ecf20Sopenharmony_ci
11048c2ecf20Sopenharmony_ci	return 0;
11058c2ecf20Sopenharmony_ci}
11068c2ecf20Sopenharmony_ci
11078c2ecf20Sopenharmony_cistatic int safexcel_skcipher_exit_inv(struct crypto_tfm *tfm)
11088c2ecf20Sopenharmony_ci{
11098c2ecf20Sopenharmony_ci	EIP197_REQUEST_ON_STACK(req, skcipher, EIP197_SKCIPHER_REQ_SIZE);
11108c2ecf20Sopenharmony_ci	struct safexcel_cipher_req *sreq = skcipher_request_ctx(req);
11118c2ecf20Sopenharmony_ci	struct safexcel_inv_result result = {};
11128c2ecf20Sopenharmony_ci
11138c2ecf20Sopenharmony_ci	memset(req, 0, sizeof(struct skcipher_request));
11148c2ecf20Sopenharmony_ci
11158c2ecf20Sopenharmony_ci	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
11168c2ecf20Sopenharmony_ci				      safexcel_inv_complete, &result);
11178c2ecf20Sopenharmony_ci	skcipher_request_set_tfm(req, __crypto_skcipher_cast(tfm));
11188c2ecf20Sopenharmony_ci
11198c2ecf20Sopenharmony_ci	return safexcel_cipher_exit_inv(tfm, &req->base, sreq, &result);
11208c2ecf20Sopenharmony_ci}
11218c2ecf20Sopenharmony_ci
11228c2ecf20Sopenharmony_cistatic int safexcel_aead_exit_inv(struct crypto_tfm *tfm)
11238c2ecf20Sopenharmony_ci{
11248c2ecf20Sopenharmony_ci	EIP197_REQUEST_ON_STACK(req, aead, EIP197_AEAD_REQ_SIZE);
11258c2ecf20Sopenharmony_ci	struct safexcel_cipher_req *sreq = aead_request_ctx(req);
11268c2ecf20Sopenharmony_ci	struct safexcel_inv_result result = {};
11278c2ecf20Sopenharmony_ci
11288c2ecf20Sopenharmony_ci	memset(req, 0, sizeof(struct aead_request));
11298c2ecf20Sopenharmony_ci
11308c2ecf20Sopenharmony_ci	aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
11318c2ecf20Sopenharmony_ci				  safexcel_inv_complete, &result);
11328c2ecf20Sopenharmony_ci	aead_request_set_tfm(req, __crypto_aead_cast(tfm));
11338c2ecf20Sopenharmony_ci
11348c2ecf20Sopenharmony_ci	return safexcel_cipher_exit_inv(tfm, &req->base, sreq, &result);
11358c2ecf20Sopenharmony_ci}
11368c2ecf20Sopenharmony_ci
11378c2ecf20Sopenharmony_cistatic int safexcel_queue_req(struct crypto_async_request *base,
11388c2ecf20Sopenharmony_ci			struct safexcel_cipher_req *sreq,
11398c2ecf20Sopenharmony_ci			enum safexcel_cipher_direction dir)
11408c2ecf20Sopenharmony_ci{
11418c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm);
11428c2ecf20Sopenharmony_ci	struct safexcel_crypto_priv *priv = ctx->base.priv;
11438c2ecf20Sopenharmony_ci	int ret, ring;
11448c2ecf20Sopenharmony_ci
11458c2ecf20Sopenharmony_ci	sreq->needs_inv = false;
11468c2ecf20Sopenharmony_ci	sreq->direction = dir;
11478c2ecf20Sopenharmony_ci
11488c2ecf20Sopenharmony_ci	if (ctx->base.ctxr) {
11498c2ecf20Sopenharmony_ci		if (priv->flags & EIP197_TRC_CACHE && ctx->base.needs_inv) {
11508c2ecf20Sopenharmony_ci			sreq->needs_inv = true;
11518c2ecf20Sopenharmony_ci			ctx->base.needs_inv = false;
11528c2ecf20Sopenharmony_ci		}
11538c2ecf20Sopenharmony_ci	} else {
11548c2ecf20Sopenharmony_ci		ctx->base.ring = safexcel_select_ring(priv);
11558c2ecf20Sopenharmony_ci		ctx->base.ctxr = dma_pool_zalloc(priv->context_pool,
11568c2ecf20Sopenharmony_ci						 EIP197_GFP_FLAGS(*base),
11578c2ecf20Sopenharmony_ci						 &ctx->base.ctxr_dma);
11588c2ecf20Sopenharmony_ci		if (!ctx->base.ctxr)
11598c2ecf20Sopenharmony_ci			return -ENOMEM;
11608c2ecf20Sopenharmony_ci	}
11618c2ecf20Sopenharmony_ci
11628c2ecf20Sopenharmony_ci	ring = ctx->base.ring;
11638c2ecf20Sopenharmony_ci
11648c2ecf20Sopenharmony_ci	spin_lock_bh(&priv->ring[ring].queue_lock);
11658c2ecf20Sopenharmony_ci	ret = crypto_enqueue_request(&priv->ring[ring].queue, base);
11668c2ecf20Sopenharmony_ci	spin_unlock_bh(&priv->ring[ring].queue_lock);
11678c2ecf20Sopenharmony_ci
11688c2ecf20Sopenharmony_ci	queue_work(priv->ring[ring].workqueue,
11698c2ecf20Sopenharmony_ci		   &priv->ring[ring].work_data.work);
11708c2ecf20Sopenharmony_ci
11718c2ecf20Sopenharmony_ci	return ret;
11728c2ecf20Sopenharmony_ci}
11738c2ecf20Sopenharmony_ci
11748c2ecf20Sopenharmony_cistatic int safexcel_encrypt(struct skcipher_request *req)
11758c2ecf20Sopenharmony_ci{
11768c2ecf20Sopenharmony_ci	return safexcel_queue_req(&req->base, skcipher_request_ctx(req),
11778c2ecf20Sopenharmony_ci			SAFEXCEL_ENCRYPT);
11788c2ecf20Sopenharmony_ci}
11798c2ecf20Sopenharmony_ci
11808c2ecf20Sopenharmony_cistatic int safexcel_decrypt(struct skcipher_request *req)
11818c2ecf20Sopenharmony_ci{
11828c2ecf20Sopenharmony_ci	return safexcel_queue_req(&req->base, skcipher_request_ctx(req),
11838c2ecf20Sopenharmony_ci			SAFEXCEL_DECRYPT);
11848c2ecf20Sopenharmony_ci}
11858c2ecf20Sopenharmony_ci
11868c2ecf20Sopenharmony_cistatic int safexcel_skcipher_cra_init(struct crypto_tfm *tfm)
11878c2ecf20Sopenharmony_ci{
11888c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
11898c2ecf20Sopenharmony_ci	struct safexcel_alg_template *tmpl =
11908c2ecf20Sopenharmony_ci		container_of(tfm->__crt_alg, struct safexcel_alg_template,
11918c2ecf20Sopenharmony_ci			     alg.skcipher.base);
11928c2ecf20Sopenharmony_ci
11938c2ecf20Sopenharmony_ci	crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm),
11948c2ecf20Sopenharmony_ci				    sizeof(struct safexcel_cipher_req));
11958c2ecf20Sopenharmony_ci
11968c2ecf20Sopenharmony_ci	ctx->base.priv = tmpl->priv;
11978c2ecf20Sopenharmony_ci
11988c2ecf20Sopenharmony_ci	ctx->base.send = safexcel_skcipher_send;
11998c2ecf20Sopenharmony_ci	ctx->base.handle_result = safexcel_skcipher_handle_result;
12008c2ecf20Sopenharmony_ci	ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD;
12018c2ecf20Sopenharmony_ci	ctx->ctrinit = 1;
12028c2ecf20Sopenharmony_ci	return 0;
12038c2ecf20Sopenharmony_ci}
12048c2ecf20Sopenharmony_ci
12058c2ecf20Sopenharmony_cistatic int safexcel_cipher_cra_exit(struct crypto_tfm *tfm)
12068c2ecf20Sopenharmony_ci{
12078c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
12088c2ecf20Sopenharmony_ci
12098c2ecf20Sopenharmony_ci	memzero_explicit(ctx->key, sizeof(ctx->key));
12108c2ecf20Sopenharmony_ci
12118c2ecf20Sopenharmony_ci	/* context not allocated, skip invalidation */
12128c2ecf20Sopenharmony_ci	if (!ctx->base.ctxr)
12138c2ecf20Sopenharmony_ci		return -ENOMEM;
12148c2ecf20Sopenharmony_ci
12158c2ecf20Sopenharmony_ci	memzero_explicit(ctx->base.ctxr->data, sizeof(ctx->base.ctxr->data));
12168c2ecf20Sopenharmony_ci	return 0;
12178c2ecf20Sopenharmony_ci}
12188c2ecf20Sopenharmony_ci
12198c2ecf20Sopenharmony_cistatic void safexcel_skcipher_cra_exit(struct crypto_tfm *tfm)
12208c2ecf20Sopenharmony_ci{
12218c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
12228c2ecf20Sopenharmony_ci	struct safexcel_crypto_priv *priv = ctx->base.priv;
12238c2ecf20Sopenharmony_ci	int ret;
12248c2ecf20Sopenharmony_ci
12258c2ecf20Sopenharmony_ci	if (safexcel_cipher_cra_exit(tfm))
12268c2ecf20Sopenharmony_ci		return;
12278c2ecf20Sopenharmony_ci
12288c2ecf20Sopenharmony_ci	if (priv->flags & EIP197_TRC_CACHE) {
12298c2ecf20Sopenharmony_ci		ret = safexcel_skcipher_exit_inv(tfm);
12308c2ecf20Sopenharmony_ci		if (ret)
12318c2ecf20Sopenharmony_ci			dev_warn(priv->dev, "skcipher: invalidation error %d\n",
12328c2ecf20Sopenharmony_ci				 ret);
12338c2ecf20Sopenharmony_ci	} else {
12348c2ecf20Sopenharmony_ci		dma_pool_free(priv->context_pool, ctx->base.ctxr,
12358c2ecf20Sopenharmony_ci			      ctx->base.ctxr_dma);
12368c2ecf20Sopenharmony_ci	}
12378c2ecf20Sopenharmony_ci}
12388c2ecf20Sopenharmony_ci
12398c2ecf20Sopenharmony_cistatic void safexcel_aead_cra_exit(struct crypto_tfm *tfm)
12408c2ecf20Sopenharmony_ci{
12418c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
12428c2ecf20Sopenharmony_ci	struct safexcel_crypto_priv *priv = ctx->base.priv;
12438c2ecf20Sopenharmony_ci	int ret;
12448c2ecf20Sopenharmony_ci
12458c2ecf20Sopenharmony_ci	if (safexcel_cipher_cra_exit(tfm))
12468c2ecf20Sopenharmony_ci		return;
12478c2ecf20Sopenharmony_ci
12488c2ecf20Sopenharmony_ci	if (priv->flags & EIP197_TRC_CACHE) {
12498c2ecf20Sopenharmony_ci		ret = safexcel_aead_exit_inv(tfm);
12508c2ecf20Sopenharmony_ci		if (ret)
12518c2ecf20Sopenharmony_ci			dev_warn(priv->dev, "aead: invalidation error %d\n",
12528c2ecf20Sopenharmony_ci				 ret);
12538c2ecf20Sopenharmony_ci	} else {
12548c2ecf20Sopenharmony_ci		dma_pool_free(priv->context_pool, ctx->base.ctxr,
12558c2ecf20Sopenharmony_ci			      ctx->base.ctxr_dma);
12568c2ecf20Sopenharmony_ci	}
12578c2ecf20Sopenharmony_ci}
12588c2ecf20Sopenharmony_ci
12598c2ecf20Sopenharmony_cistatic int safexcel_skcipher_aes_ecb_cra_init(struct crypto_tfm *tfm)
12608c2ecf20Sopenharmony_ci{
12618c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
12628c2ecf20Sopenharmony_ci
12638c2ecf20Sopenharmony_ci	safexcel_skcipher_cra_init(tfm);
12648c2ecf20Sopenharmony_ci	ctx->alg  = SAFEXCEL_AES;
12658c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB;
12668c2ecf20Sopenharmony_ci	ctx->blocksz = 0;
12678c2ecf20Sopenharmony_ci	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
12688c2ecf20Sopenharmony_ci	return 0;
12698c2ecf20Sopenharmony_ci}
12708c2ecf20Sopenharmony_ci
12718c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ecb_aes = {
12728c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
12738c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES,
12748c2ecf20Sopenharmony_ci	.alg.skcipher = {
12758c2ecf20Sopenharmony_ci		.setkey = safexcel_skcipher_aes_setkey,
12768c2ecf20Sopenharmony_ci		.encrypt = safexcel_encrypt,
12778c2ecf20Sopenharmony_ci		.decrypt = safexcel_decrypt,
12788c2ecf20Sopenharmony_ci		.min_keysize = AES_MIN_KEY_SIZE,
12798c2ecf20Sopenharmony_ci		.max_keysize = AES_MAX_KEY_SIZE,
12808c2ecf20Sopenharmony_ci		.base = {
12818c2ecf20Sopenharmony_ci			.cra_name = "ecb(aes)",
12828c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-ecb-aes",
12838c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
12848c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
12858c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
12868c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
12878c2ecf20Sopenharmony_ci			.cra_blocksize = AES_BLOCK_SIZE,
12888c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
12898c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
12908c2ecf20Sopenharmony_ci			.cra_init = safexcel_skcipher_aes_ecb_cra_init,
12918c2ecf20Sopenharmony_ci			.cra_exit = safexcel_skcipher_cra_exit,
12928c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
12938c2ecf20Sopenharmony_ci		},
12948c2ecf20Sopenharmony_ci	},
12958c2ecf20Sopenharmony_ci};
12968c2ecf20Sopenharmony_ci
12978c2ecf20Sopenharmony_cistatic int safexcel_skcipher_aes_cbc_cra_init(struct crypto_tfm *tfm)
12988c2ecf20Sopenharmony_ci{
12998c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
13008c2ecf20Sopenharmony_ci
13018c2ecf20Sopenharmony_ci	safexcel_skcipher_cra_init(tfm);
13028c2ecf20Sopenharmony_ci	ctx->alg  = SAFEXCEL_AES;
13038c2ecf20Sopenharmony_ci	ctx->blocksz = AES_BLOCK_SIZE;
13048c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC;
13058c2ecf20Sopenharmony_ci	return 0;
13068c2ecf20Sopenharmony_ci}
13078c2ecf20Sopenharmony_ci
13088c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_cbc_aes = {
13098c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
13108c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES,
13118c2ecf20Sopenharmony_ci	.alg.skcipher = {
13128c2ecf20Sopenharmony_ci		.setkey = safexcel_skcipher_aes_setkey,
13138c2ecf20Sopenharmony_ci		.encrypt = safexcel_encrypt,
13148c2ecf20Sopenharmony_ci		.decrypt = safexcel_decrypt,
13158c2ecf20Sopenharmony_ci		.min_keysize = AES_MIN_KEY_SIZE,
13168c2ecf20Sopenharmony_ci		.max_keysize = AES_MAX_KEY_SIZE,
13178c2ecf20Sopenharmony_ci		.ivsize = AES_BLOCK_SIZE,
13188c2ecf20Sopenharmony_ci		.base = {
13198c2ecf20Sopenharmony_ci			.cra_name = "cbc(aes)",
13208c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-cbc-aes",
13218c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
13228c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
13238c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
13248c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
13258c2ecf20Sopenharmony_ci			.cra_blocksize = AES_BLOCK_SIZE,
13268c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
13278c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
13288c2ecf20Sopenharmony_ci			.cra_init = safexcel_skcipher_aes_cbc_cra_init,
13298c2ecf20Sopenharmony_ci			.cra_exit = safexcel_skcipher_cra_exit,
13308c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
13318c2ecf20Sopenharmony_ci		},
13328c2ecf20Sopenharmony_ci	},
13338c2ecf20Sopenharmony_ci};
13348c2ecf20Sopenharmony_ci
13358c2ecf20Sopenharmony_cistatic int safexcel_skcipher_aes_cfb_cra_init(struct crypto_tfm *tfm)
13368c2ecf20Sopenharmony_ci{
13378c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
13388c2ecf20Sopenharmony_ci
13398c2ecf20Sopenharmony_ci	safexcel_skcipher_cra_init(tfm);
13408c2ecf20Sopenharmony_ci	ctx->alg  = SAFEXCEL_AES;
13418c2ecf20Sopenharmony_ci	ctx->blocksz = AES_BLOCK_SIZE;
13428c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CFB;
13438c2ecf20Sopenharmony_ci	return 0;
13448c2ecf20Sopenharmony_ci}
13458c2ecf20Sopenharmony_ci
13468c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_cfb_aes = {
13478c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
13488c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XFB,
13498c2ecf20Sopenharmony_ci	.alg.skcipher = {
13508c2ecf20Sopenharmony_ci		.setkey = safexcel_skcipher_aes_setkey,
13518c2ecf20Sopenharmony_ci		.encrypt = safexcel_encrypt,
13528c2ecf20Sopenharmony_ci		.decrypt = safexcel_decrypt,
13538c2ecf20Sopenharmony_ci		.min_keysize = AES_MIN_KEY_SIZE,
13548c2ecf20Sopenharmony_ci		.max_keysize = AES_MAX_KEY_SIZE,
13558c2ecf20Sopenharmony_ci		.ivsize = AES_BLOCK_SIZE,
13568c2ecf20Sopenharmony_ci		.base = {
13578c2ecf20Sopenharmony_ci			.cra_name = "cfb(aes)",
13588c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-cfb-aes",
13598c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
13608c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
13618c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
13628c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
13638c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
13648c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
13658c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
13668c2ecf20Sopenharmony_ci			.cra_init = safexcel_skcipher_aes_cfb_cra_init,
13678c2ecf20Sopenharmony_ci			.cra_exit = safexcel_skcipher_cra_exit,
13688c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
13698c2ecf20Sopenharmony_ci		},
13708c2ecf20Sopenharmony_ci	},
13718c2ecf20Sopenharmony_ci};
13728c2ecf20Sopenharmony_ci
13738c2ecf20Sopenharmony_cistatic int safexcel_skcipher_aes_ofb_cra_init(struct crypto_tfm *tfm)
13748c2ecf20Sopenharmony_ci{
13758c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
13768c2ecf20Sopenharmony_ci
13778c2ecf20Sopenharmony_ci	safexcel_skcipher_cra_init(tfm);
13788c2ecf20Sopenharmony_ci	ctx->alg  = SAFEXCEL_AES;
13798c2ecf20Sopenharmony_ci	ctx->blocksz = AES_BLOCK_SIZE;
13808c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_OFB;
13818c2ecf20Sopenharmony_ci	return 0;
13828c2ecf20Sopenharmony_ci}
13838c2ecf20Sopenharmony_ci
13848c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ofb_aes = {
13858c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
13868c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XFB,
13878c2ecf20Sopenharmony_ci	.alg.skcipher = {
13888c2ecf20Sopenharmony_ci		.setkey = safexcel_skcipher_aes_setkey,
13898c2ecf20Sopenharmony_ci		.encrypt = safexcel_encrypt,
13908c2ecf20Sopenharmony_ci		.decrypt = safexcel_decrypt,
13918c2ecf20Sopenharmony_ci		.min_keysize = AES_MIN_KEY_SIZE,
13928c2ecf20Sopenharmony_ci		.max_keysize = AES_MAX_KEY_SIZE,
13938c2ecf20Sopenharmony_ci		.ivsize = AES_BLOCK_SIZE,
13948c2ecf20Sopenharmony_ci		.base = {
13958c2ecf20Sopenharmony_ci			.cra_name = "ofb(aes)",
13968c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-ofb-aes",
13978c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
13988c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
13998c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
14008c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
14018c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
14028c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
14038c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
14048c2ecf20Sopenharmony_ci			.cra_init = safexcel_skcipher_aes_ofb_cra_init,
14058c2ecf20Sopenharmony_ci			.cra_exit = safexcel_skcipher_cra_exit,
14068c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
14078c2ecf20Sopenharmony_ci		},
14088c2ecf20Sopenharmony_ci	},
14098c2ecf20Sopenharmony_ci};
14108c2ecf20Sopenharmony_ci
14118c2ecf20Sopenharmony_cistatic int safexcel_skcipher_aesctr_setkey(struct crypto_skcipher *ctfm,
14128c2ecf20Sopenharmony_ci					   const u8 *key, unsigned int len)
14138c2ecf20Sopenharmony_ci{
14148c2ecf20Sopenharmony_ci	struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);
14158c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
14168c2ecf20Sopenharmony_ci	struct safexcel_crypto_priv *priv = ctx->base.priv;
14178c2ecf20Sopenharmony_ci	struct crypto_aes_ctx aes;
14188c2ecf20Sopenharmony_ci	int ret, i;
14198c2ecf20Sopenharmony_ci	unsigned int keylen;
14208c2ecf20Sopenharmony_ci
14218c2ecf20Sopenharmony_ci	/* last 4 bytes of key are the nonce! */
14228c2ecf20Sopenharmony_ci	ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE);
14238c2ecf20Sopenharmony_ci	/* exclude the nonce here */
14248c2ecf20Sopenharmony_ci	keylen = len - CTR_RFC3686_NONCE_SIZE;
14258c2ecf20Sopenharmony_ci	ret = aes_expandkey(&aes, key, keylen);
14268c2ecf20Sopenharmony_ci	if (ret)
14278c2ecf20Sopenharmony_ci		return ret;
14288c2ecf20Sopenharmony_ci
14298c2ecf20Sopenharmony_ci	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
14308c2ecf20Sopenharmony_ci		for (i = 0; i < keylen / sizeof(u32); i++) {
14318c2ecf20Sopenharmony_ci			if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {
14328c2ecf20Sopenharmony_ci				ctx->base.needs_inv = true;
14338c2ecf20Sopenharmony_ci				break;
14348c2ecf20Sopenharmony_ci			}
14358c2ecf20Sopenharmony_ci		}
14368c2ecf20Sopenharmony_ci	}
14378c2ecf20Sopenharmony_ci
14388c2ecf20Sopenharmony_ci	for (i = 0; i < keylen / sizeof(u32); i++)
14398c2ecf20Sopenharmony_ci		ctx->key[i] = cpu_to_le32(aes.key_enc[i]);
14408c2ecf20Sopenharmony_ci
14418c2ecf20Sopenharmony_ci	ctx->key_len = keylen;
14428c2ecf20Sopenharmony_ci
14438c2ecf20Sopenharmony_ci	memzero_explicit(&aes, sizeof(aes));
14448c2ecf20Sopenharmony_ci	return 0;
14458c2ecf20Sopenharmony_ci}
14468c2ecf20Sopenharmony_ci
14478c2ecf20Sopenharmony_cistatic int safexcel_skcipher_aes_ctr_cra_init(struct crypto_tfm *tfm)
14488c2ecf20Sopenharmony_ci{
14498c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
14508c2ecf20Sopenharmony_ci
14518c2ecf20Sopenharmony_ci	safexcel_skcipher_cra_init(tfm);
14528c2ecf20Sopenharmony_ci	ctx->alg  = SAFEXCEL_AES;
14538c2ecf20Sopenharmony_ci	ctx->blocksz = AES_BLOCK_SIZE;
14548c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;
14558c2ecf20Sopenharmony_ci	return 0;
14568c2ecf20Sopenharmony_ci}
14578c2ecf20Sopenharmony_ci
14588c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ctr_aes = {
14598c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
14608c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES,
14618c2ecf20Sopenharmony_ci	.alg.skcipher = {
14628c2ecf20Sopenharmony_ci		.setkey = safexcel_skcipher_aesctr_setkey,
14638c2ecf20Sopenharmony_ci		.encrypt = safexcel_encrypt,
14648c2ecf20Sopenharmony_ci		.decrypt = safexcel_decrypt,
14658c2ecf20Sopenharmony_ci		/* Add nonce size */
14668c2ecf20Sopenharmony_ci		.min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,
14678c2ecf20Sopenharmony_ci		.max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,
14688c2ecf20Sopenharmony_ci		.ivsize = CTR_RFC3686_IV_SIZE,
14698c2ecf20Sopenharmony_ci		.base = {
14708c2ecf20Sopenharmony_ci			.cra_name = "rfc3686(ctr(aes))",
14718c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-ctr-aes",
14728c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
14738c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
14748c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
14758c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
14768c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
14778c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
14788c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
14798c2ecf20Sopenharmony_ci			.cra_init = safexcel_skcipher_aes_ctr_cra_init,
14808c2ecf20Sopenharmony_ci			.cra_exit = safexcel_skcipher_cra_exit,
14818c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
14828c2ecf20Sopenharmony_ci		},
14838c2ecf20Sopenharmony_ci	},
14848c2ecf20Sopenharmony_ci};
14858c2ecf20Sopenharmony_ci
14868c2ecf20Sopenharmony_cistatic int safexcel_des_setkey(struct crypto_skcipher *ctfm, const u8 *key,
14878c2ecf20Sopenharmony_ci			       unsigned int len)
14888c2ecf20Sopenharmony_ci{
14898c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm);
14908c2ecf20Sopenharmony_ci	struct safexcel_crypto_priv *priv = ctx->base.priv;
14918c2ecf20Sopenharmony_ci	int ret;
14928c2ecf20Sopenharmony_ci
14938c2ecf20Sopenharmony_ci	ret = verify_skcipher_des_key(ctfm, key);
14948c2ecf20Sopenharmony_ci	if (ret)
14958c2ecf20Sopenharmony_ci		return ret;
14968c2ecf20Sopenharmony_ci
14978c2ecf20Sopenharmony_ci	/* if context exits and key changed, need to invalidate it */
14988c2ecf20Sopenharmony_ci	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma)
14998c2ecf20Sopenharmony_ci		if (memcmp(ctx->key, key, len))
15008c2ecf20Sopenharmony_ci			ctx->base.needs_inv = true;
15018c2ecf20Sopenharmony_ci
15028c2ecf20Sopenharmony_ci	memcpy(ctx->key, key, len);
15038c2ecf20Sopenharmony_ci	ctx->key_len = len;
15048c2ecf20Sopenharmony_ci
15058c2ecf20Sopenharmony_ci	return 0;
15068c2ecf20Sopenharmony_ci}
15078c2ecf20Sopenharmony_ci
15088c2ecf20Sopenharmony_cistatic int safexcel_skcipher_des_cbc_cra_init(struct crypto_tfm *tfm)
15098c2ecf20Sopenharmony_ci{
15108c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
15118c2ecf20Sopenharmony_ci
15128c2ecf20Sopenharmony_ci	safexcel_skcipher_cra_init(tfm);
15138c2ecf20Sopenharmony_ci	ctx->alg  = SAFEXCEL_DES;
15148c2ecf20Sopenharmony_ci	ctx->blocksz = DES_BLOCK_SIZE;
15158c2ecf20Sopenharmony_ci	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
15168c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC;
15178c2ecf20Sopenharmony_ci	return 0;
15188c2ecf20Sopenharmony_ci}
15198c2ecf20Sopenharmony_ci
15208c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_cbc_des = {
15218c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
15228c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_DES,
15238c2ecf20Sopenharmony_ci	.alg.skcipher = {
15248c2ecf20Sopenharmony_ci		.setkey = safexcel_des_setkey,
15258c2ecf20Sopenharmony_ci		.encrypt = safexcel_encrypt,
15268c2ecf20Sopenharmony_ci		.decrypt = safexcel_decrypt,
15278c2ecf20Sopenharmony_ci		.min_keysize = DES_KEY_SIZE,
15288c2ecf20Sopenharmony_ci		.max_keysize = DES_KEY_SIZE,
15298c2ecf20Sopenharmony_ci		.ivsize = DES_BLOCK_SIZE,
15308c2ecf20Sopenharmony_ci		.base = {
15318c2ecf20Sopenharmony_ci			.cra_name = "cbc(des)",
15328c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-cbc-des",
15338c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
15348c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
15358c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
15368c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
15378c2ecf20Sopenharmony_ci			.cra_blocksize = DES_BLOCK_SIZE,
15388c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
15398c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
15408c2ecf20Sopenharmony_ci			.cra_init = safexcel_skcipher_des_cbc_cra_init,
15418c2ecf20Sopenharmony_ci			.cra_exit = safexcel_skcipher_cra_exit,
15428c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
15438c2ecf20Sopenharmony_ci		},
15448c2ecf20Sopenharmony_ci	},
15458c2ecf20Sopenharmony_ci};
15468c2ecf20Sopenharmony_ci
15478c2ecf20Sopenharmony_cistatic int safexcel_skcipher_des_ecb_cra_init(struct crypto_tfm *tfm)
15488c2ecf20Sopenharmony_ci{
15498c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
15508c2ecf20Sopenharmony_ci
15518c2ecf20Sopenharmony_ci	safexcel_skcipher_cra_init(tfm);
15528c2ecf20Sopenharmony_ci	ctx->alg  = SAFEXCEL_DES;
15538c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB;
15548c2ecf20Sopenharmony_ci	ctx->blocksz = 0;
15558c2ecf20Sopenharmony_ci	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
15568c2ecf20Sopenharmony_ci	return 0;
15578c2ecf20Sopenharmony_ci}
15588c2ecf20Sopenharmony_ci
15598c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ecb_des = {
15608c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
15618c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_DES,
15628c2ecf20Sopenharmony_ci	.alg.skcipher = {
15638c2ecf20Sopenharmony_ci		.setkey = safexcel_des_setkey,
15648c2ecf20Sopenharmony_ci		.encrypt = safexcel_encrypt,
15658c2ecf20Sopenharmony_ci		.decrypt = safexcel_decrypt,
15668c2ecf20Sopenharmony_ci		.min_keysize = DES_KEY_SIZE,
15678c2ecf20Sopenharmony_ci		.max_keysize = DES_KEY_SIZE,
15688c2ecf20Sopenharmony_ci		.base = {
15698c2ecf20Sopenharmony_ci			.cra_name = "ecb(des)",
15708c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-ecb-des",
15718c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
15728c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
15738c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
15748c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
15758c2ecf20Sopenharmony_ci			.cra_blocksize = DES_BLOCK_SIZE,
15768c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
15778c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
15788c2ecf20Sopenharmony_ci			.cra_init = safexcel_skcipher_des_ecb_cra_init,
15798c2ecf20Sopenharmony_ci			.cra_exit = safexcel_skcipher_cra_exit,
15808c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
15818c2ecf20Sopenharmony_ci		},
15828c2ecf20Sopenharmony_ci	},
15838c2ecf20Sopenharmony_ci};
15848c2ecf20Sopenharmony_ci
15858c2ecf20Sopenharmony_cistatic int safexcel_des3_ede_setkey(struct crypto_skcipher *ctfm,
15868c2ecf20Sopenharmony_ci				   const u8 *key, unsigned int len)
15878c2ecf20Sopenharmony_ci{
15888c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm);
15898c2ecf20Sopenharmony_ci	struct safexcel_crypto_priv *priv = ctx->base.priv;
15908c2ecf20Sopenharmony_ci	int err;
15918c2ecf20Sopenharmony_ci
15928c2ecf20Sopenharmony_ci	err = verify_skcipher_des3_key(ctfm, key);
15938c2ecf20Sopenharmony_ci	if (err)
15948c2ecf20Sopenharmony_ci		return err;
15958c2ecf20Sopenharmony_ci
15968c2ecf20Sopenharmony_ci	/* if context exits and key changed, need to invalidate it */
15978c2ecf20Sopenharmony_ci	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma)
15988c2ecf20Sopenharmony_ci		if (memcmp(ctx->key, key, len))
15998c2ecf20Sopenharmony_ci			ctx->base.needs_inv = true;
16008c2ecf20Sopenharmony_ci
16018c2ecf20Sopenharmony_ci	memcpy(ctx->key, key, len);
16028c2ecf20Sopenharmony_ci	ctx->key_len = len;
16038c2ecf20Sopenharmony_ci
16048c2ecf20Sopenharmony_ci	return 0;
16058c2ecf20Sopenharmony_ci}
16068c2ecf20Sopenharmony_ci
16078c2ecf20Sopenharmony_cistatic int safexcel_skcipher_des3_cbc_cra_init(struct crypto_tfm *tfm)
16088c2ecf20Sopenharmony_ci{
16098c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
16108c2ecf20Sopenharmony_ci
16118c2ecf20Sopenharmony_ci	safexcel_skcipher_cra_init(tfm);
16128c2ecf20Sopenharmony_ci	ctx->alg  = SAFEXCEL_3DES;
16138c2ecf20Sopenharmony_ci	ctx->blocksz = DES3_EDE_BLOCK_SIZE;
16148c2ecf20Sopenharmony_ci	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
16158c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC;
16168c2ecf20Sopenharmony_ci	return 0;
16178c2ecf20Sopenharmony_ci}
16188c2ecf20Sopenharmony_ci
16198c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_cbc_des3_ede = {
16208c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
16218c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_DES,
16228c2ecf20Sopenharmony_ci	.alg.skcipher = {
16238c2ecf20Sopenharmony_ci		.setkey = safexcel_des3_ede_setkey,
16248c2ecf20Sopenharmony_ci		.encrypt = safexcel_encrypt,
16258c2ecf20Sopenharmony_ci		.decrypt = safexcel_decrypt,
16268c2ecf20Sopenharmony_ci		.min_keysize = DES3_EDE_KEY_SIZE,
16278c2ecf20Sopenharmony_ci		.max_keysize = DES3_EDE_KEY_SIZE,
16288c2ecf20Sopenharmony_ci		.ivsize = DES3_EDE_BLOCK_SIZE,
16298c2ecf20Sopenharmony_ci		.base = {
16308c2ecf20Sopenharmony_ci			.cra_name = "cbc(des3_ede)",
16318c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-cbc-des3_ede",
16328c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
16338c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
16348c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
16358c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
16368c2ecf20Sopenharmony_ci			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
16378c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
16388c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
16398c2ecf20Sopenharmony_ci			.cra_init = safexcel_skcipher_des3_cbc_cra_init,
16408c2ecf20Sopenharmony_ci			.cra_exit = safexcel_skcipher_cra_exit,
16418c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
16428c2ecf20Sopenharmony_ci		},
16438c2ecf20Sopenharmony_ci	},
16448c2ecf20Sopenharmony_ci};
16458c2ecf20Sopenharmony_ci
16468c2ecf20Sopenharmony_cistatic int safexcel_skcipher_des3_ecb_cra_init(struct crypto_tfm *tfm)
16478c2ecf20Sopenharmony_ci{
16488c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
16498c2ecf20Sopenharmony_ci
16508c2ecf20Sopenharmony_ci	safexcel_skcipher_cra_init(tfm);
16518c2ecf20Sopenharmony_ci	ctx->alg  = SAFEXCEL_3DES;
16528c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB;
16538c2ecf20Sopenharmony_ci	ctx->blocksz = 0;
16548c2ecf20Sopenharmony_ci	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
16558c2ecf20Sopenharmony_ci	return 0;
16568c2ecf20Sopenharmony_ci}
16578c2ecf20Sopenharmony_ci
16588c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ecb_des3_ede = {
16598c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
16608c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_DES,
16618c2ecf20Sopenharmony_ci	.alg.skcipher = {
16628c2ecf20Sopenharmony_ci		.setkey = safexcel_des3_ede_setkey,
16638c2ecf20Sopenharmony_ci		.encrypt = safexcel_encrypt,
16648c2ecf20Sopenharmony_ci		.decrypt = safexcel_decrypt,
16658c2ecf20Sopenharmony_ci		.min_keysize = DES3_EDE_KEY_SIZE,
16668c2ecf20Sopenharmony_ci		.max_keysize = DES3_EDE_KEY_SIZE,
16678c2ecf20Sopenharmony_ci		.base = {
16688c2ecf20Sopenharmony_ci			.cra_name = "ecb(des3_ede)",
16698c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-ecb-des3_ede",
16708c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
16718c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
16728c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
16738c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
16748c2ecf20Sopenharmony_ci			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
16758c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
16768c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
16778c2ecf20Sopenharmony_ci			.cra_init = safexcel_skcipher_des3_ecb_cra_init,
16788c2ecf20Sopenharmony_ci			.cra_exit = safexcel_skcipher_cra_exit,
16798c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
16808c2ecf20Sopenharmony_ci		},
16818c2ecf20Sopenharmony_ci	},
16828c2ecf20Sopenharmony_ci};
16838c2ecf20Sopenharmony_ci
16848c2ecf20Sopenharmony_cistatic int safexcel_aead_encrypt(struct aead_request *req)
16858c2ecf20Sopenharmony_ci{
16868c2ecf20Sopenharmony_ci	struct safexcel_cipher_req *creq = aead_request_ctx(req);
16878c2ecf20Sopenharmony_ci
16888c2ecf20Sopenharmony_ci	return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT);
16898c2ecf20Sopenharmony_ci}
16908c2ecf20Sopenharmony_ci
16918c2ecf20Sopenharmony_cistatic int safexcel_aead_decrypt(struct aead_request *req)
16928c2ecf20Sopenharmony_ci{
16938c2ecf20Sopenharmony_ci	struct safexcel_cipher_req *creq = aead_request_ctx(req);
16948c2ecf20Sopenharmony_ci
16958c2ecf20Sopenharmony_ci	return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT);
16968c2ecf20Sopenharmony_ci}
16978c2ecf20Sopenharmony_ci
16988c2ecf20Sopenharmony_cistatic int safexcel_aead_cra_init(struct crypto_tfm *tfm)
16998c2ecf20Sopenharmony_ci{
17008c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
17018c2ecf20Sopenharmony_ci	struct safexcel_alg_template *tmpl =
17028c2ecf20Sopenharmony_ci		container_of(tfm->__crt_alg, struct safexcel_alg_template,
17038c2ecf20Sopenharmony_ci			     alg.aead.base);
17048c2ecf20Sopenharmony_ci
17058c2ecf20Sopenharmony_ci	crypto_aead_set_reqsize(__crypto_aead_cast(tfm),
17068c2ecf20Sopenharmony_ci				sizeof(struct safexcel_cipher_req));
17078c2ecf20Sopenharmony_ci
17088c2ecf20Sopenharmony_ci	ctx->base.priv = tmpl->priv;
17098c2ecf20Sopenharmony_ci
17108c2ecf20Sopenharmony_ci	ctx->alg  = SAFEXCEL_AES; /* default */
17118c2ecf20Sopenharmony_ci	ctx->blocksz = AES_BLOCK_SIZE;
17128c2ecf20Sopenharmony_ci	ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD;
17138c2ecf20Sopenharmony_ci	ctx->ctrinit = 1;
17148c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; /* default */
17158c2ecf20Sopenharmony_ci	ctx->aead = true;
17168c2ecf20Sopenharmony_ci	ctx->base.send = safexcel_aead_send;
17178c2ecf20Sopenharmony_ci	ctx->base.handle_result = safexcel_aead_handle_result;
17188c2ecf20Sopenharmony_ci	return 0;
17198c2ecf20Sopenharmony_ci}
17208c2ecf20Sopenharmony_ci
17218c2ecf20Sopenharmony_cistatic int safexcel_aead_sha1_cra_init(struct crypto_tfm *tfm)
17228c2ecf20Sopenharmony_ci{
17238c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
17248c2ecf20Sopenharmony_ci
17258c2ecf20Sopenharmony_ci	safexcel_aead_cra_init(tfm);
17268c2ecf20Sopenharmony_ci	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1;
17278c2ecf20Sopenharmony_ci	ctx->state_sz = SHA1_DIGEST_SIZE;
17288c2ecf20Sopenharmony_ci	return 0;
17298c2ecf20Sopenharmony_ci}
17308c2ecf20Sopenharmony_ci
17318c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_aes = {
17328c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
17338c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA1,
17348c2ecf20Sopenharmony_ci	.alg.aead = {
17358c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
17368c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
17378c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
17388c2ecf20Sopenharmony_ci		.ivsize = AES_BLOCK_SIZE,
17398c2ecf20Sopenharmony_ci		.maxauthsize = SHA1_DIGEST_SIZE,
17408c2ecf20Sopenharmony_ci		.base = {
17418c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha1),cbc(aes))",
17428c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-aes",
17438c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
17448c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
17458c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
17468c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
17478c2ecf20Sopenharmony_ci			.cra_blocksize = AES_BLOCK_SIZE,
17488c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
17498c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
17508c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sha1_cra_init,
17518c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
17528c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
17538c2ecf20Sopenharmony_ci		},
17548c2ecf20Sopenharmony_ci	},
17558c2ecf20Sopenharmony_ci};
17568c2ecf20Sopenharmony_ci
17578c2ecf20Sopenharmony_cistatic int safexcel_aead_sha256_cra_init(struct crypto_tfm *tfm)
17588c2ecf20Sopenharmony_ci{
17598c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
17608c2ecf20Sopenharmony_ci
17618c2ecf20Sopenharmony_ci	safexcel_aead_cra_init(tfm);
17628c2ecf20Sopenharmony_ci	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA256;
17638c2ecf20Sopenharmony_ci	ctx->state_sz = SHA256_DIGEST_SIZE;
17648c2ecf20Sopenharmony_ci	return 0;
17658c2ecf20Sopenharmony_ci}
17668c2ecf20Sopenharmony_ci
17678c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_aes = {
17688c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
17698c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256,
17708c2ecf20Sopenharmony_ci	.alg.aead = {
17718c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
17728c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
17738c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
17748c2ecf20Sopenharmony_ci		.ivsize = AES_BLOCK_SIZE,
17758c2ecf20Sopenharmony_ci		.maxauthsize = SHA256_DIGEST_SIZE,
17768c2ecf20Sopenharmony_ci		.base = {
17778c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha256),cbc(aes))",
17788c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-aes",
17798c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
17808c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
17818c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
17828c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
17838c2ecf20Sopenharmony_ci			.cra_blocksize = AES_BLOCK_SIZE,
17848c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
17858c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
17868c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sha256_cra_init,
17878c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
17888c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
17898c2ecf20Sopenharmony_ci		},
17908c2ecf20Sopenharmony_ci	},
17918c2ecf20Sopenharmony_ci};
17928c2ecf20Sopenharmony_ci
17938c2ecf20Sopenharmony_cistatic int safexcel_aead_sha224_cra_init(struct crypto_tfm *tfm)
17948c2ecf20Sopenharmony_ci{
17958c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
17968c2ecf20Sopenharmony_ci
17978c2ecf20Sopenharmony_ci	safexcel_aead_cra_init(tfm);
17988c2ecf20Sopenharmony_ci	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA224;
17998c2ecf20Sopenharmony_ci	ctx->state_sz = SHA256_DIGEST_SIZE;
18008c2ecf20Sopenharmony_ci	return 0;
18018c2ecf20Sopenharmony_ci}
18028c2ecf20Sopenharmony_ci
18038c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_aes = {
18048c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
18058c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256,
18068c2ecf20Sopenharmony_ci	.alg.aead = {
18078c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
18088c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
18098c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
18108c2ecf20Sopenharmony_ci		.ivsize = AES_BLOCK_SIZE,
18118c2ecf20Sopenharmony_ci		.maxauthsize = SHA224_DIGEST_SIZE,
18128c2ecf20Sopenharmony_ci		.base = {
18138c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha224),cbc(aes))",
18148c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-aes",
18158c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
18168c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
18178c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
18188c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
18198c2ecf20Sopenharmony_ci			.cra_blocksize = AES_BLOCK_SIZE,
18208c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
18218c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
18228c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sha224_cra_init,
18238c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
18248c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
18258c2ecf20Sopenharmony_ci		},
18268c2ecf20Sopenharmony_ci	},
18278c2ecf20Sopenharmony_ci};
18288c2ecf20Sopenharmony_ci
18298c2ecf20Sopenharmony_cistatic int safexcel_aead_sha512_cra_init(struct crypto_tfm *tfm)
18308c2ecf20Sopenharmony_ci{
18318c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
18328c2ecf20Sopenharmony_ci
18338c2ecf20Sopenharmony_ci	safexcel_aead_cra_init(tfm);
18348c2ecf20Sopenharmony_ci	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA512;
18358c2ecf20Sopenharmony_ci	ctx->state_sz = SHA512_DIGEST_SIZE;
18368c2ecf20Sopenharmony_ci	return 0;
18378c2ecf20Sopenharmony_ci}
18388c2ecf20Sopenharmony_ci
18398c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_aes = {
18408c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
18418c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512,
18428c2ecf20Sopenharmony_ci	.alg.aead = {
18438c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
18448c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
18458c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
18468c2ecf20Sopenharmony_ci		.ivsize = AES_BLOCK_SIZE,
18478c2ecf20Sopenharmony_ci		.maxauthsize = SHA512_DIGEST_SIZE,
18488c2ecf20Sopenharmony_ci		.base = {
18498c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha512),cbc(aes))",
18508c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-aes",
18518c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
18528c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
18538c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
18548c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
18558c2ecf20Sopenharmony_ci			.cra_blocksize = AES_BLOCK_SIZE,
18568c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
18578c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
18588c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sha512_cra_init,
18598c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
18608c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
18618c2ecf20Sopenharmony_ci		},
18628c2ecf20Sopenharmony_ci	},
18638c2ecf20Sopenharmony_ci};
18648c2ecf20Sopenharmony_ci
18658c2ecf20Sopenharmony_cistatic int safexcel_aead_sha384_cra_init(struct crypto_tfm *tfm)
18668c2ecf20Sopenharmony_ci{
18678c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
18688c2ecf20Sopenharmony_ci
18698c2ecf20Sopenharmony_ci	safexcel_aead_cra_init(tfm);
18708c2ecf20Sopenharmony_ci	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA384;
18718c2ecf20Sopenharmony_ci	ctx->state_sz = SHA512_DIGEST_SIZE;
18728c2ecf20Sopenharmony_ci	return 0;
18738c2ecf20Sopenharmony_ci}
18748c2ecf20Sopenharmony_ci
18758c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_aes = {
18768c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
18778c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512,
18788c2ecf20Sopenharmony_ci	.alg.aead = {
18798c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
18808c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
18818c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
18828c2ecf20Sopenharmony_ci		.ivsize = AES_BLOCK_SIZE,
18838c2ecf20Sopenharmony_ci		.maxauthsize = SHA384_DIGEST_SIZE,
18848c2ecf20Sopenharmony_ci		.base = {
18858c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha384),cbc(aes))",
18868c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-aes",
18878c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
18888c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
18898c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
18908c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
18918c2ecf20Sopenharmony_ci			.cra_blocksize = AES_BLOCK_SIZE,
18928c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
18938c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
18948c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sha384_cra_init,
18958c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
18968c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
18978c2ecf20Sopenharmony_ci		},
18988c2ecf20Sopenharmony_ci	},
18998c2ecf20Sopenharmony_ci};
19008c2ecf20Sopenharmony_ci
19018c2ecf20Sopenharmony_cistatic int safexcel_aead_sha1_des3_cra_init(struct crypto_tfm *tfm)
19028c2ecf20Sopenharmony_ci{
19038c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
19048c2ecf20Sopenharmony_ci
19058c2ecf20Sopenharmony_ci	safexcel_aead_sha1_cra_init(tfm);
19068c2ecf20Sopenharmony_ci	ctx->alg = SAFEXCEL_3DES; /* override default */
19078c2ecf20Sopenharmony_ci	ctx->blocksz = DES3_EDE_BLOCK_SIZE;
19088c2ecf20Sopenharmony_ci	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
19098c2ecf20Sopenharmony_ci	return 0;
19108c2ecf20Sopenharmony_ci}
19118c2ecf20Sopenharmony_ci
19128c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des3_ede = {
19138c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
19148c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1,
19158c2ecf20Sopenharmony_ci	.alg.aead = {
19168c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
19178c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
19188c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
19198c2ecf20Sopenharmony_ci		.ivsize = DES3_EDE_BLOCK_SIZE,
19208c2ecf20Sopenharmony_ci		.maxauthsize = SHA1_DIGEST_SIZE,
19218c2ecf20Sopenharmony_ci		.base = {
19228c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha1),cbc(des3_ede))",
19238c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des3_ede",
19248c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
19258c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
19268c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
19278c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
19288c2ecf20Sopenharmony_ci			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
19298c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
19308c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
19318c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sha1_des3_cra_init,
19328c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
19338c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
19348c2ecf20Sopenharmony_ci		},
19358c2ecf20Sopenharmony_ci	},
19368c2ecf20Sopenharmony_ci};
19378c2ecf20Sopenharmony_ci
19388c2ecf20Sopenharmony_cistatic int safexcel_aead_sha256_des3_cra_init(struct crypto_tfm *tfm)
19398c2ecf20Sopenharmony_ci{
19408c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
19418c2ecf20Sopenharmony_ci
19428c2ecf20Sopenharmony_ci	safexcel_aead_sha256_cra_init(tfm);
19438c2ecf20Sopenharmony_ci	ctx->alg = SAFEXCEL_3DES; /* override default */
19448c2ecf20Sopenharmony_ci	ctx->blocksz = DES3_EDE_BLOCK_SIZE;
19458c2ecf20Sopenharmony_ci	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
19468c2ecf20Sopenharmony_ci	return 0;
19478c2ecf20Sopenharmony_ci}
19488c2ecf20Sopenharmony_ci
19498c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des3_ede = {
19508c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
19518c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256,
19528c2ecf20Sopenharmony_ci	.alg.aead = {
19538c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
19548c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
19558c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
19568c2ecf20Sopenharmony_ci		.ivsize = DES3_EDE_BLOCK_SIZE,
19578c2ecf20Sopenharmony_ci		.maxauthsize = SHA256_DIGEST_SIZE,
19588c2ecf20Sopenharmony_ci		.base = {
19598c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha256),cbc(des3_ede))",
19608c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des3_ede",
19618c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
19628c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
19638c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
19648c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
19658c2ecf20Sopenharmony_ci			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
19668c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
19678c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
19688c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sha256_des3_cra_init,
19698c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
19708c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
19718c2ecf20Sopenharmony_ci		},
19728c2ecf20Sopenharmony_ci	},
19738c2ecf20Sopenharmony_ci};
19748c2ecf20Sopenharmony_ci
19758c2ecf20Sopenharmony_cistatic int safexcel_aead_sha224_des3_cra_init(struct crypto_tfm *tfm)
19768c2ecf20Sopenharmony_ci{
19778c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
19788c2ecf20Sopenharmony_ci
19798c2ecf20Sopenharmony_ci	safexcel_aead_sha224_cra_init(tfm);
19808c2ecf20Sopenharmony_ci	ctx->alg = SAFEXCEL_3DES; /* override default */
19818c2ecf20Sopenharmony_ci	ctx->blocksz = DES3_EDE_BLOCK_SIZE;
19828c2ecf20Sopenharmony_ci	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
19838c2ecf20Sopenharmony_ci	return 0;
19848c2ecf20Sopenharmony_ci}
19858c2ecf20Sopenharmony_ci
19868c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des3_ede = {
19878c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
19888c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256,
19898c2ecf20Sopenharmony_ci	.alg.aead = {
19908c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
19918c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
19928c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
19938c2ecf20Sopenharmony_ci		.ivsize = DES3_EDE_BLOCK_SIZE,
19948c2ecf20Sopenharmony_ci		.maxauthsize = SHA224_DIGEST_SIZE,
19958c2ecf20Sopenharmony_ci		.base = {
19968c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha224),cbc(des3_ede))",
19978c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des3_ede",
19988c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
19998c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
20008c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
20018c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
20028c2ecf20Sopenharmony_ci			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
20038c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
20048c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
20058c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sha224_des3_cra_init,
20068c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
20078c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
20088c2ecf20Sopenharmony_ci		},
20098c2ecf20Sopenharmony_ci	},
20108c2ecf20Sopenharmony_ci};
20118c2ecf20Sopenharmony_ci
20128c2ecf20Sopenharmony_cistatic int safexcel_aead_sha512_des3_cra_init(struct crypto_tfm *tfm)
20138c2ecf20Sopenharmony_ci{
20148c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
20158c2ecf20Sopenharmony_ci
20168c2ecf20Sopenharmony_ci	safexcel_aead_sha512_cra_init(tfm);
20178c2ecf20Sopenharmony_ci	ctx->alg = SAFEXCEL_3DES; /* override default */
20188c2ecf20Sopenharmony_ci	ctx->blocksz = DES3_EDE_BLOCK_SIZE;
20198c2ecf20Sopenharmony_ci	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
20208c2ecf20Sopenharmony_ci	return 0;
20218c2ecf20Sopenharmony_ci}
20228c2ecf20Sopenharmony_ci
20238c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des3_ede = {
20248c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
20258c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512,
20268c2ecf20Sopenharmony_ci	.alg.aead = {
20278c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
20288c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
20298c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
20308c2ecf20Sopenharmony_ci		.ivsize = DES3_EDE_BLOCK_SIZE,
20318c2ecf20Sopenharmony_ci		.maxauthsize = SHA512_DIGEST_SIZE,
20328c2ecf20Sopenharmony_ci		.base = {
20338c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha512),cbc(des3_ede))",
20348c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des3_ede",
20358c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
20368c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
20378c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
20388c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
20398c2ecf20Sopenharmony_ci			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
20408c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
20418c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
20428c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sha512_des3_cra_init,
20438c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
20448c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
20458c2ecf20Sopenharmony_ci		},
20468c2ecf20Sopenharmony_ci	},
20478c2ecf20Sopenharmony_ci};
20488c2ecf20Sopenharmony_ci
20498c2ecf20Sopenharmony_cistatic int safexcel_aead_sha384_des3_cra_init(struct crypto_tfm *tfm)
20508c2ecf20Sopenharmony_ci{
20518c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
20528c2ecf20Sopenharmony_ci
20538c2ecf20Sopenharmony_ci	safexcel_aead_sha384_cra_init(tfm);
20548c2ecf20Sopenharmony_ci	ctx->alg = SAFEXCEL_3DES; /* override default */
20558c2ecf20Sopenharmony_ci	ctx->blocksz = DES3_EDE_BLOCK_SIZE;
20568c2ecf20Sopenharmony_ci	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
20578c2ecf20Sopenharmony_ci	return 0;
20588c2ecf20Sopenharmony_ci}
20598c2ecf20Sopenharmony_ci
20608c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des3_ede = {
20618c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
20628c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512,
20638c2ecf20Sopenharmony_ci	.alg.aead = {
20648c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
20658c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
20668c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
20678c2ecf20Sopenharmony_ci		.ivsize = DES3_EDE_BLOCK_SIZE,
20688c2ecf20Sopenharmony_ci		.maxauthsize = SHA384_DIGEST_SIZE,
20698c2ecf20Sopenharmony_ci		.base = {
20708c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha384),cbc(des3_ede))",
20718c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des3_ede",
20728c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
20738c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
20748c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
20758c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
20768c2ecf20Sopenharmony_ci			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
20778c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
20788c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
20798c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sha384_des3_cra_init,
20808c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
20818c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
20828c2ecf20Sopenharmony_ci		},
20838c2ecf20Sopenharmony_ci	},
20848c2ecf20Sopenharmony_ci};
20858c2ecf20Sopenharmony_ci
20868c2ecf20Sopenharmony_cistatic int safexcel_aead_sha1_des_cra_init(struct crypto_tfm *tfm)
20878c2ecf20Sopenharmony_ci{
20888c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
20898c2ecf20Sopenharmony_ci
20908c2ecf20Sopenharmony_ci	safexcel_aead_sha1_cra_init(tfm);
20918c2ecf20Sopenharmony_ci	ctx->alg = SAFEXCEL_DES; /* override default */
20928c2ecf20Sopenharmony_ci	ctx->blocksz = DES_BLOCK_SIZE;
20938c2ecf20Sopenharmony_ci	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
20948c2ecf20Sopenharmony_ci	return 0;
20958c2ecf20Sopenharmony_ci}
20968c2ecf20Sopenharmony_ci
20978c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des = {
20988c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
20998c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1,
21008c2ecf20Sopenharmony_ci	.alg.aead = {
21018c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
21028c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
21038c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
21048c2ecf20Sopenharmony_ci		.ivsize = DES_BLOCK_SIZE,
21058c2ecf20Sopenharmony_ci		.maxauthsize = SHA1_DIGEST_SIZE,
21068c2ecf20Sopenharmony_ci		.base = {
21078c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha1),cbc(des))",
21088c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des",
21098c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
21108c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
21118c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
21128c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
21138c2ecf20Sopenharmony_ci			.cra_blocksize = DES_BLOCK_SIZE,
21148c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
21158c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
21168c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sha1_des_cra_init,
21178c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
21188c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
21198c2ecf20Sopenharmony_ci		},
21208c2ecf20Sopenharmony_ci	},
21218c2ecf20Sopenharmony_ci};
21228c2ecf20Sopenharmony_ci
21238c2ecf20Sopenharmony_cistatic int safexcel_aead_sha256_des_cra_init(struct crypto_tfm *tfm)
21248c2ecf20Sopenharmony_ci{
21258c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
21268c2ecf20Sopenharmony_ci
21278c2ecf20Sopenharmony_ci	safexcel_aead_sha256_cra_init(tfm);
21288c2ecf20Sopenharmony_ci	ctx->alg = SAFEXCEL_DES; /* override default */
21298c2ecf20Sopenharmony_ci	ctx->blocksz = DES_BLOCK_SIZE;
21308c2ecf20Sopenharmony_ci	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
21318c2ecf20Sopenharmony_ci	return 0;
21328c2ecf20Sopenharmony_ci}
21338c2ecf20Sopenharmony_ci
21348c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des = {
21358c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
21368c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256,
21378c2ecf20Sopenharmony_ci	.alg.aead = {
21388c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
21398c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
21408c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
21418c2ecf20Sopenharmony_ci		.ivsize = DES_BLOCK_SIZE,
21428c2ecf20Sopenharmony_ci		.maxauthsize = SHA256_DIGEST_SIZE,
21438c2ecf20Sopenharmony_ci		.base = {
21448c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha256),cbc(des))",
21458c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des",
21468c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
21478c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
21488c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
21498c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
21508c2ecf20Sopenharmony_ci			.cra_blocksize = DES_BLOCK_SIZE,
21518c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
21528c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
21538c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sha256_des_cra_init,
21548c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
21558c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
21568c2ecf20Sopenharmony_ci		},
21578c2ecf20Sopenharmony_ci	},
21588c2ecf20Sopenharmony_ci};
21598c2ecf20Sopenharmony_ci
21608c2ecf20Sopenharmony_cistatic int safexcel_aead_sha224_des_cra_init(struct crypto_tfm *tfm)
21618c2ecf20Sopenharmony_ci{
21628c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
21638c2ecf20Sopenharmony_ci
21648c2ecf20Sopenharmony_ci	safexcel_aead_sha224_cra_init(tfm);
21658c2ecf20Sopenharmony_ci	ctx->alg = SAFEXCEL_DES; /* override default */
21668c2ecf20Sopenharmony_ci	ctx->blocksz = DES_BLOCK_SIZE;
21678c2ecf20Sopenharmony_ci	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
21688c2ecf20Sopenharmony_ci	return 0;
21698c2ecf20Sopenharmony_ci}
21708c2ecf20Sopenharmony_ci
21718c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des = {
21728c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
21738c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256,
21748c2ecf20Sopenharmony_ci	.alg.aead = {
21758c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
21768c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
21778c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
21788c2ecf20Sopenharmony_ci		.ivsize = DES_BLOCK_SIZE,
21798c2ecf20Sopenharmony_ci		.maxauthsize = SHA224_DIGEST_SIZE,
21808c2ecf20Sopenharmony_ci		.base = {
21818c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha224),cbc(des))",
21828c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des",
21838c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
21848c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
21858c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
21868c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
21878c2ecf20Sopenharmony_ci			.cra_blocksize = DES_BLOCK_SIZE,
21888c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
21898c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
21908c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sha224_des_cra_init,
21918c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
21928c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
21938c2ecf20Sopenharmony_ci		},
21948c2ecf20Sopenharmony_ci	},
21958c2ecf20Sopenharmony_ci};
21968c2ecf20Sopenharmony_ci
21978c2ecf20Sopenharmony_cistatic int safexcel_aead_sha512_des_cra_init(struct crypto_tfm *tfm)
21988c2ecf20Sopenharmony_ci{
21998c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
22008c2ecf20Sopenharmony_ci
22018c2ecf20Sopenharmony_ci	safexcel_aead_sha512_cra_init(tfm);
22028c2ecf20Sopenharmony_ci	ctx->alg = SAFEXCEL_DES; /* override default */
22038c2ecf20Sopenharmony_ci	ctx->blocksz = DES_BLOCK_SIZE;
22048c2ecf20Sopenharmony_ci	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
22058c2ecf20Sopenharmony_ci	return 0;
22068c2ecf20Sopenharmony_ci}
22078c2ecf20Sopenharmony_ci
22088c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des = {
22098c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
22108c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512,
22118c2ecf20Sopenharmony_ci	.alg.aead = {
22128c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
22138c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
22148c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
22158c2ecf20Sopenharmony_ci		.ivsize = DES_BLOCK_SIZE,
22168c2ecf20Sopenharmony_ci		.maxauthsize = SHA512_DIGEST_SIZE,
22178c2ecf20Sopenharmony_ci		.base = {
22188c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha512),cbc(des))",
22198c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des",
22208c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
22218c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
22228c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
22238c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
22248c2ecf20Sopenharmony_ci			.cra_blocksize = DES_BLOCK_SIZE,
22258c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
22268c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
22278c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sha512_des_cra_init,
22288c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
22298c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
22308c2ecf20Sopenharmony_ci		},
22318c2ecf20Sopenharmony_ci	},
22328c2ecf20Sopenharmony_ci};
22338c2ecf20Sopenharmony_ci
22348c2ecf20Sopenharmony_cistatic int safexcel_aead_sha384_des_cra_init(struct crypto_tfm *tfm)
22358c2ecf20Sopenharmony_ci{
22368c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
22378c2ecf20Sopenharmony_ci
22388c2ecf20Sopenharmony_ci	safexcel_aead_sha384_cra_init(tfm);
22398c2ecf20Sopenharmony_ci	ctx->alg = SAFEXCEL_DES; /* override default */
22408c2ecf20Sopenharmony_ci	ctx->blocksz = DES_BLOCK_SIZE;
22418c2ecf20Sopenharmony_ci	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
22428c2ecf20Sopenharmony_ci	return 0;
22438c2ecf20Sopenharmony_ci}
22448c2ecf20Sopenharmony_ci
22458c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des = {
22468c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
22478c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512,
22488c2ecf20Sopenharmony_ci	.alg.aead = {
22498c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
22508c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
22518c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
22528c2ecf20Sopenharmony_ci		.ivsize = DES_BLOCK_SIZE,
22538c2ecf20Sopenharmony_ci		.maxauthsize = SHA384_DIGEST_SIZE,
22548c2ecf20Sopenharmony_ci		.base = {
22558c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha384),cbc(des))",
22568c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des",
22578c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
22588c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
22598c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
22608c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
22618c2ecf20Sopenharmony_ci			.cra_blocksize = DES_BLOCK_SIZE,
22628c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
22638c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
22648c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sha384_des_cra_init,
22658c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
22668c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
22678c2ecf20Sopenharmony_ci		},
22688c2ecf20Sopenharmony_ci	},
22698c2ecf20Sopenharmony_ci};
22708c2ecf20Sopenharmony_ci
22718c2ecf20Sopenharmony_cistatic int safexcel_aead_sha1_ctr_cra_init(struct crypto_tfm *tfm)
22728c2ecf20Sopenharmony_ci{
22738c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
22748c2ecf20Sopenharmony_ci
22758c2ecf20Sopenharmony_ci	safexcel_aead_sha1_cra_init(tfm);
22768c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */
22778c2ecf20Sopenharmony_ci	return 0;
22788c2ecf20Sopenharmony_ci}
22798c2ecf20Sopenharmony_ci
22808c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_aes = {
22818c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
22828c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA1,
22838c2ecf20Sopenharmony_ci	.alg.aead = {
22848c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
22858c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
22868c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
22878c2ecf20Sopenharmony_ci		.ivsize = CTR_RFC3686_IV_SIZE,
22888c2ecf20Sopenharmony_ci		.maxauthsize = SHA1_DIGEST_SIZE,
22898c2ecf20Sopenharmony_ci		.base = {
22908c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha1),rfc3686(ctr(aes)))",
22918c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-aes",
22928c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
22938c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
22948c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
22958c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
22968c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
22978c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
22988c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
22998c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sha1_ctr_cra_init,
23008c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
23018c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
23028c2ecf20Sopenharmony_ci		},
23038c2ecf20Sopenharmony_ci	},
23048c2ecf20Sopenharmony_ci};
23058c2ecf20Sopenharmony_ci
23068c2ecf20Sopenharmony_cistatic int safexcel_aead_sha256_ctr_cra_init(struct crypto_tfm *tfm)
23078c2ecf20Sopenharmony_ci{
23088c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
23098c2ecf20Sopenharmony_ci
23108c2ecf20Sopenharmony_ci	safexcel_aead_sha256_cra_init(tfm);
23118c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */
23128c2ecf20Sopenharmony_ci	return 0;
23138c2ecf20Sopenharmony_ci}
23148c2ecf20Sopenharmony_ci
23158c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_ctr_aes = {
23168c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
23178c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256,
23188c2ecf20Sopenharmony_ci	.alg.aead = {
23198c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
23208c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
23218c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
23228c2ecf20Sopenharmony_ci		.ivsize = CTR_RFC3686_IV_SIZE,
23238c2ecf20Sopenharmony_ci		.maxauthsize = SHA256_DIGEST_SIZE,
23248c2ecf20Sopenharmony_ci		.base = {
23258c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha256),rfc3686(ctr(aes)))",
23268c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha256-ctr-aes",
23278c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
23288c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
23298c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
23308c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
23318c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
23328c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
23338c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
23348c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sha256_ctr_cra_init,
23358c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
23368c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
23378c2ecf20Sopenharmony_ci		},
23388c2ecf20Sopenharmony_ci	},
23398c2ecf20Sopenharmony_ci};
23408c2ecf20Sopenharmony_ci
23418c2ecf20Sopenharmony_cistatic int safexcel_aead_sha224_ctr_cra_init(struct crypto_tfm *tfm)
23428c2ecf20Sopenharmony_ci{
23438c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
23448c2ecf20Sopenharmony_ci
23458c2ecf20Sopenharmony_ci	safexcel_aead_sha224_cra_init(tfm);
23468c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */
23478c2ecf20Sopenharmony_ci	return 0;
23488c2ecf20Sopenharmony_ci}
23498c2ecf20Sopenharmony_ci
23508c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_ctr_aes = {
23518c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
23528c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256,
23538c2ecf20Sopenharmony_ci	.alg.aead = {
23548c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
23558c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
23568c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
23578c2ecf20Sopenharmony_ci		.ivsize = CTR_RFC3686_IV_SIZE,
23588c2ecf20Sopenharmony_ci		.maxauthsize = SHA224_DIGEST_SIZE,
23598c2ecf20Sopenharmony_ci		.base = {
23608c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha224),rfc3686(ctr(aes)))",
23618c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha224-ctr-aes",
23628c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
23638c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
23648c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
23658c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
23668c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
23678c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
23688c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
23698c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sha224_ctr_cra_init,
23708c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
23718c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
23728c2ecf20Sopenharmony_ci		},
23738c2ecf20Sopenharmony_ci	},
23748c2ecf20Sopenharmony_ci};
23758c2ecf20Sopenharmony_ci
23768c2ecf20Sopenharmony_cistatic int safexcel_aead_sha512_ctr_cra_init(struct crypto_tfm *tfm)
23778c2ecf20Sopenharmony_ci{
23788c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
23798c2ecf20Sopenharmony_ci
23808c2ecf20Sopenharmony_ci	safexcel_aead_sha512_cra_init(tfm);
23818c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */
23828c2ecf20Sopenharmony_ci	return 0;
23838c2ecf20Sopenharmony_ci}
23848c2ecf20Sopenharmony_ci
23858c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_ctr_aes = {
23868c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
23878c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512,
23888c2ecf20Sopenharmony_ci	.alg.aead = {
23898c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
23908c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
23918c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
23928c2ecf20Sopenharmony_ci		.ivsize = CTR_RFC3686_IV_SIZE,
23938c2ecf20Sopenharmony_ci		.maxauthsize = SHA512_DIGEST_SIZE,
23948c2ecf20Sopenharmony_ci		.base = {
23958c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha512),rfc3686(ctr(aes)))",
23968c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha512-ctr-aes",
23978c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
23988c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
23998c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
24008c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
24018c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
24028c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
24038c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
24048c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sha512_ctr_cra_init,
24058c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
24068c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
24078c2ecf20Sopenharmony_ci		},
24088c2ecf20Sopenharmony_ci	},
24098c2ecf20Sopenharmony_ci};
24108c2ecf20Sopenharmony_ci
24118c2ecf20Sopenharmony_cistatic int safexcel_aead_sha384_ctr_cra_init(struct crypto_tfm *tfm)
24128c2ecf20Sopenharmony_ci{
24138c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
24148c2ecf20Sopenharmony_ci
24158c2ecf20Sopenharmony_ci	safexcel_aead_sha384_cra_init(tfm);
24168c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */
24178c2ecf20Sopenharmony_ci	return 0;
24188c2ecf20Sopenharmony_ci}
24198c2ecf20Sopenharmony_ci
24208c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_ctr_aes = {
24218c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
24228c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512,
24238c2ecf20Sopenharmony_ci	.alg.aead = {
24248c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
24258c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
24268c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
24278c2ecf20Sopenharmony_ci		.ivsize = CTR_RFC3686_IV_SIZE,
24288c2ecf20Sopenharmony_ci		.maxauthsize = SHA384_DIGEST_SIZE,
24298c2ecf20Sopenharmony_ci		.base = {
24308c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha384),rfc3686(ctr(aes)))",
24318c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha384-ctr-aes",
24328c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
24338c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
24348c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
24358c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
24368c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
24378c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
24388c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
24398c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sha384_ctr_cra_init,
24408c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
24418c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
24428c2ecf20Sopenharmony_ci		},
24438c2ecf20Sopenharmony_ci	},
24448c2ecf20Sopenharmony_ci};
24458c2ecf20Sopenharmony_ci
24468c2ecf20Sopenharmony_cistatic int safexcel_skcipher_aesxts_setkey(struct crypto_skcipher *ctfm,
24478c2ecf20Sopenharmony_ci					   const u8 *key, unsigned int len)
24488c2ecf20Sopenharmony_ci{
24498c2ecf20Sopenharmony_ci	struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);
24508c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
24518c2ecf20Sopenharmony_ci	struct safexcel_crypto_priv *priv = ctx->base.priv;
24528c2ecf20Sopenharmony_ci	struct crypto_aes_ctx aes;
24538c2ecf20Sopenharmony_ci	int ret, i;
24548c2ecf20Sopenharmony_ci	unsigned int keylen;
24558c2ecf20Sopenharmony_ci
24568c2ecf20Sopenharmony_ci	/* Check for illegal XTS keys */
24578c2ecf20Sopenharmony_ci	ret = xts_verify_key(ctfm, key, len);
24588c2ecf20Sopenharmony_ci	if (ret)
24598c2ecf20Sopenharmony_ci		return ret;
24608c2ecf20Sopenharmony_ci
24618c2ecf20Sopenharmony_ci	/* Only half of the key data is cipher key */
24628c2ecf20Sopenharmony_ci	keylen = (len >> 1);
24638c2ecf20Sopenharmony_ci	ret = aes_expandkey(&aes, key, keylen);
24648c2ecf20Sopenharmony_ci	if (ret)
24658c2ecf20Sopenharmony_ci		return ret;
24668c2ecf20Sopenharmony_ci
24678c2ecf20Sopenharmony_ci	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
24688c2ecf20Sopenharmony_ci		for (i = 0; i < keylen / sizeof(u32); i++) {
24698c2ecf20Sopenharmony_ci			if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {
24708c2ecf20Sopenharmony_ci				ctx->base.needs_inv = true;
24718c2ecf20Sopenharmony_ci				break;
24728c2ecf20Sopenharmony_ci			}
24738c2ecf20Sopenharmony_ci		}
24748c2ecf20Sopenharmony_ci	}
24758c2ecf20Sopenharmony_ci
24768c2ecf20Sopenharmony_ci	for (i = 0; i < keylen / sizeof(u32); i++)
24778c2ecf20Sopenharmony_ci		ctx->key[i] = cpu_to_le32(aes.key_enc[i]);
24788c2ecf20Sopenharmony_ci
24798c2ecf20Sopenharmony_ci	/* The other half is the tweak key */
24808c2ecf20Sopenharmony_ci	ret = aes_expandkey(&aes, (u8 *)(key + keylen), keylen);
24818c2ecf20Sopenharmony_ci	if (ret)
24828c2ecf20Sopenharmony_ci		return ret;
24838c2ecf20Sopenharmony_ci
24848c2ecf20Sopenharmony_ci	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
24858c2ecf20Sopenharmony_ci		for (i = 0; i < keylen / sizeof(u32); i++) {
24868c2ecf20Sopenharmony_ci			if (le32_to_cpu(ctx->key[i + keylen / sizeof(u32)]) !=
24878c2ecf20Sopenharmony_ci			    aes.key_enc[i]) {
24888c2ecf20Sopenharmony_ci				ctx->base.needs_inv = true;
24898c2ecf20Sopenharmony_ci				break;
24908c2ecf20Sopenharmony_ci			}
24918c2ecf20Sopenharmony_ci		}
24928c2ecf20Sopenharmony_ci	}
24938c2ecf20Sopenharmony_ci
24948c2ecf20Sopenharmony_ci	for (i = 0; i < keylen / sizeof(u32); i++)
24958c2ecf20Sopenharmony_ci		ctx->key[i + keylen / sizeof(u32)] =
24968c2ecf20Sopenharmony_ci			cpu_to_le32(aes.key_enc[i]);
24978c2ecf20Sopenharmony_ci
24988c2ecf20Sopenharmony_ci	ctx->key_len = keylen << 1;
24998c2ecf20Sopenharmony_ci
25008c2ecf20Sopenharmony_ci	memzero_explicit(&aes, sizeof(aes));
25018c2ecf20Sopenharmony_ci	return 0;
25028c2ecf20Sopenharmony_ci}
25038c2ecf20Sopenharmony_ci
25048c2ecf20Sopenharmony_cistatic int safexcel_skcipher_aes_xts_cra_init(struct crypto_tfm *tfm)
25058c2ecf20Sopenharmony_ci{
25068c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
25078c2ecf20Sopenharmony_ci
25088c2ecf20Sopenharmony_ci	safexcel_skcipher_cra_init(tfm);
25098c2ecf20Sopenharmony_ci	ctx->alg  = SAFEXCEL_AES;
25108c2ecf20Sopenharmony_ci	ctx->blocksz = AES_BLOCK_SIZE;
25118c2ecf20Sopenharmony_ci	ctx->xts  = 1;
25128c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XTS;
25138c2ecf20Sopenharmony_ci	return 0;
25148c2ecf20Sopenharmony_ci}
25158c2ecf20Sopenharmony_ci
25168c2ecf20Sopenharmony_cistatic int safexcel_encrypt_xts(struct skcipher_request *req)
25178c2ecf20Sopenharmony_ci{
25188c2ecf20Sopenharmony_ci	if (req->cryptlen < XTS_BLOCK_SIZE)
25198c2ecf20Sopenharmony_ci		return -EINVAL;
25208c2ecf20Sopenharmony_ci	return safexcel_queue_req(&req->base, skcipher_request_ctx(req),
25218c2ecf20Sopenharmony_ci				  SAFEXCEL_ENCRYPT);
25228c2ecf20Sopenharmony_ci}
25238c2ecf20Sopenharmony_ci
25248c2ecf20Sopenharmony_cistatic int safexcel_decrypt_xts(struct skcipher_request *req)
25258c2ecf20Sopenharmony_ci{
25268c2ecf20Sopenharmony_ci	if (req->cryptlen < XTS_BLOCK_SIZE)
25278c2ecf20Sopenharmony_ci		return -EINVAL;
25288c2ecf20Sopenharmony_ci	return safexcel_queue_req(&req->base, skcipher_request_ctx(req),
25298c2ecf20Sopenharmony_ci				  SAFEXCEL_DECRYPT);
25308c2ecf20Sopenharmony_ci}
25318c2ecf20Sopenharmony_ci
25328c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_xts_aes = {
25338c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
25348c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XTS,
25358c2ecf20Sopenharmony_ci	.alg.skcipher = {
25368c2ecf20Sopenharmony_ci		.setkey = safexcel_skcipher_aesxts_setkey,
25378c2ecf20Sopenharmony_ci		.encrypt = safexcel_encrypt_xts,
25388c2ecf20Sopenharmony_ci		.decrypt = safexcel_decrypt_xts,
25398c2ecf20Sopenharmony_ci		/* XTS actually uses 2 AES keys glued together */
25408c2ecf20Sopenharmony_ci		.min_keysize = AES_MIN_KEY_SIZE * 2,
25418c2ecf20Sopenharmony_ci		.max_keysize = AES_MAX_KEY_SIZE * 2,
25428c2ecf20Sopenharmony_ci		.ivsize = XTS_BLOCK_SIZE,
25438c2ecf20Sopenharmony_ci		.base = {
25448c2ecf20Sopenharmony_ci			.cra_name = "xts(aes)",
25458c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-xts-aes",
25468c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
25478c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
25488c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
25498c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
25508c2ecf20Sopenharmony_ci			.cra_blocksize = XTS_BLOCK_SIZE,
25518c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
25528c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
25538c2ecf20Sopenharmony_ci			.cra_init = safexcel_skcipher_aes_xts_cra_init,
25548c2ecf20Sopenharmony_ci			.cra_exit = safexcel_skcipher_cra_exit,
25558c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
25568c2ecf20Sopenharmony_ci		},
25578c2ecf20Sopenharmony_ci	},
25588c2ecf20Sopenharmony_ci};
25598c2ecf20Sopenharmony_ci
25608c2ecf20Sopenharmony_cistatic int safexcel_aead_gcm_setkey(struct crypto_aead *ctfm, const u8 *key,
25618c2ecf20Sopenharmony_ci				    unsigned int len)
25628c2ecf20Sopenharmony_ci{
25638c2ecf20Sopenharmony_ci	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);
25648c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
25658c2ecf20Sopenharmony_ci	struct safexcel_crypto_priv *priv = ctx->base.priv;
25668c2ecf20Sopenharmony_ci	struct crypto_aes_ctx aes;
25678c2ecf20Sopenharmony_ci	u32 hashkey[AES_BLOCK_SIZE >> 2];
25688c2ecf20Sopenharmony_ci	int ret, i;
25698c2ecf20Sopenharmony_ci
25708c2ecf20Sopenharmony_ci	ret = aes_expandkey(&aes, key, len);
25718c2ecf20Sopenharmony_ci	if (ret) {
25728c2ecf20Sopenharmony_ci		memzero_explicit(&aes, sizeof(aes));
25738c2ecf20Sopenharmony_ci		return ret;
25748c2ecf20Sopenharmony_ci	}
25758c2ecf20Sopenharmony_ci
25768c2ecf20Sopenharmony_ci	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
25778c2ecf20Sopenharmony_ci		for (i = 0; i < len / sizeof(u32); i++) {
25788c2ecf20Sopenharmony_ci			if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {
25798c2ecf20Sopenharmony_ci				ctx->base.needs_inv = true;
25808c2ecf20Sopenharmony_ci				break;
25818c2ecf20Sopenharmony_ci			}
25828c2ecf20Sopenharmony_ci		}
25838c2ecf20Sopenharmony_ci	}
25848c2ecf20Sopenharmony_ci
25858c2ecf20Sopenharmony_ci	for (i = 0; i < len / sizeof(u32); i++)
25868c2ecf20Sopenharmony_ci		ctx->key[i] = cpu_to_le32(aes.key_enc[i]);
25878c2ecf20Sopenharmony_ci
25888c2ecf20Sopenharmony_ci	ctx->key_len = len;
25898c2ecf20Sopenharmony_ci
25908c2ecf20Sopenharmony_ci	/* Compute hash key by encrypting zeroes with cipher key */
25918c2ecf20Sopenharmony_ci	crypto_cipher_clear_flags(ctx->hkaes, CRYPTO_TFM_REQ_MASK);
25928c2ecf20Sopenharmony_ci	crypto_cipher_set_flags(ctx->hkaes, crypto_aead_get_flags(ctfm) &
25938c2ecf20Sopenharmony_ci				CRYPTO_TFM_REQ_MASK);
25948c2ecf20Sopenharmony_ci	ret = crypto_cipher_setkey(ctx->hkaes, key, len);
25958c2ecf20Sopenharmony_ci	if (ret)
25968c2ecf20Sopenharmony_ci		return ret;
25978c2ecf20Sopenharmony_ci
25988c2ecf20Sopenharmony_ci	memset(hashkey, 0, AES_BLOCK_SIZE);
25998c2ecf20Sopenharmony_ci	crypto_cipher_encrypt_one(ctx->hkaes, (u8 *)hashkey, (u8 *)hashkey);
26008c2ecf20Sopenharmony_ci
26018c2ecf20Sopenharmony_ci	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
26028c2ecf20Sopenharmony_ci		for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) {
26038c2ecf20Sopenharmony_ci			if (be32_to_cpu(ctx->base.ipad.be[i]) != hashkey[i]) {
26048c2ecf20Sopenharmony_ci				ctx->base.needs_inv = true;
26058c2ecf20Sopenharmony_ci				break;
26068c2ecf20Sopenharmony_ci			}
26078c2ecf20Sopenharmony_ci		}
26088c2ecf20Sopenharmony_ci	}
26098c2ecf20Sopenharmony_ci
26108c2ecf20Sopenharmony_ci	for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++)
26118c2ecf20Sopenharmony_ci		ctx->base.ipad.be[i] = cpu_to_be32(hashkey[i]);
26128c2ecf20Sopenharmony_ci
26138c2ecf20Sopenharmony_ci	memzero_explicit(hashkey, AES_BLOCK_SIZE);
26148c2ecf20Sopenharmony_ci	memzero_explicit(&aes, sizeof(aes));
26158c2ecf20Sopenharmony_ci	return 0;
26168c2ecf20Sopenharmony_ci}
26178c2ecf20Sopenharmony_ci
26188c2ecf20Sopenharmony_cistatic int safexcel_aead_gcm_cra_init(struct crypto_tfm *tfm)
26198c2ecf20Sopenharmony_ci{
26208c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
26218c2ecf20Sopenharmony_ci
26228c2ecf20Sopenharmony_ci	safexcel_aead_cra_init(tfm);
26238c2ecf20Sopenharmony_ci	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_GHASH;
26248c2ecf20Sopenharmony_ci	ctx->state_sz = GHASH_BLOCK_SIZE;
26258c2ecf20Sopenharmony_ci	ctx->xcm = EIP197_XCM_MODE_GCM;
26268c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */
26278c2ecf20Sopenharmony_ci
26288c2ecf20Sopenharmony_ci	ctx->hkaes = crypto_alloc_cipher("aes", 0, 0);
26298c2ecf20Sopenharmony_ci	return PTR_ERR_OR_ZERO(ctx->hkaes);
26308c2ecf20Sopenharmony_ci}
26318c2ecf20Sopenharmony_ci
26328c2ecf20Sopenharmony_cistatic void safexcel_aead_gcm_cra_exit(struct crypto_tfm *tfm)
26338c2ecf20Sopenharmony_ci{
26348c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
26358c2ecf20Sopenharmony_ci
26368c2ecf20Sopenharmony_ci	crypto_free_cipher(ctx->hkaes);
26378c2ecf20Sopenharmony_ci	safexcel_aead_cra_exit(tfm);
26388c2ecf20Sopenharmony_ci}
26398c2ecf20Sopenharmony_ci
26408c2ecf20Sopenharmony_cistatic int safexcel_aead_gcm_setauthsize(struct crypto_aead *tfm,
26418c2ecf20Sopenharmony_ci					 unsigned int authsize)
26428c2ecf20Sopenharmony_ci{
26438c2ecf20Sopenharmony_ci	return crypto_gcm_check_authsize(authsize);
26448c2ecf20Sopenharmony_ci}
26458c2ecf20Sopenharmony_ci
26468c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_gcm = {
26478c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
26488c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH,
26498c2ecf20Sopenharmony_ci	.alg.aead = {
26508c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_gcm_setkey,
26518c2ecf20Sopenharmony_ci		.setauthsize = safexcel_aead_gcm_setauthsize,
26528c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
26538c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
26548c2ecf20Sopenharmony_ci		.ivsize = GCM_AES_IV_SIZE,
26558c2ecf20Sopenharmony_ci		.maxauthsize = GHASH_DIGEST_SIZE,
26568c2ecf20Sopenharmony_ci		.base = {
26578c2ecf20Sopenharmony_ci			.cra_name = "gcm(aes)",
26588c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-gcm-aes",
26598c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
26608c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
26618c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
26628c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
26638c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
26648c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
26658c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
26668c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_gcm_cra_init,
26678c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_gcm_cra_exit,
26688c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
26698c2ecf20Sopenharmony_ci		},
26708c2ecf20Sopenharmony_ci	},
26718c2ecf20Sopenharmony_ci};
26728c2ecf20Sopenharmony_ci
26738c2ecf20Sopenharmony_cistatic int safexcel_aead_ccm_setkey(struct crypto_aead *ctfm, const u8 *key,
26748c2ecf20Sopenharmony_ci				    unsigned int len)
26758c2ecf20Sopenharmony_ci{
26768c2ecf20Sopenharmony_ci	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);
26778c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
26788c2ecf20Sopenharmony_ci	struct safexcel_crypto_priv *priv = ctx->base.priv;
26798c2ecf20Sopenharmony_ci	struct crypto_aes_ctx aes;
26808c2ecf20Sopenharmony_ci	int ret, i;
26818c2ecf20Sopenharmony_ci
26828c2ecf20Sopenharmony_ci	ret = aes_expandkey(&aes, key, len);
26838c2ecf20Sopenharmony_ci	if (ret) {
26848c2ecf20Sopenharmony_ci		memzero_explicit(&aes, sizeof(aes));
26858c2ecf20Sopenharmony_ci		return ret;
26868c2ecf20Sopenharmony_ci	}
26878c2ecf20Sopenharmony_ci
26888c2ecf20Sopenharmony_ci	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
26898c2ecf20Sopenharmony_ci		for (i = 0; i < len / sizeof(u32); i++) {
26908c2ecf20Sopenharmony_ci			if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {
26918c2ecf20Sopenharmony_ci				ctx->base.needs_inv = true;
26928c2ecf20Sopenharmony_ci				break;
26938c2ecf20Sopenharmony_ci			}
26948c2ecf20Sopenharmony_ci		}
26958c2ecf20Sopenharmony_ci	}
26968c2ecf20Sopenharmony_ci
26978c2ecf20Sopenharmony_ci	for (i = 0; i < len / sizeof(u32); i++) {
26988c2ecf20Sopenharmony_ci		ctx->key[i] = cpu_to_le32(aes.key_enc[i]);
26998c2ecf20Sopenharmony_ci		ctx->base.ipad.be[i + 2 * AES_BLOCK_SIZE / sizeof(u32)] =
27008c2ecf20Sopenharmony_ci			cpu_to_be32(aes.key_enc[i]);
27018c2ecf20Sopenharmony_ci	}
27028c2ecf20Sopenharmony_ci
27038c2ecf20Sopenharmony_ci	ctx->key_len = len;
27048c2ecf20Sopenharmony_ci	ctx->state_sz = 2 * AES_BLOCK_SIZE + len;
27058c2ecf20Sopenharmony_ci
27068c2ecf20Sopenharmony_ci	if (len == AES_KEYSIZE_192)
27078c2ecf20Sopenharmony_ci		ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC192;
27088c2ecf20Sopenharmony_ci	else if (len == AES_KEYSIZE_256)
27098c2ecf20Sopenharmony_ci		ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC256;
27108c2ecf20Sopenharmony_ci	else
27118c2ecf20Sopenharmony_ci		ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128;
27128c2ecf20Sopenharmony_ci
27138c2ecf20Sopenharmony_ci	memzero_explicit(&aes, sizeof(aes));
27148c2ecf20Sopenharmony_ci	return 0;
27158c2ecf20Sopenharmony_ci}
27168c2ecf20Sopenharmony_ci
27178c2ecf20Sopenharmony_cistatic int safexcel_aead_ccm_cra_init(struct crypto_tfm *tfm)
27188c2ecf20Sopenharmony_ci{
27198c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
27208c2ecf20Sopenharmony_ci
27218c2ecf20Sopenharmony_ci	safexcel_aead_cra_init(tfm);
27228c2ecf20Sopenharmony_ci	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128;
27238c2ecf20Sopenharmony_ci	ctx->state_sz = 3 * AES_BLOCK_SIZE;
27248c2ecf20Sopenharmony_ci	ctx->xcm = EIP197_XCM_MODE_CCM;
27258c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */
27268c2ecf20Sopenharmony_ci	ctx->ctrinit = 0;
27278c2ecf20Sopenharmony_ci	return 0;
27288c2ecf20Sopenharmony_ci}
27298c2ecf20Sopenharmony_ci
27308c2ecf20Sopenharmony_cistatic int safexcel_aead_ccm_setauthsize(struct crypto_aead *tfm,
27318c2ecf20Sopenharmony_ci					 unsigned int authsize)
27328c2ecf20Sopenharmony_ci{
27338c2ecf20Sopenharmony_ci	/* Borrowed from crypto/ccm.c */
27348c2ecf20Sopenharmony_ci	switch (authsize) {
27358c2ecf20Sopenharmony_ci	case 4:
27368c2ecf20Sopenharmony_ci	case 6:
27378c2ecf20Sopenharmony_ci	case 8:
27388c2ecf20Sopenharmony_ci	case 10:
27398c2ecf20Sopenharmony_ci	case 12:
27408c2ecf20Sopenharmony_ci	case 14:
27418c2ecf20Sopenharmony_ci	case 16:
27428c2ecf20Sopenharmony_ci		break;
27438c2ecf20Sopenharmony_ci	default:
27448c2ecf20Sopenharmony_ci		return -EINVAL;
27458c2ecf20Sopenharmony_ci	}
27468c2ecf20Sopenharmony_ci
27478c2ecf20Sopenharmony_ci	return 0;
27488c2ecf20Sopenharmony_ci}
27498c2ecf20Sopenharmony_ci
27508c2ecf20Sopenharmony_cistatic int safexcel_ccm_encrypt(struct aead_request *req)
27518c2ecf20Sopenharmony_ci{
27528c2ecf20Sopenharmony_ci	struct safexcel_cipher_req *creq = aead_request_ctx(req);
27538c2ecf20Sopenharmony_ci
27548c2ecf20Sopenharmony_ci	if (req->iv[0] < 1 || req->iv[0] > 7)
27558c2ecf20Sopenharmony_ci		return -EINVAL;
27568c2ecf20Sopenharmony_ci
27578c2ecf20Sopenharmony_ci	return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT);
27588c2ecf20Sopenharmony_ci}
27598c2ecf20Sopenharmony_ci
27608c2ecf20Sopenharmony_cistatic int safexcel_ccm_decrypt(struct aead_request *req)
27618c2ecf20Sopenharmony_ci{
27628c2ecf20Sopenharmony_ci	struct safexcel_cipher_req *creq = aead_request_ctx(req);
27638c2ecf20Sopenharmony_ci
27648c2ecf20Sopenharmony_ci	if (req->iv[0] < 1 || req->iv[0] > 7)
27658c2ecf20Sopenharmony_ci		return -EINVAL;
27668c2ecf20Sopenharmony_ci
27678c2ecf20Sopenharmony_ci	return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT);
27688c2ecf20Sopenharmony_ci}
27698c2ecf20Sopenharmony_ci
27708c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ccm = {
27718c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
27728c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL,
27738c2ecf20Sopenharmony_ci	.alg.aead = {
27748c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_ccm_setkey,
27758c2ecf20Sopenharmony_ci		.setauthsize = safexcel_aead_ccm_setauthsize,
27768c2ecf20Sopenharmony_ci		.encrypt = safexcel_ccm_encrypt,
27778c2ecf20Sopenharmony_ci		.decrypt = safexcel_ccm_decrypt,
27788c2ecf20Sopenharmony_ci		.ivsize = AES_BLOCK_SIZE,
27798c2ecf20Sopenharmony_ci		.maxauthsize = AES_BLOCK_SIZE,
27808c2ecf20Sopenharmony_ci		.base = {
27818c2ecf20Sopenharmony_ci			.cra_name = "ccm(aes)",
27828c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-ccm-aes",
27838c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
27848c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
27858c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
27868c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
27878c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
27888c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
27898c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
27908c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_ccm_cra_init,
27918c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
27928c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
27938c2ecf20Sopenharmony_ci		},
27948c2ecf20Sopenharmony_ci	},
27958c2ecf20Sopenharmony_ci};
27968c2ecf20Sopenharmony_ci
27978c2ecf20Sopenharmony_cistatic void safexcel_chacha20_setkey(struct safexcel_cipher_ctx *ctx,
27988c2ecf20Sopenharmony_ci				     const u8 *key)
27998c2ecf20Sopenharmony_ci{
28008c2ecf20Sopenharmony_ci	struct safexcel_crypto_priv *priv = ctx->base.priv;
28018c2ecf20Sopenharmony_ci
28028c2ecf20Sopenharmony_ci	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma)
28038c2ecf20Sopenharmony_ci		if (memcmp(ctx->key, key, CHACHA_KEY_SIZE))
28048c2ecf20Sopenharmony_ci			ctx->base.needs_inv = true;
28058c2ecf20Sopenharmony_ci
28068c2ecf20Sopenharmony_ci	memcpy(ctx->key, key, CHACHA_KEY_SIZE);
28078c2ecf20Sopenharmony_ci	ctx->key_len = CHACHA_KEY_SIZE;
28088c2ecf20Sopenharmony_ci}
28098c2ecf20Sopenharmony_ci
28108c2ecf20Sopenharmony_cistatic int safexcel_skcipher_chacha20_setkey(struct crypto_skcipher *ctfm,
28118c2ecf20Sopenharmony_ci					     const u8 *key, unsigned int len)
28128c2ecf20Sopenharmony_ci{
28138c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm);
28148c2ecf20Sopenharmony_ci
28158c2ecf20Sopenharmony_ci	if (len != CHACHA_KEY_SIZE)
28168c2ecf20Sopenharmony_ci		return -EINVAL;
28178c2ecf20Sopenharmony_ci
28188c2ecf20Sopenharmony_ci	safexcel_chacha20_setkey(ctx, key);
28198c2ecf20Sopenharmony_ci
28208c2ecf20Sopenharmony_ci	return 0;
28218c2ecf20Sopenharmony_ci}
28228c2ecf20Sopenharmony_ci
28238c2ecf20Sopenharmony_cistatic int safexcel_skcipher_chacha20_cra_init(struct crypto_tfm *tfm)
28248c2ecf20Sopenharmony_ci{
28258c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
28268c2ecf20Sopenharmony_ci
28278c2ecf20Sopenharmony_ci	safexcel_skcipher_cra_init(tfm);
28288c2ecf20Sopenharmony_ci	ctx->alg  = SAFEXCEL_CHACHA20;
28298c2ecf20Sopenharmony_ci	ctx->ctrinit = 0;
28308c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32;
28318c2ecf20Sopenharmony_ci	return 0;
28328c2ecf20Sopenharmony_ci}
28338c2ecf20Sopenharmony_ci
28348c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_chacha20 = {
28358c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
28368c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_CHACHA20,
28378c2ecf20Sopenharmony_ci	.alg.skcipher = {
28388c2ecf20Sopenharmony_ci		.setkey = safexcel_skcipher_chacha20_setkey,
28398c2ecf20Sopenharmony_ci		.encrypt = safexcel_encrypt,
28408c2ecf20Sopenharmony_ci		.decrypt = safexcel_decrypt,
28418c2ecf20Sopenharmony_ci		.min_keysize = CHACHA_KEY_SIZE,
28428c2ecf20Sopenharmony_ci		.max_keysize = CHACHA_KEY_SIZE,
28438c2ecf20Sopenharmony_ci		.ivsize = CHACHA_IV_SIZE,
28448c2ecf20Sopenharmony_ci		.base = {
28458c2ecf20Sopenharmony_ci			.cra_name = "chacha20",
28468c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-chacha20",
28478c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
28488c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
28498c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
28508c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
28518c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
28528c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
28538c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
28548c2ecf20Sopenharmony_ci			.cra_init = safexcel_skcipher_chacha20_cra_init,
28558c2ecf20Sopenharmony_ci			.cra_exit = safexcel_skcipher_cra_exit,
28568c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
28578c2ecf20Sopenharmony_ci		},
28588c2ecf20Sopenharmony_ci	},
28598c2ecf20Sopenharmony_ci};
28608c2ecf20Sopenharmony_ci
28618c2ecf20Sopenharmony_cistatic int safexcel_aead_chachapoly_setkey(struct crypto_aead *ctfm,
28628c2ecf20Sopenharmony_ci				    const u8 *key, unsigned int len)
28638c2ecf20Sopenharmony_ci{
28648c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_aead_ctx(ctfm);
28658c2ecf20Sopenharmony_ci
28668c2ecf20Sopenharmony_ci	if (ctx->aead  == EIP197_AEAD_TYPE_IPSEC_ESP &&
28678c2ecf20Sopenharmony_ci	    len > EIP197_AEAD_IPSEC_NONCE_SIZE) {
28688c2ecf20Sopenharmony_ci		/* ESP variant has nonce appended to key */
28698c2ecf20Sopenharmony_ci		len -= EIP197_AEAD_IPSEC_NONCE_SIZE;
28708c2ecf20Sopenharmony_ci		ctx->nonce = *(u32 *)(key + len);
28718c2ecf20Sopenharmony_ci	}
28728c2ecf20Sopenharmony_ci	if (len != CHACHA_KEY_SIZE)
28738c2ecf20Sopenharmony_ci		return -EINVAL;
28748c2ecf20Sopenharmony_ci
28758c2ecf20Sopenharmony_ci	safexcel_chacha20_setkey(ctx, key);
28768c2ecf20Sopenharmony_ci
28778c2ecf20Sopenharmony_ci	return 0;
28788c2ecf20Sopenharmony_ci}
28798c2ecf20Sopenharmony_ci
28808c2ecf20Sopenharmony_cistatic int safexcel_aead_chachapoly_setauthsize(struct crypto_aead *tfm,
28818c2ecf20Sopenharmony_ci					 unsigned int authsize)
28828c2ecf20Sopenharmony_ci{
28838c2ecf20Sopenharmony_ci	if (authsize != POLY1305_DIGEST_SIZE)
28848c2ecf20Sopenharmony_ci		return -EINVAL;
28858c2ecf20Sopenharmony_ci	return 0;
28868c2ecf20Sopenharmony_ci}
28878c2ecf20Sopenharmony_ci
28888c2ecf20Sopenharmony_cistatic int safexcel_aead_chachapoly_crypt(struct aead_request *req,
28898c2ecf20Sopenharmony_ci					  enum safexcel_cipher_direction dir)
28908c2ecf20Sopenharmony_ci{
28918c2ecf20Sopenharmony_ci	struct safexcel_cipher_req *creq = aead_request_ctx(req);
28928c2ecf20Sopenharmony_ci	struct crypto_aead *aead = crypto_aead_reqtfm(req);
28938c2ecf20Sopenharmony_ci	struct crypto_tfm *tfm = crypto_aead_tfm(aead);
28948c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
28958c2ecf20Sopenharmony_ci	struct aead_request *subreq = aead_request_ctx(req);
28968c2ecf20Sopenharmony_ci	u32 key[CHACHA_KEY_SIZE / sizeof(u32) + 1];
28978c2ecf20Sopenharmony_ci	int ret = 0;
28988c2ecf20Sopenharmony_ci
28998c2ecf20Sopenharmony_ci	/*
29008c2ecf20Sopenharmony_ci	 * Instead of wasting time detecting umpteen silly corner cases,
29018c2ecf20Sopenharmony_ci	 * just dump all "small" requests to the fallback implementation.
29028c2ecf20Sopenharmony_ci	 * HW would not be faster on such small requests anyway.
29038c2ecf20Sopenharmony_ci	 */
29048c2ecf20Sopenharmony_ci	if (likely((ctx->aead != EIP197_AEAD_TYPE_IPSEC_ESP ||
29058c2ecf20Sopenharmony_ci		    req->assoclen >= EIP197_AEAD_IPSEC_IV_SIZE) &&
29068c2ecf20Sopenharmony_ci		   req->cryptlen > POLY1305_DIGEST_SIZE)) {
29078c2ecf20Sopenharmony_ci		return safexcel_queue_req(&req->base, creq, dir);
29088c2ecf20Sopenharmony_ci	}
29098c2ecf20Sopenharmony_ci
29108c2ecf20Sopenharmony_ci	/* HW cannot do full (AAD+payload) zero length, use fallback */
29118c2ecf20Sopenharmony_ci	memcpy(key, ctx->key, CHACHA_KEY_SIZE);
29128c2ecf20Sopenharmony_ci	if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) {
29138c2ecf20Sopenharmony_ci		/* ESP variant has nonce appended to the key */
29148c2ecf20Sopenharmony_ci		key[CHACHA_KEY_SIZE / sizeof(u32)] = ctx->nonce;
29158c2ecf20Sopenharmony_ci		ret = crypto_aead_setkey(ctx->fback, (u8 *)key,
29168c2ecf20Sopenharmony_ci					 CHACHA_KEY_SIZE +
29178c2ecf20Sopenharmony_ci					 EIP197_AEAD_IPSEC_NONCE_SIZE);
29188c2ecf20Sopenharmony_ci	} else {
29198c2ecf20Sopenharmony_ci		ret = crypto_aead_setkey(ctx->fback, (u8 *)key,
29208c2ecf20Sopenharmony_ci					 CHACHA_KEY_SIZE);
29218c2ecf20Sopenharmony_ci	}
29228c2ecf20Sopenharmony_ci	if (ret) {
29238c2ecf20Sopenharmony_ci		crypto_aead_clear_flags(aead, CRYPTO_TFM_REQ_MASK);
29248c2ecf20Sopenharmony_ci		crypto_aead_set_flags(aead, crypto_aead_get_flags(ctx->fback) &
29258c2ecf20Sopenharmony_ci					    CRYPTO_TFM_REQ_MASK);
29268c2ecf20Sopenharmony_ci		return ret;
29278c2ecf20Sopenharmony_ci	}
29288c2ecf20Sopenharmony_ci
29298c2ecf20Sopenharmony_ci	aead_request_set_tfm(subreq, ctx->fback);
29308c2ecf20Sopenharmony_ci	aead_request_set_callback(subreq, req->base.flags, req->base.complete,
29318c2ecf20Sopenharmony_ci				  req->base.data);
29328c2ecf20Sopenharmony_ci	aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen,
29338c2ecf20Sopenharmony_ci			       req->iv);
29348c2ecf20Sopenharmony_ci	aead_request_set_ad(subreq, req->assoclen);
29358c2ecf20Sopenharmony_ci
29368c2ecf20Sopenharmony_ci	return (dir ==  SAFEXCEL_ENCRYPT) ?
29378c2ecf20Sopenharmony_ci		crypto_aead_encrypt(subreq) :
29388c2ecf20Sopenharmony_ci		crypto_aead_decrypt(subreq);
29398c2ecf20Sopenharmony_ci}
29408c2ecf20Sopenharmony_ci
29418c2ecf20Sopenharmony_cistatic int safexcel_aead_chachapoly_encrypt(struct aead_request *req)
29428c2ecf20Sopenharmony_ci{
29438c2ecf20Sopenharmony_ci	return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_ENCRYPT);
29448c2ecf20Sopenharmony_ci}
29458c2ecf20Sopenharmony_ci
29468c2ecf20Sopenharmony_cistatic int safexcel_aead_chachapoly_decrypt(struct aead_request *req)
29478c2ecf20Sopenharmony_ci{
29488c2ecf20Sopenharmony_ci	return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_DECRYPT);
29498c2ecf20Sopenharmony_ci}
29508c2ecf20Sopenharmony_ci
29518c2ecf20Sopenharmony_cistatic int safexcel_aead_fallback_cra_init(struct crypto_tfm *tfm)
29528c2ecf20Sopenharmony_ci{
29538c2ecf20Sopenharmony_ci	struct crypto_aead *aead = __crypto_aead_cast(tfm);
29548c2ecf20Sopenharmony_ci	struct aead_alg *alg = crypto_aead_alg(aead);
29558c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
29568c2ecf20Sopenharmony_ci
29578c2ecf20Sopenharmony_ci	safexcel_aead_cra_init(tfm);
29588c2ecf20Sopenharmony_ci
29598c2ecf20Sopenharmony_ci	/* Allocate fallback implementation */
29608c2ecf20Sopenharmony_ci	ctx->fback = crypto_alloc_aead(alg->base.cra_name, 0,
29618c2ecf20Sopenharmony_ci				       CRYPTO_ALG_ASYNC |
29628c2ecf20Sopenharmony_ci				       CRYPTO_ALG_NEED_FALLBACK);
29638c2ecf20Sopenharmony_ci	if (IS_ERR(ctx->fback))
29648c2ecf20Sopenharmony_ci		return PTR_ERR(ctx->fback);
29658c2ecf20Sopenharmony_ci
29668c2ecf20Sopenharmony_ci	crypto_aead_set_reqsize(aead, max(sizeof(struct safexcel_cipher_req),
29678c2ecf20Sopenharmony_ci					  sizeof(struct aead_request) +
29688c2ecf20Sopenharmony_ci					  crypto_aead_reqsize(ctx->fback)));
29698c2ecf20Sopenharmony_ci
29708c2ecf20Sopenharmony_ci	return 0;
29718c2ecf20Sopenharmony_ci}
29728c2ecf20Sopenharmony_ci
29738c2ecf20Sopenharmony_cistatic int safexcel_aead_chachapoly_cra_init(struct crypto_tfm *tfm)
29748c2ecf20Sopenharmony_ci{
29758c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
29768c2ecf20Sopenharmony_ci
29778c2ecf20Sopenharmony_ci	safexcel_aead_fallback_cra_init(tfm);
29788c2ecf20Sopenharmony_ci	ctx->alg  = SAFEXCEL_CHACHA20;
29798c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32 |
29808c2ecf20Sopenharmony_ci		    CONTEXT_CONTROL_CHACHA20_MODE_CALC_OTK;
29818c2ecf20Sopenharmony_ci	ctx->ctrinit = 0;
29828c2ecf20Sopenharmony_ci	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_POLY1305;
29838c2ecf20Sopenharmony_ci	ctx->state_sz = 0; /* Precomputed by HW */
29848c2ecf20Sopenharmony_ci	return 0;
29858c2ecf20Sopenharmony_ci}
29868c2ecf20Sopenharmony_ci
29878c2ecf20Sopenharmony_cistatic void safexcel_aead_fallback_cra_exit(struct crypto_tfm *tfm)
29888c2ecf20Sopenharmony_ci{
29898c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
29908c2ecf20Sopenharmony_ci
29918c2ecf20Sopenharmony_ci	crypto_free_aead(ctx->fback);
29928c2ecf20Sopenharmony_ci	safexcel_aead_cra_exit(tfm);
29938c2ecf20Sopenharmony_ci}
29948c2ecf20Sopenharmony_ci
29958c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_chachapoly = {
29968c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
29978c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305,
29988c2ecf20Sopenharmony_ci	.alg.aead = {
29998c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_chachapoly_setkey,
30008c2ecf20Sopenharmony_ci		.setauthsize = safexcel_aead_chachapoly_setauthsize,
30018c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_chachapoly_encrypt,
30028c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_chachapoly_decrypt,
30038c2ecf20Sopenharmony_ci		.ivsize = CHACHAPOLY_IV_SIZE,
30048c2ecf20Sopenharmony_ci		.maxauthsize = POLY1305_DIGEST_SIZE,
30058c2ecf20Sopenharmony_ci		.base = {
30068c2ecf20Sopenharmony_ci			.cra_name = "rfc7539(chacha20,poly1305)",
30078c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-chacha20-poly1305",
30088c2ecf20Sopenharmony_ci			/* +1 to put it above HW chacha + SW poly */
30098c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY + 1,
30108c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
30118c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
30128c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY |
30138c2ecf20Sopenharmony_ci				     CRYPTO_ALG_NEED_FALLBACK,
30148c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
30158c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
30168c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
30178c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_chachapoly_cra_init,
30188c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_fallback_cra_exit,
30198c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
30208c2ecf20Sopenharmony_ci		},
30218c2ecf20Sopenharmony_ci	},
30228c2ecf20Sopenharmony_ci};
30238c2ecf20Sopenharmony_ci
30248c2ecf20Sopenharmony_cistatic int safexcel_aead_chachapolyesp_cra_init(struct crypto_tfm *tfm)
30258c2ecf20Sopenharmony_ci{
30268c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
30278c2ecf20Sopenharmony_ci	int ret;
30288c2ecf20Sopenharmony_ci
30298c2ecf20Sopenharmony_ci	ret = safexcel_aead_chachapoly_cra_init(tfm);
30308c2ecf20Sopenharmony_ci	ctx->aead  = EIP197_AEAD_TYPE_IPSEC_ESP;
30318c2ecf20Sopenharmony_ci	ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE;
30328c2ecf20Sopenharmony_ci	return ret;
30338c2ecf20Sopenharmony_ci}
30348c2ecf20Sopenharmony_ci
30358c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_chachapoly_esp = {
30368c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
30378c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305,
30388c2ecf20Sopenharmony_ci	.alg.aead = {
30398c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_chachapoly_setkey,
30408c2ecf20Sopenharmony_ci		.setauthsize = safexcel_aead_chachapoly_setauthsize,
30418c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_chachapoly_encrypt,
30428c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_chachapoly_decrypt,
30438c2ecf20Sopenharmony_ci		.ivsize = CHACHAPOLY_IV_SIZE - EIP197_AEAD_IPSEC_NONCE_SIZE,
30448c2ecf20Sopenharmony_ci		.maxauthsize = POLY1305_DIGEST_SIZE,
30458c2ecf20Sopenharmony_ci		.base = {
30468c2ecf20Sopenharmony_ci			.cra_name = "rfc7539esp(chacha20,poly1305)",
30478c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-chacha20-poly1305-esp",
30488c2ecf20Sopenharmony_ci			/* +1 to put it above HW chacha + SW poly */
30498c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY + 1,
30508c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
30518c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
30528c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY |
30538c2ecf20Sopenharmony_ci				     CRYPTO_ALG_NEED_FALLBACK,
30548c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
30558c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
30568c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
30578c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_chachapolyesp_cra_init,
30588c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_fallback_cra_exit,
30598c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
30608c2ecf20Sopenharmony_ci		},
30618c2ecf20Sopenharmony_ci	},
30628c2ecf20Sopenharmony_ci};
30638c2ecf20Sopenharmony_ci
30648c2ecf20Sopenharmony_cistatic int safexcel_skcipher_sm4_setkey(struct crypto_skcipher *ctfm,
30658c2ecf20Sopenharmony_ci					const u8 *key, unsigned int len)
30668c2ecf20Sopenharmony_ci{
30678c2ecf20Sopenharmony_ci	struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);
30688c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
30698c2ecf20Sopenharmony_ci	struct safexcel_crypto_priv *priv = ctx->base.priv;
30708c2ecf20Sopenharmony_ci
30718c2ecf20Sopenharmony_ci	if (len != SM4_KEY_SIZE)
30728c2ecf20Sopenharmony_ci		return -EINVAL;
30738c2ecf20Sopenharmony_ci
30748c2ecf20Sopenharmony_ci	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma)
30758c2ecf20Sopenharmony_ci		if (memcmp(ctx->key, key, SM4_KEY_SIZE))
30768c2ecf20Sopenharmony_ci			ctx->base.needs_inv = true;
30778c2ecf20Sopenharmony_ci
30788c2ecf20Sopenharmony_ci	memcpy(ctx->key, key, SM4_KEY_SIZE);
30798c2ecf20Sopenharmony_ci	ctx->key_len = SM4_KEY_SIZE;
30808c2ecf20Sopenharmony_ci
30818c2ecf20Sopenharmony_ci	return 0;
30828c2ecf20Sopenharmony_ci}
30838c2ecf20Sopenharmony_ci
30848c2ecf20Sopenharmony_cistatic int safexcel_sm4_blk_encrypt(struct skcipher_request *req)
30858c2ecf20Sopenharmony_ci{
30868c2ecf20Sopenharmony_ci	/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */
30878c2ecf20Sopenharmony_ci	if (req->cryptlen & (SM4_BLOCK_SIZE - 1))
30888c2ecf20Sopenharmony_ci		return -EINVAL;
30898c2ecf20Sopenharmony_ci	else
30908c2ecf20Sopenharmony_ci		return safexcel_queue_req(&req->base, skcipher_request_ctx(req),
30918c2ecf20Sopenharmony_ci					  SAFEXCEL_ENCRYPT);
30928c2ecf20Sopenharmony_ci}
30938c2ecf20Sopenharmony_ci
30948c2ecf20Sopenharmony_cistatic int safexcel_sm4_blk_decrypt(struct skcipher_request *req)
30958c2ecf20Sopenharmony_ci{
30968c2ecf20Sopenharmony_ci	/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */
30978c2ecf20Sopenharmony_ci	if (req->cryptlen & (SM4_BLOCK_SIZE - 1))
30988c2ecf20Sopenharmony_ci		return -EINVAL;
30998c2ecf20Sopenharmony_ci	else
31008c2ecf20Sopenharmony_ci		return safexcel_queue_req(&req->base, skcipher_request_ctx(req),
31018c2ecf20Sopenharmony_ci					  SAFEXCEL_DECRYPT);
31028c2ecf20Sopenharmony_ci}
31038c2ecf20Sopenharmony_ci
31048c2ecf20Sopenharmony_cistatic int safexcel_skcipher_sm4_ecb_cra_init(struct crypto_tfm *tfm)
31058c2ecf20Sopenharmony_ci{
31068c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
31078c2ecf20Sopenharmony_ci
31088c2ecf20Sopenharmony_ci	safexcel_skcipher_cra_init(tfm);
31098c2ecf20Sopenharmony_ci	ctx->alg  = SAFEXCEL_SM4;
31108c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB;
31118c2ecf20Sopenharmony_ci	ctx->blocksz = 0;
31128c2ecf20Sopenharmony_ci	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
31138c2ecf20Sopenharmony_ci	return 0;
31148c2ecf20Sopenharmony_ci}
31158c2ecf20Sopenharmony_ci
31168c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ecb_sm4 = {
31178c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
31188c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_SM4,
31198c2ecf20Sopenharmony_ci	.alg.skcipher = {
31208c2ecf20Sopenharmony_ci		.setkey = safexcel_skcipher_sm4_setkey,
31218c2ecf20Sopenharmony_ci		.encrypt = safexcel_sm4_blk_encrypt,
31228c2ecf20Sopenharmony_ci		.decrypt = safexcel_sm4_blk_decrypt,
31238c2ecf20Sopenharmony_ci		.min_keysize = SM4_KEY_SIZE,
31248c2ecf20Sopenharmony_ci		.max_keysize = SM4_KEY_SIZE,
31258c2ecf20Sopenharmony_ci		.base = {
31268c2ecf20Sopenharmony_ci			.cra_name = "ecb(sm4)",
31278c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-ecb-sm4",
31288c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
31298c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
31308c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
31318c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
31328c2ecf20Sopenharmony_ci			.cra_blocksize = SM4_BLOCK_SIZE,
31338c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
31348c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
31358c2ecf20Sopenharmony_ci			.cra_init = safexcel_skcipher_sm4_ecb_cra_init,
31368c2ecf20Sopenharmony_ci			.cra_exit = safexcel_skcipher_cra_exit,
31378c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
31388c2ecf20Sopenharmony_ci		},
31398c2ecf20Sopenharmony_ci	},
31408c2ecf20Sopenharmony_ci};
31418c2ecf20Sopenharmony_ci
31428c2ecf20Sopenharmony_cistatic int safexcel_skcipher_sm4_cbc_cra_init(struct crypto_tfm *tfm)
31438c2ecf20Sopenharmony_ci{
31448c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
31458c2ecf20Sopenharmony_ci
31468c2ecf20Sopenharmony_ci	safexcel_skcipher_cra_init(tfm);
31478c2ecf20Sopenharmony_ci	ctx->alg  = SAFEXCEL_SM4;
31488c2ecf20Sopenharmony_ci	ctx->blocksz = SM4_BLOCK_SIZE;
31498c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC;
31508c2ecf20Sopenharmony_ci	return 0;
31518c2ecf20Sopenharmony_ci}
31528c2ecf20Sopenharmony_ci
31538c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_cbc_sm4 = {
31548c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
31558c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_SM4,
31568c2ecf20Sopenharmony_ci	.alg.skcipher = {
31578c2ecf20Sopenharmony_ci		.setkey = safexcel_skcipher_sm4_setkey,
31588c2ecf20Sopenharmony_ci		.encrypt = safexcel_sm4_blk_encrypt,
31598c2ecf20Sopenharmony_ci		.decrypt = safexcel_sm4_blk_decrypt,
31608c2ecf20Sopenharmony_ci		.min_keysize = SM4_KEY_SIZE,
31618c2ecf20Sopenharmony_ci		.max_keysize = SM4_KEY_SIZE,
31628c2ecf20Sopenharmony_ci		.ivsize = SM4_BLOCK_SIZE,
31638c2ecf20Sopenharmony_ci		.base = {
31648c2ecf20Sopenharmony_ci			.cra_name = "cbc(sm4)",
31658c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-cbc-sm4",
31668c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
31678c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
31688c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
31698c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
31708c2ecf20Sopenharmony_ci			.cra_blocksize = SM4_BLOCK_SIZE,
31718c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
31728c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
31738c2ecf20Sopenharmony_ci			.cra_init = safexcel_skcipher_sm4_cbc_cra_init,
31748c2ecf20Sopenharmony_ci			.cra_exit = safexcel_skcipher_cra_exit,
31758c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
31768c2ecf20Sopenharmony_ci		},
31778c2ecf20Sopenharmony_ci	},
31788c2ecf20Sopenharmony_ci};
31798c2ecf20Sopenharmony_ci
31808c2ecf20Sopenharmony_cistatic int safexcel_skcipher_sm4_ofb_cra_init(struct crypto_tfm *tfm)
31818c2ecf20Sopenharmony_ci{
31828c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
31838c2ecf20Sopenharmony_ci
31848c2ecf20Sopenharmony_ci	safexcel_skcipher_cra_init(tfm);
31858c2ecf20Sopenharmony_ci	ctx->alg  = SAFEXCEL_SM4;
31868c2ecf20Sopenharmony_ci	ctx->blocksz = SM4_BLOCK_SIZE;
31878c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_OFB;
31888c2ecf20Sopenharmony_ci	return 0;
31898c2ecf20Sopenharmony_ci}
31908c2ecf20Sopenharmony_ci
31918c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ofb_sm4 = {
31928c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
31938c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_AES_XFB,
31948c2ecf20Sopenharmony_ci	.alg.skcipher = {
31958c2ecf20Sopenharmony_ci		.setkey = safexcel_skcipher_sm4_setkey,
31968c2ecf20Sopenharmony_ci		.encrypt = safexcel_encrypt,
31978c2ecf20Sopenharmony_ci		.decrypt = safexcel_decrypt,
31988c2ecf20Sopenharmony_ci		.min_keysize = SM4_KEY_SIZE,
31998c2ecf20Sopenharmony_ci		.max_keysize = SM4_KEY_SIZE,
32008c2ecf20Sopenharmony_ci		.ivsize = SM4_BLOCK_SIZE,
32018c2ecf20Sopenharmony_ci		.base = {
32028c2ecf20Sopenharmony_ci			.cra_name = "ofb(sm4)",
32038c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-ofb-sm4",
32048c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
32058c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
32068c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
32078c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
32088c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
32098c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
32108c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
32118c2ecf20Sopenharmony_ci			.cra_init = safexcel_skcipher_sm4_ofb_cra_init,
32128c2ecf20Sopenharmony_ci			.cra_exit = safexcel_skcipher_cra_exit,
32138c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
32148c2ecf20Sopenharmony_ci		},
32158c2ecf20Sopenharmony_ci	},
32168c2ecf20Sopenharmony_ci};
32178c2ecf20Sopenharmony_ci
32188c2ecf20Sopenharmony_cistatic int safexcel_skcipher_sm4_cfb_cra_init(struct crypto_tfm *tfm)
32198c2ecf20Sopenharmony_ci{
32208c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
32218c2ecf20Sopenharmony_ci
32228c2ecf20Sopenharmony_ci	safexcel_skcipher_cra_init(tfm);
32238c2ecf20Sopenharmony_ci	ctx->alg  = SAFEXCEL_SM4;
32248c2ecf20Sopenharmony_ci	ctx->blocksz = SM4_BLOCK_SIZE;
32258c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CFB;
32268c2ecf20Sopenharmony_ci	return 0;
32278c2ecf20Sopenharmony_ci}
32288c2ecf20Sopenharmony_ci
32298c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_cfb_sm4 = {
32308c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
32318c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_AES_XFB,
32328c2ecf20Sopenharmony_ci	.alg.skcipher = {
32338c2ecf20Sopenharmony_ci		.setkey = safexcel_skcipher_sm4_setkey,
32348c2ecf20Sopenharmony_ci		.encrypt = safexcel_encrypt,
32358c2ecf20Sopenharmony_ci		.decrypt = safexcel_decrypt,
32368c2ecf20Sopenharmony_ci		.min_keysize = SM4_KEY_SIZE,
32378c2ecf20Sopenharmony_ci		.max_keysize = SM4_KEY_SIZE,
32388c2ecf20Sopenharmony_ci		.ivsize = SM4_BLOCK_SIZE,
32398c2ecf20Sopenharmony_ci		.base = {
32408c2ecf20Sopenharmony_ci			.cra_name = "cfb(sm4)",
32418c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-cfb-sm4",
32428c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
32438c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
32448c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
32458c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
32468c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
32478c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
32488c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
32498c2ecf20Sopenharmony_ci			.cra_init = safexcel_skcipher_sm4_cfb_cra_init,
32508c2ecf20Sopenharmony_ci			.cra_exit = safexcel_skcipher_cra_exit,
32518c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
32528c2ecf20Sopenharmony_ci		},
32538c2ecf20Sopenharmony_ci	},
32548c2ecf20Sopenharmony_ci};
32558c2ecf20Sopenharmony_ci
32568c2ecf20Sopenharmony_cistatic int safexcel_skcipher_sm4ctr_setkey(struct crypto_skcipher *ctfm,
32578c2ecf20Sopenharmony_ci					   const u8 *key, unsigned int len)
32588c2ecf20Sopenharmony_ci{
32598c2ecf20Sopenharmony_ci	struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);
32608c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
32618c2ecf20Sopenharmony_ci
32628c2ecf20Sopenharmony_ci	/* last 4 bytes of key are the nonce! */
32638c2ecf20Sopenharmony_ci	ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE);
32648c2ecf20Sopenharmony_ci	/* exclude the nonce here */
32658c2ecf20Sopenharmony_ci	len -= CTR_RFC3686_NONCE_SIZE;
32668c2ecf20Sopenharmony_ci
32678c2ecf20Sopenharmony_ci	return safexcel_skcipher_sm4_setkey(ctfm, key, len);
32688c2ecf20Sopenharmony_ci}
32698c2ecf20Sopenharmony_ci
32708c2ecf20Sopenharmony_cistatic int safexcel_skcipher_sm4_ctr_cra_init(struct crypto_tfm *tfm)
32718c2ecf20Sopenharmony_ci{
32728c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
32738c2ecf20Sopenharmony_ci
32748c2ecf20Sopenharmony_ci	safexcel_skcipher_cra_init(tfm);
32758c2ecf20Sopenharmony_ci	ctx->alg  = SAFEXCEL_SM4;
32768c2ecf20Sopenharmony_ci	ctx->blocksz = SM4_BLOCK_SIZE;
32778c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;
32788c2ecf20Sopenharmony_ci	return 0;
32798c2ecf20Sopenharmony_ci}
32808c2ecf20Sopenharmony_ci
32818c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_ctr_sm4 = {
32828c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
32838c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_SM4,
32848c2ecf20Sopenharmony_ci	.alg.skcipher = {
32858c2ecf20Sopenharmony_ci		.setkey = safexcel_skcipher_sm4ctr_setkey,
32868c2ecf20Sopenharmony_ci		.encrypt = safexcel_encrypt,
32878c2ecf20Sopenharmony_ci		.decrypt = safexcel_decrypt,
32888c2ecf20Sopenharmony_ci		/* Add nonce size */
32898c2ecf20Sopenharmony_ci		.min_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,
32908c2ecf20Sopenharmony_ci		.max_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,
32918c2ecf20Sopenharmony_ci		.ivsize = CTR_RFC3686_IV_SIZE,
32928c2ecf20Sopenharmony_ci		.base = {
32938c2ecf20Sopenharmony_ci			.cra_name = "rfc3686(ctr(sm4))",
32948c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-ctr-sm4",
32958c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
32968c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
32978c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
32988c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
32998c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
33008c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
33018c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
33028c2ecf20Sopenharmony_ci			.cra_init = safexcel_skcipher_sm4_ctr_cra_init,
33038c2ecf20Sopenharmony_ci			.cra_exit = safexcel_skcipher_cra_exit,
33048c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
33058c2ecf20Sopenharmony_ci		},
33068c2ecf20Sopenharmony_ci	},
33078c2ecf20Sopenharmony_ci};
33088c2ecf20Sopenharmony_ci
33098c2ecf20Sopenharmony_cistatic int safexcel_aead_sm4_blk_encrypt(struct aead_request *req)
33108c2ecf20Sopenharmony_ci{
33118c2ecf20Sopenharmony_ci	/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */
33128c2ecf20Sopenharmony_ci	if (req->cryptlen & (SM4_BLOCK_SIZE - 1))
33138c2ecf20Sopenharmony_ci		return -EINVAL;
33148c2ecf20Sopenharmony_ci
33158c2ecf20Sopenharmony_ci	return safexcel_queue_req(&req->base, aead_request_ctx(req),
33168c2ecf20Sopenharmony_ci				  SAFEXCEL_ENCRYPT);
33178c2ecf20Sopenharmony_ci}
33188c2ecf20Sopenharmony_ci
33198c2ecf20Sopenharmony_cistatic int safexcel_aead_sm4_blk_decrypt(struct aead_request *req)
33208c2ecf20Sopenharmony_ci{
33218c2ecf20Sopenharmony_ci	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
33228c2ecf20Sopenharmony_ci
33238c2ecf20Sopenharmony_ci	/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */
33248c2ecf20Sopenharmony_ci	if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1))
33258c2ecf20Sopenharmony_ci		return -EINVAL;
33268c2ecf20Sopenharmony_ci
33278c2ecf20Sopenharmony_ci	return safexcel_queue_req(&req->base, aead_request_ctx(req),
33288c2ecf20Sopenharmony_ci				  SAFEXCEL_DECRYPT);
33298c2ecf20Sopenharmony_ci}
33308c2ecf20Sopenharmony_ci
33318c2ecf20Sopenharmony_cistatic int safexcel_aead_sm4cbc_sha1_cra_init(struct crypto_tfm *tfm)
33328c2ecf20Sopenharmony_ci{
33338c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
33348c2ecf20Sopenharmony_ci
33358c2ecf20Sopenharmony_ci	safexcel_aead_cra_init(tfm);
33368c2ecf20Sopenharmony_ci	ctx->alg = SAFEXCEL_SM4;
33378c2ecf20Sopenharmony_ci	ctx->blocksz = SM4_BLOCK_SIZE;
33388c2ecf20Sopenharmony_ci	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1;
33398c2ecf20Sopenharmony_ci	ctx->state_sz = SHA1_DIGEST_SIZE;
33408c2ecf20Sopenharmony_ci	return 0;
33418c2ecf20Sopenharmony_ci}
33428c2ecf20Sopenharmony_ci
33438c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_sm4 = {
33448c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
33458c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1,
33468c2ecf20Sopenharmony_ci	.alg.aead = {
33478c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
33488c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_sm4_blk_encrypt,
33498c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_sm4_blk_decrypt,
33508c2ecf20Sopenharmony_ci		.ivsize = SM4_BLOCK_SIZE,
33518c2ecf20Sopenharmony_ci		.maxauthsize = SHA1_DIGEST_SIZE,
33528c2ecf20Sopenharmony_ci		.base = {
33538c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha1),cbc(sm4))",
33548c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-sm4",
33558c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
33568c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
33578c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
33588c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
33598c2ecf20Sopenharmony_ci			.cra_blocksize = SM4_BLOCK_SIZE,
33608c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
33618c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
33628c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sm4cbc_sha1_cra_init,
33638c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
33648c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
33658c2ecf20Sopenharmony_ci		},
33668c2ecf20Sopenharmony_ci	},
33678c2ecf20Sopenharmony_ci};
33688c2ecf20Sopenharmony_ci
33698c2ecf20Sopenharmony_cistatic int safexcel_aead_fallback_setkey(struct crypto_aead *ctfm,
33708c2ecf20Sopenharmony_ci					 const u8 *key, unsigned int len)
33718c2ecf20Sopenharmony_ci{
33728c2ecf20Sopenharmony_ci	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);
33738c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
33748c2ecf20Sopenharmony_ci
33758c2ecf20Sopenharmony_ci	/* Keep fallback cipher synchronized */
33768c2ecf20Sopenharmony_ci	return crypto_aead_setkey(ctx->fback, (u8 *)key, len) ?:
33778c2ecf20Sopenharmony_ci	       safexcel_aead_setkey(ctfm, key, len);
33788c2ecf20Sopenharmony_ci}
33798c2ecf20Sopenharmony_ci
33808c2ecf20Sopenharmony_cistatic int safexcel_aead_fallback_setauthsize(struct crypto_aead *ctfm,
33818c2ecf20Sopenharmony_ci					      unsigned int authsize)
33828c2ecf20Sopenharmony_ci{
33838c2ecf20Sopenharmony_ci	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);
33848c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
33858c2ecf20Sopenharmony_ci
33868c2ecf20Sopenharmony_ci	/* Keep fallback cipher synchronized */
33878c2ecf20Sopenharmony_ci	return crypto_aead_setauthsize(ctx->fback, authsize);
33888c2ecf20Sopenharmony_ci}
33898c2ecf20Sopenharmony_ci
33908c2ecf20Sopenharmony_cistatic int safexcel_aead_fallback_crypt(struct aead_request *req,
33918c2ecf20Sopenharmony_ci					enum safexcel_cipher_direction dir)
33928c2ecf20Sopenharmony_ci{
33938c2ecf20Sopenharmony_ci	struct crypto_aead *aead = crypto_aead_reqtfm(req);
33948c2ecf20Sopenharmony_ci	struct crypto_tfm *tfm = crypto_aead_tfm(aead);
33958c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
33968c2ecf20Sopenharmony_ci	struct aead_request *subreq = aead_request_ctx(req);
33978c2ecf20Sopenharmony_ci
33988c2ecf20Sopenharmony_ci	aead_request_set_tfm(subreq, ctx->fback);
33998c2ecf20Sopenharmony_ci	aead_request_set_callback(subreq, req->base.flags, req->base.complete,
34008c2ecf20Sopenharmony_ci				  req->base.data);
34018c2ecf20Sopenharmony_ci	aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen,
34028c2ecf20Sopenharmony_ci			       req->iv);
34038c2ecf20Sopenharmony_ci	aead_request_set_ad(subreq, req->assoclen);
34048c2ecf20Sopenharmony_ci
34058c2ecf20Sopenharmony_ci	return (dir ==  SAFEXCEL_ENCRYPT) ?
34068c2ecf20Sopenharmony_ci		crypto_aead_encrypt(subreq) :
34078c2ecf20Sopenharmony_ci		crypto_aead_decrypt(subreq);
34088c2ecf20Sopenharmony_ci}
34098c2ecf20Sopenharmony_ci
34108c2ecf20Sopenharmony_cistatic int safexcel_aead_sm4cbc_sm3_encrypt(struct aead_request *req)
34118c2ecf20Sopenharmony_ci{
34128c2ecf20Sopenharmony_ci	struct safexcel_cipher_req *creq = aead_request_ctx(req);
34138c2ecf20Sopenharmony_ci
34148c2ecf20Sopenharmony_ci	/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */
34158c2ecf20Sopenharmony_ci	if (req->cryptlen & (SM4_BLOCK_SIZE - 1))
34168c2ecf20Sopenharmony_ci		return -EINVAL;
34178c2ecf20Sopenharmony_ci	else if (req->cryptlen || req->assoclen) /* If input length > 0 only */
34188c2ecf20Sopenharmony_ci		return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT);
34198c2ecf20Sopenharmony_ci
34208c2ecf20Sopenharmony_ci	/* HW cannot do full (AAD+payload) zero length, use fallback */
34218c2ecf20Sopenharmony_ci	return safexcel_aead_fallback_crypt(req, SAFEXCEL_ENCRYPT);
34228c2ecf20Sopenharmony_ci}
34238c2ecf20Sopenharmony_ci
34248c2ecf20Sopenharmony_cistatic int safexcel_aead_sm4cbc_sm3_decrypt(struct aead_request *req)
34258c2ecf20Sopenharmony_ci{
34268c2ecf20Sopenharmony_ci	struct safexcel_cipher_req *creq = aead_request_ctx(req);
34278c2ecf20Sopenharmony_ci	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
34288c2ecf20Sopenharmony_ci
34298c2ecf20Sopenharmony_ci	/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */
34308c2ecf20Sopenharmony_ci	if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1))
34318c2ecf20Sopenharmony_ci		return -EINVAL;
34328c2ecf20Sopenharmony_ci	else if (req->cryptlen > crypto_aead_authsize(tfm) || req->assoclen)
34338c2ecf20Sopenharmony_ci		/* If input length > 0 only */
34348c2ecf20Sopenharmony_ci		return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT);
34358c2ecf20Sopenharmony_ci
34368c2ecf20Sopenharmony_ci	/* HW cannot do full (AAD+payload) zero length, use fallback */
34378c2ecf20Sopenharmony_ci	return safexcel_aead_fallback_crypt(req, SAFEXCEL_DECRYPT);
34388c2ecf20Sopenharmony_ci}
34398c2ecf20Sopenharmony_ci
34408c2ecf20Sopenharmony_cistatic int safexcel_aead_sm4cbc_sm3_cra_init(struct crypto_tfm *tfm)
34418c2ecf20Sopenharmony_ci{
34428c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
34438c2ecf20Sopenharmony_ci
34448c2ecf20Sopenharmony_ci	safexcel_aead_fallback_cra_init(tfm);
34458c2ecf20Sopenharmony_ci	ctx->alg = SAFEXCEL_SM4;
34468c2ecf20Sopenharmony_ci	ctx->blocksz = SM4_BLOCK_SIZE;
34478c2ecf20Sopenharmony_ci	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SM3;
34488c2ecf20Sopenharmony_ci	ctx->state_sz = SM3_DIGEST_SIZE;
34498c2ecf20Sopenharmony_ci	return 0;
34508c2ecf20Sopenharmony_ci}
34518c2ecf20Sopenharmony_ci
34528c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_cbc_sm4 = {
34538c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
34548c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3,
34558c2ecf20Sopenharmony_ci	.alg.aead = {
34568c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_fallback_setkey,
34578c2ecf20Sopenharmony_ci		.setauthsize = safexcel_aead_fallback_setauthsize,
34588c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_sm4cbc_sm3_encrypt,
34598c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_sm4cbc_sm3_decrypt,
34608c2ecf20Sopenharmony_ci		.ivsize = SM4_BLOCK_SIZE,
34618c2ecf20Sopenharmony_ci		.maxauthsize = SM3_DIGEST_SIZE,
34628c2ecf20Sopenharmony_ci		.base = {
34638c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sm3),cbc(sm4))",
34648c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sm3-cbc-sm4",
34658c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
34668c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
34678c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
34688c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY |
34698c2ecf20Sopenharmony_ci				     CRYPTO_ALG_NEED_FALLBACK,
34708c2ecf20Sopenharmony_ci			.cra_blocksize = SM4_BLOCK_SIZE,
34718c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
34728c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
34738c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sm4cbc_sm3_cra_init,
34748c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_fallback_cra_exit,
34758c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
34768c2ecf20Sopenharmony_ci		},
34778c2ecf20Sopenharmony_ci	},
34788c2ecf20Sopenharmony_ci};
34798c2ecf20Sopenharmony_ci
34808c2ecf20Sopenharmony_cistatic int safexcel_aead_sm4ctr_sha1_cra_init(struct crypto_tfm *tfm)
34818c2ecf20Sopenharmony_ci{
34828c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
34838c2ecf20Sopenharmony_ci
34848c2ecf20Sopenharmony_ci	safexcel_aead_sm4cbc_sha1_cra_init(tfm);
34858c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;
34868c2ecf20Sopenharmony_ci	return 0;
34878c2ecf20Sopenharmony_ci}
34888c2ecf20Sopenharmony_ci
34898c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_sm4 = {
34908c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
34918c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1,
34928c2ecf20Sopenharmony_ci	.alg.aead = {
34938c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
34948c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
34958c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
34968c2ecf20Sopenharmony_ci		.ivsize = CTR_RFC3686_IV_SIZE,
34978c2ecf20Sopenharmony_ci		.maxauthsize = SHA1_DIGEST_SIZE,
34988c2ecf20Sopenharmony_ci		.base = {
34998c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sha1),rfc3686(ctr(sm4)))",
35008c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-sm4",
35018c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
35028c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
35038c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
35048c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
35058c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
35068c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
35078c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
35088c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sm4ctr_sha1_cra_init,
35098c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
35108c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
35118c2ecf20Sopenharmony_ci		},
35128c2ecf20Sopenharmony_ci	},
35138c2ecf20Sopenharmony_ci};
35148c2ecf20Sopenharmony_ci
35158c2ecf20Sopenharmony_cistatic int safexcel_aead_sm4ctr_sm3_cra_init(struct crypto_tfm *tfm)
35168c2ecf20Sopenharmony_ci{
35178c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
35188c2ecf20Sopenharmony_ci
35198c2ecf20Sopenharmony_ci	safexcel_aead_sm4cbc_sm3_cra_init(tfm);
35208c2ecf20Sopenharmony_ci	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;
35218c2ecf20Sopenharmony_ci	return 0;
35228c2ecf20Sopenharmony_ci}
35238c2ecf20Sopenharmony_ci
35248c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_ctr_sm4 = {
35258c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
35268c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3,
35278c2ecf20Sopenharmony_ci	.alg.aead = {
35288c2ecf20Sopenharmony_ci		.setkey = safexcel_aead_setkey,
35298c2ecf20Sopenharmony_ci		.encrypt = safexcel_aead_encrypt,
35308c2ecf20Sopenharmony_ci		.decrypt = safexcel_aead_decrypt,
35318c2ecf20Sopenharmony_ci		.ivsize = CTR_RFC3686_IV_SIZE,
35328c2ecf20Sopenharmony_ci		.maxauthsize = SM3_DIGEST_SIZE,
35338c2ecf20Sopenharmony_ci		.base = {
35348c2ecf20Sopenharmony_ci			.cra_name = "authenc(hmac(sm3),rfc3686(ctr(sm4)))",
35358c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-authenc-hmac-sm3-ctr-sm4",
35368c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
35378c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
35388c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
35398c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
35408c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
35418c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
35428c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
35438c2ecf20Sopenharmony_ci			.cra_init = safexcel_aead_sm4ctr_sm3_cra_init,
35448c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
35458c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
35468c2ecf20Sopenharmony_ci		},
35478c2ecf20Sopenharmony_ci	},
35488c2ecf20Sopenharmony_ci};
35498c2ecf20Sopenharmony_ci
35508c2ecf20Sopenharmony_cistatic int safexcel_rfc4106_gcm_setkey(struct crypto_aead *ctfm, const u8 *key,
35518c2ecf20Sopenharmony_ci				       unsigned int len)
35528c2ecf20Sopenharmony_ci{
35538c2ecf20Sopenharmony_ci	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);
35548c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
35558c2ecf20Sopenharmony_ci
35568c2ecf20Sopenharmony_ci	/* last 4 bytes of key are the nonce! */
35578c2ecf20Sopenharmony_ci	ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE);
35588c2ecf20Sopenharmony_ci
35598c2ecf20Sopenharmony_ci	len -= CTR_RFC3686_NONCE_SIZE;
35608c2ecf20Sopenharmony_ci	return safexcel_aead_gcm_setkey(ctfm, key, len);
35618c2ecf20Sopenharmony_ci}
35628c2ecf20Sopenharmony_ci
35638c2ecf20Sopenharmony_cistatic int safexcel_rfc4106_gcm_setauthsize(struct crypto_aead *tfm,
35648c2ecf20Sopenharmony_ci					    unsigned int authsize)
35658c2ecf20Sopenharmony_ci{
35668c2ecf20Sopenharmony_ci	return crypto_rfc4106_check_authsize(authsize);
35678c2ecf20Sopenharmony_ci}
35688c2ecf20Sopenharmony_ci
35698c2ecf20Sopenharmony_cistatic int safexcel_rfc4106_encrypt(struct aead_request *req)
35708c2ecf20Sopenharmony_ci{
35718c2ecf20Sopenharmony_ci	return crypto_ipsec_check_assoclen(req->assoclen) ?:
35728c2ecf20Sopenharmony_ci	       safexcel_aead_encrypt(req);
35738c2ecf20Sopenharmony_ci}
35748c2ecf20Sopenharmony_ci
35758c2ecf20Sopenharmony_cistatic int safexcel_rfc4106_decrypt(struct aead_request *req)
35768c2ecf20Sopenharmony_ci{
35778c2ecf20Sopenharmony_ci	return crypto_ipsec_check_assoclen(req->assoclen) ?:
35788c2ecf20Sopenharmony_ci	       safexcel_aead_decrypt(req);
35798c2ecf20Sopenharmony_ci}
35808c2ecf20Sopenharmony_ci
35818c2ecf20Sopenharmony_cistatic int safexcel_rfc4106_gcm_cra_init(struct crypto_tfm *tfm)
35828c2ecf20Sopenharmony_ci{
35838c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
35848c2ecf20Sopenharmony_ci	int ret;
35858c2ecf20Sopenharmony_ci
35868c2ecf20Sopenharmony_ci	ret = safexcel_aead_gcm_cra_init(tfm);
35878c2ecf20Sopenharmony_ci	ctx->aead  = EIP197_AEAD_TYPE_IPSEC_ESP;
35888c2ecf20Sopenharmony_ci	ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE;
35898c2ecf20Sopenharmony_ci	return ret;
35908c2ecf20Sopenharmony_ci}
35918c2ecf20Sopenharmony_ci
35928c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_rfc4106_gcm = {
35938c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
35948c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH,
35958c2ecf20Sopenharmony_ci	.alg.aead = {
35968c2ecf20Sopenharmony_ci		.setkey = safexcel_rfc4106_gcm_setkey,
35978c2ecf20Sopenharmony_ci		.setauthsize = safexcel_rfc4106_gcm_setauthsize,
35988c2ecf20Sopenharmony_ci		.encrypt = safexcel_rfc4106_encrypt,
35998c2ecf20Sopenharmony_ci		.decrypt = safexcel_rfc4106_decrypt,
36008c2ecf20Sopenharmony_ci		.ivsize = GCM_RFC4106_IV_SIZE,
36018c2ecf20Sopenharmony_ci		.maxauthsize = GHASH_DIGEST_SIZE,
36028c2ecf20Sopenharmony_ci		.base = {
36038c2ecf20Sopenharmony_ci			.cra_name = "rfc4106(gcm(aes))",
36048c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-rfc4106-gcm-aes",
36058c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
36068c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
36078c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
36088c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
36098c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
36108c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
36118c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
36128c2ecf20Sopenharmony_ci			.cra_init = safexcel_rfc4106_gcm_cra_init,
36138c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_gcm_cra_exit,
36148c2ecf20Sopenharmony_ci		},
36158c2ecf20Sopenharmony_ci	},
36168c2ecf20Sopenharmony_ci};
36178c2ecf20Sopenharmony_ci
36188c2ecf20Sopenharmony_cistatic int safexcel_rfc4543_gcm_setauthsize(struct crypto_aead *tfm,
36198c2ecf20Sopenharmony_ci					    unsigned int authsize)
36208c2ecf20Sopenharmony_ci{
36218c2ecf20Sopenharmony_ci	if (authsize != GHASH_DIGEST_SIZE)
36228c2ecf20Sopenharmony_ci		return -EINVAL;
36238c2ecf20Sopenharmony_ci
36248c2ecf20Sopenharmony_ci	return 0;
36258c2ecf20Sopenharmony_ci}
36268c2ecf20Sopenharmony_ci
36278c2ecf20Sopenharmony_cistatic int safexcel_rfc4543_gcm_cra_init(struct crypto_tfm *tfm)
36288c2ecf20Sopenharmony_ci{
36298c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
36308c2ecf20Sopenharmony_ci	int ret;
36318c2ecf20Sopenharmony_ci
36328c2ecf20Sopenharmony_ci	ret = safexcel_aead_gcm_cra_init(tfm);
36338c2ecf20Sopenharmony_ci	ctx->aead  = EIP197_AEAD_TYPE_IPSEC_ESP_GMAC;
36348c2ecf20Sopenharmony_ci	return ret;
36358c2ecf20Sopenharmony_ci}
36368c2ecf20Sopenharmony_ci
36378c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_rfc4543_gcm = {
36388c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
36398c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH,
36408c2ecf20Sopenharmony_ci	.alg.aead = {
36418c2ecf20Sopenharmony_ci		.setkey = safexcel_rfc4106_gcm_setkey,
36428c2ecf20Sopenharmony_ci		.setauthsize = safexcel_rfc4543_gcm_setauthsize,
36438c2ecf20Sopenharmony_ci		.encrypt = safexcel_rfc4106_encrypt,
36448c2ecf20Sopenharmony_ci		.decrypt = safexcel_rfc4106_decrypt,
36458c2ecf20Sopenharmony_ci		.ivsize = GCM_RFC4543_IV_SIZE,
36468c2ecf20Sopenharmony_ci		.maxauthsize = GHASH_DIGEST_SIZE,
36478c2ecf20Sopenharmony_ci		.base = {
36488c2ecf20Sopenharmony_ci			.cra_name = "rfc4543(gcm(aes))",
36498c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-rfc4543-gcm-aes",
36508c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
36518c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
36528c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
36538c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
36548c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
36558c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
36568c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
36578c2ecf20Sopenharmony_ci			.cra_init = safexcel_rfc4543_gcm_cra_init,
36588c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_gcm_cra_exit,
36598c2ecf20Sopenharmony_ci		},
36608c2ecf20Sopenharmony_ci	},
36618c2ecf20Sopenharmony_ci};
36628c2ecf20Sopenharmony_ci
36638c2ecf20Sopenharmony_cistatic int safexcel_rfc4309_ccm_setkey(struct crypto_aead *ctfm, const u8 *key,
36648c2ecf20Sopenharmony_ci				       unsigned int len)
36658c2ecf20Sopenharmony_ci{
36668c2ecf20Sopenharmony_ci	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);
36678c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
36688c2ecf20Sopenharmony_ci
36698c2ecf20Sopenharmony_ci	/* First byte of the nonce = L = always 3 for RFC4309 (4 byte ctr) */
36708c2ecf20Sopenharmony_ci	*(u8 *)&ctx->nonce = EIP197_AEAD_IPSEC_COUNTER_SIZE - 1;
36718c2ecf20Sopenharmony_ci	/* last 3 bytes of key are the nonce! */
36728c2ecf20Sopenharmony_ci	memcpy((u8 *)&ctx->nonce + 1, key + len -
36738c2ecf20Sopenharmony_ci	       EIP197_AEAD_IPSEC_CCM_NONCE_SIZE,
36748c2ecf20Sopenharmony_ci	       EIP197_AEAD_IPSEC_CCM_NONCE_SIZE);
36758c2ecf20Sopenharmony_ci
36768c2ecf20Sopenharmony_ci	len -= EIP197_AEAD_IPSEC_CCM_NONCE_SIZE;
36778c2ecf20Sopenharmony_ci	return safexcel_aead_ccm_setkey(ctfm, key, len);
36788c2ecf20Sopenharmony_ci}
36798c2ecf20Sopenharmony_ci
36808c2ecf20Sopenharmony_cistatic int safexcel_rfc4309_ccm_setauthsize(struct crypto_aead *tfm,
36818c2ecf20Sopenharmony_ci					    unsigned int authsize)
36828c2ecf20Sopenharmony_ci{
36838c2ecf20Sopenharmony_ci	/* Borrowed from crypto/ccm.c */
36848c2ecf20Sopenharmony_ci	switch (authsize) {
36858c2ecf20Sopenharmony_ci	case 8:
36868c2ecf20Sopenharmony_ci	case 12:
36878c2ecf20Sopenharmony_ci	case 16:
36888c2ecf20Sopenharmony_ci		break;
36898c2ecf20Sopenharmony_ci	default:
36908c2ecf20Sopenharmony_ci		return -EINVAL;
36918c2ecf20Sopenharmony_ci	}
36928c2ecf20Sopenharmony_ci
36938c2ecf20Sopenharmony_ci	return 0;
36948c2ecf20Sopenharmony_ci}
36958c2ecf20Sopenharmony_ci
36968c2ecf20Sopenharmony_cistatic int safexcel_rfc4309_ccm_encrypt(struct aead_request *req)
36978c2ecf20Sopenharmony_ci{
36988c2ecf20Sopenharmony_ci	struct safexcel_cipher_req *creq = aead_request_ctx(req);
36998c2ecf20Sopenharmony_ci
37008c2ecf20Sopenharmony_ci	/* Borrowed from crypto/ccm.c */
37018c2ecf20Sopenharmony_ci	if (req->assoclen != 16 && req->assoclen != 20)
37028c2ecf20Sopenharmony_ci		return -EINVAL;
37038c2ecf20Sopenharmony_ci
37048c2ecf20Sopenharmony_ci	return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT);
37058c2ecf20Sopenharmony_ci}
37068c2ecf20Sopenharmony_ci
37078c2ecf20Sopenharmony_cistatic int safexcel_rfc4309_ccm_decrypt(struct aead_request *req)
37088c2ecf20Sopenharmony_ci{
37098c2ecf20Sopenharmony_ci	struct safexcel_cipher_req *creq = aead_request_ctx(req);
37108c2ecf20Sopenharmony_ci
37118c2ecf20Sopenharmony_ci	/* Borrowed from crypto/ccm.c */
37128c2ecf20Sopenharmony_ci	if (req->assoclen != 16 && req->assoclen != 20)
37138c2ecf20Sopenharmony_ci		return -EINVAL;
37148c2ecf20Sopenharmony_ci
37158c2ecf20Sopenharmony_ci	return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT);
37168c2ecf20Sopenharmony_ci}
37178c2ecf20Sopenharmony_ci
37188c2ecf20Sopenharmony_cistatic int safexcel_rfc4309_ccm_cra_init(struct crypto_tfm *tfm)
37198c2ecf20Sopenharmony_ci{
37208c2ecf20Sopenharmony_ci	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
37218c2ecf20Sopenharmony_ci	int ret;
37228c2ecf20Sopenharmony_ci
37238c2ecf20Sopenharmony_ci	ret = safexcel_aead_ccm_cra_init(tfm);
37248c2ecf20Sopenharmony_ci	ctx->aead  = EIP197_AEAD_TYPE_IPSEC_ESP;
37258c2ecf20Sopenharmony_ci	ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE;
37268c2ecf20Sopenharmony_ci	return ret;
37278c2ecf20Sopenharmony_ci}
37288c2ecf20Sopenharmony_ci
37298c2ecf20Sopenharmony_cistruct safexcel_alg_template safexcel_alg_rfc4309_ccm = {
37308c2ecf20Sopenharmony_ci	.type = SAFEXCEL_ALG_TYPE_AEAD,
37318c2ecf20Sopenharmony_ci	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL,
37328c2ecf20Sopenharmony_ci	.alg.aead = {
37338c2ecf20Sopenharmony_ci		.setkey = safexcel_rfc4309_ccm_setkey,
37348c2ecf20Sopenharmony_ci		.setauthsize = safexcel_rfc4309_ccm_setauthsize,
37358c2ecf20Sopenharmony_ci		.encrypt = safexcel_rfc4309_ccm_encrypt,
37368c2ecf20Sopenharmony_ci		.decrypt = safexcel_rfc4309_ccm_decrypt,
37378c2ecf20Sopenharmony_ci		.ivsize = EIP197_AEAD_IPSEC_IV_SIZE,
37388c2ecf20Sopenharmony_ci		.maxauthsize = AES_BLOCK_SIZE,
37398c2ecf20Sopenharmony_ci		.base = {
37408c2ecf20Sopenharmony_ci			.cra_name = "rfc4309(ccm(aes))",
37418c2ecf20Sopenharmony_ci			.cra_driver_name = "safexcel-rfc4309-ccm-aes",
37428c2ecf20Sopenharmony_ci			.cra_priority = SAFEXCEL_CRA_PRIORITY,
37438c2ecf20Sopenharmony_ci			.cra_flags = CRYPTO_ALG_ASYNC |
37448c2ecf20Sopenharmony_ci				     CRYPTO_ALG_ALLOCATES_MEMORY |
37458c2ecf20Sopenharmony_ci				     CRYPTO_ALG_KERN_DRIVER_ONLY,
37468c2ecf20Sopenharmony_ci			.cra_blocksize = 1,
37478c2ecf20Sopenharmony_ci			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
37488c2ecf20Sopenharmony_ci			.cra_alignmask = 0,
37498c2ecf20Sopenharmony_ci			.cra_init = safexcel_rfc4309_ccm_cra_init,
37508c2ecf20Sopenharmony_ci			.cra_exit = safexcel_aead_cra_exit,
37518c2ecf20Sopenharmony_ci			.cra_module = THIS_MODULE,
37528c2ecf20Sopenharmony_ci		},
37538c2ecf20Sopenharmony_ci	},
37548c2ecf20Sopenharmony_ci};
3755