162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Shared descriptors for aead, skcipher algorithms
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright 2016-2019 NXP
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include "compat.h"
962306a36Sopenharmony_ci#include "desc_constr.h"
1062306a36Sopenharmony_ci#include "caamalg_desc.h"
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci/*
1362306a36Sopenharmony_ci * For aead functions, read payload and write payload,
1462306a36Sopenharmony_ci * both of which are specified in req->src and req->dst
1562306a36Sopenharmony_ci */
1662306a36Sopenharmony_cistatic inline void aead_append_src_dst(u32 *desc, u32 msg_type)
1762306a36Sopenharmony_ci{
1862306a36Sopenharmony_ci	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
1962306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH |
2062306a36Sopenharmony_ci			     KEY_VLF | msg_type | FIFOLD_TYPE_LASTBOTH);
2162306a36Sopenharmony_ci}
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci/* Set DK bit in class 1 operation if shared */
2462306a36Sopenharmony_cistatic inline void append_dec_op1(u32 *desc, u32 type)
2562306a36Sopenharmony_ci{
2662306a36Sopenharmony_ci	u32 *jump_cmd, *uncond_jump_cmd;
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci	/* DK bit is valid only for AES */
2962306a36Sopenharmony_ci	if ((type & OP_ALG_ALGSEL_MASK) != OP_ALG_ALGSEL_AES) {
3062306a36Sopenharmony_ci		append_operation(desc, type | OP_ALG_AS_INITFINAL |
3162306a36Sopenharmony_ci				 OP_ALG_DECRYPT);
3262306a36Sopenharmony_ci		return;
3362306a36Sopenharmony_ci	}
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci	jump_cmd = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
3662306a36Sopenharmony_ci	append_operation(desc, type | OP_ALG_AS_INIT | OP_ALG_DECRYPT);
3762306a36Sopenharmony_ci	uncond_jump_cmd = append_jump(desc, JUMP_TEST_ALL);
3862306a36Sopenharmony_ci	set_jump_tgt_here(desc, jump_cmd);
3962306a36Sopenharmony_ci	append_operation(desc, type | OP_ALG_AS_INIT | OP_ALG_DECRYPT |
4062306a36Sopenharmony_ci			 OP_ALG_AAI_DK);
4162306a36Sopenharmony_ci	set_jump_tgt_here(desc, uncond_jump_cmd);
4262306a36Sopenharmony_ci}
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci/**
4562306a36Sopenharmony_ci * cnstr_shdsc_aead_null_encap - IPSec ESP encapsulation shared descriptor
4662306a36Sopenharmony_ci *                               (non-protocol) with no (null) encryption.
4762306a36Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction
4862306a36Sopenharmony_ci * @adata: pointer to authentication transform definitions.
4962306a36Sopenharmony_ci *         A split key is required for SEC Era < 6; the size of the split key
5062306a36Sopenharmony_ci *         is specified in this case. Valid algorithm values - one of
5162306a36Sopenharmony_ci *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
5262306a36Sopenharmony_ci *         with OP_ALG_AAI_HMAC_PRECOMP.
5362306a36Sopenharmony_ci * @icvsize: integrity check value (ICV) size (truncated or full)
5462306a36Sopenharmony_ci * @era: SEC Era
5562306a36Sopenharmony_ci */
5662306a36Sopenharmony_civoid cnstr_shdsc_aead_null_encap(u32 * const desc, struct alginfo *adata,
5762306a36Sopenharmony_ci				 unsigned int icvsize, int era)
5862306a36Sopenharmony_ci{
5962306a36Sopenharmony_ci	u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	init_sh_desc(desc, HDR_SHARE_SERIAL);
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci	/* Skip if already shared */
6462306a36Sopenharmony_ci	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
6562306a36Sopenharmony_ci				   JUMP_COND_SHRD);
6662306a36Sopenharmony_ci	if (era < 6) {
6762306a36Sopenharmony_ci		if (adata->key_inline)
6862306a36Sopenharmony_ci			append_key_as_imm(desc, adata->key_virt,
6962306a36Sopenharmony_ci					  adata->keylen_pad, adata->keylen,
7062306a36Sopenharmony_ci					  CLASS_2 | KEY_DEST_MDHA_SPLIT |
7162306a36Sopenharmony_ci					  KEY_ENC);
7262306a36Sopenharmony_ci		else
7362306a36Sopenharmony_ci			append_key(desc, adata->key_dma, adata->keylen,
7462306a36Sopenharmony_ci				   CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
7562306a36Sopenharmony_ci	} else {
7662306a36Sopenharmony_ci		append_proto_dkp(desc, adata);
7762306a36Sopenharmony_ci	}
7862306a36Sopenharmony_ci	set_jump_tgt_here(desc, key_jump_cmd);
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci	/* assoclen + cryptlen = seqinlen */
8162306a36Sopenharmony_ci	append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci	/* Prepare to read and write cryptlen + assoclen bytes */
8462306a36Sopenharmony_ci	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
8562306a36Sopenharmony_ci	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	/*
8862306a36Sopenharmony_ci	 * MOVE_LEN opcode is not available in all SEC HW revisions,
8962306a36Sopenharmony_ci	 * thus need to do some magic, i.e. self-patch the descriptor
9062306a36Sopenharmony_ci	 * buffer.
9162306a36Sopenharmony_ci	 */
9262306a36Sopenharmony_ci	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
9362306a36Sopenharmony_ci				    MOVE_DEST_MATH3 |
9462306a36Sopenharmony_ci				    (0x6 << MOVE_LEN_SHIFT));
9562306a36Sopenharmony_ci	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 |
9662306a36Sopenharmony_ci				     MOVE_DEST_DESCBUF |
9762306a36Sopenharmony_ci				     MOVE_WAITCOMP |
9862306a36Sopenharmony_ci				     (0x8 << MOVE_LEN_SHIFT));
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	/* Class 2 operation */
10162306a36Sopenharmony_ci	append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
10262306a36Sopenharmony_ci			 OP_ALG_ENCRYPT);
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci	/* Read and write cryptlen bytes */
10562306a36Sopenharmony_ci	aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	set_move_tgt_here(desc, read_move_cmd);
10862306a36Sopenharmony_ci	set_move_tgt_here(desc, write_move_cmd);
10962306a36Sopenharmony_ci	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
11062306a36Sopenharmony_ci	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
11162306a36Sopenharmony_ci		    MOVE_AUX_LS);
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci	/* Write ICV */
11462306a36Sopenharmony_ci	append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
11562306a36Sopenharmony_ci			 LDST_SRCDST_BYTE_CONTEXT);
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci	print_hex_dump_debug("aead null enc shdesc@" __stringify(__LINE__)": ",
11862306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
11962306a36Sopenharmony_ci			     1);
12062306a36Sopenharmony_ci}
12162306a36Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_aead_null_encap);
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci/**
12462306a36Sopenharmony_ci * cnstr_shdsc_aead_null_decap - IPSec ESP decapsulation shared descriptor
12562306a36Sopenharmony_ci *                               (non-protocol) with no (null) decryption.
12662306a36Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction
12762306a36Sopenharmony_ci * @adata: pointer to authentication transform definitions.
12862306a36Sopenharmony_ci *         A split key is required for SEC Era < 6; the size of the split key
12962306a36Sopenharmony_ci *         is specified in this case. Valid algorithm values - one of
13062306a36Sopenharmony_ci *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
13162306a36Sopenharmony_ci *         with OP_ALG_AAI_HMAC_PRECOMP.
13262306a36Sopenharmony_ci * @icvsize: integrity check value (ICV) size (truncated or full)
13362306a36Sopenharmony_ci * @era: SEC Era
13462306a36Sopenharmony_ci */
13562306a36Sopenharmony_civoid cnstr_shdsc_aead_null_decap(u32 * const desc, struct alginfo *adata,
13662306a36Sopenharmony_ci				 unsigned int icvsize, int era)
13762306a36Sopenharmony_ci{
13862306a36Sopenharmony_ci	u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd, *jump_cmd;
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	init_sh_desc(desc, HDR_SHARE_SERIAL);
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci	/* Skip if already shared */
14362306a36Sopenharmony_ci	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
14462306a36Sopenharmony_ci				   JUMP_COND_SHRD);
14562306a36Sopenharmony_ci	if (era < 6) {
14662306a36Sopenharmony_ci		if (adata->key_inline)
14762306a36Sopenharmony_ci			append_key_as_imm(desc, adata->key_virt,
14862306a36Sopenharmony_ci					  adata->keylen_pad, adata->keylen,
14962306a36Sopenharmony_ci					  CLASS_2 | KEY_DEST_MDHA_SPLIT |
15062306a36Sopenharmony_ci					  KEY_ENC);
15162306a36Sopenharmony_ci		else
15262306a36Sopenharmony_ci			append_key(desc, adata->key_dma, adata->keylen,
15362306a36Sopenharmony_ci				   CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
15462306a36Sopenharmony_ci	} else {
15562306a36Sopenharmony_ci		append_proto_dkp(desc, adata);
15662306a36Sopenharmony_ci	}
15762306a36Sopenharmony_ci	set_jump_tgt_here(desc, key_jump_cmd);
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci	/* Class 2 operation */
16062306a36Sopenharmony_ci	append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
16162306a36Sopenharmony_ci			 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci	/* assoclen + cryptlen = seqoutlen */
16462306a36Sopenharmony_ci	append_math_sub(desc, REG2, SEQOUTLEN, REG0, CAAM_CMD_SZ);
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci	/* Prepare to read and write cryptlen + assoclen bytes */
16762306a36Sopenharmony_ci	append_math_add(desc, VARSEQINLEN, ZERO, REG2, CAAM_CMD_SZ);
16862306a36Sopenharmony_ci	append_math_add(desc, VARSEQOUTLEN, ZERO, REG2, CAAM_CMD_SZ);
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci	/*
17162306a36Sopenharmony_ci	 * MOVE_LEN opcode is not available in all SEC HW revisions,
17262306a36Sopenharmony_ci	 * thus need to do some magic, i.e. self-patch the descriptor
17362306a36Sopenharmony_ci	 * buffer.
17462306a36Sopenharmony_ci	 */
17562306a36Sopenharmony_ci	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
17662306a36Sopenharmony_ci				    MOVE_DEST_MATH2 |
17762306a36Sopenharmony_ci				    (0x6 << MOVE_LEN_SHIFT));
17862306a36Sopenharmony_ci	write_move_cmd = append_move(desc, MOVE_SRC_MATH2 |
17962306a36Sopenharmony_ci				     MOVE_DEST_DESCBUF |
18062306a36Sopenharmony_ci				     MOVE_WAITCOMP |
18162306a36Sopenharmony_ci				     (0x8 << MOVE_LEN_SHIFT));
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci	/* Read and write cryptlen bytes */
18462306a36Sopenharmony_ci	aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci	/*
18762306a36Sopenharmony_ci	 * Insert a NOP here, since we need at least 4 instructions between
18862306a36Sopenharmony_ci	 * code patching the descriptor buffer and the location being patched.
18962306a36Sopenharmony_ci	 */
19062306a36Sopenharmony_ci	jump_cmd = append_jump(desc, JUMP_TEST_ALL);
19162306a36Sopenharmony_ci	set_jump_tgt_here(desc, jump_cmd);
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci	set_move_tgt_here(desc, read_move_cmd);
19462306a36Sopenharmony_ci	set_move_tgt_here(desc, write_move_cmd);
19562306a36Sopenharmony_ci	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
19662306a36Sopenharmony_ci	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
19762306a36Sopenharmony_ci		    MOVE_AUX_LS);
19862306a36Sopenharmony_ci	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci	/* Load ICV */
20162306a36Sopenharmony_ci	append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
20262306a36Sopenharmony_ci			     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci	print_hex_dump_debug("aead null dec shdesc@" __stringify(__LINE__)": ",
20562306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
20662306a36Sopenharmony_ci			     1);
20762306a36Sopenharmony_ci}
20862306a36Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_aead_null_decap);
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_cistatic void init_sh_desc_key_aead(u32 * const desc,
21162306a36Sopenharmony_ci				  struct alginfo * const cdata,
21262306a36Sopenharmony_ci				  struct alginfo * const adata,
21362306a36Sopenharmony_ci				  const bool is_rfc3686, u32 *nonce, int era)
21462306a36Sopenharmony_ci{
21562306a36Sopenharmony_ci	u32 *key_jump_cmd;
21662306a36Sopenharmony_ci	unsigned int enckeylen = cdata->keylen;
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	/* Note: Context registers are saved. */
21962306a36Sopenharmony_ci	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci	/* Skip if already shared */
22262306a36Sopenharmony_ci	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
22362306a36Sopenharmony_ci				   JUMP_COND_SHRD);
22462306a36Sopenharmony_ci
22562306a36Sopenharmony_ci	/*
22662306a36Sopenharmony_ci	 * RFC3686 specific:
22762306a36Sopenharmony_ci	 *	| key = {AUTH_KEY, ENC_KEY, NONCE}
22862306a36Sopenharmony_ci	 *	| enckeylen = encryption key size + nonce size
22962306a36Sopenharmony_ci	 */
23062306a36Sopenharmony_ci	if (is_rfc3686)
23162306a36Sopenharmony_ci		enckeylen -= CTR_RFC3686_NONCE_SIZE;
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci	if (era < 6) {
23462306a36Sopenharmony_ci		if (adata->key_inline)
23562306a36Sopenharmony_ci			append_key_as_imm(desc, adata->key_virt,
23662306a36Sopenharmony_ci					  adata->keylen_pad, adata->keylen,
23762306a36Sopenharmony_ci					  CLASS_2 | KEY_DEST_MDHA_SPLIT |
23862306a36Sopenharmony_ci					  KEY_ENC);
23962306a36Sopenharmony_ci		else
24062306a36Sopenharmony_ci			append_key(desc, adata->key_dma, adata->keylen,
24162306a36Sopenharmony_ci				   CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
24262306a36Sopenharmony_ci	} else {
24362306a36Sopenharmony_ci		append_proto_dkp(desc, adata);
24462306a36Sopenharmony_ci	}
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ci	if (cdata->key_inline)
24762306a36Sopenharmony_ci		append_key_as_imm(desc, cdata->key_virt, enckeylen,
24862306a36Sopenharmony_ci				  enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
24962306a36Sopenharmony_ci	else
25062306a36Sopenharmony_ci		append_key(desc, cdata->key_dma, enckeylen, CLASS_1 |
25162306a36Sopenharmony_ci			   KEY_DEST_CLASS_REG);
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci	/* Load Counter into CONTEXT1 reg */
25462306a36Sopenharmony_ci	if (is_rfc3686) {
25562306a36Sopenharmony_ci		append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
25662306a36Sopenharmony_ci				   LDST_CLASS_IND_CCB |
25762306a36Sopenharmony_ci				   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
25862306a36Sopenharmony_ci		append_move(desc,
25962306a36Sopenharmony_ci			    MOVE_SRC_OUTFIFO |
26062306a36Sopenharmony_ci			    MOVE_DEST_CLASS1CTX |
26162306a36Sopenharmony_ci			    (16 << MOVE_OFFSET_SHIFT) |
26262306a36Sopenharmony_ci			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
26362306a36Sopenharmony_ci	}
26462306a36Sopenharmony_ci
26562306a36Sopenharmony_ci	set_jump_tgt_here(desc, key_jump_cmd);
26662306a36Sopenharmony_ci}
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci/**
26962306a36Sopenharmony_ci * cnstr_shdsc_aead_encap - IPSec ESP encapsulation shared descriptor
27062306a36Sopenharmony_ci *                          (non-protocol).
27162306a36Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction
27262306a36Sopenharmony_ci * @cdata: pointer to block cipher transform definitions
27362306a36Sopenharmony_ci *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
27462306a36Sopenharmony_ci *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
27562306a36Sopenharmony_ci * @adata: pointer to authentication transform definitions.
27662306a36Sopenharmony_ci *         A split key is required for SEC Era < 6; the size of the split key
27762306a36Sopenharmony_ci *         is specified in this case. Valid algorithm values - one of
27862306a36Sopenharmony_ci *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
27962306a36Sopenharmony_ci *         with OP_ALG_AAI_HMAC_PRECOMP.
28062306a36Sopenharmony_ci * @ivsize: initialization vector size
28162306a36Sopenharmony_ci * @icvsize: integrity check value (ICV) size (truncated or full)
28262306a36Sopenharmony_ci * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
28362306a36Sopenharmony_ci * @nonce: pointer to rfc3686 nonce
28462306a36Sopenharmony_ci * @ctx1_iv_off: IV offset in CONTEXT1 register
28562306a36Sopenharmony_ci * @is_qi: true when called from caam/qi
28662306a36Sopenharmony_ci * @era: SEC Era
28762306a36Sopenharmony_ci */
28862306a36Sopenharmony_civoid cnstr_shdsc_aead_encap(u32 * const desc, struct alginfo *cdata,
28962306a36Sopenharmony_ci			    struct alginfo *adata, unsigned int ivsize,
29062306a36Sopenharmony_ci			    unsigned int icvsize, const bool is_rfc3686,
29162306a36Sopenharmony_ci			    u32 *nonce, const u32 ctx1_iv_off, const bool is_qi,
29262306a36Sopenharmony_ci			    int era)
29362306a36Sopenharmony_ci{
29462306a36Sopenharmony_ci	/* Note: Context registers are saved. */
29562306a36Sopenharmony_ci	init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	/* Class 2 operation */
29862306a36Sopenharmony_ci	append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
29962306a36Sopenharmony_ci			 OP_ALG_ENCRYPT);
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci	if (is_qi) {
30262306a36Sopenharmony_ci		u32 *wait_load_cmd;
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci		/* REG3 = assoclen */
30562306a36Sopenharmony_ci		append_seq_load(desc, 4, LDST_CLASS_DECO |
30662306a36Sopenharmony_ci				LDST_SRCDST_WORD_DECO_MATH3 |
30762306a36Sopenharmony_ci				(4 << LDST_OFFSET_SHIFT));
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_ci		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
31062306a36Sopenharmony_ci					    JUMP_COND_CALM | JUMP_COND_NCP |
31162306a36Sopenharmony_ci					    JUMP_COND_NOP | JUMP_COND_NIP |
31262306a36Sopenharmony_ci					    JUMP_COND_NIFP);
31362306a36Sopenharmony_ci		set_jump_tgt_here(desc, wait_load_cmd);
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci		append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
31662306a36Sopenharmony_ci				LDST_SRCDST_BYTE_CONTEXT |
31762306a36Sopenharmony_ci				(ctx1_iv_off << LDST_OFFSET_SHIFT));
31862306a36Sopenharmony_ci	}
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci	/* Read and write assoclen bytes */
32162306a36Sopenharmony_ci	if (is_qi || era < 3) {
32262306a36Sopenharmony_ci		append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
32362306a36Sopenharmony_ci		append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
32462306a36Sopenharmony_ci	} else {
32562306a36Sopenharmony_ci		append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
32662306a36Sopenharmony_ci		append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
32762306a36Sopenharmony_ci	}
32862306a36Sopenharmony_ci
32962306a36Sopenharmony_ci	/* Skip assoc data */
33062306a36Sopenharmony_ci	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ci	/* read assoc before reading payload */
33362306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
33462306a36Sopenharmony_ci				      FIFOLDST_VLF);
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci	/* Load Counter into CONTEXT1 reg */
33762306a36Sopenharmony_ci	if (is_rfc3686)
33862306a36Sopenharmony_ci		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
33962306a36Sopenharmony_ci				     LDST_SRCDST_BYTE_CONTEXT |
34062306a36Sopenharmony_ci				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
34162306a36Sopenharmony_ci				      LDST_OFFSET_SHIFT));
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci	/* Class 1 operation */
34462306a36Sopenharmony_ci	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
34562306a36Sopenharmony_ci			 OP_ALG_ENCRYPT);
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci	/* Read and write cryptlen bytes */
34862306a36Sopenharmony_ci	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
34962306a36Sopenharmony_ci	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
35062306a36Sopenharmony_ci	aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci	/* Write ICV */
35362306a36Sopenharmony_ci	append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
35462306a36Sopenharmony_ci			 LDST_SRCDST_BYTE_CONTEXT);
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci	print_hex_dump_debug("aead enc shdesc@" __stringify(__LINE__)": ",
35762306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
35862306a36Sopenharmony_ci			     1);
35962306a36Sopenharmony_ci}
36062306a36Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_aead_encap);
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci/**
36362306a36Sopenharmony_ci * cnstr_shdsc_aead_decap - IPSec ESP decapsulation shared descriptor
36462306a36Sopenharmony_ci *                          (non-protocol).
36562306a36Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction
36662306a36Sopenharmony_ci * @cdata: pointer to block cipher transform definitions
36762306a36Sopenharmony_ci *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
36862306a36Sopenharmony_ci *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
36962306a36Sopenharmony_ci * @adata: pointer to authentication transform definitions.
37062306a36Sopenharmony_ci *         A split key is required for SEC Era < 6; the size of the split key
37162306a36Sopenharmony_ci *         is specified in this case. Valid algorithm values - one of
37262306a36Sopenharmony_ci *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
37362306a36Sopenharmony_ci *         with OP_ALG_AAI_HMAC_PRECOMP.
37462306a36Sopenharmony_ci * @ivsize: initialization vector size
37562306a36Sopenharmony_ci * @icvsize: integrity check value (ICV) size (truncated or full)
37662306a36Sopenharmony_ci * @geniv: whether to generate Encrypted Chain IV
37762306a36Sopenharmony_ci * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
37862306a36Sopenharmony_ci * @nonce: pointer to rfc3686 nonce
37962306a36Sopenharmony_ci * @ctx1_iv_off: IV offset in CONTEXT1 register
38062306a36Sopenharmony_ci * @is_qi: true when called from caam/qi
38162306a36Sopenharmony_ci * @era: SEC Era
38262306a36Sopenharmony_ci */
38362306a36Sopenharmony_civoid cnstr_shdsc_aead_decap(u32 * const desc, struct alginfo *cdata,
38462306a36Sopenharmony_ci			    struct alginfo *adata, unsigned int ivsize,
38562306a36Sopenharmony_ci			    unsigned int icvsize, const bool geniv,
38662306a36Sopenharmony_ci			    const bool is_rfc3686, u32 *nonce,
38762306a36Sopenharmony_ci			    const u32 ctx1_iv_off, const bool is_qi, int era)
38862306a36Sopenharmony_ci{
38962306a36Sopenharmony_ci	/* Note: Context registers are saved. */
39062306a36Sopenharmony_ci	init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
39162306a36Sopenharmony_ci
39262306a36Sopenharmony_ci	/* Class 2 operation */
39362306a36Sopenharmony_ci	append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
39462306a36Sopenharmony_ci			 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ci	if (is_qi) {
39762306a36Sopenharmony_ci		u32 *wait_load_cmd;
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci		/* REG3 = assoclen */
40062306a36Sopenharmony_ci		append_seq_load(desc, 4, LDST_CLASS_DECO |
40162306a36Sopenharmony_ci				LDST_SRCDST_WORD_DECO_MATH3 |
40262306a36Sopenharmony_ci				(4 << LDST_OFFSET_SHIFT));
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ci		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
40562306a36Sopenharmony_ci					    JUMP_COND_CALM | JUMP_COND_NCP |
40662306a36Sopenharmony_ci					    JUMP_COND_NOP | JUMP_COND_NIP |
40762306a36Sopenharmony_ci					    JUMP_COND_NIFP);
40862306a36Sopenharmony_ci		set_jump_tgt_here(desc, wait_load_cmd);
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ci		if (!geniv)
41162306a36Sopenharmony_ci			append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
41262306a36Sopenharmony_ci					LDST_SRCDST_BYTE_CONTEXT |
41362306a36Sopenharmony_ci					(ctx1_iv_off << LDST_OFFSET_SHIFT));
41462306a36Sopenharmony_ci	}
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ci	/* Read and write assoclen bytes */
41762306a36Sopenharmony_ci	if (is_qi || era < 3) {
41862306a36Sopenharmony_ci		append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
41962306a36Sopenharmony_ci		if (geniv)
42062306a36Sopenharmony_ci			append_math_add_imm_u32(desc, VARSEQOUTLEN, REG3, IMM,
42162306a36Sopenharmony_ci						ivsize);
42262306a36Sopenharmony_ci		else
42362306a36Sopenharmony_ci			append_math_add(desc, VARSEQOUTLEN, ZERO, REG3,
42462306a36Sopenharmony_ci					CAAM_CMD_SZ);
42562306a36Sopenharmony_ci	} else {
42662306a36Sopenharmony_ci		append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
42762306a36Sopenharmony_ci		if (geniv)
42862306a36Sopenharmony_ci			append_math_add_imm_u32(desc, VARSEQOUTLEN, DPOVRD, IMM,
42962306a36Sopenharmony_ci						ivsize);
43062306a36Sopenharmony_ci		else
43162306a36Sopenharmony_ci			append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD,
43262306a36Sopenharmony_ci					CAAM_CMD_SZ);
43362306a36Sopenharmony_ci	}
43462306a36Sopenharmony_ci
43562306a36Sopenharmony_ci	/* Skip assoc data */
43662306a36Sopenharmony_ci	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci	/* read assoc before reading payload */
43962306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
44062306a36Sopenharmony_ci			     KEY_VLF);
44162306a36Sopenharmony_ci
44262306a36Sopenharmony_ci	if (geniv) {
44362306a36Sopenharmony_ci		append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
44462306a36Sopenharmony_ci				LDST_SRCDST_BYTE_CONTEXT |
44562306a36Sopenharmony_ci				(ctx1_iv_off << LDST_OFFSET_SHIFT));
44662306a36Sopenharmony_ci		append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO |
44762306a36Sopenharmony_ci			    (ctx1_iv_off << MOVE_OFFSET_SHIFT) | ivsize);
44862306a36Sopenharmony_ci	}
44962306a36Sopenharmony_ci
45062306a36Sopenharmony_ci	/* Load Counter into CONTEXT1 reg */
45162306a36Sopenharmony_ci	if (is_rfc3686)
45262306a36Sopenharmony_ci		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
45362306a36Sopenharmony_ci				     LDST_SRCDST_BYTE_CONTEXT |
45462306a36Sopenharmony_ci				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
45562306a36Sopenharmony_ci				      LDST_OFFSET_SHIFT));
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_ci	/* Choose operation */
45862306a36Sopenharmony_ci	if (ctx1_iv_off)
45962306a36Sopenharmony_ci		append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
46062306a36Sopenharmony_ci				 OP_ALG_DECRYPT);
46162306a36Sopenharmony_ci	else
46262306a36Sopenharmony_ci		append_dec_op1(desc, cdata->algtype);
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ci	/* Read and write cryptlen bytes */
46562306a36Sopenharmony_ci	append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
46662306a36Sopenharmony_ci	append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
46762306a36Sopenharmony_ci	aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci	/* Load ICV */
47062306a36Sopenharmony_ci	append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
47162306a36Sopenharmony_ci			     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_ci	print_hex_dump_debug("aead dec shdesc@" __stringify(__LINE__)": ",
47462306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
47562306a36Sopenharmony_ci			     1);
47662306a36Sopenharmony_ci}
47762306a36Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_aead_decap);
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci/**
48062306a36Sopenharmony_ci * cnstr_shdsc_aead_givencap - IPSec ESP encapsulation shared descriptor
48162306a36Sopenharmony_ci *                             (non-protocol) with HW-generated initialization
48262306a36Sopenharmony_ci *                             vector.
48362306a36Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction
48462306a36Sopenharmony_ci * @cdata: pointer to block cipher transform definitions
48562306a36Sopenharmony_ci *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
48662306a36Sopenharmony_ci *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
48762306a36Sopenharmony_ci * @adata: pointer to authentication transform definitions.
48862306a36Sopenharmony_ci *         A split key is required for SEC Era < 6; the size of the split key
48962306a36Sopenharmony_ci *         is specified in this case. Valid algorithm values - one of
49062306a36Sopenharmony_ci *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
49162306a36Sopenharmony_ci *         with OP_ALG_AAI_HMAC_PRECOMP.
49262306a36Sopenharmony_ci * @ivsize: initialization vector size
49362306a36Sopenharmony_ci * @icvsize: integrity check value (ICV) size (truncated or full)
49462306a36Sopenharmony_ci * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
49562306a36Sopenharmony_ci * @nonce: pointer to rfc3686 nonce
49662306a36Sopenharmony_ci * @ctx1_iv_off: IV offset in CONTEXT1 register
49762306a36Sopenharmony_ci * @is_qi: true when called from caam/qi
49862306a36Sopenharmony_ci * @era: SEC Era
49962306a36Sopenharmony_ci */
50062306a36Sopenharmony_civoid cnstr_shdsc_aead_givencap(u32 * const desc, struct alginfo *cdata,
50162306a36Sopenharmony_ci			       struct alginfo *adata, unsigned int ivsize,
50262306a36Sopenharmony_ci			       unsigned int icvsize, const bool is_rfc3686,
50362306a36Sopenharmony_ci			       u32 *nonce, const u32 ctx1_iv_off,
50462306a36Sopenharmony_ci			       const bool is_qi, int era)
50562306a36Sopenharmony_ci{
50662306a36Sopenharmony_ci	u32 geniv, moveiv;
50762306a36Sopenharmony_ci	u32 *wait_cmd;
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ci	/* Note: Context registers are saved. */
51062306a36Sopenharmony_ci	init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_ci	if (is_qi) {
51362306a36Sopenharmony_ci		u32 *wait_load_cmd;
51462306a36Sopenharmony_ci
51562306a36Sopenharmony_ci		/* REG3 = assoclen */
51662306a36Sopenharmony_ci		append_seq_load(desc, 4, LDST_CLASS_DECO |
51762306a36Sopenharmony_ci				LDST_SRCDST_WORD_DECO_MATH3 |
51862306a36Sopenharmony_ci				(4 << LDST_OFFSET_SHIFT));
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ci		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
52162306a36Sopenharmony_ci					    JUMP_COND_CALM | JUMP_COND_NCP |
52262306a36Sopenharmony_ci					    JUMP_COND_NOP | JUMP_COND_NIP |
52362306a36Sopenharmony_ci					    JUMP_COND_NIFP);
52462306a36Sopenharmony_ci		set_jump_tgt_here(desc, wait_load_cmd);
52562306a36Sopenharmony_ci	}
52662306a36Sopenharmony_ci
52762306a36Sopenharmony_ci	if (is_rfc3686) {
52862306a36Sopenharmony_ci		if (is_qi)
52962306a36Sopenharmony_ci			append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
53062306a36Sopenharmony_ci					LDST_SRCDST_BYTE_CONTEXT |
53162306a36Sopenharmony_ci					(ctx1_iv_off << LDST_OFFSET_SHIFT));
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_ci		goto copy_iv;
53462306a36Sopenharmony_ci	}
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_ci	/* Generate IV */
53762306a36Sopenharmony_ci	geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
53862306a36Sopenharmony_ci		NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 |
53962306a36Sopenharmony_ci		NFIFOENTRY_PTYPE_RND | (ivsize << NFIFOENTRY_DLEN_SHIFT);
54062306a36Sopenharmony_ci	append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
54162306a36Sopenharmony_ci			    LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
54262306a36Sopenharmony_ci	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
54362306a36Sopenharmony_ci	append_move(desc, MOVE_WAITCOMP |
54462306a36Sopenharmony_ci		    MOVE_SRC_INFIFO | MOVE_DEST_CLASS1CTX |
54562306a36Sopenharmony_ci		    (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
54662306a36Sopenharmony_ci		    (ivsize << MOVE_LEN_SHIFT));
54762306a36Sopenharmony_ci	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
54862306a36Sopenharmony_ci
54962306a36Sopenharmony_cicopy_iv:
55062306a36Sopenharmony_ci	/* Copy IV to class 1 context */
55162306a36Sopenharmony_ci	append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_OUTFIFO |
55262306a36Sopenharmony_ci		    (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
55362306a36Sopenharmony_ci		    (ivsize << MOVE_LEN_SHIFT));
55462306a36Sopenharmony_ci
55562306a36Sopenharmony_ci	/* Return to encryption */
55662306a36Sopenharmony_ci	append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
55762306a36Sopenharmony_ci			 OP_ALG_ENCRYPT);
55862306a36Sopenharmony_ci
55962306a36Sopenharmony_ci	/* Read and write assoclen bytes */
56062306a36Sopenharmony_ci	if (is_qi || era < 3) {
56162306a36Sopenharmony_ci		append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
56262306a36Sopenharmony_ci		append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
56362306a36Sopenharmony_ci	} else {
56462306a36Sopenharmony_ci		append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
56562306a36Sopenharmony_ci		append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
56662306a36Sopenharmony_ci	}
56762306a36Sopenharmony_ci
56862306a36Sopenharmony_ci	/* Skip assoc data */
56962306a36Sopenharmony_ci	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
57062306a36Sopenharmony_ci
57162306a36Sopenharmony_ci	/* read assoc before reading payload */
57262306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
57362306a36Sopenharmony_ci			     KEY_VLF);
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_ci	/* Copy iv from outfifo to class 2 fifo */
57662306a36Sopenharmony_ci	moveiv = NFIFOENTRY_STYPE_OFIFO | NFIFOENTRY_DEST_CLASS2 |
57762306a36Sopenharmony_ci		 NFIFOENTRY_DTYPE_MSG | (ivsize << NFIFOENTRY_DLEN_SHIFT);
57862306a36Sopenharmony_ci	append_load_imm_u32(desc, moveiv, LDST_CLASS_IND_CCB |
57962306a36Sopenharmony_ci			    LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
58062306a36Sopenharmony_ci	append_load_imm_u32(desc, ivsize, LDST_CLASS_2_CCB |
58162306a36Sopenharmony_ci			    LDST_SRCDST_WORD_DATASZ_REG | LDST_IMM);
58262306a36Sopenharmony_ci
58362306a36Sopenharmony_ci	/* Load Counter into CONTEXT1 reg */
58462306a36Sopenharmony_ci	if (is_rfc3686)
58562306a36Sopenharmony_ci		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
58662306a36Sopenharmony_ci				     LDST_SRCDST_BYTE_CONTEXT |
58762306a36Sopenharmony_ci				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
58862306a36Sopenharmony_ci				      LDST_OFFSET_SHIFT));
58962306a36Sopenharmony_ci
59062306a36Sopenharmony_ci	/* Class 1 operation */
59162306a36Sopenharmony_ci	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
59262306a36Sopenharmony_ci			 OP_ALG_ENCRYPT);
59362306a36Sopenharmony_ci
59462306a36Sopenharmony_ci	/* Will write ivsize + cryptlen */
59562306a36Sopenharmony_ci	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
59662306a36Sopenharmony_ci
59762306a36Sopenharmony_ci	/* Not need to reload iv */
59862306a36Sopenharmony_ci	append_seq_fifo_load(desc, ivsize,
59962306a36Sopenharmony_ci			     FIFOLD_CLASS_SKIP);
60062306a36Sopenharmony_ci
60162306a36Sopenharmony_ci	/* Will read cryptlen */
60262306a36Sopenharmony_ci	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci	/*
60562306a36Sopenharmony_ci	 * Wait for IV transfer (ofifo -> class2) to finish before starting
60662306a36Sopenharmony_ci	 * ciphertext transfer (ofifo -> external memory).
60762306a36Sopenharmony_ci	 */
60862306a36Sopenharmony_ci	wait_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | JUMP_COND_NIFP);
60962306a36Sopenharmony_ci	set_jump_tgt_here(desc, wait_cmd);
61062306a36Sopenharmony_ci
61162306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | KEY_VLF |
61262306a36Sopenharmony_ci			     FIFOLD_TYPE_MSG1OUT2 | FIFOLD_TYPE_LASTBOTH);
61362306a36Sopenharmony_ci	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
61462306a36Sopenharmony_ci
61562306a36Sopenharmony_ci	/* Write ICV */
61662306a36Sopenharmony_ci	append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
61762306a36Sopenharmony_ci			 LDST_SRCDST_BYTE_CONTEXT);
61862306a36Sopenharmony_ci
61962306a36Sopenharmony_ci	print_hex_dump_debug("aead givenc shdesc@" __stringify(__LINE__)": ",
62062306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
62162306a36Sopenharmony_ci			     1);
62262306a36Sopenharmony_ci}
62362306a36Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_aead_givencap);
62462306a36Sopenharmony_ci
62562306a36Sopenharmony_ci/**
62662306a36Sopenharmony_ci * cnstr_shdsc_gcm_encap - gcm encapsulation shared descriptor
62762306a36Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction
62862306a36Sopenharmony_ci * @cdata: pointer to block cipher transform definitions
62962306a36Sopenharmony_ci *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
63062306a36Sopenharmony_ci * @ivsize: initialization vector size
63162306a36Sopenharmony_ci * @icvsize: integrity check value (ICV) size (truncated or full)
63262306a36Sopenharmony_ci * @is_qi: true when called from caam/qi
63362306a36Sopenharmony_ci */
63462306a36Sopenharmony_civoid cnstr_shdsc_gcm_encap(u32 * const desc, struct alginfo *cdata,
63562306a36Sopenharmony_ci			   unsigned int ivsize, unsigned int icvsize,
63662306a36Sopenharmony_ci			   const bool is_qi)
63762306a36Sopenharmony_ci{
63862306a36Sopenharmony_ci	u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1,
63962306a36Sopenharmony_ci	    *zero_assoc_jump_cmd2;
64062306a36Sopenharmony_ci
64162306a36Sopenharmony_ci	init_sh_desc(desc, HDR_SHARE_SERIAL);
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_ci	/* skip key loading if they are loaded due to sharing */
64462306a36Sopenharmony_ci	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
64562306a36Sopenharmony_ci				   JUMP_COND_SHRD);
64662306a36Sopenharmony_ci	if (cdata->key_inline)
64762306a36Sopenharmony_ci		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
64862306a36Sopenharmony_ci				  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
64962306a36Sopenharmony_ci	else
65062306a36Sopenharmony_ci		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
65162306a36Sopenharmony_ci			   KEY_DEST_CLASS_REG);
65262306a36Sopenharmony_ci	set_jump_tgt_here(desc, key_jump_cmd);
65362306a36Sopenharmony_ci
65462306a36Sopenharmony_ci	/* class 1 operation */
65562306a36Sopenharmony_ci	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
65662306a36Sopenharmony_ci			 OP_ALG_ENCRYPT);
65762306a36Sopenharmony_ci
65862306a36Sopenharmony_ci	if (is_qi) {
65962306a36Sopenharmony_ci		u32 *wait_load_cmd;
66062306a36Sopenharmony_ci
66162306a36Sopenharmony_ci		/* REG3 = assoclen */
66262306a36Sopenharmony_ci		append_seq_load(desc, 4, LDST_CLASS_DECO |
66362306a36Sopenharmony_ci				LDST_SRCDST_WORD_DECO_MATH3 |
66462306a36Sopenharmony_ci				(4 << LDST_OFFSET_SHIFT));
66562306a36Sopenharmony_ci
66662306a36Sopenharmony_ci		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
66762306a36Sopenharmony_ci					    JUMP_COND_CALM | JUMP_COND_NCP |
66862306a36Sopenharmony_ci					    JUMP_COND_NOP | JUMP_COND_NIP |
66962306a36Sopenharmony_ci					    JUMP_COND_NIFP);
67062306a36Sopenharmony_ci		set_jump_tgt_here(desc, wait_load_cmd);
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_ci		append_math_sub_imm_u32(desc, VARSEQOUTLEN, SEQINLEN, IMM,
67362306a36Sopenharmony_ci					ivsize);
67462306a36Sopenharmony_ci	} else {
67562306a36Sopenharmony_ci		append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0,
67662306a36Sopenharmony_ci				CAAM_CMD_SZ);
67762306a36Sopenharmony_ci	}
67862306a36Sopenharmony_ci
67962306a36Sopenharmony_ci	/* if assoclen + cryptlen is ZERO, skip to ICV write */
68062306a36Sopenharmony_ci	zero_assoc_jump_cmd2 = append_jump(desc, JUMP_TEST_ALL |
68162306a36Sopenharmony_ci						 JUMP_COND_MATH_Z);
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_ci	if (is_qi)
68462306a36Sopenharmony_ci		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
68562306a36Sopenharmony_ci				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_ci	/* if assoclen is ZERO, skip reading the assoc data */
68862306a36Sopenharmony_ci	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
68962306a36Sopenharmony_ci	zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
69062306a36Sopenharmony_ci					   JUMP_COND_MATH_Z);
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_ci	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
69362306a36Sopenharmony_ci
69462306a36Sopenharmony_ci	/* skip assoc data */
69562306a36Sopenharmony_ci	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
69662306a36Sopenharmony_ci
69762306a36Sopenharmony_ci	/* cryptlen = seqinlen - assoclen */
69862306a36Sopenharmony_ci	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
69962306a36Sopenharmony_ci
70062306a36Sopenharmony_ci	/* if cryptlen is ZERO jump to zero-payload commands */
70162306a36Sopenharmony_ci	zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
70262306a36Sopenharmony_ci					    JUMP_COND_MATH_Z);
70362306a36Sopenharmony_ci
70462306a36Sopenharmony_ci	/* read assoc data */
70562306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
70662306a36Sopenharmony_ci			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
70762306a36Sopenharmony_ci	set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
70862306a36Sopenharmony_ci
70962306a36Sopenharmony_ci	append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
71062306a36Sopenharmony_ci
71162306a36Sopenharmony_ci	/* write encrypted data */
71262306a36Sopenharmony_ci	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
71362306a36Sopenharmony_ci
71462306a36Sopenharmony_ci	/* read payload data */
71562306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
71662306a36Sopenharmony_ci			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
71762306a36Sopenharmony_ci
71862306a36Sopenharmony_ci	/* jump to ICV writing */
71962306a36Sopenharmony_ci	if (is_qi)
72062306a36Sopenharmony_ci		append_jump(desc, JUMP_TEST_ALL | 4);
72162306a36Sopenharmony_ci	else
72262306a36Sopenharmony_ci		append_jump(desc, JUMP_TEST_ALL | 2);
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_ci	/* zero-payload commands */
72562306a36Sopenharmony_ci	set_jump_tgt_here(desc, zero_payload_jump_cmd);
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_ci	/* read assoc data */
72862306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
72962306a36Sopenharmony_ci			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
73062306a36Sopenharmony_ci	if (is_qi)
73162306a36Sopenharmony_ci		/* jump to ICV writing */
73262306a36Sopenharmony_ci		append_jump(desc, JUMP_TEST_ALL | 2);
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_ci	/* There is no input data */
73562306a36Sopenharmony_ci	set_jump_tgt_here(desc, zero_assoc_jump_cmd2);
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_ci	if (is_qi)
73862306a36Sopenharmony_ci		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
73962306a36Sopenharmony_ci				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 |
74062306a36Sopenharmony_ci				     FIFOLD_TYPE_LAST1);
74162306a36Sopenharmony_ci
74262306a36Sopenharmony_ci	/* write ICV */
74362306a36Sopenharmony_ci	append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
74462306a36Sopenharmony_ci			 LDST_SRCDST_BYTE_CONTEXT);
74562306a36Sopenharmony_ci
74662306a36Sopenharmony_ci	print_hex_dump_debug("gcm enc shdesc@" __stringify(__LINE__)": ",
74762306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
74862306a36Sopenharmony_ci			     1);
74962306a36Sopenharmony_ci}
75062306a36Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_gcm_encap);
75162306a36Sopenharmony_ci
75262306a36Sopenharmony_ci/**
75362306a36Sopenharmony_ci * cnstr_shdsc_gcm_decap - gcm decapsulation shared descriptor
75462306a36Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction
75562306a36Sopenharmony_ci * @cdata: pointer to block cipher transform definitions
75662306a36Sopenharmony_ci *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
75762306a36Sopenharmony_ci * @ivsize: initialization vector size
75862306a36Sopenharmony_ci * @icvsize: integrity check value (ICV) size (truncated or full)
75962306a36Sopenharmony_ci * @is_qi: true when called from caam/qi
76062306a36Sopenharmony_ci */
76162306a36Sopenharmony_civoid cnstr_shdsc_gcm_decap(u32 * const desc, struct alginfo *cdata,
76262306a36Sopenharmony_ci			   unsigned int ivsize, unsigned int icvsize,
76362306a36Sopenharmony_ci			   const bool is_qi)
76462306a36Sopenharmony_ci{
76562306a36Sopenharmony_ci	u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1;
76662306a36Sopenharmony_ci
76762306a36Sopenharmony_ci	init_sh_desc(desc, HDR_SHARE_SERIAL);
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_ci	/* skip key loading if they are loaded due to sharing */
77062306a36Sopenharmony_ci	key_jump_cmd = append_jump(desc, JUMP_JSL |
77162306a36Sopenharmony_ci				   JUMP_TEST_ALL | JUMP_COND_SHRD);
77262306a36Sopenharmony_ci	if (cdata->key_inline)
77362306a36Sopenharmony_ci		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
77462306a36Sopenharmony_ci				  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
77562306a36Sopenharmony_ci	else
77662306a36Sopenharmony_ci		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
77762306a36Sopenharmony_ci			   KEY_DEST_CLASS_REG);
77862306a36Sopenharmony_ci	set_jump_tgt_here(desc, key_jump_cmd);
77962306a36Sopenharmony_ci
78062306a36Sopenharmony_ci	/* class 1 operation */
78162306a36Sopenharmony_ci	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
78262306a36Sopenharmony_ci			 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
78362306a36Sopenharmony_ci
78462306a36Sopenharmony_ci	if (is_qi) {
78562306a36Sopenharmony_ci		u32 *wait_load_cmd;
78662306a36Sopenharmony_ci
78762306a36Sopenharmony_ci		/* REG3 = assoclen */
78862306a36Sopenharmony_ci		append_seq_load(desc, 4, LDST_CLASS_DECO |
78962306a36Sopenharmony_ci				LDST_SRCDST_WORD_DECO_MATH3 |
79062306a36Sopenharmony_ci				(4 << LDST_OFFSET_SHIFT));
79162306a36Sopenharmony_ci
79262306a36Sopenharmony_ci		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
79362306a36Sopenharmony_ci					    JUMP_COND_CALM | JUMP_COND_NCP |
79462306a36Sopenharmony_ci					    JUMP_COND_NOP | JUMP_COND_NIP |
79562306a36Sopenharmony_ci					    JUMP_COND_NIFP);
79662306a36Sopenharmony_ci		set_jump_tgt_here(desc, wait_load_cmd);
79762306a36Sopenharmony_ci
79862306a36Sopenharmony_ci		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
79962306a36Sopenharmony_ci				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
80062306a36Sopenharmony_ci	}
80162306a36Sopenharmony_ci
80262306a36Sopenharmony_ci	/* if assoclen is ZERO, skip reading the assoc data */
80362306a36Sopenharmony_ci	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
80462306a36Sopenharmony_ci	zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
80562306a36Sopenharmony_ci						 JUMP_COND_MATH_Z);
80662306a36Sopenharmony_ci
80762306a36Sopenharmony_ci	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
80862306a36Sopenharmony_ci
80962306a36Sopenharmony_ci	/* skip assoc data */
81062306a36Sopenharmony_ci	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_ci	/* read assoc data */
81362306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
81462306a36Sopenharmony_ci			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
81562306a36Sopenharmony_ci
81662306a36Sopenharmony_ci	set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
81762306a36Sopenharmony_ci
81862306a36Sopenharmony_ci	/* cryptlen = seqoutlen - assoclen */
81962306a36Sopenharmony_ci	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
82062306a36Sopenharmony_ci
82162306a36Sopenharmony_ci	/* jump to zero-payload command if cryptlen is zero */
82262306a36Sopenharmony_ci	zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
82362306a36Sopenharmony_ci					    JUMP_COND_MATH_Z);
82462306a36Sopenharmony_ci
82562306a36Sopenharmony_ci	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
82662306a36Sopenharmony_ci
82762306a36Sopenharmony_ci	/* store encrypted data */
82862306a36Sopenharmony_ci	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
82962306a36Sopenharmony_ci
83062306a36Sopenharmony_ci	/* read payload data */
83162306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
83262306a36Sopenharmony_ci			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_ci	/* zero-payload command */
83562306a36Sopenharmony_ci	set_jump_tgt_here(desc, zero_payload_jump_cmd);
83662306a36Sopenharmony_ci
83762306a36Sopenharmony_ci	/* read ICV */
83862306a36Sopenharmony_ci	append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
83962306a36Sopenharmony_ci			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
84062306a36Sopenharmony_ci
84162306a36Sopenharmony_ci	print_hex_dump_debug("gcm dec shdesc@" __stringify(__LINE__)": ",
84262306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
84362306a36Sopenharmony_ci			     1);
84462306a36Sopenharmony_ci}
84562306a36Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_gcm_decap);
84662306a36Sopenharmony_ci
84762306a36Sopenharmony_ci/**
84862306a36Sopenharmony_ci * cnstr_shdsc_rfc4106_encap - IPSec ESP gcm encapsulation shared descriptor
84962306a36Sopenharmony_ci *                             (non-protocol).
85062306a36Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction
85162306a36Sopenharmony_ci * @cdata: pointer to block cipher transform definitions
85262306a36Sopenharmony_ci *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
85362306a36Sopenharmony_ci * @ivsize: initialization vector size
85462306a36Sopenharmony_ci * @icvsize: integrity check value (ICV) size (truncated or full)
85562306a36Sopenharmony_ci * @is_qi: true when called from caam/qi
85662306a36Sopenharmony_ci *
85762306a36Sopenharmony_ci * Input sequence: AAD | PTXT
85862306a36Sopenharmony_ci * Output sequence: AAD | CTXT | ICV
85962306a36Sopenharmony_ci * AAD length (assoclen), which includes the IV length, is available in Math3.
86062306a36Sopenharmony_ci */
86162306a36Sopenharmony_civoid cnstr_shdsc_rfc4106_encap(u32 * const desc, struct alginfo *cdata,
86262306a36Sopenharmony_ci			       unsigned int ivsize, unsigned int icvsize,
86362306a36Sopenharmony_ci			       const bool is_qi)
86462306a36Sopenharmony_ci{
86562306a36Sopenharmony_ci	u32 *key_jump_cmd, *zero_cryptlen_jump_cmd, *skip_instructions;
86662306a36Sopenharmony_ci	init_sh_desc(desc, HDR_SHARE_SERIAL);
86762306a36Sopenharmony_ci
86862306a36Sopenharmony_ci	/* Skip key loading if it is loaded due to sharing */
86962306a36Sopenharmony_ci	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
87062306a36Sopenharmony_ci				   JUMP_COND_SHRD);
87162306a36Sopenharmony_ci	if (cdata->key_inline)
87262306a36Sopenharmony_ci		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
87362306a36Sopenharmony_ci				  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
87462306a36Sopenharmony_ci	else
87562306a36Sopenharmony_ci		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
87662306a36Sopenharmony_ci			   KEY_DEST_CLASS_REG);
87762306a36Sopenharmony_ci	set_jump_tgt_here(desc, key_jump_cmd);
87862306a36Sopenharmony_ci
87962306a36Sopenharmony_ci	/* Class 1 operation */
88062306a36Sopenharmony_ci	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
88162306a36Sopenharmony_ci			 OP_ALG_ENCRYPT);
88262306a36Sopenharmony_ci
88362306a36Sopenharmony_ci	if (is_qi) {
88462306a36Sopenharmony_ci		u32 *wait_load_cmd;
88562306a36Sopenharmony_ci
88662306a36Sopenharmony_ci		/* REG3 = assoclen */
88762306a36Sopenharmony_ci		append_seq_load(desc, 4, LDST_CLASS_DECO |
88862306a36Sopenharmony_ci				LDST_SRCDST_WORD_DECO_MATH3 |
88962306a36Sopenharmony_ci				(4 << LDST_OFFSET_SHIFT));
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_ci		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
89262306a36Sopenharmony_ci					    JUMP_COND_CALM | JUMP_COND_NCP |
89362306a36Sopenharmony_ci					    JUMP_COND_NOP | JUMP_COND_NIP |
89462306a36Sopenharmony_ci					    JUMP_COND_NIFP);
89562306a36Sopenharmony_ci		set_jump_tgt_here(desc, wait_load_cmd);
89662306a36Sopenharmony_ci
89762306a36Sopenharmony_ci		/* Read salt and IV */
89862306a36Sopenharmony_ci		append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
89962306a36Sopenharmony_ci					cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
90062306a36Sopenharmony_ci					FIFOLD_TYPE_IV);
90162306a36Sopenharmony_ci		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
90262306a36Sopenharmony_ci				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
90362306a36Sopenharmony_ci	}
90462306a36Sopenharmony_ci
90562306a36Sopenharmony_ci	append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, ivsize);
90662306a36Sopenharmony_ci	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
90762306a36Sopenharmony_ci
90862306a36Sopenharmony_ci	/* Skip AAD */
90962306a36Sopenharmony_ci	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
91062306a36Sopenharmony_ci
91162306a36Sopenharmony_ci	/* Read cryptlen and set this value into VARSEQOUTLEN */
91262306a36Sopenharmony_ci	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
91362306a36Sopenharmony_ci
91462306a36Sopenharmony_ci	/* If cryptlen is ZERO jump to AAD command */
91562306a36Sopenharmony_ci	zero_cryptlen_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
91662306a36Sopenharmony_ci					    JUMP_COND_MATH_Z);
91762306a36Sopenharmony_ci
91862306a36Sopenharmony_ci	/* Read AAD data */
91962306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
92062306a36Sopenharmony_ci			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
92162306a36Sopenharmony_ci
92262306a36Sopenharmony_ci	/* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
92362306a36Sopenharmony_ci	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA);
92462306a36Sopenharmony_ci
92562306a36Sopenharmony_ci	/* Skip IV */
92662306a36Sopenharmony_ci	append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_SKIP);
92762306a36Sopenharmony_ci	append_math_add(desc, VARSEQINLEN, VARSEQOUTLEN, REG0, CAAM_CMD_SZ);
92862306a36Sopenharmony_ci
92962306a36Sopenharmony_ci	/* Write encrypted data */
93062306a36Sopenharmony_ci	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
93162306a36Sopenharmony_ci
93262306a36Sopenharmony_ci	/* Read payload data */
93362306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
93462306a36Sopenharmony_ci			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
93562306a36Sopenharmony_ci
93662306a36Sopenharmony_ci	/* Jump instructions to avoid double reading of AAD */
93762306a36Sopenharmony_ci	skip_instructions = append_jump(desc, JUMP_TEST_ALL);
93862306a36Sopenharmony_ci
93962306a36Sopenharmony_ci	/* There is no input data, cryptlen = 0 */
94062306a36Sopenharmony_ci	set_jump_tgt_here(desc, zero_cryptlen_jump_cmd);
94162306a36Sopenharmony_ci
94262306a36Sopenharmony_ci	/* Read AAD */
94362306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
94462306a36Sopenharmony_ci			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
94562306a36Sopenharmony_ci
94662306a36Sopenharmony_ci	set_jump_tgt_here(desc, skip_instructions);
94762306a36Sopenharmony_ci
94862306a36Sopenharmony_ci	/* Write ICV */
94962306a36Sopenharmony_ci	append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
95062306a36Sopenharmony_ci			 LDST_SRCDST_BYTE_CONTEXT);
95162306a36Sopenharmony_ci
95262306a36Sopenharmony_ci	print_hex_dump_debug("rfc4106 enc shdesc@" __stringify(__LINE__)": ",
95362306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
95462306a36Sopenharmony_ci			     1);
95562306a36Sopenharmony_ci}
95662306a36Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_rfc4106_encap);
95762306a36Sopenharmony_ci
95862306a36Sopenharmony_ci/**
95962306a36Sopenharmony_ci * cnstr_shdsc_rfc4106_decap - IPSec ESP gcm decapsulation shared descriptor
96062306a36Sopenharmony_ci *                             (non-protocol).
96162306a36Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction
96262306a36Sopenharmony_ci * @cdata: pointer to block cipher transform definitions
96362306a36Sopenharmony_ci *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
96462306a36Sopenharmony_ci * @ivsize: initialization vector size
96562306a36Sopenharmony_ci * @icvsize: integrity check value (ICV) size (truncated or full)
96662306a36Sopenharmony_ci * @is_qi: true when called from caam/qi
96762306a36Sopenharmony_ci */
96862306a36Sopenharmony_civoid cnstr_shdsc_rfc4106_decap(u32 * const desc, struct alginfo *cdata,
96962306a36Sopenharmony_ci			       unsigned int ivsize, unsigned int icvsize,
97062306a36Sopenharmony_ci			       const bool is_qi)
97162306a36Sopenharmony_ci{
97262306a36Sopenharmony_ci	u32 *key_jump_cmd;
97362306a36Sopenharmony_ci
97462306a36Sopenharmony_ci	init_sh_desc(desc, HDR_SHARE_SERIAL);
97562306a36Sopenharmony_ci
97662306a36Sopenharmony_ci	/* Skip key loading if it is loaded due to sharing */
97762306a36Sopenharmony_ci	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
97862306a36Sopenharmony_ci				   JUMP_COND_SHRD);
97962306a36Sopenharmony_ci	if (cdata->key_inline)
98062306a36Sopenharmony_ci		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
98162306a36Sopenharmony_ci				  cdata->keylen, CLASS_1 |
98262306a36Sopenharmony_ci				  KEY_DEST_CLASS_REG);
98362306a36Sopenharmony_ci	else
98462306a36Sopenharmony_ci		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
98562306a36Sopenharmony_ci			   KEY_DEST_CLASS_REG);
98662306a36Sopenharmony_ci	set_jump_tgt_here(desc, key_jump_cmd);
98762306a36Sopenharmony_ci
98862306a36Sopenharmony_ci	/* Class 1 operation */
98962306a36Sopenharmony_ci	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
99062306a36Sopenharmony_ci			 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
99162306a36Sopenharmony_ci
99262306a36Sopenharmony_ci	if (is_qi) {
99362306a36Sopenharmony_ci		u32 *wait_load_cmd;
99462306a36Sopenharmony_ci
99562306a36Sopenharmony_ci		/* REG3 = assoclen */
99662306a36Sopenharmony_ci		append_seq_load(desc, 4, LDST_CLASS_DECO |
99762306a36Sopenharmony_ci				LDST_SRCDST_WORD_DECO_MATH3 |
99862306a36Sopenharmony_ci				(4 << LDST_OFFSET_SHIFT));
99962306a36Sopenharmony_ci
100062306a36Sopenharmony_ci		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
100162306a36Sopenharmony_ci					    JUMP_COND_CALM | JUMP_COND_NCP |
100262306a36Sopenharmony_ci					    JUMP_COND_NOP | JUMP_COND_NIP |
100362306a36Sopenharmony_ci					    JUMP_COND_NIFP);
100462306a36Sopenharmony_ci		set_jump_tgt_here(desc, wait_load_cmd);
100562306a36Sopenharmony_ci
100662306a36Sopenharmony_ci		/* Read salt and IV */
100762306a36Sopenharmony_ci		append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
100862306a36Sopenharmony_ci					cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
100962306a36Sopenharmony_ci					FIFOLD_TYPE_IV);
101062306a36Sopenharmony_ci		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
101162306a36Sopenharmony_ci				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
101262306a36Sopenharmony_ci	}
101362306a36Sopenharmony_ci
101462306a36Sopenharmony_ci	append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, ivsize);
101562306a36Sopenharmony_ci	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
101662306a36Sopenharmony_ci
101762306a36Sopenharmony_ci	/* Read assoc data */
101862306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
101962306a36Sopenharmony_ci			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
102062306a36Sopenharmony_ci
102162306a36Sopenharmony_ci	/* Skip IV */
102262306a36Sopenharmony_ci	append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_SKIP);
102362306a36Sopenharmony_ci
102462306a36Sopenharmony_ci	/* Will read cryptlen bytes */
102562306a36Sopenharmony_ci	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG3, CAAM_CMD_SZ);
102662306a36Sopenharmony_ci
102762306a36Sopenharmony_ci	/* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
102862306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG);
102962306a36Sopenharmony_ci
103062306a36Sopenharmony_ci	/* Skip assoc data */
103162306a36Sopenharmony_ci	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
103262306a36Sopenharmony_ci
103362306a36Sopenharmony_ci	/* Will write cryptlen bytes */
103462306a36Sopenharmony_ci	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
103562306a36Sopenharmony_ci
103662306a36Sopenharmony_ci	/* Store payload data */
103762306a36Sopenharmony_ci	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
103862306a36Sopenharmony_ci
103962306a36Sopenharmony_ci	/* Read encrypted data */
104062306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
104162306a36Sopenharmony_ci			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
104262306a36Sopenharmony_ci
104362306a36Sopenharmony_ci	/* Read ICV */
104462306a36Sopenharmony_ci	append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
104562306a36Sopenharmony_ci			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
104662306a36Sopenharmony_ci
104762306a36Sopenharmony_ci	print_hex_dump_debug("rfc4106 dec shdesc@" __stringify(__LINE__)": ",
104862306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
104962306a36Sopenharmony_ci			     1);
105062306a36Sopenharmony_ci}
105162306a36Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_rfc4106_decap);
105262306a36Sopenharmony_ci
105362306a36Sopenharmony_ci/**
105462306a36Sopenharmony_ci * cnstr_shdsc_rfc4543_encap - IPSec ESP gmac encapsulation shared descriptor
105562306a36Sopenharmony_ci *                             (non-protocol).
105662306a36Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction
105762306a36Sopenharmony_ci * @cdata: pointer to block cipher transform definitions
105862306a36Sopenharmony_ci *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
105962306a36Sopenharmony_ci * @ivsize: initialization vector size
106062306a36Sopenharmony_ci * @icvsize: integrity check value (ICV) size (truncated or full)
106162306a36Sopenharmony_ci * @is_qi: true when called from caam/qi
106262306a36Sopenharmony_ci */
106362306a36Sopenharmony_civoid cnstr_shdsc_rfc4543_encap(u32 * const desc, struct alginfo *cdata,
106462306a36Sopenharmony_ci			       unsigned int ivsize, unsigned int icvsize,
106562306a36Sopenharmony_ci			       const bool is_qi)
106662306a36Sopenharmony_ci{
106762306a36Sopenharmony_ci	u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
106862306a36Sopenharmony_ci
106962306a36Sopenharmony_ci	init_sh_desc(desc, HDR_SHARE_SERIAL);
107062306a36Sopenharmony_ci
107162306a36Sopenharmony_ci	/* Skip key loading if it is loaded due to sharing */
107262306a36Sopenharmony_ci	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
107362306a36Sopenharmony_ci				   JUMP_COND_SHRD);
107462306a36Sopenharmony_ci	if (cdata->key_inline)
107562306a36Sopenharmony_ci		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
107662306a36Sopenharmony_ci				  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
107762306a36Sopenharmony_ci	else
107862306a36Sopenharmony_ci		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
107962306a36Sopenharmony_ci			   KEY_DEST_CLASS_REG);
108062306a36Sopenharmony_ci	set_jump_tgt_here(desc, key_jump_cmd);
108162306a36Sopenharmony_ci
108262306a36Sopenharmony_ci	/* Class 1 operation */
108362306a36Sopenharmony_ci	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
108462306a36Sopenharmony_ci			 OP_ALG_ENCRYPT);
108562306a36Sopenharmony_ci
108662306a36Sopenharmony_ci	if (is_qi) {
108762306a36Sopenharmony_ci		/* assoclen is not needed, skip it */
108862306a36Sopenharmony_ci		append_seq_fifo_load(desc, 4, FIFOLD_CLASS_SKIP);
108962306a36Sopenharmony_ci
109062306a36Sopenharmony_ci		/* Read salt and IV */
109162306a36Sopenharmony_ci		append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
109262306a36Sopenharmony_ci					cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
109362306a36Sopenharmony_ci					FIFOLD_TYPE_IV);
109462306a36Sopenharmony_ci		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
109562306a36Sopenharmony_ci				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
109662306a36Sopenharmony_ci	}
109762306a36Sopenharmony_ci
109862306a36Sopenharmony_ci	/* assoclen + cryptlen = seqinlen */
109962306a36Sopenharmony_ci	append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
110062306a36Sopenharmony_ci
110162306a36Sopenharmony_ci	/*
110262306a36Sopenharmony_ci	 * MOVE_LEN opcode is not available in all SEC HW revisions,
110362306a36Sopenharmony_ci	 * thus need to do some magic, i.e. self-patch the descriptor
110462306a36Sopenharmony_ci	 * buffer.
110562306a36Sopenharmony_ci	 */
110662306a36Sopenharmony_ci	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
110762306a36Sopenharmony_ci				    (0x6 << MOVE_LEN_SHIFT));
110862306a36Sopenharmony_ci	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
110962306a36Sopenharmony_ci				     (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
111062306a36Sopenharmony_ci
111162306a36Sopenharmony_ci	/* Will read assoclen + cryptlen bytes */
111262306a36Sopenharmony_ci	append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
111362306a36Sopenharmony_ci
111462306a36Sopenharmony_ci	/* Will write assoclen + cryptlen bytes */
111562306a36Sopenharmony_ci	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
111662306a36Sopenharmony_ci
111762306a36Sopenharmony_ci	/* Read and write assoclen + cryptlen bytes */
111862306a36Sopenharmony_ci	aead_append_src_dst(desc, FIFOLD_TYPE_AAD);
111962306a36Sopenharmony_ci
112062306a36Sopenharmony_ci	set_move_tgt_here(desc, read_move_cmd);
112162306a36Sopenharmony_ci	set_move_tgt_here(desc, write_move_cmd);
112262306a36Sopenharmony_ci	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
112362306a36Sopenharmony_ci	/* Move payload data to OFIFO */
112462306a36Sopenharmony_ci	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
112562306a36Sopenharmony_ci
112662306a36Sopenharmony_ci	/* Write ICV */
112762306a36Sopenharmony_ci	append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
112862306a36Sopenharmony_ci			 LDST_SRCDST_BYTE_CONTEXT);
112962306a36Sopenharmony_ci
113062306a36Sopenharmony_ci	print_hex_dump_debug("rfc4543 enc shdesc@" __stringify(__LINE__)": ",
113162306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
113262306a36Sopenharmony_ci			     1);
113362306a36Sopenharmony_ci}
113462306a36Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_rfc4543_encap);
113562306a36Sopenharmony_ci
113662306a36Sopenharmony_ci/**
113762306a36Sopenharmony_ci * cnstr_shdsc_rfc4543_decap - IPSec ESP gmac decapsulation shared descriptor
113862306a36Sopenharmony_ci *                             (non-protocol).
113962306a36Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction
114062306a36Sopenharmony_ci * @cdata: pointer to block cipher transform definitions
114162306a36Sopenharmony_ci *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
114262306a36Sopenharmony_ci * @ivsize: initialization vector size
114362306a36Sopenharmony_ci * @icvsize: integrity check value (ICV) size (truncated or full)
114462306a36Sopenharmony_ci * @is_qi: true when called from caam/qi
114562306a36Sopenharmony_ci */
114662306a36Sopenharmony_civoid cnstr_shdsc_rfc4543_decap(u32 * const desc, struct alginfo *cdata,
114762306a36Sopenharmony_ci			       unsigned int ivsize, unsigned int icvsize,
114862306a36Sopenharmony_ci			       const bool is_qi)
114962306a36Sopenharmony_ci{
115062306a36Sopenharmony_ci	u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
115162306a36Sopenharmony_ci
115262306a36Sopenharmony_ci	init_sh_desc(desc, HDR_SHARE_SERIAL);
115362306a36Sopenharmony_ci
115462306a36Sopenharmony_ci	/* Skip key loading if it is loaded due to sharing */
115562306a36Sopenharmony_ci	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
115662306a36Sopenharmony_ci				   JUMP_COND_SHRD);
115762306a36Sopenharmony_ci	if (cdata->key_inline)
115862306a36Sopenharmony_ci		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
115962306a36Sopenharmony_ci				  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
116062306a36Sopenharmony_ci	else
116162306a36Sopenharmony_ci		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
116262306a36Sopenharmony_ci			   KEY_DEST_CLASS_REG);
116362306a36Sopenharmony_ci	set_jump_tgt_here(desc, key_jump_cmd);
116462306a36Sopenharmony_ci
116562306a36Sopenharmony_ci	/* Class 1 operation */
116662306a36Sopenharmony_ci	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
116762306a36Sopenharmony_ci			 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
116862306a36Sopenharmony_ci
116962306a36Sopenharmony_ci	if (is_qi) {
117062306a36Sopenharmony_ci		/* assoclen is not needed, skip it */
117162306a36Sopenharmony_ci		append_seq_fifo_load(desc, 4, FIFOLD_CLASS_SKIP);
117262306a36Sopenharmony_ci
117362306a36Sopenharmony_ci		/* Read salt and IV */
117462306a36Sopenharmony_ci		append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
117562306a36Sopenharmony_ci					cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
117662306a36Sopenharmony_ci					FIFOLD_TYPE_IV);
117762306a36Sopenharmony_ci		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
117862306a36Sopenharmony_ci				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
117962306a36Sopenharmony_ci	}
118062306a36Sopenharmony_ci
118162306a36Sopenharmony_ci	/* assoclen + cryptlen = seqoutlen */
118262306a36Sopenharmony_ci	append_math_sub(desc, REG3, SEQOUTLEN, REG0, CAAM_CMD_SZ);
118362306a36Sopenharmony_ci
118462306a36Sopenharmony_ci	/*
118562306a36Sopenharmony_ci	 * MOVE_LEN opcode is not available in all SEC HW revisions,
118662306a36Sopenharmony_ci	 * thus need to do some magic, i.e. self-patch the descriptor
118762306a36Sopenharmony_ci	 * buffer.
118862306a36Sopenharmony_ci	 */
118962306a36Sopenharmony_ci	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
119062306a36Sopenharmony_ci				    (0x6 << MOVE_LEN_SHIFT));
119162306a36Sopenharmony_ci	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
119262306a36Sopenharmony_ci				     (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
119362306a36Sopenharmony_ci
119462306a36Sopenharmony_ci	/* Will read assoclen + cryptlen bytes */
119562306a36Sopenharmony_ci	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
119662306a36Sopenharmony_ci
119762306a36Sopenharmony_ci	/* Will write assoclen + cryptlen bytes */
119862306a36Sopenharmony_ci	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
119962306a36Sopenharmony_ci
120062306a36Sopenharmony_ci	/* Store payload data */
120162306a36Sopenharmony_ci	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
120262306a36Sopenharmony_ci
120362306a36Sopenharmony_ci	/* In-snoop assoclen + cryptlen data */
120462306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | FIFOLDST_VLF |
120562306a36Sopenharmony_ci			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST2FLUSH1);
120662306a36Sopenharmony_ci
120762306a36Sopenharmony_ci	set_move_tgt_here(desc, read_move_cmd);
120862306a36Sopenharmony_ci	set_move_tgt_here(desc, write_move_cmd);
120962306a36Sopenharmony_ci	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
121062306a36Sopenharmony_ci	/* Move payload data to OFIFO */
121162306a36Sopenharmony_ci	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
121262306a36Sopenharmony_ci	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
121362306a36Sopenharmony_ci
121462306a36Sopenharmony_ci	/* Read ICV */
121562306a36Sopenharmony_ci	append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
121662306a36Sopenharmony_ci			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
121762306a36Sopenharmony_ci
121862306a36Sopenharmony_ci	print_hex_dump_debug("rfc4543 dec shdesc@" __stringify(__LINE__)": ",
121962306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
122062306a36Sopenharmony_ci			     1);
122162306a36Sopenharmony_ci}
122262306a36Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_rfc4543_decap);
122362306a36Sopenharmony_ci
122462306a36Sopenharmony_ci/**
122562306a36Sopenharmony_ci * cnstr_shdsc_chachapoly - Chacha20 + Poly1305 generic AEAD (rfc7539) and
122662306a36Sopenharmony_ci *                          IPsec ESP (rfc7634, a.k.a. rfc7539esp) shared
122762306a36Sopenharmony_ci *                          descriptor (non-protocol).
122862306a36Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction
122962306a36Sopenharmony_ci * @cdata: pointer to block cipher transform definitions
123062306a36Sopenharmony_ci *         Valid algorithm values - OP_ALG_ALGSEL_CHACHA20 ANDed with
123162306a36Sopenharmony_ci *         OP_ALG_AAI_AEAD.
123262306a36Sopenharmony_ci * @adata: pointer to authentication transform definitions
123362306a36Sopenharmony_ci *         Valid algorithm values - OP_ALG_ALGSEL_POLY1305 ANDed with
123462306a36Sopenharmony_ci *         OP_ALG_AAI_AEAD.
123562306a36Sopenharmony_ci * @ivsize: initialization vector size
123662306a36Sopenharmony_ci * @icvsize: integrity check value (ICV) size (truncated or full)
123762306a36Sopenharmony_ci * @encap: true if encapsulation, false if decapsulation
123862306a36Sopenharmony_ci * @is_qi: true when called from caam/qi
123962306a36Sopenharmony_ci */
124062306a36Sopenharmony_civoid cnstr_shdsc_chachapoly(u32 * const desc, struct alginfo *cdata,
124162306a36Sopenharmony_ci			    struct alginfo *adata, unsigned int ivsize,
124262306a36Sopenharmony_ci			    unsigned int icvsize, const bool encap,
124362306a36Sopenharmony_ci			    const bool is_qi)
124462306a36Sopenharmony_ci{
124562306a36Sopenharmony_ci	u32 *key_jump_cmd, *wait_cmd;
124662306a36Sopenharmony_ci	u32 nfifo;
124762306a36Sopenharmony_ci	const bool is_ipsec = (ivsize != CHACHAPOLY_IV_SIZE);
124862306a36Sopenharmony_ci
124962306a36Sopenharmony_ci	/* Note: Context registers are saved. */
125062306a36Sopenharmony_ci	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
125162306a36Sopenharmony_ci
125262306a36Sopenharmony_ci	/* skip key loading if they are loaded due to sharing */
125362306a36Sopenharmony_ci	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
125462306a36Sopenharmony_ci				   JUMP_COND_SHRD);
125562306a36Sopenharmony_ci
125662306a36Sopenharmony_ci	append_key_as_imm(desc, cdata->key_virt, cdata->keylen, cdata->keylen,
125762306a36Sopenharmony_ci			  CLASS_1 | KEY_DEST_CLASS_REG);
125862306a36Sopenharmony_ci
125962306a36Sopenharmony_ci	/* For IPsec load the salt from keymat in the context register */
126062306a36Sopenharmony_ci	if (is_ipsec)
126162306a36Sopenharmony_ci		append_load_as_imm(desc, cdata->key_virt + cdata->keylen, 4,
126262306a36Sopenharmony_ci				   LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT |
126362306a36Sopenharmony_ci				   4 << LDST_OFFSET_SHIFT);
126462306a36Sopenharmony_ci
126562306a36Sopenharmony_ci	set_jump_tgt_here(desc, key_jump_cmd);
126662306a36Sopenharmony_ci
126762306a36Sopenharmony_ci	/* Class 2 and 1 operations: Poly & ChaCha */
126862306a36Sopenharmony_ci	if (encap) {
126962306a36Sopenharmony_ci		append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
127062306a36Sopenharmony_ci				 OP_ALG_ENCRYPT);
127162306a36Sopenharmony_ci		append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
127262306a36Sopenharmony_ci				 OP_ALG_ENCRYPT);
127362306a36Sopenharmony_ci	} else {
127462306a36Sopenharmony_ci		append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
127562306a36Sopenharmony_ci				 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
127662306a36Sopenharmony_ci		append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
127762306a36Sopenharmony_ci				 OP_ALG_DECRYPT);
127862306a36Sopenharmony_ci	}
127962306a36Sopenharmony_ci
128062306a36Sopenharmony_ci	if (is_qi) {
128162306a36Sopenharmony_ci		u32 *wait_load_cmd;
128262306a36Sopenharmony_ci		u32 ctx1_iv_off = is_ipsec ? 8 : 4;
128362306a36Sopenharmony_ci
128462306a36Sopenharmony_ci		/* REG3 = assoclen */
128562306a36Sopenharmony_ci		append_seq_load(desc, 4, LDST_CLASS_DECO |
128662306a36Sopenharmony_ci				LDST_SRCDST_WORD_DECO_MATH3 |
128762306a36Sopenharmony_ci				4 << LDST_OFFSET_SHIFT);
128862306a36Sopenharmony_ci
128962306a36Sopenharmony_ci		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
129062306a36Sopenharmony_ci					    JUMP_COND_CALM | JUMP_COND_NCP |
129162306a36Sopenharmony_ci					    JUMP_COND_NOP | JUMP_COND_NIP |
129262306a36Sopenharmony_ci					    JUMP_COND_NIFP);
129362306a36Sopenharmony_ci		set_jump_tgt_here(desc, wait_load_cmd);
129462306a36Sopenharmony_ci
129562306a36Sopenharmony_ci		append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
129662306a36Sopenharmony_ci				LDST_SRCDST_BYTE_CONTEXT |
129762306a36Sopenharmony_ci				ctx1_iv_off << LDST_OFFSET_SHIFT);
129862306a36Sopenharmony_ci	}
129962306a36Sopenharmony_ci
130062306a36Sopenharmony_ci	/*
130162306a36Sopenharmony_ci	 * MAGIC with NFIFO
130262306a36Sopenharmony_ci	 * Read associated data from the input and send them to class1 and
130362306a36Sopenharmony_ci	 * class2 alignment blocks. From class1 send data to output fifo and
130462306a36Sopenharmony_ci	 * then write it to memory since we don't need to encrypt AD.
130562306a36Sopenharmony_ci	 */
130662306a36Sopenharmony_ci	nfifo = NFIFOENTRY_DEST_BOTH | NFIFOENTRY_FC1 | NFIFOENTRY_FC2 |
130762306a36Sopenharmony_ci		NFIFOENTRY_DTYPE_POLY | NFIFOENTRY_BND;
130862306a36Sopenharmony_ci	append_load_imm_u32(desc, nfifo, LDST_CLASS_IND_CCB |
130962306a36Sopenharmony_ci			    LDST_SRCDST_WORD_INFO_FIFO_SM | LDLEN_MATH3);
131062306a36Sopenharmony_ci
131162306a36Sopenharmony_ci	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
131262306a36Sopenharmony_ci	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
131362306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_TYPE_NOINFOFIFO |
131462306a36Sopenharmony_ci			     FIFOLD_CLASS_CLASS1 | LDST_VLF);
131562306a36Sopenharmony_ci	append_move_len(desc, MOVE_AUX_LS | MOVE_SRC_AUX_ABLK |
131662306a36Sopenharmony_ci			MOVE_DEST_OUTFIFO | MOVELEN_MRSEL_MATH3);
131762306a36Sopenharmony_ci	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | LDST_VLF);
131862306a36Sopenharmony_ci
131962306a36Sopenharmony_ci	/* IPsec - copy IV at the output */
132062306a36Sopenharmony_ci	if (is_ipsec)
132162306a36Sopenharmony_ci		append_seq_fifo_store(desc, ivsize, FIFOST_TYPE_METADATA |
132262306a36Sopenharmony_ci				      0x2 << 25);
132362306a36Sopenharmony_ci
132462306a36Sopenharmony_ci	wait_cmd = append_jump(desc, JUMP_JSL | JUMP_TYPE_LOCAL |
132562306a36Sopenharmony_ci			       JUMP_COND_NOP | JUMP_TEST_ALL);
132662306a36Sopenharmony_ci	set_jump_tgt_here(desc, wait_cmd);
132762306a36Sopenharmony_ci
132862306a36Sopenharmony_ci	if (encap) {
132962306a36Sopenharmony_ci		/* Read and write cryptlen bytes */
133062306a36Sopenharmony_ci		append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
133162306a36Sopenharmony_ci		append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0,
133262306a36Sopenharmony_ci				CAAM_CMD_SZ);
133362306a36Sopenharmony_ci		aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
133462306a36Sopenharmony_ci
133562306a36Sopenharmony_ci		/* Write ICV */
133662306a36Sopenharmony_ci		append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
133762306a36Sopenharmony_ci				 LDST_SRCDST_BYTE_CONTEXT);
133862306a36Sopenharmony_ci	} else {
133962306a36Sopenharmony_ci		/* Read and write cryptlen bytes */
134062306a36Sopenharmony_ci		append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0,
134162306a36Sopenharmony_ci				CAAM_CMD_SZ);
134262306a36Sopenharmony_ci		append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0,
134362306a36Sopenharmony_ci				CAAM_CMD_SZ);
134462306a36Sopenharmony_ci		aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
134562306a36Sopenharmony_ci
134662306a36Sopenharmony_ci		/* Load ICV for verification */
134762306a36Sopenharmony_ci		append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
134862306a36Sopenharmony_ci				     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
134962306a36Sopenharmony_ci	}
135062306a36Sopenharmony_ci
135162306a36Sopenharmony_ci	print_hex_dump_debug("chachapoly shdesc@" __stringify(__LINE__)": ",
135262306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
135362306a36Sopenharmony_ci			     1);
135462306a36Sopenharmony_ci}
135562306a36Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_chachapoly);
135662306a36Sopenharmony_ci
135762306a36Sopenharmony_ci/* For skcipher encrypt and decrypt, read from req->src and write to req->dst */
135862306a36Sopenharmony_cistatic inline void skcipher_append_src_dst(u32 *desc)
135962306a36Sopenharmony_ci{
136062306a36Sopenharmony_ci	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
136162306a36Sopenharmony_ci	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
136262306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 |
136362306a36Sopenharmony_ci			     KEY_VLF | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
136462306a36Sopenharmony_ci	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
136562306a36Sopenharmony_ci}
136662306a36Sopenharmony_ci
136762306a36Sopenharmony_ci/**
136862306a36Sopenharmony_ci * cnstr_shdsc_skcipher_encap - skcipher encapsulation shared descriptor
136962306a36Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction
137062306a36Sopenharmony_ci * @cdata: pointer to block cipher transform definitions
137162306a36Sopenharmony_ci *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
137262306a36Sopenharmony_ci *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128
137362306a36Sopenharmony_ci *                                - OP_ALG_ALGSEL_CHACHA20
137462306a36Sopenharmony_ci * @ivsize: initialization vector size
137562306a36Sopenharmony_ci * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
137662306a36Sopenharmony_ci * @ctx1_iv_off: IV offset in CONTEXT1 register
137762306a36Sopenharmony_ci */
137862306a36Sopenharmony_civoid cnstr_shdsc_skcipher_encap(u32 * const desc, struct alginfo *cdata,
137962306a36Sopenharmony_ci				unsigned int ivsize, const bool is_rfc3686,
138062306a36Sopenharmony_ci				const u32 ctx1_iv_off)
138162306a36Sopenharmony_ci{
138262306a36Sopenharmony_ci	u32 *key_jump_cmd;
138362306a36Sopenharmony_ci	u32 options = cdata->algtype | OP_ALG_AS_INIT | OP_ALG_ENCRYPT;
138462306a36Sopenharmony_ci	bool is_chacha20 = ((cdata->algtype & OP_ALG_ALGSEL_MASK) ==
138562306a36Sopenharmony_ci			    OP_ALG_ALGSEL_CHACHA20);
138662306a36Sopenharmony_ci
138762306a36Sopenharmony_ci	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
138862306a36Sopenharmony_ci	/* Skip if already shared */
138962306a36Sopenharmony_ci	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
139062306a36Sopenharmony_ci				   JUMP_COND_SHRD);
139162306a36Sopenharmony_ci
139262306a36Sopenharmony_ci	/* Load class1 key only */
139362306a36Sopenharmony_ci	append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
139462306a36Sopenharmony_ci			  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
139562306a36Sopenharmony_ci
139662306a36Sopenharmony_ci	/* Load nonce into CONTEXT1 reg */
139762306a36Sopenharmony_ci	if (is_rfc3686) {
139862306a36Sopenharmony_ci		const u8 *nonce = cdata->key_virt + cdata->keylen;
139962306a36Sopenharmony_ci
140062306a36Sopenharmony_ci		append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
140162306a36Sopenharmony_ci				   LDST_CLASS_IND_CCB |
140262306a36Sopenharmony_ci				   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
140362306a36Sopenharmony_ci		append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
140462306a36Sopenharmony_ci			    MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
140562306a36Sopenharmony_ci			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
140662306a36Sopenharmony_ci	}
140762306a36Sopenharmony_ci
140862306a36Sopenharmony_ci	set_jump_tgt_here(desc, key_jump_cmd);
140962306a36Sopenharmony_ci
141062306a36Sopenharmony_ci	/* Load IV, if there is one */
141162306a36Sopenharmony_ci	if (ivsize)
141262306a36Sopenharmony_ci		append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
141362306a36Sopenharmony_ci				LDST_CLASS_1_CCB | (ctx1_iv_off <<
141462306a36Sopenharmony_ci				LDST_OFFSET_SHIFT));
141562306a36Sopenharmony_ci
141662306a36Sopenharmony_ci	/* Load counter into CONTEXT1 reg */
141762306a36Sopenharmony_ci	if (is_rfc3686)
141862306a36Sopenharmony_ci		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
141962306a36Sopenharmony_ci				     LDST_SRCDST_BYTE_CONTEXT |
142062306a36Sopenharmony_ci				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
142162306a36Sopenharmony_ci				      LDST_OFFSET_SHIFT));
142262306a36Sopenharmony_ci
142362306a36Sopenharmony_ci	/* Load operation */
142462306a36Sopenharmony_ci	if (is_chacha20)
142562306a36Sopenharmony_ci		options |= OP_ALG_AS_FINALIZE;
142662306a36Sopenharmony_ci	append_operation(desc, options);
142762306a36Sopenharmony_ci
142862306a36Sopenharmony_ci	/* Perform operation */
142962306a36Sopenharmony_ci	skcipher_append_src_dst(desc);
143062306a36Sopenharmony_ci
143162306a36Sopenharmony_ci	/* Store IV */
143262306a36Sopenharmony_ci	if (!is_chacha20 && ivsize)
143362306a36Sopenharmony_ci		append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
143462306a36Sopenharmony_ci				 LDST_CLASS_1_CCB | (ctx1_iv_off <<
143562306a36Sopenharmony_ci				 LDST_OFFSET_SHIFT));
143662306a36Sopenharmony_ci
143762306a36Sopenharmony_ci	print_hex_dump_debug("skcipher enc shdesc@" __stringify(__LINE__)": ",
143862306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
143962306a36Sopenharmony_ci			     1);
144062306a36Sopenharmony_ci}
144162306a36Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_skcipher_encap);
144262306a36Sopenharmony_ci
144362306a36Sopenharmony_ci/**
144462306a36Sopenharmony_ci * cnstr_shdsc_skcipher_decap - skcipher decapsulation shared descriptor
144562306a36Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction
144662306a36Sopenharmony_ci * @cdata: pointer to block cipher transform definitions
144762306a36Sopenharmony_ci *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
144862306a36Sopenharmony_ci *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128
144962306a36Sopenharmony_ci *                                - OP_ALG_ALGSEL_CHACHA20
145062306a36Sopenharmony_ci * @ivsize: initialization vector size
145162306a36Sopenharmony_ci * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
145262306a36Sopenharmony_ci * @ctx1_iv_off: IV offset in CONTEXT1 register
145362306a36Sopenharmony_ci */
145462306a36Sopenharmony_civoid cnstr_shdsc_skcipher_decap(u32 * const desc, struct alginfo *cdata,
145562306a36Sopenharmony_ci				unsigned int ivsize, const bool is_rfc3686,
145662306a36Sopenharmony_ci				const u32 ctx1_iv_off)
145762306a36Sopenharmony_ci{
145862306a36Sopenharmony_ci	u32 *key_jump_cmd;
145962306a36Sopenharmony_ci	bool is_chacha20 = ((cdata->algtype & OP_ALG_ALGSEL_MASK) ==
146062306a36Sopenharmony_ci			    OP_ALG_ALGSEL_CHACHA20);
146162306a36Sopenharmony_ci
146262306a36Sopenharmony_ci	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
146362306a36Sopenharmony_ci	/* Skip if already shared */
146462306a36Sopenharmony_ci	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
146562306a36Sopenharmony_ci				   JUMP_COND_SHRD);
146662306a36Sopenharmony_ci
146762306a36Sopenharmony_ci	/* Load class1 key only */
146862306a36Sopenharmony_ci	append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
146962306a36Sopenharmony_ci			  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
147062306a36Sopenharmony_ci
147162306a36Sopenharmony_ci	/* Load nonce into CONTEXT1 reg */
147262306a36Sopenharmony_ci	if (is_rfc3686) {
147362306a36Sopenharmony_ci		const u8 *nonce = cdata->key_virt + cdata->keylen;
147462306a36Sopenharmony_ci
147562306a36Sopenharmony_ci		append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
147662306a36Sopenharmony_ci				   LDST_CLASS_IND_CCB |
147762306a36Sopenharmony_ci				   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
147862306a36Sopenharmony_ci		append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
147962306a36Sopenharmony_ci			    MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
148062306a36Sopenharmony_ci			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
148162306a36Sopenharmony_ci	}
148262306a36Sopenharmony_ci
148362306a36Sopenharmony_ci	set_jump_tgt_here(desc, key_jump_cmd);
148462306a36Sopenharmony_ci
148562306a36Sopenharmony_ci	/* Load IV, if there is one */
148662306a36Sopenharmony_ci	if (ivsize)
148762306a36Sopenharmony_ci		append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
148862306a36Sopenharmony_ci				LDST_CLASS_1_CCB | (ctx1_iv_off <<
148962306a36Sopenharmony_ci				LDST_OFFSET_SHIFT));
149062306a36Sopenharmony_ci
149162306a36Sopenharmony_ci	/* Load counter into CONTEXT1 reg */
149262306a36Sopenharmony_ci	if (is_rfc3686)
149362306a36Sopenharmony_ci		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
149462306a36Sopenharmony_ci				     LDST_SRCDST_BYTE_CONTEXT |
149562306a36Sopenharmony_ci				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
149662306a36Sopenharmony_ci				      LDST_OFFSET_SHIFT));
149762306a36Sopenharmony_ci
149862306a36Sopenharmony_ci	/* Choose operation */
149962306a36Sopenharmony_ci	if (ctx1_iv_off)
150062306a36Sopenharmony_ci		append_operation(desc, cdata->algtype | OP_ALG_AS_INIT |
150162306a36Sopenharmony_ci				 OP_ALG_DECRYPT);
150262306a36Sopenharmony_ci	else
150362306a36Sopenharmony_ci		append_dec_op1(desc, cdata->algtype);
150462306a36Sopenharmony_ci
150562306a36Sopenharmony_ci	/* Perform operation */
150662306a36Sopenharmony_ci	skcipher_append_src_dst(desc);
150762306a36Sopenharmony_ci
150862306a36Sopenharmony_ci	/* Store IV */
150962306a36Sopenharmony_ci	if (!is_chacha20 && ivsize)
151062306a36Sopenharmony_ci		append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
151162306a36Sopenharmony_ci				 LDST_CLASS_1_CCB | (ctx1_iv_off <<
151262306a36Sopenharmony_ci				 LDST_OFFSET_SHIFT));
151362306a36Sopenharmony_ci
151462306a36Sopenharmony_ci	print_hex_dump_debug("skcipher dec shdesc@" __stringify(__LINE__)": ",
151562306a36Sopenharmony_ci			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
151662306a36Sopenharmony_ci			     1);
151762306a36Sopenharmony_ci}
151862306a36Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_skcipher_decap);
151962306a36Sopenharmony_ci
152062306a36Sopenharmony_ci/**
152162306a36Sopenharmony_ci * cnstr_shdsc_xts_skcipher_encap - xts skcipher encapsulation shared descriptor
152262306a36Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction
152362306a36Sopenharmony_ci * @cdata: pointer to block cipher transform definitions
152462306a36Sopenharmony_ci *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_XTS.
152562306a36Sopenharmony_ci */
152662306a36Sopenharmony_civoid cnstr_shdsc_xts_skcipher_encap(u32 * const desc, struct alginfo *cdata)
152762306a36Sopenharmony_ci{
152862306a36Sopenharmony_ci	/*
152962306a36Sopenharmony_ci	 * Set sector size to a big value, practically disabling
153062306a36Sopenharmony_ci	 * sector size segmentation in xts implementation. We cannot
153162306a36Sopenharmony_ci	 * take full advantage of this HW feature with existing
153262306a36Sopenharmony_ci	 * crypto API / dm-crypt SW architecture.
153362306a36Sopenharmony_ci	 */
153462306a36Sopenharmony_ci	__be64 sector_size = cpu_to_be64(BIT(15));
153562306a36Sopenharmony_ci	u32 *key_jump_cmd;
153662306a36Sopenharmony_ci
153762306a36Sopenharmony_ci	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
153862306a36Sopenharmony_ci	/* Skip if already shared */
153962306a36Sopenharmony_ci	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
154062306a36Sopenharmony_ci				   JUMP_COND_SHRD);
154162306a36Sopenharmony_ci
154262306a36Sopenharmony_ci	/* Load class1 keys only */
154362306a36Sopenharmony_ci	append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
154462306a36Sopenharmony_ci			  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
154562306a36Sopenharmony_ci
154662306a36Sopenharmony_ci	/* Load sector size with index 40 bytes (0x28) */
154762306a36Sopenharmony_ci	append_load_as_imm(desc, (void *)&sector_size, 8, LDST_CLASS_1_CCB |
154862306a36Sopenharmony_ci			   LDST_SRCDST_BYTE_CONTEXT |
154962306a36Sopenharmony_ci			   (0x28 << LDST_OFFSET_SHIFT));
155062306a36Sopenharmony_ci
155162306a36Sopenharmony_ci	set_jump_tgt_here(desc, key_jump_cmd);
155262306a36Sopenharmony_ci
155362306a36Sopenharmony_ci	/*
155462306a36Sopenharmony_ci	 * create sequence for loading the sector index / 16B tweak value
155562306a36Sopenharmony_ci	 * Lower 8B of IV - sector index / tweak lower half
155662306a36Sopenharmony_ci	 * Upper 8B of IV - upper half of 16B tweak
155762306a36Sopenharmony_ci	 */
155862306a36Sopenharmony_ci	append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
155962306a36Sopenharmony_ci			(0x20 << LDST_OFFSET_SHIFT));
156062306a36Sopenharmony_ci	append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
156162306a36Sopenharmony_ci			(0x30 << LDST_OFFSET_SHIFT));
156262306a36Sopenharmony_ci
156362306a36Sopenharmony_ci	/* Load operation */
156462306a36Sopenharmony_ci	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
156562306a36Sopenharmony_ci			 OP_ALG_ENCRYPT);
156662306a36Sopenharmony_ci
156762306a36Sopenharmony_ci	/* Perform operation */
156862306a36Sopenharmony_ci	skcipher_append_src_dst(desc);
156962306a36Sopenharmony_ci
157062306a36Sopenharmony_ci	/* Store lower 8B and upper 8B of IV */
157162306a36Sopenharmony_ci	append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
157262306a36Sopenharmony_ci			 (0x20 << LDST_OFFSET_SHIFT));
157362306a36Sopenharmony_ci	append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
157462306a36Sopenharmony_ci			 (0x30 << LDST_OFFSET_SHIFT));
157562306a36Sopenharmony_ci
157662306a36Sopenharmony_ci	print_hex_dump_debug("xts skcipher enc shdesc@" __stringify(__LINE__)
157762306a36Sopenharmony_ci			     ": ", DUMP_PREFIX_ADDRESS, 16, 4,
157862306a36Sopenharmony_ci			     desc, desc_bytes(desc), 1);
157962306a36Sopenharmony_ci}
158062306a36Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_xts_skcipher_encap);
158162306a36Sopenharmony_ci
158262306a36Sopenharmony_ci/**
158362306a36Sopenharmony_ci * cnstr_shdsc_xts_skcipher_decap - xts skcipher decapsulation shared descriptor
158462306a36Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction
158562306a36Sopenharmony_ci * @cdata: pointer to block cipher transform definitions
158662306a36Sopenharmony_ci *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_XTS.
158762306a36Sopenharmony_ci */
158862306a36Sopenharmony_civoid cnstr_shdsc_xts_skcipher_decap(u32 * const desc, struct alginfo *cdata)
158962306a36Sopenharmony_ci{
159062306a36Sopenharmony_ci	/*
159162306a36Sopenharmony_ci	 * Set sector size to a big value, practically disabling
159262306a36Sopenharmony_ci	 * sector size segmentation in xts implementation. We cannot
159362306a36Sopenharmony_ci	 * take full advantage of this HW feature with existing
159462306a36Sopenharmony_ci	 * crypto API / dm-crypt SW architecture.
159562306a36Sopenharmony_ci	 */
159662306a36Sopenharmony_ci	__be64 sector_size = cpu_to_be64(BIT(15));
159762306a36Sopenharmony_ci	u32 *key_jump_cmd;
159862306a36Sopenharmony_ci
159962306a36Sopenharmony_ci	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
160062306a36Sopenharmony_ci	/* Skip if already shared */
160162306a36Sopenharmony_ci	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
160262306a36Sopenharmony_ci				   JUMP_COND_SHRD);
160362306a36Sopenharmony_ci
160462306a36Sopenharmony_ci	/* Load class1 key only */
160562306a36Sopenharmony_ci	append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
160662306a36Sopenharmony_ci			  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
160762306a36Sopenharmony_ci
160862306a36Sopenharmony_ci	/* Load sector size with index 40 bytes (0x28) */
160962306a36Sopenharmony_ci	append_load_as_imm(desc, (void *)&sector_size, 8, LDST_CLASS_1_CCB |
161062306a36Sopenharmony_ci			   LDST_SRCDST_BYTE_CONTEXT |
161162306a36Sopenharmony_ci			   (0x28 << LDST_OFFSET_SHIFT));
161262306a36Sopenharmony_ci
161362306a36Sopenharmony_ci	set_jump_tgt_here(desc, key_jump_cmd);
161462306a36Sopenharmony_ci
161562306a36Sopenharmony_ci	/*
161662306a36Sopenharmony_ci	 * create sequence for loading the sector index / 16B tweak value
161762306a36Sopenharmony_ci	 * Lower 8B of IV - sector index / tweak lower half
161862306a36Sopenharmony_ci	 * Upper 8B of IV - upper half of 16B tweak
161962306a36Sopenharmony_ci	 */
162062306a36Sopenharmony_ci	append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
162162306a36Sopenharmony_ci			(0x20 << LDST_OFFSET_SHIFT));
162262306a36Sopenharmony_ci	append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
162362306a36Sopenharmony_ci			(0x30 << LDST_OFFSET_SHIFT));
162462306a36Sopenharmony_ci	/* Load operation */
162562306a36Sopenharmony_ci	append_dec_op1(desc, cdata->algtype);
162662306a36Sopenharmony_ci
162762306a36Sopenharmony_ci	/* Perform operation */
162862306a36Sopenharmony_ci	skcipher_append_src_dst(desc);
162962306a36Sopenharmony_ci
163062306a36Sopenharmony_ci	/* Store lower 8B and upper 8B of IV */
163162306a36Sopenharmony_ci	append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
163262306a36Sopenharmony_ci			 (0x20 << LDST_OFFSET_SHIFT));
163362306a36Sopenharmony_ci	append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
163462306a36Sopenharmony_ci			 (0x30 << LDST_OFFSET_SHIFT));
163562306a36Sopenharmony_ci
163662306a36Sopenharmony_ci	print_hex_dump_debug("xts skcipher dec shdesc@" __stringify(__LINE__)
163762306a36Sopenharmony_ci			     ": ", DUMP_PREFIX_ADDRESS, 16, 4, desc,
163862306a36Sopenharmony_ci			     desc_bytes(desc), 1);
163962306a36Sopenharmony_ci}
164062306a36Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_xts_skcipher_decap);
164162306a36Sopenharmony_ci
164262306a36Sopenharmony_ciMODULE_LICENSE("GPL");
164362306a36Sopenharmony_ciMODULE_DESCRIPTION("FSL CAAM descriptor support");
164462306a36Sopenharmony_ciMODULE_AUTHOR("Freescale Semiconductor - NMG/STC");
1645