xref: /linux/drivers/crypto/caam/caamalg_desc.c (revision 78eebbfa)
1618b5dc4SHoria Geantă // SPDX-License-Identifier: GPL-2.0+
28cea7b66SHoria Geantă /*
39dbe3072SHoria Geantă  * Shared descriptors for aead, skcipher algorithms
48cea7b66SHoria Geantă  *
5eaed71a4SIuliana Prodan  * Copyright 2016-2019 NXP
68cea7b66SHoria Geantă  */
78cea7b66SHoria Geantă 
88cea7b66SHoria Geantă #include "compat.h"
98cea7b66SHoria Geantă #include "desc_constr.h"
108cea7b66SHoria Geantă #include "caamalg_desc.h"
118cea7b66SHoria Geantă 
128cea7b66SHoria Geantă /*
138cea7b66SHoria Geantă  * For aead functions, read payload and write payload,
148cea7b66SHoria Geantă  * both of which are specified in req->src and req->dst
158cea7b66SHoria Geantă  */
aead_append_src_dst(u32 * desc,u32 msg_type)168cea7b66SHoria Geantă static inline void aead_append_src_dst(u32 *desc, u32 msg_type)
178cea7b66SHoria Geantă {
188cea7b66SHoria Geantă 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
198cea7b66SHoria Geantă 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH |
208cea7b66SHoria Geantă 			     KEY_VLF | msg_type | FIFOLD_TYPE_LASTBOTH);
218cea7b66SHoria Geantă }
228cea7b66SHoria Geantă 
238cea7b66SHoria Geantă /* Set DK bit in class 1 operation if shared */
append_dec_op1(u32 * desc,u32 type)248cea7b66SHoria Geantă static inline void append_dec_op1(u32 *desc, u32 type)
258cea7b66SHoria Geantă {
268cea7b66SHoria Geantă 	u32 *jump_cmd, *uncond_jump_cmd;
278cea7b66SHoria Geantă 
288cea7b66SHoria Geantă 	/* DK bit is valid only for AES */
298cea7b66SHoria Geantă 	if ((type & OP_ALG_ALGSEL_MASK) != OP_ALG_ALGSEL_AES) {
308cea7b66SHoria Geantă 		append_operation(desc, type | OP_ALG_AS_INITFINAL |
318cea7b66SHoria Geantă 				 OP_ALG_DECRYPT);
328cea7b66SHoria Geantă 		return;
338cea7b66SHoria Geantă 	}
348cea7b66SHoria Geantă 
358cea7b66SHoria Geantă 	jump_cmd = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
36334d37c9SHoria Geantă 	append_operation(desc, type | OP_ALG_AS_INIT | OP_ALG_DECRYPT);
378cea7b66SHoria Geantă 	uncond_jump_cmd = append_jump(desc, JUMP_TEST_ALL);
388cea7b66SHoria Geantă 	set_jump_tgt_here(desc, jump_cmd);
39334d37c9SHoria Geantă 	append_operation(desc, type | OP_ALG_AS_INIT | OP_ALG_DECRYPT |
40334d37c9SHoria Geantă 			 OP_ALG_AAI_DK);
418cea7b66SHoria Geantă 	set_jump_tgt_here(desc, uncond_jump_cmd);
428cea7b66SHoria Geantă }
438cea7b66SHoria Geantă 
448cea7b66SHoria Geantă /**
458cea7b66SHoria Geantă  * cnstr_shdsc_aead_null_encap - IPSec ESP encapsulation shared descriptor
468cea7b66SHoria Geantă  *                               (non-protocol) with no (null) encryption.
478cea7b66SHoria Geantă  * @desc: pointer to buffer used for descriptor construction
487e0880b9SHoria Geantă  * @adata: pointer to authentication transform definitions.
497e0880b9SHoria Geantă  *         A split key is required for SEC Era < 6; the size of the split key
507e0880b9SHoria Geantă  *         is specified in this case. Valid algorithm values - one of
517e0880b9SHoria Geantă  *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
527e0880b9SHoria Geantă  *         with OP_ALG_AAI_HMAC_PRECOMP.
538cea7b66SHoria Geantă  * @icvsize: integrity check value (ICV) size (truncated or full)
547e0880b9SHoria Geantă  * @era: SEC Era
558cea7b66SHoria Geantă  */
cnstr_shdsc_aead_null_encap(u32 * const desc,struct alginfo * adata,unsigned int icvsize,int era)568cea7b66SHoria Geantă void cnstr_shdsc_aead_null_encap(u32 * const desc, struct alginfo *adata,
577e0880b9SHoria Geantă 				 unsigned int icvsize, int era)
588cea7b66SHoria Geantă {
598cea7b66SHoria Geantă 	u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
608cea7b66SHoria Geantă 
618cea7b66SHoria Geantă 	init_sh_desc(desc, HDR_SHARE_SERIAL);
628cea7b66SHoria Geantă 
638cea7b66SHoria Geantă 	/* Skip if already shared */
648cea7b66SHoria Geantă 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
658cea7b66SHoria Geantă 				   JUMP_COND_SHRD);
667e0880b9SHoria Geantă 	if (era < 6) {
678cea7b66SHoria Geantă 		if (adata->key_inline)
687e0880b9SHoria Geantă 			append_key_as_imm(desc, adata->key_virt,
697e0880b9SHoria Geantă 					  adata->keylen_pad, adata->keylen,
707e0880b9SHoria Geantă 					  CLASS_2 | KEY_DEST_MDHA_SPLIT |
718cea7b66SHoria Geantă 					  KEY_ENC);
728cea7b66SHoria Geantă 		else
737e0880b9SHoria Geantă 			append_key(desc, adata->key_dma, adata->keylen,
747e0880b9SHoria Geantă 				   CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
757e0880b9SHoria Geantă 	} else {
767e0880b9SHoria Geantă 		append_proto_dkp(desc, adata);
777e0880b9SHoria Geantă 	}
788cea7b66SHoria Geantă 	set_jump_tgt_here(desc, key_jump_cmd);
798cea7b66SHoria Geantă 
808cea7b66SHoria Geantă 	/* assoclen + cryptlen = seqinlen */
818cea7b66SHoria Geantă 	append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
828cea7b66SHoria Geantă 
838cea7b66SHoria Geantă 	/* Prepare to read and write cryptlen + assoclen bytes */
848cea7b66SHoria Geantă 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
858cea7b66SHoria Geantă 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
868cea7b66SHoria Geantă 
878cea7b66SHoria Geantă 	/*
888cea7b66SHoria Geantă 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
898cea7b66SHoria Geantă 	 * thus need to do some magic, i.e. self-patch the descriptor
908cea7b66SHoria Geantă 	 * buffer.
918cea7b66SHoria Geantă 	 */
928cea7b66SHoria Geantă 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
938cea7b66SHoria Geantă 				    MOVE_DEST_MATH3 |
948cea7b66SHoria Geantă 				    (0x6 << MOVE_LEN_SHIFT));
958cea7b66SHoria Geantă 	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 |
968cea7b66SHoria Geantă 				     MOVE_DEST_DESCBUF |
978cea7b66SHoria Geantă 				     MOVE_WAITCOMP |
988cea7b66SHoria Geantă 				     (0x8 << MOVE_LEN_SHIFT));
998cea7b66SHoria Geantă 
1008cea7b66SHoria Geantă 	/* Class 2 operation */
1018cea7b66SHoria Geantă 	append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
1028cea7b66SHoria Geantă 			 OP_ALG_ENCRYPT);
1038cea7b66SHoria Geantă 
1048cea7b66SHoria Geantă 	/* Read and write cryptlen bytes */
1058cea7b66SHoria Geantă 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
1068cea7b66SHoria Geantă 
1078cea7b66SHoria Geantă 	set_move_tgt_here(desc, read_move_cmd);
1088cea7b66SHoria Geantă 	set_move_tgt_here(desc, write_move_cmd);
1098cea7b66SHoria Geantă 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
1108cea7b66SHoria Geantă 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
1118cea7b66SHoria Geantă 		    MOVE_AUX_LS);
1128cea7b66SHoria Geantă 
1138cea7b66SHoria Geantă 	/* Write ICV */
1148cea7b66SHoria Geantă 	append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
1158cea7b66SHoria Geantă 			 LDST_SRCDST_BYTE_CONTEXT);
1168cea7b66SHoria Geantă 
1176e005503SSascha Hauer 	print_hex_dump_debug("aead null enc shdesc@" __stringify(__LINE__)": ",
1186e005503SSascha Hauer 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1196e005503SSascha Hauer 			     1);
1208cea7b66SHoria Geantă }
1218cea7b66SHoria Geantă EXPORT_SYMBOL(cnstr_shdsc_aead_null_encap);
1228cea7b66SHoria Geantă 
1238cea7b66SHoria Geantă /**
1248cea7b66SHoria Geantă  * cnstr_shdsc_aead_null_decap - IPSec ESP decapsulation shared descriptor
1258cea7b66SHoria Geantă  *                               (non-protocol) with no (null) decryption.
1268cea7b66SHoria Geantă  * @desc: pointer to buffer used for descriptor construction
1277e0880b9SHoria Geantă  * @adata: pointer to authentication transform definitions.
1287e0880b9SHoria Geantă  *         A split key is required for SEC Era < 6; the size of the split key
1297e0880b9SHoria Geantă  *         is specified in this case. Valid algorithm values - one of
1307e0880b9SHoria Geantă  *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
1317e0880b9SHoria Geantă  *         with OP_ALG_AAI_HMAC_PRECOMP.
1328cea7b66SHoria Geantă  * @icvsize: integrity check value (ICV) size (truncated or full)
1337e0880b9SHoria Geantă  * @era: SEC Era
1348cea7b66SHoria Geantă  */
cnstr_shdsc_aead_null_decap(u32 * const desc,struct alginfo * adata,unsigned int icvsize,int era)1358cea7b66SHoria Geantă void cnstr_shdsc_aead_null_decap(u32 * const desc, struct alginfo *adata,
1367e0880b9SHoria Geantă 				 unsigned int icvsize, int era)
1378cea7b66SHoria Geantă {
1388cea7b66SHoria Geantă 	u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd, *jump_cmd;
1398cea7b66SHoria Geantă 
1408cea7b66SHoria Geantă 	init_sh_desc(desc, HDR_SHARE_SERIAL);
1418cea7b66SHoria Geantă 
1428cea7b66SHoria Geantă 	/* Skip if already shared */
1438cea7b66SHoria Geantă 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1448cea7b66SHoria Geantă 				   JUMP_COND_SHRD);
1457e0880b9SHoria Geantă 	if (era < 6) {
1468cea7b66SHoria Geantă 		if (adata->key_inline)
1477e0880b9SHoria Geantă 			append_key_as_imm(desc, adata->key_virt,
1487e0880b9SHoria Geantă 					  adata->keylen_pad, adata->keylen,
1497e0880b9SHoria Geantă 					  CLASS_2 | KEY_DEST_MDHA_SPLIT |
1507e0880b9SHoria Geantă 					  KEY_ENC);
1518cea7b66SHoria Geantă 		else
1527e0880b9SHoria Geantă 			append_key(desc, adata->key_dma, adata->keylen,
1537e0880b9SHoria Geantă 				   CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
1547e0880b9SHoria Geantă 	} else {
1557e0880b9SHoria Geantă 		append_proto_dkp(desc, adata);
1567e0880b9SHoria Geantă 	}
1578cea7b66SHoria Geantă 	set_jump_tgt_here(desc, key_jump_cmd);
1588cea7b66SHoria Geantă 
1598cea7b66SHoria Geantă 	/* Class 2 operation */
1608cea7b66SHoria Geantă 	append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
1618cea7b66SHoria Geantă 			 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
1628cea7b66SHoria Geantă 
1638cea7b66SHoria Geantă 	/* assoclen + cryptlen = seqoutlen */
1648cea7b66SHoria Geantă 	append_math_sub(desc, REG2, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1658cea7b66SHoria Geantă 
1668cea7b66SHoria Geantă 	/* Prepare to read and write cryptlen + assoclen bytes */
1678cea7b66SHoria Geantă 	append_math_add(desc, VARSEQINLEN, ZERO, REG2, CAAM_CMD_SZ);
1688cea7b66SHoria Geantă 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG2, CAAM_CMD_SZ);
1698cea7b66SHoria Geantă 
1708cea7b66SHoria Geantă 	/*
1718cea7b66SHoria Geantă 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
1728cea7b66SHoria Geantă 	 * thus need to do some magic, i.e. self-patch the descriptor
1738cea7b66SHoria Geantă 	 * buffer.
1748cea7b66SHoria Geantă 	 */
1758cea7b66SHoria Geantă 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
1768cea7b66SHoria Geantă 				    MOVE_DEST_MATH2 |
1778cea7b66SHoria Geantă 				    (0x6 << MOVE_LEN_SHIFT));
1788cea7b66SHoria Geantă 	write_move_cmd = append_move(desc, MOVE_SRC_MATH2 |
1798cea7b66SHoria Geantă 				     MOVE_DEST_DESCBUF |
1808cea7b66SHoria Geantă 				     MOVE_WAITCOMP |
1818cea7b66SHoria Geantă 				     (0x8 << MOVE_LEN_SHIFT));
1828cea7b66SHoria Geantă 
1838cea7b66SHoria Geantă 	/* Read and write cryptlen bytes */
1848cea7b66SHoria Geantă 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
1858cea7b66SHoria Geantă 
1868cea7b66SHoria Geantă 	/*
1878cea7b66SHoria Geantă 	 * Insert a NOP here, since we need at least 4 instructions between
1888cea7b66SHoria Geantă 	 * code patching the descriptor buffer and the location being patched.
1898cea7b66SHoria Geantă 	 */
1908cea7b66SHoria Geantă 	jump_cmd = append_jump(desc, JUMP_TEST_ALL);
1918cea7b66SHoria Geantă 	set_jump_tgt_here(desc, jump_cmd);
1928cea7b66SHoria Geantă 
1938cea7b66SHoria Geantă 	set_move_tgt_here(desc, read_move_cmd);
1948cea7b66SHoria Geantă 	set_move_tgt_here(desc, write_move_cmd);
1958cea7b66SHoria Geantă 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
1968cea7b66SHoria Geantă 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
1978cea7b66SHoria Geantă 		    MOVE_AUX_LS);
1988cea7b66SHoria Geantă 	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
1998cea7b66SHoria Geantă 
2008cea7b66SHoria Geantă 	/* Load ICV */
2018cea7b66SHoria Geantă 	append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
2028cea7b66SHoria Geantă 			     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
2038cea7b66SHoria Geantă 
2046e005503SSascha Hauer 	print_hex_dump_debug("aead null dec shdesc@" __stringify(__LINE__)": ",
2056e005503SSascha Hauer 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
2066e005503SSascha Hauer 			     1);
2078cea7b66SHoria Geantă }
2088cea7b66SHoria Geantă EXPORT_SYMBOL(cnstr_shdsc_aead_null_decap);
2098cea7b66SHoria Geantă 
init_sh_desc_key_aead(u32 * const desc,struct alginfo * const cdata,struct alginfo * const adata,const bool is_rfc3686,u32 * nonce,int era)2108cea7b66SHoria Geantă static void init_sh_desc_key_aead(u32 * const desc,
2118cea7b66SHoria Geantă 				  struct alginfo * const cdata,
2128cea7b66SHoria Geantă 				  struct alginfo * const adata,
2137e0880b9SHoria Geantă 				  const bool is_rfc3686, u32 *nonce, int era)
2148cea7b66SHoria Geantă {
2158cea7b66SHoria Geantă 	u32 *key_jump_cmd;
2168cea7b66SHoria Geantă 	unsigned int enckeylen = cdata->keylen;
2178cea7b66SHoria Geantă 
2188cea7b66SHoria Geantă 	/* Note: Context registers are saved. */
2198cea7b66SHoria Geantă 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
2208cea7b66SHoria Geantă 
2218cea7b66SHoria Geantă 	/* Skip if already shared */
2228cea7b66SHoria Geantă 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
2238cea7b66SHoria Geantă 				   JUMP_COND_SHRD);
2248cea7b66SHoria Geantă 
2258cea7b66SHoria Geantă 	/*
2268cea7b66SHoria Geantă 	 * RFC3686 specific:
2278cea7b66SHoria Geantă 	 *	| key = {AUTH_KEY, ENC_KEY, NONCE}
2288cea7b66SHoria Geantă 	 *	| enckeylen = encryption key size + nonce size
2298cea7b66SHoria Geantă 	 */
2308cea7b66SHoria Geantă 	if (is_rfc3686)
2318cea7b66SHoria Geantă 		enckeylen -= CTR_RFC3686_NONCE_SIZE;
2328cea7b66SHoria Geantă 
2337e0880b9SHoria Geantă 	if (era < 6) {
2348cea7b66SHoria Geantă 		if (adata->key_inline)
2357e0880b9SHoria Geantă 			append_key_as_imm(desc, adata->key_virt,
2367e0880b9SHoria Geantă 					  adata->keylen_pad, adata->keylen,
2377e0880b9SHoria Geantă 					  CLASS_2 | KEY_DEST_MDHA_SPLIT |
2387e0880b9SHoria Geantă 					  KEY_ENC);
2398cea7b66SHoria Geantă 		else
2407e0880b9SHoria Geantă 			append_key(desc, adata->key_dma, adata->keylen,
2417e0880b9SHoria Geantă 				   CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
2427e0880b9SHoria Geantă 	} else {
2437e0880b9SHoria Geantă 		append_proto_dkp(desc, adata);
2447e0880b9SHoria Geantă 	}
2458cea7b66SHoria Geantă 
2468cea7b66SHoria Geantă 	if (cdata->key_inline)
2479c0bc511SArnd Bergmann 		append_key_as_imm(desc, cdata->key_virt, enckeylen,
2488cea7b66SHoria Geantă 				  enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
2498cea7b66SHoria Geantă 	else
2509c0bc511SArnd Bergmann 		append_key(desc, cdata->key_dma, enckeylen, CLASS_1 |
2518cea7b66SHoria Geantă 			   KEY_DEST_CLASS_REG);
2528cea7b66SHoria Geantă 
2538cea7b66SHoria Geantă 	/* Load Counter into CONTEXT1 reg */
2548cea7b66SHoria Geantă 	if (is_rfc3686) {
2558cea7b66SHoria Geantă 		append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
2568cea7b66SHoria Geantă 				   LDST_CLASS_IND_CCB |
2578cea7b66SHoria Geantă 				   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
2588cea7b66SHoria Geantă 		append_move(desc,
2598cea7b66SHoria Geantă 			    MOVE_SRC_OUTFIFO |
2608cea7b66SHoria Geantă 			    MOVE_DEST_CLASS1CTX |
2618cea7b66SHoria Geantă 			    (16 << MOVE_OFFSET_SHIFT) |
2628cea7b66SHoria Geantă 			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
2638cea7b66SHoria Geantă 	}
2648cea7b66SHoria Geantă 
2658cea7b66SHoria Geantă 	set_jump_tgt_here(desc, key_jump_cmd);
2668cea7b66SHoria Geantă }
2678cea7b66SHoria Geantă 
2688cea7b66SHoria Geantă /**
2698cea7b66SHoria Geantă  * cnstr_shdsc_aead_encap - IPSec ESP encapsulation shared descriptor
2708cea7b66SHoria Geantă  *                          (non-protocol).
2718cea7b66SHoria Geantă  * @desc: pointer to buffer used for descriptor construction
2728cea7b66SHoria Geantă  * @cdata: pointer to block cipher transform definitions
2738cea7b66SHoria Geantă  *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
2748cea7b66SHoria Geantă  *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
2757e0880b9SHoria Geantă  * @adata: pointer to authentication transform definitions.
2767e0880b9SHoria Geantă  *         A split key is required for SEC Era < 6; the size of the split key
2777e0880b9SHoria Geantă  *         is specified in this case. Valid algorithm values - one of
2787e0880b9SHoria Geantă  *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
2797e0880b9SHoria Geantă  *         with OP_ALG_AAI_HMAC_PRECOMP.
280b189817cSHoria Geantă  * @ivsize: initialization vector size
2818cea7b66SHoria Geantă  * @icvsize: integrity check value (ICV) size (truncated or full)
2828cea7b66SHoria Geantă  * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
2838cea7b66SHoria Geantă  * @nonce: pointer to rfc3686 nonce
2848cea7b66SHoria Geantă  * @ctx1_iv_off: IV offset in CONTEXT1 register
285b189817cSHoria Geantă  * @is_qi: true when called from caam/qi
2867e0880b9SHoria Geantă  * @era: SEC Era
2878cea7b66SHoria Geantă  */
cnstr_shdsc_aead_encap(u32 * const desc,struct alginfo * cdata,struct alginfo * adata,unsigned int ivsize,unsigned int icvsize,const bool is_rfc3686,u32 * nonce,const u32 ctx1_iv_off,const bool is_qi,int era)2888cea7b66SHoria Geantă void cnstr_shdsc_aead_encap(u32 * const desc, struct alginfo *cdata,
289b189817cSHoria Geantă 			    struct alginfo *adata, unsigned int ivsize,
290b189817cSHoria Geantă 			    unsigned int icvsize, const bool is_rfc3686,
2917e0880b9SHoria Geantă 			    u32 *nonce, const u32 ctx1_iv_off, const bool is_qi,
2927e0880b9SHoria Geantă 			    int era)
2938cea7b66SHoria Geantă {
2948cea7b66SHoria Geantă 	/* Note: Context registers are saved. */
2957e0880b9SHoria Geantă 	init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
2968cea7b66SHoria Geantă 
2978cea7b66SHoria Geantă 	/* Class 2 operation */
2988cea7b66SHoria Geantă 	append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
2998cea7b66SHoria Geantă 			 OP_ALG_ENCRYPT);
3008cea7b66SHoria Geantă 
301b189817cSHoria Geantă 	if (is_qi) {
302b189817cSHoria Geantă 		u32 *wait_load_cmd;
303b189817cSHoria Geantă 
304b189817cSHoria Geantă 		/* REG3 = assoclen */
305b189817cSHoria Geantă 		append_seq_load(desc, 4, LDST_CLASS_DECO |
306b189817cSHoria Geantă 				LDST_SRCDST_WORD_DECO_MATH3 |
307b189817cSHoria Geantă 				(4 << LDST_OFFSET_SHIFT));
308b189817cSHoria Geantă 
309b189817cSHoria Geantă 		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
310b189817cSHoria Geantă 					    JUMP_COND_CALM | JUMP_COND_NCP |
311b189817cSHoria Geantă 					    JUMP_COND_NOP | JUMP_COND_NIP |
312b189817cSHoria Geantă 					    JUMP_COND_NIFP);
313b189817cSHoria Geantă 		set_jump_tgt_here(desc, wait_load_cmd);
314b189817cSHoria Geantă 
315b189817cSHoria Geantă 		append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
316b189817cSHoria Geantă 				LDST_SRCDST_BYTE_CONTEXT |
317b189817cSHoria Geantă 				(ctx1_iv_off << LDST_OFFSET_SHIFT));
318b189817cSHoria Geantă 	}
319b189817cSHoria Geantă 
3208cea7b66SHoria Geantă 	/* Read and write assoclen bytes */
3217e0880b9SHoria Geantă 	if (is_qi || era < 3) {
3228cea7b66SHoria Geantă 		append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
3238cea7b66SHoria Geantă 		append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
3247e0880b9SHoria Geantă 	} else {
3257e0880b9SHoria Geantă 		append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
3267e0880b9SHoria Geantă 		append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
3277e0880b9SHoria Geantă 	}
3288cea7b66SHoria Geantă 
3298cea7b66SHoria Geantă 	/* Skip assoc data */
3308cea7b66SHoria Geantă 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
3318cea7b66SHoria Geantă 
3328cea7b66SHoria Geantă 	/* read assoc before reading payload */
3338cea7b66SHoria Geantă 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
3348cea7b66SHoria Geantă 				      FIFOLDST_VLF);
3358cea7b66SHoria Geantă 
3368cea7b66SHoria Geantă 	/* Load Counter into CONTEXT1 reg */
3378cea7b66SHoria Geantă 	if (is_rfc3686)
3388cea7b66SHoria Geantă 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
3398cea7b66SHoria Geantă 				     LDST_SRCDST_BYTE_CONTEXT |
3408cea7b66SHoria Geantă 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
3418cea7b66SHoria Geantă 				      LDST_OFFSET_SHIFT));
3428cea7b66SHoria Geantă 
3438cea7b66SHoria Geantă 	/* Class 1 operation */
3448cea7b66SHoria Geantă 	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
3458cea7b66SHoria Geantă 			 OP_ALG_ENCRYPT);
3468cea7b66SHoria Geantă 
3478cea7b66SHoria Geantă 	/* Read and write cryptlen bytes */
3488cea7b66SHoria Geantă 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
3498cea7b66SHoria Geantă 	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
3508cea7b66SHoria Geantă 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
3518cea7b66SHoria Geantă 
3528cea7b66SHoria Geantă 	/* Write ICV */
3538cea7b66SHoria Geantă 	append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
3548cea7b66SHoria Geantă 			 LDST_SRCDST_BYTE_CONTEXT);
3558cea7b66SHoria Geantă 
3566e005503SSascha Hauer 	print_hex_dump_debug("aead enc shdesc@" __stringify(__LINE__)": ",
3576e005503SSascha Hauer 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
3586e005503SSascha Hauer 			     1);
3598cea7b66SHoria Geantă }
3608cea7b66SHoria Geantă EXPORT_SYMBOL(cnstr_shdsc_aead_encap);
3618cea7b66SHoria Geantă 
3628cea7b66SHoria Geantă /**
3638cea7b66SHoria Geantă  * cnstr_shdsc_aead_decap - IPSec ESP decapsulation shared descriptor
3648cea7b66SHoria Geantă  *                          (non-protocol).
3658cea7b66SHoria Geantă  * @desc: pointer to buffer used for descriptor construction
3668cea7b66SHoria Geantă  * @cdata: pointer to block cipher transform definitions
3678cea7b66SHoria Geantă  *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
3688cea7b66SHoria Geantă  *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
3697e0880b9SHoria Geantă  * @adata: pointer to authentication transform definitions.
3707e0880b9SHoria Geantă  *         A split key is required for SEC Era < 6; the size of the split key
3717e0880b9SHoria Geantă  *         is specified in this case. Valid algorithm values - one of
3727e0880b9SHoria Geantă  *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
3737e0880b9SHoria Geantă  *         with OP_ALG_AAI_HMAC_PRECOMP.
3748cea7b66SHoria Geantă  * @ivsize: initialization vector size
3758cea7b66SHoria Geantă  * @icvsize: integrity check value (ICV) size (truncated or full)
376319936bfSKrzysztof Kozlowski  * @geniv: whether to generate Encrypted Chain IV
3778cea7b66SHoria Geantă  * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
3788cea7b66SHoria Geantă  * @nonce: pointer to rfc3686 nonce
3798cea7b66SHoria Geantă  * @ctx1_iv_off: IV offset in CONTEXT1 register
380b189817cSHoria Geantă  * @is_qi: true when called from caam/qi
3817e0880b9SHoria Geantă  * @era: SEC Era
3828cea7b66SHoria Geantă  */
cnstr_shdsc_aead_decap(u32 * const desc,struct alginfo * cdata,struct alginfo * adata,unsigned int ivsize,unsigned int icvsize,const bool geniv,const bool is_rfc3686,u32 * nonce,const u32 ctx1_iv_off,const bool is_qi,int era)3838cea7b66SHoria Geantă void cnstr_shdsc_aead_decap(u32 * const desc, struct alginfo *cdata,
3848cea7b66SHoria Geantă 			    struct alginfo *adata, unsigned int ivsize,
3858cea7b66SHoria Geantă 			    unsigned int icvsize, const bool geniv,
3868cea7b66SHoria Geantă 			    const bool is_rfc3686, u32 *nonce,
3877e0880b9SHoria Geantă 			    const u32 ctx1_iv_off, const bool is_qi, int era)
3888cea7b66SHoria Geantă {
3898cea7b66SHoria Geantă 	/* Note: Context registers are saved. */
3907e0880b9SHoria Geantă 	init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
3918cea7b66SHoria Geantă 
3928cea7b66SHoria Geantă 	/* Class 2 operation */
3938cea7b66SHoria Geantă 	append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
3948cea7b66SHoria Geantă 			 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
3958cea7b66SHoria Geantă 
396b189817cSHoria Geantă 	if (is_qi) {
397b189817cSHoria Geantă 		u32 *wait_load_cmd;
398b189817cSHoria Geantă 
399b189817cSHoria Geantă 		/* REG3 = assoclen */
400b189817cSHoria Geantă 		append_seq_load(desc, 4, LDST_CLASS_DECO |
401b189817cSHoria Geantă 				LDST_SRCDST_WORD_DECO_MATH3 |
402b189817cSHoria Geantă 				(4 << LDST_OFFSET_SHIFT));
403b189817cSHoria Geantă 
404b189817cSHoria Geantă 		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
405b189817cSHoria Geantă 					    JUMP_COND_CALM | JUMP_COND_NCP |
406b189817cSHoria Geantă 					    JUMP_COND_NOP | JUMP_COND_NIP |
407b189817cSHoria Geantă 					    JUMP_COND_NIFP);
408b189817cSHoria Geantă 		set_jump_tgt_here(desc, wait_load_cmd);
409b189817cSHoria Geantă 
410b189817cSHoria Geantă 		if (!geniv)
411b189817cSHoria Geantă 			append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
412b189817cSHoria Geantă 					LDST_SRCDST_BYTE_CONTEXT |
413b189817cSHoria Geantă 					(ctx1_iv_off << LDST_OFFSET_SHIFT));
414b189817cSHoria Geantă 	}
415b189817cSHoria Geantă 
4168cea7b66SHoria Geantă 	/* Read and write assoclen bytes */
4177e0880b9SHoria Geantă 	if (is_qi || era < 3) {
4188cea7b66SHoria Geantă 		append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
4198cea7b66SHoria Geantă 		if (geniv)
4207e0880b9SHoria Geantă 			append_math_add_imm_u32(desc, VARSEQOUTLEN, REG3, IMM,
4217e0880b9SHoria Geantă 						ivsize);
4228cea7b66SHoria Geantă 		else
4237e0880b9SHoria Geantă 			append_math_add(desc, VARSEQOUTLEN, ZERO, REG3,
4247e0880b9SHoria Geantă 					CAAM_CMD_SZ);
4257e0880b9SHoria Geantă 	} else {
4267e0880b9SHoria Geantă 		append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
4277e0880b9SHoria Geantă 		if (geniv)
4287e0880b9SHoria Geantă 			append_math_add_imm_u32(desc, VARSEQOUTLEN, DPOVRD, IMM,
4297e0880b9SHoria Geantă 						ivsize);
4307e0880b9SHoria Geantă 		else
4317e0880b9SHoria Geantă 			append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD,
4327e0880b9SHoria Geantă 					CAAM_CMD_SZ);
4337e0880b9SHoria Geantă 	}
4348cea7b66SHoria Geantă 
4358cea7b66SHoria Geantă 	/* Skip assoc data */
4368cea7b66SHoria Geantă 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
4378cea7b66SHoria Geantă 
4388cea7b66SHoria Geantă 	/* read assoc before reading payload */
4398cea7b66SHoria Geantă 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
4408cea7b66SHoria Geantă 			     KEY_VLF);
4418cea7b66SHoria Geantă 
4428cea7b66SHoria Geantă 	if (geniv) {
4438cea7b66SHoria Geantă 		append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
4448cea7b66SHoria Geantă 				LDST_SRCDST_BYTE_CONTEXT |
4458cea7b66SHoria Geantă 				(ctx1_iv_off << LDST_OFFSET_SHIFT));
4468cea7b66SHoria Geantă 		append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO |
4478cea7b66SHoria Geantă 			    (ctx1_iv_off << MOVE_OFFSET_SHIFT) | ivsize);
4488cea7b66SHoria Geantă 	}
4498cea7b66SHoria Geantă 
4508cea7b66SHoria Geantă 	/* Load Counter into CONTEXT1 reg */
4518cea7b66SHoria Geantă 	if (is_rfc3686)
4528cea7b66SHoria Geantă 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
4538cea7b66SHoria Geantă 				     LDST_SRCDST_BYTE_CONTEXT |
4548cea7b66SHoria Geantă 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
4558cea7b66SHoria Geantă 				      LDST_OFFSET_SHIFT));
4568cea7b66SHoria Geantă 
4578cea7b66SHoria Geantă 	/* Choose operation */
4588cea7b66SHoria Geantă 	if (ctx1_iv_off)
4598cea7b66SHoria Geantă 		append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
4608cea7b66SHoria Geantă 				 OP_ALG_DECRYPT);
4618cea7b66SHoria Geantă 	else
4628cea7b66SHoria Geantă 		append_dec_op1(desc, cdata->algtype);
4638cea7b66SHoria Geantă 
4648cea7b66SHoria Geantă 	/* Read and write cryptlen bytes */
4658cea7b66SHoria Geantă 	append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
4668cea7b66SHoria Geantă 	append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
4678cea7b66SHoria Geantă 	aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
4688cea7b66SHoria Geantă 
4698cea7b66SHoria Geantă 	/* Load ICV */
4708cea7b66SHoria Geantă 	append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
4718cea7b66SHoria Geantă 			     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
4728cea7b66SHoria Geantă 
4736e005503SSascha Hauer 	print_hex_dump_debug("aead dec shdesc@" __stringify(__LINE__)": ",
4746e005503SSascha Hauer 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
4756e005503SSascha Hauer 			     1);
4768cea7b66SHoria Geantă }
4778cea7b66SHoria Geantă EXPORT_SYMBOL(cnstr_shdsc_aead_decap);
4788cea7b66SHoria Geantă 
4798cea7b66SHoria Geantă /**
4808cea7b66SHoria Geantă  * cnstr_shdsc_aead_givencap - IPSec ESP encapsulation shared descriptor
4818cea7b66SHoria Geantă  *                             (non-protocol) with HW-generated initialization
4828cea7b66SHoria Geantă  *                             vector.
4838cea7b66SHoria Geantă  * @desc: pointer to buffer used for descriptor construction
4848cea7b66SHoria Geantă  * @cdata: pointer to block cipher transform definitions
4858cea7b66SHoria Geantă  *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
4868cea7b66SHoria Geantă  *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
4877e0880b9SHoria Geantă  * @adata: pointer to authentication transform definitions.
4887e0880b9SHoria Geantă  *         A split key is required for SEC Era < 6; the size of the split key
4897e0880b9SHoria Geantă  *         is specified in this case. Valid algorithm values - one of
4907e0880b9SHoria Geantă  *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
4917e0880b9SHoria Geantă  *         with OP_ALG_AAI_HMAC_PRECOMP.
4928cea7b66SHoria Geantă  * @ivsize: initialization vector size
4938cea7b66SHoria Geantă  * @icvsize: integrity check value (ICV) size (truncated or full)
4948cea7b66SHoria Geantă  * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
4958cea7b66SHoria Geantă  * @nonce: pointer to rfc3686 nonce
4968cea7b66SHoria Geantă  * @ctx1_iv_off: IV offset in CONTEXT1 register
497b189817cSHoria Geantă  * @is_qi: true when called from caam/qi
4987e0880b9SHoria Geantă  * @era: SEC Era
4998cea7b66SHoria Geantă  */
cnstr_shdsc_aead_givencap(u32 * const desc,struct alginfo * cdata,struct alginfo * adata,unsigned int ivsize,unsigned int icvsize,const bool is_rfc3686,u32 * nonce,const u32 ctx1_iv_off,const bool is_qi,int era)5008cea7b66SHoria Geantă void cnstr_shdsc_aead_givencap(u32 * const desc, struct alginfo *cdata,
5018cea7b66SHoria Geantă 			       struct alginfo *adata, unsigned int ivsize,
5028cea7b66SHoria Geantă 			       unsigned int icvsize, const bool is_rfc3686,
503b189817cSHoria Geantă 			       u32 *nonce, const u32 ctx1_iv_off,
5047e0880b9SHoria Geantă 			       const bool is_qi, int era)
5058cea7b66SHoria Geantă {
5068cea7b66SHoria Geantă 	u32 geniv, moveiv;
50748f89d2aSHoria Geantă 	u32 *wait_cmd;
5088cea7b66SHoria Geantă 
5098cea7b66SHoria Geantă 	/* Note: Context registers are saved. */
5107e0880b9SHoria Geantă 	init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
5118cea7b66SHoria Geantă 
512b189817cSHoria Geantă 	if (is_qi) {
513b189817cSHoria Geantă 		u32 *wait_load_cmd;
514b189817cSHoria Geantă 
515b189817cSHoria Geantă 		/* REG3 = assoclen */
516b189817cSHoria Geantă 		append_seq_load(desc, 4, LDST_CLASS_DECO |
517b189817cSHoria Geantă 				LDST_SRCDST_WORD_DECO_MATH3 |
518b189817cSHoria Geantă 				(4 << LDST_OFFSET_SHIFT));
519b189817cSHoria Geantă 
520b189817cSHoria Geantă 		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
521b189817cSHoria Geantă 					    JUMP_COND_CALM | JUMP_COND_NCP |
522b189817cSHoria Geantă 					    JUMP_COND_NOP | JUMP_COND_NIP |
523b189817cSHoria Geantă 					    JUMP_COND_NIFP);
524b189817cSHoria Geantă 		set_jump_tgt_here(desc, wait_load_cmd);
525b189817cSHoria Geantă 	}
526b189817cSHoria Geantă 
527b189817cSHoria Geantă 	if (is_rfc3686) {
528b189817cSHoria Geantă 		if (is_qi)
529b189817cSHoria Geantă 			append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
530b189817cSHoria Geantă 					LDST_SRCDST_BYTE_CONTEXT |
531b189817cSHoria Geantă 					(ctx1_iv_off << LDST_OFFSET_SHIFT));
532b189817cSHoria Geantă 
5338cea7b66SHoria Geantă 		goto copy_iv;
534b189817cSHoria Geantă 	}
5358cea7b66SHoria Geantă 
5368cea7b66SHoria Geantă 	/* Generate IV */
5378cea7b66SHoria Geantă 	geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
5388cea7b66SHoria Geantă 		NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 |
5398cea7b66SHoria Geantă 		NFIFOENTRY_PTYPE_RND | (ivsize << NFIFOENTRY_DLEN_SHIFT);
5408cea7b66SHoria Geantă 	append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
5418cea7b66SHoria Geantă 			    LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
5428cea7b66SHoria Geantă 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
5438cea7b66SHoria Geantă 	append_move(desc, MOVE_WAITCOMP |
5448cea7b66SHoria Geantă 		    MOVE_SRC_INFIFO | MOVE_DEST_CLASS1CTX |
5458cea7b66SHoria Geantă 		    (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
5468cea7b66SHoria Geantă 		    (ivsize << MOVE_LEN_SHIFT));
5478cea7b66SHoria Geantă 	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
5488cea7b66SHoria Geantă 
5498cea7b66SHoria Geantă copy_iv:
5508cea7b66SHoria Geantă 	/* Copy IV to class 1 context */
5518cea7b66SHoria Geantă 	append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_OUTFIFO |
5528cea7b66SHoria Geantă 		    (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
5538cea7b66SHoria Geantă 		    (ivsize << MOVE_LEN_SHIFT));
5548cea7b66SHoria Geantă 
5558cea7b66SHoria Geantă 	/* Return to encryption */
5568cea7b66SHoria Geantă 	append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
5578cea7b66SHoria Geantă 			 OP_ALG_ENCRYPT);
5588cea7b66SHoria Geantă 
5598cea7b66SHoria Geantă 	/* Read and write assoclen bytes */
5607e0880b9SHoria Geantă 	if (is_qi || era < 3) {
5618cea7b66SHoria Geantă 		append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
5628cea7b66SHoria Geantă 		append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
5637e0880b9SHoria Geantă 	} else {
5647e0880b9SHoria Geantă 		append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
5657e0880b9SHoria Geantă 		append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
5667e0880b9SHoria Geantă 	}
5678cea7b66SHoria Geantă 
5688cea7b66SHoria Geantă 	/* Skip assoc data */
5698cea7b66SHoria Geantă 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
5708cea7b66SHoria Geantă 
5718cea7b66SHoria Geantă 	/* read assoc before reading payload */
5728cea7b66SHoria Geantă 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
5738cea7b66SHoria Geantă 			     KEY_VLF);
5748cea7b66SHoria Geantă 
5758cea7b66SHoria Geantă 	/* Copy iv from outfifo to class 2 fifo */
5768cea7b66SHoria Geantă 	moveiv = NFIFOENTRY_STYPE_OFIFO | NFIFOENTRY_DEST_CLASS2 |
5778cea7b66SHoria Geantă 		 NFIFOENTRY_DTYPE_MSG | (ivsize << NFIFOENTRY_DLEN_SHIFT);
5788cea7b66SHoria Geantă 	append_load_imm_u32(desc, moveiv, LDST_CLASS_IND_CCB |
5798cea7b66SHoria Geantă 			    LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
5808cea7b66SHoria Geantă 	append_load_imm_u32(desc, ivsize, LDST_CLASS_2_CCB |
5818cea7b66SHoria Geantă 			    LDST_SRCDST_WORD_DATASZ_REG | LDST_IMM);
5828cea7b66SHoria Geantă 
5838cea7b66SHoria Geantă 	/* Load Counter into CONTEXT1 reg */
5848cea7b66SHoria Geantă 	if (is_rfc3686)
5858cea7b66SHoria Geantă 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
5868cea7b66SHoria Geantă 				     LDST_SRCDST_BYTE_CONTEXT |
5878cea7b66SHoria Geantă 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
5888cea7b66SHoria Geantă 				      LDST_OFFSET_SHIFT));
5898cea7b66SHoria Geantă 
5908cea7b66SHoria Geantă 	/* Class 1 operation */
5918cea7b66SHoria Geantă 	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
5928cea7b66SHoria Geantă 			 OP_ALG_ENCRYPT);
5938cea7b66SHoria Geantă 
5948cea7b66SHoria Geantă 	/* Will write ivsize + cryptlen */
5958cea7b66SHoria Geantă 	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
5968cea7b66SHoria Geantă 
5978cea7b66SHoria Geantă 	/* Not need to reload iv */
5988cea7b66SHoria Geantă 	append_seq_fifo_load(desc, ivsize,
5998cea7b66SHoria Geantă 			     FIFOLD_CLASS_SKIP);
6008cea7b66SHoria Geantă 
6018cea7b66SHoria Geantă 	/* Will read cryptlen */
6028cea7b66SHoria Geantă 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
60348f89d2aSHoria Geantă 
60448f89d2aSHoria Geantă 	/*
60548f89d2aSHoria Geantă 	 * Wait for IV transfer (ofifo -> class2) to finish before starting
60648f89d2aSHoria Geantă 	 * ciphertext transfer (ofifo -> external memory).
60748f89d2aSHoria Geantă 	 */
60848f89d2aSHoria Geantă 	wait_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | JUMP_COND_NIFP);
60948f89d2aSHoria Geantă 	set_jump_tgt_here(desc, wait_cmd);
61048f89d2aSHoria Geantă 
6118cea7b66SHoria Geantă 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | KEY_VLF |
6128cea7b66SHoria Geantă 			     FIFOLD_TYPE_MSG1OUT2 | FIFOLD_TYPE_LASTBOTH);
6138cea7b66SHoria Geantă 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
6148cea7b66SHoria Geantă 
6158cea7b66SHoria Geantă 	/* Write ICV */
6168cea7b66SHoria Geantă 	append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
6178cea7b66SHoria Geantă 			 LDST_SRCDST_BYTE_CONTEXT);
6188cea7b66SHoria Geantă 
6196e005503SSascha Hauer 	print_hex_dump_debug("aead givenc shdesc@" __stringify(__LINE__)": ",
6206e005503SSascha Hauer 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
6216e005503SSascha Hauer 			     1);
6228cea7b66SHoria Geantă }
6238cea7b66SHoria Geantă EXPORT_SYMBOL(cnstr_shdsc_aead_givencap);
6248cea7b66SHoria Geantă 
6258cea7b66SHoria Geantă /**
6268cea7b66SHoria Geantă  * cnstr_shdsc_gcm_encap - gcm encapsulation shared descriptor
6278cea7b66SHoria Geantă  * @desc: pointer to buffer used for descriptor construction
6288cea7b66SHoria Geantă  * @cdata: pointer to block cipher transform definitions
6298cea7b66SHoria Geantă  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
63087ec3a0bSHoria Geantă  * @ivsize: initialization vector size
6318cea7b66SHoria Geantă  * @icvsize: integrity check value (ICV) size (truncated or full)
63287ec3a0bSHoria Geantă  * @is_qi: true when called from caam/qi
6338cea7b66SHoria Geantă  */
cnstr_shdsc_gcm_encap(u32 * const desc,struct alginfo * cdata,unsigned int ivsize,unsigned int icvsize,const bool is_qi)6348cea7b66SHoria Geantă void cnstr_shdsc_gcm_encap(u32 * const desc, struct alginfo *cdata,
63587ec3a0bSHoria Geantă 			   unsigned int ivsize, unsigned int icvsize,
63687ec3a0bSHoria Geantă 			   const bool is_qi)
6378cea7b66SHoria Geantă {
6388cea7b66SHoria Geantă 	u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1,
6398cea7b66SHoria Geantă 	    *zero_assoc_jump_cmd2;
6408cea7b66SHoria Geantă 
6418cea7b66SHoria Geantă 	init_sh_desc(desc, HDR_SHARE_SERIAL);
6428cea7b66SHoria Geantă 
6438cea7b66SHoria Geantă 	/* skip key loading if they are loaded due to sharing */
6448cea7b66SHoria Geantă 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
645ad818080STudor Ambarus 				   JUMP_COND_SHRD);
6468cea7b66SHoria Geantă 	if (cdata->key_inline)
6479c0bc511SArnd Bergmann 		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
6488cea7b66SHoria Geantă 				  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
6498cea7b66SHoria Geantă 	else
6509c0bc511SArnd Bergmann 		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
6518cea7b66SHoria Geantă 			   KEY_DEST_CLASS_REG);
6528cea7b66SHoria Geantă 	set_jump_tgt_here(desc, key_jump_cmd);
6538cea7b66SHoria Geantă 
6548cea7b66SHoria Geantă 	/* class 1 operation */
6558cea7b66SHoria Geantă 	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
6568cea7b66SHoria Geantă 			 OP_ALG_ENCRYPT);
6578cea7b66SHoria Geantă 
65887ec3a0bSHoria Geantă 	if (is_qi) {
65987ec3a0bSHoria Geantă 		u32 *wait_load_cmd;
66087ec3a0bSHoria Geantă 
66187ec3a0bSHoria Geantă 		/* REG3 = assoclen */
66287ec3a0bSHoria Geantă 		append_seq_load(desc, 4, LDST_CLASS_DECO |
66387ec3a0bSHoria Geantă 				LDST_SRCDST_WORD_DECO_MATH3 |
66487ec3a0bSHoria Geantă 				(4 << LDST_OFFSET_SHIFT));
66587ec3a0bSHoria Geantă 
66687ec3a0bSHoria Geantă 		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
66787ec3a0bSHoria Geantă 					    JUMP_COND_CALM | JUMP_COND_NCP |
66887ec3a0bSHoria Geantă 					    JUMP_COND_NOP | JUMP_COND_NIP |
66987ec3a0bSHoria Geantă 					    JUMP_COND_NIFP);
67087ec3a0bSHoria Geantă 		set_jump_tgt_here(desc, wait_load_cmd);
67187ec3a0bSHoria Geantă 
67287ec3a0bSHoria Geantă 		append_math_sub_imm_u32(desc, VARSEQOUTLEN, SEQINLEN, IMM,
67387ec3a0bSHoria Geantă 					ivsize);
67487ec3a0bSHoria Geantă 	} else {
67587ec3a0bSHoria Geantă 		append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0,
67687ec3a0bSHoria Geantă 				CAAM_CMD_SZ);
67787ec3a0bSHoria Geantă 	}
67887ec3a0bSHoria Geantă 
6798cea7b66SHoria Geantă 	/* if assoclen + cryptlen is ZERO, skip to ICV write */
6808cea7b66SHoria Geantă 	zero_assoc_jump_cmd2 = append_jump(desc, JUMP_TEST_ALL |
6818cea7b66SHoria Geantă 						 JUMP_COND_MATH_Z);
6828cea7b66SHoria Geantă 
68387ec3a0bSHoria Geantă 	if (is_qi)
68487ec3a0bSHoria Geantă 		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
68587ec3a0bSHoria Geantă 				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
68687ec3a0bSHoria Geantă 
6878cea7b66SHoria Geantă 	/* if assoclen is ZERO, skip reading the assoc data */
6888cea7b66SHoria Geantă 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
6898cea7b66SHoria Geantă 	zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
6908cea7b66SHoria Geantă 					   JUMP_COND_MATH_Z);
6918cea7b66SHoria Geantă 
6928cea7b66SHoria Geantă 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
6938cea7b66SHoria Geantă 
6948cea7b66SHoria Geantă 	/* skip assoc data */
6958cea7b66SHoria Geantă 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
6968cea7b66SHoria Geantă 
6978cea7b66SHoria Geantă 	/* cryptlen = seqinlen - assoclen */
6988cea7b66SHoria Geantă 	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
6998cea7b66SHoria Geantă 
7008cea7b66SHoria Geantă 	/* if cryptlen is ZERO jump to zero-payload commands */
7018cea7b66SHoria Geantă 	zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
7028cea7b66SHoria Geantă 					    JUMP_COND_MATH_Z);
7038cea7b66SHoria Geantă 
7048cea7b66SHoria Geantă 	/* read assoc data */
7058cea7b66SHoria Geantă 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
7068cea7b66SHoria Geantă 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
7078cea7b66SHoria Geantă 	set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
7088cea7b66SHoria Geantă 
7098cea7b66SHoria Geantă 	append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
7108cea7b66SHoria Geantă 
7118cea7b66SHoria Geantă 	/* write encrypted data */
7128cea7b66SHoria Geantă 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
7138cea7b66SHoria Geantă 
7148cea7b66SHoria Geantă 	/* read payload data */
7158cea7b66SHoria Geantă 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
7168cea7b66SHoria Geantă 			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
7178cea7b66SHoria Geantă 
71887ec3a0bSHoria Geantă 	/* jump to ICV writing */
71987ec3a0bSHoria Geantă 	if (is_qi)
72087ec3a0bSHoria Geantă 		append_jump(desc, JUMP_TEST_ALL | 4);
72187ec3a0bSHoria Geantă 	else
7228cea7b66SHoria Geantă 		append_jump(desc, JUMP_TEST_ALL | 2);
7238cea7b66SHoria Geantă 
7248cea7b66SHoria Geantă 	/* zero-payload commands */
7258cea7b66SHoria Geantă 	set_jump_tgt_here(desc, zero_payload_jump_cmd);
7268cea7b66SHoria Geantă 
7278cea7b66SHoria Geantă 	/* read assoc data */
7288cea7b66SHoria Geantă 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
7298cea7b66SHoria Geantă 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
73087ec3a0bSHoria Geantă 	if (is_qi)
73187ec3a0bSHoria Geantă 		/* jump to ICV writing */
73287ec3a0bSHoria Geantă 		append_jump(desc, JUMP_TEST_ALL | 2);
7338cea7b66SHoria Geantă 
7348cea7b66SHoria Geantă 	/* There is no input data */
7358cea7b66SHoria Geantă 	set_jump_tgt_here(desc, zero_assoc_jump_cmd2);
7368cea7b66SHoria Geantă 
73787ec3a0bSHoria Geantă 	if (is_qi)
73887ec3a0bSHoria Geantă 		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
73987ec3a0bSHoria Geantă 				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 |
74087ec3a0bSHoria Geantă 				     FIFOLD_TYPE_LAST1);
74187ec3a0bSHoria Geantă 
7428cea7b66SHoria Geantă 	/* write ICV */
7438cea7b66SHoria Geantă 	append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
7448cea7b66SHoria Geantă 			 LDST_SRCDST_BYTE_CONTEXT);
7458cea7b66SHoria Geantă 
7466e005503SSascha Hauer 	print_hex_dump_debug("gcm enc shdesc@" __stringify(__LINE__)": ",
7476e005503SSascha Hauer 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
7486e005503SSascha Hauer 			     1);
7498cea7b66SHoria Geantă }
7508cea7b66SHoria Geantă EXPORT_SYMBOL(cnstr_shdsc_gcm_encap);
7518cea7b66SHoria Geantă 
7528cea7b66SHoria Geantă /**
7538cea7b66SHoria Geantă  * cnstr_shdsc_gcm_decap - gcm decapsulation shared descriptor
7548cea7b66SHoria Geantă  * @desc: pointer to buffer used for descriptor construction
7558cea7b66SHoria Geantă  * @cdata: pointer to block cipher transform definitions
7568cea7b66SHoria Geantă  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
75787ec3a0bSHoria Geantă  * @ivsize: initialization vector size
7588cea7b66SHoria Geantă  * @icvsize: integrity check value (ICV) size (truncated or full)
75987ec3a0bSHoria Geantă  * @is_qi: true when called from caam/qi
7608cea7b66SHoria Geantă  */
cnstr_shdsc_gcm_decap(u32 * const desc,struct alginfo * cdata,unsigned int ivsize,unsigned int icvsize,const bool is_qi)7618cea7b66SHoria Geantă void cnstr_shdsc_gcm_decap(u32 * const desc, struct alginfo *cdata,
76287ec3a0bSHoria Geantă 			   unsigned int ivsize, unsigned int icvsize,
76387ec3a0bSHoria Geantă 			   const bool is_qi)
7648cea7b66SHoria Geantă {
7658cea7b66SHoria Geantă 	u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1;
7668cea7b66SHoria Geantă 
7678cea7b66SHoria Geantă 	init_sh_desc(desc, HDR_SHARE_SERIAL);
7688cea7b66SHoria Geantă 
7698cea7b66SHoria Geantă 	/* skip key loading if they are loaded due to sharing */
7708cea7b66SHoria Geantă 	key_jump_cmd = append_jump(desc, JUMP_JSL |
771ad818080STudor Ambarus 				   JUMP_TEST_ALL | JUMP_COND_SHRD);
7728cea7b66SHoria Geantă 	if (cdata->key_inline)
7739c0bc511SArnd Bergmann 		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
7748cea7b66SHoria Geantă 				  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
7758cea7b66SHoria Geantă 	else
7769c0bc511SArnd Bergmann 		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
7778cea7b66SHoria Geantă 			   KEY_DEST_CLASS_REG);
7788cea7b66SHoria Geantă 	set_jump_tgt_here(desc, key_jump_cmd);
7798cea7b66SHoria Geantă 
7808cea7b66SHoria Geantă 	/* class 1 operation */
7818cea7b66SHoria Geantă 	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
7828cea7b66SHoria Geantă 			 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
7838cea7b66SHoria Geantă 
78487ec3a0bSHoria Geantă 	if (is_qi) {
78587ec3a0bSHoria Geantă 		u32 *wait_load_cmd;
78687ec3a0bSHoria Geantă 
78787ec3a0bSHoria Geantă 		/* REG3 = assoclen */
78887ec3a0bSHoria Geantă 		append_seq_load(desc, 4, LDST_CLASS_DECO |
78987ec3a0bSHoria Geantă 				LDST_SRCDST_WORD_DECO_MATH3 |
79087ec3a0bSHoria Geantă 				(4 << LDST_OFFSET_SHIFT));
79187ec3a0bSHoria Geantă 
79287ec3a0bSHoria Geantă 		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
79387ec3a0bSHoria Geantă 					    JUMP_COND_CALM | JUMP_COND_NCP |
79487ec3a0bSHoria Geantă 					    JUMP_COND_NOP | JUMP_COND_NIP |
79587ec3a0bSHoria Geantă 					    JUMP_COND_NIFP);
79687ec3a0bSHoria Geantă 		set_jump_tgt_here(desc, wait_load_cmd);
79787ec3a0bSHoria Geantă 
79887ec3a0bSHoria Geantă 		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
79987ec3a0bSHoria Geantă 				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
80087ec3a0bSHoria Geantă 	}
80187ec3a0bSHoria Geantă 
8028cea7b66SHoria Geantă 	/* if assoclen is ZERO, skip reading the assoc data */
8038cea7b66SHoria Geantă 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
8048cea7b66SHoria Geantă 	zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
8058cea7b66SHoria Geantă 						 JUMP_COND_MATH_Z);
8068cea7b66SHoria Geantă 
8078cea7b66SHoria Geantă 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
8088cea7b66SHoria Geantă 
8098cea7b66SHoria Geantă 	/* skip assoc data */
8108cea7b66SHoria Geantă 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
8118cea7b66SHoria Geantă 
8128cea7b66SHoria Geantă 	/* read assoc data */
8138cea7b66SHoria Geantă 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
8148cea7b66SHoria Geantă 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
8158cea7b66SHoria Geantă 
8168cea7b66SHoria Geantă 	set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
8178cea7b66SHoria Geantă 
8188cea7b66SHoria Geantă 	/* cryptlen = seqoutlen - assoclen */
8198cea7b66SHoria Geantă 	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
8208cea7b66SHoria Geantă 
8218cea7b66SHoria Geantă 	/* jump to zero-payload command if cryptlen is zero */
8228cea7b66SHoria Geantă 	zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
8238cea7b66SHoria Geantă 					    JUMP_COND_MATH_Z);
8248cea7b66SHoria Geantă 
8258cea7b66SHoria Geantă 	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
8268cea7b66SHoria Geantă 
8278cea7b66SHoria Geantă 	/* store encrypted data */
8288cea7b66SHoria Geantă 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
8298cea7b66SHoria Geantă 
8308cea7b66SHoria Geantă 	/* read payload data */
8318cea7b66SHoria Geantă 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
8328cea7b66SHoria Geantă 			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
8338cea7b66SHoria Geantă 
8348cea7b66SHoria Geantă 	/* zero-payload command */
8358cea7b66SHoria Geantă 	set_jump_tgt_here(desc, zero_payload_jump_cmd);
8368cea7b66SHoria Geantă 
8378cea7b66SHoria Geantă 	/* read ICV */
8388cea7b66SHoria Geantă 	append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
8398cea7b66SHoria Geantă 			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
8408cea7b66SHoria Geantă 
8416e005503SSascha Hauer 	print_hex_dump_debug("gcm dec shdesc@" __stringify(__LINE__)": ",
8426e005503SSascha Hauer 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
8436e005503SSascha Hauer 			     1);
8448cea7b66SHoria Geantă }
8458cea7b66SHoria Geantă EXPORT_SYMBOL(cnstr_shdsc_gcm_decap);
8468cea7b66SHoria Geantă 
8478cea7b66SHoria Geantă /**
8488cea7b66SHoria Geantă  * cnstr_shdsc_rfc4106_encap - IPSec ESP gcm encapsulation shared descriptor
8498cea7b66SHoria Geantă  *                             (non-protocol).
8508cea7b66SHoria Geantă  * @desc: pointer to buffer used for descriptor construction
8518cea7b66SHoria Geantă  * @cdata: pointer to block cipher transform definitions
8528cea7b66SHoria Geantă  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
85387ec3a0bSHoria Geantă  * @ivsize: initialization vector size
8548cea7b66SHoria Geantă  * @icvsize: integrity check value (ICV) size (truncated or full)
85587ec3a0bSHoria Geantă  * @is_qi: true when called from caam/qi
856d28a43edSIuliana Prodan  *
857d28a43edSIuliana Prodan  * Input sequence: AAD | PTXT
858d28a43edSIuliana Prodan  * Output sequence: AAD | CTXT | ICV
859d28a43edSIuliana Prodan  * AAD length (assoclen), which includes the IV length, is available in Math3.
8608cea7b66SHoria Geantă  */
cnstr_shdsc_rfc4106_encap(u32 * const desc,struct alginfo * cdata,unsigned int ivsize,unsigned int icvsize,const bool is_qi)8618cea7b66SHoria Geantă void cnstr_shdsc_rfc4106_encap(u32 * const desc, struct alginfo *cdata,
86287ec3a0bSHoria Geantă 			       unsigned int ivsize, unsigned int icvsize,
86387ec3a0bSHoria Geantă 			       const bool is_qi)
8648cea7b66SHoria Geantă {
865d28a43edSIuliana Prodan 	u32 *key_jump_cmd, *zero_cryptlen_jump_cmd, *skip_instructions;
8668cea7b66SHoria Geantă 	init_sh_desc(desc, HDR_SHARE_SERIAL);
8678cea7b66SHoria Geantă 
8688cea7b66SHoria Geantă 	/* Skip key loading if it is loaded due to sharing */
8698cea7b66SHoria Geantă 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
8708cea7b66SHoria Geantă 				   JUMP_COND_SHRD);
8718cea7b66SHoria Geantă 	if (cdata->key_inline)
8729c0bc511SArnd Bergmann 		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
8738cea7b66SHoria Geantă 				  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
8748cea7b66SHoria Geantă 	else
8759c0bc511SArnd Bergmann 		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
8768cea7b66SHoria Geantă 			   KEY_DEST_CLASS_REG);
8778cea7b66SHoria Geantă 	set_jump_tgt_here(desc, key_jump_cmd);
8788cea7b66SHoria Geantă 
8798cea7b66SHoria Geantă 	/* Class 1 operation */
8808cea7b66SHoria Geantă 	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
8818cea7b66SHoria Geantă 			 OP_ALG_ENCRYPT);
8828cea7b66SHoria Geantă 
88387ec3a0bSHoria Geantă 	if (is_qi) {
88487ec3a0bSHoria Geantă 		u32 *wait_load_cmd;
88587ec3a0bSHoria Geantă 
88687ec3a0bSHoria Geantă 		/* REG3 = assoclen */
88787ec3a0bSHoria Geantă 		append_seq_load(desc, 4, LDST_CLASS_DECO |
88887ec3a0bSHoria Geantă 				LDST_SRCDST_WORD_DECO_MATH3 |
88987ec3a0bSHoria Geantă 				(4 << LDST_OFFSET_SHIFT));
89087ec3a0bSHoria Geantă 
89187ec3a0bSHoria Geantă 		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
89287ec3a0bSHoria Geantă 					    JUMP_COND_CALM | JUMP_COND_NCP |
89387ec3a0bSHoria Geantă 					    JUMP_COND_NOP | JUMP_COND_NIP |
89487ec3a0bSHoria Geantă 					    JUMP_COND_NIFP);
89587ec3a0bSHoria Geantă 		set_jump_tgt_here(desc, wait_load_cmd);
89687ec3a0bSHoria Geantă 
89787ec3a0bSHoria Geantă 		/* Read salt and IV */
89887ec3a0bSHoria Geantă 		append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
89987ec3a0bSHoria Geantă 					cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
90087ec3a0bSHoria Geantă 					FIFOLD_TYPE_IV);
90187ec3a0bSHoria Geantă 		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
90287ec3a0bSHoria Geantă 				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
90387ec3a0bSHoria Geantă 	}
90487ec3a0bSHoria Geantă 
90587ec3a0bSHoria Geantă 	append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, ivsize);
9068cea7b66SHoria Geantă 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
9078cea7b66SHoria Geantă 
908d28a43edSIuliana Prodan 	/* Skip AAD */
909d28a43edSIuliana Prodan 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
910d28a43edSIuliana Prodan 
911d28a43edSIuliana Prodan 	/* Read cryptlen and set this value into VARSEQOUTLEN */
912d28a43edSIuliana Prodan 	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
913d28a43edSIuliana Prodan 
914d28a43edSIuliana Prodan 	/* If cryptlen is ZERO jump to AAD command */
915d28a43edSIuliana Prodan 	zero_cryptlen_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
916d28a43edSIuliana Prodan 					    JUMP_COND_MATH_Z);
917d28a43edSIuliana Prodan 
918d28a43edSIuliana Prodan 	/* Read AAD data */
9198cea7b66SHoria Geantă 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
9208cea7b66SHoria Geantă 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
9218cea7b66SHoria Geantă 
922d28a43edSIuliana Prodan 	/* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
923d28a43edSIuliana Prodan 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA);
924d28a43edSIuliana Prodan 
9258cea7b66SHoria Geantă 	/* Skip IV */
92687ec3a0bSHoria Geantă 	append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_SKIP);
927d28a43edSIuliana Prodan 	append_math_add(desc, VARSEQINLEN, VARSEQOUTLEN, REG0, CAAM_CMD_SZ);
9288cea7b66SHoria Geantă 
9298cea7b66SHoria Geantă 	/* Write encrypted data */
9308cea7b66SHoria Geantă 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
9318cea7b66SHoria Geantă 
9328cea7b66SHoria Geantă 	/* Read payload data */
9338cea7b66SHoria Geantă 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
9348cea7b66SHoria Geantă 			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
9358cea7b66SHoria Geantă 
936d28a43edSIuliana Prodan 	/* Jump instructions to avoid double reading of AAD */
937d28a43edSIuliana Prodan 	skip_instructions = append_jump(desc, JUMP_TEST_ALL);
938d28a43edSIuliana Prodan 
939d28a43edSIuliana Prodan 	/* There is no input data, cryptlen = 0 */
940d28a43edSIuliana Prodan 	set_jump_tgt_here(desc, zero_cryptlen_jump_cmd);
941d28a43edSIuliana Prodan 
942d28a43edSIuliana Prodan 	/* Read AAD */
943d28a43edSIuliana Prodan 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
944d28a43edSIuliana Prodan 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
945d28a43edSIuliana Prodan 
946d28a43edSIuliana Prodan 	set_jump_tgt_here(desc, skip_instructions);
947d28a43edSIuliana Prodan 
9488cea7b66SHoria Geantă 	/* Write ICV */
9498cea7b66SHoria Geantă 	append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
9508cea7b66SHoria Geantă 			 LDST_SRCDST_BYTE_CONTEXT);
9518cea7b66SHoria Geantă 
9526e005503SSascha Hauer 	print_hex_dump_debug("rfc4106 enc shdesc@" __stringify(__LINE__)": ",
9536e005503SSascha Hauer 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
9546e005503SSascha Hauer 			     1);
9558cea7b66SHoria Geantă }
9568cea7b66SHoria Geantă EXPORT_SYMBOL(cnstr_shdsc_rfc4106_encap);
9578cea7b66SHoria Geantă 
9588cea7b66SHoria Geantă /**
9598cea7b66SHoria Geantă  * cnstr_shdsc_rfc4106_decap - IPSec ESP gcm decapsulation shared descriptor
9608cea7b66SHoria Geantă  *                             (non-protocol).
9618cea7b66SHoria Geantă  * @desc: pointer to buffer used for descriptor construction
9628cea7b66SHoria Geantă  * @cdata: pointer to block cipher transform definitions
9638cea7b66SHoria Geantă  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
96487ec3a0bSHoria Geantă  * @ivsize: initialization vector size
9658cea7b66SHoria Geantă  * @icvsize: integrity check value (ICV) size (truncated or full)
96687ec3a0bSHoria Geantă  * @is_qi: true when called from caam/qi
9678cea7b66SHoria Geantă  */
cnstr_shdsc_rfc4106_decap(u32 * const desc,struct alginfo * cdata,unsigned int ivsize,unsigned int icvsize,const bool is_qi)9688cea7b66SHoria Geantă void cnstr_shdsc_rfc4106_decap(u32 * const desc, struct alginfo *cdata,
96987ec3a0bSHoria Geantă 			       unsigned int ivsize, unsigned int icvsize,
97087ec3a0bSHoria Geantă 			       const bool is_qi)
9718cea7b66SHoria Geantă {
9728cea7b66SHoria Geantă 	u32 *key_jump_cmd;
9738cea7b66SHoria Geantă 
9748cea7b66SHoria Geantă 	init_sh_desc(desc, HDR_SHARE_SERIAL);
9758cea7b66SHoria Geantă 
9768cea7b66SHoria Geantă 	/* Skip key loading if it is loaded due to sharing */
9778cea7b66SHoria Geantă 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
9788cea7b66SHoria Geantă 				   JUMP_COND_SHRD);
9798cea7b66SHoria Geantă 	if (cdata->key_inline)
9809c0bc511SArnd Bergmann 		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
9818cea7b66SHoria Geantă 				  cdata->keylen, CLASS_1 |
9828cea7b66SHoria Geantă 				  KEY_DEST_CLASS_REG);
9838cea7b66SHoria Geantă 	else
9849c0bc511SArnd Bergmann 		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
9858cea7b66SHoria Geantă 			   KEY_DEST_CLASS_REG);
9868cea7b66SHoria Geantă 	set_jump_tgt_here(desc, key_jump_cmd);
9878cea7b66SHoria Geantă 
9888cea7b66SHoria Geantă 	/* Class 1 operation */
9898cea7b66SHoria Geantă 	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
9908cea7b66SHoria Geantă 			 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
9918cea7b66SHoria Geantă 
99287ec3a0bSHoria Geantă 	if (is_qi) {
99387ec3a0bSHoria Geantă 		u32 *wait_load_cmd;
99487ec3a0bSHoria Geantă 
99587ec3a0bSHoria Geantă 		/* REG3 = assoclen */
99687ec3a0bSHoria Geantă 		append_seq_load(desc, 4, LDST_CLASS_DECO |
99787ec3a0bSHoria Geantă 				LDST_SRCDST_WORD_DECO_MATH3 |
99887ec3a0bSHoria Geantă 				(4 << LDST_OFFSET_SHIFT));
99987ec3a0bSHoria Geantă 
100087ec3a0bSHoria Geantă 		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
100187ec3a0bSHoria Geantă 					    JUMP_COND_CALM | JUMP_COND_NCP |
100287ec3a0bSHoria Geantă 					    JUMP_COND_NOP | JUMP_COND_NIP |
100387ec3a0bSHoria Geantă 					    JUMP_COND_NIFP);
100487ec3a0bSHoria Geantă 		set_jump_tgt_here(desc, wait_load_cmd);
100587ec3a0bSHoria Geantă 
100687ec3a0bSHoria Geantă 		/* Read salt and IV */
100787ec3a0bSHoria Geantă 		append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
100887ec3a0bSHoria Geantă 					cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
100987ec3a0bSHoria Geantă 					FIFOLD_TYPE_IV);
101087ec3a0bSHoria Geantă 		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
101187ec3a0bSHoria Geantă 				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
101287ec3a0bSHoria Geantă 	}
101387ec3a0bSHoria Geantă 
101487ec3a0bSHoria Geantă 	append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, ivsize);
10158cea7b66SHoria Geantă 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
10168cea7b66SHoria Geantă 
10178cea7b66SHoria Geantă 	/* Read assoc data */
10188cea7b66SHoria Geantă 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
10198cea7b66SHoria Geantă 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
10208cea7b66SHoria Geantă 
10218cea7b66SHoria Geantă 	/* Skip IV */
102287ec3a0bSHoria Geantă 	append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_SKIP);
10238cea7b66SHoria Geantă 
10248cea7b66SHoria Geantă 	/* Will read cryptlen bytes */
10258cea7b66SHoria Geantă 	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG3, CAAM_CMD_SZ);
10268cea7b66SHoria Geantă 
10278cea7b66SHoria Geantă 	/* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
10288cea7b66SHoria Geantă 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG);
10298cea7b66SHoria Geantă 
10308cea7b66SHoria Geantă 	/* Skip assoc data */
10318cea7b66SHoria Geantă 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
10328cea7b66SHoria Geantă 
10338cea7b66SHoria Geantă 	/* Will write cryptlen bytes */
10348cea7b66SHoria Geantă 	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
10358cea7b66SHoria Geantă 
10368cea7b66SHoria Geantă 	/* Store payload data */
10378cea7b66SHoria Geantă 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
10388cea7b66SHoria Geantă 
10398cea7b66SHoria Geantă 	/* Read encrypted data */
10408cea7b66SHoria Geantă 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
10418cea7b66SHoria Geantă 			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
10428cea7b66SHoria Geantă 
10438cea7b66SHoria Geantă 	/* Read ICV */
10448cea7b66SHoria Geantă 	append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
10458cea7b66SHoria Geantă 			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
10468cea7b66SHoria Geantă 
10476e005503SSascha Hauer 	print_hex_dump_debug("rfc4106 dec shdesc@" __stringify(__LINE__)": ",
10486e005503SSascha Hauer 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
10496e005503SSascha Hauer 			     1);
10508cea7b66SHoria Geantă }
10518cea7b66SHoria Geantă EXPORT_SYMBOL(cnstr_shdsc_rfc4106_decap);
10528cea7b66SHoria Geantă 
10538cea7b66SHoria Geantă /**
10548cea7b66SHoria Geantă  * cnstr_shdsc_rfc4543_encap - IPSec ESP gmac encapsulation shared descriptor
10558cea7b66SHoria Geantă  *                             (non-protocol).
10568cea7b66SHoria Geantă  * @desc: pointer to buffer used for descriptor construction
10578cea7b66SHoria Geantă  * @cdata: pointer to block cipher transform definitions
10588cea7b66SHoria Geantă  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
105987ec3a0bSHoria Geantă  * @ivsize: initialization vector size
10608cea7b66SHoria Geantă  * @icvsize: integrity check value (ICV) size (truncated or full)
106187ec3a0bSHoria Geantă  * @is_qi: true when called from caam/qi
10628cea7b66SHoria Geantă  */
cnstr_shdsc_rfc4543_encap(u32 * const desc,struct alginfo * cdata,unsigned int ivsize,unsigned int icvsize,const bool is_qi)10638cea7b66SHoria Geantă void cnstr_shdsc_rfc4543_encap(u32 * const desc, struct alginfo *cdata,
106487ec3a0bSHoria Geantă 			       unsigned int ivsize, unsigned int icvsize,
106587ec3a0bSHoria Geantă 			       const bool is_qi)
10668cea7b66SHoria Geantă {
10678cea7b66SHoria Geantă 	u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
10688cea7b66SHoria Geantă 
10698cea7b66SHoria Geantă 	init_sh_desc(desc, HDR_SHARE_SERIAL);
10708cea7b66SHoria Geantă 
10718cea7b66SHoria Geantă 	/* Skip key loading if it is loaded due to sharing */
10728cea7b66SHoria Geantă 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
10738cea7b66SHoria Geantă 				   JUMP_COND_SHRD);
10748cea7b66SHoria Geantă 	if (cdata->key_inline)
10759c0bc511SArnd Bergmann 		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
10768cea7b66SHoria Geantă 				  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
10778cea7b66SHoria Geantă 	else
10789c0bc511SArnd Bergmann 		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
10798cea7b66SHoria Geantă 			   KEY_DEST_CLASS_REG);
10808cea7b66SHoria Geantă 	set_jump_tgt_here(desc, key_jump_cmd);
10818cea7b66SHoria Geantă 
10828cea7b66SHoria Geantă 	/* Class 1 operation */
10838cea7b66SHoria Geantă 	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
10848cea7b66SHoria Geantă 			 OP_ALG_ENCRYPT);
10858cea7b66SHoria Geantă 
108687ec3a0bSHoria Geantă 	if (is_qi) {
108787ec3a0bSHoria Geantă 		/* assoclen is not needed, skip it */
108887ec3a0bSHoria Geantă 		append_seq_fifo_load(desc, 4, FIFOLD_CLASS_SKIP);
108987ec3a0bSHoria Geantă 
109087ec3a0bSHoria Geantă 		/* Read salt and IV */
109187ec3a0bSHoria Geantă 		append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
109287ec3a0bSHoria Geantă 					cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
109387ec3a0bSHoria Geantă 					FIFOLD_TYPE_IV);
109487ec3a0bSHoria Geantă 		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
109587ec3a0bSHoria Geantă 				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
109687ec3a0bSHoria Geantă 	}
109787ec3a0bSHoria Geantă 
10988cea7b66SHoria Geantă 	/* assoclen + cryptlen = seqinlen */
10998cea7b66SHoria Geantă 	append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
11008cea7b66SHoria Geantă 
11018cea7b66SHoria Geantă 	/*
11028cea7b66SHoria Geantă 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
11038cea7b66SHoria Geantă 	 * thus need to do some magic, i.e. self-patch the descriptor
11048cea7b66SHoria Geantă 	 * buffer.
11058cea7b66SHoria Geantă 	 */
11068cea7b66SHoria Geantă 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
11078cea7b66SHoria Geantă 				    (0x6 << MOVE_LEN_SHIFT));
11088cea7b66SHoria Geantă 	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
1109b2106476SHoria Geantă 				     (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
11108cea7b66SHoria Geantă 
11118cea7b66SHoria Geantă 	/* Will read assoclen + cryptlen bytes */
11128cea7b66SHoria Geantă 	append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
11138cea7b66SHoria Geantă 
11148cea7b66SHoria Geantă 	/* Will write assoclen + cryptlen bytes */
11158cea7b66SHoria Geantă 	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
11168cea7b66SHoria Geantă 
11178cea7b66SHoria Geantă 	/* Read and write assoclen + cryptlen bytes */
11188cea7b66SHoria Geantă 	aead_append_src_dst(desc, FIFOLD_TYPE_AAD);
11198cea7b66SHoria Geantă 
11208cea7b66SHoria Geantă 	set_move_tgt_here(desc, read_move_cmd);
11218cea7b66SHoria Geantă 	set_move_tgt_here(desc, write_move_cmd);
11228cea7b66SHoria Geantă 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
11238cea7b66SHoria Geantă 	/* Move payload data to OFIFO */
11248cea7b66SHoria Geantă 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
11258cea7b66SHoria Geantă 
11268cea7b66SHoria Geantă 	/* Write ICV */
11278cea7b66SHoria Geantă 	append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
11288cea7b66SHoria Geantă 			 LDST_SRCDST_BYTE_CONTEXT);
11298cea7b66SHoria Geantă 
11306e005503SSascha Hauer 	print_hex_dump_debug("rfc4543 enc shdesc@" __stringify(__LINE__)": ",
11316e005503SSascha Hauer 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
11326e005503SSascha Hauer 			     1);
11338cea7b66SHoria Geantă }
11348cea7b66SHoria Geantă EXPORT_SYMBOL(cnstr_shdsc_rfc4543_encap);
11358cea7b66SHoria Geantă 
11368cea7b66SHoria Geantă /**
11378cea7b66SHoria Geantă  * cnstr_shdsc_rfc4543_decap - IPSec ESP gmac decapsulation shared descriptor
11388cea7b66SHoria Geantă  *                             (non-protocol).
11398cea7b66SHoria Geantă  * @desc: pointer to buffer used for descriptor construction
11408cea7b66SHoria Geantă  * @cdata: pointer to block cipher transform definitions
11418cea7b66SHoria Geantă  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
114287ec3a0bSHoria Geantă  * @ivsize: initialization vector size
11438cea7b66SHoria Geantă  * @icvsize: integrity check value (ICV) size (truncated or full)
114487ec3a0bSHoria Geantă  * @is_qi: true when called from caam/qi
11458cea7b66SHoria Geantă  */
cnstr_shdsc_rfc4543_decap(u32 * const desc,struct alginfo * cdata,unsigned int ivsize,unsigned int icvsize,const bool is_qi)11468cea7b66SHoria Geantă void cnstr_shdsc_rfc4543_decap(u32 * const desc, struct alginfo *cdata,
114787ec3a0bSHoria Geantă 			       unsigned int ivsize, unsigned int icvsize,
114887ec3a0bSHoria Geantă 			       const bool is_qi)
11498cea7b66SHoria Geantă {
11508cea7b66SHoria Geantă 	u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
11518cea7b66SHoria Geantă 
11528cea7b66SHoria Geantă 	init_sh_desc(desc, HDR_SHARE_SERIAL);
11538cea7b66SHoria Geantă 
11548cea7b66SHoria Geantă 	/* Skip key loading if it is loaded due to sharing */
11558cea7b66SHoria Geantă 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
11568cea7b66SHoria Geantă 				   JUMP_COND_SHRD);
11578cea7b66SHoria Geantă 	if (cdata->key_inline)
11589c0bc511SArnd Bergmann 		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
11598cea7b66SHoria Geantă 				  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
11608cea7b66SHoria Geantă 	else
11619c0bc511SArnd Bergmann 		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
11628cea7b66SHoria Geantă 			   KEY_DEST_CLASS_REG);
11638cea7b66SHoria Geantă 	set_jump_tgt_here(desc, key_jump_cmd);
11648cea7b66SHoria Geantă 
11658cea7b66SHoria Geantă 	/* Class 1 operation */
11668cea7b66SHoria Geantă 	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
11678cea7b66SHoria Geantă 			 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
11688cea7b66SHoria Geantă 
116987ec3a0bSHoria Geantă 	if (is_qi) {
117087ec3a0bSHoria Geantă 		/* assoclen is not needed, skip it */
117187ec3a0bSHoria Geantă 		append_seq_fifo_load(desc, 4, FIFOLD_CLASS_SKIP);
117287ec3a0bSHoria Geantă 
117387ec3a0bSHoria Geantă 		/* Read salt and IV */
117487ec3a0bSHoria Geantă 		append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
117587ec3a0bSHoria Geantă 					cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
117687ec3a0bSHoria Geantă 					FIFOLD_TYPE_IV);
117787ec3a0bSHoria Geantă 		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
117887ec3a0bSHoria Geantă 				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
117987ec3a0bSHoria Geantă 	}
118087ec3a0bSHoria Geantă 
11818cea7b66SHoria Geantă 	/* assoclen + cryptlen = seqoutlen */
11828cea7b66SHoria Geantă 	append_math_sub(desc, REG3, SEQOUTLEN, REG0, CAAM_CMD_SZ);
11838cea7b66SHoria Geantă 
11848cea7b66SHoria Geantă 	/*
11858cea7b66SHoria Geantă 	 * MOVE_LEN opcode is not available in all SEC HW revisions,
11868cea7b66SHoria Geantă 	 * thus need to do some magic, i.e. self-patch the descriptor
11878cea7b66SHoria Geantă 	 * buffer.
11888cea7b66SHoria Geantă 	 */
11898cea7b66SHoria Geantă 	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
11908cea7b66SHoria Geantă 				    (0x6 << MOVE_LEN_SHIFT));
11918cea7b66SHoria Geantă 	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
1192b2106476SHoria Geantă 				     (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
11938cea7b66SHoria Geantă 
11948cea7b66SHoria Geantă 	/* Will read assoclen + cryptlen bytes */
11958cea7b66SHoria Geantă 	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
11968cea7b66SHoria Geantă 
11978cea7b66SHoria Geantă 	/* Will write assoclen + cryptlen bytes */
11988cea7b66SHoria Geantă 	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
11998cea7b66SHoria Geantă 
12008cea7b66SHoria Geantă 	/* Store payload data */
12018cea7b66SHoria Geantă 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
12028cea7b66SHoria Geantă 
12038cea7b66SHoria Geantă 	/* In-snoop assoclen + cryptlen data */
12048cea7b66SHoria Geantă 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | FIFOLDST_VLF |
12058cea7b66SHoria Geantă 			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST2FLUSH1);
12068cea7b66SHoria Geantă 
12078cea7b66SHoria Geantă 	set_move_tgt_here(desc, read_move_cmd);
12088cea7b66SHoria Geantă 	set_move_tgt_here(desc, write_move_cmd);
12098cea7b66SHoria Geantă 	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
12108cea7b66SHoria Geantă 	/* Move payload data to OFIFO */
12118cea7b66SHoria Geantă 	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
12128cea7b66SHoria Geantă 	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
12138cea7b66SHoria Geantă 
12148cea7b66SHoria Geantă 	/* Read ICV */
12158cea7b66SHoria Geantă 	append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
12168cea7b66SHoria Geantă 			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
12178cea7b66SHoria Geantă 
12186e005503SSascha Hauer 	print_hex_dump_debug("rfc4543 dec shdesc@" __stringify(__LINE__)": ",
12196e005503SSascha Hauer 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
12206e005503SSascha Hauer 			     1);
12218cea7b66SHoria Geantă }
12228cea7b66SHoria Geantă EXPORT_SYMBOL(cnstr_shdsc_rfc4543_decap);
12238cea7b66SHoria Geantă 
1224d6bbd4eeSHoria Geantă /**
1225d6bbd4eeSHoria Geantă  * cnstr_shdsc_chachapoly - Chacha20 + Poly1305 generic AEAD (rfc7539) and
1226d6bbd4eeSHoria Geantă  *                          IPsec ESP (rfc7634, a.k.a. rfc7539esp) shared
1227d6bbd4eeSHoria Geantă  *                          descriptor (non-protocol).
1228d6bbd4eeSHoria Geantă  * @desc: pointer to buffer used for descriptor construction
1229d6bbd4eeSHoria Geantă  * @cdata: pointer to block cipher transform definitions
1230d6bbd4eeSHoria Geantă  *         Valid algorithm values - OP_ALG_ALGSEL_CHACHA20 ANDed with
1231d6bbd4eeSHoria Geantă  *         OP_ALG_AAI_AEAD.
1232d6bbd4eeSHoria Geantă  * @adata: pointer to authentication transform definitions
1233d6bbd4eeSHoria Geantă  *         Valid algorithm values - OP_ALG_ALGSEL_POLY1305 ANDed with
1234d6bbd4eeSHoria Geantă  *         OP_ALG_AAI_AEAD.
1235d6bbd4eeSHoria Geantă  * @ivsize: initialization vector size
1236d6bbd4eeSHoria Geantă  * @icvsize: integrity check value (ICV) size (truncated or full)
1237d6bbd4eeSHoria Geantă  * @encap: true if encapsulation, false if decapsulation
1238c10a5336SHoria Geantă  * @is_qi: true when called from caam/qi
1239d6bbd4eeSHoria Geantă  */
cnstr_shdsc_chachapoly(u32 * const desc,struct alginfo * cdata,struct alginfo * adata,unsigned int ivsize,unsigned int icvsize,const bool encap,const bool is_qi)1240d6bbd4eeSHoria Geantă void cnstr_shdsc_chachapoly(u32 * const desc, struct alginfo *cdata,
1241d6bbd4eeSHoria Geantă 			    struct alginfo *adata, unsigned int ivsize,
1242c10a5336SHoria Geantă 			    unsigned int icvsize, const bool encap,
1243c10a5336SHoria Geantă 			    const bool is_qi)
1244d6bbd4eeSHoria Geantă {
1245d6bbd4eeSHoria Geantă 	u32 *key_jump_cmd, *wait_cmd;
1246d6bbd4eeSHoria Geantă 	u32 nfifo;
1247d6bbd4eeSHoria Geantă 	const bool is_ipsec = (ivsize != CHACHAPOLY_IV_SIZE);
1248d6bbd4eeSHoria Geantă 
1249d6bbd4eeSHoria Geantă 	/* Note: Context registers are saved. */
1250d6bbd4eeSHoria Geantă 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1251d6bbd4eeSHoria Geantă 
1252d6bbd4eeSHoria Geantă 	/* skip key loading if they are loaded due to sharing */
1253d6bbd4eeSHoria Geantă 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1254d6bbd4eeSHoria Geantă 				   JUMP_COND_SHRD);
1255d6bbd4eeSHoria Geantă 
1256d6bbd4eeSHoria Geantă 	append_key_as_imm(desc, cdata->key_virt, cdata->keylen, cdata->keylen,
1257d6bbd4eeSHoria Geantă 			  CLASS_1 | KEY_DEST_CLASS_REG);
1258d6bbd4eeSHoria Geantă 
1259d6bbd4eeSHoria Geantă 	/* For IPsec load the salt from keymat in the context register */
1260d6bbd4eeSHoria Geantă 	if (is_ipsec)
1261d6bbd4eeSHoria Geantă 		append_load_as_imm(desc, cdata->key_virt + cdata->keylen, 4,
1262d6bbd4eeSHoria Geantă 				   LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT |
1263d6bbd4eeSHoria Geantă 				   4 << LDST_OFFSET_SHIFT);
1264d6bbd4eeSHoria Geantă 
1265d6bbd4eeSHoria Geantă 	set_jump_tgt_here(desc, key_jump_cmd);
1266d6bbd4eeSHoria Geantă 
1267d6bbd4eeSHoria Geantă 	/* Class 2 and 1 operations: Poly & ChaCha */
1268d6bbd4eeSHoria Geantă 	if (encap) {
1269d6bbd4eeSHoria Geantă 		append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
1270d6bbd4eeSHoria Geantă 				 OP_ALG_ENCRYPT);
1271d6bbd4eeSHoria Geantă 		append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1272d6bbd4eeSHoria Geantă 				 OP_ALG_ENCRYPT);
1273d6bbd4eeSHoria Geantă 	} else {
1274d6bbd4eeSHoria Geantă 		append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
1275d6bbd4eeSHoria Geantă 				 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
1276d6bbd4eeSHoria Geantă 		append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1277d6bbd4eeSHoria Geantă 				 OP_ALG_DECRYPT);
1278d6bbd4eeSHoria Geantă 	}
1279d6bbd4eeSHoria Geantă 
1280c10a5336SHoria Geantă 	if (is_qi) {
1281c10a5336SHoria Geantă 		u32 *wait_load_cmd;
1282c10a5336SHoria Geantă 		u32 ctx1_iv_off = is_ipsec ? 8 : 4;
1283c10a5336SHoria Geantă 
1284c10a5336SHoria Geantă 		/* REG3 = assoclen */
1285c10a5336SHoria Geantă 		append_seq_load(desc, 4, LDST_CLASS_DECO |
1286c10a5336SHoria Geantă 				LDST_SRCDST_WORD_DECO_MATH3 |
1287c10a5336SHoria Geantă 				4 << LDST_OFFSET_SHIFT);
1288c10a5336SHoria Geantă 
1289c10a5336SHoria Geantă 		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1290c10a5336SHoria Geantă 					    JUMP_COND_CALM | JUMP_COND_NCP |
1291c10a5336SHoria Geantă 					    JUMP_COND_NOP | JUMP_COND_NIP |
1292c10a5336SHoria Geantă 					    JUMP_COND_NIFP);
1293c10a5336SHoria Geantă 		set_jump_tgt_here(desc, wait_load_cmd);
1294c10a5336SHoria Geantă 
1295c10a5336SHoria Geantă 		append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
1296c10a5336SHoria Geantă 				LDST_SRCDST_BYTE_CONTEXT |
1297c10a5336SHoria Geantă 				ctx1_iv_off << LDST_OFFSET_SHIFT);
1298c10a5336SHoria Geantă 	}
1299c10a5336SHoria Geantă 
1300d6bbd4eeSHoria Geantă 	/*
1301d6bbd4eeSHoria Geantă 	 * MAGIC with NFIFO
1302d6bbd4eeSHoria Geantă 	 * Read associated data from the input and send them to class1 and
1303d6bbd4eeSHoria Geantă 	 * class2 alignment blocks. From class1 send data to output fifo and
1304d6bbd4eeSHoria Geantă 	 * then write it to memory since we don't need to encrypt AD.
1305d6bbd4eeSHoria Geantă 	 */
1306d6bbd4eeSHoria Geantă 	nfifo = NFIFOENTRY_DEST_BOTH | NFIFOENTRY_FC1 | NFIFOENTRY_FC2 |
1307d6bbd4eeSHoria Geantă 		NFIFOENTRY_DTYPE_POLY | NFIFOENTRY_BND;
1308d6bbd4eeSHoria Geantă 	append_load_imm_u32(desc, nfifo, LDST_CLASS_IND_CCB |
1309d6bbd4eeSHoria Geantă 			    LDST_SRCDST_WORD_INFO_FIFO_SM | LDLEN_MATH3);
1310d6bbd4eeSHoria Geantă 
1311d6bbd4eeSHoria Geantă 	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
1312d6bbd4eeSHoria Geantă 	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
1313d6bbd4eeSHoria Geantă 	append_seq_fifo_load(desc, 0, FIFOLD_TYPE_NOINFOFIFO |
1314d6bbd4eeSHoria Geantă 			     FIFOLD_CLASS_CLASS1 | LDST_VLF);
1315d6bbd4eeSHoria Geantă 	append_move_len(desc, MOVE_AUX_LS | MOVE_SRC_AUX_ABLK |
1316d6bbd4eeSHoria Geantă 			MOVE_DEST_OUTFIFO | MOVELEN_MRSEL_MATH3);
1317d6bbd4eeSHoria Geantă 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | LDST_VLF);
1318d6bbd4eeSHoria Geantă 
1319d6bbd4eeSHoria Geantă 	/* IPsec - copy IV at the output */
1320d6bbd4eeSHoria Geantă 	if (is_ipsec)
1321d6bbd4eeSHoria Geantă 		append_seq_fifo_store(desc, ivsize, FIFOST_TYPE_METADATA |
1322d6bbd4eeSHoria Geantă 				      0x2 << 25);
1323d6bbd4eeSHoria Geantă 
1324d6bbd4eeSHoria Geantă 	wait_cmd = append_jump(desc, JUMP_JSL | JUMP_TYPE_LOCAL |
1325d6bbd4eeSHoria Geantă 			       JUMP_COND_NOP | JUMP_TEST_ALL);
1326d6bbd4eeSHoria Geantă 	set_jump_tgt_here(desc, wait_cmd);
1327d6bbd4eeSHoria Geantă 
1328d6bbd4eeSHoria Geantă 	if (encap) {
1329d6bbd4eeSHoria Geantă 		/* Read and write cryptlen bytes */
1330d6bbd4eeSHoria Geantă 		append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1331d6bbd4eeSHoria Geantă 		append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0,
1332d6bbd4eeSHoria Geantă 				CAAM_CMD_SZ);
1333d6bbd4eeSHoria Geantă 		aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
1334d6bbd4eeSHoria Geantă 
1335d6bbd4eeSHoria Geantă 		/* Write ICV */
1336d6bbd4eeSHoria Geantă 		append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
1337d6bbd4eeSHoria Geantă 				 LDST_SRCDST_BYTE_CONTEXT);
1338d6bbd4eeSHoria Geantă 	} else {
1339d6bbd4eeSHoria Geantă 		/* Read and write cryptlen bytes */
1340d6bbd4eeSHoria Geantă 		append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0,
1341d6bbd4eeSHoria Geantă 				CAAM_CMD_SZ);
1342d6bbd4eeSHoria Geantă 		append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0,
1343d6bbd4eeSHoria Geantă 				CAAM_CMD_SZ);
1344d6bbd4eeSHoria Geantă 		aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
1345d6bbd4eeSHoria Geantă 
1346d6bbd4eeSHoria Geantă 		/* Load ICV for verification */
1347d6bbd4eeSHoria Geantă 		append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
1348d6bbd4eeSHoria Geantă 				     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
1349d6bbd4eeSHoria Geantă 	}
1350d6bbd4eeSHoria Geantă 
1351d6bbd4eeSHoria Geantă 	print_hex_dump_debug("chachapoly shdesc@" __stringify(__LINE__)": ",
1352d6bbd4eeSHoria Geantă 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1353d6bbd4eeSHoria Geantă 			     1);
1354d6bbd4eeSHoria Geantă }
1355d6bbd4eeSHoria Geantă EXPORT_SYMBOL(cnstr_shdsc_chachapoly);
1356d6bbd4eeSHoria Geantă 
13579dbe3072SHoria Geantă /* For skcipher encrypt and decrypt, read from req->src and write to req->dst */
skcipher_append_src_dst(u32 * desc)13589dbe3072SHoria Geantă static inline void skcipher_append_src_dst(u32 *desc)
13598cea7b66SHoria Geantă {
13608cea7b66SHoria Geantă 	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
13618cea7b66SHoria Geantă 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
13628cea7b66SHoria Geantă 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 |
13638cea7b66SHoria Geantă 			     KEY_VLF | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
13648cea7b66SHoria Geantă 	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
13658cea7b66SHoria Geantă }
13668cea7b66SHoria Geantă 
13678cea7b66SHoria Geantă /**
13689dbe3072SHoria Geantă  * cnstr_shdsc_skcipher_encap - skcipher encapsulation shared descriptor
13698cea7b66SHoria Geantă  * @desc: pointer to buffer used for descriptor construction
13708cea7b66SHoria Geantă  * @cdata: pointer to block cipher transform definitions
13718cea7b66SHoria Geantă  *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
1372c99d4a24SHoria Geantă  *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128
1373c99d4a24SHoria Geantă  *                                - OP_ALG_ALGSEL_CHACHA20
13748cea7b66SHoria Geantă  * @ivsize: initialization vector size
13758cea7b66SHoria Geantă  * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
13768cea7b66SHoria Geantă  * @ctx1_iv_off: IV offset in CONTEXT1 register
13778cea7b66SHoria Geantă  */
cnstr_shdsc_skcipher_encap(u32 * const desc,struct alginfo * cdata,unsigned int ivsize,const bool is_rfc3686,const u32 ctx1_iv_off)13789dbe3072SHoria Geantă void cnstr_shdsc_skcipher_encap(u32 * const desc, struct alginfo *cdata,
13798cea7b66SHoria Geantă 				unsigned int ivsize, const bool is_rfc3686,
13808cea7b66SHoria Geantă 				const u32 ctx1_iv_off)
13818cea7b66SHoria Geantă {
13828cea7b66SHoria Geantă 	u32 *key_jump_cmd;
13833a5a9e1eSHoria Geantă 	u32 options = cdata->algtype | OP_ALG_AS_INIT | OP_ALG_ENCRYPT;
13843a5a9e1eSHoria Geantă 	bool is_chacha20 = ((cdata->algtype & OP_ALG_ALGSEL_MASK) ==
13853a5a9e1eSHoria Geantă 			    OP_ALG_ALGSEL_CHACHA20);
13868cea7b66SHoria Geantă 
13878cea7b66SHoria Geantă 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
13888cea7b66SHoria Geantă 	/* Skip if already shared */
13898cea7b66SHoria Geantă 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
13908cea7b66SHoria Geantă 				   JUMP_COND_SHRD);
13918cea7b66SHoria Geantă 
13928cea7b66SHoria Geantă 	/* Load class1 key only */
13939c0bc511SArnd Bergmann 	append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
13948cea7b66SHoria Geantă 			  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
13958cea7b66SHoria Geantă 
13968cea7b66SHoria Geantă 	/* Load nonce into CONTEXT1 reg */
13978cea7b66SHoria Geantă 	if (is_rfc3686) {
13986674a4fdSHoria Geantă 		const u8 *nonce = cdata->key_virt + cdata->keylen;
13998cea7b66SHoria Geantă 
14008cea7b66SHoria Geantă 		append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
14018cea7b66SHoria Geantă 				   LDST_CLASS_IND_CCB |
14028cea7b66SHoria Geantă 				   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
14038cea7b66SHoria Geantă 		append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
14048cea7b66SHoria Geantă 			    MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
14058cea7b66SHoria Geantă 			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
14068cea7b66SHoria Geantă 	}
14078cea7b66SHoria Geantă 
14088cea7b66SHoria Geantă 	set_jump_tgt_here(desc, key_jump_cmd);
14098cea7b66SHoria Geantă 
1410eaed71a4SIuliana Prodan 	/* Load IV, if there is one */
1411eaed71a4SIuliana Prodan 	if (ivsize)
14128cea7b66SHoria Geantă 		append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1413eaed71a4SIuliana Prodan 				LDST_CLASS_1_CCB | (ctx1_iv_off <<
1414eaed71a4SIuliana Prodan 				LDST_OFFSET_SHIFT));
14158cea7b66SHoria Geantă 
14168cea7b66SHoria Geantă 	/* Load counter into CONTEXT1 reg */
14178cea7b66SHoria Geantă 	if (is_rfc3686)
14188cea7b66SHoria Geantă 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
14198cea7b66SHoria Geantă 				     LDST_SRCDST_BYTE_CONTEXT |
14208cea7b66SHoria Geantă 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
14218cea7b66SHoria Geantă 				      LDST_OFFSET_SHIFT));
14228cea7b66SHoria Geantă 
14238cea7b66SHoria Geantă 	/* Load operation */
14243a5a9e1eSHoria Geantă 	if (is_chacha20)
14253a5a9e1eSHoria Geantă 		options |= OP_ALG_AS_FINALIZE;
14263a5a9e1eSHoria Geantă 	append_operation(desc, options);
14278cea7b66SHoria Geantă 
14288cea7b66SHoria Geantă 	/* Perform operation */
14299dbe3072SHoria Geantă 	skcipher_append_src_dst(desc);
14308cea7b66SHoria Geantă 
1431334d37c9SHoria Geantă 	/* Store IV */
14323a5a9e1eSHoria Geantă 	if (!is_chacha20 && ivsize)
1433334d37c9SHoria Geantă 		append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1434334d37c9SHoria Geantă 				 LDST_CLASS_1_CCB | (ctx1_iv_off <<
1435334d37c9SHoria Geantă 				 LDST_OFFSET_SHIFT));
1436334d37c9SHoria Geantă 
14376e005503SSascha Hauer 	print_hex_dump_debug("skcipher enc shdesc@" __stringify(__LINE__)": ",
14386e005503SSascha Hauer 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
14396e005503SSascha Hauer 			     1);
14408cea7b66SHoria Geantă }
14419dbe3072SHoria Geantă EXPORT_SYMBOL(cnstr_shdsc_skcipher_encap);
14428cea7b66SHoria Geantă 
14438cea7b66SHoria Geantă /**
14449dbe3072SHoria Geantă  * cnstr_shdsc_skcipher_decap - skcipher decapsulation shared descriptor
14458cea7b66SHoria Geantă  * @desc: pointer to buffer used for descriptor construction
14468cea7b66SHoria Geantă  * @cdata: pointer to block cipher transform definitions
14478cea7b66SHoria Geantă  *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
1448c99d4a24SHoria Geantă  *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128
1449c99d4a24SHoria Geantă  *                                - OP_ALG_ALGSEL_CHACHA20
14508cea7b66SHoria Geantă  * @ivsize: initialization vector size
14518cea7b66SHoria Geantă  * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
14528cea7b66SHoria Geantă  * @ctx1_iv_off: IV offset in CONTEXT1 register
14538cea7b66SHoria Geantă  */
cnstr_shdsc_skcipher_decap(u32 * const desc,struct alginfo * cdata,unsigned int ivsize,const bool is_rfc3686,const u32 ctx1_iv_off)14549dbe3072SHoria Geantă void cnstr_shdsc_skcipher_decap(u32 * const desc, struct alginfo *cdata,
14558cea7b66SHoria Geantă 				unsigned int ivsize, const bool is_rfc3686,
14568cea7b66SHoria Geantă 				const u32 ctx1_iv_off)
14578cea7b66SHoria Geantă {
14588cea7b66SHoria Geantă 	u32 *key_jump_cmd;
14593a5a9e1eSHoria Geantă 	bool is_chacha20 = ((cdata->algtype & OP_ALG_ALGSEL_MASK) ==
14603a5a9e1eSHoria Geantă 			    OP_ALG_ALGSEL_CHACHA20);
14618cea7b66SHoria Geantă 
14628cea7b66SHoria Geantă 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
14638cea7b66SHoria Geantă 	/* Skip if already shared */
14648cea7b66SHoria Geantă 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
14658cea7b66SHoria Geantă 				   JUMP_COND_SHRD);
14668cea7b66SHoria Geantă 
14678cea7b66SHoria Geantă 	/* Load class1 key only */
14689c0bc511SArnd Bergmann 	append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
14698cea7b66SHoria Geantă 			  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
14708cea7b66SHoria Geantă 
14718cea7b66SHoria Geantă 	/* Load nonce into CONTEXT1 reg */
14728cea7b66SHoria Geantă 	if (is_rfc3686) {
14736674a4fdSHoria Geantă 		const u8 *nonce = cdata->key_virt + cdata->keylen;
14748cea7b66SHoria Geantă 
14758cea7b66SHoria Geantă 		append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
14768cea7b66SHoria Geantă 				   LDST_CLASS_IND_CCB |
14778cea7b66SHoria Geantă 				   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
14788cea7b66SHoria Geantă 		append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
14798cea7b66SHoria Geantă 			    MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
14808cea7b66SHoria Geantă 			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
14818cea7b66SHoria Geantă 	}
14828cea7b66SHoria Geantă 
14838cea7b66SHoria Geantă 	set_jump_tgt_here(desc, key_jump_cmd);
14848cea7b66SHoria Geantă 
1485eaed71a4SIuliana Prodan 	/* Load IV, if there is one */
1486eaed71a4SIuliana Prodan 	if (ivsize)
14878cea7b66SHoria Geantă 		append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1488eaed71a4SIuliana Prodan 				LDST_CLASS_1_CCB | (ctx1_iv_off <<
1489eaed71a4SIuliana Prodan 				LDST_OFFSET_SHIFT));
14908cea7b66SHoria Geantă 
14918cea7b66SHoria Geantă 	/* Load counter into CONTEXT1 reg */
14928cea7b66SHoria Geantă 	if (is_rfc3686)
14938cea7b66SHoria Geantă 		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
14948cea7b66SHoria Geantă 				     LDST_SRCDST_BYTE_CONTEXT |
14958cea7b66SHoria Geantă 				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
14968cea7b66SHoria Geantă 				      LDST_OFFSET_SHIFT));
14978cea7b66SHoria Geantă 
14988cea7b66SHoria Geantă 	/* Choose operation */
14998cea7b66SHoria Geantă 	if (ctx1_iv_off)
1500334d37c9SHoria Geantă 		append_operation(desc, cdata->algtype | OP_ALG_AS_INIT |
15018cea7b66SHoria Geantă 				 OP_ALG_DECRYPT);
15028cea7b66SHoria Geantă 	else
15038cea7b66SHoria Geantă 		append_dec_op1(desc, cdata->algtype);
15048cea7b66SHoria Geantă 
15058cea7b66SHoria Geantă 	/* Perform operation */
15069dbe3072SHoria Geantă 	skcipher_append_src_dst(desc);
15078cea7b66SHoria Geantă 
1508334d37c9SHoria Geantă 	/* Store IV */
15093a5a9e1eSHoria Geantă 	if (!is_chacha20 && ivsize)
1510334d37c9SHoria Geantă 		append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1511334d37c9SHoria Geantă 				 LDST_CLASS_1_CCB | (ctx1_iv_off <<
1512334d37c9SHoria Geantă 				 LDST_OFFSET_SHIFT));
1513334d37c9SHoria Geantă 
15146e005503SSascha Hauer 	print_hex_dump_debug("skcipher dec shdesc@" __stringify(__LINE__)": ",
15156e005503SSascha Hauer 			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
15166e005503SSascha Hauer 			     1);
15178cea7b66SHoria Geantă }
15189dbe3072SHoria Geantă EXPORT_SYMBOL(cnstr_shdsc_skcipher_decap);
15198cea7b66SHoria Geantă 
15208cea7b66SHoria Geantă /**
15219dbe3072SHoria Geantă  * cnstr_shdsc_xts_skcipher_encap - xts skcipher encapsulation shared descriptor
15228cea7b66SHoria Geantă  * @desc: pointer to buffer used for descriptor construction
15238cea7b66SHoria Geantă  * @cdata: pointer to block cipher transform definitions
15248cea7b66SHoria Geantă  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_XTS.
15258cea7b66SHoria Geantă  */
cnstr_shdsc_xts_skcipher_encap(u32 * const desc,struct alginfo * cdata)15269dbe3072SHoria Geantă void cnstr_shdsc_xts_skcipher_encap(u32 * const desc, struct alginfo *cdata)
15278cea7b66SHoria Geantă {
15283f142b6aSAndrei Botila 	/*
15293f142b6aSAndrei Botila 	 * Set sector size to a big value, practically disabling
15303f142b6aSAndrei Botila 	 * sector size segmentation in xts implementation. We cannot
15313f142b6aSAndrei Botila 	 * take full advantage of this HW feature with existing
15323f142b6aSAndrei Botila 	 * crypto API / dm-crypt SW architecture.
15333f142b6aSAndrei Botila 	 */
15343f142b6aSAndrei Botila 	__be64 sector_size = cpu_to_be64(BIT(15));
15358cea7b66SHoria Geantă 	u32 *key_jump_cmd;
15368cea7b66SHoria Geantă 
15378cea7b66SHoria Geantă 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
15388cea7b66SHoria Geantă 	/* Skip if already shared */
15398cea7b66SHoria Geantă 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
15408cea7b66SHoria Geantă 				   JUMP_COND_SHRD);
15418cea7b66SHoria Geantă 
15428cea7b66SHoria Geantă 	/* Load class1 keys only */
15439c0bc511SArnd Bergmann 	append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
15448cea7b66SHoria Geantă 			  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
15458cea7b66SHoria Geantă 
15468cea7b66SHoria Geantă 	/* Load sector size with index 40 bytes (0x28) */
15478cea7b66SHoria Geantă 	append_load_as_imm(desc, (void *)&sector_size, 8, LDST_CLASS_1_CCB |
15488cea7b66SHoria Geantă 			   LDST_SRCDST_BYTE_CONTEXT |
15498cea7b66SHoria Geantă 			   (0x28 << LDST_OFFSET_SHIFT));
15508cea7b66SHoria Geantă 
15518cea7b66SHoria Geantă 	set_jump_tgt_here(desc, key_jump_cmd);
15528cea7b66SHoria Geantă 
15538cea7b66SHoria Geantă 	/*
1554*78eebbfaSAndrei Botila 	 * create sequence for loading the sector index / 16B tweak value
1555*78eebbfaSAndrei Botila 	 * Lower 8B of IV - sector index / tweak lower half
1556*78eebbfaSAndrei Botila 	 * Upper 8B of IV - upper half of 16B tweak
15578cea7b66SHoria Geantă 	 */
15588cea7b66SHoria Geantă 	append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
15598cea7b66SHoria Geantă 			(0x20 << LDST_OFFSET_SHIFT));
1560*78eebbfaSAndrei Botila 	append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1561*78eebbfaSAndrei Botila 			(0x30 << LDST_OFFSET_SHIFT));
15628cea7b66SHoria Geantă 
15638cea7b66SHoria Geantă 	/* Load operation */
15648cea7b66SHoria Geantă 	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
15658cea7b66SHoria Geantă 			 OP_ALG_ENCRYPT);
15668cea7b66SHoria Geantă 
15678cea7b66SHoria Geantă 	/* Perform operation */
15689dbe3072SHoria Geantă 	skcipher_append_src_dst(desc);
15698cea7b66SHoria Geantă 
1570*78eebbfaSAndrei Botila 	/* Store lower 8B and upper 8B of IV */
1571334d37c9SHoria Geantă 	append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1572334d37c9SHoria Geantă 			 (0x20 << LDST_OFFSET_SHIFT));
1573*78eebbfaSAndrei Botila 	append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1574*78eebbfaSAndrei Botila 			 (0x30 << LDST_OFFSET_SHIFT));
1575334d37c9SHoria Geantă 
15766e005503SSascha Hauer 	print_hex_dump_debug("xts skcipher enc shdesc@" __stringify(__LINE__)
15776e005503SSascha Hauer 			     ": ", DUMP_PREFIX_ADDRESS, 16, 4,
15786e005503SSascha Hauer 			     desc, desc_bytes(desc), 1);
15798cea7b66SHoria Geantă }
15809dbe3072SHoria Geantă EXPORT_SYMBOL(cnstr_shdsc_xts_skcipher_encap);
15818cea7b66SHoria Geantă 
15828cea7b66SHoria Geantă /**
15839dbe3072SHoria Geantă  * cnstr_shdsc_xts_skcipher_decap - xts skcipher decapsulation shared descriptor
15848cea7b66SHoria Geantă  * @desc: pointer to buffer used for descriptor construction
15858cea7b66SHoria Geantă  * @cdata: pointer to block cipher transform definitions
15868cea7b66SHoria Geantă  *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_XTS.
15878cea7b66SHoria Geantă  */
cnstr_shdsc_xts_skcipher_decap(u32 * const desc,struct alginfo * cdata)15889dbe3072SHoria Geantă void cnstr_shdsc_xts_skcipher_decap(u32 * const desc, struct alginfo *cdata)
15898cea7b66SHoria Geantă {
15903f142b6aSAndrei Botila 	/*
15913f142b6aSAndrei Botila 	 * Set sector size to a big value, practically disabling
15923f142b6aSAndrei Botila 	 * sector size segmentation in xts implementation. We cannot
15933f142b6aSAndrei Botila 	 * take full advantage of this HW feature with existing
15943f142b6aSAndrei Botila 	 * crypto API / dm-crypt SW architecture.
15953f142b6aSAndrei Botila 	 */
15963f142b6aSAndrei Botila 	__be64 sector_size = cpu_to_be64(BIT(15));
15978cea7b66SHoria Geantă 	u32 *key_jump_cmd;
15988cea7b66SHoria Geantă 
15998cea7b66SHoria Geantă 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
16008cea7b66SHoria Geantă 	/* Skip if already shared */
16018cea7b66SHoria Geantă 	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
16028cea7b66SHoria Geantă 				   JUMP_COND_SHRD);
16038cea7b66SHoria Geantă 
16048cea7b66SHoria Geantă 	/* Load class1 key only */
16059c0bc511SArnd Bergmann 	append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
16068cea7b66SHoria Geantă 			  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
16078cea7b66SHoria Geantă 
16088cea7b66SHoria Geantă 	/* Load sector size with index 40 bytes (0x28) */
16098cea7b66SHoria Geantă 	append_load_as_imm(desc, (void *)&sector_size, 8, LDST_CLASS_1_CCB |
16108cea7b66SHoria Geantă 			   LDST_SRCDST_BYTE_CONTEXT |
16118cea7b66SHoria Geantă 			   (0x28 << LDST_OFFSET_SHIFT));
16128cea7b66SHoria Geantă 
16138cea7b66SHoria Geantă 	set_jump_tgt_here(desc, key_jump_cmd);
16148cea7b66SHoria Geantă 
16158cea7b66SHoria Geantă 	/*
1616*78eebbfaSAndrei Botila 	 * create sequence for loading the sector index / 16B tweak value
1617*78eebbfaSAndrei Botila 	 * Lower 8B of IV - sector index / tweak lower half
1618*78eebbfaSAndrei Botila 	 * Upper 8B of IV - upper half of 16B tweak
16198cea7b66SHoria Geantă 	 */
16208cea7b66SHoria Geantă 	append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
16218cea7b66SHoria Geantă 			(0x20 << LDST_OFFSET_SHIFT));
1622*78eebbfaSAndrei Botila 	append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1623*78eebbfaSAndrei Botila 			(0x30 << LDST_OFFSET_SHIFT));
16248cea7b66SHoria Geantă 	/* Load operation */
16258cea7b66SHoria Geantă 	append_dec_op1(desc, cdata->algtype);
16268cea7b66SHoria Geantă 
16278cea7b66SHoria Geantă 	/* Perform operation */
16289dbe3072SHoria Geantă 	skcipher_append_src_dst(desc);
16298cea7b66SHoria Geantă 
1630*78eebbfaSAndrei Botila 	/* Store lower 8B and upper 8B of IV */
1631334d37c9SHoria Geantă 	append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1632334d37c9SHoria Geantă 			 (0x20 << LDST_OFFSET_SHIFT));
1633*78eebbfaSAndrei Botila 	append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1634*78eebbfaSAndrei Botila 			 (0x30 << LDST_OFFSET_SHIFT));
1635334d37c9SHoria Geantă 
16366e005503SSascha Hauer 	print_hex_dump_debug("xts skcipher dec shdesc@" __stringify(__LINE__)
16376e005503SSascha Hauer 			     ": ", DUMP_PREFIX_ADDRESS, 16, 4, desc,
16386e005503SSascha Hauer 			     desc_bytes(desc), 1);
16398cea7b66SHoria Geantă }
16409dbe3072SHoria Geantă EXPORT_SYMBOL(cnstr_shdsc_xts_skcipher_decap);
164137d84681SArnd Bergmann 
164237d84681SArnd Bergmann MODULE_LICENSE("GPL");
164337d84681SArnd Bergmann MODULE_DESCRIPTION("FSL CAAM descriptor support");
164437d84681SArnd Bergmann MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
1645