Linux Audio

Check our new training course

Loading...
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Shared descriptors for aead, skcipher algorithms
   4 *
   5 * Copyright 2016-2019 NXP
   6 */
   7
   8#include "compat.h"
   9#include "desc_constr.h"
  10#include "caamalg_desc.h"
  11
  12/*
  13 * For aead functions, read payload and write payload,
  14 * both of which are specified in req->src and req->dst
  15 */
  16static inline void aead_append_src_dst(u32 *desc, u32 msg_type)
  17{
  18	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
  19	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH |
  20			     KEY_VLF | msg_type | FIFOLD_TYPE_LASTBOTH);
  21}
  22
  23/* Set DK bit in class 1 operation if shared */
  24static inline void append_dec_op1(u32 *desc, u32 type)
  25{
  26	u32 *jump_cmd, *uncond_jump_cmd;
  27
  28	/* DK bit is valid only for AES */
  29	if ((type & OP_ALG_ALGSEL_MASK) != OP_ALG_ALGSEL_AES) {
  30		append_operation(desc, type | OP_ALG_AS_INITFINAL |
  31				 OP_ALG_DECRYPT);
  32		return;
  33	}
  34
  35	jump_cmd = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
  36	append_operation(desc, type | OP_ALG_AS_INIT | OP_ALG_DECRYPT);
  37	uncond_jump_cmd = append_jump(desc, JUMP_TEST_ALL);
  38	set_jump_tgt_here(desc, jump_cmd);
  39	append_operation(desc, type | OP_ALG_AS_INIT | OP_ALG_DECRYPT |
  40			 OP_ALG_AAI_DK);
  41	set_jump_tgt_here(desc, uncond_jump_cmd);
  42}
  43
  44/**
  45 * cnstr_shdsc_aead_null_encap - IPSec ESP encapsulation shared descriptor
  46 *                               (non-protocol) with no (null) encryption.
  47 * @desc: pointer to buffer used for descriptor construction
  48 * @adata: pointer to authentication transform definitions.
  49 *         A split key is required for SEC Era < 6; the size of the split key
  50 *         is specified in this case. Valid algorithm values - one of
  51 *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
  52 *         with OP_ALG_AAI_HMAC_PRECOMP.
  53 * @icvsize: integrity check value (ICV) size (truncated or full)
  54 * @era: SEC Era
  55 */
  56void cnstr_shdsc_aead_null_encap(u32 * const desc, struct alginfo *adata,
  57				 unsigned int icvsize, int era)
  58{
  59	u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
  60
  61	init_sh_desc(desc, HDR_SHARE_SERIAL);
  62
  63	/* Skip if already shared */
  64	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
  65				   JUMP_COND_SHRD);
  66	if (era < 6) {
  67		if (adata->key_inline)
  68			append_key_as_imm(desc, adata->key_virt,
  69					  adata->keylen_pad, adata->keylen,
  70					  CLASS_2 | KEY_DEST_MDHA_SPLIT |
  71					  KEY_ENC);
  72		else
  73			append_key(desc, adata->key_dma, adata->keylen,
  74				   CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
  75	} else {
  76		append_proto_dkp(desc, adata);
  77	}
  78	set_jump_tgt_here(desc, key_jump_cmd);
  79
  80	/* assoclen + cryptlen = seqinlen */
  81	append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
  82
  83	/* Prepare to read and write cryptlen + assoclen bytes */
  84	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
  85	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
  86
  87	/*
  88	 * MOVE_LEN opcode is not available in all SEC HW revisions,
  89	 * thus need to do some magic, i.e. self-patch the descriptor
  90	 * buffer.
  91	 */
  92	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
  93				    MOVE_DEST_MATH3 |
  94				    (0x6 << MOVE_LEN_SHIFT));
  95	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 |
  96				     MOVE_DEST_DESCBUF |
  97				     MOVE_WAITCOMP |
  98				     (0x8 << MOVE_LEN_SHIFT));
  99
 100	/* Class 2 operation */
 101	append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
 102			 OP_ALG_ENCRYPT);
 103
 104	/* Read and write cryptlen bytes */
 105	aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
 106
 107	set_move_tgt_here(desc, read_move_cmd);
 108	set_move_tgt_here(desc, write_move_cmd);
 109	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
 110	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
 111		    MOVE_AUX_LS);
 112
 113	/* Write ICV */
 114	append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
 115			 LDST_SRCDST_BYTE_CONTEXT);
 116
 117	print_hex_dump_debug("aead null enc shdesc@" __stringify(__LINE__)": ",
 118			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
 119			     1);
 120}
 121EXPORT_SYMBOL(cnstr_shdsc_aead_null_encap);
 122
 123/**
 124 * cnstr_shdsc_aead_null_decap - IPSec ESP decapsulation shared descriptor
 125 *                               (non-protocol) with no (null) decryption.
 126 * @desc: pointer to buffer used for descriptor construction
 127 * @adata: pointer to authentication transform definitions.
 128 *         A split key is required for SEC Era < 6; the size of the split key
 129 *         is specified in this case. Valid algorithm values - one of
 130 *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
 131 *         with OP_ALG_AAI_HMAC_PRECOMP.
 132 * @icvsize: integrity check value (ICV) size (truncated or full)
 133 * @era: SEC Era
 134 */
 135void cnstr_shdsc_aead_null_decap(u32 * const desc, struct alginfo *adata,
 136				 unsigned int icvsize, int era)
 137{
 138	u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd, *jump_cmd;
 139
 140	init_sh_desc(desc, HDR_SHARE_SERIAL);
 141
 142	/* Skip if already shared */
 143	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
 144				   JUMP_COND_SHRD);
 145	if (era < 6) {
 146		if (adata->key_inline)
 147			append_key_as_imm(desc, adata->key_virt,
 148					  adata->keylen_pad, adata->keylen,
 149					  CLASS_2 | KEY_DEST_MDHA_SPLIT |
 150					  KEY_ENC);
 151		else
 152			append_key(desc, adata->key_dma, adata->keylen,
 153				   CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
 154	} else {
 155		append_proto_dkp(desc, adata);
 156	}
 157	set_jump_tgt_here(desc, key_jump_cmd);
 158
 159	/* Class 2 operation */
 160	append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
 161			 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
 162
 163	/* assoclen + cryptlen = seqoutlen */
 164	append_math_sub(desc, REG2, SEQOUTLEN, REG0, CAAM_CMD_SZ);
 165
 166	/* Prepare to read and write cryptlen + assoclen bytes */
 167	append_math_add(desc, VARSEQINLEN, ZERO, REG2, CAAM_CMD_SZ);
 168	append_math_add(desc, VARSEQOUTLEN, ZERO, REG2, CAAM_CMD_SZ);
 169
 170	/*
 171	 * MOVE_LEN opcode is not available in all SEC HW revisions,
 172	 * thus need to do some magic, i.e. self-patch the descriptor
 173	 * buffer.
 174	 */
 175	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF |
 176				    MOVE_DEST_MATH2 |
 177				    (0x6 << MOVE_LEN_SHIFT));
 178	write_move_cmd = append_move(desc, MOVE_SRC_MATH2 |
 179				     MOVE_DEST_DESCBUF |
 180				     MOVE_WAITCOMP |
 181				     (0x8 << MOVE_LEN_SHIFT));
 182
 183	/* Read and write cryptlen bytes */
 184	aead_append_src_dst(desc, FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
 185
 186	/*
 187	 * Insert a NOP here, since we need at least 4 instructions between
 188	 * code patching the descriptor buffer and the location being patched.
 189	 */
 190	jump_cmd = append_jump(desc, JUMP_TEST_ALL);
 191	set_jump_tgt_here(desc, jump_cmd);
 192
 193	set_move_tgt_here(desc, read_move_cmd);
 194	set_move_tgt_here(desc, write_move_cmd);
 195	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
 196	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO |
 197		    MOVE_AUX_LS);
 198	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
 199
 200	/* Load ICV */
 201	append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
 202			     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
 203
 204	print_hex_dump_debug("aead null dec shdesc@" __stringify(__LINE__)": ",
 205			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
 206			     1);
 207}
 208EXPORT_SYMBOL(cnstr_shdsc_aead_null_decap);
 209
 210static void init_sh_desc_key_aead(u32 * const desc,
 211				  struct alginfo * const cdata,
 212				  struct alginfo * const adata,
 213				  const bool is_rfc3686, u32 *nonce, int era)
 214{
 215	u32 *key_jump_cmd;
 216	unsigned int enckeylen = cdata->keylen;
 217
 218	/* Note: Context registers are saved. */
 219	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
 220
 221	/* Skip if already shared */
 222	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
 223				   JUMP_COND_SHRD);
 224
 225	/*
 226	 * RFC3686 specific:
 227	 *	| key = {AUTH_KEY, ENC_KEY, NONCE}
 228	 *	| enckeylen = encryption key size + nonce size
 229	 */
 230	if (is_rfc3686)
 231		enckeylen -= CTR_RFC3686_NONCE_SIZE;
 232
 233	if (era < 6) {
 234		if (adata->key_inline)
 235			append_key_as_imm(desc, adata->key_virt,
 236					  adata->keylen_pad, adata->keylen,
 237					  CLASS_2 | KEY_DEST_MDHA_SPLIT |
 238					  KEY_ENC);
 239		else
 240			append_key(desc, adata->key_dma, adata->keylen,
 241				   CLASS_2 | KEY_DEST_MDHA_SPLIT | KEY_ENC);
 242	} else {
 243		append_proto_dkp(desc, adata);
 244	}
 245
 246	if (cdata->key_inline)
 247		append_key_as_imm(desc, cdata->key_virt, enckeylen,
 248				  enckeylen, CLASS_1 | KEY_DEST_CLASS_REG);
 249	else
 250		append_key(desc, cdata->key_dma, enckeylen, CLASS_1 |
 251			   KEY_DEST_CLASS_REG);
 252
 253	/* Load Counter into CONTEXT1 reg */
 254	if (is_rfc3686) {
 255		append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
 256				   LDST_CLASS_IND_CCB |
 257				   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
 258		append_move(desc,
 259			    MOVE_SRC_OUTFIFO |
 260			    MOVE_DEST_CLASS1CTX |
 261			    (16 << MOVE_OFFSET_SHIFT) |
 262			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
 263	}
 264
 265	set_jump_tgt_here(desc, key_jump_cmd);
 266}
 267
 268/**
 269 * cnstr_shdsc_aead_encap - IPSec ESP encapsulation shared descriptor
 270 *                          (non-protocol).
 271 * @desc: pointer to buffer used for descriptor construction
 272 * @cdata: pointer to block cipher transform definitions
 273 *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
 274 *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
 275 * @adata: pointer to authentication transform definitions.
 276 *         A split key is required for SEC Era < 6; the size of the split key
 277 *         is specified in this case. Valid algorithm values - one of
 278 *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
 279 *         with OP_ALG_AAI_HMAC_PRECOMP.
 280 * @ivsize: initialization vector size
 281 * @icvsize: integrity check value (ICV) size (truncated or full)
 282 * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
 283 * @nonce: pointer to rfc3686 nonce
 284 * @ctx1_iv_off: IV offset in CONTEXT1 register
 285 * @is_qi: true when called from caam/qi
 286 * @era: SEC Era
 287 */
 288void cnstr_shdsc_aead_encap(u32 * const desc, struct alginfo *cdata,
 289			    struct alginfo *adata, unsigned int ivsize,
 290			    unsigned int icvsize, const bool is_rfc3686,
 291			    u32 *nonce, const u32 ctx1_iv_off, const bool is_qi,
 292			    int era)
 293{
 294	/* Note: Context registers are saved. */
 295	init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
 296
 297	/* Class 2 operation */
 298	append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
 299			 OP_ALG_ENCRYPT);
 300
 301	if (is_qi) {
 302		u32 *wait_load_cmd;
 303
 304		/* REG3 = assoclen */
 305		append_seq_load(desc, 4, LDST_CLASS_DECO |
 306				LDST_SRCDST_WORD_DECO_MATH3 |
 307				(4 << LDST_OFFSET_SHIFT));
 308
 309		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
 310					    JUMP_COND_CALM | JUMP_COND_NCP |
 311					    JUMP_COND_NOP | JUMP_COND_NIP |
 312					    JUMP_COND_NIFP);
 313		set_jump_tgt_here(desc, wait_load_cmd);
 314
 315		append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
 316				LDST_SRCDST_BYTE_CONTEXT |
 317				(ctx1_iv_off << LDST_OFFSET_SHIFT));
 318	}
 319
 320	/* Read and write assoclen bytes */
 321	if (is_qi || era < 3) {
 322		append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
 323		append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
 324	} else {
 325		append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
 326		append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
 327	}
 328
 329	/* Skip assoc data */
 330	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
 331
 332	/* read assoc before reading payload */
 333	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
 334				      FIFOLDST_VLF);
 335
 336	/* Load Counter into CONTEXT1 reg */
 337	if (is_rfc3686)
 338		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
 339				     LDST_SRCDST_BYTE_CONTEXT |
 340				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
 341				      LDST_OFFSET_SHIFT));
 342
 343	/* Class 1 operation */
 344	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
 345			 OP_ALG_ENCRYPT);
 346
 347	/* Read and write cryptlen bytes */
 348	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
 349	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
 350	aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
 351
 352	/* Write ICV */
 353	append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
 354			 LDST_SRCDST_BYTE_CONTEXT);
 355
 356	print_hex_dump_debug("aead enc shdesc@" __stringify(__LINE__)": ",
 357			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
 358			     1);
 359}
 360EXPORT_SYMBOL(cnstr_shdsc_aead_encap);
 361
 362/**
 363 * cnstr_shdsc_aead_decap - IPSec ESP decapsulation shared descriptor
 364 *                          (non-protocol).
 365 * @desc: pointer to buffer used for descriptor construction
 366 * @cdata: pointer to block cipher transform definitions
 367 *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
 368 *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
 369 * @adata: pointer to authentication transform definitions.
 370 *         A split key is required for SEC Era < 6; the size of the split key
 371 *         is specified in this case. Valid algorithm values - one of
 372 *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
 373 *         with OP_ALG_AAI_HMAC_PRECOMP.
 374 * @ivsize: initialization vector size
 375 * @icvsize: integrity check value (ICV) size (truncated or full)
 376 * @geniv: whether to generate Encrypted Chain IV
 377 * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
 378 * @nonce: pointer to rfc3686 nonce
 379 * @ctx1_iv_off: IV offset in CONTEXT1 register
 380 * @is_qi: true when called from caam/qi
 381 * @era: SEC Era
 382 */
 383void cnstr_shdsc_aead_decap(u32 * const desc, struct alginfo *cdata,
 384			    struct alginfo *adata, unsigned int ivsize,
 385			    unsigned int icvsize, const bool geniv,
 386			    const bool is_rfc3686, u32 *nonce,
 387			    const u32 ctx1_iv_off, const bool is_qi, int era)
 388{
 389	/* Note: Context registers are saved. */
 390	init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
 391
 392	/* Class 2 operation */
 393	append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
 394			 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
 395
 396	if (is_qi) {
 397		u32 *wait_load_cmd;
 398
 399		/* REG3 = assoclen */
 400		append_seq_load(desc, 4, LDST_CLASS_DECO |
 401				LDST_SRCDST_WORD_DECO_MATH3 |
 402				(4 << LDST_OFFSET_SHIFT));
 403
 404		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
 405					    JUMP_COND_CALM | JUMP_COND_NCP |
 406					    JUMP_COND_NOP | JUMP_COND_NIP |
 407					    JUMP_COND_NIFP);
 408		set_jump_tgt_here(desc, wait_load_cmd);
 409
 410		if (!geniv)
 411			append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
 412					LDST_SRCDST_BYTE_CONTEXT |
 413					(ctx1_iv_off << LDST_OFFSET_SHIFT));
 414	}
 415
 416	/* Read and write assoclen bytes */
 417	if (is_qi || era < 3) {
 418		append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
 419		if (geniv)
 420			append_math_add_imm_u32(desc, VARSEQOUTLEN, REG3, IMM,
 421						ivsize);
 422		else
 423			append_math_add(desc, VARSEQOUTLEN, ZERO, REG3,
 424					CAAM_CMD_SZ);
 425	} else {
 426		append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
 427		if (geniv)
 428			append_math_add_imm_u32(desc, VARSEQOUTLEN, DPOVRD, IMM,
 429						ivsize);
 430		else
 431			append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD,
 432					CAAM_CMD_SZ);
 433	}
 434
 435	/* Skip assoc data */
 436	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
 437
 438	/* read assoc before reading payload */
 439	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
 440			     KEY_VLF);
 441
 442	if (geniv) {
 443		append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
 444				LDST_SRCDST_BYTE_CONTEXT |
 445				(ctx1_iv_off << LDST_OFFSET_SHIFT));
 446		append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_CLASS2INFIFO |
 447			    (ctx1_iv_off << MOVE_OFFSET_SHIFT) | ivsize);
 448	}
 449
 450	/* Load Counter into CONTEXT1 reg */
 451	if (is_rfc3686)
 452		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
 453				     LDST_SRCDST_BYTE_CONTEXT |
 454				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
 455				      LDST_OFFSET_SHIFT));
 456
 457	/* Choose operation */
 458	if (ctx1_iv_off)
 459		append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
 460				 OP_ALG_DECRYPT);
 461	else
 462		append_dec_op1(desc, cdata->algtype);
 463
 464	/* Read and write cryptlen bytes */
 465	append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
 466	append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
 467	aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
 468
 469	/* Load ICV */
 470	append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
 471			     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
 472
 473	print_hex_dump_debug("aead dec shdesc@" __stringify(__LINE__)": ",
 474			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
 475			     1);
 476}
 477EXPORT_SYMBOL(cnstr_shdsc_aead_decap);
 478
 479/**
 480 * cnstr_shdsc_aead_givencap - IPSec ESP encapsulation shared descriptor
 481 *                             (non-protocol) with HW-generated initialization
 482 *                             vector.
 483 * @desc: pointer to buffer used for descriptor construction
 484 * @cdata: pointer to block cipher transform definitions
 485 *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
 486 *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128.
 487 * @adata: pointer to authentication transform definitions.
 488 *         A split key is required for SEC Era < 6; the size of the split key
 489 *         is specified in this case. Valid algorithm values - one of
 490 *         OP_ALG_ALGSEL_{MD5, SHA1, SHA224, SHA256, SHA384, SHA512} ANDed
 491 *         with OP_ALG_AAI_HMAC_PRECOMP.
 492 * @ivsize: initialization vector size
 493 * @icvsize: integrity check value (ICV) size (truncated or full)
 494 * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
 495 * @nonce: pointer to rfc3686 nonce
 496 * @ctx1_iv_off: IV offset in CONTEXT1 register
 497 * @is_qi: true when called from caam/qi
 498 * @era: SEC Era
 499 */
 500void cnstr_shdsc_aead_givencap(u32 * const desc, struct alginfo *cdata,
 501			       struct alginfo *adata, unsigned int ivsize,
 502			       unsigned int icvsize, const bool is_rfc3686,
 503			       u32 *nonce, const u32 ctx1_iv_off,
 504			       const bool is_qi, int era)
 505{
 506	u32 geniv, moveiv;
 507	u32 *wait_cmd;
 508
 509	/* Note: Context registers are saved. */
 510	init_sh_desc_key_aead(desc, cdata, adata, is_rfc3686, nonce, era);
 511
 512	if (is_qi) {
 513		u32 *wait_load_cmd;
 514
 515		/* REG3 = assoclen */
 516		append_seq_load(desc, 4, LDST_CLASS_DECO |
 517				LDST_SRCDST_WORD_DECO_MATH3 |
 518				(4 << LDST_OFFSET_SHIFT));
 519
 520		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
 521					    JUMP_COND_CALM | JUMP_COND_NCP |
 522					    JUMP_COND_NOP | JUMP_COND_NIP |
 523					    JUMP_COND_NIFP);
 524		set_jump_tgt_here(desc, wait_load_cmd);
 525	}
 526
 527	if (is_rfc3686) {
 528		if (is_qi)
 529			append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
 530					LDST_SRCDST_BYTE_CONTEXT |
 531					(ctx1_iv_off << LDST_OFFSET_SHIFT));
 532
 533		goto copy_iv;
 534	}
 535
 536	/* Generate IV */
 537	geniv = NFIFOENTRY_STYPE_PAD | NFIFOENTRY_DEST_DECO |
 538		NFIFOENTRY_DTYPE_MSG | NFIFOENTRY_LC1 |
 539		NFIFOENTRY_PTYPE_RND | (ivsize << NFIFOENTRY_DLEN_SHIFT);
 540	append_load_imm_u32(desc, geniv, LDST_CLASS_IND_CCB |
 541			    LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
 542	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
 543	append_move(desc, MOVE_WAITCOMP |
 544		    MOVE_SRC_INFIFO | MOVE_DEST_CLASS1CTX |
 545		    (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
 546		    (ivsize << MOVE_LEN_SHIFT));
 547	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
 548
 549copy_iv:
 550	/* Copy IV to class 1 context */
 551	append_move(desc, MOVE_SRC_CLASS1CTX | MOVE_DEST_OUTFIFO |
 552		    (ctx1_iv_off << MOVE_OFFSET_SHIFT) |
 553		    (ivsize << MOVE_LEN_SHIFT));
 554
 555	/* Return to encryption */
 556	append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
 557			 OP_ALG_ENCRYPT);
 558
 559	/* Read and write assoclen bytes */
 560	if (is_qi || era < 3) {
 561		append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
 562		append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
 563	} else {
 564		append_math_add(desc, VARSEQINLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
 565		append_math_add(desc, VARSEQOUTLEN, ZERO, DPOVRD, CAAM_CMD_SZ);
 566	}
 567
 568	/* Skip assoc data */
 569	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
 570
 571	/* read assoc before reading payload */
 572	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_MSG |
 573			     KEY_VLF);
 574
 575	/* Copy iv from outfifo to class 2 fifo */
 576	moveiv = NFIFOENTRY_STYPE_OFIFO | NFIFOENTRY_DEST_CLASS2 |
 577		 NFIFOENTRY_DTYPE_MSG | (ivsize << NFIFOENTRY_DLEN_SHIFT);
 578	append_load_imm_u32(desc, moveiv, LDST_CLASS_IND_CCB |
 579			    LDST_SRCDST_WORD_INFO_FIFO | LDST_IMM);
 580	append_load_imm_u32(desc, ivsize, LDST_CLASS_2_CCB |
 581			    LDST_SRCDST_WORD_DATASZ_REG | LDST_IMM);
 582
 583	/* Load Counter into CONTEXT1 reg */
 584	if (is_rfc3686)
 585		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
 586				     LDST_SRCDST_BYTE_CONTEXT |
 587				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
 588				      LDST_OFFSET_SHIFT));
 589
 590	/* Class 1 operation */
 591	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
 592			 OP_ALG_ENCRYPT);
 593
 594	/* Will write ivsize + cryptlen */
 595	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
 596
 597	/* Not need to reload iv */
 598	append_seq_fifo_load(desc, ivsize,
 599			     FIFOLD_CLASS_SKIP);
 600
 601	/* Will read cryptlen */
 602	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
 603
 604	/*
 605	 * Wait for IV transfer (ofifo -> class2) to finish before starting
 606	 * ciphertext transfer (ofifo -> external memory).
 607	 */
 608	wait_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL | JUMP_COND_NIFP);
 609	set_jump_tgt_here(desc, wait_cmd);
 610
 611	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | KEY_VLF |
 612			     FIFOLD_TYPE_MSG1OUT2 | FIFOLD_TYPE_LASTBOTH);
 613	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
 614
 615	/* Write ICV */
 616	append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
 617			 LDST_SRCDST_BYTE_CONTEXT);
 618
 619	print_hex_dump_debug("aead givenc shdesc@" __stringify(__LINE__)": ",
 620			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
 621			     1);
 622}
 623EXPORT_SYMBOL(cnstr_shdsc_aead_givencap);
 624
 625/**
 626 * cnstr_shdsc_gcm_encap - gcm encapsulation shared descriptor
 627 * @desc: pointer to buffer used for descriptor construction
 628 * @cdata: pointer to block cipher transform definitions
 629 *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
 630 * @ivsize: initialization vector size
 631 * @icvsize: integrity check value (ICV) size (truncated or full)
 632 * @is_qi: true when called from caam/qi
 633 */
 634void cnstr_shdsc_gcm_encap(u32 * const desc, struct alginfo *cdata,
 635			   unsigned int ivsize, unsigned int icvsize,
 636			   const bool is_qi)
 637{
 638	u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1,
 639	    *zero_assoc_jump_cmd2;
 640
 641	init_sh_desc(desc, HDR_SHARE_SERIAL);
 642
 643	/* skip key loading if they are loaded due to sharing */
 644	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
 645				   JUMP_COND_SHRD);
 646	if (cdata->key_inline)
 647		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
 648				  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
 649	else
 650		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
 651			   KEY_DEST_CLASS_REG);
 652	set_jump_tgt_here(desc, key_jump_cmd);
 653
 654	/* class 1 operation */
 655	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
 656			 OP_ALG_ENCRYPT);
 657
 658	if (is_qi) {
 659		u32 *wait_load_cmd;
 660
 661		/* REG3 = assoclen */
 662		append_seq_load(desc, 4, LDST_CLASS_DECO |
 663				LDST_SRCDST_WORD_DECO_MATH3 |
 664				(4 << LDST_OFFSET_SHIFT));
 665
 666		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
 667					    JUMP_COND_CALM | JUMP_COND_NCP |
 668					    JUMP_COND_NOP | JUMP_COND_NIP |
 669					    JUMP_COND_NIFP);
 670		set_jump_tgt_here(desc, wait_load_cmd);
 671
 672		append_math_sub_imm_u32(desc, VARSEQOUTLEN, SEQINLEN, IMM,
 673					ivsize);
 674	} else {
 675		append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0,
 676				CAAM_CMD_SZ);
 677	}
 678
 679	/* if assoclen + cryptlen is ZERO, skip to ICV write */
 680	zero_assoc_jump_cmd2 = append_jump(desc, JUMP_TEST_ALL |
 681						 JUMP_COND_MATH_Z);
 682
 683	if (is_qi)
 684		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
 685				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
 686
 687	/* if assoclen is ZERO, skip reading the assoc data */
 688	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
 689	zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
 690					   JUMP_COND_MATH_Z);
 691
 692	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
 693
 694	/* skip assoc data */
 695	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
 696
 697	/* cryptlen = seqinlen - assoclen */
 698	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
 699
 700	/* if cryptlen is ZERO jump to zero-payload commands */
 701	zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
 702					    JUMP_COND_MATH_Z);
 703
 704	/* read assoc data */
 705	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
 706			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
 707	set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
 708
 709	append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
 710
 711	/* write encrypted data */
 712	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
 713
 714	/* read payload data */
 715	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
 716			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
 717
 718	/* jump to ICV writing */
 719	if (is_qi)
 720		append_jump(desc, JUMP_TEST_ALL | 4);
 721	else
 722		append_jump(desc, JUMP_TEST_ALL | 2);
 723
 724	/* zero-payload commands */
 725	set_jump_tgt_here(desc, zero_payload_jump_cmd);
 726
 727	/* read assoc data */
 728	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
 729			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
 730	if (is_qi)
 731		/* jump to ICV writing */
 732		append_jump(desc, JUMP_TEST_ALL | 2);
 733
 734	/* There is no input data */
 735	set_jump_tgt_here(desc, zero_assoc_jump_cmd2);
 736
 737	if (is_qi)
 738		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
 739				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1 |
 740				     FIFOLD_TYPE_LAST1);
 741
 742	/* write ICV */
 743	append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
 744			 LDST_SRCDST_BYTE_CONTEXT);
 745
 746	print_hex_dump_debug("gcm enc shdesc@" __stringify(__LINE__)": ",
 747			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
 748			     1);
 749}
 750EXPORT_SYMBOL(cnstr_shdsc_gcm_encap);
 751
 752/**
 753 * cnstr_shdsc_gcm_decap - gcm decapsulation shared descriptor
 754 * @desc: pointer to buffer used for descriptor construction
 755 * @cdata: pointer to block cipher transform definitions
 756 *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
 757 * @ivsize: initialization vector size
 758 * @icvsize: integrity check value (ICV) size (truncated or full)
 759 * @is_qi: true when called from caam/qi
 760 */
 761void cnstr_shdsc_gcm_decap(u32 * const desc, struct alginfo *cdata,
 762			   unsigned int ivsize, unsigned int icvsize,
 763			   const bool is_qi)
 764{
 765	u32 *key_jump_cmd, *zero_payload_jump_cmd, *zero_assoc_jump_cmd1;
 766
 767	init_sh_desc(desc, HDR_SHARE_SERIAL);
 768
 769	/* skip key loading if they are loaded due to sharing */
 770	key_jump_cmd = append_jump(desc, JUMP_JSL |
 771				   JUMP_TEST_ALL | JUMP_COND_SHRD);
 772	if (cdata->key_inline)
 773		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
 774				  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
 775	else
 776		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
 777			   KEY_DEST_CLASS_REG);
 778	set_jump_tgt_here(desc, key_jump_cmd);
 779
 780	/* class 1 operation */
 781	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
 782			 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
 783
 784	if (is_qi) {
 785		u32 *wait_load_cmd;
 786
 787		/* REG3 = assoclen */
 788		append_seq_load(desc, 4, LDST_CLASS_DECO |
 789				LDST_SRCDST_WORD_DECO_MATH3 |
 790				(4 << LDST_OFFSET_SHIFT));
 791
 792		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
 793					    JUMP_COND_CALM | JUMP_COND_NCP |
 794					    JUMP_COND_NOP | JUMP_COND_NIP |
 795					    JUMP_COND_NIFP);
 796		set_jump_tgt_here(desc, wait_load_cmd);
 797
 798		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
 799				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
 800	}
 801
 802	/* if assoclen is ZERO, skip reading the assoc data */
 803	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
 804	zero_assoc_jump_cmd1 = append_jump(desc, JUMP_TEST_ALL |
 805						 JUMP_COND_MATH_Z);
 806
 807	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
 808
 809	/* skip assoc data */
 810	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
 811
 812	/* read assoc data */
 813	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
 814			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
 815
 816	set_jump_tgt_here(desc, zero_assoc_jump_cmd1);
 817
 818	/* cryptlen = seqoutlen - assoclen */
 819	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
 820
 821	/* jump to zero-payload command if cryptlen is zero */
 822	zero_payload_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
 823					    JUMP_COND_MATH_Z);
 824
 825	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
 826
 827	/* store encrypted data */
 828	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
 829
 830	/* read payload data */
 831	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
 832			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
 833
 834	/* zero-payload command */
 835	set_jump_tgt_here(desc, zero_payload_jump_cmd);
 836
 837	/* read ICV */
 838	append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
 839			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
 840
 841	print_hex_dump_debug("gcm dec shdesc@" __stringify(__LINE__)": ",
 842			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
 843			     1);
 844}
 845EXPORT_SYMBOL(cnstr_shdsc_gcm_decap);
 846
 847/**
 848 * cnstr_shdsc_rfc4106_encap - IPSec ESP gcm encapsulation shared descriptor
 849 *                             (non-protocol).
 850 * @desc: pointer to buffer used for descriptor construction
 851 * @cdata: pointer to block cipher transform definitions
 852 *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
 853 * @ivsize: initialization vector size
 854 * @icvsize: integrity check value (ICV) size (truncated or full)
 855 * @is_qi: true when called from caam/qi
 856 *
 857 * Input sequence: AAD | PTXT
 858 * Output sequence: AAD | CTXT | ICV
 859 * AAD length (assoclen), which includes the IV length, is available in Math3.
 860 */
 861void cnstr_shdsc_rfc4106_encap(u32 * const desc, struct alginfo *cdata,
 862			       unsigned int ivsize, unsigned int icvsize,
 863			       const bool is_qi)
 864{
 865	u32 *key_jump_cmd, *zero_cryptlen_jump_cmd, *skip_instructions;
 866	init_sh_desc(desc, HDR_SHARE_SERIAL);
 867
 868	/* Skip key loading if it is loaded due to sharing */
 869	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
 870				   JUMP_COND_SHRD);
 871	if (cdata->key_inline)
 872		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
 873				  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
 874	else
 875		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
 876			   KEY_DEST_CLASS_REG);
 877	set_jump_tgt_here(desc, key_jump_cmd);
 878
 879	/* Class 1 operation */
 880	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
 881			 OP_ALG_ENCRYPT);
 882
 883	if (is_qi) {
 884		u32 *wait_load_cmd;
 885
 886		/* REG3 = assoclen */
 887		append_seq_load(desc, 4, LDST_CLASS_DECO |
 888				LDST_SRCDST_WORD_DECO_MATH3 |
 889				(4 << LDST_OFFSET_SHIFT));
 890
 891		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
 892					    JUMP_COND_CALM | JUMP_COND_NCP |
 893					    JUMP_COND_NOP | JUMP_COND_NIP |
 894					    JUMP_COND_NIFP);
 895		set_jump_tgt_here(desc, wait_load_cmd);
 896
 897		/* Read salt and IV */
 898		append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
 899					cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
 900					FIFOLD_TYPE_IV);
 901		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
 902				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
 903	}
 904
 905	append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, ivsize);
 906	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
 907
 908	/* Skip AAD */
 909	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
 910
 911	/* Read cryptlen and set this value into VARSEQOUTLEN */
 912	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG3, CAAM_CMD_SZ);
 913
 914	/* If cryptlen is ZERO jump to AAD command */
 915	zero_cryptlen_jump_cmd = append_jump(desc, JUMP_TEST_ALL |
 916					    JUMP_COND_MATH_Z);
 917
 918	/* Read AAD data */
 919	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
 920			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
 921
 922	/* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
 923	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA);
 924
 925	/* Skip IV */
 926	append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_SKIP);
 927	append_math_add(desc, VARSEQINLEN, VARSEQOUTLEN, REG0, CAAM_CMD_SZ);
 928
 929	/* Write encrypted data */
 930	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
 931
 932	/* Read payload data */
 933	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
 934			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
 935
 936	/* Jump instructions to avoid double reading of AAD */
 937	skip_instructions = append_jump(desc, JUMP_TEST_ALL);
 938
 939	/* There is no input data, cryptlen = 0 */
 940	set_jump_tgt_here(desc, zero_cryptlen_jump_cmd);
 941
 942	/* Read AAD */
 943	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
 944			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST1);
 945
 946	set_jump_tgt_here(desc, skip_instructions);
 947
 948	/* Write ICV */
 949	append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
 950			 LDST_SRCDST_BYTE_CONTEXT);
 951
 952	print_hex_dump_debug("rfc4106 enc shdesc@" __stringify(__LINE__)": ",
 953			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
 954			     1);
 955}
 956EXPORT_SYMBOL(cnstr_shdsc_rfc4106_encap);
 957
 958/**
 959 * cnstr_shdsc_rfc4106_decap - IPSec ESP gcm decapsulation shared descriptor
 960 *                             (non-protocol).
 961 * @desc: pointer to buffer used for descriptor construction
 962 * @cdata: pointer to block cipher transform definitions
 963 *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
 964 * @ivsize: initialization vector size
 965 * @icvsize: integrity check value (ICV) size (truncated or full)
 966 * @is_qi: true when called from caam/qi
 967 */
 968void cnstr_shdsc_rfc4106_decap(u32 * const desc, struct alginfo *cdata,
 969			       unsigned int ivsize, unsigned int icvsize,
 970			       const bool is_qi)
 971{
 972	u32 *key_jump_cmd;
 973
 974	init_sh_desc(desc, HDR_SHARE_SERIAL);
 975
 976	/* Skip key loading if it is loaded due to sharing */
 977	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
 978				   JUMP_COND_SHRD);
 979	if (cdata->key_inline)
 980		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
 981				  cdata->keylen, CLASS_1 |
 982				  KEY_DEST_CLASS_REG);
 983	else
 984		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
 985			   KEY_DEST_CLASS_REG);
 986	set_jump_tgt_here(desc, key_jump_cmd);
 987
 988	/* Class 1 operation */
 989	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
 990			 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
 991
 992	if (is_qi) {
 993		u32 *wait_load_cmd;
 994
 995		/* REG3 = assoclen */
 996		append_seq_load(desc, 4, LDST_CLASS_DECO |
 997				LDST_SRCDST_WORD_DECO_MATH3 |
 998				(4 << LDST_OFFSET_SHIFT));
 999
1000		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1001					    JUMP_COND_CALM | JUMP_COND_NCP |
1002					    JUMP_COND_NOP | JUMP_COND_NIP |
1003					    JUMP_COND_NIFP);
1004		set_jump_tgt_here(desc, wait_load_cmd);
1005
1006		/* Read salt and IV */
1007		append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
1008					cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
1009					FIFOLD_TYPE_IV);
1010		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
1011				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
1012	}
1013
1014	append_math_sub_imm_u32(desc, VARSEQINLEN, REG3, IMM, ivsize);
1015	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
1016
1017	/* Read assoc data */
1018	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
1019			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_FLUSH1);
1020
1021	/* Skip IV */
1022	append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_SKIP);
1023
1024	/* Will read cryptlen bytes */
1025	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG3, CAAM_CMD_SZ);
1026
1027	/* Workaround for erratum A-005473 (simultaneous SEQ FIFO skips) */
1028	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_MSG);
1029
1030	/* Skip assoc data */
1031	append_seq_fifo_store(desc, 0, FIFOST_TYPE_SKIP | FIFOLDST_VLF);
1032
1033	/* Will write cryptlen bytes */
1034	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1035
1036	/* Store payload data */
1037	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
1038
1039	/* Read encrypted data */
1040	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLDST_VLF |
1041			     FIFOLD_TYPE_MSG | FIFOLD_TYPE_FLUSH1);
1042
1043	/* Read ICV */
1044	append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
1045			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
1046
1047	print_hex_dump_debug("rfc4106 dec shdesc@" __stringify(__LINE__)": ",
1048			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1049			     1);
1050}
1051EXPORT_SYMBOL(cnstr_shdsc_rfc4106_decap);
1052
1053/**
1054 * cnstr_shdsc_rfc4543_encap - IPSec ESP gmac encapsulation shared descriptor
1055 *                             (non-protocol).
1056 * @desc: pointer to buffer used for descriptor construction
1057 * @cdata: pointer to block cipher transform definitions
1058 *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
1059 * @ivsize: initialization vector size
1060 * @icvsize: integrity check value (ICV) size (truncated or full)
1061 * @is_qi: true when called from caam/qi
1062 */
1063void cnstr_shdsc_rfc4543_encap(u32 * const desc, struct alginfo *cdata,
1064			       unsigned int ivsize, unsigned int icvsize,
1065			       const bool is_qi)
1066{
1067	u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
1068
1069	init_sh_desc(desc, HDR_SHARE_SERIAL);
1070
1071	/* Skip key loading if it is loaded due to sharing */
1072	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1073				   JUMP_COND_SHRD);
1074	if (cdata->key_inline)
1075		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1076				  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1077	else
1078		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
1079			   KEY_DEST_CLASS_REG);
1080	set_jump_tgt_here(desc, key_jump_cmd);
1081
1082	/* Class 1 operation */
1083	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1084			 OP_ALG_ENCRYPT);
1085
1086	if (is_qi) {
1087		/* assoclen is not needed, skip it */
1088		append_seq_fifo_load(desc, 4, FIFOLD_CLASS_SKIP);
1089
1090		/* Read salt and IV */
1091		append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
1092					cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
1093					FIFOLD_TYPE_IV);
1094		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
1095				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
1096	}
1097
1098	/* assoclen + cryptlen = seqinlen */
1099	append_math_sub(desc, REG3, SEQINLEN, REG0, CAAM_CMD_SZ);
1100
1101	/*
1102	 * MOVE_LEN opcode is not available in all SEC HW revisions,
1103	 * thus need to do some magic, i.e. self-patch the descriptor
1104	 * buffer.
1105	 */
1106	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
1107				    (0x6 << MOVE_LEN_SHIFT));
1108	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
1109				     (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
1110
1111	/* Will read assoclen + cryptlen bytes */
1112	append_math_sub(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1113
1114	/* Will write assoclen + cryptlen bytes */
1115	append_math_sub(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1116
1117	/* Read and write assoclen + cryptlen bytes */
1118	aead_append_src_dst(desc, FIFOLD_TYPE_AAD);
1119
1120	set_move_tgt_here(desc, read_move_cmd);
1121	set_move_tgt_here(desc, write_move_cmd);
1122	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
1123	/* Move payload data to OFIFO */
1124	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
1125
1126	/* Write ICV */
1127	append_seq_store(desc, icvsize, LDST_CLASS_1_CCB |
1128			 LDST_SRCDST_BYTE_CONTEXT);
1129
1130	print_hex_dump_debug("rfc4543 enc shdesc@" __stringify(__LINE__)": ",
1131			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1132			     1);
1133}
1134EXPORT_SYMBOL(cnstr_shdsc_rfc4543_encap);
1135
1136/**
1137 * cnstr_shdsc_rfc4543_decap - IPSec ESP gmac decapsulation shared descriptor
1138 *                             (non-protocol).
1139 * @desc: pointer to buffer used for descriptor construction
1140 * @cdata: pointer to block cipher transform definitions
1141 *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_GCM.
1142 * @ivsize: initialization vector size
1143 * @icvsize: integrity check value (ICV) size (truncated or full)
1144 * @is_qi: true when called from caam/qi
1145 */
1146void cnstr_shdsc_rfc4543_decap(u32 * const desc, struct alginfo *cdata,
1147			       unsigned int ivsize, unsigned int icvsize,
1148			       const bool is_qi)
1149{
1150	u32 *key_jump_cmd, *read_move_cmd, *write_move_cmd;
1151
1152	init_sh_desc(desc, HDR_SHARE_SERIAL);
1153
1154	/* Skip key loading if it is loaded due to sharing */
1155	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1156				   JUMP_COND_SHRD);
1157	if (cdata->key_inline)
1158		append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1159				  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1160	else
1161		append_key(desc, cdata->key_dma, cdata->keylen, CLASS_1 |
1162			   KEY_DEST_CLASS_REG);
1163	set_jump_tgt_here(desc, key_jump_cmd);
1164
1165	/* Class 1 operation */
1166	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1167			 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
1168
1169	if (is_qi) {
1170		/* assoclen is not needed, skip it */
1171		append_seq_fifo_load(desc, 4, FIFOLD_CLASS_SKIP);
1172
1173		/* Read salt and IV */
1174		append_fifo_load_as_imm(desc, (void *)(cdata->key_virt +
1175					cdata->keylen), 4, FIFOLD_CLASS_CLASS1 |
1176					FIFOLD_TYPE_IV);
1177		append_seq_fifo_load(desc, ivsize, FIFOLD_CLASS_CLASS1 |
1178				     FIFOLD_TYPE_IV | FIFOLD_TYPE_FLUSH1);
1179	}
1180
1181	/* assoclen + cryptlen = seqoutlen */
1182	append_math_sub(desc, REG3, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1183
1184	/*
1185	 * MOVE_LEN opcode is not available in all SEC HW revisions,
1186	 * thus need to do some magic, i.e. self-patch the descriptor
1187	 * buffer.
1188	 */
1189	read_move_cmd = append_move(desc, MOVE_SRC_DESCBUF | MOVE_DEST_MATH3 |
1190				    (0x6 << MOVE_LEN_SHIFT));
1191	write_move_cmd = append_move(desc, MOVE_SRC_MATH3 | MOVE_DEST_DESCBUF |
1192				     (0x8 << MOVE_LEN_SHIFT) | MOVE_WAITCOMP);
1193
1194	/* Will read assoclen + cryptlen bytes */
1195	append_math_sub(desc, VARSEQINLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1196
1197	/* Will write assoclen + cryptlen bytes */
1198	append_math_sub(desc, VARSEQOUTLEN, SEQOUTLEN, REG0, CAAM_CMD_SZ);
1199
1200	/* Store payload data */
1201	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | FIFOLDST_VLF);
1202
1203	/* In-snoop assoclen + cryptlen data */
1204	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | FIFOLDST_VLF |
1205			     FIFOLD_TYPE_AAD | FIFOLD_TYPE_LAST2FLUSH1);
1206
1207	set_move_tgt_here(desc, read_move_cmd);
1208	set_move_tgt_here(desc, write_move_cmd);
1209	append_cmd(desc, CMD_LOAD | DISABLE_AUTO_INFO_FIFO);
1210	/* Move payload data to OFIFO */
1211	append_move(desc, MOVE_SRC_INFIFO_CL | MOVE_DEST_OUTFIFO);
1212	append_cmd(desc, CMD_LOAD | ENABLE_AUTO_INFO_FIFO);
1213
1214	/* Read ICV */
1215	append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS1 |
1216			     FIFOLD_TYPE_ICV | FIFOLD_TYPE_LAST1);
1217
1218	print_hex_dump_debug("rfc4543 dec shdesc@" __stringify(__LINE__)": ",
1219			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1220			     1);
1221}
1222EXPORT_SYMBOL(cnstr_shdsc_rfc4543_decap);
1223
1224/**
1225 * cnstr_shdsc_chachapoly - Chacha20 + Poly1305 generic AEAD (rfc7539) and
1226 *                          IPsec ESP (rfc7634, a.k.a. rfc7539esp) shared
1227 *                          descriptor (non-protocol).
1228 * @desc: pointer to buffer used for descriptor construction
1229 * @cdata: pointer to block cipher transform definitions
1230 *         Valid algorithm values - OP_ALG_ALGSEL_CHACHA20 ANDed with
1231 *         OP_ALG_AAI_AEAD.
1232 * @adata: pointer to authentication transform definitions
1233 *         Valid algorithm values - OP_ALG_ALGSEL_POLY1305 ANDed with
1234 *         OP_ALG_AAI_AEAD.
1235 * @ivsize: initialization vector size
1236 * @icvsize: integrity check value (ICV) size (truncated or full)
1237 * @encap: true if encapsulation, false if decapsulation
1238 * @is_qi: true when called from caam/qi
1239 */
1240void cnstr_shdsc_chachapoly(u32 * const desc, struct alginfo *cdata,
1241			    struct alginfo *adata, unsigned int ivsize,
1242			    unsigned int icvsize, const bool encap,
1243			    const bool is_qi)
1244{
1245	u32 *key_jump_cmd, *wait_cmd;
1246	u32 nfifo;
1247	const bool is_ipsec = (ivsize != CHACHAPOLY_IV_SIZE);
1248
1249	/* Note: Context registers are saved. */
1250	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1251
1252	/* skip key loading if they are loaded due to sharing */
1253	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1254				   JUMP_COND_SHRD);
1255
1256	append_key_as_imm(desc, cdata->key_virt, cdata->keylen, cdata->keylen,
1257			  CLASS_1 | KEY_DEST_CLASS_REG);
1258
1259	/* For IPsec load the salt from keymat in the context register */
1260	if (is_ipsec)
1261		append_load_as_imm(desc, cdata->key_virt + cdata->keylen, 4,
1262				   LDST_CLASS_1_CCB | LDST_SRCDST_BYTE_CONTEXT |
1263				   4 << LDST_OFFSET_SHIFT);
1264
1265	set_jump_tgt_here(desc, key_jump_cmd);
1266
1267	/* Class 2 and 1 operations: Poly & ChaCha */
1268	if (encap) {
1269		append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
1270				 OP_ALG_ENCRYPT);
1271		append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1272				 OP_ALG_ENCRYPT);
1273	} else {
1274		append_operation(desc, adata->algtype | OP_ALG_AS_INITFINAL |
1275				 OP_ALG_DECRYPT | OP_ALG_ICV_ON);
1276		append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1277				 OP_ALG_DECRYPT);
1278	}
1279
1280	if (is_qi) {
1281		u32 *wait_load_cmd;
1282		u32 ctx1_iv_off = is_ipsec ? 8 : 4;
1283
1284		/* REG3 = assoclen */
1285		append_seq_load(desc, 4, LDST_CLASS_DECO |
1286				LDST_SRCDST_WORD_DECO_MATH3 |
1287				4 << LDST_OFFSET_SHIFT);
1288
1289		wait_load_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1290					    JUMP_COND_CALM | JUMP_COND_NCP |
1291					    JUMP_COND_NOP | JUMP_COND_NIP |
1292					    JUMP_COND_NIFP);
1293		set_jump_tgt_here(desc, wait_load_cmd);
1294
1295		append_seq_load(desc, ivsize, LDST_CLASS_1_CCB |
1296				LDST_SRCDST_BYTE_CONTEXT |
1297				ctx1_iv_off << LDST_OFFSET_SHIFT);
1298	}
1299
1300	/*
1301	 * MAGIC with NFIFO
1302	 * Read associated data from the input and send them to class1 and
1303	 * class2 alignment blocks. From class1 send data to output fifo and
1304	 * then write it to memory since we don't need to encrypt AD.
1305	 */
1306	nfifo = NFIFOENTRY_DEST_BOTH | NFIFOENTRY_FC1 | NFIFOENTRY_FC2 |
1307		NFIFOENTRY_DTYPE_POLY | NFIFOENTRY_BND;
1308	append_load_imm_u32(desc, nfifo, LDST_CLASS_IND_CCB |
1309			    LDST_SRCDST_WORD_INFO_FIFO_SM | LDLEN_MATH3);
1310
1311	append_math_add(desc, VARSEQINLEN, ZERO, REG3, CAAM_CMD_SZ);
1312	append_math_add(desc, VARSEQOUTLEN, ZERO, REG3, CAAM_CMD_SZ);
1313	append_seq_fifo_load(desc, 0, FIFOLD_TYPE_NOINFOFIFO |
1314			     FIFOLD_CLASS_CLASS1 | LDST_VLF);
1315	append_move_len(desc, MOVE_AUX_LS | MOVE_SRC_AUX_ABLK |
1316			MOVE_DEST_OUTFIFO | MOVELEN_MRSEL_MATH3);
1317	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | LDST_VLF);
1318
1319	/* IPsec - copy IV at the output */
1320	if (is_ipsec)
1321		append_seq_fifo_store(desc, ivsize, FIFOST_TYPE_METADATA |
1322				      0x2 << 25);
1323
1324	wait_cmd = append_jump(desc, JUMP_JSL | JUMP_TYPE_LOCAL |
1325			       JUMP_COND_NOP | JUMP_TEST_ALL);
1326	set_jump_tgt_here(desc, wait_cmd);
1327
1328	if (encap) {
1329		/* Read and write cryptlen bytes */
1330		append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1331		append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0,
1332				CAAM_CMD_SZ);
1333		aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
1334
1335		/* Write ICV */
1336		append_seq_store(desc, icvsize, LDST_CLASS_2_CCB |
1337				 LDST_SRCDST_BYTE_CONTEXT);
1338	} else {
1339		/* Read and write cryptlen bytes */
1340		append_math_add(desc, VARSEQINLEN, SEQOUTLEN, REG0,
1341				CAAM_CMD_SZ);
1342		append_math_add(desc, VARSEQOUTLEN, SEQOUTLEN, REG0,
1343				CAAM_CMD_SZ);
1344		aead_append_src_dst(desc, FIFOLD_TYPE_MSG);
1345
1346		/* Load ICV for verification */
1347		append_seq_fifo_load(desc, icvsize, FIFOLD_CLASS_CLASS2 |
1348				     FIFOLD_TYPE_LAST2 | FIFOLD_TYPE_ICV);
1349	}
1350
1351	print_hex_dump_debug("chachapoly shdesc@" __stringify(__LINE__)": ",
1352			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1353			     1);
1354}
1355EXPORT_SYMBOL(cnstr_shdsc_chachapoly);
1356
1357/* For skcipher encrypt and decrypt, read from req->src and write to req->dst */
1358static inline void skcipher_append_src_dst(u32 *desc)
1359{
1360	append_math_add(desc, VARSEQOUTLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1361	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1362	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 |
1363			     KEY_VLF | FIFOLD_TYPE_MSG | FIFOLD_TYPE_LAST1);
1364	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
1365}
1366
1367/**
1368 * cnstr_shdsc_skcipher_encap - skcipher encapsulation shared descriptor
1369 * @desc: pointer to buffer used for descriptor construction
1370 * @cdata: pointer to block cipher transform definitions
1371 *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
1372 *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128
1373 *                                - OP_ALG_ALGSEL_CHACHA20
1374 * @ivsize: initialization vector size
1375 * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
1376 * @ctx1_iv_off: IV offset in CONTEXT1 register
1377 */
1378void cnstr_shdsc_skcipher_encap(u32 * const desc, struct alginfo *cdata,
1379				unsigned int ivsize, const bool is_rfc3686,
1380				const u32 ctx1_iv_off)
1381{
1382	u32 *key_jump_cmd;
1383	u32 options = cdata->algtype | OP_ALG_AS_INIT | OP_ALG_ENCRYPT;
1384	bool is_chacha20 = ((cdata->algtype & OP_ALG_ALGSEL_MASK) ==
1385			    OP_ALG_ALGSEL_CHACHA20);
1386
1387	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1388	/* Skip if already shared */
1389	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1390				   JUMP_COND_SHRD);
1391
1392	/* Load class1 key only */
1393	append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1394			  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1395
1396	/* Load nonce into CONTEXT1 reg */
1397	if (is_rfc3686) {
1398		const u8 *nonce = cdata->key_virt + cdata->keylen;
1399
1400		append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
1401				   LDST_CLASS_IND_CCB |
1402				   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
1403		append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
1404			    MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
1405			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
1406	}
1407
1408	set_jump_tgt_here(desc, key_jump_cmd);
1409
1410	/* Load IV, if there is one */
1411	if (ivsize)
1412		append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1413				LDST_CLASS_1_CCB | (ctx1_iv_off <<
1414				LDST_OFFSET_SHIFT));
1415
1416	/* Load counter into CONTEXT1 reg */
1417	if (is_rfc3686)
1418		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
1419				     LDST_SRCDST_BYTE_CONTEXT |
1420				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
1421				      LDST_OFFSET_SHIFT));
1422
1423	/* Load operation */
1424	if (is_chacha20)
1425		options |= OP_ALG_AS_FINALIZE;
1426	append_operation(desc, options);
1427
1428	/* Perform operation */
1429	skcipher_append_src_dst(desc);
1430
1431	/* Store IV */
1432	if (!is_chacha20 && ivsize)
1433		append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1434				 LDST_CLASS_1_CCB | (ctx1_iv_off <<
1435				 LDST_OFFSET_SHIFT));
1436
1437	print_hex_dump_debug("skcipher enc shdesc@" __stringify(__LINE__)": ",
1438			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1439			     1);
1440}
1441EXPORT_SYMBOL(cnstr_shdsc_skcipher_encap);
1442
1443/**
1444 * cnstr_shdsc_skcipher_decap - skcipher decapsulation shared descriptor
1445 * @desc: pointer to buffer used for descriptor construction
1446 * @cdata: pointer to block cipher transform definitions
1447 *         Valid algorithm values - one of OP_ALG_ALGSEL_{AES, DES, 3DES} ANDed
1448 *         with OP_ALG_AAI_CBC or OP_ALG_AAI_CTR_MOD128
1449 *                                - OP_ALG_ALGSEL_CHACHA20
1450 * @ivsize: initialization vector size
1451 * @is_rfc3686: true when ctr(aes) is wrapped by rfc3686 template
1452 * @ctx1_iv_off: IV offset in CONTEXT1 register
1453 */
1454void cnstr_shdsc_skcipher_decap(u32 * const desc, struct alginfo *cdata,
1455				unsigned int ivsize, const bool is_rfc3686,
1456				const u32 ctx1_iv_off)
1457{
1458	u32 *key_jump_cmd;
1459	bool is_chacha20 = ((cdata->algtype & OP_ALG_ALGSEL_MASK) ==
1460			    OP_ALG_ALGSEL_CHACHA20);
1461
1462	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1463	/* Skip if already shared */
1464	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1465				   JUMP_COND_SHRD);
1466
1467	/* Load class1 key only */
1468	append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1469			  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1470
1471	/* Load nonce into CONTEXT1 reg */
1472	if (is_rfc3686) {
1473		const u8 *nonce = cdata->key_virt + cdata->keylen;
1474
1475		append_load_as_imm(desc, nonce, CTR_RFC3686_NONCE_SIZE,
1476				   LDST_CLASS_IND_CCB |
1477				   LDST_SRCDST_BYTE_OUTFIFO | LDST_IMM);
1478		append_move(desc, MOVE_WAITCOMP | MOVE_SRC_OUTFIFO |
1479			    MOVE_DEST_CLASS1CTX | (16 << MOVE_OFFSET_SHIFT) |
1480			    (CTR_RFC3686_NONCE_SIZE << MOVE_LEN_SHIFT));
1481	}
1482
1483	set_jump_tgt_here(desc, key_jump_cmd);
1484
1485	/* Load IV, if there is one */
1486	if (ivsize)
1487		append_seq_load(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1488				LDST_CLASS_1_CCB | (ctx1_iv_off <<
1489				LDST_OFFSET_SHIFT));
1490
1491	/* Load counter into CONTEXT1 reg */
1492	if (is_rfc3686)
1493		append_load_imm_be32(desc, 1, LDST_IMM | LDST_CLASS_1_CCB |
1494				     LDST_SRCDST_BYTE_CONTEXT |
1495				     ((ctx1_iv_off + CTR_RFC3686_IV_SIZE) <<
1496				      LDST_OFFSET_SHIFT));
1497
1498	/* Choose operation */
1499	if (ctx1_iv_off)
1500		append_operation(desc, cdata->algtype | OP_ALG_AS_INIT |
1501				 OP_ALG_DECRYPT);
1502	else
1503		append_dec_op1(desc, cdata->algtype);
1504
1505	/* Perform operation */
1506	skcipher_append_src_dst(desc);
1507
1508	/* Store IV */
1509	if (!is_chacha20 && ivsize)
1510		append_seq_store(desc, ivsize, LDST_SRCDST_BYTE_CONTEXT |
1511				 LDST_CLASS_1_CCB | (ctx1_iv_off <<
1512				 LDST_OFFSET_SHIFT));
1513
1514	print_hex_dump_debug("skcipher dec shdesc@" __stringify(__LINE__)": ",
1515			     DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
1516			     1);
1517}
1518EXPORT_SYMBOL(cnstr_shdsc_skcipher_decap);
1519
1520/**
1521 * cnstr_shdsc_xts_skcipher_encap - xts skcipher encapsulation shared descriptor
1522 * @desc: pointer to buffer used for descriptor construction
1523 * @cdata: pointer to block cipher transform definitions
1524 *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_XTS.
1525 */
1526void cnstr_shdsc_xts_skcipher_encap(u32 * const desc, struct alginfo *cdata)
1527{
1528	/*
1529	 * Set sector size to a big value, practically disabling
1530	 * sector size segmentation in xts implementation. We cannot
1531	 * take full advantage of this HW feature with existing
1532	 * crypto API / dm-crypt SW architecture.
1533	 */
1534	__be64 sector_size = cpu_to_be64(BIT(15));
1535	u32 *key_jump_cmd;
1536
1537	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1538	/* Skip if already shared */
1539	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1540				   JUMP_COND_SHRD);
1541
1542	/* Load class1 keys only */
1543	append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1544			  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1545
1546	/* Load sector size with index 40 bytes (0x28) */
1547	append_load_as_imm(desc, (void *)&sector_size, 8, LDST_CLASS_1_CCB |
1548			   LDST_SRCDST_BYTE_CONTEXT |
1549			   (0x28 << LDST_OFFSET_SHIFT));
1550
1551	set_jump_tgt_here(desc, key_jump_cmd);
1552
1553	/*
1554	 * create sequence for loading the sector index / 16B tweak value
1555	 * Lower 8B of IV - sector index / tweak lower half
1556	 * Upper 8B of IV - upper half of 16B tweak
1557	 */
1558	append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1559			(0x20 << LDST_OFFSET_SHIFT));
1560	append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1561			(0x30 << LDST_OFFSET_SHIFT));
1562
1563	/* Load operation */
1564	append_operation(desc, cdata->algtype | OP_ALG_AS_INITFINAL |
1565			 OP_ALG_ENCRYPT);
1566
1567	/* Perform operation */
1568	skcipher_append_src_dst(desc);
1569
1570	/* Store lower 8B and upper 8B of IV */
1571	append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1572			 (0x20 << LDST_OFFSET_SHIFT));
1573	append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1574			 (0x30 << LDST_OFFSET_SHIFT));
1575
1576	print_hex_dump_debug("xts skcipher enc shdesc@" __stringify(__LINE__)
1577			     ": ", DUMP_PREFIX_ADDRESS, 16, 4,
1578			     desc, desc_bytes(desc), 1);
1579}
1580EXPORT_SYMBOL(cnstr_shdsc_xts_skcipher_encap);
1581
1582/**
1583 * cnstr_shdsc_xts_skcipher_decap - xts skcipher decapsulation shared descriptor
1584 * @desc: pointer to buffer used for descriptor construction
1585 * @cdata: pointer to block cipher transform definitions
1586 *         Valid algorithm values - OP_ALG_ALGSEL_AES ANDed with OP_ALG_AAI_XTS.
1587 */
1588void cnstr_shdsc_xts_skcipher_decap(u32 * const desc, struct alginfo *cdata)
1589{
1590	/*
1591	 * Set sector size to a big value, practically disabling
1592	 * sector size segmentation in xts implementation. We cannot
1593	 * take full advantage of this HW feature with existing
1594	 * crypto API / dm-crypt SW architecture.
1595	 */
1596	__be64 sector_size = cpu_to_be64(BIT(15));
1597	u32 *key_jump_cmd;
1598
1599	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
1600	/* Skip if already shared */
1601	key_jump_cmd = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
1602				   JUMP_COND_SHRD);
1603
1604	/* Load class1 key only */
1605	append_key_as_imm(desc, cdata->key_virt, cdata->keylen,
1606			  cdata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1607
1608	/* Load sector size with index 40 bytes (0x28) */
1609	append_load_as_imm(desc, (void *)&sector_size, 8, LDST_CLASS_1_CCB |
1610			   LDST_SRCDST_BYTE_CONTEXT |
1611			   (0x28 << LDST_OFFSET_SHIFT));
1612
1613	set_jump_tgt_here(desc, key_jump_cmd);
1614
1615	/*
1616	 * create sequence for loading the sector index / 16B tweak value
1617	 * Lower 8B of IV - sector index / tweak lower half
1618	 * Upper 8B of IV - upper half of 16B tweak
1619	 */
1620	append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1621			(0x20 << LDST_OFFSET_SHIFT));
1622	append_seq_load(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1623			(0x30 << LDST_OFFSET_SHIFT));
1624	/* Load operation */
1625	append_dec_op1(desc, cdata->algtype);
1626
1627	/* Perform operation */
1628	skcipher_append_src_dst(desc);
1629
1630	/* Store lower 8B and upper 8B of IV */
1631	append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1632			 (0x20 << LDST_OFFSET_SHIFT));
1633	append_seq_store(desc, 8, LDST_SRCDST_BYTE_CONTEXT | LDST_CLASS_1_CCB |
1634			 (0x30 << LDST_OFFSET_SHIFT));
1635
1636	print_hex_dump_debug("xts skcipher dec shdesc@" __stringify(__LINE__)
1637			     ": ", DUMP_PREFIX_ADDRESS, 16, 4, desc,
1638			     desc_bytes(desc), 1);
1639}
1640EXPORT_SYMBOL(cnstr_shdsc_xts_skcipher_decap);
1641
1642MODULE_LICENSE("GPL");
1643MODULE_DESCRIPTION("FSL CAAM descriptor support");
1644MODULE_AUTHOR("Freescale Semiconductor - NMG/STC");