xref: /openbmc/linux/drivers/crypto/caam/caamalg.c (revision eaed71a4)
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 
808e8ec596SKim Phillips #ifdef DEBUG
818e8ec596SKim Phillips /* for print_hex_dumps with line references */
828e8ec596SKim Phillips #define debug(format, arg...) printk(format, arg)
838e8ec596SKim Phillips #else
848e8ec596SKim Phillips #define debug(format, arg...)
858e8ec596SKim Phillips #endif
865ecf8ef9SCatalin Vasile 
87479bcc7cSHerbert Xu struct caam_alg_entry {
88479bcc7cSHerbert Xu 	int class1_alg_type;
89479bcc7cSHerbert Xu 	int class2_alg_type;
90479bcc7cSHerbert Xu 	bool rfc3686;
91479bcc7cSHerbert Xu 	bool geniv;
92479bcc7cSHerbert Xu };
93479bcc7cSHerbert Xu 
94479bcc7cSHerbert Xu struct caam_aead_alg {
95479bcc7cSHerbert Xu 	struct aead_alg aead;
96479bcc7cSHerbert Xu 	struct caam_alg_entry caam;
97479bcc7cSHerbert Xu 	bool registered;
98479bcc7cSHerbert Xu };
99479bcc7cSHerbert Xu 
1005ca7badbSHoria Geantă struct caam_skcipher_alg {
1015ca7badbSHoria Geantă 	struct skcipher_alg skcipher;
1025ca7badbSHoria Geantă 	struct caam_alg_entry caam;
1035ca7badbSHoria Geantă 	bool registered;
1045ca7badbSHoria Geantă };
1055ca7badbSHoria Geantă 
106acdca31dSYuan Kang /*
1078e8ec596SKim Phillips  * per-session context
1088e8ec596SKim Phillips  */
1098e8ec596SKim Phillips struct caam_ctx {
1101acebad3SYuan Kang 	u32 sh_desc_enc[DESC_MAX_USED_LEN];
1111acebad3SYuan Kang 	u32 sh_desc_dec[DESC_MAX_USED_LEN];
112bbf22344SHoria Geantă 	u8 key[CAAM_MAX_KEY_SIZE];
1131acebad3SYuan Kang 	dma_addr_t sh_desc_enc_dma;
1141acebad3SYuan Kang 	dma_addr_t sh_desc_dec_dma;
115885e9e2fSYuan Kang 	dma_addr_t key_dma;
1167e0880b9SHoria Geantă 	enum dma_data_direction dir;
117bbf22344SHoria Geantă 	struct device *jrdev;
118db57656bSHoria Geantă 	struct alginfo adata;
119db57656bSHoria Geantă 	struct alginfo cdata;
1208e8ec596SKim Phillips 	unsigned int authsize;
1218e8ec596SKim Phillips };
1228e8ec596SKim Phillips 
123ae4a825fSHoria Geanta static int aead_null_set_sh_desc(struct crypto_aead *aead)
124ae4a825fSHoria Geanta {
125ae4a825fSHoria Geanta 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
126ae4a825fSHoria Geanta 	struct device *jrdev = ctx->jrdev;
1277e0880b9SHoria Geantă 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
128ae4a825fSHoria Geanta 	u32 *desc;
1294cbe79ccSHoria Geantă 	int rem_bytes = CAAM_DESC_BYTES_MAX - AEAD_DESC_JOB_IO_LEN -
1304cbe79ccSHoria Geantă 			ctx->adata.keylen_pad;
131ae4a825fSHoria Geanta 
132ae4a825fSHoria Geanta 	/*
133ae4a825fSHoria Geanta 	 * Job Descriptor and Shared Descriptors
134ae4a825fSHoria Geanta 	 * must all fit into the 64-word Descriptor h/w Buffer
135ae4a825fSHoria Geanta 	 */
1364cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_AEAD_NULL_ENC_LEN) {
137db57656bSHoria Geantă 		ctx->adata.key_inline = true;
1389c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
139db57656bSHoria Geantă 	} else {
140db57656bSHoria Geantă 		ctx->adata.key_inline = false;
1419c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
142db57656bSHoria Geantă 	}
143ae4a825fSHoria Geanta 
144479bcc7cSHerbert Xu 	/* aead_encrypt shared descriptor */
145ae4a825fSHoria Geanta 	desc = ctx->sh_desc_enc;
1467e0880b9SHoria Geantă 	cnstr_shdsc_aead_null_encap(desc, &ctx->adata, ctx->authsize,
1477e0880b9SHoria Geantă 				    ctrlpriv->era);
148bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
1497e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
150ae4a825fSHoria Geanta 
151ae4a825fSHoria Geanta 	/*
152ae4a825fSHoria Geanta 	 * Job Descriptor and Shared Descriptors
153ae4a825fSHoria Geanta 	 * must all fit into the 64-word Descriptor h/w Buffer
154ae4a825fSHoria Geanta 	 */
1554cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_AEAD_NULL_DEC_LEN) {
156db57656bSHoria Geantă 		ctx->adata.key_inline = true;
1579c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
158db57656bSHoria Geantă 	} else {
159db57656bSHoria Geantă 		ctx->adata.key_inline = false;
1609c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
161db57656bSHoria Geantă 	}
162ae4a825fSHoria Geanta 
163479bcc7cSHerbert Xu 	/* aead_decrypt shared descriptor */
1648cea7b66SHoria Geantă 	desc = ctx->sh_desc_dec;
1657e0880b9SHoria Geantă 	cnstr_shdsc_aead_null_decap(desc, &ctx->adata, ctx->authsize,
1667e0880b9SHoria Geantă 				    ctrlpriv->era);
167bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
1687e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
169ae4a825fSHoria Geanta 
170ae4a825fSHoria Geanta 	return 0;
171ae4a825fSHoria Geanta }
172ae4a825fSHoria Geanta 
1731acebad3SYuan Kang static int aead_set_sh_desc(struct crypto_aead *aead)
1741acebad3SYuan Kang {
175479bcc7cSHerbert Xu 	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
176479bcc7cSHerbert Xu 						 struct caam_aead_alg, aead);
177add86d55SHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
1781acebad3SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1791acebad3SYuan Kang 	struct device *jrdev = ctx->jrdev;
1807e0880b9SHoria Geantă 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
181daebc465SCatalin Vasile 	u32 ctx1_iv_off = 0;
1828cea7b66SHoria Geantă 	u32 *desc, *nonce = NULL;
1834cbe79ccSHoria Geantă 	u32 inl_mask;
1844cbe79ccSHoria Geantă 	unsigned int data_len[2];
185db57656bSHoria Geantă 	const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
186daebc465SCatalin Vasile 			       OP_ALG_AAI_CTR_MOD128);
187479bcc7cSHerbert Xu 	const bool is_rfc3686 = alg->caam.rfc3686;
1881acebad3SYuan Kang 
1892fdea258SHoria Geantă 	if (!ctx->authsize)
1902fdea258SHoria Geantă 		return 0;
1912fdea258SHoria Geantă 
192ae4a825fSHoria Geanta 	/* NULL encryption / decryption */
193db57656bSHoria Geantă 	if (!ctx->cdata.keylen)
194ae4a825fSHoria Geanta 		return aead_null_set_sh_desc(aead);
195ae4a825fSHoria Geanta 
1961acebad3SYuan Kang 	/*
197daebc465SCatalin Vasile 	 * AES-CTR needs to load IV in CONTEXT1 reg
198daebc465SCatalin Vasile 	 * at an offset of 128bits (16bytes)
199daebc465SCatalin Vasile 	 * CONTEXT1[255:128] = IV
200daebc465SCatalin Vasile 	 */
201daebc465SCatalin Vasile 	if (ctr_mode)
202daebc465SCatalin Vasile 		ctx1_iv_off = 16;
203daebc465SCatalin Vasile 
204daebc465SCatalin Vasile 	/*
205daebc465SCatalin Vasile 	 * RFC3686 specific:
206daebc465SCatalin Vasile 	 *	CONTEXT1[255:128] = {NONCE, IV, COUNTER}
207daebc465SCatalin Vasile 	 */
2088cea7b66SHoria Geantă 	if (is_rfc3686) {
209daebc465SCatalin Vasile 		ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
2108cea7b66SHoria Geantă 		nonce = (u32 *)((void *)ctx->key + ctx->adata.keylen_pad +
2118cea7b66SHoria Geantă 				ctx->cdata.keylen - CTR_RFC3686_NONCE_SIZE);
2128cea7b66SHoria Geantă 	}
213daebc465SCatalin Vasile 
2144cbe79ccSHoria Geantă 	data_len[0] = ctx->adata.keylen_pad;
2154cbe79ccSHoria Geantă 	data_len[1] = ctx->cdata.keylen;
2164cbe79ccSHoria Geantă 
217479bcc7cSHerbert Xu 	if (alg->caam.geniv)
218479bcc7cSHerbert Xu 		goto skip_enc;
219479bcc7cSHerbert Xu 
220daebc465SCatalin Vasile 	/*
2211acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
2221acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
2231acebad3SYuan Kang 	 */
2244cbe79ccSHoria Geantă 	if (desc_inline_query(DESC_AEAD_ENC_LEN +
2254cbe79ccSHoria Geantă 			      (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
2264cbe79ccSHoria Geantă 			      AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
2274cbe79ccSHoria Geantă 			      ARRAY_SIZE(data_len)) < 0)
2284cbe79ccSHoria Geantă 		return -EINVAL;
2294cbe79ccSHoria Geantă 
2304cbe79ccSHoria Geantă 	if (inl_mask & 1)
2319c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
2324cbe79ccSHoria Geantă 	else
2339c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
2344cbe79ccSHoria Geantă 
2354cbe79ccSHoria Geantă 	if (inl_mask & 2)
2369c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
2374cbe79ccSHoria Geantă 	else
2389c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
2394cbe79ccSHoria Geantă 
2404cbe79ccSHoria Geantă 	ctx->adata.key_inline = !!(inl_mask & 1);
2414cbe79ccSHoria Geantă 	ctx->cdata.key_inline = !!(inl_mask & 2);
2421acebad3SYuan Kang 
243479bcc7cSHerbert Xu 	/* aead_encrypt shared descriptor */
2441acebad3SYuan Kang 	desc = ctx->sh_desc_enc;
245b189817cSHoria Geantă 	cnstr_shdsc_aead_encap(desc, &ctx->cdata, &ctx->adata, ivsize,
246b189817cSHoria Geantă 			       ctx->authsize, is_rfc3686, nonce, ctx1_iv_off,
2477e0880b9SHoria Geantă 			       false, ctrlpriv->era);
248bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
2497e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
2501acebad3SYuan Kang 
251479bcc7cSHerbert Xu skip_enc:
2521acebad3SYuan Kang 	/*
2531acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
2541acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
2551acebad3SYuan Kang 	 */
2564cbe79ccSHoria Geantă 	if (desc_inline_query(DESC_AEAD_DEC_LEN +
2574cbe79ccSHoria Geantă 			      (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
2584cbe79ccSHoria Geantă 			      AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
2594cbe79ccSHoria Geantă 			      ARRAY_SIZE(data_len)) < 0)
2604cbe79ccSHoria Geantă 		return -EINVAL;
2614cbe79ccSHoria Geantă 
2624cbe79ccSHoria Geantă 	if (inl_mask & 1)
2639c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
2644cbe79ccSHoria Geantă 	else
2659c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
2664cbe79ccSHoria Geantă 
2674cbe79ccSHoria Geantă 	if (inl_mask & 2)
2689c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
2694cbe79ccSHoria Geantă 	else
2709c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
2714cbe79ccSHoria Geantă 
2724cbe79ccSHoria Geantă 	ctx->adata.key_inline = !!(inl_mask & 1);
2734cbe79ccSHoria Geantă 	ctx->cdata.key_inline = !!(inl_mask & 2);
2741acebad3SYuan Kang 
275479bcc7cSHerbert Xu 	/* aead_decrypt shared descriptor */
2761acebad3SYuan Kang 	desc = ctx->sh_desc_dec;
2778cea7b66SHoria Geantă 	cnstr_shdsc_aead_decap(desc, &ctx->cdata, &ctx->adata, ivsize,
2788cea7b66SHoria Geantă 			       ctx->authsize, alg->caam.geniv, is_rfc3686,
2797e0880b9SHoria Geantă 			       nonce, ctx1_iv_off, false, ctrlpriv->era);
280bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
2817e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
2821acebad3SYuan Kang 
283479bcc7cSHerbert Xu 	if (!alg->caam.geniv)
284479bcc7cSHerbert Xu 		goto skip_givenc;
285479bcc7cSHerbert Xu 
2861acebad3SYuan Kang 	/*
2871acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
2881acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
2891acebad3SYuan Kang 	 */
2904cbe79ccSHoria Geantă 	if (desc_inline_query(DESC_AEAD_GIVENC_LEN +
2914cbe79ccSHoria Geantă 			      (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
2924cbe79ccSHoria Geantă 			      AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
2934cbe79ccSHoria Geantă 			      ARRAY_SIZE(data_len)) < 0)
2944cbe79ccSHoria Geantă 		return -EINVAL;
2954cbe79ccSHoria Geantă 
2964cbe79ccSHoria Geantă 	if (inl_mask & 1)
2979c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
2984cbe79ccSHoria Geantă 	else
2999c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
3004cbe79ccSHoria Geantă 
3014cbe79ccSHoria Geantă 	if (inl_mask & 2)
3029c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
3034cbe79ccSHoria Geantă 	else
3049c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
3054cbe79ccSHoria Geantă 
3064cbe79ccSHoria Geantă 	ctx->adata.key_inline = !!(inl_mask & 1);
3074cbe79ccSHoria Geantă 	ctx->cdata.key_inline = !!(inl_mask & 2);
3081acebad3SYuan Kang 
3091acebad3SYuan Kang 	/* aead_givencrypt shared descriptor */
3101d2d87e8SHoria Geantă 	desc = ctx->sh_desc_enc;
3118cea7b66SHoria Geantă 	cnstr_shdsc_aead_givencap(desc, &ctx->cdata, &ctx->adata, ivsize,
3128cea7b66SHoria Geantă 				  ctx->authsize, is_rfc3686, nonce,
3137e0880b9SHoria Geantă 				  ctx1_iv_off, false, ctrlpriv->era);
314bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
3157e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
3161acebad3SYuan Kang 
317479bcc7cSHerbert Xu skip_givenc:
3181acebad3SYuan Kang 	return 0;
3191acebad3SYuan Kang }
3201acebad3SYuan Kang 
3210e479300SYuan Kang static int aead_setauthsize(struct crypto_aead *authenc,
3228e8ec596SKim Phillips 				    unsigned int authsize)
3238e8ec596SKim Phillips {
3248e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
3258e8ec596SKim Phillips 
3268e8ec596SKim Phillips 	ctx->authsize = authsize;
3271acebad3SYuan Kang 	aead_set_sh_desc(authenc);
3288e8ec596SKim Phillips 
3298e8ec596SKim Phillips 	return 0;
3308e8ec596SKim Phillips }
3318e8ec596SKim Phillips 
3323ef8d945STudor Ambarus static int gcm_set_sh_desc(struct crypto_aead *aead)
3333ef8d945STudor Ambarus {
3343ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
3353ef8d945STudor Ambarus 	struct device *jrdev = ctx->jrdev;
33687ec3a0bSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
3373ef8d945STudor Ambarus 	u32 *desc;
3384cbe79ccSHoria Geantă 	int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
3394cbe79ccSHoria Geantă 			ctx->cdata.keylen;
3403ef8d945STudor Ambarus 
341db57656bSHoria Geantă 	if (!ctx->cdata.keylen || !ctx->authsize)
3423ef8d945STudor Ambarus 		return 0;
3433ef8d945STudor Ambarus 
3443ef8d945STudor Ambarus 	/*
3453ef8d945STudor Ambarus 	 * AES GCM encrypt shared descriptor
3463ef8d945STudor Ambarus 	 * Job Descriptor and Shared Descriptor
3473ef8d945STudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
3483ef8d945STudor Ambarus 	 */
3494cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_GCM_ENC_LEN) {
350db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
3519c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
352db57656bSHoria Geantă 	} else {
353db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
3549c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
355db57656bSHoria Geantă 	}
3563ef8d945STudor Ambarus 
3573ef8d945STudor Ambarus 	desc = ctx->sh_desc_enc;
35887ec3a0bSHoria Geantă 	cnstr_shdsc_gcm_encap(desc, &ctx->cdata, ivsize, ctx->authsize, false);
359bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
3607e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
3613ef8d945STudor Ambarus 
3623ef8d945STudor Ambarus 	/*
3633ef8d945STudor Ambarus 	 * Job Descriptor and Shared Descriptors
3643ef8d945STudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
3653ef8d945STudor Ambarus 	 */
3664cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_GCM_DEC_LEN) {
367db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
3689c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
369db57656bSHoria Geantă 	} else {
370db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
3719c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
372db57656bSHoria Geantă 	}
3733ef8d945STudor Ambarus 
3743ef8d945STudor Ambarus 	desc = ctx->sh_desc_dec;
37587ec3a0bSHoria Geantă 	cnstr_shdsc_gcm_decap(desc, &ctx->cdata, ivsize, ctx->authsize, false);
376bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
3777e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
3783ef8d945STudor Ambarus 
3793ef8d945STudor Ambarus 	return 0;
3803ef8d945STudor Ambarus }
3813ef8d945STudor Ambarus 
3823ef8d945STudor Ambarus static int gcm_setauthsize(struct crypto_aead *authenc, unsigned int authsize)
3833ef8d945STudor Ambarus {
3843ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
3853ef8d945STudor Ambarus 
3863ef8d945STudor Ambarus 	ctx->authsize = authsize;
3873ef8d945STudor Ambarus 	gcm_set_sh_desc(authenc);
3883ef8d945STudor Ambarus 
3893ef8d945STudor Ambarus 	return 0;
3903ef8d945STudor Ambarus }
3913ef8d945STudor Ambarus 
392bac68f2cSTudor Ambarus static int rfc4106_set_sh_desc(struct crypto_aead *aead)
393bac68f2cSTudor Ambarus {
394bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
395bac68f2cSTudor Ambarus 	struct device *jrdev = ctx->jrdev;
39687ec3a0bSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
397bac68f2cSTudor Ambarus 	u32 *desc;
3984cbe79ccSHoria Geantă 	int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
3994cbe79ccSHoria Geantă 			ctx->cdata.keylen;
400bac68f2cSTudor Ambarus 
401db57656bSHoria Geantă 	if (!ctx->cdata.keylen || !ctx->authsize)
402bac68f2cSTudor Ambarus 		return 0;
403bac68f2cSTudor Ambarus 
404bac68f2cSTudor Ambarus 	/*
405bac68f2cSTudor Ambarus 	 * RFC4106 encrypt shared descriptor
406bac68f2cSTudor Ambarus 	 * Job Descriptor and Shared Descriptor
407bac68f2cSTudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
408bac68f2cSTudor Ambarus 	 */
4094cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_RFC4106_ENC_LEN) {
410db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
4119c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
412db57656bSHoria Geantă 	} else {
413db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
4149c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
415db57656bSHoria Geantă 	}
416bac68f2cSTudor Ambarus 
417bac68f2cSTudor Ambarus 	desc = ctx->sh_desc_enc;
41887ec3a0bSHoria Geantă 	cnstr_shdsc_rfc4106_encap(desc, &ctx->cdata, ivsize, ctx->authsize,
41987ec3a0bSHoria Geantă 				  false);
420bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
4217e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
422bac68f2cSTudor Ambarus 
423bac68f2cSTudor Ambarus 	/*
424bac68f2cSTudor Ambarus 	 * Job Descriptor and Shared Descriptors
425bac68f2cSTudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
426bac68f2cSTudor Ambarus 	 */
4274cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_RFC4106_DEC_LEN) {
428db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
4299c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
430db57656bSHoria Geantă 	} else {
431db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
4329c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
433db57656bSHoria Geantă 	}
434bac68f2cSTudor Ambarus 
435bac68f2cSTudor Ambarus 	desc = ctx->sh_desc_dec;
43687ec3a0bSHoria Geantă 	cnstr_shdsc_rfc4106_decap(desc, &ctx->cdata, ivsize, ctx->authsize,
43787ec3a0bSHoria Geantă 				  false);
438bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
4397e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
440bac68f2cSTudor Ambarus 
441bac68f2cSTudor Ambarus 	return 0;
442bac68f2cSTudor Ambarus }
443bac68f2cSTudor Ambarus 
444bac68f2cSTudor Ambarus static int rfc4106_setauthsize(struct crypto_aead *authenc,
445bac68f2cSTudor Ambarus 			       unsigned int authsize)
446bac68f2cSTudor Ambarus {
447bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
448bac68f2cSTudor Ambarus 
449bac68f2cSTudor Ambarus 	ctx->authsize = authsize;
450bac68f2cSTudor Ambarus 	rfc4106_set_sh_desc(authenc);
451bac68f2cSTudor Ambarus 
452bac68f2cSTudor Ambarus 	return 0;
453bac68f2cSTudor Ambarus }
454bac68f2cSTudor Ambarus 
4555d0429a3STudor Ambarus static int rfc4543_set_sh_desc(struct crypto_aead *aead)
4565d0429a3STudor Ambarus {
4575d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
4585d0429a3STudor Ambarus 	struct device *jrdev = ctx->jrdev;
45987ec3a0bSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
4605d0429a3STudor Ambarus 	u32 *desc;
4614cbe79ccSHoria Geantă 	int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
4624cbe79ccSHoria Geantă 			ctx->cdata.keylen;
4635d0429a3STudor Ambarus 
464db57656bSHoria Geantă 	if (!ctx->cdata.keylen || !ctx->authsize)
4655d0429a3STudor Ambarus 		return 0;
4665d0429a3STudor Ambarus 
4675d0429a3STudor Ambarus 	/*
4685d0429a3STudor Ambarus 	 * RFC4543 encrypt shared descriptor
4695d0429a3STudor Ambarus 	 * Job Descriptor and Shared Descriptor
4705d0429a3STudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
4715d0429a3STudor Ambarus 	 */
4724cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_RFC4543_ENC_LEN) {
473db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
4749c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
475db57656bSHoria Geantă 	} else {
476db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
4779c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
478db57656bSHoria Geantă 	}
4795d0429a3STudor Ambarus 
4805d0429a3STudor Ambarus 	desc = ctx->sh_desc_enc;
48187ec3a0bSHoria Geantă 	cnstr_shdsc_rfc4543_encap(desc, &ctx->cdata, ivsize, ctx->authsize,
48287ec3a0bSHoria Geantă 				  false);
483bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
4847e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
4855d0429a3STudor Ambarus 
4865d0429a3STudor Ambarus 	/*
4875d0429a3STudor Ambarus 	 * Job Descriptor and Shared Descriptors
4885d0429a3STudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
4895d0429a3STudor Ambarus 	 */
4904cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_RFC4543_DEC_LEN) {
491db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
4929c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
493db57656bSHoria Geantă 	} else {
494db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
4959c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
496db57656bSHoria Geantă 	}
4975d0429a3STudor Ambarus 
4985d0429a3STudor Ambarus 	desc = ctx->sh_desc_dec;
49987ec3a0bSHoria Geantă 	cnstr_shdsc_rfc4543_decap(desc, &ctx->cdata, ivsize, ctx->authsize,
50087ec3a0bSHoria Geantă 				  false);
501bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
5027e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
5035d0429a3STudor Ambarus 
5045d0429a3STudor Ambarus 	return 0;
5055d0429a3STudor Ambarus }
5065d0429a3STudor Ambarus 
5075d0429a3STudor Ambarus static int rfc4543_setauthsize(struct crypto_aead *authenc,
5085d0429a3STudor Ambarus 			       unsigned int authsize)
5095d0429a3STudor Ambarus {
5105d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
5115d0429a3STudor Ambarus 
5125d0429a3STudor Ambarus 	ctx->authsize = authsize;
5135d0429a3STudor Ambarus 	rfc4543_set_sh_desc(authenc);
5145d0429a3STudor Ambarus 
5155d0429a3STudor Ambarus 	return 0;
5165d0429a3STudor Ambarus }
5175d0429a3STudor Ambarus 
518d6bbd4eeSHoria Geantă static int chachapoly_set_sh_desc(struct crypto_aead *aead)
519d6bbd4eeSHoria Geantă {
520d6bbd4eeSHoria Geantă 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
521d6bbd4eeSHoria Geantă 	struct device *jrdev = ctx->jrdev;
522d6bbd4eeSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
523d6bbd4eeSHoria Geantă 	u32 *desc;
524d6bbd4eeSHoria Geantă 
525d6bbd4eeSHoria Geantă 	if (!ctx->cdata.keylen || !ctx->authsize)
526d6bbd4eeSHoria Geantă 		return 0;
527d6bbd4eeSHoria Geantă 
528d6bbd4eeSHoria Geantă 	desc = ctx->sh_desc_enc;
529d6bbd4eeSHoria Geantă 	cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize,
530c10a5336SHoria Geantă 			       ctx->authsize, true, false);
531d6bbd4eeSHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
532d6bbd4eeSHoria Geantă 				   desc_bytes(desc), ctx->dir);
533d6bbd4eeSHoria Geantă 
534d6bbd4eeSHoria Geantă 	desc = ctx->sh_desc_dec;
535d6bbd4eeSHoria Geantă 	cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize,
536c10a5336SHoria Geantă 			       ctx->authsize, false, false);
537d6bbd4eeSHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
538d6bbd4eeSHoria Geantă 				   desc_bytes(desc), ctx->dir);
539d6bbd4eeSHoria Geantă 
540d6bbd4eeSHoria Geantă 	return 0;
541d6bbd4eeSHoria Geantă }
542d6bbd4eeSHoria Geantă 
543d6bbd4eeSHoria Geantă static int chachapoly_setauthsize(struct crypto_aead *aead,
544d6bbd4eeSHoria Geantă 				  unsigned int authsize)
545d6bbd4eeSHoria Geantă {
546d6bbd4eeSHoria Geantă 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
547d6bbd4eeSHoria Geantă 
548d6bbd4eeSHoria Geantă 	if (authsize != POLY1305_DIGEST_SIZE)
549d6bbd4eeSHoria Geantă 		return -EINVAL;
550d6bbd4eeSHoria Geantă 
551d6bbd4eeSHoria Geantă 	ctx->authsize = authsize;
552d6bbd4eeSHoria Geantă 	return chachapoly_set_sh_desc(aead);
553d6bbd4eeSHoria Geantă }
554d6bbd4eeSHoria Geantă 
555d6bbd4eeSHoria Geantă static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key,
556d6bbd4eeSHoria Geantă 			     unsigned int keylen)
557d6bbd4eeSHoria Geantă {
558d6bbd4eeSHoria Geantă 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
559d6bbd4eeSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
560d6bbd4eeSHoria Geantă 	unsigned int saltlen = CHACHAPOLY_IV_SIZE - ivsize;
561d6bbd4eeSHoria Geantă 
5621ca1b917SEric Biggers 	if (keylen != CHACHA_KEY_SIZE + saltlen) {
563d6bbd4eeSHoria Geantă 		crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
564d6bbd4eeSHoria Geantă 		return -EINVAL;
565d6bbd4eeSHoria Geantă 	}
566d6bbd4eeSHoria Geantă 
567d6bbd4eeSHoria Geantă 	ctx->cdata.key_virt = key;
568d6bbd4eeSHoria Geantă 	ctx->cdata.keylen = keylen - saltlen;
569d6bbd4eeSHoria Geantă 
570d6bbd4eeSHoria Geantă 	return chachapoly_set_sh_desc(aead);
571d6bbd4eeSHoria Geantă }
572d6bbd4eeSHoria Geantă 
5730e479300SYuan Kang static int aead_setkey(struct crypto_aead *aead,
5748e8ec596SKim Phillips 			       const u8 *key, unsigned int keylen)
5758e8ec596SKim Phillips {
5768e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
5778e8ec596SKim Phillips 	struct device *jrdev = ctx->jrdev;
5787e0880b9SHoria Geantă 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
5794e6e0b27SHoria Geanta 	struct crypto_authenc_keys keys;
5808e8ec596SKim Phillips 	int ret = 0;
5818e8ec596SKim Phillips 
5824e6e0b27SHoria Geanta 	if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
5838e8ec596SKim Phillips 		goto badkey;
5848e8ec596SKim Phillips 
5858e8ec596SKim Phillips #ifdef DEBUG
5868e8ec596SKim Phillips 	printk(KERN_ERR "keylen %d enckeylen %d authkeylen %d\n",
5874e6e0b27SHoria Geanta 	       keys.authkeylen + keys.enckeylen, keys.enckeylen,
5884e6e0b27SHoria Geanta 	       keys.authkeylen);
589514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
5908e8ec596SKim Phillips 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
5918e8ec596SKim Phillips #endif
5928e8ec596SKim Phillips 
5937e0880b9SHoria Geantă 	/*
5947e0880b9SHoria Geantă 	 * If DKP is supported, use it in the shared descriptor to generate
5957e0880b9SHoria Geantă 	 * the split key.
5967e0880b9SHoria Geantă 	 */
5977e0880b9SHoria Geantă 	if (ctrlpriv->era >= 6) {
5987e0880b9SHoria Geantă 		ctx->adata.keylen = keys.authkeylen;
5997e0880b9SHoria Geantă 		ctx->adata.keylen_pad = split_key_len(ctx->adata.algtype &
6007e0880b9SHoria Geantă 						      OP_ALG_ALGSEL_MASK);
6017e0880b9SHoria Geantă 
6027e0880b9SHoria Geantă 		if (ctx->adata.keylen_pad + keys.enckeylen > CAAM_MAX_KEY_SIZE)
6037e0880b9SHoria Geantă 			goto badkey;
6047e0880b9SHoria Geantă 
6057e0880b9SHoria Geantă 		memcpy(ctx->key, keys.authkey, keys.authkeylen);
6067e0880b9SHoria Geantă 		memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey,
6077e0880b9SHoria Geantă 		       keys.enckeylen);
6087e0880b9SHoria Geantă 		dma_sync_single_for_device(jrdev, ctx->key_dma,
6097e0880b9SHoria Geantă 					   ctx->adata.keylen_pad +
6107e0880b9SHoria Geantă 					   keys.enckeylen, ctx->dir);
6117e0880b9SHoria Geantă 		goto skip_split_key;
6127e0880b9SHoria Geantă 	}
6137e0880b9SHoria Geantă 
6146655cb8eSHoria Geantă 	ret = gen_split_key(ctx->jrdev, ctx->key, &ctx->adata, keys.authkey,
6156655cb8eSHoria Geantă 			    keys.authkeylen, CAAM_MAX_KEY_SIZE -
6166655cb8eSHoria Geantă 			    keys.enckeylen);
6178e8ec596SKim Phillips 	if (ret) {
6188e8ec596SKim Phillips 		goto badkey;
6198e8ec596SKim Phillips 	}
6208e8ec596SKim Phillips 
6218e8ec596SKim Phillips 	/* postpend encryption key to auth split key */
622db57656bSHoria Geantă 	memcpy(ctx->key + ctx->adata.keylen_pad, keys.enckey, keys.enckeylen);
623bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->adata.keylen_pad +
6247e0880b9SHoria Geantă 				   keys.enckeylen, ctx->dir);
6258e8ec596SKim Phillips #ifdef DEBUG
626514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ctx.key@"__stringify(__LINE__)": ",
6278e8ec596SKim Phillips 		       DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
628db57656bSHoria Geantă 		       ctx->adata.keylen_pad + keys.enckeylen, 1);
6298e8ec596SKim Phillips #endif
6307e0880b9SHoria Geantă 
6317e0880b9SHoria Geantă skip_split_key:
632db57656bSHoria Geantă 	ctx->cdata.keylen = keys.enckeylen;
63361dab972STudor-Dan Ambarus 	memzero_explicit(&keys, sizeof(keys));
634bbf22344SHoria Geantă 	return aead_set_sh_desc(aead);
6358e8ec596SKim Phillips badkey:
6368e8ec596SKim Phillips 	crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
63761dab972STudor-Dan Ambarus 	memzero_explicit(&keys, sizeof(keys));
6388e8ec596SKim Phillips 	return -EINVAL;
6398e8ec596SKim Phillips }
6408e8ec596SKim Phillips 
6413ef8d945STudor Ambarus static int gcm_setkey(struct crypto_aead *aead,
6423ef8d945STudor Ambarus 		      const u8 *key, unsigned int keylen)
6433ef8d945STudor Ambarus {
6443ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
6453ef8d945STudor Ambarus 	struct device *jrdev = ctx->jrdev;
6463ef8d945STudor Ambarus 
6473ef8d945STudor Ambarus #ifdef DEBUG
6483ef8d945STudor Ambarus 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
6493ef8d945STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
6503ef8d945STudor Ambarus #endif
6513ef8d945STudor Ambarus 
6523ef8d945STudor Ambarus 	memcpy(ctx->key, key, keylen);
6537e0880b9SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, ctx->dir);
654db57656bSHoria Geantă 	ctx->cdata.keylen = keylen;
6553ef8d945STudor Ambarus 
656bbf22344SHoria Geantă 	return gcm_set_sh_desc(aead);
6573ef8d945STudor Ambarus }
6583ef8d945STudor Ambarus 
659bac68f2cSTudor Ambarus static int rfc4106_setkey(struct crypto_aead *aead,
660bac68f2cSTudor Ambarus 			  const u8 *key, unsigned int keylen)
661bac68f2cSTudor Ambarus {
662bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
663bac68f2cSTudor Ambarus 	struct device *jrdev = ctx->jrdev;
664bac68f2cSTudor Ambarus 
665bac68f2cSTudor Ambarus 	if (keylen < 4)
666bac68f2cSTudor Ambarus 		return -EINVAL;
667bac68f2cSTudor Ambarus 
668bac68f2cSTudor Ambarus #ifdef DEBUG
669bac68f2cSTudor Ambarus 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
670bac68f2cSTudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
671bac68f2cSTudor Ambarus #endif
672bac68f2cSTudor Ambarus 
673bac68f2cSTudor Ambarus 	memcpy(ctx->key, key, keylen);
674bac68f2cSTudor Ambarus 
675bac68f2cSTudor Ambarus 	/*
676bac68f2cSTudor Ambarus 	 * The last four bytes of the key material are used as the salt value
677bac68f2cSTudor Ambarus 	 * in the nonce. Update the AES key length.
678bac68f2cSTudor Ambarus 	 */
679db57656bSHoria Geantă 	ctx->cdata.keylen = keylen - 4;
680bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
6817e0880b9SHoria Geantă 				   ctx->dir);
682bbf22344SHoria Geantă 	return rfc4106_set_sh_desc(aead);
683bac68f2cSTudor Ambarus }
684bac68f2cSTudor Ambarus 
6855d0429a3STudor Ambarus static int rfc4543_setkey(struct crypto_aead *aead,
6865d0429a3STudor Ambarus 			  const u8 *key, unsigned int keylen)
6875d0429a3STudor Ambarus {
6885d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
6895d0429a3STudor Ambarus 	struct device *jrdev = ctx->jrdev;
6905d0429a3STudor Ambarus 
6915d0429a3STudor Ambarus 	if (keylen < 4)
6925d0429a3STudor Ambarus 		return -EINVAL;
6935d0429a3STudor Ambarus 
6945d0429a3STudor Ambarus #ifdef DEBUG
6955d0429a3STudor Ambarus 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
6965d0429a3STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
6975d0429a3STudor Ambarus #endif
6985d0429a3STudor Ambarus 
6995d0429a3STudor Ambarus 	memcpy(ctx->key, key, keylen);
7005d0429a3STudor Ambarus 
7015d0429a3STudor Ambarus 	/*
7025d0429a3STudor Ambarus 	 * The last four bytes of the key material are used as the salt value
7035d0429a3STudor Ambarus 	 * in the nonce. Update the AES key length.
7045d0429a3STudor Ambarus 	 */
705db57656bSHoria Geantă 	ctx->cdata.keylen = keylen - 4;
706bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
7077e0880b9SHoria Geantă 				   ctx->dir);
708bbf22344SHoria Geantă 	return rfc4543_set_sh_desc(aead);
7095d0429a3STudor Ambarus }
7105d0429a3STudor Ambarus 
7115ca7badbSHoria Geantă static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
7125ca7badbSHoria Geantă 			   unsigned int keylen)
713acdca31dSYuan Kang {
7145ca7badbSHoria Geantă 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
7155ca7badbSHoria Geantă 	struct caam_skcipher_alg *alg =
7165ca7badbSHoria Geantă 		container_of(crypto_skcipher_alg(skcipher), typeof(*alg),
7175ca7badbSHoria Geantă 			     skcipher);
718acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
7195ca7badbSHoria Geantă 	unsigned int ivsize = crypto_skcipher_ivsize(skcipher);
720acdca31dSYuan Kang 	u32 *desc;
7212b22f6c5SCatalin Vasile 	u32 ctx1_iv_off = 0;
722db57656bSHoria Geantă 	const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
7232b22f6c5SCatalin Vasile 			       OP_ALG_AAI_CTR_MOD128);
7245ca7badbSHoria Geantă 	const bool is_rfc3686 = alg->caam.rfc3686;
725acdca31dSYuan Kang 
726acdca31dSYuan Kang #ifdef DEBUG
727514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
728acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
729acdca31dSYuan Kang #endif
7302b22f6c5SCatalin Vasile 	/*
7312b22f6c5SCatalin Vasile 	 * AES-CTR needs to load IV in CONTEXT1 reg
7322b22f6c5SCatalin Vasile 	 * at an offset of 128bits (16bytes)
7332b22f6c5SCatalin Vasile 	 * CONTEXT1[255:128] = IV
7342b22f6c5SCatalin Vasile 	 */
7352b22f6c5SCatalin Vasile 	if (ctr_mode)
7362b22f6c5SCatalin Vasile 		ctx1_iv_off = 16;
737acdca31dSYuan Kang 
738a5f57cffSCatalin Vasile 	/*
739a5f57cffSCatalin Vasile 	 * RFC3686 specific:
740a5f57cffSCatalin Vasile 	 *	| CONTEXT1[255:128] = {NONCE, IV, COUNTER}
741a5f57cffSCatalin Vasile 	 *	| *key = {KEY, NONCE}
742a5f57cffSCatalin Vasile 	 */
743a5f57cffSCatalin Vasile 	if (is_rfc3686) {
744a5f57cffSCatalin Vasile 		ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
745a5f57cffSCatalin Vasile 		keylen -= CTR_RFC3686_NONCE_SIZE;
746a5f57cffSCatalin Vasile 	}
747a5f57cffSCatalin Vasile 
748db57656bSHoria Geantă 	ctx->cdata.keylen = keylen;
749662f70edSHoria Geantă 	ctx->cdata.key_virt = key;
750db57656bSHoria Geantă 	ctx->cdata.key_inline = true;
751acdca31dSYuan Kang 
7525ca7badbSHoria Geantă 	/* skcipher_encrypt shared descriptor */
753acdca31dSYuan Kang 	desc = ctx->sh_desc_enc;
7549dbe3072SHoria Geantă 	cnstr_shdsc_skcipher_encap(desc, &ctx->cdata, ivsize, is_rfc3686,
7558cea7b66SHoria Geantă 				   ctx1_iv_off);
756bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
7577e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
7588cea7b66SHoria Geantă 
7595ca7badbSHoria Geantă 	/* skcipher_decrypt shared descriptor */
760acdca31dSYuan Kang 	desc = ctx->sh_desc_dec;
7619dbe3072SHoria Geantă 	cnstr_shdsc_skcipher_decap(desc, &ctx->cdata, ivsize, is_rfc3686,
7628cea7b66SHoria Geantă 				   ctx1_iv_off);
763bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
7647e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
765acdca31dSYuan Kang 
7668cea7b66SHoria Geantă 	return 0;
767acdca31dSYuan Kang }
768acdca31dSYuan Kang 
769eaed71a4SIuliana Prodan static int des_skcipher_setkey(struct crypto_skcipher *skcipher,
770eaed71a4SIuliana Prodan 			       const u8 *key, unsigned int keylen)
771eaed71a4SIuliana Prodan {
772eaed71a4SIuliana Prodan 	u32 tmp[DES3_EDE_EXPKEY_WORDS];
773eaed71a4SIuliana Prodan 	struct crypto_tfm *tfm = crypto_skcipher_tfm(skcipher);
774eaed71a4SIuliana Prodan 
775eaed71a4SIuliana Prodan 	if (keylen == DES3_EDE_KEY_SIZE &&
776eaed71a4SIuliana Prodan 	    __des3_ede_setkey(tmp, &tfm->crt_flags, key, DES3_EDE_KEY_SIZE)) {
777eaed71a4SIuliana Prodan 		return -EINVAL;
778eaed71a4SIuliana Prodan 	}
779eaed71a4SIuliana Prodan 
780eaed71a4SIuliana Prodan 	if (!des_ekey(tmp, key) && (crypto_skcipher_get_flags(skcipher) &
781eaed71a4SIuliana Prodan 	    CRYPTO_TFM_REQ_FORBID_WEAK_KEYS)) {
782eaed71a4SIuliana Prodan 		crypto_skcipher_set_flags(skcipher,
783eaed71a4SIuliana Prodan 					  CRYPTO_TFM_RES_WEAK_KEY);
784eaed71a4SIuliana Prodan 		return -EINVAL;
785eaed71a4SIuliana Prodan 	}
786eaed71a4SIuliana Prodan 
787eaed71a4SIuliana Prodan 	return skcipher_setkey(skcipher, key, keylen);
788eaed71a4SIuliana Prodan }
789eaed71a4SIuliana Prodan 
7905ca7badbSHoria Geantă static int xts_skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
7915ca7badbSHoria Geantă 			       unsigned int keylen)
792c6415a60SCatalin Vasile {
7935ca7badbSHoria Geantă 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
794c6415a60SCatalin Vasile 	struct device *jrdev = ctx->jrdev;
7958cea7b66SHoria Geantă 	u32 *desc;
796c6415a60SCatalin Vasile 
797c6415a60SCatalin Vasile 	if (keylen != 2 * AES_MIN_KEY_SIZE  && keylen != 2 * AES_MAX_KEY_SIZE) {
7985ca7badbSHoria Geantă 		crypto_skcipher_set_flags(skcipher, CRYPTO_TFM_RES_BAD_KEY_LEN);
799c6415a60SCatalin Vasile 		dev_err(jrdev, "key size mismatch\n");
800c6415a60SCatalin Vasile 		return -EINVAL;
801c6415a60SCatalin Vasile 	}
802c6415a60SCatalin Vasile 
803db57656bSHoria Geantă 	ctx->cdata.keylen = keylen;
804662f70edSHoria Geantă 	ctx->cdata.key_virt = key;
805db57656bSHoria Geantă 	ctx->cdata.key_inline = true;
806c6415a60SCatalin Vasile 
8075ca7badbSHoria Geantă 	/* xts_skcipher_encrypt shared descriptor */
808c6415a60SCatalin Vasile 	desc = ctx->sh_desc_enc;
8099dbe3072SHoria Geantă 	cnstr_shdsc_xts_skcipher_encap(desc, &ctx->cdata);
810bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
8117e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
812c6415a60SCatalin Vasile 
8135ca7badbSHoria Geantă 	/* xts_skcipher_decrypt shared descriptor */
814c6415a60SCatalin Vasile 	desc = ctx->sh_desc_dec;
8159dbe3072SHoria Geantă 	cnstr_shdsc_xts_skcipher_decap(desc, &ctx->cdata);
816bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
8177e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
818c6415a60SCatalin Vasile 
819c6415a60SCatalin Vasile 	return 0;
820c6415a60SCatalin Vasile }
821c6415a60SCatalin Vasile 
8228e8ec596SKim Phillips /*
8231acebad3SYuan Kang  * aead_edesc - s/w-extended aead descriptor
824fa0c92dbSHoria Geantă  * @src_nents: number of segments in input s/w scatterlist
825fa0c92dbSHoria Geantă  * @dst_nents: number of segments in output s/w scatterlist
826ba4cf71bSIuliana Prodan  * @mapped_src_nents: number of segments in input h/w link table
827ba4cf71bSIuliana Prodan  * @mapped_dst_nents: number of segments in output h/w link table
828a299c837SYuan Kang  * @sec4_sg_bytes: length of dma mapped sec4_sg space
829a299c837SYuan Kang  * @sec4_sg_dma: bus physical mapped address of h/w link table
8304ca7c7d8SHoria Geantă  * @sec4_sg: pointer to h/w link table
8318e8ec596SKim Phillips  * @hw_desc: the h/w job descriptor followed by any referenced link tables
8328e8ec596SKim Phillips  */
8330e479300SYuan Kang struct aead_edesc {
8348e8ec596SKim Phillips 	int src_nents;
8358e8ec596SKim Phillips 	int dst_nents;
836ba4cf71bSIuliana Prodan 	int mapped_src_nents;
837ba4cf71bSIuliana Prodan 	int mapped_dst_nents;
838a299c837SYuan Kang 	int sec4_sg_bytes;
839a299c837SYuan Kang 	dma_addr_t sec4_sg_dma;
840a299c837SYuan Kang 	struct sec4_sg_entry *sec4_sg;
841f2147b88SHerbert Xu 	u32 hw_desc[];
8428e8ec596SKim Phillips };
8438e8ec596SKim Phillips 
844acdca31dSYuan Kang /*
8455ca7badbSHoria Geantă  * skcipher_edesc - s/w-extended skcipher descriptor
846fa0c92dbSHoria Geantă  * @src_nents: number of segments in input s/w scatterlist
847fa0c92dbSHoria Geantă  * @dst_nents: number of segments in output s/w scatterlist
848ba4cf71bSIuliana Prodan  * @mapped_src_nents: number of segments in input h/w link table
849ba4cf71bSIuliana Prodan  * @mapped_dst_nents: number of segments in output h/w link table
850acdca31dSYuan Kang  * @iv_dma: dma address of iv for checking continuity and link table
851a299c837SYuan Kang  * @sec4_sg_bytes: length of dma mapped sec4_sg space
852a299c837SYuan Kang  * @sec4_sg_dma: bus physical mapped address of h/w link table
8534ca7c7d8SHoria Geantă  * @sec4_sg: pointer to h/w link table
854acdca31dSYuan Kang  * @hw_desc: the h/w job descriptor followed by any referenced link tables
855115957bbSHoria Geantă  *	     and IV
856acdca31dSYuan Kang  */
8575ca7badbSHoria Geantă struct skcipher_edesc {
858acdca31dSYuan Kang 	int src_nents;
859acdca31dSYuan Kang 	int dst_nents;
860ba4cf71bSIuliana Prodan 	int mapped_src_nents;
861ba4cf71bSIuliana Prodan 	int mapped_dst_nents;
862acdca31dSYuan Kang 	dma_addr_t iv_dma;
863a299c837SYuan Kang 	int sec4_sg_bytes;
864a299c837SYuan Kang 	dma_addr_t sec4_sg_dma;
865a299c837SYuan Kang 	struct sec4_sg_entry *sec4_sg;
866acdca31dSYuan Kang 	u32 hw_desc[0];
867acdca31dSYuan Kang };
868acdca31dSYuan Kang 
8691acebad3SYuan Kang static void caam_unmap(struct device *dev, struct scatterlist *src,
870643b39b0SYuan Kang 		       struct scatterlist *dst, int src_nents,
87113fb8fd7SLABBE Corentin 		       int dst_nents,
872cf5448b5SHoria Geantă 		       dma_addr_t iv_dma, int ivsize, dma_addr_t sec4_sg_dma,
873a299c837SYuan Kang 		       int sec4_sg_bytes)
8741acebad3SYuan Kang {
875643b39b0SYuan Kang 	if (dst != src) {
876fa0c92dbSHoria Geantă 		if (src_nents)
877fa0c92dbSHoria Geantă 			dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
878763069baSHoria Geantă 		if (dst_nents)
879fa0c92dbSHoria Geantă 			dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
8801acebad3SYuan Kang 	} else {
881fa0c92dbSHoria Geantă 		dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
8821acebad3SYuan Kang 	}
8831acebad3SYuan Kang 
8841acebad3SYuan Kang 	if (iv_dma)
885cf5448b5SHoria Geantă 		dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);
886a299c837SYuan Kang 	if (sec4_sg_bytes)
887a299c837SYuan Kang 		dma_unmap_single(dev, sec4_sg_dma, sec4_sg_bytes,
8881acebad3SYuan Kang 				 DMA_TO_DEVICE);
8891acebad3SYuan Kang }
8901acebad3SYuan Kang 
8910e479300SYuan Kang static void aead_unmap(struct device *dev,
8920e479300SYuan Kang 		       struct aead_edesc *edesc,
8930e479300SYuan Kang 		       struct aead_request *req)
8948e8ec596SKim Phillips {
895f2147b88SHerbert Xu 	caam_unmap(dev, req->src, req->dst,
896cf5448b5SHoria Geantă 		   edesc->src_nents, edesc->dst_nents, 0, 0,
897f2147b88SHerbert Xu 		   edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
898f2147b88SHerbert Xu }
899f2147b88SHerbert Xu 
9005ca7badbSHoria Geantă static void skcipher_unmap(struct device *dev, struct skcipher_edesc *edesc,
9015ca7badbSHoria Geantă 			   struct skcipher_request *req)
902acdca31dSYuan Kang {
9035ca7badbSHoria Geantă 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
9045ca7badbSHoria Geantă 	int ivsize = crypto_skcipher_ivsize(skcipher);
905acdca31dSYuan Kang 
906acdca31dSYuan Kang 	caam_unmap(dev, req->src, req->dst,
90713fb8fd7SLABBE Corentin 		   edesc->src_nents, edesc->dst_nents,
908cf5448b5SHoria Geantă 		   edesc->iv_dma, ivsize,
909643b39b0SYuan Kang 		   edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
910acdca31dSYuan Kang }
911acdca31dSYuan Kang 
9120e479300SYuan Kang static void aead_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
9138e8ec596SKim Phillips 				   void *context)
9148e8ec596SKim Phillips {
9150e479300SYuan Kang 	struct aead_request *req = context;
9160e479300SYuan Kang 	struct aead_edesc *edesc;
917f2147b88SHerbert Xu 
918f2147b88SHerbert Xu #ifdef DEBUG
919f2147b88SHerbert Xu 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
920f2147b88SHerbert Xu #endif
921f2147b88SHerbert Xu 
922f2147b88SHerbert Xu 	edesc = container_of(desc, struct aead_edesc, hw_desc[0]);
923f2147b88SHerbert Xu 
924f2147b88SHerbert Xu 	if (err)
925f2147b88SHerbert Xu 		caam_jr_strstatus(jrdev, err);
926f2147b88SHerbert Xu 
927f2147b88SHerbert Xu 	aead_unmap(jrdev, edesc, req);
928f2147b88SHerbert Xu 
929f2147b88SHerbert Xu 	kfree(edesc);
930f2147b88SHerbert Xu 
931f2147b88SHerbert Xu 	aead_request_complete(req, err);
932f2147b88SHerbert Xu }
933f2147b88SHerbert Xu 
9340e479300SYuan Kang static void aead_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
9358e8ec596SKim Phillips 				   void *context)
9368e8ec596SKim Phillips {
9370e479300SYuan Kang 	struct aead_request *req = context;
9380e479300SYuan Kang 	struct aead_edesc *edesc;
939f2147b88SHerbert Xu 
940f2147b88SHerbert Xu #ifdef DEBUG
941f2147b88SHerbert Xu 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
942f2147b88SHerbert Xu #endif
943f2147b88SHerbert Xu 
944f2147b88SHerbert Xu 	edesc = container_of(desc, struct aead_edesc, hw_desc[0]);
945f2147b88SHerbert Xu 
946f2147b88SHerbert Xu 	if (err)
947f2147b88SHerbert Xu 		caam_jr_strstatus(jrdev, err);
948f2147b88SHerbert Xu 
949f2147b88SHerbert Xu 	aead_unmap(jrdev, edesc, req);
950f2147b88SHerbert Xu 
951f2147b88SHerbert Xu 	/*
952f2147b88SHerbert Xu 	 * verify hw auth check passed else return -EBADMSG
953f2147b88SHerbert Xu 	 */
954f2147b88SHerbert Xu 	if ((err & JRSTA_CCBERR_ERRID_MASK) == JRSTA_CCBERR_ERRID_ICVCHK)
955f2147b88SHerbert Xu 		err = -EBADMSG;
956f2147b88SHerbert Xu 
957f2147b88SHerbert Xu 	kfree(edesc);
958f2147b88SHerbert Xu 
959f2147b88SHerbert Xu 	aead_request_complete(req, err);
960f2147b88SHerbert Xu }
961f2147b88SHerbert Xu 
9625ca7badbSHoria Geantă static void skcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
963acdca31dSYuan Kang 				  void *context)
964acdca31dSYuan Kang {
9655ca7badbSHoria Geantă 	struct skcipher_request *req = context;
9665ca7badbSHoria Geantă 	struct skcipher_edesc *edesc;
9675ca7badbSHoria Geantă 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
9685ca7badbSHoria Geantă 	int ivsize = crypto_skcipher_ivsize(skcipher);
969acdca31dSYuan Kang 
970854b06f7SDavid Gstir #ifdef DEBUG
971acdca31dSYuan Kang 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
972acdca31dSYuan Kang #endif
973acdca31dSYuan Kang 
9745ca7badbSHoria Geantă 	edesc = container_of(desc, struct skcipher_edesc, hw_desc[0]);
975acdca31dSYuan Kang 
976fa9659cdSMarek Vasut 	if (err)
977fa9659cdSMarek Vasut 		caam_jr_strstatus(jrdev, err);
978acdca31dSYuan Kang 
979acdca31dSYuan Kang #ifdef DEBUG
980514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dstiv  @"__stringify(__LINE__)": ",
9815ca7badbSHoria Geantă 		       DUMP_PREFIX_ADDRESS, 16, 4, req->iv,
982acdca31dSYuan Kang 		       edesc->src_nents > 1 ? 100 : ivsize, 1);
983972b812bSHoria Geantă #endif
984972b812bSHoria Geantă 	caam_dump_sg(KERN_ERR, "dst    @" __stringify(__LINE__)": ",
9855ecf8ef9SCatalin Vasile 		     DUMP_PREFIX_ADDRESS, 16, 4, req->dst,
9865ca7badbSHoria Geantă 		     edesc->dst_nents > 1 ? 100 : req->cryptlen, 1);
987acdca31dSYuan Kang 
9885ca7badbSHoria Geantă 	skcipher_unmap(jrdev, edesc, req);
989854b06f7SDavid Gstir 
990854b06f7SDavid Gstir 	/*
9915ca7badbSHoria Geantă 	 * The crypto API expects us to set the IV (req->iv) to the last
992854b06f7SDavid Gstir 	 * ciphertext block. This is used e.g. by the CTS mode.
993854b06f7SDavid Gstir 	 */
994eaed71a4SIuliana Prodan 	if (ivsize)
995eaed71a4SIuliana Prodan 		scatterwalk_map_and_copy(req->iv, req->dst, req->cryptlen -
996eaed71a4SIuliana Prodan 					 ivsize, ivsize, 0);
997854b06f7SDavid Gstir 
998acdca31dSYuan Kang 	kfree(edesc);
999acdca31dSYuan Kang 
10005ca7badbSHoria Geantă 	skcipher_request_complete(req, err);
1001acdca31dSYuan Kang }
1002acdca31dSYuan Kang 
10035ca7badbSHoria Geantă static void skcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
1004acdca31dSYuan Kang 				  void *context)
1005acdca31dSYuan Kang {
10065ca7badbSHoria Geantă 	struct skcipher_request *req = context;
10075ca7badbSHoria Geantă 	struct skcipher_edesc *edesc;
1008115957bbSHoria Geantă #ifdef DEBUG
10095ca7badbSHoria Geantă 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
10105ca7badbSHoria Geantă 	int ivsize = crypto_skcipher_ivsize(skcipher);
1011acdca31dSYuan Kang 
1012acdca31dSYuan Kang 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
1013acdca31dSYuan Kang #endif
1014acdca31dSYuan Kang 
10155ca7badbSHoria Geantă 	edesc = container_of(desc, struct skcipher_edesc, hw_desc[0]);
1016fa9659cdSMarek Vasut 	if (err)
1017fa9659cdSMarek Vasut 		caam_jr_strstatus(jrdev, err);
1018acdca31dSYuan Kang 
1019acdca31dSYuan Kang #ifdef DEBUG
1020514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dstiv  @"__stringify(__LINE__)": ",
10215ca7badbSHoria Geantă 		       DUMP_PREFIX_ADDRESS, 16, 4, req->iv, ivsize, 1);
1022972b812bSHoria Geantă #endif
1023972b812bSHoria Geantă 	caam_dump_sg(KERN_ERR, "dst    @" __stringify(__LINE__)": ",
10245ecf8ef9SCatalin Vasile 		     DUMP_PREFIX_ADDRESS, 16, 4, req->dst,
10255ca7badbSHoria Geantă 		     edesc->dst_nents > 1 ? 100 : req->cryptlen, 1);
1026acdca31dSYuan Kang 
10275ca7badbSHoria Geantă 	skcipher_unmap(jrdev, edesc, req);
1028acdca31dSYuan Kang 	kfree(edesc);
1029acdca31dSYuan Kang 
10305ca7badbSHoria Geantă 	skcipher_request_complete(req, err);
1031acdca31dSYuan Kang }
1032acdca31dSYuan Kang 
10338e8ec596SKim Phillips /*
10341acebad3SYuan Kang  * Fill in aead job descriptor
10358e8ec596SKim Phillips  */
1036f2147b88SHerbert Xu static void init_aead_job(struct aead_request *req,
1037f2147b88SHerbert Xu 			  struct aead_edesc *edesc,
1038f2147b88SHerbert Xu 			  bool all_contig, bool encrypt)
1039f2147b88SHerbert Xu {
1040f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1041f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1042f2147b88SHerbert Xu 	int authsize = ctx->authsize;
1043f2147b88SHerbert Xu 	u32 *desc = edesc->hw_desc;
1044f2147b88SHerbert Xu 	u32 out_options, in_options;
1045f2147b88SHerbert Xu 	dma_addr_t dst_dma, src_dma;
1046f2147b88SHerbert Xu 	int len, sec4_sg_index = 0;
1047f2147b88SHerbert Xu 	dma_addr_t ptr;
1048f2147b88SHerbert Xu 	u32 *sh_desc;
1049f2147b88SHerbert Xu 
1050f2147b88SHerbert Xu 	sh_desc = encrypt ? ctx->sh_desc_enc : ctx->sh_desc_dec;
1051f2147b88SHerbert Xu 	ptr = encrypt ? ctx->sh_desc_enc_dma : ctx->sh_desc_dec_dma;
1052f2147b88SHerbert Xu 
1053f2147b88SHerbert Xu 	len = desc_len(sh_desc);
1054f2147b88SHerbert Xu 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
1055f2147b88SHerbert Xu 
1056f2147b88SHerbert Xu 	if (all_contig) {
1057ba4cf71bSIuliana Prodan 		src_dma = edesc->mapped_src_nents ? sg_dma_address(req->src) :
1058ba4cf71bSIuliana Prodan 						    0;
1059f2147b88SHerbert Xu 		in_options = 0;
1060f2147b88SHerbert Xu 	} else {
1061f2147b88SHerbert Xu 		src_dma = edesc->sec4_sg_dma;
1062ba4cf71bSIuliana Prodan 		sec4_sg_index += edesc->mapped_src_nents;
1063f2147b88SHerbert Xu 		in_options = LDST_SGF;
1064f2147b88SHerbert Xu 	}
1065f2147b88SHerbert Xu 
1066f2147b88SHerbert Xu 	append_seq_in_ptr(desc, src_dma, req->assoclen + req->cryptlen,
1067f2147b88SHerbert Xu 			  in_options);
1068f2147b88SHerbert Xu 
1069f2147b88SHerbert Xu 	dst_dma = src_dma;
1070f2147b88SHerbert Xu 	out_options = in_options;
1071f2147b88SHerbert Xu 
1072f2147b88SHerbert Xu 	if (unlikely(req->src != req->dst)) {
1073ba4cf71bSIuliana Prodan 		if (!edesc->mapped_dst_nents) {
1074763069baSHoria Geantă 			dst_dma = 0;
1075ba4cf71bSIuliana Prodan 		} else if (edesc->mapped_dst_nents == 1) {
1076f2147b88SHerbert Xu 			dst_dma = sg_dma_address(req->dst);
107742e95d1fSPankaj Gupta 			out_options = 0;
1078f2147b88SHerbert Xu 		} else {
1079f2147b88SHerbert Xu 			dst_dma = edesc->sec4_sg_dma +
1080f2147b88SHerbert Xu 				  sec4_sg_index *
1081f2147b88SHerbert Xu 				  sizeof(struct sec4_sg_entry);
1082f2147b88SHerbert Xu 			out_options = LDST_SGF;
1083f2147b88SHerbert Xu 		}
1084f2147b88SHerbert Xu 	}
1085f2147b88SHerbert Xu 
1086f2147b88SHerbert Xu 	if (encrypt)
1087f2147b88SHerbert Xu 		append_seq_out_ptr(desc, dst_dma,
1088f2147b88SHerbert Xu 				   req->assoclen + req->cryptlen + authsize,
1089f2147b88SHerbert Xu 				   out_options);
1090f2147b88SHerbert Xu 	else
1091f2147b88SHerbert Xu 		append_seq_out_ptr(desc, dst_dma,
1092f2147b88SHerbert Xu 				   req->assoclen + req->cryptlen - authsize,
1093f2147b88SHerbert Xu 				   out_options);
1094f2147b88SHerbert Xu }
1095f2147b88SHerbert Xu 
1096f2147b88SHerbert Xu static void init_gcm_job(struct aead_request *req,
1097f2147b88SHerbert Xu 			 struct aead_edesc *edesc,
1098f2147b88SHerbert Xu 			 bool all_contig, bool encrypt)
1099f2147b88SHerbert Xu {
1100f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1101f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1102f2147b88SHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
1103f2147b88SHerbert Xu 	u32 *desc = edesc->hw_desc;
11047545e166SCorentin LABBE 	bool generic_gcm = (ivsize == GCM_AES_IV_SIZE);
1105f2147b88SHerbert Xu 	unsigned int last;
1106f2147b88SHerbert Xu 
1107f2147b88SHerbert Xu 	init_aead_job(req, edesc, all_contig, encrypt);
11087e0880b9SHoria Geantă 	append_math_add_imm_u32(desc, REG3, ZERO, IMM, req->assoclen);
1109f2147b88SHerbert Xu 
1110f2147b88SHerbert Xu 	/* BUG This should not be specific to generic GCM. */
1111f2147b88SHerbert Xu 	last = 0;
1112f2147b88SHerbert Xu 	if (encrypt && generic_gcm && !(req->assoclen + req->cryptlen))
1113f2147b88SHerbert Xu 		last = FIFOLD_TYPE_LAST1;
1114f2147b88SHerbert Xu 
1115f2147b88SHerbert Xu 	/* Read GCM IV */
1116f2147b88SHerbert Xu 	append_cmd(desc, CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 | IMMEDIATE |
11177545e166SCorentin LABBE 			 FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 | GCM_AES_IV_SIZE | last);
1118f2147b88SHerbert Xu 	/* Append Salt */
1119f2147b88SHerbert Xu 	if (!generic_gcm)
1120db57656bSHoria Geantă 		append_data(desc, ctx->key + ctx->cdata.keylen, 4);
1121f2147b88SHerbert Xu 	/* Append IV */
1122f2147b88SHerbert Xu 	append_data(desc, req->iv, ivsize);
1123f2147b88SHerbert Xu 	/* End of blank commands */
1124f2147b88SHerbert Xu }
1125f2147b88SHerbert Xu 
1126d6bbd4eeSHoria Geantă static void init_chachapoly_job(struct aead_request *req,
1127d6bbd4eeSHoria Geantă 				struct aead_edesc *edesc, bool all_contig,
1128d6bbd4eeSHoria Geantă 				bool encrypt)
1129d6bbd4eeSHoria Geantă {
1130d6bbd4eeSHoria Geantă 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1131d6bbd4eeSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
1132d6bbd4eeSHoria Geantă 	unsigned int assoclen = req->assoclen;
1133d6bbd4eeSHoria Geantă 	u32 *desc = edesc->hw_desc;
1134d6bbd4eeSHoria Geantă 	u32 ctx_iv_off = 4;
1135d6bbd4eeSHoria Geantă 
1136d6bbd4eeSHoria Geantă 	init_aead_job(req, edesc, all_contig, encrypt);
1137d6bbd4eeSHoria Geantă 
1138d6bbd4eeSHoria Geantă 	if (ivsize != CHACHAPOLY_IV_SIZE) {
1139d6bbd4eeSHoria Geantă 		/* IPsec specific: CONTEXT1[223:128] = {NONCE, IV} */
1140d6bbd4eeSHoria Geantă 		ctx_iv_off += 4;
1141d6bbd4eeSHoria Geantă 
1142d6bbd4eeSHoria Geantă 		/*
1143d6bbd4eeSHoria Geantă 		 * The associated data comes already with the IV but we need
1144d6bbd4eeSHoria Geantă 		 * to skip it when we authenticate or encrypt...
1145d6bbd4eeSHoria Geantă 		 */
1146d6bbd4eeSHoria Geantă 		assoclen -= ivsize;
1147d6bbd4eeSHoria Geantă 	}
1148d6bbd4eeSHoria Geantă 
1149d6bbd4eeSHoria Geantă 	append_math_add_imm_u32(desc, REG3, ZERO, IMM, assoclen);
1150d6bbd4eeSHoria Geantă 
1151d6bbd4eeSHoria Geantă 	/*
1152d6bbd4eeSHoria Geantă 	 * For IPsec load the IV further in the same register.
1153d6bbd4eeSHoria Geantă 	 * For RFC7539 simply load the 12 bytes nonce in a single operation
1154d6bbd4eeSHoria Geantă 	 */
1155d6bbd4eeSHoria Geantă 	append_load_as_imm(desc, req->iv, ivsize, LDST_CLASS_1_CCB |
1156d6bbd4eeSHoria Geantă 			   LDST_SRCDST_BYTE_CONTEXT |
1157d6bbd4eeSHoria Geantă 			   ctx_iv_off << LDST_OFFSET_SHIFT);
1158d6bbd4eeSHoria Geantă }
1159d6bbd4eeSHoria Geantă 
1160479bcc7cSHerbert Xu static void init_authenc_job(struct aead_request *req,
11611acebad3SYuan Kang 			     struct aead_edesc *edesc,
1162479bcc7cSHerbert Xu 			     bool all_contig, bool encrypt)
11631acebad3SYuan Kang {
11641acebad3SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1165479bcc7cSHerbert Xu 	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
1166479bcc7cSHerbert Xu 						 struct caam_aead_alg, aead);
1167479bcc7cSHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
11681acebad3SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
11697e0880b9SHoria Geantă 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctx->jrdev->parent);
1170db57656bSHoria Geantă 	const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
1171479bcc7cSHerbert Xu 			       OP_ALG_AAI_CTR_MOD128);
1172479bcc7cSHerbert Xu 	const bool is_rfc3686 = alg->caam.rfc3686;
11731acebad3SYuan Kang 	u32 *desc = edesc->hw_desc;
1174479bcc7cSHerbert Xu 	u32 ivoffset = 0;
11758e8ec596SKim Phillips 
1176479bcc7cSHerbert Xu 	/*
1177479bcc7cSHerbert Xu 	 * AES-CTR needs to load IV in CONTEXT1 reg
1178479bcc7cSHerbert Xu 	 * at an offset of 128bits (16bytes)
1179479bcc7cSHerbert Xu 	 * CONTEXT1[255:128] = IV
1180479bcc7cSHerbert Xu 	 */
1181479bcc7cSHerbert Xu 	if (ctr_mode)
1182479bcc7cSHerbert Xu 		ivoffset = 16;
11838e8ec596SKim Phillips 
1184479bcc7cSHerbert Xu 	/*
1185479bcc7cSHerbert Xu 	 * RFC3686 specific:
1186479bcc7cSHerbert Xu 	 *	CONTEXT1[255:128] = {NONCE, IV, COUNTER}
1187479bcc7cSHerbert Xu 	 */
1188479bcc7cSHerbert Xu 	if (is_rfc3686)
1189479bcc7cSHerbert Xu 		ivoffset = 16 + CTR_RFC3686_NONCE_SIZE;
1190bac68f2cSTudor Ambarus 
1191479bcc7cSHerbert Xu 	init_aead_job(req, edesc, all_contig, encrypt);
11921acebad3SYuan Kang 
11937e0880b9SHoria Geantă 	/*
11947e0880b9SHoria Geantă 	 * {REG3, DPOVRD} = assoclen, depending on whether MATH command supports
11957e0880b9SHoria Geantă 	 * having DPOVRD as destination.
11967e0880b9SHoria Geantă 	 */
11977e0880b9SHoria Geantă 	if (ctrlpriv->era < 3)
11987e0880b9SHoria Geantă 		append_math_add_imm_u32(desc, REG3, ZERO, IMM, req->assoclen);
11997e0880b9SHoria Geantă 	else
12007e0880b9SHoria Geantă 		append_math_add_imm_u32(desc, DPOVRD, ZERO, IMM, req->assoclen);
12017e0880b9SHoria Geantă 
12028b18e235SHoria Geantă 	if (ivsize && ((is_rfc3686 && encrypt) || !alg->caam.geniv))
1203479bcc7cSHerbert Xu 		append_load_as_imm(desc, req->iv, ivsize,
1204479bcc7cSHerbert Xu 				   LDST_CLASS_1_CCB |
1205479bcc7cSHerbert Xu 				   LDST_SRCDST_BYTE_CONTEXT |
1206479bcc7cSHerbert Xu 				   (ivoffset << LDST_OFFSET_SHIFT));
12078e8ec596SKim Phillips }
12088e8ec596SKim Phillips 
12098e8ec596SKim Phillips /*
12105ca7badbSHoria Geantă  * Fill in skcipher job descriptor
1211acdca31dSYuan Kang  */
12125ca7badbSHoria Geantă static void init_skcipher_job(struct skcipher_request *req,
12135ca7badbSHoria Geantă 			      struct skcipher_edesc *edesc,
12145ca7badbSHoria Geantă 			      const bool encrypt)
1215acdca31dSYuan Kang {
12165ca7badbSHoria Geantă 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
12175ca7badbSHoria Geantă 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
12185ca7badbSHoria Geantă 	int ivsize = crypto_skcipher_ivsize(skcipher);
1219acdca31dSYuan Kang 	u32 *desc = edesc->hw_desc;
12205ca7badbSHoria Geantă 	u32 *sh_desc;
1221eaed71a4SIuliana Prodan 	u32 in_options = 0, out_options = 0;
1222eaed71a4SIuliana Prodan 	dma_addr_t src_dma, dst_dma, ptr;
1223eaed71a4SIuliana Prodan 	int len, sec4_sg_index = 0;
1224acdca31dSYuan Kang 
1225acdca31dSYuan Kang #ifdef DEBUG
1226514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "presciv@"__stringify(__LINE__)": ",
12275ca7badbSHoria Geantă 		       DUMP_PREFIX_ADDRESS, 16, 4, req->iv, ivsize, 1);
12285ca7badbSHoria Geantă 	pr_err("asked=%d, cryptlen%d\n",
12295ca7badbSHoria Geantă 	       (int)edesc->src_nents > 1 ? 100 : req->cryptlen, req->cryptlen);
1230972b812bSHoria Geantă #endif
1231972b812bSHoria Geantă 	caam_dump_sg(KERN_ERR, "src    @" __stringify(__LINE__)": ",
12325ecf8ef9SCatalin Vasile 		     DUMP_PREFIX_ADDRESS, 16, 4, req->src,
12335ca7badbSHoria Geantă 		     edesc->src_nents > 1 ? 100 : req->cryptlen, 1);
12345ca7badbSHoria Geantă 
12355ca7badbSHoria Geantă 	sh_desc = encrypt ? ctx->sh_desc_enc : ctx->sh_desc_dec;
12365ca7badbSHoria Geantă 	ptr = encrypt ? ctx->sh_desc_enc_dma : ctx->sh_desc_dec_dma;
1237acdca31dSYuan Kang 
1238acdca31dSYuan Kang 	len = desc_len(sh_desc);
1239acdca31dSYuan Kang 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
1240acdca31dSYuan Kang 
1241eaed71a4SIuliana Prodan 	if (ivsize || edesc->mapped_src_nents > 1) {
1242eaed71a4SIuliana Prodan 		src_dma = edesc->sec4_sg_dma;
1243eaed71a4SIuliana Prodan 		sec4_sg_index = edesc->mapped_src_nents + !!ivsize;
1244eaed71a4SIuliana Prodan 		in_options = LDST_SGF;
1245eaed71a4SIuliana Prodan 	} else {
1246eaed71a4SIuliana Prodan 		src_dma = sg_dma_address(req->src);
1247eaed71a4SIuliana Prodan 	}
1248eaed71a4SIuliana Prodan 
1249eaed71a4SIuliana Prodan 	append_seq_in_ptr(desc, src_dma, req->cryptlen + ivsize, in_options);
1250acdca31dSYuan Kang 
1251acdca31dSYuan Kang 	if (likely(req->src == req->dst)) {
1252eaed71a4SIuliana Prodan 		dst_dma = src_dma + !!ivsize * sizeof(struct sec4_sg_entry);
1253eaed71a4SIuliana Prodan 		out_options = in_options;
1254eaed71a4SIuliana Prodan 	} else if (edesc->mapped_dst_nents == 1) {
1255acdca31dSYuan Kang 		dst_dma = sg_dma_address(req->dst);
1256acdca31dSYuan Kang 	} else {
1257eaed71a4SIuliana Prodan 		dst_dma = edesc->sec4_sg_dma + sec4_sg_index *
1258eaed71a4SIuliana Prodan 			  sizeof(struct sec4_sg_entry);
1259acdca31dSYuan Kang 		out_options = LDST_SGF;
1260acdca31dSYuan Kang 	}
1261eaed71a4SIuliana Prodan 
12625ca7badbSHoria Geantă 	append_seq_out_ptr(desc, dst_dma, req->cryptlen, out_options);
1263acdca31dSYuan Kang }
1264acdca31dSYuan Kang 
1265acdca31dSYuan Kang /*
12661acebad3SYuan Kang  * allocate and map the aead extended descriptor
12678e8ec596SKim Phillips  */
1268f2147b88SHerbert Xu static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
1269f2147b88SHerbert Xu 					   int desc_bytes, bool *all_contig_ptr,
1270f2147b88SHerbert Xu 					   bool encrypt)
1271f2147b88SHerbert Xu {
1272f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1273f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1274f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
1275019d62dbSHoria Geantă 	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
1276019d62dbSHoria Geantă 		       GFP_KERNEL : GFP_ATOMIC;
1277838e0a89SHoria Geantă 	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
1278f2147b88SHerbert Xu 	struct aead_edesc *edesc;
1279fa0c92dbSHoria Geantă 	int sec4_sg_index, sec4_sg_len, sec4_sg_bytes;
1280f2147b88SHerbert Xu 	unsigned int authsize = ctx->authsize;
1281f2147b88SHerbert Xu 
1282f2147b88SHerbert Xu 	if (unlikely(req->dst != req->src)) {
1283fa0c92dbSHoria Geantă 		src_nents = sg_nents_for_len(req->src, req->assoclen +
1284fa0c92dbSHoria Geantă 					     req->cryptlen);
1285fd144d83SHoria Geantă 		if (unlikely(src_nents < 0)) {
1286fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
1287fd144d83SHoria Geantă 				req->assoclen + req->cryptlen);
1288fd144d83SHoria Geantă 			return ERR_PTR(src_nents);
1289fd144d83SHoria Geantă 		}
1290fd144d83SHoria Geantă 
1291fa0c92dbSHoria Geantă 		dst_nents = sg_nents_for_len(req->dst, req->assoclen +
1292fa0c92dbSHoria Geantă 					     req->cryptlen +
1293fa0c92dbSHoria Geantă 						(encrypt ? authsize :
1294fa0c92dbSHoria Geantă 							   (-authsize)));
1295fd144d83SHoria Geantă 		if (unlikely(dst_nents < 0)) {
1296fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in dst S/G\n",
1297fd144d83SHoria Geantă 				req->assoclen + req->cryptlen +
1298fd144d83SHoria Geantă 				(encrypt ? authsize : (-authsize)));
1299fd144d83SHoria Geantă 			return ERR_PTR(dst_nents);
1300fd144d83SHoria Geantă 		}
1301f2147b88SHerbert Xu 	} else {
1302fa0c92dbSHoria Geantă 		src_nents = sg_nents_for_len(req->src, req->assoclen +
1303fa0c92dbSHoria Geantă 					     req->cryptlen +
130413fb8fd7SLABBE Corentin 					     (encrypt ? authsize : 0));
1305fd144d83SHoria Geantă 		if (unlikely(src_nents < 0)) {
1306fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
1307fd144d83SHoria Geantă 				req->assoclen + req->cryptlen +
1308fd144d83SHoria Geantă 				(encrypt ? authsize : 0));
1309fd144d83SHoria Geantă 			return ERR_PTR(src_nents);
1310fd144d83SHoria Geantă 		}
1311f2147b88SHerbert Xu 	}
1312f2147b88SHerbert Xu 
1313838e0a89SHoria Geantă 	if (likely(req->src == req->dst)) {
1314838e0a89SHoria Geantă 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1315838e0a89SHoria Geantă 					      DMA_BIDIRECTIONAL);
1316838e0a89SHoria Geantă 		if (unlikely(!mapped_src_nents)) {
1317838e0a89SHoria Geantă 			dev_err(jrdev, "unable to map source\n");
1318838e0a89SHoria Geantă 			return ERR_PTR(-ENOMEM);
1319838e0a89SHoria Geantă 		}
1320838e0a89SHoria Geantă 	} else {
1321838e0a89SHoria Geantă 		/* Cover also the case of null (zero length) input data */
1322838e0a89SHoria Geantă 		if (src_nents) {
1323838e0a89SHoria Geantă 			mapped_src_nents = dma_map_sg(jrdev, req->src,
1324838e0a89SHoria Geantă 						      src_nents, DMA_TO_DEVICE);
1325838e0a89SHoria Geantă 			if (unlikely(!mapped_src_nents)) {
1326838e0a89SHoria Geantă 				dev_err(jrdev, "unable to map source\n");
1327838e0a89SHoria Geantă 				return ERR_PTR(-ENOMEM);
1328838e0a89SHoria Geantă 			}
1329838e0a89SHoria Geantă 		} else {
1330838e0a89SHoria Geantă 			mapped_src_nents = 0;
1331838e0a89SHoria Geantă 		}
1332838e0a89SHoria Geantă 
1333763069baSHoria Geantă 		/* Cover also the case of null (zero length) output data */
1334763069baSHoria Geantă 		if (dst_nents) {
1335763069baSHoria Geantă 			mapped_dst_nents = dma_map_sg(jrdev, req->dst,
1336763069baSHoria Geantă 						      dst_nents,
1337838e0a89SHoria Geantă 						      DMA_FROM_DEVICE);
1338838e0a89SHoria Geantă 			if (unlikely(!mapped_dst_nents)) {
1339838e0a89SHoria Geantă 				dev_err(jrdev, "unable to map destination\n");
1340763069baSHoria Geantă 				dma_unmap_sg(jrdev, req->src, src_nents,
1341763069baSHoria Geantă 					     DMA_TO_DEVICE);
1342838e0a89SHoria Geantă 				return ERR_PTR(-ENOMEM);
1343838e0a89SHoria Geantă 			}
1344763069baSHoria Geantă 		} else {
1345763069baSHoria Geantă 			mapped_dst_nents = 0;
1346763069baSHoria Geantă 		}
1347838e0a89SHoria Geantă 	}
1348838e0a89SHoria Geantă 
1349838e0a89SHoria Geantă 	sec4_sg_len = mapped_src_nents > 1 ? mapped_src_nents : 0;
1350838e0a89SHoria Geantă 	sec4_sg_len += mapped_dst_nents > 1 ? mapped_dst_nents : 0;
1351f2147b88SHerbert Xu 	sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry);
1352f2147b88SHerbert Xu 
1353f2147b88SHerbert Xu 	/* allocate space for base edesc and hw desc commands, link tables */
1354dde20ae9SVictoria Milhoan 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes,
1355dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
1356f2147b88SHerbert Xu 	if (!edesc) {
1357838e0a89SHoria Geantă 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
1358cf5448b5SHoria Geantă 			   0, 0, 0);
1359f2147b88SHerbert Xu 		return ERR_PTR(-ENOMEM);
1360f2147b88SHerbert Xu 	}
1361f2147b88SHerbert Xu 
1362f2147b88SHerbert Xu 	edesc->src_nents = src_nents;
1363f2147b88SHerbert Xu 	edesc->dst_nents = dst_nents;
1364ba4cf71bSIuliana Prodan 	edesc->mapped_src_nents = mapped_src_nents;
1365ba4cf71bSIuliana Prodan 	edesc->mapped_dst_nents = mapped_dst_nents;
1366f2147b88SHerbert Xu 	edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) +
1367f2147b88SHerbert Xu 			 desc_bytes;
1368838e0a89SHoria Geantă 	*all_contig_ptr = !(mapped_src_nents > 1);
1369f2147b88SHerbert Xu 
1370f2147b88SHerbert Xu 	sec4_sg_index = 0;
1371838e0a89SHoria Geantă 	if (mapped_src_nents > 1) {
1372838e0a89SHoria Geantă 		sg_to_sec4_sg_last(req->src, mapped_src_nents,
1373f2147b88SHerbert Xu 				   edesc->sec4_sg + sec4_sg_index, 0);
1374838e0a89SHoria Geantă 		sec4_sg_index += mapped_src_nents;
1375f2147b88SHerbert Xu 	}
1376838e0a89SHoria Geantă 	if (mapped_dst_nents > 1) {
1377838e0a89SHoria Geantă 		sg_to_sec4_sg_last(req->dst, mapped_dst_nents,
1378f2147b88SHerbert Xu 				   edesc->sec4_sg + sec4_sg_index, 0);
1379f2147b88SHerbert Xu 	}
1380f2147b88SHerbert Xu 
1381f2147b88SHerbert Xu 	if (!sec4_sg_bytes)
1382f2147b88SHerbert Xu 		return edesc;
1383f2147b88SHerbert Xu 
1384f2147b88SHerbert Xu 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
1385f2147b88SHerbert Xu 					    sec4_sg_bytes, DMA_TO_DEVICE);
1386f2147b88SHerbert Xu 	if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
1387f2147b88SHerbert Xu 		dev_err(jrdev, "unable to map S/G table\n");
1388f2147b88SHerbert Xu 		aead_unmap(jrdev, edesc, req);
1389f2147b88SHerbert Xu 		kfree(edesc);
1390f2147b88SHerbert Xu 		return ERR_PTR(-ENOMEM);
1391f2147b88SHerbert Xu 	}
1392f2147b88SHerbert Xu 
1393f2147b88SHerbert Xu 	edesc->sec4_sg_bytes = sec4_sg_bytes;
1394f2147b88SHerbert Xu 
1395f2147b88SHerbert Xu 	return edesc;
1396f2147b88SHerbert Xu }
1397f2147b88SHerbert Xu 
1398f2147b88SHerbert Xu static int gcm_encrypt(struct aead_request *req)
13998e8ec596SKim Phillips {
14000e479300SYuan Kang 	struct aead_edesc *edesc;
14018e8ec596SKim Phillips 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
14028e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
14038e8ec596SKim Phillips 	struct device *jrdev = ctx->jrdev;
14041acebad3SYuan Kang 	bool all_contig;
14058e8ec596SKim Phillips 	u32 *desc;
14061acebad3SYuan Kang 	int ret = 0;
14071acebad3SYuan Kang 
14088e8ec596SKim Phillips 	/* allocate extended descriptor */
1409f2147b88SHerbert Xu 	edesc = aead_edesc_alloc(req, GCM_DESC_JOB_IO_LEN, &all_contig, true);
14108e8ec596SKim Phillips 	if (IS_ERR(edesc))
14118e8ec596SKim Phillips 		return PTR_ERR(edesc);
14128e8ec596SKim Phillips 
14131acebad3SYuan Kang 	/* Create and submit job descriptor */
1414f2147b88SHerbert Xu 	init_gcm_job(req, edesc, all_contig, true);
14151acebad3SYuan Kang #ifdef DEBUG
1416514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
14171acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
14181acebad3SYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
14191acebad3SYuan Kang #endif
14201acebad3SYuan Kang 
14218e8ec596SKim Phillips 	desc = edesc->hw_desc;
14221acebad3SYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
14231acebad3SYuan Kang 	if (!ret) {
14241acebad3SYuan Kang 		ret = -EINPROGRESS;
14251acebad3SYuan Kang 	} else {
14261acebad3SYuan Kang 		aead_unmap(jrdev, edesc, req);
14271acebad3SYuan Kang 		kfree(edesc);
14281acebad3SYuan Kang 	}
14298e8ec596SKim Phillips 
14301acebad3SYuan Kang 	return ret;
14318e8ec596SKim Phillips }
14328e8ec596SKim Phillips 
1433d6bbd4eeSHoria Geantă static int chachapoly_encrypt(struct aead_request *req)
1434d6bbd4eeSHoria Geantă {
1435d6bbd4eeSHoria Geantă 	struct aead_edesc *edesc;
1436d6bbd4eeSHoria Geantă 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1437d6bbd4eeSHoria Geantă 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1438d6bbd4eeSHoria Geantă 	struct device *jrdev = ctx->jrdev;
1439d6bbd4eeSHoria Geantă 	bool all_contig;
1440d6bbd4eeSHoria Geantă 	u32 *desc;
1441d6bbd4eeSHoria Geantă 	int ret;
1442d6bbd4eeSHoria Geantă 
1443d6bbd4eeSHoria Geantă 	edesc = aead_edesc_alloc(req, CHACHAPOLY_DESC_JOB_IO_LEN, &all_contig,
1444d6bbd4eeSHoria Geantă 				 true);
1445d6bbd4eeSHoria Geantă 	if (IS_ERR(edesc))
1446d6bbd4eeSHoria Geantă 		return PTR_ERR(edesc);
1447d6bbd4eeSHoria Geantă 
1448d6bbd4eeSHoria Geantă 	desc = edesc->hw_desc;
1449d6bbd4eeSHoria Geantă 
1450d6bbd4eeSHoria Geantă 	init_chachapoly_job(req, edesc, all_contig, true);
1451d6bbd4eeSHoria Geantă 	print_hex_dump_debug("chachapoly jobdesc@" __stringify(__LINE__)": ",
1452d6bbd4eeSHoria Geantă 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1453d6bbd4eeSHoria Geantă 			     1);
1454d6bbd4eeSHoria Geantă 
1455d6bbd4eeSHoria Geantă 	ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
1456d6bbd4eeSHoria Geantă 	if (!ret) {
1457d6bbd4eeSHoria Geantă 		ret = -EINPROGRESS;
1458d6bbd4eeSHoria Geantă 	} else {
1459d6bbd4eeSHoria Geantă 		aead_unmap(jrdev, edesc, req);
1460d6bbd4eeSHoria Geantă 		kfree(edesc);
1461d6bbd4eeSHoria Geantă 	}
1462d6bbd4eeSHoria Geantă 
1463d6bbd4eeSHoria Geantă 	return ret;
1464d6bbd4eeSHoria Geantă }
1465d6bbd4eeSHoria Geantă 
1466d6bbd4eeSHoria Geantă static int chachapoly_decrypt(struct aead_request *req)
1467d6bbd4eeSHoria Geantă {
1468d6bbd4eeSHoria Geantă 	struct aead_edesc *edesc;
1469d6bbd4eeSHoria Geantă 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1470d6bbd4eeSHoria Geantă 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1471d6bbd4eeSHoria Geantă 	struct device *jrdev = ctx->jrdev;
1472d6bbd4eeSHoria Geantă 	bool all_contig;
1473d6bbd4eeSHoria Geantă 	u32 *desc;
1474d6bbd4eeSHoria Geantă 	int ret;
1475d6bbd4eeSHoria Geantă 
1476d6bbd4eeSHoria Geantă 	edesc = aead_edesc_alloc(req, CHACHAPOLY_DESC_JOB_IO_LEN, &all_contig,
1477d6bbd4eeSHoria Geantă 				 false);
1478d6bbd4eeSHoria Geantă 	if (IS_ERR(edesc))
1479d6bbd4eeSHoria Geantă 		return PTR_ERR(edesc);
1480d6bbd4eeSHoria Geantă 
1481d6bbd4eeSHoria Geantă 	desc = edesc->hw_desc;
1482d6bbd4eeSHoria Geantă 
1483d6bbd4eeSHoria Geantă 	init_chachapoly_job(req, edesc, all_contig, false);
1484d6bbd4eeSHoria Geantă 	print_hex_dump_debug("chachapoly jobdesc@" __stringify(__LINE__)": ",
1485d6bbd4eeSHoria Geantă 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1486d6bbd4eeSHoria Geantă 			     1);
1487d6bbd4eeSHoria Geantă 
1488d6bbd4eeSHoria Geantă 	ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
1489d6bbd4eeSHoria Geantă 	if (!ret) {
1490d6bbd4eeSHoria Geantă 		ret = -EINPROGRESS;
1491d6bbd4eeSHoria Geantă 	} else {
1492d6bbd4eeSHoria Geantă 		aead_unmap(jrdev, edesc, req);
1493d6bbd4eeSHoria Geantă 		kfree(edesc);
1494d6bbd4eeSHoria Geantă 	}
1495d6bbd4eeSHoria Geantă 
1496d6bbd4eeSHoria Geantă 	return ret;
1497d6bbd4eeSHoria Geantă }
1498d6bbd4eeSHoria Geantă 
149946218750SHerbert Xu static int ipsec_gcm_encrypt(struct aead_request *req)
150046218750SHerbert Xu {
150146218750SHerbert Xu 	if (req->assoclen < 8)
150246218750SHerbert Xu 		return -EINVAL;
150346218750SHerbert Xu 
150446218750SHerbert Xu 	return gcm_encrypt(req);
150546218750SHerbert Xu }
150646218750SHerbert Xu 
1507479bcc7cSHerbert Xu static int aead_encrypt(struct aead_request *req)
15088e8ec596SKim Phillips {
15091acebad3SYuan Kang 	struct aead_edesc *edesc;
15100e479300SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
15110e479300SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
15120e479300SYuan Kang 	struct device *jrdev = ctx->jrdev;
15131acebad3SYuan Kang 	bool all_contig;
15140e479300SYuan Kang 	u32 *desc;
15151acebad3SYuan Kang 	int ret = 0;
15160e479300SYuan Kang 
15170e479300SYuan Kang 	/* allocate extended descriptor */
1518479bcc7cSHerbert Xu 	edesc = aead_edesc_alloc(req, AUTHENC_DESC_JOB_IO_LEN,
1519479bcc7cSHerbert Xu 				 &all_contig, true);
15200e479300SYuan Kang 	if (IS_ERR(edesc))
15210e479300SYuan Kang 		return PTR_ERR(edesc);
15220e479300SYuan Kang 
1523f2147b88SHerbert Xu 	/* Create and submit job descriptor */
1524479bcc7cSHerbert Xu 	init_authenc_job(req, edesc, all_contig, true);
15251acebad3SYuan Kang #ifdef DEBUG
1526f2147b88SHerbert Xu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
1527f2147b88SHerbert Xu 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1528f2147b88SHerbert Xu 		       desc_bytes(edesc->hw_desc), 1);
15291acebad3SYuan Kang #endif
15301acebad3SYuan Kang 
1531f2147b88SHerbert Xu 	desc = edesc->hw_desc;
1532479bcc7cSHerbert Xu 	ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
1533f2147b88SHerbert Xu 	if (!ret) {
1534f2147b88SHerbert Xu 		ret = -EINPROGRESS;
1535f2147b88SHerbert Xu 	} else {
1536479bcc7cSHerbert Xu 		aead_unmap(jrdev, edesc, req);
1537f2147b88SHerbert Xu 		kfree(edesc);
1538f2147b88SHerbert Xu 	}
1539f2147b88SHerbert Xu 
1540f2147b88SHerbert Xu 	return ret;
1541f2147b88SHerbert Xu }
1542f2147b88SHerbert Xu 
1543f2147b88SHerbert Xu static int gcm_decrypt(struct aead_request *req)
1544f2147b88SHerbert Xu {
1545f2147b88SHerbert Xu 	struct aead_edesc *edesc;
1546f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1547f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1548f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
1549f2147b88SHerbert Xu 	bool all_contig;
1550f2147b88SHerbert Xu 	u32 *desc;
1551f2147b88SHerbert Xu 	int ret = 0;
1552f2147b88SHerbert Xu 
1553f2147b88SHerbert Xu 	/* allocate extended descriptor */
1554f2147b88SHerbert Xu 	edesc = aead_edesc_alloc(req, GCM_DESC_JOB_IO_LEN, &all_contig, false);
1555f2147b88SHerbert Xu 	if (IS_ERR(edesc))
1556f2147b88SHerbert Xu 		return PTR_ERR(edesc);
1557f2147b88SHerbert Xu 
15581acebad3SYuan Kang 	/* Create and submit job descriptor*/
1559f2147b88SHerbert Xu 	init_gcm_job(req, edesc, all_contig, false);
15601acebad3SYuan Kang #ifdef DEBUG
1561514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
15621acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
15631acebad3SYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
15641acebad3SYuan Kang #endif
15651acebad3SYuan Kang 
15660e479300SYuan Kang 	desc = edesc->hw_desc;
15671acebad3SYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
15681acebad3SYuan Kang 	if (!ret) {
15691acebad3SYuan Kang 		ret = -EINPROGRESS;
15701acebad3SYuan Kang 	} else {
15711acebad3SYuan Kang 		aead_unmap(jrdev, edesc, req);
15721acebad3SYuan Kang 		kfree(edesc);
15731acebad3SYuan Kang 	}
15740e479300SYuan Kang 
15751acebad3SYuan Kang 	return ret;
15761acebad3SYuan Kang }
15770e479300SYuan Kang 
157846218750SHerbert Xu static int ipsec_gcm_decrypt(struct aead_request *req)
157946218750SHerbert Xu {
158046218750SHerbert Xu 	if (req->assoclen < 8)
158146218750SHerbert Xu 		return -EINVAL;
158246218750SHerbert Xu 
158346218750SHerbert Xu 	return gcm_decrypt(req);
158446218750SHerbert Xu }
158546218750SHerbert Xu 
1586479bcc7cSHerbert Xu static int aead_decrypt(struct aead_request *req)
1587f2147b88SHerbert Xu {
1588f2147b88SHerbert Xu 	struct aead_edesc *edesc;
1589f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1590f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1591f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
1592f2147b88SHerbert Xu 	bool all_contig;
1593f2147b88SHerbert Xu 	u32 *desc;
1594f2147b88SHerbert Xu 	int ret = 0;
1595f2147b88SHerbert Xu 
1596972b812bSHoria Geantă 	caam_dump_sg(KERN_ERR, "dec src@" __stringify(__LINE__)": ",
15975ecf8ef9SCatalin Vasile 		     DUMP_PREFIX_ADDRESS, 16, 4, req->src,
159800fef2b2SHoria Geantă 		     req->assoclen + req->cryptlen, 1);
15995ecf8ef9SCatalin Vasile 
1600f2147b88SHerbert Xu 	/* allocate extended descriptor */
1601479bcc7cSHerbert Xu 	edesc = aead_edesc_alloc(req, AUTHENC_DESC_JOB_IO_LEN,
1602479bcc7cSHerbert Xu 				 &all_contig, false);
1603f2147b88SHerbert Xu 	if (IS_ERR(edesc))
1604f2147b88SHerbert Xu 		return PTR_ERR(edesc);
1605f2147b88SHerbert Xu 
1606f2147b88SHerbert Xu 	/* Create and submit job descriptor*/
1607479bcc7cSHerbert Xu 	init_authenc_job(req, edesc, all_contig, false);
1608f2147b88SHerbert Xu #ifdef DEBUG
1609f2147b88SHerbert Xu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
1610f2147b88SHerbert Xu 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1611f2147b88SHerbert Xu 		       desc_bytes(edesc->hw_desc), 1);
1612f2147b88SHerbert Xu #endif
1613f2147b88SHerbert Xu 
1614f2147b88SHerbert Xu 	desc = edesc->hw_desc;
1615479bcc7cSHerbert Xu 	ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
1616f2147b88SHerbert Xu 	if (!ret) {
1617f2147b88SHerbert Xu 		ret = -EINPROGRESS;
1618f2147b88SHerbert Xu 	} else {
1619479bcc7cSHerbert Xu 		aead_unmap(jrdev, edesc, req);
1620f2147b88SHerbert Xu 		kfree(edesc);
1621f2147b88SHerbert Xu 	}
1622f2147b88SHerbert Xu 
1623f2147b88SHerbert Xu 	return ret;
1624f2147b88SHerbert Xu }
1625f2147b88SHerbert Xu 
1626acdca31dSYuan Kang /*
16275ca7badbSHoria Geantă  * allocate and map the skcipher extended descriptor for skcipher
1628acdca31dSYuan Kang  */
16295ca7badbSHoria Geantă static struct skcipher_edesc *skcipher_edesc_alloc(struct skcipher_request *req,
16305ca7badbSHoria Geantă 						   int desc_bytes)
1631acdca31dSYuan Kang {
16325ca7badbSHoria Geantă 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
16335ca7badbSHoria Geantă 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
1634acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
163542cfcafbSHoria Geantă 	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
1636acdca31dSYuan Kang 		       GFP_KERNEL : GFP_ATOMIC;
1637838e0a89SHoria Geantă 	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
16385ca7badbSHoria Geantă 	struct skcipher_edesc *edesc;
1639eaed71a4SIuliana Prodan 	dma_addr_t iv_dma = 0;
1640115957bbSHoria Geantă 	u8 *iv;
16415ca7badbSHoria Geantă 	int ivsize = crypto_skcipher_ivsize(skcipher);
1642838e0a89SHoria Geantă 	int dst_sg_idx, sec4_sg_ents, sec4_sg_bytes;
1643acdca31dSYuan Kang 
16445ca7badbSHoria Geantă 	src_nents = sg_nents_for_len(req->src, req->cryptlen);
1645fd144d83SHoria Geantă 	if (unlikely(src_nents < 0)) {
1646fd144d83SHoria Geantă 		dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
16475ca7badbSHoria Geantă 			req->cryptlen);
1648fd144d83SHoria Geantă 		return ERR_PTR(src_nents);
1649fd144d83SHoria Geantă 	}
1650acdca31dSYuan Kang 
1651fd144d83SHoria Geantă 	if (req->dst != req->src) {
16525ca7badbSHoria Geantă 		dst_nents = sg_nents_for_len(req->dst, req->cryptlen);
1653fd144d83SHoria Geantă 		if (unlikely(dst_nents < 0)) {
1654fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in dst S/G\n",
16555ca7badbSHoria Geantă 				req->cryptlen);
1656fd144d83SHoria Geantă 			return ERR_PTR(dst_nents);
1657fd144d83SHoria Geantă 		}
1658fd144d83SHoria Geantă 	}
1659acdca31dSYuan Kang 
1660acdca31dSYuan Kang 	if (likely(req->src == req->dst)) {
1661838e0a89SHoria Geantă 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1662838e0a89SHoria Geantă 					      DMA_BIDIRECTIONAL);
1663838e0a89SHoria Geantă 		if (unlikely(!mapped_src_nents)) {
1664c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map source\n");
1665c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1666c73e36e8SHoria Geantă 		}
1667acdca31dSYuan Kang 	} else {
1668838e0a89SHoria Geantă 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1669838e0a89SHoria Geantă 					      DMA_TO_DEVICE);
1670838e0a89SHoria Geantă 		if (unlikely(!mapped_src_nents)) {
1671c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map source\n");
1672c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1673c73e36e8SHoria Geantă 		}
1674838e0a89SHoria Geantă 		mapped_dst_nents = dma_map_sg(jrdev, req->dst, dst_nents,
1675838e0a89SHoria Geantă 					      DMA_FROM_DEVICE);
1676838e0a89SHoria Geantă 		if (unlikely(!mapped_dst_nents)) {
1677c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map destination\n");
1678fa0c92dbSHoria Geantă 			dma_unmap_sg(jrdev, req->src, src_nents, DMA_TO_DEVICE);
1679c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1680c73e36e8SHoria Geantă 		}
1681acdca31dSYuan Kang 	}
1682acdca31dSYuan Kang 
1683eaed71a4SIuliana Prodan 	if (!ivsize && mapped_src_nents == 1)
1684eaed71a4SIuliana Prodan 		sec4_sg_ents = 0; // no need for an input hw s/g table
1685eaed71a4SIuliana Prodan 	else
1686eaed71a4SIuliana Prodan 		sec4_sg_ents = mapped_src_nents + !!ivsize;
1687fa0c92dbSHoria Geantă 	dst_sg_idx = sec4_sg_ents;
1688838e0a89SHoria Geantă 	sec4_sg_ents += mapped_dst_nents > 1 ? mapped_dst_nents : 0;
1689fa0c92dbSHoria Geantă 	sec4_sg_bytes = sec4_sg_ents * sizeof(struct sec4_sg_entry);
1690acdca31dSYuan Kang 
1691115957bbSHoria Geantă 	/*
1692115957bbSHoria Geantă 	 * allocate space for base edesc and hw desc commands, link tables, IV
1693115957bbSHoria Geantă 	 */
1694115957bbSHoria Geantă 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes + ivsize,
1695dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
1696acdca31dSYuan Kang 	if (!edesc) {
1697acdca31dSYuan Kang 		dev_err(jrdev, "could not allocate extended descriptor\n");
1698115957bbSHoria Geantă 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
1699cf5448b5SHoria Geantă 			   0, 0, 0);
1700acdca31dSYuan Kang 		return ERR_PTR(-ENOMEM);
1701acdca31dSYuan Kang 	}
1702acdca31dSYuan Kang 
1703acdca31dSYuan Kang 	edesc->src_nents = src_nents;
1704acdca31dSYuan Kang 	edesc->dst_nents = dst_nents;
1705ba4cf71bSIuliana Prodan 	edesc->mapped_src_nents = mapped_src_nents;
1706ba4cf71bSIuliana Prodan 	edesc->mapped_dst_nents = mapped_dst_nents;
1707a299c837SYuan Kang 	edesc->sec4_sg_bytes = sec4_sg_bytes;
170813cc6f48SHoria Geantă 	edesc->sec4_sg = (struct sec4_sg_entry *)((u8 *)edesc->hw_desc +
170913cc6f48SHoria Geantă 						  desc_bytes);
1710acdca31dSYuan Kang 
1711115957bbSHoria Geantă 	/* Make sure IV is located in a DMAable area */
1712eaed71a4SIuliana Prodan 	if (ivsize) {
1713115957bbSHoria Geantă 		iv = (u8 *)edesc->hw_desc + desc_bytes + sec4_sg_bytes;
17145ca7badbSHoria Geantă 		memcpy(iv, req->iv, ivsize);
1715115957bbSHoria Geantă 
1716115957bbSHoria Geantă 		iv_dma = dma_map_single(jrdev, iv, ivsize, DMA_TO_DEVICE);
1717115957bbSHoria Geantă 		if (dma_mapping_error(jrdev, iv_dma)) {
1718115957bbSHoria Geantă 			dev_err(jrdev, "unable to map IV\n");
1719eaed71a4SIuliana Prodan 			caam_unmap(jrdev, req->src, req->dst, src_nents,
1720eaed71a4SIuliana Prodan 				   dst_nents, 0, 0, 0, 0);
1721115957bbSHoria Geantă 			kfree(edesc);
1722115957bbSHoria Geantă 			return ERR_PTR(-ENOMEM);
1723acdca31dSYuan Kang 		}
1724acdca31dSYuan Kang 
1725115957bbSHoria Geantă 		dma_to_sec4_sg_one(edesc->sec4_sg, iv_dma, ivsize, 0);
1726eaed71a4SIuliana Prodan 	}
1727eaed71a4SIuliana Prodan 	if (dst_sg_idx)
1728eaed71a4SIuliana Prodan 		sg_to_sec4_sg_last(req->src, mapped_src_nents, edesc->sec4_sg +
1729eaed71a4SIuliana Prodan 				   !!ivsize, 0);
1730115957bbSHoria Geantă 
1731838e0a89SHoria Geantă 	if (mapped_dst_nents > 1) {
1732838e0a89SHoria Geantă 		sg_to_sec4_sg_last(req->dst, mapped_dst_nents,
1733fa0c92dbSHoria Geantă 				   edesc->sec4_sg + dst_sg_idx, 0);
1734acdca31dSYuan Kang 	}
1735acdca31dSYuan Kang 
1736eaed71a4SIuliana Prodan 	if (sec4_sg_bytes) {
1737a299c837SYuan Kang 		edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
1738eaed71a4SIuliana Prodan 						    sec4_sg_bytes,
1739eaed71a4SIuliana Prodan 						    DMA_TO_DEVICE);
1740ce572085SHoria Geanta 		if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
1741ce572085SHoria Geanta 			dev_err(jrdev, "unable to map S/G table\n");
1742eaed71a4SIuliana Prodan 			caam_unmap(jrdev, req->src, req->dst, src_nents,
1743eaed71a4SIuliana Prodan 				   dst_nents, iv_dma, ivsize, 0, 0);
1744c73e36e8SHoria Geantă 			kfree(edesc);
1745ce572085SHoria Geanta 			return ERR_PTR(-ENOMEM);
1746ce572085SHoria Geanta 		}
1747eaed71a4SIuliana Prodan 	}
1748ce572085SHoria Geanta 
1749acdca31dSYuan Kang 	edesc->iv_dma = iv_dma;
1750acdca31dSYuan Kang 
1751acdca31dSYuan Kang #ifdef DEBUG
17525ca7badbSHoria Geantă 	print_hex_dump(KERN_ERR, "skcipher sec4_sg@" __stringify(__LINE__)": ",
1753a299c837SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->sec4_sg,
1754a299c837SYuan Kang 		       sec4_sg_bytes, 1);
1755acdca31dSYuan Kang #endif
1756acdca31dSYuan Kang 
1757acdca31dSYuan Kang 	return edesc;
1758acdca31dSYuan Kang }
1759acdca31dSYuan Kang 
17605ca7badbSHoria Geantă static int skcipher_encrypt(struct skcipher_request *req)
1761acdca31dSYuan Kang {
17625ca7badbSHoria Geantă 	struct skcipher_edesc *edesc;
17635ca7badbSHoria Geantă 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
17645ca7badbSHoria Geantă 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
1765acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
1766acdca31dSYuan Kang 	u32 *desc;
1767acdca31dSYuan Kang 	int ret = 0;
1768acdca31dSYuan Kang 
1769acdca31dSYuan Kang 	/* allocate extended descriptor */
17705ca7badbSHoria Geantă 	edesc = skcipher_edesc_alloc(req, DESC_JOB_IO_LEN * CAAM_CMD_SZ);
1771acdca31dSYuan Kang 	if (IS_ERR(edesc))
1772acdca31dSYuan Kang 		return PTR_ERR(edesc);
1773acdca31dSYuan Kang 
1774acdca31dSYuan Kang 	/* Create and submit job descriptor*/
17755ca7badbSHoria Geantă 	init_skcipher_job(req, edesc, true);
1776acdca31dSYuan Kang #ifdef DEBUG
17775ca7badbSHoria Geantă 	print_hex_dump(KERN_ERR, "skcipher jobdesc@" __stringify(__LINE__)": ",
1778acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1779acdca31dSYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
1780acdca31dSYuan Kang #endif
1781acdca31dSYuan Kang 	desc = edesc->hw_desc;
17825ca7badbSHoria Geantă 	ret = caam_jr_enqueue(jrdev, desc, skcipher_encrypt_done, req);
1783acdca31dSYuan Kang 
1784acdca31dSYuan Kang 	if (!ret) {
1785acdca31dSYuan Kang 		ret = -EINPROGRESS;
1786acdca31dSYuan Kang 	} else {
17875ca7badbSHoria Geantă 		skcipher_unmap(jrdev, edesc, req);
1788acdca31dSYuan Kang 		kfree(edesc);
1789acdca31dSYuan Kang 	}
1790acdca31dSYuan Kang 
1791acdca31dSYuan Kang 	return ret;
1792acdca31dSYuan Kang }
1793acdca31dSYuan Kang 
17945ca7badbSHoria Geantă static int skcipher_decrypt(struct skcipher_request *req)
1795acdca31dSYuan Kang {
17965ca7badbSHoria Geantă 	struct skcipher_edesc *edesc;
17975ca7badbSHoria Geantă 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
17985ca7badbSHoria Geantă 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
17995ca7badbSHoria Geantă 	int ivsize = crypto_skcipher_ivsize(skcipher);
1800acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
1801acdca31dSYuan Kang 	u32 *desc;
1802acdca31dSYuan Kang 	int ret = 0;
1803acdca31dSYuan Kang 
1804acdca31dSYuan Kang 	/* allocate extended descriptor */
18055ca7badbSHoria Geantă 	edesc = skcipher_edesc_alloc(req, DESC_JOB_IO_LEN * CAAM_CMD_SZ);
1806acdca31dSYuan Kang 	if (IS_ERR(edesc))
1807acdca31dSYuan Kang 		return PTR_ERR(edesc);
1808acdca31dSYuan Kang 
1809115957bbSHoria Geantă 	/*
18105ca7badbSHoria Geantă 	 * The crypto API expects us to set the IV (req->iv) to the last
1811115957bbSHoria Geantă 	 * ciphertext block.
1812115957bbSHoria Geantă 	 */
1813eaed71a4SIuliana Prodan 	if (ivsize)
1814eaed71a4SIuliana Prodan 		scatterwalk_map_and_copy(req->iv, req->src, req->cryptlen -
1815eaed71a4SIuliana Prodan 					 ivsize, ivsize, 0);
1816115957bbSHoria Geantă 
1817acdca31dSYuan Kang 	/* Create and submit job descriptor*/
18185ca7badbSHoria Geantă 	init_skcipher_job(req, edesc, false);
1819acdca31dSYuan Kang 	desc = edesc->hw_desc;
1820acdca31dSYuan Kang #ifdef DEBUG
18215ca7badbSHoria Geantă 	print_hex_dump(KERN_ERR, "skcipher jobdesc@" __stringify(__LINE__)": ",
1822acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1823acdca31dSYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
1824acdca31dSYuan Kang #endif
1825acdca31dSYuan Kang 
18265ca7badbSHoria Geantă 	ret = caam_jr_enqueue(jrdev, desc, skcipher_decrypt_done, req);
1827acdca31dSYuan Kang 	if (!ret) {
1828acdca31dSYuan Kang 		ret = -EINPROGRESS;
1829acdca31dSYuan Kang 	} else {
18305ca7badbSHoria Geantă 		skcipher_unmap(jrdev, edesc, req);
1831acdca31dSYuan Kang 		kfree(edesc);
1832acdca31dSYuan Kang 	}
1833acdca31dSYuan Kang 
1834acdca31dSYuan Kang 	return ret;
1835acdca31dSYuan Kang }
1836acdca31dSYuan Kang 
18375ca7badbSHoria Geantă static struct caam_skcipher_alg driver_algs[] = {
1838acdca31dSYuan Kang 	{
18395ca7badbSHoria Geantă 		.skcipher = {
18405ca7badbSHoria Geantă 			.base = {
18415ca7badbSHoria Geantă 				.cra_name = "cbc(aes)",
18425ca7badbSHoria Geantă 				.cra_driver_name = "cbc-aes-caam",
18435ca7badbSHoria Geantă 				.cra_blocksize = AES_BLOCK_SIZE,
18445ca7badbSHoria Geantă 			},
18455ca7badbSHoria Geantă 			.setkey = skcipher_setkey,
18465ca7badbSHoria Geantă 			.encrypt = skcipher_encrypt,
18475ca7badbSHoria Geantă 			.decrypt = skcipher_decrypt,
1848acdca31dSYuan Kang 			.min_keysize = AES_MIN_KEY_SIZE,
1849acdca31dSYuan Kang 			.max_keysize = AES_MAX_KEY_SIZE,
1850acdca31dSYuan Kang 			.ivsize = AES_BLOCK_SIZE,
1851acdca31dSYuan Kang 		},
18525ca7badbSHoria Geantă 		.caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
1853acdca31dSYuan Kang 	},
1854acdca31dSYuan Kang 	{
18555ca7badbSHoria Geantă 		.skcipher = {
18565ca7badbSHoria Geantă 			.base = {
18575ca7badbSHoria Geantă 				.cra_name = "cbc(des3_ede)",
18585ca7badbSHoria Geantă 				.cra_driver_name = "cbc-3des-caam",
18595ca7badbSHoria Geantă 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
18605ca7badbSHoria Geantă 			},
18615ca7badbSHoria Geantă 			.setkey = skcipher_setkey,
18625ca7badbSHoria Geantă 			.encrypt = skcipher_encrypt,
18635ca7badbSHoria Geantă 			.decrypt = skcipher_decrypt,
1864acdca31dSYuan Kang 			.min_keysize = DES3_EDE_KEY_SIZE,
1865acdca31dSYuan Kang 			.max_keysize = DES3_EDE_KEY_SIZE,
1866acdca31dSYuan Kang 			.ivsize = DES3_EDE_BLOCK_SIZE,
1867acdca31dSYuan Kang 		},
18685ca7badbSHoria Geantă 		.caam.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
1869acdca31dSYuan Kang 	},
1870acdca31dSYuan Kang 	{
18715ca7badbSHoria Geantă 		.skcipher = {
18725ca7badbSHoria Geantă 			.base = {
18735ca7badbSHoria Geantă 				.cra_name = "cbc(des)",
18745ca7badbSHoria Geantă 				.cra_driver_name = "cbc-des-caam",
18755ca7badbSHoria Geantă 				.cra_blocksize = DES_BLOCK_SIZE,
18765ca7badbSHoria Geantă 			},
18775ca7badbSHoria Geantă 			.setkey = skcipher_setkey,
18785ca7badbSHoria Geantă 			.encrypt = skcipher_encrypt,
18795ca7badbSHoria Geantă 			.decrypt = skcipher_decrypt,
1880acdca31dSYuan Kang 			.min_keysize = DES_KEY_SIZE,
1881acdca31dSYuan Kang 			.max_keysize = DES_KEY_SIZE,
1882acdca31dSYuan Kang 			.ivsize = DES_BLOCK_SIZE,
1883acdca31dSYuan Kang 		},
18845ca7badbSHoria Geantă 		.caam.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
18852b22f6c5SCatalin Vasile 	},
18862b22f6c5SCatalin Vasile 	{
18875ca7badbSHoria Geantă 		.skcipher = {
18885ca7badbSHoria Geantă 			.base = {
18895ca7badbSHoria Geantă 				.cra_name = "ctr(aes)",
18905ca7badbSHoria Geantă 				.cra_driver_name = "ctr-aes-caam",
18915ca7badbSHoria Geantă 				.cra_blocksize = 1,
18925ca7badbSHoria Geantă 			},
18935ca7badbSHoria Geantă 			.setkey = skcipher_setkey,
18945ca7badbSHoria Geantă 			.encrypt = skcipher_encrypt,
18955ca7badbSHoria Geantă 			.decrypt = skcipher_decrypt,
18962b22f6c5SCatalin Vasile 			.min_keysize = AES_MIN_KEY_SIZE,
18972b22f6c5SCatalin Vasile 			.max_keysize = AES_MAX_KEY_SIZE,
18982b22f6c5SCatalin Vasile 			.ivsize = AES_BLOCK_SIZE,
18995ca7badbSHoria Geantă 			.chunksize = AES_BLOCK_SIZE,
19002b22f6c5SCatalin Vasile 		},
19015ca7badbSHoria Geantă 		.caam.class1_alg_type = OP_ALG_ALGSEL_AES |
19025ca7badbSHoria Geantă 					OP_ALG_AAI_CTR_MOD128,
1903a5f57cffSCatalin Vasile 	},
1904a5f57cffSCatalin Vasile 	{
19055ca7badbSHoria Geantă 		.skcipher = {
19065ca7badbSHoria Geantă 			.base = {
19075ca7badbSHoria Geantă 				.cra_name = "rfc3686(ctr(aes))",
19085ca7badbSHoria Geantă 				.cra_driver_name = "rfc3686-ctr-aes-caam",
19095ca7badbSHoria Geantă 				.cra_blocksize = 1,
19105ca7badbSHoria Geantă 			},
19115ca7badbSHoria Geantă 			.setkey = skcipher_setkey,
19125ca7badbSHoria Geantă 			.encrypt = skcipher_encrypt,
19135ca7badbSHoria Geantă 			.decrypt = skcipher_decrypt,
1914a5f57cffSCatalin Vasile 			.min_keysize = AES_MIN_KEY_SIZE +
1915a5f57cffSCatalin Vasile 				       CTR_RFC3686_NONCE_SIZE,
1916a5f57cffSCatalin Vasile 			.max_keysize = AES_MAX_KEY_SIZE +
1917a5f57cffSCatalin Vasile 				       CTR_RFC3686_NONCE_SIZE,
1918a5f57cffSCatalin Vasile 			.ivsize = CTR_RFC3686_IV_SIZE,
19195ca7badbSHoria Geantă 			.chunksize = AES_BLOCK_SIZE,
1920a5f57cffSCatalin Vasile 		},
19215ca7badbSHoria Geantă 		.caam = {
19225ca7badbSHoria Geantă 			.class1_alg_type = OP_ALG_ALGSEL_AES |
19235ca7badbSHoria Geantă 					   OP_ALG_AAI_CTR_MOD128,
19245ca7badbSHoria Geantă 			.rfc3686 = true,
19255ca7badbSHoria Geantă 		},
1926c6415a60SCatalin Vasile 	},
1927c6415a60SCatalin Vasile 	{
19285ca7badbSHoria Geantă 		.skcipher = {
19295ca7badbSHoria Geantă 			.base = {
19305ca7badbSHoria Geantă 				.cra_name = "xts(aes)",
19315ca7badbSHoria Geantă 				.cra_driver_name = "xts-aes-caam",
19325ca7badbSHoria Geantă 				.cra_blocksize = AES_BLOCK_SIZE,
19335ca7badbSHoria Geantă 			},
19345ca7badbSHoria Geantă 			.setkey = xts_skcipher_setkey,
19355ca7badbSHoria Geantă 			.encrypt = skcipher_encrypt,
19365ca7badbSHoria Geantă 			.decrypt = skcipher_decrypt,
1937c6415a60SCatalin Vasile 			.min_keysize = 2 * AES_MIN_KEY_SIZE,
1938c6415a60SCatalin Vasile 			.max_keysize = 2 * AES_MAX_KEY_SIZE,
1939c6415a60SCatalin Vasile 			.ivsize = AES_BLOCK_SIZE,
1940c6415a60SCatalin Vasile 		},
19415ca7badbSHoria Geantă 		.caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_XTS,
1942c6415a60SCatalin Vasile 	},
1943eaed71a4SIuliana Prodan 	{
1944eaed71a4SIuliana Prodan 		.skcipher = {
1945eaed71a4SIuliana Prodan 			.base = {
1946eaed71a4SIuliana Prodan 				.cra_name = "ecb(des)",
1947eaed71a4SIuliana Prodan 				.cra_driver_name = "ecb-des-caam",
1948eaed71a4SIuliana Prodan 				.cra_blocksize = DES_BLOCK_SIZE,
1949eaed71a4SIuliana Prodan 			},
1950eaed71a4SIuliana Prodan 			.setkey = des_skcipher_setkey,
1951eaed71a4SIuliana Prodan 			.encrypt = skcipher_encrypt,
1952eaed71a4SIuliana Prodan 			.decrypt = skcipher_decrypt,
1953eaed71a4SIuliana Prodan 			.min_keysize = DES_KEY_SIZE,
1954eaed71a4SIuliana Prodan 			.max_keysize = DES_KEY_SIZE,
1955eaed71a4SIuliana Prodan 		},
1956eaed71a4SIuliana Prodan 		.caam.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_ECB,
1957eaed71a4SIuliana Prodan 	},
1958eaed71a4SIuliana Prodan 	{
1959eaed71a4SIuliana Prodan 		.skcipher = {
1960eaed71a4SIuliana Prodan 			.base = {
1961eaed71a4SIuliana Prodan 				.cra_name = "ecb(aes)",
1962eaed71a4SIuliana Prodan 				.cra_driver_name = "ecb-aes-caam",
1963eaed71a4SIuliana Prodan 				.cra_blocksize = AES_BLOCK_SIZE,
1964eaed71a4SIuliana Prodan 			},
1965eaed71a4SIuliana Prodan 			.setkey = skcipher_setkey,
1966eaed71a4SIuliana Prodan 			.encrypt = skcipher_encrypt,
1967eaed71a4SIuliana Prodan 			.decrypt = skcipher_decrypt,
1968eaed71a4SIuliana Prodan 			.min_keysize = AES_MIN_KEY_SIZE,
1969eaed71a4SIuliana Prodan 			.max_keysize = AES_MAX_KEY_SIZE,
1970eaed71a4SIuliana Prodan 		},
1971eaed71a4SIuliana Prodan 		.caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_ECB,
1972eaed71a4SIuliana Prodan 	},
1973eaed71a4SIuliana Prodan 	{
1974eaed71a4SIuliana Prodan 		.skcipher = {
1975eaed71a4SIuliana Prodan 			.base = {
1976eaed71a4SIuliana Prodan 				.cra_name = "ecb(des3_ede)",
1977eaed71a4SIuliana Prodan 				.cra_driver_name = "ecb-des3-caam",
1978eaed71a4SIuliana Prodan 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
1979eaed71a4SIuliana Prodan 			},
1980eaed71a4SIuliana Prodan 			.setkey = des_skcipher_setkey,
1981eaed71a4SIuliana Prodan 			.encrypt = skcipher_encrypt,
1982eaed71a4SIuliana Prodan 			.decrypt = skcipher_decrypt,
1983eaed71a4SIuliana Prodan 			.min_keysize = DES3_EDE_KEY_SIZE,
1984eaed71a4SIuliana Prodan 			.max_keysize = DES3_EDE_KEY_SIZE,
1985eaed71a4SIuliana Prodan 		},
1986eaed71a4SIuliana Prodan 		.caam.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_ECB,
1987eaed71a4SIuliana Prodan 	},
1988eaed71a4SIuliana Prodan 	{
1989eaed71a4SIuliana Prodan 		.skcipher = {
1990eaed71a4SIuliana Prodan 			.base = {
1991eaed71a4SIuliana Prodan 				.cra_name = "ecb(arc4)",
1992eaed71a4SIuliana Prodan 				.cra_driver_name = "ecb-arc4-caam",
1993eaed71a4SIuliana Prodan 				.cra_blocksize = ARC4_BLOCK_SIZE,
1994eaed71a4SIuliana Prodan 			},
1995eaed71a4SIuliana Prodan 			.setkey = skcipher_setkey,
1996eaed71a4SIuliana Prodan 			.encrypt = skcipher_encrypt,
1997eaed71a4SIuliana Prodan 			.decrypt = skcipher_decrypt,
1998eaed71a4SIuliana Prodan 			.min_keysize = ARC4_MIN_KEY_SIZE,
1999eaed71a4SIuliana Prodan 			.max_keysize = ARC4_MAX_KEY_SIZE,
2000eaed71a4SIuliana Prodan 		},
2001eaed71a4SIuliana Prodan 		.caam.class1_alg_type = OP_ALG_ALGSEL_ARC4 | OP_ALG_AAI_ECB,
2002eaed71a4SIuliana Prodan 	},
20038e8ec596SKim Phillips };
20048e8ec596SKim Phillips 
2005f2147b88SHerbert Xu static struct caam_aead_alg driver_aeads[] = {
2006f2147b88SHerbert Xu 	{
2007f2147b88SHerbert Xu 		.aead = {
2008f2147b88SHerbert Xu 			.base = {
2009f2147b88SHerbert Xu 				.cra_name = "rfc4106(gcm(aes))",
2010f2147b88SHerbert Xu 				.cra_driver_name = "rfc4106-gcm-aes-caam",
2011f2147b88SHerbert Xu 				.cra_blocksize = 1,
2012f2147b88SHerbert Xu 			},
2013f2147b88SHerbert Xu 			.setkey = rfc4106_setkey,
2014f2147b88SHerbert Xu 			.setauthsize = rfc4106_setauthsize,
201546218750SHerbert Xu 			.encrypt = ipsec_gcm_encrypt,
201646218750SHerbert Xu 			.decrypt = ipsec_gcm_decrypt,
20177545e166SCorentin LABBE 			.ivsize = GCM_RFC4106_IV_SIZE,
2018f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
2019f2147b88SHerbert Xu 		},
2020f2147b88SHerbert Xu 		.caam = {
2021f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
2022f2147b88SHerbert Xu 		},
2023f2147b88SHerbert Xu 	},
2024f2147b88SHerbert Xu 	{
2025f2147b88SHerbert Xu 		.aead = {
2026f2147b88SHerbert Xu 			.base = {
2027f2147b88SHerbert Xu 				.cra_name = "rfc4543(gcm(aes))",
2028f2147b88SHerbert Xu 				.cra_driver_name = "rfc4543-gcm-aes-caam",
2029f2147b88SHerbert Xu 				.cra_blocksize = 1,
2030f2147b88SHerbert Xu 			},
2031f2147b88SHerbert Xu 			.setkey = rfc4543_setkey,
2032f2147b88SHerbert Xu 			.setauthsize = rfc4543_setauthsize,
203346218750SHerbert Xu 			.encrypt = ipsec_gcm_encrypt,
203446218750SHerbert Xu 			.decrypt = ipsec_gcm_decrypt,
20357545e166SCorentin LABBE 			.ivsize = GCM_RFC4543_IV_SIZE,
2036f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
2037f2147b88SHerbert Xu 		},
2038f2147b88SHerbert Xu 		.caam = {
2039f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
2040f2147b88SHerbert Xu 		},
2041f2147b88SHerbert Xu 	},
2042f2147b88SHerbert Xu 	/* Galois Counter Mode */
2043f2147b88SHerbert Xu 	{
2044f2147b88SHerbert Xu 		.aead = {
2045f2147b88SHerbert Xu 			.base = {
2046f2147b88SHerbert Xu 				.cra_name = "gcm(aes)",
2047f2147b88SHerbert Xu 				.cra_driver_name = "gcm-aes-caam",
2048f2147b88SHerbert Xu 				.cra_blocksize = 1,
2049f2147b88SHerbert Xu 			},
2050f2147b88SHerbert Xu 			.setkey = gcm_setkey,
2051f2147b88SHerbert Xu 			.setauthsize = gcm_setauthsize,
2052f2147b88SHerbert Xu 			.encrypt = gcm_encrypt,
2053f2147b88SHerbert Xu 			.decrypt = gcm_decrypt,
20547545e166SCorentin LABBE 			.ivsize = GCM_AES_IV_SIZE,
2055f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
2056f2147b88SHerbert Xu 		},
2057f2147b88SHerbert Xu 		.caam = {
2058f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
2059f2147b88SHerbert Xu 		},
2060f2147b88SHerbert Xu 	},
2061479bcc7cSHerbert Xu 	/* single-pass ipsec_esp descriptor */
2062479bcc7cSHerbert Xu 	{
2063479bcc7cSHerbert Xu 		.aead = {
2064479bcc7cSHerbert Xu 			.base = {
2065479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),"
2066479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2067479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2068479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2069479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2070479bcc7cSHerbert Xu 			},
2071479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2072479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2073479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2074479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2075479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2076479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2077479bcc7cSHerbert Xu 		},
2078479bcc7cSHerbert Xu 		.caam = {
2079479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2080479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2081479bcc7cSHerbert Xu 		},
2082479bcc7cSHerbert Xu 	},
2083479bcc7cSHerbert Xu 	{
2084479bcc7cSHerbert Xu 		.aead = {
2085479bcc7cSHerbert Xu 			.base = {
2086479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
2087479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2088479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2089479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2090479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2091479bcc7cSHerbert Xu 			},
2092479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2093479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2094479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2095479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2096479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2097479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2098479bcc7cSHerbert Xu 		},
2099479bcc7cSHerbert Xu 		.caam = {
2100479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2101479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2102479bcc7cSHerbert Xu 		},
2103479bcc7cSHerbert Xu 	},
2104479bcc7cSHerbert Xu 	{
2105479bcc7cSHerbert Xu 		.aead = {
2106479bcc7cSHerbert Xu 			.base = {
2107479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
2108479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2109479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2110479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2111479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2112479bcc7cSHerbert Xu 			},
2113479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2114479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2115479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2116479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2117479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2118479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2119479bcc7cSHerbert Xu 		},
2120479bcc7cSHerbert Xu 		.caam = {
2121479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2122479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2123479bcc7cSHerbert Xu 		},
2124479bcc7cSHerbert Xu 	},
2125479bcc7cSHerbert Xu 	{
2126479bcc7cSHerbert Xu 		.aead = {
2127479bcc7cSHerbert Xu 			.base = {
2128479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
2129479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2130479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
2131479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2132479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2133479bcc7cSHerbert Xu 			},
2134479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2135479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2136479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2137479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2138479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2139479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2140479bcc7cSHerbert Xu 		},
2141479bcc7cSHerbert Xu 		.caam = {
2142479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2143479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2144479bcc7cSHerbert Xu 		},
2145479bcc7cSHerbert Xu 	},
2146479bcc7cSHerbert Xu 	{
2147479bcc7cSHerbert Xu 		.aead = {
2148479bcc7cSHerbert Xu 			.base = {
2149479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
2150479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2151479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
2152479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2153479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2154479bcc7cSHerbert Xu 			},
2155479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2156479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2157479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2158479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2159479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2160479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2161479bcc7cSHerbert Xu 		},
2162479bcc7cSHerbert Xu 		.caam = {
2163479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2164479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2165479bcc7cSHerbert Xu 		},
2166479bcc7cSHerbert Xu 	},
2167479bcc7cSHerbert Xu 	{
2168479bcc7cSHerbert Xu 		.aead = {
2169479bcc7cSHerbert Xu 			.base = {
2170479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
2171479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2172479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
2173479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2174479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2175479bcc7cSHerbert Xu 			},
2176479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2177479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2178479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2179479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2180479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2181479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2182479bcc7cSHerbert Xu 		},
2183479bcc7cSHerbert Xu 		.caam = {
2184479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2185479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2186479bcc7cSHerbert Xu 		},
2187479bcc7cSHerbert Xu 	},
2188479bcc7cSHerbert Xu 	{
2189479bcc7cSHerbert Xu 		.aead = {
2190479bcc7cSHerbert Xu 			.base = {
2191479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(aes))",
2192479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2193479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2194479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2195479bcc7cSHerbert Xu 			},
2196479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2197479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2198479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2199479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2200479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2201479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2202479bcc7cSHerbert Xu 		},
2203479bcc7cSHerbert Xu 		.caam = {
2204479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2205479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2206479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2207479bcc7cSHerbert Xu 		},
2208479bcc7cSHerbert Xu 	},
2209479bcc7cSHerbert Xu 	{
2210479bcc7cSHerbert Xu 		.aead = {
2211479bcc7cSHerbert Xu 			.base = {
2212479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
2213479bcc7cSHerbert Xu 					    "cbc(aes)))",
2214479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
2215479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2216479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2217479bcc7cSHerbert Xu 			},
2218479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2219479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2220479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
22218b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2222479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2223479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2224479bcc7cSHerbert Xu 		},
2225479bcc7cSHerbert Xu 		.caam = {
2226479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2227479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2228479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2229479bcc7cSHerbert Xu 			.geniv = true,
2230479bcc7cSHerbert Xu 		},
2231479bcc7cSHerbert Xu 	},
2232479bcc7cSHerbert Xu 	{
2233479bcc7cSHerbert Xu 		.aead = {
2234479bcc7cSHerbert Xu 			.base = {
2235479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),cbc(aes))",
2236479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2237479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2238479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2239479bcc7cSHerbert Xu 			},
2240479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2241479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2242479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2243479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2244479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2245479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2246479bcc7cSHerbert Xu 		},
2247479bcc7cSHerbert Xu 		.caam = {
2248479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2249479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2250479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2251479bcc7cSHerbert Xu 		},
2252479bcc7cSHerbert Xu 	},
2253479bcc7cSHerbert Xu 	{
2254479bcc7cSHerbert Xu 		.aead = {
2255479bcc7cSHerbert Xu 			.base = {
2256479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
2257479bcc7cSHerbert Xu 					    "cbc(aes)))",
2258479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2259479bcc7cSHerbert Xu 						   "hmac-sha1-cbc-aes-caam",
2260479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2261479bcc7cSHerbert Xu 			},
2262479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2263479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2264479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
22658b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2266479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2267479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2268479bcc7cSHerbert Xu 		},
2269479bcc7cSHerbert Xu 		.caam = {
2270479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2271479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2272479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2273479bcc7cSHerbert Xu 			.geniv = true,
2274479bcc7cSHerbert Xu 		},
2275479bcc7cSHerbert Xu 	},
2276479bcc7cSHerbert Xu 	{
2277479bcc7cSHerbert Xu 		.aead = {
2278479bcc7cSHerbert Xu 			.base = {
2279479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),cbc(aes))",
2280479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2281479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2282479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2283479bcc7cSHerbert Xu 			},
2284479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2285479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2286479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2287479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2288479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2289479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2290479bcc7cSHerbert Xu 		},
2291479bcc7cSHerbert Xu 		.caam = {
2292479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2293479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2294479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2295479bcc7cSHerbert Xu 		},
2296479bcc7cSHerbert Xu 	},
2297479bcc7cSHerbert Xu 	{
2298479bcc7cSHerbert Xu 		.aead = {
2299479bcc7cSHerbert Xu 			.base = {
2300479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
2301479bcc7cSHerbert Xu 					    "cbc(aes)))",
2302479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2303479bcc7cSHerbert Xu 						   "hmac-sha224-cbc-aes-caam",
2304479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2305479bcc7cSHerbert Xu 			},
2306479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2307479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2308479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
23098b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2310479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2311479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2312479bcc7cSHerbert Xu 		},
2313479bcc7cSHerbert Xu 		.caam = {
2314479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2315479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2316479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2317479bcc7cSHerbert Xu 			.geniv = true,
2318479bcc7cSHerbert Xu 		},
2319479bcc7cSHerbert Xu 	},
2320479bcc7cSHerbert Xu 	{
2321479bcc7cSHerbert Xu 		.aead = {
2322479bcc7cSHerbert Xu 			.base = {
2323479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),cbc(aes))",
2324479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
2325479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2326479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2327479bcc7cSHerbert Xu 			},
2328479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2329479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2330479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2331479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2332479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2333479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2334479bcc7cSHerbert Xu 		},
2335479bcc7cSHerbert Xu 		.caam = {
2336479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2337479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2338479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2339479bcc7cSHerbert Xu 		},
2340479bcc7cSHerbert Xu 	},
2341479bcc7cSHerbert Xu 	{
2342479bcc7cSHerbert Xu 		.aead = {
2343479bcc7cSHerbert Xu 			.base = {
2344479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
2345479bcc7cSHerbert Xu 					    "cbc(aes)))",
2346479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2347479bcc7cSHerbert Xu 						   "hmac-sha256-cbc-aes-caam",
2348479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2349479bcc7cSHerbert Xu 			},
2350479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2351479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2352479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
23538b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2354479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2355479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2356479bcc7cSHerbert Xu 		},
2357479bcc7cSHerbert Xu 		.caam = {
2358479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2359479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2360479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2361479bcc7cSHerbert Xu 			.geniv = true,
2362479bcc7cSHerbert Xu 		},
2363479bcc7cSHerbert Xu 	},
2364479bcc7cSHerbert Xu 	{
2365479bcc7cSHerbert Xu 		.aead = {
2366479bcc7cSHerbert Xu 			.base = {
2367479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),cbc(aes))",
2368479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
2369479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2370479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2371479bcc7cSHerbert Xu 			},
2372479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2373479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2374479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2375479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2376479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2377479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2378479bcc7cSHerbert Xu 		},
2379479bcc7cSHerbert Xu 		.caam = {
2380479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2381479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2382479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2383479bcc7cSHerbert Xu 		},
2384479bcc7cSHerbert Xu 	},
2385479bcc7cSHerbert Xu 	{
2386479bcc7cSHerbert Xu 		.aead = {
2387479bcc7cSHerbert Xu 			.base = {
2388479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
2389479bcc7cSHerbert Xu 					    "cbc(aes)))",
2390479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2391479bcc7cSHerbert Xu 						   "hmac-sha384-cbc-aes-caam",
2392479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2393479bcc7cSHerbert Xu 			},
2394479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2395479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2396479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
23978b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2398479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2399479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2400479bcc7cSHerbert Xu 		},
2401479bcc7cSHerbert Xu 		.caam = {
2402479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2403479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2404479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2405479bcc7cSHerbert Xu 			.geniv = true,
2406479bcc7cSHerbert Xu 		},
2407479bcc7cSHerbert Xu 	},
2408479bcc7cSHerbert Xu 	{
2409479bcc7cSHerbert Xu 		.aead = {
2410479bcc7cSHerbert Xu 			.base = {
2411479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),cbc(aes))",
2412479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
2413479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2414479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2415479bcc7cSHerbert Xu 			},
2416479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2417479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2418479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2419479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2420479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2421479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2422479bcc7cSHerbert Xu 		},
2423479bcc7cSHerbert Xu 		.caam = {
2424479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2425479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2426479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2427479bcc7cSHerbert Xu 		},
2428479bcc7cSHerbert Xu 	},
2429479bcc7cSHerbert Xu 	{
2430479bcc7cSHerbert Xu 		.aead = {
2431479bcc7cSHerbert Xu 			.base = {
2432479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
2433479bcc7cSHerbert Xu 					    "cbc(aes)))",
2434479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2435479bcc7cSHerbert Xu 						   "hmac-sha512-cbc-aes-caam",
2436479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2437479bcc7cSHerbert Xu 			},
2438479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2439479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2440479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
24418b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2442479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2443479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2444479bcc7cSHerbert Xu 		},
2445479bcc7cSHerbert Xu 		.caam = {
2446479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2447479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2448479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2449479bcc7cSHerbert Xu 			.geniv = true,
2450479bcc7cSHerbert Xu 		},
2451479bcc7cSHerbert Xu 	},
2452479bcc7cSHerbert Xu 	{
2453479bcc7cSHerbert Xu 		.aead = {
2454479bcc7cSHerbert Xu 			.base = {
2455479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2456479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2457479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2458479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2459479bcc7cSHerbert Xu 			},
2460479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2461479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2462479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2463479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2464479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2465479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2466479bcc7cSHerbert Xu 		},
2467479bcc7cSHerbert Xu 		.caam = {
2468479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2469479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2470479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2471479bcc7cSHerbert Xu 		}
2472479bcc7cSHerbert Xu 	},
2473479bcc7cSHerbert Xu 	{
2474479bcc7cSHerbert Xu 		.aead = {
2475479bcc7cSHerbert Xu 			.base = {
2476479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
2477479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2478479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
2479479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2480479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2481479bcc7cSHerbert Xu 			},
2482479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2483479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2484479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
24858b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2486479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2487479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2488479bcc7cSHerbert Xu 		},
2489479bcc7cSHerbert Xu 		.caam = {
2490479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2491479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2492479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2493479bcc7cSHerbert Xu 			.geniv = true,
2494479bcc7cSHerbert Xu 		}
2495479bcc7cSHerbert Xu 	},
2496479bcc7cSHerbert Xu 	{
2497479bcc7cSHerbert Xu 		.aead = {
2498479bcc7cSHerbert Xu 			.base = {
2499479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
2500479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2501479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2502479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2503479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2504479bcc7cSHerbert Xu 			},
2505479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2506479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2507479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2508479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2509479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2510479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2511479bcc7cSHerbert Xu 		},
2512479bcc7cSHerbert Xu 		.caam = {
2513479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2514479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2515479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2516479bcc7cSHerbert Xu 		},
2517479bcc7cSHerbert Xu 	},
2518479bcc7cSHerbert Xu 	{
2519479bcc7cSHerbert Xu 		.aead = {
2520479bcc7cSHerbert Xu 			.base = {
2521479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
2522479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2523479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2524479bcc7cSHerbert Xu 						   "hmac-sha1-"
2525479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2526479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2527479bcc7cSHerbert Xu 			},
2528479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2529479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2530479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
25318b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2532479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2533479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2534479bcc7cSHerbert Xu 		},
2535479bcc7cSHerbert Xu 		.caam = {
2536479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2537479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2538479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2539479bcc7cSHerbert Xu 			.geniv = true,
2540479bcc7cSHerbert Xu 		},
2541479bcc7cSHerbert Xu 	},
2542479bcc7cSHerbert Xu 	{
2543479bcc7cSHerbert Xu 		.aead = {
2544479bcc7cSHerbert Xu 			.base = {
2545479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
2546479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2547479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2548479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2549479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2550479bcc7cSHerbert Xu 			},
2551479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2552479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2553479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2554479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2555479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2556479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2557479bcc7cSHerbert Xu 		},
2558479bcc7cSHerbert Xu 		.caam = {
2559479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2560479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2561479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2562479bcc7cSHerbert Xu 		},
2563479bcc7cSHerbert Xu 	},
2564479bcc7cSHerbert Xu 	{
2565479bcc7cSHerbert Xu 		.aead = {
2566479bcc7cSHerbert Xu 			.base = {
2567479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
2568479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2569479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2570479bcc7cSHerbert Xu 						   "hmac-sha224-"
2571479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2572479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2573479bcc7cSHerbert Xu 			},
2574479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2575479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2576479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
25778b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2578479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2579479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2580479bcc7cSHerbert Xu 		},
2581479bcc7cSHerbert Xu 		.caam = {
2582479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2583479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2584479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2585479bcc7cSHerbert Xu 			.geniv = true,
2586479bcc7cSHerbert Xu 		},
2587479bcc7cSHerbert Xu 	},
2588479bcc7cSHerbert Xu 	{
2589479bcc7cSHerbert Xu 		.aead = {
2590479bcc7cSHerbert Xu 			.base = {
2591479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
2592479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2593479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
2594479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2595479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2596479bcc7cSHerbert Xu 			},
2597479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2598479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2599479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2600479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2601479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2602479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2603479bcc7cSHerbert Xu 		},
2604479bcc7cSHerbert Xu 		.caam = {
2605479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2606479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2607479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2608479bcc7cSHerbert Xu 		},
2609479bcc7cSHerbert Xu 	},
2610479bcc7cSHerbert Xu 	{
2611479bcc7cSHerbert Xu 		.aead = {
2612479bcc7cSHerbert Xu 			.base = {
2613479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
2614479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2615479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2616479bcc7cSHerbert Xu 						   "hmac-sha256-"
2617479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2618479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2619479bcc7cSHerbert Xu 			},
2620479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2621479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2622479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
26238b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2624479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2625479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2626479bcc7cSHerbert Xu 		},
2627479bcc7cSHerbert Xu 		.caam = {
2628479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2629479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2630479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2631479bcc7cSHerbert Xu 			.geniv = true,
2632479bcc7cSHerbert Xu 		},
2633479bcc7cSHerbert Xu 	},
2634479bcc7cSHerbert Xu 	{
2635479bcc7cSHerbert Xu 		.aead = {
2636479bcc7cSHerbert Xu 			.base = {
2637479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
2638479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2639479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
2640479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2641479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2642479bcc7cSHerbert Xu 			},
2643479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2644479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2645479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2646479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2647479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2648479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2649479bcc7cSHerbert Xu 		},
2650479bcc7cSHerbert Xu 		.caam = {
2651479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2652479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2653479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2654479bcc7cSHerbert Xu 		},
2655479bcc7cSHerbert Xu 	},
2656479bcc7cSHerbert Xu 	{
2657479bcc7cSHerbert Xu 		.aead = {
2658479bcc7cSHerbert Xu 			.base = {
2659479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
2660479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2661479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2662479bcc7cSHerbert Xu 						   "hmac-sha384-"
2663479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2664479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2665479bcc7cSHerbert Xu 			},
2666479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2667479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2668479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
26698b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2670479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2671479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2672479bcc7cSHerbert Xu 		},
2673479bcc7cSHerbert Xu 		.caam = {
2674479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2675479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2676479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2677479bcc7cSHerbert Xu 			.geniv = true,
2678479bcc7cSHerbert Xu 		},
2679479bcc7cSHerbert Xu 	},
2680479bcc7cSHerbert Xu 	{
2681479bcc7cSHerbert Xu 		.aead = {
2682479bcc7cSHerbert Xu 			.base = {
2683479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
2684479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2685479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
2686479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2687479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2688479bcc7cSHerbert Xu 			},
2689479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2690479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2691479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2692479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2693479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2694479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2695479bcc7cSHerbert Xu 		},
2696479bcc7cSHerbert Xu 		.caam = {
2697479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2698479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2699479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2700479bcc7cSHerbert Xu 		},
2701479bcc7cSHerbert Xu 	},
2702479bcc7cSHerbert Xu 	{
2703479bcc7cSHerbert Xu 		.aead = {
2704479bcc7cSHerbert Xu 			.base = {
2705479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
2706479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2707479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2708479bcc7cSHerbert Xu 						   "hmac-sha512-"
2709479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2710479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2711479bcc7cSHerbert Xu 			},
2712479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2713479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2714479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
27158b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2716479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2717479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2718479bcc7cSHerbert Xu 		},
2719479bcc7cSHerbert Xu 		.caam = {
2720479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2721479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2722479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2723479bcc7cSHerbert Xu 			.geniv = true,
2724479bcc7cSHerbert Xu 		},
2725479bcc7cSHerbert Xu 	},
2726479bcc7cSHerbert Xu 	{
2727479bcc7cSHerbert Xu 		.aead = {
2728479bcc7cSHerbert Xu 			.base = {
2729479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(des))",
2730479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2731479bcc7cSHerbert Xu 						   "cbc-des-caam",
2732479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2733479bcc7cSHerbert Xu 			},
2734479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2735479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2736479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2737479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2738479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2739479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2740479bcc7cSHerbert Xu 		},
2741479bcc7cSHerbert Xu 		.caam = {
2742479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2743479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2744479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2745479bcc7cSHerbert Xu 		},
2746479bcc7cSHerbert Xu 	},
2747479bcc7cSHerbert Xu 	{
2748479bcc7cSHerbert Xu 		.aead = {
2749479bcc7cSHerbert Xu 			.base = {
2750479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
2751479bcc7cSHerbert Xu 					    "cbc(des)))",
2752479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
2753479bcc7cSHerbert Xu 						   "cbc-des-caam",
2754479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2755479bcc7cSHerbert Xu 			},
2756479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2757479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2758479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
27598b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2760479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2761479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2762479bcc7cSHerbert Xu 		},
2763479bcc7cSHerbert Xu 		.caam = {
2764479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2765479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2766479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2767479bcc7cSHerbert Xu 			.geniv = true,
2768479bcc7cSHerbert Xu 		},
2769479bcc7cSHerbert Xu 	},
2770479bcc7cSHerbert Xu 	{
2771479bcc7cSHerbert Xu 		.aead = {
2772479bcc7cSHerbert Xu 			.base = {
2773479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),cbc(des))",
2774479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2775479bcc7cSHerbert Xu 						   "cbc-des-caam",
2776479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2777479bcc7cSHerbert Xu 			},
2778479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2779479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2780479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2781479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2782479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2783479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2784479bcc7cSHerbert Xu 		},
2785479bcc7cSHerbert Xu 		.caam = {
2786479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2787479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2788479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2789479bcc7cSHerbert Xu 		},
2790479bcc7cSHerbert Xu 	},
2791479bcc7cSHerbert Xu 	{
2792479bcc7cSHerbert Xu 		.aead = {
2793479bcc7cSHerbert Xu 			.base = {
2794479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
2795479bcc7cSHerbert Xu 					    "cbc(des)))",
2796479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2797479bcc7cSHerbert Xu 						   "hmac-sha1-cbc-des-caam",
2798479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2799479bcc7cSHerbert Xu 			},
2800479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2801479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2802479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
28038b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2804479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2805479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2806479bcc7cSHerbert Xu 		},
2807479bcc7cSHerbert Xu 		.caam = {
2808479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2809479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2810479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2811479bcc7cSHerbert Xu 			.geniv = true,
2812479bcc7cSHerbert Xu 		},
2813479bcc7cSHerbert Xu 	},
2814479bcc7cSHerbert Xu 	{
2815479bcc7cSHerbert Xu 		.aead = {
2816479bcc7cSHerbert Xu 			.base = {
2817479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),cbc(des))",
2818479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2819479bcc7cSHerbert Xu 						   "cbc-des-caam",
2820479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2821479bcc7cSHerbert Xu 			},
2822479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2823479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2824479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2825479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2826479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2827479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2828479bcc7cSHerbert Xu 		},
2829479bcc7cSHerbert Xu 		.caam = {
2830479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2831479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2832479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2833479bcc7cSHerbert Xu 		},
2834479bcc7cSHerbert Xu 	},
2835479bcc7cSHerbert Xu 	{
2836479bcc7cSHerbert Xu 		.aead = {
2837479bcc7cSHerbert Xu 			.base = {
2838479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
2839479bcc7cSHerbert Xu 					    "cbc(des)))",
2840479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2841479bcc7cSHerbert Xu 						   "hmac-sha224-cbc-des-caam",
2842479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2843479bcc7cSHerbert Xu 			},
2844479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2845479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2846479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
28478b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2848479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2849479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2850479bcc7cSHerbert Xu 		},
2851479bcc7cSHerbert Xu 		.caam = {
2852479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2853479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2854479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2855479bcc7cSHerbert Xu 			.geniv = true,
2856479bcc7cSHerbert Xu 		},
2857479bcc7cSHerbert Xu 	},
2858479bcc7cSHerbert Xu 	{
2859479bcc7cSHerbert Xu 		.aead = {
2860479bcc7cSHerbert Xu 			.base = {
2861479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),cbc(des))",
2862479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
2863479bcc7cSHerbert Xu 						   "cbc-des-caam",
2864479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2865479bcc7cSHerbert Xu 			},
2866479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2867479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2868479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2869479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2870479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2871479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2872479bcc7cSHerbert Xu 		},
2873479bcc7cSHerbert Xu 		.caam = {
2874479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2875479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2876479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2877479bcc7cSHerbert Xu 		},
2878479bcc7cSHerbert Xu 	},
2879479bcc7cSHerbert Xu 	{
2880479bcc7cSHerbert Xu 		.aead = {
2881479bcc7cSHerbert Xu 			.base = {
2882479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
2883479bcc7cSHerbert Xu 					    "cbc(des)))",
2884479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2885479bcc7cSHerbert Xu 						   "hmac-sha256-cbc-des-caam",
2886479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2887479bcc7cSHerbert Xu 			},
2888479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2889479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2890479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
28918b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2892479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2893479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2894479bcc7cSHerbert Xu 		},
2895479bcc7cSHerbert Xu 		.caam = {
2896479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2897479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2898479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2899479bcc7cSHerbert Xu 			.geniv = true,
2900479bcc7cSHerbert Xu 		},
2901479bcc7cSHerbert Xu 	},
2902479bcc7cSHerbert Xu 	{
2903479bcc7cSHerbert Xu 		.aead = {
2904479bcc7cSHerbert Xu 			.base = {
2905479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),cbc(des))",
2906479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
2907479bcc7cSHerbert Xu 						   "cbc-des-caam",
2908479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2909479bcc7cSHerbert Xu 			},
2910479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2911479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2912479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2913479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2914479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2915479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2916479bcc7cSHerbert Xu 		},
2917479bcc7cSHerbert Xu 		.caam = {
2918479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2919479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2920479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2921479bcc7cSHerbert Xu 		},
2922479bcc7cSHerbert Xu 	},
2923479bcc7cSHerbert Xu 	{
2924479bcc7cSHerbert Xu 		.aead = {
2925479bcc7cSHerbert Xu 			.base = {
2926479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
2927479bcc7cSHerbert Xu 					    "cbc(des)))",
2928479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2929479bcc7cSHerbert Xu 						   "hmac-sha384-cbc-des-caam",
2930479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2931479bcc7cSHerbert Xu 			},
2932479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2933479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2934479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
29358b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2936479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2937479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2938479bcc7cSHerbert Xu 		},
2939479bcc7cSHerbert Xu 		.caam = {
2940479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2941479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2942479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2943479bcc7cSHerbert Xu 			.geniv = true,
2944479bcc7cSHerbert Xu 		},
2945479bcc7cSHerbert Xu 	},
2946479bcc7cSHerbert Xu 	{
2947479bcc7cSHerbert Xu 		.aead = {
2948479bcc7cSHerbert Xu 			.base = {
2949479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),cbc(des))",
2950479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
2951479bcc7cSHerbert Xu 						   "cbc-des-caam",
2952479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2953479bcc7cSHerbert Xu 			},
2954479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2955479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2956479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2957479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2958479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2959479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2960479bcc7cSHerbert Xu 		},
2961479bcc7cSHerbert Xu 		.caam = {
2962479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2963479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2964479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2965479bcc7cSHerbert Xu 		},
2966479bcc7cSHerbert Xu 	},
2967479bcc7cSHerbert Xu 	{
2968479bcc7cSHerbert Xu 		.aead = {
2969479bcc7cSHerbert Xu 			.base = {
2970479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
2971479bcc7cSHerbert Xu 					    "cbc(des)))",
2972479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2973479bcc7cSHerbert Xu 						   "hmac-sha512-cbc-des-caam",
2974479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2975479bcc7cSHerbert Xu 			},
2976479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2977479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2978479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
29798b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2980479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2981479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2982479bcc7cSHerbert Xu 		},
2983479bcc7cSHerbert Xu 		.caam = {
2984479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2985479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2986479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2987479bcc7cSHerbert Xu 			.geniv = true,
2988479bcc7cSHerbert Xu 		},
2989479bcc7cSHerbert Xu 	},
2990479bcc7cSHerbert Xu 	{
2991479bcc7cSHerbert Xu 		.aead = {
2992479bcc7cSHerbert Xu 			.base = {
2993479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),"
2994479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
2995479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2996479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
2997479bcc7cSHerbert Xu 				.cra_blocksize = 1,
2998479bcc7cSHerbert Xu 			},
2999479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3000479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3001479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3002479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3003479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3004479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3005479bcc7cSHerbert Xu 		},
3006479bcc7cSHerbert Xu 		.caam = {
3007479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3008479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3009479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3010479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3011479bcc7cSHerbert Xu 			.rfc3686 = true,
3012479bcc7cSHerbert Xu 		},
3013479bcc7cSHerbert Xu 	},
3014479bcc7cSHerbert Xu 	{
3015479bcc7cSHerbert Xu 		.aead = {
3016479bcc7cSHerbert Xu 			.base = {
3017479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
3018479bcc7cSHerbert Xu 					    "hmac(md5),rfc3686(ctr(aes))))",
3019479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-md5-"
3020479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3021479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3022479bcc7cSHerbert Xu 			},
3023479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3024479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3025479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
30268b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3027479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3028479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3029479bcc7cSHerbert Xu 		},
3030479bcc7cSHerbert Xu 		.caam = {
3031479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3032479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3033479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3034479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3035479bcc7cSHerbert Xu 			.rfc3686 = true,
3036479bcc7cSHerbert Xu 			.geniv = true,
3037479bcc7cSHerbert Xu 		},
3038479bcc7cSHerbert Xu 	},
3039479bcc7cSHerbert Xu 	{
3040479bcc7cSHerbert Xu 		.aead = {
3041479bcc7cSHerbert Xu 			.base = {
3042479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
3043479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3044479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
3045479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3046479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3047479bcc7cSHerbert Xu 			},
3048479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3049479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3050479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3051479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3052479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3053479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3054479bcc7cSHerbert Xu 		},
3055479bcc7cSHerbert Xu 		.caam = {
3056479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3057479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3058479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3059479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3060479bcc7cSHerbert Xu 			.rfc3686 = true,
3061479bcc7cSHerbert Xu 		},
3062479bcc7cSHerbert Xu 	},
3063479bcc7cSHerbert Xu 	{
3064479bcc7cSHerbert Xu 		.aead = {
3065479bcc7cSHerbert Xu 			.base = {
3066479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
3067479bcc7cSHerbert Xu 					    "hmac(sha1),rfc3686(ctr(aes))))",
3068479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha1-"
3069479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3070479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3071479bcc7cSHerbert Xu 			},
3072479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3073479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3074479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
30758b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3076479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3077479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3078479bcc7cSHerbert Xu 		},
3079479bcc7cSHerbert Xu 		.caam = {
3080479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3081479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3082479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3083479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3084479bcc7cSHerbert Xu 			.rfc3686 = true,
3085479bcc7cSHerbert Xu 			.geniv = true,
3086479bcc7cSHerbert Xu 		},
3087479bcc7cSHerbert Xu 	},
3088479bcc7cSHerbert Xu 	{
3089479bcc7cSHerbert Xu 		.aead = {
3090479bcc7cSHerbert Xu 			.base = {
3091479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
3092479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3093479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
3094479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3095479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3096479bcc7cSHerbert Xu 			},
3097479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3098479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3099479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3100479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3101479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3102479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3103479bcc7cSHerbert Xu 		},
3104479bcc7cSHerbert Xu 		.caam = {
3105479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3106479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3107479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3108479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3109479bcc7cSHerbert Xu 			.rfc3686 = true,
3110479bcc7cSHerbert Xu 		},
3111479bcc7cSHerbert Xu 	},
3112479bcc7cSHerbert Xu 	{
3113479bcc7cSHerbert Xu 		.aead = {
3114479bcc7cSHerbert Xu 			.base = {
3115479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
3116479bcc7cSHerbert Xu 					    "hmac(sha224),rfc3686(ctr(aes))))",
3117479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha224-"
3118479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3119479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3120479bcc7cSHerbert Xu 			},
3121479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3122479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3123479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
31248b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3125479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3126479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3127479bcc7cSHerbert Xu 		},
3128479bcc7cSHerbert Xu 		.caam = {
3129479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3130479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3131479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3132479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3133479bcc7cSHerbert Xu 			.rfc3686 = true,
3134479bcc7cSHerbert Xu 			.geniv = true,
3135479bcc7cSHerbert Xu 		},
3136479bcc7cSHerbert Xu 	},
3137479bcc7cSHerbert Xu 	{
3138479bcc7cSHerbert Xu 		.aead = {
3139479bcc7cSHerbert Xu 			.base = {
3140479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
3141479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3142479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
3143479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3144479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3145479bcc7cSHerbert Xu 			},
3146479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3147479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3148479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3149479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3150479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3151479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3152479bcc7cSHerbert Xu 		},
3153479bcc7cSHerbert Xu 		.caam = {
3154479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3155479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3156479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3157479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3158479bcc7cSHerbert Xu 			.rfc3686 = true,
3159479bcc7cSHerbert Xu 		},
3160479bcc7cSHerbert Xu 	},
3161479bcc7cSHerbert Xu 	{
3162479bcc7cSHerbert Xu 		.aead = {
3163479bcc7cSHerbert Xu 			.base = {
3164479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha256),"
3165479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
3166479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha256-"
3167479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3168479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3169479bcc7cSHerbert Xu 			},
3170479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3171479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3172479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
31738b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3174479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3175479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3176479bcc7cSHerbert Xu 		},
3177479bcc7cSHerbert Xu 		.caam = {
3178479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3179479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3180479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3181479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3182479bcc7cSHerbert Xu 			.rfc3686 = true,
3183479bcc7cSHerbert Xu 			.geniv = true,
3184479bcc7cSHerbert Xu 		},
3185479bcc7cSHerbert Xu 	},
3186479bcc7cSHerbert Xu 	{
3187479bcc7cSHerbert Xu 		.aead = {
3188479bcc7cSHerbert Xu 			.base = {
3189479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
3190479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3191479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
3192479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3193479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3194479bcc7cSHerbert Xu 			},
3195479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3196479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3197479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3198479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3199479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3200479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3201479bcc7cSHerbert Xu 		},
3202479bcc7cSHerbert Xu 		.caam = {
3203479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3204479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3205479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3206479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3207479bcc7cSHerbert Xu 			.rfc3686 = true,
3208479bcc7cSHerbert Xu 		},
3209479bcc7cSHerbert Xu 	},
3210479bcc7cSHerbert Xu 	{
3211479bcc7cSHerbert Xu 		.aead = {
3212479bcc7cSHerbert Xu 			.base = {
3213479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha384),"
3214479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
3215479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha384-"
3216479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3217479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3218479bcc7cSHerbert Xu 			},
3219479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3220479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3221479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
32228b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3223479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3224479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3225479bcc7cSHerbert Xu 		},
3226479bcc7cSHerbert Xu 		.caam = {
3227479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3228479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3229479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3230479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3231479bcc7cSHerbert Xu 			.rfc3686 = true,
3232479bcc7cSHerbert Xu 			.geniv = true,
3233479bcc7cSHerbert Xu 		},
3234479bcc7cSHerbert Xu 	},
3235479bcc7cSHerbert Xu 	{
3236479bcc7cSHerbert Xu 		.aead = {
3237479bcc7cSHerbert Xu 			.base = {
3238479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
3239479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3240479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
3241479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3242479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3243479bcc7cSHerbert Xu 			},
3244479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3245479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3246479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3247479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3248479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3249479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3250479bcc7cSHerbert Xu 		},
3251479bcc7cSHerbert Xu 		.caam = {
3252479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3253479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3254479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3255479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3256479bcc7cSHerbert Xu 			.rfc3686 = true,
3257479bcc7cSHerbert Xu 		},
3258479bcc7cSHerbert Xu 	},
3259479bcc7cSHerbert Xu 	{
3260479bcc7cSHerbert Xu 		.aead = {
3261479bcc7cSHerbert Xu 			.base = {
3262479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha512),"
3263479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
3264479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha512-"
3265479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3266479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3267479bcc7cSHerbert Xu 			},
3268479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3269479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3270479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
32718b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3272479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3273479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3274479bcc7cSHerbert Xu 		},
3275479bcc7cSHerbert Xu 		.caam = {
3276479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3277479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3278479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3279479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3280479bcc7cSHerbert Xu 			.rfc3686 = true,
3281479bcc7cSHerbert Xu 			.geniv = true,
3282479bcc7cSHerbert Xu 		},
3283479bcc7cSHerbert Xu 	},
3284d6bbd4eeSHoria Geantă 	{
3285d6bbd4eeSHoria Geantă 		.aead = {
3286d6bbd4eeSHoria Geantă 			.base = {
3287d6bbd4eeSHoria Geantă 				.cra_name = "rfc7539(chacha20,poly1305)",
3288d6bbd4eeSHoria Geantă 				.cra_driver_name = "rfc7539-chacha20-poly1305-"
3289d6bbd4eeSHoria Geantă 						   "caam",
3290d6bbd4eeSHoria Geantă 				.cra_blocksize = 1,
3291d6bbd4eeSHoria Geantă 			},
3292d6bbd4eeSHoria Geantă 			.setkey = chachapoly_setkey,
3293d6bbd4eeSHoria Geantă 			.setauthsize = chachapoly_setauthsize,
3294d6bbd4eeSHoria Geantă 			.encrypt = chachapoly_encrypt,
3295d6bbd4eeSHoria Geantă 			.decrypt = chachapoly_decrypt,
3296d6bbd4eeSHoria Geantă 			.ivsize = CHACHAPOLY_IV_SIZE,
3297d6bbd4eeSHoria Geantă 			.maxauthsize = POLY1305_DIGEST_SIZE,
3298d6bbd4eeSHoria Geantă 		},
3299d6bbd4eeSHoria Geantă 		.caam = {
3300d6bbd4eeSHoria Geantă 			.class1_alg_type = OP_ALG_ALGSEL_CHACHA20 |
3301d6bbd4eeSHoria Geantă 					   OP_ALG_AAI_AEAD,
3302d6bbd4eeSHoria Geantă 			.class2_alg_type = OP_ALG_ALGSEL_POLY1305 |
3303d6bbd4eeSHoria Geantă 					   OP_ALG_AAI_AEAD,
3304d6bbd4eeSHoria Geantă 		},
3305d6bbd4eeSHoria Geantă 	},
3306d6bbd4eeSHoria Geantă 	{
3307d6bbd4eeSHoria Geantă 		.aead = {
3308d6bbd4eeSHoria Geantă 			.base = {
3309d6bbd4eeSHoria Geantă 				.cra_name = "rfc7539esp(chacha20,poly1305)",
3310d6bbd4eeSHoria Geantă 				.cra_driver_name = "rfc7539esp-chacha20-"
3311d6bbd4eeSHoria Geantă 						   "poly1305-caam",
3312d6bbd4eeSHoria Geantă 				.cra_blocksize = 1,
3313d6bbd4eeSHoria Geantă 			},
3314d6bbd4eeSHoria Geantă 			.setkey = chachapoly_setkey,
3315d6bbd4eeSHoria Geantă 			.setauthsize = chachapoly_setauthsize,
3316d6bbd4eeSHoria Geantă 			.encrypt = chachapoly_encrypt,
3317d6bbd4eeSHoria Geantă 			.decrypt = chachapoly_decrypt,
3318d6bbd4eeSHoria Geantă 			.ivsize = 8,
3319d6bbd4eeSHoria Geantă 			.maxauthsize = POLY1305_DIGEST_SIZE,
3320d6bbd4eeSHoria Geantă 		},
3321d6bbd4eeSHoria Geantă 		.caam = {
3322d6bbd4eeSHoria Geantă 			.class1_alg_type = OP_ALG_ALGSEL_CHACHA20 |
3323d6bbd4eeSHoria Geantă 					   OP_ALG_AAI_AEAD,
3324d6bbd4eeSHoria Geantă 			.class2_alg_type = OP_ALG_ALGSEL_POLY1305 |
3325d6bbd4eeSHoria Geantă 					   OP_ALG_AAI_AEAD,
3326d6bbd4eeSHoria Geantă 		},
3327d6bbd4eeSHoria Geantă 	},
3328f2147b88SHerbert Xu };
3329f2147b88SHerbert Xu 
33307e0880b9SHoria Geantă static int caam_init_common(struct caam_ctx *ctx, struct caam_alg_entry *caam,
33317e0880b9SHoria Geantă 			    bool uses_dkp)
3332f2147b88SHerbert Xu {
3333bbf22344SHoria Geantă 	dma_addr_t dma_addr;
33347e0880b9SHoria Geantă 	struct caam_drv_private *priv;
3335bbf22344SHoria Geantă 
3336f2147b88SHerbert Xu 	ctx->jrdev = caam_jr_alloc();
3337f2147b88SHerbert Xu 	if (IS_ERR(ctx->jrdev)) {
3338f2147b88SHerbert Xu 		pr_err("Job Ring Device allocation for transform failed\n");
3339f2147b88SHerbert Xu 		return PTR_ERR(ctx->jrdev);
3340f2147b88SHerbert Xu 	}
3341f2147b88SHerbert Xu 
33427e0880b9SHoria Geantă 	priv = dev_get_drvdata(ctx->jrdev->parent);
33437e0880b9SHoria Geantă 	if (priv->era >= 6 && uses_dkp)
33447e0880b9SHoria Geantă 		ctx->dir = DMA_BIDIRECTIONAL;
33457e0880b9SHoria Geantă 	else
33467e0880b9SHoria Geantă 		ctx->dir = DMA_TO_DEVICE;
33477e0880b9SHoria Geantă 
3348bbf22344SHoria Geantă 	dma_addr = dma_map_single_attrs(ctx->jrdev, ctx->sh_desc_enc,
3349bbf22344SHoria Geantă 					offsetof(struct caam_ctx,
3350bbf22344SHoria Geantă 						 sh_desc_enc_dma),
33517e0880b9SHoria Geantă 					ctx->dir, DMA_ATTR_SKIP_CPU_SYNC);
3352bbf22344SHoria Geantă 	if (dma_mapping_error(ctx->jrdev, dma_addr)) {
3353bbf22344SHoria Geantă 		dev_err(ctx->jrdev, "unable to map key, shared descriptors\n");
3354bbf22344SHoria Geantă 		caam_jr_free(ctx->jrdev);
3355bbf22344SHoria Geantă 		return -ENOMEM;
3356bbf22344SHoria Geantă 	}
3357bbf22344SHoria Geantă 
3358bbf22344SHoria Geantă 	ctx->sh_desc_enc_dma = dma_addr;
3359bbf22344SHoria Geantă 	ctx->sh_desc_dec_dma = dma_addr + offsetof(struct caam_ctx,
3360bbf22344SHoria Geantă 						   sh_desc_dec);
3361bbf22344SHoria Geantă 	ctx->key_dma = dma_addr + offsetof(struct caam_ctx, key);
3362bbf22344SHoria Geantă 
3363f2147b88SHerbert Xu 	/* copy descriptor header template value */
3364db57656bSHoria Geantă 	ctx->cdata.algtype = OP_TYPE_CLASS1_ALG | caam->class1_alg_type;
3365db57656bSHoria Geantă 	ctx->adata.algtype = OP_TYPE_CLASS2_ALG | caam->class2_alg_type;
3366f2147b88SHerbert Xu 
3367f2147b88SHerbert Xu 	return 0;
3368f2147b88SHerbert Xu }
3369f2147b88SHerbert Xu 
33705ca7badbSHoria Geantă static int caam_cra_init(struct crypto_skcipher *tfm)
33718e8ec596SKim Phillips {
33725ca7badbSHoria Geantă 	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
33735ca7badbSHoria Geantă 	struct caam_skcipher_alg *caam_alg =
33745ca7badbSHoria Geantă 		container_of(alg, typeof(*caam_alg), skcipher);
33758e8ec596SKim Phillips 
33765ca7badbSHoria Geantă 	return caam_init_common(crypto_skcipher_ctx(tfm), &caam_alg->caam,
33775ca7badbSHoria Geantă 				false);
3378cfc6f11bSRuchika Gupta }
33798e8ec596SKim Phillips 
3380f2147b88SHerbert Xu static int caam_aead_init(struct crypto_aead *tfm)
33818e8ec596SKim Phillips {
3382f2147b88SHerbert Xu 	struct aead_alg *alg = crypto_aead_alg(tfm);
3383f2147b88SHerbert Xu 	struct caam_aead_alg *caam_alg =
3384f2147b88SHerbert Xu 		 container_of(alg, struct caam_aead_alg, aead);
3385f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(tfm);
33868e8ec596SKim Phillips 
33877e0880b9SHoria Geantă 	return caam_init_common(ctx, &caam_alg->caam,
33887e0880b9SHoria Geantă 				alg->setkey == aead_setkey);
3389f2147b88SHerbert Xu }
3390f2147b88SHerbert Xu 
3391f2147b88SHerbert Xu static void caam_exit_common(struct caam_ctx *ctx)
3392f2147b88SHerbert Xu {
3393bbf22344SHoria Geantă 	dma_unmap_single_attrs(ctx->jrdev, ctx->sh_desc_enc_dma,
3394bbf22344SHoria Geantă 			       offsetof(struct caam_ctx, sh_desc_enc_dma),
33957e0880b9SHoria Geantă 			       ctx->dir, DMA_ATTR_SKIP_CPU_SYNC);
3396cfc6f11bSRuchika Gupta 	caam_jr_free(ctx->jrdev);
33978e8ec596SKim Phillips }
33988e8ec596SKim Phillips 
33995ca7badbSHoria Geantă static void caam_cra_exit(struct crypto_skcipher *tfm)
3400f2147b88SHerbert Xu {
34015ca7badbSHoria Geantă 	caam_exit_common(crypto_skcipher_ctx(tfm));
3402f2147b88SHerbert Xu }
3403f2147b88SHerbert Xu 
3404f2147b88SHerbert Xu static void caam_aead_exit(struct crypto_aead *tfm)
3405f2147b88SHerbert Xu {
3406f2147b88SHerbert Xu 	caam_exit_common(crypto_aead_ctx(tfm));
3407f2147b88SHerbert Xu }
3408f2147b88SHerbert Xu 
34098e8ec596SKim Phillips static void __exit caam_algapi_exit(void)
34108e8ec596SKim Phillips {
3411f2147b88SHerbert Xu 	int i;
3412f2147b88SHerbert Xu 
3413f2147b88SHerbert Xu 	for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
3414f2147b88SHerbert Xu 		struct caam_aead_alg *t_alg = driver_aeads + i;
3415f2147b88SHerbert Xu 
3416f2147b88SHerbert Xu 		if (t_alg->registered)
3417f2147b88SHerbert Xu 			crypto_unregister_aead(&t_alg->aead);
3418f2147b88SHerbert Xu 	}
34198e8ec596SKim Phillips 
34205ca7badbSHoria Geantă 	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
34215ca7badbSHoria Geantă 		struct caam_skcipher_alg *t_alg = driver_algs + i;
34228e8ec596SKim Phillips 
34235ca7badbSHoria Geantă 		if (t_alg->registered)
34245ca7badbSHoria Geantă 			crypto_unregister_skcipher(&t_alg->skcipher);
34258e8ec596SKim Phillips 	}
34268e8ec596SKim Phillips }
34278e8ec596SKim Phillips 
34285ca7badbSHoria Geantă static void caam_skcipher_alg_init(struct caam_skcipher_alg *t_alg)
34298e8ec596SKim Phillips {
34305ca7badbSHoria Geantă 	struct skcipher_alg *alg = &t_alg->skcipher;
34318e8ec596SKim Phillips 
34325ca7badbSHoria Geantă 	alg->base.cra_module = THIS_MODULE;
34335ca7badbSHoria Geantă 	alg->base.cra_priority = CAAM_CRA_PRIORITY;
34345ca7badbSHoria Geantă 	alg->base.cra_ctxsize = sizeof(struct caam_ctx);
34355ca7badbSHoria Geantă 	alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY;
34368e8ec596SKim Phillips 
34375ca7badbSHoria Geantă 	alg->init = caam_cra_init;
34385ca7badbSHoria Geantă 	alg->exit = caam_cra_exit;
34398e8ec596SKim Phillips }
34408e8ec596SKim Phillips 
3441f2147b88SHerbert Xu static void caam_aead_alg_init(struct caam_aead_alg *t_alg)
3442f2147b88SHerbert Xu {
3443f2147b88SHerbert Xu 	struct aead_alg *alg = &t_alg->aead;
3444f2147b88SHerbert Xu 
3445f2147b88SHerbert Xu 	alg->base.cra_module = THIS_MODULE;
3446f2147b88SHerbert Xu 	alg->base.cra_priority = CAAM_CRA_PRIORITY;
3447f2147b88SHerbert Xu 	alg->base.cra_ctxsize = sizeof(struct caam_ctx);
34485e4b8c1fSHerbert Xu 	alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY;
3449f2147b88SHerbert Xu 
3450f2147b88SHerbert Xu 	alg->init = caam_aead_init;
3451f2147b88SHerbert Xu 	alg->exit = caam_aead_exit;
3452f2147b88SHerbert Xu }
3453f2147b88SHerbert Xu 
34548e8ec596SKim Phillips static int __init caam_algapi_init(void)
34558e8ec596SKim Phillips {
345635af6403SRuchika Gupta 	struct device_node *dev_node;
345735af6403SRuchika Gupta 	struct platform_device *pdev;
345835af6403SRuchika Gupta 	struct device *ctrldev;
3459bf83490eSVictoria Milhoan 	struct caam_drv_private *priv;
34608e8ec596SKim Phillips 	int i = 0, err = 0;
3461d6bbd4eeSHoria Geantă 	u32 aes_vid, aes_inst, des_inst, md_vid, md_inst, ccha_inst, ptha_inst;
3462eaed71a4SIuliana Prodan 	u32 arc4_inst;
3463bf83490eSVictoria Milhoan 	unsigned int md_limit = SHA512_DIGEST_SIZE;
3464f2147b88SHerbert Xu 	bool registered = false;
34658e8ec596SKim Phillips 
346635af6403SRuchika Gupta 	dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
346735af6403SRuchika Gupta 	if (!dev_node) {
346835af6403SRuchika Gupta 		dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
346935af6403SRuchika Gupta 		if (!dev_node)
347035af6403SRuchika Gupta 			return -ENODEV;
347135af6403SRuchika Gupta 	}
347235af6403SRuchika Gupta 
347335af6403SRuchika Gupta 	pdev = of_find_device_by_node(dev_node);
347435af6403SRuchika Gupta 	if (!pdev) {
347535af6403SRuchika Gupta 		of_node_put(dev_node);
347635af6403SRuchika Gupta 		return -ENODEV;
347735af6403SRuchika Gupta 	}
347835af6403SRuchika Gupta 
347935af6403SRuchika Gupta 	ctrldev = &pdev->dev;
348035af6403SRuchika Gupta 	priv = dev_get_drvdata(ctrldev);
348135af6403SRuchika Gupta 	of_node_put(dev_node);
348235af6403SRuchika Gupta 
348335af6403SRuchika Gupta 	/*
348435af6403SRuchika Gupta 	 * If priv is NULL, it's probably because the caam driver wasn't
348535af6403SRuchika Gupta 	 * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
348635af6403SRuchika Gupta 	 */
348735af6403SRuchika Gupta 	if (!priv)
348835af6403SRuchika Gupta 		return -ENODEV;
348935af6403SRuchika Gupta 
349035af6403SRuchika Gupta 
3491bf83490eSVictoria Milhoan 	/*
3492bf83490eSVictoria Milhoan 	 * Register crypto algorithms the device supports.
3493bf83490eSVictoria Milhoan 	 * First, detect presence and attributes of DES, AES, and MD blocks.
3494bf83490eSVictoria Milhoan 	 */
3495d239b10dSHoria Geantă 	if (priv->era < 10) {
3496d239b10dSHoria Geantă 		u32 cha_vid, cha_inst;
3497d239b10dSHoria Geantă 
3498bf83490eSVictoria Milhoan 		cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
3499d239b10dSHoria Geantă 		aes_vid = cha_vid & CHA_ID_LS_AES_MASK;
3500d239b10dSHoria Geantă 		md_vid = (cha_vid & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
3501d239b10dSHoria Geantă 
3502bf83490eSVictoria Milhoan 		cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
3503d239b10dSHoria Geantă 		des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >>
3504d239b10dSHoria Geantă 			   CHA_ID_LS_DES_SHIFT;
3505d239b10dSHoria Geantă 		aes_inst = cha_inst & CHA_ID_LS_AES_MASK;
3506bf83490eSVictoria Milhoan 		md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
3507eaed71a4SIuliana Prodan 		arc4_inst = (cha_inst & CHA_ID_LS_ARC4_MASK) >>
3508eaed71a4SIuliana Prodan 			    CHA_ID_LS_ARC4_SHIFT;
3509d6bbd4eeSHoria Geantă 		ccha_inst = 0;
3510d6bbd4eeSHoria Geantă 		ptha_inst = 0;
3511d239b10dSHoria Geantă 	} else {
3512d239b10dSHoria Geantă 		u32 aesa, mdha;
3513d239b10dSHoria Geantă 
3514d239b10dSHoria Geantă 		aesa = rd_reg32(&priv->ctrl->vreg.aesa);
3515d239b10dSHoria Geantă 		mdha = rd_reg32(&priv->ctrl->vreg.mdha);
3516d239b10dSHoria Geantă 
3517d239b10dSHoria Geantă 		aes_vid = (aesa & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
3518d239b10dSHoria Geantă 		md_vid = (mdha & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
3519d239b10dSHoria Geantă 
3520d239b10dSHoria Geantă 		des_inst = rd_reg32(&priv->ctrl->vreg.desa) & CHA_VER_NUM_MASK;
3521d239b10dSHoria Geantă 		aes_inst = aesa & CHA_VER_NUM_MASK;
3522d239b10dSHoria Geantă 		md_inst = mdha & CHA_VER_NUM_MASK;
3523d6bbd4eeSHoria Geantă 		ccha_inst = rd_reg32(&priv->ctrl->vreg.ccha) & CHA_VER_NUM_MASK;
3524d6bbd4eeSHoria Geantă 		ptha_inst = rd_reg32(&priv->ctrl->vreg.ptha) & CHA_VER_NUM_MASK;
3525eaed71a4SIuliana Prodan 		arc4_inst = rd_reg32(&priv->ctrl->vreg.afha) & CHA_VER_NUM_MASK;
3526d239b10dSHoria Geantă 	}
35278e8ec596SKim Phillips 
3528bf83490eSVictoria Milhoan 	/* If MD is present, limit digest size based on LP256 */
3529d239b10dSHoria Geantă 	if (md_inst && md_vid  == CHA_VER_VID_MD_LP256)
3530bf83490eSVictoria Milhoan 		md_limit = SHA256_DIGEST_SIZE;
3531bf83490eSVictoria Milhoan 
3532bf83490eSVictoria Milhoan 	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
35335ca7badbSHoria Geantă 		struct caam_skcipher_alg *t_alg = driver_algs + i;
35345ca7badbSHoria Geantă 		u32 alg_sel = t_alg->caam.class1_alg_type & OP_ALG_ALGSEL_MASK;
3535bf83490eSVictoria Milhoan 
3536bf83490eSVictoria Milhoan 		/* Skip DES algorithms if not supported by device */
3537bf83490eSVictoria Milhoan 		if (!des_inst &&
3538bf83490eSVictoria Milhoan 		    ((alg_sel == OP_ALG_ALGSEL_3DES) ||
3539bf83490eSVictoria Milhoan 		     (alg_sel == OP_ALG_ALGSEL_DES)))
3540bf83490eSVictoria Milhoan 				continue;
3541bf83490eSVictoria Milhoan 
3542bf83490eSVictoria Milhoan 		/* Skip AES algorithms if not supported by device */
3543bf83490eSVictoria Milhoan 		if (!aes_inst && (alg_sel == OP_ALG_ALGSEL_AES))
3544bf83490eSVictoria Milhoan 				continue;
3545bf83490eSVictoria Milhoan 
3546eaed71a4SIuliana Prodan 		/* Skip ARC4 algorithms if not supported by device */
3547eaed71a4SIuliana Prodan 		if (!arc4_inst && alg_sel == OP_ALG_ALGSEL_ARC4)
3548eaed71a4SIuliana Prodan 			continue;
3549eaed71a4SIuliana Prodan 
355083d2c9a9SSven Ebenfeld 		/*
355183d2c9a9SSven Ebenfeld 		 * Check support for AES modes not available
355283d2c9a9SSven Ebenfeld 		 * on LP devices.
355383d2c9a9SSven Ebenfeld 		 */
3554d239b10dSHoria Geantă 		if (aes_vid == CHA_VER_VID_AES_LP &&
3555d239b10dSHoria Geantă 		    (t_alg->caam.class1_alg_type & OP_ALG_AAI_MASK) ==
355683d2c9a9SSven Ebenfeld 		    OP_ALG_AAI_XTS)
355783d2c9a9SSven Ebenfeld 			continue;
355883d2c9a9SSven Ebenfeld 
35595ca7badbSHoria Geantă 		caam_skcipher_alg_init(t_alg);
35608e8ec596SKim Phillips 
35615ca7badbSHoria Geantă 		err = crypto_register_skcipher(&t_alg->skcipher);
35628e8ec596SKim Phillips 		if (err) {
3563cfc6f11bSRuchika Gupta 			pr_warn("%s alg registration failed\n",
35645ca7badbSHoria Geantă 				t_alg->skcipher.base.cra_driver_name);
3565f2147b88SHerbert Xu 			continue;
35668e8ec596SKim Phillips 		}
3567f2147b88SHerbert Xu 
35685ca7badbSHoria Geantă 		t_alg->registered = true;
3569f2147b88SHerbert Xu 		registered = true;
3570f2147b88SHerbert Xu 	}
3571f2147b88SHerbert Xu 
3572f2147b88SHerbert Xu 	for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
3573f2147b88SHerbert Xu 		struct caam_aead_alg *t_alg = driver_aeads + i;
3574bf83490eSVictoria Milhoan 		u32 c1_alg_sel = t_alg->caam.class1_alg_type &
3575bf83490eSVictoria Milhoan 				 OP_ALG_ALGSEL_MASK;
3576bf83490eSVictoria Milhoan 		u32 c2_alg_sel = t_alg->caam.class2_alg_type &
3577bf83490eSVictoria Milhoan 				 OP_ALG_ALGSEL_MASK;
3578bf83490eSVictoria Milhoan 		u32 alg_aai = t_alg->caam.class1_alg_type & OP_ALG_AAI_MASK;
3579bf83490eSVictoria Milhoan 
3580bf83490eSVictoria Milhoan 		/* Skip DES algorithms if not supported by device */
3581bf83490eSVictoria Milhoan 		if (!des_inst &&
3582bf83490eSVictoria Milhoan 		    ((c1_alg_sel == OP_ALG_ALGSEL_3DES) ||
3583bf83490eSVictoria Milhoan 		     (c1_alg_sel == OP_ALG_ALGSEL_DES)))
3584bf83490eSVictoria Milhoan 				continue;
3585bf83490eSVictoria Milhoan 
3586bf83490eSVictoria Milhoan 		/* Skip AES algorithms if not supported by device */
3587bf83490eSVictoria Milhoan 		if (!aes_inst && (c1_alg_sel == OP_ALG_ALGSEL_AES))
3588bf83490eSVictoria Milhoan 				continue;
3589bf83490eSVictoria Milhoan 
3590d6bbd4eeSHoria Geantă 		/* Skip CHACHA20 algorithms if not supported by device */
3591d6bbd4eeSHoria Geantă 		if (c1_alg_sel == OP_ALG_ALGSEL_CHACHA20 && !ccha_inst)
3592d6bbd4eeSHoria Geantă 			continue;
3593d6bbd4eeSHoria Geantă 
3594d6bbd4eeSHoria Geantă 		/* Skip POLY1305 algorithms if not supported by device */
3595d6bbd4eeSHoria Geantă 		if (c2_alg_sel == OP_ALG_ALGSEL_POLY1305 && !ptha_inst)
3596d6bbd4eeSHoria Geantă 			continue;
3597d6bbd4eeSHoria Geantă 
3598bf83490eSVictoria Milhoan 		/*
3599bf83490eSVictoria Milhoan 		 * Check support for AES algorithms not available
3600bf83490eSVictoria Milhoan 		 * on LP devices.
3601bf83490eSVictoria Milhoan 		 */
3602d239b10dSHoria Geantă 		if (aes_vid  == CHA_VER_VID_AES_LP && alg_aai == OP_ALG_AAI_GCM)
3603bf83490eSVictoria Milhoan 			continue;
3604bf83490eSVictoria Milhoan 
3605bf83490eSVictoria Milhoan 		/*
3606bf83490eSVictoria Milhoan 		 * Skip algorithms requiring message digests
3607bf83490eSVictoria Milhoan 		 * if MD or MD size is not supported by device.
3608bf83490eSVictoria Milhoan 		 */
36092dd3fde4SHoria Geantă 		if (is_mdha(c2_alg_sel) &&
3610d6bbd4eeSHoria Geantă 		    (!md_inst || t_alg->aead.maxauthsize > md_limit))
3611bf83490eSVictoria Milhoan 			continue;
3612f2147b88SHerbert Xu 
3613f2147b88SHerbert Xu 		caam_aead_alg_init(t_alg);
3614f2147b88SHerbert Xu 
3615f2147b88SHerbert Xu 		err = crypto_register_aead(&t_alg->aead);
3616f2147b88SHerbert Xu 		if (err) {
3617f2147b88SHerbert Xu 			pr_warn("%s alg registration failed\n",
3618f2147b88SHerbert Xu 				t_alg->aead.base.cra_driver_name);
3619f2147b88SHerbert Xu 			continue;
3620f2147b88SHerbert Xu 		}
3621f2147b88SHerbert Xu 
3622f2147b88SHerbert Xu 		t_alg->registered = true;
3623f2147b88SHerbert Xu 		registered = true;
3624f2147b88SHerbert Xu 	}
3625f2147b88SHerbert Xu 
3626f2147b88SHerbert Xu 	if (registered)
3627cfc6f11bSRuchika Gupta 		pr_info("caam algorithms registered in /proc/crypto\n");
36288e8ec596SKim Phillips 
36298e8ec596SKim Phillips 	return err;
36308e8ec596SKim Phillips }
36318e8ec596SKim Phillips 
36328e8ec596SKim Phillips module_init(caam_algapi_init);
36338e8ec596SKim Phillips module_exit(caam_algapi_exit);
36348e8ec596SKim Phillips 
36358e8ec596SKim Phillips MODULE_LICENSE("GPL");
36368e8ec596SKim Phillips MODULE_DESCRIPTION("FSL CAAM support for crypto API");
36378e8ec596SKim Phillips MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
3638