xref: /optee_os/core/lib/libtomcrypt/ecc.c (revision 11fa71b9ddb429088f325cfda430183003ccd1db)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2014-2019, Linaro Limited
4  */
5 
6 #include <crypto/crypto.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <tee_api_types.h>
10 #include <trace.h>
11 #include <utee_defines.h>
12 
13 #include "acipher_helpers.h"
14 
15 TEE_Result crypto_acipher_alloc_ecc_keypair(struct ecc_keypair *s,
16 					    size_t key_size_bits __unused)
17 {
18 	memset(s, 0, sizeof(*s));
19 	if (!bn_alloc_max(&s->d))
20 		goto err;
21 	if (!bn_alloc_max(&s->x))
22 		goto err;
23 	if (!bn_alloc_max(&s->y))
24 		goto err;
25 	return TEE_SUCCESS;
26 err:
27 	crypto_bignum_free(s->d);
28 	crypto_bignum_free(s->x);
29 	crypto_bignum_free(s->y);
30 	return TEE_ERROR_OUT_OF_MEMORY;
31 }
32 
33 TEE_Result crypto_acipher_alloc_ecc_public_key(struct ecc_public_key *s,
34 					       size_t key_size_bits __unused)
35 {
36 	memset(s, 0, sizeof(*s));
37 	if (!bn_alloc_max(&s->x))
38 		goto err;
39 	if (!bn_alloc_max(&s->y))
40 		goto err;
41 	return TEE_SUCCESS;
42 err:
43 	crypto_bignum_free(s->x);
44 	crypto_bignum_free(s->y);
45 	return TEE_ERROR_OUT_OF_MEMORY;
46 }
47 
48 void crypto_acipher_free_ecc_public_key(struct ecc_public_key *s)
49 {
50 	if (!s)
51 		return;
52 
53 	crypto_bignum_free(s->x);
54 	crypto_bignum_free(s->y);
55 }
56 
57 /*
58  * For a given TEE @curve, return key size and LTC curve name. Also check that
59  * @algo is compatible with this curve.
60  * @curve: TEE_ECC_CURVE_NIST_P192, ...
61  * @algo: TEE_ALG_ECDSA_P192, ...
62  */
63 static TEE_Result ecc_get_curve_info(uint32_t curve, uint32_t algo,
64 				     size_t *key_size_bytes,
65 				     size_t *key_size_bits,
66 				     const char **curve_name)
67 {
68 	size_t size_bytes = 0;
69 	size_t size_bits = 0;
70 	const char *name = NULL;
71 
72 	/*
73 	 * Excerpt of libtomcrypt documentation:
74 	 * ecc_make_key(... key_size ...): The keysize is the size of the
75 	 * modulus in bytes desired. Currently directly supported values
76 	 * are 12, 16, 20, 24, 28, 32, 48, and 65 bytes which correspond
77 	 * to key sizes of 112, 128, 160, 192, 224, 256, 384, and 521 bits
78 	 * respectively.
79 	 */
80 
81 	/*
82 	 * Note GPv1.1 indicates TEE_ALG_ECDH_NIST_P192_DERIVE_SHARED_SECRET
83 	 * but defines TEE_ALG_ECDH_P192
84 	 */
85 
86 	switch (curve) {
87 	case TEE_ECC_CURVE_NIST_P192:
88 		size_bits = 192;
89 		size_bytes = 24;
90 		name = "NISTP192";
91 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P192) &&
92 		    (algo != TEE_ALG_ECDH_P192))
93 			return TEE_ERROR_BAD_PARAMETERS;
94 		break;
95 	case TEE_ECC_CURVE_NIST_P224:
96 		size_bits = 224;
97 		size_bytes = 28;
98 		name = "NISTP224";
99 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P224) &&
100 		    (algo != TEE_ALG_ECDH_P224))
101 			return TEE_ERROR_BAD_PARAMETERS;
102 		break;
103 	case TEE_ECC_CURVE_NIST_P256:
104 		size_bits = 256;
105 		size_bytes = 32;
106 		name = "NISTP256";
107 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P256) &&
108 		    (algo != TEE_ALG_ECDH_P256))
109 			return TEE_ERROR_BAD_PARAMETERS;
110 		break;
111 	case TEE_ECC_CURVE_NIST_P384:
112 		size_bits = 384;
113 		size_bytes = 48;
114 		name = "NISTP384";
115 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P384) &&
116 		    (algo != TEE_ALG_ECDH_P384))
117 			return TEE_ERROR_BAD_PARAMETERS;
118 		break;
119 	case TEE_ECC_CURVE_NIST_P521:
120 		size_bits = 521;
121 		size_bytes = 66;
122 		name = "NISTP521";
123 		if ((algo != 0) && (algo != TEE_ALG_ECDSA_P521) &&
124 		    (algo != TEE_ALG_ECDH_P521))
125 			return TEE_ERROR_BAD_PARAMETERS;
126 		break;
127 	case TEE_ECC_CURVE_SM2:
128 		size_bits = 256;
129 		size_bytes = 32;
130 		name = "SM2";
131 		if ((algo != 0) && (algo != TEE_ALG_SM2_PKE) &&
132 		    (algo != TEE_ALG_SM2_DSA_SM3) &&
133 		    (algo != TEE_ALG_SM2_KEP))
134 			return TEE_ERROR_BAD_PARAMETERS;
135 		break;
136 	default:
137 		return TEE_ERROR_NOT_SUPPORTED;
138 	}
139 
140 	if (key_size_bytes)
141 		*key_size_bytes = size_bytes;
142 	if (key_size_bits)
143 		*key_size_bits = size_bits;
144 	if (curve_name)
145 		*curve_name = name;
146 	return TEE_SUCCESS;
147 }
148 
149 TEE_Result crypto_acipher_gen_ecc_key(struct ecc_keypair *key, size_t key_size)
150 {
151 	TEE_Result res;
152 	ecc_key ltc_tmp_key;
153 	int ltc_res;
154 	size_t key_size_bytes = 0;
155 	size_t key_size_bits = 0;
156 
157 	res = ecc_get_curve_info(key->curve, 0, &key_size_bytes, &key_size_bits,
158 				 NULL);
159 	if (res != TEE_SUCCESS)
160 		return res;
161 
162 	if (key_size != key_size_bits)
163 		return TEE_ERROR_BAD_PARAMETERS;
164 
165 	/* Generate the ECC key */
166 	ltc_res = ecc_make_key(NULL, find_prng("prng_crypto"),
167 			       key_size_bytes, &ltc_tmp_key);
168 	if (ltc_res != CRYPT_OK)
169 		return TEE_ERROR_BAD_PARAMETERS;
170 
171 	/* check the size of the keys */
172 	if (((size_t)mp_count_bits(ltc_tmp_key.pubkey.x) > key_size_bits) ||
173 	    ((size_t)mp_count_bits(ltc_tmp_key.pubkey.y) > key_size_bits) ||
174 	    ((size_t)mp_count_bits(ltc_tmp_key.k) > key_size_bits)) {
175 		res = TEE_ERROR_BAD_PARAMETERS;
176 		goto exit;
177 	}
178 
179 	/* check LTC is returning z==1 */
180 	if (mp_count_bits(ltc_tmp_key.pubkey.z) != 1) {
181 		res = TEE_ERROR_BAD_PARAMETERS;
182 		goto exit;
183 	}
184 
185 	/* Copy the key */
186 	ltc_mp.copy(ltc_tmp_key.k, key->d);
187 	ltc_mp.copy(ltc_tmp_key.pubkey.x, key->x);
188 	ltc_mp.copy(ltc_tmp_key.pubkey.y, key->y);
189 
190 	res = TEE_SUCCESS;
191 
192 exit:
193 	ecc_free(&ltc_tmp_key);		/* Free the temporary key */
194 	return res;
195 }
196 
197 /* Note: this function clears the key before setting the curve */
198 static TEE_Result ecc_set_curve_from_name(ecc_key *ltc_key,
199 					  const char *curve_name)
200 {
201 	const ltc_ecc_curve *curve = NULL;
202 	int ltc_res = 0;
203 
204 	ltc_res = ecc_find_curve(curve_name, &curve);
205 	if (ltc_res != CRYPT_OK)
206 		return TEE_ERROR_NOT_SUPPORTED;
207 
208 	ltc_res = ecc_set_curve(curve, ltc_key);
209 	if (ltc_res != CRYPT_OK)
210 		return TEE_ERROR_GENERIC;
211 
212 	return TEE_SUCCESS;
213 }
214 
215 /*
216  * Given a keypair "key", populate the Libtomcrypt private key "ltc_key"
217  * It also returns the key size, in bytes
218  */
219 TEE_Result ecc_populate_ltc_private_key(ecc_key *ltc_key,
220 					struct ecc_keypair *key,
221 					uint32_t algo, size_t *key_size_bytes)
222 {
223 	TEE_Result res = TEE_ERROR_GENERIC;
224 	const char *name = NULL;
225 
226 	res = ecc_get_curve_info(key->curve, algo, key_size_bytes, NULL, &name);
227 	if (res)
228 		return res;
229 
230 	memset(ltc_key, 0, sizeof(*ltc_key));
231 
232 	res = ecc_set_curve_from_name(ltc_key, name);
233 	if (res)
234 		return res;
235 
236 	ltc_key->type = PK_PRIVATE;
237 	mp_copy(key->d, ltc_key->k);
238 	mp_copy(key->x, ltc_key->pubkey.x);
239 	mp_copy(key->y, ltc_key->pubkey.y);
240 	mp_set_int(ltc_key->pubkey.z, 1);
241 
242 	return TEE_SUCCESS;
243 }
244 
245 /*
246  * Given a public "key", populate the Libtomcrypt public key "ltc_key"
247  * It also returns the key size, in bytes
248  */
249 TEE_Result ecc_populate_ltc_public_key(ecc_key *ltc_key,
250 				       struct ecc_public_key *key,
251 				       uint32_t algo, size_t *key_size_bytes)
252 {
253 	TEE_Result res = TEE_ERROR_GENERIC;
254 	const char *name = NULL;
255 	uint8_t one[1] = { 1 };
256 
257 	res = ecc_get_curve_info(key->curve, algo, key_size_bytes, NULL, &name);
258 	if (res)
259 		return res;
260 
261 	memset(ltc_key, 0, sizeof(*ltc_key));
262 
263 	res = ecc_set_curve_from_name(ltc_key, name);
264 	if (res)
265 		return res;
266 
267 	ltc_key->type = PK_PUBLIC;
268 
269 	mp_copy(key->x, ltc_key->pubkey.x);
270 	mp_copy(key->y, ltc_key->pubkey.y);
271 	mp_read_unsigned_bin(ltc_key->pubkey.z, one, sizeof(one));
272 
273 	return TEE_SUCCESS;
274 }
275 
276 TEE_Result crypto_acipher_ecc_sign(uint32_t algo, struct ecc_keypair *key,
277 				   const uint8_t *msg, size_t msg_len,
278 				   uint8_t *sig, size_t *sig_len)
279 {
280 	TEE_Result res = TEE_ERROR_GENERIC;
281 	int ltc_res = 0;
282 	size_t key_size_bytes = 0;
283 	ecc_key ltc_key = { };
284 	unsigned long ltc_sig_len = 0;
285 
286 	if (algo == 0)
287 		return TEE_ERROR_BAD_PARAMETERS;
288 
289 	res = ecc_populate_ltc_private_key(&ltc_key, key, algo,
290 					   &key_size_bytes);
291 	if (res != TEE_SUCCESS)
292 		return res;
293 
294 	if (*sig_len < 2 * key_size_bytes) {
295 		*sig_len = 2 * key_size_bytes;
296 		res = TEE_ERROR_SHORT_BUFFER;
297 		goto out;
298 	}
299 
300 	ltc_sig_len = *sig_len;
301 	ltc_res = ecc_sign_hash_rfc7518(msg, msg_len, sig, &ltc_sig_len,
302 				    NULL, find_prng("prng_crypto"), &ltc_key);
303 	if (ltc_res == CRYPT_OK) {
304 		res = TEE_SUCCESS;
305 	} else {
306 		res = TEE_ERROR_GENERIC;
307 	}
308 	*sig_len = ltc_sig_len;
309 
310 out:
311 	ecc_free(&ltc_key);
312 	return res;
313 }
314 
315 TEE_Result crypto_acipher_ecc_verify(uint32_t algo, struct ecc_public_key *key,
316 				     const uint8_t *msg, size_t msg_len,
317 				     const uint8_t *sig, size_t sig_len)
318 {
319 	TEE_Result res = TEE_ERROR_GENERIC;
320 	int ltc_stat = 0;
321 	int ltc_res = 0;
322 	size_t key_size_bytes = 0;
323 	ecc_key ltc_key = { };
324 
325 	if (algo == 0)
326 		return TEE_ERROR_BAD_PARAMETERS;
327 
328 	res = ecc_populate_ltc_public_key(&ltc_key, key, algo, &key_size_bytes);
329 	if (res != TEE_SUCCESS)
330 		goto out;
331 
332 	/* check keysize vs sig_len */
333 	if ((key_size_bytes * 2) != sig_len) {
334 		res = TEE_ERROR_BAD_PARAMETERS;
335 		goto out;
336 	}
337 
338 	ltc_res = ecc_verify_hash_rfc7518(sig, sig_len, msg, msg_len, &ltc_stat,
339 					  &ltc_key);
340 	res = convert_ltc_verify_status(ltc_res, ltc_stat);
341 out:
342 	ecc_free(&ltc_key);
343 	return res;
344 }
345 
346 TEE_Result crypto_acipher_ecc_shared_secret(struct ecc_keypair *private_key,
347 					    struct ecc_public_key *public_key,
348 					    void *secret,
349 					    unsigned long *secret_len)
350 {
351 	TEE_Result res = TEE_ERROR_GENERIC;
352 	int ltc_res = 0;
353 	ecc_key ltc_private_key = { };
354 	ecc_key ltc_public_key = { };
355 	size_t key_size_bytes = 0;
356 
357 	/* Check the curves are the same */
358 	if (private_key->curve != public_key->curve)
359 		return TEE_ERROR_BAD_PARAMETERS;
360 
361 	res = ecc_populate_ltc_private_key(&ltc_private_key, private_key,
362 					   0, &key_size_bytes);
363 	if (res != TEE_SUCCESS)
364 		goto out;
365 	res = ecc_populate_ltc_public_key(&ltc_public_key, public_key,
366 					  0, &key_size_bytes);
367 	if (res != TEE_SUCCESS)
368 		goto out;
369 
370 	ltc_res = ecc_shared_secret(&ltc_private_key, &ltc_public_key,
371 				    secret, secret_len);
372 	if (ltc_res == CRYPT_OK)
373 		res = TEE_SUCCESS;
374 	else
375 		res = TEE_ERROR_BAD_PARAMETERS;
376 
377 out:
378 	ecc_free(&ltc_private_key);
379 	ecc_free(&ltc_public_key);
380 	return res;
381 }
382