1301422e3SAntoine Tenart // SPDX-License-Identifier: GPL-2.0
21b44c5a6SAntoine Ténart /*
31b44c5a6SAntoine Ténart  * Copyright (C) 2017 Marvell
41b44c5a6SAntoine Ténart  *
51b44c5a6SAntoine Ténart  * Antoine Tenart <antoine.tenart@free-electrons.com>
61b44c5a6SAntoine Ténart  */
71b44c5a6SAntoine Ténart 
84a593fb3SPascal van Leeuwen #include <asm/unaligned.h>
91b44c5a6SAntoine Ténart #include <linux/device.h>
101b44c5a6SAntoine Ténart #include <linux/dma-mapping.h>
111b44c5a6SAntoine Ténart #include <linux/dmapool.h>
12f6beaea3SAntoine Tenart #include <crypto/aead.h>
131b44c5a6SAntoine Ténart #include <crypto/aes.h>
14f6beaea3SAntoine Tenart #include <crypto/authenc.h>
154a593fb3SPascal van Leeuwen #include <crypto/chacha.h>
16f26882a3SPascal van Leeuwen #include <crypto/ctr.h>
1704007b0eSArd Biesheuvel #include <crypto/internal/des.h>
183e450886SPascal van Leeuwen #include <crypto/gcm.h>
193e450886SPascal van Leeuwen #include <crypto/ghash.h>
20a6061921SPascal van Leeuwen #include <crypto/poly1305.h>
21a24d22b2SEric Biggers #include <crypto/sha1.h>
22a24d22b2SEric Biggers #include <crypto/sha2.h>
231769f704SPascal van Leeuwen #include <crypto/sm3.h>
24fcca797dSPascal van Leeuwen #include <crypto/sm4.h>
25c7da38a7SPascal van Leeuwen #include <crypto/xts.h>
261b44c5a6SAntoine Ténart #include <crypto/skcipher.h>
27f6beaea3SAntoine Tenart #include <crypto/internal/aead.h>
281eb7b403SOfer Heifetz #include <crypto/internal/skcipher.h>
291b44c5a6SAntoine Ténart 
301b44c5a6SAntoine Ténart #include "safexcel.h"
311b44c5a6SAntoine Ténart 
321b44c5a6SAntoine Ténart enum safexcel_cipher_direction {
331b44c5a6SAntoine Ténart 	SAFEXCEL_ENCRYPT,
341b44c5a6SAntoine Ténart 	SAFEXCEL_DECRYPT,
351b44c5a6SAntoine Ténart };
361b44c5a6SAntoine Ténart 
37a7dea8c0SOfer Heifetz enum safexcel_cipher_alg {
38a7dea8c0SOfer Heifetz 	SAFEXCEL_DES,
3962469879SOfer Heifetz 	SAFEXCEL_3DES,
40a7dea8c0SOfer Heifetz 	SAFEXCEL_AES,
414a593fb3SPascal van Leeuwen 	SAFEXCEL_CHACHA20,
42fcca797dSPascal van Leeuwen 	SAFEXCEL_SM4,
43a7dea8c0SOfer Heifetz };
44a7dea8c0SOfer Heifetz 
451b44c5a6SAntoine Ténart struct safexcel_cipher_ctx {
461b44c5a6SAntoine Ténart 	struct safexcel_context base;
471b44c5a6SAntoine Ténart 	struct safexcel_crypto_priv *priv;
481b44c5a6SAntoine Ténart 
491b44c5a6SAntoine Ténart 	u32 mode;
50a7dea8c0SOfer Heifetz 	enum safexcel_cipher_alg alg;
51098e51e5SPascal van Leeuwen 	u8 aead; /* !=0=AEAD, 2=IPSec ESP AEAD, 3=IPsec ESP GMAC */
52098e51e5SPascal van Leeuwen 	u8 xcm;  /* 0=authenc, 1=GCM, 2 reserved for CCM */
53098e51e5SPascal van Leeuwen 	u8 aadskip;
54098e51e5SPascal van Leeuwen 	u8 blocksz;
55098e51e5SPascal van Leeuwen 	u32 ivmask;
56098e51e5SPascal van Leeuwen 	u32 ctrinit;
571b44c5a6SAntoine Ténart 
58c7da38a7SPascal van Leeuwen 	__le32 key[16];
5954f9e8faSPascal van Leeuwen 	u32 nonce;
60c7da38a7SPascal van Leeuwen 	unsigned int key_len, xts;
61f6beaea3SAntoine Tenart 
62f6beaea3SAntoine Tenart 	/* All the below is AEAD specific */
63a7dea8c0SOfer Heifetz 	u32 hash_alg;
64f6beaea3SAntoine Tenart 	u32 state_sz;
653e450886SPascal van Leeuwen 
66a6061921SPascal van Leeuwen 	struct crypto_aead *fback;
671b44c5a6SAntoine Ténart };
681b44c5a6SAntoine Ténart 
691eb7b403SOfer Heifetz struct safexcel_cipher_req {
70847ccfc5SOfer Heifetz 	enum safexcel_cipher_direction direction;
7189332590SAntoine Tenart 	/* Number of result descriptors associated to the request */
7289332590SAntoine Tenart 	unsigned int rdescs;
731eb7b403SOfer Heifetz 	bool needs_inv;
7419b347b3SPascal van Leeuwen 	int  nr_src, nr_dst;
751eb7b403SOfer Heifetz };
761eb7b403SOfer Heifetz 
safexcel_skcipher_iv(struct safexcel_cipher_ctx * ctx,u8 * iv,struct safexcel_command_desc * cdesc)77098e51e5SPascal van Leeuwen static int safexcel_skcipher_iv(struct safexcel_cipher_ctx *ctx, u8 *iv,
780e17e362SPascal van Leeuwen 				struct safexcel_command_desc *cdesc)
791b44c5a6SAntoine Ténart {
80098e51e5SPascal van Leeuwen 	if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) {
81493e289cSPascal van Leeuwen 		cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;
82493e289cSPascal van Leeuwen 		/* 32 bit nonce */
83493e289cSPascal van Leeuwen 		cdesc->control_data.token[0] = ctx->nonce;
84493e289cSPascal van Leeuwen 		/* 64 bit IV part */
85493e289cSPascal van Leeuwen 		memcpy(&cdesc->control_data.token[1], iv, 8);
86098e51e5SPascal van Leeuwen 		/* 32 bit counter, start at 0 or 1 (big endian!) */
8713a1bb93SPascal van Leeuwen 		cdesc->control_data.token[3] =
88098e51e5SPascal van Leeuwen 			(__force u32)cpu_to_be32(ctx->ctrinit);
89098e51e5SPascal van Leeuwen 		return 4;
90a19052d4SPascal van Leeuwen 	}
91a19052d4SPascal van Leeuwen 	if (ctx->alg == SAFEXCEL_CHACHA20) {
924a593fb3SPascal van Leeuwen 		cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;
934a593fb3SPascal van Leeuwen 		/* 96 bit nonce part */
944a593fb3SPascal van Leeuwen 		memcpy(&cdesc->control_data.token[0], &iv[4], 12);
954a593fb3SPascal van Leeuwen 		/* 32 bit counter */
964a593fb3SPascal van Leeuwen 		cdesc->control_data.token[3] = *(u32 *)iv;
97098e51e5SPascal van Leeuwen 		return 4;
98493e289cSPascal van Leeuwen 	}
99493e289cSPascal van Leeuwen 
100098e51e5SPascal van Leeuwen 	cdesc->control_data.options |= ctx->ivmask;
101098e51e5SPascal van Leeuwen 	memcpy(cdesc->control_data.token, iv, ctx->blocksz);
102098e51e5SPascal van Leeuwen 	return ctx->blocksz / sizeof(u32);
10354f9e8faSPascal van Leeuwen }
1040e17e362SPascal van Leeuwen 
safexcel_skcipher_token(struct safexcel_cipher_ctx * ctx,u8 * iv,struct safexcel_command_desc * cdesc,struct safexcel_token * atoken,u32 length)1050e17e362SPascal van Leeuwen static void safexcel_skcipher_token(struct safexcel_cipher_ctx *ctx, u8 *iv,
1060e17e362SPascal van Leeuwen 				    struct safexcel_command_desc *cdesc,
107098e51e5SPascal van Leeuwen 				    struct safexcel_token *atoken,
1080e17e362SPascal van Leeuwen 				    u32 length)
1090e17e362SPascal van Leeuwen {
1100e17e362SPascal van Leeuwen 	struct safexcel_token *token;
111098e51e5SPascal van Leeuwen 	int ivlen;
1120e17e362SPascal van Leeuwen 
113098e51e5SPascal van Leeuwen 	ivlen = safexcel_skcipher_iv(ctx, iv, cdesc);
114098e51e5SPascal van Leeuwen 	if (ivlen == 4) {
115098e51e5SPascal van Leeuwen 		/* No space in cdesc, instruction moves to atoken */
116098e51e5SPascal van Leeuwen 		cdesc->additional_cdata_size = 1;
117098e51e5SPascal van Leeuwen 		token = atoken;
118098e51e5SPascal van Leeuwen 	} else {
119098e51e5SPascal van Leeuwen 		/* Everything fits in cdesc */
120098e51e5SPascal van Leeuwen 		token = (struct safexcel_token *)(cdesc->control_data.token + 2);
121098e51e5SPascal van Leeuwen 		/* Need to pad with NOP */
122098e51e5SPascal van Leeuwen 		eip197_noop_token(&token[1]);
123098e51e5SPascal van Leeuwen 	}
1241b44c5a6SAntoine Ténart 
125098e51e5SPascal van Leeuwen 	token->opcode = EIP197_TOKEN_OPCODE_DIRECTION;
126098e51e5SPascal van Leeuwen 	token->packet_length = length;
127098e51e5SPascal van Leeuwen 	token->stat = EIP197_TOKEN_STAT_LAST_PACKET |
12815f64ee0SAntoine Tenart 		      EIP197_TOKEN_STAT_LAST_HASH;
129098e51e5SPascal van Leeuwen 	token->instructions = EIP197_TOKEN_INS_LAST |
130a74d850fSPascal van Leeuwen 			      EIP197_TOKEN_INS_TYPE_CRYPTO |
1311b44c5a6SAntoine Ténart 			      EIP197_TOKEN_INS_TYPE_OUTPUT;
1321b44c5a6SAntoine Ténart }
1331b44c5a6SAntoine Ténart 
safexcel_aead_iv(struct safexcel_cipher_ctx * ctx,u8 * iv,struct safexcel_command_desc * cdesc)134098e51e5SPascal van Leeuwen static void safexcel_aead_iv(struct safexcel_cipher_ctx *ctx, u8 *iv,
135098e51e5SPascal van Leeuwen 			     struct safexcel_command_desc *cdesc)
136098e51e5SPascal van Leeuwen {
137098e51e5SPascal van Leeuwen 	if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD ||
138098e51e5SPascal van Leeuwen 	    ctx->aead & EIP197_AEAD_TYPE_IPSEC_ESP) { /* _ESP and _ESP_GMAC */
139098e51e5SPascal van Leeuwen 		/* 32 bit nonce */
140098e51e5SPascal van Leeuwen 		cdesc->control_data.token[0] = ctx->nonce;
141098e51e5SPascal van Leeuwen 		/* 64 bit IV part */
142098e51e5SPascal van Leeuwen 		memcpy(&cdesc->control_data.token[1], iv, 8);
143098e51e5SPascal van Leeuwen 		/* 32 bit counter, start at 0 or 1 (big endian!) */
144098e51e5SPascal van Leeuwen 		cdesc->control_data.token[3] =
145098e51e5SPascal van Leeuwen 			(__force u32)cpu_to_be32(ctx->ctrinit);
146098e51e5SPascal van Leeuwen 		return;
147098e51e5SPascal van Leeuwen 	}
148098e51e5SPascal van Leeuwen 	if (ctx->xcm == EIP197_XCM_MODE_GCM || ctx->alg == SAFEXCEL_CHACHA20) {
149098e51e5SPascal van Leeuwen 		/* 96 bit IV part */
150098e51e5SPascal van Leeuwen 		memcpy(&cdesc->control_data.token[0], iv, 12);
151098e51e5SPascal van Leeuwen 		/* 32 bit counter, start at 0 or 1 (big endian!) */
152098e51e5SPascal van Leeuwen 		cdesc->control_data.token[3] =
153098e51e5SPascal van Leeuwen 			(__force u32)cpu_to_be32(ctx->ctrinit);
154098e51e5SPascal van Leeuwen 		return;
155098e51e5SPascal van Leeuwen 	}
156098e51e5SPascal van Leeuwen 	/* CBC */
157098e51e5SPascal van Leeuwen 	memcpy(cdesc->control_data.token, iv, ctx->blocksz);
158098e51e5SPascal van Leeuwen }
159098e51e5SPascal van Leeuwen 
safexcel_aead_token(struct safexcel_cipher_ctx * ctx,u8 * iv,struct safexcel_command_desc * cdesc,struct safexcel_token * atoken,enum safexcel_cipher_direction direction,u32 cryptlen,u32 assoclen,u32 digestsize)160f6beaea3SAntoine Tenart static void safexcel_aead_token(struct safexcel_cipher_ctx *ctx, u8 *iv,
161f6beaea3SAntoine Tenart 				struct safexcel_command_desc *cdesc,
162098e51e5SPascal van Leeuwen 				struct safexcel_token *atoken,
163f6beaea3SAntoine Tenart 				enum safexcel_cipher_direction direction,
164f6beaea3SAntoine Tenart 				u32 cryptlen, u32 assoclen, u32 digestsize)
165f6beaea3SAntoine Tenart {
166098e51e5SPascal van Leeuwen 	struct safexcel_token *aadref;
167098e51e5SPascal van Leeuwen 	int atoksize = 2; /* Start with minimum size */
168098e51e5SPascal van Leeuwen 	int assocadj = assoclen - ctx->aadskip, aadalign;
169f6beaea3SAntoine Tenart 
170098e51e5SPascal van Leeuwen 	/* Always 4 dwords of embedded IV  for AEAD modes */
171098e51e5SPascal van Leeuwen 	cdesc->control_data.options |= EIP197_OPTION_4_TOKEN_IV_CMD;
172f6beaea3SAntoine Tenart 
173098e51e5SPascal van Leeuwen 	if (direction == SAFEXCEL_DECRYPT)
174d2d9e6fdSPascal van Leeuwen 		cryptlen -= digestsize;
175d2d9e6fdSPascal van Leeuwen 
176098e51e5SPascal van Leeuwen 	if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM)) {
177098e51e5SPascal van Leeuwen 		/* Construct IV block B0 for the CBC-MAC */
178098e51e5SPascal van Leeuwen 		u8 *final_iv = (u8 *)cdesc->control_data.token;
179098e51e5SPascal van Leeuwen 		u8 *cbcmaciv = (u8 *)&atoken[1];
180098e51e5SPascal van Leeuwen 		__le32 *aadlen = (__le32 *)&atoken[5];
18154f9e8faSPascal van Leeuwen 
182098e51e5SPascal van Leeuwen 		if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) {
183098e51e5SPascal van Leeuwen 			/* Length + nonce */
184098e51e5SPascal van Leeuwen 			cdesc->control_data.token[0] = ctx->nonce;
185098e51e5SPascal van Leeuwen 			/* Fixup flags byte */
186098e51e5SPascal van Leeuwen 			*(__le32 *)cbcmaciv =
187098e51e5SPascal van Leeuwen 				cpu_to_le32(ctx->nonce |
188098e51e5SPascal van Leeuwen 					    ((assocadj > 0) << 6) |
189098e51e5SPascal van Leeuwen 					    ((digestsize - 2) << 2));
190098e51e5SPascal van Leeuwen 			/* 64 bit IV part */
191098e51e5SPascal van Leeuwen 			memcpy(&cdesc->control_data.token[1], iv, 8);
192098e51e5SPascal van Leeuwen 			memcpy(cbcmaciv + 4, iv, 8);
193098e51e5SPascal van Leeuwen 			/* Start counter at 0 */
194098e51e5SPascal van Leeuwen 			cdesc->control_data.token[3] = 0;
195098e51e5SPascal van Leeuwen 			/* Message length */
196098e51e5SPascal van Leeuwen 			*(__be32 *)(cbcmaciv + 12) = cpu_to_be32(cryptlen);
197098e51e5SPascal van Leeuwen 		} else {
198098e51e5SPascal van Leeuwen 			/* Variable length IV part */
199098e51e5SPascal van Leeuwen 			memcpy(final_iv, iv, 15 - iv[0]);
200098e51e5SPascal van Leeuwen 			memcpy(cbcmaciv, iv, 15 - iv[0]);
201098e51e5SPascal van Leeuwen 			/* Start variable length counter at 0 */
202098e51e5SPascal van Leeuwen 			memset(final_iv + 15 - iv[0], 0, iv[0] + 1);
203098e51e5SPascal van Leeuwen 			memset(cbcmaciv + 15 - iv[0], 0, iv[0] - 1);
204098e51e5SPascal van Leeuwen 			/* fixup flags byte */
205098e51e5SPascal van Leeuwen 			cbcmaciv[0] |= ((assocadj > 0) << 6) |
206098e51e5SPascal van Leeuwen 				       ((digestsize - 2) << 2);
207098e51e5SPascal van Leeuwen 			/* insert lower 2 bytes of message length */
208098e51e5SPascal van Leeuwen 			cbcmaciv[14] = cryptlen >> 8;
209098e51e5SPascal van Leeuwen 			cbcmaciv[15] = cryptlen & 255;
210f6beaea3SAntoine Tenart 		}
21154f9e8faSPascal van Leeuwen 
212098e51e5SPascal van Leeuwen 		atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;
213098e51e5SPascal van Leeuwen 		atoken->packet_length = AES_BLOCK_SIZE +
214098e51e5SPascal van Leeuwen 					((assocadj > 0) << 1);
215098e51e5SPascal van Leeuwen 		atoken->stat = 0;
216098e51e5SPascal van Leeuwen 		atoken->instructions = EIP197_TOKEN_INS_ORIGIN_TOKEN |
217098e51e5SPascal van Leeuwen 				       EIP197_TOKEN_INS_TYPE_HASH;
218098e51e5SPascal van Leeuwen 
219098e51e5SPascal van Leeuwen 		if (likely(assocadj)) {
220098e51e5SPascal van Leeuwen 			*aadlen = cpu_to_le32((assocadj >> 8) |
221098e51e5SPascal van Leeuwen 					      (assocadj & 255) << 8);
222098e51e5SPascal van Leeuwen 			atoken += 6;
223098e51e5SPascal van Leeuwen 			atoksize += 7;
224098e51e5SPascal van Leeuwen 		} else {
225098e51e5SPascal van Leeuwen 			atoken += 5;
226098e51e5SPascal van Leeuwen 			atoksize += 6;
227098e51e5SPascal van Leeuwen 		}
228098e51e5SPascal van Leeuwen 
229098e51e5SPascal van Leeuwen 		/* Process AAD data */
230098e51e5SPascal van Leeuwen 		aadref = atoken;
231098e51e5SPascal van Leeuwen 		atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION;
232098e51e5SPascal van Leeuwen 		atoken->packet_length = assocadj;
233098e51e5SPascal van Leeuwen 		atoken->stat = 0;
234098e51e5SPascal van Leeuwen 		atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH;
235098e51e5SPascal van Leeuwen 		atoken++;
236098e51e5SPascal van Leeuwen 
237098e51e5SPascal van Leeuwen 		/* For CCM only, align AAD data towards hash engine */
238098e51e5SPascal van Leeuwen 		atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;
239098e51e5SPascal van Leeuwen 		aadalign = (assocadj + 2) & 15;
240098e51e5SPascal van Leeuwen 		atoken->packet_length = assocadj && aadalign ?
241098e51e5SPascal van Leeuwen 						16 - aadalign :
242098e51e5SPascal van Leeuwen 						0;
243098e51e5SPascal van Leeuwen 		if (likely(cryptlen)) {
244098e51e5SPascal van Leeuwen 			atoken->stat = 0;
245098e51e5SPascal van Leeuwen 			atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH;
246098e51e5SPascal van Leeuwen 		} else {
247098e51e5SPascal van Leeuwen 			atoken->stat = EIP197_TOKEN_STAT_LAST_HASH;
248098e51e5SPascal van Leeuwen 			atoken->instructions = EIP197_TOKEN_INS_LAST |
249098e51e5SPascal van Leeuwen 					       EIP197_TOKEN_INS_TYPE_HASH;
250098e51e5SPascal van Leeuwen 		}
251098e51e5SPascal van Leeuwen 	} else {
252098e51e5SPascal van Leeuwen 		safexcel_aead_iv(ctx, iv, cdesc);
253098e51e5SPascal van Leeuwen 
254098e51e5SPascal van Leeuwen 		/* Process AAD data */
255098e51e5SPascal van Leeuwen 		aadref = atoken;
256098e51e5SPascal van Leeuwen 		atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION;
257098e51e5SPascal van Leeuwen 		atoken->packet_length = assocadj;
258098e51e5SPascal van Leeuwen 		atoken->stat = EIP197_TOKEN_STAT_LAST_HASH;
259098e51e5SPascal van Leeuwen 		atoken->instructions = EIP197_TOKEN_INS_LAST |
260098e51e5SPascal van Leeuwen 				       EIP197_TOKEN_INS_TYPE_HASH;
261098e51e5SPascal van Leeuwen 	}
262098e51e5SPascal van Leeuwen 	atoken++;
263098e51e5SPascal van Leeuwen 
264a6061921SPascal van Leeuwen 	if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) {
26592c60cefSPascal van Leeuwen 		/* For ESP mode (and not GMAC), skip over the IV */
266098e51e5SPascal van Leeuwen 		atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION;
267098e51e5SPascal van Leeuwen 		atoken->packet_length = EIP197_AEAD_IPSEC_IV_SIZE;
268098e51e5SPascal van Leeuwen 		atoken->stat = 0;
269098e51e5SPascal van Leeuwen 		atoken->instructions = 0;
270098e51e5SPascal van Leeuwen 		atoken++;
271098e51e5SPascal van Leeuwen 		atoksize++;
272098e51e5SPascal van Leeuwen 	} else if (unlikely(ctx->alg == SAFEXCEL_CHACHA20 &&
273098e51e5SPascal van Leeuwen 			    direction == SAFEXCEL_DECRYPT)) {
274098e51e5SPascal van Leeuwen 		/* Poly-chacha decryption needs a dummy NOP here ... */
275098e51e5SPascal van Leeuwen 		atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;
276098e51e5SPascal van Leeuwen 		atoken->packet_length = 16; /* According to Op Manual */
277098e51e5SPascal van Leeuwen 		atoken->stat = 0;
278098e51e5SPascal van Leeuwen 		atoken->instructions = 0;
279098e51e5SPascal van Leeuwen 		atoken++;
280098e51e5SPascal van Leeuwen 		atoksize++;
281a6061921SPascal van Leeuwen 	}
282a6061921SPascal van Leeuwen 
283098e51e5SPascal van Leeuwen 	if  (ctx->xcm) {
284098e51e5SPascal van Leeuwen 		/* For GCM and CCM, obtain enc(Y0) */
285098e51e5SPascal van Leeuwen 		atoken->opcode = EIP197_TOKEN_OPCODE_INSERT_REMRES;
286098e51e5SPascal van Leeuwen 		atoken->packet_length = 0;
287098e51e5SPascal van Leeuwen 		atoken->stat = 0;
288098e51e5SPascal van Leeuwen 		atoken->instructions = AES_BLOCK_SIZE;
289098e51e5SPascal van Leeuwen 		atoken++;
290098e51e5SPascal van Leeuwen 
291098e51e5SPascal van Leeuwen 		atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;
292098e51e5SPascal van Leeuwen 		atoken->packet_length = AES_BLOCK_SIZE;
293098e51e5SPascal van Leeuwen 		atoken->stat = 0;
294098e51e5SPascal van Leeuwen 		atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT |
295098e51e5SPascal van Leeuwen 				       EIP197_TOKEN_INS_TYPE_CRYPTO;
296098e51e5SPascal van Leeuwen 		atoken++;
297098e51e5SPascal van Leeuwen 		atoksize += 2;
298098e51e5SPascal van Leeuwen 	}
29954f9e8faSPascal van Leeuwen 
300a6061921SPascal van Leeuwen 	if (likely(cryptlen || ctx->alg == SAFEXCEL_CHACHA20)) {
301098e51e5SPascal van Leeuwen 		/* Fixup stat field for AAD direction instruction */
302098e51e5SPascal van Leeuwen 		aadref->stat = 0;
303098e51e5SPascal van Leeuwen 
304098e51e5SPascal van Leeuwen 		/* Process crypto data */
305098e51e5SPascal van Leeuwen 		atoken->opcode = EIP197_TOKEN_OPCODE_DIRECTION;
306098e51e5SPascal van Leeuwen 		atoken->packet_length = cryptlen;
307098e51e5SPascal van Leeuwen 
30892c60cefSPascal van Leeuwen 		if (unlikely(ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC)) {
309098e51e5SPascal van Leeuwen 			/* Fixup instruction field for AAD dir instruction */
310098e51e5SPascal van Leeuwen 			aadref->instructions = EIP197_TOKEN_INS_TYPE_HASH;
311098e51e5SPascal van Leeuwen 
31292c60cefSPascal van Leeuwen 			/* Do not send to crypt engine in case of GMAC */
313098e51e5SPascal van Leeuwen 			atoken->instructions = EIP197_TOKEN_INS_LAST |
31492c60cefSPascal van Leeuwen 					       EIP197_TOKEN_INS_TYPE_HASH |
31592c60cefSPascal van Leeuwen 					       EIP197_TOKEN_INS_TYPE_OUTPUT;
31692c60cefSPascal van Leeuwen 		} else {
317098e51e5SPascal van Leeuwen 			atoken->instructions = EIP197_TOKEN_INS_LAST |
31854f9e8faSPascal van Leeuwen 					       EIP197_TOKEN_INS_TYPE_CRYPTO |
31954f9e8faSPascal van Leeuwen 					       EIP197_TOKEN_INS_TYPE_HASH |
32054f9e8faSPascal van Leeuwen 					       EIP197_TOKEN_INS_TYPE_OUTPUT;
32192c60cefSPascal van Leeuwen 		}
3223e450886SPascal van Leeuwen 
3234eb76fafSPascal van Leeuwen 		cryptlen &= 15;
324098e51e5SPascal van Leeuwen 		if (unlikely(ctx->xcm == EIP197_XCM_MODE_CCM && cryptlen)) {
325098e51e5SPascal van Leeuwen 			atoken->stat = 0;
326098e51e5SPascal van Leeuwen 			/* For CCM only, pad crypto data to the hash engine */
327098e51e5SPascal van Leeuwen 			atoken++;
328098e51e5SPascal van Leeuwen 			atoksize++;
329098e51e5SPascal van Leeuwen 			atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;
330098e51e5SPascal van Leeuwen 			atoken->packet_length = 16 - cryptlen;
331098e51e5SPascal van Leeuwen 			atoken->stat = EIP197_TOKEN_STAT_LAST_HASH;
332098e51e5SPascal van Leeuwen 			atoken->instructions = EIP197_TOKEN_INS_TYPE_HASH;
3334eb76fafSPascal van Leeuwen 		} else {
334098e51e5SPascal van Leeuwen 			atoken->stat = EIP197_TOKEN_STAT_LAST_HASH;
3354eb76fafSPascal van Leeuwen 		}
336098e51e5SPascal van Leeuwen 		atoken++;
337098e51e5SPascal van Leeuwen 		atoksize++;
3383e450886SPascal van Leeuwen 	}
339098e51e5SPascal van Leeuwen 
340098e51e5SPascal van Leeuwen 	if (direction == SAFEXCEL_ENCRYPT) {
341098e51e5SPascal van Leeuwen 		/* Append ICV */
342098e51e5SPascal van Leeuwen 		atoken->opcode = EIP197_TOKEN_OPCODE_INSERT;
343098e51e5SPascal van Leeuwen 		atoken->packet_length = digestsize;
344098e51e5SPascal van Leeuwen 		atoken->stat = EIP197_TOKEN_STAT_LAST_HASH |
345098e51e5SPascal van Leeuwen 			       EIP197_TOKEN_STAT_LAST_PACKET;
346098e51e5SPascal van Leeuwen 		atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT |
347098e51e5SPascal van Leeuwen 				       EIP197_TOKEN_INS_INSERT_HASH_DIGEST;
348098e51e5SPascal van Leeuwen 	} else {
349098e51e5SPascal van Leeuwen 		/* Extract ICV */
350098e51e5SPascal van Leeuwen 		atoken->opcode = EIP197_TOKEN_OPCODE_RETRIEVE;
351098e51e5SPascal van Leeuwen 		atoken->packet_length = digestsize;
352098e51e5SPascal van Leeuwen 		atoken->stat = EIP197_TOKEN_STAT_LAST_HASH |
353098e51e5SPascal van Leeuwen 			       EIP197_TOKEN_STAT_LAST_PACKET;
354098e51e5SPascal van Leeuwen 		atoken->instructions = EIP197_TOKEN_INS_INSERT_HASH_DIGEST;
355098e51e5SPascal van Leeuwen 		atoken++;
356098e51e5SPascal van Leeuwen 		atoksize++;
357098e51e5SPascal van Leeuwen 
358098e51e5SPascal van Leeuwen 		/* Verify ICV */
359098e51e5SPascal van Leeuwen 		atoken->opcode = EIP197_TOKEN_OPCODE_VERIFY;
360098e51e5SPascal van Leeuwen 		atoken->packet_length = digestsize |
361098e51e5SPascal van Leeuwen 					EIP197_TOKEN_HASH_RESULT_VERIFY;
362098e51e5SPascal van Leeuwen 		atoken->stat = EIP197_TOKEN_STAT_LAST_HASH |
363098e51e5SPascal van Leeuwen 			       EIP197_TOKEN_STAT_LAST_PACKET;
364098e51e5SPascal van Leeuwen 		atoken->instructions = EIP197_TOKEN_INS_TYPE_OUTPUT;
365098e51e5SPascal van Leeuwen 	}
366098e51e5SPascal van Leeuwen 
367098e51e5SPascal van Leeuwen 	/* Fixup length of the token in the command descriptor */
368098e51e5SPascal van Leeuwen 	cdesc->additional_cdata_size = atoksize;
369f6beaea3SAntoine Tenart }
370f6beaea3SAntoine Tenart 
safexcel_skcipher_aes_setkey(struct crypto_skcipher * ctfm,const u8 * key,unsigned int len)3718ac1283eSAntoine Tenart static int safexcel_skcipher_aes_setkey(struct crypto_skcipher *ctfm,
3728ac1283eSAntoine Tenart 					const u8 *key, unsigned int len)
3731b44c5a6SAntoine Ténart {
3741b44c5a6SAntoine Ténart 	struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);
3751b44c5a6SAntoine Ténart 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
37618e51895SHerbert Xu 	struct safexcel_crypto_priv *priv = ctx->base.priv;
3771b44c5a6SAntoine Ténart 	struct crypto_aes_ctx aes;
3781b44c5a6SAntoine Ténart 	int ret, i;
3791b44c5a6SAntoine Ténart 
380363a90c2SArd Biesheuvel 	ret = aes_expandkey(&aes, key, len);
381674f368aSEric Biggers 	if (ret)
3821b44c5a6SAntoine Ténart 		return ret;
3831b44c5a6SAntoine Ténart 
38453c83e91SAntoine Tenart 	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
3851b44c5a6SAntoine Ténart 		for (i = 0; i < len / sizeof(u32); i++) {
38613a1bb93SPascal van Leeuwen 			if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {
3871b44c5a6SAntoine Ténart 				ctx->base.needs_inv = true;
3881b44c5a6SAntoine Ténart 				break;
3891b44c5a6SAntoine Ténart 			}
3901b44c5a6SAntoine Ténart 		}
391c4daf4ccSOfer Heifetz 	}
3921b44c5a6SAntoine Ténart 
3931b44c5a6SAntoine Ténart 	for (i = 0; i < len / sizeof(u32); i++)
3941b44c5a6SAntoine Ténart 		ctx->key[i] = cpu_to_le32(aes.key_enc[i]);
3951b44c5a6SAntoine Ténart 
3961b44c5a6SAntoine Ténart 	ctx->key_len = len;
3971b44c5a6SAntoine Ténart 
3981b44c5a6SAntoine Ténart 	memzero_explicit(&aes, sizeof(aes));
3991b44c5a6SAntoine Ténart 	return 0;
4001b44c5a6SAntoine Ténart }
4011b44c5a6SAntoine Ténart 
safexcel_aead_setkey(struct crypto_aead * ctfm,const u8 * key,unsigned int len)40277cdd4efSPascal van Leeuwen static int safexcel_aead_setkey(struct crypto_aead *ctfm, const u8 *key,
403f6beaea3SAntoine Tenart 				unsigned int len)
404f6beaea3SAntoine Tenart {
405f6beaea3SAntoine Tenart 	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);
406f6beaea3SAntoine Tenart 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
40718e51895SHerbert Xu 	struct safexcel_crypto_priv *priv = ctx->base.priv;
408f6beaea3SAntoine Tenart 	struct crypto_authenc_keys keys;
4090e17e362SPascal van Leeuwen 	struct crypto_aes_ctx aes;
41013a1bb93SPascal van Leeuwen 	int err = -EINVAL, i;
41163cdd870SHerbert Xu 	const char *alg;
412f6beaea3SAntoine Tenart 
4131769f704SPascal van Leeuwen 	if (unlikely(crypto_authenc_extractkeys(&keys, key, len)))
414f6beaea3SAntoine Tenart 		goto badkey;
415f6beaea3SAntoine Tenart 
4160e17e362SPascal van Leeuwen 	if (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD) {
4171769f704SPascal van Leeuwen 		/* Must have at least space for the nonce here */
4181769f704SPascal van Leeuwen 		if (unlikely(keys.enckeylen < CTR_RFC3686_NONCE_SIZE))
419f6beaea3SAntoine Tenart 			goto badkey;
4200e17e362SPascal van Leeuwen 		/* last 4 bytes of key are the nonce! */
421f26882a3SPascal van Leeuwen 		ctx->nonce = *(u32 *)(keys.enckey + keys.enckeylen -
422f26882a3SPascal van Leeuwen 				      CTR_RFC3686_NONCE_SIZE);
4230e17e362SPascal van Leeuwen 		/* exclude the nonce here */
4241769f704SPascal van Leeuwen 		keys.enckeylen -= CTR_RFC3686_NONCE_SIZE;
4250e17e362SPascal van Leeuwen 	}
426f6beaea3SAntoine Tenart 
427f6beaea3SAntoine Tenart 	/* Encryption key */
4280e17e362SPascal van Leeuwen 	switch (ctx->alg) {
429bb7679b8SPascal van Leeuwen 	case SAFEXCEL_DES:
430bb7679b8SPascal van Leeuwen 		err = verify_aead_des_key(ctfm, keys.enckey, keys.enckeylen);
431bb7679b8SPascal van Leeuwen 		if (unlikely(err))
432674f368aSEric Biggers 			goto badkey;
433bb7679b8SPascal van Leeuwen 		break;
4340e17e362SPascal van Leeuwen 	case SAFEXCEL_3DES:
43521f5a15eSArd Biesheuvel 		err = verify_aead_des3_key(ctfm, keys.enckey, keys.enckeylen);
43677cdd4efSPascal van Leeuwen 		if (unlikely(err))
437674f368aSEric Biggers 			goto badkey;
4380e17e362SPascal van Leeuwen 		break;
4390e17e362SPascal van Leeuwen 	case SAFEXCEL_AES:
4400e17e362SPascal van Leeuwen 		err = aes_expandkey(&aes, keys.enckey, keys.enckeylen);
4410e17e362SPascal van Leeuwen 		if (unlikely(err))
4420e17e362SPascal van Leeuwen 			goto badkey;
4430e17e362SPascal van Leeuwen 		break;
4441769f704SPascal van Leeuwen 	case SAFEXCEL_SM4:
4451769f704SPascal van Leeuwen 		if (unlikely(keys.enckeylen != SM4_KEY_SIZE))
4461769f704SPascal van Leeuwen 			goto badkey;
4471769f704SPascal van Leeuwen 		break;
4480e17e362SPascal van Leeuwen 	default:
4490e17e362SPascal van Leeuwen 		dev_err(priv->dev, "aead: unsupported cipher algorithm\n");
4500e17e362SPascal van Leeuwen 		goto badkey;
45177cdd4efSPascal van Leeuwen 	}
45277cdd4efSPascal van Leeuwen 
45313a1bb93SPascal van Leeuwen 	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
45413a1bb93SPascal van Leeuwen 		for (i = 0; i < keys.enckeylen / sizeof(u32); i++) {
455b8151220SPascal van Leeuwen 			if (le32_to_cpu(ctx->key[i]) !=
456b8151220SPascal van Leeuwen 			    ((u32 *)keys.enckey)[i]) {
457f6beaea3SAntoine Tenart 				ctx->base.needs_inv = true;
45813a1bb93SPascal van Leeuwen 				break;
45913a1bb93SPascal van Leeuwen 			}
46013a1bb93SPascal van Leeuwen 		}
46113a1bb93SPascal van Leeuwen 	}
462f6beaea3SAntoine Tenart 
463f6beaea3SAntoine Tenart 	/* Auth key */
464a7dea8c0SOfer Heifetz 	switch (ctx->hash_alg) {
46501ba061dSAntoine Tenart 	case CONTEXT_CONTROL_CRYPTO_ALG_SHA1:
46663cdd870SHerbert Xu 		alg = "safexcel-sha1";
46701ba061dSAntoine Tenart 		break;
468678b2878SAntoine Tenart 	case CONTEXT_CONTROL_CRYPTO_ALG_SHA224:
46963cdd870SHerbert Xu 		alg = "safexcel-sha224";
470678b2878SAntoine Tenart 		break;
471678b2878SAntoine Tenart 	case CONTEXT_CONTROL_CRYPTO_ALG_SHA256:
47263cdd870SHerbert Xu 		alg = "safexcel-sha256";
473678b2878SAntoine Tenart 		break;
474ea23cb53SAntoine Tenart 	case CONTEXT_CONTROL_CRYPTO_ALG_SHA384:
47563cdd870SHerbert Xu 		alg = "safexcel-sha384";
476ea23cb53SAntoine Tenart 		break;
47787eee125SAntoine Tenart 	case CONTEXT_CONTROL_CRYPTO_ALG_SHA512:
47863cdd870SHerbert Xu 		alg = "safexcel-sha512";
47987eee125SAntoine Tenart 		break;
4801769f704SPascal van Leeuwen 	case CONTEXT_CONTROL_CRYPTO_ALG_SM3:
48163cdd870SHerbert Xu 		alg = "safexcel-sm3";
4821769f704SPascal van Leeuwen 		break;
483678b2878SAntoine Tenart 	default:
4841a61af28SColin Ian King 		dev_err(priv->dev, "aead: unsupported hash algorithm\n");
485678b2878SAntoine Tenart 		goto badkey;
486678b2878SAntoine Tenart 	}
487f6beaea3SAntoine Tenart 
48863cdd870SHerbert Xu 	if (safexcel_hmac_setkey(&ctx->base, keys.authkey, keys.authkeylen,
48963cdd870SHerbert Xu 				 alg, ctx->state_sz))
49063cdd870SHerbert Xu 		goto badkey;
491f6beaea3SAntoine Tenart 
492f6beaea3SAntoine Tenart 	/* Now copy the keys into the context */
49313a1bb93SPascal van Leeuwen 	for (i = 0; i < keys.enckeylen / sizeof(u32); i++)
494b8151220SPascal van Leeuwen 		ctx->key[i] = cpu_to_le32(((u32 *)keys.enckey)[i]);
495f6beaea3SAntoine Tenart 	ctx->key_len = keys.enckeylen;
496f6beaea3SAntoine Tenart 
497f6beaea3SAntoine Tenart 	memzero_explicit(&keys, sizeof(keys));
498f6beaea3SAntoine Tenart 	return 0;
499f6beaea3SAntoine Tenart 
500f6beaea3SAntoine Tenart badkey:
501f6beaea3SAntoine Tenart 	memzero_explicit(&keys, sizeof(keys));
5020e17e362SPascal van Leeuwen 	return err;
503f6beaea3SAntoine Tenart }
504f6beaea3SAntoine Tenart 
safexcel_context_control(struct safexcel_cipher_ctx * ctx,struct crypto_async_request * async,struct safexcel_cipher_req * sreq,struct safexcel_command_desc * cdesc)5051b44c5a6SAntoine Ténart static int safexcel_context_control(struct safexcel_cipher_ctx *ctx,
506847ccfc5SOfer Heifetz 				    struct crypto_async_request *async,
5078ac1283eSAntoine Tenart 				    struct safexcel_cipher_req *sreq,
5081b44c5a6SAntoine Ténart 				    struct safexcel_command_desc *cdesc)
5091b44c5a6SAntoine Ténart {
51018e51895SHerbert Xu 	struct safexcel_crypto_priv *priv = ctx->base.priv;
511d2d9e6fdSPascal van Leeuwen 	int ctrl_size = ctx->key_len / sizeof(u32);
512d2d9e6fdSPascal van Leeuwen 
513d2d9e6fdSPascal van Leeuwen 	cdesc->control_data.control1 = ctx->mode;
5141b44c5a6SAntoine Ténart 
515f6beaea3SAntoine Tenart 	if (ctx->aead) {
516d2d9e6fdSPascal van Leeuwen 		/* Take in account the ipad+opad digests */
5173e450886SPascal van Leeuwen 		if (ctx->xcm) {
5183e450886SPascal van Leeuwen 			ctrl_size += ctx->state_sz / sizeof(u32);
5193e450886SPascal van Leeuwen 			cdesc->control_data.control0 =
5203e450886SPascal van Leeuwen 				CONTEXT_CONTROL_KEY_EN |
5213e450886SPascal van Leeuwen 				CONTEXT_CONTROL_DIGEST_XCM |
5223e450886SPascal van Leeuwen 				ctx->hash_alg |
5233e450886SPascal van Leeuwen 				CONTEXT_CONTROL_SIZE(ctrl_size);
524a6061921SPascal van Leeuwen 		} else if (ctx->alg == SAFEXCEL_CHACHA20) {
525a6061921SPascal van Leeuwen 			/* Chacha20-Poly1305 */
526a6061921SPascal van Leeuwen 			cdesc->control_data.control0 =
527a6061921SPascal van Leeuwen 				CONTEXT_CONTROL_KEY_EN |
528a6061921SPascal van Leeuwen 				CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20 |
529a6061921SPascal van Leeuwen 				(sreq->direction == SAFEXCEL_ENCRYPT ?
530a6061921SPascal van Leeuwen 					CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT :
531a6061921SPascal van Leeuwen 					CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN) |
532a6061921SPascal van Leeuwen 				ctx->hash_alg |
533a6061921SPascal van Leeuwen 				CONTEXT_CONTROL_SIZE(ctrl_size);
534a6061921SPascal van Leeuwen 			return 0;
5353e450886SPascal van Leeuwen 		} else {
536d2d9e6fdSPascal van Leeuwen 			ctrl_size += ctx->state_sz / sizeof(u32) * 2;
5373e450886SPascal van Leeuwen 			cdesc->control_data.control0 =
5383e450886SPascal van Leeuwen 				CONTEXT_CONTROL_KEY_EN |
5393e450886SPascal van Leeuwen 				CONTEXT_CONTROL_DIGEST_HMAC |
5403e450886SPascal van Leeuwen 				ctx->hash_alg |
5413e450886SPascal van Leeuwen 				CONTEXT_CONTROL_SIZE(ctrl_size);
5423e450886SPascal van Leeuwen 		}
5434eb76fafSPascal van Leeuwen 
54492c60cefSPascal van Leeuwen 		if (sreq->direction == SAFEXCEL_ENCRYPT &&
54592c60cefSPascal van Leeuwen 		    (ctx->xcm == EIP197_XCM_MODE_CCM ||
54692c60cefSPascal van Leeuwen 		     ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP_GMAC))
54792c60cefSPascal van Leeuwen 			cdesc->control_data.control0 |=
54892c60cefSPascal van Leeuwen 				CONTEXT_CONTROL_TYPE_HASH_ENCRYPT_OUT;
54992c60cefSPascal van Leeuwen 		else if (sreq->direction == SAFEXCEL_ENCRYPT)
55092c60cefSPascal van Leeuwen 			cdesc->control_data.control0 |=
55192c60cefSPascal van Leeuwen 				CONTEXT_CONTROL_TYPE_ENCRYPT_HASH_OUT;
55292c60cefSPascal van Leeuwen 		else if (ctx->xcm == EIP197_XCM_MODE_CCM)
55392c60cefSPascal van Leeuwen 			cdesc->control_data.control0 |=
55492c60cefSPascal van Leeuwen 				CONTEXT_CONTROL_TYPE_DECRYPT_HASH_IN;
555d2d9e6fdSPascal van Leeuwen 		else
5563e450886SPascal van Leeuwen 			cdesc->control_data.control0 |=
5573e450886SPascal van Leeuwen 				CONTEXT_CONTROL_TYPE_HASH_DECRYPT_IN;
558d2d9e6fdSPascal van Leeuwen 	} else {
559d2d9e6fdSPascal van Leeuwen 		if (sreq->direction == SAFEXCEL_ENCRYPT)
560d2d9e6fdSPascal van Leeuwen 			cdesc->control_data.control0 =
561d2d9e6fdSPascal van Leeuwen 				CONTEXT_CONTROL_TYPE_CRYPTO_OUT |
562d2d9e6fdSPascal van Leeuwen 				CONTEXT_CONTROL_KEY_EN |
563d2d9e6fdSPascal van Leeuwen 				CONTEXT_CONTROL_SIZE(ctrl_size);
564d2d9e6fdSPascal van Leeuwen 		else
565d2d9e6fdSPascal van Leeuwen 			cdesc->control_data.control0 =
566d2d9e6fdSPascal van Leeuwen 				CONTEXT_CONTROL_TYPE_CRYPTO_IN |
567d2d9e6fdSPascal van Leeuwen 				CONTEXT_CONTROL_KEY_EN |
568d2d9e6fdSPascal van Leeuwen 				CONTEXT_CONTROL_SIZE(ctrl_size);
569f6beaea3SAntoine Tenart 	}
5701b44c5a6SAntoine Ténart 
571a7dea8c0SOfer Heifetz 	if (ctx->alg == SAFEXCEL_DES) {
572d2d9e6fdSPascal van Leeuwen 		cdesc->control_data.control0 |=
573d2d9e6fdSPascal van Leeuwen 			CONTEXT_CONTROL_CRYPTO_ALG_DES;
57462469879SOfer Heifetz 	} else if (ctx->alg == SAFEXCEL_3DES) {
575d2d9e6fdSPascal van Leeuwen 		cdesc->control_data.control0 |=
576d2d9e6fdSPascal van Leeuwen 			CONTEXT_CONTROL_CRYPTO_ALG_3DES;
577a7dea8c0SOfer Heifetz 	} else if (ctx->alg == SAFEXCEL_AES) {
578c7da38a7SPascal van Leeuwen 		switch (ctx->key_len >> ctx->xts) {
5791b44c5a6SAntoine Ténart 		case AES_KEYSIZE_128:
580d2d9e6fdSPascal van Leeuwen 			cdesc->control_data.control0 |=
581d2d9e6fdSPascal van Leeuwen 				CONTEXT_CONTROL_CRYPTO_ALG_AES128;
5821b44c5a6SAntoine Ténart 			break;
5831b44c5a6SAntoine Ténart 		case AES_KEYSIZE_192:
584d2d9e6fdSPascal van Leeuwen 			cdesc->control_data.control0 |=
585d2d9e6fdSPascal van Leeuwen 				CONTEXT_CONTROL_CRYPTO_ALG_AES192;
5861b44c5a6SAntoine Ténart 			break;
5871b44c5a6SAntoine Ténart 		case AES_KEYSIZE_256:
588d2d9e6fdSPascal van Leeuwen 			cdesc->control_data.control0 |=
589d2d9e6fdSPascal van Leeuwen 				CONTEXT_CONTROL_CRYPTO_ALG_AES256;
5901b44c5a6SAntoine Ténart 			break;
5911b44c5a6SAntoine Ténart 		default:
5921b44c5a6SAntoine Ténart 			dev_err(priv->dev, "aes keysize not supported: %u\n",
593c7da38a7SPascal van Leeuwen 				ctx->key_len >> ctx->xts);
5941b44c5a6SAntoine Ténart 			return -EINVAL;
5951b44c5a6SAntoine Ténart 		}
5964a593fb3SPascal van Leeuwen 	} else if (ctx->alg == SAFEXCEL_CHACHA20) {
5974a593fb3SPascal van Leeuwen 		cdesc->control_data.control0 |=
5984a593fb3SPascal van Leeuwen 			CONTEXT_CONTROL_CRYPTO_ALG_CHACHA20;
599fcca797dSPascal van Leeuwen 	} else if (ctx->alg == SAFEXCEL_SM4) {
600fcca797dSPascal van Leeuwen 		cdesc->control_data.control0 |=
601fcca797dSPascal van Leeuwen 			CONTEXT_CONTROL_CRYPTO_ALG_SM4;
602a7dea8c0SOfer Heifetz 	}
603fef0cfe5SAntoine Tenart 
6041b44c5a6SAntoine Ténart 	return 0;
6051b44c5a6SAntoine Ténart }
6061b44c5a6SAntoine Ténart 
safexcel_handle_req_result(struct safexcel_crypto_priv * priv,int ring,struct crypto_async_request * async,struct scatterlist * src,struct scatterlist * dst,unsigned int cryptlen,struct safexcel_cipher_req * sreq,bool * should_complete,int * ret)6071eb7b403SOfer Heifetz static int safexcel_handle_req_result(struct safexcel_crypto_priv *priv, int ring,
6081b44c5a6SAntoine Ténart 				      struct crypto_async_request *async,
6098ac1283eSAntoine Tenart 				      struct scatterlist *src,
6108ac1283eSAntoine Tenart 				      struct scatterlist *dst,
6118ac1283eSAntoine Tenart 				      unsigned int cryptlen,
6128ac1283eSAntoine Tenart 				      struct safexcel_cipher_req *sreq,
6131b44c5a6SAntoine Ténart 				      bool *should_complete, int *ret)
6141b44c5a6SAntoine Ténart {
6155bdb6e6aSPascal van Leeuwen 	struct skcipher_request *areq = skcipher_request_cast(async);
6165bdb6e6aSPascal van Leeuwen 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(areq);
6175bdb6e6aSPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(skcipher);
6181b44c5a6SAntoine Ténart 	struct safexcel_result_desc *rdesc;
6191b44c5a6SAntoine Ténart 	int ndesc = 0;
6201b44c5a6SAntoine Ténart 
6211b44c5a6SAntoine Ténart 	*ret = 0;
6221b44c5a6SAntoine Ténart 
62389332590SAntoine Tenart 	if (unlikely(!sreq->rdescs))
62489332590SAntoine Tenart 		return 0;
62589332590SAntoine Tenart 
62689332590SAntoine Tenart 	while (sreq->rdescs--) {
6271b44c5a6SAntoine Ténart 		rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr);
6281b44c5a6SAntoine Ténart 		if (IS_ERR(rdesc)) {
6291b44c5a6SAntoine Ténart 			dev_err(priv->dev,
6301b44c5a6SAntoine Ténart 				"cipher: result: could not retrieve the result descriptor\n");
6311b44c5a6SAntoine Ténart 			*ret = PTR_ERR(rdesc);
6321b44c5a6SAntoine Ténart 			break;
6331b44c5a6SAntoine Ténart 		}
6341b44c5a6SAntoine Ténart 
635bdfd1909SAntoine Tenart 		if (likely(!*ret))
636bdfd1909SAntoine Tenart 			*ret = safexcel_rdesc_check_errors(priv, rdesc);
6371b44c5a6SAntoine Ténart 
6381b44c5a6SAntoine Ténart 		ndesc++;
63989332590SAntoine Tenart 	}
6401b44c5a6SAntoine Ténart 
6411b44c5a6SAntoine Ténart 	safexcel_complete(priv, ring);
6421b44c5a6SAntoine Ténart 
6438ac1283eSAntoine Tenart 	if (src == dst) {
64449186a7dSPeter Harliman Liem 		if (sreq->nr_src > 0)
64549186a7dSPeter Harliman Liem 			dma_unmap_sg(priv->dev, src, sreq->nr_src,
64649186a7dSPeter Harliman Liem 				     DMA_BIDIRECTIONAL);
6471b44c5a6SAntoine Ténart 	} else {
64849186a7dSPeter Harliman Liem 		if (sreq->nr_src > 0)
64949186a7dSPeter Harliman Liem 			dma_unmap_sg(priv->dev, src, sreq->nr_src,
65049186a7dSPeter Harliman Liem 				     DMA_TO_DEVICE);
65149186a7dSPeter Harliman Liem 		if (sreq->nr_dst > 0)
65249186a7dSPeter Harliman Liem 			dma_unmap_sg(priv->dev, dst, sreq->nr_dst,
65349186a7dSPeter Harliman Liem 				     DMA_FROM_DEVICE);
6541b44c5a6SAntoine Ténart 	}
6551b44c5a6SAntoine Ténart 
6565bdb6e6aSPascal van Leeuwen 	/*
6575bdb6e6aSPascal van Leeuwen 	 * Update IV in req from last crypto output word for CBC modes
6585bdb6e6aSPascal van Leeuwen 	 */
6595bdb6e6aSPascal van Leeuwen 	if ((!ctx->aead) && (ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) &&
6605bdb6e6aSPascal van Leeuwen 	    (sreq->direction == SAFEXCEL_ENCRYPT)) {
6615bdb6e6aSPascal van Leeuwen 		/* For encrypt take the last output word */
66219b347b3SPascal van Leeuwen 		sg_pcopy_to_buffer(dst, sreq->nr_dst, areq->iv,
6635bdb6e6aSPascal van Leeuwen 				   crypto_skcipher_ivsize(skcipher),
6645bdb6e6aSPascal van Leeuwen 				   (cryptlen -
6655bdb6e6aSPascal van Leeuwen 				    crypto_skcipher_ivsize(skcipher)));
6665bdb6e6aSPascal van Leeuwen 	}
6675bdb6e6aSPascal van Leeuwen 
6681b44c5a6SAntoine Ténart 	*should_complete = true;
6691b44c5a6SAntoine Ténart 
6701b44c5a6SAntoine Ténart 	return ndesc;
6711b44c5a6SAntoine Ténart }
6721b44c5a6SAntoine Ténart 
safexcel_send_req(struct crypto_async_request * base,int ring,struct safexcel_cipher_req * sreq,struct scatterlist * src,struct scatterlist * dst,unsigned int cryptlen,unsigned int assoclen,unsigned int digestsize,u8 * iv,int * commands,int * results)673a7dea8c0SOfer Heifetz static int safexcel_send_req(struct crypto_async_request *base, int ring,
6748ac1283eSAntoine Tenart 			     struct safexcel_cipher_req *sreq,
6758ac1283eSAntoine Tenart 			     struct scatterlist *src, struct scatterlist *dst,
676f6beaea3SAntoine Tenart 			     unsigned int cryptlen, unsigned int assoclen,
677f6beaea3SAntoine Tenart 			     unsigned int digestsize, u8 *iv, int *commands,
6788ac1283eSAntoine Tenart 			     int *results)
6791b44c5a6SAntoine Ténart {
6805bdb6e6aSPascal van Leeuwen 	struct skcipher_request *areq = skcipher_request_cast(base);
6815bdb6e6aSPascal van Leeuwen 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(areq);
6828ac1283eSAntoine Tenart 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm);
68318e51895SHerbert Xu 	struct safexcel_crypto_priv *priv = ctx->base.priv;
6841b44c5a6SAntoine Ténart 	struct safexcel_command_desc *cdesc;
68519b347b3SPascal van Leeuwen 	struct safexcel_command_desc *first_cdesc = NULL;
686e5c8ee1fSAntoine Tenart 	struct safexcel_result_desc *rdesc, *first_rdesc = NULL;
6871b44c5a6SAntoine Ténart 	struct scatterlist *sg;
68819b347b3SPascal van Leeuwen 	unsigned int totlen;
68919b347b3SPascal van Leeuwen 	unsigned int totlen_src = cryptlen + assoclen;
69019b347b3SPascal van Leeuwen 	unsigned int totlen_dst = totlen_src;
691098e51e5SPascal van Leeuwen 	struct safexcel_token *atoken;
69219b347b3SPascal van Leeuwen 	int n_cdesc = 0, n_rdesc = 0;
69319b347b3SPascal van Leeuwen 	int queued, i, ret = 0;
69419b347b3SPascal van Leeuwen 	bool first = true;
6951b44c5a6SAntoine Ténart 
69619b347b3SPascal van Leeuwen 	sreq->nr_src = sg_nents_for_len(src, totlen_src);
69719b347b3SPascal van Leeuwen 
69819b347b3SPascal van Leeuwen 	if (ctx->aead) {
69919b347b3SPascal van Leeuwen 		/*
70019b347b3SPascal van Leeuwen 		 * AEAD has auth tag appended to output for encrypt and
70119b347b3SPascal van Leeuwen 		 * removed from the output for decrypt!
70219b347b3SPascal van Leeuwen 		 */
70319b347b3SPascal van Leeuwen 		if (sreq->direction == SAFEXCEL_DECRYPT)
70419b347b3SPascal van Leeuwen 			totlen_dst -= digestsize;
70519b347b3SPascal van Leeuwen 		else
70619b347b3SPascal van Leeuwen 			totlen_dst += digestsize;
70719b347b3SPascal van Leeuwen 
70819b347b3SPascal van Leeuwen 		memcpy(ctx->base.ctxr->data + ctx->key_len / sizeof(u32),
70978cf1c8bSHerbert Xu 		       &ctx->base.ipad, ctx->state_sz);
7103e450886SPascal van Leeuwen 		if (!ctx->xcm)
7113e450886SPascal van Leeuwen 			memcpy(ctx->base.ctxr->data + (ctx->key_len +
71278cf1c8bSHerbert Xu 			       ctx->state_sz) / sizeof(u32), &ctx->base.opad,
7133e450886SPascal van Leeuwen 			       ctx->state_sz);
71419b347b3SPascal van Leeuwen 	} else if ((ctx->mode == CONTEXT_CONTROL_CRYPTO_MODE_CBC) &&
7155bdb6e6aSPascal van Leeuwen 		   (sreq->direction == SAFEXCEL_DECRYPT)) {
7165bdb6e6aSPascal van Leeuwen 		/*
7175bdb6e6aSPascal van Leeuwen 		 * Save IV from last crypto input word for CBC modes in decrypt
7185bdb6e6aSPascal van Leeuwen 		 * direction. Need to do this first in case of inplace operation
7195bdb6e6aSPascal van Leeuwen 		 * as it will be overwritten.
7205bdb6e6aSPascal van Leeuwen 		 */
72119b347b3SPascal van Leeuwen 		sg_pcopy_to_buffer(src, sreq->nr_src, areq->iv,
7225bdb6e6aSPascal van Leeuwen 				   crypto_skcipher_ivsize(skcipher),
72319b347b3SPascal van Leeuwen 				   (totlen_src -
7245bdb6e6aSPascal van Leeuwen 				    crypto_skcipher_ivsize(skcipher)));
7255bdb6e6aSPascal van Leeuwen 	}
7265bdb6e6aSPascal van Leeuwen 
72719b347b3SPascal van Leeuwen 	sreq->nr_dst = sg_nents_for_len(dst, totlen_dst);
7281b44c5a6SAntoine Ténart 
72919b347b3SPascal van Leeuwen 	/*
73019b347b3SPascal van Leeuwen 	 * Remember actual input length, source buffer length may be
73119b347b3SPascal van Leeuwen 	 * updated in case of inline operation below.
73219b347b3SPascal van Leeuwen 	 */
73319b347b3SPascal van Leeuwen 	totlen = totlen_src;
73419b347b3SPascal van Leeuwen 	queued = totlen_src;
73519b347b3SPascal van Leeuwen 
73619b347b3SPascal van Leeuwen 	if (src == dst) {
73719b347b3SPascal van Leeuwen 		sreq->nr_src = max(sreq->nr_src, sreq->nr_dst);
73819b347b3SPascal van Leeuwen 		sreq->nr_dst = sreq->nr_src;
73919b347b3SPascal van Leeuwen 		if (unlikely((totlen_src || totlen_dst) &&
74019b347b3SPascal van Leeuwen 		    (sreq->nr_src <= 0))) {
74119b347b3SPascal van Leeuwen 			dev_err(priv->dev, "In-place buffer not large enough (need %d bytes)!",
74219b347b3SPascal van Leeuwen 				max(totlen_src, totlen_dst));
7431b44c5a6SAntoine Ténart 			return -EINVAL;
7441b44c5a6SAntoine Ténart 		}
745*87e02063SNikita Zhandarovich 		if (sreq->nr_src > 0 &&
746*87e02063SNikita Zhandarovich 		    !dma_map_sg(priv->dev, src, sreq->nr_src, DMA_BIDIRECTIONAL))
747*87e02063SNikita Zhandarovich 			return -EIO;
74819b347b3SPascal van Leeuwen 	} else {
74919b347b3SPascal van Leeuwen 		if (unlikely(totlen_src && (sreq->nr_src <= 0))) {
75019b347b3SPascal van Leeuwen 			dev_err(priv->dev, "Source buffer not large enough (need %d bytes)!",
75119b347b3SPascal van Leeuwen 				totlen_src);
75219b347b3SPascal van Leeuwen 			return -EINVAL;
75319b347b3SPascal van Leeuwen 		}
75449186a7dSPeter Harliman Liem 
755*87e02063SNikita Zhandarovich 		if (sreq->nr_src > 0 &&
756*87e02063SNikita Zhandarovich 		    !dma_map_sg(priv->dev, src, sreq->nr_src, DMA_TO_DEVICE))
757*87e02063SNikita Zhandarovich 			return -EIO;
75819b347b3SPascal van Leeuwen 
75919b347b3SPascal van Leeuwen 		if (unlikely(totlen_dst && (sreq->nr_dst <= 0))) {
76019b347b3SPascal van Leeuwen 			dev_err(priv->dev, "Dest buffer not large enough (need %d bytes)!",
76119b347b3SPascal van Leeuwen 				totlen_dst);
76249186a7dSPeter Harliman Liem 			ret = -EINVAL;
76349186a7dSPeter Harliman Liem 			goto unmap;
76419b347b3SPascal van Leeuwen 		}
76549186a7dSPeter Harliman Liem 
766*87e02063SNikita Zhandarovich 		if (sreq->nr_dst > 0 &&
767*87e02063SNikita Zhandarovich 		    !dma_map_sg(priv->dev, dst, sreq->nr_dst, DMA_FROM_DEVICE)) {
768*87e02063SNikita Zhandarovich 			ret = -EIO;
769*87e02063SNikita Zhandarovich 			goto unmap;
770*87e02063SNikita Zhandarovich 		}
7711b44c5a6SAntoine Ténart 	}
7721b44c5a6SAntoine Ténart 
7731b44c5a6SAntoine Ténart 	memcpy(ctx->base.ctxr->data, ctx->key, ctx->key_len);
7741b44c5a6SAntoine Ténart 
775cb97aa94SPascal van Leeuwen 	if (!totlen) {
776cb97aa94SPascal van Leeuwen 		/*
777cb97aa94SPascal van Leeuwen 		 * The EIP97 cannot deal with zero length input packets!
778cb97aa94SPascal van Leeuwen 		 * So stuff a dummy command descriptor indicating a 1 byte
779cb97aa94SPascal van Leeuwen 		 * (dummy) input packet, using the context record as source.
780cb97aa94SPascal van Leeuwen 		 */
781cb97aa94SPascal van Leeuwen 		first_cdesc = safexcel_add_cdesc(priv, ring,
782cb97aa94SPascal van Leeuwen 						 1, 1, ctx->base.ctxr_dma,
783cb97aa94SPascal van Leeuwen 						 1, 1, ctx->base.ctxr_dma,
784cb97aa94SPascal van Leeuwen 						 &atoken);
785cb97aa94SPascal van Leeuwen 		if (IS_ERR(first_cdesc)) {
786cb97aa94SPascal van Leeuwen 			/* No space left in the command descriptor ring */
787cb97aa94SPascal van Leeuwen 			ret = PTR_ERR(first_cdesc);
788cb97aa94SPascal van Leeuwen 			goto cdesc_rollback;
789cb97aa94SPascal van Leeuwen 		}
790cb97aa94SPascal van Leeuwen 		n_cdesc = 1;
791cb97aa94SPascal van Leeuwen 		goto skip_cdesc;
792cb97aa94SPascal van Leeuwen 	}
793f6beaea3SAntoine Tenart 
7941b44c5a6SAntoine Ténart 	/* command descriptors */
79519b347b3SPascal van Leeuwen 	for_each_sg(src, sg, sreq->nr_src, i) {
7961b44c5a6SAntoine Ténart 		int len = sg_dma_len(sg);
7971b44c5a6SAntoine Ténart 
7981b44c5a6SAntoine Ténart 		/* Do not overflow the request */
799cb97aa94SPascal van Leeuwen 		if (queued < len)
8001b44c5a6SAntoine Ténart 			len = queued;
8011b44c5a6SAntoine Ténart 
80219b347b3SPascal van Leeuwen 		cdesc = safexcel_add_cdesc(priv, ring, !n_cdesc,
80319b347b3SPascal van Leeuwen 					   !(queued - len),
804f6beaea3SAntoine Tenart 					   sg_dma_address(sg), len, totlen,
805098e51e5SPascal van Leeuwen 					   ctx->base.ctxr_dma, &atoken);
8061b44c5a6SAntoine Ténart 		if (IS_ERR(cdesc)) {
8071b44c5a6SAntoine Ténart 			/* No space left in the command descriptor ring */
8081b44c5a6SAntoine Ténart 			ret = PTR_ERR(cdesc);
8091b44c5a6SAntoine Ténart 			goto cdesc_rollback;
8101b44c5a6SAntoine Ténart 		}
8111b44c5a6SAntoine Ténart 
812cb97aa94SPascal van Leeuwen 		if (!n_cdesc)
81319b347b3SPascal van Leeuwen 			first_cdesc = cdesc;
8141b44c5a6SAntoine Ténart 
815cb97aa94SPascal van Leeuwen 		n_cdesc++;
8161b44c5a6SAntoine Ténart 		queued -= len;
8171b44c5a6SAntoine Ténart 		if (!queued)
8181b44c5a6SAntoine Ténart 			break;
8191b44c5a6SAntoine Ténart 	}
820cb97aa94SPascal van Leeuwen skip_cdesc:
82119b347b3SPascal van Leeuwen 	/* Add context control words and token to first command descriptor */
82219b347b3SPascal van Leeuwen 	safexcel_context_control(ctx, base, sreq, first_cdesc);
82319b347b3SPascal van Leeuwen 	if (ctx->aead)
824098e51e5SPascal van Leeuwen 		safexcel_aead_token(ctx, iv, first_cdesc, atoken,
82519b347b3SPascal van Leeuwen 				    sreq->direction, cryptlen,
82619b347b3SPascal van Leeuwen 				    assoclen, digestsize);
82719b347b3SPascal van Leeuwen 	else
828098e51e5SPascal van Leeuwen 		safexcel_skcipher_token(ctx, iv, first_cdesc, atoken,
82919b347b3SPascal van Leeuwen 					cryptlen);
83019b347b3SPascal van Leeuwen 
8311b44c5a6SAntoine Ténart 	/* result descriptors */
83219b347b3SPascal van Leeuwen 	for_each_sg(dst, sg, sreq->nr_dst, i) {
83319b347b3SPascal van Leeuwen 		bool last = (i == sreq->nr_dst - 1);
8341b44c5a6SAntoine Ténart 		u32 len = sg_dma_len(sg);
8351b44c5a6SAntoine Ténart 
83619b347b3SPascal van Leeuwen 		/* only allow the part of the buffer we know we need */
83719b347b3SPascal van Leeuwen 		if (len > totlen_dst)
83819b347b3SPascal van Leeuwen 			len = totlen_dst;
83919b347b3SPascal van Leeuwen 		if (unlikely(!len))
84019b347b3SPascal van Leeuwen 			break;
84119b347b3SPascal van Leeuwen 		totlen_dst -= len;
84219b347b3SPascal van Leeuwen 
84319b347b3SPascal van Leeuwen 		/* skip over AAD space in buffer - not written */
84419b347b3SPascal van Leeuwen 		if (assoclen) {
84519b347b3SPascal van Leeuwen 			if (assoclen >= len) {
84619b347b3SPascal van Leeuwen 				assoclen -= len;
84719b347b3SPascal van Leeuwen 				continue;
84819b347b3SPascal van Leeuwen 			}
8491b44c5a6SAntoine Ténart 			rdesc = safexcel_add_rdesc(priv, ring, first, last,
85019b347b3SPascal van Leeuwen 						   sg_dma_address(sg) +
85119b347b3SPascal van Leeuwen 						   assoclen,
85219b347b3SPascal van Leeuwen 						   len - assoclen);
85319b347b3SPascal van Leeuwen 			assoclen = 0;
85419b347b3SPascal van Leeuwen 		} else {
85519b347b3SPascal van Leeuwen 			rdesc = safexcel_add_rdesc(priv, ring, first, last,
85619b347b3SPascal van Leeuwen 						   sg_dma_address(sg),
85719b347b3SPascal van Leeuwen 						   len);
85819b347b3SPascal van Leeuwen 		}
8591b44c5a6SAntoine Ténart 		if (IS_ERR(rdesc)) {
8601b44c5a6SAntoine Ténart 			/* No space left in the result descriptor ring */
8611b44c5a6SAntoine Ténart 			ret = PTR_ERR(rdesc);
8621b44c5a6SAntoine Ténart 			goto rdesc_rollback;
8631b44c5a6SAntoine Ténart 		}
86419b347b3SPascal van Leeuwen 		if (first) {
8659744fec9SOfer Heifetz 			first_rdesc = rdesc;
86619b347b3SPascal van Leeuwen 			first = false;
86719b347b3SPascal van Leeuwen 		}
8681b44c5a6SAntoine Ténart 		n_rdesc++;
8691b44c5a6SAntoine Ténart 	}
8701b44c5a6SAntoine Ténart 
87119b347b3SPascal van Leeuwen 	if (unlikely(first)) {
87219b347b3SPascal van Leeuwen 		/*
87319b347b3SPascal van Leeuwen 		 * Special case: AEAD decrypt with only AAD data.
87419b347b3SPascal van Leeuwen 		 * In this case there is NO output data from the engine,
87519b347b3SPascal van Leeuwen 		 * but the engine still needs a result descriptor!
87619b347b3SPascal van Leeuwen 		 * Create a dummy one just for catching the result token.
87719b347b3SPascal van Leeuwen 		 */
87819b347b3SPascal van Leeuwen 		rdesc = safexcel_add_rdesc(priv, ring, true, true, 0, 0);
87919b347b3SPascal van Leeuwen 		if (IS_ERR(rdesc)) {
88019b347b3SPascal van Leeuwen 			/* No space left in the result descriptor ring */
88119b347b3SPascal van Leeuwen 			ret = PTR_ERR(rdesc);
88219b347b3SPascal van Leeuwen 			goto rdesc_rollback;
88319b347b3SPascal van Leeuwen 		}
88419b347b3SPascal van Leeuwen 		first_rdesc = rdesc;
88519b347b3SPascal van Leeuwen 		n_rdesc = 1;
88619b347b3SPascal van Leeuwen 	}
88719b347b3SPascal van Leeuwen 
8889744fec9SOfer Heifetz 	safexcel_rdr_req_set(priv, ring, first_rdesc, base);
88997858434SAntoine Ténart 
8901b44c5a6SAntoine Ténart 	*commands = n_cdesc;
891152bdf4cSOfer Heifetz 	*results = n_rdesc;
8921b44c5a6SAntoine Ténart 	return 0;
8931b44c5a6SAntoine Ténart 
8941b44c5a6SAntoine Ténart rdesc_rollback:
8951b44c5a6SAntoine Ténart 	for (i = 0; i < n_rdesc; i++)
8961b44c5a6SAntoine Ténart 		safexcel_ring_rollback_wptr(priv, &priv->ring[ring].rdr);
8971b44c5a6SAntoine Ténart cdesc_rollback:
8981b44c5a6SAntoine Ténart 	for (i = 0; i < n_cdesc; i++)
8991b44c5a6SAntoine Ténart 		safexcel_ring_rollback_wptr(priv, &priv->ring[ring].cdr);
90049186a7dSPeter Harliman Liem unmap:
9018ac1283eSAntoine Tenart 	if (src == dst) {
90249186a7dSPeter Harliman Liem 		if (sreq->nr_src > 0)
90349186a7dSPeter Harliman Liem 			dma_unmap_sg(priv->dev, src, sreq->nr_src,
90449186a7dSPeter Harliman Liem 				     DMA_BIDIRECTIONAL);
9051b44c5a6SAntoine Ténart 	} else {
90649186a7dSPeter Harliman Liem 		if (sreq->nr_src > 0)
90749186a7dSPeter Harliman Liem 			dma_unmap_sg(priv->dev, src, sreq->nr_src,
90849186a7dSPeter Harliman Liem 				     DMA_TO_DEVICE);
90949186a7dSPeter Harliman Liem 		if (sreq->nr_dst > 0)
91049186a7dSPeter Harliman Liem 			dma_unmap_sg(priv->dev, dst, sreq->nr_dst,
91149186a7dSPeter Harliman Liem 				     DMA_FROM_DEVICE);
9121b44c5a6SAntoine Ténart 	}
9131b44c5a6SAntoine Ténart 
9141b44c5a6SAntoine Ténart 	return ret;
9151b44c5a6SAntoine Ténart }
9161b44c5a6SAntoine Ténart 
safexcel_handle_inv_result(struct safexcel_crypto_priv * priv,int ring,struct crypto_async_request * base,struct safexcel_cipher_req * sreq,bool * should_complete,int * ret)9171b44c5a6SAntoine Ténart static int safexcel_handle_inv_result(struct safexcel_crypto_priv *priv,
9181b44c5a6SAntoine Ténart 				      int ring,
9198ac1283eSAntoine Tenart 				      struct crypto_async_request *base,
92089332590SAntoine Tenart 				      struct safexcel_cipher_req *sreq,
9211b44c5a6SAntoine Ténart 				      bool *should_complete, int *ret)
9221b44c5a6SAntoine Ténart {
9238ac1283eSAntoine Tenart 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm);
9241b44c5a6SAntoine Ténart 	struct safexcel_result_desc *rdesc;
9251b44c5a6SAntoine Ténart 	int ndesc = 0, enq_ret;
9261b44c5a6SAntoine Ténart 
9271b44c5a6SAntoine Ténart 	*ret = 0;
9281b44c5a6SAntoine Ténart 
92989332590SAntoine Tenart 	if (unlikely(!sreq->rdescs))
93089332590SAntoine Tenart 		return 0;
93189332590SAntoine Tenart 
93289332590SAntoine Tenart 	while (sreq->rdescs--) {
9331b44c5a6SAntoine Ténart 		rdesc = safexcel_ring_next_rptr(priv, &priv->ring[ring].rdr);
9341b44c5a6SAntoine Ténart 		if (IS_ERR(rdesc)) {
9351b44c5a6SAntoine Ténart 			dev_err(priv->dev,
9361b44c5a6SAntoine Ténart 				"cipher: invalidate: could not retrieve the result descriptor\n");
9371b44c5a6SAntoine Ténart 			*ret = PTR_ERR(rdesc);
9381b44c5a6SAntoine Ténart 			break;
9391b44c5a6SAntoine Ténart 		}
9401b44c5a6SAntoine Ténart 
941cda3e73aSAntoine Tenart 		if (likely(!*ret))
942cda3e73aSAntoine Tenart 			*ret = safexcel_rdesc_check_errors(priv, rdesc);
9431b44c5a6SAntoine Ténart 
9441b44c5a6SAntoine Ténart 		ndesc++;
94589332590SAntoine Tenart 	}
9461b44c5a6SAntoine Ténart 
9471b44c5a6SAntoine Ténart 	safexcel_complete(priv, ring);
9481b44c5a6SAntoine Ténart 
9491b44c5a6SAntoine Ténart 	if (ctx->base.exit_inv) {
9501b44c5a6SAntoine Ténart 		dma_pool_free(priv->context_pool, ctx->base.ctxr,
9511b44c5a6SAntoine Ténart 			      ctx->base.ctxr_dma);
9521b44c5a6SAntoine Ténart 
9531b44c5a6SAntoine Ténart 		*should_complete = true;
9541b44c5a6SAntoine Ténart 
9551b44c5a6SAntoine Ténart 		return ndesc;
9561b44c5a6SAntoine Ténart 	}
9571b44c5a6SAntoine Ténart 
95886671abbSAntoine Ténart 	ring = safexcel_select_ring(priv);
95986671abbSAntoine Ténart 	ctx->base.ring = ring;
9601b44c5a6SAntoine Ténart 
96186671abbSAntoine Ténart 	spin_lock_bh(&priv->ring[ring].queue_lock);
9628ac1283eSAntoine Tenart 	enq_ret = crypto_enqueue_request(&priv->ring[ring].queue, base);
96386671abbSAntoine Ténart 	spin_unlock_bh(&priv->ring[ring].queue_lock);
9641b44c5a6SAntoine Ténart 
9651b44c5a6SAntoine Ténart 	if (enq_ret != -EINPROGRESS)
9661b44c5a6SAntoine Ténart 		*ret = enq_ret;
9671b44c5a6SAntoine Ténart 
9688472e778SAntoine Ténart 	queue_work(priv->ring[ring].workqueue,
9698472e778SAntoine Ténart 		   &priv->ring[ring].work_data.work);
97086671abbSAntoine Ténart 
9711b44c5a6SAntoine Ténart 	*should_complete = false;
9721b44c5a6SAntoine Ténart 
9731b44c5a6SAntoine Ténart 	return ndesc;
9741b44c5a6SAntoine Ténart }
9751b44c5a6SAntoine Ténart 
safexcel_skcipher_handle_result(struct safexcel_crypto_priv * priv,int ring,struct crypto_async_request * async,bool * should_complete,int * ret)9768ac1283eSAntoine Tenart static int safexcel_skcipher_handle_result(struct safexcel_crypto_priv *priv,
9778ac1283eSAntoine Tenart 					   int ring,
9781eb7b403SOfer Heifetz 					   struct crypto_async_request *async,
9791eb7b403SOfer Heifetz 					   bool *should_complete, int *ret)
9801eb7b403SOfer Heifetz {
9811eb7b403SOfer Heifetz 	struct skcipher_request *req = skcipher_request_cast(async);
9821eb7b403SOfer Heifetz 	struct safexcel_cipher_req *sreq = skcipher_request_ctx(req);
9831eb7b403SOfer Heifetz 	int err;
9841eb7b403SOfer Heifetz 
9851eb7b403SOfer Heifetz 	if (sreq->needs_inv) {
9861eb7b403SOfer Heifetz 		sreq->needs_inv = false;
98789332590SAntoine Tenart 		err = safexcel_handle_inv_result(priv, ring, async, sreq,
9881eb7b403SOfer Heifetz 						 should_complete, ret);
9891eb7b403SOfer Heifetz 	} else {
9908ac1283eSAntoine Tenart 		err = safexcel_handle_req_result(priv, ring, async, req->src,
9918ac1283eSAntoine Tenart 						 req->dst, req->cryptlen, sreq,
9921eb7b403SOfer Heifetz 						 should_complete, ret);
9931eb7b403SOfer Heifetz 	}
9941eb7b403SOfer Heifetz 
9951eb7b403SOfer Heifetz 	return err;
9961eb7b403SOfer Heifetz }
9971eb7b403SOfer Heifetz 
safexcel_aead_handle_result(struct safexcel_crypto_priv * priv,int ring,struct crypto_async_request * async,bool * should_complete,int * ret)998f6beaea3SAntoine Tenart static int safexcel_aead_handle_result(struct safexcel_crypto_priv *priv,
999f6beaea3SAntoine Tenart 				       int ring,
1000f6beaea3SAntoine Tenart 				       struct crypto_async_request *async,
1001f6beaea3SAntoine Tenart 				       bool *should_complete, int *ret)
1002f6beaea3SAntoine Tenart {
1003f6beaea3SAntoine Tenart 	struct aead_request *req = aead_request_cast(async);
1004f6beaea3SAntoine Tenart 	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
1005f6beaea3SAntoine Tenart 	struct safexcel_cipher_req *sreq = aead_request_ctx(req);
1006f6beaea3SAntoine Tenart 	int err;
1007f6beaea3SAntoine Tenart 
1008f6beaea3SAntoine Tenart 	if (sreq->needs_inv) {
1009f6beaea3SAntoine Tenart 		sreq->needs_inv = false;
101089332590SAntoine Tenart 		err = safexcel_handle_inv_result(priv, ring, async, sreq,
1011f6beaea3SAntoine Tenart 						 should_complete, ret);
1012f6beaea3SAntoine Tenart 	} else {
1013f6beaea3SAntoine Tenart 		err = safexcel_handle_req_result(priv, ring, async, req->src,
1014f6beaea3SAntoine Tenart 						 req->dst,
1015f6beaea3SAntoine Tenart 						 req->cryptlen + crypto_aead_authsize(tfm),
1016f6beaea3SAntoine Tenart 						 sreq, should_complete, ret);
1017f6beaea3SAntoine Tenart 	}
1018f6beaea3SAntoine Tenart 
1019f6beaea3SAntoine Tenart 	return err;
1020f6beaea3SAntoine Tenart }
1021f6beaea3SAntoine Tenart 
safexcel_cipher_send_inv(struct crypto_async_request * base,int ring,int * commands,int * results)10228ac1283eSAntoine Tenart static int safexcel_cipher_send_inv(struct crypto_async_request *base,
10239744fec9SOfer Heifetz 				    int ring, int *commands, int *results)
10241b44c5a6SAntoine Ténart {
10258ac1283eSAntoine Tenart 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm);
102618e51895SHerbert Xu 	struct safexcel_crypto_priv *priv = ctx->base.priv;
10271b44c5a6SAntoine Ténart 	int ret;
10281b44c5a6SAntoine Ténart 
10299744fec9SOfer Heifetz 	ret = safexcel_invalidate_cache(base, priv, ctx->base.ctxr_dma, ring);
10301b44c5a6SAntoine Ténart 	if (unlikely(ret))
10311b44c5a6SAntoine Ténart 		return ret;
10321b44c5a6SAntoine Ténart 
10331b44c5a6SAntoine Ténart 	*commands = 1;
10341b44c5a6SAntoine Ténart 	*results = 1;
10351b44c5a6SAntoine Ténart 
10361b44c5a6SAntoine Ténart 	return 0;
10371b44c5a6SAntoine Ténart }
10381b44c5a6SAntoine Ténart 
safexcel_skcipher_send(struct crypto_async_request * async,int ring,int * commands,int * results)10398ac1283eSAntoine Tenart static int safexcel_skcipher_send(struct crypto_async_request *async, int ring,
10401eb7b403SOfer Heifetz 				  int *commands, int *results)
10411eb7b403SOfer Heifetz {
10421eb7b403SOfer Heifetz 	struct skcipher_request *req = skcipher_request_cast(async);
1043871df319SAntoine Ténart 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
10441eb7b403SOfer Heifetz 	struct safexcel_cipher_req *sreq = skcipher_request_ctx(req);
104518e51895SHerbert Xu 	struct safexcel_crypto_priv *priv = ctx->base.priv;
10461eb7b403SOfer Heifetz 	int ret;
10471eb7b403SOfer Heifetz 
104853c83e91SAntoine Tenart 	BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && sreq->needs_inv);
1049871df319SAntoine Ténart 
10505bdb6e6aSPascal van Leeuwen 	if (sreq->needs_inv) {
10519744fec9SOfer Heifetz 		ret = safexcel_cipher_send_inv(async, ring, commands, results);
10525bdb6e6aSPascal van Leeuwen 	} else {
10535bdb6e6aSPascal van Leeuwen 		struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
10545bdb6e6aSPascal van Leeuwen 		u8 input_iv[AES_BLOCK_SIZE];
10555bdb6e6aSPascal van Leeuwen 
10565bdb6e6aSPascal van Leeuwen 		/*
10575bdb6e6aSPascal van Leeuwen 		 * Save input IV in case of CBC decrypt mode
10585bdb6e6aSPascal van Leeuwen 		 * Will be overwritten with output IV prior to use!
10595bdb6e6aSPascal van Leeuwen 		 */
10605bdb6e6aSPascal van Leeuwen 		memcpy(input_iv, req->iv, crypto_skcipher_ivsize(skcipher));
10615bdb6e6aSPascal van Leeuwen 
10629744fec9SOfer Heifetz 		ret = safexcel_send_req(async, ring, sreq, req->src,
10635bdb6e6aSPascal van Leeuwen 					req->dst, req->cryptlen, 0, 0, input_iv,
1064f6beaea3SAntoine Tenart 					commands, results);
10655bdb6e6aSPascal van Leeuwen 	}
106689332590SAntoine Tenart 
106789332590SAntoine Tenart 	sreq->rdescs = *results;
1068f6beaea3SAntoine Tenart 	return ret;
1069f6beaea3SAntoine Tenart }
1070f6beaea3SAntoine Tenart 
safexcel_aead_send(struct crypto_async_request * async,int ring,int * commands,int * results)1071f6beaea3SAntoine Tenart static int safexcel_aead_send(struct crypto_async_request *async, int ring,
10729744fec9SOfer Heifetz 			      int *commands, int *results)
1073f6beaea3SAntoine Tenart {
1074f6beaea3SAntoine Tenart 	struct aead_request *req = aead_request_cast(async);
1075f6beaea3SAntoine Tenart 	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
1076f6beaea3SAntoine Tenart 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
1077f6beaea3SAntoine Tenart 	struct safexcel_cipher_req *sreq = aead_request_ctx(req);
107818e51895SHerbert Xu 	struct safexcel_crypto_priv *priv = ctx->base.priv;
1079f6beaea3SAntoine Tenart 	int ret;
1080f6beaea3SAntoine Tenart 
108153c83e91SAntoine Tenart 	BUG_ON(!(priv->flags & EIP197_TRC_CACHE) && sreq->needs_inv);
1082f6beaea3SAntoine Tenart 
1083f6beaea3SAntoine Tenart 	if (sreq->needs_inv)
10849744fec9SOfer Heifetz 		ret = safexcel_cipher_send_inv(async, ring, commands, results);
1085f6beaea3SAntoine Tenart 	else
10869744fec9SOfer Heifetz 		ret = safexcel_send_req(async, ring, sreq, req->src, req->dst,
10879744fec9SOfer Heifetz 					req->cryptlen, req->assoclen,
1088f6beaea3SAntoine Tenart 					crypto_aead_authsize(tfm), req->iv,
10891eb7b403SOfer Heifetz 					commands, results);
109089332590SAntoine Tenart 	sreq->rdescs = *results;
10911eb7b403SOfer Heifetz 	return ret;
10921eb7b403SOfer Heifetz }
10931eb7b403SOfer Heifetz 
safexcel_cipher_exit_inv(struct crypto_tfm * tfm,struct crypto_async_request * base,struct safexcel_cipher_req * sreq,struct crypto_wait * result)10948ac1283eSAntoine Tenart static int safexcel_cipher_exit_inv(struct crypto_tfm *tfm,
10958ac1283eSAntoine Tenart 				    struct crypto_async_request *base,
10968ac1283eSAntoine Tenart 				    struct safexcel_cipher_req *sreq,
1097acc3f550SHerbert Xu 				    struct crypto_wait *result)
10981b44c5a6SAntoine Ténart {
10991b44c5a6SAntoine Ténart 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
110018e51895SHerbert Xu 	struct safexcel_crypto_priv *priv = ctx->base.priv;
110186671abbSAntoine Ténart 	int ring = ctx->base.ring;
1102acc3f550SHerbert Xu 	int err;
11031b44c5a6SAntoine Ténart 
11048ac1283eSAntoine Tenart 	ctx = crypto_tfm_ctx(base->tfm);
11051b44c5a6SAntoine Ténart 	ctx->base.exit_inv = true;
11061eb7b403SOfer Heifetz 	sreq->needs_inv = true;
11071b44c5a6SAntoine Ténart 
110886671abbSAntoine Ténart 	spin_lock_bh(&priv->ring[ring].queue_lock);
11098ac1283eSAntoine Tenart 	crypto_enqueue_request(&priv->ring[ring].queue, base);
111086671abbSAntoine Ténart 	spin_unlock_bh(&priv->ring[ring].queue_lock);
11111b44c5a6SAntoine Ténart 
11128472e778SAntoine Ténart 	queue_work(priv->ring[ring].workqueue,
11138472e778SAntoine Ténart 		   &priv->ring[ring].work_data.work);
11141b44c5a6SAntoine Ténart 
1115acc3f550SHerbert Xu 	err = crypto_wait_req(-EINPROGRESS, result);
11161b44c5a6SAntoine Ténart 
1117acc3f550SHerbert Xu 	if (err) {
11181b44c5a6SAntoine Ténart 		dev_warn(priv->dev,
11191b44c5a6SAntoine Ténart 			"cipher: sync: invalidate: completion error %d\n",
1120acc3f550SHerbert Xu 			 err);
1121acc3f550SHerbert Xu 		return err;
11221b44c5a6SAntoine Ténart 	}
11231b44c5a6SAntoine Ténart 
11241b44c5a6SAntoine Ténart 	return 0;
11251b44c5a6SAntoine Ténart }
11261b44c5a6SAntoine Ténart 
safexcel_skcipher_exit_inv(struct crypto_tfm * tfm)11278ac1283eSAntoine Tenart static int safexcel_skcipher_exit_inv(struct crypto_tfm *tfm)
11288ac1283eSAntoine Tenart {
11298ac1283eSAntoine Tenart 	EIP197_REQUEST_ON_STACK(req, skcipher, EIP197_SKCIPHER_REQ_SIZE);
11308ac1283eSAntoine Tenart 	struct safexcel_cipher_req *sreq = skcipher_request_ctx(req);
1131acc3f550SHerbert Xu 	DECLARE_CRYPTO_WAIT(result);
11328ac1283eSAntoine Tenart 
11338ac1283eSAntoine Tenart 	memset(req, 0, sizeof(struct skcipher_request));
11348ac1283eSAntoine Tenart 
11358ac1283eSAntoine Tenart 	skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
1136acc3f550SHerbert Xu 				      crypto_req_done, &result);
11378ac1283eSAntoine Tenart 	skcipher_request_set_tfm(req, __crypto_skcipher_cast(tfm));
11388ac1283eSAntoine Tenart 
11398ac1283eSAntoine Tenart 	return safexcel_cipher_exit_inv(tfm, &req->base, sreq, &result);
11408ac1283eSAntoine Tenart }
11418ac1283eSAntoine Tenart 
safexcel_aead_exit_inv(struct crypto_tfm * tfm)1142f6beaea3SAntoine Tenart static int safexcel_aead_exit_inv(struct crypto_tfm *tfm)
1143f6beaea3SAntoine Tenart {
1144f6beaea3SAntoine Tenart 	EIP197_REQUEST_ON_STACK(req, aead, EIP197_AEAD_REQ_SIZE);
1145f6beaea3SAntoine Tenart 	struct safexcel_cipher_req *sreq = aead_request_ctx(req);
1146acc3f550SHerbert Xu 	DECLARE_CRYPTO_WAIT(result);
1147f6beaea3SAntoine Tenart 
1148f6beaea3SAntoine Tenart 	memset(req, 0, sizeof(struct aead_request));
1149f6beaea3SAntoine Tenart 
1150f6beaea3SAntoine Tenart 	aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG,
1151acc3f550SHerbert Xu 				  crypto_req_done, &result);
1152f6beaea3SAntoine Tenart 	aead_request_set_tfm(req, __crypto_aead_cast(tfm));
1153f6beaea3SAntoine Tenart 
1154f6beaea3SAntoine Tenart 	return safexcel_cipher_exit_inv(tfm, &req->base, sreq, &result);
1155f6beaea3SAntoine Tenart }
1156f6beaea3SAntoine Tenart 
safexcel_queue_req(struct crypto_async_request * base,struct safexcel_cipher_req * sreq,enum safexcel_cipher_direction dir)1157a7dea8c0SOfer Heifetz static int safexcel_queue_req(struct crypto_async_request *base,
11588ac1283eSAntoine Tenart 			struct safexcel_cipher_req *sreq,
115993369b5dSPascal van Leeuwen 			enum safexcel_cipher_direction dir)
11601b44c5a6SAntoine Ténart {
11618ac1283eSAntoine Tenart 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(base->tfm);
116218e51895SHerbert Xu 	struct safexcel_crypto_priv *priv = ctx->base.priv;
116386671abbSAntoine Ténart 	int ret, ring;
11641b44c5a6SAntoine Ténart 
11651eb7b403SOfer Heifetz 	sreq->needs_inv = false;
1166847ccfc5SOfer Heifetz 	sreq->direction = dir;
11671b44c5a6SAntoine Ténart 
11681b44c5a6SAntoine Ténart 	if (ctx->base.ctxr) {
116953c83e91SAntoine Tenart 		if (priv->flags & EIP197_TRC_CACHE && ctx->base.needs_inv) {
11701eb7b403SOfer Heifetz 			sreq->needs_inv = true;
11711eb7b403SOfer Heifetz 			ctx->base.needs_inv = false;
11721eb7b403SOfer Heifetz 		}
11731b44c5a6SAntoine Ténart 	} else {
11741b44c5a6SAntoine Ténart 		ctx->base.ring = safexcel_select_ring(priv);
11751b44c5a6SAntoine Ténart 		ctx->base.ctxr = dma_pool_zalloc(priv->context_pool,
11768ac1283eSAntoine Tenart 						 EIP197_GFP_FLAGS(*base),
11771b44c5a6SAntoine Ténart 						 &ctx->base.ctxr_dma);
11781b44c5a6SAntoine Ténart 		if (!ctx->base.ctxr)
11791b44c5a6SAntoine Ténart 			return -ENOMEM;
11801b44c5a6SAntoine Ténart 	}
11811b44c5a6SAntoine Ténart 
118286671abbSAntoine Ténart 	ring = ctx->base.ring;
11831b44c5a6SAntoine Ténart 
118486671abbSAntoine Ténart 	spin_lock_bh(&priv->ring[ring].queue_lock);
11858ac1283eSAntoine Tenart 	ret = crypto_enqueue_request(&priv->ring[ring].queue, base);
118686671abbSAntoine Ténart 	spin_unlock_bh(&priv->ring[ring].queue_lock);
118786671abbSAntoine Ténart 
11888472e778SAntoine Ténart 	queue_work(priv->ring[ring].workqueue,
11898472e778SAntoine Ténart 		   &priv->ring[ring].work_data.work);
11901b44c5a6SAntoine Ténart 
11911b44c5a6SAntoine Ténart 	return ret;
11921b44c5a6SAntoine Ténart }
11931b44c5a6SAntoine Ténart 
safexcel_encrypt(struct skcipher_request * req)119493369b5dSPascal van Leeuwen static int safexcel_encrypt(struct skcipher_request *req)
11951b44c5a6SAntoine Ténart {
1196a7dea8c0SOfer Heifetz 	return safexcel_queue_req(&req->base, skcipher_request_ctx(req),
119793369b5dSPascal van Leeuwen 			SAFEXCEL_ENCRYPT);
11981b44c5a6SAntoine Ténart }
11991b44c5a6SAntoine Ténart 
safexcel_decrypt(struct skcipher_request * req)120093369b5dSPascal van Leeuwen static int safexcel_decrypt(struct skcipher_request *req)
12011b44c5a6SAntoine Ténart {
1202a7dea8c0SOfer Heifetz 	return safexcel_queue_req(&req->base, skcipher_request_ctx(req),
120393369b5dSPascal van Leeuwen 			SAFEXCEL_DECRYPT);
12041b44c5a6SAntoine Ténart }
12051b44c5a6SAntoine Ténart 
safexcel_skcipher_cra_init(struct crypto_tfm * tfm)12061b44c5a6SAntoine Ténart static int safexcel_skcipher_cra_init(struct crypto_tfm *tfm)
12071b44c5a6SAntoine Ténart {
12081b44c5a6SAntoine Ténart 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
12091b44c5a6SAntoine Ténart 	struct safexcel_alg_template *tmpl =
12101b44c5a6SAntoine Ténart 		container_of(tfm->__crt_alg, struct safexcel_alg_template,
12111b44c5a6SAntoine Ténart 			     alg.skcipher.base);
12121b44c5a6SAntoine Ténart 
12131eb7b403SOfer Heifetz 	crypto_skcipher_set_reqsize(__crypto_skcipher_cast(tfm),
12141eb7b403SOfer Heifetz 				    sizeof(struct safexcel_cipher_req));
12151b44c5a6SAntoine Ténart 
121618e51895SHerbert Xu 	ctx->base.priv = tmpl->priv;
12178ac1283eSAntoine Tenart 
12188ac1283eSAntoine Tenart 	ctx->base.send = safexcel_skcipher_send;
12198ac1283eSAntoine Tenart 	ctx->base.handle_result = safexcel_skcipher_handle_result;
1220098e51e5SPascal van Leeuwen 	ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD;
1221098e51e5SPascal van Leeuwen 	ctx->ctrinit = 1;
12228ac1283eSAntoine Tenart 	return 0;
12238ac1283eSAntoine Tenart }
12248ac1283eSAntoine Tenart 
safexcel_cipher_cra_exit(struct crypto_tfm * tfm)12258ac1283eSAntoine Tenart static int safexcel_cipher_cra_exit(struct crypto_tfm *tfm)
12268ac1283eSAntoine Tenart {
12278ac1283eSAntoine Tenart 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
12288ac1283eSAntoine Tenart 
1229ce679559SAntoine Tenart 	memzero_explicit(ctx->key, sizeof(ctx->key));
12308ac1283eSAntoine Tenart 
12318ac1283eSAntoine Tenart 	/* context not allocated, skip invalidation */
12328ac1283eSAntoine Tenart 	if (!ctx->base.ctxr)
12338ac1283eSAntoine Tenart 		return -ENOMEM;
12348ac1283eSAntoine Tenart 
1235ce679559SAntoine Tenart 	memzero_explicit(ctx->base.ctxr->data, sizeof(ctx->base.ctxr->data));
12361b44c5a6SAntoine Ténart 	return 0;
12371b44c5a6SAntoine Ténart }
12381b44c5a6SAntoine Ténart 
safexcel_skcipher_cra_exit(struct crypto_tfm * tfm)12391b44c5a6SAntoine Ténart static void safexcel_skcipher_cra_exit(struct crypto_tfm *tfm)
12401b44c5a6SAntoine Ténart {
12411b44c5a6SAntoine Ténart 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
124218e51895SHerbert Xu 	struct safexcel_crypto_priv *priv = ctx->base.priv;
12431b44c5a6SAntoine Ténart 	int ret;
12441b44c5a6SAntoine Ténart 
12458ac1283eSAntoine Tenart 	if (safexcel_cipher_cra_exit(tfm))
12461b44c5a6SAntoine Ténart 		return;
12471b44c5a6SAntoine Ténart 
124853c83e91SAntoine Tenart 	if (priv->flags & EIP197_TRC_CACHE) {
12498ac1283eSAntoine Tenart 		ret = safexcel_skcipher_exit_inv(tfm);
12501b44c5a6SAntoine Ténart 		if (ret)
12518ac1283eSAntoine Tenart 			dev_warn(priv->dev, "skcipher: invalidation error %d\n",
12528ac1283eSAntoine Tenart 				 ret);
1253871df319SAntoine Ténart 	} else {
1254871df319SAntoine Ténart 		dma_pool_free(priv->context_pool, ctx->base.ctxr,
1255871df319SAntoine Ténart 			      ctx->base.ctxr_dma);
1256871df319SAntoine Ténart 	}
12571b44c5a6SAntoine Ténart }
12581b44c5a6SAntoine Ténart 
safexcel_aead_cra_exit(struct crypto_tfm * tfm)1259f6beaea3SAntoine Tenart static void safexcel_aead_cra_exit(struct crypto_tfm *tfm)
1260f6beaea3SAntoine Tenart {
1261f6beaea3SAntoine Tenart 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
126218e51895SHerbert Xu 	struct safexcel_crypto_priv *priv = ctx->base.priv;
1263f6beaea3SAntoine Tenart 	int ret;
1264f6beaea3SAntoine Tenart 
1265f6beaea3SAntoine Tenart 	if (safexcel_cipher_cra_exit(tfm))
1266f6beaea3SAntoine Tenart 		return;
1267f6beaea3SAntoine Tenart 
126853c83e91SAntoine Tenart 	if (priv->flags & EIP197_TRC_CACHE) {
1269f6beaea3SAntoine Tenart 		ret = safexcel_aead_exit_inv(tfm);
1270f6beaea3SAntoine Tenart 		if (ret)
1271f6beaea3SAntoine Tenart 			dev_warn(priv->dev, "aead: invalidation error %d\n",
1272f6beaea3SAntoine Tenart 				 ret);
1273f6beaea3SAntoine Tenart 	} else {
1274f6beaea3SAntoine Tenart 		dma_pool_free(priv->context_pool, ctx->base.ctxr,
1275f6beaea3SAntoine Tenart 			      ctx->base.ctxr_dma);
1276f6beaea3SAntoine Tenart 	}
1277f6beaea3SAntoine Tenart }
1278f6beaea3SAntoine Tenart 
safexcel_skcipher_aes_ecb_cra_init(struct crypto_tfm * tfm)127993369b5dSPascal van Leeuwen static int safexcel_skcipher_aes_ecb_cra_init(struct crypto_tfm *tfm)
128093369b5dSPascal van Leeuwen {
128193369b5dSPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
128293369b5dSPascal van Leeuwen 
128393369b5dSPascal van Leeuwen 	safexcel_skcipher_cra_init(tfm);
128493369b5dSPascal van Leeuwen 	ctx->alg  = SAFEXCEL_AES;
128593369b5dSPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB;
1286098e51e5SPascal van Leeuwen 	ctx->blocksz = 0;
1287098e51e5SPascal van Leeuwen 	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
128893369b5dSPascal van Leeuwen 	return 0;
128993369b5dSPascal van Leeuwen }
129093369b5dSPascal van Leeuwen 
12911b44c5a6SAntoine Ténart struct safexcel_alg_template safexcel_alg_ecb_aes = {
12921b44c5a6SAntoine Ténart 	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
1293062b64caSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_AES,
12941b44c5a6SAntoine Ténart 	.alg.skcipher = {
12958ac1283eSAntoine Tenart 		.setkey = safexcel_skcipher_aes_setkey,
129693369b5dSPascal van Leeuwen 		.encrypt = safexcel_encrypt,
129793369b5dSPascal van Leeuwen 		.decrypt = safexcel_decrypt,
12981b44c5a6SAntoine Ténart 		.min_keysize = AES_MIN_KEY_SIZE,
12991b44c5a6SAntoine Ténart 		.max_keysize = AES_MAX_KEY_SIZE,
13001b44c5a6SAntoine Ténart 		.base = {
13011b44c5a6SAntoine Ténart 			.cra_name = "ecb(aes)",
13021b44c5a6SAntoine Ténart 			.cra_driver_name = "safexcel-ecb-aes",
1303aa88f331SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
13042c95e6d9SEric Biggers 			.cra_flags = CRYPTO_ALG_ASYNC |
1305b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
13061b44c5a6SAntoine Ténart 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
13071b44c5a6SAntoine Ténart 			.cra_blocksize = AES_BLOCK_SIZE,
13081b44c5a6SAntoine Ténart 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
13091b44c5a6SAntoine Ténart 			.cra_alignmask = 0,
131093369b5dSPascal van Leeuwen 			.cra_init = safexcel_skcipher_aes_ecb_cra_init,
13111b44c5a6SAntoine Ténart 			.cra_exit = safexcel_skcipher_cra_exit,
13121b44c5a6SAntoine Ténart 			.cra_module = THIS_MODULE,
13131b44c5a6SAntoine Ténart 		},
13141b44c5a6SAntoine Ténart 	},
13151b44c5a6SAntoine Ténart };
13161b44c5a6SAntoine Ténart 
safexcel_skcipher_aes_cbc_cra_init(struct crypto_tfm * tfm)131793369b5dSPascal van Leeuwen static int safexcel_skcipher_aes_cbc_cra_init(struct crypto_tfm *tfm)
13181b44c5a6SAntoine Ténart {
131993369b5dSPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
13201b44c5a6SAntoine Ténart 
132193369b5dSPascal van Leeuwen 	safexcel_skcipher_cra_init(tfm);
132293369b5dSPascal van Leeuwen 	ctx->alg  = SAFEXCEL_AES;
1323098e51e5SPascal van Leeuwen 	ctx->blocksz = AES_BLOCK_SIZE;
132493369b5dSPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC;
132593369b5dSPascal van Leeuwen 	return 0;
13261b44c5a6SAntoine Ténart }
13271b44c5a6SAntoine Ténart 
13281b44c5a6SAntoine Ténart struct safexcel_alg_template safexcel_alg_cbc_aes = {
13291b44c5a6SAntoine Ténart 	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
1330062b64caSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_AES,
13311b44c5a6SAntoine Ténart 	.alg.skcipher = {
13328ac1283eSAntoine Tenart 		.setkey = safexcel_skcipher_aes_setkey,
133393369b5dSPascal van Leeuwen 		.encrypt = safexcel_encrypt,
133493369b5dSPascal van Leeuwen 		.decrypt = safexcel_decrypt,
13351b44c5a6SAntoine Ténart 		.min_keysize = AES_MIN_KEY_SIZE,
13361b44c5a6SAntoine Ténart 		.max_keysize = AES_MAX_KEY_SIZE,
13371b44c5a6SAntoine Ténart 		.ivsize = AES_BLOCK_SIZE,
13381b44c5a6SAntoine Ténart 		.base = {
13391b44c5a6SAntoine Ténart 			.cra_name = "cbc(aes)",
13401b44c5a6SAntoine Ténart 			.cra_driver_name = "safexcel-cbc-aes",
1341aa88f331SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
13422c95e6d9SEric Biggers 			.cra_flags = CRYPTO_ALG_ASYNC |
1343b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
13441b44c5a6SAntoine Ténart 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
13451b44c5a6SAntoine Ténart 			.cra_blocksize = AES_BLOCK_SIZE,
13461b44c5a6SAntoine Ténart 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
13471b44c5a6SAntoine Ténart 			.cra_alignmask = 0,
134893369b5dSPascal van Leeuwen 			.cra_init = safexcel_skcipher_aes_cbc_cra_init,
13491b44c5a6SAntoine Ténart 			.cra_exit = safexcel_skcipher_cra_exit,
13501b44c5a6SAntoine Ténart 			.cra_module = THIS_MODULE,
13511b44c5a6SAntoine Ténart 		},
13521b44c5a6SAntoine Ténart 	},
13531b44c5a6SAntoine Ténart };
1354f6beaea3SAntoine Tenart 
safexcel_skcipher_aesctr_setkey(struct crypto_skcipher * ctfm,const u8 * key,unsigned int len)135554f9e8faSPascal van Leeuwen static int safexcel_skcipher_aesctr_setkey(struct crypto_skcipher *ctfm,
135654f9e8faSPascal van Leeuwen 					   const u8 *key, unsigned int len)
135754f9e8faSPascal van Leeuwen {
135854f9e8faSPascal van Leeuwen 	struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);
135954f9e8faSPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
136018e51895SHerbert Xu 	struct safexcel_crypto_priv *priv = ctx->base.priv;
136154f9e8faSPascal van Leeuwen 	struct crypto_aes_ctx aes;
136254f9e8faSPascal van Leeuwen 	int ret, i;
136354f9e8faSPascal van Leeuwen 	unsigned int keylen;
136454f9e8faSPascal van Leeuwen 
136554f9e8faSPascal van Leeuwen 	/* last 4 bytes of key are the nonce! */
1366f26882a3SPascal van Leeuwen 	ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE);
136754f9e8faSPascal van Leeuwen 	/* exclude the nonce here */
1368f26882a3SPascal van Leeuwen 	keylen = len - CTR_RFC3686_NONCE_SIZE;
136954f9e8faSPascal van Leeuwen 	ret = aes_expandkey(&aes, key, keylen);
1370674f368aSEric Biggers 	if (ret)
137154f9e8faSPascal van Leeuwen 		return ret;
137254f9e8faSPascal van Leeuwen 
137354f9e8faSPascal van Leeuwen 	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
137454f9e8faSPascal van Leeuwen 		for (i = 0; i < keylen / sizeof(u32); i++) {
137513a1bb93SPascal van Leeuwen 			if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {
137654f9e8faSPascal van Leeuwen 				ctx->base.needs_inv = true;
137754f9e8faSPascal van Leeuwen 				break;
137854f9e8faSPascal van Leeuwen 			}
137954f9e8faSPascal van Leeuwen 		}
138054f9e8faSPascal van Leeuwen 	}
138154f9e8faSPascal van Leeuwen 
138254f9e8faSPascal van Leeuwen 	for (i = 0; i < keylen / sizeof(u32); i++)
138354f9e8faSPascal van Leeuwen 		ctx->key[i] = cpu_to_le32(aes.key_enc[i]);
138454f9e8faSPascal van Leeuwen 
138554f9e8faSPascal van Leeuwen 	ctx->key_len = keylen;
138654f9e8faSPascal van Leeuwen 
138754f9e8faSPascal van Leeuwen 	memzero_explicit(&aes, sizeof(aes));
138854f9e8faSPascal van Leeuwen 	return 0;
138954f9e8faSPascal van Leeuwen }
139054f9e8faSPascal van Leeuwen 
safexcel_skcipher_aes_ctr_cra_init(struct crypto_tfm * tfm)139193369b5dSPascal van Leeuwen static int safexcel_skcipher_aes_ctr_cra_init(struct crypto_tfm *tfm)
139293369b5dSPascal van Leeuwen {
139393369b5dSPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
139493369b5dSPascal van Leeuwen 
139593369b5dSPascal van Leeuwen 	safexcel_skcipher_cra_init(tfm);
139693369b5dSPascal van Leeuwen 	ctx->alg  = SAFEXCEL_AES;
1397098e51e5SPascal van Leeuwen 	ctx->blocksz = AES_BLOCK_SIZE;
139893369b5dSPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;
139993369b5dSPascal van Leeuwen 	return 0;
140093369b5dSPascal van Leeuwen }
140193369b5dSPascal van Leeuwen 
140254f9e8faSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ctr_aes = {
140354f9e8faSPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
1404062b64caSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_AES,
140554f9e8faSPascal van Leeuwen 	.alg.skcipher = {
140654f9e8faSPascal van Leeuwen 		.setkey = safexcel_skcipher_aesctr_setkey,
140793369b5dSPascal van Leeuwen 		.encrypt = safexcel_encrypt,
140893369b5dSPascal van Leeuwen 		.decrypt = safexcel_decrypt,
1409f26882a3SPascal van Leeuwen 		/* Add nonce size */
1410f26882a3SPascal van Leeuwen 		.min_keysize = AES_MIN_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,
1411f26882a3SPascal van Leeuwen 		.max_keysize = AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,
1412f26882a3SPascal van Leeuwen 		.ivsize = CTR_RFC3686_IV_SIZE,
141354f9e8faSPascal van Leeuwen 		.base = {
141454f9e8faSPascal van Leeuwen 			.cra_name = "rfc3686(ctr(aes))",
141554f9e8faSPascal van Leeuwen 			.cra_driver_name = "safexcel-ctr-aes",
1416aa88f331SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
141754f9e8faSPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
1418b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
141954f9e8faSPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
142054f9e8faSPascal van Leeuwen 			.cra_blocksize = 1,
142154f9e8faSPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
142254f9e8faSPascal van Leeuwen 			.cra_alignmask = 0,
142393369b5dSPascal van Leeuwen 			.cra_init = safexcel_skcipher_aes_ctr_cra_init,
142454f9e8faSPascal van Leeuwen 			.cra_exit = safexcel_skcipher_cra_exit,
142554f9e8faSPascal van Leeuwen 			.cra_module = THIS_MODULE,
142654f9e8faSPascal van Leeuwen 		},
142754f9e8faSPascal van Leeuwen 	},
142854f9e8faSPascal van Leeuwen };
142954f9e8faSPascal van Leeuwen 
safexcel_des_setkey(struct crypto_skcipher * ctfm,const u8 * key,unsigned int len)1430a7dea8c0SOfer Heifetz static int safexcel_des_setkey(struct crypto_skcipher *ctfm, const u8 *key,
1431a7dea8c0SOfer Heifetz 			       unsigned int len)
1432a7dea8c0SOfer Heifetz {
143321f5a15eSArd Biesheuvel 	struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm);
143418e51895SHerbert Xu 	struct safexcel_crypto_priv *priv = ctx->base.priv;
1435a7dea8c0SOfer Heifetz 	int ret;
1436a7dea8c0SOfer Heifetz 
143721f5a15eSArd Biesheuvel 	ret = verify_skcipher_des_key(ctfm, key);
143821f5a15eSArd Biesheuvel 	if (ret)
143921f5a15eSArd Biesheuvel 		return ret;
1440a7dea8c0SOfer Heifetz 
1441a7dea8c0SOfer Heifetz 	/* if context exits and key changed, need to invalidate it */
1442177e358cSPascal van Leeuwen 	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma)
1443a7dea8c0SOfer Heifetz 		if (memcmp(ctx->key, key, len))
1444a7dea8c0SOfer Heifetz 			ctx->base.needs_inv = true;
1445a7dea8c0SOfer Heifetz 
1446a7dea8c0SOfer Heifetz 	memcpy(ctx->key, key, len);
1447a7dea8c0SOfer Heifetz 	ctx->key_len = len;
1448a7dea8c0SOfer Heifetz 
1449a7dea8c0SOfer Heifetz 	return 0;
1450a7dea8c0SOfer Heifetz }
1451a7dea8c0SOfer Heifetz 
safexcel_skcipher_des_cbc_cra_init(struct crypto_tfm * tfm)145293369b5dSPascal van Leeuwen static int safexcel_skcipher_des_cbc_cra_init(struct crypto_tfm *tfm)
145393369b5dSPascal van Leeuwen {
145493369b5dSPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
145593369b5dSPascal van Leeuwen 
145693369b5dSPascal van Leeuwen 	safexcel_skcipher_cra_init(tfm);
145793369b5dSPascal van Leeuwen 	ctx->alg  = SAFEXCEL_DES;
1458098e51e5SPascal van Leeuwen 	ctx->blocksz = DES_BLOCK_SIZE;
1459098e51e5SPascal van Leeuwen 	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
146093369b5dSPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC;
146193369b5dSPascal van Leeuwen 	return 0;
146293369b5dSPascal van Leeuwen }
146393369b5dSPascal van Leeuwen 
1464a7dea8c0SOfer Heifetz struct safexcel_alg_template safexcel_alg_cbc_des = {
1465a7dea8c0SOfer Heifetz 	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
1466062b64caSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_DES,
1467a7dea8c0SOfer Heifetz 	.alg.skcipher = {
1468a7dea8c0SOfer Heifetz 		.setkey = safexcel_des_setkey,
146993369b5dSPascal van Leeuwen 		.encrypt = safexcel_encrypt,
147093369b5dSPascal van Leeuwen 		.decrypt = safexcel_decrypt,
1471a7dea8c0SOfer Heifetz 		.min_keysize = DES_KEY_SIZE,
1472a7dea8c0SOfer Heifetz 		.max_keysize = DES_KEY_SIZE,
1473a7dea8c0SOfer Heifetz 		.ivsize = DES_BLOCK_SIZE,
1474a7dea8c0SOfer Heifetz 		.base = {
1475a7dea8c0SOfer Heifetz 			.cra_name = "cbc(des)",
1476a7dea8c0SOfer Heifetz 			.cra_driver_name = "safexcel-cbc-des",
1477aa88f331SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
14782b78aeb3SEric Biggers 			.cra_flags = CRYPTO_ALG_ASYNC |
1479b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
1480a7dea8c0SOfer Heifetz 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
1481a7dea8c0SOfer Heifetz 			.cra_blocksize = DES_BLOCK_SIZE,
1482a7dea8c0SOfer Heifetz 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
1483a7dea8c0SOfer Heifetz 			.cra_alignmask = 0,
148493369b5dSPascal van Leeuwen 			.cra_init = safexcel_skcipher_des_cbc_cra_init,
1485a7dea8c0SOfer Heifetz 			.cra_exit = safexcel_skcipher_cra_exit,
1486a7dea8c0SOfer Heifetz 			.cra_module = THIS_MODULE,
1487a7dea8c0SOfer Heifetz 		},
1488a7dea8c0SOfer Heifetz 	},
1489a7dea8c0SOfer Heifetz };
1490a7dea8c0SOfer Heifetz 
safexcel_skcipher_des_ecb_cra_init(struct crypto_tfm * tfm)149193369b5dSPascal van Leeuwen static int safexcel_skcipher_des_ecb_cra_init(struct crypto_tfm *tfm)
1492a7dea8c0SOfer Heifetz {
149393369b5dSPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
1494a7dea8c0SOfer Heifetz 
149593369b5dSPascal van Leeuwen 	safexcel_skcipher_cra_init(tfm);
149693369b5dSPascal van Leeuwen 	ctx->alg  = SAFEXCEL_DES;
149793369b5dSPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB;
1498098e51e5SPascal van Leeuwen 	ctx->blocksz = 0;
1499098e51e5SPascal van Leeuwen 	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
150093369b5dSPascal van Leeuwen 	return 0;
1501a7dea8c0SOfer Heifetz }
1502a7dea8c0SOfer Heifetz 
1503a7dea8c0SOfer Heifetz struct safexcel_alg_template safexcel_alg_ecb_des = {
1504a7dea8c0SOfer Heifetz 	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
1505062b64caSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_DES,
1506a7dea8c0SOfer Heifetz 	.alg.skcipher = {
1507a7dea8c0SOfer Heifetz 		.setkey = safexcel_des_setkey,
150893369b5dSPascal van Leeuwen 		.encrypt = safexcel_encrypt,
150993369b5dSPascal van Leeuwen 		.decrypt = safexcel_decrypt,
1510a7dea8c0SOfer Heifetz 		.min_keysize = DES_KEY_SIZE,
1511a7dea8c0SOfer Heifetz 		.max_keysize = DES_KEY_SIZE,
1512a7dea8c0SOfer Heifetz 		.base = {
1513a7dea8c0SOfer Heifetz 			.cra_name = "ecb(des)",
1514a7dea8c0SOfer Heifetz 			.cra_driver_name = "safexcel-ecb-des",
1515aa88f331SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
15162b78aeb3SEric Biggers 			.cra_flags = CRYPTO_ALG_ASYNC |
1517b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
1518a7dea8c0SOfer Heifetz 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
1519a7dea8c0SOfer Heifetz 			.cra_blocksize = DES_BLOCK_SIZE,
1520a7dea8c0SOfer Heifetz 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
1521a7dea8c0SOfer Heifetz 			.cra_alignmask = 0,
152293369b5dSPascal van Leeuwen 			.cra_init = safexcel_skcipher_des_ecb_cra_init,
1523a7dea8c0SOfer Heifetz 			.cra_exit = safexcel_skcipher_cra_exit,
1524a7dea8c0SOfer Heifetz 			.cra_module = THIS_MODULE,
1525a7dea8c0SOfer Heifetz 		},
1526a7dea8c0SOfer Heifetz 	},
1527a7dea8c0SOfer Heifetz };
152862469879SOfer Heifetz 
safexcel_des3_ede_setkey(struct crypto_skcipher * ctfm,const u8 * key,unsigned int len)152962469879SOfer Heifetz static int safexcel_des3_ede_setkey(struct crypto_skcipher *ctfm,
153062469879SOfer Heifetz 				   const u8 *key, unsigned int len)
153162469879SOfer Heifetz {
153267ac62bfSHerbert Xu 	struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm);
153318e51895SHerbert Xu 	struct safexcel_crypto_priv *priv = ctx->base.priv;
153467ac62bfSHerbert Xu 	int err;
153562469879SOfer Heifetz 
153621f5a15eSArd Biesheuvel 	err = verify_skcipher_des3_key(ctfm, key);
153721f5a15eSArd Biesheuvel 	if (err)
153867ac62bfSHerbert Xu 		return err;
153962469879SOfer Heifetz 
154062469879SOfer Heifetz 	/* if context exits and key changed, need to invalidate it */
1541177e358cSPascal van Leeuwen 	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma)
154262469879SOfer Heifetz 		if (memcmp(ctx->key, key, len))
154362469879SOfer Heifetz 			ctx->base.needs_inv = true;
154462469879SOfer Heifetz 
154562469879SOfer Heifetz 	memcpy(ctx->key, key, len);
154662469879SOfer Heifetz 	ctx->key_len = len;
154762469879SOfer Heifetz 
154862469879SOfer Heifetz 	return 0;
154962469879SOfer Heifetz }
155062469879SOfer Heifetz 
safexcel_skcipher_des3_cbc_cra_init(struct crypto_tfm * tfm)155193369b5dSPascal van Leeuwen static int safexcel_skcipher_des3_cbc_cra_init(struct crypto_tfm *tfm)
155293369b5dSPascal van Leeuwen {
155393369b5dSPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
155493369b5dSPascal van Leeuwen 
155593369b5dSPascal van Leeuwen 	safexcel_skcipher_cra_init(tfm);
155693369b5dSPascal van Leeuwen 	ctx->alg  = SAFEXCEL_3DES;
1557098e51e5SPascal van Leeuwen 	ctx->blocksz = DES3_EDE_BLOCK_SIZE;
1558098e51e5SPascal van Leeuwen 	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
155993369b5dSPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC;
156093369b5dSPascal van Leeuwen 	return 0;
156193369b5dSPascal van Leeuwen }
156293369b5dSPascal van Leeuwen 
156362469879SOfer Heifetz struct safexcel_alg_template safexcel_alg_cbc_des3_ede = {
156462469879SOfer Heifetz 	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
1565062b64caSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_DES,
156662469879SOfer Heifetz 	.alg.skcipher = {
156762469879SOfer Heifetz 		.setkey = safexcel_des3_ede_setkey,
156893369b5dSPascal van Leeuwen 		.encrypt = safexcel_encrypt,
156993369b5dSPascal van Leeuwen 		.decrypt = safexcel_decrypt,
157062469879SOfer Heifetz 		.min_keysize = DES3_EDE_KEY_SIZE,
157162469879SOfer Heifetz 		.max_keysize = DES3_EDE_KEY_SIZE,
157262469879SOfer Heifetz 		.ivsize = DES3_EDE_BLOCK_SIZE,
157362469879SOfer Heifetz 		.base = {
157462469879SOfer Heifetz 			.cra_name = "cbc(des3_ede)",
157562469879SOfer Heifetz 			.cra_driver_name = "safexcel-cbc-des3_ede",
1576aa88f331SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
15772b78aeb3SEric Biggers 			.cra_flags = CRYPTO_ALG_ASYNC |
1578b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
157962469879SOfer Heifetz 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
158062469879SOfer Heifetz 			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
158162469879SOfer Heifetz 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
158262469879SOfer Heifetz 			.cra_alignmask = 0,
158393369b5dSPascal van Leeuwen 			.cra_init = safexcel_skcipher_des3_cbc_cra_init,
158462469879SOfer Heifetz 			.cra_exit = safexcel_skcipher_cra_exit,
158562469879SOfer Heifetz 			.cra_module = THIS_MODULE,
158662469879SOfer Heifetz 		},
158762469879SOfer Heifetz 	},
158862469879SOfer Heifetz };
158962469879SOfer Heifetz 
safexcel_skcipher_des3_ecb_cra_init(struct crypto_tfm * tfm)159093369b5dSPascal van Leeuwen static int safexcel_skcipher_des3_ecb_cra_init(struct crypto_tfm *tfm)
159162469879SOfer Heifetz {
159293369b5dSPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
159362469879SOfer Heifetz 
159493369b5dSPascal van Leeuwen 	safexcel_skcipher_cra_init(tfm);
159593369b5dSPascal van Leeuwen 	ctx->alg  = SAFEXCEL_3DES;
159693369b5dSPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB;
1597098e51e5SPascal van Leeuwen 	ctx->blocksz = 0;
1598098e51e5SPascal van Leeuwen 	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
159993369b5dSPascal van Leeuwen 	return 0;
160062469879SOfer Heifetz }
160162469879SOfer Heifetz 
160262469879SOfer Heifetz struct safexcel_alg_template safexcel_alg_ecb_des3_ede = {
160362469879SOfer Heifetz 	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
1604062b64caSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_DES,
160562469879SOfer Heifetz 	.alg.skcipher = {
160662469879SOfer Heifetz 		.setkey = safexcel_des3_ede_setkey,
160793369b5dSPascal van Leeuwen 		.encrypt = safexcel_encrypt,
160893369b5dSPascal van Leeuwen 		.decrypt = safexcel_decrypt,
160962469879SOfer Heifetz 		.min_keysize = DES3_EDE_KEY_SIZE,
161062469879SOfer Heifetz 		.max_keysize = DES3_EDE_KEY_SIZE,
161162469879SOfer Heifetz 		.base = {
161262469879SOfer Heifetz 			.cra_name = "ecb(des3_ede)",
161362469879SOfer Heifetz 			.cra_driver_name = "safexcel-ecb-des3_ede",
1614aa88f331SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
16152b78aeb3SEric Biggers 			.cra_flags = CRYPTO_ALG_ASYNC |
1616b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
161762469879SOfer Heifetz 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
161862469879SOfer Heifetz 			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
161962469879SOfer Heifetz 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
162062469879SOfer Heifetz 			.cra_alignmask = 0,
162193369b5dSPascal van Leeuwen 			.cra_init = safexcel_skcipher_des3_ecb_cra_init,
162262469879SOfer Heifetz 			.cra_exit = safexcel_skcipher_cra_exit,
162362469879SOfer Heifetz 			.cra_module = THIS_MODULE,
162462469879SOfer Heifetz 		},
162562469879SOfer Heifetz 	},
162662469879SOfer Heifetz };
162762469879SOfer Heifetz 
safexcel_aead_encrypt(struct aead_request * req)162893369b5dSPascal van Leeuwen static int safexcel_aead_encrypt(struct aead_request *req)
1629f6beaea3SAntoine Tenart {
1630f6beaea3SAntoine Tenart 	struct safexcel_cipher_req *creq = aead_request_ctx(req);
1631f6beaea3SAntoine Tenart 
163293369b5dSPascal van Leeuwen 	return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT);
1633f6beaea3SAntoine Tenart }
1634f6beaea3SAntoine Tenart 
safexcel_aead_decrypt(struct aead_request * req)163593369b5dSPascal van Leeuwen static int safexcel_aead_decrypt(struct aead_request *req)
1636f6beaea3SAntoine Tenart {
1637f6beaea3SAntoine Tenart 	struct safexcel_cipher_req *creq = aead_request_ctx(req);
1638f6beaea3SAntoine Tenart 
163993369b5dSPascal van Leeuwen 	return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT);
1640f6beaea3SAntoine Tenart }
1641f6beaea3SAntoine Tenart 
safexcel_aead_cra_init(struct crypto_tfm * tfm)1642f6beaea3SAntoine Tenart static int safexcel_aead_cra_init(struct crypto_tfm *tfm)
1643f6beaea3SAntoine Tenart {
1644f6beaea3SAntoine Tenart 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
1645f6beaea3SAntoine Tenart 	struct safexcel_alg_template *tmpl =
1646f6beaea3SAntoine Tenart 		container_of(tfm->__crt_alg, struct safexcel_alg_template,
1647f6beaea3SAntoine Tenart 			     alg.aead.base);
1648f6beaea3SAntoine Tenart 
1649f6beaea3SAntoine Tenart 	crypto_aead_set_reqsize(__crypto_aead_cast(tfm),
1650f6beaea3SAntoine Tenart 				sizeof(struct safexcel_cipher_req));
1651f6beaea3SAntoine Tenart 
165218e51895SHerbert Xu 	ctx->base.priv = tmpl->priv;
1653f6beaea3SAntoine Tenart 
16540e17e362SPascal van Leeuwen 	ctx->alg  = SAFEXCEL_AES; /* default */
1655098e51e5SPascal van Leeuwen 	ctx->blocksz = AES_BLOCK_SIZE;
1656098e51e5SPascal van Leeuwen 	ctx->ivmask = EIP197_OPTION_4_TOKEN_IV_CMD;
1657098e51e5SPascal van Leeuwen 	ctx->ctrinit = 1;
165893369b5dSPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC; /* default */
1659f6beaea3SAntoine Tenart 	ctx->aead = true;
1660f6beaea3SAntoine Tenart 	ctx->base.send = safexcel_aead_send;
1661f6beaea3SAntoine Tenart 	ctx->base.handle_result = safexcel_aead_handle_result;
1662f6beaea3SAntoine Tenart 	return 0;
1663f6beaea3SAntoine Tenart }
1664f6beaea3SAntoine Tenart 
safexcel_aead_sha1_cra_init(struct crypto_tfm * tfm)166501ba061dSAntoine Tenart static int safexcel_aead_sha1_cra_init(struct crypto_tfm *tfm)
166601ba061dSAntoine Tenart {
166701ba061dSAntoine Tenart 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
166801ba061dSAntoine Tenart 
166901ba061dSAntoine Tenart 	safexcel_aead_cra_init(tfm);
1670a7dea8c0SOfer Heifetz 	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1;
167101ba061dSAntoine Tenart 	ctx->state_sz = SHA1_DIGEST_SIZE;
167201ba061dSAntoine Tenart 	return 0;
167301ba061dSAntoine Tenart }
167401ba061dSAntoine Tenart 
167501ba061dSAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_aes = {
167601ba061dSAntoine Tenart 	.type = SAFEXCEL_ALG_TYPE_AEAD,
1677062b64caSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA1,
167801ba061dSAntoine Tenart 	.alg.aead = {
167977cdd4efSPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
168093369b5dSPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
168193369b5dSPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
168201ba061dSAntoine Tenart 		.ivsize = AES_BLOCK_SIZE,
168301ba061dSAntoine Tenart 		.maxauthsize = SHA1_DIGEST_SIZE,
168401ba061dSAntoine Tenart 		.base = {
168501ba061dSAntoine Tenart 			.cra_name = "authenc(hmac(sha1),cbc(aes))",
168601ba061dSAntoine Tenart 			.cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-aes",
1687aa88f331SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
16883f4a537aSEric Biggers 			.cra_flags = CRYPTO_ALG_ASYNC |
1689b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
169001ba061dSAntoine Tenart 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
169101ba061dSAntoine Tenart 			.cra_blocksize = AES_BLOCK_SIZE,
169201ba061dSAntoine Tenart 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
169301ba061dSAntoine Tenart 			.cra_alignmask = 0,
169401ba061dSAntoine Tenart 			.cra_init = safexcel_aead_sha1_cra_init,
169501ba061dSAntoine Tenart 			.cra_exit = safexcel_aead_cra_exit,
169601ba061dSAntoine Tenart 			.cra_module = THIS_MODULE,
169701ba061dSAntoine Tenart 		},
169801ba061dSAntoine Tenart 	},
169901ba061dSAntoine Tenart };
170001ba061dSAntoine Tenart 
safexcel_aead_sha256_cra_init(struct crypto_tfm * tfm)1701f6beaea3SAntoine Tenart static int safexcel_aead_sha256_cra_init(struct crypto_tfm *tfm)
1702f6beaea3SAntoine Tenart {
1703f6beaea3SAntoine Tenart 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
1704f6beaea3SAntoine Tenart 
1705f6beaea3SAntoine Tenart 	safexcel_aead_cra_init(tfm);
1706a7dea8c0SOfer Heifetz 	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA256;
1707f6beaea3SAntoine Tenart 	ctx->state_sz = SHA256_DIGEST_SIZE;
1708f6beaea3SAntoine Tenart 	return 0;
1709f6beaea3SAntoine Tenart }
1710f6beaea3SAntoine Tenart 
1711f6beaea3SAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_aes = {
1712f6beaea3SAntoine Tenart 	.type = SAFEXCEL_ALG_TYPE_AEAD,
1713062b64caSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256,
1714f6beaea3SAntoine Tenart 	.alg.aead = {
171577cdd4efSPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
171693369b5dSPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
171793369b5dSPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
1718f6beaea3SAntoine Tenart 		.ivsize = AES_BLOCK_SIZE,
1719f6beaea3SAntoine Tenart 		.maxauthsize = SHA256_DIGEST_SIZE,
1720f6beaea3SAntoine Tenart 		.base = {
1721f6beaea3SAntoine Tenart 			.cra_name = "authenc(hmac(sha256),cbc(aes))",
1722f6beaea3SAntoine Tenart 			.cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-aes",
1723aa88f331SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
17243f4a537aSEric Biggers 			.cra_flags = CRYPTO_ALG_ASYNC |
1725b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
1726f6beaea3SAntoine Tenart 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
1727f6beaea3SAntoine Tenart 			.cra_blocksize = AES_BLOCK_SIZE,
1728f6beaea3SAntoine Tenart 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
1729f6beaea3SAntoine Tenart 			.cra_alignmask = 0,
1730f6beaea3SAntoine Tenart 			.cra_init = safexcel_aead_sha256_cra_init,
1731f6beaea3SAntoine Tenart 			.cra_exit = safexcel_aead_cra_exit,
1732f6beaea3SAntoine Tenart 			.cra_module = THIS_MODULE,
1733f6beaea3SAntoine Tenart 		},
1734f6beaea3SAntoine Tenart 	},
1735f6beaea3SAntoine Tenart };
1736678b2878SAntoine Tenart 
safexcel_aead_sha224_cra_init(struct crypto_tfm * tfm)1737678b2878SAntoine Tenart static int safexcel_aead_sha224_cra_init(struct crypto_tfm *tfm)
1738678b2878SAntoine Tenart {
1739678b2878SAntoine Tenart 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
1740678b2878SAntoine Tenart 
1741678b2878SAntoine Tenart 	safexcel_aead_cra_init(tfm);
1742a7dea8c0SOfer Heifetz 	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA224;
1743678b2878SAntoine Tenart 	ctx->state_sz = SHA256_DIGEST_SIZE;
1744678b2878SAntoine Tenart 	return 0;
1745678b2878SAntoine Tenart }
1746678b2878SAntoine Tenart 
1747678b2878SAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_aes = {
1748678b2878SAntoine Tenart 	.type = SAFEXCEL_ALG_TYPE_AEAD,
1749062b64caSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256,
1750678b2878SAntoine Tenart 	.alg.aead = {
175177cdd4efSPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
175293369b5dSPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
175393369b5dSPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
1754678b2878SAntoine Tenart 		.ivsize = AES_BLOCK_SIZE,
1755678b2878SAntoine Tenart 		.maxauthsize = SHA224_DIGEST_SIZE,
1756678b2878SAntoine Tenart 		.base = {
1757678b2878SAntoine Tenart 			.cra_name = "authenc(hmac(sha224),cbc(aes))",
1758678b2878SAntoine Tenart 			.cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-aes",
1759aa88f331SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
17603f4a537aSEric Biggers 			.cra_flags = CRYPTO_ALG_ASYNC |
1761b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
1762678b2878SAntoine Tenart 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
1763678b2878SAntoine Tenart 			.cra_blocksize = AES_BLOCK_SIZE,
1764678b2878SAntoine Tenart 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
1765678b2878SAntoine Tenart 			.cra_alignmask = 0,
1766678b2878SAntoine Tenart 			.cra_init = safexcel_aead_sha224_cra_init,
1767678b2878SAntoine Tenart 			.cra_exit = safexcel_aead_cra_exit,
1768678b2878SAntoine Tenart 			.cra_module = THIS_MODULE,
1769678b2878SAntoine Tenart 		},
1770678b2878SAntoine Tenart 	},
1771678b2878SAntoine Tenart };
177287eee125SAntoine Tenart 
safexcel_aead_sha512_cra_init(struct crypto_tfm * tfm)177387eee125SAntoine Tenart static int safexcel_aead_sha512_cra_init(struct crypto_tfm *tfm)
177487eee125SAntoine Tenart {
177587eee125SAntoine Tenart 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
177687eee125SAntoine Tenart 
177787eee125SAntoine Tenart 	safexcel_aead_cra_init(tfm);
1778a7dea8c0SOfer Heifetz 	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA512;
177987eee125SAntoine Tenart 	ctx->state_sz = SHA512_DIGEST_SIZE;
178087eee125SAntoine Tenart 	return 0;
178187eee125SAntoine Tenart }
178287eee125SAntoine Tenart 
178387eee125SAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_aes = {
178487eee125SAntoine Tenart 	.type = SAFEXCEL_ALG_TYPE_AEAD,
1785062b64caSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512,
178687eee125SAntoine Tenart 	.alg.aead = {
178777cdd4efSPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
178893369b5dSPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
178993369b5dSPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
179087eee125SAntoine Tenart 		.ivsize = AES_BLOCK_SIZE,
179187eee125SAntoine Tenart 		.maxauthsize = SHA512_DIGEST_SIZE,
179287eee125SAntoine Tenart 		.base = {
179387eee125SAntoine Tenart 			.cra_name = "authenc(hmac(sha512),cbc(aes))",
179487eee125SAntoine Tenart 			.cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-aes",
1795aa88f331SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
17963f4a537aSEric Biggers 			.cra_flags = CRYPTO_ALG_ASYNC |
1797b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
179887eee125SAntoine Tenart 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
179987eee125SAntoine Tenart 			.cra_blocksize = AES_BLOCK_SIZE,
180087eee125SAntoine Tenart 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
180187eee125SAntoine Tenart 			.cra_alignmask = 0,
180287eee125SAntoine Tenart 			.cra_init = safexcel_aead_sha512_cra_init,
180387eee125SAntoine Tenart 			.cra_exit = safexcel_aead_cra_exit,
180487eee125SAntoine Tenart 			.cra_module = THIS_MODULE,
180587eee125SAntoine Tenart 		},
180687eee125SAntoine Tenart 	},
180787eee125SAntoine Tenart };
1808ea23cb53SAntoine Tenart 
safexcel_aead_sha384_cra_init(struct crypto_tfm * tfm)1809ea23cb53SAntoine Tenart static int safexcel_aead_sha384_cra_init(struct crypto_tfm *tfm)
1810ea23cb53SAntoine Tenart {
1811ea23cb53SAntoine Tenart 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
1812ea23cb53SAntoine Tenart 
1813ea23cb53SAntoine Tenart 	safexcel_aead_cra_init(tfm);
1814a7dea8c0SOfer Heifetz 	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA384;
1815ea23cb53SAntoine Tenart 	ctx->state_sz = SHA512_DIGEST_SIZE;
1816ea23cb53SAntoine Tenart 	return 0;
1817ea23cb53SAntoine Tenart }
1818ea23cb53SAntoine Tenart 
1819ea23cb53SAntoine Tenart struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_aes = {
1820ea23cb53SAntoine Tenart 	.type = SAFEXCEL_ALG_TYPE_AEAD,
1821062b64caSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512,
1822ea23cb53SAntoine Tenart 	.alg.aead = {
182377cdd4efSPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
182493369b5dSPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
182593369b5dSPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
1826ea23cb53SAntoine Tenart 		.ivsize = AES_BLOCK_SIZE,
1827ea23cb53SAntoine Tenart 		.maxauthsize = SHA384_DIGEST_SIZE,
1828ea23cb53SAntoine Tenart 		.base = {
1829ea23cb53SAntoine Tenart 			.cra_name = "authenc(hmac(sha384),cbc(aes))",
1830ea23cb53SAntoine Tenart 			.cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-aes",
1831aa88f331SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
18323f4a537aSEric Biggers 			.cra_flags = CRYPTO_ALG_ASYNC |
1833b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
1834ea23cb53SAntoine Tenart 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
1835ea23cb53SAntoine Tenart 			.cra_blocksize = AES_BLOCK_SIZE,
1836ea23cb53SAntoine Tenart 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
1837ea23cb53SAntoine Tenart 			.cra_alignmask = 0,
1838ea23cb53SAntoine Tenart 			.cra_init = safexcel_aead_sha384_cra_init,
1839ea23cb53SAntoine Tenart 			.cra_exit = safexcel_aead_cra_exit,
1840ea23cb53SAntoine Tenart 			.cra_module = THIS_MODULE,
1841ea23cb53SAntoine Tenart 		},
1842ea23cb53SAntoine Tenart 	},
1843ea23cb53SAntoine Tenart };
184477cdd4efSPascal van Leeuwen 
safexcel_aead_sha1_des3_cra_init(struct crypto_tfm * tfm)18450e17e362SPascal van Leeuwen static int safexcel_aead_sha1_des3_cra_init(struct crypto_tfm *tfm)
18460e17e362SPascal van Leeuwen {
18470e17e362SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
18480e17e362SPascal van Leeuwen 
18490e17e362SPascal van Leeuwen 	safexcel_aead_sha1_cra_init(tfm);
18500e17e362SPascal van Leeuwen 	ctx->alg = SAFEXCEL_3DES; /* override default */
1851098e51e5SPascal van Leeuwen 	ctx->blocksz = DES3_EDE_BLOCK_SIZE;
1852098e51e5SPascal van Leeuwen 	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
18530e17e362SPascal van Leeuwen 	return 0;
18540e17e362SPascal van Leeuwen }
18550e17e362SPascal van Leeuwen 
185677cdd4efSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des3_ede = {
185777cdd4efSPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
1858062b64caSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1,
185977cdd4efSPascal van Leeuwen 	.alg.aead = {
186077cdd4efSPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
186193369b5dSPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
186293369b5dSPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
186377cdd4efSPascal van Leeuwen 		.ivsize = DES3_EDE_BLOCK_SIZE,
186477cdd4efSPascal van Leeuwen 		.maxauthsize = SHA1_DIGEST_SIZE,
186577cdd4efSPascal van Leeuwen 		.base = {
186677cdd4efSPascal van Leeuwen 			.cra_name = "authenc(hmac(sha1),cbc(des3_ede))",
186777cdd4efSPascal van Leeuwen 			.cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des3_ede",
1868aa88f331SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
186977cdd4efSPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
1870b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
187177cdd4efSPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
187277cdd4efSPascal van Leeuwen 			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
187377cdd4efSPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
187477cdd4efSPascal van Leeuwen 			.cra_alignmask = 0,
18750e17e362SPascal van Leeuwen 			.cra_init = safexcel_aead_sha1_des3_cra_init,
18760e17e362SPascal van Leeuwen 			.cra_exit = safexcel_aead_cra_exit,
18770e17e362SPascal van Leeuwen 			.cra_module = THIS_MODULE,
18780e17e362SPascal van Leeuwen 		},
18790e17e362SPascal van Leeuwen 	},
18800e17e362SPascal van Leeuwen };
18810e17e362SPascal van Leeuwen 
safexcel_aead_sha256_des3_cra_init(struct crypto_tfm * tfm)1882f0a8bdf0SPascal van Leeuwen static int safexcel_aead_sha256_des3_cra_init(struct crypto_tfm *tfm)
1883f0a8bdf0SPascal van Leeuwen {
1884f0a8bdf0SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
1885f0a8bdf0SPascal van Leeuwen 
1886f0a8bdf0SPascal van Leeuwen 	safexcel_aead_sha256_cra_init(tfm);
1887f0a8bdf0SPascal van Leeuwen 	ctx->alg = SAFEXCEL_3DES; /* override default */
1888098e51e5SPascal van Leeuwen 	ctx->blocksz = DES3_EDE_BLOCK_SIZE;
1889098e51e5SPascal van Leeuwen 	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
1890f0a8bdf0SPascal van Leeuwen 	return 0;
1891f0a8bdf0SPascal van Leeuwen }
1892f0a8bdf0SPascal van Leeuwen 
1893f0a8bdf0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des3_ede = {
1894f0a8bdf0SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
1895f0a8bdf0SPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256,
1896f0a8bdf0SPascal van Leeuwen 	.alg.aead = {
1897f0a8bdf0SPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
1898f0a8bdf0SPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
1899f0a8bdf0SPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
1900f0a8bdf0SPascal van Leeuwen 		.ivsize = DES3_EDE_BLOCK_SIZE,
1901f0a8bdf0SPascal van Leeuwen 		.maxauthsize = SHA256_DIGEST_SIZE,
1902f0a8bdf0SPascal van Leeuwen 		.base = {
1903f0a8bdf0SPascal van Leeuwen 			.cra_name = "authenc(hmac(sha256),cbc(des3_ede))",
1904f0a8bdf0SPascal van Leeuwen 			.cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des3_ede",
1905f0a8bdf0SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
1906f0a8bdf0SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
1907b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
1908f0a8bdf0SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
1909f0a8bdf0SPascal van Leeuwen 			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
1910f0a8bdf0SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
1911f0a8bdf0SPascal van Leeuwen 			.cra_alignmask = 0,
1912f0a8bdf0SPascal van Leeuwen 			.cra_init = safexcel_aead_sha256_des3_cra_init,
1913f0a8bdf0SPascal van Leeuwen 			.cra_exit = safexcel_aead_cra_exit,
1914f0a8bdf0SPascal van Leeuwen 			.cra_module = THIS_MODULE,
1915f0a8bdf0SPascal van Leeuwen 		},
1916f0a8bdf0SPascal van Leeuwen 	},
1917f0a8bdf0SPascal van Leeuwen };
1918f0a8bdf0SPascal van Leeuwen 
safexcel_aead_sha224_des3_cra_init(struct crypto_tfm * tfm)1919f0a8bdf0SPascal van Leeuwen static int safexcel_aead_sha224_des3_cra_init(struct crypto_tfm *tfm)
1920f0a8bdf0SPascal van Leeuwen {
1921f0a8bdf0SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
1922f0a8bdf0SPascal van Leeuwen 
1923f0a8bdf0SPascal van Leeuwen 	safexcel_aead_sha224_cra_init(tfm);
1924f0a8bdf0SPascal van Leeuwen 	ctx->alg = SAFEXCEL_3DES; /* override default */
1925098e51e5SPascal van Leeuwen 	ctx->blocksz = DES3_EDE_BLOCK_SIZE;
1926098e51e5SPascal van Leeuwen 	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
1927f0a8bdf0SPascal van Leeuwen 	return 0;
1928f0a8bdf0SPascal van Leeuwen }
1929f0a8bdf0SPascal van Leeuwen 
1930f0a8bdf0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des3_ede = {
1931f0a8bdf0SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
1932f0a8bdf0SPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256,
1933f0a8bdf0SPascal van Leeuwen 	.alg.aead = {
1934f0a8bdf0SPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
1935f0a8bdf0SPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
1936f0a8bdf0SPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
1937f0a8bdf0SPascal van Leeuwen 		.ivsize = DES3_EDE_BLOCK_SIZE,
1938f0a8bdf0SPascal van Leeuwen 		.maxauthsize = SHA224_DIGEST_SIZE,
1939f0a8bdf0SPascal van Leeuwen 		.base = {
1940f0a8bdf0SPascal van Leeuwen 			.cra_name = "authenc(hmac(sha224),cbc(des3_ede))",
1941f0a8bdf0SPascal van Leeuwen 			.cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des3_ede",
1942f0a8bdf0SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
1943f0a8bdf0SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
1944b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
1945f0a8bdf0SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
1946f0a8bdf0SPascal van Leeuwen 			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
1947f0a8bdf0SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
1948f0a8bdf0SPascal van Leeuwen 			.cra_alignmask = 0,
1949f0a8bdf0SPascal van Leeuwen 			.cra_init = safexcel_aead_sha224_des3_cra_init,
1950f0a8bdf0SPascal van Leeuwen 			.cra_exit = safexcel_aead_cra_exit,
1951f0a8bdf0SPascal van Leeuwen 			.cra_module = THIS_MODULE,
1952f0a8bdf0SPascal van Leeuwen 		},
1953f0a8bdf0SPascal van Leeuwen 	},
1954f0a8bdf0SPascal van Leeuwen };
1955f0a8bdf0SPascal van Leeuwen 
safexcel_aead_sha512_des3_cra_init(struct crypto_tfm * tfm)1956f0a8bdf0SPascal van Leeuwen static int safexcel_aead_sha512_des3_cra_init(struct crypto_tfm *tfm)
1957f0a8bdf0SPascal van Leeuwen {
1958f0a8bdf0SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
1959f0a8bdf0SPascal van Leeuwen 
1960f0a8bdf0SPascal van Leeuwen 	safexcel_aead_sha512_cra_init(tfm);
1961f0a8bdf0SPascal van Leeuwen 	ctx->alg = SAFEXCEL_3DES; /* override default */
1962098e51e5SPascal van Leeuwen 	ctx->blocksz = DES3_EDE_BLOCK_SIZE;
1963098e51e5SPascal van Leeuwen 	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
1964f0a8bdf0SPascal van Leeuwen 	return 0;
1965f0a8bdf0SPascal van Leeuwen }
1966f0a8bdf0SPascal van Leeuwen 
1967f0a8bdf0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des3_ede = {
1968f0a8bdf0SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
1969f0a8bdf0SPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512,
1970f0a8bdf0SPascal van Leeuwen 	.alg.aead = {
1971f0a8bdf0SPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
1972f0a8bdf0SPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
1973f0a8bdf0SPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
1974f0a8bdf0SPascal van Leeuwen 		.ivsize = DES3_EDE_BLOCK_SIZE,
1975f0a8bdf0SPascal van Leeuwen 		.maxauthsize = SHA512_DIGEST_SIZE,
1976f0a8bdf0SPascal van Leeuwen 		.base = {
1977f0a8bdf0SPascal van Leeuwen 			.cra_name = "authenc(hmac(sha512),cbc(des3_ede))",
1978f0a8bdf0SPascal van Leeuwen 			.cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des3_ede",
1979f0a8bdf0SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
1980f0a8bdf0SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
1981b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
1982f0a8bdf0SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
1983f0a8bdf0SPascal van Leeuwen 			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
1984f0a8bdf0SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
1985f0a8bdf0SPascal van Leeuwen 			.cra_alignmask = 0,
1986f0a8bdf0SPascal van Leeuwen 			.cra_init = safexcel_aead_sha512_des3_cra_init,
1987f0a8bdf0SPascal van Leeuwen 			.cra_exit = safexcel_aead_cra_exit,
1988f0a8bdf0SPascal van Leeuwen 			.cra_module = THIS_MODULE,
1989f0a8bdf0SPascal van Leeuwen 		},
1990f0a8bdf0SPascal van Leeuwen 	},
1991f0a8bdf0SPascal van Leeuwen };
1992f0a8bdf0SPascal van Leeuwen 
safexcel_aead_sha384_des3_cra_init(struct crypto_tfm * tfm)1993f0a8bdf0SPascal van Leeuwen static int safexcel_aead_sha384_des3_cra_init(struct crypto_tfm *tfm)
1994f0a8bdf0SPascal van Leeuwen {
1995f0a8bdf0SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
1996f0a8bdf0SPascal van Leeuwen 
1997f0a8bdf0SPascal van Leeuwen 	safexcel_aead_sha384_cra_init(tfm);
1998f0a8bdf0SPascal van Leeuwen 	ctx->alg = SAFEXCEL_3DES; /* override default */
1999098e51e5SPascal van Leeuwen 	ctx->blocksz = DES3_EDE_BLOCK_SIZE;
2000098e51e5SPascal van Leeuwen 	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
2001f0a8bdf0SPascal van Leeuwen 	return 0;
2002f0a8bdf0SPascal van Leeuwen }
2003f0a8bdf0SPascal van Leeuwen 
2004f0a8bdf0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des3_ede = {
2005f0a8bdf0SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
2006f0a8bdf0SPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512,
2007f0a8bdf0SPascal van Leeuwen 	.alg.aead = {
2008f0a8bdf0SPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
2009f0a8bdf0SPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
2010f0a8bdf0SPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
2011f0a8bdf0SPascal van Leeuwen 		.ivsize = DES3_EDE_BLOCK_SIZE,
2012f0a8bdf0SPascal van Leeuwen 		.maxauthsize = SHA384_DIGEST_SIZE,
2013f0a8bdf0SPascal van Leeuwen 		.base = {
2014f0a8bdf0SPascal van Leeuwen 			.cra_name = "authenc(hmac(sha384),cbc(des3_ede))",
2015f0a8bdf0SPascal van Leeuwen 			.cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des3_ede",
2016f0a8bdf0SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
2017f0a8bdf0SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
2018b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
2019f0a8bdf0SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
2020f0a8bdf0SPascal van Leeuwen 			.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2021f0a8bdf0SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
2022f0a8bdf0SPascal van Leeuwen 			.cra_alignmask = 0,
2023f0a8bdf0SPascal van Leeuwen 			.cra_init = safexcel_aead_sha384_des3_cra_init,
2024f0a8bdf0SPascal van Leeuwen 			.cra_exit = safexcel_aead_cra_exit,
2025f0a8bdf0SPascal van Leeuwen 			.cra_module = THIS_MODULE,
2026f0a8bdf0SPascal van Leeuwen 		},
2027f0a8bdf0SPascal van Leeuwen 	},
2028f0a8bdf0SPascal van Leeuwen };
2029f0a8bdf0SPascal van Leeuwen 
safexcel_aead_sha1_des_cra_init(struct crypto_tfm * tfm)2030bb7679b8SPascal van Leeuwen static int safexcel_aead_sha1_des_cra_init(struct crypto_tfm *tfm)
2031bb7679b8SPascal van Leeuwen {
2032bb7679b8SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
2033bb7679b8SPascal van Leeuwen 
2034bb7679b8SPascal van Leeuwen 	safexcel_aead_sha1_cra_init(tfm);
2035bb7679b8SPascal van Leeuwen 	ctx->alg = SAFEXCEL_DES; /* override default */
2036098e51e5SPascal van Leeuwen 	ctx->blocksz = DES_BLOCK_SIZE;
2037098e51e5SPascal van Leeuwen 	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
2038bb7679b8SPascal van Leeuwen 	return 0;
2039bb7679b8SPascal van Leeuwen }
2040bb7679b8SPascal van Leeuwen 
2041bb7679b8SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_des = {
2042bb7679b8SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
2043bb7679b8SPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA1,
2044bb7679b8SPascal van Leeuwen 	.alg.aead = {
2045bb7679b8SPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
2046bb7679b8SPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
2047bb7679b8SPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
2048bb7679b8SPascal van Leeuwen 		.ivsize = DES_BLOCK_SIZE,
2049bb7679b8SPascal van Leeuwen 		.maxauthsize = SHA1_DIGEST_SIZE,
2050bb7679b8SPascal van Leeuwen 		.base = {
2051bb7679b8SPascal van Leeuwen 			.cra_name = "authenc(hmac(sha1),cbc(des))",
2052bb7679b8SPascal van Leeuwen 			.cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-des",
2053bb7679b8SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
2054bb7679b8SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
2055b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
2056bb7679b8SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
2057bb7679b8SPascal van Leeuwen 			.cra_blocksize = DES_BLOCK_SIZE,
2058bb7679b8SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
2059bb7679b8SPascal van Leeuwen 			.cra_alignmask = 0,
2060bb7679b8SPascal van Leeuwen 			.cra_init = safexcel_aead_sha1_des_cra_init,
2061bb7679b8SPascal van Leeuwen 			.cra_exit = safexcel_aead_cra_exit,
2062bb7679b8SPascal van Leeuwen 			.cra_module = THIS_MODULE,
2063bb7679b8SPascal van Leeuwen 		},
2064bb7679b8SPascal van Leeuwen 	},
2065bb7679b8SPascal van Leeuwen };
2066bb7679b8SPascal van Leeuwen 
safexcel_aead_sha256_des_cra_init(struct crypto_tfm * tfm)2067457a6fdfSPascal van Leeuwen static int safexcel_aead_sha256_des_cra_init(struct crypto_tfm *tfm)
2068457a6fdfSPascal van Leeuwen {
2069457a6fdfSPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
2070457a6fdfSPascal van Leeuwen 
2071457a6fdfSPascal van Leeuwen 	safexcel_aead_sha256_cra_init(tfm);
2072457a6fdfSPascal van Leeuwen 	ctx->alg = SAFEXCEL_DES; /* override default */
2073098e51e5SPascal van Leeuwen 	ctx->blocksz = DES_BLOCK_SIZE;
2074098e51e5SPascal van Leeuwen 	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
2075457a6fdfSPascal van Leeuwen 	return 0;
2076457a6fdfSPascal van Leeuwen }
2077457a6fdfSPascal van Leeuwen 
2078457a6fdfSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_cbc_des = {
2079457a6fdfSPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
2080457a6fdfSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256,
2081457a6fdfSPascal van Leeuwen 	.alg.aead = {
2082457a6fdfSPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
2083457a6fdfSPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
2084457a6fdfSPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
2085457a6fdfSPascal van Leeuwen 		.ivsize = DES_BLOCK_SIZE,
2086457a6fdfSPascal van Leeuwen 		.maxauthsize = SHA256_DIGEST_SIZE,
2087457a6fdfSPascal van Leeuwen 		.base = {
2088457a6fdfSPascal van Leeuwen 			.cra_name = "authenc(hmac(sha256),cbc(des))",
2089457a6fdfSPascal van Leeuwen 			.cra_driver_name = "safexcel-authenc-hmac-sha256-cbc-des",
2090457a6fdfSPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
2091457a6fdfSPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
2092b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
2093457a6fdfSPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
2094457a6fdfSPascal van Leeuwen 			.cra_blocksize = DES_BLOCK_SIZE,
2095457a6fdfSPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
2096457a6fdfSPascal van Leeuwen 			.cra_alignmask = 0,
2097457a6fdfSPascal van Leeuwen 			.cra_init = safexcel_aead_sha256_des_cra_init,
2098457a6fdfSPascal van Leeuwen 			.cra_exit = safexcel_aead_cra_exit,
2099457a6fdfSPascal van Leeuwen 			.cra_module = THIS_MODULE,
2100457a6fdfSPascal van Leeuwen 		},
2101457a6fdfSPascal van Leeuwen 	},
2102457a6fdfSPascal van Leeuwen };
2103457a6fdfSPascal van Leeuwen 
safexcel_aead_sha224_des_cra_init(struct crypto_tfm * tfm)2104457a6fdfSPascal van Leeuwen static int safexcel_aead_sha224_des_cra_init(struct crypto_tfm *tfm)
2105457a6fdfSPascal van Leeuwen {
2106457a6fdfSPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
2107457a6fdfSPascal van Leeuwen 
2108457a6fdfSPascal van Leeuwen 	safexcel_aead_sha224_cra_init(tfm);
2109457a6fdfSPascal van Leeuwen 	ctx->alg = SAFEXCEL_DES; /* override default */
2110098e51e5SPascal van Leeuwen 	ctx->blocksz = DES_BLOCK_SIZE;
2111098e51e5SPascal van Leeuwen 	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
2112457a6fdfSPascal van Leeuwen 	return 0;
2113457a6fdfSPascal van Leeuwen }
2114457a6fdfSPascal van Leeuwen 
2115457a6fdfSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_cbc_des = {
2116457a6fdfSPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
2117457a6fdfSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_256,
2118457a6fdfSPascal van Leeuwen 	.alg.aead = {
2119457a6fdfSPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
2120457a6fdfSPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
2121457a6fdfSPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
2122457a6fdfSPascal van Leeuwen 		.ivsize = DES_BLOCK_SIZE,
2123457a6fdfSPascal van Leeuwen 		.maxauthsize = SHA224_DIGEST_SIZE,
2124457a6fdfSPascal van Leeuwen 		.base = {
2125457a6fdfSPascal van Leeuwen 			.cra_name = "authenc(hmac(sha224),cbc(des))",
2126457a6fdfSPascal van Leeuwen 			.cra_driver_name = "safexcel-authenc-hmac-sha224-cbc-des",
2127457a6fdfSPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
2128457a6fdfSPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
2129b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
2130457a6fdfSPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
2131457a6fdfSPascal van Leeuwen 			.cra_blocksize = DES_BLOCK_SIZE,
2132457a6fdfSPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
2133457a6fdfSPascal van Leeuwen 			.cra_alignmask = 0,
2134457a6fdfSPascal van Leeuwen 			.cra_init = safexcel_aead_sha224_des_cra_init,
2135457a6fdfSPascal van Leeuwen 			.cra_exit = safexcel_aead_cra_exit,
2136457a6fdfSPascal van Leeuwen 			.cra_module = THIS_MODULE,
2137457a6fdfSPascal van Leeuwen 		},
2138457a6fdfSPascal van Leeuwen 	},
2139457a6fdfSPascal van Leeuwen };
2140457a6fdfSPascal van Leeuwen 
safexcel_aead_sha512_des_cra_init(struct crypto_tfm * tfm)2141457a6fdfSPascal van Leeuwen static int safexcel_aead_sha512_des_cra_init(struct crypto_tfm *tfm)
2142457a6fdfSPascal van Leeuwen {
2143457a6fdfSPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
2144457a6fdfSPascal van Leeuwen 
2145457a6fdfSPascal van Leeuwen 	safexcel_aead_sha512_cra_init(tfm);
2146457a6fdfSPascal van Leeuwen 	ctx->alg = SAFEXCEL_DES; /* override default */
2147098e51e5SPascal van Leeuwen 	ctx->blocksz = DES_BLOCK_SIZE;
2148098e51e5SPascal van Leeuwen 	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
2149457a6fdfSPascal van Leeuwen 	return 0;
2150457a6fdfSPascal van Leeuwen }
2151457a6fdfSPascal van Leeuwen 
2152457a6fdfSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_cbc_des = {
2153457a6fdfSPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
2154457a6fdfSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512,
2155457a6fdfSPascal van Leeuwen 	.alg.aead = {
2156457a6fdfSPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
2157457a6fdfSPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
2158457a6fdfSPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
2159457a6fdfSPascal van Leeuwen 		.ivsize = DES_BLOCK_SIZE,
2160457a6fdfSPascal van Leeuwen 		.maxauthsize = SHA512_DIGEST_SIZE,
2161457a6fdfSPascal van Leeuwen 		.base = {
2162457a6fdfSPascal van Leeuwen 			.cra_name = "authenc(hmac(sha512),cbc(des))",
2163457a6fdfSPascal van Leeuwen 			.cra_driver_name = "safexcel-authenc-hmac-sha512-cbc-des",
2164457a6fdfSPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
2165457a6fdfSPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
2166b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
2167457a6fdfSPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
2168457a6fdfSPascal van Leeuwen 			.cra_blocksize = DES_BLOCK_SIZE,
2169457a6fdfSPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
2170457a6fdfSPascal van Leeuwen 			.cra_alignmask = 0,
2171457a6fdfSPascal van Leeuwen 			.cra_init = safexcel_aead_sha512_des_cra_init,
2172457a6fdfSPascal van Leeuwen 			.cra_exit = safexcel_aead_cra_exit,
2173457a6fdfSPascal van Leeuwen 			.cra_module = THIS_MODULE,
2174457a6fdfSPascal van Leeuwen 		},
2175457a6fdfSPascal van Leeuwen 	},
2176457a6fdfSPascal van Leeuwen };
2177457a6fdfSPascal van Leeuwen 
safexcel_aead_sha384_des_cra_init(struct crypto_tfm * tfm)2178457a6fdfSPascal van Leeuwen static int safexcel_aead_sha384_des_cra_init(struct crypto_tfm *tfm)
2179457a6fdfSPascal van Leeuwen {
2180457a6fdfSPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
2181457a6fdfSPascal van Leeuwen 
2182457a6fdfSPascal van Leeuwen 	safexcel_aead_sha384_cra_init(tfm);
2183457a6fdfSPascal van Leeuwen 	ctx->alg = SAFEXCEL_DES; /* override default */
2184098e51e5SPascal van Leeuwen 	ctx->blocksz = DES_BLOCK_SIZE;
2185098e51e5SPascal van Leeuwen 	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
2186457a6fdfSPascal van Leeuwen 	return 0;
2187457a6fdfSPascal van Leeuwen }
2188457a6fdfSPascal van Leeuwen 
2189457a6fdfSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_cbc_des = {
2190457a6fdfSPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
2191457a6fdfSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_DES | SAFEXCEL_ALG_SHA2_512,
2192457a6fdfSPascal van Leeuwen 	.alg.aead = {
2193457a6fdfSPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
2194457a6fdfSPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
2195457a6fdfSPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
2196457a6fdfSPascal van Leeuwen 		.ivsize = DES_BLOCK_SIZE,
2197457a6fdfSPascal van Leeuwen 		.maxauthsize = SHA384_DIGEST_SIZE,
2198457a6fdfSPascal van Leeuwen 		.base = {
2199457a6fdfSPascal van Leeuwen 			.cra_name = "authenc(hmac(sha384),cbc(des))",
2200457a6fdfSPascal van Leeuwen 			.cra_driver_name = "safexcel-authenc-hmac-sha384-cbc-des",
2201457a6fdfSPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
2202457a6fdfSPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
2203b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
2204457a6fdfSPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
2205457a6fdfSPascal van Leeuwen 			.cra_blocksize = DES_BLOCK_SIZE,
2206457a6fdfSPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
2207457a6fdfSPascal van Leeuwen 			.cra_alignmask = 0,
2208457a6fdfSPascal van Leeuwen 			.cra_init = safexcel_aead_sha384_des_cra_init,
2209457a6fdfSPascal van Leeuwen 			.cra_exit = safexcel_aead_cra_exit,
2210457a6fdfSPascal van Leeuwen 			.cra_module = THIS_MODULE,
2211457a6fdfSPascal van Leeuwen 		},
2212457a6fdfSPascal van Leeuwen 	},
2213457a6fdfSPascal van Leeuwen };
2214457a6fdfSPascal van Leeuwen 
safexcel_aead_sha1_ctr_cra_init(struct crypto_tfm * tfm)22150e17e362SPascal van Leeuwen static int safexcel_aead_sha1_ctr_cra_init(struct crypto_tfm *tfm)
22160e17e362SPascal van Leeuwen {
22170e17e362SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
22180e17e362SPascal van Leeuwen 
22190e17e362SPascal van Leeuwen 	safexcel_aead_sha1_cra_init(tfm);
22200e17e362SPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */
22210e17e362SPascal van Leeuwen 	return 0;
22220e17e362SPascal van Leeuwen }
22230e17e362SPascal van Leeuwen 
22240e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_aes = {
22250e17e362SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
2226062b64caSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA1,
22270e17e362SPascal van Leeuwen 	.alg.aead = {
22280e17e362SPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
222993369b5dSPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
223093369b5dSPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
2231f26882a3SPascal van Leeuwen 		.ivsize = CTR_RFC3686_IV_SIZE,
22320e17e362SPascal van Leeuwen 		.maxauthsize = SHA1_DIGEST_SIZE,
22330e17e362SPascal van Leeuwen 		.base = {
22340e17e362SPascal van Leeuwen 			.cra_name = "authenc(hmac(sha1),rfc3686(ctr(aes)))",
22350e17e362SPascal van Leeuwen 			.cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-aes",
2236aa88f331SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
22370e17e362SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
2238b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
22390e17e362SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
22400e17e362SPascal van Leeuwen 			.cra_blocksize = 1,
22410e17e362SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
22420e17e362SPascal van Leeuwen 			.cra_alignmask = 0,
22430e17e362SPascal van Leeuwen 			.cra_init = safexcel_aead_sha1_ctr_cra_init,
22440e17e362SPascal van Leeuwen 			.cra_exit = safexcel_aead_cra_exit,
22450e17e362SPascal van Leeuwen 			.cra_module = THIS_MODULE,
22460e17e362SPascal van Leeuwen 		},
22470e17e362SPascal van Leeuwen 	},
22480e17e362SPascal van Leeuwen };
22490e17e362SPascal van Leeuwen 
safexcel_aead_sha256_ctr_cra_init(struct crypto_tfm * tfm)22500e17e362SPascal van Leeuwen static int safexcel_aead_sha256_ctr_cra_init(struct crypto_tfm *tfm)
22510e17e362SPascal van Leeuwen {
22520e17e362SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
22530e17e362SPascal van Leeuwen 
22540e17e362SPascal van Leeuwen 	safexcel_aead_sha256_cra_init(tfm);
22550e17e362SPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */
22560e17e362SPascal van Leeuwen 	return 0;
22570e17e362SPascal van Leeuwen }
22580e17e362SPascal van Leeuwen 
22590e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha256_ctr_aes = {
22600e17e362SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
2261062b64caSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256,
22620e17e362SPascal van Leeuwen 	.alg.aead = {
22630e17e362SPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
226493369b5dSPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
226593369b5dSPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
2266f26882a3SPascal van Leeuwen 		.ivsize = CTR_RFC3686_IV_SIZE,
22670e17e362SPascal van Leeuwen 		.maxauthsize = SHA256_DIGEST_SIZE,
22680e17e362SPascal van Leeuwen 		.base = {
22690e17e362SPascal van Leeuwen 			.cra_name = "authenc(hmac(sha256),rfc3686(ctr(aes)))",
22700e17e362SPascal van Leeuwen 			.cra_driver_name = "safexcel-authenc-hmac-sha256-ctr-aes",
2271aa88f331SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
22720e17e362SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
2273b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
22740e17e362SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
22750e17e362SPascal van Leeuwen 			.cra_blocksize = 1,
22760e17e362SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
22770e17e362SPascal van Leeuwen 			.cra_alignmask = 0,
22780e17e362SPascal van Leeuwen 			.cra_init = safexcel_aead_sha256_ctr_cra_init,
22790e17e362SPascal van Leeuwen 			.cra_exit = safexcel_aead_cra_exit,
22800e17e362SPascal van Leeuwen 			.cra_module = THIS_MODULE,
22810e17e362SPascal van Leeuwen 		},
22820e17e362SPascal van Leeuwen 	},
22830e17e362SPascal van Leeuwen };
22840e17e362SPascal van Leeuwen 
safexcel_aead_sha224_ctr_cra_init(struct crypto_tfm * tfm)22850e17e362SPascal van Leeuwen static int safexcel_aead_sha224_ctr_cra_init(struct crypto_tfm *tfm)
22860e17e362SPascal van Leeuwen {
22870e17e362SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
22880e17e362SPascal van Leeuwen 
22890e17e362SPascal van Leeuwen 	safexcel_aead_sha224_cra_init(tfm);
22900e17e362SPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */
22910e17e362SPascal van Leeuwen 	return 0;
22920e17e362SPascal van Leeuwen }
22930e17e362SPascal van Leeuwen 
22940e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha224_ctr_aes = {
22950e17e362SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
2296062b64caSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_256,
22970e17e362SPascal van Leeuwen 	.alg.aead = {
22980e17e362SPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
229993369b5dSPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
230093369b5dSPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
2301f26882a3SPascal van Leeuwen 		.ivsize = CTR_RFC3686_IV_SIZE,
23020e17e362SPascal van Leeuwen 		.maxauthsize = SHA224_DIGEST_SIZE,
23030e17e362SPascal van Leeuwen 		.base = {
23040e17e362SPascal van Leeuwen 			.cra_name = "authenc(hmac(sha224),rfc3686(ctr(aes)))",
23050e17e362SPascal van Leeuwen 			.cra_driver_name = "safexcel-authenc-hmac-sha224-ctr-aes",
2306aa88f331SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
23070e17e362SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
2308b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
23090e17e362SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
23100e17e362SPascal van Leeuwen 			.cra_blocksize = 1,
23110e17e362SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
23120e17e362SPascal van Leeuwen 			.cra_alignmask = 0,
23130e17e362SPascal van Leeuwen 			.cra_init = safexcel_aead_sha224_ctr_cra_init,
23140e17e362SPascal van Leeuwen 			.cra_exit = safexcel_aead_cra_exit,
23150e17e362SPascal van Leeuwen 			.cra_module = THIS_MODULE,
23160e17e362SPascal van Leeuwen 		},
23170e17e362SPascal van Leeuwen 	},
23180e17e362SPascal van Leeuwen };
23190e17e362SPascal van Leeuwen 
safexcel_aead_sha512_ctr_cra_init(struct crypto_tfm * tfm)23200e17e362SPascal van Leeuwen static int safexcel_aead_sha512_ctr_cra_init(struct crypto_tfm *tfm)
23210e17e362SPascal van Leeuwen {
23220e17e362SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
23230e17e362SPascal van Leeuwen 
23240e17e362SPascal van Leeuwen 	safexcel_aead_sha512_cra_init(tfm);
23250e17e362SPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */
23260e17e362SPascal van Leeuwen 	return 0;
23270e17e362SPascal van Leeuwen }
23280e17e362SPascal van Leeuwen 
23290e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha512_ctr_aes = {
23300e17e362SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
2331062b64caSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512,
23320e17e362SPascal van Leeuwen 	.alg.aead = {
23330e17e362SPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
233493369b5dSPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
233593369b5dSPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
2336f26882a3SPascal van Leeuwen 		.ivsize = CTR_RFC3686_IV_SIZE,
23370e17e362SPascal van Leeuwen 		.maxauthsize = SHA512_DIGEST_SIZE,
23380e17e362SPascal van Leeuwen 		.base = {
23390e17e362SPascal van Leeuwen 			.cra_name = "authenc(hmac(sha512),rfc3686(ctr(aes)))",
23400e17e362SPascal van Leeuwen 			.cra_driver_name = "safexcel-authenc-hmac-sha512-ctr-aes",
2341aa88f331SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
23420e17e362SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
2343b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
23440e17e362SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
23450e17e362SPascal van Leeuwen 			.cra_blocksize = 1,
23460e17e362SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
23470e17e362SPascal van Leeuwen 			.cra_alignmask = 0,
23480e17e362SPascal van Leeuwen 			.cra_init = safexcel_aead_sha512_ctr_cra_init,
23490e17e362SPascal van Leeuwen 			.cra_exit = safexcel_aead_cra_exit,
23500e17e362SPascal van Leeuwen 			.cra_module = THIS_MODULE,
23510e17e362SPascal van Leeuwen 		},
23520e17e362SPascal van Leeuwen 	},
23530e17e362SPascal van Leeuwen };
23540e17e362SPascal van Leeuwen 
safexcel_aead_sha384_ctr_cra_init(struct crypto_tfm * tfm)23550e17e362SPascal van Leeuwen static int safexcel_aead_sha384_ctr_cra_init(struct crypto_tfm *tfm)
23560e17e362SPascal van Leeuwen {
23570e17e362SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
23580e17e362SPascal van Leeuwen 
23590e17e362SPascal van Leeuwen 	safexcel_aead_sha384_cra_init(tfm);
23600e17e362SPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD; /* override default */
23610e17e362SPascal van Leeuwen 	return 0;
23620e17e362SPascal van Leeuwen }
23630e17e362SPascal van Leeuwen 
23640e17e362SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha384_ctr_aes = {
23650e17e362SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
2366062b64caSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_SHA2_512,
23670e17e362SPascal van Leeuwen 	.alg.aead = {
23680e17e362SPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
236993369b5dSPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
237093369b5dSPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
2371f26882a3SPascal van Leeuwen 		.ivsize = CTR_RFC3686_IV_SIZE,
23720e17e362SPascal van Leeuwen 		.maxauthsize = SHA384_DIGEST_SIZE,
23730e17e362SPascal van Leeuwen 		.base = {
23740e17e362SPascal van Leeuwen 			.cra_name = "authenc(hmac(sha384),rfc3686(ctr(aes)))",
23750e17e362SPascal van Leeuwen 			.cra_driver_name = "safexcel-authenc-hmac-sha384-ctr-aes",
2376aa88f331SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
23770e17e362SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
2378b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
23790e17e362SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
23800e17e362SPascal van Leeuwen 			.cra_blocksize = 1,
23810e17e362SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
23820e17e362SPascal van Leeuwen 			.cra_alignmask = 0,
23830e17e362SPascal van Leeuwen 			.cra_init = safexcel_aead_sha384_ctr_cra_init,
238477cdd4efSPascal van Leeuwen 			.cra_exit = safexcel_aead_cra_exit,
238577cdd4efSPascal van Leeuwen 			.cra_module = THIS_MODULE,
238677cdd4efSPascal van Leeuwen 		},
238777cdd4efSPascal van Leeuwen 	},
238877cdd4efSPascal van Leeuwen };
2389c7da38a7SPascal van Leeuwen 
safexcel_skcipher_aesxts_setkey(struct crypto_skcipher * ctfm,const u8 * key,unsigned int len)2390c7da38a7SPascal van Leeuwen static int safexcel_skcipher_aesxts_setkey(struct crypto_skcipher *ctfm,
2391c7da38a7SPascal van Leeuwen 					   const u8 *key, unsigned int len)
2392c7da38a7SPascal van Leeuwen {
2393c7da38a7SPascal van Leeuwen 	struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);
2394c7da38a7SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
239518e51895SHerbert Xu 	struct safexcel_crypto_priv *priv = ctx->base.priv;
2396c7da38a7SPascal van Leeuwen 	struct crypto_aes_ctx aes;
2397c7da38a7SPascal van Leeuwen 	int ret, i;
2398c7da38a7SPascal van Leeuwen 	unsigned int keylen;
2399c7da38a7SPascal van Leeuwen 
2400c7da38a7SPascal van Leeuwen 	/* Check for illegal XTS keys */
2401c7da38a7SPascal van Leeuwen 	ret = xts_verify_key(ctfm, key, len);
2402c7da38a7SPascal van Leeuwen 	if (ret)
2403c7da38a7SPascal van Leeuwen 		return ret;
2404c7da38a7SPascal van Leeuwen 
2405c7da38a7SPascal van Leeuwen 	/* Only half of the key data is cipher key */
2406c7da38a7SPascal van Leeuwen 	keylen = (len >> 1);
2407c7da38a7SPascal van Leeuwen 	ret = aes_expandkey(&aes, key, keylen);
2408674f368aSEric Biggers 	if (ret)
2409c7da38a7SPascal van Leeuwen 		return ret;
2410c7da38a7SPascal van Leeuwen 
2411c7da38a7SPascal van Leeuwen 	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
2412c7da38a7SPascal van Leeuwen 		for (i = 0; i < keylen / sizeof(u32); i++) {
241313a1bb93SPascal van Leeuwen 			if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {
2414c7da38a7SPascal van Leeuwen 				ctx->base.needs_inv = true;
2415c7da38a7SPascal van Leeuwen 				break;
2416c7da38a7SPascal van Leeuwen 			}
2417c7da38a7SPascal van Leeuwen 		}
2418c7da38a7SPascal van Leeuwen 	}
2419c7da38a7SPascal van Leeuwen 
2420c7da38a7SPascal van Leeuwen 	for (i = 0; i < keylen / sizeof(u32); i++)
2421c7da38a7SPascal van Leeuwen 		ctx->key[i] = cpu_to_le32(aes.key_enc[i]);
2422c7da38a7SPascal van Leeuwen 
2423c7da38a7SPascal van Leeuwen 	/* The other half is the tweak key */
2424c7da38a7SPascal van Leeuwen 	ret = aes_expandkey(&aes, (u8 *)(key + keylen), keylen);
2425674f368aSEric Biggers 	if (ret)
2426c7da38a7SPascal van Leeuwen 		return ret;
2427c7da38a7SPascal van Leeuwen 
2428c7da38a7SPascal van Leeuwen 	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
2429c7da38a7SPascal van Leeuwen 		for (i = 0; i < keylen / sizeof(u32); i++) {
243013a1bb93SPascal van Leeuwen 			if (le32_to_cpu(ctx->key[i + keylen / sizeof(u32)]) !=
243113a1bb93SPascal van Leeuwen 			    aes.key_enc[i]) {
2432c7da38a7SPascal van Leeuwen 				ctx->base.needs_inv = true;
2433c7da38a7SPascal van Leeuwen 				break;
2434c7da38a7SPascal van Leeuwen 			}
2435c7da38a7SPascal van Leeuwen 		}
2436c7da38a7SPascal van Leeuwen 	}
2437c7da38a7SPascal van Leeuwen 
2438c7da38a7SPascal van Leeuwen 	for (i = 0; i < keylen / sizeof(u32); i++)
2439c7da38a7SPascal van Leeuwen 		ctx->key[i + keylen / sizeof(u32)] =
2440c7da38a7SPascal van Leeuwen 			cpu_to_le32(aes.key_enc[i]);
2441c7da38a7SPascal van Leeuwen 
2442c7da38a7SPascal van Leeuwen 	ctx->key_len = keylen << 1;
2443c7da38a7SPascal van Leeuwen 
2444c7da38a7SPascal van Leeuwen 	memzero_explicit(&aes, sizeof(aes));
2445c7da38a7SPascal van Leeuwen 	return 0;
2446c7da38a7SPascal van Leeuwen }
2447c7da38a7SPascal van Leeuwen 
safexcel_skcipher_aes_xts_cra_init(struct crypto_tfm * tfm)2448c7da38a7SPascal van Leeuwen static int safexcel_skcipher_aes_xts_cra_init(struct crypto_tfm *tfm)
2449c7da38a7SPascal van Leeuwen {
2450c7da38a7SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
2451c7da38a7SPascal van Leeuwen 
2452c7da38a7SPascal van Leeuwen 	safexcel_skcipher_cra_init(tfm);
2453c7da38a7SPascal van Leeuwen 	ctx->alg  = SAFEXCEL_AES;
2454098e51e5SPascal van Leeuwen 	ctx->blocksz = AES_BLOCK_SIZE;
2455c7da38a7SPascal van Leeuwen 	ctx->xts  = 1;
2456c7da38a7SPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XTS;
2457c7da38a7SPascal van Leeuwen 	return 0;
2458c7da38a7SPascal van Leeuwen }
2459c7da38a7SPascal van Leeuwen 
safexcel_encrypt_xts(struct skcipher_request * req)2460c7da38a7SPascal van Leeuwen static int safexcel_encrypt_xts(struct skcipher_request *req)
2461c7da38a7SPascal van Leeuwen {
2462c7da38a7SPascal van Leeuwen 	if (req->cryptlen < XTS_BLOCK_SIZE)
2463c7da38a7SPascal van Leeuwen 		return -EINVAL;
2464c7da38a7SPascal van Leeuwen 	return safexcel_queue_req(&req->base, skcipher_request_ctx(req),
2465c7da38a7SPascal van Leeuwen 				  SAFEXCEL_ENCRYPT);
2466c7da38a7SPascal van Leeuwen }
2467c7da38a7SPascal van Leeuwen 
safexcel_decrypt_xts(struct skcipher_request * req)2468c7da38a7SPascal van Leeuwen static int safexcel_decrypt_xts(struct skcipher_request *req)
2469c7da38a7SPascal van Leeuwen {
2470c7da38a7SPascal van Leeuwen 	if (req->cryptlen < XTS_BLOCK_SIZE)
2471c7da38a7SPascal van Leeuwen 		return -EINVAL;
2472c7da38a7SPascal van Leeuwen 	return safexcel_queue_req(&req->base, skcipher_request_ctx(req),
2473c7da38a7SPascal van Leeuwen 				  SAFEXCEL_DECRYPT);
2474c7da38a7SPascal van Leeuwen }
2475c7da38a7SPascal van Leeuwen 
2476c7da38a7SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_xts_aes = {
2477c7da38a7SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
2478062b64caSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_AES_XTS,
2479c7da38a7SPascal van Leeuwen 	.alg.skcipher = {
2480c7da38a7SPascal van Leeuwen 		.setkey = safexcel_skcipher_aesxts_setkey,
2481c7da38a7SPascal van Leeuwen 		.encrypt = safexcel_encrypt_xts,
2482c7da38a7SPascal van Leeuwen 		.decrypt = safexcel_decrypt_xts,
2483c7da38a7SPascal van Leeuwen 		/* XTS actually uses 2 AES keys glued together */
2484c7da38a7SPascal van Leeuwen 		.min_keysize = AES_MIN_KEY_SIZE * 2,
2485c7da38a7SPascal van Leeuwen 		.max_keysize = AES_MAX_KEY_SIZE * 2,
2486c7da38a7SPascal van Leeuwen 		.ivsize = XTS_BLOCK_SIZE,
2487c7da38a7SPascal van Leeuwen 		.base = {
2488c7da38a7SPascal van Leeuwen 			.cra_name = "xts(aes)",
2489c7da38a7SPascal van Leeuwen 			.cra_driver_name = "safexcel-xts-aes",
2490aa88f331SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
2491c7da38a7SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
2492b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
2493c7da38a7SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
2494c7da38a7SPascal van Leeuwen 			.cra_blocksize = XTS_BLOCK_SIZE,
2495c7da38a7SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
2496c7da38a7SPascal van Leeuwen 			.cra_alignmask = 0,
2497c7da38a7SPascal van Leeuwen 			.cra_init = safexcel_skcipher_aes_xts_cra_init,
2498c7da38a7SPascal van Leeuwen 			.cra_exit = safexcel_skcipher_cra_exit,
2499c7da38a7SPascal van Leeuwen 			.cra_module = THIS_MODULE,
2500c7da38a7SPascal van Leeuwen 		},
2501c7da38a7SPascal van Leeuwen 	},
2502c7da38a7SPascal van Leeuwen };
25033e450886SPascal van Leeuwen 
safexcel_aead_gcm_setkey(struct crypto_aead * ctfm,const u8 * key,unsigned int len)25043e450886SPascal van Leeuwen static int safexcel_aead_gcm_setkey(struct crypto_aead *ctfm, const u8 *key,
25053e450886SPascal van Leeuwen 				    unsigned int len)
25063e450886SPascal van Leeuwen {
25073e450886SPascal van Leeuwen 	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);
25083e450886SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
250918e51895SHerbert Xu 	struct safexcel_crypto_priv *priv = ctx->base.priv;
25103e450886SPascal van Leeuwen 	struct crypto_aes_ctx aes;
25113e450886SPascal van Leeuwen 	u32 hashkey[AES_BLOCK_SIZE >> 2];
25123e450886SPascal van Leeuwen 	int ret, i;
25133e450886SPascal van Leeuwen 
25143e450886SPascal van Leeuwen 	ret = aes_expandkey(&aes, key, len);
25153e450886SPascal van Leeuwen 	if (ret) {
25163e450886SPascal van Leeuwen 		memzero_explicit(&aes, sizeof(aes));
25173e450886SPascal van Leeuwen 		return ret;
25183e450886SPascal van Leeuwen 	}
25193e450886SPascal van Leeuwen 
25203e450886SPascal van Leeuwen 	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
25213e450886SPascal van Leeuwen 		for (i = 0; i < len / sizeof(u32); i++) {
252213a1bb93SPascal van Leeuwen 			if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {
25233e450886SPascal van Leeuwen 				ctx->base.needs_inv = true;
25243e450886SPascal van Leeuwen 				break;
25253e450886SPascal van Leeuwen 			}
25263e450886SPascal van Leeuwen 		}
25273e450886SPascal van Leeuwen 	}
25283e450886SPascal van Leeuwen 
25293e450886SPascal van Leeuwen 	for (i = 0; i < len / sizeof(u32); i++)
25303e450886SPascal van Leeuwen 		ctx->key[i] = cpu_to_le32(aes.key_enc[i]);
25313e450886SPascal van Leeuwen 
25323e450886SPascal van Leeuwen 	ctx->key_len = len;
25333e450886SPascal van Leeuwen 
25343e450886SPascal van Leeuwen 	/* Compute hash key by encrypting zeroes with cipher key */
25353e450886SPascal van Leeuwen 	memset(hashkey, 0, AES_BLOCK_SIZE);
2536320406cbSPeter Harliman Liem 	aes_encrypt(&aes, (u8 *)hashkey, (u8 *)hashkey);
25373e450886SPascal van Leeuwen 
25383e450886SPascal van Leeuwen 	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
25393e450886SPascal van Leeuwen 		for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++) {
254078cf1c8bSHerbert Xu 			if (be32_to_cpu(ctx->base.ipad.be[i]) != hashkey[i]) {
25413e450886SPascal van Leeuwen 				ctx->base.needs_inv = true;
25423e450886SPascal van Leeuwen 				break;
25433e450886SPascal van Leeuwen 			}
25443e450886SPascal van Leeuwen 		}
25453e450886SPascal van Leeuwen 	}
25463e450886SPascal van Leeuwen 
25473e450886SPascal van Leeuwen 	for (i = 0; i < AES_BLOCK_SIZE / sizeof(u32); i++)
254878cf1c8bSHerbert Xu 		ctx->base.ipad.be[i] = cpu_to_be32(hashkey[i]);
25493e450886SPascal van Leeuwen 
25503e450886SPascal van Leeuwen 	memzero_explicit(hashkey, AES_BLOCK_SIZE);
25513e450886SPascal van Leeuwen 	memzero_explicit(&aes, sizeof(aes));
25523e450886SPascal van Leeuwen 	return 0;
25533e450886SPascal van Leeuwen }
25543e450886SPascal van Leeuwen 
safexcel_aead_gcm_cra_init(struct crypto_tfm * tfm)25553e450886SPascal van Leeuwen static int safexcel_aead_gcm_cra_init(struct crypto_tfm *tfm)
25563e450886SPascal van Leeuwen {
25573e450886SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
25583e450886SPascal van Leeuwen 
25593e450886SPascal van Leeuwen 	safexcel_aead_cra_init(tfm);
25603e450886SPascal van Leeuwen 	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_GHASH;
25613e450886SPascal van Leeuwen 	ctx->state_sz = GHASH_BLOCK_SIZE;
25624eb76fafSPascal van Leeuwen 	ctx->xcm = EIP197_XCM_MODE_GCM;
25633e450886SPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */
25643e450886SPascal van Leeuwen 
2565320406cbSPeter Harliman Liem 	return 0;
25663e450886SPascal van Leeuwen }
25673e450886SPascal van Leeuwen 
safexcel_aead_gcm_cra_exit(struct crypto_tfm * tfm)25683e450886SPascal van Leeuwen static void safexcel_aead_gcm_cra_exit(struct crypto_tfm *tfm)
25693e450886SPascal van Leeuwen {
25703e450886SPascal van Leeuwen 	safexcel_aead_cra_exit(tfm);
25713e450886SPascal van Leeuwen }
25723e450886SPascal van Leeuwen 
safexcel_aead_gcm_setauthsize(struct crypto_aead * tfm,unsigned int authsize)25733e450886SPascal van Leeuwen static int safexcel_aead_gcm_setauthsize(struct crypto_aead *tfm,
25743e450886SPascal van Leeuwen 					 unsigned int authsize)
25753e450886SPascal van Leeuwen {
25763e450886SPascal van Leeuwen 	return crypto_gcm_check_authsize(authsize);
25773e450886SPascal van Leeuwen }
25783e450886SPascal van Leeuwen 
25793e450886SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_gcm = {
25803e450886SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
25813e450886SPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH,
25823e450886SPascal van Leeuwen 	.alg.aead = {
25833e450886SPascal van Leeuwen 		.setkey = safexcel_aead_gcm_setkey,
25843e450886SPascal van Leeuwen 		.setauthsize = safexcel_aead_gcm_setauthsize,
25853e450886SPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
25863e450886SPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
25873e450886SPascal van Leeuwen 		.ivsize = GCM_AES_IV_SIZE,
25883e450886SPascal van Leeuwen 		.maxauthsize = GHASH_DIGEST_SIZE,
25893e450886SPascal van Leeuwen 		.base = {
25903e450886SPascal van Leeuwen 			.cra_name = "gcm(aes)",
25913e450886SPascal van Leeuwen 			.cra_driver_name = "safexcel-gcm-aes",
25923e450886SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
25933e450886SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
2594b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
25953e450886SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
25963e450886SPascal van Leeuwen 			.cra_blocksize = 1,
25973e450886SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
25983e450886SPascal van Leeuwen 			.cra_alignmask = 0,
25993e450886SPascal van Leeuwen 			.cra_init = safexcel_aead_gcm_cra_init,
26003e450886SPascal van Leeuwen 			.cra_exit = safexcel_aead_gcm_cra_exit,
26013e450886SPascal van Leeuwen 			.cra_module = THIS_MODULE,
26023e450886SPascal van Leeuwen 		},
26033e450886SPascal van Leeuwen 	},
26043e450886SPascal van Leeuwen };
26054eb76fafSPascal van Leeuwen 
safexcel_aead_ccm_setkey(struct crypto_aead * ctfm,const u8 * key,unsigned int len)26064eb76fafSPascal van Leeuwen static int safexcel_aead_ccm_setkey(struct crypto_aead *ctfm, const u8 *key,
26074eb76fafSPascal van Leeuwen 				    unsigned int len)
26084eb76fafSPascal van Leeuwen {
26094eb76fafSPascal van Leeuwen 	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);
26104eb76fafSPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
261118e51895SHerbert Xu 	struct safexcel_crypto_priv *priv = ctx->base.priv;
26124eb76fafSPascal van Leeuwen 	struct crypto_aes_ctx aes;
26134eb76fafSPascal van Leeuwen 	int ret, i;
26144eb76fafSPascal van Leeuwen 
26154eb76fafSPascal van Leeuwen 	ret = aes_expandkey(&aes, key, len);
26164eb76fafSPascal van Leeuwen 	if (ret) {
26174eb76fafSPascal van Leeuwen 		memzero_explicit(&aes, sizeof(aes));
26184eb76fafSPascal van Leeuwen 		return ret;
26194eb76fafSPascal van Leeuwen 	}
26204eb76fafSPascal van Leeuwen 
26214eb76fafSPascal van Leeuwen 	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma) {
26224eb76fafSPascal van Leeuwen 		for (i = 0; i < len / sizeof(u32); i++) {
262313a1bb93SPascal van Leeuwen 			if (le32_to_cpu(ctx->key[i]) != aes.key_enc[i]) {
26244eb76fafSPascal van Leeuwen 				ctx->base.needs_inv = true;
26254eb76fafSPascal van Leeuwen 				break;
26264eb76fafSPascal van Leeuwen 			}
26274eb76fafSPascal van Leeuwen 		}
26284eb76fafSPascal van Leeuwen 	}
26294eb76fafSPascal van Leeuwen 
26304eb76fafSPascal van Leeuwen 	for (i = 0; i < len / sizeof(u32); i++) {
26314eb76fafSPascal van Leeuwen 		ctx->key[i] = cpu_to_le32(aes.key_enc[i]);
263278cf1c8bSHerbert Xu 		ctx->base.ipad.be[i + 2 * AES_BLOCK_SIZE / sizeof(u32)] =
26334eb76fafSPascal van Leeuwen 			cpu_to_be32(aes.key_enc[i]);
26344eb76fafSPascal van Leeuwen 	}
26354eb76fafSPascal van Leeuwen 
26364eb76fafSPascal van Leeuwen 	ctx->key_len = len;
26374eb76fafSPascal van Leeuwen 	ctx->state_sz = 2 * AES_BLOCK_SIZE + len;
26384eb76fafSPascal van Leeuwen 
26394eb76fafSPascal van Leeuwen 	if (len == AES_KEYSIZE_192)
26404eb76fafSPascal van Leeuwen 		ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC192;
26414eb76fafSPascal van Leeuwen 	else if (len == AES_KEYSIZE_256)
26424eb76fafSPascal van Leeuwen 		ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC256;
26434eb76fafSPascal van Leeuwen 	else
26444eb76fafSPascal van Leeuwen 		ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128;
26454eb76fafSPascal van Leeuwen 
26464eb76fafSPascal van Leeuwen 	memzero_explicit(&aes, sizeof(aes));
26474eb76fafSPascal van Leeuwen 	return 0;
26484eb76fafSPascal van Leeuwen }
26494eb76fafSPascal van Leeuwen 
safexcel_aead_ccm_cra_init(struct crypto_tfm * tfm)26504eb76fafSPascal van Leeuwen static int safexcel_aead_ccm_cra_init(struct crypto_tfm *tfm)
26514eb76fafSPascal van Leeuwen {
26524eb76fafSPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
26534eb76fafSPascal van Leeuwen 
26544eb76fafSPascal van Leeuwen 	safexcel_aead_cra_init(tfm);
26554eb76fafSPascal van Leeuwen 	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128;
26564eb76fafSPascal van Leeuwen 	ctx->state_sz = 3 * AES_BLOCK_SIZE;
26574eb76fafSPascal van Leeuwen 	ctx->xcm = EIP197_XCM_MODE_CCM;
26584eb76fafSPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_XCM; /* override default */
2659098e51e5SPascal van Leeuwen 	ctx->ctrinit = 0;
26604eb76fafSPascal van Leeuwen 	return 0;
26614eb76fafSPascal van Leeuwen }
26624eb76fafSPascal van Leeuwen 
safexcel_aead_ccm_setauthsize(struct crypto_aead * tfm,unsigned int authsize)26634eb76fafSPascal van Leeuwen static int safexcel_aead_ccm_setauthsize(struct crypto_aead *tfm,
26644eb76fafSPascal van Leeuwen 					 unsigned int authsize)
26654eb76fafSPascal van Leeuwen {
26664eb76fafSPascal van Leeuwen 	/* Borrowed from crypto/ccm.c */
26674eb76fafSPascal van Leeuwen 	switch (authsize) {
26684eb76fafSPascal van Leeuwen 	case 4:
26694eb76fafSPascal van Leeuwen 	case 6:
26704eb76fafSPascal van Leeuwen 	case 8:
26714eb76fafSPascal van Leeuwen 	case 10:
26724eb76fafSPascal van Leeuwen 	case 12:
26734eb76fafSPascal van Leeuwen 	case 14:
26744eb76fafSPascal van Leeuwen 	case 16:
26754eb76fafSPascal van Leeuwen 		break;
26764eb76fafSPascal van Leeuwen 	default:
26774eb76fafSPascal van Leeuwen 		return -EINVAL;
26784eb76fafSPascal van Leeuwen 	}
26794eb76fafSPascal van Leeuwen 
26804eb76fafSPascal van Leeuwen 	return 0;
26814eb76fafSPascal van Leeuwen }
26824eb76fafSPascal van Leeuwen 
safexcel_ccm_encrypt(struct aead_request * req)26834eb76fafSPascal van Leeuwen static int safexcel_ccm_encrypt(struct aead_request *req)
26844eb76fafSPascal van Leeuwen {
26854eb76fafSPascal van Leeuwen 	struct safexcel_cipher_req *creq = aead_request_ctx(req);
26864eb76fafSPascal van Leeuwen 
26874eb76fafSPascal van Leeuwen 	if (req->iv[0] < 1 || req->iv[0] > 7)
26884eb76fafSPascal van Leeuwen 		return -EINVAL;
26894eb76fafSPascal van Leeuwen 
26904eb76fafSPascal van Leeuwen 	return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT);
26914eb76fafSPascal van Leeuwen }
26924eb76fafSPascal van Leeuwen 
safexcel_ccm_decrypt(struct aead_request * req)26934eb76fafSPascal van Leeuwen static int safexcel_ccm_decrypt(struct aead_request *req)
26944eb76fafSPascal van Leeuwen {
26954eb76fafSPascal van Leeuwen 	struct safexcel_cipher_req *creq = aead_request_ctx(req);
26964eb76fafSPascal van Leeuwen 
26974eb76fafSPascal van Leeuwen 	if (req->iv[0] < 1 || req->iv[0] > 7)
26984eb76fafSPascal van Leeuwen 		return -EINVAL;
26994eb76fafSPascal van Leeuwen 
27004eb76fafSPascal van Leeuwen 	return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT);
27014eb76fafSPascal van Leeuwen }
27024eb76fafSPascal van Leeuwen 
27034eb76fafSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ccm = {
27044eb76fafSPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
27054eb76fafSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL,
27064eb76fafSPascal van Leeuwen 	.alg.aead = {
27074eb76fafSPascal van Leeuwen 		.setkey = safexcel_aead_ccm_setkey,
27084eb76fafSPascal van Leeuwen 		.setauthsize = safexcel_aead_ccm_setauthsize,
27094eb76fafSPascal van Leeuwen 		.encrypt = safexcel_ccm_encrypt,
27104eb76fafSPascal van Leeuwen 		.decrypt = safexcel_ccm_decrypt,
27114eb76fafSPascal van Leeuwen 		.ivsize = AES_BLOCK_SIZE,
27124eb76fafSPascal van Leeuwen 		.maxauthsize = AES_BLOCK_SIZE,
27134eb76fafSPascal van Leeuwen 		.base = {
27144eb76fafSPascal van Leeuwen 			.cra_name = "ccm(aes)",
27154eb76fafSPascal van Leeuwen 			.cra_driver_name = "safexcel-ccm-aes",
27164eb76fafSPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
27174eb76fafSPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
2718b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
27194eb76fafSPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
27204eb76fafSPascal van Leeuwen 			.cra_blocksize = 1,
27214eb76fafSPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
27224eb76fafSPascal van Leeuwen 			.cra_alignmask = 0,
27234eb76fafSPascal van Leeuwen 			.cra_init = safexcel_aead_ccm_cra_init,
27244eb76fafSPascal van Leeuwen 			.cra_exit = safexcel_aead_cra_exit,
27254eb76fafSPascal van Leeuwen 			.cra_module = THIS_MODULE,
27264eb76fafSPascal van Leeuwen 		},
27274eb76fafSPascal van Leeuwen 	},
27284eb76fafSPascal van Leeuwen };
27294a593fb3SPascal van Leeuwen 
safexcel_chacha20_setkey(struct safexcel_cipher_ctx * ctx,const u8 * key)2730a6061921SPascal van Leeuwen static void safexcel_chacha20_setkey(struct safexcel_cipher_ctx *ctx,
2731a6061921SPascal van Leeuwen 				     const u8 *key)
27324a593fb3SPascal van Leeuwen {
273318e51895SHerbert Xu 	struct safexcel_crypto_priv *priv = ctx->base.priv;
27344a593fb3SPascal van Leeuwen 
273513a1bb93SPascal van Leeuwen 	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma)
273613a1bb93SPascal van Leeuwen 		if (memcmp(ctx->key, key, CHACHA_KEY_SIZE))
27374a593fb3SPascal van Leeuwen 			ctx->base.needs_inv = true;
27384a593fb3SPascal van Leeuwen 
273913a1bb93SPascal van Leeuwen 	memcpy(ctx->key, key, CHACHA_KEY_SIZE);
27404a593fb3SPascal van Leeuwen 	ctx->key_len = CHACHA_KEY_SIZE;
2741a6061921SPascal van Leeuwen }
2742a6061921SPascal van Leeuwen 
safexcel_skcipher_chacha20_setkey(struct crypto_skcipher * ctfm,const u8 * key,unsigned int len)2743a6061921SPascal van Leeuwen static int safexcel_skcipher_chacha20_setkey(struct crypto_skcipher *ctfm,
2744a6061921SPascal van Leeuwen 					     const u8 *key, unsigned int len)
2745a6061921SPascal van Leeuwen {
2746a6061921SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_skcipher_ctx(ctfm);
2747a6061921SPascal van Leeuwen 
2748674f368aSEric Biggers 	if (len != CHACHA_KEY_SIZE)
2749a6061921SPascal van Leeuwen 		return -EINVAL;
2750674f368aSEric Biggers 
2751a6061921SPascal van Leeuwen 	safexcel_chacha20_setkey(ctx, key);
27524a593fb3SPascal van Leeuwen 
27534a593fb3SPascal van Leeuwen 	return 0;
27544a593fb3SPascal van Leeuwen }
27554a593fb3SPascal van Leeuwen 
safexcel_skcipher_chacha20_cra_init(struct crypto_tfm * tfm)27564a593fb3SPascal van Leeuwen static int safexcel_skcipher_chacha20_cra_init(struct crypto_tfm *tfm)
27574a593fb3SPascal van Leeuwen {
27584a593fb3SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
27594a593fb3SPascal van Leeuwen 
27604a593fb3SPascal van Leeuwen 	safexcel_skcipher_cra_init(tfm);
27614a593fb3SPascal van Leeuwen 	ctx->alg  = SAFEXCEL_CHACHA20;
2762098e51e5SPascal van Leeuwen 	ctx->ctrinit = 0;
27634a593fb3SPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32;
27644a593fb3SPascal van Leeuwen 	return 0;
27654a593fb3SPascal van Leeuwen }
27664a593fb3SPascal van Leeuwen 
27674a593fb3SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_chacha20 = {
27684a593fb3SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
27694a593fb3SPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_CHACHA20,
27704a593fb3SPascal van Leeuwen 	.alg.skcipher = {
27714a593fb3SPascal van Leeuwen 		.setkey = safexcel_skcipher_chacha20_setkey,
27724a593fb3SPascal van Leeuwen 		.encrypt = safexcel_encrypt,
27734a593fb3SPascal van Leeuwen 		.decrypt = safexcel_decrypt,
27744a593fb3SPascal van Leeuwen 		.min_keysize = CHACHA_KEY_SIZE,
27754a593fb3SPascal van Leeuwen 		.max_keysize = CHACHA_KEY_SIZE,
27764a593fb3SPascal van Leeuwen 		.ivsize = CHACHA_IV_SIZE,
27774a593fb3SPascal van Leeuwen 		.base = {
27784a593fb3SPascal van Leeuwen 			.cra_name = "chacha20",
27794a593fb3SPascal van Leeuwen 			.cra_driver_name = "safexcel-chacha20",
27804a593fb3SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
27814a593fb3SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
2782b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
27834a593fb3SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
27844a593fb3SPascal van Leeuwen 			.cra_blocksize = 1,
27854a593fb3SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
27864a593fb3SPascal van Leeuwen 			.cra_alignmask = 0,
27874a593fb3SPascal van Leeuwen 			.cra_init = safexcel_skcipher_chacha20_cra_init,
27884a593fb3SPascal van Leeuwen 			.cra_exit = safexcel_skcipher_cra_exit,
27894a593fb3SPascal van Leeuwen 			.cra_module = THIS_MODULE,
27904a593fb3SPascal van Leeuwen 		},
27914a593fb3SPascal van Leeuwen 	},
27924a593fb3SPascal van Leeuwen };
2793a6061921SPascal van Leeuwen 
safexcel_aead_chachapoly_setkey(struct crypto_aead * ctfm,const u8 * key,unsigned int len)2794a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_setkey(struct crypto_aead *ctfm,
2795a6061921SPascal van Leeuwen 				    const u8 *key, unsigned int len)
2796a6061921SPascal van Leeuwen {
2797a6061921SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_aead_ctx(ctfm);
2798a6061921SPascal van Leeuwen 
2799a6061921SPascal van Leeuwen 	if (ctx->aead  == EIP197_AEAD_TYPE_IPSEC_ESP &&
2800a6061921SPascal van Leeuwen 	    len > EIP197_AEAD_IPSEC_NONCE_SIZE) {
2801a6061921SPascal van Leeuwen 		/* ESP variant has nonce appended to key */
2802a6061921SPascal van Leeuwen 		len -= EIP197_AEAD_IPSEC_NONCE_SIZE;
2803a6061921SPascal van Leeuwen 		ctx->nonce = *(u32 *)(key + len);
2804a6061921SPascal van Leeuwen 	}
2805674f368aSEric Biggers 	if (len != CHACHA_KEY_SIZE)
2806a6061921SPascal van Leeuwen 		return -EINVAL;
2807674f368aSEric Biggers 
2808a6061921SPascal van Leeuwen 	safexcel_chacha20_setkey(ctx, key);
2809a6061921SPascal van Leeuwen 
2810a6061921SPascal van Leeuwen 	return 0;
2811a6061921SPascal van Leeuwen }
2812a6061921SPascal van Leeuwen 
safexcel_aead_chachapoly_setauthsize(struct crypto_aead * tfm,unsigned int authsize)2813a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_setauthsize(struct crypto_aead *tfm,
2814a6061921SPascal van Leeuwen 					 unsigned int authsize)
2815a6061921SPascal van Leeuwen {
2816a6061921SPascal van Leeuwen 	if (authsize != POLY1305_DIGEST_SIZE)
2817a6061921SPascal van Leeuwen 		return -EINVAL;
2818a6061921SPascal van Leeuwen 	return 0;
2819a6061921SPascal van Leeuwen }
2820a6061921SPascal van Leeuwen 
safexcel_aead_chachapoly_crypt(struct aead_request * req,enum safexcel_cipher_direction dir)2821a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_crypt(struct aead_request *req,
2822a6061921SPascal van Leeuwen 					  enum safexcel_cipher_direction dir)
2823a6061921SPascal van Leeuwen {
2824a6061921SPascal van Leeuwen 	struct safexcel_cipher_req *creq = aead_request_ctx(req);
2825a6061921SPascal van Leeuwen 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
2826a6061921SPascal van Leeuwen 	struct crypto_tfm *tfm = crypto_aead_tfm(aead);
2827a6061921SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
2828a6061921SPascal van Leeuwen 	struct aead_request *subreq = aead_request_ctx(req);
2829a6061921SPascal van Leeuwen 	u32 key[CHACHA_KEY_SIZE / sizeof(u32) + 1];
283013a1bb93SPascal van Leeuwen 	int ret = 0;
2831a6061921SPascal van Leeuwen 
2832a6061921SPascal van Leeuwen 	/*
2833a6061921SPascal van Leeuwen 	 * Instead of wasting time detecting umpteen silly corner cases,
2834a6061921SPascal van Leeuwen 	 * just dump all "small" requests to the fallback implementation.
2835a6061921SPascal van Leeuwen 	 * HW would not be faster on such small requests anyway.
2836a6061921SPascal van Leeuwen 	 */
2837a6061921SPascal van Leeuwen 	if (likely((ctx->aead != EIP197_AEAD_TYPE_IPSEC_ESP ||
2838a6061921SPascal van Leeuwen 		    req->assoclen >= EIP197_AEAD_IPSEC_IV_SIZE) &&
2839a6061921SPascal van Leeuwen 		   req->cryptlen > POLY1305_DIGEST_SIZE)) {
2840a6061921SPascal van Leeuwen 		return safexcel_queue_req(&req->base, creq, dir);
2841a6061921SPascal van Leeuwen 	}
2842a6061921SPascal van Leeuwen 
2843a6061921SPascal van Leeuwen 	/* HW cannot do full (AAD+payload) zero length, use fallback */
284413a1bb93SPascal van Leeuwen 	memcpy(key, ctx->key, CHACHA_KEY_SIZE);
2845a6061921SPascal van Leeuwen 	if (ctx->aead == EIP197_AEAD_TYPE_IPSEC_ESP) {
2846a6061921SPascal van Leeuwen 		/* ESP variant has nonce appended to the key */
2847a6061921SPascal van Leeuwen 		key[CHACHA_KEY_SIZE / sizeof(u32)] = ctx->nonce;
2848a6061921SPascal van Leeuwen 		ret = crypto_aead_setkey(ctx->fback, (u8 *)key,
2849a6061921SPascal van Leeuwen 					 CHACHA_KEY_SIZE +
2850a6061921SPascal van Leeuwen 					 EIP197_AEAD_IPSEC_NONCE_SIZE);
2851a6061921SPascal van Leeuwen 	} else {
2852a6061921SPascal van Leeuwen 		ret = crypto_aead_setkey(ctx->fback, (u8 *)key,
2853a6061921SPascal van Leeuwen 					 CHACHA_KEY_SIZE);
2854a6061921SPascal van Leeuwen 	}
2855a6061921SPascal van Leeuwen 	if (ret) {
2856a6061921SPascal van Leeuwen 		crypto_aead_clear_flags(aead, CRYPTO_TFM_REQ_MASK);
2857a6061921SPascal van Leeuwen 		crypto_aead_set_flags(aead, crypto_aead_get_flags(ctx->fback) &
2858a6061921SPascal van Leeuwen 					    CRYPTO_TFM_REQ_MASK);
2859a6061921SPascal van Leeuwen 		return ret;
2860a6061921SPascal van Leeuwen 	}
2861a6061921SPascal van Leeuwen 
2862a6061921SPascal van Leeuwen 	aead_request_set_tfm(subreq, ctx->fback);
2863a6061921SPascal van Leeuwen 	aead_request_set_callback(subreq, req->base.flags, req->base.complete,
2864a6061921SPascal van Leeuwen 				  req->base.data);
2865a6061921SPascal van Leeuwen 	aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen,
2866a6061921SPascal van Leeuwen 			       req->iv);
2867a6061921SPascal van Leeuwen 	aead_request_set_ad(subreq, req->assoclen);
2868a6061921SPascal van Leeuwen 
2869a6061921SPascal van Leeuwen 	return (dir ==  SAFEXCEL_ENCRYPT) ?
2870a6061921SPascal van Leeuwen 		crypto_aead_encrypt(subreq) :
2871a6061921SPascal van Leeuwen 		crypto_aead_decrypt(subreq);
2872a6061921SPascal van Leeuwen }
2873a6061921SPascal van Leeuwen 
safexcel_aead_chachapoly_encrypt(struct aead_request * req)2874a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_encrypt(struct aead_request *req)
2875a6061921SPascal van Leeuwen {
2876a6061921SPascal van Leeuwen 	return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_ENCRYPT);
2877a6061921SPascal van Leeuwen }
2878a6061921SPascal van Leeuwen 
safexcel_aead_chachapoly_decrypt(struct aead_request * req)2879a6061921SPascal van Leeuwen static int safexcel_aead_chachapoly_decrypt(struct aead_request *req)
2880a6061921SPascal van Leeuwen {
2881a6061921SPascal van Leeuwen 	return safexcel_aead_chachapoly_crypt(req, SAFEXCEL_DECRYPT);
2882a6061921SPascal van Leeuwen }
2883a6061921SPascal van Leeuwen 
safexcel_aead_fallback_cra_init(struct crypto_tfm * tfm)28841769f704SPascal van Leeuwen static int safexcel_aead_fallback_cra_init(struct crypto_tfm *tfm)
2885a6061921SPascal van Leeuwen {
2886a6061921SPascal van Leeuwen 	struct crypto_aead *aead = __crypto_aead_cast(tfm);
2887a6061921SPascal van Leeuwen 	struct aead_alg *alg = crypto_aead_alg(aead);
2888a6061921SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
2889a6061921SPascal van Leeuwen 
2890a6061921SPascal van Leeuwen 	safexcel_aead_cra_init(tfm);
2891a6061921SPascal van Leeuwen 
2892a6061921SPascal van Leeuwen 	/* Allocate fallback implementation */
2893a6061921SPascal van Leeuwen 	ctx->fback = crypto_alloc_aead(alg->base.cra_name, 0,
2894a6061921SPascal van Leeuwen 				       CRYPTO_ALG_ASYNC |
2895a6061921SPascal van Leeuwen 				       CRYPTO_ALG_NEED_FALLBACK);
2896a6061921SPascal van Leeuwen 	if (IS_ERR(ctx->fback))
2897a6061921SPascal van Leeuwen 		return PTR_ERR(ctx->fback);
2898a6061921SPascal van Leeuwen 
2899a6061921SPascal van Leeuwen 	crypto_aead_set_reqsize(aead, max(sizeof(struct safexcel_cipher_req),
2900a6061921SPascal van Leeuwen 					  sizeof(struct aead_request) +
2901a6061921SPascal van Leeuwen 					  crypto_aead_reqsize(ctx->fback)));
2902a6061921SPascal van Leeuwen 
2903a6061921SPascal van Leeuwen 	return 0;
2904a6061921SPascal van Leeuwen }
2905a6061921SPascal van Leeuwen 
safexcel_aead_chachapoly_cra_init(struct crypto_tfm * tfm)29061769f704SPascal van Leeuwen static int safexcel_aead_chachapoly_cra_init(struct crypto_tfm *tfm)
29071769f704SPascal van Leeuwen {
29081769f704SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
29091769f704SPascal van Leeuwen 
29101769f704SPascal van Leeuwen 	safexcel_aead_fallback_cra_init(tfm);
29111769f704SPascal van Leeuwen 	ctx->alg  = SAFEXCEL_CHACHA20;
29121769f704SPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CHACHA20_MODE_256_32 |
29131769f704SPascal van Leeuwen 		    CONTEXT_CONTROL_CHACHA20_MODE_CALC_OTK;
2914098e51e5SPascal van Leeuwen 	ctx->ctrinit = 0;
29151769f704SPascal van Leeuwen 	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_POLY1305;
29161769f704SPascal van Leeuwen 	ctx->state_sz = 0; /* Precomputed by HW */
29171769f704SPascal van Leeuwen 	return 0;
29181769f704SPascal van Leeuwen }
29191769f704SPascal van Leeuwen 
safexcel_aead_fallback_cra_exit(struct crypto_tfm * tfm)29201769f704SPascal van Leeuwen static void safexcel_aead_fallback_cra_exit(struct crypto_tfm *tfm)
2921a6061921SPascal van Leeuwen {
2922a6061921SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
2923a6061921SPascal van Leeuwen 
2924a6061921SPascal van Leeuwen 	crypto_free_aead(ctx->fback);
2925a6061921SPascal van Leeuwen 	safexcel_aead_cra_exit(tfm);
2926a6061921SPascal van Leeuwen }
2927a6061921SPascal van Leeuwen 
2928a6061921SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_chachapoly = {
2929a6061921SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
2930a6061921SPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305,
2931a6061921SPascal van Leeuwen 	.alg.aead = {
2932a6061921SPascal van Leeuwen 		.setkey = safexcel_aead_chachapoly_setkey,
2933a6061921SPascal van Leeuwen 		.setauthsize = safexcel_aead_chachapoly_setauthsize,
2934a6061921SPascal van Leeuwen 		.encrypt = safexcel_aead_chachapoly_encrypt,
2935a6061921SPascal van Leeuwen 		.decrypt = safexcel_aead_chachapoly_decrypt,
2936a6061921SPascal van Leeuwen 		.ivsize = CHACHAPOLY_IV_SIZE,
2937a6061921SPascal van Leeuwen 		.maxauthsize = POLY1305_DIGEST_SIZE,
2938a6061921SPascal van Leeuwen 		.base = {
2939a6061921SPascal van Leeuwen 			.cra_name = "rfc7539(chacha20,poly1305)",
2940a6061921SPascal van Leeuwen 			.cra_driver_name = "safexcel-chacha20-poly1305",
2941a6061921SPascal van Leeuwen 			/* +1 to put it above HW chacha + SW poly */
2942a6061921SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY + 1,
2943a6061921SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
2944b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
2945a6061921SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY |
2946a6061921SPascal van Leeuwen 				     CRYPTO_ALG_NEED_FALLBACK,
2947a6061921SPascal van Leeuwen 			.cra_blocksize = 1,
2948a6061921SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
2949a6061921SPascal van Leeuwen 			.cra_alignmask = 0,
2950a6061921SPascal van Leeuwen 			.cra_init = safexcel_aead_chachapoly_cra_init,
29511769f704SPascal van Leeuwen 			.cra_exit = safexcel_aead_fallback_cra_exit,
2952a6061921SPascal van Leeuwen 			.cra_module = THIS_MODULE,
2953a6061921SPascal van Leeuwen 		},
2954a6061921SPascal van Leeuwen 	},
2955a6061921SPascal van Leeuwen };
2956a6061921SPascal van Leeuwen 
safexcel_aead_chachapolyesp_cra_init(struct crypto_tfm * tfm)2957a6061921SPascal van Leeuwen static int safexcel_aead_chachapolyesp_cra_init(struct crypto_tfm *tfm)
2958a6061921SPascal van Leeuwen {
2959a6061921SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
2960a6061921SPascal van Leeuwen 	int ret;
2961a6061921SPascal van Leeuwen 
2962a6061921SPascal van Leeuwen 	ret = safexcel_aead_chachapoly_cra_init(tfm);
2963a6061921SPascal van Leeuwen 	ctx->aead  = EIP197_AEAD_TYPE_IPSEC_ESP;
2964098e51e5SPascal van Leeuwen 	ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE;
2965a6061921SPascal van Leeuwen 	return ret;
2966a6061921SPascal van Leeuwen }
2967a6061921SPascal van Leeuwen 
2968a6061921SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_chachapoly_esp = {
2969a6061921SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
2970a6061921SPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_CHACHA20 | SAFEXCEL_ALG_POLY1305,
2971a6061921SPascal van Leeuwen 	.alg.aead = {
2972a6061921SPascal van Leeuwen 		.setkey = safexcel_aead_chachapoly_setkey,
2973a6061921SPascal van Leeuwen 		.setauthsize = safexcel_aead_chachapoly_setauthsize,
2974a6061921SPascal van Leeuwen 		.encrypt = safexcel_aead_chachapoly_encrypt,
2975a6061921SPascal van Leeuwen 		.decrypt = safexcel_aead_chachapoly_decrypt,
2976a6061921SPascal van Leeuwen 		.ivsize = CHACHAPOLY_IV_SIZE - EIP197_AEAD_IPSEC_NONCE_SIZE,
2977a6061921SPascal van Leeuwen 		.maxauthsize = POLY1305_DIGEST_SIZE,
2978a6061921SPascal van Leeuwen 		.base = {
2979a6061921SPascal van Leeuwen 			.cra_name = "rfc7539esp(chacha20,poly1305)",
2980a6061921SPascal van Leeuwen 			.cra_driver_name = "safexcel-chacha20-poly1305-esp",
2981a6061921SPascal van Leeuwen 			/* +1 to put it above HW chacha + SW poly */
2982a6061921SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY + 1,
2983a6061921SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
2984b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
2985a6061921SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY |
2986a6061921SPascal van Leeuwen 				     CRYPTO_ALG_NEED_FALLBACK,
2987a6061921SPascal van Leeuwen 			.cra_blocksize = 1,
2988a6061921SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
2989a6061921SPascal van Leeuwen 			.cra_alignmask = 0,
2990a6061921SPascal van Leeuwen 			.cra_init = safexcel_aead_chachapolyesp_cra_init,
29911769f704SPascal van Leeuwen 			.cra_exit = safexcel_aead_fallback_cra_exit,
2992a6061921SPascal van Leeuwen 			.cra_module = THIS_MODULE,
2993a6061921SPascal van Leeuwen 		},
2994a6061921SPascal van Leeuwen 	},
2995a6061921SPascal van Leeuwen };
2996fcca797dSPascal van Leeuwen 
safexcel_skcipher_sm4_setkey(struct crypto_skcipher * ctfm,const u8 * key,unsigned int len)2997fcca797dSPascal van Leeuwen static int safexcel_skcipher_sm4_setkey(struct crypto_skcipher *ctfm,
2998fcca797dSPascal van Leeuwen 					const u8 *key, unsigned int len)
2999fcca797dSPascal van Leeuwen {
3000fcca797dSPascal van Leeuwen 	struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);
3001fcca797dSPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
300218e51895SHerbert Xu 	struct safexcel_crypto_priv *priv = ctx->base.priv;
3003fcca797dSPascal van Leeuwen 
3004674f368aSEric Biggers 	if (len != SM4_KEY_SIZE)
3005fcca797dSPascal van Leeuwen 		return -EINVAL;
3006fcca797dSPascal van Leeuwen 
300713a1bb93SPascal van Leeuwen 	if (priv->flags & EIP197_TRC_CACHE && ctx->base.ctxr_dma)
300813a1bb93SPascal van Leeuwen 		if (memcmp(ctx->key, key, SM4_KEY_SIZE))
3009fcca797dSPascal van Leeuwen 			ctx->base.needs_inv = true;
3010fcca797dSPascal van Leeuwen 
301113a1bb93SPascal van Leeuwen 	memcpy(ctx->key, key, SM4_KEY_SIZE);
3012fcca797dSPascal van Leeuwen 	ctx->key_len = SM4_KEY_SIZE;
3013fcca797dSPascal van Leeuwen 
3014fcca797dSPascal van Leeuwen 	return 0;
3015fcca797dSPascal van Leeuwen }
3016fcca797dSPascal van Leeuwen 
safexcel_sm4_blk_encrypt(struct skcipher_request * req)3017fcca797dSPascal van Leeuwen static int safexcel_sm4_blk_encrypt(struct skcipher_request *req)
3018fcca797dSPascal van Leeuwen {
3019fcca797dSPascal van Leeuwen 	/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */
3020fcca797dSPascal van Leeuwen 	if (req->cryptlen & (SM4_BLOCK_SIZE - 1))
3021fcca797dSPascal van Leeuwen 		return -EINVAL;
3022fcca797dSPascal van Leeuwen 	else
3023fcca797dSPascal van Leeuwen 		return safexcel_queue_req(&req->base, skcipher_request_ctx(req),
3024fcca797dSPascal van Leeuwen 					  SAFEXCEL_ENCRYPT);
3025fcca797dSPascal van Leeuwen }
3026fcca797dSPascal van Leeuwen 
safexcel_sm4_blk_decrypt(struct skcipher_request * req)3027fcca797dSPascal van Leeuwen static int safexcel_sm4_blk_decrypt(struct skcipher_request *req)
3028fcca797dSPascal van Leeuwen {
3029fcca797dSPascal van Leeuwen 	/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */
3030fcca797dSPascal van Leeuwen 	if (req->cryptlen & (SM4_BLOCK_SIZE - 1))
3031fcca797dSPascal van Leeuwen 		return -EINVAL;
3032fcca797dSPascal van Leeuwen 	else
3033fcca797dSPascal van Leeuwen 		return safexcel_queue_req(&req->base, skcipher_request_ctx(req),
3034fcca797dSPascal van Leeuwen 					  SAFEXCEL_DECRYPT);
3035fcca797dSPascal van Leeuwen }
3036fcca797dSPascal van Leeuwen 
safexcel_skcipher_sm4_ecb_cra_init(struct crypto_tfm * tfm)3037fcca797dSPascal van Leeuwen static int safexcel_skcipher_sm4_ecb_cra_init(struct crypto_tfm *tfm)
3038fcca797dSPascal van Leeuwen {
3039fcca797dSPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
3040fcca797dSPascal van Leeuwen 
3041fcca797dSPascal van Leeuwen 	safexcel_skcipher_cra_init(tfm);
3042fcca797dSPascal van Leeuwen 	ctx->alg  = SAFEXCEL_SM4;
3043fcca797dSPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_ECB;
3044098e51e5SPascal van Leeuwen 	ctx->blocksz = 0;
3045098e51e5SPascal van Leeuwen 	ctx->ivmask = EIP197_OPTION_2_TOKEN_IV_CMD;
3046fcca797dSPascal van Leeuwen 	return 0;
3047fcca797dSPascal van Leeuwen }
3048fcca797dSPascal van Leeuwen 
3049fcca797dSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ecb_sm4 = {
3050fcca797dSPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
3051fcca797dSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_SM4,
3052fcca797dSPascal van Leeuwen 	.alg.skcipher = {
3053fcca797dSPascal van Leeuwen 		.setkey = safexcel_skcipher_sm4_setkey,
3054fcca797dSPascal van Leeuwen 		.encrypt = safexcel_sm4_blk_encrypt,
3055fcca797dSPascal van Leeuwen 		.decrypt = safexcel_sm4_blk_decrypt,
3056fcca797dSPascal van Leeuwen 		.min_keysize = SM4_KEY_SIZE,
3057fcca797dSPascal van Leeuwen 		.max_keysize = SM4_KEY_SIZE,
3058fcca797dSPascal van Leeuwen 		.base = {
3059fcca797dSPascal van Leeuwen 			.cra_name = "ecb(sm4)",
3060fcca797dSPascal van Leeuwen 			.cra_driver_name = "safexcel-ecb-sm4",
3061fcca797dSPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
3062fcca797dSPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
3063b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
3064fcca797dSPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
3065fcca797dSPascal van Leeuwen 			.cra_blocksize = SM4_BLOCK_SIZE,
3066fcca797dSPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
3067fcca797dSPascal van Leeuwen 			.cra_alignmask = 0,
3068fcca797dSPascal van Leeuwen 			.cra_init = safexcel_skcipher_sm4_ecb_cra_init,
3069fcca797dSPascal van Leeuwen 			.cra_exit = safexcel_skcipher_cra_exit,
3070fcca797dSPascal van Leeuwen 			.cra_module = THIS_MODULE,
3071fcca797dSPascal van Leeuwen 		},
3072fcca797dSPascal van Leeuwen 	},
3073fcca797dSPascal van Leeuwen };
30746f2d1428SPascal van Leeuwen 
safexcel_skcipher_sm4_cbc_cra_init(struct crypto_tfm * tfm)30756f2d1428SPascal van Leeuwen static int safexcel_skcipher_sm4_cbc_cra_init(struct crypto_tfm *tfm)
30766f2d1428SPascal van Leeuwen {
30776f2d1428SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
30786f2d1428SPascal van Leeuwen 
30796f2d1428SPascal van Leeuwen 	safexcel_skcipher_cra_init(tfm);
30806f2d1428SPascal van Leeuwen 	ctx->alg  = SAFEXCEL_SM4;
3081098e51e5SPascal van Leeuwen 	ctx->blocksz = SM4_BLOCK_SIZE;
30826f2d1428SPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CBC;
30836f2d1428SPascal van Leeuwen 	return 0;
30846f2d1428SPascal van Leeuwen }
30856f2d1428SPascal van Leeuwen 
30866f2d1428SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_cbc_sm4 = {
30876f2d1428SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
30886f2d1428SPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_SM4,
30896f2d1428SPascal van Leeuwen 	.alg.skcipher = {
30906f2d1428SPascal van Leeuwen 		.setkey = safexcel_skcipher_sm4_setkey,
30916f2d1428SPascal van Leeuwen 		.encrypt = safexcel_sm4_blk_encrypt,
30926f2d1428SPascal van Leeuwen 		.decrypt = safexcel_sm4_blk_decrypt,
30936f2d1428SPascal van Leeuwen 		.min_keysize = SM4_KEY_SIZE,
30946f2d1428SPascal van Leeuwen 		.max_keysize = SM4_KEY_SIZE,
30956f2d1428SPascal van Leeuwen 		.ivsize = SM4_BLOCK_SIZE,
30966f2d1428SPascal van Leeuwen 		.base = {
30976f2d1428SPascal van Leeuwen 			.cra_name = "cbc(sm4)",
30986f2d1428SPascal van Leeuwen 			.cra_driver_name = "safexcel-cbc-sm4",
30996f2d1428SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
31006f2d1428SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
3101b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
31026f2d1428SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
31036f2d1428SPascal van Leeuwen 			.cra_blocksize = SM4_BLOCK_SIZE,
31046f2d1428SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
31056f2d1428SPascal van Leeuwen 			.cra_alignmask = 0,
31066f2d1428SPascal van Leeuwen 			.cra_init = safexcel_skcipher_sm4_cbc_cra_init,
31076f2d1428SPascal van Leeuwen 			.cra_exit = safexcel_skcipher_cra_exit,
31086f2d1428SPascal van Leeuwen 			.cra_module = THIS_MODULE,
31096f2d1428SPascal van Leeuwen 		},
31106f2d1428SPascal van Leeuwen 	},
31116f2d1428SPascal van Leeuwen };
311203a6cfb9SPascal van Leeuwen 
safexcel_skcipher_sm4ctr_setkey(struct crypto_skcipher * ctfm,const u8 * key,unsigned int len)3113f77e5dc0SPascal van Leeuwen static int safexcel_skcipher_sm4ctr_setkey(struct crypto_skcipher *ctfm,
3114f77e5dc0SPascal van Leeuwen 					   const u8 *key, unsigned int len)
3115f77e5dc0SPascal van Leeuwen {
3116f77e5dc0SPascal van Leeuwen 	struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm);
3117f77e5dc0SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
3118f77e5dc0SPascal van Leeuwen 
3119f77e5dc0SPascal van Leeuwen 	/* last 4 bytes of key are the nonce! */
3120f77e5dc0SPascal van Leeuwen 	ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE);
3121f77e5dc0SPascal van Leeuwen 	/* exclude the nonce here */
3122f77e5dc0SPascal van Leeuwen 	len -= CTR_RFC3686_NONCE_SIZE;
3123f77e5dc0SPascal van Leeuwen 
3124f77e5dc0SPascal van Leeuwen 	return safexcel_skcipher_sm4_setkey(ctfm, key, len);
3125f77e5dc0SPascal van Leeuwen }
3126f77e5dc0SPascal van Leeuwen 
safexcel_skcipher_sm4_ctr_cra_init(struct crypto_tfm * tfm)3127f77e5dc0SPascal van Leeuwen static int safexcel_skcipher_sm4_ctr_cra_init(struct crypto_tfm *tfm)
3128f77e5dc0SPascal van Leeuwen {
3129f77e5dc0SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
3130f77e5dc0SPascal van Leeuwen 
3131f77e5dc0SPascal van Leeuwen 	safexcel_skcipher_cra_init(tfm);
3132f77e5dc0SPascal van Leeuwen 	ctx->alg  = SAFEXCEL_SM4;
3133098e51e5SPascal van Leeuwen 	ctx->blocksz = SM4_BLOCK_SIZE;
3134f77e5dc0SPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;
3135f77e5dc0SPascal van Leeuwen 	return 0;
3136f77e5dc0SPascal van Leeuwen }
3137f77e5dc0SPascal van Leeuwen 
3138f77e5dc0SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_ctr_sm4 = {
3139f77e5dc0SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_SKCIPHER,
3140f77e5dc0SPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_SM4,
3141f77e5dc0SPascal van Leeuwen 	.alg.skcipher = {
3142f77e5dc0SPascal van Leeuwen 		.setkey = safexcel_skcipher_sm4ctr_setkey,
3143f77e5dc0SPascal van Leeuwen 		.encrypt = safexcel_encrypt,
3144f77e5dc0SPascal van Leeuwen 		.decrypt = safexcel_decrypt,
3145f77e5dc0SPascal van Leeuwen 		/* Add nonce size */
3146f77e5dc0SPascal van Leeuwen 		.min_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,
3147f77e5dc0SPascal van Leeuwen 		.max_keysize = SM4_KEY_SIZE + CTR_RFC3686_NONCE_SIZE,
3148f77e5dc0SPascal van Leeuwen 		.ivsize = CTR_RFC3686_IV_SIZE,
3149f77e5dc0SPascal van Leeuwen 		.base = {
3150f77e5dc0SPascal van Leeuwen 			.cra_name = "rfc3686(ctr(sm4))",
3151f77e5dc0SPascal van Leeuwen 			.cra_driver_name = "safexcel-ctr-sm4",
3152f77e5dc0SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
3153f77e5dc0SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
3154b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
3155f77e5dc0SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
3156f77e5dc0SPascal van Leeuwen 			.cra_blocksize = 1,
3157f77e5dc0SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
3158f77e5dc0SPascal van Leeuwen 			.cra_alignmask = 0,
3159f77e5dc0SPascal van Leeuwen 			.cra_init = safexcel_skcipher_sm4_ctr_cra_init,
3160f77e5dc0SPascal van Leeuwen 			.cra_exit = safexcel_skcipher_cra_exit,
3161f77e5dc0SPascal van Leeuwen 			.cra_module = THIS_MODULE,
3162f77e5dc0SPascal van Leeuwen 		},
3163f77e5dc0SPascal van Leeuwen 	},
3164f77e5dc0SPascal van Leeuwen };
31651769f704SPascal van Leeuwen 
safexcel_aead_sm4_blk_encrypt(struct aead_request * req)31661769f704SPascal van Leeuwen static int safexcel_aead_sm4_blk_encrypt(struct aead_request *req)
31671769f704SPascal van Leeuwen {
31681769f704SPascal van Leeuwen 	/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */
31691769f704SPascal van Leeuwen 	if (req->cryptlen & (SM4_BLOCK_SIZE - 1))
31701769f704SPascal van Leeuwen 		return -EINVAL;
31711769f704SPascal van Leeuwen 
31721769f704SPascal van Leeuwen 	return safexcel_queue_req(&req->base, aead_request_ctx(req),
31731769f704SPascal van Leeuwen 				  SAFEXCEL_ENCRYPT);
31741769f704SPascal van Leeuwen }
31751769f704SPascal van Leeuwen 
safexcel_aead_sm4_blk_decrypt(struct aead_request * req)31761769f704SPascal van Leeuwen static int safexcel_aead_sm4_blk_decrypt(struct aead_request *req)
31771769f704SPascal van Leeuwen {
31781769f704SPascal van Leeuwen 	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
31791769f704SPascal van Leeuwen 
31801769f704SPascal van Leeuwen 	/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */
31811769f704SPascal van Leeuwen 	if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1))
31821769f704SPascal van Leeuwen 		return -EINVAL;
31831769f704SPascal van Leeuwen 
31841769f704SPascal van Leeuwen 	return safexcel_queue_req(&req->base, aead_request_ctx(req),
31851769f704SPascal van Leeuwen 				  SAFEXCEL_DECRYPT);
31861769f704SPascal van Leeuwen }
31871769f704SPascal van Leeuwen 
safexcel_aead_sm4cbc_sha1_cra_init(struct crypto_tfm * tfm)31881769f704SPascal van Leeuwen static int safexcel_aead_sm4cbc_sha1_cra_init(struct crypto_tfm *tfm)
31891769f704SPascal van Leeuwen {
31901769f704SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
31911769f704SPascal van Leeuwen 
31921769f704SPascal van Leeuwen 	safexcel_aead_cra_init(tfm);
31931769f704SPascal van Leeuwen 	ctx->alg = SAFEXCEL_SM4;
3194098e51e5SPascal van Leeuwen 	ctx->blocksz = SM4_BLOCK_SIZE;
31951769f704SPascal van Leeuwen 	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SHA1;
31961769f704SPascal van Leeuwen 	ctx->state_sz = SHA1_DIGEST_SIZE;
31971769f704SPascal van Leeuwen 	return 0;
31981769f704SPascal van Leeuwen }
31991769f704SPascal van Leeuwen 
32001769f704SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_cbc_sm4 = {
32011769f704SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
32021769f704SPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1,
32031769f704SPascal van Leeuwen 	.alg.aead = {
32041769f704SPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
32051769f704SPascal van Leeuwen 		.encrypt = safexcel_aead_sm4_blk_encrypt,
32061769f704SPascal van Leeuwen 		.decrypt = safexcel_aead_sm4_blk_decrypt,
32071769f704SPascal van Leeuwen 		.ivsize = SM4_BLOCK_SIZE,
32081769f704SPascal van Leeuwen 		.maxauthsize = SHA1_DIGEST_SIZE,
32091769f704SPascal van Leeuwen 		.base = {
32101769f704SPascal van Leeuwen 			.cra_name = "authenc(hmac(sha1),cbc(sm4))",
32111769f704SPascal van Leeuwen 			.cra_driver_name = "safexcel-authenc-hmac-sha1-cbc-sm4",
32121769f704SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
32131769f704SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
3214b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
32151769f704SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
32161769f704SPascal van Leeuwen 			.cra_blocksize = SM4_BLOCK_SIZE,
32171769f704SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
32181769f704SPascal van Leeuwen 			.cra_alignmask = 0,
32191769f704SPascal van Leeuwen 			.cra_init = safexcel_aead_sm4cbc_sha1_cra_init,
32201769f704SPascal van Leeuwen 			.cra_exit = safexcel_aead_cra_exit,
32211769f704SPascal van Leeuwen 			.cra_module = THIS_MODULE,
32221769f704SPascal van Leeuwen 		},
32231769f704SPascal van Leeuwen 	},
32241769f704SPascal van Leeuwen };
32251769f704SPascal van Leeuwen 
safexcel_aead_fallback_setkey(struct crypto_aead * ctfm,const u8 * key,unsigned int len)32261769f704SPascal van Leeuwen static int safexcel_aead_fallback_setkey(struct crypto_aead *ctfm,
32271769f704SPascal van Leeuwen 					 const u8 *key, unsigned int len)
32281769f704SPascal van Leeuwen {
32291769f704SPascal van Leeuwen 	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);
32301769f704SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
32311769f704SPascal van Leeuwen 
32321769f704SPascal van Leeuwen 	/* Keep fallback cipher synchronized */
32331769f704SPascal van Leeuwen 	return crypto_aead_setkey(ctx->fback, (u8 *)key, len) ?:
32341769f704SPascal van Leeuwen 	       safexcel_aead_setkey(ctfm, key, len);
32351769f704SPascal van Leeuwen }
32361769f704SPascal van Leeuwen 
safexcel_aead_fallback_setauthsize(struct crypto_aead * ctfm,unsigned int authsize)32371769f704SPascal van Leeuwen static int safexcel_aead_fallback_setauthsize(struct crypto_aead *ctfm,
32381769f704SPascal van Leeuwen 					      unsigned int authsize)
32391769f704SPascal van Leeuwen {
32401769f704SPascal van Leeuwen 	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);
32411769f704SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
32421769f704SPascal van Leeuwen 
32431769f704SPascal van Leeuwen 	/* Keep fallback cipher synchronized */
32441769f704SPascal van Leeuwen 	return crypto_aead_setauthsize(ctx->fback, authsize);
32451769f704SPascal van Leeuwen }
32461769f704SPascal van Leeuwen 
safexcel_aead_fallback_crypt(struct aead_request * req,enum safexcel_cipher_direction dir)32471769f704SPascal van Leeuwen static int safexcel_aead_fallback_crypt(struct aead_request *req,
32481769f704SPascal van Leeuwen 					enum safexcel_cipher_direction dir)
32491769f704SPascal van Leeuwen {
32501769f704SPascal van Leeuwen 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
32511769f704SPascal van Leeuwen 	struct crypto_tfm *tfm = crypto_aead_tfm(aead);
32521769f704SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
32531769f704SPascal van Leeuwen 	struct aead_request *subreq = aead_request_ctx(req);
32541769f704SPascal van Leeuwen 
32551769f704SPascal van Leeuwen 	aead_request_set_tfm(subreq, ctx->fback);
32561769f704SPascal van Leeuwen 	aead_request_set_callback(subreq, req->base.flags, req->base.complete,
32571769f704SPascal van Leeuwen 				  req->base.data);
32581769f704SPascal van Leeuwen 	aead_request_set_crypt(subreq, req->src, req->dst, req->cryptlen,
32591769f704SPascal van Leeuwen 			       req->iv);
32601769f704SPascal van Leeuwen 	aead_request_set_ad(subreq, req->assoclen);
32611769f704SPascal van Leeuwen 
32621769f704SPascal van Leeuwen 	return (dir ==  SAFEXCEL_ENCRYPT) ?
32631769f704SPascal van Leeuwen 		crypto_aead_encrypt(subreq) :
32641769f704SPascal van Leeuwen 		crypto_aead_decrypt(subreq);
32651769f704SPascal van Leeuwen }
32661769f704SPascal van Leeuwen 
safexcel_aead_sm4cbc_sm3_encrypt(struct aead_request * req)32671769f704SPascal van Leeuwen static int safexcel_aead_sm4cbc_sm3_encrypt(struct aead_request *req)
32681769f704SPascal van Leeuwen {
32691769f704SPascal van Leeuwen 	struct safexcel_cipher_req *creq = aead_request_ctx(req);
32701769f704SPascal van Leeuwen 
32711769f704SPascal van Leeuwen 	/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */
32721769f704SPascal van Leeuwen 	if (req->cryptlen & (SM4_BLOCK_SIZE - 1))
32731769f704SPascal van Leeuwen 		return -EINVAL;
32741769f704SPascal van Leeuwen 	else if (req->cryptlen || req->assoclen) /* If input length > 0 only */
32751769f704SPascal van Leeuwen 		return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT);
32761769f704SPascal van Leeuwen 
32771769f704SPascal van Leeuwen 	/* HW cannot do full (AAD+payload) zero length, use fallback */
32781769f704SPascal van Leeuwen 	return safexcel_aead_fallback_crypt(req, SAFEXCEL_ENCRYPT);
32791769f704SPascal van Leeuwen }
32801769f704SPascal van Leeuwen 
safexcel_aead_sm4cbc_sm3_decrypt(struct aead_request * req)32811769f704SPascal van Leeuwen static int safexcel_aead_sm4cbc_sm3_decrypt(struct aead_request *req)
32821769f704SPascal van Leeuwen {
32831769f704SPascal van Leeuwen 	struct safexcel_cipher_req *creq = aead_request_ctx(req);
32841769f704SPascal van Leeuwen 	struct crypto_aead *tfm = crypto_aead_reqtfm(req);
32851769f704SPascal van Leeuwen 
32861769f704SPascal van Leeuwen 	/* Workaround for HW bug: EIP96 4.3 does not report blocksize error */
32871769f704SPascal van Leeuwen 	if ((req->cryptlen - crypto_aead_authsize(tfm)) & (SM4_BLOCK_SIZE - 1))
32881769f704SPascal van Leeuwen 		return -EINVAL;
32891769f704SPascal van Leeuwen 	else if (req->cryptlen > crypto_aead_authsize(tfm) || req->assoclen)
32901769f704SPascal van Leeuwen 		/* If input length > 0 only */
32911769f704SPascal van Leeuwen 		return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT);
32921769f704SPascal van Leeuwen 
32931769f704SPascal van Leeuwen 	/* HW cannot do full (AAD+payload) zero length, use fallback */
32941769f704SPascal van Leeuwen 	return safexcel_aead_fallback_crypt(req, SAFEXCEL_DECRYPT);
32951769f704SPascal van Leeuwen }
32961769f704SPascal van Leeuwen 
safexcel_aead_sm4cbc_sm3_cra_init(struct crypto_tfm * tfm)32971769f704SPascal van Leeuwen static int safexcel_aead_sm4cbc_sm3_cra_init(struct crypto_tfm *tfm)
32981769f704SPascal van Leeuwen {
32991769f704SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
33001769f704SPascal van Leeuwen 
33011769f704SPascal van Leeuwen 	safexcel_aead_fallback_cra_init(tfm);
33021769f704SPascal van Leeuwen 	ctx->alg = SAFEXCEL_SM4;
3303098e51e5SPascal van Leeuwen 	ctx->blocksz = SM4_BLOCK_SIZE;
33041769f704SPascal van Leeuwen 	ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_SM3;
33051769f704SPascal van Leeuwen 	ctx->state_sz = SM3_DIGEST_SIZE;
33061769f704SPascal van Leeuwen 	return 0;
33071769f704SPascal van Leeuwen }
33081769f704SPascal van Leeuwen 
33091769f704SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_cbc_sm4 = {
33101769f704SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
33111769f704SPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3,
33121769f704SPascal van Leeuwen 	.alg.aead = {
33131769f704SPascal van Leeuwen 		.setkey = safexcel_aead_fallback_setkey,
33141769f704SPascal van Leeuwen 		.setauthsize = safexcel_aead_fallback_setauthsize,
33151769f704SPascal van Leeuwen 		.encrypt = safexcel_aead_sm4cbc_sm3_encrypt,
33161769f704SPascal van Leeuwen 		.decrypt = safexcel_aead_sm4cbc_sm3_decrypt,
33171769f704SPascal van Leeuwen 		.ivsize = SM4_BLOCK_SIZE,
33181769f704SPascal van Leeuwen 		.maxauthsize = SM3_DIGEST_SIZE,
33191769f704SPascal van Leeuwen 		.base = {
33201769f704SPascal van Leeuwen 			.cra_name = "authenc(hmac(sm3),cbc(sm4))",
33211769f704SPascal van Leeuwen 			.cra_driver_name = "safexcel-authenc-hmac-sm3-cbc-sm4",
33221769f704SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
33231769f704SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
3324b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
33251769f704SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY |
33261769f704SPascal van Leeuwen 				     CRYPTO_ALG_NEED_FALLBACK,
33271769f704SPascal van Leeuwen 			.cra_blocksize = SM4_BLOCK_SIZE,
33281769f704SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
33291769f704SPascal van Leeuwen 			.cra_alignmask = 0,
33301769f704SPascal van Leeuwen 			.cra_init = safexcel_aead_sm4cbc_sm3_cra_init,
33311769f704SPascal van Leeuwen 			.cra_exit = safexcel_aead_fallback_cra_exit,
33321769f704SPascal van Leeuwen 			.cra_module = THIS_MODULE,
33331769f704SPascal van Leeuwen 		},
33341769f704SPascal van Leeuwen 	},
33351769f704SPascal van Leeuwen };
33361769f704SPascal van Leeuwen 
safexcel_aead_sm4ctr_sha1_cra_init(struct crypto_tfm * tfm)33371769f704SPascal van Leeuwen static int safexcel_aead_sm4ctr_sha1_cra_init(struct crypto_tfm *tfm)
33381769f704SPascal van Leeuwen {
33391769f704SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
33401769f704SPascal van Leeuwen 
33411769f704SPascal van Leeuwen 	safexcel_aead_sm4cbc_sha1_cra_init(tfm);
33421769f704SPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;
33431769f704SPascal van Leeuwen 	return 0;
33441769f704SPascal van Leeuwen }
33451769f704SPascal van Leeuwen 
33461769f704SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sha1_ctr_sm4 = {
33471769f704SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
33481769f704SPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SHA1,
33491769f704SPascal van Leeuwen 	.alg.aead = {
33501769f704SPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
33511769f704SPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
33521769f704SPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
33531769f704SPascal van Leeuwen 		.ivsize = CTR_RFC3686_IV_SIZE,
33541769f704SPascal van Leeuwen 		.maxauthsize = SHA1_DIGEST_SIZE,
33551769f704SPascal van Leeuwen 		.base = {
33561769f704SPascal van Leeuwen 			.cra_name = "authenc(hmac(sha1),rfc3686(ctr(sm4)))",
33571769f704SPascal van Leeuwen 			.cra_driver_name = "safexcel-authenc-hmac-sha1-ctr-sm4",
33581769f704SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
33591769f704SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
3360b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
33611769f704SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
33621769f704SPascal van Leeuwen 			.cra_blocksize = 1,
33631769f704SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
33641769f704SPascal van Leeuwen 			.cra_alignmask = 0,
33651769f704SPascal van Leeuwen 			.cra_init = safexcel_aead_sm4ctr_sha1_cra_init,
33661769f704SPascal van Leeuwen 			.cra_exit = safexcel_aead_cra_exit,
33671769f704SPascal van Leeuwen 			.cra_module = THIS_MODULE,
33681769f704SPascal van Leeuwen 		},
33691769f704SPascal van Leeuwen 	},
33701769f704SPascal van Leeuwen };
33711769f704SPascal van Leeuwen 
safexcel_aead_sm4ctr_sm3_cra_init(struct crypto_tfm * tfm)33721769f704SPascal van Leeuwen static int safexcel_aead_sm4ctr_sm3_cra_init(struct crypto_tfm *tfm)
33731769f704SPascal van Leeuwen {
33741769f704SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
33751769f704SPascal van Leeuwen 
33761769f704SPascal van Leeuwen 	safexcel_aead_sm4cbc_sm3_cra_init(tfm);
33771769f704SPascal van Leeuwen 	ctx->mode = CONTEXT_CONTROL_CRYPTO_MODE_CTR_LOAD;
33781769f704SPascal van Leeuwen 	return 0;
33791769f704SPascal van Leeuwen }
33801769f704SPascal van Leeuwen 
33811769f704SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_authenc_hmac_sm3_ctr_sm4 = {
33821769f704SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
33831769f704SPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_SM4 | SAFEXCEL_ALG_SM3,
33841769f704SPascal van Leeuwen 	.alg.aead = {
33851769f704SPascal van Leeuwen 		.setkey = safexcel_aead_setkey,
33861769f704SPascal van Leeuwen 		.encrypt = safexcel_aead_encrypt,
33871769f704SPascal van Leeuwen 		.decrypt = safexcel_aead_decrypt,
33881769f704SPascal van Leeuwen 		.ivsize = CTR_RFC3686_IV_SIZE,
33891769f704SPascal van Leeuwen 		.maxauthsize = SM3_DIGEST_SIZE,
33901769f704SPascal van Leeuwen 		.base = {
33911769f704SPascal van Leeuwen 			.cra_name = "authenc(hmac(sm3),rfc3686(ctr(sm4)))",
33921769f704SPascal van Leeuwen 			.cra_driver_name = "safexcel-authenc-hmac-sm3-ctr-sm4",
33931769f704SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
33941769f704SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
3395b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
33961769f704SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
33971769f704SPascal van Leeuwen 			.cra_blocksize = 1,
33981769f704SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
33991769f704SPascal van Leeuwen 			.cra_alignmask = 0,
34001769f704SPascal van Leeuwen 			.cra_init = safexcel_aead_sm4ctr_sm3_cra_init,
34011769f704SPascal van Leeuwen 			.cra_exit = safexcel_aead_cra_exit,
34021769f704SPascal van Leeuwen 			.cra_module = THIS_MODULE,
34031769f704SPascal van Leeuwen 		},
34041769f704SPascal van Leeuwen 	},
34051769f704SPascal van Leeuwen };
3406a19052d4SPascal van Leeuwen 
safexcel_rfc4106_gcm_setkey(struct crypto_aead * ctfm,const u8 * key,unsigned int len)3407a19052d4SPascal van Leeuwen static int safexcel_rfc4106_gcm_setkey(struct crypto_aead *ctfm, const u8 *key,
3408a19052d4SPascal van Leeuwen 				       unsigned int len)
3409a19052d4SPascal van Leeuwen {
3410a19052d4SPascal van Leeuwen 	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);
3411a19052d4SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
3412a19052d4SPascal van Leeuwen 
3413a19052d4SPascal van Leeuwen 	/* last 4 bytes of key are the nonce! */
3414a19052d4SPascal van Leeuwen 	ctx->nonce = *(u32 *)(key + len - CTR_RFC3686_NONCE_SIZE);
3415a19052d4SPascal van Leeuwen 
3416a19052d4SPascal van Leeuwen 	len -= CTR_RFC3686_NONCE_SIZE;
3417a19052d4SPascal van Leeuwen 	return safexcel_aead_gcm_setkey(ctfm, key, len);
3418a19052d4SPascal van Leeuwen }
3419a19052d4SPascal van Leeuwen 
safexcel_rfc4106_gcm_setauthsize(struct crypto_aead * tfm,unsigned int authsize)3420a19052d4SPascal van Leeuwen static int safexcel_rfc4106_gcm_setauthsize(struct crypto_aead *tfm,
3421a19052d4SPascal van Leeuwen 					    unsigned int authsize)
3422a19052d4SPascal van Leeuwen {
3423a19052d4SPascal van Leeuwen 	return crypto_rfc4106_check_authsize(authsize);
3424a19052d4SPascal van Leeuwen }
3425a19052d4SPascal van Leeuwen 
safexcel_rfc4106_encrypt(struct aead_request * req)3426a19052d4SPascal van Leeuwen static int safexcel_rfc4106_encrypt(struct aead_request *req)
3427a19052d4SPascal van Leeuwen {
3428a19052d4SPascal van Leeuwen 	return crypto_ipsec_check_assoclen(req->assoclen) ?:
3429a19052d4SPascal van Leeuwen 	       safexcel_aead_encrypt(req);
3430a19052d4SPascal van Leeuwen }
3431a19052d4SPascal van Leeuwen 
safexcel_rfc4106_decrypt(struct aead_request * req)3432a19052d4SPascal van Leeuwen static int safexcel_rfc4106_decrypt(struct aead_request *req)
3433a19052d4SPascal van Leeuwen {
3434a19052d4SPascal van Leeuwen 	return crypto_ipsec_check_assoclen(req->assoclen) ?:
3435a19052d4SPascal van Leeuwen 	       safexcel_aead_decrypt(req);
3436a19052d4SPascal van Leeuwen }
3437a19052d4SPascal van Leeuwen 
safexcel_rfc4106_gcm_cra_init(struct crypto_tfm * tfm)3438a19052d4SPascal van Leeuwen static int safexcel_rfc4106_gcm_cra_init(struct crypto_tfm *tfm)
3439a19052d4SPascal van Leeuwen {
3440a19052d4SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
3441a19052d4SPascal van Leeuwen 	int ret;
3442a19052d4SPascal van Leeuwen 
3443a19052d4SPascal van Leeuwen 	ret = safexcel_aead_gcm_cra_init(tfm);
3444a19052d4SPascal van Leeuwen 	ctx->aead  = EIP197_AEAD_TYPE_IPSEC_ESP;
3445098e51e5SPascal van Leeuwen 	ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE;
3446a19052d4SPascal van Leeuwen 	return ret;
3447a19052d4SPascal van Leeuwen }
3448a19052d4SPascal van Leeuwen 
3449a19052d4SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_rfc4106_gcm = {
3450a19052d4SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
3451a19052d4SPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH,
3452a19052d4SPascal van Leeuwen 	.alg.aead = {
3453a19052d4SPascal van Leeuwen 		.setkey = safexcel_rfc4106_gcm_setkey,
3454a19052d4SPascal van Leeuwen 		.setauthsize = safexcel_rfc4106_gcm_setauthsize,
3455a19052d4SPascal van Leeuwen 		.encrypt = safexcel_rfc4106_encrypt,
3456a19052d4SPascal van Leeuwen 		.decrypt = safexcel_rfc4106_decrypt,
3457a19052d4SPascal van Leeuwen 		.ivsize = GCM_RFC4106_IV_SIZE,
3458a19052d4SPascal van Leeuwen 		.maxauthsize = GHASH_DIGEST_SIZE,
3459a19052d4SPascal van Leeuwen 		.base = {
3460a19052d4SPascal van Leeuwen 			.cra_name = "rfc4106(gcm(aes))",
3461a19052d4SPascal van Leeuwen 			.cra_driver_name = "safexcel-rfc4106-gcm-aes",
3462a19052d4SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
3463a19052d4SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
3464b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
3465a19052d4SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
3466a19052d4SPascal van Leeuwen 			.cra_blocksize = 1,
3467a19052d4SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
3468a19052d4SPascal van Leeuwen 			.cra_alignmask = 0,
3469a19052d4SPascal van Leeuwen 			.cra_init = safexcel_rfc4106_gcm_cra_init,
3470a19052d4SPascal van Leeuwen 			.cra_exit = safexcel_aead_gcm_cra_exit,
3471a19052d4SPascal van Leeuwen 		},
3472a19052d4SPascal van Leeuwen 	},
3473a19052d4SPascal van Leeuwen };
347492c60cefSPascal van Leeuwen 
safexcel_rfc4543_gcm_setauthsize(struct crypto_aead * tfm,unsigned int authsize)347592c60cefSPascal van Leeuwen static int safexcel_rfc4543_gcm_setauthsize(struct crypto_aead *tfm,
347692c60cefSPascal van Leeuwen 					    unsigned int authsize)
347792c60cefSPascal van Leeuwen {
347892c60cefSPascal van Leeuwen 	if (authsize != GHASH_DIGEST_SIZE)
347992c60cefSPascal van Leeuwen 		return -EINVAL;
348092c60cefSPascal van Leeuwen 
348192c60cefSPascal van Leeuwen 	return 0;
348292c60cefSPascal van Leeuwen }
348392c60cefSPascal van Leeuwen 
safexcel_rfc4543_gcm_cra_init(struct crypto_tfm * tfm)348492c60cefSPascal van Leeuwen static int safexcel_rfc4543_gcm_cra_init(struct crypto_tfm *tfm)
348592c60cefSPascal van Leeuwen {
348692c60cefSPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
348792c60cefSPascal van Leeuwen 	int ret;
348892c60cefSPascal van Leeuwen 
348992c60cefSPascal van Leeuwen 	ret = safexcel_aead_gcm_cra_init(tfm);
349092c60cefSPascal van Leeuwen 	ctx->aead  = EIP197_AEAD_TYPE_IPSEC_ESP_GMAC;
349192c60cefSPascal van Leeuwen 	return ret;
349292c60cefSPascal van Leeuwen }
349392c60cefSPascal van Leeuwen 
349492c60cefSPascal van Leeuwen struct safexcel_alg_template safexcel_alg_rfc4543_gcm = {
349592c60cefSPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
349692c60cefSPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_GHASH,
349792c60cefSPascal van Leeuwen 	.alg.aead = {
349892c60cefSPascal van Leeuwen 		.setkey = safexcel_rfc4106_gcm_setkey,
349992c60cefSPascal van Leeuwen 		.setauthsize = safexcel_rfc4543_gcm_setauthsize,
350092c60cefSPascal van Leeuwen 		.encrypt = safexcel_rfc4106_encrypt,
350192c60cefSPascal van Leeuwen 		.decrypt = safexcel_rfc4106_decrypt,
350292c60cefSPascal van Leeuwen 		.ivsize = GCM_RFC4543_IV_SIZE,
350392c60cefSPascal van Leeuwen 		.maxauthsize = GHASH_DIGEST_SIZE,
350492c60cefSPascal van Leeuwen 		.base = {
350592c60cefSPascal van Leeuwen 			.cra_name = "rfc4543(gcm(aes))",
350692c60cefSPascal van Leeuwen 			.cra_driver_name = "safexcel-rfc4543-gcm-aes",
350792c60cefSPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
350892c60cefSPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
3509b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
351092c60cefSPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
351192c60cefSPascal van Leeuwen 			.cra_blocksize = 1,
351292c60cefSPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
351392c60cefSPascal van Leeuwen 			.cra_alignmask = 0,
351492c60cefSPascal van Leeuwen 			.cra_init = safexcel_rfc4543_gcm_cra_init,
351592c60cefSPascal van Leeuwen 			.cra_exit = safexcel_aead_gcm_cra_exit,
351692c60cefSPascal van Leeuwen 		},
351792c60cefSPascal van Leeuwen 	},
351892c60cefSPascal van Leeuwen };
3519a9a89624SPascal van Leeuwen 
safexcel_rfc4309_ccm_setkey(struct crypto_aead * ctfm,const u8 * key,unsigned int len)3520a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_setkey(struct crypto_aead *ctfm, const u8 *key,
3521a9a89624SPascal van Leeuwen 				       unsigned int len)
3522a9a89624SPascal van Leeuwen {
3523a9a89624SPascal van Leeuwen 	struct crypto_tfm *tfm = crypto_aead_tfm(ctfm);
3524a9a89624SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
3525a9a89624SPascal van Leeuwen 
3526a9a89624SPascal van Leeuwen 	/* First byte of the nonce = L = always 3 for RFC4309 (4 byte ctr) */
3527a9a89624SPascal van Leeuwen 	*(u8 *)&ctx->nonce = EIP197_AEAD_IPSEC_COUNTER_SIZE - 1;
3528a9a89624SPascal van Leeuwen 	/* last 3 bytes of key are the nonce! */
3529a9a89624SPascal van Leeuwen 	memcpy((u8 *)&ctx->nonce + 1, key + len -
3530a9a89624SPascal van Leeuwen 	       EIP197_AEAD_IPSEC_CCM_NONCE_SIZE,
3531a9a89624SPascal van Leeuwen 	       EIP197_AEAD_IPSEC_CCM_NONCE_SIZE);
3532a9a89624SPascal van Leeuwen 
3533a9a89624SPascal van Leeuwen 	len -= EIP197_AEAD_IPSEC_CCM_NONCE_SIZE;
3534a9a89624SPascal van Leeuwen 	return safexcel_aead_ccm_setkey(ctfm, key, len);
3535a9a89624SPascal van Leeuwen }
3536a9a89624SPascal van Leeuwen 
safexcel_rfc4309_ccm_setauthsize(struct crypto_aead * tfm,unsigned int authsize)3537a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_setauthsize(struct crypto_aead *tfm,
3538a9a89624SPascal van Leeuwen 					    unsigned int authsize)
3539a9a89624SPascal van Leeuwen {
3540a9a89624SPascal van Leeuwen 	/* Borrowed from crypto/ccm.c */
3541a9a89624SPascal van Leeuwen 	switch (authsize) {
3542a9a89624SPascal van Leeuwen 	case 8:
3543a9a89624SPascal van Leeuwen 	case 12:
3544a9a89624SPascal van Leeuwen 	case 16:
3545a9a89624SPascal van Leeuwen 		break;
3546a9a89624SPascal van Leeuwen 	default:
3547a9a89624SPascal van Leeuwen 		return -EINVAL;
3548a9a89624SPascal van Leeuwen 	}
3549a9a89624SPascal van Leeuwen 
3550a9a89624SPascal van Leeuwen 	return 0;
3551a9a89624SPascal van Leeuwen }
3552a9a89624SPascal van Leeuwen 
safexcel_rfc4309_ccm_encrypt(struct aead_request * req)3553a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_encrypt(struct aead_request *req)
3554a9a89624SPascal van Leeuwen {
3555a9a89624SPascal van Leeuwen 	struct safexcel_cipher_req *creq = aead_request_ctx(req);
3556a9a89624SPascal van Leeuwen 
3557a9a89624SPascal van Leeuwen 	/* Borrowed from crypto/ccm.c */
3558a9a89624SPascal van Leeuwen 	if (req->assoclen != 16 && req->assoclen != 20)
3559a9a89624SPascal van Leeuwen 		return -EINVAL;
3560a9a89624SPascal van Leeuwen 
3561a9a89624SPascal van Leeuwen 	return safexcel_queue_req(&req->base, creq, SAFEXCEL_ENCRYPT);
3562a9a89624SPascal van Leeuwen }
3563a9a89624SPascal van Leeuwen 
safexcel_rfc4309_ccm_decrypt(struct aead_request * req)3564a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_decrypt(struct aead_request *req)
3565a9a89624SPascal van Leeuwen {
3566a9a89624SPascal van Leeuwen 	struct safexcel_cipher_req *creq = aead_request_ctx(req);
3567a9a89624SPascal van Leeuwen 
3568a9a89624SPascal van Leeuwen 	/* Borrowed from crypto/ccm.c */
3569a9a89624SPascal van Leeuwen 	if (req->assoclen != 16 && req->assoclen != 20)
3570a9a89624SPascal van Leeuwen 		return -EINVAL;
3571a9a89624SPascal van Leeuwen 
3572a9a89624SPascal van Leeuwen 	return safexcel_queue_req(&req->base, creq, SAFEXCEL_DECRYPT);
3573a9a89624SPascal van Leeuwen }
3574a9a89624SPascal van Leeuwen 
safexcel_rfc4309_ccm_cra_init(struct crypto_tfm * tfm)3575a9a89624SPascal van Leeuwen static int safexcel_rfc4309_ccm_cra_init(struct crypto_tfm *tfm)
3576a9a89624SPascal van Leeuwen {
3577a9a89624SPascal van Leeuwen 	struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm);
3578a9a89624SPascal van Leeuwen 	int ret;
3579a9a89624SPascal van Leeuwen 
3580a9a89624SPascal van Leeuwen 	ret = safexcel_aead_ccm_cra_init(tfm);
3581a9a89624SPascal van Leeuwen 	ctx->aead  = EIP197_AEAD_TYPE_IPSEC_ESP;
3582098e51e5SPascal van Leeuwen 	ctx->aadskip = EIP197_AEAD_IPSEC_IV_SIZE;
3583a9a89624SPascal van Leeuwen 	return ret;
3584a9a89624SPascal van Leeuwen }
3585a9a89624SPascal van Leeuwen 
3586a9a89624SPascal van Leeuwen struct safexcel_alg_template safexcel_alg_rfc4309_ccm = {
3587a9a89624SPascal van Leeuwen 	.type = SAFEXCEL_ALG_TYPE_AEAD,
3588a9a89624SPascal van Leeuwen 	.algo_mask = SAFEXCEL_ALG_AES | SAFEXCEL_ALG_CBC_MAC_ALL,
3589a9a89624SPascal van Leeuwen 	.alg.aead = {
3590a9a89624SPascal van Leeuwen 		.setkey = safexcel_rfc4309_ccm_setkey,
3591a9a89624SPascal van Leeuwen 		.setauthsize = safexcel_rfc4309_ccm_setauthsize,
3592a9a89624SPascal van Leeuwen 		.encrypt = safexcel_rfc4309_ccm_encrypt,
3593a9a89624SPascal van Leeuwen 		.decrypt = safexcel_rfc4309_ccm_decrypt,
3594a9a89624SPascal van Leeuwen 		.ivsize = EIP197_AEAD_IPSEC_IV_SIZE,
3595a9a89624SPascal van Leeuwen 		.maxauthsize = AES_BLOCK_SIZE,
3596a9a89624SPascal van Leeuwen 		.base = {
3597a9a89624SPascal van Leeuwen 			.cra_name = "rfc4309(ccm(aes))",
3598a9a89624SPascal van Leeuwen 			.cra_driver_name = "safexcel-rfc4309-ccm-aes",
3599a9a89624SPascal van Leeuwen 			.cra_priority = SAFEXCEL_CRA_PRIORITY,
3600a9a89624SPascal van Leeuwen 			.cra_flags = CRYPTO_ALG_ASYNC |
3601b8aa7dc5SMikulas Patocka 				     CRYPTO_ALG_ALLOCATES_MEMORY |
3602a9a89624SPascal van Leeuwen 				     CRYPTO_ALG_KERN_DRIVER_ONLY,
3603a9a89624SPascal van Leeuwen 			.cra_blocksize = 1,
3604a9a89624SPascal van Leeuwen 			.cra_ctxsize = sizeof(struct safexcel_cipher_ctx),
3605a9a89624SPascal van Leeuwen 			.cra_alignmask = 0,
3606a9a89624SPascal van Leeuwen 			.cra_init = safexcel_rfc4309_ccm_cra_init,
3607a9a89624SPascal van Leeuwen 			.cra_exit = safexcel_aead_cra_exit,
3608a9a89624SPascal van Leeuwen 			.cra_module = THIS_MODULE,
3609a9a89624SPascal van Leeuwen 		},
3610a9a89624SPascal van Leeuwen 	},
3611a9a89624SPascal van Leeuwen };
3612