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 <config.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 #include "sm2-dsa.h"
21 #include "sm2-pke.h"
22
23 /* Translate mbedtls result to TEE result */
get_tee_result(int lmd_res)24 static TEE_Result get_tee_result(int lmd_res)
25 {
26 switch (lmd_res) {
27 case 0:
28 return TEE_SUCCESS;
29 case MBEDTLS_ERR_ECP_VERIFY_FAILED:
30 return TEE_ERROR_SIGNATURE_INVALID;
31 case MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL:
32 return TEE_ERROR_SHORT_BUFFER;
33 default:
34 return TEE_ERROR_BAD_STATE;
35 }
36 }
37
ecc_free_public_key(struct ecc_public_key * s)38 static void ecc_free_public_key(struct ecc_public_key *s)
39 {
40 if (!s)
41 return;
42
43 crypto_bignum_free(s->x);
44 crypto_bignum_free(s->y);
45 }
46
47 /*
48 * curve is part of TEE_ECC_CURVE_NIST_P192,...
49 * algo is part of TEE_ALG_ECDSA_P192,..., and 0 if we do not have it
50 */
ecc_get_keysize(uint32_t curve,uint32_t algo,size_t * key_size_bytes,size_t * key_size_bits)51 static TEE_Result ecc_get_keysize(uint32_t curve, uint32_t algo,
52 size_t *key_size_bytes, size_t *key_size_bits)
53 {
54 /*
55 * Note GPv1.1 indicates TEE_ALG_ECDH_NIST_P192_DERIVE_SHARED_SECRET
56 * but defines TEE_ALG_ECDH_P192
57 */
58 switch (curve) {
59 case TEE_ECC_CURVE_NIST_P192:
60 *key_size_bits = 192;
61 *key_size_bytes = 24;
62 if ((algo != 0) && (algo != TEE_ALG_ECDSA_P192) &&
63 (algo != TEE_ALG_ECDH_P192))
64 return TEE_ERROR_BAD_PARAMETERS;
65 break;
66 case TEE_ECC_CURVE_NIST_P224:
67 *key_size_bits = 224;
68 *key_size_bytes = 28;
69 if ((algo != 0) && (algo != TEE_ALG_ECDSA_P224) &&
70 (algo != TEE_ALG_ECDH_P224))
71 return TEE_ERROR_BAD_PARAMETERS;
72 break;
73 case TEE_ECC_CURVE_NIST_P256:
74 *key_size_bits = 256;
75 *key_size_bytes = 32;
76 if ((algo != 0) && (algo != TEE_ALG_ECDSA_P256) &&
77 (algo != TEE_ALG_ECDH_P256))
78 return TEE_ERROR_BAD_PARAMETERS;
79 break;
80 case TEE_ECC_CURVE_NIST_P384:
81 *key_size_bits = 384;
82 *key_size_bytes = 48;
83 if ((algo != 0) && (algo != TEE_ALG_ECDSA_P384) &&
84 (algo != TEE_ALG_ECDH_P384))
85 return TEE_ERROR_BAD_PARAMETERS;
86 break;
87 case TEE_ECC_CURVE_NIST_P521:
88 *key_size_bits = 521;
89 *key_size_bytes = 66;
90 if ((algo != 0) && (algo != TEE_ALG_ECDSA_P521) &&
91 (algo != TEE_ALG_ECDH_P521))
92 return TEE_ERROR_BAD_PARAMETERS;
93 break;
94 case TEE_ECC_CURVE_SM2:
95 *key_size_bits = 256;
96 *key_size_bytes = 32;
97 if (algo != 0 && algo != TEE_ALG_SM2_DSA_SM3 &&
98 algo != TEE_ALG_SM2_KEP && algo != TEE_ALG_SM2_PKE)
99 return TEE_ERROR_BAD_PARAMETERS;
100 break;
101 default:
102 *key_size_bits = 0;
103 *key_size_bytes = 0;
104 return TEE_ERROR_NOT_SUPPORTED;
105 }
106
107 return TEE_SUCCESS;
108 }
109
110 /*
111 * Clear some memory that was used to prepare the context
112 */
ecc_clear_precomputed(mbedtls_ecp_group * grp)113 static void ecc_clear_precomputed(mbedtls_ecp_group *grp)
114 {
115 size_t i = 0;
116
117 if (grp->T) {
118 for (i = 0; i < grp->T_size; i++)
119 mbedtls_ecp_point_free(&grp->T[i]);
120 free(grp->T);
121 }
122 grp->T = NULL;
123 grp->T_size = 0;
124 }
125
curve_to_group_id(uint32_t curve)126 static mbedtls_ecp_group_id curve_to_group_id(uint32_t curve)
127 {
128 switch (curve) {
129 case TEE_ECC_CURVE_NIST_P192:
130 return MBEDTLS_ECP_DP_SECP192R1;
131 case TEE_ECC_CURVE_NIST_P224:
132 return MBEDTLS_ECP_DP_SECP224R1;
133 case TEE_ECC_CURVE_NIST_P256:
134 return MBEDTLS_ECP_DP_SECP256R1;
135 case TEE_ECC_CURVE_NIST_P384:
136 return MBEDTLS_ECP_DP_SECP384R1;
137 case TEE_ECC_CURVE_NIST_P521:
138 return MBEDTLS_ECP_DP_SECP521R1;
139 case TEE_ECC_CURVE_SM2:
140 return MBEDTLS_ECP_DP_SM2;
141 default:
142 return MBEDTLS_ECP_DP_NONE;
143 }
144 }
145
ecc_generate_keypair(struct ecc_keypair * key,size_t key_size)146 static TEE_Result ecc_generate_keypair(struct ecc_keypair *key, size_t key_size)
147 {
148 TEE_Result res = TEE_SUCCESS;
149 int lmd_res = 0;
150 mbedtls_ecdsa_context ecdsa;
151 mbedtls_ecp_group_id gid;
152 size_t key_size_bytes = 0;
153 size_t key_size_bits = 0;
154
155 memset(&ecdsa, 0, sizeof(ecdsa));
156 memset(&gid, 0, sizeof(gid));
157
158 res = ecc_get_keysize(key->curve, 0, &key_size_bytes, &key_size_bits);
159 if (res != TEE_SUCCESS)
160 return res;
161
162 if (key_size != key_size_bits)
163 return TEE_ERROR_BAD_PARAMETERS;
164
165 mbedtls_ecdsa_init(&ecdsa);
166
167 /* Generate the ECC key */
168 gid = curve_to_group_id(key->curve);
169 lmd_res = mbedtls_ecdsa_genkey(&ecdsa, gid, mbd_rand, NULL);
170 if (lmd_res != 0) {
171 res = TEE_ERROR_BAD_PARAMETERS;
172 FMSG("mbedtls_ecdsa_genkey failed.");
173 goto exit;
174 }
175 ecc_clear_precomputed(&ecdsa.grp);
176
177 /* check the size of the keys */
178 if ((mbedtls_mpi_bitlen(&ecdsa.Q.X) > key_size_bits) ||
179 (mbedtls_mpi_bitlen(&ecdsa.Q.Y) > key_size_bits) ||
180 (mbedtls_mpi_bitlen(&ecdsa.d) > key_size_bits)) {
181 res = TEE_ERROR_BAD_PARAMETERS;
182 FMSG("Check the size of the keys failed.");
183 goto exit;
184 }
185
186 /* check LMD is returning z==1 */
187 if (mbedtls_mpi_bitlen(&ecdsa.Q.Z) != 1) {
188 res = TEE_ERROR_BAD_PARAMETERS;
189 FMSG("Check LMD failed.");
190 goto exit;
191 }
192
193 /* Copy the key */
194 crypto_bignum_copy(key->d, (void *)&ecdsa.d);
195 crypto_bignum_copy(key->x, (void *)&ecdsa.Q.X);
196 crypto_bignum_copy(key->y, (void *)&ecdsa.Q.Y);
197
198 res = TEE_SUCCESS;
199 exit:
200 mbedtls_ecdsa_free(&ecdsa); /* Free the temporary key */
201 return res;
202 }
203
ecc_sign(uint32_t algo,struct ecc_keypair * key,const uint8_t * msg,size_t msg_len,uint8_t * sig,size_t * sig_len)204 static TEE_Result ecc_sign(uint32_t algo, struct ecc_keypair *key,
205 const uint8_t *msg, size_t msg_len, uint8_t *sig,
206 size_t *sig_len)
207 {
208 TEE_Result res = TEE_SUCCESS;
209 int lmd_res = 0;
210 const mbedtls_pk_info_t *pk_info = NULL;
211 mbedtls_ecdsa_context ecdsa;
212 mbedtls_ecp_group_id gid;
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(&gid, 0, sizeof(gid));
220 memset(&r, 0, sizeof(r));
221 memset(&s, 0, sizeof(s));
222
223 if (algo == 0)
224 return TEE_ERROR_BAD_PARAMETERS;
225
226 mbedtls_mpi_init(&r);
227 mbedtls_mpi_init(&s);
228
229 mbedtls_ecdsa_init(&ecdsa);
230
231 gid = curve_to_group_id(key->curve);
232 lmd_res = mbedtls_ecp_group_load(&ecdsa.grp, gid);
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 if (*sig_len < 2 * key_size_bytes) {
246 *sig_len = 2 * key_size_bytes;
247 res = TEE_ERROR_SHORT_BUFFER;
248 goto out;
249 }
250
251 pk_info = mbedtls_pk_info_from_type(MBEDTLS_PK_ECDSA);
252 if (pk_info == NULL) {
253 res = TEE_ERROR_NOT_SUPPORTED;
254 goto out;
255 }
256
257 lmd_res = mbedtls_ecdsa_sign(&ecdsa.grp, &r, &s, &ecdsa.d, msg,
258 msg_len, mbd_rand, NULL);
259 if (lmd_res == 0) {
260 *sig_len = 2 * key_size_bytes;
261 memset(sig, 0, *sig_len);
262 mbedtls_mpi_write_binary(&r, sig + *sig_len / 2 -
263 mbedtls_mpi_size(&r),
264 mbedtls_mpi_size(&r));
265
266 mbedtls_mpi_write_binary(&s, sig + *sig_len -
267 mbedtls_mpi_size(&s),
268 mbedtls_mpi_size(&s));
269 res = TEE_SUCCESS;
270 } else {
271 FMSG("mbedtls_ecdsa_sign failed, returned 0x%x\n", -lmd_res);
272 res = TEE_ERROR_GENERIC;
273 }
274 out:
275 mbedtls_mpi_free(&r);
276 mbedtls_mpi_free(&s);
277 /* Reset mpi to skip freeing here, those mpis will be freed with key */
278 mbedtls_mpi_init(&ecdsa.d);
279 mbedtls_ecdsa_free(&ecdsa);
280 return res;
281 }
282
ecc_verify(uint32_t algo,struct ecc_public_key * key,const uint8_t * msg,size_t msg_len,const uint8_t * sig,size_t sig_len)283 static TEE_Result ecc_verify(uint32_t algo, struct ecc_public_key *key,
284 const uint8_t *msg, size_t msg_len,
285 const uint8_t *sig, size_t sig_len)
286 {
287 TEE_Result res = TEE_SUCCESS;
288 int lmd_res = 0;
289 mbedtls_ecdsa_context ecdsa;
290 mbedtls_ecp_group_id gid;
291 size_t key_size_bytes, key_size_bits = 0;
292 uint8_t one[1] = { 1 };
293 mbedtls_mpi r;
294 mbedtls_mpi s;
295
296 memset(&ecdsa, 0, sizeof(ecdsa));
297 memset(&gid, 0, sizeof(gid));
298 memset(&r, 0, sizeof(r));
299 memset(&s, 0, sizeof(s));
300
301 if (algo == 0)
302 return TEE_ERROR_BAD_PARAMETERS;
303
304 mbedtls_mpi_init(&r);
305 mbedtls_mpi_init(&s);
306
307 mbedtls_ecdsa_init(&ecdsa);
308
309 gid = curve_to_group_id(key->curve);
310 lmd_res = mbedtls_ecp_group_load(&ecdsa.grp, gid);
311 if (lmd_res != 0) {
312 res = TEE_ERROR_NOT_SUPPORTED;
313 goto out;
314 }
315
316 ecdsa.Q.X = *(mbedtls_mpi *)key->x;
317 ecdsa.Q.Y = *(mbedtls_mpi *)key->y;
318 mbedtls_mpi_read_binary(&ecdsa.Q.Z, one, sizeof(one));
319
320 res = ecc_get_keysize(key->curve, algo,
321 &key_size_bytes, &key_size_bits);
322 if (res != TEE_SUCCESS) {
323 res = TEE_ERROR_BAD_PARAMETERS;
324 goto out;
325 }
326
327 /* check keysize vs sig_len */
328 if ((key_size_bytes * 2) != sig_len) {
329 res = TEE_ERROR_BAD_PARAMETERS;
330 goto out;
331 }
332
333 mbedtls_mpi_read_binary(&r, sig, sig_len / 2);
334 mbedtls_mpi_read_binary(&s, sig + sig_len / 2, sig_len / 2);
335
336 lmd_res = mbedtls_ecdsa_verify(&ecdsa.grp, msg, msg_len, &ecdsa.Q,
337 &r, &s);
338 if (lmd_res != 0) {
339 FMSG("mbedtls_ecdsa_verify failed, returned 0x%x", -lmd_res);
340 res = get_tee_result(lmd_res);
341 }
342 out:
343 mbedtls_mpi_free(&r);
344 mbedtls_mpi_free(&s);
345 /* Reset mpi to skip freeing here, those mpis will be freed with key */
346 mbedtls_mpi_init(&ecdsa.Q.X);
347 mbedtls_mpi_init(&ecdsa.Q.Y);
348 mbedtls_ecdsa_free(&ecdsa);
349 return res;
350 }
351
ecc_shared_secret(struct ecc_keypair * private_key,struct ecc_public_key * public_key,void * secret,unsigned long * secret_len)352 static TEE_Result ecc_shared_secret(struct ecc_keypair *private_key,
353 struct ecc_public_key *public_key,
354 void *secret, unsigned long *secret_len)
355 {
356 TEE_Result res = TEE_SUCCESS;
357 int lmd_res = 0;
358 uint8_t one[1] = { 1 };
359 mbedtls_ecdh_context ecdh;
360 mbedtls_ecp_group_id gid;
361 size_t out_len = 0;
362
363 memset(&ecdh, 0, sizeof(ecdh));
364 memset(&gid, 0, sizeof(gid));
365 mbedtls_ecdh_init(&ecdh);
366 gid = curve_to_group_id(private_key->curve);
367 lmd_res = mbedtls_ecp_group_load(&ecdh.grp, gid);
368 if (lmd_res != 0) {
369 res = TEE_ERROR_NOT_SUPPORTED;
370 goto out;
371 }
372
373 ecdh.d = *(mbedtls_mpi *)private_key->d;
374 ecdh.Qp.X = *(mbedtls_mpi *)public_key->x;
375 ecdh.Qp.Y = *(mbedtls_mpi *)public_key->y;
376 mbedtls_mpi_read_binary(&ecdh.Qp.Z, one, sizeof(one));
377
378 lmd_res = mbedtls_ecdh_calc_secret(&ecdh, &out_len, secret,
379 *secret_len, mbd_rand, NULL);
380 if (lmd_res != 0) {
381 res = get_tee_result(lmd_res);
382 goto out;
383 }
384 *secret_len = out_len;
385 out:
386 /* Reset mpi to skip freeing here, those mpis will be freed with key */
387 mbedtls_mpi_init(&ecdh.d);
388 mbedtls_mpi_init(&ecdh.Qp.X);
389 mbedtls_mpi_init(&ecdh.Qp.Y);
390 mbedtls_ecdh_free(&ecdh);
391 return res;
392 }
393
394 static const struct crypto_ecc_keypair_ops ecc_keypair_ops = {
395 .generate = ecc_generate_keypair,
396 .sign = ecc_sign,
397 .shared_secret = ecc_shared_secret,
398 };
399
400 static const struct crypto_ecc_keypair_ops sm2_pke_keypair_ops = {
401 .generate = ecc_generate_keypair,
402 .decrypt = sm2_mbedtls_pke_decrypt,
403 };
404
405 static const struct crypto_ecc_keypair_ops sm2_kep_keypair_ops = {
406 .generate = ecc_generate_keypair,
407 };
408
409 static const struct crypto_ecc_keypair_ops sm2_dsa_keypair_ops = {
410 .generate = ecc_generate_keypair,
411 .sign = sm2_mbedtls_dsa_sign,
412 };
413
414 const struct crypto_ecc_keypair_ops *
crypto_asym_get_ecc_keypair_ops(uint32_t key_type)415 crypto_asym_get_ecc_keypair_ops(uint32_t key_type)
416 {
417 switch (key_type) {
418 case TEE_TYPE_ECDSA_KEYPAIR:
419 case TEE_TYPE_ECDH_KEYPAIR:
420 return &ecc_keypair_ops;
421 case TEE_TYPE_SM2_DSA_KEYPAIR:
422 if (!IS_ENABLED(CFG_CRYPTO_SM2_DSA))
423 return NULL;
424 return &sm2_dsa_keypair_ops;
425 case TEE_TYPE_SM2_PKE_KEYPAIR:
426 if (!IS_ENABLED(CFG_CRYPTO_SM2_PKE))
427 return NULL;
428 return &sm2_pke_keypair_ops;
429 case TEE_TYPE_SM2_KEP_KEYPAIR:
430 if (!IS_ENABLED(CFG_CRYPTO_SM2_KEP))
431 return NULL;
432 return &sm2_kep_keypair_ops;
433 default:
434 return NULL;
435 }
436 }
437
crypto_asym_alloc_ecc_keypair(struct ecc_keypair * s,uint32_t key_type,size_t key_size_bits)438 TEE_Result crypto_asym_alloc_ecc_keypair(struct ecc_keypair *s,
439 uint32_t key_type,
440 size_t key_size_bits)
441 {
442 memset(s, 0, sizeof(*s));
443
444 switch (key_type) {
445 case TEE_TYPE_ECDSA_KEYPAIR:
446 case TEE_TYPE_ECDH_KEYPAIR:
447 s->ops = &ecc_keypair_ops;
448 break;
449 case TEE_TYPE_SM2_DSA_KEYPAIR:
450 if (!IS_ENABLED(CFG_CRYPTO_SM2_DSA))
451 return TEE_ERROR_NOT_IMPLEMENTED;
452
453 s->curve = TEE_ECC_CURVE_SM2;
454 s->ops = &sm2_dsa_keypair_ops;
455 break;
456 case TEE_TYPE_SM2_PKE_KEYPAIR:
457 if (!IS_ENABLED(CFG_CRYPTO_SM2_PKE))
458 return TEE_ERROR_NOT_IMPLEMENTED;
459
460 s->curve = TEE_ECC_CURVE_SM2;
461 s->ops = &sm2_pke_keypair_ops;
462 break;
463 case TEE_TYPE_SM2_KEP_KEYPAIR:
464 if (!IS_ENABLED(CFG_CRYPTO_SM2_KEP))
465 return TEE_ERROR_NOT_IMPLEMENTED;
466
467 s->curve = TEE_ECC_CURVE_SM2;
468 s->ops = &sm2_kep_keypair_ops;
469 break;
470 default:
471 return TEE_ERROR_NOT_IMPLEMENTED;
472 }
473
474 s->d = crypto_bignum_allocate(key_size_bits);
475 if (!s->d)
476 goto err;
477 s->x = crypto_bignum_allocate(key_size_bits);
478 if (!s->x)
479 goto err;
480 s->y = crypto_bignum_allocate(key_size_bits);
481 if (!s->y)
482 goto err;
483
484 return TEE_SUCCESS;
485
486 err:
487 crypto_bignum_free(s->d);
488 crypto_bignum_free(s->x);
489
490 return TEE_ERROR_OUT_OF_MEMORY;
491 }
492
493 static const struct crypto_ecc_public_ops ecc_public_key_ops = {
494 .free = ecc_free_public_key,
495 .verify = ecc_verify,
496 };
497
498 static const struct crypto_ecc_public_ops sm2_pke_public_key_ops = {
499 .free = ecc_free_public_key,
500 .encrypt = sm2_mbedtls_pke_encrypt,
501 };
502
503 static const struct crypto_ecc_public_ops sm2_kep_public_key_ops = {
504 .free = ecc_free_public_key,
505 };
506
507 static const struct crypto_ecc_public_ops sm2_dsa_public_key_ops = {
508 .free = ecc_free_public_key,
509 .verify = sm2_mbedtls_dsa_verify,
510 };
511
512 const struct crypto_ecc_public_ops*
crypto_asym_get_ecc_public_ops(uint32_t key_type)513 crypto_asym_get_ecc_public_ops(uint32_t key_type)
514 {
515 switch (key_type) {
516 case TEE_TYPE_ECDSA_PUBLIC_KEY:
517 case TEE_TYPE_ECDH_PUBLIC_KEY:
518 return &ecc_public_key_ops;
519 case TEE_TYPE_SM2_DSA_PUBLIC_KEY:
520 if (!IS_ENABLED(CFG_CRYPTO_SM2_DSA))
521 return NULL;
522
523 return &sm2_dsa_public_key_ops;
524 case TEE_TYPE_SM2_PKE_PUBLIC_KEY:
525 if (!IS_ENABLED(CFG_CRYPTO_SM2_PKE))
526 return NULL;
527
528 return &sm2_pke_public_key_ops;
529 case TEE_TYPE_SM2_KEP_PUBLIC_KEY:
530 if (!IS_ENABLED(CFG_CRYPTO_SM2_KEP))
531 return NULL;
532 return &sm2_kep_public_key_ops;
533 default:
534 return NULL;
535 }
536 }
537
crypto_asym_alloc_ecc_public_key(struct ecc_public_key * s,uint32_t key_type,size_t key_size_bits)538 TEE_Result crypto_asym_alloc_ecc_public_key(struct ecc_public_key *s,
539 uint32_t key_type,
540 size_t key_size_bits)
541 {
542 memset(s, 0, sizeof(*s));
543
544 switch (key_type) {
545 case TEE_TYPE_ECDSA_PUBLIC_KEY:
546 case TEE_TYPE_ECDH_PUBLIC_KEY:
547 s->ops = &ecc_public_key_ops;
548 break;
549 case TEE_TYPE_SM2_DSA_PUBLIC_KEY:
550 if (!IS_ENABLED(CFG_CRYPTO_SM2_DSA))
551 return TEE_ERROR_NOT_IMPLEMENTED;
552
553 s->curve = TEE_ECC_CURVE_SM2;
554 s->ops = &sm2_dsa_public_key_ops;
555 break;
556 case TEE_TYPE_SM2_PKE_PUBLIC_KEY:
557 if (!IS_ENABLED(CFG_CRYPTO_SM2_PKE))
558 return TEE_ERROR_NOT_IMPLEMENTED;
559
560 s->curve = TEE_ECC_CURVE_SM2;
561 s->ops = &sm2_pke_public_key_ops;
562 break;
563 case TEE_TYPE_SM2_KEP_PUBLIC_KEY:
564 if (!IS_ENABLED(CFG_CRYPTO_SM2_KEP))
565 return TEE_ERROR_NOT_IMPLEMENTED;
566
567 s->curve = TEE_ECC_CURVE_SM2;
568 s->ops = &sm2_kep_public_key_ops;
569 break;
570 default:
571 return TEE_ERROR_NOT_IMPLEMENTED;
572 }
573
574 s->x = crypto_bignum_allocate(key_size_bits);
575 if (!s->x)
576 goto err;
577 s->y = crypto_bignum_allocate(key_size_bits);
578 if (!s->y)
579 goto err;
580
581 return TEE_SUCCESS;
582
583 err:
584 crypto_bignum_free(s->x);
585
586 return TEE_ERROR_OUT_OF_MEMORY;
587 }
588