xref: /optee_os/core/drivers/crypto/hisilicon/hpre_ecc.c (revision 8448708b940452a529bba3b669b200e7714f41cb)
1b32598bfSZexi Yu // SPDX-License-Identifier: BSD-2-Clause
2b32598bfSZexi Yu /*
3b32598bfSZexi Yu  * Copyright (c) 2022, HiSilicon Technologies Co., Ltd.
4b32598bfSZexi Yu  * Kunpeng hardware accelerator hpre ecc algorithm implementation.
5b32598bfSZexi Yu  */
6b32598bfSZexi Yu #include <drvcrypt.h>
7b32598bfSZexi Yu #include <drvcrypt_acipher.h>
8b32598bfSZexi Yu #include <initcall.h>
9b32598bfSZexi Yu #include <malloc.h>
10b32598bfSZexi Yu #include <rng_support.h>
11b32598bfSZexi Yu #include <stdlib_ext.h>
12b32598bfSZexi Yu #include <string.h>
13b32598bfSZexi Yu #include <string_ext.h>
14b32598bfSZexi Yu #include <trace.h>
15b32598bfSZexi Yu 
16b32598bfSZexi Yu #include "hpre_main.h"
17b32598bfSZexi Yu #include "hpre_ecc.h"
18b32598bfSZexi Yu 
19b32598bfSZexi Yu #define ECC_DH_IN_PARAM_NUM	2
20b32598bfSZexi Yu #define ECC_DH_KEY_PARAM_NUM	4
21b32598bfSZexi Yu #define ECC_DH_OUT_PARAM_NUM	2
22b32598bfSZexi Yu #define ECC_DH_IN_SIZE(hsz)	((hsz) * ECC_DH_IN_PARAM_NUM)
23b32598bfSZexi Yu #define ECC_DH_KEY_SIZE(hsz)	((hsz) * ECC_DH_KEY_PARAM_NUM)
24b32598bfSZexi Yu #define ECC_DH_OUT_SIZE(hsz)	((hsz) * ECC_DH_OUT_PARAM_NUM)
25b32598bfSZexi Yu 
26b32598bfSZexi Yu #define ECC_SIGN_IN_PARAM_NUM	2
27b32598bfSZexi Yu #define ECC_SIGN_KEY_PARAM_NUM	7
28b32598bfSZexi Yu #define SM2_DEC_KEY_PARAM_NUM	4
29b32598bfSZexi Yu #define SM2_DEC_IN_PARAM_NUM	4
30b32598bfSZexi Yu #define ECC_SIGN_OUT_PARAM_NUM	2
31b32598bfSZexi Yu #define ECC_SIGN_IN_SIZE(hsz)	((hsz) * ECC_SIGN_IN_PARAM_NUM)
32b32598bfSZexi Yu #define ECC_SIGN_KEY_SIZE(hsz)	((hsz) * ECC_SIGN_KEY_PARAM_NUM)
33b32598bfSZexi Yu #define ECC_SIGN_OUT_SIZE(hsz)	((hsz) * ECC_SIGN_OUT_PARAM_NUM)
34b32598bfSZexi Yu 
35b32598bfSZexi Yu #define ECC_VERIF_IN_PARAM_NUM	3
36b32598bfSZexi Yu #define ECC_VERIF_KEY_PARAM_NUM	8
37b32598bfSZexi Yu #define SM2_ENC_KEY_PARAM_NUM	8
38b32598bfSZexi Yu #define ECC_VERIF_IN_SIZE(hsz)	((hsz) * ECC_VERIF_IN_PARAM_NUM)
39b32598bfSZexi Yu #define ECC_VERIF_KEY_SIZE(hsz)	((hsz) * ECC_VERIF_KEY_PARAM_NUM)
40b32598bfSZexi Yu #define SM2_ENC_KEY_SIZE(hsz)	((hsz) * SM2_ENC_KEY_PARAM_NUM)
41b32598bfSZexi Yu #define SM2_DEC_KEY_SIZE(hsz)	((hsz) * SM2_DEC_KEY_PARAM_NUM)
42b32598bfSZexi Yu #define ECC_POINT_PARAM_NUM		2
43b32598bfSZexi Yu #define MAX_SM2_MLEN			512
44b32598bfSZexi Yu 
45b32598bfSZexi Yu #define HPRE_ECC_DH_TOTAL_BUF_SIZE(key_bytes) ((key_bytes) * 8)
46b32598bfSZexi Yu #define HPRE_ECC_SIGN_TOTAL_BUF_SIZE(key_bytes) ((key_bytes) * 11)
47b32598bfSZexi Yu #define HPRE_ECC_VERIFY_TOTAL_BUF_SIZE(key_bytes) ((key_bytes) * 11)
48b32598bfSZexi Yu #define HPRE_SM2_ENC_TOTAL_BUF_SIZE(key_bytes, sm2_mlen) \
49b32598bfSZexi Yu 	((key_bytes) * 12 + (sm2_mlen) * 2)
50b32598bfSZexi Yu #define HPRE_SM2_DEC_TOTAL_BUF_SIZE(key_bytes, sm2_mlen) \
51b32598bfSZexi Yu 	((key_bytes) * 7 + (sm2_mlen) * 2)
52b32598bfSZexi Yu 
53b32598bfSZexi Yu #define SM2_X2Y2_LEN 64
54b32598bfSZexi Yu 
55b32598bfSZexi Yu struct hpre_ecc_curve {
56b32598bfSZexi Yu 	const uint32_t id;
57b32598bfSZexi Yu 	const uint32_t key_bits;
58b32598bfSZexi Yu 	const uint8_t *p;
59b32598bfSZexi Yu 	const uint8_t *a;
60b32598bfSZexi Yu 	const uint8_t *b;
61b32598bfSZexi Yu 	const uint8_t *x;
62b32598bfSZexi Yu 	const uint8_t *y;
63b32598bfSZexi Yu 	const uint8_t *n;
64b32598bfSZexi Yu };
65b32598bfSZexi Yu 
66b32598bfSZexi Yu /* NID_X9_62_prime192v1 */
67b32598bfSZexi Yu static const uint8_t g_prime192v1_p[] = {
68b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
69b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
70b32598bfSZexi Yu };
71b32598bfSZexi Yu 
72b32598bfSZexi Yu static const uint8_t g_prime192v1_a[] = {
73b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
74b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC
75b32598bfSZexi Yu };
76b32598bfSZexi Yu 
77b32598bfSZexi Yu static const uint8_t g_prime192v1_b[] = {
78b32598bfSZexi Yu 	0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7, 0x0F, 0xA7, 0xE9, 0xAB,
79b32598bfSZexi Yu 	0x72, 0x24, 0x30, 0x49, 0xFE, 0xB8, 0xDE, 0xEC, 0xC1, 0x46, 0xB9, 0xB1
80b32598bfSZexi Yu };
81b32598bfSZexi Yu 
82b32598bfSZexi Yu static const uint8_t g_prime192v1_gx[] = {
83b32598bfSZexi Yu 	0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6, 0x7C, 0xBF, 0x20, 0xEB,
84b32598bfSZexi Yu 	0x43, 0xA1, 0x88, 0x00, 0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12
85b32598bfSZexi Yu };
86b32598bfSZexi Yu 
87b32598bfSZexi Yu static const uint8_t g_prime192v1_gy[] = {
88b32598bfSZexi Yu 	0x07, 0x19, 0x2b, 0x95, 0xff, 0xc8, 0xda, 0x78, 0x63, 0x10, 0x11, 0xed,
89b32598bfSZexi Yu 	0x6b, 0x24, 0xcd, 0xd5, 0x73, 0xf9, 0x77, 0xa1, 0x1e, 0x79, 0x48, 0x11
90b32598bfSZexi Yu };
91b32598bfSZexi Yu 
92b32598bfSZexi Yu static const uint8_t g_prime192v1_n[] = {
93b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
94b32598bfSZexi Yu 	0x99, 0xDE, 0xF8, 0x36, 0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31
95b32598bfSZexi Yu };
96b32598bfSZexi Yu 
97b32598bfSZexi Yu /* NID_secp224r1 */
98b32598bfSZexi Yu static const uint8_t g_secp224r1_p[] = {
99b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
100b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101b32598bfSZexi Yu 	0x00, 0x00, 0x00, 0x01
102b32598bfSZexi Yu };
103b32598bfSZexi Yu 
104b32598bfSZexi Yu static const uint8_t g_secp224r1_a[] = {
105b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
106b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
107b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFE
108b32598bfSZexi Yu };
109b32598bfSZexi Yu 
110b32598bfSZexi Yu static const uint8_t g_secp224r1_b[] = {
111b32598bfSZexi Yu 	0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56,
112b32598bfSZexi Yu 	0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43,
113b32598bfSZexi Yu 	0x23, 0x55, 0xFF, 0xB4
114b32598bfSZexi Yu };
115b32598bfSZexi Yu 
116b32598bfSZexi Yu static const uint8_t g_secp224r1_gx[] = {
117b32598bfSZexi Yu 	0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9,
118b32598bfSZexi Yu 	0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6,
119b32598bfSZexi Yu 	0x11, 0x5C, 0x1D, 0x21
120b32598bfSZexi Yu };
121b32598bfSZexi Yu 
122b32598bfSZexi Yu static const uint8_t g_secp224r1_gy[] = {
123b32598bfSZexi Yu 	0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6,
124b32598bfSZexi Yu 	0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99,
125b32598bfSZexi Yu 	0x85, 0x00, 0x7e, 0x34
126b32598bfSZexi Yu };
127b32598bfSZexi Yu 
128b32598bfSZexi Yu static const uint8_t g_secp224r1_n[] = {
129b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
130b32598bfSZexi Yu 	0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45,
131b32598bfSZexi Yu 	0x5C, 0x5C, 0x2A, 0x3D
132b32598bfSZexi Yu };
133b32598bfSZexi Yu 
134b32598bfSZexi Yu /* NID_X9_62_prime256v1 */
135b32598bfSZexi Yu static const uint8_t g_prime256v1_p[] = {
136b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
137b32598bfSZexi Yu 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
138b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
139b32598bfSZexi Yu };
140b32598bfSZexi Yu 
141b32598bfSZexi Yu static const uint8_t g_prime256v1_a[] = {
142b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
143b32598bfSZexi Yu 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
144b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC
145b32598bfSZexi Yu };
146b32598bfSZexi Yu 
147b32598bfSZexi Yu static const uint8_t g_prime256v1_b[] = {
148b32598bfSZexi Yu 	0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55,
149b32598bfSZexi Yu 	0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6,
150b32598bfSZexi Yu 	0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B
151b32598bfSZexi Yu };
152b32598bfSZexi Yu 
153b32598bfSZexi Yu static const uint8_t g_prime256v1_gx[] = {
154b32598bfSZexi Yu 	0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5,
155b32598bfSZexi Yu 	0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0,
156b32598bfSZexi Yu 	0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96
157b32598bfSZexi Yu };
158b32598bfSZexi Yu 
159b32598bfSZexi Yu static const uint8_t g_prime256v1_gy[] = {
160b32598bfSZexi Yu 	0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a,
161b32598bfSZexi Yu 	0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce,
162b32598bfSZexi Yu 	0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5
163b32598bfSZexi Yu };
164b32598bfSZexi Yu 
165b32598bfSZexi Yu static const uint8_t g_prime256v1_n[] = {
166b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
167b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84,
168b32598bfSZexi Yu 	0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51
169b32598bfSZexi Yu };
170b32598bfSZexi Yu 
171b32598bfSZexi Yu /* NID_secp384r1 */
172b32598bfSZexi Yu static const uint8_t g_secp384r1_p[] = {
173b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
174b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
175b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
176b32598bfSZexi Yu 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF
177b32598bfSZexi Yu };
178b32598bfSZexi Yu 
179b32598bfSZexi Yu static const uint8_t g_secp384r1_a[] = {
180b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
181b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
182b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
183b32598bfSZexi Yu 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC
184b32598bfSZexi Yu };
185b32598bfSZexi Yu 
186b32598bfSZexi Yu static const uint8_t g_secp384r1_b[] = {
187b32598bfSZexi Yu 	0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B,
188b32598bfSZexi Yu 	0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
189b32598bfSZexi Yu 	0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
190b32598bfSZexi Yu 	0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF
191b32598bfSZexi Yu };
192b32598bfSZexi Yu 
193b32598bfSZexi Yu static const uint8_t g_secp384r1_gx[] = {
194b32598bfSZexi Yu 	0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E,
195b32598bfSZexi Yu 	0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
196b32598bfSZexi Yu 	0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
197b32598bfSZexi Yu 	0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7
198b32598bfSZexi Yu };
199b32598bfSZexi Yu 
200b32598bfSZexi Yu static const uint8_t g_secp384r1_gy[] = {
201b32598bfSZexi Yu 	0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf,
202b32598bfSZexi Yu 	0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c,
203b32598bfSZexi Yu 	0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce,
204b32598bfSZexi Yu 	0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f
205b32598bfSZexi Yu };
206b32598bfSZexi Yu 
207b32598bfSZexi Yu static const uint8_t g_secp384r1_n[] = {
208b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
209b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
210b32598bfSZexi Yu 	0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2,
211b32598bfSZexi Yu 	0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73
212b32598bfSZexi Yu };
213b32598bfSZexi Yu 
214b32598bfSZexi Yu /* NID_secp521r1 */
215b32598bfSZexi Yu static const uint8_t g_secp521r1_p[] = {
216b32598bfSZexi Yu 	0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
217b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
218b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
219b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
220b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
221b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
222b32598bfSZexi Yu };
223b32598bfSZexi Yu 
224b32598bfSZexi Yu static const uint8_t g_secp521r1_a[] = {
225b32598bfSZexi Yu 	0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
226b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
227b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
228b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
229b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
230b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC
231b32598bfSZexi Yu };
232b32598bfSZexi Yu 
233b32598bfSZexi Yu static const uint8_t g_secp521r1_b[] = {
234b32598bfSZexi Yu 	0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A,
235b32598bfSZexi Yu 	0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3,
236b32598bfSZexi Yu 	0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19,
237b32598bfSZexi Yu 	0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1,
238b32598bfSZexi Yu 	0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45,
239b32598bfSZexi Yu 	0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00
240b32598bfSZexi Yu };
241b32598bfSZexi Yu 
242b32598bfSZexi Yu static const uint8_t g_secp521r1_gx[] = {
243b32598bfSZexi Yu 	0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E,
244b32598bfSZexi Yu 	0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F,
245b32598bfSZexi Yu 	0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B,
246b32598bfSZexi Yu 	0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF,
247b32598bfSZexi Yu 	0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E,
248b32598bfSZexi Yu 	0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66
249b32598bfSZexi Yu };
250b32598bfSZexi Yu 
251b32598bfSZexi Yu static const uint8_t g_secp521r1_gy[] = {
252b32598bfSZexi Yu 	0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a,
253b32598bfSZexi Yu 	0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b,
254b32598bfSZexi Yu 	0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee,
255b32598bfSZexi Yu 	0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad,
256b32598bfSZexi Yu 	0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe,
257b32598bfSZexi Yu 	0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50
258b32598bfSZexi Yu };
259b32598bfSZexi Yu 
260b32598bfSZexi Yu static const uint8_t g_secp521r1_n[] = {
261b32598bfSZexi Yu 	0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
262b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
263b32598bfSZexi Yu 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86,
264b32598bfSZexi Yu 	0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09,
265b32598bfSZexi Yu 	0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F,
266b32598bfSZexi Yu 	0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09
267b32598bfSZexi Yu };
268b32598bfSZexi Yu 
269b32598bfSZexi Yu /* NID_SM2 */
270b32598bfSZexi Yu static const uint8_t g_sm2_p[] = {
271b32598bfSZexi Yu 	0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
272b32598bfSZexi Yu 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
273b32598bfSZexi Yu 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
274b32598bfSZexi Yu };
275b32598bfSZexi Yu 
276b32598bfSZexi Yu static const uint8_t g_sm2_a[] = {
277b32598bfSZexi Yu 	0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
278b32598bfSZexi Yu 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
279b32598bfSZexi Yu 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc
280b32598bfSZexi Yu };
281b32598bfSZexi Yu 
282b32598bfSZexi Yu static const uint8_t g_sm2_b[] = {
283b32598bfSZexi Yu 	0x28, 0xe9, 0xfa, 0x9e, 0x9d, 0x9f, 0x5e, 0x34, 0x4d, 0x5a, 0x9e, 0x4b,
284b32598bfSZexi Yu 	0xcf, 0x65, 0x09, 0xa7, 0xf3, 0x97, 0x89, 0xf5, 0x15, 0xab, 0x8f, 0x92,
285b32598bfSZexi Yu 	0xdd, 0xbc, 0xbd, 0x41, 0x4d, 0x94, 0x0e, 0x93
286b32598bfSZexi Yu };
287b32598bfSZexi Yu 
288b32598bfSZexi Yu static const uint8_t g_sm2_gx[] = {
289b32598bfSZexi Yu 	0x32, 0xc4, 0xae, 0x2c, 0x1f, 0x19, 0x81, 0x19, 0x5f, 0x99, 0x04, 0x46,
290b32598bfSZexi Yu 	0x6a, 0x39, 0xc9, 0x94, 0x8f, 0xe3, 0x0b, 0xbf, 0xf2, 0x66, 0x0b, 0xe1,
291b32598bfSZexi Yu 	0x71, 0x5a, 0x45, 0x89, 0x33, 0x4c, 0x74, 0xc7
292b32598bfSZexi Yu };
293b32598bfSZexi Yu 
294b32598bfSZexi Yu static const uint8_t g_sm2_gy[] = {
295b32598bfSZexi Yu 	0xbc, 0x37, 0x36, 0xa2, 0xf4, 0xf6, 0x77, 0x9c, 0x59, 0xbd, 0xce, 0xe3,
296b32598bfSZexi Yu 	0x6b, 0x69, 0x21, 0x53, 0xd0, 0xa9, 0x87, 0x7c, 0xc6, 0x2a, 0x47, 0x40,
297b32598bfSZexi Yu 	0x02, 0xdf, 0x32, 0xe5, 0x21, 0x39, 0xf0, 0xa0
298b32598bfSZexi Yu };
299b32598bfSZexi Yu 
300b32598bfSZexi Yu static const uint8_t g_sm2_n[] = {
301b32598bfSZexi Yu 	0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
302b32598bfSZexi Yu 	0xff, 0xff, 0xff, 0xff, 0x72, 0x03, 0xdf, 0x6b, 0x21, 0xc6, 0x05, 0x2b,
303b32598bfSZexi Yu 	0x53, 0xbb, 0xf4, 0x09, 0x39, 0xd5, 0x41, 0x23
304b32598bfSZexi Yu };
305b32598bfSZexi Yu 
306b32598bfSZexi Yu static const struct hpre_ecc_curve g_curve_list[] = {
307b32598bfSZexi Yu 	{
308b32598bfSZexi Yu 		.id = TEE_ECC_CURVE_NIST_P192,
309b32598bfSZexi Yu 		.key_bits = 192,
310b32598bfSZexi Yu 		.p = g_prime192v1_p,
311b32598bfSZexi Yu 		.a = g_prime192v1_a,
312b32598bfSZexi Yu 		.b = g_prime192v1_b,
313b32598bfSZexi Yu 		.x = g_prime192v1_gx,
314b32598bfSZexi Yu 		.y = g_prime192v1_gy,
315b32598bfSZexi Yu 		.n = g_prime192v1_n,
316b32598bfSZexi Yu 	},
317b32598bfSZexi Yu 	{
318b32598bfSZexi Yu 		.id = TEE_ECC_CURVE_NIST_P224,
319b32598bfSZexi Yu 		.key_bits = 224,
320b32598bfSZexi Yu 		.p = g_secp224r1_p,
321b32598bfSZexi Yu 		.a = g_secp224r1_a,
322b32598bfSZexi Yu 		.b = g_secp224r1_b,
323b32598bfSZexi Yu 		.x = g_secp224r1_gx,
324b32598bfSZexi Yu 		.y = g_secp224r1_gy,
325b32598bfSZexi Yu 		.n = g_secp224r1_n,
326b32598bfSZexi Yu 	},
327b32598bfSZexi Yu 	{
328b32598bfSZexi Yu 		.id = TEE_ECC_CURVE_NIST_P256,
329b32598bfSZexi Yu 		.key_bits = 256,
330b32598bfSZexi Yu 		.p = g_prime256v1_p,
331b32598bfSZexi Yu 		.a = g_prime256v1_a,
332b32598bfSZexi Yu 		.b = g_prime256v1_b,
333b32598bfSZexi Yu 		.x = g_prime256v1_gx,
334b32598bfSZexi Yu 		.y = g_prime256v1_gy,
335b32598bfSZexi Yu 		.n = g_prime256v1_n,
336b32598bfSZexi Yu 	},
337b32598bfSZexi Yu 	{
338b32598bfSZexi Yu 		.id = TEE_ECC_CURVE_NIST_P384,
339b32598bfSZexi Yu 		.key_bits = 384,
340b32598bfSZexi Yu 		.p = g_secp384r1_p,
341b32598bfSZexi Yu 		.a = g_secp384r1_a,
342b32598bfSZexi Yu 		.b = g_secp384r1_b,
343b32598bfSZexi Yu 		.x = g_secp384r1_gx,
344b32598bfSZexi Yu 		.y = g_secp384r1_gy,
345b32598bfSZexi Yu 		.n = g_secp384r1_n,
346b32598bfSZexi Yu 	},
347b32598bfSZexi Yu 	{
348b32598bfSZexi Yu 		.id = TEE_ECC_CURVE_NIST_P521,
349b32598bfSZexi Yu 		.key_bits = 521,
350b32598bfSZexi Yu 		.p = g_secp521r1_p,
351b32598bfSZexi Yu 		.a = g_secp521r1_a,
352b32598bfSZexi Yu 		.b = g_secp521r1_b,
353b32598bfSZexi Yu 		.x = g_secp521r1_gx,
354b32598bfSZexi Yu 		.y = g_secp521r1_gy,
355b32598bfSZexi Yu 		.n = g_secp521r1_n,
356b32598bfSZexi Yu 	},
357b32598bfSZexi Yu 	{
358b32598bfSZexi Yu 		.id = TEE_ECC_CURVE_SM2,
359b32598bfSZexi Yu 		.key_bits = 256,
360b32598bfSZexi Yu 		.p = g_sm2_p,
361b32598bfSZexi Yu 		.a = g_sm2_a,
362b32598bfSZexi Yu 		.b = g_sm2_b,
363b32598bfSZexi Yu 		.x = g_sm2_gx,
364b32598bfSZexi Yu 		.y = g_sm2_gy,
365b32598bfSZexi Yu 		.n = g_sm2_n,
366b32598bfSZexi Yu 	}
367b32598bfSZexi Yu };
368b32598bfSZexi Yu 
is_all_zero(uint8_t * data,uint32_t size,const char * p_name)369b32598bfSZexi Yu static bool is_all_zero(uint8_t *data, uint32_t size, const char *p_name)
370b32598bfSZexi Yu {
371b32598bfSZexi Yu 	uint32_t i = 0;
372b32598bfSZexi Yu 
373b32598bfSZexi Yu 	for (i = 0; i < size; i++) {
374b32598bfSZexi Yu 		if (data[i])
375b32598bfSZexi Yu 			return false;
376b32598bfSZexi Yu 	}
377b32598bfSZexi Yu 
378b32598bfSZexi Yu 	EMSG("Error: %s all zero", p_name);
379b32598bfSZexi Yu 
380b32598bfSZexi Yu 	return true;
381b32598bfSZexi Yu }
382b32598bfSZexi Yu 
hpre_ecc_curve_to_hpre_bin(uint8_t * p,uint8_t * a,uint8_t * b,uint8_t * n,uint8_t * gx,uint8_t * gy,uint32_t curve_bytes,uint32_t key_bytes)383b32598bfSZexi Yu static enum hisi_drv_status hpre_ecc_curve_to_hpre_bin(uint8_t *p, uint8_t *a,
384b32598bfSZexi Yu 						       uint8_t *b, uint8_t *n,
385b32598bfSZexi Yu 						       uint8_t *gx, uint8_t *gy,
386b32598bfSZexi Yu 						       uint32_t curve_bytes,
387b32598bfSZexi Yu 						       uint32_t key_bytes)
388b32598bfSZexi Yu {
389b32598bfSZexi Yu 	enum hisi_drv_status ret = HISI_QM_DRVCRYPT_NO_ERR;
390b32598bfSZexi Yu 
391b32598bfSZexi Yu 	ret = hpre_bin_from_crypto_bin(p, p, key_bytes, curve_bytes);
392b32598bfSZexi Yu 	if (ret) {
393b32598bfSZexi Yu 		EMSG("Fail to transfer p from crypto_bin to hpre_bin");
394b32598bfSZexi Yu 		return ret;
395b32598bfSZexi Yu 	}
396b32598bfSZexi Yu 
397b32598bfSZexi Yu 	ret = hpre_bin_from_crypto_bin(a, a, key_bytes, curve_bytes);
398b32598bfSZexi Yu 	if (ret) {
399b32598bfSZexi Yu 		EMSG("Fail to transfer a from crypto_bin to hpre_bin");
400b32598bfSZexi Yu 		return ret;
401b32598bfSZexi Yu 	}
402b32598bfSZexi Yu 
403b32598bfSZexi Yu 	ret = hpre_bin_from_crypto_bin(b, b, key_bytes, curve_bytes);
404b32598bfSZexi Yu 	if (ret) {
405b32598bfSZexi Yu 		EMSG("Fail to transfer b from crypto_bin to hpre_bin");
406b32598bfSZexi Yu 		return ret;
407b32598bfSZexi Yu 	}
408b32598bfSZexi Yu 
409b32598bfSZexi Yu 	if (n) {
410b32598bfSZexi Yu 		ret = hpre_bin_from_crypto_bin(n, n, key_bytes, curve_bytes);
411b32598bfSZexi Yu 		if (ret) {
412b32598bfSZexi Yu 			EMSG("Fail to transfer n from crypto_bin to hpre_bin");
413b32598bfSZexi Yu 			return ret;
414b32598bfSZexi Yu 		}
415b32598bfSZexi Yu 	}
416b32598bfSZexi Yu 
417b32598bfSZexi Yu 	if (gx) {
418b32598bfSZexi Yu 		ret = hpre_bin_from_crypto_bin(gx, gx, key_bytes, curve_bytes);
419b32598bfSZexi Yu 		if (ret) {
420b32598bfSZexi Yu 			EMSG("Fail to transfer gx from crypto_bin to hpre_bin");
421b32598bfSZexi Yu 			return ret;
422b32598bfSZexi Yu 		}
423b32598bfSZexi Yu 	}
424b32598bfSZexi Yu 
425b32598bfSZexi Yu 	if (gy) {
426b32598bfSZexi Yu 		ret = hpre_bin_from_crypto_bin(gy, gy, key_bytes, curve_bytes);
427b32598bfSZexi Yu 		if (ret)
428b32598bfSZexi Yu 			EMSG("Fail to transfer gy from crypto_bin to hpre_bin");
429b32598bfSZexi Yu 	}
430b32598bfSZexi Yu 
431b32598bfSZexi Yu 	return ret;
432b32598bfSZexi Yu }
433b32598bfSZexi Yu 
hpre_ecc_fill_sqe(void * bd,void * info)434b32598bfSZexi Yu static enum hisi_drv_status hpre_ecc_fill_sqe(void *bd, void *info)
435b32598bfSZexi Yu {
436b32598bfSZexi Yu 	struct hpre_ecc_msg *msg = (struct hpre_ecc_msg *)info;
437b32598bfSZexi Yu 	struct hpre_sqe *sqe = (struct hpre_sqe *)bd;
438b32598bfSZexi Yu 
439b32598bfSZexi Yu 	sqe->w0 = msg->alg_type | SHIFT_U32(0x1, HPRE_DONE_SHIFT);
440b32598bfSZexi Yu 	sqe->task_len1 = TASK_LENGTH(msg->key_bytes);
441b32598bfSZexi Yu 	sqe->ext1 = msg->sm2_sp << HPRE_SQE_BD_RSV2_SHIFT;
442b32598bfSZexi Yu 
443b32598bfSZexi Yu 	if (msg->alg_type == HPRE_ALG_SM2_ENC ||
444b32598bfSZexi Yu 	    msg->alg_type == HPRE_ALG_SM2_DEC)
445b32598bfSZexi Yu 		sqe->sm2enc_klen = msg->sm2_mlen - 1;
446b32598bfSZexi Yu 
447b32598bfSZexi Yu 	if (msg->alg_type == HPRE_ALG_SM2_SIGN ||
448b32598bfSZexi Yu 	    msg->alg_type == HPRE_ALG_SM2_ENC)
449b32598bfSZexi Yu 		sqe->ext1 |= SHIFT_U32(0x1, HPRE_SQE_SM2_KSEL_SHIFT);
450b32598bfSZexi Yu 
451b32598bfSZexi Yu 	sqe->key = msg->key_dma;
452b32598bfSZexi Yu 	sqe->in = msg->in_dma;
453b32598bfSZexi Yu 	if (msg->alg_type != HPRE_ALG_ECDSA_VERF &&
454b32598bfSZexi Yu 	    msg->alg_type != HPRE_ALG_SM2_VERF)
455b32598bfSZexi Yu 		sqe->out = msg->out_dma;
456b32598bfSZexi Yu 
457b32598bfSZexi Yu 	return HISI_QM_DRVCRYPT_NO_ERR;
458b32598bfSZexi Yu }
459b32598bfSZexi Yu 
ecc_dh_out_to_crypto_bin(struct hpre_ecc_msg * msg)460b32598bfSZexi Yu static enum hisi_drv_status ecc_dh_out_to_crypto_bin(struct hpre_ecc_msg *msg)
461b32598bfSZexi Yu {
462b32598bfSZexi Yu 	struct hpre_ecc_dh *ecc_dh = &msg->param_size.ecc_dh;
463b32598bfSZexi Yu 	uint8_t *rx = msg->out;
464b32598bfSZexi Yu 	uint8_t *ry = rx + msg->key_bytes;
465b32598bfSZexi Yu 	enum hisi_drv_status ret = HISI_QM_DRVCRYPT_NO_ERR;
466b32598bfSZexi Yu 
467b32598bfSZexi Yu 	ret = hpre_bin_to_crypto_bin(rx, rx, msg->key_bytes,
468b32598bfSZexi Yu 				     ecc_dh->rx_bytes);
469b32598bfSZexi Yu 	if (ret) {
470b32598bfSZexi Yu 		EMSG("Fail to transfer ecc dh rx from hpre_bin to crypto_bin");
471b32598bfSZexi Yu 		return ret;
472b32598bfSZexi Yu 	}
473b32598bfSZexi Yu 
474b32598bfSZexi Yu 	ret = hpre_bin_to_crypto_bin(ry, ry, msg->key_bytes,
475b32598bfSZexi Yu 				     ecc_dh->ry_bytes);
476b32598bfSZexi Yu 	if (ret)
477b32598bfSZexi Yu 		EMSG("Fail to transfer ecc dh ry from hpre_bin to crypto_bin");
478b32598bfSZexi Yu 
479b32598bfSZexi Yu 	return ret;
480b32598bfSZexi Yu }
481b32598bfSZexi Yu 
ecc_sign_out_to_crypto_bin(struct hpre_ecc_msg * msg)482b5203cb1Syuzexi static enum hisi_drv_status ecc_sign_out_to_crypto_bin(struct hpre_ecc_msg *msg)
483b5203cb1Syuzexi {
484b5203cb1Syuzexi 	struct hpre_ecc_sign *ecc_sign = &msg->param_size.ecc_sign;
485b5203cb1Syuzexi 	uint8_t *r = msg->out;
486b5203cb1Syuzexi 	uint8_t *s = r + msg->key_bytes;
487b5203cb1Syuzexi 	enum hisi_drv_status ret = HISI_QM_DRVCRYPT_NO_ERR;
488b5203cb1Syuzexi 
489b5203cb1Syuzexi 	ret = hpre_bin_to_crypto_bin(r, r, msg->key_bytes,
490b5203cb1Syuzexi 				     ecc_sign->r_bytes);
491b5203cb1Syuzexi 	if (ret) {
492b5203cb1Syuzexi 		EMSG("Fail to transfer ecc sign r from hpre_bin to crypto_bin");
493b5203cb1Syuzexi 		return ret;
494b5203cb1Syuzexi 	}
495b5203cb1Syuzexi 
496b5203cb1Syuzexi 	ret = hpre_bin_to_crypto_bin(s, s, msg->key_bytes,
497b5203cb1Syuzexi 				     ecc_sign->s_bytes);
498b5203cb1Syuzexi 	if (ret)
499b5203cb1Syuzexi 		EMSG("Fail to transfer ecc sign s from hpre_bin to crypto_bin");
500b5203cb1Syuzexi 
501b5203cb1Syuzexi 	return ret;
502b5203cb1Syuzexi }
503b5203cb1Syuzexi 
hpre_ecc_verify_get_result(struct hpre_ecc_msg * msg,struct hpre_sqe * sqe)504b5203cb1Syuzexi static enum hisi_drv_status hpre_ecc_verify_get_result(struct hpre_ecc_msg *msg,
505b5203cb1Syuzexi 						       struct hpre_sqe *sqe)
506b5203cb1Syuzexi {
507b5203cb1Syuzexi 	if (sqe->out & BIT64(1)) {
508b5203cb1Syuzexi 		msg->result = ECC_VERIFY_SUCCESS;
509b5203cb1Syuzexi 		return HISI_QM_DRVCRYPT_NO_ERR;
510b5203cb1Syuzexi 	}
511b5203cb1Syuzexi 
512b5203cb1Syuzexi 	msg->result = ECC_VERIFY_ERR;
513b5203cb1Syuzexi 	return HISI_QM_DRVCRYPT_VERIFY_ERR;
514b5203cb1Syuzexi }
515b5203cb1Syuzexi 
516b5203cb1Syuzexi static enum hisi_drv_status
hpre_ecc_out_to_crypto_bin(struct hpre_ecc_msg * msg,struct hpre_sqe * sqe)517b5203cb1Syuzexi hpre_ecc_out_to_crypto_bin(struct hpre_ecc_msg *msg, struct hpre_sqe *sqe)
518b32598bfSZexi Yu {
519b32598bfSZexi Yu 	enum hisi_drv_status ret = HISI_QM_DRVCRYPT_NO_ERR;
520b32598bfSZexi Yu 
521b32598bfSZexi Yu 	switch (msg->alg_type) {
522b32598bfSZexi Yu 	case HPRE_ALG_ECDH_MULTIPLY:
523b32598bfSZexi Yu 		ret = ecc_dh_out_to_crypto_bin(msg);
524b32598bfSZexi Yu 		break;
525b5203cb1Syuzexi 	case HPRE_ALG_ECDSA_SIGN:
526b5203cb1Syuzexi 	case HPRE_ALG_SM2_SIGN:
527b5203cb1Syuzexi 		ret = ecc_sign_out_to_crypto_bin(msg);
528b5203cb1Syuzexi 		break;
529b5203cb1Syuzexi 	case HPRE_ALG_ECDSA_VERF:
530b5203cb1Syuzexi 	case HPRE_ALG_SM2_VERF:
531b5203cb1Syuzexi 		ret = hpre_ecc_verify_get_result(msg, sqe);
532b5203cb1Syuzexi 		break;
533b32598bfSZexi Yu 	default:
534b32598bfSZexi Yu 		EMSG("Invalid alg type.");
535b32598bfSZexi Yu 		return HISI_QM_DRVCRYPT_EINVAL;
536b32598bfSZexi Yu 	}
537b32598bfSZexi Yu 
538b32598bfSZexi Yu 	return ret;
539b32598bfSZexi Yu }
540b32598bfSZexi Yu 
hpre_ecc_parse_sqe(void * bd,void * info)541b32598bfSZexi Yu static enum hisi_drv_status hpre_ecc_parse_sqe(void *bd, void *info)
542b32598bfSZexi Yu {
543b32598bfSZexi Yu 	struct hpre_ecc_msg *msg = (struct hpre_ecc_msg *)info;
544b32598bfSZexi Yu 	struct hpre_sqe *sqe = (struct hpre_sqe *)bd;
545b32598bfSZexi Yu 	uint16_t err = 0;
546b32598bfSZexi Yu 	uint16_t err1 = 0;
547b32598bfSZexi Yu 	uint16_t done = 0;
548b32598bfSZexi Yu 
549b32598bfSZexi Yu 	err = HPRE_TASK_ETYPE(sqe->w0);
550b32598bfSZexi Yu 	err1 = HPRE_TASK_ETYPE1(sqe->w0);
551b32598bfSZexi Yu 	done = HPRE_TASK_DONE(sqe->w0);
552b32598bfSZexi Yu 	if (done != HPRE_HW_TASK_DONE || err || err1) {
553b32598bfSZexi Yu 		EMSG("HPRE do ecc fail! done=0x%"PRIX16", etype=0x%"PRIX16
554b32598bfSZexi Yu 		     ",etype1=0x%"PRIX16, done, err, err1);
555b32598bfSZexi Yu 
5565cab250eSZexi Yu 		if (done == HPRE_HW_TASK_INIT)
557b32598bfSZexi Yu 			return HISI_QM_DRVCRYPT_ENOPROC;
558b32598bfSZexi Yu 
559b32598bfSZexi Yu 		return HISI_QM_DRVCRYPT_IN_EPARA;
560b32598bfSZexi Yu 	}
561b32598bfSZexi Yu 
562b5203cb1Syuzexi 	if (hpre_ecc_out_to_crypto_bin(msg, sqe)) {
563b32598bfSZexi Yu 		EMSG("HPRE qm transfer ecc out fail.");
564b32598bfSZexi Yu 		return HISI_QM_DRVCRYPT_EINVAL;
565b32598bfSZexi Yu 	}
566b32598bfSZexi Yu 
567b32598bfSZexi Yu 	return HISI_QM_DRVCRYPT_NO_ERR;
568b32598bfSZexi Yu }
569b32598bfSZexi Yu 
hpre_do_ecc_task(void * msg)570b32598bfSZexi Yu static TEE_Result hpre_do_ecc_task(void *msg)
571b32598bfSZexi Yu {
572b32598bfSZexi Yu 	struct hisi_qp *ecc_qp = NULL;
573b32598bfSZexi Yu 	enum hisi_drv_status ret = HISI_QM_DRVCRYPT_NO_ERR;
574b32598bfSZexi Yu 
575b32598bfSZexi Yu 	ecc_qp = hpre_create_qp(HISI_QM_CHANNEL_TYPE1);
576b32598bfSZexi Yu 	if (!ecc_qp) {
577b32598bfSZexi Yu 		EMSG("Fail to create ecc qp");
578b32598bfSZexi Yu 		return TEE_ERROR_BUSY;
579b32598bfSZexi Yu 	}
580b32598bfSZexi Yu 
581b32598bfSZexi Yu 	ecc_qp->fill_sqe = hpre_ecc_fill_sqe;
582b32598bfSZexi Yu 	ecc_qp->parse_sqe = hpre_ecc_parse_sqe;
583b32598bfSZexi Yu 	ret = hisi_qp_send(ecc_qp, msg);
584b32598bfSZexi Yu 	if (ret) {
585b32598bfSZexi Yu 		EMSG("Fail to send task, ret=%d", ret);
586b32598bfSZexi Yu 		hisi_qm_release_qp(ecc_qp);
587b32598bfSZexi Yu 		return TEE_ERROR_BAD_STATE;
588b32598bfSZexi Yu 	}
589b32598bfSZexi Yu 
590b32598bfSZexi Yu 	ret = hisi_qp_recv_sync(ecc_qp, msg);
591b32598bfSZexi Yu 	if (ret) {
592b32598bfSZexi Yu 		EMSG("Recv task error, ret=%d", ret);
593b32598bfSZexi Yu 		hisi_qm_release_qp(ecc_qp);
594b32598bfSZexi Yu 		return TEE_ERROR_BAD_STATE;
595b32598bfSZexi Yu 	}
596b32598bfSZexi Yu 
597b32598bfSZexi Yu 	hisi_qm_release_qp(ecc_qp);
598b32598bfSZexi Yu 
599b32598bfSZexi Yu 	return TEE_SUCCESS;
600b32598bfSZexi Yu }
601b32598bfSZexi Yu 
key_size_is_supported(size_t key_bits)602b32598bfSZexi Yu static bool key_size_is_supported(size_t key_bits)
603b32598bfSZexi Yu {
604b32598bfSZexi Yu 	return (key_bits == 192 || key_bits == 224 || key_bits == 256 ||
605b32598bfSZexi Yu 		key_bits == 384 || key_bits == 448 || key_bits == 512 ||
606b32598bfSZexi Yu 		BITS_TO_BYTES(key_bits) == BITS_TO_BYTES(521) ||
607b32598bfSZexi Yu 		BITS_TO_BYTES(key_bits) == BITS_TO_BYTES(225));
608b32598bfSZexi Yu }
609b32598bfSZexi Yu 
hpre_ecc_alloc_keypair(struct ecc_keypair * key,uint32_t type __unused,size_t size_bits)610b32598bfSZexi Yu static TEE_Result hpre_ecc_alloc_keypair(struct ecc_keypair *key,
611b32598bfSZexi Yu 					 uint32_t type __unused,
612b32598bfSZexi Yu 					 size_t size_bits)
613b32598bfSZexi Yu {
614b32598bfSZexi Yu 	if (!key || !key_size_is_supported(size_bits)) {
615b32598bfSZexi Yu 		EMSG("Invalid input params.");
616b32598bfSZexi Yu 		return TEE_ERROR_BAD_PARAMETERS;
617b32598bfSZexi Yu 	}
618b32598bfSZexi Yu 
619b32598bfSZexi Yu 	memset(key, 0, sizeof(*key));
620b32598bfSZexi Yu 
621b32598bfSZexi Yu 	key->d = crypto_bignum_allocate(size_bits);
622b32598bfSZexi Yu 	if (!key->d)
623b32598bfSZexi Yu 		goto d_err;
624b32598bfSZexi Yu 
625b32598bfSZexi Yu 	key->x = crypto_bignum_allocate(size_bits);
626b32598bfSZexi Yu 	if (!key->x)
627b32598bfSZexi Yu 		goto x_err;
628b32598bfSZexi Yu 
629b32598bfSZexi Yu 	key->y = crypto_bignum_allocate(size_bits);
630b32598bfSZexi Yu 	if (!key->y)
631b32598bfSZexi Yu 		goto y_err;
632b32598bfSZexi Yu 
633b32598bfSZexi Yu 	return TEE_SUCCESS;
634b32598bfSZexi Yu 
635b32598bfSZexi Yu y_err:
636b32598bfSZexi Yu 	crypto_bignum_free(&key->x);
637b32598bfSZexi Yu x_err:
638b32598bfSZexi Yu 	crypto_bignum_free(&key->d);
639b32598bfSZexi Yu d_err:
640b32598bfSZexi Yu 	EMSG("Hpre ecc alloc key pair fail.");
641b32598bfSZexi Yu 
642b32598bfSZexi Yu 	return TEE_ERROR_OUT_OF_MEMORY;
643b32598bfSZexi Yu }
644b32598bfSZexi Yu 
hpre_ecc_alloc_publickey(struct ecc_public_key * key,uint32_t type __unused,size_t size_bits)645b32598bfSZexi Yu static TEE_Result hpre_ecc_alloc_publickey(struct ecc_public_key *key,
646b32598bfSZexi Yu 					   uint32_t type __unused,
647b32598bfSZexi Yu 					   size_t size_bits)
648b32598bfSZexi Yu {
649b32598bfSZexi Yu 	if (!key || !key_size_is_supported(size_bits)) {
650b32598bfSZexi Yu 		EMSG("Invalid input params.");
651b32598bfSZexi Yu 		return TEE_ERROR_BAD_PARAMETERS;
652b32598bfSZexi Yu 	}
653b32598bfSZexi Yu 
654b32598bfSZexi Yu 	memset(key, 0, sizeof(*key));
655b32598bfSZexi Yu 
656b32598bfSZexi Yu 	key->x = crypto_bignum_allocate(size_bits);
657b32598bfSZexi Yu 	if (!key->x)
658b32598bfSZexi Yu 		goto x_err;
659b32598bfSZexi Yu 
660b32598bfSZexi Yu 	key->y = crypto_bignum_allocate(size_bits);
661b32598bfSZexi Yu 	if (!key->y)
662b32598bfSZexi Yu 		goto y_err;
663b32598bfSZexi Yu 
664b32598bfSZexi Yu 	return TEE_SUCCESS;
665b32598bfSZexi Yu 
666b32598bfSZexi Yu y_err:
667b32598bfSZexi Yu 	crypto_bignum_free(&key->x);
668b32598bfSZexi Yu x_err:
669b32598bfSZexi Yu 	EMSG("Hpre ecc alloc publickey fail.");
670b32598bfSZexi Yu 
671b32598bfSZexi Yu 	return TEE_ERROR_OUT_OF_MEMORY;
672b32598bfSZexi Yu }
673b32598bfSZexi Yu 
hpre_ecc_free_publickey(struct ecc_public_key * key)674b32598bfSZexi Yu static void hpre_ecc_free_publickey(struct ecc_public_key *key)
675b32598bfSZexi Yu {
676b32598bfSZexi Yu 	if (key) {
677b32598bfSZexi Yu 		crypto_bignum_free(&key->x);
678b32598bfSZexi Yu 		crypto_bignum_free(&key->y);
679b32598bfSZexi Yu 	}
680b32598bfSZexi Yu }
681b32598bfSZexi Yu 
get_curve_from_list(uint32_t curve_id)682b32598bfSZexi Yu static const struct hpre_ecc_curve *get_curve_from_list(uint32_t curve_id)
683b32598bfSZexi Yu {
684b32598bfSZexi Yu 	size_t i = 0;
685b32598bfSZexi Yu 
686b32598bfSZexi Yu 	for (i = 0; i < ARRAY_SIZE(g_curve_list); i++) {
687b32598bfSZexi Yu 		if (g_curve_list[i].id == curve_id)
688b32598bfSZexi Yu 			return &g_curve_list[i];
689b32598bfSZexi Yu 	}
690b32598bfSZexi Yu 
691b32598bfSZexi Yu 	return NULL;
692b32598bfSZexi Yu }
693b32598bfSZexi Yu 
hpre_ecc_get_hw_kbytes(size_t key_bits)694b32598bfSZexi Yu static size_t hpre_ecc_get_hw_kbytes(size_t key_bits)
695b32598bfSZexi Yu {
696b32598bfSZexi Yu 	size_t size = 0;
697b32598bfSZexi Yu 
698b32598bfSZexi Yu 	if (BITS_TO_BYTES(key_bits) <= BITS_TO_BYTES(256))
699b32598bfSZexi Yu 		size = BITS_TO_BYTES(256);
700b32598bfSZexi Yu 	else if (BITS_TO_BYTES(key_bits) <= BITS_TO_BYTES(384))
701b32598bfSZexi Yu 		size = BITS_TO_BYTES(384);
702b32598bfSZexi Yu 	else if (BITS_TO_BYTES(key_bits) <= BITS_TO_BYTES(576))
703b32598bfSZexi Yu 		size = BITS_TO_BYTES(576);
704b32598bfSZexi Yu 	else
705b32598bfSZexi Yu 		EMSG("Fail to get key buffer size.");
706b32598bfSZexi Yu 
707b32598bfSZexi Yu 	return size;
708b32598bfSZexi Yu }
709b32598bfSZexi Yu 
hpre_ecc_dh_transfer_key(struct hpre_ecc_msg * msg)710b32598bfSZexi Yu static enum hisi_drv_status hpre_ecc_dh_transfer_key(struct hpre_ecc_msg *msg)
711b32598bfSZexi Yu {
712b32598bfSZexi Yu 	struct hpre_ecc_dh *ecc_dh = &msg->param_size.ecc_dh;
713b32598bfSZexi Yu 	uint8_t *p = msg->key;
714b32598bfSZexi Yu 	uint8_t *a = p + msg->key_bytes;
715b32598bfSZexi Yu 	uint8_t *d = a + msg->key_bytes;
716b32598bfSZexi Yu 	uint8_t *b = d + msg->key_bytes;
717b32598bfSZexi Yu 	enum hisi_drv_status ret = HISI_QM_DRVCRYPT_NO_ERR;
718b32598bfSZexi Yu 
719b32598bfSZexi Yu 	ret = hpre_ecc_curve_to_hpre_bin(p, a, b, NULL, NULL, NULL,
720b32598bfSZexi Yu 					 msg->curve_bytes, msg->key_bytes);
721b32598bfSZexi Yu 	if (ret)
722b32598bfSZexi Yu 		return ret;
723b32598bfSZexi Yu 
724b32598bfSZexi Yu 	ret = hpre_bin_from_crypto_bin(d, d, msg->key_bytes, ecc_dh->d_bytes);
725b32598bfSZexi Yu 	if (ret)
726b32598bfSZexi Yu 		EMSG("Fail to transfer ecc dh d from crypto_bin to hpre_bin");
727b32598bfSZexi Yu 
728b32598bfSZexi Yu 	return ret;
729b32598bfSZexi Yu }
730b32598bfSZexi Yu 
hpre_ecc_dh_transfer_in(struct hpre_ecc_msg * msg)731b32598bfSZexi Yu static enum hisi_drv_status hpre_ecc_dh_transfer_in(struct hpre_ecc_msg *msg)
732b32598bfSZexi Yu {
733b32598bfSZexi Yu 	struct hpre_ecc_dh *ecc_dh = &msg->param_size.ecc_dh;
734b32598bfSZexi Yu 	uint8_t *x = msg->in;
735b32598bfSZexi Yu 	uint8_t *y = x + msg->key_bytes;
736b32598bfSZexi Yu 	enum hisi_drv_status ret = HISI_QM_DRVCRYPT_NO_ERR;
737b32598bfSZexi Yu 
738b32598bfSZexi Yu 	ret = hpre_bin_from_crypto_bin(x, x, msg->key_bytes,
739b32598bfSZexi Yu 				       ecc_dh->x_bytes);
740b32598bfSZexi Yu 	if (ret) {
741b32598bfSZexi Yu 		EMSG("Fail to transfer ecdh gx from crypto_bin to hpre_bin");
742b32598bfSZexi Yu 		return ret;
743b32598bfSZexi Yu 	}
744b32598bfSZexi Yu 
745b32598bfSZexi Yu 	ret = hpre_bin_from_crypto_bin(y, y, msg->key_bytes,
746b32598bfSZexi Yu 				       ecc_dh->y_bytes);
747b32598bfSZexi Yu 	if (ret)
748b32598bfSZexi Yu 		EMSG("Fail to transfer ecdh gy from crypto_bin to hpre_bin");
749b32598bfSZexi Yu 
750b32598bfSZexi Yu 	return ret;
751b32598bfSZexi Yu }
752b32598bfSZexi Yu 
753b32598bfSZexi Yu static enum hisi_drv_status
hpre_ecc_dh_params_fill(const struct hpre_ecc_curve * curve,struct hpre_ecc_msg * msg,struct bignum * privkey,struct ecc_public_key * pubkey)754b32598bfSZexi Yu hpre_ecc_dh_params_fill(const struct hpre_ecc_curve *curve,
755b32598bfSZexi Yu 			struct hpre_ecc_msg *msg, struct bignum *privkey,
756b32598bfSZexi Yu 			struct ecc_public_key *pubkey)
757b32598bfSZexi Yu {
758b32598bfSZexi Yu 	struct hpre_ecc_dh *ecc_dh = &msg->param_size.ecc_dh;
759b32598bfSZexi Yu 	uint8_t *p = msg->key;
760b32598bfSZexi Yu 	uint8_t *a = p + msg->key_bytes;
761b32598bfSZexi Yu 	uint8_t *d = a + msg->key_bytes;
762b32598bfSZexi Yu 	uint8_t *b = d + msg->key_bytes;
763b32598bfSZexi Yu 	uint8_t *x = msg->in;
764b32598bfSZexi Yu 	uint8_t *y = x + msg->key_bytes;
765b32598bfSZexi Yu 	enum hisi_drv_status ret = HISI_QM_DRVCRYPT_NO_ERR;
766b32598bfSZexi Yu 
767b32598bfSZexi Yu 	memcpy(p, curve->p, msg->curve_bytes);
768b32598bfSZexi Yu 	memcpy(a, curve->a, msg->curve_bytes);
769b32598bfSZexi Yu 	crypto_bignum_bn2bin(privkey, d);
770b32598bfSZexi Yu 	ecc_dh->d_bytes = crypto_bignum_num_bytes(privkey);
771b32598bfSZexi Yu 	if (is_all_zero(d, ecc_dh->d_bytes, "ecc dh d"))
772b32598bfSZexi Yu 		return HISI_QM_DRVCRYPT_EINVAL;
773b32598bfSZexi Yu 
774b32598bfSZexi Yu 	memcpy(b, curve->b, msg->curve_bytes);
775b32598bfSZexi Yu 
776b32598bfSZexi Yu 	ecc_dh->x_bytes = msg->curve_bytes;
777b32598bfSZexi Yu 	ecc_dh->y_bytes = msg->curve_bytes;
778b32598bfSZexi Yu 	if (!pubkey) {
779b32598bfSZexi Yu 		/* gen key pair */
780b32598bfSZexi Yu 		memcpy(x, curve->x, ecc_dh->x_bytes);
781b32598bfSZexi Yu 		memcpy(y, curve->y, ecc_dh->y_bytes);
782b32598bfSZexi Yu 	} else {
783b32598bfSZexi Yu 		/* do shared secret */
784b32598bfSZexi Yu 		crypto_bignum_bn2bin(pubkey->x, x);
785b32598bfSZexi Yu 		ecc_dh->x_bytes = crypto_bignum_num_bytes(pubkey->x);
786b32598bfSZexi Yu 		crypto_bignum_bn2bin(pubkey->y, y);
787b32598bfSZexi Yu 		ecc_dh->y_bytes = crypto_bignum_num_bytes(pubkey->y);
788b32598bfSZexi Yu 	}
789b32598bfSZexi Yu 
790b32598bfSZexi Yu 	ret = hpre_ecc_dh_transfer_key(msg);
791b32598bfSZexi Yu 	if (ret)
792b32598bfSZexi Yu 		return ret;
793b32598bfSZexi Yu 
794b32598bfSZexi Yu 	return hpre_ecc_dh_transfer_in(msg);
795b32598bfSZexi Yu }
796b32598bfSZexi Yu 
hpre_ecc_dh_params_alloc(struct hpre_ecc_msg * msg)797b32598bfSZexi Yu static enum hisi_drv_status hpre_ecc_dh_params_alloc(struct hpre_ecc_msg *msg)
798b32598bfSZexi Yu {
799b32598bfSZexi Yu 	uint32_t size = HPRE_ECC_DH_TOTAL_BUF_SIZE(msg->key_bytes);
800b32598bfSZexi Yu 	uint8_t *data = NULL;
801b32598bfSZexi Yu 
802b32598bfSZexi Yu 	data = calloc(1, size);
803b32598bfSZexi Yu 	if (!data) {
804b32598bfSZexi Yu 		EMSG("Fail to alloc ecc dh total buf");
805b32598bfSZexi Yu 		return HISI_QM_DRVCRYPT_ENOMEM;
806b32598bfSZexi Yu 	}
807b32598bfSZexi Yu 
808b32598bfSZexi Yu 	msg->key = data;
809b32598bfSZexi Yu 	msg->key_dma = virt_to_phys(msg->key);
810b32598bfSZexi Yu 
811b32598bfSZexi Yu 	msg->in = msg->key + ECC_DH_KEY_SIZE(msg->key_bytes);
812b32598bfSZexi Yu 	msg->in_dma = msg->key_dma + ECC_DH_KEY_SIZE(msg->key_bytes);
813b32598bfSZexi Yu 	msg->out = msg->in + ECC_DH_IN_SIZE(msg->key_bytes);
814b32598bfSZexi Yu 	msg->out_dma = msg->in_dma + ECC_DH_IN_SIZE(msg->key_bytes);
815b32598bfSZexi Yu 
816b32598bfSZexi Yu 	return HISI_QM_DRVCRYPT_NO_ERR;
817b32598bfSZexi Yu }
818b32598bfSZexi Yu 
hpre_ecc_request_deinit(struct hpre_ecc_msg * msg)819b32598bfSZexi Yu static void hpre_ecc_request_deinit(struct hpre_ecc_msg *msg)
820b32598bfSZexi Yu {
821b32598bfSZexi Yu 	if (msg->key) {
822*8448708bSZexi Yu 		free_wipe(msg->key);
823b32598bfSZexi Yu 		msg->key = NULL;
824b32598bfSZexi Yu 	}
825b32598bfSZexi Yu }
826b32598bfSZexi Yu 
hpre_ecc_request_init(const struct hpre_ecc_curve * curve,struct hpre_ecc_msg * msg,struct bignum * d,struct ecc_public_key * pubkey)827b32598bfSZexi Yu static TEE_Result hpre_ecc_request_init(const struct hpre_ecc_curve *curve,
828b32598bfSZexi Yu 					struct hpre_ecc_msg *msg,
829b32598bfSZexi Yu 					struct bignum *d,
830b32598bfSZexi Yu 					struct ecc_public_key *pubkey)
831b32598bfSZexi Yu {
832b32598bfSZexi Yu 	enum hisi_drv_status ret = HISI_QM_DRVCRYPT_NO_ERR;
833b32598bfSZexi Yu 
834b32598bfSZexi Yu 	msg->alg_type = HPRE_ALG_ECDH_MULTIPLY;
835b32598bfSZexi Yu 
836b32598bfSZexi Yu 	if (curve->id == TEE_ECC_CURVE_SM2)
837b32598bfSZexi Yu 		msg->sm2_sp = true;
838b32598bfSZexi Yu 
839b32598bfSZexi Yu 	msg->curve_bytes = BITS_TO_BYTES(curve->key_bits);
840b32598bfSZexi Yu 	msg->key_bytes = hpre_ecc_get_hw_kbytes(curve->key_bits);
841b32598bfSZexi Yu 	if (!msg->key_bytes)
842b32598bfSZexi Yu 		return TEE_ERROR_BAD_PARAMETERS;
843b32598bfSZexi Yu 
844b32598bfSZexi Yu 	ret = hpre_ecc_dh_params_alloc(msg);
845b32598bfSZexi Yu 	if (ret)
846b32598bfSZexi Yu 		return TEE_ERROR_OUT_OF_MEMORY;
847b32598bfSZexi Yu 
848b32598bfSZexi Yu 	ret = hpre_ecc_dh_params_fill(curve, msg, d, pubkey);
849b32598bfSZexi Yu 	if (ret) {
850b32598bfSZexi Yu 		hpre_ecc_request_deinit(msg);
851b32598bfSZexi Yu 		return TEE_ERROR_BAD_STATE;
852b32598bfSZexi Yu 	}
853b32598bfSZexi Yu 
854b32598bfSZexi Yu 	msg->param_size.ecc_dh.rx_bytes = msg->curve_bytes;
855b32598bfSZexi Yu 	msg->param_size.ecc_dh.ry_bytes = msg->curve_bytes;
856b32598bfSZexi Yu 
857b32598bfSZexi Yu 	return TEE_SUCCESS;
858b32598bfSZexi Yu }
859b32598bfSZexi Yu 
gen_random_k(struct bignum * d,size_t key_bits,const uint8_t * n)860b32598bfSZexi Yu static TEE_Result gen_random_k(struct bignum *d, size_t key_bits,
861b32598bfSZexi Yu 			       const uint8_t *n)
862b32598bfSZexi Yu {
863b32598bfSZexi Yu 	size_t size = BITS_TO_BYTES(key_bits);
864b32598bfSZexi Yu 	uint8_t *rand_k = NULL;
865b32598bfSZexi Yu 	size_t i = 0;
866b32598bfSZexi Yu 	size_t j = 0;
867b32598bfSZexi Yu 	TEE_Result ret = TEE_SUCCESS;
868b32598bfSZexi Yu 
869b32598bfSZexi Yu 	if (!d || !n) {
870b32598bfSZexi Yu 		EMSG("Input param is NULL.");
871b32598bfSZexi Yu 		return TEE_ERROR_BAD_PARAMETERS;
872b32598bfSZexi Yu 	}
873b32598bfSZexi Yu 
874b32598bfSZexi Yu 	rand_k = malloc(size);
875b32598bfSZexi Yu 	if (!rand_k) {
876b32598bfSZexi Yu 		EMSG("Fail to malloc rand_k buf.");
877b32598bfSZexi Yu 		return TEE_ERROR_OUT_OF_MEMORY;
878b32598bfSZexi Yu 	}
879b32598bfSZexi Yu 
880b32598bfSZexi Yu 	for (i = 0; i < size; i++) {
881b32598bfSZexi Yu 		if (n[i] > 1) {
882b32598bfSZexi Yu 			rand_k[i] = n[i] - 1;
883b32598bfSZexi Yu 			break;
884b32598bfSZexi Yu 		}
885b32598bfSZexi Yu 		rand_k[i] = n[i];
886b32598bfSZexi Yu 	}
887b32598bfSZexi Yu 
888b32598bfSZexi Yu 	j = i + 1;
889b32598bfSZexi Yu 	if (hw_get_random_bytes(rand_k + j, size - j)) {
890b32598bfSZexi Yu 		EMSG("Fail to fill rand_k buf.");
891b32598bfSZexi Yu 		free(rand_k);
892b32598bfSZexi Yu 		return TEE_ERROR_NO_DATA;
893b32598bfSZexi Yu 	}
894b32598bfSZexi Yu 
895b32598bfSZexi Yu 	ret = crypto_bignum_bin2bn(rand_k, size, d);
896b32598bfSZexi Yu 	if (ret)
897b32598bfSZexi Yu 		EMSG("Rand_k bin2bn fail.");
898b32598bfSZexi Yu 
899b32598bfSZexi Yu 	free(rand_k);
900b32598bfSZexi Yu 
901b32598bfSZexi Yu 	return ret;
902b32598bfSZexi Yu }
903b32598bfSZexi Yu 
hpre_ecc_gen_keypair(struct ecc_keypair * key,size_t size_bits)904b32598bfSZexi Yu static TEE_Result hpre_ecc_gen_keypair(struct ecc_keypair *key,
905b32598bfSZexi Yu 				       size_t size_bits)
906b32598bfSZexi Yu {
907b32598bfSZexi Yu 	struct hpre_ecc_msg msg = { };
908b32598bfSZexi Yu 	const struct hpre_ecc_curve *curve = NULL;
909b32598bfSZexi Yu 	struct hpre_ecc_dh *ecc_dh = NULL;
910b32598bfSZexi Yu 	TEE_Result ret = TEE_SUCCESS;
911b32598bfSZexi Yu 
912b32598bfSZexi Yu 	if (!key || !key->d || !key->x || !key->y) {
913b32598bfSZexi Yu 		EMSG("Invalid ecc_gen_keypair input parameters.");
914b32598bfSZexi Yu 		return TEE_ERROR_BAD_PARAMETERS;
915b32598bfSZexi Yu 	}
916b32598bfSZexi Yu 
917b32598bfSZexi Yu 	curve = get_curve_from_list(key->curve);
918b32598bfSZexi Yu 	if (!curve) {
919b32598bfSZexi Yu 		EMSG("Fail to get valid curve, id %"PRIu32, key->curve);
920b32598bfSZexi Yu 		return TEE_ERROR_NOT_SUPPORTED;
921b32598bfSZexi Yu 	}
922b32598bfSZexi Yu 
923b32598bfSZexi Yu 	if (BITS_TO_BYTES(size_bits) != BITS_TO_BYTES(curve->key_bits)) {
924b32598bfSZexi Yu 		EMSG("Invalid size_bits %zu.", size_bits);
925b32598bfSZexi Yu 		return TEE_ERROR_BAD_PARAMETERS;
926b32598bfSZexi Yu 	}
927b32598bfSZexi Yu 
928b32598bfSZexi Yu 	ret = gen_random_k(key->d, curve->key_bits, curve->n);
929b32598bfSZexi Yu 	if (ret)
930b32598bfSZexi Yu 		return ret;
931b32598bfSZexi Yu 
932b32598bfSZexi Yu 	ret = hpre_ecc_request_init(curve, &msg, key->d, NULL);
933b32598bfSZexi Yu 	if (ret) {
934b32598bfSZexi Yu 		EMSG("Ecc key pair request init fail.");
935b32598bfSZexi Yu 		return ret;
936b32598bfSZexi Yu 	}
937b32598bfSZexi Yu 
938b32598bfSZexi Yu 	ret = hpre_do_ecc_task(&msg);
939b32598bfSZexi Yu 	if (ret) {
940b32598bfSZexi Yu 		EMSG("Fail to do ecc key pair task! ret = 0x%"PRIX16, ret);
941b32598bfSZexi Yu 		goto done;
942b32598bfSZexi Yu 	}
943b32598bfSZexi Yu 
944b32598bfSZexi Yu 	ecc_dh = &msg.param_size.ecc_dh;
945b32598bfSZexi Yu 	ret = crypto_bignum_bin2bn(msg.out, ecc_dh->rx_bytes, key->x);
946b32598bfSZexi Yu 	if (ret) {
947b32598bfSZexi Yu 		EMSG("Fail to trans res x to bn.");
948b32598bfSZexi Yu 		goto done;
949b32598bfSZexi Yu 	}
950b32598bfSZexi Yu 
951b32598bfSZexi Yu 	ret = crypto_bignum_bin2bn(msg.out + msg.key_bytes,
952b32598bfSZexi Yu 				   ecc_dh->ry_bytes, key->y);
953b32598bfSZexi Yu 	if (ret)
954b32598bfSZexi Yu 		EMSG("Fail to trans res y to bn.");
955b32598bfSZexi Yu done:
956b32598bfSZexi Yu 	hpre_ecc_request_deinit(&msg);
957b32598bfSZexi Yu 	return ret;
958b32598bfSZexi Yu }
959b32598bfSZexi Yu 
hpre_ecc_do_shared_secret(struct drvcrypt_secret_data * sdata)960b32598bfSZexi Yu static TEE_Result hpre_ecc_do_shared_secret(struct drvcrypt_secret_data *sdata)
961b32598bfSZexi Yu {
962b32598bfSZexi Yu 	struct hpre_ecc_msg msg = { };
963b32598bfSZexi Yu 	const struct hpre_ecc_curve *curve = NULL;
964b32598bfSZexi Yu 	struct ecc_public_key *pubkey = NULL;
965b32598bfSZexi Yu 	struct ecc_keypair *ecc_key = NULL;
966b32598bfSZexi Yu 	struct hpre_ecc_dh *ecc_dh = NULL;
967b32598bfSZexi Yu 	TEE_Result ret = TEE_SUCCESS;
968b32598bfSZexi Yu 
969b32598bfSZexi Yu 	if (!sdata || !sdata->key_priv || !sdata->key_pub) {
970b32598bfSZexi Yu 		EMSG("Invalid ecc_do_shared_secret input parameters.");
971b32598bfSZexi Yu 		return TEE_ERROR_BAD_PARAMETERS;
972b32598bfSZexi Yu 	}
973b32598bfSZexi Yu 
974b32598bfSZexi Yu 	ecc_key = sdata->key_priv;
975b32598bfSZexi Yu 	pubkey = sdata->key_pub;
976b32598bfSZexi Yu 
977b32598bfSZexi Yu 	curve = get_curve_from_list(ecc_key->curve);
978b32598bfSZexi Yu 	if (!curve) {
979b32598bfSZexi Yu 		EMSG("Fail to get valid curve, id %"PRIu32, ecc_key->curve);
980b32598bfSZexi Yu 		return TEE_ERROR_NOT_SUPPORTED;
981b32598bfSZexi Yu 	}
982b32598bfSZexi Yu 
983b32598bfSZexi Yu 	if (sdata->size_sec != BITS_TO_BYTES(curve->key_bits)) {
984b32598bfSZexi Yu 		EMSG("Invalid sdata size_sec %zu.", sdata->size_sec);
985b32598bfSZexi Yu 		return TEE_ERROR_BAD_PARAMETERS;
986b32598bfSZexi Yu 	}
987b32598bfSZexi Yu 
988b32598bfSZexi Yu 	ret = hpre_ecc_request_init(curve, &msg, ecc_key->d, pubkey);
989b32598bfSZexi Yu 	if (ret) {
990b32598bfSZexi Yu 		EMSG("Ecc shared secret request init fail.");
991b32598bfSZexi Yu 		return ret;
992b32598bfSZexi Yu 	}
993b32598bfSZexi Yu 
994b32598bfSZexi Yu 	ret = hpre_do_ecc_task(&msg);
995b32598bfSZexi Yu 	if (ret) {
996b32598bfSZexi Yu 		EMSG("Fail to do ecc shared secret task! ret = 0x%"PRIX32,
997b32598bfSZexi Yu 		     ret);
998b32598bfSZexi Yu 		goto done;
999b32598bfSZexi Yu 	}
1000b32598bfSZexi Yu 
1001b32598bfSZexi Yu 	ecc_dh = &msg.param_size.ecc_dh;
1002b32598bfSZexi Yu 	/*
1003b32598bfSZexi Yu 	 * Only take the x coordinate as the output result, according to
1004b32598bfSZexi Yu 	 * soft computing implementation.
1005b32598bfSZexi Yu 	 */
1006b32598bfSZexi Yu 	memcpy(sdata->secret.data, msg.out, ecc_dh->rx_bytes);
1007b32598bfSZexi Yu 	sdata->secret.length = ecc_dh->rx_bytes;
1008b32598bfSZexi Yu 	memzero_explicit(msg.out, ECC_DH_OUT_SIZE(msg.key_bytes));
1009b32598bfSZexi Yu 
1010b32598bfSZexi Yu done:
1011b32598bfSZexi Yu 	hpre_ecc_request_deinit(&msg);
1012b32598bfSZexi Yu 	return ret;
1013b32598bfSZexi Yu }
1014b32598bfSZexi Yu 
1015b5203cb1Syuzexi static enum hisi_drv_status
hpre_ecc_sign_params_fill(const struct hpre_ecc_curve * curve,struct hpre_ecc_msg * msg,struct drvcrypt_sign_data * sdata,struct bignum * rand_k)1016b5203cb1Syuzexi hpre_ecc_sign_params_fill(const struct hpre_ecc_curve *curve,
1017b5203cb1Syuzexi 			  struct hpre_ecc_msg *msg,
1018b5203cb1Syuzexi 			  struct drvcrypt_sign_data *sdata,
1019b5203cb1Syuzexi 			  struct bignum *rand_k)
1020b5203cb1Syuzexi {
1021b5203cb1Syuzexi 	struct ecc_keypair *ecc_key = sdata->key;
1022b5203cb1Syuzexi 	struct hpre_ecc_sign *ecc_sign = &msg->param_size.ecc_sign;
1023b5203cb1Syuzexi 	uint8_t *p = msg->key;
1024b5203cb1Syuzexi 	uint8_t *a = p + msg->key_bytes;
1025b5203cb1Syuzexi 	uint8_t *d = a + msg->key_bytes;
1026b5203cb1Syuzexi 	uint8_t *b = d + msg->key_bytes;
1027b5203cb1Syuzexi 	uint8_t *n = b + msg->key_bytes;
1028b5203cb1Syuzexi 	uint8_t *gx = n + msg->key_bytes;
1029b5203cb1Syuzexi 	uint8_t *gy = gx + msg->key_bytes;
1030b5203cb1Syuzexi 	uint8_t *e = msg->in;
1031b5203cb1Syuzexi 	uint8_t *k = e + msg->key_bytes;
1032b5203cb1Syuzexi 	enum hisi_drv_status ret = HISI_QM_DRVCRYPT_NO_ERR;
1033b5203cb1Syuzexi 
1034b5203cb1Syuzexi 	memcpy(p, curve->p, msg->curve_bytes);
1035b5203cb1Syuzexi 	memcpy(a, curve->a, msg->curve_bytes);
1036b5203cb1Syuzexi 	crypto_bignum_bn2bin(ecc_key->d, d);
1037b5203cb1Syuzexi 	ecc_sign->d_bytes = crypto_bignum_num_bytes(ecc_key->d);
1038b5203cb1Syuzexi 	memcpy(b, curve->b, msg->curve_bytes);
1039b5203cb1Syuzexi 	memcpy(n, curve->n, msg->curve_bytes);
1040b5203cb1Syuzexi 	memcpy(gx, curve->x, msg->curve_bytes);
1041b5203cb1Syuzexi 	memcpy(gy, curve->y, msg->curve_bytes);
1042b5203cb1Syuzexi 	crypto_bignum_bn2bin(rand_k, k);
1043b5203cb1Syuzexi 	ecc_sign->k_bytes = crypto_bignum_num_bytes(rand_k);
1044b5203cb1Syuzexi 
1045b5203cb1Syuzexi 	ecc_sign->e_bytes = MIN(sdata->message.length, msg->curve_bytes);
1046b5203cb1Syuzexi 	memcpy(e, sdata->message.data, ecc_sign->e_bytes);
1047b5203cb1Syuzexi 	if (is_all_zero(e, ecc_sign->e_bytes, "ecc sign msg_e"))
1048b5203cb1Syuzexi 		return HISI_QM_DRVCRYPT_EINVAL;
1049b5203cb1Syuzexi 
1050b5203cb1Syuzexi 	ret = hpre_ecc_curve_to_hpre_bin(p, a, b, n, gx, gy, msg->curve_bytes,
1051b5203cb1Syuzexi 					 msg->key_bytes);
1052b5203cb1Syuzexi 	if (ret)
1053b5203cb1Syuzexi 		return ret;
1054b5203cb1Syuzexi 
1055b5203cb1Syuzexi 	ret = hpre_bin_from_crypto_bin(d, d, msg->key_bytes,
1056b5203cb1Syuzexi 				       ecc_sign->d_bytes);
1057b5203cb1Syuzexi 	if (ret) {
1058b5203cb1Syuzexi 		EMSG("Fail to transfer ecdsa sign d");
1059b5203cb1Syuzexi 		return ret;
1060b5203cb1Syuzexi 	}
1061b5203cb1Syuzexi 
1062b5203cb1Syuzexi 	ret = hpre_bin_from_crypto_bin(e, e, msg->key_bytes,
1063b5203cb1Syuzexi 				       ecc_sign->e_bytes);
1064b5203cb1Syuzexi 	if (ret) {
1065b5203cb1Syuzexi 		EMSG("Fail to transfer ecdsa sign e");
1066b5203cb1Syuzexi 		return ret;
1067b5203cb1Syuzexi 	}
1068b5203cb1Syuzexi 
1069b5203cb1Syuzexi 	ret = hpre_bin_from_crypto_bin(k, k, msg->key_bytes,
1070b5203cb1Syuzexi 				       ecc_sign->k_bytes);
1071b5203cb1Syuzexi 	if (ret)
1072b5203cb1Syuzexi 		EMSG("Fail to transfer ecdsa sign k");
1073b5203cb1Syuzexi 
1074b5203cb1Syuzexi 	return ret;
1075b5203cb1Syuzexi }
1076b5203cb1Syuzexi 
hpre_ecc_sign_params_alloc(struct hpre_ecc_msg * msg)1077b5203cb1Syuzexi static enum hisi_drv_status hpre_ecc_sign_params_alloc(struct hpre_ecc_msg *msg)
1078b5203cb1Syuzexi {
1079b5203cb1Syuzexi 	uint32_t size = HPRE_ECC_SIGN_TOTAL_BUF_SIZE(msg->key_bytes);
1080b5203cb1Syuzexi 	uint8_t *data = NULL;
1081b5203cb1Syuzexi 
1082b5203cb1Syuzexi 	data = calloc(1, size);
1083b5203cb1Syuzexi 	if (!data) {
1084b5203cb1Syuzexi 		EMSG("Fail to alloc ecc sign total buf");
1085b5203cb1Syuzexi 		return HISI_QM_DRVCRYPT_ENOMEM;
1086b5203cb1Syuzexi 	}
1087b5203cb1Syuzexi 
1088b5203cb1Syuzexi 	msg->key = data;
1089b5203cb1Syuzexi 	msg->key_dma = virt_to_phys(msg->key);
1090b5203cb1Syuzexi 	if (!msg->key_dma) {
1091b5203cb1Syuzexi 		EMSG("Fail to get key dma addr");
1092b5203cb1Syuzexi 		free(data);
1093b5203cb1Syuzexi 		return HISI_QM_DRVCRYPT_EFAULT;
1094b5203cb1Syuzexi 	}
1095b5203cb1Syuzexi 
1096b5203cb1Syuzexi 	msg->in = msg->key + ECC_SIGN_KEY_SIZE(msg->key_bytes);
1097b5203cb1Syuzexi 	msg->in_dma = msg->key_dma + ECC_SIGN_KEY_SIZE(msg->key_bytes);
1098b5203cb1Syuzexi 	msg->out = msg->in + ECC_SIGN_IN_SIZE(msg->key_bytes);
1099b5203cb1Syuzexi 	msg->out_dma = msg->in_dma + ECC_SIGN_IN_SIZE(msg->key_bytes);
1100b5203cb1Syuzexi 
1101b5203cb1Syuzexi 	return HISI_QM_DRVCRYPT_NO_ERR;
1102b5203cb1Syuzexi }
1103b5203cb1Syuzexi 
hpre_ecc_sign_request_deinit(struct hpre_ecc_msg * msg)1104b5203cb1Syuzexi static void hpre_ecc_sign_request_deinit(struct hpre_ecc_msg *msg)
1105b5203cb1Syuzexi {
1106b5203cb1Syuzexi 	if (msg->key) {
1107b5203cb1Syuzexi 		free_wipe(msg->key);
1108b5203cb1Syuzexi 		msg->key = NULL;
1109b5203cb1Syuzexi 	}
1110b5203cb1Syuzexi }
1111b5203cb1Syuzexi 
1112b5203cb1Syuzexi static TEE_Result
hpre_ecc_sign_request_init(const struct hpre_ecc_curve * curve,struct hpre_ecc_msg * msg,struct drvcrypt_sign_data * sdata,struct bignum * rand_k)1113b5203cb1Syuzexi hpre_ecc_sign_request_init(const struct hpre_ecc_curve *curve,
1114b5203cb1Syuzexi 			   struct hpre_ecc_msg *msg,
1115b5203cb1Syuzexi 			   struct drvcrypt_sign_data *sdata,
1116b5203cb1Syuzexi 			   struct bignum *rand_k)
1117b5203cb1Syuzexi {
1118b5203cb1Syuzexi 	enum hisi_drv_status ret = HISI_QM_DRVCRYPT_NO_ERR;
1119b5203cb1Syuzexi 
1120b5203cb1Syuzexi 	if (curve->id == TEE_ECC_CURVE_SM2)
1121b5203cb1Syuzexi 		msg->alg_type = HPRE_ALG_SM2_SIGN;
1122b5203cb1Syuzexi 	else
1123b5203cb1Syuzexi 		msg->alg_type = HPRE_ALG_ECDSA_SIGN;
1124b5203cb1Syuzexi 	msg->curve_bytes = BITS_TO_BYTES(curve->key_bits);
1125b5203cb1Syuzexi 	msg->key_bytes = hpre_ecc_get_hw_kbytes(curve->key_bits);
1126b5203cb1Syuzexi 	if (!msg->key_bytes)
1127b5203cb1Syuzexi 		return TEE_ERROR_BAD_PARAMETERS;
1128b5203cb1Syuzexi 
1129b5203cb1Syuzexi 	ret = hpre_ecc_sign_params_alloc(msg);
1130b5203cb1Syuzexi 	if (ret)
1131b5203cb1Syuzexi 		return TEE_ERROR_OUT_OF_MEMORY;
1132b5203cb1Syuzexi 
1133b5203cb1Syuzexi 	ret = hpre_ecc_sign_params_fill(curve, msg, sdata, rand_k);
1134b5203cb1Syuzexi 	if (ret) {
1135b5203cb1Syuzexi 		hpre_ecc_sign_request_deinit(msg);
1136b5203cb1Syuzexi 		return TEE_ERROR_BAD_STATE;
1137b5203cb1Syuzexi 	}
1138b5203cb1Syuzexi 
1139b5203cb1Syuzexi 	msg->param_size.ecc_sign.r_bytes = msg->curve_bytes;
1140b5203cb1Syuzexi 	msg->param_size.ecc_sign.s_bytes = msg->curve_bytes;
1141b5203cb1Syuzexi 
1142b5203cb1Syuzexi 	return TEE_SUCCESS;
1143b5203cb1Syuzexi }
1144b5203cb1Syuzexi 
hpre_ecdsa_param_check(struct drvcrypt_sign_data * sdata,const struct hpre_ecc_curve * curve)1145b5203cb1Syuzexi static TEE_Result hpre_ecdsa_param_check(struct drvcrypt_sign_data *sdata,
1146b5203cb1Syuzexi 					 const struct hpre_ecc_curve *curve)
1147b5203cb1Syuzexi {
1148b5203cb1Syuzexi 	if (sdata->size_sec != BITS_TO_BYTES(curve->key_bits)) {
1149b5203cb1Syuzexi 		EMSG("Invalid sdata size_sec %zu", sdata->size_sec);
1150b5203cb1Syuzexi 		return TEE_ERROR_BAD_PARAMETERS;
1151b5203cb1Syuzexi 	}
1152b5203cb1Syuzexi 
1153b5203cb1Syuzexi 	return TEE_SUCCESS;
1154b5203cb1Syuzexi }
1155b5203cb1Syuzexi 
hpre_ecc_sign_get_data_out(struct hpre_ecc_msg * msg,struct drvcrypt_sign_data * sdata)1156b5203cb1Syuzexi static void hpre_ecc_sign_get_data_out(struct hpre_ecc_msg *msg,
1157b5203cb1Syuzexi 				       struct drvcrypt_sign_data *sdata)
1158b5203cb1Syuzexi {
1159b5203cb1Syuzexi 	struct hpre_ecc_sign *ecc_sign;
1160b5203cb1Syuzexi 
1161b5203cb1Syuzexi 	ecc_sign = &msg->param_size.ecc_sign;
1162b5203cb1Syuzexi 	sdata->signature.length = ecc_sign->r_bytes + ecc_sign->s_bytes;
1163b5203cb1Syuzexi 	memcpy(sdata->signature.data, msg->out, ecc_sign->r_bytes);
1164b5203cb1Syuzexi 	memcpy(sdata->signature.data + ecc_sign->r_bytes, msg->out +
1165b5203cb1Syuzexi 	       msg->key_bytes, ecc_sign->s_bytes);
1166b5203cb1Syuzexi }
1167b5203cb1Syuzexi 
hpre_ecc_sign(struct drvcrypt_sign_data * sdata)1168b5203cb1Syuzexi static TEE_Result hpre_ecc_sign(struct drvcrypt_sign_data *sdata)
1169b5203cb1Syuzexi {
1170b5203cb1Syuzexi 	struct hpre_ecc_msg msg = { };
1171b5203cb1Syuzexi 	const struct hpre_ecc_curve *curve = NULL;
1172b5203cb1Syuzexi 	struct ecc_keypair *ecc_key = NULL;
1173b5203cb1Syuzexi 	struct bignum *rand_k = NULL;
1174b5203cb1Syuzexi 	TEE_Result ret = TEE_SUCCESS;
1175b5203cb1Syuzexi 
1176b5203cb1Syuzexi 	if (!sdata || !sdata->key) {
1177b5203cb1Syuzexi 		EMSG("Invalid ecc_sign input parameters");
1178b5203cb1Syuzexi 		return TEE_ERROR_BAD_PARAMETERS;
1179b5203cb1Syuzexi 	}
1180b5203cb1Syuzexi 
1181b5203cb1Syuzexi 	ecc_key = sdata->key;
1182b5203cb1Syuzexi 
1183b5203cb1Syuzexi 	curve = get_curve_from_list(ecc_key->curve);
1184b5203cb1Syuzexi 	if (!curve) {
1185b5203cb1Syuzexi 		EMSG("Fail to get valid curve, id %"PRIu32, ecc_key->curve);
1186b5203cb1Syuzexi 		return TEE_ERROR_NOT_SUPPORTED;
1187b5203cb1Syuzexi 	}
1188b5203cb1Syuzexi 
1189b5203cb1Syuzexi 	ret = hpre_ecdsa_param_check(sdata, curve);
1190b5203cb1Syuzexi 	if (ret)
1191b5203cb1Syuzexi 		return ret;
1192b5203cb1Syuzexi 
1193b5203cb1Syuzexi 	rand_k = crypto_bignum_allocate(curve->key_bits);
1194b5203cb1Syuzexi 	if (!rand_k) {
1195b5203cb1Syuzexi 		EMSG("Fail to alloc private k");
1196b5203cb1Syuzexi 		return TEE_ERROR_OUT_OF_MEMORY;
1197b5203cb1Syuzexi 	}
1198b5203cb1Syuzexi 
1199b5203cb1Syuzexi 	ret = gen_random_k(rand_k, curve->key_bits, curve->n);
1200b5203cb1Syuzexi 	if (ret)
1201b5203cb1Syuzexi 		goto free_key;
1202b5203cb1Syuzexi 
1203b5203cb1Syuzexi 	ret = hpre_ecc_sign_request_init(curve, &msg, sdata, rand_k);
1204b5203cb1Syuzexi 	if (ret) {
1205b5203cb1Syuzexi 		EMSG("Ecc sign request init fail");
1206b5203cb1Syuzexi 		goto free_key;
1207b5203cb1Syuzexi 	}
1208b5203cb1Syuzexi 
1209b5203cb1Syuzexi 	ret = hpre_do_ecc_task(&msg);
1210b5203cb1Syuzexi 	if (ret) {
1211b5203cb1Syuzexi 		EMSG("Fail to do ecc sign task! ret = 0x%"PRIX16, ret);
1212b5203cb1Syuzexi 		goto done;
1213b5203cb1Syuzexi 	}
1214b5203cb1Syuzexi 
1215b5203cb1Syuzexi 	hpre_ecc_sign_get_data_out(&msg, sdata);
1216b5203cb1Syuzexi 
1217b5203cb1Syuzexi done:
1218b5203cb1Syuzexi 	hpre_ecc_sign_request_deinit(&msg);
1219b5203cb1Syuzexi free_key:
1220b5203cb1Syuzexi 	crypto_bignum_free(&rand_k);
1221b5203cb1Syuzexi 
1222b5203cb1Syuzexi 	return ret;
1223b5203cb1Syuzexi }
1224b5203cb1Syuzexi 
1225b5203cb1Syuzexi static enum hisi_drv_status
hpre_ecc_verify_transfer_key(struct hpre_ecc_msg * msg)1226b5203cb1Syuzexi hpre_ecc_verify_transfer_key(struct hpre_ecc_msg *msg)
1227b5203cb1Syuzexi {
1228b5203cb1Syuzexi 	struct hpre_ecc_verify *ecc_verify = &msg->param_size.ecc_verify;
1229b5203cb1Syuzexi 	uint8_t *p = msg->key;
1230b5203cb1Syuzexi 	uint8_t *a = p + msg->key_bytes;
1231b5203cb1Syuzexi 	uint8_t *b = a + msg->key_bytes;
1232b5203cb1Syuzexi 	uint8_t *n = b + msg->key_bytes;
1233b5203cb1Syuzexi 	uint8_t *gx = n + msg->key_bytes;
1234b5203cb1Syuzexi 	uint8_t *gy = gx + msg->key_bytes;
1235b5203cb1Syuzexi 	uint8_t *pubx = gy + msg->key_bytes;
1236b5203cb1Syuzexi 	uint8_t *puby = pubx + msg->key_bytes;
1237b5203cb1Syuzexi 	enum hisi_drv_status ret = HISI_QM_DRVCRYPT_NO_ERR;
1238b5203cb1Syuzexi 
1239b5203cb1Syuzexi 	ret = hpre_ecc_curve_to_hpre_bin(p, a, b, n, gx, gy, msg->curve_bytes,
1240b5203cb1Syuzexi 					 msg->key_bytes);
1241b5203cb1Syuzexi 	if (ret)
1242b5203cb1Syuzexi 		return ret;
1243b5203cb1Syuzexi 
1244b5203cb1Syuzexi 	ret = hpre_bin_from_crypto_bin(pubx, pubx, msg->key_bytes,
1245b5203cb1Syuzexi 				       ecc_verify->pubx_bytes);
1246b5203cb1Syuzexi 	if (ret) {
1247b5203cb1Syuzexi 		EMSG("Fail to transfer ecdsa verify pub_x");
1248b5203cb1Syuzexi 		return ret;
1249b5203cb1Syuzexi 	}
1250b5203cb1Syuzexi 
1251b5203cb1Syuzexi 	ret = hpre_bin_from_crypto_bin(puby, puby, msg->key_bytes,
1252b5203cb1Syuzexi 				       ecc_verify->puby_bytes);
1253b5203cb1Syuzexi 	if (ret)
1254b5203cb1Syuzexi 		EMSG("Fail to transfer ecdsa verify pub_y");
1255b5203cb1Syuzexi 
1256b5203cb1Syuzexi 	return ret;
1257b5203cb1Syuzexi }
1258b5203cb1Syuzexi 
1259b5203cb1Syuzexi static enum hisi_drv_status
hpre_ecc_verify_transfer_in(struct hpre_ecc_msg * msg)1260b5203cb1Syuzexi hpre_ecc_verify_transfer_in(struct hpre_ecc_msg *msg)
1261b5203cb1Syuzexi {
1262b5203cb1Syuzexi 	struct hpre_ecc_verify *ecc_verify = &msg->param_size.ecc_verify;
1263b5203cb1Syuzexi 	uint8_t *e = msg->in;
1264b5203cb1Syuzexi 	uint8_t *s = e + msg->key_bytes;
1265b5203cb1Syuzexi 	uint8_t *r = s + msg->key_bytes;
1266b5203cb1Syuzexi 	enum hisi_drv_status ret = HISI_QM_DRVCRYPT_NO_ERR;
1267b5203cb1Syuzexi 
1268b5203cb1Syuzexi 	ret = hpre_bin_from_crypto_bin(e, e, msg->key_bytes,
1269b5203cb1Syuzexi 				       ecc_verify->e_bytes);
1270b5203cb1Syuzexi 	if (ret) {
1271b5203cb1Syuzexi 		EMSG("Fail to transfer ecdsa verify e");
1272b5203cb1Syuzexi 		return ret;
1273b5203cb1Syuzexi 	}
1274b5203cb1Syuzexi 
1275b5203cb1Syuzexi 	ret = hpre_bin_from_crypto_bin(s, s, msg->key_bytes,
1276b5203cb1Syuzexi 				       ecc_verify->s_bytes);
1277b5203cb1Syuzexi 	if (ret) {
1278b5203cb1Syuzexi 		EMSG("Fail to transfer ecdsa verify s");
1279b5203cb1Syuzexi 		return ret;
1280b5203cb1Syuzexi 	}
1281b5203cb1Syuzexi 
1282b5203cb1Syuzexi 	ret = hpre_bin_from_crypto_bin(r, r, msg->key_bytes,
1283b5203cb1Syuzexi 				       ecc_verify->r_bytes);
1284b5203cb1Syuzexi 	if (ret)
1285b5203cb1Syuzexi 		EMSG("Fail to transfer ecdsa verify r");
1286b5203cb1Syuzexi 
1287b5203cb1Syuzexi 	return ret;
1288b5203cb1Syuzexi }
1289b5203cb1Syuzexi 
1290b5203cb1Syuzexi static TEE_Result
hpre_ecc_verify_params_fill(const struct hpre_ecc_curve * curve,struct hpre_ecc_msg * msg,struct drvcrypt_sign_data * sdata)1291b5203cb1Syuzexi hpre_ecc_verify_params_fill(const struct hpre_ecc_curve *curve,
1292b5203cb1Syuzexi 			    struct hpre_ecc_msg *msg,
1293b5203cb1Syuzexi 			    struct drvcrypt_sign_data *sdata)
1294b5203cb1Syuzexi {
1295b5203cb1Syuzexi 	struct ecc_public_key *ecc_key = sdata->key;
1296b5203cb1Syuzexi 	struct hpre_ecc_verify *ecc_verify = &msg->param_size.ecc_verify;
1297b5203cb1Syuzexi 	uint8_t *p = msg->key;
1298b5203cb1Syuzexi 	uint8_t *a = p + msg->key_bytes;
1299b5203cb1Syuzexi 	uint8_t *b = a + msg->key_bytes;
1300b5203cb1Syuzexi 	uint8_t *n = b + msg->key_bytes;
1301b5203cb1Syuzexi 	uint8_t *gx = n + msg->key_bytes;
1302b5203cb1Syuzexi 	uint8_t *gy = gx + msg->key_bytes;
1303b5203cb1Syuzexi 	uint8_t *pubx = gy + msg->key_bytes;
1304b5203cb1Syuzexi 	uint8_t *puby = pubx + msg->key_bytes;
1305b5203cb1Syuzexi 	uint8_t *e = msg->in;
1306b5203cb1Syuzexi 	uint8_t *s = e + msg->key_bytes;
1307b5203cb1Syuzexi 	uint8_t *r = s + msg->key_bytes;
1308b5203cb1Syuzexi 	enum hisi_drv_status ret = HISI_QM_DRVCRYPT_NO_ERR;
1309b5203cb1Syuzexi 
1310b5203cb1Syuzexi 	memcpy(p, curve->p, msg->curve_bytes);
1311b5203cb1Syuzexi 	memcpy(a, curve->a, msg->curve_bytes);
1312b5203cb1Syuzexi 	memcpy(b, curve->b, msg->curve_bytes);
1313b5203cb1Syuzexi 	memcpy(n, curve->n, msg->curve_bytes);
1314b5203cb1Syuzexi 	memcpy(gx, curve->x, msg->curve_bytes);
1315b5203cb1Syuzexi 	memcpy(gy, curve->y, msg->curve_bytes);
1316b5203cb1Syuzexi 	crypto_bignum_bn2bin(ecc_key->x, pubx);
1317b5203cb1Syuzexi 	ecc_verify->pubx_bytes = crypto_bignum_num_bytes(ecc_key->x);
1318b5203cb1Syuzexi 	crypto_bignum_bn2bin(ecc_key->y, puby);
1319b5203cb1Syuzexi 	ecc_verify->puby_bytes = crypto_bignum_num_bytes(ecc_key->y);
1320b5203cb1Syuzexi 
1321b5203cb1Syuzexi 	ecc_verify->e_bytes = MIN(sdata->message.length, msg->curve_bytes);
1322b5203cb1Syuzexi 	memcpy(e, sdata->message.data, ecc_verify->e_bytes);
1323b5203cb1Syuzexi 	if (is_all_zero(e, ecc_verify->e_bytes, "ecc verify msg_e"))
1324b5203cb1Syuzexi 		return TEE_ERROR_BAD_PARAMETERS;
1325b5203cb1Syuzexi 
1326b5203cb1Syuzexi 	/* user should make param r and s be full width */
1327b5203cb1Syuzexi 	ecc_verify->r_bytes = sdata->signature.length >> 1;
1328b5203cb1Syuzexi 	memcpy(r, sdata->signature.data, ecc_verify->r_bytes);
1329b5203cb1Syuzexi 	ecc_verify->s_bytes = ecc_verify->r_bytes;
1330b5203cb1Syuzexi 	memcpy(s, sdata->signature.data + ecc_verify->r_bytes,
1331b5203cb1Syuzexi 	       ecc_verify->s_bytes);
1332b5203cb1Syuzexi 
1333b5203cb1Syuzexi 	ret = hpre_ecc_verify_transfer_key(msg);
1334b5203cb1Syuzexi 	if (ret)
1335b5203cb1Syuzexi 		return TEE_ERROR_BAD_STATE;
1336b5203cb1Syuzexi 
1337b5203cb1Syuzexi 	ret = hpre_ecc_verify_transfer_in(msg);
1338b5203cb1Syuzexi 	if (ret)
1339b5203cb1Syuzexi 		return TEE_ERROR_BAD_STATE;
1340b5203cb1Syuzexi 
1341b5203cb1Syuzexi 	return TEE_SUCCESS;
1342b5203cb1Syuzexi }
1343b5203cb1Syuzexi 
1344b5203cb1Syuzexi static enum hisi_drv_status
hpre_ecc_verify_params_alloc(struct hpre_ecc_msg * msg)1345b5203cb1Syuzexi hpre_ecc_verify_params_alloc(struct hpre_ecc_msg *msg)
1346b5203cb1Syuzexi {
1347b5203cb1Syuzexi 	uint32_t size = HPRE_ECC_VERIFY_TOTAL_BUF_SIZE(msg->key_bytes);
1348b5203cb1Syuzexi 	uint8_t *data = NULL;
1349b5203cb1Syuzexi 
1350b5203cb1Syuzexi 	data = calloc(1, size);
1351b5203cb1Syuzexi 	if (!data) {
1352b5203cb1Syuzexi 		EMSG("Fail to alloc ecc verify total buf");
1353b5203cb1Syuzexi 		return HISI_QM_DRVCRYPT_ENOMEM;
1354b5203cb1Syuzexi 	}
1355b5203cb1Syuzexi 
1356b5203cb1Syuzexi 	msg->key = data;
1357b5203cb1Syuzexi 	msg->key_dma = virt_to_phys(msg->key);
1358b5203cb1Syuzexi 	if (!msg->key_dma) {
1359b5203cb1Syuzexi 		EMSG("Fail to get key dma addr");
1360b5203cb1Syuzexi 		free(data);
1361b5203cb1Syuzexi 		return HISI_QM_DRVCRYPT_EFAULT;
1362b5203cb1Syuzexi 	}
1363b5203cb1Syuzexi 
1364b5203cb1Syuzexi 	msg->in = msg->key + ECC_VERIF_KEY_SIZE(msg->key_bytes);
1365b5203cb1Syuzexi 	msg->in_dma = msg->key_dma + ECC_VERIF_KEY_SIZE(msg->key_bytes);
1366b5203cb1Syuzexi 	msg->out = msg->in + ECC_VERIF_IN_SIZE(msg->key_bytes);
1367b5203cb1Syuzexi 	msg->out_dma = msg->in_dma + ECC_VERIF_IN_SIZE(msg->key_bytes);
1368b5203cb1Syuzexi 
1369b5203cb1Syuzexi 	return HISI_QM_DRVCRYPT_NO_ERR;
1370b5203cb1Syuzexi }
1371b5203cb1Syuzexi 
hpre_ecc_verify_request_deinit(struct hpre_ecc_msg * msg)1372b5203cb1Syuzexi static void hpre_ecc_verify_request_deinit(struct hpre_ecc_msg *msg)
1373b5203cb1Syuzexi {
1374b5203cb1Syuzexi 	if (msg->key) {
1375b5203cb1Syuzexi 		free_wipe(msg->key);
1376b5203cb1Syuzexi 		msg->key = NULL;
1377b5203cb1Syuzexi 	}
1378b5203cb1Syuzexi }
1379b5203cb1Syuzexi 
1380b5203cb1Syuzexi static TEE_Result
hpre_ecc_verify_request_init(const struct hpre_ecc_curve * curve,struct hpre_ecc_msg * msg,struct drvcrypt_sign_data * sdata)1381b5203cb1Syuzexi hpre_ecc_verify_request_init(const struct hpre_ecc_curve *curve,
1382b5203cb1Syuzexi 			     struct hpre_ecc_msg *msg,
1383b5203cb1Syuzexi 			     struct drvcrypt_sign_data *sdata)
1384b5203cb1Syuzexi {
1385b5203cb1Syuzexi 	int32_t ret = 0;
1386b5203cb1Syuzexi 
1387b5203cb1Syuzexi 	if (curve->id == TEE_ECC_CURVE_SM2)
1388b5203cb1Syuzexi 		msg->alg_type = HPRE_ALG_SM2_VERF;
1389b5203cb1Syuzexi 	else
1390b5203cb1Syuzexi 		msg->alg_type = HPRE_ALG_ECDSA_VERF;
1391b5203cb1Syuzexi 	msg->curve_bytes = BITS_TO_BYTES(curve->key_bits);
1392b5203cb1Syuzexi 	msg->key_bytes = hpre_ecc_get_hw_kbytes(curve->key_bits);
1393b5203cb1Syuzexi 	if (!msg->key_bytes)
1394b5203cb1Syuzexi 		return TEE_ERROR_BAD_PARAMETERS;
1395b5203cb1Syuzexi 
1396b5203cb1Syuzexi 	ret = hpre_ecc_verify_params_alloc(msg);
1397b5203cb1Syuzexi 	if (ret)
1398b5203cb1Syuzexi 		return TEE_ERROR_OUT_OF_MEMORY;
1399b5203cb1Syuzexi 
1400b5203cb1Syuzexi 	ret = hpre_ecc_verify_params_fill(curve, msg, sdata);
1401b5203cb1Syuzexi 	if (ret) {
1402b5203cb1Syuzexi 		hpre_ecc_verify_request_deinit(msg);
1403b5203cb1Syuzexi 		return TEE_ERROR_BAD_STATE;
1404b5203cb1Syuzexi 	}
1405b5203cb1Syuzexi 
1406b5203cb1Syuzexi 	return TEE_SUCCESS;
1407b5203cb1Syuzexi }
1408b5203cb1Syuzexi 
hpre_ecc_verify(struct drvcrypt_sign_data * sdata)1409b5203cb1Syuzexi static TEE_Result hpre_ecc_verify(struct drvcrypt_sign_data *sdata)
1410b5203cb1Syuzexi {
1411b5203cb1Syuzexi 	struct hpre_ecc_msg msg = { };
1412b5203cb1Syuzexi 	const struct hpre_ecc_curve *curve = NULL;
1413b5203cb1Syuzexi 	struct ecc_public_key *pub_key = NULL;
1414b5203cb1Syuzexi 	TEE_Result ret = TEE_SUCCESS;
1415b5203cb1Syuzexi 
1416b5203cb1Syuzexi 	if (!sdata || !sdata->key) {
1417b5203cb1Syuzexi 		EMSG("Invalid ecc_verify input parameters");
1418b5203cb1Syuzexi 		return TEE_ERROR_BAD_PARAMETERS;
1419b5203cb1Syuzexi 	}
1420b5203cb1Syuzexi 
1421b5203cb1Syuzexi 	pub_key = sdata->key;
1422b5203cb1Syuzexi 
1423b5203cb1Syuzexi 	curve = get_curve_from_list(pub_key->curve);
1424b5203cb1Syuzexi 	if (!curve) {
1425b5203cb1Syuzexi 		EMSG("Fail to get valid curve, id %"PRIu32, pub_key->curve);
1426b5203cb1Syuzexi 		return TEE_ERROR_NOT_SUPPORTED;
1427b5203cb1Syuzexi 	}
1428b5203cb1Syuzexi 
1429b5203cb1Syuzexi 	ret = hpre_ecdsa_param_check(sdata, curve);
1430b5203cb1Syuzexi 	if (ret)
1431b5203cb1Syuzexi 		return ret;
1432b5203cb1Syuzexi 
1433b5203cb1Syuzexi 	ret = hpre_ecc_verify_request_init(curve, &msg, sdata);
1434b5203cb1Syuzexi 	if (ret) {
1435b5203cb1Syuzexi 		EMSG("Ecc verify request init fail");
1436b5203cb1Syuzexi 		return ret;
1437b5203cb1Syuzexi 	}
1438b5203cb1Syuzexi 
1439b5203cb1Syuzexi 	ret = hpre_do_ecc_task(&msg);
1440b5203cb1Syuzexi 	if (ret) {
1441b5203cb1Syuzexi 		EMSG("Fail to do ecc verify task! ret = 0x%"PRIX16, ret);
1442b5203cb1Syuzexi 		goto done;
1443b5203cb1Syuzexi 	}
1444b5203cb1Syuzexi 
1445b5203cb1Syuzexi 	if (msg.result == ECC_VERIFY_ERR) {
1446b5203cb1Syuzexi 		EMSG("Hpre ecc verify fail");
1447b5203cb1Syuzexi 		ret = TEE_ERROR_SIGNATURE_INVALID;
1448b5203cb1Syuzexi 	}
1449b5203cb1Syuzexi 
1450b5203cb1Syuzexi done:
1451b5203cb1Syuzexi 	hpre_ecc_verify_request_deinit(&msg);
1452b5203cb1Syuzexi 	return ret;
1453b5203cb1Syuzexi }
1454b5203cb1Syuzexi 
1455b32598bfSZexi Yu static struct drvcrypt_ecc driver_ecc = {
1456b32598bfSZexi Yu 	.alloc_keypair = hpre_ecc_alloc_keypair,
1457b32598bfSZexi Yu 	.alloc_publickey = hpre_ecc_alloc_publickey,
1458b32598bfSZexi Yu 	.free_publickey = hpre_ecc_free_publickey,
1459b32598bfSZexi Yu 	.gen_keypair = hpre_ecc_gen_keypair,
1460b32598bfSZexi Yu 	.shared_secret = hpre_ecc_do_shared_secret,
1461b5203cb1Syuzexi 	.sign = hpre_ecc_sign,
1462b5203cb1Syuzexi 	.verify = hpre_ecc_verify,
1463b32598bfSZexi Yu };
1464b32598bfSZexi Yu 
hpre_ecc_init(void)1465b32598bfSZexi Yu static TEE_Result hpre_ecc_init(void)
1466b32598bfSZexi Yu {
1467b32598bfSZexi Yu 	TEE_Result ret = drvcrypt_register_ecc(&driver_ecc);
1468b32598bfSZexi Yu 
1469b32598bfSZexi Yu 	if (ret != TEE_SUCCESS)
1470b32598bfSZexi Yu 		EMSG("Hpre ecc register to crypto fail");
1471b32598bfSZexi Yu 
1472b32598bfSZexi Yu 	return ret;
1473b32598bfSZexi Yu }
1474b32598bfSZexi Yu 
1475b32598bfSZexi Yu driver_init(hpre_ecc_init);
1476