xref: /openbmc/linux/drivers/crypto/caam/caamalg.c (revision 5ba1c7b5)
18e8ec596SKim Phillips /*
28e8ec596SKim Phillips  * caam - Freescale FSL CAAM support for crypto API
38e8ec596SKim Phillips  *
48e8ec596SKim Phillips  * Copyright 2008-2011 Freescale Semiconductor, Inc.
58e8ec596SKim Phillips  *
68e8ec596SKim Phillips  * Based on talitos crypto API driver.
78e8ec596SKim Phillips  *
88e8ec596SKim Phillips  * relationship of job descriptors to shared descriptors (SteveC Dec 10 2008):
98e8ec596SKim Phillips  *
108e8ec596SKim Phillips  * ---------------                     ---------------
118e8ec596SKim Phillips  * | JobDesc #1  |-------------------->|  ShareDesc  |
128e8ec596SKim Phillips  * | *(packet 1) |                     |   (PDB)     |
138e8ec596SKim Phillips  * ---------------      |------------->|  (hashKey)  |
148e8ec596SKim Phillips  *       .              |              | (cipherKey) |
158e8ec596SKim Phillips  *       .              |    |-------->| (operation) |
168e8ec596SKim Phillips  * ---------------      |    |         ---------------
178e8ec596SKim Phillips  * | JobDesc #2  |------|    |
188e8ec596SKim Phillips  * | *(packet 2) |           |
198e8ec596SKim Phillips  * ---------------           |
208e8ec596SKim Phillips  *       .                   |
218e8ec596SKim Phillips  *       .                   |
228e8ec596SKim Phillips  * ---------------           |
238e8ec596SKim Phillips  * | JobDesc #3  |------------
248e8ec596SKim Phillips  * | *(packet 3) |
258e8ec596SKim Phillips  * ---------------
268e8ec596SKim Phillips  *
278e8ec596SKim Phillips  * The SharedDesc never changes for a connection unless rekeyed, but
288e8ec596SKim Phillips  * each packet will likely be in a different place. So all we need
298e8ec596SKim Phillips  * to know to process the packet is where the input is, where the
308e8ec596SKim Phillips  * output goes, and what context we want to process with. Context is
318e8ec596SKim Phillips  * in the SharedDesc, packet references in the JobDesc.
328e8ec596SKim Phillips  *
338e8ec596SKim Phillips  * So, a job desc looks like:
348e8ec596SKim Phillips  *
358e8ec596SKim Phillips  * ---------------------
368e8ec596SKim Phillips  * | Header            |
378e8ec596SKim Phillips  * | ShareDesc Pointer |
388e8ec596SKim Phillips  * | SEQ_OUT_PTR       |
398e8ec596SKim Phillips  * | (output buffer)   |
406ec47334SYuan Kang  * | (output length)   |
418e8ec596SKim Phillips  * | SEQ_IN_PTR        |
428e8ec596SKim Phillips  * | (input buffer)    |
436ec47334SYuan Kang  * | (input length)    |
448e8ec596SKim Phillips  * ---------------------
458e8ec596SKim Phillips  */
468e8ec596SKim Phillips 
478e8ec596SKim Phillips #include "compat.h"
488e8ec596SKim Phillips 
498e8ec596SKim Phillips #include "regs.h"
508e8ec596SKim Phillips #include "intern.h"
518e8ec596SKim Phillips #include "desc_constr.h"
528e8ec596SKim Phillips #include "jr.h"
538e8ec596SKim Phillips #include "error.h"
54a299c837SYuan Kang #include "sg_sw_sec4.h"
554c1ec1f9SYuan Kang #include "key_gen.h"
568e8ec596SKim Phillips 
578e8ec596SKim Phillips /*
588e8ec596SKim Phillips  * crypto alg
598e8ec596SKim Phillips  */
608e8ec596SKim Phillips #define CAAM_CRA_PRIORITY		3000
618e8ec596SKim Phillips /* max key is sum of AES_MAX_KEY_SIZE, max split key size */
628e8ec596SKim Phillips #define CAAM_MAX_KEY_SIZE		(AES_MAX_KEY_SIZE + \
63daebc465SCatalin Vasile 					 CTR_RFC3686_NONCE_SIZE + \
648e8ec596SKim Phillips 					 SHA512_DIGEST_SIZE * 2)
658e8ec596SKim Phillips /* max IV is max of AES_BLOCK_SIZE, DES3_EDE_BLOCK_SIZE */
668e8ec596SKim Phillips #define CAAM_MAX_IV_LENGTH		16
678e8ec596SKim Phillips 
68f2147b88SHerbert Xu #define AEAD_DESC_JOB_IO_LEN		(DESC_JOB_IO_LEN + CAAM_CMD_SZ * 2)
69f2147b88SHerbert Xu #define GCM_DESC_JOB_IO_LEN		(AEAD_DESC_JOB_IO_LEN + \
70f2147b88SHerbert Xu 					 CAAM_CMD_SZ * 4)
71479bcc7cSHerbert Xu #define AUTHENC_DESC_JOB_IO_LEN		(AEAD_DESC_JOB_IO_LEN + \
72479bcc7cSHerbert Xu 					 CAAM_CMD_SZ * 5)
73f2147b88SHerbert Xu 
744427b1b4SKim Phillips /* length of descriptors text */
751acebad3SYuan Kang #define DESC_AEAD_BASE			(4 * CAAM_CMD_SZ)
76479bcc7cSHerbert Xu #define DESC_AEAD_ENC_LEN		(DESC_AEAD_BASE + 11 * CAAM_CMD_SZ)
77479bcc7cSHerbert Xu #define DESC_AEAD_DEC_LEN		(DESC_AEAD_BASE + 15 * CAAM_CMD_SZ)
78479bcc7cSHerbert Xu #define DESC_AEAD_GIVENC_LEN		(DESC_AEAD_ENC_LEN + 9 * CAAM_CMD_SZ)
791acebad3SYuan Kang 
80daebc465SCatalin Vasile /* Note: Nonce is counted in enckeylen */
81479bcc7cSHerbert Xu #define DESC_AEAD_CTR_RFC3686_LEN	(4 * CAAM_CMD_SZ)
82daebc465SCatalin Vasile 
83ae4a825fSHoria Geanta #define DESC_AEAD_NULL_BASE		(3 * CAAM_CMD_SZ)
84479bcc7cSHerbert Xu #define DESC_AEAD_NULL_ENC_LEN		(DESC_AEAD_NULL_BASE + 11 * CAAM_CMD_SZ)
85479bcc7cSHerbert Xu #define DESC_AEAD_NULL_DEC_LEN		(DESC_AEAD_NULL_BASE + 13 * CAAM_CMD_SZ)
86ae4a825fSHoria Geanta 
873ef8d945STudor Ambarus #define DESC_GCM_BASE			(3 * CAAM_CMD_SZ)
88f2147b88SHerbert Xu #define DESC_GCM_ENC_LEN		(DESC_GCM_BASE + 16 * CAAM_CMD_SZ)
89f2147b88SHerbert Xu #define DESC_GCM_DEC_LEN		(DESC_GCM_BASE + 12 * CAAM_CMD_SZ)
903ef8d945STudor Ambarus 
91bac68f2cSTudor Ambarus #define DESC_RFC4106_BASE		(3 * CAAM_CMD_SZ)
924aad0cc5SHoria Geant? #define DESC_RFC4106_ENC_LEN		(DESC_RFC4106_BASE + 13 * CAAM_CMD_SZ)
934aad0cc5SHoria Geant? #define DESC_RFC4106_DEC_LEN		(DESC_RFC4106_BASE + 13 * CAAM_CMD_SZ)
94bac68f2cSTudor Ambarus 
955d0429a3STudor Ambarus #define DESC_RFC4543_BASE		(3 * CAAM_CMD_SZ)
96f2147b88SHerbert Xu #define DESC_RFC4543_ENC_LEN		(DESC_RFC4543_BASE + 11 * CAAM_CMD_SZ)
97f2147b88SHerbert Xu #define DESC_RFC4543_DEC_LEN		(DESC_RFC4543_BASE + 12 * CAAM_CMD_SZ)
985d0429a3STudor Ambarus 
99acdca31dSYuan Kang #define DESC_ABLKCIPHER_BASE		(3 * CAAM_CMD_SZ)
100acdca31dSYuan Kang #define DESC_ABLKCIPHER_ENC_LEN		(DESC_ABLKCIPHER_BASE + \
101acdca31dSYuan Kang 					 20 * CAAM_CMD_SZ)
102acdca31dSYuan Kang #define DESC_ABLKCIPHER_DEC_LEN		(DESC_ABLKCIPHER_BASE + \
103acdca31dSYuan Kang 					 15 * CAAM_CMD_SZ)
104acdca31dSYuan Kang 
10587e51b07SHerbert Xu #define DESC_MAX_USED_BYTES		(CAAM_DESC_BYTES_MAX - DESC_JOB_IO_LEN)
10687e51b07SHerbert Xu #define DESC_MAX_USED_LEN		(DESC_MAX_USED_BYTES / CAAM_CMD_SZ)
1074427b1b4SKim Phillips 
1088e8ec596SKim Phillips #ifdef DEBUG
1098e8ec596SKim Phillips /* for print_hex_dumps with line references */
1108e8ec596SKim Phillips #define debug(format, arg...) printk(format, arg)
1118e8ec596SKim Phillips #else
1128e8ec596SKim Phillips #define debug(format, arg...)
1138e8ec596SKim Phillips #endif
114cfc6f11bSRuchika Gupta static struct list_head alg_list;
1158e8ec596SKim Phillips 
116479bcc7cSHerbert Xu struct caam_alg_entry {
117479bcc7cSHerbert Xu 	int class1_alg_type;
118479bcc7cSHerbert Xu 	int class2_alg_type;
119479bcc7cSHerbert Xu 	int alg_op;
120479bcc7cSHerbert Xu 	bool rfc3686;
121479bcc7cSHerbert Xu 	bool geniv;
122479bcc7cSHerbert Xu };
123479bcc7cSHerbert Xu 
124479bcc7cSHerbert Xu struct caam_aead_alg {
125479bcc7cSHerbert Xu 	struct aead_alg aead;
126479bcc7cSHerbert Xu 	struct caam_alg_entry caam;
127479bcc7cSHerbert Xu 	bool registered;
128479bcc7cSHerbert Xu };
129479bcc7cSHerbert Xu 
1301acebad3SYuan Kang /* Set DK bit in class 1 operation if shared */
1311acebad3SYuan Kang static inline void append_dec_op1(u32 *desc, u32 type)
1321acebad3SYuan Kang {
1331acebad3SYuan Kang 	u32 *jump_cmd, *uncond_jump_cmd;
1341acebad3SYuan Kang 
135a60384dfSHoria Geanta 	/* DK bit is valid only for AES */
136a60384dfSHoria Geanta 	if ((type & OP_ALG_ALGSEL_MASK) != OP_ALG_ALGSEL_AES) {
137a60384dfSHoria Geanta 		append_operation(desc, type | OP_ALG_AS_INITFINAL |
138a60384dfSHoria Geanta 				 OP_ALG_DECRYPT);
139a60384dfSHoria Geanta 		return;
140a60384dfSHoria Geanta 	}
141a60384dfSHoria Geanta 
1421acebad3SYuan Kang 	jump_cmd = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
1431acebad3SYuan Kang 	append_operation(desc, type | OP_ALG_AS_INITFINAL |
1441acebad3SYuan Kang 			 OP_ALG_DECRYPT);
1451acebad3SYuan Kang 	uncond_jump_cmd = append_jump(desc, JUMP_TEST_ALL);
1461acebad3SYuan Kang 	set_jump_tgt_here(desc, jump_cmd);
1471acebad3SYuan Kang 	append_operation(desc, type | OP_ALG_AS_INITFINAL |
1481acebad3SYuan Kang 			 OP_ALG_DECRYPT | OP_ALG_AAI_DK);
1491acebad3SYuan Kang 	set_jump_tgt_here(desc, uncond_jump_cmd);
1501acebad3SYuan Kang }
1511acebad3SYuan Kang 
1521acebad3SYuan Kang /*
1531acebad3SYuan Kang  * For aead functions, read payload and write payload,
1541acebad3SYuan Kang  * both of which are specified in req->src and req->dst
1551acebad3SYuan Kang  */
1561acebad3SYuan Kang static inline void aead_append_src_dst(u32 *desc, u32 msg_type)
1571acebad3SYuan Kang {
158ae4a825fSHoria Geanta 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
1591acebad3SYuan Kang 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH |
1601acebad3SYuan Kang 			     KEY_VLF | msg_type | FIFOLD_TYPE_LASTBOTH);
1611acebad3SYuan Kang }
1621acebad3SYuan Kang 
1631acebad3SYuan Kang /*
164acdca31dSYuan Kang  * For ablkcipher encrypt and decrypt, read from req->src and
165acdca31dSYuan Kang  * write to req->dst
166acdca31dSYuan Kang  */
167acdca31dSYuan Kang static inline void ablkcipher_append_src_dst(u32 *desc)
168acdca31dSYuan Kang {
16970d793ccSKim Phillips 	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
17070d793ccSKim Phillips 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
17170d793ccSKim Phillips 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 |
17270d793ccSKim Phillips 			     KEY_VLF | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
17370d793ccSKim Phillips 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
174acdca31dSYuan Kang }
175acdca31dSYuan Kang 
176acdca31dSYuan Kang /*
1778e8ec596SKim Phillips  * per-session context
1788e8ec596SKim Phillips  */
1798e8ec596SKim Phillips struct caam_ctx {
1808e8ec596SKim Phillips 	struct device *jrdev;
1811acebad3SYuan Kang 	u32 sh_desc_enc[DESC_MAX_USED_LEN];
1821acebad3SYuan Kang 	u32 sh_desc_dec[DESC_MAX_USED_LEN];
1831acebad3SYuan Kang 	u32 sh_desc_givenc[DESC_MAX_USED_LEN];
1841acebad3SYuan Kang 	dma_addr_t sh_desc_enc_dma;
1851acebad3SYuan Kang 	dma_addr_t sh_desc_dec_dma;
1861acebad3SYuan Kang 	dma_addr_t sh_desc_givenc_dma;
1878e8ec596SKim Phillips 	u32 class1_alg_type;
1888e8ec596SKim Phillips 	u32 class2_alg_type;
1898e8ec596SKim Phillips 	u32 alg_op;
1901acebad3SYuan Kang 	u8 key[CAAM_MAX_KEY_SIZE];
191885e9e2fSYuan Kang 	dma_addr_t key_dma;
1928e8ec596SKim Phillips 	unsigned int enckeylen;
1938e8ec596SKim Phillips 	unsigned int split_key_len;
1948e8ec596SKim Phillips 	unsigned int split_key_pad_len;
1958e8ec596SKim Phillips 	unsigned int authsize;
1968e8ec596SKim Phillips };
1978e8ec596SKim Phillips 
1981acebad3SYuan Kang static void append_key_aead(u32 *desc, struct caam_ctx *ctx,
199daebc465SCatalin Vasile 			    int keys_fit_inline, bool is_rfc3686)
2001acebad3SYuan Kang {
201daebc465SCatalin Vasile 	u32 *nonce;
202daebc465SCatalin Vasile 	unsigned int enckeylen = ctx->enckeylen;
203daebc465SCatalin Vasile 
204daebc465SCatalin Vasile 	/*
205daebc465SCatalin Vasile 	 * RFC3686 specific:
206daebc465SCatalin Vasile 	 *	| ctx->key = {AUTH_KEY, ENC_KEY, NONCE}
207daebc465SCatalin Vasile 	 *	| enckeylen = encryption key size + nonce size
208daebc465SCatalin Vasile 	 */
209daebc465SCatalin Vasile 	if (is_rfc3686)
210daebc465SCatalin Vasile 		enckeylen -= CTR_RFC3686_NONCE_SIZE;
211daebc465SCatalin Vasile 
2121acebad3SYuan Kang 	if (keys_fit_inline) {
2131acebad3SYuan Kang 		append_key_as_imm(desc, ctx->key, ctx->split_key_pad_len,
2141acebad3SYuan Kang 				  ctx->split_key_len, CLASS_2 |
2151acebad3SYuan Kang 				  KEY_DEST_MDHA_SPLIT | KEY_ENC);
2161acebad3SYuan Kang 		append_key_as_imm(desc, (void *)ctx->key +
217daebc465SCatalin Vasile 				  ctx->split_key_pad_len, enckeylen,
218daebc465SCatalin Vasile 				  enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
2191acebad3SYuan Kang 	} else {
2201acebad3SYuan Kang 		append_key(desc, ctx->key_dma, ctx->split_key_len, CLASS_2 |
2211acebad3SYuan Kang 			   KEY_DEST_MDHA_SPLIT | KEY_ENC);
2221acebad3SYuan Kang 		append_key(desc, ctx->key_dma + ctx->split_key_pad_len,
223daebc465SCatalin Vasile 			   enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
224daebc465SCatalin Vasile 	}
225daebc465SCatalin Vasile 
226daebc465SCatalin Vasile 	/* Load Counter into CONTEXT1 reg */
227daebc465SCatalin Vasile 	if (is_rfc3686) {
228daebc465SCatalin Vasile 		nonce = (u32 *)((void *)ctx->key + ctx->split_key_pad_len +
229daebc465SCatalin Vasile 			       enckeylen);
2305ba1c7b5SCatalin Vasile 		append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
2315ba1c7b5SCatalin Vasile 				   LDST_CLASS_IND_CCB |
232daebc465SCatalin Vasile 				   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
233daebc465SCatalin Vasile 		append_move(desc,
234daebc465SCatalin Vasile 			    MOVE_SRC_OUTFIFO |
235daebc465SCatalin Vasile 			    MOVE_DEST_CLASS1CTX |
236daebc465SCatalin Vasile 			    (16 << MOVE_OFFSET_SHIFT) |
237daebc465SCatalin Vasile 			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
2381acebad3SYuan Kang 	}
2391acebad3SYuan Kang }
2401acebad3SYuan Kang 
2411acebad3SYuan Kang static void init_sh_desc_key_aead(u32 *desc, struct caam_ctx *ctx,
242daebc465SCatalin Vasile 				  int keys_fit_inline, bool is_rfc3686)
2431acebad3SYuan Kang {
2441acebad3SYuan Kang 	u32 *key_jump_cmd;
2451acebad3SYuan Kang 
246daebc465SCatalin Vasile 	/* Note: Context registers are saved. */
247daebc465SCatalin Vasile 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
2481acebad3SYuan Kang 
2491acebad3SYuan Kang 	/* Skip if already shared */
2501acebad3SYuan Kang 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
2511acebad3SYuan Kang 				   JUMP_COND_SHRD);
2521acebad3SYuan Kang 
253daebc465SCatalin Vasile 	append_key_aead(desc, ctx, keys_fit_inline, is_rfc3686);
2541acebad3SYuan Kang 
2551acebad3SYuan Kang 	set_jump_tgt_here(desc, key_jump_cmd);
2561acebad3SYuan Kang }
2571acebad3SYuan Kang 
258ae4a825fSHoria Geanta static int aead_null_set_sh_desc(struct crypto_aead *aead)
259ae4a825fSHoria Geanta {
260ae4a825fSHoria Geanta 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
261ae4a825fSHoria Geanta 	struct device *jrdev = ctx->jrdev;
262ae4a825fSHoria Geanta 	bool keys_fit_inline = false;
263ae4a825fSHoria Geanta 	u32 *key_jump_cmd, *jump_cmd, *read_move_cmd, *write_move_cmd;
264ae4a825fSHoria Geanta 	u32 *desc;
265ae4a825fSHoria Geanta 
266ae4a825fSHoria Geanta 	/*
267ae4a825fSHoria Geanta 	 * Job Descriptor and Shared Descriptors
268ae4a825fSHoria Geanta 	 * must all fit into the 64-word Descriptor h/w Buffer
269ae4a825fSHoria Geanta 	 */
270479bcc7cSHerbert Xu 	if (DESC_AEAD_NULL_ENC_LEN + AEAD_DESC_JOB_IO_LEN +
271ae4a825fSHoria Geanta 	    ctx->split_key_pad_len <= CAAM_DESC_BYTES_MAX)
272ae4a825fSHoria Geanta 		keys_fit_inline = true;
273ae4a825fSHoria Geanta 
274479bcc7cSHerbert Xu 	/* aead_encrypt shared descriptor */
275ae4a825fSHoria Geanta 	desc = ctx->sh_desc_enc;
276ae4a825fSHoria Geanta 
277ae4a825fSHoria Geanta 	init_sh_desc(desc, HDR_SHARE_SERIAL);
278ae4a825fSHoria Geanta 
279ae4a825fSHoria Geanta 	/* Skip if already shared */
280ae4a825fSHoria Geanta 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
281ae4a825fSHoria Geanta 				   JUMP_COND_SHRD);
282ae4a825fSHoria Geanta 	if (keys_fit_inline)
283ae4a825fSHoria Geanta 		append_key_as_imm(desc, ctx->key, ctx->split_key_pad_len,
284ae4a825fSHoria Geanta 				  ctx->split_key_len, CLASS_2 |
285ae4a825fSHoria Geanta 				  KEY_DEST_MDHA_SPLIT | KEY_ENC);
286ae4a825fSHoria Geanta 	else
287ae4a825fSHoria Geanta 		append_key(desc, ctx->key_dma, ctx->split_key_len, CLASS_2 |
288ae4a825fSHoria Geanta 			   KEY_DEST_MDHA_SPLIT | KEY_ENC);
289ae4a825fSHoria Geanta 	set_jump_tgt_here(desc, key_jump_cmd);
290ae4a825fSHoria Geanta 
291479bcc7cSHerbert Xu 	/* assoclen + cryptlen = seqinlen */
292479bcc7cSHerbert Xu 	append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
293ae4a825fSHoria Geanta 
294479bcc7cSHerbert Xu 	/* Prepare to read and write cryptlen + assoclen bytes */
295ae4a825fSHoria Geanta 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
296ae4a825fSHoria Geanta 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
297ae4a825fSHoria Geanta 
298ae4a825fSHoria Geanta 	/*
299ae4a825fSHoria Geanta 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
300ae4a825fSHoria Geanta 	 * thus need to do some magic, i.e. self-patch the descriptor
301ae4a825fSHoria Geanta 	 * buffer.
302ae4a825fSHoria Geanta 	 */
303ae4a825fSHoria Geanta 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
304ae4a825fSHoria Geanta 				    MOVE_DEST_MATH3 |
305ae4a825fSHoria Geanta 				    (0x6 << MOVE_LEN_SHIFT));
306ae4a825fSHoria Geanta 	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 |
307ae4a825fSHoria Geanta 				     MOVE_DEST_DESCBUF |
308ae4a825fSHoria Geanta 				     MOVE_WAITCOMP |
309ae4a825fSHoria Geanta 				     (0x8 << MOVE_LEN_SHIFT));
310ae4a825fSHoria Geanta 
311ae4a825fSHoria Geanta 	/* Class 2 operation */
312ae4a825fSHoria Geanta 	append_operation(desc, ctx->class2_alg_type |
313ae4a825fSHoria Geanta 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
314ae4a825fSHoria Geanta 
315ae4a825fSHoria Geanta 	/* Read and write cryptlen bytes */
316ae4a825fSHoria Geanta 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
317ae4a825fSHoria Geanta 
318ae4a825fSHoria Geanta 	set_move_tgt_here(desc, read_move_cmd);
319ae4a825fSHoria Geanta 	set_move_tgt_here(desc, write_move_cmd);
320ae4a825fSHoria Geanta 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
321ae4a825fSHoria Geanta 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
322ae4a825fSHoria Geanta 		    MOVE_AUX_LS);
323ae4a825fSHoria Geanta 
324ae4a825fSHoria Geanta 	/* Write ICV */
325ae4a825fSHoria Geanta 	append_seq_store(desc, ctx->authsize, LDST_CLASS_2_CCB |
326ae4a825fSHoria Geanta 			 LDST_SRCDST_BYTE_CONTEXT);
327ae4a825fSHoria Geanta 
328ae4a825fSHoria Geanta 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
329ae4a825fSHoria Geanta 					      desc_bytes(desc),
330ae4a825fSHoria Geanta 					      DMA_TO_DEVICE);
331ae4a825fSHoria Geanta 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
332ae4a825fSHoria Geanta 		dev_err(jrdev, "unable to map shared descriptor\n");
333ae4a825fSHoria Geanta 		return -ENOMEM;
334ae4a825fSHoria Geanta 	}
335ae4a825fSHoria Geanta #ifdef DEBUG
336ae4a825fSHoria Geanta 	print_hex_dump(KERN_ERR,
337ae4a825fSHoria Geanta 		       "aead null enc shdesc@"__stringify(__LINE__)": ",
338ae4a825fSHoria Geanta 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
339ae4a825fSHoria Geanta 		       desc_bytes(desc), 1);
340ae4a825fSHoria Geanta #endif
341ae4a825fSHoria Geanta 
342ae4a825fSHoria Geanta 	/*
343ae4a825fSHoria Geanta 	 * Job Descriptor and Shared Descriptors
344ae4a825fSHoria Geanta 	 * must all fit into the 64-word Descriptor h/w Buffer
345ae4a825fSHoria Geanta 	 */
34680cd88f2SVakul Garg 	keys_fit_inline = false;
347ae4a825fSHoria Geanta 	if (DESC_AEAD_NULL_DEC_LEN + DESC_JOB_IO_LEN +
348ae4a825fSHoria Geanta 	    ctx->split_key_pad_len <= CAAM_DESC_BYTES_MAX)
349ae4a825fSHoria Geanta 		keys_fit_inline = true;
350ae4a825fSHoria Geanta 
351ae4a825fSHoria Geanta 	desc = ctx->sh_desc_dec;
352ae4a825fSHoria Geanta 
353479bcc7cSHerbert Xu 	/* aead_decrypt shared descriptor */
354ae4a825fSHoria Geanta 	init_sh_desc(desc, HDR_SHARE_SERIAL);
355ae4a825fSHoria Geanta 
356ae4a825fSHoria Geanta 	/* Skip if already shared */
357ae4a825fSHoria Geanta 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
358ae4a825fSHoria Geanta 				   JUMP_COND_SHRD);
359ae4a825fSHoria Geanta 	if (keys_fit_inline)
360ae4a825fSHoria Geanta 		append_key_as_imm(desc, ctx->key, ctx->split_key_pad_len,
361ae4a825fSHoria Geanta 				  ctx->split_key_len, CLASS_2 |
362ae4a825fSHoria Geanta 				  KEY_DEST_MDHA_SPLIT | KEY_ENC);
363ae4a825fSHoria Geanta 	else
364ae4a825fSHoria Geanta 		append_key(desc, ctx->key_dma, ctx->split_key_len, CLASS_2 |
365ae4a825fSHoria Geanta 			   KEY_DEST_MDHA_SPLIT | KEY_ENC);
366ae4a825fSHoria Geanta 	set_jump_tgt_here(desc, key_jump_cmd);
367ae4a825fSHoria Geanta 
368ae4a825fSHoria Geanta 	/* Class 2 operation */
369ae4a825fSHoria Geanta 	append_operation(desc, ctx->class2_alg_type |
370ae4a825fSHoria Geanta 			 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON);
371ae4a825fSHoria Geanta 
372479bcc7cSHerbert Xu 	/* assoclen + cryptlen = seqoutlen */
373ae4a825fSHoria Geanta 	append_math_sub(desc, REG2, SEQOUTLEN, REG0, CAAM_CMD_SZ);
374ae4a825fSHoria Geanta 
375479bcc7cSHerbert Xu 	/* Prepare to read and write cryptlen + assoclen bytes */
376ae4a825fSHoria Geanta 	append_math_add(desc, VARSEQINLEN, ZERO, REG2, CAAM_CMD_SZ);
377ae4a825fSHoria Geanta 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG2, CAAM_CMD_SZ);
378ae4a825fSHoria Geanta 
379ae4a825fSHoria Geanta 	/*
380ae4a825fSHoria Geanta 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
381ae4a825fSHoria Geanta 	 * thus need to do some magic, i.e. self-patch the descriptor
382ae4a825fSHoria Geanta 	 * buffer.
383ae4a825fSHoria Geanta 	 */
384ae4a825fSHoria Geanta 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
385ae4a825fSHoria Geanta 				    MOVE_DEST_MATH2 |
386ae4a825fSHoria Geanta 				    (0x6 << MOVE_LEN_SHIFT));
387ae4a825fSHoria Geanta 	write_move_cmd = append_move(desc, MOVE_SRC_MATH2 |
388ae4a825fSHoria Geanta 				     MOVE_DEST_DESCBUF |
389ae4a825fSHoria Geanta 				     MOVE_WAITCOMP |
390ae4a825fSHoria Geanta 				     (0x8 << MOVE_LEN_SHIFT));
391ae4a825fSHoria Geanta 
392ae4a825fSHoria Geanta 	/* Read and write cryptlen bytes */
393ae4a825fSHoria Geanta 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
394ae4a825fSHoria Geanta 
395ae4a825fSHoria Geanta 	/*
396ae4a825fSHoria Geanta 	 * Insert a NOP here, since we need at least 4 instructions between
397ae4a825fSHoria Geanta 	 * code patching the descriptor buffer and the location being patched.
398ae4a825fSHoria Geanta 	 */
399ae4a825fSHoria Geanta 	jump_cmd = append_jump(desc, JUMP_TEST_ALL);
400ae4a825fSHoria Geanta 	set_jump_tgt_here(desc, jump_cmd);
401ae4a825fSHoria Geanta 
402ae4a825fSHoria Geanta 	set_move_tgt_here(desc, read_move_cmd);
403ae4a825fSHoria Geanta 	set_move_tgt_here(desc, write_move_cmd);
404ae4a825fSHoria Geanta 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
405ae4a825fSHoria Geanta 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
406ae4a825fSHoria Geanta 		    MOVE_AUX_LS);
407ae4a825fSHoria Geanta 	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
408ae4a825fSHoria Geanta 
409ae4a825fSHoria Geanta 	/* Load ICV */
410ae4a825fSHoria Geanta 	append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS2 |
411ae4a825fSHoria Geanta 			     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
412ae4a825fSHoria Geanta 
413ae4a825fSHoria Geanta 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
414ae4a825fSHoria Geanta 					      desc_bytes(desc),
415ae4a825fSHoria Geanta 					      DMA_TO_DEVICE);
416ae4a825fSHoria Geanta 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
417ae4a825fSHoria Geanta 		dev_err(jrdev, "unable to map shared descriptor\n");
418ae4a825fSHoria Geanta 		return -ENOMEM;
419ae4a825fSHoria Geanta 	}
420ae4a825fSHoria Geanta #ifdef DEBUG
421ae4a825fSHoria Geanta 	print_hex_dump(KERN_ERR,
422ae4a825fSHoria Geanta 		       "aead null dec shdesc@"__stringify(__LINE__)": ",
423ae4a825fSHoria Geanta 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
424ae4a825fSHoria Geanta 		       desc_bytes(desc), 1);
425ae4a825fSHoria Geanta #endif
426ae4a825fSHoria Geanta 
427ae4a825fSHoria Geanta 	return 0;
428ae4a825fSHoria Geanta }
429ae4a825fSHoria Geanta 
4301acebad3SYuan Kang static int aead_set_sh_desc(struct crypto_aead *aead)
4311acebad3SYuan Kang {
432479bcc7cSHerbert Xu 	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
433479bcc7cSHerbert Xu 						 struct caam_aead_alg, aead);
434add86d55SHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
4351acebad3SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
4361acebad3SYuan Kang 	struct device *jrdev = ctx->jrdev;
437daebc465SCatalin Vasile 	bool keys_fit_inline;
4381acebad3SYuan Kang 	u32 geniv, moveiv;
439daebc465SCatalin Vasile 	u32 ctx1_iv_off = 0;
4401acebad3SYuan Kang 	u32 *desc;
441daebc465SCatalin Vasile 	const bool ctr_mode = ((ctx->class1_alg_type & OP_ALG_AAI_MASK) ==
442daebc465SCatalin Vasile 			       OP_ALG_AAI_CTR_MOD128);
443479bcc7cSHerbert Xu 	const bool is_rfc3686 = alg->caam.rfc3686;
4441acebad3SYuan Kang 
4452fdea258SHoria Geantă 	if (!ctx->authsize)
4462fdea258SHoria Geantă 		return 0;
4472fdea258SHoria Geantă 
448ae4a825fSHoria Geanta 	/* NULL encryption / decryption */
449ae4a825fSHoria Geanta 	if (!ctx->enckeylen)
450ae4a825fSHoria Geanta 		return aead_null_set_sh_desc(aead);
451ae4a825fSHoria Geanta 
4521acebad3SYuan Kang 	/*
453daebc465SCatalin Vasile 	 * AES-CTR needs to load IV in CONTEXT1 reg
454daebc465SCatalin Vasile 	 * at an offset of 128bits (16bytes)
455daebc465SCatalin Vasile 	 * CONTEXT1[255:128] = IV
456daebc465SCatalin Vasile 	 */
457daebc465SCatalin Vasile 	if (ctr_mode)
458daebc465SCatalin Vasile 		ctx1_iv_off = 16;
459daebc465SCatalin Vasile 
460daebc465SCatalin Vasile 	/*
461daebc465SCatalin Vasile 	 * RFC3686 specific:
462daebc465SCatalin Vasile 	 *	CONTEXT1[255:128] = {NONCE, IV, COUNTER}
463daebc465SCatalin Vasile 	 */
464daebc465SCatalin Vasile 	if (is_rfc3686)
465daebc465SCatalin Vasile 		ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
466daebc465SCatalin Vasile 
467479bcc7cSHerbert Xu 	if (alg->caam.geniv)
468479bcc7cSHerbert Xu 		goto skip_enc;
469479bcc7cSHerbert Xu 
470daebc465SCatalin Vasile 	/*
4711acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
4721acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
4731acebad3SYuan Kang 	 */
474daebc465SCatalin Vasile 	keys_fit_inline = false;
475479bcc7cSHerbert Xu 	if (DESC_AEAD_ENC_LEN + AUTHENC_DESC_JOB_IO_LEN +
476daebc465SCatalin Vasile 	    ctx->split_key_pad_len + ctx->enckeylen +
477daebc465SCatalin Vasile 	    (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0) <=
4781acebad3SYuan Kang 	    CAAM_DESC_BYTES_MAX)
4792af8f4a2SKim Phillips 		keys_fit_inline = true;
4801acebad3SYuan Kang 
481479bcc7cSHerbert Xu 	/* aead_encrypt shared descriptor */
4821acebad3SYuan Kang 	desc = ctx->sh_desc_enc;
4831acebad3SYuan Kang 
484daebc465SCatalin Vasile 	/* Note: Context registers are saved. */
485daebc465SCatalin Vasile 	init_sh_desc_key_aead(desc, ctx, keys_fit_inline, is_rfc3686);
4861acebad3SYuan Kang 
4871acebad3SYuan Kang 	/* Class 2 operation */
4881acebad3SYuan Kang 	append_operation(desc, ctx->class2_alg_type |
4891acebad3SYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
4901acebad3SYuan Kang 
491479bcc7cSHerbert Xu 	/* Read and write assoclen bytes */
492479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
493479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
4941acebad3SYuan Kang 
495479bcc7cSHerbert Xu 	/* Skip assoc data */
496479bcc7cSHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
4971acebad3SYuan Kang 
4981acebad3SYuan Kang 	/* read assoc before reading payload */
4991acebad3SYuan Kang 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
500479bcc7cSHerbert Xu 				      FIFOLDST_VLF);
501daebc465SCatalin Vasile 
502daebc465SCatalin Vasile 	/* Load Counter into CONTEXT1 reg */
503daebc465SCatalin Vasile 	if (is_rfc3686)
5045ba1c7b5SCatalin Vasile 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
505daebc465SCatalin Vasile 				     LDST_SRCDST_BYTE_CONTEXT |
506daebc465SCatalin Vasile 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
507daebc465SCatalin Vasile 				      LDST_OFFSET_SHIFT));
5081acebad3SYuan Kang 
5091acebad3SYuan Kang 	/* Class 1 operation */
5101acebad3SYuan Kang 	append_operation(desc, ctx->class1_alg_type |
5111acebad3SYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
5121acebad3SYuan Kang 
5131acebad3SYuan Kang 	/* Read and write cryptlen bytes */
514479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
515479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
5161acebad3SYuan Kang 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
5171acebad3SYuan Kang 
5181acebad3SYuan Kang 	/* Write ICV */
5191acebad3SYuan Kang 	append_seq_store(desc, ctx->authsize, LDST_CLASS_2_CCB |
5201acebad3SYuan Kang 			 LDST_SRCDST_BYTE_CONTEXT);
5211acebad3SYuan Kang 
5221acebad3SYuan Kang 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
5231acebad3SYuan Kang 					      desc_bytes(desc),
5241acebad3SYuan Kang 					      DMA_TO_DEVICE);
5251acebad3SYuan Kang 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
5261acebad3SYuan Kang 		dev_err(jrdev, "unable to map shared descriptor\n");
5271acebad3SYuan Kang 		return -ENOMEM;
5281acebad3SYuan Kang 	}
5291acebad3SYuan Kang #ifdef DEBUG
530514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead enc shdesc@"__stringify(__LINE__)": ",
5311acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
5321acebad3SYuan Kang 		       desc_bytes(desc), 1);
5331acebad3SYuan Kang #endif
5341acebad3SYuan Kang 
535479bcc7cSHerbert Xu skip_enc:
5361acebad3SYuan Kang 	/*
5371acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
5381acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
5391acebad3SYuan Kang 	 */
54080cd88f2SVakul Garg 	keys_fit_inline = false;
541479bcc7cSHerbert Xu 	if (DESC_AEAD_DEC_LEN + AUTHENC_DESC_JOB_IO_LEN +
542daebc465SCatalin Vasile 	    ctx->split_key_pad_len + ctx->enckeylen +
543daebc465SCatalin Vasile 	    (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0) <=
5441acebad3SYuan Kang 	    CAAM_DESC_BYTES_MAX)
5452af8f4a2SKim Phillips 		keys_fit_inline = true;
5461acebad3SYuan Kang 
547479bcc7cSHerbert Xu 	/* aead_decrypt shared descriptor */
5481acebad3SYuan Kang 	desc = ctx->sh_desc_dec;
5491acebad3SYuan Kang 
550daebc465SCatalin Vasile 	/* Note: Context registers are saved. */
551daebc465SCatalin Vasile 	init_sh_desc_key_aead(desc, ctx, keys_fit_inline, is_rfc3686);
5521acebad3SYuan Kang 
5531acebad3SYuan Kang 	/* Class 2 operation */
5541acebad3SYuan Kang 	append_operation(desc, ctx->class2_alg_type |
5551acebad3SYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON);
5561acebad3SYuan Kang 
557479bcc7cSHerbert Xu 	/* Read and write assoclen bytes */
558479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
559479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
560479bcc7cSHerbert Xu 
561479bcc7cSHerbert Xu 	/* Skip assoc data */
562479bcc7cSHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
5631acebad3SYuan Kang 
5641acebad3SYuan Kang 	/* read assoc before reading payload */
5651acebad3SYuan Kang 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
5661acebad3SYuan Kang 			     KEY_VLF);
5671acebad3SYuan Kang 
568daebc465SCatalin Vasile 	/* Load Counter into CONTEXT1 reg */
569daebc465SCatalin Vasile 	if (is_rfc3686)
5705ba1c7b5SCatalin Vasile 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
571daebc465SCatalin Vasile 				     LDST_SRCDST_BYTE_CONTEXT |
572daebc465SCatalin Vasile 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
573daebc465SCatalin Vasile 				      LDST_OFFSET_SHIFT));
574daebc465SCatalin Vasile 
575daebc465SCatalin Vasile 	/* Choose operation */
576daebc465SCatalin Vasile 	if (ctr_mode)
577daebc465SCatalin Vasile 		append_operation(desc, ctx->class1_alg_type |
578daebc465SCatalin Vasile 				 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT);
579daebc465SCatalin Vasile 	else
5801acebad3SYuan Kang 		append_dec_op1(desc, ctx->class1_alg_type);
5811acebad3SYuan Kang 
5821acebad3SYuan Kang 	/* Read and write cryptlen bytes */
583479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
584479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
5851acebad3SYuan Kang 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
5861acebad3SYuan Kang 
5871acebad3SYuan Kang 	/* Load ICV */
5881acebad3SYuan Kang 	append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS2 |
5891acebad3SYuan Kang 			     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
5901acebad3SYuan Kang 
5911acebad3SYuan Kang 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
5921acebad3SYuan Kang 					      desc_bytes(desc),
5931acebad3SYuan Kang 					      DMA_TO_DEVICE);
5941acebad3SYuan Kang 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
5951acebad3SYuan Kang 		dev_err(jrdev, "unable to map shared descriptor\n");
5961acebad3SYuan Kang 		return -ENOMEM;
5971acebad3SYuan Kang 	}
5981acebad3SYuan Kang #ifdef DEBUG
599514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead dec shdesc@"__stringify(__LINE__)": ",
6001acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
6011acebad3SYuan Kang 		       desc_bytes(desc), 1);
6021acebad3SYuan Kang #endif
6031acebad3SYuan Kang 
604479bcc7cSHerbert Xu 	if (!alg->caam.geniv)
605479bcc7cSHerbert Xu 		goto skip_givenc;
606479bcc7cSHerbert Xu 
6071acebad3SYuan Kang 	/*
6081acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
6091acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
6101acebad3SYuan Kang 	 */
61180cd88f2SVakul Garg 	keys_fit_inline = false;
612479bcc7cSHerbert Xu 	if (DESC_AEAD_GIVENC_LEN + AUTHENC_DESC_JOB_IO_LEN +
613daebc465SCatalin Vasile 	    ctx->split_key_pad_len + ctx->enckeylen +
614daebc465SCatalin Vasile 	    (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0) <=
6151acebad3SYuan Kang 	    CAAM_DESC_BYTES_MAX)
6162af8f4a2SKim Phillips 		keys_fit_inline = true;
6171acebad3SYuan Kang 
6181acebad3SYuan Kang 	/* aead_givencrypt shared descriptor */
6191d2d87e8SHoria Geantă 	desc = ctx->sh_desc_enc;
6201acebad3SYuan Kang 
621daebc465SCatalin Vasile 	/* Note: Context registers are saved. */
622daebc465SCatalin Vasile 	init_sh_desc_key_aead(desc, ctx, keys_fit_inline, is_rfc3686);
6231acebad3SYuan Kang 
624479bcc7cSHerbert Xu 	if (is_rfc3686)
625479bcc7cSHerbert Xu 		goto copy_iv;
626479bcc7cSHerbert Xu 
6271acebad3SYuan Kang 	/* Generate IV */
6281acebad3SYuan Kang 	geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
6291acebad3SYuan Kang 		NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 |
630add86d55SHerbert Xu 		NFIFOENTRY_PTYPE_RND | (ivsize << NFIFOENTRY_DLEN_SHIFT);
6311acebad3SYuan Kang 	append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
6321acebad3SYuan Kang 			    LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
6331acebad3SYuan Kang 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
634daebc465SCatalin Vasile 	append_move(desc, MOVE_WAITCOMP |
635daebc465SCatalin Vasile 		    MOVE_SRC_INFIFO | MOVE_DEST_CLASS1CTX |
636daebc465SCatalin Vasile 		    (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
637add86d55SHerbert Xu 		    (ivsize << MOVE_LEN_SHIFT));
6381acebad3SYuan Kang 	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
6391acebad3SYuan Kang 
640479bcc7cSHerbert Xu copy_iv:
6411acebad3SYuan Kang 	/* Copy IV to class 1 context */
642daebc465SCatalin Vasile 	append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_OUTFIFO |
643daebc465SCatalin Vasile 		    (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
644add86d55SHerbert Xu 		    (ivsize << MOVE_LEN_SHIFT));
6451acebad3SYuan Kang 
6461acebad3SYuan Kang 	/* Return to encryption */
6471acebad3SYuan Kang 	append_operation(desc, ctx->class2_alg_type |
6481acebad3SYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
6491acebad3SYuan Kang 
650479bcc7cSHerbert Xu 	/* Read and write assoclen bytes */
651479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
652479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
653479bcc7cSHerbert Xu 
6541d2d87e8SHoria Geantă 	/* ivsize + cryptlen = seqoutlen - authsize */
6551d2d87e8SHoria Geantă 	append_math_sub_imm_u32(desc, REG3, SEQOUTLEN, IMM, ctx->authsize);
6561d2d87e8SHoria Geantă 
657479bcc7cSHerbert Xu 	/* Skip assoc data */
658479bcc7cSHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
6591acebad3SYuan Kang 
6601acebad3SYuan Kang 	/* read assoc before reading payload */
6611acebad3SYuan Kang 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
6621acebad3SYuan Kang 			     KEY_VLF);
6631acebad3SYuan Kang 
664daebc465SCatalin Vasile 	/* Copy iv from outfifo to class 2 fifo */
6651acebad3SYuan Kang 	moveiv = NFIFOENTRY_STYPE_OFIFO | NFIFOENTRY_DEST_CLASS2 |
666add86d55SHerbert Xu 		 NFIFOENTRY_DTYPE_MSG | (ivsize << NFIFOENTRY_DLEN_SHIFT);
6671acebad3SYuan Kang 	append_load_imm_u32(desc, moveiv, LDST_CLASS_IND_CCB |
6681acebad3SYuan Kang 			    LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
669add86d55SHerbert Xu 	append_load_imm_u32(desc, ivsize, LDST_CLASS_2_CCB |
6701acebad3SYuan Kang 			    LDST_SRCDST_WORD_DATASZ_REG | LDST_IMM);
6711acebad3SYuan Kang 
672daebc465SCatalin Vasile 	/* Load Counter into CONTEXT1 reg */
673daebc465SCatalin Vasile 	if (is_rfc3686)
6745ba1c7b5SCatalin Vasile 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
675daebc465SCatalin Vasile 				     LDST_SRCDST_BYTE_CONTEXT |
676daebc465SCatalin Vasile 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
677daebc465SCatalin Vasile 				      LDST_OFFSET_SHIFT));
678daebc465SCatalin Vasile 
6791acebad3SYuan Kang 	/* Class 1 operation */
6801acebad3SYuan Kang 	append_operation(desc, ctx->class1_alg_type |
6811acebad3SYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
6821acebad3SYuan Kang 
6831acebad3SYuan Kang 	/* Will write ivsize + cryptlen */
6841acebad3SYuan Kang 	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
6851acebad3SYuan Kang 
6861acebad3SYuan Kang 	/* Not need to reload iv */
687add86d55SHerbert Xu 	append_seq_fifo_load(desc, ivsize,
6881acebad3SYuan Kang 			     FIFOLD_CLASS_SKIP);
6891acebad3SYuan Kang 
6901acebad3SYuan Kang 	/* Will read cryptlen */
6911acebad3SYuan Kang 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
6921acebad3SYuan Kang 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
6931acebad3SYuan Kang 
6941acebad3SYuan Kang 	/* Write ICV */
6951acebad3SYuan Kang 	append_seq_store(desc, ctx->authsize, LDST_CLASS_2_CCB |
6961acebad3SYuan Kang 			 LDST_SRCDST_BYTE_CONTEXT);
6971acebad3SYuan Kang 
698479bcc7cSHerbert Xu 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
6991acebad3SYuan Kang 					      desc_bytes(desc),
7001acebad3SYuan Kang 					      DMA_TO_DEVICE);
7011d2d87e8SHoria Geantă 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
7021acebad3SYuan Kang 		dev_err(jrdev, "unable to map shared descriptor\n");
7031acebad3SYuan Kang 		return -ENOMEM;
7041acebad3SYuan Kang 	}
7051acebad3SYuan Kang #ifdef DEBUG
706514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead givenc shdesc@"__stringify(__LINE__)": ",
7071acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
7081acebad3SYuan Kang 		       desc_bytes(desc), 1);
7091acebad3SYuan Kang #endif
7101acebad3SYuan Kang 
711479bcc7cSHerbert Xu skip_givenc:
7121acebad3SYuan Kang 	return 0;
7131acebad3SYuan Kang }
7141acebad3SYuan Kang 
7150e479300SYuan Kang static int aead_setauthsize(struct crypto_aead *authenc,
7168e8ec596SKim Phillips 				    unsigned int authsize)
7178e8ec596SKim Phillips {
7188e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
7198e8ec596SKim Phillips 
7208e8ec596SKim Phillips 	ctx->authsize = authsize;
7211acebad3SYuan Kang 	aead_set_sh_desc(authenc);
7228e8ec596SKim Phillips 
7238e8ec596SKim Phillips 	return 0;
7248e8ec596SKim Phillips }
7258e8ec596SKim Phillips 
7263ef8d945STudor Ambarus static int gcm_set_sh_desc(struct crypto_aead *aead)
7273ef8d945STudor Ambarus {
7283ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
7293ef8d945STudor Ambarus 	struct device *jrdev = ctx->jrdev;
7303ef8d945STudor Ambarus 	bool keys_fit_inline = false;
7313ef8d945STudor Ambarus 	u32 *key_jump_cmd, *zero_payload_jump_cmd,
7323ef8d945STudor Ambarus 	    *zero_assoc_jump_cmd1, *zero_assoc_jump_cmd2;
7333ef8d945STudor Ambarus 	u32 *desc;
7343ef8d945STudor Ambarus 
7353ef8d945STudor Ambarus 	if (!ctx->enckeylen || !ctx->authsize)
7363ef8d945STudor Ambarus 		return 0;
7373ef8d945STudor Ambarus 
7383ef8d945STudor Ambarus 	/*
7393ef8d945STudor Ambarus 	 * AES GCM encrypt shared descriptor
7403ef8d945STudor Ambarus 	 * Job Descriptor and Shared Descriptor
7413ef8d945STudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
7423ef8d945STudor Ambarus 	 */
743f2147b88SHerbert Xu 	if (DESC_GCM_ENC_LEN + GCM_DESC_JOB_IO_LEN +
7443ef8d945STudor Ambarus 	    ctx->enckeylen <= CAAM_DESC_BYTES_MAX)
7453ef8d945STudor Ambarus 		keys_fit_inline = true;
7463ef8d945STudor Ambarus 
7473ef8d945STudor Ambarus 	desc = ctx->sh_desc_enc;
7483ef8d945STudor Ambarus 
7493ef8d945STudor Ambarus 	init_sh_desc(desc, HDR_SHARE_SERIAL);
7503ef8d945STudor Ambarus 
7513ef8d945STudor Ambarus 	/* skip key loading if they are loaded due to sharing */
7523ef8d945STudor Ambarus 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
7533ef8d945STudor Ambarus 				   JUMP_COND_SHRD | JUMP_COND_SELF);
7543ef8d945STudor Ambarus 	if (keys_fit_inline)
7553ef8d945STudor Ambarus 		append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
7563ef8d945STudor Ambarus 				  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
7573ef8d945STudor Ambarus 	else
7583ef8d945STudor Ambarus 		append_key(desc, ctx->key_dma, ctx->enckeylen,
7593ef8d945STudor Ambarus 			   CLASS_1 | KEY_DEST_CLASS_REG);
7603ef8d945STudor Ambarus 	set_jump_tgt_here(desc, key_jump_cmd);
7613ef8d945STudor Ambarus 
7623ef8d945STudor Ambarus 	/* class 1 operation */
7633ef8d945STudor Ambarus 	append_operation(desc, ctx->class1_alg_type |
7643ef8d945STudor Ambarus 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
7653ef8d945STudor Ambarus 
766f2147b88SHerbert Xu 	/* if assoclen + cryptlen is ZERO, skip to ICV write */
767f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
768f2147b88SHerbert Xu 	zero_assoc_jump_cmd2 = append_jump(desc, JUMP_TEST_ALL |
7693ef8d945STudor Ambarus 						 JUMP_COND_MATH_Z);
7703ef8d945STudor Ambarus 
7713ef8d945STudor Ambarus 	/* if assoclen is ZERO, skip reading the assoc data */
772f2147b88SHerbert Xu 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
7733ef8d945STudor Ambarus 	zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
7743ef8d945STudor Ambarus 						 JUMP_COND_MATH_Z);
7753ef8d945STudor Ambarus 
776f2147b88SHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
777f2147b88SHerbert Xu 
778f2147b88SHerbert Xu 	/* skip assoc data */
779f2147b88SHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
780f2147b88SHerbert Xu 
781f2147b88SHerbert Xu 	/* cryptlen = seqinlen - assoclen */
782f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
783f2147b88SHerbert Xu 
784f2147b88SHerbert Xu 	/* if cryptlen is ZERO jump to zero-payload commands */
785f2147b88SHerbert Xu 	zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
786f2147b88SHerbert Xu 					    JUMP_COND_MATH_Z);
787f2147b88SHerbert Xu 
7883ef8d945STudor Ambarus 	/* read assoc data */
7893ef8d945STudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
7903ef8d945STudor Ambarus 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
7913ef8d945STudor Ambarus 	set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
7923ef8d945STudor Ambarus 
793f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
7943ef8d945STudor Ambarus 
7953ef8d945STudor Ambarus 	/* write encrypted data */
7963ef8d945STudor Ambarus 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
7973ef8d945STudor Ambarus 
7983ef8d945STudor Ambarus 	/* read payload data */
7993ef8d945STudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
8003ef8d945STudor Ambarus 			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
8013ef8d945STudor Ambarus 
8023ef8d945STudor Ambarus 	/* jump the zero-payload commands */
803f2147b88SHerbert Xu 	append_jump(desc, JUMP_TEST_ALL | 2);
8043ef8d945STudor Ambarus 
8053ef8d945STudor Ambarus 	/* zero-payload commands */
8063ef8d945STudor Ambarus 	set_jump_tgt_here(desc, zero_payload_jump_cmd);
8073ef8d945STudor Ambarus 
8083ef8d945STudor Ambarus 	/* read assoc data */
8093ef8d945STudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
8103ef8d945STudor Ambarus 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
8113ef8d945STudor Ambarus 
812f2147b88SHerbert Xu 	/* There is no input data */
8133ef8d945STudor Ambarus 	set_jump_tgt_here(desc, zero_assoc_jump_cmd2);
8143ef8d945STudor Ambarus 
8153ef8d945STudor Ambarus 	/* write ICV */
8163ef8d945STudor Ambarus 	append_seq_store(desc, ctx->authsize, LDST_CLASS_1_CCB |
8173ef8d945STudor Ambarus 			 LDST_SRCDST_BYTE_CONTEXT);
8183ef8d945STudor Ambarus 
8193ef8d945STudor Ambarus 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
8203ef8d945STudor Ambarus 					      desc_bytes(desc),
8213ef8d945STudor Ambarus 					      DMA_TO_DEVICE);
8223ef8d945STudor Ambarus 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
8233ef8d945STudor Ambarus 		dev_err(jrdev, "unable to map shared descriptor\n");
8243ef8d945STudor Ambarus 		return -ENOMEM;
8253ef8d945STudor Ambarus 	}
8263ef8d945STudor Ambarus #ifdef DEBUG
8273ef8d945STudor Ambarus 	print_hex_dump(KERN_ERR, "gcm enc shdesc@"__stringify(__LINE__)": ",
8283ef8d945STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
8293ef8d945STudor Ambarus 		       desc_bytes(desc), 1);
8303ef8d945STudor Ambarus #endif
8313ef8d945STudor Ambarus 
8323ef8d945STudor Ambarus 	/*
8333ef8d945STudor Ambarus 	 * Job Descriptor and Shared Descriptors
8343ef8d945STudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
8353ef8d945STudor Ambarus 	 */
8363ef8d945STudor Ambarus 	keys_fit_inline = false;
837f2147b88SHerbert Xu 	if (DESC_GCM_DEC_LEN + GCM_DESC_JOB_IO_LEN +
8383ef8d945STudor Ambarus 	    ctx->enckeylen <= CAAM_DESC_BYTES_MAX)
8393ef8d945STudor Ambarus 		keys_fit_inline = true;
8403ef8d945STudor Ambarus 
8413ef8d945STudor Ambarus 	desc = ctx->sh_desc_dec;
8423ef8d945STudor Ambarus 
8433ef8d945STudor Ambarus 	init_sh_desc(desc, HDR_SHARE_SERIAL);
8443ef8d945STudor Ambarus 
8453ef8d945STudor Ambarus 	/* skip key loading if they are loaded due to sharing */
8463ef8d945STudor Ambarus 	key_jump_cmd = append_jump(desc, JUMP_JSL |
8473ef8d945STudor Ambarus 				   JUMP_TEST_ALL | JUMP_COND_SHRD |
8483ef8d945STudor Ambarus 				   JUMP_COND_SELF);
8493ef8d945STudor Ambarus 	if (keys_fit_inline)
8503ef8d945STudor Ambarus 		append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
8513ef8d945STudor Ambarus 				  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
8523ef8d945STudor Ambarus 	else
8533ef8d945STudor Ambarus 		append_key(desc, ctx->key_dma, ctx->enckeylen,
8543ef8d945STudor Ambarus 			   CLASS_1 | KEY_DEST_CLASS_REG);
8553ef8d945STudor Ambarus 	set_jump_tgt_here(desc, key_jump_cmd);
8563ef8d945STudor Ambarus 
8573ef8d945STudor Ambarus 	/* class 1 operation */
8583ef8d945STudor Ambarus 	append_operation(desc, ctx->class1_alg_type |
8593ef8d945STudor Ambarus 			 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON);
8603ef8d945STudor Ambarus 
861f2147b88SHerbert Xu 	/* if assoclen is ZERO, skip reading the assoc data */
862f2147b88SHerbert Xu 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
8633ef8d945STudor Ambarus 	zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
8643ef8d945STudor Ambarus 						 JUMP_COND_MATH_Z);
865f2147b88SHerbert Xu 
866f2147b88SHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
867f2147b88SHerbert Xu 
868f2147b88SHerbert Xu 	/* skip assoc data */
869f2147b88SHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
870f2147b88SHerbert Xu 
8713ef8d945STudor Ambarus 	/* read assoc data */
8723ef8d945STudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
8733ef8d945STudor Ambarus 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
874f2147b88SHerbert Xu 
8753ef8d945STudor Ambarus 	set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
8763ef8d945STudor Ambarus 
877f2147b88SHerbert Xu 	/* cryptlen = seqoutlen - assoclen */
878f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
879f2147b88SHerbert Xu 
880f2147b88SHerbert Xu 	/* jump to zero-payload command if cryptlen is zero */
881f2147b88SHerbert Xu 	zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
882f2147b88SHerbert Xu 					    JUMP_COND_MATH_Z);
883f2147b88SHerbert Xu 
884f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
8853ef8d945STudor Ambarus 
8863ef8d945STudor Ambarus 	/* store encrypted data */
8873ef8d945STudor Ambarus 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
8883ef8d945STudor Ambarus 
8893ef8d945STudor Ambarus 	/* read payload data */
8903ef8d945STudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
8913ef8d945STudor Ambarus 			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
8923ef8d945STudor Ambarus 
8933ef8d945STudor Ambarus 	/* zero-payload command */
8943ef8d945STudor Ambarus 	set_jump_tgt_here(desc, zero_payload_jump_cmd);
8953ef8d945STudor Ambarus 
8963ef8d945STudor Ambarus 	/* read ICV */
8973ef8d945STudor Ambarus 	append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS1 |
8983ef8d945STudor Ambarus 			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
8993ef8d945STudor Ambarus 
9003ef8d945STudor Ambarus 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
9013ef8d945STudor Ambarus 					      desc_bytes(desc),
9023ef8d945STudor Ambarus 					      DMA_TO_DEVICE);
9033ef8d945STudor Ambarus 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
9043ef8d945STudor Ambarus 		dev_err(jrdev, "unable to map shared descriptor\n");
9053ef8d945STudor Ambarus 		return -ENOMEM;
9063ef8d945STudor Ambarus 	}
9073ef8d945STudor Ambarus #ifdef DEBUG
9083ef8d945STudor Ambarus 	print_hex_dump(KERN_ERR, "gcm dec shdesc@"__stringify(__LINE__)": ",
9093ef8d945STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
9103ef8d945STudor Ambarus 		       desc_bytes(desc), 1);
9113ef8d945STudor Ambarus #endif
9123ef8d945STudor Ambarus 
9133ef8d945STudor Ambarus 	return 0;
9143ef8d945STudor Ambarus }
9153ef8d945STudor Ambarus 
9163ef8d945STudor Ambarus static int gcm_setauthsize(struct crypto_aead *authenc, unsigned int authsize)
9173ef8d945STudor Ambarus {
9183ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
9193ef8d945STudor Ambarus 
9203ef8d945STudor Ambarus 	ctx->authsize = authsize;
9213ef8d945STudor Ambarus 	gcm_set_sh_desc(authenc);
9223ef8d945STudor Ambarus 
9233ef8d945STudor Ambarus 	return 0;
9243ef8d945STudor Ambarus }
9253ef8d945STudor Ambarus 
926bac68f2cSTudor Ambarus static int rfc4106_set_sh_desc(struct crypto_aead *aead)
927bac68f2cSTudor Ambarus {
928bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
929bac68f2cSTudor Ambarus 	struct device *jrdev = ctx->jrdev;
930bac68f2cSTudor Ambarus 	bool keys_fit_inline = false;
931f2147b88SHerbert Xu 	u32 *key_jump_cmd;
932bac68f2cSTudor Ambarus 	u32 *desc;
933bac68f2cSTudor Ambarus 
934bac68f2cSTudor Ambarus 	if (!ctx->enckeylen || !ctx->authsize)
935bac68f2cSTudor Ambarus 		return 0;
936bac68f2cSTudor Ambarus 
937bac68f2cSTudor Ambarus 	/*
938bac68f2cSTudor Ambarus 	 * RFC4106 encrypt shared descriptor
939bac68f2cSTudor Ambarus 	 * Job Descriptor and Shared Descriptor
940bac68f2cSTudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
941bac68f2cSTudor Ambarus 	 */
942f2147b88SHerbert Xu 	if (DESC_RFC4106_ENC_LEN + GCM_DESC_JOB_IO_LEN +
943bac68f2cSTudor Ambarus 	    ctx->enckeylen <= CAAM_DESC_BYTES_MAX)
944bac68f2cSTudor Ambarus 		keys_fit_inline = true;
945bac68f2cSTudor Ambarus 
946bac68f2cSTudor Ambarus 	desc = ctx->sh_desc_enc;
947bac68f2cSTudor Ambarus 
948bac68f2cSTudor Ambarus 	init_sh_desc(desc, HDR_SHARE_SERIAL);
949bac68f2cSTudor Ambarus 
950bac68f2cSTudor Ambarus 	/* Skip key loading if it is loaded due to sharing */
951bac68f2cSTudor Ambarus 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
952bac68f2cSTudor Ambarus 				   JUMP_COND_SHRD);
953bac68f2cSTudor Ambarus 	if (keys_fit_inline)
954bac68f2cSTudor Ambarus 		append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
955bac68f2cSTudor Ambarus 				  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
956bac68f2cSTudor Ambarus 	else
957bac68f2cSTudor Ambarus 		append_key(desc, ctx->key_dma, ctx->enckeylen,
958bac68f2cSTudor Ambarus 			   CLASS_1 | KEY_DEST_CLASS_REG);
959bac68f2cSTudor Ambarus 	set_jump_tgt_here(desc, key_jump_cmd);
960bac68f2cSTudor Ambarus 
961bac68f2cSTudor Ambarus 	/* Class 1 operation */
962bac68f2cSTudor Ambarus 	append_operation(desc, ctx->class1_alg_type |
963bac68f2cSTudor Ambarus 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
964bac68f2cSTudor Ambarus 
96546218750SHerbert Xu 	append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, 8);
966bac68f2cSTudor Ambarus 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
967bac68f2cSTudor Ambarus 
968bac68f2cSTudor Ambarus 	/* Read assoc data */
969bac68f2cSTudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
970bac68f2cSTudor Ambarus 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
971bac68f2cSTudor Ambarus 
97246218750SHerbert Xu 	/* Skip IV */
97346218750SHerbert Xu 	append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
974f2147b88SHerbert Xu 
975bac68f2cSTudor Ambarus 	/* Will read cryptlen bytes */
976f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
977bac68f2cSTudor Ambarus 
9784aad0cc5SHoria Geant? 	/* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
9794aad0cc5SHoria Geant? 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG);
980bac68f2cSTudor Ambarus 
98146218750SHerbert Xu 	/* Skip assoc data */
98246218750SHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
98346218750SHerbert Xu 
98446218750SHerbert Xu 	/* cryptlen = seqoutlen - assoclen */
9854aad0cc5SHoria Geant? 	append_math_sub(desc, VARSEQOUTLEN, VARSEQINLEN, REG0, CAAM_CMD_SZ);
98646218750SHerbert Xu 
98746218750SHerbert Xu 	/* Write encrypted data */
98846218750SHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
98946218750SHerbert Xu 
9904aad0cc5SHoria Geant? 	/* Read payload data */
9914aad0cc5SHoria Geant? 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
9924aad0cc5SHoria Geant? 			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
9934aad0cc5SHoria Geant? 
994bac68f2cSTudor Ambarus 	/* Write ICV */
995bac68f2cSTudor Ambarus 	append_seq_store(desc, ctx->authsize, LDST_CLASS_1_CCB |
996bac68f2cSTudor Ambarus 			 LDST_SRCDST_BYTE_CONTEXT);
997bac68f2cSTudor Ambarus 
998bac68f2cSTudor Ambarus 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
999bac68f2cSTudor Ambarus 					      desc_bytes(desc),
1000bac68f2cSTudor Ambarus 					      DMA_TO_DEVICE);
1001bac68f2cSTudor Ambarus 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
1002bac68f2cSTudor Ambarus 		dev_err(jrdev, "unable to map shared descriptor\n");
1003bac68f2cSTudor Ambarus 		return -ENOMEM;
1004bac68f2cSTudor Ambarus 	}
1005bac68f2cSTudor Ambarus #ifdef DEBUG
1006bac68f2cSTudor Ambarus 	print_hex_dump(KERN_ERR, "rfc4106 enc shdesc@"__stringify(__LINE__)": ",
1007bac68f2cSTudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
1008bac68f2cSTudor Ambarus 		       desc_bytes(desc), 1);
1009bac68f2cSTudor Ambarus #endif
1010bac68f2cSTudor Ambarus 
1011bac68f2cSTudor Ambarus 	/*
1012bac68f2cSTudor Ambarus 	 * Job Descriptor and Shared Descriptors
1013bac68f2cSTudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
1014bac68f2cSTudor Ambarus 	 */
1015bac68f2cSTudor Ambarus 	keys_fit_inline = false;
1016bac68f2cSTudor Ambarus 	if (DESC_RFC4106_DEC_LEN + DESC_JOB_IO_LEN +
1017bac68f2cSTudor Ambarus 	    ctx->enckeylen <= CAAM_DESC_BYTES_MAX)
1018bac68f2cSTudor Ambarus 		keys_fit_inline = true;
1019bac68f2cSTudor Ambarus 
1020bac68f2cSTudor Ambarus 	desc = ctx->sh_desc_dec;
1021bac68f2cSTudor Ambarus 
1022bac68f2cSTudor Ambarus 	init_sh_desc(desc, HDR_SHARE_SERIAL);
1023bac68f2cSTudor Ambarus 
1024bac68f2cSTudor Ambarus 	/* Skip key loading if it is loaded due to sharing */
1025bac68f2cSTudor Ambarus 	key_jump_cmd = append_jump(desc, JUMP_JSL |
1026bac68f2cSTudor Ambarus 				   JUMP_TEST_ALL | JUMP_COND_SHRD);
1027bac68f2cSTudor Ambarus 	if (keys_fit_inline)
1028bac68f2cSTudor Ambarus 		append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
1029bac68f2cSTudor Ambarus 				  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
1030bac68f2cSTudor Ambarus 	else
1031bac68f2cSTudor Ambarus 		append_key(desc, ctx->key_dma, ctx->enckeylen,
1032bac68f2cSTudor Ambarus 			   CLASS_1 | KEY_DEST_CLASS_REG);
1033bac68f2cSTudor Ambarus 	set_jump_tgt_here(desc, key_jump_cmd);
1034bac68f2cSTudor Ambarus 
1035bac68f2cSTudor Ambarus 	/* Class 1 operation */
1036bac68f2cSTudor Ambarus 	append_operation(desc, ctx->class1_alg_type |
1037bac68f2cSTudor Ambarus 			 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON);
1038bac68f2cSTudor Ambarus 
103946218750SHerbert Xu 	append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, 8);
1040f2147b88SHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
1041bac68f2cSTudor Ambarus 
1042bac68f2cSTudor Ambarus 	/* Read assoc data */
1043bac68f2cSTudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
1044bac68f2cSTudor Ambarus 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
1045bac68f2cSTudor Ambarus 
104646218750SHerbert Xu 	/* Skip IV */
104746218750SHerbert Xu 	append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
1048f2147b88SHerbert Xu 
1049bac68f2cSTudor Ambarus 	/* Will read cryptlen bytes */
105046218750SHerbert Xu 	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG3, CAAM_CMD_SZ);
1051bac68f2cSTudor Ambarus 
10524aad0cc5SHoria Geant? 	/* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
10534aad0cc5SHoria Geant? 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG);
1054bac68f2cSTudor Ambarus 
105546218750SHerbert Xu 	/* Skip assoc data */
105646218750SHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
105746218750SHerbert Xu 
105846218750SHerbert Xu 	/* Will write cryptlen bytes */
105946218750SHerbert Xu 	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
106046218750SHerbert Xu 
106146218750SHerbert Xu 	/* Store payload data */
106246218750SHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
106346218750SHerbert Xu 
10644aad0cc5SHoria Geant? 	/* Read encrypted data */
10654aad0cc5SHoria Geant? 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
10664aad0cc5SHoria Geant? 			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
10674aad0cc5SHoria Geant? 
1068bac68f2cSTudor Ambarus 	/* Read ICV */
1069bac68f2cSTudor Ambarus 	append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS1 |
1070bac68f2cSTudor Ambarus 			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
1071bac68f2cSTudor Ambarus 
1072bac68f2cSTudor Ambarus 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
1073bac68f2cSTudor Ambarus 					      desc_bytes(desc),
1074bac68f2cSTudor Ambarus 					      DMA_TO_DEVICE);
1075bac68f2cSTudor Ambarus 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
1076bac68f2cSTudor Ambarus 		dev_err(jrdev, "unable to map shared descriptor\n");
1077bac68f2cSTudor Ambarus 		return -ENOMEM;
1078bac68f2cSTudor Ambarus 	}
1079bac68f2cSTudor Ambarus #ifdef DEBUG
1080bac68f2cSTudor Ambarus 	print_hex_dump(KERN_ERR, "rfc4106 dec shdesc@"__stringify(__LINE__)": ",
1081bac68f2cSTudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
1082bac68f2cSTudor Ambarus 		       desc_bytes(desc), 1);
1083bac68f2cSTudor Ambarus #endif
1084bac68f2cSTudor Ambarus 
1085bac68f2cSTudor Ambarus 	return 0;
1086bac68f2cSTudor Ambarus }
1087bac68f2cSTudor Ambarus 
1088bac68f2cSTudor Ambarus static int rfc4106_setauthsize(struct crypto_aead *authenc,
1089bac68f2cSTudor Ambarus 			       unsigned int authsize)
1090bac68f2cSTudor Ambarus {
1091bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
1092bac68f2cSTudor Ambarus 
1093bac68f2cSTudor Ambarus 	ctx->authsize = authsize;
1094bac68f2cSTudor Ambarus 	rfc4106_set_sh_desc(authenc);
1095bac68f2cSTudor Ambarus 
1096bac68f2cSTudor Ambarus 	return 0;
1097bac68f2cSTudor Ambarus }
1098bac68f2cSTudor Ambarus 
10995d0429a3STudor Ambarus static int rfc4543_set_sh_desc(struct crypto_aead *aead)
11005d0429a3STudor Ambarus {
11015d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
11025d0429a3STudor Ambarus 	struct device *jrdev = ctx->jrdev;
11035d0429a3STudor Ambarus 	bool keys_fit_inline = false;
1104f2147b88SHerbert Xu 	u32 *key_jump_cmd;
11055d0429a3STudor Ambarus 	u32 *read_move_cmd, *write_move_cmd;
11065d0429a3STudor Ambarus 	u32 *desc;
11075d0429a3STudor Ambarus 
11085d0429a3STudor Ambarus 	if (!ctx->enckeylen || !ctx->authsize)
11095d0429a3STudor Ambarus 		return 0;
11105d0429a3STudor Ambarus 
11115d0429a3STudor Ambarus 	/*
11125d0429a3STudor Ambarus 	 * RFC4543 encrypt shared descriptor
11135d0429a3STudor Ambarus 	 * Job Descriptor and Shared Descriptor
11145d0429a3STudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
11155d0429a3STudor Ambarus 	 */
1116f2147b88SHerbert Xu 	if (DESC_RFC4543_ENC_LEN + GCM_DESC_JOB_IO_LEN +
11175d0429a3STudor Ambarus 	    ctx->enckeylen <= CAAM_DESC_BYTES_MAX)
11185d0429a3STudor Ambarus 		keys_fit_inline = true;
11195d0429a3STudor Ambarus 
11205d0429a3STudor Ambarus 	desc = ctx->sh_desc_enc;
11215d0429a3STudor Ambarus 
11225d0429a3STudor Ambarus 	init_sh_desc(desc, HDR_SHARE_SERIAL);
11235d0429a3STudor Ambarus 
11245d0429a3STudor Ambarus 	/* Skip key loading if it is loaded due to sharing */
11255d0429a3STudor Ambarus 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
11265d0429a3STudor Ambarus 				   JUMP_COND_SHRD);
11275d0429a3STudor Ambarus 	if (keys_fit_inline)
11285d0429a3STudor Ambarus 		append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
11295d0429a3STudor Ambarus 				  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
11305d0429a3STudor Ambarus 	else
11315d0429a3STudor Ambarus 		append_key(desc, ctx->key_dma, ctx->enckeylen,
11325d0429a3STudor Ambarus 			   CLASS_1 | KEY_DEST_CLASS_REG);
11335d0429a3STudor Ambarus 	set_jump_tgt_here(desc, key_jump_cmd);
11345d0429a3STudor Ambarus 
11355d0429a3STudor Ambarus 	/* Class 1 operation */
11365d0429a3STudor Ambarus 	append_operation(desc, ctx->class1_alg_type |
11375d0429a3STudor Ambarus 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
11385d0429a3STudor Ambarus 
1139f2147b88SHerbert Xu 	/* assoclen + cryptlen = seqinlen */
1140f2147b88SHerbert Xu 	append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
11415d0429a3STudor Ambarus 
11425d0429a3STudor Ambarus 	/*
11435d0429a3STudor Ambarus 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
11445d0429a3STudor Ambarus 	 * thus need to do some magic, i.e. self-patch the descriptor
11455d0429a3STudor Ambarus 	 * buffer.
11465d0429a3STudor Ambarus 	 */
11475d0429a3STudor Ambarus 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
11485d0429a3STudor Ambarus 				    (0x6 << MOVE_LEN_SHIFT));
11495d0429a3STudor Ambarus 	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
11505d0429a3STudor Ambarus 				     (0x8 << MOVE_LEN_SHIFT));
11515d0429a3STudor Ambarus 
1152f2147b88SHerbert Xu 	/* Will read assoclen + cryptlen bytes */
1153f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
11545d0429a3STudor Ambarus 
1155f2147b88SHerbert Xu 	/* Will write assoclen + cryptlen bytes */
1156f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1157f2147b88SHerbert Xu 
1158f2147b88SHerbert Xu 	/* Read and write assoclen + cryptlen bytes */
11595d0429a3STudor Ambarus 	aead_append_src_dst(desc, FIFOLD_TYPE_AAD);
11605d0429a3STudor Ambarus 
11615d0429a3STudor Ambarus 	set_move_tgt_here(desc, read_move_cmd);
11625d0429a3STudor Ambarus 	set_move_tgt_here(desc, write_move_cmd);
11635d0429a3STudor Ambarus 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
11645d0429a3STudor Ambarus 	/* Move payload data to OFIFO */
11655d0429a3STudor Ambarus 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
11665d0429a3STudor Ambarus 
11675d0429a3STudor Ambarus 	/* Write ICV */
11685d0429a3STudor Ambarus 	append_seq_store(desc, ctx->authsize, LDST_CLASS_1_CCB |
11695d0429a3STudor Ambarus 			 LDST_SRCDST_BYTE_CONTEXT);
11705d0429a3STudor Ambarus 
11715d0429a3STudor Ambarus 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
11725d0429a3STudor Ambarus 					      desc_bytes(desc),
11735d0429a3STudor Ambarus 					      DMA_TO_DEVICE);
11745d0429a3STudor Ambarus 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
11755d0429a3STudor Ambarus 		dev_err(jrdev, "unable to map shared descriptor\n");
11765d0429a3STudor Ambarus 		return -ENOMEM;
11775d0429a3STudor Ambarus 	}
11785d0429a3STudor Ambarus #ifdef DEBUG
11795d0429a3STudor Ambarus 	print_hex_dump(KERN_ERR, "rfc4543 enc shdesc@"__stringify(__LINE__)": ",
11805d0429a3STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
11815d0429a3STudor Ambarus 		       desc_bytes(desc), 1);
11825d0429a3STudor Ambarus #endif
11835d0429a3STudor Ambarus 
11845d0429a3STudor Ambarus 	/*
11855d0429a3STudor Ambarus 	 * Job Descriptor and Shared Descriptors
11865d0429a3STudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
11875d0429a3STudor Ambarus 	 */
11885d0429a3STudor Ambarus 	keys_fit_inline = false;
1189f2147b88SHerbert Xu 	if (DESC_RFC4543_DEC_LEN + GCM_DESC_JOB_IO_LEN +
11905d0429a3STudor Ambarus 	    ctx->enckeylen <= CAAM_DESC_BYTES_MAX)
11915d0429a3STudor Ambarus 		keys_fit_inline = true;
11925d0429a3STudor Ambarus 
11935d0429a3STudor Ambarus 	desc = ctx->sh_desc_dec;
11945d0429a3STudor Ambarus 
11955d0429a3STudor Ambarus 	init_sh_desc(desc, HDR_SHARE_SERIAL);
11965d0429a3STudor Ambarus 
11975d0429a3STudor Ambarus 	/* Skip key loading if it is loaded due to sharing */
11985d0429a3STudor Ambarus 	key_jump_cmd = append_jump(desc, JUMP_JSL |
11995d0429a3STudor Ambarus 				   JUMP_TEST_ALL | JUMP_COND_SHRD);
12005d0429a3STudor Ambarus 	if (keys_fit_inline)
12015d0429a3STudor Ambarus 		append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
12025d0429a3STudor Ambarus 				  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
12035d0429a3STudor Ambarus 	else
12045d0429a3STudor Ambarus 		append_key(desc, ctx->key_dma, ctx->enckeylen,
12055d0429a3STudor Ambarus 			   CLASS_1 | KEY_DEST_CLASS_REG);
12065d0429a3STudor Ambarus 	set_jump_tgt_here(desc, key_jump_cmd);
12075d0429a3STudor Ambarus 
12085d0429a3STudor Ambarus 	/* Class 1 operation */
12095d0429a3STudor Ambarus 	append_operation(desc, ctx->class1_alg_type |
12105d0429a3STudor Ambarus 			 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON);
12115d0429a3STudor Ambarus 
1212f2147b88SHerbert Xu 	/* assoclen + cryptlen = seqoutlen */
1213f2147b88SHerbert Xu 	append_math_sub(desc, REG3, SEQOUTLEN, REG0, CAAM_CMD_SZ);
12145d0429a3STudor Ambarus 
12155d0429a3STudor Ambarus 	/*
12165d0429a3STudor Ambarus 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
12175d0429a3STudor Ambarus 	 * thus need to do some magic, i.e. self-patch the descriptor
12185d0429a3STudor Ambarus 	 * buffer.
12195d0429a3STudor Ambarus 	 */
12205d0429a3STudor Ambarus 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
12215d0429a3STudor Ambarus 				    (0x6 << MOVE_LEN_SHIFT));
12225d0429a3STudor Ambarus 	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
12235d0429a3STudor Ambarus 				     (0x8 << MOVE_LEN_SHIFT));
12245d0429a3STudor Ambarus 
1225f2147b88SHerbert Xu 	/* Will read assoclen + cryptlen bytes */
1226f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
12275d0429a3STudor Ambarus 
1228f2147b88SHerbert Xu 	/* Will write assoclen + cryptlen bytes */
1229f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
12305d0429a3STudor Ambarus 
12315d0429a3STudor Ambarus 	/* Store payload data */
12325d0429a3STudor Ambarus 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
12335d0429a3STudor Ambarus 
1234f2147b88SHerbert Xu 	/* In-snoop assoclen + cryptlen data */
12355d0429a3STudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | FIFOLDST_VLF |
12365d0429a3STudor Ambarus 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST2FLUSH1);
12375d0429a3STudor Ambarus 
12385d0429a3STudor Ambarus 	set_move_tgt_here(desc, read_move_cmd);
12395d0429a3STudor Ambarus 	set_move_tgt_here(desc, write_move_cmd);
12405d0429a3STudor Ambarus 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
12415d0429a3STudor Ambarus 	/* Move payload data to OFIFO */
12425d0429a3STudor Ambarus 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
12435d0429a3STudor Ambarus 	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
12445d0429a3STudor Ambarus 
12455d0429a3STudor Ambarus 	/* Read ICV */
12465d0429a3STudor Ambarus 	append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS1 |
12475d0429a3STudor Ambarus 			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
12485d0429a3STudor Ambarus 
12495d0429a3STudor Ambarus 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
12505d0429a3STudor Ambarus 					      desc_bytes(desc),
12515d0429a3STudor Ambarus 					      DMA_TO_DEVICE);
12525d0429a3STudor Ambarus 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
12535d0429a3STudor Ambarus 		dev_err(jrdev, "unable to map shared descriptor\n");
12545d0429a3STudor Ambarus 		return -ENOMEM;
12555d0429a3STudor Ambarus 	}
12565d0429a3STudor Ambarus #ifdef DEBUG
12575d0429a3STudor Ambarus 	print_hex_dump(KERN_ERR, "rfc4543 dec shdesc@"__stringify(__LINE__)": ",
12585d0429a3STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
12595d0429a3STudor Ambarus 		       desc_bytes(desc), 1);
12605d0429a3STudor Ambarus #endif
12615d0429a3STudor Ambarus 
12625d0429a3STudor Ambarus 	return 0;
12635d0429a3STudor Ambarus }
12645d0429a3STudor Ambarus 
12655d0429a3STudor Ambarus static int rfc4543_setauthsize(struct crypto_aead *authenc,
12665d0429a3STudor Ambarus 			       unsigned int authsize)
12675d0429a3STudor Ambarus {
12685d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
12695d0429a3STudor Ambarus 
12705d0429a3STudor Ambarus 	ctx->authsize = authsize;
12715d0429a3STudor Ambarus 	rfc4543_set_sh_desc(authenc);
12725d0429a3STudor Ambarus 
12735d0429a3STudor Ambarus 	return 0;
12745d0429a3STudor Ambarus }
12755d0429a3STudor Ambarus 
12764c1ec1f9SYuan Kang static u32 gen_split_aead_key(struct caam_ctx *ctx, const u8 *key_in,
12774c1ec1f9SYuan Kang 			      u32 authkeylen)
12788e8ec596SKim Phillips {
12794c1ec1f9SYuan Kang 	return gen_split_key(ctx->jrdev, ctx->key, ctx->split_key_len,
12804c1ec1f9SYuan Kang 			       ctx->split_key_pad_len, key_in, authkeylen,
12814c1ec1f9SYuan Kang 			       ctx->alg_op);
12828e8ec596SKim Phillips }
12838e8ec596SKim Phillips 
12840e479300SYuan Kang static int aead_setkey(struct crypto_aead *aead,
12858e8ec596SKim Phillips 			       const u8 *key, unsigned int keylen)
12868e8ec596SKim Phillips {
12878e8ec596SKim Phillips 	/* Sizes for MDHA pads (*not* keys): MD5, SHA1, 224, 256, 384, 512 */
12888e8ec596SKim Phillips 	static const u8 mdpadlen[] = { 16, 20, 32, 32, 64, 64 };
12898e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
12908e8ec596SKim Phillips 	struct device *jrdev = ctx->jrdev;
12914e6e0b27SHoria Geanta 	struct crypto_authenc_keys keys;
12928e8ec596SKim Phillips 	int ret = 0;
12938e8ec596SKim Phillips 
12944e6e0b27SHoria Geanta 	if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
12958e8ec596SKim Phillips 		goto badkey;
12968e8ec596SKim Phillips 
12978e8ec596SKim Phillips 	/* Pick class 2 key length from algorithm submask */
12988e8ec596SKim Phillips 	ctx->split_key_len = mdpadlen[(ctx->alg_op & OP_ALG_ALGSEL_SUBMASK) >>
12998e8ec596SKim Phillips 				      OP_ALG_ALGSEL_SHIFT] * 2;
13008e8ec596SKim Phillips 	ctx->split_key_pad_len = ALIGN(ctx->split_key_len, 16);
13018e8ec596SKim Phillips 
13024e6e0b27SHoria Geanta 	if (ctx->split_key_pad_len + keys.enckeylen > CAAM_MAX_KEY_SIZE)
13034e6e0b27SHoria Geanta 		goto badkey;
13044e6e0b27SHoria Geanta 
13058e8ec596SKim Phillips #ifdef DEBUG
13068e8ec596SKim Phillips 	printk(KERN_ERR "keylen %d enckeylen %d authkeylen %d\n",
13074e6e0b27SHoria Geanta 	       keys.authkeylen + keys.enckeylen, keys.enckeylen,
13084e6e0b27SHoria Geanta 	       keys.authkeylen);
13098e8ec596SKim Phillips 	printk(KERN_ERR "split_key_len %d split_key_pad_len %d\n",
13108e8ec596SKim Phillips 	       ctx->split_key_len, ctx->split_key_pad_len);
1311514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
13128e8ec596SKim Phillips 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
13138e8ec596SKim Phillips #endif
13148e8ec596SKim Phillips 
13154e6e0b27SHoria Geanta 	ret = gen_split_aead_key(ctx, keys.authkey, keys.authkeylen);
13168e8ec596SKim Phillips 	if (ret) {
13178e8ec596SKim Phillips 		goto badkey;
13188e8ec596SKim Phillips 	}
13198e8ec596SKim Phillips 
13208e8ec596SKim Phillips 	/* postpend encryption key to auth split key */
13214e6e0b27SHoria Geanta 	memcpy(ctx->key + ctx->split_key_pad_len, keys.enckey, keys.enckeylen);
13228e8ec596SKim Phillips 
1323885e9e2fSYuan Kang 	ctx->key_dma = dma_map_single(jrdev, ctx->key, ctx->split_key_pad_len +
13244e6e0b27SHoria Geanta 				      keys.enckeylen, DMA_TO_DEVICE);
1325885e9e2fSYuan Kang 	if (dma_mapping_error(jrdev, ctx->key_dma)) {
13268e8ec596SKim Phillips 		dev_err(jrdev, "unable to map key i/o memory\n");
13278e8ec596SKim Phillips 		return -ENOMEM;
13288e8ec596SKim Phillips 	}
13298e8ec596SKim Phillips #ifdef DEBUG
1330514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ctx.key@"__stringify(__LINE__)": ",
13318e8ec596SKim Phillips 		       DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
13324e6e0b27SHoria Geanta 		       ctx->split_key_pad_len + keys.enckeylen, 1);
13338e8ec596SKim Phillips #endif
13348e8ec596SKim Phillips 
13354e6e0b27SHoria Geanta 	ctx->enckeylen = keys.enckeylen;
13368e8ec596SKim Phillips 
13371acebad3SYuan Kang 	ret = aead_set_sh_desc(aead);
13388e8ec596SKim Phillips 	if (ret) {
1339885e9e2fSYuan Kang 		dma_unmap_single(jrdev, ctx->key_dma, ctx->split_key_pad_len +
13404e6e0b27SHoria Geanta 				 keys.enckeylen, DMA_TO_DEVICE);
13418e8ec596SKim Phillips 	}
13428e8ec596SKim Phillips 
13438e8ec596SKim Phillips 	return ret;
13448e8ec596SKim Phillips badkey:
13458e8ec596SKim Phillips 	crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
13468e8ec596SKim Phillips 	return -EINVAL;
13478e8ec596SKim Phillips }
13488e8ec596SKim Phillips 
13493ef8d945STudor Ambarus static int gcm_setkey(struct crypto_aead *aead,
13503ef8d945STudor Ambarus 		      const u8 *key, unsigned int keylen)
13513ef8d945STudor Ambarus {
13523ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
13533ef8d945STudor Ambarus 	struct device *jrdev = ctx->jrdev;
13543ef8d945STudor Ambarus 	int ret = 0;
13553ef8d945STudor Ambarus 
13563ef8d945STudor Ambarus #ifdef DEBUG
13573ef8d945STudor Ambarus 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
13583ef8d945STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
13593ef8d945STudor Ambarus #endif
13603ef8d945STudor Ambarus 
13613ef8d945STudor Ambarus 	memcpy(ctx->key, key, keylen);
13623ef8d945STudor Ambarus 	ctx->key_dma = dma_map_single(jrdev, ctx->key, keylen,
13633ef8d945STudor Ambarus 				      DMA_TO_DEVICE);
13643ef8d945STudor Ambarus 	if (dma_mapping_error(jrdev, ctx->key_dma)) {
13653ef8d945STudor Ambarus 		dev_err(jrdev, "unable to map key i/o memory\n");
13663ef8d945STudor Ambarus 		return -ENOMEM;
13673ef8d945STudor Ambarus 	}
13683ef8d945STudor Ambarus 	ctx->enckeylen = keylen;
13693ef8d945STudor Ambarus 
13703ef8d945STudor Ambarus 	ret = gcm_set_sh_desc(aead);
13713ef8d945STudor Ambarus 	if (ret) {
13723ef8d945STudor Ambarus 		dma_unmap_single(jrdev, ctx->key_dma, ctx->enckeylen,
13733ef8d945STudor Ambarus 				 DMA_TO_DEVICE);
13743ef8d945STudor Ambarus 	}
13753ef8d945STudor Ambarus 
13763ef8d945STudor Ambarus 	return ret;
13773ef8d945STudor Ambarus }
13783ef8d945STudor Ambarus 
1379bac68f2cSTudor Ambarus static int rfc4106_setkey(struct crypto_aead *aead,
1380bac68f2cSTudor Ambarus 			  const u8 *key, unsigned int keylen)
1381bac68f2cSTudor Ambarus {
1382bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1383bac68f2cSTudor Ambarus 	struct device *jrdev = ctx->jrdev;
1384bac68f2cSTudor Ambarus 	int ret = 0;
1385bac68f2cSTudor Ambarus 
1386bac68f2cSTudor Ambarus 	if (keylen < 4)
1387bac68f2cSTudor Ambarus 		return -EINVAL;
1388bac68f2cSTudor Ambarus 
1389bac68f2cSTudor Ambarus #ifdef DEBUG
1390bac68f2cSTudor Ambarus 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
1391bac68f2cSTudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
1392bac68f2cSTudor Ambarus #endif
1393bac68f2cSTudor Ambarus 
1394bac68f2cSTudor Ambarus 	memcpy(ctx->key, key, keylen);
1395bac68f2cSTudor Ambarus 
1396bac68f2cSTudor Ambarus 	/*
1397bac68f2cSTudor Ambarus 	 * The last four bytes of the key material are used as the salt value
1398bac68f2cSTudor Ambarus 	 * in the nonce. Update the AES key length.
1399bac68f2cSTudor Ambarus 	 */
1400bac68f2cSTudor Ambarus 	ctx->enckeylen = keylen - 4;
1401bac68f2cSTudor Ambarus 
1402bac68f2cSTudor Ambarus 	ctx->key_dma = dma_map_single(jrdev, ctx->key, ctx->enckeylen,
1403bac68f2cSTudor Ambarus 				      DMA_TO_DEVICE);
1404bac68f2cSTudor Ambarus 	if (dma_mapping_error(jrdev, ctx->key_dma)) {
1405bac68f2cSTudor Ambarus 		dev_err(jrdev, "unable to map key i/o memory\n");
1406bac68f2cSTudor Ambarus 		return -ENOMEM;
1407bac68f2cSTudor Ambarus 	}
1408bac68f2cSTudor Ambarus 
1409bac68f2cSTudor Ambarus 	ret = rfc4106_set_sh_desc(aead);
1410bac68f2cSTudor Ambarus 	if (ret) {
1411bac68f2cSTudor Ambarus 		dma_unmap_single(jrdev, ctx->key_dma, ctx->enckeylen,
1412bac68f2cSTudor Ambarus 				 DMA_TO_DEVICE);
1413bac68f2cSTudor Ambarus 	}
1414bac68f2cSTudor Ambarus 
1415bac68f2cSTudor Ambarus 	return ret;
1416bac68f2cSTudor Ambarus }
1417bac68f2cSTudor Ambarus 
14185d0429a3STudor Ambarus static int rfc4543_setkey(struct crypto_aead *aead,
14195d0429a3STudor Ambarus 			  const u8 *key, unsigned int keylen)
14205d0429a3STudor Ambarus {
14215d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
14225d0429a3STudor Ambarus 	struct device *jrdev = ctx->jrdev;
14235d0429a3STudor Ambarus 	int ret = 0;
14245d0429a3STudor Ambarus 
14255d0429a3STudor Ambarus 	if (keylen < 4)
14265d0429a3STudor Ambarus 		return -EINVAL;
14275d0429a3STudor Ambarus 
14285d0429a3STudor Ambarus #ifdef DEBUG
14295d0429a3STudor Ambarus 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
14305d0429a3STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
14315d0429a3STudor Ambarus #endif
14325d0429a3STudor Ambarus 
14335d0429a3STudor Ambarus 	memcpy(ctx->key, key, keylen);
14345d0429a3STudor Ambarus 
14355d0429a3STudor Ambarus 	/*
14365d0429a3STudor Ambarus 	 * The last four bytes of the key material are used as the salt value
14375d0429a3STudor Ambarus 	 * in the nonce. Update the AES key length.
14385d0429a3STudor Ambarus 	 */
14395d0429a3STudor Ambarus 	ctx->enckeylen = keylen - 4;
14405d0429a3STudor Ambarus 
14415d0429a3STudor Ambarus 	ctx->key_dma = dma_map_single(jrdev, ctx->key, ctx->enckeylen,
14425d0429a3STudor Ambarus 				      DMA_TO_DEVICE);
14435d0429a3STudor Ambarus 	if (dma_mapping_error(jrdev, ctx->key_dma)) {
14445d0429a3STudor Ambarus 		dev_err(jrdev, "unable to map key i/o memory\n");
14455d0429a3STudor Ambarus 		return -ENOMEM;
14465d0429a3STudor Ambarus 	}
14475d0429a3STudor Ambarus 
14485d0429a3STudor Ambarus 	ret = rfc4543_set_sh_desc(aead);
14495d0429a3STudor Ambarus 	if (ret) {
14505d0429a3STudor Ambarus 		dma_unmap_single(jrdev, ctx->key_dma, ctx->enckeylen,
14515d0429a3STudor Ambarus 				 DMA_TO_DEVICE);
14525d0429a3STudor Ambarus 	}
14535d0429a3STudor Ambarus 
14545d0429a3STudor Ambarus 	return ret;
14555d0429a3STudor Ambarus }
14565d0429a3STudor Ambarus 
1457acdca31dSYuan Kang static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
1458acdca31dSYuan Kang 			     const u8 *key, unsigned int keylen)
1459acdca31dSYuan Kang {
1460acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
1461a5f57cffSCatalin Vasile 	struct ablkcipher_tfm *crt = &ablkcipher->base.crt_ablkcipher;
1462a5f57cffSCatalin Vasile 	struct crypto_tfm *tfm = crypto_ablkcipher_tfm(ablkcipher);
1463a5f57cffSCatalin Vasile 	const char *alg_name = crypto_tfm_alg_name(tfm);
1464acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
1465acdca31dSYuan Kang 	int ret = 0;
14664464a7d4SHoria Geanta 	u32 *key_jump_cmd;
1467acdca31dSYuan Kang 	u32 *desc;
14685ba1c7b5SCatalin Vasile 	u8 *nonce;
14697222d1a3SCatalin Vasile 	u32 geniv;
14702b22f6c5SCatalin Vasile 	u32 ctx1_iv_off = 0;
14712b22f6c5SCatalin Vasile 	const bool ctr_mode = ((ctx->class1_alg_type & OP_ALG_AAI_MASK) ==
14722b22f6c5SCatalin Vasile 			       OP_ALG_AAI_CTR_MOD128);
1473a5f57cffSCatalin Vasile 	const bool is_rfc3686 = (ctr_mode &&
1474a5f57cffSCatalin Vasile 				 (strstr(alg_name, "rfc3686") != NULL));
1475acdca31dSYuan Kang 
1476acdca31dSYuan Kang #ifdef DEBUG
1477514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
1478acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
1479acdca31dSYuan Kang #endif
14802b22f6c5SCatalin Vasile 	/*
14812b22f6c5SCatalin Vasile 	 * AES-CTR needs to load IV in CONTEXT1 reg
14822b22f6c5SCatalin Vasile 	 * at an offset of 128bits (16bytes)
14832b22f6c5SCatalin Vasile 	 * CONTEXT1[255:128] = IV
14842b22f6c5SCatalin Vasile 	 */
14852b22f6c5SCatalin Vasile 	if (ctr_mode)
14862b22f6c5SCatalin Vasile 		ctx1_iv_off = 16;
1487acdca31dSYuan Kang 
1488a5f57cffSCatalin Vasile 	/*
1489a5f57cffSCatalin Vasile 	 * RFC3686 specific:
1490a5f57cffSCatalin Vasile 	 *	| CONTEXT1[255:128] = {NONCE, IV, COUNTER}
1491a5f57cffSCatalin Vasile 	 *	| *key = {KEY, NONCE}
1492a5f57cffSCatalin Vasile 	 */
1493a5f57cffSCatalin Vasile 	if (is_rfc3686) {
1494a5f57cffSCatalin Vasile 		ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
1495a5f57cffSCatalin Vasile 		keylen -= CTR_RFC3686_NONCE_SIZE;
1496a5f57cffSCatalin Vasile 	}
1497a5f57cffSCatalin Vasile 
1498acdca31dSYuan Kang 	memcpy(ctx->key, key, keylen);
1499acdca31dSYuan Kang 	ctx->key_dma = dma_map_single(jrdev, ctx->key, keylen,
1500acdca31dSYuan Kang 				      DMA_TO_DEVICE);
1501acdca31dSYuan Kang 	if (dma_mapping_error(jrdev, ctx->key_dma)) {
1502acdca31dSYuan Kang 		dev_err(jrdev, "unable to map key i/o memory\n");
1503acdca31dSYuan Kang 		return -ENOMEM;
1504acdca31dSYuan Kang 	}
1505acdca31dSYuan Kang 	ctx->enckeylen = keylen;
1506acdca31dSYuan Kang 
1507acdca31dSYuan Kang 	/* ablkcipher_encrypt shared descriptor */
1508acdca31dSYuan Kang 	desc = ctx->sh_desc_enc;
1509a5f57cffSCatalin Vasile 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1510acdca31dSYuan Kang 	/* Skip if already shared */
1511acdca31dSYuan Kang 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1512acdca31dSYuan Kang 				   JUMP_COND_SHRD);
1513acdca31dSYuan Kang 
1514acdca31dSYuan Kang 	/* Load class1 key only */
1515acdca31dSYuan Kang 	append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
1516acdca31dSYuan Kang 			  ctx->enckeylen, CLASS_1 |
1517acdca31dSYuan Kang 			  KEY_DEST_CLASS_REG);
1518acdca31dSYuan Kang 
1519a5f57cffSCatalin Vasile 	/* Load nonce into CONTEXT1 reg */
1520a5f57cffSCatalin Vasile 	if (is_rfc3686) {
15215ba1c7b5SCatalin Vasile 		nonce = (u8 *)key + keylen;
15225ba1c7b5SCatalin Vasile 		append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
15235ba1c7b5SCatalin Vasile 				   LDST_CLASS_IND_CCB |
1524a5f57cffSCatalin Vasile 				   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
1525a5f57cffSCatalin Vasile 		append_move(desc, MOVE_WAITCOMP |
1526a5f57cffSCatalin Vasile 			    MOVE_SRC_OUTFIFO |
1527a5f57cffSCatalin Vasile 			    MOVE_DEST_CLASS1CTX |
1528a5f57cffSCatalin Vasile 			    (16 << MOVE_OFFSET_SHIFT) |
1529a5f57cffSCatalin Vasile 			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
1530a5f57cffSCatalin Vasile 	}
1531a5f57cffSCatalin Vasile 
1532acdca31dSYuan Kang 	set_jump_tgt_here(desc, key_jump_cmd);
1533acdca31dSYuan Kang 
1534acdca31dSYuan Kang 	/* Load iv */
1535a5f57cffSCatalin Vasile 	append_seq_load(desc, crt->ivsize, LDST_SRCDST_BYTE_CONTEXT |
15362b22f6c5SCatalin Vasile 			LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT));
1537acdca31dSYuan Kang 
1538a5f57cffSCatalin Vasile 	/* Load counter into CONTEXT1 reg */
1539a5f57cffSCatalin Vasile 	if (is_rfc3686)
15405ba1c7b5SCatalin Vasile 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
1541a5f57cffSCatalin Vasile 				     LDST_SRCDST_BYTE_CONTEXT |
1542a5f57cffSCatalin Vasile 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
1543a5f57cffSCatalin Vasile 				      LDST_OFFSET_SHIFT));
1544a5f57cffSCatalin Vasile 
1545acdca31dSYuan Kang 	/* Load operation */
1546acdca31dSYuan Kang 	append_operation(desc, ctx->class1_alg_type |
1547acdca31dSYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
1548acdca31dSYuan Kang 
1549acdca31dSYuan Kang 	/* Perform operation */
1550acdca31dSYuan Kang 	ablkcipher_append_src_dst(desc);
1551acdca31dSYuan Kang 
1552acdca31dSYuan Kang 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
1553acdca31dSYuan Kang 					      desc_bytes(desc),
1554acdca31dSYuan Kang 					      DMA_TO_DEVICE);
1555acdca31dSYuan Kang 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
1556acdca31dSYuan Kang 		dev_err(jrdev, "unable to map shared descriptor\n");
1557acdca31dSYuan Kang 		return -ENOMEM;
1558acdca31dSYuan Kang 	}
1559acdca31dSYuan Kang #ifdef DEBUG
1560514df281SAlex Porosanu 	print_hex_dump(KERN_ERR,
1561514df281SAlex Porosanu 		       "ablkcipher enc shdesc@"__stringify(__LINE__)": ",
1562acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
1563acdca31dSYuan Kang 		       desc_bytes(desc), 1);
1564acdca31dSYuan Kang #endif
1565acdca31dSYuan Kang 	/* ablkcipher_decrypt shared descriptor */
1566acdca31dSYuan Kang 	desc = ctx->sh_desc_dec;
1567acdca31dSYuan Kang 
1568a5f57cffSCatalin Vasile 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1569acdca31dSYuan Kang 	/* Skip if already shared */
1570acdca31dSYuan Kang 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1571acdca31dSYuan Kang 				   JUMP_COND_SHRD);
1572acdca31dSYuan Kang 
1573acdca31dSYuan Kang 	/* Load class1 key only */
1574acdca31dSYuan Kang 	append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
1575acdca31dSYuan Kang 			  ctx->enckeylen, CLASS_1 |
1576acdca31dSYuan Kang 			  KEY_DEST_CLASS_REG);
1577acdca31dSYuan Kang 
1578a5f57cffSCatalin Vasile 	/* Load nonce into CONTEXT1 reg */
1579a5f57cffSCatalin Vasile 	if (is_rfc3686) {
15805ba1c7b5SCatalin Vasile 		nonce = (u8 *)key + keylen;
15815ba1c7b5SCatalin Vasile 		append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
15825ba1c7b5SCatalin Vasile 				   LDST_CLASS_IND_CCB |
1583a5f57cffSCatalin Vasile 				   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
1584a5f57cffSCatalin Vasile 		append_move(desc, MOVE_WAITCOMP |
1585a5f57cffSCatalin Vasile 			    MOVE_SRC_OUTFIFO |
1586a5f57cffSCatalin Vasile 			    MOVE_DEST_CLASS1CTX |
1587a5f57cffSCatalin Vasile 			    (16 << MOVE_OFFSET_SHIFT) |
1588a5f57cffSCatalin Vasile 			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
1589a5f57cffSCatalin Vasile 	}
1590a5f57cffSCatalin Vasile 
1591acdca31dSYuan Kang 	set_jump_tgt_here(desc, key_jump_cmd);
1592acdca31dSYuan Kang 
1593acdca31dSYuan Kang 	/* load IV */
1594a5f57cffSCatalin Vasile 	append_seq_load(desc, crt->ivsize, LDST_SRCDST_BYTE_CONTEXT |
15952b22f6c5SCatalin Vasile 			LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT));
1596acdca31dSYuan Kang 
1597a5f57cffSCatalin Vasile 	/* Load counter into CONTEXT1 reg */
1598a5f57cffSCatalin Vasile 	if (is_rfc3686)
15995ba1c7b5SCatalin Vasile 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
1600a5f57cffSCatalin Vasile 				     LDST_SRCDST_BYTE_CONTEXT |
1601a5f57cffSCatalin Vasile 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
1602a5f57cffSCatalin Vasile 				      LDST_OFFSET_SHIFT));
1603a5f57cffSCatalin Vasile 
1604acdca31dSYuan Kang 	/* Choose operation */
16052b22f6c5SCatalin Vasile 	if (ctr_mode)
16062b22f6c5SCatalin Vasile 		append_operation(desc, ctx->class1_alg_type |
16072b22f6c5SCatalin Vasile 				 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT);
16082b22f6c5SCatalin Vasile 	else
1609acdca31dSYuan Kang 		append_dec_op1(desc, ctx->class1_alg_type);
1610acdca31dSYuan Kang 
1611acdca31dSYuan Kang 	/* Perform operation */
1612acdca31dSYuan Kang 	ablkcipher_append_src_dst(desc);
1613acdca31dSYuan Kang 
1614acdca31dSYuan Kang 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
1615acdca31dSYuan Kang 					      desc_bytes(desc),
1616acdca31dSYuan Kang 					      DMA_TO_DEVICE);
161771c65f7cSHoria Geanta 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
1618acdca31dSYuan Kang 		dev_err(jrdev, "unable to map shared descriptor\n");
1619acdca31dSYuan Kang 		return -ENOMEM;
1620acdca31dSYuan Kang 	}
1621acdca31dSYuan Kang 
1622acdca31dSYuan Kang #ifdef DEBUG
1623514df281SAlex Porosanu 	print_hex_dump(KERN_ERR,
1624514df281SAlex Porosanu 		       "ablkcipher dec shdesc@"__stringify(__LINE__)": ",
1625acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
1626acdca31dSYuan Kang 		       desc_bytes(desc), 1);
1627acdca31dSYuan Kang #endif
16287222d1a3SCatalin Vasile 	/* ablkcipher_givencrypt shared descriptor */
16297222d1a3SCatalin Vasile 	desc = ctx->sh_desc_givenc;
16307222d1a3SCatalin Vasile 
16317222d1a3SCatalin Vasile 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
16327222d1a3SCatalin Vasile 	/* Skip if already shared */
16337222d1a3SCatalin Vasile 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
16347222d1a3SCatalin Vasile 				   JUMP_COND_SHRD);
16357222d1a3SCatalin Vasile 
16367222d1a3SCatalin Vasile 	/* Load class1 key only */
16377222d1a3SCatalin Vasile 	append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
16387222d1a3SCatalin Vasile 			  ctx->enckeylen, CLASS_1 |
16397222d1a3SCatalin Vasile 			  KEY_DEST_CLASS_REG);
16407222d1a3SCatalin Vasile 
16417222d1a3SCatalin Vasile 	/* Load Nonce into CONTEXT1 reg */
16427222d1a3SCatalin Vasile 	if (is_rfc3686) {
16435ba1c7b5SCatalin Vasile 		nonce = (u8 *)key + keylen;
16445ba1c7b5SCatalin Vasile 		append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
16455ba1c7b5SCatalin Vasile 				   LDST_CLASS_IND_CCB |
16467222d1a3SCatalin Vasile 				   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
16477222d1a3SCatalin Vasile 		append_move(desc, MOVE_WAITCOMP |
16487222d1a3SCatalin Vasile 			    MOVE_SRC_OUTFIFO |
16497222d1a3SCatalin Vasile 			    MOVE_DEST_CLASS1CTX |
16507222d1a3SCatalin Vasile 			    (16 << MOVE_OFFSET_SHIFT) |
16517222d1a3SCatalin Vasile 			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
16527222d1a3SCatalin Vasile 	}
16537222d1a3SCatalin Vasile 	set_jump_tgt_here(desc, key_jump_cmd);
16547222d1a3SCatalin Vasile 
16557222d1a3SCatalin Vasile 	/* Generate IV */
16567222d1a3SCatalin Vasile 	geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
16577222d1a3SCatalin Vasile 		NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 |
16587222d1a3SCatalin Vasile 		NFIFOENTRY_PTYPE_RND | (crt->ivsize << NFIFOENTRY_DLEN_SHIFT);
16597222d1a3SCatalin Vasile 	append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
16607222d1a3SCatalin Vasile 			    LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
16617222d1a3SCatalin Vasile 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
16627222d1a3SCatalin Vasile 	append_move(desc, MOVE_WAITCOMP |
16637222d1a3SCatalin Vasile 		    MOVE_SRC_INFIFO |
16647222d1a3SCatalin Vasile 		    MOVE_DEST_CLASS1CTX |
16657222d1a3SCatalin Vasile 		    (crt->ivsize << MOVE_LEN_SHIFT) |
16667222d1a3SCatalin Vasile 		    (ctx1_iv_off << MOVE_OFFSET_SHIFT));
16677222d1a3SCatalin Vasile 	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
16687222d1a3SCatalin Vasile 
16697222d1a3SCatalin Vasile 	/* Copy generated IV to memory */
16707222d1a3SCatalin Vasile 	append_seq_store(desc, crt->ivsize,
16717222d1a3SCatalin Vasile 			 LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
16727222d1a3SCatalin Vasile 			 (ctx1_iv_off << LDST_OFFSET_SHIFT));
16737222d1a3SCatalin Vasile 
16747222d1a3SCatalin Vasile 	/* Load Counter into CONTEXT1 reg */
16757222d1a3SCatalin Vasile 	if (is_rfc3686)
16765ba1c7b5SCatalin Vasile 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
16777222d1a3SCatalin Vasile 				     LDST_SRCDST_BYTE_CONTEXT |
16787222d1a3SCatalin Vasile 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
16797222d1a3SCatalin Vasile 				      LDST_OFFSET_SHIFT));
16807222d1a3SCatalin Vasile 
16817222d1a3SCatalin Vasile 	if (ctx1_iv_off)
16827222d1a3SCatalin Vasile 		append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | JUMP_COND_NCP |
16837222d1a3SCatalin Vasile 			    (1 << JUMP_OFFSET_SHIFT));
16847222d1a3SCatalin Vasile 
16857222d1a3SCatalin Vasile 	/* Load operation */
16867222d1a3SCatalin Vasile 	append_operation(desc, ctx->class1_alg_type |
16877222d1a3SCatalin Vasile 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
16887222d1a3SCatalin Vasile 
16897222d1a3SCatalin Vasile 	/* Perform operation */
16907222d1a3SCatalin Vasile 	ablkcipher_append_src_dst(desc);
16917222d1a3SCatalin Vasile 
16927222d1a3SCatalin Vasile 	ctx->sh_desc_givenc_dma = dma_map_single(jrdev, desc,
16937222d1a3SCatalin Vasile 						 desc_bytes(desc),
16947222d1a3SCatalin Vasile 						 DMA_TO_DEVICE);
16957222d1a3SCatalin Vasile 	if (dma_mapping_error(jrdev, ctx->sh_desc_givenc_dma)) {
16967222d1a3SCatalin Vasile 		dev_err(jrdev, "unable to map shared descriptor\n");
16977222d1a3SCatalin Vasile 		return -ENOMEM;
16987222d1a3SCatalin Vasile 	}
16997222d1a3SCatalin Vasile #ifdef DEBUG
17007222d1a3SCatalin Vasile 	print_hex_dump(KERN_ERR,
17017222d1a3SCatalin Vasile 		       "ablkcipher givenc shdesc@" __stringify(__LINE__) ": ",
17027222d1a3SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
17037222d1a3SCatalin Vasile 		       desc_bytes(desc), 1);
17047222d1a3SCatalin Vasile #endif
1705acdca31dSYuan Kang 
1706acdca31dSYuan Kang 	return ret;
1707acdca31dSYuan Kang }
1708acdca31dSYuan Kang 
1709c6415a60SCatalin Vasile static int xts_ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
1710c6415a60SCatalin Vasile 				 const u8 *key, unsigned int keylen)
1711c6415a60SCatalin Vasile {
1712c6415a60SCatalin Vasile 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
1713c6415a60SCatalin Vasile 	struct device *jrdev = ctx->jrdev;
1714c6415a60SCatalin Vasile 	u32 *key_jump_cmd, *desc;
1715c6415a60SCatalin Vasile 	__be64 sector_size = cpu_to_be64(512);
1716c6415a60SCatalin Vasile 
1717c6415a60SCatalin Vasile 	if (keylen != 2 * AES_MIN_KEY_SIZE  && keylen != 2 * AES_MAX_KEY_SIZE) {
1718c6415a60SCatalin Vasile 		crypto_ablkcipher_set_flags(ablkcipher,
1719c6415a60SCatalin Vasile 					    CRYPTO_TFM_RES_BAD_KEY_LEN);
1720c6415a60SCatalin Vasile 		dev_err(jrdev, "key size mismatch\n");
1721c6415a60SCatalin Vasile 		return -EINVAL;
1722c6415a60SCatalin Vasile 	}
1723c6415a60SCatalin Vasile 
1724c6415a60SCatalin Vasile 	memcpy(ctx->key, key, keylen);
1725c6415a60SCatalin Vasile 	ctx->key_dma = dma_map_single(jrdev, ctx->key, keylen, DMA_TO_DEVICE);
1726c6415a60SCatalin Vasile 	if (dma_mapping_error(jrdev, ctx->key_dma)) {
1727c6415a60SCatalin Vasile 		dev_err(jrdev, "unable to map key i/o memory\n");
1728c6415a60SCatalin Vasile 		return -ENOMEM;
1729c6415a60SCatalin Vasile 	}
1730c6415a60SCatalin Vasile 	ctx->enckeylen = keylen;
1731c6415a60SCatalin Vasile 
1732c6415a60SCatalin Vasile 	/* xts_ablkcipher_encrypt shared descriptor */
1733c6415a60SCatalin Vasile 	desc = ctx->sh_desc_enc;
1734c6415a60SCatalin Vasile 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1735c6415a60SCatalin Vasile 	/* Skip if already shared */
1736c6415a60SCatalin Vasile 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1737c6415a60SCatalin Vasile 				   JUMP_COND_SHRD);
1738c6415a60SCatalin Vasile 
1739c6415a60SCatalin Vasile 	/* Load class1 keys only */
1740c6415a60SCatalin Vasile 	append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
1741c6415a60SCatalin Vasile 			  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
1742c6415a60SCatalin Vasile 
1743c6415a60SCatalin Vasile 	/* Load sector size with index 40 bytes (0x28) */
1744c6415a60SCatalin Vasile 	append_cmd(desc, CMD_LOAD | IMMEDIATE | LDST_SRCDST_BYTE_CONTEXT |
1745c6415a60SCatalin Vasile 		   LDST_CLASS_1_CCB | (0x28 << LDST_OFFSET_SHIFT) | 8);
1746c6415a60SCatalin Vasile 	append_data(desc, (void *)&sector_size, 8);
1747c6415a60SCatalin Vasile 
1748c6415a60SCatalin Vasile 	set_jump_tgt_here(desc, key_jump_cmd);
1749c6415a60SCatalin Vasile 
1750c6415a60SCatalin Vasile 	/*
1751c6415a60SCatalin Vasile 	 * create sequence for loading the sector index
1752c6415a60SCatalin Vasile 	 * Upper 8B of IV - will be used as sector index
1753c6415a60SCatalin Vasile 	 * Lower 8B of IV - will be discarded
1754c6415a60SCatalin Vasile 	 */
1755c6415a60SCatalin Vasile 	append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_BYTE_CONTEXT |
1756c6415a60SCatalin Vasile 		   LDST_CLASS_1_CCB | (0x20 << LDST_OFFSET_SHIFT) | 8);
1757c6415a60SCatalin Vasile 	append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
1758c6415a60SCatalin Vasile 
1759c6415a60SCatalin Vasile 	/* Load operation */
1760c6415a60SCatalin Vasile 	append_operation(desc, ctx->class1_alg_type | OP_ALG_AS_INITFINAL |
1761c6415a60SCatalin Vasile 			 OP_ALG_ENCRYPT);
1762c6415a60SCatalin Vasile 
1763c6415a60SCatalin Vasile 	/* Perform operation */
1764c6415a60SCatalin Vasile 	ablkcipher_append_src_dst(desc);
1765c6415a60SCatalin Vasile 
1766c6415a60SCatalin Vasile 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc, desc_bytes(desc),
1767c6415a60SCatalin Vasile 					      DMA_TO_DEVICE);
1768c6415a60SCatalin Vasile 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
1769c6415a60SCatalin Vasile 		dev_err(jrdev, "unable to map shared descriptor\n");
1770c6415a60SCatalin Vasile 		return -ENOMEM;
1771c6415a60SCatalin Vasile 	}
1772c6415a60SCatalin Vasile #ifdef DEBUG
1773c6415a60SCatalin Vasile 	print_hex_dump(KERN_ERR,
1774c6415a60SCatalin Vasile 		       "xts ablkcipher enc shdesc@" __stringify(__LINE__) ": ",
1775c6415a60SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
1776c6415a60SCatalin Vasile #endif
1777c6415a60SCatalin Vasile 
1778c6415a60SCatalin Vasile 	/* xts_ablkcipher_decrypt shared descriptor */
1779c6415a60SCatalin Vasile 	desc = ctx->sh_desc_dec;
1780c6415a60SCatalin Vasile 
1781c6415a60SCatalin Vasile 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1782c6415a60SCatalin Vasile 	/* Skip if already shared */
1783c6415a60SCatalin Vasile 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1784c6415a60SCatalin Vasile 				   JUMP_COND_SHRD);
1785c6415a60SCatalin Vasile 
1786c6415a60SCatalin Vasile 	/* Load class1 key only */
1787c6415a60SCatalin Vasile 	append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
1788c6415a60SCatalin Vasile 			  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
1789c6415a60SCatalin Vasile 
1790c6415a60SCatalin Vasile 	/* Load sector size with index 40 bytes (0x28) */
1791c6415a60SCatalin Vasile 	append_cmd(desc, CMD_LOAD | IMMEDIATE | LDST_SRCDST_BYTE_CONTEXT |
1792c6415a60SCatalin Vasile 		   LDST_CLASS_1_CCB | (0x28 << LDST_OFFSET_SHIFT) | 8);
1793c6415a60SCatalin Vasile 	append_data(desc, (void *)&sector_size, 8);
1794c6415a60SCatalin Vasile 
1795c6415a60SCatalin Vasile 	set_jump_tgt_here(desc, key_jump_cmd);
1796c6415a60SCatalin Vasile 
1797c6415a60SCatalin Vasile 	/*
1798c6415a60SCatalin Vasile 	 * create sequence for loading the sector index
1799c6415a60SCatalin Vasile 	 * Upper 8B of IV - will be used as sector index
1800c6415a60SCatalin Vasile 	 * Lower 8B of IV - will be discarded
1801c6415a60SCatalin Vasile 	 */
1802c6415a60SCatalin Vasile 	append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_BYTE_CONTEXT |
1803c6415a60SCatalin Vasile 		   LDST_CLASS_1_CCB | (0x20 << LDST_OFFSET_SHIFT) | 8);
1804c6415a60SCatalin Vasile 	append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
1805c6415a60SCatalin Vasile 
1806c6415a60SCatalin Vasile 	/* Load operation */
1807c6415a60SCatalin Vasile 	append_dec_op1(desc, ctx->class1_alg_type);
1808c6415a60SCatalin Vasile 
1809c6415a60SCatalin Vasile 	/* Perform operation */
1810c6415a60SCatalin Vasile 	ablkcipher_append_src_dst(desc);
1811c6415a60SCatalin Vasile 
1812c6415a60SCatalin Vasile 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc, desc_bytes(desc),
1813c6415a60SCatalin Vasile 					      DMA_TO_DEVICE);
1814c6415a60SCatalin Vasile 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
1815c6415a60SCatalin Vasile 		dma_unmap_single(jrdev, ctx->sh_desc_enc_dma,
1816c6415a60SCatalin Vasile 				 desc_bytes(ctx->sh_desc_enc), DMA_TO_DEVICE);
1817c6415a60SCatalin Vasile 		dev_err(jrdev, "unable to map shared descriptor\n");
1818c6415a60SCatalin Vasile 		return -ENOMEM;
1819c6415a60SCatalin Vasile 	}
1820c6415a60SCatalin Vasile #ifdef DEBUG
1821c6415a60SCatalin Vasile 	print_hex_dump(KERN_ERR,
1822c6415a60SCatalin Vasile 		       "xts ablkcipher dec shdesc@" __stringify(__LINE__) ": ",
1823c6415a60SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
1824c6415a60SCatalin Vasile #endif
1825c6415a60SCatalin Vasile 
1826c6415a60SCatalin Vasile 	return 0;
1827c6415a60SCatalin Vasile }
1828c6415a60SCatalin Vasile 
18298e8ec596SKim Phillips /*
18301acebad3SYuan Kang  * aead_edesc - s/w-extended aead descriptor
18311acebad3SYuan Kang  * @assoc_nents: number of segments in associated data (SPI+Seq) scatterlist
18328e8ec596SKim Phillips  * @src_nents: number of segments in input scatterlist
18338e8ec596SKim Phillips  * @dst_nents: number of segments in output scatterlist
18341acebad3SYuan Kang  * @iv_dma: dma address of iv for checking continuity and link table
18358e8ec596SKim Phillips  * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE)
1836a299c837SYuan Kang  * @sec4_sg_bytes: length of dma mapped sec4_sg space
1837a299c837SYuan Kang  * @sec4_sg_dma: bus physical mapped address of h/w link table
18388e8ec596SKim Phillips  * @hw_desc: the h/w job descriptor followed by any referenced link tables
18398e8ec596SKim Phillips  */
18400e479300SYuan Kang struct aead_edesc {
18418e8ec596SKim Phillips 	int assoc_nents;
18428e8ec596SKim Phillips 	int src_nents;
18438e8ec596SKim Phillips 	int dst_nents;
18441acebad3SYuan Kang 	dma_addr_t iv_dma;
1845a299c837SYuan Kang 	int sec4_sg_bytes;
1846a299c837SYuan Kang 	dma_addr_t sec4_sg_dma;
1847a299c837SYuan Kang 	struct sec4_sg_entry *sec4_sg;
1848f2147b88SHerbert Xu 	u32 hw_desc[];
18498e8ec596SKim Phillips };
18508e8ec596SKim Phillips 
1851acdca31dSYuan Kang /*
1852acdca31dSYuan Kang  * ablkcipher_edesc - s/w-extended ablkcipher descriptor
1853acdca31dSYuan Kang  * @src_nents: number of segments in input scatterlist
1854acdca31dSYuan Kang  * @dst_nents: number of segments in output scatterlist
1855acdca31dSYuan Kang  * @iv_dma: dma address of iv for checking continuity and link table
1856acdca31dSYuan Kang  * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE)
1857a299c837SYuan Kang  * @sec4_sg_bytes: length of dma mapped sec4_sg space
1858a299c837SYuan Kang  * @sec4_sg_dma: bus physical mapped address of h/w link table
1859acdca31dSYuan Kang  * @hw_desc: the h/w job descriptor followed by any referenced link tables
1860acdca31dSYuan Kang  */
1861acdca31dSYuan Kang struct ablkcipher_edesc {
1862acdca31dSYuan Kang 	int src_nents;
1863acdca31dSYuan Kang 	int dst_nents;
1864acdca31dSYuan Kang 	dma_addr_t iv_dma;
1865a299c837SYuan Kang 	int sec4_sg_bytes;
1866a299c837SYuan Kang 	dma_addr_t sec4_sg_dma;
1867a299c837SYuan Kang 	struct sec4_sg_entry *sec4_sg;
1868acdca31dSYuan Kang 	u32 hw_desc[0];
1869acdca31dSYuan Kang };
1870acdca31dSYuan Kang 
18711acebad3SYuan Kang static void caam_unmap(struct device *dev, struct scatterlist *src,
1872643b39b0SYuan Kang 		       struct scatterlist *dst, int src_nents,
187313fb8fd7SLABBE Corentin 		       int dst_nents,
1874a299c837SYuan Kang 		       dma_addr_t iv_dma, int ivsize, dma_addr_t sec4_sg_dma,
1875a299c837SYuan Kang 		       int sec4_sg_bytes)
18761acebad3SYuan Kang {
1877643b39b0SYuan Kang 	if (dst != src) {
187813fb8fd7SLABBE Corentin 		dma_unmap_sg(dev, src, src_nents ? : 1, DMA_TO_DEVICE);
187913fb8fd7SLABBE Corentin 		dma_unmap_sg(dev, dst, dst_nents ? : 1, DMA_FROM_DEVICE);
18801acebad3SYuan Kang 	} else {
188113fb8fd7SLABBE Corentin 		dma_unmap_sg(dev, src, src_nents ? : 1, DMA_BIDIRECTIONAL);
18821acebad3SYuan Kang 	}
18831acebad3SYuan Kang 
18841acebad3SYuan Kang 	if (iv_dma)
18851acebad3SYuan Kang 		dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);
1886a299c837SYuan Kang 	if (sec4_sg_bytes)
1887a299c837SYuan Kang 		dma_unmap_single(dev, sec4_sg_dma, sec4_sg_bytes,
18881acebad3SYuan Kang 				 DMA_TO_DEVICE);
18891acebad3SYuan Kang }
18901acebad3SYuan Kang 
18910e479300SYuan Kang static void aead_unmap(struct device *dev,
18920e479300SYuan Kang 		       struct aead_edesc *edesc,
18930e479300SYuan Kang 		       struct aead_request *req)
18948e8ec596SKim Phillips {
1895f2147b88SHerbert Xu 	caam_unmap(dev, req->src, req->dst,
189613fb8fd7SLABBE Corentin 		   edesc->src_nents, edesc->dst_nents, 0, 0,
1897f2147b88SHerbert Xu 		   edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
1898f2147b88SHerbert Xu }
1899f2147b88SHerbert Xu 
1900acdca31dSYuan Kang static void ablkcipher_unmap(struct device *dev,
1901acdca31dSYuan Kang 			     struct ablkcipher_edesc *edesc,
1902acdca31dSYuan Kang 			     struct ablkcipher_request *req)
1903acdca31dSYuan Kang {
1904acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
1905acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
1906acdca31dSYuan Kang 
1907acdca31dSYuan Kang 	caam_unmap(dev, req->src, req->dst,
190813fb8fd7SLABBE Corentin 		   edesc->src_nents, edesc->dst_nents,
190913fb8fd7SLABBE Corentin 		   edesc->iv_dma, ivsize,
1910643b39b0SYuan Kang 		   edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
1911acdca31dSYuan Kang }
1912acdca31dSYuan Kang 
19130e479300SYuan Kang static void aead_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
19148e8ec596SKim Phillips 				   void *context)
19158e8ec596SKim Phillips {
19160e479300SYuan Kang 	struct aead_request *req = context;
19170e479300SYuan Kang 	struct aead_edesc *edesc;
1918f2147b88SHerbert Xu 
1919f2147b88SHerbert Xu #ifdef DEBUG
1920f2147b88SHerbert Xu 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
1921f2147b88SHerbert Xu #endif
1922f2147b88SHerbert Xu 
1923f2147b88SHerbert Xu 	edesc = container_of(desc, struct aead_edesc, hw_desc[0]);
1924f2147b88SHerbert Xu 
1925f2147b88SHerbert Xu 	if (err)
1926f2147b88SHerbert Xu 		caam_jr_strstatus(jrdev, err);
1927f2147b88SHerbert Xu 
1928f2147b88SHerbert Xu 	aead_unmap(jrdev, edesc, req);
1929f2147b88SHerbert Xu 
1930f2147b88SHerbert Xu 	kfree(edesc);
1931f2147b88SHerbert Xu 
1932f2147b88SHerbert Xu 	aead_request_complete(req, err);
1933f2147b88SHerbert Xu }
1934f2147b88SHerbert Xu 
19350e479300SYuan Kang static void aead_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
19368e8ec596SKim Phillips 				   void *context)
19378e8ec596SKim Phillips {
19380e479300SYuan Kang 	struct aead_request *req = context;
19390e479300SYuan Kang 	struct aead_edesc *edesc;
1940f2147b88SHerbert Xu 
1941f2147b88SHerbert Xu #ifdef DEBUG
1942f2147b88SHerbert Xu 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
1943f2147b88SHerbert Xu #endif
1944f2147b88SHerbert Xu 
1945f2147b88SHerbert Xu 	edesc = container_of(desc, struct aead_edesc, hw_desc[0]);
1946f2147b88SHerbert Xu 
1947f2147b88SHerbert Xu 	if (err)
1948f2147b88SHerbert Xu 		caam_jr_strstatus(jrdev, err);
1949f2147b88SHerbert Xu 
1950f2147b88SHerbert Xu 	aead_unmap(jrdev, edesc, req);
1951f2147b88SHerbert Xu 
1952f2147b88SHerbert Xu 	/*
1953f2147b88SHerbert Xu 	 * verify hw auth check passed else return -EBADMSG
1954f2147b88SHerbert Xu 	 */
1955f2147b88SHerbert Xu 	if ((err & JRSTA_CCBERR_ERRID_MASK) == JRSTA_CCBERR_ERRID_ICVCHK)
1956f2147b88SHerbert Xu 		err = -EBADMSG;
1957f2147b88SHerbert Xu 
1958f2147b88SHerbert Xu 	kfree(edesc);
1959f2147b88SHerbert Xu 
1960f2147b88SHerbert Xu 	aead_request_complete(req, err);
1961f2147b88SHerbert Xu }
1962f2147b88SHerbert Xu 
1963acdca31dSYuan Kang static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
1964acdca31dSYuan Kang 				   void *context)
1965acdca31dSYuan Kang {
1966acdca31dSYuan Kang 	struct ablkcipher_request *req = context;
1967acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
1968acdca31dSYuan Kang #ifdef DEBUG
1969acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
1970acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
1971acdca31dSYuan Kang 
1972acdca31dSYuan Kang 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
1973acdca31dSYuan Kang #endif
1974acdca31dSYuan Kang 
1975acdca31dSYuan Kang 	edesc = (struct ablkcipher_edesc *)((char *)desc -
1976acdca31dSYuan Kang 		 offsetof(struct ablkcipher_edesc, hw_desc));
1977acdca31dSYuan Kang 
1978fa9659cdSMarek Vasut 	if (err)
1979fa9659cdSMarek Vasut 		caam_jr_strstatus(jrdev, err);
1980acdca31dSYuan Kang 
1981acdca31dSYuan Kang #ifdef DEBUG
1982514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dstiv  @"__stringify(__LINE__)": ",
1983acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
1984acdca31dSYuan Kang 		       edesc->src_nents > 1 ? 100 : ivsize, 1);
1985514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dst    @"__stringify(__LINE__)": ",
1986acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src),
1987acdca31dSYuan Kang 		       edesc->dst_nents > 1 ? 100 : req->nbytes, 1);
1988acdca31dSYuan Kang #endif
1989acdca31dSYuan Kang 
1990acdca31dSYuan Kang 	ablkcipher_unmap(jrdev, edesc, req);
1991acdca31dSYuan Kang 	kfree(edesc);
1992acdca31dSYuan Kang 
1993acdca31dSYuan Kang 	ablkcipher_request_complete(req, err);
1994acdca31dSYuan Kang }
1995acdca31dSYuan Kang 
1996acdca31dSYuan Kang static void ablkcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
1997acdca31dSYuan Kang 				    void *context)
1998acdca31dSYuan Kang {
1999acdca31dSYuan Kang 	struct ablkcipher_request *req = context;
2000acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
2001acdca31dSYuan Kang #ifdef DEBUG
2002acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
2003acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
2004acdca31dSYuan Kang 
2005acdca31dSYuan Kang 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
2006acdca31dSYuan Kang #endif
2007acdca31dSYuan Kang 
2008acdca31dSYuan Kang 	edesc = (struct ablkcipher_edesc *)((char *)desc -
2009acdca31dSYuan Kang 		 offsetof(struct ablkcipher_edesc, hw_desc));
2010fa9659cdSMarek Vasut 	if (err)
2011fa9659cdSMarek Vasut 		caam_jr_strstatus(jrdev, err);
2012acdca31dSYuan Kang 
2013acdca31dSYuan Kang #ifdef DEBUG
2014514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dstiv  @"__stringify(__LINE__)": ",
2015acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
2016acdca31dSYuan Kang 		       ivsize, 1);
2017514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dst    @"__stringify(__LINE__)": ",
2018acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src),
2019acdca31dSYuan Kang 		       edesc->dst_nents > 1 ? 100 : req->nbytes, 1);
2020acdca31dSYuan Kang #endif
2021acdca31dSYuan Kang 
2022acdca31dSYuan Kang 	ablkcipher_unmap(jrdev, edesc, req);
2023acdca31dSYuan Kang 	kfree(edesc);
2024acdca31dSYuan Kang 
2025acdca31dSYuan Kang 	ablkcipher_request_complete(req, err);
2026acdca31dSYuan Kang }
2027acdca31dSYuan Kang 
20288e8ec596SKim Phillips /*
20291acebad3SYuan Kang  * Fill in aead job descriptor
20308e8ec596SKim Phillips  */
2031f2147b88SHerbert Xu static void init_aead_job(struct aead_request *req,
2032f2147b88SHerbert Xu 			  struct aead_edesc *edesc,
2033f2147b88SHerbert Xu 			  bool all_contig, bool encrypt)
2034f2147b88SHerbert Xu {
2035f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
2036f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
2037f2147b88SHerbert Xu 	int authsize = ctx->authsize;
2038f2147b88SHerbert Xu 	u32 *desc = edesc->hw_desc;
2039f2147b88SHerbert Xu 	u32 out_options, in_options;
2040f2147b88SHerbert Xu 	dma_addr_t dst_dma, src_dma;
2041f2147b88SHerbert Xu 	int len, sec4_sg_index = 0;
2042f2147b88SHerbert Xu 	dma_addr_t ptr;
2043f2147b88SHerbert Xu 	u32 *sh_desc;
2044f2147b88SHerbert Xu 
2045f2147b88SHerbert Xu 	sh_desc = encrypt ? ctx->sh_desc_enc : ctx->sh_desc_dec;
2046f2147b88SHerbert Xu 	ptr = encrypt ? ctx->sh_desc_enc_dma : ctx->sh_desc_dec_dma;
2047f2147b88SHerbert Xu 
2048f2147b88SHerbert Xu 	len = desc_len(sh_desc);
2049f2147b88SHerbert Xu 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
2050f2147b88SHerbert Xu 
2051f2147b88SHerbert Xu 	if (all_contig) {
2052f2147b88SHerbert Xu 		src_dma = sg_dma_address(req->src);
2053f2147b88SHerbert Xu 		in_options = 0;
2054f2147b88SHerbert Xu 	} else {
2055f2147b88SHerbert Xu 		src_dma = edesc->sec4_sg_dma;
2056f2147b88SHerbert Xu 		sec4_sg_index += edesc->src_nents;
2057f2147b88SHerbert Xu 		in_options = LDST_SGF;
2058f2147b88SHerbert Xu 	}
2059f2147b88SHerbert Xu 
2060f2147b88SHerbert Xu 	append_seq_in_ptr(desc, src_dma, req->assoclen + req->cryptlen,
2061f2147b88SHerbert Xu 			  in_options);
2062f2147b88SHerbert Xu 
2063f2147b88SHerbert Xu 	dst_dma = src_dma;
2064f2147b88SHerbert Xu 	out_options = in_options;
2065f2147b88SHerbert Xu 
2066f2147b88SHerbert Xu 	if (unlikely(req->src != req->dst)) {
2067f2147b88SHerbert Xu 		if (!edesc->dst_nents) {
2068f2147b88SHerbert Xu 			dst_dma = sg_dma_address(req->dst);
2069f2147b88SHerbert Xu 		} else {
2070f2147b88SHerbert Xu 			dst_dma = edesc->sec4_sg_dma +
2071f2147b88SHerbert Xu 				  sec4_sg_index *
2072f2147b88SHerbert Xu 				  sizeof(struct sec4_sg_entry);
2073f2147b88SHerbert Xu 			out_options = LDST_SGF;
2074f2147b88SHerbert Xu 		}
2075f2147b88SHerbert Xu 	}
2076f2147b88SHerbert Xu 
2077f2147b88SHerbert Xu 	if (encrypt)
2078f2147b88SHerbert Xu 		append_seq_out_ptr(desc, dst_dma,
2079f2147b88SHerbert Xu 				   req->assoclen + req->cryptlen + authsize,
2080f2147b88SHerbert Xu 				   out_options);
2081f2147b88SHerbert Xu 	else
2082f2147b88SHerbert Xu 		append_seq_out_ptr(desc, dst_dma,
2083f2147b88SHerbert Xu 				   req->assoclen + req->cryptlen - authsize,
2084f2147b88SHerbert Xu 				   out_options);
2085f2147b88SHerbert Xu 
2086f2147b88SHerbert Xu 	/* REG3 = assoclen */
2087f2147b88SHerbert Xu 	append_math_add_imm_u32(desc, REG3, ZERO, IMM, req->assoclen);
2088f2147b88SHerbert Xu }
2089f2147b88SHerbert Xu 
2090f2147b88SHerbert Xu static void init_gcm_job(struct aead_request *req,
2091f2147b88SHerbert Xu 			 struct aead_edesc *edesc,
2092f2147b88SHerbert Xu 			 bool all_contig, bool encrypt)
2093f2147b88SHerbert Xu {
2094f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
2095f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
2096f2147b88SHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
2097f2147b88SHerbert Xu 	u32 *desc = edesc->hw_desc;
2098f2147b88SHerbert Xu 	bool generic_gcm = (ivsize == 12);
2099f2147b88SHerbert Xu 	unsigned int last;
2100f2147b88SHerbert Xu 
2101f2147b88SHerbert Xu 	init_aead_job(req, edesc, all_contig, encrypt);
2102f2147b88SHerbert Xu 
2103f2147b88SHerbert Xu 	/* BUG This should not be specific to generic GCM. */
2104f2147b88SHerbert Xu 	last = 0;
2105f2147b88SHerbert Xu 	if (encrypt && generic_gcm && !(req->assoclen + req->cryptlen))
2106f2147b88SHerbert Xu 		last = FIFOLD_TYPE_LAST1;
2107f2147b88SHerbert Xu 
2108f2147b88SHerbert Xu 	/* Read GCM IV */
2109f2147b88SHerbert Xu 	append_cmd(desc, CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 | IMMEDIATE |
2110f2147b88SHerbert Xu 			 FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 | 12 | last);
2111f2147b88SHerbert Xu 	/* Append Salt */
2112f2147b88SHerbert Xu 	if (!generic_gcm)
2113f2147b88SHerbert Xu 		append_data(desc, ctx->key + ctx->enckeylen, 4);
2114f2147b88SHerbert Xu 	/* Append IV */
2115f2147b88SHerbert Xu 	append_data(desc, req->iv, ivsize);
2116f2147b88SHerbert Xu 	/* End of blank commands */
2117f2147b88SHerbert Xu }
2118f2147b88SHerbert Xu 
2119479bcc7cSHerbert Xu static void init_authenc_job(struct aead_request *req,
21201acebad3SYuan Kang 			     struct aead_edesc *edesc,
2121479bcc7cSHerbert Xu 			     bool all_contig, bool encrypt)
21221acebad3SYuan Kang {
21231acebad3SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
2124479bcc7cSHerbert Xu 	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
2125479bcc7cSHerbert Xu 						 struct caam_aead_alg, aead);
2126479bcc7cSHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
21271acebad3SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
2128479bcc7cSHerbert Xu 	const bool ctr_mode = ((ctx->class1_alg_type & OP_ALG_AAI_MASK) ==
2129479bcc7cSHerbert Xu 			       OP_ALG_AAI_CTR_MOD128);
2130479bcc7cSHerbert Xu 	const bool is_rfc3686 = alg->caam.rfc3686;
21311acebad3SYuan Kang 	u32 *desc = edesc->hw_desc;
2132479bcc7cSHerbert Xu 	u32 ivoffset = 0;
21338e8ec596SKim Phillips 
2134479bcc7cSHerbert Xu 	/*
2135479bcc7cSHerbert Xu 	 * AES-CTR needs to load IV in CONTEXT1 reg
2136479bcc7cSHerbert Xu 	 * at an offset of 128bits (16bytes)
2137479bcc7cSHerbert Xu 	 * CONTEXT1[255:128] = IV
2138479bcc7cSHerbert Xu 	 */
2139479bcc7cSHerbert Xu 	if (ctr_mode)
2140479bcc7cSHerbert Xu 		ivoffset = 16;
21418e8ec596SKim Phillips 
2142479bcc7cSHerbert Xu 	/*
2143479bcc7cSHerbert Xu 	 * RFC3686 specific:
2144479bcc7cSHerbert Xu 	 *	CONTEXT1[255:128] = {NONCE, IV, COUNTER}
2145479bcc7cSHerbert Xu 	 */
2146479bcc7cSHerbert Xu 	if (is_rfc3686)
2147479bcc7cSHerbert Xu 		ivoffset = 16 + CTR_RFC3686_NONCE_SIZE;
2148bac68f2cSTudor Ambarus 
2149479bcc7cSHerbert Xu 	init_aead_job(req, edesc, all_contig, encrypt);
21501acebad3SYuan Kang 
2151479bcc7cSHerbert Xu 	if (ivsize && (is_rfc3686 || !(alg->caam.geniv && encrypt)))
2152479bcc7cSHerbert Xu 		append_load_as_imm(desc, req->iv, ivsize,
2153479bcc7cSHerbert Xu 				   LDST_CLASS_1_CCB |
2154479bcc7cSHerbert Xu 				   LDST_SRCDST_BYTE_CONTEXT |
2155479bcc7cSHerbert Xu 				   (ivoffset << LDST_OFFSET_SHIFT));
21568e8ec596SKim Phillips }
21578e8ec596SKim Phillips 
21588e8ec596SKim Phillips /*
2159acdca31dSYuan Kang  * Fill in ablkcipher job descriptor
2160acdca31dSYuan Kang  */
2161acdca31dSYuan Kang static void init_ablkcipher_job(u32 *sh_desc, dma_addr_t ptr,
2162acdca31dSYuan Kang 				struct ablkcipher_edesc *edesc,
2163acdca31dSYuan Kang 				struct ablkcipher_request *req,
2164acdca31dSYuan Kang 				bool iv_contig)
2165acdca31dSYuan Kang {
2166acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
2167acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
2168acdca31dSYuan Kang 	u32 *desc = edesc->hw_desc;
2169acdca31dSYuan Kang 	u32 out_options = 0, in_options;
2170acdca31dSYuan Kang 	dma_addr_t dst_dma, src_dma;
2171a299c837SYuan Kang 	int len, sec4_sg_index = 0;
2172acdca31dSYuan Kang 
2173acdca31dSYuan Kang #ifdef DEBUG
2174514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "presciv@"__stringify(__LINE__)": ",
2175acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
2176acdca31dSYuan Kang 		       ivsize, 1);
2177514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "src    @"__stringify(__LINE__)": ",
2178acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src),
2179acdca31dSYuan Kang 		       edesc->src_nents ? 100 : req->nbytes, 1);
2180acdca31dSYuan Kang #endif
2181acdca31dSYuan Kang 
2182acdca31dSYuan Kang 	len = desc_len(sh_desc);
2183acdca31dSYuan Kang 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
2184acdca31dSYuan Kang 
2185acdca31dSYuan Kang 	if (iv_contig) {
2186acdca31dSYuan Kang 		src_dma = edesc->iv_dma;
2187acdca31dSYuan Kang 		in_options = 0;
2188acdca31dSYuan Kang 	} else {
2189a299c837SYuan Kang 		src_dma = edesc->sec4_sg_dma;
219035b82e55SCristian Stoica 		sec4_sg_index += edesc->src_nents + 1;
2191acdca31dSYuan Kang 		in_options = LDST_SGF;
2192acdca31dSYuan Kang 	}
2193acdca31dSYuan Kang 	append_seq_in_ptr(desc, src_dma, req->nbytes + ivsize, in_options);
2194acdca31dSYuan Kang 
2195acdca31dSYuan Kang 	if (likely(req->src == req->dst)) {
2196acdca31dSYuan Kang 		if (!edesc->src_nents && iv_contig) {
2197acdca31dSYuan Kang 			dst_dma = sg_dma_address(req->src);
2198acdca31dSYuan Kang 		} else {
2199a299c837SYuan Kang 			dst_dma = edesc->sec4_sg_dma +
2200a299c837SYuan Kang 				sizeof(struct sec4_sg_entry);
2201acdca31dSYuan Kang 			out_options = LDST_SGF;
2202acdca31dSYuan Kang 		}
2203acdca31dSYuan Kang 	} else {
2204acdca31dSYuan Kang 		if (!edesc->dst_nents) {
2205acdca31dSYuan Kang 			dst_dma = sg_dma_address(req->dst);
2206acdca31dSYuan Kang 		} else {
2207a299c837SYuan Kang 			dst_dma = edesc->sec4_sg_dma +
2208a299c837SYuan Kang 				sec4_sg_index * sizeof(struct sec4_sg_entry);
2209acdca31dSYuan Kang 			out_options = LDST_SGF;
2210acdca31dSYuan Kang 		}
2211acdca31dSYuan Kang 	}
2212acdca31dSYuan Kang 	append_seq_out_ptr(desc, dst_dma, req->nbytes, out_options);
2213acdca31dSYuan Kang }
2214acdca31dSYuan Kang 
2215acdca31dSYuan Kang /*
22167222d1a3SCatalin Vasile  * Fill in ablkcipher givencrypt job descriptor
22177222d1a3SCatalin Vasile  */
22187222d1a3SCatalin Vasile static void init_ablkcipher_giv_job(u32 *sh_desc, dma_addr_t ptr,
22197222d1a3SCatalin Vasile 				    struct ablkcipher_edesc *edesc,
22207222d1a3SCatalin Vasile 				    struct ablkcipher_request *req,
22217222d1a3SCatalin Vasile 				    bool iv_contig)
22227222d1a3SCatalin Vasile {
22237222d1a3SCatalin Vasile 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
22247222d1a3SCatalin Vasile 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
22257222d1a3SCatalin Vasile 	u32 *desc = edesc->hw_desc;
22267222d1a3SCatalin Vasile 	u32 out_options, in_options;
22277222d1a3SCatalin Vasile 	dma_addr_t dst_dma, src_dma;
22287222d1a3SCatalin Vasile 	int len, sec4_sg_index = 0;
22297222d1a3SCatalin Vasile 
22307222d1a3SCatalin Vasile #ifdef DEBUG
22317222d1a3SCatalin Vasile 	print_hex_dump(KERN_ERR, "presciv@" __stringify(__LINE__) ": ",
22327222d1a3SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
22337222d1a3SCatalin Vasile 		       ivsize, 1);
22347222d1a3SCatalin Vasile 	print_hex_dump(KERN_ERR, "src    @" __stringify(__LINE__) ": ",
22357222d1a3SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src),
22367222d1a3SCatalin Vasile 		       edesc->src_nents ? 100 : req->nbytes, 1);
22377222d1a3SCatalin Vasile #endif
22387222d1a3SCatalin Vasile 
22397222d1a3SCatalin Vasile 	len = desc_len(sh_desc);
22407222d1a3SCatalin Vasile 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
22417222d1a3SCatalin Vasile 
22427222d1a3SCatalin Vasile 	if (!edesc->src_nents) {
22437222d1a3SCatalin Vasile 		src_dma = sg_dma_address(req->src);
22447222d1a3SCatalin Vasile 		in_options = 0;
22457222d1a3SCatalin Vasile 	} else {
22467222d1a3SCatalin Vasile 		src_dma = edesc->sec4_sg_dma;
22477222d1a3SCatalin Vasile 		sec4_sg_index += edesc->src_nents;
22487222d1a3SCatalin Vasile 		in_options = LDST_SGF;
22497222d1a3SCatalin Vasile 	}
22507222d1a3SCatalin Vasile 	append_seq_in_ptr(desc, src_dma, req->nbytes, in_options);
22517222d1a3SCatalin Vasile 
22527222d1a3SCatalin Vasile 	if (iv_contig) {
22537222d1a3SCatalin Vasile 		dst_dma = edesc->iv_dma;
22547222d1a3SCatalin Vasile 		out_options = 0;
22557222d1a3SCatalin Vasile 	} else {
22567222d1a3SCatalin Vasile 		dst_dma = edesc->sec4_sg_dma +
22577222d1a3SCatalin Vasile 			  sec4_sg_index * sizeof(struct sec4_sg_entry);
22587222d1a3SCatalin Vasile 		out_options = LDST_SGF;
22597222d1a3SCatalin Vasile 	}
22607222d1a3SCatalin Vasile 	append_seq_out_ptr(desc, dst_dma, req->nbytes + ivsize, out_options);
22617222d1a3SCatalin Vasile }
22627222d1a3SCatalin Vasile 
22637222d1a3SCatalin Vasile /*
22641acebad3SYuan Kang  * allocate and map the aead extended descriptor
22658e8ec596SKim Phillips  */
2266f2147b88SHerbert Xu static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
2267f2147b88SHerbert Xu 					   int desc_bytes, bool *all_contig_ptr,
2268f2147b88SHerbert Xu 					   bool encrypt)
2269f2147b88SHerbert Xu {
2270f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
2271f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
2272f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
2273f2147b88SHerbert Xu 	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
2274f2147b88SHerbert Xu 		       CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC;
2275f2147b88SHerbert Xu 	int src_nents, dst_nents = 0;
2276f2147b88SHerbert Xu 	struct aead_edesc *edesc;
2277f2147b88SHerbert Xu 	int sgc;
2278f2147b88SHerbert Xu 	bool all_contig = true;
2279f2147b88SHerbert Xu 	int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes;
2280f2147b88SHerbert Xu 	unsigned int authsize = ctx->authsize;
2281f2147b88SHerbert Xu 
2282f2147b88SHerbert Xu 	if (unlikely(req->dst != req->src)) {
228313fb8fd7SLABBE Corentin 		src_nents = sg_count(req->src, req->assoclen + req->cryptlen);
2284f2147b88SHerbert Xu 		dst_nents = sg_count(req->dst,
2285f2147b88SHerbert Xu 				     req->assoclen + req->cryptlen +
228613fb8fd7SLABBE Corentin 					(encrypt ? authsize : (-authsize)));
2287f2147b88SHerbert Xu 	} else {
2288f2147b88SHerbert Xu 		src_nents = sg_count(req->src,
2289f2147b88SHerbert Xu 				     req->assoclen + req->cryptlen +
229013fb8fd7SLABBE Corentin 					(encrypt ? authsize : 0));
2291f2147b88SHerbert Xu 	}
2292f2147b88SHerbert Xu 
2293f2147b88SHerbert Xu 	/* Check if data are contiguous. */
2294f2147b88SHerbert Xu 	all_contig = !src_nents;
2295f2147b88SHerbert Xu 	if (!all_contig) {
2296f2147b88SHerbert Xu 		src_nents = src_nents ? : 1;
2297f2147b88SHerbert Xu 		sec4_sg_len = src_nents;
2298f2147b88SHerbert Xu 	}
2299f2147b88SHerbert Xu 
2300f2147b88SHerbert Xu 	sec4_sg_len += dst_nents;
2301f2147b88SHerbert Xu 
2302f2147b88SHerbert Xu 	sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry);
2303f2147b88SHerbert Xu 
2304f2147b88SHerbert Xu 	/* allocate space for base edesc and hw desc commands, link tables */
2305dde20ae9SVictoria Milhoan 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes,
2306dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
2307f2147b88SHerbert Xu 	if (!edesc) {
2308f2147b88SHerbert Xu 		dev_err(jrdev, "could not allocate extended descriptor\n");
2309f2147b88SHerbert Xu 		return ERR_PTR(-ENOMEM);
2310f2147b88SHerbert Xu 	}
2311f2147b88SHerbert Xu 
2312f2147b88SHerbert Xu 	if (likely(req->src == req->dst)) {
231313fb8fd7SLABBE Corentin 		sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1,
231413fb8fd7SLABBE Corentin 				 DMA_BIDIRECTIONAL);
2315f2147b88SHerbert Xu 		if (unlikely(!sgc)) {
2316f2147b88SHerbert Xu 			dev_err(jrdev, "unable to map source\n");
2317f2147b88SHerbert Xu 			kfree(edesc);
2318f2147b88SHerbert Xu 			return ERR_PTR(-ENOMEM);
2319f2147b88SHerbert Xu 		}
2320f2147b88SHerbert Xu 	} else {
232113fb8fd7SLABBE Corentin 		sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1,
232213fb8fd7SLABBE Corentin 				 DMA_TO_DEVICE);
2323f2147b88SHerbert Xu 		if (unlikely(!sgc)) {
2324f2147b88SHerbert Xu 			dev_err(jrdev, "unable to map source\n");
2325f2147b88SHerbert Xu 			kfree(edesc);
2326f2147b88SHerbert Xu 			return ERR_PTR(-ENOMEM);
2327f2147b88SHerbert Xu 		}
2328f2147b88SHerbert Xu 
232913fb8fd7SLABBE Corentin 		sgc = dma_map_sg(jrdev, req->dst, dst_nents ? : 1,
233013fb8fd7SLABBE Corentin 				 DMA_FROM_DEVICE);
2331f2147b88SHerbert Xu 		if (unlikely(!sgc)) {
2332f2147b88SHerbert Xu 			dev_err(jrdev, "unable to map destination\n");
233313fb8fd7SLABBE Corentin 			dma_unmap_sg(jrdev, req->src, src_nents ? : 1,
233413fb8fd7SLABBE Corentin 				     DMA_TO_DEVICE);
2335f2147b88SHerbert Xu 			kfree(edesc);
2336f2147b88SHerbert Xu 			return ERR_PTR(-ENOMEM);
2337f2147b88SHerbert Xu 		}
2338f2147b88SHerbert Xu 	}
2339f2147b88SHerbert Xu 
2340f2147b88SHerbert Xu 	edesc->src_nents = src_nents;
2341f2147b88SHerbert Xu 	edesc->dst_nents = dst_nents;
2342f2147b88SHerbert Xu 	edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) +
2343f2147b88SHerbert Xu 			 desc_bytes;
2344f2147b88SHerbert Xu 	*all_contig_ptr = all_contig;
2345f2147b88SHerbert Xu 
2346f2147b88SHerbert Xu 	sec4_sg_index = 0;
2347f2147b88SHerbert Xu 	if (!all_contig) {
23487793bda8SHerbert Xu 		sg_to_sec4_sg_last(req->src, src_nents,
2349f2147b88SHerbert Xu 			      edesc->sec4_sg + sec4_sg_index, 0);
2350f2147b88SHerbert Xu 		sec4_sg_index += src_nents;
2351f2147b88SHerbert Xu 	}
2352f2147b88SHerbert Xu 	if (dst_nents) {
2353f2147b88SHerbert Xu 		sg_to_sec4_sg_last(req->dst, dst_nents,
2354f2147b88SHerbert Xu 				   edesc->sec4_sg + sec4_sg_index, 0);
2355f2147b88SHerbert Xu 	}
2356f2147b88SHerbert Xu 
2357f2147b88SHerbert Xu 	if (!sec4_sg_bytes)
2358f2147b88SHerbert Xu 		return edesc;
2359f2147b88SHerbert Xu 
2360f2147b88SHerbert Xu 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
2361f2147b88SHerbert Xu 					    sec4_sg_bytes, DMA_TO_DEVICE);
2362f2147b88SHerbert Xu 	if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
2363f2147b88SHerbert Xu 		dev_err(jrdev, "unable to map S/G table\n");
2364f2147b88SHerbert Xu 		aead_unmap(jrdev, edesc, req);
2365f2147b88SHerbert Xu 		kfree(edesc);
2366f2147b88SHerbert Xu 		return ERR_PTR(-ENOMEM);
2367f2147b88SHerbert Xu 	}
2368f2147b88SHerbert Xu 
2369f2147b88SHerbert Xu 	edesc->sec4_sg_bytes = sec4_sg_bytes;
2370f2147b88SHerbert Xu 
2371f2147b88SHerbert Xu 	return edesc;
2372f2147b88SHerbert Xu }
2373f2147b88SHerbert Xu 
2374f2147b88SHerbert Xu static int gcm_encrypt(struct aead_request *req)
23758e8ec596SKim Phillips {
23760e479300SYuan Kang 	struct aead_edesc *edesc;
23778e8ec596SKim Phillips 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
23788e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
23798e8ec596SKim Phillips 	struct device *jrdev = ctx->jrdev;
23801acebad3SYuan Kang 	bool all_contig;
23818e8ec596SKim Phillips 	u32 *desc;
23821acebad3SYuan Kang 	int ret = 0;
23831acebad3SYuan Kang 
23848e8ec596SKim Phillips 	/* allocate extended descriptor */
2385f2147b88SHerbert Xu 	edesc = aead_edesc_alloc(req, GCM_DESC_JOB_IO_LEN, &all_contig, true);
23868e8ec596SKim Phillips 	if (IS_ERR(edesc))
23878e8ec596SKim Phillips 		return PTR_ERR(edesc);
23888e8ec596SKim Phillips 
23891acebad3SYuan Kang 	/* Create and submit job descriptor */
2390f2147b88SHerbert Xu 	init_gcm_job(req, edesc, all_contig, true);
23911acebad3SYuan Kang #ifdef DEBUG
2392514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
23931acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
23941acebad3SYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
23951acebad3SYuan Kang #endif
23961acebad3SYuan Kang 
23978e8ec596SKim Phillips 	desc = edesc->hw_desc;
23981acebad3SYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
23991acebad3SYuan Kang 	if (!ret) {
24001acebad3SYuan Kang 		ret = -EINPROGRESS;
24011acebad3SYuan Kang 	} else {
24021acebad3SYuan Kang 		aead_unmap(jrdev, edesc, req);
24031acebad3SYuan Kang 		kfree(edesc);
24041acebad3SYuan Kang 	}
24058e8ec596SKim Phillips 
24061acebad3SYuan Kang 	return ret;
24078e8ec596SKim Phillips }
24088e8ec596SKim Phillips 
240946218750SHerbert Xu static int ipsec_gcm_encrypt(struct aead_request *req)
241046218750SHerbert Xu {
241146218750SHerbert Xu 	if (req->assoclen < 8)
241246218750SHerbert Xu 		return -EINVAL;
241346218750SHerbert Xu 
241446218750SHerbert Xu 	return gcm_encrypt(req);
241546218750SHerbert Xu }
241646218750SHerbert Xu 
2417479bcc7cSHerbert Xu static int aead_encrypt(struct aead_request *req)
24188e8ec596SKim Phillips {
24191acebad3SYuan Kang 	struct aead_edesc *edesc;
24200e479300SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
24210e479300SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
24220e479300SYuan Kang 	struct device *jrdev = ctx->jrdev;
24231acebad3SYuan Kang 	bool all_contig;
24240e479300SYuan Kang 	u32 *desc;
24251acebad3SYuan Kang 	int ret = 0;
24260e479300SYuan Kang 
24270e479300SYuan Kang 	/* allocate extended descriptor */
2428479bcc7cSHerbert Xu 	edesc = aead_edesc_alloc(req, AUTHENC_DESC_JOB_IO_LEN,
2429479bcc7cSHerbert Xu 				 &all_contig, true);
24300e479300SYuan Kang 	if (IS_ERR(edesc))
24310e479300SYuan Kang 		return PTR_ERR(edesc);
24320e479300SYuan Kang 
2433f2147b88SHerbert Xu 	/* Create and submit job descriptor */
2434479bcc7cSHerbert Xu 	init_authenc_job(req, edesc, all_contig, true);
24351acebad3SYuan Kang #ifdef DEBUG
2436f2147b88SHerbert Xu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
2437f2147b88SHerbert Xu 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
2438f2147b88SHerbert Xu 		       desc_bytes(edesc->hw_desc), 1);
24391acebad3SYuan Kang #endif
24401acebad3SYuan Kang 
2441f2147b88SHerbert Xu 	desc = edesc->hw_desc;
2442479bcc7cSHerbert Xu 	ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
2443f2147b88SHerbert Xu 	if (!ret) {
2444f2147b88SHerbert Xu 		ret = -EINPROGRESS;
2445f2147b88SHerbert Xu 	} else {
2446479bcc7cSHerbert Xu 		aead_unmap(jrdev, edesc, req);
2447f2147b88SHerbert Xu 		kfree(edesc);
2448f2147b88SHerbert Xu 	}
2449f2147b88SHerbert Xu 
2450f2147b88SHerbert Xu 	return ret;
2451f2147b88SHerbert Xu }
2452f2147b88SHerbert Xu 
2453f2147b88SHerbert Xu static int gcm_decrypt(struct aead_request *req)
2454f2147b88SHerbert Xu {
2455f2147b88SHerbert Xu 	struct aead_edesc *edesc;
2456f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
2457f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
2458f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
2459f2147b88SHerbert Xu 	bool all_contig;
2460f2147b88SHerbert Xu 	u32 *desc;
2461f2147b88SHerbert Xu 	int ret = 0;
2462f2147b88SHerbert Xu 
2463f2147b88SHerbert Xu 	/* allocate extended descriptor */
2464f2147b88SHerbert Xu 	edesc = aead_edesc_alloc(req, GCM_DESC_JOB_IO_LEN, &all_contig, false);
2465f2147b88SHerbert Xu 	if (IS_ERR(edesc))
2466f2147b88SHerbert Xu 		return PTR_ERR(edesc);
2467f2147b88SHerbert Xu 
24681acebad3SYuan Kang 	/* Create and submit job descriptor*/
2469f2147b88SHerbert Xu 	init_gcm_job(req, edesc, all_contig, false);
24701acebad3SYuan Kang #ifdef DEBUG
2471514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
24721acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
24731acebad3SYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
24741acebad3SYuan Kang #endif
24751acebad3SYuan Kang 
24760e479300SYuan Kang 	desc = edesc->hw_desc;
24771acebad3SYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
24781acebad3SYuan Kang 	if (!ret) {
24791acebad3SYuan Kang 		ret = -EINPROGRESS;
24801acebad3SYuan Kang 	} else {
24811acebad3SYuan Kang 		aead_unmap(jrdev, edesc, req);
24821acebad3SYuan Kang 		kfree(edesc);
24831acebad3SYuan Kang 	}
24840e479300SYuan Kang 
24851acebad3SYuan Kang 	return ret;
24861acebad3SYuan Kang }
24870e479300SYuan Kang 
248846218750SHerbert Xu static int ipsec_gcm_decrypt(struct aead_request *req)
248946218750SHerbert Xu {
249046218750SHerbert Xu 	if (req->assoclen < 8)
249146218750SHerbert Xu 		return -EINVAL;
249246218750SHerbert Xu 
249346218750SHerbert Xu 	return gcm_decrypt(req);
249446218750SHerbert Xu }
249546218750SHerbert Xu 
2496479bcc7cSHerbert Xu static int aead_decrypt(struct aead_request *req)
2497f2147b88SHerbert Xu {
2498f2147b88SHerbert Xu 	struct aead_edesc *edesc;
2499f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
2500f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
2501f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
2502f2147b88SHerbert Xu 	bool all_contig;
2503f2147b88SHerbert Xu 	u32 *desc;
2504f2147b88SHerbert Xu 	int ret = 0;
2505f2147b88SHerbert Xu 
2506f2147b88SHerbert Xu 	/* allocate extended descriptor */
2507479bcc7cSHerbert Xu 	edesc = aead_edesc_alloc(req, AUTHENC_DESC_JOB_IO_LEN,
2508479bcc7cSHerbert Xu 				 &all_contig, false);
2509f2147b88SHerbert Xu 	if (IS_ERR(edesc))
2510f2147b88SHerbert Xu 		return PTR_ERR(edesc);
2511f2147b88SHerbert Xu 
2512f2147b88SHerbert Xu #ifdef DEBUG
2513f2147b88SHerbert Xu 	print_hex_dump(KERN_ERR, "dec src@"__stringify(__LINE__)": ",
2514f2147b88SHerbert Xu 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src),
2515479bcc7cSHerbert Xu 		       req->assoclen + req->cryptlen, 1);
2516f2147b88SHerbert Xu #endif
2517f2147b88SHerbert Xu 
2518f2147b88SHerbert Xu 	/* Create and submit job descriptor*/
2519479bcc7cSHerbert Xu 	init_authenc_job(req, edesc, all_contig, false);
2520f2147b88SHerbert Xu #ifdef DEBUG
2521f2147b88SHerbert Xu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
2522f2147b88SHerbert Xu 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
2523f2147b88SHerbert Xu 		       desc_bytes(edesc->hw_desc), 1);
2524f2147b88SHerbert Xu #endif
2525f2147b88SHerbert Xu 
2526f2147b88SHerbert Xu 	desc = edesc->hw_desc;
2527479bcc7cSHerbert Xu 	ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
2528f2147b88SHerbert Xu 	if (!ret) {
2529f2147b88SHerbert Xu 		ret = -EINPROGRESS;
2530f2147b88SHerbert Xu 	} else {
2531479bcc7cSHerbert Xu 		aead_unmap(jrdev, edesc, req);
2532f2147b88SHerbert Xu 		kfree(edesc);
2533f2147b88SHerbert Xu 	}
2534f2147b88SHerbert Xu 
2535f2147b88SHerbert Xu 	return ret;
2536f2147b88SHerbert Xu }
2537f2147b88SHerbert Xu 
2538479bcc7cSHerbert Xu static int aead_givdecrypt(struct aead_request *req)
25391acebad3SYuan Kang {
25401acebad3SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
2541479bcc7cSHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
25420e479300SYuan Kang 
2543479bcc7cSHerbert Xu 	if (req->cryptlen < ivsize)
2544479bcc7cSHerbert Xu 		return -EINVAL;
25450e479300SYuan Kang 
2546479bcc7cSHerbert Xu 	req->cryptlen -= ivsize;
2547479bcc7cSHerbert Xu 	req->assoclen += ivsize;
25481acebad3SYuan Kang 
2549479bcc7cSHerbert Xu 	return aead_decrypt(req);
2550ae4a825fSHoria Geanta }
2551ae4a825fSHoria Geanta 
2552acdca31dSYuan Kang /*
2553acdca31dSYuan Kang  * allocate and map the ablkcipher extended descriptor for ablkcipher
2554acdca31dSYuan Kang  */
2555acdca31dSYuan Kang static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request
2556acdca31dSYuan Kang 						       *req, int desc_bytes,
2557acdca31dSYuan Kang 						       bool *iv_contig_out)
2558acdca31dSYuan Kang {
2559acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
2560acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
2561acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
2562acdca31dSYuan Kang 	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
2563acdca31dSYuan Kang 					  CRYPTO_TFM_REQ_MAY_SLEEP)) ?
2564acdca31dSYuan Kang 		       GFP_KERNEL : GFP_ATOMIC;
2565a299c837SYuan Kang 	int src_nents, dst_nents = 0, sec4_sg_bytes;
2566acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
2567acdca31dSYuan Kang 	dma_addr_t iv_dma = 0;
2568acdca31dSYuan Kang 	bool iv_contig = false;
2569acdca31dSYuan Kang 	int sgc;
2570acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
2571a299c837SYuan Kang 	int sec4_sg_index;
2572acdca31dSYuan Kang 
257313fb8fd7SLABBE Corentin 	src_nents = sg_count(req->src, req->nbytes);
2574acdca31dSYuan Kang 
2575643b39b0SYuan Kang 	if (req->dst != req->src)
257613fb8fd7SLABBE Corentin 		dst_nents = sg_count(req->dst, req->nbytes);
2577acdca31dSYuan Kang 
2578acdca31dSYuan Kang 	if (likely(req->src == req->dst)) {
257913fb8fd7SLABBE Corentin 		sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1,
258013fb8fd7SLABBE Corentin 				 DMA_BIDIRECTIONAL);
2581acdca31dSYuan Kang 	} else {
258213fb8fd7SLABBE Corentin 		sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1,
258313fb8fd7SLABBE Corentin 				 DMA_TO_DEVICE);
258413fb8fd7SLABBE Corentin 		sgc = dma_map_sg(jrdev, req->dst, dst_nents ? : 1,
258513fb8fd7SLABBE Corentin 				 DMA_FROM_DEVICE);
2586acdca31dSYuan Kang 	}
2587acdca31dSYuan Kang 
2588ce572085SHoria Geanta 	iv_dma = dma_map_single(jrdev, req->info, ivsize, DMA_TO_DEVICE);
2589ce572085SHoria Geanta 	if (dma_mapping_error(jrdev, iv_dma)) {
2590ce572085SHoria Geanta 		dev_err(jrdev, "unable to map IV\n");
2591ce572085SHoria Geanta 		return ERR_PTR(-ENOMEM);
2592ce572085SHoria Geanta 	}
2593ce572085SHoria Geanta 
2594acdca31dSYuan Kang 	/*
2595acdca31dSYuan Kang 	 * Check if iv can be contiguous with source and destination.
2596acdca31dSYuan Kang 	 * If so, include it. If not, create scatterlist.
2597acdca31dSYuan Kang 	 */
2598acdca31dSYuan Kang 	if (!src_nents && iv_dma + ivsize == sg_dma_address(req->src))
2599acdca31dSYuan Kang 		iv_contig = true;
2600acdca31dSYuan Kang 	else
2601acdca31dSYuan Kang 		src_nents = src_nents ? : 1;
2602a299c837SYuan Kang 	sec4_sg_bytes = ((iv_contig ? 0 : 1) + src_nents + dst_nents) *
2603a299c837SYuan Kang 			sizeof(struct sec4_sg_entry);
2604acdca31dSYuan Kang 
2605acdca31dSYuan Kang 	/* allocate space for base edesc and hw desc commands, link tables */
2606dde20ae9SVictoria Milhoan 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes,
2607dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
2608acdca31dSYuan Kang 	if (!edesc) {
2609acdca31dSYuan Kang 		dev_err(jrdev, "could not allocate extended descriptor\n");
2610acdca31dSYuan Kang 		return ERR_PTR(-ENOMEM);
2611acdca31dSYuan Kang 	}
2612acdca31dSYuan Kang 
2613acdca31dSYuan Kang 	edesc->src_nents = src_nents;
2614acdca31dSYuan Kang 	edesc->dst_nents = dst_nents;
2615a299c837SYuan Kang 	edesc->sec4_sg_bytes = sec4_sg_bytes;
2616a299c837SYuan Kang 	edesc->sec4_sg = (void *)edesc + sizeof(struct ablkcipher_edesc) +
2617acdca31dSYuan Kang 			 desc_bytes;
2618acdca31dSYuan Kang 
2619a299c837SYuan Kang 	sec4_sg_index = 0;
2620acdca31dSYuan Kang 	if (!iv_contig) {
2621a299c837SYuan Kang 		dma_to_sec4_sg_one(edesc->sec4_sg, iv_dma, ivsize, 0);
2622a299c837SYuan Kang 		sg_to_sec4_sg_last(req->src, src_nents,
2623a299c837SYuan Kang 				   edesc->sec4_sg + 1, 0);
2624a299c837SYuan Kang 		sec4_sg_index += 1 + src_nents;
2625acdca31dSYuan Kang 	}
2626acdca31dSYuan Kang 
2627643b39b0SYuan Kang 	if (dst_nents) {
2628a299c837SYuan Kang 		sg_to_sec4_sg_last(req->dst, dst_nents,
2629a299c837SYuan Kang 			edesc->sec4_sg + sec4_sg_index, 0);
2630acdca31dSYuan Kang 	}
2631acdca31dSYuan Kang 
2632a299c837SYuan Kang 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
2633a299c837SYuan Kang 					    sec4_sg_bytes, DMA_TO_DEVICE);
2634ce572085SHoria Geanta 	if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
2635ce572085SHoria Geanta 		dev_err(jrdev, "unable to map S/G table\n");
2636ce572085SHoria Geanta 		return ERR_PTR(-ENOMEM);
2637ce572085SHoria Geanta 	}
2638ce572085SHoria Geanta 
2639acdca31dSYuan Kang 	edesc->iv_dma = iv_dma;
2640acdca31dSYuan Kang 
2641acdca31dSYuan Kang #ifdef DEBUG
2642514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ablkcipher sec4_sg@"__stringify(__LINE__)": ",
2643a299c837SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->sec4_sg,
2644a299c837SYuan Kang 		       sec4_sg_bytes, 1);
2645acdca31dSYuan Kang #endif
2646acdca31dSYuan Kang 
2647acdca31dSYuan Kang 	*iv_contig_out = iv_contig;
2648acdca31dSYuan Kang 	return edesc;
2649acdca31dSYuan Kang }
2650acdca31dSYuan Kang 
2651acdca31dSYuan Kang static int ablkcipher_encrypt(struct ablkcipher_request *req)
2652acdca31dSYuan Kang {
2653acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
2654acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
2655acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
2656acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
2657acdca31dSYuan Kang 	bool iv_contig;
2658acdca31dSYuan Kang 	u32 *desc;
2659acdca31dSYuan Kang 	int ret = 0;
2660acdca31dSYuan Kang 
2661acdca31dSYuan Kang 	/* allocate extended descriptor */
2662acdca31dSYuan Kang 	edesc = ablkcipher_edesc_alloc(req, DESC_JOB_IO_LEN *
2663acdca31dSYuan Kang 				       CAAM_CMD_SZ, &iv_contig);
2664acdca31dSYuan Kang 	if (IS_ERR(edesc))
2665acdca31dSYuan Kang 		return PTR_ERR(edesc);
2666acdca31dSYuan Kang 
2667acdca31dSYuan Kang 	/* Create and submit job descriptor*/
2668acdca31dSYuan Kang 	init_ablkcipher_job(ctx->sh_desc_enc,
2669acdca31dSYuan Kang 		ctx->sh_desc_enc_dma, edesc, req, iv_contig);
2670acdca31dSYuan Kang #ifdef DEBUG
2671514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ablkcipher jobdesc@"__stringify(__LINE__)": ",
2672acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
2673acdca31dSYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
2674acdca31dSYuan Kang #endif
2675acdca31dSYuan Kang 	desc = edesc->hw_desc;
2676acdca31dSYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, ablkcipher_encrypt_done, req);
2677acdca31dSYuan Kang 
2678acdca31dSYuan Kang 	if (!ret) {
2679acdca31dSYuan Kang 		ret = -EINPROGRESS;
2680acdca31dSYuan Kang 	} else {
2681acdca31dSYuan Kang 		ablkcipher_unmap(jrdev, edesc, req);
2682acdca31dSYuan Kang 		kfree(edesc);
2683acdca31dSYuan Kang 	}
2684acdca31dSYuan Kang 
2685acdca31dSYuan Kang 	return ret;
2686acdca31dSYuan Kang }
2687acdca31dSYuan Kang 
2688acdca31dSYuan Kang static int ablkcipher_decrypt(struct ablkcipher_request *req)
2689acdca31dSYuan Kang {
2690acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
2691acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
2692acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
2693acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
2694acdca31dSYuan Kang 	bool iv_contig;
2695acdca31dSYuan Kang 	u32 *desc;
2696acdca31dSYuan Kang 	int ret = 0;
2697acdca31dSYuan Kang 
2698acdca31dSYuan Kang 	/* allocate extended descriptor */
2699acdca31dSYuan Kang 	edesc = ablkcipher_edesc_alloc(req, DESC_JOB_IO_LEN *
2700acdca31dSYuan Kang 				       CAAM_CMD_SZ, &iv_contig);
2701acdca31dSYuan Kang 	if (IS_ERR(edesc))
2702acdca31dSYuan Kang 		return PTR_ERR(edesc);
2703acdca31dSYuan Kang 
2704acdca31dSYuan Kang 	/* Create and submit job descriptor*/
2705acdca31dSYuan Kang 	init_ablkcipher_job(ctx->sh_desc_dec,
2706acdca31dSYuan Kang 		ctx->sh_desc_dec_dma, edesc, req, iv_contig);
2707acdca31dSYuan Kang 	desc = edesc->hw_desc;
2708acdca31dSYuan Kang #ifdef DEBUG
2709514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ablkcipher jobdesc@"__stringify(__LINE__)": ",
2710acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
2711acdca31dSYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
2712acdca31dSYuan Kang #endif
2713acdca31dSYuan Kang 
2714acdca31dSYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, ablkcipher_decrypt_done, req);
2715acdca31dSYuan Kang 	if (!ret) {
2716acdca31dSYuan Kang 		ret = -EINPROGRESS;
2717acdca31dSYuan Kang 	} else {
2718acdca31dSYuan Kang 		ablkcipher_unmap(jrdev, edesc, req);
2719acdca31dSYuan Kang 		kfree(edesc);
2720acdca31dSYuan Kang 	}
2721acdca31dSYuan Kang 
2722acdca31dSYuan Kang 	return ret;
2723acdca31dSYuan Kang }
2724acdca31dSYuan Kang 
27257222d1a3SCatalin Vasile /*
27267222d1a3SCatalin Vasile  * allocate and map the ablkcipher extended descriptor
27277222d1a3SCatalin Vasile  * for ablkcipher givencrypt
27287222d1a3SCatalin Vasile  */
27297222d1a3SCatalin Vasile static struct ablkcipher_edesc *ablkcipher_giv_edesc_alloc(
27307222d1a3SCatalin Vasile 				struct skcipher_givcrypt_request *greq,
27317222d1a3SCatalin Vasile 				int desc_bytes,
27327222d1a3SCatalin Vasile 				bool *iv_contig_out)
27337222d1a3SCatalin Vasile {
27347222d1a3SCatalin Vasile 	struct ablkcipher_request *req = &greq->creq;
27357222d1a3SCatalin Vasile 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
27367222d1a3SCatalin Vasile 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
27377222d1a3SCatalin Vasile 	struct device *jrdev = ctx->jrdev;
27387222d1a3SCatalin Vasile 	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
27397222d1a3SCatalin Vasile 					  CRYPTO_TFM_REQ_MAY_SLEEP)) ?
27407222d1a3SCatalin Vasile 		       GFP_KERNEL : GFP_ATOMIC;
27417222d1a3SCatalin Vasile 	int src_nents, dst_nents = 0, sec4_sg_bytes;
27427222d1a3SCatalin Vasile 	struct ablkcipher_edesc *edesc;
27437222d1a3SCatalin Vasile 	dma_addr_t iv_dma = 0;
27447222d1a3SCatalin Vasile 	bool iv_contig = false;
27457222d1a3SCatalin Vasile 	int sgc;
27467222d1a3SCatalin Vasile 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
27477222d1a3SCatalin Vasile 	int sec4_sg_index;
27487222d1a3SCatalin Vasile 
274913fb8fd7SLABBE Corentin 	src_nents = sg_count(req->src, req->nbytes);
27507222d1a3SCatalin Vasile 
27517222d1a3SCatalin Vasile 	if (unlikely(req->dst != req->src))
275213fb8fd7SLABBE Corentin 		dst_nents = sg_count(req->dst, req->nbytes);
27537222d1a3SCatalin Vasile 
27547222d1a3SCatalin Vasile 	if (likely(req->src == req->dst)) {
275513fb8fd7SLABBE Corentin 		sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1,
275613fb8fd7SLABBE Corentin 				 DMA_BIDIRECTIONAL);
27577222d1a3SCatalin Vasile 	} else {
275813fb8fd7SLABBE Corentin 		sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1,
275913fb8fd7SLABBE Corentin 				 DMA_TO_DEVICE);
276013fb8fd7SLABBE Corentin 		sgc = dma_map_sg(jrdev, req->dst, dst_nents ? : 1,
276113fb8fd7SLABBE Corentin 				 DMA_FROM_DEVICE);
27627222d1a3SCatalin Vasile 	}
27637222d1a3SCatalin Vasile 
27647222d1a3SCatalin Vasile 	/*
27657222d1a3SCatalin Vasile 	 * Check if iv can be contiguous with source and destination.
27667222d1a3SCatalin Vasile 	 * If so, include it. If not, create scatterlist.
27677222d1a3SCatalin Vasile 	 */
27687222d1a3SCatalin Vasile 	iv_dma = dma_map_single(jrdev, greq->giv, ivsize, DMA_TO_DEVICE);
27697222d1a3SCatalin Vasile 	if (dma_mapping_error(jrdev, iv_dma)) {
27707222d1a3SCatalin Vasile 		dev_err(jrdev, "unable to map IV\n");
27717222d1a3SCatalin Vasile 		return ERR_PTR(-ENOMEM);
27727222d1a3SCatalin Vasile 	}
27737222d1a3SCatalin Vasile 
27747222d1a3SCatalin Vasile 	if (!dst_nents && iv_dma + ivsize == sg_dma_address(req->dst))
27757222d1a3SCatalin Vasile 		iv_contig = true;
27767222d1a3SCatalin Vasile 	else
27777222d1a3SCatalin Vasile 		dst_nents = dst_nents ? : 1;
27787222d1a3SCatalin Vasile 	sec4_sg_bytes = ((iv_contig ? 0 : 1) + src_nents + dst_nents) *
27797222d1a3SCatalin Vasile 			sizeof(struct sec4_sg_entry);
27807222d1a3SCatalin Vasile 
27817222d1a3SCatalin Vasile 	/* allocate space for base edesc and hw desc commands, link tables */
2782dde20ae9SVictoria Milhoan 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes,
2783dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
27847222d1a3SCatalin Vasile 	if (!edesc) {
27857222d1a3SCatalin Vasile 		dev_err(jrdev, "could not allocate extended descriptor\n");
27867222d1a3SCatalin Vasile 		return ERR_PTR(-ENOMEM);
27877222d1a3SCatalin Vasile 	}
27887222d1a3SCatalin Vasile 
27897222d1a3SCatalin Vasile 	edesc->src_nents = src_nents;
27907222d1a3SCatalin Vasile 	edesc->dst_nents = dst_nents;
27917222d1a3SCatalin Vasile 	edesc->sec4_sg_bytes = sec4_sg_bytes;
27927222d1a3SCatalin Vasile 	edesc->sec4_sg = (void *)edesc + sizeof(struct ablkcipher_edesc) +
27937222d1a3SCatalin Vasile 			 desc_bytes;
27947222d1a3SCatalin Vasile 
27957222d1a3SCatalin Vasile 	sec4_sg_index = 0;
27967222d1a3SCatalin Vasile 	if (src_nents) {
27977222d1a3SCatalin Vasile 		sg_to_sec4_sg_last(req->src, src_nents, edesc->sec4_sg, 0);
27987222d1a3SCatalin Vasile 		sec4_sg_index += src_nents;
27997222d1a3SCatalin Vasile 	}
28007222d1a3SCatalin Vasile 
28017222d1a3SCatalin Vasile 	if (!iv_contig) {
28027222d1a3SCatalin Vasile 		dma_to_sec4_sg_one(edesc->sec4_sg + sec4_sg_index,
28037222d1a3SCatalin Vasile 				   iv_dma, ivsize, 0);
28047222d1a3SCatalin Vasile 		sec4_sg_index += 1;
28057222d1a3SCatalin Vasile 		sg_to_sec4_sg_last(req->dst, dst_nents,
28067222d1a3SCatalin Vasile 				   edesc->sec4_sg + sec4_sg_index, 0);
28077222d1a3SCatalin Vasile 	}
28087222d1a3SCatalin Vasile 
28097222d1a3SCatalin Vasile 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
28107222d1a3SCatalin Vasile 					    sec4_sg_bytes, DMA_TO_DEVICE);
28117222d1a3SCatalin Vasile 	if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
28127222d1a3SCatalin Vasile 		dev_err(jrdev, "unable to map S/G table\n");
28137222d1a3SCatalin Vasile 		return ERR_PTR(-ENOMEM);
28147222d1a3SCatalin Vasile 	}
28157222d1a3SCatalin Vasile 	edesc->iv_dma = iv_dma;
28167222d1a3SCatalin Vasile 
28177222d1a3SCatalin Vasile #ifdef DEBUG
28187222d1a3SCatalin Vasile 	print_hex_dump(KERN_ERR,
28197222d1a3SCatalin Vasile 		       "ablkcipher sec4_sg@" __stringify(__LINE__) ": ",
28207222d1a3SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->sec4_sg,
28217222d1a3SCatalin Vasile 		       sec4_sg_bytes, 1);
28227222d1a3SCatalin Vasile #endif
28237222d1a3SCatalin Vasile 
28247222d1a3SCatalin Vasile 	*iv_contig_out = iv_contig;
28257222d1a3SCatalin Vasile 	return edesc;
28267222d1a3SCatalin Vasile }
28277222d1a3SCatalin Vasile 
28287222d1a3SCatalin Vasile static int ablkcipher_givencrypt(struct skcipher_givcrypt_request *creq)
28297222d1a3SCatalin Vasile {
28307222d1a3SCatalin Vasile 	struct ablkcipher_request *req = &creq->creq;
28317222d1a3SCatalin Vasile 	struct ablkcipher_edesc *edesc;
28327222d1a3SCatalin Vasile 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
28337222d1a3SCatalin Vasile 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
28347222d1a3SCatalin Vasile 	struct device *jrdev = ctx->jrdev;
28357222d1a3SCatalin Vasile 	bool iv_contig;
28367222d1a3SCatalin Vasile 	u32 *desc;
28377222d1a3SCatalin Vasile 	int ret = 0;
28387222d1a3SCatalin Vasile 
28397222d1a3SCatalin Vasile 	/* allocate extended descriptor */
28407222d1a3SCatalin Vasile 	edesc = ablkcipher_giv_edesc_alloc(creq, DESC_JOB_IO_LEN *
28417222d1a3SCatalin Vasile 				       CAAM_CMD_SZ, &iv_contig);
28427222d1a3SCatalin Vasile 	if (IS_ERR(edesc))
28437222d1a3SCatalin Vasile 		return PTR_ERR(edesc);
28447222d1a3SCatalin Vasile 
28457222d1a3SCatalin Vasile 	/* Create and submit job descriptor*/
28467222d1a3SCatalin Vasile 	init_ablkcipher_giv_job(ctx->sh_desc_givenc, ctx->sh_desc_givenc_dma,
28477222d1a3SCatalin Vasile 				edesc, req, iv_contig);
28487222d1a3SCatalin Vasile #ifdef DEBUG
28497222d1a3SCatalin Vasile 	print_hex_dump(KERN_ERR,
28507222d1a3SCatalin Vasile 		       "ablkcipher jobdesc@" __stringify(__LINE__) ": ",
28517222d1a3SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
28527222d1a3SCatalin Vasile 		       desc_bytes(edesc->hw_desc), 1);
28537222d1a3SCatalin Vasile #endif
28547222d1a3SCatalin Vasile 	desc = edesc->hw_desc;
28557222d1a3SCatalin Vasile 	ret = caam_jr_enqueue(jrdev, desc, ablkcipher_encrypt_done, req);
28567222d1a3SCatalin Vasile 
28577222d1a3SCatalin Vasile 	if (!ret) {
28587222d1a3SCatalin Vasile 		ret = -EINPROGRESS;
28597222d1a3SCatalin Vasile 	} else {
28607222d1a3SCatalin Vasile 		ablkcipher_unmap(jrdev, edesc, req);
28617222d1a3SCatalin Vasile 		kfree(edesc);
28627222d1a3SCatalin Vasile 	}
28637222d1a3SCatalin Vasile 
28647222d1a3SCatalin Vasile 	return ret;
28657222d1a3SCatalin Vasile }
28667222d1a3SCatalin Vasile 
2867885e9e2fSYuan Kang #define template_aead		template_u.aead
2868acdca31dSYuan Kang #define template_ablkcipher	template_u.ablkcipher
28698e8ec596SKim Phillips struct caam_alg_template {
28708e8ec596SKim Phillips 	char name[CRYPTO_MAX_ALG_NAME];
28718e8ec596SKim Phillips 	char driver_name[CRYPTO_MAX_ALG_NAME];
28728e8ec596SKim Phillips 	unsigned int blocksize;
2873885e9e2fSYuan Kang 	u32 type;
2874885e9e2fSYuan Kang 	union {
2875885e9e2fSYuan Kang 		struct ablkcipher_alg ablkcipher;
2876885e9e2fSYuan Kang 	} template_u;
28778e8ec596SKim Phillips 	u32 class1_alg_type;
28788e8ec596SKim Phillips 	u32 class2_alg_type;
28798e8ec596SKim Phillips 	u32 alg_op;
28808e8ec596SKim Phillips };
28818e8ec596SKim Phillips 
28828e8ec596SKim Phillips static struct caam_alg_template driver_algs[] = {
2883acdca31dSYuan Kang 	/* ablkcipher descriptor */
2884acdca31dSYuan Kang 	{
2885acdca31dSYuan Kang 		.name = "cbc(aes)",
2886acdca31dSYuan Kang 		.driver_name = "cbc-aes-caam",
2887acdca31dSYuan Kang 		.blocksize = AES_BLOCK_SIZE,
28887222d1a3SCatalin Vasile 		.type = CRYPTO_ALG_TYPE_GIVCIPHER,
2889acdca31dSYuan Kang 		.template_ablkcipher = {
2890acdca31dSYuan Kang 			.setkey = ablkcipher_setkey,
2891acdca31dSYuan Kang 			.encrypt = ablkcipher_encrypt,
2892acdca31dSYuan Kang 			.decrypt = ablkcipher_decrypt,
28937222d1a3SCatalin Vasile 			.givencrypt = ablkcipher_givencrypt,
28947222d1a3SCatalin Vasile 			.geniv = "<built-in>",
2895acdca31dSYuan Kang 			.min_keysize = AES_MIN_KEY_SIZE,
2896acdca31dSYuan Kang 			.max_keysize = AES_MAX_KEY_SIZE,
2897acdca31dSYuan Kang 			.ivsize = AES_BLOCK_SIZE,
2898acdca31dSYuan Kang 			},
2899acdca31dSYuan Kang 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2900acdca31dSYuan Kang 	},
2901acdca31dSYuan Kang 	{
2902acdca31dSYuan Kang 		.name = "cbc(des3_ede)",
2903acdca31dSYuan Kang 		.driver_name = "cbc-3des-caam",
2904acdca31dSYuan Kang 		.blocksize = DES3_EDE_BLOCK_SIZE,
2905ff2c3a3bSCatalin Vasile 		.type = CRYPTO_ALG_TYPE_GIVCIPHER,
2906acdca31dSYuan Kang 		.template_ablkcipher = {
2907acdca31dSYuan Kang 			.setkey = ablkcipher_setkey,
2908acdca31dSYuan Kang 			.encrypt = ablkcipher_encrypt,
2909acdca31dSYuan Kang 			.decrypt = ablkcipher_decrypt,
2910ff2c3a3bSCatalin Vasile 			.givencrypt = ablkcipher_givencrypt,
2911ff2c3a3bSCatalin Vasile 			.geniv = "<built-in>",
2912acdca31dSYuan Kang 			.min_keysize = DES3_EDE_KEY_SIZE,
2913acdca31dSYuan Kang 			.max_keysize = DES3_EDE_KEY_SIZE,
2914acdca31dSYuan Kang 			.ivsize = DES3_EDE_BLOCK_SIZE,
2915acdca31dSYuan Kang 			},
2916acdca31dSYuan Kang 		.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2917acdca31dSYuan Kang 	},
2918acdca31dSYuan Kang 	{
2919acdca31dSYuan Kang 		.name = "cbc(des)",
2920acdca31dSYuan Kang 		.driver_name = "cbc-des-caam",
2921acdca31dSYuan Kang 		.blocksize = DES_BLOCK_SIZE,
2922ff2c3a3bSCatalin Vasile 		.type = CRYPTO_ALG_TYPE_GIVCIPHER,
2923acdca31dSYuan Kang 		.template_ablkcipher = {
2924acdca31dSYuan Kang 			.setkey = ablkcipher_setkey,
2925acdca31dSYuan Kang 			.encrypt = ablkcipher_encrypt,
2926acdca31dSYuan Kang 			.decrypt = ablkcipher_decrypt,
2927ff2c3a3bSCatalin Vasile 			.givencrypt = ablkcipher_givencrypt,
2928ff2c3a3bSCatalin Vasile 			.geniv = "<built-in>",
2929acdca31dSYuan Kang 			.min_keysize = DES_KEY_SIZE,
2930acdca31dSYuan Kang 			.max_keysize = DES_KEY_SIZE,
2931acdca31dSYuan Kang 			.ivsize = DES_BLOCK_SIZE,
2932acdca31dSYuan Kang 			},
2933acdca31dSYuan Kang 		.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
29342b22f6c5SCatalin Vasile 	},
29352b22f6c5SCatalin Vasile 	{
29362b22f6c5SCatalin Vasile 		.name = "ctr(aes)",
29372b22f6c5SCatalin Vasile 		.driver_name = "ctr-aes-caam",
29382b22f6c5SCatalin Vasile 		.blocksize = 1,
29392b22f6c5SCatalin Vasile 		.type = CRYPTO_ALG_TYPE_ABLKCIPHER,
29402b22f6c5SCatalin Vasile 		.template_ablkcipher = {
29412b22f6c5SCatalin Vasile 			.setkey = ablkcipher_setkey,
29422b22f6c5SCatalin Vasile 			.encrypt = ablkcipher_encrypt,
29432b22f6c5SCatalin Vasile 			.decrypt = ablkcipher_decrypt,
29442b22f6c5SCatalin Vasile 			.geniv = "chainiv",
29452b22f6c5SCatalin Vasile 			.min_keysize = AES_MIN_KEY_SIZE,
29462b22f6c5SCatalin Vasile 			.max_keysize = AES_MAX_KEY_SIZE,
29472b22f6c5SCatalin Vasile 			.ivsize = AES_BLOCK_SIZE,
29482b22f6c5SCatalin Vasile 			},
29492b22f6c5SCatalin Vasile 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CTR_MOD128,
2950a5f57cffSCatalin Vasile 	},
2951a5f57cffSCatalin Vasile 	{
2952a5f57cffSCatalin Vasile 		.name = "rfc3686(ctr(aes))",
2953a5f57cffSCatalin Vasile 		.driver_name = "rfc3686-ctr-aes-caam",
2954a5f57cffSCatalin Vasile 		.blocksize = 1,
29557222d1a3SCatalin Vasile 		.type = CRYPTO_ALG_TYPE_GIVCIPHER,
2956a5f57cffSCatalin Vasile 		.template_ablkcipher = {
2957a5f57cffSCatalin Vasile 			.setkey = ablkcipher_setkey,
2958a5f57cffSCatalin Vasile 			.encrypt = ablkcipher_encrypt,
2959a5f57cffSCatalin Vasile 			.decrypt = ablkcipher_decrypt,
29607222d1a3SCatalin Vasile 			.givencrypt = ablkcipher_givencrypt,
29617222d1a3SCatalin Vasile 			.geniv = "<built-in>",
2962a5f57cffSCatalin Vasile 			.min_keysize = AES_MIN_KEY_SIZE +
2963a5f57cffSCatalin Vasile 				       CTR_RFC3686_NONCE_SIZE,
2964a5f57cffSCatalin Vasile 			.max_keysize = AES_MAX_KEY_SIZE +
2965a5f57cffSCatalin Vasile 				       CTR_RFC3686_NONCE_SIZE,
2966a5f57cffSCatalin Vasile 			.ivsize = CTR_RFC3686_IV_SIZE,
2967a5f57cffSCatalin Vasile 			},
2968a5f57cffSCatalin Vasile 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CTR_MOD128,
2969c6415a60SCatalin Vasile 	},
2970c6415a60SCatalin Vasile 	{
2971c6415a60SCatalin Vasile 		.name = "xts(aes)",
2972c6415a60SCatalin Vasile 		.driver_name = "xts-aes-caam",
2973c6415a60SCatalin Vasile 		.blocksize = AES_BLOCK_SIZE,
2974c6415a60SCatalin Vasile 		.type = CRYPTO_ALG_TYPE_ABLKCIPHER,
2975c6415a60SCatalin Vasile 		.template_ablkcipher = {
2976c6415a60SCatalin Vasile 			.setkey = xts_ablkcipher_setkey,
2977c6415a60SCatalin Vasile 			.encrypt = ablkcipher_encrypt,
2978c6415a60SCatalin Vasile 			.decrypt = ablkcipher_decrypt,
2979c6415a60SCatalin Vasile 			.geniv = "eseqiv",
2980c6415a60SCatalin Vasile 			.min_keysize = 2 * AES_MIN_KEY_SIZE,
2981c6415a60SCatalin Vasile 			.max_keysize = 2 * AES_MAX_KEY_SIZE,
2982c6415a60SCatalin Vasile 			.ivsize = AES_BLOCK_SIZE,
2983c6415a60SCatalin Vasile 			},
2984c6415a60SCatalin Vasile 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_XTS,
2985c6415a60SCatalin Vasile 	},
29868e8ec596SKim Phillips };
29878e8ec596SKim Phillips 
2988f2147b88SHerbert Xu static struct caam_aead_alg driver_aeads[] = {
2989f2147b88SHerbert Xu 	{
2990f2147b88SHerbert Xu 		.aead = {
2991f2147b88SHerbert Xu 			.base = {
2992f2147b88SHerbert Xu 				.cra_name = "rfc4106(gcm(aes))",
2993f2147b88SHerbert Xu 				.cra_driver_name = "rfc4106-gcm-aes-caam",
2994f2147b88SHerbert Xu 				.cra_blocksize = 1,
2995f2147b88SHerbert Xu 			},
2996f2147b88SHerbert Xu 			.setkey = rfc4106_setkey,
2997f2147b88SHerbert Xu 			.setauthsize = rfc4106_setauthsize,
299846218750SHerbert Xu 			.encrypt = ipsec_gcm_encrypt,
299946218750SHerbert Xu 			.decrypt = ipsec_gcm_decrypt,
3000f2147b88SHerbert Xu 			.ivsize = 8,
3001f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
3002f2147b88SHerbert Xu 		},
3003f2147b88SHerbert Xu 		.caam = {
3004f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
3005f2147b88SHerbert Xu 		},
3006f2147b88SHerbert Xu 	},
3007f2147b88SHerbert Xu 	{
3008f2147b88SHerbert Xu 		.aead = {
3009f2147b88SHerbert Xu 			.base = {
3010f2147b88SHerbert Xu 				.cra_name = "rfc4543(gcm(aes))",
3011f2147b88SHerbert Xu 				.cra_driver_name = "rfc4543-gcm-aes-caam",
3012f2147b88SHerbert Xu 				.cra_blocksize = 1,
3013f2147b88SHerbert Xu 			},
3014f2147b88SHerbert Xu 			.setkey = rfc4543_setkey,
3015f2147b88SHerbert Xu 			.setauthsize = rfc4543_setauthsize,
301646218750SHerbert Xu 			.encrypt = ipsec_gcm_encrypt,
301746218750SHerbert Xu 			.decrypt = ipsec_gcm_decrypt,
3018f2147b88SHerbert Xu 			.ivsize = 8,
3019f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
3020f2147b88SHerbert Xu 		},
3021f2147b88SHerbert Xu 		.caam = {
3022f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
3023f2147b88SHerbert Xu 		},
3024f2147b88SHerbert Xu 	},
3025f2147b88SHerbert Xu 	/* Galois Counter Mode */
3026f2147b88SHerbert Xu 	{
3027f2147b88SHerbert Xu 		.aead = {
3028f2147b88SHerbert Xu 			.base = {
3029f2147b88SHerbert Xu 				.cra_name = "gcm(aes)",
3030f2147b88SHerbert Xu 				.cra_driver_name = "gcm-aes-caam",
3031f2147b88SHerbert Xu 				.cra_blocksize = 1,
3032f2147b88SHerbert Xu 			},
3033f2147b88SHerbert Xu 			.setkey = gcm_setkey,
3034f2147b88SHerbert Xu 			.setauthsize = gcm_setauthsize,
3035f2147b88SHerbert Xu 			.encrypt = gcm_encrypt,
3036f2147b88SHerbert Xu 			.decrypt = gcm_decrypt,
3037f2147b88SHerbert Xu 			.ivsize = 12,
3038f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
3039f2147b88SHerbert Xu 		},
3040f2147b88SHerbert Xu 		.caam = {
3041f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
3042f2147b88SHerbert Xu 		},
3043f2147b88SHerbert Xu 	},
3044479bcc7cSHerbert Xu 	/* single-pass ipsec_esp descriptor */
3045479bcc7cSHerbert Xu 	{
3046479bcc7cSHerbert Xu 		.aead = {
3047479bcc7cSHerbert Xu 			.base = {
3048479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),"
3049479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
3050479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
3051479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
3052479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
3053479bcc7cSHerbert Xu 			},
3054479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3055479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3056479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3057479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3058479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
3059479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3060479bcc7cSHerbert Xu 		},
3061479bcc7cSHerbert Xu 		.caam = {
3062479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3063479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3064479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3065479bcc7cSHerbert Xu 		},
3066479bcc7cSHerbert Xu 	},
3067479bcc7cSHerbert Xu 	{
3068479bcc7cSHerbert Xu 		.aead = {
3069479bcc7cSHerbert Xu 			.base = {
3070479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
3071479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
3072479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
3073479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
3074479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
3075479bcc7cSHerbert Xu 			},
3076479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3077479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3078479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3079479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3080479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
3081479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3082479bcc7cSHerbert Xu 		},
3083479bcc7cSHerbert Xu 		.caam = {
3084479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3085479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3086479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
3087479bcc7cSHerbert Xu 		},
3088479bcc7cSHerbert Xu 	},
3089479bcc7cSHerbert Xu 	{
3090479bcc7cSHerbert Xu 		.aead = {
3091479bcc7cSHerbert Xu 			.base = {
3092479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
3093479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
3094479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
3095479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
3096479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
3097479bcc7cSHerbert Xu 			},
3098479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3099479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3100479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3101479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3102479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
3103479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3104479bcc7cSHerbert Xu 		},
3105479bcc7cSHerbert Xu 		.caam = {
3106479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3107479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3108479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
3109479bcc7cSHerbert Xu 		},
3110479bcc7cSHerbert Xu 	},
3111479bcc7cSHerbert Xu 	{
3112479bcc7cSHerbert Xu 		.aead = {
3113479bcc7cSHerbert Xu 			.base = {
3114479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
3115479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
3116479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
3117479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
3118479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
3119479bcc7cSHerbert Xu 			},
3120479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3121479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3122479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3123479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3124479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
3125479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3126479bcc7cSHerbert Xu 		},
3127479bcc7cSHerbert Xu 		.caam = {
3128479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3129479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3130479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3131479bcc7cSHerbert Xu 		},
3132479bcc7cSHerbert Xu 	},
3133479bcc7cSHerbert Xu 	{
3134479bcc7cSHerbert Xu 		.aead = {
3135479bcc7cSHerbert Xu 			.base = {
3136479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
3137479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
3138479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
3139479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
3140479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
3141479bcc7cSHerbert Xu 			},
3142479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3143479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3144479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3145479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3146479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
3147479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3148479bcc7cSHerbert Xu 		},
3149479bcc7cSHerbert Xu 		.caam = {
3150479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3151479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3152479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3153479bcc7cSHerbert Xu 		},
3154479bcc7cSHerbert Xu 	},
3155479bcc7cSHerbert Xu 	{
3156479bcc7cSHerbert Xu 		.aead = {
3157479bcc7cSHerbert Xu 			.base = {
3158479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
3159479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
3160479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
3161479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
3162479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
3163479bcc7cSHerbert Xu 			},
3164479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3165479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3166479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3167479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3168479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
3169479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3170479bcc7cSHerbert Xu 		},
3171479bcc7cSHerbert Xu 		.caam = {
3172479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3173479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3174479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
3175479bcc7cSHerbert Xu 		},
3176479bcc7cSHerbert Xu 	},
3177479bcc7cSHerbert Xu 	{
3178479bcc7cSHerbert Xu 		.aead = {
3179479bcc7cSHerbert Xu 			.base = {
3180479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(aes))",
3181479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
3182479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3183479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3184479bcc7cSHerbert Xu 			},
3185479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3186479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3187479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3188479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3189479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3190479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3191479bcc7cSHerbert Xu 		},
3192479bcc7cSHerbert Xu 		.caam = {
3193479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3194479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3195479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3196479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3197479bcc7cSHerbert Xu 		},
3198479bcc7cSHerbert Xu 	},
3199479bcc7cSHerbert Xu 	{
3200479bcc7cSHerbert Xu 		.aead = {
3201479bcc7cSHerbert Xu 			.base = {
3202479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
3203479bcc7cSHerbert Xu 					    "cbc(aes)))",
3204479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
3205479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3206479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3207479bcc7cSHerbert Xu 			},
3208479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3209479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3210479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3211479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3212479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3213479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3214479bcc7cSHerbert Xu 		},
3215479bcc7cSHerbert Xu 		.caam = {
3216479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3217479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3218479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3219479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3220479bcc7cSHerbert Xu 			.geniv = true,
3221479bcc7cSHerbert Xu 		},
3222479bcc7cSHerbert Xu 	},
3223479bcc7cSHerbert Xu 	{
3224479bcc7cSHerbert Xu 		.aead = {
3225479bcc7cSHerbert Xu 			.base = {
3226479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),cbc(aes))",
3227479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
3228479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3229479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3230479bcc7cSHerbert Xu 			},
3231479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3232479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3233479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3234479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3235479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3236479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3237479bcc7cSHerbert Xu 		},
3238479bcc7cSHerbert Xu 		.caam = {
3239479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3240479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3241479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3242479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
3243479bcc7cSHerbert Xu 		},
3244479bcc7cSHerbert Xu 	},
3245479bcc7cSHerbert Xu 	{
3246479bcc7cSHerbert Xu 		.aead = {
3247479bcc7cSHerbert Xu 			.base = {
3248479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
3249479bcc7cSHerbert Xu 					    "cbc(aes)))",
3250479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3251479bcc7cSHerbert Xu 						   "hmac-sha1-cbc-aes-caam",
3252479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3253479bcc7cSHerbert Xu 			},
3254479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3255479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3256479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3257479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3258479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3259479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3260479bcc7cSHerbert Xu 		},
3261479bcc7cSHerbert Xu 		.caam = {
3262479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3263479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3264479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3265479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
3266479bcc7cSHerbert Xu 			.geniv = true,
3267479bcc7cSHerbert Xu 		},
3268479bcc7cSHerbert Xu 	},
3269479bcc7cSHerbert Xu 	{
3270479bcc7cSHerbert Xu 		.aead = {
3271479bcc7cSHerbert Xu 			.base = {
3272479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),cbc(aes))",
3273479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
3274479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3275479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3276479bcc7cSHerbert Xu 			},
3277479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3278479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3279479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3280479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3281479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3282479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3283479bcc7cSHerbert Xu 		},
3284479bcc7cSHerbert Xu 		.caam = {
3285479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3286479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3287479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3288479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
3289479bcc7cSHerbert Xu 		},
3290479bcc7cSHerbert Xu 	},
3291479bcc7cSHerbert Xu 	{
3292479bcc7cSHerbert Xu 		.aead = {
3293479bcc7cSHerbert Xu 			.base = {
3294479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
3295479bcc7cSHerbert Xu 					    "cbc(aes)))",
3296479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3297479bcc7cSHerbert Xu 						   "hmac-sha224-cbc-aes-caam",
3298479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3299479bcc7cSHerbert Xu 			},
3300479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3301479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3302479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3303479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3304479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3305479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3306479bcc7cSHerbert Xu 		},
3307479bcc7cSHerbert Xu 		.caam = {
3308479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3309479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3310479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3311479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
3312479bcc7cSHerbert Xu 			.geniv = true,
3313479bcc7cSHerbert Xu 		},
3314479bcc7cSHerbert Xu 	},
3315479bcc7cSHerbert Xu 	{
3316479bcc7cSHerbert Xu 		.aead = {
3317479bcc7cSHerbert Xu 			.base = {
3318479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),cbc(aes))",
3319479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
3320479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3321479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3322479bcc7cSHerbert Xu 			},
3323479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3324479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3325479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3326479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3327479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3328479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3329479bcc7cSHerbert Xu 		},
3330479bcc7cSHerbert Xu 		.caam = {
3331479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3332479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3333479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3334479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3335479bcc7cSHerbert Xu 		},
3336479bcc7cSHerbert Xu 	},
3337479bcc7cSHerbert Xu 	{
3338479bcc7cSHerbert Xu 		.aead = {
3339479bcc7cSHerbert Xu 			.base = {
3340479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
3341479bcc7cSHerbert Xu 					    "cbc(aes)))",
3342479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3343479bcc7cSHerbert Xu 						   "hmac-sha256-cbc-aes-caam",
3344479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3345479bcc7cSHerbert Xu 			},
3346479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3347479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3348479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3349479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3350479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3351479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3352479bcc7cSHerbert Xu 		},
3353479bcc7cSHerbert Xu 		.caam = {
3354479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3355479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3356479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3357479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3358479bcc7cSHerbert Xu 			.geniv = true,
3359479bcc7cSHerbert Xu 		},
3360479bcc7cSHerbert Xu 	},
3361479bcc7cSHerbert Xu 	{
3362479bcc7cSHerbert Xu 		.aead = {
3363479bcc7cSHerbert Xu 			.base = {
3364479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),cbc(aes))",
3365479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
3366479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3367479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3368479bcc7cSHerbert Xu 			},
3369479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3370479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3371479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3372479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3373479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3374479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3375479bcc7cSHerbert Xu 		},
3376479bcc7cSHerbert Xu 		.caam = {
3377479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3378479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3379479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3380479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3381479bcc7cSHerbert Xu 		},
3382479bcc7cSHerbert Xu 	},
3383479bcc7cSHerbert Xu 	{
3384479bcc7cSHerbert Xu 		.aead = {
3385479bcc7cSHerbert Xu 			.base = {
3386479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
3387479bcc7cSHerbert Xu 					    "cbc(aes)))",
3388479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3389479bcc7cSHerbert Xu 						   "hmac-sha384-cbc-aes-caam",
3390479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3391479bcc7cSHerbert Xu 			},
3392479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3393479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3394479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3395479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3396479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3397479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3398479bcc7cSHerbert Xu 		},
3399479bcc7cSHerbert Xu 		.caam = {
3400479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3401479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3402479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3403479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3404479bcc7cSHerbert Xu 			.geniv = true,
3405479bcc7cSHerbert Xu 		},
3406479bcc7cSHerbert Xu 	},
3407479bcc7cSHerbert Xu 	{
3408479bcc7cSHerbert Xu 		.aead = {
3409479bcc7cSHerbert Xu 			.base = {
3410479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),cbc(aes))",
3411479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
3412479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3413479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3414479bcc7cSHerbert Xu 			},
3415479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3416479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3417479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3418479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3419479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3420479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3421479bcc7cSHerbert Xu 		},
3422479bcc7cSHerbert Xu 		.caam = {
3423479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3424479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3425479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3426479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
3427479bcc7cSHerbert Xu 		},
3428479bcc7cSHerbert Xu 	},
3429479bcc7cSHerbert Xu 	{
3430479bcc7cSHerbert Xu 		.aead = {
3431479bcc7cSHerbert Xu 			.base = {
3432479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
3433479bcc7cSHerbert Xu 					    "cbc(aes)))",
3434479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3435479bcc7cSHerbert Xu 						   "hmac-sha512-cbc-aes-caam",
3436479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3437479bcc7cSHerbert Xu 			},
3438479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3439479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3440479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3441479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3442479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3443479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3444479bcc7cSHerbert Xu 		},
3445479bcc7cSHerbert Xu 		.caam = {
3446479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3447479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3448479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3449479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
3450479bcc7cSHerbert Xu 			.geniv = true,
3451479bcc7cSHerbert Xu 		},
3452479bcc7cSHerbert Xu 	},
3453479bcc7cSHerbert Xu 	{
3454479bcc7cSHerbert Xu 		.aead = {
3455479bcc7cSHerbert Xu 			.base = {
3456479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(des3_ede))",
3457479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
3458479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3459479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3460479bcc7cSHerbert Xu 			},
3461479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3462479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3463479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3464479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3465479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3466479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3467479bcc7cSHerbert Xu 		},
3468479bcc7cSHerbert Xu 		.caam = {
3469479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3470479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3471479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3472479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3473479bcc7cSHerbert Xu 		}
3474479bcc7cSHerbert Xu 	},
3475479bcc7cSHerbert Xu 	{
3476479bcc7cSHerbert Xu 		.aead = {
3477479bcc7cSHerbert Xu 			.base = {
3478479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
3479479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
3480479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
3481479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3482479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3483479bcc7cSHerbert Xu 			},
3484479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3485479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3486479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3487479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3488479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3489479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3490479bcc7cSHerbert Xu 		},
3491479bcc7cSHerbert Xu 		.caam = {
3492479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3493479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3494479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3495479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3496479bcc7cSHerbert Xu 			.geniv = true,
3497479bcc7cSHerbert Xu 		}
3498479bcc7cSHerbert Xu 	},
3499479bcc7cSHerbert Xu 	{
3500479bcc7cSHerbert Xu 		.aead = {
3501479bcc7cSHerbert Xu 			.base = {
3502479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
3503479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
3504479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
3505479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3506479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3507479bcc7cSHerbert Xu 			},
3508479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3509479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3510479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3511479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3512479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3513479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3514479bcc7cSHerbert Xu 		},
3515479bcc7cSHerbert Xu 		.caam = {
3516479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3517479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3518479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3519479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
3520479bcc7cSHerbert Xu 		},
3521479bcc7cSHerbert Xu 	},
3522479bcc7cSHerbert Xu 	{
3523479bcc7cSHerbert Xu 		.aead = {
3524479bcc7cSHerbert Xu 			.base = {
3525479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
3526479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
3527479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3528479bcc7cSHerbert Xu 						   "hmac-sha1-"
3529479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3530479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3531479bcc7cSHerbert Xu 			},
3532479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3533479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3534479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3535479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3536479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3537479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3538479bcc7cSHerbert Xu 		},
3539479bcc7cSHerbert Xu 		.caam = {
3540479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3541479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3542479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3543479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
3544479bcc7cSHerbert Xu 			.geniv = true,
3545479bcc7cSHerbert Xu 		},
3546479bcc7cSHerbert Xu 	},
3547479bcc7cSHerbert Xu 	{
3548479bcc7cSHerbert Xu 		.aead = {
3549479bcc7cSHerbert Xu 			.base = {
3550479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
3551479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
3552479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
3553479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3554479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3555479bcc7cSHerbert Xu 			},
3556479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3557479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3558479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3559479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3560479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3561479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3562479bcc7cSHerbert Xu 		},
3563479bcc7cSHerbert Xu 		.caam = {
3564479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3565479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3566479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3567479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
3568479bcc7cSHerbert Xu 		},
3569479bcc7cSHerbert Xu 	},
3570479bcc7cSHerbert Xu 	{
3571479bcc7cSHerbert Xu 		.aead = {
3572479bcc7cSHerbert Xu 			.base = {
3573479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
3574479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
3575479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3576479bcc7cSHerbert Xu 						   "hmac-sha224-"
3577479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3578479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3579479bcc7cSHerbert Xu 			},
3580479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3581479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3582479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3583479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3584479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3585479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3586479bcc7cSHerbert Xu 		},
3587479bcc7cSHerbert Xu 		.caam = {
3588479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3589479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3590479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3591479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
3592479bcc7cSHerbert Xu 			.geniv = true,
3593479bcc7cSHerbert Xu 		},
3594479bcc7cSHerbert Xu 	},
3595479bcc7cSHerbert Xu 	{
3596479bcc7cSHerbert Xu 		.aead = {
3597479bcc7cSHerbert Xu 			.base = {
3598479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
3599479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
3600479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
3601479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3602479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3603479bcc7cSHerbert Xu 			},
3604479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3605479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3606479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3607479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3608479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3609479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3610479bcc7cSHerbert Xu 		},
3611479bcc7cSHerbert Xu 		.caam = {
3612479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3613479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3614479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3615479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3616479bcc7cSHerbert Xu 		},
3617479bcc7cSHerbert Xu 	},
3618479bcc7cSHerbert Xu 	{
3619479bcc7cSHerbert Xu 		.aead = {
3620479bcc7cSHerbert Xu 			.base = {
3621479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
3622479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
3623479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3624479bcc7cSHerbert Xu 						   "hmac-sha256-"
3625479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3626479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3627479bcc7cSHerbert Xu 			},
3628479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3629479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3630479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3631479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3632479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3633479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3634479bcc7cSHerbert Xu 		},
3635479bcc7cSHerbert Xu 		.caam = {
3636479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3637479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3638479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3639479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3640479bcc7cSHerbert Xu 			.geniv = true,
3641479bcc7cSHerbert Xu 		},
3642479bcc7cSHerbert Xu 	},
3643479bcc7cSHerbert Xu 	{
3644479bcc7cSHerbert Xu 		.aead = {
3645479bcc7cSHerbert Xu 			.base = {
3646479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
3647479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
3648479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
3649479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3650479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3651479bcc7cSHerbert Xu 			},
3652479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3653479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3654479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3655479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3656479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3657479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3658479bcc7cSHerbert Xu 		},
3659479bcc7cSHerbert Xu 		.caam = {
3660479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3661479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3662479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3663479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3664479bcc7cSHerbert Xu 		},
3665479bcc7cSHerbert Xu 	},
3666479bcc7cSHerbert Xu 	{
3667479bcc7cSHerbert Xu 		.aead = {
3668479bcc7cSHerbert Xu 			.base = {
3669479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
3670479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
3671479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3672479bcc7cSHerbert Xu 						   "hmac-sha384-"
3673479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3674479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3675479bcc7cSHerbert Xu 			},
3676479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3677479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3678479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3679479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3680479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3681479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3682479bcc7cSHerbert Xu 		},
3683479bcc7cSHerbert Xu 		.caam = {
3684479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3685479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3686479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3687479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3688479bcc7cSHerbert Xu 			.geniv = true,
3689479bcc7cSHerbert Xu 		},
3690479bcc7cSHerbert Xu 	},
3691479bcc7cSHerbert Xu 	{
3692479bcc7cSHerbert Xu 		.aead = {
3693479bcc7cSHerbert Xu 			.base = {
3694479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
3695479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
3696479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
3697479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3698479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3699479bcc7cSHerbert Xu 			},
3700479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3701479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3702479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3703479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3704479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3705479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3706479bcc7cSHerbert Xu 		},
3707479bcc7cSHerbert Xu 		.caam = {
3708479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3709479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3710479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3711479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
3712479bcc7cSHerbert Xu 		},
3713479bcc7cSHerbert Xu 	},
3714479bcc7cSHerbert Xu 	{
3715479bcc7cSHerbert Xu 		.aead = {
3716479bcc7cSHerbert Xu 			.base = {
3717479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
3718479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
3719479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3720479bcc7cSHerbert Xu 						   "hmac-sha512-"
3721479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3722479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3723479bcc7cSHerbert Xu 			},
3724479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3725479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3726479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3727479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3728479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3729479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3730479bcc7cSHerbert Xu 		},
3731479bcc7cSHerbert Xu 		.caam = {
3732479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3733479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3734479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3735479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
3736479bcc7cSHerbert Xu 			.geniv = true,
3737479bcc7cSHerbert Xu 		},
3738479bcc7cSHerbert Xu 	},
3739479bcc7cSHerbert Xu 	{
3740479bcc7cSHerbert Xu 		.aead = {
3741479bcc7cSHerbert Xu 			.base = {
3742479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(des))",
3743479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
3744479bcc7cSHerbert Xu 						   "cbc-des-caam",
3745479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3746479bcc7cSHerbert Xu 			},
3747479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3748479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3749479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3750479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3751479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3752479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3753479bcc7cSHerbert Xu 		},
3754479bcc7cSHerbert Xu 		.caam = {
3755479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3756479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3757479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3758479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3759479bcc7cSHerbert Xu 		},
3760479bcc7cSHerbert Xu 	},
3761479bcc7cSHerbert Xu 	{
3762479bcc7cSHerbert Xu 		.aead = {
3763479bcc7cSHerbert Xu 			.base = {
3764479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
3765479bcc7cSHerbert Xu 					    "cbc(des)))",
3766479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
3767479bcc7cSHerbert Xu 						   "cbc-des-caam",
3768479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3769479bcc7cSHerbert Xu 			},
3770479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3771479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3772479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3773479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3774479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3775479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3776479bcc7cSHerbert Xu 		},
3777479bcc7cSHerbert Xu 		.caam = {
3778479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3779479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3780479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3781479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3782479bcc7cSHerbert Xu 			.geniv = true,
3783479bcc7cSHerbert Xu 		},
3784479bcc7cSHerbert Xu 	},
3785479bcc7cSHerbert Xu 	{
3786479bcc7cSHerbert Xu 		.aead = {
3787479bcc7cSHerbert Xu 			.base = {
3788479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),cbc(des))",
3789479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
3790479bcc7cSHerbert Xu 						   "cbc-des-caam",
3791479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3792479bcc7cSHerbert Xu 			},
3793479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3794479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3795479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3796479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3797479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3798479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3799479bcc7cSHerbert Xu 		},
3800479bcc7cSHerbert Xu 		.caam = {
3801479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3802479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3803479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3804479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
3805479bcc7cSHerbert Xu 		},
3806479bcc7cSHerbert Xu 	},
3807479bcc7cSHerbert Xu 	{
3808479bcc7cSHerbert Xu 		.aead = {
3809479bcc7cSHerbert Xu 			.base = {
3810479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
3811479bcc7cSHerbert Xu 					    "cbc(des)))",
3812479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3813479bcc7cSHerbert Xu 						   "hmac-sha1-cbc-des-caam",
3814479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3815479bcc7cSHerbert Xu 			},
3816479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3817479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3818479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3819479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3820479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3821479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3822479bcc7cSHerbert Xu 		},
3823479bcc7cSHerbert Xu 		.caam = {
3824479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3825479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3826479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3827479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
3828479bcc7cSHerbert Xu 			.geniv = true,
3829479bcc7cSHerbert Xu 		},
3830479bcc7cSHerbert Xu 	},
3831479bcc7cSHerbert Xu 	{
3832479bcc7cSHerbert Xu 		.aead = {
3833479bcc7cSHerbert Xu 			.base = {
3834479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),cbc(des))",
3835479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
3836479bcc7cSHerbert Xu 						   "cbc-des-caam",
3837479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3838479bcc7cSHerbert Xu 			},
3839479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3840479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3841479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3842479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3843479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3844479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3845479bcc7cSHerbert Xu 		},
3846479bcc7cSHerbert Xu 		.caam = {
3847479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3848479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3849479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3850479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
3851479bcc7cSHerbert Xu 		},
3852479bcc7cSHerbert Xu 	},
3853479bcc7cSHerbert Xu 	{
3854479bcc7cSHerbert Xu 		.aead = {
3855479bcc7cSHerbert Xu 			.base = {
3856479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
3857479bcc7cSHerbert Xu 					    "cbc(des)))",
3858479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3859479bcc7cSHerbert Xu 						   "hmac-sha224-cbc-des-caam",
3860479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3861479bcc7cSHerbert Xu 			},
3862479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3863479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3864479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3865479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3866479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3867479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3868479bcc7cSHerbert Xu 		},
3869479bcc7cSHerbert Xu 		.caam = {
3870479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3871479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3872479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3873479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
3874479bcc7cSHerbert Xu 			.geniv = true,
3875479bcc7cSHerbert Xu 		},
3876479bcc7cSHerbert Xu 	},
3877479bcc7cSHerbert Xu 	{
3878479bcc7cSHerbert Xu 		.aead = {
3879479bcc7cSHerbert Xu 			.base = {
3880479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),cbc(des))",
3881479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
3882479bcc7cSHerbert Xu 						   "cbc-des-caam",
3883479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3884479bcc7cSHerbert Xu 			},
3885479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3886479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3887479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3888479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3889479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3890479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3891479bcc7cSHerbert Xu 		},
3892479bcc7cSHerbert Xu 		.caam = {
3893479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3894479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3895479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3896479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3897479bcc7cSHerbert Xu 		},
3898479bcc7cSHerbert Xu 	},
3899479bcc7cSHerbert Xu 	{
3900479bcc7cSHerbert Xu 		.aead = {
3901479bcc7cSHerbert Xu 			.base = {
3902479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
3903479bcc7cSHerbert Xu 					    "cbc(des)))",
3904479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3905479bcc7cSHerbert Xu 						   "hmac-sha256-cbc-des-caam",
3906479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3907479bcc7cSHerbert Xu 			},
3908479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3909479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3910479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3911479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3912479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3913479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3914479bcc7cSHerbert Xu 		},
3915479bcc7cSHerbert Xu 		.caam = {
3916479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3917479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3918479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3919479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3920479bcc7cSHerbert Xu 			.geniv = true,
3921479bcc7cSHerbert Xu 		},
3922479bcc7cSHerbert Xu 	},
3923479bcc7cSHerbert Xu 	{
3924479bcc7cSHerbert Xu 		.aead = {
3925479bcc7cSHerbert Xu 			.base = {
3926479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),cbc(des))",
3927479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
3928479bcc7cSHerbert Xu 						   "cbc-des-caam",
3929479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3930479bcc7cSHerbert Xu 			},
3931479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3932479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3933479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3934479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3935479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3936479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3937479bcc7cSHerbert Xu 		},
3938479bcc7cSHerbert Xu 		.caam = {
3939479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3940479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3941479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3942479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3943479bcc7cSHerbert Xu 		},
3944479bcc7cSHerbert Xu 	},
3945479bcc7cSHerbert Xu 	{
3946479bcc7cSHerbert Xu 		.aead = {
3947479bcc7cSHerbert Xu 			.base = {
3948479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
3949479bcc7cSHerbert Xu 					    "cbc(des)))",
3950479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3951479bcc7cSHerbert Xu 						   "hmac-sha384-cbc-des-caam",
3952479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3953479bcc7cSHerbert Xu 			},
3954479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3955479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3956479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3957479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3958479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3959479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3960479bcc7cSHerbert Xu 		},
3961479bcc7cSHerbert Xu 		.caam = {
3962479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3963479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3964479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3965479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3966479bcc7cSHerbert Xu 			.geniv = true,
3967479bcc7cSHerbert Xu 		},
3968479bcc7cSHerbert Xu 	},
3969479bcc7cSHerbert Xu 	{
3970479bcc7cSHerbert Xu 		.aead = {
3971479bcc7cSHerbert Xu 			.base = {
3972479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),cbc(des))",
3973479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
3974479bcc7cSHerbert Xu 						   "cbc-des-caam",
3975479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3976479bcc7cSHerbert Xu 			},
3977479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3978479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3979479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3980479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3981479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3982479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3983479bcc7cSHerbert Xu 		},
3984479bcc7cSHerbert Xu 		.caam = {
3985479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3986479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3987479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3988479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
3989479bcc7cSHerbert Xu 		},
3990479bcc7cSHerbert Xu 	},
3991479bcc7cSHerbert Xu 	{
3992479bcc7cSHerbert Xu 		.aead = {
3993479bcc7cSHerbert Xu 			.base = {
3994479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
3995479bcc7cSHerbert Xu 					    "cbc(des)))",
3996479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3997479bcc7cSHerbert Xu 						   "hmac-sha512-cbc-des-caam",
3998479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3999479bcc7cSHerbert Xu 			},
4000479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4001479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4002479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4003479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
4004479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
4005479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
4006479bcc7cSHerbert Xu 		},
4007479bcc7cSHerbert Xu 		.caam = {
4008479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
4009479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
4010479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4011479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
4012479bcc7cSHerbert Xu 			.geniv = true,
4013479bcc7cSHerbert Xu 		},
4014479bcc7cSHerbert Xu 	},
4015479bcc7cSHerbert Xu 	{
4016479bcc7cSHerbert Xu 		.aead = {
4017479bcc7cSHerbert Xu 			.base = {
4018479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),"
4019479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
4020479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
4021479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4022479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4023479bcc7cSHerbert Xu 			},
4024479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4025479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4026479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4027479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
4028479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4029479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
4030479bcc7cSHerbert Xu 		},
4031479bcc7cSHerbert Xu 		.caam = {
4032479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4033479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4034479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
4035479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4036479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
4037479bcc7cSHerbert Xu 			.rfc3686 = true,
4038479bcc7cSHerbert Xu 		},
4039479bcc7cSHerbert Xu 	},
4040479bcc7cSHerbert Xu 	{
4041479bcc7cSHerbert Xu 		.aead = {
4042479bcc7cSHerbert Xu 			.base = {
4043479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
4044479bcc7cSHerbert Xu 					    "hmac(md5),rfc3686(ctr(aes))))",
4045479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-md5-"
4046479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4047479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4048479bcc7cSHerbert Xu 			},
4049479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4050479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4051479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4052479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
4053479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4054479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
4055479bcc7cSHerbert Xu 		},
4056479bcc7cSHerbert Xu 		.caam = {
4057479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4058479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4059479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
4060479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4061479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
4062479bcc7cSHerbert Xu 			.rfc3686 = true,
4063479bcc7cSHerbert Xu 			.geniv = true,
4064479bcc7cSHerbert Xu 		},
4065479bcc7cSHerbert Xu 	},
4066479bcc7cSHerbert Xu 	{
4067479bcc7cSHerbert Xu 		.aead = {
4068479bcc7cSHerbert Xu 			.base = {
4069479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
4070479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
4071479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
4072479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4073479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4074479bcc7cSHerbert Xu 			},
4075479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4076479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4077479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4078479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
4079479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4080479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
4081479bcc7cSHerbert Xu 		},
4082479bcc7cSHerbert Xu 		.caam = {
4083479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4084479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4085479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
4086479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4087479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
4088479bcc7cSHerbert Xu 			.rfc3686 = true,
4089479bcc7cSHerbert Xu 		},
4090479bcc7cSHerbert Xu 	},
4091479bcc7cSHerbert Xu 	{
4092479bcc7cSHerbert Xu 		.aead = {
4093479bcc7cSHerbert Xu 			.base = {
4094479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
4095479bcc7cSHerbert Xu 					    "hmac(sha1),rfc3686(ctr(aes))))",
4096479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha1-"
4097479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4098479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4099479bcc7cSHerbert Xu 			},
4100479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4101479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4102479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4103479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
4104479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4105479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
4106479bcc7cSHerbert Xu 		},
4107479bcc7cSHerbert Xu 		.caam = {
4108479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4109479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4110479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
4111479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4112479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
4113479bcc7cSHerbert Xu 			.rfc3686 = true,
4114479bcc7cSHerbert Xu 			.geniv = true,
4115479bcc7cSHerbert Xu 		},
4116479bcc7cSHerbert Xu 	},
4117479bcc7cSHerbert Xu 	{
4118479bcc7cSHerbert Xu 		.aead = {
4119479bcc7cSHerbert Xu 			.base = {
4120479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
4121479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
4122479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
4123479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4124479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4125479bcc7cSHerbert Xu 			},
4126479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4127479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4128479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4129479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
4130479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4131479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
4132479bcc7cSHerbert Xu 		},
4133479bcc7cSHerbert Xu 		.caam = {
4134479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4135479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4136479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
4137479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4138479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
4139479bcc7cSHerbert Xu 			.rfc3686 = true,
4140479bcc7cSHerbert Xu 		},
4141479bcc7cSHerbert Xu 	},
4142479bcc7cSHerbert Xu 	{
4143479bcc7cSHerbert Xu 		.aead = {
4144479bcc7cSHerbert Xu 			.base = {
4145479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
4146479bcc7cSHerbert Xu 					    "hmac(sha224),rfc3686(ctr(aes))))",
4147479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha224-"
4148479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4149479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4150479bcc7cSHerbert Xu 			},
4151479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4152479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4153479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4154479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
4155479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4156479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
4157479bcc7cSHerbert Xu 		},
4158479bcc7cSHerbert Xu 		.caam = {
4159479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4160479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4161479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
4162479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4163479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
4164479bcc7cSHerbert Xu 			.rfc3686 = true,
4165479bcc7cSHerbert Xu 			.geniv = true,
4166479bcc7cSHerbert Xu 		},
4167479bcc7cSHerbert Xu 	},
4168479bcc7cSHerbert Xu 	{
4169479bcc7cSHerbert Xu 		.aead = {
4170479bcc7cSHerbert Xu 			.base = {
4171479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
4172479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
4173479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
4174479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4175479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4176479bcc7cSHerbert Xu 			},
4177479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4178479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4179479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4180479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
4181479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4182479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
4183479bcc7cSHerbert Xu 		},
4184479bcc7cSHerbert Xu 		.caam = {
4185479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4186479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4187479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
4188479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4189479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
4190479bcc7cSHerbert Xu 			.rfc3686 = true,
4191479bcc7cSHerbert Xu 		},
4192479bcc7cSHerbert Xu 	},
4193479bcc7cSHerbert Xu 	{
4194479bcc7cSHerbert Xu 		.aead = {
4195479bcc7cSHerbert Xu 			.base = {
4196479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha256),"
4197479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
4198479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha256-"
4199479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4200479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4201479bcc7cSHerbert Xu 			},
4202479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4203479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4204479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4205479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
4206479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4207479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
4208479bcc7cSHerbert Xu 		},
4209479bcc7cSHerbert Xu 		.caam = {
4210479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4211479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4212479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
4213479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4214479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
4215479bcc7cSHerbert Xu 			.rfc3686 = true,
4216479bcc7cSHerbert Xu 			.geniv = true,
4217479bcc7cSHerbert Xu 		},
4218479bcc7cSHerbert Xu 	},
4219479bcc7cSHerbert Xu 	{
4220479bcc7cSHerbert Xu 		.aead = {
4221479bcc7cSHerbert Xu 			.base = {
4222479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
4223479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
4224479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
4225479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4226479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4227479bcc7cSHerbert Xu 			},
4228479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4229479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4230479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4231479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
4232479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4233479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
4234479bcc7cSHerbert Xu 		},
4235479bcc7cSHerbert Xu 		.caam = {
4236479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4237479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4238479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
4239479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4240479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
4241479bcc7cSHerbert Xu 			.rfc3686 = true,
4242479bcc7cSHerbert Xu 		},
4243479bcc7cSHerbert Xu 	},
4244479bcc7cSHerbert Xu 	{
4245479bcc7cSHerbert Xu 		.aead = {
4246479bcc7cSHerbert Xu 			.base = {
4247479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha384),"
4248479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
4249479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha384-"
4250479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4251479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4252479bcc7cSHerbert Xu 			},
4253479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4254479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4255479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4256479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
4257479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4258479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
4259479bcc7cSHerbert Xu 		},
4260479bcc7cSHerbert Xu 		.caam = {
4261479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4262479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4263479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
4264479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4265479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
4266479bcc7cSHerbert Xu 			.rfc3686 = true,
4267479bcc7cSHerbert Xu 			.geniv = true,
4268479bcc7cSHerbert Xu 		},
4269479bcc7cSHerbert Xu 	},
4270479bcc7cSHerbert Xu 	{
4271479bcc7cSHerbert Xu 		.aead = {
4272479bcc7cSHerbert Xu 			.base = {
4273479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
4274479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
4275479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
4276479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4277479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4278479bcc7cSHerbert Xu 			},
4279479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4280479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4281479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4282479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
4283479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4284479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
4285479bcc7cSHerbert Xu 		},
4286479bcc7cSHerbert Xu 		.caam = {
4287479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4288479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4289479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
4290479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4291479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
4292479bcc7cSHerbert Xu 			.rfc3686 = true,
4293479bcc7cSHerbert Xu 		},
4294479bcc7cSHerbert Xu 	},
4295479bcc7cSHerbert Xu 	{
4296479bcc7cSHerbert Xu 		.aead = {
4297479bcc7cSHerbert Xu 			.base = {
4298479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha512),"
4299479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
4300479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha512-"
4301479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4302479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4303479bcc7cSHerbert Xu 			},
4304479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4305479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4306479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4307479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
4308479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4309479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
4310479bcc7cSHerbert Xu 		},
4311479bcc7cSHerbert Xu 		.caam = {
4312479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4313479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4314479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
4315479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4316479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
4317479bcc7cSHerbert Xu 			.rfc3686 = true,
4318479bcc7cSHerbert Xu 			.geniv = true,
4319479bcc7cSHerbert Xu 		},
4320479bcc7cSHerbert Xu 	},
4321f2147b88SHerbert Xu };
4322f2147b88SHerbert Xu 
4323f2147b88SHerbert Xu struct caam_crypto_alg {
4324f2147b88SHerbert Xu 	struct crypto_alg crypto_alg;
4325f2147b88SHerbert Xu 	struct list_head entry;
4326f2147b88SHerbert Xu 	struct caam_alg_entry caam;
4327f2147b88SHerbert Xu };
4328f2147b88SHerbert Xu 
4329f2147b88SHerbert Xu static int caam_init_common(struct caam_ctx *ctx, struct caam_alg_entry *caam)
4330f2147b88SHerbert Xu {
4331f2147b88SHerbert Xu 	ctx->jrdev = caam_jr_alloc();
4332f2147b88SHerbert Xu 	if (IS_ERR(ctx->jrdev)) {
4333f2147b88SHerbert Xu 		pr_err("Job Ring Device allocation for transform failed\n");
4334f2147b88SHerbert Xu 		return PTR_ERR(ctx->jrdev);
4335f2147b88SHerbert Xu 	}
4336f2147b88SHerbert Xu 
4337f2147b88SHerbert Xu 	/* copy descriptor header template value */
4338f2147b88SHerbert Xu 	ctx->class1_alg_type = OP_TYPE_CLASS1_ALG | caam->class1_alg_type;
4339f2147b88SHerbert Xu 	ctx->class2_alg_type = OP_TYPE_CLASS2_ALG | caam->class2_alg_type;
4340f2147b88SHerbert Xu 	ctx->alg_op = OP_TYPE_CLASS2_ALG | caam->alg_op;
4341f2147b88SHerbert Xu 
4342f2147b88SHerbert Xu 	return 0;
4343f2147b88SHerbert Xu }
4344f2147b88SHerbert Xu 
43458e8ec596SKim Phillips static int caam_cra_init(struct crypto_tfm *tfm)
43468e8ec596SKim Phillips {
43478e8ec596SKim Phillips 	struct crypto_alg *alg = tfm->__crt_alg;
43488e8ec596SKim Phillips 	struct caam_crypto_alg *caam_alg =
43498e8ec596SKim Phillips 		 container_of(alg, struct caam_crypto_alg, crypto_alg);
43508e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_tfm_ctx(tfm);
43518e8ec596SKim Phillips 
4352f2147b88SHerbert Xu 	return caam_init_common(ctx, &caam_alg->caam);
4353cfc6f11bSRuchika Gupta }
43548e8ec596SKim Phillips 
4355f2147b88SHerbert Xu static int caam_aead_init(struct crypto_aead *tfm)
43568e8ec596SKim Phillips {
4357f2147b88SHerbert Xu 	struct aead_alg *alg = crypto_aead_alg(tfm);
4358f2147b88SHerbert Xu 	struct caam_aead_alg *caam_alg =
4359f2147b88SHerbert Xu 		 container_of(alg, struct caam_aead_alg, aead);
4360f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(tfm);
43618e8ec596SKim Phillips 
4362f2147b88SHerbert Xu 	return caam_init_common(ctx, &caam_alg->caam);
4363f2147b88SHerbert Xu }
4364f2147b88SHerbert Xu 
4365f2147b88SHerbert Xu static void caam_exit_common(struct caam_ctx *ctx)
4366f2147b88SHerbert Xu {
43671acebad3SYuan Kang 	if (ctx->sh_desc_enc_dma &&
43681acebad3SYuan Kang 	    !dma_mapping_error(ctx->jrdev, ctx->sh_desc_enc_dma))
43691acebad3SYuan Kang 		dma_unmap_single(ctx->jrdev, ctx->sh_desc_enc_dma,
43701acebad3SYuan Kang 				 desc_bytes(ctx->sh_desc_enc), DMA_TO_DEVICE);
43711acebad3SYuan Kang 	if (ctx->sh_desc_dec_dma &&
43721acebad3SYuan Kang 	    !dma_mapping_error(ctx->jrdev, ctx->sh_desc_dec_dma))
43731acebad3SYuan Kang 		dma_unmap_single(ctx->jrdev, ctx->sh_desc_dec_dma,
43741acebad3SYuan Kang 				 desc_bytes(ctx->sh_desc_dec), DMA_TO_DEVICE);
43751acebad3SYuan Kang 	if (ctx->sh_desc_givenc_dma &&
43761acebad3SYuan Kang 	    !dma_mapping_error(ctx->jrdev, ctx->sh_desc_givenc_dma))
43771acebad3SYuan Kang 		dma_unmap_single(ctx->jrdev, ctx->sh_desc_givenc_dma,
43781acebad3SYuan Kang 				 desc_bytes(ctx->sh_desc_givenc),
43794427b1b4SKim Phillips 				 DMA_TO_DEVICE);
4380ec31eed7SHoria Geanta 	if (ctx->key_dma &&
4381ec31eed7SHoria Geanta 	    !dma_mapping_error(ctx->jrdev, ctx->key_dma))
4382ec31eed7SHoria Geanta 		dma_unmap_single(ctx->jrdev, ctx->key_dma,
4383ec31eed7SHoria Geanta 				 ctx->enckeylen + ctx->split_key_pad_len,
4384ec31eed7SHoria Geanta 				 DMA_TO_DEVICE);
4385cfc6f11bSRuchika Gupta 
4386cfc6f11bSRuchika Gupta 	caam_jr_free(ctx->jrdev);
43878e8ec596SKim Phillips }
43888e8ec596SKim Phillips 
4389f2147b88SHerbert Xu static void caam_cra_exit(struct crypto_tfm *tfm)
4390f2147b88SHerbert Xu {
4391f2147b88SHerbert Xu 	caam_exit_common(crypto_tfm_ctx(tfm));
4392f2147b88SHerbert Xu }
4393f2147b88SHerbert Xu 
4394f2147b88SHerbert Xu static void caam_aead_exit(struct crypto_aead *tfm)
4395f2147b88SHerbert Xu {
4396f2147b88SHerbert Xu 	caam_exit_common(crypto_aead_ctx(tfm));
4397f2147b88SHerbert Xu }
4398f2147b88SHerbert Xu 
43998e8ec596SKim Phillips static void __exit caam_algapi_exit(void)
44008e8ec596SKim Phillips {
44018e8ec596SKim Phillips 
44028e8ec596SKim Phillips 	struct caam_crypto_alg *t_alg, *n;
4403f2147b88SHerbert Xu 	int i;
4404f2147b88SHerbert Xu 
4405f2147b88SHerbert Xu 	for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
4406f2147b88SHerbert Xu 		struct caam_aead_alg *t_alg = driver_aeads + i;
4407f2147b88SHerbert Xu 
4408f2147b88SHerbert Xu 		if (t_alg->registered)
4409f2147b88SHerbert Xu 			crypto_unregister_aead(&t_alg->aead);
4410f2147b88SHerbert Xu 	}
44118e8ec596SKim Phillips 
4412cfc6f11bSRuchika Gupta 	if (!alg_list.next)
44138e8ec596SKim Phillips 		return;
44148e8ec596SKim Phillips 
4415cfc6f11bSRuchika Gupta 	list_for_each_entry_safe(t_alg, n, &alg_list, entry) {
44168e8ec596SKim Phillips 		crypto_unregister_alg(&t_alg->crypto_alg);
44178e8ec596SKim Phillips 		list_del(&t_alg->entry);
44188e8ec596SKim Phillips 		kfree(t_alg);
44198e8ec596SKim Phillips 	}
44208e8ec596SKim Phillips }
44218e8ec596SKim Phillips 
4422cfc6f11bSRuchika Gupta static struct caam_crypto_alg *caam_alg_alloc(struct caam_alg_template
44238e8ec596SKim Phillips 					      *template)
44248e8ec596SKim Phillips {
44258e8ec596SKim Phillips 	struct caam_crypto_alg *t_alg;
44268e8ec596SKim Phillips 	struct crypto_alg *alg;
44278e8ec596SKim Phillips 
44289c4f9733SFabio Estevam 	t_alg = kzalloc(sizeof(*t_alg), GFP_KERNEL);
44298e8ec596SKim Phillips 	if (!t_alg) {
4430cfc6f11bSRuchika Gupta 		pr_err("failed to allocate t_alg\n");
44318e8ec596SKim Phillips 		return ERR_PTR(-ENOMEM);
44328e8ec596SKim Phillips 	}
44338e8ec596SKim Phillips 
44348e8ec596SKim Phillips 	alg = &t_alg->crypto_alg;
44358e8ec596SKim Phillips 
44368e8ec596SKim Phillips 	snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", template->name);
44378e8ec596SKim Phillips 	snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
44388e8ec596SKim Phillips 		 template->driver_name);
44398e8ec596SKim Phillips 	alg->cra_module = THIS_MODULE;
44408e8ec596SKim Phillips 	alg->cra_init = caam_cra_init;
44418e8ec596SKim Phillips 	alg->cra_exit = caam_cra_exit;
44428e8ec596SKim Phillips 	alg->cra_priority = CAAM_CRA_PRIORITY;
44438e8ec596SKim Phillips 	alg->cra_blocksize = template->blocksize;
44448e8ec596SKim Phillips 	alg->cra_alignmask = 0;
44458e8ec596SKim Phillips 	alg->cra_ctxsize = sizeof(struct caam_ctx);
4446d912bb76SNikos Mavrogiannopoulos 	alg->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY |
4447d912bb76SNikos Mavrogiannopoulos 			 template->type;
4448885e9e2fSYuan Kang 	switch (template->type) {
44497222d1a3SCatalin Vasile 	case CRYPTO_ALG_TYPE_GIVCIPHER:
44507222d1a3SCatalin Vasile 		alg->cra_type = &crypto_givcipher_type;
44517222d1a3SCatalin Vasile 		alg->cra_ablkcipher = template->template_ablkcipher;
44527222d1a3SCatalin Vasile 		break;
4453acdca31dSYuan Kang 	case CRYPTO_ALG_TYPE_ABLKCIPHER:
4454acdca31dSYuan Kang 		alg->cra_type = &crypto_ablkcipher_type;
4455acdca31dSYuan Kang 		alg->cra_ablkcipher = template->template_ablkcipher;
4456acdca31dSYuan Kang 		break;
4457885e9e2fSYuan Kang 	}
44588e8ec596SKim Phillips 
4459f2147b88SHerbert Xu 	t_alg->caam.class1_alg_type = template->class1_alg_type;
4460f2147b88SHerbert Xu 	t_alg->caam.class2_alg_type = template->class2_alg_type;
4461f2147b88SHerbert Xu 	t_alg->caam.alg_op = template->alg_op;
44628e8ec596SKim Phillips 
44638e8ec596SKim Phillips 	return t_alg;
44648e8ec596SKim Phillips }
44658e8ec596SKim Phillips 
4466f2147b88SHerbert Xu static void caam_aead_alg_init(struct caam_aead_alg *t_alg)
4467f2147b88SHerbert Xu {
4468f2147b88SHerbert Xu 	struct aead_alg *alg = &t_alg->aead;
4469f2147b88SHerbert Xu 
4470f2147b88SHerbert Xu 	alg->base.cra_module = THIS_MODULE;
4471f2147b88SHerbert Xu 	alg->base.cra_priority = CAAM_CRA_PRIORITY;
4472f2147b88SHerbert Xu 	alg->base.cra_ctxsize = sizeof(struct caam_ctx);
44735e4b8c1fSHerbert Xu 	alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY;
4474f2147b88SHerbert Xu 
4475f2147b88SHerbert Xu 	alg->init = caam_aead_init;
4476f2147b88SHerbert Xu 	alg->exit = caam_aead_exit;
4477f2147b88SHerbert Xu }
4478f2147b88SHerbert Xu 
44798e8ec596SKim Phillips static int __init caam_algapi_init(void)
44808e8ec596SKim Phillips {
448135af6403SRuchika Gupta 	struct device_node *dev_node;
448235af6403SRuchika Gupta 	struct platform_device *pdev;
448335af6403SRuchika Gupta 	struct device *ctrldev;
4484bf83490eSVictoria Milhoan 	struct caam_drv_private *priv;
44858e8ec596SKim Phillips 	int i = 0, err = 0;
4486bf83490eSVictoria Milhoan 	u32 cha_vid, cha_inst, des_inst, aes_inst, md_inst;
4487bf83490eSVictoria Milhoan 	unsigned int md_limit = SHA512_DIGEST_SIZE;
4488f2147b88SHerbert Xu 	bool registered = false;
44898e8ec596SKim Phillips 
449035af6403SRuchika Gupta 	dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
449135af6403SRuchika Gupta 	if (!dev_node) {
449235af6403SRuchika Gupta 		dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
449335af6403SRuchika Gupta 		if (!dev_node)
449435af6403SRuchika Gupta 			return -ENODEV;
449535af6403SRuchika Gupta 	}
449635af6403SRuchika Gupta 
449735af6403SRuchika Gupta 	pdev = of_find_device_by_node(dev_node);
449835af6403SRuchika Gupta 	if (!pdev) {
449935af6403SRuchika Gupta 		of_node_put(dev_node);
450035af6403SRuchika Gupta 		return -ENODEV;
450135af6403SRuchika Gupta 	}
450235af6403SRuchika Gupta 
450335af6403SRuchika Gupta 	ctrldev = &pdev->dev;
450435af6403SRuchika Gupta 	priv = dev_get_drvdata(ctrldev);
450535af6403SRuchika Gupta 	of_node_put(dev_node);
450635af6403SRuchika Gupta 
450735af6403SRuchika Gupta 	/*
450835af6403SRuchika Gupta 	 * If priv is NULL, it's probably because the caam driver wasn't
450935af6403SRuchika Gupta 	 * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
451035af6403SRuchika Gupta 	 */
451135af6403SRuchika Gupta 	if (!priv)
451235af6403SRuchika Gupta 		return -ENODEV;
451335af6403SRuchika Gupta 
451435af6403SRuchika Gupta 
4515cfc6f11bSRuchika Gupta 	INIT_LIST_HEAD(&alg_list);
45168e8ec596SKim Phillips 
4517bf83490eSVictoria Milhoan 	/*
4518bf83490eSVictoria Milhoan 	 * Register crypto algorithms the device supports.
4519bf83490eSVictoria Milhoan 	 * First, detect presence and attributes of DES, AES, and MD blocks.
4520bf83490eSVictoria Milhoan 	 */
4521bf83490eSVictoria Milhoan 	cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
4522bf83490eSVictoria Milhoan 	cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
4523bf83490eSVictoria Milhoan 	des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >> CHA_ID_LS_DES_SHIFT;
4524bf83490eSVictoria Milhoan 	aes_inst = (cha_inst & CHA_ID_LS_AES_MASK) >> CHA_ID_LS_AES_SHIFT;
4525bf83490eSVictoria Milhoan 	md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
45268e8ec596SKim Phillips 
4527bf83490eSVictoria Milhoan 	/* If MD is present, limit digest size based on LP256 */
4528bf83490eSVictoria Milhoan 	if (md_inst && ((cha_vid & CHA_ID_LS_MD_MASK) == CHA_ID_LS_MD_LP256))
4529bf83490eSVictoria Milhoan 		md_limit = SHA256_DIGEST_SIZE;
4530bf83490eSVictoria Milhoan 
4531bf83490eSVictoria Milhoan 	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
4532bf83490eSVictoria Milhoan 		struct caam_crypto_alg *t_alg;
4533bf83490eSVictoria Milhoan 		struct caam_alg_template *alg = driver_algs + i;
4534bf83490eSVictoria Milhoan 		u32 alg_sel = alg->class1_alg_type & OP_ALG_ALGSEL_MASK;
4535bf83490eSVictoria Milhoan 
4536bf83490eSVictoria Milhoan 		/* Skip DES algorithms if not supported by device */
4537bf83490eSVictoria Milhoan 		if (!des_inst &&
4538bf83490eSVictoria Milhoan 		    ((alg_sel == OP_ALG_ALGSEL_3DES) ||
4539bf83490eSVictoria Milhoan 		     (alg_sel == OP_ALG_ALGSEL_DES)))
4540bf83490eSVictoria Milhoan 				continue;
4541bf83490eSVictoria Milhoan 
4542bf83490eSVictoria Milhoan 		/* Skip AES algorithms if not supported by device */
4543bf83490eSVictoria Milhoan 		if (!aes_inst && (alg_sel == OP_ALG_ALGSEL_AES))
4544bf83490eSVictoria Milhoan 				continue;
4545bf83490eSVictoria Milhoan 
4546bf83490eSVictoria Milhoan 		t_alg = caam_alg_alloc(alg);
45478e8ec596SKim Phillips 		if (IS_ERR(t_alg)) {
45488e8ec596SKim Phillips 			err = PTR_ERR(t_alg);
4549bf83490eSVictoria Milhoan 			pr_warn("%s alg allocation failed\n", alg->driver_name);
45508e8ec596SKim Phillips 			continue;
45518e8ec596SKim Phillips 		}
45528e8ec596SKim Phillips 
45538e8ec596SKim Phillips 		err = crypto_register_alg(&t_alg->crypto_alg);
45548e8ec596SKim Phillips 		if (err) {
4555cfc6f11bSRuchika Gupta 			pr_warn("%s alg registration failed\n",
45568e8ec596SKim Phillips 				t_alg->crypto_alg.cra_driver_name);
45578e8ec596SKim Phillips 			kfree(t_alg);
4558f2147b88SHerbert Xu 			continue;
45598e8ec596SKim Phillips 		}
4560f2147b88SHerbert Xu 
4561f2147b88SHerbert Xu 		list_add_tail(&t_alg->entry, &alg_list);
4562f2147b88SHerbert Xu 		registered = true;
4563f2147b88SHerbert Xu 	}
4564f2147b88SHerbert Xu 
4565f2147b88SHerbert Xu 	for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
4566f2147b88SHerbert Xu 		struct caam_aead_alg *t_alg = driver_aeads + i;
4567bf83490eSVictoria Milhoan 		u32 c1_alg_sel = t_alg->caam.class1_alg_type &
4568bf83490eSVictoria Milhoan 				 OP_ALG_ALGSEL_MASK;
4569bf83490eSVictoria Milhoan 		u32 c2_alg_sel = t_alg->caam.class2_alg_type &
4570bf83490eSVictoria Milhoan 				 OP_ALG_ALGSEL_MASK;
4571bf83490eSVictoria Milhoan 		u32 alg_aai = t_alg->caam.class1_alg_type & OP_ALG_AAI_MASK;
4572bf83490eSVictoria Milhoan 
4573bf83490eSVictoria Milhoan 		/* Skip DES algorithms if not supported by device */
4574bf83490eSVictoria Milhoan 		if (!des_inst &&
4575bf83490eSVictoria Milhoan 		    ((c1_alg_sel == OP_ALG_ALGSEL_3DES) ||
4576bf83490eSVictoria Milhoan 		     (c1_alg_sel == OP_ALG_ALGSEL_DES)))
4577bf83490eSVictoria Milhoan 				continue;
4578bf83490eSVictoria Milhoan 
4579bf83490eSVictoria Milhoan 		/* Skip AES algorithms if not supported by device */
4580bf83490eSVictoria Milhoan 		if (!aes_inst && (c1_alg_sel == OP_ALG_ALGSEL_AES))
4581bf83490eSVictoria Milhoan 				continue;
4582bf83490eSVictoria Milhoan 
4583bf83490eSVictoria Milhoan 		/*
4584bf83490eSVictoria Milhoan 		 * Check support for AES algorithms not available
4585bf83490eSVictoria Milhoan 		 * on LP devices.
4586bf83490eSVictoria Milhoan 		 */
4587bf83490eSVictoria Milhoan 		if ((cha_vid & CHA_ID_LS_AES_MASK) == CHA_ID_LS_AES_LP)
4588bf83490eSVictoria Milhoan 			if (alg_aai == OP_ALG_AAI_GCM)
4589bf83490eSVictoria Milhoan 				continue;
4590bf83490eSVictoria Milhoan 
4591bf83490eSVictoria Milhoan 		/*
4592bf83490eSVictoria Milhoan 		 * Skip algorithms requiring message digests
4593bf83490eSVictoria Milhoan 		 * if MD or MD size is not supported by device.
4594bf83490eSVictoria Milhoan 		 */
4595bf83490eSVictoria Milhoan 		if (c2_alg_sel &&
4596bf83490eSVictoria Milhoan 		    (!md_inst || (t_alg->aead.maxauthsize > md_limit)))
4597bf83490eSVictoria Milhoan 				continue;
4598f2147b88SHerbert Xu 
4599f2147b88SHerbert Xu 		caam_aead_alg_init(t_alg);
4600f2147b88SHerbert Xu 
4601f2147b88SHerbert Xu 		err = crypto_register_aead(&t_alg->aead);
4602f2147b88SHerbert Xu 		if (err) {
4603f2147b88SHerbert Xu 			pr_warn("%s alg registration failed\n",
4604f2147b88SHerbert Xu 				t_alg->aead.base.cra_driver_name);
4605f2147b88SHerbert Xu 			continue;
4606f2147b88SHerbert Xu 		}
4607f2147b88SHerbert Xu 
4608f2147b88SHerbert Xu 		t_alg->registered = true;
4609f2147b88SHerbert Xu 		registered = true;
4610f2147b88SHerbert Xu 	}
4611f2147b88SHerbert Xu 
4612f2147b88SHerbert Xu 	if (registered)
4613cfc6f11bSRuchika Gupta 		pr_info("caam algorithms registered in /proc/crypto\n");
46148e8ec596SKim Phillips 
46158e8ec596SKim Phillips 	return err;
46168e8ec596SKim Phillips }
46178e8ec596SKim Phillips 
46188e8ec596SKim Phillips module_init(caam_algapi_init);
46198e8ec596SKim Phillips module_exit(caam_algapi_exit);
46208e8ec596SKim Phillips 
46218e8ec596SKim Phillips MODULE_LICENSE("GPL");
46228e8ec596SKim Phillips MODULE_DESCRIPTION("FSL CAAM support for crypto API");
46238e8ec596SKim Phillips MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
4624