xref: /optee_os/lib/libmbedtls/core/ecc.c (revision 9fc2442cc66c279cb962c90c4375746fc9b28bb9)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (C) 2018, ARM Limited
4  * Copyright (C) 2019, Linaro Limited
5  */
6 
7 #include <assert.h>
8 #include <compiler.h>
9 #include <crypto/crypto_impl.h>
10 #include <mbedtls/ctr_drbg.h>
11 #include <mbedtls/ecdh.h>
12 #include <mbedtls/ecdsa.h>
13 #include <mbedtls/ecp.h>
14 #include <mbedtls/entropy.h>
15 #include <mbedtls/pk.h>
16 #include <stdlib.h>
17 #include <string.h>
18 
19 #include "mbed_helpers.h"
20 
21 /* Translate mbedtls result to TEE result */
22 static TEE_Result get_tee_result(int lmd_res)
23 {
24 	switch (lmd_res) {
25 	case 0:
26 		return TEE_SUCCESS;
27 	case MBEDTLS_ERR_ECP_VERIFY_FAILED:
28 		return TEE_ERROR_SIGNATURE_INVALID;
29 	case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
30 		return TEE_ERROR_SHORT_BUFFER;
31 	default:
32 		return TEE_ERROR_BAD_STATE;
33 	}
34 }
35 
36 static void ecc_free_public_key(struct ecc_public_key *s)
37 {
38 	if (!s)
39 		return;
40 
41 	crypto_bignum_free(s->x);
42 	crypto_bignum_free(s->y);
43 }
44 
45 /*
46  * curve is part of TEE_ECC_CURVE_NIST_P192,...
47  * algo is part of TEE_ALG_ECDSA_P192,..., and 0 if we do not have it
48  */
49 static TEE_Result ecc_get_keysize(uint32_t curve, uint32_t algo,
50 				  size_t *key_size_bytes, size_t *key_size_bits)
51 {
52 	/*
53 	 * Note GPv1.1 indicates TEE_ALG_ECDH_NIST_P192_DERIVE_SHARED_SECRET
54 	 * but defines TEE_ALG_ECDH_P192
55 	 */
56 	switch (curve) {
57 	case TEE_ECC_CURVE_NIST_P192:
58 		*key_size_bits = 192;
59 		*key_size_bytes = 24;
60 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P192) &&
61 		    (algo != TEE_ALG_ECDH_P192))
62 			return TEE_ERROR_BAD_PARAMETERS;
63 		break;
64 	case TEE_ECC_CURVE_NIST_P224:
65 		*key_size_bits = 224;
66 		*key_size_bytes = 28;
67 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P224) &&
68 		    (algo != TEE_ALG_ECDH_P224))
69 			return TEE_ERROR_BAD_PARAMETERS;
70 		break;
71 	case TEE_ECC_CURVE_NIST_P256:
72 		*key_size_bits = 256;
73 		*key_size_bytes = 32;
74 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P256) &&
75 		    (algo != TEE_ALG_ECDH_P256))
76 			return TEE_ERROR_BAD_PARAMETERS;
77 		break;
78 	case TEE_ECC_CURVE_NIST_P384:
79 		*key_size_bits = 384;
80 		*key_size_bytes = 48;
81 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P384) &&
82 		    (algo != TEE_ALG_ECDH_P384))
83 			return TEE_ERROR_BAD_PARAMETERS;
84 		break;
85 	case TEE_ECC_CURVE_NIST_P521:
86 		*key_size_bits = 521;
87 		*key_size_bytes = 66;
88 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P521) &&
89 		    (algo != TEE_ALG_ECDH_P521))
90 			return TEE_ERROR_BAD_PARAMETERS;
91 		break;
92 	default:
93 		*key_size_bits = 0;
94 		*key_size_bytes = 0;
95 		return TEE_ERROR_NOT_SUPPORTED;
96 	}
97 
98 	return TEE_SUCCESS;
99 }
100 
101 /*
102  * Clear some memory that was used to prepare the context
103  */
104 static void ecc_clear_precomputed(mbedtls_ecp_group *grp)
105 {
106 	size_t i = 0;
107 
108 	if (grp->T) {
109 		for (i = 0; i < grp->T_size; i++)
110 			mbedtls_ecp_point_free(&grp->T[i]);
111 		free(grp->T);
112 	}
113 	grp->T = NULL;
114 	grp->T_size = 0;
115 }
116 
117 static TEE_Result ecc_generate_keypair(struct ecc_keypair *key, size_t key_size)
118 {
119 	TEE_Result res = TEE_SUCCESS;
120 	int lmd_res = 0;
121 	mbedtls_ecdsa_context ecdsa;
122 	size_t key_size_bytes = 0;
123 	size_t key_size_bits = 0;
124 
125 	memset(&ecdsa, 0, sizeof(ecdsa));
126 
127 	res = ecc_get_keysize(key->curve, 0, &key_size_bytes, &key_size_bits);
128 	if (res != TEE_SUCCESS)
129 		return res;
130 
131 	if (key_size != key_size_bits)
132 		return TEE_ERROR_BAD_PARAMETERS;
133 
134 	mbedtls_ecdsa_init(&ecdsa);
135 
136 	/* Generate the ECC key */
137 	lmd_res = mbedtls_ecdsa_genkey(&ecdsa, key->curve, mbd_rand, NULL);
138 	if (lmd_res != 0) {
139 		res = TEE_ERROR_BAD_PARAMETERS;
140 		FMSG("mbedtls_ecdsa_genkey failed.");
141 		goto exit;
142 	}
143 	ecc_clear_precomputed(&ecdsa.grp);
144 
145 	/* check the size of the keys */
146 	if ((mbedtls_mpi_bitlen(&ecdsa.Q.X) > key_size_bits) ||
147 	    (mbedtls_mpi_bitlen(&ecdsa.Q.Y) > key_size_bits) ||
148 	    (mbedtls_mpi_bitlen(&ecdsa.d) > key_size_bits)) {
149 		res = TEE_ERROR_BAD_PARAMETERS;
150 		FMSG("Check the size of the keys failed.");
151 		goto exit;
152 	}
153 
154 	/* check LMD is returning z==1 */
155 	if (mbedtls_mpi_bitlen(&ecdsa.Q.Z) != 1) {
156 		res = TEE_ERROR_BAD_PARAMETERS;
157 		FMSG("Check LMD failed.");
158 		goto exit;
159 	}
160 
161 	/* Copy the key */
162 	crypto_bignum_copy(key->d, (void *)&ecdsa.d);
163 	crypto_bignum_copy(key->x, (void *)&ecdsa.Q.X);
164 	crypto_bignum_copy(key->y, (void *)&ecdsa.Q.Y);
165 
166 	res = TEE_SUCCESS;
167 exit:
168 	mbedtls_ecdsa_free(&ecdsa);		/* Free the temporary key */
169 	return res;
170 }
171 
172 static TEE_Result ecc_sign(uint32_t algo, struct ecc_keypair *key,
173 			   const uint8_t *msg, size_t msg_len, uint8_t *sig,
174 			   size_t *sig_len)
175 {
176 	TEE_Result res = TEE_SUCCESS;
177 	int lmd_res = 0;
178 	const mbedtls_pk_info_t *pk_info = NULL;
179 	mbedtls_ecdsa_context ecdsa;
180 	size_t key_size_bytes = 0;
181 	size_t key_size_bits = 0;
182 	mbedtls_mpi r;
183 	mbedtls_mpi s;
184 
185 	memset(&ecdsa, 0, sizeof(ecdsa));
186 	memset(&r, 0, sizeof(r));
187 	memset(&s, 0, sizeof(s));
188 
189 	if (algo == 0)
190 		return TEE_ERROR_BAD_PARAMETERS;
191 
192 	mbedtls_mpi_init(&r);
193 	mbedtls_mpi_init(&s);
194 
195 	mbedtls_ecdsa_init(&ecdsa);
196 	lmd_res = mbedtls_ecp_group_load(&ecdsa.grp, key->curve);
197 	if (lmd_res != 0) {
198 		res = TEE_ERROR_NOT_SUPPORTED;
199 		goto out;
200 	}
201 
202 	ecdsa.d = *(mbedtls_mpi *)key->d;
203 
204 	res = ecc_get_keysize(key->curve, algo, &key_size_bytes,
205 			      &key_size_bits);
206 	if (res != TEE_SUCCESS)
207 		goto out;
208 
209 	pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECDSA);
210 	if (pk_info == NULL) {
211 		res = TEE_ERROR_NOT_SUPPORTED;
212 		goto out;
213 	}
214 
215 	lmd_res = mbedtls_ecdsa_sign(&ecdsa.grp, &r, &s, &ecdsa.d, msg,
216 				     msg_len, mbd_rand, NULL);
217 	if (lmd_res == 0) {
218 		*sig_len = 2 * key_size_bytes;
219 		memset(sig, 0, *sig_len);
220 		mbedtls_mpi_write_binary(&r, sig + *sig_len / 2 -
221 					 mbedtls_mpi_size(&r),
222 					 mbedtls_mpi_size(&r));
223 
224 		mbedtls_mpi_write_binary(&s, sig + *sig_len -
225 					 mbedtls_mpi_size(&s),
226 					 mbedtls_mpi_size(&s));
227 		res = TEE_SUCCESS;
228 	} else {
229 		FMSG("mbedtls_ecdsa_sign failed, returned 0x%x\n", -lmd_res);
230 		res = TEE_ERROR_GENERIC;
231 	}
232 out:
233 	mbedtls_mpi_free(&r);
234 	mbedtls_mpi_free(&s);
235 	/* Reset mpi to skip freeing here, those mpis will be freed with key */
236 	mbedtls_mpi_init(&ecdsa.d);
237 	mbedtls_ecdsa_free(&ecdsa);
238 	return res;
239 }
240 
241 static TEE_Result ecc_verify(uint32_t algo, struct ecc_public_key *key,
242 			     const uint8_t *msg, size_t msg_len,
243 			     const uint8_t *sig, size_t sig_len)
244 {
245 	TEE_Result res = TEE_SUCCESS;
246 	int lmd_res = 0;
247 	mbedtls_ecdsa_context ecdsa;
248 	size_t key_size_bytes, key_size_bits = 0;
249 	uint8_t one[1] = { 1 };
250 	mbedtls_mpi r;
251 	mbedtls_mpi s;
252 
253 	memset(&ecdsa, 0, sizeof(ecdsa));
254 	memset(&r, 0, sizeof(r));
255 	memset(&s, 0, sizeof(s));
256 
257 	if (algo == 0)
258 		return TEE_ERROR_BAD_PARAMETERS;
259 
260 	mbedtls_mpi_init(&r);
261 	mbedtls_mpi_init(&s);
262 
263 	mbedtls_ecdsa_init(&ecdsa);
264 
265 	lmd_res = mbedtls_ecp_group_load(&ecdsa.grp, key->curve);
266 	if (lmd_res != 0) {
267 		res = TEE_ERROR_NOT_SUPPORTED;
268 		goto out;
269 	}
270 
271 	ecdsa.Q.X = *(mbedtls_mpi *)key->x;
272 	ecdsa.Q.Y = *(mbedtls_mpi *)key->y;
273 	mbedtls_mpi_read_binary(&ecdsa.Q.Z, one, sizeof(one));
274 
275 	res = ecc_get_keysize(key->curve, algo,
276 			      &key_size_bytes, &key_size_bits);
277 	if (res != TEE_SUCCESS) {
278 		res = TEE_ERROR_BAD_PARAMETERS;
279 		goto out;
280 	}
281 
282 	/* check keysize vs sig_len */
283 	if ((key_size_bytes * 2) != sig_len) {
284 		res = TEE_ERROR_BAD_PARAMETERS;
285 		goto out;
286 	}
287 
288 	mbedtls_mpi_read_binary(&r, sig, sig_len / 2);
289 	mbedtls_mpi_read_binary(&s, sig + sig_len / 2, sig_len / 2);
290 
291 	lmd_res = mbedtls_ecdsa_verify(&ecdsa.grp, msg, msg_len, &ecdsa.Q,
292 				       &r, &s);
293 	if (lmd_res != 0) {
294 		FMSG("mbedtls_ecdsa_verify failed, returned 0x%x", -lmd_res);
295 		res = get_tee_result(lmd_res);
296 	}
297 out:
298 	mbedtls_mpi_free(&r);
299 	mbedtls_mpi_free(&s);
300 	/* Reset mpi to skip freeing here, those mpis will be freed with key */
301 	mbedtls_mpi_init(&ecdsa.Q.X);
302 	mbedtls_mpi_init(&ecdsa.Q.Y);
303 	mbedtls_ecdsa_free(&ecdsa);
304 	return res;
305 }
306 
307 static TEE_Result ecc_shared_secret(struct ecc_keypair *private_key,
308 				    struct ecc_public_key *public_key,
309 				    void *secret, unsigned long *secret_len)
310 {
311 	TEE_Result res = TEE_SUCCESS;
312 	int lmd_res = 0;
313 	uint8_t one[1] = { 1 };
314 	mbedtls_ecdh_context ecdh;
315 	size_t out_len = 0;
316 
317 	memset(&ecdh, 0, sizeof(ecdh));
318 	mbedtls_ecdh_init(&ecdh);
319 	lmd_res = mbedtls_ecp_group_load(&ecdh.grp, private_key->curve);
320 	if (lmd_res != 0) {
321 		res = TEE_ERROR_NOT_SUPPORTED;
322 		goto out;
323 	}
324 
325 	ecdh.d = *(mbedtls_mpi *)private_key->d;
326 	ecdh.Qp.X = *(mbedtls_mpi *)public_key->x;
327 	ecdh.Qp.Y = *(mbedtls_mpi *)public_key->y;
328 	mbedtls_mpi_read_binary(&ecdh.Qp.Z, one, sizeof(one));
329 
330 	lmd_res = mbedtls_ecdh_calc_secret(&ecdh, &out_len, secret,
331 					   *secret_len, mbd_rand, NULL);
332 	if (lmd_res != 0) {
333 		res = get_tee_result(lmd_res);
334 		goto out;
335 	}
336 	*secret_len = out_len;
337 out:
338 	/* Reset mpi to skip freeing here, those mpis will be freed with key */
339 	mbedtls_mpi_init(&ecdh.d);
340 	mbedtls_mpi_init(&ecdh.Qp.X);
341 	mbedtls_mpi_init(&ecdh.Qp.Y);
342 	mbedtls_ecdh_free(&ecdh);
343 	return res;
344 }
345 
346 static const struct crypto_ecc_keypair_ops ecc_keypair_ops = {
347 	.generate = ecc_generate_keypair,
348 	.sign = ecc_sign,
349 	.shared_secret = ecc_shared_secret,
350 };
351 
352 TEE_Result crypto_asym_alloc_ecc_keypair(struct ecc_keypair *s,
353 					 uint32_t key_type,
354 					 size_t key_size_bits)
355 {
356 	switch (key_type) {
357 	case TEE_TYPE_SM2_DSA_KEYPAIR:
358 	case TEE_TYPE_SM2_PKE_KEYPAIR:
359 	case TEE_TYPE_SM2_KEP_KEYPAIR:
360 		return TEE_ERROR_NOT_IMPLEMENTED;
361 	default:
362 		break;
363 	}
364 
365 	memset(s, 0, sizeof(*s));
366 	s->d = crypto_bignum_allocate(key_size_bits);
367 	if (!s->d)
368 		goto err;
369 	s->x = crypto_bignum_allocate(key_size_bits);
370 	if (!s->x)
371 		goto err;
372 	s->y = crypto_bignum_allocate(key_size_bits);
373 	if (!s->y)
374 		goto err;
375 
376 	s->ops = &ecc_keypair_ops;
377 
378 	return TEE_SUCCESS;
379 
380 err:
381 	crypto_bignum_free(s->d);
382 	crypto_bignum_free(s->x);
383 
384 	return TEE_ERROR_OUT_OF_MEMORY;
385 }
386 
387 static const struct crypto_ecc_public_ops ecc_public_key_ops = {
388 	.free = ecc_free_public_key,
389 	.verify = ecc_verify,
390 };
391 
392 TEE_Result crypto_asym_alloc_ecc_public_key(struct ecc_public_key *s,
393 					    uint32_t key_type,
394 					    size_t key_size_bits)
395 {
396 	switch (key_type) {
397 	case TEE_TYPE_SM2_DSA_PUBLIC_KEY:
398 	case TEE_TYPE_SM2_PKE_PUBLIC_KEY:
399 	case TEE_TYPE_SM2_KEP_PUBLIC_KEY:
400 		return TEE_ERROR_NOT_IMPLEMENTED;
401 	default:
402 		break;
403 	}
404 
405 	memset(s, 0, sizeof(*s));
406 	s->x = crypto_bignum_allocate(key_size_bits);
407 	if (!s->x)
408 		goto err;
409 	s->y = crypto_bignum_allocate(key_size_bits);
410 	if (!s->y)
411 		goto err;
412 
413 	s->ops = &ecc_public_key_ops;
414 
415 	return TEE_SUCCESS;
416 
417 err:
418 	crypto_bignum_free(s->x);
419 
420 	return TEE_ERROR_OUT_OF_MEMORY;
421 }
422