xref: /OK3568_Linux_fs/kernel/drivers/crypto/caam/caamalg.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * caam - Freescale FSL CAAM support for crypto API
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright 2008-2011 Freescale Semiconductor, Inc.
6*4882a593Smuzhiyun  * Copyright 2016-2019 NXP
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * Based on talitos crypto API driver.
9*4882a593Smuzhiyun  *
10*4882a593Smuzhiyun  * relationship of job descriptors to shared descriptors (SteveC Dec 10 2008):
11*4882a593Smuzhiyun  *
12*4882a593Smuzhiyun  * ---------------                     ---------------
13*4882a593Smuzhiyun  * | JobDesc #1  |-------------------->|  ShareDesc  |
14*4882a593Smuzhiyun  * | *(packet 1) |                     |   (PDB)     |
15*4882a593Smuzhiyun  * ---------------      |------------->|  (hashKey)  |
16*4882a593Smuzhiyun  *       .              |              | (cipherKey) |
17*4882a593Smuzhiyun  *       .              |    |-------->| (operation) |
18*4882a593Smuzhiyun  * ---------------      |    |         ---------------
19*4882a593Smuzhiyun  * | JobDesc #2  |------|    |
20*4882a593Smuzhiyun  * | *(packet 2) |           |
21*4882a593Smuzhiyun  * ---------------           |
22*4882a593Smuzhiyun  *       .                   |
23*4882a593Smuzhiyun  *       .                   |
24*4882a593Smuzhiyun  * ---------------           |
25*4882a593Smuzhiyun  * | JobDesc #3  |------------
26*4882a593Smuzhiyun  * | *(packet 3) |
27*4882a593Smuzhiyun  * ---------------
28*4882a593Smuzhiyun  *
29*4882a593Smuzhiyun  * The SharedDesc never changes for a connection unless rekeyed, but
30*4882a593Smuzhiyun  * each packet will likely be in a different place. So all we need
31*4882a593Smuzhiyun  * to know to process the packet is where the input is, where the
32*4882a593Smuzhiyun  * output goes, and what context we want to process with. Context is
33*4882a593Smuzhiyun  * in the SharedDesc, packet references in the JobDesc.
34*4882a593Smuzhiyun  *
35*4882a593Smuzhiyun  * So, a job desc looks like:
36*4882a593Smuzhiyun  *
37*4882a593Smuzhiyun  * ---------------------
38*4882a593Smuzhiyun  * | Header            |
39*4882a593Smuzhiyun  * | ShareDesc Pointer |
40*4882a593Smuzhiyun  * | SEQ_OUT_PTR       |
41*4882a593Smuzhiyun  * | (output buffer)   |
42*4882a593Smuzhiyun  * | (output length)   |
43*4882a593Smuzhiyun  * | SEQ_IN_PTR        |
44*4882a593Smuzhiyun  * | (input buffer)    |
45*4882a593Smuzhiyun  * | (input length)    |
46*4882a593Smuzhiyun  * ---------------------
47*4882a593Smuzhiyun  */
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun #include "compat.h"
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun #include "regs.h"
52*4882a593Smuzhiyun #include "intern.h"
53*4882a593Smuzhiyun #include "desc_constr.h"
54*4882a593Smuzhiyun #include "jr.h"
55*4882a593Smuzhiyun #include "error.h"
56*4882a593Smuzhiyun #include "sg_sw_sec4.h"
57*4882a593Smuzhiyun #include "key_gen.h"
58*4882a593Smuzhiyun #include "caamalg_desc.h"
59*4882a593Smuzhiyun #include <crypto/engine.h>
60*4882a593Smuzhiyun #include <crypto/xts.h>
61*4882a593Smuzhiyun #include <asm/unaligned.h>
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun /*
64*4882a593Smuzhiyun  * crypto alg
65*4882a593Smuzhiyun  */
66*4882a593Smuzhiyun #define CAAM_CRA_PRIORITY		3000
67*4882a593Smuzhiyun /* max key is sum of AES_MAX_KEY_SIZE, max split key size */
68*4882a593Smuzhiyun #define CAAM_MAX_KEY_SIZE		(AES_MAX_KEY_SIZE + \
69*4882a593Smuzhiyun 					 CTR_RFC3686_NONCE_SIZE + \
70*4882a593Smuzhiyun 					 SHA512_DIGEST_SIZE * 2)
71*4882a593Smuzhiyun 
72*4882a593Smuzhiyun #define AEAD_DESC_JOB_IO_LEN		(DESC_JOB_IO_LEN + CAAM_CMD_SZ * 2)
73*4882a593Smuzhiyun #define GCM_DESC_JOB_IO_LEN		(AEAD_DESC_JOB_IO_LEN + \
74*4882a593Smuzhiyun 					 CAAM_CMD_SZ * 4)
75*4882a593Smuzhiyun #define AUTHENC_DESC_JOB_IO_LEN		(AEAD_DESC_JOB_IO_LEN + \
76*4882a593Smuzhiyun 					 CAAM_CMD_SZ * 5)
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun #define CHACHAPOLY_DESC_JOB_IO_LEN	(AEAD_DESC_JOB_IO_LEN + CAAM_CMD_SZ * 6)
79*4882a593Smuzhiyun 
80*4882a593Smuzhiyun #define DESC_MAX_USED_BYTES		(CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN_MIN)
81*4882a593Smuzhiyun #define DESC_MAX_USED_LEN		(DESC_MAX_USED_BYTES / CAAM_CMD_SZ)
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun struct caam_alg_entry {
84*4882a593Smuzhiyun 	int class1_alg_type;
85*4882a593Smuzhiyun 	int class2_alg_type;
86*4882a593Smuzhiyun 	bool rfc3686;
87*4882a593Smuzhiyun 	bool geniv;
88*4882a593Smuzhiyun 	bool nodkp;
89*4882a593Smuzhiyun };
90*4882a593Smuzhiyun 
91*4882a593Smuzhiyun struct caam_aead_alg {
92*4882a593Smuzhiyun 	struct aead_alg aead;
93*4882a593Smuzhiyun 	struct caam_alg_entry caam;
94*4882a593Smuzhiyun 	bool registered;
95*4882a593Smuzhiyun };
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun struct caam_skcipher_alg {
98*4882a593Smuzhiyun 	struct skcipher_alg skcipher;
99*4882a593Smuzhiyun 	struct caam_alg_entry caam;
100*4882a593Smuzhiyun 	bool registered;
101*4882a593Smuzhiyun };
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun /*
104*4882a593Smuzhiyun  * per-session context
105*4882a593Smuzhiyun  */
106*4882a593Smuzhiyun struct caam_ctx {
107*4882a593Smuzhiyun 	struct crypto_engine_ctx enginectx;
108*4882a593Smuzhiyun 	u32 sh_desc_enc[DESC_MAX_USED_LEN];
109*4882a593Smuzhiyun 	u32 sh_desc_dec[DESC_MAX_USED_LEN];
110*4882a593Smuzhiyun 	u8 key[CAAM_MAX_KEY_SIZE];
111*4882a593Smuzhiyun 	dma_addr_t sh_desc_enc_dma;
112*4882a593Smuzhiyun 	dma_addr_t sh_desc_dec_dma;
113*4882a593Smuzhiyun 	dma_addr_t key_dma;
114*4882a593Smuzhiyun 	enum dma_data_direction dir;
115*4882a593Smuzhiyun 	struct device *jrdev;
116*4882a593Smuzhiyun 	struct alginfo adata;
117*4882a593Smuzhiyun 	struct alginfo cdata;
118*4882a593Smuzhiyun 	unsigned int authsize;
119*4882a593Smuzhiyun 	bool xts_key_fallback;
120*4882a593Smuzhiyun 	struct crypto_skcipher *fallback;
121*4882a593Smuzhiyun };
122*4882a593Smuzhiyun 
123*4882a593Smuzhiyun struct caam_skcipher_req_ctx {
124*4882a593Smuzhiyun 	struct skcipher_edesc *edesc;
125*4882a593Smuzhiyun 	struct skcipher_request fallback_req;
126*4882a593Smuzhiyun };
127*4882a593Smuzhiyun 
128*4882a593Smuzhiyun struct caam_aead_req_ctx {
129*4882a593Smuzhiyun 	struct aead_edesc *edesc;
130*4882a593Smuzhiyun };
131*4882a593Smuzhiyun 
aead_null_set_sh_desc(struct crypto_aead * aead)132*4882a593Smuzhiyun static int aead_null_set_sh_desc(struct crypto_aead *aead)
133*4882a593Smuzhiyun {
134*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
135*4882a593Smuzhiyun 	struct device *jrdev = ctx->jrdev;
136*4882a593Smuzhiyun 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
137*4882a593Smuzhiyun 	u32 *desc;
138*4882a593Smuzhiyun 	int rem_bytes = CAAM_DESC_BYTES_MAX - AEAD_DESC_JOB_IO_LEN -
139*4882a593Smuzhiyun 			ctx->adata.keylen_pad;
140*4882a593Smuzhiyun 
141*4882a593Smuzhiyun 	/*
142*4882a593Smuzhiyun 	 * Job Descriptor and Shared Descriptors
143*4882a593Smuzhiyun 	 * must all fit into the 64-word Descriptor h/w Buffer
144*4882a593Smuzhiyun 	 */
145*4882a593Smuzhiyun 	if (rem_bytes >= DESC_AEAD_NULL_ENC_LEN) {
146*4882a593Smuzhiyun 		ctx->adata.key_inline = true;
147*4882a593Smuzhiyun 		ctx->adata.key_virt = ctx->key;
148*4882a593Smuzhiyun 	} else {
149*4882a593Smuzhiyun 		ctx->adata.key_inline = false;
150*4882a593Smuzhiyun 		ctx->adata.key_dma = ctx->key_dma;
151*4882a593Smuzhiyun 	}
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	/* aead_encrypt shared descriptor */
154*4882a593Smuzhiyun 	desc = ctx->sh_desc_enc;
155*4882a593Smuzhiyun 	cnstr_shdsc_aead_null_encap(desc, &ctx->adata, ctx->authsize,
156*4882a593Smuzhiyun 				    ctrlpriv->era);
157*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
158*4882a593Smuzhiyun 				   desc_bytes(desc), ctx->dir);
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 	/*
161*4882a593Smuzhiyun 	 * Job Descriptor and Shared Descriptors
162*4882a593Smuzhiyun 	 * must all fit into the 64-word Descriptor h/w Buffer
163*4882a593Smuzhiyun 	 */
164*4882a593Smuzhiyun 	if (rem_bytes >= DESC_AEAD_NULL_DEC_LEN) {
165*4882a593Smuzhiyun 		ctx->adata.key_inline = true;
166*4882a593Smuzhiyun 		ctx->adata.key_virt = ctx->key;
167*4882a593Smuzhiyun 	} else {
168*4882a593Smuzhiyun 		ctx->adata.key_inline = false;
169*4882a593Smuzhiyun 		ctx->adata.key_dma = ctx->key_dma;
170*4882a593Smuzhiyun 	}
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	/* aead_decrypt shared descriptor */
173*4882a593Smuzhiyun 	desc = ctx->sh_desc_dec;
174*4882a593Smuzhiyun 	cnstr_shdsc_aead_null_decap(desc, &ctx->adata, ctx->authsize,
175*4882a593Smuzhiyun 				    ctrlpriv->era);
176*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
177*4882a593Smuzhiyun 				   desc_bytes(desc), ctx->dir);
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 	return 0;
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun 
aead_set_sh_desc(struct crypto_aead * aead)182*4882a593Smuzhiyun static int aead_set_sh_desc(struct crypto_aead *aead)
183*4882a593Smuzhiyun {
184*4882a593Smuzhiyun 	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
185*4882a593Smuzhiyun 						 struct caam_aead_alg, aead);
186*4882a593Smuzhiyun 	unsigned int ivsize = crypto_aead_ivsize(aead);
187*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
188*4882a593Smuzhiyun 	struct device *jrdev = ctx->jrdev;
189*4882a593Smuzhiyun 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
190*4882a593Smuzhiyun 	u32 ctx1_iv_off = 0;
191*4882a593Smuzhiyun 	u32 *desc, *nonce = NULL;
192*4882a593Smuzhiyun 	u32 inl_mask;
193*4882a593Smuzhiyun 	unsigned int data_len[2];
194*4882a593Smuzhiyun 	const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
195*4882a593Smuzhiyun 			       OP_ALG_AAI_CTR_MOD128);
196*4882a593Smuzhiyun 	const bool is_rfc3686 = alg->caam.rfc3686;
197*4882a593Smuzhiyun 
198*4882a593Smuzhiyun 	if (!ctx->authsize)
199*4882a593Smuzhiyun 		return 0;
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 	/* NULL encryption / decryption */
202*4882a593Smuzhiyun 	if (!ctx->cdata.keylen)
203*4882a593Smuzhiyun 		return aead_null_set_sh_desc(aead);
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun 	/*
206*4882a593Smuzhiyun 	 * AES-CTR needs to load IV in CONTEXT1 reg
207*4882a593Smuzhiyun 	 * at an offset of 128bits (16bytes)
208*4882a593Smuzhiyun 	 * CONTEXT1[255:128] = IV
209*4882a593Smuzhiyun 	 */
210*4882a593Smuzhiyun 	if (ctr_mode)
211*4882a593Smuzhiyun 		ctx1_iv_off = 16;
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	/*
214*4882a593Smuzhiyun 	 * RFC3686 specific:
215*4882a593Smuzhiyun 	 *	CONTEXT1[255:128] = {NONCE, IV, COUNTER}
216*4882a593Smuzhiyun 	 */
217*4882a593Smuzhiyun 	if (is_rfc3686) {
218*4882a593Smuzhiyun 		ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
219*4882a593Smuzhiyun 		nonce = (u32 *)((void *)ctx->key + ctx->adata.keylen_pad +
220*4882a593Smuzhiyun 				ctx->cdata.keylen - CTR_RFC3686_NONCE_SIZE);
221*4882a593Smuzhiyun 	}
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun 	/*
224*4882a593Smuzhiyun 	 * In case |user key| > |derived key|, using DKP<imm,imm>
225*4882a593Smuzhiyun 	 * would result in invalid opcodes (last bytes of user key) in
226*4882a593Smuzhiyun 	 * the resulting descriptor. Use DKP<ptr,imm> instead => both
227*4882a593Smuzhiyun 	 * virtual and dma key addresses are needed.
228*4882a593Smuzhiyun 	 */
229*4882a593Smuzhiyun 	ctx->adata.key_virt = ctx->key;
230*4882a593Smuzhiyun 	ctx->adata.key_dma = ctx->key_dma;
231*4882a593Smuzhiyun 
232*4882a593Smuzhiyun 	ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
233*4882a593Smuzhiyun 	ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun 	data_len[0] = ctx->adata.keylen_pad;
236*4882a593Smuzhiyun 	data_len[1] = ctx->cdata.keylen;
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun 	if (alg->caam.geniv)
239*4882a593Smuzhiyun 		goto skip_enc;
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 	/*
242*4882a593Smuzhiyun 	 * Job Descriptor and Shared Descriptors
243*4882a593Smuzhiyun 	 * must all fit into the 64-word Descriptor h/w Buffer
244*4882a593Smuzhiyun 	 */
245*4882a593Smuzhiyun 	if (desc_inline_query(DESC_AEAD_ENC_LEN +
246*4882a593Smuzhiyun 			      (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
247*4882a593Smuzhiyun 			      AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
248*4882a593Smuzhiyun 			      ARRAY_SIZE(data_len)) < 0)
249*4882a593Smuzhiyun 		return -EINVAL;
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun 	ctx->adata.key_inline = !!(inl_mask & 1);
252*4882a593Smuzhiyun 	ctx->cdata.key_inline = !!(inl_mask & 2);
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	/* aead_encrypt shared descriptor */
255*4882a593Smuzhiyun 	desc = ctx->sh_desc_enc;
256*4882a593Smuzhiyun 	cnstr_shdsc_aead_encap(desc, &ctx->cdata, &ctx->adata, ivsize,
257*4882a593Smuzhiyun 			       ctx->authsize, is_rfc3686, nonce, ctx1_iv_off,
258*4882a593Smuzhiyun 			       false, ctrlpriv->era);
259*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
260*4882a593Smuzhiyun 				   desc_bytes(desc), ctx->dir);
261*4882a593Smuzhiyun 
262*4882a593Smuzhiyun skip_enc:
263*4882a593Smuzhiyun 	/*
264*4882a593Smuzhiyun 	 * Job Descriptor and Shared Descriptors
265*4882a593Smuzhiyun 	 * must all fit into the 64-word Descriptor h/w Buffer
266*4882a593Smuzhiyun 	 */
267*4882a593Smuzhiyun 	if (desc_inline_query(DESC_AEAD_DEC_LEN +
268*4882a593Smuzhiyun 			      (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
269*4882a593Smuzhiyun 			      AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
270*4882a593Smuzhiyun 			      ARRAY_SIZE(data_len)) < 0)
271*4882a593Smuzhiyun 		return -EINVAL;
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun 	ctx->adata.key_inline = !!(inl_mask & 1);
274*4882a593Smuzhiyun 	ctx->cdata.key_inline = !!(inl_mask & 2);
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun 	/* aead_decrypt shared descriptor */
277*4882a593Smuzhiyun 	desc = ctx->sh_desc_dec;
278*4882a593Smuzhiyun 	cnstr_shdsc_aead_decap(desc, &ctx->cdata, &ctx->adata, ivsize,
279*4882a593Smuzhiyun 			       ctx->authsize, alg->caam.geniv, is_rfc3686,
280*4882a593Smuzhiyun 			       nonce, ctx1_iv_off, false, ctrlpriv->era);
281*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
282*4882a593Smuzhiyun 				   desc_bytes(desc), ctx->dir);
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun 	if (!alg->caam.geniv)
285*4882a593Smuzhiyun 		goto skip_givenc;
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun 	/*
288*4882a593Smuzhiyun 	 * Job Descriptor and Shared Descriptors
289*4882a593Smuzhiyun 	 * must all fit into the 64-word Descriptor h/w Buffer
290*4882a593Smuzhiyun 	 */
291*4882a593Smuzhiyun 	if (desc_inline_query(DESC_AEAD_GIVENC_LEN +
292*4882a593Smuzhiyun 			      (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
293*4882a593Smuzhiyun 			      AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
294*4882a593Smuzhiyun 			      ARRAY_SIZE(data_len)) < 0)
295*4882a593Smuzhiyun 		return -EINVAL;
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun 	ctx->adata.key_inline = !!(inl_mask & 1);
298*4882a593Smuzhiyun 	ctx->cdata.key_inline = !!(inl_mask & 2);
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 	/* aead_givencrypt shared descriptor */
301*4882a593Smuzhiyun 	desc = ctx->sh_desc_enc;
302*4882a593Smuzhiyun 	cnstr_shdsc_aead_givencap(desc, &ctx->cdata, &ctx->adata, ivsize,
303*4882a593Smuzhiyun 				  ctx->authsize, is_rfc3686, nonce,
304*4882a593Smuzhiyun 				  ctx1_iv_off, false, ctrlpriv->era);
305*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
306*4882a593Smuzhiyun 				   desc_bytes(desc), ctx->dir);
307*4882a593Smuzhiyun 
308*4882a593Smuzhiyun skip_givenc:
309*4882a593Smuzhiyun 	return 0;
310*4882a593Smuzhiyun }
311*4882a593Smuzhiyun 
aead_setauthsize(struct crypto_aead * authenc,unsigned int authsize)312*4882a593Smuzhiyun static int aead_setauthsize(struct crypto_aead *authenc,
313*4882a593Smuzhiyun 				    unsigned int authsize)
314*4882a593Smuzhiyun {
315*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 	ctx->authsize = authsize;
318*4882a593Smuzhiyun 	aead_set_sh_desc(authenc);
319*4882a593Smuzhiyun 
320*4882a593Smuzhiyun 	return 0;
321*4882a593Smuzhiyun }
322*4882a593Smuzhiyun 
gcm_set_sh_desc(struct crypto_aead * aead)323*4882a593Smuzhiyun static int gcm_set_sh_desc(struct crypto_aead *aead)
324*4882a593Smuzhiyun {
325*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
326*4882a593Smuzhiyun 	struct device *jrdev = ctx->jrdev;
327*4882a593Smuzhiyun 	unsigned int ivsize = crypto_aead_ivsize(aead);
328*4882a593Smuzhiyun 	u32 *desc;
329*4882a593Smuzhiyun 	int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
330*4882a593Smuzhiyun 			ctx->cdata.keylen;
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun 	if (!ctx->cdata.keylen || !ctx->authsize)
333*4882a593Smuzhiyun 		return 0;
334*4882a593Smuzhiyun 
335*4882a593Smuzhiyun 	/*
336*4882a593Smuzhiyun 	 * AES GCM encrypt shared descriptor
337*4882a593Smuzhiyun 	 * Job Descriptor and Shared Descriptor
338*4882a593Smuzhiyun 	 * must fit into the 64-word Descriptor h/w Buffer
339*4882a593Smuzhiyun 	 */
340*4882a593Smuzhiyun 	if (rem_bytes >= DESC_GCM_ENC_LEN) {
341*4882a593Smuzhiyun 		ctx->cdata.key_inline = true;
342*4882a593Smuzhiyun 		ctx->cdata.key_virt = ctx->key;
343*4882a593Smuzhiyun 	} else {
344*4882a593Smuzhiyun 		ctx->cdata.key_inline = false;
345*4882a593Smuzhiyun 		ctx->cdata.key_dma = ctx->key_dma;
346*4882a593Smuzhiyun 	}
347*4882a593Smuzhiyun 
348*4882a593Smuzhiyun 	desc = ctx->sh_desc_enc;
349*4882a593Smuzhiyun 	cnstr_shdsc_gcm_encap(desc, &ctx->cdata, ivsize, ctx->authsize, false);
350*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
351*4882a593Smuzhiyun 				   desc_bytes(desc), ctx->dir);
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun 	/*
354*4882a593Smuzhiyun 	 * Job Descriptor and Shared Descriptors
355*4882a593Smuzhiyun 	 * must all fit into the 64-word Descriptor h/w Buffer
356*4882a593Smuzhiyun 	 */
357*4882a593Smuzhiyun 	if (rem_bytes >= DESC_GCM_DEC_LEN) {
358*4882a593Smuzhiyun 		ctx->cdata.key_inline = true;
359*4882a593Smuzhiyun 		ctx->cdata.key_virt = ctx->key;
360*4882a593Smuzhiyun 	} else {
361*4882a593Smuzhiyun 		ctx->cdata.key_inline = false;
362*4882a593Smuzhiyun 		ctx->cdata.key_dma = ctx->key_dma;
363*4882a593Smuzhiyun 	}
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun 	desc = ctx->sh_desc_dec;
366*4882a593Smuzhiyun 	cnstr_shdsc_gcm_decap(desc, &ctx->cdata, ivsize, ctx->authsize, false);
367*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
368*4882a593Smuzhiyun 				   desc_bytes(desc), ctx->dir);
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun 	return 0;
371*4882a593Smuzhiyun }
372*4882a593Smuzhiyun 
gcm_setauthsize(struct crypto_aead * authenc,unsigned int authsize)373*4882a593Smuzhiyun static int gcm_setauthsize(struct crypto_aead *authenc, unsigned int authsize)
374*4882a593Smuzhiyun {
375*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
376*4882a593Smuzhiyun 	int err;
377*4882a593Smuzhiyun 
378*4882a593Smuzhiyun 	err = crypto_gcm_check_authsize(authsize);
379*4882a593Smuzhiyun 	if (err)
380*4882a593Smuzhiyun 		return err;
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun 	ctx->authsize = authsize;
383*4882a593Smuzhiyun 	gcm_set_sh_desc(authenc);
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun 	return 0;
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun 
rfc4106_set_sh_desc(struct crypto_aead * aead)388*4882a593Smuzhiyun static int rfc4106_set_sh_desc(struct crypto_aead *aead)
389*4882a593Smuzhiyun {
390*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
391*4882a593Smuzhiyun 	struct device *jrdev = ctx->jrdev;
392*4882a593Smuzhiyun 	unsigned int ivsize = crypto_aead_ivsize(aead);
393*4882a593Smuzhiyun 	u32 *desc;
394*4882a593Smuzhiyun 	int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
395*4882a593Smuzhiyun 			ctx->cdata.keylen;
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun 	if (!ctx->cdata.keylen || !ctx->authsize)
398*4882a593Smuzhiyun 		return 0;
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 	/*
401*4882a593Smuzhiyun 	 * RFC4106 encrypt shared descriptor
402*4882a593Smuzhiyun 	 * Job Descriptor and Shared Descriptor
403*4882a593Smuzhiyun 	 * must fit into the 64-word Descriptor h/w Buffer
404*4882a593Smuzhiyun 	 */
405*4882a593Smuzhiyun 	if (rem_bytes >= DESC_RFC4106_ENC_LEN) {
406*4882a593Smuzhiyun 		ctx->cdata.key_inline = true;
407*4882a593Smuzhiyun 		ctx->cdata.key_virt = ctx->key;
408*4882a593Smuzhiyun 	} else {
409*4882a593Smuzhiyun 		ctx->cdata.key_inline = false;
410*4882a593Smuzhiyun 		ctx->cdata.key_dma = ctx->key_dma;
411*4882a593Smuzhiyun 	}
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun 	desc = ctx->sh_desc_enc;
414*4882a593Smuzhiyun 	cnstr_shdsc_rfc4106_encap(desc, &ctx->cdata, ivsize, ctx->authsize,
415*4882a593Smuzhiyun 				  false);
416*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
417*4882a593Smuzhiyun 				   desc_bytes(desc), ctx->dir);
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun 	/*
420*4882a593Smuzhiyun 	 * Job Descriptor and Shared Descriptors
421*4882a593Smuzhiyun 	 * must all fit into the 64-word Descriptor h/w Buffer
422*4882a593Smuzhiyun 	 */
423*4882a593Smuzhiyun 	if (rem_bytes >= DESC_RFC4106_DEC_LEN) {
424*4882a593Smuzhiyun 		ctx->cdata.key_inline = true;
425*4882a593Smuzhiyun 		ctx->cdata.key_virt = ctx->key;
426*4882a593Smuzhiyun 	} else {
427*4882a593Smuzhiyun 		ctx->cdata.key_inline = false;
428*4882a593Smuzhiyun 		ctx->cdata.key_dma = ctx->key_dma;
429*4882a593Smuzhiyun 	}
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun 	desc = ctx->sh_desc_dec;
432*4882a593Smuzhiyun 	cnstr_shdsc_rfc4106_decap(desc, &ctx->cdata, ivsize, ctx->authsize,
433*4882a593Smuzhiyun 				  false);
434*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
435*4882a593Smuzhiyun 				   desc_bytes(desc), ctx->dir);
436*4882a593Smuzhiyun 
437*4882a593Smuzhiyun 	return 0;
438*4882a593Smuzhiyun }
439*4882a593Smuzhiyun 
rfc4106_setauthsize(struct crypto_aead * authenc,unsigned int authsize)440*4882a593Smuzhiyun static int rfc4106_setauthsize(struct crypto_aead *authenc,
441*4882a593Smuzhiyun 			       unsigned int authsize)
442*4882a593Smuzhiyun {
443*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
444*4882a593Smuzhiyun 	int err;
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 	err = crypto_rfc4106_check_authsize(authsize);
447*4882a593Smuzhiyun 	if (err)
448*4882a593Smuzhiyun 		return err;
449*4882a593Smuzhiyun 
450*4882a593Smuzhiyun 	ctx->authsize = authsize;
451*4882a593Smuzhiyun 	rfc4106_set_sh_desc(authenc);
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun 	return 0;
454*4882a593Smuzhiyun }
455*4882a593Smuzhiyun 
rfc4543_set_sh_desc(struct crypto_aead * aead)456*4882a593Smuzhiyun static int rfc4543_set_sh_desc(struct crypto_aead *aead)
457*4882a593Smuzhiyun {
458*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
459*4882a593Smuzhiyun 	struct device *jrdev = ctx->jrdev;
460*4882a593Smuzhiyun 	unsigned int ivsize = crypto_aead_ivsize(aead);
461*4882a593Smuzhiyun 	u32 *desc;
462*4882a593Smuzhiyun 	int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
463*4882a593Smuzhiyun 			ctx->cdata.keylen;
464*4882a593Smuzhiyun 
465*4882a593Smuzhiyun 	if (!ctx->cdata.keylen || !ctx->authsize)
466*4882a593Smuzhiyun 		return 0;
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun 	/*
469*4882a593Smuzhiyun 	 * RFC4543 encrypt shared descriptor
470*4882a593Smuzhiyun 	 * Job Descriptor and Shared Descriptor
471*4882a593Smuzhiyun 	 * must fit into the 64-word Descriptor h/w Buffer
472*4882a593Smuzhiyun 	 */
473*4882a593Smuzhiyun 	if (rem_bytes >= DESC_RFC4543_ENC_LEN) {
474*4882a593Smuzhiyun 		ctx->cdata.key_inline = true;
475*4882a593Smuzhiyun 		ctx->cdata.key_virt = ctx->key;
476*4882a593Smuzhiyun 	} else {
477*4882a593Smuzhiyun 		ctx->cdata.key_inline = false;
478*4882a593Smuzhiyun 		ctx->cdata.key_dma = ctx->key_dma;
479*4882a593Smuzhiyun 	}
480*4882a593Smuzhiyun 
481*4882a593Smuzhiyun 	desc = ctx->sh_desc_enc;
482*4882a593Smuzhiyun 	cnstr_shdsc_rfc4543_encap(desc, &ctx->cdata, ivsize, ctx->authsize,
483*4882a593Smuzhiyun 				  false);
484*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
485*4882a593Smuzhiyun 				   desc_bytes(desc), ctx->dir);
486*4882a593Smuzhiyun 
487*4882a593Smuzhiyun 	/*
488*4882a593Smuzhiyun 	 * Job Descriptor and Shared Descriptors
489*4882a593Smuzhiyun 	 * must all fit into the 64-word Descriptor h/w Buffer
490*4882a593Smuzhiyun 	 */
491*4882a593Smuzhiyun 	if (rem_bytes >= DESC_RFC4543_DEC_LEN) {
492*4882a593Smuzhiyun 		ctx->cdata.key_inline = true;
493*4882a593Smuzhiyun 		ctx->cdata.key_virt = ctx->key;
494*4882a593Smuzhiyun 	} else {
495*4882a593Smuzhiyun 		ctx->cdata.key_inline = false;
496*4882a593Smuzhiyun 		ctx->cdata.key_dma = ctx->key_dma;
497*4882a593Smuzhiyun 	}
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun 	desc = ctx->sh_desc_dec;
500*4882a593Smuzhiyun 	cnstr_shdsc_rfc4543_decap(desc, &ctx->cdata, ivsize, ctx->authsize,
501*4882a593Smuzhiyun 				  false);
502*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
503*4882a593Smuzhiyun 				   desc_bytes(desc), ctx->dir);
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun 	return 0;
506*4882a593Smuzhiyun }
507*4882a593Smuzhiyun 
rfc4543_setauthsize(struct crypto_aead * authenc,unsigned int authsize)508*4882a593Smuzhiyun static int rfc4543_setauthsize(struct crypto_aead *authenc,
509*4882a593Smuzhiyun 			       unsigned int authsize)
510*4882a593Smuzhiyun {
511*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
512*4882a593Smuzhiyun 
513*4882a593Smuzhiyun 	if (authsize != 16)
514*4882a593Smuzhiyun 		return -EINVAL;
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun 	ctx->authsize = authsize;
517*4882a593Smuzhiyun 	rfc4543_set_sh_desc(authenc);
518*4882a593Smuzhiyun 
519*4882a593Smuzhiyun 	return 0;
520*4882a593Smuzhiyun }
521*4882a593Smuzhiyun 
chachapoly_set_sh_desc(struct crypto_aead * aead)522*4882a593Smuzhiyun static int chachapoly_set_sh_desc(struct crypto_aead *aead)
523*4882a593Smuzhiyun {
524*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
525*4882a593Smuzhiyun 	struct device *jrdev = ctx->jrdev;
526*4882a593Smuzhiyun 	unsigned int ivsize = crypto_aead_ivsize(aead);
527*4882a593Smuzhiyun 	u32 *desc;
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun 	if (!ctx->cdata.keylen || !ctx->authsize)
530*4882a593Smuzhiyun 		return 0;
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun 	desc = ctx->sh_desc_enc;
533*4882a593Smuzhiyun 	cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize,
534*4882a593Smuzhiyun 			       ctx->authsize, true, false);
535*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
536*4882a593Smuzhiyun 				   desc_bytes(desc), ctx->dir);
537*4882a593Smuzhiyun 
538*4882a593Smuzhiyun 	desc = ctx->sh_desc_dec;
539*4882a593Smuzhiyun 	cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize,
540*4882a593Smuzhiyun 			       ctx->authsize, false, false);
541*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
542*4882a593Smuzhiyun 				   desc_bytes(desc), ctx->dir);
543*4882a593Smuzhiyun 
544*4882a593Smuzhiyun 	return 0;
545*4882a593Smuzhiyun }
546*4882a593Smuzhiyun 
chachapoly_setauthsize(struct crypto_aead * aead,unsigned int authsize)547*4882a593Smuzhiyun static int chachapoly_setauthsize(struct crypto_aead *aead,
548*4882a593Smuzhiyun 				  unsigned int authsize)
549*4882a593Smuzhiyun {
550*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun 	if (authsize != POLY1305_DIGEST_SIZE)
553*4882a593Smuzhiyun 		return -EINVAL;
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun 	ctx->authsize = authsize;
556*4882a593Smuzhiyun 	return chachapoly_set_sh_desc(aead);
557*4882a593Smuzhiyun }
558*4882a593Smuzhiyun 
chachapoly_setkey(struct crypto_aead * aead,const u8 * key,unsigned int keylen)559*4882a593Smuzhiyun static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key,
560*4882a593Smuzhiyun 			     unsigned int keylen)
561*4882a593Smuzhiyun {
562*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
563*4882a593Smuzhiyun 	unsigned int ivsize = crypto_aead_ivsize(aead);
564*4882a593Smuzhiyun 	unsigned int saltlen = CHACHAPOLY_IV_SIZE - ivsize;
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun 	if (keylen != CHACHA_KEY_SIZE + saltlen)
567*4882a593Smuzhiyun 		return -EINVAL;
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun 	ctx->cdata.key_virt = key;
570*4882a593Smuzhiyun 	ctx->cdata.keylen = keylen - saltlen;
571*4882a593Smuzhiyun 
572*4882a593Smuzhiyun 	return chachapoly_set_sh_desc(aead);
573*4882a593Smuzhiyun }
574*4882a593Smuzhiyun 
aead_setkey(struct crypto_aead * aead,const u8 * key,unsigned int keylen)575*4882a593Smuzhiyun static int aead_setkey(struct crypto_aead *aead,
576*4882a593Smuzhiyun 			       const u8 *key, unsigned int keylen)
577*4882a593Smuzhiyun {
578*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
579*4882a593Smuzhiyun 	struct device *jrdev = ctx->jrdev;
580*4882a593Smuzhiyun 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
581*4882a593Smuzhiyun 	struct crypto_authenc_keys keys;
582*4882a593Smuzhiyun 	int ret = 0;
583*4882a593Smuzhiyun 
584*4882a593Smuzhiyun 	if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
585*4882a593Smuzhiyun 		goto badkey;
586*4882a593Smuzhiyun 
587*4882a593Smuzhiyun 	dev_dbg(jrdev, "keylen %d enckeylen %d authkeylen %d\n",
588*4882a593Smuzhiyun 	       keys.authkeylen + keys.enckeylen, keys.enckeylen,
589*4882a593Smuzhiyun 	       keys.authkeylen);
590*4882a593Smuzhiyun 	print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
591*4882a593Smuzhiyun 			     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
592*4882a593Smuzhiyun 
593*4882a593Smuzhiyun 	/*
594*4882a593Smuzhiyun 	 * If DKP is supported, use it in the shared descriptor to generate
595*4882a593Smuzhiyun 	 * the split key.
596*4882a593Smuzhiyun 	 */
597*4882a593Smuzhiyun 	if (ctrlpriv->era >= 6) {
598*4882a593Smuzhiyun 		ctx->adata.keylen = keys.authkeylen;
599*4882a593Smuzhiyun 		ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype &
600*4882a593Smuzhiyun 						      OP_ALG_ALGSEL_MASK);
601*4882a593Smuzhiyun 
602*4882a593Smuzhiyun 		if (ctx->adata.keylen_pad + keys.enckeylen > CAAM_MAX_KEY_SIZE)
603*4882a593Smuzhiyun 			goto badkey;
604*4882a593Smuzhiyun 
605*4882a593Smuzhiyun 		memcpy(ctx->key, keys.authkey, keys.authkeylen);
606*4882a593Smuzhiyun 		memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey,
607*4882a593Smuzhiyun 		       keys.enckeylen);
608*4882a593Smuzhiyun 		dma_sync_single_for_device(jrdev, ctx->key_dma,
609*4882a593Smuzhiyun 					   ctx->adata.keylen_pad +
610*4882a593Smuzhiyun 					   keys.enckeylen, ctx->dir);
611*4882a593Smuzhiyun 		goto skip_split_key;
612*4882a593Smuzhiyun 	}
613*4882a593Smuzhiyun 
614*4882a593Smuzhiyun 	ret = gen_split_key(ctx->jrdev, ctx->key, &ctx->adata, keys.authkey,
615*4882a593Smuzhiyun 			    keys.authkeylen, CAAM_MAX_KEY_SIZE -
616*4882a593Smuzhiyun 			    keys.enckeylen);
617*4882a593Smuzhiyun 	if (ret) {
618*4882a593Smuzhiyun 		goto badkey;
619*4882a593Smuzhiyun 	}
620*4882a593Smuzhiyun 
621*4882a593Smuzhiyun 	/* postpend encryption key to auth split key */
622*4882a593Smuzhiyun 	memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen);
623*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->adata.keylen_pad +
624*4882a593Smuzhiyun 				   keys.enckeylen, ctx->dir);
625*4882a593Smuzhiyun 
626*4882a593Smuzhiyun 	print_hex_dump_debug("ctx.key@"__stringify(__LINE__)": ",
627*4882a593Smuzhiyun 			     DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
628*4882a593Smuzhiyun 			     ctx->adata.keylen_pad + keys.enckeylen, 1);
629*4882a593Smuzhiyun 
630*4882a593Smuzhiyun skip_split_key:
631*4882a593Smuzhiyun 	ctx->cdata.keylen = keys.enckeylen;
632*4882a593Smuzhiyun 	memzero_explicit(&keys, sizeof(keys));
633*4882a593Smuzhiyun 	return aead_set_sh_desc(aead);
634*4882a593Smuzhiyun badkey:
635*4882a593Smuzhiyun 	memzero_explicit(&keys, sizeof(keys));
636*4882a593Smuzhiyun 	return -EINVAL;
637*4882a593Smuzhiyun }
638*4882a593Smuzhiyun 
des3_aead_setkey(struct crypto_aead * aead,const u8 * key,unsigned int keylen)639*4882a593Smuzhiyun static int des3_aead_setkey(struct crypto_aead *aead, const u8 *key,
640*4882a593Smuzhiyun 			    unsigned int keylen)
641*4882a593Smuzhiyun {
642*4882a593Smuzhiyun 	struct crypto_authenc_keys keys;
643*4882a593Smuzhiyun 	int err;
644*4882a593Smuzhiyun 
645*4882a593Smuzhiyun 	err = crypto_authenc_extractkeys(&keys, key, keylen);
646*4882a593Smuzhiyun 	if (unlikely(err))
647*4882a593Smuzhiyun 		return err;
648*4882a593Smuzhiyun 
649*4882a593Smuzhiyun 	err = verify_aead_des3_key(aead, keys.enckey, keys.enckeylen) ?:
650*4882a593Smuzhiyun 	      aead_setkey(aead, key, keylen);
651*4882a593Smuzhiyun 
652*4882a593Smuzhiyun 	memzero_explicit(&keys, sizeof(keys));
653*4882a593Smuzhiyun 	return err;
654*4882a593Smuzhiyun }
655*4882a593Smuzhiyun 
gcm_setkey(struct crypto_aead * aead,const u8 * key,unsigned int keylen)656*4882a593Smuzhiyun static int gcm_setkey(struct crypto_aead *aead,
657*4882a593Smuzhiyun 		      const u8 *key, unsigned int keylen)
658*4882a593Smuzhiyun {
659*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
660*4882a593Smuzhiyun 	struct device *jrdev = ctx->jrdev;
661*4882a593Smuzhiyun 	int err;
662*4882a593Smuzhiyun 
663*4882a593Smuzhiyun 	err = aes_check_keylen(keylen);
664*4882a593Smuzhiyun 	if (err)
665*4882a593Smuzhiyun 		return err;
666*4882a593Smuzhiyun 
667*4882a593Smuzhiyun 	print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
668*4882a593Smuzhiyun 			     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
669*4882a593Smuzhiyun 
670*4882a593Smuzhiyun 	memcpy(ctx->key, key, keylen);
671*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, ctx->dir);
672*4882a593Smuzhiyun 	ctx->cdata.keylen = keylen;
673*4882a593Smuzhiyun 
674*4882a593Smuzhiyun 	return gcm_set_sh_desc(aead);
675*4882a593Smuzhiyun }
676*4882a593Smuzhiyun 
rfc4106_setkey(struct crypto_aead * aead,const u8 * key,unsigned int keylen)677*4882a593Smuzhiyun static int rfc4106_setkey(struct crypto_aead *aead,
678*4882a593Smuzhiyun 			  const u8 *key, unsigned int keylen)
679*4882a593Smuzhiyun {
680*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
681*4882a593Smuzhiyun 	struct device *jrdev = ctx->jrdev;
682*4882a593Smuzhiyun 	int err;
683*4882a593Smuzhiyun 
684*4882a593Smuzhiyun 	err = aes_check_keylen(keylen - 4);
685*4882a593Smuzhiyun 	if (err)
686*4882a593Smuzhiyun 		return err;
687*4882a593Smuzhiyun 
688*4882a593Smuzhiyun 	print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
689*4882a593Smuzhiyun 			     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
690*4882a593Smuzhiyun 
691*4882a593Smuzhiyun 	memcpy(ctx->key, key, keylen);
692*4882a593Smuzhiyun 
693*4882a593Smuzhiyun 	/*
694*4882a593Smuzhiyun 	 * The last four bytes of the key material are used as the salt value
695*4882a593Smuzhiyun 	 * in the nonce. Update the AES key length.
696*4882a593Smuzhiyun 	 */
697*4882a593Smuzhiyun 	ctx->cdata.keylen = keylen - 4;
698*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
699*4882a593Smuzhiyun 				   ctx->dir);
700*4882a593Smuzhiyun 	return rfc4106_set_sh_desc(aead);
701*4882a593Smuzhiyun }
702*4882a593Smuzhiyun 
rfc4543_setkey(struct crypto_aead * aead,const u8 * key,unsigned int keylen)703*4882a593Smuzhiyun static int rfc4543_setkey(struct crypto_aead *aead,
704*4882a593Smuzhiyun 			  const u8 *key, unsigned int keylen)
705*4882a593Smuzhiyun {
706*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
707*4882a593Smuzhiyun 	struct device *jrdev = ctx->jrdev;
708*4882a593Smuzhiyun 	int err;
709*4882a593Smuzhiyun 
710*4882a593Smuzhiyun 	err = aes_check_keylen(keylen - 4);
711*4882a593Smuzhiyun 	if (err)
712*4882a593Smuzhiyun 		return err;
713*4882a593Smuzhiyun 
714*4882a593Smuzhiyun 	print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
715*4882a593Smuzhiyun 			     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
716*4882a593Smuzhiyun 
717*4882a593Smuzhiyun 	memcpy(ctx->key, key, keylen);
718*4882a593Smuzhiyun 
719*4882a593Smuzhiyun 	/*
720*4882a593Smuzhiyun 	 * The last four bytes of the key material are used as the salt value
721*4882a593Smuzhiyun 	 * in the nonce. Update the AES key length.
722*4882a593Smuzhiyun 	 */
723*4882a593Smuzhiyun 	ctx->cdata.keylen = keylen - 4;
724*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
725*4882a593Smuzhiyun 				   ctx->dir);
726*4882a593Smuzhiyun 	return rfc4543_set_sh_desc(aead);
727*4882a593Smuzhiyun }
728*4882a593Smuzhiyun 
skcipher_setkey(struct crypto_skcipher * skcipher,const u8 * key,unsigned int keylen,const u32 ctx1_iv_off)729*4882a593Smuzhiyun static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
730*4882a593Smuzhiyun 			   unsigned int keylen, const u32 ctx1_iv_off)
731*4882a593Smuzhiyun {
732*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
733*4882a593Smuzhiyun 	struct caam_skcipher_alg *alg =
734*4882a593Smuzhiyun 		container_of(crypto_skcipher_alg(skcipher), typeof(*alg),
735*4882a593Smuzhiyun 			     skcipher);
736*4882a593Smuzhiyun 	struct device *jrdev = ctx->jrdev;
737*4882a593Smuzhiyun 	unsigned int ivsize = crypto_skcipher_ivsize(skcipher);
738*4882a593Smuzhiyun 	u32 *desc;
739*4882a593Smuzhiyun 	const bool is_rfc3686 = alg->caam.rfc3686;
740*4882a593Smuzhiyun 
741*4882a593Smuzhiyun 	print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
742*4882a593Smuzhiyun 			     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
743*4882a593Smuzhiyun 
744*4882a593Smuzhiyun 	ctx->cdata.keylen = keylen;
745*4882a593Smuzhiyun 	ctx->cdata.key_virt = key;
746*4882a593Smuzhiyun 	ctx->cdata.key_inline = true;
747*4882a593Smuzhiyun 
748*4882a593Smuzhiyun 	/* skcipher_encrypt shared descriptor */
749*4882a593Smuzhiyun 	desc = ctx->sh_desc_enc;
750*4882a593Smuzhiyun 	cnstr_shdsc_skcipher_encap(desc, &ctx->cdata, ivsize, is_rfc3686,
751*4882a593Smuzhiyun 				   ctx1_iv_off);
752*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
753*4882a593Smuzhiyun 				   desc_bytes(desc), ctx->dir);
754*4882a593Smuzhiyun 
755*4882a593Smuzhiyun 	/* skcipher_decrypt shared descriptor */
756*4882a593Smuzhiyun 	desc = ctx->sh_desc_dec;
757*4882a593Smuzhiyun 	cnstr_shdsc_skcipher_decap(desc, &ctx->cdata, ivsize, is_rfc3686,
758*4882a593Smuzhiyun 				   ctx1_iv_off);
759*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
760*4882a593Smuzhiyun 				   desc_bytes(desc), ctx->dir);
761*4882a593Smuzhiyun 
762*4882a593Smuzhiyun 	return 0;
763*4882a593Smuzhiyun }
764*4882a593Smuzhiyun 
aes_skcipher_setkey(struct crypto_skcipher * skcipher,const u8 * key,unsigned int keylen)765*4882a593Smuzhiyun static int aes_skcipher_setkey(struct crypto_skcipher *skcipher,
766*4882a593Smuzhiyun 			       const u8 *key, unsigned int keylen)
767*4882a593Smuzhiyun {
768*4882a593Smuzhiyun 	int err;
769*4882a593Smuzhiyun 
770*4882a593Smuzhiyun 	err = aes_check_keylen(keylen);
771*4882a593Smuzhiyun 	if (err)
772*4882a593Smuzhiyun 		return err;
773*4882a593Smuzhiyun 
774*4882a593Smuzhiyun 	return skcipher_setkey(skcipher, key, keylen, 0);
775*4882a593Smuzhiyun }
776*4882a593Smuzhiyun 
rfc3686_skcipher_setkey(struct crypto_skcipher * skcipher,const u8 * key,unsigned int keylen)777*4882a593Smuzhiyun static int rfc3686_skcipher_setkey(struct crypto_skcipher *skcipher,
778*4882a593Smuzhiyun 				   const u8 *key, unsigned int keylen)
779*4882a593Smuzhiyun {
780*4882a593Smuzhiyun 	u32 ctx1_iv_off;
781*4882a593Smuzhiyun 	int err;
782*4882a593Smuzhiyun 
783*4882a593Smuzhiyun 	/*
784*4882a593Smuzhiyun 	 * RFC3686 specific:
785*4882a593Smuzhiyun 	 *	| CONTEXT1[255:128] = {NONCE, IV, COUNTER}
786*4882a593Smuzhiyun 	 *	| *key = {KEY, NONCE}
787*4882a593Smuzhiyun 	 */
788*4882a593Smuzhiyun 	ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
789*4882a593Smuzhiyun 	keylen -= CTR_RFC3686_NONCE_SIZE;
790*4882a593Smuzhiyun 
791*4882a593Smuzhiyun 	err = aes_check_keylen(keylen);
792*4882a593Smuzhiyun 	if (err)
793*4882a593Smuzhiyun 		return err;
794*4882a593Smuzhiyun 
795*4882a593Smuzhiyun 	return skcipher_setkey(skcipher, key, keylen, ctx1_iv_off);
796*4882a593Smuzhiyun }
797*4882a593Smuzhiyun 
ctr_skcipher_setkey(struct crypto_skcipher * skcipher,const u8 * key,unsigned int keylen)798*4882a593Smuzhiyun static int ctr_skcipher_setkey(struct crypto_skcipher *skcipher,
799*4882a593Smuzhiyun 			       const u8 *key, unsigned int keylen)
800*4882a593Smuzhiyun {
801*4882a593Smuzhiyun 	u32 ctx1_iv_off;
802*4882a593Smuzhiyun 	int err;
803*4882a593Smuzhiyun 
804*4882a593Smuzhiyun 	/*
805*4882a593Smuzhiyun 	 * AES-CTR needs to load IV in CONTEXT1 reg
806*4882a593Smuzhiyun 	 * at an offset of 128bits (16bytes)
807*4882a593Smuzhiyun 	 * CONTEXT1[255:128] = IV
808*4882a593Smuzhiyun 	 */
809*4882a593Smuzhiyun 	ctx1_iv_off = 16;
810*4882a593Smuzhiyun 
811*4882a593Smuzhiyun 	err = aes_check_keylen(keylen);
812*4882a593Smuzhiyun 	if (err)
813*4882a593Smuzhiyun 		return err;
814*4882a593Smuzhiyun 
815*4882a593Smuzhiyun 	return skcipher_setkey(skcipher, key, keylen, ctx1_iv_off);
816*4882a593Smuzhiyun }
817*4882a593Smuzhiyun 
des_skcipher_setkey(struct crypto_skcipher * skcipher,const u8 * key,unsigned int keylen)818*4882a593Smuzhiyun static int des_skcipher_setkey(struct crypto_skcipher *skcipher,
819*4882a593Smuzhiyun 			       const u8 *key, unsigned int keylen)
820*4882a593Smuzhiyun {
821*4882a593Smuzhiyun 	return verify_skcipher_des_key(skcipher, key) ?:
822*4882a593Smuzhiyun 	       skcipher_setkey(skcipher, key, keylen, 0);
823*4882a593Smuzhiyun }
824*4882a593Smuzhiyun 
des3_skcipher_setkey(struct crypto_skcipher * skcipher,const u8 * key,unsigned int keylen)825*4882a593Smuzhiyun static int des3_skcipher_setkey(struct crypto_skcipher *skcipher,
826*4882a593Smuzhiyun 				const u8 *key, unsigned int keylen)
827*4882a593Smuzhiyun {
828*4882a593Smuzhiyun 	return verify_skcipher_des3_key(skcipher, key) ?:
829*4882a593Smuzhiyun 	       skcipher_setkey(skcipher, key, keylen, 0);
830*4882a593Smuzhiyun }
831*4882a593Smuzhiyun 
xts_skcipher_setkey(struct crypto_skcipher * skcipher,const u8 * key,unsigned int keylen)832*4882a593Smuzhiyun static int xts_skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
833*4882a593Smuzhiyun 			       unsigned int keylen)
834*4882a593Smuzhiyun {
835*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
836*4882a593Smuzhiyun 	struct device *jrdev = ctx->jrdev;
837*4882a593Smuzhiyun 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
838*4882a593Smuzhiyun 	u32 *desc;
839*4882a593Smuzhiyun 	int err;
840*4882a593Smuzhiyun 
841*4882a593Smuzhiyun 	err = xts_verify_key(skcipher, key, keylen);
842*4882a593Smuzhiyun 	if (err) {
843*4882a593Smuzhiyun 		dev_dbg(jrdev, "key size mismatch\n");
844*4882a593Smuzhiyun 		return err;
845*4882a593Smuzhiyun 	}
846*4882a593Smuzhiyun 
847*4882a593Smuzhiyun 	if (keylen != 2 * AES_KEYSIZE_128 && keylen != 2 * AES_KEYSIZE_256)
848*4882a593Smuzhiyun 		ctx->xts_key_fallback = true;
849*4882a593Smuzhiyun 
850*4882a593Smuzhiyun 	if (ctrlpriv->era <= 8 || ctx->xts_key_fallback) {
851*4882a593Smuzhiyun 		err = crypto_skcipher_setkey(ctx->fallback, key, keylen);
852*4882a593Smuzhiyun 		if (err)
853*4882a593Smuzhiyun 			return err;
854*4882a593Smuzhiyun 	}
855*4882a593Smuzhiyun 
856*4882a593Smuzhiyun 	ctx->cdata.keylen = keylen;
857*4882a593Smuzhiyun 	ctx->cdata.key_virt = key;
858*4882a593Smuzhiyun 	ctx->cdata.key_inline = true;
859*4882a593Smuzhiyun 
860*4882a593Smuzhiyun 	/* xts_skcipher_encrypt shared descriptor */
861*4882a593Smuzhiyun 	desc = ctx->sh_desc_enc;
862*4882a593Smuzhiyun 	cnstr_shdsc_xts_skcipher_encap(desc, &ctx->cdata);
863*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
864*4882a593Smuzhiyun 				   desc_bytes(desc), ctx->dir);
865*4882a593Smuzhiyun 
866*4882a593Smuzhiyun 	/* xts_skcipher_decrypt shared descriptor */
867*4882a593Smuzhiyun 	desc = ctx->sh_desc_dec;
868*4882a593Smuzhiyun 	cnstr_shdsc_xts_skcipher_decap(desc, &ctx->cdata);
869*4882a593Smuzhiyun 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
870*4882a593Smuzhiyun 				   desc_bytes(desc), ctx->dir);
871*4882a593Smuzhiyun 
872*4882a593Smuzhiyun 	return 0;
873*4882a593Smuzhiyun }
874*4882a593Smuzhiyun 
875*4882a593Smuzhiyun /*
876*4882a593Smuzhiyun  * aead_edesc - s/w-extended aead descriptor
877*4882a593Smuzhiyun  * @src_nents: number of segments in input s/w scatterlist
878*4882a593Smuzhiyun  * @dst_nents: number of segments in output s/w scatterlist
879*4882a593Smuzhiyun  * @mapped_src_nents: number of segments in input h/w link table
880*4882a593Smuzhiyun  * @mapped_dst_nents: number of segments in output h/w link table
881*4882a593Smuzhiyun  * @sec4_sg_bytes: length of dma mapped sec4_sg space
882*4882a593Smuzhiyun  * @bklog: stored to determine if the request needs backlog
883*4882a593Smuzhiyun  * @sec4_sg_dma: bus physical mapped address of h/w link table
884*4882a593Smuzhiyun  * @sec4_sg: pointer to h/w link table
885*4882a593Smuzhiyun  * @hw_desc: the h/w job descriptor followed by any referenced link tables
886*4882a593Smuzhiyun  */
887*4882a593Smuzhiyun struct aead_edesc {
888*4882a593Smuzhiyun 	int src_nents;
889*4882a593Smuzhiyun 	int dst_nents;
890*4882a593Smuzhiyun 	int mapped_src_nents;
891*4882a593Smuzhiyun 	int mapped_dst_nents;
892*4882a593Smuzhiyun 	int sec4_sg_bytes;
893*4882a593Smuzhiyun 	bool bklog;
894*4882a593Smuzhiyun 	dma_addr_t sec4_sg_dma;
895*4882a593Smuzhiyun 	struct sec4_sg_entry *sec4_sg;
896*4882a593Smuzhiyun 	u32 hw_desc[];
897*4882a593Smuzhiyun };
898*4882a593Smuzhiyun 
899*4882a593Smuzhiyun /*
900*4882a593Smuzhiyun  * skcipher_edesc - s/w-extended skcipher descriptor
901*4882a593Smuzhiyun  * @src_nents: number of segments in input s/w scatterlist
902*4882a593Smuzhiyun  * @dst_nents: number of segments in output s/w scatterlist
903*4882a593Smuzhiyun  * @mapped_src_nents: number of segments in input h/w link table
904*4882a593Smuzhiyun  * @mapped_dst_nents: number of segments in output h/w link table
905*4882a593Smuzhiyun  * @iv_dma: dma address of iv for checking continuity and link table
906*4882a593Smuzhiyun  * @sec4_sg_bytes: length of dma mapped sec4_sg space
907*4882a593Smuzhiyun  * @bklog: stored to determine if the request needs backlog
908*4882a593Smuzhiyun  * @sec4_sg_dma: bus physical mapped address of h/w link table
909*4882a593Smuzhiyun  * @sec4_sg: pointer to h/w link table
910*4882a593Smuzhiyun  * @hw_desc: the h/w job descriptor followed by any referenced link tables
911*4882a593Smuzhiyun  *	     and IV
912*4882a593Smuzhiyun  */
913*4882a593Smuzhiyun struct skcipher_edesc {
914*4882a593Smuzhiyun 	int src_nents;
915*4882a593Smuzhiyun 	int dst_nents;
916*4882a593Smuzhiyun 	int mapped_src_nents;
917*4882a593Smuzhiyun 	int mapped_dst_nents;
918*4882a593Smuzhiyun 	dma_addr_t iv_dma;
919*4882a593Smuzhiyun 	int sec4_sg_bytes;
920*4882a593Smuzhiyun 	bool bklog;
921*4882a593Smuzhiyun 	dma_addr_t sec4_sg_dma;
922*4882a593Smuzhiyun 	struct sec4_sg_entry *sec4_sg;
923*4882a593Smuzhiyun 	u32 hw_desc[];
924*4882a593Smuzhiyun };
925*4882a593Smuzhiyun 
caam_unmap(struct device * dev,struct scatterlist * src,struct scatterlist * dst,int src_nents,int dst_nents,dma_addr_t iv_dma,int ivsize,dma_addr_t sec4_sg_dma,int sec4_sg_bytes)926*4882a593Smuzhiyun static void caam_unmap(struct device *dev, struct scatterlist *src,
927*4882a593Smuzhiyun 		       struct scatterlist *dst, int src_nents,
928*4882a593Smuzhiyun 		       int dst_nents,
929*4882a593Smuzhiyun 		       dma_addr_t iv_dma, int ivsize, dma_addr_t sec4_sg_dma,
930*4882a593Smuzhiyun 		       int sec4_sg_bytes)
931*4882a593Smuzhiyun {
932*4882a593Smuzhiyun 	if (dst != src) {
933*4882a593Smuzhiyun 		if (src_nents)
934*4882a593Smuzhiyun 			dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
935*4882a593Smuzhiyun 		if (dst_nents)
936*4882a593Smuzhiyun 			dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
937*4882a593Smuzhiyun 	} else {
938*4882a593Smuzhiyun 		dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
939*4882a593Smuzhiyun 	}
940*4882a593Smuzhiyun 
941*4882a593Smuzhiyun 	if (iv_dma)
942*4882a593Smuzhiyun 		dma_unmap_single(dev, iv_dma, ivsize, DMA_BIDIRECTIONAL);
943*4882a593Smuzhiyun 	if (sec4_sg_bytes)
944*4882a593Smuzhiyun 		dma_unmap_single(dev, sec4_sg_dma, sec4_sg_bytes,
945*4882a593Smuzhiyun 				 DMA_TO_DEVICE);
946*4882a593Smuzhiyun }
947*4882a593Smuzhiyun 
aead_unmap(struct device * dev,struct aead_edesc * edesc,struct aead_request * req)948*4882a593Smuzhiyun static void aead_unmap(struct device *dev,
949*4882a593Smuzhiyun 		       struct aead_edesc *edesc,
950*4882a593Smuzhiyun 		       struct aead_request *req)
951*4882a593Smuzhiyun {
952*4882a593Smuzhiyun 	caam_unmap(dev, req->src, req->dst,
953*4882a593Smuzhiyun 		   edesc->src_nents, edesc->dst_nents, 0, 0,
954*4882a593Smuzhiyun 		   edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
955*4882a593Smuzhiyun }
956*4882a593Smuzhiyun 
skcipher_unmap(struct device * dev,struct skcipher_edesc * edesc,struct skcipher_request * req)957*4882a593Smuzhiyun static void skcipher_unmap(struct device *dev, struct skcipher_edesc *edesc,
958*4882a593Smuzhiyun 			   struct skcipher_request *req)
959*4882a593Smuzhiyun {
960*4882a593Smuzhiyun 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
961*4882a593Smuzhiyun 	int ivsize = crypto_skcipher_ivsize(skcipher);
962*4882a593Smuzhiyun 
963*4882a593Smuzhiyun 	caam_unmap(dev, req->src, req->dst,
964*4882a593Smuzhiyun 		   edesc->src_nents, edesc->dst_nents,
965*4882a593Smuzhiyun 		   edesc->iv_dma, ivsize,
966*4882a593Smuzhiyun 		   edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
967*4882a593Smuzhiyun }
968*4882a593Smuzhiyun 
aead_crypt_done(struct device * jrdev,u32 * desc,u32 err,void * context)969*4882a593Smuzhiyun static void aead_crypt_done(struct device *jrdev, u32 *desc, u32 err,
970*4882a593Smuzhiyun 			    void *context)
971*4882a593Smuzhiyun {
972*4882a593Smuzhiyun 	struct aead_request *req = context;
973*4882a593Smuzhiyun 	struct caam_aead_req_ctx *rctx = aead_request_ctx(req);
974*4882a593Smuzhiyun 	struct caam_drv_private_jr *jrp = dev_get_drvdata(jrdev);
975*4882a593Smuzhiyun 	struct aead_edesc *edesc;
976*4882a593Smuzhiyun 	int ecode = 0;
977*4882a593Smuzhiyun 	bool has_bklog;
978*4882a593Smuzhiyun 
979*4882a593Smuzhiyun 	dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
980*4882a593Smuzhiyun 
981*4882a593Smuzhiyun 	edesc = rctx->edesc;
982*4882a593Smuzhiyun 	has_bklog = edesc->bklog;
983*4882a593Smuzhiyun 
984*4882a593Smuzhiyun 	if (err)
985*4882a593Smuzhiyun 		ecode = caam_jr_strstatus(jrdev, err);
986*4882a593Smuzhiyun 
987*4882a593Smuzhiyun 	aead_unmap(jrdev, edesc, req);
988*4882a593Smuzhiyun 
989*4882a593Smuzhiyun 	kfree(edesc);
990*4882a593Smuzhiyun 
991*4882a593Smuzhiyun 	/*
992*4882a593Smuzhiyun 	 * If no backlog flag, the completion of the request is done
993*4882a593Smuzhiyun 	 * by CAAM, not crypto engine.
994*4882a593Smuzhiyun 	 */
995*4882a593Smuzhiyun 	if (!has_bklog)
996*4882a593Smuzhiyun 		aead_request_complete(req, ecode);
997*4882a593Smuzhiyun 	else
998*4882a593Smuzhiyun 		crypto_finalize_aead_request(jrp->engine, req, ecode);
999*4882a593Smuzhiyun }
1000*4882a593Smuzhiyun 
skcipher_crypt_done(struct device * jrdev,u32 * desc,u32 err,void * context)1001*4882a593Smuzhiyun static void skcipher_crypt_done(struct device *jrdev, u32 *desc, u32 err,
1002*4882a593Smuzhiyun 				void *context)
1003*4882a593Smuzhiyun {
1004*4882a593Smuzhiyun 	struct skcipher_request *req = context;
1005*4882a593Smuzhiyun 	struct skcipher_edesc *edesc;
1006*4882a593Smuzhiyun 	struct caam_skcipher_req_ctx *rctx = skcipher_request_ctx(req);
1007*4882a593Smuzhiyun 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
1008*4882a593Smuzhiyun 	struct caam_drv_private_jr *jrp = dev_get_drvdata(jrdev);
1009*4882a593Smuzhiyun 	int ivsize = crypto_skcipher_ivsize(skcipher);
1010*4882a593Smuzhiyun 	int ecode = 0;
1011*4882a593Smuzhiyun 	bool has_bklog;
1012*4882a593Smuzhiyun 
1013*4882a593Smuzhiyun 	dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
1014*4882a593Smuzhiyun 
1015*4882a593Smuzhiyun 	edesc = rctx->edesc;
1016*4882a593Smuzhiyun 	has_bklog = edesc->bklog;
1017*4882a593Smuzhiyun 	if (err)
1018*4882a593Smuzhiyun 		ecode = caam_jr_strstatus(jrdev, err);
1019*4882a593Smuzhiyun 
1020*4882a593Smuzhiyun 	skcipher_unmap(jrdev, edesc, req);
1021*4882a593Smuzhiyun 
1022*4882a593Smuzhiyun 	/*
1023*4882a593Smuzhiyun 	 * The crypto API expects us to set the IV (req->iv) to the last
1024*4882a593Smuzhiyun 	 * ciphertext block (CBC mode) or last counter (CTR mode).
1025*4882a593Smuzhiyun 	 * This is used e.g. by the CTS mode.
1026*4882a593Smuzhiyun 	 */
1027*4882a593Smuzhiyun 	if (ivsize && !ecode) {
1028*4882a593Smuzhiyun 		memcpy(req->iv, (u8 *)edesc->sec4_sg + edesc->sec4_sg_bytes,
1029*4882a593Smuzhiyun 		       ivsize);
1030*4882a593Smuzhiyun 
1031*4882a593Smuzhiyun 		print_hex_dump_debug("dstiv  @" __stringify(__LINE__)": ",
1032*4882a593Smuzhiyun 				     DUMP_PREFIX_ADDRESS, 16, 4, req->iv,
1033*4882a593Smuzhiyun 				     ivsize, 1);
1034*4882a593Smuzhiyun 	}
1035*4882a593Smuzhiyun 
1036*4882a593Smuzhiyun 	caam_dump_sg("dst    @" __stringify(__LINE__)": ",
1037*4882a593Smuzhiyun 		     DUMP_PREFIX_ADDRESS, 16, 4, req->dst,
1038*4882a593Smuzhiyun 		     edesc->dst_nents > 1 ? 100 : req->cryptlen, 1);
1039*4882a593Smuzhiyun 
1040*4882a593Smuzhiyun 	kfree(edesc);
1041*4882a593Smuzhiyun 
1042*4882a593Smuzhiyun 	/*
1043*4882a593Smuzhiyun 	 * If no backlog flag, the completion of the request is done
1044*4882a593Smuzhiyun 	 * by CAAM, not crypto engine.
1045*4882a593Smuzhiyun 	 */
1046*4882a593Smuzhiyun 	if (!has_bklog)
1047*4882a593Smuzhiyun 		skcipher_request_complete(req, ecode);
1048*4882a593Smuzhiyun 	else
1049*4882a593Smuzhiyun 		crypto_finalize_skcipher_request(jrp->engine, req, ecode);
1050*4882a593Smuzhiyun }
1051*4882a593Smuzhiyun 
1052*4882a593Smuzhiyun /*
1053*4882a593Smuzhiyun  * Fill in aead job descriptor
1054*4882a593Smuzhiyun  */
init_aead_job(struct aead_request * req,struct aead_edesc * edesc,bool all_contig,bool encrypt)1055*4882a593Smuzhiyun static void init_aead_job(struct aead_request *req,
1056*4882a593Smuzhiyun 			  struct aead_edesc *edesc,
1057*4882a593Smuzhiyun 			  bool all_contig, bool encrypt)
1058*4882a593Smuzhiyun {
1059*4882a593Smuzhiyun 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1060*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1061*4882a593Smuzhiyun 	int authsize = ctx->authsize;
1062*4882a593Smuzhiyun 	u32 *desc = edesc->hw_desc;
1063*4882a593Smuzhiyun 	u32 out_options, in_options;
1064*4882a593Smuzhiyun 	dma_addr_t dst_dma, src_dma;
1065*4882a593Smuzhiyun 	int len, sec4_sg_index = 0;
1066*4882a593Smuzhiyun 	dma_addr_t ptr;
1067*4882a593Smuzhiyun 	u32 *sh_desc;
1068*4882a593Smuzhiyun 
1069*4882a593Smuzhiyun 	sh_desc = encrypt ? ctx->sh_desc_enc : ctx->sh_desc_dec;
1070*4882a593Smuzhiyun 	ptr = encrypt ? ctx->sh_desc_enc_dma : ctx->sh_desc_dec_dma;
1071*4882a593Smuzhiyun 
1072*4882a593Smuzhiyun 	len = desc_len(sh_desc);
1073*4882a593Smuzhiyun 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
1074*4882a593Smuzhiyun 
1075*4882a593Smuzhiyun 	if (all_contig) {
1076*4882a593Smuzhiyun 		src_dma = edesc->mapped_src_nents ? sg_dma_address(req->src) :
1077*4882a593Smuzhiyun 						    0;
1078*4882a593Smuzhiyun 		in_options = 0;
1079*4882a593Smuzhiyun 	} else {
1080*4882a593Smuzhiyun 		src_dma = edesc->sec4_sg_dma;
1081*4882a593Smuzhiyun 		sec4_sg_index += edesc->mapped_src_nents;
1082*4882a593Smuzhiyun 		in_options = LDST_SGF;
1083*4882a593Smuzhiyun 	}
1084*4882a593Smuzhiyun 
1085*4882a593Smuzhiyun 	append_seq_in_ptr(desc, src_dma, req->assoclen + req->cryptlen,
1086*4882a593Smuzhiyun 			  in_options);
1087*4882a593Smuzhiyun 
1088*4882a593Smuzhiyun 	dst_dma = src_dma;
1089*4882a593Smuzhiyun 	out_options = in_options;
1090*4882a593Smuzhiyun 
1091*4882a593Smuzhiyun 	if (unlikely(req->src != req->dst)) {
1092*4882a593Smuzhiyun 		if (!edesc->mapped_dst_nents) {
1093*4882a593Smuzhiyun 			dst_dma = 0;
1094*4882a593Smuzhiyun 			out_options = 0;
1095*4882a593Smuzhiyun 		} else if (edesc->mapped_dst_nents == 1) {
1096*4882a593Smuzhiyun 			dst_dma = sg_dma_address(req->dst);
1097*4882a593Smuzhiyun 			out_options = 0;
1098*4882a593Smuzhiyun 		} else {
1099*4882a593Smuzhiyun 			dst_dma = edesc->sec4_sg_dma +
1100*4882a593Smuzhiyun 				  sec4_sg_index *
1101*4882a593Smuzhiyun 				  sizeof(struct sec4_sg_entry);
1102*4882a593Smuzhiyun 			out_options = LDST_SGF;
1103*4882a593Smuzhiyun 		}
1104*4882a593Smuzhiyun 	}
1105*4882a593Smuzhiyun 
1106*4882a593Smuzhiyun 	if (encrypt)
1107*4882a593Smuzhiyun 		append_seq_out_ptr(desc, dst_dma,
1108*4882a593Smuzhiyun 				   req->assoclen + req->cryptlen + authsize,
1109*4882a593Smuzhiyun 				   out_options);
1110*4882a593Smuzhiyun 	else
1111*4882a593Smuzhiyun 		append_seq_out_ptr(desc, dst_dma,
1112*4882a593Smuzhiyun 				   req->assoclen + req->cryptlen - authsize,
1113*4882a593Smuzhiyun 				   out_options);
1114*4882a593Smuzhiyun }
1115*4882a593Smuzhiyun 
init_gcm_job(struct aead_request * req,struct aead_edesc * edesc,bool all_contig,bool encrypt)1116*4882a593Smuzhiyun static void init_gcm_job(struct aead_request *req,
1117*4882a593Smuzhiyun 			 struct aead_edesc *edesc,
1118*4882a593Smuzhiyun 			 bool all_contig, bool encrypt)
1119*4882a593Smuzhiyun {
1120*4882a593Smuzhiyun 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1121*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1122*4882a593Smuzhiyun 	unsigned int ivsize = crypto_aead_ivsize(aead);
1123*4882a593Smuzhiyun 	u32 *desc = edesc->hw_desc;
1124*4882a593Smuzhiyun 	bool generic_gcm = (ivsize == GCM_AES_IV_SIZE);
1125*4882a593Smuzhiyun 	unsigned int last;
1126*4882a593Smuzhiyun 
1127*4882a593Smuzhiyun 	init_aead_job(req, edesc, all_contig, encrypt);
1128*4882a593Smuzhiyun 	append_math_add_imm_u32(desc, REG3, ZERO, IMM, req->assoclen);
1129*4882a593Smuzhiyun 
1130*4882a593Smuzhiyun 	/* BUG This should not be specific to generic GCM. */
1131*4882a593Smuzhiyun 	last = 0;
1132*4882a593Smuzhiyun 	if (encrypt && generic_gcm && !(req->assoclen + req->cryptlen))
1133*4882a593Smuzhiyun 		last = FIFOLD_TYPE_LAST1;
1134*4882a593Smuzhiyun 
1135*4882a593Smuzhiyun 	/* Read GCM IV */
1136*4882a593Smuzhiyun 	append_cmd(desc, CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 | IMMEDIATE |
1137*4882a593Smuzhiyun 			 FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 | GCM_AES_IV_SIZE | last);
1138*4882a593Smuzhiyun 	/* Append Salt */
1139*4882a593Smuzhiyun 	if (!generic_gcm)
1140*4882a593Smuzhiyun 		append_data(desc, ctx->key + ctx->cdata.keylen, 4);
1141*4882a593Smuzhiyun 	/* Append IV */
1142*4882a593Smuzhiyun 	append_data(desc, req->iv, ivsize);
1143*4882a593Smuzhiyun 	/* End of blank commands */
1144*4882a593Smuzhiyun }
1145*4882a593Smuzhiyun 
init_chachapoly_job(struct aead_request * req,struct aead_edesc * edesc,bool all_contig,bool encrypt)1146*4882a593Smuzhiyun static void init_chachapoly_job(struct aead_request *req,
1147*4882a593Smuzhiyun 				struct aead_edesc *edesc, bool all_contig,
1148*4882a593Smuzhiyun 				bool encrypt)
1149*4882a593Smuzhiyun {
1150*4882a593Smuzhiyun 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1151*4882a593Smuzhiyun 	unsigned int ivsize = crypto_aead_ivsize(aead);
1152*4882a593Smuzhiyun 	unsigned int assoclen = req->assoclen;
1153*4882a593Smuzhiyun 	u32 *desc = edesc->hw_desc;
1154*4882a593Smuzhiyun 	u32 ctx_iv_off = 4;
1155*4882a593Smuzhiyun 
1156*4882a593Smuzhiyun 	init_aead_job(req, edesc, all_contig, encrypt);
1157*4882a593Smuzhiyun 
1158*4882a593Smuzhiyun 	if (ivsize != CHACHAPOLY_IV_SIZE) {
1159*4882a593Smuzhiyun 		/* IPsec specific: CONTEXT1[223:128] = {NONCE, IV} */
1160*4882a593Smuzhiyun 		ctx_iv_off += 4;
1161*4882a593Smuzhiyun 
1162*4882a593Smuzhiyun 		/*
1163*4882a593Smuzhiyun 		 * The associated data comes already with the IV but we need
1164*4882a593Smuzhiyun 		 * to skip it when we authenticate or encrypt...
1165*4882a593Smuzhiyun 		 */
1166*4882a593Smuzhiyun 		assoclen -= ivsize;
1167*4882a593Smuzhiyun 	}
1168*4882a593Smuzhiyun 
1169*4882a593Smuzhiyun 	append_math_add_imm_u32(desc, REG3, ZERO, IMM, assoclen);
1170*4882a593Smuzhiyun 
1171*4882a593Smuzhiyun 	/*
1172*4882a593Smuzhiyun 	 * For IPsec load the IV further in the same register.
1173*4882a593Smuzhiyun 	 * For RFC7539 simply load the 12 bytes nonce in a single operation
1174*4882a593Smuzhiyun 	 */
1175*4882a593Smuzhiyun 	append_load_as_imm(desc, req->iv, ivsize, LDST_CLASS_1_CCB |
1176*4882a593Smuzhiyun 			   LDST_SRCDST_BYTE_CONTEXT |
1177*4882a593Smuzhiyun 			   ctx_iv_off << LDST_OFFSET_SHIFT);
1178*4882a593Smuzhiyun }
1179*4882a593Smuzhiyun 
init_authenc_job(struct aead_request * req,struct aead_edesc * edesc,bool all_contig,bool encrypt)1180*4882a593Smuzhiyun static void init_authenc_job(struct aead_request *req,
1181*4882a593Smuzhiyun 			     struct aead_edesc *edesc,
1182*4882a593Smuzhiyun 			     bool all_contig, bool encrypt)
1183*4882a593Smuzhiyun {
1184*4882a593Smuzhiyun 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1185*4882a593Smuzhiyun 	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
1186*4882a593Smuzhiyun 						 struct caam_aead_alg, aead);
1187*4882a593Smuzhiyun 	unsigned int ivsize = crypto_aead_ivsize(aead);
1188*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1189*4882a593Smuzhiyun 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctx->jrdev->parent);
1190*4882a593Smuzhiyun 	const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
1191*4882a593Smuzhiyun 			       OP_ALG_AAI_CTR_MOD128);
1192*4882a593Smuzhiyun 	const bool is_rfc3686 = alg->caam.rfc3686;
1193*4882a593Smuzhiyun 	u32 *desc = edesc->hw_desc;
1194*4882a593Smuzhiyun 	u32 ivoffset = 0;
1195*4882a593Smuzhiyun 
1196*4882a593Smuzhiyun 	/*
1197*4882a593Smuzhiyun 	 * AES-CTR needs to load IV in CONTEXT1 reg
1198*4882a593Smuzhiyun 	 * at an offset of 128bits (16bytes)
1199*4882a593Smuzhiyun 	 * CONTEXT1[255:128] = IV
1200*4882a593Smuzhiyun 	 */
1201*4882a593Smuzhiyun 	if (ctr_mode)
1202*4882a593Smuzhiyun 		ivoffset = 16;
1203*4882a593Smuzhiyun 
1204*4882a593Smuzhiyun 	/*
1205*4882a593Smuzhiyun 	 * RFC3686 specific:
1206*4882a593Smuzhiyun 	 *	CONTEXT1[255:128] = {NONCE, IV, COUNTER}
1207*4882a593Smuzhiyun 	 */
1208*4882a593Smuzhiyun 	if (is_rfc3686)
1209*4882a593Smuzhiyun 		ivoffset = 16 + CTR_RFC3686_NONCE_SIZE;
1210*4882a593Smuzhiyun 
1211*4882a593Smuzhiyun 	init_aead_job(req, edesc, all_contig, encrypt);
1212*4882a593Smuzhiyun 
1213*4882a593Smuzhiyun 	/*
1214*4882a593Smuzhiyun 	 * {REG3, DPOVRD} = assoclen, depending on whether MATH command supports
1215*4882a593Smuzhiyun 	 * having DPOVRD as destination.
1216*4882a593Smuzhiyun 	 */
1217*4882a593Smuzhiyun 	if (ctrlpriv->era < 3)
1218*4882a593Smuzhiyun 		append_math_add_imm_u32(desc, REG3, ZERO, IMM, req->assoclen);
1219*4882a593Smuzhiyun 	else
1220*4882a593Smuzhiyun 		append_math_add_imm_u32(desc, DPOVRD, ZERO, IMM, req->assoclen);
1221*4882a593Smuzhiyun 
1222*4882a593Smuzhiyun 	if (ivsize && ((is_rfc3686 && encrypt) || !alg->caam.geniv))
1223*4882a593Smuzhiyun 		append_load_as_imm(desc, req->iv, ivsize,
1224*4882a593Smuzhiyun 				   LDST_CLASS_1_CCB |
1225*4882a593Smuzhiyun 				   LDST_SRCDST_BYTE_CONTEXT |
1226*4882a593Smuzhiyun 				   (ivoffset << LDST_OFFSET_SHIFT));
1227*4882a593Smuzhiyun }
1228*4882a593Smuzhiyun 
1229*4882a593Smuzhiyun /*
1230*4882a593Smuzhiyun  * Fill in skcipher job descriptor
1231*4882a593Smuzhiyun  */
init_skcipher_job(struct skcipher_request * req,struct skcipher_edesc * edesc,const bool encrypt)1232*4882a593Smuzhiyun static void init_skcipher_job(struct skcipher_request *req,
1233*4882a593Smuzhiyun 			      struct skcipher_edesc *edesc,
1234*4882a593Smuzhiyun 			      const bool encrypt)
1235*4882a593Smuzhiyun {
1236*4882a593Smuzhiyun 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
1237*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
1238*4882a593Smuzhiyun 	struct device *jrdev = ctx->jrdev;
1239*4882a593Smuzhiyun 	int ivsize = crypto_skcipher_ivsize(skcipher);
1240*4882a593Smuzhiyun 	u32 *desc = edesc->hw_desc;
1241*4882a593Smuzhiyun 	u32 *sh_desc;
1242*4882a593Smuzhiyun 	u32 in_options = 0, out_options = 0;
1243*4882a593Smuzhiyun 	dma_addr_t src_dma, dst_dma, ptr;
1244*4882a593Smuzhiyun 	int len, sec4_sg_index = 0;
1245*4882a593Smuzhiyun 
1246*4882a593Smuzhiyun 	print_hex_dump_debug("presciv@"__stringify(__LINE__)": ",
1247*4882a593Smuzhiyun 			     DUMP_PREFIX_ADDRESS, 16, 4, req->iv, ivsize, 1);
1248*4882a593Smuzhiyun 	dev_dbg(jrdev, "asked=%d, cryptlen%d\n",
1249*4882a593Smuzhiyun 	       (int)edesc->src_nents > 1 ? 100 : req->cryptlen, req->cryptlen);
1250*4882a593Smuzhiyun 
1251*4882a593Smuzhiyun 	caam_dump_sg("src    @" __stringify(__LINE__)": ",
1252*4882a593Smuzhiyun 		     DUMP_PREFIX_ADDRESS, 16, 4, req->src,
1253*4882a593Smuzhiyun 		     edesc->src_nents > 1 ? 100 : req->cryptlen, 1);
1254*4882a593Smuzhiyun 
1255*4882a593Smuzhiyun 	sh_desc = encrypt ? ctx->sh_desc_enc : ctx->sh_desc_dec;
1256*4882a593Smuzhiyun 	ptr = encrypt ? ctx->sh_desc_enc_dma : ctx->sh_desc_dec_dma;
1257*4882a593Smuzhiyun 
1258*4882a593Smuzhiyun 	len = desc_len(sh_desc);
1259*4882a593Smuzhiyun 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
1260*4882a593Smuzhiyun 
1261*4882a593Smuzhiyun 	if (ivsize || edesc->mapped_src_nents > 1) {
1262*4882a593Smuzhiyun 		src_dma = edesc->sec4_sg_dma;
1263*4882a593Smuzhiyun 		sec4_sg_index = edesc->mapped_src_nents + !!ivsize;
1264*4882a593Smuzhiyun 		in_options = LDST_SGF;
1265*4882a593Smuzhiyun 	} else {
1266*4882a593Smuzhiyun 		src_dma = sg_dma_address(req->src);
1267*4882a593Smuzhiyun 	}
1268*4882a593Smuzhiyun 
1269*4882a593Smuzhiyun 	append_seq_in_ptr(desc, src_dma, req->cryptlen + ivsize, in_options);
1270*4882a593Smuzhiyun 
1271*4882a593Smuzhiyun 	if (likely(req->src == req->dst)) {
1272*4882a593Smuzhiyun 		dst_dma = src_dma + !!ivsize * sizeof(struct sec4_sg_entry);
1273*4882a593Smuzhiyun 		out_options = in_options;
1274*4882a593Smuzhiyun 	} else if (!ivsize && edesc->mapped_dst_nents == 1) {
1275*4882a593Smuzhiyun 		dst_dma = sg_dma_address(req->dst);
1276*4882a593Smuzhiyun 	} else {
1277*4882a593Smuzhiyun 		dst_dma = edesc->sec4_sg_dma + sec4_sg_index *
1278*4882a593Smuzhiyun 			  sizeof(struct sec4_sg_entry);
1279*4882a593Smuzhiyun 		out_options = LDST_SGF;
1280*4882a593Smuzhiyun 	}
1281*4882a593Smuzhiyun 
1282*4882a593Smuzhiyun 	append_seq_out_ptr(desc, dst_dma, req->cryptlen + ivsize, out_options);
1283*4882a593Smuzhiyun }
1284*4882a593Smuzhiyun 
1285*4882a593Smuzhiyun /*
1286*4882a593Smuzhiyun  * allocate and map the aead extended descriptor
1287*4882a593Smuzhiyun  */
aead_edesc_alloc(struct aead_request * req,int desc_bytes,bool * all_contig_ptr,bool encrypt)1288*4882a593Smuzhiyun static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
1289*4882a593Smuzhiyun 					   int desc_bytes, bool *all_contig_ptr,
1290*4882a593Smuzhiyun 					   bool encrypt)
1291*4882a593Smuzhiyun {
1292*4882a593Smuzhiyun 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1293*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1294*4882a593Smuzhiyun 	struct device *jrdev = ctx->jrdev;
1295*4882a593Smuzhiyun 	struct caam_aead_req_ctx *rctx = aead_request_ctx(req);
1296*4882a593Smuzhiyun 	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
1297*4882a593Smuzhiyun 		       GFP_KERNEL : GFP_ATOMIC;
1298*4882a593Smuzhiyun 	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
1299*4882a593Smuzhiyun 	int src_len, dst_len = 0;
1300*4882a593Smuzhiyun 	struct aead_edesc *edesc;
1301*4882a593Smuzhiyun 	int sec4_sg_index, sec4_sg_len, sec4_sg_bytes;
1302*4882a593Smuzhiyun 	unsigned int authsize = ctx->authsize;
1303*4882a593Smuzhiyun 
1304*4882a593Smuzhiyun 	if (unlikely(req->dst != req->src)) {
1305*4882a593Smuzhiyun 		src_len = req->assoclen + req->cryptlen;
1306*4882a593Smuzhiyun 		dst_len = src_len + (encrypt ? authsize : (-authsize));
1307*4882a593Smuzhiyun 
1308*4882a593Smuzhiyun 		src_nents = sg_nents_for_len(req->src, src_len);
1309*4882a593Smuzhiyun 		if (unlikely(src_nents < 0)) {
1310*4882a593Smuzhiyun 			dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
1311*4882a593Smuzhiyun 				src_len);
1312*4882a593Smuzhiyun 			return ERR_PTR(src_nents);
1313*4882a593Smuzhiyun 		}
1314*4882a593Smuzhiyun 
1315*4882a593Smuzhiyun 		dst_nents = sg_nents_for_len(req->dst, dst_len);
1316*4882a593Smuzhiyun 		if (unlikely(dst_nents < 0)) {
1317*4882a593Smuzhiyun 			dev_err(jrdev, "Insufficient bytes (%d) in dst S/G\n",
1318*4882a593Smuzhiyun 				dst_len);
1319*4882a593Smuzhiyun 			return ERR_PTR(dst_nents);
1320*4882a593Smuzhiyun 		}
1321*4882a593Smuzhiyun 	} else {
1322*4882a593Smuzhiyun 		src_len = req->assoclen + req->cryptlen +
1323*4882a593Smuzhiyun 			  (encrypt ? authsize : 0);
1324*4882a593Smuzhiyun 
1325*4882a593Smuzhiyun 		src_nents = sg_nents_for_len(req->src, src_len);
1326*4882a593Smuzhiyun 		if (unlikely(src_nents < 0)) {
1327*4882a593Smuzhiyun 			dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
1328*4882a593Smuzhiyun 				src_len);
1329*4882a593Smuzhiyun 			return ERR_PTR(src_nents);
1330*4882a593Smuzhiyun 		}
1331*4882a593Smuzhiyun 	}
1332*4882a593Smuzhiyun 
1333*4882a593Smuzhiyun 	if (likely(req->src == req->dst)) {
1334*4882a593Smuzhiyun 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1335*4882a593Smuzhiyun 					      DMA_BIDIRECTIONAL);
1336*4882a593Smuzhiyun 		if (unlikely(!mapped_src_nents)) {
1337*4882a593Smuzhiyun 			dev_err(jrdev, "unable to map source\n");
1338*4882a593Smuzhiyun 			return ERR_PTR(-ENOMEM);
1339*4882a593Smuzhiyun 		}
1340*4882a593Smuzhiyun 	} else {
1341*4882a593Smuzhiyun 		/* Cover also the case of null (zero length) input data */
1342*4882a593Smuzhiyun 		if (src_nents) {
1343*4882a593Smuzhiyun 			mapped_src_nents = dma_map_sg(jrdev, req->src,
1344*4882a593Smuzhiyun 						      src_nents, DMA_TO_DEVICE);
1345*4882a593Smuzhiyun 			if (unlikely(!mapped_src_nents)) {
1346*4882a593Smuzhiyun 				dev_err(jrdev, "unable to map source\n");
1347*4882a593Smuzhiyun 				return ERR_PTR(-ENOMEM);
1348*4882a593Smuzhiyun 			}
1349*4882a593Smuzhiyun 		} else {
1350*4882a593Smuzhiyun 			mapped_src_nents = 0;
1351*4882a593Smuzhiyun 		}
1352*4882a593Smuzhiyun 
1353*4882a593Smuzhiyun 		/* Cover also the case of null (zero length) output data */
1354*4882a593Smuzhiyun 		if (dst_nents) {
1355*4882a593Smuzhiyun 			mapped_dst_nents = dma_map_sg(jrdev, req->dst,
1356*4882a593Smuzhiyun 						      dst_nents,
1357*4882a593Smuzhiyun 						      DMA_FROM_DEVICE);
1358*4882a593Smuzhiyun 			if (unlikely(!mapped_dst_nents)) {
1359*4882a593Smuzhiyun 				dev_err(jrdev, "unable to map destination\n");
1360*4882a593Smuzhiyun 				dma_unmap_sg(jrdev, req->src, src_nents,
1361*4882a593Smuzhiyun 					     DMA_TO_DEVICE);
1362*4882a593Smuzhiyun 				return ERR_PTR(-ENOMEM);
1363*4882a593Smuzhiyun 			}
1364*4882a593Smuzhiyun 		} else {
1365*4882a593Smuzhiyun 			mapped_dst_nents = 0;
1366*4882a593Smuzhiyun 		}
1367*4882a593Smuzhiyun 	}
1368*4882a593Smuzhiyun 
1369*4882a593Smuzhiyun 	/*
1370*4882a593Smuzhiyun 	 * HW reads 4 S/G entries at a time; make sure the reads don't go beyond
1371*4882a593Smuzhiyun 	 * the end of the table by allocating more S/G entries.
1372*4882a593Smuzhiyun 	 */
1373*4882a593Smuzhiyun 	sec4_sg_len = mapped_src_nents > 1 ? mapped_src_nents : 0;
1374*4882a593Smuzhiyun 	if (mapped_dst_nents > 1)
1375*4882a593Smuzhiyun 		sec4_sg_len += pad_sg_nents(mapped_dst_nents);
1376*4882a593Smuzhiyun 	else
1377*4882a593Smuzhiyun 		sec4_sg_len = pad_sg_nents(sec4_sg_len);
1378*4882a593Smuzhiyun 
1379*4882a593Smuzhiyun 	sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry);
1380*4882a593Smuzhiyun 
1381*4882a593Smuzhiyun 	/* allocate space for base edesc and hw desc commands, link tables */
1382*4882a593Smuzhiyun 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes,
1383*4882a593Smuzhiyun 			GFP_DMA | flags);
1384*4882a593Smuzhiyun 	if (!edesc) {
1385*4882a593Smuzhiyun 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
1386*4882a593Smuzhiyun 			   0, 0, 0);
1387*4882a593Smuzhiyun 		return ERR_PTR(-ENOMEM);
1388*4882a593Smuzhiyun 	}
1389*4882a593Smuzhiyun 
1390*4882a593Smuzhiyun 	edesc->src_nents = src_nents;
1391*4882a593Smuzhiyun 	edesc->dst_nents = dst_nents;
1392*4882a593Smuzhiyun 	edesc->mapped_src_nents = mapped_src_nents;
1393*4882a593Smuzhiyun 	edesc->mapped_dst_nents = mapped_dst_nents;
1394*4882a593Smuzhiyun 	edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) +
1395*4882a593Smuzhiyun 			 desc_bytes;
1396*4882a593Smuzhiyun 
1397*4882a593Smuzhiyun 	rctx->edesc = edesc;
1398*4882a593Smuzhiyun 
1399*4882a593Smuzhiyun 	*all_contig_ptr = !(mapped_src_nents > 1);
1400*4882a593Smuzhiyun 
1401*4882a593Smuzhiyun 	sec4_sg_index = 0;
1402*4882a593Smuzhiyun 	if (mapped_src_nents > 1) {
1403*4882a593Smuzhiyun 		sg_to_sec4_sg_last(req->src, src_len,
1404*4882a593Smuzhiyun 				   edesc->sec4_sg + sec4_sg_index, 0);
1405*4882a593Smuzhiyun 		sec4_sg_index += mapped_src_nents;
1406*4882a593Smuzhiyun 	}
1407*4882a593Smuzhiyun 	if (mapped_dst_nents > 1) {
1408*4882a593Smuzhiyun 		sg_to_sec4_sg_last(req->dst, dst_len,
1409*4882a593Smuzhiyun 				   edesc->sec4_sg + sec4_sg_index, 0);
1410*4882a593Smuzhiyun 	}
1411*4882a593Smuzhiyun 
1412*4882a593Smuzhiyun 	if (!sec4_sg_bytes)
1413*4882a593Smuzhiyun 		return edesc;
1414*4882a593Smuzhiyun 
1415*4882a593Smuzhiyun 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
1416*4882a593Smuzhiyun 					    sec4_sg_bytes, DMA_TO_DEVICE);
1417*4882a593Smuzhiyun 	if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
1418*4882a593Smuzhiyun 		dev_err(jrdev, "unable to map S/G table\n");
1419*4882a593Smuzhiyun 		aead_unmap(jrdev, edesc, req);
1420*4882a593Smuzhiyun 		kfree(edesc);
1421*4882a593Smuzhiyun 		return ERR_PTR(-ENOMEM);
1422*4882a593Smuzhiyun 	}
1423*4882a593Smuzhiyun 
1424*4882a593Smuzhiyun 	edesc->sec4_sg_bytes = sec4_sg_bytes;
1425*4882a593Smuzhiyun 
1426*4882a593Smuzhiyun 	return edesc;
1427*4882a593Smuzhiyun }
1428*4882a593Smuzhiyun 
aead_enqueue_req(struct device * jrdev,struct aead_request * req)1429*4882a593Smuzhiyun static int aead_enqueue_req(struct device *jrdev, struct aead_request *req)
1430*4882a593Smuzhiyun {
1431*4882a593Smuzhiyun 	struct caam_drv_private_jr *jrpriv = dev_get_drvdata(jrdev);
1432*4882a593Smuzhiyun 	struct caam_aead_req_ctx *rctx = aead_request_ctx(req);
1433*4882a593Smuzhiyun 	struct aead_edesc *edesc = rctx->edesc;
1434*4882a593Smuzhiyun 	u32 *desc = edesc->hw_desc;
1435*4882a593Smuzhiyun 	int ret;
1436*4882a593Smuzhiyun 
1437*4882a593Smuzhiyun 	/*
1438*4882a593Smuzhiyun 	 * Only the backlog request are sent to crypto-engine since the others
1439*4882a593Smuzhiyun 	 * can be handled by CAAM, if free, especially since JR has up to 1024
1440*4882a593Smuzhiyun 	 * entries (more than the 10 entries from crypto-engine).
1441*4882a593Smuzhiyun 	 */
1442*4882a593Smuzhiyun 	if (req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)
1443*4882a593Smuzhiyun 		ret = crypto_transfer_aead_request_to_engine(jrpriv->engine,
1444*4882a593Smuzhiyun 							     req);
1445*4882a593Smuzhiyun 	else
1446*4882a593Smuzhiyun 		ret = caam_jr_enqueue(jrdev, desc, aead_crypt_done, req);
1447*4882a593Smuzhiyun 
1448*4882a593Smuzhiyun 	if ((ret != -EINPROGRESS) && (ret != -EBUSY)) {
1449*4882a593Smuzhiyun 		aead_unmap(jrdev, edesc, req);
1450*4882a593Smuzhiyun 		kfree(rctx->edesc);
1451*4882a593Smuzhiyun 	}
1452*4882a593Smuzhiyun 
1453*4882a593Smuzhiyun 	return ret;
1454*4882a593Smuzhiyun }
1455*4882a593Smuzhiyun 
chachapoly_crypt(struct aead_request * req,bool encrypt)1456*4882a593Smuzhiyun static inline int chachapoly_crypt(struct aead_request *req, bool encrypt)
1457*4882a593Smuzhiyun {
1458*4882a593Smuzhiyun 	struct aead_edesc *edesc;
1459*4882a593Smuzhiyun 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1460*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1461*4882a593Smuzhiyun 	struct device *jrdev = ctx->jrdev;
1462*4882a593Smuzhiyun 	bool all_contig;
1463*4882a593Smuzhiyun 	u32 *desc;
1464*4882a593Smuzhiyun 
1465*4882a593Smuzhiyun 	edesc = aead_edesc_alloc(req, CHACHAPOLY_DESC_JOB_IO_LEN, &all_contig,
1466*4882a593Smuzhiyun 				 encrypt);
1467*4882a593Smuzhiyun 	if (IS_ERR(edesc))
1468*4882a593Smuzhiyun 		return PTR_ERR(edesc);
1469*4882a593Smuzhiyun 
1470*4882a593Smuzhiyun 	desc = edesc->hw_desc;
1471*4882a593Smuzhiyun 
1472*4882a593Smuzhiyun 	init_chachapoly_job(req, edesc, all_contig, encrypt);
1473*4882a593Smuzhiyun 	print_hex_dump_debug("chachapoly jobdesc@" __stringify(__LINE__)": ",
1474*4882a593Smuzhiyun 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1475*4882a593Smuzhiyun 			     1);
1476*4882a593Smuzhiyun 
1477*4882a593Smuzhiyun 	return aead_enqueue_req(jrdev, req);
1478*4882a593Smuzhiyun }
1479*4882a593Smuzhiyun 
chachapoly_encrypt(struct aead_request * req)1480*4882a593Smuzhiyun static int chachapoly_encrypt(struct aead_request *req)
1481*4882a593Smuzhiyun {
1482*4882a593Smuzhiyun 	return chachapoly_crypt(req, true);
1483*4882a593Smuzhiyun }
1484*4882a593Smuzhiyun 
chachapoly_decrypt(struct aead_request * req)1485*4882a593Smuzhiyun static int chachapoly_decrypt(struct aead_request *req)
1486*4882a593Smuzhiyun {
1487*4882a593Smuzhiyun 	return chachapoly_crypt(req, false);
1488*4882a593Smuzhiyun }
1489*4882a593Smuzhiyun 
aead_crypt(struct aead_request * req,bool encrypt)1490*4882a593Smuzhiyun static inline int aead_crypt(struct aead_request *req, bool encrypt)
1491*4882a593Smuzhiyun {
1492*4882a593Smuzhiyun 	struct aead_edesc *edesc;
1493*4882a593Smuzhiyun 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1494*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1495*4882a593Smuzhiyun 	struct device *jrdev = ctx->jrdev;
1496*4882a593Smuzhiyun 	bool all_contig;
1497*4882a593Smuzhiyun 
1498*4882a593Smuzhiyun 	/* allocate extended descriptor */
1499*4882a593Smuzhiyun 	edesc = aead_edesc_alloc(req, AUTHENC_DESC_JOB_IO_LEN,
1500*4882a593Smuzhiyun 				 &all_contig, encrypt);
1501*4882a593Smuzhiyun 	if (IS_ERR(edesc))
1502*4882a593Smuzhiyun 		return PTR_ERR(edesc);
1503*4882a593Smuzhiyun 
1504*4882a593Smuzhiyun 	/* Create and submit job descriptor */
1505*4882a593Smuzhiyun 	init_authenc_job(req, edesc, all_contig, encrypt);
1506*4882a593Smuzhiyun 
1507*4882a593Smuzhiyun 	print_hex_dump_debug("aead jobdesc@"__stringify(__LINE__)": ",
1508*4882a593Smuzhiyun 			     DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1509*4882a593Smuzhiyun 			     desc_bytes(edesc->hw_desc), 1);
1510*4882a593Smuzhiyun 
1511*4882a593Smuzhiyun 	return aead_enqueue_req(jrdev, req);
1512*4882a593Smuzhiyun }
1513*4882a593Smuzhiyun 
aead_encrypt(struct aead_request * req)1514*4882a593Smuzhiyun static int aead_encrypt(struct aead_request *req)
1515*4882a593Smuzhiyun {
1516*4882a593Smuzhiyun 	return aead_crypt(req, true);
1517*4882a593Smuzhiyun }
1518*4882a593Smuzhiyun 
aead_decrypt(struct aead_request * req)1519*4882a593Smuzhiyun static int aead_decrypt(struct aead_request *req)
1520*4882a593Smuzhiyun {
1521*4882a593Smuzhiyun 	return aead_crypt(req, false);
1522*4882a593Smuzhiyun }
1523*4882a593Smuzhiyun 
aead_do_one_req(struct crypto_engine * engine,void * areq)1524*4882a593Smuzhiyun static int aead_do_one_req(struct crypto_engine *engine, void *areq)
1525*4882a593Smuzhiyun {
1526*4882a593Smuzhiyun 	struct aead_request *req = aead_request_cast(areq);
1527*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
1528*4882a593Smuzhiyun 	struct caam_aead_req_ctx *rctx = aead_request_ctx(req);
1529*4882a593Smuzhiyun 	u32 *desc = rctx->edesc->hw_desc;
1530*4882a593Smuzhiyun 	int ret;
1531*4882a593Smuzhiyun 
1532*4882a593Smuzhiyun 	rctx->edesc->bklog = true;
1533*4882a593Smuzhiyun 
1534*4882a593Smuzhiyun 	ret = caam_jr_enqueue(ctx->jrdev, desc, aead_crypt_done, req);
1535*4882a593Smuzhiyun 
1536*4882a593Smuzhiyun 	if (ret != -EINPROGRESS) {
1537*4882a593Smuzhiyun 		aead_unmap(ctx->jrdev, rctx->edesc, req);
1538*4882a593Smuzhiyun 		kfree(rctx->edesc);
1539*4882a593Smuzhiyun 	} else {
1540*4882a593Smuzhiyun 		ret = 0;
1541*4882a593Smuzhiyun 	}
1542*4882a593Smuzhiyun 
1543*4882a593Smuzhiyun 	return ret;
1544*4882a593Smuzhiyun }
1545*4882a593Smuzhiyun 
gcm_crypt(struct aead_request * req,bool encrypt)1546*4882a593Smuzhiyun static inline int gcm_crypt(struct aead_request *req, bool encrypt)
1547*4882a593Smuzhiyun {
1548*4882a593Smuzhiyun 	struct aead_edesc *edesc;
1549*4882a593Smuzhiyun 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1550*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1551*4882a593Smuzhiyun 	struct device *jrdev = ctx->jrdev;
1552*4882a593Smuzhiyun 	bool all_contig;
1553*4882a593Smuzhiyun 
1554*4882a593Smuzhiyun 	/* allocate extended descriptor */
1555*4882a593Smuzhiyun 	edesc = aead_edesc_alloc(req, GCM_DESC_JOB_IO_LEN, &all_contig,
1556*4882a593Smuzhiyun 				 encrypt);
1557*4882a593Smuzhiyun 	if (IS_ERR(edesc))
1558*4882a593Smuzhiyun 		return PTR_ERR(edesc);
1559*4882a593Smuzhiyun 
1560*4882a593Smuzhiyun 	/* Create and submit job descriptor */
1561*4882a593Smuzhiyun 	init_gcm_job(req, edesc, all_contig, encrypt);
1562*4882a593Smuzhiyun 
1563*4882a593Smuzhiyun 	print_hex_dump_debug("aead jobdesc@"__stringify(__LINE__)": ",
1564*4882a593Smuzhiyun 			     DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1565*4882a593Smuzhiyun 			     desc_bytes(edesc->hw_desc), 1);
1566*4882a593Smuzhiyun 
1567*4882a593Smuzhiyun 	return aead_enqueue_req(jrdev, req);
1568*4882a593Smuzhiyun }
1569*4882a593Smuzhiyun 
gcm_encrypt(struct aead_request * req)1570*4882a593Smuzhiyun static int gcm_encrypt(struct aead_request *req)
1571*4882a593Smuzhiyun {
1572*4882a593Smuzhiyun 	return gcm_crypt(req, true);
1573*4882a593Smuzhiyun }
1574*4882a593Smuzhiyun 
gcm_decrypt(struct aead_request * req)1575*4882a593Smuzhiyun static int gcm_decrypt(struct aead_request *req)
1576*4882a593Smuzhiyun {
1577*4882a593Smuzhiyun 	return gcm_crypt(req, false);
1578*4882a593Smuzhiyun }
1579*4882a593Smuzhiyun 
ipsec_gcm_encrypt(struct aead_request * req)1580*4882a593Smuzhiyun static int ipsec_gcm_encrypt(struct aead_request *req)
1581*4882a593Smuzhiyun {
1582*4882a593Smuzhiyun 	return crypto_ipsec_check_assoclen(req->assoclen) ? : gcm_encrypt(req);
1583*4882a593Smuzhiyun }
1584*4882a593Smuzhiyun 
ipsec_gcm_decrypt(struct aead_request * req)1585*4882a593Smuzhiyun static int ipsec_gcm_decrypt(struct aead_request *req)
1586*4882a593Smuzhiyun {
1587*4882a593Smuzhiyun 	return crypto_ipsec_check_assoclen(req->assoclen) ? : gcm_decrypt(req);
1588*4882a593Smuzhiyun }
1589*4882a593Smuzhiyun 
1590*4882a593Smuzhiyun /*
1591*4882a593Smuzhiyun  * allocate and map the skcipher extended descriptor for skcipher
1592*4882a593Smuzhiyun  */
skcipher_edesc_alloc(struct skcipher_request * req,int desc_bytes)1593*4882a593Smuzhiyun static struct skcipher_edesc *skcipher_edesc_alloc(struct skcipher_request *req,
1594*4882a593Smuzhiyun 						   int desc_bytes)
1595*4882a593Smuzhiyun {
1596*4882a593Smuzhiyun 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
1597*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
1598*4882a593Smuzhiyun 	struct caam_skcipher_req_ctx *rctx = skcipher_request_ctx(req);
1599*4882a593Smuzhiyun 	struct device *jrdev = ctx->jrdev;
1600*4882a593Smuzhiyun 	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
1601*4882a593Smuzhiyun 		       GFP_KERNEL : GFP_ATOMIC;
1602*4882a593Smuzhiyun 	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
1603*4882a593Smuzhiyun 	struct skcipher_edesc *edesc;
1604*4882a593Smuzhiyun 	dma_addr_t iv_dma = 0;
1605*4882a593Smuzhiyun 	u8 *iv;
1606*4882a593Smuzhiyun 	int ivsize = crypto_skcipher_ivsize(skcipher);
1607*4882a593Smuzhiyun 	int dst_sg_idx, sec4_sg_ents, sec4_sg_bytes;
1608*4882a593Smuzhiyun 
1609*4882a593Smuzhiyun 	src_nents = sg_nents_for_len(req->src, req->cryptlen);
1610*4882a593Smuzhiyun 	if (unlikely(src_nents < 0)) {
1611*4882a593Smuzhiyun 		dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
1612*4882a593Smuzhiyun 			req->cryptlen);
1613*4882a593Smuzhiyun 		return ERR_PTR(src_nents);
1614*4882a593Smuzhiyun 	}
1615*4882a593Smuzhiyun 
1616*4882a593Smuzhiyun 	if (req->dst != req->src) {
1617*4882a593Smuzhiyun 		dst_nents = sg_nents_for_len(req->dst, req->cryptlen);
1618*4882a593Smuzhiyun 		if (unlikely(dst_nents < 0)) {
1619*4882a593Smuzhiyun 			dev_err(jrdev, "Insufficient bytes (%d) in dst S/G\n",
1620*4882a593Smuzhiyun 				req->cryptlen);
1621*4882a593Smuzhiyun 			return ERR_PTR(dst_nents);
1622*4882a593Smuzhiyun 		}
1623*4882a593Smuzhiyun 	}
1624*4882a593Smuzhiyun 
1625*4882a593Smuzhiyun 	if (likely(req->src == req->dst)) {
1626*4882a593Smuzhiyun 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1627*4882a593Smuzhiyun 					      DMA_BIDIRECTIONAL);
1628*4882a593Smuzhiyun 		if (unlikely(!mapped_src_nents)) {
1629*4882a593Smuzhiyun 			dev_err(jrdev, "unable to map source\n");
1630*4882a593Smuzhiyun 			return ERR_PTR(-ENOMEM);
1631*4882a593Smuzhiyun 		}
1632*4882a593Smuzhiyun 	} else {
1633*4882a593Smuzhiyun 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1634*4882a593Smuzhiyun 					      DMA_TO_DEVICE);
1635*4882a593Smuzhiyun 		if (unlikely(!mapped_src_nents)) {
1636*4882a593Smuzhiyun 			dev_err(jrdev, "unable to map source\n");
1637*4882a593Smuzhiyun 			return ERR_PTR(-ENOMEM);
1638*4882a593Smuzhiyun 		}
1639*4882a593Smuzhiyun 		mapped_dst_nents = dma_map_sg(jrdev, req->dst, dst_nents,
1640*4882a593Smuzhiyun 					      DMA_FROM_DEVICE);
1641*4882a593Smuzhiyun 		if (unlikely(!mapped_dst_nents)) {
1642*4882a593Smuzhiyun 			dev_err(jrdev, "unable to map destination\n");
1643*4882a593Smuzhiyun 			dma_unmap_sg(jrdev, req->src, src_nents, DMA_TO_DEVICE);
1644*4882a593Smuzhiyun 			return ERR_PTR(-ENOMEM);
1645*4882a593Smuzhiyun 		}
1646*4882a593Smuzhiyun 	}
1647*4882a593Smuzhiyun 
1648*4882a593Smuzhiyun 	if (!ivsize && mapped_src_nents == 1)
1649*4882a593Smuzhiyun 		sec4_sg_ents = 0; // no need for an input hw s/g table
1650*4882a593Smuzhiyun 	else
1651*4882a593Smuzhiyun 		sec4_sg_ents = mapped_src_nents + !!ivsize;
1652*4882a593Smuzhiyun 	dst_sg_idx = sec4_sg_ents;
1653*4882a593Smuzhiyun 
1654*4882a593Smuzhiyun 	/*
1655*4882a593Smuzhiyun 	 * Input, output HW S/G tables: [IV, src][dst, IV]
1656*4882a593Smuzhiyun 	 * IV entries point to the same buffer
1657*4882a593Smuzhiyun 	 * If src == dst, S/G entries are reused (S/G tables overlap)
1658*4882a593Smuzhiyun 	 *
1659*4882a593Smuzhiyun 	 * HW reads 4 S/G entries at a time; make sure the reads don't go beyond
1660*4882a593Smuzhiyun 	 * the end of the table by allocating more S/G entries. Logic:
1661*4882a593Smuzhiyun 	 * if (output S/G)
1662*4882a593Smuzhiyun 	 *      pad output S/G, if needed
1663*4882a593Smuzhiyun 	 * else if (input S/G) ...
1664*4882a593Smuzhiyun 	 *      pad input S/G, if needed
1665*4882a593Smuzhiyun 	 */
1666*4882a593Smuzhiyun 	if (ivsize || mapped_dst_nents > 1) {
1667*4882a593Smuzhiyun 		if (req->src == req->dst)
1668*4882a593Smuzhiyun 			sec4_sg_ents = !!ivsize + pad_sg_nents(sec4_sg_ents);
1669*4882a593Smuzhiyun 		else
1670*4882a593Smuzhiyun 			sec4_sg_ents += pad_sg_nents(mapped_dst_nents +
1671*4882a593Smuzhiyun 						     !!ivsize);
1672*4882a593Smuzhiyun 	} else {
1673*4882a593Smuzhiyun 		sec4_sg_ents = pad_sg_nents(sec4_sg_ents);
1674*4882a593Smuzhiyun 	}
1675*4882a593Smuzhiyun 
1676*4882a593Smuzhiyun 	sec4_sg_bytes = sec4_sg_ents * sizeof(struct sec4_sg_entry);
1677*4882a593Smuzhiyun 
1678*4882a593Smuzhiyun 	/*
1679*4882a593Smuzhiyun 	 * allocate space for base edesc and hw desc commands, link tables, IV
1680*4882a593Smuzhiyun 	 */
1681*4882a593Smuzhiyun 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes + ivsize,
1682*4882a593Smuzhiyun 			GFP_DMA | flags);
1683*4882a593Smuzhiyun 	if (!edesc) {
1684*4882a593Smuzhiyun 		dev_err(jrdev, "could not allocate extended descriptor\n");
1685*4882a593Smuzhiyun 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
1686*4882a593Smuzhiyun 			   0, 0, 0);
1687*4882a593Smuzhiyun 		return ERR_PTR(-ENOMEM);
1688*4882a593Smuzhiyun 	}
1689*4882a593Smuzhiyun 
1690*4882a593Smuzhiyun 	edesc->src_nents = src_nents;
1691*4882a593Smuzhiyun 	edesc->dst_nents = dst_nents;
1692*4882a593Smuzhiyun 	edesc->mapped_src_nents = mapped_src_nents;
1693*4882a593Smuzhiyun 	edesc->mapped_dst_nents = mapped_dst_nents;
1694*4882a593Smuzhiyun 	edesc->sec4_sg_bytes = sec4_sg_bytes;
1695*4882a593Smuzhiyun 	edesc->sec4_sg = (struct sec4_sg_entry *)((u8 *)edesc->hw_desc +
1696*4882a593Smuzhiyun 						  desc_bytes);
1697*4882a593Smuzhiyun 	rctx->edesc = edesc;
1698*4882a593Smuzhiyun 
1699*4882a593Smuzhiyun 	/* Make sure IV is located in a DMAable area */
1700*4882a593Smuzhiyun 	if (ivsize) {
1701*4882a593Smuzhiyun 		iv = (u8 *)edesc->sec4_sg + sec4_sg_bytes;
1702*4882a593Smuzhiyun 		memcpy(iv, req->iv, ivsize);
1703*4882a593Smuzhiyun 
1704*4882a593Smuzhiyun 		iv_dma = dma_map_single(jrdev, iv, ivsize, DMA_BIDIRECTIONAL);
1705*4882a593Smuzhiyun 		if (dma_mapping_error(jrdev, iv_dma)) {
1706*4882a593Smuzhiyun 			dev_err(jrdev, "unable to map IV\n");
1707*4882a593Smuzhiyun 			caam_unmap(jrdev, req->src, req->dst, src_nents,
1708*4882a593Smuzhiyun 				   dst_nents, 0, 0, 0, 0);
1709*4882a593Smuzhiyun 			kfree(edesc);
1710*4882a593Smuzhiyun 			return ERR_PTR(-ENOMEM);
1711*4882a593Smuzhiyun 		}
1712*4882a593Smuzhiyun 
1713*4882a593Smuzhiyun 		dma_to_sec4_sg_one(edesc->sec4_sg, iv_dma, ivsize, 0);
1714*4882a593Smuzhiyun 	}
1715*4882a593Smuzhiyun 	if (dst_sg_idx)
1716*4882a593Smuzhiyun 		sg_to_sec4_sg(req->src, req->cryptlen, edesc->sec4_sg +
1717*4882a593Smuzhiyun 			      !!ivsize, 0);
1718*4882a593Smuzhiyun 
1719*4882a593Smuzhiyun 	if (req->src != req->dst && (ivsize || mapped_dst_nents > 1))
1720*4882a593Smuzhiyun 		sg_to_sec4_sg(req->dst, req->cryptlen, edesc->sec4_sg +
1721*4882a593Smuzhiyun 			      dst_sg_idx, 0);
1722*4882a593Smuzhiyun 
1723*4882a593Smuzhiyun 	if (ivsize)
1724*4882a593Smuzhiyun 		dma_to_sec4_sg_one(edesc->sec4_sg + dst_sg_idx +
1725*4882a593Smuzhiyun 				   mapped_dst_nents, iv_dma, ivsize, 0);
1726*4882a593Smuzhiyun 
1727*4882a593Smuzhiyun 	if (ivsize || mapped_dst_nents > 1)
1728*4882a593Smuzhiyun 		sg_to_sec4_set_last(edesc->sec4_sg + dst_sg_idx +
1729*4882a593Smuzhiyun 				    mapped_dst_nents - 1 + !!ivsize);
1730*4882a593Smuzhiyun 
1731*4882a593Smuzhiyun 	if (sec4_sg_bytes) {
1732*4882a593Smuzhiyun 		edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
1733*4882a593Smuzhiyun 						    sec4_sg_bytes,
1734*4882a593Smuzhiyun 						    DMA_TO_DEVICE);
1735*4882a593Smuzhiyun 		if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
1736*4882a593Smuzhiyun 			dev_err(jrdev, "unable to map S/G table\n");
1737*4882a593Smuzhiyun 			caam_unmap(jrdev, req->src, req->dst, src_nents,
1738*4882a593Smuzhiyun 				   dst_nents, iv_dma, ivsize, 0, 0);
1739*4882a593Smuzhiyun 			kfree(edesc);
1740*4882a593Smuzhiyun 			return ERR_PTR(-ENOMEM);
1741*4882a593Smuzhiyun 		}
1742*4882a593Smuzhiyun 	}
1743*4882a593Smuzhiyun 
1744*4882a593Smuzhiyun 	edesc->iv_dma = iv_dma;
1745*4882a593Smuzhiyun 
1746*4882a593Smuzhiyun 	print_hex_dump_debug("skcipher sec4_sg@" __stringify(__LINE__)": ",
1747*4882a593Smuzhiyun 			     DUMP_PREFIX_ADDRESS, 16, 4, edesc->sec4_sg,
1748*4882a593Smuzhiyun 			     sec4_sg_bytes, 1);
1749*4882a593Smuzhiyun 
1750*4882a593Smuzhiyun 	return edesc;
1751*4882a593Smuzhiyun }
1752*4882a593Smuzhiyun 
skcipher_do_one_req(struct crypto_engine * engine,void * areq)1753*4882a593Smuzhiyun static int skcipher_do_one_req(struct crypto_engine *engine, void *areq)
1754*4882a593Smuzhiyun {
1755*4882a593Smuzhiyun 	struct skcipher_request *req = skcipher_request_cast(areq);
1756*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_skcipher_ctx(crypto_skcipher_reqtfm(req));
1757*4882a593Smuzhiyun 	struct caam_skcipher_req_ctx *rctx = skcipher_request_ctx(req);
1758*4882a593Smuzhiyun 	u32 *desc = rctx->edesc->hw_desc;
1759*4882a593Smuzhiyun 	int ret;
1760*4882a593Smuzhiyun 
1761*4882a593Smuzhiyun 	rctx->edesc->bklog = true;
1762*4882a593Smuzhiyun 
1763*4882a593Smuzhiyun 	ret = caam_jr_enqueue(ctx->jrdev, desc, skcipher_crypt_done, req);
1764*4882a593Smuzhiyun 
1765*4882a593Smuzhiyun 	if (ret != -EINPROGRESS) {
1766*4882a593Smuzhiyun 		skcipher_unmap(ctx->jrdev, rctx->edesc, req);
1767*4882a593Smuzhiyun 		kfree(rctx->edesc);
1768*4882a593Smuzhiyun 	} else {
1769*4882a593Smuzhiyun 		ret = 0;
1770*4882a593Smuzhiyun 	}
1771*4882a593Smuzhiyun 
1772*4882a593Smuzhiyun 	return ret;
1773*4882a593Smuzhiyun }
1774*4882a593Smuzhiyun 
xts_skcipher_ivsize(struct skcipher_request * req)1775*4882a593Smuzhiyun static inline bool xts_skcipher_ivsize(struct skcipher_request *req)
1776*4882a593Smuzhiyun {
1777*4882a593Smuzhiyun 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
1778*4882a593Smuzhiyun 	unsigned int ivsize = crypto_skcipher_ivsize(skcipher);
1779*4882a593Smuzhiyun 
1780*4882a593Smuzhiyun 	return !!get_unaligned((u64 *)(req->iv + (ivsize / 2)));
1781*4882a593Smuzhiyun }
1782*4882a593Smuzhiyun 
skcipher_crypt(struct skcipher_request * req,bool encrypt)1783*4882a593Smuzhiyun static inline int skcipher_crypt(struct skcipher_request *req, bool encrypt)
1784*4882a593Smuzhiyun {
1785*4882a593Smuzhiyun 	struct skcipher_edesc *edesc;
1786*4882a593Smuzhiyun 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
1787*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
1788*4882a593Smuzhiyun 	struct device *jrdev = ctx->jrdev;
1789*4882a593Smuzhiyun 	struct caam_drv_private_jr *jrpriv = dev_get_drvdata(jrdev);
1790*4882a593Smuzhiyun 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
1791*4882a593Smuzhiyun 	u32 *desc;
1792*4882a593Smuzhiyun 	int ret = 0;
1793*4882a593Smuzhiyun 
1794*4882a593Smuzhiyun 	/*
1795*4882a593Smuzhiyun 	 * XTS is expected to return an error even for input length = 0
1796*4882a593Smuzhiyun 	 * Note that the case input length < block size will be caught during
1797*4882a593Smuzhiyun 	 * HW offloading and return an error.
1798*4882a593Smuzhiyun 	 */
1799*4882a593Smuzhiyun 	if (!req->cryptlen && !ctx->fallback)
1800*4882a593Smuzhiyun 		return 0;
1801*4882a593Smuzhiyun 
1802*4882a593Smuzhiyun 	if (ctx->fallback && ((ctrlpriv->era <= 8 && xts_skcipher_ivsize(req)) ||
1803*4882a593Smuzhiyun 			      ctx->xts_key_fallback)) {
1804*4882a593Smuzhiyun 		struct caam_skcipher_req_ctx *rctx = skcipher_request_ctx(req);
1805*4882a593Smuzhiyun 
1806*4882a593Smuzhiyun 		skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback);
1807*4882a593Smuzhiyun 		skcipher_request_set_callback(&rctx->fallback_req,
1808*4882a593Smuzhiyun 					      req->base.flags,
1809*4882a593Smuzhiyun 					      req->base.complete,
1810*4882a593Smuzhiyun 					      req->base.data);
1811*4882a593Smuzhiyun 		skcipher_request_set_crypt(&rctx->fallback_req, req->src,
1812*4882a593Smuzhiyun 					   req->dst, req->cryptlen, req->iv);
1813*4882a593Smuzhiyun 
1814*4882a593Smuzhiyun 		return encrypt ? crypto_skcipher_encrypt(&rctx->fallback_req) :
1815*4882a593Smuzhiyun 				 crypto_skcipher_decrypt(&rctx->fallback_req);
1816*4882a593Smuzhiyun 	}
1817*4882a593Smuzhiyun 
1818*4882a593Smuzhiyun 	/* allocate extended descriptor */
1819*4882a593Smuzhiyun 	edesc = skcipher_edesc_alloc(req, DESC_JOB_IO_LEN * CAAM_CMD_SZ);
1820*4882a593Smuzhiyun 	if (IS_ERR(edesc))
1821*4882a593Smuzhiyun 		return PTR_ERR(edesc);
1822*4882a593Smuzhiyun 
1823*4882a593Smuzhiyun 	/* Create and submit job descriptor*/
1824*4882a593Smuzhiyun 	init_skcipher_job(req, edesc, encrypt);
1825*4882a593Smuzhiyun 
1826*4882a593Smuzhiyun 	print_hex_dump_debug("skcipher jobdesc@" __stringify(__LINE__)": ",
1827*4882a593Smuzhiyun 			     DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1828*4882a593Smuzhiyun 			     desc_bytes(edesc->hw_desc), 1);
1829*4882a593Smuzhiyun 
1830*4882a593Smuzhiyun 	desc = edesc->hw_desc;
1831*4882a593Smuzhiyun 	/*
1832*4882a593Smuzhiyun 	 * Only the backlog request are sent to crypto-engine since the others
1833*4882a593Smuzhiyun 	 * can be handled by CAAM, if free, especially since JR has up to 1024
1834*4882a593Smuzhiyun 	 * entries (more than the 10 entries from crypto-engine).
1835*4882a593Smuzhiyun 	 */
1836*4882a593Smuzhiyun 	if (req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)
1837*4882a593Smuzhiyun 		ret = crypto_transfer_skcipher_request_to_engine(jrpriv->engine,
1838*4882a593Smuzhiyun 								 req);
1839*4882a593Smuzhiyun 	else
1840*4882a593Smuzhiyun 		ret = caam_jr_enqueue(jrdev, desc, skcipher_crypt_done, req);
1841*4882a593Smuzhiyun 
1842*4882a593Smuzhiyun 	if ((ret != -EINPROGRESS) && (ret != -EBUSY)) {
1843*4882a593Smuzhiyun 		skcipher_unmap(jrdev, edesc, req);
1844*4882a593Smuzhiyun 		kfree(edesc);
1845*4882a593Smuzhiyun 	}
1846*4882a593Smuzhiyun 
1847*4882a593Smuzhiyun 	return ret;
1848*4882a593Smuzhiyun }
1849*4882a593Smuzhiyun 
skcipher_encrypt(struct skcipher_request * req)1850*4882a593Smuzhiyun static int skcipher_encrypt(struct skcipher_request *req)
1851*4882a593Smuzhiyun {
1852*4882a593Smuzhiyun 	return skcipher_crypt(req, true);
1853*4882a593Smuzhiyun }
1854*4882a593Smuzhiyun 
skcipher_decrypt(struct skcipher_request * req)1855*4882a593Smuzhiyun static int skcipher_decrypt(struct skcipher_request *req)
1856*4882a593Smuzhiyun {
1857*4882a593Smuzhiyun 	return skcipher_crypt(req, false);
1858*4882a593Smuzhiyun }
1859*4882a593Smuzhiyun 
1860*4882a593Smuzhiyun static struct caam_skcipher_alg driver_algs[] = {
1861*4882a593Smuzhiyun 	{
1862*4882a593Smuzhiyun 		.skcipher = {
1863*4882a593Smuzhiyun 			.base = {
1864*4882a593Smuzhiyun 				.cra_name = "cbc(aes)",
1865*4882a593Smuzhiyun 				.cra_driver_name = "cbc-aes-caam",
1866*4882a593Smuzhiyun 				.cra_blocksize = AES_BLOCK_SIZE,
1867*4882a593Smuzhiyun 			},
1868*4882a593Smuzhiyun 			.setkey = aes_skcipher_setkey,
1869*4882a593Smuzhiyun 			.encrypt = skcipher_encrypt,
1870*4882a593Smuzhiyun 			.decrypt = skcipher_decrypt,
1871*4882a593Smuzhiyun 			.min_keysize = AES_MIN_KEY_SIZE,
1872*4882a593Smuzhiyun 			.max_keysize = AES_MAX_KEY_SIZE,
1873*4882a593Smuzhiyun 			.ivsize = AES_BLOCK_SIZE,
1874*4882a593Smuzhiyun 		},
1875*4882a593Smuzhiyun 		.caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
1876*4882a593Smuzhiyun 	},
1877*4882a593Smuzhiyun 	{
1878*4882a593Smuzhiyun 		.skcipher = {
1879*4882a593Smuzhiyun 			.base = {
1880*4882a593Smuzhiyun 				.cra_name = "cbc(des3_ede)",
1881*4882a593Smuzhiyun 				.cra_driver_name = "cbc-3des-caam",
1882*4882a593Smuzhiyun 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
1883*4882a593Smuzhiyun 			},
1884*4882a593Smuzhiyun 			.setkey = des3_skcipher_setkey,
1885*4882a593Smuzhiyun 			.encrypt = skcipher_encrypt,
1886*4882a593Smuzhiyun 			.decrypt = skcipher_decrypt,
1887*4882a593Smuzhiyun 			.min_keysize = DES3_EDE_KEY_SIZE,
1888*4882a593Smuzhiyun 			.max_keysize = DES3_EDE_KEY_SIZE,
1889*4882a593Smuzhiyun 			.ivsize = DES3_EDE_BLOCK_SIZE,
1890*4882a593Smuzhiyun 		},
1891*4882a593Smuzhiyun 		.caam.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
1892*4882a593Smuzhiyun 	},
1893*4882a593Smuzhiyun 	{
1894*4882a593Smuzhiyun 		.skcipher = {
1895*4882a593Smuzhiyun 			.base = {
1896*4882a593Smuzhiyun 				.cra_name = "cbc(des)",
1897*4882a593Smuzhiyun 				.cra_driver_name = "cbc-des-caam",
1898*4882a593Smuzhiyun 				.cra_blocksize = DES_BLOCK_SIZE,
1899*4882a593Smuzhiyun 			},
1900*4882a593Smuzhiyun 			.setkey = des_skcipher_setkey,
1901*4882a593Smuzhiyun 			.encrypt = skcipher_encrypt,
1902*4882a593Smuzhiyun 			.decrypt = skcipher_decrypt,
1903*4882a593Smuzhiyun 			.min_keysize = DES_KEY_SIZE,
1904*4882a593Smuzhiyun 			.max_keysize = DES_KEY_SIZE,
1905*4882a593Smuzhiyun 			.ivsize = DES_BLOCK_SIZE,
1906*4882a593Smuzhiyun 		},
1907*4882a593Smuzhiyun 		.caam.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
1908*4882a593Smuzhiyun 	},
1909*4882a593Smuzhiyun 	{
1910*4882a593Smuzhiyun 		.skcipher = {
1911*4882a593Smuzhiyun 			.base = {
1912*4882a593Smuzhiyun 				.cra_name = "ctr(aes)",
1913*4882a593Smuzhiyun 				.cra_driver_name = "ctr-aes-caam",
1914*4882a593Smuzhiyun 				.cra_blocksize = 1,
1915*4882a593Smuzhiyun 			},
1916*4882a593Smuzhiyun 			.setkey = ctr_skcipher_setkey,
1917*4882a593Smuzhiyun 			.encrypt = skcipher_encrypt,
1918*4882a593Smuzhiyun 			.decrypt = skcipher_decrypt,
1919*4882a593Smuzhiyun 			.min_keysize = AES_MIN_KEY_SIZE,
1920*4882a593Smuzhiyun 			.max_keysize = AES_MAX_KEY_SIZE,
1921*4882a593Smuzhiyun 			.ivsize = AES_BLOCK_SIZE,
1922*4882a593Smuzhiyun 			.chunksize = AES_BLOCK_SIZE,
1923*4882a593Smuzhiyun 		},
1924*4882a593Smuzhiyun 		.caam.class1_alg_type = OP_ALG_ALGSEL_AES |
1925*4882a593Smuzhiyun 					OP_ALG_AAI_CTR_MOD128,
1926*4882a593Smuzhiyun 	},
1927*4882a593Smuzhiyun 	{
1928*4882a593Smuzhiyun 		.skcipher = {
1929*4882a593Smuzhiyun 			.base = {
1930*4882a593Smuzhiyun 				.cra_name = "rfc3686(ctr(aes))",
1931*4882a593Smuzhiyun 				.cra_driver_name = "rfc3686-ctr-aes-caam",
1932*4882a593Smuzhiyun 				.cra_blocksize = 1,
1933*4882a593Smuzhiyun 			},
1934*4882a593Smuzhiyun 			.setkey = rfc3686_skcipher_setkey,
1935*4882a593Smuzhiyun 			.encrypt = skcipher_encrypt,
1936*4882a593Smuzhiyun 			.decrypt = skcipher_decrypt,
1937*4882a593Smuzhiyun 			.min_keysize = AES_MIN_KEY_SIZE +
1938*4882a593Smuzhiyun 				       CTR_RFC3686_NONCE_SIZE,
1939*4882a593Smuzhiyun 			.max_keysize = AES_MAX_KEY_SIZE +
1940*4882a593Smuzhiyun 				       CTR_RFC3686_NONCE_SIZE,
1941*4882a593Smuzhiyun 			.ivsize = CTR_RFC3686_IV_SIZE,
1942*4882a593Smuzhiyun 			.chunksize = AES_BLOCK_SIZE,
1943*4882a593Smuzhiyun 		},
1944*4882a593Smuzhiyun 		.caam = {
1945*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES |
1946*4882a593Smuzhiyun 					   OP_ALG_AAI_CTR_MOD128,
1947*4882a593Smuzhiyun 			.rfc3686 = true,
1948*4882a593Smuzhiyun 		},
1949*4882a593Smuzhiyun 	},
1950*4882a593Smuzhiyun 	{
1951*4882a593Smuzhiyun 		.skcipher = {
1952*4882a593Smuzhiyun 			.base = {
1953*4882a593Smuzhiyun 				.cra_name = "xts(aes)",
1954*4882a593Smuzhiyun 				.cra_driver_name = "xts-aes-caam",
1955*4882a593Smuzhiyun 				.cra_flags = CRYPTO_ALG_NEED_FALLBACK,
1956*4882a593Smuzhiyun 				.cra_blocksize = AES_BLOCK_SIZE,
1957*4882a593Smuzhiyun 			},
1958*4882a593Smuzhiyun 			.setkey = xts_skcipher_setkey,
1959*4882a593Smuzhiyun 			.encrypt = skcipher_encrypt,
1960*4882a593Smuzhiyun 			.decrypt = skcipher_decrypt,
1961*4882a593Smuzhiyun 			.min_keysize = 2 * AES_MIN_KEY_SIZE,
1962*4882a593Smuzhiyun 			.max_keysize = 2 * AES_MAX_KEY_SIZE,
1963*4882a593Smuzhiyun 			.ivsize = AES_BLOCK_SIZE,
1964*4882a593Smuzhiyun 		},
1965*4882a593Smuzhiyun 		.caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_XTS,
1966*4882a593Smuzhiyun 	},
1967*4882a593Smuzhiyun 	{
1968*4882a593Smuzhiyun 		.skcipher = {
1969*4882a593Smuzhiyun 			.base = {
1970*4882a593Smuzhiyun 				.cra_name = "ecb(des)",
1971*4882a593Smuzhiyun 				.cra_driver_name = "ecb-des-caam",
1972*4882a593Smuzhiyun 				.cra_blocksize = DES_BLOCK_SIZE,
1973*4882a593Smuzhiyun 			},
1974*4882a593Smuzhiyun 			.setkey = des_skcipher_setkey,
1975*4882a593Smuzhiyun 			.encrypt = skcipher_encrypt,
1976*4882a593Smuzhiyun 			.decrypt = skcipher_decrypt,
1977*4882a593Smuzhiyun 			.min_keysize = DES_KEY_SIZE,
1978*4882a593Smuzhiyun 			.max_keysize = DES_KEY_SIZE,
1979*4882a593Smuzhiyun 		},
1980*4882a593Smuzhiyun 		.caam.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_ECB,
1981*4882a593Smuzhiyun 	},
1982*4882a593Smuzhiyun 	{
1983*4882a593Smuzhiyun 		.skcipher = {
1984*4882a593Smuzhiyun 			.base = {
1985*4882a593Smuzhiyun 				.cra_name = "ecb(aes)",
1986*4882a593Smuzhiyun 				.cra_driver_name = "ecb-aes-caam",
1987*4882a593Smuzhiyun 				.cra_blocksize = AES_BLOCK_SIZE,
1988*4882a593Smuzhiyun 			},
1989*4882a593Smuzhiyun 			.setkey = aes_skcipher_setkey,
1990*4882a593Smuzhiyun 			.encrypt = skcipher_encrypt,
1991*4882a593Smuzhiyun 			.decrypt = skcipher_decrypt,
1992*4882a593Smuzhiyun 			.min_keysize = AES_MIN_KEY_SIZE,
1993*4882a593Smuzhiyun 			.max_keysize = AES_MAX_KEY_SIZE,
1994*4882a593Smuzhiyun 		},
1995*4882a593Smuzhiyun 		.caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_ECB,
1996*4882a593Smuzhiyun 	},
1997*4882a593Smuzhiyun 	{
1998*4882a593Smuzhiyun 		.skcipher = {
1999*4882a593Smuzhiyun 			.base = {
2000*4882a593Smuzhiyun 				.cra_name = "ecb(des3_ede)",
2001*4882a593Smuzhiyun 				.cra_driver_name = "ecb-des3-caam",
2002*4882a593Smuzhiyun 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2003*4882a593Smuzhiyun 			},
2004*4882a593Smuzhiyun 			.setkey = des3_skcipher_setkey,
2005*4882a593Smuzhiyun 			.encrypt = skcipher_encrypt,
2006*4882a593Smuzhiyun 			.decrypt = skcipher_decrypt,
2007*4882a593Smuzhiyun 			.min_keysize = DES3_EDE_KEY_SIZE,
2008*4882a593Smuzhiyun 			.max_keysize = DES3_EDE_KEY_SIZE,
2009*4882a593Smuzhiyun 		},
2010*4882a593Smuzhiyun 		.caam.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_ECB,
2011*4882a593Smuzhiyun 	},
2012*4882a593Smuzhiyun };
2013*4882a593Smuzhiyun 
2014*4882a593Smuzhiyun static struct caam_aead_alg driver_aeads[] = {
2015*4882a593Smuzhiyun 	{
2016*4882a593Smuzhiyun 		.aead = {
2017*4882a593Smuzhiyun 			.base = {
2018*4882a593Smuzhiyun 				.cra_name = "rfc4106(gcm(aes))",
2019*4882a593Smuzhiyun 				.cra_driver_name = "rfc4106-gcm-aes-caam",
2020*4882a593Smuzhiyun 				.cra_blocksize = 1,
2021*4882a593Smuzhiyun 			},
2022*4882a593Smuzhiyun 			.setkey = rfc4106_setkey,
2023*4882a593Smuzhiyun 			.setauthsize = rfc4106_setauthsize,
2024*4882a593Smuzhiyun 			.encrypt = ipsec_gcm_encrypt,
2025*4882a593Smuzhiyun 			.decrypt = ipsec_gcm_decrypt,
2026*4882a593Smuzhiyun 			.ivsize = GCM_RFC4106_IV_SIZE,
2027*4882a593Smuzhiyun 			.maxauthsize = AES_BLOCK_SIZE,
2028*4882a593Smuzhiyun 		},
2029*4882a593Smuzhiyun 		.caam = {
2030*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
2031*4882a593Smuzhiyun 			.nodkp = true,
2032*4882a593Smuzhiyun 		},
2033*4882a593Smuzhiyun 	},
2034*4882a593Smuzhiyun 	{
2035*4882a593Smuzhiyun 		.aead = {
2036*4882a593Smuzhiyun 			.base = {
2037*4882a593Smuzhiyun 				.cra_name = "rfc4543(gcm(aes))",
2038*4882a593Smuzhiyun 				.cra_driver_name = "rfc4543-gcm-aes-caam",
2039*4882a593Smuzhiyun 				.cra_blocksize = 1,
2040*4882a593Smuzhiyun 			},
2041*4882a593Smuzhiyun 			.setkey = rfc4543_setkey,
2042*4882a593Smuzhiyun 			.setauthsize = rfc4543_setauthsize,
2043*4882a593Smuzhiyun 			.encrypt = ipsec_gcm_encrypt,
2044*4882a593Smuzhiyun 			.decrypt = ipsec_gcm_decrypt,
2045*4882a593Smuzhiyun 			.ivsize = GCM_RFC4543_IV_SIZE,
2046*4882a593Smuzhiyun 			.maxauthsize = AES_BLOCK_SIZE,
2047*4882a593Smuzhiyun 		},
2048*4882a593Smuzhiyun 		.caam = {
2049*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
2050*4882a593Smuzhiyun 			.nodkp = true,
2051*4882a593Smuzhiyun 		},
2052*4882a593Smuzhiyun 	},
2053*4882a593Smuzhiyun 	/* Galois Counter Mode */
2054*4882a593Smuzhiyun 	{
2055*4882a593Smuzhiyun 		.aead = {
2056*4882a593Smuzhiyun 			.base = {
2057*4882a593Smuzhiyun 				.cra_name = "gcm(aes)",
2058*4882a593Smuzhiyun 				.cra_driver_name = "gcm-aes-caam",
2059*4882a593Smuzhiyun 				.cra_blocksize = 1,
2060*4882a593Smuzhiyun 			},
2061*4882a593Smuzhiyun 			.setkey = gcm_setkey,
2062*4882a593Smuzhiyun 			.setauthsize = gcm_setauthsize,
2063*4882a593Smuzhiyun 			.encrypt = gcm_encrypt,
2064*4882a593Smuzhiyun 			.decrypt = gcm_decrypt,
2065*4882a593Smuzhiyun 			.ivsize = GCM_AES_IV_SIZE,
2066*4882a593Smuzhiyun 			.maxauthsize = AES_BLOCK_SIZE,
2067*4882a593Smuzhiyun 		},
2068*4882a593Smuzhiyun 		.caam = {
2069*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
2070*4882a593Smuzhiyun 			.nodkp = true,
2071*4882a593Smuzhiyun 		},
2072*4882a593Smuzhiyun 	},
2073*4882a593Smuzhiyun 	/* single-pass ipsec_esp descriptor */
2074*4882a593Smuzhiyun 	{
2075*4882a593Smuzhiyun 		.aead = {
2076*4882a593Smuzhiyun 			.base = {
2077*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(md5),"
2078*4882a593Smuzhiyun 					    "ecb(cipher_null))",
2079*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-md5-"
2080*4882a593Smuzhiyun 						   "ecb-cipher_null-caam",
2081*4882a593Smuzhiyun 				.cra_blocksize = NULL_BLOCK_SIZE,
2082*4882a593Smuzhiyun 			},
2083*4882a593Smuzhiyun 			.setkey = aead_setkey,
2084*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2085*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2086*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2087*4882a593Smuzhiyun 			.ivsize = NULL_IV_SIZE,
2088*4882a593Smuzhiyun 			.maxauthsize = MD5_DIGEST_SIZE,
2089*4882a593Smuzhiyun 		},
2090*4882a593Smuzhiyun 		.caam = {
2091*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2092*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2093*4882a593Smuzhiyun 		},
2094*4882a593Smuzhiyun 	},
2095*4882a593Smuzhiyun 	{
2096*4882a593Smuzhiyun 		.aead = {
2097*4882a593Smuzhiyun 			.base = {
2098*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha1),"
2099*4882a593Smuzhiyun 					    "ecb(cipher_null))",
2100*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha1-"
2101*4882a593Smuzhiyun 						   "ecb-cipher_null-caam",
2102*4882a593Smuzhiyun 				.cra_blocksize = NULL_BLOCK_SIZE,
2103*4882a593Smuzhiyun 			},
2104*4882a593Smuzhiyun 			.setkey = aead_setkey,
2105*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2106*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2107*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2108*4882a593Smuzhiyun 			.ivsize = NULL_IV_SIZE,
2109*4882a593Smuzhiyun 			.maxauthsize = SHA1_DIGEST_SIZE,
2110*4882a593Smuzhiyun 		},
2111*4882a593Smuzhiyun 		.caam = {
2112*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2113*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2114*4882a593Smuzhiyun 		},
2115*4882a593Smuzhiyun 	},
2116*4882a593Smuzhiyun 	{
2117*4882a593Smuzhiyun 		.aead = {
2118*4882a593Smuzhiyun 			.base = {
2119*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha224),"
2120*4882a593Smuzhiyun 					    "ecb(cipher_null))",
2121*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha224-"
2122*4882a593Smuzhiyun 						   "ecb-cipher_null-caam",
2123*4882a593Smuzhiyun 				.cra_blocksize = NULL_BLOCK_SIZE,
2124*4882a593Smuzhiyun 			},
2125*4882a593Smuzhiyun 			.setkey = aead_setkey,
2126*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2127*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2128*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2129*4882a593Smuzhiyun 			.ivsize = NULL_IV_SIZE,
2130*4882a593Smuzhiyun 			.maxauthsize = SHA224_DIGEST_SIZE,
2131*4882a593Smuzhiyun 		},
2132*4882a593Smuzhiyun 		.caam = {
2133*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2134*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2135*4882a593Smuzhiyun 		},
2136*4882a593Smuzhiyun 	},
2137*4882a593Smuzhiyun 	{
2138*4882a593Smuzhiyun 		.aead = {
2139*4882a593Smuzhiyun 			.base = {
2140*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha256),"
2141*4882a593Smuzhiyun 					    "ecb(cipher_null))",
2142*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha256-"
2143*4882a593Smuzhiyun 						   "ecb-cipher_null-caam",
2144*4882a593Smuzhiyun 				.cra_blocksize = NULL_BLOCK_SIZE,
2145*4882a593Smuzhiyun 			},
2146*4882a593Smuzhiyun 			.setkey = aead_setkey,
2147*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2148*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2149*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2150*4882a593Smuzhiyun 			.ivsize = NULL_IV_SIZE,
2151*4882a593Smuzhiyun 			.maxauthsize = SHA256_DIGEST_SIZE,
2152*4882a593Smuzhiyun 		},
2153*4882a593Smuzhiyun 		.caam = {
2154*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2155*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2156*4882a593Smuzhiyun 		},
2157*4882a593Smuzhiyun 	},
2158*4882a593Smuzhiyun 	{
2159*4882a593Smuzhiyun 		.aead = {
2160*4882a593Smuzhiyun 			.base = {
2161*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha384),"
2162*4882a593Smuzhiyun 					    "ecb(cipher_null))",
2163*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha384-"
2164*4882a593Smuzhiyun 						   "ecb-cipher_null-caam",
2165*4882a593Smuzhiyun 				.cra_blocksize = NULL_BLOCK_SIZE,
2166*4882a593Smuzhiyun 			},
2167*4882a593Smuzhiyun 			.setkey = aead_setkey,
2168*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2169*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2170*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2171*4882a593Smuzhiyun 			.ivsize = NULL_IV_SIZE,
2172*4882a593Smuzhiyun 			.maxauthsize = SHA384_DIGEST_SIZE,
2173*4882a593Smuzhiyun 		},
2174*4882a593Smuzhiyun 		.caam = {
2175*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2176*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2177*4882a593Smuzhiyun 		},
2178*4882a593Smuzhiyun 	},
2179*4882a593Smuzhiyun 	{
2180*4882a593Smuzhiyun 		.aead = {
2181*4882a593Smuzhiyun 			.base = {
2182*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha512),"
2183*4882a593Smuzhiyun 					    "ecb(cipher_null))",
2184*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha512-"
2185*4882a593Smuzhiyun 						   "ecb-cipher_null-caam",
2186*4882a593Smuzhiyun 				.cra_blocksize = NULL_BLOCK_SIZE,
2187*4882a593Smuzhiyun 			},
2188*4882a593Smuzhiyun 			.setkey = aead_setkey,
2189*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2190*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2191*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2192*4882a593Smuzhiyun 			.ivsize = NULL_IV_SIZE,
2193*4882a593Smuzhiyun 			.maxauthsize = SHA512_DIGEST_SIZE,
2194*4882a593Smuzhiyun 		},
2195*4882a593Smuzhiyun 		.caam = {
2196*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2197*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2198*4882a593Smuzhiyun 		},
2199*4882a593Smuzhiyun 	},
2200*4882a593Smuzhiyun 	{
2201*4882a593Smuzhiyun 		.aead = {
2202*4882a593Smuzhiyun 			.base = {
2203*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(md5),cbc(aes))",
2204*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-md5-"
2205*4882a593Smuzhiyun 						   "cbc-aes-caam",
2206*4882a593Smuzhiyun 				.cra_blocksize = AES_BLOCK_SIZE,
2207*4882a593Smuzhiyun 			},
2208*4882a593Smuzhiyun 			.setkey = aead_setkey,
2209*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2210*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2211*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2212*4882a593Smuzhiyun 			.ivsize = AES_BLOCK_SIZE,
2213*4882a593Smuzhiyun 			.maxauthsize = MD5_DIGEST_SIZE,
2214*4882a593Smuzhiyun 		},
2215*4882a593Smuzhiyun 		.caam = {
2216*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2217*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2218*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2219*4882a593Smuzhiyun 		},
2220*4882a593Smuzhiyun 	},
2221*4882a593Smuzhiyun 	{
2222*4882a593Smuzhiyun 		.aead = {
2223*4882a593Smuzhiyun 			.base = {
2224*4882a593Smuzhiyun 				.cra_name = "echainiv(authenc(hmac(md5),"
2225*4882a593Smuzhiyun 					    "cbc(aes)))",
2226*4882a593Smuzhiyun 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
2227*4882a593Smuzhiyun 						   "cbc-aes-caam",
2228*4882a593Smuzhiyun 				.cra_blocksize = AES_BLOCK_SIZE,
2229*4882a593Smuzhiyun 			},
2230*4882a593Smuzhiyun 			.setkey = aead_setkey,
2231*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2232*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2233*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2234*4882a593Smuzhiyun 			.ivsize = AES_BLOCK_SIZE,
2235*4882a593Smuzhiyun 			.maxauthsize = MD5_DIGEST_SIZE,
2236*4882a593Smuzhiyun 		},
2237*4882a593Smuzhiyun 		.caam = {
2238*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2239*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2240*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2241*4882a593Smuzhiyun 			.geniv = true,
2242*4882a593Smuzhiyun 		},
2243*4882a593Smuzhiyun 	},
2244*4882a593Smuzhiyun 	{
2245*4882a593Smuzhiyun 		.aead = {
2246*4882a593Smuzhiyun 			.base = {
2247*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha1),cbc(aes))",
2248*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha1-"
2249*4882a593Smuzhiyun 						   "cbc-aes-caam",
2250*4882a593Smuzhiyun 				.cra_blocksize = AES_BLOCK_SIZE,
2251*4882a593Smuzhiyun 			},
2252*4882a593Smuzhiyun 			.setkey = aead_setkey,
2253*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2254*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2255*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2256*4882a593Smuzhiyun 			.ivsize = AES_BLOCK_SIZE,
2257*4882a593Smuzhiyun 			.maxauthsize = SHA1_DIGEST_SIZE,
2258*4882a593Smuzhiyun 		},
2259*4882a593Smuzhiyun 		.caam = {
2260*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2261*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2262*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2263*4882a593Smuzhiyun 		},
2264*4882a593Smuzhiyun 	},
2265*4882a593Smuzhiyun 	{
2266*4882a593Smuzhiyun 		.aead = {
2267*4882a593Smuzhiyun 			.base = {
2268*4882a593Smuzhiyun 				.cra_name = "echainiv(authenc(hmac(sha1),"
2269*4882a593Smuzhiyun 					    "cbc(aes)))",
2270*4882a593Smuzhiyun 				.cra_driver_name = "echainiv-authenc-"
2271*4882a593Smuzhiyun 						   "hmac-sha1-cbc-aes-caam",
2272*4882a593Smuzhiyun 				.cra_blocksize = AES_BLOCK_SIZE,
2273*4882a593Smuzhiyun 			},
2274*4882a593Smuzhiyun 			.setkey = aead_setkey,
2275*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2276*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2277*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2278*4882a593Smuzhiyun 			.ivsize = AES_BLOCK_SIZE,
2279*4882a593Smuzhiyun 			.maxauthsize = SHA1_DIGEST_SIZE,
2280*4882a593Smuzhiyun 		},
2281*4882a593Smuzhiyun 		.caam = {
2282*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2283*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2284*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2285*4882a593Smuzhiyun 			.geniv = true,
2286*4882a593Smuzhiyun 		},
2287*4882a593Smuzhiyun 	},
2288*4882a593Smuzhiyun 	{
2289*4882a593Smuzhiyun 		.aead = {
2290*4882a593Smuzhiyun 			.base = {
2291*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha224),cbc(aes))",
2292*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha224-"
2293*4882a593Smuzhiyun 						   "cbc-aes-caam",
2294*4882a593Smuzhiyun 				.cra_blocksize = AES_BLOCK_SIZE,
2295*4882a593Smuzhiyun 			},
2296*4882a593Smuzhiyun 			.setkey = aead_setkey,
2297*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2298*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2299*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2300*4882a593Smuzhiyun 			.ivsize = AES_BLOCK_SIZE,
2301*4882a593Smuzhiyun 			.maxauthsize = SHA224_DIGEST_SIZE,
2302*4882a593Smuzhiyun 		},
2303*4882a593Smuzhiyun 		.caam = {
2304*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2305*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2306*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2307*4882a593Smuzhiyun 		},
2308*4882a593Smuzhiyun 	},
2309*4882a593Smuzhiyun 	{
2310*4882a593Smuzhiyun 		.aead = {
2311*4882a593Smuzhiyun 			.base = {
2312*4882a593Smuzhiyun 				.cra_name = "echainiv(authenc(hmac(sha224),"
2313*4882a593Smuzhiyun 					    "cbc(aes)))",
2314*4882a593Smuzhiyun 				.cra_driver_name = "echainiv-authenc-"
2315*4882a593Smuzhiyun 						   "hmac-sha224-cbc-aes-caam",
2316*4882a593Smuzhiyun 				.cra_blocksize = AES_BLOCK_SIZE,
2317*4882a593Smuzhiyun 			},
2318*4882a593Smuzhiyun 			.setkey = aead_setkey,
2319*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2320*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2321*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2322*4882a593Smuzhiyun 			.ivsize = AES_BLOCK_SIZE,
2323*4882a593Smuzhiyun 			.maxauthsize = SHA224_DIGEST_SIZE,
2324*4882a593Smuzhiyun 		},
2325*4882a593Smuzhiyun 		.caam = {
2326*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2327*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2328*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2329*4882a593Smuzhiyun 			.geniv = true,
2330*4882a593Smuzhiyun 		},
2331*4882a593Smuzhiyun 	},
2332*4882a593Smuzhiyun 	{
2333*4882a593Smuzhiyun 		.aead = {
2334*4882a593Smuzhiyun 			.base = {
2335*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha256),cbc(aes))",
2336*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha256-"
2337*4882a593Smuzhiyun 						   "cbc-aes-caam",
2338*4882a593Smuzhiyun 				.cra_blocksize = AES_BLOCK_SIZE,
2339*4882a593Smuzhiyun 			},
2340*4882a593Smuzhiyun 			.setkey = aead_setkey,
2341*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2342*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2343*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2344*4882a593Smuzhiyun 			.ivsize = AES_BLOCK_SIZE,
2345*4882a593Smuzhiyun 			.maxauthsize = SHA256_DIGEST_SIZE,
2346*4882a593Smuzhiyun 		},
2347*4882a593Smuzhiyun 		.caam = {
2348*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2349*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2350*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2351*4882a593Smuzhiyun 		},
2352*4882a593Smuzhiyun 	},
2353*4882a593Smuzhiyun 	{
2354*4882a593Smuzhiyun 		.aead = {
2355*4882a593Smuzhiyun 			.base = {
2356*4882a593Smuzhiyun 				.cra_name = "echainiv(authenc(hmac(sha256),"
2357*4882a593Smuzhiyun 					    "cbc(aes)))",
2358*4882a593Smuzhiyun 				.cra_driver_name = "echainiv-authenc-"
2359*4882a593Smuzhiyun 						   "hmac-sha256-cbc-aes-caam",
2360*4882a593Smuzhiyun 				.cra_blocksize = AES_BLOCK_SIZE,
2361*4882a593Smuzhiyun 			},
2362*4882a593Smuzhiyun 			.setkey = aead_setkey,
2363*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2364*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2365*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2366*4882a593Smuzhiyun 			.ivsize = AES_BLOCK_SIZE,
2367*4882a593Smuzhiyun 			.maxauthsize = SHA256_DIGEST_SIZE,
2368*4882a593Smuzhiyun 		},
2369*4882a593Smuzhiyun 		.caam = {
2370*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2371*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2372*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2373*4882a593Smuzhiyun 			.geniv = true,
2374*4882a593Smuzhiyun 		},
2375*4882a593Smuzhiyun 	},
2376*4882a593Smuzhiyun 	{
2377*4882a593Smuzhiyun 		.aead = {
2378*4882a593Smuzhiyun 			.base = {
2379*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha384),cbc(aes))",
2380*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha384-"
2381*4882a593Smuzhiyun 						   "cbc-aes-caam",
2382*4882a593Smuzhiyun 				.cra_blocksize = AES_BLOCK_SIZE,
2383*4882a593Smuzhiyun 			},
2384*4882a593Smuzhiyun 			.setkey = aead_setkey,
2385*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2386*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2387*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2388*4882a593Smuzhiyun 			.ivsize = AES_BLOCK_SIZE,
2389*4882a593Smuzhiyun 			.maxauthsize = SHA384_DIGEST_SIZE,
2390*4882a593Smuzhiyun 		},
2391*4882a593Smuzhiyun 		.caam = {
2392*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2393*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2394*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2395*4882a593Smuzhiyun 		},
2396*4882a593Smuzhiyun 	},
2397*4882a593Smuzhiyun 	{
2398*4882a593Smuzhiyun 		.aead = {
2399*4882a593Smuzhiyun 			.base = {
2400*4882a593Smuzhiyun 				.cra_name = "echainiv(authenc(hmac(sha384),"
2401*4882a593Smuzhiyun 					    "cbc(aes)))",
2402*4882a593Smuzhiyun 				.cra_driver_name = "echainiv-authenc-"
2403*4882a593Smuzhiyun 						   "hmac-sha384-cbc-aes-caam",
2404*4882a593Smuzhiyun 				.cra_blocksize = AES_BLOCK_SIZE,
2405*4882a593Smuzhiyun 			},
2406*4882a593Smuzhiyun 			.setkey = aead_setkey,
2407*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2408*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2409*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2410*4882a593Smuzhiyun 			.ivsize = AES_BLOCK_SIZE,
2411*4882a593Smuzhiyun 			.maxauthsize = SHA384_DIGEST_SIZE,
2412*4882a593Smuzhiyun 		},
2413*4882a593Smuzhiyun 		.caam = {
2414*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2415*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2416*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2417*4882a593Smuzhiyun 			.geniv = true,
2418*4882a593Smuzhiyun 		},
2419*4882a593Smuzhiyun 	},
2420*4882a593Smuzhiyun 	{
2421*4882a593Smuzhiyun 		.aead = {
2422*4882a593Smuzhiyun 			.base = {
2423*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha512),cbc(aes))",
2424*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha512-"
2425*4882a593Smuzhiyun 						   "cbc-aes-caam",
2426*4882a593Smuzhiyun 				.cra_blocksize = AES_BLOCK_SIZE,
2427*4882a593Smuzhiyun 			},
2428*4882a593Smuzhiyun 			.setkey = aead_setkey,
2429*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2430*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2431*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2432*4882a593Smuzhiyun 			.ivsize = AES_BLOCK_SIZE,
2433*4882a593Smuzhiyun 			.maxauthsize = SHA512_DIGEST_SIZE,
2434*4882a593Smuzhiyun 		},
2435*4882a593Smuzhiyun 		.caam = {
2436*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2437*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2438*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2439*4882a593Smuzhiyun 		},
2440*4882a593Smuzhiyun 	},
2441*4882a593Smuzhiyun 	{
2442*4882a593Smuzhiyun 		.aead = {
2443*4882a593Smuzhiyun 			.base = {
2444*4882a593Smuzhiyun 				.cra_name = "echainiv(authenc(hmac(sha512),"
2445*4882a593Smuzhiyun 					    "cbc(aes)))",
2446*4882a593Smuzhiyun 				.cra_driver_name = "echainiv-authenc-"
2447*4882a593Smuzhiyun 						   "hmac-sha512-cbc-aes-caam",
2448*4882a593Smuzhiyun 				.cra_blocksize = AES_BLOCK_SIZE,
2449*4882a593Smuzhiyun 			},
2450*4882a593Smuzhiyun 			.setkey = aead_setkey,
2451*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2452*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2453*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2454*4882a593Smuzhiyun 			.ivsize = AES_BLOCK_SIZE,
2455*4882a593Smuzhiyun 			.maxauthsize = SHA512_DIGEST_SIZE,
2456*4882a593Smuzhiyun 		},
2457*4882a593Smuzhiyun 		.caam = {
2458*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2459*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2460*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2461*4882a593Smuzhiyun 			.geniv = true,
2462*4882a593Smuzhiyun 		},
2463*4882a593Smuzhiyun 	},
2464*4882a593Smuzhiyun 	{
2465*4882a593Smuzhiyun 		.aead = {
2466*4882a593Smuzhiyun 			.base = {
2467*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2468*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-md5-"
2469*4882a593Smuzhiyun 						   "cbc-des3_ede-caam",
2470*4882a593Smuzhiyun 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2471*4882a593Smuzhiyun 			},
2472*4882a593Smuzhiyun 			.setkey = des3_aead_setkey,
2473*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2474*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2475*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2476*4882a593Smuzhiyun 			.ivsize = DES3_EDE_BLOCK_SIZE,
2477*4882a593Smuzhiyun 			.maxauthsize = MD5_DIGEST_SIZE,
2478*4882a593Smuzhiyun 		},
2479*4882a593Smuzhiyun 		.caam = {
2480*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2481*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2482*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2483*4882a593Smuzhiyun 		}
2484*4882a593Smuzhiyun 	},
2485*4882a593Smuzhiyun 	{
2486*4882a593Smuzhiyun 		.aead = {
2487*4882a593Smuzhiyun 			.base = {
2488*4882a593Smuzhiyun 				.cra_name = "echainiv(authenc(hmac(md5),"
2489*4882a593Smuzhiyun 					    "cbc(des3_ede)))",
2490*4882a593Smuzhiyun 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
2491*4882a593Smuzhiyun 						   "cbc-des3_ede-caam",
2492*4882a593Smuzhiyun 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2493*4882a593Smuzhiyun 			},
2494*4882a593Smuzhiyun 			.setkey = des3_aead_setkey,
2495*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2496*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2497*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2498*4882a593Smuzhiyun 			.ivsize = DES3_EDE_BLOCK_SIZE,
2499*4882a593Smuzhiyun 			.maxauthsize = MD5_DIGEST_SIZE,
2500*4882a593Smuzhiyun 		},
2501*4882a593Smuzhiyun 		.caam = {
2502*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2503*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2504*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2505*4882a593Smuzhiyun 			.geniv = true,
2506*4882a593Smuzhiyun 		}
2507*4882a593Smuzhiyun 	},
2508*4882a593Smuzhiyun 	{
2509*4882a593Smuzhiyun 		.aead = {
2510*4882a593Smuzhiyun 			.base = {
2511*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha1),"
2512*4882a593Smuzhiyun 					    "cbc(des3_ede))",
2513*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha1-"
2514*4882a593Smuzhiyun 						   "cbc-des3_ede-caam",
2515*4882a593Smuzhiyun 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2516*4882a593Smuzhiyun 			},
2517*4882a593Smuzhiyun 			.setkey = des3_aead_setkey,
2518*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2519*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2520*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2521*4882a593Smuzhiyun 			.ivsize = DES3_EDE_BLOCK_SIZE,
2522*4882a593Smuzhiyun 			.maxauthsize = SHA1_DIGEST_SIZE,
2523*4882a593Smuzhiyun 		},
2524*4882a593Smuzhiyun 		.caam = {
2525*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2526*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2527*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2528*4882a593Smuzhiyun 		},
2529*4882a593Smuzhiyun 	},
2530*4882a593Smuzhiyun 	{
2531*4882a593Smuzhiyun 		.aead = {
2532*4882a593Smuzhiyun 			.base = {
2533*4882a593Smuzhiyun 				.cra_name = "echainiv(authenc(hmac(sha1),"
2534*4882a593Smuzhiyun 					    "cbc(des3_ede)))",
2535*4882a593Smuzhiyun 				.cra_driver_name = "echainiv-authenc-"
2536*4882a593Smuzhiyun 						   "hmac-sha1-"
2537*4882a593Smuzhiyun 						   "cbc-des3_ede-caam",
2538*4882a593Smuzhiyun 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2539*4882a593Smuzhiyun 			},
2540*4882a593Smuzhiyun 			.setkey = des3_aead_setkey,
2541*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2542*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2543*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2544*4882a593Smuzhiyun 			.ivsize = DES3_EDE_BLOCK_SIZE,
2545*4882a593Smuzhiyun 			.maxauthsize = SHA1_DIGEST_SIZE,
2546*4882a593Smuzhiyun 		},
2547*4882a593Smuzhiyun 		.caam = {
2548*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2549*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2550*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2551*4882a593Smuzhiyun 			.geniv = true,
2552*4882a593Smuzhiyun 		},
2553*4882a593Smuzhiyun 	},
2554*4882a593Smuzhiyun 	{
2555*4882a593Smuzhiyun 		.aead = {
2556*4882a593Smuzhiyun 			.base = {
2557*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha224),"
2558*4882a593Smuzhiyun 					    "cbc(des3_ede))",
2559*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha224-"
2560*4882a593Smuzhiyun 						   "cbc-des3_ede-caam",
2561*4882a593Smuzhiyun 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2562*4882a593Smuzhiyun 			},
2563*4882a593Smuzhiyun 			.setkey = des3_aead_setkey,
2564*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2565*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2566*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2567*4882a593Smuzhiyun 			.ivsize = DES3_EDE_BLOCK_SIZE,
2568*4882a593Smuzhiyun 			.maxauthsize = SHA224_DIGEST_SIZE,
2569*4882a593Smuzhiyun 		},
2570*4882a593Smuzhiyun 		.caam = {
2571*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2572*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2573*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2574*4882a593Smuzhiyun 		},
2575*4882a593Smuzhiyun 	},
2576*4882a593Smuzhiyun 	{
2577*4882a593Smuzhiyun 		.aead = {
2578*4882a593Smuzhiyun 			.base = {
2579*4882a593Smuzhiyun 				.cra_name = "echainiv(authenc(hmac(sha224),"
2580*4882a593Smuzhiyun 					    "cbc(des3_ede)))",
2581*4882a593Smuzhiyun 				.cra_driver_name = "echainiv-authenc-"
2582*4882a593Smuzhiyun 						   "hmac-sha224-"
2583*4882a593Smuzhiyun 						   "cbc-des3_ede-caam",
2584*4882a593Smuzhiyun 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2585*4882a593Smuzhiyun 			},
2586*4882a593Smuzhiyun 			.setkey = des3_aead_setkey,
2587*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2588*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2589*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2590*4882a593Smuzhiyun 			.ivsize = DES3_EDE_BLOCK_SIZE,
2591*4882a593Smuzhiyun 			.maxauthsize = SHA224_DIGEST_SIZE,
2592*4882a593Smuzhiyun 		},
2593*4882a593Smuzhiyun 		.caam = {
2594*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2595*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2596*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2597*4882a593Smuzhiyun 			.geniv = true,
2598*4882a593Smuzhiyun 		},
2599*4882a593Smuzhiyun 	},
2600*4882a593Smuzhiyun 	{
2601*4882a593Smuzhiyun 		.aead = {
2602*4882a593Smuzhiyun 			.base = {
2603*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha256),"
2604*4882a593Smuzhiyun 					    "cbc(des3_ede))",
2605*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha256-"
2606*4882a593Smuzhiyun 						   "cbc-des3_ede-caam",
2607*4882a593Smuzhiyun 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2608*4882a593Smuzhiyun 			},
2609*4882a593Smuzhiyun 			.setkey = des3_aead_setkey,
2610*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2611*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2612*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2613*4882a593Smuzhiyun 			.ivsize = DES3_EDE_BLOCK_SIZE,
2614*4882a593Smuzhiyun 			.maxauthsize = SHA256_DIGEST_SIZE,
2615*4882a593Smuzhiyun 		},
2616*4882a593Smuzhiyun 		.caam = {
2617*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2618*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2619*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2620*4882a593Smuzhiyun 		},
2621*4882a593Smuzhiyun 	},
2622*4882a593Smuzhiyun 	{
2623*4882a593Smuzhiyun 		.aead = {
2624*4882a593Smuzhiyun 			.base = {
2625*4882a593Smuzhiyun 				.cra_name = "echainiv(authenc(hmac(sha256),"
2626*4882a593Smuzhiyun 					    "cbc(des3_ede)))",
2627*4882a593Smuzhiyun 				.cra_driver_name = "echainiv-authenc-"
2628*4882a593Smuzhiyun 						   "hmac-sha256-"
2629*4882a593Smuzhiyun 						   "cbc-des3_ede-caam",
2630*4882a593Smuzhiyun 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2631*4882a593Smuzhiyun 			},
2632*4882a593Smuzhiyun 			.setkey = des3_aead_setkey,
2633*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2634*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2635*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2636*4882a593Smuzhiyun 			.ivsize = DES3_EDE_BLOCK_SIZE,
2637*4882a593Smuzhiyun 			.maxauthsize = SHA256_DIGEST_SIZE,
2638*4882a593Smuzhiyun 		},
2639*4882a593Smuzhiyun 		.caam = {
2640*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2641*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2642*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2643*4882a593Smuzhiyun 			.geniv = true,
2644*4882a593Smuzhiyun 		},
2645*4882a593Smuzhiyun 	},
2646*4882a593Smuzhiyun 	{
2647*4882a593Smuzhiyun 		.aead = {
2648*4882a593Smuzhiyun 			.base = {
2649*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha384),"
2650*4882a593Smuzhiyun 					    "cbc(des3_ede))",
2651*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha384-"
2652*4882a593Smuzhiyun 						   "cbc-des3_ede-caam",
2653*4882a593Smuzhiyun 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2654*4882a593Smuzhiyun 			},
2655*4882a593Smuzhiyun 			.setkey = des3_aead_setkey,
2656*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2657*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2658*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2659*4882a593Smuzhiyun 			.ivsize = DES3_EDE_BLOCK_SIZE,
2660*4882a593Smuzhiyun 			.maxauthsize = SHA384_DIGEST_SIZE,
2661*4882a593Smuzhiyun 		},
2662*4882a593Smuzhiyun 		.caam = {
2663*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2664*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2665*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2666*4882a593Smuzhiyun 		},
2667*4882a593Smuzhiyun 	},
2668*4882a593Smuzhiyun 	{
2669*4882a593Smuzhiyun 		.aead = {
2670*4882a593Smuzhiyun 			.base = {
2671*4882a593Smuzhiyun 				.cra_name = "echainiv(authenc(hmac(sha384),"
2672*4882a593Smuzhiyun 					    "cbc(des3_ede)))",
2673*4882a593Smuzhiyun 				.cra_driver_name = "echainiv-authenc-"
2674*4882a593Smuzhiyun 						   "hmac-sha384-"
2675*4882a593Smuzhiyun 						   "cbc-des3_ede-caam",
2676*4882a593Smuzhiyun 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2677*4882a593Smuzhiyun 			},
2678*4882a593Smuzhiyun 			.setkey = des3_aead_setkey,
2679*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2680*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2681*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2682*4882a593Smuzhiyun 			.ivsize = DES3_EDE_BLOCK_SIZE,
2683*4882a593Smuzhiyun 			.maxauthsize = SHA384_DIGEST_SIZE,
2684*4882a593Smuzhiyun 		},
2685*4882a593Smuzhiyun 		.caam = {
2686*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2687*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2688*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2689*4882a593Smuzhiyun 			.geniv = true,
2690*4882a593Smuzhiyun 		},
2691*4882a593Smuzhiyun 	},
2692*4882a593Smuzhiyun 	{
2693*4882a593Smuzhiyun 		.aead = {
2694*4882a593Smuzhiyun 			.base = {
2695*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha512),"
2696*4882a593Smuzhiyun 					    "cbc(des3_ede))",
2697*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha512-"
2698*4882a593Smuzhiyun 						   "cbc-des3_ede-caam",
2699*4882a593Smuzhiyun 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2700*4882a593Smuzhiyun 			},
2701*4882a593Smuzhiyun 			.setkey = des3_aead_setkey,
2702*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2703*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2704*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2705*4882a593Smuzhiyun 			.ivsize = DES3_EDE_BLOCK_SIZE,
2706*4882a593Smuzhiyun 			.maxauthsize = SHA512_DIGEST_SIZE,
2707*4882a593Smuzhiyun 		},
2708*4882a593Smuzhiyun 		.caam = {
2709*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2710*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2711*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2712*4882a593Smuzhiyun 		},
2713*4882a593Smuzhiyun 	},
2714*4882a593Smuzhiyun 	{
2715*4882a593Smuzhiyun 		.aead = {
2716*4882a593Smuzhiyun 			.base = {
2717*4882a593Smuzhiyun 				.cra_name = "echainiv(authenc(hmac(sha512),"
2718*4882a593Smuzhiyun 					    "cbc(des3_ede)))",
2719*4882a593Smuzhiyun 				.cra_driver_name = "echainiv-authenc-"
2720*4882a593Smuzhiyun 						   "hmac-sha512-"
2721*4882a593Smuzhiyun 						   "cbc-des3_ede-caam",
2722*4882a593Smuzhiyun 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2723*4882a593Smuzhiyun 			},
2724*4882a593Smuzhiyun 			.setkey = des3_aead_setkey,
2725*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2726*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2727*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2728*4882a593Smuzhiyun 			.ivsize = DES3_EDE_BLOCK_SIZE,
2729*4882a593Smuzhiyun 			.maxauthsize = SHA512_DIGEST_SIZE,
2730*4882a593Smuzhiyun 		},
2731*4882a593Smuzhiyun 		.caam = {
2732*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2733*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2734*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2735*4882a593Smuzhiyun 			.geniv = true,
2736*4882a593Smuzhiyun 		},
2737*4882a593Smuzhiyun 	},
2738*4882a593Smuzhiyun 	{
2739*4882a593Smuzhiyun 		.aead = {
2740*4882a593Smuzhiyun 			.base = {
2741*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(md5),cbc(des))",
2742*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-md5-"
2743*4882a593Smuzhiyun 						   "cbc-des-caam",
2744*4882a593Smuzhiyun 				.cra_blocksize = DES_BLOCK_SIZE,
2745*4882a593Smuzhiyun 			},
2746*4882a593Smuzhiyun 			.setkey = aead_setkey,
2747*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2748*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2749*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2750*4882a593Smuzhiyun 			.ivsize = DES_BLOCK_SIZE,
2751*4882a593Smuzhiyun 			.maxauthsize = MD5_DIGEST_SIZE,
2752*4882a593Smuzhiyun 		},
2753*4882a593Smuzhiyun 		.caam = {
2754*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2755*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2756*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2757*4882a593Smuzhiyun 		},
2758*4882a593Smuzhiyun 	},
2759*4882a593Smuzhiyun 	{
2760*4882a593Smuzhiyun 		.aead = {
2761*4882a593Smuzhiyun 			.base = {
2762*4882a593Smuzhiyun 				.cra_name = "echainiv(authenc(hmac(md5),"
2763*4882a593Smuzhiyun 					    "cbc(des)))",
2764*4882a593Smuzhiyun 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
2765*4882a593Smuzhiyun 						   "cbc-des-caam",
2766*4882a593Smuzhiyun 				.cra_blocksize = DES_BLOCK_SIZE,
2767*4882a593Smuzhiyun 			},
2768*4882a593Smuzhiyun 			.setkey = aead_setkey,
2769*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2770*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2771*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2772*4882a593Smuzhiyun 			.ivsize = DES_BLOCK_SIZE,
2773*4882a593Smuzhiyun 			.maxauthsize = MD5_DIGEST_SIZE,
2774*4882a593Smuzhiyun 		},
2775*4882a593Smuzhiyun 		.caam = {
2776*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2777*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2778*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2779*4882a593Smuzhiyun 			.geniv = true,
2780*4882a593Smuzhiyun 		},
2781*4882a593Smuzhiyun 	},
2782*4882a593Smuzhiyun 	{
2783*4882a593Smuzhiyun 		.aead = {
2784*4882a593Smuzhiyun 			.base = {
2785*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha1),cbc(des))",
2786*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha1-"
2787*4882a593Smuzhiyun 						   "cbc-des-caam",
2788*4882a593Smuzhiyun 				.cra_blocksize = DES_BLOCK_SIZE,
2789*4882a593Smuzhiyun 			},
2790*4882a593Smuzhiyun 			.setkey = aead_setkey,
2791*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2792*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2793*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2794*4882a593Smuzhiyun 			.ivsize = DES_BLOCK_SIZE,
2795*4882a593Smuzhiyun 			.maxauthsize = SHA1_DIGEST_SIZE,
2796*4882a593Smuzhiyun 		},
2797*4882a593Smuzhiyun 		.caam = {
2798*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2799*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2800*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2801*4882a593Smuzhiyun 		},
2802*4882a593Smuzhiyun 	},
2803*4882a593Smuzhiyun 	{
2804*4882a593Smuzhiyun 		.aead = {
2805*4882a593Smuzhiyun 			.base = {
2806*4882a593Smuzhiyun 				.cra_name = "echainiv(authenc(hmac(sha1),"
2807*4882a593Smuzhiyun 					    "cbc(des)))",
2808*4882a593Smuzhiyun 				.cra_driver_name = "echainiv-authenc-"
2809*4882a593Smuzhiyun 						   "hmac-sha1-cbc-des-caam",
2810*4882a593Smuzhiyun 				.cra_blocksize = DES_BLOCK_SIZE,
2811*4882a593Smuzhiyun 			},
2812*4882a593Smuzhiyun 			.setkey = aead_setkey,
2813*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2814*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2815*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2816*4882a593Smuzhiyun 			.ivsize = DES_BLOCK_SIZE,
2817*4882a593Smuzhiyun 			.maxauthsize = SHA1_DIGEST_SIZE,
2818*4882a593Smuzhiyun 		},
2819*4882a593Smuzhiyun 		.caam = {
2820*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2821*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2822*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2823*4882a593Smuzhiyun 			.geniv = true,
2824*4882a593Smuzhiyun 		},
2825*4882a593Smuzhiyun 	},
2826*4882a593Smuzhiyun 	{
2827*4882a593Smuzhiyun 		.aead = {
2828*4882a593Smuzhiyun 			.base = {
2829*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha224),cbc(des))",
2830*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha224-"
2831*4882a593Smuzhiyun 						   "cbc-des-caam",
2832*4882a593Smuzhiyun 				.cra_blocksize = DES_BLOCK_SIZE,
2833*4882a593Smuzhiyun 			},
2834*4882a593Smuzhiyun 			.setkey = aead_setkey,
2835*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2836*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2837*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2838*4882a593Smuzhiyun 			.ivsize = DES_BLOCK_SIZE,
2839*4882a593Smuzhiyun 			.maxauthsize = SHA224_DIGEST_SIZE,
2840*4882a593Smuzhiyun 		},
2841*4882a593Smuzhiyun 		.caam = {
2842*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2843*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2844*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2845*4882a593Smuzhiyun 		},
2846*4882a593Smuzhiyun 	},
2847*4882a593Smuzhiyun 	{
2848*4882a593Smuzhiyun 		.aead = {
2849*4882a593Smuzhiyun 			.base = {
2850*4882a593Smuzhiyun 				.cra_name = "echainiv(authenc(hmac(sha224),"
2851*4882a593Smuzhiyun 					    "cbc(des)))",
2852*4882a593Smuzhiyun 				.cra_driver_name = "echainiv-authenc-"
2853*4882a593Smuzhiyun 						   "hmac-sha224-cbc-des-caam",
2854*4882a593Smuzhiyun 				.cra_blocksize = DES_BLOCK_SIZE,
2855*4882a593Smuzhiyun 			},
2856*4882a593Smuzhiyun 			.setkey = aead_setkey,
2857*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2858*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2859*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2860*4882a593Smuzhiyun 			.ivsize = DES_BLOCK_SIZE,
2861*4882a593Smuzhiyun 			.maxauthsize = SHA224_DIGEST_SIZE,
2862*4882a593Smuzhiyun 		},
2863*4882a593Smuzhiyun 		.caam = {
2864*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2865*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2866*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2867*4882a593Smuzhiyun 			.geniv = true,
2868*4882a593Smuzhiyun 		},
2869*4882a593Smuzhiyun 	},
2870*4882a593Smuzhiyun 	{
2871*4882a593Smuzhiyun 		.aead = {
2872*4882a593Smuzhiyun 			.base = {
2873*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha256),cbc(des))",
2874*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha256-"
2875*4882a593Smuzhiyun 						   "cbc-des-caam",
2876*4882a593Smuzhiyun 				.cra_blocksize = DES_BLOCK_SIZE,
2877*4882a593Smuzhiyun 			},
2878*4882a593Smuzhiyun 			.setkey = aead_setkey,
2879*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2880*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2881*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2882*4882a593Smuzhiyun 			.ivsize = DES_BLOCK_SIZE,
2883*4882a593Smuzhiyun 			.maxauthsize = SHA256_DIGEST_SIZE,
2884*4882a593Smuzhiyun 		},
2885*4882a593Smuzhiyun 		.caam = {
2886*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2887*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2888*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2889*4882a593Smuzhiyun 		},
2890*4882a593Smuzhiyun 	},
2891*4882a593Smuzhiyun 	{
2892*4882a593Smuzhiyun 		.aead = {
2893*4882a593Smuzhiyun 			.base = {
2894*4882a593Smuzhiyun 				.cra_name = "echainiv(authenc(hmac(sha256),"
2895*4882a593Smuzhiyun 					    "cbc(des)))",
2896*4882a593Smuzhiyun 				.cra_driver_name = "echainiv-authenc-"
2897*4882a593Smuzhiyun 						   "hmac-sha256-cbc-des-caam",
2898*4882a593Smuzhiyun 				.cra_blocksize = DES_BLOCK_SIZE,
2899*4882a593Smuzhiyun 			},
2900*4882a593Smuzhiyun 			.setkey = aead_setkey,
2901*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2902*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2903*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2904*4882a593Smuzhiyun 			.ivsize = DES_BLOCK_SIZE,
2905*4882a593Smuzhiyun 			.maxauthsize = SHA256_DIGEST_SIZE,
2906*4882a593Smuzhiyun 		},
2907*4882a593Smuzhiyun 		.caam = {
2908*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2909*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2910*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2911*4882a593Smuzhiyun 			.geniv = true,
2912*4882a593Smuzhiyun 		},
2913*4882a593Smuzhiyun 	},
2914*4882a593Smuzhiyun 	{
2915*4882a593Smuzhiyun 		.aead = {
2916*4882a593Smuzhiyun 			.base = {
2917*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha384),cbc(des))",
2918*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha384-"
2919*4882a593Smuzhiyun 						   "cbc-des-caam",
2920*4882a593Smuzhiyun 				.cra_blocksize = DES_BLOCK_SIZE,
2921*4882a593Smuzhiyun 			},
2922*4882a593Smuzhiyun 			.setkey = aead_setkey,
2923*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2924*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2925*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2926*4882a593Smuzhiyun 			.ivsize = DES_BLOCK_SIZE,
2927*4882a593Smuzhiyun 			.maxauthsize = SHA384_DIGEST_SIZE,
2928*4882a593Smuzhiyun 		},
2929*4882a593Smuzhiyun 		.caam = {
2930*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2931*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2932*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2933*4882a593Smuzhiyun 		},
2934*4882a593Smuzhiyun 	},
2935*4882a593Smuzhiyun 	{
2936*4882a593Smuzhiyun 		.aead = {
2937*4882a593Smuzhiyun 			.base = {
2938*4882a593Smuzhiyun 				.cra_name = "echainiv(authenc(hmac(sha384),"
2939*4882a593Smuzhiyun 					    "cbc(des)))",
2940*4882a593Smuzhiyun 				.cra_driver_name = "echainiv-authenc-"
2941*4882a593Smuzhiyun 						   "hmac-sha384-cbc-des-caam",
2942*4882a593Smuzhiyun 				.cra_blocksize = DES_BLOCK_SIZE,
2943*4882a593Smuzhiyun 			},
2944*4882a593Smuzhiyun 			.setkey = aead_setkey,
2945*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2946*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2947*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2948*4882a593Smuzhiyun 			.ivsize = DES_BLOCK_SIZE,
2949*4882a593Smuzhiyun 			.maxauthsize = SHA384_DIGEST_SIZE,
2950*4882a593Smuzhiyun 		},
2951*4882a593Smuzhiyun 		.caam = {
2952*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2953*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2954*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2955*4882a593Smuzhiyun 			.geniv = true,
2956*4882a593Smuzhiyun 		},
2957*4882a593Smuzhiyun 	},
2958*4882a593Smuzhiyun 	{
2959*4882a593Smuzhiyun 		.aead = {
2960*4882a593Smuzhiyun 			.base = {
2961*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha512),cbc(des))",
2962*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha512-"
2963*4882a593Smuzhiyun 						   "cbc-des-caam",
2964*4882a593Smuzhiyun 				.cra_blocksize = DES_BLOCK_SIZE,
2965*4882a593Smuzhiyun 			},
2966*4882a593Smuzhiyun 			.setkey = aead_setkey,
2967*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2968*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2969*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2970*4882a593Smuzhiyun 			.ivsize = DES_BLOCK_SIZE,
2971*4882a593Smuzhiyun 			.maxauthsize = SHA512_DIGEST_SIZE,
2972*4882a593Smuzhiyun 		},
2973*4882a593Smuzhiyun 		.caam = {
2974*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2975*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2976*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2977*4882a593Smuzhiyun 		},
2978*4882a593Smuzhiyun 	},
2979*4882a593Smuzhiyun 	{
2980*4882a593Smuzhiyun 		.aead = {
2981*4882a593Smuzhiyun 			.base = {
2982*4882a593Smuzhiyun 				.cra_name = "echainiv(authenc(hmac(sha512),"
2983*4882a593Smuzhiyun 					    "cbc(des)))",
2984*4882a593Smuzhiyun 				.cra_driver_name = "echainiv-authenc-"
2985*4882a593Smuzhiyun 						   "hmac-sha512-cbc-des-caam",
2986*4882a593Smuzhiyun 				.cra_blocksize = DES_BLOCK_SIZE,
2987*4882a593Smuzhiyun 			},
2988*4882a593Smuzhiyun 			.setkey = aead_setkey,
2989*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
2990*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
2991*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
2992*4882a593Smuzhiyun 			.ivsize = DES_BLOCK_SIZE,
2993*4882a593Smuzhiyun 			.maxauthsize = SHA512_DIGEST_SIZE,
2994*4882a593Smuzhiyun 		},
2995*4882a593Smuzhiyun 		.caam = {
2996*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2997*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2998*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
2999*4882a593Smuzhiyun 			.geniv = true,
3000*4882a593Smuzhiyun 		},
3001*4882a593Smuzhiyun 	},
3002*4882a593Smuzhiyun 	{
3003*4882a593Smuzhiyun 		.aead = {
3004*4882a593Smuzhiyun 			.base = {
3005*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(md5),"
3006*4882a593Smuzhiyun 					    "rfc3686(ctr(aes)))",
3007*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-md5-"
3008*4882a593Smuzhiyun 						   "rfc3686-ctr-aes-caam",
3009*4882a593Smuzhiyun 				.cra_blocksize = 1,
3010*4882a593Smuzhiyun 			},
3011*4882a593Smuzhiyun 			.setkey = aead_setkey,
3012*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
3013*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
3014*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
3015*4882a593Smuzhiyun 			.ivsize = CTR_RFC3686_IV_SIZE,
3016*4882a593Smuzhiyun 			.maxauthsize = MD5_DIGEST_SIZE,
3017*4882a593Smuzhiyun 		},
3018*4882a593Smuzhiyun 		.caam = {
3019*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3020*4882a593Smuzhiyun 					   OP_ALG_AAI_CTR_MOD128,
3021*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3022*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
3023*4882a593Smuzhiyun 			.rfc3686 = true,
3024*4882a593Smuzhiyun 		},
3025*4882a593Smuzhiyun 	},
3026*4882a593Smuzhiyun 	{
3027*4882a593Smuzhiyun 		.aead = {
3028*4882a593Smuzhiyun 			.base = {
3029*4882a593Smuzhiyun 				.cra_name = "seqiv(authenc("
3030*4882a593Smuzhiyun 					    "hmac(md5),rfc3686(ctr(aes))))",
3031*4882a593Smuzhiyun 				.cra_driver_name = "seqiv-authenc-hmac-md5-"
3032*4882a593Smuzhiyun 						   "rfc3686-ctr-aes-caam",
3033*4882a593Smuzhiyun 				.cra_blocksize = 1,
3034*4882a593Smuzhiyun 			},
3035*4882a593Smuzhiyun 			.setkey = aead_setkey,
3036*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
3037*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
3038*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
3039*4882a593Smuzhiyun 			.ivsize = CTR_RFC3686_IV_SIZE,
3040*4882a593Smuzhiyun 			.maxauthsize = MD5_DIGEST_SIZE,
3041*4882a593Smuzhiyun 		},
3042*4882a593Smuzhiyun 		.caam = {
3043*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3044*4882a593Smuzhiyun 					   OP_ALG_AAI_CTR_MOD128,
3045*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3046*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
3047*4882a593Smuzhiyun 			.rfc3686 = true,
3048*4882a593Smuzhiyun 			.geniv = true,
3049*4882a593Smuzhiyun 		},
3050*4882a593Smuzhiyun 	},
3051*4882a593Smuzhiyun 	{
3052*4882a593Smuzhiyun 		.aead = {
3053*4882a593Smuzhiyun 			.base = {
3054*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha1),"
3055*4882a593Smuzhiyun 					    "rfc3686(ctr(aes)))",
3056*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha1-"
3057*4882a593Smuzhiyun 						   "rfc3686-ctr-aes-caam",
3058*4882a593Smuzhiyun 				.cra_blocksize = 1,
3059*4882a593Smuzhiyun 			},
3060*4882a593Smuzhiyun 			.setkey = aead_setkey,
3061*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
3062*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
3063*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
3064*4882a593Smuzhiyun 			.ivsize = CTR_RFC3686_IV_SIZE,
3065*4882a593Smuzhiyun 			.maxauthsize = SHA1_DIGEST_SIZE,
3066*4882a593Smuzhiyun 		},
3067*4882a593Smuzhiyun 		.caam = {
3068*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3069*4882a593Smuzhiyun 					   OP_ALG_AAI_CTR_MOD128,
3070*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3071*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
3072*4882a593Smuzhiyun 			.rfc3686 = true,
3073*4882a593Smuzhiyun 		},
3074*4882a593Smuzhiyun 	},
3075*4882a593Smuzhiyun 	{
3076*4882a593Smuzhiyun 		.aead = {
3077*4882a593Smuzhiyun 			.base = {
3078*4882a593Smuzhiyun 				.cra_name = "seqiv(authenc("
3079*4882a593Smuzhiyun 					    "hmac(sha1),rfc3686(ctr(aes))))",
3080*4882a593Smuzhiyun 				.cra_driver_name = "seqiv-authenc-hmac-sha1-"
3081*4882a593Smuzhiyun 						   "rfc3686-ctr-aes-caam",
3082*4882a593Smuzhiyun 				.cra_blocksize = 1,
3083*4882a593Smuzhiyun 			},
3084*4882a593Smuzhiyun 			.setkey = aead_setkey,
3085*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
3086*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
3087*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
3088*4882a593Smuzhiyun 			.ivsize = CTR_RFC3686_IV_SIZE,
3089*4882a593Smuzhiyun 			.maxauthsize = SHA1_DIGEST_SIZE,
3090*4882a593Smuzhiyun 		},
3091*4882a593Smuzhiyun 		.caam = {
3092*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3093*4882a593Smuzhiyun 					   OP_ALG_AAI_CTR_MOD128,
3094*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3095*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
3096*4882a593Smuzhiyun 			.rfc3686 = true,
3097*4882a593Smuzhiyun 			.geniv = true,
3098*4882a593Smuzhiyun 		},
3099*4882a593Smuzhiyun 	},
3100*4882a593Smuzhiyun 	{
3101*4882a593Smuzhiyun 		.aead = {
3102*4882a593Smuzhiyun 			.base = {
3103*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha224),"
3104*4882a593Smuzhiyun 					    "rfc3686(ctr(aes)))",
3105*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha224-"
3106*4882a593Smuzhiyun 						   "rfc3686-ctr-aes-caam",
3107*4882a593Smuzhiyun 				.cra_blocksize = 1,
3108*4882a593Smuzhiyun 			},
3109*4882a593Smuzhiyun 			.setkey = aead_setkey,
3110*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
3111*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
3112*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
3113*4882a593Smuzhiyun 			.ivsize = CTR_RFC3686_IV_SIZE,
3114*4882a593Smuzhiyun 			.maxauthsize = SHA224_DIGEST_SIZE,
3115*4882a593Smuzhiyun 		},
3116*4882a593Smuzhiyun 		.caam = {
3117*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3118*4882a593Smuzhiyun 					   OP_ALG_AAI_CTR_MOD128,
3119*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3120*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
3121*4882a593Smuzhiyun 			.rfc3686 = true,
3122*4882a593Smuzhiyun 		},
3123*4882a593Smuzhiyun 	},
3124*4882a593Smuzhiyun 	{
3125*4882a593Smuzhiyun 		.aead = {
3126*4882a593Smuzhiyun 			.base = {
3127*4882a593Smuzhiyun 				.cra_name = "seqiv(authenc("
3128*4882a593Smuzhiyun 					    "hmac(sha224),rfc3686(ctr(aes))))",
3129*4882a593Smuzhiyun 				.cra_driver_name = "seqiv-authenc-hmac-sha224-"
3130*4882a593Smuzhiyun 						   "rfc3686-ctr-aes-caam",
3131*4882a593Smuzhiyun 				.cra_blocksize = 1,
3132*4882a593Smuzhiyun 			},
3133*4882a593Smuzhiyun 			.setkey = aead_setkey,
3134*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
3135*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
3136*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
3137*4882a593Smuzhiyun 			.ivsize = CTR_RFC3686_IV_SIZE,
3138*4882a593Smuzhiyun 			.maxauthsize = SHA224_DIGEST_SIZE,
3139*4882a593Smuzhiyun 		},
3140*4882a593Smuzhiyun 		.caam = {
3141*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3142*4882a593Smuzhiyun 					   OP_ALG_AAI_CTR_MOD128,
3143*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3144*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
3145*4882a593Smuzhiyun 			.rfc3686 = true,
3146*4882a593Smuzhiyun 			.geniv = true,
3147*4882a593Smuzhiyun 		},
3148*4882a593Smuzhiyun 	},
3149*4882a593Smuzhiyun 	{
3150*4882a593Smuzhiyun 		.aead = {
3151*4882a593Smuzhiyun 			.base = {
3152*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha256),"
3153*4882a593Smuzhiyun 					    "rfc3686(ctr(aes)))",
3154*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha256-"
3155*4882a593Smuzhiyun 						   "rfc3686-ctr-aes-caam",
3156*4882a593Smuzhiyun 				.cra_blocksize = 1,
3157*4882a593Smuzhiyun 			},
3158*4882a593Smuzhiyun 			.setkey = aead_setkey,
3159*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
3160*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
3161*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
3162*4882a593Smuzhiyun 			.ivsize = CTR_RFC3686_IV_SIZE,
3163*4882a593Smuzhiyun 			.maxauthsize = SHA256_DIGEST_SIZE,
3164*4882a593Smuzhiyun 		},
3165*4882a593Smuzhiyun 		.caam = {
3166*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3167*4882a593Smuzhiyun 					   OP_ALG_AAI_CTR_MOD128,
3168*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3169*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
3170*4882a593Smuzhiyun 			.rfc3686 = true,
3171*4882a593Smuzhiyun 		},
3172*4882a593Smuzhiyun 	},
3173*4882a593Smuzhiyun 	{
3174*4882a593Smuzhiyun 		.aead = {
3175*4882a593Smuzhiyun 			.base = {
3176*4882a593Smuzhiyun 				.cra_name = "seqiv(authenc(hmac(sha256),"
3177*4882a593Smuzhiyun 					    "rfc3686(ctr(aes))))",
3178*4882a593Smuzhiyun 				.cra_driver_name = "seqiv-authenc-hmac-sha256-"
3179*4882a593Smuzhiyun 						   "rfc3686-ctr-aes-caam",
3180*4882a593Smuzhiyun 				.cra_blocksize = 1,
3181*4882a593Smuzhiyun 			},
3182*4882a593Smuzhiyun 			.setkey = aead_setkey,
3183*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
3184*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
3185*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
3186*4882a593Smuzhiyun 			.ivsize = CTR_RFC3686_IV_SIZE,
3187*4882a593Smuzhiyun 			.maxauthsize = SHA256_DIGEST_SIZE,
3188*4882a593Smuzhiyun 		},
3189*4882a593Smuzhiyun 		.caam = {
3190*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3191*4882a593Smuzhiyun 					   OP_ALG_AAI_CTR_MOD128,
3192*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3193*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
3194*4882a593Smuzhiyun 			.rfc3686 = true,
3195*4882a593Smuzhiyun 			.geniv = true,
3196*4882a593Smuzhiyun 		},
3197*4882a593Smuzhiyun 	},
3198*4882a593Smuzhiyun 	{
3199*4882a593Smuzhiyun 		.aead = {
3200*4882a593Smuzhiyun 			.base = {
3201*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha384),"
3202*4882a593Smuzhiyun 					    "rfc3686(ctr(aes)))",
3203*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha384-"
3204*4882a593Smuzhiyun 						   "rfc3686-ctr-aes-caam",
3205*4882a593Smuzhiyun 				.cra_blocksize = 1,
3206*4882a593Smuzhiyun 			},
3207*4882a593Smuzhiyun 			.setkey = aead_setkey,
3208*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
3209*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
3210*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
3211*4882a593Smuzhiyun 			.ivsize = CTR_RFC3686_IV_SIZE,
3212*4882a593Smuzhiyun 			.maxauthsize = SHA384_DIGEST_SIZE,
3213*4882a593Smuzhiyun 		},
3214*4882a593Smuzhiyun 		.caam = {
3215*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3216*4882a593Smuzhiyun 					   OP_ALG_AAI_CTR_MOD128,
3217*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3218*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
3219*4882a593Smuzhiyun 			.rfc3686 = true,
3220*4882a593Smuzhiyun 		},
3221*4882a593Smuzhiyun 	},
3222*4882a593Smuzhiyun 	{
3223*4882a593Smuzhiyun 		.aead = {
3224*4882a593Smuzhiyun 			.base = {
3225*4882a593Smuzhiyun 				.cra_name = "seqiv(authenc(hmac(sha384),"
3226*4882a593Smuzhiyun 					    "rfc3686(ctr(aes))))",
3227*4882a593Smuzhiyun 				.cra_driver_name = "seqiv-authenc-hmac-sha384-"
3228*4882a593Smuzhiyun 						   "rfc3686-ctr-aes-caam",
3229*4882a593Smuzhiyun 				.cra_blocksize = 1,
3230*4882a593Smuzhiyun 			},
3231*4882a593Smuzhiyun 			.setkey = aead_setkey,
3232*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
3233*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
3234*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
3235*4882a593Smuzhiyun 			.ivsize = CTR_RFC3686_IV_SIZE,
3236*4882a593Smuzhiyun 			.maxauthsize = SHA384_DIGEST_SIZE,
3237*4882a593Smuzhiyun 		},
3238*4882a593Smuzhiyun 		.caam = {
3239*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3240*4882a593Smuzhiyun 					   OP_ALG_AAI_CTR_MOD128,
3241*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3242*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
3243*4882a593Smuzhiyun 			.rfc3686 = true,
3244*4882a593Smuzhiyun 			.geniv = true,
3245*4882a593Smuzhiyun 		},
3246*4882a593Smuzhiyun 	},
3247*4882a593Smuzhiyun 	{
3248*4882a593Smuzhiyun 		.aead = {
3249*4882a593Smuzhiyun 			.base = {
3250*4882a593Smuzhiyun 				.cra_name = "authenc(hmac(sha512),"
3251*4882a593Smuzhiyun 					    "rfc3686(ctr(aes)))",
3252*4882a593Smuzhiyun 				.cra_driver_name = "authenc-hmac-sha512-"
3253*4882a593Smuzhiyun 						   "rfc3686-ctr-aes-caam",
3254*4882a593Smuzhiyun 				.cra_blocksize = 1,
3255*4882a593Smuzhiyun 			},
3256*4882a593Smuzhiyun 			.setkey = aead_setkey,
3257*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
3258*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
3259*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
3260*4882a593Smuzhiyun 			.ivsize = CTR_RFC3686_IV_SIZE,
3261*4882a593Smuzhiyun 			.maxauthsize = SHA512_DIGEST_SIZE,
3262*4882a593Smuzhiyun 		},
3263*4882a593Smuzhiyun 		.caam = {
3264*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3265*4882a593Smuzhiyun 					   OP_ALG_AAI_CTR_MOD128,
3266*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3267*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
3268*4882a593Smuzhiyun 			.rfc3686 = true,
3269*4882a593Smuzhiyun 		},
3270*4882a593Smuzhiyun 	},
3271*4882a593Smuzhiyun 	{
3272*4882a593Smuzhiyun 		.aead = {
3273*4882a593Smuzhiyun 			.base = {
3274*4882a593Smuzhiyun 				.cra_name = "seqiv(authenc(hmac(sha512),"
3275*4882a593Smuzhiyun 					    "rfc3686(ctr(aes))))",
3276*4882a593Smuzhiyun 				.cra_driver_name = "seqiv-authenc-hmac-sha512-"
3277*4882a593Smuzhiyun 						   "rfc3686-ctr-aes-caam",
3278*4882a593Smuzhiyun 				.cra_blocksize = 1,
3279*4882a593Smuzhiyun 			},
3280*4882a593Smuzhiyun 			.setkey = aead_setkey,
3281*4882a593Smuzhiyun 			.setauthsize = aead_setauthsize,
3282*4882a593Smuzhiyun 			.encrypt = aead_encrypt,
3283*4882a593Smuzhiyun 			.decrypt = aead_decrypt,
3284*4882a593Smuzhiyun 			.ivsize = CTR_RFC3686_IV_SIZE,
3285*4882a593Smuzhiyun 			.maxauthsize = SHA512_DIGEST_SIZE,
3286*4882a593Smuzhiyun 		},
3287*4882a593Smuzhiyun 		.caam = {
3288*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3289*4882a593Smuzhiyun 					   OP_ALG_AAI_CTR_MOD128,
3290*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3291*4882a593Smuzhiyun 					   OP_ALG_AAI_HMAC_PRECOMP,
3292*4882a593Smuzhiyun 			.rfc3686 = true,
3293*4882a593Smuzhiyun 			.geniv = true,
3294*4882a593Smuzhiyun 		},
3295*4882a593Smuzhiyun 	},
3296*4882a593Smuzhiyun 	{
3297*4882a593Smuzhiyun 		.aead = {
3298*4882a593Smuzhiyun 			.base = {
3299*4882a593Smuzhiyun 				.cra_name = "rfc7539(chacha20,poly1305)",
3300*4882a593Smuzhiyun 				.cra_driver_name = "rfc7539-chacha20-poly1305-"
3301*4882a593Smuzhiyun 						   "caam",
3302*4882a593Smuzhiyun 				.cra_blocksize = 1,
3303*4882a593Smuzhiyun 			},
3304*4882a593Smuzhiyun 			.setkey = chachapoly_setkey,
3305*4882a593Smuzhiyun 			.setauthsize = chachapoly_setauthsize,
3306*4882a593Smuzhiyun 			.encrypt = chachapoly_encrypt,
3307*4882a593Smuzhiyun 			.decrypt = chachapoly_decrypt,
3308*4882a593Smuzhiyun 			.ivsize = CHACHAPOLY_IV_SIZE,
3309*4882a593Smuzhiyun 			.maxauthsize = POLY1305_DIGEST_SIZE,
3310*4882a593Smuzhiyun 		},
3311*4882a593Smuzhiyun 		.caam = {
3312*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_CHACHA20 |
3313*4882a593Smuzhiyun 					   OP_ALG_AAI_AEAD,
3314*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_POLY1305 |
3315*4882a593Smuzhiyun 					   OP_ALG_AAI_AEAD,
3316*4882a593Smuzhiyun 			.nodkp = true,
3317*4882a593Smuzhiyun 		},
3318*4882a593Smuzhiyun 	},
3319*4882a593Smuzhiyun 	{
3320*4882a593Smuzhiyun 		.aead = {
3321*4882a593Smuzhiyun 			.base = {
3322*4882a593Smuzhiyun 				.cra_name = "rfc7539esp(chacha20,poly1305)",
3323*4882a593Smuzhiyun 				.cra_driver_name = "rfc7539esp-chacha20-"
3324*4882a593Smuzhiyun 						   "poly1305-caam",
3325*4882a593Smuzhiyun 				.cra_blocksize = 1,
3326*4882a593Smuzhiyun 			},
3327*4882a593Smuzhiyun 			.setkey = chachapoly_setkey,
3328*4882a593Smuzhiyun 			.setauthsize = chachapoly_setauthsize,
3329*4882a593Smuzhiyun 			.encrypt = chachapoly_encrypt,
3330*4882a593Smuzhiyun 			.decrypt = chachapoly_decrypt,
3331*4882a593Smuzhiyun 			.ivsize = 8,
3332*4882a593Smuzhiyun 			.maxauthsize = POLY1305_DIGEST_SIZE,
3333*4882a593Smuzhiyun 		},
3334*4882a593Smuzhiyun 		.caam = {
3335*4882a593Smuzhiyun 			.class1_alg_type = OP_ALG_ALGSEL_CHACHA20 |
3336*4882a593Smuzhiyun 					   OP_ALG_AAI_AEAD,
3337*4882a593Smuzhiyun 			.class2_alg_type = OP_ALG_ALGSEL_POLY1305 |
3338*4882a593Smuzhiyun 					   OP_ALG_AAI_AEAD,
3339*4882a593Smuzhiyun 			.nodkp = true,
3340*4882a593Smuzhiyun 		},
3341*4882a593Smuzhiyun 	},
3342*4882a593Smuzhiyun };
3343*4882a593Smuzhiyun 
caam_init_common(struct caam_ctx * ctx,struct caam_alg_entry * caam,bool uses_dkp)3344*4882a593Smuzhiyun static int caam_init_common(struct caam_ctx *ctx, struct caam_alg_entry *caam,
3345*4882a593Smuzhiyun 			    bool uses_dkp)
3346*4882a593Smuzhiyun {
3347*4882a593Smuzhiyun 	dma_addr_t dma_addr;
3348*4882a593Smuzhiyun 	struct caam_drv_private *priv;
3349*4882a593Smuzhiyun 	const size_t sh_desc_enc_offset = offsetof(struct caam_ctx,
3350*4882a593Smuzhiyun 						   sh_desc_enc);
3351*4882a593Smuzhiyun 
3352*4882a593Smuzhiyun 	ctx->jrdev = caam_jr_alloc();
3353*4882a593Smuzhiyun 	if (IS_ERR(ctx->jrdev)) {
3354*4882a593Smuzhiyun 		pr_err("Job Ring Device allocation for transform failed\n");
3355*4882a593Smuzhiyun 		return PTR_ERR(ctx->jrdev);
3356*4882a593Smuzhiyun 	}
3357*4882a593Smuzhiyun 
3358*4882a593Smuzhiyun 	priv = dev_get_drvdata(ctx->jrdev->parent);
3359*4882a593Smuzhiyun 	if (priv->era >= 6 && uses_dkp)
3360*4882a593Smuzhiyun 		ctx->dir = DMA_BIDIRECTIONAL;
3361*4882a593Smuzhiyun 	else
3362*4882a593Smuzhiyun 		ctx->dir = DMA_TO_DEVICE;
3363*4882a593Smuzhiyun 
3364*4882a593Smuzhiyun 	dma_addr = dma_map_single_attrs(ctx->jrdev, ctx->sh_desc_enc,
3365*4882a593Smuzhiyun 					offsetof(struct caam_ctx,
3366*4882a593Smuzhiyun 						 sh_desc_enc_dma) -
3367*4882a593Smuzhiyun 					sh_desc_enc_offset,
3368*4882a593Smuzhiyun 					ctx->dir, DMA_ATTR_SKIP_CPU_SYNC);
3369*4882a593Smuzhiyun 	if (dma_mapping_error(ctx->jrdev, dma_addr)) {
3370*4882a593Smuzhiyun 		dev_err(ctx->jrdev, "unable to map key, shared descriptors\n");
3371*4882a593Smuzhiyun 		caam_jr_free(ctx->jrdev);
3372*4882a593Smuzhiyun 		return -ENOMEM;
3373*4882a593Smuzhiyun 	}
3374*4882a593Smuzhiyun 
3375*4882a593Smuzhiyun 	ctx->sh_desc_enc_dma = dma_addr;
3376*4882a593Smuzhiyun 	ctx->sh_desc_dec_dma = dma_addr + offsetof(struct caam_ctx,
3377*4882a593Smuzhiyun 						   sh_desc_dec) -
3378*4882a593Smuzhiyun 					sh_desc_enc_offset;
3379*4882a593Smuzhiyun 	ctx->key_dma = dma_addr + offsetof(struct caam_ctx, key) -
3380*4882a593Smuzhiyun 					sh_desc_enc_offset;
3381*4882a593Smuzhiyun 
3382*4882a593Smuzhiyun 	/* copy descriptor header template value */
3383*4882a593Smuzhiyun 	ctx->cdata.algtype = OP_TYPE_CLASS1_ALG | caam->class1_alg_type;
3384*4882a593Smuzhiyun 	ctx->adata.algtype = OP_TYPE_CLASS2_ALG | caam->class2_alg_type;
3385*4882a593Smuzhiyun 
3386*4882a593Smuzhiyun 	return 0;
3387*4882a593Smuzhiyun }
3388*4882a593Smuzhiyun 
caam_cra_init(struct crypto_skcipher * tfm)3389*4882a593Smuzhiyun static int caam_cra_init(struct crypto_skcipher *tfm)
3390*4882a593Smuzhiyun {
3391*4882a593Smuzhiyun 	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
3392*4882a593Smuzhiyun 	struct caam_skcipher_alg *caam_alg =
3393*4882a593Smuzhiyun 		container_of(alg, typeof(*caam_alg), skcipher);
3394*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_skcipher_ctx(tfm);
3395*4882a593Smuzhiyun 	u32 alg_aai = caam_alg->caam.class1_alg_type & OP_ALG_AAI_MASK;
3396*4882a593Smuzhiyun 	int ret = 0;
3397*4882a593Smuzhiyun 
3398*4882a593Smuzhiyun 	ctx->enginectx.op.do_one_request = skcipher_do_one_req;
3399*4882a593Smuzhiyun 
3400*4882a593Smuzhiyun 	if (alg_aai == OP_ALG_AAI_XTS) {
3401*4882a593Smuzhiyun 		const char *tfm_name = crypto_tfm_alg_name(&tfm->base);
3402*4882a593Smuzhiyun 		struct crypto_skcipher *fallback;
3403*4882a593Smuzhiyun 
3404*4882a593Smuzhiyun 		fallback = crypto_alloc_skcipher(tfm_name, 0,
3405*4882a593Smuzhiyun 						 CRYPTO_ALG_NEED_FALLBACK);
3406*4882a593Smuzhiyun 		if (IS_ERR(fallback)) {
3407*4882a593Smuzhiyun 			pr_err("Failed to allocate %s fallback: %ld\n",
3408*4882a593Smuzhiyun 			       tfm_name, PTR_ERR(fallback));
3409*4882a593Smuzhiyun 			return PTR_ERR(fallback);
3410*4882a593Smuzhiyun 		}
3411*4882a593Smuzhiyun 
3412*4882a593Smuzhiyun 		ctx->fallback = fallback;
3413*4882a593Smuzhiyun 		crypto_skcipher_set_reqsize(tfm, sizeof(struct caam_skcipher_req_ctx) +
3414*4882a593Smuzhiyun 					    crypto_skcipher_reqsize(fallback));
3415*4882a593Smuzhiyun 	} else {
3416*4882a593Smuzhiyun 		crypto_skcipher_set_reqsize(tfm, sizeof(struct caam_skcipher_req_ctx));
3417*4882a593Smuzhiyun 	}
3418*4882a593Smuzhiyun 
3419*4882a593Smuzhiyun 	ret = caam_init_common(ctx, &caam_alg->caam, false);
3420*4882a593Smuzhiyun 	if (ret && ctx->fallback)
3421*4882a593Smuzhiyun 		crypto_free_skcipher(ctx->fallback);
3422*4882a593Smuzhiyun 
3423*4882a593Smuzhiyun 	return ret;
3424*4882a593Smuzhiyun }
3425*4882a593Smuzhiyun 
caam_aead_init(struct crypto_aead * tfm)3426*4882a593Smuzhiyun static int caam_aead_init(struct crypto_aead *tfm)
3427*4882a593Smuzhiyun {
3428*4882a593Smuzhiyun 	struct aead_alg *alg = crypto_aead_alg(tfm);
3429*4882a593Smuzhiyun 	struct caam_aead_alg *caam_alg =
3430*4882a593Smuzhiyun 		 container_of(alg, struct caam_aead_alg, aead);
3431*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_aead_ctx(tfm);
3432*4882a593Smuzhiyun 
3433*4882a593Smuzhiyun 	crypto_aead_set_reqsize(tfm, sizeof(struct caam_aead_req_ctx));
3434*4882a593Smuzhiyun 
3435*4882a593Smuzhiyun 	ctx->enginectx.op.do_one_request = aead_do_one_req;
3436*4882a593Smuzhiyun 
3437*4882a593Smuzhiyun 	return caam_init_common(ctx, &caam_alg->caam, !caam_alg->caam.nodkp);
3438*4882a593Smuzhiyun }
3439*4882a593Smuzhiyun 
caam_exit_common(struct caam_ctx * ctx)3440*4882a593Smuzhiyun static void caam_exit_common(struct caam_ctx *ctx)
3441*4882a593Smuzhiyun {
3442*4882a593Smuzhiyun 	dma_unmap_single_attrs(ctx->jrdev, ctx->sh_desc_enc_dma,
3443*4882a593Smuzhiyun 			       offsetof(struct caam_ctx, sh_desc_enc_dma) -
3444*4882a593Smuzhiyun 			       offsetof(struct caam_ctx, sh_desc_enc),
3445*4882a593Smuzhiyun 			       ctx->dir, DMA_ATTR_SKIP_CPU_SYNC);
3446*4882a593Smuzhiyun 	caam_jr_free(ctx->jrdev);
3447*4882a593Smuzhiyun }
3448*4882a593Smuzhiyun 
caam_cra_exit(struct crypto_skcipher * tfm)3449*4882a593Smuzhiyun static void caam_cra_exit(struct crypto_skcipher *tfm)
3450*4882a593Smuzhiyun {
3451*4882a593Smuzhiyun 	struct caam_ctx *ctx = crypto_skcipher_ctx(tfm);
3452*4882a593Smuzhiyun 
3453*4882a593Smuzhiyun 	if (ctx->fallback)
3454*4882a593Smuzhiyun 		crypto_free_skcipher(ctx->fallback);
3455*4882a593Smuzhiyun 	caam_exit_common(ctx);
3456*4882a593Smuzhiyun }
3457*4882a593Smuzhiyun 
caam_aead_exit(struct crypto_aead * tfm)3458*4882a593Smuzhiyun static void caam_aead_exit(struct crypto_aead *tfm)
3459*4882a593Smuzhiyun {
3460*4882a593Smuzhiyun 	caam_exit_common(crypto_aead_ctx(tfm));
3461*4882a593Smuzhiyun }
3462*4882a593Smuzhiyun 
caam_algapi_exit(void)3463*4882a593Smuzhiyun void caam_algapi_exit(void)
3464*4882a593Smuzhiyun {
3465*4882a593Smuzhiyun 	int i;
3466*4882a593Smuzhiyun 
3467*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
3468*4882a593Smuzhiyun 		struct caam_aead_alg *t_alg = driver_aeads + i;
3469*4882a593Smuzhiyun 
3470*4882a593Smuzhiyun 		if (t_alg->registered)
3471*4882a593Smuzhiyun 			crypto_unregister_aead(&t_alg->aead);
3472*4882a593Smuzhiyun 	}
3473*4882a593Smuzhiyun 
3474*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
3475*4882a593Smuzhiyun 		struct caam_skcipher_alg *t_alg = driver_algs + i;
3476*4882a593Smuzhiyun 
3477*4882a593Smuzhiyun 		if (t_alg->registered)
3478*4882a593Smuzhiyun 			crypto_unregister_skcipher(&t_alg->skcipher);
3479*4882a593Smuzhiyun 	}
3480*4882a593Smuzhiyun }
3481*4882a593Smuzhiyun 
caam_skcipher_alg_init(struct caam_skcipher_alg * t_alg)3482*4882a593Smuzhiyun static void caam_skcipher_alg_init(struct caam_skcipher_alg *t_alg)
3483*4882a593Smuzhiyun {
3484*4882a593Smuzhiyun 	struct skcipher_alg *alg = &t_alg->skcipher;
3485*4882a593Smuzhiyun 
3486*4882a593Smuzhiyun 	alg->base.cra_module = THIS_MODULE;
3487*4882a593Smuzhiyun 	alg->base.cra_priority = CAAM_CRA_PRIORITY;
3488*4882a593Smuzhiyun 	alg->base.cra_ctxsize = sizeof(struct caam_ctx);
3489*4882a593Smuzhiyun 	alg->base.cra_flags |= (CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
3490*4882a593Smuzhiyun 			      CRYPTO_ALG_KERN_DRIVER_ONLY);
3491*4882a593Smuzhiyun 
3492*4882a593Smuzhiyun 	alg->init = caam_cra_init;
3493*4882a593Smuzhiyun 	alg->exit = caam_cra_exit;
3494*4882a593Smuzhiyun }
3495*4882a593Smuzhiyun 
caam_aead_alg_init(struct caam_aead_alg * t_alg)3496*4882a593Smuzhiyun static void caam_aead_alg_init(struct caam_aead_alg *t_alg)
3497*4882a593Smuzhiyun {
3498*4882a593Smuzhiyun 	struct aead_alg *alg = &t_alg->aead;
3499*4882a593Smuzhiyun 
3500*4882a593Smuzhiyun 	alg->base.cra_module = THIS_MODULE;
3501*4882a593Smuzhiyun 	alg->base.cra_priority = CAAM_CRA_PRIORITY;
3502*4882a593Smuzhiyun 	alg->base.cra_ctxsize = sizeof(struct caam_ctx);
3503*4882a593Smuzhiyun 	alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
3504*4882a593Smuzhiyun 			      CRYPTO_ALG_KERN_DRIVER_ONLY;
3505*4882a593Smuzhiyun 
3506*4882a593Smuzhiyun 	alg->init = caam_aead_init;
3507*4882a593Smuzhiyun 	alg->exit = caam_aead_exit;
3508*4882a593Smuzhiyun }
3509*4882a593Smuzhiyun 
caam_algapi_init(struct device * ctrldev)3510*4882a593Smuzhiyun int caam_algapi_init(struct device *ctrldev)
3511*4882a593Smuzhiyun {
3512*4882a593Smuzhiyun 	struct caam_drv_private *priv = dev_get_drvdata(ctrldev);
3513*4882a593Smuzhiyun 	int i = 0, err = 0;
3514*4882a593Smuzhiyun 	u32 aes_vid, aes_inst, des_inst, md_vid, md_inst, ccha_inst, ptha_inst;
3515*4882a593Smuzhiyun 	unsigned int md_limit = SHA512_DIGEST_SIZE;
3516*4882a593Smuzhiyun 	bool registered = false, gcm_support;
3517*4882a593Smuzhiyun 
3518*4882a593Smuzhiyun 	/*
3519*4882a593Smuzhiyun 	 * Register crypto algorithms the device supports.
3520*4882a593Smuzhiyun 	 * First, detect presence and attributes of DES, AES, and MD blocks.
3521*4882a593Smuzhiyun 	 */
3522*4882a593Smuzhiyun 	if (priv->era < 10) {
3523*4882a593Smuzhiyun 		u32 cha_vid, cha_inst, aes_rn;
3524*4882a593Smuzhiyun 
3525*4882a593Smuzhiyun 		cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
3526*4882a593Smuzhiyun 		aes_vid = cha_vid & CHA_ID_LS_AES_MASK;
3527*4882a593Smuzhiyun 		md_vid = (cha_vid & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
3528*4882a593Smuzhiyun 
3529*4882a593Smuzhiyun 		cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
3530*4882a593Smuzhiyun 		des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >>
3531*4882a593Smuzhiyun 			   CHA_ID_LS_DES_SHIFT;
3532*4882a593Smuzhiyun 		aes_inst = cha_inst & CHA_ID_LS_AES_MASK;
3533*4882a593Smuzhiyun 		md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
3534*4882a593Smuzhiyun 		ccha_inst = 0;
3535*4882a593Smuzhiyun 		ptha_inst = 0;
3536*4882a593Smuzhiyun 
3537*4882a593Smuzhiyun 		aes_rn = rd_reg32(&priv->ctrl->perfmon.cha_rev_ls) &
3538*4882a593Smuzhiyun 			 CHA_ID_LS_AES_MASK;
3539*4882a593Smuzhiyun 		gcm_support = !(aes_vid == CHA_VER_VID_AES_LP && aes_rn < 8);
3540*4882a593Smuzhiyun 	} else {
3541*4882a593Smuzhiyun 		u32 aesa, mdha;
3542*4882a593Smuzhiyun 
3543*4882a593Smuzhiyun 		aesa = rd_reg32(&priv->ctrl->vreg.aesa);
3544*4882a593Smuzhiyun 		mdha = rd_reg32(&priv->ctrl->vreg.mdha);
3545*4882a593Smuzhiyun 
3546*4882a593Smuzhiyun 		aes_vid = (aesa & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
3547*4882a593Smuzhiyun 		md_vid = (mdha & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
3548*4882a593Smuzhiyun 
3549*4882a593Smuzhiyun 		des_inst = rd_reg32(&priv->ctrl->vreg.desa) & CHA_VER_NUM_MASK;
3550*4882a593Smuzhiyun 		aes_inst = aesa & CHA_VER_NUM_MASK;
3551*4882a593Smuzhiyun 		md_inst = mdha & CHA_VER_NUM_MASK;
3552*4882a593Smuzhiyun 		ccha_inst = rd_reg32(&priv->ctrl->vreg.ccha) & CHA_VER_NUM_MASK;
3553*4882a593Smuzhiyun 		ptha_inst = rd_reg32(&priv->ctrl->vreg.ptha) & CHA_VER_NUM_MASK;
3554*4882a593Smuzhiyun 
3555*4882a593Smuzhiyun 		gcm_support = aesa & CHA_VER_MISC_AES_GCM;
3556*4882a593Smuzhiyun 	}
3557*4882a593Smuzhiyun 
3558*4882a593Smuzhiyun 	/* If MD is present, limit digest size based on LP256 */
3559*4882a593Smuzhiyun 	if (md_inst && md_vid  == CHA_VER_VID_MD_LP256)
3560*4882a593Smuzhiyun 		md_limit = SHA256_DIGEST_SIZE;
3561*4882a593Smuzhiyun 
3562*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
3563*4882a593Smuzhiyun 		struct caam_skcipher_alg *t_alg = driver_algs + i;
3564*4882a593Smuzhiyun 		u32 alg_sel = t_alg->caam.class1_alg_type & OP_ALG_ALGSEL_MASK;
3565*4882a593Smuzhiyun 
3566*4882a593Smuzhiyun 		/* Skip DES algorithms if not supported by device */
3567*4882a593Smuzhiyun 		if (!des_inst &&
3568*4882a593Smuzhiyun 		    ((alg_sel == OP_ALG_ALGSEL_3DES) ||
3569*4882a593Smuzhiyun 		     (alg_sel == OP_ALG_ALGSEL_DES)))
3570*4882a593Smuzhiyun 				continue;
3571*4882a593Smuzhiyun 
3572*4882a593Smuzhiyun 		/* Skip AES algorithms if not supported by device */
3573*4882a593Smuzhiyun 		if (!aes_inst && (alg_sel == OP_ALG_ALGSEL_AES))
3574*4882a593Smuzhiyun 				continue;
3575*4882a593Smuzhiyun 
3576*4882a593Smuzhiyun 		/*
3577*4882a593Smuzhiyun 		 * Check support for AES modes not available
3578*4882a593Smuzhiyun 		 * on LP devices.
3579*4882a593Smuzhiyun 		 */
3580*4882a593Smuzhiyun 		if (aes_vid == CHA_VER_VID_AES_LP &&
3581*4882a593Smuzhiyun 		    (t_alg->caam.class1_alg_type & OP_ALG_AAI_MASK) ==
3582*4882a593Smuzhiyun 		    OP_ALG_AAI_XTS)
3583*4882a593Smuzhiyun 			continue;
3584*4882a593Smuzhiyun 
3585*4882a593Smuzhiyun 		caam_skcipher_alg_init(t_alg);
3586*4882a593Smuzhiyun 
3587*4882a593Smuzhiyun 		err = crypto_register_skcipher(&t_alg->skcipher);
3588*4882a593Smuzhiyun 		if (err) {
3589*4882a593Smuzhiyun 			pr_warn("%s alg registration failed\n",
3590*4882a593Smuzhiyun 				t_alg->skcipher.base.cra_driver_name);
3591*4882a593Smuzhiyun 			continue;
3592*4882a593Smuzhiyun 		}
3593*4882a593Smuzhiyun 
3594*4882a593Smuzhiyun 		t_alg->registered = true;
3595*4882a593Smuzhiyun 		registered = true;
3596*4882a593Smuzhiyun 	}
3597*4882a593Smuzhiyun 
3598*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
3599*4882a593Smuzhiyun 		struct caam_aead_alg *t_alg = driver_aeads + i;
3600*4882a593Smuzhiyun 		u32 c1_alg_sel = t_alg->caam.class1_alg_type &
3601*4882a593Smuzhiyun 				 OP_ALG_ALGSEL_MASK;
3602*4882a593Smuzhiyun 		u32 c2_alg_sel = t_alg->caam.class2_alg_type &
3603*4882a593Smuzhiyun 				 OP_ALG_ALGSEL_MASK;
3604*4882a593Smuzhiyun 		u32 alg_aai = t_alg->caam.class1_alg_type & OP_ALG_AAI_MASK;
3605*4882a593Smuzhiyun 
3606*4882a593Smuzhiyun 		/* Skip DES algorithms if not supported by device */
3607*4882a593Smuzhiyun 		if (!des_inst &&
3608*4882a593Smuzhiyun 		    ((c1_alg_sel == OP_ALG_ALGSEL_3DES) ||
3609*4882a593Smuzhiyun 		     (c1_alg_sel == OP_ALG_ALGSEL_DES)))
3610*4882a593Smuzhiyun 				continue;
3611*4882a593Smuzhiyun 
3612*4882a593Smuzhiyun 		/* Skip AES algorithms if not supported by device */
3613*4882a593Smuzhiyun 		if (!aes_inst && (c1_alg_sel == OP_ALG_ALGSEL_AES))
3614*4882a593Smuzhiyun 				continue;
3615*4882a593Smuzhiyun 
3616*4882a593Smuzhiyun 		/* Skip CHACHA20 algorithms if not supported by device */
3617*4882a593Smuzhiyun 		if (c1_alg_sel == OP_ALG_ALGSEL_CHACHA20 && !ccha_inst)
3618*4882a593Smuzhiyun 			continue;
3619*4882a593Smuzhiyun 
3620*4882a593Smuzhiyun 		/* Skip POLY1305 algorithms if not supported by device */
3621*4882a593Smuzhiyun 		if (c2_alg_sel == OP_ALG_ALGSEL_POLY1305 && !ptha_inst)
3622*4882a593Smuzhiyun 			continue;
3623*4882a593Smuzhiyun 
3624*4882a593Smuzhiyun 		/* Skip GCM algorithms if not supported by device */
3625*4882a593Smuzhiyun 		if (c1_alg_sel == OP_ALG_ALGSEL_AES &&
3626*4882a593Smuzhiyun 		    alg_aai == OP_ALG_AAI_GCM && !gcm_support)
3627*4882a593Smuzhiyun 			continue;
3628*4882a593Smuzhiyun 
3629*4882a593Smuzhiyun 		/*
3630*4882a593Smuzhiyun 		 * Skip algorithms requiring message digests
3631*4882a593Smuzhiyun 		 * if MD or MD size is not supported by device.
3632*4882a593Smuzhiyun 		 */
3633*4882a593Smuzhiyun 		if (is_mdha(c2_alg_sel) &&
3634*4882a593Smuzhiyun 		    (!md_inst || t_alg->aead.maxauthsize > md_limit))
3635*4882a593Smuzhiyun 			continue;
3636*4882a593Smuzhiyun 
3637*4882a593Smuzhiyun 		caam_aead_alg_init(t_alg);
3638*4882a593Smuzhiyun 
3639*4882a593Smuzhiyun 		err = crypto_register_aead(&t_alg->aead);
3640*4882a593Smuzhiyun 		if (err) {
3641*4882a593Smuzhiyun 			pr_warn("%s alg registration failed\n",
3642*4882a593Smuzhiyun 				t_alg->aead.base.cra_driver_name);
3643*4882a593Smuzhiyun 			continue;
3644*4882a593Smuzhiyun 		}
3645*4882a593Smuzhiyun 
3646*4882a593Smuzhiyun 		t_alg->registered = true;
3647*4882a593Smuzhiyun 		registered = true;
3648*4882a593Smuzhiyun 	}
3649*4882a593Smuzhiyun 
3650*4882a593Smuzhiyun 	if (registered)
3651*4882a593Smuzhiyun 		pr_info("caam algorithms registered in /proc/crypto\n");
3652*4882a593Smuzhiyun 
3653*4882a593Smuzhiyun 	return err;
3654*4882a593Smuzhiyun }
3655