162306a36Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Shared descriptors for ahash algorithms
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright 2017-2019 NXP
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include "compat.h"
962306a36Sopenharmony_ci#include "desc_constr.h"
1062306a36Sopenharmony_ci#include "caamhash_desc.h"
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci/**
1362306a36Sopenharmony_ci * cnstr_shdsc_ahash - ahash shared descriptor
1462306a36Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction
1562306a36Sopenharmony_ci * @adata: pointer to authentication transform definitions.
1662306a36Sopenharmony_ci *         A split key is required for SEC Era < 6; the size of the split key
1762306a36Sopenharmony_ci *         is specified in this case.
1862306a36Sopenharmony_ci *         Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1, SHA224,
1962306a36Sopenharmony_ci *         SHA256, SHA384, SHA512}.
2062306a36Sopenharmony_ci * @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE}
2162306a36Sopenharmony_ci * @digestsize: algorithm's digest size
2262306a36Sopenharmony_ci * @ctx_len: size of Context Register
2362306a36Sopenharmony_ci * @import_ctx: true if previous Context Register needs to be restored
2462306a36Sopenharmony_ci *              must be true for ahash update and final
2562306a36Sopenharmony_ci *              must be false for ahash first and digest
2662306a36Sopenharmony_ci * @era: SEC Era
2762306a36Sopenharmony_ci */
2862306a36Sopenharmony_civoid cnstr_shdsc_ahash(u32 * const desc, struct alginfo *adata, u32 state,
2962306a36Sopenharmony_ci		       int digestsize, int ctx_len, bool import_ctx, int era)
3062306a36Sopenharmony_ci{
3162306a36Sopenharmony_ci	u32 op = adata->algtype;
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	init_sh_desc(desc, HDR_SHARE_SERIAL);
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci	/* Append key if it has been set; ahash update excluded */
3662306a36Sopenharmony_ci	if (state != OP_ALG_AS_UPDATE && adata->keylen) {
3762306a36Sopenharmony_ci		u32 *skip_key_load;
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci		/* Skip key loading if already shared */
4062306a36Sopenharmony_ci		skip_key_load = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
4162306a36Sopenharmony_ci					    JUMP_COND_SHRD);
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci		if (era < 6)
4462306a36Sopenharmony_ci			append_key_as_imm(desc, adata->key_virt,
4562306a36Sopenharmony_ci					  adata->keylen_pad,
4662306a36Sopenharmony_ci					  adata->keylen, CLASS_2 |
4762306a36Sopenharmony_ci					  KEY_DEST_MDHA_SPLIT | KEY_ENC);
4862306a36Sopenharmony_ci		else
4962306a36Sopenharmony_ci			append_proto_dkp(desc, adata);
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci		set_jump_tgt_here(desc, skip_key_load);
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci		op |= OP_ALG_AAI_HMAC_PRECOMP;
5462306a36Sopenharmony_ci	}
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	/* If needed, import context from software */
5762306a36Sopenharmony_ci	if (import_ctx)
5862306a36Sopenharmony_ci		append_seq_load(desc, ctx_len, LDST_CLASS_2_CCB |
5962306a36Sopenharmony_ci				LDST_SRCDST_BYTE_CONTEXT);
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	/* Class 2 operation */
6262306a36Sopenharmony_ci	append_operation(desc, op | state | OP_ALG_ENCRYPT);
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	/*
6562306a36Sopenharmony_ci	 * Load from buf and/or src and write to req->result or state->context
6662306a36Sopenharmony_ci	 * Calculate remaining bytes to read
6762306a36Sopenharmony_ci	 */
6862306a36Sopenharmony_ci	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
6962306a36Sopenharmony_ci	/* Read remaining bytes */
7062306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_LAST2 |
7162306a36Sopenharmony_ci			     FIFOLD_TYPE_MSG | KEY_VLF);
7262306a36Sopenharmony_ci	/* Store class2 context bytes */
7362306a36Sopenharmony_ci	append_seq_store(desc, digestsize, LDST_CLASS_2_CCB |
7462306a36Sopenharmony_ci			 LDST_SRCDST_BYTE_CONTEXT);
7562306a36Sopenharmony_ci}
7662306a36Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_ahash);
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci/**
7962306a36Sopenharmony_ci * cnstr_shdsc_sk_hash - shared descriptor for symmetric key cipher-based
8062306a36Sopenharmony_ci *                       hash algorithms
8162306a36Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction
8262306a36Sopenharmony_ci * @adata: pointer to authentication transform definitions.
8362306a36Sopenharmony_ci * @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE}
8462306a36Sopenharmony_ci * @digestsize: algorithm's digest size
8562306a36Sopenharmony_ci * @ctx_len: size of Context Register
8662306a36Sopenharmony_ci */
8762306a36Sopenharmony_civoid cnstr_shdsc_sk_hash(u32 * const desc, struct alginfo *adata, u32 state,
8862306a36Sopenharmony_ci			 int digestsize, int ctx_len)
8962306a36Sopenharmony_ci{
9062306a36Sopenharmony_ci	u32 *skip_key_load;
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	/* Skip loading of key, context if already shared */
9562306a36Sopenharmony_ci	skip_key_load = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci	if (state == OP_ALG_AS_INIT || state == OP_ALG_AS_INITFINAL) {
9862306a36Sopenharmony_ci		append_key_as_imm(desc, adata->key_virt, adata->keylen,
9962306a36Sopenharmony_ci				  adata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
10062306a36Sopenharmony_ci	} else { /* UPDATE, FINALIZE */
10162306a36Sopenharmony_ci		if (is_xcbc_aes(adata->algtype))
10262306a36Sopenharmony_ci			/* Load K1 */
10362306a36Sopenharmony_ci			append_key(desc, adata->key_dma, adata->keylen,
10462306a36Sopenharmony_ci				   CLASS_1 | KEY_DEST_CLASS_REG | KEY_ENC);
10562306a36Sopenharmony_ci		else /* CMAC */
10662306a36Sopenharmony_ci			append_key_as_imm(desc, adata->key_virt, adata->keylen,
10762306a36Sopenharmony_ci					  adata->keylen, CLASS_1 |
10862306a36Sopenharmony_ci					  KEY_DEST_CLASS_REG);
10962306a36Sopenharmony_ci		/* Restore context */
11062306a36Sopenharmony_ci		append_seq_load(desc, ctx_len, LDST_CLASS_1_CCB |
11162306a36Sopenharmony_ci				LDST_SRCDST_BYTE_CONTEXT);
11262306a36Sopenharmony_ci	}
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci	set_jump_tgt_here(desc, skip_key_load);
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci	/* Class 1 operation */
11762306a36Sopenharmony_ci	append_operation(desc, adata->algtype | state | OP_ALG_ENCRYPT);
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci	/*
12062306a36Sopenharmony_ci	 * Load from buf and/or src and write to req->result or state->context
12162306a36Sopenharmony_ci	 * Calculate remaining bytes to read
12262306a36Sopenharmony_ci	 */
12362306a36Sopenharmony_ci	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci	/* Read remaining bytes */
12662306a36Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_LAST1 |
12762306a36Sopenharmony_ci			     FIFOLD_TYPE_MSG | FIFOLDST_VLF);
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci	/*
13062306a36Sopenharmony_ci	 * Save context:
13162306a36Sopenharmony_ci	 * - xcbc: partial hash, keys K2 and K3
13262306a36Sopenharmony_ci	 * - cmac: partial hash, constant L = E(K,0)
13362306a36Sopenharmony_ci	 */
13462306a36Sopenharmony_ci	append_seq_store(desc, digestsize, LDST_CLASS_1_CCB |
13562306a36Sopenharmony_ci			 LDST_SRCDST_BYTE_CONTEXT);
13662306a36Sopenharmony_ci	if (is_xcbc_aes(adata->algtype) && state == OP_ALG_AS_INIT)
13762306a36Sopenharmony_ci		/* Save K1 */
13862306a36Sopenharmony_ci		append_fifo_store(desc, adata->key_dma, adata->keylen,
13962306a36Sopenharmony_ci				  LDST_CLASS_1_CCB | FIFOST_TYPE_KEY_KEK);
14062306a36Sopenharmony_ci}
14162306a36Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_sk_hash);
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL");
14462306a36Sopenharmony_ciMODULE_DESCRIPTION("FSL CAAM ahash descriptors support");
14562306a36Sopenharmony_ciMODULE_AUTHOR("NXP Semiconductors");
146