xref: /openbmc/linux/drivers/crypto/caam/caamalg.c (revision 5e4b8c1f)
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);
230daebc465SCatalin Vasile 		append_load_imm_u32(desc, *nonce, LDST_CLASS_IND_CCB |
231daebc465SCatalin Vasile 				    LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
232daebc465SCatalin Vasile 		append_move(desc,
233daebc465SCatalin Vasile 			    MOVE_SRC_OUTFIFO |
234daebc465SCatalin Vasile 			    MOVE_DEST_CLASS1CTX |
235daebc465SCatalin Vasile 			    (16 << MOVE_OFFSET_SHIFT) |
236daebc465SCatalin Vasile 			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
2371acebad3SYuan Kang 	}
2381acebad3SYuan Kang }
2391acebad3SYuan Kang 
2401acebad3SYuan Kang static void init_sh_desc_key_aead(u32 *desc, struct caam_ctx *ctx,
241daebc465SCatalin Vasile 				  int keys_fit_inline, bool is_rfc3686)
2421acebad3SYuan Kang {
2431acebad3SYuan Kang 	u32 *key_jump_cmd;
2441acebad3SYuan Kang 
245daebc465SCatalin Vasile 	/* Note: Context registers are saved. */
246daebc465SCatalin Vasile 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
2471acebad3SYuan Kang 
2481acebad3SYuan Kang 	/* Skip if already shared */
2491acebad3SYuan Kang 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
2501acebad3SYuan Kang 				   JUMP_COND_SHRD);
2511acebad3SYuan Kang 
252daebc465SCatalin Vasile 	append_key_aead(desc, ctx, keys_fit_inline, is_rfc3686);
2531acebad3SYuan Kang 
2541acebad3SYuan Kang 	set_jump_tgt_here(desc, key_jump_cmd);
2551acebad3SYuan Kang }
2561acebad3SYuan Kang 
257ae4a825fSHoria Geanta static int aead_null_set_sh_desc(struct crypto_aead *aead)
258ae4a825fSHoria Geanta {
259ae4a825fSHoria Geanta 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
260ae4a825fSHoria Geanta 	struct device *jrdev = ctx->jrdev;
261ae4a825fSHoria Geanta 	bool keys_fit_inline = false;
262ae4a825fSHoria Geanta 	u32 *key_jump_cmd, *jump_cmd, *read_move_cmd, *write_move_cmd;
263ae4a825fSHoria Geanta 	u32 *desc;
264ae4a825fSHoria Geanta 
265ae4a825fSHoria Geanta 	/*
266ae4a825fSHoria Geanta 	 * Job Descriptor and Shared Descriptors
267ae4a825fSHoria Geanta 	 * must all fit into the 64-word Descriptor h/w Buffer
268ae4a825fSHoria Geanta 	 */
269479bcc7cSHerbert Xu 	if (DESC_AEAD_NULL_ENC_LEN + AEAD_DESC_JOB_IO_LEN +
270ae4a825fSHoria Geanta 	    ctx->split_key_pad_len <= CAAM_DESC_BYTES_MAX)
271ae4a825fSHoria Geanta 		keys_fit_inline = true;
272ae4a825fSHoria Geanta 
273479bcc7cSHerbert Xu 	/* aead_encrypt shared descriptor */
274ae4a825fSHoria Geanta 	desc = ctx->sh_desc_enc;
275ae4a825fSHoria Geanta 
276ae4a825fSHoria Geanta 	init_sh_desc(desc, HDR_SHARE_SERIAL);
277ae4a825fSHoria Geanta 
278ae4a825fSHoria Geanta 	/* Skip if already shared */
279ae4a825fSHoria Geanta 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
280ae4a825fSHoria Geanta 				   JUMP_COND_SHRD);
281ae4a825fSHoria Geanta 	if (keys_fit_inline)
282ae4a825fSHoria Geanta 		append_key_as_imm(desc, ctx->key, ctx->split_key_pad_len,
283ae4a825fSHoria Geanta 				  ctx->split_key_len, CLASS_2 |
284ae4a825fSHoria Geanta 				  KEY_DEST_MDHA_SPLIT | KEY_ENC);
285ae4a825fSHoria Geanta 	else
286ae4a825fSHoria Geanta 		append_key(desc, ctx->key_dma, ctx->split_key_len, CLASS_2 |
287ae4a825fSHoria Geanta 			   KEY_DEST_MDHA_SPLIT | KEY_ENC);
288ae4a825fSHoria Geanta 	set_jump_tgt_here(desc, key_jump_cmd);
289ae4a825fSHoria Geanta 
290479bcc7cSHerbert Xu 	/* assoclen + cryptlen = seqinlen */
291479bcc7cSHerbert Xu 	append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
292ae4a825fSHoria Geanta 
293479bcc7cSHerbert Xu 	/* Prepare to read and write cryptlen + assoclen bytes */
294ae4a825fSHoria Geanta 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
295ae4a825fSHoria Geanta 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
296ae4a825fSHoria Geanta 
297ae4a825fSHoria Geanta 	/*
298ae4a825fSHoria Geanta 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
299ae4a825fSHoria Geanta 	 * thus need to do some magic, i.e. self-patch the descriptor
300ae4a825fSHoria Geanta 	 * buffer.
301ae4a825fSHoria Geanta 	 */
302ae4a825fSHoria Geanta 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
303ae4a825fSHoria Geanta 				    MOVE_DEST_MATH3 |
304ae4a825fSHoria Geanta 				    (0x6 << MOVE_LEN_SHIFT));
305ae4a825fSHoria Geanta 	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 |
306ae4a825fSHoria Geanta 				     MOVE_DEST_DESCBUF |
307ae4a825fSHoria Geanta 				     MOVE_WAITCOMP |
308ae4a825fSHoria Geanta 				     (0x8 << MOVE_LEN_SHIFT));
309ae4a825fSHoria Geanta 
310ae4a825fSHoria Geanta 	/* Class 2 operation */
311ae4a825fSHoria Geanta 	append_operation(desc, ctx->class2_alg_type |
312ae4a825fSHoria Geanta 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
313ae4a825fSHoria Geanta 
314ae4a825fSHoria Geanta 	/* Read and write cryptlen bytes */
315ae4a825fSHoria Geanta 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
316ae4a825fSHoria Geanta 
317ae4a825fSHoria Geanta 	set_move_tgt_here(desc, read_move_cmd);
318ae4a825fSHoria Geanta 	set_move_tgt_here(desc, write_move_cmd);
319ae4a825fSHoria Geanta 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
320ae4a825fSHoria Geanta 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
321ae4a825fSHoria Geanta 		    MOVE_AUX_LS);
322ae4a825fSHoria Geanta 
323ae4a825fSHoria Geanta 	/* Write ICV */
324ae4a825fSHoria Geanta 	append_seq_store(desc, ctx->authsize, LDST_CLASS_2_CCB |
325ae4a825fSHoria Geanta 			 LDST_SRCDST_BYTE_CONTEXT);
326ae4a825fSHoria Geanta 
327ae4a825fSHoria Geanta 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
328ae4a825fSHoria Geanta 					      desc_bytes(desc),
329ae4a825fSHoria Geanta 					      DMA_TO_DEVICE);
330ae4a825fSHoria Geanta 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
331ae4a825fSHoria Geanta 		dev_err(jrdev, "unable to map shared descriptor\n");
332ae4a825fSHoria Geanta 		return -ENOMEM;
333ae4a825fSHoria Geanta 	}
334ae4a825fSHoria Geanta #ifdef DEBUG
335ae4a825fSHoria Geanta 	print_hex_dump(KERN_ERR,
336ae4a825fSHoria Geanta 		       "aead null enc shdesc@"__stringify(__LINE__)": ",
337ae4a825fSHoria Geanta 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
338ae4a825fSHoria Geanta 		       desc_bytes(desc), 1);
339ae4a825fSHoria Geanta #endif
340ae4a825fSHoria Geanta 
341ae4a825fSHoria Geanta 	/*
342ae4a825fSHoria Geanta 	 * Job Descriptor and Shared Descriptors
343ae4a825fSHoria Geanta 	 * must all fit into the 64-word Descriptor h/w Buffer
344ae4a825fSHoria Geanta 	 */
34580cd88f2SVakul Garg 	keys_fit_inline = false;
346ae4a825fSHoria Geanta 	if (DESC_AEAD_NULL_DEC_LEN + DESC_JOB_IO_LEN +
347ae4a825fSHoria Geanta 	    ctx->split_key_pad_len <= CAAM_DESC_BYTES_MAX)
348ae4a825fSHoria Geanta 		keys_fit_inline = true;
349ae4a825fSHoria Geanta 
350ae4a825fSHoria Geanta 	desc = ctx->sh_desc_dec;
351ae4a825fSHoria Geanta 
352479bcc7cSHerbert Xu 	/* aead_decrypt shared descriptor */
353ae4a825fSHoria Geanta 	init_sh_desc(desc, HDR_SHARE_SERIAL);
354ae4a825fSHoria Geanta 
355ae4a825fSHoria Geanta 	/* Skip if already shared */
356ae4a825fSHoria Geanta 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
357ae4a825fSHoria Geanta 				   JUMP_COND_SHRD);
358ae4a825fSHoria Geanta 	if (keys_fit_inline)
359ae4a825fSHoria Geanta 		append_key_as_imm(desc, ctx->key, ctx->split_key_pad_len,
360ae4a825fSHoria Geanta 				  ctx->split_key_len, CLASS_2 |
361ae4a825fSHoria Geanta 				  KEY_DEST_MDHA_SPLIT | KEY_ENC);
362ae4a825fSHoria Geanta 	else
363ae4a825fSHoria Geanta 		append_key(desc, ctx->key_dma, ctx->split_key_len, CLASS_2 |
364ae4a825fSHoria Geanta 			   KEY_DEST_MDHA_SPLIT | KEY_ENC);
365ae4a825fSHoria Geanta 	set_jump_tgt_here(desc, key_jump_cmd);
366ae4a825fSHoria Geanta 
367ae4a825fSHoria Geanta 	/* Class 2 operation */
368ae4a825fSHoria Geanta 	append_operation(desc, ctx->class2_alg_type |
369ae4a825fSHoria Geanta 			 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON);
370ae4a825fSHoria Geanta 
371479bcc7cSHerbert Xu 	/* assoclen + cryptlen = seqoutlen */
372ae4a825fSHoria Geanta 	append_math_sub(desc, REG2, SEQOUTLEN, REG0, CAAM_CMD_SZ);
373ae4a825fSHoria Geanta 
374479bcc7cSHerbert Xu 	/* Prepare to read and write cryptlen + assoclen bytes */
375ae4a825fSHoria Geanta 	append_math_add(desc, VARSEQINLEN, ZERO, REG2, CAAM_CMD_SZ);
376ae4a825fSHoria Geanta 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG2, CAAM_CMD_SZ);
377ae4a825fSHoria Geanta 
378ae4a825fSHoria Geanta 	/*
379ae4a825fSHoria Geanta 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
380ae4a825fSHoria Geanta 	 * thus need to do some magic, i.e. self-patch the descriptor
381ae4a825fSHoria Geanta 	 * buffer.
382ae4a825fSHoria Geanta 	 */
383ae4a825fSHoria Geanta 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
384ae4a825fSHoria Geanta 				    MOVE_DEST_MATH2 |
385ae4a825fSHoria Geanta 				    (0x6 << MOVE_LEN_SHIFT));
386ae4a825fSHoria Geanta 	write_move_cmd = append_move(desc, MOVE_SRC_MATH2 |
387ae4a825fSHoria Geanta 				     MOVE_DEST_DESCBUF |
388ae4a825fSHoria Geanta 				     MOVE_WAITCOMP |
389ae4a825fSHoria Geanta 				     (0x8 << MOVE_LEN_SHIFT));
390ae4a825fSHoria Geanta 
391ae4a825fSHoria Geanta 	/* Read and write cryptlen bytes */
392ae4a825fSHoria Geanta 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
393ae4a825fSHoria Geanta 
394ae4a825fSHoria Geanta 	/*
395ae4a825fSHoria Geanta 	 * Insert a NOP here, since we need at least 4 instructions between
396ae4a825fSHoria Geanta 	 * code patching the descriptor buffer and the location being patched.
397ae4a825fSHoria Geanta 	 */
398ae4a825fSHoria Geanta 	jump_cmd = append_jump(desc, JUMP_TEST_ALL);
399ae4a825fSHoria Geanta 	set_jump_tgt_here(desc, jump_cmd);
400ae4a825fSHoria Geanta 
401ae4a825fSHoria Geanta 	set_move_tgt_here(desc, read_move_cmd);
402ae4a825fSHoria Geanta 	set_move_tgt_here(desc, write_move_cmd);
403ae4a825fSHoria Geanta 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
404ae4a825fSHoria Geanta 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
405ae4a825fSHoria Geanta 		    MOVE_AUX_LS);
406ae4a825fSHoria Geanta 	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
407ae4a825fSHoria Geanta 
408ae4a825fSHoria Geanta 	/* Load ICV */
409ae4a825fSHoria Geanta 	append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS2 |
410ae4a825fSHoria Geanta 			     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
411ae4a825fSHoria Geanta 
412ae4a825fSHoria Geanta 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
413ae4a825fSHoria Geanta 					      desc_bytes(desc),
414ae4a825fSHoria Geanta 					      DMA_TO_DEVICE);
415ae4a825fSHoria Geanta 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
416ae4a825fSHoria Geanta 		dev_err(jrdev, "unable to map shared descriptor\n");
417ae4a825fSHoria Geanta 		return -ENOMEM;
418ae4a825fSHoria Geanta 	}
419ae4a825fSHoria Geanta #ifdef DEBUG
420ae4a825fSHoria Geanta 	print_hex_dump(KERN_ERR,
421ae4a825fSHoria Geanta 		       "aead null dec shdesc@"__stringify(__LINE__)": ",
422ae4a825fSHoria Geanta 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
423ae4a825fSHoria Geanta 		       desc_bytes(desc), 1);
424ae4a825fSHoria Geanta #endif
425ae4a825fSHoria Geanta 
426ae4a825fSHoria Geanta 	return 0;
427ae4a825fSHoria Geanta }
428ae4a825fSHoria Geanta 
4291acebad3SYuan Kang static int aead_set_sh_desc(struct crypto_aead *aead)
4301acebad3SYuan Kang {
431479bcc7cSHerbert Xu 	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
432479bcc7cSHerbert Xu 						 struct caam_aead_alg, aead);
433add86d55SHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
4341acebad3SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
4351acebad3SYuan Kang 	struct device *jrdev = ctx->jrdev;
436daebc465SCatalin Vasile 	bool keys_fit_inline;
4371acebad3SYuan Kang 	u32 geniv, moveiv;
438daebc465SCatalin Vasile 	u32 ctx1_iv_off = 0;
4391acebad3SYuan Kang 	u32 *desc;
440daebc465SCatalin Vasile 	const bool ctr_mode = ((ctx->class1_alg_type & OP_ALG_AAI_MASK) ==
441daebc465SCatalin Vasile 			       OP_ALG_AAI_CTR_MOD128);
442479bcc7cSHerbert Xu 	const bool is_rfc3686 = alg->caam.rfc3686;
4431acebad3SYuan Kang 
444ae4a825fSHoria Geanta 	/* NULL encryption / decryption */
445ae4a825fSHoria Geanta 	if (!ctx->enckeylen)
446ae4a825fSHoria Geanta 		return aead_null_set_sh_desc(aead);
447ae4a825fSHoria Geanta 
4481acebad3SYuan Kang 	/*
449daebc465SCatalin Vasile 	 * AES-CTR needs to load IV in CONTEXT1 reg
450daebc465SCatalin Vasile 	 * at an offset of 128bits (16bytes)
451daebc465SCatalin Vasile 	 * CONTEXT1[255:128] = IV
452daebc465SCatalin Vasile 	 */
453daebc465SCatalin Vasile 	if (ctr_mode)
454daebc465SCatalin Vasile 		ctx1_iv_off = 16;
455daebc465SCatalin Vasile 
456daebc465SCatalin Vasile 	/*
457daebc465SCatalin Vasile 	 * RFC3686 specific:
458daebc465SCatalin Vasile 	 *	CONTEXT1[255:128] = {NONCE, IV, COUNTER}
459daebc465SCatalin Vasile 	 */
460daebc465SCatalin Vasile 	if (is_rfc3686)
461daebc465SCatalin Vasile 		ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
462daebc465SCatalin Vasile 
463479bcc7cSHerbert Xu 	if (alg->caam.geniv)
464479bcc7cSHerbert Xu 		goto skip_enc;
465479bcc7cSHerbert Xu 
466daebc465SCatalin Vasile 	/*
4671acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
4681acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
4691acebad3SYuan Kang 	 */
470daebc465SCatalin Vasile 	keys_fit_inline = false;
471479bcc7cSHerbert Xu 	if (DESC_AEAD_ENC_LEN + AUTHENC_DESC_JOB_IO_LEN +
472daebc465SCatalin Vasile 	    ctx->split_key_pad_len + ctx->enckeylen +
473daebc465SCatalin Vasile 	    (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0) <=
4741acebad3SYuan Kang 	    CAAM_DESC_BYTES_MAX)
4752af8f4a2SKim Phillips 		keys_fit_inline = true;
4761acebad3SYuan Kang 
477479bcc7cSHerbert Xu 	/* aead_encrypt shared descriptor */
4781acebad3SYuan Kang 	desc = ctx->sh_desc_enc;
4791acebad3SYuan Kang 
480daebc465SCatalin Vasile 	/* Note: Context registers are saved. */
481daebc465SCatalin Vasile 	init_sh_desc_key_aead(desc, ctx, keys_fit_inline, is_rfc3686);
4821acebad3SYuan Kang 
4831acebad3SYuan Kang 	/* Class 2 operation */
4841acebad3SYuan Kang 	append_operation(desc, ctx->class2_alg_type |
4851acebad3SYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
4861acebad3SYuan Kang 
487479bcc7cSHerbert Xu 	/* Read and write assoclen bytes */
488479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
489479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
4901acebad3SYuan Kang 
491479bcc7cSHerbert Xu 	/* Skip assoc data */
492479bcc7cSHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
4931acebad3SYuan Kang 
4941acebad3SYuan Kang 	/* read assoc before reading payload */
4951acebad3SYuan Kang 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
496479bcc7cSHerbert Xu 				      FIFOLDST_VLF);
497daebc465SCatalin Vasile 
498daebc465SCatalin Vasile 	/* Load Counter into CONTEXT1 reg */
499daebc465SCatalin Vasile 	if (is_rfc3686)
500daebc465SCatalin Vasile 		append_load_imm_u32(desc, be32_to_cpu(1), LDST_IMM |
501daebc465SCatalin Vasile 				    LDST_CLASS_1_CCB |
502daebc465SCatalin Vasile 				    LDST_SRCDST_BYTE_CONTEXT |
503daebc465SCatalin Vasile 				    ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
504daebc465SCatalin Vasile 				     LDST_OFFSET_SHIFT));
5051acebad3SYuan Kang 
5061acebad3SYuan Kang 	/* Class 1 operation */
5071acebad3SYuan Kang 	append_operation(desc, ctx->class1_alg_type |
5081acebad3SYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
5091acebad3SYuan Kang 
5101acebad3SYuan Kang 	/* Read and write cryptlen bytes */
511479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
512479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
5131acebad3SYuan Kang 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
5141acebad3SYuan Kang 
5151acebad3SYuan Kang 	/* Write ICV */
5161acebad3SYuan Kang 	append_seq_store(desc, ctx->authsize, LDST_CLASS_2_CCB |
5171acebad3SYuan Kang 			 LDST_SRCDST_BYTE_CONTEXT);
5181acebad3SYuan Kang 
5191acebad3SYuan Kang 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
5201acebad3SYuan Kang 					      desc_bytes(desc),
5211acebad3SYuan Kang 					      DMA_TO_DEVICE);
5221acebad3SYuan Kang 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
5231acebad3SYuan Kang 		dev_err(jrdev, "unable to map shared descriptor\n");
5241acebad3SYuan Kang 		return -ENOMEM;
5251acebad3SYuan Kang 	}
5261acebad3SYuan Kang #ifdef DEBUG
527514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead enc shdesc@"__stringify(__LINE__)": ",
5281acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
5291acebad3SYuan Kang 		       desc_bytes(desc), 1);
5301acebad3SYuan Kang #endif
5311acebad3SYuan Kang 
532479bcc7cSHerbert Xu skip_enc:
5331acebad3SYuan Kang 	/*
5341acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
5351acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
5361acebad3SYuan Kang 	 */
53780cd88f2SVakul Garg 	keys_fit_inline = false;
538479bcc7cSHerbert Xu 	if (DESC_AEAD_DEC_LEN + AUTHENC_DESC_JOB_IO_LEN +
539daebc465SCatalin Vasile 	    ctx->split_key_pad_len + ctx->enckeylen +
540daebc465SCatalin Vasile 	    (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0) <=
5411acebad3SYuan Kang 	    CAAM_DESC_BYTES_MAX)
5422af8f4a2SKim Phillips 		keys_fit_inline = true;
5431acebad3SYuan Kang 
544479bcc7cSHerbert Xu 	/* aead_decrypt shared descriptor */
5451acebad3SYuan Kang 	desc = ctx->sh_desc_dec;
5461acebad3SYuan Kang 
547daebc465SCatalin Vasile 	/* Note: Context registers are saved. */
548daebc465SCatalin Vasile 	init_sh_desc_key_aead(desc, ctx, keys_fit_inline, is_rfc3686);
5491acebad3SYuan Kang 
5501acebad3SYuan Kang 	/* Class 2 operation */
5511acebad3SYuan Kang 	append_operation(desc, ctx->class2_alg_type |
5521acebad3SYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON);
5531acebad3SYuan Kang 
554479bcc7cSHerbert Xu 	/* Read and write assoclen bytes */
555479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
556479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
557479bcc7cSHerbert Xu 
558479bcc7cSHerbert Xu 	/* Skip assoc data */
559479bcc7cSHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
5601acebad3SYuan Kang 
5611acebad3SYuan Kang 	/* read assoc before reading payload */
5621acebad3SYuan Kang 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
5631acebad3SYuan Kang 			     KEY_VLF);
5641acebad3SYuan Kang 
565daebc465SCatalin Vasile 	/* Load Counter into CONTEXT1 reg */
566daebc465SCatalin Vasile 	if (is_rfc3686)
567daebc465SCatalin Vasile 		append_load_imm_u32(desc, be32_to_cpu(1), LDST_IMM |
568daebc465SCatalin Vasile 				    LDST_CLASS_1_CCB |
569daebc465SCatalin Vasile 				    LDST_SRCDST_BYTE_CONTEXT |
570daebc465SCatalin Vasile 				    ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
571daebc465SCatalin Vasile 				     LDST_OFFSET_SHIFT));
572daebc465SCatalin Vasile 
573daebc465SCatalin Vasile 	/* Choose operation */
574daebc465SCatalin Vasile 	if (ctr_mode)
575daebc465SCatalin Vasile 		append_operation(desc, ctx->class1_alg_type |
576daebc465SCatalin Vasile 				 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT);
577daebc465SCatalin Vasile 	else
5781acebad3SYuan Kang 		append_dec_op1(desc, ctx->class1_alg_type);
5791acebad3SYuan Kang 
5801acebad3SYuan Kang 	/* Read and write cryptlen bytes */
581479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
582479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
5831acebad3SYuan Kang 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
5841acebad3SYuan Kang 
5851acebad3SYuan Kang 	/* Load ICV */
5861acebad3SYuan Kang 	append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS2 |
5871acebad3SYuan Kang 			     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
5881acebad3SYuan Kang 
5891acebad3SYuan Kang 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
5901acebad3SYuan Kang 					      desc_bytes(desc),
5911acebad3SYuan Kang 					      DMA_TO_DEVICE);
5921acebad3SYuan Kang 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
5931acebad3SYuan Kang 		dev_err(jrdev, "unable to map shared descriptor\n");
5941acebad3SYuan Kang 		return -ENOMEM;
5951acebad3SYuan Kang 	}
5961acebad3SYuan Kang #ifdef DEBUG
597514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead dec shdesc@"__stringify(__LINE__)": ",
5981acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
5991acebad3SYuan Kang 		       desc_bytes(desc), 1);
6001acebad3SYuan Kang #endif
6011acebad3SYuan Kang 
602479bcc7cSHerbert Xu 	if (!alg->caam.geniv)
603479bcc7cSHerbert Xu 		goto skip_givenc;
604479bcc7cSHerbert Xu 
6051acebad3SYuan Kang 	/*
6061acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
6071acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
6081acebad3SYuan Kang 	 */
60980cd88f2SVakul Garg 	keys_fit_inline = false;
610479bcc7cSHerbert Xu 	if (DESC_AEAD_GIVENC_LEN + AUTHENC_DESC_JOB_IO_LEN +
611daebc465SCatalin Vasile 	    ctx->split_key_pad_len + ctx->enckeylen +
612daebc465SCatalin Vasile 	    (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0) <=
6131acebad3SYuan Kang 	    CAAM_DESC_BYTES_MAX)
6142af8f4a2SKim Phillips 		keys_fit_inline = true;
6151acebad3SYuan Kang 
6161acebad3SYuan Kang 	/* aead_givencrypt shared descriptor */
6171acebad3SYuan Kang 	desc = ctx->sh_desc_givenc;
6181acebad3SYuan Kang 
619daebc465SCatalin Vasile 	/* Note: Context registers are saved. */
620daebc465SCatalin Vasile 	init_sh_desc_key_aead(desc, ctx, keys_fit_inline, is_rfc3686);
6211acebad3SYuan Kang 
622479bcc7cSHerbert Xu 	if (is_rfc3686)
623479bcc7cSHerbert Xu 		goto copy_iv;
624479bcc7cSHerbert Xu 
6251acebad3SYuan Kang 	/* Generate IV */
6261acebad3SYuan Kang 	geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
6271acebad3SYuan Kang 		NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 |
628add86d55SHerbert Xu 		NFIFOENTRY_PTYPE_RND | (ivsize << NFIFOENTRY_DLEN_SHIFT);
6291acebad3SYuan Kang 	append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
6301acebad3SYuan Kang 			    LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
6311acebad3SYuan Kang 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
632daebc465SCatalin Vasile 	append_move(desc, MOVE_WAITCOMP |
633daebc465SCatalin Vasile 		    MOVE_SRC_INFIFO | MOVE_DEST_CLASS1CTX |
634daebc465SCatalin Vasile 		    (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
635add86d55SHerbert Xu 		    (ivsize << MOVE_LEN_SHIFT));
6361acebad3SYuan Kang 	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
6371acebad3SYuan Kang 
638479bcc7cSHerbert Xu copy_iv:
6391acebad3SYuan Kang 	/* Copy IV to class 1 context */
640daebc465SCatalin Vasile 	append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_OUTFIFO |
641daebc465SCatalin Vasile 		    (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
642add86d55SHerbert Xu 		    (ivsize << MOVE_LEN_SHIFT));
6431acebad3SYuan Kang 
6441acebad3SYuan Kang 	/* Return to encryption */
6451acebad3SYuan Kang 	append_operation(desc, ctx->class2_alg_type |
6461acebad3SYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
6471acebad3SYuan Kang 
6481acebad3SYuan Kang 	/* ivsize + cryptlen = seqoutlen - authsize */
6491acebad3SYuan Kang 	append_math_sub_imm_u32(desc, REG3, SEQOUTLEN, IMM, ctx->authsize);
6501acebad3SYuan Kang 
651479bcc7cSHerbert Xu 	/* Read and write assoclen bytes */
652479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
653479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
654479bcc7cSHerbert Xu 
655479bcc7cSHerbert Xu 	/* Skip assoc data */
656479bcc7cSHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
6571acebad3SYuan Kang 
6581acebad3SYuan Kang 	/* read assoc before reading payload */
6591acebad3SYuan Kang 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
6601acebad3SYuan Kang 			     KEY_VLF);
6611acebad3SYuan Kang 
662daebc465SCatalin Vasile 	/* Copy iv from outfifo to class 2 fifo */
6631acebad3SYuan Kang 	moveiv = NFIFOENTRY_STYPE_OFIFO | NFIFOENTRY_DEST_CLASS2 |
664add86d55SHerbert Xu 		 NFIFOENTRY_DTYPE_MSG | (ivsize << NFIFOENTRY_DLEN_SHIFT);
6651acebad3SYuan Kang 	append_load_imm_u32(desc, moveiv, LDST_CLASS_IND_CCB |
6661acebad3SYuan Kang 			    LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
667add86d55SHerbert Xu 	append_load_imm_u32(desc, ivsize, LDST_CLASS_2_CCB |
6681acebad3SYuan Kang 			    LDST_SRCDST_WORD_DATASZ_REG | LDST_IMM);
6691acebad3SYuan Kang 
670daebc465SCatalin Vasile 	/* Load Counter into CONTEXT1 reg */
671daebc465SCatalin Vasile 	if (is_rfc3686)
672daebc465SCatalin Vasile 		append_load_imm_u32(desc, be32_to_cpu(1), LDST_IMM |
673daebc465SCatalin Vasile 				    LDST_CLASS_1_CCB |
674daebc465SCatalin Vasile 				    LDST_SRCDST_BYTE_CONTEXT |
675daebc465SCatalin Vasile 				    ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
676daebc465SCatalin Vasile 				     LDST_OFFSET_SHIFT));
677daebc465SCatalin Vasile 
6781acebad3SYuan Kang 	/* Class 1 operation */
6791acebad3SYuan Kang 	append_operation(desc, ctx->class1_alg_type |
6801acebad3SYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
6811acebad3SYuan Kang 
6821acebad3SYuan Kang 	/* Will write ivsize + cryptlen */
6831acebad3SYuan Kang 	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
6841acebad3SYuan Kang 
6851acebad3SYuan Kang 	/* Not need to reload iv */
686add86d55SHerbert Xu 	append_seq_fifo_load(desc, ivsize,
6871acebad3SYuan Kang 			     FIFOLD_CLASS_SKIP);
6881acebad3SYuan Kang 
6891acebad3SYuan Kang 	/* Will read cryptlen */
6901acebad3SYuan Kang 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
6911acebad3SYuan Kang 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
6921acebad3SYuan Kang 
6931acebad3SYuan Kang 	/* Write ICV */
6941acebad3SYuan Kang 	append_seq_store(desc, ctx->authsize, LDST_CLASS_2_CCB |
6951acebad3SYuan Kang 			 LDST_SRCDST_BYTE_CONTEXT);
6961acebad3SYuan Kang 
697479bcc7cSHerbert Xu 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
6981acebad3SYuan Kang 					      desc_bytes(desc),
6991acebad3SYuan Kang 					      DMA_TO_DEVICE);
7001acebad3SYuan Kang 	if (dma_mapping_error(jrdev, ctx->sh_desc_givenc_dma)) {
7011acebad3SYuan Kang 		dev_err(jrdev, "unable to map shared descriptor\n");
7021acebad3SYuan Kang 		return -ENOMEM;
7031acebad3SYuan Kang 	}
7041acebad3SYuan Kang #ifdef DEBUG
705514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead givenc shdesc@"__stringify(__LINE__)": ",
7061acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
7071acebad3SYuan Kang 		       desc_bytes(desc), 1);
7081acebad3SYuan Kang #endif
7091acebad3SYuan Kang 
710479bcc7cSHerbert Xu skip_givenc:
7111acebad3SYuan Kang 	return 0;
7121acebad3SYuan Kang }
7131acebad3SYuan Kang 
7140e479300SYuan Kang static int aead_setauthsize(struct crypto_aead *authenc,
7158e8ec596SKim Phillips 				    unsigned int authsize)
7168e8ec596SKim Phillips {
7178e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
7188e8ec596SKim Phillips 
7198e8ec596SKim Phillips 	ctx->authsize = authsize;
7201acebad3SYuan Kang 	aead_set_sh_desc(authenc);
7218e8ec596SKim Phillips 
7228e8ec596SKim Phillips 	return 0;
7238e8ec596SKim Phillips }
7248e8ec596SKim Phillips 
7253ef8d945STudor Ambarus static int gcm_set_sh_desc(struct crypto_aead *aead)
7263ef8d945STudor Ambarus {
7273ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
7283ef8d945STudor Ambarus 	struct device *jrdev = ctx->jrdev;
7293ef8d945STudor Ambarus 	bool keys_fit_inline = false;
7303ef8d945STudor Ambarus 	u32 *key_jump_cmd, *zero_payload_jump_cmd,
7313ef8d945STudor Ambarus 	    *zero_assoc_jump_cmd1, *zero_assoc_jump_cmd2;
7323ef8d945STudor Ambarus 	u32 *desc;
7333ef8d945STudor Ambarus 
7343ef8d945STudor Ambarus 	if (!ctx->enckeylen || !ctx->authsize)
7353ef8d945STudor Ambarus 		return 0;
7363ef8d945STudor Ambarus 
7373ef8d945STudor Ambarus 	/*
7383ef8d945STudor Ambarus 	 * AES GCM encrypt shared descriptor
7393ef8d945STudor Ambarus 	 * Job Descriptor and Shared Descriptor
7403ef8d945STudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
7413ef8d945STudor Ambarus 	 */
742f2147b88SHerbert Xu 	if (DESC_GCM_ENC_LEN + GCM_DESC_JOB_IO_LEN +
7433ef8d945STudor Ambarus 	    ctx->enckeylen <= CAAM_DESC_BYTES_MAX)
7443ef8d945STudor Ambarus 		keys_fit_inline = true;
7453ef8d945STudor Ambarus 
7463ef8d945STudor Ambarus 	desc = ctx->sh_desc_enc;
7473ef8d945STudor Ambarus 
7483ef8d945STudor Ambarus 	init_sh_desc(desc, HDR_SHARE_SERIAL);
7493ef8d945STudor Ambarus 
7503ef8d945STudor Ambarus 	/* skip key loading if they are loaded due to sharing */
7513ef8d945STudor Ambarus 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
7523ef8d945STudor Ambarus 				   JUMP_COND_SHRD | JUMP_COND_SELF);
7533ef8d945STudor Ambarus 	if (keys_fit_inline)
7543ef8d945STudor Ambarus 		append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
7553ef8d945STudor Ambarus 				  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
7563ef8d945STudor Ambarus 	else
7573ef8d945STudor Ambarus 		append_key(desc, ctx->key_dma, ctx->enckeylen,
7583ef8d945STudor Ambarus 			   CLASS_1 | KEY_DEST_CLASS_REG);
7593ef8d945STudor Ambarus 	set_jump_tgt_here(desc, key_jump_cmd);
7603ef8d945STudor Ambarus 
7613ef8d945STudor Ambarus 	/* class 1 operation */
7623ef8d945STudor Ambarus 	append_operation(desc, ctx->class1_alg_type |
7633ef8d945STudor Ambarus 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
7643ef8d945STudor Ambarus 
765f2147b88SHerbert Xu 	/* if assoclen + cryptlen is ZERO, skip to ICV write */
766f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
767f2147b88SHerbert Xu 	zero_assoc_jump_cmd2 = append_jump(desc, JUMP_TEST_ALL |
7683ef8d945STudor Ambarus 						 JUMP_COND_MATH_Z);
7693ef8d945STudor Ambarus 
7703ef8d945STudor Ambarus 	/* if assoclen is ZERO, skip reading the assoc data */
771f2147b88SHerbert Xu 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
7723ef8d945STudor Ambarus 	zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
7733ef8d945STudor Ambarus 						 JUMP_COND_MATH_Z);
7743ef8d945STudor Ambarus 
775f2147b88SHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
776f2147b88SHerbert Xu 
777f2147b88SHerbert Xu 	/* skip assoc data */
778f2147b88SHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
779f2147b88SHerbert Xu 
780f2147b88SHerbert Xu 	/* cryptlen = seqinlen - assoclen */
781f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
782f2147b88SHerbert Xu 
783f2147b88SHerbert Xu 	/* if cryptlen is ZERO jump to zero-payload commands */
784f2147b88SHerbert Xu 	zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
785f2147b88SHerbert Xu 					    JUMP_COND_MATH_Z);
786f2147b88SHerbert Xu 
7873ef8d945STudor Ambarus 	/* read assoc data */
7883ef8d945STudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
7893ef8d945STudor Ambarus 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
7903ef8d945STudor Ambarus 	set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
7913ef8d945STudor Ambarus 
792f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
7933ef8d945STudor Ambarus 
7943ef8d945STudor Ambarus 	/* write encrypted data */
7953ef8d945STudor Ambarus 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
7963ef8d945STudor Ambarus 
7973ef8d945STudor Ambarus 	/* read payload data */
7983ef8d945STudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
7993ef8d945STudor Ambarus 			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
8003ef8d945STudor Ambarus 
8013ef8d945STudor Ambarus 	/* jump the zero-payload commands */
802f2147b88SHerbert Xu 	append_jump(desc, JUMP_TEST_ALL | 2);
8033ef8d945STudor Ambarus 
8043ef8d945STudor Ambarus 	/* zero-payload commands */
8053ef8d945STudor Ambarus 	set_jump_tgt_here(desc, zero_payload_jump_cmd);
8063ef8d945STudor Ambarus 
8073ef8d945STudor Ambarus 	/* read assoc data */
8083ef8d945STudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
8093ef8d945STudor Ambarus 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
8103ef8d945STudor Ambarus 
811f2147b88SHerbert Xu 	/* There is no input data */
8123ef8d945STudor Ambarus 	set_jump_tgt_here(desc, zero_assoc_jump_cmd2);
8133ef8d945STudor Ambarus 
8143ef8d945STudor Ambarus 	/* write ICV */
8153ef8d945STudor Ambarus 	append_seq_store(desc, ctx->authsize, LDST_CLASS_1_CCB |
8163ef8d945STudor Ambarus 			 LDST_SRCDST_BYTE_CONTEXT);
8173ef8d945STudor Ambarus 
8183ef8d945STudor Ambarus 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
8193ef8d945STudor Ambarus 					      desc_bytes(desc),
8203ef8d945STudor Ambarus 					      DMA_TO_DEVICE);
8213ef8d945STudor Ambarus 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
8223ef8d945STudor Ambarus 		dev_err(jrdev, "unable to map shared descriptor\n");
8233ef8d945STudor Ambarus 		return -ENOMEM;
8243ef8d945STudor Ambarus 	}
8253ef8d945STudor Ambarus #ifdef DEBUG
8263ef8d945STudor Ambarus 	print_hex_dump(KERN_ERR, "gcm enc shdesc@"__stringify(__LINE__)": ",
8273ef8d945STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
8283ef8d945STudor Ambarus 		       desc_bytes(desc), 1);
8293ef8d945STudor Ambarus #endif
8303ef8d945STudor Ambarus 
8313ef8d945STudor Ambarus 	/*
8323ef8d945STudor Ambarus 	 * Job Descriptor and Shared Descriptors
8333ef8d945STudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
8343ef8d945STudor Ambarus 	 */
8353ef8d945STudor Ambarus 	keys_fit_inline = false;
836f2147b88SHerbert Xu 	if (DESC_GCM_DEC_LEN + GCM_DESC_JOB_IO_LEN +
8373ef8d945STudor Ambarus 	    ctx->enckeylen <= CAAM_DESC_BYTES_MAX)
8383ef8d945STudor Ambarus 		keys_fit_inline = true;
8393ef8d945STudor Ambarus 
8403ef8d945STudor Ambarus 	desc = ctx->sh_desc_dec;
8413ef8d945STudor Ambarus 
8423ef8d945STudor Ambarus 	init_sh_desc(desc, HDR_SHARE_SERIAL);
8433ef8d945STudor Ambarus 
8443ef8d945STudor Ambarus 	/* skip key loading if they are loaded due to sharing */
8453ef8d945STudor Ambarus 	key_jump_cmd = append_jump(desc, JUMP_JSL |
8463ef8d945STudor Ambarus 				   JUMP_TEST_ALL | JUMP_COND_SHRD |
8473ef8d945STudor Ambarus 				   JUMP_COND_SELF);
8483ef8d945STudor Ambarus 	if (keys_fit_inline)
8493ef8d945STudor Ambarus 		append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
8503ef8d945STudor Ambarus 				  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
8513ef8d945STudor Ambarus 	else
8523ef8d945STudor Ambarus 		append_key(desc, ctx->key_dma, ctx->enckeylen,
8533ef8d945STudor Ambarus 			   CLASS_1 | KEY_DEST_CLASS_REG);
8543ef8d945STudor Ambarus 	set_jump_tgt_here(desc, key_jump_cmd);
8553ef8d945STudor Ambarus 
8563ef8d945STudor Ambarus 	/* class 1 operation */
8573ef8d945STudor Ambarus 	append_operation(desc, ctx->class1_alg_type |
8583ef8d945STudor Ambarus 			 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON);
8593ef8d945STudor Ambarus 
860f2147b88SHerbert Xu 	/* if assoclen is ZERO, skip reading the assoc data */
861f2147b88SHerbert Xu 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
8623ef8d945STudor Ambarus 	zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
8633ef8d945STudor Ambarus 						 JUMP_COND_MATH_Z);
864f2147b88SHerbert Xu 
865f2147b88SHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
866f2147b88SHerbert Xu 
867f2147b88SHerbert Xu 	/* skip assoc data */
868f2147b88SHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
869f2147b88SHerbert Xu 
8703ef8d945STudor Ambarus 	/* read assoc data */
8713ef8d945STudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
8723ef8d945STudor Ambarus 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
873f2147b88SHerbert Xu 
8743ef8d945STudor Ambarus 	set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
8753ef8d945STudor Ambarus 
876f2147b88SHerbert Xu 	/* cryptlen = seqoutlen - assoclen */
877f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
878f2147b88SHerbert Xu 
879f2147b88SHerbert Xu 	/* jump to zero-payload command if cryptlen is zero */
880f2147b88SHerbert Xu 	zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
881f2147b88SHerbert Xu 					    JUMP_COND_MATH_Z);
882f2147b88SHerbert Xu 
883f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
8843ef8d945STudor Ambarus 
8853ef8d945STudor Ambarus 	/* store encrypted data */
8863ef8d945STudor Ambarus 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
8873ef8d945STudor Ambarus 
8883ef8d945STudor Ambarus 	/* read payload data */
8893ef8d945STudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
8903ef8d945STudor Ambarus 			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
8913ef8d945STudor Ambarus 
8923ef8d945STudor Ambarus 	/* zero-payload command */
8933ef8d945STudor Ambarus 	set_jump_tgt_here(desc, zero_payload_jump_cmd);
8943ef8d945STudor Ambarus 
8953ef8d945STudor Ambarus 	/* read ICV */
8963ef8d945STudor Ambarus 	append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS1 |
8973ef8d945STudor Ambarus 			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
8983ef8d945STudor Ambarus 
8993ef8d945STudor Ambarus 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
9003ef8d945STudor Ambarus 					      desc_bytes(desc),
9013ef8d945STudor Ambarus 					      DMA_TO_DEVICE);
9023ef8d945STudor Ambarus 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
9033ef8d945STudor Ambarus 		dev_err(jrdev, "unable to map shared descriptor\n");
9043ef8d945STudor Ambarus 		return -ENOMEM;
9053ef8d945STudor Ambarus 	}
9063ef8d945STudor Ambarus #ifdef DEBUG
9073ef8d945STudor Ambarus 	print_hex_dump(KERN_ERR, "gcm dec shdesc@"__stringify(__LINE__)": ",
9083ef8d945STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
9093ef8d945STudor Ambarus 		       desc_bytes(desc), 1);
9103ef8d945STudor Ambarus #endif
9113ef8d945STudor Ambarus 
9123ef8d945STudor Ambarus 	return 0;
9133ef8d945STudor Ambarus }
9143ef8d945STudor Ambarus 
9153ef8d945STudor Ambarus static int gcm_setauthsize(struct crypto_aead *authenc, unsigned int authsize)
9163ef8d945STudor Ambarus {
9173ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
9183ef8d945STudor Ambarus 
9193ef8d945STudor Ambarus 	ctx->authsize = authsize;
9203ef8d945STudor Ambarus 	gcm_set_sh_desc(authenc);
9213ef8d945STudor Ambarus 
9223ef8d945STudor Ambarus 	return 0;
9233ef8d945STudor Ambarus }
9243ef8d945STudor Ambarus 
925bac68f2cSTudor Ambarus static int rfc4106_set_sh_desc(struct crypto_aead *aead)
926bac68f2cSTudor Ambarus {
927bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
928bac68f2cSTudor Ambarus 	struct device *jrdev = ctx->jrdev;
929bac68f2cSTudor Ambarus 	bool keys_fit_inline = false;
930f2147b88SHerbert Xu 	u32 *key_jump_cmd;
931bac68f2cSTudor Ambarus 	u32 *desc;
932bac68f2cSTudor Ambarus 
933bac68f2cSTudor Ambarus 	if (!ctx->enckeylen || !ctx->authsize)
934bac68f2cSTudor Ambarus 		return 0;
935bac68f2cSTudor Ambarus 
936bac68f2cSTudor Ambarus 	/*
937bac68f2cSTudor Ambarus 	 * RFC4106 encrypt shared descriptor
938bac68f2cSTudor Ambarus 	 * Job Descriptor and Shared Descriptor
939bac68f2cSTudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
940bac68f2cSTudor Ambarus 	 */
941f2147b88SHerbert Xu 	if (DESC_RFC4106_ENC_LEN + GCM_DESC_JOB_IO_LEN +
942bac68f2cSTudor Ambarus 	    ctx->enckeylen <= CAAM_DESC_BYTES_MAX)
943bac68f2cSTudor Ambarus 		keys_fit_inline = true;
944bac68f2cSTudor Ambarus 
945bac68f2cSTudor Ambarus 	desc = ctx->sh_desc_enc;
946bac68f2cSTudor Ambarus 
947bac68f2cSTudor Ambarus 	init_sh_desc(desc, HDR_SHARE_SERIAL);
948bac68f2cSTudor Ambarus 
949bac68f2cSTudor Ambarus 	/* Skip key loading if it is loaded due to sharing */
950bac68f2cSTudor Ambarus 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
951bac68f2cSTudor Ambarus 				   JUMP_COND_SHRD);
952bac68f2cSTudor Ambarus 	if (keys_fit_inline)
953bac68f2cSTudor Ambarus 		append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
954bac68f2cSTudor Ambarus 				  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
955bac68f2cSTudor Ambarus 	else
956bac68f2cSTudor Ambarus 		append_key(desc, ctx->key_dma, ctx->enckeylen,
957bac68f2cSTudor Ambarus 			   CLASS_1 | KEY_DEST_CLASS_REG);
958bac68f2cSTudor Ambarus 	set_jump_tgt_here(desc, key_jump_cmd);
959bac68f2cSTudor Ambarus 
960bac68f2cSTudor Ambarus 	/* Class 1 operation */
961bac68f2cSTudor Ambarus 	append_operation(desc, ctx->class1_alg_type |
962bac68f2cSTudor Ambarus 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
963bac68f2cSTudor Ambarus 
96446218750SHerbert Xu 	append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, 8);
965bac68f2cSTudor Ambarus 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
966bac68f2cSTudor Ambarus 
967bac68f2cSTudor Ambarus 	/* Read assoc data */
968bac68f2cSTudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
969bac68f2cSTudor Ambarus 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
970bac68f2cSTudor Ambarus 
97146218750SHerbert Xu 	/* Skip IV */
97246218750SHerbert Xu 	append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
973f2147b88SHerbert Xu 
974bac68f2cSTudor Ambarus 	/* Will read cryptlen bytes */
975f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
976bac68f2cSTudor Ambarus 
9774aad0cc5SHoria Geant? 	/* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
9784aad0cc5SHoria Geant? 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG);
979bac68f2cSTudor Ambarus 
98046218750SHerbert Xu 	/* Skip assoc data */
98146218750SHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
98246218750SHerbert Xu 
98346218750SHerbert Xu 	/* cryptlen = seqoutlen - assoclen */
9844aad0cc5SHoria Geant? 	append_math_sub(desc, VARSEQOUTLEN, VARSEQINLEN, REG0, CAAM_CMD_SZ);
98546218750SHerbert Xu 
98646218750SHerbert Xu 	/* Write encrypted data */
98746218750SHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
98846218750SHerbert Xu 
9894aad0cc5SHoria Geant? 	/* Read payload data */
9904aad0cc5SHoria Geant? 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
9914aad0cc5SHoria Geant? 			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
9924aad0cc5SHoria Geant? 
993bac68f2cSTudor Ambarus 	/* Write ICV */
994bac68f2cSTudor Ambarus 	append_seq_store(desc, ctx->authsize, LDST_CLASS_1_CCB |
995bac68f2cSTudor Ambarus 			 LDST_SRCDST_BYTE_CONTEXT);
996bac68f2cSTudor Ambarus 
997bac68f2cSTudor Ambarus 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
998bac68f2cSTudor Ambarus 					      desc_bytes(desc),
999bac68f2cSTudor Ambarus 					      DMA_TO_DEVICE);
1000bac68f2cSTudor Ambarus 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
1001bac68f2cSTudor Ambarus 		dev_err(jrdev, "unable to map shared descriptor\n");
1002bac68f2cSTudor Ambarus 		return -ENOMEM;
1003bac68f2cSTudor Ambarus 	}
1004bac68f2cSTudor Ambarus #ifdef DEBUG
1005bac68f2cSTudor Ambarus 	print_hex_dump(KERN_ERR, "rfc4106 enc shdesc@"__stringify(__LINE__)": ",
1006bac68f2cSTudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
1007bac68f2cSTudor Ambarus 		       desc_bytes(desc), 1);
1008bac68f2cSTudor Ambarus #endif
1009bac68f2cSTudor Ambarus 
1010bac68f2cSTudor Ambarus 	/*
1011bac68f2cSTudor Ambarus 	 * Job Descriptor and Shared Descriptors
1012bac68f2cSTudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
1013bac68f2cSTudor Ambarus 	 */
1014bac68f2cSTudor Ambarus 	keys_fit_inline = false;
1015bac68f2cSTudor Ambarus 	if (DESC_RFC4106_DEC_LEN + DESC_JOB_IO_LEN +
1016bac68f2cSTudor Ambarus 	    ctx->enckeylen <= CAAM_DESC_BYTES_MAX)
1017bac68f2cSTudor Ambarus 		keys_fit_inline = true;
1018bac68f2cSTudor Ambarus 
1019bac68f2cSTudor Ambarus 	desc = ctx->sh_desc_dec;
1020bac68f2cSTudor Ambarus 
1021bac68f2cSTudor Ambarus 	init_sh_desc(desc, HDR_SHARE_SERIAL);
1022bac68f2cSTudor Ambarus 
1023bac68f2cSTudor Ambarus 	/* Skip key loading if it is loaded due to sharing */
1024bac68f2cSTudor Ambarus 	key_jump_cmd = append_jump(desc, JUMP_JSL |
1025bac68f2cSTudor Ambarus 				   JUMP_TEST_ALL | JUMP_COND_SHRD);
1026bac68f2cSTudor Ambarus 	if (keys_fit_inline)
1027bac68f2cSTudor Ambarus 		append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
1028bac68f2cSTudor Ambarus 				  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
1029bac68f2cSTudor Ambarus 	else
1030bac68f2cSTudor Ambarus 		append_key(desc, ctx->key_dma, ctx->enckeylen,
1031bac68f2cSTudor Ambarus 			   CLASS_1 | KEY_DEST_CLASS_REG);
1032bac68f2cSTudor Ambarus 	set_jump_tgt_here(desc, key_jump_cmd);
1033bac68f2cSTudor Ambarus 
1034bac68f2cSTudor Ambarus 	/* Class 1 operation */
1035bac68f2cSTudor Ambarus 	append_operation(desc, ctx->class1_alg_type |
1036bac68f2cSTudor Ambarus 			 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON);
1037bac68f2cSTudor Ambarus 
103846218750SHerbert Xu 	append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, 8);
1039f2147b88SHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
1040bac68f2cSTudor Ambarus 
1041bac68f2cSTudor Ambarus 	/* Read assoc data */
1042bac68f2cSTudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
1043bac68f2cSTudor Ambarus 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
1044bac68f2cSTudor Ambarus 
104546218750SHerbert Xu 	/* Skip IV */
104646218750SHerbert Xu 	append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
1047f2147b88SHerbert Xu 
1048bac68f2cSTudor Ambarus 	/* Will read cryptlen bytes */
104946218750SHerbert Xu 	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG3, CAAM_CMD_SZ);
1050bac68f2cSTudor Ambarus 
10514aad0cc5SHoria Geant? 	/* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
10524aad0cc5SHoria Geant? 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG);
1053bac68f2cSTudor Ambarus 
105446218750SHerbert Xu 	/* Skip assoc data */
105546218750SHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
105646218750SHerbert Xu 
105746218750SHerbert Xu 	/* Will write cryptlen bytes */
105846218750SHerbert Xu 	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
105946218750SHerbert Xu 
106046218750SHerbert Xu 	/* Store payload data */
106146218750SHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
106246218750SHerbert Xu 
10634aad0cc5SHoria Geant? 	/* Read encrypted data */
10644aad0cc5SHoria Geant? 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
10654aad0cc5SHoria Geant? 			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
10664aad0cc5SHoria Geant? 
1067bac68f2cSTudor Ambarus 	/* Read ICV */
1068bac68f2cSTudor Ambarus 	append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS1 |
1069bac68f2cSTudor Ambarus 			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
1070bac68f2cSTudor Ambarus 
1071bac68f2cSTudor Ambarus 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
1072bac68f2cSTudor Ambarus 					      desc_bytes(desc),
1073bac68f2cSTudor Ambarus 					      DMA_TO_DEVICE);
1074bac68f2cSTudor Ambarus 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
1075bac68f2cSTudor Ambarus 		dev_err(jrdev, "unable to map shared descriptor\n");
1076bac68f2cSTudor Ambarus 		return -ENOMEM;
1077bac68f2cSTudor Ambarus 	}
1078bac68f2cSTudor Ambarus #ifdef DEBUG
1079bac68f2cSTudor Ambarus 	print_hex_dump(KERN_ERR, "rfc4106 dec shdesc@"__stringify(__LINE__)": ",
1080bac68f2cSTudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
1081bac68f2cSTudor Ambarus 		       desc_bytes(desc), 1);
1082bac68f2cSTudor Ambarus #endif
1083bac68f2cSTudor Ambarus 
1084bac68f2cSTudor Ambarus 	return 0;
1085bac68f2cSTudor Ambarus }
1086bac68f2cSTudor Ambarus 
1087bac68f2cSTudor Ambarus static int rfc4106_setauthsize(struct crypto_aead *authenc,
1088bac68f2cSTudor Ambarus 			       unsigned int authsize)
1089bac68f2cSTudor Ambarus {
1090bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
1091bac68f2cSTudor Ambarus 
1092bac68f2cSTudor Ambarus 	ctx->authsize = authsize;
1093bac68f2cSTudor Ambarus 	rfc4106_set_sh_desc(authenc);
1094bac68f2cSTudor Ambarus 
1095bac68f2cSTudor Ambarus 	return 0;
1096bac68f2cSTudor Ambarus }
1097bac68f2cSTudor Ambarus 
10985d0429a3STudor Ambarus static int rfc4543_set_sh_desc(struct crypto_aead *aead)
10995d0429a3STudor Ambarus {
11005d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
11015d0429a3STudor Ambarus 	struct device *jrdev = ctx->jrdev;
11025d0429a3STudor Ambarus 	bool keys_fit_inline = false;
1103f2147b88SHerbert Xu 	u32 *key_jump_cmd;
11045d0429a3STudor Ambarus 	u32 *read_move_cmd, *write_move_cmd;
11055d0429a3STudor Ambarus 	u32 *desc;
11065d0429a3STudor Ambarus 
11075d0429a3STudor Ambarus 	if (!ctx->enckeylen || !ctx->authsize)
11085d0429a3STudor Ambarus 		return 0;
11095d0429a3STudor Ambarus 
11105d0429a3STudor Ambarus 	/*
11115d0429a3STudor Ambarus 	 * RFC4543 encrypt shared descriptor
11125d0429a3STudor Ambarus 	 * Job Descriptor and Shared Descriptor
11135d0429a3STudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
11145d0429a3STudor Ambarus 	 */
1115f2147b88SHerbert Xu 	if (DESC_RFC4543_ENC_LEN + GCM_DESC_JOB_IO_LEN +
11165d0429a3STudor Ambarus 	    ctx->enckeylen <= CAAM_DESC_BYTES_MAX)
11175d0429a3STudor Ambarus 		keys_fit_inline = true;
11185d0429a3STudor Ambarus 
11195d0429a3STudor Ambarus 	desc = ctx->sh_desc_enc;
11205d0429a3STudor Ambarus 
11215d0429a3STudor Ambarus 	init_sh_desc(desc, HDR_SHARE_SERIAL);
11225d0429a3STudor Ambarus 
11235d0429a3STudor Ambarus 	/* Skip key loading if it is loaded due to sharing */
11245d0429a3STudor Ambarus 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
11255d0429a3STudor Ambarus 				   JUMP_COND_SHRD);
11265d0429a3STudor Ambarus 	if (keys_fit_inline)
11275d0429a3STudor Ambarus 		append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
11285d0429a3STudor Ambarus 				  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
11295d0429a3STudor Ambarus 	else
11305d0429a3STudor Ambarus 		append_key(desc, ctx->key_dma, ctx->enckeylen,
11315d0429a3STudor Ambarus 			   CLASS_1 | KEY_DEST_CLASS_REG);
11325d0429a3STudor Ambarus 	set_jump_tgt_here(desc, key_jump_cmd);
11335d0429a3STudor Ambarus 
11345d0429a3STudor Ambarus 	/* Class 1 operation */
11355d0429a3STudor Ambarus 	append_operation(desc, ctx->class1_alg_type |
11365d0429a3STudor Ambarus 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
11375d0429a3STudor Ambarus 
1138f2147b88SHerbert Xu 	/* assoclen + cryptlen = seqinlen */
1139f2147b88SHerbert Xu 	append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
11405d0429a3STudor Ambarus 
11415d0429a3STudor Ambarus 	/*
11425d0429a3STudor Ambarus 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
11435d0429a3STudor Ambarus 	 * thus need to do some magic, i.e. self-patch the descriptor
11445d0429a3STudor Ambarus 	 * buffer.
11455d0429a3STudor Ambarus 	 */
11465d0429a3STudor Ambarus 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
11475d0429a3STudor Ambarus 				    (0x6 << MOVE_LEN_SHIFT));
11485d0429a3STudor Ambarus 	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
11495d0429a3STudor Ambarus 				     (0x8 << MOVE_LEN_SHIFT));
11505d0429a3STudor Ambarus 
1151f2147b88SHerbert Xu 	/* Will read assoclen + cryptlen bytes */
1152f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
11535d0429a3STudor Ambarus 
1154f2147b88SHerbert Xu 	/* Will write assoclen + cryptlen bytes */
1155f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1156f2147b88SHerbert Xu 
1157f2147b88SHerbert Xu 	/* Read and write assoclen + cryptlen bytes */
11585d0429a3STudor Ambarus 	aead_append_src_dst(desc, FIFOLD_TYPE_AAD);
11595d0429a3STudor Ambarus 
11605d0429a3STudor Ambarus 	set_move_tgt_here(desc, read_move_cmd);
11615d0429a3STudor Ambarus 	set_move_tgt_here(desc, write_move_cmd);
11625d0429a3STudor Ambarus 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
11635d0429a3STudor Ambarus 	/* Move payload data to OFIFO */
11645d0429a3STudor Ambarus 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
11655d0429a3STudor Ambarus 
11665d0429a3STudor Ambarus 	/* Write ICV */
11675d0429a3STudor Ambarus 	append_seq_store(desc, ctx->authsize, LDST_CLASS_1_CCB |
11685d0429a3STudor Ambarus 			 LDST_SRCDST_BYTE_CONTEXT);
11695d0429a3STudor Ambarus 
11705d0429a3STudor Ambarus 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
11715d0429a3STudor Ambarus 					      desc_bytes(desc),
11725d0429a3STudor Ambarus 					      DMA_TO_DEVICE);
11735d0429a3STudor Ambarus 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
11745d0429a3STudor Ambarus 		dev_err(jrdev, "unable to map shared descriptor\n");
11755d0429a3STudor Ambarus 		return -ENOMEM;
11765d0429a3STudor Ambarus 	}
11775d0429a3STudor Ambarus #ifdef DEBUG
11785d0429a3STudor Ambarus 	print_hex_dump(KERN_ERR, "rfc4543 enc shdesc@"__stringify(__LINE__)": ",
11795d0429a3STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
11805d0429a3STudor Ambarus 		       desc_bytes(desc), 1);
11815d0429a3STudor Ambarus #endif
11825d0429a3STudor Ambarus 
11835d0429a3STudor Ambarus 	/*
11845d0429a3STudor Ambarus 	 * Job Descriptor and Shared Descriptors
11855d0429a3STudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
11865d0429a3STudor Ambarus 	 */
11875d0429a3STudor Ambarus 	keys_fit_inline = false;
1188f2147b88SHerbert Xu 	if (DESC_RFC4543_DEC_LEN + GCM_DESC_JOB_IO_LEN +
11895d0429a3STudor Ambarus 	    ctx->enckeylen <= CAAM_DESC_BYTES_MAX)
11905d0429a3STudor Ambarus 		keys_fit_inline = true;
11915d0429a3STudor Ambarus 
11925d0429a3STudor Ambarus 	desc = ctx->sh_desc_dec;
11935d0429a3STudor Ambarus 
11945d0429a3STudor Ambarus 	init_sh_desc(desc, HDR_SHARE_SERIAL);
11955d0429a3STudor Ambarus 
11965d0429a3STudor Ambarus 	/* Skip key loading if it is loaded due to sharing */
11975d0429a3STudor Ambarus 	key_jump_cmd = append_jump(desc, JUMP_JSL |
11985d0429a3STudor Ambarus 				   JUMP_TEST_ALL | JUMP_COND_SHRD);
11995d0429a3STudor Ambarus 	if (keys_fit_inline)
12005d0429a3STudor Ambarus 		append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
12015d0429a3STudor Ambarus 				  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
12025d0429a3STudor Ambarus 	else
12035d0429a3STudor Ambarus 		append_key(desc, ctx->key_dma, ctx->enckeylen,
12045d0429a3STudor Ambarus 			   CLASS_1 | KEY_DEST_CLASS_REG);
12055d0429a3STudor Ambarus 	set_jump_tgt_here(desc, key_jump_cmd);
12065d0429a3STudor Ambarus 
12075d0429a3STudor Ambarus 	/* Class 1 operation */
12085d0429a3STudor Ambarus 	append_operation(desc, ctx->class1_alg_type |
12095d0429a3STudor Ambarus 			 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON);
12105d0429a3STudor Ambarus 
1211f2147b88SHerbert Xu 	/* assoclen + cryptlen = seqoutlen */
1212f2147b88SHerbert Xu 	append_math_sub(desc, REG3, SEQOUTLEN, REG0, CAAM_CMD_SZ);
12135d0429a3STudor Ambarus 
12145d0429a3STudor Ambarus 	/*
12155d0429a3STudor Ambarus 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
12165d0429a3STudor Ambarus 	 * thus need to do some magic, i.e. self-patch the descriptor
12175d0429a3STudor Ambarus 	 * buffer.
12185d0429a3STudor Ambarus 	 */
12195d0429a3STudor Ambarus 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
12205d0429a3STudor Ambarus 				    (0x6 << MOVE_LEN_SHIFT));
12215d0429a3STudor Ambarus 	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
12225d0429a3STudor Ambarus 				     (0x8 << MOVE_LEN_SHIFT));
12235d0429a3STudor Ambarus 
1224f2147b88SHerbert Xu 	/* Will read assoclen + cryptlen bytes */
1225f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
12265d0429a3STudor Ambarus 
1227f2147b88SHerbert Xu 	/* Will write assoclen + cryptlen bytes */
1228f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
12295d0429a3STudor Ambarus 
12305d0429a3STudor Ambarus 	/* Store payload data */
12315d0429a3STudor Ambarus 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
12325d0429a3STudor Ambarus 
1233f2147b88SHerbert Xu 	/* In-snoop assoclen + cryptlen data */
12345d0429a3STudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | FIFOLDST_VLF |
12355d0429a3STudor Ambarus 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST2FLUSH1);
12365d0429a3STudor Ambarus 
12375d0429a3STudor Ambarus 	set_move_tgt_here(desc, read_move_cmd);
12385d0429a3STudor Ambarus 	set_move_tgt_here(desc, write_move_cmd);
12395d0429a3STudor Ambarus 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
12405d0429a3STudor Ambarus 	/* Move payload data to OFIFO */
12415d0429a3STudor Ambarus 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
12425d0429a3STudor Ambarus 	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
12435d0429a3STudor Ambarus 
12445d0429a3STudor Ambarus 	/* Read ICV */
12455d0429a3STudor Ambarus 	append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS1 |
12465d0429a3STudor Ambarus 			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
12475d0429a3STudor Ambarus 
12485d0429a3STudor Ambarus 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
12495d0429a3STudor Ambarus 					      desc_bytes(desc),
12505d0429a3STudor Ambarus 					      DMA_TO_DEVICE);
12515d0429a3STudor Ambarus 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
12525d0429a3STudor Ambarus 		dev_err(jrdev, "unable to map shared descriptor\n");
12535d0429a3STudor Ambarus 		return -ENOMEM;
12545d0429a3STudor Ambarus 	}
12555d0429a3STudor Ambarus #ifdef DEBUG
12565d0429a3STudor Ambarus 	print_hex_dump(KERN_ERR, "rfc4543 dec shdesc@"__stringify(__LINE__)": ",
12575d0429a3STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
12585d0429a3STudor Ambarus 		       desc_bytes(desc), 1);
12595d0429a3STudor Ambarus #endif
12605d0429a3STudor Ambarus 
12615d0429a3STudor Ambarus 	return 0;
12625d0429a3STudor Ambarus }
12635d0429a3STudor Ambarus 
12645d0429a3STudor Ambarus static int rfc4543_setauthsize(struct crypto_aead *authenc,
12655d0429a3STudor Ambarus 			       unsigned int authsize)
12665d0429a3STudor Ambarus {
12675d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
12685d0429a3STudor Ambarus 
12695d0429a3STudor Ambarus 	ctx->authsize = authsize;
12705d0429a3STudor Ambarus 	rfc4543_set_sh_desc(authenc);
12715d0429a3STudor Ambarus 
12725d0429a3STudor Ambarus 	return 0;
12735d0429a3STudor Ambarus }
12745d0429a3STudor Ambarus 
12754c1ec1f9SYuan Kang static u32 gen_split_aead_key(struct caam_ctx *ctx, const u8 *key_in,
12764c1ec1f9SYuan Kang 			      u32 authkeylen)
12778e8ec596SKim Phillips {
12784c1ec1f9SYuan Kang 	return gen_split_key(ctx->jrdev, ctx->key, ctx->split_key_len,
12794c1ec1f9SYuan Kang 			       ctx->split_key_pad_len, key_in, authkeylen,
12804c1ec1f9SYuan Kang 			       ctx->alg_op);
12818e8ec596SKim Phillips }
12828e8ec596SKim Phillips 
12830e479300SYuan Kang static int aead_setkey(struct crypto_aead *aead,
12848e8ec596SKim Phillips 			       const u8 *key, unsigned int keylen)
12858e8ec596SKim Phillips {
12868e8ec596SKim Phillips 	/* Sizes for MDHA pads (*not* keys): MD5, SHA1, 224, 256, 384, 512 */
12878e8ec596SKim Phillips 	static const u8 mdpadlen[] = { 16, 20, 32, 32, 64, 64 };
12888e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
12898e8ec596SKim Phillips 	struct device *jrdev = ctx->jrdev;
12904e6e0b27SHoria Geanta 	struct crypto_authenc_keys keys;
12918e8ec596SKim Phillips 	int ret = 0;
12928e8ec596SKim Phillips 
12934e6e0b27SHoria Geanta 	if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
12948e8ec596SKim Phillips 		goto badkey;
12958e8ec596SKim Phillips 
12968e8ec596SKim Phillips 	/* Pick class 2 key length from algorithm submask */
12978e8ec596SKim Phillips 	ctx->split_key_len = mdpadlen[(ctx->alg_op & OP_ALG_ALGSEL_SUBMASK) >>
12988e8ec596SKim Phillips 				      OP_ALG_ALGSEL_SHIFT] * 2;
12998e8ec596SKim Phillips 	ctx->split_key_pad_len = ALIGN(ctx->split_key_len, 16);
13008e8ec596SKim Phillips 
13014e6e0b27SHoria Geanta 	if (ctx->split_key_pad_len + keys.enckeylen > CAAM_MAX_KEY_SIZE)
13024e6e0b27SHoria Geanta 		goto badkey;
13034e6e0b27SHoria Geanta 
13048e8ec596SKim Phillips #ifdef DEBUG
13058e8ec596SKim Phillips 	printk(KERN_ERR "keylen %d enckeylen %d authkeylen %d\n",
13064e6e0b27SHoria Geanta 	       keys.authkeylen + keys.enckeylen, keys.enckeylen,
13074e6e0b27SHoria Geanta 	       keys.authkeylen);
13088e8ec596SKim Phillips 	printk(KERN_ERR "split_key_len %d split_key_pad_len %d\n",
13098e8ec596SKim Phillips 	       ctx->split_key_len, ctx->split_key_pad_len);
1310514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
13118e8ec596SKim Phillips 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
13128e8ec596SKim Phillips #endif
13138e8ec596SKim Phillips 
13144e6e0b27SHoria Geanta 	ret = gen_split_aead_key(ctx, keys.authkey, keys.authkeylen);
13158e8ec596SKim Phillips 	if (ret) {
13168e8ec596SKim Phillips 		goto badkey;
13178e8ec596SKim Phillips 	}
13188e8ec596SKim Phillips 
13198e8ec596SKim Phillips 	/* postpend encryption key to auth split key */
13204e6e0b27SHoria Geanta 	memcpy(ctx->key + ctx->split_key_pad_len, keys.enckey, keys.enckeylen);
13218e8ec596SKim Phillips 
1322885e9e2fSYuan Kang 	ctx->key_dma = dma_map_single(jrdev, ctx->key, ctx->split_key_pad_len +
13234e6e0b27SHoria Geanta 				      keys.enckeylen, DMA_TO_DEVICE);
1324885e9e2fSYuan Kang 	if (dma_mapping_error(jrdev, ctx->key_dma)) {
13258e8ec596SKim Phillips 		dev_err(jrdev, "unable to map key i/o memory\n");
13268e8ec596SKim Phillips 		return -ENOMEM;
13278e8ec596SKim Phillips 	}
13288e8ec596SKim Phillips #ifdef DEBUG
1329514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ctx.key@"__stringify(__LINE__)": ",
13308e8ec596SKim Phillips 		       DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
13314e6e0b27SHoria Geanta 		       ctx->split_key_pad_len + keys.enckeylen, 1);
13328e8ec596SKim Phillips #endif
13338e8ec596SKim Phillips 
13344e6e0b27SHoria Geanta 	ctx->enckeylen = keys.enckeylen;
13358e8ec596SKim Phillips 
13361acebad3SYuan Kang 	ret = aead_set_sh_desc(aead);
13378e8ec596SKim Phillips 	if (ret) {
1338885e9e2fSYuan Kang 		dma_unmap_single(jrdev, ctx->key_dma, ctx->split_key_pad_len +
13394e6e0b27SHoria Geanta 				 keys.enckeylen, DMA_TO_DEVICE);
13408e8ec596SKim Phillips 	}
13418e8ec596SKim Phillips 
13428e8ec596SKim Phillips 	return ret;
13438e8ec596SKim Phillips badkey:
13448e8ec596SKim Phillips 	crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
13458e8ec596SKim Phillips 	return -EINVAL;
13468e8ec596SKim Phillips }
13478e8ec596SKim Phillips 
13483ef8d945STudor Ambarus static int gcm_setkey(struct crypto_aead *aead,
13493ef8d945STudor Ambarus 		      const u8 *key, unsigned int keylen)
13503ef8d945STudor Ambarus {
13513ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
13523ef8d945STudor Ambarus 	struct device *jrdev = ctx->jrdev;
13533ef8d945STudor Ambarus 	int ret = 0;
13543ef8d945STudor Ambarus 
13553ef8d945STudor Ambarus #ifdef DEBUG
13563ef8d945STudor Ambarus 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
13573ef8d945STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
13583ef8d945STudor Ambarus #endif
13593ef8d945STudor Ambarus 
13603ef8d945STudor Ambarus 	memcpy(ctx->key, key, keylen);
13613ef8d945STudor Ambarus 	ctx->key_dma = dma_map_single(jrdev, ctx->key, keylen,
13623ef8d945STudor Ambarus 				      DMA_TO_DEVICE);
13633ef8d945STudor Ambarus 	if (dma_mapping_error(jrdev, ctx->key_dma)) {
13643ef8d945STudor Ambarus 		dev_err(jrdev, "unable to map key i/o memory\n");
13653ef8d945STudor Ambarus 		return -ENOMEM;
13663ef8d945STudor Ambarus 	}
13673ef8d945STudor Ambarus 	ctx->enckeylen = keylen;
13683ef8d945STudor Ambarus 
13693ef8d945STudor Ambarus 	ret = gcm_set_sh_desc(aead);
13703ef8d945STudor Ambarus 	if (ret) {
13713ef8d945STudor Ambarus 		dma_unmap_single(jrdev, ctx->key_dma, ctx->enckeylen,
13723ef8d945STudor Ambarus 				 DMA_TO_DEVICE);
13733ef8d945STudor Ambarus 	}
13743ef8d945STudor Ambarus 
13753ef8d945STudor Ambarus 	return ret;
13763ef8d945STudor Ambarus }
13773ef8d945STudor Ambarus 
1378bac68f2cSTudor Ambarus static int rfc4106_setkey(struct crypto_aead *aead,
1379bac68f2cSTudor Ambarus 			  const u8 *key, unsigned int keylen)
1380bac68f2cSTudor Ambarus {
1381bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1382bac68f2cSTudor Ambarus 	struct device *jrdev = ctx->jrdev;
1383bac68f2cSTudor Ambarus 	int ret = 0;
1384bac68f2cSTudor Ambarus 
1385bac68f2cSTudor Ambarus 	if (keylen < 4)
1386bac68f2cSTudor Ambarus 		return -EINVAL;
1387bac68f2cSTudor Ambarus 
1388bac68f2cSTudor Ambarus #ifdef DEBUG
1389bac68f2cSTudor Ambarus 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
1390bac68f2cSTudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
1391bac68f2cSTudor Ambarus #endif
1392bac68f2cSTudor Ambarus 
1393bac68f2cSTudor Ambarus 	memcpy(ctx->key, key, keylen);
1394bac68f2cSTudor Ambarus 
1395bac68f2cSTudor Ambarus 	/*
1396bac68f2cSTudor Ambarus 	 * The last four bytes of the key material are used as the salt value
1397bac68f2cSTudor Ambarus 	 * in the nonce. Update the AES key length.
1398bac68f2cSTudor Ambarus 	 */
1399bac68f2cSTudor Ambarus 	ctx->enckeylen = keylen - 4;
1400bac68f2cSTudor Ambarus 
1401bac68f2cSTudor Ambarus 	ctx->key_dma = dma_map_single(jrdev, ctx->key, ctx->enckeylen,
1402bac68f2cSTudor Ambarus 				      DMA_TO_DEVICE);
1403bac68f2cSTudor Ambarus 	if (dma_mapping_error(jrdev, ctx->key_dma)) {
1404bac68f2cSTudor Ambarus 		dev_err(jrdev, "unable to map key i/o memory\n");
1405bac68f2cSTudor Ambarus 		return -ENOMEM;
1406bac68f2cSTudor Ambarus 	}
1407bac68f2cSTudor Ambarus 
1408bac68f2cSTudor Ambarus 	ret = rfc4106_set_sh_desc(aead);
1409bac68f2cSTudor Ambarus 	if (ret) {
1410bac68f2cSTudor Ambarus 		dma_unmap_single(jrdev, ctx->key_dma, ctx->enckeylen,
1411bac68f2cSTudor Ambarus 				 DMA_TO_DEVICE);
1412bac68f2cSTudor Ambarus 	}
1413bac68f2cSTudor Ambarus 
1414bac68f2cSTudor Ambarus 	return ret;
1415bac68f2cSTudor Ambarus }
1416bac68f2cSTudor Ambarus 
14175d0429a3STudor Ambarus static int rfc4543_setkey(struct crypto_aead *aead,
14185d0429a3STudor Ambarus 			  const u8 *key, unsigned int keylen)
14195d0429a3STudor Ambarus {
14205d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
14215d0429a3STudor Ambarus 	struct device *jrdev = ctx->jrdev;
14225d0429a3STudor Ambarus 	int ret = 0;
14235d0429a3STudor Ambarus 
14245d0429a3STudor Ambarus 	if (keylen < 4)
14255d0429a3STudor Ambarus 		return -EINVAL;
14265d0429a3STudor Ambarus 
14275d0429a3STudor Ambarus #ifdef DEBUG
14285d0429a3STudor Ambarus 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
14295d0429a3STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
14305d0429a3STudor Ambarus #endif
14315d0429a3STudor Ambarus 
14325d0429a3STudor Ambarus 	memcpy(ctx->key, key, keylen);
14335d0429a3STudor Ambarus 
14345d0429a3STudor Ambarus 	/*
14355d0429a3STudor Ambarus 	 * The last four bytes of the key material are used as the salt value
14365d0429a3STudor Ambarus 	 * in the nonce. Update the AES key length.
14375d0429a3STudor Ambarus 	 */
14385d0429a3STudor Ambarus 	ctx->enckeylen = keylen - 4;
14395d0429a3STudor Ambarus 
14405d0429a3STudor Ambarus 	ctx->key_dma = dma_map_single(jrdev, ctx->key, ctx->enckeylen,
14415d0429a3STudor Ambarus 				      DMA_TO_DEVICE);
14425d0429a3STudor Ambarus 	if (dma_mapping_error(jrdev, ctx->key_dma)) {
14435d0429a3STudor Ambarus 		dev_err(jrdev, "unable to map key i/o memory\n");
14445d0429a3STudor Ambarus 		return -ENOMEM;
14455d0429a3STudor Ambarus 	}
14465d0429a3STudor Ambarus 
14475d0429a3STudor Ambarus 	ret = rfc4543_set_sh_desc(aead);
14485d0429a3STudor Ambarus 	if (ret) {
14495d0429a3STudor Ambarus 		dma_unmap_single(jrdev, ctx->key_dma, ctx->enckeylen,
14505d0429a3STudor Ambarus 				 DMA_TO_DEVICE);
14515d0429a3STudor Ambarus 	}
14525d0429a3STudor Ambarus 
14535d0429a3STudor Ambarus 	return ret;
14545d0429a3STudor Ambarus }
14555d0429a3STudor Ambarus 
1456acdca31dSYuan Kang static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
1457acdca31dSYuan Kang 			     const u8 *key, unsigned int keylen)
1458acdca31dSYuan Kang {
1459acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
1460a5f57cffSCatalin Vasile 	struct ablkcipher_tfm *crt = &ablkcipher->base.crt_ablkcipher;
1461a5f57cffSCatalin Vasile 	struct crypto_tfm *tfm = crypto_ablkcipher_tfm(ablkcipher);
1462a5f57cffSCatalin Vasile 	const char *alg_name = crypto_tfm_alg_name(tfm);
1463acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
1464acdca31dSYuan Kang 	int ret = 0;
14654464a7d4SHoria Geanta 	u32 *key_jump_cmd;
1466acdca31dSYuan Kang 	u32 *desc;
1467a5f57cffSCatalin Vasile 	u32 *nonce;
14687222d1a3SCatalin Vasile 	u32 geniv;
14692b22f6c5SCatalin Vasile 	u32 ctx1_iv_off = 0;
14702b22f6c5SCatalin Vasile 	const bool ctr_mode = ((ctx->class1_alg_type & OP_ALG_AAI_MASK) ==
14712b22f6c5SCatalin Vasile 			       OP_ALG_AAI_CTR_MOD128);
1472a5f57cffSCatalin Vasile 	const bool is_rfc3686 = (ctr_mode &&
1473a5f57cffSCatalin Vasile 				 (strstr(alg_name, "rfc3686") != NULL));
1474acdca31dSYuan Kang 
1475acdca31dSYuan Kang #ifdef DEBUG
1476514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
1477acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
1478acdca31dSYuan Kang #endif
14792b22f6c5SCatalin Vasile 	/*
14802b22f6c5SCatalin Vasile 	 * AES-CTR needs to load IV in CONTEXT1 reg
14812b22f6c5SCatalin Vasile 	 * at an offset of 128bits (16bytes)
14822b22f6c5SCatalin Vasile 	 * CONTEXT1[255:128] = IV
14832b22f6c5SCatalin Vasile 	 */
14842b22f6c5SCatalin Vasile 	if (ctr_mode)
14852b22f6c5SCatalin Vasile 		ctx1_iv_off = 16;
1486acdca31dSYuan Kang 
1487a5f57cffSCatalin Vasile 	/*
1488a5f57cffSCatalin Vasile 	 * RFC3686 specific:
1489a5f57cffSCatalin Vasile 	 *	| CONTEXT1[255:128] = {NONCE, IV, COUNTER}
1490a5f57cffSCatalin Vasile 	 *	| *key = {KEY, NONCE}
1491a5f57cffSCatalin Vasile 	 */
1492a5f57cffSCatalin Vasile 	if (is_rfc3686) {
1493a5f57cffSCatalin Vasile 		ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
1494a5f57cffSCatalin Vasile 		keylen -= CTR_RFC3686_NONCE_SIZE;
1495a5f57cffSCatalin Vasile 	}
1496a5f57cffSCatalin Vasile 
1497acdca31dSYuan Kang 	memcpy(ctx->key, key, keylen);
1498acdca31dSYuan Kang 	ctx->key_dma = dma_map_single(jrdev, ctx->key, keylen,
1499acdca31dSYuan Kang 				      DMA_TO_DEVICE);
1500acdca31dSYuan Kang 	if (dma_mapping_error(jrdev, ctx->key_dma)) {
1501acdca31dSYuan Kang 		dev_err(jrdev, "unable to map key i/o memory\n");
1502acdca31dSYuan Kang 		return -ENOMEM;
1503acdca31dSYuan Kang 	}
1504acdca31dSYuan Kang 	ctx->enckeylen = keylen;
1505acdca31dSYuan Kang 
1506acdca31dSYuan Kang 	/* ablkcipher_encrypt shared descriptor */
1507acdca31dSYuan Kang 	desc = ctx->sh_desc_enc;
1508a5f57cffSCatalin Vasile 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1509acdca31dSYuan Kang 	/* Skip if already shared */
1510acdca31dSYuan Kang 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1511acdca31dSYuan Kang 				   JUMP_COND_SHRD);
1512acdca31dSYuan Kang 
1513acdca31dSYuan Kang 	/* Load class1 key only */
1514acdca31dSYuan Kang 	append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
1515acdca31dSYuan Kang 			  ctx->enckeylen, CLASS_1 |
1516acdca31dSYuan Kang 			  KEY_DEST_CLASS_REG);
1517acdca31dSYuan Kang 
1518a5f57cffSCatalin Vasile 	/* Load nonce into CONTEXT1 reg */
1519a5f57cffSCatalin Vasile 	if (is_rfc3686) {
1520a5f57cffSCatalin Vasile 		nonce = (u32 *)(key + keylen);
1521a5f57cffSCatalin Vasile 		append_load_imm_u32(desc, *nonce, LDST_CLASS_IND_CCB |
1522a5f57cffSCatalin Vasile 				    LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
1523a5f57cffSCatalin Vasile 		append_move(desc, MOVE_WAITCOMP |
1524a5f57cffSCatalin Vasile 			    MOVE_SRC_OUTFIFO |
1525a5f57cffSCatalin Vasile 			    MOVE_DEST_CLASS1CTX |
1526a5f57cffSCatalin Vasile 			    (16 << MOVE_OFFSET_SHIFT) |
1527a5f57cffSCatalin Vasile 			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
1528a5f57cffSCatalin Vasile 	}
1529a5f57cffSCatalin Vasile 
1530acdca31dSYuan Kang 	set_jump_tgt_here(desc, key_jump_cmd);
1531acdca31dSYuan Kang 
1532acdca31dSYuan Kang 	/* Load iv */
1533a5f57cffSCatalin Vasile 	append_seq_load(desc, crt->ivsize, LDST_SRCDST_BYTE_CONTEXT |
15342b22f6c5SCatalin Vasile 			LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT));
1535acdca31dSYuan Kang 
1536a5f57cffSCatalin Vasile 	/* Load counter into CONTEXT1 reg */
1537a5f57cffSCatalin Vasile 	if (is_rfc3686)
1538a5f57cffSCatalin Vasile 		append_load_imm_u32(desc, be32_to_cpu(1), LDST_IMM |
1539a5f57cffSCatalin Vasile 				    LDST_CLASS_1_CCB |
1540a5f57cffSCatalin Vasile 				    LDST_SRCDST_BYTE_CONTEXT |
1541a5f57cffSCatalin Vasile 				    ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
1542a5f57cffSCatalin Vasile 				     LDST_OFFSET_SHIFT));
1543a5f57cffSCatalin Vasile 
1544acdca31dSYuan Kang 	/* Load operation */
1545acdca31dSYuan Kang 	append_operation(desc, ctx->class1_alg_type |
1546acdca31dSYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
1547acdca31dSYuan Kang 
1548acdca31dSYuan Kang 	/* Perform operation */
1549acdca31dSYuan Kang 	ablkcipher_append_src_dst(desc);
1550acdca31dSYuan Kang 
1551acdca31dSYuan Kang 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
1552acdca31dSYuan Kang 					      desc_bytes(desc),
1553acdca31dSYuan Kang 					      DMA_TO_DEVICE);
1554acdca31dSYuan Kang 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
1555acdca31dSYuan Kang 		dev_err(jrdev, "unable to map shared descriptor\n");
1556acdca31dSYuan Kang 		return -ENOMEM;
1557acdca31dSYuan Kang 	}
1558acdca31dSYuan Kang #ifdef DEBUG
1559514df281SAlex Porosanu 	print_hex_dump(KERN_ERR,
1560514df281SAlex Porosanu 		       "ablkcipher enc shdesc@"__stringify(__LINE__)": ",
1561acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
1562acdca31dSYuan Kang 		       desc_bytes(desc), 1);
1563acdca31dSYuan Kang #endif
1564acdca31dSYuan Kang 	/* ablkcipher_decrypt shared descriptor */
1565acdca31dSYuan Kang 	desc = ctx->sh_desc_dec;
1566acdca31dSYuan Kang 
1567a5f57cffSCatalin Vasile 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1568acdca31dSYuan Kang 	/* Skip if already shared */
1569acdca31dSYuan Kang 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1570acdca31dSYuan Kang 				   JUMP_COND_SHRD);
1571acdca31dSYuan Kang 
1572acdca31dSYuan Kang 	/* Load class1 key only */
1573acdca31dSYuan Kang 	append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
1574acdca31dSYuan Kang 			  ctx->enckeylen, CLASS_1 |
1575acdca31dSYuan Kang 			  KEY_DEST_CLASS_REG);
1576acdca31dSYuan Kang 
1577a5f57cffSCatalin Vasile 	/* Load nonce into CONTEXT1 reg */
1578a5f57cffSCatalin Vasile 	if (is_rfc3686) {
1579a5f57cffSCatalin Vasile 		nonce = (u32 *)(key + keylen);
1580a5f57cffSCatalin Vasile 		append_load_imm_u32(desc, *nonce, LDST_CLASS_IND_CCB |
1581a5f57cffSCatalin Vasile 				    LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
1582a5f57cffSCatalin Vasile 		append_move(desc, MOVE_WAITCOMP |
1583a5f57cffSCatalin Vasile 			    MOVE_SRC_OUTFIFO |
1584a5f57cffSCatalin Vasile 			    MOVE_DEST_CLASS1CTX |
1585a5f57cffSCatalin Vasile 			    (16 << MOVE_OFFSET_SHIFT) |
1586a5f57cffSCatalin Vasile 			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
1587a5f57cffSCatalin Vasile 	}
1588a5f57cffSCatalin Vasile 
1589acdca31dSYuan Kang 	set_jump_tgt_here(desc, key_jump_cmd);
1590acdca31dSYuan Kang 
1591acdca31dSYuan Kang 	/* load IV */
1592a5f57cffSCatalin Vasile 	append_seq_load(desc, crt->ivsize, LDST_SRCDST_BYTE_CONTEXT |
15932b22f6c5SCatalin Vasile 			LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT));
1594acdca31dSYuan Kang 
1595a5f57cffSCatalin Vasile 	/* Load counter into CONTEXT1 reg */
1596a5f57cffSCatalin Vasile 	if (is_rfc3686)
1597a5f57cffSCatalin Vasile 		append_load_imm_u32(desc, be32_to_cpu(1), LDST_IMM |
1598a5f57cffSCatalin Vasile 				    LDST_CLASS_1_CCB |
1599a5f57cffSCatalin Vasile 				    LDST_SRCDST_BYTE_CONTEXT |
1600a5f57cffSCatalin Vasile 				    ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
1601a5f57cffSCatalin Vasile 				     LDST_OFFSET_SHIFT));
1602a5f57cffSCatalin Vasile 
1603acdca31dSYuan Kang 	/* Choose operation */
16042b22f6c5SCatalin Vasile 	if (ctr_mode)
16052b22f6c5SCatalin Vasile 		append_operation(desc, ctx->class1_alg_type |
16062b22f6c5SCatalin Vasile 				 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT);
16072b22f6c5SCatalin Vasile 	else
1608acdca31dSYuan Kang 		append_dec_op1(desc, ctx->class1_alg_type);
1609acdca31dSYuan Kang 
1610acdca31dSYuan Kang 	/* Perform operation */
1611acdca31dSYuan Kang 	ablkcipher_append_src_dst(desc);
1612acdca31dSYuan Kang 
1613acdca31dSYuan Kang 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
1614acdca31dSYuan Kang 					      desc_bytes(desc),
1615acdca31dSYuan Kang 					      DMA_TO_DEVICE);
161671c65f7cSHoria Geanta 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
1617acdca31dSYuan Kang 		dev_err(jrdev, "unable to map shared descriptor\n");
1618acdca31dSYuan Kang 		return -ENOMEM;
1619acdca31dSYuan Kang 	}
1620acdca31dSYuan Kang 
1621acdca31dSYuan Kang #ifdef DEBUG
1622514df281SAlex Porosanu 	print_hex_dump(KERN_ERR,
1623514df281SAlex Porosanu 		       "ablkcipher dec shdesc@"__stringify(__LINE__)": ",
1624acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
1625acdca31dSYuan Kang 		       desc_bytes(desc), 1);
1626acdca31dSYuan Kang #endif
16277222d1a3SCatalin Vasile 	/* ablkcipher_givencrypt shared descriptor */
16287222d1a3SCatalin Vasile 	desc = ctx->sh_desc_givenc;
16297222d1a3SCatalin Vasile 
16307222d1a3SCatalin Vasile 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
16317222d1a3SCatalin Vasile 	/* Skip if already shared */
16327222d1a3SCatalin Vasile 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
16337222d1a3SCatalin Vasile 				   JUMP_COND_SHRD);
16347222d1a3SCatalin Vasile 
16357222d1a3SCatalin Vasile 	/* Load class1 key only */
16367222d1a3SCatalin Vasile 	append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
16377222d1a3SCatalin Vasile 			  ctx->enckeylen, CLASS_1 |
16387222d1a3SCatalin Vasile 			  KEY_DEST_CLASS_REG);
16397222d1a3SCatalin Vasile 
16407222d1a3SCatalin Vasile 	/* Load Nonce into CONTEXT1 reg */
16417222d1a3SCatalin Vasile 	if (is_rfc3686) {
16427222d1a3SCatalin Vasile 		nonce = (u32 *)(key + keylen);
16437222d1a3SCatalin Vasile 		append_load_imm_u32(desc, *nonce, LDST_CLASS_IND_CCB |
16447222d1a3SCatalin Vasile 				    LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
16457222d1a3SCatalin Vasile 		append_move(desc, MOVE_WAITCOMP |
16467222d1a3SCatalin Vasile 			    MOVE_SRC_OUTFIFO |
16477222d1a3SCatalin Vasile 			    MOVE_DEST_CLASS1CTX |
16487222d1a3SCatalin Vasile 			    (16 << MOVE_OFFSET_SHIFT) |
16497222d1a3SCatalin Vasile 			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
16507222d1a3SCatalin Vasile 	}
16517222d1a3SCatalin Vasile 	set_jump_tgt_here(desc, key_jump_cmd);
16527222d1a3SCatalin Vasile 
16537222d1a3SCatalin Vasile 	/* Generate IV */
16547222d1a3SCatalin Vasile 	geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
16557222d1a3SCatalin Vasile 		NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 |
16567222d1a3SCatalin Vasile 		NFIFOENTRY_PTYPE_RND | (crt->ivsize << NFIFOENTRY_DLEN_SHIFT);
16577222d1a3SCatalin Vasile 	append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
16587222d1a3SCatalin Vasile 			    LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
16597222d1a3SCatalin Vasile 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
16607222d1a3SCatalin Vasile 	append_move(desc, MOVE_WAITCOMP |
16617222d1a3SCatalin Vasile 		    MOVE_SRC_INFIFO |
16627222d1a3SCatalin Vasile 		    MOVE_DEST_CLASS1CTX |
16637222d1a3SCatalin Vasile 		    (crt->ivsize << MOVE_LEN_SHIFT) |
16647222d1a3SCatalin Vasile 		    (ctx1_iv_off << MOVE_OFFSET_SHIFT));
16657222d1a3SCatalin Vasile 	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
16667222d1a3SCatalin Vasile 
16677222d1a3SCatalin Vasile 	/* Copy generated IV to memory */
16687222d1a3SCatalin Vasile 	append_seq_store(desc, crt->ivsize,
16697222d1a3SCatalin Vasile 			 LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
16707222d1a3SCatalin Vasile 			 (ctx1_iv_off << LDST_OFFSET_SHIFT));
16717222d1a3SCatalin Vasile 
16727222d1a3SCatalin Vasile 	/* Load Counter into CONTEXT1 reg */
16737222d1a3SCatalin Vasile 	if (is_rfc3686)
16747222d1a3SCatalin Vasile 		append_load_imm_u32(desc, (u32)1, LDST_IMM |
16757222d1a3SCatalin Vasile 				    LDST_CLASS_1_CCB |
16767222d1a3SCatalin Vasile 				    LDST_SRCDST_BYTE_CONTEXT |
16777222d1a3SCatalin Vasile 				    ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
16787222d1a3SCatalin Vasile 				     LDST_OFFSET_SHIFT));
16797222d1a3SCatalin Vasile 
16807222d1a3SCatalin Vasile 	if (ctx1_iv_off)
16817222d1a3SCatalin Vasile 		append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | JUMP_COND_NCP |
16827222d1a3SCatalin Vasile 			    (1 << JUMP_OFFSET_SHIFT));
16837222d1a3SCatalin Vasile 
16847222d1a3SCatalin Vasile 	/* Load operation */
16857222d1a3SCatalin Vasile 	append_operation(desc, ctx->class1_alg_type |
16867222d1a3SCatalin Vasile 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
16877222d1a3SCatalin Vasile 
16887222d1a3SCatalin Vasile 	/* Perform operation */
16897222d1a3SCatalin Vasile 	ablkcipher_append_src_dst(desc);
16907222d1a3SCatalin Vasile 
16917222d1a3SCatalin Vasile 	ctx->sh_desc_givenc_dma = dma_map_single(jrdev, desc,
16927222d1a3SCatalin Vasile 						 desc_bytes(desc),
16937222d1a3SCatalin Vasile 						 DMA_TO_DEVICE);
16947222d1a3SCatalin Vasile 	if (dma_mapping_error(jrdev, ctx->sh_desc_givenc_dma)) {
16957222d1a3SCatalin Vasile 		dev_err(jrdev, "unable to map shared descriptor\n");
16967222d1a3SCatalin Vasile 		return -ENOMEM;
16977222d1a3SCatalin Vasile 	}
16987222d1a3SCatalin Vasile #ifdef DEBUG
16997222d1a3SCatalin Vasile 	print_hex_dump(KERN_ERR,
17007222d1a3SCatalin Vasile 		       "ablkcipher givenc shdesc@" __stringify(__LINE__) ": ",
17017222d1a3SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
17027222d1a3SCatalin Vasile 		       desc_bytes(desc), 1);
17037222d1a3SCatalin Vasile #endif
1704acdca31dSYuan Kang 
1705acdca31dSYuan Kang 	return ret;
1706acdca31dSYuan Kang }
1707acdca31dSYuan Kang 
17088e8ec596SKim Phillips /*
17091acebad3SYuan Kang  * aead_edesc - s/w-extended aead descriptor
17101acebad3SYuan Kang  * @assoc_nents: number of segments in associated data (SPI+Seq) scatterlist
1711643b39b0SYuan Kang  * @assoc_chained: if source is chained
17128e8ec596SKim Phillips  * @src_nents: number of segments in input scatterlist
1713643b39b0SYuan Kang  * @src_chained: if source is chained
17148e8ec596SKim Phillips  * @dst_nents: number of segments in output scatterlist
1715643b39b0SYuan Kang  * @dst_chained: if destination is chained
17161acebad3SYuan Kang  * @iv_dma: dma address of iv for checking continuity and link table
17178e8ec596SKim Phillips  * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE)
1718a299c837SYuan Kang  * @sec4_sg_bytes: length of dma mapped sec4_sg space
1719a299c837SYuan Kang  * @sec4_sg_dma: bus physical mapped address of h/w link table
17208e8ec596SKim Phillips  * @hw_desc: the h/w job descriptor followed by any referenced link tables
17218e8ec596SKim Phillips  */
17220e479300SYuan Kang struct aead_edesc {
17238e8ec596SKim Phillips 	int assoc_nents;
1724643b39b0SYuan Kang 	bool assoc_chained;
17258e8ec596SKim Phillips 	int src_nents;
1726643b39b0SYuan Kang 	bool src_chained;
17278e8ec596SKim Phillips 	int dst_nents;
1728643b39b0SYuan Kang 	bool dst_chained;
17291acebad3SYuan Kang 	dma_addr_t iv_dma;
1730a299c837SYuan Kang 	int sec4_sg_bytes;
1731a299c837SYuan Kang 	dma_addr_t sec4_sg_dma;
1732a299c837SYuan Kang 	struct sec4_sg_entry *sec4_sg;
1733f2147b88SHerbert Xu 	u32 hw_desc[];
17348e8ec596SKim Phillips };
17358e8ec596SKim Phillips 
1736acdca31dSYuan Kang /*
1737acdca31dSYuan Kang  * ablkcipher_edesc - s/w-extended ablkcipher descriptor
1738acdca31dSYuan Kang  * @src_nents: number of segments in input scatterlist
1739643b39b0SYuan Kang  * @src_chained: if source is chained
1740acdca31dSYuan Kang  * @dst_nents: number of segments in output scatterlist
1741643b39b0SYuan Kang  * @dst_chained: if destination is chained
1742acdca31dSYuan Kang  * @iv_dma: dma address of iv for checking continuity and link table
1743acdca31dSYuan Kang  * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE)
1744a299c837SYuan Kang  * @sec4_sg_bytes: length of dma mapped sec4_sg space
1745a299c837SYuan Kang  * @sec4_sg_dma: bus physical mapped address of h/w link table
1746acdca31dSYuan Kang  * @hw_desc: the h/w job descriptor followed by any referenced link tables
1747acdca31dSYuan Kang  */
1748acdca31dSYuan Kang struct ablkcipher_edesc {
1749acdca31dSYuan Kang 	int src_nents;
1750643b39b0SYuan Kang 	bool src_chained;
1751acdca31dSYuan Kang 	int dst_nents;
1752643b39b0SYuan Kang 	bool dst_chained;
1753acdca31dSYuan Kang 	dma_addr_t iv_dma;
1754a299c837SYuan Kang 	int sec4_sg_bytes;
1755a299c837SYuan Kang 	dma_addr_t sec4_sg_dma;
1756a299c837SYuan Kang 	struct sec4_sg_entry *sec4_sg;
1757acdca31dSYuan Kang 	u32 hw_desc[0];
1758acdca31dSYuan Kang };
1759acdca31dSYuan Kang 
17601acebad3SYuan Kang static void caam_unmap(struct device *dev, struct scatterlist *src,
1761643b39b0SYuan Kang 		       struct scatterlist *dst, int src_nents,
1762643b39b0SYuan Kang 		       bool src_chained, int dst_nents, bool dst_chained,
1763a299c837SYuan Kang 		       dma_addr_t iv_dma, int ivsize, dma_addr_t sec4_sg_dma,
1764a299c837SYuan Kang 		       int sec4_sg_bytes)
17651acebad3SYuan Kang {
1766643b39b0SYuan Kang 	if (dst != src) {
1767643b39b0SYuan Kang 		dma_unmap_sg_chained(dev, src, src_nents ? : 1, DMA_TO_DEVICE,
1768643b39b0SYuan Kang 				     src_chained);
1769643b39b0SYuan Kang 		dma_unmap_sg_chained(dev, dst, dst_nents ? : 1, DMA_FROM_DEVICE,
1770643b39b0SYuan Kang 				     dst_chained);
17711acebad3SYuan Kang 	} else {
1772643b39b0SYuan Kang 		dma_unmap_sg_chained(dev, src, src_nents ? : 1,
1773643b39b0SYuan Kang 				     DMA_BIDIRECTIONAL, src_chained);
17741acebad3SYuan Kang 	}
17751acebad3SYuan Kang 
17761acebad3SYuan Kang 	if (iv_dma)
17771acebad3SYuan Kang 		dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);
1778a299c837SYuan Kang 	if (sec4_sg_bytes)
1779a299c837SYuan Kang 		dma_unmap_single(dev, sec4_sg_dma, sec4_sg_bytes,
17801acebad3SYuan Kang 				 DMA_TO_DEVICE);
17811acebad3SYuan Kang }
17821acebad3SYuan Kang 
17830e479300SYuan Kang static void aead_unmap(struct device *dev,
17840e479300SYuan Kang 		       struct aead_edesc *edesc,
17850e479300SYuan Kang 		       struct aead_request *req)
17868e8ec596SKim Phillips {
1787f2147b88SHerbert Xu 	caam_unmap(dev, req->src, req->dst,
1788f2147b88SHerbert Xu 		   edesc->src_nents, edesc->src_chained, edesc->dst_nents,
1789f2147b88SHerbert Xu 		   edesc->dst_chained, 0, 0,
1790f2147b88SHerbert Xu 		   edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
1791f2147b88SHerbert Xu }
1792f2147b88SHerbert Xu 
1793acdca31dSYuan Kang static void ablkcipher_unmap(struct device *dev,
1794acdca31dSYuan Kang 			     struct ablkcipher_edesc *edesc,
1795acdca31dSYuan Kang 			     struct ablkcipher_request *req)
1796acdca31dSYuan Kang {
1797acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
1798acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
1799acdca31dSYuan Kang 
1800acdca31dSYuan Kang 	caam_unmap(dev, req->src, req->dst,
1801643b39b0SYuan Kang 		   edesc->src_nents, edesc->src_chained, edesc->dst_nents,
1802643b39b0SYuan Kang 		   edesc->dst_chained, edesc->iv_dma, ivsize,
1803643b39b0SYuan Kang 		   edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
1804acdca31dSYuan Kang }
1805acdca31dSYuan Kang 
18060e479300SYuan Kang static void aead_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
18078e8ec596SKim Phillips 				   void *context)
18088e8ec596SKim Phillips {
18090e479300SYuan Kang 	struct aead_request *req = context;
18100e479300SYuan Kang 	struct aead_edesc *edesc;
1811f2147b88SHerbert Xu 
1812f2147b88SHerbert Xu #ifdef DEBUG
1813f2147b88SHerbert Xu 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
1814f2147b88SHerbert Xu #endif
1815f2147b88SHerbert Xu 
1816f2147b88SHerbert Xu 	edesc = container_of(desc, struct aead_edesc, hw_desc[0]);
1817f2147b88SHerbert Xu 
1818f2147b88SHerbert Xu 	if (err)
1819f2147b88SHerbert Xu 		caam_jr_strstatus(jrdev, err);
1820f2147b88SHerbert Xu 
1821f2147b88SHerbert Xu 	aead_unmap(jrdev, edesc, req);
1822f2147b88SHerbert Xu 
1823f2147b88SHerbert Xu 	kfree(edesc);
1824f2147b88SHerbert Xu 
1825f2147b88SHerbert Xu 	aead_request_complete(req, err);
1826f2147b88SHerbert Xu }
1827f2147b88SHerbert Xu 
18280e479300SYuan Kang static void aead_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
18298e8ec596SKim Phillips 				   void *context)
18308e8ec596SKim Phillips {
18310e479300SYuan Kang 	struct aead_request *req = context;
18320e479300SYuan Kang 	struct aead_edesc *edesc;
1833f2147b88SHerbert Xu 
1834f2147b88SHerbert Xu #ifdef DEBUG
1835f2147b88SHerbert Xu 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
1836f2147b88SHerbert Xu #endif
1837f2147b88SHerbert Xu 
1838f2147b88SHerbert Xu 	edesc = container_of(desc, struct aead_edesc, hw_desc[0]);
1839f2147b88SHerbert Xu 
1840f2147b88SHerbert Xu 	if (err)
1841f2147b88SHerbert Xu 		caam_jr_strstatus(jrdev, err);
1842f2147b88SHerbert Xu 
1843f2147b88SHerbert Xu 	aead_unmap(jrdev, edesc, req);
1844f2147b88SHerbert Xu 
1845f2147b88SHerbert Xu 	/*
1846f2147b88SHerbert Xu 	 * verify hw auth check passed else return -EBADMSG
1847f2147b88SHerbert Xu 	 */
1848f2147b88SHerbert Xu 	if ((err & JRSTA_CCBERR_ERRID_MASK) == JRSTA_CCBERR_ERRID_ICVCHK)
1849f2147b88SHerbert Xu 		err = -EBADMSG;
1850f2147b88SHerbert Xu 
1851f2147b88SHerbert Xu 	kfree(edesc);
1852f2147b88SHerbert Xu 
1853f2147b88SHerbert Xu 	aead_request_complete(req, err);
1854f2147b88SHerbert Xu }
1855f2147b88SHerbert Xu 
1856acdca31dSYuan Kang static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
1857acdca31dSYuan Kang 				   void *context)
1858acdca31dSYuan Kang {
1859acdca31dSYuan Kang 	struct ablkcipher_request *req = context;
1860acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
1861acdca31dSYuan Kang #ifdef DEBUG
1862acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
1863acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
1864acdca31dSYuan Kang 
1865acdca31dSYuan Kang 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
1866acdca31dSYuan Kang #endif
1867acdca31dSYuan Kang 
1868acdca31dSYuan Kang 	edesc = (struct ablkcipher_edesc *)((char *)desc -
1869acdca31dSYuan Kang 		 offsetof(struct ablkcipher_edesc, hw_desc));
1870acdca31dSYuan Kang 
1871fa9659cdSMarek Vasut 	if (err)
1872fa9659cdSMarek Vasut 		caam_jr_strstatus(jrdev, err);
1873acdca31dSYuan Kang 
1874acdca31dSYuan Kang #ifdef DEBUG
1875514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dstiv  @"__stringify(__LINE__)": ",
1876acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
1877acdca31dSYuan Kang 		       edesc->src_nents > 1 ? 100 : ivsize, 1);
1878514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dst    @"__stringify(__LINE__)": ",
1879acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src),
1880acdca31dSYuan Kang 		       edesc->dst_nents > 1 ? 100 : req->nbytes, 1);
1881acdca31dSYuan Kang #endif
1882acdca31dSYuan Kang 
1883acdca31dSYuan Kang 	ablkcipher_unmap(jrdev, edesc, req);
1884acdca31dSYuan Kang 	kfree(edesc);
1885acdca31dSYuan Kang 
1886acdca31dSYuan Kang 	ablkcipher_request_complete(req, err);
1887acdca31dSYuan Kang }
1888acdca31dSYuan Kang 
1889acdca31dSYuan Kang static void ablkcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
1890acdca31dSYuan Kang 				    void *context)
1891acdca31dSYuan Kang {
1892acdca31dSYuan Kang 	struct ablkcipher_request *req = context;
1893acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
1894acdca31dSYuan Kang #ifdef DEBUG
1895acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
1896acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
1897acdca31dSYuan Kang 
1898acdca31dSYuan Kang 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
1899acdca31dSYuan Kang #endif
1900acdca31dSYuan Kang 
1901acdca31dSYuan Kang 	edesc = (struct ablkcipher_edesc *)((char *)desc -
1902acdca31dSYuan Kang 		 offsetof(struct ablkcipher_edesc, hw_desc));
1903fa9659cdSMarek Vasut 	if (err)
1904fa9659cdSMarek Vasut 		caam_jr_strstatus(jrdev, err);
1905acdca31dSYuan Kang 
1906acdca31dSYuan Kang #ifdef DEBUG
1907514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dstiv  @"__stringify(__LINE__)": ",
1908acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
1909acdca31dSYuan Kang 		       ivsize, 1);
1910514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dst    @"__stringify(__LINE__)": ",
1911acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src),
1912acdca31dSYuan Kang 		       edesc->dst_nents > 1 ? 100 : req->nbytes, 1);
1913acdca31dSYuan Kang #endif
1914acdca31dSYuan Kang 
1915acdca31dSYuan Kang 	ablkcipher_unmap(jrdev, edesc, req);
1916acdca31dSYuan Kang 	kfree(edesc);
1917acdca31dSYuan Kang 
1918acdca31dSYuan Kang 	ablkcipher_request_complete(req, err);
1919acdca31dSYuan Kang }
1920acdca31dSYuan Kang 
19218e8ec596SKim Phillips /*
19221acebad3SYuan Kang  * Fill in aead job descriptor
19238e8ec596SKim Phillips  */
1924f2147b88SHerbert Xu static void init_aead_job(struct aead_request *req,
1925f2147b88SHerbert Xu 			  struct aead_edesc *edesc,
1926f2147b88SHerbert Xu 			  bool all_contig, bool encrypt)
1927f2147b88SHerbert Xu {
1928f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1929f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1930f2147b88SHerbert Xu 	int authsize = ctx->authsize;
1931f2147b88SHerbert Xu 	u32 *desc = edesc->hw_desc;
1932f2147b88SHerbert Xu 	u32 out_options, in_options;
1933f2147b88SHerbert Xu 	dma_addr_t dst_dma, src_dma;
1934f2147b88SHerbert Xu 	int len, sec4_sg_index = 0;
1935f2147b88SHerbert Xu 	dma_addr_t ptr;
1936f2147b88SHerbert Xu 	u32 *sh_desc;
1937f2147b88SHerbert Xu 
1938f2147b88SHerbert Xu 	sh_desc = encrypt ? ctx->sh_desc_enc : ctx->sh_desc_dec;
1939f2147b88SHerbert Xu 	ptr = encrypt ? ctx->sh_desc_enc_dma : ctx->sh_desc_dec_dma;
1940f2147b88SHerbert Xu 
1941f2147b88SHerbert Xu 	len = desc_len(sh_desc);
1942f2147b88SHerbert Xu 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
1943f2147b88SHerbert Xu 
1944f2147b88SHerbert Xu 	if (all_contig) {
1945f2147b88SHerbert Xu 		src_dma = sg_dma_address(req->src);
1946f2147b88SHerbert Xu 		in_options = 0;
1947f2147b88SHerbert Xu 	} else {
1948f2147b88SHerbert Xu 		src_dma = edesc->sec4_sg_dma;
1949f2147b88SHerbert Xu 		sec4_sg_index += edesc->src_nents;
1950f2147b88SHerbert Xu 		in_options = LDST_SGF;
1951f2147b88SHerbert Xu 	}
1952f2147b88SHerbert Xu 
1953f2147b88SHerbert Xu 	append_seq_in_ptr(desc, src_dma, req->assoclen + req->cryptlen,
1954f2147b88SHerbert Xu 			  in_options);
1955f2147b88SHerbert Xu 
1956f2147b88SHerbert Xu 	dst_dma = src_dma;
1957f2147b88SHerbert Xu 	out_options = in_options;
1958f2147b88SHerbert Xu 
1959f2147b88SHerbert Xu 	if (unlikely(req->src != req->dst)) {
1960f2147b88SHerbert Xu 		if (!edesc->dst_nents) {
1961f2147b88SHerbert Xu 			dst_dma = sg_dma_address(req->dst);
1962f2147b88SHerbert Xu 		} else {
1963f2147b88SHerbert Xu 			dst_dma = edesc->sec4_sg_dma +
1964f2147b88SHerbert Xu 				  sec4_sg_index *
1965f2147b88SHerbert Xu 				  sizeof(struct sec4_sg_entry);
1966f2147b88SHerbert Xu 			out_options = LDST_SGF;
1967f2147b88SHerbert Xu 		}
1968f2147b88SHerbert Xu 	}
1969f2147b88SHerbert Xu 
1970f2147b88SHerbert Xu 	if (encrypt)
1971f2147b88SHerbert Xu 		append_seq_out_ptr(desc, dst_dma,
1972f2147b88SHerbert Xu 				   req->assoclen + req->cryptlen + authsize,
1973f2147b88SHerbert Xu 				   out_options);
1974f2147b88SHerbert Xu 	else
1975f2147b88SHerbert Xu 		append_seq_out_ptr(desc, dst_dma,
1976f2147b88SHerbert Xu 				   req->assoclen + req->cryptlen - authsize,
1977f2147b88SHerbert Xu 				   out_options);
1978f2147b88SHerbert Xu 
1979f2147b88SHerbert Xu 	/* REG3 = assoclen */
1980f2147b88SHerbert Xu 	append_math_add_imm_u32(desc, REG3, ZERO, IMM, req->assoclen);
1981f2147b88SHerbert Xu }
1982f2147b88SHerbert Xu 
1983f2147b88SHerbert Xu static void init_gcm_job(struct aead_request *req,
1984f2147b88SHerbert Xu 			 struct aead_edesc *edesc,
1985f2147b88SHerbert Xu 			 bool all_contig, bool encrypt)
1986f2147b88SHerbert Xu {
1987f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
1988f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1989f2147b88SHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
1990f2147b88SHerbert Xu 	u32 *desc = edesc->hw_desc;
1991f2147b88SHerbert Xu 	bool generic_gcm = (ivsize == 12);
1992f2147b88SHerbert Xu 	unsigned int last;
1993f2147b88SHerbert Xu 
1994f2147b88SHerbert Xu 	init_aead_job(req, edesc, all_contig, encrypt);
1995f2147b88SHerbert Xu 
1996f2147b88SHerbert Xu 	/* BUG This should not be specific to generic GCM. */
1997f2147b88SHerbert Xu 	last = 0;
1998f2147b88SHerbert Xu 	if (encrypt && generic_gcm && !(req->assoclen + req->cryptlen))
1999f2147b88SHerbert Xu 		last = FIFOLD_TYPE_LAST1;
2000f2147b88SHerbert Xu 
2001f2147b88SHerbert Xu 	/* Read GCM IV */
2002f2147b88SHerbert Xu 	append_cmd(desc, CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 | IMMEDIATE |
2003f2147b88SHerbert Xu 			 FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 | 12 | last);
2004f2147b88SHerbert Xu 	/* Append Salt */
2005f2147b88SHerbert Xu 	if (!generic_gcm)
2006f2147b88SHerbert Xu 		append_data(desc, ctx->key + ctx->enckeylen, 4);
2007f2147b88SHerbert Xu 	/* Append IV */
2008f2147b88SHerbert Xu 	append_data(desc, req->iv, ivsize);
2009f2147b88SHerbert Xu 	/* End of blank commands */
2010f2147b88SHerbert Xu }
2011f2147b88SHerbert Xu 
2012479bcc7cSHerbert Xu static void init_authenc_job(struct aead_request *req,
20131acebad3SYuan Kang 			     struct aead_edesc *edesc,
2014479bcc7cSHerbert Xu 			     bool all_contig, bool encrypt)
20151acebad3SYuan Kang {
20161acebad3SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
2017479bcc7cSHerbert Xu 	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
2018479bcc7cSHerbert Xu 						 struct caam_aead_alg, aead);
2019479bcc7cSHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
20201acebad3SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
2021479bcc7cSHerbert Xu 	const bool ctr_mode = ((ctx->class1_alg_type & OP_ALG_AAI_MASK) ==
2022479bcc7cSHerbert Xu 			       OP_ALG_AAI_CTR_MOD128);
2023479bcc7cSHerbert Xu 	const bool is_rfc3686 = alg->caam.rfc3686;
20241acebad3SYuan Kang 	u32 *desc = edesc->hw_desc;
2025479bcc7cSHerbert Xu 	u32 ivoffset = 0;
20268e8ec596SKim Phillips 
2027479bcc7cSHerbert Xu 	/*
2028479bcc7cSHerbert Xu 	 * AES-CTR needs to load IV in CONTEXT1 reg
2029479bcc7cSHerbert Xu 	 * at an offset of 128bits (16bytes)
2030479bcc7cSHerbert Xu 	 * CONTEXT1[255:128] = IV
2031479bcc7cSHerbert Xu 	 */
2032479bcc7cSHerbert Xu 	if (ctr_mode)
2033479bcc7cSHerbert Xu 		ivoffset = 16;
20348e8ec596SKim Phillips 
2035479bcc7cSHerbert Xu 	/*
2036479bcc7cSHerbert Xu 	 * RFC3686 specific:
2037479bcc7cSHerbert Xu 	 *	CONTEXT1[255:128] = {NONCE, IV, COUNTER}
2038479bcc7cSHerbert Xu 	 */
2039479bcc7cSHerbert Xu 	if (is_rfc3686)
2040479bcc7cSHerbert Xu 		ivoffset = 16 + CTR_RFC3686_NONCE_SIZE;
2041bac68f2cSTudor Ambarus 
2042479bcc7cSHerbert Xu 	init_aead_job(req, edesc, all_contig, encrypt);
20431acebad3SYuan Kang 
2044479bcc7cSHerbert Xu 	if (ivsize && (is_rfc3686 || !(alg->caam.geniv && encrypt)))
2045479bcc7cSHerbert Xu 		append_load_as_imm(desc, req->iv, ivsize,
2046479bcc7cSHerbert Xu 				   LDST_CLASS_1_CCB |
2047479bcc7cSHerbert Xu 				   LDST_SRCDST_BYTE_CONTEXT |
2048479bcc7cSHerbert Xu 				   (ivoffset << LDST_OFFSET_SHIFT));
20498e8ec596SKim Phillips }
20508e8ec596SKim Phillips 
20518e8ec596SKim Phillips /*
2052acdca31dSYuan Kang  * Fill in ablkcipher job descriptor
2053acdca31dSYuan Kang  */
2054acdca31dSYuan Kang static void init_ablkcipher_job(u32 *sh_desc, dma_addr_t ptr,
2055acdca31dSYuan Kang 				struct ablkcipher_edesc *edesc,
2056acdca31dSYuan Kang 				struct ablkcipher_request *req,
2057acdca31dSYuan Kang 				bool iv_contig)
2058acdca31dSYuan Kang {
2059acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
2060acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
2061acdca31dSYuan Kang 	u32 *desc = edesc->hw_desc;
2062acdca31dSYuan Kang 	u32 out_options = 0, in_options;
2063acdca31dSYuan Kang 	dma_addr_t dst_dma, src_dma;
2064a299c837SYuan Kang 	int len, sec4_sg_index = 0;
2065acdca31dSYuan Kang 
2066acdca31dSYuan Kang #ifdef DEBUG
2067514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "presciv@"__stringify(__LINE__)": ",
2068acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
2069acdca31dSYuan Kang 		       ivsize, 1);
2070514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "src    @"__stringify(__LINE__)": ",
2071acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src),
2072acdca31dSYuan Kang 		       edesc->src_nents ? 100 : req->nbytes, 1);
2073acdca31dSYuan Kang #endif
2074acdca31dSYuan Kang 
2075acdca31dSYuan Kang 	len = desc_len(sh_desc);
2076acdca31dSYuan Kang 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
2077acdca31dSYuan Kang 
2078acdca31dSYuan Kang 	if (iv_contig) {
2079acdca31dSYuan Kang 		src_dma = edesc->iv_dma;
2080acdca31dSYuan Kang 		in_options = 0;
2081acdca31dSYuan Kang 	} else {
2082a299c837SYuan Kang 		src_dma = edesc->sec4_sg_dma;
208335b82e55SCristian Stoica 		sec4_sg_index += edesc->src_nents + 1;
2084acdca31dSYuan Kang 		in_options = LDST_SGF;
2085acdca31dSYuan Kang 	}
2086acdca31dSYuan Kang 	append_seq_in_ptr(desc, src_dma, req->nbytes + ivsize, in_options);
2087acdca31dSYuan Kang 
2088acdca31dSYuan Kang 	if (likely(req->src == req->dst)) {
2089acdca31dSYuan Kang 		if (!edesc->src_nents && iv_contig) {
2090acdca31dSYuan Kang 			dst_dma = sg_dma_address(req->src);
2091acdca31dSYuan Kang 		} else {
2092a299c837SYuan Kang 			dst_dma = edesc->sec4_sg_dma +
2093a299c837SYuan Kang 				sizeof(struct sec4_sg_entry);
2094acdca31dSYuan Kang 			out_options = LDST_SGF;
2095acdca31dSYuan Kang 		}
2096acdca31dSYuan Kang 	} else {
2097acdca31dSYuan Kang 		if (!edesc->dst_nents) {
2098acdca31dSYuan Kang 			dst_dma = sg_dma_address(req->dst);
2099acdca31dSYuan Kang 		} else {
2100a299c837SYuan Kang 			dst_dma = edesc->sec4_sg_dma +
2101a299c837SYuan Kang 				sec4_sg_index * sizeof(struct sec4_sg_entry);
2102acdca31dSYuan Kang 			out_options = LDST_SGF;
2103acdca31dSYuan Kang 		}
2104acdca31dSYuan Kang 	}
2105acdca31dSYuan Kang 	append_seq_out_ptr(desc, dst_dma, req->nbytes, out_options);
2106acdca31dSYuan Kang }
2107acdca31dSYuan Kang 
2108acdca31dSYuan Kang /*
21097222d1a3SCatalin Vasile  * Fill in ablkcipher givencrypt job descriptor
21107222d1a3SCatalin Vasile  */
21117222d1a3SCatalin Vasile static void init_ablkcipher_giv_job(u32 *sh_desc, dma_addr_t ptr,
21127222d1a3SCatalin Vasile 				    struct ablkcipher_edesc *edesc,
21137222d1a3SCatalin Vasile 				    struct ablkcipher_request *req,
21147222d1a3SCatalin Vasile 				    bool iv_contig)
21157222d1a3SCatalin Vasile {
21167222d1a3SCatalin Vasile 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
21177222d1a3SCatalin Vasile 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
21187222d1a3SCatalin Vasile 	u32 *desc = edesc->hw_desc;
21197222d1a3SCatalin Vasile 	u32 out_options, in_options;
21207222d1a3SCatalin Vasile 	dma_addr_t dst_dma, src_dma;
21217222d1a3SCatalin Vasile 	int len, sec4_sg_index = 0;
21227222d1a3SCatalin Vasile 
21237222d1a3SCatalin Vasile #ifdef DEBUG
21247222d1a3SCatalin Vasile 	print_hex_dump(KERN_ERR, "presciv@" __stringify(__LINE__) ": ",
21257222d1a3SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
21267222d1a3SCatalin Vasile 		       ivsize, 1);
21277222d1a3SCatalin Vasile 	print_hex_dump(KERN_ERR, "src    @" __stringify(__LINE__) ": ",
21287222d1a3SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src),
21297222d1a3SCatalin Vasile 		       edesc->src_nents ? 100 : req->nbytes, 1);
21307222d1a3SCatalin Vasile #endif
21317222d1a3SCatalin Vasile 
21327222d1a3SCatalin Vasile 	len = desc_len(sh_desc);
21337222d1a3SCatalin Vasile 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
21347222d1a3SCatalin Vasile 
21357222d1a3SCatalin Vasile 	if (!edesc->src_nents) {
21367222d1a3SCatalin Vasile 		src_dma = sg_dma_address(req->src);
21377222d1a3SCatalin Vasile 		in_options = 0;
21387222d1a3SCatalin Vasile 	} else {
21397222d1a3SCatalin Vasile 		src_dma = edesc->sec4_sg_dma;
21407222d1a3SCatalin Vasile 		sec4_sg_index += edesc->src_nents;
21417222d1a3SCatalin Vasile 		in_options = LDST_SGF;
21427222d1a3SCatalin Vasile 	}
21437222d1a3SCatalin Vasile 	append_seq_in_ptr(desc, src_dma, req->nbytes, in_options);
21447222d1a3SCatalin Vasile 
21457222d1a3SCatalin Vasile 	if (iv_contig) {
21467222d1a3SCatalin Vasile 		dst_dma = edesc->iv_dma;
21477222d1a3SCatalin Vasile 		out_options = 0;
21487222d1a3SCatalin Vasile 	} else {
21497222d1a3SCatalin Vasile 		dst_dma = edesc->sec4_sg_dma +
21507222d1a3SCatalin Vasile 			  sec4_sg_index * sizeof(struct sec4_sg_entry);
21517222d1a3SCatalin Vasile 		out_options = LDST_SGF;
21527222d1a3SCatalin Vasile 	}
21537222d1a3SCatalin Vasile 	append_seq_out_ptr(desc, dst_dma, req->nbytes + ivsize, out_options);
21547222d1a3SCatalin Vasile }
21557222d1a3SCatalin Vasile 
21567222d1a3SCatalin Vasile /*
21571acebad3SYuan Kang  * allocate and map the aead extended descriptor
21588e8ec596SKim Phillips  */
2159f2147b88SHerbert Xu static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
2160f2147b88SHerbert Xu 					   int desc_bytes, bool *all_contig_ptr,
2161f2147b88SHerbert Xu 					   bool encrypt)
2162f2147b88SHerbert Xu {
2163f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
2164f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
2165f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
2166f2147b88SHerbert Xu 	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
2167f2147b88SHerbert Xu 		       CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC;
2168f2147b88SHerbert Xu 	int src_nents, dst_nents = 0;
2169f2147b88SHerbert Xu 	struct aead_edesc *edesc;
2170f2147b88SHerbert Xu 	int sgc;
2171f2147b88SHerbert Xu 	bool all_contig = true;
2172f2147b88SHerbert Xu 	bool src_chained = false, dst_chained = false;
2173f2147b88SHerbert Xu 	int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes;
2174f2147b88SHerbert Xu 	unsigned int authsize = ctx->authsize;
2175f2147b88SHerbert Xu 
2176f2147b88SHerbert Xu 	if (unlikely(req->dst != req->src)) {
2177f2147b88SHerbert Xu 		src_nents = sg_count(req->src, req->assoclen + req->cryptlen,
2178f2147b88SHerbert Xu 				     &src_chained);
2179f2147b88SHerbert Xu 		dst_nents = sg_count(req->dst,
2180f2147b88SHerbert Xu 				     req->assoclen + req->cryptlen +
2181f2147b88SHerbert Xu 					(encrypt ? authsize : (-authsize)),
2182f2147b88SHerbert Xu 				     &dst_chained);
2183f2147b88SHerbert Xu 	} else {
2184f2147b88SHerbert Xu 		src_nents = sg_count(req->src,
2185f2147b88SHerbert Xu 				     req->assoclen + req->cryptlen +
2186f2147b88SHerbert Xu 					(encrypt ? authsize : 0),
2187f2147b88SHerbert Xu 				     &src_chained);
2188f2147b88SHerbert Xu 	}
2189f2147b88SHerbert Xu 
2190f2147b88SHerbert Xu 	/* Check if data are contiguous. */
2191f2147b88SHerbert Xu 	all_contig = !src_nents;
2192f2147b88SHerbert Xu 	if (!all_contig) {
2193f2147b88SHerbert Xu 		src_nents = src_nents ? : 1;
2194f2147b88SHerbert Xu 		sec4_sg_len = src_nents;
2195f2147b88SHerbert Xu 	}
2196f2147b88SHerbert Xu 
2197f2147b88SHerbert Xu 	sec4_sg_len += dst_nents;
2198f2147b88SHerbert Xu 
2199f2147b88SHerbert Xu 	sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry);
2200f2147b88SHerbert Xu 
2201f2147b88SHerbert Xu 	/* allocate space for base edesc and hw desc commands, link tables */
2202dde20ae9SVictoria Milhoan 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes,
2203dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
2204f2147b88SHerbert Xu 	if (!edesc) {
2205f2147b88SHerbert Xu 		dev_err(jrdev, "could not allocate extended descriptor\n");
2206f2147b88SHerbert Xu 		return ERR_PTR(-ENOMEM);
2207f2147b88SHerbert Xu 	}
2208f2147b88SHerbert Xu 
2209f2147b88SHerbert Xu 	if (likely(req->src == req->dst)) {
2210f2147b88SHerbert Xu 		sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
2211f2147b88SHerbert Xu 					 DMA_BIDIRECTIONAL, src_chained);
2212f2147b88SHerbert Xu 		if (unlikely(!sgc)) {
2213f2147b88SHerbert Xu 			dev_err(jrdev, "unable to map source\n");
2214f2147b88SHerbert Xu 			kfree(edesc);
2215f2147b88SHerbert Xu 			return ERR_PTR(-ENOMEM);
2216f2147b88SHerbert Xu 		}
2217f2147b88SHerbert Xu 	} else {
2218f2147b88SHerbert Xu 		sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
2219f2147b88SHerbert Xu 					 DMA_TO_DEVICE, src_chained);
2220f2147b88SHerbert Xu 		if (unlikely(!sgc)) {
2221f2147b88SHerbert Xu 			dev_err(jrdev, "unable to map source\n");
2222f2147b88SHerbert Xu 			kfree(edesc);
2223f2147b88SHerbert Xu 			return ERR_PTR(-ENOMEM);
2224f2147b88SHerbert Xu 		}
2225f2147b88SHerbert Xu 
2226f2147b88SHerbert Xu 		sgc = dma_map_sg_chained(jrdev, req->dst, dst_nents ? : 1,
2227f2147b88SHerbert Xu 					 DMA_FROM_DEVICE, dst_chained);
2228f2147b88SHerbert Xu 		if (unlikely(!sgc)) {
2229f2147b88SHerbert Xu 			dev_err(jrdev, "unable to map destination\n");
2230f2147b88SHerbert Xu 			dma_unmap_sg_chained(jrdev, req->src, src_nents ? : 1,
2231f2147b88SHerbert Xu 					     DMA_TO_DEVICE, src_chained);
2232f2147b88SHerbert Xu 			kfree(edesc);
2233f2147b88SHerbert Xu 			return ERR_PTR(-ENOMEM);
2234f2147b88SHerbert Xu 		}
2235f2147b88SHerbert Xu 	}
2236f2147b88SHerbert Xu 
2237f2147b88SHerbert Xu 	edesc->src_nents = src_nents;
2238f2147b88SHerbert Xu 	edesc->src_chained = src_chained;
2239f2147b88SHerbert Xu 	edesc->dst_nents = dst_nents;
2240f2147b88SHerbert Xu 	edesc->dst_chained = dst_chained;
2241f2147b88SHerbert Xu 	edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) +
2242f2147b88SHerbert Xu 			 desc_bytes;
2243f2147b88SHerbert Xu 	*all_contig_ptr = all_contig;
2244f2147b88SHerbert Xu 
2245f2147b88SHerbert Xu 	sec4_sg_index = 0;
2246f2147b88SHerbert Xu 	if (!all_contig) {
22477793bda8SHerbert Xu 		sg_to_sec4_sg_last(req->src, src_nents,
2248f2147b88SHerbert Xu 			      edesc->sec4_sg + sec4_sg_index, 0);
2249f2147b88SHerbert Xu 		sec4_sg_index += src_nents;
2250f2147b88SHerbert Xu 	}
2251f2147b88SHerbert Xu 	if (dst_nents) {
2252f2147b88SHerbert Xu 		sg_to_sec4_sg_last(req->dst, dst_nents,
2253f2147b88SHerbert Xu 				   edesc->sec4_sg + sec4_sg_index, 0);
2254f2147b88SHerbert Xu 	}
2255f2147b88SHerbert Xu 
2256f2147b88SHerbert Xu 	if (!sec4_sg_bytes)
2257f2147b88SHerbert Xu 		return edesc;
2258f2147b88SHerbert Xu 
2259f2147b88SHerbert Xu 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
2260f2147b88SHerbert Xu 					    sec4_sg_bytes, DMA_TO_DEVICE);
2261f2147b88SHerbert Xu 	if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
2262f2147b88SHerbert Xu 		dev_err(jrdev, "unable to map S/G table\n");
2263f2147b88SHerbert Xu 		aead_unmap(jrdev, edesc, req);
2264f2147b88SHerbert Xu 		kfree(edesc);
2265f2147b88SHerbert Xu 		return ERR_PTR(-ENOMEM);
2266f2147b88SHerbert Xu 	}
2267f2147b88SHerbert Xu 
2268f2147b88SHerbert Xu 	edesc->sec4_sg_bytes = sec4_sg_bytes;
2269f2147b88SHerbert Xu 
2270f2147b88SHerbert Xu 	return edesc;
2271f2147b88SHerbert Xu }
2272f2147b88SHerbert Xu 
2273f2147b88SHerbert Xu static int gcm_encrypt(struct aead_request *req)
22748e8ec596SKim Phillips {
22750e479300SYuan Kang 	struct aead_edesc *edesc;
22768e8ec596SKim Phillips 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
22778e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
22788e8ec596SKim Phillips 	struct device *jrdev = ctx->jrdev;
22791acebad3SYuan Kang 	bool all_contig;
22808e8ec596SKim Phillips 	u32 *desc;
22811acebad3SYuan Kang 	int ret = 0;
22821acebad3SYuan Kang 
22838e8ec596SKim Phillips 	/* allocate extended descriptor */
2284f2147b88SHerbert Xu 	edesc = aead_edesc_alloc(req, GCM_DESC_JOB_IO_LEN, &all_contig, true);
22858e8ec596SKim Phillips 	if (IS_ERR(edesc))
22868e8ec596SKim Phillips 		return PTR_ERR(edesc);
22878e8ec596SKim Phillips 
22881acebad3SYuan Kang 	/* Create and submit job descriptor */
2289f2147b88SHerbert Xu 	init_gcm_job(req, edesc, all_contig, true);
22901acebad3SYuan Kang #ifdef DEBUG
2291514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
22921acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
22931acebad3SYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
22941acebad3SYuan Kang #endif
22951acebad3SYuan Kang 
22968e8ec596SKim Phillips 	desc = edesc->hw_desc;
22971acebad3SYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
22981acebad3SYuan Kang 	if (!ret) {
22991acebad3SYuan Kang 		ret = -EINPROGRESS;
23001acebad3SYuan Kang 	} else {
23011acebad3SYuan Kang 		aead_unmap(jrdev, edesc, req);
23021acebad3SYuan Kang 		kfree(edesc);
23031acebad3SYuan Kang 	}
23048e8ec596SKim Phillips 
23051acebad3SYuan Kang 	return ret;
23068e8ec596SKim Phillips }
23078e8ec596SKim Phillips 
230846218750SHerbert Xu static int ipsec_gcm_encrypt(struct aead_request *req)
230946218750SHerbert Xu {
231046218750SHerbert Xu 	if (req->assoclen < 8)
231146218750SHerbert Xu 		return -EINVAL;
231246218750SHerbert Xu 
231346218750SHerbert Xu 	return gcm_encrypt(req);
231446218750SHerbert Xu }
231546218750SHerbert Xu 
2316479bcc7cSHerbert Xu static int aead_encrypt(struct aead_request *req)
23178e8ec596SKim Phillips {
23181acebad3SYuan Kang 	struct aead_edesc *edesc;
23190e479300SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
23200e479300SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
23210e479300SYuan Kang 	struct device *jrdev = ctx->jrdev;
23221acebad3SYuan Kang 	bool all_contig;
23230e479300SYuan Kang 	u32 *desc;
23241acebad3SYuan Kang 	int ret = 0;
23250e479300SYuan Kang 
23260e479300SYuan Kang 	/* allocate extended descriptor */
2327479bcc7cSHerbert Xu 	edesc = aead_edesc_alloc(req, AUTHENC_DESC_JOB_IO_LEN,
2328479bcc7cSHerbert Xu 				 &all_contig, true);
23290e479300SYuan Kang 	if (IS_ERR(edesc))
23300e479300SYuan Kang 		return PTR_ERR(edesc);
23310e479300SYuan Kang 
2332f2147b88SHerbert Xu 	/* Create and submit job descriptor */
2333479bcc7cSHerbert Xu 	init_authenc_job(req, edesc, all_contig, true);
23341acebad3SYuan Kang #ifdef DEBUG
2335f2147b88SHerbert Xu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
2336f2147b88SHerbert Xu 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
2337f2147b88SHerbert Xu 		       desc_bytes(edesc->hw_desc), 1);
23381acebad3SYuan Kang #endif
23391acebad3SYuan Kang 
2340f2147b88SHerbert Xu 	desc = edesc->hw_desc;
2341479bcc7cSHerbert Xu 	ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
2342f2147b88SHerbert Xu 	if (!ret) {
2343f2147b88SHerbert Xu 		ret = -EINPROGRESS;
2344f2147b88SHerbert Xu 	} else {
2345479bcc7cSHerbert Xu 		aead_unmap(jrdev, edesc, req);
2346f2147b88SHerbert Xu 		kfree(edesc);
2347f2147b88SHerbert Xu 	}
2348f2147b88SHerbert Xu 
2349f2147b88SHerbert Xu 	return ret;
2350f2147b88SHerbert Xu }
2351f2147b88SHerbert Xu 
2352f2147b88SHerbert Xu static int gcm_decrypt(struct aead_request *req)
2353f2147b88SHerbert Xu {
2354f2147b88SHerbert Xu 	struct aead_edesc *edesc;
2355f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
2356f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
2357f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
2358f2147b88SHerbert Xu 	bool all_contig;
2359f2147b88SHerbert Xu 	u32 *desc;
2360f2147b88SHerbert Xu 	int ret = 0;
2361f2147b88SHerbert Xu 
2362f2147b88SHerbert Xu 	/* allocate extended descriptor */
2363f2147b88SHerbert Xu 	edesc = aead_edesc_alloc(req, GCM_DESC_JOB_IO_LEN, &all_contig, false);
2364f2147b88SHerbert Xu 	if (IS_ERR(edesc))
2365f2147b88SHerbert Xu 		return PTR_ERR(edesc);
2366f2147b88SHerbert Xu 
23671acebad3SYuan Kang 	/* Create and submit job descriptor*/
2368f2147b88SHerbert Xu 	init_gcm_job(req, edesc, all_contig, false);
23691acebad3SYuan Kang #ifdef DEBUG
2370514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
23711acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
23721acebad3SYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
23731acebad3SYuan Kang #endif
23741acebad3SYuan Kang 
23750e479300SYuan Kang 	desc = edesc->hw_desc;
23761acebad3SYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
23771acebad3SYuan Kang 	if (!ret) {
23781acebad3SYuan Kang 		ret = -EINPROGRESS;
23791acebad3SYuan Kang 	} else {
23801acebad3SYuan Kang 		aead_unmap(jrdev, edesc, req);
23811acebad3SYuan Kang 		kfree(edesc);
23821acebad3SYuan Kang 	}
23830e479300SYuan Kang 
23841acebad3SYuan Kang 	return ret;
23851acebad3SYuan Kang }
23860e479300SYuan Kang 
238746218750SHerbert Xu static int ipsec_gcm_decrypt(struct aead_request *req)
238846218750SHerbert Xu {
238946218750SHerbert Xu 	if (req->assoclen < 8)
239046218750SHerbert Xu 		return -EINVAL;
239146218750SHerbert Xu 
239246218750SHerbert Xu 	return gcm_decrypt(req);
239346218750SHerbert Xu }
239446218750SHerbert Xu 
2395479bcc7cSHerbert Xu static int aead_decrypt(struct aead_request *req)
2396f2147b88SHerbert Xu {
2397f2147b88SHerbert Xu 	struct aead_edesc *edesc;
2398f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
2399f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
2400f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
2401f2147b88SHerbert Xu 	bool all_contig;
2402f2147b88SHerbert Xu 	u32 *desc;
2403f2147b88SHerbert Xu 	int ret = 0;
2404f2147b88SHerbert Xu 
2405f2147b88SHerbert Xu 	/* allocate extended descriptor */
2406479bcc7cSHerbert Xu 	edesc = aead_edesc_alloc(req, AUTHENC_DESC_JOB_IO_LEN,
2407479bcc7cSHerbert Xu 				 &all_contig, false);
2408f2147b88SHerbert Xu 	if (IS_ERR(edesc))
2409f2147b88SHerbert Xu 		return PTR_ERR(edesc);
2410f2147b88SHerbert Xu 
2411f2147b88SHerbert Xu #ifdef DEBUG
2412f2147b88SHerbert Xu 	print_hex_dump(KERN_ERR, "dec src@"__stringify(__LINE__)": ",
2413f2147b88SHerbert Xu 		       DUMP_PREFIX_ADDRESS, 16, 4, sg_virt(req->src),
2414479bcc7cSHerbert Xu 		       req->assoclen + req->cryptlen, 1);
2415f2147b88SHerbert Xu #endif
2416f2147b88SHerbert Xu 
2417f2147b88SHerbert Xu 	/* Create and submit job descriptor*/
2418479bcc7cSHerbert Xu 	init_authenc_job(req, edesc, all_contig, false);
2419f2147b88SHerbert Xu #ifdef DEBUG
2420f2147b88SHerbert Xu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
2421f2147b88SHerbert Xu 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
2422f2147b88SHerbert Xu 		       desc_bytes(edesc->hw_desc), 1);
2423f2147b88SHerbert Xu #endif
2424f2147b88SHerbert Xu 
2425f2147b88SHerbert Xu 	desc = edesc->hw_desc;
2426479bcc7cSHerbert Xu 	ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
2427f2147b88SHerbert Xu 	if (!ret) {
2428f2147b88SHerbert Xu 		ret = -EINPROGRESS;
2429f2147b88SHerbert Xu 	} else {
2430479bcc7cSHerbert Xu 		aead_unmap(jrdev, edesc, req);
2431f2147b88SHerbert Xu 		kfree(edesc);
2432f2147b88SHerbert Xu 	}
2433f2147b88SHerbert Xu 
2434f2147b88SHerbert Xu 	return ret;
2435f2147b88SHerbert Xu }
2436f2147b88SHerbert Xu 
2437479bcc7cSHerbert Xu static int aead_givdecrypt(struct aead_request *req)
24381acebad3SYuan Kang {
24391acebad3SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
2440479bcc7cSHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
24410e479300SYuan Kang 
2442479bcc7cSHerbert Xu 	if (req->cryptlen < ivsize)
2443479bcc7cSHerbert Xu 		return -EINVAL;
24440e479300SYuan Kang 
2445479bcc7cSHerbert Xu 	req->cryptlen -= ivsize;
2446479bcc7cSHerbert Xu 	req->assoclen += ivsize;
24471acebad3SYuan Kang 
2448479bcc7cSHerbert Xu 	return aead_decrypt(req);
2449ae4a825fSHoria Geanta }
2450ae4a825fSHoria Geanta 
2451acdca31dSYuan Kang /*
2452acdca31dSYuan Kang  * allocate and map the ablkcipher extended descriptor for ablkcipher
2453acdca31dSYuan Kang  */
2454acdca31dSYuan Kang static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request
2455acdca31dSYuan Kang 						       *req, int desc_bytes,
2456acdca31dSYuan Kang 						       bool *iv_contig_out)
2457acdca31dSYuan Kang {
2458acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
2459acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
2460acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
2461acdca31dSYuan Kang 	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
2462acdca31dSYuan Kang 					  CRYPTO_TFM_REQ_MAY_SLEEP)) ?
2463acdca31dSYuan Kang 		       GFP_KERNEL : GFP_ATOMIC;
2464a299c837SYuan Kang 	int src_nents, dst_nents = 0, sec4_sg_bytes;
2465acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
2466acdca31dSYuan Kang 	dma_addr_t iv_dma = 0;
2467acdca31dSYuan Kang 	bool iv_contig = false;
2468acdca31dSYuan Kang 	int sgc;
2469acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
2470643b39b0SYuan Kang 	bool src_chained = false, dst_chained = false;
2471a299c837SYuan Kang 	int sec4_sg_index;
2472acdca31dSYuan Kang 
2473643b39b0SYuan Kang 	src_nents = sg_count(req->src, req->nbytes, &src_chained);
2474acdca31dSYuan Kang 
2475643b39b0SYuan Kang 	if (req->dst != req->src)
2476643b39b0SYuan Kang 		dst_nents = sg_count(req->dst, req->nbytes, &dst_chained);
2477acdca31dSYuan Kang 
2478acdca31dSYuan Kang 	if (likely(req->src == req->dst)) {
2479643b39b0SYuan Kang 		sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
2480643b39b0SYuan Kang 					 DMA_BIDIRECTIONAL, src_chained);
2481acdca31dSYuan Kang 	} else {
2482643b39b0SYuan Kang 		sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
2483643b39b0SYuan Kang 					 DMA_TO_DEVICE, src_chained);
2484643b39b0SYuan Kang 		sgc = dma_map_sg_chained(jrdev, req->dst, dst_nents ? : 1,
2485643b39b0SYuan Kang 					 DMA_FROM_DEVICE, dst_chained);
2486acdca31dSYuan Kang 	}
2487acdca31dSYuan Kang 
2488ce572085SHoria Geanta 	iv_dma = dma_map_single(jrdev, req->info, ivsize, DMA_TO_DEVICE);
2489ce572085SHoria Geanta 	if (dma_mapping_error(jrdev, iv_dma)) {
2490ce572085SHoria Geanta 		dev_err(jrdev, "unable to map IV\n");
2491ce572085SHoria Geanta 		return ERR_PTR(-ENOMEM);
2492ce572085SHoria Geanta 	}
2493ce572085SHoria Geanta 
2494acdca31dSYuan Kang 	/*
2495acdca31dSYuan Kang 	 * Check if iv can be contiguous with source and destination.
2496acdca31dSYuan Kang 	 * If so, include it. If not, create scatterlist.
2497acdca31dSYuan Kang 	 */
2498acdca31dSYuan Kang 	if (!src_nents && iv_dma + ivsize == sg_dma_address(req->src))
2499acdca31dSYuan Kang 		iv_contig = true;
2500acdca31dSYuan Kang 	else
2501acdca31dSYuan Kang 		src_nents = src_nents ? : 1;
2502a299c837SYuan Kang 	sec4_sg_bytes = ((iv_contig ? 0 : 1) + src_nents + dst_nents) *
2503a299c837SYuan Kang 			sizeof(struct sec4_sg_entry);
2504acdca31dSYuan Kang 
2505acdca31dSYuan Kang 	/* allocate space for base edesc and hw desc commands, link tables */
2506dde20ae9SVictoria Milhoan 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes,
2507dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
2508acdca31dSYuan Kang 	if (!edesc) {
2509acdca31dSYuan Kang 		dev_err(jrdev, "could not allocate extended descriptor\n");
2510acdca31dSYuan Kang 		return ERR_PTR(-ENOMEM);
2511acdca31dSYuan Kang 	}
2512acdca31dSYuan Kang 
2513acdca31dSYuan Kang 	edesc->src_nents = src_nents;
2514643b39b0SYuan Kang 	edesc->src_chained = src_chained;
2515acdca31dSYuan Kang 	edesc->dst_nents = dst_nents;
2516643b39b0SYuan Kang 	edesc->dst_chained = dst_chained;
2517a299c837SYuan Kang 	edesc->sec4_sg_bytes = sec4_sg_bytes;
2518a299c837SYuan Kang 	edesc->sec4_sg = (void *)edesc + sizeof(struct ablkcipher_edesc) +
2519acdca31dSYuan Kang 			 desc_bytes;
2520acdca31dSYuan Kang 
2521a299c837SYuan Kang 	sec4_sg_index = 0;
2522acdca31dSYuan Kang 	if (!iv_contig) {
2523a299c837SYuan Kang 		dma_to_sec4_sg_one(edesc->sec4_sg, iv_dma, ivsize, 0);
2524a299c837SYuan Kang 		sg_to_sec4_sg_last(req->src, src_nents,
2525a299c837SYuan Kang 				   edesc->sec4_sg + 1, 0);
2526a299c837SYuan Kang 		sec4_sg_index += 1 + src_nents;
2527acdca31dSYuan Kang 	}
2528acdca31dSYuan Kang 
2529643b39b0SYuan Kang 	if (dst_nents) {
2530a299c837SYuan Kang 		sg_to_sec4_sg_last(req->dst, dst_nents,
2531a299c837SYuan Kang 			edesc->sec4_sg + sec4_sg_index, 0);
2532acdca31dSYuan Kang 	}
2533acdca31dSYuan Kang 
2534a299c837SYuan Kang 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
2535a299c837SYuan Kang 					    sec4_sg_bytes, DMA_TO_DEVICE);
2536ce572085SHoria Geanta 	if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
2537ce572085SHoria Geanta 		dev_err(jrdev, "unable to map S/G table\n");
2538ce572085SHoria Geanta 		return ERR_PTR(-ENOMEM);
2539ce572085SHoria Geanta 	}
2540ce572085SHoria Geanta 
2541acdca31dSYuan Kang 	edesc->iv_dma = iv_dma;
2542acdca31dSYuan Kang 
2543acdca31dSYuan Kang #ifdef DEBUG
2544514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ablkcipher sec4_sg@"__stringify(__LINE__)": ",
2545a299c837SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->sec4_sg,
2546a299c837SYuan Kang 		       sec4_sg_bytes, 1);
2547acdca31dSYuan Kang #endif
2548acdca31dSYuan Kang 
2549acdca31dSYuan Kang 	*iv_contig_out = iv_contig;
2550acdca31dSYuan Kang 	return edesc;
2551acdca31dSYuan Kang }
2552acdca31dSYuan Kang 
2553acdca31dSYuan Kang static int ablkcipher_encrypt(struct ablkcipher_request *req)
2554acdca31dSYuan Kang {
2555acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
2556acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
2557acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
2558acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
2559acdca31dSYuan Kang 	bool iv_contig;
2560acdca31dSYuan Kang 	u32 *desc;
2561acdca31dSYuan Kang 	int ret = 0;
2562acdca31dSYuan Kang 
2563acdca31dSYuan Kang 	/* allocate extended descriptor */
2564acdca31dSYuan Kang 	edesc = ablkcipher_edesc_alloc(req, DESC_JOB_IO_LEN *
2565acdca31dSYuan Kang 				       CAAM_CMD_SZ, &iv_contig);
2566acdca31dSYuan Kang 	if (IS_ERR(edesc))
2567acdca31dSYuan Kang 		return PTR_ERR(edesc);
2568acdca31dSYuan Kang 
2569acdca31dSYuan Kang 	/* Create and submit job descriptor*/
2570acdca31dSYuan Kang 	init_ablkcipher_job(ctx->sh_desc_enc,
2571acdca31dSYuan Kang 		ctx->sh_desc_enc_dma, edesc, req, iv_contig);
2572acdca31dSYuan Kang #ifdef DEBUG
2573514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ablkcipher jobdesc@"__stringify(__LINE__)": ",
2574acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
2575acdca31dSYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
2576acdca31dSYuan Kang #endif
2577acdca31dSYuan Kang 	desc = edesc->hw_desc;
2578acdca31dSYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, ablkcipher_encrypt_done, req);
2579acdca31dSYuan Kang 
2580acdca31dSYuan Kang 	if (!ret) {
2581acdca31dSYuan Kang 		ret = -EINPROGRESS;
2582acdca31dSYuan Kang 	} else {
2583acdca31dSYuan Kang 		ablkcipher_unmap(jrdev, edesc, req);
2584acdca31dSYuan Kang 		kfree(edesc);
2585acdca31dSYuan Kang 	}
2586acdca31dSYuan Kang 
2587acdca31dSYuan Kang 	return ret;
2588acdca31dSYuan Kang }
2589acdca31dSYuan Kang 
2590acdca31dSYuan Kang static int ablkcipher_decrypt(struct ablkcipher_request *req)
2591acdca31dSYuan Kang {
2592acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
2593acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
2594acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
2595acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
2596acdca31dSYuan Kang 	bool iv_contig;
2597acdca31dSYuan Kang 	u32 *desc;
2598acdca31dSYuan Kang 	int ret = 0;
2599acdca31dSYuan Kang 
2600acdca31dSYuan Kang 	/* allocate extended descriptor */
2601acdca31dSYuan Kang 	edesc = ablkcipher_edesc_alloc(req, DESC_JOB_IO_LEN *
2602acdca31dSYuan Kang 				       CAAM_CMD_SZ, &iv_contig);
2603acdca31dSYuan Kang 	if (IS_ERR(edesc))
2604acdca31dSYuan Kang 		return PTR_ERR(edesc);
2605acdca31dSYuan Kang 
2606acdca31dSYuan Kang 	/* Create and submit job descriptor*/
2607acdca31dSYuan Kang 	init_ablkcipher_job(ctx->sh_desc_dec,
2608acdca31dSYuan Kang 		ctx->sh_desc_dec_dma, edesc, req, iv_contig);
2609acdca31dSYuan Kang 	desc = edesc->hw_desc;
2610acdca31dSYuan Kang #ifdef DEBUG
2611514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ablkcipher jobdesc@"__stringify(__LINE__)": ",
2612acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
2613acdca31dSYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
2614acdca31dSYuan Kang #endif
2615acdca31dSYuan Kang 
2616acdca31dSYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, ablkcipher_decrypt_done, req);
2617acdca31dSYuan Kang 	if (!ret) {
2618acdca31dSYuan Kang 		ret = -EINPROGRESS;
2619acdca31dSYuan Kang 	} else {
2620acdca31dSYuan Kang 		ablkcipher_unmap(jrdev, edesc, req);
2621acdca31dSYuan Kang 		kfree(edesc);
2622acdca31dSYuan Kang 	}
2623acdca31dSYuan Kang 
2624acdca31dSYuan Kang 	return ret;
2625acdca31dSYuan Kang }
2626acdca31dSYuan Kang 
26277222d1a3SCatalin Vasile /*
26287222d1a3SCatalin Vasile  * allocate and map the ablkcipher extended descriptor
26297222d1a3SCatalin Vasile  * for ablkcipher givencrypt
26307222d1a3SCatalin Vasile  */
26317222d1a3SCatalin Vasile static struct ablkcipher_edesc *ablkcipher_giv_edesc_alloc(
26327222d1a3SCatalin Vasile 				struct skcipher_givcrypt_request *greq,
26337222d1a3SCatalin Vasile 				int desc_bytes,
26347222d1a3SCatalin Vasile 				bool *iv_contig_out)
26357222d1a3SCatalin Vasile {
26367222d1a3SCatalin Vasile 	struct ablkcipher_request *req = &greq->creq;
26377222d1a3SCatalin Vasile 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
26387222d1a3SCatalin Vasile 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
26397222d1a3SCatalin Vasile 	struct device *jrdev = ctx->jrdev;
26407222d1a3SCatalin Vasile 	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
26417222d1a3SCatalin Vasile 					  CRYPTO_TFM_REQ_MAY_SLEEP)) ?
26427222d1a3SCatalin Vasile 		       GFP_KERNEL : GFP_ATOMIC;
26437222d1a3SCatalin Vasile 	int src_nents, dst_nents = 0, sec4_sg_bytes;
26447222d1a3SCatalin Vasile 	struct ablkcipher_edesc *edesc;
26457222d1a3SCatalin Vasile 	dma_addr_t iv_dma = 0;
26467222d1a3SCatalin Vasile 	bool iv_contig = false;
26477222d1a3SCatalin Vasile 	int sgc;
26487222d1a3SCatalin Vasile 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
26497222d1a3SCatalin Vasile 	bool src_chained = false, dst_chained = false;
26507222d1a3SCatalin Vasile 	int sec4_sg_index;
26517222d1a3SCatalin Vasile 
26527222d1a3SCatalin Vasile 	src_nents = sg_count(req->src, req->nbytes, &src_chained);
26537222d1a3SCatalin Vasile 
26547222d1a3SCatalin Vasile 	if (unlikely(req->dst != req->src))
26557222d1a3SCatalin Vasile 		dst_nents = sg_count(req->dst, req->nbytes, &dst_chained);
26567222d1a3SCatalin Vasile 
26577222d1a3SCatalin Vasile 	if (likely(req->src == req->dst)) {
26587222d1a3SCatalin Vasile 		sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
26597222d1a3SCatalin Vasile 					 DMA_BIDIRECTIONAL, src_chained);
26607222d1a3SCatalin Vasile 	} else {
26617222d1a3SCatalin Vasile 		sgc = dma_map_sg_chained(jrdev, req->src, src_nents ? : 1,
26627222d1a3SCatalin Vasile 					 DMA_TO_DEVICE, src_chained);
26637222d1a3SCatalin Vasile 		sgc = dma_map_sg_chained(jrdev, req->dst, dst_nents ? : 1,
26647222d1a3SCatalin Vasile 					 DMA_FROM_DEVICE, dst_chained);
26657222d1a3SCatalin Vasile 	}
26667222d1a3SCatalin Vasile 
26677222d1a3SCatalin Vasile 	/*
26687222d1a3SCatalin Vasile 	 * Check if iv can be contiguous with source and destination.
26697222d1a3SCatalin Vasile 	 * If so, include it. If not, create scatterlist.
26707222d1a3SCatalin Vasile 	 */
26717222d1a3SCatalin Vasile 	iv_dma = dma_map_single(jrdev, greq->giv, ivsize, DMA_TO_DEVICE);
26727222d1a3SCatalin Vasile 	if (dma_mapping_error(jrdev, iv_dma)) {
26737222d1a3SCatalin Vasile 		dev_err(jrdev, "unable to map IV\n");
26747222d1a3SCatalin Vasile 		return ERR_PTR(-ENOMEM);
26757222d1a3SCatalin Vasile 	}
26767222d1a3SCatalin Vasile 
26777222d1a3SCatalin Vasile 	if (!dst_nents && iv_dma + ivsize == sg_dma_address(req->dst))
26787222d1a3SCatalin Vasile 		iv_contig = true;
26797222d1a3SCatalin Vasile 	else
26807222d1a3SCatalin Vasile 		dst_nents = dst_nents ? : 1;
26817222d1a3SCatalin Vasile 	sec4_sg_bytes = ((iv_contig ? 0 : 1) + src_nents + dst_nents) *
26827222d1a3SCatalin Vasile 			sizeof(struct sec4_sg_entry);
26837222d1a3SCatalin Vasile 
26847222d1a3SCatalin Vasile 	/* allocate space for base edesc and hw desc commands, link tables */
2685dde20ae9SVictoria Milhoan 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes,
2686dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
26877222d1a3SCatalin Vasile 	if (!edesc) {
26887222d1a3SCatalin Vasile 		dev_err(jrdev, "could not allocate extended descriptor\n");
26897222d1a3SCatalin Vasile 		return ERR_PTR(-ENOMEM);
26907222d1a3SCatalin Vasile 	}
26917222d1a3SCatalin Vasile 
26927222d1a3SCatalin Vasile 	edesc->src_nents = src_nents;
26937222d1a3SCatalin Vasile 	edesc->src_chained = src_chained;
26947222d1a3SCatalin Vasile 	edesc->dst_nents = dst_nents;
26957222d1a3SCatalin Vasile 	edesc->dst_chained = dst_chained;
26967222d1a3SCatalin Vasile 	edesc->sec4_sg_bytes = sec4_sg_bytes;
26977222d1a3SCatalin Vasile 	edesc->sec4_sg = (void *)edesc + sizeof(struct ablkcipher_edesc) +
26987222d1a3SCatalin Vasile 			 desc_bytes;
26997222d1a3SCatalin Vasile 
27007222d1a3SCatalin Vasile 	sec4_sg_index = 0;
27017222d1a3SCatalin Vasile 	if (src_nents) {
27027222d1a3SCatalin Vasile 		sg_to_sec4_sg_last(req->src, src_nents, edesc->sec4_sg, 0);
27037222d1a3SCatalin Vasile 		sec4_sg_index += src_nents;
27047222d1a3SCatalin Vasile 	}
27057222d1a3SCatalin Vasile 
27067222d1a3SCatalin Vasile 	if (!iv_contig) {
27077222d1a3SCatalin Vasile 		dma_to_sec4_sg_one(edesc->sec4_sg + sec4_sg_index,
27087222d1a3SCatalin Vasile 				   iv_dma, ivsize, 0);
27097222d1a3SCatalin Vasile 		sec4_sg_index += 1;
27107222d1a3SCatalin Vasile 		sg_to_sec4_sg_last(req->dst, dst_nents,
27117222d1a3SCatalin Vasile 				   edesc->sec4_sg + sec4_sg_index, 0);
27127222d1a3SCatalin Vasile 	}
27137222d1a3SCatalin Vasile 
27147222d1a3SCatalin Vasile 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
27157222d1a3SCatalin Vasile 					    sec4_sg_bytes, DMA_TO_DEVICE);
27167222d1a3SCatalin Vasile 	if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
27177222d1a3SCatalin Vasile 		dev_err(jrdev, "unable to map S/G table\n");
27187222d1a3SCatalin Vasile 		return ERR_PTR(-ENOMEM);
27197222d1a3SCatalin Vasile 	}
27207222d1a3SCatalin Vasile 	edesc->iv_dma = iv_dma;
27217222d1a3SCatalin Vasile 
27227222d1a3SCatalin Vasile #ifdef DEBUG
27237222d1a3SCatalin Vasile 	print_hex_dump(KERN_ERR,
27247222d1a3SCatalin Vasile 		       "ablkcipher sec4_sg@" __stringify(__LINE__) ": ",
27257222d1a3SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->sec4_sg,
27267222d1a3SCatalin Vasile 		       sec4_sg_bytes, 1);
27277222d1a3SCatalin Vasile #endif
27287222d1a3SCatalin Vasile 
27297222d1a3SCatalin Vasile 	*iv_contig_out = iv_contig;
27307222d1a3SCatalin Vasile 	return edesc;
27317222d1a3SCatalin Vasile }
27327222d1a3SCatalin Vasile 
27337222d1a3SCatalin Vasile static int ablkcipher_givencrypt(struct skcipher_givcrypt_request *creq)
27347222d1a3SCatalin Vasile {
27357222d1a3SCatalin Vasile 	struct ablkcipher_request *req = &creq->creq;
27367222d1a3SCatalin Vasile 	struct ablkcipher_edesc *edesc;
27377222d1a3SCatalin Vasile 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
27387222d1a3SCatalin Vasile 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
27397222d1a3SCatalin Vasile 	struct device *jrdev = ctx->jrdev;
27407222d1a3SCatalin Vasile 	bool iv_contig;
27417222d1a3SCatalin Vasile 	u32 *desc;
27427222d1a3SCatalin Vasile 	int ret = 0;
27437222d1a3SCatalin Vasile 
27447222d1a3SCatalin Vasile 	/* allocate extended descriptor */
27457222d1a3SCatalin Vasile 	edesc = ablkcipher_giv_edesc_alloc(creq, DESC_JOB_IO_LEN *
27467222d1a3SCatalin Vasile 				       CAAM_CMD_SZ, &iv_contig);
27477222d1a3SCatalin Vasile 	if (IS_ERR(edesc))
27487222d1a3SCatalin Vasile 		return PTR_ERR(edesc);
27497222d1a3SCatalin Vasile 
27507222d1a3SCatalin Vasile 	/* Create and submit job descriptor*/
27517222d1a3SCatalin Vasile 	init_ablkcipher_giv_job(ctx->sh_desc_givenc, ctx->sh_desc_givenc_dma,
27527222d1a3SCatalin Vasile 				edesc, req, iv_contig);
27537222d1a3SCatalin Vasile #ifdef DEBUG
27547222d1a3SCatalin Vasile 	print_hex_dump(KERN_ERR,
27557222d1a3SCatalin Vasile 		       "ablkcipher jobdesc@" __stringify(__LINE__) ": ",
27567222d1a3SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
27577222d1a3SCatalin Vasile 		       desc_bytes(edesc->hw_desc), 1);
27587222d1a3SCatalin Vasile #endif
27597222d1a3SCatalin Vasile 	desc = edesc->hw_desc;
27607222d1a3SCatalin Vasile 	ret = caam_jr_enqueue(jrdev, desc, ablkcipher_encrypt_done, req);
27617222d1a3SCatalin Vasile 
27627222d1a3SCatalin Vasile 	if (!ret) {
27637222d1a3SCatalin Vasile 		ret = -EINPROGRESS;
27647222d1a3SCatalin Vasile 	} else {
27657222d1a3SCatalin Vasile 		ablkcipher_unmap(jrdev, edesc, req);
27667222d1a3SCatalin Vasile 		kfree(edesc);
27677222d1a3SCatalin Vasile 	}
27687222d1a3SCatalin Vasile 
27697222d1a3SCatalin Vasile 	return ret;
27707222d1a3SCatalin Vasile }
27717222d1a3SCatalin Vasile 
2772885e9e2fSYuan Kang #define template_aead		template_u.aead
2773acdca31dSYuan Kang #define template_ablkcipher	template_u.ablkcipher
27748e8ec596SKim Phillips struct caam_alg_template {
27758e8ec596SKim Phillips 	char name[CRYPTO_MAX_ALG_NAME];
27768e8ec596SKim Phillips 	char driver_name[CRYPTO_MAX_ALG_NAME];
27778e8ec596SKim Phillips 	unsigned int blocksize;
2778885e9e2fSYuan Kang 	u32 type;
2779885e9e2fSYuan Kang 	union {
2780885e9e2fSYuan Kang 		struct ablkcipher_alg ablkcipher;
2781885e9e2fSYuan Kang 	} template_u;
27828e8ec596SKim Phillips 	u32 class1_alg_type;
27838e8ec596SKim Phillips 	u32 class2_alg_type;
27848e8ec596SKim Phillips 	u32 alg_op;
27858e8ec596SKim Phillips };
27868e8ec596SKim Phillips 
27878e8ec596SKim Phillips static struct caam_alg_template driver_algs[] = {
2788acdca31dSYuan Kang 	/* ablkcipher descriptor */
2789acdca31dSYuan Kang 	{
2790acdca31dSYuan Kang 		.name = "cbc(aes)",
2791acdca31dSYuan Kang 		.driver_name = "cbc-aes-caam",
2792acdca31dSYuan Kang 		.blocksize = AES_BLOCK_SIZE,
27937222d1a3SCatalin Vasile 		.type = CRYPTO_ALG_TYPE_GIVCIPHER,
2794acdca31dSYuan Kang 		.template_ablkcipher = {
2795acdca31dSYuan Kang 			.setkey = ablkcipher_setkey,
2796acdca31dSYuan Kang 			.encrypt = ablkcipher_encrypt,
2797acdca31dSYuan Kang 			.decrypt = ablkcipher_decrypt,
27987222d1a3SCatalin Vasile 			.givencrypt = ablkcipher_givencrypt,
27997222d1a3SCatalin Vasile 			.geniv = "<built-in>",
2800acdca31dSYuan Kang 			.min_keysize = AES_MIN_KEY_SIZE,
2801acdca31dSYuan Kang 			.max_keysize = AES_MAX_KEY_SIZE,
2802acdca31dSYuan Kang 			.ivsize = AES_BLOCK_SIZE,
2803acdca31dSYuan Kang 			},
2804acdca31dSYuan Kang 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2805acdca31dSYuan Kang 	},
2806acdca31dSYuan Kang 	{
2807acdca31dSYuan Kang 		.name = "cbc(des3_ede)",
2808acdca31dSYuan Kang 		.driver_name = "cbc-3des-caam",
2809acdca31dSYuan Kang 		.blocksize = DES3_EDE_BLOCK_SIZE,
2810ff2c3a3bSCatalin Vasile 		.type = CRYPTO_ALG_TYPE_GIVCIPHER,
2811acdca31dSYuan Kang 		.template_ablkcipher = {
2812acdca31dSYuan Kang 			.setkey = ablkcipher_setkey,
2813acdca31dSYuan Kang 			.encrypt = ablkcipher_encrypt,
2814acdca31dSYuan Kang 			.decrypt = ablkcipher_decrypt,
2815ff2c3a3bSCatalin Vasile 			.givencrypt = ablkcipher_givencrypt,
2816ff2c3a3bSCatalin Vasile 			.geniv = "<built-in>",
2817acdca31dSYuan Kang 			.min_keysize = DES3_EDE_KEY_SIZE,
2818acdca31dSYuan Kang 			.max_keysize = DES3_EDE_KEY_SIZE,
2819acdca31dSYuan Kang 			.ivsize = DES3_EDE_BLOCK_SIZE,
2820acdca31dSYuan Kang 			},
2821acdca31dSYuan Kang 		.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2822acdca31dSYuan Kang 	},
2823acdca31dSYuan Kang 	{
2824acdca31dSYuan Kang 		.name = "cbc(des)",
2825acdca31dSYuan Kang 		.driver_name = "cbc-des-caam",
2826acdca31dSYuan Kang 		.blocksize = DES_BLOCK_SIZE,
2827ff2c3a3bSCatalin Vasile 		.type = CRYPTO_ALG_TYPE_GIVCIPHER,
2828acdca31dSYuan Kang 		.template_ablkcipher = {
2829acdca31dSYuan Kang 			.setkey = ablkcipher_setkey,
2830acdca31dSYuan Kang 			.encrypt = ablkcipher_encrypt,
2831acdca31dSYuan Kang 			.decrypt = ablkcipher_decrypt,
2832ff2c3a3bSCatalin Vasile 			.givencrypt = ablkcipher_givencrypt,
2833ff2c3a3bSCatalin Vasile 			.geniv = "<built-in>",
2834acdca31dSYuan Kang 			.min_keysize = DES_KEY_SIZE,
2835acdca31dSYuan Kang 			.max_keysize = DES_KEY_SIZE,
2836acdca31dSYuan Kang 			.ivsize = DES_BLOCK_SIZE,
2837acdca31dSYuan Kang 			},
2838acdca31dSYuan Kang 		.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
28392b22f6c5SCatalin Vasile 	},
28402b22f6c5SCatalin Vasile 	{
28412b22f6c5SCatalin Vasile 		.name = "ctr(aes)",
28422b22f6c5SCatalin Vasile 		.driver_name = "ctr-aes-caam",
28432b22f6c5SCatalin Vasile 		.blocksize = 1,
28442b22f6c5SCatalin Vasile 		.type = CRYPTO_ALG_TYPE_ABLKCIPHER,
28452b22f6c5SCatalin Vasile 		.template_ablkcipher = {
28462b22f6c5SCatalin Vasile 			.setkey = ablkcipher_setkey,
28472b22f6c5SCatalin Vasile 			.encrypt = ablkcipher_encrypt,
28482b22f6c5SCatalin Vasile 			.decrypt = ablkcipher_decrypt,
28492b22f6c5SCatalin Vasile 			.geniv = "chainiv",
28502b22f6c5SCatalin Vasile 			.min_keysize = AES_MIN_KEY_SIZE,
28512b22f6c5SCatalin Vasile 			.max_keysize = AES_MAX_KEY_SIZE,
28522b22f6c5SCatalin Vasile 			.ivsize = AES_BLOCK_SIZE,
28532b22f6c5SCatalin Vasile 			},
28542b22f6c5SCatalin Vasile 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CTR_MOD128,
2855a5f57cffSCatalin Vasile 	},
2856a5f57cffSCatalin Vasile 	{
2857a5f57cffSCatalin Vasile 		.name = "rfc3686(ctr(aes))",
2858a5f57cffSCatalin Vasile 		.driver_name = "rfc3686-ctr-aes-caam",
2859a5f57cffSCatalin Vasile 		.blocksize = 1,
28607222d1a3SCatalin Vasile 		.type = CRYPTO_ALG_TYPE_GIVCIPHER,
2861a5f57cffSCatalin Vasile 		.template_ablkcipher = {
2862a5f57cffSCatalin Vasile 			.setkey = ablkcipher_setkey,
2863a5f57cffSCatalin Vasile 			.encrypt = ablkcipher_encrypt,
2864a5f57cffSCatalin Vasile 			.decrypt = ablkcipher_decrypt,
28657222d1a3SCatalin Vasile 			.givencrypt = ablkcipher_givencrypt,
28667222d1a3SCatalin Vasile 			.geniv = "<built-in>",
2867a5f57cffSCatalin Vasile 			.min_keysize = AES_MIN_KEY_SIZE +
2868a5f57cffSCatalin Vasile 				       CTR_RFC3686_NONCE_SIZE,
2869a5f57cffSCatalin Vasile 			.max_keysize = AES_MAX_KEY_SIZE +
2870a5f57cffSCatalin Vasile 				       CTR_RFC3686_NONCE_SIZE,
2871a5f57cffSCatalin Vasile 			.ivsize = CTR_RFC3686_IV_SIZE,
2872a5f57cffSCatalin Vasile 			},
2873a5f57cffSCatalin Vasile 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CTR_MOD128,
2874acdca31dSYuan Kang 	}
28758e8ec596SKim Phillips };
28768e8ec596SKim Phillips 
2877f2147b88SHerbert Xu static struct caam_aead_alg driver_aeads[] = {
2878f2147b88SHerbert Xu 	{
2879f2147b88SHerbert Xu 		.aead = {
2880f2147b88SHerbert Xu 			.base = {
2881f2147b88SHerbert Xu 				.cra_name = "rfc4106(gcm(aes))",
2882f2147b88SHerbert Xu 				.cra_driver_name = "rfc4106-gcm-aes-caam",
2883f2147b88SHerbert Xu 				.cra_blocksize = 1,
2884f2147b88SHerbert Xu 			},
2885f2147b88SHerbert Xu 			.setkey = rfc4106_setkey,
2886f2147b88SHerbert Xu 			.setauthsize = rfc4106_setauthsize,
288746218750SHerbert Xu 			.encrypt = ipsec_gcm_encrypt,
288846218750SHerbert Xu 			.decrypt = ipsec_gcm_decrypt,
2889f2147b88SHerbert Xu 			.ivsize = 8,
2890f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
2891f2147b88SHerbert Xu 		},
2892f2147b88SHerbert Xu 		.caam = {
2893f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
2894f2147b88SHerbert Xu 		},
2895f2147b88SHerbert Xu 	},
2896f2147b88SHerbert Xu 	{
2897f2147b88SHerbert Xu 		.aead = {
2898f2147b88SHerbert Xu 			.base = {
2899f2147b88SHerbert Xu 				.cra_name = "rfc4543(gcm(aes))",
2900f2147b88SHerbert Xu 				.cra_driver_name = "rfc4543-gcm-aes-caam",
2901f2147b88SHerbert Xu 				.cra_blocksize = 1,
2902f2147b88SHerbert Xu 			},
2903f2147b88SHerbert Xu 			.setkey = rfc4543_setkey,
2904f2147b88SHerbert Xu 			.setauthsize = rfc4543_setauthsize,
290546218750SHerbert Xu 			.encrypt = ipsec_gcm_encrypt,
290646218750SHerbert Xu 			.decrypt = ipsec_gcm_decrypt,
2907f2147b88SHerbert Xu 			.ivsize = 8,
2908f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
2909f2147b88SHerbert Xu 		},
2910f2147b88SHerbert Xu 		.caam = {
2911f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
2912f2147b88SHerbert Xu 		},
2913f2147b88SHerbert Xu 	},
2914f2147b88SHerbert Xu 	/* Galois Counter Mode */
2915f2147b88SHerbert Xu 	{
2916f2147b88SHerbert Xu 		.aead = {
2917f2147b88SHerbert Xu 			.base = {
2918f2147b88SHerbert Xu 				.cra_name = "gcm(aes)",
2919f2147b88SHerbert Xu 				.cra_driver_name = "gcm-aes-caam",
2920f2147b88SHerbert Xu 				.cra_blocksize = 1,
2921f2147b88SHerbert Xu 			},
2922f2147b88SHerbert Xu 			.setkey = gcm_setkey,
2923f2147b88SHerbert Xu 			.setauthsize = gcm_setauthsize,
2924f2147b88SHerbert Xu 			.encrypt = gcm_encrypt,
2925f2147b88SHerbert Xu 			.decrypt = gcm_decrypt,
2926f2147b88SHerbert Xu 			.ivsize = 12,
2927f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
2928f2147b88SHerbert Xu 		},
2929f2147b88SHerbert Xu 		.caam = {
2930f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
2931f2147b88SHerbert Xu 		},
2932f2147b88SHerbert Xu 	},
2933479bcc7cSHerbert Xu 	/* single-pass ipsec_esp descriptor */
2934479bcc7cSHerbert Xu 	{
2935479bcc7cSHerbert Xu 		.aead = {
2936479bcc7cSHerbert Xu 			.base = {
2937479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),"
2938479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2939479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
2940479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2941479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2942479bcc7cSHerbert Xu 			},
2943479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2944479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2945479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2946479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2947479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2948479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
2949479bcc7cSHerbert Xu 		},
2950479bcc7cSHerbert Xu 		.caam = {
2951479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
2952479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2953479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
2954479bcc7cSHerbert Xu 		},
2955479bcc7cSHerbert Xu 	},
2956479bcc7cSHerbert Xu 	{
2957479bcc7cSHerbert Xu 		.aead = {
2958479bcc7cSHerbert Xu 			.base = {
2959479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
2960479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2961479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
2962479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2963479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2964479bcc7cSHerbert Xu 			},
2965479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2966479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2967479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2968479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2969479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2970479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
2971479bcc7cSHerbert Xu 		},
2972479bcc7cSHerbert Xu 		.caam = {
2973479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
2974479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2975479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
2976479bcc7cSHerbert Xu 		},
2977479bcc7cSHerbert Xu 	},
2978479bcc7cSHerbert Xu 	{
2979479bcc7cSHerbert Xu 		.aead = {
2980479bcc7cSHerbert Xu 			.base = {
2981479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
2982479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
2983479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
2984479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
2985479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
2986479bcc7cSHerbert Xu 			},
2987479bcc7cSHerbert Xu 			.setkey = aead_setkey,
2988479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
2989479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
2990479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
2991479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
2992479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
2993479bcc7cSHerbert Xu 		},
2994479bcc7cSHerbert Xu 		.caam = {
2995479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
2996479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
2997479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
2998479bcc7cSHerbert Xu 		},
2999479bcc7cSHerbert Xu 	},
3000479bcc7cSHerbert Xu 	{
3001479bcc7cSHerbert Xu 		.aead = {
3002479bcc7cSHerbert Xu 			.base = {
3003479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
3004479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
3005479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
3006479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
3007479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
3008479bcc7cSHerbert Xu 			},
3009479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3010479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3011479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3012479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3013479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
3014479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3015479bcc7cSHerbert Xu 		},
3016479bcc7cSHerbert Xu 		.caam = {
3017479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3018479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3019479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3020479bcc7cSHerbert Xu 		},
3021479bcc7cSHerbert Xu 	},
3022479bcc7cSHerbert Xu 	{
3023479bcc7cSHerbert Xu 		.aead = {
3024479bcc7cSHerbert Xu 			.base = {
3025479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
3026479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
3027479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
3028479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
3029479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
3030479bcc7cSHerbert Xu 			},
3031479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3032479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3033479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3034479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3035479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
3036479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3037479bcc7cSHerbert Xu 		},
3038479bcc7cSHerbert Xu 		.caam = {
3039479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3040479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3041479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3042479bcc7cSHerbert Xu 		},
3043479bcc7cSHerbert Xu 	},
3044479bcc7cSHerbert Xu 	{
3045479bcc7cSHerbert Xu 		.aead = {
3046479bcc7cSHerbert Xu 			.base = {
3047479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
3048479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
3049479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
3050479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
3051479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
3052479bcc7cSHerbert Xu 			},
3053479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3054479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3055479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3056479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3057479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
3058479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3059479bcc7cSHerbert Xu 		},
3060479bcc7cSHerbert Xu 		.caam = {
3061479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3062479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3063479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
3064479bcc7cSHerbert Xu 		},
3065479bcc7cSHerbert Xu 	},
3066479bcc7cSHerbert Xu 	{
3067479bcc7cSHerbert Xu 		.aead = {
3068479bcc7cSHerbert Xu 			.base = {
3069479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(aes))",
3070479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
3071479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3072479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3073479bcc7cSHerbert Xu 			},
3074479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3075479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3076479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3077479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3078479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3079479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3080479bcc7cSHerbert Xu 		},
3081479bcc7cSHerbert Xu 		.caam = {
3082479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3083479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3084479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3085479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3086479bcc7cSHerbert Xu 		},
3087479bcc7cSHerbert Xu 	},
3088479bcc7cSHerbert Xu 	{
3089479bcc7cSHerbert Xu 		.aead = {
3090479bcc7cSHerbert Xu 			.base = {
3091479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
3092479bcc7cSHerbert Xu 					    "cbc(aes)))",
3093479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
3094479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3095479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3096479bcc7cSHerbert Xu 			},
3097479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3098479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3099479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3100479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3101479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3102479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3103479bcc7cSHerbert Xu 		},
3104479bcc7cSHerbert Xu 		.caam = {
3105479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3106479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3107479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3108479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3109479bcc7cSHerbert Xu 			.geniv = true,
3110479bcc7cSHerbert Xu 		},
3111479bcc7cSHerbert Xu 	},
3112479bcc7cSHerbert Xu 	{
3113479bcc7cSHerbert Xu 		.aead = {
3114479bcc7cSHerbert Xu 			.base = {
3115479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),cbc(aes))",
3116479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
3117479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3118479bcc7cSHerbert Xu 				.cra_blocksize = AES_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 = AES_BLOCK_SIZE,
3125479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3126479bcc7cSHerbert Xu 		},
3127479bcc7cSHerbert Xu 		.caam = {
3128479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3129479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3130479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3131479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
3132479bcc7cSHerbert Xu 		},
3133479bcc7cSHerbert Xu 	},
3134479bcc7cSHerbert Xu 	{
3135479bcc7cSHerbert Xu 		.aead = {
3136479bcc7cSHerbert Xu 			.base = {
3137479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
3138479bcc7cSHerbert Xu 					    "cbc(aes)))",
3139479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3140479bcc7cSHerbert Xu 						   "hmac-sha1-cbc-aes-caam",
3141479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3142479bcc7cSHerbert Xu 			},
3143479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3144479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3145479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3146479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3147479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3148479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3149479bcc7cSHerbert Xu 		},
3150479bcc7cSHerbert Xu 		.caam = {
3151479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3152479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3153479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3154479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
3155479bcc7cSHerbert Xu 			.geniv = true,
3156479bcc7cSHerbert Xu 		},
3157479bcc7cSHerbert Xu 	},
3158479bcc7cSHerbert Xu 	{
3159479bcc7cSHerbert Xu 		.aead = {
3160479bcc7cSHerbert Xu 			.base = {
3161479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),cbc(aes))",
3162479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
3163479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3164479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3165479bcc7cSHerbert Xu 			},
3166479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3167479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3168479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3169479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3170479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3171479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3172479bcc7cSHerbert Xu 		},
3173479bcc7cSHerbert Xu 		.caam = {
3174479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3175479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3176479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3177479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
3178479bcc7cSHerbert Xu 		},
3179479bcc7cSHerbert Xu 	},
3180479bcc7cSHerbert Xu 	{
3181479bcc7cSHerbert Xu 		.aead = {
3182479bcc7cSHerbert Xu 			.base = {
3183479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
3184479bcc7cSHerbert Xu 					    "cbc(aes)))",
3185479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3186479bcc7cSHerbert Xu 						   "hmac-sha224-cbc-aes-caam",
3187479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3188479bcc7cSHerbert Xu 			},
3189479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3190479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3191479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3192479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3193479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3194479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3195479bcc7cSHerbert Xu 		},
3196479bcc7cSHerbert Xu 		.caam = {
3197479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3198479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3199479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3200479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
3201479bcc7cSHerbert Xu 			.geniv = true,
3202479bcc7cSHerbert Xu 		},
3203479bcc7cSHerbert Xu 	},
3204479bcc7cSHerbert Xu 	{
3205479bcc7cSHerbert Xu 		.aead = {
3206479bcc7cSHerbert Xu 			.base = {
3207479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),cbc(aes))",
3208479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
3209479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3210479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3211479bcc7cSHerbert Xu 			},
3212479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3213479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3214479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3215479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3216479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3217479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3218479bcc7cSHerbert Xu 		},
3219479bcc7cSHerbert Xu 		.caam = {
3220479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3221479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3222479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3223479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3224479bcc7cSHerbert Xu 		},
3225479bcc7cSHerbert Xu 	},
3226479bcc7cSHerbert Xu 	{
3227479bcc7cSHerbert Xu 		.aead = {
3228479bcc7cSHerbert Xu 			.base = {
3229479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
3230479bcc7cSHerbert Xu 					    "cbc(aes)))",
3231479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3232479bcc7cSHerbert Xu 						   "hmac-sha256-cbc-aes-caam",
3233479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3234479bcc7cSHerbert Xu 			},
3235479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3236479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3237479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3238479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3239479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3240479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3241479bcc7cSHerbert Xu 		},
3242479bcc7cSHerbert Xu 		.caam = {
3243479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3244479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3245479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3246479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3247479bcc7cSHerbert Xu 			.geniv = true,
3248479bcc7cSHerbert Xu 		},
3249479bcc7cSHerbert Xu 	},
3250479bcc7cSHerbert Xu 	{
3251479bcc7cSHerbert Xu 		.aead = {
3252479bcc7cSHerbert Xu 			.base = {
3253479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),cbc(aes))",
3254479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
3255479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3256479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3257479bcc7cSHerbert Xu 			},
3258479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3259479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3260479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3261479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3262479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3263479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3264479bcc7cSHerbert Xu 		},
3265479bcc7cSHerbert Xu 		.caam = {
3266479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3267479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3268479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3269479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3270479bcc7cSHerbert Xu 		},
3271479bcc7cSHerbert Xu 	},
3272479bcc7cSHerbert Xu 	{
3273479bcc7cSHerbert Xu 		.aead = {
3274479bcc7cSHerbert Xu 			.base = {
3275479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
3276479bcc7cSHerbert Xu 					    "cbc(aes)))",
3277479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3278479bcc7cSHerbert Xu 						   "hmac-sha384-cbc-aes-caam",
3279479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3280479bcc7cSHerbert Xu 			},
3281479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3282479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3283479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3284479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3285479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3286479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3287479bcc7cSHerbert Xu 		},
3288479bcc7cSHerbert Xu 		.caam = {
3289479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3290479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3291479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3292479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3293479bcc7cSHerbert Xu 			.geniv = true,
3294479bcc7cSHerbert Xu 		},
3295479bcc7cSHerbert Xu 	},
3296479bcc7cSHerbert Xu 	{
3297479bcc7cSHerbert Xu 		.aead = {
3298479bcc7cSHerbert Xu 			.base = {
3299479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),cbc(aes))",
3300479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
3301479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3302479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3303479bcc7cSHerbert Xu 			},
3304479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3305479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3306479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3307479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3308479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3309479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3310479bcc7cSHerbert Xu 		},
3311479bcc7cSHerbert Xu 		.caam = {
3312479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3313479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3314479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3315479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
3316479bcc7cSHerbert Xu 		},
3317479bcc7cSHerbert Xu 	},
3318479bcc7cSHerbert Xu 	{
3319479bcc7cSHerbert Xu 		.aead = {
3320479bcc7cSHerbert Xu 			.base = {
3321479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
3322479bcc7cSHerbert Xu 					    "cbc(aes)))",
3323479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3324479bcc7cSHerbert Xu 						   "hmac-sha512-cbc-aes-caam",
3325479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3326479bcc7cSHerbert Xu 			},
3327479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3328479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3329479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3330479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3331479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3332479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3333479bcc7cSHerbert Xu 		},
3334479bcc7cSHerbert Xu 		.caam = {
3335479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3336479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3337479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3338479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
3339479bcc7cSHerbert Xu 			.geniv = true,
3340479bcc7cSHerbert Xu 		},
3341479bcc7cSHerbert Xu 	},
3342479bcc7cSHerbert Xu 	{
3343479bcc7cSHerbert Xu 		.aead = {
3344479bcc7cSHerbert Xu 			.base = {
3345479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(des3_ede))",
3346479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
3347479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3348479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3349479bcc7cSHerbert Xu 			},
3350479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3351479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3352479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3353479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3354479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3355479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3356479bcc7cSHerbert Xu 		},
3357479bcc7cSHerbert Xu 		.caam = {
3358479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3359479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3360479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3361479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3362479bcc7cSHerbert Xu 		}
3363479bcc7cSHerbert Xu 	},
3364479bcc7cSHerbert Xu 	{
3365479bcc7cSHerbert Xu 		.aead = {
3366479bcc7cSHerbert Xu 			.base = {
3367479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
3368479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
3369479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
3370479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3371479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3372479bcc7cSHerbert Xu 			},
3373479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3374479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3375479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3376479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3377479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3378479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3379479bcc7cSHerbert Xu 		},
3380479bcc7cSHerbert Xu 		.caam = {
3381479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3382479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3383479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3384479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3385479bcc7cSHerbert Xu 			.geniv = true,
3386479bcc7cSHerbert Xu 		}
3387479bcc7cSHerbert Xu 	},
3388479bcc7cSHerbert Xu 	{
3389479bcc7cSHerbert Xu 		.aead = {
3390479bcc7cSHerbert Xu 			.base = {
3391479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
3392479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
3393479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
3394479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3395479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3396479bcc7cSHerbert Xu 			},
3397479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3398479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3399479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3400479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3401479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3402479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3403479bcc7cSHerbert Xu 		},
3404479bcc7cSHerbert Xu 		.caam = {
3405479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3406479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3407479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3408479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
3409479bcc7cSHerbert Xu 		},
3410479bcc7cSHerbert Xu 	},
3411479bcc7cSHerbert Xu 	{
3412479bcc7cSHerbert Xu 		.aead = {
3413479bcc7cSHerbert Xu 			.base = {
3414479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
3415479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
3416479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3417479bcc7cSHerbert Xu 						   "hmac-sha1-"
3418479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3419479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3420479bcc7cSHerbert Xu 			},
3421479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3422479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3423479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3424479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3425479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3426479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3427479bcc7cSHerbert Xu 		},
3428479bcc7cSHerbert Xu 		.caam = {
3429479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3430479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3431479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3432479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
3433479bcc7cSHerbert Xu 			.geniv = true,
3434479bcc7cSHerbert Xu 		},
3435479bcc7cSHerbert Xu 	},
3436479bcc7cSHerbert Xu 	{
3437479bcc7cSHerbert Xu 		.aead = {
3438479bcc7cSHerbert Xu 			.base = {
3439479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
3440479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
3441479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
3442479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3443479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3444479bcc7cSHerbert Xu 			},
3445479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3446479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3447479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3448479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3449479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3450479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3451479bcc7cSHerbert Xu 		},
3452479bcc7cSHerbert Xu 		.caam = {
3453479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3454479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3455479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3456479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
3457479bcc7cSHerbert Xu 		},
3458479bcc7cSHerbert Xu 	},
3459479bcc7cSHerbert Xu 	{
3460479bcc7cSHerbert Xu 		.aead = {
3461479bcc7cSHerbert Xu 			.base = {
3462479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
3463479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
3464479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3465479bcc7cSHerbert Xu 						   "hmac-sha224-"
3466479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3467479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3468479bcc7cSHerbert Xu 			},
3469479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3470479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3471479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3472479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3473479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3474479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3475479bcc7cSHerbert Xu 		},
3476479bcc7cSHerbert Xu 		.caam = {
3477479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3478479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3479479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3480479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
3481479bcc7cSHerbert Xu 			.geniv = true,
3482479bcc7cSHerbert Xu 		},
3483479bcc7cSHerbert Xu 	},
3484479bcc7cSHerbert Xu 	{
3485479bcc7cSHerbert Xu 		.aead = {
3486479bcc7cSHerbert Xu 			.base = {
3487479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
3488479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
3489479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
3490479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3491479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3492479bcc7cSHerbert Xu 			},
3493479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3494479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3495479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3496479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3497479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3498479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3499479bcc7cSHerbert Xu 		},
3500479bcc7cSHerbert Xu 		.caam = {
3501479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3502479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3503479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3504479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3505479bcc7cSHerbert Xu 		},
3506479bcc7cSHerbert Xu 	},
3507479bcc7cSHerbert Xu 	{
3508479bcc7cSHerbert Xu 		.aead = {
3509479bcc7cSHerbert Xu 			.base = {
3510479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
3511479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
3512479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3513479bcc7cSHerbert Xu 						   "hmac-sha256-"
3514479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3515479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3516479bcc7cSHerbert Xu 			},
3517479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3518479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3519479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3520479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3521479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3522479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3523479bcc7cSHerbert Xu 		},
3524479bcc7cSHerbert Xu 		.caam = {
3525479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3526479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3527479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3528479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3529479bcc7cSHerbert Xu 			.geniv = true,
3530479bcc7cSHerbert Xu 		},
3531479bcc7cSHerbert Xu 	},
3532479bcc7cSHerbert Xu 	{
3533479bcc7cSHerbert Xu 		.aead = {
3534479bcc7cSHerbert Xu 			.base = {
3535479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
3536479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
3537479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
3538479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3539479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3540479bcc7cSHerbert Xu 			},
3541479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3542479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3543479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3544479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3545479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3546479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3547479bcc7cSHerbert Xu 		},
3548479bcc7cSHerbert Xu 		.caam = {
3549479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3550479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3551479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3552479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3553479bcc7cSHerbert Xu 		},
3554479bcc7cSHerbert Xu 	},
3555479bcc7cSHerbert Xu 	{
3556479bcc7cSHerbert Xu 		.aead = {
3557479bcc7cSHerbert Xu 			.base = {
3558479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
3559479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
3560479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3561479bcc7cSHerbert Xu 						   "hmac-sha384-"
3562479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3563479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3564479bcc7cSHerbert Xu 			},
3565479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3566479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3567479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3568479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3569479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3570479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3571479bcc7cSHerbert Xu 		},
3572479bcc7cSHerbert Xu 		.caam = {
3573479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3574479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3575479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3576479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3577479bcc7cSHerbert Xu 			.geniv = true,
3578479bcc7cSHerbert Xu 		},
3579479bcc7cSHerbert Xu 	},
3580479bcc7cSHerbert Xu 	{
3581479bcc7cSHerbert Xu 		.aead = {
3582479bcc7cSHerbert Xu 			.base = {
3583479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
3584479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
3585479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
3586479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3587479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3588479bcc7cSHerbert Xu 			},
3589479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3590479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3591479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3592479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3593479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3594479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3595479bcc7cSHerbert Xu 		},
3596479bcc7cSHerbert Xu 		.caam = {
3597479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3598479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3599479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3600479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
3601479bcc7cSHerbert Xu 		},
3602479bcc7cSHerbert Xu 	},
3603479bcc7cSHerbert Xu 	{
3604479bcc7cSHerbert Xu 		.aead = {
3605479bcc7cSHerbert Xu 			.base = {
3606479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
3607479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
3608479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3609479bcc7cSHerbert Xu 						   "hmac-sha512-"
3610479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3611479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3612479bcc7cSHerbert Xu 			},
3613479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3614479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3615479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3616479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3617479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3618479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3619479bcc7cSHerbert Xu 		},
3620479bcc7cSHerbert Xu 		.caam = {
3621479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3622479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3623479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3624479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
3625479bcc7cSHerbert Xu 			.geniv = true,
3626479bcc7cSHerbert Xu 		},
3627479bcc7cSHerbert Xu 	},
3628479bcc7cSHerbert Xu 	{
3629479bcc7cSHerbert Xu 		.aead = {
3630479bcc7cSHerbert Xu 			.base = {
3631479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(des))",
3632479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
3633479bcc7cSHerbert Xu 						   "cbc-des-caam",
3634479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3635479bcc7cSHerbert Xu 			},
3636479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3637479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3638479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3639479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3640479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3641479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3642479bcc7cSHerbert Xu 		},
3643479bcc7cSHerbert Xu 		.caam = {
3644479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3645479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3646479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3647479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3648479bcc7cSHerbert Xu 		},
3649479bcc7cSHerbert Xu 	},
3650479bcc7cSHerbert Xu 	{
3651479bcc7cSHerbert Xu 		.aead = {
3652479bcc7cSHerbert Xu 			.base = {
3653479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
3654479bcc7cSHerbert Xu 					    "cbc(des)))",
3655479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
3656479bcc7cSHerbert Xu 						   "cbc-des-caam",
3657479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3658479bcc7cSHerbert Xu 			},
3659479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3660479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3661479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3662479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3663479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3664479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3665479bcc7cSHerbert Xu 		},
3666479bcc7cSHerbert Xu 		.caam = {
3667479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3668479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3669479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3670479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3671479bcc7cSHerbert Xu 			.geniv = true,
3672479bcc7cSHerbert Xu 		},
3673479bcc7cSHerbert Xu 	},
3674479bcc7cSHerbert Xu 	{
3675479bcc7cSHerbert Xu 		.aead = {
3676479bcc7cSHerbert Xu 			.base = {
3677479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),cbc(des))",
3678479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
3679479bcc7cSHerbert Xu 						   "cbc-des-caam",
3680479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3681479bcc7cSHerbert Xu 			},
3682479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3683479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3684479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3685479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3686479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3687479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3688479bcc7cSHerbert Xu 		},
3689479bcc7cSHerbert Xu 		.caam = {
3690479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3691479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3692479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3693479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
3694479bcc7cSHerbert Xu 		},
3695479bcc7cSHerbert Xu 	},
3696479bcc7cSHerbert Xu 	{
3697479bcc7cSHerbert Xu 		.aead = {
3698479bcc7cSHerbert Xu 			.base = {
3699479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
3700479bcc7cSHerbert Xu 					    "cbc(des)))",
3701479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3702479bcc7cSHerbert Xu 						   "hmac-sha1-cbc-des-caam",
3703479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3704479bcc7cSHerbert Xu 			},
3705479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3706479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3707479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3708479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3709479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3710479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3711479bcc7cSHerbert Xu 		},
3712479bcc7cSHerbert Xu 		.caam = {
3713479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3714479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3715479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3716479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
3717479bcc7cSHerbert Xu 			.geniv = true,
3718479bcc7cSHerbert Xu 		},
3719479bcc7cSHerbert Xu 	},
3720479bcc7cSHerbert Xu 	{
3721479bcc7cSHerbert Xu 		.aead = {
3722479bcc7cSHerbert Xu 			.base = {
3723479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),cbc(des))",
3724479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
3725479bcc7cSHerbert Xu 						   "cbc-des-caam",
3726479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3727479bcc7cSHerbert Xu 			},
3728479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3729479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3730479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3731479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3732479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3733479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3734479bcc7cSHerbert Xu 		},
3735479bcc7cSHerbert Xu 		.caam = {
3736479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3737479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3738479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3739479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
3740479bcc7cSHerbert Xu 		},
3741479bcc7cSHerbert Xu 	},
3742479bcc7cSHerbert Xu 	{
3743479bcc7cSHerbert Xu 		.aead = {
3744479bcc7cSHerbert Xu 			.base = {
3745479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
3746479bcc7cSHerbert Xu 					    "cbc(des)))",
3747479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3748479bcc7cSHerbert Xu 						   "hmac-sha224-cbc-des-caam",
3749479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3750479bcc7cSHerbert Xu 			},
3751479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3752479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3753479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3754479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3755479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3756479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3757479bcc7cSHerbert Xu 		},
3758479bcc7cSHerbert Xu 		.caam = {
3759479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3760479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3761479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3762479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
3763479bcc7cSHerbert Xu 			.geniv = true,
3764479bcc7cSHerbert Xu 		},
3765479bcc7cSHerbert Xu 	},
3766479bcc7cSHerbert Xu 	{
3767479bcc7cSHerbert Xu 		.aead = {
3768479bcc7cSHerbert Xu 			.base = {
3769479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),cbc(des))",
3770479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
3771479bcc7cSHerbert Xu 						   "cbc-des-caam",
3772479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3773479bcc7cSHerbert Xu 			},
3774479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3775479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3776479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3777479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3778479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3779479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3780479bcc7cSHerbert Xu 		},
3781479bcc7cSHerbert Xu 		.caam = {
3782479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3783479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3784479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3785479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3786479bcc7cSHerbert Xu 		},
3787479bcc7cSHerbert Xu 	},
3788479bcc7cSHerbert Xu 	{
3789479bcc7cSHerbert Xu 		.aead = {
3790479bcc7cSHerbert Xu 			.base = {
3791479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
3792479bcc7cSHerbert Xu 					    "cbc(des)))",
3793479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3794479bcc7cSHerbert Xu 						   "hmac-sha256-cbc-des-caam",
3795479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3796479bcc7cSHerbert Xu 			},
3797479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3798479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3799479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3800479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3801479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3802479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3803479bcc7cSHerbert Xu 		},
3804479bcc7cSHerbert Xu 		.caam = {
3805479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3806479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3807479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3808479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3809479bcc7cSHerbert Xu 			.geniv = true,
3810479bcc7cSHerbert Xu 		},
3811479bcc7cSHerbert Xu 	},
3812479bcc7cSHerbert Xu 	{
3813479bcc7cSHerbert Xu 		.aead = {
3814479bcc7cSHerbert Xu 			.base = {
3815479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),cbc(des))",
3816479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
3817479bcc7cSHerbert Xu 						   "cbc-des-caam",
3818479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3819479bcc7cSHerbert Xu 			},
3820479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3821479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3822479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3823479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3824479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3825479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3826479bcc7cSHerbert Xu 		},
3827479bcc7cSHerbert Xu 		.caam = {
3828479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3829479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3830479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3831479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3832479bcc7cSHerbert Xu 		},
3833479bcc7cSHerbert Xu 	},
3834479bcc7cSHerbert Xu 	{
3835479bcc7cSHerbert Xu 		.aead = {
3836479bcc7cSHerbert Xu 			.base = {
3837479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
3838479bcc7cSHerbert Xu 					    "cbc(des)))",
3839479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3840479bcc7cSHerbert Xu 						   "hmac-sha384-cbc-des-caam",
3841479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3842479bcc7cSHerbert Xu 			},
3843479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3844479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3845479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3846479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3847479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3848479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3849479bcc7cSHerbert Xu 		},
3850479bcc7cSHerbert Xu 		.caam = {
3851479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3852479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3853479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3854479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3855479bcc7cSHerbert Xu 			.geniv = true,
3856479bcc7cSHerbert Xu 		},
3857479bcc7cSHerbert Xu 	},
3858479bcc7cSHerbert Xu 	{
3859479bcc7cSHerbert Xu 		.aead = {
3860479bcc7cSHerbert Xu 			.base = {
3861479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),cbc(des))",
3862479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
3863479bcc7cSHerbert Xu 						   "cbc-des-caam",
3864479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3865479bcc7cSHerbert Xu 			},
3866479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3867479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3868479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3869479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3870479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3871479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3872479bcc7cSHerbert Xu 		},
3873479bcc7cSHerbert Xu 		.caam = {
3874479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3875479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3876479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3877479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
3878479bcc7cSHerbert Xu 		},
3879479bcc7cSHerbert Xu 	},
3880479bcc7cSHerbert Xu 	{
3881479bcc7cSHerbert Xu 		.aead = {
3882479bcc7cSHerbert Xu 			.base = {
3883479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
3884479bcc7cSHerbert Xu 					    "cbc(des)))",
3885479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3886479bcc7cSHerbert Xu 						   "hmac-sha512-cbc-des-caam",
3887479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3888479bcc7cSHerbert Xu 			},
3889479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3890479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3891479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3892479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3893479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3894479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3895479bcc7cSHerbert Xu 		},
3896479bcc7cSHerbert Xu 		.caam = {
3897479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3898479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3899479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3900479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
3901479bcc7cSHerbert Xu 			.geniv = true,
3902479bcc7cSHerbert Xu 		},
3903479bcc7cSHerbert Xu 	},
3904479bcc7cSHerbert Xu 	{
3905479bcc7cSHerbert Xu 		.aead = {
3906479bcc7cSHerbert Xu 			.base = {
3907479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),"
3908479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3909479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
3910479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3911479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3912479bcc7cSHerbert Xu 			},
3913479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3914479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3915479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3916479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3917479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3918479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3919479bcc7cSHerbert Xu 		},
3920479bcc7cSHerbert Xu 		.caam = {
3921479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3922479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3923479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3924479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3925479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3926479bcc7cSHerbert Xu 			.rfc3686 = true,
3927479bcc7cSHerbert Xu 		},
3928479bcc7cSHerbert Xu 	},
3929479bcc7cSHerbert Xu 	{
3930479bcc7cSHerbert Xu 		.aead = {
3931479bcc7cSHerbert Xu 			.base = {
3932479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
3933479bcc7cSHerbert Xu 					    "hmac(md5),rfc3686(ctr(aes))))",
3934479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-md5-"
3935479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3936479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3937479bcc7cSHerbert Xu 			},
3938479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3939479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3940479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3941479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3942479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3943479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3944479bcc7cSHerbert Xu 		},
3945479bcc7cSHerbert Xu 		.caam = {
3946479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3947479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3948479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3949479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3950479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3951479bcc7cSHerbert Xu 			.rfc3686 = true,
3952479bcc7cSHerbert Xu 			.geniv = true,
3953479bcc7cSHerbert Xu 		},
3954479bcc7cSHerbert Xu 	},
3955479bcc7cSHerbert Xu 	{
3956479bcc7cSHerbert Xu 		.aead = {
3957479bcc7cSHerbert Xu 			.base = {
3958479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
3959479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
3960479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
3961479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3962479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3963479bcc7cSHerbert Xu 			},
3964479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3965479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3966479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3967479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3968479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3969479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3970479bcc7cSHerbert Xu 		},
3971479bcc7cSHerbert Xu 		.caam = {
3972479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3973479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3974479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3975479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3976479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
3977479bcc7cSHerbert Xu 			.rfc3686 = true,
3978479bcc7cSHerbert Xu 		},
3979479bcc7cSHerbert Xu 	},
3980479bcc7cSHerbert Xu 	{
3981479bcc7cSHerbert Xu 		.aead = {
3982479bcc7cSHerbert Xu 			.base = {
3983479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
3984479bcc7cSHerbert Xu 					    "hmac(sha1),rfc3686(ctr(aes))))",
3985479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha1-"
3986479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
3987479bcc7cSHerbert Xu 				.cra_blocksize = 1,
3988479bcc7cSHerbert Xu 			},
3989479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3990479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3991479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3992479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
3993479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
3994479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3995479bcc7cSHerbert Xu 		},
3996479bcc7cSHerbert Xu 		.caam = {
3997479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
3998479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
3999479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
4000479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4001479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
4002479bcc7cSHerbert Xu 			.rfc3686 = true,
4003479bcc7cSHerbert Xu 			.geniv = true,
4004479bcc7cSHerbert Xu 		},
4005479bcc7cSHerbert Xu 	},
4006479bcc7cSHerbert Xu 	{
4007479bcc7cSHerbert Xu 		.aead = {
4008479bcc7cSHerbert Xu 			.base = {
4009479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
4010479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
4011479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
4012479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4013479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4014479bcc7cSHerbert Xu 			},
4015479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4016479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4017479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4018479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
4019479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4020479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
4021479bcc7cSHerbert Xu 		},
4022479bcc7cSHerbert Xu 		.caam = {
4023479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4024479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4025479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
4026479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4027479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
4028479bcc7cSHerbert Xu 			.rfc3686 = true,
4029479bcc7cSHerbert Xu 		},
4030479bcc7cSHerbert Xu 	},
4031479bcc7cSHerbert Xu 	{
4032479bcc7cSHerbert Xu 		.aead = {
4033479bcc7cSHerbert Xu 			.base = {
4034479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
4035479bcc7cSHerbert Xu 					    "hmac(sha224),rfc3686(ctr(aes))))",
4036479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha224-"
4037479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4038479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4039479bcc7cSHerbert Xu 			},
4040479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4041479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4042479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4043479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
4044479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4045479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
4046479bcc7cSHerbert Xu 		},
4047479bcc7cSHerbert Xu 		.caam = {
4048479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4049479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4050479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
4051479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4052479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
4053479bcc7cSHerbert Xu 			.rfc3686 = true,
4054479bcc7cSHerbert Xu 			.geniv = true,
4055479bcc7cSHerbert Xu 		},
4056479bcc7cSHerbert Xu 	},
4057479bcc7cSHerbert Xu 	{
4058479bcc7cSHerbert Xu 		.aead = {
4059479bcc7cSHerbert Xu 			.base = {
4060479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
4061479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
4062479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
4063479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4064479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4065479bcc7cSHerbert Xu 			},
4066479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4067479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4068479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4069479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
4070479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4071479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
4072479bcc7cSHerbert Xu 		},
4073479bcc7cSHerbert Xu 		.caam = {
4074479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4075479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4076479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
4077479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4078479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
4079479bcc7cSHerbert Xu 			.rfc3686 = true,
4080479bcc7cSHerbert Xu 		},
4081479bcc7cSHerbert Xu 	},
4082479bcc7cSHerbert Xu 	{
4083479bcc7cSHerbert Xu 		.aead = {
4084479bcc7cSHerbert Xu 			.base = {
4085479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha256),"
4086479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
4087479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha256-"
4088479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4089479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4090479bcc7cSHerbert Xu 			},
4091479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4092479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4093479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4094479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
4095479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4096479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
4097479bcc7cSHerbert Xu 		},
4098479bcc7cSHerbert Xu 		.caam = {
4099479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4100479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4101479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
4102479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4103479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
4104479bcc7cSHerbert Xu 			.rfc3686 = true,
4105479bcc7cSHerbert Xu 			.geniv = true,
4106479bcc7cSHerbert Xu 		},
4107479bcc7cSHerbert Xu 	},
4108479bcc7cSHerbert Xu 	{
4109479bcc7cSHerbert Xu 		.aead = {
4110479bcc7cSHerbert Xu 			.base = {
4111479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
4112479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
4113479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
4114479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4115479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4116479bcc7cSHerbert Xu 			},
4117479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4118479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4119479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4120479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
4121479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4122479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
4123479bcc7cSHerbert Xu 		},
4124479bcc7cSHerbert Xu 		.caam = {
4125479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4126479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4127479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
4128479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4129479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
4130479bcc7cSHerbert Xu 			.rfc3686 = true,
4131479bcc7cSHerbert Xu 		},
4132479bcc7cSHerbert Xu 	},
4133479bcc7cSHerbert Xu 	{
4134479bcc7cSHerbert Xu 		.aead = {
4135479bcc7cSHerbert Xu 			.base = {
4136479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha384),"
4137479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
4138479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha384-"
4139479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4140479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4141479bcc7cSHerbert Xu 			},
4142479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4143479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4144479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4145479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
4146479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4147479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
4148479bcc7cSHerbert Xu 		},
4149479bcc7cSHerbert Xu 		.caam = {
4150479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4151479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4152479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
4153479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4154479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
4155479bcc7cSHerbert Xu 			.rfc3686 = true,
4156479bcc7cSHerbert Xu 			.geniv = true,
4157479bcc7cSHerbert Xu 		},
4158479bcc7cSHerbert Xu 	},
4159479bcc7cSHerbert Xu 	{
4160479bcc7cSHerbert Xu 		.aead = {
4161479bcc7cSHerbert Xu 			.base = {
4162479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
4163479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
4164479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
4165479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4166479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4167479bcc7cSHerbert Xu 			},
4168479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4169479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4170479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4171479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
4172479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4173479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
4174479bcc7cSHerbert Xu 		},
4175479bcc7cSHerbert Xu 		.caam = {
4176479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4177479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4178479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
4179479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4180479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
4181479bcc7cSHerbert Xu 			.rfc3686 = true,
4182479bcc7cSHerbert Xu 		},
4183479bcc7cSHerbert Xu 	},
4184479bcc7cSHerbert Xu 	{
4185479bcc7cSHerbert Xu 		.aead = {
4186479bcc7cSHerbert Xu 			.base = {
4187479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha512),"
4188479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
4189479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha512-"
4190479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4191479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4192479bcc7cSHerbert Xu 			},
4193479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4194479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4195479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4196479bcc7cSHerbert Xu 			.decrypt = aead_givdecrypt,
4197479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4198479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
4199479bcc7cSHerbert Xu 		},
4200479bcc7cSHerbert Xu 		.caam = {
4201479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4202479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4203479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
4204479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4205479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
4206479bcc7cSHerbert Xu 			.rfc3686 = true,
4207479bcc7cSHerbert Xu 			.geniv = true,
4208479bcc7cSHerbert Xu 		},
4209479bcc7cSHerbert Xu 	},
4210f2147b88SHerbert Xu };
4211f2147b88SHerbert Xu 
4212f2147b88SHerbert Xu struct caam_crypto_alg {
4213f2147b88SHerbert Xu 	struct crypto_alg crypto_alg;
4214f2147b88SHerbert Xu 	struct list_head entry;
4215f2147b88SHerbert Xu 	struct caam_alg_entry caam;
4216f2147b88SHerbert Xu };
4217f2147b88SHerbert Xu 
4218f2147b88SHerbert Xu static int caam_init_common(struct caam_ctx *ctx, struct caam_alg_entry *caam)
4219f2147b88SHerbert Xu {
4220f2147b88SHerbert Xu 	ctx->jrdev = caam_jr_alloc();
4221f2147b88SHerbert Xu 	if (IS_ERR(ctx->jrdev)) {
4222f2147b88SHerbert Xu 		pr_err("Job Ring Device allocation for transform failed\n");
4223f2147b88SHerbert Xu 		return PTR_ERR(ctx->jrdev);
4224f2147b88SHerbert Xu 	}
4225f2147b88SHerbert Xu 
4226f2147b88SHerbert Xu 	/* copy descriptor header template value */
4227f2147b88SHerbert Xu 	ctx->class1_alg_type = OP_TYPE_CLASS1_ALG | caam->class1_alg_type;
4228f2147b88SHerbert Xu 	ctx->class2_alg_type = OP_TYPE_CLASS2_ALG | caam->class2_alg_type;
4229f2147b88SHerbert Xu 	ctx->alg_op = OP_TYPE_CLASS2_ALG | caam->alg_op;
4230f2147b88SHerbert Xu 
4231f2147b88SHerbert Xu 	return 0;
4232f2147b88SHerbert Xu }
4233f2147b88SHerbert Xu 
42348e8ec596SKim Phillips static int caam_cra_init(struct crypto_tfm *tfm)
42358e8ec596SKim Phillips {
42368e8ec596SKim Phillips 	struct crypto_alg *alg = tfm->__crt_alg;
42378e8ec596SKim Phillips 	struct caam_crypto_alg *caam_alg =
42388e8ec596SKim Phillips 		 container_of(alg, struct caam_crypto_alg, crypto_alg);
42398e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_tfm_ctx(tfm);
42408e8ec596SKim Phillips 
4241f2147b88SHerbert Xu 	return caam_init_common(ctx, &caam_alg->caam);
4242cfc6f11bSRuchika Gupta }
42438e8ec596SKim Phillips 
4244f2147b88SHerbert Xu static int caam_aead_init(struct crypto_aead *tfm)
42458e8ec596SKim Phillips {
4246f2147b88SHerbert Xu 	struct aead_alg *alg = crypto_aead_alg(tfm);
4247f2147b88SHerbert Xu 	struct caam_aead_alg *caam_alg =
4248f2147b88SHerbert Xu 		 container_of(alg, struct caam_aead_alg, aead);
4249f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(tfm);
42508e8ec596SKim Phillips 
4251f2147b88SHerbert Xu 	return caam_init_common(ctx, &caam_alg->caam);
4252f2147b88SHerbert Xu }
4253f2147b88SHerbert Xu 
4254f2147b88SHerbert Xu static void caam_exit_common(struct caam_ctx *ctx)
4255f2147b88SHerbert Xu {
42561acebad3SYuan Kang 	if (ctx->sh_desc_enc_dma &&
42571acebad3SYuan Kang 	    !dma_mapping_error(ctx->jrdev, ctx->sh_desc_enc_dma))
42581acebad3SYuan Kang 		dma_unmap_single(ctx->jrdev, ctx->sh_desc_enc_dma,
42591acebad3SYuan Kang 				 desc_bytes(ctx->sh_desc_enc), DMA_TO_DEVICE);
42601acebad3SYuan Kang 	if (ctx->sh_desc_dec_dma &&
42611acebad3SYuan Kang 	    !dma_mapping_error(ctx->jrdev, ctx->sh_desc_dec_dma))
42621acebad3SYuan Kang 		dma_unmap_single(ctx->jrdev, ctx->sh_desc_dec_dma,
42631acebad3SYuan Kang 				 desc_bytes(ctx->sh_desc_dec), DMA_TO_DEVICE);
42641acebad3SYuan Kang 	if (ctx->sh_desc_givenc_dma &&
42651acebad3SYuan Kang 	    !dma_mapping_error(ctx->jrdev, ctx->sh_desc_givenc_dma))
42661acebad3SYuan Kang 		dma_unmap_single(ctx->jrdev, ctx->sh_desc_givenc_dma,
42671acebad3SYuan Kang 				 desc_bytes(ctx->sh_desc_givenc),
42684427b1b4SKim Phillips 				 DMA_TO_DEVICE);
4269ec31eed7SHoria Geanta 	if (ctx->key_dma &&
4270ec31eed7SHoria Geanta 	    !dma_mapping_error(ctx->jrdev, ctx->key_dma))
4271ec31eed7SHoria Geanta 		dma_unmap_single(ctx->jrdev, ctx->key_dma,
4272ec31eed7SHoria Geanta 				 ctx->enckeylen + ctx->split_key_pad_len,
4273ec31eed7SHoria Geanta 				 DMA_TO_DEVICE);
4274cfc6f11bSRuchika Gupta 
4275cfc6f11bSRuchika Gupta 	caam_jr_free(ctx->jrdev);
42768e8ec596SKim Phillips }
42778e8ec596SKim Phillips 
4278f2147b88SHerbert Xu static void caam_cra_exit(struct crypto_tfm *tfm)
4279f2147b88SHerbert Xu {
4280f2147b88SHerbert Xu 	caam_exit_common(crypto_tfm_ctx(tfm));
4281f2147b88SHerbert Xu }
4282f2147b88SHerbert Xu 
4283f2147b88SHerbert Xu static void caam_aead_exit(struct crypto_aead *tfm)
4284f2147b88SHerbert Xu {
4285f2147b88SHerbert Xu 	caam_exit_common(crypto_aead_ctx(tfm));
4286f2147b88SHerbert Xu }
4287f2147b88SHerbert Xu 
42888e8ec596SKim Phillips static void __exit caam_algapi_exit(void)
42898e8ec596SKim Phillips {
42908e8ec596SKim Phillips 
42918e8ec596SKim Phillips 	struct caam_crypto_alg *t_alg, *n;
4292f2147b88SHerbert Xu 	int i;
4293f2147b88SHerbert Xu 
4294f2147b88SHerbert Xu 	for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
4295f2147b88SHerbert Xu 		struct caam_aead_alg *t_alg = driver_aeads + i;
4296f2147b88SHerbert Xu 
4297f2147b88SHerbert Xu 		if (t_alg->registered)
4298f2147b88SHerbert Xu 			crypto_unregister_aead(&t_alg->aead);
4299f2147b88SHerbert Xu 	}
43008e8ec596SKim Phillips 
4301cfc6f11bSRuchika Gupta 	if (!alg_list.next)
43028e8ec596SKim Phillips 		return;
43038e8ec596SKim Phillips 
4304cfc6f11bSRuchika Gupta 	list_for_each_entry_safe(t_alg, n, &alg_list, entry) {
43058e8ec596SKim Phillips 		crypto_unregister_alg(&t_alg->crypto_alg);
43068e8ec596SKim Phillips 		list_del(&t_alg->entry);
43078e8ec596SKim Phillips 		kfree(t_alg);
43088e8ec596SKim Phillips 	}
43098e8ec596SKim Phillips }
43108e8ec596SKim Phillips 
4311cfc6f11bSRuchika Gupta static struct caam_crypto_alg *caam_alg_alloc(struct caam_alg_template
43128e8ec596SKim Phillips 					      *template)
43138e8ec596SKim Phillips {
43148e8ec596SKim Phillips 	struct caam_crypto_alg *t_alg;
43158e8ec596SKim Phillips 	struct crypto_alg *alg;
43168e8ec596SKim Phillips 
43178e8ec596SKim Phillips 	t_alg = kzalloc(sizeof(struct caam_crypto_alg), GFP_KERNEL);
43188e8ec596SKim Phillips 	if (!t_alg) {
4319cfc6f11bSRuchika Gupta 		pr_err("failed to allocate t_alg\n");
43208e8ec596SKim Phillips 		return ERR_PTR(-ENOMEM);
43218e8ec596SKim Phillips 	}
43228e8ec596SKim Phillips 
43238e8ec596SKim Phillips 	alg = &t_alg->crypto_alg;
43248e8ec596SKim Phillips 
43258e8ec596SKim Phillips 	snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", template->name);
43268e8ec596SKim Phillips 	snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
43278e8ec596SKim Phillips 		 template->driver_name);
43288e8ec596SKim Phillips 	alg->cra_module = THIS_MODULE;
43298e8ec596SKim Phillips 	alg->cra_init = caam_cra_init;
43308e8ec596SKim Phillips 	alg->cra_exit = caam_cra_exit;
43318e8ec596SKim Phillips 	alg->cra_priority = CAAM_CRA_PRIORITY;
43328e8ec596SKim Phillips 	alg->cra_blocksize = template->blocksize;
43338e8ec596SKim Phillips 	alg->cra_alignmask = 0;
43348e8ec596SKim Phillips 	alg->cra_ctxsize = sizeof(struct caam_ctx);
4335d912bb76SNikos Mavrogiannopoulos 	alg->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY |
4336d912bb76SNikos Mavrogiannopoulos 			 template->type;
4337885e9e2fSYuan Kang 	switch (template->type) {
43387222d1a3SCatalin Vasile 	case CRYPTO_ALG_TYPE_GIVCIPHER:
43397222d1a3SCatalin Vasile 		alg->cra_type = &crypto_givcipher_type;
43407222d1a3SCatalin Vasile 		alg->cra_ablkcipher = template->template_ablkcipher;
43417222d1a3SCatalin Vasile 		break;
4342acdca31dSYuan Kang 	case CRYPTO_ALG_TYPE_ABLKCIPHER:
4343acdca31dSYuan Kang 		alg->cra_type = &crypto_ablkcipher_type;
4344acdca31dSYuan Kang 		alg->cra_ablkcipher = template->template_ablkcipher;
4345acdca31dSYuan Kang 		break;
4346885e9e2fSYuan Kang 	}
43478e8ec596SKim Phillips 
4348f2147b88SHerbert Xu 	t_alg->caam.class1_alg_type = template->class1_alg_type;
4349f2147b88SHerbert Xu 	t_alg->caam.class2_alg_type = template->class2_alg_type;
4350f2147b88SHerbert Xu 	t_alg->caam.alg_op = template->alg_op;
43518e8ec596SKim Phillips 
43528e8ec596SKim Phillips 	return t_alg;
43538e8ec596SKim Phillips }
43548e8ec596SKim Phillips 
4355f2147b88SHerbert Xu static void caam_aead_alg_init(struct caam_aead_alg *t_alg)
4356f2147b88SHerbert Xu {
4357f2147b88SHerbert Xu 	struct aead_alg *alg = &t_alg->aead;
4358f2147b88SHerbert Xu 
4359f2147b88SHerbert Xu 	alg->base.cra_module = THIS_MODULE;
4360f2147b88SHerbert Xu 	alg->base.cra_priority = CAAM_CRA_PRIORITY;
4361f2147b88SHerbert Xu 	alg->base.cra_ctxsize = sizeof(struct caam_ctx);
43625e4b8c1fSHerbert Xu 	alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY;
4363f2147b88SHerbert Xu 
4364f2147b88SHerbert Xu 	alg->init = caam_aead_init;
4365f2147b88SHerbert Xu 	alg->exit = caam_aead_exit;
4366f2147b88SHerbert Xu }
4367f2147b88SHerbert Xu 
43688e8ec596SKim Phillips static int __init caam_algapi_init(void)
43698e8ec596SKim Phillips {
437035af6403SRuchika Gupta 	struct device_node *dev_node;
437135af6403SRuchika Gupta 	struct platform_device *pdev;
437235af6403SRuchika Gupta 	struct device *ctrldev;
4373bf83490eSVictoria Milhoan 	struct caam_drv_private *priv;
43748e8ec596SKim Phillips 	int i = 0, err = 0;
4375bf83490eSVictoria Milhoan 	u32 cha_vid, cha_inst, des_inst, aes_inst, md_inst;
4376bf83490eSVictoria Milhoan 	unsigned int md_limit = SHA512_DIGEST_SIZE;
4377f2147b88SHerbert Xu 	bool registered = false;
43788e8ec596SKim Phillips 
437935af6403SRuchika Gupta 	dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
438035af6403SRuchika Gupta 	if (!dev_node) {
438135af6403SRuchika Gupta 		dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
438235af6403SRuchika Gupta 		if (!dev_node)
438335af6403SRuchika Gupta 			return -ENODEV;
438435af6403SRuchika Gupta 	}
438535af6403SRuchika Gupta 
438635af6403SRuchika Gupta 	pdev = of_find_device_by_node(dev_node);
438735af6403SRuchika Gupta 	if (!pdev) {
438835af6403SRuchika Gupta 		of_node_put(dev_node);
438935af6403SRuchika Gupta 		return -ENODEV;
439035af6403SRuchika Gupta 	}
439135af6403SRuchika Gupta 
439235af6403SRuchika Gupta 	ctrldev = &pdev->dev;
439335af6403SRuchika Gupta 	priv = dev_get_drvdata(ctrldev);
439435af6403SRuchika Gupta 	of_node_put(dev_node);
439535af6403SRuchika Gupta 
439635af6403SRuchika Gupta 	/*
439735af6403SRuchika Gupta 	 * If priv is NULL, it's probably because the caam driver wasn't
439835af6403SRuchika Gupta 	 * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
439935af6403SRuchika Gupta 	 */
440035af6403SRuchika Gupta 	if (!priv)
440135af6403SRuchika Gupta 		return -ENODEV;
440235af6403SRuchika Gupta 
440335af6403SRuchika Gupta 
4404cfc6f11bSRuchika Gupta 	INIT_LIST_HEAD(&alg_list);
44058e8ec596SKim Phillips 
4406bf83490eSVictoria Milhoan 	/*
4407bf83490eSVictoria Milhoan 	 * Register crypto algorithms the device supports.
4408bf83490eSVictoria Milhoan 	 * First, detect presence and attributes of DES, AES, and MD blocks.
4409bf83490eSVictoria Milhoan 	 */
4410bf83490eSVictoria Milhoan 	cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
4411bf83490eSVictoria Milhoan 	cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
4412bf83490eSVictoria Milhoan 	des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >> CHA_ID_LS_DES_SHIFT;
4413bf83490eSVictoria Milhoan 	aes_inst = (cha_inst & CHA_ID_LS_AES_MASK) >> CHA_ID_LS_AES_SHIFT;
4414bf83490eSVictoria Milhoan 	md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
44158e8ec596SKim Phillips 
4416bf83490eSVictoria Milhoan 	/* If MD is present, limit digest size based on LP256 */
4417bf83490eSVictoria Milhoan 	if (md_inst && ((cha_vid & CHA_ID_LS_MD_MASK) == CHA_ID_LS_MD_LP256))
4418bf83490eSVictoria Milhoan 		md_limit = SHA256_DIGEST_SIZE;
4419bf83490eSVictoria Milhoan 
4420bf83490eSVictoria Milhoan 	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
4421bf83490eSVictoria Milhoan 		struct caam_crypto_alg *t_alg;
4422bf83490eSVictoria Milhoan 		struct caam_alg_template *alg = driver_algs + i;
4423bf83490eSVictoria Milhoan 		u32 alg_sel = alg->class1_alg_type & OP_ALG_ALGSEL_MASK;
4424bf83490eSVictoria Milhoan 
4425bf83490eSVictoria Milhoan 		/* Skip DES algorithms if not supported by device */
4426bf83490eSVictoria Milhoan 		if (!des_inst &&
4427bf83490eSVictoria Milhoan 		    ((alg_sel == OP_ALG_ALGSEL_3DES) ||
4428bf83490eSVictoria Milhoan 		     (alg_sel == OP_ALG_ALGSEL_DES)))
4429bf83490eSVictoria Milhoan 				continue;
4430bf83490eSVictoria Milhoan 
4431bf83490eSVictoria Milhoan 		/* Skip AES algorithms if not supported by device */
4432bf83490eSVictoria Milhoan 		if (!aes_inst && (alg_sel == OP_ALG_ALGSEL_AES))
4433bf83490eSVictoria Milhoan 				continue;
4434bf83490eSVictoria Milhoan 
4435bf83490eSVictoria Milhoan 		t_alg = caam_alg_alloc(alg);
44368e8ec596SKim Phillips 		if (IS_ERR(t_alg)) {
44378e8ec596SKim Phillips 			err = PTR_ERR(t_alg);
4438bf83490eSVictoria Milhoan 			pr_warn("%s alg allocation failed\n", alg->driver_name);
44398e8ec596SKim Phillips 			continue;
44408e8ec596SKim Phillips 		}
44418e8ec596SKim Phillips 
44428e8ec596SKim Phillips 		err = crypto_register_alg(&t_alg->crypto_alg);
44438e8ec596SKim Phillips 		if (err) {
4444cfc6f11bSRuchika Gupta 			pr_warn("%s alg registration failed\n",
44458e8ec596SKim Phillips 				t_alg->crypto_alg.cra_driver_name);
44468e8ec596SKim Phillips 			kfree(t_alg);
4447f2147b88SHerbert Xu 			continue;
44488e8ec596SKim Phillips 		}
4449f2147b88SHerbert Xu 
4450f2147b88SHerbert Xu 		list_add_tail(&t_alg->entry, &alg_list);
4451f2147b88SHerbert Xu 		registered = true;
4452f2147b88SHerbert Xu 	}
4453f2147b88SHerbert Xu 
4454f2147b88SHerbert Xu 	for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
4455f2147b88SHerbert Xu 		struct caam_aead_alg *t_alg = driver_aeads + i;
4456bf83490eSVictoria Milhoan 		u32 c1_alg_sel = t_alg->caam.class1_alg_type &
4457bf83490eSVictoria Milhoan 				 OP_ALG_ALGSEL_MASK;
4458bf83490eSVictoria Milhoan 		u32 c2_alg_sel = t_alg->caam.class2_alg_type &
4459bf83490eSVictoria Milhoan 				 OP_ALG_ALGSEL_MASK;
4460bf83490eSVictoria Milhoan 		u32 alg_aai = t_alg->caam.class1_alg_type & OP_ALG_AAI_MASK;
4461bf83490eSVictoria Milhoan 
4462bf83490eSVictoria Milhoan 		/* Skip DES algorithms if not supported by device */
4463bf83490eSVictoria Milhoan 		if (!des_inst &&
4464bf83490eSVictoria Milhoan 		    ((c1_alg_sel == OP_ALG_ALGSEL_3DES) ||
4465bf83490eSVictoria Milhoan 		     (c1_alg_sel == OP_ALG_ALGSEL_DES)))
4466bf83490eSVictoria Milhoan 				continue;
4467bf83490eSVictoria Milhoan 
4468bf83490eSVictoria Milhoan 		/* Skip AES algorithms if not supported by device */
4469bf83490eSVictoria Milhoan 		if (!aes_inst && (c1_alg_sel == OP_ALG_ALGSEL_AES))
4470bf83490eSVictoria Milhoan 				continue;
4471bf83490eSVictoria Milhoan 
4472bf83490eSVictoria Milhoan 		/*
4473bf83490eSVictoria Milhoan 		 * Check support for AES algorithms not available
4474bf83490eSVictoria Milhoan 		 * on LP devices.
4475bf83490eSVictoria Milhoan 		 */
4476bf83490eSVictoria Milhoan 		if ((cha_vid & CHA_ID_LS_AES_MASK) == CHA_ID_LS_AES_LP)
4477bf83490eSVictoria Milhoan 			if (alg_aai == OP_ALG_AAI_GCM)
4478bf83490eSVictoria Milhoan 				continue;
4479bf83490eSVictoria Milhoan 
4480bf83490eSVictoria Milhoan 		/*
4481bf83490eSVictoria Milhoan 		 * Skip algorithms requiring message digests
4482bf83490eSVictoria Milhoan 		 * if MD or MD size is not supported by device.
4483bf83490eSVictoria Milhoan 		 */
4484bf83490eSVictoria Milhoan 		if (c2_alg_sel &&
4485bf83490eSVictoria Milhoan 		    (!md_inst || (t_alg->aead.maxauthsize > md_limit)))
4486bf83490eSVictoria Milhoan 				continue;
4487f2147b88SHerbert Xu 
4488f2147b88SHerbert Xu 		caam_aead_alg_init(t_alg);
4489f2147b88SHerbert Xu 
4490f2147b88SHerbert Xu 		err = crypto_register_aead(&t_alg->aead);
4491f2147b88SHerbert Xu 		if (err) {
4492f2147b88SHerbert Xu 			pr_warn("%s alg registration failed\n",
4493f2147b88SHerbert Xu 				t_alg->aead.base.cra_driver_name);
4494f2147b88SHerbert Xu 			continue;
4495f2147b88SHerbert Xu 		}
4496f2147b88SHerbert Xu 
4497f2147b88SHerbert Xu 		t_alg->registered = true;
4498f2147b88SHerbert Xu 		registered = true;
4499f2147b88SHerbert Xu 	}
4500f2147b88SHerbert Xu 
4501f2147b88SHerbert Xu 	if (registered)
4502cfc6f11bSRuchika Gupta 		pr_info("caam algorithms registered in /proc/crypto\n");
45038e8ec596SKim Phillips 
45048e8ec596SKim Phillips 	return err;
45058e8ec596SKim Phillips }
45068e8ec596SKim Phillips 
45078e8ec596SKim Phillips module_init(caam_algapi_init);
45088e8ec596SKim Phillips module_exit(caam_algapi_exit);
45098e8ec596SKim Phillips 
45108e8ec596SKim Phillips MODULE_LICENSE("GPL");
45118e8ec596SKim Phillips MODULE_DESCRIPTION("FSL CAAM support for crypto API");
45128e8ec596SKim Phillips MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
4513