xref: /openbmc/linux/drivers/crypto/caam/caamalg.c (revision bbf22344)
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 
845ecf8ef9SCatalin Vasile #ifdef DEBUG
855ecf8ef9SCatalin Vasile #include <linux/highmem.h>
865ecf8ef9SCatalin Vasile 
875ecf8ef9SCatalin Vasile static void dbg_dump_sg(const char *level, const char *prefix_str,
885ecf8ef9SCatalin Vasile 			int prefix_type, int rowsize, int groupsize,
8900fef2b2SHoria Geantă 			struct scatterlist *sg, size_t tlen, bool ascii)
905ecf8ef9SCatalin Vasile {
915ecf8ef9SCatalin Vasile 	struct scatterlist *it;
925ecf8ef9SCatalin Vasile 	void *it_page;
935ecf8ef9SCatalin Vasile 	size_t len;
945ecf8ef9SCatalin Vasile 	void *buf;
955ecf8ef9SCatalin Vasile 
965ecf8ef9SCatalin Vasile 	for (it = sg; it != NULL && tlen > 0 ; it = sg_next(sg)) {
975ecf8ef9SCatalin Vasile 		/*
985ecf8ef9SCatalin Vasile 		 * make sure the scatterlist's page
995ecf8ef9SCatalin Vasile 		 * has a valid virtual memory mapping
1005ecf8ef9SCatalin Vasile 		 */
1015ecf8ef9SCatalin Vasile 		it_page = kmap_atomic(sg_page(it));
1025ecf8ef9SCatalin Vasile 		if (unlikely(!it_page)) {
1035ecf8ef9SCatalin Vasile 			printk(KERN_ERR "dbg_dump_sg: kmap failed\n");
1045ecf8ef9SCatalin Vasile 			return;
1055ecf8ef9SCatalin Vasile 		}
1065ecf8ef9SCatalin Vasile 
1075ecf8ef9SCatalin Vasile 		buf = it_page + it->offset;
108d69985a0SArnd Bergmann 		len = min_t(size_t, tlen, it->length);
1095ecf8ef9SCatalin Vasile 		print_hex_dump(level, prefix_str, prefix_type, rowsize,
1105ecf8ef9SCatalin Vasile 			       groupsize, buf, len, ascii);
1115ecf8ef9SCatalin Vasile 		tlen -= len;
1125ecf8ef9SCatalin Vasile 
1135ecf8ef9SCatalin Vasile 		kunmap_atomic(it_page);
1145ecf8ef9SCatalin Vasile 	}
1155ecf8ef9SCatalin Vasile }
1165ecf8ef9SCatalin Vasile #endif
1175ecf8ef9SCatalin Vasile 
118cfc6f11bSRuchika Gupta static struct list_head alg_list;
1198e8ec596SKim Phillips 
120479bcc7cSHerbert Xu struct caam_alg_entry {
121479bcc7cSHerbert Xu 	int class1_alg_type;
122479bcc7cSHerbert Xu 	int class2_alg_type;
123479bcc7cSHerbert Xu 	bool rfc3686;
124479bcc7cSHerbert Xu 	bool geniv;
125479bcc7cSHerbert Xu };
126479bcc7cSHerbert Xu 
127479bcc7cSHerbert Xu struct caam_aead_alg {
128479bcc7cSHerbert Xu 	struct aead_alg aead;
129479bcc7cSHerbert Xu 	struct caam_alg_entry caam;
130479bcc7cSHerbert Xu 	bool registered;
131479bcc7cSHerbert Xu };
132479bcc7cSHerbert Xu 
133acdca31dSYuan Kang /*
1348e8ec596SKim Phillips  * per-session context
1358e8ec596SKim Phillips  */
1368e8ec596SKim Phillips struct caam_ctx {
1371acebad3SYuan Kang 	u32 sh_desc_enc[DESC_MAX_USED_LEN];
1381acebad3SYuan Kang 	u32 sh_desc_dec[DESC_MAX_USED_LEN];
1391acebad3SYuan Kang 	u32 sh_desc_givenc[DESC_MAX_USED_LEN];
140bbf22344SHoria Geantă 	u8 key[CAAM_MAX_KEY_SIZE];
1411acebad3SYuan Kang 	dma_addr_t sh_desc_enc_dma;
1421acebad3SYuan Kang 	dma_addr_t sh_desc_dec_dma;
1431acebad3SYuan Kang 	dma_addr_t sh_desc_givenc_dma;
144885e9e2fSYuan Kang 	dma_addr_t key_dma;
145bbf22344SHoria Geantă 	struct device *jrdev;
146db57656bSHoria Geantă 	struct alginfo adata;
147db57656bSHoria Geantă 	struct alginfo cdata;
1488e8ec596SKim Phillips 	unsigned int authsize;
1498e8ec596SKim Phillips };
1508e8ec596SKim Phillips 
151ae4a825fSHoria Geanta static int aead_null_set_sh_desc(struct crypto_aead *aead)
152ae4a825fSHoria Geanta {
153ae4a825fSHoria Geanta 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
154ae4a825fSHoria Geanta 	struct device *jrdev = ctx->jrdev;
155ae4a825fSHoria Geanta 	u32 *desc;
1564cbe79ccSHoria Geantă 	int rem_bytes = CAAM_DESC_BYTES_MAX - AEAD_DESC_JOB_IO_LEN -
1574cbe79ccSHoria Geantă 			ctx->adata.keylen_pad;
158ae4a825fSHoria Geanta 
159ae4a825fSHoria Geanta 	/*
160ae4a825fSHoria Geanta 	 * Job Descriptor and Shared Descriptors
161ae4a825fSHoria Geanta 	 * must all fit into the 64-word Descriptor h/w Buffer
162ae4a825fSHoria Geanta 	 */
1634cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_AEAD_NULL_ENC_LEN) {
164db57656bSHoria Geantă 		ctx->adata.key_inline = true;
1659c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
166db57656bSHoria Geantă 	} else {
167db57656bSHoria Geantă 		ctx->adata.key_inline = false;
1689c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
169db57656bSHoria Geantă 	}
170ae4a825fSHoria Geanta 
171479bcc7cSHerbert Xu 	/* aead_encrypt shared descriptor */
172ae4a825fSHoria Geanta 	desc = ctx->sh_desc_enc;
1738cea7b66SHoria Geantă 	cnstr_shdsc_aead_null_encap(desc, &ctx->adata, ctx->authsize);
174bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
175bbf22344SHoria Geantă 				   desc_bytes(desc), DMA_TO_DEVICE);
176ae4a825fSHoria Geanta 
177ae4a825fSHoria Geanta 	/*
178ae4a825fSHoria Geanta 	 * Job Descriptor and Shared Descriptors
179ae4a825fSHoria Geanta 	 * must all fit into the 64-word Descriptor h/w Buffer
180ae4a825fSHoria Geanta 	 */
1814cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_AEAD_NULL_DEC_LEN) {
182db57656bSHoria Geantă 		ctx->adata.key_inline = true;
1839c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
184db57656bSHoria Geantă 	} else {
185db57656bSHoria Geantă 		ctx->adata.key_inline = false;
1869c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
187db57656bSHoria Geantă 	}
188ae4a825fSHoria Geanta 
189479bcc7cSHerbert Xu 	/* aead_decrypt shared descriptor */
1908cea7b66SHoria Geantă 	desc = ctx->sh_desc_dec;
1918cea7b66SHoria Geantă 	cnstr_shdsc_aead_null_decap(desc, &ctx->adata, ctx->authsize);
192bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
193bbf22344SHoria Geantă 				   desc_bytes(desc), DMA_TO_DEVICE);
194ae4a825fSHoria Geanta 
195ae4a825fSHoria Geanta 	return 0;
196ae4a825fSHoria Geanta }
197ae4a825fSHoria Geanta 
1981acebad3SYuan Kang static int aead_set_sh_desc(struct crypto_aead *aead)
1991acebad3SYuan Kang {
200479bcc7cSHerbert Xu 	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
201479bcc7cSHerbert Xu 						 struct caam_aead_alg, aead);
202add86d55SHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
2031acebad3SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
2041acebad3SYuan Kang 	struct device *jrdev = ctx->jrdev;
205daebc465SCatalin Vasile 	u32 ctx1_iv_off = 0;
2068cea7b66SHoria Geantă 	u32 *desc, *nonce = NULL;
2074cbe79ccSHoria Geantă 	u32 inl_mask;
2084cbe79ccSHoria Geantă 	unsigned int data_len[2];
209db57656bSHoria Geantă 	const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
210daebc465SCatalin Vasile 			       OP_ALG_AAI_CTR_MOD128);
211479bcc7cSHerbert Xu 	const bool is_rfc3686 = alg->caam.rfc3686;
2121acebad3SYuan Kang 
2132fdea258SHoria Geantă 	if (!ctx->authsize)
2142fdea258SHoria Geantă 		return 0;
2152fdea258SHoria Geantă 
216ae4a825fSHoria Geanta 	/* NULL encryption / decryption */
217db57656bSHoria Geantă 	if (!ctx->cdata.keylen)
218ae4a825fSHoria Geanta 		return aead_null_set_sh_desc(aead);
219ae4a825fSHoria Geanta 
2201acebad3SYuan Kang 	/*
221daebc465SCatalin Vasile 	 * AES-CTR needs to load IV in CONTEXT1 reg
222daebc465SCatalin Vasile 	 * at an offset of 128bits (16bytes)
223daebc465SCatalin Vasile 	 * CONTEXT1[255:128] = IV
224daebc465SCatalin Vasile 	 */
225daebc465SCatalin Vasile 	if (ctr_mode)
226daebc465SCatalin Vasile 		ctx1_iv_off = 16;
227daebc465SCatalin Vasile 
228daebc465SCatalin Vasile 	/*
229daebc465SCatalin Vasile 	 * RFC3686 specific:
230daebc465SCatalin Vasile 	 *	CONTEXT1[255:128] = {NONCE, IV, COUNTER}
231daebc465SCatalin Vasile 	 */
2328cea7b66SHoria Geantă 	if (is_rfc3686) {
233daebc465SCatalin Vasile 		ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
2348cea7b66SHoria Geantă 		nonce = (u32 *)((void *)ctx->key + ctx->adata.keylen_pad +
2358cea7b66SHoria Geantă 				ctx->cdata.keylen - CTR_RFC3686_NONCE_SIZE);
2368cea7b66SHoria Geantă 	}
237daebc465SCatalin Vasile 
2384cbe79ccSHoria Geantă 	data_len[0] = ctx->adata.keylen_pad;
2394cbe79ccSHoria Geantă 	data_len[1] = ctx->cdata.keylen;
2404cbe79ccSHoria Geantă 
241479bcc7cSHerbert Xu 	if (alg->caam.geniv)
242479bcc7cSHerbert Xu 		goto skip_enc;
243479bcc7cSHerbert Xu 
244daebc465SCatalin Vasile 	/*
2451acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
2461acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
2471acebad3SYuan Kang 	 */
2484cbe79ccSHoria Geantă 	if (desc_inline_query(DESC_AEAD_ENC_LEN +
2494cbe79ccSHoria Geantă 			      (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
2504cbe79ccSHoria Geantă 			      AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
2514cbe79ccSHoria Geantă 			      ARRAY_SIZE(data_len)) < 0)
2524cbe79ccSHoria Geantă 		return -EINVAL;
2534cbe79ccSHoria Geantă 
2544cbe79ccSHoria Geantă 	if (inl_mask & 1)
2559c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
2564cbe79ccSHoria Geantă 	else
2579c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
2584cbe79ccSHoria Geantă 
2594cbe79ccSHoria Geantă 	if (inl_mask & 2)
2609c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
2614cbe79ccSHoria Geantă 	else
2629c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
2634cbe79ccSHoria Geantă 
2644cbe79ccSHoria Geantă 	ctx->adata.key_inline = !!(inl_mask & 1);
2654cbe79ccSHoria Geantă 	ctx->cdata.key_inline = !!(inl_mask & 2);
2661acebad3SYuan Kang 
267479bcc7cSHerbert Xu 	/* aead_encrypt shared descriptor */
2681acebad3SYuan Kang 	desc = ctx->sh_desc_enc;
2698cea7b66SHoria Geantă 	cnstr_shdsc_aead_encap(desc, &ctx->cdata, &ctx->adata, ctx->authsize,
2708cea7b66SHoria Geantă 			       is_rfc3686, nonce, ctx1_iv_off);
271bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
272bbf22344SHoria Geantă 				   desc_bytes(desc), DMA_TO_DEVICE);
2731acebad3SYuan Kang 
274479bcc7cSHerbert Xu skip_enc:
2751acebad3SYuan Kang 	/*
2761acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
2771acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
2781acebad3SYuan Kang 	 */
2794cbe79ccSHoria Geantă 	if (desc_inline_query(DESC_AEAD_DEC_LEN +
2804cbe79ccSHoria Geantă 			      (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
2814cbe79ccSHoria Geantă 			      AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
2824cbe79ccSHoria Geantă 			      ARRAY_SIZE(data_len)) < 0)
2834cbe79ccSHoria Geantă 		return -EINVAL;
2844cbe79ccSHoria Geantă 
2854cbe79ccSHoria Geantă 	if (inl_mask & 1)
2869c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
2874cbe79ccSHoria Geantă 	else
2889c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
2894cbe79ccSHoria Geantă 
2904cbe79ccSHoria Geantă 	if (inl_mask & 2)
2919c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
2924cbe79ccSHoria Geantă 	else
2939c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
2944cbe79ccSHoria Geantă 
2954cbe79ccSHoria Geantă 	ctx->adata.key_inline = !!(inl_mask & 1);
2964cbe79ccSHoria Geantă 	ctx->cdata.key_inline = !!(inl_mask & 2);
2971acebad3SYuan Kang 
298479bcc7cSHerbert Xu 	/* aead_decrypt shared descriptor */
2991acebad3SYuan Kang 	desc = ctx->sh_desc_dec;
3008cea7b66SHoria Geantă 	cnstr_shdsc_aead_decap(desc, &ctx->cdata, &ctx->adata, ivsize,
3018cea7b66SHoria Geantă 			       ctx->authsize, alg->caam.geniv, is_rfc3686,
3028cea7b66SHoria Geantă 			       nonce, ctx1_iv_off);
303bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
304bbf22344SHoria Geantă 				   desc_bytes(desc), DMA_TO_DEVICE);
3051acebad3SYuan Kang 
306479bcc7cSHerbert Xu 	if (!alg->caam.geniv)
307479bcc7cSHerbert Xu 		goto skip_givenc;
308479bcc7cSHerbert Xu 
3091acebad3SYuan Kang 	/*
3101acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
3111acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
3121acebad3SYuan Kang 	 */
3134cbe79ccSHoria Geantă 	if (desc_inline_query(DESC_AEAD_GIVENC_LEN +
3144cbe79ccSHoria Geantă 			      (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
3154cbe79ccSHoria Geantă 			      AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
3164cbe79ccSHoria Geantă 			      ARRAY_SIZE(data_len)) < 0)
3174cbe79ccSHoria Geantă 		return -EINVAL;
3184cbe79ccSHoria Geantă 
3194cbe79ccSHoria Geantă 	if (inl_mask & 1)
3209c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
3214cbe79ccSHoria Geantă 	else
3229c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
3234cbe79ccSHoria Geantă 
3244cbe79ccSHoria Geantă 	if (inl_mask & 2)
3259c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
3264cbe79ccSHoria Geantă 	else
3279c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
3284cbe79ccSHoria Geantă 
3294cbe79ccSHoria Geantă 	ctx->adata.key_inline = !!(inl_mask & 1);
3304cbe79ccSHoria Geantă 	ctx->cdata.key_inline = !!(inl_mask & 2);
3311acebad3SYuan Kang 
3321acebad3SYuan Kang 	/* aead_givencrypt shared descriptor */
3331d2d87e8SHoria Geantă 	desc = ctx->sh_desc_enc;
3348cea7b66SHoria Geantă 	cnstr_shdsc_aead_givencap(desc, &ctx->cdata, &ctx->adata, ivsize,
3358cea7b66SHoria Geantă 				  ctx->authsize, is_rfc3686, nonce,
3368cea7b66SHoria Geantă 				  ctx1_iv_off);
337bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
338bbf22344SHoria Geantă 				   desc_bytes(desc), DMA_TO_DEVICE);
3391acebad3SYuan Kang 
340479bcc7cSHerbert Xu skip_givenc:
3411acebad3SYuan Kang 	return 0;
3421acebad3SYuan Kang }
3431acebad3SYuan Kang 
3440e479300SYuan Kang static int aead_setauthsize(struct crypto_aead *authenc,
3458e8ec596SKim Phillips 				    unsigned int authsize)
3468e8ec596SKim Phillips {
3478e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
3488e8ec596SKim Phillips 
3498e8ec596SKim Phillips 	ctx->authsize = authsize;
3501acebad3SYuan Kang 	aead_set_sh_desc(authenc);
3518e8ec596SKim Phillips 
3528e8ec596SKim Phillips 	return 0;
3538e8ec596SKim Phillips }
3548e8ec596SKim Phillips 
3553ef8d945STudor Ambarus static int gcm_set_sh_desc(struct crypto_aead *aead)
3563ef8d945STudor Ambarus {
3573ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
3583ef8d945STudor Ambarus 	struct device *jrdev = ctx->jrdev;
3593ef8d945STudor Ambarus 	u32 *desc;
3604cbe79ccSHoria Geantă 	int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
3614cbe79ccSHoria Geantă 			ctx->cdata.keylen;
3623ef8d945STudor Ambarus 
363db57656bSHoria Geantă 	if (!ctx->cdata.keylen || !ctx->authsize)
3643ef8d945STudor Ambarus 		return 0;
3653ef8d945STudor Ambarus 
3663ef8d945STudor Ambarus 	/*
3673ef8d945STudor Ambarus 	 * AES GCM encrypt shared descriptor
3683ef8d945STudor Ambarus 	 * Job Descriptor and Shared Descriptor
3693ef8d945STudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
3703ef8d945STudor Ambarus 	 */
3714cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_GCM_ENC_LEN) {
372db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
3739c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
374db57656bSHoria Geantă 	} else {
375db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
3769c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
377db57656bSHoria Geantă 	}
3783ef8d945STudor Ambarus 
3793ef8d945STudor Ambarus 	desc = ctx->sh_desc_enc;
3808cea7b66SHoria Geantă 	cnstr_shdsc_gcm_encap(desc, &ctx->cdata, ctx->authsize);
381bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
382bbf22344SHoria Geantă 				   desc_bytes(desc), DMA_TO_DEVICE);
3833ef8d945STudor Ambarus 
3843ef8d945STudor Ambarus 	/*
3853ef8d945STudor Ambarus 	 * Job Descriptor and Shared Descriptors
3863ef8d945STudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
3873ef8d945STudor Ambarus 	 */
3884cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_GCM_DEC_LEN) {
389db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
3909c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
391db57656bSHoria Geantă 	} else {
392db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
3939c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
394db57656bSHoria Geantă 	}
3953ef8d945STudor Ambarus 
3963ef8d945STudor Ambarus 	desc = ctx->sh_desc_dec;
3978cea7b66SHoria Geantă 	cnstr_shdsc_gcm_decap(desc, &ctx->cdata, ctx->authsize);
398bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
399bbf22344SHoria Geantă 				   desc_bytes(desc), DMA_TO_DEVICE);
4003ef8d945STudor Ambarus 
4013ef8d945STudor Ambarus 	return 0;
4023ef8d945STudor Ambarus }
4033ef8d945STudor Ambarus 
4043ef8d945STudor Ambarus static int gcm_setauthsize(struct crypto_aead *authenc, unsigned int authsize)
4053ef8d945STudor Ambarus {
4063ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
4073ef8d945STudor Ambarus 
4083ef8d945STudor Ambarus 	ctx->authsize = authsize;
4093ef8d945STudor Ambarus 	gcm_set_sh_desc(authenc);
4103ef8d945STudor Ambarus 
4113ef8d945STudor Ambarus 	return 0;
4123ef8d945STudor Ambarus }
4133ef8d945STudor Ambarus 
414bac68f2cSTudor Ambarus static int rfc4106_set_sh_desc(struct crypto_aead *aead)
415bac68f2cSTudor Ambarus {
416bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
417bac68f2cSTudor Ambarus 	struct device *jrdev = ctx->jrdev;
418bac68f2cSTudor Ambarus 	u32 *desc;
4194cbe79ccSHoria Geantă 	int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
4204cbe79ccSHoria Geantă 			ctx->cdata.keylen;
421bac68f2cSTudor Ambarus 
422db57656bSHoria Geantă 	if (!ctx->cdata.keylen || !ctx->authsize)
423bac68f2cSTudor Ambarus 		return 0;
424bac68f2cSTudor Ambarus 
425bac68f2cSTudor Ambarus 	/*
426bac68f2cSTudor Ambarus 	 * RFC4106 encrypt shared descriptor
427bac68f2cSTudor Ambarus 	 * Job Descriptor and Shared Descriptor
428bac68f2cSTudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
429bac68f2cSTudor Ambarus 	 */
4304cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_RFC4106_ENC_LEN) {
431db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
4329c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
433db57656bSHoria Geantă 	} else {
434db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
4359c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
436db57656bSHoria Geantă 	}
437bac68f2cSTudor Ambarus 
438bac68f2cSTudor Ambarus 	desc = ctx->sh_desc_enc;
4398cea7b66SHoria Geantă 	cnstr_shdsc_rfc4106_encap(desc, &ctx->cdata, ctx->authsize);
440bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
441bbf22344SHoria Geantă 				   desc_bytes(desc), DMA_TO_DEVICE);
442bac68f2cSTudor Ambarus 
443bac68f2cSTudor Ambarus 	/*
444bac68f2cSTudor Ambarus 	 * Job Descriptor and Shared Descriptors
445bac68f2cSTudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
446bac68f2cSTudor Ambarus 	 */
4474cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_RFC4106_DEC_LEN) {
448db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
4499c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
450db57656bSHoria Geantă 	} else {
451db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
4529c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
453db57656bSHoria Geantă 	}
454bac68f2cSTudor Ambarus 
455bac68f2cSTudor Ambarus 	desc = ctx->sh_desc_dec;
4568cea7b66SHoria Geantă 	cnstr_shdsc_rfc4106_decap(desc, &ctx->cdata, ctx->authsize);
457bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
458bbf22344SHoria Geantă 				   desc_bytes(desc), DMA_TO_DEVICE);
459bac68f2cSTudor Ambarus 
460bac68f2cSTudor Ambarus 	return 0;
461bac68f2cSTudor Ambarus }
462bac68f2cSTudor Ambarus 
463bac68f2cSTudor Ambarus static int rfc4106_setauthsize(struct crypto_aead *authenc,
464bac68f2cSTudor Ambarus 			       unsigned int authsize)
465bac68f2cSTudor Ambarus {
466bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
467bac68f2cSTudor Ambarus 
468bac68f2cSTudor Ambarus 	ctx->authsize = authsize;
469bac68f2cSTudor Ambarus 	rfc4106_set_sh_desc(authenc);
470bac68f2cSTudor Ambarus 
471bac68f2cSTudor Ambarus 	return 0;
472bac68f2cSTudor Ambarus }
473bac68f2cSTudor Ambarus 
4745d0429a3STudor Ambarus static int rfc4543_set_sh_desc(struct crypto_aead *aead)
4755d0429a3STudor Ambarus {
4765d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
4775d0429a3STudor Ambarus 	struct device *jrdev = ctx->jrdev;
4785d0429a3STudor Ambarus 	u32 *desc;
4794cbe79ccSHoria Geantă 	int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
4804cbe79ccSHoria Geantă 			ctx->cdata.keylen;
4815d0429a3STudor Ambarus 
482db57656bSHoria Geantă 	if (!ctx->cdata.keylen || !ctx->authsize)
4835d0429a3STudor Ambarus 		return 0;
4845d0429a3STudor Ambarus 
4855d0429a3STudor Ambarus 	/*
4865d0429a3STudor Ambarus 	 * RFC4543 encrypt shared descriptor
4875d0429a3STudor Ambarus 	 * Job Descriptor and Shared Descriptor
4885d0429a3STudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
4895d0429a3STudor Ambarus 	 */
4904cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_RFC4543_ENC_LEN) {
491db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
4929c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
493db57656bSHoria Geantă 	} else {
494db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
4959c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
496db57656bSHoria Geantă 	}
4975d0429a3STudor Ambarus 
4985d0429a3STudor Ambarus 	desc = ctx->sh_desc_enc;
4998cea7b66SHoria Geantă 	cnstr_shdsc_rfc4543_encap(desc, &ctx->cdata, ctx->authsize);
500bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
501bbf22344SHoria Geantă 				   desc_bytes(desc), DMA_TO_DEVICE);
5025d0429a3STudor Ambarus 
5035d0429a3STudor Ambarus 	/*
5045d0429a3STudor Ambarus 	 * Job Descriptor and Shared Descriptors
5055d0429a3STudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
5065d0429a3STudor Ambarus 	 */
5074cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_RFC4543_DEC_LEN) {
508db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
5099c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
510db57656bSHoria Geantă 	} else {
511db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
5129c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
513db57656bSHoria Geantă 	}
5145d0429a3STudor Ambarus 
5155d0429a3STudor Ambarus 	desc = ctx->sh_desc_dec;
5168cea7b66SHoria Geantă 	cnstr_shdsc_rfc4543_decap(desc, &ctx->cdata, ctx->authsize);
517bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
518bbf22344SHoria Geantă 				   desc_bytes(desc), DMA_TO_DEVICE);
5195d0429a3STudor Ambarus 
5205d0429a3STudor Ambarus 	return 0;
5215d0429a3STudor Ambarus }
5225d0429a3STudor Ambarus 
5235d0429a3STudor Ambarus static int rfc4543_setauthsize(struct crypto_aead *authenc,
5245d0429a3STudor Ambarus 			       unsigned int authsize)
5255d0429a3STudor Ambarus {
5265d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
5275d0429a3STudor Ambarus 
5285d0429a3STudor Ambarus 	ctx->authsize = authsize;
5295d0429a3STudor Ambarus 	rfc4543_set_sh_desc(authenc);
5305d0429a3STudor Ambarus 
5315d0429a3STudor Ambarus 	return 0;
5325d0429a3STudor Ambarus }
5335d0429a3STudor Ambarus 
5340e479300SYuan Kang static int aead_setkey(struct crypto_aead *aead,
5358e8ec596SKim Phillips 			       const u8 *key, unsigned int keylen)
5368e8ec596SKim Phillips {
5378e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
5388e8ec596SKim Phillips 	struct device *jrdev = ctx->jrdev;
5394e6e0b27SHoria Geanta 	struct crypto_authenc_keys keys;
5408e8ec596SKim Phillips 	int ret = 0;
5418e8ec596SKim Phillips 
5424e6e0b27SHoria Geanta 	if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
5438e8ec596SKim Phillips 		goto badkey;
5448e8ec596SKim Phillips 
5458e8ec596SKim Phillips #ifdef DEBUG
5468e8ec596SKim Phillips 	printk(KERN_ERR "keylen %d enckeylen %d authkeylen %d\n",
5474e6e0b27SHoria Geanta 	       keys.authkeylen + keys.enckeylen, keys.enckeylen,
5484e6e0b27SHoria Geanta 	       keys.authkeylen);
549514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
5508e8ec596SKim Phillips 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
5518e8ec596SKim Phillips #endif
5528e8ec596SKim Phillips 
5536655cb8eSHoria Geantă 	ret = gen_split_key(ctx->jrdev, ctx->key, &ctx->adata, keys.authkey,
5546655cb8eSHoria Geantă 			    keys.authkeylen, CAAM_MAX_KEY_SIZE -
5556655cb8eSHoria Geantă 			    keys.enckeylen);
5568e8ec596SKim Phillips 	if (ret) {
5578e8ec596SKim Phillips 		goto badkey;
5588e8ec596SKim Phillips 	}
5598e8ec596SKim Phillips 
5608e8ec596SKim Phillips 	/* postpend encryption key to auth split key */
561db57656bSHoria Geantă 	memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen);
562bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->adata.keylen_pad +
5634e6e0b27SHoria Geanta 				   keys.enckeylen, DMA_TO_DEVICE);
5648e8ec596SKim Phillips #ifdef DEBUG
565514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ctx.key@"__stringify(__LINE__)": ",
5668e8ec596SKim Phillips 		       DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
567db57656bSHoria Geantă 		       ctx->adata.keylen_pad + keys.enckeylen, 1);
5688e8ec596SKim Phillips #endif
569db57656bSHoria Geantă 	ctx->cdata.keylen = keys.enckeylen;
570bbf22344SHoria Geantă 	return aead_set_sh_desc(aead);
5718e8ec596SKim Phillips badkey:
5728e8ec596SKim Phillips 	crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
5738e8ec596SKim Phillips 	return -EINVAL;
5748e8ec596SKim Phillips }
5758e8ec596SKim Phillips 
5763ef8d945STudor Ambarus static int gcm_setkey(struct crypto_aead *aead,
5773ef8d945STudor Ambarus 		      const u8 *key, unsigned int keylen)
5783ef8d945STudor Ambarus {
5793ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
5803ef8d945STudor Ambarus 	struct device *jrdev = ctx->jrdev;
5813ef8d945STudor Ambarus 
5823ef8d945STudor Ambarus #ifdef DEBUG
5833ef8d945STudor Ambarus 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
5843ef8d945STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
5853ef8d945STudor Ambarus #endif
5863ef8d945STudor Ambarus 
5873ef8d945STudor Ambarus 	memcpy(ctx->key, key, keylen);
588bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, DMA_TO_DEVICE);
589db57656bSHoria Geantă 	ctx->cdata.keylen = keylen;
5903ef8d945STudor Ambarus 
591bbf22344SHoria Geantă 	return gcm_set_sh_desc(aead);
5923ef8d945STudor Ambarus }
5933ef8d945STudor Ambarus 
594bac68f2cSTudor Ambarus static int rfc4106_setkey(struct crypto_aead *aead,
595bac68f2cSTudor Ambarus 			  const u8 *key, unsigned int keylen)
596bac68f2cSTudor Ambarus {
597bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
598bac68f2cSTudor Ambarus 	struct device *jrdev = ctx->jrdev;
599bac68f2cSTudor Ambarus 
600bac68f2cSTudor Ambarus 	if (keylen < 4)
601bac68f2cSTudor Ambarus 		return -EINVAL;
602bac68f2cSTudor Ambarus 
603bac68f2cSTudor Ambarus #ifdef DEBUG
604bac68f2cSTudor Ambarus 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
605bac68f2cSTudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
606bac68f2cSTudor Ambarus #endif
607bac68f2cSTudor Ambarus 
608bac68f2cSTudor Ambarus 	memcpy(ctx->key, key, keylen);
609bac68f2cSTudor Ambarus 
610bac68f2cSTudor Ambarus 	/*
611bac68f2cSTudor Ambarus 	 * The last four bytes of the key material are used as the salt value
612bac68f2cSTudor Ambarus 	 * in the nonce. Update the AES key length.
613bac68f2cSTudor Ambarus 	 */
614db57656bSHoria Geantă 	ctx->cdata.keylen = keylen - 4;
615bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
616bac68f2cSTudor Ambarus 				   DMA_TO_DEVICE);
617bbf22344SHoria Geantă 	return rfc4106_set_sh_desc(aead);
618bac68f2cSTudor Ambarus }
619bac68f2cSTudor Ambarus 
6205d0429a3STudor Ambarus static int rfc4543_setkey(struct crypto_aead *aead,
6215d0429a3STudor Ambarus 			  const u8 *key, unsigned int keylen)
6225d0429a3STudor Ambarus {
6235d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
6245d0429a3STudor Ambarus 	struct device *jrdev = ctx->jrdev;
6255d0429a3STudor Ambarus 
6265d0429a3STudor Ambarus 	if (keylen < 4)
6275d0429a3STudor Ambarus 		return -EINVAL;
6285d0429a3STudor Ambarus 
6295d0429a3STudor Ambarus #ifdef DEBUG
6305d0429a3STudor Ambarus 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
6315d0429a3STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
6325d0429a3STudor Ambarus #endif
6335d0429a3STudor Ambarus 
6345d0429a3STudor Ambarus 	memcpy(ctx->key, key, keylen);
6355d0429a3STudor Ambarus 
6365d0429a3STudor Ambarus 	/*
6375d0429a3STudor Ambarus 	 * The last four bytes of the key material are used as the salt value
6385d0429a3STudor Ambarus 	 * in the nonce. Update the AES key length.
6395d0429a3STudor Ambarus 	 */
640db57656bSHoria Geantă 	ctx->cdata.keylen = keylen - 4;
641bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
6425d0429a3STudor Ambarus 				   DMA_TO_DEVICE);
643bbf22344SHoria Geantă 	return rfc4543_set_sh_desc(aead);
6445d0429a3STudor Ambarus }
6455d0429a3STudor Ambarus 
646acdca31dSYuan Kang static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
647acdca31dSYuan Kang 			     const u8 *key, unsigned int keylen)
648acdca31dSYuan Kang {
649acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
650a5f57cffSCatalin Vasile 	struct crypto_tfm *tfm = crypto_ablkcipher_tfm(ablkcipher);
651a5f57cffSCatalin Vasile 	const char *alg_name = crypto_tfm_alg_name(tfm);
652acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
6538cea7b66SHoria Geantă 	unsigned int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
654acdca31dSYuan Kang 	u32 *desc;
6552b22f6c5SCatalin Vasile 	u32 ctx1_iv_off = 0;
656db57656bSHoria Geantă 	const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
6572b22f6c5SCatalin Vasile 			       OP_ALG_AAI_CTR_MOD128);
658a5f57cffSCatalin Vasile 	const bool is_rfc3686 = (ctr_mode &&
659a5f57cffSCatalin Vasile 				 (strstr(alg_name, "rfc3686") != NULL));
660acdca31dSYuan Kang 
6618cea7b66SHoria Geantă 	memcpy(ctx->key, key, keylen);
662acdca31dSYuan Kang #ifdef DEBUG
663514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
664acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
665acdca31dSYuan Kang #endif
6662b22f6c5SCatalin Vasile 	/*
6672b22f6c5SCatalin Vasile 	 * AES-CTR needs to load IV in CONTEXT1 reg
6682b22f6c5SCatalin Vasile 	 * at an offset of 128bits (16bytes)
6692b22f6c5SCatalin Vasile 	 * CONTEXT1[255:128] = IV
6702b22f6c5SCatalin Vasile 	 */
6712b22f6c5SCatalin Vasile 	if (ctr_mode)
6722b22f6c5SCatalin Vasile 		ctx1_iv_off = 16;
673acdca31dSYuan Kang 
674a5f57cffSCatalin Vasile 	/*
675a5f57cffSCatalin Vasile 	 * RFC3686 specific:
676a5f57cffSCatalin Vasile 	 *	| CONTEXT1[255:128] = {NONCE, IV, COUNTER}
677a5f57cffSCatalin Vasile 	 *	| *key = {KEY, NONCE}
678a5f57cffSCatalin Vasile 	 */
679a5f57cffSCatalin Vasile 	if (is_rfc3686) {
680a5f57cffSCatalin Vasile 		ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
681a5f57cffSCatalin Vasile 		keylen -= CTR_RFC3686_NONCE_SIZE;
682a5f57cffSCatalin Vasile 	}
683a5f57cffSCatalin Vasile 
684bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, DMA_TO_DEVICE);
685db57656bSHoria Geantă 	ctx->cdata.keylen = keylen;
6869c0bc511SArnd Bergmann 	ctx->cdata.key_virt = ctx->key;
687db57656bSHoria Geantă 	ctx->cdata.key_inline = true;
688acdca31dSYuan Kang 
689acdca31dSYuan Kang 	/* ablkcipher_encrypt shared descriptor */
690acdca31dSYuan Kang 	desc = ctx->sh_desc_enc;
6918cea7b66SHoria Geantă 	cnstr_shdsc_ablkcipher_encap(desc, &ctx->cdata, ivsize, is_rfc3686,
6928cea7b66SHoria Geantă 				     ctx1_iv_off);
693bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
694bbf22344SHoria Geantă 				   desc_bytes(desc), DMA_TO_DEVICE);
6958cea7b66SHoria Geantă 
696acdca31dSYuan Kang 	/* ablkcipher_decrypt shared descriptor */
697acdca31dSYuan Kang 	desc = ctx->sh_desc_dec;
6988cea7b66SHoria Geantă 	cnstr_shdsc_ablkcipher_decap(desc, &ctx->cdata, ivsize, is_rfc3686,
6998cea7b66SHoria Geantă 				     ctx1_iv_off);
700bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
701bbf22344SHoria Geantă 				   desc_bytes(desc), DMA_TO_DEVICE);
702acdca31dSYuan Kang 
7037222d1a3SCatalin Vasile 	/* ablkcipher_givencrypt shared descriptor */
7047222d1a3SCatalin Vasile 	desc = ctx->sh_desc_givenc;
7058cea7b66SHoria Geantă 	cnstr_shdsc_ablkcipher_givencap(desc, &ctx->cdata, ivsize, is_rfc3686,
7068cea7b66SHoria Geantă 					ctx1_iv_off);
707bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_givenc_dma,
708bbf22344SHoria Geantă 				   desc_bytes(desc), DMA_TO_DEVICE);
709acdca31dSYuan Kang 
7108cea7b66SHoria Geantă 	return 0;
711acdca31dSYuan Kang }
712acdca31dSYuan Kang 
713c6415a60SCatalin Vasile static int xts_ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
714c6415a60SCatalin Vasile 				 const u8 *key, unsigned int keylen)
715c6415a60SCatalin Vasile {
716c6415a60SCatalin Vasile 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
717c6415a60SCatalin Vasile 	struct device *jrdev = ctx->jrdev;
7188cea7b66SHoria Geantă 	u32 *desc;
719c6415a60SCatalin Vasile 
720c6415a60SCatalin Vasile 	if (keylen != 2 * AES_MIN_KEY_SIZE  && keylen != 2 * AES_MAX_KEY_SIZE) {
721c6415a60SCatalin Vasile 		crypto_ablkcipher_set_flags(ablkcipher,
722c6415a60SCatalin Vasile 					    CRYPTO_TFM_RES_BAD_KEY_LEN);
723c6415a60SCatalin Vasile 		dev_err(jrdev, "key size mismatch\n");
724c6415a60SCatalin Vasile 		return -EINVAL;
725c6415a60SCatalin Vasile 	}
726c6415a60SCatalin Vasile 
727c6415a60SCatalin Vasile 	memcpy(ctx->key, key, keylen);
728bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, DMA_TO_DEVICE);
729db57656bSHoria Geantă 	ctx->cdata.keylen = keylen;
7309c0bc511SArnd Bergmann 	ctx->cdata.key_virt = ctx->key;
731db57656bSHoria Geantă 	ctx->cdata.key_inline = true;
732c6415a60SCatalin Vasile 
733c6415a60SCatalin Vasile 	/* xts_ablkcipher_encrypt shared descriptor */
734c6415a60SCatalin Vasile 	desc = ctx->sh_desc_enc;
7358cea7b66SHoria Geantă 	cnstr_shdsc_xts_ablkcipher_encap(desc, &ctx->cdata);
736bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
737bbf22344SHoria Geantă 				   desc_bytes(desc), DMA_TO_DEVICE);
738c6415a60SCatalin Vasile 
739c6415a60SCatalin Vasile 	/* xts_ablkcipher_decrypt shared descriptor */
740c6415a60SCatalin Vasile 	desc = ctx->sh_desc_dec;
7418cea7b66SHoria Geantă 	cnstr_shdsc_xts_ablkcipher_decap(desc, &ctx->cdata);
742bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
743bbf22344SHoria Geantă 				   desc_bytes(desc), DMA_TO_DEVICE);
744c6415a60SCatalin Vasile 
745c6415a60SCatalin Vasile 	return 0;
746c6415a60SCatalin Vasile }
747c6415a60SCatalin Vasile 
7488e8ec596SKim Phillips /*
7491acebad3SYuan Kang  * aead_edesc - s/w-extended aead descriptor
750fa0c92dbSHoria Geantă  * @src_nents: number of segments in input s/w scatterlist
751fa0c92dbSHoria Geantă  * @dst_nents: number of segments in output s/w scatterlist
752a299c837SYuan Kang  * @sec4_sg_bytes: length of dma mapped sec4_sg space
753a299c837SYuan Kang  * @sec4_sg_dma: bus physical mapped address of h/w link table
7544ca7c7d8SHoria Geantă  * @sec4_sg: pointer to h/w link table
7558e8ec596SKim Phillips  * @hw_desc: the h/w job descriptor followed by any referenced link tables
7568e8ec596SKim Phillips  */
7570e479300SYuan Kang struct aead_edesc {
7588e8ec596SKim Phillips 	int src_nents;
7598e8ec596SKim Phillips 	int dst_nents;
760a299c837SYuan Kang 	int sec4_sg_bytes;
761a299c837SYuan Kang 	dma_addr_t sec4_sg_dma;
762a299c837SYuan Kang 	struct sec4_sg_entry *sec4_sg;
763f2147b88SHerbert Xu 	u32 hw_desc[];
7648e8ec596SKim Phillips };
7658e8ec596SKim Phillips 
766acdca31dSYuan Kang /*
767acdca31dSYuan Kang  * ablkcipher_edesc - s/w-extended ablkcipher descriptor
768fa0c92dbSHoria Geantă  * @src_nents: number of segments in input s/w scatterlist
769fa0c92dbSHoria Geantă  * @dst_nents: number of segments in output s/w scatterlist
770acdca31dSYuan Kang  * @iv_dma: dma address of iv for checking continuity and link table
771a299c837SYuan Kang  * @sec4_sg_bytes: length of dma mapped sec4_sg space
772a299c837SYuan Kang  * @sec4_sg_dma: bus physical mapped address of h/w link table
7734ca7c7d8SHoria Geantă  * @sec4_sg: pointer to h/w link table
774acdca31dSYuan Kang  * @hw_desc: the h/w job descriptor followed by any referenced link tables
775acdca31dSYuan Kang  */
776acdca31dSYuan Kang struct ablkcipher_edesc {
777acdca31dSYuan Kang 	int src_nents;
778acdca31dSYuan Kang 	int dst_nents;
779acdca31dSYuan Kang 	dma_addr_t iv_dma;
780a299c837SYuan Kang 	int sec4_sg_bytes;
781a299c837SYuan Kang 	dma_addr_t sec4_sg_dma;
782a299c837SYuan Kang 	struct sec4_sg_entry *sec4_sg;
783acdca31dSYuan Kang 	u32 hw_desc[0];
784acdca31dSYuan Kang };
785acdca31dSYuan Kang 
7861acebad3SYuan Kang static void caam_unmap(struct device *dev, struct scatterlist *src,
787643b39b0SYuan Kang 		       struct scatterlist *dst, int src_nents,
78813fb8fd7SLABBE Corentin 		       int dst_nents,
789a299c837SYuan Kang 		       dma_addr_t iv_dma, int ivsize, dma_addr_t sec4_sg_dma,
790a299c837SYuan Kang 		       int sec4_sg_bytes)
7911acebad3SYuan Kang {
792643b39b0SYuan Kang 	if (dst != src) {
793fa0c92dbSHoria Geantă 		if (src_nents)
794fa0c92dbSHoria Geantă 			dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
795fa0c92dbSHoria Geantă 		dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
7961acebad3SYuan Kang 	} else {
797fa0c92dbSHoria Geantă 		dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
7981acebad3SYuan Kang 	}
7991acebad3SYuan Kang 
8001acebad3SYuan Kang 	if (iv_dma)
8011acebad3SYuan Kang 		dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);
802a299c837SYuan Kang 	if (sec4_sg_bytes)
803a299c837SYuan Kang 		dma_unmap_single(dev, sec4_sg_dma, sec4_sg_bytes,
8041acebad3SYuan Kang 				 DMA_TO_DEVICE);
8051acebad3SYuan Kang }
8061acebad3SYuan Kang 
8070e479300SYuan Kang static void aead_unmap(struct device *dev,
8080e479300SYuan Kang 		       struct aead_edesc *edesc,
8090e479300SYuan Kang 		       struct aead_request *req)
8108e8ec596SKim Phillips {
811f2147b88SHerbert Xu 	caam_unmap(dev, req->src, req->dst,
81213fb8fd7SLABBE Corentin 		   edesc->src_nents, edesc->dst_nents, 0, 0,
813f2147b88SHerbert Xu 		   edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
814f2147b88SHerbert Xu }
815f2147b88SHerbert Xu 
816acdca31dSYuan Kang static void ablkcipher_unmap(struct device *dev,
817acdca31dSYuan Kang 			     struct ablkcipher_edesc *edesc,
818acdca31dSYuan Kang 			     struct ablkcipher_request *req)
819acdca31dSYuan Kang {
820acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
821acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
822acdca31dSYuan Kang 
823acdca31dSYuan Kang 	caam_unmap(dev, req->src, req->dst,
82413fb8fd7SLABBE Corentin 		   edesc->src_nents, edesc->dst_nents,
82513fb8fd7SLABBE Corentin 		   edesc->iv_dma, ivsize,
826643b39b0SYuan Kang 		   edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
827acdca31dSYuan Kang }
828acdca31dSYuan Kang 
8290e479300SYuan Kang static void aead_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
8308e8ec596SKim Phillips 				   void *context)
8318e8ec596SKim Phillips {
8320e479300SYuan Kang 	struct aead_request *req = context;
8330e479300SYuan Kang 	struct aead_edesc *edesc;
834f2147b88SHerbert Xu 
835f2147b88SHerbert Xu #ifdef DEBUG
836f2147b88SHerbert Xu 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
837f2147b88SHerbert Xu #endif
838f2147b88SHerbert Xu 
839f2147b88SHerbert Xu 	edesc = container_of(desc, struct aead_edesc, hw_desc[0]);
840f2147b88SHerbert Xu 
841f2147b88SHerbert Xu 	if (err)
842f2147b88SHerbert Xu 		caam_jr_strstatus(jrdev, err);
843f2147b88SHerbert Xu 
844f2147b88SHerbert Xu 	aead_unmap(jrdev, edesc, req);
845f2147b88SHerbert Xu 
846f2147b88SHerbert Xu 	kfree(edesc);
847f2147b88SHerbert Xu 
848f2147b88SHerbert Xu 	aead_request_complete(req, err);
849f2147b88SHerbert Xu }
850f2147b88SHerbert Xu 
8510e479300SYuan Kang static void aead_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
8528e8ec596SKim Phillips 				   void *context)
8538e8ec596SKim Phillips {
8540e479300SYuan Kang 	struct aead_request *req = context;
8550e479300SYuan Kang 	struct aead_edesc *edesc;
856f2147b88SHerbert Xu 
857f2147b88SHerbert Xu #ifdef DEBUG
858f2147b88SHerbert Xu 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
859f2147b88SHerbert Xu #endif
860f2147b88SHerbert Xu 
861f2147b88SHerbert Xu 	edesc = container_of(desc, struct aead_edesc, hw_desc[0]);
862f2147b88SHerbert Xu 
863f2147b88SHerbert Xu 	if (err)
864f2147b88SHerbert Xu 		caam_jr_strstatus(jrdev, err);
865f2147b88SHerbert Xu 
866f2147b88SHerbert Xu 	aead_unmap(jrdev, edesc, req);
867f2147b88SHerbert Xu 
868f2147b88SHerbert Xu 	/*
869f2147b88SHerbert Xu 	 * verify hw auth check passed else return -EBADMSG
870f2147b88SHerbert Xu 	 */
871f2147b88SHerbert Xu 	if ((err & JRSTA_CCBERR_ERRID_MASK) == JRSTA_CCBERR_ERRID_ICVCHK)
872f2147b88SHerbert Xu 		err = -EBADMSG;
873f2147b88SHerbert Xu 
874f2147b88SHerbert Xu 	kfree(edesc);
875f2147b88SHerbert Xu 
876f2147b88SHerbert Xu 	aead_request_complete(req, err);
877f2147b88SHerbert Xu }
878f2147b88SHerbert Xu 
879acdca31dSYuan Kang static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
880acdca31dSYuan Kang 				   void *context)
881acdca31dSYuan Kang {
882acdca31dSYuan Kang 	struct ablkcipher_request *req = context;
883acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
884acdca31dSYuan Kang #ifdef DEBUG
885acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
886acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
887acdca31dSYuan Kang 
888acdca31dSYuan Kang 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
889acdca31dSYuan Kang #endif
890acdca31dSYuan Kang 
8914ca7c7d8SHoria Geantă 	edesc = container_of(desc, struct ablkcipher_edesc, hw_desc[0]);
892acdca31dSYuan Kang 
893fa9659cdSMarek Vasut 	if (err)
894fa9659cdSMarek Vasut 		caam_jr_strstatus(jrdev, err);
895acdca31dSYuan Kang 
896acdca31dSYuan Kang #ifdef DEBUG
897514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dstiv  @"__stringify(__LINE__)": ",
898acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
899acdca31dSYuan Kang 		       edesc->src_nents > 1 ? 100 : ivsize, 1);
9005ecf8ef9SCatalin Vasile 	dbg_dump_sg(KERN_ERR, "dst    @"__stringify(__LINE__)": ",
9015ecf8ef9SCatalin Vasile 		    DUMP_PREFIX_ADDRESS, 16, 4, req->dst,
90200fef2b2SHoria Geantă 		    edesc->dst_nents > 1 ? 100 : req->nbytes, 1);
903acdca31dSYuan Kang #endif
904acdca31dSYuan Kang 
905acdca31dSYuan Kang 	ablkcipher_unmap(jrdev, edesc, req);
906acdca31dSYuan Kang 	kfree(edesc);
907acdca31dSYuan Kang 
908acdca31dSYuan Kang 	ablkcipher_request_complete(req, err);
909acdca31dSYuan Kang }
910acdca31dSYuan Kang 
911acdca31dSYuan Kang static void ablkcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
912acdca31dSYuan Kang 				    void *context)
913acdca31dSYuan Kang {
914acdca31dSYuan Kang 	struct ablkcipher_request *req = context;
915acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
916acdca31dSYuan Kang #ifdef DEBUG
917acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
918acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
919acdca31dSYuan Kang 
920acdca31dSYuan Kang 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
921acdca31dSYuan Kang #endif
922acdca31dSYuan Kang 
9234ca7c7d8SHoria Geantă 	edesc = container_of(desc, struct ablkcipher_edesc, hw_desc[0]);
924fa9659cdSMarek Vasut 	if (err)
925fa9659cdSMarek Vasut 		caam_jr_strstatus(jrdev, err);
926acdca31dSYuan Kang 
927acdca31dSYuan Kang #ifdef DEBUG
928514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dstiv  @"__stringify(__LINE__)": ",
929acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
930acdca31dSYuan Kang 		       ivsize, 1);
9315ecf8ef9SCatalin Vasile 	dbg_dump_sg(KERN_ERR, "dst    @"__stringify(__LINE__)": ",
9325ecf8ef9SCatalin Vasile 		    DUMP_PREFIX_ADDRESS, 16, 4, req->dst,
93300fef2b2SHoria Geantă 		    edesc->dst_nents > 1 ? 100 : req->nbytes, 1);
934acdca31dSYuan Kang #endif
935acdca31dSYuan Kang 
936acdca31dSYuan Kang 	ablkcipher_unmap(jrdev, edesc, req);
937acdca31dSYuan Kang 	kfree(edesc);
938acdca31dSYuan Kang 
939acdca31dSYuan Kang 	ablkcipher_request_complete(req, err);
940acdca31dSYuan Kang }
941acdca31dSYuan Kang 
9428e8ec596SKim Phillips /*
9431acebad3SYuan Kang  * Fill in aead job descriptor
9448e8ec596SKim Phillips  */
945f2147b88SHerbert Xu static void init_aead_job(struct aead_request *req,
946f2147b88SHerbert Xu 			  struct aead_edesc *edesc,
947f2147b88SHerbert Xu 			  bool all_contig, bool encrypt)
948f2147b88SHerbert Xu {
949f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
950f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
951f2147b88SHerbert Xu 	int authsize = ctx->authsize;
952f2147b88SHerbert Xu 	u32 *desc = edesc->hw_desc;
953f2147b88SHerbert Xu 	u32 out_options, in_options;
954f2147b88SHerbert Xu 	dma_addr_t dst_dma, src_dma;
955f2147b88SHerbert Xu 	int len, sec4_sg_index = 0;
956f2147b88SHerbert Xu 	dma_addr_t ptr;
957f2147b88SHerbert Xu 	u32 *sh_desc;
958f2147b88SHerbert Xu 
959f2147b88SHerbert Xu 	sh_desc = encrypt ? ctx->sh_desc_enc : ctx->sh_desc_dec;
960f2147b88SHerbert Xu 	ptr = encrypt ? ctx->sh_desc_enc_dma : ctx->sh_desc_dec_dma;
961f2147b88SHerbert Xu 
962f2147b88SHerbert Xu 	len = desc_len(sh_desc);
963f2147b88SHerbert Xu 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
964f2147b88SHerbert Xu 
965f2147b88SHerbert Xu 	if (all_contig) {
966fa0c92dbSHoria Geantă 		src_dma = edesc->src_nents ? sg_dma_address(req->src) : 0;
967f2147b88SHerbert Xu 		in_options = 0;
968f2147b88SHerbert Xu 	} else {
969f2147b88SHerbert Xu 		src_dma = edesc->sec4_sg_dma;
970f2147b88SHerbert Xu 		sec4_sg_index += edesc->src_nents;
971f2147b88SHerbert Xu 		in_options = LDST_SGF;
972f2147b88SHerbert Xu 	}
973f2147b88SHerbert Xu 
974f2147b88SHerbert Xu 	append_seq_in_ptr(desc, src_dma, req->assoclen + req->cryptlen,
975f2147b88SHerbert Xu 			  in_options);
976f2147b88SHerbert Xu 
977f2147b88SHerbert Xu 	dst_dma = src_dma;
978f2147b88SHerbert Xu 	out_options = in_options;
979f2147b88SHerbert Xu 
980f2147b88SHerbert Xu 	if (unlikely(req->src != req->dst)) {
981fa0c92dbSHoria Geantă 		if (edesc->dst_nents == 1) {
982f2147b88SHerbert Xu 			dst_dma = sg_dma_address(req->dst);
983f2147b88SHerbert Xu 		} else {
984f2147b88SHerbert Xu 			dst_dma = edesc->sec4_sg_dma +
985f2147b88SHerbert Xu 				  sec4_sg_index *
986f2147b88SHerbert Xu 				  sizeof(struct sec4_sg_entry);
987f2147b88SHerbert Xu 			out_options = LDST_SGF;
988f2147b88SHerbert Xu 		}
989f2147b88SHerbert Xu 	}
990f2147b88SHerbert Xu 
991f2147b88SHerbert Xu 	if (encrypt)
992f2147b88SHerbert Xu 		append_seq_out_ptr(desc, dst_dma,
993f2147b88SHerbert Xu 				   req->assoclen + req->cryptlen + authsize,
994f2147b88SHerbert Xu 				   out_options);
995f2147b88SHerbert Xu 	else
996f2147b88SHerbert Xu 		append_seq_out_ptr(desc, dst_dma,
997f2147b88SHerbert Xu 				   req->assoclen + req->cryptlen - authsize,
998f2147b88SHerbert Xu 				   out_options);
999f2147b88SHerbert Xu 
1000f2147b88SHerbert Xu 	/* REG3 = assoclen */
1001f2147b88SHerbert Xu 	append_math_add_imm_u32(desc, REG3, ZERO, IMM, req->assoclen);
1002f2147b88SHerbert Xu }
1003f2147b88SHerbert Xu 
1004f2147b88SHerbert Xu static void init_gcm_job(struct aead_request *req,
1005f2147b88SHerbert Xu 			 struct aead_edesc *edesc,
1006f2147b88SHerbert Xu 			 bool all_contig, bool encrypt)
1007f2147b88SHerbert Xu {
1008f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1009f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1010f2147b88SHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
1011f2147b88SHerbert Xu 	u32 *desc = edesc->hw_desc;
1012f2147b88SHerbert Xu 	bool generic_gcm = (ivsize == 12);
1013f2147b88SHerbert Xu 	unsigned int last;
1014f2147b88SHerbert Xu 
1015f2147b88SHerbert Xu 	init_aead_job(req, edesc, all_contig, encrypt);
1016f2147b88SHerbert Xu 
1017f2147b88SHerbert Xu 	/* BUG This should not be specific to generic GCM. */
1018f2147b88SHerbert Xu 	last = 0;
1019f2147b88SHerbert Xu 	if (encrypt && generic_gcm && !(req->assoclen + req->cryptlen))
1020f2147b88SHerbert Xu 		last = FIFOLD_TYPE_LAST1;
1021f2147b88SHerbert Xu 
1022f2147b88SHerbert Xu 	/* Read GCM IV */
1023f2147b88SHerbert Xu 	append_cmd(desc, CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 | IMMEDIATE |
1024f2147b88SHerbert Xu 			 FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 | 12 | last);
1025f2147b88SHerbert Xu 	/* Append Salt */
1026f2147b88SHerbert Xu 	if (!generic_gcm)
1027db57656bSHoria Geantă 		append_data(desc, ctx->key + ctx->cdata.keylen, 4);
1028f2147b88SHerbert Xu 	/* Append IV */
1029f2147b88SHerbert Xu 	append_data(desc, req->iv, ivsize);
1030f2147b88SHerbert Xu 	/* End of blank commands */
1031f2147b88SHerbert Xu }
1032f2147b88SHerbert Xu 
1033479bcc7cSHerbert Xu static void init_authenc_job(struct aead_request *req,
10341acebad3SYuan Kang 			     struct aead_edesc *edesc,
1035479bcc7cSHerbert Xu 			     bool all_contig, bool encrypt)
10361acebad3SYuan Kang {
10371acebad3SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1038479bcc7cSHerbert Xu 	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
1039479bcc7cSHerbert Xu 						 struct caam_aead_alg, aead);
1040479bcc7cSHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
10411acebad3SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1042db57656bSHoria Geantă 	const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
1043479bcc7cSHerbert Xu 			       OP_ALG_AAI_CTR_MOD128);
1044479bcc7cSHerbert Xu 	const bool is_rfc3686 = alg->caam.rfc3686;
10451acebad3SYuan Kang 	u32 *desc = edesc->hw_desc;
1046479bcc7cSHerbert Xu 	u32 ivoffset = 0;
10478e8ec596SKim Phillips 
1048479bcc7cSHerbert Xu 	/*
1049479bcc7cSHerbert Xu 	 * AES-CTR needs to load IV in CONTEXT1 reg
1050479bcc7cSHerbert Xu 	 * at an offset of 128bits (16bytes)
1051479bcc7cSHerbert Xu 	 * CONTEXT1[255:128] = IV
1052479bcc7cSHerbert Xu 	 */
1053479bcc7cSHerbert Xu 	if (ctr_mode)
1054479bcc7cSHerbert Xu 		ivoffset = 16;
10558e8ec596SKim Phillips 
1056479bcc7cSHerbert Xu 	/*
1057479bcc7cSHerbert Xu 	 * RFC3686 specific:
1058479bcc7cSHerbert Xu 	 *	CONTEXT1[255:128] = {NONCE, IV, COUNTER}
1059479bcc7cSHerbert Xu 	 */
1060479bcc7cSHerbert Xu 	if (is_rfc3686)
1061479bcc7cSHerbert Xu 		ivoffset = 16 + CTR_RFC3686_NONCE_SIZE;
1062bac68f2cSTudor Ambarus 
1063479bcc7cSHerbert Xu 	init_aead_job(req, edesc, all_contig, encrypt);
10641acebad3SYuan Kang 
10658b18e235SHoria Geantă 	if (ivsize && ((is_rfc3686 && encrypt) || !alg->caam.geniv))
1066479bcc7cSHerbert Xu 		append_load_as_imm(desc, req->iv, ivsize,
1067479bcc7cSHerbert Xu 				   LDST_CLASS_1_CCB |
1068479bcc7cSHerbert Xu 				   LDST_SRCDST_BYTE_CONTEXT |
1069479bcc7cSHerbert Xu 				   (ivoffset << LDST_OFFSET_SHIFT));
10708e8ec596SKim Phillips }
10718e8ec596SKim Phillips 
10728e8ec596SKim Phillips /*
1073acdca31dSYuan Kang  * Fill in ablkcipher job descriptor
1074acdca31dSYuan Kang  */
1075acdca31dSYuan Kang static void init_ablkcipher_job(u32 *sh_desc, dma_addr_t ptr,
1076acdca31dSYuan Kang 				struct ablkcipher_edesc *edesc,
1077acdca31dSYuan Kang 				struct ablkcipher_request *req,
1078acdca31dSYuan Kang 				bool iv_contig)
1079acdca31dSYuan Kang {
1080acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
1081acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
1082acdca31dSYuan Kang 	u32 *desc = edesc->hw_desc;
1083acdca31dSYuan Kang 	u32 out_options = 0, in_options;
1084acdca31dSYuan Kang 	dma_addr_t dst_dma, src_dma;
1085a299c837SYuan Kang 	int len, sec4_sg_index = 0;
1086acdca31dSYuan Kang 
1087acdca31dSYuan Kang #ifdef DEBUG
1088514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "presciv@"__stringify(__LINE__)": ",
1089acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
1090acdca31dSYuan Kang 		       ivsize, 1);
1091fa0c92dbSHoria Geantă 	pr_err("asked=%d, nbytes%d\n",
1092fa0c92dbSHoria Geantă 	       (int)edesc->src_nents > 1 ? 100 : req->nbytes, req->nbytes);
10935ecf8ef9SCatalin Vasile 	dbg_dump_sg(KERN_ERR, "src    @"__stringify(__LINE__)": ",
10945ecf8ef9SCatalin Vasile 		    DUMP_PREFIX_ADDRESS, 16, 4, req->src,
1095fa0c92dbSHoria Geantă 		    edesc->src_nents > 1 ? 100 : req->nbytes, 1);
1096acdca31dSYuan Kang #endif
1097acdca31dSYuan Kang 
1098acdca31dSYuan Kang 	len = desc_len(sh_desc);
1099acdca31dSYuan Kang 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
1100acdca31dSYuan Kang 
1101acdca31dSYuan Kang 	if (iv_contig) {
1102acdca31dSYuan Kang 		src_dma = edesc->iv_dma;
1103acdca31dSYuan Kang 		in_options = 0;
1104acdca31dSYuan Kang 	} else {
1105a299c837SYuan Kang 		src_dma = edesc->sec4_sg_dma;
110635b82e55SCristian Stoica 		sec4_sg_index += edesc->src_nents + 1;
1107acdca31dSYuan Kang 		in_options = LDST_SGF;
1108acdca31dSYuan Kang 	}
1109acdca31dSYuan Kang 	append_seq_in_ptr(desc, src_dma, req->nbytes + ivsize, in_options);
1110acdca31dSYuan Kang 
1111acdca31dSYuan Kang 	if (likely(req->src == req->dst)) {
1112fa0c92dbSHoria Geantă 		if (edesc->src_nents == 1 && iv_contig) {
1113acdca31dSYuan Kang 			dst_dma = sg_dma_address(req->src);
1114acdca31dSYuan Kang 		} else {
1115a299c837SYuan Kang 			dst_dma = edesc->sec4_sg_dma +
1116a299c837SYuan Kang 				sizeof(struct sec4_sg_entry);
1117acdca31dSYuan Kang 			out_options = LDST_SGF;
1118acdca31dSYuan Kang 		}
1119acdca31dSYuan Kang 	} else {
1120fa0c92dbSHoria Geantă 		if (edesc->dst_nents == 1) {
1121acdca31dSYuan Kang 			dst_dma = sg_dma_address(req->dst);
1122acdca31dSYuan Kang 		} else {
1123a299c837SYuan Kang 			dst_dma = edesc->sec4_sg_dma +
1124a299c837SYuan Kang 				sec4_sg_index * sizeof(struct sec4_sg_entry);
1125acdca31dSYuan Kang 			out_options = LDST_SGF;
1126acdca31dSYuan Kang 		}
1127acdca31dSYuan Kang 	}
1128acdca31dSYuan Kang 	append_seq_out_ptr(desc, dst_dma, req->nbytes, out_options);
1129acdca31dSYuan Kang }
1130acdca31dSYuan Kang 
1131acdca31dSYuan Kang /*
11327222d1a3SCatalin Vasile  * Fill in ablkcipher givencrypt job descriptor
11337222d1a3SCatalin Vasile  */
11347222d1a3SCatalin Vasile static void init_ablkcipher_giv_job(u32 *sh_desc, dma_addr_t ptr,
11357222d1a3SCatalin Vasile 				    struct ablkcipher_edesc *edesc,
11367222d1a3SCatalin Vasile 				    struct ablkcipher_request *req,
11377222d1a3SCatalin Vasile 				    bool iv_contig)
11387222d1a3SCatalin Vasile {
11397222d1a3SCatalin Vasile 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
11407222d1a3SCatalin Vasile 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
11417222d1a3SCatalin Vasile 	u32 *desc = edesc->hw_desc;
11427222d1a3SCatalin Vasile 	u32 out_options, in_options;
11437222d1a3SCatalin Vasile 	dma_addr_t dst_dma, src_dma;
11447222d1a3SCatalin Vasile 	int len, sec4_sg_index = 0;
11457222d1a3SCatalin Vasile 
11467222d1a3SCatalin Vasile #ifdef DEBUG
11477222d1a3SCatalin Vasile 	print_hex_dump(KERN_ERR, "presciv@" __stringify(__LINE__) ": ",
11487222d1a3SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
11497222d1a3SCatalin Vasile 		       ivsize, 1);
11505ecf8ef9SCatalin Vasile 	dbg_dump_sg(KERN_ERR, "src    @" __stringify(__LINE__) ": ",
11515ecf8ef9SCatalin Vasile 		    DUMP_PREFIX_ADDRESS, 16, 4, req->src,
1152fa0c92dbSHoria Geantă 		    edesc->src_nents > 1 ? 100 : req->nbytes, 1);
11537222d1a3SCatalin Vasile #endif
11547222d1a3SCatalin Vasile 
11557222d1a3SCatalin Vasile 	len = desc_len(sh_desc);
11567222d1a3SCatalin Vasile 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
11577222d1a3SCatalin Vasile 
1158fa0c92dbSHoria Geantă 	if (edesc->src_nents == 1) {
11597222d1a3SCatalin Vasile 		src_dma = sg_dma_address(req->src);
11607222d1a3SCatalin Vasile 		in_options = 0;
11617222d1a3SCatalin Vasile 	} else {
11627222d1a3SCatalin Vasile 		src_dma = edesc->sec4_sg_dma;
11637222d1a3SCatalin Vasile 		sec4_sg_index += edesc->src_nents;
11647222d1a3SCatalin Vasile 		in_options = LDST_SGF;
11657222d1a3SCatalin Vasile 	}
11667222d1a3SCatalin Vasile 	append_seq_in_ptr(desc, src_dma, req->nbytes, in_options);
11677222d1a3SCatalin Vasile 
11687222d1a3SCatalin Vasile 	if (iv_contig) {
11697222d1a3SCatalin Vasile 		dst_dma = edesc->iv_dma;
11707222d1a3SCatalin Vasile 		out_options = 0;
11717222d1a3SCatalin Vasile 	} else {
11727222d1a3SCatalin Vasile 		dst_dma = edesc->sec4_sg_dma +
11737222d1a3SCatalin Vasile 			  sec4_sg_index * sizeof(struct sec4_sg_entry);
11747222d1a3SCatalin Vasile 		out_options = LDST_SGF;
11757222d1a3SCatalin Vasile 	}
11767222d1a3SCatalin Vasile 	append_seq_out_ptr(desc, dst_dma, req->nbytes + ivsize, out_options);
11777222d1a3SCatalin Vasile }
11787222d1a3SCatalin Vasile 
11797222d1a3SCatalin Vasile /*
11801acebad3SYuan Kang  * allocate and map the aead extended descriptor
11818e8ec596SKim Phillips  */
1182f2147b88SHerbert Xu static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
1183f2147b88SHerbert Xu 					   int desc_bytes, bool *all_contig_ptr,
1184f2147b88SHerbert Xu 					   bool encrypt)
1185f2147b88SHerbert Xu {
1186f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1187f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1188f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
1189f2147b88SHerbert Xu 	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
1190f2147b88SHerbert Xu 		       CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC;
1191838e0a89SHoria Geantă 	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
1192f2147b88SHerbert Xu 	struct aead_edesc *edesc;
1193fa0c92dbSHoria Geantă 	int sec4_sg_index, sec4_sg_len, sec4_sg_bytes;
1194f2147b88SHerbert Xu 	unsigned int authsize = ctx->authsize;
1195f2147b88SHerbert Xu 
1196f2147b88SHerbert Xu 	if (unlikely(req->dst != req->src)) {
1197fa0c92dbSHoria Geantă 		src_nents = sg_nents_for_len(req->src, req->assoclen +
1198fa0c92dbSHoria Geantă 					     req->cryptlen);
1199fd144d83SHoria Geantă 		if (unlikely(src_nents < 0)) {
1200fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
1201fd144d83SHoria Geantă 				req->assoclen + req->cryptlen);
1202fd144d83SHoria Geantă 			return ERR_PTR(src_nents);
1203fd144d83SHoria Geantă 		}
1204fd144d83SHoria Geantă 
1205fa0c92dbSHoria Geantă 		dst_nents = sg_nents_for_len(req->dst, req->assoclen +
1206fa0c92dbSHoria Geantă 					     req->cryptlen +
1207fa0c92dbSHoria Geantă 						(encrypt ? authsize :
1208fa0c92dbSHoria Geantă 							   (-authsize)));
1209fd144d83SHoria Geantă 		if (unlikely(dst_nents < 0)) {
1210fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in dst S/G\n",
1211fd144d83SHoria Geantă 				req->assoclen + req->cryptlen +
1212fd144d83SHoria Geantă 				(encrypt ? authsize : (-authsize)));
1213fd144d83SHoria Geantă 			return ERR_PTR(dst_nents);
1214fd144d83SHoria Geantă 		}
1215f2147b88SHerbert Xu 	} else {
1216fa0c92dbSHoria Geantă 		src_nents = sg_nents_for_len(req->src, req->assoclen +
1217fa0c92dbSHoria Geantă 					     req->cryptlen +
121813fb8fd7SLABBE Corentin 					     (encrypt ? authsize : 0));
1219fd144d83SHoria Geantă 		if (unlikely(src_nents < 0)) {
1220fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
1221fd144d83SHoria Geantă 				req->assoclen + req->cryptlen +
1222fd144d83SHoria Geantă 				(encrypt ? authsize : 0));
1223fd144d83SHoria Geantă 			return ERR_PTR(src_nents);
1224fd144d83SHoria Geantă 		}
1225f2147b88SHerbert Xu 	}
1226f2147b88SHerbert Xu 
1227838e0a89SHoria Geantă 	if (likely(req->src == req->dst)) {
1228838e0a89SHoria Geantă 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1229838e0a89SHoria Geantă 					      DMA_BIDIRECTIONAL);
1230838e0a89SHoria Geantă 		if (unlikely(!mapped_src_nents)) {
1231838e0a89SHoria Geantă 			dev_err(jrdev, "unable to map source\n");
1232838e0a89SHoria Geantă 			return ERR_PTR(-ENOMEM);
1233838e0a89SHoria Geantă 		}
1234838e0a89SHoria Geantă 	} else {
1235838e0a89SHoria Geantă 		/* Cover also the case of null (zero length) input data */
1236838e0a89SHoria Geantă 		if (src_nents) {
1237838e0a89SHoria Geantă 			mapped_src_nents = dma_map_sg(jrdev, req->src,
1238838e0a89SHoria Geantă 						      src_nents, DMA_TO_DEVICE);
1239838e0a89SHoria Geantă 			if (unlikely(!mapped_src_nents)) {
1240838e0a89SHoria Geantă 				dev_err(jrdev, "unable to map source\n");
1241838e0a89SHoria Geantă 				return ERR_PTR(-ENOMEM);
1242838e0a89SHoria Geantă 			}
1243838e0a89SHoria Geantă 		} else {
1244838e0a89SHoria Geantă 			mapped_src_nents = 0;
1245838e0a89SHoria Geantă 		}
1246838e0a89SHoria Geantă 
1247838e0a89SHoria Geantă 		mapped_dst_nents = dma_map_sg(jrdev, req->dst, dst_nents,
1248838e0a89SHoria Geantă 					      DMA_FROM_DEVICE);
1249838e0a89SHoria Geantă 		if (unlikely(!mapped_dst_nents)) {
1250838e0a89SHoria Geantă 			dev_err(jrdev, "unable to map destination\n");
1251838e0a89SHoria Geantă 			dma_unmap_sg(jrdev, req->src, src_nents, DMA_TO_DEVICE);
1252838e0a89SHoria Geantă 			return ERR_PTR(-ENOMEM);
1253838e0a89SHoria Geantă 		}
1254838e0a89SHoria Geantă 	}
1255838e0a89SHoria Geantă 
1256838e0a89SHoria Geantă 	sec4_sg_len = mapped_src_nents > 1 ? mapped_src_nents : 0;
1257838e0a89SHoria Geantă 	sec4_sg_len += mapped_dst_nents > 1 ? mapped_dst_nents : 0;
1258f2147b88SHerbert Xu 	sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry);
1259f2147b88SHerbert Xu 
1260f2147b88SHerbert Xu 	/* allocate space for base edesc and hw desc commands, link tables */
1261dde20ae9SVictoria Milhoan 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes,
1262dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
1263f2147b88SHerbert Xu 	if (!edesc) {
1264838e0a89SHoria Geantă 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
1265838e0a89SHoria Geantă 			   0, 0, 0);
1266f2147b88SHerbert Xu 		return ERR_PTR(-ENOMEM);
1267f2147b88SHerbert Xu 	}
1268f2147b88SHerbert Xu 
1269f2147b88SHerbert Xu 	edesc->src_nents = src_nents;
1270f2147b88SHerbert Xu 	edesc->dst_nents = dst_nents;
1271f2147b88SHerbert Xu 	edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) +
1272f2147b88SHerbert Xu 			 desc_bytes;
1273838e0a89SHoria Geantă 	*all_contig_ptr = !(mapped_src_nents > 1);
1274f2147b88SHerbert Xu 
1275f2147b88SHerbert Xu 	sec4_sg_index = 0;
1276838e0a89SHoria Geantă 	if (mapped_src_nents > 1) {
1277838e0a89SHoria Geantă 		sg_to_sec4_sg_last(req->src, mapped_src_nents,
1278f2147b88SHerbert Xu 				   edesc->sec4_sg + sec4_sg_index, 0);
1279838e0a89SHoria Geantă 		sec4_sg_index += mapped_src_nents;
1280f2147b88SHerbert Xu 	}
1281838e0a89SHoria Geantă 	if (mapped_dst_nents > 1) {
1282838e0a89SHoria Geantă 		sg_to_sec4_sg_last(req->dst, mapped_dst_nents,
1283f2147b88SHerbert Xu 				   edesc->sec4_sg + sec4_sg_index, 0);
1284f2147b88SHerbert Xu 	}
1285f2147b88SHerbert Xu 
1286f2147b88SHerbert Xu 	if (!sec4_sg_bytes)
1287f2147b88SHerbert Xu 		return edesc;
1288f2147b88SHerbert Xu 
1289f2147b88SHerbert Xu 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
1290f2147b88SHerbert Xu 					    sec4_sg_bytes, DMA_TO_DEVICE);
1291f2147b88SHerbert Xu 	if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
1292f2147b88SHerbert Xu 		dev_err(jrdev, "unable to map S/G table\n");
1293f2147b88SHerbert Xu 		aead_unmap(jrdev, edesc, req);
1294f2147b88SHerbert Xu 		kfree(edesc);
1295f2147b88SHerbert Xu 		return ERR_PTR(-ENOMEM);
1296f2147b88SHerbert Xu 	}
1297f2147b88SHerbert Xu 
1298f2147b88SHerbert Xu 	edesc->sec4_sg_bytes = sec4_sg_bytes;
1299f2147b88SHerbert Xu 
1300f2147b88SHerbert Xu 	return edesc;
1301f2147b88SHerbert Xu }
1302f2147b88SHerbert Xu 
1303f2147b88SHerbert Xu static int gcm_encrypt(struct aead_request *req)
13048e8ec596SKim Phillips {
13050e479300SYuan Kang 	struct aead_edesc *edesc;
13068e8ec596SKim Phillips 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
13078e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
13088e8ec596SKim Phillips 	struct device *jrdev = ctx->jrdev;
13091acebad3SYuan Kang 	bool all_contig;
13108e8ec596SKim Phillips 	u32 *desc;
13111acebad3SYuan Kang 	int ret = 0;
13121acebad3SYuan Kang 
13138e8ec596SKim Phillips 	/* allocate extended descriptor */
1314f2147b88SHerbert Xu 	edesc = aead_edesc_alloc(req, GCM_DESC_JOB_IO_LEN, &all_contig, true);
13158e8ec596SKim Phillips 	if (IS_ERR(edesc))
13168e8ec596SKim Phillips 		return PTR_ERR(edesc);
13178e8ec596SKim Phillips 
13181acebad3SYuan Kang 	/* Create and submit job descriptor */
1319f2147b88SHerbert Xu 	init_gcm_job(req, edesc, all_contig, true);
13201acebad3SYuan Kang #ifdef DEBUG
1321514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
13221acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
13231acebad3SYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
13241acebad3SYuan Kang #endif
13251acebad3SYuan Kang 
13268e8ec596SKim Phillips 	desc = edesc->hw_desc;
13271acebad3SYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
13281acebad3SYuan Kang 	if (!ret) {
13291acebad3SYuan Kang 		ret = -EINPROGRESS;
13301acebad3SYuan Kang 	} else {
13311acebad3SYuan Kang 		aead_unmap(jrdev, edesc, req);
13321acebad3SYuan Kang 		kfree(edesc);
13331acebad3SYuan Kang 	}
13348e8ec596SKim Phillips 
13351acebad3SYuan Kang 	return ret;
13368e8ec596SKim Phillips }
13378e8ec596SKim Phillips 
133846218750SHerbert Xu static int ipsec_gcm_encrypt(struct aead_request *req)
133946218750SHerbert Xu {
134046218750SHerbert Xu 	if (req->assoclen < 8)
134146218750SHerbert Xu 		return -EINVAL;
134246218750SHerbert Xu 
134346218750SHerbert Xu 	return gcm_encrypt(req);
134446218750SHerbert Xu }
134546218750SHerbert Xu 
1346479bcc7cSHerbert Xu static int aead_encrypt(struct aead_request *req)
13478e8ec596SKim Phillips {
13481acebad3SYuan Kang 	struct aead_edesc *edesc;
13490e479300SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
13500e479300SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
13510e479300SYuan Kang 	struct device *jrdev = ctx->jrdev;
13521acebad3SYuan Kang 	bool all_contig;
13530e479300SYuan Kang 	u32 *desc;
13541acebad3SYuan Kang 	int ret = 0;
13550e479300SYuan Kang 
13560e479300SYuan Kang 	/* allocate extended descriptor */
1357479bcc7cSHerbert Xu 	edesc = aead_edesc_alloc(req, AUTHENC_DESC_JOB_IO_LEN,
1358479bcc7cSHerbert Xu 				 &all_contig, true);
13590e479300SYuan Kang 	if (IS_ERR(edesc))
13600e479300SYuan Kang 		return PTR_ERR(edesc);
13610e479300SYuan Kang 
1362f2147b88SHerbert Xu 	/* Create and submit job descriptor */
1363479bcc7cSHerbert Xu 	init_authenc_job(req, edesc, all_contig, true);
13641acebad3SYuan Kang #ifdef DEBUG
1365f2147b88SHerbert Xu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
1366f2147b88SHerbert Xu 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1367f2147b88SHerbert Xu 		       desc_bytes(edesc->hw_desc), 1);
13681acebad3SYuan Kang #endif
13691acebad3SYuan Kang 
1370f2147b88SHerbert Xu 	desc = edesc->hw_desc;
1371479bcc7cSHerbert Xu 	ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
1372f2147b88SHerbert Xu 	if (!ret) {
1373f2147b88SHerbert Xu 		ret = -EINPROGRESS;
1374f2147b88SHerbert Xu 	} else {
1375479bcc7cSHerbert Xu 		aead_unmap(jrdev, edesc, req);
1376f2147b88SHerbert Xu 		kfree(edesc);
1377f2147b88SHerbert Xu 	}
1378f2147b88SHerbert Xu 
1379f2147b88SHerbert Xu 	return ret;
1380f2147b88SHerbert Xu }
1381f2147b88SHerbert Xu 
1382f2147b88SHerbert Xu static int gcm_decrypt(struct aead_request *req)
1383f2147b88SHerbert Xu {
1384f2147b88SHerbert Xu 	struct aead_edesc *edesc;
1385f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1386f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1387f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
1388f2147b88SHerbert Xu 	bool all_contig;
1389f2147b88SHerbert Xu 	u32 *desc;
1390f2147b88SHerbert Xu 	int ret = 0;
1391f2147b88SHerbert Xu 
1392f2147b88SHerbert Xu 	/* allocate extended descriptor */
1393f2147b88SHerbert Xu 	edesc = aead_edesc_alloc(req, GCM_DESC_JOB_IO_LEN, &all_contig, false);
1394f2147b88SHerbert Xu 	if (IS_ERR(edesc))
1395f2147b88SHerbert Xu 		return PTR_ERR(edesc);
1396f2147b88SHerbert Xu 
13971acebad3SYuan Kang 	/* Create and submit job descriptor*/
1398f2147b88SHerbert Xu 	init_gcm_job(req, edesc, all_contig, false);
13991acebad3SYuan Kang #ifdef DEBUG
1400514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
14011acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
14021acebad3SYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
14031acebad3SYuan Kang #endif
14041acebad3SYuan Kang 
14050e479300SYuan Kang 	desc = edesc->hw_desc;
14061acebad3SYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
14071acebad3SYuan Kang 	if (!ret) {
14081acebad3SYuan Kang 		ret = -EINPROGRESS;
14091acebad3SYuan Kang 	} else {
14101acebad3SYuan Kang 		aead_unmap(jrdev, edesc, req);
14111acebad3SYuan Kang 		kfree(edesc);
14121acebad3SYuan Kang 	}
14130e479300SYuan Kang 
14141acebad3SYuan Kang 	return ret;
14151acebad3SYuan Kang }
14160e479300SYuan Kang 
141746218750SHerbert Xu static int ipsec_gcm_decrypt(struct aead_request *req)
141846218750SHerbert Xu {
141946218750SHerbert Xu 	if (req->assoclen < 8)
142046218750SHerbert Xu 		return -EINVAL;
142146218750SHerbert Xu 
142246218750SHerbert Xu 	return gcm_decrypt(req);
142346218750SHerbert Xu }
142446218750SHerbert Xu 
1425479bcc7cSHerbert Xu static int aead_decrypt(struct aead_request *req)
1426f2147b88SHerbert Xu {
1427f2147b88SHerbert Xu 	struct aead_edesc *edesc;
1428f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1429f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1430f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
1431f2147b88SHerbert Xu 	bool all_contig;
1432f2147b88SHerbert Xu 	u32 *desc;
1433f2147b88SHerbert Xu 	int ret = 0;
1434f2147b88SHerbert Xu 
14355ecf8ef9SCatalin Vasile #ifdef DEBUG
14365ecf8ef9SCatalin Vasile 	dbg_dump_sg(KERN_ERR, "dec src@"__stringify(__LINE__)": ",
14375ecf8ef9SCatalin Vasile 		    DUMP_PREFIX_ADDRESS, 16, 4, req->src,
143800fef2b2SHoria Geantă 		    req->assoclen + req->cryptlen, 1);
14395ecf8ef9SCatalin Vasile #endif
14405ecf8ef9SCatalin Vasile 
1441f2147b88SHerbert Xu 	/* allocate extended descriptor */
1442479bcc7cSHerbert Xu 	edesc = aead_edesc_alloc(req, AUTHENC_DESC_JOB_IO_LEN,
1443479bcc7cSHerbert Xu 				 &all_contig, false);
1444f2147b88SHerbert Xu 	if (IS_ERR(edesc))
1445f2147b88SHerbert Xu 		return PTR_ERR(edesc);
1446f2147b88SHerbert Xu 
1447f2147b88SHerbert Xu 	/* Create and submit job descriptor*/
1448479bcc7cSHerbert Xu 	init_authenc_job(req, edesc, all_contig, false);
1449f2147b88SHerbert Xu #ifdef DEBUG
1450f2147b88SHerbert Xu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
1451f2147b88SHerbert Xu 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1452f2147b88SHerbert Xu 		       desc_bytes(edesc->hw_desc), 1);
1453f2147b88SHerbert Xu #endif
1454f2147b88SHerbert Xu 
1455f2147b88SHerbert Xu 	desc = edesc->hw_desc;
1456479bcc7cSHerbert Xu 	ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
1457f2147b88SHerbert Xu 	if (!ret) {
1458f2147b88SHerbert Xu 		ret = -EINPROGRESS;
1459f2147b88SHerbert Xu 	} else {
1460479bcc7cSHerbert Xu 		aead_unmap(jrdev, edesc, req);
1461f2147b88SHerbert Xu 		kfree(edesc);
1462f2147b88SHerbert Xu 	}
1463f2147b88SHerbert Xu 
1464f2147b88SHerbert Xu 	return ret;
1465f2147b88SHerbert Xu }
1466f2147b88SHerbert Xu 
1467acdca31dSYuan Kang /*
1468acdca31dSYuan Kang  * allocate and map the ablkcipher extended descriptor for ablkcipher
1469acdca31dSYuan Kang  */
1470acdca31dSYuan Kang static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request
1471acdca31dSYuan Kang 						       *req, int desc_bytes,
1472acdca31dSYuan Kang 						       bool *iv_contig_out)
1473acdca31dSYuan Kang {
1474acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
1475acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
1476acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
1477acdca31dSYuan Kang 	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
1478acdca31dSYuan Kang 					  CRYPTO_TFM_REQ_MAY_SLEEP)) ?
1479acdca31dSYuan Kang 		       GFP_KERNEL : GFP_ATOMIC;
1480838e0a89SHoria Geantă 	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
1481acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
1482acdca31dSYuan Kang 	dma_addr_t iv_dma = 0;
1483fa0c92dbSHoria Geantă 	bool in_contig;
1484acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
1485838e0a89SHoria Geantă 	int dst_sg_idx, sec4_sg_ents, sec4_sg_bytes;
1486acdca31dSYuan Kang 
1487fa0c92dbSHoria Geantă 	src_nents = sg_nents_for_len(req->src, req->nbytes);
1488fd144d83SHoria Geantă 	if (unlikely(src_nents < 0)) {
1489fd144d83SHoria Geantă 		dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
1490fd144d83SHoria Geantă 			req->nbytes);
1491fd144d83SHoria Geantă 		return ERR_PTR(src_nents);
1492fd144d83SHoria Geantă 	}
1493acdca31dSYuan Kang 
1494fd144d83SHoria Geantă 	if (req->dst != req->src) {
1495fa0c92dbSHoria Geantă 		dst_nents = sg_nents_for_len(req->dst, req->nbytes);
1496fd144d83SHoria Geantă 		if (unlikely(dst_nents < 0)) {
1497fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in dst S/G\n",
1498fd144d83SHoria Geantă 				req->nbytes);
1499fd144d83SHoria Geantă 			return ERR_PTR(dst_nents);
1500fd144d83SHoria Geantă 		}
1501fd144d83SHoria Geantă 	}
1502acdca31dSYuan Kang 
1503acdca31dSYuan Kang 	if (likely(req->src == req->dst)) {
1504838e0a89SHoria Geantă 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1505838e0a89SHoria Geantă 					      DMA_BIDIRECTIONAL);
1506838e0a89SHoria Geantă 		if (unlikely(!mapped_src_nents)) {
1507c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map source\n");
1508c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1509c73e36e8SHoria Geantă 		}
1510acdca31dSYuan Kang 	} else {
1511838e0a89SHoria Geantă 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1512838e0a89SHoria Geantă 					      DMA_TO_DEVICE);
1513838e0a89SHoria Geantă 		if (unlikely(!mapped_src_nents)) {
1514c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map source\n");
1515c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1516c73e36e8SHoria Geantă 		}
1517c73e36e8SHoria Geantă 
1518838e0a89SHoria Geantă 		mapped_dst_nents = dma_map_sg(jrdev, req->dst, dst_nents,
1519838e0a89SHoria Geantă 					      DMA_FROM_DEVICE);
1520838e0a89SHoria Geantă 		if (unlikely(!mapped_dst_nents)) {
1521c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map destination\n");
1522fa0c92dbSHoria Geantă 			dma_unmap_sg(jrdev, req->src, src_nents, DMA_TO_DEVICE);
1523c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1524c73e36e8SHoria Geantă 		}
1525acdca31dSYuan Kang 	}
1526acdca31dSYuan Kang 
1527ce572085SHoria Geanta 	iv_dma = dma_map_single(jrdev, req->info, ivsize, DMA_TO_DEVICE);
1528ce572085SHoria Geanta 	if (dma_mapping_error(jrdev, iv_dma)) {
1529ce572085SHoria Geanta 		dev_err(jrdev, "unable to map IV\n");
1530c73e36e8SHoria Geantă 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
1531c73e36e8SHoria Geantă 			   0, 0, 0);
1532ce572085SHoria Geanta 		return ERR_PTR(-ENOMEM);
1533ce572085SHoria Geanta 	}
1534ce572085SHoria Geanta 
1535838e0a89SHoria Geantă 	if (mapped_src_nents == 1 &&
1536838e0a89SHoria Geantă 	    iv_dma + ivsize == sg_dma_address(req->src)) {
1537fa0c92dbSHoria Geantă 		in_contig = true;
1538fa0c92dbSHoria Geantă 		sec4_sg_ents = 0;
1539fa0c92dbSHoria Geantă 	} else {
1540fa0c92dbSHoria Geantă 		in_contig = false;
1541838e0a89SHoria Geantă 		sec4_sg_ents = 1 + mapped_src_nents;
1542fa0c92dbSHoria Geantă 	}
1543fa0c92dbSHoria Geantă 	dst_sg_idx = sec4_sg_ents;
1544838e0a89SHoria Geantă 	sec4_sg_ents += mapped_dst_nents > 1 ? mapped_dst_nents : 0;
1545fa0c92dbSHoria Geantă 	sec4_sg_bytes = sec4_sg_ents * sizeof(struct sec4_sg_entry);
1546acdca31dSYuan Kang 
1547acdca31dSYuan Kang 	/* allocate space for base edesc and hw desc commands, link tables */
1548dde20ae9SVictoria Milhoan 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes,
1549dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
1550acdca31dSYuan Kang 	if (!edesc) {
1551acdca31dSYuan Kang 		dev_err(jrdev, "could not allocate extended descriptor\n");
1552c73e36e8SHoria Geantă 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents,
1553c73e36e8SHoria Geantă 			   iv_dma, ivsize, 0, 0);
1554acdca31dSYuan Kang 		return ERR_PTR(-ENOMEM);
1555acdca31dSYuan Kang 	}
1556acdca31dSYuan Kang 
1557acdca31dSYuan Kang 	edesc->src_nents = src_nents;
1558acdca31dSYuan Kang 	edesc->dst_nents = dst_nents;
1559a299c837SYuan Kang 	edesc->sec4_sg_bytes = sec4_sg_bytes;
1560a299c837SYuan Kang 	edesc->sec4_sg = (void *)edesc + sizeof(struct ablkcipher_edesc) +
1561acdca31dSYuan Kang 			 desc_bytes;
1562acdca31dSYuan Kang 
1563fa0c92dbSHoria Geantă 	if (!in_contig) {
1564a299c837SYuan Kang 		dma_to_sec4_sg_one(edesc->sec4_sg, iv_dma, ivsize, 0);
1565838e0a89SHoria Geantă 		sg_to_sec4_sg_last(req->src, mapped_src_nents,
1566a299c837SYuan Kang 				   edesc->sec4_sg + 1, 0);
1567acdca31dSYuan Kang 	}
1568acdca31dSYuan Kang 
1569838e0a89SHoria Geantă 	if (mapped_dst_nents > 1) {
1570838e0a89SHoria Geantă 		sg_to_sec4_sg_last(req->dst, mapped_dst_nents,
1571fa0c92dbSHoria Geantă 				   edesc->sec4_sg + dst_sg_idx, 0);
1572acdca31dSYuan Kang 	}
1573acdca31dSYuan Kang 
1574a299c837SYuan Kang 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
1575a299c837SYuan Kang 					    sec4_sg_bytes, DMA_TO_DEVICE);
1576ce572085SHoria Geanta 	if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
1577ce572085SHoria Geanta 		dev_err(jrdev, "unable to map S/G table\n");
1578c73e36e8SHoria Geantă 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents,
1579c73e36e8SHoria Geantă 			   iv_dma, ivsize, 0, 0);
1580c73e36e8SHoria Geantă 		kfree(edesc);
1581ce572085SHoria Geanta 		return ERR_PTR(-ENOMEM);
1582ce572085SHoria Geanta 	}
1583ce572085SHoria Geanta 
1584acdca31dSYuan Kang 	edesc->iv_dma = iv_dma;
1585acdca31dSYuan Kang 
1586acdca31dSYuan Kang #ifdef DEBUG
1587514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ablkcipher sec4_sg@"__stringify(__LINE__)": ",
1588a299c837SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->sec4_sg,
1589a299c837SYuan Kang 		       sec4_sg_bytes, 1);
1590acdca31dSYuan Kang #endif
1591acdca31dSYuan Kang 
1592fa0c92dbSHoria Geantă 	*iv_contig_out = in_contig;
1593acdca31dSYuan Kang 	return edesc;
1594acdca31dSYuan Kang }
1595acdca31dSYuan Kang 
1596acdca31dSYuan Kang static int ablkcipher_encrypt(struct ablkcipher_request *req)
1597acdca31dSYuan Kang {
1598acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
1599acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
1600acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
1601acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
1602acdca31dSYuan Kang 	bool iv_contig;
1603acdca31dSYuan Kang 	u32 *desc;
1604acdca31dSYuan Kang 	int ret = 0;
1605acdca31dSYuan Kang 
1606acdca31dSYuan Kang 	/* allocate extended descriptor */
1607acdca31dSYuan Kang 	edesc = ablkcipher_edesc_alloc(req, DESC_JOB_IO_LEN *
1608acdca31dSYuan Kang 				       CAAM_CMD_SZ, &iv_contig);
1609acdca31dSYuan Kang 	if (IS_ERR(edesc))
1610acdca31dSYuan Kang 		return PTR_ERR(edesc);
1611acdca31dSYuan Kang 
1612acdca31dSYuan Kang 	/* Create and submit job descriptor*/
1613acdca31dSYuan Kang 	init_ablkcipher_job(ctx->sh_desc_enc,
1614acdca31dSYuan Kang 		ctx->sh_desc_enc_dma, edesc, req, iv_contig);
1615acdca31dSYuan Kang #ifdef DEBUG
1616514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ablkcipher jobdesc@"__stringify(__LINE__)": ",
1617acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1618acdca31dSYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
1619acdca31dSYuan Kang #endif
1620acdca31dSYuan Kang 	desc = edesc->hw_desc;
1621acdca31dSYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, ablkcipher_encrypt_done, req);
1622acdca31dSYuan Kang 
1623acdca31dSYuan Kang 	if (!ret) {
1624acdca31dSYuan Kang 		ret = -EINPROGRESS;
1625acdca31dSYuan Kang 	} else {
1626acdca31dSYuan Kang 		ablkcipher_unmap(jrdev, edesc, req);
1627acdca31dSYuan Kang 		kfree(edesc);
1628acdca31dSYuan Kang 	}
1629acdca31dSYuan Kang 
1630acdca31dSYuan Kang 	return ret;
1631acdca31dSYuan Kang }
1632acdca31dSYuan Kang 
1633acdca31dSYuan Kang static int ablkcipher_decrypt(struct ablkcipher_request *req)
1634acdca31dSYuan Kang {
1635acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
1636acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
1637acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
1638acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
1639acdca31dSYuan Kang 	bool iv_contig;
1640acdca31dSYuan Kang 	u32 *desc;
1641acdca31dSYuan Kang 	int ret = 0;
1642acdca31dSYuan Kang 
1643acdca31dSYuan Kang 	/* allocate extended descriptor */
1644acdca31dSYuan Kang 	edesc = ablkcipher_edesc_alloc(req, DESC_JOB_IO_LEN *
1645acdca31dSYuan Kang 				       CAAM_CMD_SZ, &iv_contig);
1646acdca31dSYuan Kang 	if (IS_ERR(edesc))
1647acdca31dSYuan Kang 		return PTR_ERR(edesc);
1648acdca31dSYuan Kang 
1649acdca31dSYuan Kang 	/* Create and submit job descriptor*/
1650acdca31dSYuan Kang 	init_ablkcipher_job(ctx->sh_desc_dec,
1651acdca31dSYuan Kang 		ctx->sh_desc_dec_dma, edesc, req, iv_contig);
1652acdca31dSYuan Kang 	desc = edesc->hw_desc;
1653acdca31dSYuan Kang #ifdef DEBUG
1654514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ablkcipher jobdesc@"__stringify(__LINE__)": ",
1655acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1656acdca31dSYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
1657acdca31dSYuan Kang #endif
1658acdca31dSYuan Kang 
1659acdca31dSYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, ablkcipher_decrypt_done, req);
1660acdca31dSYuan Kang 	if (!ret) {
1661acdca31dSYuan Kang 		ret = -EINPROGRESS;
1662acdca31dSYuan Kang 	} else {
1663acdca31dSYuan Kang 		ablkcipher_unmap(jrdev, edesc, req);
1664acdca31dSYuan Kang 		kfree(edesc);
1665acdca31dSYuan Kang 	}
1666acdca31dSYuan Kang 
1667acdca31dSYuan Kang 	return ret;
1668acdca31dSYuan Kang }
1669acdca31dSYuan Kang 
16707222d1a3SCatalin Vasile /*
16717222d1a3SCatalin Vasile  * allocate and map the ablkcipher extended descriptor
16727222d1a3SCatalin Vasile  * for ablkcipher givencrypt
16737222d1a3SCatalin Vasile  */
16747222d1a3SCatalin Vasile static struct ablkcipher_edesc *ablkcipher_giv_edesc_alloc(
16757222d1a3SCatalin Vasile 				struct skcipher_givcrypt_request *greq,
16767222d1a3SCatalin Vasile 				int desc_bytes,
16777222d1a3SCatalin Vasile 				bool *iv_contig_out)
16787222d1a3SCatalin Vasile {
16797222d1a3SCatalin Vasile 	struct ablkcipher_request *req = &greq->creq;
16807222d1a3SCatalin Vasile 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
16817222d1a3SCatalin Vasile 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
16827222d1a3SCatalin Vasile 	struct device *jrdev = ctx->jrdev;
16837222d1a3SCatalin Vasile 	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
16847222d1a3SCatalin Vasile 					  CRYPTO_TFM_REQ_MAY_SLEEP)) ?
16857222d1a3SCatalin Vasile 		       GFP_KERNEL : GFP_ATOMIC;
1686838e0a89SHoria Geantă 	int src_nents, mapped_src_nents, dst_nents, mapped_dst_nents;
16877222d1a3SCatalin Vasile 	struct ablkcipher_edesc *edesc;
16887222d1a3SCatalin Vasile 	dma_addr_t iv_dma = 0;
1689fa0c92dbSHoria Geantă 	bool out_contig;
16907222d1a3SCatalin Vasile 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
1691838e0a89SHoria Geantă 	int dst_sg_idx, sec4_sg_ents, sec4_sg_bytes;
16927222d1a3SCatalin Vasile 
1693fa0c92dbSHoria Geantă 	src_nents = sg_nents_for_len(req->src, req->nbytes);
1694fd144d83SHoria Geantă 	if (unlikely(src_nents < 0)) {
1695fd144d83SHoria Geantă 		dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
1696fd144d83SHoria Geantă 			req->nbytes);
1697fd144d83SHoria Geantă 		return ERR_PTR(src_nents);
1698fd144d83SHoria Geantă 	}
16997222d1a3SCatalin Vasile 
17007222d1a3SCatalin Vasile 	if (likely(req->src == req->dst)) {
1701838e0a89SHoria Geantă 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1702838e0a89SHoria Geantă 					      DMA_BIDIRECTIONAL);
1703838e0a89SHoria Geantă 		if (unlikely(!mapped_src_nents)) {
1704c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map source\n");
1705c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1706c73e36e8SHoria Geantă 		}
1707fd88aac9SHoria Geantă 
1708fd88aac9SHoria Geantă 		dst_nents = src_nents;
1709838e0a89SHoria Geantă 		mapped_dst_nents = src_nents;
17107222d1a3SCatalin Vasile 	} else {
1711838e0a89SHoria Geantă 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1712838e0a89SHoria Geantă 					      DMA_TO_DEVICE);
1713838e0a89SHoria Geantă 		if (unlikely(!mapped_src_nents)) {
1714c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map source\n");
1715c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1716c73e36e8SHoria Geantă 		}
1717c73e36e8SHoria Geantă 
1718fa0c92dbSHoria Geantă 		dst_nents = sg_nents_for_len(req->dst, req->nbytes);
1719fd144d83SHoria Geantă 		if (unlikely(dst_nents < 0)) {
1720fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in dst S/G\n",
1721fd144d83SHoria Geantă 				req->nbytes);
1722fd144d83SHoria Geantă 			return ERR_PTR(dst_nents);
1723fd144d83SHoria Geantă 		}
1724fd144d83SHoria Geantă 
1725838e0a89SHoria Geantă 		mapped_dst_nents = dma_map_sg(jrdev, req->dst, dst_nents,
1726838e0a89SHoria Geantă 					      DMA_FROM_DEVICE);
1727838e0a89SHoria Geantă 		if (unlikely(!mapped_dst_nents)) {
1728c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map destination\n");
1729fa0c92dbSHoria Geantă 			dma_unmap_sg(jrdev, req->src, src_nents, DMA_TO_DEVICE);
1730c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1731c73e36e8SHoria Geantă 		}
17327222d1a3SCatalin Vasile 	}
17337222d1a3SCatalin Vasile 
17347222d1a3SCatalin Vasile 	/*
17357222d1a3SCatalin Vasile 	 * Check if iv can be contiguous with source and destination.
17367222d1a3SCatalin Vasile 	 * If so, include it. If not, create scatterlist.
17377222d1a3SCatalin Vasile 	 */
17387222d1a3SCatalin Vasile 	iv_dma = dma_map_single(jrdev, greq->giv, ivsize, DMA_TO_DEVICE);
17397222d1a3SCatalin Vasile 	if (dma_mapping_error(jrdev, iv_dma)) {
17407222d1a3SCatalin Vasile 		dev_err(jrdev, "unable to map IV\n");
1741c73e36e8SHoria Geantă 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
1742c73e36e8SHoria Geantă 			   0, 0, 0);
17437222d1a3SCatalin Vasile 		return ERR_PTR(-ENOMEM);
17447222d1a3SCatalin Vasile 	}
17457222d1a3SCatalin Vasile 
1746838e0a89SHoria Geantă 	sec4_sg_ents = mapped_src_nents > 1 ? mapped_src_nents : 0;
1747fa0c92dbSHoria Geantă 	dst_sg_idx = sec4_sg_ents;
1748838e0a89SHoria Geantă 	if (mapped_dst_nents == 1 &&
1749838e0a89SHoria Geantă 	    iv_dma + ivsize == sg_dma_address(req->dst)) {
1750fa0c92dbSHoria Geantă 		out_contig = true;
1751fa0c92dbSHoria Geantă 	} else {
1752fa0c92dbSHoria Geantă 		out_contig = false;
1753838e0a89SHoria Geantă 		sec4_sg_ents += 1 + mapped_dst_nents;
1754fa0c92dbSHoria Geantă 	}
17557222d1a3SCatalin Vasile 
17567222d1a3SCatalin Vasile 	/* allocate space for base edesc and hw desc commands, link tables */
1757fa0c92dbSHoria Geantă 	sec4_sg_bytes = sec4_sg_ents * sizeof(struct sec4_sg_entry);
1758dde20ae9SVictoria Milhoan 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes,
1759dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
17607222d1a3SCatalin Vasile 	if (!edesc) {
17617222d1a3SCatalin Vasile 		dev_err(jrdev, "could not allocate extended descriptor\n");
1762c73e36e8SHoria Geantă 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents,
1763c73e36e8SHoria Geantă 			   iv_dma, ivsize, 0, 0);
17647222d1a3SCatalin Vasile 		return ERR_PTR(-ENOMEM);
17657222d1a3SCatalin Vasile 	}
17667222d1a3SCatalin Vasile 
17677222d1a3SCatalin Vasile 	edesc->src_nents = src_nents;
17687222d1a3SCatalin Vasile 	edesc->dst_nents = dst_nents;
17697222d1a3SCatalin Vasile 	edesc->sec4_sg_bytes = sec4_sg_bytes;
17707222d1a3SCatalin Vasile 	edesc->sec4_sg = (void *)edesc + sizeof(struct ablkcipher_edesc) +
17717222d1a3SCatalin Vasile 			 desc_bytes;
17727222d1a3SCatalin Vasile 
1773838e0a89SHoria Geantă 	if (mapped_src_nents > 1)
1774838e0a89SHoria Geantă 		sg_to_sec4_sg_last(req->src, mapped_src_nents, edesc->sec4_sg,
1775838e0a89SHoria Geantă 				   0);
17767222d1a3SCatalin Vasile 
1777fa0c92dbSHoria Geantă 	if (!out_contig) {
1778fa0c92dbSHoria Geantă 		dma_to_sec4_sg_one(edesc->sec4_sg + dst_sg_idx,
17797222d1a3SCatalin Vasile 				   iv_dma, ivsize, 0);
1780838e0a89SHoria Geantă 		sg_to_sec4_sg_last(req->dst, mapped_dst_nents,
1781fa0c92dbSHoria Geantă 				   edesc->sec4_sg + dst_sg_idx + 1, 0);
17827222d1a3SCatalin Vasile 	}
17837222d1a3SCatalin Vasile 
17847222d1a3SCatalin Vasile 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
17857222d1a3SCatalin Vasile 					    sec4_sg_bytes, DMA_TO_DEVICE);
17867222d1a3SCatalin Vasile 	if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
17877222d1a3SCatalin Vasile 		dev_err(jrdev, "unable to map S/G table\n");
1788c73e36e8SHoria Geantă 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents,
1789c73e36e8SHoria Geantă 			   iv_dma, ivsize, 0, 0);
1790c73e36e8SHoria Geantă 		kfree(edesc);
17917222d1a3SCatalin Vasile 		return ERR_PTR(-ENOMEM);
17927222d1a3SCatalin Vasile 	}
17937222d1a3SCatalin Vasile 	edesc->iv_dma = iv_dma;
17947222d1a3SCatalin Vasile 
17957222d1a3SCatalin Vasile #ifdef DEBUG
17967222d1a3SCatalin Vasile 	print_hex_dump(KERN_ERR,
17977222d1a3SCatalin Vasile 		       "ablkcipher sec4_sg@" __stringify(__LINE__) ": ",
17987222d1a3SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->sec4_sg,
17997222d1a3SCatalin Vasile 		       sec4_sg_bytes, 1);
18007222d1a3SCatalin Vasile #endif
18017222d1a3SCatalin Vasile 
1802fa0c92dbSHoria Geantă 	*iv_contig_out = out_contig;
18037222d1a3SCatalin Vasile 	return edesc;
18047222d1a3SCatalin Vasile }
18057222d1a3SCatalin Vasile 
18067222d1a3SCatalin Vasile static int ablkcipher_givencrypt(struct skcipher_givcrypt_request *creq)
18077222d1a3SCatalin Vasile {
18087222d1a3SCatalin Vasile 	struct ablkcipher_request *req = &creq->creq;
18097222d1a3SCatalin Vasile 	struct ablkcipher_edesc *edesc;
18107222d1a3SCatalin Vasile 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
18117222d1a3SCatalin Vasile 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
18127222d1a3SCatalin Vasile 	struct device *jrdev = ctx->jrdev;
1813fd144d83SHoria Geantă 	bool iv_contig = false;
18147222d1a3SCatalin Vasile 	u32 *desc;
18157222d1a3SCatalin Vasile 	int ret = 0;
18167222d1a3SCatalin Vasile 
18177222d1a3SCatalin Vasile 	/* allocate extended descriptor */
18187222d1a3SCatalin Vasile 	edesc = ablkcipher_giv_edesc_alloc(creq, DESC_JOB_IO_LEN *
18197222d1a3SCatalin Vasile 				       CAAM_CMD_SZ, &iv_contig);
18207222d1a3SCatalin Vasile 	if (IS_ERR(edesc))
18217222d1a3SCatalin Vasile 		return PTR_ERR(edesc);
18227222d1a3SCatalin Vasile 
18237222d1a3SCatalin Vasile 	/* Create and submit job descriptor*/
18247222d1a3SCatalin Vasile 	init_ablkcipher_giv_job(ctx->sh_desc_givenc, ctx->sh_desc_givenc_dma,
18257222d1a3SCatalin Vasile 				edesc, req, iv_contig);
18267222d1a3SCatalin Vasile #ifdef DEBUG
18277222d1a3SCatalin Vasile 	print_hex_dump(KERN_ERR,
18287222d1a3SCatalin Vasile 		       "ablkcipher jobdesc@" __stringify(__LINE__) ": ",
18297222d1a3SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
18307222d1a3SCatalin Vasile 		       desc_bytes(edesc->hw_desc), 1);
18317222d1a3SCatalin Vasile #endif
18327222d1a3SCatalin Vasile 	desc = edesc->hw_desc;
18337222d1a3SCatalin Vasile 	ret = caam_jr_enqueue(jrdev, desc, ablkcipher_encrypt_done, req);
18347222d1a3SCatalin Vasile 
18357222d1a3SCatalin Vasile 	if (!ret) {
18367222d1a3SCatalin Vasile 		ret = -EINPROGRESS;
18377222d1a3SCatalin Vasile 	} else {
18387222d1a3SCatalin Vasile 		ablkcipher_unmap(jrdev, edesc, req);
18397222d1a3SCatalin Vasile 		kfree(edesc);
18407222d1a3SCatalin Vasile 	}
18417222d1a3SCatalin Vasile 
18427222d1a3SCatalin Vasile 	return ret;
18437222d1a3SCatalin Vasile }
18447222d1a3SCatalin Vasile 
1845885e9e2fSYuan Kang #define template_aead		template_u.aead
1846acdca31dSYuan Kang #define template_ablkcipher	template_u.ablkcipher
18478e8ec596SKim Phillips struct caam_alg_template {
18488e8ec596SKim Phillips 	char name[CRYPTO_MAX_ALG_NAME];
18498e8ec596SKim Phillips 	char driver_name[CRYPTO_MAX_ALG_NAME];
18508e8ec596SKim Phillips 	unsigned int blocksize;
1851885e9e2fSYuan Kang 	u32 type;
1852885e9e2fSYuan Kang 	union {
1853885e9e2fSYuan Kang 		struct ablkcipher_alg ablkcipher;
1854885e9e2fSYuan Kang 	} template_u;
18558e8ec596SKim Phillips 	u32 class1_alg_type;
18568e8ec596SKim Phillips 	u32 class2_alg_type;
18578e8ec596SKim Phillips };
18588e8ec596SKim Phillips 
18598e8ec596SKim Phillips static struct caam_alg_template driver_algs[] = {
1860acdca31dSYuan Kang 	/* ablkcipher descriptor */
1861acdca31dSYuan Kang 	{
1862acdca31dSYuan Kang 		.name = "cbc(aes)",
1863acdca31dSYuan Kang 		.driver_name = "cbc-aes-caam",
1864acdca31dSYuan Kang 		.blocksize = AES_BLOCK_SIZE,
18657222d1a3SCatalin Vasile 		.type = CRYPTO_ALG_TYPE_GIVCIPHER,
1866acdca31dSYuan Kang 		.template_ablkcipher = {
1867acdca31dSYuan Kang 			.setkey = ablkcipher_setkey,
1868acdca31dSYuan Kang 			.encrypt = ablkcipher_encrypt,
1869acdca31dSYuan Kang 			.decrypt = ablkcipher_decrypt,
18707222d1a3SCatalin Vasile 			.givencrypt = ablkcipher_givencrypt,
18717222d1a3SCatalin Vasile 			.geniv = "<built-in>",
1872acdca31dSYuan Kang 			.min_keysize = AES_MIN_KEY_SIZE,
1873acdca31dSYuan Kang 			.max_keysize = AES_MAX_KEY_SIZE,
1874acdca31dSYuan Kang 			.ivsize = AES_BLOCK_SIZE,
1875acdca31dSYuan Kang 			},
1876acdca31dSYuan Kang 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
1877acdca31dSYuan Kang 	},
1878acdca31dSYuan Kang 	{
1879acdca31dSYuan Kang 		.name = "cbc(des3_ede)",
1880acdca31dSYuan Kang 		.driver_name = "cbc-3des-caam",
1881acdca31dSYuan Kang 		.blocksize = DES3_EDE_BLOCK_SIZE,
1882ff2c3a3bSCatalin Vasile 		.type = CRYPTO_ALG_TYPE_GIVCIPHER,
1883acdca31dSYuan Kang 		.template_ablkcipher = {
1884acdca31dSYuan Kang 			.setkey = ablkcipher_setkey,
1885acdca31dSYuan Kang 			.encrypt = ablkcipher_encrypt,
1886acdca31dSYuan Kang 			.decrypt = ablkcipher_decrypt,
1887ff2c3a3bSCatalin Vasile 			.givencrypt = ablkcipher_givencrypt,
1888ff2c3a3bSCatalin Vasile 			.geniv = "<built-in>",
1889acdca31dSYuan Kang 			.min_keysize = DES3_EDE_KEY_SIZE,
1890acdca31dSYuan Kang 			.max_keysize = DES3_EDE_KEY_SIZE,
1891acdca31dSYuan Kang 			.ivsize = DES3_EDE_BLOCK_SIZE,
1892acdca31dSYuan Kang 			},
1893acdca31dSYuan Kang 		.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
1894acdca31dSYuan Kang 	},
1895acdca31dSYuan Kang 	{
1896acdca31dSYuan Kang 		.name = "cbc(des)",
1897acdca31dSYuan Kang 		.driver_name = "cbc-des-caam",
1898acdca31dSYuan Kang 		.blocksize = DES_BLOCK_SIZE,
1899ff2c3a3bSCatalin Vasile 		.type = CRYPTO_ALG_TYPE_GIVCIPHER,
1900acdca31dSYuan Kang 		.template_ablkcipher = {
1901acdca31dSYuan Kang 			.setkey = ablkcipher_setkey,
1902acdca31dSYuan Kang 			.encrypt = ablkcipher_encrypt,
1903acdca31dSYuan Kang 			.decrypt = ablkcipher_decrypt,
1904ff2c3a3bSCatalin Vasile 			.givencrypt = ablkcipher_givencrypt,
1905ff2c3a3bSCatalin Vasile 			.geniv = "<built-in>",
1906acdca31dSYuan Kang 			.min_keysize = DES_KEY_SIZE,
1907acdca31dSYuan Kang 			.max_keysize = DES_KEY_SIZE,
1908acdca31dSYuan Kang 			.ivsize = DES_BLOCK_SIZE,
1909acdca31dSYuan Kang 			},
1910acdca31dSYuan Kang 		.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
19112b22f6c5SCatalin Vasile 	},
19122b22f6c5SCatalin Vasile 	{
19132b22f6c5SCatalin Vasile 		.name = "ctr(aes)",
19142b22f6c5SCatalin Vasile 		.driver_name = "ctr-aes-caam",
19152b22f6c5SCatalin Vasile 		.blocksize = 1,
19162b22f6c5SCatalin Vasile 		.type = CRYPTO_ALG_TYPE_ABLKCIPHER,
19172b22f6c5SCatalin Vasile 		.template_ablkcipher = {
19182b22f6c5SCatalin Vasile 			.setkey = ablkcipher_setkey,
19192b22f6c5SCatalin Vasile 			.encrypt = ablkcipher_encrypt,
19202b22f6c5SCatalin Vasile 			.decrypt = ablkcipher_decrypt,
19212b22f6c5SCatalin Vasile 			.geniv = "chainiv",
19222b22f6c5SCatalin Vasile 			.min_keysize = AES_MIN_KEY_SIZE,
19232b22f6c5SCatalin Vasile 			.max_keysize = AES_MAX_KEY_SIZE,
19242b22f6c5SCatalin Vasile 			.ivsize = AES_BLOCK_SIZE,
19252b22f6c5SCatalin Vasile 			},
19262b22f6c5SCatalin Vasile 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CTR_MOD128,
1927a5f57cffSCatalin Vasile 	},
1928a5f57cffSCatalin Vasile 	{
1929a5f57cffSCatalin Vasile 		.name = "rfc3686(ctr(aes))",
1930a5f57cffSCatalin Vasile 		.driver_name = "rfc3686-ctr-aes-caam",
1931a5f57cffSCatalin Vasile 		.blocksize = 1,
19327222d1a3SCatalin Vasile 		.type = CRYPTO_ALG_TYPE_GIVCIPHER,
1933a5f57cffSCatalin Vasile 		.template_ablkcipher = {
1934a5f57cffSCatalin Vasile 			.setkey = ablkcipher_setkey,
1935a5f57cffSCatalin Vasile 			.encrypt = ablkcipher_encrypt,
1936a5f57cffSCatalin Vasile 			.decrypt = ablkcipher_decrypt,
19377222d1a3SCatalin Vasile 			.givencrypt = ablkcipher_givencrypt,
19387222d1a3SCatalin Vasile 			.geniv = "<built-in>",
1939a5f57cffSCatalin Vasile 			.min_keysize = AES_MIN_KEY_SIZE +
1940a5f57cffSCatalin Vasile 				       CTR_RFC3686_NONCE_SIZE,
1941a5f57cffSCatalin Vasile 			.max_keysize = AES_MAX_KEY_SIZE +
1942a5f57cffSCatalin Vasile 				       CTR_RFC3686_NONCE_SIZE,
1943a5f57cffSCatalin Vasile 			.ivsize = CTR_RFC3686_IV_SIZE,
1944a5f57cffSCatalin Vasile 			},
1945a5f57cffSCatalin Vasile 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CTR_MOD128,
1946c6415a60SCatalin Vasile 	},
1947c6415a60SCatalin Vasile 	{
1948c6415a60SCatalin Vasile 		.name = "xts(aes)",
1949c6415a60SCatalin Vasile 		.driver_name = "xts-aes-caam",
1950c6415a60SCatalin Vasile 		.blocksize = AES_BLOCK_SIZE,
1951c6415a60SCatalin Vasile 		.type = CRYPTO_ALG_TYPE_ABLKCIPHER,
1952c6415a60SCatalin Vasile 		.template_ablkcipher = {
1953c6415a60SCatalin Vasile 			.setkey = xts_ablkcipher_setkey,
1954c6415a60SCatalin Vasile 			.encrypt = ablkcipher_encrypt,
1955c6415a60SCatalin Vasile 			.decrypt = ablkcipher_decrypt,
1956c6415a60SCatalin Vasile 			.geniv = "eseqiv",
1957c6415a60SCatalin Vasile 			.min_keysize = 2 * AES_MIN_KEY_SIZE,
1958c6415a60SCatalin Vasile 			.max_keysize = 2 * AES_MAX_KEY_SIZE,
1959c6415a60SCatalin Vasile 			.ivsize = AES_BLOCK_SIZE,
1960c6415a60SCatalin Vasile 			},
1961c6415a60SCatalin Vasile 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_XTS,
1962c6415a60SCatalin Vasile 	},
19638e8ec596SKim Phillips };
19648e8ec596SKim Phillips 
1965f2147b88SHerbert Xu static struct caam_aead_alg driver_aeads[] = {
1966f2147b88SHerbert Xu 	{
1967f2147b88SHerbert Xu 		.aead = {
1968f2147b88SHerbert Xu 			.base = {
1969f2147b88SHerbert Xu 				.cra_name = "rfc4106(gcm(aes))",
1970f2147b88SHerbert Xu 				.cra_driver_name = "rfc4106-gcm-aes-caam",
1971f2147b88SHerbert Xu 				.cra_blocksize = 1,
1972f2147b88SHerbert Xu 			},
1973f2147b88SHerbert Xu 			.setkey = rfc4106_setkey,
1974f2147b88SHerbert Xu 			.setauthsize = rfc4106_setauthsize,
197546218750SHerbert Xu 			.encrypt = ipsec_gcm_encrypt,
197646218750SHerbert Xu 			.decrypt = ipsec_gcm_decrypt,
1977f2147b88SHerbert Xu 			.ivsize = 8,
1978f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
1979f2147b88SHerbert Xu 		},
1980f2147b88SHerbert Xu 		.caam = {
1981f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
1982f2147b88SHerbert Xu 		},
1983f2147b88SHerbert Xu 	},
1984f2147b88SHerbert Xu 	{
1985f2147b88SHerbert Xu 		.aead = {
1986f2147b88SHerbert Xu 			.base = {
1987f2147b88SHerbert Xu 				.cra_name = "rfc4543(gcm(aes))",
1988f2147b88SHerbert Xu 				.cra_driver_name = "rfc4543-gcm-aes-caam",
1989f2147b88SHerbert Xu 				.cra_blocksize = 1,
1990f2147b88SHerbert Xu 			},
1991f2147b88SHerbert Xu 			.setkey = rfc4543_setkey,
1992f2147b88SHerbert Xu 			.setauthsize = rfc4543_setauthsize,
199346218750SHerbert Xu 			.encrypt = ipsec_gcm_encrypt,
199446218750SHerbert Xu 			.decrypt = ipsec_gcm_decrypt,
1995f2147b88SHerbert Xu 			.ivsize = 8,
1996f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
1997f2147b88SHerbert Xu 		},
1998f2147b88SHerbert Xu 		.caam = {
1999f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
2000f2147b88SHerbert Xu 		},
2001f2147b88SHerbert Xu 	},
2002f2147b88SHerbert Xu 	/* Galois Counter Mode */
2003f2147b88SHerbert Xu 	{
2004f2147b88SHerbert Xu 		.aead = {
2005f2147b88SHerbert Xu 			.base = {
2006f2147b88SHerbert Xu 				.cra_name = "gcm(aes)",
2007f2147b88SHerbert Xu 				.cra_driver_name = "gcm-aes-caam",
2008f2147b88SHerbert Xu 				.cra_blocksize = 1,
2009f2147b88SHerbert Xu 			},
2010f2147b88SHerbert Xu 			.setkey = gcm_setkey,
2011f2147b88SHerbert Xu 			.setauthsize = gcm_setauthsize,
2012f2147b88SHerbert Xu 			.encrypt = gcm_encrypt,
2013f2147b88SHerbert Xu 			.decrypt = gcm_decrypt,
2014f2147b88SHerbert Xu 			.ivsize = 12,
2015f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
2016f2147b88SHerbert Xu 		},
2017f2147b88SHerbert Xu 		.caam = {
2018f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
2019f2147b88SHerbert Xu 		},
2020f2147b88SHerbert Xu 	},
2021479bcc7cSHerbert Xu 	/* single-pass ipsec_esp descriptor */
2022479bcc7cSHerbert Xu 	{
2023479bcc7cSHerbert Xu 		.aead = {
2024479bcc7cSHerbert Xu 			.base = {
2025479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),"
2026479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2027479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2028479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2029479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2030479bcc7cSHerbert Xu 			},
2031479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2032479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2033479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2034479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2035479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2036479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2037479bcc7cSHerbert Xu 		},
2038479bcc7cSHerbert Xu 		.caam = {
2039479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2040479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2041479bcc7cSHerbert Xu 		},
2042479bcc7cSHerbert Xu 	},
2043479bcc7cSHerbert Xu 	{
2044479bcc7cSHerbert Xu 		.aead = {
2045479bcc7cSHerbert Xu 			.base = {
2046479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
2047479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2048479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2049479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2050479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2051479bcc7cSHerbert Xu 			},
2052479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2053479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2054479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2055479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2056479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2057479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2058479bcc7cSHerbert Xu 		},
2059479bcc7cSHerbert Xu 		.caam = {
2060479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2061479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2062479bcc7cSHerbert Xu 		},
2063479bcc7cSHerbert Xu 	},
2064479bcc7cSHerbert Xu 	{
2065479bcc7cSHerbert Xu 		.aead = {
2066479bcc7cSHerbert Xu 			.base = {
2067479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
2068479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2069479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2070479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2071479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2072479bcc7cSHerbert Xu 			},
2073479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2074479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2075479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2076479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2077479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2078479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2079479bcc7cSHerbert Xu 		},
2080479bcc7cSHerbert Xu 		.caam = {
2081479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2082479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2083479bcc7cSHerbert Xu 		},
2084479bcc7cSHerbert Xu 	},
2085479bcc7cSHerbert Xu 	{
2086479bcc7cSHerbert Xu 		.aead = {
2087479bcc7cSHerbert Xu 			.base = {
2088479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
2089479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2090479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
2091479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2092479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2093479bcc7cSHerbert Xu 			},
2094479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2095479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2096479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2097479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2098479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2099479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2100479bcc7cSHerbert Xu 		},
2101479bcc7cSHerbert Xu 		.caam = {
2102479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2103479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2104479bcc7cSHerbert Xu 		},
2105479bcc7cSHerbert Xu 	},
2106479bcc7cSHerbert Xu 	{
2107479bcc7cSHerbert Xu 		.aead = {
2108479bcc7cSHerbert Xu 			.base = {
2109479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
2110479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2111479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
2112479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2113479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2114479bcc7cSHerbert Xu 			},
2115479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2116479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2117479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2118479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2119479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2120479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2121479bcc7cSHerbert Xu 		},
2122479bcc7cSHerbert Xu 		.caam = {
2123479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2124479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2125479bcc7cSHerbert Xu 		},
2126479bcc7cSHerbert Xu 	},
2127479bcc7cSHerbert Xu 	{
2128479bcc7cSHerbert Xu 		.aead = {
2129479bcc7cSHerbert Xu 			.base = {
2130479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
2131479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2132479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
2133479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2134479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2135479bcc7cSHerbert Xu 			},
2136479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2137479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2138479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2139479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2140479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2141479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2142479bcc7cSHerbert Xu 		},
2143479bcc7cSHerbert Xu 		.caam = {
2144479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2145479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2146479bcc7cSHerbert Xu 		},
2147479bcc7cSHerbert Xu 	},
2148479bcc7cSHerbert Xu 	{
2149479bcc7cSHerbert Xu 		.aead = {
2150479bcc7cSHerbert Xu 			.base = {
2151479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(aes))",
2152479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2153479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2154479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2155479bcc7cSHerbert Xu 			},
2156479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2157479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2158479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2159479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2160479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2161479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2162479bcc7cSHerbert Xu 		},
2163479bcc7cSHerbert Xu 		.caam = {
2164479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2165479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2166479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2167479bcc7cSHerbert Xu 		},
2168479bcc7cSHerbert Xu 	},
2169479bcc7cSHerbert Xu 	{
2170479bcc7cSHerbert Xu 		.aead = {
2171479bcc7cSHerbert Xu 			.base = {
2172479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
2173479bcc7cSHerbert Xu 					    "cbc(aes)))",
2174479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
2175479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2176479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2177479bcc7cSHerbert Xu 			},
2178479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2179479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2180479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
21818b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2182479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2183479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2184479bcc7cSHerbert Xu 		},
2185479bcc7cSHerbert Xu 		.caam = {
2186479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2187479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2188479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2189479bcc7cSHerbert Xu 			.geniv = true,
2190479bcc7cSHerbert Xu 		},
2191479bcc7cSHerbert Xu 	},
2192479bcc7cSHerbert Xu 	{
2193479bcc7cSHerbert Xu 		.aead = {
2194479bcc7cSHerbert Xu 			.base = {
2195479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),cbc(aes))",
2196479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2197479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2198479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2199479bcc7cSHerbert Xu 			},
2200479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2201479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2202479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2203479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2204479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2205479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2206479bcc7cSHerbert Xu 		},
2207479bcc7cSHerbert Xu 		.caam = {
2208479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2209479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2210479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2211479bcc7cSHerbert Xu 		},
2212479bcc7cSHerbert Xu 	},
2213479bcc7cSHerbert Xu 	{
2214479bcc7cSHerbert Xu 		.aead = {
2215479bcc7cSHerbert Xu 			.base = {
2216479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
2217479bcc7cSHerbert Xu 					    "cbc(aes)))",
2218479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2219479bcc7cSHerbert Xu 						   "hmac-sha1-cbc-aes-caam",
2220479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2221479bcc7cSHerbert Xu 			},
2222479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2223479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2224479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
22258b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2226479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2227479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2228479bcc7cSHerbert Xu 		},
2229479bcc7cSHerbert Xu 		.caam = {
2230479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2231479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2232479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2233479bcc7cSHerbert Xu 			.geniv = true,
2234479bcc7cSHerbert Xu 		},
2235479bcc7cSHerbert Xu 	},
2236479bcc7cSHerbert Xu 	{
2237479bcc7cSHerbert Xu 		.aead = {
2238479bcc7cSHerbert Xu 			.base = {
2239479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),cbc(aes))",
2240479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2241479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2242479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2243479bcc7cSHerbert Xu 			},
2244479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2245479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2246479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2247479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2248479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2249479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2250479bcc7cSHerbert Xu 		},
2251479bcc7cSHerbert Xu 		.caam = {
2252479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2253479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2254479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2255479bcc7cSHerbert Xu 		},
2256479bcc7cSHerbert Xu 	},
2257479bcc7cSHerbert Xu 	{
2258479bcc7cSHerbert Xu 		.aead = {
2259479bcc7cSHerbert Xu 			.base = {
2260479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
2261479bcc7cSHerbert Xu 					    "cbc(aes)))",
2262479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2263479bcc7cSHerbert Xu 						   "hmac-sha224-cbc-aes-caam",
2264479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2265479bcc7cSHerbert Xu 			},
2266479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2267479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2268479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
22698b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2270479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2271479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2272479bcc7cSHerbert Xu 		},
2273479bcc7cSHerbert Xu 		.caam = {
2274479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2275479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2276479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2277479bcc7cSHerbert Xu 			.geniv = true,
2278479bcc7cSHerbert Xu 		},
2279479bcc7cSHerbert Xu 	},
2280479bcc7cSHerbert Xu 	{
2281479bcc7cSHerbert Xu 		.aead = {
2282479bcc7cSHerbert Xu 			.base = {
2283479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),cbc(aes))",
2284479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
2285479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2286479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2287479bcc7cSHerbert Xu 			},
2288479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2289479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2290479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2291479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2292479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2293479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2294479bcc7cSHerbert Xu 		},
2295479bcc7cSHerbert Xu 		.caam = {
2296479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2297479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2298479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2299479bcc7cSHerbert Xu 		},
2300479bcc7cSHerbert Xu 	},
2301479bcc7cSHerbert Xu 	{
2302479bcc7cSHerbert Xu 		.aead = {
2303479bcc7cSHerbert Xu 			.base = {
2304479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
2305479bcc7cSHerbert Xu 					    "cbc(aes)))",
2306479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2307479bcc7cSHerbert Xu 						   "hmac-sha256-cbc-aes-caam",
2308479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2309479bcc7cSHerbert Xu 			},
2310479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2311479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2312479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
23138b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2314479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2315479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2316479bcc7cSHerbert Xu 		},
2317479bcc7cSHerbert Xu 		.caam = {
2318479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2319479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2320479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2321479bcc7cSHerbert Xu 			.geniv = true,
2322479bcc7cSHerbert Xu 		},
2323479bcc7cSHerbert Xu 	},
2324479bcc7cSHerbert Xu 	{
2325479bcc7cSHerbert Xu 		.aead = {
2326479bcc7cSHerbert Xu 			.base = {
2327479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),cbc(aes))",
2328479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
2329479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2330479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2331479bcc7cSHerbert Xu 			},
2332479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2333479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2334479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2335479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2336479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2337479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2338479bcc7cSHerbert Xu 		},
2339479bcc7cSHerbert Xu 		.caam = {
2340479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2341479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2342479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2343479bcc7cSHerbert Xu 		},
2344479bcc7cSHerbert Xu 	},
2345479bcc7cSHerbert Xu 	{
2346479bcc7cSHerbert Xu 		.aead = {
2347479bcc7cSHerbert Xu 			.base = {
2348479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
2349479bcc7cSHerbert Xu 					    "cbc(aes)))",
2350479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2351479bcc7cSHerbert Xu 						   "hmac-sha384-cbc-aes-caam",
2352479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2353479bcc7cSHerbert Xu 			},
2354479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2355479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2356479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
23578b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2358479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2359479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2360479bcc7cSHerbert Xu 		},
2361479bcc7cSHerbert Xu 		.caam = {
2362479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2363479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2364479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2365479bcc7cSHerbert Xu 			.geniv = true,
2366479bcc7cSHerbert Xu 		},
2367479bcc7cSHerbert Xu 	},
2368479bcc7cSHerbert Xu 	{
2369479bcc7cSHerbert Xu 		.aead = {
2370479bcc7cSHerbert Xu 			.base = {
2371479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),cbc(aes))",
2372479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
2373479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2374479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2375479bcc7cSHerbert Xu 			},
2376479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2377479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2378479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2379479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2380479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2381479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2382479bcc7cSHerbert Xu 		},
2383479bcc7cSHerbert Xu 		.caam = {
2384479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2385479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2386479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2387479bcc7cSHerbert Xu 		},
2388479bcc7cSHerbert Xu 	},
2389479bcc7cSHerbert Xu 	{
2390479bcc7cSHerbert Xu 		.aead = {
2391479bcc7cSHerbert Xu 			.base = {
2392479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
2393479bcc7cSHerbert Xu 					    "cbc(aes)))",
2394479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2395479bcc7cSHerbert Xu 						   "hmac-sha512-cbc-aes-caam",
2396479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2397479bcc7cSHerbert Xu 			},
2398479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2399479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2400479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
24018b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2402479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2403479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2404479bcc7cSHerbert Xu 		},
2405479bcc7cSHerbert Xu 		.caam = {
2406479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2407479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2408479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2409479bcc7cSHerbert Xu 			.geniv = true,
2410479bcc7cSHerbert Xu 		},
2411479bcc7cSHerbert Xu 	},
2412479bcc7cSHerbert Xu 	{
2413479bcc7cSHerbert Xu 		.aead = {
2414479bcc7cSHerbert Xu 			.base = {
2415479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2416479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2417479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2418479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2419479bcc7cSHerbert Xu 			},
2420479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2421479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2422479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2423479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2424479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2425479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2426479bcc7cSHerbert Xu 		},
2427479bcc7cSHerbert Xu 		.caam = {
2428479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2429479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2430479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2431479bcc7cSHerbert Xu 		}
2432479bcc7cSHerbert Xu 	},
2433479bcc7cSHerbert Xu 	{
2434479bcc7cSHerbert Xu 		.aead = {
2435479bcc7cSHerbert Xu 			.base = {
2436479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
2437479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2438479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
2439479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2440479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2441479bcc7cSHerbert Xu 			},
2442479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2443479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2444479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
24458b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2446479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2447479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2448479bcc7cSHerbert Xu 		},
2449479bcc7cSHerbert Xu 		.caam = {
2450479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2451479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2452479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2453479bcc7cSHerbert Xu 			.geniv = true,
2454479bcc7cSHerbert Xu 		}
2455479bcc7cSHerbert Xu 	},
2456479bcc7cSHerbert Xu 	{
2457479bcc7cSHerbert Xu 		.aead = {
2458479bcc7cSHerbert Xu 			.base = {
2459479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
2460479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2461479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2462479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2463479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2464479bcc7cSHerbert Xu 			},
2465479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2466479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2467479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2468479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2469479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2470479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2471479bcc7cSHerbert Xu 		},
2472479bcc7cSHerbert Xu 		.caam = {
2473479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2474479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2475479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2476479bcc7cSHerbert Xu 		},
2477479bcc7cSHerbert Xu 	},
2478479bcc7cSHerbert Xu 	{
2479479bcc7cSHerbert Xu 		.aead = {
2480479bcc7cSHerbert Xu 			.base = {
2481479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
2482479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2483479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2484479bcc7cSHerbert Xu 						   "hmac-sha1-"
2485479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2486479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2487479bcc7cSHerbert Xu 			},
2488479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2489479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2490479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
24918b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2492479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2493479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2494479bcc7cSHerbert Xu 		},
2495479bcc7cSHerbert Xu 		.caam = {
2496479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2497479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2498479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2499479bcc7cSHerbert Xu 			.geniv = true,
2500479bcc7cSHerbert Xu 		},
2501479bcc7cSHerbert Xu 	},
2502479bcc7cSHerbert Xu 	{
2503479bcc7cSHerbert Xu 		.aead = {
2504479bcc7cSHerbert Xu 			.base = {
2505479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
2506479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2507479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2508479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2509479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2510479bcc7cSHerbert Xu 			},
2511479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2512479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2513479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2514479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2515479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2516479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2517479bcc7cSHerbert Xu 		},
2518479bcc7cSHerbert Xu 		.caam = {
2519479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2520479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2521479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2522479bcc7cSHerbert Xu 		},
2523479bcc7cSHerbert Xu 	},
2524479bcc7cSHerbert Xu 	{
2525479bcc7cSHerbert Xu 		.aead = {
2526479bcc7cSHerbert Xu 			.base = {
2527479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
2528479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2529479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2530479bcc7cSHerbert Xu 						   "hmac-sha224-"
2531479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2532479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2533479bcc7cSHerbert Xu 			},
2534479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2535479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2536479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
25378b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2538479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2539479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2540479bcc7cSHerbert Xu 		},
2541479bcc7cSHerbert Xu 		.caam = {
2542479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2543479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2544479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2545479bcc7cSHerbert Xu 			.geniv = true,
2546479bcc7cSHerbert Xu 		},
2547479bcc7cSHerbert Xu 	},
2548479bcc7cSHerbert Xu 	{
2549479bcc7cSHerbert Xu 		.aead = {
2550479bcc7cSHerbert Xu 			.base = {
2551479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
2552479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2553479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
2554479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2555479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2556479bcc7cSHerbert Xu 			},
2557479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2558479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2559479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2560479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2561479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2562479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2563479bcc7cSHerbert Xu 		},
2564479bcc7cSHerbert Xu 		.caam = {
2565479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2566479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2567479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2568479bcc7cSHerbert Xu 		},
2569479bcc7cSHerbert Xu 	},
2570479bcc7cSHerbert Xu 	{
2571479bcc7cSHerbert Xu 		.aead = {
2572479bcc7cSHerbert Xu 			.base = {
2573479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
2574479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2575479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2576479bcc7cSHerbert Xu 						   "hmac-sha256-"
2577479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2578479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2579479bcc7cSHerbert Xu 			},
2580479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2581479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2582479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
25838b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2584479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2585479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2586479bcc7cSHerbert Xu 		},
2587479bcc7cSHerbert Xu 		.caam = {
2588479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2589479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2590479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2591479bcc7cSHerbert Xu 			.geniv = true,
2592479bcc7cSHerbert Xu 		},
2593479bcc7cSHerbert Xu 	},
2594479bcc7cSHerbert Xu 	{
2595479bcc7cSHerbert Xu 		.aead = {
2596479bcc7cSHerbert Xu 			.base = {
2597479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
2598479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2599479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
2600479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2601479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2602479bcc7cSHerbert Xu 			},
2603479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2604479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2605479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2606479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2607479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2608479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2609479bcc7cSHerbert Xu 		},
2610479bcc7cSHerbert Xu 		.caam = {
2611479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2612479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2613479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2614479bcc7cSHerbert Xu 		},
2615479bcc7cSHerbert Xu 	},
2616479bcc7cSHerbert Xu 	{
2617479bcc7cSHerbert Xu 		.aead = {
2618479bcc7cSHerbert Xu 			.base = {
2619479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
2620479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2621479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2622479bcc7cSHerbert Xu 						   "hmac-sha384-"
2623479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2624479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2625479bcc7cSHerbert Xu 			},
2626479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2627479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2628479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
26298b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2630479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2631479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2632479bcc7cSHerbert Xu 		},
2633479bcc7cSHerbert Xu 		.caam = {
2634479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2635479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2636479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2637479bcc7cSHerbert Xu 			.geniv = true,
2638479bcc7cSHerbert Xu 		},
2639479bcc7cSHerbert Xu 	},
2640479bcc7cSHerbert Xu 	{
2641479bcc7cSHerbert Xu 		.aead = {
2642479bcc7cSHerbert Xu 			.base = {
2643479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
2644479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2645479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
2646479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2647479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2648479bcc7cSHerbert Xu 			},
2649479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2650479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2651479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2652479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2653479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2654479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2655479bcc7cSHerbert Xu 		},
2656479bcc7cSHerbert Xu 		.caam = {
2657479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2658479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2659479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2660479bcc7cSHerbert Xu 		},
2661479bcc7cSHerbert Xu 	},
2662479bcc7cSHerbert Xu 	{
2663479bcc7cSHerbert Xu 		.aead = {
2664479bcc7cSHerbert Xu 			.base = {
2665479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
2666479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2667479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2668479bcc7cSHerbert Xu 						   "hmac-sha512-"
2669479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2670479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2671479bcc7cSHerbert Xu 			},
2672479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2673479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2674479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
26758b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2676479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2677479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2678479bcc7cSHerbert Xu 		},
2679479bcc7cSHerbert Xu 		.caam = {
2680479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2681479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2682479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2683479bcc7cSHerbert Xu 			.geniv = true,
2684479bcc7cSHerbert Xu 		},
2685479bcc7cSHerbert Xu 	},
2686479bcc7cSHerbert Xu 	{
2687479bcc7cSHerbert Xu 		.aead = {
2688479bcc7cSHerbert Xu 			.base = {
2689479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(des))",
2690479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2691479bcc7cSHerbert Xu 						   "cbc-des-caam",
2692479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2693479bcc7cSHerbert Xu 			},
2694479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2695479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2696479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2697479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2698479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2699479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2700479bcc7cSHerbert Xu 		},
2701479bcc7cSHerbert Xu 		.caam = {
2702479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2703479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2704479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2705479bcc7cSHerbert Xu 		},
2706479bcc7cSHerbert Xu 	},
2707479bcc7cSHerbert Xu 	{
2708479bcc7cSHerbert Xu 		.aead = {
2709479bcc7cSHerbert Xu 			.base = {
2710479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
2711479bcc7cSHerbert Xu 					    "cbc(des)))",
2712479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
2713479bcc7cSHerbert Xu 						   "cbc-des-caam",
2714479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2715479bcc7cSHerbert Xu 			},
2716479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2717479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2718479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
27198b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2720479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2721479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2722479bcc7cSHerbert Xu 		},
2723479bcc7cSHerbert Xu 		.caam = {
2724479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2725479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2726479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2727479bcc7cSHerbert Xu 			.geniv = true,
2728479bcc7cSHerbert Xu 		},
2729479bcc7cSHerbert Xu 	},
2730479bcc7cSHerbert Xu 	{
2731479bcc7cSHerbert Xu 		.aead = {
2732479bcc7cSHerbert Xu 			.base = {
2733479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),cbc(des))",
2734479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2735479bcc7cSHerbert Xu 						   "cbc-des-caam",
2736479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2737479bcc7cSHerbert Xu 			},
2738479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2739479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2740479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2741479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2742479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2743479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2744479bcc7cSHerbert Xu 		},
2745479bcc7cSHerbert Xu 		.caam = {
2746479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2747479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2748479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2749479bcc7cSHerbert Xu 		},
2750479bcc7cSHerbert Xu 	},
2751479bcc7cSHerbert Xu 	{
2752479bcc7cSHerbert Xu 		.aead = {
2753479bcc7cSHerbert Xu 			.base = {
2754479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
2755479bcc7cSHerbert Xu 					    "cbc(des)))",
2756479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2757479bcc7cSHerbert Xu 						   "hmac-sha1-cbc-des-caam",
2758479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2759479bcc7cSHerbert Xu 			},
2760479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2761479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2762479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
27638b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2764479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2765479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2766479bcc7cSHerbert Xu 		},
2767479bcc7cSHerbert Xu 		.caam = {
2768479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2769479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2770479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2771479bcc7cSHerbert Xu 			.geniv = true,
2772479bcc7cSHerbert Xu 		},
2773479bcc7cSHerbert Xu 	},
2774479bcc7cSHerbert Xu 	{
2775479bcc7cSHerbert Xu 		.aead = {
2776479bcc7cSHerbert Xu 			.base = {
2777479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),cbc(des))",
2778479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2779479bcc7cSHerbert Xu 						   "cbc-des-caam",
2780479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2781479bcc7cSHerbert Xu 			},
2782479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2783479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2784479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2785479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2786479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2787479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2788479bcc7cSHerbert Xu 		},
2789479bcc7cSHerbert Xu 		.caam = {
2790479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2791479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2792479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2793479bcc7cSHerbert Xu 		},
2794479bcc7cSHerbert Xu 	},
2795479bcc7cSHerbert Xu 	{
2796479bcc7cSHerbert Xu 		.aead = {
2797479bcc7cSHerbert Xu 			.base = {
2798479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
2799479bcc7cSHerbert Xu 					    "cbc(des)))",
2800479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2801479bcc7cSHerbert Xu 						   "hmac-sha224-cbc-des-caam",
2802479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2803479bcc7cSHerbert Xu 			},
2804479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2805479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2806479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
28078b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2808479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2809479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2810479bcc7cSHerbert Xu 		},
2811479bcc7cSHerbert Xu 		.caam = {
2812479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2813479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2814479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2815479bcc7cSHerbert Xu 			.geniv = true,
2816479bcc7cSHerbert Xu 		},
2817479bcc7cSHerbert Xu 	},
2818479bcc7cSHerbert Xu 	{
2819479bcc7cSHerbert Xu 		.aead = {
2820479bcc7cSHerbert Xu 			.base = {
2821479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),cbc(des))",
2822479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
2823479bcc7cSHerbert Xu 						   "cbc-des-caam",
2824479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2825479bcc7cSHerbert Xu 			},
2826479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2827479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2828479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2829479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2830479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2831479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2832479bcc7cSHerbert Xu 		},
2833479bcc7cSHerbert Xu 		.caam = {
2834479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2835479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2836479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2837479bcc7cSHerbert Xu 		},
2838479bcc7cSHerbert Xu 	},
2839479bcc7cSHerbert Xu 	{
2840479bcc7cSHerbert Xu 		.aead = {
2841479bcc7cSHerbert Xu 			.base = {
2842479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
2843479bcc7cSHerbert Xu 					    "cbc(des)))",
2844479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2845479bcc7cSHerbert Xu 						   "hmac-sha256-cbc-des-caam",
2846479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2847479bcc7cSHerbert Xu 			},
2848479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2849479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2850479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
28518b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2852479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2853479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2854479bcc7cSHerbert Xu 		},
2855479bcc7cSHerbert Xu 		.caam = {
2856479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2857479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2858479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2859479bcc7cSHerbert Xu 			.geniv = true,
2860479bcc7cSHerbert Xu 		},
2861479bcc7cSHerbert Xu 	},
2862479bcc7cSHerbert Xu 	{
2863479bcc7cSHerbert Xu 		.aead = {
2864479bcc7cSHerbert Xu 			.base = {
2865479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),cbc(des))",
2866479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
2867479bcc7cSHerbert Xu 						   "cbc-des-caam",
2868479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2869479bcc7cSHerbert Xu 			},
2870479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2871479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2872479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2873479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2874479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2875479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2876479bcc7cSHerbert Xu 		},
2877479bcc7cSHerbert Xu 		.caam = {
2878479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2879479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2880479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2881479bcc7cSHerbert Xu 		},
2882479bcc7cSHerbert Xu 	},
2883479bcc7cSHerbert Xu 	{
2884479bcc7cSHerbert Xu 		.aead = {
2885479bcc7cSHerbert Xu 			.base = {
2886479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
2887479bcc7cSHerbert Xu 					    "cbc(des)))",
2888479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2889479bcc7cSHerbert Xu 						   "hmac-sha384-cbc-des-caam",
2890479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2891479bcc7cSHerbert Xu 			},
2892479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2893479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2894479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
28958b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2896479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2897479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2898479bcc7cSHerbert Xu 		},
2899479bcc7cSHerbert Xu 		.caam = {
2900479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2901479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2902479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2903479bcc7cSHerbert Xu 			.geniv = true,
2904479bcc7cSHerbert Xu 		},
2905479bcc7cSHerbert Xu 	},
2906479bcc7cSHerbert Xu 	{
2907479bcc7cSHerbert Xu 		.aead = {
2908479bcc7cSHerbert Xu 			.base = {
2909479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),cbc(des))",
2910479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
2911479bcc7cSHerbert Xu 						   "cbc-des-caam",
2912479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2913479bcc7cSHerbert Xu 			},
2914479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2915479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2916479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2917479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2918479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2919479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2920479bcc7cSHerbert Xu 		},
2921479bcc7cSHerbert Xu 		.caam = {
2922479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2923479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2924479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2925479bcc7cSHerbert Xu 		},
2926479bcc7cSHerbert Xu 	},
2927479bcc7cSHerbert Xu 	{
2928479bcc7cSHerbert Xu 		.aead = {
2929479bcc7cSHerbert Xu 			.base = {
2930479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
2931479bcc7cSHerbert Xu 					    "cbc(des)))",
2932479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2933479bcc7cSHerbert Xu 						   "hmac-sha512-cbc-des-caam",
2934479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2935479bcc7cSHerbert Xu 			},
2936479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2937479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2938479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
29398b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2940479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2941479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2942479bcc7cSHerbert Xu 		},
2943479bcc7cSHerbert Xu 		.caam = {
2944479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2945479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2946479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2947479bcc7cSHerbert Xu 			.geniv = true,
2948479bcc7cSHerbert Xu 		},
2949479bcc7cSHerbert Xu 	},
2950479bcc7cSHerbert Xu 	{
2951479bcc7cSHerbert Xu 		.aead = {
2952479bcc7cSHerbert Xu 			.base = {
2953479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),"
2954479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
2955479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2956479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
2957479bcc7cSHerbert Xu 				.cra_blocksize = 1,
2958479bcc7cSHerbert Xu 			},
2959479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2960479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2961479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2962479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2963479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
2964479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2965479bcc7cSHerbert Xu 		},
2966479bcc7cSHerbert Xu 		.caam = {
2967479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
2968479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
2969479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2970479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2971479bcc7cSHerbert Xu 			.rfc3686 = true,
2972479bcc7cSHerbert Xu 		},
2973479bcc7cSHerbert Xu 	},
2974479bcc7cSHerbert Xu 	{
2975479bcc7cSHerbert Xu 		.aead = {
2976479bcc7cSHerbert Xu 			.base = {
2977479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
2978479bcc7cSHerbert Xu 					    "hmac(md5),rfc3686(ctr(aes))))",
2979479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-md5-"
2980479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
2981479bcc7cSHerbert Xu 				.cra_blocksize = 1,
2982479bcc7cSHerbert Xu 			},
2983479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2984479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2985479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
29868b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2987479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
2988479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2989479bcc7cSHerbert Xu 		},
2990479bcc7cSHerbert Xu 		.caam = {
2991479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
2992479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
2993479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2994479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2995479bcc7cSHerbert Xu 			.rfc3686 = true,
2996479bcc7cSHerbert Xu 			.geniv = true,
2997479bcc7cSHerbert Xu 		},
2998479bcc7cSHerbert Xu 	},
2999479bcc7cSHerbert Xu 	{
3000479bcc7cSHerbert Xu 		.aead = {
3001479bcc7cSHerbert Xu 			.base = {
3002479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
3003479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3004479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
3005479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3006479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3007479bcc7cSHerbert Xu 			},
3008479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3009479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3010479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3011479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3012479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3013479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3014479bcc7cSHerbert Xu 		},
3015479bcc7cSHerbert Xu 		.caam = {
3016479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3017479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3018479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3019479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3020479bcc7cSHerbert Xu 			.rfc3686 = true,
3021479bcc7cSHerbert Xu 		},
3022479bcc7cSHerbert Xu 	},
3023479bcc7cSHerbert Xu 	{
3024479bcc7cSHerbert Xu 		.aead = {
3025479bcc7cSHerbert Xu 			.base = {
3026479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
3027479bcc7cSHerbert Xu 					    "hmac(sha1),rfc3686(ctr(aes))))",
3028479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha1-"
3029479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3030479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3031479bcc7cSHerbert Xu 			},
3032479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3033479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3034479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
30358b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3036479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3037479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3038479bcc7cSHerbert Xu 		},
3039479bcc7cSHerbert Xu 		.caam = {
3040479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3041479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3042479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3043479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3044479bcc7cSHerbert Xu 			.rfc3686 = true,
3045479bcc7cSHerbert Xu 			.geniv = true,
3046479bcc7cSHerbert Xu 		},
3047479bcc7cSHerbert Xu 	},
3048479bcc7cSHerbert Xu 	{
3049479bcc7cSHerbert Xu 		.aead = {
3050479bcc7cSHerbert Xu 			.base = {
3051479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
3052479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3053479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
3054479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3055479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3056479bcc7cSHerbert Xu 			},
3057479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3058479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3059479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3060479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3061479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3062479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3063479bcc7cSHerbert Xu 		},
3064479bcc7cSHerbert Xu 		.caam = {
3065479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3066479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3067479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3068479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3069479bcc7cSHerbert Xu 			.rfc3686 = true,
3070479bcc7cSHerbert Xu 		},
3071479bcc7cSHerbert Xu 	},
3072479bcc7cSHerbert Xu 	{
3073479bcc7cSHerbert Xu 		.aead = {
3074479bcc7cSHerbert Xu 			.base = {
3075479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
3076479bcc7cSHerbert Xu 					    "hmac(sha224),rfc3686(ctr(aes))))",
3077479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha224-"
3078479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3079479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3080479bcc7cSHerbert Xu 			},
3081479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3082479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3083479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
30848b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3085479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3086479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3087479bcc7cSHerbert Xu 		},
3088479bcc7cSHerbert Xu 		.caam = {
3089479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3090479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3091479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3092479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3093479bcc7cSHerbert Xu 			.rfc3686 = true,
3094479bcc7cSHerbert Xu 			.geniv = true,
3095479bcc7cSHerbert Xu 		},
3096479bcc7cSHerbert Xu 	},
3097479bcc7cSHerbert Xu 	{
3098479bcc7cSHerbert Xu 		.aead = {
3099479bcc7cSHerbert Xu 			.base = {
3100479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
3101479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3102479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
3103479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3104479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3105479bcc7cSHerbert Xu 			},
3106479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3107479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3108479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3109479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3110479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3111479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3112479bcc7cSHerbert Xu 		},
3113479bcc7cSHerbert Xu 		.caam = {
3114479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3115479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3116479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3117479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3118479bcc7cSHerbert Xu 			.rfc3686 = true,
3119479bcc7cSHerbert Xu 		},
3120479bcc7cSHerbert Xu 	},
3121479bcc7cSHerbert Xu 	{
3122479bcc7cSHerbert Xu 		.aead = {
3123479bcc7cSHerbert Xu 			.base = {
3124479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha256),"
3125479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
3126479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha256-"
3127479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3128479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3129479bcc7cSHerbert Xu 			},
3130479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3131479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3132479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
31338b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3134479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3135479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3136479bcc7cSHerbert Xu 		},
3137479bcc7cSHerbert Xu 		.caam = {
3138479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3139479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3140479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3141479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3142479bcc7cSHerbert Xu 			.rfc3686 = true,
3143479bcc7cSHerbert Xu 			.geniv = true,
3144479bcc7cSHerbert Xu 		},
3145479bcc7cSHerbert Xu 	},
3146479bcc7cSHerbert Xu 	{
3147479bcc7cSHerbert Xu 		.aead = {
3148479bcc7cSHerbert Xu 			.base = {
3149479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
3150479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3151479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
3152479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3153479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3154479bcc7cSHerbert Xu 			},
3155479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3156479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3157479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3158479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3159479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3160479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3161479bcc7cSHerbert Xu 		},
3162479bcc7cSHerbert Xu 		.caam = {
3163479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3164479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3165479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3166479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3167479bcc7cSHerbert Xu 			.rfc3686 = true,
3168479bcc7cSHerbert Xu 		},
3169479bcc7cSHerbert Xu 	},
3170479bcc7cSHerbert Xu 	{
3171479bcc7cSHerbert Xu 		.aead = {
3172479bcc7cSHerbert Xu 			.base = {
3173479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha384),"
3174479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
3175479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha384-"
3176479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3177479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3178479bcc7cSHerbert Xu 			},
3179479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3180479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3181479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
31828b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3183479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3184479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3185479bcc7cSHerbert Xu 		},
3186479bcc7cSHerbert Xu 		.caam = {
3187479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3188479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3189479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3190479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3191479bcc7cSHerbert Xu 			.rfc3686 = true,
3192479bcc7cSHerbert Xu 			.geniv = true,
3193479bcc7cSHerbert Xu 		},
3194479bcc7cSHerbert Xu 	},
3195479bcc7cSHerbert Xu 	{
3196479bcc7cSHerbert Xu 		.aead = {
3197479bcc7cSHerbert Xu 			.base = {
3198479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
3199479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3200479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
3201479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3202479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3203479bcc7cSHerbert Xu 			},
3204479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3205479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3206479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3207479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3208479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3209479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3210479bcc7cSHerbert Xu 		},
3211479bcc7cSHerbert Xu 		.caam = {
3212479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3213479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3214479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3215479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3216479bcc7cSHerbert Xu 			.rfc3686 = true,
3217479bcc7cSHerbert Xu 		},
3218479bcc7cSHerbert Xu 	},
3219479bcc7cSHerbert Xu 	{
3220479bcc7cSHerbert Xu 		.aead = {
3221479bcc7cSHerbert Xu 			.base = {
3222479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha512),"
3223479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
3224479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha512-"
3225479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3226479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3227479bcc7cSHerbert Xu 			},
3228479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3229479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3230479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
32318b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3232479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3233479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3234479bcc7cSHerbert Xu 		},
3235479bcc7cSHerbert Xu 		.caam = {
3236479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3237479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3238479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3239479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3240479bcc7cSHerbert Xu 			.rfc3686 = true,
3241479bcc7cSHerbert Xu 			.geniv = true,
3242479bcc7cSHerbert Xu 		},
3243479bcc7cSHerbert Xu 	},
3244f2147b88SHerbert Xu };
3245f2147b88SHerbert Xu 
3246f2147b88SHerbert Xu struct caam_crypto_alg {
3247f2147b88SHerbert Xu 	struct crypto_alg crypto_alg;
3248f2147b88SHerbert Xu 	struct list_head entry;
3249f2147b88SHerbert Xu 	struct caam_alg_entry caam;
3250f2147b88SHerbert Xu };
3251f2147b88SHerbert Xu 
3252f2147b88SHerbert Xu static int caam_init_common(struct caam_ctx *ctx, struct caam_alg_entry *caam)
3253f2147b88SHerbert Xu {
3254bbf22344SHoria Geantă 	dma_addr_t dma_addr;
3255bbf22344SHoria Geantă 
3256f2147b88SHerbert Xu 	ctx->jrdev = caam_jr_alloc();
3257f2147b88SHerbert Xu 	if (IS_ERR(ctx->jrdev)) {
3258f2147b88SHerbert Xu 		pr_err("Job Ring Device allocation for transform failed\n");
3259f2147b88SHerbert Xu 		return PTR_ERR(ctx->jrdev);
3260f2147b88SHerbert Xu 	}
3261f2147b88SHerbert Xu 
3262bbf22344SHoria Geantă 	dma_addr = dma_map_single_attrs(ctx->jrdev, ctx->sh_desc_enc,
3263bbf22344SHoria Geantă 					offsetof(struct caam_ctx,
3264bbf22344SHoria Geantă 						 sh_desc_enc_dma),
3265bbf22344SHoria Geantă 					DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
3266bbf22344SHoria Geantă 	if (dma_mapping_error(ctx->jrdev, dma_addr)) {
3267bbf22344SHoria Geantă 		dev_err(ctx->jrdev, "unable to map key, shared descriptors\n");
3268bbf22344SHoria Geantă 		caam_jr_free(ctx->jrdev);
3269bbf22344SHoria Geantă 		return -ENOMEM;
3270bbf22344SHoria Geantă 	}
3271bbf22344SHoria Geantă 
3272bbf22344SHoria Geantă 	ctx->sh_desc_enc_dma = dma_addr;
3273bbf22344SHoria Geantă 	ctx->sh_desc_dec_dma = dma_addr + offsetof(struct caam_ctx,
3274bbf22344SHoria Geantă 						   sh_desc_dec);
3275bbf22344SHoria Geantă 	ctx->sh_desc_givenc_dma = dma_addr + offsetof(struct caam_ctx,
3276bbf22344SHoria Geantă 						      sh_desc_givenc);
3277bbf22344SHoria Geantă 	ctx->key_dma = dma_addr + offsetof(struct caam_ctx, key);
3278bbf22344SHoria Geantă 
3279f2147b88SHerbert Xu 	/* copy descriptor header template value */
3280db57656bSHoria Geantă 	ctx->cdata.algtype = OP_TYPE_CLASS1_ALG | caam->class1_alg_type;
3281db57656bSHoria Geantă 	ctx->adata.algtype = OP_TYPE_CLASS2_ALG | caam->class2_alg_type;
3282f2147b88SHerbert Xu 
3283f2147b88SHerbert Xu 	return 0;
3284f2147b88SHerbert Xu }
3285f2147b88SHerbert Xu 
32868e8ec596SKim Phillips static int caam_cra_init(struct crypto_tfm *tfm)
32878e8ec596SKim Phillips {
32888e8ec596SKim Phillips 	struct crypto_alg *alg = tfm->__crt_alg;
32898e8ec596SKim Phillips 	struct caam_crypto_alg *caam_alg =
32908e8ec596SKim Phillips 		 container_of(alg, struct caam_crypto_alg, crypto_alg);
32918e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_tfm_ctx(tfm);
32928e8ec596SKim Phillips 
3293f2147b88SHerbert Xu 	return caam_init_common(ctx, &caam_alg->caam);
3294cfc6f11bSRuchika Gupta }
32958e8ec596SKim Phillips 
3296f2147b88SHerbert Xu static int caam_aead_init(struct crypto_aead *tfm)
32978e8ec596SKim Phillips {
3298f2147b88SHerbert Xu 	struct aead_alg *alg = crypto_aead_alg(tfm);
3299f2147b88SHerbert Xu 	struct caam_aead_alg *caam_alg =
3300f2147b88SHerbert Xu 		 container_of(alg, struct caam_aead_alg, aead);
3301f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(tfm);
33028e8ec596SKim Phillips 
3303f2147b88SHerbert Xu 	return caam_init_common(ctx, &caam_alg->caam);
3304f2147b88SHerbert Xu }
3305f2147b88SHerbert Xu 
3306f2147b88SHerbert Xu static void caam_exit_common(struct caam_ctx *ctx)
3307f2147b88SHerbert Xu {
3308bbf22344SHoria Geantă 	dma_unmap_single_attrs(ctx->jrdev, ctx->sh_desc_enc_dma,
3309bbf22344SHoria Geantă 			       offsetof(struct caam_ctx, sh_desc_enc_dma),
3310bbf22344SHoria Geantă 			       DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC);
3311cfc6f11bSRuchika Gupta 	caam_jr_free(ctx->jrdev);
33128e8ec596SKim Phillips }
33138e8ec596SKim Phillips 
3314f2147b88SHerbert Xu static void caam_cra_exit(struct crypto_tfm *tfm)
3315f2147b88SHerbert Xu {
3316f2147b88SHerbert Xu 	caam_exit_common(crypto_tfm_ctx(tfm));
3317f2147b88SHerbert Xu }
3318f2147b88SHerbert Xu 
3319f2147b88SHerbert Xu static void caam_aead_exit(struct crypto_aead *tfm)
3320f2147b88SHerbert Xu {
3321f2147b88SHerbert Xu 	caam_exit_common(crypto_aead_ctx(tfm));
3322f2147b88SHerbert Xu }
3323f2147b88SHerbert Xu 
33248e8ec596SKim Phillips static void __exit caam_algapi_exit(void)
33258e8ec596SKim Phillips {
33268e8ec596SKim Phillips 
33278e8ec596SKim Phillips 	struct caam_crypto_alg *t_alg, *n;
3328f2147b88SHerbert Xu 	int i;
3329f2147b88SHerbert Xu 
3330f2147b88SHerbert Xu 	for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
3331f2147b88SHerbert Xu 		struct caam_aead_alg *t_alg = driver_aeads + i;
3332f2147b88SHerbert Xu 
3333f2147b88SHerbert Xu 		if (t_alg->registered)
3334f2147b88SHerbert Xu 			crypto_unregister_aead(&t_alg->aead);
3335f2147b88SHerbert Xu 	}
33368e8ec596SKim Phillips 
3337cfc6f11bSRuchika Gupta 	if (!alg_list.next)
33388e8ec596SKim Phillips 		return;
33398e8ec596SKim Phillips 
3340cfc6f11bSRuchika Gupta 	list_for_each_entry_safe(t_alg, n, &alg_list, entry) {
33418e8ec596SKim Phillips 		crypto_unregister_alg(&t_alg->crypto_alg);
33428e8ec596SKim Phillips 		list_del(&t_alg->entry);
33438e8ec596SKim Phillips 		kfree(t_alg);
33448e8ec596SKim Phillips 	}
33458e8ec596SKim Phillips }
33468e8ec596SKim Phillips 
3347cfc6f11bSRuchika Gupta static struct caam_crypto_alg *caam_alg_alloc(struct caam_alg_template
33488e8ec596SKim Phillips 					      *template)
33498e8ec596SKim Phillips {
33508e8ec596SKim Phillips 	struct caam_crypto_alg *t_alg;
33518e8ec596SKim Phillips 	struct crypto_alg *alg;
33528e8ec596SKim Phillips 
33539c4f9733SFabio Estevam 	t_alg = kzalloc(sizeof(*t_alg), GFP_KERNEL);
33548e8ec596SKim Phillips 	if (!t_alg) {
3355cfc6f11bSRuchika Gupta 		pr_err("failed to allocate t_alg\n");
33568e8ec596SKim Phillips 		return ERR_PTR(-ENOMEM);
33578e8ec596SKim Phillips 	}
33588e8ec596SKim Phillips 
33598e8ec596SKim Phillips 	alg = &t_alg->crypto_alg;
33608e8ec596SKim Phillips 
33618e8ec596SKim Phillips 	snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", template->name);
33628e8ec596SKim Phillips 	snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
33638e8ec596SKim Phillips 		 template->driver_name);
33648e8ec596SKim Phillips 	alg->cra_module = THIS_MODULE;
33658e8ec596SKim Phillips 	alg->cra_init = caam_cra_init;
33668e8ec596SKim Phillips 	alg->cra_exit = caam_cra_exit;
33678e8ec596SKim Phillips 	alg->cra_priority = CAAM_CRA_PRIORITY;
33688e8ec596SKim Phillips 	alg->cra_blocksize = template->blocksize;
33698e8ec596SKim Phillips 	alg->cra_alignmask = 0;
33708e8ec596SKim Phillips 	alg->cra_ctxsize = sizeof(struct caam_ctx);
3371d912bb76SNikos Mavrogiannopoulos 	alg->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY |
3372d912bb76SNikos Mavrogiannopoulos 			 template->type;
3373885e9e2fSYuan Kang 	switch (template->type) {
33747222d1a3SCatalin Vasile 	case CRYPTO_ALG_TYPE_GIVCIPHER:
33757222d1a3SCatalin Vasile 		alg->cra_type = &crypto_givcipher_type;
33767222d1a3SCatalin Vasile 		alg->cra_ablkcipher = template->template_ablkcipher;
33777222d1a3SCatalin Vasile 		break;
3378acdca31dSYuan Kang 	case CRYPTO_ALG_TYPE_ABLKCIPHER:
3379acdca31dSYuan Kang 		alg->cra_type = &crypto_ablkcipher_type;
3380acdca31dSYuan Kang 		alg->cra_ablkcipher = template->template_ablkcipher;
3381acdca31dSYuan Kang 		break;
3382885e9e2fSYuan Kang 	}
33838e8ec596SKim Phillips 
3384f2147b88SHerbert Xu 	t_alg->caam.class1_alg_type = template->class1_alg_type;
3385f2147b88SHerbert Xu 	t_alg->caam.class2_alg_type = template->class2_alg_type;
33868e8ec596SKim Phillips 
33878e8ec596SKim Phillips 	return t_alg;
33888e8ec596SKim Phillips }
33898e8ec596SKim Phillips 
3390f2147b88SHerbert Xu static void caam_aead_alg_init(struct caam_aead_alg *t_alg)
3391f2147b88SHerbert Xu {
3392f2147b88SHerbert Xu 	struct aead_alg *alg = &t_alg->aead;
3393f2147b88SHerbert Xu 
3394f2147b88SHerbert Xu 	alg->base.cra_module = THIS_MODULE;
3395f2147b88SHerbert Xu 	alg->base.cra_priority = CAAM_CRA_PRIORITY;
3396f2147b88SHerbert Xu 	alg->base.cra_ctxsize = sizeof(struct caam_ctx);
33975e4b8c1fSHerbert Xu 	alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY;
3398f2147b88SHerbert Xu 
3399f2147b88SHerbert Xu 	alg->init = caam_aead_init;
3400f2147b88SHerbert Xu 	alg->exit = caam_aead_exit;
3401f2147b88SHerbert Xu }
3402f2147b88SHerbert Xu 
34038e8ec596SKim Phillips static int __init caam_algapi_init(void)
34048e8ec596SKim Phillips {
340535af6403SRuchika Gupta 	struct device_node *dev_node;
340635af6403SRuchika Gupta 	struct platform_device *pdev;
340735af6403SRuchika Gupta 	struct device *ctrldev;
3408bf83490eSVictoria Milhoan 	struct caam_drv_private *priv;
34098e8ec596SKim Phillips 	int i = 0, err = 0;
3410bf83490eSVictoria Milhoan 	u32 cha_vid, cha_inst, des_inst, aes_inst, md_inst;
3411bf83490eSVictoria Milhoan 	unsigned int md_limit = SHA512_DIGEST_SIZE;
3412f2147b88SHerbert Xu 	bool registered = false;
34138e8ec596SKim Phillips 
341435af6403SRuchika Gupta 	dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
341535af6403SRuchika Gupta 	if (!dev_node) {
341635af6403SRuchika Gupta 		dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
341735af6403SRuchika Gupta 		if (!dev_node)
341835af6403SRuchika Gupta 			return -ENODEV;
341935af6403SRuchika Gupta 	}
342035af6403SRuchika Gupta 
342135af6403SRuchika Gupta 	pdev = of_find_device_by_node(dev_node);
342235af6403SRuchika Gupta 	if (!pdev) {
342335af6403SRuchika Gupta 		of_node_put(dev_node);
342435af6403SRuchika Gupta 		return -ENODEV;
342535af6403SRuchika Gupta 	}
342635af6403SRuchika Gupta 
342735af6403SRuchika Gupta 	ctrldev = &pdev->dev;
342835af6403SRuchika Gupta 	priv = dev_get_drvdata(ctrldev);
342935af6403SRuchika Gupta 	of_node_put(dev_node);
343035af6403SRuchika Gupta 
343135af6403SRuchika Gupta 	/*
343235af6403SRuchika Gupta 	 * If priv is NULL, it's probably because the caam driver wasn't
343335af6403SRuchika Gupta 	 * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
343435af6403SRuchika Gupta 	 */
343535af6403SRuchika Gupta 	if (!priv)
343635af6403SRuchika Gupta 		return -ENODEV;
343735af6403SRuchika Gupta 
343835af6403SRuchika Gupta 
3439cfc6f11bSRuchika Gupta 	INIT_LIST_HEAD(&alg_list);
34408e8ec596SKim Phillips 
3441bf83490eSVictoria Milhoan 	/*
3442bf83490eSVictoria Milhoan 	 * Register crypto algorithms the device supports.
3443bf83490eSVictoria Milhoan 	 * First, detect presence and attributes of DES, AES, and MD blocks.
3444bf83490eSVictoria Milhoan 	 */
3445bf83490eSVictoria Milhoan 	cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
3446bf83490eSVictoria Milhoan 	cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
3447bf83490eSVictoria Milhoan 	des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >> CHA_ID_LS_DES_SHIFT;
3448bf83490eSVictoria Milhoan 	aes_inst = (cha_inst & CHA_ID_LS_AES_MASK) >> CHA_ID_LS_AES_SHIFT;
3449bf83490eSVictoria Milhoan 	md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
34508e8ec596SKim Phillips 
3451bf83490eSVictoria Milhoan 	/* If MD is present, limit digest size based on LP256 */
3452bf83490eSVictoria Milhoan 	if (md_inst && ((cha_vid & CHA_ID_LS_MD_MASK) == CHA_ID_LS_MD_LP256))
3453bf83490eSVictoria Milhoan 		md_limit = SHA256_DIGEST_SIZE;
3454bf83490eSVictoria Milhoan 
3455bf83490eSVictoria Milhoan 	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
3456bf83490eSVictoria Milhoan 		struct caam_crypto_alg *t_alg;
3457bf83490eSVictoria Milhoan 		struct caam_alg_template *alg = driver_algs + i;
3458bf83490eSVictoria Milhoan 		u32 alg_sel = alg->class1_alg_type & OP_ALG_ALGSEL_MASK;
3459bf83490eSVictoria Milhoan 
3460bf83490eSVictoria Milhoan 		/* Skip DES algorithms if not supported by device */
3461bf83490eSVictoria Milhoan 		if (!des_inst &&
3462bf83490eSVictoria Milhoan 		    ((alg_sel == OP_ALG_ALGSEL_3DES) ||
3463bf83490eSVictoria Milhoan 		     (alg_sel == OP_ALG_ALGSEL_DES)))
3464bf83490eSVictoria Milhoan 				continue;
3465bf83490eSVictoria Milhoan 
3466bf83490eSVictoria Milhoan 		/* Skip AES algorithms if not supported by device */
3467bf83490eSVictoria Milhoan 		if (!aes_inst && (alg_sel == OP_ALG_ALGSEL_AES))
3468bf83490eSVictoria Milhoan 				continue;
3469bf83490eSVictoria Milhoan 
347083d2c9a9SSven Ebenfeld 		/*
347183d2c9a9SSven Ebenfeld 		 * Check support for AES modes not available
347283d2c9a9SSven Ebenfeld 		 * on LP devices.
347383d2c9a9SSven Ebenfeld 		 */
347483d2c9a9SSven Ebenfeld 		if ((cha_vid & CHA_ID_LS_AES_MASK) == CHA_ID_LS_AES_LP)
347583d2c9a9SSven Ebenfeld 			if ((alg->class1_alg_type & OP_ALG_AAI_MASK) ==
347683d2c9a9SSven Ebenfeld 			     OP_ALG_AAI_XTS)
347783d2c9a9SSven Ebenfeld 				continue;
347883d2c9a9SSven Ebenfeld 
3479bf83490eSVictoria Milhoan 		t_alg = caam_alg_alloc(alg);
34808e8ec596SKim Phillips 		if (IS_ERR(t_alg)) {
34818e8ec596SKim Phillips 			err = PTR_ERR(t_alg);
3482bf83490eSVictoria Milhoan 			pr_warn("%s alg allocation failed\n", alg->driver_name);
34838e8ec596SKim Phillips 			continue;
34848e8ec596SKim Phillips 		}
34858e8ec596SKim Phillips 
34868e8ec596SKim Phillips 		err = crypto_register_alg(&t_alg->crypto_alg);
34878e8ec596SKim Phillips 		if (err) {
3488cfc6f11bSRuchika Gupta 			pr_warn("%s alg registration failed\n",
34898e8ec596SKim Phillips 				t_alg->crypto_alg.cra_driver_name);
34908e8ec596SKim Phillips 			kfree(t_alg);
3491f2147b88SHerbert Xu 			continue;
34928e8ec596SKim Phillips 		}
3493f2147b88SHerbert Xu 
3494f2147b88SHerbert Xu 		list_add_tail(&t_alg->entry, &alg_list);
3495f2147b88SHerbert Xu 		registered = true;
3496f2147b88SHerbert Xu 	}
3497f2147b88SHerbert Xu 
3498f2147b88SHerbert Xu 	for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
3499f2147b88SHerbert Xu 		struct caam_aead_alg *t_alg = driver_aeads + i;
3500bf83490eSVictoria Milhoan 		u32 c1_alg_sel = t_alg->caam.class1_alg_type &
3501bf83490eSVictoria Milhoan 				 OP_ALG_ALGSEL_MASK;
3502bf83490eSVictoria Milhoan 		u32 c2_alg_sel = t_alg->caam.class2_alg_type &
3503bf83490eSVictoria Milhoan 				 OP_ALG_ALGSEL_MASK;
3504bf83490eSVictoria Milhoan 		u32 alg_aai = t_alg->caam.class1_alg_type & OP_ALG_AAI_MASK;
3505bf83490eSVictoria Milhoan 
3506bf83490eSVictoria Milhoan 		/* Skip DES algorithms if not supported by device */
3507bf83490eSVictoria Milhoan 		if (!des_inst &&
3508bf83490eSVictoria Milhoan 		    ((c1_alg_sel == OP_ALG_ALGSEL_3DES) ||
3509bf83490eSVictoria Milhoan 		     (c1_alg_sel == OP_ALG_ALGSEL_DES)))
3510bf83490eSVictoria Milhoan 				continue;
3511bf83490eSVictoria Milhoan 
3512bf83490eSVictoria Milhoan 		/* Skip AES algorithms if not supported by device */
3513bf83490eSVictoria Milhoan 		if (!aes_inst && (c1_alg_sel == OP_ALG_ALGSEL_AES))
3514bf83490eSVictoria Milhoan 				continue;
3515bf83490eSVictoria Milhoan 
3516bf83490eSVictoria Milhoan 		/*
3517bf83490eSVictoria Milhoan 		 * Check support for AES algorithms not available
3518bf83490eSVictoria Milhoan 		 * on LP devices.
3519bf83490eSVictoria Milhoan 		 */
3520bf83490eSVictoria Milhoan 		if ((cha_vid & CHA_ID_LS_AES_MASK) == CHA_ID_LS_AES_LP)
3521bf83490eSVictoria Milhoan 			if (alg_aai == OP_ALG_AAI_GCM)
3522bf83490eSVictoria Milhoan 				continue;
3523bf83490eSVictoria Milhoan 
3524bf83490eSVictoria Milhoan 		/*
3525bf83490eSVictoria Milhoan 		 * Skip algorithms requiring message digests
3526bf83490eSVictoria Milhoan 		 * if MD or MD size is not supported by device.
3527bf83490eSVictoria Milhoan 		 */
3528bf83490eSVictoria Milhoan 		if (c2_alg_sel &&
3529bf83490eSVictoria Milhoan 		    (!md_inst || (t_alg->aead.maxauthsize > md_limit)))
3530bf83490eSVictoria Milhoan 				continue;
3531f2147b88SHerbert Xu 
3532f2147b88SHerbert Xu 		caam_aead_alg_init(t_alg);
3533f2147b88SHerbert Xu 
3534f2147b88SHerbert Xu 		err = crypto_register_aead(&t_alg->aead);
3535f2147b88SHerbert Xu 		if (err) {
3536f2147b88SHerbert Xu 			pr_warn("%s alg registration failed\n",
3537f2147b88SHerbert Xu 				t_alg->aead.base.cra_driver_name);
3538f2147b88SHerbert Xu 			continue;
3539f2147b88SHerbert Xu 		}
3540f2147b88SHerbert Xu 
3541f2147b88SHerbert Xu 		t_alg->registered = true;
3542f2147b88SHerbert Xu 		registered = true;
3543f2147b88SHerbert Xu 	}
3544f2147b88SHerbert Xu 
3545f2147b88SHerbert Xu 	if (registered)
3546cfc6f11bSRuchika Gupta 		pr_info("caam algorithms registered in /proc/crypto\n");
35478e8ec596SKim Phillips 
35488e8ec596SKim Phillips 	return err;
35498e8ec596SKim Phillips }
35508e8ec596SKim Phillips 
35518e8ec596SKim Phillips module_init(caam_algapi_init);
35528e8ec596SKim Phillips module_exit(caam_algapi_exit);
35538e8ec596SKim Phillips 
35548e8ec596SKim Phillips MODULE_LICENSE("GPL");
35558e8ec596SKim Phillips MODULE_DESCRIPTION("FSL CAAM support for crypto API");
35568e8ec596SKim Phillips MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
3557