1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2020 Huawei Technologies Co., Ltd
4  */
5 
6 #include <crypto/crypto.h>
7 #include <crypto/sm2-kdf.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <string_ext.h>
11 #include <tee_api_types.h>
12 #include <tee/tee_cryp_utl.h>
13 #include <util.h>
14 #include <utee_defines.h>
15 
16 #include "acipher_helpers.h"
17 
18 /* SM2 uses 256 bit unsigned integers in big endian format */
19 #define SM2_INT_SIZE_BYTES 32
20 
21 /*
22  * Compute a hash of a user's identity and public key
23  * For user A: ZA = SM3(ENTLA || IDA || a || b || xG || yG || xA || yA)
24  */
sm2_kep_compute_Z(uint8_t * Z,size_t Zlen,const uint8_t * id,size_t idlen,const ecc_key * key)25 static TEE_Result sm2_kep_compute_Z(uint8_t *Z, size_t Zlen, const uint8_t *id,
26 				    size_t idlen, const ecc_key *key)
27 {
28 	TEE_Result res = TEE_ERROR_GENERIC;
29 	uint8_t ENTLEN[2] = { };
30 	uint8_t buf[SM2_INT_SIZE_BYTES];
31 	void *ctx = NULL;
32 
33 	if (Zlen < TEE_SM3_HASH_SIZE)
34 		return TEE_ERROR_SHORT_BUFFER;
35 
36 	/*
37 	 * ENTLEN is the length in bits if the user's distinguished identifier
38 	 * encoded over 16 bits in big endian format.
39 	 */
40 	ENTLEN[0] = (idlen * 8) >> 8;
41 	ENTLEN[1] = idlen * 8;
42 
43 	res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SM3);
44 	if (res)
45 		goto out;
46 
47 	res = crypto_hash_init(ctx);
48 	if (res)
49 		goto out;
50 
51 	res = crypto_hash_update(ctx, ENTLEN, sizeof(ENTLEN));
52 	if (res)
53 		goto out;
54 
55 	res = crypto_hash_update(ctx, id, idlen);
56 	if (res)
57 		goto out;
58 
59 	mp_to_unsigned_bin2(key->dp.A, buf, SM2_INT_SIZE_BYTES);
60 	res = crypto_hash_update(ctx, buf, sizeof(buf));
61 	if (res)
62 		goto out;
63 
64 	mp_to_unsigned_bin2(key->dp.B, buf, SM2_INT_SIZE_BYTES);
65 	res = crypto_hash_update(ctx, buf, sizeof(buf));
66 	if (res)
67 		goto out;
68 
69 	mp_to_unsigned_bin2(key->dp.base.x, buf, SM2_INT_SIZE_BYTES);
70 	res = crypto_hash_update(ctx, buf, sizeof(buf));
71 	if (res)
72 		goto out;
73 
74 	mp_to_unsigned_bin2(key->dp.base.y, buf, SM2_INT_SIZE_BYTES);
75 	res = crypto_hash_update(ctx, buf, sizeof(buf));
76 	if (res)
77 		goto out;
78 
79 	mp_to_unsigned_bin2(key->pubkey.x, buf, SM2_INT_SIZE_BYTES);
80 	res = crypto_hash_update(ctx, buf, sizeof(buf));
81 	if (res)
82 		goto out;
83 
84 	mp_to_unsigned_bin2(key->pubkey.y, buf, SM2_INT_SIZE_BYTES);
85 	res = crypto_hash_update(ctx, buf, sizeof(buf));
86 	if (res)
87 		goto out;
88 
89 	res = crypto_hash_final(ctx, Z, TEE_SM3_HASH_SIZE);
90 out:
91 	crypto_hash_free_ctx(ctx);
92 	return res;
93 }
94 
95 /*
96  * Compute a verification value, to be checked against the value sent by the
97  * peer.
98  * On the initiator's side:
99  *   S1 = SM3(0x02 || yU || SM3(xU || ZA || ZB || x1 || y1 || x2 || y2))
100  * On the responder's side:
101  *   S2 = SM3(0x03 || yV || SM3(xV || ZA || ZB || x1 || y1 || x2 || y2))
102  */
sm2_kep_compute_S(uint8_t * S,size_t S_len,uint8_t flag,ecc_point * UV,const uint8_t * ZAZB,size_t ZAZB_len,ecc_key * initiator_eph_key,ecc_key * responder_eph_key)103 static TEE_Result sm2_kep_compute_S(uint8_t *S, size_t S_len, uint8_t flag,
104 				    ecc_point *UV, const uint8_t *ZAZB,
105 				    size_t ZAZB_len, ecc_key *initiator_eph_key,
106 				    ecc_key *responder_eph_key)
107 {
108 	uint8_t hash[TEE_SM3_HASH_SIZE] = { };
109 	TEE_Result res = TEE_ERROR_GENERIC;
110 	uint8_t buf[SM2_INT_SIZE_BYTES];
111 	void *ctx = NULL;
112 
113 	if (S_len < TEE_SM3_HASH_SIZE)
114 		return TEE_ERROR_SHORT_BUFFER;
115 
116 	res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SM3);
117 	if (res)
118 		goto out;
119 
120 	/* Compute the inner hash */
121 
122 	res = crypto_hash_init(ctx);
123 	if (res)
124 		goto out;
125 
126 	/* xU or xV */
127 	mp_to_unsigned_bin2(UV->x, buf, SM2_INT_SIZE_BYTES);
128 	res = crypto_hash_update(ctx, buf, sizeof(buf));
129 	if (res)
130 		goto out;
131 
132 	/* ZA || ZB */
133 	res = crypto_hash_update(ctx, ZAZB, ZAZB_len);
134 	if (res)
135 		goto out;
136 
137 	/* x1 */
138 	mp_to_unsigned_bin2(initiator_eph_key->pubkey.x, buf,
139 			    SM2_INT_SIZE_BYTES);
140 	res = crypto_hash_update(ctx, buf, sizeof(buf));
141 	if (res)
142 		goto out;
143 
144 	/* y1 */
145 	mp_to_unsigned_bin2(initiator_eph_key->pubkey.y, buf,
146 			    SM2_INT_SIZE_BYTES);
147 	res = crypto_hash_update(ctx, buf, sizeof(buf));
148 	if (res)
149 		goto out;
150 
151 	/* x2 */
152 	mp_to_unsigned_bin2(responder_eph_key->pubkey.x, buf,
153 			    SM2_INT_SIZE_BYTES);
154 	res = crypto_hash_update(ctx, buf, sizeof(buf));
155 	if (res)
156 		goto out;
157 
158 	/* y2 */
159 	mp_to_unsigned_bin2(responder_eph_key->pubkey.y, buf,
160 			   SM2_INT_SIZE_BYTES);
161 	res = crypto_hash_update(ctx, buf, sizeof(buf));
162 	if (res)
163 		goto out;
164 
165 	res = crypto_hash_final(ctx, hash, sizeof(hash));
166 	if (res)
167 		goto out;
168 
169 	/* Now compute S */
170 
171 	res = crypto_hash_init(ctx);
172 	if (res)
173 		goto out;
174 
175 	/* 0x02 or 0x03  */
176 	res = crypto_hash_update(ctx, &flag, sizeof(flag));
177 	if (res)
178 		goto out;
179 
180 	/* yU or yV */
181 	mp_to_unsigned_bin2(UV->y, buf, SM2_INT_SIZE_BYTES);
182 	res = crypto_hash_update(ctx, buf, sizeof(buf));
183 	if (res)
184 		goto out;
185 
186 	/* Inner SM3(...) */
187 	res = crypto_hash_update(ctx, hash, sizeof(hash));
188 	if (res)
189 		goto out;
190 
191 	res = crypto_hash_final(ctx, S, TEE_SM3_HASH_SIZE);
192 
193 out:
194 	crypto_hash_free_ctx(ctx);
195 	return res;
196 
197 }
198 
199 /*
200  * GM/T 0003.1‒2012 Part 3 Section 6.1
201  * Key exchange protocol
202  */
sm2_kep_derive(ecc_key * my_key,ecc_key * my_eph_key,ecc_key * peer_key,ecc_key * peer_eph_key,struct sm2_kep_parms * p)203 static TEE_Result sm2_kep_derive(ecc_key *my_key, ecc_key *my_eph_key,
204 				 ecc_key *peer_key, ecc_key *peer_eph_key,
205 				 struct sm2_kep_parms *p)
206 {
207 	/*
208 	 * Variable names and documented steps reflect the initator side (user A
209 	 * in the spec), but the other side is quite similar hence only one
210 	 * function.
211 	 */
212 	uint8_t xUyUZAZB[2 * SM2_INT_SIZE_BYTES + 2 * TEE_SM3_HASH_SIZE] = { };
213 	ecc_key *initiator_eph_key = p->is_initiator ? my_eph_key :
214 						       peer_eph_key;
215 	ecc_key *responder_eph_key = p->is_initiator ? peer_eph_key :
216 						       my_eph_key;
217 	ecc_key *initiator_key = p->is_initiator ? my_key : peer_key;
218 	ecc_key *responder_key = p->is_initiator ? peer_key : my_key;
219 	TEE_Result res = TEE_ERROR_BAD_STATE;
220 	uint8_t tmp[SM2_INT_SIZE_BYTES];
221 	void *n = my_key->dp.order;
222 	ecc_point *U = NULL;
223 	void *x1bar = NULL;
224 	void *x2bar = NULL;
225 	void *tA = NULL;
226 	void *h = NULL;
227 	void *htA = NULL;
228 	void *mp = NULL;
229 	void *mu = NULL;
230 	void *ma = NULL;
231 	void *one = NULL;
232 	int ltc_res = 0;
233 	int inf = 0;
234 
235 	ltc_res = mp_init_multi(&x1bar, &x2bar, &tA, &h, &htA, &mu, &ma, &one,
236 				NULL);
237 	if (ltc_res != CRYPT_OK) {
238 		res = TEE_ERROR_OUT_OF_MEMORY;
239 		goto out;
240 	}
241 
242 	U = ltc_ecc_new_point();
243 	if (!U) {
244 		res = TEE_ERROR_OUT_OF_MEMORY;
245 		goto out;
246 	}
247 
248 	/*
249 	 * Steps A1-A3 are supposedly done already (generate ephemeral key, send
250 	 * it to peer).
251 	 * Step A4: (x1, y1) = RA; x1bar = 2^w + (x1 & (2^w - 1))
252 	 */
253 
254 	mp_to_unsigned_bin2(my_eph_key->pubkey.x, tmp, SM2_INT_SIZE_BYTES);
255 	tmp[SM2_INT_SIZE_BYTES / 2] |= 0x80;
256 	mp_read_unsigned_bin(x1bar, tmp + SM2_INT_SIZE_BYTES / 2,
257 			     SM2_INT_SIZE_BYTES / 2);
258 
259 	/* Step A5: tA = (dA + x1bar * rA) mod n */
260 
261 	ltc_res = mp_mulmod(x1bar, my_eph_key->k, n, tA);
262 	if (ltc_res != CRYPT_OK)
263 		goto out;
264 
265 	ltc_res = mp_addmod(tA, my_key->k, n, tA);
266 	if (ltc_res != CRYPT_OK)
267 		goto out;
268 
269 	/* Step A6: verify whether RB verifies the curve equation */
270 
271 	ltc_res = ltc_ecc_is_point(&peer_eph_key->dp, peer_eph_key->pubkey.x,
272 				   peer_eph_key->pubkey.y);
273 	if (ltc_res != CRYPT_OK)
274 		goto out;
275 
276 	/* Step A6 (continued): (x2, y2) = RB; x2bar = 2^w + (x2 & (2^w - 1)) */
277 
278 	mp_to_unsigned_bin2(peer_eph_key->pubkey.x, tmp, SM2_INT_SIZE_BYTES);
279 	tmp[SM2_INT_SIZE_BYTES / 2] |= 0x80;
280 	mp_read_unsigned_bin(x2bar, tmp + SM2_INT_SIZE_BYTES / 2,
281 			     SM2_INT_SIZE_BYTES / 2);
282 
283 
284 	/* Step A7: compute U = [h.tA](PB + [x2bar]RB) and check for infinity */
285 
286 	ltc_res = mp_montgomery_setup(peer_key->dp.prime, &mp);
287 	if (ltc_res != CRYPT_OK)
288 		goto out;
289 
290 	ltc_res = mp_montgomery_normalization(mu, peer_key->dp.prime);
291 	if (ltc_res != CRYPT_OK)
292 		goto out;
293 
294 	ltc_res = mp_mulmod(peer_key->dp.A, mu, peer_key->dp.prime, ma);
295 	if (ltc_res != CRYPT_OK)
296 		goto out;
297 
298 	ltc_res = mp_set_int(one, 1);
299 	if (ltc_res != CRYPT_OK)
300 		goto out;
301 
302 	ltc_res = ltc_ecc_mul2add(&peer_key->pubkey, one, &peer_eph_key->pubkey,
303 				  x2bar, U, ma, peer_key->dp.prime);
304 	if (ltc_res != CRYPT_OK)
305 		goto out;
306 
307 	ltc_res = mp_set_int(h, peer_key->dp.cofactor);
308 	if (ltc_res != CRYPT_OK)
309 		goto out;
310 
311 	ltc_res = mp_mul(h, tA, htA);
312 	if (ltc_res != CRYPT_OK)
313 		goto out;
314 
315 	ltc_res = ltc_ecc_mulmod(htA, U, U, peer_key->dp.A, peer_key->dp.prime,
316 				 1);
317 	if (ltc_res != CRYPT_OK)
318 		goto out;
319 
320 	ltc_res = ltc_ecc_is_point_at_infinity(U, peer_key->dp.prime, &inf);
321 	if (ltc_res != CRYPT_OK)
322 		goto out;
323 
324 	if (inf)
325 		goto out;
326 
327 	/* Step A8: compute KA = KDF(xU || yU || ZA || ZB, klen) */
328 
329 	/* xU */
330 	mp_to_unsigned_bin2(U->x, xUyUZAZB, SM2_INT_SIZE_BYTES);
331 
332 	/* yU */
333 	mp_to_unsigned_bin2(U->y, xUyUZAZB + SM2_INT_SIZE_BYTES,
334 			    SM2_INT_SIZE_BYTES);
335 
336 	/* ZA */
337 	res = sm2_kep_compute_Z(xUyUZAZB + 2 * SM2_INT_SIZE_BYTES,
338 				TEE_SM3_HASH_SIZE, p->initiator_id,
339 				p->initiator_id_len, initiator_key);
340 	if (res)
341 		goto out;
342 
343 	/* ZB */
344 	res = sm2_kep_compute_Z(xUyUZAZB + 2 * SM2_INT_SIZE_BYTES +
345 					TEE_SM3_HASH_SIZE,
346 				TEE_SM3_HASH_SIZE, p->responder_id,
347 				p->responder_id_len, responder_key);
348 	if (res)
349 		goto out;
350 
351 	res = sm2_kdf(xUyUZAZB, sizeof(xUyUZAZB), p->out, p->out_len);
352 	if (res)
353 		goto out;
354 
355 	/* Step A9: compute S1 and check S1 == SB */
356 
357 	if (p->conf_in) {
358 		uint8_t S1[TEE_SM3_HASH_SIZE];
359 		uint8_t flag = p->is_initiator ? 0x02 : 0x03;
360 
361 		if (p->conf_in_len < TEE_SM3_HASH_SIZE) {
362 			res = TEE_ERROR_BAD_PARAMETERS;
363 			goto out;
364 		}
365 		res = sm2_kep_compute_S(S1, sizeof(S1), flag, U,
366 					xUyUZAZB + 2 * SM2_INT_SIZE_BYTES,
367 					2 * SM2_INT_SIZE_BYTES,
368 					initiator_eph_key, responder_eph_key);
369 		if (res)
370 			goto out;
371 
372 		if (consttime_memcmp(S1, p->conf_in, sizeof(S1))) {
373 			/* Verification failed */
374 			res = TEE_ERROR_BAD_STATE;
375 			goto out;
376 		}
377 	}
378 
379 	/* Step A10: compute SA */
380 
381 	if (p->conf_out) {
382 		uint8_t flag = p->is_initiator ? 0x03 : 0x02;
383 
384 		if (p->conf_out_len < TEE_SM3_HASH_SIZE) {
385 			res = TEE_ERROR_BAD_PARAMETERS;
386 			goto out;
387 		}
388 
389 		res = sm2_kep_compute_S(p->conf_out, TEE_SM3_HASH_SIZE, flag, U,
390 					xUyUZAZB + 2 * SM2_INT_SIZE_BYTES,
391 					2 * SM2_INT_SIZE_BYTES,
392 					initiator_eph_key, responder_eph_key);
393 		if (res)
394 			goto out;
395 	}
396 out:
397 	mp_montgomery_free(mp);
398 	ltc_ecc_del_point(U);
399 	mp_clear_multi(x1bar, x2bar, tA, h, htA, mu, ma, one, NULL);
400 	return res;
401 }
402 
crypto_acipher_sm2_kep_derive(struct ecc_keypair * my_key,struct ecc_keypair * my_eph_key,struct ecc_public_key * peer_key,struct ecc_public_key * peer_eph_key,struct sm2_kep_parms * p)403 TEE_Result crypto_acipher_sm2_kep_derive(struct ecc_keypair *my_key,
404 					 struct ecc_keypair *my_eph_key,
405 					 struct ecc_public_key *peer_key,
406 					 struct ecc_public_key *peer_eph_key,
407 					 struct sm2_kep_parms *p)
408 {
409 	TEE_Result res = TEE_SUCCESS;
410 	ecc_key ltc_my_key = { };
411 	ecc_key ltc_my_eph_key = { };
412 	ecc_key ltc_peer_key = { };
413 	ecc_key ltc_peer_eph_key = { };
414 
415 	res = ecc_populate_ltc_private_key(&ltc_my_key, my_key,
416 					   TEE_ALG_SM2_KEP, NULL);
417 	if (res)
418 		goto out;
419 
420 	res = ecc_populate_ltc_private_key(&ltc_my_eph_key, my_eph_key,
421 					   TEE_ALG_SM2_KEP, NULL);
422 	if (res)
423 		goto out;
424 
425 	res = ecc_populate_ltc_public_key(&ltc_peer_key, peer_key,
426 					  TEE_ALG_SM2_KEP, NULL);
427 	if (res)
428 		goto out;
429 
430 	res = ecc_populate_ltc_public_key(&ltc_peer_eph_key, peer_eph_key,
431 					  TEE_ALG_SM2_KEP, NULL);
432 	if (res)
433 		goto out;
434 
435 	res = sm2_kep_derive(&ltc_my_key, &ltc_my_eph_key, &ltc_peer_key,
436 			     &ltc_peer_eph_key, p);
437 out:
438 	ecc_free(&ltc_peer_eph_key);
439 	ecc_free(&ltc_peer_key);
440 	ecc_free(&ltc_my_eph_key);
441 	ecc_free(&ltc_my_key);
442 	return res;
443 }
444