1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright (c) 2019-2021 Huawei Technologies Co., Ltd
4 */
5
6 #include <compiler.h>
7 #include <crypto/crypto.h>
8 #include <mbedtls/bignum.h>
9 #include <mbedtls/ecp.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <tee_api_types.h>
13 #include <util.h>
14 #include <utee_defines.h>
15
16 #include "mbed_helpers.h"
17 #include "sm2-dsa.h"
18
19 /* SM2 uses 256 bit unsigned integers in big endian format */
20 #define SM2_INT_SIZE_BYTES 32
21
22 /*
23 * GM/T 0003.1‒2012 Part1 2 Section 6.1
24 */
sm2_mbedtls_dsa_sign(uint32_t algo __unused,struct ecc_keypair * key,const uint8_t * msg,size_t msg_len,uint8_t * sig,size_t * sig_len)25 TEE_Result sm2_mbedtls_dsa_sign(uint32_t algo __unused, struct ecc_keypair *key,
26 const uint8_t *msg, size_t msg_len,
27 uint8_t *sig, size_t *sig_len)
28 {
29 TEE_Result res = TEE_SUCCESS;
30 mbedtls_ecp_group grp = { };
31 mbedtls_ecp_point x1y1p = { };
32 int mres = 0;
33 mbedtls_mpi k = { };
34 mbedtls_mpi e = { };
35 mbedtls_mpi r = { };
36 mbedtls_mpi s = { };
37 mbedtls_mpi tmp = { };
38
39 if (*sig_len < 2 * SM2_INT_SIZE_BYTES) {
40 *sig_len = 64;
41 return TEE_ERROR_SHORT_BUFFER;
42 }
43
44 mbedtls_mpi_init(&k);
45 mbedtls_mpi_init(&e);
46 mbedtls_mpi_init(&r);
47 mbedtls_mpi_init(&s);
48 mbedtls_mpi_init(&tmp);
49
50 mbedtls_ecp_point_init(&x1y1p);
51
52 mbedtls_ecp_group_init(&grp);
53 mres = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SM2);
54 if (mres) {
55 res = TEE_ERROR_GENERIC;
56 goto out;
57 }
58
59 /*
60 * Steps A1 and A2 are the generation of the hash value e from user
61 * information (ZA) and the message to be signed (M). There are not done
62 * here since @msg is expected to be the hash value e already.
63 */
64
65 /* Step A3: generate random number 1 <= k < n */
66 do {
67 res = mbed_gen_random_upto(&k, &grp.N);
68 if (res)
69 goto out;
70
71 res = TEE_ERROR_BAD_STATE;
72
73 /* Step A4: compute (x1, y1) = [k]G */
74
75 mres = mbedtls_ecp_mul(&grp, &x1y1p, &k, &grp.G, mbd_rand,
76 NULL);
77 if (mres)
78 goto out;
79
80 /* Step A5: compute r = (e + x1) mod n */
81
82 mbedtls_mpi_read_binary(&e, (unsigned char *)msg, msg_len);
83 mres = mbedtls_mpi_add_mpi(&r, &e, &x1y1p.X);
84 if (mres)
85 goto out;
86 mres = mbedtls_mpi_mod_mpi(&r, &r, &grp.N);
87 if (mres)
88 goto out;
89
90 /* Step A5 (continued): return to A3 if r = 0 or r + k = n */
91
92 mres = mbedtls_mpi_add_mpi(&tmp, &r, &k);
93 if (mres)
94 goto out;
95 } while (!mbedtls_mpi_cmp_int(&r, 0) ||
96 !mbedtls_mpi_cmp_mpi(&tmp, &grp.N));
97
98 /* Step A6: compute s = ((1 + dA)^-1 * (k - r*dA)) mod n */
99
100 mres = mbedtls_mpi_add_int(&s, (mbedtls_mpi *)key->d, 1);
101 if (mres)
102 goto out;
103 mres = mbedtls_mpi_inv_mod(&s, &s, &grp.N);
104 if (mres)
105 goto out;
106 mres = mbedtls_mpi_mul_mpi(&tmp, &r, (mbedtls_mpi *)key->d);
107 if (mres)
108 goto out;
109 mres = mbedtls_mpi_mod_mpi(&tmp, &tmp, &grp.N);
110 if (mres)
111 goto out;
112 mres = mbedtls_mpi_sub_mpi(&tmp, &k, &tmp);
113 if (mres)
114 goto out;
115 mres = mbedtls_mpi_mul_mpi(&s, &s, &tmp);
116 if (mres)
117 goto out;
118 mres = mbedtls_mpi_mod_mpi(&s, &s, &grp.N);
119 if (mres)
120 goto out;
121
122 /* Step A7: convert (r, s) to binary for output */
123
124 *sig_len = 2 * SM2_INT_SIZE_BYTES;
125 memset(sig, 0, *sig_len);
126 mres = mbedtls_mpi_write_binary(&r, sig, SM2_INT_SIZE_BYTES);
127 if (mres)
128 goto out;
129 mres = mbedtls_mpi_write_binary(&s, sig + SM2_INT_SIZE_BYTES,
130 SM2_INT_SIZE_BYTES);
131 if (mres)
132 goto out;
133
134 res = TEE_SUCCESS;
135 out:
136 mbedtls_ecp_point_free(&x1y1p);
137 mbedtls_mpi_free(&k);
138 mbedtls_mpi_free(&e);
139 mbedtls_mpi_free(&r);
140 mbedtls_mpi_free(&s);
141 mbedtls_mpi_free(&tmp);
142 mbedtls_ecp_group_free(&grp);
143 return res;
144 }
145
146 /*
147 * GM/T 0003.1‒2012 Part1 2 Section 7.1
148 */
sm2_mbedtls_dsa_verify(uint32_t algo __unused,struct ecc_public_key * key,const uint8_t * msg,size_t msg_len,const uint8_t * sig,size_t sig_len)149 TEE_Result sm2_mbedtls_dsa_verify(uint32_t algo __unused,
150 struct ecc_public_key *key,
151 const uint8_t *msg, size_t msg_len,
152 const uint8_t *sig, size_t sig_len)
153 {
154 TEE_Result res = TEE_ERROR_BAD_STATE;
155 mbedtls_ecp_group grp = { };
156 mbedtls_mpi rprime = { };
157 mbedtls_mpi sprime = { };
158 mbedtls_mpi t = { };
159 mbedtls_mpi eprime = { };
160 mbedtls_mpi R = { };
161 mbedtls_ecp_point x1y1p = { };
162 mbedtls_ecp_point PA = { };
163 int mres = 0;
164
165 if (sig_len != 64)
166 return TEE_ERROR_BAD_PARAMETERS;
167
168 mbedtls_mpi_init(&rprime);
169 mbedtls_mpi_init(&sprime);
170 mbedtls_mpi_init(&t);
171 mbedtls_mpi_init(&eprime);
172 mbedtls_mpi_init(&R);
173
174 mbedtls_ecp_point_init(&x1y1p);
175 mbedtls_ecp_point_init(&PA);
176
177 mbedtls_ecp_group_init(&grp);
178 mres = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SM2);
179 if (mres) {
180 res = TEE_ERROR_GENERIC;
181 goto out;
182 }
183
184 mres = mbedtls_mpi_read_binary(&rprime, sig, 32);
185 if (mres)
186 goto out;
187 mres = mbedtls_mpi_read_binary(&sprime, sig + 32, 32);
188 if (mres)
189 goto out;
190
191 /* Step B1: verify r' in [1, n - 1] */
192
193 if (mbedtls_mpi_cmp_int(&rprime, 1) < 0 ||
194 mbedtls_mpi_cmp_mpi(&rprime, &grp.N) >= 0) {
195 res = TEE_ERROR_SIGNATURE_INVALID;
196 goto out;
197 }
198
199 /* Step B2: verify s' in [1, n - 1] */
200
201 if (mbedtls_mpi_cmp_int(&sprime, 1) < 0 ||
202 mbedtls_mpi_cmp_mpi(&sprime, &grp.N) >= 0) {
203 res = TEE_ERROR_SIGNATURE_INVALID;
204 goto out;
205 }
206
207 /*
208 * Steps B3: M'bar = (ZA || M') and B4: e' = Hv(M'bar) are not done here
209 * because @msg is supposed to contain the hash value e' already.
210 */
211
212 /* Step B5: t = (r' + s') mod n and check t != 0 */
213
214 mres = mbedtls_mpi_add_mpi(&t, &rprime, &sprime);
215 if (mres)
216 goto out;
217 mres = mbedtls_mpi_mod_mpi(&t, &t, &grp.N);
218 if (mres)
219 goto out;
220 if (!mbedtls_mpi_cmp_int(&t, 0)) {
221 res = TEE_ERROR_SIGNATURE_INVALID;
222 goto out;
223 }
224
225 /* Step B6: (x1', y1') = [s']G + [t]PA */
226
227 mres = mbedtls_mpi_copy(&PA.X, (mbedtls_mpi *)key->x);
228 if (mres)
229 goto out;
230 mres = mbedtls_mpi_copy(&PA.Y, (mbedtls_mpi *)key->y);
231 if (mres)
232 goto out;
233 mres = mbedtls_mpi_lset(&PA.Z, 1);
234 if (mres)
235 goto out;
236
237 mres = mbedtls_ecp_muladd(&grp, &x1y1p, &sprime, &grp.G, &t, &PA);
238 if (mres)
239 goto out;
240
241 /* Step B7: compute R = (e' + x1') mod n and verify R == r' */
242
243 mres = mbedtls_mpi_read_binary(&eprime, msg, msg_len);
244 if (mres)
245 goto out;
246 mres = mbedtls_mpi_add_mpi(&R, &eprime, &x1y1p.X);
247 if (mres)
248 goto out;
249 mres = mbedtls_mpi_mod_mpi(&R, &R, &grp.N);
250 if (mres)
251 goto out;
252 if (mbedtls_mpi_cmp_mpi(&R, &rprime)) {
253 res = TEE_ERROR_SIGNATURE_INVALID;
254 goto out;
255 }
256
257 res = TEE_SUCCESS;
258 out:
259 mbedtls_ecp_point_free(&x1y1p);
260 mbedtls_ecp_point_free(&PA);
261 mbedtls_mpi_free(&rprime);
262 mbedtls_mpi_free(&sprime);
263 mbedtls_mpi_free(&t);
264 mbedtls_mpi_free(&eprime);
265 mbedtls_mpi_free(&R);
266 mbedtls_ecp_group_free(&grp);
267 return res;
268 }
269