xref: /openbmc/linux/drivers/crypto/caam/caamalg.c (revision 00fef2b2)
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
1145ecf8ef9SCatalin Vasile 
1155ecf8ef9SCatalin Vasile #ifdef DEBUG
1165ecf8ef9SCatalin Vasile #include <linux/highmem.h>
1175ecf8ef9SCatalin Vasile 
1185ecf8ef9SCatalin Vasile static void dbg_dump_sg(const char *level, const char *prefix_str,
1195ecf8ef9SCatalin Vasile 			int prefix_type, int rowsize, int groupsize,
12000fef2b2SHoria Geantă 			struct scatterlist *sg, size_t tlen, bool ascii)
1215ecf8ef9SCatalin Vasile {
1225ecf8ef9SCatalin Vasile 	struct scatterlist *it;
1235ecf8ef9SCatalin Vasile 	void *it_page;
1245ecf8ef9SCatalin Vasile 	size_t len;
1255ecf8ef9SCatalin Vasile 	void *buf;
1265ecf8ef9SCatalin Vasile 
1275ecf8ef9SCatalin Vasile 	for (it = sg; it != NULL && tlen > 0 ; it = sg_next(sg)) {
1285ecf8ef9SCatalin Vasile 		/*
1295ecf8ef9SCatalin Vasile 		 * make sure the scatterlist's page
1305ecf8ef9SCatalin Vasile 		 * has a valid virtual memory mapping
1315ecf8ef9SCatalin Vasile 		 */
1325ecf8ef9SCatalin Vasile 		it_page = kmap_atomic(sg_page(it));
1335ecf8ef9SCatalin Vasile 		if (unlikely(!it_page)) {
1345ecf8ef9SCatalin Vasile 			printk(KERN_ERR "dbg_dump_sg: kmap failed\n");
1355ecf8ef9SCatalin Vasile 			return;
1365ecf8ef9SCatalin Vasile 		}
1375ecf8ef9SCatalin Vasile 
1385ecf8ef9SCatalin Vasile 		buf = it_page + it->offset;
139d69985a0SArnd Bergmann 		len = min_t(size_t, tlen, it->length);
1405ecf8ef9SCatalin Vasile 		print_hex_dump(level, prefix_str, prefix_type, rowsize,
1415ecf8ef9SCatalin Vasile 			       groupsize, buf, len, ascii);
1425ecf8ef9SCatalin Vasile 		tlen -= len;
1435ecf8ef9SCatalin Vasile 
1445ecf8ef9SCatalin Vasile 		kunmap_atomic(it_page);
1455ecf8ef9SCatalin Vasile 	}
1465ecf8ef9SCatalin Vasile }
1475ecf8ef9SCatalin Vasile #endif
1485ecf8ef9SCatalin Vasile 
149cfc6f11bSRuchika Gupta static struct list_head alg_list;
1508e8ec596SKim Phillips 
151479bcc7cSHerbert Xu struct caam_alg_entry {
152479bcc7cSHerbert Xu 	int class1_alg_type;
153479bcc7cSHerbert Xu 	int class2_alg_type;
154479bcc7cSHerbert Xu 	int alg_op;
155479bcc7cSHerbert Xu 	bool rfc3686;
156479bcc7cSHerbert Xu 	bool geniv;
157479bcc7cSHerbert Xu };
158479bcc7cSHerbert Xu 
159479bcc7cSHerbert Xu struct caam_aead_alg {
160479bcc7cSHerbert Xu 	struct aead_alg aead;
161479bcc7cSHerbert Xu 	struct caam_alg_entry caam;
162479bcc7cSHerbert Xu 	bool registered;
163479bcc7cSHerbert Xu };
164479bcc7cSHerbert Xu 
1651acebad3SYuan Kang /* Set DK bit in class 1 operation if shared */
1661acebad3SYuan Kang static inline void append_dec_op1(u32 *desc, u32 type)
1671acebad3SYuan Kang {
1681acebad3SYuan Kang 	u32 *jump_cmd, *uncond_jump_cmd;
1691acebad3SYuan Kang 
170a60384dfSHoria Geanta 	/* DK bit is valid only for AES */
171a60384dfSHoria Geanta 	if ((type & OP_ALG_ALGSEL_MASK) != OP_ALG_ALGSEL_AES) {
172a60384dfSHoria Geanta 		append_operation(desc, type | OP_ALG_AS_INITFINAL |
173a60384dfSHoria Geanta 				 OP_ALG_DECRYPT);
174a60384dfSHoria Geanta 		return;
175a60384dfSHoria Geanta 	}
176a60384dfSHoria Geanta 
1771acebad3SYuan Kang 	jump_cmd = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
1781acebad3SYuan Kang 	append_operation(desc, type | OP_ALG_AS_INITFINAL |
1791acebad3SYuan Kang 			 OP_ALG_DECRYPT);
1801acebad3SYuan Kang 	uncond_jump_cmd = append_jump(desc, JUMP_TEST_ALL);
1811acebad3SYuan Kang 	set_jump_tgt_here(desc, jump_cmd);
1821acebad3SYuan Kang 	append_operation(desc, type | OP_ALG_AS_INITFINAL |
1831acebad3SYuan Kang 			 OP_ALG_DECRYPT | OP_ALG_AAI_DK);
1841acebad3SYuan Kang 	set_jump_tgt_here(desc, uncond_jump_cmd);
1851acebad3SYuan Kang }
1861acebad3SYuan Kang 
1871acebad3SYuan Kang /*
1881acebad3SYuan Kang  * For aead functions, read payload and write payload,
1891acebad3SYuan Kang  * both of which are specified in req->src and req->dst
1901acebad3SYuan Kang  */
1911acebad3SYuan Kang static inline void aead_append_src_dst(u32 *desc, u32 msg_type)
1921acebad3SYuan Kang {
193ae4a825fSHoria Geanta 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
1941acebad3SYuan Kang 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH |
1951acebad3SYuan Kang 			     KEY_VLF | msg_type | FIFOLD_TYPE_LASTBOTH);
1961acebad3SYuan Kang }
1971acebad3SYuan Kang 
1981acebad3SYuan Kang /*
199acdca31dSYuan Kang  * For ablkcipher encrypt and decrypt, read from req->src and
200acdca31dSYuan Kang  * write to req->dst
201acdca31dSYuan Kang  */
202acdca31dSYuan Kang static inline void ablkcipher_append_src_dst(u32 *desc)
203acdca31dSYuan Kang {
20470d793ccSKim Phillips 	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
20570d793ccSKim Phillips 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
20670d793ccSKim Phillips 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 |
20770d793ccSKim Phillips 			     KEY_VLF | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
20870d793ccSKim Phillips 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
209acdca31dSYuan Kang }
210acdca31dSYuan Kang 
211acdca31dSYuan Kang /*
2128e8ec596SKim Phillips  * per-session context
2138e8ec596SKim Phillips  */
2148e8ec596SKim Phillips struct caam_ctx {
2158e8ec596SKim Phillips 	struct device *jrdev;
2161acebad3SYuan Kang 	u32 sh_desc_enc[DESC_MAX_USED_LEN];
2171acebad3SYuan Kang 	u32 sh_desc_dec[DESC_MAX_USED_LEN];
2181acebad3SYuan Kang 	u32 sh_desc_givenc[DESC_MAX_USED_LEN];
2191acebad3SYuan Kang 	dma_addr_t sh_desc_enc_dma;
2201acebad3SYuan Kang 	dma_addr_t sh_desc_dec_dma;
2211acebad3SYuan Kang 	dma_addr_t sh_desc_givenc_dma;
2228e8ec596SKim Phillips 	u32 class1_alg_type;
2238e8ec596SKim Phillips 	u32 class2_alg_type;
2248e8ec596SKim Phillips 	u32 alg_op;
2251acebad3SYuan Kang 	u8 key[CAAM_MAX_KEY_SIZE];
226885e9e2fSYuan Kang 	dma_addr_t key_dma;
2278e8ec596SKim Phillips 	unsigned int enckeylen;
2288e8ec596SKim Phillips 	unsigned int split_key_len;
2298e8ec596SKim Phillips 	unsigned int split_key_pad_len;
2308e8ec596SKim Phillips 	unsigned int authsize;
2318e8ec596SKim Phillips };
2328e8ec596SKim Phillips 
2331acebad3SYuan Kang static void append_key_aead(u32 *desc, struct caam_ctx *ctx,
234daebc465SCatalin Vasile 			    int keys_fit_inline, bool is_rfc3686)
2351acebad3SYuan Kang {
236daebc465SCatalin Vasile 	u32 *nonce;
237daebc465SCatalin Vasile 	unsigned int enckeylen = ctx->enckeylen;
238daebc465SCatalin Vasile 
239daebc465SCatalin Vasile 	/*
240daebc465SCatalin Vasile 	 * RFC3686 specific:
241daebc465SCatalin Vasile 	 *	| ctx->key = {AUTH_KEY, ENC_KEY, NONCE}
242daebc465SCatalin Vasile 	 *	| enckeylen = encryption key size + nonce size
243daebc465SCatalin Vasile 	 */
244daebc465SCatalin Vasile 	if (is_rfc3686)
245daebc465SCatalin Vasile 		enckeylen -= CTR_RFC3686_NONCE_SIZE;
246daebc465SCatalin Vasile 
2471acebad3SYuan Kang 	if (keys_fit_inline) {
2481acebad3SYuan Kang 		append_key_as_imm(desc, ctx->key, ctx->split_key_pad_len,
2491acebad3SYuan Kang 				  ctx->split_key_len, CLASS_2 |
2501acebad3SYuan Kang 				  KEY_DEST_MDHA_SPLIT | KEY_ENC);
2511acebad3SYuan Kang 		append_key_as_imm(desc, (void *)ctx->key +
252daebc465SCatalin Vasile 				  ctx->split_key_pad_len, enckeylen,
253daebc465SCatalin Vasile 				  enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
2541acebad3SYuan Kang 	} else {
2551acebad3SYuan Kang 		append_key(desc, ctx->key_dma, ctx->split_key_len, CLASS_2 |
2561acebad3SYuan Kang 			   KEY_DEST_MDHA_SPLIT | KEY_ENC);
2571acebad3SYuan Kang 		append_key(desc, ctx->key_dma + ctx->split_key_pad_len,
258daebc465SCatalin Vasile 			   enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
259daebc465SCatalin Vasile 	}
260daebc465SCatalin Vasile 
261daebc465SCatalin Vasile 	/* Load Counter into CONTEXT1 reg */
262daebc465SCatalin Vasile 	if (is_rfc3686) {
263daebc465SCatalin Vasile 		nonce = (u32 *)((void *)ctx->key + ctx->split_key_pad_len +
264daebc465SCatalin Vasile 			       enckeylen);
2655ba1c7b5SCatalin Vasile 		append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
2665ba1c7b5SCatalin Vasile 				   LDST_CLASS_IND_CCB |
267daebc465SCatalin Vasile 				   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
268daebc465SCatalin Vasile 		append_move(desc,
269daebc465SCatalin Vasile 			    MOVE_SRC_OUTFIFO |
270daebc465SCatalin Vasile 			    MOVE_DEST_CLASS1CTX |
271daebc465SCatalin Vasile 			    (16 << MOVE_OFFSET_SHIFT) |
272daebc465SCatalin Vasile 			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
2731acebad3SYuan Kang 	}
2741acebad3SYuan Kang }
2751acebad3SYuan Kang 
2761acebad3SYuan Kang static void init_sh_desc_key_aead(u32 *desc, struct caam_ctx *ctx,
277daebc465SCatalin Vasile 				  int keys_fit_inline, bool is_rfc3686)
2781acebad3SYuan Kang {
2791acebad3SYuan Kang 	u32 *key_jump_cmd;
2801acebad3SYuan Kang 
281daebc465SCatalin Vasile 	/* Note: Context registers are saved. */
282daebc465SCatalin Vasile 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
2831acebad3SYuan Kang 
2841acebad3SYuan Kang 	/* Skip if already shared */
2851acebad3SYuan Kang 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
2861acebad3SYuan Kang 				   JUMP_COND_SHRD);
2871acebad3SYuan Kang 
288daebc465SCatalin Vasile 	append_key_aead(desc, ctx, keys_fit_inline, is_rfc3686);
2891acebad3SYuan Kang 
2901acebad3SYuan Kang 	set_jump_tgt_here(desc, key_jump_cmd);
2911acebad3SYuan Kang }
2921acebad3SYuan Kang 
293ae4a825fSHoria Geanta static int aead_null_set_sh_desc(struct crypto_aead *aead)
294ae4a825fSHoria Geanta {
295ae4a825fSHoria Geanta 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
296ae4a825fSHoria Geanta 	struct device *jrdev = ctx->jrdev;
297ae4a825fSHoria Geanta 	bool keys_fit_inline = false;
298ae4a825fSHoria Geanta 	u32 *key_jump_cmd, *jump_cmd, *read_move_cmd, *write_move_cmd;
299ae4a825fSHoria Geanta 	u32 *desc;
300ae4a825fSHoria Geanta 
301ae4a825fSHoria Geanta 	/*
302ae4a825fSHoria Geanta 	 * Job Descriptor and Shared Descriptors
303ae4a825fSHoria Geanta 	 * must all fit into the 64-word Descriptor h/w Buffer
304ae4a825fSHoria Geanta 	 */
305479bcc7cSHerbert Xu 	if (DESC_AEAD_NULL_ENC_LEN + AEAD_DESC_JOB_IO_LEN +
306ae4a825fSHoria Geanta 	    ctx->split_key_pad_len <= CAAM_DESC_BYTES_MAX)
307ae4a825fSHoria Geanta 		keys_fit_inline = true;
308ae4a825fSHoria Geanta 
309479bcc7cSHerbert Xu 	/* aead_encrypt shared descriptor */
310ae4a825fSHoria Geanta 	desc = ctx->sh_desc_enc;
311ae4a825fSHoria Geanta 
312ae4a825fSHoria Geanta 	init_sh_desc(desc, HDR_SHARE_SERIAL);
313ae4a825fSHoria Geanta 
314ae4a825fSHoria Geanta 	/* Skip if already shared */
315ae4a825fSHoria Geanta 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
316ae4a825fSHoria Geanta 				   JUMP_COND_SHRD);
317ae4a825fSHoria Geanta 	if (keys_fit_inline)
318ae4a825fSHoria Geanta 		append_key_as_imm(desc, ctx->key, ctx->split_key_pad_len,
319ae4a825fSHoria Geanta 				  ctx->split_key_len, CLASS_2 |
320ae4a825fSHoria Geanta 				  KEY_DEST_MDHA_SPLIT | KEY_ENC);
321ae4a825fSHoria Geanta 	else
322ae4a825fSHoria Geanta 		append_key(desc, ctx->key_dma, ctx->split_key_len, CLASS_2 |
323ae4a825fSHoria Geanta 			   KEY_DEST_MDHA_SPLIT | KEY_ENC);
324ae4a825fSHoria Geanta 	set_jump_tgt_here(desc, key_jump_cmd);
325ae4a825fSHoria Geanta 
326479bcc7cSHerbert Xu 	/* assoclen + cryptlen = seqinlen */
327479bcc7cSHerbert Xu 	append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
328ae4a825fSHoria Geanta 
329479bcc7cSHerbert Xu 	/* Prepare to read and write cryptlen + assoclen bytes */
330ae4a825fSHoria Geanta 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
331ae4a825fSHoria Geanta 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
332ae4a825fSHoria Geanta 
333ae4a825fSHoria Geanta 	/*
334ae4a825fSHoria Geanta 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
335ae4a825fSHoria Geanta 	 * thus need to do some magic, i.e. self-patch the descriptor
336ae4a825fSHoria Geanta 	 * buffer.
337ae4a825fSHoria Geanta 	 */
338ae4a825fSHoria Geanta 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
339ae4a825fSHoria Geanta 				    MOVE_DEST_MATH3 |
340ae4a825fSHoria Geanta 				    (0x6 << MOVE_LEN_SHIFT));
341ae4a825fSHoria Geanta 	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 |
342ae4a825fSHoria Geanta 				     MOVE_DEST_DESCBUF |
343ae4a825fSHoria Geanta 				     MOVE_WAITCOMP |
344ae4a825fSHoria Geanta 				     (0x8 << MOVE_LEN_SHIFT));
345ae4a825fSHoria Geanta 
346ae4a825fSHoria Geanta 	/* Class 2 operation */
347ae4a825fSHoria Geanta 	append_operation(desc, ctx->class2_alg_type |
348ae4a825fSHoria Geanta 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
349ae4a825fSHoria Geanta 
350ae4a825fSHoria Geanta 	/* Read and write cryptlen bytes */
351ae4a825fSHoria Geanta 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
352ae4a825fSHoria Geanta 
353ae4a825fSHoria Geanta 	set_move_tgt_here(desc, read_move_cmd);
354ae4a825fSHoria Geanta 	set_move_tgt_here(desc, write_move_cmd);
355ae4a825fSHoria Geanta 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
356ae4a825fSHoria Geanta 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
357ae4a825fSHoria Geanta 		    MOVE_AUX_LS);
358ae4a825fSHoria Geanta 
359ae4a825fSHoria Geanta 	/* Write ICV */
360ae4a825fSHoria Geanta 	append_seq_store(desc, ctx->authsize, LDST_CLASS_2_CCB |
361ae4a825fSHoria Geanta 			 LDST_SRCDST_BYTE_CONTEXT);
362ae4a825fSHoria Geanta 
363ae4a825fSHoria Geanta 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
364ae4a825fSHoria Geanta 					      desc_bytes(desc),
365ae4a825fSHoria Geanta 					      DMA_TO_DEVICE);
366ae4a825fSHoria Geanta 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
367ae4a825fSHoria Geanta 		dev_err(jrdev, "unable to map shared descriptor\n");
368ae4a825fSHoria Geanta 		return -ENOMEM;
369ae4a825fSHoria Geanta 	}
370ae4a825fSHoria Geanta #ifdef DEBUG
371ae4a825fSHoria Geanta 	print_hex_dump(KERN_ERR,
372ae4a825fSHoria Geanta 		       "aead null enc shdesc@"__stringify(__LINE__)": ",
373ae4a825fSHoria Geanta 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
374ae4a825fSHoria Geanta 		       desc_bytes(desc), 1);
375ae4a825fSHoria Geanta #endif
376ae4a825fSHoria Geanta 
377ae4a825fSHoria Geanta 	/*
378ae4a825fSHoria Geanta 	 * Job Descriptor and Shared Descriptors
379ae4a825fSHoria Geanta 	 * must all fit into the 64-word Descriptor h/w Buffer
380ae4a825fSHoria Geanta 	 */
38180cd88f2SVakul Garg 	keys_fit_inline = false;
382ae4a825fSHoria Geanta 	if (DESC_AEAD_NULL_DEC_LEN + DESC_JOB_IO_LEN +
383ae4a825fSHoria Geanta 	    ctx->split_key_pad_len <= CAAM_DESC_BYTES_MAX)
384ae4a825fSHoria Geanta 		keys_fit_inline = true;
385ae4a825fSHoria Geanta 
386ae4a825fSHoria Geanta 	desc = ctx->sh_desc_dec;
387ae4a825fSHoria Geanta 
388479bcc7cSHerbert Xu 	/* aead_decrypt shared descriptor */
389ae4a825fSHoria Geanta 	init_sh_desc(desc, HDR_SHARE_SERIAL);
390ae4a825fSHoria Geanta 
391ae4a825fSHoria Geanta 	/* Skip if already shared */
392ae4a825fSHoria Geanta 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
393ae4a825fSHoria Geanta 				   JUMP_COND_SHRD);
394ae4a825fSHoria Geanta 	if (keys_fit_inline)
395ae4a825fSHoria Geanta 		append_key_as_imm(desc, ctx->key, ctx->split_key_pad_len,
396ae4a825fSHoria Geanta 				  ctx->split_key_len, CLASS_2 |
397ae4a825fSHoria Geanta 				  KEY_DEST_MDHA_SPLIT | KEY_ENC);
398ae4a825fSHoria Geanta 	else
399ae4a825fSHoria Geanta 		append_key(desc, ctx->key_dma, ctx->split_key_len, CLASS_2 |
400ae4a825fSHoria Geanta 			   KEY_DEST_MDHA_SPLIT | KEY_ENC);
401ae4a825fSHoria Geanta 	set_jump_tgt_here(desc, key_jump_cmd);
402ae4a825fSHoria Geanta 
403ae4a825fSHoria Geanta 	/* Class 2 operation */
404ae4a825fSHoria Geanta 	append_operation(desc, ctx->class2_alg_type |
405ae4a825fSHoria Geanta 			 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON);
406ae4a825fSHoria Geanta 
407479bcc7cSHerbert Xu 	/* assoclen + cryptlen = seqoutlen */
408ae4a825fSHoria Geanta 	append_math_sub(desc, REG2, SEQOUTLEN, REG0, CAAM_CMD_SZ);
409ae4a825fSHoria Geanta 
410479bcc7cSHerbert Xu 	/* Prepare to read and write cryptlen + assoclen bytes */
411ae4a825fSHoria Geanta 	append_math_add(desc, VARSEQINLEN, ZERO, REG2, CAAM_CMD_SZ);
412ae4a825fSHoria Geanta 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG2, CAAM_CMD_SZ);
413ae4a825fSHoria Geanta 
414ae4a825fSHoria Geanta 	/*
415ae4a825fSHoria Geanta 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
416ae4a825fSHoria Geanta 	 * thus need to do some magic, i.e. self-patch the descriptor
417ae4a825fSHoria Geanta 	 * buffer.
418ae4a825fSHoria Geanta 	 */
419ae4a825fSHoria Geanta 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
420ae4a825fSHoria Geanta 				    MOVE_DEST_MATH2 |
421ae4a825fSHoria Geanta 				    (0x6 << MOVE_LEN_SHIFT));
422ae4a825fSHoria Geanta 	write_move_cmd = append_move(desc, MOVE_SRC_MATH2 |
423ae4a825fSHoria Geanta 				     MOVE_DEST_DESCBUF |
424ae4a825fSHoria Geanta 				     MOVE_WAITCOMP |
425ae4a825fSHoria Geanta 				     (0x8 << MOVE_LEN_SHIFT));
426ae4a825fSHoria Geanta 
427ae4a825fSHoria Geanta 	/* Read and write cryptlen bytes */
428ae4a825fSHoria Geanta 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
429ae4a825fSHoria Geanta 
430ae4a825fSHoria Geanta 	/*
431ae4a825fSHoria Geanta 	 * Insert a NOP here, since we need at least 4 instructions between
432ae4a825fSHoria Geanta 	 * code patching the descriptor buffer and the location being patched.
433ae4a825fSHoria Geanta 	 */
434ae4a825fSHoria Geanta 	jump_cmd = append_jump(desc, JUMP_TEST_ALL);
435ae4a825fSHoria Geanta 	set_jump_tgt_here(desc, jump_cmd);
436ae4a825fSHoria Geanta 
437ae4a825fSHoria Geanta 	set_move_tgt_here(desc, read_move_cmd);
438ae4a825fSHoria Geanta 	set_move_tgt_here(desc, write_move_cmd);
439ae4a825fSHoria Geanta 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
440ae4a825fSHoria Geanta 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
441ae4a825fSHoria Geanta 		    MOVE_AUX_LS);
442ae4a825fSHoria Geanta 	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
443ae4a825fSHoria Geanta 
444ae4a825fSHoria Geanta 	/* Load ICV */
445ae4a825fSHoria Geanta 	append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS2 |
446ae4a825fSHoria Geanta 			     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
447ae4a825fSHoria Geanta 
448ae4a825fSHoria Geanta 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
449ae4a825fSHoria Geanta 					      desc_bytes(desc),
450ae4a825fSHoria Geanta 					      DMA_TO_DEVICE);
451ae4a825fSHoria Geanta 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
452ae4a825fSHoria Geanta 		dev_err(jrdev, "unable to map shared descriptor\n");
453ae4a825fSHoria Geanta 		return -ENOMEM;
454ae4a825fSHoria Geanta 	}
455ae4a825fSHoria Geanta #ifdef DEBUG
456ae4a825fSHoria Geanta 	print_hex_dump(KERN_ERR,
457ae4a825fSHoria Geanta 		       "aead null dec shdesc@"__stringify(__LINE__)": ",
458ae4a825fSHoria Geanta 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
459ae4a825fSHoria Geanta 		       desc_bytes(desc), 1);
460ae4a825fSHoria Geanta #endif
461ae4a825fSHoria Geanta 
462ae4a825fSHoria Geanta 	return 0;
463ae4a825fSHoria Geanta }
464ae4a825fSHoria Geanta 
4651acebad3SYuan Kang static int aead_set_sh_desc(struct crypto_aead *aead)
4661acebad3SYuan Kang {
467479bcc7cSHerbert Xu 	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
468479bcc7cSHerbert Xu 						 struct caam_aead_alg, aead);
469add86d55SHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
4701acebad3SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
4711acebad3SYuan Kang 	struct device *jrdev = ctx->jrdev;
472daebc465SCatalin Vasile 	bool keys_fit_inline;
4731acebad3SYuan Kang 	u32 geniv, moveiv;
474daebc465SCatalin Vasile 	u32 ctx1_iv_off = 0;
4751acebad3SYuan Kang 	u32 *desc;
476daebc465SCatalin Vasile 	const bool ctr_mode = ((ctx->class1_alg_type & OP_ALG_AAI_MASK) ==
477daebc465SCatalin Vasile 			       OP_ALG_AAI_CTR_MOD128);
478479bcc7cSHerbert Xu 	const bool is_rfc3686 = alg->caam.rfc3686;
4791acebad3SYuan Kang 
4802fdea258SHoria Geantă 	if (!ctx->authsize)
4812fdea258SHoria Geantă 		return 0;
4822fdea258SHoria Geantă 
483ae4a825fSHoria Geanta 	/* NULL encryption / decryption */
484ae4a825fSHoria Geanta 	if (!ctx->enckeylen)
485ae4a825fSHoria Geanta 		return aead_null_set_sh_desc(aead);
486ae4a825fSHoria Geanta 
4871acebad3SYuan Kang 	/*
488daebc465SCatalin Vasile 	 * AES-CTR needs to load IV in CONTEXT1 reg
489daebc465SCatalin Vasile 	 * at an offset of 128bits (16bytes)
490daebc465SCatalin Vasile 	 * CONTEXT1[255:128] = IV
491daebc465SCatalin Vasile 	 */
492daebc465SCatalin Vasile 	if (ctr_mode)
493daebc465SCatalin Vasile 		ctx1_iv_off = 16;
494daebc465SCatalin Vasile 
495daebc465SCatalin Vasile 	/*
496daebc465SCatalin Vasile 	 * RFC3686 specific:
497daebc465SCatalin Vasile 	 *	CONTEXT1[255:128] = {NONCE, IV, COUNTER}
498daebc465SCatalin Vasile 	 */
499daebc465SCatalin Vasile 	if (is_rfc3686)
500daebc465SCatalin Vasile 		ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
501daebc465SCatalin Vasile 
502479bcc7cSHerbert Xu 	if (alg->caam.geniv)
503479bcc7cSHerbert Xu 		goto skip_enc;
504479bcc7cSHerbert Xu 
505daebc465SCatalin Vasile 	/*
5061acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
5071acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
5081acebad3SYuan Kang 	 */
509daebc465SCatalin Vasile 	keys_fit_inline = false;
510479bcc7cSHerbert Xu 	if (DESC_AEAD_ENC_LEN + AUTHENC_DESC_JOB_IO_LEN +
511daebc465SCatalin Vasile 	    ctx->split_key_pad_len + ctx->enckeylen +
512daebc465SCatalin Vasile 	    (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0) <=
5131acebad3SYuan Kang 	    CAAM_DESC_BYTES_MAX)
5142af8f4a2SKim Phillips 		keys_fit_inline = true;
5151acebad3SYuan Kang 
516479bcc7cSHerbert Xu 	/* aead_encrypt shared descriptor */
5171acebad3SYuan Kang 	desc = ctx->sh_desc_enc;
5181acebad3SYuan Kang 
519daebc465SCatalin Vasile 	/* Note: Context registers are saved. */
520daebc465SCatalin Vasile 	init_sh_desc_key_aead(desc, ctx, keys_fit_inline, is_rfc3686);
5211acebad3SYuan Kang 
5221acebad3SYuan Kang 	/* Class 2 operation */
5231acebad3SYuan Kang 	append_operation(desc, ctx->class2_alg_type |
5241acebad3SYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
5251acebad3SYuan Kang 
526479bcc7cSHerbert Xu 	/* Read and write assoclen bytes */
527479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
528479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
5291acebad3SYuan Kang 
530479bcc7cSHerbert Xu 	/* Skip assoc data */
531479bcc7cSHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
5321acebad3SYuan Kang 
5331acebad3SYuan Kang 	/* read assoc before reading payload */
5341acebad3SYuan Kang 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
535479bcc7cSHerbert Xu 				      FIFOLDST_VLF);
536daebc465SCatalin Vasile 
537daebc465SCatalin Vasile 	/* Load Counter into CONTEXT1 reg */
538daebc465SCatalin Vasile 	if (is_rfc3686)
5395ba1c7b5SCatalin Vasile 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
540daebc465SCatalin Vasile 				     LDST_SRCDST_BYTE_CONTEXT |
541daebc465SCatalin Vasile 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
542daebc465SCatalin Vasile 				      LDST_OFFSET_SHIFT));
5431acebad3SYuan Kang 
5441acebad3SYuan Kang 	/* Class 1 operation */
5451acebad3SYuan Kang 	append_operation(desc, ctx->class1_alg_type |
5461acebad3SYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
5471acebad3SYuan Kang 
5481acebad3SYuan Kang 	/* Read and write cryptlen bytes */
549479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
550479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
5511acebad3SYuan Kang 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
5521acebad3SYuan Kang 
5531acebad3SYuan Kang 	/* Write ICV */
5541acebad3SYuan Kang 	append_seq_store(desc, ctx->authsize, LDST_CLASS_2_CCB |
5551acebad3SYuan Kang 			 LDST_SRCDST_BYTE_CONTEXT);
5561acebad3SYuan Kang 
5571acebad3SYuan Kang 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
5581acebad3SYuan Kang 					      desc_bytes(desc),
5591acebad3SYuan Kang 					      DMA_TO_DEVICE);
5601acebad3SYuan Kang 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
5611acebad3SYuan Kang 		dev_err(jrdev, "unable to map shared descriptor\n");
5621acebad3SYuan Kang 		return -ENOMEM;
5631acebad3SYuan Kang 	}
5641acebad3SYuan Kang #ifdef DEBUG
565514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead enc shdesc@"__stringify(__LINE__)": ",
5661acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
5671acebad3SYuan Kang 		       desc_bytes(desc), 1);
5681acebad3SYuan Kang #endif
5691acebad3SYuan Kang 
570479bcc7cSHerbert Xu skip_enc:
5711acebad3SYuan Kang 	/*
5721acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
5731acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
5741acebad3SYuan Kang 	 */
57580cd88f2SVakul Garg 	keys_fit_inline = false;
576479bcc7cSHerbert Xu 	if (DESC_AEAD_DEC_LEN + AUTHENC_DESC_JOB_IO_LEN +
577daebc465SCatalin Vasile 	    ctx->split_key_pad_len + ctx->enckeylen +
578daebc465SCatalin Vasile 	    (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0) <=
5791acebad3SYuan Kang 	    CAAM_DESC_BYTES_MAX)
5802af8f4a2SKim Phillips 		keys_fit_inline = true;
5811acebad3SYuan Kang 
582479bcc7cSHerbert Xu 	/* aead_decrypt shared descriptor */
5831acebad3SYuan Kang 	desc = ctx->sh_desc_dec;
5841acebad3SYuan Kang 
585daebc465SCatalin Vasile 	/* Note: Context registers are saved. */
586daebc465SCatalin Vasile 	init_sh_desc_key_aead(desc, ctx, keys_fit_inline, is_rfc3686);
5871acebad3SYuan Kang 
5881acebad3SYuan Kang 	/* Class 2 operation */
5891acebad3SYuan Kang 	append_operation(desc, ctx->class2_alg_type |
5901acebad3SYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON);
5911acebad3SYuan Kang 
592479bcc7cSHerbert Xu 	/* Read and write assoclen bytes */
593479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
5948b18e235SHoria Geantă 	if (alg->caam.geniv)
5958b18e235SHoria Geantă 		append_math_add_imm_u32(desc, VARSEQOUTLEN, REG3, IMM, ivsize);
5968b18e235SHoria Geantă 	else
597479bcc7cSHerbert Xu 		append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
598479bcc7cSHerbert Xu 
599479bcc7cSHerbert Xu 	/* Skip assoc data */
600479bcc7cSHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
6011acebad3SYuan Kang 
6021acebad3SYuan Kang 	/* read assoc before reading payload */
6031acebad3SYuan Kang 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
6041acebad3SYuan Kang 			     KEY_VLF);
6051acebad3SYuan Kang 
6068b18e235SHoria Geantă 	if (alg->caam.geniv) {
6078b18e235SHoria Geantă 		append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
6088b18e235SHoria Geantă 				LDST_SRCDST_BYTE_CONTEXT |
6098b18e235SHoria Geantă 				(ctx1_iv_off << LDST_OFFSET_SHIFT));
6108b18e235SHoria Geantă 		append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO |
6118b18e235SHoria Geantă 			    (ctx1_iv_off << MOVE_OFFSET_SHIFT) | ivsize);
6128b18e235SHoria Geantă 	}
6138b18e235SHoria Geantă 
614daebc465SCatalin Vasile 	/* Load Counter into CONTEXT1 reg */
615daebc465SCatalin Vasile 	if (is_rfc3686)
6165ba1c7b5SCatalin Vasile 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
617daebc465SCatalin Vasile 				     LDST_SRCDST_BYTE_CONTEXT |
618daebc465SCatalin Vasile 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
619daebc465SCatalin Vasile 				      LDST_OFFSET_SHIFT));
620daebc465SCatalin Vasile 
621daebc465SCatalin Vasile 	/* Choose operation */
622daebc465SCatalin Vasile 	if (ctr_mode)
623daebc465SCatalin Vasile 		append_operation(desc, ctx->class1_alg_type |
624daebc465SCatalin Vasile 				 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT);
625daebc465SCatalin Vasile 	else
6261acebad3SYuan Kang 		append_dec_op1(desc, ctx->class1_alg_type);
6271acebad3SYuan Kang 
6281acebad3SYuan Kang 	/* Read and write cryptlen bytes */
629479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
630479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
6311acebad3SYuan Kang 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
6321acebad3SYuan Kang 
6331acebad3SYuan Kang 	/* Load ICV */
6341acebad3SYuan Kang 	append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS2 |
6351acebad3SYuan Kang 			     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
6361acebad3SYuan Kang 
6371acebad3SYuan Kang 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
6381acebad3SYuan Kang 					      desc_bytes(desc),
6391acebad3SYuan Kang 					      DMA_TO_DEVICE);
6401acebad3SYuan Kang 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
6411acebad3SYuan Kang 		dev_err(jrdev, "unable to map shared descriptor\n");
6421acebad3SYuan Kang 		return -ENOMEM;
6431acebad3SYuan Kang 	}
6441acebad3SYuan Kang #ifdef DEBUG
645514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead dec shdesc@"__stringify(__LINE__)": ",
6461acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
6471acebad3SYuan Kang 		       desc_bytes(desc), 1);
6481acebad3SYuan Kang #endif
6491acebad3SYuan Kang 
650479bcc7cSHerbert Xu 	if (!alg->caam.geniv)
651479bcc7cSHerbert Xu 		goto skip_givenc;
652479bcc7cSHerbert Xu 
6531acebad3SYuan Kang 	/*
6541acebad3SYuan Kang 	 * Job Descriptor and Shared Descriptors
6551acebad3SYuan Kang 	 * must all fit into the 64-word Descriptor h/w Buffer
6561acebad3SYuan Kang 	 */
65780cd88f2SVakul Garg 	keys_fit_inline = false;
658479bcc7cSHerbert Xu 	if (DESC_AEAD_GIVENC_LEN + AUTHENC_DESC_JOB_IO_LEN +
659daebc465SCatalin Vasile 	    ctx->split_key_pad_len + ctx->enckeylen +
660daebc465SCatalin Vasile 	    (is_rfc3686 ? DESC_AEAD_CTR_RFC3686_LEN : 0) <=
6611acebad3SYuan Kang 	    CAAM_DESC_BYTES_MAX)
6622af8f4a2SKim Phillips 		keys_fit_inline = true;
6631acebad3SYuan Kang 
6641acebad3SYuan Kang 	/* aead_givencrypt shared descriptor */
6651d2d87e8SHoria Geantă 	desc = ctx->sh_desc_enc;
6661acebad3SYuan Kang 
667daebc465SCatalin Vasile 	/* Note: Context registers are saved. */
668daebc465SCatalin Vasile 	init_sh_desc_key_aead(desc, ctx, keys_fit_inline, is_rfc3686);
6691acebad3SYuan Kang 
670479bcc7cSHerbert Xu 	if (is_rfc3686)
671479bcc7cSHerbert Xu 		goto copy_iv;
672479bcc7cSHerbert Xu 
6731acebad3SYuan Kang 	/* Generate IV */
6741acebad3SYuan Kang 	geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
6751acebad3SYuan Kang 		NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 |
676add86d55SHerbert Xu 		NFIFOENTRY_PTYPE_RND | (ivsize << NFIFOENTRY_DLEN_SHIFT);
6771acebad3SYuan Kang 	append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
6781acebad3SYuan Kang 			    LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
6791acebad3SYuan Kang 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
680daebc465SCatalin Vasile 	append_move(desc, MOVE_WAITCOMP |
681daebc465SCatalin Vasile 		    MOVE_SRC_INFIFO | MOVE_DEST_CLASS1CTX |
682daebc465SCatalin Vasile 		    (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
683add86d55SHerbert Xu 		    (ivsize << MOVE_LEN_SHIFT));
6841acebad3SYuan Kang 	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
6851acebad3SYuan Kang 
686479bcc7cSHerbert Xu copy_iv:
6871acebad3SYuan Kang 	/* Copy IV to class 1 context */
688daebc465SCatalin Vasile 	append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_OUTFIFO |
689daebc465SCatalin Vasile 		    (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
690add86d55SHerbert Xu 		    (ivsize << MOVE_LEN_SHIFT));
6911acebad3SYuan Kang 
6921acebad3SYuan Kang 	/* Return to encryption */
6931acebad3SYuan Kang 	append_operation(desc, ctx->class2_alg_type |
6941acebad3SYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
6951acebad3SYuan Kang 
696479bcc7cSHerbert Xu 	/* Read and write assoclen bytes */
697479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
698479bcc7cSHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
699479bcc7cSHerbert Xu 
7001d2d87e8SHoria Geantă 	/* ivsize + cryptlen = seqoutlen - authsize */
7011d2d87e8SHoria Geantă 	append_math_sub_imm_u32(desc, REG3, SEQOUTLEN, IMM, ctx->authsize);
7021d2d87e8SHoria Geantă 
703479bcc7cSHerbert Xu 	/* Skip assoc data */
704479bcc7cSHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
7051acebad3SYuan Kang 
7061acebad3SYuan Kang 	/* read assoc before reading payload */
7071acebad3SYuan Kang 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
7081acebad3SYuan Kang 			     KEY_VLF);
7091acebad3SYuan Kang 
710daebc465SCatalin Vasile 	/* Copy iv from outfifo to class 2 fifo */
7111acebad3SYuan Kang 	moveiv = NFIFOENTRY_STYPE_OFIFO | NFIFOENTRY_DEST_CLASS2 |
712add86d55SHerbert Xu 		 NFIFOENTRY_DTYPE_MSG | (ivsize << NFIFOENTRY_DLEN_SHIFT);
7131acebad3SYuan Kang 	append_load_imm_u32(desc, moveiv, LDST_CLASS_IND_CCB |
7141acebad3SYuan Kang 			    LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
715add86d55SHerbert Xu 	append_load_imm_u32(desc, ivsize, LDST_CLASS_2_CCB |
7161acebad3SYuan Kang 			    LDST_SRCDST_WORD_DATASZ_REG | LDST_IMM);
7171acebad3SYuan Kang 
718daebc465SCatalin Vasile 	/* Load Counter into CONTEXT1 reg */
719daebc465SCatalin Vasile 	if (is_rfc3686)
7205ba1c7b5SCatalin Vasile 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
721daebc465SCatalin Vasile 				     LDST_SRCDST_BYTE_CONTEXT |
722daebc465SCatalin Vasile 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
723daebc465SCatalin Vasile 				      LDST_OFFSET_SHIFT));
724daebc465SCatalin Vasile 
7251acebad3SYuan Kang 	/* Class 1 operation */
7261acebad3SYuan Kang 	append_operation(desc, ctx->class1_alg_type |
7271acebad3SYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
7281acebad3SYuan Kang 
7291acebad3SYuan Kang 	/* Will write ivsize + cryptlen */
7301acebad3SYuan Kang 	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
7311acebad3SYuan Kang 
7321acebad3SYuan Kang 	/* Not need to reload iv */
733add86d55SHerbert Xu 	append_seq_fifo_load(desc, ivsize,
7341acebad3SYuan Kang 			     FIFOLD_CLASS_SKIP);
7351acebad3SYuan Kang 
7361acebad3SYuan Kang 	/* Will read cryptlen */
7371acebad3SYuan Kang 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
738d128af17SAlex Porosanu 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | KEY_VLF |
739d128af17SAlex Porosanu 			     FIFOLD_TYPE_MSG1OUT2 | FIFOLD_TYPE_LASTBOTH);
740d128af17SAlex Porosanu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
7411acebad3SYuan Kang 
7421acebad3SYuan Kang 	/* Write ICV */
7431acebad3SYuan Kang 	append_seq_store(desc, ctx->authsize, LDST_CLASS_2_CCB |
7441acebad3SYuan Kang 			 LDST_SRCDST_BYTE_CONTEXT);
7451acebad3SYuan Kang 
746479bcc7cSHerbert Xu 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
7471acebad3SYuan Kang 					      desc_bytes(desc),
7481acebad3SYuan Kang 					      DMA_TO_DEVICE);
7491d2d87e8SHoria Geantă 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
7501acebad3SYuan Kang 		dev_err(jrdev, "unable to map shared descriptor\n");
7511acebad3SYuan Kang 		return -ENOMEM;
7521acebad3SYuan Kang 	}
7531acebad3SYuan Kang #ifdef DEBUG
754514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead givenc shdesc@"__stringify(__LINE__)": ",
7551acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
7561acebad3SYuan Kang 		       desc_bytes(desc), 1);
7571acebad3SYuan Kang #endif
7581acebad3SYuan Kang 
759479bcc7cSHerbert Xu skip_givenc:
7601acebad3SYuan Kang 	return 0;
7611acebad3SYuan Kang }
7621acebad3SYuan Kang 
7630e479300SYuan Kang static int aead_setauthsize(struct crypto_aead *authenc,
7648e8ec596SKim Phillips 				    unsigned int authsize)
7658e8ec596SKim Phillips {
7668e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
7678e8ec596SKim Phillips 
7688e8ec596SKim Phillips 	ctx->authsize = authsize;
7691acebad3SYuan Kang 	aead_set_sh_desc(authenc);
7708e8ec596SKim Phillips 
7718e8ec596SKim Phillips 	return 0;
7728e8ec596SKim Phillips }
7738e8ec596SKim Phillips 
7743ef8d945STudor Ambarus static int gcm_set_sh_desc(struct crypto_aead *aead)
7753ef8d945STudor Ambarus {
7763ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
7773ef8d945STudor Ambarus 	struct device *jrdev = ctx->jrdev;
7783ef8d945STudor Ambarus 	bool keys_fit_inline = false;
7793ef8d945STudor Ambarus 	u32 *key_jump_cmd, *zero_payload_jump_cmd,
7803ef8d945STudor Ambarus 	    *zero_assoc_jump_cmd1, *zero_assoc_jump_cmd2;
7813ef8d945STudor Ambarus 	u32 *desc;
7823ef8d945STudor Ambarus 
7833ef8d945STudor Ambarus 	if (!ctx->enckeylen || !ctx->authsize)
7843ef8d945STudor Ambarus 		return 0;
7853ef8d945STudor Ambarus 
7863ef8d945STudor Ambarus 	/*
7873ef8d945STudor Ambarus 	 * AES GCM encrypt shared descriptor
7883ef8d945STudor Ambarus 	 * Job Descriptor and Shared Descriptor
7893ef8d945STudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
7903ef8d945STudor Ambarus 	 */
791f2147b88SHerbert Xu 	if (DESC_GCM_ENC_LEN + GCM_DESC_JOB_IO_LEN +
7923ef8d945STudor Ambarus 	    ctx->enckeylen <= CAAM_DESC_BYTES_MAX)
7933ef8d945STudor Ambarus 		keys_fit_inline = true;
7943ef8d945STudor Ambarus 
7953ef8d945STudor Ambarus 	desc = ctx->sh_desc_enc;
7963ef8d945STudor Ambarus 
7973ef8d945STudor Ambarus 	init_sh_desc(desc, HDR_SHARE_SERIAL);
7983ef8d945STudor Ambarus 
7993ef8d945STudor Ambarus 	/* skip key loading if they are loaded due to sharing */
8003ef8d945STudor Ambarus 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
8013ef8d945STudor Ambarus 				   JUMP_COND_SHRD | JUMP_COND_SELF);
8023ef8d945STudor Ambarus 	if (keys_fit_inline)
8033ef8d945STudor Ambarus 		append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
8043ef8d945STudor Ambarus 				  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
8053ef8d945STudor Ambarus 	else
8063ef8d945STudor Ambarus 		append_key(desc, ctx->key_dma, ctx->enckeylen,
8073ef8d945STudor Ambarus 			   CLASS_1 | KEY_DEST_CLASS_REG);
8083ef8d945STudor Ambarus 	set_jump_tgt_here(desc, key_jump_cmd);
8093ef8d945STudor Ambarus 
8103ef8d945STudor Ambarus 	/* class 1 operation */
8113ef8d945STudor Ambarus 	append_operation(desc, ctx->class1_alg_type |
8123ef8d945STudor Ambarus 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
8133ef8d945STudor Ambarus 
814f2147b88SHerbert Xu 	/* if assoclen + cryptlen is ZERO, skip to ICV write */
815f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
816f2147b88SHerbert Xu 	zero_assoc_jump_cmd2 = append_jump(desc, JUMP_TEST_ALL |
8173ef8d945STudor Ambarus 						 JUMP_COND_MATH_Z);
8183ef8d945STudor Ambarus 
8193ef8d945STudor Ambarus 	/* if assoclen is ZERO, skip reading the assoc data */
820f2147b88SHerbert Xu 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
8213ef8d945STudor Ambarus 	zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
8223ef8d945STudor Ambarus 						 JUMP_COND_MATH_Z);
8233ef8d945STudor Ambarus 
824f2147b88SHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
825f2147b88SHerbert Xu 
826f2147b88SHerbert Xu 	/* skip assoc data */
827f2147b88SHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
828f2147b88SHerbert Xu 
829f2147b88SHerbert Xu 	/* cryptlen = seqinlen - assoclen */
830f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
831f2147b88SHerbert Xu 
832f2147b88SHerbert Xu 	/* if cryptlen is ZERO jump to zero-payload commands */
833f2147b88SHerbert Xu 	zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
834f2147b88SHerbert Xu 					    JUMP_COND_MATH_Z);
835f2147b88SHerbert Xu 
8363ef8d945STudor Ambarus 	/* read assoc data */
8373ef8d945STudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
8383ef8d945STudor Ambarus 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
8393ef8d945STudor Ambarus 	set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
8403ef8d945STudor Ambarus 
841f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
8423ef8d945STudor Ambarus 
8433ef8d945STudor Ambarus 	/* write encrypted data */
8443ef8d945STudor Ambarus 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
8453ef8d945STudor Ambarus 
8463ef8d945STudor Ambarus 	/* read payload data */
8473ef8d945STudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
8483ef8d945STudor Ambarus 			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
8493ef8d945STudor Ambarus 
8503ef8d945STudor Ambarus 	/* jump the zero-payload commands */
851f2147b88SHerbert Xu 	append_jump(desc, JUMP_TEST_ALL | 2);
8523ef8d945STudor Ambarus 
8533ef8d945STudor Ambarus 	/* zero-payload commands */
8543ef8d945STudor Ambarus 	set_jump_tgt_here(desc, zero_payload_jump_cmd);
8553ef8d945STudor Ambarus 
8563ef8d945STudor Ambarus 	/* read assoc data */
8573ef8d945STudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
8583ef8d945STudor Ambarus 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
8593ef8d945STudor Ambarus 
860f2147b88SHerbert Xu 	/* There is no input data */
8613ef8d945STudor Ambarus 	set_jump_tgt_here(desc, zero_assoc_jump_cmd2);
8623ef8d945STudor Ambarus 
8633ef8d945STudor Ambarus 	/* write ICV */
8643ef8d945STudor Ambarus 	append_seq_store(desc, ctx->authsize, LDST_CLASS_1_CCB |
8653ef8d945STudor Ambarus 			 LDST_SRCDST_BYTE_CONTEXT);
8663ef8d945STudor Ambarus 
8673ef8d945STudor Ambarus 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
8683ef8d945STudor Ambarus 					      desc_bytes(desc),
8693ef8d945STudor Ambarus 					      DMA_TO_DEVICE);
8703ef8d945STudor Ambarus 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
8713ef8d945STudor Ambarus 		dev_err(jrdev, "unable to map shared descriptor\n");
8723ef8d945STudor Ambarus 		return -ENOMEM;
8733ef8d945STudor Ambarus 	}
8743ef8d945STudor Ambarus #ifdef DEBUG
8753ef8d945STudor Ambarus 	print_hex_dump(KERN_ERR, "gcm enc shdesc@"__stringify(__LINE__)": ",
8763ef8d945STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
8773ef8d945STudor Ambarus 		       desc_bytes(desc), 1);
8783ef8d945STudor Ambarus #endif
8793ef8d945STudor Ambarus 
8803ef8d945STudor Ambarus 	/*
8813ef8d945STudor Ambarus 	 * Job Descriptor and Shared Descriptors
8823ef8d945STudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
8833ef8d945STudor Ambarus 	 */
8843ef8d945STudor Ambarus 	keys_fit_inline = false;
885f2147b88SHerbert Xu 	if (DESC_GCM_DEC_LEN + GCM_DESC_JOB_IO_LEN +
8863ef8d945STudor Ambarus 	    ctx->enckeylen <= CAAM_DESC_BYTES_MAX)
8873ef8d945STudor Ambarus 		keys_fit_inline = true;
8883ef8d945STudor Ambarus 
8893ef8d945STudor Ambarus 	desc = ctx->sh_desc_dec;
8903ef8d945STudor Ambarus 
8913ef8d945STudor Ambarus 	init_sh_desc(desc, HDR_SHARE_SERIAL);
8923ef8d945STudor Ambarus 
8933ef8d945STudor Ambarus 	/* skip key loading if they are loaded due to sharing */
8943ef8d945STudor Ambarus 	key_jump_cmd = append_jump(desc, JUMP_JSL |
8953ef8d945STudor Ambarus 				   JUMP_TEST_ALL | JUMP_COND_SHRD |
8963ef8d945STudor Ambarus 				   JUMP_COND_SELF);
8973ef8d945STudor Ambarus 	if (keys_fit_inline)
8983ef8d945STudor Ambarus 		append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
8993ef8d945STudor Ambarus 				  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
9003ef8d945STudor Ambarus 	else
9013ef8d945STudor Ambarus 		append_key(desc, ctx->key_dma, ctx->enckeylen,
9023ef8d945STudor Ambarus 			   CLASS_1 | KEY_DEST_CLASS_REG);
9033ef8d945STudor Ambarus 	set_jump_tgt_here(desc, key_jump_cmd);
9043ef8d945STudor Ambarus 
9053ef8d945STudor Ambarus 	/* class 1 operation */
9063ef8d945STudor Ambarus 	append_operation(desc, ctx->class1_alg_type |
9073ef8d945STudor Ambarus 			 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON);
9083ef8d945STudor Ambarus 
909f2147b88SHerbert Xu 	/* if assoclen is ZERO, skip reading the assoc data */
910f2147b88SHerbert Xu 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
9113ef8d945STudor Ambarus 	zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
9123ef8d945STudor Ambarus 						 JUMP_COND_MATH_Z);
913f2147b88SHerbert Xu 
914f2147b88SHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
915f2147b88SHerbert Xu 
916f2147b88SHerbert Xu 	/* skip assoc data */
917f2147b88SHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
918f2147b88SHerbert Xu 
9193ef8d945STudor Ambarus 	/* read assoc data */
9203ef8d945STudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
9213ef8d945STudor Ambarus 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
922f2147b88SHerbert Xu 
9233ef8d945STudor Ambarus 	set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
9243ef8d945STudor Ambarus 
925f2147b88SHerbert Xu 	/* cryptlen = seqoutlen - assoclen */
926f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
927f2147b88SHerbert Xu 
928f2147b88SHerbert Xu 	/* jump to zero-payload command if cryptlen is zero */
929f2147b88SHerbert Xu 	zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
930f2147b88SHerbert Xu 					    JUMP_COND_MATH_Z);
931f2147b88SHerbert Xu 
932f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
9333ef8d945STudor Ambarus 
9343ef8d945STudor Ambarus 	/* store encrypted data */
9353ef8d945STudor Ambarus 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
9363ef8d945STudor Ambarus 
9373ef8d945STudor Ambarus 	/* read payload data */
9383ef8d945STudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
9393ef8d945STudor Ambarus 			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
9403ef8d945STudor Ambarus 
9413ef8d945STudor Ambarus 	/* zero-payload command */
9423ef8d945STudor Ambarus 	set_jump_tgt_here(desc, zero_payload_jump_cmd);
9433ef8d945STudor Ambarus 
9443ef8d945STudor Ambarus 	/* read ICV */
9453ef8d945STudor Ambarus 	append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS1 |
9463ef8d945STudor Ambarus 			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
9473ef8d945STudor Ambarus 
9483ef8d945STudor Ambarus 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
9493ef8d945STudor Ambarus 					      desc_bytes(desc),
9503ef8d945STudor Ambarus 					      DMA_TO_DEVICE);
9513ef8d945STudor Ambarus 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
9523ef8d945STudor Ambarus 		dev_err(jrdev, "unable to map shared descriptor\n");
9533ef8d945STudor Ambarus 		return -ENOMEM;
9543ef8d945STudor Ambarus 	}
9553ef8d945STudor Ambarus #ifdef DEBUG
9563ef8d945STudor Ambarus 	print_hex_dump(KERN_ERR, "gcm dec shdesc@"__stringify(__LINE__)": ",
9573ef8d945STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
9583ef8d945STudor Ambarus 		       desc_bytes(desc), 1);
9593ef8d945STudor Ambarus #endif
9603ef8d945STudor Ambarus 
9613ef8d945STudor Ambarus 	return 0;
9623ef8d945STudor Ambarus }
9633ef8d945STudor Ambarus 
9643ef8d945STudor Ambarus static int gcm_setauthsize(struct crypto_aead *authenc, unsigned int authsize)
9653ef8d945STudor Ambarus {
9663ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
9673ef8d945STudor Ambarus 
9683ef8d945STudor Ambarus 	ctx->authsize = authsize;
9693ef8d945STudor Ambarus 	gcm_set_sh_desc(authenc);
9703ef8d945STudor Ambarus 
9713ef8d945STudor Ambarus 	return 0;
9723ef8d945STudor Ambarus }
9733ef8d945STudor Ambarus 
974bac68f2cSTudor Ambarus static int rfc4106_set_sh_desc(struct crypto_aead *aead)
975bac68f2cSTudor Ambarus {
976bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
977bac68f2cSTudor Ambarus 	struct device *jrdev = ctx->jrdev;
978bac68f2cSTudor Ambarus 	bool keys_fit_inline = false;
979f2147b88SHerbert Xu 	u32 *key_jump_cmd;
980bac68f2cSTudor Ambarus 	u32 *desc;
981bac68f2cSTudor Ambarus 
982bac68f2cSTudor Ambarus 	if (!ctx->enckeylen || !ctx->authsize)
983bac68f2cSTudor Ambarus 		return 0;
984bac68f2cSTudor Ambarus 
985bac68f2cSTudor Ambarus 	/*
986bac68f2cSTudor Ambarus 	 * RFC4106 encrypt shared descriptor
987bac68f2cSTudor Ambarus 	 * Job Descriptor and Shared Descriptor
988bac68f2cSTudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
989bac68f2cSTudor Ambarus 	 */
990f2147b88SHerbert Xu 	if (DESC_RFC4106_ENC_LEN + GCM_DESC_JOB_IO_LEN +
991bac68f2cSTudor Ambarus 	    ctx->enckeylen <= CAAM_DESC_BYTES_MAX)
992bac68f2cSTudor Ambarus 		keys_fit_inline = true;
993bac68f2cSTudor Ambarus 
994bac68f2cSTudor Ambarus 	desc = ctx->sh_desc_enc;
995bac68f2cSTudor Ambarus 
996bac68f2cSTudor Ambarus 	init_sh_desc(desc, HDR_SHARE_SERIAL);
997bac68f2cSTudor Ambarus 
998bac68f2cSTudor Ambarus 	/* Skip key loading if it is loaded due to sharing */
999bac68f2cSTudor Ambarus 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1000bac68f2cSTudor Ambarus 				   JUMP_COND_SHRD);
1001bac68f2cSTudor Ambarus 	if (keys_fit_inline)
1002bac68f2cSTudor Ambarus 		append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
1003bac68f2cSTudor Ambarus 				  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
1004bac68f2cSTudor Ambarus 	else
1005bac68f2cSTudor Ambarus 		append_key(desc, ctx->key_dma, ctx->enckeylen,
1006bac68f2cSTudor Ambarus 			   CLASS_1 | KEY_DEST_CLASS_REG);
1007bac68f2cSTudor Ambarus 	set_jump_tgt_here(desc, key_jump_cmd);
1008bac68f2cSTudor Ambarus 
1009bac68f2cSTudor Ambarus 	/* Class 1 operation */
1010bac68f2cSTudor Ambarus 	append_operation(desc, ctx->class1_alg_type |
1011bac68f2cSTudor Ambarus 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
1012bac68f2cSTudor Ambarus 
101346218750SHerbert Xu 	append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, 8);
1014bac68f2cSTudor Ambarus 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
1015bac68f2cSTudor Ambarus 
1016bac68f2cSTudor Ambarus 	/* Read assoc data */
1017bac68f2cSTudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
1018bac68f2cSTudor Ambarus 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
1019bac68f2cSTudor Ambarus 
102046218750SHerbert Xu 	/* Skip IV */
102146218750SHerbert Xu 	append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
1022f2147b88SHerbert Xu 
1023bac68f2cSTudor Ambarus 	/* Will read cryptlen bytes */
1024f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1025bac68f2cSTudor Ambarus 
10264aad0cc5SHoria Geant? 	/* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
10274aad0cc5SHoria Geant? 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG);
1028bac68f2cSTudor Ambarus 
102946218750SHerbert Xu 	/* Skip assoc data */
103046218750SHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
103146218750SHerbert Xu 
103246218750SHerbert Xu 	/* cryptlen = seqoutlen - assoclen */
10334aad0cc5SHoria Geant? 	append_math_sub(desc, VARSEQOUTLEN, VARSEQINLEN, REG0, CAAM_CMD_SZ);
103446218750SHerbert Xu 
103546218750SHerbert Xu 	/* Write encrypted data */
103646218750SHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
103746218750SHerbert Xu 
10384aad0cc5SHoria Geant? 	/* Read payload data */
10394aad0cc5SHoria Geant? 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
10404aad0cc5SHoria Geant? 			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
10414aad0cc5SHoria Geant? 
1042bac68f2cSTudor Ambarus 	/* Write ICV */
1043bac68f2cSTudor Ambarus 	append_seq_store(desc, ctx->authsize, LDST_CLASS_1_CCB |
1044bac68f2cSTudor Ambarus 			 LDST_SRCDST_BYTE_CONTEXT);
1045bac68f2cSTudor Ambarus 
1046bac68f2cSTudor Ambarus 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
1047bac68f2cSTudor Ambarus 					      desc_bytes(desc),
1048bac68f2cSTudor Ambarus 					      DMA_TO_DEVICE);
1049bac68f2cSTudor Ambarus 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
1050bac68f2cSTudor Ambarus 		dev_err(jrdev, "unable to map shared descriptor\n");
1051bac68f2cSTudor Ambarus 		return -ENOMEM;
1052bac68f2cSTudor Ambarus 	}
1053bac68f2cSTudor Ambarus #ifdef DEBUG
1054bac68f2cSTudor Ambarus 	print_hex_dump(KERN_ERR, "rfc4106 enc shdesc@"__stringify(__LINE__)": ",
1055bac68f2cSTudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
1056bac68f2cSTudor Ambarus 		       desc_bytes(desc), 1);
1057bac68f2cSTudor Ambarus #endif
1058bac68f2cSTudor Ambarus 
1059bac68f2cSTudor Ambarus 	/*
1060bac68f2cSTudor Ambarus 	 * Job Descriptor and Shared Descriptors
1061bac68f2cSTudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
1062bac68f2cSTudor Ambarus 	 */
1063bac68f2cSTudor Ambarus 	keys_fit_inline = false;
1064bac68f2cSTudor Ambarus 	if (DESC_RFC4106_DEC_LEN + DESC_JOB_IO_LEN +
1065bac68f2cSTudor Ambarus 	    ctx->enckeylen <= CAAM_DESC_BYTES_MAX)
1066bac68f2cSTudor Ambarus 		keys_fit_inline = true;
1067bac68f2cSTudor Ambarus 
1068bac68f2cSTudor Ambarus 	desc = ctx->sh_desc_dec;
1069bac68f2cSTudor Ambarus 
1070bac68f2cSTudor Ambarus 	init_sh_desc(desc, HDR_SHARE_SERIAL);
1071bac68f2cSTudor Ambarus 
1072bac68f2cSTudor Ambarus 	/* Skip key loading if it is loaded due to sharing */
1073bac68f2cSTudor Ambarus 	key_jump_cmd = append_jump(desc, JUMP_JSL |
1074bac68f2cSTudor Ambarus 				   JUMP_TEST_ALL | JUMP_COND_SHRD);
1075bac68f2cSTudor Ambarus 	if (keys_fit_inline)
1076bac68f2cSTudor Ambarus 		append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
1077bac68f2cSTudor Ambarus 				  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
1078bac68f2cSTudor Ambarus 	else
1079bac68f2cSTudor Ambarus 		append_key(desc, ctx->key_dma, ctx->enckeylen,
1080bac68f2cSTudor Ambarus 			   CLASS_1 | KEY_DEST_CLASS_REG);
1081bac68f2cSTudor Ambarus 	set_jump_tgt_here(desc, key_jump_cmd);
1082bac68f2cSTudor Ambarus 
1083bac68f2cSTudor Ambarus 	/* Class 1 operation */
1084bac68f2cSTudor Ambarus 	append_operation(desc, ctx->class1_alg_type |
1085bac68f2cSTudor Ambarus 			 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON);
1086bac68f2cSTudor Ambarus 
108746218750SHerbert Xu 	append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, 8);
1088f2147b88SHerbert Xu 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
1089bac68f2cSTudor Ambarus 
1090bac68f2cSTudor Ambarus 	/* Read assoc data */
1091bac68f2cSTudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
1092bac68f2cSTudor Ambarus 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
1093bac68f2cSTudor Ambarus 
109446218750SHerbert Xu 	/* Skip IV */
109546218750SHerbert Xu 	append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
1096f2147b88SHerbert Xu 
1097bac68f2cSTudor Ambarus 	/* Will read cryptlen bytes */
109846218750SHerbert Xu 	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG3, CAAM_CMD_SZ);
1099bac68f2cSTudor Ambarus 
11004aad0cc5SHoria Geant? 	/* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
11014aad0cc5SHoria Geant? 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG);
1102bac68f2cSTudor Ambarus 
110346218750SHerbert Xu 	/* Skip assoc data */
110446218750SHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
110546218750SHerbert Xu 
110646218750SHerbert Xu 	/* Will write cryptlen bytes */
110746218750SHerbert Xu 	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
110846218750SHerbert Xu 
110946218750SHerbert Xu 	/* Store payload data */
111046218750SHerbert Xu 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
111146218750SHerbert Xu 
11124aad0cc5SHoria Geant? 	/* Read encrypted data */
11134aad0cc5SHoria Geant? 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
11144aad0cc5SHoria Geant? 			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
11154aad0cc5SHoria Geant? 
1116bac68f2cSTudor Ambarus 	/* Read ICV */
1117bac68f2cSTudor Ambarus 	append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS1 |
1118bac68f2cSTudor Ambarus 			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
1119bac68f2cSTudor Ambarus 
1120bac68f2cSTudor Ambarus 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
1121bac68f2cSTudor Ambarus 					      desc_bytes(desc),
1122bac68f2cSTudor Ambarus 					      DMA_TO_DEVICE);
1123bac68f2cSTudor Ambarus 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
1124bac68f2cSTudor Ambarus 		dev_err(jrdev, "unable to map shared descriptor\n");
1125bac68f2cSTudor Ambarus 		return -ENOMEM;
1126bac68f2cSTudor Ambarus 	}
1127bac68f2cSTudor Ambarus #ifdef DEBUG
1128bac68f2cSTudor Ambarus 	print_hex_dump(KERN_ERR, "rfc4106 dec shdesc@"__stringify(__LINE__)": ",
1129bac68f2cSTudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
1130bac68f2cSTudor Ambarus 		       desc_bytes(desc), 1);
1131bac68f2cSTudor Ambarus #endif
1132bac68f2cSTudor Ambarus 
1133bac68f2cSTudor Ambarus 	return 0;
1134bac68f2cSTudor Ambarus }
1135bac68f2cSTudor Ambarus 
1136bac68f2cSTudor Ambarus static int rfc4106_setauthsize(struct crypto_aead *authenc,
1137bac68f2cSTudor Ambarus 			       unsigned int authsize)
1138bac68f2cSTudor Ambarus {
1139bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
1140bac68f2cSTudor Ambarus 
1141bac68f2cSTudor Ambarus 	ctx->authsize = authsize;
1142bac68f2cSTudor Ambarus 	rfc4106_set_sh_desc(authenc);
1143bac68f2cSTudor Ambarus 
1144bac68f2cSTudor Ambarus 	return 0;
1145bac68f2cSTudor Ambarus }
1146bac68f2cSTudor Ambarus 
11475d0429a3STudor Ambarus static int rfc4543_set_sh_desc(struct crypto_aead *aead)
11485d0429a3STudor Ambarus {
11495d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
11505d0429a3STudor Ambarus 	struct device *jrdev = ctx->jrdev;
11515d0429a3STudor Ambarus 	bool keys_fit_inline = false;
1152f2147b88SHerbert Xu 	u32 *key_jump_cmd;
11535d0429a3STudor Ambarus 	u32 *read_move_cmd, *write_move_cmd;
11545d0429a3STudor Ambarus 	u32 *desc;
11555d0429a3STudor Ambarus 
11565d0429a3STudor Ambarus 	if (!ctx->enckeylen || !ctx->authsize)
11575d0429a3STudor Ambarus 		return 0;
11585d0429a3STudor Ambarus 
11595d0429a3STudor Ambarus 	/*
11605d0429a3STudor Ambarus 	 * RFC4543 encrypt shared descriptor
11615d0429a3STudor Ambarus 	 * Job Descriptor and Shared Descriptor
11625d0429a3STudor Ambarus 	 * must fit into the 64-word Descriptor h/w Buffer
11635d0429a3STudor Ambarus 	 */
1164f2147b88SHerbert Xu 	if (DESC_RFC4543_ENC_LEN + GCM_DESC_JOB_IO_LEN +
11655d0429a3STudor Ambarus 	    ctx->enckeylen <= CAAM_DESC_BYTES_MAX)
11665d0429a3STudor Ambarus 		keys_fit_inline = true;
11675d0429a3STudor Ambarus 
11685d0429a3STudor Ambarus 	desc = ctx->sh_desc_enc;
11695d0429a3STudor Ambarus 
11705d0429a3STudor Ambarus 	init_sh_desc(desc, HDR_SHARE_SERIAL);
11715d0429a3STudor Ambarus 
11725d0429a3STudor Ambarus 	/* Skip key loading if it is loaded due to sharing */
11735d0429a3STudor Ambarus 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
11745d0429a3STudor Ambarus 				   JUMP_COND_SHRD);
11755d0429a3STudor Ambarus 	if (keys_fit_inline)
11765d0429a3STudor Ambarus 		append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
11775d0429a3STudor Ambarus 				  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
11785d0429a3STudor Ambarus 	else
11795d0429a3STudor Ambarus 		append_key(desc, ctx->key_dma, ctx->enckeylen,
11805d0429a3STudor Ambarus 			   CLASS_1 | KEY_DEST_CLASS_REG);
11815d0429a3STudor Ambarus 	set_jump_tgt_here(desc, key_jump_cmd);
11825d0429a3STudor Ambarus 
11835d0429a3STudor Ambarus 	/* Class 1 operation */
11845d0429a3STudor Ambarus 	append_operation(desc, ctx->class1_alg_type |
11855d0429a3STudor Ambarus 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
11865d0429a3STudor Ambarus 
1187f2147b88SHerbert Xu 	/* assoclen + cryptlen = seqinlen */
1188f2147b88SHerbert Xu 	append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
11895d0429a3STudor Ambarus 
11905d0429a3STudor Ambarus 	/*
11915d0429a3STudor Ambarus 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
11925d0429a3STudor Ambarus 	 * thus need to do some magic, i.e. self-patch the descriptor
11935d0429a3STudor Ambarus 	 * buffer.
11945d0429a3STudor Ambarus 	 */
11955d0429a3STudor Ambarus 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
11965d0429a3STudor Ambarus 				    (0x6 << MOVE_LEN_SHIFT));
11975d0429a3STudor Ambarus 	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
11985d0429a3STudor Ambarus 				     (0x8 << MOVE_LEN_SHIFT));
11995d0429a3STudor Ambarus 
1200f2147b88SHerbert Xu 	/* Will read assoclen + cryptlen bytes */
1201f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
12025d0429a3STudor Ambarus 
1203f2147b88SHerbert Xu 	/* Will write assoclen + cryptlen bytes */
1204f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1205f2147b88SHerbert Xu 
1206f2147b88SHerbert Xu 	/* Read and write assoclen + cryptlen bytes */
12075d0429a3STudor Ambarus 	aead_append_src_dst(desc, FIFOLD_TYPE_AAD);
12085d0429a3STudor Ambarus 
12095d0429a3STudor Ambarus 	set_move_tgt_here(desc, read_move_cmd);
12105d0429a3STudor Ambarus 	set_move_tgt_here(desc, write_move_cmd);
12115d0429a3STudor Ambarus 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
12125d0429a3STudor Ambarus 	/* Move payload data to OFIFO */
12135d0429a3STudor Ambarus 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
12145d0429a3STudor Ambarus 
12155d0429a3STudor Ambarus 	/* Write ICV */
12165d0429a3STudor Ambarus 	append_seq_store(desc, ctx->authsize, LDST_CLASS_1_CCB |
12175d0429a3STudor Ambarus 			 LDST_SRCDST_BYTE_CONTEXT);
12185d0429a3STudor Ambarus 
12195d0429a3STudor Ambarus 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
12205d0429a3STudor Ambarus 					      desc_bytes(desc),
12215d0429a3STudor Ambarus 					      DMA_TO_DEVICE);
12225d0429a3STudor Ambarus 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
12235d0429a3STudor Ambarus 		dev_err(jrdev, "unable to map shared descriptor\n");
12245d0429a3STudor Ambarus 		return -ENOMEM;
12255d0429a3STudor Ambarus 	}
12265d0429a3STudor Ambarus #ifdef DEBUG
12275d0429a3STudor Ambarus 	print_hex_dump(KERN_ERR, "rfc4543 enc shdesc@"__stringify(__LINE__)": ",
12285d0429a3STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
12295d0429a3STudor Ambarus 		       desc_bytes(desc), 1);
12305d0429a3STudor Ambarus #endif
12315d0429a3STudor Ambarus 
12325d0429a3STudor Ambarus 	/*
12335d0429a3STudor Ambarus 	 * Job Descriptor and Shared Descriptors
12345d0429a3STudor Ambarus 	 * must all fit into the 64-word Descriptor h/w Buffer
12355d0429a3STudor Ambarus 	 */
12365d0429a3STudor Ambarus 	keys_fit_inline = false;
1237f2147b88SHerbert Xu 	if (DESC_RFC4543_DEC_LEN + GCM_DESC_JOB_IO_LEN +
12385d0429a3STudor Ambarus 	    ctx->enckeylen <= CAAM_DESC_BYTES_MAX)
12395d0429a3STudor Ambarus 		keys_fit_inline = true;
12405d0429a3STudor Ambarus 
12415d0429a3STudor Ambarus 	desc = ctx->sh_desc_dec;
12425d0429a3STudor Ambarus 
12435d0429a3STudor Ambarus 	init_sh_desc(desc, HDR_SHARE_SERIAL);
12445d0429a3STudor Ambarus 
12455d0429a3STudor Ambarus 	/* Skip key loading if it is loaded due to sharing */
12465d0429a3STudor Ambarus 	key_jump_cmd = append_jump(desc, JUMP_JSL |
12475d0429a3STudor Ambarus 				   JUMP_TEST_ALL | JUMP_COND_SHRD);
12485d0429a3STudor Ambarus 	if (keys_fit_inline)
12495d0429a3STudor Ambarus 		append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
12505d0429a3STudor Ambarus 				  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
12515d0429a3STudor Ambarus 	else
12525d0429a3STudor Ambarus 		append_key(desc, ctx->key_dma, ctx->enckeylen,
12535d0429a3STudor Ambarus 			   CLASS_1 | KEY_DEST_CLASS_REG);
12545d0429a3STudor Ambarus 	set_jump_tgt_here(desc, key_jump_cmd);
12555d0429a3STudor Ambarus 
12565d0429a3STudor Ambarus 	/* Class 1 operation */
12575d0429a3STudor Ambarus 	append_operation(desc, ctx->class1_alg_type |
12585d0429a3STudor Ambarus 			 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT | OP_ALG_ICV_ON);
12595d0429a3STudor Ambarus 
1260f2147b88SHerbert Xu 	/* assoclen + cryptlen = seqoutlen */
1261f2147b88SHerbert Xu 	append_math_sub(desc, REG3, SEQOUTLEN, REG0, CAAM_CMD_SZ);
12625d0429a3STudor Ambarus 
12635d0429a3STudor Ambarus 	/*
12645d0429a3STudor Ambarus 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
12655d0429a3STudor Ambarus 	 * thus need to do some magic, i.e. self-patch the descriptor
12665d0429a3STudor Ambarus 	 * buffer.
12675d0429a3STudor Ambarus 	 */
12685d0429a3STudor Ambarus 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
12695d0429a3STudor Ambarus 				    (0x6 << MOVE_LEN_SHIFT));
12705d0429a3STudor Ambarus 	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
12715d0429a3STudor Ambarus 				     (0x8 << MOVE_LEN_SHIFT));
12725d0429a3STudor Ambarus 
1273f2147b88SHerbert Xu 	/* Will read assoclen + cryptlen bytes */
1274f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
12755d0429a3STudor Ambarus 
1276f2147b88SHerbert Xu 	/* Will write assoclen + cryptlen bytes */
1277f2147b88SHerbert Xu 	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
12785d0429a3STudor Ambarus 
12795d0429a3STudor Ambarus 	/* Store payload data */
12805d0429a3STudor Ambarus 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
12815d0429a3STudor Ambarus 
1282f2147b88SHerbert Xu 	/* In-snoop assoclen + cryptlen data */
12835d0429a3STudor Ambarus 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | FIFOLDST_VLF |
12845d0429a3STudor Ambarus 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST2FLUSH1);
12855d0429a3STudor Ambarus 
12865d0429a3STudor Ambarus 	set_move_tgt_here(desc, read_move_cmd);
12875d0429a3STudor Ambarus 	set_move_tgt_here(desc, write_move_cmd);
12885d0429a3STudor Ambarus 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
12895d0429a3STudor Ambarus 	/* Move payload data to OFIFO */
12905d0429a3STudor Ambarus 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
12915d0429a3STudor Ambarus 	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
12925d0429a3STudor Ambarus 
12935d0429a3STudor Ambarus 	/* Read ICV */
12945d0429a3STudor Ambarus 	append_seq_fifo_load(desc, ctx->authsize, FIFOLD_CLASS_CLASS1 |
12955d0429a3STudor Ambarus 			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
12965d0429a3STudor Ambarus 
12975d0429a3STudor Ambarus 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
12985d0429a3STudor Ambarus 					      desc_bytes(desc),
12995d0429a3STudor Ambarus 					      DMA_TO_DEVICE);
13005d0429a3STudor Ambarus 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
13015d0429a3STudor Ambarus 		dev_err(jrdev, "unable to map shared descriptor\n");
13025d0429a3STudor Ambarus 		return -ENOMEM;
13035d0429a3STudor Ambarus 	}
13045d0429a3STudor Ambarus #ifdef DEBUG
13055d0429a3STudor Ambarus 	print_hex_dump(KERN_ERR, "rfc4543 dec shdesc@"__stringify(__LINE__)": ",
13065d0429a3STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
13075d0429a3STudor Ambarus 		       desc_bytes(desc), 1);
13085d0429a3STudor Ambarus #endif
13095d0429a3STudor Ambarus 
13105d0429a3STudor Ambarus 	return 0;
13115d0429a3STudor Ambarus }
13125d0429a3STudor Ambarus 
13135d0429a3STudor Ambarus static int rfc4543_setauthsize(struct crypto_aead *authenc,
13145d0429a3STudor Ambarus 			       unsigned int authsize)
13155d0429a3STudor Ambarus {
13165d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(authenc);
13175d0429a3STudor Ambarus 
13185d0429a3STudor Ambarus 	ctx->authsize = authsize;
13195d0429a3STudor Ambarus 	rfc4543_set_sh_desc(authenc);
13205d0429a3STudor Ambarus 
13215d0429a3STudor Ambarus 	return 0;
13225d0429a3STudor Ambarus }
13235d0429a3STudor Ambarus 
13244c1ec1f9SYuan Kang static u32 gen_split_aead_key(struct caam_ctx *ctx, const u8 *key_in,
13254c1ec1f9SYuan Kang 			      u32 authkeylen)
13268e8ec596SKim Phillips {
13274c1ec1f9SYuan Kang 	return gen_split_key(ctx->jrdev, ctx->key, ctx->split_key_len,
13284c1ec1f9SYuan Kang 			       ctx->split_key_pad_len, key_in, authkeylen,
13294c1ec1f9SYuan Kang 			       ctx->alg_op);
13308e8ec596SKim Phillips }
13318e8ec596SKim Phillips 
13320e479300SYuan Kang static int aead_setkey(struct crypto_aead *aead,
13338e8ec596SKim Phillips 			       const u8 *key, unsigned int keylen)
13348e8ec596SKim Phillips {
13358e8ec596SKim Phillips 	/* Sizes for MDHA pads (*not* keys): MD5, SHA1, 224, 256, 384, 512 */
13368e8ec596SKim Phillips 	static const u8 mdpadlen[] = { 16, 20, 32, 32, 64, 64 };
13378e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
13388e8ec596SKim Phillips 	struct device *jrdev = ctx->jrdev;
13394e6e0b27SHoria Geanta 	struct crypto_authenc_keys keys;
13408e8ec596SKim Phillips 	int ret = 0;
13418e8ec596SKim Phillips 
13424e6e0b27SHoria Geanta 	if (crypto_authenc_extractkeys(&keys, key, keylen) != 0)
13438e8ec596SKim Phillips 		goto badkey;
13448e8ec596SKim Phillips 
13458e8ec596SKim Phillips 	/* Pick class 2 key length from algorithm submask */
13468e8ec596SKim Phillips 	ctx->split_key_len = mdpadlen[(ctx->alg_op & OP_ALG_ALGSEL_SUBMASK) >>
13478e8ec596SKim Phillips 				      OP_ALG_ALGSEL_SHIFT] * 2;
13488e8ec596SKim Phillips 	ctx->split_key_pad_len = ALIGN(ctx->split_key_len, 16);
13498e8ec596SKim Phillips 
13504e6e0b27SHoria Geanta 	if (ctx->split_key_pad_len + keys.enckeylen > CAAM_MAX_KEY_SIZE)
13514e6e0b27SHoria Geanta 		goto badkey;
13524e6e0b27SHoria Geanta 
13538e8ec596SKim Phillips #ifdef DEBUG
13548e8ec596SKim Phillips 	printk(KERN_ERR "keylen %d enckeylen %d authkeylen %d\n",
13554e6e0b27SHoria Geanta 	       keys.authkeylen + keys.enckeylen, keys.enckeylen,
13564e6e0b27SHoria Geanta 	       keys.authkeylen);
13578e8ec596SKim Phillips 	printk(KERN_ERR "split_key_len %d split_key_pad_len %d\n",
13588e8ec596SKim Phillips 	       ctx->split_key_len, ctx->split_key_pad_len);
1359514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
13608e8ec596SKim Phillips 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
13618e8ec596SKim Phillips #endif
13628e8ec596SKim Phillips 
13634e6e0b27SHoria Geanta 	ret = gen_split_aead_key(ctx, keys.authkey, keys.authkeylen);
13648e8ec596SKim Phillips 	if (ret) {
13658e8ec596SKim Phillips 		goto badkey;
13668e8ec596SKim Phillips 	}
13678e8ec596SKim Phillips 
13688e8ec596SKim Phillips 	/* postpend encryption key to auth split key */
13694e6e0b27SHoria Geanta 	memcpy(ctx->key + ctx->split_key_pad_len, keys.enckey, keys.enckeylen);
13708e8ec596SKim Phillips 
1371885e9e2fSYuan Kang 	ctx->key_dma = dma_map_single(jrdev, ctx->key, ctx->split_key_pad_len +
13724e6e0b27SHoria Geanta 				      keys.enckeylen, DMA_TO_DEVICE);
1373885e9e2fSYuan Kang 	if (dma_mapping_error(jrdev, ctx->key_dma)) {
13748e8ec596SKim Phillips 		dev_err(jrdev, "unable to map key i/o memory\n");
13758e8ec596SKim Phillips 		return -ENOMEM;
13768e8ec596SKim Phillips 	}
13778e8ec596SKim Phillips #ifdef DEBUG
1378514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ctx.key@"__stringify(__LINE__)": ",
13798e8ec596SKim Phillips 		       DUMP_PREFIX_ADDRESS, 16, 4, ctx->key,
13804e6e0b27SHoria Geanta 		       ctx->split_key_pad_len + keys.enckeylen, 1);
13818e8ec596SKim Phillips #endif
13828e8ec596SKim Phillips 
13834e6e0b27SHoria Geanta 	ctx->enckeylen = keys.enckeylen;
13848e8ec596SKim Phillips 
13851acebad3SYuan Kang 	ret = aead_set_sh_desc(aead);
13868e8ec596SKim Phillips 	if (ret) {
1387885e9e2fSYuan Kang 		dma_unmap_single(jrdev, ctx->key_dma, ctx->split_key_pad_len +
13884e6e0b27SHoria Geanta 				 keys.enckeylen, DMA_TO_DEVICE);
13898e8ec596SKim Phillips 	}
13908e8ec596SKim Phillips 
13918e8ec596SKim Phillips 	return ret;
13928e8ec596SKim Phillips badkey:
13938e8ec596SKim Phillips 	crypto_aead_set_flags(aead, CRYPTO_TFM_RES_BAD_KEY_LEN);
13948e8ec596SKim Phillips 	return -EINVAL;
13958e8ec596SKim Phillips }
13968e8ec596SKim Phillips 
13973ef8d945STudor Ambarus static int gcm_setkey(struct crypto_aead *aead,
13983ef8d945STudor Ambarus 		      const u8 *key, unsigned int keylen)
13993ef8d945STudor Ambarus {
14003ef8d945STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
14013ef8d945STudor Ambarus 	struct device *jrdev = ctx->jrdev;
14023ef8d945STudor Ambarus 	int ret = 0;
14033ef8d945STudor Ambarus 
14043ef8d945STudor Ambarus #ifdef DEBUG
14053ef8d945STudor Ambarus 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
14063ef8d945STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
14073ef8d945STudor Ambarus #endif
14083ef8d945STudor Ambarus 
14093ef8d945STudor Ambarus 	memcpy(ctx->key, key, keylen);
14103ef8d945STudor Ambarus 	ctx->key_dma = dma_map_single(jrdev, ctx->key, keylen,
14113ef8d945STudor Ambarus 				      DMA_TO_DEVICE);
14123ef8d945STudor Ambarus 	if (dma_mapping_error(jrdev, ctx->key_dma)) {
14133ef8d945STudor Ambarus 		dev_err(jrdev, "unable to map key i/o memory\n");
14143ef8d945STudor Ambarus 		return -ENOMEM;
14153ef8d945STudor Ambarus 	}
14163ef8d945STudor Ambarus 	ctx->enckeylen = keylen;
14173ef8d945STudor Ambarus 
14183ef8d945STudor Ambarus 	ret = gcm_set_sh_desc(aead);
14193ef8d945STudor Ambarus 	if (ret) {
14203ef8d945STudor Ambarus 		dma_unmap_single(jrdev, ctx->key_dma, ctx->enckeylen,
14213ef8d945STudor Ambarus 				 DMA_TO_DEVICE);
14223ef8d945STudor Ambarus 	}
14233ef8d945STudor Ambarus 
14243ef8d945STudor Ambarus 	return ret;
14253ef8d945STudor Ambarus }
14263ef8d945STudor Ambarus 
1427bac68f2cSTudor Ambarus static int rfc4106_setkey(struct crypto_aead *aead,
1428bac68f2cSTudor Ambarus 			  const u8 *key, unsigned int keylen)
1429bac68f2cSTudor Ambarus {
1430bac68f2cSTudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
1431bac68f2cSTudor Ambarus 	struct device *jrdev = ctx->jrdev;
1432bac68f2cSTudor Ambarus 	int ret = 0;
1433bac68f2cSTudor Ambarus 
1434bac68f2cSTudor Ambarus 	if (keylen < 4)
1435bac68f2cSTudor Ambarus 		return -EINVAL;
1436bac68f2cSTudor Ambarus 
1437bac68f2cSTudor Ambarus #ifdef DEBUG
1438bac68f2cSTudor Ambarus 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
1439bac68f2cSTudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
1440bac68f2cSTudor Ambarus #endif
1441bac68f2cSTudor Ambarus 
1442bac68f2cSTudor Ambarus 	memcpy(ctx->key, key, keylen);
1443bac68f2cSTudor Ambarus 
1444bac68f2cSTudor Ambarus 	/*
1445bac68f2cSTudor Ambarus 	 * The last four bytes of the key material are used as the salt value
1446bac68f2cSTudor Ambarus 	 * in the nonce. Update the AES key length.
1447bac68f2cSTudor Ambarus 	 */
1448bac68f2cSTudor Ambarus 	ctx->enckeylen = keylen - 4;
1449bac68f2cSTudor Ambarus 
1450bac68f2cSTudor Ambarus 	ctx->key_dma = dma_map_single(jrdev, ctx->key, ctx->enckeylen,
1451bac68f2cSTudor Ambarus 				      DMA_TO_DEVICE);
1452bac68f2cSTudor Ambarus 	if (dma_mapping_error(jrdev, ctx->key_dma)) {
1453bac68f2cSTudor Ambarus 		dev_err(jrdev, "unable to map key i/o memory\n");
1454bac68f2cSTudor Ambarus 		return -ENOMEM;
1455bac68f2cSTudor Ambarus 	}
1456bac68f2cSTudor Ambarus 
1457bac68f2cSTudor Ambarus 	ret = rfc4106_set_sh_desc(aead);
1458bac68f2cSTudor Ambarus 	if (ret) {
1459bac68f2cSTudor Ambarus 		dma_unmap_single(jrdev, ctx->key_dma, ctx->enckeylen,
1460bac68f2cSTudor Ambarus 				 DMA_TO_DEVICE);
1461bac68f2cSTudor Ambarus 	}
1462bac68f2cSTudor Ambarus 
1463bac68f2cSTudor Ambarus 	return ret;
1464bac68f2cSTudor Ambarus }
1465bac68f2cSTudor Ambarus 
14665d0429a3STudor Ambarus static int rfc4543_setkey(struct crypto_aead *aead,
14675d0429a3STudor Ambarus 			  const u8 *key, unsigned int keylen)
14685d0429a3STudor Ambarus {
14695d0429a3STudor Ambarus 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
14705d0429a3STudor Ambarus 	struct device *jrdev = ctx->jrdev;
14715d0429a3STudor Ambarus 	int ret = 0;
14725d0429a3STudor Ambarus 
14735d0429a3STudor Ambarus 	if (keylen < 4)
14745d0429a3STudor Ambarus 		return -EINVAL;
14755d0429a3STudor Ambarus 
14765d0429a3STudor Ambarus #ifdef DEBUG
14775d0429a3STudor Ambarus 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
14785d0429a3STudor Ambarus 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
14795d0429a3STudor Ambarus #endif
14805d0429a3STudor Ambarus 
14815d0429a3STudor Ambarus 	memcpy(ctx->key, key, keylen);
14825d0429a3STudor Ambarus 
14835d0429a3STudor Ambarus 	/*
14845d0429a3STudor Ambarus 	 * The last four bytes of the key material are used as the salt value
14855d0429a3STudor Ambarus 	 * in the nonce. Update the AES key length.
14865d0429a3STudor Ambarus 	 */
14875d0429a3STudor Ambarus 	ctx->enckeylen = keylen - 4;
14885d0429a3STudor Ambarus 
14895d0429a3STudor Ambarus 	ctx->key_dma = dma_map_single(jrdev, ctx->key, ctx->enckeylen,
14905d0429a3STudor Ambarus 				      DMA_TO_DEVICE);
14915d0429a3STudor Ambarus 	if (dma_mapping_error(jrdev, ctx->key_dma)) {
14925d0429a3STudor Ambarus 		dev_err(jrdev, "unable to map key i/o memory\n");
14935d0429a3STudor Ambarus 		return -ENOMEM;
14945d0429a3STudor Ambarus 	}
14955d0429a3STudor Ambarus 
14965d0429a3STudor Ambarus 	ret = rfc4543_set_sh_desc(aead);
14975d0429a3STudor Ambarus 	if (ret) {
14985d0429a3STudor Ambarus 		dma_unmap_single(jrdev, ctx->key_dma, ctx->enckeylen,
14995d0429a3STudor Ambarus 				 DMA_TO_DEVICE);
15005d0429a3STudor Ambarus 	}
15015d0429a3STudor Ambarus 
15025d0429a3STudor Ambarus 	return ret;
15035d0429a3STudor Ambarus }
15045d0429a3STudor Ambarus 
1505acdca31dSYuan Kang static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
1506acdca31dSYuan Kang 			     const u8 *key, unsigned int keylen)
1507acdca31dSYuan Kang {
1508acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
1509a5f57cffSCatalin Vasile 	struct ablkcipher_tfm *crt = &ablkcipher->base.crt_ablkcipher;
1510a5f57cffSCatalin Vasile 	struct crypto_tfm *tfm = crypto_ablkcipher_tfm(ablkcipher);
1511a5f57cffSCatalin Vasile 	const char *alg_name = crypto_tfm_alg_name(tfm);
1512acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
1513acdca31dSYuan Kang 	int ret = 0;
15144464a7d4SHoria Geanta 	u32 *key_jump_cmd;
1515acdca31dSYuan Kang 	u32 *desc;
15165ba1c7b5SCatalin Vasile 	u8 *nonce;
15177222d1a3SCatalin Vasile 	u32 geniv;
15182b22f6c5SCatalin Vasile 	u32 ctx1_iv_off = 0;
15192b22f6c5SCatalin Vasile 	const bool ctr_mode = ((ctx->class1_alg_type & OP_ALG_AAI_MASK) ==
15202b22f6c5SCatalin Vasile 			       OP_ALG_AAI_CTR_MOD128);
1521a5f57cffSCatalin Vasile 	const bool is_rfc3686 = (ctr_mode &&
1522a5f57cffSCatalin Vasile 				 (strstr(alg_name, "rfc3686") != NULL));
1523acdca31dSYuan Kang 
1524acdca31dSYuan Kang #ifdef DEBUG
1525514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "key in @"__stringify(__LINE__)": ",
1526acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, key, keylen, 1);
1527acdca31dSYuan Kang #endif
15282b22f6c5SCatalin Vasile 	/*
15292b22f6c5SCatalin Vasile 	 * AES-CTR needs to load IV in CONTEXT1 reg
15302b22f6c5SCatalin Vasile 	 * at an offset of 128bits (16bytes)
15312b22f6c5SCatalin Vasile 	 * CONTEXT1[255:128] = IV
15322b22f6c5SCatalin Vasile 	 */
15332b22f6c5SCatalin Vasile 	if (ctr_mode)
15342b22f6c5SCatalin Vasile 		ctx1_iv_off = 16;
1535acdca31dSYuan Kang 
1536a5f57cffSCatalin Vasile 	/*
1537a5f57cffSCatalin Vasile 	 * RFC3686 specific:
1538a5f57cffSCatalin Vasile 	 *	| CONTEXT1[255:128] = {NONCE, IV, COUNTER}
1539a5f57cffSCatalin Vasile 	 *	| *key = {KEY, NONCE}
1540a5f57cffSCatalin Vasile 	 */
1541a5f57cffSCatalin Vasile 	if (is_rfc3686) {
1542a5f57cffSCatalin Vasile 		ctx1_iv_off = 16 + CTR_RFC3686_NONCE_SIZE;
1543a5f57cffSCatalin Vasile 		keylen -= CTR_RFC3686_NONCE_SIZE;
1544a5f57cffSCatalin Vasile 	}
1545a5f57cffSCatalin Vasile 
1546acdca31dSYuan Kang 	memcpy(ctx->key, key, keylen);
1547acdca31dSYuan Kang 	ctx->key_dma = dma_map_single(jrdev, ctx->key, keylen,
1548acdca31dSYuan Kang 				      DMA_TO_DEVICE);
1549acdca31dSYuan Kang 	if (dma_mapping_error(jrdev, ctx->key_dma)) {
1550acdca31dSYuan Kang 		dev_err(jrdev, "unable to map key i/o memory\n");
1551acdca31dSYuan Kang 		return -ENOMEM;
1552acdca31dSYuan Kang 	}
1553acdca31dSYuan Kang 	ctx->enckeylen = keylen;
1554acdca31dSYuan Kang 
1555acdca31dSYuan Kang 	/* ablkcipher_encrypt shared descriptor */
1556acdca31dSYuan Kang 	desc = ctx->sh_desc_enc;
1557a5f57cffSCatalin Vasile 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1558acdca31dSYuan Kang 	/* Skip if already shared */
1559acdca31dSYuan Kang 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1560acdca31dSYuan Kang 				   JUMP_COND_SHRD);
1561acdca31dSYuan Kang 
1562acdca31dSYuan Kang 	/* Load class1 key only */
1563acdca31dSYuan Kang 	append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
1564acdca31dSYuan Kang 			  ctx->enckeylen, CLASS_1 |
1565acdca31dSYuan Kang 			  KEY_DEST_CLASS_REG);
1566acdca31dSYuan Kang 
1567a5f57cffSCatalin Vasile 	/* Load nonce into CONTEXT1 reg */
1568a5f57cffSCatalin Vasile 	if (is_rfc3686) {
15695ba1c7b5SCatalin Vasile 		nonce = (u8 *)key + keylen;
15705ba1c7b5SCatalin Vasile 		append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
15715ba1c7b5SCatalin Vasile 				   LDST_CLASS_IND_CCB |
1572a5f57cffSCatalin Vasile 				   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
1573a5f57cffSCatalin Vasile 		append_move(desc, MOVE_WAITCOMP |
1574a5f57cffSCatalin Vasile 			    MOVE_SRC_OUTFIFO |
1575a5f57cffSCatalin Vasile 			    MOVE_DEST_CLASS1CTX |
1576a5f57cffSCatalin Vasile 			    (16 << MOVE_OFFSET_SHIFT) |
1577a5f57cffSCatalin Vasile 			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
1578a5f57cffSCatalin Vasile 	}
1579a5f57cffSCatalin Vasile 
1580acdca31dSYuan Kang 	set_jump_tgt_here(desc, key_jump_cmd);
1581acdca31dSYuan Kang 
1582acdca31dSYuan Kang 	/* Load iv */
1583a5f57cffSCatalin Vasile 	append_seq_load(desc, crt->ivsize, LDST_SRCDST_BYTE_CONTEXT |
15842b22f6c5SCatalin Vasile 			LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT));
1585acdca31dSYuan Kang 
1586a5f57cffSCatalin Vasile 	/* Load counter into CONTEXT1 reg */
1587a5f57cffSCatalin Vasile 	if (is_rfc3686)
15885ba1c7b5SCatalin Vasile 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
1589a5f57cffSCatalin Vasile 				     LDST_SRCDST_BYTE_CONTEXT |
1590a5f57cffSCatalin Vasile 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
1591a5f57cffSCatalin Vasile 				      LDST_OFFSET_SHIFT));
1592a5f57cffSCatalin Vasile 
1593acdca31dSYuan Kang 	/* Load operation */
1594acdca31dSYuan Kang 	append_operation(desc, ctx->class1_alg_type |
1595acdca31dSYuan Kang 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
1596acdca31dSYuan Kang 
1597acdca31dSYuan Kang 	/* Perform operation */
1598acdca31dSYuan Kang 	ablkcipher_append_src_dst(desc);
1599acdca31dSYuan Kang 
1600acdca31dSYuan Kang 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc,
1601acdca31dSYuan Kang 					      desc_bytes(desc),
1602acdca31dSYuan Kang 					      DMA_TO_DEVICE);
1603acdca31dSYuan Kang 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
1604acdca31dSYuan Kang 		dev_err(jrdev, "unable to map shared descriptor\n");
1605acdca31dSYuan Kang 		return -ENOMEM;
1606acdca31dSYuan Kang 	}
1607acdca31dSYuan Kang #ifdef DEBUG
1608514df281SAlex Porosanu 	print_hex_dump(KERN_ERR,
1609514df281SAlex Porosanu 		       "ablkcipher enc shdesc@"__stringify(__LINE__)": ",
1610acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
1611acdca31dSYuan Kang 		       desc_bytes(desc), 1);
1612acdca31dSYuan Kang #endif
1613acdca31dSYuan Kang 	/* ablkcipher_decrypt shared descriptor */
1614acdca31dSYuan Kang 	desc = ctx->sh_desc_dec;
1615acdca31dSYuan Kang 
1616a5f57cffSCatalin Vasile 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1617acdca31dSYuan Kang 	/* Skip if already shared */
1618acdca31dSYuan Kang 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1619acdca31dSYuan Kang 				   JUMP_COND_SHRD);
1620acdca31dSYuan Kang 
1621acdca31dSYuan Kang 	/* Load class1 key only */
1622acdca31dSYuan Kang 	append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
1623acdca31dSYuan Kang 			  ctx->enckeylen, CLASS_1 |
1624acdca31dSYuan Kang 			  KEY_DEST_CLASS_REG);
1625acdca31dSYuan Kang 
1626a5f57cffSCatalin Vasile 	/* Load nonce into CONTEXT1 reg */
1627a5f57cffSCatalin Vasile 	if (is_rfc3686) {
16285ba1c7b5SCatalin Vasile 		nonce = (u8 *)key + keylen;
16295ba1c7b5SCatalin Vasile 		append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
16305ba1c7b5SCatalin Vasile 				   LDST_CLASS_IND_CCB |
1631a5f57cffSCatalin Vasile 				   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
1632a5f57cffSCatalin Vasile 		append_move(desc, MOVE_WAITCOMP |
1633a5f57cffSCatalin Vasile 			    MOVE_SRC_OUTFIFO |
1634a5f57cffSCatalin Vasile 			    MOVE_DEST_CLASS1CTX |
1635a5f57cffSCatalin Vasile 			    (16 << MOVE_OFFSET_SHIFT) |
1636a5f57cffSCatalin Vasile 			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
1637a5f57cffSCatalin Vasile 	}
1638a5f57cffSCatalin Vasile 
1639acdca31dSYuan Kang 	set_jump_tgt_here(desc, key_jump_cmd);
1640acdca31dSYuan Kang 
1641acdca31dSYuan Kang 	/* load IV */
1642a5f57cffSCatalin Vasile 	append_seq_load(desc, crt->ivsize, LDST_SRCDST_BYTE_CONTEXT |
16432b22f6c5SCatalin Vasile 			LDST_CLASS_1_CCB | (ctx1_iv_off << LDST_OFFSET_SHIFT));
1644acdca31dSYuan Kang 
1645a5f57cffSCatalin Vasile 	/* Load counter into CONTEXT1 reg */
1646a5f57cffSCatalin Vasile 	if (is_rfc3686)
16475ba1c7b5SCatalin Vasile 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
1648a5f57cffSCatalin Vasile 				     LDST_SRCDST_BYTE_CONTEXT |
1649a5f57cffSCatalin Vasile 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
1650a5f57cffSCatalin Vasile 				      LDST_OFFSET_SHIFT));
1651a5f57cffSCatalin Vasile 
1652acdca31dSYuan Kang 	/* Choose operation */
16532b22f6c5SCatalin Vasile 	if (ctr_mode)
16542b22f6c5SCatalin Vasile 		append_operation(desc, ctx->class1_alg_type |
16552b22f6c5SCatalin Vasile 				 OP_ALG_AS_INITFINAL | OP_ALG_DECRYPT);
16562b22f6c5SCatalin Vasile 	else
1657acdca31dSYuan Kang 		append_dec_op1(desc, ctx->class1_alg_type);
1658acdca31dSYuan Kang 
1659acdca31dSYuan Kang 	/* Perform operation */
1660acdca31dSYuan Kang 	ablkcipher_append_src_dst(desc);
1661acdca31dSYuan Kang 
1662acdca31dSYuan Kang 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
1663acdca31dSYuan Kang 					      desc_bytes(desc),
1664acdca31dSYuan Kang 					      DMA_TO_DEVICE);
166571c65f7cSHoria Geanta 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
1666acdca31dSYuan Kang 		dev_err(jrdev, "unable to map shared descriptor\n");
1667acdca31dSYuan Kang 		return -ENOMEM;
1668acdca31dSYuan Kang 	}
1669acdca31dSYuan Kang 
1670acdca31dSYuan Kang #ifdef DEBUG
1671514df281SAlex Porosanu 	print_hex_dump(KERN_ERR,
1672514df281SAlex Porosanu 		       "ablkcipher dec shdesc@"__stringify(__LINE__)": ",
1673acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
1674acdca31dSYuan Kang 		       desc_bytes(desc), 1);
1675acdca31dSYuan Kang #endif
16767222d1a3SCatalin Vasile 	/* ablkcipher_givencrypt shared descriptor */
16777222d1a3SCatalin Vasile 	desc = ctx->sh_desc_givenc;
16787222d1a3SCatalin Vasile 
16797222d1a3SCatalin Vasile 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
16807222d1a3SCatalin Vasile 	/* Skip if already shared */
16817222d1a3SCatalin Vasile 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
16827222d1a3SCatalin Vasile 				   JUMP_COND_SHRD);
16837222d1a3SCatalin Vasile 
16847222d1a3SCatalin Vasile 	/* Load class1 key only */
16857222d1a3SCatalin Vasile 	append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
16867222d1a3SCatalin Vasile 			  ctx->enckeylen, CLASS_1 |
16877222d1a3SCatalin Vasile 			  KEY_DEST_CLASS_REG);
16887222d1a3SCatalin Vasile 
16897222d1a3SCatalin Vasile 	/* Load Nonce into CONTEXT1 reg */
16907222d1a3SCatalin Vasile 	if (is_rfc3686) {
16915ba1c7b5SCatalin Vasile 		nonce = (u8 *)key + keylen;
16925ba1c7b5SCatalin Vasile 		append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
16935ba1c7b5SCatalin Vasile 				   LDST_CLASS_IND_CCB |
16947222d1a3SCatalin Vasile 				   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
16957222d1a3SCatalin Vasile 		append_move(desc, MOVE_WAITCOMP |
16967222d1a3SCatalin Vasile 			    MOVE_SRC_OUTFIFO |
16977222d1a3SCatalin Vasile 			    MOVE_DEST_CLASS1CTX |
16987222d1a3SCatalin Vasile 			    (16 << MOVE_OFFSET_SHIFT) |
16997222d1a3SCatalin Vasile 			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
17007222d1a3SCatalin Vasile 	}
17017222d1a3SCatalin Vasile 	set_jump_tgt_here(desc, key_jump_cmd);
17027222d1a3SCatalin Vasile 
17037222d1a3SCatalin Vasile 	/* Generate IV */
17047222d1a3SCatalin Vasile 	geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
17057222d1a3SCatalin Vasile 		NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 |
17067222d1a3SCatalin Vasile 		NFIFOENTRY_PTYPE_RND | (crt->ivsize << NFIFOENTRY_DLEN_SHIFT);
17077222d1a3SCatalin Vasile 	append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
17087222d1a3SCatalin Vasile 			    LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
17097222d1a3SCatalin Vasile 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
17107222d1a3SCatalin Vasile 	append_move(desc, MOVE_WAITCOMP |
17117222d1a3SCatalin Vasile 		    MOVE_SRC_INFIFO |
17127222d1a3SCatalin Vasile 		    MOVE_DEST_CLASS1CTX |
17137222d1a3SCatalin Vasile 		    (crt->ivsize << MOVE_LEN_SHIFT) |
17147222d1a3SCatalin Vasile 		    (ctx1_iv_off << MOVE_OFFSET_SHIFT));
17157222d1a3SCatalin Vasile 	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
17167222d1a3SCatalin Vasile 
17177222d1a3SCatalin Vasile 	/* Copy generated IV to memory */
17187222d1a3SCatalin Vasile 	append_seq_store(desc, crt->ivsize,
17197222d1a3SCatalin Vasile 			 LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
17207222d1a3SCatalin Vasile 			 (ctx1_iv_off << LDST_OFFSET_SHIFT));
17217222d1a3SCatalin Vasile 
17227222d1a3SCatalin Vasile 	/* Load Counter into CONTEXT1 reg */
17237222d1a3SCatalin Vasile 	if (is_rfc3686)
17245ba1c7b5SCatalin Vasile 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
17257222d1a3SCatalin Vasile 				     LDST_SRCDST_BYTE_CONTEXT |
17267222d1a3SCatalin Vasile 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
17277222d1a3SCatalin Vasile 				      LDST_OFFSET_SHIFT));
17287222d1a3SCatalin Vasile 
17297222d1a3SCatalin Vasile 	if (ctx1_iv_off)
17307222d1a3SCatalin Vasile 		append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | JUMP_COND_NCP |
17317222d1a3SCatalin Vasile 			    (1 << JUMP_OFFSET_SHIFT));
17327222d1a3SCatalin Vasile 
17337222d1a3SCatalin Vasile 	/* Load operation */
17347222d1a3SCatalin Vasile 	append_operation(desc, ctx->class1_alg_type |
17357222d1a3SCatalin Vasile 			 OP_ALG_AS_INITFINAL | OP_ALG_ENCRYPT);
17367222d1a3SCatalin Vasile 
17377222d1a3SCatalin Vasile 	/* Perform operation */
17387222d1a3SCatalin Vasile 	ablkcipher_append_src_dst(desc);
17397222d1a3SCatalin Vasile 
17407222d1a3SCatalin Vasile 	ctx->sh_desc_givenc_dma = dma_map_single(jrdev, desc,
17417222d1a3SCatalin Vasile 						 desc_bytes(desc),
17427222d1a3SCatalin Vasile 						 DMA_TO_DEVICE);
17437222d1a3SCatalin Vasile 	if (dma_mapping_error(jrdev, ctx->sh_desc_givenc_dma)) {
17447222d1a3SCatalin Vasile 		dev_err(jrdev, "unable to map shared descriptor\n");
17457222d1a3SCatalin Vasile 		return -ENOMEM;
17467222d1a3SCatalin Vasile 	}
17477222d1a3SCatalin Vasile #ifdef DEBUG
17487222d1a3SCatalin Vasile 	print_hex_dump(KERN_ERR,
17497222d1a3SCatalin Vasile 		       "ablkcipher givenc shdesc@" __stringify(__LINE__) ": ",
17507222d1a3SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, desc,
17517222d1a3SCatalin Vasile 		       desc_bytes(desc), 1);
17527222d1a3SCatalin Vasile #endif
1753acdca31dSYuan Kang 
1754acdca31dSYuan Kang 	return ret;
1755acdca31dSYuan Kang }
1756acdca31dSYuan Kang 
1757c6415a60SCatalin Vasile static int xts_ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
1758c6415a60SCatalin Vasile 				 const u8 *key, unsigned int keylen)
1759c6415a60SCatalin Vasile {
1760c6415a60SCatalin Vasile 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
1761c6415a60SCatalin Vasile 	struct device *jrdev = ctx->jrdev;
1762c6415a60SCatalin Vasile 	u32 *key_jump_cmd, *desc;
1763c6415a60SCatalin Vasile 	__be64 sector_size = cpu_to_be64(512);
1764c6415a60SCatalin Vasile 
1765c6415a60SCatalin Vasile 	if (keylen != 2 * AES_MIN_KEY_SIZE  && keylen != 2 * AES_MAX_KEY_SIZE) {
1766c6415a60SCatalin Vasile 		crypto_ablkcipher_set_flags(ablkcipher,
1767c6415a60SCatalin Vasile 					    CRYPTO_TFM_RES_BAD_KEY_LEN);
1768c6415a60SCatalin Vasile 		dev_err(jrdev, "key size mismatch\n");
1769c6415a60SCatalin Vasile 		return -EINVAL;
1770c6415a60SCatalin Vasile 	}
1771c6415a60SCatalin Vasile 
1772c6415a60SCatalin Vasile 	memcpy(ctx->key, key, keylen);
1773c6415a60SCatalin Vasile 	ctx->key_dma = dma_map_single(jrdev, ctx->key, keylen, DMA_TO_DEVICE);
1774c6415a60SCatalin Vasile 	if (dma_mapping_error(jrdev, ctx->key_dma)) {
1775c6415a60SCatalin Vasile 		dev_err(jrdev, "unable to map key i/o memory\n");
1776c6415a60SCatalin Vasile 		return -ENOMEM;
1777c6415a60SCatalin Vasile 	}
1778c6415a60SCatalin Vasile 	ctx->enckeylen = keylen;
1779c6415a60SCatalin Vasile 
1780c6415a60SCatalin Vasile 	/* xts_ablkcipher_encrypt shared descriptor */
1781c6415a60SCatalin Vasile 	desc = ctx->sh_desc_enc;
1782c6415a60SCatalin Vasile 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1783c6415a60SCatalin Vasile 	/* Skip if already shared */
1784c6415a60SCatalin Vasile 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1785c6415a60SCatalin Vasile 				   JUMP_COND_SHRD);
1786c6415a60SCatalin Vasile 
1787c6415a60SCatalin Vasile 	/* Load class1 keys only */
1788c6415a60SCatalin Vasile 	append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
1789c6415a60SCatalin Vasile 			  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
1790c6415a60SCatalin Vasile 
1791c6415a60SCatalin Vasile 	/* Load sector size with index 40 bytes (0x28) */
1792c6415a60SCatalin Vasile 	append_cmd(desc, CMD_LOAD | IMMEDIATE | LDST_SRCDST_BYTE_CONTEXT |
1793c6415a60SCatalin Vasile 		   LDST_CLASS_1_CCB | (0x28 << LDST_OFFSET_SHIFT) | 8);
1794c6415a60SCatalin Vasile 	append_data(desc, (void *)&sector_size, 8);
1795c6415a60SCatalin Vasile 
1796c6415a60SCatalin Vasile 	set_jump_tgt_here(desc, key_jump_cmd);
1797c6415a60SCatalin Vasile 
1798c6415a60SCatalin Vasile 	/*
1799c6415a60SCatalin Vasile 	 * create sequence for loading the sector index
1800c6415a60SCatalin Vasile 	 * Upper 8B of IV - will be used as sector index
1801c6415a60SCatalin Vasile 	 * Lower 8B of IV - will be discarded
1802c6415a60SCatalin Vasile 	 */
1803c6415a60SCatalin Vasile 	append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_BYTE_CONTEXT |
1804c6415a60SCatalin Vasile 		   LDST_CLASS_1_CCB | (0x20 << LDST_OFFSET_SHIFT) | 8);
1805c6415a60SCatalin Vasile 	append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
1806c6415a60SCatalin Vasile 
1807c6415a60SCatalin Vasile 	/* Load operation */
1808c6415a60SCatalin Vasile 	append_operation(desc, ctx->class1_alg_type | OP_ALG_AS_INITFINAL |
1809c6415a60SCatalin Vasile 			 OP_ALG_ENCRYPT);
1810c6415a60SCatalin Vasile 
1811c6415a60SCatalin Vasile 	/* Perform operation */
1812c6415a60SCatalin Vasile 	ablkcipher_append_src_dst(desc);
1813c6415a60SCatalin Vasile 
1814c6415a60SCatalin Vasile 	ctx->sh_desc_enc_dma = dma_map_single(jrdev, desc, desc_bytes(desc),
1815c6415a60SCatalin Vasile 					      DMA_TO_DEVICE);
1816c6415a60SCatalin Vasile 	if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
1817c6415a60SCatalin Vasile 		dev_err(jrdev, "unable to map shared descriptor\n");
1818c6415a60SCatalin Vasile 		return -ENOMEM;
1819c6415a60SCatalin Vasile 	}
1820c6415a60SCatalin Vasile #ifdef DEBUG
1821c6415a60SCatalin Vasile 	print_hex_dump(KERN_ERR,
1822c6415a60SCatalin Vasile 		       "xts ablkcipher enc shdesc@" __stringify(__LINE__) ": ",
1823c6415a60SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
1824c6415a60SCatalin Vasile #endif
1825c6415a60SCatalin Vasile 
1826c6415a60SCatalin Vasile 	/* xts_ablkcipher_decrypt shared descriptor */
1827c6415a60SCatalin Vasile 	desc = ctx->sh_desc_dec;
1828c6415a60SCatalin Vasile 
1829c6415a60SCatalin Vasile 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1830c6415a60SCatalin Vasile 	/* Skip if already shared */
1831c6415a60SCatalin Vasile 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1832c6415a60SCatalin Vasile 				   JUMP_COND_SHRD);
1833c6415a60SCatalin Vasile 
1834c6415a60SCatalin Vasile 	/* Load class1 key only */
1835c6415a60SCatalin Vasile 	append_key_as_imm(desc, (void *)ctx->key, ctx->enckeylen,
1836c6415a60SCatalin Vasile 			  ctx->enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
1837c6415a60SCatalin Vasile 
1838c6415a60SCatalin Vasile 	/* Load sector size with index 40 bytes (0x28) */
1839c6415a60SCatalin Vasile 	append_cmd(desc, CMD_LOAD | IMMEDIATE | LDST_SRCDST_BYTE_CONTEXT |
1840c6415a60SCatalin Vasile 		   LDST_CLASS_1_CCB | (0x28 << LDST_OFFSET_SHIFT) | 8);
1841c6415a60SCatalin Vasile 	append_data(desc, (void *)&sector_size, 8);
1842c6415a60SCatalin Vasile 
1843c6415a60SCatalin Vasile 	set_jump_tgt_here(desc, key_jump_cmd);
1844c6415a60SCatalin Vasile 
1845c6415a60SCatalin Vasile 	/*
1846c6415a60SCatalin Vasile 	 * create sequence for loading the sector index
1847c6415a60SCatalin Vasile 	 * Upper 8B of IV - will be used as sector index
1848c6415a60SCatalin Vasile 	 * Lower 8B of IV - will be discarded
1849c6415a60SCatalin Vasile 	 */
1850c6415a60SCatalin Vasile 	append_cmd(desc, CMD_SEQ_LOAD | LDST_SRCDST_BYTE_CONTEXT |
1851c6415a60SCatalin Vasile 		   LDST_CLASS_1_CCB | (0x20 << LDST_OFFSET_SHIFT) | 8);
1852c6415a60SCatalin Vasile 	append_seq_fifo_load(desc, 8, FIFOLD_CLASS_SKIP);
1853c6415a60SCatalin Vasile 
1854c6415a60SCatalin Vasile 	/* Load operation */
1855c6415a60SCatalin Vasile 	append_dec_op1(desc, ctx->class1_alg_type);
1856c6415a60SCatalin Vasile 
1857c6415a60SCatalin Vasile 	/* Perform operation */
1858c6415a60SCatalin Vasile 	ablkcipher_append_src_dst(desc);
1859c6415a60SCatalin Vasile 
1860c6415a60SCatalin Vasile 	ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc, desc_bytes(desc),
1861c6415a60SCatalin Vasile 					      DMA_TO_DEVICE);
1862c6415a60SCatalin Vasile 	if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
1863c6415a60SCatalin Vasile 		dma_unmap_single(jrdev, ctx->sh_desc_enc_dma,
1864c6415a60SCatalin Vasile 				 desc_bytes(ctx->sh_desc_enc), DMA_TO_DEVICE);
1865c6415a60SCatalin Vasile 		dev_err(jrdev, "unable to map shared descriptor\n");
1866c6415a60SCatalin Vasile 		return -ENOMEM;
1867c6415a60SCatalin Vasile 	}
1868c6415a60SCatalin Vasile #ifdef DEBUG
1869c6415a60SCatalin Vasile 	print_hex_dump(KERN_ERR,
1870c6415a60SCatalin Vasile 		       "xts ablkcipher dec shdesc@" __stringify(__LINE__) ": ",
1871c6415a60SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc), 1);
1872c6415a60SCatalin Vasile #endif
1873c6415a60SCatalin Vasile 
1874c6415a60SCatalin Vasile 	return 0;
1875c6415a60SCatalin Vasile }
1876c6415a60SCatalin Vasile 
18778e8ec596SKim Phillips /*
18781acebad3SYuan Kang  * aead_edesc - s/w-extended aead descriptor
18791acebad3SYuan Kang  * @assoc_nents: number of segments in associated data (SPI+Seq) scatterlist
18808e8ec596SKim Phillips  * @src_nents: number of segments in input scatterlist
18818e8ec596SKim Phillips  * @dst_nents: number of segments in output scatterlist
18821acebad3SYuan Kang  * @iv_dma: dma address of iv for checking continuity and link table
18838e8ec596SKim Phillips  * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE)
1884a299c837SYuan Kang  * @sec4_sg_bytes: length of dma mapped sec4_sg space
1885a299c837SYuan Kang  * @sec4_sg_dma: bus physical mapped address of h/w link table
18868e8ec596SKim Phillips  * @hw_desc: the h/w job descriptor followed by any referenced link tables
18878e8ec596SKim Phillips  */
18880e479300SYuan Kang struct aead_edesc {
18898e8ec596SKim Phillips 	int assoc_nents;
18908e8ec596SKim Phillips 	int src_nents;
18918e8ec596SKim Phillips 	int dst_nents;
18921acebad3SYuan Kang 	dma_addr_t iv_dma;
1893a299c837SYuan Kang 	int sec4_sg_bytes;
1894a299c837SYuan Kang 	dma_addr_t sec4_sg_dma;
1895a299c837SYuan Kang 	struct sec4_sg_entry *sec4_sg;
1896f2147b88SHerbert Xu 	u32 hw_desc[];
18978e8ec596SKim Phillips };
18988e8ec596SKim Phillips 
1899acdca31dSYuan Kang /*
1900acdca31dSYuan Kang  * ablkcipher_edesc - s/w-extended ablkcipher descriptor
1901acdca31dSYuan Kang  * @src_nents: number of segments in input scatterlist
1902acdca31dSYuan Kang  * @dst_nents: number of segments in output scatterlist
1903acdca31dSYuan Kang  * @iv_dma: dma address of iv for checking continuity and link table
1904acdca31dSYuan Kang  * @desc: h/w descriptor (variable length; must not exceed MAX_CAAM_DESCSIZE)
1905a299c837SYuan Kang  * @sec4_sg_bytes: length of dma mapped sec4_sg space
1906a299c837SYuan Kang  * @sec4_sg_dma: bus physical mapped address of h/w link table
1907acdca31dSYuan Kang  * @hw_desc: the h/w job descriptor followed by any referenced link tables
1908acdca31dSYuan Kang  */
1909acdca31dSYuan Kang struct ablkcipher_edesc {
1910acdca31dSYuan Kang 	int src_nents;
1911acdca31dSYuan Kang 	int dst_nents;
1912acdca31dSYuan Kang 	dma_addr_t iv_dma;
1913a299c837SYuan Kang 	int sec4_sg_bytes;
1914a299c837SYuan Kang 	dma_addr_t sec4_sg_dma;
1915a299c837SYuan Kang 	struct sec4_sg_entry *sec4_sg;
1916acdca31dSYuan Kang 	u32 hw_desc[0];
1917acdca31dSYuan Kang };
1918acdca31dSYuan Kang 
19191acebad3SYuan Kang static void caam_unmap(struct device *dev, struct scatterlist *src,
1920643b39b0SYuan Kang 		       struct scatterlist *dst, int src_nents,
192113fb8fd7SLABBE Corentin 		       int dst_nents,
1922a299c837SYuan Kang 		       dma_addr_t iv_dma, int ivsize, dma_addr_t sec4_sg_dma,
1923a299c837SYuan Kang 		       int sec4_sg_bytes)
19241acebad3SYuan Kang {
1925643b39b0SYuan Kang 	if (dst != src) {
192613fb8fd7SLABBE Corentin 		dma_unmap_sg(dev, src, src_nents ? : 1, DMA_TO_DEVICE);
192713fb8fd7SLABBE Corentin 		dma_unmap_sg(dev, dst, dst_nents ? : 1, DMA_FROM_DEVICE);
19281acebad3SYuan Kang 	} else {
192913fb8fd7SLABBE Corentin 		dma_unmap_sg(dev, src, src_nents ? : 1, DMA_BIDIRECTIONAL);
19301acebad3SYuan Kang 	}
19311acebad3SYuan Kang 
19321acebad3SYuan Kang 	if (iv_dma)
19331acebad3SYuan Kang 		dma_unmap_single(dev, iv_dma, ivsize, DMA_TO_DEVICE);
1934a299c837SYuan Kang 	if (sec4_sg_bytes)
1935a299c837SYuan Kang 		dma_unmap_single(dev, sec4_sg_dma, sec4_sg_bytes,
19361acebad3SYuan Kang 				 DMA_TO_DEVICE);
19371acebad3SYuan Kang }
19381acebad3SYuan Kang 
19390e479300SYuan Kang static void aead_unmap(struct device *dev,
19400e479300SYuan Kang 		       struct aead_edesc *edesc,
19410e479300SYuan Kang 		       struct aead_request *req)
19428e8ec596SKim Phillips {
1943f2147b88SHerbert Xu 	caam_unmap(dev, req->src, req->dst,
194413fb8fd7SLABBE Corentin 		   edesc->src_nents, edesc->dst_nents, 0, 0,
1945f2147b88SHerbert Xu 		   edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
1946f2147b88SHerbert Xu }
1947f2147b88SHerbert Xu 
1948acdca31dSYuan Kang static void ablkcipher_unmap(struct device *dev,
1949acdca31dSYuan Kang 			     struct ablkcipher_edesc *edesc,
1950acdca31dSYuan Kang 			     struct ablkcipher_request *req)
1951acdca31dSYuan Kang {
1952acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
1953acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
1954acdca31dSYuan Kang 
1955acdca31dSYuan Kang 	caam_unmap(dev, req->src, req->dst,
195613fb8fd7SLABBE Corentin 		   edesc->src_nents, edesc->dst_nents,
195713fb8fd7SLABBE Corentin 		   edesc->iv_dma, ivsize,
1958643b39b0SYuan Kang 		   edesc->sec4_sg_dma, edesc->sec4_sg_bytes);
1959acdca31dSYuan Kang }
1960acdca31dSYuan Kang 
19610e479300SYuan Kang static void aead_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
19628e8ec596SKim Phillips 				   void *context)
19638e8ec596SKim Phillips {
19640e479300SYuan Kang 	struct aead_request *req = context;
19650e479300SYuan Kang 	struct aead_edesc *edesc;
1966f2147b88SHerbert Xu 
1967f2147b88SHerbert Xu #ifdef DEBUG
1968f2147b88SHerbert Xu 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
1969f2147b88SHerbert Xu #endif
1970f2147b88SHerbert Xu 
1971f2147b88SHerbert Xu 	edesc = container_of(desc, struct aead_edesc, hw_desc[0]);
1972f2147b88SHerbert Xu 
1973f2147b88SHerbert Xu 	if (err)
1974f2147b88SHerbert Xu 		caam_jr_strstatus(jrdev, err);
1975f2147b88SHerbert Xu 
1976f2147b88SHerbert Xu 	aead_unmap(jrdev, edesc, req);
1977f2147b88SHerbert Xu 
1978f2147b88SHerbert Xu 	kfree(edesc);
1979f2147b88SHerbert Xu 
1980f2147b88SHerbert Xu 	aead_request_complete(req, err);
1981f2147b88SHerbert Xu }
1982f2147b88SHerbert Xu 
19830e479300SYuan Kang static void aead_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
19848e8ec596SKim Phillips 				   void *context)
19858e8ec596SKim Phillips {
19860e479300SYuan Kang 	struct aead_request *req = context;
19870e479300SYuan Kang 	struct aead_edesc *edesc;
1988f2147b88SHerbert Xu 
1989f2147b88SHerbert Xu #ifdef DEBUG
1990f2147b88SHerbert Xu 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
1991f2147b88SHerbert Xu #endif
1992f2147b88SHerbert Xu 
1993f2147b88SHerbert Xu 	edesc = container_of(desc, struct aead_edesc, hw_desc[0]);
1994f2147b88SHerbert Xu 
1995f2147b88SHerbert Xu 	if (err)
1996f2147b88SHerbert Xu 		caam_jr_strstatus(jrdev, err);
1997f2147b88SHerbert Xu 
1998f2147b88SHerbert Xu 	aead_unmap(jrdev, edesc, req);
1999f2147b88SHerbert Xu 
2000f2147b88SHerbert Xu 	/*
2001f2147b88SHerbert Xu 	 * verify hw auth check passed else return -EBADMSG
2002f2147b88SHerbert Xu 	 */
2003f2147b88SHerbert Xu 	if ((err & JRSTA_CCBERR_ERRID_MASK) == JRSTA_CCBERR_ERRID_ICVCHK)
2004f2147b88SHerbert Xu 		err = -EBADMSG;
2005f2147b88SHerbert Xu 
2006f2147b88SHerbert Xu 	kfree(edesc);
2007f2147b88SHerbert Xu 
2008f2147b88SHerbert Xu 	aead_request_complete(req, err);
2009f2147b88SHerbert Xu }
2010f2147b88SHerbert Xu 
2011acdca31dSYuan Kang static void ablkcipher_encrypt_done(struct device *jrdev, u32 *desc, u32 err,
2012acdca31dSYuan Kang 				   void *context)
2013acdca31dSYuan Kang {
2014acdca31dSYuan Kang 	struct ablkcipher_request *req = context;
2015acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
2016acdca31dSYuan Kang #ifdef DEBUG
2017acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
2018acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
2019acdca31dSYuan Kang 
2020acdca31dSYuan Kang 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
2021acdca31dSYuan Kang #endif
2022acdca31dSYuan Kang 
2023acdca31dSYuan Kang 	edesc = (struct ablkcipher_edesc *)((char *)desc -
2024acdca31dSYuan Kang 		 offsetof(struct ablkcipher_edesc, hw_desc));
2025acdca31dSYuan Kang 
2026fa9659cdSMarek Vasut 	if (err)
2027fa9659cdSMarek Vasut 		caam_jr_strstatus(jrdev, err);
2028acdca31dSYuan Kang 
2029acdca31dSYuan Kang #ifdef DEBUG
2030514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dstiv  @"__stringify(__LINE__)": ",
2031acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
2032acdca31dSYuan Kang 		       edesc->src_nents > 1 ? 100 : ivsize, 1);
20335ecf8ef9SCatalin Vasile 	dbg_dump_sg(KERN_ERR, "dst    @"__stringify(__LINE__)": ",
20345ecf8ef9SCatalin Vasile 		    DUMP_PREFIX_ADDRESS, 16, 4, req->dst,
203500fef2b2SHoria Geantă 		    edesc->dst_nents > 1 ? 100 : req->nbytes, 1);
2036acdca31dSYuan Kang #endif
2037acdca31dSYuan Kang 
2038acdca31dSYuan Kang 	ablkcipher_unmap(jrdev, edesc, req);
2039acdca31dSYuan Kang 	kfree(edesc);
2040acdca31dSYuan Kang 
2041acdca31dSYuan Kang 	ablkcipher_request_complete(req, err);
2042acdca31dSYuan Kang }
2043acdca31dSYuan Kang 
2044acdca31dSYuan Kang static void ablkcipher_decrypt_done(struct device *jrdev, u32 *desc, u32 err,
2045acdca31dSYuan Kang 				    void *context)
2046acdca31dSYuan Kang {
2047acdca31dSYuan Kang 	struct ablkcipher_request *req = context;
2048acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
2049acdca31dSYuan Kang #ifdef DEBUG
2050acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
2051acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
2052acdca31dSYuan Kang 
2053acdca31dSYuan Kang 	dev_err(jrdev, "%s %d: err 0x%x\n", __func__, __LINE__, err);
2054acdca31dSYuan Kang #endif
2055acdca31dSYuan Kang 
2056acdca31dSYuan Kang 	edesc = (struct ablkcipher_edesc *)((char *)desc -
2057acdca31dSYuan Kang 		 offsetof(struct ablkcipher_edesc, hw_desc));
2058fa9659cdSMarek Vasut 	if (err)
2059fa9659cdSMarek Vasut 		caam_jr_strstatus(jrdev, err);
2060acdca31dSYuan Kang 
2061acdca31dSYuan Kang #ifdef DEBUG
2062514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "dstiv  @"__stringify(__LINE__)": ",
2063acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
2064acdca31dSYuan Kang 		       ivsize, 1);
20655ecf8ef9SCatalin Vasile 	dbg_dump_sg(KERN_ERR, "dst    @"__stringify(__LINE__)": ",
20665ecf8ef9SCatalin Vasile 		    DUMP_PREFIX_ADDRESS, 16, 4, req->dst,
206700fef2b2SHoria Geantă 		    edesc->dst_nents > 1 ? 100 : req->nbytes, 1);
2068acdca31dSYuan Kang #endif
2069acdca31dSYuan Kang 
2070acdca31dSYuan Kang 	ablkcipher_unmap(jrdev, edesc, req);
2071acdca31dSYuan Kang 	kfree(edesc);
2072acdca31dSYuan Kang 
2073acdca31dSYuan Kang 	ablkcipher_request_complete(req, err);
2074acdca31dSYuan Kang }
2075acdca31dSYuan Kang 
20768e8ec596SKim Phillips /*
20771acebad3SYuan Kang  * Fill in aead job descriptor
20788e8ec596SKim Phillips  */
2079f2147b88SHerbert Xu static void init_aead_job(struct aead_request *req,
2080f2147b88SHerbert Xu 			  struct aead_edesc *edesc,
2081f2147b88SHerbert Xu 			  bool all_contig, bool encrypt)
2082f2147b88SHerbert Xu {
2083f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
2084f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
2085f2147b88SHerbert Xu 	int authsize = ctx->authsize;
2086f2147b88SHerbert Xu 	u32 *desc = edesc->hw_desc;
2087f2147b88SHerbert Xu 	u32 out_options, in_options;
2088f2147b88SHerbert Xu 	dma_addr_t dst_dma, src_dma;
2089f2147b88SHerbert Xu 	int len, sec4_sg_index = 0;
2090f2147b88SHerbert Xu 	dma_addr_t ptr;
2091f2147b88SHerbert Xu 	u32 *sh_desc;
2092f2147b88SHerbert Xu 
2093f2147b88SHerbert Xu 	sh_desc = encrypt ? ctx->sh_desc_enc : ctx->sh_desc_dec;
2094f2147b88SHerbert Xu 	ptr = encrypt ? ctx->sh_desc_enc_dma : ctx->sh_desc_dec_dma;
2095f2147b88SHerbert Xu 
2096f2147b88SHerbert Xu 	len = desc_len(sh_desc);
2097f2147b88SHerbert Xu 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
2098f2147b88SHerbert Xu 
2099f2147b88SHerbert Xu 	if (all_contig) {
2100f2147b88SHerbert Xu 		src_dma = sg_dma_address(req->src);
2101f2147b88SHerbert Xu 		in_options = 0;
2102f2147b88SHerbert Xu 	} else {
2103f2147b88SHerbert Xu 		src_dma = edesc->sec4_sg_dma;
2104f2147b88SHerbert Xu 		sec4_sg_index += edesc->src_nents;
2105f2147b88SHerbert Xu 		in_options = LDST_SGF;
2106f2147b88SHerbert Xu 	}
2107f2147b88SHerbert Xu 
2108f2147b88SHerbert Xu 	append_seq_in_ptr(desc, src_dma, req->assoclen + req->cryptlen,
2109f2147b88SHerbert Xu 			  in_options);
2110f2147b88SHerbert Xu 
2111f2147b88SHerbert Xu 	dst_dma = src_dma;
2112f2147b88SHerbert Xu 	out_options = in_options;
2113f2147b88SHerbert Xu 
2114f2147b88SHerbert Xu 	if (unlikely(req->src != req->dst)) {
2115f2147b88SHerbert Xu 		if (!edesc->dst_nents) {
2116f2147b88SHerbert Xu 			dst_dma = sg_dma_address(req->dst);
2117f2147b88SHerbert Xu 		} else {
2118f2147b88SHerbert Xu 			dst_dma = edesc->sec4_sg_dma +
2119f2147b88SHerbert Xu 				  sec4_sg_index *
2120f2147b88SHerbert Xu 				  sizeof(struct sec4_sg_entry);
2121f2147b88SHerbert Xu 			out_options = LDST_SGF;
2122f2147b88SHerbert Xu 		}
2123f2147b88SHerbert Xu 	}
2124f2147b88SHerbert Xu 
2125f2147b88SHerbert Xu 	if (encrypt)
2126f2147b88SHerbert Xu 		append_seq_out_ptr(desc, dst_dma,
2127f2147b88SHerbert Xu 				   req->assoclen + req->cryptlen + authsize,
2128f2147b88SHerbert Xu 				   out_options);
2129f2147b88SHerbert Xu 	else
2130f2147b88SHerbert Xu 		append_seq_out_ptr(desc, dst_dma,
2131f2147b88SHerbert Xu 				   req->assoclen + req->cryptlen - authsize,
2132f2147b88SHerbert Xu 				   out_options);
2133f2147b88SHerbert Xu 
2134f2147b88SHerbert Xu 	/* REG3 = assoclen */
2135f2147b88SHerbert Xu 	append_math_add_imm_u32(desc, REG3, ZERO, IMM, req->assoclen);
2136f2147b88SHerbert Xu }
2137f2147b88SHerbert Xu 
2138f2147b88SHerbert Xu static void init_gcm_job(struct aead_request *req,
2139f2147b88SHerbert Xu 			 struct aead_edesc *edesc,
2140f2147b88SHerbert Xu 			 bool all_contig, bool encrypt)
2141f2147b88SHerbert Xu {
2142f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
2143f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
2144f2147b88SHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
2145f2147b88SHerbert Xu 	u32 *desc = edesc->hw_desc;
2146f2147b88SHerbert Xu 	bool generic_gcm = (ivsize == 12);
2147f2147b88SHerbert Xu 	unsigned int last;
2148f2147b88SHerbert Xu 
2149f2147b88SHerbert Xu 	init_aead_job(req, edesc, all_contig, encrypt);
2150f2147b88SHerbert Xu 
2151f2147b88SHerbert Xu 	/* BUG This should not be specific to generic GCM. */
2152f2147b88SHerbert Xu 	last = 0;
2153f2147b88SHerbert Xu 	if (encrypt && generic_gcm && !(req->assoclen + req->cryptlen))
2154f2147b88SHerbert Xu 		last = FIFOLD_TYPE_LAST1;
2155f2147b88SHerbert Xu 
2156f2147b88SHerbert Xu 	/* Read GCM IV */
2157f2147b88SHerbert Xu 	append_cmd(desc, CMD_FIFO_LOAD | FIFOLD_CLASS_CLASS1 | IMMEDIATE |
2158f2147b88SHerbert Xu 			 FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 | 12 | last);
2159f2147b88SHerbert Xu 	/* Append Salt */
2160f2147b88SHerbert Xu 	if (!generic_gcm)
2161f2147b88SHerbert Xu 		append_data(desc, ctx->key + ctx->enckeylen, 4);
2162f2147b88SHerbert Xu 	/* Append IV */
2163f2147b88SHerbert Xu 	append_data(desc, req->iv, ivsize);
2164f2147b88SHerbert Xu 	/* End of blank commands */
2165f2147b88SHerbert Xu }
2166f2147b88SHerbert Xu 
2167479bcc7cSHerbert Xu static void init_authenc_job(struct aead_request *req,
21681acebad3SYuan Kang 			     struct aead_edesc *edesc,
2169479bcc7cSHerbert Xu 			     bool all_contig, bool encrypt)
21701acebad3SYuan Kang {
21711acebad3SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
2172479bcc7cSHerbert Xu 	struct caam_aead_alg *alg = container_of(crypto_aead_alg(aead),
2173479bcc7cSHerbert Xu 						 struct caam_aead_alg, aead);
2174479bcc7cSHerbert Xu 	unsigned int ivsize = crypto_aead_ivsize(aead);
21751acebad3SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
2176479bcc7cSHerbert Xu 	const bool ctr_mode = ((ctx->class1_alg_type & OP_ALG_AAI_MASK) ==
2177479bcc7cSHerbert Xu 			       OP_ALG_AAI_CTR_MOD128);
2178479bcc7cSHerbert Xu 	const bool is_rfc3686 = alg->caam.rfc3686;
21791acebad3SYuan Kang 	u32 *desc = edesc->hw_desc;
2180479bcc7cSHerbert Xu 	u32 ivoffset = 0;
21818e8ec596SKim Phillips 
2182479bcc7cSHerbert Xu 	/*
2183479bcc7cSHerbert Xu 	 * AES-CTR needs to load IV in CONTEXT1 reg
2184479bcc7cSHerbert Xu 	 * at an offset of 128bits (16bytes)
2185479bcc7cSHerbert Xu 	 * CONTEXT1[255:128] = IV
2186479bcc7cSHerbert Xu 	 */
2187479bcc7cSHerbert Xu 	if (ctr_mode)
2188479bcc7cSHerbert Xu 		ivoffset = 16;
21898e8ec596SKim Phillips 
2190479bcc7cSHerbert Xu 	/*
2191479bcc7cSHerbert Xu 	 * RFC3686 specific:
2192479bcc7cSHerbert Xu 	 *	CONTEXT1[255:128] = {NONCE, IV, COUNTER}
2193479bcc7cSHerbert Xu 	 */
2194479bcc7cSHerbert Xu 	if (is_rfc3686)
2195479bcc7cSHerbert Xu 		ivoffset = 16 + CTR_RFC3686_NONCE_SIZE;
2196bac68f2cSTudor Ambarus 
2197479bcc7cSHerbert Xu 	init_aead_job(req, edesc, all_contig, encrypt);
21981acebad3SYuan Kang 
21998b18e235SHoria Geantă 	if (ivsize && ((is_rfc3686 && encrypt) || !alg->caam.geniv))
2200479bcc7cSHerbert Xu 		append_load_as_imm(desc, req->iv, ivsize,
2201479bcc7cSHerbert Xu 				   LDST_CLASS_1_CCB |
2202479bcc7cSHerbert Xu 				   LDST_SRCDST_BYTE_CONTEXT |
2203479bcc7cSHerbert Xu 				   (ivoffset << LDST_OFFSET_SHIFT));
22048e8ec596SKim Phillips }
22058e8ec596SKim Phillips 
22068e8ec596SKim Phillips /*
2207acdca31dSYuan Kang  * Fill in ablkcipher job descriptor
2208acdca31dSYuan Kang  */
2209acdca31dSYuan Kang static void init_ablkcipher_job(u32 *sh_desc, dma_addr_t ptr,
2210acdca31dSYuan Kang 				struct ablkcipher_edesc *edesc,
2211acdca31dSYuan Kang 				struct ablkcipher_request *req,
2212acdca31dSYuan Kang 				bool iv_contig)
2213acdca31dSYuan Kang {
2214acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
2215acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
2216acdca31dSYuan Kang 	u32 *desc = edesc->hw_desc;
2217acdca31dSYuan Kang 	u32 out_options = 0, in_options;
2218acdca31dSYuan Kang 	dma_addr_t dst_dma, src_dma;
2219a299c837SYuan Kang 	int len, sec4_sg_index = 0;
2220acdca31dSYuan Kang 
2221acdca31dSYuan Kang #ifdef DEBUG
2222514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "presciv@"__stringify(__LINE__)": ",
2223acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
2224acdca31dSYuan Kang 		       ivsize, 1);
22255ecf8ef9SCatalin Vasile 	printk(KERN_ERR "asked=%d, nbytes%d\n", (int)edesc->src_nents ? 100 : req->nbytes, req->nbytes);
22265ecf8ef9SCatalin Vasile 	dbg_dump_sg(KERN_ERR, "src    @"__stringify(__LINE__)": ",
22275ecf8ef9SCatalin Vasile 		    DUMP_PREFIX_ADDRESS, 16, 4, req->src,
222800fef2b2SHoria Geantă 		    edesc->src_nents ? 100 : req->nbytes, 1);
2229acdca31dSYuan Kang #endif
2230acdca31dSYuan Kang 
2231acdca31dSYuan Kang 	len = desc_len(sh_desc);
2232acdca31dSYuan Kang 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
2233acdca31dSYuan Kang 
2234acdca31dSYuan Kang 	if (iv_contig) {
2235acdca31dSYuan Kang 		src_dma = edesc->iv_dma;
2236acdca31dSYuan Kang 		in_options = 0;
2237acdca31dSYuan Kang 	} else {
2238a299c837SYuan Kang 		src_dma = edesc->sec4_sg_dma;
223935b82e55SCristian Stoica 		sec4_sg_index += edesc->src_nents + 1;
2240acdca31dSYuan Kang 		in_options = LDST_SGF;
2241acdca31dSYuan Kang 	}
2242acdca31dSYuan Kang 	append_seq_in_ptr(desc, src_dma, req->nbytes + ivsize, in_options);
2243acdca31dSYuan Kang 
2244acdca31dSYuan Kang 	if (likely(req->src == req->dst)) {
2245acdca31dSYuan Kang 		if (!edesc->src_nents && iv_contig) {
2246acdca31dSYuan Kang 			dst_dma = sg_dma_address(req->src);
2247acdca31dSYuan Kang 		} else {
2248a299c837SYuan Kang 			dst_dma = edesc->sec4_sg_dma +
2249a299c837SYuan Kang 				sizeof(struct sec4_sg_entry);
2250acdca31dSYuan Kang 			out_options = LDST_SGF;
2251acdca31dSYuan Kang 		}
2252acdca31dSYuan Kang 	} else {
2253acdca31dSYuan Kang 		if (!edesc->dst_nents) {
2254acdca31dSYuan Kang 			dst_dma = sg_dma_address(req->dst);
2255acdca31dSYuan Kang 		} else {
2256a299c837SYuan Kang 			dst_dma = edesc->sec4_sg_dma +
2257a299c837SYuan Kang 				sec4_sg_index * sizeof(struct sec4_sg_entry);
2258acdca31dSYuan Kang 			out_options = LDST_SGF;
2259acdca31dSYuan Kang 		}
2260acdca31dSYuan Kang 	}
2261acdca31dSYuan Kang 	append_seq_out_ptr(desc, dst_dma, req->nbytes, out_options);
2262acdca31dSYuan Kang }
2263acdca31dSYuan Kang 
2264acdca31dSYuan Kang /*
22657222d1a3SCatalin Vasile  * Fill in ablkcipher givencrypt job descriptor
22667222d1a3SCatalin Vasile  */
22677222d1a3SCatalin Vasile static void init_ablkcipher_giv_job(u32 *sh_desc, dma_addr_t ptr,
22687222d1a3SCatalin Vasile 				    struct ablkcipher_edesc *edesc,
22697222d1a3SCatalin Vasile 				    struct ablkcipher_request *req,
22707222d1a3SCatalin Vasile 				    bool iv_contig)
22717222d1a3SCatalin Vasile {
22727222d1a3SCatalin Vasile 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
22737222d1a3SCatalin Vasile 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
22747222d1a3SCatalin Vasile 	u32 *desc = edesc->hw_desc;
22757222d1a3SCatalin Vasile 	u32 out_options, in_options;
22767222d1a3SCatalin Vasile 	dma_addr_t dst_dma, src_dma;
22777222d1a3SCatalin Vasile 	int len, sec4_sg_index = 0;
22787222d1a3SCatalin Vasile 
22797222d1a3SCatalin Vasile #ifdef DEBUG
22807222d1a3SCatalin Vasile 	print_hex_dump(KERN_ERR, "presciv@" __stringify(__LINE__) ": ",
22817222d1a3SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, req->info,
22827222d1a3SCatalin Vasile 		       ivsize, 1);
22835ecf8ef9SCatalin Vasile 	dbg_dump_sg(KERN_ERR, "src    @" __stringify(__LINE__) ": ",
22845ecf8ef9SCatalin Vasile 		    DUMP_PREFIX_ADDRESS, 16, 4, req->src,
228500fef2b2SHoria Geantă 		    edesc->src_nents ? 100 : req->nbytes, 1);
22867222d1a3SCatalin Vasile #endif
22877222d1a3SCatalin Vasile 
22887222d1a3SCatalin Vasile 	len = desc_len(sh_desc);
22897222d1a3SCatalin Vasile 	init_job_desc_shared(desc, ptr, len, HDR_SHARE_DEFER | HDR_REVERSE);
22907222d1a3SCatalin Vasile 
22917222d1a3SCatalin Vasile 	if (!edesc->src_nents) {
22927222d1a3SCatalin Vasile 		src_dma = sg_dma_address(req->src);
22937222d1a3SCatalin Vasile 		in_options = 0;
22947222d1a3SCatalin Vasile 	} else {
22957222d1a3SCatalin Vasile 		src_dma = edesc->sec4_sg_dma;
22967222d1a3SCatalin Vasile 		sec4_sg_index += edesc->src_nents;
22977222d1a3SCatalin Vasile 		in_options = LDST_SGF;
22987222d1a3SCatalin Vasile 	}
22997222d1a3SCatalin Vasile 	append_seq_in_ptr(desc, src_dma, req->nbytes, in_options);
23007222d1a3SCatalin Vasile 
23017222d1a3SCatalin Vasile 	if (iv_contig) {
23027222d1a3SCatalin Vasile 		dst_dma = edesc->iv_dma;
23037222d1a3SCatalin Vasile 		out_options = 0;
23047222d1a3SCatalin Vasile 	} else {
23057222d1a3SCatalin Vasile 		dst_dma = edesc->sec4_sg_dma +
23067222d1a3SCatalin Vasile 			  sec4_sg_index * sizeof(struct sec4_sg_entry);
23077222d1a3SCatalin Vasile 		out_options = LDST_SGF;
23087222d1a3SCatalin Vasile 	}
23097222d1a3SCatalin Vasile 	append_seq_out_ptr(desc, dst_dma, req->nbytes + ivsize, out_options);
23107222d1a3SCatalin Vasile }
23117222d1a3SCatalin Vasile 
23127222d1a3SCatalin Vasile /*
23131acebad3SYuan Kang  * allocate and map the aead extended descriptor
23148e8ec596SKim Phillips  */
2315f2147b88SHerbert Xu static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
2316f2147b88SHerbert Xu 					   int desc_bytes, bool *all_contig_ptr,
2317f2147b88SHerbert Xu 					   bool encrypt)
2318f2147b88SHerbert Xu {
2319f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
2320f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
2321f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
2322f2147b88SHerbert Xu 	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
2323f2147b88SHerbert Xu 		       CRYPTO_TFM_REQ_MAY_SLEEP)) ? GFP_KERNEL : GFP_ATOMIC;
2324f2147b88SHerbert Xu 	int src_nents, dst_nents = 0;
2325f2147b88SHerbert Xu 	struct aead_edesc *edesc;
2326f2147b88SHerbert Xu 	int sgc;
2327f2147b88SHerbert Xu 	bool all_contig = true;
2328f2147b88SHerbert Xu 	int sec4_sg_index, sec4_sg_len = 0, sec4_sg_bytes;
2329f2147b88SHerbert Xu 	unsigned int authsize = ctx->authsize;
2330f2147b88SHerbert Xu 
2331f2147b88SHerbert Xu 	if (unlikely(req->dst != req->src)) {
233213fb8fd7SLABBE Corentin 		src_nents = sg_count(req->src, req->assoclen + req->cryptlen);
2333f2147b88SHerbert Xu 		dst_nents = sg_count(req->dst,
2334f2147b88SHerbert Xu 				     req->assoclen + req->cryptlen +
233513fb8fd7SLABBE Corentin 					(encrypt ? authsize : (-authsize)));
2336f2147b88SHerbert Xu 	} else {
2337f2147b88SHerbert Xu 		src_nents = sg_count(req->src,
2338f2147b88SHerbert Xu 				     req->assoclen + req->cryptlen +
233913fb8fd7SLABBE Corentin 					(encrypt ? authsize : 0));
2340f2147b88SHerbert Xu 	}
2341f2147b88SHerbert Xu 
2342f2147b88SHerbert Xu 	/* Check if data are contiguous. */
2343f2147b88SHerbert Xu 	all_contig = !src_nents;
2344c530e341SHoria Geantă 	if (!all_contig)
2345f2147b88SHerbert Xu 		sec4_sg_len = src_nents;
2346f2147b88SHerbert Xu 
2347f2147b88SHerbert Xu 	sec4_sg_len += dst_nents;
2348f2147b88SHerbert Xu 
2349f2147b88SHerbert Xu 	sec4_sg_bytes = sec4_sg_len * sizeof(struct sec4_sg_entry);
2350f2147b88SHerbert Xu 
2351f2147b88SHerbert Xu 	/* allocate space for base edesc and hw desc commands, link tables */
2352dde20ae9SVictoria Milhoan 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes,
2353dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
2354f2147b88SHerbert Xu 	if (!edesc) {
2355f2147b88SHerbert Xu 		dev_err(jrdev, "could not allocate extended descriptor\n");
2356f2147b88SHerbert Xu 		return ERR_PTR(-ENOMEM);
2357f2147b88SHerbert Xu 	}
2358f2147b88SHerbert Xu 
2359f2147b88SHerbert Xu 	if (likely(req->src == req->dst)) {
236013fb8fd7SLABBE Corentin 		sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1,
236113fb8fd7SLABBE Corentin 				 DMA_BIDIRECTIONAL);
2362f2147b88SHerbert Xu 		if (unlikely(!sgc)) {
2363f2147b88SHerbert Xu 			dev_err(jrdev, "unable to map source\n");
2364f2147b88SHerbert Xu 			kfree(edesc);
2365f2147b88SHerbert Xu 			return ERR_PTR(-ENOMEM);
2366f2147b88SHerbert Xu 		}
2367f2147b88SHerbert Xu 	} else {
236813fb8fd7SLABBE Corentin 		sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1,
236913fb8fd7SLABBE Corentin 				 DMA_TO_DEVICE);
2370f2147b88SHerbert Xu 		if (unlikely(!sgc)) {
2371f2147b88SHerbert Xu 			dev_err(jrdev, "unable to map source\n");
2372f2147b88SHerbert Xu 			kfree(edesc);
2373f2147b88SHerbert Xu 			return ERR_PTR(-ENOMEM);
2374f2147b88SHerbert Xu 		}
2375f2147b88SHerbert Xu 
237613fb8fd7SLABBE Corentin 		sgc = dma_map_sg(jrdev, req->dst, dst_nents ? : 1,
237713fb8fd7SLABBE Corentin 				 DMA_FROM_DEVICE);
2378f2147b88SHerbert Xu 		if (unlikely(!sgc)) {
2379f2147b88SHerbert Xu 			dev_err(jrdev, "unable to map destination\n");
238013fb8fd7SLABBE Corentin 			dma_unmap_sg(jrdev, req->src, src_nents ? : 1,
238113fb8fd7SLABBE Corentin 				     DMA_TO_DEVICE);
2382f2147b88SHerbert Xu 			kfree(edesc);
2383f2147b88SHerbert Xu 			return ERR_PTR(-ENOMEM);
2384f2147b88SHerbert Xu 		}
2385f2147b88SHerbert Xu 	}
2386f2147b88SHerbert Xu 
2387f2147b88SHerbert Xu 	edesc->src_nents = src_nents;
2388f2147b88SHerbert Xu 	edesc->dst_nents = dst_nents;
2389f2147b88SHerbert Xu 	edesc->sec4_sg = (void *)edesc + sizeof(struct aead_edesc) +
2390f2147b88SHerbert Xu 			 desc_bytes;
2391f2147b88SHerbert Xu 	*all_contig_ptr = all_contig;
2392f2147b88SHerbert Xu 
2393f2147b88SHerbert Xu 	sec4_sg_index = 0;
2394f2147b88SHerbert Xu 	if (!all_contig) {
23957793bda8SHerbert Xu 		sg_to_sec4_sg_last(req->src, src_nents,
2396f2147b88SHerbert Xu 			      edesc->sec4_sg + sec4_sg_index, 0);
2397f2147b88SHerbert Xu 		sec4_sg_index += src_nents;
2398f2147b88SHerbert Xu 	}
2399f2147b88SHerbert Xu 	if (dst_nents) {
2400f2147b88SHerbert Xu 		sg_to_sec4_sg_last(req->dst, dst_nents,
2401f2147b88SHerbert Xu 				   edesc->sec4_sg + sec4_sg_index, 0);
2402f2147b88SHerbert Xu 	}
2403f2147b88SHerbert Xu 
2404f2147b88SHerbert Xu 	if (!sec4_sg_bytes)
2405f2147b88SHerbert Xu 		return edesc;
2406f2147b88SHerbert Xu 
2407f2147b88SHerbert Xu 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
2408f2147b88SHerbert Xu 					    sec4_sg_bytes, DMA_TO_DEVICE);
2409f2147b88SHerbert Xu 	if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
2410f2147b88SHerbert Xu 		dev_err(jrdev, "unable to map S/G table\n");
2411f2147b88SHerbert Xu 		aead_unmap(jrdev, edesc, req);
2412f2147b88SHerbert Xu 		kfree(edesc);
2413f2147b88SHerbert Xu 		return ERR_PTR(-ENOMEM);
2414f2147b88SHerbert Xu 	}
2415f2147b88SHerbert Xu 
2416f2147b88SHerbert Xu 	edesc->sec4_sg_bytes = sec4_sg_bytes;
2417f2147b88SHerbert Xu 
2418f2147b88SHerbert Xu 	return edesc;
2419f2147b88SHerbert Xu }
2420f2147b88SHerbert Xu 
2421f2147b88SHerbert Xu static int gcm_encrypt(struct aead_request *req)
24228e8ec596SKim Phillips {
24230e479300SYuan Kang 	struct aead_edesc *edesc;
24248e8ec596SKim Phillips 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
24258e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
24268e8ec596SKim Phillips 	struct device *jrdev = ctx->jrdev;
24271acebad3SYuan Kang 	bool all_contig;
24288e8ec596SKim Phillips 	u32 *desc;
24291acebad3SYuan Kang 	int ret = 0;
24301acebad3SYuan Kang 
24318e8ec596SKim Phillips 	/* allocate extended descriptor */
2432f2147b88SHerbert Xu 	edesc = aead_edesc_alloc(req, GCM_DESC_JOB_IO_LEN, &all_contig, true);
24338e8ec596SKim Phillips 	if (IS_ERR(edesc))
24348e8ec596SKim Phillips 		return PTR_ERR(edesc);
24358e8ec596SKim Phillips 
24361acebad3SYuan Kang 	/* Create and submit job descriptor */
2437f2147b88SHerbert Xu 	init_gcm_job(req, edesc, all_contig, true);
24381acebad3SYuan Kang #ifdef DEBUG
2439514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
24401acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
24411acebad3SYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
24421acebad3SYuan Kang #endif
24431acebad3SYuan Kang 
24448e8ec596SKim Phillips 	desc = edesc->hw_desc;
24451acebad3SYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
24461acebad3SYuan Kang 	if (!ret) {
24471acebad3SYuan Kang 		ret = -EINPROGRESS;
24481acebad3SYuan Kang 	} else {
24491acebad3SYuan Kang 		aead_unmap(jrdev, edesc, req);
24501acebad3SYuan Kang 		kfree(edesc);
24511acebad3SYuan Kang 	}
24528e8ec596SKim Phillips 
24531acebad3SYuan Kang 	return ret;
24548e8ec596SKim Phillips }
24558e8ec596SKim Phillips 
245646218750SHerbert Xu static int ipsec_gcm_encrypt(struct aead_request *req)
245746218750SHerbert Xu {
245846218750SHerbert Xu 	if (req->assoclen < 8)
245946218750SHerbert Xu 		return -EINVAL;
246046218750SHerbert Xu 
246146218750SHerbert Xu 	return gcm_encrypt(req);
246246218750SHerbert Xu }
246346218750SHerbert Xu 
2464479bcc7cSHerbert Xu static int aead_encrypt(struct aead_request *req)
24658e8ec596SKim Phillips {
24661acebad3SYuan Kang 	struct aead_edesc *edesc;
24670e479300SYuan Kang 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
24680e479300SYuan Kang 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
24690e479300SYuan Kang 	struct device *jrdev = ctx->jrdev;
24701acebad3SYuan Kang 	bool all_contig;
24710e479300SYuan Kang 	u32 *desc;
24721acebad3SYuan Kang 	int ret = 0;
24730e479300SYuan Kang 
24740e479300SYuan Kang 	/* allocate extended descriptor */
2475479bcc7cSHerbert Xu 	edesc = aead_edesc_alloc(req, AUTHENC_DESC_JOB_IO_LEN,
2476479bcc7cSHerbert Xu 				 &all_contig, true);
24770e479300SYuan Kang 	if (IS_ERR(edesc))
24780e479300SYuan Kang 		return PTR_ERR(edesc);
24790e479300SYuan Kang 
2480f2147b88SHerbert Xu 	/* Create and submit job descriptor */
2481479bcc7cSHerbert Xu 	init_authenc_job(req, edesc, all_contig, true);
24821acebad3SYuan Kang #ifdef DEBUG
2483f2147b88SHerbert Xu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
2484f2147b88SHerbert Xu 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
2485f2147b88SHerbert Xu 		       desc_bytes(edesc->hw_desc), 1);
24861acebad3SYuan Kang #endif
24871acebad3SYuan Kang 
2488f2147b88SHerbert Xu 	desc = edesc->hw_desc;
2489479bcc7cSHerbert Xu 	ret = caam_jr_enqueue(jrdev, desc, aead_encrypt_done, req);
2490f2147b88SHerbert Xu 	if (!ret) {
2491f2147b88SHerbert Xu 		ret = -EINPROGRESS;
2492f2147b88SHerbert Xu 	} else {
2493479bcc7cSHerbert Xu 		aead_unmap(jrdev, edesc, req);
2494f2147b88SHerbert Xu 		kfree(edesc);
2495f2147b88SHerbert Xu 	}
2496f2147b88SHerbert Xu 
2497f2147b88SHerbert Xu 	return ret;
2498f2147b88SHerbert Xu }
2499f2147b88SHerbert Xu 
2500f2147b88SHerbert Xu static int gcm_decrypt(struct aead_request *req)
2501f2147b88SHerbert Xu {
2502f2147b88SHerbert Xu 	struct aead_edesc *edesc;
2503f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
2504f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
2505f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
2506f2147b88SHerbert Xu 	bool all_contig;
2507f2147b88SHerbert Xu 	u32 *desc;
2508f2147b88SHerbert Xu 	int ret = 0;
2509f2147b88SHerbert Xu 
2510f2147b88SHerbert Xu 	/* allocate extended descriptor */
2511f2147b88SHerbert Xu 	edesc = aead_edesc_alloc(req, GCM_DESC_JOB_IO_LEN, &all_contig, false);
2512f2147b88SHerbert Xu 	if (IS_ERR(edesc))
2513f2147b88SHerbert Xu 		return PTR_ERR(edesc);
2514f2147b88SHerbert Xu 
25151acebad3SYuan Kang 	/* Create and submit job descriptor*/
2516f2147b88SHerbert Xu 	init_gcm_job(req, edesc, all_contig, false);
25171acebad3SYuan Kang #ifdef DEBUG
2518514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
25191acebad3SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
25201acebad3SYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
25211acebad3SYuan Kang #endif
25221acebad3SYuan Kang 
25230e479300SYuan Kang 	desc = edesc->hw_desc;
25241acebad3SYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
25251acebad3SYuan Kang 	if (!ret) {
25261acebad3SYuan Kang 		ret = -EINPROGRESS;
25271acebad3SYuan Kang 	} else {
25281acebad3SYuan Kang 		aead_unmap(jrdev, edesc, req);
25291acebad3SYuan Kang 		kfree(edesc);
25301acebad3SYuan Kang 	}
25310e479300SYuan Kang 
25321acebad3SYuan Kang 	return ret;
25331acebad3SYuan Kang }
25340e479300SYuan Kang 
253546218750SHerbert Xu static int ipsec_gcm_decrypt(struct aead_request *req)
253646218750SHerbert Xu {
253746218750SHerbert Xu 	if (req->assoclen < 8)
253846218750SHerbert Xu 		return -EINVAL;
253946218750SHerbert Xu 
254046218750SHerbert Xu 	return gcm_decrypt(req);
254146218750SHerbert Xu }
254246218750SHerbert Xu 
2543479bcc7cSHerbert Xu static int aead_decrypt(struct aead_request *req)
2544f2147b88SHerbert Xu {
2545f2147b88SHerbert Xu 	struct aead_edesc *edesc;
2546f2147b88SHerbert Xu 	struct crypto_aead *aead = crypto_aead_reqtfm(req);
2547f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(aead);
2548f2147b88SHerbert Xu 	struct device *jrdev = ctx->jrdev;
2549f2147b88SHerbert Xu 	bool all_contig;
2550f2147b88SHerbert Xu 	u32 *desc;
2551f2147b88SHerbert Xu 	int ret = 0;
2552f2147b88SHerbert Xu 
25535ecf8ef9SCatalin Vasile #ifdef DEBUG
25545ecf8ef9SCatalin Vasile 	dbg_dump_sg(KERN_ERR, "dec src@"__stringify(__LINE__)": ",
25555ecf8ef9SCatalin Vasile 		    DUMP_PREFIX_ADDRESS, 16, 4, req->src,
255600fef2b2SHoria Geantă 		    req->assoclen + req->cryptlen, 1);
25575ecf8ef9SCatalin Vasile #endif
25585ecf8ef9SCatalin Vasile 
2559f2147b88SHerbert Xu 	/* allocate extended descriptor */
2560479bcc7cSHerbert Xu 	edesc = aead_edesc_alloc(req, AUTHENC_DESC_JOB_IO_LEN,
2561479bcc7cSHerbert Xu 				 &all_contig, false);
2562f2147b88SHerbert Xu 	if (IS_ERR(edesc))
2563f2147b88SHerbert Xu 		return PTR_ERR(edesc);
2564f2147b88SHerbert Xu 
2565f2147b88SHerbert Xu 	/* Create and submit job descriptor*/
2566479bcc7cSHerbert Xu 	init_authenc_job(req, edesc, all_contig, false);
2567f2147b88SHerbert Xu #ifdef DEBUG
2568f2147b88SHerbert Xu 	print_hex_dump(KERN_ERR, "aead jobdesc@"__stringify(__LINE__)": ",
2569f2147b88SHerbert Xu 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
2570f2147b88SHerbert Xu 		       desc_bytes(edesc->hw_desc), 1);
2571f2147b88SHerbert Xu #endif
2572f2147b88SHerbert Xu 
2573f2147b88SHerbert Xu 	desc = edesc->hw_desc;
2574479bcc7cSHerbert Xu 	ret = caam_jr_enqueue(jrdev, desc, aead_decrypt_done, req);
2575f2147b88SHerbert Xu 	if (!ret) {
2576f2147b88SHerbert Xu 		ret = -EINPROGRESS;
2577f2147b88SHerbert Xu 	} else {
2578479bcc7cSHerbert Xu 		aead_unmap(jrdev, edesc, req);
2579f2147b88SHerbert Xu 		kfree(edesc);
2580f2147b88SHerbert Xu 	}
2581f2147b88SHerbert Xu 
2582f2147b88SHerbert Xu 	return ret;
2583f2147b88SHerbert Xu }
2584f2147b88SHerbert Xu 
2585acdca31dSYuan Kang /*
2586acdca31dSYuan Kang  * allocate and map the ablkcipher extended descriptor for ablkcipher
2587acdca31dSYuan Kang  */
2588acdca31dSYuan Kang static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request
2589acdca31dSYuan Kang 						       *req, int desc_bytes,
2590acdca31dSYuan Kang 						       bool *iv_contig_out)
2591acdca31dSYuan Kang {
2592acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
2593acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
2594acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
2595acdca31dSYuan Kang 	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
2596acdca31dSYuan Kang 					  CRYPTO_TFM_REQ_MAY_SLEEP)) ?
2597acdca31dSYuan Kang 		       GFP_KERNEL : GFP_ATOMIC;
2598a299c837SYuan Kang 	int src_nents, dst_nents = 0, sec4_sg_bytes;
2599acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
2600acdca31dSYuan Kang 	dma_addr_t iv_dma = 0;
2601acdca31dSYuan Kang 	bool iv_contig = false;
2602acdca31dSYuan Kang 	int sgc;
2603acdca31dSYuan Kang 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
2604a299c837SYuan Kang 	int sec4_sg_index;
2605acdca31dSYuan Kang 
260613fb8fd7SLABBE Corentin 	src_nents = sg_count(req->src, req->nbytes);
2607acdca31dSYuan Kang 
2608643b39b0SYuan Kang 	if (req->dst != req->src)
260913fb8fd7SLABBE Corentin 		dst_nents = sg_count(req->dst, req->nbytes);
2610acdca31dSYuan Kang 
2611acdca31dSYuan Kang 	if (likely(req->src == req->dst)) {
261213fb8fd7SLABBE Corentin 		sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1,
261313fb8fd7SLABBE Corentin 				 DMA_BIDIRECTIONAL);
2614acdca31dSYuan Kang 	} else {
261513fb8fd7SLABBE Corentin 		sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1,
261613fb8fd7SLABBE Corentin 				 DMA_TO_DEVICE);
261713fb8fd7SLABBE Corentin 		sgc = dma_map_sg(jrdev, req->dst, dst_nents ? : 1,
261813fb8fd7SLABBE Corentin 				 DMA_FROM_DEVICE);
2619acdca31dSYuan Kang 	}
2620acdca31dSYuan Kang 
2621ce572085SHoria Geanta 	iv_dma = dma_map_single(jrdev, req->info, ivsize, DMA_TO_DEVICE);
2622ce572085SHoria Geanta 	if (dma_mapping_error(jrdev, iv_dma)) {
2623ce572085SHoria Geanta 		dev_err(jrdev, "unable to map IV\n");
2624ce572085SHoria Geanta 		return ERR_PTR(-ENOMEM);
2625ce572085SHoria Geanta 	}
2626ce572085SHoria Geanta 
2627acdca31dSYuan Kang 	/*
2628acdca31dSYuan Kang 	 * Check if iv can be contiguous with source and destination.
2629acdca31dSYuan Kang 	 * If so, include it. If not, create scatterlist.
2630acdca31dSYuan Kang 	 */
2631acdca31dSYuan Kang 	if (!src_nents && iv_dma + ivsize == sg_dma_address(req->src))
2632acdca31dSYuan Kang 		iv_contig = true;
2633acdca31dSYuan Kang 	else
2634acdca31dSYuan Kang 		src_nents = src_nents ? : 1;
2635a299c837SYuan Kang 	sec4_sg_bytes = ((iv_contig ? 0 : 1) + src_nents + dst_nents) *
2636a299c837SYuan Kang 			sizeof(struct sec4_sg_entry);
2637acdca31dSYuan Kang 
2638acdca31dSYuan Kang 	/* allocate space for base edesc and hw desc commands, link tables */
2639dde20ae9SVictoria Milhoan 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes,
2640dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
2641acdca31dSYuan Kang 	if (!edesc) {
2642acdca31dSYuan Kang 		dev_err(jrdev, "could not allocate extended descriptor\n");
2643acdca31dSYuan Kang 		return ERR_PTR(-ENOMEM);
2644acdca31dSYuan Kang 	}
2645acdca31dSYuan Kang 
2646acdca31dSYuan Kang 	edesc->src_nents = src_nents;
2647acdca31dSYuan Kang 	edesc->dst_nents = dst_nents;
2648a299c837SYuan Kang 	edesc->sec4_sg_bytes = sec4_sg_bytes;
2649a299c837SYuan Kang 	edesc->sec4_sg = (void *)edesc + sizeof(struct ablkcipher_edesc) +
2650acdca31dSYuan Kang 			 desc_bytes;
2651acdca31dSYuan Kang 
2652a299c837SYuan Kang 	sec4_sg_index = 0;
2653acdca31dSYuan Kang 	if (!iv_contig) {
2654a299c837SYuan Kang 		dma_to_sec4_sg_one(edesc->sec4_sg, iv_dma, ivsize, 0);
2655a299c837SYuan Kang 		sg_to_sec4_sg_last(req->src, src_nents,
2656a299c837SYuan Kang 				   edesc->sec4_sg + 1, 0);
2657a299c837SYuan Kang 		sec4_sg_index += 1 + src_nents;
2658acdca31dSYuan Kang 	}
2659acdca31dSYuan Kang 
2660643b39b0SYuan Kang 	if (dst_nents) {
2661a299c837SYuan Kang 		sg_to_sec4_sg_last(req->dst, dst_nents,
2662a299c837SYuan Kang 			edesc->sec4_sg + sec4_sg_index, 0);
2663acdca31dSYuan Kang 	}
2664acdca31dSYuan Kang 
2665a299c837SYuan Kang 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
2666a299c837SYuan Kang 					    sec4_sg_bytes, DMA_TO_DEVICE);
2667ce572085SHoria Geanta 	if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
2668ce572085SHoria Geanta 		dev_err(jrdev, "unable to map S/G table\n");
2669ce572085SHoria Geanta 		return ERR_PTR(-ENOMEM);
2670ce572085SHoria Geanta 	}
2671ce572085SHoria Geanta 
2672acdca31dSYuan Kang 	edesc->iv_dma = iv_dma;
2673acdca31dSYuan Kang 
2674acdca31dSYuan Kang #ifdef DEBUG
2675514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ablkcipher sec4_sg@"__stringify(__LINE__)": ",
2676a299c837SYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->sec4_sg,
2677a299c837SYuan Kang 		       sec4_sg_bytes, 1);
2678acdca31dSYuan Kang #endif
2679acdca31dSYuan Kang 
2680acdca31dSYuan Kang 	*iv_contig_out = iv_contig;
2681acdca31dSYuan Kang 	return edesc;
2682acdca31dSYuan Kang }
2683acdca31dSYuan Kang 
2684acdca31dSYuan Kang static int ablkcipher_encrypt(struct ablkcipher_request *req)
2685acdca31dSYuan Kang {
2686acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
2687acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
2688acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
2689acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
2690acdca31dSYuan Kang 	bool iv_contig;
2691acdca31dSYuan Kang 	u32 *desc;
2692acdca31dSYuan Kang 	int ret = 0;
2693acdca31dSYuan Kang 
2694acdca31dSYuan Kang 	/* allocate extended descriptor */
2695acdca31dSYuan Kang 	edesc = ablkcipher_edesc_alloc(req, DESC_JOB_IO_LEN *
2696acdca31dSYuan Kang 				       CAAM_CMD_SZ, &iv_contig);
2697acdca31dSYuan Kang 	if (IS_ERR(edesc))
2698acdca31dSYuan Kang 		return PTR_ERR(edesc);
2699acdca31dSYuan Kang 
2700acdca31dSYuan Kang 	/* Create and submit job descriptor*/
2701acdca31dSYuan Kang 	init_ablkcipher_job(ctx->sh_desc_enc,
2702acdca31dSYuan Kang 		ctx->sh_desc_enc_dma, edesc, req, iv_contig);
2703acdca31dSYuan Kang #ifdef DEBUG
2704514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ablkcipher jobdesc@"__stringify(__LINE__)": ",
2705acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
2706acdca31dSYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
2707acdca31dSYuan Kang #endif
2708acdca31dSYuan Kang 	desc = edesc->hw_desc;
2709acdca31dSYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, ablkcipher_encrypt_done, req);
2710acdca31dSYuan Kang 
2711acdca31dSYuan Kang 	if (!ret) {
2712acdca31dSYuan Kang 		ret = -EINPROGRESS;
2713acdca31dSYuan Kang 	} else {
2714acdca31dSYuan Kang 		ablkcipher_unmap(jrdev, edesc, req);
2715acdca31dSYuan Kang 		kfree(edesc);
2716acdca31dSYuan Kang 	}
2717acdca31dSYuan Kang 
2718acdca31dSYuan Kang 	return ret;
2719acdca31dSYuan Kang }
2720acdca31dSYuan Kang 
2721acdca31dSYuan Kang static int ablkcipher_decrypt(struct ablkcipher_request *req)
2722acdca31dSYuan Kang {
2723acdca31dSYuan Kang 	struct ablkcipher_edesc *edesc;
2724acdca31dSYuan Kang 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
2725acdca31dSYuan Kang 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
2726acdca31dSYuan Kang 	struct device *jrdev = ctx->jrdev;
2727acdca31dSYuan Kang 	bool iv_contig;
2728acdca31dSYuan Kang 	u32 *desc;
2729acdca31dSYuan Kang 	int ret = 0;
2730acdca31dSYuan Kang 
2731acdca31dSYuan Kang 	/* allocate extended descriptor */
2732acdca31dSYuan Kang 	edesc = ablkcipher_edesc_alloc(req, DESC_JOB_IO_LEN *
2733acdca31dSYuan Kang 				       CAAM_CMD_SZ, &iv_contig);
2734acdca31dSYuan Kang 	if (IS_ERR(edesc))
2735acdca31dSYuan Kang 		return PTR_ERR(edesc);
2736acdca31dSYuan Kang 
2737acdca31dSYuan Kang 	/* Create and submit job descriptor*/
2738acdca31dSYuan Kang 	init_ablkcipher_job(ctx->sh_desc_dec,
2739acdca31dSYuan Kang 		ctx->sh_desc_dec_dma, edesc, req, iv_contig);
2740acdca31dSYuan Kang 	desc = edesc->hw_desc;
2741acdca31dSYuan Kang #ifdef DEBUG
2742514df281SAlex Porosanu 	print_hex_dump(KERN_ERR, "ablkcipher jobdesc@"__stringify(__LINE__)": ",
2743acdca31dSYuan Kang 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
2744acdca31dSYuan Kang 		       desc_bytes(edesc->hw_desc), 1);
2745acdca31dSYuan Kang #endif
2746acdca31dSYuan Kang 
2747acdca31dSYuan Kang 	ret = caam_jr_enqueue(jrdev, desc, ablkcipher_decrypt_done, req);
2748acdca31dSYuan Kang 	if (!ret) {
2749acdca31dSYuan Kang 		ret = -EINPROGRESS;
2750acdca31dSYuan Kang 	} else {
2751acdca31dSYuan Kang 		ablkcipher_unmap(jrdev, edesc, req);
2752acdca31dSYuan Kang 		kfree(edesc);
2753acdca31dSYuan Kang 	}
2754acdca31dSYuan Kang 
2755acdca31dSYuan Kang 	return ret;
2756acdca31dSYuan Kang }
2757acdca31dSYuan Kang 
27587222d1a3SCatalin Vasile /*
27597222d1a3SCatalin Vasile  * allocate and map the ablkcipher extended descriptor
27607222d1a3SCatalin Vasile  * for ablkcipher givencrypt
27617222d1a3SCatalin Vasile  */
27627222d1a3SCatalin Vasile static struct ablkcipher_edesc *ablkcipher_giv_edesc_alloc(
27637222d1a3SCatalin Vasile 				struct skcipher_givcrypt_request *greq,
27647222d1a3SCatalin Vasile 				int desc_bytes,
27657222d1a3SCatalin Vasile 				bool *iv_contig_out)
27667222d1a3SCatalin Vasile {
27677222d1a3SCatalin Vasile 	struct ablkcipher_request *req = &greq->creq;
27687222d1a3SCatalin Vasile 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
27697222d1a3SCatalin Vasile 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
27707222d1a3SCatalin Vasile 	struct device *jrdev = ctx->jrdev;
27717222d1a3SCatalin Vasile 	gfp_t flags = (req->base.flags & (CRYPTO_TFM_REQ_MAY_BACKLOG |
27727222d1a3SCatalin Vasile 					  CRYPTO_TFM_REQ_MAY_SLEEP)) ?
27737222d1a3SCatalin Vasile 		       GFP_KERNEL : GFP_ATOMIC;
27747222d1a3SCatalin Vasile 	int src_nents, dst_nents = 0, sec4_sg_bytes;
27757222d1a3SCatalin Vasile 	struct ablkcipher_edesc *edesc;
27767222d1a3SCatalin Vasile 	dma_addr_t iv_dma = 0;
27777222d1a3SCatalin Vasile 	bool iv_contig = false;
27787222d1a3SCatalin Vasile 	int sgc;
27797222d1a3SCatalin Vasile 	int ivsize = crypto_ablkcipher_ivsize(ablkcipher);
27807222d1a3SCatalin Vasile 	int sec4_sg_index;
27817222d1a3SCatalin Vasile 
278213fb8fd7SLABBE Corentin 	src_nents = sg_count(req->src, req->nbytes);
27837222d1a3SCatalin Vasile 
27847222d1a3SCatalin Vasile 	if (unlikely(req->dst != req->src))
278513fb8fd7SLABBE Corentin 		dst_nents = sg_count(req->dst, req->nbytes);
27867222d1a3SCatalin Vasile 
27877222d1a3SCatalin Vasile 	if (likely(req->src == req->dst)) {
278813fb8fd7SLABBE Corentin 		sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1,
278913fb8fd7SLABBE Corentin 				 DMA_BIDIRECTIONAL);
27907222d1a3SCatalin Vasile 	} else {
279113fb8fd7SLABBE Corentin 		sgc = dma_map_sg(jrdev, req->src, src_nents ? : 1,
279213fb8fd7SLABBE Corentin 				 DMA_TO_DEVICE);
279313fb8fd7SLABBE Corentin 		sgc = dma_map_sg(jrdev, req->dst, dst_nents ? : 1,
279413fb8fd7SLABBE Corentin 				 DMA_FROM_DEVICE);
27957222d1a3SCatalin Vasile 	}
27967222d1a3SCatalin Vasile 
27977222d1a3SCatalin Vasile 	/*
27987222d1a3SCatalin Vasile 	 * Check if iv can be contiguous with source and destination.
27997222d1a3SCatalin Vasile 	 * If so, include it. If not, create scatterlist.
28007222d1a3SCatalin Vasile 	 */
28017222d1a3SCatalin Vasile 	iv_dma = dma_map_single(jrdev, greq->giv, ivsize, DMA_TO_DEVICE);
28027222d1a3SCatalin Vasile 	if (dma_mapping_error(jrdev, iv_dma)) {
28037222d1a3SCatalin Vasile 		dev_err(jrdev, "unable to map IV\n");
28047222d1a3SCatalin Vasile 		return ERR_PTR(-ENOMEM);
28057222d1a3SCatalin Vasile 	}
28067222d1a3SCatalin Vasile 
28077222d1a3SCatalin Vasile 	if (!dst_nents && iv_dma + ivsize == sg_dma_address(req->dst))
28087222d1a3SCatalin Vasile 		iv_contig = true;
28097222d1a3SCatalin Vasile 	else
28107222d1a3SCatalin Vasile 		dst_nents = dst_nents ? : 1;
28117222d1a3SCatalin Vasile 	sec4_sg_bytes = ((iv_contig ? 0 : 1) + src_nents + dst_nents) *
28127222d1a3SCatalin Vasile 			sizeof(struct sec4_sg_entry);
28137222d1a3SCatalin Vasile 
28147222d1a3SCatalin Vasile 	/* allocate space for base edesc and hw desc commands, link tables */
2815dde20ae9SVictoria Milhoan 	edesc = kzalloc(sizeof(*edesc) + desc_bytes + sec4_sg_bytes,
2816dde20ae9SVictoria Milhoan 			GFP_DMA | flags);
28177222d1a3SCatalin Vasile 	if (!edesc) {
28187222d1a3SCatalin Vasile 		dev_err(jrdev, "could not allocate extended descriptor\n");
28197222d1a3SCatalin Vasile 		return ERR_PTR(-ENOMEM);
28207222d1a3SCatalin Vasile 	}
28217222d1a3SCatalin Vasile 
28227222d1a3SCatalin Vasile 	edesc->src_nents = src_nents;
28237222d1a3SCatalin Vasile 	edesc->dst_nents = dst_nents;
28247222d1a3SCatalin Vasile 	edesc->sec4_sg_bytes = sec4_sg_bytes;
28257222d1a3SCatalin Vasile 	edesc->sec4_sg = (void *)edesc + sizeof(struct ablkcipher_edesc) +
28267222d1a3SCatalin Vasile 			 desc_bytes;
28277222d1a3SCatalin Vasile 
28287222d1a3SCatalin Vasile 	sec4_sg_index = 0;
28297222d1a3SCatalin Vasile 	if (src_nents) {
28307222d1a3SCatalin Vasile 		sg_to_sec4_sg_last(req->src, src_nents, edesc->sec4_sg, 0);
28317222d1a3SCatalin Vasile 		sec4_sg_index += src_nents;
28327222d1a3SCatalin Vasile 	}
28337222d1a3SCatalin Vasile 
28347222d1a3SCatalin Vasile 	if (!iv_contig) {
28357222d1a3SCatalin Vasile 		dma_to_sec4_sg_one(edesc->sec4_sg + sec4_sg_index,
28367222d1a3SCatalin Vasile 				   iv_dma, ivsize, 0);
28377222d1a3SCatalin Vasile 		sec4_sg_index += 1;
28387222d1a3SCatalin Vasile 		sg_to_sec4_sg_last(req->dst, dst_nents,
28397222d1a3SCatalin Vasile 				   edesc->sec4_sg + sec4_sg_index, 0);
28407222d1a3SCatalin Vasile 	}
28417222d1a3SCatalin Vasile 
28427222d1a3SCatalin Vasile 	edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
28437222d1a3SCatalin Vasile 					    sec4_sg_bytes, DMA_TO_DEVICE);
28447222d1a3SCatalin Vasile 	if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
28457222d1a3SCatalin Vasile 		dev_err(jrdev, "unable to map S/G table\n");
28467222d1a3SCatalin Vasile 		return ERR_PTR(-ENOMEM);
28477222d1a3SCatalin Vasile 	}
28487222d1a3SCatalin Vasile 	edesc->iv_dma = iv_dma;
28497222d1a3SCatalin Vasile 
28507222d1a3SCatalin Vasile #ifdef DEBUG
28517222d1a3SCatalin Vasile 	print_hex_dump(KERN_ERR,
28527222d1a3SCatalin Vasile 		       "ablkcipher sec4_sg@" __stringify(__LINE__) ": ",
28537222d1a3SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->sec4_sg,
28547222d1a3SCatalin Vasile 		       sec4_sg_bytes, 1);
28557222d1a3SCatalin Vasile #endif
28567222d1a3SCatalin Vasile 
28577222d1a3SCatalin Vasile 	*iv_contig_out = iv_contig;
28587222d1a3SCatalin Vasile 	return edesc;
28597222d1a3SCatalin Vasile }
28607222d1a3SCatalin Vasile 
28617222d1a3SCatalin Vasile static int ablkcipher_givencrypt(struct skcipher_givcrypt_request *creq)
28627222d1a3SCatalin Vasile {
28637222d1a3SCatalin Vasile 	struct ablkcipher_request *req = &creq->creq;
28647222d1a3SCatalin Vasile 	struct ablkcipher_edesc *edesc;
28657222d1a3SCatalin Vasile 	struct crypto_ablkcipher *ablkcipher = crypto_ablkcipher_reqtfm(req);
28667222d1a3SCatalin Vasile 	struct caam_ctx *ctx = crypto_ablkcipher_ctx(ablkcipher);
28677222d1a3SCatalin Vasile 	struct device *jrdev = ctx->jrdev;
28687222d1a3SCatalin Vasile 	bool iv_contig;
28697222d1a3SCatalin Vasile 	u32 *desc;
28707222d1a3SCatalin Vasile 	int ret = 0;
28717222d1a3SCatalin Vasile 
28727222d1a3SCatalin Vasile 	/* allocate extended descriptor */
28737222d1a3SCatalin Vasile 	edesc = ablkcipher_giv_edesc_alloc(creq, DESC_JOB_IO_LEN *
28747222d1a3SCatalin Vasile 				       CAAM_CMD_SZ, &iv_contig);
28757222d1a3SCatalin Vasile 	if (IS_ERR(edesc))
28767222d1a3SCatalin Vasile 		return PTR_ERR(edesc);
28777222d1a3SCatalin Vasile 
28787222d1a3SCatalin Vasile 	/* Create and submit job descriptor*/
28797222d1a3SCatalin Vasile 	init_ablkcipher_giv_job(ctx->sh_desc_givenc, ctx->sh_desc_givenc_dma,
28807222d1a3SCatalin Vasile 				edesc, req, iv_contig);
28817222d1a3SCatalin Vasile #ifdef DEBUG
28827222d1a3SCatalin Vasile 	print_hex_dump(KERN_ERR,
28837222d1a3SCatalin Vasile 		       "ablkcipher jobdesc@" __stringify(__LINE__) ": ",
28847222d1a3SCatalin Vasile 		       DUMP_PREFIX_ADDRESS, 16, 4, edesc->hw_desc,
28857222d1a3SCatalin Vasile 		       desc_bytes(edesc->hw_desc), 1);
28867222d1a3SCatalin Vasile #endif
28877222d1a3SCatalin Vasile 	desc = edesc->hw_desc;
28887222d1a3SCatalin Vasile 	ret = caam_jr_enqueue(jrdev, desc, ablkcipher_encrypt_done, req);
28897222d1a3SCatalin Vasile 
28907222d1a3SCatalin Vasile 	if (!ret) {
28917222d1a3SCatalin Vasile 		ret = -EINPROGRESS;
28927222d1a3SCatalin Vasile 	} else {
28937222d1a3SCatalin Vasile 		ablkcipher_unmap(jrdev, edesc, req);
28947222d1a3SCatalin Vasile 		kfree(edesc);
28957222d1a3SCatalin Vasile 	}
28967222d1a3SCatalin Vasile 
28977222d1a3SCatalin Vasile 	return ret;
28987222d1a3SCatalin Vasile }
28997222d1a3SCatalin Vasile 
2900885e9e2fSYuan Kang #define template_aead		template_u.aead
2901acdca31dSYuan Kang #define template_ablkcipher	template_u.ablkcipher
29028e8ec596SKim Phillips struct caam_alg_template {
29038e8ec596SKim Phillips 	char name[CRYPTO_MAX_ALG_NAME];
29048e8ec596SKim Phillips 	char driver_name[CRYPTO_MAX_ALG_NAME];
29058e8ec596SKim Phillips 	unsigned int blocksize;
2906885e9e2fSYuan Kang 	u32 type;
2907885e9e2fSYuan Kang 	union {
2908885e9e2fSYuan Kang 		struct ablkcipher_alg ablkcipher;
2909885e9e2fSYuan Kang 	} template_u;
29108e8ec596SKim Phillips 	u32 class1_alg_type;
29118e8ec596SKim Phillips 	u32 class2_alg_type;
29128e8ec596SKim Phillips 	u32 alg_op;
29138e8ec596SKim Phillips };
29148e8ec596SKim Phillips 
29158e8ec596SKim Phillips static struct caam_alg_template driver_algs[] = {
2916acdca31dSYuan Kang 	/* ablkcipher descriptor */
2917acdca31dSYuan Kang 	{
2918acdca31dSYuan Kang 		.name = "cbc(aes)",
2919acdca31dSYuan Kang 		.driver_name = "cbc-aes-caam",
2920acdca31dSYuan Kang 		.blocksize = AES_BLOCK_SIZE,
29217222d1a3SCatalin Vasile 		.type = CRYPTO_ALG_TYPE_GIVCIPHER,
2922acdca31dSYuan Kang 		.template_ablkcipher = {
2923acdca31dSYuan Kang 			.setkey = ablkcipher_setkey,
2924acdca31dSYuan Kang 			.encrypt = ablkcipher_encrypt,
2925acdca31dSYuan Kang 			.decrypt = ablkcipher_decrypt,
29267222d1a3SCatalin Vasile 			.givencrypt = ablkcipher_givencrypt,
29277222d1a3SCatalin Vasile 			.geniv = "<built-in>",
2928acdca31dSYuan Kang 			.min_keysize = AES_MIN_KEY_SIZE,
2929acdca31dSYuan Kang 			.max_keysize = AES_MAX_KEY_SIZE,
2930acdca31dSYuan Kang 			.ivsize = AES_BLOCK_SIZE,
2931acdca31dSYuan Kang 			},
2932acdca31dSYuan Kang 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
2933acdca31dSYuan Kang 	},
2934acdca31dSYuan Kang 	{
2935acdca31dSYuan Kang 		.name = "cbc(des3_ede)",
2936acdca31dSYuan Kang 		.driver_name = "cbc-3des-caam",
2937acdca31dSYuan Kang 		.blocksize = DES3_EDE_BLOCK_SIZE,
2938ff2c3a3bSCatalin Vasile 		.type = CRYPTO_ALG_TYPE_GIVCIPHER,
2939acdca31dSYuan Kang 		.template_ablkcipher = {
2940acdca31dSYuan Kang 			.setkey = ablkcipher_setkey,
2941acdca31dSYuan Kang 			.encrypt = ablkcipher_encrypt,
2942acdca31dSYuan Kang 			.decrypt = ablkcipher_decrypt,
2943ff2c3a3bSCatalin Vasile 			.givencrypt = ablkcipher_givencrypt,
2944ff2c3a3bSCatalin Vasile 			.geniv = "<built-in>",
2945acdca31dSYuan Kang 			.min_keysize = DES3_EDE_KEY_SIZE,
2946acdca31dSYuan Kang 			.max_keysize = DES3_EDE_KEY_SIZE,
2947acdca31dSYuan Kang 			.ivsize = DES3_EDE_BLOCK_SIZE,
2948acdca31dSYuan Kang 			},
2949acdca31dSYuan Kang 		.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
2950acdca31dSYuan Kang 	},
2951acdca31dSYuan Kang 	{
2952acdca31dSYuan Kang 		.name = "cbc(des)",
2953acdca31dSYuan Kang 		.driver_name = "cbc-des-caam",
2954acdca31dSYuan Kang 		.blocksize = DES_BLOCK_SIZE,
2955ff2c3a3bSCatalin Vasile 		.type = CRYPTO_ALG_TYPE_GIVCIPHER,
2956acdca31dSYuan Kang 		.template_ablkcipher = {
2957acdca31dSYuan Kang 			.setkey = ablkcipher_setkey,
2958acdca31dSYuan Kang 			.encrypt = ablkcipher_encrypt,
2959acdca31dSYuan Kang 			.decrypt = ablkcipher_decrypt,
2960ff2c3a3bSCatalin Vasile 			.givencrypt = ablkcipher_givencrypt,
2961ff2c3a3bSCatalin Vasile 			.geniv = "<built-in>",
2962acdca31dSYuan Kang 			.min_keysize = DES_KEY_SIZE,
2963acdca31dSYuan Kang 			.max_keysize = DES_KEY_SIZE,
2964acdca31dSYuan Kang 			.ivsize = DES_BLOCK_SIZE,
2965acdca31dSYuan Kang 			},
2966acdca31dSYuan Kang 		.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
29672b22f6c5SCatalin Vasile 	},
29682b22f6c5SCatalin Vasile 	{
29692b22f6c5SCatalin Vasile 		.name = "ctr(aes)",
29702b22f6c5SCatalin Vasile 		.driver_name = "ctr-aes-caam",
29712b22f6c5SCatalin Vasile 		.blocksize = 1,
29722b22f6c5SCatalin Vasile 		.type = CRYPTO_ALG_TYPE_ABLKCIPHER,
29732b22f6c5SCatalin Vasile 		.template_ablkcipher = {
29742b22f6c5SCatalin Vasile 			.setkey = ablkcipher_setkey,
29752b22f6c5SCatalin Vasile 			.encrypt = ablkcipher_encrypt,
29762b22f6c5SCatalin Vasile 			.decrypt = ablkcipher_decrypt,
29772b22f6c5SCatalin Vasile 			.geniv = "chainiv",
29782b22f6c5SCatalin Vasile 			.min_keysize = AES_MIN_KEY_SIZE,
29792b22f6c5SCatalin Vasile 			.max_keysize = AES_MAX_KEY_SIZE,
29802b22f6c5SCatalin Vasile 			.ivsize = AES_BLOCK_SIZE,
29812b22f6c5SCatalin Vasile 			},
29822b22f6c5SCatalin Vasile 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CTR_MOD128,
2983a5f57cffSCatalin Vasile 	},
2984a5f57cffSCatalin Vasile 	{
2985a5f57cffSCatalin Vasile 		.name = "rfc3686(ctr(aes))",
2986a5f57cffSCatalin Vasile 		.driver_name = "rfc3686-ctr-aes-caam",
2987a5f57cffSCatalin Vasile 		.blocksize = 1,
29887222d1a3SCatalin Vasile 		.type = CRYPTO_ALG_TYPE_GIVCIPHER,
2989a5f57cffSCatalin Vasile 		.template_ablkcipher = {
2990a5f57cffSCatalin Vasile 			.setkey = ablkcipher_setkey,
2991a5f57cffSCatalin Vasile 			.encrypt = ablkcipher_encrypt,
2992a5f57cffSCatalin Vasile 			.decrypt = ablkcipher_decrypt,
29937222d1a3SCatalin Vasile 			.givencrypt = ablkcipher_givencrypt,
29947222d1a3SCatalin Vasile 			.geniv = "<built-in>",
2995a5f57cffSCatalin Vasile 			.min_keysize = AES_MIN_KEY_SIZE +
2996a5f57cffSCatalin Vasile 				       CTR_RFC3686_NONCE_SIZE,
2997a5f57cffSCatalin Vasile 			.max_keysize = AES_MAX_KEY_SIZE +
2998a5f57cffSCatalin Vasile 				       CTR_RFC3686_NONCE_SIZE,
2999a5f57cffSCatalin Vasile 			.ivsize = CTR_RFC3686_IV_SIZE,
3000a5f57cffSCatalin Vasile 			},
3001a5f57cffSCatalin Vasile 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CTR_MOD128,
3002c6415a60SCatalin Vasile 	},
3003c6415a60SCatalin Vasile 	{
3004c6415a60SCatalin Vasile 		.name = "xts(aes)",
3005c6415a60SCatalin Vasile 		.driver_name = "xts-aes-caam",
3006c6415a60SCatalin Vasile 		.blocksize = AES_BLOCK_SIZE,
3007c6415a60SCatalin Vasile 		.type = CRYPTO_ALG_TYPE_ABLKCIPHER,
3008c6415a60SCatalin Vasile 		.template_ablkcipher = {
3009c6415a60SCatalin Vasile 			.setkey = xts_ablkcipher_setkey,
3010c6415a60SCatalin Vasile 			.encrypt = ablkcipher_encrypt,
3011c6415a60SCatalin Vasile 			.decrypt = ablkcipher_decrypt,
3012c6415a60SCatalin Vasile 			.geniv = "eseqiv",
3013c6415a60SCatalin Vasile 			.min_keysize = 2 * AES_MIN_KEY_SIZE,
3014c6415a60SCatalin Vasile 			.max_keysize = 2 * AES_MAX_KEY_SIZE,
3015c6415a60SCatalin Vasile 			.ivsize = AES_BLOCK_SIZE,
3016c6415a60SCatalin Vasile 			},
3017c6415a60SCatalin Vasile 		.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_XTS,
3018c6415a60SCatalin Vasile 	},
30198e8ec596SKim Phillips };
30208e8ec596SKim Phillips 
3021f2147b88SHerbert Xu static struct caam_aead_alg driver_aeads[] = {
3022f2147b88SHerbert Xu 	{
3023f2147b88SHerbert Xu 		.aead = {
3024f2147b88SHerbert Xu 			.base = {
3025f2147b88SHerbert Xu 				.cra_name = "rfc4106(gcm(aes))",
3026f2147b88SHerbert Xu 				.cra_driver_name = "rfc4106-gcm-aes-caam",
3027f2147b88SHerbert Xu 				.cra_blocksize = 1,
3028f2147b88SHerbert Xu 			},
3029f2147b88SHerbert Xu 			.setkey = rfc4106_setkey,
3030f2147b88SHerbert Xu 			.setauthsize = rfc4106_setauthsize,
303146218750SHerbert Xu 			.encrypt = ipsec_gcm_encrypt,
303246218750SHerbert Xu 			.decrypt = ipsec_gcm_decrypt,
3033f2147b88SHerbert Xu 			.ivsize = 8,
3034f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
3035f2147b88SHerbert Xu 		},
3036f2147b88SHerbert Xu 		.caam = {
3037f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
3038f2147b88SHerbert Xu 		},
3039f2147b88SHerbert Xu 	},
3040f2147b88SHerbert Xu 	{
3041f2147b88SHerbert Xu 		.aead = {
3042f2147b88SHerbert Xu 			.base = {
3043f2147b88SHerbert Xu 				.cra_name = "rfc4543(gcm(aes))",
3044f2147b88SHerbert Xu 				.cra_driver_name = "rfc4543-gcm-aes-caam",
3045f2147b88SHerbert Xu 				.cra_blocksize = 1,
3046f2147b88SHerbert Xu 			},
3047f2147b88SHerbert Xu 			.setkey = rfc4543_setkey,
3048f2147b88SHerbert Xu 			.setauthsize = rfc4543_setauthsize,
304946218750SHerbert Xu 			.encrypt = ipsec_gcm_encrypt,
305046218750SHerbert Xu 			.decrypt = ipsec_gcm_decrypt,
3051f2147b88SHerbert Xu 			.ivsize = 8,
3052f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
3053f2147b88SHerbert Xu 		},
3054f2147b88SHerbert Xu 		.caam = {
3055f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
3056f2147b88SHerbert Xu 		},
3057f2147b88SHerbert Xu 	},
3058f2147b88SHerbert Xu 	/* Galois Counter Mode */
3059f2147b88SHerbert Xu 	{
3060f2147b88SHerbert Xu 		.aead = {
3061f2147b88SHerbert Xu 			.base = {
3062f2147b88SHerbert Xu 				.cra_name = "gcm(aes)",
3063f2147b88SHerbert Xu 				.cra_driver_name = "gcm-aes-caam",
3064f2147b88SHerbert Xu 				.cra_blocksize = 1,
3065f2147b88SHerbert Xu 			},
3066f2147b88SHerbert Xu 			.setkey = gcm_setkey,
3067f2147b88SHerbert Xu 			.setauthsize = gcm_setauthsize,
3068f2147b88SHerbert Xu 			.encrypt = gcm_encrypt,
3069f2147b88SHerbert Xu 			.decrypt = gcm_decrypt,
3070f2147b88SHerbert Xu 			.ivsize = 12,
3071f2147b88SHerbert Xu 			.maxauthsize = AES_BLOCK_SIZE,
3072f2147b88SHerbert Xu 		},
3073f2147b88SHerbert Xu 		.caam = {
3074f2147b88SHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_GCM,
3075f2147b88SHerbert Xu 		},
3076f2147b88SHerbert Xu 	},
3077479bcc7cSHerbert Xu 	/* single-pass ipsec_esp descriptor */
3078479bcc7cSHerbert Xu 	{
3079479bcc7cSHerbert Xu 		.aead = {
3080479bcc7cSHerbert Xu 			.base = {
3081479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),"
3082479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
3083479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
3084479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
3085479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
3086479bcc7cSHerbert Xu 			},
3087479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3088479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3089479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3090479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3091479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
3092479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3093479bcc7cSHerbert Xu 		},
3094479bcc7cSHerbert Xu 		.caam = {
3095479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3096479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3097479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3098479bcc7cSHerbert Xu 		},
3099479bcc7cSHerbert Xu 	},
3100479bcc7cSHerbert Xu 	{
3101479bcc7cSHerbert Xu 		.aead = {
3102479bcc7cSHerbert Xu 			.base = {
3103479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
3104479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
3105479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
3106479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
3107479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
3108479bcc7cSHerbert Xu 			},
3109479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3110479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3111479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3112479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3113479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
3114479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3115479bcc7cSHerbert Xu 		},
3116479bcc7cSHerbert Xu 		.caam = {
3117479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3118479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3119479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
3120479bcc7cSHerbert Xu 		},
3121479bcc7cSHerbert Xu 	},
3122479bcc7cSHerbert Xu 	{
3123479bcc7cSHerbert Xu 		.aead = {
3124479bcc7cSHerbert Xu 			.base = {
3125479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
3126479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
3127479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
3128479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
3129479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
3130479bcc7cSHerbert Xu 			},
3131479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3132479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3133479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3134479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3135479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
3136479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3137479bcc7cSHerbert Xu 		},
3138479bcc7cSHerbert Xu 		.caam = {
3139479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3140479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3141479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
3142479bcc7cSHerbert Xu 		},
3143479bcc7cSHerbert Xu 	},
3144479bcc7cSHerbert Xu 	{
3145479bcc7cSHerbert Xu 		.aead = {
3146479bcc7cSHerbert Xu 			.base = {
3147479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
3148479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
3149479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
3150479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
3151479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
3152479bcc7cSHerbert Xu 			},
3153479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3154479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3155479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3156479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3157479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
3158479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3159479bcc7cSHerbert Xu 		},
3160479bcc7cSHerbert Xu 		.caam = {
3161479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3162479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3163479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3164479bcc7cSHerbert Xu 		},
3165479bcc7cSHerbert Xu 	},
3166479bcc7cSHerbert Xu 	{
3167479bcc7cSHerbert Xu 		.aead = {
3168479bcc7cSHerbert Xu 			.base = {
3169479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
3170479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
3171479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
3172479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
3173479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
3174479bcc7cSHerbert Xu 			},
3175479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3176479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3177479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3178479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3179479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
3180479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3181479bcc7cSHerbert Xu 		},
3182479bcc7cSHerbert Xu 		.caam = {
3183479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3184479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3185479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3186479bcc7cSHerbert Xu 		},
3187479bcc7cSHerbert Xu 	},
3188479bcc7cSHerbert Xu 	{
3189479bcc7cSHerbert Xu 		.aead = {
3190479bcc7cSHerbert Xu 			.base = {
3191479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
3192479bcc7cSHerbert Xu 					    "ecb(cipher_null))",
3193479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
3194479bcc7cSHerbert Xu 						   "ecb-cipher_null-caam",
3195479bcc7cSHerbert Xu 				.cra_blocksize = NULL_BLOCK_SIZE,
3196479bcc7cSHerbert Xu 			},
3197479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3198479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3199479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3200479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3201479bcc7cSHerbert Xu 			.ivsize = NULL_IV_SIZE,
3202479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3203479bcc7cSHerbert Xu 		},
3204479bcc7cSHerbert Xu 		.caam = {
3205479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3206479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3207479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
3208479bcc7cSHerbert Xu 		},
3209479bcc7cSHerbert Xu 	},
3210479bcc7cSHerbert Xu 	{
3211479bcc7cSHerbert Xu 		.aead = {
3212479bcc7cSHerbert Xu 			.base = {
3213479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(aes))",
3214479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
3215479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3216479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3217479bcc7cSHerbert Xu 			},
3218479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3219479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3220479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3221479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3222479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3223479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3224479bcc7cSHerbert Xu 		},
3225479bcc7cSHerbert Xu 		.caam = {
3226479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3227479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3228479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3229479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3230479bcc7cSHerbert Xu 		},
3231479bcc7cSHerbert Xu 	},
3232479bcc7cSHerbert Xu 	{
3233479bcc7cSHerbert Xu 		.aead = {
3234479bcc7cSHerbert Xu 			.base = {
3235479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
3236479bcc7cSHerbert Xu 					    "cbc(aes)))",
3237479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
3238479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3239479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3240479bcc7cSHerbert Xu 			},
3241479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3242479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3243479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
32448b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3245479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3246479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3247479bcc7cSHerbert Xu 		},
3248479bcc7cSHerbert Xu 		.caam = {
3249479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3250479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3251479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3252479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3253479bcc7cSHerbert Xu 			.geniv = true,
3254479bcc7cSHerbert Xu 		},
3255479bcc7cSHerbert Xu 	},
3256479bcc7cSHerbert Xu 	{
3257479bcc7cSHerbert Xu 		.aead = {
3258479bcc7cSHerbert Xu 			.base = {
3259479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),cbc(aes))",
3260479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
3261479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3262479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3263479bcc7cSHerbert Xu 			},
3264479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3265479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3266479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3267479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3268479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3269479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3270479bcc7cSHerbert Xu 		},
3271479bcc7cSHerbert Xu 		.caam = {
3272479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3273479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3274479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3275479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
3276479bcc7cSHerbert Xu 		},
3277479bcc7cSHerbert Xu 	},
3278479bcc7cSHerbert Xu 	{
3279479bcc7cSHerbert Xu 		.aead = {
3280479bcc7cSHerbert Xu 			.base = {
3281479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
3282479bcc7cSHerbert Xu 					    "cbc(aes)))",
3283479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3284479bcc7cSHerbert Xu 						   "hmac-sha1-cbc-aes-caam",
3285479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3286479bcc7cSHerbert Xu 			},
3287479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3288479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3289479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
32908b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3291479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3292479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3293479bcc7cSHerbert Xu 		},
3294479bcc7cSHerbert Xu 		.caam = {
3295479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3296479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3297479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3298479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
3299479bcc7cSHerbert Xu 			.geniv = true,
3300479bcc7cSHerbert Xu 		},
3301479bcc7cSHerbert Xu 	},
3302479bcc7cSHerbert Xu 	{
3303479bcc7cSHerbert Xu 		.aead = {
3304479bcc7cSHerbert Xu 			.base = {
3305479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),cbc(aes))",
3306479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
3307479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3308479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3309479bcc7cSHerbert Xu 			},
3310479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3311479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3312479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3313479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3314479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3315479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3316479bcc7cSHerbert Xu 		},
3317479bcc7cSHerbert Xu 		.caam = {
3318479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3319479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3320479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3321479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
3322479bcc7cSHerbert Xu 		},
3323479bcc7cSHerbert Xu 	},
3324479bcc7cSHerbert Xu 	{
3325479bcc7cSHerbert Xu 		.aead = {
3326479bcc7cSHerbert Xu 			.base = {
3327479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
3328479bcc7cSHerbert Xu 					    "cbc(aes)))",
3329479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3330479bcc7cSHerbert Xu 						   "hmac-sha224-cbc-aes-caam",
3331479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3332479bcc7cSHerbert Xu 			},
3333479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3334479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3335479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
33368b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3337479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3338479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3339479bcc7cSHerbert Xu 		},
3340479bcc7cSHerbert Xu 		.caam = {
3341479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3342479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3343479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3344479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
3345479bcc7cSHerbert Xu 			.geniv = true,
3346479bcc7cSHerbert Xu 		},
3347479bcc7cSHerbert Xu 	},
3348479bcc7cSHerbert Xu 	{
3349479bcc7cSHerbert Xu 		.aead = {
3350479bcc7cSHerbert Xu 			.base = {
3351479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),cbc(aes))",
3352479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
3353479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3354479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3355479bcc7cSHerbert Xu 			},
3356479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3357479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3358479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3359479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3360479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3361479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3362479bcc7cSHerbert Xu 		},
3363479bcc7cSHerbert Xu 		.caam = {
3364479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3365479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3366479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3367479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3368479bcc7cSHerbert Xu 		},
3369479bcc7cSHerbert Xu 	},
3370479bcc7cSHerbert Xu 	{
3371479bcc7cSHerbert Xu 		.aead = {
3372479bcc7cSHerbert Xu 			.base = {
3373479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
3374479bcc7cSHerbert Xu 					    "cbc(aes)))",
3375479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3376479bcc7cSHerbert Xu 						   "hmac-sha256-cbc-aes-caam",
3377479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3378479bcc7cSHerbert Xu 			},
3379479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3380479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3381479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
33828b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3383479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3384479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3385479bcc7cSHerbert Xu 		},
3386479bcc7cSHerbert Xu 		.caam = {
3387479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3388479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3389479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3390479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3391479bcc7cSHerbert Xu 			.geniv = true,
3392479bcc7cSHerbert Xu 		},
3393479bcc7cSHerbert Xu 	},
3394479bcc7cSHerbert Xu 	{
3395479bcc7cSHerbert Xu 		.aead = {
3396479bcc7cSHerbert Xu 			.base = {
3397479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),cbc(aes))",
3398479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
3399479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3400479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3401479bcc7cSHerbert Xu 			},
3402479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3403479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3404479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3405479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3406479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3407479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3408479bcc7cSHerbert Xu 		},
3409479bcc7cSHerbert Xu 		.caam = {
3410479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3411479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3412479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3413479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3414479bcc7cSHerbert Xu 		},
3415479bcc7cSHerbert Xu 	},
3416479bcc7cSHerbert Xu 	{
3417479bcc7cSHerbert Xu 		.aead = {
3418479bcc7cSHerbert Xu 			.base = {
3419479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
3420479bcc7cSHerbert Xu 					    "cbc(aes)))",
3421479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3422479bcc7cSHerbert Xu 						   "hmac-sha384-cbc-aes-caam",
3423479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3424479bcc7cSHerbert Xu 			},
3425479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3426479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3427479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
34288b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3429479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3430479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3431479bcc7cSHerbert Xu 		},
3432479bcc7cSHerbert Xu 		.caam = {
3433479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3434479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3435479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3436479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3437479bcc7cSHerbert Xu 			.geniv = true,
3438479bcc7cSHerbert Xu 		},
3439479bcc7cSHerbert Xu 	},
3440479bcc7cSHerbert Xu 	{
3441479bcc7cSHerbert Xu 		.aead = {
3442479bcc7cSHerbert Xu 			.base = {
3443479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),cbc(aes))",
3444479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
3445479bcc7cSHerbert Xu 						   "cbc-aes-caam",
3446479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3447479bcc7cSHerbert Xu 			},
3448479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3449479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3450479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3451479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3452479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3453479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3454479bcc7cSHerbert Xu 		},
3455479bcc7cSHerbert Xu 		.caam = {
3456479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3457479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3458479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3459479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
3460479bcc7cSHerbert Xu 		},
3461479bcc7cSHerbert Xu 	},
3462479bcc7cSHerbert Xu 	{
3463479bcc7cSHerbert Xu 		.aead = {
3464479bcc7cSHerbert Xu 			.base = {
3465479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
3466479bcc7cSHerbert Xu 					    "cbc(aes)))",
3467479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3468479bcc7cSHerbert Xu 						   "hmac-sha512-cbc-aes-caam",
3469479bcc7cSHerbert Xu 				.cra_blocksize = AES_BLOCK_SIZE,
3470479bcc7cSHerbert Xu 			},
3471479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3472479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3473479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
34748b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3475479bcc7cSHerbert Xu 			.ivsize = AES_BLOCK_SIZE,
3476479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3477479bcc7cSHerbert Xu 		},
3478479bcc7cSHerbert Xu 		.caam = {
3479479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES | OP_ALG_AAI_CBC,
3480479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3481479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3482479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
3483479bcc7cSHerbert Xu 			.geniv = true,
3484479bcc7cSHerbert Xu 		},
3485479bcc7cSHerbert Xu 	},
3486479bcc7cSHerbert Xu 	{
3487479bcc7cSHerbert Xu 		.aead = {
3488479bcc7cSHerbert Xu 			.base = {
3489479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(des3_ede))",
3490479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
3491479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3492479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3493479bcc7cSHerbert Xu 			},
3494479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3495479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3496479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3497479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3498479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3499479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3500479bcc7cSHerbert Xu 		},
3501479bcc7cSHerbert Xu 		.caam = {
3502479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3503479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3504479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3505479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3506479bcc7cSHerbert Xu 		}
3507479bcc7cSHerbert Xu 	},
3508479bcc7cSHerbert Xu 	{
3509479bcc7cSHerbert Xu 		.aead = {
3510479bcc7cSHerbert Xu 			.base = {
3511479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
3512479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
3513479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
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,
35208b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3521479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3522479bcc7cSHerbert Xu 			.maxauthsize = MD5_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_MD5 |
3527479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3528479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | 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(sha1),"
3536479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
3537479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
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 = SHA1_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_SHA1 |
3551479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3552479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
3553479bcc7cSHerbert Xu 		},
3554479bcc7cSHerbert Xu 	},
3555479bcc7cSHerbert Xu 	{
3556479bcc7cSHerbert Xu 		.aead = {
3557479bcc7cSHerbert Xu 			.base = {
3558479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
3559479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
3560479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3561479bcc7cSHerbert Xu 						   "hmac-sha1-"
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,
35688b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3569479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3570479bcc7cSHerbert Xu 			.maxauthsize = SHA1_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_SHA1 |
3575479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3576479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | 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(sha224),"
3584479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
3585479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
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 = SHA224_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_SHA224 |
3599479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3600479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
3601479bcc7cSHerbert Xu 		},
3602479bcc7cSHerbert Xu 	},
3603479bcc7cSHerbert Xu 	{
3604479bcc7cSHerbert Xu 		.aead = {
3605479bcc7cSHerbert Xu 			.base = {
3606479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
3607479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
3608479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3609479bcc7cSHerbert Xu 						   "hmac-sha224-"
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,
36168b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3617479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3618479bcc7cSHerbert Xu 			.maxauthsize = SHA224_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_SHA224 |
3623479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3624479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | 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(sha256),"
3632479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
3633479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
3634479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3635479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3636479bcc7cSHerbert Xu 			},
3637479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3638479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3639479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3640479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3641479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3642479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3643479bcc7cSHerbert Xu 		},
3644479bcc7cSHerbert Xu 		.caam = {
3645479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3646479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3647479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3648479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3649479bcc7cSHerbert Xu 		},
3650479bcc7cSHerbert Xu 	},
3651479bcc7cSHerbert Xu 	{
3652479bcc7cSHerbert Xu 		.aead = {
3653479bcc7cSHerbert Xu 			.base = {
3654479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
3655479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
3656479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3657479bcc7cSHerbert Xu 						   "hmac-sha256-"
3658479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3659479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3660479bcc7cSHerbert Xu 			},
3661479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3662479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3663479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
36648b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3665479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3666479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3667479bcc7cSHerbert Xu 		},
3668479bcc7cSHerbert Xu 		.caam = {
3669479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3670479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3671479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3672479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3673479bcc7cSHerbert Xu 			.geniv = true,
3674479bcc7cSHerbert Xu 		},
3675479bcc7cSHerbert Xu 	},
3676479bcc7cSHerbert Xu 	{
3677479bcc7cSHerbert Xu 		.aead = {
3678479bcc7cSHerbert Xu 			.base = {
3679479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
3680479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
3681479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
3682479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3683479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3684479bcc7cSHerbert Xu 			},
3685479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3686479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3687479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3688479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3689479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3690479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3691479bcc7cSHerbert Xu 		},
3692479bcc7cSHerbert Xu 		.caam = {
3693479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3694479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3695479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3696479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3697479bcc7cSHerbert Xu 		},
3698479bcc7cSHerbert Xu 	},
3699479bcc7cSHerbert Xu 	{
3700479bcc7cSHerbert Xu 		.aead = {
3701479bcc7cSHerbert Xu 			.base = {
3702479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
3703479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
3704479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3705479bcc7cSHerbert Xu 						   "hmac-sha384-"
3706479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3707479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3708479bcc7cSHerbert Xu 			},
3709479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3710479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3711479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
37128b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3713479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3714479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3715479bcc7cSHerbert Xu 		},
3716479bcc7cSHerbert Xu 		.caam = {
3717479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3718479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3719479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3720479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3721479bcc7cSHerbert Xu 			.geniv = true,
3722479bcc7cSHerbert Xu 		},
3723479bcc7cSHerbert Xu 	},
3724479bcc7cSHerbert Xu 	{
3725479bcc7cSHerbert Xu 		.aead = {
3726479bcc7cSHerbert Xu 			.base = {
3727479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
3728479bcc7cSHerbert Xu 					    "cbc(des3_ede))",
3729479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
3730479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3731479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3732479bcc7cSHerbert Xu 			},
3733479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3734479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3735479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3736479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3737479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3738479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3739479bcc7cSHerbert Xu 		},
3740479bcc7cSHerbert Xu 		.caam = {
3741479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3742479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3743479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3744479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
3745479bcc7cSHerbert Xu 		},
3746479bcc7cSHerbert Xu 	},
3747479bcc7cSHerbert Xu 	{
3748479bcc7cSHerbert Xu 		.aead = {
3749479bcc7cSHerbert Xu 			.base = {
3750479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
3751479bcc7cSHerbert Xu 					    "cbc(des3_ede)))",
3752479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3753479bcc7cSHerbert Xu 						   "hmac-sha512-"
3754479bcc7cSHerbert Xu 						   "cbc-des3_ede-caam",
3755479bcc7cSHerbert Xu 				.cra_blocksize = DES3_EDE_BLOCK_SIZE,
3756479bcc7cSHerbert Xu 			},
3757479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3758479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3759479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
37608b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3761479bcc7cSHerbert Xu 			.ivsize = DES3_EDE_BLOCK_SIZE,
3762479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
3763479bcc7cSHerbert Xu 		},
3764479bcc7cSHerbert Xu 		.caam = {
3765479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_3DES | OP_ALG_AAI_CBC,
3766479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
3767479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3768479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
3769479bcc7cSHerbert Xu 			.geniv = true,
3770479bcc7cSHerbert Xu 		},
3771479bcc7cSHerbert Xu 	},
3772479bcc7cSHerbert Xu 	{
3773479bcc7cSHerbert Xu 		.aead = {
3774479bcc7cSHerbert Xu 			.base = {
3775479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),cbc(des))",
3776479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
3777479bcc7cSHerbert Xu 						   "cbc-des-caam",
3778479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3779479bcc7cSHerbert Xu 			},
3780479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3781479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3782479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3783479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3784479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3785479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3786479bcc7cSHerbert Xu 		},
3787479bcc7cSHerbert Xu 		.caam = {
3788479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3789479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3790479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3791479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3792479bcc7cSHerbert Xu 		},
3793479bcc7cSHerbert Xu 	},
3794479bcc7cSHerbert Xu 	{
3795479bcc7cSHerbert Xu 		.aead = {
3796479bcc7cSHerbert Xu 			.base = {
3797479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(md5),"
3798479bcc7cSHerbert Xu 					    "cbc(des)))",
3799479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-hmac-md5-"
3800479bcc7cSHerbert Xu 						   "cbc-des-caam",
3801479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3802479bcc7cSHerbert Xu 			},
3803479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3804479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3805479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
38068b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3807479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3808479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
3809479bcc7cSHerbert Xu 		},
3810479bcc7cSHerbert Xu 		.caam = {
3811479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3812479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
3813479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3814479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
3815479bcc7cSHerbert Xu 			.geniv = true,
3816479bcc7cSHerbert Xu 		},
3817479bcc7cSHerbert Xu 	},
3818479bcc7cSHerbert Xu 	{
3819479bcc7cSHerbert Xu 		.aead = {
3820479bcc7cSHerbert Xu 			.base = {
3821479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),cbc(des))",
3822479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
3823479bcc7cSHerbert Xu 						   "cbc-des-caam",
3824479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3825479bcc7cSHerbert Xu 			},
3826479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3827479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3828479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3829479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3830479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3831479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3832479bcc7cSHerbert Xu 		},
3833479bcc7cSHerbert Xu 		.caam = {
3834479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3835479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3836479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3837479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
3838479bcc7cSHerbert Xu 		},
3839479bcc7cSHerbert Xu 	},
3840479bcc7cSHerbert Xu 	{
3841479bcc7cSHerbert Xu 		.aead = {
3842479bcc7cSHerbert Xu 			.base = {
3843479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha1),"
3844479bcc7cSHerbert Xu 					    "cbc(des)))",
3845479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3846479bcc7cSHerbert Xu 						   "hmac-sha1-cbc-des-caam",
3847479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3848479bcc7cSHerbert Xu 			},
3849479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3850479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3851479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
38528b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3853479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3854479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
3855479bcc7cSHerbert Xu 		},
3856479bcc7cSHerbert Xu 		.caam = {
3857479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3858479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
3859479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3860479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
3861479bcc7cSHerbert Xu 			.geniv = true,
3862479bcc7cSHerbert Xu 		},
3863479bcc7cSHerbert Xu 	},
3864479bcc7cSHerbert Xu 	{
3865479bcc7cSHerbert Xu 		.aead = {
3866479bcc7cSHerbert Xu 			.base = {
3867479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),cbc(des))",
3868479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
3869479bcc7cSHerbert Xu 						   "cbc-des-caam",
3870479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3871479bcc7cSHerbert Xu 			},
3872479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3873479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3874479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3875479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3876479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3877479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3878479bcc7cSHerbert Xu 		},
3879479bcc7cSHerbert Xu 		.caam = {
3880479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3881479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3882479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3883479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
3884479bcc7cSHerbert Xu 		},
3885479bcc7cSHerbert Xu 	},
3886479bcc7cSHerbert Xu 	{
3887479bcc7cSHerbert Xu 		.aead = {
3888479bcc7cSHerbert Xu 			.base = {
3889479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha224),"
3890479bcc7cSHerbert Xu 					    "cbc(des)))",
3891479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3892479bcc7cSHerbert Xu 						   "hmac-sha224-cbc-des-caam",
3893479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3894479bcc7cSHerbert Xu 			},
3895479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3896479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3897479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
38988b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3899479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3900479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
3901479bcc7cSHerbert Xu 		},
3902479bcc7cSHerbert Xu 		.caam = {
3903479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3904479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
3905479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3906479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
3907479bcc7cSHerbert Xu 			.geniv = true,
3908479bcc7cSHerbert Xu 		},
3909479bcc7cSHerbert Xu 	},
3910479bcc7cSHerbert Xu 	{
3911479bcc7cSHerbert Xu 		.aead = {
3912479bcc7cSHerbert Xu 			.base = {
3913479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),cbc(des))",
3914479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
3915479bcc7cSHerbert Xu 						   "cbc-des-caam",
3916479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3917479bcc7cSHerbert Xu 			},
3918479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3919479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3920479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
3921479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
3922479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3923479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3924479bcc7cSHerbert Xu 		},
3925479bcc7cSHerbert Xu 		.caam = {
3926479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3927479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3928479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3929479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3930479bcc7cSHerbert Xu 		},
3931479bcc7cSHerbert Xu 	},
3932479bcc7cSHerbert Xu 	{
3933479bcc7cSHerbert Xu 		.aead = {
3934479bcc7cSHerbert Xu 			.base = {
3935479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha256),"
3936479bcc7cSHerbert Xu 					    "cbc(des)))",
3937479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3938479bcc7cSHerbert Xu 						   "hmac-sha256-cbc-des-caam",
3939479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3940479bcc7cSHerbert Xu 			},
3941479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3942479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3943479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
39448b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3945479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3946479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
3947479bcc7cSHerbert Xu 		},
3948479bcc7cSHerbert Xu 		.caam = {
3949479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3950479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
3951479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3952479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
3953479bcc7cSHerbert Xu 			.geniv = true,
3954479bcc7cSHerbert Xu 		},
3955479bcc7cSHerbert Xu 	},
3956479bcc7cSHerbert Xu 	{
3957479bcc7cSHerbert Xu 		.aead = {
3958479bcc7cSHerbert Xu 			.base = {
3959479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),cbc(des))",
3960479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
3961479bcc7cSHerbert Xu 						   "cbc-des-caam",
3962479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
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 = DES_BLOCK_SIZE,
3969479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3970479bcc7cSHerbert Xu 		},
3971479bcc7cSHerbert Xu 		.caam = {
3972479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3973479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3974479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3975479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3976479bcc7cSHerbert Xu 		},
3977479bcc7cSHerbert Xu 	},
3978479bcc7cSHerbert Xu 	{
3979479bcc7cSHerbert Xu 		.aead = {
3980479bcc7cSHerbert Xu 			.base = {
3981479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha384),"
3982479bcc7cSHerbert Xu 					    "cbc(des)))",
3983479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
3984479bcc7cSHerbert Xu 						   "hmac-sha384-cbc-des-caam",
3985479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
3986479bcc7cSHerbert Xu 			},
3987479bcc7cSHerbert Xu 			.setkey = aead_setkey,
3988479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
3989479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
39908b18e235SHoria Geantă 			.decrypt = aead_decrypt,
3991479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
3992479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
3993479bcc7cSHerbert Xu 		},
3994479bcc7cSHerbert Xu 		.caam = {
3995479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
3996479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
3997479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
3998479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
3999479bcc7cSHerbert Xu 			.geniv = true,
4000479bcc7cSHerbert Xu 		},
4001479bcc7cSHerbert Xu 	},
4002479bcc7cSHerbert Xu 	{
4003479bcc7cSHerbert Xu 		.aead = {
4004479bcc7cSHerbert Xu 			.base = {
4005479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),cbc(des))",
4006479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
4007479bcc7cSHerbert Xu 						   "cbc-des-caam",
4008479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
4009479bcc7cSHerbert Xu 			},
4010479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4011479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4012479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4013479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
4014479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
4015479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
4016479bcc7cSHerbert Xu 		},
4017479bcc7cSHerbert Xu 		.caam = {
4018479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
4019479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
4020479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4021479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
4022479bcc7cSHerbert Xu 		},
4023479bcc7cSHerbert Xu 	},
4024479bcc7cSHerbert Xu 	{
4025479bcc7cSHerbert Xu 		.aead = {
4026479bcc7cSHerbert Xu 			.base = {
4027479bcc7cSHerbert Xu 				.cra_name = "echainiv(authenc(hmac(sha512),"
4028479bcc7cSHerbert Xu 					    "cbc(des)))",
4029479bcc7cSHerbert Xu 				.cra_driver_name = "echainiv-authenc-"
4030479bcc7cSHerbert Xu 						   "hmac-sha512-cbc-des-caam",
4031479bcc7cSHerbert Xu 				.cra_blocksize = DES_BLOCK_SIZE,
4032479bcc7cSHerbert Xu 			},
4033479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4034479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4035479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
40368b18e235SHoria Geantă 			.decrypt = aead_decrypt,
4037479bcc7cSHerbert Xu 			.ivsize = DES_BLOCK_SIZE,
4038479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
4039479bcc7cSHerbert Xu 		},
4040479bcc7cSHerbert Xu 		.caam = {
4041479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_DES | OP_ALG_AAI_CBC,
4042479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
4043479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4044479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
4045479bcc7cSHerbert Xu 			.geniv = true,
4046479bcc7cSHerbert Xu 		},
4047479bcc7cSHerbert Xu 	},
4048479bcc7cSHerbert Xu 	{
4049479bcc7cSHerbert Xu 		.aead = {
4050479bcc7cSHerbert Xu 			.base = {
4051479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(md5),"
4052479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
4053479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-md5-"
4054479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4055479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4056479bcc7cSHerbert Xu 			},
4057479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4058479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4059479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4060479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
4061479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4062479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
4063479bcc7cSHerbert Xu 		},
4064479bcc7cSHerbert Xu 		.caam = {
4065479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4066479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4067479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
4068479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4069479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
4070479bcc7cSHerbert Xu 			.rfc3686 = true,
4071479bcc7cSHerbert Xu 		},
4072479bcc7cSHerbert Xu 	},
4073479bcc7cSHerbert Xu 	{
4074479bcc7cSHerbert Xu 		.aead = {
4075479bcc7cSHerbert Xu 			.base = {
4076479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
4077479bcc7cSHerbert Xu 					    "hmac(md5),rfc3686(ctr(aes))))",
4078479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-md5-"
4079479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4080479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4081479bcc7cSHerbert Xu 			},
4082479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4083479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4084479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
40858b18e235SHoria Geantă 			.decrypt = aead_decrypt,
4086479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4087479bcc7cSHerbert Xu 			.maxauthsize = MD5_DIGEST_SIZE,
4088479bcc7cSHerbert Xu 		},
4089479bcc7cSHerbert Xu 		.caam = {
4090479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4091479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4092479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_MD5 |
4093479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4094479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_MD5 | OP_ALG_AAI_HMAC,
4095479bcc7cSHerbert Xu 			.rfc3686 = true,
4096479bcc7cSHerbert Xu 			.geniv = true,
4097479bcc7cSHerbert Xu 		},
4098479bcc7cSHerbert Xu 	},
4099479bcc7cSHerbert Xu 	{
4100479bcc7cSHerbert Xu 		.aead = {
4101479bcc7cSHerbert Xu 			.base = {
4102479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha1),"
4103479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
4104479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha1-"
4105479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4106479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4107479bcc7cSHerbert Xu 			},
4108479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4109479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4110479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4111479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
4112479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4113479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
4114479bcc7cSHerbert Xu 		},
4115479bcc7cSHerbert Xu 		.caam = {
4116479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4117479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4118479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
4119479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4120479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
4121479bcc7cSHerbert Xu 			.rfc3686 = true,
4122479bcc7cSHerbert Xu 		},
4123479bcc7cSHerbert Xu 	},
4124479bcc7cSHerbert Xu 	{
4125479bcc7cSHerbert Xu 		.aead = {
4126479bcc7cSHerbert Xu 			.base = {
4127479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
4128479bcc7cSHerbert Xu 					    "hmac(sha1),rfc3686(ctr(aes))))",
4129479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha1-"
4130479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4131479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4132479bcc7cSHerbert Xu 			},
4133479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4134479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4135479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
41368b18e235SHoria Geantă 			.decrypt = aead_decrypt,
4137479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4138479bcc7cSHerbert Xu 			.maxauthsize = SHA1_DIGEST_SIZE,
4139479bcc7cSHerbert Xu 		},
4140479bcc7cSHerbert Xu 		.caam = {
4141479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4142479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4143479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA1 |
4144479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4145479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA1 | OP_ALG_AAI_HMAC,
4146479bcc7cSHerbert Xu 			.rfc3686 = true,
4147479bcc7cSHerbert Xu 			.geniv = true,
4148479bcc7cSHerbert Xu 		},
4149479bcc7cSHerbert Xu 	},
4150479bcc7cSHerbert Xu 	{
4151479bcc7cSHerbert Xu 		.aead = {
4152479bcc7cSHerbert Xu 			.base = {
4153479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha224),"
4154479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
4155479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha224-"
4156479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4157479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4158479bcc7cSHerbert Xu 			},
4159479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4160479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4161479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4162479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
4163479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4164479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
4165479bcc7cSHerbert Xu 		},
4166479bcc7cSHerbert Xu 		.caam = {
4167479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4168479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4169479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
4170479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4171479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
4172479bcc7cSHerbert Xu 			.rfc3686 = true,
4173479bcc7cSHerbert Xu 		},
4174479bcc7cSHerbert Xu 	},
4175479bcc7cSHerbert Xu 	{
4176479bcc7cSHerbert Xu 		.aead = {
4177479bcc7cSHerbert Xu 			.base = {
4178479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc("
4179479bcc7cSHerbert Xu 					    "hmac(sha224),rfc3686(ctr(aes))))",
4180479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha224-"
4181479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4182479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4183479bcc7cSHerbert Xu 			},
4184479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4185479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4186479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
41878b18e235SHoria Geantă 			.decrypt = aead_decrypt,
4188479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4189479bcc7cSHerbert Xu 			.maxauthsize = SHA224_DIGEST_SIZE,
4190479bcc7cSHerbert Xu 		},
4191479bcc7cSHerbert Xu 		.caam = {
4192479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4193479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4194479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA224 |
4195479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4196479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA224 | OP_ALG_AAI_HMAC,
4197479bcc7cSHerbert Xu 			.rfc3686 = true,
4198479bcc7cSHerbert Xu 			.geniv = true,
4199479bcc7cSHerbert Xu 		},
4200479bcc7cSHerbert Xu 	},
4201479bcc7cSHerbert Xu 	{
4202479bcc7cSHerbert Xu 		.aead = {
4203479bcc7cSHerbert Xu 			.base = {
4204479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha256),"
4205479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
4206479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha256-"
4207479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4208479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4209479bcc7cSHerbert Xu 			},
4210479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4211479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4212479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4213479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
4214479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4215479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
4216479bcc7cSHerbert Xu 		},
4217479bcc7cSHerbert Xu 		.caam = {
4218479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4219479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4220479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
4221479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4222479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
4223479bcc7cSHerbert Xu 			.rfc3686 = true,
4224479bcc7cSHerbert Xu 		},
4225479bcc7cSHerbert Xu 	},
4226479bcc7cSHerbert Xu 	{
4227479bcc7cSHerbert Xu 		.aead = {
4228479bcc7cSHerbert Xu 			.base = {
4229479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha256),"
4230479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
4231479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha256-"
4232479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4233479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4234479bcc7cSHerbert Xu 			},
4235479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4236479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4237479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
42388b18e235SHoria Geantă 			.decrypt = aead_decrypt,
4239479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4240479bcc7cSHerbert Xu 			.maxauthsize = SHA256_DIGEST_SIZE,
4241479bcc7cSHerbert Xu 		},
4242479bcc7cSHerbert Xu 		.caam = {
4243479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4244479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4245479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA256 |
4246479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4247479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA256 | OP_ALG_AAI_HMAC,
4248479bcc7cSHerbert Xu 			.rfc3686 = true,
4249479bcc7cSHerbert Xu 			.geniv = true,
4250479bcc7cSHerbert Xu 		},
4251479bcc7cSHerbert Xu 	},
4252479bcc7cSHerbert Xu 	{
4253479bcc7cSHerbert Xu 		.aead = {
4254479bcc7cSHerbert Xu 			.base = {
4255479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha384),"
4256479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
4257479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha384-"
4258479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4259479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4260479bcc7cSHerbert Xu 			},
4261479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4262479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4263479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4264479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
4265479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4266479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
4267479bcc7cSHerbert Xu 		},
4268479bcc7cSHerbert Xu 		.caam = {
4269479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4270479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4271479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
4272479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4273479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
4274479bcc7cSHerbert Xu 			.rfc3686 = true,
4275479bcc7cSHerbert Xu 		},
4276479bcc7cSHerbert Xu 	},
4277479bcc7cSHerbert Xu 	{
4278479bcc7cSHerbert Xu 		.aead = {
4279479bcc7cSHerbert Xu 			.base = {
4280479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha384),"
4281479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
4282479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha384-"
4283479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4284479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4285479bcc7cSHerbert Xu 			},
4286479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4287479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4288479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
42898b18e235SHoria Geantă 			.decrypt = aead_decrypt,
4290479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4291479bcc7cSHerbert Xu 			.maxauthsize = SHA384_DIGEST_SIZE,
4292479bcc7cSHerbert Xu 		},
4293479bcc7cSHerbert Xu 		.caam = {
4294479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4295479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4296479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA384 |
4297479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4298479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA384 | OP_ALG_AAI_HMAC,
4299479bcc7cSHerbert Xu 			.rfc3686 = true,
4300479bcc7cSHerbert Xu 			.geniv = true,
4301479bcc7cSHerbert Xu 		},
4302479bcc7cSHerbert Xu 	},
4303479bcc7cSHerbert Xu 	{
4304479bcc7cSHerbert Xu 		.aead = {
4305479bcc7cSHerbert Xu 			.base = {
4306479bcc7cSHerbert Xu 				.cra_name = "authenc(hmac(sha512),"
4307479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes)))",
4308479bcc7cSHerbert Xu 				.cra_driver_name = "authenc-hmac-sha512-"
4309479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4310479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4311479bcc7cSHerbert Xu 			},
4312479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4313479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4314479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
4315479bcc7cSHerbert Xu 			.decrypt = aead_decrypt,
4316479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4317479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
4318479bcc7cSHerbert Xu 		},
4319479bcc7cSHerbert Xu 		.caam = {
4320479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4321479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4322479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
4323479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4324479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
4325479bcc7cSHerbert Xu 			.rfc3686 = true,
4326479bcc7cSHerbert Xu 		},
4327479bcc7cSHerbert Xu 	},
4328479bcc7cSHerbert Xu 	{
4329479bcc7cSHerbert Xu 		.aead = {
4330479bcc7cSHerbert Xu 			.base = {
4331479bcc7cSHerbert Xu 				.cra_name = "seqiv(authenc(hmac(sha512),"
4332479bcc7cSHerbert Xu 					    "rfc3686(ctr(aes))))",
4333479bcc7cSHerbert Xu 				.cra_driver_name = "seqiv-authenc-hmac-sha512-"
4334479bcc7cSHerbert Xu 						   "rfc3686-ctr-aes-caam",
4335479bcc7cSHerbert Xu 				.cra_blocksize = 1,
4336479bcc7cSHerbert Xu 			},
4337479bcc7cSHerbert Xu 			.setkey = aead_setkey,
4338479bcc7cSHerbert Xu 			.setauthsize = aead_setauthsize,
4339479bcc7cSHerbert Xu 			.encrypt = aead_encrypt,
43408b18e235SHoria Geantă 			.decrypt = aead_decrypt,
4341479bcc7cSHerbert Xu 			.ivsize = CTR_RFC3686_IV_SIZE,
4342479bcc7cSHerbert Xu 			.maxauthsize = SHA512_DIGEST_SIZE,
4343479bcc7cSHerbert Xu 		},
4344479bcc7cSHerbert Xu 		.caam = {
4345479bcc7cSHerbert Xu 			.class1_alg_type = OP_ALG_ALGSEL_AES |
4346479bcc7cSHerbert Xu 					   OP_ALG_AAI_CTR_MOD128,
4347479bcc7cSHerbert Xu 			.class2_alg_type = OP_ALG_ALGSEL_SHA512 |
4348479bcc7cSHerbert Xu 					   OP_ALG_AAI_HMAC_PRECOMP,
4349479bcc7cSHerbert Xu 			.alg_op = OP_ALG_ALGSEL_SHA512 | OP_ALG_AAI_HMAC,
4350479bcc7cSHerbert Xu 			.rfc3686 = true,
4351479bcc7cSHerbert Xu 			.geniv = true,
4352479bcc7cSHerbert Xu 		},
4353479bcc7cSHerbert Xu 	},
4354f2147b88SHerbert Xu };
4355f2147b88SHerbert Xu 
4356f2147b88SHerbert Xu struct caam_crypto_alg {
4357f2147b88SHerbert Xu 	struct crypto_alg crypto_alg;
4358f2147b88SHerbert Xu 	struct list_head entry;
4359f2147b88SHerbert Xu 	struct caam_alg_entry caam;
4360f2147b88SHerbert Xu };
4361f2147b88SHerbert Xu 
4362f2147b88SHerbert Xu static int caam_init_common(struct caam_ctx *ctx, struct caam_alg_entry *caam)
4363f2147b88SHerbert Xu {
4364f2147b88SHerbert Xu 	ctx->jrdev = caam_jr_alloc();
4365f2147b88SHerbert Xu 	if (IS_ERR(ctx->jrdev)) {
4366f2147b88SHerbert Xu 		pr_err("Job Ring Device allocation for transform failed\n");
4367f2147b88SHerbert Xu 		return PTR_ERR(ctx->jrdev);
4368f2147b88SHerbert Xu 	}
4369f2147b88SHerbert Xu 
4370f2147b88SHerbert Xu 	/* copy descriptor header template value */
4371f2147b88SHerbert Xu 	ctx->class1_alg_type = OP_TYPE_CLASS1_ALG | caam->class1_alg_type;
4372f2147b88SHerbert Xu 	ctx->class2_alg_type = OP_TYPE_CLASS2_ALG | caam->class2_alg_type;
4373f2147b88SHerbert Xu 	ctx->alg_op = OP_TYPE_CLASS2_ALG | caam->alg_op;
4374f2147b88SHerbert Xu 
4375f2147b88SHerbert Xu 	return 0;
4376f2147b88SHerbert Xu }
4377f2147b88SHerbert Xu 
43788e8ec596SKim Phillips static int caam_cra_init(struct crypto_tfm *tfm)
43798e8ec596SKim Phillips {
43808e8ec596SKim Phillips 	struct crypto_alg *alg = tfm->__crt_alg;
43818e8ec596SKim Phillips 	struct caam_crypto_alg *caam_alg =
43828e8ec596SKim Phillips 		 container_of(alg, struct caam_crypto_alg, crypto_alg);
43838e8ec596SKim Phillips 	struct caam_ctx *ctx = crypto_tfm_ctx(tfm);
43848e8ec596SKim Phillips 
4385f2147b88SHerbert Xu 	return caam_init_common(ctx, &caam_alg->caam);
4386cfc6f11bSRuchika Gupta }
43878e8ec596SKim Phillips 
4388f2147b88SHerbert Xu static int caam_aead_init(struct crypto_aead *tfm)
43898e8ec596SKim Phillips {
4390f2147b88SHerbert Xu 	struct aead_alg *alg = crypto_aead_alg(tfm);
4391f2147b88SHerbert Xu 	struct caam_aead_alg *caam_alg =
4392f2147b88SHerbert Xu 		 container_of(alg, struct caam_aead_alg, aead);
4393f2147b88SHerbert Xu 	struct caam_ctx *ctx = crypto_aead_ctx(tfm);
43948e8ec596SKim Phillips 
4395f2147b88SHerbert Xu 	return caam_init_common(ctx, &caam_alg->caam);
4396f2147b88SHerbert Xu }
4397f2147b88SHerbert Xu 
4398f2147b88SHerbert Xu static void caam_exit_common(struct caam_ctx *ctx)
4399f2147b88SHerbert Xu {
44001acebad3SYuan Kang 	if (ctx->sh_desc_enc_dma &&
44011acebad3SYuan Kang 	    !dma_mapping_error(ctx->jrdev, ctx->sh_desc_enc_dma))
44021acebad3SYuan Kang 		dma_unmap_single(ctx->jrdev, ctx->sh_desc_enc_dma,
44031acebad3SYuan Kang 				 desc_bytes(ctx->sh_desc_enc), DMA_TO_DEVICE);
44041acebad3SYuan Kang 	if (ctx->sh_desc_dec_dma &&
44051acebad3SYuan Kang 	    !dma_mapping_error(ctx->jrdev, ctx->sh_desc_dec_dma))
44061acebad3SYuan Kang 		dma_unmap_single(ctx->jrdev, ctx->sh_desc_dec_dma,
44071acebad3SYuan Kang 				 desc_bytes(ctx->sh_desc_dec), DMA_TO_DEVICE);
44081acebad3SYuan Kang 	if (ctx->sh_desc_givenc_dma &&
44091acebad3SYuan Kang 	    !dma_mapping_error(ctx->jrdev, ctx->sh_desc_givenc_dma))
44101acebad3SYuan Kang 		dma_unmap_single(ctx->jrdev, ctx->sh_desc_givenc_dma,
44111acebad3SYuan Kang 				 desc_bytes(ctx->sh_desc_givenc),
44124427b1b4SKim Phillips 				 DMA_TO_DEVICE);
4413ec31eed7SHoria Geanta 	if (ctx->key_dma &&
4414ec31eed7SHoria Geanta 	    !dma_mapping_error(ctx->jrdev, ctx->key_dma))
4415ec31eed7SHoria Geanta 		dma_unmap_single(ctx->jrdev, ctx->key_dma,
4416ec31eed7SHoria Geanta 				 ctx->enckeylen + ctx->split_key_pad_len,
4417ec31eed7SHoria Geanta 				 DMA_TO_DEVICE);
4418cfc6f11bSRuchika Gupta 
4419cfc6f11bSRuchika Gupta 	caam_jr_free(ctx->jrdev);
44208e8ec596SKim Phillips }
44218e8ec596SKim Phillips 
4422f2147b88SHerbert Xu static void caam_cra_exit(struct crypto_tfm *tfm)
4423f2147b88SHerbert Xu {
4424f2147b88SHerbert Xu 	caam_exit_common(crypto_tfm_ctx(tfm));
4425f2147b88SHerbert Xu }
4426f2147b88SHerbert Xu 
4427f2147b88SHerbert Xu static void caam_aead_exit(struct crypto_aead *tfm)
4428f2147b88SHerbert Xu {
4429f2147b88SHerbert Xu 	caam_exit_common(crypto_aead_ctx(tfm));
4430f2147b88SHerbert Xu }
4431f2147b88SHerbert Xu 
44328e8ec596SKim Phillips static void __exit caam_algapi_exit(void)
44338e8ec596SKim Phillips {
44348e8ec596SKim Phillips 
44358e8ec596SKim Phillips 	struct caam_crypto_alg *t_alg, *n;
4436f2147b88SHerbert Xu 	int i;
4437f2147b88SHerbert Xu 
4438f2147b88SHerbert Xu 	for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
4439f2147b88SHerbert Xu 		struct caam_aead_alg *t_alg = driver_aeads + i;
4440f2147b88SHerbert Xu 
4441f2147b88SHerbert Xu 		if (t_alg->registered)
4442f2147b88SHerbert Xu 			crypto_unregister_aead(&t_alg->aead);
4443f2147b88SHerbert Xu 	}
44448e8ec596SKim Phillips 
4445cfc6f11bSRuchika Gupta 	if (!alg_list.next)
44468e8ec596SKim Phillips 		return;
44478e8ec596SKim Phillips 
4448cfc6f11bSRuchika Gupta 	list_for_each_entry_safe(t_alg, n, &alg_list, entry) {
44498e8ec596SKim Phillips 		crypto_unregister_alg(&t_alg->crypto_alg);
44508e8ec596SKim Phillips 		list_del(&t_alg->entry);
44518e8ec596SKim Phillips 		kfree(t_alg);
44528e8ec596SKim Phillips 	}
44538e8ec596SKim Phillips }
44548e8ec596SKim Phillips 
4455cfc6f11bSRuchika Gupta static struct caam_crypto_alg *caam_alg_alloc(struct caam_alg_template
44568e8ec596SKim Phillips 					      *template)
44578e8ec596SKim Phillips {
44588e8ec596SKim Phillips 	struct caam_crypto_alg *t_alg;
44598e8ec596SKim Phillips 	struct crypto_alg *alg;
44608e8ec596SKim Phillips 
44619c4f9733SFabio Estevam 	t_alg = kzalloc(sizeof(*t_alg), GFP_KERNEL);
44628e8ec596SKim Phillips 	if (!t_alg) {
4463cfc6f11bSRuchika Gupta 		pr_err("failed to allocate t_alg\n");
44648e8ec596SKim Phillips 		return ERR_PTR(-ENOMEM);
44658e8ec596SKim Phillips 	}
44668e8ec596SKim Phillips 
44678e8ec596SKim Phillips 	alg = &t_alg->crypto_alg;
44688e8ec596SKim Phillips 
44698e8ec596SKim Phillips 	snprintf(alg->cra_name, CRYPTO_MAX_ALG_NAME, "%s", template->name);
44708e8ec596SKim Phillips 	snprintf(alg->cra_driver_name, CRYPTO_MAX_ALG_NAME, "%s",
44718e8ec596SKim Phillips 		 template->driver_name);
44728e8ec596SKim Phillips 	alg->cra_module = THIS_MODULE;
44738e8ec596SKim Phillips 	alg->cra_init = caam_cra_init;
44748e8ec596SKim Phillips 	alg->cra_exit = caam_cra_exit;
44758e8ec596SKim Phillips 	alg->cra_priority = CAAM_CRA_PRIORITY;
44768e8ec596SKim Phillips 	alg->cra_blocksize = template->blocksize;
44778e8ec596SKim Phillips 	alg->cra_alignmask = 0;
44788e8ec596SKim Phillips 	alg->cra_ctxsize = sizeof(struct caam_ctx);
4479d912bb76SNikos Mavrogiannopoulos 	alg->cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY |
4480d912bb76SNikos Mavrogiannopoulos 			 template->type;
4481885e9e2fSYuan Kang 	switch (template->type) {
44827222d1a3SCatalin Vasile 	case CRYPTO_ALG_TYPE_GIVCIPHER:
44837222d1a3SCatalin Vasile 		alg->cra_type = &crypto_givcipher_type;
44847222d1a3SCatalin Vasile 		alg->cra_ablkcipher = template->template_ablkcipher;
44857222d1a3SCatalin Vasile 		break;
4486acdca31dSYuan Kang 	case CRYPTO_ALG_TYPE_ABLKCIPHER:
4487acdca31dSYuan Kang 		alg->cra_type = &crypto_ablkcipher_type;
4488acdca31dSYuan Kang 		alg->cra_ablkcipher = template->template_ablkcipher;
4489acdca31dSYuan Kang 		break;
4490885e9e2fSYuan Kang 	}
44918e8ec596SKim Phillips 
4492f2147b88SHerbert Xu 	t_alg->caam.class1_alg_type = template->class1_alg_type;
4493f2147b88SHerbert Xu 	t_alg->caam.class2_alg_type = template->class2_alg_type;
4494f2147b88SHerbert Xu 	t_alg->caam.alg_op = template->alg_op;
44958e8ec596SKim Phillips 
44968e8ec596SKim Phillips 	return t_alg;
44978e8ec596SKim Phillips }
44988e8ec596SKim Phillips 
4499f2147b88SHerbert Xu static void caam_aead_alg_init(struct caam_aead_alg *t_alg)
4500f2147b88SHerbert Xu {
4501f2147b88SHerbert Xu 	struct aead_alg *alg = &t_alg->aead;
4502f2147b88SHerbert Xu 
4503f2147b88SHerbert Xu 	alg->base.cra_module = THIS_MODULE;
4504f2147b88SHerbert Xu 	alg->base.cra_priority = CAAM_CRA_PRIORITY;
4505f2147b88SHerbert Xu 	alg->base.cra_ctxsize = sizeof(struct caam_ctx);
45065e4b8c1fSHerbert Xu 	alg->base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_KERN_DRIVER_ONLY;
4507f2147b88SHerbert Xu 
4508f2147b88SHerbert Xu 	alg->init = caam_aead_init;
4509f2147b88SHerbert Xu 	alg->exit = caam_aead_exit;
4510f2147b88SHerbert Xu }
4511f2147b88SHerbert Xu 
45128e8ec596SKim Phillips static int __init caam_algapi_init(void)
45138e8ec596SKim Phillips {
451435af6403SRuchika Gupta 	struct device_node *dev_node;
451535af6403SRuchika Gupta 	struct platform_device *pdev;
451635af6403SRuchika Gupta 	struct device *ctrldev;
4517bf83490eSVictoria Milhoan 	struct caam_drv_private *priv;
45188e8ec596SKim Phillips 	int i = 0, err = 0;
4519bf83490eSVictoria Milhoan 	u32 cha_vid, cha_inst, des_inst, aes_inst, md_inst;
4520bf83490eSVictoria Milhoan 	unsigned int md_limit = SHA512_DIGEST_SIZE;
4521f2147b88SHerbert Xu 	bool registered = false;
45228e8ec596SKim Phillips 
452335af6403SRuchika Gupta 	dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
452435af6403SRuchika Gupta 	if (!dev_node) {
452535af6403SRuchika Gupta 		dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec4.0");
452635af6403SRuchika Gupta 		if (!dev_node)
452735af6403SRuchika Gupta 			return -ENODEV;
452835af6403SRuchika Gupta 	}
452935af6403SRuchika Gupta 
453035af6403SRuchika Gupta 	pdev = of_find_device_by_node(dev_node);
453135af6403SRuchika Gupta 	if (!pdev) {
453235af6403SRuchika Gupta 		of_node_put(dev_node);
453335af6403SRuchika Gupta 		return -ENODEV;
453435af6403SRuchika Gupta 	}
453535af6403SRuchika Gupta 
453635af6403SRuchika Gupta 	ctrldev = &pdev->dev;
453735af6403SRuchika Gupta 	priv = dev_get_drvdata(ctrldev);
453835af6403SRuchika Gupta 	of_node_put(dev_node);
453935af6403SRuchika Gupta 
454035af6403SRuchika Gupta 	/*
454135af6403SRuchika Gupta 	 * If priv is NULL, it's probably because the caam driver wasn't
454235af6403SRuchika Gupta 	 * properly initialized (e.g. RNG4 init failed). Thus, bail out here.
454335af6403SRuchika Gupta 	 */
454435af6403SRuchika Gupta 	if (!priv)
454535af6403SRuchika Gupta 		return -ENODEV;
454635af6403SRuchika Gupta 
454735af6403SRuchika Gupta 
4548cfc6f11bSRuchika Gupta 	INIT_LIST_HEAD(&alg_list);
45498e8ec596SKim Phillips 
4550bf83490eSVictoria Milhoan 	/*
4551bf83490eSVictoria Milhoan 	 * Register crypto algorithms the device supports.
4552bf83490eSVictoria Milhoan 	 * First, detect presence and attributes of DES, AES, and MD blocks.
4553bf83490eSVictoria Milhoan 	 */
4554bf83490eSVictoria Milhoan 	cha_vid = rd_reg32(&priv->ctrl->perfmon.cha_id_ls);
4555bf83490eSVictoria Milhoan 	cha_inst = rd_reg32(&priv->ctrl->perfmon.cha_num_ls);
4556bf83490eSVictoria Milhoan 	des_inst = (cha_inst & CHA_ID_LS_DES_MASK) >> CHA_ID_LS_DES_SHIFT;
4557bf83490eSVictoria Milhoan 	aes_inst = (cha_inst & CHA_ID_LS_AES_MASK) >> CHA_ID_LS_AES_SHIFT;
4558bf83490eSVictoria Milhoan 	md_inst = (cha_inst & CHA_ID_LS_MD_MASK) >> CHA_ID_LS_MD_SHIFT;
45598e8ec596SKim Phillips 
4560bf83490eSVictoria Milhoan 	/* If MD is present, limit digest size based on LP256 */
4561bf83490eSVictoria Milhoan 	if (md_inst && ((cha_vid & CHA_ID_LS_MD_MASK) == CHA_ID_LS_MD_LP256))
4562bf83490eSVictoria Milhoan 		md_limit = SHA256_DIGEST_SIZE;
4563bf83490eSVictoria Milhoan 
4564bf83490eSVictoria Milhoan 	for (i = 0; i < ARRAY_SIZE(driver_algs); i++) {
4565bf83490eSVictoria Milhoan 		struct caam_crypto_alg *t_alg;
4566bf83490eSVictoria Milhoan 		struct caam_alg_template *alg = driver_algs + i;
4567bf83490eSVictoria Milhoan 		u32 alg_sel = alg->class1_alg_type & OP_ALG_ALGSEL_MASK;
4568bf83490eSVictoria Milhoan 
4569bf83490eSVictoria Milhoan 		/* Skip DES algorithms if not supported by device */
4570bf83490eSVictoria Milhoan 		if (!des_inst &&
4571bf83490eSVictoria Milhoan 		    ((alg_sel == OP_ALG_ALGSEL_3DES) ||
4572bf83490eSVictoria Milhoan 		     (alg_sel == OP_ALG_ALGSEL_DES)))
4573bf83490eSVictoria Milhoan 				continue;
4574bf83490eSVictoria Milhoan 
4575bf83490eSVictoria Milhoan 		/* Skip AES algorithms if not supported by device */
4576bf83490eSVictoria Milhoan 		if (!aes_inst && (alg_sel == OP_ALG_ALGSEL_AES))
4577bf83490eSVictoria Milhoan 				continue;
4578bf83490eSVictoria Milhoan 
4579bf83490eSVictoria Milhoan 		t_alg = caam_alg_alloc(alg);
45808e8ec596SKim Phillips 		if (IS_ERR(t_alg)) {
45818e8ec596SKim Phillips 			err = PTR_ERR(t_alg);
4582bf83490eSVictoria Milhoan 			pr_warn("%s alg allocation failed\n", alg->driver_name);
45838e8ec596SKim Phillips 			continue;
45848e8ec596SKim Phillips 		}
45858e8ec596SKim Phillips 
45868e8ec596SKim Phillips 		err = crypto_register_alg(&t_alg->crypto_alg);
45878e8ec596SKim Phillips 		if (err) {
4588cfc6f11bSRuchika Gupta 			pr_warn("%s alg registration failed\n",
45898e8ec596SKim Phillips 				t_alg->crypto_alg.cra_driver_name);
45908e8ec596SKim Phillips 			kfree(t_alg);
4591f2147b88SHerbert Xu 			continue;
45928e8ec596SKim Phillips 		}
4593f2147b88SHerbert Xu 
4594f2147b88SHerbert Xu 		list_add_tail(&t_alg->entry, &alg_list);
4595f2147b88SHerbert Xu 		registered = true;
4596f2147b88SHerbert Xu 	}
4597f2147b88SHerbert Xu 
4598f2147b88SHerbert Xu 	for (i = 0; i < ARRAY_SIZE(driver_aeads); i++) {
4599f2147b88SHerbert Xu 		struct caam_aead_alg *t_alg = driver_aeads + i;
4600bf83490eSVictoria Milhoan 		u32 c1_alg_sel = t_alg->caam.class1_alg_type &
4601bf83490eSVictoria Milhoan 				 OP_ALG_ALGSEL_MASK;
4602bf83490eSVictoria Milhoan 		u32 c2_alg_sel = t_alg->caam.class2_alg_type &
4603bf83490eSVictoria Milhoan 				 OP_ALG_ALGSEL_MASK;
4604bf83490eSVictoria Milhoan 		u32 alg_aai = t_alg->caam.class1_alg_type & OP_ALG_AAI_MASK;
4605bf83490eSVictoria Milhoan 
4606bf83490eSVictoria Milhoan 		/* Skip DES algorithms if not supported by device */
4607bf83490eSVictoria Milhoan 		if (!des_inst &&
4608bf83490eSVictoria Milhoan 		    ((c1_alg_sel == OP_ALG_ALGSEL_3DES) ||
4609bf83490eSVictoria Milhoan 		     (c1_alg_sel == OP_ALG_ALGSEL_DES)))
4610bf83490eSVictoria Milhoan 				continue;
4611bf83490eSVictoria Milhoan 
4612bf83490eSVictoria Milhoan 		/* Skip AES algorithms if not supported by device */
4613bf83490eSVictoria Milhoan 		if (!aes_inst && (c1_alg_sel == OP_ALG_ALGSEL_AES))
4614bf83490eSVictoria Milhoan 				continue;
4615bf83490eSVictoria Milhoan 
4616bf83490eSVictoria Milhoan 		/*
4617bf83490eSVictoria Milhoan 		 * Check support for AES algorithms not available
4618bf83490eSVictoria Milhoan 		 * on LP devices.
4619bf83490eSVictoria Milhoan 		 */
4620bf83490eSVictoria Milhoan 		if ((cha_vid & CHA_ID_LS_AES_MASK) == CHA_ID_LS_AES_LP)
4621bf83490eSVictoria Milhoan 			if (alg_aai == OP_ALG_AAI_GCM)
4622bf83490eSVictoria Milhoan 				continue;
4623bf83490eSVictoria Milhoan 
4624bf83490eSVictoria Milhoan 		/*
4625bf83490eSVictoria Milhoan 		 * Skip algorithms requiring message digests
4626bf83490eSVictoria Milhoan 		 * if MD or MD size is not supported by device.
4627bf83490eSVictoria Milhoan 		 */
4628bf83490eSVictoria Milhoan 		if (c2_alg_sel &&
4629bf83490eSVictoria Milhoan 		    (!md_inst || (t_alg->aead.maxauthsize > md_limit)))
4630bf83490eSVictoria Milhoan 				continue;
4631f2147b88SHerbert Xu 
4632f2147b88SHerbert Xu 		caam_aead_alg_init(t_alg);
4633f2147b88SHerbert Xu 
4634f2147b88SHerbert Xu 		err = crypto_register_aead(&t_alg->aead);
4635f2147b88SHerbert Xu 		if (err) {
4636f2147b88SHerbert Xu 			pr_warn("%s alg registration failed\n",
4637f2147b88SHerbert Xu 				t_alg->aead.base.cra_driver_name);
4638f2147b88SHerbert Xu 			continue;
4639f2147b88SHerbert Xu 		}
4640f2147b88SHerbert Xu 
4641f2147b88SHerbert Xu 		t_alg->registered = true;
4642f2147b88SHerbert Xu 		registered = true;
4643f2147b88SHerbert Xu 	}
4644f2147b88SHerbert Xu 
4645f2147b88SHerbert Xu 	if (registered)
4646cfc6f11bSRuchika Gupta 		pr_info("caam algorithms registered in /proc/crypto\n");
46478e8ec596SKim Phillips 
46488e8ec596SKim Phillips 	return err;
46498e8ec596SKim Phillips }
46508e8ec596SKim Phillips 
46518e8ec596SKim Phillips module_init(caam_algapi_init);
46528e8ec596SKim Phillips module_exit(caam_algapi_exit);
46538e8ec596SKim Phillips 
46548e8ec596SKim Phillips MODULE_LICENSE("GPL");
46558e8ec596SKim Phillips MODULE_DESCRIPTION("FSL CAAM support for crypto API");
46568e8ec596SKim Phillips MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
4657