xref: /optee_os/core/drivers/crypto/hisilicon/sec_cipher.c (revision 562874beda99c45a47e8e1927a832ba33c65bc11)
1*562874beSleisen // SPDX-License-Identifier: BSD-2-Clause
2*562874beSleisen /*
3*562874beSleisen  * Copyright 2022-2024 HiSilicon Limited.
4*562874beSleisen  * Kunpeng hardware accelerator sec cipher algorithm implementation.
5*562874beSleisen  */
6*562874beSleisen 
7*562874beSleisen #include <drvcrypt.h>
8*562874beSleisen #include <drvcrypt_cipher.h>
9*562874beSleisen #include <initcall.h>
10*562874beSleisen #include <trace.h>
11*562874beSleisen #include <utee_defines.h>
12*562874beSleisen 
13*562874beSleisen #include "sec_cipher.h"
14*562874beSleisen #include "sec_main.h"
15*562874beSleisen 
sec_do_cipher_task(struct hisi_qp * qp,void * msg)16*562874beSleisen static TEE_Result sec_do_cipher_task(struct hisi_qp *qp, void *msg)
17*562874beSleisen {
18*562874beSleisen 	enum hisi_drv_status ret = HISI_QM_DRVCRYPT_NO_ERR;
19*562874beSleisen 
20*562874beSleisen 	ret = hisi_qp_send(qp, msg);
21*562874beSleisen 	if (ret) {
22*562874beSleisen 		EMSG("Fail to send task, ret=%d", ret);
23*562874beSleisen 		return TEE_ERROR_BAD_STATE;
24*562874beSleisen 	}
25*562874beSleisen 
26*562874beSleisen 	ret = hisi_qp_recv_sync(qp, msg);
27*562874beSleisen 	if (ret) {
28*562874beSleisen 		EMSG("Recv task error, ret=%d", ret);
29*562874beSleisen 		return TEE_ERROR_BAD_STATE;
30*562874beSleisen 	}
31*562874beSleisen 
32*562874beSleisen 	return TEE_SUCCESS;
33*562874beSleisen }
34*562874beSleisen 
sec_cipher_des_get_c_key_len(size_t key_len,uint8_t * c_key_len)35*562874beSleisen static TEE_Result sec_cipher_des_get_c_key_len(size_t key_len,
36*562874beSleisen 					       uint8_t *c_key_len)
37*562874beSleisen {
38*562874beSleisen 	if (key_len == DES_KEY_SIZE) {
39*562874beSleisen 		*c_key_len = CKEY_LEN_DES;
40*562874beSleisen 	} else {
41*562874beSleisen 		EMSG("Invalid DES key size");
42*562874beSleisen 		return TEE_ERROR_BAD_PARAMETERS;
43*562874beSleisen 	}
44*562874beSleisen 
45*562874beSleisen 	return TEE_SUCCESS;
46*562874beSleisen }
47*562874beSleisen 
sec_cipher_3des_get_c_key_len(size_t key_len,uint8_t * c_key_len)48*562874beSleisen static TEE_Result sec_cipher_3des_get_c_key_len(size_t key_len,
49*562874beSleisen 						uint8_t *c_key_len)
50*562874beSleisen {
51*562874beSleisen 	if (key_len == SEC_3DES_2KEY_SIZE) {
52*562874beSleisen 		*c_key_len = CKEY_LEN_3DES_2KEY;
53*562874beSleisen 	} else if (key_len == SEC_3DES_3KEY_SIZE) {
54*562874beSleisen 		*c_key_len = CKEY_LEN_3DES_3KEY;
55*562874beSleisen 	} else {
56*562874beSleisen 		EMSG("Invalid 3DES key size");
57*562874beSleisen 		return TEE_ERROR_BAD_PARAMETERS;
58*562874beSleisen 	}
59*562874beSleisen 
60*562874beSleisen 	return TEE_SUCCESS;
61*562874beSleisen }
62*562874beSleisen 
sec_cipher_aes_get_c_key_len(size_t key_len,enum sec_c_mode mode,uint8_t * c_key_len)63*562874beSleisen static TEE_Result sec_cipher_aes_get_c_key_len(size_t key_len,
64*562874beSleisen 					       enum sec_c_mode mode,
65*562874beSleisen 					       uint8_t *c_key_len)
66*562874beSleisen {
67*562874beSleisen 	switch (mode) {
68*562874beSleisen 	case C_MODE_ECB:
69*562874beSleisen 	case C_MODE_CBC:
70*562874beSleisen 	case C_MODE_CTR:
71*562874beSleisen 		switch (key_len) {
72*562874beSleisen 		case AES_KEYSIZE_128:
73*562874beSleisen 			*c_key_len = CKEY_LEN_128_BIT;
74*562874beSleisen 			break;
75*562874beSleisen 		case AES_KEYSIZE_192:
76*562874beSleisen 			*c_key_len = CKEY_LEN_192_BIT;
77*562874beSleisen 			break;
78*562874beSleisen 		case AES_KEYSIZE_256:
79*562874beSleisen 			*c_key_len = CKEY_LEN_256_BIT;
80*562874beSleisen 			break;
81*562874beSleisen 		default:
82*562874beSleisen 			EMSG("Invalid AES key size");
83*562874beSleisen 			return TEE_ERROR_BAD_PARAMETERS;
84*562874beSleisen 		}
85*562874beSleisen 		break;
86*562874beSleisen 	case C_MODE_XTS:
87*562874beSleisen 		switch (key_len) {
88*562874beSleisen 		case XTS_KEYSIZE_128:
89*562874beSleisen 			*c_key_len = CKEY_LEN_128_BIT;
90*562874beSleisen 			break;
91*562874beSleisen 		case XTS_KEYSIZE_256:
92*562874beSleisen 			*c_key_len = CKEY_LEN_256_BIT;
93*562874beSleisen 			break;
94*562874beSleisen 		default:
95*562874beSleisen 			EMSG("Invalid AES-XTS key size");
96*562874beSleisen 			return TEE_ERROR_BAD_PARAMETERS;
97*562874beSleisen 		}
98*562874beSleisen 		break;
99*562874beSleisen 	default:
100*562874beSleisen 		EMSG("Unsupported AES mode");
101*562874beSleisen 		return TEE_ERROR_BAD_PARAMETERS;
102*562874beSleisen 	}
103*562874beSleisen 
104*562874beSleisen 	return TEE_SUCCESS;
105*562874beSleisen }
106*562874beSleisen 
sec_cipher_sm4_get_c_key_len(size_t key_len,enum sec_c_mode mode,uint8_t * c_key_len)107*562874beSleisen static TEE_Result sec_cipher_sm4_get_c_key_len(size_t key_len,
108*562874beSleisen 					       enum sec_c_mode mode,
109*562874beSleisen 					       uint8_t *c_key_len)
110*562874beSleisen {
111*562874beSleisen 	switch (mode) {
112*562874beSleisen 	case C_MODE_ECB:
113*562874beSleisen 	case C_MODE_CBC:
114*562874beSleisen 	case C_MODE_CTR:
115*562874beSleisen 		if (key_len != AES_KEYSIZE_128) {
116*562874beSleisen 			EMSG("Invalid SM4 key size");
117*562874beSleisen 			return TEE_ERROR_BAD_PARAMETERS;
118*562874beSleisen 		}
119*562874beSleisen 		*c_key_len = CKEY_LEN_128_BIT;
120*562874beSleisen 		break;
121*562874beSleisen 	case C_MODE_XTS:
122*562874beSleisen 		if (key_len != XTS_KEYSIZE_128) {
123*562874beSleisen 			EMSG("Invalid SM4-XTS key size");
124*562874beSleisen 			return TEE_ERROR_BAD_PARAMETERS;
125*562874beSleisen 		}
126*562874beSleisen 		*c_key_len = CKEY_LEN_128_BIT;
127*562874beSleisen 		break;
128*562874beSleisen 	default:
129*562874beSleisen 		EMSG("Unsupported SM4 mode");
130*562874beSleisen 		return TEE_ERROR_BAD_PARAMETERS;
131*562874beSleisen 	}
132*562874beSleisen 
133*562874beSleisen 	return TEE_SUCCESS;
134*562874beSleisen }
135*562874beSleisen 
sec_cipher_set_key(struct sec_cipher_ctx * c_ctx,uint8_t * key1,size_t key1_len,uint8_t * key2,size_t key2_len)136*562874beSleisen static TEE_Result sec_cipher_set_key(struct sec_cipher_ctx *c_ctx,
137*562874beSleisen 				     uint8_t *key1, size_t key1_len,
138*562874beSleisen 				     uint8_t *key2, size_t key2_len)
139*562874beSleisen {
140*562874beSleisen 	size_t key_len = key1_len + key2_len;
141*562874beSleisen 	TEE_Result ret = TEE_SUCCESS;
142*562874beSleisen 	uint8_t c_key_len = 0;
143*562874beSleisen 
144*562874beSleisen 	switch (c_ctx->alg) {
145*562874beSleisen 	case C_ALG_DES:
146*562874beSleisen 		ret = sec_cipher_des_get_c_key_len(key_len, &c_key_len);
147*562874beSleisen 		break;
148*562874beSleisen 	case C_ALG_3DES:
149*562874beSleisen 		ret = sec_cipher_3des_get_c_key_len(key_len, &c_key_len);
150*562874beSleisen 		break;
151*562874beSleisen 	case C_ALG_AES:
152*562874beSleisen 		ret = sec_cipher_aes_get_c_key_len(key_len, c_ctx->mode,
153*562874beSleisen 						   &c_key_len);
154*562874beSleisen 		break;
155*562874beSleisen 	case C_ALG_SM4:
156*562874beSleisen 		ret = sec_cipher_sm4_get_c_key_len(key_len, c_ctx->mode,
157*562874beSleisen 						   &c_key_len);
158*562874beSleisen 		break;
159*562874beSleisen 	default:
160*562874beSleisen 		EMSG("Invalid cipher type %#"PRIx8, c_ctx->alg);
161*562874beSleisen 		ret = TEE_ERROR_NOT_IMPLEMENTED;
162*562874beSleisen 		break;
163*562874beSleisen 	}
164*562874beSleisen 
165*562874beSleisen 	if (ret)
166*562874beSleisen 		return ret;
167*562874beSleisen 
168*562874beSleisen 	c_ctx->key_dma = virt_to_phys(c_ctx->key);
169*562874beSleisen 	if (!c_ctx->key_dma) {
170*562874beSleisen 		EMSG("c_key_dma is NULL");
171*562874beSleisen 		return TEE_ERROR_GENERIC;
172*562874beSleisen 	}
173*562874beSleisen 
174*562874beSleisen 	c_ctx->key_len = key_len;
175*562874beSleisen 	c_ctx->c_key_len = c_key_len;
176*562874beSleisen 
177*562874beSleisen 	memcpy(c_ctx->key, key1, key1_len);
178*562874beSleisen 	memcpy(c_ctx->key + key1_len, key2, key2_len);
179*562874beSleisen 
180*562874beSleisen 	return TEE_SUCCESS;
181*562874beSleisen }
182*562874beSleisen 
ctr_iv_inc(uint64_t * ctr,uint32_t inc)183*562874beSleisen static void ctr_iv_inc(uint64_t *ctr, uint32_t inc)
184*562874beSleisen {
185*562874beSleisen 	uint64_t v0 = TEE_U64_FROM_BIG_ENDIAN(ctr[0]);
186*562874beSleisen 	uint64_t v1 = TEE_U64_FROM_BIG_ENDIAN(ctr[1]);
187*562874beSleisen 
188*562874beSleisen 	/* increment counter (128-bit int) by inc */
189*562874beSleisen 	if (ADD_OVERFLOW(v1, inc, &v1))
190*562874beSleisen 		v0++;
191*562874beSleisen 
192*562874beSleisen 	ctr[0] = TEE_U64_TO_BIG_ENDIAN(v0);
193*562874beSleisen 	ctr[1] = TEE_U64_TO_BIG_ENDIAN(v1);
194*562874beSleisen }
195*562874beSleisen 
xts_multi_galois(unsigned char * data)196*562874beSleisen static void xts_multi_galois(unsigned char *data)
197*562874beSleisen {
198*562874beSleisen 	int i = 0;
199*562874beSleisen 	uint8_t t = 0;
200*562874beSleisen 	uint8_t tt = 0;
201*562874beSleisen 
202*562874beSleisen 	for (i = 0; i < AES_SM4_IV_SIZE; i++) {
203*562874beSleisen 		tt = data[i] >> LEFT_MOST_BIT;
204*562874beSleisen 		data[i] = ((data[i] << 1) | t) & 0xFF;
205*562874beSleisen 		t = tt;
206*562874beSleisen 	}
207*562874beSleisen 	if (tt)
208*562874beSleisen 		data[0] ^= 0x87;
209*562874beSleisen }
210*562874beSleisen 
211*562874beSleisen /*
212*562874beSleisen  * When the IV is delivered by segment,
213*562874beSleisen  * the AES/SM4-ECB is used to update the IV to be used next time.
214*562874beSleisen  */
xts_iv_update(struct sec_cipher_ctx * c_ctx)215*562874beSleisen static TEE_Result xts_iv_update(struct sec_cipher_ctx *c_ctx)
216*562874beSleisen {
217*562874beSleisen 	size_t xts_key_len = c_ctx->key_len / 2;
218*562874beSleisen 	struct sec_cipher_ctx ecb_ctx = { };
219*562874beSleisen 	TEE_Result ret = TEE_SUCCESS;
220*562874beSleisen 	size_t i = 0;
221*562874beSleisen 
222*562874beSleisen 	ecb_ctx.alg = c_ctx->alg;
223*562874beSleisen 	ecb_ctx.mode = C_MODE_ECB;
224*562874beSleisen 	ret = sec_cipher_set_key(&ecb_ctx, c_ctx->key + xts_key_len,
225*562874beSleisen 				 xts_key_len, NULL, 0);
226*562874beSleisen 	if (ret)
227*562874beSleisen 		return ret;
228*562874beSleisen 
229*562874beSleisen 	ecb_ctx.encrypt = true;
230*562874beSleisen 	ecb_ctx.in = (uint8_t *)c_ctx->iv;
231*562874beSleisen 	ecb_ctx.out = (uint8_t *)c_ctx->iv;
232*562874beSleisen 	ecb_ctx.in_dma = c_ctx->iv_dma;
233*562874beSleisen 	ecb_ctx.out_dma = c_ctx->iv_dma;
234*562874beSleisen 	ecb_ctx.len = c_ctx->iv_len;
235*562874beSleisen 
236*562874beSleisen 	ret = sec_do_cipher_task(c_ctx->qp, &ecb_ctx);
237*562874beSleisen 	if (ret) {
238*562874beSleisen 		EMSG("Fail to encrypt xts iv, ret=%#"PRIx32, ret);
239*562874beSleisen 		return ret;
240*562874beSleisen 	}
241*562874beSleisen 
242*562874beSleisen 	for (i = 0; i < DIV_ROUND_UP(c_ctx->len, AES_SM4_BLOCK_SIZE); i++)
243*562874beSleisen 		xts_multi_galois((uint8_t *)c_ctx->iv);
244*562874beSleisen 
245*562874beSleisen 	ecb_ctx.encrypt = false;
246*562874beSleisen 	ret = sec_do_cipher_task(c_ctx->qp, &ecb_ctx);
247*562874beSleisen 	if (ret)
248*562874beSleisen 		EMSG("Fail to decrypt xts iv, ret=%#"PRIx32, ret);
249*562874beSleisen 
250*562874beSleisen 	return ret;
251*562874beSleisen }
252*562874beSleisen 
sec_update_iv(struct sec_cipher_ctx * c_ctx)253*562874beSleisen static TEE_Result sec_update_iv(struct sec_cipher_ctx *c_ctx)
254*562874beSleisen {
255*562874beSleisen 	TEE_Result ret = TEE_SUCCESS;
256*562874beSleisen 	size_t offset = 0;
257*562874beSleisen 
258*562874beSleisen 	switch (c_ctx->mode) {
259*562874beSleisen 	case C_MODE_CBC:
260*562874beSleisen 		offset = c_ctx->len - c_ctx->iv_len;
261*562874beSleisen 		if (c_ctx->encrypt && c_ctx->len >= c_ctx->iv_len)
262*562874beSleisen 			memcpy(c_ctx->iv, c_ctx->out + offset, c_ctx->iv_len);
263*562874beSleisen 		if (!c_ctx->encrypt && c_ctx->len >= c_ctx->iv_len)
264*562874beSleisen 			memcpy(c_ctx->iv, c_ctx->in + offset, c_ctx->iv_len);
265*562874beSleisen 		break;
266*562874beSleisen 	case C_MODE_CTR:
267*562874beSleisen 		/*
268*562874beSleisen 		 * Increase the iv counter with the number of processed blocks.
269*562874beSleisen 		 */
270*562874beSleisen 		ctr_iv_inc(c_ctx->iv, c_ctx->len >> CTR_MODE_LEN_SHIFT);
271*562874beSleisen 		break;
272*562874beSleisen 	case C_MODE_XTS:
273*562874beSleisen 		ret = xts_iv_update(c_ctx);
274*562874beSleisen 		break;
275*562874beSleisen 	default:
276*562874beSleisen 		break;
277*562874beSleisen 	}
278*562874beSleisen 
279*562874beSleisen 	return ret;
280*562874beSleisen }
281*562874beSleisen 
sec_cipher_iv_check(struct sec_cipher_ctx * c_ctx,size_t iv_size)282*562874beSleisen static TEE_Result sec_cipher_iv_check(struct sec_cipher_ctx *c_ctx,
283*562874beSleisen 				      size_t iv_size)
284*562874beSleisen {
285*562874beSleisen 	TEE_Result ret = TEE_ERROR_BAD_PARAMETERS;
286*562874beSleisen 
287*562874beSleisen 	switch (c_ctx->mode) {
288*562874beSleisen 	case C_MODE_ECB:
289*562874beSleisen 		if (!iv_size)
290*562874beSleisen 			ret = TEE_SUCCESS;
291*562874beSleisen 		break;
292*562874beSleisen 	case C_MODE_CBC:
293*562874beSleisen 		if (c_ctx->alg == C_ALG_DES || c_ctx->alg == C_ALG_3DES) {
294*562874beSleisen 			if (iv_size == DES_CBC_IV_SIZE)
295*562874beSleisen 				ret = TEE_SUCCESS;
296*562874beSleisen 			break;
297*562874beSleisen 		}
298*562874beSleisen 		fallthrough;
299*562874beSleisen 	case C_MODE_XTS:
300*562874beSleisen 	case C_MODE_CTR:
301*562874beSleisen 		if (c_ctx->alg == C_ALG_AES || c_ctx->alg == C_ALG_SM4) {
302*562874beSleisen 			if (iv_size == AES_SM4_IV_SIZE)
303*562874beSleisen 				ret = TEE_SUCCESS;
304*562874beSleisen 		}
305*562874beSleisen 		break;
306*562874beSleisen 	default:
307*562874beSleisen 		break;
308*562874beSleisen 	}
309*562874beSleisen 
310*562874beSleisen 	if (ret)
311*562874beSleisen 		EMSG("Fail to check iv_size");
312*562874beSleisen 
313*562874beSleisen 	return ret;
314*562874beSleisen }
315*562874beSleisen 
sec_cipher_set_iv(struct sec_cipher_ctx * c_ctx,uint8_t * iv,size_t iv_len)316*562874beSleisen static TEE_Result sec_cipher_set_iv(struct sec_cipher_ctx *c_ctx,
317*562874beSleisen 				    uint8_t *iv, size_t iv_len)
318*562874beSleisen {
319*562874beSleisen 	TEE_Result ret = TEE_SUCCESS;
320*562874beSleisen 
321*562874beSleisen 	if (!iv && iv_len) {
322*562874beSleisen 		EMSG("iv is NULL");
323*562874beSleisen 		return TEE_ERROR_BAD_PARAMETERS;
324*562874beSleisen 	}
325*562874beSleisen 
326*562874beSleisen 	ret = sec_cipher_iv_check(c_ctx, iv_len);
327*562874beSleisen 	if (ret)
328*562874beSleisen 		return ret;
329*562874beSleisen 
330*562874beSleisen 	c_ctx->iv_len = iv_len;
331*562874beSleisen 	c_ctx->iv_dma = virt_to_phys(c_ctx->iv);
332*562874beSleisen 	if (!c_ctx->iv_dma) {
333*562874beSleisen 		EMSG("c_iv_dma is NULL");
334*562874beSleisen 		return TEE_ERROR_BAD_PARAMETERS;
335*562874beSleisen 	}
336*562874beSleisen 
337*562874beSleisen 	memcpy(c_ctx->iv, iv, c_ctx->iv_len);
338*562874beSleisen 
339*562874beSleisen 	return TEE_SUCCESS;
340*562874beSleisen }
341*562874beSleisen 
sec_cipher_bd_fill(void * bd,void * msg)342*562874beSleisen static enum hisi_drv_status sec_cipher_bd_fill(void *bd, void *msg)
343*562874beSleisen {
344*562874beSleisen 	struct sec_cipher_ctx *c_ctx = msg;
345*562874beSleisen 	struct hisi_sec_sqe *sqe = bd;
346*562874beSleisen 	uint8_t cipher = 0;
347*562874beSleisen 	uint8_t scene = 0;
348*562874beSleisen 	uint8_t de = 0;
349*562874beSleisen 
350*562874beSleisen 	sqe->type_auth_cipher = BD_TYPE2;
351*562874beSleisen 	scene = SHIFT_U32(SCENE_NOTHING, SEC_SCENE_OFFSET);
352*562874beSleisen 	de = SHIFT_U32(DATA_DST_ADDR_ENABLE, SEC_DE_OFFSET);
353*562874beSleisen 	sqe->sds_sa_type = de | scene;
354*562874beSleisen 	sqe->type2.clen_ivhlen = c_ctx->len;
355*562874beSleisen 
356*562874beSleisen 	sqe->type2.c_alg = c_ctx->alg;
357*562874beSleisen 	sqe->type2.icvw_kmode = SHIFT_U32(c_ctx->mode, SEC_CMODE_OFFSET) |
358*562874beSleisen 				SHIFT_U32(c_ctx->c_key_len, SEC_CKEY_OFFSET);
359*562874beSleisen 
360*562874beSleisen 	if (c_ctx->encrypt)
361*562874beSleisen 		cipher = SHIFT_U32(CIPHER_ENCRYPT, SEC_CIPHER_OFFSET);
362*562874beSleisen 	else
363*562874beSleisen 		cipher = SHIFT_U32(CIPHER_DECRYPT, SEC_CIPHER_OFFSET);
364*562874beSleisen 
365*562874beSleisen 	sqe->type_auth_cipher |= cipher;
366*562874beSleisen 
367*562874beSleisen 	sqe->type2.data_dst_addr = c_ctx->out_dma;
368*562874beSleisen 	sqe->type2.data_src_addr = c_ctx->in_dma;
369*562874beSleisen 	sqe->type2.c_key_addr = c_ctx->key_dma;
370*562874beSleisen 	sqe->type2.c_ivin_addr = c_ctx->iv_dma;
371*562874beSleisen 
372*562874beSleisen 	return HISI_QM_DRVCRYPT_NO_ERR;
373*562874beSleisen }
374*562874beSleisen 
sec_cipher_bd_parse(void * bd,void * msg __unused)375*562874beSleisen static enum hisi_drv_status sec_cipher_bd_parse(void *bd, void *msg __unused)
376*562874beSleisen {
377*562874beSleisen 	struct hisi_sec_sqe *sqe = bd;
378*562874beSleisen 	uint16_t done = 0;
379*562874beSleisen 
380*562874beSleisen 	done = SEC_GET_FIELD(sqe->type2.done_flag, SEC_DONE_MASK, 0);
381*562874beSleisen 	if (done != SEC_HW_TASK_DONE || sqe->type2.error_type) {
382*562874beSleisen 		EMSG("SEC BD2 fail! done=%#"PRIx16", etype=%#"PRIx8,
383*562874beSleisen 		     done, sqe->type2.error_type);
384*562874beSleisen 		return HISI_QM_DRVCRYPT_IN_EPARA;
385*562874beSleisen 	}
386*562874beSleisen 
387*562874beSleisen 	return HISI_QM_DRVCRYPT_NO_ERR;
388*562874beSleisen }
389*562874beSleisen 
sec_cipher_bd3_fill(void * bd,void * msg)390*562874beSleisen static enum hisi_drv_status sec_cipher_bd3_fill(void *bd, void *msg)
391*562874beSleisen {
392*562874beSleisen 	struct hisi_sec_bd3_sqe *sqe = bd;
393*562874beSleisen 	struct sec_cipher_ctx *c_ctx = msg;
394*562874beSleisen 
395*562874beSleisen 	sqe->bd_param = BD_TYPE3 | SHIFT_U32(SCENE_NOTHING,
396*562874beSleisen 					     SEC_SCENE_OFFSET_V3) |
397*562874beSleisen 			SHIFT_U32(DATA_DST_ADDR_ENABLE, SEC_DE_OFFSET_V3);
398*562874beSleisen 	sqe->c_len_ivin = c_ctx->len;
399*562874beSleisen 	sqe->c_mode_alg = c_ctx->mode |
400*562874beSleisen 			  SHIFT_U32(c_ctx->alg, SEC_CALG_OFFSET_V3);
401*562874beSleisen 	sqe->c_icv_key = SHIFT_U32(c_ctx->c_key_len, SEC_CKEY_OFFSET_V3);
402*562874beSleisen 
403*562874beSleisen 	if (c_ctx->encrypt)
404*562874beSleisen 		sqe->c_icv_key |= CIPHER_ENCRYPT;
405*562874beSleisen 	else
406*562874beSleisen 		sqe->c_icv_key |= CIPHER_DECRYPT;
407*562874beSleisen 
408*562874beSleisen 	sqe->data_dst_addr = c_ctx->out_dma;
409*562874beSleisen 	sqe->data_src_addr = c_ctx->in_dma;
410*562874beSleisen 	sqe->c_key_addr = c_ctx->key_dma;
411*562874beSleisen 	sqe->no_scene.c_ivin_addr = c_ctx->iv_dma;
412*562874beSleisen 
413*562874beSleisen 	return HISI_QM_DRVCRYPT_NO_ERR;
414*562874beSleisen }
415*562874beSleisen 
sec_cipher_bd3_parse(void * bd,void * msg __unused)416*562874beSleisen static enum hisi_drv_status sec_cipher_bd3_parse(void *bd, void *msg __unused)
417*562874beSleisen {
418*562874beSleisen 	struct hisi_sec_bd3_sqe *sqe = bd;
419*562874beSleisen 	uint16_t done = 0;
420*562874beSleisen 
421*562874beSleisen 	done = SEC_GET_FIELD(sqe->done_flag, SEC_DONE_MASK, 0);
422*562874beSleisen 	if (done != SEC_HW_TASK_DONE || sqe->error_type) {
423*562874beSleisen 		EMSG("SEC BD3 fail! done=%#"PRIx16", etype=%#"PRIx8,
424*562874beSleisen 		     done, sqe->error_type);
425*562874beSleisen 		return HISI_QM_DRVCRYPT_IN_EPARA;
426*562874beSleisen 	}
427*562874beSleisen 
428*562874beSleisen 	return HISI_QM_DRVCRYPT_NO_ERR;
429*562874beSleisen }
430*562874beSleisen 
cipher_algo_check(uint32_t algo)431*562874beSleisen static TEE_Result cipher_algo_check(uint32_t algo)
432*562874beSleisen {
433*562874beSleisen 	switch (algo) {
434*562874beSleisen 	case TEE_ALG_AES_ECB_NOPAD:
435*562874beSleisen 	case TEE_ALG_AES_CBC_NOPAD:
436*562874beSleisen 	case TEE_ALG_AES_CTR:
437*562874beSleisen 	case TEE_ALG_AES_XTS:
438*562874beSleisen 	case TEE_ALG_DES_ECB_NOPAD:
439*562874beSleisen 	case TEE_ALG_DES3_ECB_NOPAD:
440*562874beSleisen 	case TEE_ALG_DES_CBC_NOPAD:
441*562874beSleisen 	case TEE_ALG_DES3_CBC_NOPAD:
442*562874beSleisen 	case TEE_ALG_SM4_CBC_NOPAD:
443*562874beSleisen 	case TEE_ALG_SM4_ECB_NOPAD:
444*562874beSleisen 	case TEE_ALG_SM4_XTS:
445*562874beSleisen 	case TEE_ALG_SM4_CTR:
446*562874beSleisen 		break;
447*562874beSleisen 	default:
448*562874beSleisen 		return TEE_ERROR_NOT_IMPLEMENTED;
449*562874beSleisen 	}
450*562874beSleisen 
451*562874beSleisen 	return TEE_SUCCESS;
452*562874beSleisen }
453*562874beSleisen 
crypto_set_alg(struct sec_cipher_ctx * c_ctx,uint32_t alg)454*562874beSleisen static TEE_Result crypto_set_alg(struct sec_cipher_ctx *c_ctx, uint32_t alg)
455*562874beSleisen {
456*562874beSleisen 	TEE_Result ret = TEE_SUCCESS;
457*562874beSleisen 
458*562874beSleisen 	switch (alg) {
459*562874beSleisen 	case TEE_MAIN_ALGO_DES:
460*562874beSleisen 		c_ctx->alg = C_ALG_DES;
461*562874beSleisen 		break;
462*562874beSleisen 	case TEE_MAIN_ALGO_DES3:
463*562874beSleisen 		c_ctx->alg = C_ALG_3DES;
464*562874beSleisen 		break;
465*562874beSleisen 	case TEE_MAIN_ALGO_AES:
466*562874beSleisen 		c_ctx->alg = C_ALG_AES;
467*562874beSleisen 		break;
468*562874beSleisen 	case TEE_MAIN_ALGO_SM4:
469*562874beSleisen 		c_ctx->alg = C_ALG_SM4;
470*562874beSleisen 		break;
471*562874beSleisen 	default:
472*562874beSleisen 		EMSG("Invalid cipher type %#"PRIx32, alg);
473*562874beSleisen 		ret = TEE_ERROR_NOT_IMPLEMENTED;
474*562874beSleisen 		break;
475*562874beSleisen 	}
476*562874beSleisen 
477*562874beSleisen 	return ret;
478*562874beSleisen }
479*562874beSleisen 
crypto_set_mode(struct sec_cipher_ctx * c_ctx,uint32_t mode)480*562874beSleisen static TEE_Result crypto_set_mode(struct sec_cipher_ctx *c_ctx, uint32_t mode)
481*562874beSleisen {
482*562874beSleisen 	TEE_Result ret = TEE_SUCCESS;
483*562874beSleisen 
484*562874beSleisen 	switch (mode) {
485*562874beSleisen 	case TEE_CHAIN_MODE_ECB_NOPAD:
486*562874beSleisen 		c_ctx->mode = C_MODE_ECB;
487*562874beSleisen 		break;
488*562874beSleisen 	case TEE_CHAIN_MODE_CBC_NOPAD:
489*562874beSleisen 		c_ctx->mode = C_MODE_CBC;
490*562874beSleisen 		break;
491*562874beSleisen 	case TEE_CHAIN_MODE_XTS:
492*562874beSleisen 		c_ctx->mode = C_MODE_XTS;
493*562874beSleisen 		break;
494*562874beSleisen 	case TEE_CHAIN_MODE_CTR:
495*562874beSleisen 		c_ctx->mode = C_MODE_CTR;
496*562874beSleisen 		break;
497*562874beSleisen 	default:
498*562874beSleisen 		EMSG("Invalid cipher mode type %#"PRIx32, mode);
499*562874beSleisen 		ret = TEE_ERROR_NOT_IMPLEMENTED;
500*562874beSleisen 		break;
501*562874beSleisen 	}
502*562874beSleisen 
503*562874beSleisen 	return ret;
504*562874beSleisen }
505*562874beSleisen 
sec_cipher_ctx_allocate(void ** ctx,uint32_t algo)506*562874beSleisen static TEE_Result sec_cipher_ctx_allocate(void **ctx, uint32_t algo)
507*562874beSleisen {
508*562874beSleisen 	struct sec_cipher_ctx *c_ctx = NULL;
509*562874beSleisen 	TEE_Result ret = TEE_SUCCESS;
510*562874beSleisen 
511*562874beSleisen 	if (!ctx) {
512*562874beSleisen 		EMSG("ctx is NULL");
513*562874beSleisen 		return TEE_ERROR_BAD_PARAMETERS;
514*562874beSleisen 	}
515*562874beSleisen 
516*562874beSleisen 	ret = cipher_algo_check(algo);
517*562874beSleisen 	if (ret)
518*562874beSleisen 		return ret;
519*562874beSleisen 
520*562874beSleisen 	c_ctx = calloc(1, sizeof(struct sec_cipher_ctx));
521*562874beSleisen 	if (!c_ctx) {
522*562874beSleisen 		EMSG("c_ctx is NULL");
523*562874beSleisen 		return TEE_ERROR_OUT_OF_MEMORY;
524*562874beSleisen 	}
525*562874beSleisen 
526*562874beSleisen 	ret = crypto_set_alg(c_ctx, TEE_ALG_GET_MAIN_ALG(algo));
527*562874beSleisen 	if (ret)
528*562874beSleisen 		goto free_c_ctx;
529*562874beSleisen 
530*562874beSleisen 	ret = crypto_set_mode(c_ctx, TEE_ALG_GET_CHAIN_MODE(algo));
531*562874beSleisen 	if (ret)
532*562874beSleisen 		goto free_c_ctx;
533*562874beSleisen 
534*562874beSleisen 	c_ctx->qp = sec_create_qp(HISI_QM_CHANNEL_TYPE0);
535*562874beSleisen 	if (!c_ctx->qp) {
536*562874beSleisen 		ret = TEE_ERROR_BUSY;
537*562874beSleisen 		goto free_c_ctx;
538*562874beSleisen 	}
539*562874beSleisen 
540*562874beSleisen 	if (c_ctx->qp->qm->version == HISI_QM_HW_V2) {
541*562874beSleisen 		c_ctx->qp->fill_sqe = sec_cipher_bd_fill;
542*562874beSleisen 		c_ctx->qp->parse_sqe = sec_cipher_bd_parse;
543*562874beSleisen 	} else {
544*562874beSleisen 		c_ctx->qp->fill_sqe = sec_cipher_bd3_fill;
545*562874beSleisen 		c_ctx->qp->parse_sqe = sec_cipher_bd3_parse;
546*562874beSleisen 	}
547*562874beSleisen 
548*562874beSleisen 	c_ctx->offs = 0;
549*562874beSleisen 	*ctx = c_ctx;
550*562874beSleisen 
551*562874beSleisen 	return TEE_SUCCESS;
552*562874beSleisen 
553*562874beSleisen free_c_ctx:
554*562874beSleisen 	free(c_ctx);
555*562874beSleisen 
556*562874beSleisen 	return ret;
557*562874beSleisen }
558*562874beSleisen 
sec_cipher_ctx_free(void * ctx)559*562874beSleisen static void sec_cipher_ctx_free(void *ctx)
560*562874beSleisen {
561*562874beSleisen 	struct sec_cipher_ctx *c_ctx = ctx;
562*562874beSleisen 
563*562874beSleisen 	if (!c_ctx)
564*562874beSleisen 		return;
565*562874beSleisen 
566*562874beSleisen 	hisi_qm_release_qp(c_ctx->qp);
567*562874beSleisen 	memzero_explicit(c_ctx->key, c_ctx->key_len);
568*562874beSleisen 	free(c_ctx);
569*562874beSleisen }
570*562874beSleisen 
sec_cipher_initialize(struct drvcrypt_cipher_init * dinit)571*562874beSleisen static TEE_Result sec_cipher_initialize(struct drvcrypt_cipher_init *dinit)
572*562874beSleisen {
573*562874beSleisen 	struct sec_cipher_ctx *c_ctx = NULL;
574*562874beSleisen 	TEE_Result ret = TEE_SUCCESS;
575*562874beSleisen 
576*562874beSleisen 	if (!dinit || !dinit->ctx || !dinit->key1.data) {
577*562874beSleisen 		EMSG("drvcrypt_cipher init param error");
578*562874beSleisen 		return TEE_ERROR_BAD_PARAMETERS;
579*562874beSleisen 	}
580*562874beSleisen 
581*562874beSleisen 	c_ctx = dinit->ctx;
582*562874beSleisen 
583*562874beSleisen 	ret = sec_cipher_set_key(c_ctx, dinit->key1.data, dinit->key1.length,
584*562874beSleisen 				 dinit->key2.data, dinit->key2.length);
585*562874beSleisen 	if (ret)
586*562874beSleisen 		return ret;
587*562874beSleisen 
588*562874beSleisen 	ret = sec_cipher_set_iv(c_ctx, dinit->iv.data, dinit->iv.length);
589*562874beSleisen 	if (ret)
590*562874beSleisen 		return ret;
591*562874beSleisen 
592*562874beSleisen 	c_ctx->encrypt = dinit->encrypt;
593*562874beSleisen 
594*562874beSleisen 	return TEE_SUCCESS;
595*562874beSleisen }
596*562874beSleisen 
sec_cipher_cryptlen_check(struct sec_cipher_ctx * c_ctx,size_t length)597*562874beSleisen static TEE_Result sec_cipher_cryptlen_check(struct sec_cipher_ctx *c_ctx,
598*562874beSleisen 					    size_t length)
599*562874beSleisen {
600*562874beSleisen 	if (c_ctx->mode == C_MODE_XTS && length < AES_SM4_BLOCK_SIZE) {
601*562874beSleisen 		EMSG("Invalid xts src len");
602*562874beSleisen 		return TEE_ERROR_BAD_PARAMETERS;
603*562874beSleisen 	}
604*562874beSleisen 
605*562874beSleisen 	if ((c_ctx->mode == C_MODE_ECB || c_ctx->mode == C_MODE_CBC) &&
606*562874beSleisen 	    (length & (AES_SM4_BLOCK_SIZE - 1))) {
607*562874beSleisen 		EMSG("Invalid ecb cbc src len");
608*562874beSleisen 		return TEE_ERROR_BAD_PARAMETERS;
609*562874beSleisen 	}
610*562874beSleisen 
611*562874beSleisen 	return TEE_SUCCESS;
612*562874beSleisen }
613*562874beSleisen 
sec_cipher_param_check(struct drvcrypt_cipher_update * dupdate)614*562874beSleisen static TEE_Result sec_cipher_param_check(struct drvcrypt_cipher_update *dupdate)
615*562874beSleisen {
616*562874beSleisen 	struct sec_cipher_ctx *c_ctx = NULL;
617*562874beSleisen 
618*562874beSleisen 	if (!dupdate || !dupdate->src.data || !dupdate->dst.data ||
619*562874beSleisen 	    dupdate->src.length != dupdate->dst.length ||
620*562874beSleisen 	    dupdate->src.length > MAX_CIPHER_LENGTH || !dupdate->src.length) {
621*562874beSleisen 		EMSG("Dupdate input param error");
622*562874beSleisen 		return TEE_ERROR_BAD_PARAMETERS;
623*562874beSleisen 	}
624*562874beSleisen 
625*562874beSleisen 	c_ctx = dupdate->ctx;
626*562874beSleisen 	switch (c_ctx->alg) {
627*562874beSleisen 	case C_ALG_SM4:
628*562874beSleisen 	case C_ALG_AES:
629*562874beSleisen 		if (sec_cipher_cryptlen_check(c_ctx, dupdate->src.length))
630*562874beSleisen 			return TEE_ERROR_BAD_PARAMETERS;
631*562874beSleisen 		break;
632*562874beSleisen 	case C_ALG_DES:
633*562874beSleisen 	case C_ALG_3DES:
634*562874beSleisen 		if (dupdate->src.length % TEE_DES_BLOCK_SIZE) {
635*562874beSleisen 			EMSG("Invalid src len");
636*562874beSleisen 			return TEE_ERROR_BAD_PARAMETERS;
637*562874beSleisen 		}
638*562874beSleisen 		break;
639*562874beSleisen 	default:
640*562874beSleisen 		return TEE_ERROR_BAD_PARAMETERS;
641*562874beSleisen 	}
642*562874beSleisen 
643*562874beSleisen 	return TEE_SUCCESS;
644*562874beSleisen }
645*562874beSleisen 
sec_alloc_buffer(struct sec_cipher_ctx * c_ctx)646*562874beSleisen static TEE_Result sec_alloc_buffer(struct sec_cipher_ctx *c_ctx)
647*562874beSleisen {
648*562874beSleisen 	c_ctx->in = malloc(c_ctx->len);
649*562874beSleisen 	if (!c_ctx->in) {
650*562874beSleisen 		EMSG("Fail to alloc c_in buf");
651*562874beSleisen 		return TEE_ERROR_OUT_OF_MEMORY;
652*562874beSleisen 	}
653*562874beSleisen 
654*562874beSleisen 	c_ctx->in_dma = virt_to_phys(c_ctx->in);
655*562874beSleisen 
656*562874beSleisen 	c_ctx->out = malloc(c_ctx->len);
657*562874beSleisen 	if (!c_ctx->out) {
658*562874beSleisen 		EMSG("Fail to alloc c_out buf");
659*562874beSleisen 		goto free_c_in;
660*562874beSleisen 	}
661*562874beSleisen 
662*562874beSleisen 	c_ctx->out_dma = virt_to_phys(c_ctx->out);
663*562874beSleisen 
664*562874beSleisen 	return TEE_SUCCESS;
665*562874beSleisen 
666*562874beSleisen free_c_in:
667*562874beSleisen 	free(c_ctx->in);
668*562874beSleisen 	c_ctx->in = NULL;
669*562874beSleisen 	return TEE_ERROR_OUT_OF_MEMORY;
670*562874beSleisen }
671*562874beSleisen 
sec_free_buffer(struct sec_cipher_ctx * c_ctx)672*562874beSleisen static void sec_free_buffer(struct sec_cipher_ctx *c_ctx)
673*562874beSleisen {
674*562874beSleisen 	free(c_ctx->in);
675*562874beSleisen 	free(c_ctx->out);
676*562874beSleisen 	c_ctx->in = NULL;
677*562874beSleisen 	c_ctx->out = NULL;
678*562874beSleisen }
679*562874beSleisen 
sec_cipher_update(struct drvcrypt_cipher_update * dupdate)680*562874beSleisen static TEE_Result sec_cipher_update(struct drvcrypt_cipher_update *dupdate)
681*562874beSleisen {
682*562874beSleisen 	struct sec_cipher_ctx *c_ctx = NULL;
683*562874beSleisen 	TEE_Result ret = TEE_SUCCESS;
684*562874beSleisen 	size_t padding_size = 0;
685*562874beSleisen 
686*562874beSleisen 	ret = sec_cipher_param_check(dupdate);
687*562874beSleisen 	if (ret)
688*562874beSleisen 		return ret;
689*562874beSleisen 
690*562874beSleisen 	c_ctx = dupdate->ctx;
691*562874beSleisen 	if (c_ctx->mode == C_MODE_CTR && (c_ctx->offs & CTR_SRC_ALIGN_MASK))
692*562874beSleisen 		padding_size = c_ctx->offs % CTR_SRC_BLOCK_SIZE;
693*562874beSleisen 
694*562874beSleisen 	c_ctx->offs += dupdate->src.length;
695*562874beSleisen 	c_ctx->len = dupdate->src.length + padding_size;
696*562874beSleisen 	ret = sec_alloc_buffer(c_ctx);
697*562874beSleisen 	if (ret)
698*562874beSleisen 		return ret;
699*562874beSleisen 
700*562874beSleisen 	memset(c_ctx->in, 0, padding_size);
701*562874beSleisen 	memcpy(c_ctx->in + padding_size, dupdate->src.data,
702*562874beSleisen 	       dupdate->src.length);
703*562874beSleisen 
704*562874beSleisen 	ret = sec_do_cipher_task(c_ctx->qp, c_ctx);
705*562874beSleisen 	if (ret)
706*562874beSleisen 		goto free_buffer;
707*562874beSleisen 
708*562874beSleisen 	ret = sec_update_iv(c_ctx);
709*562874beSleisen 	if (ret) {
710*562874beSleisen 		EMSG("Fail to update iv, ret=%#"PRIx32, ret);
711*562874beSleisen 		goto free_buffer;
712*562874beSleisen 	}
713*562874beSleisen 
714*562874beSleisen 	memcpy(dupdate->dst.data, c_ctx->out + padding_size,
715*562874beSleisen 	       dupdate->src.length);
716*562874beSleisen 
717*562874beSleisen free_buffer:
718*562874beSleisen 	sec_free_buffer(c_ctx);
719*562874beSleisen 	return ret;
720*562874beSleisen }
721*562874beSleisen 
sec_cipher_final(void * ctx __unused)722*562874beSleisen static void sec_cipher_final(void *ctx __unused)
723*562874beSleisen {
724*562874beSleisen }
725*562874beSleisen 
sec_cipher_copy_state(void * dst_ctx,void * src_ctx)726*562874beSleisen static void sec_cipher_copy_state(void *dst_ctx, void *src_ctx)
727*562874beSleisen {
728*562874beSleisen 	struct sec_cipher_ctx *dst_c_ctx = dst_ctx;
729*562874beSleisen 	struct sec_cipher_ctx *src_c_ctx = src_ctx;
730*562874beSleisen 
731*562874beSleisen 	dst_c_ctx->alg = src_c_ctx->alg;
732*562874beSleisen 	dst_c_ctx->mode = src_c_ctx->mode;
733*562874beSleisen 	dst_c_ctx->encrypt = src_c_ctx->encrypt;
734*562874beSleisen 	dst_c_ctx->offs = src_c_ctx->offs;
735*562874beSleisen 
736*562874beSleisen 	if (src_c_ctx->key_len) {
737*562874beSleisen 		dst_c_ctx->key_len = src_c_ctx->key_len;
738*562874beSleisen 		dst_c_ctx->c_key_len = src_c_ctx->c_key_len;
739*562874beSleisen 		memcpy(dst_c_ctx->key, src_c_ctx->key, dst_c_ctx->key_len);
740*562874beSleisen 		dst_c_ctx->key_dma = virt_to_phys(dst_c_ctx->key);
741*562874beSleisen 	} else {
742*562874beSleisen 		dst_c_ctx->key_len = 0;
743*562874beSleisen 		dst_c_ctx->c_key_len = 0;
744*562874beSleisen 	}
745*562874beSleisen 
746*562874beSleisen 	if (src_c_ctx->iv_len) {
747*562874beSleisen 		dst_c_ctx->iv_len = src_c_ctx->iv_len;
748*562874beSleisen 		memcpy(dst_c_ctx->iv, src_c_ctx->iv, dst_c_ctx->iv_len);
749*562874beSleisen 		dst_c_ctx->iv_dma = virt_to_phys(dst_c_ctx->iv);
750*562874beSleisen 	} else {
751*562874beSleisen 		dst_c_ctx->iv_len = 0;
752*562874beSleisen 	}
753*562874beSleisen }
754*562874beSleisen 
755*562874beSleisen static struct drvcrypt_cipher driver_cipher = {
756*562874beSleisen 	.alloc_ctx = sec_cipher_ctx_allocate,
757*562874beSleisen 	.free_ctx = sec_cipher_ctx_free,
758*562874beSleisen 	.init = sec_cipher_initialize,
759*562874beSleisen 	.update = sec_cipher_update,
760*562874beSleisen 	.final = sec_cipher_final,
761*562874beSleisen 	.copy_state = sec_cipher_copy_state,
762*562874beSleisen };
763*562874beSleisen 
sec_cipher_init(void)764*562874beSleisen static TEE_Result sec_cipher_init(void)
765*562874beSleisen {
766*562874beSleisen 	TEE_Result ret = TEE_SUCCESS;
767*562874beSleisen 
768*562874beSleisen 	ret = drvcrypt_register_cipher(&driver_cipher);
769*562874beSleisen 	if (ret)
770*562874beSleisen 		EMSG("Sec cipher register to crypto fail ret=%#"PRIx32, ret);
771*562874beSleisen 
772*562874beSleisen 	return ret;
773*562874beSleisen }
774*562874beSleisen driver_init(sec_cipher_init);
775