1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2019 Huawei Technologies Co., Ltd
4  */
5 
6 #include <crypto/crypto.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <tee_api_types.h>
10 #include <util.h>
11 #include <utee_defines.h>
12 
13 #include "acipher_helpers.h"
14 
15 /* SM2 uses 256 bit unsigned integers in big endian format */
16 #define SM2_INT_SIZE_BYTES 32
17 
18 /*
19  * GM/T 0003.1‒2012 Part1 2 Section 6.1
20  */
sm2_ltc_dsa_sign(uint32_t algo,struct ecc_keypair * key,const uint8_t * msg,size_t msg_len,uint8_t * sig,size_t * sig_len)21 TEE_Result sm2_ltc_dsa_sign(uint32_t algo, struct ecc_keypair *key,
22 			    const uint8_t *msg, size_t msg_len, uint8_t *sig,
23 			    size_t *sig_len)
24 {
25 	TEE_Result res = TEE_SUCCESS;
26 	ecc_point *x1y1p = NULL;
27 	ecc_key ltc_key = { };
28 	int ltc_res = 0;
29 	void *k = NULL;
30 	void *e = NULL;
31 	void *r = NULL;
32 	void *s = NULL;
33 	void *tmp = NULL;
34 
35 	if (*sig_len < 2 * SM2_INT_SIZE_BYTES) {
36 		*sig_len = 64;
37 		return TEE_ERROR_SHORT_BUFFER;
38 	}
39 
40 	ltc_res = mp_init_multi(&k, &e, &r, &s, &tmp, NULL);
41 	if (ltc_res != CRYPT_OK)
42 		return TEE_ERROR_OUT_OF_MEMORY;
43 
44 	x1y1p = ltc_ecc_new_point();
45 	if (!x1y1p) {
46 		res = TEE_ERROR_OUT_OF_MEMORY;
47 		goto out;
48 	}
49 
50 	res = ecc_populate_ltc_private_key(&ltc_key, key, algo, NULL);
51 	if (res)
52 		goto out;
53 
54 	/*
55 	 * Steps A1 and A2 are the generation of the hash value e from user
56 	 * information (ZA) and the message to be signed (M). There are not done
57 	 * here since @msg is expected to be the hash value e already.
58 	 */
59 
60 	/* Step A3: generate random number 1 <= k < n */
61 A3:
62 	ltc_res = rand_bn_upto(k, ltc_key.dp.order, NULL,
63 			       find_prng("prng_crypto"));
64 	if (ltc_res != CRYPT_OK) {
65 		res = TEE_ERROR_BAD_STATE;
66 		goto out;
67 	}
68 
69 	/* Step A4: compute (x1, y1) = [k]G */
70 
71 	ltc_res = ltc_ecc_mulmod(k, &ltc_key.dp.base, x1y1p, ltc_key.dp.A,
72 				 ltc_key.dp.prime, 1);
73 	if (ltc_res != CRYPT_OK) {
74 		res = TEE_ERROR_BAD_STATE;
75 		goto out;
76 	}
77 
78 	/* Step A5: compute r = (e + x1) mod n */
79 
80 	mp_read_unsigned_bin(e, (unsigned char *)msg, msg_len);
81 	ltc_res = mp_addmod(e, x1y1p->x, ltc_key.dp.order, r);
82 	if (ltc_res != CRYPT_OK) {
83 		res = TEE_ERROR_BAD_STATE;
84 		goto out;
85 	}
86 	ltc_res = mp_add(r, k, tmp);
87 	if (ltc_res != CRYPT_OK) {
88 		res = TEE_ERROR_BAD_STATE;
89 		goto out;
90 	}
91 	if (mp_cmp_d(r, 0) == LTC_MP_EQ ||
92 	    mp_cmp(tmp, ltc_key.dp.order) == LTC_MP_EQ)
93 		goto A3;
94 
95 	/* Step A6: compute s = ((1 + dA)^-1 * (k - r*dA)) mod n */
96 
97 	ltc_res = mp_add_d(ltc_key.k, 1, s);
98 	if (ltc_res != CRYPT_OK) {
99 		res = TEE_ERROR_BAD_STATE;
100 		goto out;
101 	}
102 	ltc_res = mp_invmod(s, ltc_key.dp.order, s);
103 	if (ltc_res != CRYPT_OK) {
104 		res = TEE_ERROR_BAD_STATE;
105 		goto out;
106 	}
107 	ltc_res = mp_mul(r, ltc_key.k, tmp);
108 	if (ltc_res != CRYPT_OK) {
109 		res = TEE_ERROR_BAD_STATE;
110 		goto out;
111 	}
112 	ltc_res = mp_sub(k, tmp, tmp);
113 	if (ltc_res != CRYPT_OK) {
114 		res = TEE_ERROR_BAD_STATE;
115 		goto out;
116 	}
117 	ltc_res = mp_mulmod(s, tmp, ltc_key.dp.order, s);
118 	if (ltc_res != CRYPT_OK) {
119 		res = TEE_ERROR_BAD_STATE;
120 		goto out;
121 	}
122 
123 	/* Step A7: convert (r, s) to binary for output */
124 
125 	*sig_len = 2 * SM2_INT_SIZE_BYTES;
126 	memset(sig, 0, *sig_len);
127 	mp_to_unsigned_bin2(r, sig, SM2_INT_SIZE_BYTES);
128 	mp_to_unsigned_bin2(s, sig + SM2_INT_SIZE_BYTES, SM2_INT_SIZE_BYTES);
129 out:
130 	ecc_free(&ltc_key);
131 	ltc_ecc_del_point(x1y1p);
132 	mp_clear_multi(k, e, r, s, tmp, NULL);
133 	return res;
134 }
135 
136 /*
137  * GM/T 0003.1‒2012 Part1 2 Section 7.1
138  */
sm2_ltc_dsa_verify(uint32_t algo,struct ecc_public_key * key,const uint8_t * msg,size_t msg_len,const uint8_t * sig,size_t sig_len)139 TEE_Result sm2_ltc_dsa_verify(uint32_t algo, struct ecc_public_key *key,
140 			      const uint8_t *msg, size_t msg_len,
141 			      const uint8_t *sig, size_t sig_len)
142 {
143 	TEE_Result res = TEE_SUCCESS;
144 	ecc_key ltc_key = { };
145 	int ltc_res = 0;
146 	void *rprime = NULL;
147 	void *sprime = NULL;
148 	void *t = NULL;
149 	void *mp = NULL;
150 	void *mu = NULL;
151 	void *ma = NULL;
152 	void *eprime = NULL;
153 	void *R = NULL;
154 	ecc_point *x1y1p = NULL;
155 
156 	if (sig_len != 64)
157 		return TEE_ERROR_BAD_PARAMETERS;
158 
159 	ltc_res = mp_init_multi(&rprime, &sprime, &t, &mu, &ma, &eprime, &R,
160 				NULL);
161 	if (ltc_res != CRYPT_OK)
162 		return TEE_ERROR_OUT_OF_MEMORY;
163 
164 	mp_read_unsigned_bin(rprime, (unsigned char *)sig, 32);
165 	mp_read_unsigned_bin(sprime, (unsigned char *)sig + 32, 32);
166 
167 	res = ecc_populate_ltc_public_key(&ltc_key, key, algo, NULL);
168 	if (res)
169 		goto out;
170 
171 	/* Step B1: verify r' in [1, n - 1] */
172 
173 	if (mp_cmp_d(rprime, 1) == LTC_MP_LT ||
174 	    mp_cmp(rprime, ltc_key.dp.order) != LTC_MP_LT) {
175 		res = TEE_ERROR_SIGNATURE_INVALID;
176 		goto out;
177 	}
178 
179 	/* Step B2: verify s' in [1, n - 1] */
180 
181 	if (mp_cmp_d(sprime, 1) == LTC_MP_LT ||
182 	    mp_cmp(sprime, ltc_key.dp.order) != LTC_MP_LT) {
183 		res = TEE_ERROR_SIGNATURE_INVALID;
184 		goto out;
185 	}
186 
187 	/*
188 	 * Steps B3: M'bar = (ZA || M') and B4: e' = Hv(M'bar) are not done here
189 	 * because @msg is supposed to contain the hash value e' already.
190 	 */
191 
192 	/* Step B5: t = (r' + s') mod n and check t != 0 */
193 
194 	ltc_res = mp_addmod(rprime, sprime, ltc_key.dp.order, t);
195 	if (ltc_res != CRYPT_OK) {
196 		res = TEE_ERROR_BAD_STATE;
197 		goto out;
198 	}
199 	if (mp_cmp_d(t, 0) == LTC_MP_EQ) {
200 		res = TEE_ERROR_SIGNATURE_INVALID;
201 		goto out;
202 	}
203 
204 	/* Step B6: (x1', y1') = [s']G + [t]PA */
205 
206 	x1y1p = ltc_ecc_new_point();
207 	if (!x1y1p) {
208 		res = TEE_ERROR_OUT_OF_MEMORY;
209 		goto out;
210 	}
211 	ltc_res = mp_montgomery_setup(ltc_key.dp.prime, &mp);
212 	if (ltc_res != CRYPT_OK) {
213 		res = TEE_ERROR_BAD_STATE;
214 		goto out;
215 	}
216 	ltc_res = mp_montgomery_normalization(mu, ltc_key.dp.prime);
217 	if (ltc_res != CRYPT_OK) {
218 		res = TEE_ERROR_BAD_STATE;
219 		goto out;
220 	}
221 	ltc_res = mp_mulmod(ltc_key.dp.A, mu, ltc_key.dp.prime, ma);
222 	if (ltc_res != CRYPT_OK) {
223 		res = TEE_ERROR_BAD_STATE;
224 		goto out;
225 	}
226 	ltc_res = ltc_ecc_mul2add(&ltc_key.dp.base, sprime, &ltc_key.pubkey, t,
227 				  x1y1p, ma, ltc_key.dp.prime);
228 	if (ltc_res != CRYPT_OK) {
229 		res = TEE_ERROR_BAD_STATE;
230 		goto out;
231 	}
232 
233 	/* Step B7: compute R = (e' + x1') mod n and verify R == r' */
234 
235 	mp_read_unsigned_bin(eprime, (unsigned char *)msg, msg_len);
236 	ltc_res = mp_addmod(eprime, x1y1p->x, ltc_key.dp.order, R);
237 	if (ltc_res != CRYPT_OK) {
238 		res = TEE_ERROR_BAD_STATE;
239 		goto out;
240 	}
241 	if (mp_cmp(R, rprime) != LTC_MP_EQ)
242 		res = TEE_ERROR_SIGNATURE_INVALID;
243 out:
244 	mp_montgomery_free(mp);
245 	ltc_ecc_del_point(x1y1p);
246 	ecc_free(&ltc_key);
247 	mp_clear_multi(rprime, sprime, t, mu, ma, eprime, R, NULL);
248 	return res;
249 }
250