xref: /optee_os/lib/libmbedtls/core/ecc.c (revision 11fa71b9ddb429088f325cfda430183003ccd1db)
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.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 "mbd_rand.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 TEE_Result crypto_acipher_alloc_ecc_keypair(struct ecc_keypair *s,
37 					    size_t key_size_bits)
38 {
39 	memset(s, 0, sizeof(*s));
40 	s->d = crypto_bignum_allocate(key_size_bits);
41 	if (!s->d)
42 		goto err;
43 	s->x = crypto_bignum_allocate(key_size_bits);
44 	if (!s->x)
45 		goto err;
46 	s->y = crypto_bignum_allocate(key_size_bits);
47 	if (!s->y)
48 		goto err;
49 	return TEE_SUCCESS;
50 err:
51 	crypto_bignum_free(s->d);
52 	crypto_bignum_free(s->x);
53 	return TEE_ERROR_OUT_OF_MEMORY;
54 }
55 
56 TEE_Result crypto_acipher_alloc_ecc_public_key(struct ecc_public_key *s,
57 					       size_t key_size_bits)
58 {
59 	memset(s, 0, sizeof(*s));
60 	s->x = crypto_bignum_allocate(key_size_bits);
61 	if (!s->x)
62 		goto err;
63 	s->y = crypto_bignum_allocate(key_size_bits);
64 	if (!s->y)
65 		goto err;
66 	return TEE_SUCCESS;
67 err:
68 	crypto_bignum_free(s->x);
69 	return TEE_ERROR_OUT_OF_MEMORY;
70 }
71 
72 void crypto_acipher_free_ecc_public_key(struct ecc_public_key *s)
73 {
74 	if (!s)
75 		return;
76 
77 	crypto_bignum_free(s->x);
78 	crypto_bignum_free(s->y);
79 }
80 
81 /*
82  * curve is part of TEE_ECC_CURVE_NIST_P192,...
83  * algo is part of TEE_ALG_ECDSA_P192,..., and 0 if we do not have it
84  */
85 static TEE_Result ecc_get_keysize(uint32_t curve, uint32_t algo,
86 				  size_t *key_size_bytes, size_t *key_size_bits)
87 {
88 	/*
89 	 * Note GPv1.1 indicates TEE_ALG_ECDH_NIST_P192_DERIVE_SHARED_SECRET
90 	 * but defines TEE_ALG_ECDH_P192
91 	 */
92 	switch (curve) {
93 	case TEE_ECC_CURVE_NIST_P192:
94 		*key_size_bits = 192;
95 		*key_size_bytes = 24;
96 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P192) &&
97 		    (algo != TEE_ALG_ECDH_P192))
98 			return TEE_ERROR_BAD_PARAMETERS;
99 		break;
100 	case TEE_ECC_CURVE_NIST_P224:
101 		*key_size_bits = 224;
102 		*key_size_bytes = 28;
103 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P224) &&
104 		    (algo != TEE_ALG_ECDH_P224))
105 			return TEE_ERROR_BAD_PARAMETERS;
106 		break;
107 	case TEE_ECC_CURVE_NIST_P256:
108 		*key_size_bits = 256;
109 		*key_size_bytes = 32;
110 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P256) &&
111 		    (algo != TEE_ALG_ECDH_P256))
112 			return TEE_ERROR_BAD_PARAMETERS;
113 		break;
114 	case TEE_ECC_CURVE_NIST_P384:
115 		*key_size_bits = 384;
116 		*key_size_bytes = 48;
117 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P384) &&
118 		    (algo != TEE_ALG_ECDH_P384))
119 			return TEE_ERROR_BAD_PARAMETERS;
120 		break;
121 	case TEE_ECC_CURVE_NIST_P521:
122 		*key_size_bits = 521;
123 		*key_size_bytes = 66;
124 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P521) &&
125 		    (algo != TEE_ALG_ECDH_P521))
126 			return TEE_ERROR_BAD_PARAMETERS;
127 		break;
128 	default:
129 		*key_size_bits = 0;
130 		*key_size_bytes = 0;
131 		return TEE_ERROR_NOT_SUPPORTED;
132 	}
133 
134 	return TEE_SUCCESS;
135 }
136 
137 /*
138  * Clear some memory that was used to prepare the context
139  */
140 static void ecc_clear_precomputed(mbedtls_ecp_group *grp)
141 {
142 	size_t i = 0;
143 
144 	if (grp->T) {
145 		for (i = 0; i < grp->T_size; i++)
146 			mbedtls_ecp_point_free(&grp->T[i]);
147 		free(grp->T);
148 	}
149 	grp->T = NULL;
150 	grp->T_size = 0;
151 }
152 
153 TEE_Result crypto_acipher_gen_ecc_key(struct ecc_keypair *key, size_t key_size)
154 {
155 	TEE_Result res = TEE_SUCCESS;
156 	int lmd_res = 0;
157 	mbedtls_ecdsa_context ecdsa;
158 	size_t key_size_bytes = 0;
159 	size_t key_size_bits = 0;
160 
161 	memset(&ecdsa, 0, sizeof(ecdsa));
162 
163 	res = ecc_get_keysize(key->curve, 0, &key_size_bytes, &key_size_bits);
164 	if (res != TEE_SUCCESS)
165 		return res;
166 
167 	if (key_size != key_size_bits)
168 		return TEE_ERROR_BAD_PARAMETERS;
169 
170 	mbedtls_ecdsa_init(&ecdsa);
171 
172 	/* Generate the ECC key */
173 	lmd_res = mbedtls_ecdsa_genkey(&ecdsa, key->curve, mbd_rand, NULL);
174 	if (lmd_res != 0) {
175 		res = TEE_ERROR_BAD_PARAMETERS;
176 		FMSG("mbedtls_ecdsa_genkey failed.");
177 		goto exit;
178 	}
179 	ecc_clear_precomputed(&ecdsa.grp);
180 
181 	/* check the size of the keys */
182 	if ((mbedtls_mpi_bitlen(&ecdsa.Q.X) > key_size_bits) ||
183 	    (mbedtls_mpi_bitlen(&ecdsa.Q.Y) > key_size_bits) ||
184 	    (mbedtls_mpi_bitlen(&ecdsa.d) > key_size_bits)) {
185 		res = TEE_ERROR_BAD_PARAMETERS;
186 		FMSG("Check the size of the keys failed.");
187 		goto exit;
188 	}
189 
190 	/* check LMD is returning z==1 */
191 	if (mbedtls_mpi_bitlen(&ecdsa.Q.Z) != 1) {
192 		res = TEE_ERROR_BAD_PARAMETERS;
193 		FMSG("Check LMD failed.");
194 		goto exit;
195 	}
196 
197 	/* Copy the key */
198 	crypto_bignum_copy(key->d, (void *)&ecdsa.d);
199 	crypto_bignum_copy(key->x, (void *)&ecdsa.Q.X);
200 	crypto_bignum_copy(key->y, (void *)&ecdsa.Q.Y);
201 
202 	res = TEE_SUCCESS;
203 exit:
204 	mbedtls_ecdsa_free(&ecdsa);		/* Free the temporary key */
205 	return res;
206 }
207 
208 TEE_Result crypto_acipher_ecc_sign(uint32_t algo, struct ecc_keypair *key,
209 				   const uint8_t *msg, size_t msg_len,
210 				   uint8_t *sig, size_t *sig_len)
211 {
212 	TEE_Result res = TEE_SUCCESS;
213 	int lmd_res = 0;
214 	const mbedtls_pk_info_t *pk_info = NULL;
215 	mbedtls_ecdsa_context ecdsa;
216 	size_t key_size_bytes = 0;
217 	size_t key_size_bits = 0;
218 	mbedtls_mpi r;
219 	mbedtls_mpi s;
220 
221 	memset(&ecdsa, 0, sizeof(ecdsa));
222 	memset(&r, 0, sizeof(r));
223 	memset(&s, 0, sizeof(s));
224 
225 	if (algo == 0)
226 		return TEE_ERROR_BAD_PARAMETERS;
227 
228 	mbedtls_mpi_init(&r);
229 	mbedtls_mpi_init(&s);
230 
231 	mbedtls_ecdsa_init(&ecdsa);
232 	lmd_res = mbedtls_ecp_group_load(&ecdsa.grp, key->curve);
233 	if (lmd_res != 0) {
234 		res = TEE_ERROR_NOT_SUPPORTED;
235 		goto out;
236 	}
237 
238 	ecdsa.d = *(mbedtls_mpi *)key->d;
239 
240 	res = ecc_get_keysize(key->curve, algo, &key_size_bytes,
241 			      &key_size_bits);
242 	if (res != TEE_SUCCESS)
243 		goto out;
244 
245 	pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECDSA);
246 	if (pk_info == NULL) {
247 		res = TEE_ERROR_NOT_SUPPORTED;
248 		goto out;
249 	}
250 
251 	lmd_res = mbedtls_ecdsa_sign(&ecdsa.grp, &r, &s, &ecdsa.d, msg,
252 				     msg_len, mbd_rand, NULL);
253 	if (lmd_res == 0) {
254 		*sig_len = 2 * key_size_bytes;
255 		memset(sig, 0, *sig_len);
256 		mbedtls_mpi_write_binary(&r, sig + *sig_len / 2 -
257 					 mbedtls_mpi_size(&r),
258 					 mbedtls_mpi_size(&r));
259 
260 		mbedtls_mpi_write_binary(&s, sig + *sig_len -
261 					 mbedtls_mpi_size(&s),
262 					 mbedtls_mpi_size(&s));
263 		res = TEE_SUCCESS;
264 	} else {
265 		FMSG("mbedtls_ecdsa_sign failed, returned 0x%x\n", -lmd_res);
266 		res = TEE_ERROR_GENERIC;
267 	}
268 out:
269 	mbedtls_mpi_free(&r);
270 	mbedtls_mpi_free(&s);
271 	/* Reset mpi to skip freeing here, those mpis will be freed with key */
272 	mbedtls_mpi_init(&ecdsa.d);
273 	mbedtls_ecdsa_free(&ecdsa);
274 	return res;
275 }
276 
277 TEE_Result crypto_acipher_ecc_verify(uint32_t algo, struct ecc_public_key *key,
278 				     const uint8_t *msg, size_t msg_len,
279 				     const uint8_t *sig, size_t sig_len)
280 {
281 	TEE_Result res = TEE_SUCCESS;
282 	int lmd_res = 0;
283 	mbedtls_ecdsa_context ecdsa;
284 	size_t key_size_bytes, key_size_bits = 0;
285 	uint8_t one[1] = { 1 };
286 	mbedtls_mpi r;
287 	mbedtls_mpi s;
288 
289 	memset(&ecdsa, 0, sizeof(ecdsa));
290 	memset(&r, 0, sizeof(r));
291 	memset(&s, 0, sizeof(s));
292 
293 	if (algo == 0)
294 		return TEE_ERROR_BAD_PARAMETERS;
295 
296 	mbedtls_mpi_init(&r);
297 	mbedtls_mpi_init(&s);
298 
299 	mbedtls_ecdsa_init(&ecdsa);
300 
301 	lmd_res = mbedtls_ecp_group_load(&ecdsa.grp, key->curve);
302 	if (lmd_res != 0) {
303 		res = TEE_ERROR_NOT_SUPPORTED;
304 		goto out;
305 	}
306 
307 	ecdsa.Q.X = *(mbedtls_mpi *)key->x;
308 	ecdsa.Q.Y = *(mbedtls_mpi *)key->y;
309 	mbedtls_mpi_read_binary(&ecdsa.Q.Z, one, sizeof(one));
310 
311 	res = ecc_get_keysize(key->curve, algo,
312 			      &key_size_bytes, &key_size_bits);
313 	if (res != TEE_SUCCESS) {
314 		res = TEE_ERROR_BAD_PARAMETERS;
315 		goto out;
316 	}
317 
318 	/* check keysize vs sig_len */
319 	if ((key_size_bytes * 2) != sig_len) {
320 		res = TEE_ERROR_BAD_PARAMETERS;
321 		goto out;
322 	}
323 
324 	mbedtls_mpi_read_binary(&r, sig, sig_len / 2);
325 	mbedtls_mpi_read_binary(&s, sig + sig_len / 2, sig_len / 2);
326 
327 	lmd_res = mbedtls_ecdsa_verify(&ecdsa.grp, msg, msg_len, &ecdsa.Q,
328 				       &r, &s);
329 	if (lmd_res != 0) {
330 		FMSG("mbedtls_ecdsa_verify failed, returned 0x%x", -lmd_res);
331 		res = get_tee_result(lmd_res);
332 	}
333 out:
334 	mbedtls_mpi_free(&r);
335 	mbedtls_mpi_free(&s);
336 	/* Reset mpi to skip freeing here, those mpis will be freed with key */
337 	mbedtls_mpi_init(&ecdsa.Q.X);
338 	mbedtls_mpi_init(&ecdsa.Q.Y);
339 	mbedtls_ecdsa_free(&ecdsa);
340 	return res;
341 }
342 
343 TEE_Result crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key,
344 					    struct ecc_public_key *public_key,
345 					    void *secret,
346 					    unsigned long *secret_len)
347 {
348 	TEE_Result res = TEE_SUCCESS;
349 	int lmd_res = 0;
350 	uint8_t one[1] = { 1 };
351 	mbedtls_ecdh_context ecdh;
352 	size_t out_len = 0;
353 
354 	memset(&ecdh, 0, sizeof(ecdh));
355 	mbedtls_ecdh_init(&ecdh);
356 	lmd_res = mbedtls_ecp_group_load(&ecdh.grp, private_key->curve);
357 	if (lmd_res != 0) {
358 		res = TEE_ERROR_NOT_SUPPORTED;
359 		goto out;
360 	}
361 
362 	ecdh.d = *(mbedtls_mpi *)private_key->d;
363 	ecdh.Qp.X = *(mbedtls_mpi *)public_key->x;
364 	ecdh.Qp.Y = *(mbedtls_mpi *)public_key->y;
365 	mbedtls_mpi_read_binary(&ecdh.Qp.Z, one, sizeof(one));
366 
367 	lmd_res = mbedtls_ecdh_calc_secret(&ecdh, &out_len, secret,
368 					   *secret_len, mbd_rand, NULL);
369 	if (lmd_res != 0) {
370 		res = get_tee_result(lmd_res);
371 		goto out;
372 	}
373 	*secret_len = out_len;
374 out:
375 	/* Reset mpi to skip freeing here, those mpis will be freed with key */
376 	mbedtls_mpi_init(&ecdh.d);
377 	mbedtls_mpi_init(&ecdh.Qp.X);
378 	mbedtls_mpi_init(&ecdh.Qp.Y);
379 	mbedtls_ecdh_free(&ecdh);
380 	return res;
381 }
382