xref: /optee_os/lib/libmbedtls/core/ecc.c (revision 5b25c76ac40f830867e3d60800120ffd7874e8dc)
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)
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 	mbedtls_ecdsa_init(&ecdsa);
168 
169 	/* Generate the ECC key */
170 	lmd_res = mbedtls_ecdsa_genkey(&ecdsa, key->curve, mbd_rand, NULL);
171 	if (lmd_res != 0) {
172 		res = TEE_ERROR_BAD_PARAMETERS;
173 		FMSG("mbedtls_ecdsa_genkey failed.");
174 		goto exit;
175 	}
176 	ecc_clear_precomputed(&ecdsa.grp);
177 
178 	/* check the size of the keys */
179 	if ((mbedtls_mpi_bitlen(&ecdsa.Q.X) > key_size_bits) ||
180 	    (mbedtls_mpi_bitlen(&ecdsa.Q.Y) > key_size_bits) ||
181 	    (mbedtls_mpi_bitlen(&ecdsa.d) > key_size_bits)) {
182 		res = TEE_ERROR_BAD_PARAMETERS;
183 		FMSG("Check the size of the keys failed.");
184 		goto exit;
185 	}
186 
187 	/* check LMD is returning z==1 */
188 	if (mbedtls_mpi_bitlen(&ecdsa.Q.Z) != 1) {
189 		res = TEE_ERROR_BAD_PARAMETERS;
190 		FMSG("Check LMD failed.");
191 		goto exit;
192 	}
193 
194 	/* Copy the key */
195 	crypto_bignum_copy(key->d, (void *)&ecdsa.d);
196 	crypto_bignum_copy(key->x, (void *)&ecdsa.Q.X);
197 	crypto_bignum_copy(key->y, (void *)&ecdsa.Q.Y);
198 
199 	res = TEE_SUCCESS;
200 exit:
201 	mbedtls_ecdsa_free(&ecdsa);		/* Free the temporary key */
202 	return res;
203 }
204 
205 TEE_Result crypto_acipher_ecc_sign(uint32_t algo, struct ecc_keypair *key,
206 				   const uint8_t *msg, size_t msg_len,
207 				   uint8_t *sig, size_t *sig_len)
208 {
209 	TEE_Result res = TEE_SUCCESS;
210 	int lmd_res = 0;
211 	const mbedtls_pk_info_t *pk_info = NULL;
212 	mbedtls_ecdsa_context ecdsa;
213 	size_t key_size_bytes = 0;
214 	size_t key_size_bits = 0;
215 	mbedtls_mpi r;
216 	mbedtls_mpi s;
217 
218 	memset(&ecdsa, 0, sizeof(ecdsa));
219 	memset(&r, 0, sizeof(r));
220 	memset(&s, 0, sizeof(s));
221 
222 	if (algo == 0)
223 		return TEE_ERROR_BAD_PARAMETERS;
224 
225 	mbedtls_mpi_init(&r);
226 	mbedtls_mpi_init(&s);
227 
228 	mbedtls_ecdsa_init(&ecdsa);
229 	lmd_res = mbedtls_ecp_group_load(&ecdsa.grp, key->curve);
230 	if (lmd_res != 0) {
231 		res = TEE_ERROR_NOT_SUPPORTED;
232 		goto out;
233 	}
234 
235 	ecdsa.d = *(mbedtls_mpi *)key->d;
236 
237 	res = ecc_get_keysize(key->curve, algo, &key_size_bytes,
238 			      &key_size_bits);
239 	if (res != TEE_SUCCESS)
240 		goto out;
241 
242 	pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECDSA);
243 	if (pk_info == NULL) {
244 		res = TEE_ERROR_NOT_SUPPORTED;
245 		goto out;
246 	}
247 
248 	lmd_res = mbedtls_ecdsa_sign(&ecdsa.grp, &r, &s, &ecdsa.d, msg,
249 				     msg_len, mbd_rand, NULL);
250 	if (lmd_res == 0) {
251 		*sig_len = 2 * key_size_bytes;
252 		memset(sig, 0, *sig_len);
253 		mbedtls_mpi_write_binary(&r, sig + *sig_len / 2 -
254 					 mbedtls_mpi_size(&r),
255 					 mbedtls_mpi_size(&r));
256 
257 		mbedtls_mpi_write_binary(&s, sig + *sig_len -
258 					 mbedtls_mpi_size(&s),
259 					 mbedtls_mpi_size(&s));
260 		res = TEE_SUCCESS;
261 	} else {
262 		FMSG("mbedtls_ecdsa_sign failed, returned 0x%x\n", -lmd_res);
263 		res = TEE_ERROR_GENERIC;
264 	}
265 out:
266 	mbedtls_mpi_free(&r);
267 	mbedtls_mpi_free(&s);
268 	/* Reset mpi to skip freeing here, those mpis will be freed with key */
269 	mbedtls_mpi_init(&ecdsa.d);
270 	mbedtls_ecdsa_free(&ecdsa);
271 	return res;
272 }
273 
274 TEE_Result crypto_acipher_ecc_verify(uint32_t algo, struct ecc_public_key *key,
275 				     const uint8_t *msg, size_t msg_len,
276 				     const uint8_t *sig, size_t sig_len)
277 {
278 	TEE_Result res = TEE_SUCCESS;
279 	int lmd_res = 0;
280 	mbedtls_ecdsa_context ecdsa;
281 	size_t key_size_bytes, key_size_bits = 0;
282 	uint8_t one[1] = { 1 };
283 	mbedtls_mpi r;
284 	mbedtls_mpi s;
285 
286 	memset(&ecdsa, 0, sizeof(ecdsa));
287 	memset(&r, 0, sizeof(r));
288 	memset(&s, 0, sizeof(s));
289 
290 	if (algo == 0)
291 		return TEE_ERROR_BAD_PARAMETERS;
292 
293 	mbedtls_mpi_init(&r);
294 	mbedtls_mpi_init(&s);
295 
296 	mbedtls_ecdsa_init(&ecdsa);
297 
298 	lmd_res = mbedtls_ecp_group_load(&ecdsa.grp, key->curve);
299 	if (lmd_res != 0) {
300 		res = TEE_ERROR_NOT_SUPPORTED;
301 		goto out;
302 	}
303 
304 	ecdsa.Q.X = *(mbedtls_mpi *)key->x;
305 	ecdsa.Q.Y = *(mbedtls_mpi *)key->y;
306 	mbedtls_mpi_read_binary(&ecdsa.Q.Z, one, sizeof(one));
307 
308 	res = ecc_get_keysize(key->curve, algo,
309 			      &key_size_bytes, &key_size_bits);
310 	if (res != TEE_SUCCESS) {
311 		res = TEE_ERROR_BAD_PARAMETERS;
312 		goto out;
313 	}
314 
315 	/* check keysize vs sig_len */
316 	if ((key_size_bytes * 2) != sig_len) {
317 		res = TEE_ERROR_BAD_PARAMETERS;
318 		goto out;
319 	}
320 
321 	mbedtls_mpi_read_binary(&r, sig, sig_len / 2);
322 	mbedtls_mpi_read_binary(&s, sig + sig_len / 2, sig_len / 2);
323 
324 	lmd_res = mbedtls_ecdsa_verify(&ecdsa.grp, msg, msg_len, &ecdsa.Q,
325 				       &r, &s);
326 	if (lmd_res != 0) {
327 		FMSG("mbedtls_ecdsa_verify failed, returned 0x%x", -lmd_res);
328 		res = get_tee_result(lmd_res);
329 	}
330 out:
331 	mbedtls_mpi_free(&r);
332 	mbedtls_mpi_free(&s);
333 	/* Reset mpi to skip freeing here, those mpis will be freed with key */
334 	mbedtls_mpi_init(&ecdsa.Q.X);
335 	mbedtls_mpi_init(&ecdsa.Q.Y);
336 	mbedtls_ecdsa_free(&ecdsa);
337 	return res;
338 }
339 
340 TEE_Result crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key,
341 					    struct ecc_public_key *public_key,
342 					    void *secret,
343 					    unsigned long *secret_len)
344 {
345 	TEE_Result res = TEE_SUCCESS;
346 	int lmd_res = 0;
347 	uint8_t one[1] = { 1 };
348 	mbedtls_ecdh_context ecdh;
349 	size_t out_len = 0;
350 
351 	memset(&ecdh, 0, sizeof(ecdh));
352 	mbedtls_ecdh_init(&ecdh);
353 	lmd_res = mbedtls_ecp_group_load(&ecdh.grp, private_key->curve);
354 	if (lmd_res != 0) {
355 		res = TEE_ERROR_NOT_SUPPORTED;
356 		goto out;
357 	}
358 
359 	ecdh.d = *(mbedtls_mpi *)private_key->d;
360 	ecdh.Qp.X = *(mbedtls_mpi *)public_key->x;
361 	ecdh.Qp.Y = *(mbedtls_mpi *)public_key->y;
362 	mbedtls_mpi_read_binary(&ecdh.Qp.Z, one, sizeof(one));
363 
364 	lmd_res = mbedtls_ecdh_calc_secret(&ecdh, &out_len, secret,
365 					   *secret_len, mbd_rand, NULL);
366 	if (lmd_res != 0) {
367 		res = get_tee_result(lmd_res);
368 		goto out;
369 	}
370 	*secret_len = out_len;
371 out:
372 	/* Reset mpi to skip freeing here, those mpis will be freed with key */
373 	mbedtls_mpi_init(&ecdh.d);
374 	mbedtls_mpi_init(&ecdh.Qp.X);
375 	mbedtls_mpi_init(&ecdh.Qp.Y);
376 	mbedtls_ecdh_free(&ecdh);
377 	return res;
378 }
379