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