xref: /OK3568_Linux_fs/kernel/drivers/crypto/caam/caamhash_desc.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Shared descriptors for ahash algorithms
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright 2017-2019 NXP
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include "compat.h"
9*4882a593Smuzhiyun #include "desc_constr.h"
10*4882a593Smuzhiyun #include "caamhash_desc.h"
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun /**
13*4882a593Smuzhiyun  * cnstr_shdsc_ahash - ahash shared descriptor
14*4882a593Smuzhiyun  * @desc: pointer to buffer used for descriptor construction
15*4882a593Smuzhiyun  * @adata: pointer to authentication transform definitions.
16*4882a593Smuzhiyun  *         A split key is required for SEC Era < 6; the size of the split key
17*4882a593Smuzhiyun  *         is specified in this case.
18*4882a593Smuzhiyun  *         Valid algorithm values - one of OP_ALG_ALGSEL_{MD5, SHA1, SHA224,
19*4882a593Smuzhiyun  *         SHA256, SHA384, SHA512}.
20*4882a593Smuzhiyun  * @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE}
21*4882a593Smuzhiyun  * @digestsize: algorithm's digest size
22*4882a593Smuzhiyun  * @ctx_len: size of Context Register
23*4882a593Smuzhiyun  * @import_ctx: true if previous Context Register needs to be restored
24*4882a593Smuzhiyun  *              must be true for ahash update and final
25*4882a593Smuzhiyun  *              must be false for for ahash first and digest
26*4882a593Smuzhiyun  * @era: SEC Era
27*4882a593Smuzhiyun  */
cnstr_shdsc_ahash(u32 * const desc,struct alginfo * adata,u32 state,int digestsize,int ctx_len,bool import_ctx,int era)28*4882a593Smuzhiyun void cnstr_shdsc_ahash(u32 * const desc, struct alginfo *adata, u32 state,
29*4882a593Smuzhiyun 		       int digestsize, int ctx_len, bool import_ctx, int era)
30*4882a593Smuzhiyun {
31*4882a593Smuzhiyun 	u32 op = adata->algtype;
32*4882a593Smuzhiyun 
33*4882a593Smuzhiyun 	init_sh_desc(desc, HDR_SHARE_SERIAL);
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun 	/* Append key if it has been set; ahash update excluded */
36*4882a593Smuzhiyun 	if (state != OP_ALG_AS_UPDATE && adata->keylen) {
37*4882a593Smuzhiyun 		u32 *skip_key_load;
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun 		/* Skip key loading if already shared */
40*4882a593Smuzhiyun 		skip_key_load = append_jump(desc, JUMP_JSL | JUMP_TEST_ALL |
41*4882a593Smuzhiyun 					    JUMP_COND_SHRD);
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 		if (era < 6)
44*4882a593Smuzhiyun 			append_key_as_imm(desc, adata->key_virt,
45*4882a593Smuzhiyun 					  adata->keylen_pad,
46*4882a593Smuzhiyun 					  adata->keylen, CLASS_2 |
47*4882a593Smuzhiyun 					  KEY_DEST_MDHA_SPLIT | KEY_ENC);
48*4882a593Smuzhiyun 		else
49*4882a593Smuzhiyun 			append_proto_dkp(desc, adata);
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun 		set_jump_tgt_here(desc, skip_key_load);
52*4882a593Smuzhiyun 
53*4882a593Smuzhiyun 		op |= OP_ALG_AAI_HMAC_PRECOMP;
54*4882a593Smuzhiyun 	}
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 	/* If needed, import context from software */
57*4882a593Smuzhiyun 	if (import_ctx)
58*4882a593Smuzhiyun 		append_seq_load(desc, ctx_len, LDST_CLASS_2_CCB |
59*4882a593Smuzhiyun 				LDST_SRCDST_BYTE_CONTEXT);
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun 	/* Class 2 operation */
62*4882a593Smuzhiyun 	append_operation(desc, op | state | OP_ALG_ENCRYPT);
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 	/*
65*4882a593Smuzhiyun 	 * Load from buf and/or src and write to req->result or state->context
66*4882a593Smuzhiyun 	 * Calculate remaining bytes to read
67*4882a593Smuzhiyun 	 */
68*4882a593Smuzhiyun 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
69*4882a593Smuzhiyun 	/* Read remaining bytes */
70*4882a593Smuzhiyun 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS2 | FIFOLD_TYPE_LAST2 |
71*4882a593Smuzhiyun 			     FIFOLD_TYPE_MSG | KEY_VLF);
72*4882a593Smuzhiyun 	/* Store class2 context bytes */
73*4882a593Smuzhiyun 	append_seq_store(desc, digestsize, LDST_CLASS_2_CCB |
74*4882a593Smuzhiyun 			 LDST_SRCDST_BYTE_CONTEXT);
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun EXPORT_SYMBOL(cnstr_shdsc_ahash);
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun /**
79*4882a593Smuzhiyun  * cnstr_shdsc_sk_hash - shared descriptor for symmetric key cipher-based
80*4882a593Smuzhiyun  *                       hash algorithms
81*4882a593Smuzhiyun  * @desc: pointer to buffer used for descriptor construction
82*4882a593Smuzhiyun  * @adata: pointer to authentication transform definitions.
83*4882a593Smuzhiyun  * @state: algorithm state OP_ALG_AS_{INIT, FINALIZE, INITFINALIZE, UPDATE}
84*4882a593Smuzhiyun  * @digestsize: algorithm's digest size
85*4882a593Smuzhiyun  * @ctx_len: size of Context Register
86*4882a593Smuzhiyun  */
cnstr_shdsc_sk_hash(u32 * const desc,struct alginfo * adata,u32 state,int digestsize,int ctx_len)87*4882a593Smuzhiyun void cnstr_shdsc_sk_hash(u32 * const desc, struct alginfo *adata, u32 state,
88*4882a593Smuzhiyun 			 int digestsize, int ctx_len)
89*4882a593Smuzhiyun {
90*4882a593Smuzhiyun 	u32 *skip_key_load;
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 	init_sh_desc(desc, HDR_SHARE_SERIAL | HDR_SAVECTX);
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun 	/* Skip loading of key, context if already shared */
95*4882a593Smuzhiyun 	skip_key_load = append_jump(desc, JUMP_TEST_ALL | JUMP_COND_SHRD);
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun 	if (state == OP_ALG_AS_INIT || state == OP_ALG_AS_INITFINAL) {
98*4882a593Smuzhiyun 		append_key_as_imm(desc, adata->key_virt, adata->keylen,
99*4882a593Smuzhiyun 				  adata->keylen, CLASS_1 | KEY_DEST_CLASS_REG);
100*4882a593Smuzhiyun 	} else { /* UPDATE, FINALIZE */
101*4882a593Smuzhiyun 		if (is_xcbc_aes(adata->algtype))
102*4882a593Smuzhiyun 			/* Load K1 */
103*4882a593Smuzhiyun 			append_key(desc, adata->key_dma, adata->keylen,
104*4882a593Smuzhiyun 				   CLASS_1 | KEY_DEST_CLASS_REG | KEY_ENC);
105*4882a593Smuzhiyun 		else /* CMAC */
106*4882a593Smuzhiyun 			append_key_as_imm(desc, adata->key_virt, adata->keylen,
107*4882a593Smuzhiyun 					  adata->keylen, CLASS_1 |
108*4882a593Smuzhiyun 					  KEY_DEST_CLASS_REG);
109*4882a593Smuzhiyun 		/* Restore context */
110*4882a593Smuzhiyun 		append_seq_load(desc, ctx_len, LDST_CLASS_1_CCB |
111*4882a593Smuzhiyun 				LDST_SRCDST_BYTE_CONTEXT);
112*4882a593Smuzhiyun 	}
113*4882a593Smuzhiyun 
114*4882a593Smuzhiyun 	set_jump_tgt_here(desc, skip_key_load);
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	/* Class 1 operation */
117*4882a593Smuzhiyun 	append_operation(desc, adata->algtype | state | OP_ALG_ENCRYPT);
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 	/*
120*4882a593Smuzhiyun 	 * Load from buf and/or src and write to req->result or state->context
121*4882a593Smuzhiyun 	 * Calculate remaining bytes to read
122*4882a593Smuzhiyun 	 */
123*4882a593Smuzhiyun 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
124*4882a593Smuzhiyun 
125*4882a593Smuzhiyun 	/* Read remaining bytes */
126*4882a593Smuzhiyun 	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_CLASS1 | FIFOLD_TYPE_LAST1 |
127*4882a593Smuzhiyun 			     FIFOLD_TYPE_MSG | FIFOLDST_VLF);
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	/*
130*4882a593Smuzhiyun 	 * Save context:
131*4882a593Smuzhiyun 	 * - xcbc: partial hash, keys K2 and K3
132*4882a593Smuzhiyun 	 * - cmac: partial hash, constant L = E(K,0)
133*4882a593Smuzhiyun 	 */
134*4882a593Smuzhiyun 	append_seq_store(desc, digestsize, LDST_CLASS_1_CCB |
135*4882a593Smuzhiyun 			 LDST_SRCDST_BYTE_CONTEXT);
136*4882a593Smuzhiyun 	if (is_xcbc_aes(adata->algtype) && state == OP_ALG_AS_INIT)
137*4882a593Smuzhiyun 		/* Save K1 */
138*4882a593Smuzhiyun 		append_fifo_store(desc, adata->key_dma, adata->keylen,
139*4882a593Smuzhiyun 				  LDST_CLASS_1_CCB | FIFOST_TYPE_KEY_KEK);
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun EXPORT_SYMBOL(cnstr_shdsc_sk_hash);
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun MODULE_LICENSE("Dual BSD/GPL");
144*4882a593Smuzhiyun MODULE_DESCRIPTION("FSL CAAM ahash descriptors support");
145*4882a593Smuzhiyun MODULE_AUTHOR("NXP Semiconductors");
146