10efa7579SHoria Geantă // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
20efa7579SHoria Geantă /*
30efa7579SHoria Geantă  * Shared descriptors for ahash algorithms
40efa7579SHoria Geantă  *
587870cfbSIuliana Prodan  * Copyright 2017-2019 NXP
60efa7579SHoria Geantă  */
70efa7579SHoria Geantă 
80efa7579SHoria Geantă #include "compat.h"
90efa7579SHoria Geantă #include "desc_constr.h"
100efa7579SHoria Geantă #include "caamhash_desc.h"
110efa7579SHoria Geantă 
120efa7579SHoria Geantă /**
130efa7579SHoria Geantă  * cnstr_shdsc_ahash - ahash shared descriptor
140efa7579SHoria Geantă  * @desc: pointer to buffer used for descriptor construction
150efa7579SHoria Geantă  * @adata: pointer to authentication transform definitions.
160efa7579SHoria Geantă  *         A split key is required for SEC Era < 6; the size of the split key
170efa7579SHoria Geantă  *         is specified in this case.
180efa7579SHoria Geantă  *         Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1, SHA224,
190efa7579SHoria Geantă  *         SHA256, SHA384, SHA512}.
200efa7579SHoria Geantă  * @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE}
210efa7579SHoria Geantă  * @digestsize: algorithm's digest size
220efa7579SHoria Geantă  * @ctx_len: size of Context Register
230efa7579SHoria Geantă  * @import_ctx: true if previous Context Register needs to be restored
240efa7579SHoria Geantă  *              must be true for ahash update and final
25*a89db059SJiang Jian  *              must be false for ahash first and digest
260efa7579SHoria Geantă  * @era: SEC Era
270efa7579SHoria Geantă  */
cnstr_shdsc_ahash(u32 * const desc,struct alginfo * adata,u32 state,int digestsize,int ctx_len,bool import_ctx,int era)280efa7579SHoria Geantă void cnstr_shdsc_ahash(u32 * const desc, struct alginfo *adata, u32 state,
290efa7579SHoria Geantă 		       int digestsize, int ctx_len, bool import_ctx, int era)
300efa7579SHoria Geantă {
310efa7579SHoria Geantă 	u32 op = adata->algtype;
320efa7579SHoria Geantă 
330efa7579SHoria Geantă 	init_sh_desc(desc, HDR_SHARE_SERIAL);
340efa7579SHoria Geantă 
350efa7579SHoria Geantă 	/* Append key if it has been set; ahash update excluded */
360efa7579SHoria Geantă 	if (state != OP_ALG_AS_UPDATE && adata->keylen) {
370efa7579SHoria Geantă 		u32 *skip_key_load;
380efa7579SHoria Geantă 
390efa7579SHoria Geantă 		/* Skip key loading if already shared */
400efa7579SHoria Geantă 		skip_key_load = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
410efa7579SHoria Geantă 					    JUMP_COND_SHRD);
420efa7579SHoria Geantă 
430efa7579SHoria Geantă 		if (era < 6)
440efa7579SHoria Geantă 			append_key_as_imm(desc, adata->key_virt,
450efa7579SHoria Geantă 					  adata->keylen_pad,
460efa7579SHoria Geantă 					  adata->keylen, CLASS_2 |
470efa7579SHoria Geantă 					  KEY_DEST_MDHA_SPLIT | KEY_ENC);
480efa7579SHoria Geantă 		else
490efa7579SHoria Geantă 			append_proto_dkp(desc, adata);
500efa7579SHoria Geantă 
510efa7579SHoria Geantă 		set_jump_tgt_here(desc, skip_key_load);
520efa7579SHoria Geantă 
530efa7579SHoria Geantă 		op |= OP_ALG_AAI_HMAC_PRECOMP;
540efa7579SHoria Geantă 	}
550efa7579SHoria Geantă 
560efa7579SHoria Geantă 	/* If needed, import context from software */
570efa7579SHoria Geantă 	if (import_ctx)
580efa7579SHoria Geantă 		append_seq_load(desc, ctx_len, LDST_CLASS_2_CCB |
590efa7579SHoria Geantă 				LDST_SRCDST_BYTE_CONTEXT);
600efa7579SHoria Geantă 
610efa7579SHoria Geantă 	/* Class 2 operation */
620efa7579SHoria Geantă 	append_operation(desc, op | state | OP_ALG_ENCRYPT);
630efa7579SHoria Geantă 
640efa7579SHoria Geantă 	/*
650efa7579SHoria Geantă 	 * Load from buf and/or src and write to req->result or state->context
660efa7579SHoria Geantă 	 * Calculate remaining bytes to read
670efa7579SHoria Geantă 	 */
680efa7579SHoria Geantă 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
690efa7579SHoria Geantă 	/* Read remaining bytes */
700efa7579SHoria Geantă 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_LAST2 |
710efa7579SHoria Geantă 			     FIFOLD_TYPE_MSG | KEY_VLF);
720efa7579SHoria Geantă 	/* Store class2 context bytes */
730efa7579SHoria Geantă 	append_seq_store(desc, digestsize, LDST_CLASS_2_CCB |
740efa7579SHoria Geantă 			 LDST_SRCDST_BYTE_CONTEXT);
750efa7579SHoria Geantă }
760efa7579SHoria Geantă EXPORT_SYMBOL(cnstr_shdsc_ahash);
770efa7579SHoria Geantă 
7812b8567fSIuliana Prodan /**
7987870cfbSIuliana Prodan  * cnstr_shdsc_sk_hash - shared descriptor for symmetric key cipher-based
8087870cfbSIuliana Prodan  *                       hash algorithms
8112b8567fSIuliana Prodan  * @desc: pointer to buffer used for descriptor construction
8212b8567fSIuliana Prodan  * @adata: pointer to authentication transform definitions.
8312b8567fSIuliana Prodan  * @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE}
8412b8567fSIuliana Prodan  * @digestsize: algorithm's digest size
8512b8567fSIuliana Prodan  * @ctx_len: size of Context Register
8612b8567fSIuliana Prodan  */
cnstr_shdsc_sk_hash(u32 * const desc,struct alginfo * adata,u32 state,int digestsize,int ctx_len)8787870cfbSIuliana Prodan void cnstr_shdsc_sk_hash(u32 * const desc, struct alginfo *adata, u32 state,
88a2fb864cSHoria Geantă 			 int digestsize, int ctx_len)
8912b8567fSIuliana Prodan {
9012b8567fSIuliana Prodan 	u32 *skip_key_load;
9112b8567fSIuliana Prodan 
9212b8567fSIuliana Prodan 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
9312b8567fSIuliana Prodan 
9412b8567fSIuliana Prodan 	/* Skip loading of key, context if already shared */
9512b8567fSIuliana Prodan 	skip_key_load = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
9612b8567fSIuliana Prodan 
9712b8567fSIuliana Prodan 	if (state == OP_ALG_AS_INIT || state == OP_ALG_AS_INITFINAL) {
9812b8567fSIuliana Prodan 		append_key_as_imm(desc, adata->key_virt, adata->keylen,
9912b8567fSIuliana Prodan 				  adata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
10012b8567fSIuliana Prodan 	} else { /* UPDATE, FINALIZE */
10187870cfbSIuliana Prodan 		if (is_xcbc_aes(adata->algtype))
10212b8567fSIuliana Prodan 			/* Load K1 */
10312b8567fSIuliana Prodan 			append_key(desc, adata->key_dma, adata->keylen,
10412b8567fSIuliana Prodan 				   CLASS_1 | KEY_DEST_CLASS_REG | KEY_ENC);
10587870cfbSIuliana Prodan 		else /* CMAC */
10687870cfbSIuliana Prodan 			append_key_as_imm(desc, adata->key_virt, adata->keylen,
10787870cfbSIuliana Prodan 					  adata->keylen, CLASS_1 |
10887870cfbSIuliana Prodan 					  KEY_DEST_CLASS_REG);
10912b8567fSIuliana Prodan 		/* Restore context */
11012b8567fSIuliana Prodan 		append_seq_load(desc, ctx_len, LDST_CLASS_1_CCB |
11112b8567fSIuliana Prodan 				LDST_SRCDST_BYTE_CONTEXT);
11212b8567fSIuliana Prodan 	}
11312b8567fSIuliana Prodan 
11412b8567fSIuliana Prodan 	set_jump_tgt_here(desc, skip_key_load);
11512b8567fSIuliana Prodan 
11612b8567fSIuliana Prodan 	/* Class 1 operation */
11712b8567fSIuliana Prodan 	append_operation(desc, adata->algtype | state | OP_ALG_ENCRYPT);
11812b8567fSIuliana Prodan 
11912b8567fSIuliana Prodan 	/*
12012b8567fSIuliana Prodan 	 * Load from buf and/or src and write to req->result or state->context
12112b8567fSIuliana Prodan 	 * Calculate remaining bytes to read
12212b8567fSIuliana Prodan 	 */
12312b8567fSIuliana Prodan 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
12412b8567fSIuliana Prodan 
12512b8567fSIuliana Prodan 	/* Read remaining bytes */
12612b8567fSIuliana Prodan 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_LAST1 |
12712b8567fSIuliana Prodan 			     FIFOLD_TYPE_MSG | FIFOLDST_VLF);
12812b8567fSIuliana Prodan 
12987870cfbSIuliana Prodan 	/*
13087870cfbSIuliana Prodan 	 * Save context:
13187870cfbSIuliana Prodan 	 * - xcbc: partial hash, keys K2 and K3
13287870cfbSIuliana Prodan 	 * - cmac: partial hash, constant L = E(K,0)
13387870cfbSIuliana Prodan 	 */
13412b8567fSIuliana Prodan 	append_seq_store(desc, digestsize, LDST_CLASS_1_CCB |
13512b8567fSIuliana Prodan 			 LDST_SRCDST_BYTE_CONTEXT);
13687870cfbSIuliana Prodan 	if (is_xcbc_aes(adata->algtype) && state == OP_ALG_AS_INIT)
13712b8567fSIuliana Prodan 		/* Save K1 */
138a2fb864cSHoria Geantă 		append_fifo_store(desc, adata->key_dma, adata->keylen,
13912b8567fSIuliana Prodan 				  LDST_CLASS_1_CCB | FIFOST_TYPE_KEY_KEK);
14012b8567fSIuliana Prodan }
14187870cfbSIuliana Prodan EXPORT_SYMBOL(cnstr_shdsc_sk_hash);
14212b8567fSIuliana Prodan 
1430efa7579SHoria Geantă MODULE_LICENSE("Dual BSD/GPL");
1440efa7579SHoria Geantă MODULE_DESCRIPTION("FSL CAAM ahash descriptors support");
1450efa7579SHoria Geantă MODULE_AUTHOR("NXP Semiconductors");
146