xref: /openbmc/linux/drivers/crypto/caam/caamalg.c (revision 115957bb)
18e8ec596SKim Phillips /*
28e8ec596SKim Phillips  * caam - Freescale FSL CAAM support for crypto API
38e8ec596SKim Phillips  *
48e8ec596SKim Phillips  * Copyright 2008-2011 Freescale Semiconductor, Inc.
58cea7b66SHoria Geantă  * Copyright 2016 NXP
68e8ec596SKim Phillips  *
78e8ec596SKim Phillips  * Based on talitos crypto API driver.
88e8ec596SKim Phillips  *
98e8ec596SKim Phillips  * relationship of job descriptors to shared descriptors (SteveC Dec 10 2008):
108e8ec596SKim Phillips  *
118e8ec596SKim Phillips  * ---------------                     ---------------
128e8ec596SKim Phillips  * | JobDesc #1  |-------------------->|  ShareDesc  |
138e8ec596SKim Phillips  * | *(packet 1) |                     |   (PDB)     |
148e8ec596SKim Phillips  * ---------------      |------------->|  (hashKey)  |
158e8ec596SKim Phillips  *       .              |              | (cipherKey) |
168e8ec596SKim Phillips  *       .              |    |-------->| (operation) |
178e8ec596SKim Phillips  * ---------------      |    |         ---------------
188e8ec596SKim Phillips  * | JobDesc #2  |------|    |
198e8ec596SKim Phillips  * | *(packet 2) |           |
208e8ec596SKim Phillips  * ---------------           |
218e8ec596SKim Phillips  *       .                   |
228e8ec596SKim Phillips  *       .                   |
238e8ec596SKim Phillips  * ---------------           |
248e8ec596SKim Phillips  * | JobDesc #3  |------------
258e8ec596SKim Phillips  * | *(packet 3) |
268e8ec596SKim Phillips  * ---------------
278e8ec596SKim Phillips  *
288e8ec596SKim Phillips  * The SharedDesc never changes for a connection unless rekeyed, but
298e8ec596SKim Phillips  * each packet will likely be in a different place. So all we need
308e8ec596SKim Phillips  * to know to process the packet is where the input is, where the
318e8ec596SKim Phillips  * output goes, and what context we want to process with. Context is
328e8ec596SKim Phillips  * in the SharedDesc, packet references in the JobDesc.
338e8ec596SKim Phillips  *
348e8ec596SKim Phillips  * So, a job desc looks like:
358e8ec596SKim Phillips  *
368e8ec596SKim Phillips  * ---------------------
378e8ec596SKim Phillips  * | Header            |
388e8ec596SKim Phillips  * | ShareDesc Pointer |
398e8ec596SKim Phillips  * | SEQ_OUT_PTR       |
408e8ec596SKim Phillips  * | (output buffer)   |
416ec47334SYuan Kang  * | (output length)   |
428e8ec596SKim Phillips  * | SEQ_IN_PTR        |
438e8ec596SKim Phillips  * | (input buffer)    |
446ec47334SYuan Kang  * | (input length)    |
458e8ec596SKim Phillips  * ---------------------
468e8ec596SKim Phillips  */
478e8ec596SKim Phillips 
488e8ec596SKim Phillips #include "compat.h"
498e8ec596SKim Phillips 
508e8ec596SKim Phillips #include "regs.h"
518e8ec596SKim Phillips #include "intern.h"
528e8ec596SKim Phillips #include "desc_constr.h"
538e8ec596SKim Phillips #include "jr.h"
548e8ec596SKim Phillips #include "error.h"
55a299c837SYuan Kang #include "sg_sw_sec4.h"
564c1ec1f9SYuan Kang #include "key_gen.h"
578cea7b66SHoria Geantă #include "caamalg_desc.h"
588e8ec596SKim Phillips 
598e8ec596SKim Phillips /*
608e8ec596SKim Phillips  * crypto alg
618e8ec596SKim Phillips  */
628e8ec596SKim Phillips #define CAAM_CRA_PRIORITY		3000
638e8ec596SKim Phillips /* max key is sum of AES_MAX_KEY_SIZE, max split key size */
648e8ec596SKim Phillips #define CAAM_MAX_KEY_SIZE		(AES_MAX_KEY_SIZE + \
65daebc465SCatalin Vasile 					 CTR_RFC3686_NONCE_SIZE + \
668e8ec596SKim Phillips 					 SHA512_DIGEST_SIZE * 2)
678e8ec596SKim Phillips 
68f2147b88SHerbert Xu #define AEAD_DESC_JOB_IO_LEN		(DESC_JOB_IO_LEN + CAAM_CMD_SZ * 2)
69f2147b88SHerbert Xu #define GCM_DESC_JOB_IO_LEN		(AEAD_DESC_JOB_IO_LEN + \
70f2147b88SHerbert Xu 					 CAAM_CMD_SZ * 4)
71479bcc7cSHerbert Xu #define AUTHENC_DESC_JOB_IO_LEN		(AEAD_DESC_JOB_IO_LEN + \
72479bcc7cSHerbert Xu 					 CAAM_CMD_SZ * 5)
73f2147b88SHerbert Xu 
7487e51b07SHerbert Xu #define DESC_MAX_USED_BYTES		(CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN)
7587e51b07SHerbert Xu #define DESC_MAX_USED_LEN		(DESC_MAX_USED_BYTES / CAAM_CMD_SZ)
764427b1b4SKim Phillips 
778e8ec596SKim Phillips #ifdef DEBUG
788e8ec596SKim Phillips /* for print_hex_dumps with line references */
798e8ec596SKim Phillips #define debug(format, arg...) printk(format, arg)
808e8ec596SKim Phillips #else
818e8ec596SKim Phillips #define debug(format, arg...)
828e8ec596SKim Phillips #endif
835ecf8ef9SCatalin Vasile 
84cfc6f11bSRuchika Gupta static struct list_head alg_list;
858e8ec596SKim Phillips 
86479bcc7cSHerbert Xu struct caam_alg_entry {
87479bcc7cSHerbert Xu 	int class1_alg_type;
88479bcc7cSHerbert Xu 	int class2_alg_type;
89479bcc7cSHerbert Xu 	bool rfc3686;
90479bcc7cSHerbert Xu 	bool geniv;
91479bcc7cSHerbert Xu };
92479bcc7cSHerbert Xu 
93479bcc7cSHerbert Xu struct caam_aead_alg {
94479bcc7cSHerbert Xu 	struct aead_alg aead;
95479bcc7cSHerbert Xu 	struct caam_alg_entry caam;
96479bcc7cSHerbert Xu 	bool registered;
97479bcc7cSHerbert Xu };
98479bcc7cSHerbert Xu 
99acdca31dSYuan Kang /*
1008e8ec596SKim Phillips  * per-session context
1018e8ec596SKim Phillips  */
1028e8ec596SKim Phillips struct caam_ctx {
1031acebad3SYuan Kang 	u32 sh_desc_enc[DESC_MAX_USED_LEN];
1041acebad3SYuan Kang 	u32 sh_desc_dec[DESC_MAX_USED_LEN];
1051acebad3SYuan Kang 	u32 sh_desc_givenc[DESC_MAX_USED_LEN];
106bbf22344SHoria Geantă 	u8 key[CAAM_MAX_KEY_SIZE];
1071acebad3SYuan Kang 	dma_addr_t sh_desc_enc_dma;
1081acebad3SYuan Kang 	dma_addr_t sh_desc_dec_dma;
1091acebad3SYuan Kang 	dma_addr_t sh_desc_givenc_dma;
110885e9e2fSYuan Kang 	dma_addr_t key_dma;
1117e0880b9SHoria Geantă 	enum dma_data_direction dir;
112bbf22344SHoria Geantă 	struct device *jrdev;
113db57656bSHoria Geantă 	struct alginfo adata;
114db57656bSHoria Geantă 	struct alginfo cdata;
1158e8ec596SKim Phillips 	unsigned int authsize;
1168e8ec596SKim Phillips };
1178e8ec596SKim Phillips 
118ae4a825fSHoria Geanta static int aead_null_set_sh_desc(struct crypto_aead *aead)
119ae4a825fSHoria Geanta {
120ae4a825fSHoria Geanta 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
121ae4a825fSHoria Geanta 	struct device *jrdev = ctx->jrdev;
1227e0880b9SHoria Geantă 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
123ae4a825fSHoria Geanta 	u32 *desc;
1244cbe79ccSHoria Geantă 	int rem_bytes = CAAM_DESC_BYTES_MAX - AEAD_DESC_JOB_IO_LEN -
1254cbe79ccSHoria Geantă 			ctx->adata.keylen_pad;
126ae4a825fSHoria Geanta 
127ae4a825fSHoria Geanta 	/*
128ae4a825fSHoria Geanta 	 * Job Descriptor and Shared Descriptors
129ae4a825fSHoria Geanta 	 * must all fit into the 64-word Descriptor h/w Buffer
130ae4a825fSHoria Geanta 	 */
1314cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_AEAD_NULL_ENC_LEN) {
132db57656bSHoria Geantă 		ctx->adata.key_inline = true;
1339c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
134db57656bSHoria Geantă 	} else {
135db57656bSHoria Geantă 		ctx->adata.key_inline = false;
1369c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
137db57656bSHoria Geantă 	}
138ae4a825fSHoria Geanta 
139479bcc7cSHerbert Xu 	/* aead_encrypt shared descriptor */
140ae4a825fSHoria Geanta 	desc = ctx->sh_desc_enc;
1417e0880b9SHoria Geantă 	cnstr_shdsc_aead_null_encap(desc, &ctx->adata, ctx->authsize,
1427e0880b9SHoria Geantă 				    ctrlpriv->era);
143bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
1447e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
145ae4a825fSHoria Geanta 
146ae4a825fSHoria Geanta 	/*
147ae4a825fSHoria Geanta 	 * Job Descriptor and Shared Descriptors
148ae4a825fSHoria Geanta 	 * must all fit into the 64-word Descriptor h/w Buffer
149ae4a825fSHoria Geanta 	 */
1504cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_AEAD_NULL_DEC_LEN) {
151db57656bSHoria Geantă 		ctx->adata.key_inline = true;
1529c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
153db57656bSHoria Geantă 	} else {
154db57656bSHoria Geantă 		ctx->adata.key_inline = false;
1559c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
156db57656bSHoria Geantă 	}
157ae4a825fSHoria Geanta 
158479bcc7cSHerbert Xu 	/* aead_decrypt shared descriptor */
1598cea7b66SHoria Geantă 	desc = ctx->sh_desc_dec;
1607e0880b9SHoria Geantă 	cnstr_shdsc_aead_null_decap(desc, &ctx->adata, ctx->authsize,
1617e0880b9SHoria Geantă 				    ctrlpriv->era);
162bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
1637e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
164ae4a825fSHoria Geanta 
165ae4a825fSHoria Geanta 	return 0;
166ae4a825fSHoria Geanta }
167ae4a825fSHoria Geanta 
1681acebad3SYuan Kang static int aead_set_sh_desc(struct crypto_aead *aead)
1691acebad3SYuan Kang {
170479bcc7cSHerbert Xu 	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
171479bcc7cSHerbert Xu 						 struct caam_aead_alg, aead);
172add86d55SHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
1731acebad3SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1741acebad3SYuan Kang 	struct device *jrdev = ctx->jrdev;
1757e0880b9SHoria Geantă 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
176daebc465SCatalin Vasile 	u32 ctx1_iv_off = 0;
1778cea7b66SHoria Geantă 	u32 *desc, *nonce = NULL;
1784cbe79ccSHoria Geantă 	u32 inl_mask;
1794cbe79ccSHoria Geantă 	unsigned int data_len[2];
180db57656bSHoria Geantă 	const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
181daebc465SCatalin Vasile 			       OP_ALG_AAI_CTR_MOD128);
182479bcc7cSHerbert Xu 	const bool is_rfc3686 = alg->caam.rfc3686;
1831acebad3SYuan Kang 
1842fdea258SHoria Geantă 	if (!ctx->authsize)
1852fdea258SHoria Geantă 		return 0;
1862fdea258SHoria Geantă 
187ae4a825fSHoria Geanta 	/* NULL encryption / decryption */
188db57656bSHoria Geantă 	if (!ctx->cdata.keylen)
189ae4a825fSHoria Geanta 		return aead_null_set_sh_desc(aead);
190ae4a825fSHoria Geanta 
1911acebad3SYuan Kang 	/*
192daebc465SCatalin Vasile 	 * AES-CTR needs to load IV in CONTEXT1 reg
193daebc465SCatalin Vasile 	 * at an offset of 128bits (16bytes)
194daebc465SCatalin Vasile 	 * CONTEXT1[255:128] = IV
195daebc465SCatalin Vasile 	 */
196daebc465SCatalin Vasile 	if (ctr_mode)
197daebc465SCatalin Vasile 		ctx1_iv_off = 16;
198daebc465SCatalin Vasile 
199daebc465SCatalin Vasile 	/*
200daebc465SCatalin Vasile 	 * RFC3686 specific:
201daebc465SCatalin Vasile 	 *	CONTEXT1[255:128] = {NONCE, IV, COUNTER}
202daebc465SCatalin Vasile 	 */
2038cea7b66SHoria Geantă 	if (is_rfc3686) {
204daebc465SCatalin Vasile 		ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
2058cea7b66SHoria Geantă 		nonce = (u32 *)((void *)ctx->key + ctx->adata.keylen_pad +
2068cea7b66SHoria Geantă 				ctx->cdata.keylen - CTR_RFC3686_NONCE_SIZE);
2078cea7b66SHoria Geantă 	}
208daebc465SCatalin Vasile 
2094cbe79ccSHoria Geantă 	data_len[0] = ctx->adata.keylen_pad;
2104cbe79ccSHoria Geantă 	data_len[1] = ctx->cdata.keylen;
2114cbe79ccSHoria Geantă 
212479bcc7cSHerbert Xu 	if (alg->caam.geniv)
213479bcc7cSHerbert Xu 		goto skip_enc;
214479bcc7cSHerbert Xu 
215daebc465SCatalin Vasile 	/*
2161acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
2171acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
2181acebad3SYuan Kang 	 */
2194cbe79ccSHoria Geantă 	if (desc_inline_query(DESC_AEAD_ENC_LEN +
2204cbe79ccSHoria Geantă 			      (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
2214cbe79ccSHoria Geantă 			      AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
2224cbe79ccSHoria Geantă 			      ARRAY_SIZE(data_len)) < 0)
2234cbe79ccSHoria Geantă 		return -EINVAL;
2244cbe79ccSHoria Geantă 
2254cbe79ccSHoria Geantă 	if (inl_mask & 1)
2269c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
2274cbe79ccSHoria Geantă 	else
2289c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
2294cbe79ccSHoria Geantă 
2304cbe79ccSHoria Geantă 	if (inl_mask & 2)
2319c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
2324cbe79ccSHoria Geantă 	else
2339c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
2344cbe79ccSHoria Geantă 
2354cbe79ccSHoria Geantă 	ctx->adata.key_inline = !!(inl_mask & 1);
2364cbe79ccSHoria Geantă 	ctx->cdata.key_inline = !!(inl_mask & 2);
2371acebad3SYuan Kang 
238479bcc7cSHerbert Xu 	/* aead_encrypt shared descriptor */
2391acebad3SYuan Kang 	desc = ctx->sh_desc_enc;
240b189817cSHoria Geantă 	cnstr_shdsc_aead_encap(desc, &ctx->cdata, &ctx->adata, ivsize,
241b189817cSHoria Geantă 			       ctx->authsize, is_rfc3686, nonce, ctx1_iv_off,
2427e0880b9SHoria Geantă 			       false, ctrlpriv->era);
243bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
2447e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
2451acebad3SYuan Kang 
246479bcc7cSHerbert Xu skip_enc:
2471acebad3SYuan Kang 	/*
2481acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
2491acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
2501acebad3SYuan Kang 	 */
2514cbe79ccSHoria Geantă 	if (desc_inline_query(DESC_AEAD_DEC_LEN +
2524cbe79ccSHoria Geantă 			      (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
2534cbe79ccSHoria Geantă 			      AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
2544cbe79ccSHoria Geantă 			      ARRAY_SIZE(data_len)) < 0)
2554cbe79ccSHoria Geantă 		return -EINVAL;
2564cbe79ccSHoria Geantă 
2574cbe79ccSHoria Geantă 	if (inl_mask & 1)
2589c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
2594cbe79ccSHoria Geantă 	else
2609c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
2614cbe79ccSHoria Geantă 
2624cbe79ccSHoria Geantă 	if (inl_mask & 2)
2639c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
2644cbe79ccSHoria Geantă 	else
2659c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
2664cbe79ccSHoria Geantă 
2674cbe79ccSHoria Geantă 	ctx->adata.key_inline = !!(inl_mask & 1);
2684cbe79ccSHoria Geantă 	ctx->cdata.key_inline = !!(inl_mask & 2);
2691acebad3SYuan Kang 
270479bcc7cSHerbert Xu 	/* aead_decrypt shared descriptor */
2711acebad3SYuan Kang 	desc = ctx->sh_desc_dec;
2728cea7b66SHoria Geantă 	cnstr_shdsc_aead_decap(desc, &ctx->cdata, &ctx->adata, ivsize,
2738cea7b66SHoria Geantă 			       ctx->authsize, alg->caam.geniv, is_rfc3686,
2747e0880b9SHoria Geantă 			       nonce, ctx1_iv_off, false, ctrlpriv->era);
275bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
2767e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
2771acebad3SYuan Kang 
278479bcc7cSHerbert Xu 	if (!alg->caam.geniv)
279479bcc7cSHerbert Xu 		goto skip_givenc;
280479bcc7cSHerbert Xu 
2811acebad3SYuan Kang 	/*
2821acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
2831acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
2841acebad3SYuan Kang 	 */
2854cbe79ccSHoria Geantă 	if (desc_inline_query(DESC_AEAD_GIVENC_LEN +
2864cbe79ccSHoria Geantă 			      (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
2874cbe79ccSHoria Geantă 			      AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
2884cbe79ccSHoria Geantă 			      ARRAY_SIZE(data_len)) < 0)
2894cbe79ccSHoria Geantă 		return -EINVAL;
2904cbe79ccSHoria Geantă 
2914cbe79ccSHoria Geantă 	if (inl_mask & 1)
2929c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
2934cbe79ccSHoria Geantă 	else
2949c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
2954cbe79ccSHoria Geantă 
2964cbe79ccSHoria Geantă 	if (inl_mask & 2)
2979c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
2984cbe79ccSHoria Geantă 	else
2999c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
3004cbe79ccSHoria Geantă 
3014cbe79ccSHoria Geantă 	ctx->adata.key_inline = !!(inl_mask & 1);
3024cbe79ccSHoria Geantă 	ctx->cdata.key_inline = !!(inl_mask & 2);
3031acebad3SYuan Kang 
3041acebad3SYuan Kang 	/* aead_givencrypt shared descriptor */
3051d2d87e8SHoria Geantă 	desc = ctx->sh_desc_enc;
3068cea7b66SHoria Geantă 	cnstr_shdsc_aead_givencap(desc, &ctx->cdata, &ctx->adata, ivsize,
3078cea7b66SHoria Geantă 				  ctx->authsize, is_rfc3686, nonce,
3087e0880b9SHoria Geantă 				  ctx1_iv_off, false, ctrlpriv->era);
309bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
3107e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
3111acebad3SYuan Kang 
312479bcc7cSHerbert Xu skip_givenc:
3131acebad3SYuan Kang 	return 0;
3141acebad3SYuan Kang }
3151acebad3SYuan Kang 
3160e479300SYuan Kang static int aead_setauthsize(struct crypto_aead *authenc,
3178e8ec596SKim Phillips 				    unsigned int authsize)
3188e8ec596SKim Phillips {
3198e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
3208e8ec596SKim Phillips 
3218e8ec596SKim Phillips 	ctx->authsize = authsize;
3221acebad3SYuan Kang 	aead_set_sh_desc(authenc);
3238e8ec596SKim Phillips 
3248e8ec596SKim Phillips 	return 0;
3258e8ec596SKim Phillips }
3268e8ec596SKim Phillips 
3273ef8d945STudor Ambarus static int gcm_set_sh_desc(struct crypto_aead *aead)
3283ef8d945STudor Ambarus {
3293ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
3303ef8d945STudor Ambarus 	struct device *jrdev = ctx->jrdev;
33187ec3a0bSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
3323ef8d945STudor Ambarus 	u32 *desc;
3334cbe79ccSHoria Geantă 	int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
3344cbe79ccSHoria Geantă 			ctx->cdata.keylen;
3353ef8d945STudor Ambarus 
336db57656bSHoria Geantă 	if (!ctx->cdata.keylen || !ctx->authsize)
3373ef8d945STudor Ambarus 		return 0;
3383ef8d945STudor Ambarus 
3393ef8d945STudor Ambarus 	/*
3403ef8d945STudor Ambarus 	 * AES GCM encrypt shared descriptor
3413ef8d945STudor Ambarus 	 * Job Descriptor and Shared Descriptor
3423ef8d945STudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
3433ef8d945STudor Ambarus 	 */
3444cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_GCM_ENC_LEN) {
345db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
3469c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
347db57656bSHoria Geantă 	} else {
348db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
3499c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
350db57656bSHoria Geantă 	}
3513ef8d945STudor Ambarus 
3523ef8d945STudor Ambarus 	desc = ctx->sh_desc_enc;
35387ec3a0bSHoria Geantă 	cnstr_shdsc_gcm_encap(desc, &ctx->cdata, ivsize, ctx->authsize, false);
354bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
3557e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
3563ef8d945STudor Ambarus 
3573ef8d945STudor Ambarus 	/*
3583ef8d945STudor Ambarus 	 * Job Descriptor and Shared Descriptors
3593ef8d945STudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
3603ef8d945STudor Ambarus 	 */
3614cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_GCM_DEC_LEN) {
362db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
3639c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
364db57656bSHoria Geantă 	} else {
365db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
3669c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
367db57656bSHoria Geantă 	}
3683ef8d945STudor Ambarus 
3693ef8d945STudor Ambarus 	desc = ctx->sh_desc_dec;
37087ec3a0bSHoria Geantă 	cnstr_shdsc_gcm_decap(desc, &ctx->cdata, ivsize, ctx->authsize, false);
371bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
3727e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
3733ef8d945STudor Ambarus 
3743ef8d945STudor Ambarus 	return 0;
3753ef8d945STudor Ambarus }
3763ef8d945STudor Ambarus 
3773ef8d945STudor Ambarus static int gcm_setauthsize(struct crypto_aead *authenc, unsigned int authsize)
3783ef8d945STudor Ambarus {
3793ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
3803ef8d945STudor Ambarus 
3813ef8d945STudor Ambarus 	ctx->authsize = authsize;
3823ef8d945STudor Ambarus 	gcm_set_sh_desc(authenc);
3833ef8d945STudor Ambarus 
3843ef8d945STudor Ambarus 	return 0;
3853ef8d945STudor Ambarus }
3863ef8d945STudor Ambarus 
387bac68f2cSTudor Ambarus static int rfc4106_set_sh_desc(struct crypto_aead *aead)
388bac68f2cSTudor Ambarus {
389bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
390bac68f2cSTudor Ambarus 	struct device *jrdev = ctx->jrdev;
39187ec3a0bSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
392bac68f2cSTudor Ambarus 	u32 *desc;
3934cbe79ccSHoria Geantă 	int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
3944cbe79ccSHoria Geantă 			ctx->cdata.keylen;
395bac68f2cSTudor Ambarus 
396db57656bSHoria Geantă 	if (!ctx->cdata.keylen || !ctx->authsize)
397bac68f2cSTudor Ambarus 		return 0;
398bac68f2cSTudor Ambarus 
399bac68f2cSTudor Ambarus 	/*
400bac68f2cSTudor Ambarus 	 * RFC4106 encrypt shared descriptor
401bac68f2cSTudor Ambarus 	 * Job Descriptor and Shared Descriptor
402bac68f2cSTudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
403bac68f2cSTudor Ambarus 	 */
4044cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_RFC4106_ENC_LEN) {
405db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
4069c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
407db57656bSHoria Geantă 	} else {
408db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
4099c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
410db57656bSHoria Geantă 	}
411bac68f2cSTudor Ambarus 
412bac68f2cSTudor Ambarus 	desc = ctx->sh_desc_enc;
41387ec3a0bSHoria Geantă 	cnstr_shdsc_rfc4106_encap(desc, &ctx->cdata, ivsize, ctx->authsize,
41487ec3a0bSHoria Geantă 				  false);
415bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
4167e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
417bac68f2cSTudor Ambarus 
418bac68f2cSTudor Ambarus 	/*
419bac68f2cSTudor Ambarus 	 * Job Descriptor and Shared Descriptors
420bac68f2cSTudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
421bac68f2cSTudor Ambarus 	 */
4224cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_RFC4106_DEC_LEN) {
423db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
4249c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
425db57656bSHoria Geantă 	} else {
426db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
4279c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
428db57656bSHoria Geantă 	}
429bac68f2cSTudor Ambarus 
430bac68f2cSTudor Ambarus 	desc = ctx->sh_desc_dec;
43187ec3a0bSHoria Geantă 	cnstr_shdsc_rfc4106_decap(desc, &ctx->cdata, ivsize, ctx->authsize,
43287ec3a0bSHoria Geantă 				  false);
433bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
4347e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
435bac68f2cSTudor Ambarus 
436bac68f2cSTudor Ambarus 	return 0;
437bac68f2cSTudor Ambarus }
438bac68f2cSTudor Ambarus 
439bac68f2cSTudor Ambarus static int rfc4106_setauthsize(struct crypto_aead *authenc,
440bac68f2cSTudor Ambarus 			       unsigned int authsize)
441bac68f2cSTudor Ambarus {
442bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
443bac68f2cSTudor Ambarus 
444bac68f2cSTudor Ambarus 	ctx->authsize = authsize;
445bac68f2cSTudor Ambarus 	rfc4106_set_sh_desc(authenc);
446bac68f2cSTudor Ambarus 
447bac68f2cSTudor Ambarus 	return 0;
448bac68f2cSTudor Ambarus }
449bac68f2cSTudor Ambarus 
4505d0429a3STudor Ambarus static int rfc4543_set_sh_desc(struct crypto_aead *aead)
4515d0429a3STudor Ambarus {
4525d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
4535d0429a3STudor Ambarus 	struct device *jrdev = ctx->jrdev;
45487ec3a0bSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
4555d0429a3STudor Ambarus 	u32 *desc;
4564cbe79ccSHoria Geantă 	int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
4574cbe79ccSHoria Geantă 			ctx->cdata.keylen;
4585d0429a3STudor Ambarus 
459db57656bSHoria Geantă 	if (!ctx->cdata.keylen || !ctx->authsize)
4605d0429a3STudor Ambarus 		return 0;
4615d0429a3STudor Ambarus 
4625d0429a3STudor Ambarus 	/*
4635d0429a3STudor Ambarus 	 * RFC4543 encrypt shared descriptor
4645d0429a3STudor Ambarus 	 * Job Descriptor and Shared Descriptor
4655d0429a3STudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
4665d0429a3STudor Ambarus 	 */
4674cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_RFC4543_ENC_LEN) {
468db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
4699c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
470db57656bSHoria Geantă 	} else {
471db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
4729c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
473db57656bSHoria Geantă 	}
4745d0429a3STudor Ambarus 
4755d0429a3STudor Ambarus 	desc = ctx->sh_desc_enc;
47687ec3a0bSHoria Geantă 	cnstr_shdsc_rfc4543_encap(desc, &ctx->cdata, ivsize, ctx->authsize,
47787ec3a0bSHoria Geantă 				  false);
478bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
4797e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
4805d0429a3STudor Ambarus 
4815d0429a3STudor Ambarus 	/*
4825d0429a3STudor Ambarus 	 * Job Descriptor and Shared Descriptors
4835d0429a3STudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
4845d0429a3STudor Ambarus 	 */
4854cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_RFC4543_DEC_LEN) {
486db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
4879c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
488db57656bSHoria Geantă 	} else {
489db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
4909c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
491db57656bSHoria Geantă 	}
4925d0429a3STudor Ambarus 
4935d0429a3STudor Ambarus 	desc = ctx->sh_desc_dec;
49487ec3a0bSHoria Geantă 	cnstr_shdsc_rfc4543_decap(desc, &ctx->cdata, ivsize, ctx->authsize,
49587ec3a0bSHoria Geantă 				  false);
496bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
4977e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
4985d0429a3STudor Ambarus 
4995d0429a3STudor Ambarus 	return 0;
5005d0429a3STudor Ambarus }
5015d0429a3STudor Ambarus 
5025d0429a3STudor Ambarus static int rfc4543_setauthsize(struct crypto_aead *authenc,
5035d0429a3STudor Ambarus 			       unsigned int authsize)
5045d0429a3STudor Ambarus {
5055d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
5065d0429a3STudor Ambarus 
5075d0429a3STudor Ambarus 	ctx->authsize = authsize;
5085d0429a3STudor Ambarus 	rfc4543_set_sh_desc(authenc);
5095d0429a3STudor Ambarus 
5105d0429a3STudor Ambarus 	return 0;
5115d0429a3STudor Ambarus }
5125d0429a3STudor Ambarus 
5130e479300SYuan Kang static int aead_setkey(struct crypto_aead *aead,
5148e8ec596SKim Phillips 			       const u8 *key, unsigned int keylen)
5158e8ec596SKim Phillips {
5168e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
5178e8ec596SKim Phillips 	struct device *jrdev = ctx->jrdev;
5187e0880b9SHoria Geantă 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
5194e6e0b27SHoria Geanta 	struct crypto_authenc_keys keys;
5208e8ec596SKim Phillips 	int ret = 0;
5218e8ec596SKim Phillips 
5224e6e0b27SHoria Geanta 	if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
5238e8ec596SKim Phillips 		goto badkey;
5248e8ec596SKim Phillips 
5258e8ec596SKim Phillips #ifdef DEBUG
5268e8ec596SKim Phillips 	printk(KERN_ERR "keylen %d enckeylen %d authkeylen %d\n",
5274e6e0b27SHoria Geanta 	       keys.authkeylen + keys.enckeylen, keys.enckeylen,
5284e6e0b27SHoria Geanta 	       keys.authkeylen);
529514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
5308e8ec596SKim Phillips 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
5318e8ec596SKim Phillips #endif
5328e8ec596SKim Phillips 
5337e0880b9SHoria Geantă 	/*
5347e0880b9SHoria Geantă 	 * If DKP is supported, use it in the shared descriptor to generate
5357e0880b9SHoria Geantă 	 * the split key.
5367e0880b9SHoria Geantă 	 */
5377e0880b9SHoria Geantă 	if (ctrlpriv->era >= 6) {
5387e0880b9SHoria Geantă 		ctx->adata.keylen = keys.authkeylen;
5397e0880b9SHoria Geantă 		ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype &
5407e0880b9SHoria Geantă 						      OP_ALG_ALGSEL_MASK);
5417e0880b9SHoria Geantă 
5427e0880b9SHoria Geantă 		if (ctx->adata.keylen_pad + keys.enckeylen > CAAM_MAX_KEY_SIZE)
5437e0880b9SHoria Geantă 			goto badkey;
5447e0880b9SHoria Geantă 
5457e0880b9SHoria Geantă 		memcpy(ctx->key, keys.authkey, keys.authkeylen);
5467e0880b9SHoria Geantă 		memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey,
5477e0880b9SHoria Geantă 		       keys.enckeylen);
5487e0880b9SHoria Geantă 		dma_sync_single_for_device(jrdev, ctx->key_dma,
5497e0880b9SHoria Geantă 					   ctx->adata.keylen_pad +
5507e0880b9SHoria Geantă 					   keys.enckeylen, ctx->dir);
5517e0880b9SHoria Geantă 		goto skip_split_key;
5527e0880b9SHoria Geantă 	}
5537e0880b9SHoria Geantă 
5546655cb8eSHoria Geantă 	ret = gen_split_key(ctx->jrdev, ctx->key, &ctx->adata, keys.authkey,
5556655cb8eSHoria Geantă 			    keys.authkeylen, CAAM_MAX_KEY_SIZE -
5566655cb8eSHoria Geantă 			    keys.enckeylen);
5578e8ec596SKim Phillips 	if (ret) {
5588e8ec596SKim Phillips 		goto badkey;
5598e8ec596SKim Phillips 	}
5608e8ec596SKim Phillips 
5618e8ec596SKim Phillips 	/* postpend encryption key to auth split key */
562db57656bSHoria Geantă 	memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen);
563bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->adata.keylen_pad +
5647e0880b9SHoria Geantă 				   keys.enckeylen, ctx->dir);
5658e8ec596SKim Phillips #ifdef DEBUG
566514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ctx.key@"__stringify(__LINE__)": ",
5678e8ec596SKim Phillips 		       DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
568db57656bSHoria Geantă 		       ctx->adata.keylen_pad + keys.enckeylen, 1);
5698e8ec596SKim Phillips #endif
5707e0880b9SHoria Geantă 
5717e0880b9SHoria Geantă skip_split_key:
572db57656bSHoria Geantă 	ctx->cdata.keylen = keys.enckeylen;
57361dab972STudor-Dan Ambarus 	memzero_explicit(&keys, sizeof(keys));
574bbf22344SHoria Geantă 	return aead_set_sh_desc(aead);
5758e8ec596SKim Phillips badkey:
5768e8ec596SKim Phillips 	crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
57761dab972STudor-Dan Ambarus 	memzero_explicit(&keys, sizeof(keys));
5788e8ec596SKim Phillips 	return -EINVAL;
5798e8ec596SKim Phillips }
5808e8ec596SKim Phillips 
5813ef8d945STudor Ambarus static int gcm_setkey(struct crypto_aead *aead,
5823ef8d945STudor Ambarus 		      const u8 *key, unsigned int keylen)
5833ef8d945STudor Ambarus {
5843ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
5853ef8d945STudor Ambarus 	struct device *jrdev = ctx->jrdev;
5863ef8d945STudor Ambarus 
5873ef8d945STudor Ambarus #ifdef DEBUG
5883ef8d945STudor Ambarus 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
5893ef8d945STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
5903ef8d945STudor Ambarus #endif
5913ef8d945STudor Ambarus 
5923ef8d945STudor Ambarus 	memcpy(ctx->key, key, keylen);
5937e0880b9SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, ctx->dir);
594db57656bSHoria Geantă 	ctx->cdata.keylen = keylen;
5953ef8d945STudor Ambarus 
596bbf22344SHoria Geantă 	return gcm_set_sh_desc(aead);
5973ef8d945STudor Ambarus }
5983ef8d945STudor Ambarus 
599bac68f2cSTudor Ambarus static int rfc4106_setkey(struct crypto_aead *aead,
600bac68f2cSTudor Ambarus 			  const u8 *key, unsigned int keylen)
601bac68f2cSTudor Ambarus {
602bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
603bac68f2cSTudor Ambarus 	struct device *jrdev = ctx->jrdev;
604bac68f2cSTudor Ambarus 
605bac68f2cSTudor Ambarus 	if (keylen < 4)
606bac68f2cSTudor Ambarus 		return -EINVAL;
607bac68f2cSTudor Ambarus 
608bac68f2cSTudor Ambarus #ifdef DEBUG
609bac68f2cSTudor Ambarus 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
610bac68f2cSTudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
611bac68f2cSTudor Ambarus #endif
612bac68f2cSTudor Ambarus 
613bac68f2cSTudor Ambarus 	memcpy(ctx->key, key, keylen);
614bac68f2cSTudor Ambarus 
615bac68f2cSTudor Ambarus 	/*
616bac68f2cSTudor Ambarus 	 * The last four bytes of the key material are used as the salt value
617bac68f2cSTudor Ambarus 	 * in the nonce. Update the AES key length.
618bac68f2cSTudor Ambarus 	 */
619db57656bSHoria Geantă 	ctx->cdata.keylen = keylen - 4;
620bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
6217e0880b9SHoria Geantă 				   ctx->dir);
622bbf22344SHoria Geantă 	return rfc4106_set_sh_desc(aead);
623bac68f2cSTudor Ambarus }
624bac68f2cSTudor Ambarus 
6255d0429a3STudor Ambarus static int rfc4543_setkey(struct crypto_aead *aead,
6265d0429a3STudor Ambarus 			  const u8 *key, unsigned int keylen)
6275d0429a3STudor Ambarus {
6285d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
6295d0429a3STudor Ambarus 	struct device *jrdev = ctx->jrdev;
6305d0429a3STudor Ambarus 
6315d0429a3STudor Ambarus 	if (keylen < 4)
6325d0429a3STudor Ambarus 		return -EINVAL;
6335d0429a3STudor Ambarus 
6345d0429a3STudor Ambarus #ifdef DEBUG
6355d0429a3STudor Ambarus 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
6365d0429a3STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
6375d0429a3STudor Ambarus #endif
6385d0429a3STudor Ambarus 
6395d0429a3STudor Ambarus 	memcpy(ctx->key, key, keylen);
6405d0429a3STudor Ambarus 
6415d0429a3STudor Ambarus 	/*
6425d0429a3STudor Ambarus 	 * The last four bytes of the key material are used as the salt value
6435d0429a3STudor Ambarus 	 * in the nonce. Update the AES key length.
6445d0429a3STudor Ambarus 	 */
645db57656bSHoria Geantă 	ctx->cdata.keylen = keylen - 4;
646bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
6477e0880b9SHoria Geantă 				   ctx->dir);
648bbf22344SHoria Geantă 	return rfc4543_set_sh_desc(aead);
6495d0429a3STudor Ambarus }
6505d0429a3STudor Ambarus 
651acdca31dSYuan Kang static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
652acdca31dSYuan Kang 			     const u8 *key, unsigned int keylen)
653acdca31dSYuan Kang {
654acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
655a5f57cffSCatalin Vasile 	struct crypto_tfm *tfm = crypto_ablkcipher_tfm(ablkcipher);
656a5f57cffSCatalin Vasile 	const char *alg_name = crypto_tfm_alg_name(tfm);
657acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
6588cea7b66SHoria Geantă 	unsigned int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
659acdca31dSYuan Kang 	u32 *desc;
6602b22f6c5SCatalin Vasile 	u32 ctx1_iv_off = 0;
661db57656bSHoria Geantă 	const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
6622b22f6c5SCatalin Vasile 			       OP_ALG_AAI_CTR_MOD128);
663a5f57cffSCatalin Vasile 	const bool is_rfc3686 = (ctr_mode &&
664a5f57cffSCatalin Vasile 				 (strstr(alg_name, "rfc3686") != NULL));
665acdca31dSYuan Kang 
666acdca31dSYuan Kang #ifdef DEBUG
667514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
668acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
669acdca31dSYuan Kang #endif
6702b22f6c5SCatalin Vasile 	/*
6712b22f6c5SCatalin Vasile 	 * AES-CTR needs to load IV in CONTEXT1 reg
6722b22f6c5SCatalin Vasile 	 * at an offset of 128bits (16bytes)
6732b22f6c5SCatalin Vasile 	 * CONTEXT1[255:128] = IV
6742b22f6c5SCatalin Vasile 	 */
6752b22f6c5SCatalin Vasile 	if (ctr_mode)
6762b22f6c5SCatalin Vasile 		ctx1_iv_off = 16;
677acdca31dSYuan Kang 
678a5f57cffSCatalin Vasile 	/*
679a5f57cffSCatalin Vasile 	 * RFC3686 specific:
680a5f57cffSCatalin Vasile 	 *	| CONTEXT1[255:128] = {NONCE, IV, COUNTER}
681a5f57cffSCatalin Vasile 	 *	| *key = {KEY, NONCE}
682a5f57cffSCatalin Vasile 	 */
683a5f57cffSCatalin Vasile 	if (is_rfc3686) {
684a5f57cffSCatalin Vasile 		ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
685a5f57cffSCatalin Vasile 		keylen -= CTR_RFC3686_NONCE_SIZE;
686a5f57cffSCatalin Vasile 	}
687a5f57cffSCatalin Vasile 
688db57656bSHoria Geantă 	ctx->cdata.keylen = keylen;
689662f70edSHoria Geantă 	ctx->cdata.key_virt = key;
690db57656bSHoria Geantă 	ctx->cdata.key_inline = true;
691acdca31dSYuan Kang 
692acdca31dSYuan Kang 	/* ablkcipher_encrypt shared descriptor */
693acdca31dSYuan Kang 	desc = ctx->sh_desc_enc;
6948cea7b66SHoria Geantă 	cnstr_shdsc_ablkcipher_encap(desc, &ctx->cdata, ivsize, is_rfc3686,
6958cea7b66SHoria Geantă 				     ctx1_iv_off);
696bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
6977e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
6988cea7b66SHoria Geantă 
699acdca31dSYuan Kang 	/* ablkcipher_decrypt shared descriptor */
700acdca31dSYuan Kang 	desc = ctx->sh_desc_dec;
7018cea7b66SHoria Geantă 	cnstr_shdsc_ablkcipher_decap(desc, &ctx->cdata, ivsize, is_rfc3686,
7028cea7b66SHoria Geantă 				     ctx1_iv_off);
703bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
7047e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
705acdca31dSYuan Kang 
7067222d1a3SCatalin Vasile 	/* ablkcipher_givencrypt shared descriptor */
7077222d1a3SCatalin Vasile 	desc = ctx->sh_desc_givenc;
7088cea7b66SHoria Geantă 	cnstr_shdsc_ablkcipher_givencap(desc, &ctx->cdata, ivsize, is_rfc3686,
7098cea7b66SHoria Geantă 					ctx1_iv_off);
710bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_givenc_dma,
7117e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
712acdca31dSYuan Kang 
7138cea7b66SHoria Geantă 	return 0;
714acdca31dSYuan Kang }
715acdca31dSYuan Kang 
716c6415a60SCatalin Vasile static int xts_ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
717c6415a60SCatalin Vasile 				 const u8 *key, unsigned int keylen)
718c6415a60SCatalin Vasile {
719c6415a60SCatalin Vasile 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
720c6415a60SCatalin Vasile 	struct device *jrdev = ctx->jrdev;
7218cea7b66SHoria Geantă 	u32 *desc;
722c6415a60SCatalin Vasile 
723c6415a60SCatalin Vasile 	if (keylen != 2 * AES_MIN_KEY_SIZE  && keylen != 2 * AES_MAX_KEY_SIZE) {
724c6415a60SCatalin Vasile 		crypto_ablkcipher_set_flags(ablkcipher,
725c6415a60SCatalin Vasile 					    CRYPTO_TFM_RES_BAD_KEY_LEN);
726c6415a60SCatalin Vasile 		dev_err(jrdev, "key size mismatch\n");
727c6415a60SCatalin Vasile 		return -EINVAL;
728c6415a60SCatalin Vasile 	}
729c6415a60SCatalin Vasile 
730db57656bSHoria Geantă 	ctx->cdata.keylen = keylen;
731662f70edSHoria Geantă 	ctx->cdata.key_virt = key;
732db57656bSHoria Geantă 	ctx->cdata.key_inline = true;
733c6415a60SCatalin Vasile 
734c6415a60SCatalin Vasile 	/* xts_ablkcipher_encrypt shared descriptor */
735c6415a60SCatalin Vasile 	desc = ctx->sh_desc_enc;
7368cea7b66SHoria Geantă 	cnstr_shdsc_xts_ablkcipher_encap(desc, &ctx->cdata);
737bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
7387e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
739c6415a60SCatalin Vasile 
740c6415a60SCatalin Vasile 	/* xts_ablkcipher_decrypt shared descriptor */
741c6415a60SCatalin Vasile 	desc = ctx->sh_desc_dec;
7428cea7b66SHoria Geantă 	cnstr_shdsc_xts_ablkcipher_decap(desc, &ctx->cdata);
743bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
7447e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
745c6415a60SCatalin Vasile 
746c6415a60SCatalin Vasile 	return 0;
747c6415a60SCatalin Vasile }
748c6415a60SCatalin Vasile 
7498e8ec596SKim Phillips /*
7501acebad3SYuan Kang  * aead_edesc - s/w-extended aead descriptor
751fa0c92dbSHoria Geantă  * @src_nents: number of segments in input s/w scatterlist
752fa0c92dbSHoria Geantă  * @dst_nents: number of segments in output s/w scatterlist
753a299c837SYuan Kang  * @sec4_sg_bytes: length of dma mapped sec4_sg space
754a299c837SYuan Kang  * @sec4_sg_dma: bus physical mapped address of h/w link table
7554ca7c7d8SHoria Geantă  * @sec4_sg: pointer to h/w link table
7568e8ec596SKim Phillips  * @hw_desc: the h/w job descriptor followed by any referenced link tables
7578e8ec596SKim Phillips  */
7580e479300SYuan Kang struct aead_edesc {
7598e8ec596SKim Phillips 	int src_nents;
7608e8ec596SKim Phillips 	int dst_nents;
761a299c837SYuan Kang 	int sec4_sg_bytes;
762a299c837SYuan Kang 	dma_addr_t sec4_sg_dma;
763a299c837SYuan Kang 	struct sec4_sg_entry *sec4_sg;
764f2147b88SHerbert Xu 	u32 hw_desc[];
7658e8ec596SKim Phillips };
7668e8ec596SKim Phillips 
767acdca31dSYuan Kang /*
768acdca31dSYuan Kang  * ablkcipher_edesc - s/w-extended ablkcipher descriptor
769fa0c92dbSHoria Geantă  * @src_nents: number of segments in input s/w scatterlist
770fa0c92dbSHoria Geantă  * @dst_nents: number of segments in output s/w scatterlist
771acdca31dSYuan Kang  * @iv_dma: dma address of iv for checking continuity and link table
772a38acd23SHoria Geantă  * @iv_dir: DMA mapping direction for IV
773a299c837SYuan Kang  * @sec4_sg_bytes: length of dma mapped sec4_sg space
774a299c837SYuan Kang  * @sec4_sg_dma: bus physical mapped address of h/w link table
7754ca7c7d8SHoria Geantă  * @sec4_sg: pointer to h/w link table
776acdca31dSYuan Kang  * @hw_desc: the h/w job descriptor followed by any referenced link tables
777115957bbSHoria Geantă  *	     and IV
778acdca31dSYuan Kang  */
779acdca31dSYuan Kang struct ablkcipher_edesc {
780acdca31dSYuan Kang 	int src_nents;
781acdca31dSYuan Kang 	int dst_nents;
782acdca31dSYuan Kang 	dma_addr_t iv_dma;
783a38acd23SHoria Geantă 	enum dma_data_direction iv_dir;
784a299c837SYuan Kang 	int sec4_sg_bytes;
785a299c837SYuan Kang 	dma_addr_t sec4_sg_dma;
786a299c837SYuan Kang 	struct sec4_sg_entry *sec4_sg;
787acdca31dSYuan Kang 	u32 hw_desc[0];
788acdca31dSYuan Kang };
789acdca31dSYuan Kang 
7901acebad3SYuan Kang static void caam_unmap(struct device *dev, struct scatterlist *src,
791643b39b0SYuan Kang 		       struct scatterlist *dst, int src_nents,
79213fb8fd7SLABBE Corentin 		       int dst_nents,
793a38acd23SHoria Geantă 		       dma_addr_t iv_dma, int ivsize,
794a38acd23SHoria Geantă 		       enum dma_data_direction iv_dir, dma_addr_t sec4_sg_dma,
795a299c837SYuan Kang 		       int sec4_sg_bytes)
7961acebad3SYuan Kang {
797643b39b0SYuan Kang 	if (dst != src) {
798fa0c92dbSHoria Geantă 		if (src_nents)
799fa0c92dbSHoria Geantă 			dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
800fa0c92dbSHoria Geantă 		dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
8011acebad3SYuan Kang 	} else {
802fa0c92dbSHoria Geantă 		dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
8031acebad3SYuan Kang 	}
8041acebad3SYuan Kang 
8051acebad3SYuan Kang 	if (iv_dma)
806a38acd23SHoria Geantă 		dma_unmap_single(dev, iv_dma, ivsize, iv_dir);
807a299c837SYuan Kang 	if (sec4_sg_bytes)
808a299c837SYuan Kang 		dma_unmap_single(dev, sec4_sg_dma, sec4_sg_bytes,
8091acebad3SYuan Kang 				 DMA_TO_DEVICE);
8101acebad3SYuan Kang }
8111acebad3SYuan Kang 
8120e479300SYuan Kang static void aead_unmap(struct device *dev,
8130e479300SYuan Kang 		       struct aead_edesc *edesc,
8140e479300SYuan Kang 		       struct aead_request *req)
8158e8ec596SKim Phillips {
816f2147b88SHerbert Xu 	caam_unmap(dev, req->src, req->dst,
817a38acd23SHoria Geantă 		   edesc->src_nents, edesc->dst_nents, 0, 0, DMA_NONE,
818f2147b88SHerbert Xu 		   edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
819f2147b88SHerbert Xu }
820f2147b88SHerbert Xu 
821acdca31dSYuan Kang static void ablkcipher_unmap(struct device *dev,
822acdca31dSYuan Kang 			     struct ablkcipher_edesc *edesc,
823acdca31dSYuan Kang 			     struct ablkcipher_request *req)
824acdca31dSYuan Kang {
825acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
826acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
827acdca31dSYuan Kang 
828acdca31dSYuan Kang 	caam_unmap(dev, req->src, req->dst,
82913fb8fd7SLABBE Corentin 		   edesc->src_nents, edesc->dst_nents,
830a38acd23SHoria Geantă 		   edesc->iv_dma, ivsize, edesc->iv_dir,
831643b39b0SYuan Kang 		   edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
832acdca31dSYuan Kang }
833acdca31dSYuan Kang 
8340e479300SYuan Kang static void aead_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
8358e8ec596SKim Phillips 				   void *context)
8368e8ec596SKim Phillips {
8370e479300SYuan Kang 	struct aead_request *req = context;
8380e479300SYuan Kang 	struct aead_edesc *edesc;
839f2147b88SHerbert Xu 
840f2147b88SHerbert Xu #ifdef DEBUG
841f2147b88SHerbert Xu 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
842f2147b88SHerbert Xu #endif
843f2147b88SHerbert Xu 
844f2147b88SHerbert Xu 	edesc = container_of(desc, struct aead_edesc, hw_desc[0]);
845f2147b88SHerbert Xu 
846f2147b88SHerbert Xu 	if (err)
847f2147b88SHerbert Xu 		caam_jr_strstatus(jrdev, err);
848f2147b88SHerbert Xu 
849f2147b88SHerbert Xu 	aead_unmap(jrdev, edesc, req);
850f2147b88SHerbert Xu 
851f2147b88SHerbert Xu 	kfree(edesc);
852f2147b88SHerbert Xu 
853f2147b88SHerbert Xu 	aead_request_complete(req, err);
854f2147b88SHerbert Xu }
855f2147b88SHerbert Xu 
8560e479300SYuan Kang static void aead_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
8578e8ec596SKim Phillips 				   void *context)
8588e8ec596SKim Phillips {
8590e479300SYuan Kang 	struct aead_request *req = context;
8600e479300SYuan Kang 	struct aead_edesc *edesc;
861f2147b88SHerbert Xu 
862f2147b88SHerbert Xu #ifdef DEBUG
863f2147b88SHerbert Xu 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
864f2147b88SHerbert Xu #endif
865f2147b88SHerbert Xu 
866f2147b88SHerbert Xu 	edesc = container_of(desc, struct aead_edesc, hw_desc[0]);
867f2147b88SHerbert Xu 
868f2147b88SHerbert Xu 	if (err)
869f2147b88SHerbert Xu 		caam_jr_strstatus(jrdev, err);
870f2147b88SHerbert Xu 
871f2147b88SHerbert Xu 	aead_unmap(jrdev, edesc, req);
872f2147b88SHerbert Xu 
873f2147b88SHerbert Xu 	/*
874f2147b88SHerbert Xu 	 * verify hw auth check passed else return -EBADMSG
875f2147b88SHerbert Xu 	 */
876f2147b88SHerbert Xu 	if ((err & JRSTA_CCBERR_ERRID_MASK) == JRSTA_CCBERR_ERRID_ICVCHK)
877f2147b88SHerbert Xu 		err = -EBADMSG;
878f2147b88SHerbert Xu 
879f2147b88SHerbert Xu 	kfree(edesc);
880f2147b88SHerbert Xu 
881f2147b88SHerbert Xu 	aead_request_complete(req, err);
882f2147b88SHerbert Xu }
883f2147b88SHerbert Xu 
884acdca31dSYuan Kang static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
885acdca31dSYuan Kang 				   void *context)
886acdca31dSYuan Kang {
887acdca31dSYuan Kang 	struct ablkcipher_request *req = context;
888acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
889acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
890acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
891acdca31dSYuan Kang 
892854b06f7SDavid Gstir #ifdef DEBUG
893acdca31dSYuan Kang 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
894acdca31dSYuan Kang #endif
895acdca31dSYuan Kang 
8964ca7c7d8SHoria Geantă 	edesc = container_of(desc, struct ablkcipher_edesc, hw_desc[0]);
897acdca31dSYuan Kang 
898fa9659cdSMarek Vasut 	if (err)
899fa9659cdSMarek Vasut 		caam_jr_strstatus(jrdev, err);
900acdca31dSYuan Kang 
901acdca31dSYuan Kang #ifdef DEBUG
902514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dstiv  @"__stringify(__LINE__)": ",
903acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
904acdca31dSYuan Kang 		       edesc->src_nents > 1 ? 100 : ivsize, 1);
905972b812bSHoria Geantă #endif
906972b812bSHoria Geantă 	caam_dump_sg(KERN_ERR, "dst    @" __stringify(__LINE__)": ",
9075ecf8ef9SCatalin Vasile 		     DUMP_PREFIX_ADDRESS, 16, 4, req->dst,
90800fef2b2SHoria Geantă 		     edesc->dst_nents > 1 ? 100 : req->nbytes, 1);
909acdca31dSYuan Kang 
910acdca31dSYuan Kang 	ablkcipher_unmap(jrdev, edesc, req);
911854b06f7SDavid Gstir 
912854b06f7SDavid Gstir 	/*
913854b06f7SDavid Gstir 	 * The crypto API expects us to set the IV (req->info) to the last
914854b06f7SDavid Gstir 	 * ciphertext block. This is used e.g. by the CTS mode.
915854b06f7SDavid Gstir 	 */
916854b06f7SDavid Gstir 	scatterwalk_map_and_copy(req->info, req->dst, req->nbytes - ivsize,
917854b06f7SDavid Gstir 				 ivsize, 0);
918854b06f7SDavid Gstir 
919115957bbSHoria Geantă 	/* In case initial IV was generated, copy it in GIVCIPHER request */
920115957bbSHoria Geantă 	if (edesc->iv_dir == DMA_FROM_DEVICE) {
921115957bbSHoria Geantă 		u8 *iv;
922115957bbSHoria Geantă 		struct skcipher_givcrypt_request *greq;
923115957bbSHoria Geantă 
924115957bbSHoria Geantă 		greq = container_of(req, struct skcipher_givcrypt_request,
925115957bbSHoria Geantă 				    creq);
926115957bbSHoria Geantă 		iv = (u8 *)edesc->hw_desc + desc_bytes(edesc->hw_desc) +
927115957bbSHoria Geantă 		     edesc->sec4_sg_bytes;
928115957bbSHoria Geantă 		memcpy(greq->giv, iv, ivsize);
929115957bbSHoria Geantă 	}
930115957bbSHoria Geantă 
931acdca31dSYuan Kang 	kfree(edesc);
932acdca31dSYuan Kang 
933acdca31dSYuan Kang 	ablkcipher_request_complete(req, err);
934acdca31dSYuan Kang }
935acdca31dSYuan Kang 
936acdca31dSYuan Kang static void ablkcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
937acdca31dSYuan Kang 				    void *context)
938acdca31dSYuan Kang {
939acdca31dSYuan Kang 	struct ablkcipher_request *req = context;
940acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
941115957bbSHoria Geantă #ifdef DEBUG
942acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
943acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
944acdca31dSYuan Kang 
945acdca31dSYuan Kang 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
946acdca31dSYuan Kang #endif
947acdca31dSYuan Kang 
9484ca7c7d8SHoria Geantă 	edesc = container_of(desc, struct ablkcipher_edesc, hw_desc[0]);
949fa9659cdSMarek Vasut 	if (err)
950fa9659cdSMarek Vasut 		caam_jr_strstatus(jrdev, err);
951acdca31dSYuan Kang 
952acdca31dSYuan Kang #ifdef DEBUG
953514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dstiv  @"__stringify(__LINE__)": ",
954acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
955acdca31dSYuan Kang 		       ivsize, 1);
956972b812bSHoria Geantă #endif
957972b812bSHoria Geantă 	caam_dump_sg(KERN_ERR, "dst    @" __stringify(__LINE__)": ",
9585ecf8ef9SCatalin Vasile 		     DUMP_PREFIX_ADDRESS, 16, 4, req->dst,
95900fef2b2SHoria Geantă 		     edesc->dst_nents > 1 ? 100 : req->nbytes, 1);
960acdca31dSYuan Kang 
961acdca31dSYuan Kang 	ablkcipher_unmap(jrdev, edesc, req);
962acdca31dSYuan Kang 	kfree(edesc);
963acdca31dSYuan Kang 
964acdca31dSYuan Kang 	ablkcipher_request_complete(req, err);
965acdca31dSYuan Kang }
966acdca31dSYuan Kang 
9678e8ec596SKim Phillips /*
9681acebad3SYuan Kang  * Fill in aead job descriptor
9698e8ec596SKim Phillips  */
970f2147b88SHerbert Xu static void init_aead_job(struct aead_request *req,
971f2147b88SHerbert Xu 			  struct aead_edesc *edesc,
972f2147b88SHerbert Xu 			  bool all_contig, bool encrypt)
973f2147b88SHerbert Xu {
974f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
975f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
976f2147b88SHerbert Xu 	int authsize = ctx->authsize;
977f2147b88SHerbert Xu 	u32 *desc = edesc->hw_desc;
978f2147b88SHerbert Xu 	u32 out_options, in_options;
979f2147b88SHerbert Xu 	dma_addr_t dst_dma, src_dma;
980f2147b88SHerbert Xu 	int len, sec4_sg_index = 0;
981f2147b88SHerbert Xu 	dma_addr_t ptr;
982f2147b88SHerbert Xu 	u32 *sh_desc;
983f2147b88SHerbert Xu 
984f2147b88SHerbert Xu 	sh_desc = encrypt ? ctx->sh_desc_enc : ctx->sh_desc_dec;
985f2147b88SHerbert Xu 	ptr = encrypt ? ctx->sh_desc_enc_dma : ctx->sh_desc_dec_dma;
986f2147b88SHerbert Xu 
987f2147b88SHerbert Xu 	len = desc_len(sh_desc);
988f2147b88SHerbert Xu 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
989f2147b88SHerbert Xu 
990f2147b88SHerbert Xu 	if (all_contig) {
991fa0c92dbSHoria Geantă 		src_dma = edesc->src_nents ? sg_dma_address(req->src) : 0;
992f2147b88SHerbert Xu 		in_options = 0;
993f2147b88SHerbert Xu 	} else {
994f2147b88SHerbert Xu 		src_dma = edesc->sec4_sg_dma;
995f2147b88SHerbert Xu 		sec4_sg_index += edesc->src_nents;
996f2147b88SHerbert Xu 		in_options = LDST_SGF;
997f2147b88SHerbert Xu 	}
998f2147b88SHerbert Xu 
999f2147b88SHerbert Xu 	append_seq_in_ptr(desc, src_dma, req->assoclen + req->cryptlen,
1000f2147b88SHerbert Xu 			  in_options);
1001f2147b88SHerbert Xu 
1002f2147b88SHerbert Xu 	dst_dma = src_dma;
1003f2147b88SHerbert Xu 	out_options = in_options;
1004f2147b88SHerbert Xu 
1005f2147b88SHerbert Xu 	if (unlikely(req->src != req->dst)) {
1006fa0c92dbSHoria Geantă 		if (edesc->dst_nents == 1) {
1007f2147b88SHerbert Xu 			dst_dma = sg_dma_address(req->dst);
1008f2147b88SHerbert Xu 		} else {
1009f2147b88SHerbert Xu 			dst_dma = edesc->sec4_sg_dma +
1010f2147b88SHerbert Xu 				  sec4_sg_index *
1011f2147b88SHerbert Xu 				  sizeof(struct sec4_sg_entry);
1012f2147b88SHerbert Xu 			out_options = LDST_SGF;
1013f2147b88SHerbert Xu 		}
1014f2147b88SHerbert Xu 	}
1015f2147b88SHerbert Xu 
1016f2147b88SHerbert Xu 	if (encrypt)
1017f2147b88SHerbert Xu 		append_seq_out_ptr(desc, dst_dma,
1018f2147b88SHerbert Xu 				   req->assoclen + req->cryptlen + authsize,
1019f2147b88SHerbert Xu 				   out_options);
1020f2147b88SHerbert Xu 	else
1021f2147b88SHerbert Xu 		append_seq_out_ptr(desc, dst_dma,
1022f2147b88SHerbert Xu 				   req->assoclen + req->cryptlen - authsize,
1023f2147b88SHerbert Xu 				   out_options);
1024f2147b88SHerbert Xu }
1025f2147b88SHerbert Xu 
1026f2147b88SHerbert Xu static void init_gcm_job(struct aead_request *req,
1027f2147b88SHerbert Xu 			 struct aead_edesc *edesc,
1028f2147b88SHerbert Xu 			 bool all_contig, bool encrypt)
1029f2147b88SHerbert Xu {
1030f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1031f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1032f2147b88SHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
1033f2147b88SHerbert Xu 	u32 *desc = edesc->hw_desc;
10347545e166SCorentin LABBE 	bool generic_gcm = (ivsize == GCM_AES_IV_SIZE);
1035f2147b88SHerbert Xu 	unsigned int last;
1036f2147b88SHerbert Xu 
1037f2147b88SHerbert Xu 	init_aead_job(req, edesc, all_contig, encrypt);
10387e0880b9SHoria Geantă 	append_math_add_imm_u32(desc, REG3, ZERO, IMM, req->assoclen);
1039f2147b88SHerbert Xu 
1040f2147b88SHerbert Xu 	/* BUG This should not be specific to generic GCM. */
1041f2147b88SHerbert Xu 	last = 0;
1042f2147b88SHerbert Xu 	if (encrypt && generic_gcm && !(req->assoclen + req->cryptlen))
1043f2147b88SHerbert Xu 		last = FIFOLD_TYPE_LAST1;
1044f2147b88SHerbert Xu 
1045f2147b88SHerbert Xu 	/* Read GCM IV */
1046f2147b88SHerbert Xu 	append_cmd(desc, CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 | IMMEDIATE |
10477545e166SCorentin LABBE 			 FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 | GCM_AES_IV_SIZE | last);
1048f2147b88SHerbert Xu 	/* Append Salt */
1049f2147b88SHerbert Xu 	if (!generic_gcm)
1050db57656bSHoria Geantă 		append_data(desc, ctx->key + ctx->cdata.keylen, 4);
1051f2147b88SHerbert Xu 	/* Append IV */
1052f2147b88SHerbert Xu 	append_data(desc, req->iv, ivsize);
1053f2147b88SHerbert Xu 	/* End of blank commands */
1054f2147b88SHerbert Xu }
1055f2147b88SHerbert Xu 
1056479bcc7cSHerbert Xu static void init_authenc_job(struct aead_request *req,
10571acebad3SYuan Kang 			     struct aead_edesc *edesc,
1058479bcc7cSHerbert Xu 			     bool all_contig, bool encrypt)
10591acebad3SYuan Kang {
10601acebad3SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1061479bcc7cSHerbert Xu 	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
1062479bcc7cSHerbert Xu 						 struct caam_aead_alg, aead);
1063479bcc7cSHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
10641acebad3SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
10657e0880b9SHoria Geantă 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctx->jrdev->parent);
1066db57656bSHoria Geantă 	const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
1067479bcc7cSHerbert Xu 			       OP_ALG_AAI_CTR_MOD128);
1068479bcc7cSHerbert Xu 	const bool is_rfc3686 = alg->caam.rfc3686;
10691acebad3SYuan Kang 	u32 *desc = edesc->hw_desc;
1070479bcc7cSHerbert Xu 	u32 ivoffset = 0;
10718e8ec596SKim Phillips 
1072479bcc7cSHerbert Xu 	/*
1073479bcc7cSHerbert Xu 	 * AES-CTR needs to load IV in CONTEXT1 reg
1074479bcc7cSHerbert Xu 	 * at an offset of 128bits (16bytes)
1075479bcc7cSHerbert Xu 	 * CONTEXT1[255:128] = IV
1076479bcc7cSHerbert Xu 	 */
1077479bcc7cSHerbert Xu 	if (ctr_mode)
1078479bcc7cSHerbert Xu 		ivoffset = 16;
10798e8ec596SKim Phillips 
1080479bcc7cSHerbert Xu 	/*
1081479bcc7cSHerbert Xu 	 * RFC3686 specific:
1082479bcc7cSHerbert Xu 	 *	CONTEXT1[255:128] = {NONCE, IV, COUNTER}
1083479bcc7cSHerbert Xu 	 */
1084479bcc7cSHerbert Xu 	if (is_rfc3686)
1085479bcc7cSHerbert Xu 		ivoffset = 16 + CTR_RFC3686_NONCE_SIZE;
1086bac68f2cSTudor Ambarus 
1087479bcc7cSHerbert Xu 	init_aead_job(req, edesc, all_contig, encrypt);
10881acebad3SYuan Kang 
10897e0880b9SHoria Geantă 	/*
10907e0880b9SHoria Geantă 	 * {REG3, DPOVRD} = assoclen, depending on whether MATH command supports
10917e0880b9SHoria Geantă 	 * having DPOVRD as destination.
10927e0880b9SHoria Geantă 	 */
10937e0880b9SHoria Geantă 	if (ctrlpriv->era < 3)
10947e0880b9SHoria Geantă 		append_math_add_imm_u32(desc, REG3, ZERO, IMM, req->assoclen);
10957e0880b9SHoria Geantă 	else
10967e0880b9SHoria Geantă 		append_math_add_imm_u32(desc, DPOVRD, ZERO, IMM, req->assoclen);
10977e0880b9SHoria Geantă 
10988b18e235SHoria Geantă 	if (ivsize && ((is_rfc3686 && encrypt) || !alg->caam.geniv))
1099479bcc7cSHerbert Xu 		append_load_as_imm(desc, req->iv, ivsize,
1100479bcc7cSHerbert Xu 				   LDST_CLASS_1_CCB |
1101479bcc7cSHerbert Xu 				   LDST_SRCDST_BYTE_CONTEXT |
1102479bcc7cSHerbert Xu 				   (ivoffset << LDST_OFFSET_SHIFT));
11038e8ec596SKim Phillips }
11048e8ec596SKim Phillips 
11058e8ec596SKim Phillips /*
1106acdca31dSYuan Kang  * Fill in ablkcipher job descriptor
1107acdca31dSYuan Kang  */
1108acdca31dSYuan Kang static void init_ablkcipher_job(u32 *sh_desc, dma_addr_t ptr,
1109acdca31dSYuan Kang 				struct ablkcipher_edesc *edesc,
1110115957bbSHoria Geantă 				struct ablkcipher_request *req)
1111acdca31dSYuan Kang {
1112acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
1113acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
1114acdca31dSYuan Kang 	u32 *desc = edesc->hw_desc;
1115115957bbSHoria Geantă 	u32 out_options = 0;
1116115957bbSHoria Geantă 	dma_addr_t dst_dma;
1117115957bbSHoria Geantă 	int len;
1118acdca31dSYuan Kang 
1119acdca31dSYuan Kang #ifdef DEBUG
1120514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "presciv@"__stringify(__LINE__)": ",
1121acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
1122acdca31dSYuan Kang 		       ivsize, 1);
1123fa0c92dbSHoria Geantă 	pr_err("asked=%d, nbytes%d\n",
1124fa0c92dbSHoria Geantă 	       (int)edesc->src_nents > 1 ? 100 : req->nbytes, req->nbytes);
1125972b812bSHoria Geantă #endif
1126972b812bSHoria Geantă 	caam_dump_sg(KERN_ERR, "src    @" __stringify(__LINE__)": ",
11275ecf8ef9SCatalin Vasile 		     DUMP_PREFIX_ADDRESS, 16, 4, req->src,
1128fa0c92dbSHoria Geantă 		     edesc->src_nents > 1 ? 100 : req->nbytes, 1);
1129acdca31dSYuan Kang 
1130acdca31dSYuan Kang 	len = desc_len(sh_desc);
1131acdca31dSYuan Kang 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
1132acdca31dSYuan Kang 
1133115957bbSHoria Geantă 	append_seq_in_ptr(desc, edesc->sec4_sg_dma, req->nbytes + ivsize,
1134115957bbSHoria Geantă 			  LDST_SGF);
1135acdca31dSYuan Kang 
1136acdca31dSYuan Kang 	if (likely(req->src == req->dst)) {
1137115957bbSHoria Geantă 		dst_dma = edesc->sec4_sg_dma + sizeof(struct sec4_sg_entry);
1138acdca31dSYuan Kang 		out_options = LDST_SGF;
1139acdca31dSYuan Kang 	} else {
1140fa0c92dbSHoria Geantă 		if (edesc->dst_nents == 1) {
1141acdca31dSYuan Kang 			dst_dma = sg_dma_address(req->dst);
1142acdca31dSYuan Kang 		} else {
1143115957bbSHoria Geantă 			dst_dma = edesc->sec4_sg_dma + (edesc->src_nents + 1) *
1144115957bbSHoria Geantă 				  sizeof(struct sec4_sg_entry);
1145acdca31dSYuan Kang 			out_options = LDST_SGF;
1146acdca31dSYuan Kang 		}
1147acdca31dSYuan Kang 	}
1148acdca31dSYuan Kang 	append_seq_out_ptr(desc, dst_dma, req->nbytes, out_options);
1149acdca31dSYuan Kang }
1150acdca31dSYuan Kang 
1151acdca31dSYuan Kang /*
11527222d1a3SCatalin Vasile  * Fill in ablkcipher givencrypt job descriptor
11537222d1a3SCatalin Vasile  */
11547222d1a3SCatalin Vasile static void init_ablkcipher_giv_job(u32 *sh_desc, dma_addr_t ptr,
11557222d1a3SCatalin Vasile 				    struct ablkcipher_edesc *edesc,
1156115957bbSHoria Geantă 				    struct ablkcipher_request *req)
11577222d1a3SCatalin Vasile {
11587222d1a3SCatalin Vasile 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
11597222d1a3SCatalin Vasile 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
11607222d1a3SCatalin Vasile 	u32 *desc = edesc->hw_desc;
1161115957bbSHoria Geantă 	u32 in_options;
11627222d1a3SCatalin Vasile 	dma_addr_t dst_dma, src_dma;
11637222d1a3SCatalin Vasile 	int len, sec4_sg_index = 0;
11647222d1a3SCatalin Vasile 
11657222d1a3SCatalin Vasile #ifdef DEBUG
11667222d1a3SCatalin Vasile 	print_hex_dump(KERN_ERR, "presciv@" __stringify(__LINE__) ": ",
11677222d1a3SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
11687222d1a3SCatalin Vasile 		       ivsize, 1);
1169972b812bSHoria Geantă #endif
1170972b812bSHoria Geantă 	caam_dump_sg(KERN_ERR, "src    @" __stringify(__LINE__) ": ",
11715ecf8ef9SCatalin Vasile 		     DUMP_PREFIX_ADDRESS, 16, 4, req->src,
1172fa0c92dbSHoria Geantă 		     edesc->src_nents > 1 ? 100 : req->nbytes, 1);
11737222d1a3SCatalin Vasile 
11747222d1a3SCatalin Vasile 	len = desc_len(sh_desc);
11757222d1a3SCatalin Vasile 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
11767222d1a3SCatalin Vasile 
1177fa0c92dbSHoria Geantă 	if (edesc->src_nents == 1) {
11787222d1a3SCatalin Vasile 		src_dma = sg_dma_address(req->src);
11797222d1a3SCatalin Vasile 		in_options = 0;
11807222d1a3SCatalin Vasile 	} else {
11817222d1a3SCatalin Vasile 		src_dma = edesc->sec4_sg_dma;
11827222d1a3SCatalin Vasile 		sec4_sg_index += edesc->src_nents;
11837222d1a3SCatalin Vasile 		in_options = LDST_SGF;
11847222d1a3SCatalin Vasile 	}
11857222d1a3SCatalin Vasile 	append_seq_in_ptr(desc, src_dma, req->nbytes, in_options);
11867222d1a3SCatalin Vasile 
1187115957bbSHoria Geantă 	dst_dma = edesc->sec4_sg_dma + sec4_sg_index *
1188115957bbSHoria Geantă 		  sizeof(struct sec4_sg_entry);
1189115957bbSHoria Geantă 	append_seq_out_ptr(desc, dst_dma, req->nbytes + ivsize, LDST_SGF);
11907222d1a3SCatalin Vasile }
11917222d1a3SCatalin Vasile 
11927222d1a3SCatalin Vasile /*
11931acebad3SYuan Kang  * allocate and map the aead extended descriptor
11948e8ec596SKim Phillips  */
1195f2147b88SHerbert Xu static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
1196f2147b88SHerbert Xu 					   int desc_bytes, bool *all_contig_ptr,
1197f2147b88SHerbert Xu 					   bool encrypt)
1198f2147b88SHerbert Xu {
1199f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1200f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1201f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
1202019d62dbSHoria Geantă 	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
1203019d62dbSHoria Geantă 		       GFP_KERNEL : GFP_ATOMIC;
1204838e0a89SHoria Geantă 	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
1205f2147b88SHerbert Xu 	struct aead_edesc *edesc;
1206fa0c92dbSHoria Geantă 	int sec4_sg_index, sec4_sg_len, sec4_sg_bytes;
1207f2147b88SHerbert Xu 	unsigned int authsize = ctx->authsize;
1208f2147b88SHerbert Xu 
1209f2147b88SHerbert Xu 	if (unlikely(req->dst != req->src)) {
1210fa0c92dbSHoria Geantă 		src_nents = sg_nents_for_len(req->src, req->assoclen +
1211fa0c92dbSHoria Geantă 					     req->cryptlen);
1212fd144d83SHoria Geantă 		if (unlikely(src_nents < 0)) {
1213fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
1214fd144d83SHoria Geantă 				req->assoclen + req->cryptlen);
1215fd144d83SHoria Geantă 			return ERR_PTR(src_nents);
1216fd144d83SHoria Geantă 		}
1217fd144d83SHoria Geantă 
1218fa0c92dbSHoria Geantă 		dst_nents = sg_nents_for_len(req->dst, req->assoclen +
1219fa0c92dbSHoria Geantă 					     req->cryptlen +
1220fa0c92dbSHoria Geantă 						(encrypt ? authsize :
1221fa0c92dbSHoria Geantă 							   (-authsize)));
1222fd144d83SHoria Geantă 		if (unlikely(dst_nents < 0)) {
1223fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in dst S/G\n",
1224fd144d83SHoria Geantă 				req->assoclen + req->cryptlen +
1225fd144d83SHoria Geantă 				(encrypt ? authsize : (-authsize)));
1226fd144d83SHoria Geantă 			return ERR_PTR(dst_nents);
1227fd144d83SHoria Geantă 		}
1228f2147b88SHerbert Xu 	} else {
1229fa0c92dbSHoria Geantă 		src_nents = sg_nents_for_len(req->src, req->assoclen +
1230fa0c92dbSHoria Geantă 					     req->cryptlen +
123113fb8fd7SLABBE Corentin 					     (encrypt ? authsize : 0));
1232fd144d83SHoria Geantă 		if (unlikely(src_nents < 0)) {
1233fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
1234fd144d83SHoria Geantă 				req->assoclen + req->cryptlen +
1235fd144d83SHoria Geantă 				(encrypt ? authsize : 0));
1236fd144d83SHoria Geantă 			return ERR_PTR(src_nents);
1237fd144d83SHoria Geantă 		}
1238f2147b88SHerbert Xu 	}
1239f2147b88SHerbert Xu 
1240838e0a89SHoria Geantă 	if (likely(req->src == req->dst)) {
1241838e0a89SHoria Geantă 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1242838e0a89SHoria Geantă 					      DMA_BIDIRECTIONAL);
1243838e0a89SHoria Geantă 		if (unlikely(!mapped_src_nents)) {
1244838e0a89SHoria Geantă 			dev_err(jrdev, "unable to map source\n");
1245838e0a89SHoria Geantă 			return ERR_PTR(-ENOMEM);
1246838e0a89SHoria Geantă 		}
1247838e0a89SHoria Geantă 	} else {
1248838e0a89SHoria Geantă 		/* Cover also the case of null (zero length) input data */
1249838e0a89SHoria Geantă 		if (src_nents) {
1250838e0a89SHoria Geantă 			mapped_src_nents = dma_map_sg(jrdev, req->src,
1251838e0a89SHoria Geantă 						      src_nents, DMA_TO_DEVICE);
1252838e0a89SHoria Geantă 			if (unlikely(!mapped_src_nents)) {
1253838e0a89SHoria Geantă 				dev_err(jrdev, "unable to map source\n");
1254838e0a89SHoria Geantă 				return ERR_PTR(-ENOMEM);
1255838e0a89SHoria Geantă 			}
1256838e0a89SHoria Geantă 		} else {
1257838e0a89SHoria Geantă 			mapped_src_nents = 0;
1258838e0a89SHoria Geantă 		}
1259838e0a89SHoria Geantă 
1260838e0a89SHoria Geantă 		mapped_dst_nents = dma_map_sg(jrdev, req->dst, dst_nents,
1261838e0a89SHoria Geantă 					      DMA_FROM_DEVICE);
1262838e0a89SHoria Geantă 		if (unlikely(!mapped_dst_nents)) {
1263838e0a89SHoria Geantă 			dev_err(jrdev, "unable to map destination\n");
1264838e0a89SHoria Geantă 			dma_unmap_sg(jrdev, req->src, src_nents, DMA_TO_DEVICE);
1265838e0a89SHoria Geantă 			return ERR_PTR(-ENOMEM);
1266838e0a89SHoria Geantă 		}
1267838e0a89SHoria Geantă 	}
1268838e0a89SHoria Geantă 
1269838e0a89SHoria Geantă 	sec4_sg_len = mapped_src_nents > 1 ? mapped_src_nents : 0;
1270838e0a89SHoria Geantă 	sec4_sg_len += mapped_dst_nents > 1 ? mapped_dst_nents : 0;
1271f2147b88SHerbert Xu 	sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry);
1272f2147b88SHerbert Xu 
1273f2147b88SHerbert Xu 	/* allocate space for base edesc and hw desc commands, link tables */
1274dde20ae9SVictoria Milhoan 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes,
1275dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
1276f2147b88SHerbert Xu 	if (!edesc) {
1277838e0a89SHoria Geantă 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
1278a38acd23SHoria Geantă 			   0, DMA_NONE, 0, 0);
1279f2147b88SHerbert Xu 		return ERR_PTR(-ENOMEM);
1280f2147b88SHerbert Xu 	}
1281f2147b88SHerbert Xu 
1282f2147b88SHerbert Xu 	edesc->src_nents = src_nents;
1283f2147b88SHerbert Xu 	edesc->dst_nents = dst_nents;
1284f2147b88SHerbert Xu 	edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) +
1285f2147b88SHerbert Xu 			 desc_bytes;
1286838e0a89SHoria Geantă 	*all_contig_ptr = !(mapped_src_nents > 1);
1287f2147b88SHerbert Xu 
1288f2147b88SHerbert Xu 	sec4_sg_index = 0;
1289838e0a89SHoria Geantă 	if (mapped_src_nents > 1) {
1290838e0a89SHoria Geantă 		sg_to_sec4_sg_last(req->src, mapped_src_nents,
1291f2147b88SHerbert Xu 				   edesc->sec4_sg + sec4_sg_index, 0);
1292838e0a89SHoria Geantă 		sec4_sg_index += mapped_src_nents;
1293f2147b88SHerbert Xu 	}
1294838e0a89SHoria Geantă 	if (mapped_dst_nents > 1) {
1295838e0a89SHoria Geantă 		sg_to_sec4_sg_last(req->dst, mapped_dst_nents,
1296f2147b88SHerbert Xu 				   edesc->sec4_sg + sec4_sg_index, 0);
1297f2147b88SHerbert Xu 	}
1298f2147b88SHerbert Xu 
1299f2147b88SHerbert Xu 	if (!sec4_sg_bytes)
1300f2147b88SHerbert Xu 		return edesc;
1301f2147b88SHerbert Xu 
1302f2147b88SHerbert Xu 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
1303f2147b88SHerbert Xu 					    sec4_sg_bytes, DMA_TO_DEVICE);
1304f2147b88SHerbert Xu 	if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
1305f2147b88SHerbert Xu 		dev_err(jrdev, "unable to map S/G table\n");
1306f2147b88SHerbert Xu 		aead_unmap(jrdev, edesc, req);
1307f2147b88SHerbert Xu 		kfree(edesc);
1308f2147b88SHerbert Xu 		return ERR_PTR(-ENOMEM);
1309f2147b88SHerbert Xu 	}
1310f2147b88SHerbert Xu 
1311f2147b88SHerbert Xu 	edesc->sec4_sg_bytes = sec4_sg_bytes;
1312f2147b88SHerbert Xu 
1313f2147b88SHerbert Xu 	return edesc;
1314f2147b88SHerbert Xu }
1315f2147b88SHerbert Xu 
1316f2147b88SHerbert Xu static int gcm_encrypt(struct aead_request *req)
13178e8ec596SKim Phillips {
13180e479300SYuan Kang 	struct aead_edesc *edesc;
13198e8ec596SKim Phillips 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
13208e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
13218e8ec596SKim Phillips 	struct device *jrdev = ctx->jrdev;
13221acebad3SYuan Kang 	bool all_contig;
13238e8ec596SKim Phillips 	u32 *desc;
13241acebad3SYuan Kang 	int ret = 0;
13251acebad3SYuan Kang 
13268e8ec596SKim Phillips 	/* allocate extended descriptor */
1327f2147b88SHerbert Xu 	edesc = aead_edesc_alloc(req, GCM_DESC_JOB_IO_LEN, &all_contig, true);
13288e8ec596SKim Phillips 	if (IS_ERR(edesc))
13298e8ec596SKim Phillips 		return PTR_ERR(edesc);
13308e8ec596SKim Phillips 
13311acebad3SYuan Kang 	/* Create and submit job descriptor */
1332f2147b88SHerbert Xu 	init_gcm_job(req, edesc, all_contig, true);
13331acebad3SYuan Kang #ifdef DEBUG
1334514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
13351acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
13361acebad3SYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
13371acebad3SYuan Kang #endif
13381acebad3SYuan Kang 
13398e8ec596SKim Phillips 	desc = edesc->hw_desc;
13401acebad3SYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
13411acebad3SYuan Kang 	if (!ret) {
13421acebad3SYuan Kang 		ret = -EINPROGRESS;
13431acebad3SYuan Kang 	} else {
13441acebad3SYuan Kang 		aead_unmap(jrdev, edesc, req);
13451acebad3SYuan Kang 		kfree(edesc);
13461acebad3SYuan Kang 	}
13478e8ec596SKim Phillips 
13481acebad3SYuan Kang 	return ret;
13498e8ec596SKim Phillips }
13508e8ec596SKim Phillips 
135146218750SHerbert Xu static int ipsec_gcm_encrypt(struct aead_request *req)
135246218750SHerbert Xu {
135346218750SHerbert Xu 	if (req->assoclen < 8)
135446218750SHerbert Xu 		return -EINVAL;
135546218750SHerbert Xu 
135646218750SHerbert Xu 	return gcm_encrypt(req);
135746218750SHerbert Xu }
135846218750SHerbert Xu 
1359479bcc7cSHerbert Xu static int aead_encrypt(struct aead_request *req)
13608e8ec596SKim Phillips {
13611acebad3SYuan Kang 	struct aead_edesc *edesc;
13620e479300SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
13630e479300SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
13640e479300SYuan Kang 	struct device *jrdev = ctx->jrdev;
13651acebad3SYuan Kang 	bool all_contig;
13660e479300SYuan Kang 	u32 *desc;
13671acebad3SYuan Kang 	int ret = 0;
13680e479300SYuan Kang 
13690e479300SYuan Kang 	/* allocate extended descriptor */
1370479bcc7cSHerbert Xu 	edesc = aead_edesc_alloc(req, AUTHENC_DESC_JOB_IO_LEN,
1371479bcc7cSHerbert Xu 				 &all_contig, true);
13720e479300SYuan Kang 	if (IS_ERR(edesc))
13730e479300SYuan Kang 		return PTR_ERR(edesc);
13740e479300SYuan Kang 
1375f2147b88SHerbert Xu 	/* Create and submit job descriptor */
1376479bcc7cSHerbert Xu 	init_authenc_job(req, edesc, all_contig, true);
13771acebad3SYuan Kang #ifdef DEBUG
1378f2147b88SHerbert Xu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
1379f2147b88SHerbert Xu 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1380f2147b88SHerbert Xu 		       desc_bytes(edesc->hw_desc), 1);
13811acebad3SYuan Kang #endif
13821acebad3SYuan Kang 
1383f2147b88SHerbert Xu 	desc = edesc->hw_desc;
1384479bcc7cSHerbert Xu 	ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
1385f2147b88SHerbert Xu 	if (!ret) {
1386f2147b88SHerbert Xu 		ret = -EINPROGRESS;
1387f2147b88SHerbert Xu 	} else {
1388479bcc7cSHerbert Xu 		aead_unmap(jrdev, edesc, req);
1389f2147b88SHerbert Xu 		kfree(edesc);
1390f2147b88SHerbert Xu 	}
1391f2147b88SHerbert Xu 
1392f2147b88SHerbert Xu 	return ret;
1393f2147b88SHerbert Xu }
1394f2147b88SHerbert Xu 
1395f2147b88SHerbert Xu static int gcm_decrypt(struct aead_request *req)
1396f2147b88SHerbert Xu {
1397f2147b88SHerbert Xu 	struct aead_edesc *edesc;
1398f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1399f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1400f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
1401f2147b88SHerbert Xu 	bool all_contig;
1402f2147b88SHerbert Xu 	u32 *desc;
1403f2147b88SHerbert Xu 	int ret = 0;
1404f2147b88SHerbert Xu 
1405f2147b88SHerbert Xu 	/* allocate extended descriptor */
1406f2147b88SHerbert Xu 	edesc = aead_edesc_alloc(req, GCM_DESC_JOB_IO_LEN, &all_contig, false);
1407f2147b88SHerbert Xu 	if (IS_ERR(edesc))
1408f2147b88SHerbert Xu 		return PTR_ERR(edesc);
1409f2147b88SHerbert Xu 
14101acebad3SYuan Kang 	/* Create and submit job descriptor*/
1411f2147b88SHerbert Xu 	init_gcm_job(req, edesc, all_contig, false);
14121acebad3SYuan Kang #ifdef DEBUG
1413514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
14141acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
14151acebad3SYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
14161acebad3SYuan Kang #endif
14171acebad3SYuan Kang 
14180e479300SYuan Kang 	desc = edesc->hw_desc;
14191acebad3SYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
14201acebad3SYuan Kang 	if (!ret) {
14211acebad3SYuan Kang 		ret = -EINPROGRESS;
14221acebad3SYuan Kang 	} else {
14231acebad3SYuan Kang 		aead_unmap(jrdev, edesc, req);
14241acebad3SYuan Kang 		kfree(edesc);
14251acebad3SYuan Kang 	}
14260e479300SYuan Kang 
14271acebad3SYuan Kang 	return ret;
14281acebad3SYuan Kang }
14290e479300SYuan Kang 
143046218750SHerbert Xu static int ipsec_gcm_decrypt(struct aead_request *req)
143146218750SHerbert Xu {
143246218750SHerbert Xu 	if (req->assoclen < 8)
143346218750SHerbert Xu 		return -EINVAL;
143446218750SHerbert Xu 
143546218750SHerbert Xu 	return gcm_decrypt(req);
143646218750SHerbert Xu }
143746218750SHerbert Xu 
1438479bcc7cSHerbert Xu static int aead_decrypt(struct aead_request *req)
1439f2147b88SHerbert Xu {
1440f2147b88SHerbert Xu 	struct aead_edesc *edesc;
1441f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1442f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1443f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
1444f2147b88SHerbert Xu 	bool all_contig;
1445f2147b88SHerbert Xu 	u32 *desc;
1446f2147b88SHerbert Xu 	int ret = 0;
1447f2147b88SHerbert Xu 
1448972b812bSHoria Geantă 	caam_dump_sg(KERN_ERR, "dec src@" __stringify(__LINE__)": ",
14495ecf8ef9SCatalin Vasile 		     DUMP_PREFIX_ADDRESS, 16, 4, req->src,
145000fef2b2SHoria Geantă 		     req->assoclen + req->cryptlen, 1);
14515ecf8ef9SCatalin Vasile 
1452f2147b88SHerbert Xu 	/* allocate extended descriptor */
1453479bcc7cSHerbert Xu 	edesc = aead_edesc_alloc(req, AUTHENC_DESC_JOB_IO_LEN,
1454479bcc7cSHerbert Xu 				 &all_contig, false);
1455f2147b88SHerbert Xu 	if (IS_ERR(edesc))
1456f2147b88SHerbert Xu 		return PTR_ERR(edesc);
1457f2147b88SHerbert Xu 
1458f2147b88SHerbert Xu 	/* Create and submit job descriptor*/
1459479bcc7cSHerbert Xu 	init_authenc_job(req, edesc, all_contig, false);
1460f2147b88SHerbert Xu #ifdef DEBUG
1461f2147b88SHerbert Xu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
1462f2147b88SHerbert Xu 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1463f2147b88SHerbert Xu 		       desc_bytes(edesc->hw_desc), 1);
1464f2147b88SHerbert Xu #endif
1465f2147b88SHerbert Xu 
1466f2147b88SHerbert Xu 	desc = edesc->hw_desc;
1467479bcc7cSHerbert Xu 	ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
1468f2147b88SHerbert Xu 	if (!ret) {
1469f2147b88SHerbert Xu 		ret = -EINPROGRESS;
1470f2147b88SHerbert Xu 	} else {
1471479bcc7cSHerbert Xu 		aead_unmap(jrdev, edesc, req);
1472f2147b88SHerbert Xu 		kfree(edesc);
1473f2147b88SHerbert Xu 	}
1474f2147b88SHerbert Xu 
1475f2147b88SHerbert Xu 	return ret;
1476f2147b88SHerbert Xu }
1477f2147b88SHerbert Xu 
1478acdca31dSYuan Kang /*
1479acdca31dSYuan Kang  * allocate and map the ablkcipher extended descriptor for ablkcipher
1480acdca31dSYuan Kang  */
1481acdca31dSYuan Kang static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request
1482115957bbSHoria Geantă 						       *req, int desc_bytes)
1483acdca31dSYuan Kang {
1484acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
1485acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
1486acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
148742cfcafbSHoria Geantă 	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
1488acdca31dSYuan Kang 		       GFP_KERNEL : GFP_ATOMIC;
1489838e0a89SHoria Geantă 	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
1490acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
1491115957bbSHoria Geantă 	dma_addr_t iv_dma;
1492115957bbSHoria Geantă 	u8 *iv;
1493acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
1494838e0a89SHoria Geantă 	int dst_sg_idx, sec4_sg_ents, sec4_sg_bytes;
1495acdca31dSYuan Kang 
1496fa0c92dbSHoria Geantă 	src_nents = sg_nents_for_len(req->src, req->nbytes);
1497fd144d83SHoria Geantă 	if (unlikely(src_nents < 0)) {
1498fd144d83SHoria Geantă 		dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
1499fd144d83SHoria Geantă 			req->nbytes);
1500fd144d83SHoria Geantă 		return ERR_PTR(src_nents);
1501fd144d83SHoria Geantă 	}
1502acdca31dSYuan Kang 
1503fd144d83SHoria Geantă 	if (req->dst != req->src) {
1504fa0c92dbSHoria Geantă 		dst_nents = sg_nents_for_len(req->dst, req->nbytes);
1505fd144d83SHoria Geantă 		if (unlikely(dst_nents < 0)) {
1506fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in dst S/G\n",
1507fd144d83SHoria Geantă 				req->nbytes);
1508fd144d83SHoria Geantă 			return ERR_PTR(dst_nents);
1509fd144d83SHoria Geantă 		}
1510fd144d83SHoria Geantă 	}
1511acdca31dSYuan Kang 
1512acdca31dSYuan Kang 	if (likely(req->src == req->dst)) {
1513838e0a89SHoria Geantă 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1514838e0a89SHoria Geantă 					      DMA_BIDIRECTIONAL);
1515838e0a89SHoria Geantă 		if (unlikely(!mapped_src_nents)) {
1516c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map source\n");
1517c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1518c73e36e8SHoria Geantă 		}
1519acdca31dSYuan Kang 	} else {
1520838e0a89SHoria Geantă 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1521838e0a89SHoria Geantă 					      DMA_TO_DEVICE);
1522838e0a89SHoria Geantă 		if (unlikely(!mapped_src_nents)) {
1523c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map source\n");
1524c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1525c73e36e8SHoria Geantă 		}
1526c73e36e8SHoria Geantă 
1527838e0a89SHoria Geantă 		mapped_dst_nents = dma_map_sg(jrdev, req->dst, dst_nents,
1528838e0a89SHoria Geantă 					      DMA_FROM_DEVICE);
1529838e0a89SHoria Geantă 		if (unlikely(!mapped_dst_nents)) {
1530c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map destination\n");
1531fa0c92dbSHoria Geantă 			dma_unmap_sg(jrdev, req->src, src_nents, DMA_TO_DEVICE);
1532c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1533c73e36e8SHoria Geantă 		}
1534acdca31dSYuan Kang 	}
1535acdca31dSYuan Kang 
1536838e0a89SHoria Geantă 	sec4_sg_ents = 1 + mapped_src_nents;
1537fa0c92dbSHoria Geantă 	dst_sg_idx = sec4_sg_ents;
1538838e0a89SHoria Geantă 	sec4_sg_ents += mapped_dst_nents > 1 ? mapped_dst_nents : 0;
1539fa0c92dbSHoria Geantă 	sec4_sg_bytes = sec4_sg_ents * sizeof(struct sec4_sg_entry);
1540acdca31dSYuan Kang 
1541115957bbSHoria Geantă 	/*
1542115957bbSHoria Geantă 	 * allocate space for base edesc and hw desc commands, link tables, IV
1543115957bbSHoria Geantă 	 */
1544115957bbSHoria Geantă 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes + ivsize,
1545dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
1546acdca31dSYuan Kang 	if (!edesc) {
1547acdca31dSYuan Kang 		dev_err(jrdev, "could not allocate extended descriptor\n");
1548115957bbSHoria Geantă 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
1549115957bbSHoria Geantă 			   0, DMA_NONE, 0, 0);
1550acdca31dSYuan Kang 		return ERR_PTR(-ENOMEM);
1551acdca31dSYuan Kang 	}
1552acdca31dSYuan Kang 
1553acdca31dSYuan Kang 	edesc->src_nents = src_nents;
1554acdca31dSYuan Kang 	edesc->dst_nents = dst_nents;
1555a299c837SYuan Kang 	edesc->sec4_sg_bytes = sec4_sg_bytes;
1556a299c837SYuan Kang 	edesc->sec4_sg = (void *)edesc + sizeof(struct ablkcipher_edesc) +
1557acdca31dSYuan Kang 			 desc_bytes;
1558a38acd23SHoria Geantă 	edesc->iv_dir = DMA_TO_DEVICE;
1559acdca31dSYuan Kang 
1560115957bbSHoria Geantă 	/* Make sure IV is located in a DMAable area */
1561115957bbSHoria Geantă 	iv = (u8 *)edesc->hw_desc + desc_bytes + sec4_sg_bytes;
1562115957bbSHoria Geantă 	memcpy(iv, req->info, ivsize);
1563115957bbSHoria Geantă 
1564115957bbSHoria Geantă 	iv_dma = dma_map_single(jrdev, iv, ivsize, DMA_TO_DEVICE);
1565115957bbSHoria Geantă 	if (dma_mapping_error(jrdev, iv_dma)) {
1566115957bbSHoria Geantă 		dev_err(jrdev, "unable to map IV\n");
1567115957bbSHoria Geantă 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
1568115957bbSHoria Geantă 			   0, DMA_NONE, 0, 0);
1569115957bbSHoria Geantă 		kfree(edesc);
1570115957bbSHoria Geantă 		return ERR_PTR(-ENOMEM);
1571acdca31dSYuan Kang 	}
1572acdca31dSYuan Kang 
1573115957bbSHoria Geantă 	dma_to_sec4_sg_one(edesc->sec4_sg, iv_dma, ivsize, 0);
1574115957bbSHoria Geantă 	sg_to_sec4_sg_last(req->src, mapped_src_nents, edesc->sec4_sg + 1, 0);
1575115957bbSHoria Geantă 
1576838e0a89SHoria Geantă 	if (mapped_dst_nents > 1) {
1577838e0a89SHoria Geantă 		sg_to_sec4_sg_last(req->dst, mapped_dst_nents,
1578fa0c92dbSHoria Geantă 				   edesc->sec4_sg + dst_sg_idx, 0);
1579acdca31dSYuan Kang 	}
1580acdca31dSYuan Kang 
1581a299c837SYuan Kang 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
1582a299c837SYuan Kang 					    sec4_sg_bytes, DMA_TO_DEVICE);
1583ce572085SHoria Geanta 	if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
1584ce572085SHoria Geanta 		dev_err(jrdev, "unable to map S/G table\n");
1585c73e36e8SHoria Geantă 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents,
1586a38acd23SHoria Geantă 			   iv_dma, ivsize, DMA_TO_DEVICE, 0, 0);
1587c73e36e8SHoria Geantă 		kfree(edesc);
1588ce572085SHoria Geanta 		return ERR_PTR(-ENOMEM);
1589ce572085SHoria Geanta 	}
1590ce572085SHoria Geanta 
1591acdca31dSYuan Kang 	edesc->iv_dma = iv_dma;
1592acdca31dSYuan Kang 
1593acdca31dSYuan Kang #ifdef DEBUG
1594514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ablkcipher sec4_sg@"__stringify(__LINE__)": ",
1595a299c837SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->sec4_sg,
1596a299c837SYuan Kang 		       sec4_sg_bytes, 1);
1597acdca31dSYuan Kang #endif
1598acdca31dSYuan Kang 
1599acdca31dSYuan Kang 	return edesc;
1600acdca31dSYuan Kang }
1601acdca31dSYuan Kang 
1602acdca31dSYuan Kang static int ablkcipher_encrypt(struct ablkcipher_request *req)
1603acdca31dSYuan Kang {
1604acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
1605acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
1606acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
1607acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
1608acdca31dSYuan Kang 	u32 *desc;
1609acdca31dSYuan Kang 	int ret = 0;
1610acdca31dSYuan Kang 
1611acdca31dSYuan Kang 	/* allocate extended descriptor */
1612115957bbSHoria Geantă 	edesc = ablkcipher_edesc_alloc(req, DESC_JOB_IO_LEN * CAAM_CMD_SZ);
1613acdca31dSYuan Kang 	if (IS_ERR(edesc))
1614acdca31dSYuan Kang 		return PTR_ERR(edesc);
1615acdca31dSYuan Kang 
1616acdca31dSYuan Kang 	/* Create and submit job descriptor*/
1617115957bbSHoria Geantă 	init_ablkcipher_job(ctx->sh_desc_enc, ctx->sh_desc_enc_dma, edesc, req);
1618acdca31dSYuan Kang #ifdef DEBUG
1619514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ablkcipher jobdesc@"__stringify(__LINE__)": ",
1620acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1621acdca31dSYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
1622acdca31dSYuan Kang #endif
1623acdca31dSYuan Kang 	desc = edesc->hw_desc;
1624acdca31dSYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, ablkcipher_encrypt_done, req);
1625acdca31dSYuan Kang 
1626acdca31dSYuan Kang 	if (!ret) {
1627acdca31dSYuan Kang 		ret = -EINPROGRESS;
1628acdca31dSYuan Kang 	} else {
1629acdca31dSYuan Kang 		ablkcipher_unmap(jrdev, edesc, req);
1630acdca31dSYuan Kang 		kfree(edesc);
1631acdca31dSYuan Kang 	}
1632acdca31dSYuan Kang 
1633acdca31dSYuan Kang 	return ret;
1634acdca31dSYuan Kang }
1635acdca31dSYuan Kang 
1636acdca31dSYuan Kang static int ablkcipher_decrypt(struct ablkcipher_request *req)
1637acdca31dSYuan Kang {
1638acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
1639acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
1640acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
1641115957bbSHoria Geantă 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
1642acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
1643acdca31dSYuan Kang 	u32 *desc;
1644acdca31dSYuan Kang 	int ret = 0;
1645acdca31dSYuan Kang 
1646acdca31dSYuan Kang 	/* allocate extended descriptor */
1647115957bbSHoria Geantă 	edesc = ablkcipher_edesc_alloc(req, DESC_JOB_IO_LEN * CAAM_CMD_SZ);
1648acdca31dSYuan Kang 	if (IS_ERR(edesc))
1649acdca31dSYuan Kang 		return PTR_ERR(edesc);
1650acdca31dSYuan Kang 
1651115957bbSHoria Geantă 	/*
1652115957bbSHoria Geantă 	 * The crypto API expects us to set the IV (req->info) to the last
1653115957bbSHoria Geantă 	 * ciphertext block.
1654115957bbSHoria Geantă 	 */
1655115957bbSHoria Geantă 	scatterwalk_map_and_copy(req->info, req->src, req->nbytes - ivsize,
1656115957bbSHoria Geantă 				 ivsize, 0);
1657115957bbSHoria Geantă 
1658acdca31dSYuan Kang 	/* Create and submit job descriptor*/
1659115957bbSHoria Geantă 	init_ablkcipher_job(ctx->sh_desc_dec, ctx->sh_desc_dec_dma, edesc, req);
1660acdca31dSYuan Kang 	desc = edesc->hw_desc;
1661acdca31dSYuan Kang #ifdef DEBUG
1662514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ablkcipher jobdesc@"__stringify(__LINE__)": ",
1663acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1664acdca31dSYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
1665acdca31dSYuan Kang #endif
1666acdca31dSYuan Kang 
1667acdca31dSYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, ablkcipher_decrypt_done, req);
1668acdca31dSYuan Kang 	if (!ret) {
1669acdca31dSYuan Kang 		ret = -EINPROGRESS;
1670acdca31dSYuan Kang 	} else {
1671acdca31dSYuan Kang 		ablkcipher_unmap(jrdev, edesc, req);
1672acdca31dSYuan Kang 		kfree(edesc);
1673acdca31dSYuan Kang 	}
1674acdca31dSYuan Kang 
1675acdca31dSYuan Kang 	return ret;
1676acdca31dSYuan Kang }
1677acdca31dSYuan Kang 
16787222d1a3SCatalin Vasile /*
16797222d1a3SCatalin Vasile  * allocate and map the ablkcipher extended descriptor
16807222d1a3SCatalin Vasile  * for ablkcipher givencrypt
16817222d1a3SCatalin Vasile  */
16827222d1a3SCatalin Vasile static struct ablkcipher_edesc *ablkcipher_giv_edesc_alloc(
16837222d1a3SCatalin Vasile 				struct skcipher_givcrypt_request *greq,
1684115957bbSHoria Geantă 				int desc_bytes)
16857222d1a3SCatalin Vasile {
16867222d1a3SCatalin Vasile 	struct ablkcipher_request *req = &greq->creq;
16877222d1a3SCatalin Vasile 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
16887222d1a3SCatalin Vasile 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
16897222d1a3SCatalin Vasile 	struct device *jrdev = ctx->jrdev;
1690019d62dbSHoria Geantă 	gfp_t flags = (req->base.flags &  CRYPTO_TFM_REQ_MAY_SLEEP) ?
16917222d1a3SCatalin Vasile 		       GFP_KERNEL : GFP_ATOMIC;
1692838e0a89SHoria Geantă 	int src_nents, mapped_src_nents, dst_nents, mapped_dst_nents;
16937222d1a3SCatalin Vasile 	struct ablkcipher_edesc *edesc;
1694115957bbSHoria Geantă 	dma_addr_t iv_dma;
1695115957bbSHoria Geantă 	u8 *iv;
16967222d1a3SCatalin Vasile 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
1697838e0a89SHoria Geantă 	int dst_sg_idx, sec4_sg_ents, sec4_sg_bytes;
16987222d1a3SCatalin Vasile 
1699fa0c92dbSHoria Geantă 	src_nents = sg_nents_for_len(req->src, req->nbytes);
1700fd144d83SHoria Geantă 	if (unlikely(src_nents < 0)) {
1701fd144d83SHoria Geantă 		dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
1702fd144d83SHoria Geantă 			req->nbytes);
1703fd144d83SHoria Geantă 		return ERR_PTR(src_nents);
1704fd144d83SHoria Geantă 	}
17057222d1a3SCatalin Vasile 
17067222d1a3SCatalin Vasile 	if (likely(req->src == req->dst)) {
1707838e0a89SHoria Geantă 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1708838e0a89SHoria Geantă 					      DMA_BIDIRECTIONAL);
1709838e0a89SHoria Geantă 		if (unlikely(!mapped_src_nents)) {
1710c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map source\n");
1711c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1712c73e36e8SHoria Geantă 		}
1713fd88aac9SHoria Geantă 
1714fd88aac9SHoria Geantă 		dst_nents = src_nents;
1715838e0a89SHoria Geantă 		mapped_dst_nents = src_nents;
17167222d1a3SCatalin Vasile 	} else {
1717838e0a89SHoria Geantă 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1718838e0a89SHoria Geantă 					      DMA_TO_DEVICE);
1719838e0a89SHoria Geantă 		if (unlikely(!mapped_src_nents)) {
1720c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map source\n");
1721c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1722c73e36e8SHoria Geantă 		}
1723c73e36e8SHoria Geantă 
1724fa0c92dbSHoria Geantă 		dst_nents = sg_nents_for_len(req->dst, req->nbytes);
1725fd144d83SHoria Geantă 		if (unlikely(dst_nents < 0)) {
1726fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in dst S/G\n",
1727fd144d83SHoria Geantă 				req->nbytes);
1728fd144d83SHoria Geantă 			return ERR_PTR(dst_nents);
1729fd144d83SHoria Geantă 		}
1730fd144d83SHoria Geantă 
1731838e0a89SHoria Geantă 		mapped_dst_nents = dma_map_sg(jrdev, req->dst, dst_nents,
1732838e0a89SHoria Geantă 					      DMA_FROM_DEVICE);
1733838e0a89SHoria Geantă 		if (unlikely(!mapped_dst_nents)) {
1734c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map destination\n");
1735fa0c92dbSHoria Geantă 			dma_unmap_sg(jrdev, req->src, src_nents, DMA_TO_DEVICE);
1736c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1737c73e36e8SHoria Geantă 		}
17387222d1a3SCatalin Vasile 	}
17397222d1a3SCatalin Vasile 
1740838e0a89SHoria Geantă 	sec4_sg_ents = mapped_src_nents > 1 ? mapped_src_nents : 0;
1741fa0c92dbSHoria Geantă 	dst_sg_idx = sec4_sg_ents;
1742838e0a89SHoria Geantă 	sec4_sg_ents += 1 + mapped_dst_nents;
17437222d1a3SCatalin Vasile 
1744115957bbSHoria Geantă 	/*
1745115957bbSHoria Geantă 	 * allocate space for base edesc and hw desc commands, link tables, IV
1746115957bbSHoria Geantă 	 */
1747fa0c92dbSHoria Geantă 	sec4_sg_bytes = sec4_sg_ents * sizeof(struct sec4_sg_entry);
1748115957bbSHoria Geantă 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes + ivsize,
1749dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
17507222d1a3SCatalin Vasile 	if (!edesc) {
17517222d1a3SCatalin Vasile 		dev_err(jrdev, "could not allocate extended descriptor\n");
1752115957bbSHoria Geantă 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
1753115957bbSHoria Geantă 			   0, DMA_NONE, 0, 0);
17547222d1a3SCatalin Vasile 		return ERR_PTR(-ENOMEM);
17557222d1a3SCatalin Vasile 	}
17567222d1a3SCatalin Vasile 
17577222d1a3SCatalin Vasile 	edesc->src_nents = src_nents;
17587222d1a3SCatalin Vasile 	edesc->dst_nents = dst_nents;
17597222d1a3SCatalin Vasile 	edesc->sec4_sg_bytes = sec4_sg_bytes;
17607222d1a3SCatalin Vasile 	edesc->sec4_sg = (void *)edesc + sizeof(struct ablkcipher_edesc) +
17617222d1a3SCatalin Vasile 			 desc_bytes;
1762a38acd23SHoria Geantă 	edesc->iv_dir = DMA_FROM_DEVICE;
17637222d1a3SCatalin Vasile 
1764115957bbSHoria Geantă 	/* Make sure IV is located in a DMAable area */
1765115957bbSHoria Geantă 	iv = (u8 *)edesc->hw_desc + desc_bytes + sec4_sg_bytes;
1766115957bbSHoria Geantă 	iv_dma = dma_map_single(jrdev, iv, ivsize, DMA_FROM_DEVICE);
1767115957bbSHoria Geantă 	if (dma_mapping_error(jrdev, iv_dma)) {
1768115957bbSHoria Geantă 		dev_err(jrdev, "unable to map IV\n");
1769115957bbSHoria Geantă 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
1770115957bbSHoria Geantă 			   0, DMA_NONE, 0, 0);
1771115957bbSHoria Geantă 		kfree(edesc);
1772115957bbSHoria Geantă 		return ERR_PTR(-ENOMEM);
1773115957bbSHoria Geantă 	}
1774115957bbSHoria Geantă 
1775838e0a89SHoria Geantă 	if (mapped_src_nents > 1)
1776838e0a89SHoria Geantă 		sg_to_sec4_sg_last(req->src, mapped_src_nents, edesc->sec4_sg,
1777838e0a89SHoria Geantă 				   0);
17787222d1a3SCatalin Vasile 
1779115957bbSHoria Geantă 	dma_to_sec4_sg_one(edesc->sec4_sg + dst_sg_idx, iv_dma, ivsize, 0);
1780115957bbSHoria Geantă 	sg_to_sec4_sg_last(req->dst, mapped_dst_nents, edesc->sec4_sg +
1781115957bbSHoria Geantă 			   dst_sg_idx + 1, 0);
17827222d1a3SCatalin Vasile 
17837222d1a3SCatalin Vasile 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
17847222d1a3SCatalin Vasile 					    sec4_sg_bytes, DMA_TO_DEVICE);
17857222d1a3SCatalin Vasile 	if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
17867222d1a3SCatalin Vasile 		dev_err(jrdev, "unable to map S/G table\n");
1787c73e36e8SHoria Geantă 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents,
1788a38acd23SHoria Geantă 			   iv_dma, ivsize, DMA_FROM_DEVICE, 0, 0);
1789c73e36e8SHoria Geantă 		kfree(edesc);
17907222d1a3SCatalin Vasile 		return ERR_PTR(-ENOMEM);
17917222d1a3SCatalin Vasile 	}
17927222d1a3SCatalin Vasile 	edesc->iv_dma = iv_dma;
17937222d1a3SCatalin Vasile 
17947222d1a3SCatalin Vasile #ifdef DEBUG
17957222d1a3SCatalin Vasile 	print_hex_dump(KERN_ERR,
17967222d1a3SCatalin Vasile 		       "ablkcipher sec4_sg@" __stringify(__LINE__) ": ",
17977222d1a3SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->sec4_sg,
17987222d1a3SCatalin Vasile 		       sec4_sg_bytes, 1);
17997222d1a3SCatalin Vasile #endif
18007222d1a3SCatalin Vasile 
18017222d1a3SCatalin Vasile 	return edesc;
18027222d1a3SCatalin Vasile }
18037222d1a3SCatalin Vasile 
18047222d1a3SCatalin Vasile static int ablkcipher_givencrypt(struct skcipher_givcrypt_request *creq)
18057222d1a3SCatalin Vasile {
18067222d1a3SCatalin Vasile 	struct ablkcipher_request *req = &creq->creq;
18077222d1a3SCatalin Vasile 	struct ablkcipher_edesc *edesc;
18087222d1a3SCatalin Vasile 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
18097222d1a3SCatalin Vasile 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
18107222d1a3SCatalin Vasile 	struct device *jrdev = ctx->jrdev;
18117222d1a3SCatalin Vasile 	u32 *desc;
18127222d1a3SCatalin Vasile 	int ret = 0;
18137222d1a3SCatalin Vasile 
18147222d1a3SCatalin Vasile 	/* allocate extended descriptor */
1815115957bbSHoria Geantă 	edesc = ablkcipher_giv_edesc_alloc(creq, DESC_JOB_IO_LEN * CAAM_CMD_SZ);
18167222d1a3SCatalin Vasile 	if (IS_ERR(edesc))
18177222d1a3SCatalin Vasile 		return PTR_ERR(edesc);
18187222d1a3SCatalin Vasile 
18197222d1a3SCatalin Vasile 	/* Create and submit job descriptor*/
18207222d1a3SCatalin Vasile 	init_ablkcipher_giv_job(ctx->sh_desc_givenc, ctx->sh_desc_givenc_dma,
1821115957bbSHoria Geantă 				edesc, req);
18227222d1a3SCatalin Vasile #ifdef DEBUG
18237222d1a3SCatalin Vasile 	print_hex_dump(KERN_ERR,
18247222d1a3SCatalin Vasile 		       "ablkcipher jobdesc@" __stringify(__LINE__) ": ",
18257222d1a3SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
18267222d1a3SCatalin Vasile 		       desc_bytes(edesc->hw_desc), 1);
18277222d1a3SCatalin Vasile #endif
18287222d1a3SCatalin Vasile 	desc = edesc->hw_desc;
18297222d1a3SCatalin Vasile 	ret = caam_jr_enqueue(jrdev, desc, ablkcipher_encrypt_done, req);
18307222d1a3SCatalin Vasile 
18317222d1a3SCatalin Vasile 	if (!ret) {
18327222d1a3SCatalin Vasile 		ret = -EINPROGRESS;
18337222d1a3SCatalin Vasile 	} else {
18347222d1a3SCatalin Vasile 		ablkcipher_unmap(jrdev, edesc, req);
18357222d1a3SCatalin Vasile 		kfree(edesc);
18367222d1a3SCatalin Vasile 	}
18377222d1a3SCatalin Vasile 
18387222d1a3SCatalin Vasile 	return ret;
18397222d1a3SCatalin Vasile }
18407222d1a3SCatalin Vasile 
1841885e9e2fSYuan Kang #define template_aead		template_u.aead
1842acdca31dSYuan Kang #define template_ablkcipher	template_u.ablkcipher
18438e8ec596SKim Phillips struct caam_alg_template {
18448e8ec596SKim Phillips 	char name[CRYPTO_MAX_ALG_NAME];
18458e8ec596SKim Phillips 	char driver_name[CRYPTO_MAX_ALG_NAME];
18468e8ec596SKim Phillips 	unsigned int blocksize;
1847885e9e2fSYuan Kang 	u32 type;
1848885e9e2fSYuan Kang 	union {
1849885e9e2fSYuan Kang 		struct ablkcipher_alg ablkcipher;
1850885e9e2fSYuan Kang 	} template_u;
18518e8ec596SKim Phillips 	u32 class1_alg_type;
18528e8ec596SKim Phillips 	u32 class2_alg_type;
18538e8ec596SKim Phillips };
18548e8ec596SKim Phillips 
18558e8ec596SKim Phillips static struct caam_alg_template driver_algs[] = {
1856acdca31dSYuan Kang 	/* ablkcipher descriptor */
1857acdca31dSYuan Kang 	{
1858acdca31dSYuan Kang 		.name = "cbc(aes)",
1859acdca31dSYuan Kang 		.driver_name = "cbc-aes-caam",
1860acdca31dSYuan Kang 		.blocksize = AES_BLOCK_SIZE,
18617222d1a3SCatalin Vasile 		.type = CRYPTO_ALG_TYPE_GIVCIPHER,
1862acdca31dSYuan Kang 		.template_ablkcipher = {
1863acdca31dSYuan Kang 			.setkey = ablkcipher_setkey,
1864acdca31dSYuan Kang 			.encrypt = ablkcipher_encrypt,
1865acdca31dSYuan Kang 			.decrypt = ablkcipher_decrypt,
18667222d1a3SCatalin Vasile 			.givencrypt = ablkcipher_givencrypt,
18677222d1a3SCatalin Vasile 			.geniv = "<built-in>",
1868acdca31dSYuan Kang 			.min_keysize = AES_MIN_KEY_SIZE,
1869acdca31dSYuan Kang 			.max_keysize = AES_MAX_KEY_SIZE,
1870acdca31dSYuan Kang 			.ivsize = AES_BLOCK_SIZE,
1871acdca31dSYuan Kang 			},
1872acdca31dSYuan Kang 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
1873acdca31dSYuan Kang 	},
1874acdca31dSYuan Kang 	{
1875acdca31dSYuan Kang 		.name = "cbc(des3_ede)",
1876acdca31dSYuan Kang 		.driver_name = "cbc-3des-caam",
1877acdca31dSYuan Kang 		.blocksize = DES3_EDE_BLOCK_SIZE,
1878ff2c3a3bSCatalin Vasile 		.type = CRYPTO_ALG_TYPE_GIVCIPHER,
1879acdca31dSYuan Kang 		.template_ablkcipher = {
1880acdca31dSYuan Kang 			.setkey = ablkcipher_setkey,
1881acdca31dSYuan Kang 			.encrypt = ablkcipher_encrypt,
1882acdca31dSYuan Kang 			.decrypt = ablkcipher_decrypt,
1883ff2c3a3bSCatalin Vasile 			.givencrypt = ablkcipher_givencrypt,
1884ff2c3a3bSCatalin Vasile 			.geniv = "<built-in>",
1885acdca31dSYuan Kang 			.min_keysize = DES3_EDE_KEY_SIZE,
1886acdca31dSYuan Kang 			.max_keysize = DES3_EDE_KEY_SIZE,
1887acdca31dSYuan Kang 			.ivsize = DES3_EDE_BLOCK_SIZE,
1888acdca31dSYuan Kang 			},
1889acdca31dSYuan Kang 		.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
1890acdca31dSYuan Kang 	},
1891acdca31dSYuan Kang 	{
1892acdca31dSYuan Kang 		.name = "cbc(des)",
1893acdca31dSYuan Kang 		.driver_name = "cbc-des-caam",
1894acdca31dSYuan Kang 		.blocksize = DES_BLOCK_SIZE,
1895ff2c3a3bSCatalin Vasile 		.type = CRYPTO_ALG_TYPE_GIVCIPHER,
1896acdca31dSYuan Kang 		.template_ablkcipher = {
1897acdca31dSYuan Kang 			.setkey = ablkcipher_setkey,
1898acdca31dSYuan Kang 			.encrypt = ablkcipher_encrypt,
1899acdca31dSYuan Kang 			.decrypt = ablkcipher_decrypt,
1900ff2c3a3bSCatalin Vasile 			.givencrypt = ablkcipher_givencrypt,
1901ff2c3a3bSCatalin Vasile 			.geniv = "<built-in>",
1902acdca31dSYuan Kang 			.min_keysize = DES_KEY_SIZE,
1903acdca31dSYuan Kang 			.max_keysize = DES_KEY_SIZE,
1904acdca31dSYuan Kang 			.ivsize = DES_BLOCK_SIZE,
1905acdca31dSYuan Kang 			},
1906acdca31dSYuan Kang 		.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
19072b22f6c5SCatalin Vasile 	},
19082b22f6c5SCatalin Vasile 	{
19092b22f6c5SCatalin Vasile 		.name = "ctr(aes)",
19102b22f6c5SCatalin Vasile 		.driver_name = "ctr-aes-caam",
19112b22f6c5SCatalin Vasile 		.blocksize = 1,
19122b22f6c5SCatalin Vasile 		.type = CRYPTO_ALG_TYPE_ABLKCIPHER,
19132b22f6c5SCatalin Vasile 		.template_ablkcipher = {
19142b22f6c5SCatalin Vasile 			.setkey = ablkcipher_setkey,
19152b22f6c5SCatalin Vasile 			.encrypt = ablkcipher_encrypt,
19162b22f6c5SCatalin Vasile 			.decrypt = ablkcipher_decrypt,
19172b22f6c5SCatalin Vasile 			.geniv = "chainiv",
19182b22f6c5SCatalin Vasile 			.min_keysize = AES_MIN_KEY_SIZE,
19192b22f6c5SCatalin Vasile 			.max_keysize = AES_MAX_KEY_SIZE,
19202b22f6c5SCatalin Vasile 			.ivsize = AES_BLOCK_SIZE,
19212b22f6c5SCatalin Vasile 			},
19222b22f6c5SCatalin Vasile 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CTR_MOD128,
1923a5f57cffSCatalin Vasile 	},
1924a5f57cffSCatalin Vasile 	{
1925a5f57cffSCatalin Vasile 		.name = "rfc3686(ctr(aes))",
1926a5f57cffSCatalin Vasile 		.driver_name = "rfc3686-ctr-aes-caam",
1927a5f57cffSCatalin Vasile 		.blocksize = 1,
19287222d1a3SCatalin Vasile 		.type = CRYPTO_ALG_TYPE_GIVCIPHER,
1929a5f57cffSCatalin Vasile 		.template_ablkcipher = {
1930a5f57cffSCatalin Vasile 			.setkey = ablkcipher_setkey,
1931a5f57cffSCatalin Vasile 			.encrypt = ablkcipher_encrypt,
1932a5f57cffSCatalin Vasile 			.decrypt = ablkcipher_decrypt,
19337222d1a3SCatalin Vasile 			.givencrypt = ablkcipher_givencrypt,
19347222d1a3SCatalin Vasile 			.geniv = "<built-in>",
1935a5f57cffSCatalin Vasile 			.min_keysize = AES_MIN_KEY_SIZE +
1936a5f57cffSCatalin Vasile 				       CTR_RFC3686_NONCE_SIZE,
1937a5f57cffSCatalin Vasile 			.max_keysize = AES_MAX_KEY_SIZE +
1938a5f57cffSCatalin Vasile 				       CTR_RFC3686_NONCE_SIZE,
1939a5f57cffSCatalin Vasile 			.ivsize = CTR_RFC3686_IV_SIZE,
1940a5f57cffSCatalin Vasile 			},
1941a5f57cffSCatalin Vasile 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CTR_MOD128,
1942c6415a60SCatalin Vasile 	},
1943c6415a60SCatalin Vasile 	{
1944c6415a60SCatalin Vasile 		.name = "xts(aes)",
1945c6415a60SCatalin Vasile 		.driver_name = "xts-aes-caam",
1946c6415a60SCatalin Vasile 		.blocksize = AES_BLOCK_SIZE,
1947c6415a60SCatalin Vasile 		.type = CRYPTO_ALG_TYPE_ABLKCIPHER,
1948c6415a60SCatalin Vasile 		.template_ablkcipher = {
1949c6415a60SCatalin Vasile 			.setkey = xts_ablkcipher_setkey,
1950c6415a60SCatalin Vasile 			.encrypt = ablkcipher_encrypt,
1951c6415a60SCatalin Vasile 			.decrypt = ablkcipher_decrypt,
1952c6415a60SCatalin Vasile 			.geniv = "eseqiv",
1953c6415a60SCatalin Vasile 			.min_keysize = 2 * AES_MIN_KEY_SIZE,
1954c6415a60SCatalin Vasile 			.max_keysize = 2 * AES_MAX_KEY_SIZE,
1955c6415a60SCatalin Vasile 			.ivsize = AES_BLOCK_SIZE,
1956c6415a60SCatalin Vasile 			},
1957c6415a60SCatalin Vasile 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_XTS,
1958c6415a60SCatalin Vasile 	},
19598e8ec596SKim Phillips };
19608e8ec596SKim Phillips 
1961f2147b88SHerbert Xu static struct caam_aead_alg driver_aeads[] = {
1962f2147b88SHerbert Xu 	{
1963f2147b88SHerbert Xu 		.aead = {
1964f2147b88SHerbert Xu 			.base = {
1965f2147b88SHerbert Xu 				.cra_name = "rfc4106(gcm(aes))",
1966f2147b88SHerbert Xu 				.cra_driver_name = "rfc4106-gcm-aes-caam",
1967f2147b88SHerbert Xu 				.cra_blocksize = 1,
1968f2147b88SHerbert Xu 			},
1969f2147b88SHerbert Xu 			.setkey = rfc4106_setkey,
1970f2147b88SHerbert Xu 			.setauthsize = rfc4106_setauthsize,
197146218750SHerbert Xu 			.encrypt = ipsec_gcm_encrypt,
197246218750SHerbert Xu 			.decrypt = ipsec_gcm_decrypt,
19737545e166SCorentin LABBE 			.ivsize = GCM_RFC4106_IV_SIZE,
1974f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
1975f2147b88SHerbert Xu 		},
1976f2147b88SHerbert Xu 		.caam = {
1977f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
1978f2147b88SHerbert Xu 		},
1979f2147b88SHerbert Xu 	},
1980f2147b88SHerbert Xu 	{
1981f2147b88SHerbert Xu 		.aead = {
1982f2147b88SHerbert Xu 			.base = {
1983f2147b88SHerbert Xu 				.cra_name = "rfc4543(gcm(aes))",
1984f2147b88SHerbert Xu 				.cra_driver_name = "rfc4543-gcm-aes-caam",
1985f2147b88SHerbert Xu 				.cra_blocksize = 1,
1986f2147b88SHerbert Xu 			},
1987f2147b88SHerbert Xu 			.setkey = rfc4543_setkey,
1988f2147b88SHerbert Xu 			.setauthsize = rfc4543_setauthsize,
198946218750SHerbert Xu 			.encrypt = ipsec_gcm_encrypt,
199046218750SHerbert Xu 			.decrypt = ipsec_gcm_decrypt,
19917545e166SCorentin LABBE 			.ivsize = GCM_RFC4543_IV_SIZE,
1992f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
1993f2147b88SHerbert Xu 		},
1994f2147b88SHerbert Xu 		.caam = {
1995f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
1996f2147b88SHerbert Xu 		},
1997f2147b88SHerbert Xu 	},
1998f2147b88SHerbert Xu 	/* Galois Counter Mode */
1999f2147b88SHerbert Xu 	{
2000f2147b88SHerbert Xu 		.aead = {
2001f2147b88SHerbert Xu 			.base = {
2002f2147b88SHerbert Xu 				.cra_name = "gcm(aes)",
2003f2147b88SHerbert Xu 				.cra_driver_name = "gcm-aes-caam",
2004f2147b88SHerbert Xu 				.cra_blocksize = 1,
2005f2147b88SHerbert Xu 			},
2006f2147b88SHerbert Xu 			.setkey = gcm_setkey,
2007f2147b88SHerbert Xu 			.setauthsize = gcm_setauthsize,
2008f2147b88SHerbert Xu 			.encrypt = gcm_encrypt,
2009f2147b88SHerbert Xu 			.decrypt = gcm_decrypt,
20107545e166SCorentin LABBE 			.ivsize = GCM_AES_IV_SIZE,
2011f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
2012f2147b88SHerbert Xu 		},
2013f2147b88SHerbert Xu 		.caam = {
2014f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
2015f2147b88SHerbert Xu 		},
2016f2147b88SHerbert Xu 	},
2017479bcc7cSHerbert Xu 	/* single-pass ipsec_esp descriptor */
2018479bcc7cSHerbert Xu 	{
2019479bcc7cSHerbert Xu 		.aead = {
2020479bcc7cSHerbert Xu 			.base = {
2021479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),"
2022479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2023479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2024479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2025479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2026479bcc7cSHerbert Xu 			},
2027479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2028479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2029479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2030479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2031479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2032479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2033479bcc7cSHerbert Xu 		},
2034479bcc7cSHerbert Xu 		.caam = {
2035479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2036479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2037479bcc7cSHerbert Xu 		},
2038479bcc7cSHerbert Xu 	},
2039479bcc7cSHerbert Xu 	{
2040479bcc7cSHerbert Xu 		.aead = {
2041479bcc7cSHerbert Xu 			.base = {
2042479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
2043479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2044479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2045479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2046479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2047479bcc7cSHerbert Xu 			},
2048479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2049479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2050479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2051479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2052479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2053479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2054479bcc7cSHerbert Xu 		},
2055479bcc7cSHerbert Xu 		.caam = {
2056479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2057479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2058479bcc7cSHerbert Xu 		},
2059479bcc7cSHerbert Xu 	},
2060479bcc7cSHerbert Xu 	{
2061479bcc7cSHerbert Xu 		.aead = {
2062479bcc7cSHerbert Xu 			.base = {
2063479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
2064479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2065479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2066479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2067479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2068479bcc7cSHerbert Xu 			},
2069479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2070479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2071479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2072479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2073479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2074479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2075479bcc7cSHerbert Xu 		},
2076479bcc7cSHerbert Xu 		.caam = {
2077479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2078479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2079479bcc7cSHerbert Xu 		},
2080479bcc7cSHerbert Xu 	},
2081479bcc7cSHerbert Xu 	{
2082479bcc7cSHerbert Xu 		.aead = {
2083479bcc7cSHerbert Xu 			.base = {
2084479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
2085479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2086479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
2087479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2088479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2089479bcc7cSHerbert Xu 			},
2090479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2091479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2092479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2093479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2094479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2095479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2096479bcc7cSHerbert Xu 		},
2097479bcc7cSHerbert Xu 		.caam = {
2098479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2099479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2100479bcc7cSHerbert Xu 		},
2101479bcc7cSHerbert Xu 	},
2102479bcc7cSHerbert Xu 	{
2103479bcc7cSHerbert Xu 		.aead = {
2104479bcc7cSHerbert Xu 			.base = {
2105479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
2106479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2107479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
2108479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2109479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2110479bcc7cSHerbert Xu 			},
2111479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2112479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2113479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2114479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2115479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2116479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2117479bcc7cSHerbert Xu 		},
2118479bcc7cSHerbert Xu 		.caam = {
2119479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2120479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2121479bcc7cSHerbert Xu 		},
2122479bcc7cSHerbert Xu 	},
2123479bcc7cSHerbert Xu 	{
2124479bcc7cSHerbert Xu 		.aead = {
2125479bcc7cSHerbert Xu 			.base = {
2126479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
2127479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2128479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
2129479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2130479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2131479bcc7cSHerbert Xu 			},
2132479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2133479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2134479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2135479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2136479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2137479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2138479bcc7cSHerbert Xu 		},
2139479bcc7cSHerbert Xu 		.caam = {
2140479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2141479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2142479bcc7cSHerbert Xu 		},
2143479bcc7cSHerbert Xu 	},
2144479bcc7cSHerbert Xu 	{
2145479bcc7cSHerbert Xu 		.aead = {
2146479bcc7cSHerbert Xu 			.base = {
2147479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(aes))",
2148479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2149479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2150479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2151479bcc7cSHerbert Xu 			},
2152479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2153479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2154479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2155479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2156479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2157479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2158479bcc7cSHerbert Xu 		},
2159479bcc7cSHerbert Xu 		.caam = {
2160479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2161479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2162479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2163479bcc7cSHerbert Xu 		},
2164479bcc7cSHerbert Xu 	},
2165479bcc7cSHerbert Xu 	{
2166479bcc7cSHerbert Xu 		.aead = {
2167479bcc7cSHerbert Xu 			.base = {
2168479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
2169479bcc7cSHerbert Xu 					    "cbc(aes)))",
2170479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
2171479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2172479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2173479bcc7cSHerbert Xu 			},
2174479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2175479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2176479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
21778b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2178479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2179479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2180479bcc7cSHerbert Xu 		},
2181479bcc7cSHerbert Xu 		.caam = {
2182479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2183479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2184479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2185479bcc7cSHerbert Xu 			.geniv = true,
2186479bcc7cSHerbert Xu 		},
2187479bcc7cSHerbert Xu 	},
2188479bcc7cSHerbert Xu 	{
2189479bcc7cSHerbert Xu 		.aead = {
2190479bcc7cSHerbert Xu 			.base = {
2191479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),cbc(aes))",
2192479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2193479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2194479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2195479bcc7cSHerbert Xu 			},
2196479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2197479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2198479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2199479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2200479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2201479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2202479bcc7cSHerbert Xu 		},
2203479bcc7cSHerbert Xu 		.caam = {
2204479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2205479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2206479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2207479bcc7cSHerbert Xu 		},
2208479bcc7cSHerbert Xu 	},
2209479bcc7cSHerbert Xu 	{
2210479bcc7cSHerbert Xu 		.aead = {
2211479bcc7cSHerbert Xu 			.base = {
2212479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
2213479bcc7cSHerbert Xu 					    "cbc(aes)))",
2214479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2215479bcc7cSHerbert Xu 						   "hmac-sha1-cbc-aes-caam",
2216479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2217479bcc7cSHerbert Xu 			},
2218479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2219479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2220479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
22218b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2222479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2223479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2224479bcc7cSHerbert Xu 		},
2225479bcc7cSHerbert Xu 		.caam = {
2226479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2227479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2228479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2229479bcc7cSHerbert Xu 			.geniv = true,
2230479bcc7cSHerbert Xu 		},
2231479bcc7cSHerbert Xu 	},
2232479bcc7cSHerbert Xu 	{
2233479bcc7cSHerbert Xu 		.aead = {
2234479bcc7cSHerbert Xu 			.base = {
2235479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),cbc(aes))",
2236479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2237479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2238479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2239479bcc7cSHerbert Xu 			},
2240479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2241479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2242479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2243479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2244479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2245479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2246479bcc7cSHerbert Xu 		},
2247479bcc7cSHerbert Xu 		.caam = {
2248479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2249479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2250479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2251479bcc7cSHerbert Xu 		},
2252479bcc7cSHerbert Xu 	},
2253479bcc7cSHerbert Xu 	{
2254479bcc7cSHerbert Xu 		.aead = {
2255479bcc7cSHerbert Xu 			.base = {
2256479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
2257479bcc7cSHerbert Xu 					    "cbc(aes)))",
2258479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2259479bcc7cSHerbert Xu 						   "hmac-sha224-cbc-aes-caam",
2260479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2261479bcc7cSHerbert Xu 			},
2262479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2263479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2264479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
22658b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2266479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2267479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2268479bcc7cSHerbert Xu 		},
2269479bcc7cSHerbert Xu 		.caam = {
2270479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2271479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2272479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2273479bcc7cSHerbert Xu 			.geniv = true,
2274479bcc7cSHerbert Xu 		},
2275479bcc7cSHerbert Xu 	},
2276479bcc7cSHerbert Xu 	{
2277479bcc7cSHerbert Xu 		.aead = {
2278479bcc7cSHerbert Xu 			.base = {
2279479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),cbc(aes))",
2280479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
2281479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2282479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2283479bcc7cSHerbert Xu 			},
2284479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2285479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2286479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2287479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2288479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2289479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2290479bcc7cSHerbert Xu 		},
2291479bcc7cSHerbert Xu 		.caam = {
2292479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2293479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2294479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2295479bcc7cSHerbert Xu 		},
2296479bcc7cSHerbert Xu 	},
2297479bcc7cSHerbert Xu 	{
2298479bcc7cSHerbert Xu 		.aead = {
2299479bcc7cSHerbert Xu 			.base = {
2300479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
2301479bcc7cSHerbert Xu 					    "cbc(aes)))",
2302479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2303479bcc7cSHerbert Xu 						   "hmac-sha256-cbc-aes-caam",
2304479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2305479bcc7cSHerbert Xu 			},
2306479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2307479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2308479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
23098b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2310479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2311479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2312479bcc7cSHerbert Xu 		},
2313479bcc7cSHerbert Xu 		.caam = {
2314479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2315479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2316479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2317479bcc7cSHerbert Xu 			.geniv = true,
2318479bcc7cSHerbert Xu 		},
2319479bcc7cSHerbert Xu 	},
2320479bcc7cSHerbert Xu 	{
2321479bcc7cSHerbert Xu 		.aead = {
2322479bcc7cSHerbert Xu 			.base = {
2323479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),cbc(aes))",
2324479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
2325479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2326479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2327479bcc7cSHerbert Xu 			},
2328479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2329479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2330479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2331479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2332479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2333479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2334479bcc7cSHerbert Xu 		},
2335479bcc7cSHerbert Xu 		.caam = {
2336479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2337479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2338479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2339479bcc7cSHerbert Xu 		},
2340479bcc7cSHerbert Xu 	},
2341479bcc7cSHerbert Xu 	{
2342479bcc7cSHerbert Xu 		.aead = {
2343479bcc7cSHerbert Xu 			.base = {
2344479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
2345479bcc7cSHerbert Xu 					    "cbc(aes)))",
2346479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2347479bcc7cSHerbert Xu 						   "hmac-sha384-cbc-aes-caam",
2348479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2349479bcc7cSHerbert Xu 			},
2350479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2351479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2352479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
23538b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2354479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2355479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2356479bcc7cSHerbert Xu 		},
2357479bcc7cSHerbert Xu 		.caam = {
2358479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2359479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2360479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2361479bcc7cSHerbert Xu 			.geniv = true,
2362479bcc7cSHerbert Xu 		},
2363479bcc7cSHerbert Xu 	},
2364479bcc7cSHerbert Xu 	{
2365479bcc7cSHerbert Xu 		.aead = {
2366479bcc7cSHerbert Xu 			.base = {
2367479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),cbc(aes))",
2368479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
2369479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2370479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2371479bcc7cSHerbert Xu 			},
2372479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2373479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2374479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2375479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2376479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2377479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2378479bcc7cSHerbert Xu 		},
2379479bcc7cSHerbert Xu 		.caam = {
2380479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2381479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2382479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2383479bcc7cSHerbert Xu 		},
2384479bcc7cSHerbert Xu 	},
2385479bcc7cSHerbert Xu 	{
2386479bcc7cSHerbert Xu 		.aead = {
2387479bcc7cSHerbert Xu 			.base = {
2388479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
2389479bcc7cSHerbert Xu 					    "cbc(aes)))",
2390479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2391479bcc7cSHerbert Xu 						   "hmac-sha512-cbc-aes-caam",
2392479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2393479bcc7cSHerbert Xu 			},
2394479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2395479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2396479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
23978b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2398479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2399479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2400479bcc7cSHerbert Xu 		},
2401479bcc7cSHerbert Xu 		.caam = {
2402479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2403479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2404479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2405479bcc7cSHerbert Xu 			.geniv = true,
2406479bcc7cSHerbert Xu 		},
2407479bcc7cSHerbert Xu 	},
2408479bcc7cSHerbert Xu 	{
2409479bcc7cSHerbert Xu 		.aead = {
2410479bcc7cSHerbert Xu 			.base = {
2411479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2412479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2413479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2414479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2415479bcc7cSHerbert Xu 			},
2416479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2417479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2418479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2419479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2420479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2421479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2422479bcc7cSHerbert Xu 		},
2423479bcc7cSHerbert Xu 		.caam = {
2424479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2425479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2426479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2427479bcc7cSHerbert Xu 		}
2428479bcc7cSHerbert Xu 	},
2429479bcc7cSHerbert Xu 	{
2430479bcc7cSHerbert Xu 		.aead = {
2431479bcc7cSHerbert Xu 			.base = {
2432479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
2433479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2434479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
2435479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2436479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2437479bcc7cSHerbert Xu 			},
2438479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2439479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2440479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
24418b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2442479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2443479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2444479bcc7cSHerbert Xu 		},
2445479bcc7cSHerbert Xu 		.caam = {
2446479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2447479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2448479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2449479bcc7cSHerbert Xu 			.geniv = true,
2450479bcc7cSHerbert Xu 		}
2451479bcc7cSHerbert Xu 	},
2452479bcc7cSHerbert Xu 	{
2453479bcc7cSHerbert Xu 		.aead = {
2454479bcc7cSHerbert Xu 			.base = {
2455479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
2456479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2457479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2458479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2459479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2460479bcc7cSHerbert Xu 			},
2461479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2462479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2463479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2464479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2465479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2466479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2467479bcc7cSHerbert Xu 		},
2468479bcc7cSHerbert Xu 		.caam = {
2469479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2470479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2471479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2472479bcc7cSHerbert Xu 		},
2473479bcc7cSHerbert Xu 	},
2474479bcc7cSHerbert Xu 	{
2475479bcc7cSHerbert Xu 		.aead = {
2476479bcc7cSHerbert Xu 			.base = {
2477479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
2478479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2479479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2480479bcc7cSHerbert Xu 						   "hmac-sha1-"
2481479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2482479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2483479bcc7cSHerbert Xu 			},
2484479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2485479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2486479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
24878b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2488479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2489479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2490479bcc7cSHerbert Xu 		},
2491479bcc7cSHerbert Xu 		.caam = {
2492479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2493479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2494479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2495479bcc7cSHerbert Xu 			.geniv = true,
2496479bcc7cSHerbert Xu 		},
2497479bcc7cSHerbert Xu 	},
2498479bcc7cSHerbert Xu 	{
2499479bcc7cSHerbert Xu 		.aead = {
2500479bcc7cSHerbert Xu 			.base = {
2501479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
2502479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2503479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2504479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2505479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2506479bcc7cSHerbert Xu 			},
2507479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2508479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2509479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2510479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2511479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2512479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2513479bcc7cSHerbert Xu 		},
2514479bcc7cSHerbert Xu 		.caam = {
2515479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2516479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2517479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2518479bcc7cSHerbert Xu 		},
2519479bcc7cSHerbert Xu 	},
2520479bcc7cSHerbert Xu 	{
2521479bcc7cSHerbert Xu 		.aead = {
2522479bcc7cSHerbert Xu 			.base = {
2523479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
2524479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2525479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2526479bcc7cSHerbert Xu 						   "hmac-sha224-"
2527479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2528479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2529479bcc7cSHerbert Xu 			},
2530479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2531479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2532479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
25338b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2534479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2535479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2536479bcc7cSHerbert Xu 		},
2537479bcc7cSHerbert Xu 		.caam = {
2538479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2539479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2540479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2541479bcc7cSHerbert Xu 			.geniv = true,
2542479bcc7cSHerbert Xu 		},
2543479bcc7cSHerbert Xu 	},
2544479bcc7cSHerbert Xu 	{
2545479bcc7cSHerbert Xu 		.aead = {
2546479bcc7cSHerbert Xu 			.base = {
2547479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
2548479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2549479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
2550479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2551479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2552479bcc7cSHerbert Xu 			},
2553479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2554479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2555479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2556479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2557479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2558479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2559479bcc7cSHerbert Xu 		},
2560479bcc7cSHerbert Xu 		.caam = {
2561479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2562479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2563479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2564479bcc7cSHerbert Xu 		},
2565479bcc7cSHerbert Xu 	},
2566479bcc7cSHerbert Xu 	{
2567479bcc7cSHerbert Xu 		.aead = {
2568479bcc7cSHerbert Xu 			.base = {
2569479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
2570479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2571479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2572479bcc7cSHerbert Xu 						   "hmac-sha256-"
2573479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2574479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2575479bcc7cSHerbert Xu 			},
2576479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2577479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2578479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
25798b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2580479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2581479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2582479bcc7cSHerbert Xu 		},
2583479bcc7cSHerbert Xu 		.caam = {
2584479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2585479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2586479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2587479bcc7cSHerbert Xu 			.geniv = true,
2588479bcc7cSHerbert Xu 		},
2589479bcc7cSHerbert Xu 	},
2590479bcc7cSHerbert Xu 	{
2591479bcc7cSHerbert Xu 		.aead = {
2592479bcc7cSHerbert Xu 			.base = {
2593479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
2594479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2595479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
2596479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2597479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2598479bcc7cSHerbert Xu 			},
2599479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2600479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2601479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2602479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2603479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2604479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2605479bcc7cSHerbert Xu 		},
2606479bcc7cSHerbert Xu 		.caam = {
2607479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2608479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2609479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2610479bcc7cSHerbert Xu 		},
2611479bcc7cSHerbert Xu 	},
2612479bcc7cSHerbert Xu 	{
2613479bcc7cSHerbert Xu 		.aead = {
2614479bcc7cSHerbert Xu 			.base = {
2615479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
2616479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2617479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2618479bcc7cSHerbert Xu 						   "hmac-sha384-"
2619479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2620479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2621479bcc7cSHerbert Xu 			},
2622479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2623479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2624479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
26258b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2626479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2627479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2628479bcc7cSHerbert Xu 		},
2629479bcc7cSHerbert Xu 		.caam = {
2630479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2631479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2632479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2633479bcc7cSHerbert Xu 			.geniv = true,
2634479bcc7cSHerbert Xu 		},
2635479bcc7cSHerbert Xu 	},
2636479bcc7cSHerbert Xu 	{
2637479bcc7cSHerbert Xu 		.aead = {
2638479bcc7cSHerbert Xu 			.base = {
2639479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
2640479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2641479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
2642479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2643479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2644479bcc7cSHerbert Xu 			},
2645479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2646479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2647479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2648479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2649479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2650479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2651479bcc7cSHerbert Xu 		},
2652479bcc7cSHerbert Xu 		.caam = {
2653479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2654479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2655479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2656479bcc7cSHerbert Xu 		},
2657479bcc7cSHerbert Xu 	},
2658479bcc7cSHerbert Xu 	{
2659479bcc7cSHerbert Xu 		.aead = {
2660479bcc7cSHerbert Xu 			.base = {
2661479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
2662479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2663479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2664479bcc7cSHerbert Xu 						   "hmac-sha512-"
2665479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2666479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2667479bcc7cSHerbert Xu 			},
2668479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2669479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2670479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
26718b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2672479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2673479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2674479bcc7cSHerbert Xu 		},
2675479bcc7cSHerbert Xu 		.caam = {
2676479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2677479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2678479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2679479bcc7cSHerbert Xu 			.geniv = true,
2680479bcc7cSHerbert Xu 		},
2681479bcc7cSHerbert Xu 	},
2682479bcc7cSHerbert Xu 	{
2683479bcc7cSHerbert Xu 		.aead = {
2684479bcc7cSHerbert Xu 			.base = {
2685479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(des))",
2686479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2687479bcc7cSHerbert Xu 						   "cbc-des-caam",
2688479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2689479bcc7cSHerbert Xu 			},
2690479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2691479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2692479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2693479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2694479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2695479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2696479bcc7cSHerbert Xu 		},
2697479bcc7cSHerbert Xu 		.caam = {
2698479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2699479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2700479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2701479bcc7cSHerbert Xu 		},
2702479bcc7cSHerbert Xu 	},
2703479bcc7cSHerbert Xu 	{
2704479bcc7cSHerbert Xu 		.aead = {
2705479bcc7cSHerbert Xu 			.base = {
2706479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
2707479bcc7cSHerbert Xu 					    "cbc(des)))",
2708479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
2709479bcc7cSHerbert Xu 						   "cbc-des-caam",
2710479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2711479bcc7cSHerbert Xu 			},
2712479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2713479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2714479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
27158b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2716479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2717479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2718479bcc7cSHerbert Xu 		},
2719479bcc7cSHerbert Xu 		.caam = {
2720479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2721479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2722479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2723479bcc7cSHerbert Xu 			.geniv = true,
2724479bcc7cSHerbert Xu 		},
2725479bcc7cSHerbert Xu 	},
2726479bcc7cSHerbert Xu 	{
2727479bcc7cSHerbert Xu 		.aead = {
2728479bcc7cSHerbert Xu 			.base = {
2729479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),cbc(des))",
2730479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2731479bcc7cSHerbert Xu 						   "cbc-des-caam",
2732479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2733479bcc7cSHerbert Xu 			},
2734479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2735479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2736479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2737479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2738479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2739479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2740479bcc7cSHerbert Xu 		},
2741479bcc7cSHerbert Xu 		.caam = {
2742479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2743479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2744479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2745479bcc7cSHerbert Xu 		},
2746479bcc7cSHerbert Xu 	},
2747479bcc7cSHerbert Xu 	{
2748479bcc7cSHerbert Xu 		.aead = {
2749479bcc7cSHerbert Xu 			.base = {
2750479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
2751479bcc7cSHerbert Xu 					    "cbc(des)))",
2752479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2753479bcc7cSHerbert Xu 						   "hmac-sha1-cbc-des-caam",
2754479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2755479bcc7cSHerbert Xu 			},
2756479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2757479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2758479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
27598b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2760479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2761479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2762479bcc7cSHerbert Xu 		},
2763479bcc7cSHerbert Xu 		.caam = {
2764479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2765479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2766479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2767479bcc7cSHerbert Xu 			.geniv = true,
2768479bcc7cSHerbert Xu 		},
2769479bcc7cSHerbert Xu 	},
2770479bcc7cSHerbert Xu 	{
2771479bcc7cSHerbert Xu 		.aead = {
2772479bcc7cSHerbert Xu 			.base = {
2773479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),cbc(des))",
2774479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2775479bcc7cSHerbert Xu 						   "cbc-des-caam",
2776479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2777479bcc7cSHerbert Xu 			},
2778479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2779479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2780479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2781479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2782479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2783479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2784479bcc7cSHerbert Xu 		},
2785479bcc7cSHerbert Xu 		.caam = {
2786479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2787479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2788479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2789479bcc7cSHerbert Xu 		},
2790479bcc7cSHerbert Xu 	},
2791479bcc7cSHerbert Xu 	{
2792479bcc7cSHerbert Xu 		.aead = {
2793479bcc7cSHerbert Xu 			.base = {
2794479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
2795479bcc7cSHerbert Xu 					    "cbc(des)))",
2796479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2797479bcc7cSHerbert Xu 						   "hmac-sha224-cbc-des-caam",
2798479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2799479bcc7cSHerbert Xu 			},
2800479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2801479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2802479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
28038b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2804479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2805479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2806479bcc7cSHerbert Xu 		},
2807479bcc7cSHerbert Xu 		.caam = {
2808479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2809479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2810479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2811479bcc7cSHerbert Xu 			.geniv = true,
2812479bcc7cSHerbert Xu 		},
2813479bcc7cSHerbert Xu 	},
2814479bcc7cSHerbert Xu 	{
2815479bcc7cSHerbert Xu 		.aead = {
2816479bcc7cSHerbert Xu 			.base = {
2817479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),cbc(des))",
2818479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
2819479bcc7cSHerbert Xu 						   "cbc-des-caam",
2820479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2821479bcc7cSHerbert Xu 			},
2822479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2823479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2824479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2825479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2826479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2827479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2828479bcc7cSHerbert Xu 		},
2829479bcc7cSHerbert Xu 		.caam = {
2830479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2831479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2832479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2833479bcc7cSHerbert Xu 		},
2834479bcc7cSHerbert Xu 	},
2835479bcc7cSHerbert Xu 	{
2836479bcc7cSHerbert Xu 		.aead = {
2837479bcc7cSHerbert Xu 			.base = {
2838479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
2839479bcc7cSHerbert Xu 					    "cbc(des)))",
2840479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2841479bcc7cSHerbert Xu 						   "hmac-sha256-cbc-des-caam",
2842479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2843479bcc7cSHerbert Xu 			},
2844479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2845479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2846479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
28478b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2848479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2849479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2850479bcc7cSHerbert Xu 		},
2851479bcc7cSHerbert Xu 		.caam = {
2852479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2853479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2854479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2855479bcc7cSHerbert Xu 			.geniv = true,
2856479bcc7cSHerbert Xu 		},
2857479bcc7cSHerbert Xu 	},
2858479bcc7cSHerbert Xu 	{
2859479bcc7cSHerbert Xu 		.aead = {
2860479bcc7cSHerbert Xu 			.base = {
2861479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),cbc(des))",
2862479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
2863479bcc7cSHerbert Xu 						   "cbc-des-caam",
2864479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2865479bcc7cSHerbert Xu 			},
2866479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2867479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2868479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2869479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2870479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2871479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2872479bcc7cSHerbert Xu 		},
2873479bcc7cSHerbert Xu 		.caam = {
2874479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2875479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2876479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2877479bcc7cSHerbert Xu 		},
2878479bcc7cSHerbert Xu 	},
2879479bcc7cSHerbert Xu 	{
2880479bcc7cSHerbert Xu 		.aead = {
2881479bcc7cSHerbert Xu 			.base = {
2882479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
2883479bcc7cSHerbert Xu 					    "cbc(des)))",
2884479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2885479bcc7cSHerbert Xu 						   "hmac-sha384-cbc-des-caam",
2886479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2887479bcc7cSHerbert Xu 			},
2888479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2889479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2890479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
28918b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2892479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2893479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2894479bcc7cSHerbert Xu 		},
2895479bcc7cSHerbert Xu 		.caam = {
2896479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2897479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2898479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2899479bcc7cSHerbert Xu 			.geniv = true,
2900479bcc7cSHerbert Xu 		},
2901479bcc7cSHerbert Xu 	},
2902479bcc7cSHerbert Xu 	{
2903479bcc7cSHerbert Xu 		.aead = {
2904479bcc7cSHerbert Xu 			.base = {
2905479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),cbc(des))",
2906479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
2907479bcc7cSHerbert Xu 						   "cbc-des-caam",
2908479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2909479bcc7cSHerbert Xu 			},
2910479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2911479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2912479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2913479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2914479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2915479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2916479bcc7cSHerbert Xu 		},
2917479bcc7cSHerbert Xu 		.caam = {
2918479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2919479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2920479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2921479bcc7cSHerbert Xu 		},
2922479bcc7cSHerbert Xu 	},
2923479bcc7cSHerbert Xu 	{
2924479bcc7cSHerbert Xu 		.aead = {
2925479bcc7cSHerbert Xu 			.base = {
2926479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
2927479bcc7cSHerbert Xu 					    "cbc(des)))",
2928479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2929479bcc7cSHerbert Xu 						   "hmac-sha512-cbc-des-caam",
2930479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2931479bcc7cSHerbert Xu 			},
2932479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2933479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2934479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
29358b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2936479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2937479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2938479bcc7cSHerbert Xu 		},
2939479bcc7cSHerbert Xu 		.caam = {
2940479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2941479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2942479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2943479bcc7cSHerbert Xu 			.geniv = true,
2944479bcc7cSHerbert Xu 		},
2945479bcc7cSHerbert Xu 	},
2946479bcc7cSHerbert Xu 	{
2947479bcc7cSHerbert Xu 		.aead = {
2948479bcc7cSHerbert Xu 			.base = {
2949479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),"
2950479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
2951479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2952479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
2953479bcc7cSHerbert Xu 				.cra_blocksize = 1,
2954479bcc7cSHerbert Xu 			},
2955479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2956479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2957479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2958479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2959479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
2960479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2961479bcc7cSHerbert Xu 		},
2962479bcc7cSHerbert Xu 		.caam = {
2963479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
2964479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
2965479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2966479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2967479bcc7cSHerbert Xu 			.rfc3686 = true,
2968479bcc7cSHerbert Xu 		},
2969479bcc7cSHerbert Xu 	},
2970479bcc7cSHerbert Xu 	{
2971479bcc7cSHerbert Xu 		.aead = {
2972479bcc7cSHerbert Xu 			.base = {
2973479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
2974479bcc7cSHerbert Xu 					    "hmac(md5),rfc3686(ctr(aes))))",
2975479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-md5-"
2976479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
2977479bcc7cSHerbert Xu 				.cra_blocksize = 1,
2978479bcc7cSHerbert Xu 			},
2979479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2980479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2981479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
29828b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2983479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
2984479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2985479bcc7cSHerbert Xu 		},
2986479bcc7cSHerbert Xu 		.caam = {
2987479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
2988479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
2989479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2990479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2991479bcc7cSHerbert Xu 			.rfc3686 = true,
2992479bcc7cSHerbert Xu 			.geniv = true,
2993479bcc7cSHerbert Xu 		},
2994479bcc7cSHerbert Xu 	},
2995479bcc7cSHerbert Xu 	{
2996479bcc7cSHerbert Xu 		.aead = {
2997479bcc7cSHerbert Xu 			.base = {
2998479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
2999479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3000479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
3001479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3002479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3003479bcc7cSHerbert Xu 			},
3004479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3005479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3006479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3007479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3008479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3009479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3010479bcc7cSHerbert Xu 		},
3011479bcc7cSHerbert Xu 		.caam = {
3012479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3013479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3014479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3015479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3016479bcc7cSHerbert Xu 			.rfc3686 = true,
3017479bcc7cSHerbert Xu 		},
3018479bcc7cSHerbert Xu 	},
3019479bcc7cSHerbert Xu 	{
3020479bcc7cSHerbert Xu 		.aead = {
3021479bcc7cSHerbert Xu 			.base = {
3022479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
3023479bcc7cSHerbert Xu 					    "hmac(sha1),rfc3686(ctr(aes))))",
3024479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha1-"
3025479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3026479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3027479bcc7cSHerbert Xu 			},
3028479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3029479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3030479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
30318b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3032479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3033479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3034479bcc7cSHerbert Xu 		},
3035479bcc7cSHerbert Xu 		.caam = {
3036479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3037479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3038479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3039479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3040479bcc7cSHerbert Xu 			.rfc3686 = true,
3041479bcc7cSHerbert Xu 			.geniv = true,
3042479bcc7cSHerbert Xu 		},
3043479bcc7cSHerbert Xu 	},
3044479bcc7cSHerbert Xu 	{
3045479bcc7cSHerbert Xu 		.aead = {
3046479bcc7cSHerbert Xu 			.base = {
3047479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
3048479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3049479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
3050479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3051479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3052479bcc7cSHerbert Xu 			},
3053479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3054479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3055479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3056479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3057479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3058479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3059479bcc7cSHerbert Xu 		},
3060479bcc7cSHerbert Xu 		.caam = {
3061479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3062479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3063479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3064479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3065479bcc7cSHerbert Xu 			.rfc3686 = true,
3066479bcc7cSHerbert Xu 		},
3067479bcc7cSHerbert Xu 	},
3068479bcc7cSHerbert Xu 	{
3069479bcc7cSHerbert Xu 		.aead = {
3070479bcc7cSHerbert Xu 			.base = {
3071479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
3072479bcc7cSHerbert Xu 					    "hmac(sha224),rfc3686(ctr(aes))))",
3073479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha224-"
3074479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3075479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3076479bcc7cSHerbert Xu 			},
3077479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3078479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3079479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
30808b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3081479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3082479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3083479bcc7cSHerbert Xu 		},
3084479bcc7cSHerbert Xu 		.caam = {
3085479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3086479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3087479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3088479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3089479bcc7cSHerbert Xu 			.rfc3686 = true,
3090479bcc7cSHerbert Xu 			.geniv = true,
3091479bcc7cSHerbert Xu 		},
3092479bcc7cSHerbert Xu 	},
3093479bcc7cSHerbert Xu 	{
3094479bcc7cSHerbert Xu 		.aead = {
3095479bcc7cSHerbert Xu 			.base = {
3096479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
3097479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3098479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
3099479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3100479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3101479bcc7cSHerbert Xu 			},
3102479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3103479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3104479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3105479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3106479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3107479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3108479bcc7cSHerbert Xu 		},
3109479bcc7cSHerbert Xu 		.caam = {
3110479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3111479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3112479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3113479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3114479bcc7cSHerbert Xu 			.rfc3686 = true,
3115479bcc7cSHerbert Xu 		},
3116479bcc7cSHerbert Xu 	},
3117479bcc7cSHerbert Xu 	{
3118479bcc7cSHerbert Xu 		.aead = {
3119479bcc7cSHerbert Xu 			.base = {
3120479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha256),"
3121479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
3122479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha256-"
3123479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3124479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3125479bcc7cSHerbert Xu 			},
3126479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3127479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3128479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
31298b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3130479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3131479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3132479bcc7cSHerbert Xu 		},
3133479bcc7cSHerbert Xu 		.caam = {
3134479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3135479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3136479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3137479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3138479bcc7cSHerbert Xu 			.rfc3686 = true,
3139479bcc7cSHerbert Xu 			.geniv = true,
3140479bcc7cSHerbert Xu 		},
3141479bcc7cSHerbert Xu 	},
3142479bcc7cSHerbert Xu 	{
3143479bcc7cSHerbert Xu 		.aead = {
3144479bcc7cSHerbert Xu 			.base = {
3145479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
3146479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3147479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
3148479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3149479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3150479bcc7cSHerbert Xu 			},
3151479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3152479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3153479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3154479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3155479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3156479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3157479bcc7cSHerbert Xu 		},
3158479bcc7cSHerbert Xu 		.caam = {
3159479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3160479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3161479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3162479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3163479bcc7cSHerbert Xu 			.rfc3686 = true,
3164479bcc7cSHerbert Xu 		},
3165479bcc7cSHerbert Xu 	},
3166479bcc7cSHerbert Xu 	{
3167479bcc7cSHerbert Xu 		.aead = {
3168479bcc7cSHerbert Xu 			.base = {
3169479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha384),"
3170479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
3171479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha384-"
3172479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3173479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3174479bcc7cSHerbert Xu 			},
3175479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3176479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3177479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
31788b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3179479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3180479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3181479bcc7cSHerbert Xu 		},
3182479bcc7cSHerbert Xu 		.caam = {
3183479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3184479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3185479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3186479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3187479bcc7cSHerbert Xu 			.rfc3686 = true,
3188479bcc7cSHerbert Xu 			.geniv = true,
3189479bcc7cSHerbert Xu 		},
3190479bcc7cSHerbert Xu 	},
3191479bcc7cSHerbert Xu 	{
3192479bcc7cSHerbert Xu 		.aead = {
3193479bcc7cSHerbert Xu 			.base = {
3194479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
3195479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3196479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
3197479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3198479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3199479bcc7cSHerbert Xu 			},
3200479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3201479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3202479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3203479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3204479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3205479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3206479bcc7cSHerbert Xu 		},
3207479bcc7cSHerbert Xu 		.caam = {
3208479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3209479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3210479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3211479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3212479bcc7cSHerbert Xu 			.rfc3686 = true,
3213479bcc7cSHerbert Xu 		},
3214479bcc7cSHerbert Xu 	},
3215479bcc7cSHerbert Xu 	{
3216479bcc7cSHerbert Xu 		.aead = {
3217479bcc7cSHerbert Xu 			.base = {
3218479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha512),"
3219479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
3220479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha512-"
3221479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3222479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3223479bcc7cSHerbert Xu 			},
3224479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3225479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3226479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
32278b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3228479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3229479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3230479bcc7cSHerbert Xu 		},
3231479bcc7cSHerbert Xu 		.caam = {
3232479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3233479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3234479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3235479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3236479bcc7cSHerbert Xu 			.rfc3686 = true,
3237479bcc7cSHerbert Xu 			.geniv = true,
3238479bcc7cSHerbert Xu 		},
3239479bcc7cSHerbert Xu 	},
3240f2147b88SHerbert Xu };
3241f2147b88SHerbert Xu 
3242f2147b88SHerbert Xu struct caam_crypto_alg {
3243f2147b88SHerbert Xu 	struct crypto_alg crypto_alg;
3244f2147b88SHerbert Xu 	struct list_head entry;
3245f2147b88SHerbert Xu 	struct caam_alg_entry caam;
3246f2147b88SHerbert Xu };
3247f2147b88SHerbert Xu 
32487e0880b9SHoria Geantă static int caam_init_common(struct caam_ctx *ctx, struct caam_alg_entry *caam,
32497e0880b9SHoria Geantă 			    bool uses_dkp)
3250f2147b88SHerbert Xu {
3251bbf22344SHoria Geantă 	dma_addr_t dma_addr;
32527e0880b9SHoria Geantă 	struct caam_drv_private *priv;
3253bbf22344SHoria Geantă 
3254f2147b88SHerbert Xu 	ctx->jrdev = caam_jr_alloc();
3255f2147b88SHerbert Xu 	if (IS_ERR(ctx->jrdev)) {
3256f2147b88SHerbert Xu 		pr_err("Job Ring Device allocation for transform failed\n");
3257f2147b88SHerbert Xu 		return PTR_ERR(ctx->jrdev);
3258f2147b88SHerbert Xu 	}
3259f2147b88SHerbert Xu 
32607e0880b9SHoria Geantă 	priv = dev_get_drvdata(ctx->jrdev->parent);
32617e0880b9SHoria Geantă 	if (priv->era >= 6 && uses_dkp)
32627e0880b9SHoria Geantă 		ctx->dir = DMA_BIDIRECTIONAL;
32637e0880b9SHoria Geantă 	else
32647e0880b9SHoria Geantă 		ctx->dir = DMA_TO_DEVICE;
32657e0880b9SHoria Geantă 
3266bbf22344SHoria Geantă 	dma_addr = dma_map_single_attrs(ctx->jrdev, ctx->sh_desc_enc,
3267bbf22344SHoria Geantă 					offsetof(struct caam_ctx,
3268bbf22344SHoria Geantă 						 sh_desc_enc_dma),
32697e0880b9SHoria Geantă 					ctx->dir, DMA_ATTR_SKIP_CPU_SYNC);
3270bbf22344SHoria Geantă 	if (dma_mapping_error(ctx->jrdev, dma_addr)) {
3271bbf22344SHoria Geantă 		dev_err(ctx->jrdev, "unable to map key, shared descriptors\n");
3272bbf22344SHoria Geantă 		caam_jr_free(ctx->jrdev);
3273bbf22344SHoria Geantă 		return -ENOMEM;
3274bbf22344SHoria Geantă 	}
3275bbf22344SHoria Geantă 
3276bbf22344SHoria Geantă 	ctx->sh_desc_enc_dma = dma_addr;
3277bbf22344SHoria Geantă 	ctx->sh_desc_dec_dma = dma_addr + offsetof(struct caam_ctx,
3278bbf22344SHoria Geantă 						   sh_desc_dec);
3279bbf22344SHoria Geantă 	ctx->sh_desc_givenc_dma = dma_addr + offsetof(struct caam_ctx,
3280bbf22344SHoria Geantă 						      sh_desc_givenc);
3281bbf22344SHoria Geantă 	ctx->key_dma = dma_addr + offsetof(struct caam_ctx, key);
3282bbf22344SHoria Geantă 
3283f2147b88SHerbert Xu 	/* copy descriptor header template value */
3284db57656bSHoria Geantă 	ctx->cdata.algtype = OP_TYPE_CLASS1_ALG | caam->class1_alg_type;
3285db57656bSHoria Geantă 	ctx->adata.algtype = OP_TYPE_CLASS2_ALG | caam->class2_alg_type;
3286f2147b88SHerbert Xu 
3287f2147b88SHerbert Xu 	return 0;
3288f2147b88SHerbert Xu }
3289f2147b88SHerbert Xu 
32908e8ec596SKim Phillips static int caam_cra_init(struct crypto_tfm *tfm)
32918e8ec596SKim Phillips {
32928e8ec596SKim Phillips 	struct crypto_alg *alg = tfm->__crt_alg;
32938e8ec596SKim Phillips 	struct caam_crypto_alg *caam_alg =
32948e8ec596SKim Phillips 		 container_of(alg, struct caam_crypto_alg, crypto_alg);
32958e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_tfm_ctx(tfm);
32968e8ec596SKim Phillips 
32977e0880b9SHoria Geantă 	return caam_init_common(ctx, &caam_alg->caam, false);
3298cfc6f11bSRuchika Gupta }
32998e8ec596SKim Phillips 
3300f2147b88SHerbert Xu static int caam_aead_init(struct crypto_aead *tfm)
33018e8ec596SKim Phillips {
3302f2147b88SHerbert Xu 	struct aead_alg *alg = crypto_aead_alg(tfm);
3303f2147b88SHerbert Xu 	struct caam_aead_alg *caam_alg =
3304f2147b88SHerbert Xu 		 container_of(alg, struct caam_aead_alg, aead);
3305f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(tfm);
33068e8ec596SKim Phillips 
33077e0880b9SHoria Geantă 	return caam_init_common(ctx, &caam_alg->caam,
33087e0880b9SHoria Geantă 				alg->setkey == aead_setkey);
3309f2147b88SHerbert Xu }
3310f2147b88SHerbert Xu 
3311f2147b88SHerbert Xu static void caam_exit_common(struct caam_ctx *ctx)
3312f2147b88SHerbert Xu {
3313bbf22344SHoria Geantă 	dma_unmap_single_attrs(ctx->jrdev, ctx->sh_desc_enc_dma,
3314bbf22344SHoria Geantă 			       offsetof(struct caam_ctx, sh_desc_enc_dma),
33157e0880b9SHoria Geantă 			       ctx->dir, DMA_ATTR_SKIP_CPU_SYNC);
3316cfc6f11bSRuchika Gupta 	caam_jr_free(ctx->jrdev);
33178e8ec596SKim Phillips }
33188e8ec596SKim Phillips 
3319f2147b88SHerbert Xu static void caam_cra_exit(struct crypto_tfm *tfm)
3320f2147b88SHerbert Xu {
3321f2147b88SHerbert Xu 	caam_exit_common(crypto_tfm_ctx(tfm));
3322f2147b88SHerbert Xu }
3323f2147b88SHerbert Xu 
3324f2147b88SHerbert Xu static void caam_aead_exit(struct crypto_aead *tfm)
3325f2147b88SHerbert Xu {
3326f2147b88SHerbert Xu 	caam_exit_common(crypto_aead_ctx(tfm));
3327f2147b88SHerbert Xu }
3328f2147b88SHerbert Xu 
33298e8ec596SKim Phillips static void __exit caam_algapi_exit(void)
33308e8ec596SKim Phillips {
33318e8ec596SKim Phillips 
33328e8ec596SKim Phillips 	struct caam_crypto_alg *t_alg, *n;
3333f2147b88SHerbert Xu 	int i;
3334f2147b88SHerbert Xu 
3335f2147b88SHerbert Xu 	for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
3336f2147b88SHerbert Xu 		struct caam_aead_alg *t_alg = driver_aeads + i;
3337f2147b88SHerbert Xu 
3338f2147b88SHerbert Xu 		if (t_alg->registered)
3339f2147b88SHerbert Xu 			crypto_unregister_aead(&t_alg->aead);
3340f2147b88SHerbert Xu 	}
33418e8ec596SKim Phillips 
3342cfc6f11bSRuchika Gupta 	if (!alg_list.next)
33438e8ec596SKim Phillips 		return;
33448e8ec596SKim Phillips 
3345cfc6f11bSRuchika Gupta 	list_for_each_entry_safe(t_alg, n, &alg_list, entry) {
33468e8ec596SKim Phillips 		crypto_unregister_alg(&t_alg->crypto_alg);
33478e8ec596SKim Phillips 		list_del(&t_alg->entry);
33488e8ec596SKim Phillips 		kfree(t_alg);
33498e8ec596SKim Phillips 	}
33508e8ec596SKim Phillips }
33518e8ec596SKim Phillips 
3352cfc6f11bSRuchika Gupta static struct caam_crypto_alg *caam_alg_alloc(struct caam_alg_template
33538e8ec596SKim Phillips 					      *template)
33548e8ec596SKim Phillips {
33558e8ec596SKim Phillips 	struct caam_crypto_alg *t_alg;
33568e8ec596SKim Phillips 	struct crypto_alg *alg;
33578e8ec596SKim Phillips 
33589c4f9733SFabio Estevam 	t_alg = kzalloc(sizeof(*t_alg), GFP_KERNEL);
33598e8ec596SKim Phillips 	if (!t_alg) {
3360cfc6f11bSRuchika Gupta 		pr_err("failed to allocate t_alg\n");
33618e8ec596SKim Phillips 		return ERR_PTR(-ENOMEM);
33628e8ec596SKim Phillips 	}
33638e8ec596SKim Phillips 
33648e8ec596SKim Phillips 	alg = &t_alg->crypto_alg;
33658e8ec596SKim Phillips 
33668e8ec596SKim Phillips 	snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", template->name);
33678e8ec596SKim Phillips 	snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
33688e8ec596SKim Phillips 		 template->driver_name);
33698e8ec596SKim Phillips 	alg->cra_module = THIS_MODULE;
33708e8ec596SKim Phillips 	alg->cra_init = caam_cra_init;
33718e8ec596SKim Phillips 	alg->cra_exit = caam_cra_exit;
33728e8ec596SKim Phillips 	alg->cra_priority = CAAM_CRA_PRIORITY;
33738e8ec596SKim Phillips 	alg->cra_blocksize = template->blocksize;
33748e8ec596SKim Phillips 	alg->cra_alignmask = 0;
33758e8ec596SKim Phillips 	alg->cra_ctxsize = sizeof(struct caam_ctx);
3376d912bb76SNikos Mavrogiannopoulos 	alg->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY |
3377d912bb76SNikos Mavrogiannopoulos 			 template->type;
3378885e9e2fSYuan Kang 	switch (template->type) {
33797222d1a3SCatalin Vasile 	case CRYPTO_ALG_TYPE_GIVCIPHER:
33807222d1a3SCatalin Vasile 		alg->cra_type = &crypto_givcipher_type;
33817222d1a3SCatalin Vasile 		alg->cra_ablkcipher = template->template_ablkcipher;
33827222d1a3SCatalin Vasile 		break;
3383acdca31dSYuan Kang 	case CRYPTO_ALG_TYPE_ABLKCIPHER:
3384acdca31dSYuan Kang 		alg->cra_type = &crypto_ablkcipher_type;
3385acdca31dSYuan Kang 		alg->cra_ablkcipher = template->template_ablkcipher;
3386acdca31dSYuan Kang 		break;
3387885e9e2fSYuan Kang 	}
33888e8ec596SKim Phillips 
3389f2147b88SHerbert Xu 	t_alg->caam.class1_alg_type = template->class1_alg_type;
3390f2147b88SHerbert Xu 	t_alg->caam.class2_alg_type = template->class2_alg_type;
33918e8ec596SKim Phillips 
33928e8ec596SKim Phillips 	return t_alg;
33938e8ec596SKim Phillips }
33948e8ec596SKim Phillips 
3395f2147b88SHerbert Xu static void caam_aead_alg_init(struct caam_aead_alg *t_alg)
3396f2147b88SHerbert Xu {
3397f2147b88SHerbert Xu 	struct aead_alg *alg = &t_alg->aead;
3398f2147b88SHerbert Xu 
3399f2147b88SHerbert Xu 	alg->base.cra_module = THIS_MODULE;
3400f2147b88SHerbert Xu 	alg->base.cra_priority = CAAM_CRA_PRIORITY;
3401f2147b88SHerbert Xu 	alg->base.cra_ctxsize = sizeof(struct caam_ctx);
34025e4b8c1fSHerbert Xu 	alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY;
3403f2147b88SHerbert Xu 
3404f2147b88SHerbert Xu 	alg->init = caam_aead_init;
3405f2147b88SHerbert Xu 	alg->exit = caam_aead_exit;
3406f2147b88SHerbert Xu }
3407f2147b88SHerbert Xu 
34088e8ec596SKim Phillips static int __init caam_algapi_init(void)
34098e8ec596SKim Phillips {
341035af6403SRuchika Gupta 	struct device_node *dev_node;
341135af6403SRuchika Gupta 	struct platform_device *pdev;
341235af6403SRuchika Gupta 	struct device *ctrldev;
3413bf83490eSVictoria Milhoan 	struct caam_drv_private *priv;
34148e8ec596SKim Phillips 	int i = 0, err = 0;
3415bf83490eSVictoria Milhoan 	u32 cha_vid, cha_inst, des_inst, aes_inst, md_inst;
3416bf83490eSVictoria Milhoan 	unsigned int md_limit = SHA512_DIGEST_SIZE;
3417f2147b88SHerbert Xu 	bool registered = false;
34188e8ec596SKim Phillips 
341935af6403SRuchika Gupta 	dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
342035af6403SRuchika Gupta 	if (!dev_node) {
342135af6403SRuchika Gupta 		dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
342235af6403SRuchika Gupta 		if (!dev_node)
342335af6403SRuchika Gupta 			return -ENODEV;
342435af6403SRuchika Gupta 	}
342535af6403SRuchika Gupta 
342635af6403SRuchika Gupta 	pdev = of_find_device_by_node(dev_node);
342735af6403SRuchika Gupta 	if (!pdev) {
342835af6403SRuchika Gupta 		of_node_put(dev_node);
342935af6403SRuchika Gupta 		return -ENODEV;
343035af6403SRuchika Gupta 	}
343135af6403SRuchika Gupta 
343235af6403SRuchika Gupta 	ctrldev = &pdev->dev;
343335af6403SRuchika Gupta 	priv = dev_get_drvdata(ctrldev);
343435af6403SRuchika Gupta 	of_node_put(dev_node);
343535af6403SRuchika Gupta 
343635af6403SRuchika Gupta 	/*
343735af6403SRuchika Gupta 	 * If priv is NULL, it's probably because the caam driver wasn't
343835af6403SRuchika Gupta 	 * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
343935af6403SRuchika Gupta 	 */
344035af6403SRuchika Gupta 	if (!priv)
344135af6403SRuchika Gupta 		return -ENODEV;
344235af6403SRuchika Gupta 
344335af6403SRuchika Gupta 
3444cfc6f11bSRuchika Gupta 	INIT_LIST_HEAD(&alg_list);
34458e8ec596SKim Phillips 
3446bf83490eSVictoria Milhoan 	/*
3447bf83490eSVictoria Milhoan 	 * Register crypto algorithms the device supports.
3448bf83490eSVictoria Milhoan 	 * First, detect presence and attributes of DES, AES, and MD blocks.
3449bf83490eSVictoria Milhoan 	 */
3450bf83490eSVictoria Milhoan 	cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
3451bf83490eSVictoria Milhoan 	cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
3452bf83490eSVictoria Milhoan 	des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >> CHA_ID_LS_DES_SHIFT;
3453bf83490eSVictoria Milhoan 	aes_inst = (cha_inst & CHA_ID_LS_AES_MASK) >> CHA_ID_LS_AES_SHIFT;
3454bf83490eSVictoria Milhoan 	md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
34558e8ec596SKim Phillips 
3456bf83490eSVictoria Milhoan 	/* If MD is present, limit digest size based on LP256 */
3457bf83490eSVictoria Milhoan 	if (md_inst && ((cha_vid & CHA_ID_LS_MD_MASK) == CHA_ID_LS_MD_LP256))
3458bf83490eSVictoria Milhoan 		md_limit = SHA256_DIGEST_SIZE;
3459bf83490eSVictoria Milhoan 
3460bf83490eSVictoria Milhoan 	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
3461bf83490eSVictoria Milhoan 		struct caam_crypto_alg *t_alg;
3462bf83490eSVictoria Milhoan 		struct caam_alg_template *alg = driver_algs + i;
3463bf83490eSVictoria Milhoan 		u32 alg_sel = alg->class1_alg_type & OP_ALG_ALGSEL_MASK;
3464bf83490eSVictoria Milhoan 
3465bf83490eSVictoria Milhoan 		/* Skip DES algorithms if not supported by device */
3466bf83490eSVictoria Milhoan 		if (!des_inst &&
3467bf83490eSVictoria Milhoan 		    ((alg_sel == OP_ALG_ALGSEL_3DES) ||
3468bf83490eSVictoria Milhoan 		     (alg_sel == OP_ALG_ALGSEL_DES)))
3469bf83490eSVictoria Milhoan 				continue;
3470bf83490eSVictoria Milhoan 
3471bf83490eSVictoria Milhoan 		/* Skip AES algorithms if not supported by device */
3472bf83490eSVictoria Milhoan 		if (!aes_inst && (alg_sel == OP_ALG_ALGSEL_AES))
3473bf83490eSVictoria Milhoan 				continue;
3474bf83490eSVictoria Milhoan 
347583d2c9a9SSven Ebenfeld 		/*
347683d2c9a9SSven Ebenfeld 		 * Check support for AES modes not available
347783d2c9a9SSven Ebenfeld 		 * on LP devices.
347883d2c9a9SSven Ebenfeld 		 */
347983d2c9a9SSven Ebenfeld 		if ((cha_vid & CHA_ID_LS_AES_MASK) == CHA_ID_LS_AES_LP)
348083d2c9a9SSven Ebenfeld 			if ((alg->class1_alg_type & OP_ALG_AAI_MASK) ==
348183d2c9a9SSven Ebenfeld 			     OP_ALG_AAI_XTS)
348283d2c9a9SSven Ebenfeld 				continue;
348383d2c9a9SSven Ebenfeld 
3484bf83490eSVictoria Milhoan 		t_alg = caam_alg_alloc(alg);
34858e8ec596SKim Phillips 		if (IS_ERR(t_alg)) {
34868e8ec596SKim Phillips 			err = PTR_ERR(t_alg);
3487bf83490eSVictoria Milhoan 			pr_warn("%s alg allocation failed\n", alg->driver_name);
34888e8ec596SKim Phillips 			continue;
34898e8ec596SKim Phillips 		}
34908e8ec596SKim Phillips 
34918e8ec596SKim Phillips 		err = crypto_register_alg(&t_alg->crypto_alg);
34928e8ec596SKim Phillips 		if (err) {
3493cfc6f11bSRuchika Gupta 			pr_warn("%s alg registration failed\n",
34948e8ec596SKim Phillips 				t_alg->crypto_alg.cra_driver_name);
34958e8ec596SKim Phillips 			kfree(t_alg);
3496f2147b88SHerbert Xu 			continue;
34978e8ec596SKim Phillips 		}
3498f2147b88SHerbert Xu 
3499f2147b88SHerbert Xu 		list_add_tail(&t_alg->entry, &alg_list);
3500f2147b88SHerbert Xu 		registered = true;
3501f2147b88SHerbert Xu 	}
3502f2147b88SHerbert Xu 
3503f2147b88SHerbert Xu 	for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
3504f2147b88SHerbert Xu 		struct caam_aead_alg *t_alg = driver_aeads + i;
3505bf83490eSVictoria Milhoan 		u32 c1_alg_sel = t_alg->caam.class1_alg_type &
3506bf83490eSVictoria Milhoan 				 OP_ALG_ALGSEL_MASK;
3507bf83490eSVictoria Milhoan 		u32 c2_alg_sel = t_alg->caam.class2_alg_type &
3508bf83490eSVictoria Milhoan 				 OP_ALG_ALGSEL_MASK;
3509bf83490eSVictoria Milhoan 		u32 alg_aai = t_alg->caam.class1_alg_type & OP_ALG_AAI_MASK;
3510bf83490eSVictoria Milhoan 
3511bf83490eSVictoria Milhoan 		/* Skip DES algorithms if not supported by device */
3512bf83490eSVictoria Milhoan 		if (!des_inst &&
3513bf83490eSVictoria Milhoan 		    ((c1_alg_sel == OP_ALG_ALGSEL_3DES) ||
3514bf83490eSVictoria Milhoan 		     (c1_alg_sel == OP_ALG_ALGSEL_DES)))
3515bf83490eSVictoria Milhoan 				continue;
3516bf83490eSVictoria Milhoan 
3517bf83490eSVictoria Milhoan 		/* Skip AES algorithms if not supported by device */
3518bf83490eSVictoria Milhoan 		if (!aes_inst && (c1_alg_sel == OP_ALG_ALGSEL_AES))
3519bf83490eSVictoria Milhoan 				continue;
3520bf83490eSVictoria Milhoan 
3521bf83490eSVictoria Milhoan 		/*
3522bf83490eSVictoria Milhoan 		 * Check support for AES algorithms not available
3523bf83490eSVictoria Milhoan 		 * on LP devices.
3524bf83490eSVictoria Milhoan 		 */
3525bf83490eSVictoria Milhoan 		if ((cha_vid & CHA_ID_LS_AES_MASK) == CHA_ID_LS_AES_LP)
3526bf83490eSVictoria Milhoan 			if (alg_aai == OP_ALG_AAI_GCM)
3527bf83490eSVictoria Milhoan 				continue;
3528bf83490eSVictoria Milhoan 
3529bf83490eSVictoria Milhoan 		/*
3530bf83490eSVictoria Milhoan 		 * Skip algorithms requiring message digests
3531bf83490eSVictoria Milhoan 		 * if MD or MD size is not supported by device.
3532bf83490eSVictoria Milhoan 		 */
3533bf83490eSVictoria Milhoan 		if (c2_alg_sel &&
3534bf83490eSVictoria Milhoan 		    (!md_inst || (t_alg->aead.maxauthsize > md_limit)))
3535bf83490eSVictoria Milhoan 				continue;
3536f2147b88SHerbert Xu 
3537f2147b88SHerbert Xu 		caam_aead_alg_init(t_alg);
3538f2147b88SHerbert Xu 
3539f2147b88SHerbert Xu 		err = crypto_register_aead(&t_alg->aead);
3540f2147b88SHerbert Xu 		if (err) {
3541f2147b88SHerbert Xu 			pr_warn("%s alg registration failed\n",
3542f2147b88SHerbert Xu 				t_alg->aead.base.cra_driver_name);
3543f2147b88SHerbert Xu 			continue;
3544f2147b88SHerbert Xu 		}
3545f2147b88SHerbert Xu 
3546f2147b88SHerbert Xu 		t_alg->registered = true;
3547f2147b88SHerbert Xu 		registered = true;
3548f2147b88SHerbert Xu 	}
3549f2147b88SHerbert Xu 
3550f2147b88SHerbert Xu 	if (registered)
3551cfc6f11bSRuchika Gupta 		pr_info("caam algorithms registered in /proc/crypto\n");
35528e8ec596SKim Phillips 
35538e8ec596SKim Phillips 	return err;
35548e8ec596SKim Phillips }
35558e8ec596SKim Phillips 
35568e8ec596SKim Phillips module_init(caam_algapi_init);
35578e8ec596SKim Phillips module_exit(caam_algapi_exit);
35588e8ec596SKim Phillips 
35598e8ec596SKim Phillips MODULE_LICENSE("GPL");
35608e8ec596SKim Phillips MODULE_DESCRIPTION("FSL CAAM support for crypto API");
35618e8ec596SKim Phillips MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
3562