xref: /openbmc/linux/drivers/crypto/caam/caamalg.c (revision 68a51394)
1618b5dc4SHoria Geantă // SPDX-License-Identifier: GPL-2.0+
28e8ec596SKim Phillips /*
38e8ec596SKim Phillips  * caam - Freescale FSL CAAM support for crypto API
48e8ec596SKim Phillips  *
58e8ec596SKim Phillips  * Copyright 2008-2011 Freescale Semiconductor, Inc.
6eaed71a4SIuliana Prodan  * Copyright 2016-2019 NXP
78e8ec596SKim Phillips  *
88e8ec596SKim Phillips  * Based on talitos crypto API driver.
98e8ec596SKim Phillips  *
108e8ec596SKim Phillips  * relationship of job descriptors to shared descriptors (SteveC Dec 10 2008):
118e8ec596SKim Phillips  *
128e8ec596SKim Phillips  * ---------------                     ---------------
138e8ec596SKim Phillips  * | JobDesc #1  |-------------------->|  ShareDesc  |
148e8ec596SKim Phillips  * | *(packet 1) |                     |   (PDB)     |
158e8ec596SKim Phillips  * ---------------      |------------->|  (hashKey)  |
168e8ec596SKim Phillips  *       .              |              | (cipherKey) |
178e8ec596SKim Phillips  *       .              |    |-------->| (operation) |
188e8ec596SKim Phillips  * ---------------      |    |         ---------------
198e8ec596SKim Phillips  * | JobDesc #2  |------|    |
208e8ec596SKim Phillips  * | *(packet 2) |           |
218e8ec596SKim Phillips  * ---------------           |
228e8ec596SKim Phillips  *       .                   |
238e8ec596SKim Phillips  *       .                   |
248e8ec596SKim Phillips  * ---------------           |
258e8ec596SKim Phillips  * | JobDesc #3  |------------
268e8ec596SKim Phillips  * | *(packet 3) |
278e8ec596SKim Phillips  * ---------------
288e8ec596SKim Phillips  *
298e8ec596SKim Phillips  * The SharedDesc never changes for a connection unless rekeyed, but
308e8ec596SKim Phillips  * each packet will likely be in a different place. So all we need
318e8ec596SKim Phillips  * to know to process the packet is where the input is, where the
328e8ec596SKim Phillips  * output goes, and what context we want to process with. Context is
338e8ec596SKim Phillips  * in the SharedDesc, packet references in the JobDesc.
348e8ec596SKim Phillips  *
358e8ec596SKim Phillips  * So, a job desc looks like:
368e8ec596SKim Phillips  *
378e8ec596SKim Phillips  * ---------------------
388e8ec596SKim Phillips  * | Header            |
398e8ec596SKim Phillips  * | ShareDesc Pointer |
408e8ec596SKim Phillips  * | SEQ_OUT_PTR       |
418e8ec596SKim Phillips  * | (output buffer)   |
426ec47334SYuan Kang  * | (output length)   |
438e8ec596SKim Phillips  * | SEQ_IN_PTR        |
448e8ec596SKim Phillips  * | (input buffer)    |
456ec47334SYuan Kang  * | (input length)    |
468e8ec596SKim Phillips  * ---------------------
478e8ec596SKim Phillips  */
488e8ec596SKim Phillips 
498e8ec596SKim Phillips #include "compat.h"
508e8ec596SKim Phillips 
518e8ec596SKim Phillips #include "regs.h"
528e8ec596SKim Phillips #include "intern.h"
538e8ec596SKim Phillips #include "desc_constr.h"
548e8ec596SKim Phillips #include "jr.h"
558e8ec596SKim Phillips #include "error.h"
56a299c837SYuan Kang #include "sg_sw_sec4.h"
574c1ec1f9SYuan Kang #include "key_gen.h"
588cea7b66SHoria Geantă #include "caamalg_desc.h"
598e8ec596SKim Phillips 
608e8ec596SKim Phillips /*
618e8ec596SKim Phillips  * crypto alg
628e8ec596SKim Phillips  */
638e8ec596SKim Phillips #define CAAM_CRA_PRIORITY		3000
648e8ec596SKim Phillips /* max key is sum of AES_MAX_KEY_SIZE, max split key size */
658e8ec596SKim Phillips #define CAAM_MAX_KEY_SIZE		(AES_MAX_KEY_SIZE + \
66daebc465SCatalin Vasile 					 CTR_RFC3686_NONCE_SIZE + \
678e8ec596SKim Phillips 					 SHA512_DIGEST_SIZE * 2)
688e8ec596SKim Phillips 
69f2147b88SHerbert Xu #define AEAD_DESC_JOB_IO_LEN		(DESC_JOB_IO_LEN + CAAM_CMD_SZ * 2)
70f2147b88SHerbert Xu #define GCM_DESC_JOB_IO_LEN		(AEAD_DESC_JOB_IO_LEN + \
71f2147b88SHerbert Xu 					 CAAM_CMD_SZ * 4)
72479bcc7cSHerbert Xu #define AUTHENC_DESC_JOB_IO_LEN		(AEAD_DESC_JOB_IO_LEN + \
73479bcc7cSHerbert Xu 					 CAAM_CMD_SZ * 5)
74f2147b88SHerbert Xu 
75d6bbd4eeSHoria Geantă #define CHACHAPOLY_DESC_JOB_IO_LEN	(AEAD_DESC_JOB_IO_LEN + CAAM_CMD_SZ * 6)
76d6bbd4eeSHoria Geantă 
7787e51b07SHerbert Xu #define DESC_MAX_USED_BYTES		(CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN)
7887e51b07SHerbert Xu #define DESC_MAX_USED_LEN		(DESC_MAX_USED_BYTES / CAAM_CMD_SZ)
794427b1b4SKim Phillips 
80479bcc7cSHerbert Xu struct caam_alg_entry {
81479bcc7cSHerbert Xu 	int class1_alg_type;
82479bcc7cSHerbert Xu 	int class2_alg_type;
83479bcc7cSHerbert Xu 	bool rfc3686;
84479bcc7cSHerbert Xu 	bool geniv;
8524586b5fSHerbert Xu 	bool nodkp;
86479bcc7cSHerbert Xu };
87479bcc7cSHerbert Xu 
88479bcc7cSHerbert Xu struct caam_aead_alg {
89479bcc7cSHerbert Xu 	struct aead_alg aead;
90479bcc7cSHerbert Xu 	struct caam_alg_entry caam;
91479bcc7cSHerbert Xu 	bool registered;
92479bcc7cSHerbert Xu };
93479bcc7cSHerbert Xu 
945ca7badbSHoria Geantă struct caam_skcipher_alg {
955ca7badbSHoria Geantă 	struct skcipher_alg skcipher;
965ca7badbSHoria Geantă 	struct caam_alg_entry caam;
975ca7badbSHoria Geantă 	bool registered;
985ca7badbSHoria Geantă };
995ca7badbSHoria Geantă 
100acdca31dSYuan Kang /*
1018e8ec596SKim Phillips  * per-session context
1028e8ec596SKim Phillips  */
1038e8ec596SKim Phillips struct caam_ctx {
1041acebad3SYuan Kang 	u32 sh_desc_enc[DESC_MAX_USED_LEN];
1051acebad3SYuan Kang 	u32 sh_desc_dec[DESC_MAX_USED_LEN];
106bbf22344SHoria Geantă 	u8 key[CAAM_MAX_KEY_SIZE];
1071acebad3SYuan Kang 	dma_addr_t sh_desc_enc_dma;
1081acebad3SYuan Kang 	dma_addr_t sh_desc_dec_dma;
109885e9e2fSYuan Kang 	dma_addr_t key_dma;
1107e0880b9SHoria Geantă 	enum dma_data_direction dir;
111bbf22344SHoria Geantă 	struct device *jrdev;
112db57656bSHoria Geantă 	struct alginfo adata;
113db57656bSHoria Geantă 	struct alginfo cdata;
1148e8ec596SKim Phillips 	unsigned int authsize;
1158e8ec596SKim Phillips };
1168e8ec596SKim Phillips 
117ae4a825fSHoria Geanta static int aead_null_set_sh_desc(struct crypto_aead *aead)
118ae4a825fSHoria Geanta {
119ae4a825fSHoria Geanta 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
120ae4a825fSHoria Geanta 	struct device *jrdev = ctx->jrdev;
1217e0880b9SHoria Geantă 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
122ae4a825fSHoria Geanta 	u32 *desc;
1234cbe79ccSHoria Geantă 	int rem_bytes = CAAM_DESC_BYTES_MAX - AEAD_DESC_JOB_IO_LEN -
1244cbe79ccSHoria Geantă 			ctx->adata.keylen_pad;
125ae4a825fSHoria Geanta 
126ae4a825fSHoria Geanta 	/*
127ae4a825fSHoria Geanta 	 * Job Descriptor and Shared Descriptors
128ae4a825fSHoria Geanta 	 * must all fit into the 64-word Descriptor h/w Buffer
129ae4a825fSHoria Geanta 	 */
1304cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_AEAD_NULL_ENC_LEN) {
131db57656bSHoria Geantă 		ctx->adata.key_inline = true;
1329c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
133db57656bSHoria Geantă 	} else {
134db57656bSHoria Geantă 		ctx->adata.key_inline = false;
1359c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
136db57656bSHoria Geantă 	}
137ae4a825fSHoria Geanta 
138479bcc7cSHerbert Xu 	/* aead_encrypt shared descriptor */
139ae4a825fSHoria Geanta 	desc = ctx->sh_desc_enc;
1407e0880b9SHoria Geantă 	cnstr_shdsc_aead_null_encap(desc, &ctx->adata, ctx->authsize,
1417e0880b9SHoria Geantă 				    ctrlpriv->era);
142bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
1437e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
144ae4a825fSHoria Geanta 
145ae4a825fSHoria Geanta 	/*
146ae4a825fSHoria Geanta 	 * Job Descriptor and Shared Descriptors
147ae4a825fSHoria Geanta 	 * must all fit into the 64-word Descriptor h/w Buffer
148ae4a825fSHoria Geanta 	 */
1494cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_AEAD_NULL_DEC_LEN) {
150db57656bSHoria Geantă 		ctx->adata.key_inline = true;
1519c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
152db57656bSHoria Geantă 	} else {
153db57656bSHoria Geantă 		ctx->adata.key_inline = false;
1549c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
155db57656bSHoria Geantă 	}
156ae4a825fSHoria Geanta 
157479bcc7cSHerbert Xu 	/* aead_decrypt shared descriptor */
1588cea7b66SHoria Geantă 	desc = ctx->sh_desc_dec;
1597e0880b9SHoria Geantă 	cnstr_shdsc_aead_null_decap(desc, &ctx->adata, ctx->authsize,
1607e0880b9SHoria Geantă 				    ctrlpriv->era);
161bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
1627e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
163ae4a825fSHoria Geanta 
164ae4a825fSHoria Geanta 	return 0;
165ae4a825fSHoria Geanta }
166ae4a825fSHoria Geanta 
1671acebad3SYuan Kang static int aead_set_sh_desc(struct crypto_aead *aead)
1681acebad3SYuan Kang {
169479bcc7cSHerbert Xu 	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
170479bcc7cSHerbert Xu 						 struct caam_aead_alg, aead);
171add86d55SHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
1721acebad3SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1731acebad3SYuan Kang 	struct device *jrdev = ctx->jrdev;
1747e0880b9SHoria Geantă 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
175daebc465SCatalin Vasile 	u32 ctx1_iv_off = 0;
1768cea7b66SHoria Geantă 	u32 *desc, *nonce = NULL;
1774cbe79ccSHoria Geantă 	u32 inl_mask;
1784cbe79ccSHoria Geantă 	unsigned int data_len[2];
179db57656bSHoria Geantă 	const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
180daebc465SCatalin Vasile 			       OP_ALG_AAI_CTR_MOD128);
181479bcc7cSHerbert Xu 	const bool is_rfc3686 = alg->caam.rfc3686;
1821acebad3SYuan Kang 
1832fdea258SHoria Geantă 	if (!ctx->authsize)
1842fdea258SHoria Geantă 		return 0;
1852fdea258SHoria Geantă 
186ae4a825fSHoria Geanta 	/* NULL encryption / decryption */
187db57656bSHoria Geantă 	if (!ctx->cdata.keylen)
188ae4a825fSHoria Geanta 		return aead_null_set_sh_desc(aead);
189ae4a825fSHoria Geanta 
1901acebad3SYuan Kang 	/*
191daebc465SCatalin Vasile 	 * AES-CTR needs to load IV in CONTEXT1 reg
192daebc465SCatalin Vasile 	 * at an offset of 128bits (16bytes)
193daebc465SCatalin Vasile 	 * CONTEXT1[255:128] = IV
194daebc465SCatalin Vasile 	 */
195daebc465SCatalin Vasile 	if (ctr_mode)
196daebc465SCatalin Vasile 		ctx1_iv_off = 16;
197daebc465SCatalin Vasile 
198daebc465SCatalin Vasile 	/*
199daebc465SCatalin Vasile 	 * RFC3686 specific:
200daebc465SCatalin Vasile 	 *	CONTEXT1[255:128] = {NONCE, IV, COUNTER}
201daebc465SCatalin Vasile 	 */
2028cea7b66SHoria Geantă 	if (is_rfc3686) {
203daebc465SCatalin Vasile 		ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
2048cea7b66SHoria Geantă 		nonce = (u32 *)((void *)ctx->key + ctx->adata.keylen_pad +
2058cea7b66SHoria Geantă 				ctx->cdata.keylen - CTR_RFC3686_NONCE_SIZE);
2068cea7b66SHoria Geantă 	}
207daebc465SCatalin Vasile 
2084cbe79ccSHoria Geantă 	data_len[0] = ctx->adata.keylen_pad;
2094cbe79ccSHoria Geantă 	data_len[1] = ctx->cdata.keylen;
2104cbe79ccSHoria Geantă 
211479bcc7cSHerbert Xu 	if (alg->caam.geniv)
212479bcc7cSHerbert Xu 		goto skip_enc;
213479bcc7cSHerbert Xu 
214daebc465SCatalin Vasile 	/*
2151acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
2161acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
2171acebad3SYuan Kang 	 */
2184cbe79ccSHoria Geantă 	if (desc_inline_query(DESC_AEAD_ENC_LEN +
2194cbe79ccSHoria Geantă 			      (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
2204cbe79ccSHoria Geantă 			      AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
2214cbe79ccSHoria Geantă 			      ARRAY_SIZE(data_len)) < 0)
2224cbe79ccSHoria Geantă 		return -EINVAL;
2234cbe79ccSHoria Geantă 
2244cbe79ccSHoria Geantă 	if (inl_mask & 1)
2259c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
2264cbe79ccSHoria Geantă 	else
2279c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
2284cbe79ccSHoria Geantă 
2294cbe79ccSHoria Geantă 	if (inl_mask & 2)
2309c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
2314cbe79ccSHoria Geantă 	else
2329c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
2334cbe79ccSHoria Geantă 
2344cbe79ccSHoria Geantă 	ctx->adata.key_inline = !!(inl_mask & 1);
2354cbe79ccSHoria Geantă 	ctx->cdata.key_inline = !!(inl_mask & 2);
2361acebad3SYuan Kang 
237479bcc7cSHerbert Xu 	/* aead_encrypt shared descriptor */
2381acebad3SYuan Kang 	desc = ctx->sh_desc_enc;
239b189817cSHoria Geantă 	cnstr_shdsc_aead_encap(desc, &ctx->cdata, &ctx->adata, ivsize,
240b189817cSHoria Geantă 			       ctx->authsize, is_rfc3686, nonce, ctx1_iv_off,
2417e0880b9SHoria Geantă 			       false, ctrlpriv->era);
242bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
2437e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
2441acebad3SYuan Kang 
245479bcc7cSHerbert Xu skip_enc:
2461acebad3SYuan Kang 	/*
2471acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
2481acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
2491acebad3SYuan Kang 	 */
2504cbe79ccSHoria Geantă 	if (desc_inline_query(DESC_AEAD_DEC_LEN +
2514cbe79ccSHoria Geantă 			      (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
2524cbe79ccSHoria Geantă 			      AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
2534cbe79ccSHoria Geantă 			      ARRAY_SIZE(data_len)) < 0)
2544cbe79ccSHoria Geantă 		return -EINVAL;
2554cbe79ccSHoria Geantă 
2564cbe79ccSHoria Geantă 	if (inl_mask & 1)
2579c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
2584cbe79ccSHoria Geantă 	else
2599c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
2604cbe79ccSHoria Geantă 
2614cbe79ccSHoria Geantă 	if (inl_mask & 2)
2629c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
2634cbe79ccSHoria Geantă 	else
2649c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
2654cbe79ccSHoria Geantă 
2664cbe79ccSHoria Geantă 	ctx->adata.key_inline = !!(inl_mask & 1);
2674cbe79ccSHoria Geantă 	ctx->cdata.key_inline = !!(inl_mask & 2);
2681acebad3SYuan Kang 
269479bcc7cSHerbert Xu 	/* aead_decrypt shared descriptor */
2701acebad3SYuan Kang 	desc = ctx->sh_desc_dec;
2718cea7b66SHoria Geantă 	cnstr_shdsc_aead_decap(desc, &ctx->cdata, &ctx->adata, ivsize,
2728cea7b66SHoria Geantă 			       ctx->authsize, alg->caam.geniv, is_rfc3686,
2737e0880b9SHoria Geantă 			       nonce, ctx1_iv_off, false, ctrlpriv->era);
274bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
2757e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
2761acebad3SYuan Kang 
277479bcc7cSHerbert Xu 	if (!alg->caam.geniv)
278479bcc7cSHerbert Xu 		goto skip_givenc;
279479bcc7cSHerbert Xu 
2801acebad3SYuan Kang 	/*
2811acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
2821acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
2831acebad3SYuan Kang 	 */
2844cbe79ccSHoria Geantă 	if (desc_inline_query(DESC_AEAD_GIVENC_LEN +
2854cbe79ccSHoria Geantă 			      (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
2864cbe79ccSHoria Geantă 			      AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
2874cbe79ccSHoria Geantă 			      ARRAY_SIZE(data_len)) < 0)
2884cbe79ccSHoria Geantă 		return -EINVAL;
2894cbe79ccSHoria Geantă 
2904cbe79ccSHoria Geantă 	if (inl_mask & 1)
2919c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
2924cbe79ccSHoria Geantă 	else
2939c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
2944cbe79ccSHoria Geantă 
2954cbe79ccSHoria Geantă 	if (inl_mask & 2)
2969c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
2974cbe79ccSHoria Geantă 	else
2989c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
2994cbe79ccSHoria Geantă 
3004cbe79ccSHoria Geantă 	ctx->adata.key_inline = !!(inl_mask & 1);
3014cbe79ccSHoria Geantă 	ctx->cdata.key_inline = !!(inl_mask & 2);
3021acebad3SYuan Kang 
3031acebad3SYuan Kang 	/* aead_givencrypt shared descriptor */
3041d2d87e8SHoria Geantă 	desc = ctx->sh_desc_enc;
3058cea7b66SHoria Geantă 	cnstr_shdsc_aead_givencap(desc, &ctx->cdata, &ctx->adata, ivsize,
3068cea7b66SHoria Geantă 				  ctx->authsize, is_rfc3686, nonce,
3077e0880b9SHoria Geantă 				  ctx1_iv_off, false, ctrlpriv->era);
308bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
3097e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
3101acebad3SYuan Kang 
311479bcc7cSHerbert Xu skip_givenc:
3121acebad3SYuan Kang 	return 0;
3131acebad3SYuan Kang }
3141acebad3SYuan Kang 
3150e479300SYuan Kang static int aead_setauthsize(struct crypto_aead *authenc,
3168e8ec596SKim Phillips 				    unsigned int authsize)
3178e8ec596SKim Phillips {
3188e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
3198e8ec596SKim Phillips 
3208e8ec596SKim Phillips 	ctx->authsize = authsize;
3211acebad3SYuan Kang 	aead_set_sh_desc(authenc);
3228e8ec596SKim Phillips 
3238e8ec596SKim Phillips 	return 0;
3248e8ec596SKim Phillips }
3258e8ec596SKim Phillips 
3263ef8d945STudor Ambarus static int gcm_set_sh_desc(struct crypto_aead *aead)
3273ef8d945STudor Ambarus {
3283ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
3293ef8d945STudor Ambarus 	struct device *jrdev = ctx->jrdev;
33087ec3a0bSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
3313ef8d945STudor Ambarus 	u32 *desc;
3324cbe79ccSHoria Geantă 	int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
3334cbe79ccSHoria Geantă 			ctx->cdata.keylen;
3343ef8d945STudor Ambarus 
335db57656bSHoria Geantă 	if (!ctx->cdata.keylen || !ctx->authsize)
3363ef8d945STudor Ambarus 		return 0;
3373ef8d945STudor Ambarus 
3383ef8d945STudor Ambarus 	/*
3393ef8d945STudor Ambarus 	 * AES GCM encrypt shared descriptor
3403ef8d945STudor Ambarus 	 * Job Descriptor and Shared Descriptor
3413ef8d945STudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
3423ef8d945STudor Ambarus 	 */
3434cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_GCM_ENC_LEN) {
344db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
3459c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
346db57656bSHoria Geantă 	} else {
347db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
3489c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
349db57656bSHoria Geantă 	}
3503ef8d945STudor Ambarus 
3513ef8d945STudor Ambarus 	desc = ctx->sh_desc_enc;
35287ec3a0bSHoria Geantă 	cnstr_shdsc_gcm_encap(desc, &ctx->cdata, ivsize, ctx->authsize, false);
353bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
3547e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
3553ef8d945STudor Ambarus 
3563ef8d945STudor Ambarus 	/*
3573ef8d945STudor Ambarus 	 * Job Descriptor and Shared Descriptors
3583ef8d945STudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
3593ef8d945STudor Ambarus 	 */
3604cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_GCM_DEC_LEN) {
361db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
3629c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
363db57656bSHoria Geantă 	} else {
364db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
3659c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
366db57656bSHoria Geantă 	}
3673ef8d945STudor Ambarus 
3683ef8d945STudor Ambarus 	desc = ctx->sh_desc_dec;
36987ec3a0bSHoria Geantă 	cnstr_shdsc_gcm_decap(desc, &ctx->cdata, ivsize, ctx->authsize, false);
370bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
3717e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
3723ef8d945STudor Ambarus 
3733ef8d945STudor Ambarus 	return 0;
3743ef8d945STudor Ambarus }
3753ef8d945STudor Ambarus 
3763ef8d945STudor Ambarus static int gcm_setauthsize(struct crypto_aead *authenc, unsigned int authsize)
3773ef8d945STudor Ambarus {
3783ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
37968a51394SIuliana Prodan 	int err;
38068a51394SIuliana Prodan 
38168a51394SIuliana Prodan 	err = crypto_gcm_check_authsize(authsize);
38268a51394SIuliana Prodan 	if (err)
38368a51394SIuliana Prodan 		return err;
3843ef8d945STudor Ambarus 
3853ef8d945STudor Ambarus 	ctx->authsize = authsize;
3863ef8d945STudor Ambarus 	gcm_set_sh_desc(authenc);
3873ef8d945STudor Ambarus 
3883ef8d945STudor Ambarus 	return 0;
3893ef8d945STudor Ambarus }
3903ef8d945STudor Ambarus 
391bac68f2cSTudor Ambarus static int rfc4106_set_sh_desc(struct crypto_aead *aead)
392bac68f2cSTudor Ambarus {
393bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
394bac68f2cSTudor Ambarus 	struct device *jrdev = ctx->jrdev;
39587ec3a0bSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
396bac68f2cSTudor Ambarus 	u32 *desc;
3974cbe79ccSHoria Geantă 	int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
3984cbe79ccSHoria Geantă 			ctx->cdata.keylen;
399bac68f2cSTudor Ambarus 
400db57656bSHoria Geantă 	if (!ctx->cdata.keylen || !ctx->authsize)
401bac68f2cSTudor Ambarus 		return 0;
402bac68f2cSTudor Ambarus 
403bac68f2cSTudor Ambarus 	/*
404bac68f2cSTudor Ambarus 	 * RFC4106 encrypt shared descriptor
405bac68f2cSTudor Ambarus 	 * Job Descriptor and Shared Descriptor
406bac68f2cSTudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
407bac68f2cSTudor Ambarus 	 */
4084cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_RFC4106_ENC_LEN) {
409db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
4109c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
411db57656bSHoria Geantă 	} else {
412db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
4139c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
414db57656bSHoria Geantă 	}
415bac68f2cSTudor Ambarus 
416bac68f2cSTudor Ambarus 	desc = ctx->sh_desc_enc;
41787ec3a0bSHoria Geantă 	cnstr_shdsc_rfc4106_encap(desc, &ctx->cdata, ivsize, ctx->authsize,
41887ec3a0bSHoria Geantă 				  false);
419bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
4207e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
421bac68f2cSTudor Ambarus 
422bac68f2cSTudor Ambarus 	/*
423bac68f2cSTudor Ambarus 	 * Job Descriptor and Shared Descriptors
424bac68f2cSTudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
425bac68f2cSTudor Ambarus 	 */
4264cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_RFC4106_DEC_LEN) {
427db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
4289c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
429db57656bSHoria Geantă 	} else {
430db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
4319c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
432db57656bSHoria Geantă 	}
433bac68f2cSTudor Ambarus 
434bac68f2cSTudor Ambarus 	desc = ctx->sh_desc_dec;
43587ec3a0bSHoria Geantă 	cnstr_shdsc_rfc4106_decap(desc, &ctx->cdata, ivsize, ctx->authsize,
43687ec3a0bSHoria Geantă 				  false);
437bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
4387e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
439bac68f2cSTudor Ambarus 
440bac68f2cSTudor Ambarus 	return 0;
441bac68f2cSTudor Ambarus }
442bac68f2cSTudor Ambarus 
443bac68f2cSTudor Ambarus static int rfc4106_setauthsize(struct crypto_aead *authenc,
444bac68f2cSTudor Ambarus 			       unsigned int authsize)
445bac68f2cSTudor Ambarus {
446bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
44768a51394SIuliana Prodan 	int err;
44868a51394SIuliana Prodan 
44968a51394SIuliana Prodan 	err = crypto_rfc4106_check_authsize(authsize);
45068a51394SIuliana Prodan 	if (err)
45168a51394SIuliana Prodan 		return err;
452bac68f2cSTudor Ambarus 
453bac68f2cSTudor Ambarus 	ctx->authsize = authsize;
454bac68f2cSTudor Ambarus 	rfc4106_set_sh_desc(authenc);
455bac68f2cSTudor Ambarus 
456bac68f2cSTudor Ambarus 	return 0;
457bac68f2cSTudor Ambarus }
458bac68f2cSTudor Ambarus 
4595d0429a3STudor Ambarus static int rfc4543_set_sh_desc(struct crypto_aead *aead)
4605d0429a3STudor Ambarus {
4615d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
4625d0429a3STudor Ambarus 	struct device *jrdev = ctx->jrdev;
46387ec3a0bSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
4645d0429a3STudor Ambarus 	u32 *desc;
4654cbe79ccSHoria Geantă 	int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
4664cbe79ccSHoria Geantă 			ctx->cdata.keylen;
4675d0429a3STudor Ambarus 
468db57656bSHoria Geantă 	if (!ctx->cdata.keylen || !ctx->authsize)
4695d0429a3STudor Ambarus 		return 0;
4705d0429a3STudor Ambarus 
4715d0429a3STudor Ambarus 	/*
4725d0429a3STudor Ambarus 	 * RFC4543 encrypt shared descriptor
4735d0429a3STudor Ambarus 	 * Job Descriptor and Shared Descriptor
4745d0429a3STudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
4755d0429a3STudor Ambarus 	 */
4764cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_RFC4543_ENC_LEN) {
477db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
4789c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
479db57656bSHoria Geantă 	} else {
480db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
4819c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
482db57656bSHoria Geantă 	}
4835d0429a3STudor Ambarus 
4845d0429a3STudor Ambarus 	desc = ctx->sh_desc_enc;
48587ec3a0bSHoria Geantă 	cnstr_shdsc_rfc4543_encap(desc, &ctx->cdata, ivsize, ctx->authsize,
48687ec3a0bSHoria Geantă 				  false);
487bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
4887e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
4895d0429a3STudor Ambarus 
4905d0429a3STudor Ambarus 	/*
4915d0429a3STudor Ambarus 	 * Job Descriptor and Shared Descriptors
4925d0429a3STudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
4935d0429a3STudor Ambarus 	 */
4944cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_RFC4543_DEC_LEN) {
495db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
4969c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
497db57656bSHoria Geantă 	} else {
498db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
4999c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
500db57656bSHoria Geantă 	}
5015d0429a3STudor Ambarus 
5025d0429a3STudor Ambarus 	desc = ctx->sh_desc_dec;
50387ec3a0bSHoria Geantă 	cnstr_shdsc_rfc4543_decap(desc, &ctx->cdata, ivsize, ctx->authsize,
50487ec3a0bSHoria Geantă 				  false);
505bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
5067e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
5075d0429a3STudor Ambarus 
5085d0429a3STudor Ambarus 	return 0;
5095d0429a3STudor Ambarus }
5105d0429a3STudor Ambarus 
5115d0429a3STudor Ambarus static int rfc4543_setauthsize(struct crypto_aead *authenc,
5125d0429a3STudor Ambarus 			       unsigned int authsize)
5135d0429a3STudor Ambarus {
5145d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
5155d0429a3STudor Ambarus 
51668a51394SIuliana Prodan 	if (authsize != 16)
51768a51394SIuliana Prodan 		return -EINVAL;
51868a51394SIuliana Prodan 
5195d0429a3STudor Ambarus 	ctx->authsize = authsize;
5205d0429a3STudor Ambarus 	rfc4543_set_sh_desc(authenc);
5215d0429a3STudor Ambarus 
5225d0429a3STudor Ambarus 	return 0;
5235d0429a3STudor Ambarus }
5245d0429a3STudor Ambarus 
525d6bbd4eeSHoria Geantă static int chachapoly_set_sh_desc(struct crypto_aead *aead)
526d6bbd4eeSHoria Geantă {
527d6bbd4eeSHoria Geantă 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
528d6bbd4eeSHoria Geantă 	struct device *jrdev = ctx->jrdev;
529d6bbd4eeSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
530d6bbd4eeSHoria Geantă 	u32 *desc;
531d6bbd4eeSHoria Geantă 
532d6bbd4eeSHoria Geantă 	if (!ctx->cdata.keylen || !ctx->authsize)
533d6bbd4eeSHoria Geantă 		return 0;
534d6bbd4eeSHoria Geantă 
535d6bbd4eeSHoria Geantă 	desc = ctx->sh_desc_enc;
536d6bbd4eeSHoria Geantă 	cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize,
537c10a5336SHoria Geantă 			       ctx->authsize, true, false);
538d6bbd4eeSHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
539d6bbd4eeSHoria Geantă 				   desc_bytes(desc), ctx->dir);
540d6bbd4eeSHoria Geantă 
541d6bbd4eeSHoria Geantă 	desc = ctx->sh_desc_dec;
542d6bbd4eeSHoria Geantă 	cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize,
543c10a5336SHoria Geantă 			       ctx->authsize, false, false);
544d6bbd4eeSHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
545d6bbd4eeSHoria Geantă 				   desc_bytes(desc), ctx->dir);
546d6bbd4eeSHoria Geantă 
547d6bbd4eeSHoria Geantă 	return 0;
548d6bbd4eeSHoria Geantă }
549d6bbd4eeSHoria Geantă 
550d6bbd4eeSHoria Geantă static int chachapoly_setauthsize(struct crypto_aead *aead,
551d6bbd4eeSHoria Geantă 				  unsigned int authsize)
552d6bbd4eeSHoria Geantă {
553d6bbd4eeSHoria Geantă 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
554d6bbd4eeSHoria Geantă 
555d6bbd4eeSHoria Geantă 	if (authsize != POLY1305_DIGEST_SIZE)
556d6bbd4eeSHoria Geantă 		return -EINVAL;
557d6bbd4eeSHoria Geantă 
558d6bbd4eeSHoria Geantă 	ctx->authsize = authsize;
559d6bbd4eeSHoria Geantă 	return chachapoly_set_sh_desc(aead);
560d6bbd4eeSHoria Geantă }
561d6bbd4eeSHoria Geantă 
562d6bbd4eeSHoria Geantă static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key,
563d6bbd4eeSHoria Geantă 			     unsigned int keylen)
564d6bbd4eeSHoria Geantă {
565d6bbd4eeSHoria Geantă 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
566d6bbd4eeSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
567d6bbd4eeSHoria Geantă 	unsigned int saltlen = CHACHAPOLY_IV_SIZE - ivsize;
568d6bbd4eeSHoria Geantă 
5691ca1b917SEric Biggers 	if (keylen != CHACHA_KEY_SIZE + saltlen) {
570d6bbd4eeSHoria Geantă 		crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
571d6bbd4eeSHoria Geantă 		return -EINVAL;
572d6bbd4eeSHoria Geantă 	}
573d6bbd4eeSHoria Geantă 
574d6bbd4eeSHoria Geantă 	ctx->cdata.key_virt = key;
575d6bbd4eeSHoria Geantă 	ctx->cdata.keylen = keylen - saltlen;
576d6bbd4eeSHoria Geantă 
577d6bbd4eeSHoria Geantă 	return chachapoly_set_sh_desc(aead);
578d6bbd4eeSHoria Geantă }
579d6bbd4eeSHoria Geantă 
5800e479300SYuan Kang static int aead_setkey(struct crypto_aead *aead,
5818e8ec596SKim Phillips 			       const u8 *key, unsigned int keylen)
5828e8ec596SKim Phillips {
5838e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
5848e8ec596SKim Phillips 	struct device *jrdev = ctx->jrdev;
5857e0880b9SHoria Geantă 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
5864e6e0b27SHoria Geanta 	struct crypto_authenc_keys keys;
5878e8ec596SKim Phillips 	int ret = 0;
5888e8ec596SKim Phillips 
5894e6e0b27SHoria Geanta 	if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
5908e8ec596SKim Phillips 		goto badkey;
5918e8ec596SKim Phillips 
5926e005503SSascha Hauer 	dev_dbg(jrdev, "keylen %d enckeylen %d authkeylen %d\n",
5934e6e0b27SHoria Geanta 	       keys.authkeylen + keys.enckeylen, keys.enckeylen,
5944e6e0b27SHoria Geanta 	       keys.authkeylen);
5956e005503SSascha Hauer 	print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
5968e8ec596SKim Phillips 			     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
5978e8ec596SKim Phillips 
5987e0880b9SHoria Geantă 	/*
5997e0880b9SHoria Geantă 	 * If DKP is supported, use it in the shared descriptor to generate
6007e0880b9SHoria Geantă 	 * the split key.
6017e0880b9SHoria Geantă 	 */
6027e0880b9SHoria Geantă 	if (ctrlpriv->era >= 6) {
6037e0880b9SHoria Geantă 		ctx->adata.keylen = keys.authkeylen;
6047e0880b9SHoria Geantă 		ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype &
6057e0880b9SHoria Geantă 						      OP_ALG_ALGSEL_MASK);
6067e0880b9SHoria Geantă 
6077e0880b9SHoria Geantă 		if (ctx->adata.keylen_pad + keys.enckeylen > CAAM_MAX_KEY_SIZE)
6087e0880b9SHoria Geantă 			goto badkey;
6097e0880b9SHoria Geantă 
6107e0880b9SHoria Geantă 		memcpy(ctx->key, keys.authkey, keys.authkeylen);
6117e0880b9SHoria Geantă 		memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey,
6127e0880b9SHoria Geantă 		       keys.enckeylen);
6137e0880b9SHoria Geantă 		dma_sync_single_for_device(jrdev, ctx->key_dma,
6147e0880b9SHoria Geantă 					   ctx->adata.keylen_pad +
6157e0880b9SHoria Geantă 					   keys.enckeylen, ctx->dir);
6167e0880b9SHoria Geantă 		goto skip_split_key;
6177e0880b9SHoria Geantă 	}
6187e0880b9SHoria Geantă 
6196655cb8eSHoria Geantă 	ret = gen_split_key(ctx->jrdev, ctx->key, &ctx->adata, keys.authkey,
6206655cb8eSHoria Geantă 			    keys.authkeylen, CAAM_MAX_KEY_SIZE -
6216655cb8eSHoria Geantă 			    keys.enckeylen);
6228e8ec596SKim Phillips 	if (ret) {
6238e8ec596SKim Phillips 		goto badkey;
6248e8ec596SKim Phillips 	}
6258e8ec596SKim Phillips 
6268e8ec596SKim Phillips 	/* postpend encryption key to auth split key */
627db57656bSHoria Geantă 	memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen);
628bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->adata.keylen_pad +
6297e0880b9SHoria Geantă 				   keys.enckeylen, ctx->dir);
6306e005503SSascha Hauer 
6316e005503SSascha Hauer 	print_hex_dump_debug("ctx.key@"__stringify(__LINE__)": ",
6328e8ec596SKim Phillips 			     DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
633db57656bSHoria Geantă 			     ctx->adata.keylen_pad + keys.enckeylen, 1);
6347e0880b9SHoria Geantă 
6357e0880b9SHoria Geantă skip_split_key:
636db57656bSHoria Geantă 	ctx->cdata.keylen = keys.enckeylen;
63761dab972STudor-Dan Ambarus 	memzero_explicit(&keys, sizeof(keys));
638bbf22344SHoria Geantă 	return aead_set_sh_desc(aead);
6398e8ec596SKim Phillips badkey:
6408e8ec596SKim Phillips 	crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
64161dab972STudor-Dan Ambarus 	memzero_explicit(&keys, sizeof(keys));
6428e8ec596SKim Phillips 	return -EINVAL;
6438e8ec596SKim Phillips }
6448e8ec596SKim Phillips 
6451b52c409SHerbert Xu static int des3_aead_setkey(struct crypto_aead *aead, const u8 *key,
6461b52c409SHerbert Xu 			    unsigned int keylen)
6471b52c409SHerbert Xu {
6481b52c409SHerbert Xu 	struct crypto_authenc_keys keys;
6491b52c409SHerbert Xu 	u32 flags;
6501b52c409SHerbert Xu 	int err;
6511b52c409SHerbert Xu 
6521b52c409SHerbert Xu 	err = crypto_authenc_extractkeys(&keys, key, keylen);
6531b52c409SHerbert Xu 	if (unlikely(err))
6541b52c409SHerbert Xu 		goto badkey;
6551b52c409SHerbert Xu 
6561b52c409SHerbert Xu 	err = -EINVAL;
6571b52c409SHerbert Xu 	if (keys.enckeylen != DES3_EDE_KEY_SIZE)
6581b52c409SHerbert Xu 		goto badkey;
6591b52c409SHerbert Xu 
6601b52c409SHerbert Xu 	flags = crypto_aead_get_flags(aead);
6611b52c409SHerbert Xu 	err = __des3_verify_key(&flags, keys.enckey);
6621b52c409SHerbert Xu 	if (unlikely(err)) {
6631b52c409SHerbert Xu 		crypto_aead_set_flags(aead, flags);
6641b52c409SHerbert Xu 		goto out;
6651b52c409SHerbert Xu 	}
6661b52c409SHerbert Xu 
6671b52c409SHerbert Xu 	err = aead_setkey(aead, key, keylen);
6681b52c409SHerbert Xu 
6691b52c409SHerbert Xu out:
6701b52c409SHerbert Xu 	memzero_explicit(&keys, sizeof(keys));
6711b52c409SHerbert Xu 	return err;
6721b52c409SHerbert Xu 
6731b52c409SHerbert Xu badkey:
6741b52c409SHerbert Xu 	crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
6751b52c409SHerbert Xu 	goto out;
6761b52c409SHerbert Xu }
6771b52c409SHerbert Xu 
6783ef8d945STudor Ambarus static int gcm_setkey(struct crypto_aead *aead,
6793ef8d945STudor Ambarus 		      const u8 *key, unsigned int keylen)
6803ef8d945STudor Ambarus {
6813ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
6823ef8d945STudor Ambarus 	struct device *jrdev = ctx->jrdev;
683836d8f43SIuliana Prodan 	int err;
684836d8f43SIuliana Prodan 
685836d8f43SIuliana Prodan 	err = aes_check_keylen(keylen);
686836d8f43SIuliana Prodan 	if (err) {
687836d8f43SIuliana Prodan 		crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
688836d8f43SIuliana Prodan 		return err;
689836d8f43SIuliana Prodan 	}
6903ef8d945STudor Ambarus 
6916e005503SSascha Hauer 	print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
6923ef8d945STudor Ambarus 			     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
6933ef8d945STudor Ambarus 
6943ef8d945STudor Ambarus 	memcpy(ctx->key, key, keylen);
6957e0880b9SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, ctx->dir);
696db57656bSHoria Geantă 	ctx->cdata.keylen = keylen;
6973ef8d945STudor Ambarus 
698bbf22344SHoria Geantă 	return gcm_set_sh_desc(aead);
6993ef8d945STudor Ambarus }
7003ef8d945STudor Ambarus 
701bac68f2cSTudor Ambarus static int rfc4106_setkey(struct crypto_aead *aead,
702bac68f2cSTudor Ambarus 			  const u8 *key, unsigned int keylen)
703bac68f2cSTudor Ambarus {
704bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
705bac68f2cSTudor Ambarus 	struct device *jrdev = ctx->jrdev;
706836d8f43SIuliana Prodan 	int err;
707bac68f2cSTudor Ambarus 
708836d8f43SIuliana Prodan 	err = aes_check_keylen(keylen - 4);
709836d8f43SIuliana Prodan 	if (err) {
710836d8f43SIuliana Prodan 		crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
711836d8f43SIuliana Prodan 		return err;
712836d8f43SIuliana Prodan 	}
713bac68f2cSTudor Ambarus 
7146e005503SSascha Hauer 	print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
715bac68f2cSTudor Ambarus 			     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
716bac68f2cSTudor Ambarus 
717bac68f2cSTudor Ambarus 	memcpy(ctx->key, key, keylen);
718bac68f2cSTudor Ambarus 
719bac68f2cSTudor Ambarus 	/*
720bac68f2cSTudor Ambarus 	 * The last four bytes of the key material are used as the salt value
721bac68f2cSTudor Ambarus 	 * in the nonce. Update the AES key length.
722bac68f2cSTudor Ambarus 	 */
723db57656bSHoria Geantă 	ctx->cdata.keylen = keylen - 4;
724bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
7257e0880b9SHoria Geantă 				   ctx->dir);
726bbf22344SHoria Geantă 	return rfc4106_set_sh_desc(aead);
727bac68f2cSTudor Ambarus }
728bac68f2cSTudor Ambarus 
7295d0429a3STudor Ambarus static int rfc4543_setkey(struct crypto_aead *aead,
7305d0429a3STudor Ambarus 			  const u8 *key, unsigned int keylen)
7315d0429a3STudor Ambarus {
7325d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
7335d0429a3STudor Ambarus 	struct device *jrdev = ctx->jrdev;
734836d8f43SIuliana Prodan 	int err;
7355d0429a3STudor Ambarus 
736836d8f43SIuliana Prodan 	err = aes_check_keylen(keylen - 4);
737836d8f43SIuliana Prodan 	if (err) {
738836d8f43SIuliana Prodan 		crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
739836d8f43SIuliana Prodan 		return err;
740836d8f43SIuliana Prodan 	}
7415d0429a3STudor Ambarus 
7426e005503SSascha Hauer 	print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
7435d0429a3STudor Ambarus 			     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
7445d0429a3STudor Ambarus 
7455d0429a3STudor Ambarus 	memcpy(ctx->key, key, keylen);
7465d0429a3STudor Ambarus 
7475d0429a3STudor Ambarus 	/*
7485d0429a3STudor Ambarus 	 * The last four bytes of the key material are used as the salt value
7495d0429a3STudor Ambarus 	 * in the nonce. Update the AES key length.
7505d0429a3STudor Ambarus 	 */
751db57656bSHoria Geantă 	ctx->cdata.keylen = keylen - 4;
752bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
7537e0880b9SHoria Geantă 				   ctx->dir);
754bbf22344SHoria Geantă 	return rfc4543_set_sh_desc(aead);
7555d0429a3STudor Ambarus }
7565d0429a3STudor Ambarus 
7575ca7badbSHoria Geantă static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
758836d8f43SIuliana Prodan 			   unsigned int keylen, const u32 ctx1_iv_off)
759acdca31dSYuan Kang {
7605ca7badbSHoria Geantă 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
7615ca7badbSHoria Geantă 	struct caam_skcipher_alg *alg =
7625ca7badbSHoria Geantă 		container_of(crypto_skcipher_alg(skcipher), typeof(*alg),
7635ca7badbSHoria Geantă 			     skcipher);
764acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
7655ca7badbSHoria Geantă 	unsigned int ivsize = crypto_skcipher_ivsize(skcipher);
766acdca31dSYuan Kang 	u32 *desc;
7675ca7badbSHoria Geantă 	const bool is_rfc3686 = alg->caam.rfc3686;
768acdca31dSYuan Kang 
7696e005503SSascha Hauer 	print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
770acdca31dSYuan Kang 			     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
771a5f57cffSCatalin Vasile 
772db57656bSHoria Geantă 	ctx->cdata.keylen = keylen;
773662f70edSHoria Geantă 	ctx->cdata.key_virt = key;
774db57656bSHoria Geantă 	ctx->cdata.key_inline = true;
775acdca31dSYuan Kang 
7765ca7badbSHoria Geantă 	/* skcipher_encrypt shared descriptor */
777acdca31dSYuan Kang 	desc = ctx->sh_desc_enc;
7789dbe3072SHoria Geantă 	cnstr_shdsc_skcipher_encap(desc, &ctx->cdata, ivsize, is_rfc3686,
7798cea7b66SHoria Geantă 				   ctx1_iv_off);
780bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
7817e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
7828cea7b66SHoria Geantă 
7835ca7badbSHoria Geantă 	/* skcipher_decrypt shared descriptor */
784acdca31dSYuan Kang 	desc = ctx->sh_desc_dec;
7859dbe3072SHoria Geantă 	cnstr_shdsc_skcipher_decap(desc, &ctx->cdata, ivsize, is_rfc3686,
7868cea7b66SHoria Geantă 				   ctx1_iv_off);
787bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
7887e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
789acdca31dSYuan Kang 
7908cea7b66SHoria Geantă 	return 0;
791acdca31dSYuan Kang }
792acdca31dSYuan Kang 
793836d8f43SIuliana Prodan static int aes_skcipher_setkey(struct crypto_skcipher *skcipher,
794836d8f43SIuliana Prodan 			       const u8 *key, unsigned int keylen)
795836d8f43SIuliana Prodan {
796836d8f43SIuliana Prodan 	int err;
797836d8f43SIuliana Prodan 
798836d8f43SIuliana Prodan 	err = aes_check_keylen(keylen);
799836d8f43SIuliana Prodan 	if (err) {
800836d8f43SIuliana Prodan 		crypto_skcipher_set_flags(skcipher,
801836d8f43SIuliana Prodan 					  CRYPTO_TFM_RES_BAD_KEY_LEN);
802836d8f43SIuliana Prodan 		return err;
803836d8f43SIuliana Prodan 	}
804836d8f43SIuliana Prodan 
805836d8f43SIuliana Prodan 	return skcipher_setkey(skcipher, key, keylen, 0);
806836d8f43SIuliana Prodan }
807836d8f43SIuliana Prodan 
808836d8f43SIuliana Prodan static int rfc3686_skcipher_setkey(struct crypto_skcipher *skcipher,
809836d8f43SIuliana Prodan 				   const u8 *key, unsigned int keylen)
810836d8f43SIuliana Prodan {
811836d8f43SIuliana Prodan 	u32 ctx1_iv_off;
812836d8f43SIuliana Prodan 	int err;
813836d8f43SIuliana Prodan 
814836d8f43SIuliana Prodan 	/*
815836d8f43SIuliana Prodan 	 * RFC3686 specific:
816836d8f43SIuliana Prodan 	 *	| CONTEXT1[255:128] = {NONCE, IV, COUNTER}
817836d8f43SIuliana Prodan 	 *	| *key = {KEY, NONCE}
818836d8f43SIuliana Prodan 	 */
819836d8f43SIuliana Prodan 	ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
820836d8f43SIuliana Prodan 	keylen -= CTR_RFC3686_NONCE_SIZE;
821836d8f43SIuliana Prodan 
822836d8f43SIuliana Prodan 	err = aes_check_keylen(keylen);
823836d8f43SIuliana Prodan 	if (err) {
824836d8f43SIuliana Prodan 		crypto_skcipher_set_flags(skcipher,
825836d8f43SIuliana Prodan 					  CRYPTO_TFM_RES_BAD_KEY_LEN);
826836d8f43SIuliana Prodan 		return err;
827836d8f43SIuliana Prodan 	}
828836d8f43SIuliana Prodan 
829836d8f43SIuliana Prodan 	return skcipher_setkey(skcipher, key, keylen, ctx1_iv_off);
830836d8f43SIuliana Prodan }
831836d8f43SIuliana Prodan 
832836d8f43SIuliana Prodan static int ctr_skcipher_setkey(struct crypto_skcipher *skcipher,
833836d8f43SIuliana Prodan 			       const u8 *key, unsigned int keylen)
834836d8f43SIuliana Prodan {
835836d8f43SIuliana Prodan 	u32 ctx1_iv_off;
836836d8f43SIuliana Prodan 	int err;
837836d8f43SIuliana Prodan 
838836d8f43SIuliana Prodan 	/*
839836d8f43SIuliana Prodan 	 * AES-CTR needs to load IV in CONTEXT1 reg
840836d8f43SIuliana Prodan 	 * at an offset of 128bits (16bytes)
841836d8f43SIuliana Prodan 	 * CONTEXT1[255:128] = IV
842836d8f43SIuliana Prodan 	 */
843836d8f43SIuliana Prodan 	ctx1_iv_off = 16;
844836d8f43SIuliana Prodan 
845836d8f43SIuliana Prodan 	err = aes_check_keylen(keylen);
846836d8f43SIuliana Prodan 	if (err) {
847836d8f43SIuliana Prodan 		crypto_skcipher_set_flags(skcipher,
848836d8f43SIuliana Prodan 					  CRYPTO_TFM_RES_BAD_KEY_LEN);
849836d8f43SIuliana Prodan 		return err;
850836d8f43SIuliana Prodan 	}
851836d8f43SIuliana Prodan 
852836d8f43SIuliana Prodan 	return skcipher_setkey(skcipher, key, keylen, ctx1_iv_off);
853836d8f43SIuliana Prodan }
854836d8f43SIuliana Prodan 
855836d8f43SIuliana Prodan static int arc4_skcipher_setkey(struct crypto_skcipher *skcipher,
856836d8f43SIuliana Prodan 				const u8 *key, unsigned int keylen)
857836d8f43SIuliana Prodan {
858836d8f43SIuliana Prodan 	return skcipher_setkey(skcipher, key, keylen, 0);
859836d8f43SIuliana Prodan }
860836d8f43SIuliana Prodan 
861eaed71a4SIuliana Prodan static int des_skcipher_setkey(struct crypto_skcipher *skcipher,
862eaed71a4SIuliana Prodan 			       const u8 *key, unsigned int keylen)
863eaed71a4SIuliana Prodan {
864eaed71a4SIuliana Prodan 	u32 tmp[DES3_EDE_EXPKEY_WORDS];
865eaed71a4SIuliana Prodan 	struct crypto_tfm *tfm = crypto_skcipher_tfm(skcipher);
866eaed71a4SIuliana Prodan 
867eaed71a4SIuliana Prodan 	if (keylen == DES3_EDE_KEY_SIZE &&
868eaed71a4SIuliana Prodan 	    __des3_ede_setkey(tmp, &tfm->crt_flags, key, DES3_EDE_KEY_SIZE)) {
869eaed71a4SIuliana Prodan 		return -EINVAL;
870eaed71a4SIuliana Prodan 	}
871eaed71a4SIuliana Prodan 
872eaed71a4SIuliana Prodan 	if (!des_ekey(tmp, key) && (crypto_skcipher_get_flags(skcipher) &
873eaed71a4SIuliana Prodan 	    CRYPTO_TFM_REQ_FORBID_WEAK_KEYS)) {
874eaed71a4SIuliana Prodan 		crypto_skcipher_set_flags(skcipher,
875eaed71a4SIuliana Prodan 					  CRYPTO_TFM_RES_WEAK_KEY);
876eaed71a4SIuliana Prodan 		return -EINVAL;
877eaed71a4SIuliana Prodan 	}
878eaed71a4SIuliana Prodan 
879836d8f43SIuliana Prodan 	return skcipher_setkey(skcipher, key, keylen, 0);
880eaed71a4SIuliana Prodan }
881eaed71a4SIuliana Prodan 
8825ca7badbSHoria Geantă static int xts_skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
8835ca7badbSHoria Geantă 			       unsigned int keylen)
884c6415a60SCatalin Vasile {
8855ca7badbSHoria Geantă 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
886c6415a60SCatalin Vasile 	struct device *jrdev = ctx->jrdev;
8878cea7b66SHoria Geantă 	u32 *desc;
888c6415a60SCatalin Vasile 
889c6415a60SCatalin Vasile 	if (keylen != 2 * AES_MIN_KEY_SIZE  && keylen != 2 * AES_MAX_KEY_SIZE) {
8905ca7badbSHoria Geantă 		crypto_skcipher_set_flags(skcipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
891c6415a60SCatalin Vasile 		dev_err(jrdev, "key size mismatch\n");
892c6415a60SCatalin Vasile 		return -EINVAL;
893c6415a60SCatalin Vasile 	}
894c6415a60SCatalin Vasile 
895db57656bSHoria Geantă 	ctx->cdata.keylen = keylen;
896662f70edSHoria Geantă 	ctx->cdata.key_virt = key;
897db57656bSHoria Geantă 	ctx->cdata.key_inline = true;
898c6415a60SCatalin Vasile 
8995ca7badbSHoria Geantă 	/* xts_skcipher_encrypt shared descriptor */
900c6415a60SCatalin Vasile 	desc = ctx->sh_desc_enc;
9019dbe3072SHoria Geantă 	cnstr_shdsc_xts_skcipher_encap(desc, &ctx->cdata);
902bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
9037e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
904c6415a60SCatalin Vasile 
9055ca7badbSHoria Geantă 	/* xts_skcipher_decrypt shared descriptor */
906c6415a60SCatalin Vasile 	desc = ctx->sh_desc_dec;
9079dbe3072SHoria Geantă 	cnstr_shdsc_xts_skcipher_decap(desc, &ctx->cdata);
908bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
9097e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
910c6415a60SCatalin Vasile 
911c6415a60SCatalin Vasile 	return 0;
912c6415a60SCatalin Vasile }
913c6415a60SCatalin Vasile 
9148e8ec596SKim Phillips /*
9151acebad3SYuan Kang  * aead_edesc - s/w-extended aead descriptor
916fa0c92dbSHoria Geantă  * @src_nents: number of segments in input s/w scatterlist
917fa0c92dbSHoria Geantă  * @dst_nents: number of segments in output s/w scatterlist
918ba4cf71bSIuliana Prodan  * @mapped_src_nents: number of segments in input h/w link table
919ba4cf71bSIuliana Prodan  * @mapped_dst_nents: number of segments in output h/w link table
920a299c837SYuan Kang  * @sec4_sg_bytes: length of dma mapped sec4_sg space
921a299c837SYuan Kang  * @sec4_sg_dma: bus physical mapped address of h/w link table
9224ca7c7d8SHoria Geantă  * @sec4_sg: pointer to h/w link table
9238e8ec596SKim Phillips  * @hw_desc: the h/w job descriptor followed by any referenced link tables
9248e8ec596SKim Phillips  */
9250e479300SYuan Kang struct aead_edesc {
9268e8ec596SKim Phillips 	int src_nents;
9278e8ec596SKim Phillips 	int dst_nents;
928ba4cf71bSIuliana Prodan 	int mapped_src_nents;
929ba4cf71bSIuliana Prodan 	int mapped_dst_nents;
930a299c837SYuan Kang 	int sec4_sg_bytes;
931a299c837SYuan Kang 	dma_addr_t sec4_sg_dma;
932a299c837SYuan Kang 	struct sec4_sg_entry *sec4_sg;
933f2147b88SHerbert Xu 	u32 hw_desc[];
9348e8ec596SKim Phillips };
9358e8ec596SKim Phillips 
936acdca31dSYuan Kang /*
9375ca7badbSHoria Geantă  * skcipher_edesc - s/w-extended skcipher descriptor
938fa0c92dbSHoria Geantă  * @src_nents: number of segments in input s/w scatterlist
939fa0c92dbSHoria Geantă  * @dst_nents: number of segments in output s/w scatterlist
940ba4cf71bSIuliana Prodan  * @mapped_src_nents: number of segments in input h/w link table
941ba4cf71bSIuliana Prodan  * @mapped_dst_nents: number of segments in output h/w link table
942acdca31dSYuan Kang  * @iv_dma: dma address of iv for checking continuity and link table
943a299c837SYuan Kang  * @sec4_sg_bytes: length of dma mapped sec4_sg space
944a299c837SYuan Kang  * @sec4_sg_dma: bus physical mapped address of h/w link table
9454ca7c7d8SHoria Geantă  * @sec4_sg: pointer to h/w link table
946acdca31dSYuan Kang  * @hw_desc: the h/w job descriptor followed by any referenced link tables
947115957bbSHoria Geantă  *	     and IV
948acdca31dSYuan Kang  */
9495ca7badbSHoria Geantă struct skcipher_edesc {
950acdca31dSYuan Kang 	int src_nents;
951acdca31dSYuan Kang 	int dst_nents;
952ba4cf71bSIuliana Prodan 	int mapped_src_nents;
953ba4cf71bSIuliana Prodan 	int mapped_dst_nents;
954acdca31dSYuan Kang 	dma_addr_t iv_dma;
955a299c837SYuan Kang 	int sec4_sg_bytes;
956a299c837SYuan Kang 	dma_addr_t sec4_sg_dma;
957a299c837SYuan Kang 	struct sec4_sg_entry *sec4_sg;
958acdca31dSYuan Kang 	u32 hw_desc[0];
959acdca31dSYuan Kang };
960acdca31dSYuan Kang 
9611acebad3SYuan Kang static void caam_unmap(struct device *dev, struct scatterlist *src,
962643b39b0SYuan Kang 		       struct scatterlist *dst, int src_nents,
96313fb8fd7SLABBE Corentin 		       int dst_nents,
964cf5448b5SHoria Geantă 		       dma_addr_t iv_dma, int ivsize, dma_addr_t sec4_sg_dma,
965a299c837SYuan Kang 		       int sec4_sg_bytes)
9661acebad3SYuan Kang {
967643b39b0SYuan Kang 	if (dst != src) {
968fa0c92dbSHoria Geantă 		if (src_nents)
969fa0c92dbSHoria Geantă 			dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
970763069baSHoria Geantă 		if (dst_nents)
971fa0c92dbSHoria Geantă 			dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
9721acebad3SYuan Kang 	} else {
973fa0c92dbSHoria Geantă 		dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
9741acebad3SYuan Kang 	}
9751acebad3SYuan Kang 
9761acebad3SYuan Kang 	if (iv_dma)
977334d37c9SHoria Geantă 		dma_unmap_single(dev, iv_dma, ivsize, DMA_BIDIRECTIONAL);
978a299c837SYuan Kang 	if (sec4_sg_bytes)
979a299c837SYuan Kang 		dma_unmap_single(dev, sec4_sg_dma, sec4_sg_bytes,
9801acebad3SYuan Kang 				 DMA_TO_DEVICE);
9811acebad3SYuan Kang }
9821acebad3SYuan Kang 
9830e479300SYuan Kang static void aead_unmap(struct device *dev,
9840e479300SYuan Kang 		       struct aead_edesc *edesc,
9850e479300SYuan Kang 		       struct aead_request *req)
9868e8ec596SKim Phillips {
987f2147b88SHerbert Xu 	caam_unmap(dev, req->src, req->dst,
988cf5448b5SHoria Geantă 		   edesc->src_nents, edesc->dst_nents, 0, 0,
989f2147b88SHerbert Xu 		   edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
990f2147b88SHerbert Xu }
991f2147b88SHerbert Xu 
9925ca7badbSHoria Geantă static void skcipher_unmap(struct device *dev, struct skcipher_edesc *edesc,
9935ca7badbSHoria Geantă 			   struct skcipher_request *req)
994acdca31dSYuan Kang {
9955ca7badbSHoria Geantă 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
9965ca7badbSHoria Geantă 	int ivsize = crypto_skcipher_ivsize(skcipher);
997acdca31dSYuan Kang 
998acdca31dSYuan Kang 	caam_unmap(dev, req->src, req->dst,
99913fb8fd7SLABBE Corentin 		   edesc->src_nents, edesc->dst_nents,
1000cf5448b5SHoria Geantă 		   edesc->iv_dma, ivsize,
1001643b39b0SYuan Kang 		   edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
1002acdca31dSYuan Kang }
1003acdca31dSYuan Kang 
10040e479300SYuan Kang static void aead_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
10058e8ec596SKim Phillips 				   void *context)
10068e8ec596SKim Phillips {
10070e479300SYuan Kang 	struct aead_request *req = context;
10080e479300SYuan Kang 	struct aead_edesc *edesc;
10091984aaeeSHoria Geantă 	int ecode = 0;
1010f2147b88SHerbert Xu 
10116e005503SSascha Hauer 	dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
1012f2147b88SHerbert Xu 
1013f2147b88SHerbert Xu 	edesc = container_of(desc, struct aead_edesc, hw_desc[0]);
1014f2147b88SHerbert Xu 
1015f2147b88SHerbert Xu 	if (err)
10161984aaeeSHoria Geantă 		ecode = caam_jr_strstatus(jrdev, err);
1017f2147b88SHerbert Xu 
1018f2147b88SHerbert Xu 	aead_unmap(jrdev, edesc, req);
1019f2147b88SHerbert Xu 
1020f2147b88SHerbert Xu 	kfree(edesc);
1021f2147b88SHerbert Xu 
10221984aaeeSHoria Geantă 	aead_request_complete(req, ecode);
1023f2147b88SHerbert Xu }
1024f2147b88SHerbert Xu 
10250e479300SYuan Kang static void aead_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
10268e8ec596SKim Phillips 				   void *context)
10278e8ec596SKim Phillips {
10280e479300SYuan Kang 	struct aead_request *req = context;
10290e479300SYuan Kang 	struct aead_edesc *edesc;
10301984aaeeSHoria Geantă 	int ecode = 0;
1031f2147b88SHerbert Xu 
10326e005503SSascha Hauer 	dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
1033f2147b88SHerbert Xu 
1034f2147b88SHerbert Xu 	edesc = container_of(desc, struct aead_edesc, hw_desc[0]);
1035f2147b88SHerbert Xu 
1036f2147b88SHerbert Xu 	if (err)
10371984aaeeSHoria Geantă 		ecode = caam_jr_strstatus(jrdev, err);
1038f2147b88SHerbert Xu 
1039f2147b88SHerbert Xu 	aead_unmap(jrdev, edesc, req);
1040f2147b88SHerbert Xu 
1041f2147b88SHerbert Xu 	kfree(edesc);
1042f2147b88SHerbert Xu 
10431984aaeeSHoria Geantă 	aead_request_complete(req, ecode);
1044f2147b88SHerbert Xu }
1045f2147b88SHerbert Xu 
10465ca7badbSHoria Geantă static void skcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
1047acdca31dSYuan Kang 				  void *context)
1048acdca31dSYuan Kang {
10495ca7badbSHoria Geantă 	struct skcipher_request *req = context;
10505ca7badbSHoria Geantă 	struct skcipher_edesc *edesc;
10515ca7badbSHoria Geantă 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
10525ca7badbSHoria Geantă 	int ivsize = crypto_skcipher_ivsize(skcipher);
10531984aaeeSHoria Geantă 	int ecode = 0;
1054acdca31dSYuan Kang 
10556e005503SSascha Hauer 	dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
1056acdca31dSYuan Kang 
10575ca7badbSHoria Geantă 	edesc = container_of(desc, struct skcipher_edesc, hw_desc[0]);
1058acdca31dSYuan Kang 
1059fa9659cdSMarek Vasut 	if (err)
10601984aaeeSHoria Geantă 		ecode = caam_jr_strstatus(jrdev, err);
1061acdca31dSYuan Kang 
10625ca7badbSHoria Geantă 	skcipher_unmap(jrdev, edesc, req);
1063854b06f7SDavid Gstir 
1064854b06f7SDavid Gstir 	/*
10655ca7badbSHoria Geantă 	 * The crypto API expects us to set the IV (req->iv) to the last
1066334d37c9SHoria Geantă 	 * ciphertext block (CBC mode) or last counter (CTR mode).
1067334d37c9SHoria Geantă 	 * This is used e.g. by the CTS mode.
1068854b06f7SDavid Gstir 	 */
10691ccb39ebSHoria Geantă 	if (ivsize && !ecode) {
1070334d37c9SHoria Geantă 		memcpy(req->iv, (u8 *)edesc->sec4_sg + edesc->sec4_sg_bytes,
1071334d37c9SHoria Geantă 		       ivsize);
10726e005503SSascha Hauer 		print_hex_dump_debug("dstiv  @"__stringify(__LINE__)": ",
1073bb992bc4SSascha Hauer 				     DUMP_PREFIX_ADDRESS, 16, 4, req->iv,
1074bb992bc4SSascha Hauer 				     edesc->src_nents > 1 ? 100 : ivsize, 1);
1075334d37c9SHoria Geantă 	}
10766e005503SSascha Hauer 
10778a82451bSSascha Hauer 	caam_dump_sg("dst    @" __stringify(__LINE__)": ",
1078bb992bc4SSascha Hauer 		     DUMP_PREFIX_ADDRESS, 16, 4, req->dst,
1079bb992bc4SSascha Hauer 		     edesc->dst_nents > 1 ? 100 : req->cryptlen, 1);
1080bb992bc4SSascha Hauer 
1081acdca31dSYuan Kang 	kfree(edesc);
1082acdca31dSYuan Kang 
10831984aaeeSHoria Geantă 	skcipher_request_complete(req, ecode);
1084acdca31dSYuan Kang }
1085acdca31dSYuan Kang 
10865ca7badbSHoria Geantă static void skcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
1087acdca31dSYuan Kang 				  void *context)
1088acdca31dSYuan Kang {
10895ca7badbSHoria Geantă 	struct skcipher_request *req = context;
10905ca7badbSHoria Geantă 	struct skcipher_edesc *edesc;
10915ca7badbSHoria Geantă 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
10925ca7badbSHoria Geantă 	int ivsize = crypto_skcipher_ivsize(skcipher);
10931984aaeeSHoria Geantă 	int ecode = 0;
1094acdca31dSYuan Kang 
10956e005503SSascha Hauer 	dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
1096acdca31dSYuan Kang 
10975ca7badbSHoria Geantă 	edesc = container_of(desc, struct skcipher_edesc, hw_desc[0]);
1098fa9659cdSMarek Vasut 	if (err)
10991984aaeeSHoria Geantă 		ecode = caam_jr_strstatus(jrdev, err);
1100acdca31dSYuan Kang 
1101bb992bc4SSascha Hauer 	skcipher_unmap(jrdev, edesc, req);
1102bb992bc4SSascha Hauer 
1103334d37c9SHoria Geantă 	/*
1104334d37c9SHoria Geantă 	 * The crypto API expects us to set the IV (req->iv) to the last
1105334d37c9SHoria Geantă 	 * ciphertext block (CBC mode) or last counter (CTR mode).
1106334d37c9SHoria Geantă 	 * This is used e.g. by the CTS mode.
1107334d37c9SHoria Geantă 	 */
11081ccb39ebSHoria Geantă 	if (ivsize && !ecode) {
1109334d37c9SHoria Geantă 		memcpy(req->iv, (u8 *)edesc->sec4_sg + edesc->sec4_sg_bytes,
1110334d37c9SHoria Geantă 		       ivsize);
1111334d37c9SHoria Geantă 
11126e005503SSascha Hauer 		print_hex_dump_debug("dstiv  @" __stringify(__LINE__)": ",
1113334d37c9SHoria Geantă 				     DUMP_PREFIX_ADDRESS, 16, 4, req->iv,
1114334d37c9SHoria Geantă 				     ivsize, 1);
1115334d37c9SHoria Geantă 	}
1116334d37c9SHoria Geantă 
11178a82451bSSascha Hauer 	caam_dump_sg("dst    @" __stringify(__LINE__)": ",
11185ecf8ef9SCatalin Vasile 		     DUMP_PREFIX_ADDRESS, 16, 4, req->dst,
11195ca7badbSHoria Geantă 		     edesc->dst_nents > 1 ? 100 : req->cryptlen, 1);
1120acdca31dSYuan Kang 
1121acdca31dSYuan Kang 	kfree(edesc);
1122acdca31dSYuan Kang 
11231984aaeeSHoria Geantă 	skcipher_request_complete(req, ecode);
1124acdca31dSYuan Kang }
1125acdca31dSYuan Kang 
11268e8ec596SKim Phillips /*
11271acebad3SYuan Kang  * Fill in aead job descriptor
11288e8ec596SKim Phillips  */
1129f2147b88SHerbert Xu static void init_aead_job(struct aead_request *req,
1130f2147b88SHerbert Xu 			  struct aead_edesc *edesc,
1131f2147b88SHerbert Xu 			  bool all_contig, bool encrypt)
1132f2147b88SHerbert Xu {
1133f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1134f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1135f2147b88SHerbert Xu 	int authsize = ctx->authsize;
1136f2147b88SHerbert Xu 	u32 *desc = edesc->hw_desc;
1137f2147b88SHerbert Xu 	u32 out_options, in_options;
1138f2147b88SHerbert Xu 	dma_addr_t dst_dma, src_dma;
1139f2147b88SHerbert Xu 	int len, sec4_sg_index = 0;
1140f2147b88SHerbert Xu 	dma_addr_t ptr;
1141f2147b88SHerbert Xu 	u32 *sh_desc;
1142f2147b88SHerbert Xu 
1143f2147b88SHerbert Xu 	sh_desc = encrypt ? ctx->sh_desc_enc : ctx->sh_desc_dec;
1144f2147b88SHerbert Xu 	ptr = encrypt ? ctx->sh_desc_enc_dma : ctx->sh_desc_dec_dma;
1145f2147b88SHerbert Xu 
1146f2147b88SHerbert Xu 	len = desc_len(sh_desc);
1147f2147b88SHerbert Xu 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
1148f2147b88SHerbert Xu 
1149f2147b88SHerbert Xu 	if (all_contig) {
1150ba4cf71bSIuliana Prodan 		src_dma = edesc->mapped_src_nents ? sg_dma_address(req->src) :
1151ba4cf71bSIuliana Prodan 						    0;
1152f2147b88SHerbert Xu 		in_options = 0;
1153f2147b88SHerbert Xu 	} else {
1154f2147b88SHerbert Xu 		src_dma = edesc->sec4_sg_dma;
1155ba4cf71bSIuliana Prodan 		sec4_sg_index += edesc->mapped_src_nents;
1156f2147b88SHerbert Xu 		in_options = LDST_SGF;
1157f2147b88SHerbert Xu 	}
1158f2147b88SHerbert Xu 
1159f2147b88SHerbert Xu 	append_seq_in_ptr(desc, src_dma, req->assoclen + req->cryptlen,
1160f2147b88SHerbert Xu 			  in_options);
1161f2147b88SHerbert Xu 
1162f2147b88SHerbert Xu 	dst_dma = src_dma;
1163f2147b88SHerbert Xu 	out_options = in_options;
1164f2147b88SHerbert Xu 
1165f2147b88SHerbert Xu 	if (unlikely(req->src != req->dst)) {
1166ba4cf71bSIuliana Prodan 		if (!edesc->mapped_dst_nents) {
1167763069baSHoria Geantă 			dst_dma = 0;
1168dcd9c76eSHoria Geantă 			out_options = 0;
1169ba4cf71bSIuliana Prodan 		} else if (edesc->mapped_dst_nents == 1) {
1170f2147b88SHerbert Xu 			dst_dma = sg_dma_address(req->dst);
117142e95d1fSPankaj Gupta 			out_options = 0;
1172f2147b88SHerbert Xu 		} else {
1173f2147b88SHerbert Xu 			dst_dma = edesc->sec4_sg_dma +
1174f2147b88SHerbert Xu 				  sec4_sg_index *
1175f2147b88SHerbert Xu 				  sizeof(struct sec4_sg_entry);
1176f2147b88SHerbert Xu 			out_options = LDST_SGF;
1177f2147b88SHerbert Xu 		}
1178f2147b88SHerbert Xu 	}
1179f2147b88SHerbert Xu 
1180f2147b88SHerbert Xu 	if (encrypt)
1181f2147b88SHerbert Xu 		append_seq_out_ptr(desc, dst_dma,
1182f2147b88SHerbert Xu 				   req->assoclen + req->cryptlen + authsize,
1183f2147b88SHerbert Xu 				   out_options);
1184f2147b88SHerbert Xu 	else
1185f2147b88SHerbert Xu 		append_seq_out_ptr(desc, dst_dma,
1186f2147b88SHerbert Xu 				   req->assoclen + req->cryptlen - authsize,
1187f2147b88SHerbert Xu 				   out_options);
1188f2147b88SHerbert Xu }
1189f2147b88SHerbert Xu 
1190f2147b88SHerbert Xu static void init_gcm_job(struct aead_request *req,
1191f2147b88SHerbert Xu 			 struct aead_edesc *edesc,
1192f2147b88SHerbert Xu 			 bool all_contig, bool encrypt)
1193f2147b88SHerbert Xu {
1194f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1195f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1196f2147b88SHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
1197f2147b88SHerbert Xu 	u32 *desc = edesc->hw_desc;
11987545e166SCorentin LABBE 	bool generic_gcm = (ivsize == GCM_AES_IV_SIZE);
1199f2147b88SHerbert Xu 	unsigned int last;
1200f2147b88SHerbert Xu 
1201f2147b88SHerbert Xu 	init_aead_job(req, edesc, all_contig, encrypt);
12027e0880b9SHoria Geantă 	append_math_add_imm_u32(desc, REG3, ZERO, IMM, req->assoclen);
1203f2147b88SHerbert Xu 
1204f2147b88SHerbert Xu 	/* BUG This should not be specific to generic GCM. */
1205f2147b88SHerbert Xu 	last = 0;
1206f2147b88SHerbert Xu 	if (encrypt && generic_gcm && !(req->assoclen + req->cryptlen))
1207f2147b88SHerbert Xu 		last = FIFOLD_TYPE_LAST1;
1208f2147b88SHerbert Xu 
1209f2147b88SHerbert Xu 	/* Read GCM IV */
1210f2147b88SHerbert Xu 	append_cmd(desc, CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 | IMMEDIATE |
12117545e166SCorentin LABBE 			 FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 | GCM_AES_IV_SIZE | last);
1212f2147b88SHerbert Xu 	/* Append Salt */
1213f2147b88SHerbert Xu 	if (!generic_gcm)
1214db57656bSHoria Geantă 		append_data(desc, ctx->key + ctx->cdata.keylen, 4);
1215f2147b88SHerbert Xu 	/* Append IV */
1216f2147b88SHerbert Xu 	append_data(desc, req->iv, ivsize);
1217f2147b88SHerbert Xu 	/* End of blank commands */
1218f2147b88SHerbert Xu }
1219f2147b88SHerbert Xu 
1220d6bbd4eeSHoria Geantă static void init_chachapoly_job(struct aead_request *req,
1221d6bbd4eeSHoria Geantă 				struct aead_edesc *edesc, bool all_contig,
1222d6bbd4eeSHoria Geantă 				bool encrypt)
1223d6bbd4eeSHoria Geantă {
1224d6bbd4eeSHoria Geantă 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1225d6bbd4eeSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
1226d6bbd4eeSHoria Geantă 	unsigned int assoclen = req->assoclen;
1227d6bbd4eeSHoria Geantă 	u32 *desc = edesc->hw_desc;
1228d6bbd4eeSHoria Geantă 	u32 ctx_iv_off = 4;
1229d6bbd4eeSHoria Geantă 
1230d6bbd4eeSHoria Geantă 	init_aead_job(req, edesc, all_contig, encrypt);
1231d6bbd4eeSHoria Geantă 
1232d6bbd4eeSHoria Geantă 	if (ivsize != CHACHAPOLY_IV_SIZE) {
1233d6bbd4eeSHoria Geantă 		/* IPsec specific: CONTEXT1[223:128] = {NONCE, IV} */
1234d6bbd4eeSHoria Geantă 		ctx_iv_off += 4;
1235d6bbd4eeSHoria Geantă 
1236d6bbd4eeSHoria Geantă 		/*
1237d6bbd4eeSHoria Geantă 		 * The associated data comes already with the IV but we need
1238d6bbd4eeSHoria Geantă 		 * to skip it when we authenticate or encrypt...
1239d6bbd4eeSHoria Geantă 		 */
1240d6bbd4eeSHoria Geantă 		assoclen -= ivsize;
1241d6bbd4eeSHoria Geantă 	}
1242d6bbd4eeSHoria Geantă 
1243d6bbd4eeSHoria Geantă 	append_math_add_imm_u32(desc, REG3, ZERO, IMM, assoclen);
1244d6bbd4eeSHoria Geantă 
1245d6bbd4eeSHoria Geantă 	/*
1246d6bbd4eeSHoria Geantă 	 * For IPsec load the IV further in the same register.
1247d6bbd4eeSHoria Geantă 	 * For RFC7539 simply load the 12 bytes nonce in a single operation
1248d6bbd4eeSHoria Geantă 	 */
1249d6bbd4eeSHoria Geantă 	append_load_as_imm(desc, req->iv, ivsize, LDST_CLASS_1_CCB |
1250d6bbd4eeSHoria Geantă 			   LDST_SRCDST_BYTE_CONTEXT |
1251d6bbd4eeSHoria Geantă 			   ctx_iv_off << LDST_OFFSET_SHIFT);
1252d6bbd4eeSHoria Geantă }
1253d6bbd4eeSHoria Geantă 
1254479bcc7cSHerbert Xu static void init_authenc_job(struct aead_request *req,
12551acebad3SYuan Kang 			     struct aead_edesc *edesc,
1256479bcc7cSHerbert Xu 			     bool all_contig, bool encrypt)
12571acebad3SYuan Kang {
12581acebad3SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1259479bcc7cSHerbert Xu 	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
1260479bcc7cSHerbert Xu 						 struct caam_aead_alg, aead);
1261479bcc7cSHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
12621acebad3SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
12637e0880b9SHoria Geantă 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctx->jrdev->parent);
1264db57656bSHoria Geantă 	const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
1265479bcc7cSHerbert Xu 			       OP_ALG_AAI_CTR_MOD128);
1266479bcc7cSHerbert Xu 	const bool is_rfc3686 = alg->caam.rfc3686;
12671acebad3SYuan Kang 	u32 *desc = edesc->hw_desc;
1268479bcc7cSHerbert Xu 	u32 ivoffset = 0;
12698e8ec596SKim Phillips 
1270479bcc7cSHerbert Xu 	/*
1271479bcc7cSHerbert Xu 	 * AES-CTR needs to load IV in CONTEXT1 reg
1272479bcc7cSHerbert Xu 	 * at an offset of 128bits (16bytes)
1273479bcc7cSHerbert Xu 	 * CONTEXT1[255:128] = IV
1274479bcc7cSHerbert Xu 	 */
1275479bcc7cSHerbert Xu 	if (ctr_mode)
1276479bcc7cSHerbert Xu 		ivoffset = 16;
12778e8ec596SKim Phillips 
1278479bcc7cSHerbert Xu 	/*
1279479bcc7cSHerbert Xu 	 * RFC3686 specific:
1280479bcc7cSHerbert Xu 	 *	CONTEXT1[255:128] = {NONCE, IV, COUNTER}
1281479bcc7cSHerbert Xu 	 */
1282479bcc7cSHerbert Xu 	if (is_rfc3686)
1283479bcc7cSHerbert Xu 		ivoffset = 16 + CTR_RFC3686_NONCE_SIZE;
1284bac68f2cSTudor Ambarus 
1285479bcc7cSHerbert Xu 	init_aead_job(req, edesc, all_contig, encrypt);
12861acebad3SYuan Kang 
12877e0880b9SHoria Geantă 	/*
12887e0880b9SHoria Geantă 	 * {REG3, DPOVRD} = assoclen, depending on whether MATH command supports
12897e0880b9SHoria Geantă 	 * having DPOVRD as destination.
12907e0880b9SHoria Geantă 	 */
12917e0880b9SHoria Geantă 	if (ctrlpriv->era < 3)
12927e0880b9SHoria Geantă 		append_math_add_imm_u32(desc, REG3, ZERO, IMM, req->assoclen);
12937e0880b9SHoria Geantă 	else
12947e0880b9SHoria Geantă 		append_math_add_imm_u32(desc, DPOVRD, ZERO, IMM, req->assoclen);
12957e0880b9SHoria Geantă 
12968b18e235SHoria Geantă 	if (ivsize && ((is_rfc3686 && encrypt) || !alg->caam.geniv))
1297479bcc7cSHerbert Xu 		append_load_as_imm(desc, req->iv, ivsize,
1298479bcc7cSHerbert Xu 				   LDST_CLASS_1_CCB |
1299479bcc7cSHerbert Xu 				   LDST_SRCDST_BYTE_CONTEXT |
1300479bcc7cSHerbert Xu 				   (ivoffset << LDST_OFFSET_SHIFT));
13018e8ec596SKim Phillips }
13028e8ec596SKim Phillips 
13038e8ec596SKim Phillips /*
13045ca7badbSHoria Geantă  * Fill in skcipher job descriptor
1305acdca31dSYuan Kang  */
13065ca7badbSHoria Geantă static void init_skcipher_job(struct skcipher_request *req,
13075ca7badbSHoria Geantă 			      struct skcipher_edesc *edesc,
13085ca7badbSHoria Geantă 			      const bool encrypt)
1309acdca31dSYuan Kang {
13105ca7badbSHoria Geantă 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
13115ca7badbSHoria Geantă 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
13126e005503SSascha Hauer 	struct device *jrdev = ctx->jrdev;
13135ca7badbSHoria Geantă 	int ivsize = crypto_skcipher_ivsize(skcipher);
1314acdca31dSYuan Kang 	u32 *desc = edesc->hw_desc;
13155ca7badbSHoria Geantă 	u32 *sh_desc;
1316eaed71a4SIuliana Prodan 	u32 in_options = 0, out_options = 0;
1317eaed71a4SIuliana Prodan 	dma_addr_t src_dma, dst_dma, ptr;
1318eaed71a4SIuliana Prodan 	int len, sec4_sg_index = 0;
1319acdca31dSYuan Kang 
13206e005503SSascha Hauer 	print_hex_dump_debug("presciv@"__stringify(__LINE__)": ",
13215ca7badbSHoria Geantă 			     DUMP_PREFIX_ADDRESS, 16, 4, req->iv, ivsize, 1);
13226e005503SSascha Hauer 	dev_dbg(jrdev, "asked=%d, cryptlen%d\n",
13235ca7badbSHoria Geantă 	       (int)edesc->src_nents > 1 ? 100 : req->cryptlen, req->cryptlen);
13246e005503SSascha Hauer 
13258a82451bSSascha Hauer 	caam_dump_sg("src    @" __stringify(__LINE__)": ",
13265ecf8ef9SCatalin Vasile 		     DUMP_PREFIX_ADDRESS, 16, 4, req->src,
13275ca7badbSHoria Geantă 		     edesc->src_nents > 1 ? 100 : req->cryptlen, 1);
13285ca7badbSHoria Geantă 
13295ca7badbSHoria Geantă 	sh_desc = encrypt ? ctx->sh_desc_enc : ctx->sh_desc_dec;
13305ca7badbSHoria Geantă 	ptr = encrypt ? ctx->sh_desc_enc_dma : ctx->sh_desc_dec_dma;
1331acdca31dSYuan Kang 
1332acdca31dSYuan Kang 	len = desc_len(sh_desc);
1333acdca31dSYuan Kang 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
1334acdca31dSYuan Kang 
1335eaed71a4SIuliana Prodan 	if (ivsize || edesc->mapped_src_nents > 1) {
1336eaed71a4SIuliana Prodan 		src_dma = edesc->sec4_sg_dma;
1337eaed71a4SIuliana Prodan 		sec4_sg_index = edesc->mapped_src_nents + !!ivsize;
1338eaed71a4SIuliana Prodan 		in_options = LDST_SGF;
1339eaed71a4SIuliana Prodan 	} else {
1340eaed71a4SIuliana Prodan 		src_dma = sg_dma_address(req->src);
1341eaed71a4SIuliana Prodan 	}
1342eaed71a4SIuliana Prodan 
1343eaed71a4SIuliana Prodan 	append_seq_in_ptr(desc, src_dma, req->cryptlen + ivsize, in_options);
1344acdca31dSYuan Kang 
1345acdca31dSYuan Kang 	if (likely(req->src == req->dst)) {
1346eaed71a4SIuliana Prodan 		dst_dma = src_dma + !!ivsize * sizeof(struct sec4_sg_entry);
1347eaed71a4SIuliana Prodan 		out_options = in_options;
1348334d37c9SHoria Geantă 	} else if (!ivsize && edesc->mapped_dst_nents == 1) {
1349acdca31dSYuan Kang 		dst_dma = sg_dma_address(req->dst);
1350acdca31dSYuan Kang 	} else {
1351eaed71a4SIuliana Prodan 		dst_dma = edesc->sec4_sg_dma + sec4_sg_index *
1352eaed71a4SIuliana Prodan 			  sizeof(struct sec4_sg_entry);
1353acdca31dSYuan Kang 		out_options = LDST_SGF;
1354acdca31dSYuan Kang 	}
1355eaed71a4SIuliana Prodan 
1356334d37c9SHoria Geantă 	append_seq_out_ptr(desc, dst_dma, req->cryptlen + ivsize, out_options);
1357acdca31dSYuan Kang }
1358acdca31dSYuan Kang 
1359acdca31dSYuan Kang /*
13601acebad3SYuan Kang  * allocate and map the aead extended descriptor
13618e8ec596SKim Phillips  */
1362f2147b88SHerbert Xu static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
1363f2147b88SHerbert Xu 					   int desc_bytes, bool *all_contig_ptr,
1364f2147b88SHerbert Xu 					   bool encrypt)
1365f2147b88SHerbert Xu {
1366f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1367f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1368f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
1369019d62dbSHoria Geantă 	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
1370019d62dbSHoria Geantă 		       GFP_KERNEL : GFP_ATOMIC;
1371838e0a89SHoria Geantă 	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
1372059d73eeSHoria Geantă 	int src_len, dst_len = 0;
1373f2147b88SHerbert Xu 	struct aead_edesc *edesc;
1374fa0c92dbSHoria Geantă 	int sec4_sg_index, sec4_sg_len, sec4_sg_bytes;
1375f2147b88SHerbert Xu 	unsigned int authsize = ctx->authsize;
1376f2147b88SHerbert Xu 
1377f2147b88SHerbert Xu 	if (unlikely(req->dst != req->src)) {
1378059d73eeSHoria Geantă 		src_len = req->assoclen + req->cryptlen;
1379059d73eeSHoria Geantă 		dst_len = src_len + (encrypt ? authsize : (-authsize));
1380059d73eeSHoria Geantă 
1381059d73eeSHoria Geantă 		src_nents = sg_nents_for_len(req->src, src_len);
1382fd144d83SHoria Geantă 		if (unlikely(src_nents < 0)) {
1383fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
1384059d73eeSHoria Geantă 				src_len);
1385fd144d83SHoria Geantă 			return ERR_PTR(src_nents);
1386fd144d83SHoria Geantă 		}
1387fd144d83SHoria Geantă 
1388059d73eeSHoria Geantă 		dst_nents = sg_nents_for_len(req->dst, dst_len);
1389fd144d83SHoria Geantă 		if (unlikely(dst_nents < 0)) {
1390fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in dst S/G\n",
1391059d73eeSHoria Geantă 				dst_len);
1392fd144d83SHoria Geantă 			return ERR_PTR(dst_nents);
1393fd144d83SHoria Geantă 		}
1394f2147b88SHerbert Xu 	} else {
1395059d73eeSHoria Geantă 		src_len = req->assoclen + req->cryptlen +
1396059d73eeSHoria Geantă 			  (encrypt ? authsize : 0);
1397059d73eeSHoria Geantă 
1398059d73eeSHoria Geantă 		src_nents = sg_nents_for_len(req->src, src_len);
1399fd144d83SHoria Geantă 		if (unlikely(src_nents < 0)) {
1400fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
1401059d73eeSHoria Geantă 				src_len);
1402fd144d83SHoria Geantă 			return ERR_PTR(src_nents);
1403fd144d83SHoria Geantă 		}
1404f2147b88SHerbert Xu 	}
1405f2147b88SHerbert Xu 
1406838e0a89SHoria Geantă 	if (likely(req->src == req->dst)) {
1407838e0a89SHoria Geantă 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1408838e0a89SHoria Geantă 					      DMA_BIDIRECTIONAL);
1409838e0a89SHoria Geantă 		if (unlikely(!mapped_src_nents)) {
1410838e0a89SHoria Geantă 			dev_err(jrdev, "unable to map source\n");
1411838e0a89SHoria Geantă 			return ERR_PTR(-ENOMEM);
1412838e0a89SHoria Geantă 		}
1413838e0a89SHoria Geantă 	} else {
1414838e0a89SHoria Geantă 		/* Cover also the case of null (zero length) input data */
1415838e0a89SHoria Geantă 		if (src_nents) {
1416838e0a89SHoria Geantă 			mapped_src_nents = dma_map_sg(jrdev, req->src,
1417838e0a89SHoria Geantă 						      src_nents, DMA_TO_DEVICE);
1418838e0a89SHoria Geantă 			if (unlikely(!mapped_src_nents)) {
1419838e0a89SHoria Geantă 				dev_err(jrdev, "unable to map source\n");
1420838e0a89SHoria Geantă 				return ERR_PTR(-ENOMEM);
1421838e0a89SHoria Geantă 			}
1422838e0a89SHoria Geantă 		} else {
1423838e0a89SHoria Geantă 			mapped_src_nents = 0;
1424838e0a89SHoria Geantă 		}
1425838e0a89SHoria Geantă 
1426763069baSHoria Geantă 		/* Cover also the case of null (zero length) output data */
1427763069baSHoria Geantă 		if (dst_nents) {
1428763069baSHoria Geantă 			mapped_dst_nents = dma_map_sg(jrdev, req->dst,
1429763069baSHoria Geantă 						      dst_nents,
1430838e0a89SHoria Geantă 						      DMA_FROM_DEVICE);
1431838e0a89SHoria Geantă 			if (unlikely(!mapped_dst_nents)) {
1432838e0a89SHoria Geantă 				dev_err(jrdev, "unable to map destination\n");
1433763069baSHoria Geantă 				dma_unmap_sg(jrdev, req->src, src_nents,
1434763069baSHoria Geantă 					     DMA_TO_DEVICE);
1435838e0a89SHoria Geantă 				return ERR_PTR(-ENOMEM);
1436838e0a89SHoria Geantă 			}
1437763069baSHoria Geantă 		} else {
1438763069baSHoria Geantă 			mapped_dst_nents = 0;
1439763069baSHoria Geantă 		}
1440838e0a89SHoria Geantă 	}
1441838e0a89SHoria Geantă 
1442a5e5c133SHoria Geantă 	/*
1443a5e5c133SHoria Geantă 	 * HW reads 4 S/G entries at a time; make sure the reads don't go beyond
1444a5e5c133SHoria Geantă 	 * the end of the table by allocating more S/G entries.
1445a5e5c133SHoria Geantă 	 */
1446838e0a89SHoria Geantă 	sec4_sg_len = mapped_src_nents > 1 ? mapped_src_nents : 0;
1447a5e5c133SHoria Geantă 	if (mapped_dst_nents > 1)
1448a5e5c133SHoria Geantă 		sec4_sg_len += pad_sg_nents(mapped_dst_nents);
1449a5e5c133SHoria Geantă 	else
1450a5e5c133SHoria Geantă 		sec4_sg_len = pad_sg_nents(sec4_sg_len);
1451a5e5c133SHoria Geantă 
1452f2147b88SHerbert Xu 	sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry);
1453f2147b88SHerbert Xu 
1454f2147b88SHerbert Xu 	/* allocate space for base edesc and hw desc commands, link tables */
1455dde20ae9SVictoria Milhoan 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes,
1456dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
1457f2147b88SHerbert Xu 	if (!edesc) {
1458838e0a89SHoria Geantă 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
1459cf5448b5SHoria Geantă 			   0, 0, 0);
1460f2147b88SHerbert Xu 		return ERR_PTR(-ENOMEM);
1461f2147b88SHerbert Xu 	}
1462f2147b88SHerbert Xu 
1463f2147b88SHerbert Xu 	edesc->src_nents = src_nents;
1464f2147b88SHerbert Xu 	edesc->dst_nents = dst_nents;
1465ba4cf71bSIuliana Prodan 	edesc->mapped_src_nents = mapped_src_nents;
1466ba4cf71bSIuliana Prodan 	edesc->mapped_dst_nents = mapped_dst_nents;
1467f2147b88SHerbert Xu 	edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) +
1468f2147b88SHerbert Xu 			 desc_bytes;
1469838e0a89SHoria Geantă 	*all_contig_ptr = !(mapped_src_nents > 1);
1470f2147b88SHerbert Xu 
1471f2147b88SHerbert Xu 	sec4_sg_index = 0;
1472838e0a89SHoria Geantă 	if (mapped_src_nents > 1) {
1473059d73eeSHoria Geantă 		sg_to_sec4_sg_last(req->src, src_len,
1474f2147b88SHerbert Xu 				   edesc->sec4_sg + sec4_sg_index, 0);
1475838e0a89SHoria Geantă 		sec4_sg_index += mapped_src_nents;
1476f2147b88SHerbert Xu 	}
1477838e0a89SHoria Geantă 	if (mapped_dst_nents > 1) {
1478059d73eeSHoria Geantă 		sg_to_sec4_sg_last(req->dst, dst_len,
1479f2147b88SHerbert Xu 				   edesc->sec4_sg + sec4_sg_index, 0);
1480f2147b88SHerbert Xu 	}
1481f2147b88SHerbert Xu 
1482f2147b88SHerbert Xu 	if (!sec4_sg_bytes)
1483f2147b88SHerbert Xu 		return edesc;
1484f2147b88SHerbert Xu 
1485f2147b88SHerbert Xu 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
1486f2147b88SHerbert Xu 					    sec4_sg_bytes, DMA_TO_DEVICE);
1487f2147b88SHerbert Xu 	if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
1488f2147b88SHerbert Xu 		dev_err(jrdev, "unable to map S/G table\n");
1489f2147b88SHerbert Xu 		aead_unmap(jrdev, edesc, req);
1490f2147b88SHerbert Xu 		kfree(edesc);
1491f2147b88SHerbert Xu 		return ERR_PTR(-ENOMEM);
1492f2147b88SHerbert Xu 	}
1493f2147b88SHerbert Xu 
1494f2147b88SHerbert Xu 	edesc->sec4_sg_bytes = sec4_sg_bytes;
1495f2147b88SHerbert Xu 
1496f2147b88SHerbert Xu 	return edesc;
1497f2147b88SHerbert Xu }
1498f2147b88SHerbert Xu 
1499f2147b88SHerbert Xu static int gcm_encrypt(struct aead_request *req)
15008e8ec596SKim Phillips {
15010e479300SYuan Kang 	struct aead_edesc *edesc;
15028e8ec596SKim Phillips 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
15038e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
15048e8ec596SKim Phillips 	struct device *jrdev = ctx->jrdev;
15051acebad3SYuan Kang 	bool all_contig;
15068e8ec596SKim Phillips 	u32 *desc;
15071acebad3SYuan Kang 	int ret = 0;
15081acebad3SYuan Kang 
15098e8ec596SKim Phillips 	/* allocate extended descriptor */
1510f2147b88SHerbert Xu 	edesc = aead_edesc_alloc(req, GCM_DESC_JOB_IO_LEN, &all_contig, true);
15118e8ec596SKim Phillips 	if (IS_ERR(edesc))
15128e8ec596SKim Phillips 		return PTR_ERR(edesc);
15138e8ec596SKim Phillips 
15141acebad3SYuan Kang 	/* Create and submit job descriptor */
1515f2147b88SHerbert Xu 	init_gcm_job(req, edesc, all_contig, true);
15166e005503SSascha Hauer 
15176e005503SSascha Hauer 	print_hex_dump_debug("aead jobdesc@"__stringify(__LINE__)": ",
15181acebad3SYuan Kang 			     DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
15191acebad3SYuan Kang 			     desc_bytes(edesc->hw_desc), 1);
15201acebad3SYuan Kang 
15218e8ec596SKim Phillips 	desc = edesc->hw_desc;
15221acebad3SYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
15231acebad3SYuan Kang 	if (!ret) {
15241acebad3SYuan Kang 		ret = -EINPROGRESS;
15251acebad3SYuan Kang 	} else {
15261acebad3SYuan Kang 		aead_unmap(jrdev, edesc, req);
15271acebad3SYuan Kang 		kfree(edesc);
15281acebad3SYuan Kang 	}
15298e8ec596SKim Phillips 
15301acebad3SYuan Kang 	return ret;
15318e8ec596SKim Phillips }
15328e8ec596SKim Phillips 
1533d6bbd4eeSHoria Geantă static int chachapoly_encrypt(struct aead_request *req)
1534d6bbd4eeSHoria Geantă {
1535d6bbd4eeSHoria Geantă 	struct aead_edesc *edesc;
1536d6bbd4eeSHoria Geantă 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1537d6bbd4eeSHoria Geantă 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1538d6bbd4eeSHoria Geantă 	struct device *jrdev = ctx->jrdev;
1539d6bbd4eeSHoria Geantă 	bool all_contig;
1540d6bbd4eeSHoria Geantă 	u32 *desc;
1541d6bbd4eeSHoria Geantă 	int ret;
1542d6bbd4eeSHoria Geantă 
1543d6bbd4eeSHoria Geantă 	edesc = aead_edesc_alloc(req, CHACHAPOLY_DESC_JOB_IO_LEN, &all_contig,
1544d6bbd4eeSHoria Geantă 				 true);
1545d6bbd4eeSHoria Geantă 	if (IS_ERR(edesc))
1546d6bbd4eeSHoria Geantă 		return PTR_ERR(edesc);
1547d6bbd4eeSHoria Geantă 
1548d6bbd4eeSHoria Geantă 	desc = edesc->hw_desc;
1549d6bbd4eeSHoria Geantă 
1550d6bbd4eeSHoria Geantă 	init_chachapoly_job(req, edesc, all_contig, true);
1551d6bbd4eeSHoria Geantă 	print_hex_dump_debug("chachapoly jobdesc@" __stringify(__LINE__)": ",
1552d6bbd4eeSHoria Geantă 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1553d6bbd4eeSHoria Geantă 			     1);
1554d6bbd4eeSHoria Geantă 
1555d6bbd4eeSHoria Geantă 	ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
1556d6bbd4eeSHoria Geantă 	if (!ret) {
1557d6bbd4eeSHoria Geantă 		ret = -EINPROGRESS;
1558d6bbd4eeSHoria Geantă 	} else {
1559d6bbd4eeSHoria Geantă 		aead_unmap(jrdev, edesc, req);
1560d6bbd4eeSHoria Geantă 		kfree(edesc);
1561d6bbd4eeSHoria Geantă 	}
1562d6bbd4eeSHoria Geantă 
1563d6bbd4eeSHoria Geantă 	return ret;
1564d6bbd4eeSHoria Geantă }
1565d6bbd4eeSHoria Geantă 
1566d6bbd4eeSHoria Geantă static int chachapoly_decrypt(struct aead_request *req)
1567d6bbd4eeSHoria Geantă {
1568d6bbd4eeSHoria Geantă 	struct aead_edesc *edesc;
1569d6bbd4eeSHoria Geantă 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1570d6bbd4eeSHoria Geantă 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1571d6bbd4eeSHoria Geantă 	struct device *jrdev = ctx->jrdev;
1572d6bbd4eeSHoria Geantă 	bool all_contig;
1573d6bbd4eeSHoria Geantă 	u32 *desc;
1574d6bbd4eeSHoria Geantă 	int ret;
1575d6bbd4eeSHoria Geantă 
1576d6bbd4eeSHoria Geantă 	edesc = aead_edesc_alloc(req, CHACHAPOLY_DESC_JOB_IO_LEN, &all_contig,
1577d6bbd4eeSHoria Geantă 				 false);
1578d6bbd4eeSHoria Geantă 	if (IS_ERR(edesc))
1579d6bbd4eeSHoria Geantă 		return PTR_ERR(edesc);
1580d6bbd4eeSHoria Geantă 
1581d6bbd4eeSHoria Geantă 	desc = edesc->hw_desc;
1582d6bbd4eeSHoria Geantă 
1583d6bbd4eeSHoria Geantă 	init_chachapoly_job(req, edesc, all_contig, false);
1584d6bbd4eeSHoria Geantă 	print_hex_dump_debug("chachapoly jobdesc@" __stringify(__LINE__)": ",
1585d6bbd4eeSHoria Geantă 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1586d6bbd4eeSHoria Geantă 			     1);
1587d6bbd4eeSHoria Geantă 
1588d6bbd4eeSHoria Geantă 	ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
1589d6bbd4eeSHoria Geantă 	if (!ret) {
1590d6bbd4eeSHoria Geantă 		ret = -EINPROGRESS;
1591d6bbd4eeSHoria Geantă 	} else {
1592d6bbd4eeSHoria Geantă 		aead_unmap(jrdev, edesc, req);
1593d6bbd4eeSHoria Geantă 		kfree(edesc);
1594d6bbd4eeSHoria Geantă 	}
1595d6bbd4eeSHoria Geantă 
1596d6bbd4eeSHoria Geantă 	return ret;
1597d6bbd4eeSHoria Geantă }
1598d6bbd4eeSHoria Geantă 
159946218750SHerbert Xu static int ipsec_gcm_encrypt(struct aead_request *req)
160046218750SHerbert Xu {
160146218750SHerbert Xu 	if (req->assoclen < 8)
160246218750SHerbert Xu 		return -EINVAL;
160346218750SHerbert Xu 
160446218750SHerbert Xu 	return gcm_encrypt(req);
160546218750SHerbert Xu }
160646218750SHerbert Xu 
1607479bcc7cSHerbert Xu static int aead_encrypt(struct aead_request *req)
16088e8ec596SKim Phillips {
16091acebad3SYuan Kang 	struct aead_edesc *edesc;
16100e479300SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
16110e479300SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
16120e479300SYuan Kang 	struct device *jrdev = ctx->jrdev;
16131acebad3SYuan Kang 	bool all_contig;
16140e479300SYuan Kang 	u32 *desc;
16151acebad3SYuan Kang 	int ret = 0;
16160e479300SYuan Kang 
16170e479300SYuan Kang 	/* allocate extended descriptor */
1618479bcc7cSHerbert Xu 	edesc = aead_edesc_alloc(req, AUTHENC_DESC_JOB_IO_LEN,
1619479bcc7cSHerbert Xu 				 &all_contig, true);
16200e479300SYuan Kang 	if (IS_ERR(edesc))
16210e479300SYuan Kang 		return PTR_ERR(edesc);
16220e479300SYuan Kang 
1623f2147b88SHerbert Xu 	/* Create and submit job descriptor */
1624479bcc7cSHerbert Xu 	init_authenc_job(req, edesc, all_contig, true);
16256e005503SSascha Hauer 
16266e005503SSascha Hauer 	print_hex_dump_debug("aead jobdesc@"__stringify(__LINE__)": ",
1627f2147b88SHerbert Xu 			     DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1628f2147b88SHerbert Xu 			     desc_bytes(edesc->hw_desc), 1);
16291acebad3SYuan Kang 
1630f2147b88SHerbert Xu 	desc = edesc->hw_desc;
1631479bcc7cSHerbert Xu 	ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
1632f2147b88SHerbert Xu 	if (!ret) {
1633f2147b88SHerbert Xu 		ret = -EINPROGRESS;
1634f2147b88SHerbert Xu 	} else {
1635479bcc7cSHerbert Xu 		aead_unmap(jrdev, edesc, req);
1636f2147b88SHerbert Xu 		kfree(edesc);
1637f2147b88SHerbert Xu 	}
1638f2147b88SHerbert Xu 
1639f2147b88SHerbert Xu 	return ret;
1640f2147b88SHerbert Xu }
1641f2147b88SHerbert Xu 
1642f2147b88SHerbert Xu static int gcm_decrypt(struct aead_request *req)
1643f2147b88SHerbert Xu {
1644f2147b88SHerbert Xu 	struct aead_edesc *edesc;
1645f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1646f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1647f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
1648f2147b88SHerbert Xu 	bool all_contig;
1649f2147b88SHerbert Xu 	u32 *desc;
1650f2147b88SHerbert Xu 	int ret = 0;
1651f2147b88SHerbert Xu 
1652f2147b88SHerbert Xu 	/* allocate extended descriptor */
1653f2147b88SHerbert Xu 	edesc = aead_edesc_alloc(req, GCM_DESC_JOB_IO_LEN, &all_contig, false);
1654f2147b88SHerbert Xu 	if (IS_ERR(edesc))
1655f2147b88SHerbert Xu 		return PTR_ERR(edesc);
1656f2147b88SHerbert Xu 
16571acebad3SYuan Kang 	/* Create and submit job descriptor*/
1658f2147b88SHerbert Xu 	init_gcm_job(req, edesc, all_contig, false);
16596e005503SSascha Hauer 
16606e005503SSascha Hauer 	print_hex_dump_debug("aead jobdesc@"__stringify(__LINE__)": ",
16611acebad3SYuan Kang 			     DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
16621acebad3SYuan Kang 			     desc_bytes(edesc->hw_desc), 1);
16631acebad3SYuan Kang 
16640e479300SYuan Kang 	desc = edesc->hw_desc;
16651acebad3SYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
16661acebad3SYuan Kang 	if (!ret) {
16671acebad3SYuan Kang 		ret = -EINPROGRESS;
16681acebad3SYuan Kang 	} else {
16691acebad3SYuan Kang 		aead_unmap(jrdev, edesc, req);
16701acebad3SYuan Kang 		kfree(edesc);
16711acebad3SYuan Kang 	}
16720e479300SYuan Kang 
16731acebad3SYuan Kang 	return ret;
16741acebad3SYuan Kang }
16750e479300SYuan Kang 
167646218750SHerbert Xu static int ipsec_gcm_decrypt(struct aead_request *req)
167746218750SHerbert Xu {
167846218750SHerbert Xu 	if (req->assoclen < 8)
167946218750SHerbert Xu 		return -EINVAL;
168046218750SHerbert Xu 
168146218750SHerbert Xu 	return gcm_decrypt(req);
168246218750SHerbert Xu }
168346218750SHerbert Xu 
1684479bcc7cSHerbert Xu static int aead_decrypt(struct aead_request *req)
1685f2147b88SHerbert Xu {
1686f2147b88SHerbert Xu 	struct aead_edesc *edesc;
1687f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1688f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1689f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
1690f2147b88SHerbert Xu 	bool all_contig;
1691f2147b88SHerbert Xu 	u32 *desc;
1692f2147b88SHerbert Xu 	int ret = 0;
1693f2147b88SHerbert Xu 
16948a82451bSSascha Hauer 	caam_dump_sg("dec src@" __stringify(__LINE__)": ",
16955ecf8ef9SCatalin Vasile 		     DUMP_PREFIX_ADDRESS, 16, 4, req->src,
169600fef2b2SHoria Geantă 		     req->assoclen + req->cryptlen, 1);
16975ecf8ef9SCatalin Vasile 
1698f2147b88SHerbert Xu 	/* allocate extended descriptor */
1699479bcc7cSHerbert Xu 	edesc = aead_edesc_alloc(req, AUTHENC_DESC_JOB_IO_LEN,
1700479bcc7cSHerbert Xu 				 &all_contig, false);
1701f2147b88SHerbert Xu 	if (IS_ERR(edesc))
1702f2147b88SHerbert Xu 		return PTR_ERR(edesc);
1703f2147b88SHerbert Xu 
1704f2147b88SHerbert Xu 	/* Create and submit job descriptor*/
1705479bcc7cSHerbert Xu 	init_authenc_job(req, edesc, all_contig, false);
17066e005503SSascha Hauer 
17076e005503SSascha Hauer 	print_hex_dump_debug("aead jobdesc@"__stringify(__LINE__)": ",
1708f2147b88SHerbert Xu 			     DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1709f2147b88SHerbert Xu 			     desc_bytes(edesc->hw_desc), 1);
1710f2147b88SHerbert Xu 
1711f2147b88SHerbert Xu 	desc = edesc->hw_desc;
1712479bcc7cSHerbert Xu 	ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
1713f2147b88SHerbert Xu 	if (!ret) {
1714f2147b88SHerbert Xu 		ret = -EINPROGRESS;
1715f2147b88SHerbert Xu 	} else {
1716479bcc7cSHerbert Xu 		aead_unmap(jrdev, edesc, req);
1717f2147b88SHerbert Xu 		kfree(edesc);
1718f2147b88SHerbert Xu 	}
1719f2147b88SHerbert Xu 
1720f2147b88SHerbert Xu 	return ret;
1721f2147b88SHerbert Xu }
1722f2147b88SHerbert Xu 
1723acdca31dSYuan Kang /*
17245ca7badbSHoria Geantă  * allocate and map the skcipher extended descriptor for skcipher
1725acdca31dSYuan Kang  */
17265ca7badbSHoria Geantă static struct skcipher_edesc *skcipher_edesc_alloc(struct skcipher_request *req,
17275ca7badbSHoria Geantă 						   int desc_bytes)
1728acdca31dSYuan Kang {
17295ca7badbSHoria Geantă 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
17305ca7badbSHoria Geantă 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
1731acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
173242cfcafbSHoria Geantă 	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
1733acdca31dSYuan Kang 		       GFP_KERNEL : GFP_ATOMIC;
1734838e0a89SHoria Geantă 	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
17355ca7badbSHoria Geantă 	struct skcipher_edesc *edesc;
1736eaed71a4SIuliana Prodan 	dma_addr_t iv_dma = 0;
1737115957bbSHoria Geantă 	u8 *iv;
17385ca7badbSHoria Geantă 	int ivsize = crypto_skcipher_ivsize(skcipher);
1739838e0a89SHoria Geantă 	int dst_sg_idx, sec4_sg_ents, sec4_sg_bytes;
1740acdca31dSYuan Kang 
17415ca7badbSHoria Geantă 	src_nents = sg_nents_for_len(req->src, req->cryptlen);
1742fd144d83SHoria Geantă 	if (unlikely(src_nents < 0)) {
1743fd144d83SHoria Geantă 		dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
17445ca7badbSHoria Geantă 			req->cryptlen);
1745fd144d83SHoria Geantă 		return ERR_PTR(src_nents);
1746fd144d83SHoria Geantă 	}
1747acdca31dSYuan Kang 
1748fd144d83SHoria Geantă 	if (req->dst != req->src) {
17495ca7badbSHoria Geantă 		dst_nents = sg_nents_for_len(req->dst, req->cryptlen);
1750fd144d83SHoria Geantă 		if (unlikely(dst_nents < 0)) {
1751fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in dst S/G\n",
17525ca7badbSHoria Geantă 				req->cryptlen);
1753fd144d83SHoria Geantă 			return ERR_PTR(dst_nents);
1754fd144d83SHoria Geantă 		}
1755fd144d83SHoria Geantă 	}
1756acdca31dSYuan Kang 
1757acdca31dSYuan Kang 	if (likely(req->src == req->dst)) {
1758838e0a89SHoria Geantă 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1759838e0a89SHoria Geantă 					      DMA_BIDIRECTIONAL);
1760838e0a89SHoria Geantă 		if (unlikely(!mapped_src_nents)) {
1761c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map source\n");
1762c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1763c73e36e8SHoria Geantă 		}
1764acdca31dSYuan Kang 	} else {
1765838e0a89SHoria Geantă 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1766838e0a89SHoria Geantă 					      DMA_TO_DEVICE);
1767838e0a89SHoria Geantă 		if (unlikely(!mapped_src_nents)) {
1768c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map source\n");
1769c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1770c73e36e8SHoria Geantă 		}
1771838e0a89SHoria Geantă 		mapped_dst_nents = dma_map_sg(jrdev, req->dst, dst_nents,
1772838e0a89SHoria Geantă 					      DMA_FROM_DEVICE);
1773838e0a89SHoria Geantă 		if (unlikely(!mapped_dst_nents)) {
1774c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map destination\n");
1775fa0c92dbSHoria Geantă 			dma_unmap_sg(jrdev, req->src, src_nents, DMA_TO_DEVICE);
1776c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1777c73e36e8SHoria Geantă 		}
1778acdca31dSYuan Kang 	}
1779acdca31dSYuan Kang 
1780eaed71a4SIuliana Prodan 	if (!ivsize && mapped_src_nents == 1)
1781eaed71a4SIuliana Prodan 		sec4_sg_ents = 0; // no need for an input hw s/g table
1782eaed71a4SIuliana Prodan 	else
1783eaed71a4SIuliana Prodan 		sec4_sg_ents = mapped_src_nents + !!ivsize;
1784fa0c92dbSHoria Geantă 	dst_sg_idx = sec4_sg_ents;
1785a5e5c133SHoria Geantă 
1786a5e5c133SHoria Geantă 	/*
1787334d37c9SHoria Geantă 	 * Input, output HW S/G tables: [IV, src][dst, IV]
1788334d37c9SHoria Geantă 	 * IV entries point to the same buffer
1789334d37c9SHoria Geantă 	 * If src == dst, S/G entries are reused (S/G tables overlap)
1790334d37c9SHoria Geantă 	 *
1791a5e5c133SHoria Geantă 	 * HW reads 4 S/G entries at a time; make sure the reads don't go beyond
1792a5e5c133SHoria Geantă 	 * the end of the table by allocating more S/G entries. Logic:
1793334d37c9SHoria Geantă 	 * if (output S/G)
1794a5e5c133SHoria Geantă 	 *      pad output S/G, if needed
1795a5e5c133SHoria Geantă 	 * else if (input S/G) ...
1796a5e5c133SHoria Geantă 	 *      pad input S/G, if needed
1797a5e5c133SHoria Geantă 	 */
1798334d37c9SHoria Geantă 	if (ivsize || mapped_dst_nents > 1) {
1799334d37c9SHoria Geantă 		if (req->src == req->dst)
1800334d37c9SHoria Geantă 			sec4_sg_ents = !!ivsize + pad_sg_nents(sec4_sg_ents);
1801a5e5c133SHoria Geantă 		else
1802334d37c9SHoria Geantă 			sec4_sg_ents += pad_sg_nents(mapped_dst_nents +
1803334d37c9SHoria Geantă 						     !!ivsize);
1804334d37c9SHoria Geantă 	} else {
1805a5e5c133SHoria Geantă 		sec4_sg_ents = pad_sg_nents(sec4_sg_ents);
1806334d37c9SHoria Geantă 	}
1807a5e5c133SHoria Geantă 
1808fa0c92dbSHoria Geantă 	sec4_sg_bytes = sec4_sg_ents * sizeof(struct sec4_sg_entry);
1809acdca31dSYuan Kang 
1810115957bbSHoria Geantă 	/*
1811115957bbSHoria Geantă 	 * allocate space for base edesc and hw desc commands, link tables, IV
1812115957bbSHoria Geantă 	 */
1813115957bbSHoria Geantă 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes + ivsize,
1814dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
1815acdca31dSYuan Kang 	if (!edesc) {
1816acdca31dSYuan Kang 		dev_err(jrdev, "could not allocate extended descriptor\n");
1817115957bbSHoria Geantă 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
1818cf5448b5SHoria Geantă 			   0, 0, 0);
1819acdca31dSYuan Kang 		return ERR_PTR(-ENOMEM);
1820acdca31dSYuan Kang 	}
1821acdca31dSYuan Kang 
1822acdca31dSYuan Kang 	edesc->src_nents = src_nents;
1823acdca31dSYuan Kang 	edesc->dst_nents = dst_nents;
1824ba4cf71bSIuliana Prodan 	edesc->mapped_src_nents = mapped_src_nents;
1825ba4cf71bSIuliana Prodan 	edesc->mapped_dst_nents = mapped_dst_nents;
1826a299c837SYuan Kang 	edesc->sec4_sg_bytes = sec4_sg_bytes;
182713cc6f48SHoria Geantă 	edesc->sec4_sg = (struct sec4_sg_entry *)((u8 *)edesc->hw_desc +
182813cc6f48SHoria Geantă 						  desc_bytes);
1829acdca31dSYuan Kang 
1830115957bbSHoria Geantă 	/* Make sure IV is located in a DMAable area */
1831eaed71a4SIuliana Prodan 	if (ivsize) {
1832334d37c9SHoria Geantă 		iv = (u8 *)edesc->sec4_sg + sec4_sg_bytes;
18335ca7badbSHoria Geantă 		memcpy(iv, req->iv, ivsize);
1834115957bbSHoria Geantă 
1835334d37c9SHoria Geantă 		iv_dma = dma_map_single(jrdev, iv, ivsize, DMA_BIDIRECTIONAL);
1836115957bbSHoria Geantă 		if (dma_mapping_error(jrdev, iv_dma)) {
1837115957bbSHoria Geantă 			dev_err(jrdev, "unable to map IV\n");
1838eaed71a4SIuliana Prodan 			caam_unmap(jrdev, req->src, req->dst, src_nents,
1839eaed71a4SIuliana Prodan 				   dst_nents, 0, 0, 0, 0);
1840115957bbSHoria Geantă 			kfree(edesc);
1841115957bbSHoria Geantă 			return ERR_PTR(-ENOMEM);
1842acdca31dSYuan Kang 		}
1843acdca31dSYuan Kang 
1844115957bbSHoria Geantă 		dma_to_sec4_sg_one(edesc->sec4_sg, iv_dma, ivsize, 0);
1845eaed71a4SIuliana Prodan 	}
1846eaed71a4SIuliana Prodan 	if (dst_sg_idx)
1847334d37c9SHoria Geantă 		sg_to_sec4_sg(req->src, req->cryptlen, edesc->sec4_sg +
1848eaed71a4SIuliana Prodan 			      !!ivsize, 0);
1849115957bbSHoria Geantă 
1850334d37c9SHoria Geantă 	if (req->src != req->dst && (ivsize || mapped_dst_nents > 1))
1851334d37c9SHoria Geantă 		sg_to_sec4_sg(req->dst, req->cryptlen, edesc->sec4_sg +
1852334d37c9SHoria Geantă 			      dst_sg_idx, 0);
1853334d37c9SHoria Geantă 
1854334d37c9SHoria Geantă 	if (ivsize)
1855334d37c9SHoria Geantă 		dma_to_sec4_sg_one(edesc->sec4_sg + dst_sg_idx +
1856334d37c9SHoria Geantă 				   mapped_dst_nents, iv_dma, ivsize, 0);
1857334d37c9SHoria Geantă 
1858334d37c9SHoria Geantă 	if (ivsize || mapped_dst_nents > 1)
1859334d37c9SHoria Geantă 		sg_to_sec4_set_last(edesc->sec4_sg + dst_sg_idx +
1860334d37c9SHoria Geantă 				    mapped_dst_nents);
1861acdca31dSYuan Kang 
1862eaed71a4SIuliana Prodan 	if (sec4_sg_bytes) {
1863a299c837SYuan Kang 		edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
1864eaed71a4SIuliana Prodan 						    sec4_sg_bytes,
1865eaed71a4SIuliana Prodan 						    DMA_TO_DEVICE);
1866ce572085SHoria Geanta 		if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
1867ce572085SHoria Geanta 			dev_err(jrdev, "unable to map S/G table\n");
1868eaed71a4SIuliana Prodan 			caam_unmap(jrdev, req->src, req->dst, src_nents,
1869eaed71a4SIuliana Prodan 				   dst_nents, iv_dma, ivsize, 0, 0);
1870c73e36e8SHoria Geantă 			kfree(edesc);
1871ce572085SHoria Geanta 			return ERR_PTR(-ENOMEM);
1872ce572085SHoria Geanta 		}
1873eaed71a4SIuliana Prodan 	}
1874ce572085SHoria Geanta 
1875acdca31dSYuan Kang 	edesc->iv_dma = iv_dma;
1876acdca31dSYuan Kang 
18776e005503SSascha Hauer 	print_hex_dump_debug("skcipher sec4_sg@" __stringify(__LINE__)": ",
1878a299c837SYuan Kang 			     DUMP_PREFIX_ADDRESS, 16, 4, edesc->sec4_sg,
1879a299c837SYuan Kang 			     sec4_sg_bytes, 1);
1880acdca31dSYuan Kang 
1881acdca31dSYuan Kang 	return edesc;
1882acdca31dSYuan Kang }
1883acdca31dSYuan Kang 
18845ca7badbSHoria Geantă static int skcipher_encrypt(struct skcipher_request *req)
1885acdca31dSYuan Kang {
18865ca7badbSHoria Geantă 	struct skcipher_edesc *edesc;
18875ca7badbSHoria Geantă 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
18885ca7badbSHoria Geantă 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
1889acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
1890acdca31dSYuan Kang 	u32 *desc;
1891acdca31dSYuan Kang 	int ret = 0;
1892acdca31dSYuan Kang 
1893acdca31dSYuan Kang 	/* allocate extended descriptor */
18945ca7badbSHoria Geantă 	edesc = skcipher_edesc_alloc(req, DESC_JOB_IO_LEN * CAAM_CMD_SZ);
1895acdca31dSYuan Kang 	if (IS_ERR(edesc))
1896acdca31dSYuan Kang 		return PTR_ERR(edesc);
1897acdca31dSYuan Kang 
1898acdca31dSYuan Kang 	/* Create and submit job descriptor*/
18995ca7badbSHoria Geantă 	init_skcipher_job(req, edesc, true);
19006e005503SSascha Hauer 
19016e005503SSascha Hauer 	print_hex_dump_debug("skcipher jobdesc@" __stringify(__LINE__)": ",
1902acdca31dSYuan Kang 			     DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1903acdca31dSYuan Kang 			     desc_bytes(edesc->hw_desc), 1);
19046e005503SSascha Hauer 
1905acdca31dSYuan Kang 	desc = edesc->hw_desc;
19065ca7badbSHoria Geantă 	ret = caam_jr_enqueue(jrdev, desc, skcipher_encrypt_done, req);
1907acdca31dSYuan Kang 
1908acdca31dSYuan Kang 	if (!ret) {
1909acdca31dSYuan Kang 		ret = -EINPROGRESS;
1910acdca31dSYuan Kang 	} else {
19115ca7badbSHoria Geantă 		skcipher_unmap(jrdev, edesc, req);
1912acdca31dSYuan Kang 		kfree(edesc);
1913acdca31dSYuan Kang 	}
1914acdca31dSYuan Kang 
1915acdca31dSYuan Kang 	return ret;
1916acdca31dSYuan Kang }
1917acdca31dSYuan Kang 
19185ca7badbSHoria Geantă static int skcipher_decrypt(struct skcipher_request *req)
1919acdca31dSYuan Kang {
19205ca7badbSHoria Geantă 	struct skcipher_edesc *edesc;
19215ca7badbSHoria Geantă 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
19225ca7badbSHoria Geantă 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
1923acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
1924acdca31dSYuan Kang 	u32 *desc;
1925acdca31dSYuan Kang 	int ret = 0;
1926acdca31dSYuan Kang 
1927acdca31dSYuan Kang 	/* allocate extended descriptor */
19285ca7badbSHoria Geantă 	edesc = skcipher_edesc_alloc(req, DESC_JOB_IO_LEN * CAAM_CMD_SZ);
1929acdca31dSYuan Kang 	if (IS_ERR(edesc))
1930acdca31dSYuan Kang 		return PTR_ERR(edesc);
1931acdca31dSYuan Kang 
1932acdca31dSYuan Kang 	/* Create and submit job descriptor*/
19335ca7badbSHoria Geantă 	init_skcipher_job(req, edesc, false);
1934acdca31dSYuan Kang 	desc = edesc->hw_desc;
19356e005503SSascha Hauer 
19366e005503SSascha Hauer 	print_hex_dump_debug("skcipher jobdesc@" __stringify(__LINE__)": ",
1937acdca31dSYuan Kang 			     DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1938acdca31dSYuan Kang 			     desc_bytes(edesc->hw_desc), 1);
1939acdca31dSYuan Kang 
19405ca7badbSHoria Geantă 	ret = caam_jr_enqueue(jrdev, desc, skcipher_decrypt_done, req);
1941acdca31dSYuan Kang 	if (!ret) {
1942acdca31dSYuan Kang 		ret = -EINPROGRESS;
1943acdca31dSYuan Kang 	} else {
19445ca7badbSHoria Geantă 		skcipher_unmap(jrdev, edesc, req);
1945acdca31dSYuan Kang 		kfree(edesc);
1946acdca31dSYuan Kang 	}
1947acdca31dSYuan Kang 
1948acdca31dSYuan Kang 	return ret;
1949acdca31dSYuan Kang }
1950acdca31dSYuan Kang 
19515ca7badbSHoria Geantă static struct caam_skcipher_alg driver_algs[] = {
1952acdca31dSYuan Kang 	{
19535ca7badbSHoria Geantă 		.skcipher = {
19545ca7badbSHoria Geantă 			.base = {
19555ca7badbSHoria Geantă 				.cra_name = "cbc(aes)",
19565ca7badbSHoria Geantă 				.cra_driver_name = "cbc-aes-caam",
19575ca7badbSHoria Geantă 				.cra_blocksize = AES_BLOCK_SIZE,
19585ca7badbSHoria Geantă 			},
1959836d8f43SIuliana Prodan 			.setkey = aes_skcipher_setkey,
19605ca7badbSHoria Geantă 			.encrypt = skcipher_encrypt,
19615ca7badbSHoria Geantă 			.decrypt = skcipher_decrypt,
1962acdca31dSYuan Kang 			.min_keysize = AES_MIN_KEY_SIZE,
1963acdca31dSYuan Kang 			.max_keysize = AES_MAX_KEY_SIZE,
1964acdca31dSYuan Kang 			.ivsize = AES_BLOCK_SIZE,
1965acdca31dSYuan Kang 		},
19665ca7badbSHoria Geantă 		.caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
1967acdca31dSYuan Kang 	},
1968acdca31dSYuan Kang 	{
19695ca7badbSHoria Geantă 		.skcipher = {
19705ca7badbSHoria Geantă 			.base = {
19715ca7badbSHoria Geantă 				.cra_name = "cbc(des3_ede)",
19725ca7badbSHoria Geantă 				.cra_driver_name = "cbc-3des-caam",
19735ca7badbSHoria Geantă 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
19745ca7badbSHoria Geantă 			},
1975cf64e495SIuliana Prodan 			.setkey = des_skcipher_setkey,
19765ca7badbSHoria Geantă 			.encrypt = skcipher_encrypt,
19775ca7badbSHoria Geantă 			.decrypt = skcipher_decrypt,
1978acdca31dSYuan Kang 			.min_keysize = DES3_EDE_KEY_SIZE,
1979acdca31dSYuan Kang 			.max_keysize = DES3_EDE_KEY_SIZE,
1980acdca31dSYuan Kang 			.ivsize = DES3_EDE_BLOCK_SIZE,
1981acdca31dSYuan Kang 		},
19825ca7badbSHoria Geantă 		.caam.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
1983acdca31dSYuan Kang 	},
1984acdca31dSYuan Kang 	{
19855ca7badbSHoria Geantă 		.skcipher = {
19865ca7badbSHoria Geantă 			.base = {
19875ca7badbSHoria Geantă 				.cra_name = "cbc(des)",
19885ca7badbSHoria Geantă 				.cra_driver_name = "cbc-des-caam",
19895ca7badbSHoria Geantă 				.cra_blocksize = DES_BLOCK_SIZE,
19905ca7badbSHoria Geantă 			},
1991cf64e495SIuliana Prodan 			.setkey = des_skcipher_setkey,
19925ca7badbSHoria Geantă 			.encrypt = skcipher_encrypt,
19935ca7badbSHoria Geantă 			.decrypt = skcipher_decrypt,
1994acdca31dSYuan Kang 			.min_keysize = DES_KEY_SIZE,
1995acdca31dSYuan Kang 			.max_keysize = DES_KEY_SIZE,
1996acdca31dSYuan Kang 			.ivsize = DES_BLOCK_SIZE,
1997acdca31dSYuan Kang 		},
19985ca7badbSHoria Geantă 		.caam.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
19992b22f6c5SCatalin Vasile 	},
20002b22f6c5SCatalin Vasile 	{
20015ca7badbSHoria Geantă 		.skcipher = {
20025ca7badbSHoria Geantă 			.base = {
20035ca7badbSHoria Geantă 				.cra_name = "ctr(aes)",
20045ca7badbSHoria Geantă 				.cra_driver_name = "ctr-aes-caam",
20055ca7badbSHoria Geantă 				.cra_blocksize = 1,
20065ca7badbSHoria Geantă 			},
2007836d8f43SIuliana Prodan 			.setkey = ctr_skcipher_setkey,
20085ca7badbSHoria Geantă 			.encrypt = skcipher_encrypt,
20095ca7badbSHoria Geantă 			.decrypt = skcipher_decrypt,
20102b22f6c5SCatalin Vasile 			.min_keysize = AES_MIN_KEY_SIZE,
20112b22f6c5SCatalin Vasile 			.max_keysize = AES_MAX_KEY_SIZE,
20122b22f6c5SCatalin Vasile 			.ivsize = AES_BLOCK_SIZE,
20135ca7badbSHoria Geantă 			.chunksize = AES_BLOCK_SIZE,
20142b22f6c5SCatalin Vasile 		},
20155ca7badbSHoria Geantă 		.caam.class1_alg_type = OP_ALG_ALGSEL_AES |
20165ca7badbSHoria Geantă 					OP_ALG_AAI_CTR_MOD128,
2017a5f57cffSCatalin Vasile 	},
2018a5f57cffSCatalin Vasile 	{
20195ca7badbSHoria Geantă 		.skcipher = {
20205ca7badbSHoria Geantă 			.base = {
20215ca7badbSHoria Geantă 				.cra_name = "rfc3686(ctr(aes))",
20225ca7badbSHoria Geantă 				.cra_driver_name = "rfc3686-ctr-aes-caam",
20235ca7badbSHoria Geantă 				.cra_blocksize = 1,
20245ca7badbSHoria Geantă 			},
2025836d8f43SIuliana Prodan 			.setkey = rfc3686_skcipher_setkey,
20265ca7badbSHoria Geantă 			.encrypt = skcipher_encrypt,
20275ca7badbSHoria Geantă 			.decrypt = skcipher_decrypt,
2028a5f57cffSCatalin Vasile 			.min_keysize = AES_MIN_KEY_SIZE +
2029a5f57cffSCatalin Vasile 				       CTR_RFC3686_NONCE_SIZE,
2030a5f57cffSCatalin Vasile 			.max_keysize = AES_MAX_KEY_SIZE +
2031a5f57cffSCatalin Vasile 				       CTR_RFC3686_NONCE_SIZE,
2032a5f57cffSCatalin Vasile 			.ivsize = CTR_RFC3686_IV_SIZE,
20335ca7badbSHoria Geantă 			.chunksize = AES_BLOCK_SIZE,
2034a5f57cffSCatalin Vasile 		},
20355ca7badbSHoria Geantă 		.caam = {
20365ca7badbSHoria Geantă 			.class1_alg_type = OP_ALG_ALGSEL_AES |
20375ca7badbSHoria Geantă 					   OP_ALG_AAI_CTR_MOD128,
20385ca7badbSHoria Geantă 			.rfc3686 = true,
20395ca7badbSHoria Geantă 		},
2040c6415a60SCatalin Vasile 	},
2041c6415a60SCatalin Vasile 	{
20425ca7badbSHoria Geantă 		.skcipher = {
20435ca7badbSHoria Geantă 			.base = {
20445ca7badbSHoria Geantă 				.cra_name = "xts(aes)",
20455ca7badbSHoria Geantă 				.cra_driver_name = "xts-aes-caam",
20465ca7badbSHoria Geantă 				.cra_blocksize = AES_BLOCK_SIZE,
20475ca7badbSHoria Geantă 			},
20485ca7badbSHoria Geantă 			.setkey = xts_skcipher_setkey,
20495ca7badbSHoria Geantă 			.encrypt = skcipher_encrypt,
20505ca7badbSHoria Geantă 			.decrypt = skcipher_decrypt,
2051c6415a60SCatalin Vasile 			.min_keysize = 2 * AES_MIN_KEY_SIZE,
2052c6415a60SCatalin Vasile 			.max_keysize = 2 * AES_MAX_KEY_SIZE,
2053c6415a60SCatalin Vasile 			.ivsize = AES_BLOCK_SIZE,
2054c6415a60SCatalin Vasile 		},
20555ca7badbSHoria Geantă 		.caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_XTS,
2056c6415a60SCatalin Vasile 	},
2057eaed71a4SIuliana Prodan 	{
2058eaed71a4SIuliana Prodan 		.skcipher = {
2059eaed71a4SIuliana Prodan 			.base = {
2060eaed71a4SIuliana Prodan 				.cra_name = "ecb(des)",
2061eaed71a4SIuliana Prodan 				.cra_driver_name = "ecb-des-caam",
2062eaed71a4SIuliana Prodan 				.cra_blocksize = DES_BLOCK_SIZE,
2063eaed71a4SIuliana Prodan 			},
2064eaed71a4SIuliana Prodan 			.setkey = des_skcipher_setkey,
2065eaed71a4SIuliana Prodan 			.encrypt = skcipher_encrypt,
2066eaed71a4SIuliana Prodan 			.decrypt = skcipher_decrypt,
2067eaed71a4SIuliana Prodan 			.min_keysize = DES_KEY_SIZE,
2068eaed71a4SIuliana Prodan 			.max_keysize = DES_KEY_SIZE,
2069eaed71a4SIuliana Prodan 		},
2070eaed71a4SIuliana Prodan 		.caam.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_ECB,
2071eaed71a4SIuliana Prodan 	},
2072eaed71a4SIuliana Prodan 	{
2073eaed71a4SIuliana Prodan 		.skcipher = {
2074eaed71a4SIuliana Prodan 			.base = {
2075eaed71a4SIuliana Prodan 				.cra_name = "ecb(aes)",
2076eaed71a4SIuliana Prodan 				.cra_driver_name = "ecb-aes-caam",
2077eaed71a4SIuliana Prodan 				.cra_blocksize = AES_BLOCK_SIZE,
2078eaed71a4SIuliana Prodan 			},
2079836d8f43SIuliana Prodan 			.setkey = aes_skcipher_setkey,
2080eaed71a4SIuliana Prodan 			.encrypt = skcipher_encrypt,
2081eaed71a4SIuliana Prodan 			.decrypt = skcipher_decrypt,
2082eaed71a4SIuliana Prodan 			.min_keysize = AES_MIN_KEY_SIZE,
2083eaed71a4SIuliana Prodan 			.max_keysize = AES_MAX_KEY_SIZE,
2084eaed71a4SIuliana Prodan 		},
2085eaed71a4SIuliana Prodan 		.caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_ECB,
2086eaed71a4SIuliana Prodan 	},
2087eaed71a4SIuliana Prodan 	{
2088eaed71a4SIuliana Prodan 		.skcipher = {
2089eaed71a4SIuliana Prodan 			.base = {
2090eaed71a4SIuliana Prodan 				.cra_name = "ecb(des3_ede)",
2091eaed71a4SIuliana Prodan 				.cra_driver_name = "ecb-des3-caam",
2092eaed71a4SIuliana Prodan 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2093eaed71a4SIuliana Prodan 			},
2094eaed71a4SIuliana Prodan 			.setkey = des_skcipher_setkey,
2095eaed71a4SIuliana Prodan 			.encrypt = skcipher_encrypt,
2096eaed71a4SIuliana Prodan 			.decrypt = skcipher_decrypt,
2097eaed71a4SIuliana Prodan 			.min_keysize = DES3_EDE_KEY_SIZE,
2098eaed71a4SIuliana Prodan 			.max_keysize = DES3_EDE_KEY_SIZE,
2099eaed71a4SIuliana Prodan 		},
2100eaed71a4SIuliana Prodan 		.caam.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_ECB,
2101eaed71a4SIuliana Prodan 	},
2102eaed71a4SIuliana Prodan 	{
2103eaed71a4SIuliana Prodan 		.skcipher = {
2104eaed71a4SIuliana Prodan 			.base = {
2105eaed71a4SIuliana Prodan 				.cra_name = "ecb(arc4)",
2106eaed71a4SIuliana Prodan 				.cra_driver_name = "ecb-arc4-caam",
2107eaed71a4SIuliana Prodan 				.cra_blocksize = ARC4_BLOCK_SIZE,
2108eaed71a4SIuliana Prodan 			},
2109836d8f43SIuliana Prodan 			.setkey = arc4_skcipher_setkey,
2110eaed71a4SIuliana Prodan 			.encrypt = skcipher_encrypt,
2111eaed71a4SIuliana Prodan 			.decrypt = skcipher_decrypt,
2112eaed71a4SIuliana Prodan 			.min_keysize = ARC4_MIN_KEY_SIZE,
2113eaed71a4SIuliana Prodan 			.max_keysize = ARC4_MAX_KEY_SIZE,
2114eaed71a4SIuliana Prodan 		},
2115eaed71a4SIuliana Prodan 		.caam.class1_alg_type = OP_ALG_ALGSEL_ARC4 | OP_ALG_AAI_ECB,
2116eaed71a4SIuliana Prodan 	},
21178e8ec596SKim Phillips };
21188e8ec596SKim Phillips 
2119f2147b88SHerbert Xu static struct caam_aead_alg driver_aeads[] = {
2120f2147b88SHerbert Xu 	{
2121f2147b88SHerbert Xu 		.aead = {
2122f2147b88SHerbert Xu 			.base = {
2123f2147b88SHerbert Xu 				.cra_name = "rfc4106(gcm(aes))",
2124f2147b88SHerbert Xu 				.cra_driver_name = "rfc4106-gcm-aes-caam",
2125f2147b88SHerbert Xu 				.cra_blocksize = 1,
2126f2147b88SHerbert Xu 			},
2127f2147b88SHerbert Xu 			.setkey = rfc4106_setkey,
2128f2147b88SHerbert Xu 			.setauthsize = rfc4106_setauthsize,
212946218750SHerbert Xu 			.encrypt = ipsec_gcm_encrypt,
213046218750SHerbert Xu 			.decrypt = ipsec_gcm_decrypt,
21317545e166SCorentin LABBE 			.ivsize = GCM_RFC4106_IV_SIZE,
2132f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
2133f2147b88SHerbert Xu 		},
2134f2147b88SHerbert Xu 		.caam = {
2135f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
213624586b5fSHerbert Xu 			.nodkp = true,
2137f2147b88SHerbert Xu 		},
2138f2147b88SHerbert Xu 	},
2139f2147b88SHerbert Xu 	{
2140f2147b88SHerbert Xu 		.aead = {
2141f2147b88SHerbert Xu 			.base = {
2142f2147b88SHerbert Xu 				.cra_name = "rfc4543(gcm(aes))",
2143f2147b88SHerbert Xu 				.cra_driver_name = "rfc4543-gcm-aes-caam",
2144f2147b88SHerbert Xu 				.cra_blocksize = 1,
2145f2147b88SHerbert Xu 			},
2146f2147b88SHerbert Xu 			.setkey = rfc4543_setkey,
2147f2147b88SHerbert Xu 			.setauthsize = rfc4543_setauthsize,
214846218750SHerbert Xu 			.encrypt = ipsec_gcm_encrypt,
214946218750SHerbert Xu 			.decrypt = ipsec_gcm_decrypt,
21507545e166SCorentin LABBE 			.ivsize = GCM_RFC4543_IV_SIZE,
2151f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
2152f2147b88SHerbert Xu 		},
2153f2147b88SHerbert Xu 		.caam = {
2154f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
215524586b5fSHerbert Xu 			.nodkp = true,
2156f2147b88SHerbert Xu 		},
2157f2147b88SHerbert Xu 	},
2158f2147b88SHerbert Xu 	/* Galois Counter Mode */
2159f2147b88SHerbert Xu 	{
2160f2147b88SHerbert Xu 		.aead = {
2161f2147b88SHerbert Xu 			.base = {
2162f2147b88SHerbert Xu 				.cra_name = "gcm(aes)",
2163f2147b88SHerbert Xu 				.cra_driver_name = "gcm-aes-caam",
2164f2147b88SHerbert Xu 				.cra_blocksize = 1,
2165f2147b88SHerbert Xu 			},
2166f2147b88SHerbert Xu 			.setkey = gcm_setkey,
2167f2147b88SHerbert Xu 			.setauthsize = gcm_setauthsize,
2168f2147b88SHerbert Xu 			.encrypt = gcm_encrypt,
2169f2147b88SHerbert Xu 			.decrypt = gcm_decrypt,
21707545e166SCorentin LABBE 			.ivsize = GCM_AES_IV_SIZE,
2171f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
2172f2147b88SHerbert Xu 		},
2173f2147b88SHerbert Xu 		.caam = {
2174f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
217524586b5fSHerbert Xu 			.nodkp = true,
2176f2147b88SHerbert Xu 		},
2177f2147b88SHerbert Xu 	},
2178479bcc7cSHerbert Xu 	/* single-pass ipsec_esp descriptor */
2179479bcc7cSHerbert Xu 	{
2180479bcc7cSHerbert Xu 		.aead = {
2181479bcc7cSHerbert Xu 			.base = {
2182479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),"
2183479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2184479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2185479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2186479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2187479bcc7cSHerbert Xu 			},
2188479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2189479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2190479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2191479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2192479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2193479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2194479bcc7cSHerbert Xu 		},
2195479bcc7cSHerbert Xu 		.caam = {
2196479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2197479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2198479bcc7cSHerbert Xu 		},
2199479bcc7cSHerbert Xu 	},
2200479bcc7cSHerbert Xu 	{
2201479bcc7cSHerbert Xu 		.aead = {
2202479bcc7cSHerbert Xu 			.base = {
2203479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
2204479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2205479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2206479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2207479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2208479bcc7cSHerbert Xu 			},
2209479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2210479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2211479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2212479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2213479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2214479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2215479bcc7cSHerbert Xu 		},
2216479bcc7cSHerbert Xu 		.caam = {
2217479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2218479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2219479bcc7cSHerbert Xu 		},
2220479bcc7cSHerbert Xu 	},
2221479bcc7cSHerbert Xu 	{
2222479bcc7cSHerbert Xu 		.aead = {
2223479bcc7cSHerbert Xu 			.base = {
2224479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
2225479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2226479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2227479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2228479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2229479bcc7cSHerbert Xu 			},
2230479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2231479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2232479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2233479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2234479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2235479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2236479bcc7cSHerbert Xu 		},
2237479bcc7cSHerbert Xu 		.caam = {
2238479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2239479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2240479bcc7cSHerbert Xu 		},
2241479bcc7cSHerbert Xu 	},
2242479bcc7cSHerbert Xu 	{
2243479bcc7cSHerbert Xu 		.aead = {
2244479bcc7cSHerbert Xu 			.base = {
2245479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
2246479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2247479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
2248479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2249479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2250479bcc7cSHerbert Xu 			},
2251479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2252479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2253479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2254479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2255479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2256479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2257479bcc7cSHerbert Xu 		},
2258479bcc7cSHerbert Xu 		.caam = {
2259479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2260479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2261479bcc7cSHerbert Xu 		},
2262479bcc7cSHerbert Xu 	},
2263479bcc7cSHerbert Xu 	{
2264479bcc7cSHerbert Xu 		.aead = {
2265479bcc7cSHerbert Xu 			.base = {
2266479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
2267479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2268479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
2269479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2270479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2271479bcc7cSHerbert Xu 			},
2272479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2273479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2274479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2275479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2276479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2277479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2278479bcc7cSHerbert Xu 		},
2279479bcc7cSHerbert Xu 		.caam = {
2280479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2281479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2282479bcc7cSHerbert Xu 		},
2283479bcc7cSHerbert Xu 	},
2284479bcc7cSHerbert Xu 	{
2285479bcc7cSHerbert Xu 		.aead = {
2286479bcc7cSHerbert Xu 			.base = {
2287479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
2288479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2289479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
2290479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2291479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2292479bcc7cSHerbert Xu 			},
2293479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2294479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2295479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2296479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2297479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2298479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2299479bcc7cSHerbert Xu 		},
2300479bcc7cSHerbert Xu 		.caam = {
2301479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2302479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2303479bcc7cSHerbert Xu 		},
2304479bcc7cSHerbert Xu 	},
2305479bcc7cSHerbert Xu 	{
2306479bcc7cSHerbert Xu 		.aead = {
2307479bcc7cSHerbert Xu 			.base = {
2308479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(aes))",
2309479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2310479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2311479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2312479bcc7cSHerbert Xu 			},
2313479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2314479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2315479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2316479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2317479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2318479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2319479bcc7cSHerbert Xu 		},
2320479bcc7cSHerbert Xu 		.caam = {
2321479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2322479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2323479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2324479bcc7cSHerbert Xu 		},
2325479bcc7cSHerbert Xu 	},
2326479bcc7cSHerbert Xu 	{
2327479bcc7cSHerbert Xu 		.aead = {
2328479bcc7cSHerbert Xu 			.base = {
2329479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
2330479bcc7cSHerbert Xu 					    "cbc(aes)))",
2331479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
2332479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2333479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2334479bcc7cSHerbert Xu 			},
2335479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2336479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2337479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
23388b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2339479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2340479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2341479bcc7cSHerbert Xu 		},
2342479bcc7cSHerbert Xu 		.caam = {
2343479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2344479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2345479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2346479bcc7cSHerbert Xu 			.geniv = true,
2347479bcc7cSHerbert Xu 		},
2348479bcc7cSHerbert Xu 	},
2349479bcc7cSHerbert Xu 	{
2350479bcc7cSHerbert Xu 		.aead = {
2351479bcc7cSHerbert Xu 			.base = {
2352479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),cbc(aes))",
2353479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2354479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2355479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2356479bcc7cSHerbert Xu 			},
2357479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2358479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2359479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2360479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2361479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2362479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2363479bcc7cSHerbert Xu 		},
2364479bcc7cSHerbert Xu 		.caam = {
2365479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2366479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2367479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2368479bcc7cSHerbert Xu 		},
2369479bcc7cSHerbert Xu 	},
2370479bcc7cSHerbert Xu 	{
2371479bcc7cSHerbert Xu 		.aead = {
2372479bcc7cSHerbert Xu 			.base = {
2373479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
2374479bcc7cSHerbert Xu 					    "cbc(aes)))",
2375479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2376479bcc7cSHerbert Xu 						   "hmac-sha1-cbc-aes-caam",
2377479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2378479bcc7cSHerbert Xu 			},
2379479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2380479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2381479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
23828b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2383479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2384479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2385479bcc7cSHerbert Xu 		},
2386479bcc7cSHerbert Xu 		.caam = {
2387479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2388479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2389479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2390479bcc7cSHerbert Xu 			.geniv = true,
2391479bcc7cSHerbert Xu 		},
2392479bcc7cSHerbert Xu 	},
2393479bcc7cSHerbert Xu 	{
2394479bcc7cSHerbert Xu 		.aead = {
2395479bcc7cSHerbert Xu 			.base = {
2396479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),cbc(aes))",
2397479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2398479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2399479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2400479bcc7cSHerbert Xu 			},
2401479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2402479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2403479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2404479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2405479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2406479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2407479bcc7cSHerbert Xu 		},
2408479bcc7cSHerbert Xu 		.caam = {
2409479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2410479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2411479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2412479bcc7cSHerbert Xu 		},
2413479bcc7cSHerbert Xu 	},
2414479bcc7cSHerbert Xu 	{
2415479bcc7cSHerbert Xu 		.aead = {
2416479bcc7cSHerbert Xu 			.base = {
2417479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
2418479bcc7cSHerbert Xu 					    "cbc(aes)))",
2419479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2420479bcc7cSHerbert Xu 						   "hmac-sha224-cbc-aes-caam",
2421479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2422479bcc7cSHerbert Xu 			},
2423479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2424479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2425479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
24268b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2427479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2428479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2429479bcc7cSHerbert Xu 		},
2430479bcc7cSHerbert Xu 		.caam = {
2431479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2432479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2433479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2434479bcc7cSHerbert Xu 			.geniv = true,
2435479bcc7cSHerbert Xu 		},
2436479bcc7cSHerbert Xu 	},
2437479bcc7cSHerbert Xu 	{
2438479bcc7cSHerbert Xu 		.aead = {
2439479bcc7cSHerbert Xu 			.base = {
2440479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),cbc(aes))",
2441479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
2442479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2443479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2444479bcc7cSHerbert Xu 			},
2445479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2446479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2447479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2448479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2449479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2450479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2451479bcc7cSHerbert Xu 		},
2452479bcc7cSHerbert Xu 		.caam = {
2453479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2454479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2455479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2456479bcc7cSHerbert Xu 		},
2457479bcc7cSHerbert Xu 	},
2458479bcc7cSHerbert Xu 	{
2459479bcc7cSHerbert Xu 		.aead = {
2460479bcc7cSHerbert Xu 			.base = {
2461479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
2462479bcc7cSHerbert Xu 					    "cbc(aes)))",
2463479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2464479bcc7cSHerbert Xu 						   "hmac-sha256-cbc-aes-caam",
2465479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2466479bcc7cSHerbert Xu 			},
2467479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2468479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2469479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
24708b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2471479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2472479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2473479bcc7cSHerbert Xu 		},
2474479bcc7cSHerbert Xu 		.caam = {
2475479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2476479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2477479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2478479bcc7cSHerbert Xu 			.geniv = true,
2479479bcc7cSHerbert Xu 		},
2480479bcc7cSHerbert Xu 	},
2481479bcc7cSHerbert Xu 	{
2482479bcc7cSHerbert Xu 		.aead = {
2483479bcc7cSHerbert Xu 			.base = {
2484479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),cbc(aes))",
2485479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
2486479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2487479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2488479bcc7cSHerbert Xu 			},
2489479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2490479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2491479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2492479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2493479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2494479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2495479bcc7cSHerbert Xu 		},
2496479bcc7cSHerbert Xu 		.caam = {
2497479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2498479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2499479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2500479bcc7cSHerbert Xu 		},
2501479bcc7cSHerbert Xu 	},
2502479bcc7cSHerbert Xu 	{
2503479bcc7cSHerbert Xu 		.aead = {
2504479bcc7cSHerbert Xu 			.base = {
2505479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
2506479bcc7cSHerbert Xu 					    "cbc(aes)))",
2507479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2508479bcc7cSHerbert Xu 						   "hmac-sha384-cbc-aes-caam",
2509479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2510479bcc7cSHerbert Xu 			},
2511479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2512479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2513479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
25148b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2515479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2516479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2517479bcc7cSHerbert Xu 		},
2518479bcc7cSHerbert Xu 		.caam = {
2519479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2520479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2521479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2522479bcc7cSHerbert Xu 			.geniv = true,
2523479bcc7cSHerbert Xu 		},
2524479bcc7cSHerbert Xu 	},
2525479bcc7cSHerbert Xu 	{
2526479bcc7cSHerbert Xu 		.aead = {
2527479bcc7cSHerbert Xu 			.base = {
2528479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),cbc(aes))",
2529479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
2530479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2531479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2532479bcc7cSHerbert Xu 			},
2533479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2534479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2535479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2536479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2537479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2538479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2539479bcc7cSHerbert Xu 		},
2540479bcc7cSHerbert Xu 		.caam = {
2541479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2542479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2543479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2544479bcc7cSHerbert Xu 		},
2545479bcc7cSHerbert Xu 	},
2546479bcc7cSHerbert Xu 	{
2547479bcc7cSHerbert Xu 		.aead = {
2548479bcc7cSHerbert Xu 			.base = {
2549479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
2550479bcc7cSHerbert Xu 					    "cbc(aes)))",
2551479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2552479bcc7cSHerbert Xu 						   "hmac-sha512-cbc-aes-caam",
2553479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2554479bcc7cSHerbert Xu 			},
2555479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2556479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2557479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
25588b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2559479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2560479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2561479bcc7cSHerbert Xu 		},
2562479bcc7cSHerbert Xu 		.caam = {
2563479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2564479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2565479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2566479bcc7cSHerbert Xu 			.geniv = true,
2567479bcc7cSHerbert Xu 		},
2568479bcc7cSHerbert Xu 	},
2569479bcc7cSHerbert Xu 	{
2570479bcc7cSHerbert Xu 		.aead = {
2571479bcc7cSHerbert Xu 			.base = {
2572479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2573479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2574479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2575479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2576479bcc7cSHerbert Xu 			},
25771b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2578479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2579479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2580479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2581479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2582479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2583479bcc7cSHerbert Xu 		},
2584479bcc7cSHerbert Xu 		.caam = {
2585479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2586479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2587479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2588479bcc7cSHerbert Xu 		}
2589479bcc7cSHerbert Xu 	},
2590479bcc7cSHerbert Xu 	{
2591479bcc7cSHerbert Xu 		.aead = {
2592479bcc7cSHerbert Xu 			.base = {
2593479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
2594479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2595479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
2596479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2597479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2598479bcc7cSHerbert Xu 			},
25991b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2600479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2601479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
26028b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2603479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2604479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2605479bcc7cSHerbert Xu 		},
2606479bcc7cSHerbert Xu 		.caam = {
2607479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2608479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2609479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2610479bcc7cSHerbert Xu 			.geniv = true,
2611479bcc7cSHerbert Xu 		}
2612479bcc7cSHerbert Xu 	},
2613479bcc7cSHerbert Xu 	{
2614479bcc7cSHerbert Xu 		.aead = {
2615479bcc7cSHerbert Xu 			.base = {
2616479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
2617479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2618479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2619479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2620479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2621479bcc7cSHerbert Xu 			},
26221b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2623479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2624479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2625479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2626479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2627479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2628479bcc7cSHerbert Xu 		},
2629479bcc7cSHerbert Xu 		.caam = {
2630479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2631479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2632479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2633479bcc7cSHerbert Xu 		},
2634479bcc7cSHerbert Xu 	},
2635479bcc7cSHerbert Xu 	{
2636479bcc7cSHerbert Xu 		.aead = {
2637479bcc7cSHerbert Xu 			.base = {
2638479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
2639479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2640479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2641479bcc7cSHerbert Xu 						   "hmac-sha1-"
2642479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2643479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2644479bcc7cSHerbert Xu 			},
26451b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2646479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2647479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
26488b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2649479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2650479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2651479bcc7cSHerbert Xu 		},
2652479bcc7cSHerbert Xu 		.caam = {
2653479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2654479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2655479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2656479bcc7cSHerbert Xu 			.geniv = true,
2657479bcc7cSHerbert Xu 		},
2658479bcc7cSHerbert Xu 	},
2659479bcc7cSHerbert Xu 	{
2660479bcc7cSHerbert Xu 		.aead = {
2661479bcc7cSHerbert Xu 			.base = {
2662479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
2663479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2664479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2665479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2666479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2667479bcc7cSHerbert Xu 			},
26681b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2669479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2670479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2671479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2672479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2673479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2674479bcc7cSHerbert Xu 		},
2675479bcc7cSHerbert Xu 		.caam = {
2676479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2677479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2678479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2679479bcc7cSHerbert Xu 		},
2680479bcc7cSHerbert Xu 	},
2681479bcc7cSHerbert Xu 	{
2682479bcc7cSHerbert Xu 		.aead = {
2683479bcc7cSHerbert Xu 			.base = {
2684479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
2685479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2686479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2687479bcc7cSHerbert Xu 						   "hmac-sha224-"
2688479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2689479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2690479bcc7cSHerbert Xu 			},
26911b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2692479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2693479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
26948b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2695479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2696479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2697479bcc7cSHerbert Xu 		},
2698479bcc7cSHerbert Xu 		.caam = {
2699479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2700479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2701479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2702479bcc7cSHerbert Xu 			.geniv = true,
2703479bcc7cSHerbert Xu 		},
2704479bcc7cSHerbert Xu 	},
2705479bcc7cSHerbert Xu 	{
2706479bcc7cSHerbert Xu 		.aead = {
2707479bcc7cSHerbert Xu 			.base = {
2708479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
2709479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2710479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
2711479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2712479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2713479bcc7cSHerbert Xu 			},
27141b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2715479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2716479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2717479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2718479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2719479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2720479bcc7cSHerbert Xu 		},
2721479bcc7cSHerbert Xu 		.caam = {
2722479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2723479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2724479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2725479bcc7cSHerbert Xu 		},
2726479bcc7cSHerbert Xu 	},
2727479bcc7cSHerbert Xu 	{
2728479bcc7cSHerbert Xu 		.aead = {
2729479bcc7cSHerbert Xu 			.base = {
2730479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
2731479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2732479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2733479bcc7cSHerbert Xu 						   "hmac-sha256-"
2734479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2735479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2736479bcc7cSHerbert Xu 			},
27371b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2738479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2739479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
27408b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2741479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2742479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2743479bcc7cSHerbert Xu 		},
2744479bcc7cSHerbert Xu 		.caam = {
2745479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2746479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2747479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2748479bcc7cSHerbert Xu 			.geniv = true,
2749479bcc7cSHerbert Xu 		},
2750479bcc7cSHerbert Xu 	},
2751479bcc7cSHerbert Xu 	{
2752479bcc7cSHerbert Xu 		.aead = {
2753479bcc7cSHerbert Xu 			.base = {
2754479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
2755479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2756479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
2757479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2758479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2759479bcc7cSHerbert Xu 			},
27601b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2761479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2762479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2763479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2764479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2765479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2766479bcc7cSHerbert Xu 		},
2767479bcc7cSHerbert Xu 		.caam = {
2768479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2769479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2770479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2771479bcc7cSHerbert Xu 		},
2772479bcc7cSHerbert Xu 	},
2773479bcc7cSHerbert Xu 	{
2774479bcc7cSHerbert Xu 		.aead = {
2775479bcc7cSHerbert Xu 			.base = {
2776479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
2777479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2778479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2779479bcc7cSHerbert Xu 						   "hmac-sha384-"
2780479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2781479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2782479bcc7cSHerbert Xu 			},
27831b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2784479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2785479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
27868b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2787479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2788479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2789479bcc7cSHerbert Xu 		},
2790479bcc7cSHerbert Xu 		.caam = {
2791479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2792479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2793479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2794479bcc7cSHerbert Xu 			.geniv = true,
2795479bcc7cSHerbert Xu 		},
2796479bcc7cSHerbert Xu 	},
2797479bcc7cSHerbert Xu 	{
2798479bcc7cSHerbert Xu 		.aead = {
2799479bcc7cSHerbert Xu 			.base = {
2800479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
2801479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2802479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
2803479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2804479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2805479bcc7cSHerbert Xu 			},
28061b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2807479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2808479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2809479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2810479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2811479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2812479bcc7cSHerbert Xu 		},
2813479bcc7cSHerbert Xu 		.caam = {
2814479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2815479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2816479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2817479bcc7cSHerbert Xu 		},
2818479bcc7cSHerbert Xu 	},
2819479bcc7cSHerbert Xu 	{
2820479bcc7cSHerbert Xu 		.aead = {
2821479bcc7cSHerbert Xu 			.base = {
2822479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
2823479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2824479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2825479bcc7cSHerbert Xu 						   "hmac-sha512-"
2826479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2827479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2828479bcc7cSHerbert Xu 			},
28291b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2830479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2831479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
28328b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2833479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2834479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2835479bcc7cSHerbert Xu 		},
2836479bcc7cSHerbert Xu 		.caam = {
2837479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2838479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2839479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2840479bcc7cSHerbert Xu 			.geniv = true,
2841479bcc7cSHerbert Xu 		},
2842479bcc7cSHerbert Xu 	},
2843479bcc7cSHerbert Xu 	{
2844479bcc7cSHerbert Xu 		.aead = {
2845479bcc7cSHerbert Xu 			.base = {
2846479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(des))",
2847479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2848479bcc7cSHerbert Xu 						   "cbc-des-caam",
2849479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2850479bcc7cSHerbert Xu 			},
2851479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2852479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2853479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2854479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2855479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2856479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2857479bcc7cSHerbert Xu 		},
2858479bcc7cSHerbert Xu 		.caam = {
2859479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2860479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2861479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2862479bcc7cSHerbert Xu 		},
2863479bcc7cSHerbert Xu 	},
2864479bcc7cSHerbert Xu 	{
2865479bcc7cSHerbert Xu 		.aead = {
2866479bcc7cSHerbert Xu 			.base = {
2867479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
2868479bcc7cSHerbert Xu 					    "cbc(des)))",
2869479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
2870479bcc7cSHerbert Xu 						   "cbc-des-caam",
2871479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2872479bcc7cSHerbert Xu 			},
2873479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2874479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2875479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
28768b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2877479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2878479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2879479bcc7cSHerbert Xu 		},
2880479bcc7cSHerbert Xu 		.caam = {
2881479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2882479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2883479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2884479bcc7cSHerbert Xu 			.geniv = true,
2885479bcc7cSHerbert Xu 		},
2886479bcc7cSHerbert Xu 	},
2887479bcc7cSHerbert Xu 	{
2888479bcc7cSHerbert Xu 		.aead = {
2889479bcc7cSHerbert Xu 			.base = {
2890479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),cbc(des))",
2891479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2892479bcc7cSHerbert Xu 						   "cbc-des-caam",
2893479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2894479bcc7cSHerbert Xu 			},
2895479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2896479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2897479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2898479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2899479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2900479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2901479bcc7cSHerbert Xu 		},
2902479bcc7cSHerbert Xu 		.caam = {
2903479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2904479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2905479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2906479bcc7cSHerbert Xu 		},
2907479bcc7cSHerbert Xu 	},
2908479bcc7cSHerbert Xu 	{
2909479bcc7cSHerbert Xu 		.aead = {
2910479bcc7cSHerbert Xu 			.base = {
2911479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
2912479bcc7cSHerbert Xu 					    "cbc(des)))",
2913479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2914479bcc7cSHerbert Xu 						   "hmac-sha1-cbc-des-caam",
2915479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2916479bcc7cSHerbert Xu 			},
2917479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2918479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2919479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
29208b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2921479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2922479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2923479bcc7cSHerbert Xu 		},
2924479bcc7cSHerbert Xu 		.caam = {
2925479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2926479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2927479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2928479bcc7cSHerbert Xu 			.geniv = true,
2929479bcc7cSHerbert Xu 		},
2930479bcc7cSHerbert Xu 	},
2931479bcc7cSHerbert Xu 	{
2932479bcc7cSHerbert Xu 		.aead = {
2933479bcc7cSHerbert Xu 			.base = {
2934479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),cbc(des))",
2935479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2936479bcc7cSHerbert Xu 						   "cbc-des-caam",
2937479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2938479bcc7cSHerbert Xu 			},
2939479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2940479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2941479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2942479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2943479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2944479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2945479bcc7cSHerbert Xu 		},
2946479bcc7cSHerbert Xu 		.caam = {
2947479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2948479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2949479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2950479bcc7cSHerbert Xu 		},
2951479bcc7cSHerbert Xu 	},
2952479bcc7cSHerbert Xu 	{
2953479bcc7cSHerbert Xu 		.aead = {
2954479bcc7cSHerbert Xu 			.base = {
2955479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
2956479bcc7cSHerbert Xu 					    "cbc(des)))",
2957479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2958479bcc7cSHerbert Xu 						   "hmac-sha224-cbc-des-caam",
2959479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2960479bcc7cSHerbert Xu 			},
2961479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2962479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2963479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
29648b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2965479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2966479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2967479bcc7cSHerbert Xu 		},
2968479bcc7cSHerbert Xu 		.caam = {
2969479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2970479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2971479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2972479bcc7cSHerbert Xu 			.geniv = true,
2973479bcc7cSHerbert Xu 		},
2974479bcc7cSHerbert Xu 	},
2975479bcc7cSHerbert Xu 	{
2976479bcc7cSHerbert Xu 		.aead = {
2977479bcc7cSHerbert Xu 			.base = {
2978479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),cbc(des))",
2979479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
2980479bcc7cSHerbert Xu 						   "cbc-des-caam",
2981479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2982479bcc7cSHerbert Xu 			},
2983479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2984479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2985479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2986479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2987479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2988479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2989479bcc7cSHerbert Xu 		},
2990479bcc7cSHerbert Xu 		.caam = {
2991479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2992479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2993479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2994479bcc7cSHerbert Xu 		},
2995479bcc7cSHerbert Xu 	},
2996479bcc7cSHerbert Xu 	{
2997479bcc7cSHerbert Xu 		.aead = {
2998479bcc7cSHerbert Xu 			.base = {
2999479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
3000479bcc7cSHerbert Xu 					    "cbc(des)))",
3001479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3002479bcc7cSHerbert Xu 						   "hmac-sha256-cbc-des-caam",
3003479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3004479bcc7cSHerbert Xu 			},
3005479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3006479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3007479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
30088b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3009479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3010479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3011479bcc7cSHerbert Xu 		},
3012479bcc7cSHerbert Xu 		.caam = {
3013479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3014479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3015479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3016479bcc7cSHerbert Xu 			.geniv = true,
3017479bcc7cSHerbert Xu 		},
3018479bcc7cSHerbert Xu 	},
3019479bcc7cSHerbert Xu 	{
3020479bcc7cSHerbert Xu 		.aead = {
3021479bcc7cSHerbert Xu 			.base = {
3022479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),cbc(des))",
3023479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
3024479bcc7cSHerbert Xu 						   "cbc-des-caam",
3025479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3026479bcc7cSHerbert Xu 			},
3027479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3028479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3029479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3030479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3031479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3032479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3033479bcc7cSHerbert Xu 		},
3034479bcc7cSHerbert Xu 		.caam = {
3035479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3036479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3037479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3038479bcc7cSHerbert Xu 		},
3039479bcc7cSHerbert Xu 	},
3040479bcc7cSHerbert Xu 	{
3041479bcc7cSHerbert Xu 		.aead = {
3042479bcc7cSHerbert Xu 			.base = {
3043479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
3044479bcc7cSHerbert Xu 					    "cbc(des)))",
3045479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3046479bcc7cSHerbert Xu 						   "hmac-sha384-cbc-des-caam",
3047479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3048479bcc7cSHerbert Xu 			},
3049479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3050479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3051479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
30528b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3053479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3054479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3055479bcc7cSHerbert Xu 		},
3056479bcc7cSHerbert Xu 		.caam = {
3057479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3058479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3059479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3060479bcc7cSHerbert Xu 			.geniv = true,
3061479bcc7cSHerbert Xu 		},
3062479bcc7cSHerbert Xu 	},
3063479bcc7cSHerbert Xu 	{
3064479bcc7cSHerbert Xu 		.aead = {
3065479bcc7cSHerbert Xu 			.base = {
3066479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),cbc(des))",
3067479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
3068479bcc7cSHerbert Xu 						   "cbc-des-caam",
3069479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3070479bcc7cSHerbert Xu 			},
3071479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3072479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3073479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3074479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3075479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3076479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3077479bcc7cSHerbert Xu 		},
3078479bcc7cSHerbert Xu 		.caam = {
3079479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3080479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3081479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3082479bcc7cSHerbert Xu 		},
3083479bcc7cSHerbert Xu 	},
3084479bcc7cSHerbert Xu 	{
3085479bcc7cSHerbert Xu 		.aead = {
3086479bcc7cSHerbert Xu 			.base = {
3087479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
3088479bcc7cSHerbert Xu 					    "cbc(des)))",
3089479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3090479bcc7cSHerbert Xu 						   "hmac-sha512-cbc-des-caam",
3091479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3092479bcc7cSHerbert Xu 			},
3093479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3094479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3095479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
30968b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3097479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3098479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3099479bcc7cSHerbert Xu 		},
3100479bcc7cSHerbert Xu 		.caam = {
3101479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3102479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3103479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3104479bcc7cSHerbert Xu 			.geniv = true,
3105479bcc7cSHerbert Xu 		},
3106479bcc7cSHerbert Xu 	},
3107479bcc7cSHerbert Xu 	{
3108479bcc7cSHerbert Xu 		.aead = {
3109479bcc7cSHerbert Xu 			.base = {
3110479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),"
3111479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3112479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
3113479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3114479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3115479bcc7cSHerbert Xu 			},
3116479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3117479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3118479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3119479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3120479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3121479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3122479bcc7cSHerbert Xu 		},
3123479bcc7cSHerbert Xu 		.caam = {
3124479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3125479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3126479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3127479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3128479bcc7cSHerbert Xu 			.rfc3686 = true,
3129479bcc7cSHerbert Xu 		},
3130479bcc7cSHerbert Xu 	},
3131479bcc7cSHerbert Xu 	{
3132479bcc7cSHerbert Xu 		.aead = {
3133479bcc7cSHerbert Xu 			.base = {
3134479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
3135479bcc7cSHerbert Xu 					    "hmac(md5),rfc3686(ctr(aes))))",
3136479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-md5-"
3137479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3138479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3139479bcc7cSHerbert Xu 			},
3140479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3141479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3142479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
31438b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3144479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3145479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3146479bcc7cSHerbert Xu 		},
3147479bcc7cSHerbert Xu 		.caam = {
3148479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3149479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3150479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3151479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3152479bcc7cSHerbert Xu 			.rfc3686 = true,
3153479bcc7cSHerbert Xu 			.geniv = true,
3154479bcc7cSHerbert Xu 		},
3155479bcc7cSHerbert Xu 	},
3156479bcc7cSHerbert Xu 	{
3157479bcc7cSHerbert Xu 		.aead = {
3158479bcc7cSHerbert Xu 			.base = {
3159479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
3160479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3161479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
3162479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3163479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3164479bcc7cSHerbert Xu 			},
3165479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3166479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3167479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3168479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3169479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3170479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3171479bcc7cSHerbert Xu 		},
3172479bcc7cSHerbert Xu 		.caam = {
3173479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3174479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3175479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3176479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3177479bcc7cSHerbert Xu 			.rfc3686 = true,
3178479bcc7cSHerbert Xu 		},
3179479bcc7cSHerbert Xu 	},
3180479bcc7cSHerbert Xu 	{
3181479bcc7cSHerbert Xu 		.aead = {
3182479bcc7cSHerbert Xu 			.base = {
3183479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
3184479bcc7cSHerbert Xu 					    "hmac(sha1),rfc3686(ctr(aes))))",
3185479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha1-"
3186479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3187479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3188479bcc7cSHerbert Xu 			},
3189479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3190479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3191479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
31928b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3193479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3194479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3195479bcc7cSHerbert Xu 		},
3196479bcc7cSHerbert Xu 		.caam = {
3197479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3198479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3199479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3200479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3201479bcc7cSHerbert Xu 			.rfc3686 = true,
3202479bcc7cSHerbert Xu 			.geniv = true,
3203479bcc7cSHerbert Xu 		},
3204479bcc7cSHerbert Xu 	},
3205479bcc7cSHerbert Xu 	{
3206479bcc7cSHerbert Xu 		.aead = {
3207479bcc7cSHerbert Xu 			.base = {
3208479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
3209479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3210479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
3211479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3212479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3213479bcc7cSHerbert Xu 			},
3214479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3215479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3216479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3217479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3218479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3219479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3220479bcc7cSHerbert Xu 		},
3221479bcc7cSHerbert Xu 		.caam = {
3222479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3223479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3224479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3225479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3226479bcc7cSHerbert Xu 			.rfc3686 = true,
3227479bcc7cSHerbert Xu 		},
3228479bcc7cSHerbert Xu 	},
3229479bcc7cSHerbert Xu 	{
3230479bcc7cSHerbert Xu 		.aead = {
3231479bcc7cSHerbert Xu 			.base = {
3232479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
3233479bcc7cSHerbert Xu 					    "hmac(sha224),rfc3686(ctr(aes))))",
3234479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha224-"
3235479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3236479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3237479bcc7cSHerbert Xu 			},
3238479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3239479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3240479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
32418b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3242479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3243479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3244479bcc7cSHerbert Xu 		},
3245479bcc7cSHerbert Xu 		.caam = {
3246479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3247479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3248479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3249479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3250479bcc7cSHerbert Xu 			.rfc3686 = true,
3251479bcc7cSHerbert Xu 			.geniv = true,
3252479bcc7cSHerbert Xu 		},
3253479bcc7cSHerbert Xu 	},
3254479bcc7cSHerbert Xu 	{
3255479bcc7cSHerbert Xu 		.aead = {
3256479bcc7cSHerbert Xu 			.base = {
3257479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
3258479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3259479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
3260479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3261479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3262479bcc7cSHerbert Xu 			},
3263479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3264479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3265479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3266479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3267479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3268479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3269479bcc7cSHerbert Xu 		},
3270479bcc7cSHerbert Xu 		.caam = {
3271479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3272479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3273479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3274479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3275479bcc7cSHerbert Xu 			.rfc3686 = true,
3276479bcc7cSHerbert Xu 		},
3277479bcc7cSHerbert Xu 	},
3278479bcc7cSHerbert Xu 	{
3279479bcc7cSHerbert Xu 		.aead = {
3280479bcc7cSHerbert Xu 			.base = {
3281479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha256),"
3282479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
3283479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha256-"
3284479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3285479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3286479bcc7cSHerbert Xu 			},
3287479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3288479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3289479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
32908b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3291479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3292479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3293479bcc7cSHerbert Xu 		},
3294479bcc7cSHerbert Xu 		.caam = {
3295479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3296479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3297479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3298479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3299479bcc7cSHerbert Xu 			.rfc3686 = true,
3300479bcc7cSHerbert Xu 			.geniv = true,
3301479bcc7cSHerbert Xu 		},
3302479bcc7cSHerbert Xu 	},
3303479bcc7cSHerbert Xu 	{
3304479bcc7cSHerbert Xu 		.aead = {
3305479bcc7cSHerbert Xu 			.base = {
3306479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
3307479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3308479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
3309479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3310479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3311479bcc7cSHerbert Xu 			},
3312479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3313479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3314479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3315479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3316479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3317479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3318479bcc7cSHerbert Xu 		},
3319479bcc7cSHerbert Xu 		.caam = {
3320479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3321479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3322479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3323479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3324479bcc7cSHerbert Xu 			.rfc3686 = true,
3325479bcc7cSHerbert Xu 		},
3326479bcc7cSHerbert Xu 	},
3327479bcc7cSHerbert Xu 	{
3328479bcc7cSHerbert Xu 		.aead = {
3329479bcc7cSHerbert Xu 			.base = {
3330479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha384),"
3331479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
3332479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha384-"
3333479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3334479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3335479bcc7cSHerbert Xu 			},
3336479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3337479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3338479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
33398b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3340479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3341479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3342479bcc7cSHerbert Xu 		},
3343479bcc7cSHerbert Xu 		.caam = {
3344479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3345479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3346479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3347479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3348479bcc7cSHerbert Xu 			.rfc3686 = true,
3349479bcc7cSHerbert Xu 			.geniv = true,
3350479bcc7cSHerbert Xu 		},
3351479bcc7cSHerbert Xu 	},
3352479bcc7cSHerbert Xu 	{
3353479bcc7cSHerbert Xu 		.aead = {
3354479bcc7cSHerbert Xu 			.base = {
3355479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
3356479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3357479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
3358479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3359479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3360479bcc7cSHerbert Xu 			},
3361479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3362479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3363479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3364479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3365479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3366479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3367479bcc7cSHerbert Xu 		},
3368479bcc7cSHerbert Xu 		.caam = {
3369479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3370479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3371479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3372479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3373479bcc7cSHerbert Xu 			.rfc3686 = true,
3374479bcc7cSHerbert Xu 		},
3375479bcc7cSHerbert Xu 	},
3376479bcc7cSHerbert Xu 	{
3377479bcc7cSHerbert Xu 		.aead = {
3378479bcc7cSHerbert Xu 			.base = {
3379479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha512),"
3380479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
3381479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha512-"
3382479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3383479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3384479bcc7cSHerbert Xu 			},
3385479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3386479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3387479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
33888b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3389479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3390479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3391479bcc7cSHerbert Xu 		},
3392479bcc7cSHerbert Xu 		.caam = {
3393479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3394479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3395479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3396479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3397479bcc7cSHerbert Xu 			.rfc3686 = true,
3398479bcc7cSHerbert Xu 			.geniv = true,
3399479bcc7cSHerbert Xu 		},
3400479bcc7cSHerbert Xu 	},
3401d6bbd4eeSHoria Geantă 	{
3402d6bbd4eeSHoria Geantă 		.aead = {
3403d6bbd4eeSHoria Geantă 			.base = {
3404d6bbd4eeSHoria Geantă 				.cra_name = "rfc7539(chacha20,poly1305)",
3405d6bbd4eeSHoria Geantă 				.cra_driver_name = "rfc7539-chacha20-poly1305-"
3406d6bbd4eeSHoria Geantă 						   "caam",
3407d6bbd4eeSHoria Geantă 				.cra_blocksize = 1,
3408d6bbd4eeSHoria Geantă 			},
3409d6bbd4eeSHoria Geantă 			.setkey = chachapoly_setkey,
3410d6bbd4eeSHoria Geantă 			.setauthsize = chachapoly_setauthsize,
3411d6bbd4eeSHoria Geantă 			.encrypt = chachapoly_encrypt,
3412d6bbd4eeSHoria Geantă 			.decrypt = chachapoly_decrypt,
3413d6bbd4eeSHoria Geantă 			.ivsize = CHACHAPOLY_IV_SIZE,
3414d6bbd4eeSHoria Geantă 			.maxauthsize = POLY1305_DIGEST_SIZE,
3415d6bbd4eeSHoria Geantă 		},
3416d6bbd4eeSHoria Geantă 		.caam = {
3417d6bbd4eeSHoria Geantă 			.class1_alg_type = OP_ALG_ALGSEL_CHACHA20 |
3418d6bbd4eeSHoria Geantă 					   OP_ALG_AAI_AEAD,
3419d6bbd4eeSHoria Geantă 			.class2_alg_type = OP_ALG_ALGSEL_POLY1305 |
3420d6bbd4eeSHoria Geantă 					   OP_ALG_AAI_AEAD,
342124586b5fSHerbert Xu 			.nodkp = true,
3422d6bbd4eeSHoria Geantă 		},
3423d6bbd4eeSHoria Geantă 	},
3424d6bbd4eeSHoria Geantă 	{
3425d6bbd4eeSHoria Geantă 		.aead = {
3426d6bbd4eeSHoria Geantă 			.base = {
3427d6bbd4eeSHoria Geantă 				.cra_name = "rfc7539esp(chacha20,poly1305)",
3428d6bbd4eeSHoria Geantă 				.cra_driver_name = "rfc7539esp-chacha20-"
3429d6bbd4eeSHoria Geantă 						   "poly1305-caam",
3430d6bbd4eeSHoria Geantă 				.cra_blocksize = 1,
3431d6bbd4eeSHoria Geantă 			},
3432d6bbd4eeSHoria Geantă 			.setkey = chachapoly_setkey,
3433d6bbd4eeSHoria Geantă 			.setauthsize = chachapoly_setauthsize,
3434d6bbd4eeSHoria Geantă 			.encrypt = chachapoly_encrypt,
3435d6bbd4eeSHoria Geantă 			.decrypt = chachapoly_decrypt,
3436d6bbd4eeSHoria Geantă 			.ivsize = 8,
3437d6bbd4eeSHoria Geantă 			.maxauthsize = POLY1305_DIGEST_SIZE,
3438d6bbd4eeSHoria Geantă 		},
3439d6bbd4eeSHoria Geantă 		.caam = {
3440d6bbd4eeSHoria Geantă 			.class1_alg_type = OP_ALG_ALGSEL_CHACHA20 |
3441d6bbd4eeSHoria Geantă 					   OP_ALG_AAI_AEAD,
3442d6bbd4eeSHoria Geantă 			.class2_alg_type = OP_ALG_ALGSEL_POLY1305 |
3443d6bbd4eeSHoria Geantă 					   OP_ALG_AAI_AEAD,
344424586b5fSHerbert Xu 			.nodkp = true,
3445d6bbd4eeSHoria Geantă 		},
3446d6bbd4eeSHoria Geantă 	},
3447f2147b88SHerbert Xu };
3448f2147b88SHerbert Xu 
34497e0880b9SHoria Geantă static int caam_init_common(struct caam_ctx *ctx, struct caam_alg_entry *caam,
34507e0880b9SHoria Geantă 			    bool uses_dkp)
3451f2147b88SHerbert Xu {
3452bbf22344SHoria Geantă 	dma_addr_t dma_addr;
34537e0880b9SHoria Geantă 	struct caam_drv_private *priv;
3454bbf22344SHoria Geantă 
3455f2147b88SHerbert Xu 	ctx->jrdev = caam_jr_alloc();
3456f2147b88SHerbert Xu 	if (IS_ERR(ctx->jrdev)) {
3457f2147b88SHerbert Xu 		pr_err("Job Ring Device allocation for transform failed\n");
3458f2147b88SHerbert Xu 		return PTR_ERR(ctx->jrdev);
3459f2147b88SHerbert Xu 	}
3460f2147b88SHerbert Xu 
34617e0880b9SHoria Geantă 	priv = dev_get_drvdata(ctx->jrdev->parent);
34627e0880b9SHoria Geantă 	if (priv->era >= 6 && uses_dkp)
34637e0880b9SHoria Geantă 		ctx->dir = DMA_BIDIRECTIONAL;
34647e0880b9SHoria Geantă 	else
34657e0880b9SHoria Geantă 		ctx->dir = DMA_TO_DEVICE;
34667e0880b9SHoria Geantă 
3467bbf22344SHoria Geantă 	dma_addr = dma_map_single_attrs(ctx->jrdev, ctx->sh_desc_enc,
3468bbf22344SHoria Geantă 					offsetof(struct caam_ctx,
3469bbf22344SHoria Geantă 						 sh_desc_enc_dma),
34707e0880b9SHoria Geantă 					ctx->dir, DMA_ATTR_SKIP_CPU_SYNC);
3471bbf22344SHoria Geantă 	if (dma_mapping_error(ctx->jrdev, dma_addr)) {
3472bbf22344SHoria Geantă 		dev_err(ctx->jrdev, "unable to map key, shared descriptors\n");
3473bbf22344SHoria Geantă 		caam_jr_free(ctx->jrdev);
3474bbf22344SHoria Geantă 		return -ENOMEM;
3475bbf22344SHoria Geantă 	}
3476bbf22344SHoria Geantă 
3477bbf22344SHoria Geantă 	ctx->sh_desc_enc_dma = dma_addr;
3478bbf22344SHoria Geantă 	ctx->sh_desc_dec_dma = dma_addr + offsetof(struct caam_ctx,
3479bbf22344SHoria Geantă 						   sh_desc_dec);
3480bbf22344SHoria Geantă 	ctx->key_dma = dma_addr + offsetof(struct caam_ctx, key);
3481bbf22344SHoria Geantă 
3482f2147b88SHerbert Xu 	/* copy descriptor header template value */
3483db57656bSHoria Geantă 	ctx->cdata.algtype = OP_TYPE_CLASS1_ALG | caam->class1_alg_type;
3484db57656bSHoria Geantă 	ctx->adata.algtype = OP_TYPE_CLASS2_ALG | caam->class2_alg_type;
3485f2147b88SHerbert Xu 
3486f2147b88SHerbert Xu 	return 0;
3487f2147b88SHerbert Xu }
3488f2147b88SHerbert Xu 
34895ca7badbSHoria Geantă static int caam_cra_init(struct crypto_skcipher *tfm)
34908e8ec596SKim Phillips {
34915ca7badbSHoria Geantă 	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
34925ca7badbSHoria Geantă 	struct caam_skcipher_alg *caam_alg =
34935ca7badbSHoria Geantă 		container_of(alg, typeof(*caam_alg), skcipher);
34948e8ec596SKim Phillips 
34955ca7badbSHoria Geantă 	return caam_init_common(crypto_skcipher_ctx(tfm), &caam_alg->caam,
34965ca7badbSHoria Geantă 				false);
3497cfc6f11bSRuchika Gupta }
34988e8ec596SKim Phillips 
3499f2147b88SHerbert Xu static int caam_aead_init(struct crypto_aead *tfm)
35008e8ec596SKim Phillips {
3501f2147b88SHerbert Xu 	struct aead_alg *alg = crypto_aead_alg(tfm);
3502f2147b88SHerbert Xu 	struct caam_aead_alg *caam_alg =
3503f2147b88SHerbert Xu 		 container_of(alg, struct caam_aead_alg, aead);
3504f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(tfm);
35058e8ec596SKim Phillips 
350624586b5fSHerbert Xu 	return caam_init_common(ctx, &caam_alg->caam, !caam_alg->caam.nodkp);
3507f2147b88SHerbert Xu }
3508f2147b88SHerbert Xu 
3509f2147b88SHerbert Xu static void caam_exit_common(struct caam_ctx *ctx)
3510f2147b88SHerbert Xu {
3511bbf22344SHoria Geantă 	dma_unmap_single_attrs(ctx->jrdev, ctx->sh_desc_enc_dma,
3512bbf22344SHoria Geantă 			       offsetof(struct caam_ctx, sh_desc_enc_dma),
35137e0880b9SHoria Geantă 			       ctx->dir, DMA_ATTR_SKIP_CPU_SYNC);
3514cfc6f11bSRuchika Gupta 	caam_jr_free(ctx->jrdev);
35158e8ec596SKim Phillips }
35168e8ec596SKim Phillips 
35175ca7badbSHoria Geantă static void caam_cra_exit(struct crypto_skcipher *tfm)
3518f2147b88SHerbert Xu {
35195ca7badbSHoria Geantă 	caam_exit_common(crypto_skcipher_ctx(tfm));
3520f2147b88SHerbert Xu }
3521f2147b88SHerbert Xu 
3522f2147b88SHerbert Xu static void caam_aead_exit(struct crypto_aead *tfm)
3523f2147b88SHerbert Xu {
3524f2147b88SHerbert Xu 	caam_exit_common(crypto_aead_ctx(tfm));
3525f2147b88SHerbert Xu }
3526f2147b88SHerbert Xu 
35271b46c90cSHoria Geantă void caam_algapi_exit(void)
35288e8ec596SKim Phillips {
3529f2147b88SHerbert Xu 	int i;
3530f2147b88SHerbert Xu 
3531f2147b88SHerbert Xu 	for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
3532f2147b88SHerbert Xu 		struct caam_aead_alg *t_alg = driver_aeads + i;
3533f2147b88SHerbert Xu 
3534f2147b88SHerbert Xu 		if (t_alg->registered)
3535f2147b88SHerbert Xu 			crypto_unregister_aead(&t_alg->aead);
3536f2147b88SHerbert Xu 	}
35378e8ec596SKim Phillips 
35385ca7badbSHoria Geantă 	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
35395ca7badbSHoria Geantă 		struct caam_skcipher_alg *t_alg = driver_algs + i;
35408e8ec596SKim Phillips 
35415ca7badbSHoria Geantă 		if (t_alg->registered)
35425ca7badbSHoria Geantă 			crypto_unregister_skcipher(&t_alg->skcipher);
35438e8ec596SKim Phillips 	}
35448e8ec596SKim Phillips }
35458e8ec596SKim Phillips 
35465ca7badbSHoria Geantă static void caam_skcipher_alg_init(struct caam_skcipher_alg *t_alg)
35478e8ec596SKim Phillips {
35485ca7badbSHoria Geantă 	struct skcipher_alg *alg = &t_alg->skcipher;
35498e8ec596SKim Phillips 
35505ca7badbSHoria Geantă 	alg->base.cra_module = THIS_MODULE;
35515ca7badbSHoria Geantă 	alg->base.cra_priority = CAAM_CRA_PRIORITY;
35525ca7badbSHoria Geantă 	alg->base.cra_ctxsize = sizeof(struct caam_ctx);
35535ca7badbSHoria Geantă 	alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY;
35548e8ec596SKim Phillips 
35555ca7badbSHoria Geantă 	alg->init = caam_cra_init;
35565ca7badbSHoria Geantă 	alg->exit = caam_cra_exit;
35578e8ec596SKim Phillips }
35588e8ec596SKim Phillips 
3559f2147b88SHerbert Xu static void caam_aead_alg_init(struct caam_aead_alg *t_alg)
3560f2147b88SHerbert Xu {
3561f2147b88SHerbert Xu 	struct aead_alg *alg = &t_alg->aead;
3562f2147b88SHerbert Xu 
3563f2147b88SHerbert Xu 	alg->base.cra_module = THIS_MODULE;
3564f2147b88SHerbert Xu 	alg->base.cra_priority = CAAM_CRA_PRIORITY;
3565f2147b88SHerbert Xu 	alg->base.cra_ctxsize = sizeof(struct caam_ctx);
35665e4b8c1fSHerbert Xu 	alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY;
3567f2147b88SHerbert Xu 
3568f2147b88SHerbert Xu 	alg->init = caam_aead_init;
3569f2147b88SHerbert Xu 	alg->exit = caam_aead_exit;
3570f2147b88SHerbert Xu }
3571f2147b88SHerbert Xu 
35721b46c90cSHoria Geantă int caam_algapi_init(struct device *ctrldev)
35738e8ec596SKim Phillips {
35741b46c90cSHoria Geantă 	struct caam_drv_private *priv = dev_get_drvdata(ctrldev);
35758e8ec596SKim Phillips 	int i = 0, err = 0;
3576d6bbd4eeSHoria Geantă 	u32 aes_vid, aes_inst, des_inst, md_vid, md_inst, ccha_inst, ptha_inst;
3577eaed71a4SIuliana Prodan 	u32 arc4_inst;
3578bf83490eSVictoria Milhoan 	unsigned int md_limit = SHA512_DIGEST_SIZE;
3579df80bfd3SHoria Geantă 	bool registered = false, gcm_support;
35808e8ec596SKim Phillips 
3581bf83490eSVictoria Milhoan 	/*
3582bf83490eSVictoria Milhoan 	 * Register crypto algorithms the device supports.
3583bf83490eSVictoria Milhoan 	 * First, detect presence and attributes of DES, AES, and MD blocks.
3584bf83490eSVictoria Milhoan 	 */
3585d239b10dSHoria Geantă 	if (priv->era < 10) {
3586df80bfd3SHoria Geantă 		u32 cha_vid, cha_inst, aes_rn;
3587d239b10dSHoria Geantă 
3588bf83490eSVictoria Milhoan 		cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
3589d239b10dSHoria Geantă 		aes_vid = cha_vid & CHA_ID_LS_AES_MASK;
3590d239b10dSHoria Geantă 		md_vid = (cha_vid & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
3591d239b10dSHoria Geantă 
3592bf83490eSVictoria Milhoan 		cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
3593d239b10dSHoria Geantă 		des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >>
3594d239b10dSHoria Geantă 			   CHA_ID_LS_DES_SHIFT;
3595d239b10dSHoria Geantă 		aes_inst = cha_inst & CHA_ID_LS_AES_MASK;
3596bf83490eSVictoria Milhoan 		md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
3597eaed71a4SIuliana Prodan 		arc4_inst = (cha_inst & CHA_ID_LS_ARC4_MASK) >>
3598eaed71a4SIuliana Prodan 			    CHA_ID_LS_ARC4_SHIFT;
3599d6bbd4eeSHoria Geantă 		ccha_inst = 0;
3600d6bbd4eeSHoria Geantă 		ptha_inst = 0;
3601df80bfd3SHoria Geantă 
3602df80bfd3SHoria Geantă 		aes_rn = rd_reg32(&priv->ctrl->perfmon.cha_rev_ls) &
3603df80bfd3SHoria Geantă 			 CHA_ID_LS_AES_MASK;
3604df80bfd3SHoria Geantă 		gcm_support = !(aes_vid == CHA_VER_VID_AES_LP && aes_rn < 8);
3605d239b10dSHoria Geantă 	} else {
3606d239b10dSHoria Geantă 		u32 aesa, mdha;
3607d239b10dSHoria Geantă 
3608d239b10dSHoria Geantă 		aesa = rd_reg32(&priv->ctrl->vreg.aesa);
3609d239b10dSHoria Geantă 		mdha = rd_reg32(&priv->ctrl->vreg.mdha);
3610d239b10dSHoria Geantă 
3611d239b10dSHoria Geantă 		aes_vid = (aesa & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
3612d239b10dSHoria Geantă 		md_vid = (mdha & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
3613d239b10dSHoria Geantă 
3614d239b10dSHoria Geantă 		des_inst = rd_reg32(&priv->ctrl->vreg.desa) & CHA_VER_NUM_MASK;
3615d239b10dSHoria Geantă 		aes_inst = aesa & CHA_VER_NUM_MASK;
3616d239b10dSHoria Geantă 		md_inst = mdha & CHA_VER_NUM_MASK;
3617d6bbd4eeSHoria Geantă 		ccha_inst = rd_reg32(&priv->ctrl->vreg.ccha) & CHA_VER_NUM_MASK;
3618d6bbd4eeSHoria Geantă 		ptha_inst = rd_reg32(&priv->ctrl->vreg.ptha) & CHA_VER_NUM_MASK;
3619eaed71a4SIuliana Prodan 		arc4_inst = rd_reg32(&priv->ctrl->vreg.afha) & CHA_VER_NUM_MASK;
3620df80bfd3SHoria Geantă 
3621df80bfd3SHoria Geantă 		gcm_support = aesa & CHA_VER_MISC_AES_GCM;
3622d239b10dSHoria Geantă 	}
36238e8ec596SKim Phillips 
3624bf83490eSVictoria Milhoan 	/* If MD is present, limit digest size based on LP256 */
3625d239b10dSHoria Geantă 	if (md_inst && md_vid  == CHA_VER_VID_MD_LP256)
3626bf83490eSVictoria Milhoan 		md_limit = SHA256_DIGEST_SIZE;
3627bf83490eSVictoria Milhoan 
3628bf83490eSVictoria Milhoan 	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
36295ca7badbSHoria Geantă 		struct caam_skcipher_alg *t_alg = driver_algs + i;
36305ca7badbSHoria Geantă 		u32 alg_sel = t_alg->caam.class1_alg_type & OP_ALG_ALGSEL_MASK;
3631bf83490eSVictoria Milhoan 
3632bf83490eSVictoria Milhoan 		/* Skip DES algorithms if not supported by device */
3633bf83490eSVictoria Milhoan 		if (!des_inst &&
3634bf83490eSVictoria Milhoan 		    ((alg_sel == OP_ALG_ALGSEL_3DES) ||
3635bf83490eSVictoria Milhoan 		     (alg_sel == OP_ALG_ALGSEL_DES)))
3636bf83490eSVictoria Milhoan 				continue;
3637bf83490eSVictoria Milhoan 
3638bf83490eSVictoria Milhoan 		/* Skip AES algorithms if not supported by device */
3639bf83490eSVictoria Milhoan 		if (!aes_inst && (alg_sel == OP_ALG_ALGSEL_AES))
3640bf83490eSVictoria Milhoan 				continue;
3641bf83490eSVictoria Milhoan 
3642eaed71a4SIuliana Prodan 		/* Skip ARC4 algorithms if not supported by device */
3643eaed71a4SIuliana Prodan 		if (!arc4_inst && alg_sel == OP_ALG_ALGSEL_ARC4)
3644eaed71a4SIuliana Prodan 			continue;
3645eaed71a4SIuliana Prodan 
364683d2c9a9SSven Ebenfeld 		/*
364783d2c9a9SSven Ebenfeld 		 * Check support for AES modes not available
364883d2c9a9SSven Ebenfeld 		 * on LP devices.
364983d2c9a9SSven Ebenfeld 		 */
3650d239b10dSHoria Geantă 		if (aes_vid == CHA_VER_VID_AES_LP &&
3651d239b10dSHoria Geantă 		    (t_alg->caam.class1_alg_type & OP_ALG_AAI_MASK) ==
365283d2c9a9SSven Ebenfeld 		    OP_ALG_AAI_XTS)
365383d2c9a9SSven Ebenfeld 			continue;
365483d2c9a9SSven Ebenfeld 
36555ca7badbSHoria Geantă 		caam_skcipher_alg_init(t_alg);
36568e8ec596SKim Phillips 
36575ca7badbSHoria Geantă 		err = crypto_register_skcipher(&t_alg->skcipher);
36588e8ec596SKim Phillips 		if (err) {
3659cfc6f11bSRuchika Gupta 			pr_warn("%s alg registration failed\n",
36605ca7badbSHoria Geantă 				t_alg->skcipher.base.cra_driver_name);
3661f2147b88SHerbert Xu 			continue;
36628e8ec596SKim Phillips 		}
3663f2147b88SHerbert Xu 
36645ca7badbSHoria Geantă 		t_alg->registered = true;
3665f2147b88SHerbert Xu 		registered = true;
3666f2147b88SHerbert Xu 	}
3667f2147b88SHerbert Xu 
3668f2147b88SHerbert Xu 	for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
3669f2147b88SHerbert Xu 		struct caam_aead_alg *t_alg = driver_aeads + i;
3670bf83490eSVictoria Milhoan 		u32 c1_alg_sel = t_alg->caam.class1_alg_type &
3671bf83490eSVictoria Milhoan 				 OP_ALG_ALGSEL_MASK;
3672bf83490eSVictoria Milhoan 		u32 c2_alg_sel = t_alg->caam.class2_alg_type &
3673bf83490eSVictoria Milhoan 				 OP_ALG_ALGSEL_MASK;
3674bf83490eSVictoria Milhoan 		u32 alg_aai = t_alg->caam.class1_alg_type & OP_ALG_AAI_MASK;
3675bf83490eSVictoria Milhoan 
3676bf83490eSVictoria Milhoan 		/* Skip DES algorithms if not supported by device */
3677bf83490eSVictoria Milhoan 		if (!des_inst &&
3678bf83490eSVictoria Milhoan 		    ((c1_alg_sel == OP_ALG_ALGSEL_3DES) ||
3679bf83490eSVictoria Milhoan 		     (c1_alg_sel == OP_ALG_ALGSEL_DES)))
3680bf83490eSVictoria Milhoan 				continue;
3681bf83490eSVictoria Milhoan 
3682bf83490eSVictoria Milhoan 		/* Skip AES algorithms if not supported by device */
3683bf83490eSVictoria Milhoan 		if (!aes_inst && (c1_alg_sel == OP_ALG_ALGSEL_AES))
3684bf83490eSVictoria Milhoan 				continue;
3685bf83490eSVictoria Milhoan 
3686d6bbd4eeSHoria Geantă 		/* Skip CHACHA20 algorithms if not supported by device */
3687d6bbd4eeSHoria Geantă 		if (c1_alg_sel == OP_ALG_ALGSEL_CHACHA20 && !ccha_inst)
3688d6bbd4eeSHoria Geantă 			continue;
3689d6bbd4eeSHoria Geantă 
3690d6bbd4eeSHoria Geantă 		/* Skip POLY1305 algorithms if not supported by device */
3691d6bbd4eeSHoria Geantă 		if (c2_alg_sel == OP_ALG_ALGSEL_POLY1305 && !ptha_inst)
3692d6bbd4eeSHoria Geantă 			continue;
3693d6bbd4eeSHoria Geantă 
3694df80bfd3SHoria Geantă 		/* Skip GCM algorithms if not supported by device */
3695df80bfd3SHoria Geantă 		if (c1_alg_sel == OP_ALG_ALGSEL_AES &&
3696df80bfd3SHoria Geantă 		    alg_aai == OP_ALG_AAI_GCM && !gcm_support)
3697bf83490eSVictoria Milhoan 			continue;
3698bf83490eSVictoria Milhoan 
3699bf83490eSVictoria Milhoan 		/*
3700bf83490eSVictoria Milhoan 		 * Skip algorithms requiring message digests
3701bf83490eSVictoria Milhoan 		 * if MD or MD size is not supported by device.
3702bf83490eSVictoria Milhoan 		 */
37032dd3fde4SHoria Geantă 		if (is_mdha(c2_alg_sel) &&
3704d6bbd4eeSHoria Geantă 		    (!md_inst || t_alg->aead.maxauthsize > md_limit))
3705bf83490eSVictoria Milhoan 			continue;
3706f2147b88SHerbert Xu 
3707f2147b88SHerbert Xu 		caam_aead_alg_init(t_alg);
3708f2147b88SHerbert Xu 
3709f2147b88SHerbert Xu 		err = crypto_register_aead(&t_alg->aead);
3710f2147b88SHerbert Xu 		if (err) {
3711f2147b88SHerbert Xu 			pr_warn("%s alg registration failed\n",
3712f2147b88SHerbert Xu 				t_alg->aead.base.cra_driver_name);
3713f2147b88SHerbert Xu 			continue;
3714f2147b88SHerbert Xu 		}
3715f2147b88SHerbert Xu 
3716f2147b88SHerbert Xu 		t_alg->registered = true;
3717f2147b88SHerbert Xu 		registered = true;
3718f2147b88SHerbert Xu 	}
3719f2147b88SHerbert Xu 
3720f2147b88SHerbert Xu 	if (registered)
3721cfc6f11bSRuchika Gupta 		pr_info("caam algorithms registered in /proc/crypto\n");
37228e8ec596SKim Phillips 
37238e8ec596SKim Phillips 	return err;
37248e8ec596SKim Phillips }
3725