18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Shared descriptors for ahash algorithms
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright 2017-2019 NXP
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#include "compat.h"
98c2ecf20Sopenharmony_ci#include "desc_constr.h"
108c2ecf20Sopenharmony_ci#include "caamhash_desc.h"
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci/**
138c2ecf20Sopenharmony_ci * cnstr_shdsc_ahash - ahash shared descriptor
148c2ecf20Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction
158c2ecf20Sopenharmony_ci * @adata: pointer to authentication transform definitions.
168c2ecf20Sopenharmony_ci *         A split key is required for SEC Era < 6; the size of the split key
178c2ecf20Sopenharmony_ci *         is specified in this case.
188c2ecf20Sopenharmony_ci *         Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1, SHA224,
198c2ecf20Sopenharmony_ci *         SHA256, SHA384, SHA512}.
208c2ecf20Sopenharmony_ci * @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE}
218c2ecf20Sopenharmony_ci * @digestsize: algorithm's digest size
228c2ecf20Sopenharmony_ci * @ctx_len: size of Context Register
238c2ecf20Sopenharmony_ci * @import_ctx: true if previous Context Register needs to be restored
248c2ecf20Sopenharmony_ci *              must be true for ahash update and final
258c2ecf20Sopenharmony_ci *              must be false for for ahash first and digest
268c2ecf20Sopenharmony_ci * @era: SEC Era
278c2ecf20Sopenharmony_ci */
288c2ecf20Sopenharmony_civoid cnstr_shdsc_ahash(u32 * const desc, struct alginfo *adata, u32 state,
298c2ecf20Sopenharmony_ci		       int digestsize, int ctx_len, bool import_ctx, int era)
308c2ecf20Sopenharmony_ci{
318c2ecf20Sopenharmony_ci	u32 op = adata->algtype;
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci	init_sh_desc(desc, HDR_SHARE_SERIAL);
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	/* Append key if it has been set; ahash update excluded */
368c2ecf20Sopenharmony_ci	if (state != OP_ALG_AS_UPDATE && adata->keylen) {
378c2ecf20Sopenharmony_ci		u32 *skip_key_load;
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci		/* Skip key loading if already shared */
408c2ecf20Sopenharmony_ci		skip_key_load = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
418c2ecf20Sopenharmony_ci					    JUMP_COND_SHRD);
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci		if (era < 6)
448c2ecf20Sopenharmony_ci			append_key_as_imm(desc, adata->key_virt,
458c2ecf20Sopenharmony_ci					  adata->keylen_pad,
468c2ecf20Sopenharmony_ci					  adata->keylen, CLASS_2 |
478c2ecf20Sopenharmony_ci					  KEY_DEST_MDHA_SPLIT | KEY_ENC);
488c2ecf20Sopenharmony_ci		else
498c2ecf20Sopenharmony_ci			append_proto_dkp(desc, adata);
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci		set_jump_tgt_here(desc, skip_key_load);
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci		op |= OP_ALG_AAI_HMAC_PRECOMP;
548c2ecf20Sopenharmony_ci	}
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	/* If needed, import context from software */
578c2ecf20Sopenharmony_ci	if (import_ctx)
588c2ecf20Sopenharmony_ci		append_seq_load(desc, ctx_len, LDST_CLASS_2_CCB |
598c2ecf20Sopenharmony_ci				LDST_SRCDST_BYTE_CONTEXT);
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci	/* Class 2 operation */
628c2ecf20Sopenharmony_ci	append_operation(desc, op | state | OP_ALG_ENCRYPT);
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci	/*
658c2ecf20Sopenharmony_ci	 * Load from buf and/or src and write to req->result or state->context
668c2ecf20Sopenharmony_ci	 * Calculate remaining bytes to read
678c2ecf20Sopenharmony_ci	 */
688c2ecf20Sopenharmony_ci	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
698c2ecf20Sopenharmony_ci	/* Read remaining bytes */
708c2ecf20Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_LAST2 |
718c2ecf20Sopenharmony_ci			     FIFOLD_TYPE_MSG | KEY_VLF);
728c2ecf20Sopenharmony_ci	/* Store class2 context bytes */
738c2ecf20Sopenharmony_ci	append_seq_store(desc, digestsize, LDST_CLASS_2_CCB |
748c2ecf20Sopenharmony_ci			 LDST_SRCDST_BYTE_CONTEXT);
758c2ecf20Sopenharmony_ci}
768c2ecf20Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_ahash);
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci/**
798c2ecf20Sopenharmony_ci * cnstr_shdsc_sk_hash - shared descriptor for symmetric key cipher-based
808c2ecf20Sopenharmony_ci *                       hash algorithms
818c2ecf20Sopenharmony_ci * @desc: pointer to buffer used for descriptor construction
828c2ecf20Sopenharmony_ci * @adata: pointer to authentication transform definitions.
838c2ecf20Sopenharmony_ci * @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE}
848c2ecf20Sopenharmony_ci * @digestsize: algorithm's digest size
858c2ecf20Sopenharmony_ci * @ctx_len: size of Context Register
868c2ecf20Sopenharmony_ci */
878c2ecf20Sopenharmony_civoid cnstr_shdsc_sk_hash(u32 * const desc, struct alginfo *adata, u32 state,
888c2ecf20Sopenharmony_ci			 int digestsize, int ctx_len)
898c2ecf20Sopenharmony_ci{
908c2ecf20Sopenharmony_ci	u32 *skip_key_load;
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	/* Skip loading of key, context if already shared */
958c2ecf20Sopenharmony_ci	skip_key_load = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci	if (state == OP_ALG_AS_INIT || state == OP_ALG_AS_INITFINAL) {
988c2ecf20Sopenharmony_ci		append_key_as_imm(desc, adata->key_virt, adata->keylen,
998c2ecf20Sopenharmony_ci				  adata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
1008c2ecf20Sopenharmony_ci	} else { /* UPDATE, FINALIZE */
1018c2ecf20Sopenharmony_ci		if (is_xcbc_aes(adata->algtype))
1028c2ecf20Sopenharmony_ci			/* Load K1 */
1038c2ecf20Sopenharmony_ci			append_key(desc, adata->key_dma, adata->keylen,
1048c2ecf20Sopenharmony_ci				   CLASS_1 | KEY_DEST_CLASS_REG | KEY_ENC);
1058c2ecf20Sopenharmony_ci		else /* CMAC */
1068c2ecf20Sopenharmony_ci			append_key_as_imm(desc, adata->key_virt, adata->keylen,
1078c2ecf20Sopenharmony_ci					  adata->keylen, CLASS_1 |
1088c2ecf20Sopenharmony_ci					  KEY_DEST_CLASS_REG);
1098c2ecf20Sopenharmony_ci		/* Restore context */
1108c2ecf20Sopenharmony_ci		append_seq_load(desc, ctx_len, LDST_CLASS_1_CCB |
1118c2ecf20Sopenharmony_ci				LDST_SRCDST_BYTE_CONTEXT);
1128c2ecf20Sopenharmony_ci	}
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ci	set_jump_tgt_here(desc, skip_key_load);
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci	/* Class 1 operation */
1178c2ecf20Sopenharmony_ci	append_operation(desc, adata->algtype | state | OP_ALG_ENCRYPT);
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci	/*
1208c2ecf20Sopenharmony_ci	 * Load from buf and/or src and write to req->result or state->context
1218c2ecf20Sopenharmony_ci	 * Calculate remaining bytes to read
1228c2ecf20Sopenharmony_ci	 */
1238c2ecf20Sopenharmony_ci	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci	/* Read remaining bytes */
1268c2ecf20Sopenharmony_ci	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_LAST1 |
1278c2ecf20Sopenharmony_ci			     FIFOLD_TYPE_MSG | FIFOLDST_VLF);
1288c2ecf20Sopenharmony_ci
1298c2ecf20Sopenharmony_ci	/*
1308c2ecf20Sopenharmony_ci	 * Save context:
1318c2ecf20Sopenharmony_ci	 * - xcbc: partial hash, keys K2 and K3
1328c2ecf20Sopenharmony_ci	 * - cmac: partial hash, constant L = E(K,0)
1338c2ecf20Sopenharmony_ci	 */
1348c2ecf20Sopenharmony_ci	append_seq_store(desc, digestsize, LDST_CLASS_1_CCB |
1358c2ecf20Sopenharmony_ci			 LDST_SRCDST_BYTE_CONTEXT);
1368c2ecf20Sopenharmony_ci	if (is_xcbc_aes(adata->algtype) && state == OP_ALG_AS_INIT)
1378c2ecf20Sopenharmony_ci		/* Save K1 */
1388c2ecf20Sopenharmony_ci		append_fifo_store(desc, adata->key_dma, adata->keylen,
1398c2ecf20Sopenharmony_ci				  LDST_CLASS_1_CCB | FIFOST_TYPE_KEY_KEK);
1408c2ecf20Sopenharmony_ci}
1418c2ecf20Sopenharmony_ciEXPORT_SYMBOL(cnstr_shdsc_sk_hash);
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL");
1448c2ecf20Sopenharmony_ciMODULE_DESCRIPTION("FSL CAAM ahash descriptors support");
1458c2ecf20Sopenharmony_ciMODULE_AUTHOR("NXP Semiconductors");
146