xref: /openbmc/linux/drivers/crypto/caam/caamalg.c (revision c91f7348)
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"
59ee38767fSIuliana Prodan #include <crypto/engine.h>
60c91f7348SAndrei Botila #include <crypto/xts.h>
619d9b14dbSAndrei Botila #include <asm/unaligned.h>
628e8ec596SKim Phillips 
638e8ec596SKim Phillips /*
648e8ec596SKim Phillips  * crypto alg
658e8ec596SKim Phillips  */
668e8ec596SKim Phillips #define CAAM_CRA_PRIORITY		3000
678e8ec596SKim Phillips /* max key is sum of AES_MAX_KEY_SIZE, max split key size */
688e8ec596SKim Phillips #define CAAM_MAX_KEY_SIZE		(AES_MAX_KEY_SIZE + \
69daebc465SCatalin Vasile 					 CTR_RFC3686_NONCE_SIZE + \
708e8ec596SKim Phillips 					 SHA512_DIGEST_SIZE * 2)
718e8ec596SKim Phillips 
72f2147b88SHerbert Xu #define AEAD_DESC_JOB_IO_LEN		(DESC_JOB_IO_LEN + CAAM_CMD_SZ * 2)
73f2147b88SHerbert Xu #define GCM_DESC_JOB_IO_LEN		(AEAD_DESC_JOB_IO_LEN + \
74f2147b88SHerbert Xu 					 CAAM_CMD_SZ * 4)
75479bcc7cSHerbert Xu #define AUTHENC_DESC_JOB_IO_LEN		(AEAD_DESC_JOB_IO_LEN + \
76479bcc7cSHerbert Xu 					 CAAM_CMD_SZ * 5)
77f2147b88SHerbert Xu 
78d6bbd4eeSHoria Geantă #define CHACHAPOLY_DESC_JOB_IO_LEN	(AEAD_DESC_JOB_IO_LEN + CAAM_CMD_SZ * 6)
79d6bbd4eeSHoria Geantă 
801a3daadcSAndrey Smirnov #define DESC_MAX_USED_BYTES		(CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN_MIN)
8187e51b07SHerbert Xu #define DESC_MAX_USED_LEN		(DESC_MAX_USED_BYTES / CAAM_CMD_SZ)
824427b1b4SKim Phillips 
83479bcc7cSHerbert Xu struct caam_alg_entry {
84479bcc7cSHerbert Xu 	int class1_alg_type;
85479bcc7cSHerbert Xu 	int class2_alg_type;
86479bcc7cSHerbert Xu 	bool rfc3686;
87479bcc7cSHerbert Xu 	bool geniv;
8824586b5fSHerbert Xu 	bool nodkp;
89479bcc7cSHerbert Xu };
90479bcc7cSHerbert Xu 
91479bcc7cSHerbert Xu struct caam_aead_alg {
92479bcc7cSHerbert Xu 	struct aead_alg aead;
93479bcc7cSHerbert Xu 	struct caam_alg_entry caam;
94479bcc7cSHerbert Xu 	bool registered;
95479bcc7cSHerbert Xu };
96479bcc7cSHerbert Xu 
975ca7badbSHoria Geantă struct caam_skcipher_alg {
985ca7badbSHoria Geantă 	struct skcipher_alg skcipher;
995ca7badbSHoria Geantă 	struct caam_alg_entry caam;
1005ca7badbSHoria Geantă 	bool registered;
1015ca7badbSHoria Geantă };
1025ca7badbSHoria Geantă 
103acdca31dSYuan Kang /*
1048e8ec596SKim Phillips  * per-session context
1058e8ec596SKim Phillips  */
1068e8ec596SKim Phillips struct caam_ctx {
107ee38767fSIuliana Prodan 	struct crypto_engine_ctx enginectx;
1081acebad3SYuan Kang 	u32 sh_desc_enc[DESC_MAX_USED_LEN];
1091acebad3SYuan Kang 	u32 sh_desc_dec[DESC_MAX_USED_LEN];
110bbf22344SHoria Geantă 	u8 key[CAAM_MAX_KEY_SIZE];
1111acebad3SYuan Kang 	dma_addr_t sh_desc_enc_dma;
1121acebad3SYuan Kang 	dma_addr_t sh_desc_dec_dma;
113885e9e2fSYuan Kang 	dma_addr_t key_dma;
1147e0880b9SHoria Geantă 	enum dma_data_direction dir;
115bbf22344SHoria Geantă 	struct device *jrdev;
116db57656bSHoria Geantă 	struct alginfo adata;
117db57656bSHoria Geantă 	struct alginfo cdata;
1188e8ec596SKim Phillips 	unsigned int authsize;
119c91f7348SAndrei Botila 	bool xts_key_fallback;
1209d9b14dbSAndrei Botila 	struct crypto_skcipher *fallback;
1218e8ec596SKim Phillips };
1228e8ec596SKim Phillips 
123ee38767fSIuliana Prodan struct caam_skcipher_req_ctx {
124ee38767fSIuliana Prodan 	struct skcipher_edesc *edesc;
1259d9b14dbSAndrei Botila 	struct skcipher_request fallback_req;
126ee38767fSIuliana Prodan };
127ee38767fSIuliana Prodan 
1281c240226SIuliana Prodan struct caam_aead_req_ctx {
1291c240226SIuliana Prodan 	struct aead_edesc *edesc;
1301c240226SIuliana Prodan };
1311c240226SIuliana Prodan 
132ae4a825fSHoria Geanta static int aead_null_set_sh_desc(struct crypto_aead *aead)
133ae4a825fSHoria Geanta {
134ae4a825fSHoria Geanta 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
135ae4a825fSHoria Geanta 	struct device *jrdev = ctx->jrdev;
1367e0880b9SHoria Geantă 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
137ae4a825fSHoria Geanta 	u32 *desc;
1384cbe79ccSHoria Geantă 	int rem_bytes = CAAM_DESC_BYTES_MAX - AEAD_DESC_JOB_IO_LEN -
1394cbe79ccSHoria Geantă 			ctx->adata.keylen_pad;
140ae4a825fSHoria Geanta 
141ae4a825fSHoria Geanta 	/*
142ae4a825fSHoria Geanta 	 * Job Descriptor and Shared Descriptors
143ae4a825fSHoria Geanta 	 * must all fit into the 64-word Descriptor h/w Buffer
144ae4a825fSHoria Geanta 	 */
1454cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_AEAD_NULL_ENC_LEN) {
146db57656bSHoria Geantă 		ctx->adata.key_inline = true;
1479c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
148db57656bSHoria Geantă 	} else {
149db57656bSHoria Geantă 		ctx->adata.key_inline = false;
1509c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
151db57656bSHoria Geantă 	}
152ae4a825fSHoria Geanta 
153479bcc7cSHerbert Xu 	/* aead_encrypt shared descriptor */
154ae4a825fSHoria Geanta 	desc = ctx->sh_desc_enc;
1557e0880b9SHoria Geantă 	cnstr_shdsc_aead_null_encap(desc, &ctx->adata, ctx->authsize,
1567e0880b9SHoria Geantă 				    ctrlpriv->era);
157bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
1587e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
159ae4a825fSHoria Geanta 
160ae4a825fSHoria Geanta 	/*
161ae4a825fSHoria Geanta 	 * Job Descriptor and Shared Descriptors
162ae4a825fSHoria Geanta 	 * must all fit into the 64-word Descriptor h/w Buffer
163ae4a825fSHoria Geanta 	 */
1644cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_AEAD_NULL_DEC_LEN) {
165db57656bSHoria Geantă 		ctx->adata.key_inline = true;
1669c0bc511SArnd Bergmann 		ctx->adata.key_virt = ctx->key;
167db57656bSHoria Geantă 	} else {
168db57656bSHoria Geantă 		ctx->adata.key_inline = false;
1699c0bc511SArnd Bergmann 		ctx->adata.key_dma = ctx->key_dma;
170db57656bSHoria Geantă 	}
171ae4a825fSHoria Geanta 
172479bcc7cSHerbert Xu 	/* aead_decrypt shared descriptor */
1738cea7b66SHoria Geantă 	desc = ctx->sh_desc_dec;
1747e0880b9SHoria Geantă 	cnstr_shdsc_aead_null_decap(desc, &ctx->adata, ctx->authsize,
1757e0880b9SHoria Geantă 				    ctrlpriv->era);
176bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
1777e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
178ae4a825fSHoria Geanta 
179ae4a825fSHoria Geanta 	return 0;
180ae4a825fSHoria Geanta }
181ae4a825fSHoria Geanta 
1821acebad3SYuan Kang static int aead_set_sh_desc(struct crypto_aead *aead)
1831acebad3SYuan Kang {
184479bcc7cSHerbert Xu 	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
185479bcc7cSHerbert Xu 						 struct caam_aead_alg, aead);
186add86d55SHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
1871acebad3SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1881acebad3SYuan Kang 	struct device *jrdev = ctx->jrdev;
1897e0880b9SHoria Geantă 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
190daebc465SCatalin Vasile 	u32 ctx1_iv_off = 0;
1918cea7b66SHoria Geantă 	u32 *desc, *nonce = NULL;
1924cbe79ccSHoria Geantă 	u32 inl_mask;
1934cbe79ccSHoria Geantă 	unsigned int data_len[2];
194db57656bSHoria Geantă 	const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
195daebc465SCatalin Vasile 			       OP_ALG_AAI_CTR_MOD128);
196479bcc7cSHerbert Xu 	const bool is_rfc3686 = alg->caam.rfc3686;
1971acebad3SYuan Kang 
1982fdea258SHoria Geantă 	if (!ctx->authsize)
1992fdea258SHoria Geantă 		return 0;
2002fdea258SHoria Geantă 
201ae4a825fSHoria Geanta 	/* NULL encryption / decryption */
202db57656bSHoria Geantă 	if (!ctx->cdata.keylen)
203ae4a825fSHoria Geanta 		return aead_null_set_sh_desc(aead);
204ae4a825fSHoria Geanta 
2051acebad3SYuan Kang 	/*
206daebc465SCatalin Vasile 	 * AES-CTR needs to load IV in CONTEXT1 reg
207daebc465SCatalin Vasile 	 * at an offset of 128bits (16bytes)
208daebc465SCatalin Vasile 	 * CONTEXT1[255:128] = IV
209daebc465SCatalin Vasile 	 */
210daebc465SCatalin Vasile 	if (ctr_mode)
211daebc465SCatalin Vasile 		ctx1_iv_off = 16;
212daebc465SCatalin Vasile 
213daebc465SCatalin Vasile 	/*
214daebc465SCatalin Vasile 	 * RFC3686 specific:
215daebc465SCatalin Vasile 	 *	CONTEXT1[255:128] = {NONCE, IV, COUNTER}
216daebc465SCatalin Vasile 	 */
2178cea7b66SHoria Geantă 	if (is_rfc3686) {
218daebc465SCatalin Vasile 		ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
2198cea7b66SHoria Geantă 		nonce = (u32 *)((void *)ctx->key + ctx->adata.keylen_pad +
2208cea7b66SHoria Geantă 				ctx->cdata.keylen - CTR_RFC3686_NONCE_SIZE);
2218cea7b66SHoria Geantă 	}
222daebc465SCatalin Vasile 
223e9b4913aSHoria Geantă 	/*
224e9b4913aSHoria Geantă 	 * In case |user key| > |derived key|, using DKP<imm,imm>
225e9b4913aSHoria Geantă 	 * would result in invalid opcodes (last bytes of user key) in
226e9b4913aSHoria Geantă 	 * the resulting descriptor. Use DKP<ptr,imm> instead => both
227e9b4913aSHoria Geantă 	 * virtual and dma key addresses are needed.
228e9b4913aSHoria Geantă 	 */
229e9b4913aSHoria Geantă 	ctx->adata.key_virt = ctx->key;
230e9b4913aSHoria Geantă 	ctx->adata.key_dma = ctx->key_dma;
231e9b4913aSHoria Geantă 
232e9b4913aSHoria Geantă 	ctx->cdata.key_virt = ctx->key + ctx->adata.keylen_pad;
233e9b4913aSHoria Geantă 	ctx->cdata.key_dma = ctx->key_dma + ctx->adata.keylen_pad;
234e9b4913aSHoria Geantă 
2354cbe79ccSHoria Geantă 	data_len[0] = ctx->adata.keylen_pad;
2364cbe79ccSHoria Geantă 	data_len[1] = ctx->cdata.keylen;
2374cbe79ccSHoria Geantă 
238479bcc7cSHerbert Xu 	if (alg->caam.geniv)
239479bcc7cSHerbert Xu 		goto skip_enc;
240479bcc7cSHerbert Xu 
241daebc465SCatalin Vasile 	/*
2421acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
2431acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
2441acebad3SYuan Kang 	 */
2454cbe79ccSHoria Geantă 	if (desc_inline_query(DESC_AEAD_ENC_LEN +
2464cbe79ccSHoria Geantă 			      (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
2474cbe79ccSHoria Geantă 			      AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
2484cbe79ccSHoria Geantă 			      ARRAY_SIZE(data_len)) < 0)
2494cbe79ccSHoria Geantă 		return -EINVAL;
2504cbe79ccSHoria Geantă 
2514cbe79ccSHoria Geantă 	ctx->adata.key_inline = !!(inl_mask & 1);
2524cbe79ccSHoria Geantă 	ctx->cdata.key_inline = !!(inl_mask & 2);
2531acebad3SYuan Kang 
254479bcc7cSHerbert Xu 	/* aead_encrypt shared descriptor */
2551acebad3SYuan Kang 	desc = ctx->sh_desc_enc;
256b189817cSHoria Geantă 	cnstr_shdsc_aead_encap(desc, &ctx->cdata, &ctx->adata, ivsize,
257b189817cSHoria Geantă 			       ctx->authsize, is_rfc3686, nonce, ctx1_iv_off,
2587e0880b9SHoria Geantă 			       false, ctrlpriv->era);
259bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
2607e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
2611acebad3SYuan Kang 
262479bcc7cSHerbert Xu skip_enc:
2631acebad3SYuan Kang 	/*
2641acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
2651acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
2661acebad3SYuan Kang 	 */
2674cbe79ccSHoria Geantă 	if (desc_inline_query(DESC_AEAD_DEC_LEN +
2684cbe79ccSHoria Geantă 			      (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
2694cbe79ccSHoria Geantă 			      AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
2704cbe79ccSHoria Geantă 			      ARRAY_SIZE(data_len)) < 0)
2714cbe79ccSHoria Geantă 		return -EINVAL;
2724cbe79ccSHoria Geantă 
2734cbe79ccSHoria Geantă 	ctx->adata.key_inline = !!(inl_mask & 1);
2744cbe79ccSHoria Geantă 	ctx->cdata.key_inline = !!(inl_mask & 2);
2751acebad3SYuan Kang 
276479bcc7cSHerbert Xu 	/* aead_decrypt shared descriptor */
2771acebad3SYuan Kang 	desc = ctx->sh_desc_dec;
2788cea7b66SHoria Geantă 	cnstr_shdsc_aead_decap(desc, &ctx->cdata, &ctx->adata, ivsize,
2798cea7b66SHoria Geantă 			       ctx->authsize, alg->caam.geniv, is_rfc3686,
2807e0880b9SHoria Geantă 			       nonce, ctx1_iv_off, false, ctrlpriv->era);
281bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
2827e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
2831acebad3SYuan Kang 
284479bcc7cSHerbert Xu 	if (!alg->caam.geniv)
285479bcc7cSHerbert Xu 		goto skip_givenc;
286479bcc7cSHerbert Xu 
2871acebad3SYuan Kang 	/*
2881acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
2891acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
2901acebad3SYuan Kang 	 */
2914cbe79ccSHoria Geantă 	if (desc_inline_query(DESC_AEAD_GIVENC_LEN +
2924cbe79ccSHoria Geantă 			      (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0),
2934cbe79ccSHoria Geantă 			      AUTHENC_DESC_JOB_IO_LEN, data_len, &inl_mask,
2944cbe79ccSHoria Geantă 			      ARRAY_SIZE(data_len)) < 0)
2954cbe79ccSHoria Geantă 		return -EINVAL;
2964cbe79ccSHoria Geantă 
2974cbe79ccSHoria Geantă 	ctx->adata.key_inline = !!(inl_mask & 1);
2984cbe79ccSHoria Geantă 	ctx->cdata.key_inline = !!(inl_mask & 2);
2991acebad3SYuan Kang 
3001acebad3SYuan Kang 	/* aead_givencrypt shared descriptor */
3011d2d87e8SHoria Geantă 	desc = ctx->sh_desc_enc;
3028cea7b66SHoria Geantă 	cnstr_shdsc_aead_givencap(desc, &ctx->cdata, &ctx->adata, ivsize,
3038cea7b66SHoria Geantă 				  ctx->authsize, is_rfc3686, nonce,
3047e0880b9SHoria Geantă 				  ctx1_iv_off, false, ctrlpriv->era);
305bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
3067e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
3071acebad3SYuan Kang 
308479bcc7cSHerbert Xu skip_givenc:
3091acebad3SYuan Kang 	return 0;
3101acebad3SYuan Kang }
3111acebad3SYuan Kang 
3120e479300SYuan Kang static int aead_setauthsize(struct crypto_aead *authenc,
3138e8ec596SKim Phillips 				    unsigned int authsize)
3148e8ec596SKim Phillips {
3158e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
3168e8ec596SKim Phillips 
3178e8ec596SKim Phillips 	ctx->authsize = authsize;
3181acebad3SYuan Kang 	aead_set_sh_desc(authenc);
3198e8ec596SKim Phillips 
3208e8ec596SKim Phillips 	return 0;
3218e8ec596SKim Phillips }
3228e8ec596SKim Phillips 
3233ef8d945STudor Ambarus static int gcm_set_sh_desc(struct crypto_aead *aead)
3243ef8d945STudor Ambarus {
3253ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
3263ef8d945STudor Ambarus 	struct device *jrdev = ctx->jrdev;
32787ec3a0bSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
3283ef8d945STudor Ambarus 	u32 *desc;
3294cbe79ccSHoria Geantă 	int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
3304cbe79ccSHoria Geantă 			ctx->cdata.keylen;
3313ef8d945STudor Ambarus 
332db57656bSHoria Geantă 	if (!ctx->cdata.keylen || !ctx->authsize)
3333ef8d945STudor Ambarus 		return 0;
3343ef8d945STudor Ambarus 
3353ef8d945STudor Ambarus 	/*
3363ef8d945STudor Ambarus 	 * AES GCM encrypt shared descriptor
3373ef8d945STudor Ambarus 	 * Job Descriptor and Shared Descriptor
3383ef8d945STudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
3393ef8d945STudor Ambarus 	 */
3404cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_GCM_ENC_LEN) {
341db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
3429c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
343db57656bSHoria Geantă 	} else {
344db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
3459c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
346db57656bSHoria Geantă 	}
3473ef8d945STudor Ambarus 
3483ef8d945STudor Ambarus 	desc = ctx->sh_desc_enc;
34987ec3a0bSHoria Geantă 	cnstr_shdsc_gcm_encap(desc, &ctx->cdata, ivsize, ctx->authsize, false);
350bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
3517e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
3523ef8d945STudor Ambarus 
3533ef8d945STudor Ambarus 	/*
3543ef8d945STudor Ambarus 	 * Job Descriptor and Shared Descriptors
3553ef8d945STudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
3563ef8d945STudor Ambarus 	 */
3574cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_GCM_DEC_LEN) {
358db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
3599c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
360db57656bSHoria Geantă 	} else {
361db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
3629c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
363db57656bSHoria Geantă 	}
3643ef8d945STudor Ambarus 
3653ef8d945STudor Ambarus 	desc = ctx->sh_desc_dec;
36687ec3a0bSHoria Geantă 	cnstr_shdsc_gcm_decap(desc, &ctx->cdata, ivsize, ctx->authsize, false);
367bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
3687e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
3693ef8d945STudor Ambarus 
3703ef8d945STudor Ambarus 	return 0;
3713ef8d945STudor Ambarus }
3723ef8d945STudor Ambarus 
3733ef8d945STudor Ambarus static int gcm_setauthsize(struct crypto_aead *authenc, unsigned int authsize)
3743ef8d945STudor Ambarus {
3753ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
37668a51394SIuliana Prodan 	int err;
37768a51394SIuliana Prodan 
37868a51394SIuliana Prodan 	err = crypto_gcm_check_authsize(authsize);
37968a51394SIuliana Prodan 	if (err)
38068a51394SIuliana Prodan 		return err;
3813ef8d945STudor Ambarus 
3823ef8d945STudor Ambarus 	ctx->authsize = authsize;
3833ef8d945STudor Ambarus 	gcm_set_sh_desc(authenc);
3843ef8d945STudor Ambarus 
3853ef8d945STudor Ambarus 	return 0;
3863ef8d945STudor Ambarus }
3873ef8d945STudor Ambarus 
388bac68f2cSTudor Ambarus static int rfc4106_set_sh_desc(struct crypto_aead *aead)
389bac68f2cSTudor Ambarus {
390bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
391bac68f2cSTudor Ambarus 	struct device *jrdev = ctx->jrdev;
39287ec3a0bSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
393bac68f2cSTudor Ambarus 	u32 *desc;
3944cbe79ccSHoria Geantă 	int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
3954cbe79ccSHoria Geantă 			ctx->cdata.keylen;
396bac68f2cSTudor Ambarus 
397db57656bSHoria Geantă 	if (!ctx->cdata.keylen || !ctx->authsize)
398bac68f2cSTudor Ambarus 		return 0;
399bac68f2cSTudor Ambarus 
400bac68f2cSTudor Ambarus 	/*
401bac68f2cSTudor Ambarus 	 * RFC4106 encrypt shared descriptor
402bac68f2cSTudor Ambarus 	 * Job Descriptor and Shared Descriptor
403bac68f2cSTudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
404bac68f2cSTudor Ambarus 	 */
4054cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_RFC4106_ENC_LEN) {
406db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
4079c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
408db57656bSHoria Geantă 	} else {
409db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
4109c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
411db57656bSHoria Geantă 	}
412bac68f2cSTudor Ambarus 
413bac68f2cSTudor Ambarus 	desc = ctx->sh_desc_enc;
41487ec3a0bSHoria Geantă 	cnstr_shdsc_rfc4106_encap(desc, &ctx->cdata, ivsize, ctx->authsize,
41587ec3a0bSHoria Geantă 				  false);
416bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
4177e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
418bac68f2cSTudor Ambarus 
419bac68f2cSTudor Ambarus 	/*
420bac68f2cSTudor Ambarus 	 * Job Descriptor and Shared Descriptors
421bac68f2cSTudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
422bac68f2cSTudor Ambarus 	 */
4234cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_RFC4106_DEC_LEN) {
424db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
4259c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
426db57656bSHoria Geantă 	} else {
427db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
4289c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
429db57656bSHoria Geantă 	}
430bac68f2cSTudor Ambarus 
431bac68f2cSTudor Ambarus 	desc = ctx->sh_desc_dec;
43287ec3a0bSHoria Geantă 	cnstr_shdsc_rfc4106_decap(desc, &ctx->cdata, ivsize, ctx->authsize,
43387ec3a0bSHoria Geantă 				  false);
434bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
4357e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
436bac68f2cSTudor Ambarus 
437bac68f2cSTudor Ambarus 	return 0;
438bac68f2cSTudor Ambarus }
439bac68f2cSTudor Ambarus 
440bac68f2cSTudor Ambarus static int rfc4106_setauthsize(struct crypto_aead *authenc,
441bac68f2cSTudor Ambarus 			       unsigned int authsize)
442bac68f2cSTudor Ambarus {
443bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
44468a51394SIuliana Prodan 	int err;
44568a51394SIuliana Prodan 
44668a51394SIuliana Prodan 	err = crypto_rfc4106_check_authsize(authsize);
44768a51394SIuliana Prodan 	if (err)
44868a51394SIuliana Prodan 		return err;
449bac68f2cSTudor Ambarus 
450bac68f2cSTudor Ambarus 	ctx->authsize = authsize;
451bac68f2cSTudor Ambarus 	rfc4106_set_sh_desc(authenc);
452bac68f2cSTudor Ambarus 
453bac68f2cSTudor Ambarus 	return 0;
454bac68f2cSTudor Ambarus }
455bac68f2cSTudor Ambarus 
4565d0429a3STudor Ambarus static int rfc4543_set_sh_desc(struct crypto_aead *aead)
4575d0429a3STudor Ambarus {
4585d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
4595d0429a3STudor Ambarus 	struct device *jrdev = ctx->jrdev;
46087ec3a0bSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
4615d0429a3STudor Ambarus 	u32 *desc;
4624cbe79ccSHoria Geantă 	int rem_bytes = CAAM_DESC_BYTES_MAX - GCM_DESC_JOB_IO_LEN -
4634cbe79ccSHoria Geantă 			ctx->cdata.keylen;
4645d0429a3STudor Ambarus 
465db57656bSHoria Geantă 	if (!ctx->cdata.keylen || !ctx->authsize)
4665d0429a3STudor Ambarus 		return 0;
4675d0429a3STudor Ambarus 
4685d0429a3STudor Ambarus 	/*
4695d0429a3STudor Ambarus 	 * RFC4543 encrypt shared descriptor
4705d0429a3STudor Ambarus 	 * Job Descriptor and Shared Descriptor
4715d0429a3STudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
4725d0429a3STudor Ambarus 	 */
4734cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_RFC4543_ENC_LEN) {
474db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
4759c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
476db57656bSHoria Geantă 	} else {
477db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
4789c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
479db57656bSHoria Geantă 	}
4805d0429a3STudor Ambarus 
4815d0429a3STudor Ambarus 	desc = ctx->sh_desc_enc;
48287ec3a0bSHoria Geantă 	cnstr_shdsc_rfc4543_encap(desc, &ctx->cdata, ivsize, ctx->authsize,
48387ec3a0bSHoria Geantă 				  false);
484bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
4857e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
4865d0429a3STudor Ambarus 
4875d0429a3STudor Ambarus 	/*
4885d0429a3STudor Ambarus 	 * Job Descriptor and Shared Descriptors
4895d0429a3STudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
4905d0429a3STudor Ambarus 	 */
4914cbe79ccSHoria Geantă 	if (rem_bytes >= DESC_RFC4543_DEC_LEN) {
492db57656bSHoria Geantă 		ctx->cdata.key_inline = true;
4939c0bc511SArnd Bergmann 		ctx->cdata.key_virt = ctx->key;
494db57656bSHoria Geantă 	} else {
495db57656bSHoria Geantă 		ctx->cdata.key_inline = false;
4969c0bc511SArnd Bergmann 		ctx->cdata.key_dma = ctx->key_dma;
497db57656bSHoria Geantă 	}
4985d0429a3STudor Ambarus 
4995d0429a3STudor Ambarus 	desc = ctx->sh_desc_dec;
50087ec3a0bSHoria Geantă 	cnstr_shdsc_rfc4543_decap(desc, &ctx->cdata, ivsize, ctx->authsize,
50187ec3a0bSHoria Geantă 				  false);
502bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
5037e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
5045d0429a3STudor Ambarus 
5055d0429a3STudor Ambarus 	return 0;
5065d0429a3STudor Ambarus }
5075d0429a3STudor Ambarus 
5085d0429a3STudor Ambarus static int rfc4543_setauthsize(struct crypto_aead *authenc,
5095d0429a3STudor Ambarus 			       unsigned int authsize)
5105d0429a3STudor Ambarus {
5115d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
5125d0429a3STudor Ambarus 
51368a51394SIuliana Prodan 	if (authsize != 16)
51468a51394SIuliana Prodan 		return -EINVAL;
51568a51394SIuliana Prodan 
5165d0429a3STudor Ambarus 	ctx->authsize = authsize;
5175d0429a3STudor Ambarus 	rfc4543_set_sh_desc(authenc);
5185d0429a3STudor Ambarus 
5195d0429a3STudor Ambarus 	return 0;
5205d0429a3STudor Ambarus }
5215d0429a3STudor Ambarus 
522d6bbd4eeSHoria Geantă static int chachapoly_set_sh_desc(struct crypto_aead *aead)
523d6bbd4eeSHoria Geantă {
524d6bbd4eeSHoria Geantă 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
525d6bbd4eeSHoria Geantă 	struct device *jrdev = ctx->jrdev;
526d6bbd4eeSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
527d6bbd4eeSHoria Geantă 	u32 *desc;
528d6bbd4eeSHoria Geantă 
529d6bbd4eeSHoria Geantă 	if (!ctx->cdata.keylen || !ctx->authsize)
530d6bbd4eeSHoria Geantă 		return 0;
531d6bbd4eeSHoria Geantă 
532d6bbd4eeSHoria Geantă 	desc = ctx->sh_desc_enc;
533d6bbd4eeSHoria Geantă 	cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize,
534c10a5336SHoria Geantă 			       ctx->authsize, true, false);
535d6bbd4eeSHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
536d6bbd4eeSHoria Geantă 				   desc_bytes(desc), ctx->dir);
537d6bbd4eeSHoria Geantă 
538d6bbd4eeSHoria Geantă 	desc = ctx->sh_desc_dec;
539d6bbd4eeSHoria Geantă 	cnstr_shdsc_chachapoly(desc, &ctx->cdata, &ctx->adata, ivsize,
540c10a5336SHoria Geantă 			       ctx->authsize, false, false);
541d6bbd4eeSHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
542d6bbd4eeSHoria Geantă 				   desc_bytes(desc), ctx->dir);
543d6bbd4eeSHoria Geantă 
544d6bbd4eeSHoria Geantă 	return 0;
545d6bbd4eeSHoria Geantă }
546d6bbd4eeSHoria Geantă 
547d6bbd4eeSHoria Geantă static int chachapoly_setauthsize(struct crypto_aead *aead,
548d6bbd4eeSHoria Geantă 				  unsigned int authsize)
549d6bbd4eeSHoria Geantă {
550d6bbd4eeSHoria Geantă 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
551d6bbd4eeSHoria Geantă 
552d6bbd4eeSHoria Geantă 	if (authsize != POLY1305_DIGEST_SIZE)
553d6bbd4eeSHoria Geantă 		return -EINVAL;
554d6bbd4eeSHoria Geantă 
555d6bbd4eeSHoria Geantă 	ctx->authsize = authsize;
556d6bbd4eeSHoria Geantă 	return chachapoly_set_sh_desc(aead);
557d6bbd4eeSHoria Geantă }
558d6bbd4eeSHoria Geantă 
559d6bbd4eeSHoria Geantă static int chachapoly_setkey(struct crypto_aead *aead, const u8 *key,
560d6bbd4eeSHoria Geantă 			     unsigned int keylen)
561d6bbd4eeSHoria Geantă {
562d6bbd4eeSHoria Geantă 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
563d6bbd4eeSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
564d6bbd4eeSHoria Geantă 	unsigned int saltlen = CHACHAPOLY_IV_SIZE - ivsize;
565d6bbd4eeSHoria Geantă 
566674f368aSEric Biggers 	if (keylen != CHACHA_KEY_SIZE + saltlen)
567d6bbd4eeSHoria Geantă 		return -EINVAL;
568d6bbd4eeSHoria Geantă 
569d6bbd4eeSHoria Geantă 	ctx->cdata.key_virt = key;
570d6bbd4eeSHoria Geantă 	ctx->cdata.keylen = keylen - saltlen;
571d6bbd4eeSHoria Geantă 
572d6bbd4eeSHoria Geantă 	return chachapoly_set_sh_desc(aead);
573d6bbd4eeSHoria Geantă }
574d6bbd4eeSHoria Geantă 
5750e479300SYuan Kang static int aead_setkey(struct crypto_aead *aead,
5768e8ec596SKim Phillips 			       const u8 *key, unsigned int keylen)
5778e8ec596SKim Phillips {
5788e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
5798e8ec596SKim Phillips 	struct device *jrdev = ctx->jrdev;
5807e0880b9SHoria Geantă 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(jrdev->parent);
5814e6e0b27SHoria Geanta 	struct crypto_authenc_keys keys;
5828e8ec596SKim Phillips 	int ret = 0;
5838e8ec596SKim Phillips 
5844e6e0b27SHoria Geanta 	if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
5858e8ec596SKim Phillips 		goto badkey;
5868e8ec596SKim Phillips 
5876e005503SSascha Hauer 	dev_dbg(jrdev, "keylen %d enckeylen %d authkeylen %d\n",
5884e6e0b27SHoria Geanta 	       keys.authkeylen + keys.enckeylen, keys.enckeylen,
5894e6e0b27SHoria Geanta 	       keys.authkeylen);
5906e005503SSascha Hauer 	print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
5918e8ec596SKim Phillips 			     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
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);
6256e005503SSascha Hauer 
6266e005503SSascha Hauer 	print_hex_dump_debug("ctx.key@"__stringify(__LINE__)": ",
6278e8ec596SKim Phillips 			     DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
628db57656bSHoria Geantă 			     ctx->adata.keylen_pad + keys.enckeylen, 1);
6297e0880b9SHoria Geantă 
6307e0880b9SHoria Geantă skip_split_key:
631db57656bSHoria Geantă 	ctx->cdata.keylen = keys.enckeylen;
63261dab972STudor-Dan Ambarus 	memzero_explicit(&keys, sizeof(keys));
633bbf22344SHoria Geantă 	return aead_set_sh_desc(aead);
6348e8ec596SKim Phillips badkey:
63561dab972STudor-Dan Ambarus 	memzero_explicit(&keys, sizeof(keys));
6368e8ec596SKim Phillips 	return -EINVAL;
6378e8ec596SKim Phillips }
6388e8ec596SKim Phillips 
6391b52c409SHerbert Xu static int des3_aead_setkey(struct crypto_aead *aead, const u8 *key,
6401b52c409SHerbert Xu 			    unsigned int keylen)
6411b52c409SHerbert Xu {
6421b52c409SHerbert Xu 	struct crypto_authenc_keys keys;
6431b52c409SHerbert Xu 	int err;
6441b52c409SHerbert Xu 
6451b52c409SHerbert Xu 	err = crypto_authenc_extractkeys(&keys, key, keylen);
6461b52c409SHerbert Xu 	if (unlikely(err))
6471b52c409SHerbert Xu 		return err;
6481b52c409SHerbert Xu 
649a628c5a1SArd Biesheuvel 	err = verify_aead_des3_key(aead, keys.enckey, keys.enckeylen) ?:
650a628c5a1SArd Biesheuvel 	      aead_setkey(aead, key, keylen);
651a628c5a1SArd Biesheuvel 
652a628c5a1SArd Biesheuvel 	memzero_explicit(&keys, sizeof(keys));
653a628c5a1SArd Biesheuvel 	return err;
6541b52c409SHerbert Xu }
6551b52c409SHerbert Xu 
6563ef8d945STudor Ambarus static int gcm_setkey(struct crypto_aead *aead,
6573ef8d945STudor Ambarus 		      const u8 *key, unsigned int keylen)
6583ef8d945STudor Ambarus {
6593ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
6603ef8d945STudor Ambarus 	struct device *jrdev = ctx->jrdev;
661836d8f43SIuliana Prodan 	int err;
662836d8f43SIuliana Prodan 
663836d8f43SIuliana Prodan 	err = aes_check_keylen(keylen);
664674f368aSEric Biggers 	if (err)
665836d8f43SIuliana Prodan 		return err;
6663ef8d945STudor Ambarus 
6676e005503SSascha Hauer 	print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
6683ef8d945STudor Ambarus 			     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
6693ef8d945STudor Ambarus 
6703ef8d945STudor Ambarus 	memcpy(ctx->key, key, keylen);
6717e0880b9SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, keylen, ctx->dir);
672db57656bSHoria Geantă 	ctx->cdata.keylen = keylen;
6733ef8d945STudor Ambarus 
674bbf22344SHoria Geantă 	return gcm_set_sh_desc(aead);
6753ef8d945STudor Ambarus }
6763ef8d945STudor Ambarus 
677bac68f2cSTudor Ambarus static int rfc4106_setkey(struct crypto_aead *aead,
678bac68f2cSTudor Ambarus 			  const u8 *key, unsigned int keylen)
679bac68f2cSTudor Ambarus {
680bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
681bac68f2cSTudor Ambarus 	struct device *jrdev = ctx->jrdev;
682836d8f43SIuliana Prodan 	int err;
683bac68f2cSTudor Ambarus 
684836d8f43SIuliana Prodan 	err = aes_check_keylen(keylen - 4);
685674f368aSEric Biggers 	if (err)
686836d8f43SIuliana Prodan 		return err;
687bac68f2cSTudor Ambarus 
6886e005503SSascha Hauer 	print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
689bac68f2cSTudor Ambarus 			     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
690bac68f2cSTudor Ambarus 
691bac68f2cSTudor Ambarus 	memcpy(ctx->key, key, keylen);
692bac68f2cSTudor Ambarus 
693bac68f2cSTudor Ambarus 	/*
694bac68f2cSTudor Ambarus 	 * The last four bytes of the key material are used as the salt value
695bac68f2cSTudor Ambarus 	 * in the nonce. Update the AES key length.
696bac68f2cSTudor Ambarus 	 */
697db57656bSHoria Geantă 	ctx->cdata.keylen = keylen - 4;
698bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
6997e0880b9SHoria Geantă 				   ctx->dir);
700bbf22344SHoria Geantă 	return rfc4106_set_sh_desc(aead);
701bac68f2cSTudor Ambarus }
702bac68f2cSTudor Ambarus 
7035d0429a3STudor Ambarus static int rfc4543_setkey(struct crypto_aead *aead,
7045d0429a3STudor Ambarus 			  const u8 *key, unsigned int keylen)
7055d0429a3STudor Ambarus {
7065d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
7075d0429a3STudor Ambarus 	struct device *jrdev = ctx->jrdev;
708836d8f43SIuliana Prodan 	int err;
7095d0429a3STudor Ambarus 
710836d8f43SIuliana Prodan 	err = aes_check_keylen(keylen - 4);
711674f368aSEric Biggers 	if (err)
712836d8f43SIuliana Prodan 		return err;
7135d0429a3STudor Ambarus 
7146e005503SSascha Hauer 	print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
7155d0429a3STudor Ambarus 			     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
7165d0429a3STudor Ambarus 
7175d0429a3STudor Ambarus 	memcpy(ctx->key, key, keylen);
7185d0429a3STudor Ambarus 
7195d0429a3STudor Ambarus 	/*
7205d0429a3STudor Ambarus 	 * The last four bytes of the key material are used as the salt value
7215d0429a3STudor Ambarus 	 * in the nonce. Update the AES key length.
7225d0429a3STudor Ambarus 	 */
723db57656bSHoria Geantă 	ctx->cdata.keylen = keylen - 4;
724bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->key_dma, ctx->cdata.keylen,
7257e0880b9SHoria Geantă 				   ctx->dir);
726bbf22344SHoria Geantă 	return rfc4543_set_sh_desc(aead);
7275d0429a3STudor Ambarus }
7285d0429a3STudor Ambarus 
7295ca7badbSHoria Geantă static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
730836d8f43SIuliana Prodan 			   unsigned int keylen, const u32 ctx1_iv_off)
731acdca31dSYuan Kang {
7325ca7badbSHoria Geantă 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
7335ca7badbSHoria Geantă 	struct caam_skcipher_alg *alg =
7345ca7badbSHoria Geantă 		container_of(crypto_skcipher_alg(skcipher), typeof(*alg),
7355ca7badbSHoria Geantă 			     skcipher);
736acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
7375ca7badbSHoria Geantă 	unsigned int ivsize = crypto_skcipher_ivsize(skcipher);
738acdca31dSYuan Kang 	u32 *desc;
7395ca7badbSHoria Geantă 	const bool is_rfc3686 = alg->caam.rfc3686;
740acdca31dSYuan Kang 
7416e005503SSascha Hauer 	print_hex_dump_debug("key in @"__stringify(__LINE__)": ",
742acdca31dSYuan Kang 			     DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
743a5f57cffSCatalin Vasile 
744db57656bSHoria Geantă 	ctx->cdata.keylen = keylen;
745662f70edSHoria Geantă 	ctx->cdata.key_virt = key;
746db57656bSHoria Geantă 	ctx->cdata.key_inline = true;
747acdca31dSYuan Kang 
7485ca7badbSHoria Geantă 	/* skcipher_encrypt shared descriptor */
749acdca31dSYuan Kang 	desc = ctx->sh_desc_enc;
7509dbe3072SHoria Geantă 	cnstr_shdsc_skcipher_encap(desc, &ctx->cdata, ivsize, is_rfc3686,
7518cea7b66SHoria Geantă 				   ctx1_iv_off);
752bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
7537e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
7548cea7b66SHoria Geantă 
7555ca7badbSHoria Geantă 	/* skcipher_decrypt shared descriptor */
756acdca31dSYuan Kang 	desc = ctx->sh_desc_dec;
7579dbe3072SHoria Geantă 	cnstr_shdsc_skcipher_decap(desc, &ctx->cdata, ivsize, is_rfc3686,
7588cea7b66SHoria Geantă 				   ctx1_iv_off);
759bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
7607e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
761acdca31dSYuan Kang 
7628cea7b66SHoria Geantă 	return 0;
763acdca31dSYuan Kang }
764acdca31dSYuan Kang 
765836d8f43SIuliana Prodan static int aes_skcipher_setkey(struct crypto_skcipher *skcipher,
766836d8f43SIuliana Prodan 			       const u8 *key, unsigned int keylen)
767836d8f43SIuliana Prodan {
768836d8f43SIuliana Prodan 	int err;
769836d8f43SIuliana Prodan 
770836d8f43SIuliana Prodan 	err = aes_check_keylen(keylen);
771674f368aSEric Biggers 	if (err)
772836d8f43SIuliana Prodan 		return err;
773836d8f43SIuliana Prodan 
774836d8f43SIuliana Prodan 	return skcipher_setkey(skcipher, key, keylen, 0);
775836d8f43SIuliana Prodan }
776836d8f43SIuliana Prodan 
777836d8f43SIuliana Prodan static int rfc3686_skcipher_setkey(struct crypto_skcipher *skcipher,
778836d8f43SIuliana Prodan 				   const u8 *key, unsigned int keylen)
779836d8f43SIuliana Prodan {
780836d8f43SIuliana Prodan 	u32 ctx1_iv_off;
781836d8f43SIuliana Prodan 	int err;
782836d8f43SIuliana Prodan 
783836d8f43SIuliana Prodan 	/*
784836d8f43SIuliana Prodan 	 * RFC3686 specific:
785836d8f43SIuliana Prodan 	 *	| CONTEXT1[255:128] = {NONCE, IV, COUNTER}
786836d8f43SIuliana Prodan 	 *	| *key = {KEY, NONCE}
787836d8f43SIuliana Prodan 	 */
788836d8f43SIuliana Prodan 	ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
789836d8f43SIuliana Prodan 	keylen -= CTR_RFC3686_NONCE_SIZE;
790836d8f43SIuliana Prodan 
791836d8f43SIuliana Prodan 	err = aes_check_keylen(keylen);
792674f368aSEric Biggers 	if (err)
793836d8f43SIuliana Prodan 		return err;
794836d8f43SIuliana Prodan 
795836d8f43SIuliana Prodan 	return skcipher_setkey(skcipher, key, keylen, ctx1_iv_off);
796836d8f43SIuliana Prodan }
797836d8f43SIuliana Prodan 
798836d8f43SIuliana Prodan static int ctr_skcipher_setkey(struct crypto_skcipher *skcipher,
799836d8f43SIuliana Prodan 			       const u8 *key, unsigned int keylen)
800836d8f43SIuliana Prodan {
801836d8f43SIuliana Prodan 	u32 ctx1_iv_off;
802836d8f43SIuliana Prodan 	int err;
803836d8f43SIuliana Prodan 
804836d8f43SIuliana Prodan 	/*
805836d8f43SIuliana Prodan 	 * AES-CTR needs to load IV in CONTEXT1 reg
806836d8f43SIuliana Prodan 	 * at an offset of 128bits (16bytes)
807836d8f43SIuliana Prodan 	 * CONTEXT1[255:128] = IV
808836d8f43SIuliana Prodan 	 */
809836d8f43SIuliana Prodan 	ctx1_iv_off = 16;
810836d8f43SIuliana Prodan 
811836d8f43SIuliana Prodan 	err = aes_check_keylen(keylen);
812674f368aSEric Biggers 	if (err)
813836d8f43SIuliana Prodan 		return err;
814836d8f43SIuliana Prodan 
815836d8f43SIuliana Prodan 	return skcipher_setkey(skcipher, key, keylen, ctx1_iv_off);
816836d8f43SIuliana Prodan }
817836d8f43SIuliana Prodan 
818eaed71a4SIuliana Prodan static int des_skcipher_setkey(struct crypto_skcipher *skcipher,
819eaed71a4SIuliana Prodan 			       const u8 *key, unsigned int keylen)
820eaed71a4SIuliana Prodan {
821a628c5a1SArd Biesheuvel 	return verify_skcipher_des_key(skcipher, key) ?:
822a628c5a1SArd Biesheuvel 	       skcipher_setkey(skcipher, key, keylen, 0);
823eaed71a4SIuliana Prodan }
824eaed71a4SIuliana Prodan 
825a628c5a1SArd Biesheuvel static int des3_skcipher_setkey(struct crypto_skcipher *skcipher,
826a628c5a1SArd Biesheuvel 				const u8 *key, unsigned int keylen)
827a628c5a1SArd Biesheuvel {
828a628c5a1SArd Biesheuvel 	return verify_skcipher_des3_key(skcipher, key) ?:
829a628c5a1SArd Biesheuvel 	       skcipher_setkey(skcipher, key, keylen, 0);
830eaed71a4SIuliana Prodan }
831eaed71a4SIuliana Prodan 
8325ca7badbSHoria Geantă static int xts_skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key,
8335ca7badbSHoria Geantă 			       unsigned int keylen)
834c6415a60SCatalin Vasile {
8355ca7badbSHoria Geantă 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
836c6415a60SCatalin Vasile 	struct device *jrdev = ctx->jrdev;
8378cea7b66SHoria Geantă 	u32 *desc;
8389d9b14dbSAndrei Botila 	int err;
839c6415a60SCatalin Vasile 
840c91f7348SAndrei Botila 	err = xts_verify_key(skcipher, key, keylen);
841c91f7348SAndrei Botila 	if (err) {
842da6a6685SHoria Geantă 		dev_dbg(jrdev, "key size mismatch\n");
843c91f7348SAndrei Botila 		return err;
844c6415a60SCatalin Vasile 	}
845c6415a60SCatalin Vasile 
846c91f7348SAndrei Botila 	if (keylen != 2 * AES_KEYSIZE_128 && keylen != 2 * AES_KEYSIZE_256)
847c91f7348SAndrei Botila 		ctx->xts_key_fallback = true;
848c91f7348SAndrei Botila 
8499d9b14dbSAndrei Botila 	err = crypto_skcipher_setkey(ctx->fallback, key, keylen);
8509d9b14dbSAndrei Botila 	if (err)
8519d9b14dbSAndrei Botila 		return err;
8529d9b14dbSAndrei Botila 
853db57656bSHoria Geantă 	ctx->cdata.keylen = keylen;
854662f70edSHoria Geantă 	ctx->cdata.key_virt = key;
855db57656bSHoria Geantă 	ctx->cdata.key_inline = true;
856c6415a60SCatalin Vasile 
8575ca7badbSHoria Geantă 	/* xts_skcipher_encrypt shared descriptor */
858c6415a60SCatalin Vasile 	desc = ctx->sh_desc_enc;
8599dbe3072SHoria Geantă 	cnstr_shdsc_xts_skcipher_encap(desc, &ctx->cdata);
860bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_enc_dma,
8617e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
862c6415a60SCatalin Vasile 
8635ca7badbSHoria Geantă 	/* xts_skcipher_decrypt shared descriptor */
864c6415a60SCatalin Vasile 	desc = ctx->sh_desc_dec;
8659dbe3072SHoria Geantă 	cnstr_shdsc_xts_skcipher_decap(desc, &ctx->cdata);
866bbf22344SHoria Geantă 	dma_sync_single_for_device(jrdev, ctx->sh_desc_dec_dma,
8677e0880b9SHoria Geantă 				   desc_bytes(desc), ctx->dir);
868c6415a60SCatalin Vasile 
869c6415a60SCatalin Vasile 	return 0;
870c6415a60SCatalin Vasile }
871c6415a60SCatalin Vasile 
8728e8ec596SKim Phillips /*
8731acebad3SYuan Kang  * aead_edesc - s/w-extended aead descriptor
874fa0c92dbSHoria Geantă  * @src_nents: number of segments in input s/w scatterlist
875fa0c92dbSHoria Geantă  * @dst_nents: number of segments in output s/w scatterlist
876ba4cf71bSIuliana Prodan  * @mapped_src_nents: number of segments in input h/w link table
877ba4cf71bSIuliana Prodan  * @mapped_dst_nents: number of segments in output h/w link table
878a299c837SYuan Kang  * @sec4_sg_bytes: length of dma mapped sec4_sg space
8791c240226SIuliana Prodan  * @bklog: stored to determine if the request needs backlog
880a299c837SYuan Kang  * @sec4_sg_dma: bus physical mapped address of h/w link table
8814ca7c7d8SHoria Geantă  * @sec4_sg: pointer to h/w link table
8828e8ec596SKim Phillips  * @hw_desc: the h/w job descriptor followed by any referenced link tables
8838e8ec596SKim Phillips  */
8840e479300SYuan Kang struct aead_edesc {
8858e8ec596SKim Phillips 	int src_nents;
8868e8ec596SKim Phillips 	int dst_nents;
887ba4cf71bSIuliana Prodan 	int mapped_src_nents;
888ba4cf71bSIuliana Prodan 	int mapped_dst_nents;
889a299c837SYuan Kang 	int sec4_sg_bytes;
8901c240226SIuliana Prodan 	bool bklog;
891a299c837SYuan Kang 	dma_addr_t sec4_sg_dma;
892a299c837SYuan Kang 	struct sec4_sg_entry *sec4_sg;
893f2147b88SHerbert Xu 	u32 hw_desc[];
8948e8ec596SKim Phillips };
8958e8ec596SKim Phillips 
896acdca31dSYuan Kang /*
8975ca7badbSHoria Geantă  * skcipher_edesc - s/w-extended skcipher descriptor
898fa0c92dbSHoria Geantă  * @src_nents: number of segments in input s/w scatterlist
899fa0c92dbSHoria Geantă  * @dst_nents: number of segments in output s/w scatterlist
900ba4cf71bSIuliana Prodan  * @mapped_src_nents: number of segments in input h/w link table
901ba4cf71bSIuliana Prodan  * @mapped_dst_nents: number of segments in output h/w link table
902acdca31dSYuan Kang  * @iv_dma: dma address of iv for checking continuity and link table
903a299c837SYuan Kang  * @sec4_sg_bytes: length of dma mapped sec4_sg space
904ee38767fSIuliana Prodan  * @bklog: stored to determine if the request needs backlog
905a299c837SYuan Kang  * @sec4_sg_dma: bus physical mapped address of h/w link table
9064ca7c7d8SHoria Geantă  * @sec4_sg: pointer to h/w link table
907acdca31dSYuan Kang  * @hw_desc: the h/w job descriptor followed by any referenced link tables
908115957bbSHoria Geantă  *	     and IV
909acdca31dSYuan Kang  */
9105ca7badbSHoria Geantă struct skcipher_edesc {
911acdca31dSYuan Kang 	int src_nents;
912acdca31dSYuan Kang 	int dst_nents;
913ba4cf71bSIuliana Prodan 	int mapped_src_nents;
914ba4cf71bSIuliana Prodan 	int mapped_dst_nents;
915acdca31dSYuan Kang 	dma_addr_t iv_dma;
916a299c837SYuan Kang 	int sec4_sg_bytes;
917ee38767fSIuliana Prodan 	bool bklog;
918a299c837SYuan Kang 	dma_addr_t sec4_sg_dma;
919a299c837SYuan Kang 	struct sec4_sg_entry *sec4_sg;
9205a8a0765SGustavo A. R. Silva 	u32 hw_desc[];
921acdca31dSYuan Kang };
922acdca31dSYuan Kang 
9231acebad3SYuan Kang static void caam_unmap(struct device *dev, struct scatterlist *src,
924643b39b0SYuan Kang 		       struct scatterlist *dst, int src_nents,
92513fb8fd7SLABBE Corentin 		       int dst_nents,
926cf5448b5SHoria Geantă 		       dma_addr_t iv_dma, int ivsize, dma_addr_t sec4_sg_dma,
927a299c837SYuan Kang 		       int sec4_sg_bytes)
9281acebad3SYuan Kang {
929643b39b0SYuan Kang 	if (dst != src) {
930fa0c92dbSHoria Geantă 		if (src_nents)
931fa0c92dbSHoria Geantă 			dma_unmap_sg(dev, src, src_nents, DMA_TO_DEVICE);
932763069baSHoria Geantă 		if (dst_nents)
933fa0c92dbSHoria Geantă 			dma_unmap_sg(dev, dst, dst_nents, DMA_FROM_DEVICE);
9341acebad3SYuan Kang 	} else {
935fa0c92dbSHoria Geantă 		dma_unmap_sg(dev, src, src_nents, DMA_BIDIRECTIONAL);
9361acebad3SYuan Kang 	}
9371acebad3SYuan Kang 
9381acebad3SYuan Kang 	if (iv_dma)
939334d37c9SHoria Geantă 		dma_unmap_single(dev, iv_dma, ivsize, DMA_BIDIRECTIONAL);
940a299c837SYuan Kang 	if (sec4_sg_bytes)
941a299c837SYuan Kang 		dma_unmap_single(dev, sec4_sg_dma, sec4_sg_bytes,
9421acebad3SYuan Kang 				 DMA_TO_DEVICE);
9431acebad3SYuan Kang }
9441acebad3SYuan Kang 
9450e479300SYuan Kang static void aead_unmap(struct device *dev,
9460e479300SYuan Kang 		       struct aead_edesc *edesc,
9470e479300SYuan Kang 		       struct aead_request *req)
9488e8ec596SKim Phillips {
949f2147b88SHerbert Xu 	caam_unmap(dev, req->src, req->dst,
950cf5448b5SHoria Geantă 		   edesc->src_nents, edesc->dst_nents, 0, 0,
951f2147b88SHerbert Xu 		   edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
952f2147b88SHerbert Xu }
953f2147b88SHerbert Xu 
9545ca7badbSHoria Geantă static void skcipher_unmap(struct device *dev, struct skcipher_edesc *edesc,
9555ca7badbSHoria Geantă 			   struct skcipher_request *req)
956acdca31dSYuan Kang {
9575ca7badbSHoria Geantă 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
9585ca7badbSHoria Geantă 	int ivsize = crypto_skcipher_ivsize(skcipher);
959acdca31dSYuan Kang 
960acdca31dSYuan Kang 	caam_unmap(dev, req->src, req->dst,
96113fb8fd7SLABBE Corentin 		   edesc->src_nents, edesc->dst_nents,
962cf5448b5SHoria Geantă 		   edesc->iv_dma, ivsize,
963643b39b0SYuan Kang 		   edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
964acdca31dSYuan Kang }
965acdca31dSYuan Kang 
966b7f17fe2SIuliana Prodan static void aead_crypt_done(struct device *jrdev, u32 *desc, u32 err,
9678e8ec596SKim Phillips 			    void *context)
9688e8ec596SKim Phillips {
9690e479300SYuan Kang 	struct aead_request *req = context;
9701c240226SIuliana Prodan 	struct caam_aead_req_ctx *rctx = aead_request_ctx(req);
9711c240226SIuliana Prodan 	struct caam_drv_private_jr *jrp = dev_get_drvdata(jrdev);
9720e479300SYuan Kang 	struct aead_edesc *edesc;
9731984aaeeSHoria Geantă 	int ecode = 0;
9745ed1e8b8SIuliana Prodan 	bool has_bklog;
975f2147b88SHerbert Xu 
9766e005503SSascha Hauer 	dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
977f2147b88SHerbert Xu 
9781c240226SIuliana Prodan 	edesc = rctx->edesc;
9795ed1e8b8SIuliana Prodan 	has_bklog = edesc->bklog;
980f2147b88SHerbert Xu 
981f2147b88SHerbert Xu 	if (err)
9821984aaeeSHoria Geantă 		ecode = caam_jr_strstatus(jrdev, err);
983f2147b88SHerbert Xu 
984f2147b88SHerbert Xu 	aead_unmap(jrdev, edesc, req);
985f2147b88SHerbert Xu 
986f2147b88SHerbert Xu 	kfree(edesc);
987f2147b88SHerbert Xu 
9881c240226SIuliana Prodan 	/*
9891c240226SIuliana Prodan 	 * If no backlog flag, the completion of the request is done
9901c240226SIuliana Prodan 	 * by CAAM, not crypto engine.
9911c240226SIuliana Prodan 	 */
9925ed1e8b8SIuliana Prodan 	if (!has_bklog)
9931984aaeeSHoria Geantă 		aead_request_complete(req, ecode);
9941c240226SIuliana Prodan 	else
9951c240226SIuliana Prodan 		crypto_finalize_aead_request(jrp->engine, req, ecode);
996f2147b88SHerbert Xu }
997f2147b88SHerbert Xu 
998b7f17fe2SIuliana Prodan static void skcipher_crypt_done(struct device *jrdev, u32 *desc, u32 err,
999acdca31dSYuan Kang 				void *context)
1000acdca31dSYuan Kang {
10015ca7badbSHoria Geantă 	struct skcipher_request *req = context;
10025ca7badbSHoria Geantă 	struct skcipher_edesc *edesc;
1003ee38767fSIuliana Prodan 	struct caam_skcipher_req_ctx *rctx = skcipher_request_ctx(req);
10045ca7badbSHoria Geantă 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
1005ee38767fSIuliana Prodan 	struct caam_drv_private_jr *jrp = dev_get_drvdata(jrdev);
10065ca7badbSHoria Geantă 	int ivsize = crypto_skcipher_ivsize(skcipher);
10071984aaeeSHoria Geantă 	int ecode = 0;
10085af4e8d4SIuliana Prodan 	bool has_bklog;
1009acdca31dSYuan Kang 
10106e005503SSascha Hauer 	dev_dbg(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
1011acdca31dSYuan Kang 
1012ee38767fSIuliana Prodan 	edesc = rctx->edesc;
10135af4e8d4SIuliana Prodan 	has_bklog = edesc->bklog;
1014fa9659cdSMarek Vasut 	if (err)
10151984aaeeSHoria Geantă 		ecode = caam_jr_strstatus(jrdev, err);
1016acdca31dSYuan Kang 
1017bb992bc4SSascha Hauer 	skcipher_unmap(jrdev, edesc, req);
1018bb992bc4SSascha Hauer 
1019334d37c9SHoria Geantă 	/*
1020334d37c9SHoria Geantă 	 * The crypto API expects us to set the IV (req->iv) to the last
1021334d37c9SHoria Geantă 	 * ciphertext block (CBC mode) or last counter (CTR mode).
1022334d37c9SHoria Geantă 	 * This is used e.g. by the CTS mode.
1023334d37c9SHoria Geantă 	 */
10241ccb39ebSHoria Geantă 	if (ivsize && !ecode) {
1025334d37c9SHoria Geantă 		memcpy(req->iv, (u8 *)edesc->sec4_sg + edesc->sec4_sg_bytes,
1026334d37c9SHoria Geantă 		       ivsize);
1027334d37c9SHoria Geantă 
10286e005503SSascha Hauer 		print_hex_dump_debug("dstiv  @" __stringify(__LINE__)": ",
1029334d37c9SHoria Geantă 				     DUMP_PREFIX_ADDRESS, 16, 4, req->iv,
1030334d37c9SHoria Geantă 				     ivsize, 1);
1031334d37c9SHoria Geantă 	}
1032334d37c9SHoria Geantă 
10338a82451bSSascha Hauer 	caam_dump_sg("dst    @" __stringify(__LINE__)": ",
10345ecf8ef9SCatalin Vasile 		     DUMP_PREFIX_ADDRESS, 16, 4, req->dst,
10355ca7badbSHoria Geantă 		     edesc->dst_nents > 1 ? 100 : req->cryptlen, 1);
1036acdca31dSYuan Kang 
1037acdca31dSYuan Kang 	kfree(edesc);
1038acdca31dSYuan Kang 
1039ee38767fSIuliana Prodan 	/*
1040ee38767fSIuliana Prodan 	 * If no backlog flag, the completion of the request is done
1041ee38767fSIuliana Prodan 	 * by CAAM, not crypto engine.
1042ee38767fSIuliana Prodan 	 */
10435af4e8d4SIuliana Prodan 	if (!has_bklog)
10441984aaeeSHoria Geantă 		skcipher_request_complete(req, ecode);
1045ee38767fSIuliana Prodan 	else
1046ee38767fSIuliana Prodan 		crypto_finalize_skcipher_request(jrp->engine, req, ecode);
1047acdca31dSYuan Kang }
1048acdca31dSYuan Kang 
10498e8ec596SKim Phillips /*
10501acebad3SYuan Kang  * Fill in aead job descriptor
10518e8ec596SKim Phillips  */
1052f2147b88SHerbert Xu static void init_aead_job(struct aead_request *req,
1053f2147b88SHerbert Xu 			  struct aead_edesc *edesc,
1054f2147b88SHerbert Xu 			  bool all_contig, bool encrypt)
1055f2147b88SHerbert Xu {
1056f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1057f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1058f2147b88SHerbert Xu 	int authsize = ctx->authsize;
1059f2147b88SHerbert Xu 	u32 *desc = edesc->hw_desc;
1060f2147b88SHerbert Xu 	u32 out_options, in_options;
1061f2147b88SHerbert Xu 	dma_addr_t dst_dma, src_dma;
1062f2147b88SHerbert Xu 	int len, sec4_sg_index = 0;
1063f2147b88SHerbert Xu 	dma_addr_t ptr;
1064f2147b88SHerbert Xu 	u32 *sh_desc;
1065f2147b88SHerbert Xu 
1066f2147b88SHerbert Xu 	sh_desc = encrypt ? ctx->sh_desc_enc : ctx->sh_desc_dec;
1067f2147b88SHerbert Xu 	ptr = encrypt ? ctx->sh_desc_enc_dma : ctx->sh_desc_dec_dma;
1068f2147b88SHerbert Xu 
1069f2147b88SHerbert Xu 	len = desc_len(sh_desc);
1070f2147b88SHerbert Xu 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
1071f2147b88SHerbert Xu 
1072f2147b88SHerbert Xu 	if (all_contig) {
1073ba4cf71bSIuliana Prodan 		src_dma = edesc->mapped_src_nents ? sg_dma_address(req->src) :
1074ba4cf71bSIuliana Prodan 						    0;
1075f2147b88SHerbert Xu 		in_options = 0;
1076f2147b88SHerbert Xu 	} else {
1077f2147b88SHerbert Xu 		src_dma = edesc->sec4_sg_dma;
1078ba4cf71bSIuliana Prodan 		sec4_sg_index += edesc->mapped_src_nents;
1079f2147b88SHerbert Xu 		in_options = LDST_SGF;
1080f2147b88SHerbert Xu 	}
1081f2147b88SHerbert Xu 
1082f2147b88SHerbert Xu 	append_seq_in_ptr(desc, src_dma, req->assoclen + req->cryptlen,
1083f2147b88SHerbert Xu 			  in_options);
1084f2147b88SHerbert Xu 
1085f2147b88SHerbert Xu 	dst_dma = src_dma;
1086f2147b88SHerbert Xu 	out_options = in_options;
1087f2147b88SHerbert Xu 
1088f2147b88SHerbert Xu 	if (unlikely(req->src != req->dst)) {
1089ba4cf71bSIuliana Prodan 		if (!edesc->mapped_dst_nents) {
1090763069baSHoria Geantă 			dst_dma = 0;
1091dcd9c76eSHoria Geantă 			out_options = 0;
1092ba4cf71bSIuliana Prodan 		} else if (edesc->mapped_dst_nents == 1) {
1093f2147b88SHerbert Xu 			dst_dma = sg_dma_address(req->dst);
109442e95d1fSPankaj Gupta 			out_options = 0;
1095f2147b88SHerbert Xu 		} else {
1096f2147b88SHerbert Xu 			dst_dma = edesc->sec4_sg_dma +
1097f2147b88SHerbert Xu 				  sec4_sg_index *
1098f2147b88SHerbert Xu 				  sizeof(struct sec4_sg_entry);
1099f2147b88SHerbert Xu 			out_options = LDST_SGF;
1100f2147b88SHerbert Xu 		}
1101f2147b88SHerbert Xu 	}
1102f2147b88SHerbert Xu 
1103f2147b88SHerbert Xu 	if (encrypt)
1104f2147b88SHerbert Xu 		append_seq_out_ptr(desc, dst_dma,
1105f2147b88SHerbert Xu 				   req->assoclen + req->cryptlen + authsize,
1106f2147b88SHerbert Xu 				   out_options);
1107f2147b88SHerbert Xu 	else
1108f2147b88SHerbert Xu 		append_seq_out_ptr(desc, dst_dma,
1109f2147b88SHerbert Xu 				   req->assoclen + req->cryptlen - authsize,
1110f2147b88SHerbert Xu 				   out_options);
1111f2147b88SHerbert Xu }
1112f2147b88SHerbert Xu 
1113f2147b88SHerbert Xu static void init_gcm_job(struct aead_request *req,
1114f2147b88SHerbert Xu 			 struct aead_edesc *edesc,
1115f2147b88SHerbert Xu 			 bool all_contig, bool encrypt)
1116f2147b88SHerbert Xu {
1117f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1118f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1119f2147b88SHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
1120f2147b88SHerbert Xu 	u32 *desc = edesc->hw_desc;
11217545e166SCorentin LABBE 	bool generic_gcm = (ivsize == GCM_AES_IV_SIZE);
1122f2147b88SHerbert Xu 	unsigned int last;
1123f2147b88SHerbert Xu 
1124f2147b88SHerbert Xu 	init_aead_job(req, edesc, all_contig, encrypt);
11257e0880b9SHoria Geantă 	append_math_add_imm_u32(desc, REG3, ZERO, IMM, req->assoclen);
1126f2147b88SHerbert Xu 
1127f2147b88SHerbert Xu 	/* BUG This should not be specific to generic GCM. */
1128f2147b88SHerbert Xu 	last = 0;
1129f2147b88SHerbert Xu 	if (encrypt && generic_gcm && !(req->assoclen + req->cryptlen))
1130f2147b88SHerbert Xu 		last = FIFOLD_TYPE_LAST1;
1131f2147b88SHerbert Xu 
1132f2147b88SHerbert Xu 	/* Read GCM IV */
1133f2147b88SHerbert Xu 	append_cmd(desc, CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 | IMMEDIATE |
11347545e166SCorentin LABBE 			 FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 | GCM_AES_IV_SIZE | last);
1135f2147b88SHerbert Xu 	/* Append Salt */
1136f2147b88SHerbert Xu 	if (!generic_gcm)
1137db57656bSHoria Geantă 		append_data(desc, ctx->key + ctx->cdata.keylen, 4);
1138f2147b88SHerbert Xu 	/* Append IV */
1139f2147b88SHerbert Xu 	append_data(desc, req->iv, ivsize);
1140f2147b88SHerbert Xu 	/* End of blank commands */
1141f2147b88SHerbert Xu }
1142f2147b88SHerbert Xu 
1143d6bbd4eeSHoria Geantă static void init_chachapoly_job(struct aead_request *req,
1144d6bbd4eeSHoria Geantă 				struct aead_edesc *edesc, bool all_contig,
1145d6bbd4eeSHoria Geantă 				bool encrypt)
1146d6bbd4eeSHoria Geantă {
1147d6bbd4eeSHoria Geantă 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1148d6bbd4eeSHoria Geantă 	unsigned int ivsize = crypto_aead_ivsize(aead);
1149d6bbd4eeSHoria Geantă 	unsigned int assoclen = req->assoclen;
1150d6bbd4eeSHoria Geantă 	u32 *desc = edesc->hw_desc;
1151d6bbd4eeSHoria Geantă 	u32 ctx_iv_off = 4;
1152d6bbd4eeSHoria Geantă 
1153d6bbd4eeSHoria Geantă 	init_aead_job(req, edesc, all_contig, encrypt);
1154d6bbd4eeSHoria Geantă 
1155d6bbd4eeSHoria Geantă 	if (ivsize != CHACHAPOLY_IV_SIZE) {
1156d6bbd4eeSHoria Geantă 		/* IPsec specific: CONTEXT1[223:128] = {NONCE, IV} */
1157d6bbd4eeSHoria Geantă 		ctx_iv_off += 4;
1158d6bbd4eeSHoria Geantă 
1159d6bbd4eeSHoria Geantă 		/*
1160d6bbd4eeSHoria Geantă 		 * The associated data comes already with the IV but we need
1161d6bbd4eeSHoria Geantă 		 * to skip it when we authenticate or encrypt...
1162d6bbd4eeSHoria Geantă 		 */
1163d6bbd4eeSHoria Geantă 		assoclen -= ivsize;
1164d6bbd4eeSHoria Geantă 	}
1165d6bbd4eeSHoria Geantă 
1166d6bbd4eeSHoria Geantă 	append_math_add_imm_u32(desc, REG3, ZERO, IMM, assoclen);
1167d6bbd4eeSHoria Geantă 
1168d6bbd4eeSHoria Geantă 	/*
1169d6bbd4eeSHoria Geantă 	 * For IPsec load the IV further in the same register.
1170d6bbd4eeSHoria Geantă 	 * For RFC7539 simply load the 12 bytes nonce in a single operation
1171d6bbd4eeSHoria Geantă 	 */
1172d6bbd4eeSHoria Geantă 	append_load_as_imm(desc, req->iv, ivsize, LDST_CLASS_1_CCB |
1173d6bbd4eeSHoria Geantă 			   LDST_SRCDST_BYTE_CONTEXT |
1174d6bbd4eeSHoria Geantă 			   ctx_iv_off << LDST_OFFSET_SHIFT);
1175d6bbd4eeSHoria Geantă }
1176d6bbd4eeSHoria Geantă 
1177479bcc7cSHerbert Xu static void init_authenc_job(struct aead_request *req,
11781acebad3SYuan Kang 			     struct aead_edesc *edesc,
1179479bcc7cSHerbert Xu 			     bool all_contig, bool encrypt)
11801acebad3SYuan Kang {
11811acebad3SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1182479bcc7cSHerbert Xu 	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
1183479bcc7cSHerbert Xu 						 struct caam_aead_alg, aead);
1184479bcc7cSHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
11851acebad3SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
11867e0880b9SHoria Geantă 	struct caam_drv_private *ctrlpriv = dev_get_drvdata(ctx->jrdev->parent);
1187db57656bSHoria Geantă 	const bool ctr_mode = ((ctx->cdata.algtype & OP_ALG_AAI_MASK) ==
1188479bcc7cSHerbert Xu 			       OP_ALG_AAI_CTR_MOD128);
1189479bcc7cSHerbert Xu 	const bool is_rfc3686 = alg->caam.rfc3686;
11901acebad3SYuan Kang 	u32 *desc = edesc->hw_desc;
1191479bcc7cSHerbert Xu 	u32 ivoffset = 0;
11928e8ec596SKim Phillips 
1193479bcc7cSHerbert Xu 	/*
1194479bcc7cSHerbert Xu 	 * AES-CTR needs to load IV in CONTEXT1 reg
1195479bcc7cSHerbert Xu 	 * at an offset of 128bits (16bytes)
1196479bcc7cSHerbert Xu 	 * CONTEXT1[255:128] = IV
1197479bcc7cSHerbert Xu 	 */
1198479bcc7cSHerbert Xu 	if (ctr_mode)
1199479bcc7cSHerbert Xu 		ivoffset = 16;
12008e8ec596SKim Phillips 
1201479bcc7cSHerbert Xu 	/*
1202479bcc7cSHerbert Xu 	 * RFC3686 specific:
1203479bcc7cSHerbert Xu 	 *	CONTEXT1[255:128] = {NONCE, IV, COUNTER}
1204479bcc7cSHerbert Xu 	 */
1205479bcc7cSHerbert Xu 	if (is_rfc3686)
1206479bcc7cSHerbert Xu 		ivoffset = 16 + CTR_RFC3686_NONCE_SIZE;
1207bac68f2cSTudor Ambarus 
1208479bcc7cSHerbert Xu 	init_aead_job(req, edesc, all_contig, encrypt);
12091acebad3SYuan Kang 
12107e0880b9SHoria Geantă 	/*
12117e0880b9SHoria Geantă 	 * {REG3, DPOVRD} = assoclen, depending on whether MATH command supports
12127e0880b9SHoria Geantă 	 * having DPOVRD as destination.
12137e0880b9SHoria Geantă 	 */
12147e0880b9SHoria Geantă 	if (ctrlpriv->era < 3)
12157e0880b9SHoria Geantă 		append_math_add_imm_u32(desc, REG3, ZERO, IMM, req->assoclen);
12167e0880b9SHoria Geantă 	else
12177e0880b9SHoria Geantă 		append_math_add_imm_u32(desc, DPOVRD, ZERO, IMM, req->assoclen);
12187e0880b9SHoria Geantă 
12198b18e235SHoria Geantă 	if (ivsize && ((is_rfc3686 && encrypt) || !alg->caam.geniv))
1220479bcc7cSHerbert Xu 		append_load_as_imm(desc, req->iv, ivsize,
1221479bcc7cSHerbert Xu 				   LDST_CLASS_1_CCB |
1222479bcc7cSHerbert Xu 				   LDST_SRCDST_BYTE_CONTEXT |
1223479bcc7cSHerbert Xu 				   (ivoffset << LDST_OFFSET_SHIFT));
12248e8ec596SKim Phillips }
12258e8ec596SKim Phillips 
12268e8ec596SKim Phillips /*
12275ca7badbSHoria Geantă  * Fill in skcipher job descriptor
1228acdca31dSYuan Kang  */
12295ca7badbSHoria Geantă static void init_skcipher_job(struct skcipher_request *req,
12305ca7badbSHoria Geantă 			      struct skcipher_edesc *edesc,
12315ca7badbSHoria Geantă 			      const bool encrypt)
1232acdca31dSYuan Kang {
12335ca7badbSHoria Geantă 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
12345ca7badbSHoria Geantă 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
12356e005503SSascha Hauer 	struct device *jrdev = ctx->jrdev;
12365ca7badbSHoria Geantă 	int ivsize = crypto_skcipher_ivsize(skcipher);
1237acdca31dSYuan Kang 	u32 *desc = edesc->hw_desc;
12385ca7badbSHoria Geantă 	u32 *sh_desc;
1239eaed71a4SIuliana Prodan 	u32 in_options = 0, out_options = 0;
1240eaed71a4SIuliana Prodan 	dma_addr_t src_dma, dst_dma, ptr;
1241eaed71a4SIuliana Prodan 	int len, sec4_sg_index = 0;
1242acdca31dSYuan Kang 
12436e005503SSascha Hauer 	print_hex_dump_debug("presciv@"__stringify(__LINE__)": ",
12445ca7badbSHoria Geantă 			     DUMP_PREFIX_ADDRESS, 16, 4, req->iv, ivsize, 1);
12456e005503SSascha Hauer 	dev_dbg(jrdev, "asked=%d, cryptlen%d\n",
12465ca7badbSHoria Geantă 	       (int)edesc->src_nents > 1 ? 100 : req->cryptlen, req->cryptlen);
12476e005503SSascha Hauer 
12488a82451bSSascha Hauer 	caam_dump_sg("src    @" __stringify(__LINE__)": ",
12495ecf8ef9SCatalin Vasile 		     DUMP_PREFIX_ADDRESS, 16, 4, req->src,
12505ca7badbSHoria Geantă 		     edesc->src_nents > 1 ? 100 : req->cryptlen, 1);
12515ca7badbSHoria Geantă 
12525ca7badbSHoria Geantă 	sh_desc = encrypt ? ctx->sh_desc_enc : ctx->sh_desc_dec;
12535ca7badbSHoria Geantă 	ptr = encrypt ? ctx->sh_desc_enc_dma : ctx->sh_desc_dec_dma;
1254acdca31dSYuan Kang 
1255acdca31dSYuan Kang 	len = desc_len(sh_desc);
1256acdca31dSYuan Kang 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
1257acdca31dSYuan Kang 
1258eaed71a4SIuliana Prodan 	if (ivsize || edesc->mapped_src_nents > 1) {
1259eaed71a4SIuliana Prodan 		src_dma = edesc->sec4_sg_dma;
1260eaed71a4SIuliana Prodan 		sec4_sg_index = edesc->mapped_src_nents + !!ivsize;
1261eaed71a4SIuliana Prodan 		in_options = LDST_SGF;
1262eaed71a4SIuliana Prodan 	} else {
1263eaed71a4SIuliana Prodan 		src_dma = sg_dma_address(req->src);
1264eaed71a4SIuliana Prodan 	}
1265eaed71a4SIuliana Prodan 
1266eaed71a4SIuliana Prodan 	append_seq_in_ptr(desc, src_dma, req->cryptlen + ivsize, in_options);
1267acdca31dSYuan Kang 
1268acdca31dSYuan Kang 	if (likely(req->src == req->dst)) {
1269eaed71a4SIuliana Prodan 		dst_dma = src_dma + !!ivsize * sizeof(struct sec4_sg_entry);
1270eaed71a4SIuliana Prodan 		out_options = in_options;
1271334d37c9SHoria Geantă 	} else if (!ivsize && edesc->mapped_dst_nents == 1) {
1272acdca31dSYuan Kang 		dst_dma = sg_dma_address(req->dst);
1273acdca31dSYuan Kang 	} else {
1274eaed71a4SIuliana Prodan 		dst_dma = edesc->sec4_sg_dma + sec4_sg_index *
1275eaed71a4SIuliana Prodan 			  sizeof(struct sec4_sg_entry);
1276acdca31dSYuan Kang 		out_options = LDST_SGF;
1277acdca31dSYuan Kang 	}
1278eaed71a4SIuliana Prodan 
1279334d37c9SHoria Geantă 	append_seq_out_ptr(desc, dst_dma, req->cryptlen + ivsize, out_options);
1280acdca31dSYuan Kang }
1281acdca31dSYuan Kang 
1282acdca31dSYuan Kang /*
12831acebad3SYuan Kang  * allocate and map the aead extended descriptor
12848e8ec596SKim Phillips  */
1285f2147b88SHerbert Xu static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
1286f2147b88SHerbert Xu 					   int desc_bytes, bool *all_contig_ptr,
1287f2147b88SHerbert Xu 					   bool encrypt)
1288f2147b88SHerbert Xu {
1289f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1290f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1291f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
12921c240226SIuliana Prodan 	struct caam_aead_req_ctx *rctx = aead_request_ctx(req);
1293019d62dbSHoria Geantă 	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
1294019d62dbSHoria Geantă 		       GFP_KERNEL : GFP_ATOMIC;
1295838e0a89SHoria Geantă 	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
1296059d73eeSHoria Geantă 	int src_len, dst_len = 0;
1297f2147b88SHerbert Xu 	struct aead_edesc *edesc;
1298fa0c92dbSHoria Geantă 	int sec4_sg_index, sec4_sg_len, sec4_sg_bytes;
1299f2147b88SHerbert Xu 	unsigned int authsize = ctx->authsize;
1300f2147b88SHerbert Xu 
1301f2147b88SHerbert Xu 	if (unlikely(req->dst != req->src)) {
1302059d73eeSHoria Geantă 		src_len = req->assoclen + req->cryptlen;
1303059d73eeSHoria Geantă 		dst_len = src_len + (encrypt ? authsize : (-authsize));
1304059d73eeSHoria Geantă 
1305059d73eeSHoria Geantă 		src_nents = sg_nents_for_len(req->src, src_len);
1306fd144d83SHoria Geantă 		if (unlikely(src_nents < 0)) {
1307fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
1308059d73eeSHoria Geantă 				src_len);
1309fd144d83SHoria Geantă 			return ERR_PTR(src_nents);
1310fd144d83SHoria Geantă 		}
1311fd144d83SHoria Geantă 
1312059d73eeSHoria Geantă 		dst_nents = sg_nents_for_len(req->dst, dst_len);
1313fd144d83SHoria Geantă 		if (unlikely(dst_nents < 0)) {
1314fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in dst S/G\n",
1315059d73eeSHoria Geantă 				dst_len);
1316fd144d83SHoria Geantă 			return ERR_PTR(dst_nents);
1317fd144d83SHoria Geantă 		}
1318f2147b88SHerbert Xu 	} else {
1319059d73eeSHoria Geantă 		src_len = req->assoclen + req->cryptlen +
1320059d73eeSHoria Geantă 			  (encrypt ? authsize : 0);
1321059d73eeSHoria Geantă 
1322059d73eeSHoria Geantă 		src_nents = sg_nents_for_len(req->src, src_len);
1323fd144d83SHoria Geantă 		if (unlikely(src_nents < 0)) {
1324fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
1325059d73eeSHoria Geantă 				src_len);
1326fd144d83SHoria Geantă 			return ERR_PTR(src_nents);
1327fd144d83SHoria Geantă 		}
1328f2147b88SHerbert Xu 	}
1329f2147b88SHerbert Xu 
1330838e0a89SHoria Geantă 	if (likely(req->src == req->dst)) {
1331838e0a89SHoria Geantă 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1332838e0a89SHoria Geantă 					      DMA_BIDIRECTIONAL);
1333838e0a89SHoria Geantă 		if (unlikely(!mapped_src_nents)) {
1334838e0a89SHoria Geantă 			dev_err(jrdev, "unable to map source\n");
1335838e0a89SHoria Geantă 			return ERR_PTR(-ENOMEM);
1336838e0a89SHoria Geantă 		}
1337838e0a89SHoria Geantă 	} else {
1338838e0a89SHoria Geantă 		/* Cover also the case of null (zero length) input data */
1339838e0a89SHoria Geantă 		if (src_nents) {
1340838e0a89SHoria Geantă 			mapped_src_nents = dma_map_sg(jrdev, req->src,
1341838e0a89SHoria Geantă 						      src_nents, DMA_TO_DEVICE);
1342838e0a89SHoria Geantă 			if (unlikely(!mapped_src_nents)) {
1343838e0a89SHoria Geantă 				dev_err(jrdev, "unable to map source\n");
1344838e0a89SHoria Geantă 				return ERR_PTR(-ENOMEM);
1345838e0a89SHoria Geantă 			}
1346838e0a89SHoria Geantă 		} else {
1347838e0a89SHoria Geantă 			mapped_src_nents = 0;
1348838e0a89SHoria Geantă 		}
1349838e0a89SHoria Geantă 
1350763069baSHoria Geantă 		/* Cover also the case of null (zero length) output data */
1351763069baSHoria Geantă 		if (dst_nents) {
1352763069baSHoria Geantă 			mapped_dst_nents = dma_map_sg(jrdev, req->dst,
1353763069baSHoria Geantă 						      dst_nents,
1354838e0a89SHoria Geantă 						      DMA_FROM_DEVICE);
1355838e0a89SHoria Geantă 			if (unlikely(!mapped_dst_nents)) {
1356838e0a89SHoria Geantă 				dev_err(jrdev, "unable to map destination\n");
1357763069baSHoria Geantă 				dma_unmap_sg(jrdev, req->src, src_nents,
1358763069baSHoria Geantă 					     DMA_TO_DEVICE);
1359838e0a89SHoria Geantă 				return ERR_PTR(-ENOMEM);
1360838e0a89SHoria Geantă 			}
1361763069baSHoria Geantă 		} else {
1362763069baSHoria Geantă 			mapped_dst_nents = 0;
1363763069baSHoria Geantă 		}
1364838e0a89SHoria Geantă 	}
1365838e0a89SHoria Geantă 
1366a5e5c133SHoria Geantă 	/*
1367a5e5c133SHoria Geantă 	 * HW reads 4 S/G entries at a time; make sure the reads don't go beyond
1368a5e5c133SHoria Geantă 	 * the end of the table by allocating more S/G entries.
1369a5e5c133SHoria Geantă 	 */
1370838e0a89SHoria Geantă 	sec4_sg_len = mapped_src_nents > 1 ? mapped_src_nents : 0;
1371a5e5c133SHoria Geantă 	if (mapped_dst_nents > 1)
1372a5e5c133SHoria Geantă 		sec4_sg_len += pad_sg_nents(mapped_dst_nents);
1373a5e5c133SHoria Geantă 	else
1374a5e5c133SHoria Geantă 		sec4_sg_len = pad_sg_nents(sec4_sg_len);
1375a5e5c133SHoria Geantă 
1376f2147b88SHerbert Xu 	sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry);
1377f2147b88SHerbert Xu 
1378f2147b88SHerbert Xu 	/* allocate space for base edesc and hw desc commands, link tables */
1379dde20ae9SVictoria Milhoan 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes,
1380dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
1381f2147b88SHerbert Xu 	if (!edesc) {
1382838e0a89SHoria Geantă 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
1383cf5448b5SHoria Geantă 			   0, 0, 0);
1384f2147b88SHerbert Xu 		return ERR_PTR(-ENOMEM);
1385f2147b88SHerbert Xu 	}
1386f2147b88SHerbert Xu 
1387f2147b88SHerbert Xu 	edesc->src_nents = src_nents;
1388f2147b88SHerbert Xu 	edesc->dst_nents = dst_nents;
1389ba4cf71bSIuliana Prodan 	edesc->mapped_src_nents = mapped_src_nents;
1390ba4cf71bSIuliana Prodan 	edesc->mapped_dst_nents = mapped_dst_nents;
1391f2147b88SHerbert Xu 	edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) +
1392f2147b88SHerbert Xu 			 desc_bytes;
13931c240226SIuliana Prodan 
13941c240226SIuliana Prodan 	rctx->edesc = edesc;
13951c240226SIuliana Prodan 
1396838e0a89SHoria Geantă 	*all_contig_ptr = !(mapped_src_nents > 1);
1397f2147b88SHerbert Xu 
1398f2147b88SHerbert Xu 	sec4_sg_index = 0;
1399838e0a89SHoria Geantă 	if (mapped_src_nents > 1) {
1400059d73eeSHoria Geantă 		sg_to_sec4_sg_last(req->src, src_len,
1401f2147b88SHerbert Xu 				   edesc->sec4_sg + sec4_sg_index, 0);
1402838e0a89SHoria Geantă 		sec4_sg_index += mapped_src_nents;
1403f2147b88SHerbert Xu 	}
1404838e0a89SHoria Geantă 	if (mapped_dst_nents > 1) {
1405059d73eeSHoria Geantă 		sg_to_sec4_sg_last(req->dst, dst_len,
1406f2147b88SHerbert Xu 				   edesc->sec4_sg + sec4_sg_index, 0);
1407f2147b88SHerbert Xu 	}
1408f2147b88SHerbert Xu 
1409f2147b88SHerbert Xu 	if (!sec4_sg_bytes)
1410f2147b88SHerbert Xu 		return edesc;
1411f2147b88SHerbert Xu 
1412f2147b88SHerbert Xu 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
1413f2147b88SHerbert Xu 					    sec4_sg_bytes, DMA_TO_DEVICE);
1414f2147b88SHerbert Xu 	if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
1415f2147b88SHerbert Xu 		dev_err(jrdev, "unable to map S/G table\n");
1416f2147b88SHerbert Xu 		aead_unmap(jrdev, edesc, req);
1417f2147b88SHerbert Xu 		kfree(edesc);
1418f2147b88SHerbert Xu 		return ERR_PTR(-ENOMEM);
1419f2147b88SHerbert Xu 	}
1420f2147b88SHerbert Xu 
1421f2147b88SHerbert Xu 	edesc->sec4_sg_bytes = sec4_sg_bytes;
1422f2147b88SHerbert Xu 
1423f2147b88SHerbert Xu 	return edesc;
1424f2147b88SHerbert Xu }
1425f2147b88SHerbert Xu 
14261c240226SIuliana Prodan static int aead_enqueue_req(struct device *jrdev, struct aead_request *req)
14271c240226SIuliana Prodan {
14281c240226SIuliana Prodan 	struct caam_drv_private_jr *jrpriv = dev_get_drvdata(jrdev);
14291c240226SIuliana Prodan 	struct caam_aead_req_ctx *rctx = aead_request_ctx(req);
14301c240226SIuliana Prodan 	struct aead_edesc *edesc = rctx->edesc;
14311c240226SIuliana Prodan 	u32 *desc = edesc->hw_desc;
14321c240226SIuliana Prodan 	int ret;
14331c240226SIuliana Prodan 
14341c240226SIuliana Prodan 	/*
14351c240226SIuliana Prodan 	 * Only the backlog request are sent to crypto-engine since the others
14361c240226SIuliana Prodan 	 * can be handled by CAAM, if free, especially since JR has up to 1024
14371c240226SIuliana Prodan 	 * entries (more than the 10 entries from crypto-engine).
14381c240226SIuliana Prodan 	 */
14391c240226SIuliana Prodan 	if (req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)
14401c240226SIuliana Prodan 		ret = crypto_transfer_aead_request_to_engine(jrpriv->engine,
14411c240226SIuliana Prodan 							     req);
14421c240226SIuliana Prodan 	else
14431c240226SIuliana Prodan 		ret = caam_jr_enqueue(jrdev, desc, aead_crypt_done, req);
14441c240226SIuliana Prodan 
14451c240226SIuliana Prodan 	if ((ret != -EINPROGRESS) && (ret != -EBUSY)) {
14461c240226SIuliana Prodan 		aead_unmap(jrdev, edesc, req);
14471c240226SIuliana Prodan 		kfree(rctx->edesc);
14481c240226SIuliana Prodan 	}
14491c240226SIuliana Prodan 
14501c240226SIuliana Prodan 	return ret;
14511c240226SIuliana Prodan }
14521c240226SIuliana Prodan 
1453b7f17fe2SIuliana Prodan static inline int chachapoly_crypt(struct aead_request *req, bool encrypt)
14548e8ec596SKim Phillips {
14550e479300SYuan Kang 	struct aead_edesc *edesc;
14568e8ec596SKim Phillips 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
14578e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
14588e8ec596SKim Phillips 	struct device *jrdev = ctx->jrdev;
14591acebad3SYuan Kang 	bool all_contig;
14608e8ec596SKim Phillips 	u32 *desc;
14611acebad3SYuan Kang 
1462b7f17fe2SIuliana Prodan 	edesc = aead_edesc_alloc(req, CHACHAPOLY_DESC_JOB_IO_LEN, &all_contig,
1463b7f17fe2SIuliana Prodan 				 encrypt);
14648e8ec596SKim Phillips 	if (IS_ERR(edesc))
14658e8ec596SKim Phillips 		return PTR_ERR(edesc);
14668e8ec596SKim Phillips 
14678e8ec596SKim Phillips 	desc = edesc->hw_desc;
1468b7f17fe2SIuliana Prodan 
1469b7f17fe2SIuliana Prodan 	init_chachapoly_job(req, edesc, all_contig, encrypt);
1470b7f17fe2SIuliana Prodan 	print_hex_dump_debug("chachapoly jobdesc@" __stringify(__LINE__)": ",
1471b7f17fe2SIuliana Prodan 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1472b7f17fe2SIuliana Prodan 			     1);
1473b7f17fe2SIuliana Prodan 
14741c240226SIuliana Prodan 	return aead_enqueue_req(jrdev, req);
14758e8ec596SKim Phillips }
14768e8ec596SKim Phillips 
1477d6bbd4eeSHoria Geantă static int chachapoly_encrypt(struct aead_request *req)
1478d6bbd4eeSHoria Geantă {
1479b7f17fe2SIuliana Prodan 	return chachapoly_crypt(req, true);
1480d6bbd4eeSHoria Geantă }
1481d6bbd4eeSHoria Geantă 
1482d6bbd4eeSHoria Geantă static int chachapoly_decrypt(struct aead_request *req)
1483d6bbd4eeSHoria Geantă {
1484b7f17fe2SIuliana Prodan 	return chachapoly_crypt(req, false);
1485b7f17fe2SIuliana Prodan }
1486b7f17fe2SIuliana Prodan 
1487b7f17fe2SIuliana Prodan static inline int aead_crypt(struct aead_request *req, bool encrypt)
1488b7f17fe2SIuliana Prodan {
1489d6bbd4eeSHoria Geantă 	struct aead_edesc *edesc;
1490d6bbd4eeSHoria Geantă 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1491d6bbd4eeSHoria Geantă 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1492d6bbd4eeSHoria Geantă 	struct device *jrdev = ctx->jrdev;
1493d6bbd4eeSHoria Geantă 	bool all_contig;
1494d6bbd4eeSHoria Geantă 
1495b7f17fe2SIuliana Prodan 	/* allocate extended descriptor */
1496b7f17fe2SIuliana Prodan 	edesc = aead_edesc_alloc(req, AUTHENC_DESC_JOB_IO_LEN,
1497b7f17fe2SIuliana Prodan 				 &all_contig, encrypt);
1498d6bbd4eeSHoria Geantă 	if (IS_ERR(edesc))
1499d6bbd4eeSHoria Geantă 		return PTR_ERR(edesc);
1500d6bbd4eeSHoria Geantă 
1501b7f17fe2SIuliana Prodan 	/* Create and submit job descriptor */
1502b7f17fe2SIuliana Prodan 	init_authenc_job(req, edesc, all_contig, encrypt);
1503b7f17fe2SIuliana Prodan 
1504b7f17fe2SIuliana Prodan 	print_hex_dump_debug("aead jobdesc@"__stringify(__LINE__)": ",
1505b7f17fe2SIuliana Prodan 			     DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1506b7f17fe2SIuliana Prodan 			     desc_bytes(edesc->hw_desc), 1);
1507b7f17fe2SIuliana Prodan 
15081c240226SIuliana Prodan 	return aead_enqueue_req(jrdev, req);
1509d6bbd4eeSHoria Geantă }
1510d6bbd4eeSHoria Geantă 
1511b7f17fe2SIuliana Prodan static int aead_encrypt(struct aead_request *req)
1512b7f17fe2SIuliana Prodan {
1513b7f17fe2SIuliana Prodan 	return aead_crypt(req, true);
1514b7f17fe2SIuliana Prodan }
1515b7f17fe2SIuliana Prodan 
1516b7f17fe2SIuliana Prodan static int aead_decrypt(struct aead_request *req)
1517b7f17fe2SIuliana Prodan {
1518b7f17fe2SIuliana Prodan 	return aead_crypt(req, false);
1519b7f17fe2SIuliana Prodan }
1520b7f17fe2SIuliana Prodan 
15211c240226SIuliana Prodan static int aead_do_one_req(struct crypto_engine *engine, void *areq)
15221c240226SIuliana Prodan {
15231c240226SIuliana Prodan 	struct aead_request *req = aead_request_cast(areq);
15241c240226SIuliana Prodan 	struct caam_ctx *ctx = crypto_aead_ctx(crypto_aead_reqtfm(req));
15251c240226SIuliana Prodan 	struct caam_aead_req_ctx *rctx = aead_request_ctx(req);
15261c240226SIuliana Prodan 	u32 *desc = rctx->edesc->hw_desc;
15271c240226SIuliana Prodan 	int ret;
15281c240226SIuliana Prodan 
15291c240226SIuliana Prodan 	rctx->edesc->bklog = true;
15301c240226SIuliana Prodan 
15311c240226SIuliana Prodan 	ret = caam_jr_enqueue(ctx->jrdev, desc, aead_crypt_done, req);
15321c240226SIuliana Prodan 
15331c240226SIuliana Prodan 	if (ret != -EINPROGRESS) {
15341c240226SIuliana Prodan 		aead_unmap(ctx->jrdev, rctx->edesc, req);
15351c240226SIuliana Prodan 		kfree(rctx->edesc);
15361c240226SIuliana Prodan 	} else {
15371c240226SIuliana Prodan 		ret = 0;
15381c240226SIuliana Prodan 	}
15391c240226SIuliana Prodan 
15401c240226SIuliana Prodan 	return ret;
15411c240226SIuliana Prodan }
15421c240226SIuliana Prodan 
1543b7f17fe2SIuliana Prodan static inline int gcm_crypt(struct aead_request *req, bool encrypt)
1544b7f17fe2SIuliana Prodan {
1545b7f17fe2SIuliana Prodan 	struct aead_edesc *edesc;
1546b7f17fe2SIuliana Prodan 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1547b7f17fe2SIuliana Prodan 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1548b7f17fe2SIuliana Prodan 	struct device *jrdev = ctx->jrdev;
1549b7f17fe2SIuliana Prodan 	bool all_contig;
1550b7f17fe2SIuliana Prodan 
1551b7f17fe2SIuliana Prodan 	/* allocate extended descriptor */
1552b7f17fe2SIuliana Prodan 	edesc = aead_edesc_alloc(req, GCM_DESC_JOB_IO_LEN, &all_contig,
1553b7f17fe2SIuliana Prodan 				 encrypt);
1554b7f17fe2SIuliana Prodan 	if (IS_ERR(edesc))
1555b7f17fe2SIuliana Prodan 		return PTR_ERR(edesc);
1556b7f17fe2SIuliana Prodan 
1557b7f17fe2SIuliana Prodan 	/* Create and submit job descriptor */
1558b7f17fe2SIuliana Prodan 	init_gcm_job(req, edesc, all_contig, encrypt);
1559b7f17fe2SIuliana Prodan 
1560b7f17fe2SIuliana Prodan 	print_hex_dump_debug("aead jobdesc@"__stringify(__LINE__)": ",
1561b7f17fe2SIuliana Prodan 			     DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1562b7f17fe2SIuliana Prodan 			     desc_bytes(edesc->hw_desc), 1);
1563b7f17fe2SIuliana Prodan 
15641c240226SIuliana Prodan 	return aead_enqueue_req(jrdev, req);
1565b7f17fe2SIuliana Prodan }
1566b7f17fe2SIuliana Prodan 
1567b7f17fe2SIuliana Prodan static int gcm_encrypt(struct aead_request *req)
1568b7f17fe2SIuliana Prodan {
1569b7f17fe2SIuliana Prodan 	return gcm_crypt(req, true);
1570b7f17fe2SIuliana Prodan }
1571b7f17fe2SIuliana Prodan 
1572b7f17fe2SIuliana Prodan static int gcm_decrypt(struct aead_request *req)
1573b7f17fe2SIuliana Prodan {
1574b7f17fe2SIuliana Prodan 	return gcm_crypt(req, false);
1575b7f17fe2SIuliana Prodan }
1576b7f17fe2SIuliana Prodan 
157746218750SHerbert Xu static int ipsec_gcm_encrypt(struct aead_request *req)
157846218750SHerbert Xu {
1579fcd23ed5SIuliana Prodan 	return crypto_ipsec_check_assoclen(req->assoclen) ? : gcm_encrypt(req);
158046218750SHerbert Xu }
158146218750SHerbert Xu 
158246218750SHerbert Xu static int ipsec_gcm_decrypt(struct aead_request *req)
158346218750SHerbert Xu {
1584fcd23ed5SIuliana Prodan 	return crypto_ipsec_check_assoclen(req->assoclen) ? : gcm_decrypt(req);
158546218750SHerbert Xu }
158646218750SHerbert Xu 
1587acdca31dSYuan Kang /*
15885ca7badbSHoria Geantă  * allocate and map the skcipher extended descriptor for skcipher
1589acdca31dSYuan Kang  */
15905ca7badbSHoria Geantă static struct skcipher_edesc *skcipher_edesc_alloc(struct skcipher_request *req,
15915ca7badbSHoria Geantă 						   int desc_bytes)
1592acdca31dSYuan Kang {
15935ca7badbSHoria Geantă 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
15945ca7badbSHoria Geantă 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
1595ee38767fSIuliana Prodan 	struct caam_skcipher_req_ctx *rctx = skcipher_request_ctx(req);
1596acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
159742cfcafbSHoria Geantă 	gfp_t flags = (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ?
1598acdca31dSYuan Kang 		       GFP_KERNEL : GFP_ATOMIC;
1599838e0a89SHoria Geantă 	int src_nents, mapped_src_nents, dst_nents = 0, mapped_dst_nents = 0;
16005ca7badbSHoria Geantă 	struct skcipher_edesc *edesc;
1601eaed71a4SIuliana Prodan 	dma_addr_t iv_dma = 0;
1602115957bbSHoria Geantă 	u8 *iv;
16035ca7badbSHoria Geantă 	int ivsize = crypto_skcipher_ivsize(skcipher);
1604838e0a89SHoria Geantă 	int dst_sg_idx, sec4_sg_ents, sec4_sg_bytes;
1605acdca31dSYuan Kang 
16065ca7badbSHoria Geantă 	src_nents = sg_nents_for_len(req->src, req->cryptlen);
1607fd144d83SHoria Geantă 	if (unlikely(src_nents < 0)) {
1608fd144d83SHoria Geantă 		dev_err(jrdev, "Insufficient bytes (%d) in src S/G\n",
16095ca7badbSHoria Geantă 			req->cryptlen);
1610fd144d83SHoria Geantă 		return ERR_PTR(src_nents);
1611fd144d83SHoria Geantă 	}
1612acdca31dSYuan Kang 
1613fd144d83SHoria Geantă 	if (req->dst != req->src) {
16145ca7badbSHoria Geantă 		dst_nents = sg_nents_for_len(req->dst, req->cryptlen);
1615fd144d83SHoria Geantă 		if (unlikely(dst_nents < 0)) {
1616fd144d83SHoria Geantă 			dev_err(jrdev, "Insufficient bytes (%d) in dst S/G\n",
16175ca7badbSHoria Geantă 				req->cryptlen);
1618fd144d83SHoria Geantă 			return ERR_PTR(dst_nents);
1619fd144d83SHoria Geantă 		}
1620fd144d83SHoria Geantă 	}
1621acdca31dSYuan Kang 
1622acdca31dSYuan Kang 	if (likely(req->src == req->dst)) {
1623838e0a89SHoria Geantă 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1624838e0a89SHoria Geantă 					      DMA_BIDIRECTIONAL);
1625838e0a89SHoria Geantă 		if (unlikely(!mapped_src_nents)) {
1626c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map source\n");
1627c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1628c73e36e8SHoria Geantă 		}
1629acdca31dSYuan Kang 	} else {
1630838e0a89SHoria Geantă 		mapped_src_nents = dma_map_sg(jrdev, req->src, src_nents,
1631838e0a89SHoria Geantă 					      DMA_TO_DEVICE);
1632838e0a89SHoria Geantă 		if (unlikely(!mapped_src_nents)) {
1633c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map source\n");
1634c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1635c73e36e8SHoria Geantă 		}
1636838e0a89SHoria Geantă 		mapped_dst_nents = dma_map_sg(jrdev, req->dst, dst_nents,
1637838e0a89SHoria Geantă 					      DMA_FROM_DEVICE);
1638838e0a89SHoria Geantă 		if (unlikely(!mapped_dst_nents)) {
1639c73e36e8SHoria Geantă 			dev_err(jrdev, "unable to map destination\n");
1640fa0c92dbSHoria Geantă 			dma_unmap_sg(jrdev, req->src, src_nents, DMA_TO_DEVICE);
1641c73e36e8SHoria Geantă 			return ERR_PTR(-ENOMEM);
1642c73e36e8SHoria Geantă 		}
1643acdca31dSYuan Kang 	}
1644acdca31dSYuan Kang 
1645eaed71a4SIuliana Prodan 	if (!ivsize && mapped_src_nents == 1)
1646eaed71a4SIuliana Prodan 		sec4_sg_ents = 0; // no need for an input hw s/g table
1647eaed71a4SIuliana Prodan 	else
1648eaed71a4SIuliana Prodan 		sec4_sg_ents = mapped_src_nents + !!ivsize;
1649fa0c92dbSHoria Geantă 	dst_sg_idx = sec4_sg_ents;
1650a5e5c133SHoria Geantă 
1651a5e5c133SHoria Geantă 	/*
1652334d37c9SHoria Geantă 	 * Input, output HW S/G tables: [IV, src][dst, IV]
1653334d37c9SHoria Geantă 	 * IV entries point to the same buffer
1654334d37c9SHoria Geantă 	 * If src == dst, S/G entries are reused (S/G tables overlap)
1655334d37c9SHoria Geantă 	 *
1656a5e5c133SHoria Geantă 	 * HW reads 4 S/G entries at a time; make sure the reads don't go beyond
1657a5e5c133SHoria Geantă 	 * the end of the table by allocating more S/G entries. Logic:
1658334d37c9SHoria Geantă 	 * if (output S/G)
1659a5e5c133SHoria Geantă 	 *      pad output S/G, if needed
1660a5e5c133SHoria Geantă 	 * else if (input S/G) ...
1661a5e5c133SHoria Geantă 	 *      pad input S/G, if needed
1662a5e5c133SHoria Geantă 	 */
1663334d37c9SHoria Geantă 	if (ivsize || mapped_dst_nents > 1) {
1664334d37c9SHoria Geantă 		if (req->src == req->dst)
1665334d37c9SHoria Geantă 			sec4_sg_ents = !!ivsize + pad_sg_nents(sec4_sg_ents);
1666a5e5c133SHoria Geantă 		else
1667334d37c9SHoria Geantă 			sec4_sg_ents += pad_sg_nents(mapped_dst_nents +
1668334d37c9SHoria Geantă 						     !!ivsize);
1669334d37c9SHoria Geantă 	} else {
1670a5e5c133SHoria Geantă 		sec4_sg_ents = pad_sg_nents(sec4_sg_ents);
1671334d37c9SHoria Geantă 	}
1672a5e5c133SHoria Geantă 
1673fa0c92dbSHoria Geantă 	sec4_sg_bytes = sec4_sg_ents * sizeof(struct sec4_sg_entry);
1674acdca31dSYuan Kang 
1675115957bbSHoria Geantă 	/*
1676115957bbSHoria Geantă 	 * allocate space for base edesc and hw desc commands, link tables, IV
1677115957bbSHoria Geantă 	 */
1678115957bbSHoria Geantă 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes + ivsize,
1679dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
1680acdca31dSYuan Kang 	if (!edesc) {
1681acdca31dSYuan Kang 		dev_err(jrdev, "could not allocate extended descriptor\n");
1682115957bbSHoria Geantă 		caam_unmap(jrdev, req->src, req->dst, src_nents, dst_nents, 0,
1683cf5448b5SHoria Geantă 			   0, 0, 0);
1684acdca31dSYuan Kang 		return ERR_PTR(-ENOMEM);
1685acdca31dSYuan Kang 	}
1686acdca31dSYuan Kang 
1687acdca31dSYuan Kang 	edesc->src_nents = src_nents;
1688acdca31dSYuan Kang 	edesc->dst_nents = dst_nents;
1689ba4cf71bSIuliana Prodan 	edesc->mapped_src_nents = mapped_src_nents;
1690ba4cf71bSIuliana Prodan 	edesc->mapped_dst_nents = mapped_dst_nents;
1691a299c837SYuan Kang 	edesc->sec4_sg_bytes = sec4_sg_bytes;
169213cc6f48SHoria Geantă 	edesc->sec4_sg = (struct sec4_sg_entry *)((u8 *)edesc->hw_desc +
169313cc6f48SHoria Geantă 						  desc_bytes);
1694ee38767fSIuliana Prodan 	rctx->edesc = edesc;
1695acdca31dSYuan Kang 
1696115957bbSHoria Geantă 	/* Make sure IV is located in a DMAable area */
1697eaed71a4SIuliana Prodan 	if (ivsize) {
1698334d37c9SHoria Geantă 		iv = (u8 *)edesc->sec4_sg + sec4_sg_bytes;
16995ca7badbSHoria Geantă 		memcpy(iv, req->iv, ivsize);
1700115957bbSHoria Geantă 
1701334d37c9SHoria Geantă 		iv_dma = dma_map_single(jrdev, iv, ivsize, DMA_BIDIRECTIONAL);
1702115957bbSHoria Geantă 		if (dma_mapping_error(jrdev, iv_dma)) {
1703115957bbSHoria Geantă 			dev_err(jrdev, "unable to map IV\n");
1704eaed71a4SIuliana Prodan 			caam_unmap(jrdev, req->src, req->dst, src_nents,
1705eaed71a4SIuliana Prodan 				   dst_nents, 0, 0, 0, 0);
1706115957bbSHoria Geantă 			kfree(edesc);
1707115957bbSHoria Geantă 			return ERR_PTR(-ENOMEM);
1708acdca31dSYuan Kang 		}
1709acdca31dSYuan Kang 
1710115957bbSHoria Geantă 		dma_to_sec4_sg_one(edesc->sec4_sg, iv_dma, ivsize, 0);
1711eaed71a4SIuliana Prodan 	}
1712eaed71a4SIuliana Prodan 	if (dst_sg_idx)
1713334d37c9SHoria Geantă 		sg_to_sec4_sg(req->src, req->cryptlen, edesc->sec4_sg +
1714eaed71a4SIuliana Prodan 			      !!ivsize, 0);
1715115957bbSHoria Geantă 
1716334d37c9SHoria Geantă 	if (req->src != req->dst && (ivsize || mapped_dst_nents > 1))
1717334d37c9SHoria Geantă 		sg_to_sec4_sg(req->dst, req->cryptlen, edesc->sec4_sg +
1718334d37c9SHoria Geantă 			      dst_sg_idx, 0);
1719334d37c9SHoria Geantă 
1720334d37c9SHoria Geantă 	if (ivsize)
1721334d37c9SHoria Geantă 		dma_to_sec4_sg_one(edesc->sec4_sg + dst_sg_idx +
1722334d37c9SHoria Geantă 				   mapped_dst_nents, iv_dma, ivsize, 0);
1723334d37c9SHoria Geantă 
1724334d37c9SHoria Geantă 	if (ivsize || mapped_dst_nents > 1)
1725334d37c9SHoria Geantă 		sg_to_sec4_set_last(edesc->sec4_sg + dst_sg_idx +
172655b3209aSIuliana Prodan 				    mapped_dst_nents - 1 + !!ivsize);
1727acdca31dSYuan Kang 
1728eaed71a4SIuliana Prodan 	if (sec4_sg_bytes) {
1729a299c837SYuan Kang 		edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
1730eaed71a4SIuliana Prodan 						    sec4_sg_bytes,
1731eaed71a4SIuliana Prodan 						    DMA_TO_DEVICE);
1732ce572085SHoria Geanta 		if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
1733ce572085SHoria Geanta 			dev_err(jrdev, "unable to map S/G table\n");
1734eaed71a4SIuliana Prodan 			caam_unmap(jrdev, req->src, req->dst, src_nents,
1735eaed71a4SIuliana Prodan 				   dst_nents, iv_dma, ivsize, 0, 0);
1736c73e36e8SHoria Geantă 			kfree(edesc);
1737ce572085SHoria Geanta 			return ERR_PTR(-ENOMEM);
1738ce572085SHoria Geanta 		}
1739eaed71a4SIuliana Prodan 	}
1740ce572085SHoria Geanta 
1741acdca31dSYuan Kang 	edesc->iv_dma = iv_dma;
1742acdca31dSYuan Kang 
17436e005503SSascha Hauer 	print_hex_dump_debug("skcipher sec4_sg@" __stringify(__LINE__)": ",
1744a299c837SYuan Kang 			     DUMP_PREFIX_ADDRESS, 16, 4, edesc->sec4_sg,
1745a299c837SYuan Kang 			     sec4_sg_bytes, 1);
1746acdca31dSYuan Kang 
1747acdca31dSYuan Kang 	return edesc;
1748acdca31dSYuan Kang }
1749acdca31dSYuan Kang 
1750ee38767fSIuliana Prodan static int skcipher_do_one_req(struct crypto_engine *engine, void *areq)
1751ee38767fSIuliana Prodan {
1752ee38767fSIuliana Prodan 	struct skcipher_request *req = skcipher_request_cast(areq);
1753ee38767fSIuliana Prodan 	struct caam_ctx *ctx = crypto_skcipher_ctx(crypto_skcipher_reqtfm(req));
1754ee38767fSIuliana Prodan 	struct caam_skcipher_req_ctx *rctx = skcipher_request_ctx(req);
1755ee38767fSIuliana Prodan 	u32 *desc = rctx->edesc->hw_desc;
1756ee38767fSIuliana Prodan 	int ret;
1757ee38767fSIuliana Prodan 
1758ee38767fSIuliana Prodan 	rctx->edesc->bklog = true;
1759ee38767fSIuliana Prodan 
1760ee38767fSIuliana Prodan 	ret = caam_jr_enqueue(ctx->jrdev, desc, skcipher_crypt_done, req);
1761ee38767fSIuliana Prodan 
1762ee38767fSIuliana Prodan 	if (ret != -EINPROGRESS) {
1763ee38767fSIuliana Prodan 		skcipher_unmap(ctx->jrdev, rctx->edesc, req);
1764ee38767fSIuliana Prodan 		kfree(rctx->edesc);
1765ee38767fSIuliana Prodan 	} else {
1766ee38767fSIuliana Prodan 		ret = 0;
1767ee38767fSIuliana Prodan 	}
1768ee38767fSIuliana Prodan 
1769ee38767fSIuliana Prodan 	return ret;
1770ee38767fSIuliana Prodan }
1771ee38767fSIuliana Prodan 
17729d9b14dbSAndrei Botila static inline bool xts_skcipher_ivsize(struct skcipher_request *req)
17739d9b14dbSAndrei Botila {
17749d9b14dbSAndrei Botila 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
17759d9b14dbSAndrei Botila 	unsigned int ivsize = crypto_skcipher_ivsize(skcipher);
17769d9b14dbSAndrei Botila 
17779d9b14dbSAndrei Botila 	return !!get_unaligned((u64 *)(req->iv + (ivsize / 2)));
17789d9b14dbSAndrei Botila }
17799d9b14dbSAndrei Botila 
1780b7f17fe2SIuliana Prodan static inline int skcipher_crypt(struct skcipher_request *req, bool encrypt)
1781acdca31dSYuan Kang {
17825ca7badbSHoria Geantă 	struct skcipher_edesc *edesc;
17835ca7badbSHoria Geantă 	struct crypto_skcipher *skcipher = crypto_skcipher_reqtfm(req);
17845ca7badbSHoria Geantă 	struct caam_ctx *ctx = crypto_skcipher_ctx(skcipher);
1785acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
1786ee38767fSIuliana Prodan 	struct caam_drv_private_jr *jrpriv = dev_get_drvdata(jrdev);
1787acdca31dSYuan Kang 	u32 *desc;
1788acdca31dSYuan Kang 	int ret = 0;
1789acdca31dSYuan Kang 
179031bb2f0dSIuliana Prodan 	if (!req->cryptlen)
179131bb2f0dSIuliana Prodan 		return 0;
179231bb2f0dSIuliana Prodan 
1793c91f7348SAndrei Botila 	if (ctx->fallback && (xts_skcipher_ivsize(req) ||
1794c91f7348SAndrei Botila 			      ctx->xts_key_fallback)) {
17959d9b14dbSAndrei Botila 		struct caam_skcipher_req_ctx *rctx = skcipher_request_ctx(req);
17969d9b14dbSAndrei Botila 
17979d9b14dbSAndrei Botila 		skcipher_request_set_tfm(&rctx->fallback_req, ctx->fallback);
17989d9b14dbSAndrei Botila 		skcipher_request_set_callback(&rctx->fallback_req,
17999d9b14dbSAndrei Botila 					      req->base.flags,
18009d9b14dbSAndrei Botila 					      req->base.complete,
18019d9b14dbSAndrei Botila 					      req->base.data);
18029d9b14dbSAndrei Botila 		skcipher_request_set_crypt(&rctx->fallback_req, req->src,
18039d9b14dbSAndrei Botila 					   req->dst, req->cryptlen, req->iv);
18049d9b14dbSAndrei Botila 
18059d9b14dbSAndrei Botila 		return encrypt ? crypto_skcipher_encrypt(&rctx->fallback_req) :
18069d9b14dbSAndrei Botila 				 crypto_skcipher_decrypt(&rctx->fallback_req);
18079d9b14dbSAndrei Botila 	}
18089d9b14dbSAndrei Botila 
1809acdca31dSYuan Kang 	/* allocate extended descriptor */
18105ca7badbSHoria Geantă 	edesc = skcipher_edesc_alloc(req, DESC_JOB_IO_LEN * CAAM_CMD_SZ);
1811acdca31dSYuan Kang 	if (IS_ERR(edesc))
1812acdca31dSYuan Kang 		return PTR_ERR(edesc);
1813acdca31dSYuan Kang 
1814acdca31dSYuan Kang 	/* Create and submit job descriptor*/
1815b7f17fe2SIuliana Prodan 	init_skcipher_job(req, edesc, encrypt);
18166e005503SSascha Hauer 
18176e005503SSascha Hauer 	print_hex_dump_debug("skcipher jobdesc@" __stringify(__LINE__)": ",
1818acdca31dSYuan Kang 			     DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
1819acdca31dSYuan Kang 			     desc_bytes(edesc->hw_desc), 1);
18206e005503SSascha Hauer 
1821acdca31dSYuan Kang 	desc = edesc->hw_desc;
1822ee38767fSIuliana Prodan 	/*
1823ee38767fSIuliana Prodan 	 * Only the backlog request are sent to crypto-engine since the others
1824ee38767fSIuliana Prodan 	 * can be handled by CAAM, if free, especially since JR has up to 1024
1825ee38767fSIuliana Prodan 	 * entries (more than the 10 entries from crypto-engine).
1826ee38767fSIuliana Prodan 	 */
1827ee38767fSIuliana Prodan 	if (req->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)
1828ee38767fSIuliana Prodan 		ret = crypto_transfer_skcipher_request_to_engine(jrpriv->engine,
1829ee38767fSIuliana Prodan 								 req);
1830ee38767fSIuliana Prodan 	else
1831b7f17fe2SIuliana Prodan 		ret = caam_jr_enqueue(jrdev, desc, skcipher_crypt_done, req);
1832acdca31dSYuan Kang 
1833ee38767fSIuliana Prodan 	if ((ret != -EINPROGRESS) && (ret != -EBUSY)) {
18345ca7badbSHoria Geantă 		skcipher_unmap(jrdev, edesc, req);
1835acdca31dSYuan Kang 		kfree(edesc);
1836acdca31dSYuan Kang 	}
1837acdca31dSYuan Kang 
1838acdca31dSYuan Kang 	return ret;
1839acdca31dSYuan Kang }
1840acdca31dSYuan Kang 
1841b7f17fe2SIuliana Prodan static int skcipher_encrypt(struct skcipher_request *req)
1842b7f17fe2SIuliana Prodan {
1843b7f17fe2SIuliana Prodan 	return skcipher_crypt(req, true);
1844b7f17fe2SIuliana Prodan }
1845b7f17fe2SIuliana Prodan 
18465ca7badbSHoria Geantă static int skcipher_decrypt(struct skcipher_request *req)
1847acdca31dSYuan Kang {
1848b7f17fe2SIuliana Prodan 	return skcipher_crypt(req, false);
1849acdca31dSYuan Kang }
1850acdca31dSYuan Kang 
18515ca7badbSHoria Geantă static struct caam_skcipher_alg driver_algs[] = {
1852acdca31dSYuan Kang 	{
18535ca7badbSHoria Geantă 		.skcipher = {
18545ca7badbSHoria Geantă 			.base = {
18555ca7badbSHoria Geantă 				.cra_name = "cbc(aes)",
18565ca7badbSHoria Geantă 				.cra_driver_name = "cbc-aes-caam",
18575ca7badbSHoria Geantă 				.cra_blocksize = AES_BLOCK_SIZE,
18585ca7badbSHoria Geantă 			},
1859836d8f43SIuliana Prodan 			.setkey = aes_skcipher_setkey,
18605ca7badbSHoria Geantă 			.encrypt = skcipher_encrypt,
18615ca7badbSHoria Geantă 			.decrypt = skcipher_decrypt,
1862acdca31dSYuan Kang 			.min_keysize = AES_MIN_KEY_SIZE,
1863acdca31dSYuan Kang 			.max_keysize = AES_MAX_KEY_SIZE,
1864acdca31dSYuan Kang 			.ivsize = AES_BLOCK_SIZE,
1865acdca31dSYuan Kang 		},
18665ca7badbSHoria Geantă 		.caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
1867acdca31dSYuan Kang 	},
1868acdca31dSYuan Kang 	{
18695ca7badbSHoria Geantă 		.skcipher = {
18705ca7badbSHoria Geantă 			.base = {
18715ca7badbSHoria Geantă 				.cra_name = "cbc(des3_ede)",
18725ca7badbSHoria Geantă 				.cra_driver_name = "cbc-3des-caam",
18735ca7badbSHoria Geantă 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
18745ca7badbSHoria Geantă 			},
1875a628c5a1SArd Biesheuvel 			.setkey = des3_skcipher_setkey,
18765ca7badbSHoria Geantă 			.encrypt = skcipher_encrypt,
18775ca7badbSHoria Geantă 			.decrypt = skcipher_decrypt,
1878acdca31dSYuan Kang 			.min_keysize = DES3_EDE_KEY_SIZE,
1879acdca31dSYuan Kang 			.max_keysize = DES3_EDE_KEY_SIZE,
1880acdca31dSYuan Kang 			.ivsize = DES3_EDE_BLOCK_SIZE,
1881acdca31dSYuan Kang 		},
18825ca7badbSHoria Geantă 		.caam.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
1883acdca31dSYuan Kang 	},
1884acdca31dSYuan Kang 	{
18855ca7badbSHoria Geantă 		.skcipher = {
18865ca7badbSHoria Geantă 			.base = {
18875ca7badbSHoria Geantă 				.cra_name = "cbc(des)",
18885ca7badbSHoria Geantă 				.cra_driver_name = "cbc-des-caam",
18895ca7badbSHoria Geantă 				.cra_blocksize = DES_BLOCK_SIZE,
18905ca7badbSHoria Geantă 			},
1891cf64e495SIuliana Prodan 			.setkey = des_skcipher_setkey,
18925ca7badbSHoria Geantă 			.encrypt = skcipher_encrypt,
18935ca7badbSHoria Geantă 			.decrypt = skcipher_decrypt,
1894acdca31dSYuan Kang 			.min_keysize = DES_KEY_SIZE,
1895acdca31dSYuan Kang 			.max_keysize = DES_KEY_SIZE,
1896acdca31dSYuan Kang 			.ivsize = DES_BLOCK_SIZE,
1897acdca31dSYuan Kang 		},
18985ca7badbSHoria Geantă 		.caam.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
18992b22f6c5SCatalin Vasile 	},
19002b22f6c5SCatalin Vasile 	{
19015ca7badbSHoria Geantă 		.skcipher = {
19025ca7badbSHoria Geantă 			.base = {
19035ca7badbSHoria Geantă 				.cra_name = "ctr(aes)",
19045ca7badbSHoria Geantă 				.cra_driver_name = "ctr-aes-caam",
19055ca7badbSHoria Geantă 				.cra_blocksize = 1,
19065ca7badbSHoria Geantă 			},
1907836d8f43SIuliana Prodan 			.setkey = ctr_skcipher_setkey,
19085ca7badbSHoria Geantă 			.encrypt = skcipher_encrypt,
19095ca7badbSHoria Geantă 			.decrypt = skcipher_decrypt,
19102b22f6c5SCatalin Vasile 			.min_keysize = AES_MIN_KEY_SIZE,
19112b22f6c5SCatalin Vasile 			.max_keysize = AES_MAX_KEY_SIZE,
19122b22f6c5SCatalin Vasile 			.ivsize = AES_BLOCK_SIZE,
19135ca7badbSHoria Geantă 			.chunksize = AES_BLOCK_SIZE,
19142b22f6c5SCatalin Vasile 		},
19155ca7badbSHoria Geantă 		.caam.class1_alg_type = OP_ALG_ALGSEL_AES |
19165ca7badbSHoria Geantă 					OP_ALG_AAI_CTR_MOD128,
1917a5f57cffSCatalin Vasile 	},
1918a5f57cffSCatalin Vasile 	{
19195ca7badbSHoria Geantă 		.skcipher = {
19205ca7badbSHoria Geantă 			.base = {
19215ca7badbSHoria Geantă 				.cra_name = "rfc3686(ctr(aes))",
19225ca7badbSHoria Geantă 				.cra_driver_name = "rfc3686-ctr-aes-caam",
19235ca7badbSHoria Geantă 				.cra_blocksize = 1,
19245ca7badbSHoria Geantă 			},
1925836d8f43SIuliana Prodan 			.setkey = rfc3686_skcipher_setkey,
19265ca7badbSHoria Geantă 			.encrypt = skcipher_encrypt,
19275ca7badbSHoria Geantă 			.decrypt = skcipher_decrypt,
1928a5f57cffSCatalin Vasile 			.min_keysize = AES_MIN_KEY_SIZE +
1929a5f57cffSCatalin Vasile 				       CTR_RFC3686_NONCE_SIZE,
1930a5f57cffSCatalin Vasile 			.max_keysize = AES_MAX_KEY_SIZE +
1931a5f57cffSCatalin Vasile 				       CTR_RFC3686_NONCE_SIZE,
1932a5f57cffSCatalin Vasile 			.ivsize = CTR_RFC3686_IV_SIZE,
19335ca7badbSHoria Geantă 			.chunksize = AES_BLOCK_SIZE,
1934a5f57cffSCatalin Vasile 		},
19355ca7badbSHoria Geantă 		.caam = {
19365ca7badbSHoria Geantă 			.class1_alg_type = OP_ALG_ALGSEL_AES |
19375ca7badbSHoria Geantă 					   OP_ALG_AAI_CTR_MOD128,
19385ca7badbSHoria Geantă 			.rfc3686 = true,
19395ca7badbSHoria Geantă 		},
1940c6415a60SCatalin Vasile 	},
1941c6415a60SCatalin Vasile 	{
19425ca7badbSHoria Geantă 		.skcipher = {
19435ca7badbSHoria Geantă 			.base = {
19445ca7badbSHoria Geantă 				.cra_name = "xts(aes)",
19455ca7badbSHoria Geantă 				.cra_driver_name = "xts-aes-caam",
19469d9b14dbSAndrei Botila 				.cra_flags = CRYPTO_ALG_NEED_FALLBACK,
19475ca7badbSHoria Geantă 				.cra_blocksize = AES_BLOCK_SIZE,
19485ca7badbSHoria Geantă 			},
19495ca7badbSHoria Geantă 			.setkey = xts_skcipher_setkey,
19505ca7badbSHoria Geantă 			.encrypt = skcipher_encrypt,
19515ca7badbSHoria Geantă 			.decrypt = skcipher_decrypt,
1952c6415a60SCatalin Vasile 			.min_keysize = 2 * AES_MIN_KEY_SIZE,
1953c6415a60SCatalin Vasile 			.max_keysize = 2 * AES_MAX_KEY_SIZE,
1954c6415a60SCatalin Vasile 			.ivsize = AES_BLOCK_SIZE,
1955c6415a60SCatalin Vasile 		},
19565ca7badbSHoria Geantă 		.caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_XTS,
1957c6415a60SCatalin Vasile 	},
1958eaed71a4SIuliana Prodan 	{
1959eaed71a4SIuliana Prodan 		.skcipher = {
1960eaed71a4SIuliana Prodan 			.base = {
1961eaed71a4SIuliana Prodan 				.cra_name = "ecb(des)",
1962eaed71a4SIuliana Prodan 				.cra_driver_name = "ecb-des-caam",
1963eaed71a4SIuliana Prodan 				.cra_blocksize = DES_BLOCK_SIZE,
1964eaed71a4SIuliana Prodan 			},
1965eaed71a4SIuliana Prodan 			.setkey = des_skcipher_setkey,
1966eaed71a4SIuliana Prodan 			.encrypt = skcipher_encrypt,
1967eaed71a4SIuliana Prodan 			.decrypt = skcipher_decrypt,
1968eaed71a4SIuliana Prodan 			.min_keysize = DES_KEY_SIZE,
1969eaed71a4SIuliana Prodan 			.max_keysize = DES_KEY_SIZE,
1970eaed71a4SIuliana Prodan 		},
1971eaed71a4SIuliana Prodan 		.caam.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_ECB,
1972eaed71a4SIuliana Prodan 	},
1973eaed71a4SIuliana Prodan 	{
1974eaed71a4SIuliana Prodan 		.skcipher = {
1975eaed71a4SIuliana Prodan 			.base = {
1976eaed71a4SIuliana Prodan 				.cra_name = "ecb(aes)",
1977eaed71a4SIuliana Prodan 				.cra_driver_name = "ecb-aes-caam",
1978eaed71a4SIuliana Prodan 				.cra_blocksize = AES_BLOCK_SIZE,
1979eaed71a4SIuliana Prodan 			},
1980836d8f43SIuliana Prodan 			.setkey = aes_skcipher_setkey,
1981eaed71a4SIuliana Prodan 			.encrypt = skcipher_encrypt,
1982eaed71a4SIuliana Prodan 			.decrypt = skcipher_decrypt,
1983eaed71a4SIuliana Prodan 			.min_keysize = AES_MIN_KEY_SIZE,
1984eaed71a4SIuliana Prodan 			.max_keysize = AES_MAX_KEY_SIZE,
1985eaed71a4SIuliana Prodan 		},
1986eaed71a4SIuliana Prodan 		.caam.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_ECB,
1987eaed71a4SIuliana Prodan 	},
1988eaed71a4SIuliana Prodan 	{
1989eaed71a4SIuliana Prodan 		.skcipher = {
1990eaed71a4SIuliana Prodan 			.base = {
1991eaed71a4SIuliana Prodan 				.cra_name = "ecb(des3_ede)",
1992eaed71a4SIuliana Prodan 				.cra_driver_name = "ecb-des3-caam",
1993eaed71a4SIuliana Prodan 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
1994eaed71a4SIuliana Prodan 			},
1995a628c5a1SArd Biesheuvel 			.setkey = des3_skcipher_setkey,
1996eaed71a4SIuliana Prodan 			.encrypt = skcipher_encrypt,
1997eaed71a4SIuliana Prodan 			.decrypt = skcipher_decrypt,
1998eaed71a4SIuliana Prodan 			.min_keysize = DES3_EDE_KEY_SIZE,
1999eaed71a4SIuliana Prodan 			.max_keysize = DES3_EDE_KEY_SIZE,
2000eaed71a4SIuliana Prodan 		},
2001eaed71a4SIuliana Prodan 		.caam.class1_alg_type = OP_ALG_ALGSEL_3DES | 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,
202224586b5fSHerbert Xu 			.nodkp = true,
2023f2147b88SHerbert Xu 		},
2024f2147b88SHerbert Xu 	},
2025f2147b88SHerbert Xu 	{
2026f2147b88SHerbert Xu 		.aead = {
2027f2147b88SHerbert Xu 			.base = {
2028f2147b88SHerbert Xu 				.cra_name = "rfc4543(gcm(aes))",
2029f2147b88SHerbert Xu 				.cra_driver_name = "rfc4543-gcm-aes-caam",
2030f2147b88SHerbert Xu 				.cra_blocksize = 1,
2031f2147b88SHerbert Xu 			},
2032f2147b88SHerbert Xu 			.setkey = rfc4543_setkey,
2033f2147b88SHerbert Xu 			.setauthsize = rfc4543_setauthsize,
203446218750SHerbert Xu 			.encrypt = ipsec_gcm_encrypt,
203546218750SHerbert Xu 			.decrypt = ipsec_gcm_decrypt,
20367545e166SCorentin LABBE 			.ivsize = GCM_RFC4543_IV_SIZE,
2037f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
2038f2147b88SHerbert Xu 		},
2039f2147b88SHerbert Xu 		.caam = {
2040f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
204124586b5fSHerbert Xu 			.nodkp = true,
2042f2147b88SHerbert Xu 		},
2043f2147b88SHerbert Xu 	},
2044f2147b88SHerbert Xu 	/* Galois Counter Mode */
2045f2147b88SHerbert Xu 	{
2046f2147b88SHerbert Xu 		.aead = {
2047f2147b88SHerbert Xu 			.base = {
2048f2147b88SHerbert Xu 				.cra_name = "gcm(aes)",
2049f2147b88SHerbert Xu 				.cra_driver_name = "gcm-aes-caam",
2050f2147b88SHerbert Xu 				.cra_blocksize = 1,
2051f2147b88SHerbert Xu 			},
2052f2147b88SHerbert Xu 			.setkey = gcm_setkey,
2053f2147b88SHerbert Xu 			.setauthsize = gcm_setauthsize,
2054f2147b88SHerbert Xu 			.encrypt = gcm_encrypt,
2055f2147b88SHerbert Xu 			.decrypt = gcm_decrypt,
20567545e166SCorentin LABBE 			.ivsize = GCM_AES_IV_SIZE,
2057f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
2058f2147b88SHerbert Xu 		},
2059f2147b88SHerbert Xu 		.caam = {
2060f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
206124586b5fSHerbert Xu 			.nodkp = true,
2062f2147b88SHerbert Xu 		},
2063f2147b88SHerbert Xu 	},
2064479bcc7cSHerbert Xu 	/* single-pass ipsec_esp descriptor */
2065479bcc7cSHerbert Xu 	{
2066479bcc7cSHerbert Xu 		.aead = {
2067479bcc7cSHerbert Xu 			.base = {
2068479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),"
2069479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2070479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2071479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2072479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2073479bcc7cSHerbert Xu 			},
2074479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2075479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2076479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2077479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2078479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2079479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2080479bcc7cSHerbert Xu 		},
2081479bcc7cSHerbert Xu 		.caam = {
2082479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2083479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2084479bcc7cSHerbert Xu 		},
2085479bcc7cSHerbert Xu 	},
2086479bcc7cSHerbert Xu 	{
2087479bcc7cSHerbert Xu 		.aead = {
2088479bcc7cSHerbert Xu 			.base = {
2089479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
2090479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2091479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2092479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2093479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2094479bcc7cSHerbert Xu 			},
2095479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2096479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2097479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2098479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2099479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2100479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2101479bcc7cSHerbert Xu 		},
2102479bcc7cSHerbert Xu 		.caam = {
2103479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2104479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2105479bcc7cSHerbert Xu 		},
2106479bcc7cSHerbert Xu 	},
2107479bcc7cSHerbert Xu 	{
2108479bcc7cSHerbert Xu 		.aead = {
2109479bcc7cSHerbert Xu 			.base = {
2110479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
2111479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2112479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2113479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2114479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2115479bcc7cSHerbert Xu 			},
2116479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2117479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2118479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2119479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2120479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2121479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2122479bcc7cSHerbert Xu 		},
2123479bcc7cSHerbert Xu 		.caam = {
2124479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2125479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2126479bcc7cSHerbert Xu 		},
2127479bcc7cSHerbert Xu 	},
2128479bcc7cSHerbert Xu 	{
2129479bcc7cSHerbert Xu 		.aead = {
2130479bcc7cSHerbert Xu 			.base = {
2131479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
2132479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2133479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
2134479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2135479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2136479bcc7cSHerbert Xu 			},
2137479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2138479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2139479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2140479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2141479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2142479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2143479bcc7cSHerbert Xu 		},
2144479bcc7cSHerbert Xu 		.caam = {
2145479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2146479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2147479bcc7cSHerbert Xu 		},
2148479bcc7cSHerbert Xu 	},
2149479bcc7cSHerbert Xu 	{
2150479bcc7cSHerbert Xu 		.aead = {
2151479bcc7cSHerbert Xu 			.base = {
2152479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
2153479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2154479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
2155479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2156479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2157479bcc7cSHerbert Xu 			},
2158479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2159479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2160479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2161479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2162479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2163479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2164479bcc7cSHerbert Xu 		},
2165479bcc7cSHerbert Xu 		.caam = {
2166479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2167479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2168479bcc7cSHerbert Xu 		},
2169479bcc7cSHerbert Xu 	},
2170479bcc7cSHerbert Xu 	{
2171479bcc7cSHerbert Xu 		.aead = {
2172479bcc7cSHerbert Xu 			.base = {
2173479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
2174479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2175479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
2176479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2177479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2178479bcc7cSHerbert Xu 			},
2179479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2180479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2181479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2182479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2183479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2184479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2185479bcc7cSHerbert Xu 		},
2186479bcc7cSHerbert Xu 		.caam = {
2187479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2188479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2189479bcc7cSHerbert Xu 		},
2190479bcc7cSHerbert Xu 	},
2191479bcc7cSHerbert Xu 	{
2192479bcc7cSHerbert Xu 		.aead = {
2193479bcc7cSHerbert Xu 			.base = {
2194479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(aes))",
2195479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2196479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2197479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2198479bcc7cSHerbert Xu 			},
2199479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2200479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2201479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2202479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2203479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2204479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2205479bcc7cSHerbert Xu 		},
2206479bcc7cSHerbert Xu 		.caam = {
2207479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2208479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2209479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2210479bcc7cSHerbert Xu 		},
2211479bcc7cSHerbert Xu 	},
2212479bcc7cSHerbert Xu 	{
2213479bcc7cSHerbert Xu 		.aead = {
2214479bcc7cSHerbert Xu 			.base = {
2215479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
2216479bcc7cSHerbert Xu 					    "cbc(aes)))",
2217479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
2218479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2219479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2220479bcc7cSHerbert Xu 			},
2221479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2222479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2223479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
22248b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2225479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2226479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2227479bcc7cSHerbert Xu 		},
2228479bcc7cSHerbert Xu 		.caam = {
2229479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2230479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2231479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2232479bcc7cSHerbert Xu 			.geniv = true,
2233479bcc7cSHerbert Xu 		},
2234479bcc7cSHerbert Xu 	},
2235479bcc7cSHerbert Xu 	{
2236479bcc7cSHerbert Xu 		.aead = {
2237479bcc7cSHerbert Xu 			.base = {
2238479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),cbc(aes))",
2239479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2240479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2241479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2242479bcc7cSHerbert Xu 			},
2243479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2244479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2245479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2246479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2247479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2248479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2249479bcc7cSHerbert Xu 		},
2250479bcc7cSHerbert Xu 		.caam = {
2251479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2252479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2253479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2254479bcc7cSHerbert Xu 		},
2255479bcc7cSHerbert Xu 	},
2256479bcc7cSHerbert Xu 	{
2257479bcc7cSHerbert Xu 		.aead = {
2258479bcc7cSHerbert Xu 			.base = {
2259479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
2260479bcc7cSHerbert Xu 					    "cbc(aes)))",
2261479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2262479bcc7cSHerbert Xu 						   "hmac-sha1-cbc-aes-caam",
2263479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2264479bcc7cSHerbert Xu 			},
2265479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2266479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2267479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
22688b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2269479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2270479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2271479bcc7cSHerbert Xu 		},
2272479bcc7cSHerbert Xu 		.caam = {
2273479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2274479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2275479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2276479bcc7cSHerbert Xu 			.geniv = true,
2277479bcc7cSHerbert Xu 		},
2278479bcc7cSHerbert Xu 	},
2279479bcc7cSHerbert Xu 	{
2280479bcc7cSHerbert Xu 		.aead = {
2281479bcc7cSHerbert Xu 			.base = {
2282479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),cbc(aes))",
2283479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2284479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2285479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2286479bcc7cSHerbert Xu 			},
2287479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2288479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2289479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2290479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2291479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2292479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2293479bcc7cSHerbert Xu 		},
2294479bcc7cSHerbert Xu 		.caam = {
2295479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2296479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2297479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2298479bcc7cSHerbert Xu 		},
2299479bcc7cSHerbert Xu 	},
2300479bcc7cSHerbert Xu 	{
2301479bcc7cSHerbert Xu 		.aead = {
2302479bcc7cSHerbert Xu 			.base = {
2303479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
2304479bcc7cSHerbert Xu 					    "cbc(aes)))",
2305479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2306479bcc7cSHerbert Xu 						   "hmac-sha224-cbc-aes-caam",
2307479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2308479bcc7cSHerbert Xu 			},
2309479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2310479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2311479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
23128b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2313479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2314479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2315479bcc7cSHerbert Xu 		},
2316479bcc7cSHerbert Xu 		.caam = {
2317479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2318479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2319479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2320479bcc7cSHerbert Xu 			.geniv = true,
2321479bcc7cSHerbert Xu 		},
2322479bcc7cSHerbert Xu 	},
2323479bcc7cSHerbert Xu 	{
2324479bcc7cSHerbert Xu 		.aead = {
2325479bcc7cSHerbert Xu 			.base = {
2326479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),cbc(aes))",
2327479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
2328479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2329479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2330479bcc7cSHerbert Xu 			},
2331479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2332479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2333479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2334479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2335479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2336479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2337479bcc7cSHerbert Xu 		},
2338479bcc7cSHerbert Xu 		.caam = {
2339479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2340479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2341479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2342479bcc7cSHerbert Xu 		},
2343479bcc7cSHerbert Xu 	},
2344479bcc7cSHerbert Xu 	{
2345479bcc7cSHerbert Xu 		.aead = {
2346479bcc7cSHerbert Xu 			.base = {
2347479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
2348479bcc7cSHerbert Xu 					    "cbc(aes)))",
2349479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2350479bcc7cSHerbert Xu 						   "hmac-sha256-cbc-aes-caam",
2351479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2352479bcc7cSHerbert Xu 			},
2353479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2354479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2355479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
23568b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2357479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2358479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2359479bcc7cSHerbert Xu 		},
2360479bcc7cSHerbert Xu 		.caam = {
2361479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2362479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2363479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2364479bcc7cSHerbert Xu 			.geniv = true,
2365479bcc7cSHerbert Xu 		},
2366479bcc7cSHerbert Xu 	},
2367479bcc7cSHerbert Xu 	{
2368479bcc7cSHerbert Xu 		.aead = {
2369479bcc7cSHerbert Xu 			.base = {
2370479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),cbc(aes))",
2371479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
2372479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2373479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2374479bcc7cSHerbert Xu 			},
2375479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2376479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2377479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2378479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2379479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2380479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2381479bcc7cSHerbert Xu 		},
2382479bcc7cSHerbert Xu 		.caam = {
2383479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2384479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2385479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2386479bcc7cSHerbert Xu 		},
2387479bcc7cSHerbert Xu 	},
2388479bcc7cSHerbert Xu 	{
2389479bcc7cSHerbert Xu 		.aead = {
2390479bcc7cSHerbert Xu 			.base = {
2391479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
2392479bcc7cSHerbert Xu 					    "cbc(aes)))",
2393479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2394479bcc7cSHerbert Xu 						   "hmac-sha384-cbc-aes-caam",
2395479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2396479bcc7cSHerbert Xu 			},
2397479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2398479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2399479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
24008b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2401479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2402479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2403479bcc7cSHerbert Xu 		},
2404479bcc7cSHerbert Xu 		.caam = {
2405479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2406479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2407479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2408479bcc7cSHerbert Xu 			.geniv = true,
2409479bcc7cSHerbert Xu 		},
2410479bcc7cSHerbert Xu 	},
2411479bcc7cSHerbert Xu 	{
2412479bcc7cSHerbert Xu 		.aead = {
2413479bcc7cSHerbert Xu 			.base = {
2414479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),cbc(aes))",
2415479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
2416479bcc7cSHerbert Xu 						   "cbc-aes-caam",
2417479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2418479bcc7cSHerbert Xu 			},
2419479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2420479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2421479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2422479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2423479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2424479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2425479bcc7cSHerbert Xu 		},
2426479bcc7cSHerbert Xu 		.caam = {
2427479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2428479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2429479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2430479bcc7cSHerbert Xu 		},
2431479bcc7cSHerbert Xu 	},
2432479bcc7cSHerbert Xu 	{
2433479bcc7cSHerbert Xu 		.aead = {
2434479bcc7cSHerbert Xu 			.base = {
2435479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
2436479bcc7cSHerbert Xu 					    "cbc(aes)))",
2437479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2438479bcc7cSHerbert Xu 						   "hmac-sha512-cbc-aes-caam",
2439479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
2440479bcc7cSHerbert Xu 			},
2441479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2442479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2443479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
24448b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2445479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
2446479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2447479bcc7cSHerbert Xu 		},
2448479bcc7cSHerbert Xu 		.caam = {
2449479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2450479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2451479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2452479bcc7cSHerbert Xu 			.geniv = true,
2453479bcc7cSHerbert Xu 		},
2454479bcc7cSHerbert Xu 	},
2455479bcc7cSHerbert Xu 	{
2456479bcc7cSHerbert Xu 		.aead = {
2457479bcc7cSHerbert Xu 			.base = {
2458479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(des3_ede))",
2459479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2460479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2461479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2462479bcc7cSHerbert Xu 			},
24631b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2464479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2465479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2466479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2467479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2468479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2469479bcc7cSHerbert Xu 		},
2470479bcc7cSHerbert Xu 		.caam = {
2471479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2472479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2473479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2474479bcc7cSHerbert Xu 		}
2475479bcc7cSHerbert Xu 	},
2476479bcc7cSHerbert Xu 	{
2477479bcc7cSHerbert Xu 		.aead = {
2478479bcc7cSHerbert Xu 			.base = {
2479479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
2480479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2481479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
2482479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2483479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2484479bcc7cSHerbert Xu 			},
24851b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2486479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2487479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
24888b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2489479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2490479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2491479bcc7cSHerbert Xu 		},
2492479bcc7cSHerbert Xu 		.caam = {
2493479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2494479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2495479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2496479bcc7cSHerbert Xu 			.geniv = true,
2497479bcc7cSHerbert Xu 		}
2498479bcc7cSHerbert Xu 	},
2499479bcc7cSHerbert Xu 	{
2500479bcc7cSHerbert Xu 		.aead = {
2501479bcc7cSHerbert Xu 			.base = {
2502479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
2503479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2504479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2505479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2506479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2507479bcc7cSHerbert Xu 			},
25081b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2509479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2510479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2511479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2512479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2513479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2514479bcc7cSHerbert Xu 		},
2515479bcc7cSHerbert Xu 		.caam = {
2516479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2517479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2518479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2519479bcc7cSHerbert Xu 		},
2520479bcc7cSHerbert Xu 	},
2521479bcc7cSHerbert Xu 	{
2522479bcc7cSHerbert Xu 		.aead = {
2523479bcc7cSHerbert Xu 			.base = {
2524479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
2525479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2526479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2527479bcc7cSHerbert Xu 						   "hmac-sha1-"
2528479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2529479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2530479bcc7cSHerbert Xu 			},
25311b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2532479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2533479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
25348b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2535479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2536479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2537479bcc7cSHerbert Xu 		},
2538479bcc7cSHerbert Xu 		.caam = {
2539479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2540479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2541479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2542479bcc7cSHerbert Xu 			.geniv = true,
2543479bcc7cSHerbert Xu 		},
2544479bcc7cSHerbert Xu 	},
2545479bcc7cSHerbert Xu 	{
2546479bcc7cSHerbert Xu 		.aead = {
2547479bcc7cSHerbert Xu 			.base = {
2548479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
2549479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2550479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2551479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2552479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2553479bcc7cSHerbert Xu 			},
25541b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2555479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2556479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2557479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2558479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2559479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2560479bcc7cSHerbert Xu 		},
2561479bcc7cSHerbert Xu 		.caam = {
2562479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2563479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2564479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2565479bcc7cSHerbert Xu 		},
2566479bcc7cSHerbert Xu 	},
2567479bcc7cSHerbert Xu 	{
2568479bcc7cSHerbert Xu 		.aead = {
2569479bcc7cSHerbert Xu 			.base = {
2570479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
2571479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2572479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2573479bcc7cSHerbert Xu 						   "hmac-sha224-"
2574479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2575479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2576479bcc7cSHerbert Xu 			},
25771b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2578479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2579479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
25808b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2581479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2582479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2583479bcc7cSHerbert Xu 		},
2584479bcc7cSHerbert Xu 		.caam = {
2585479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2586479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2587479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2588479bcc7cSHerbert Xu 			.geniv = true,
2589479bcc7cSHerbert Xu 		},
2590479bcc7cSHerbert Xu 	},
2591479bcc7cSHerbert Xu 	{
2592479bcc7cSHerbert Xu 		.aead = {
2593479bcc7cSHerbert Xu 			.base = {
2594479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
2595479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2596479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
2597479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2598479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2599479bcc7cSHerbert Xu 			},
26001b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2601479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2602479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2603479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2604479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2605479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2606479bcc7cSHerbert Xu 		},
2607479bcc7cSHerbert Xu 		.caam = {
2608479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2609479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2610479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2611479bcc7cSHerbert Xu 		},
2612479bcc7cSHerbert Xu 	},
2613479bcc7cSHerbert Xu 	{
2614479bcc7cSHerbert Xu 		.aead = {
2615479bcc7cSHerbert Xu 			.base = {
2616479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
2617479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2618479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2619479bcc7cSHerbert Xu 						   "hmac-sha256-"
2620479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2621479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2622479bcc7cSHerbert Xu 			},
26231b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2624479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2625479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
26268b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2627479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2628479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2629479bcc7cSHerbert Xu 		},
2630479bcc7cSHerbert Xu 		.caam = {
2631479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2632479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2633479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2634479bcc7cSHerbert Xu 			.geniv = true,
2635479bcc7cSHerbert Xu 		},
2636479bcc7cSHerbert Xu 	},
2637479bcc7cSHerbert Xu 	{
2638479bcc7cSHerbert Xu 		.aead = {
2639479bcc7cSHerbert Xu 			.base = {
2640479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
2641479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2642479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
2643479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2644479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2645479bcc7cSHerbert Xu 			},
26461b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2647479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2648479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2649479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2650479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2651479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2652479bcc7cSHerbert Xu 		},
2653479bcc7cSHerbert Xu 		.caam = {
2654479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2655479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2656479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2657479bcc7cSHerbert Xu 		},
2658479bcc7cSHerbert Xu 	},
2659479bcc7cSHerbert Xu 	{
2660479bcc7cSHerbert Xu 		.aead = {
2661479bcc7cSHerbert Xu 			.base = {
2662479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
2663479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2664479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2665479bcc7cSHerbert Xu 						   "hmac-sha384-"
2666479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2667479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2668479bcc7cSHerbert Xu 			},
26691b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2670479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2671479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
26728b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2673479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2674479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2675479bcc7cSHerbert Xu 		},
2676479bcc7cSHerbert Xu 		.caam = {
2677479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2678479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2679479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2680479bcc7cSHerbert Xu 			.geniv = true,
2681479bcc7cSHerbert Xu 		},
2682479bcc7cSHerbert Xu 	},
2683479bcc7cSHerbert Xu 	{
2684479bcc7cSHerbert Xu 		.aead = {
2685479bcc7cSHerbert Xu 			.base = {
2686479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
2687479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
2688479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
2689479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2690479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2691479bcc7cSHerbert Xu 			},
26921b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2693479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2694479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2695479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2696479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2697479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2698479bcc7cSHerbert Xu 		},
2699479bcc7cSHerbert Xu 		.caam = {
2700479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2701479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2702479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2703479bcc7cSHerbert Xu 		},
2704479bcc7cSHerbert Xu 	},
2705479bcc7cSHerbert Xu 	{
2706479bcc7cSHerbert Xu 		.aead = {
2707479bcc7cSHerbert Xu 			.base = {
2708479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
2709479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
2710479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2711479bcc7cSHerbert Xu 						   "hmac-sha512-"
2712479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
2713479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
2714479bcc7cSHerbert Xu 			},
27151b52c409SHerbert Xu 			.setkey = des3_aead_setkey,
2716479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2717479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
27188b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2719479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
2720479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2721479bcc7cSHerbert Xu 		},
2722479bcc7cSHerbert Xu 		.caam = {
2723479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2724479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2725479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2726479bcc7cSHerbert Xu 			.geniv = true,
2727479bcc7cSHerbert Xu 		},
2728479bcc7cSHerbert Xu 	},
2729479bcc7cSHerbert Xu 	{
2730479bcc7cSHerbert Xu 		.aead = {
2731479bcc7cSHerbert Xu 			.base = {
2732479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(des))",
2733479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2734479bcc7cSHerbert Xu 						   "cbc-des-caam",
2735479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2736479bcc7cSHerbert Xu 			},
2737479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2738479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2739479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2740479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2741479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2742479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2743479bcc7cSHerbert Xu 		},
2744479bcc7cSHerbert Xu 		.caam = {
2745479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2746479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2747479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2748479bcc7cSHerbert Xu 		},
2749479bcc7cSHerbert Xu 	},
2750479bcc7cSHerbert Xu 	{
2751479bcc7cSHerbert Xu 		.aead = {
2752479bcc7cSHerbert Xu 			.base = {
2753479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
2754479bcc7cSHerbert Xu 					    "cbc(des)))",
2755479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
2756479bcc7cSHerbert Xu 						   "cbc-des-caam",
2757479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2758479bcc7cSHerbert Xu 			},
2759479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2760479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2761479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
27628b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2763479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2764479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2765479bcc7cSHerbert Xu 		},
2766479bcc7cSHerbert Xu 		.caam = {
2767479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2768479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2769479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2770479bcc7cSHerbert Xu 			.geniv = true,
2771479bcc7cSHerbert Xu 		},
2772479bcc7cSHerbert Xu 	},
2773479bcc7cSHerbert Xu 	{
2774479bcc7cSHerbert Xu 		.aead = {
2775479bcc7cSHerbert Xu 			.base = {
2776479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),cbc(des))",
2777479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2778479bcc7cSHerbert Xu 						   "cbc-des-caam",
2779479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2780479bcc7cSHerbert Xu 			},
2781479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2782479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2783479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2784479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2785479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2786479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2787479bcc7cSHerbert Xu 		},
2788479bcc7cSHerbert Xu 		.caam = {
2789479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2790479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2791479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2792479bcc7cSHerbert Xu 		},
2793479bcc7cSHerbert Xu 	},
2794479bcc7cSHerbert Xu 	{
2795479bcc7cSHerbert Xu 		.aead = {
2796479bcc7cSHerbert Xu 			.base = {
2797479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
2798479bcc7cSHerbert Xu 					    "cbc(des)))",
2799479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2800479bcc7cSHerbert Xu 						   "hmac-sha1-cbc-des-caam",
2801479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2802479bcc7cSHerbert Xu 			},
2803479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2804479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2805479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
28068b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2807479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2808479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2809479bcc7cSHerbert Xu 		},
2810479bcc7cSHerbert Xu 		.caam = {
2811479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2812479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2813479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2814479bcc7cSHerbert Xu 			.geniv = true,
2815479bcc7cSHerbert Xu 		},
2816479bcc7cSHerbert Xu 	},
2817479bcc7cSHerbert Xu 	{
2818479bcc7cSHerbert Xu 		.aead = {
2819479bcc7cSHerbert Xu 			.base = {
2820479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),cbc(des))",
2821479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2822479bcc7cSHerbert Xu 						   "cbc-des-caam",
2823479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2824479bcc7cSHerbert Xu 			},
2825479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2826479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2827479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2828479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2829479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2830479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2831479bcc7cSHerbert Xu 		},
2832479bcc7cSHerbert Xu 		.caam = {
2833479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2834479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2835479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2836479bcc7cSHerbert Xu 		},
2837479bcc7cSHerbert Xu 	},
2838479bcc7cSHerbert Xu 	{
2839479bcc7cSHerbert Xu 		.aead = {
2840479bcc7cSHerbert Xu 			.base = {
2841479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
2842479bcc7cSHerbert Xu 					    "cbc(des)))",
2843479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2844479bcc7cSHerbert Xu 						   "hmac-sha224-cbc-des-caam",
2845479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2846479bcc7cSHerbert Xu 			},
2847479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2848479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2849479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
28508b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2851479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2852479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2853479bcc7cSHerbert Xu 		},
2854479bcc7cSHerbert Xu 		.caam = {
2855479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2856479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2857479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2858479bcc7cSHerbert Xu 			.geniv = true,
2859479bcc7cSHerbert Xu 		},
2860479bcc7cSHerbert Xu 	},
2861479bcc7cSHerbert Xu 	{
2862479bcc7cSHerbert Xu 		.aead = {
2863479bcc7cSHerbert Xu 			.base = {
2864479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),cbc(des))",
2865479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
2866479bcc7cSHerbert Xu 						   "cbc-des-caam",
2867479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2868479bcc7cSHerbert Xu 			},
2869479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2870479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2871479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2872479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2873479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2874479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2875479bcc7cSHerbert Xu 		},
2876479bcc7cSHerbert Xu 		.caam = {
2877479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2878479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2879479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2880479bcc7cSHerbert Xu 		},
2881479bcc7cSHerbert Xu 	},
2882479bcc7cSHerbert Xu 	{
2883479bcc7cSHerbert Xu 		.aead = {
2884479bcc7cSHerbert Xu 			.base = {
2885479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
2886479bcc7cSHerbert Xu 					    "cbc(des)))",
2887479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2888479bcc7cSHerbert Xu 						   "hmac-sha256-cbc-des-caam",
2889479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2890479bcc7cSHerbert Xu 			},
2891479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2892479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2893479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
28948b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2895479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2896479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
2897479bcc7cSHerbert Xu 		},
2898479bcc7cSHerbert Xu 		.caam = {
2899479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2900479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
2901479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2902479bcc7cSHerbert Xu 			.geniv = true,
2903479bcc7cSHerbert Xu 		},
2904479bcc7cSHerbert Xu 	},
2905479bcc7cSHerbert Xu 	{
2906479bcc7cSHerbert Xu 		.aead = {
2907479bcc7cSHerbert Xu 			.base = {
2908479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),cbc(des))",
2909479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
2910479bcc7cSHerbert Xu 						   "cbc-des-caam",
2911479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2912479bcc7cSHerbert Xu 			},
2913479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2914479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2915479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2916479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2917479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2918479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2919479bcc7cSHerbert Xu 		},
2920479bcc7cSHerbert Xu 		.caam = {
2921479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2922479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2923479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2924479bcc7cSHerbert Xu 		},
2925479bcc7cSHerbert Xu 	},
2926479bcc7cSHerbert Xu 	{
2927479bcc7cSHerbert Xu 		.aead = {
2928479bcc7cSHerbert Xu 			.base = {
2929479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
2930479bcc7cSHerbert Xu 					    "cbc(des)))",
2931479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2932479bcc7cSHerbert Xu 						   "hmac-sha384-cbc-des-caam",
2933479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2934479bcc7cSHerbert Xu 			},
2935479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2936479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2937479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
29388b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2939479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2940479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
2941479bcc7cSHerbert Xu 		},
2942479bcc7cSHerbert Xu 		.caam = {
2943479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2944479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
2945479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2946479bcc7cSHerbert Xu 			.geniv = true,
2947479bcc7cSHerbert Xu 		},
2948479bcc7cSHerbert Xu 	},
2949479bcc7cSHerbert Xu 	{
2950479bcc7cSHerbert Xu 		.aead = {
2951479bcc7cSHerbert Xu 			.base = {
2952479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),cbc(des))",
2953479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
2954479bcc7cSHerbert Xu 						   "cbc-des-caam",
2955479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2956479bcc7cSHerbert Xu 			},
2957479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2958479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2959479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2960479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2961479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2962479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2963479bcc7cSHerbert Xu 		},
2964479bcc7cSHerbert Xu 		.caam = {
2965479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2966479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2967479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2968479bcc7cSHerbert Xu 		},
2969479bcc7cSHerbert Xu 	},
2970479bcc7cSHerbert Xu 	{
2971479bcc7cSHerbert Xu 		.aead = {
2972479bcc7cSHerbert Xu 			.base = {
2973479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
2974479bcc7cSHerbert Xu 					    "cbc(des)))",
2975479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
2976479bcc7cSHerbert Xu 						   "hmac-sha512-cbc-des-caam",
2977479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
2978479bcc7cSHerbert Xu 			},
2979479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2980479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2981479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
29828b18e235SHoria Geantă 			.decrypt = aead_decrypt,
2983479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
2984479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
2985479bcc7cSHerbert Xu 		},
2986479bcc7cSHerbert Xu 		.caam = {
2987479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
2988479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
2989479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2990479bcc7cSHerbert Xu 			.geniv = true,
2991479bcc7cSHerbert Xu 		},
2992479bcc7cSHerbert Xu 	},
2993479bcc7cSHerbert Xu 	{
2994479bcc7cSHerbert Xu 		.aead = {
2995479bcc7cSHerbert Xu 			.base = {
2996479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),"
2997479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
2998479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2999479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3000479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3001479bcc7cSHerbert Xu 			},
3002479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3003479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3004479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3005479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3006479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3007479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3008479bcc7cSHerbert Xu 		},
3009479bcc7cSHerbert Xu 		.caam = {
3010479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3011479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3012479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3013479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3014479bcc7cSHerbert Xu 			.rfc3686 = true,
3015479bcc7cSHerbert Xu 		},
3016479bcc7cSHerbert Xu 	},
3017479bcc7cSHerbert Xu 	{
3018479bcc7cSHerbert Xu 		.aead = {
3019479bcc7cSHerbert Xu 			.base = {
3020479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
3021479bcc7cSHerbert Xu 					    "hmac(md5),rfc3686(ctr(aes))))",
3022479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-md5-"
3023479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3024479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3025479bcc7cSHerbert Xu 			},
3026479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3027479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3028479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
30298b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3030479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3031479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3032479bcc7cSHerbert Xu 		},
3033479bcc7cSHerbert Xu 		.caam = {
3034479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3035479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3036479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3037479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3038479bcc7cSHerbert Xu 			.rfc3686 = true,
3039479bcc7cSHerbert Xu 			.geniv = true,
3040479bcc7cSHerbert Xu 		},
3041479bcc7cSHerbert Xu 	},
3042479bcc7cSHerbert Xu 	{
3043479bcc7cSHerbert Xu 		.aead = {
3044479bcc7cSHerbert Xu 			.base = {
3045479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
3046479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3047479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
3048479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3049479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3050479bcc7cSHerbert Xu 			},
3051479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3052479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3053479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3054479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3055479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3056479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3057479bcc7cSHerbert Xu 		},
3058479bcc7cSHerbert Xu 		.caam = {
3059479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3060479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3061479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3062479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3063479bcc7cSHerbert Xu 			.rfc3686 = true,
3064479bcc7cSHerbert Xu 		},
3065479bcc7cSHerbert Xu 	},
3066479bcc7cSHerbert Xu 	{
3067479bcc7cSHerbert Xu 		.aead = {
3068479bcc7cSHerbert Xu 			.base = {
3069479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
3070479bcc7cSHerbert Xu 					    "hmac(sha1),rfc3686(ctr(aes))))",
3071479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha1-"
3072479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3073479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3074479bcc7cSHerbert Xu 			},
3075479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3076479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3077479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
30788b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3079479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3080479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3081479bcc7cSHerbert Xu 		},
3082479bcc7cSHerbert Xu 		.caam = {
3083479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3084479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3085479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3086479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3087479bcc7cSHerbert Xu 			.rfc3686 = true,
3088479bcc7cSHerbert Xu 			.geniv = true,
3089479bcc7cSHerbert Xu 		},
3090479bcc7cSHerbert Xu 	},
3091479bcc7cSHerbert Xu 	{
3092479bcc7cSHerbert Xu 		.aead = {
3093479bcc7cSHerbert Xu 			.base = {
3094479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
3095479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3096479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
3097479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3098479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3099479bcc7cSHerbert Xu 			},
3100479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3101479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3102479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3103479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3104479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3105479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3106479bcc7cSHerbert Xu 		},
3107479bcc7cSHerbert Xu 		.caam = {
3108479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3109479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3110479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3111479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3112479bcc7cSHerbert Xu 			.rfc3686 = true,
3113479bcc7cSHerbert Xu 		},
3114479bcc7cSHerbert Xu 	},
3115479bcc7cSHerbert Xu 	{
3116479bcc7cSHerbert Xu 		.aead = {
3117479bcc7cSHerbert Xu 			.base = {
3118479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
3119479bcc7cSHerbert Xu 					    "hmac(sha224),rfc3686(ctr(aes))))",
3120479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha224-"
3121479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3122479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3123479bcc7cSHerbert Xu 			},
3124479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3125479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3126479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
31278b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3128479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3129479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3130479bcc7cSHerbert Xu 		},
3131479bcc7cSHerbert Xu 		.caam = {
3132479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3133479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3134479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3135479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3136479bcc7cSHerbert Xu 			.rfc3686 = true,
3137479bcc7cSHerbert Xu 			.geniv = true,
3138479bcc7cSHerbert Xu 		},
3139479bcc7cSHerbert Xu 	},
3140479bcc7cSHerbert Xu 	{
3141479bcc7cSHerbert Xu 		.aead = {
3142479bcc7cSHerbert Xu 			.base = {
3143479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
3144479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3145479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
3146479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3147479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3148479bcc7cSHerbert Xu 			},
3149479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3150479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3151479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3152479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3153479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3154479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3155479bcc7cSHerbert Xu 		},
3156479bcc7cSHerbert Xu 		.caam = {
3157479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3158479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3159479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3160479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3161479bcc7cSHerbert Xu 			.rfc3686 = true,
3162479bcc7cSHerbert Xu 		},
3163479bcc7cSHerbert Xu 	},
3164479bcc7cSHerbert Xu 	{
3165479bcc7cSHerbert Xu 		.aead = {
3166479bcc7cSHerbert Xu 			.base = {
3167479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha256),"
3168479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
3169479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha256-"
3170479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3171479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3172479bcc7cSHerbert Xu 			},
3173479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3174479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3175479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
31768b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3177479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3178479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3179479bcc7cSHerbert Xu 		},
3180479bcc7cSHerbert Xu 		.caam = {
3181479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3182479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3183479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3184479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3185479bcc7cSHerbert Xu 			.rfc3686 = true,
3186479bcc7cSHerbert Xu 			.geniv = true,
3187479bcc7cSHerbert Xu 		},
3188479bcc7cSHerbert Xu 	},
3189479bcc7cSHerbert Xu 	{
3190479bcc7cSHerbert Xu 		.aead = {
3191479bcc7cSHerbert Xu 			.base = {
3192479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
3193479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3194479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
3195479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3196479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3197479bcc7cSHerbert Xu 			},
3198479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3199479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3200479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3201479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3202479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3203479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3204479bcc7cSHerbert Xu 		},
3205479bcc7cSHerbert Xu 		.caam = {
3206479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3207479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3208479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3209479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3210479bcc7cSHerbert Xu 			.rfc3686 = true,
3211479bcc7cSHerbert Xu 		},
3212479bcc7cSHerbert Xu 	},
3213479bcc7cSHerbert Xu 	{
3214479bcc7cSHerbert Xu 		.aead = {
3215479bcc7cSHerbert Xu 			.base = {
3216479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha384),"
3217479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
3218479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha384-"
3219479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3220479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3221479bcc7cSHerbert Xu 			},
3222479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3223479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3224479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
32258b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3226479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3227479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3228479bcc7cSHerbert Xu 		},
3229479bcc7cSHerbert Xu 		.caam = {
3230479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3231479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3232479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3233479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3234479bcc7cSHerbert Xu 			.rfc3686 = true,
3235479bcc7cSHerbert Xu 			.geniv = true,
3236479bcc7cSHerbert Xu 		},
3237479bcc7cSHerbert Xu 	},
3238479bcc7cSHerbert Xu 	{
3239479bcc7cSHerbert Xu 		.aead = {
3240479bcc7cSHerbert Xu 			.base = {
3241479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
3242479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3243479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
3244479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3245479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3246479bcc7cSHerbert Xu 			},
3247479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3248479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3249479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3250479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3251479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3252479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3253479bcc7cSHerbert Xu 		},
3254479bcc7cSHerbert Xu 		.caam = {
3255479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3256479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3257479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3258479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3259479bcc7cSHerbert Xu 			.rfc3686 = true,
3260479bcc7cSHerbert Xu 		},
3261479bcc7cSHerbert Xu 	},
3262479bcc7cSHerbert Xu 	{
3263479bcc7cSHerbert Xu 		.aead = {
3264479bcc7cSHerbert Xu 			.base = {
3265479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha512),"
3266479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
3267479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha512-"
3268479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3269479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3270479bcc7cSHerbert Xu 			},
3271479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3272479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3273479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
32748b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3275479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3276479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3277479bcc7cSHerbert Xu 		},
3278479bcc7cSHerbert Xu 		.caam = {
3279479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3280479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3281479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3282479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3283479bcc7cSHerbert Xu 			.rfc3686 = true,
3284479bcc7cSHerbert Xu 			.geniv = true,
3285479bcc7cSHerbert Xu 		},
3286479bcc7cSHerbert Xu 	},
3287d6bbd4eeSHoria Geantă 	{
3288d6bbd4eeSHoria Geantă 		.aead = {
3289d6bbd4eeSHoria Geantă 			.base = {
3290d6bbd4eeSHoria Geantă 				.cra_name = "rfc7539(chacha20,poly1305)",
3291d6bbd4eeSHoria Geantă 				.cra_driver_name = "rfc7539-chacha20-poly1305-"
3292d6bbd4eeSHoria Geantă 						   "caam",
3293d6bbd4eeSHoria Geantă 				.cra_blocksize = 1,
3294d6bbd4eeSHoria Geantă 			},
3295d6bbd4eeSHoria Geantă 			.setkey = chachapoly_setkey,
3296d6bbd4eeSHoria Geantă 			.setauthsize = chachapoly_setauthsize,
3297d6bbd4eeSHoria Geantă 			.encrypt = chachapoly_encrypt,
3298d6bbd4eeSHoria Geantă 			.decrypt = chachapoly_decrypt,
3299d6bbd4eeSHoria Geantă 			.ivsize = CHACHAPOLY_IV_SIZE,
3300d6bbd4eeSHoria Geantă 			.maxauthsize = POLY1305_DIGEST_SIZE,
3301d6bbd4eeSHoria Geantă 		},
3302d6bbd4eeSHoria Geantă 		.caam = {
3303d6bbd4eeSHoria Geantă 			.class1_alg_type = OP_ALG_ALGSEL_CHACHA20 |
3304d6bbd4eeSHoria Geantă 					   OP_ALG_AAI_AEAD,
3305d6bbd4eeSHoria Geantă 			.class2_alg_type = OP_ALG_ALGSEL_POLY1305 |
3306d6bbd4eeSHoria Geantă 					   OP_ALG_AAI_AEAD,
330724586b5fSHerbert Xu 			.nodkp = true,
3308d6bbd4eeSHoria Geantă 		},
3309d6bbd4eeSHoria Geantă 	},
3310d6bbd4eeSHoria Geantă 	{
3311d6bbd4eeSHoria Geantă 		.aead = {
3312d6bbd4eeSHoria Geantă 			.base = {
3313d6bbd4eeSHoria Geantă 				.cra_name = "rfc7539esp(chacha20,poly1305)",
3314d6bbd4eeSHoria Geantă 				.cra_driver_name = "rfc7539esp-chacha20-"
3315d6bbd4eeSHoria Geantă 						   "poly1305-caam",
3316d6bbd4eeSHoria Geantă 				.cra_blocksize = 1,
3317d6bbd4eeSHoria Geantă 			},
3318d6bbd4eeSHoria Geantă 			.setkey = chachapoly_setkey,
3319d6bbd4eeSHoria Geantă 			.setauthsize = chachapoly_setauthsize,
3320d6bbd4eeSHoria Geantă 			.encrypt = chachapoly_encrypt,
3321d6bbd4eeSHoria Geantă 			.decrypt = chachapoly_decrypt,
3322d6bbd4eeSHoria Geantă 			.ivsize = 8,
3323d6bbd4eeSHoria Geantă 			.maxauthsize = POLY1305_DIGEST_SIZE,
3324d6bbd4eeSHoria Geantă 		},
3325d6bbd4eeSHoria Geantă 		.caam = {
3326d6bbd4eeSHoria Geantă 			.class1_alg_type = OP_ALG_ALGSEL_CHACHA20 |
3327d6bbd4eeSHoria Geantă 					   OP_ALG_AAI_AEAD,
3328d6bbd4eeSHoria Geantă 			.class2_alg_type = OP_ALG_ALGSEL_POLY1305 |
3329d6bbd4eeSHoria Geantă 					   OP_ALG_AAI_AEAD,
333024586b5fSHerbert Xu 			.nodkp = true,
3331d6bbd4eeSHoria Geantă 		},
3332d6bbd4eeSHoria Geantă 	},
3333f2147b88SHerbert Xu };
3334f2147b88SHerbert Xu 
33357e0880b9SHoria Geantă static int caam_init_common(struct caam_ctx *ctx, struct caam_alg_entry *caam,
33367e0880b9SHoria Geantă 			    bool uses_dkp)
3337f2147b88SHerbert Xu {
3338bbf22344SHoria Geantă 	dma_addr_t dma_addr;
33397e0880b9SHoria Geantă 	struct caam_drv_private *priv;
3340ee38767fSIuliana Prodan 	const size_t sh_desc_enc_offset = offsetof(struct caam_ctx,
3341ee38767fSIuliana Prodan 						   sh_desc_enc);
3342bbf22344SHoria Geantă 
3343f2147b88SHerbert Xu 	ctx->jrdev = caam_jr_alloc();
3344f2147b88SHerbert Xu 	if (IS_ERR(ctx->jrdev)) {
3345f2147b88SHerbert Xu 		pr_err("Job Ring Device allocation for transform failed\n");
3346f2147b88SHerbert Xu 		return PTR_ERR(ctx->jrdev);
3347f2147b88SHerbert Xu 	}
3348f2147b88SHerbert Xu 
33497e0880b9SHoria Geantă 	priv = dev_get_drvdata(ctx->jrdev->parent);
33507e0880b9SHoria Geantă 	if (priv->era >= 6 && uses_dkp)
33517e0880b9SHoria Geantă 		ctx->dir = DMA_BIDIRECTIONAL;
33527e0880b9SHoria Geantă 	else
33537e0880b9SHoria Geantă 		ctx->dir = DMA_TO_DEVICE;
33547e0880b9SHoria Geantă 
3355bbf22344SHoria Geantă 	dma_addr = dma_map_single_attrs(ctx->jrdev, ctx->sh_desc_enc,
3356bbf22344SHoria Geantă 					offsetof(struct caam_ctx,
3357ee38767fSIuliana Prodan 						 sh_desc_enc_dma) -
3358ee38767fSIuliana Prodan 					sh_desc_enc_offset,
33597e0880b9SHoria Geantă 					ctx->dir, DMA_ATTR_SKIP_CPU_SYNC);
3360bbf22344SHoria Geantă 	if (dma_mapping_error(ctx->jrdev, dma_addr)) {
3361bbf22344SHoria Geantă 		dev_err(ctx->jrdev, "unable to map key, shared descriptors\n");
3362bbf22344SHoria Geantă 		caam_jr_free(ctx->jrdev);
3363bbf22344SHoria Geantă 		return -ENOMEM;
3364bbf22344SHoria Geantă 	}
3365bbf22344SHoria Geantă 
3366bbf22344SHoria Geantă 	ctx->sh_desc_enc_dma = dma_addr;
3367bbf22344SHoria Geantă 	ctx->sh_desc_dec_dma = dma_addr + offsetof(struct caam_ctx,
3368ee38767fSIuliana Prodan 						   sh_desc_dec) -
3369ee38767fSIuliana Prodan 					sh_desc_enc_offset;
3370ee38767fSIuliana Prodan 	ctx->key_dma = dma_addr + offsetof(struct caam_ctx, key) -
3371ee38767fSIuliana Prodan 					sh_desc_enc_offset;
3372bbf22344SHoria Geantă 
3373f2147b88SHerbert Xu 	/* copy descriptor header template value */
3374db57656bSHoria Geantă 	ctx->cdata.algtype = OP_TYPE_CLASS1_ALG | caam->class1_alg_type;
3375db57656bSHoria Geantă 	ctx->adata.algtype = OP_TYPE_CLASS2_ALG | caam->class2_alg_type;
3376f2147b88SHerbert Xu 
3377f2147b88SHerbert Xu 	return 0;
3378f2147b88SHerbert Xu }
3379f2147b88SHerbert Xu 
33805ca7badbSHoria Geantă static int caam_cra_init(struct crypto_skcipher *tfm)
33818e8ec596SKim Phillips {
33825ca7badbSHoria Geantă 	struct skcipher_alg *alg = crypto_skcipher_alg(tfm);
33835ca7badbSHoria Geantă 	struct caam_skcipher_alg *caam_alg =
33845ca7badbSHoria Geantă 		container_of(alg, typeof(*caam_alg), skcipher);
3385ee38767fSIuliana Prodan 	struct caam_ctx *ctx = crypto_skcipher_ctx(tfm);
33869d9b14dbSAndrei Botila 	u32 alg_aai = caam_alg->caam.class1_alg_type & OP_ALG_AAI_MASK;
33879d9b14dbSAndrei Botila 	int ret = 0;
3388ee38767fSIuliana Prodan 
3389ee38767fSIuliana Prodan 	ctx->enginectx.op.do_one_request = skcipher_do_one_req;
33908e8ec596SKim Phillips 
33919d9b14dbSAndrei Botila 	if (alg_aai == OP_ALG_AAI_XTS) {
33929d9b14dbSAndrei Botila 		const char *tfm_name = crypto_tfm_alg_name(&tfm->base);
33939d9b14dbSAndrei Botila 		struct crypto_skcipher *fallback;
33949d9b14dbSAndrei Botila 
33959d9b14dbSAndrei Botila 		fallback = crypto_alloc_skcipher(tfm_name, 0,
33969d9b14dbSAndrei Botila 						 CRYPTO_ALG_NEED_FALLBACK);
33979d9b14dbSAndrei Botila 		if (IS_ERR(fallback)) {
33989d9b14dbSAndrei Botila 			dev_err(ctx->jrdev, "Failed to allocate %s fallback: %ld\n",
33999d9b14dbSAndrei Botila 				tfm_name, PTR_ERR(fallback));
34009d9b14dbSAndrei Botila 			return PTR_ERR(fallback);
34019d9b14dbSAndrei Botila 		}
34029d9b14dbSAndrei Botila 
34039d9b14dbSAndrei Botila 		ctx->fallback = fallback;
34049d9b14dbSAndrei Botila 		crypto_skcipher_set_reqsize(tfm, sizeof(struct caam_skcipher_req_ctx) +
34059d9b14dbSAndrei Botila 					    crypto_skcipher_reqsize(fallback));
34069d9b14dbSAndrei Botila 	} else {
34079d9b14dbSAndrei Botila 		crypto_skcipher_set_reqsize(tfm, sizeof(struct caam_skcipher_req_ctx));
34089d9b14dbSAndrei Botila 	}
34099d9b14dbSAndrei Botila 
34109d9b14dbSAndrei Botila 	ret = caam_init_common(ctx, &caam_alg->caam, false);
34119d9b14dbSAndrei Botila 	if (ret && ctx->fallback)
34129d9b14dbSAndrei Botila 		crypto_free_skcipher(ctx->fallback);
34139d9b14dbSAndrei Botila 
34149d9b14dbSAndrei Botila 	return ret;
3415cfc6f11bSRuchika Gupta }
34168e8ec596SKim Phillips 
3417f2147b88SHerbert Xu static int caam_aead_init(struct crypto_aead *tfm)
34188e8ec596SKim Phillips {
3419f2147b88SHerbert Xu 	struct aead_alg *alg = crypto_aead_alg(tfm);
3420f2147b88SHerbert Xu 	struct caam_aead_alg *caam_alg =
3421f2147b88SHerbert Xu 		 container_of(alg, struct caam_aead_alg, aead);
3422f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(tfm);
34238e8ec596SKim Phillips 
34241c240226SIuliana Prodan 	crypto_aead_set_reqsize(tfm, sizeof(struct caam_aead_req_ctx));
34251c240226SIuliana Prodan 
34261c240226SIuliana Prodan 	ctx->enginectx.op.do_one_request = aead_do_one_req;
34271c240226SIuliana Prodan 
342824586b5fSHerbert Xu 	return caam_init_common(ctx, &caam_alg->caam, !caam_alg->caam.nodkp);
3429f2147b88SHerbert Xu }
3430f2147b88SHerbert Xu 
3431f2147b88SHerbert Xu static void caam_exit_common(struct caam_ctx *ctx)
3432f2147b88SHerbert Xu {
3433bbf22344SHoria Geantă 	dma_unmap_single_attrs(ctx->jrdev, ctx->sh_desc_enc_dma,
3434ee38767fSIuliana Prodan 			       offsetof(struct caam_ctx, sh_desc_enc_dma) -
3435ee38767fSIuliana Prodan 			       offsetof(struct caam_ctx, sh_desc_enc),
34367e0880b9SHoria Geantă 			       ctx->dir, DMA_ATTR_SKIP_CPU_SYNC);
3437cfc6f11bSRuchika Gupta 	caam_jr_free(ctx->jrdev);
34388e8ec596SKim Phillips }
34398e8ec596SKim Phillips 
34405ca7badbSHoria Geantă static void caam_cra_exit(struct crypto_skcipher *tfm)
3441f2147b88SHerbert Xu {
34429d9b14dbSAndrei Botila 	struct caam_ctx *ctx = crypto_skcipher_ctx(tfm);
34439d9b14dbSAndrei Botila 
34449d9b14dbSAndrei Botila 	if (ctx->fallback)
34459d9b14dbSAndrei Botila 		crypto_free_skcipher(ctx->fallback);
34469d9b14dbSAndrei Botila 	caam_exit_common(ctx);
3447f2147b88SHerbert Xu }
3448f2147b88SHerbert Xu 
3449f2147b88SHerbert Xu static void caam_aead_exit(struct crypto_aead *tfm)
3450f2147b88SHerbert Xu {
3451f2147b88SHerbert Xu 	caam_exit_common(crypto_aead_ctx(tfm));
3452f2147b88SHerbert Xu }
3453f2147b88SHerbert Xu 
34541b46c90cSHoria Geantă void caam_algapi_exit(void)
34558e8ec596SKim Phillips {
3456f2147b88SHerbert Xu 	int i;
3457f2147b88SHerbert Xu 
3458f2147b88SHerbert Xu 	for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
3459f2147b88SHerbert Xu 		struct caam_aead_alg *t_alg = driver_aeads + i;
3460f2147b88SHerbert Xu 
3461f2147b88SHerbert Xu 		if (t_alg->registered)
3462f2147b88SHerbert Xu 			crypto_unregister_aead(&t_alg->aead);
3463f2147b88SHerbert Xu 	}
34648e8ec596SKim Phillips 
34655ca7badbSHoria Geantă 	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
34665ca7badbSHoria Geantă 		struct caam_skcipher_alg *t_alg = driver_algs + i;
34678e8ec596SKim Phillips 
34685ca7badbSHoria Geantă 		if (t_alg->registered)
34695ca7badbSHoria Geantă 			crypto_unregister_skcipher(&t_alg->skcipher);
34708e8ec596SKim Phillips 	}
34718e8ec596SKim Phillips }
34728e8ec596SKim Phillips 
34735ca7badbSHoria Geantă static void caam_skcipher_alg_init(struct caam_skcipher_alg *t_alg)
34748e8ec596SKim Phillips {
34755ca7badbSHoria Geantă 	struct skcipher_alg *alg = &t_alg->skcipher;
34768e8ec596SKim Phillips 
34775ca7badbSHoria Geantă 	alg->base.cra_module = THIS_MODULE;
34785ca7badbSHoria Geantă 	alg->base.cra_priority = CAAM_CRA_PRIORITY;
34795ca7badbSHoria Geantă 	alg->base.cra_ctxsize = sizeof(struct caam_ctx);
34809d9b14dbSAndrei Botila 	alg->base.cra_flags |= (CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
34819d9b14dbSAndrei Botila 			      CRYPTO_ALG_KERN_DRIVER_ONLY);
34828e8ec596SKim Phillips 
34835ca7badbSHoria Geantă 	alg->init = caam_cra_init;
34845ca7badbSHoria Geantă 	alg->exit = caam_cra_exit;
34858e8ec596SKim Phillips }
34868e8ec596SKim Phillips 
3487f2147b88SHerbert Xu static void caam_aead_alg_init(struct caam_aead_alg *t_alg)
3488f2147b88SHerbert Xu {
3489f2147b88SHerbert Xu 	struct aead_alg *alg = &t_alg->aead;
3490f2147b88SHerbert Xu 
3491f2147b88SHerbert Xu 	alg->base.cra_module = THIS_MODULE;
3492f2147b88SHerbert Xu 	alg->base.cra_priority = CAAM_CRA_PRIORITY;
3493f2147b88SHerbert Xu 	alg->base.cra_ctxsize = sizeof(struct caam_ctx);
3494b8aa7dc5SMikulas Patocka 	alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY |
3495b8aa7dc5SMikulas Patocka 			      CRYPTO_ALG_KERN_DRIVER_ONLY;
3496f2147b88SHerbert Xu 
3497f2147b88SHerbert Xu 	alg->init = caam_aead_init;
3498f2147b88SHerbert Xu 	alg->exit = caam_aead_exit;
3499f2147b88SHerbert Xu }
3500f2147b88SHerbert Xu 
35011b46c90cSHoria Geantă int caam_algapi_init(struct device *ctrldev)
35028e8ec596SKim Phillips {
35031b46c90cSHoria Geantă 	struct caam_drv_private *priv = dev_get_drvdata(ctrldev);
35048e8ec596SKim Phillips 	int i = 0, err = 0;
3505d6bbd4eeSHoria Geantă 	u32 aes_vid, aes_inst, des_inst, md_vid, md_inst, ccha_inst, ptha_inst;
3506bf83490eSVictoria Milhoan 	unsigned int md_limit = SHA512_DIGEST_SIZE;
3507df80bfd3SHoria Geantă 	bool registered = false, gcm_support;
35088e8ec596SKim Phillips 
3509bf83490eSVictoria Milhoan 	/*
3510bf83490eSVictoria Milhoan 	 * Register crypto algorithms the device supports.
3511bf83490eSVictoria Milhoan 	 * First, detect presence and attributes of DES, AES, and MD blocks.
3512bf83490eSVictoria Milhoan 	 */
3513d239b10dSHoria Geantă 	if (priv->era < 10) {
3514df80bfd3SHoria Geantă 		u32 cha_vid, cha_inst, aes_rn;
3515d239b10dSHoria Geantă 
3516bf83490eSVictoria Milhoan 		cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
3517d239b10dSHoria Geantă 		aes_vid = cha_vid & CHA_ID_LS_AES_MASK;
3518d239b10dSHoria Geantă 		md_vid = (cha_vid & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
3519d239b10dSHoria Geantă 
3520bf83490eSVictoria Milhoan 		cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
3521d239b10dSHoria Geantă 		des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >>
3522d239b10dSHoria Geantă 			   CHA_ID_LS_DES_SHIFT;
3523d239b10dSHoria Geantă 		aes_inst = cha_inst & CHA_ID_LS_AES_MASK;
3524bf83490eSVictoria Milhoan 		md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
3525d6bbd4eeSHoria Geantă 		ccha_inst = 0;
3526d6bbd4eeSHoria Geantă 		ptha_inst = 0;
3527df80bfd3SHoria Geantă 
3528df80bfd3SHoria Geantă 		aes_rn = rd_reg32(&priv->ctrl->perfmon.cha_rev_ls) &
3529df80bfd3SHoria Geantă 			 CHA_ID_LS_AES_MASK;
3530df80bfd3SHoria Geantă 		gcm_support = !(aes_vid == CHA_VER_VID_AES_LP && aes_rn < 8);
3531d239b10dSHoria Geantă 	} else {
3532d239b10dSHoria Geantă 		u32 aesa, mdha;
3533d239b10dSHoria Geantă 
3534d239b10dSHoria Geantă 		aesa = rd_reg32(&priv->ctrl->vreg.aesa);
3535d239b10dSHoria Geantă 		mdha = rd_reg32(&priv->ctrl->vreg.mdha);
3536d239b10dSHoria Geantă 
3537d239b10dSHoria Geantă 		aes_vid = (aesa & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
3538d239b10dSHoria Geantă 		md_vid = (mdha & CHA_VER_VID_MASK) >> CHA_VER_VID_SHIFT;
3539d239b10dSHoria Geantă 
3540d239b10dSHoria Geantă 		des_inst = rd_reg32(&priv->ctrl->vreg.desa) & CHA_VER_NUM_MASK;
3541d239b10dSHoria Geantă 		aes_inst = aesa & CHA_VER_NUM_MASK;
3542d239b10dSHoria Geantă 		md_inst = mdha & CHA_VER_NUM_MASK;
3543d6bbd4eeSHoria Geantă 		ccha_inst = rd_reg32(&priv->ctrl->vreg.ccha) & CHA_VER_NUM_MASK;
3544d6bbd4eeSHoria Geantă 		ptha_inst = rd_reg32(&priv->ctrl->vreg.ptha) & CHA_VER_NUM_MASK;
3545df80bfd3SHoria Geantă 
3546df80bfd3SHoria Geantă 		gcm_support = aesa & CHA_VER_MISC_AES_GCM;
3547d239b10dSHoria Geantă 	}
35488e8ec596SKim Phillips 
3549bf83490eSVictoria Milhoan 	/* If MD is present, limit digest size based on LP256 */
3550d239b10dSHoria Geantă 	if (md_inst && md_vid  == CHA_VER_VID_MD_LP256)
3551bf83490eSVictoria Milhoan 		md_limit = SHA256_DIGEST_SIZE;
3552bf83490eSVictoria Milhoan 
3553bf83490eSVictoria Milhoan 	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
35545ca7badbSHoria Geantă 		struct caam_skcipher_alg *t_alg = driver_algs + i;
35555ca7badbSHoria Geantă 		u32 alg_sel = t_alg->caam.class1_alg_type & OP_ALG_ALGSEL_MASK;
3556bf83490eSVictoria Milhoan 
3557bf83490eSVictoria Milhoan 		/* Skip DES algorithms if not supported by device */
3558bf83490eSVictoria Milhoan 		if (!des_inst &&
3559bf83490eSVictoria Milhoan 		    ((alg_sel == OP_ALG_ALGSEL_3DES) ||
3560bf83490eSVictoria Milhoan 		     (alg_sel == OP_ALG_ALGSEL_DES)))
3561bf83490eSVictoria Milhoan 				continue;
3562bf83490eSVictoria Milhoan 
3563bf83490eSVictoria Milhoan 		/* Skip AES algorithms if not supported by device */
3564bf83490eSVictoria Milhoan 		if (!aes_inst && (alg_sel == OP_ALG_ALGSEL_AES))
3565bf83490eSVictoria Milhoan 				continue;
3566bf83490eSVictoria Milhoan 
356783d2c9a9SSven Ebenfeld 		/*
356883d2c9a9SSven Ebenfeld 		 * Check support for AES modes not available
356983d2c9a9SSven Ebenfeld 		 * on LP devices.
357083d2c9a9SSven Ebenfeld 		 */
3571d239b10dSHoria Geantă 		if (aes_vid == CHA_VER_VID_AES_LP &&
3572d239b10dSHoria Geantă 		    (t_alg->caam.class1_alg_type & OP_ALG_AAI_MASK) ==
357383d2c9a9SSven Ebenfeld 		    OP_ALG_AAI_XTS)
357483d2c9a9SSven Ebenfeld 			continue;
357583d2c9a9SSven Ebenfeld 
35765ca7badbSHoria Geantă 		caam_skcipher_alg_init(t_alg);
35778e8ec596SKim Phillips 
35785ca7badbSHoria Geantă 		err = crypto_register_skcipher(&t_alg->skcipher);
35798e8ec596SKim Phillips 		if (err) {
3580cfc6f11bSRuchika Gupta 			pr_warn("%s alg registration failed\n",
35815ca7badbSHoria Geantă 				t_alg->skcipher.base.cra_driver_name);
3582f2147b88SHerbert Xu 			continue;
35838e8ec596SKim Phillips 		}
3584f2147b88SHerbert Xu 
35855ca7badbSHoria Geantă 		t_alg->registered = true;
3586f2147b88SHerbert Xu 		registered = true;
3587f2147b88SHerbert Xu 	}
3588f2147b88SHerbert Xu 
3589f2147b88SHerbert Xu 	for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
3590f2147b88SHerbert Xu 		struct caam_aead_alg *t_alg = driver_aeads + i;
3591bf83490eSVictoria Milhoan 		u32 c1_alg_sel = t_alg->caam.class1_alg_type &
3592bf83490eSVictoria Milhoan 				 OP_ALG_ALGSEL_MASK;
3593bf83490eSVictoria Milhoan 		u32 c2_alg_sel = t_alg->caam.class2_alg_type &
3594bf83490eSVictoria Milhoan 				 OP_ALG_ALGSEL_MASK;
3595bf83490eSVictoria Milhoan 		u32 alg_aai = t_alg->caam.class1_alg_type & OP_ALG_AAI_MASK;
3596bf83490eSVictoria Milhoan 
3597bf83490eSVictoria Milhoan 		/* Skip DES algorithms if not supported by device */
3598bf83490eSVictoria Milhoan 		if (!des_inst &&
3599bf83490eSVictoria Milhoan 		    ((c1_alg_sel == OP_ALG_ALGSEL_3DES) ||
3600bf83490eSVictoria Milhoan 		     (c1_alg_sel == OP_ALG_ALGSEL_DES)))
3601bf83490eSVictoria Milhoan 				continue;
3602bf83490eSVictoria Milhoan 
3603bf83490eSVictoria Milhoan 		/* Skip AES algorithms if not supported by device */
3604bf83490eSVictoria Milhoan 		if (!aes_inst && (c1_alg_sel == OP_ALG_ALGSEL_AES))
3605bf83490eSVictoria Milhoan 				continue;
3606bf83490eSVictoria Milhoan 
3607d6bbd4eeSHoria Geantă 		/* Skip CHACHA20 algorithms if not supported by device */
3608d6bbd4eeSHoria Geantă 		if (c1_alg_sel == OP_ALG_ALGSEL_CHACHA20 && !ccha_inst)
3609d6bbd4eeSHoria Geantă 			continue;
3610d6bbd4eeSHoria Geantă 
3611d6bbd4eeSHoria Geantă 		/* Skip POLY1305 algorithms if not supported by device */
3612d6bbd4eeSHoria Geantă 		if (c2_alg_sel == OP_ALG_ALGSEL_POLY1305 && !ptha_inst)
3613d6bbd4eeSHoria Geantă 			continue;
3614d6bbd4eeSHoria Geantă 
3615df80bfd3SHoria Geantă 		/* Skip GCM algorithms if not supported by device */
3616df80bfd3SHoria Geantă 		if (c1_alg_sel == OP_ALG_ALGSEL_AES &&
3617df80bfd3SHoria Geantă 		    alg_aai == OP_ALG_AAI_GCM && !gcm_support)
3618bf83490eSVictoria Milhoan 			continue;
3619bf83490eSVictoria Milhoan 
3620bf83490eSVictoria Milhoan 		/*
3621bf83490eSVictoria Milhoan 		 * Skip algorithms requiring message digests
3622bf83490eSVictoria Milhoan 		 * if MD or MD size is not supported by device.
3623bf83490eSVictoria Milhoan 		 */
36242dd3fde4SHoria Geantă 		if (is_mdha(c2_alg_sel) &&
3625d6bbd4eeSHoria Geantă 		    (!md_inst || t_alg->aead.maxauthsize > md_limit))
3626bf83490eSVictoria Milhoan 			continue;
3627f2147b88SHerbert Xu 
3628f2147b88SHerbert Xu 		caam_aead_alg_init(t_alg);
3629f2147b88SHerbert Xu 
3630f2147b88SHerbert Xu 		err = crypto_register_aead(&t_alg->aead);
3631f2147b88SHerbert Xu 		if (err) {
3632f2147b88SHerbert Xu 			pr_warn("%s alg registration failed\n",
3633f2147b88SHerbert Xu 				t_alg->aead.base.cra_driver_name);
3634f2147b88SHerbert Xu 			continue;
3635f2147b88SHerbert Xu 		}
3636f2147b88SHerbert Xu 
3637f2147b88SHerbert Xu 		t_alg->registered = true;
3638f2147b88SHerbert Xu 		registered = true;
3639f2147b88SHerbert Xu 	}
3640f2147b88SHerbert Xu 
3641f2147b88SHerbert Xu 	if (registered)
3642cfc6f11bSRuchika Gupta 		pr_info("caam algorithms registered in /proc/crypto\n");
36438e8ec596SKim Phillips 
36448e8ec596SKim Phillips 	return err;
36458e8ec596SKim Phillips }
3646