xref: /freebsd/crypto/libecc/src/tests/ec_self_tests_core.c (revision f0865ec9906d5a18fa2a3b61381f22ce16e606ad)
1 /*
2  *  Copyright (C) 2017 - This file is part of libecc project
3  *
4  *  Authors:
5  *      Ryad BENADJILA <ryadbenadjila@gmail.com>
6  *      Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr>
7  *      Jean-Pierre FLORI <jean-pierre.flori@ssi.gouv.fr>
8  *
9  *  Contributors:
10  *      Nicolas VIVET <nicolas.vivet@ssi.gouv.fr>
11  *      Karim KHALFALLAH <karim.khalfallah@ssi.gouv.fr>
12  *
13  *  This software is licensed under a dual BSD and GPL v2 license.
14  *  See LICENSE file at the root folder of the project.
15  */
16 #include <libecc/utils/utils.h>
17 #include <libecc/external_deps/rand.h>
18 #include <libecc/external_deps/time.h>
19 #include <libecc/external_deps/print.h>
20 #include "ec_self_tests_core.h"
21 
22 /* Parallelize self tests? */
23 #ifdef WITH_OPENMP_SELF_TESTS
24 /* No openmp without stdlib ... */
25 #ifndef WITH_STDLIB
26 #error "Sorry: no possible self tests parallelization (OpenMP) without stdlib! Please use WITH_STDLIB"
27 #endif
28 #include <omp.h>
29 #include <stdlib.h>
30 static omp_lock_t global_lock;
31 static volatile u8 global_lock_initialized = 0;
32 #define OPENMP_LOCK() do {					  \
33 	if(!global_lock_initialized){				  \
34 		omp_init_lock(&global_lock);			  \
35 		global_lock_initialized = 1;			  \
36 	}							  \
37 	omp_set_lock(&global_lock);				  \
38 } while(0)
39 #define OPENMP_UNLOCK() do {					  \
40 	omp_unset_lock(&global_lock);				  \
41 } while(0)
42 #define OPENMP_EG(ret, err) do {								\
43 	if(ret){										\
44 		ext_printf("OpenMP abort following error ...  %s:%d\n", __FILE__, __LINE__);	\
45 		exit(-1);									\
46 	}											\
47 } while(0)
48 #else
49 #define OPENMP_LOCK()
50 #define OPENMP_UNLOCK()
51 #define OPENMP_EG(ret, err) do {				  \
52 	EG(ret, err);						  \
53 } while(0)
54 #endif
55 
ec_gen_import_export_kp(ec_key_pair * kp,const ec_params * params,const ec_test_case * c)56 ATTRIBUTE_WARN_UNUSED_RET static int ec_gen_import_export_kp(ec_key_pair *kp, const ec_params *params,
57 				   const ec_test_case *c)
58 {
59 	u8 pub_key_buf[EC_STRUCTURED_PUB_KEY_MAX_EXPORT_SIZE];
60 	u8 priv_key_buf[EC_STRUCTURED_PRIV_KEY_MAX_EXPORT_SIZE];
61 	u8 pub_key_buf_len, priv_key_buf_len;
62 	ec_key_pair imported_kp;
63 	int ret;
64 
65 	MUST_HAVE(c != NULL, ret, err);
66 
67 	ret = local_memset(pub_key_buf, 0, sizeof(pub_key_buf)); EG(ret, err);
68 	ret = local_memset(priv_key_buf, 0, sizeof(priv_key_buf)); EG(ret, err);
69 	ret = local_memset(&imported_kp, 0, sizeof(imported_kp)); EG(ret, err);
70 
71 	/* Generate key pair */
72 	ret = ec_key_pair_gen(kp, params, c->sig_type);
73 	if (ret) {
74 		ext_printf("Error generating key pair\n");
75 		goto err;
76 	}
77 	pub_key_buf_len = EC_STRUCTURED_PUB_KEY_EXPORT_SIZE(&(kp->pub_key));
78 	priv_key_buf_len = EC_STRUCTURED_PRIV_KEY_EXPORT_SIZE(&(kp->priv_key));
79 
80 	/* Export public and private keys in buffers */
81 	ret = ec_structured_pub_key_export_to_buf(&(kp->pub_key), pub_key_buf,
82 					  pub_key_buf_len);
83 	if (ret) {
84 		ext_printf("Error exporting public key\n");
85 		goto err;
86 	}
87 	ret = ec_structured_priv_key_export_to_buf(&(kp->priv_key),
88 					   priv_key_buf,
89 					   priv_key_buf_len);
90 	if (ret) {
91 		ext_printf("Error exporting private key\n");
92 		goto err;
93 	}
94 
95 	/* Import public and private key */
96 	ret = ec_structured_pub_key_import_from_buf(&(imported_kp.pub_key),
97 					    params,
98 					    pub_key_buf,
99 					    pub_key_buf_len,
100 					    c->sig_type);
101 	if (ret) {
102 		ext_printf("Error importing public key\n");
103 		goto err;
104 	}
105 	ret = ec_structured_priv_key_import_from_buf(&(imported_kp.priv_key),
106 					     params, priv_key_buf,
107 					     priv_key_buf_len,
108 					     c->sig_type);
109 	if (ret) {
110 		ext_printf("Error importing private key\n");
111 		goto err;
112 	}
113 	ret = 0;
114 
115 err:
116 	return ret;
117 }
118 
119 /* This function randomly splits the message input in small chunks to
120  * test the signature init / multiple updates / finalize mechanism for
121  * algorithms that support them.
122  */
random_split_ec_sign(u8 * sig,u8 siglen,const ec_key_pair * key_pair,const u8 * m,u32 mlen,int (* rand)(nn_t out,nn_src_t q),ec_alg_type sig_type,hash_alg_type hash_type,const u8 * adata,u16 adata_len)123 ATTRIBUTE_WARN_UNUSED_RET static int random_split_ec_sign(u8 *sig, u8 siglen, const ec_key_pair *key_pair,
124 	     const u8 *m, u32 mlen,
125 	     int (*rand) (nn_t out, nn_src_t q),
126 	     ec_alg_type sig_type, hash_alg_type hash_type, const u8 *adata, u16 adata_len)
127 {
128 	struct ec_sign_context ctx;
129 	int ret;
130 	u32 consumed;
131 
132 	ret = local_memset(&ctx, 0, sizeof(ctx)); EG(ret, err);
133 
134 	MUST_HAVE(sig != NULL, ret, err);
135 	MUST_HAVE(key_pair != NULL, ret, err);
136 	MUST_HAVE(m != NULL, ret, err);
137 	/* note: adata == NULL is allowed */
138 
139 	ret = _ec_sign_init(&ctx, key_pair, rand, sig_type, hash_type, adata, adata_len);
140 	if (ret) {
141 		goto err;
142 	}
143 	/* We randomly split the input message in chunks and proceed with updates */
144 	consumed = 0;
145 	while(consumed < mlen){
146 		u32 toconsume = 0;
147 		ret = get_random((u8 *)&toconsume, sizeof(toconsume));
148 		if (ret) {
149 			ext_printf("Error when getting random\n");
150 			goto err;
151 		}
152 		toconsume = (toconsume % (mlen - consumed));
153 		if(((mlen - consumed) == 1) && (toconsume == 0)){
154 			toconsume = 1;
155 		}
156 		ret = ec_sign_update(&ctx, &m[consumed], toconsume);
157 		if (ret) {
158 			goto err;
159 		}
160 		consumed += toconsume;
161 	}
162 
163 	ret = ec_sign_finalize(&ctx, sig, siglen);
164 
165  err:
166 	return ret;
167 }
168 
169 /* This function randomly splits the message input in small chunks to
170  * test the verification init / multiple updates / finalize mechanism for
171  * algorithms that support them.
172  */
random_split_ec_verify(const u8 * sig,u8 siglen,const ec_pub_key * pub_key,const u8 * m,u32 mlen,ec_alg_type sig_type,hash_alg_type hash_type,const u8 * adata,u16 adata_len)173 ATTRIBUTE_WARN_UNUSED_RET static int random_split_ec_verify(const u8 *sig, u8 siglen, const ec_pub_key *pub_key,
174 	      const u8 *m, u32 mlen,
175 	      ec_alg_type sig_type, hash_alg_type hash_type, const u8 *adata, u16 adata_len)
176 {
177 	int ret;
178 	struct ec_verify_context ctx;
179 	u32 consumed;
180 
181 	ret = local_memset(&ctx, 0, sizeof(ctx)); EG(ret, err);
182 
183 	ret = ec_verify_init(&ctx, pub_key, sig, siglen, sig_type, hash_type, adata, adata_len);
184 	if (ret) {
185 		goto err;
186 	}
187 
188 	/* We randomly split the input message in chunks and proceed with updates */
189 	consumed = 0;
190 	while(consumed < mlen){
191 		u32 toconsume = 0;
192 		ret = get_random((u8 *)&toconsume, sizeof(toconsume));
193 		if (ret) {
194 			ext_printf("Error when getting random\n");
195 			goto err;
196 		}
197 		toconsume = (toconsume % (mlen - consumed));
198 		if(((mlen - consumed) == 1) && (toconsume == 0)){
199 			toconsume = 1;
200 		}
201 		ret = ec_verify_update(&ctx, &m[consumed], toconsume);
202 		if (ret) {
203 			goto err;
204 		}
205 		consumed += toconsume;
206 	}
207 
208 	ret = ec_verify_finalize(&ctx);
209 
210  err:
211 	return ret;
212 }
213 
214 
215 /* Reduce pressure on the stack for small targets
216  * by letting the user override this value.
217  */
218 #ifndef MAX_MSG_LEN
219 #if WORDSIZE == 16
220 /* For wordsize 16 bits, avoid overflows */
221 #define MAX_MSG_LEN 1024
222 #else
223 #define MAX_MSG_LEN 8192
224 #endif
225 #endif
226 #ifndef MAX_BATCH_SIG_SIZE
227 #define MAX_BATCH_SIG_SIZE 20
228 #endif
229 
230 /*
231  * ECC generic self tests (sign/verify on random values
232  * with import/export)
233  */
ec_import_export_test(const ec_test_case * c)234 ATTRIBUTE_WARN_UNUSED_RET static int ec_import_export_test(const ec_test_case *c)
235 {
236 	ec_key_pair kp;
237 	ec_params params;
238 	int ret, check;
239 
240 	MUST_HAVE(c != NULL, ret, err);
241 
242 	ret = local_memset(&kp, 0, sizeof(kp)); EG(ret, err);
243 	ret = local_memset(&params, 0, sizeof(params)); EG(ret, err);
244 
245 	/* Import EC params from test case */
246 	ret = import_params(&params, c->ec_str_p);
247 	if (ret) {
248 		ext_printf("Error importing params\n");
249 		goto err;
250 	}
251 
252 	/* Generate, import/export a key pair */
253 	ret = ec_gen_import_export_kp(&kp, &params, c);
254 	if (ret) {
255 		ext_printf("Error at key pair generation/import/export\n");
256 		goto err;
257 	}
258 
259 	/* Perform test */
260 	{
261 		u16 msglen;
262 		u8 siglen;
263 		u8 msg[MAX_MSG_LEN];
264 		u8 sig[EC_MAX_SIGLEN];
265 		u8 check_type = 0;
266 		u8 sig_tmp1[EC_MAX_SIGLEN];
267 		u8 sig_tmp2[EC_MAX_SIGLEN];
268 		FORCE_USED_VAR(check_type);
269 
270 		ret = ec_get_sig_len(&params, c->sig_type, c->hash_type,
271 				     (u8 *)&siglen);
272 		if (ret) {
273 			ext_printf("Error computing effective sig size\n");
274 			goto err;
275 		}
276 
277 		/* Generate a random message to sign */
278 		ret = get_random((u8 *)&msglen, sizeof(msglen));
279 		if (ret) {
280 			ext_printf("Error when getting random\n");
281 			goto err;
282 		}
283 		msglen = msglen % MAX_MSG_LEN;
284 		ret = get_random(msg, msglen);
285 		if (ret) {
286 			ext_printf("Error when getting random\n");
287 			goto err;
288 		}
289 
290 		ret = _ec_sign(sig, siglen, &kp, msg, msglen,
291 			       c->nn_random, c->sig_type, c->hash_type, c->adata, c->adata_len);
292 		if (ret) {
293 			ext_printf("Error when signing\n");
294 			goto err;
295 		}
296 		ret = local_memset(sig_tmp1, 0, sizeof(sig_tmp1)); EG(ret, err);
297 		ret = local_memset(sig_tmp2, 0, sizeof(sig_tmp2)); EG(ret, err);
298 		/* If the algorithm supports streaming mode, test it against direct mode */
299 		ret = is_sign_streaming_mode_supported(c->sig_type, &check); EG(ret, err);
300 		if(check){
301 			MUST_HAVE(siglen <= LOCAL_MAX(sizeof(sig_tmp1), sizeof(sig_tmp2)), ret, err);
302 			ret = generic_ec_sign(sig_tmp1, siglen, &kp, msg, msglen,
303 			       c->nn_random, c->sig_type, c->hash_type, c->adata, c->adata_len);
304 			if(ret){
305 				ext_printf("Error when signing\n");
306 				ret = -1;
307 				goto err;
308 			}
309 			ret = random_split_ec_sign(sig_tmp2, siglen, &kp, msg, msglen,
310 			       c->nn_random, c->sig_type, c->hash_type, c->adata, c->adata_len);
311 			if(ret){
312 				ext_printf("Error when signing\n");
313 				ret = -1;
314 				goto err;
315 			}
316 			/* Verify signature equality only in case of deterministic signatures */
317 			ret = is_sign_deterministic(c->sig_type, &check); EG(ret, err);
318 			if(check){
319 				ret = are_equal(sig, sig_tmp1, siglen, &check); EG(ret, err);
320 				if(!check){
321 					ext_printf("Error when signing: streaming and non streaming modes results differ "\
322 						   "for deterministic signature scheme!\n");
323 					ret = -1;
324 					goto err;
325 				}
326 				ret = are_equal(sig, sig_tmp2, siglen, &check); EG(ret, err);
327 				if(!check){
328 					ext_printf("Error when signing: streaming and non streaming modes results differ "\
329 						   "for deterministic signature scheme!\n");
330 					ret = -1;
331 					goto err;
332 				}
333 			}
334 		}
335 
336 		ret = ec_verify(sig, siglen, &(kp.pub_key), msg, msglen,
337 				c->sig_type, c->hash_type, c->adata, c->adata_len);
338 		if (ret) {
339 			ext_printf("Error when verifying signature\n");
340 			goto err;
341 		}
342 		/* If the algorithm supports streaming mode, test it against direct mode */
343 		ret = is_verify_streaming_mode_supported(c->sig_type, &check); EG(ret, err);
344 		if(check){
345 			ret = is_sign_streaming_mode_supported(c->sig_type, &check); EG(ret, err);
346 			if(check){
347 				ret = ec_verify(sig_tmp2, siglen, &(kp.pub_key), msg, msglen,
348 					c->sig_type, c->hash_type, c->adata, c->adata_len);
349 			}
350 			else{
351 				ret = ec_verify(sig, siglen, &(kp.pub_key), msg, msglen,
352 					c->sig_type, c->hash_type, c->adata, c->adata_len);
353 			}
354 			if (ret) {
355 				ext_printf("Error when verifying signature ec_verify\n");
356 				goto err;
357 			}
358 			ret = is_sign_streaming_mode_supported(c->sig_type, &check); EG(ret, err);
359 			if(check){
360 				ret = random_split_ec_verify(sig_tmp1, siglen, &(kp.pub_key), msg, msglen,
361 					c->sig_type, c->hash_type, c->adata, c->adata_len);
362 			}
363 			else{
364 				ret = random_split_ec_verify(sig, siglen, &(kp.pub_key), msg, msglen,
365 					c->sig_type, c->hash_type, c->adata, c->adata_len);
366 			}
367 			if (ret) {
368 				ext_printf("Error when verifying signature random_split_ec_verify\n");
369 				goto err;
370 			}
371 		}
372 		/* Also test the "single" signature batch verification */
373 		ret = is_verify_batch_mode_supported(c->sig_type, &check); EG(ret, err);
374 		if(check){
375 			const u8 *signatures[] = { sig };
376 			const u8 signatures_len[] = { siglen };
377 			const u8 *messages[] = { msg };
378 			const u32 messages_len[] = { msglen };
379 			const ec_pub_key *pub_keys[] = { &(kp.pub_key) };
380 			const u8 *adatas[] = { c->adata };
381 			const u16 adatas_len[] = { c->adata_len };
382 			ret = ec_verify_batch(signatures, signatures_len, pub_keys, messages, messages_len,
383 					1, c->sig_type, c->hash_type, adatas, adatas_len, NULL, NULL);
384 			if(ret){
385 				ext_printf("Error when verifying signature ec_verify_batch with batch 1\n");
386 				goto err;
387 			}
388 		}
389 		check_type = 0;
390 #if defined(WITH_SIG_ECDSA)
391 		if(c->sig_type == ECDSA){
392 			check_type = 1;
393 		}
394 #endif
395 #if defined(WITH_SIG_DECDSA)
396 		if(c->sig_type == DECDSA){
397 			check_type = 1;
398 		}
399 #endif
400 		/* Try a public key recovery from the signature and the message.
401 		 * This is only possible for ECDSA.
402 		 */
403 		if(check_type){
404 			struct ec_sign_context sig_ctx;
405 			u8 digest[MAX_DIGEST_SIZE] = { 0 };
406 			u8 digestlen;
407 			ec_pub_key pub_key1;
408 			ec_pub_key pub_key2;
409 			nn_src_t cofactor = &(params.ec_gen_cofactor);
410 			int cofactorisone;
411 			const u8 *input[2] = { (const u8*)msg , NULL};
412 			u32 ilens[2] = { msglen , 0 };
413 			/* Initialize our signature context only for the hash */
414 			ret = ec_sign_init(&sig_ctx, &kp, c->sig_type, c->hash_type, c->adata, c->adata_len); EG(ret, err);
415 			/* Perform the hash of the data ourselves */
416 			ret = hash_mapping_callbacks_sanity_check(sig_ctx.h); EG(ret, err);
417 			ret = sig_ctx.h->hfunc_scattered(input, ilens, digest); EG(ret, err);
418 			digestlen = sig_ctx.h->digest_size;
419 			MUST_HAVE(digestlen <= sizeof(digest), ret, err);
420 			/* Check the cofactor */
421 			ret = nn_isone(cofactor, &cofactorisone); EG(ret, err);
422 			/* Compute the two possible public keys */
423 			ret = __ecdsa_public_key_from_sig(&pub_key1, &pub_key2, &params, sig, siglen, digest, digestlen, c->sig_type);
424 			if(ret){
425 				ret = 0;
426 				check = -1;
427 				goto pubkey_recovery_warning;
428 			}
429 			/* Check equality with one of the two keys */
430 			ret = prj_pt_cmp(&(pub_key1.y), &(kp.pub_key.y), &check); EG(ret, err);
431 			if(check){
432 				ret = prj_pt_cmp(&(pub_key2.y), &(kp.pub_key.y), &check); EG(ret, err);
433 			}
434 pubkey_recovery_warning:
435 			if(check && cofactorisone){
436 				OPENMP_LOCK();
437 				ext_printf("[~] Warning: ECDSA recovered public key differs from real one ...");
438 				ext_printf("This can happen with very low probability. Please check the trace:\n");
439 				pub_key_print("pub_key1", &pub_key1);
440 				pub_key_print("pub_key2", &pub_key2);
441 				pub_key_print("pub_key", &(kp.pub_key));
442 				buf_print("digest", digest, digestlen);
443 				buf_print("sig", sig, siglen);
444 				OPENMP_UNLOCK();
445 			}
446 		}
447 #ifdef USE_CRYPTOFUZZ
448 		check_type = 0;
449 		/* Specific case where we have access to raw signature API */
450 #if defined(WITH_SIG_ECDSA)
451 		if(c->sig_type == ECDSA){
452 			check_type = 1;
453 		}
454 #endif
455 #if defined(WITH_SIG_ECGDSA)
456 		if(c->sig_type == ECGDSA){
457 			check_type = 1;
458 		}
459 #endif
460 #if defined(WITH_SIG_ECRDSA)
461 		if(c->sig_type == ECRDSA){
462 			check_type = 1;
463 		}
464 #endif
465 		if(check_type){
466 			struct ec_sign_context sig_ctx;
467 			struct ec_verify_context verif_ctx;
468 			u8 digest[MAX_DIGEST_SIZE] = { 0 };
469 			u8 digestlen;
470 			const u8 *input[2] = { (const u8*)msg , NULL};
471 			u32 ilens[2] = { msglen , 0 };
472 			/* Initialize our signature context */
473 			ret = ec_sign_init(&sig_ctx, &kp, c->sig_type, c->hash_type, c->adata, c->adata_len); EG(ret, err);
474 			/* Perform the hash of the data ourselves */
475 			ret = hash_mapping_callbacks_sanity_check(sig_ctx.h); EG(ret, err);
476 			ret = sig_ctx.h->hfunc_scattered(input, ilens, digest); EG(ret, err);
477 			digestlen = sig_ctx.h->digest_size;
478 			MUST_HAVE(digestlen <= sizeof(digest), ret, err);
479 			/* Raw signing of data */
480 #if defined(WITH_SIG_ECDSA)
481 			if(c->sig_type == ECDSA){
482 				ret = ecdsa_sign_raw(&sig_ctx, digest, digestlen, sig, siglen, NULL, 0); EG(ret, err);
483 			}
484 #endif
485 #if defined(WITH_SIG_ECGDSA)
486 			if(c->sig_type ==  ECGDSA){
487 				ret = ecgdsa_sign_raw(&sig_ctx, digest, digestlen, sig, siglen, NULL, 0); EG(ret, err);
488 			}
489 #endif
490 #if defined(WITH_SIG_ECRDSA)
491 			if(c->sig_type ==  ECRDSA){
492 				ret = ecrdsa_sign_raw(&sig_ctx, digest, digestlen, sig, siglen, NULL, 0); EG(ret, err);
493 			}
494 #endif
495 			/* Now verify signature */
496 			ret = ec_verify_init(&verif_ctx,  &(kp.pub_key), sig, siglen, c->sig_type, c->hash_type, c->adata, c->adata_len); EG(ret, err);
497 #if defined(WITH_SIG_ECDSA)
498 			if(c->sig_type == ECDSA){
499 				ret = ecdsa_verify_raw(&verif_ctx, digest, digestlen); EG(ret, err);
500 			}
501 #endif
502 #if defined(WITH_SIG_ECGDSA)
503 			if(c->sig_type ==  ECGDSA){
504 				ret = ecgdsa_verify_raw(&verif_ctx, digest, digestlen); EG(ret, err);
505 			}
506 #endif
507 #if defined(WITH_SIG_ECRDSA)
508 			if(c->sig_type ==  ECRDSA){
509 				ret = ecrdsa_verify_raw(&verif_ctx, digest, digestlen); EG(ret, err);
510 			}
511 #endif
512 		}
513 #endif
514 	}
515 
516 	/* Perform test specific to batch verification */
517 	ret = is_verify_batch_mode_supported(c->sig_type, &check); EG(ret, err);
518 	if(check){
519 		u16 msglen;
520 		u8 siglen;
521 		ec_key_pair keypairs[MAX_BATCH_SIG_SIZE];
522 		const ec_pub_key *pubkeys[MAX_BATCH_SIG_SIZE];
523 		u8 msg[MAX_BATCH_SIG_SIZE * MAX_MSG_LEN];
524 		const u8 *messages[MAX_BATCH_SIG_SIZE];
525 		u32 messages_len[MAX_BATCH_SIG_SIZE];
526 		u8 sig[MAX_BATCH_SIG_SIZE * EC_MAX_SIGLEN];
527 		const u8 *signatures[MAX_BATCH_SIG_SIZE];
528 		u8 signatures_len[MAX_BATCH_SIG_SIZE];
529 		const u8 *adata[MAX_BATCH_SIG_SIZE];
530 		u16 adata_len[MAX_BATCH_SIG_SIZE];
531 		u8 check_type = 0;
532 		u32 num_batch, i, current;
533 
534 		FORCE_USED_VAR(check_type);
535 
536 gen_num_batch:
537 		ret = get_random((u8 *)&num_batch, sizeof(num_batch));
538 		if(ret){
539 			ext_printf("Error when getting random\n");
540 			goto err;
541 		}
542 		num_batch = (num_batch % MAX_BATCH_SIG_SIZE);
543 		if(num_batch == 0){
544 			goto gen_num_batch;
545 		}
546 
547 		ret = ec_get_sig_len(&params, c->sig_type, c->hash_type,
548 				     (u8 *)&siglen);
549 		if (ret) {
550 			ext_printf("Error computing effective sig size\n");
551 			goto err;
552 		}
553 
554 		/* Generate random messages to sign */
555 		current = 0;
556 		for(i = 0; i < num_batch; i++){
557 			/* Generate, import/export a key pair */
558 			ret = ec_gen_import_export_kp(&keypairs[i], &params, c);
559 			pubkeys[i] = &(keypairs[i].pub_key);
560 			if (ret) {
561 				ext_printf("Error at key pair generation/import/export\n");
562 				goto err;
563 			}
564 			ret = get_random((u8 *)&msglen, sizeof(msglen));
565 			if (ret) {
566 				ext_printf("Error when getting random\n");
567 				goto err;
568 			}
569 			msglen = msglen % MAX_MSG_LEN;
570 			messages_len[i] = msglen;
571 			messages[i] = &msg[current];
572 			ret = get_random(&msg[current], msglen);
573 			if (ret) {
574 				ext_printf("Error when getting random\n");
575 				goto err;
576 			}
577 			current += msglen;
578 
579 			signatures[i] = &sig[i * siglen];
580 			signatures_len[i] = siglen;
581 			adata_len[i] = c->adata_len;
582 			adata[i] = c->adata;
583 			ret = _ec_sign(&sig[i * siglen], siglen, &keypairs[i], messages[i], messages_len[i],
584 				       c->nn_random, c->sig_type, c->hash_type, c->adata, c->adata_len);
585 			if (ret) {
586 				ext_printf("Error when signing\n");
587 				goto err;
588 			}
589 		}
590 		/* Test */
591 		ret = ec_verify_batch(signatures, signatures_len, pubkeys, messages, messages_len,
592 				num_batch, c->sig_type, c->hash_type, adata, adata_len, NULL, NULL);
593 		if(ret){
594 			ext_printf("Error when verifying signature ec_verify_batch no memory for batch size %" PRIu32 "\n", num_batch);
595 			goto err;
596 		}
597 		{
598 			u32 scratch_pad_area_len = 0;
599 			/* We need 2 * n + 1 scratch pad storage, compute this with max */
600 			verify_batch_scratch_pad scratch_pad_area[(2 * MAX_BATCH_SIG_SIZE) + 1];
601 
602 			ret = ec_verify_batch(signatures, signatures_len, pubkeys, messages, messages_len,
603 					num_batch, c->sig_type, c->hash_type, adata, adata_len, NULL, &scratch_pad_area_len);
604 			if(ret){
605 				ext_printf("Error when getting scratch_pad_area length for ec_verify_batch optimized  for batch size %" PRIu32 "\n", num_batch);
606 				goto err;
607 			}
608 			MUST_HAVE((scratch_pad_area_len <= sizeof(scratch_pad_area)), ret, err);
609 
610 			scratch_pad_area_len = sizeof(scratch_pad_area);
611 			ret = ec_verify_batch(signatures, signatures_len, pubkeys, messages, messages_len,
612 					num_batch, c->sig_type, c->hash_type, adata, adata_len, scratch_pad_area, &scratch_pad_area_len);
613 			if(ret){
614 				ext_printf("Error when verifying signature ec_verify_batch optimized for batch size %" PRIu32 "\n", num_batch);
615 				goto err;
616 			}
617 		}
618 	}
619 
620 	ret = 0;
621 
622  err:
623 	return ret;
624 }
625 
626 /*
627  * Those functions respectively perform signature and verification tests
628  * based the content of a given test case.
629  */
ec_test_sign(u8 * sig,u8 siglen,ec_key_pair * kp,const ec_test_case * c)630 ATTRIBUTE_WARN_UNUSED_RET static int ec_test_sign(u8 *sig, u8 siglen, ec_key_pair *kp,
631 			const ec_test_case *c)
632 {
633 	/* If the algorithm supports streaming, we check that both the streaming and
634 	 * non streaming modes produce the same result.
635 	 */
636 	int ret, check;
637 
638 	MUST_HAVE(sig != NULL, ret, err);
639 	MUST_HAVE(c != NULL, ret, err);
640 
641 	ret = _ec_sign(sig, siglen, kp, (const u8 *)(c->msg), c->msglen,
642 				c->nn_random, c->sig_type, c->hash_type, c->adata, c->adata_len); EG(ret, err);
643 	ret = is_sign_streaming_mode_supported(c->sig_type, &check); EG(ret, err);
644 	if(check){
645 		u8 sig_tmp[EC_MAX_SIGLEN];
646 		MUST_HAVE(siglen <= sizeof(sig_tmp), ret, err);
647 		ret = generic_ec_sign(sig_tmp, siglen, kp, (const u8 *)(c->msg), c->msglen,
648 				c->nn_random, c->sig_type, c->hash_type, c->adata, c->adata_len); EG(ret, err);
649 		ret = are_equal(sig, sig_tmp, siglen, &check); EG(ret, err);
650 		if(!check){
651 			ret = -1;
652 			goto err;
653 		}
654 		/* Now test the random split version */
655 		ret = random_split_ec_sign(sig_tmp, siglen, kp, (const u8 *)(c->msg), c->msglen,
656 				c->nn_random, c->sig_type, c->hash_type, c->adata, c->adata_len); EG(ret, err);
657 		ret = are_equal(sig, sig_tmp, siglen, &check); EG(ret, err);
658 		if(!check){
659 			ret = -1;
660 			goto err;
661 		}
662 	}
663 
664 	ret = 0;
665 err:
666 	return ret;
667 }
668 
ec_test_verify(u8 * sig,u8 siglen,const ec_pub_key * pub_key,const ec_test_case * c)669 ATTRIBUTE_WARN_UNUSED_RET static int ec_test_verify(u8 *sig, u8 siglen, const ec_pub_key *pub_key,
670 			  const ec_test_case *c)
671 {
672 	/* If the algorithm supports streaming, we check that both the streaming and
673 	 * non streaming modes produce the same result.
674 	 */
675 	int ret, check;
676 
677 	MUST_HAVE(sig != NULL, ret, err);
678 	MUST_HAVE(c != NULL, ret, err);
679 
680 	ret = ec_verify(sig, siglen, pub_key, (const u8 *)(c->msg), c->msglen,
681 				 c->sig_type, c->hash_type, c->adata, c->adata_len);
682 	if(ret){
683 		ret = -1;
684 		goto err;
685 	}
686 	ret = is_verify_streaming_mode_supported(c->sig_type, &check); EG(ret, err);
687 	if(check){
688 		ret = ec_verify(sig, siglen, pub_key, (const u8 *)(c->msg), c->msglen,
689 				 c->sig_type, c->hash_type, c->adata, c->adata_len);
690 		if(ret){
691 			ret = -1;
692 			goto err;
693 		}
694 		/* Now test the random split version */
695 		ret = random_split_ec_verify(sig, siglen, pub_key, (const u8 *)(c->msg), c->msglen,
696 				 c->sig_type, c->hash_type, c->adata, c->adata_len);
697 		if(ret){
698 			ret = -1;
699 			goto err;
700 		}
701 	}
702 	/* Also test the "single" signature batch verification */
703 	ret = is_verify_batch_mode_supported(c->sig_type, &check); EG(ret, err);
704 	if(check){
705 		const u8 *signatures[] = { sig };
706 		const u8 signatures_len[] = { siglen };
707 		const u8 *messages[] = { (const u8*)c->msg };
708 		const u32 messages_len[] = { c->msglen };
709 		const ec_pub_key *pub_keys[] = { pub_key };
710 		const u8 *adatas[] = { c->adata };
711 		const u16 adatas_len[] = { c->adata_len };
712 		ret = ec_verify_batch(signatures, signatures_len, pub_keys, messages, messages_len,
713 				1, c->sig_type, c->hash_type, adatas, adatas_len, NULL, NULL);
714 		if(ret){
715 			ret = -1;
716 			goto err;
717 		}
718 	}
719 
720 	ret = 0;
721 err:
722 	return ret;
723 }
724 
725 /*
726  * ECC generic self tests (sign/verify on known test vectors). Returns
727  * 0 if given test succeeded, or a non-zero value otherwise. In that
728  * case, the value encodes the information on what went wrong as
729  * described above.
730  */
ec_sig_known_vector_tests_one(const ec_test_case * c)731 ATTRIBUTE_WARN_UNUSED_RET static int ec_sig_known_vector_tests_one(const ec_test_case *c)
732 {
733 	test_err_kind failed_test = TEST_KEY_IMPORT_ERROR;
734 	u8 sig[EC_MAX_SIGLEN];
735 	ec_params params;
736 	ec_key_pair kp;
737 	u8 siglen;
738 	int ret;
739 	int check = 0;
740 
741 	MUST_HAVE((c != NULL), ret, err);
742 
743 	ret = local_memset(&kp, 0, sizeof(kp)); EG(ret, err);
744 	ret = local_memset(&params, 0, sizeof(params)); EG(ret, err);
745 	ret = local_memset(sig, 0, sizeof(sig)); EG(ret, err);
746 
747 	ret = import_params(&params, c->ec_str_p);
748 	if (ret) {
749 		ext_printf("Error importing params\n");
750 		goto err;
751 	}
752 
753 #if defined(WITH_SIG_EDDSA25519) || defined(WITH_SIG_EDDSA448)
754 	/* In the specific case of EdDSA, we perform a specific key derivation */
755 #if defined(WITH_SIG_EDDSA25519) && defined(WITH_SIG_EDDSA448)
756 	if((c->sig_type == EDDSA25519) || (c->sig_type == EDDSA25519CTX) || (c->sig_type == EDDSA25519PH) || \
757 	  (c->sig_type == EDDSA448) || (c->sig_type == EDDSA448PH)){
758 #endif
759 #if defined(WITH_SIG_EDDSA25519) && !defined(WITH_SIG_EDDSA448)
760 	if((c->sig_type == EDDSA25519) || (c->sig_type == EDDSA25519CTX) || (c->sig_type == EDDSA25519PH)){
761 #endif
762 #if !defined(WITH_SIG_EDDSA25519) && defined(WITH_SIG_EDDSA448)
763 	if((c->sig_type == EDDSA448) || (c->sig_type == EDDSA448PH)){
764 #endif
765 		/* Import the key pair using the EdDSA dedicated function */
766 		if(eddsa_import_key_pair_from_priv_key_buf(&kp, c->priv_key, c->priv_key_len, &params, c->sig_type)){
767 			ret = -1;
768 			failed_test = TEST_KEY_IMPORT_ERROR;
769 			goto err;
770 		}
771 	}
772 	else
773 #endif /* !(defined(WITH_SIG_EDDSA25519) || defined(WITH_SIG_EDDSA448)) */
774 	{
775 		/* Regular import if not EdDSA */
776 		ret = ec_key_pair_import_from_priv_key_buf(&kp, &params, c->priv_key,
777 							   c->priv_key_len,
778 							   c->sig_type);
779 		if (ret) {
780 			failed_test = TEST_KEY_IMPORT_ERROR;
781 			goto err;
782 		}
783 	}
784 
785 	siglen = c->exp_siglen;
786 	ret = ec_test_sign(sig, siglen, &kp, c);
787 	if (ret) {
788 		failed_test = TEST_SIG_ERROR;
789 		goto err;
790 	}
791 
792 	ret = are_equal(sig, c->exp_sig, siglen, &check); EG(ret, err);
793 	if (!check) {
794 		ret = -1;
795 		failed_test = TEST_SIG_COMP_ERROR;
796 		goto err;
797 	}
798 
799 	ret = ec_test_verify(sig, siglen, &(kp.pub_key), c);
800 	if (ret) {
801 		failed_test = TEST_VERIF_ERROR;
802 		goto err;
803 	}
804 
805 	check = 0;
806 #if defined(WITH_SIG_ECDSA)
807 	if(c->sig_type == ECDSA){
808 		check = 1;
809 	}
810 #endif
811 #if defined(WITH_SIG_DECDSA)
812 	if(c->sig_type == DECDSA){
813 		check = 1;
814 	}
815 #endif
816 	/* Try a public key recovery from the signature and the message.
817 	 * This is only possible for ECDSA.
818 	 */
819 	if(check){
820 		struct ec_sign_context sig_ctx;
821 		u8 digest[MAX_DIGEST_SIZE] = { 0 };
822 		u8 digestlen;
823 		ec_pub_key pub_key1;
824 		ec_pub_key pub_key2;
825 		nn_src_t cofactor = &(params.ec_gen_cofactor);
826 		int cofactorisone;
827 		const u8 *input[2] = { (const u8*)(c->msg) , NULL};
828 		u32 ilens[2] = { c->msglen , 0 };
829 		/* Initialize our signature context only for the hash */
830 		ret = ec_sign_init(&sig_ctx, &kp, c->sig_type, c->hash_type, c->adata, c->adata_len); EG(ret, err);
831 		/* Perform the hash of the data ourselves */
832 		ret = hash_mapping_callbacks_sanity_check(sig_ctx.h); EG(ret, err);
833 		ret = sig_ctx.h->hfunc_scattered(input, ilens, digest); EG(ret, err);
834 		digestlen = sig_ctx.h->digest_size;
835 		MUST_HAVE(digestlen <= sizeof(digest), ret, err);
836 		/* Check the cofactor */
837 		ret = nn_isone(cofactor, &cofactorisone); EG(ret, err);
838 		/* Compute the two possible public keys */
839 		ret = __ecdsa_public_key_from_sig(&pub_key1, &pub_key2, &params, sig, siglen, digest, digestlen, c->sig_type);
840 		if(ret){
841 			ret = 0;
842 			check = -1;
843 			goto pubkey_recovery_warning;
844 		}
845 		/* Check equality with one of the two keys */
846 		ret = prj_pt_cmp(&(pub_key1.y), &(kp.pub_key.y), &check); EG(ret, err);
847 		if(check){
848 			ret = prj_pt_cmp(&(pub_key2.y), &(kp.pub_key.y), &check); EG(ret, err);
849 		}
850 pubkey_recovery_warning:
851 		if(check && cofactorisone){
852 			OPENMP_LOCK();
853 			ext_printf("[~] Warning: ECDSA recovered public key differs from real one ...");
854 			ext_printf("This can happen with very low probability. Please check the trace:\n");
855 			pub_key_print("pub_key1", &pub_key1);
856 			pub_key_print("pub_key2", &pub_key2);
857 			pub_key_print("pub_key", &(kp.pub_key));
858 			buf_print("digest", digest, digestlen);
859 			buf_print("sig", sig, siglen);
860 			OPENMP_UNLOCK();
861 		}
862 	}
863 #ifdef USE_CRYPTOFUZZ
864 	check = 0;
865 	/* Specific case where we have access to raw signature API */
866 #if defined(WITH_SIG_ECDSA)
867 	if(c->sig_type == ECDSA){
868 		check = 1;
869 	}
870 #endif
871 #if defined(WITH_SIG_ECGDSA)
872 	if(c->sig_type == ECGDSA){
873 		check = 1;
874 	}
875 #endif
876 #if defined(WITH_SIG_ECRDSA)
877 	if(c->sig_type == ECRDSA){
878 		check = 1;
879 	}
880 #endif
881 	/* Specific case where we have access to raw signature API */
882 	if(check){
883 		struct ec_sign_context sig_ctx;
884 		struct ec_verify_context verif_ctx;
885 		u8 digest[MAX_DIGEST_SIZE] = { 0 };
886 		u8 digestlen;
887 		const u8 *input[2] = { (const u8*)(c->msg) , NULL};
888 		u32 ilens[2] = { c->msglen , 0 };
889 		u8 nonce[LOCAL_MIN(255, BIT_LEN_WORDS(NN_MAX_BIT_LEN) * (WORDSIZE / 8))] = { 0 };
890 		nn n_nonce;
891 		bitcnt_t q_bit_len;
892 		u8 noncelen;
893 		/* Initialize our signature context */
894 		if(ec_sign_init(&sig_ctx, &kp, c->sig_type, c->hash_type, c->adata, c->adata_len)){
895 			ret = -1;
896 			failed_test = TEST_SIG_ERROR;
897 			goto err;
898 		}
899 		/* Perform the hash of the data ourselves */
900 		if(hash_mapping_callbacks_sanity_check(sig_ctx.h)){
901 			ret = -1;
902 			failed_test = TEST_SIG_ERROR;
903 			goto err;
904 		}
905 		ret = sig_ctx.h->hfunc_scattered(input, ilens, digest); EG(ret, err);
906 		digestlen = sig_ctx.h->digest_size;
907 		MUST_HAVE(digestlen <= sizeof(digest), ret, err);
908 		/* Import the fixed nonce */
909 		q_bit_len = kp.priv_key.params->ec_gen_order_bitlen;
910 		if(c->nn_random(&n_nonce, &(kp.priv_key.params->ec_gen_order))){
911 			ret = -1;
912 			failed_test = TEST_SIG_ERROR;
913 			goto err;
914 		}
915 		ret = nn_export_to_buf(nonce, (u16)BYTECEIL(q_bit_len), &n_nonce); EG(ret, err);
916 		if((unsigned int)BYTECEIL(q_bit_len) > sizeof(nonce)){
917 			ret = -1;
918 			failed_test = TEST_SIG_ERROR;
919 			goto err;
920 		}
921 		noncelen = (u8)(BYTECEIL(q_bit_len));
922 		/* Force used variable to avoid warnings */
923 		FORCE_USED_VAR(noncelen);
924 		/* NOTE: the MUST_HAVE is protected by a preprocessing check
925 		 * to avoid -Werror=type-limits errors:
926 		 * "error: comparison is always true due to limited range of data type"
927 		 */
928 #if LOCAL_MIN(255, BIT_LEN_WORDS(NN_MAX_BIT_LEN) * (WORDSIZE / 8)) < 255
929 		MUST_HAVE((u32)noncelen <= sizeof(nonce), ret, err);
930 #endif
931 		/* Raw signing of data */
932 #if defined(WITH_SIG_ECDSA)
933 		if(c->sig_type == ECDSA){
934 			if(ecdsa_sign_raw(&sig_ctx, digest, digestlen, sig, siglen, nonce, noncelen)){
935 				ret = -1;
936 				failed_test = TEST_SIG_ERROR;
937 				goto err;
938 			}
939 		}
940 #endif
941 #if defined(WITH_SIG_ECGDSA)
942 		if(c->sig_type == ECGDSA){
943 			if(ecgdsa_sign_raw(&sig_ctx, digest, digestlen, sig, siglen, nonce, noncelen)){
944 				ret = -1;
945 				failed_test = TEST_SIG_ERROR;
946 				goto err;
947 			}
948 		}
949 #endif
950 #if defined(WITH_SIG_ECRDSA)
951 		if(c->sig_type == ECRDSA){
952 			if(ecrdsa_sign_raw(&sig_ctx, digest, digestlen, sig, siglen, nonce, noncelen)){
953 				ret = -1;
954 				failed_test = TEST_SIG_ERROR;
955 				goto err;
956 			}
957 		}
958 #endif
959 		/* Check computed signature against expected one */
960 		ret = are_equal(sig, c->exp_sig, siglen, &check); EG(ret, err);
961 		if (!check) {
962 			failed_test = TEST_SIG_COMP_ERROR;
963 			ret = -1;
964 			goto err;
965 		}
966 		/* Now verify signature */
967 		if(ec_verify_init(&verif_ctx,  &(kp.pub_key), sig, siglen, c->sig_type, c->hash_type, c->adata, c->adata_len)){
968 			ret = -1;
969 			failed_test = TEST_VERIF_ERROR;
970 			goto err;
971 		}
972 		/* Raw verification of data */
973 #if defined(WITH_SIG_ECDSA)
974 		if(c->sig_type == ECDSA){
975 			if(ecdsa_verify_raw(&verif_ctx, digest, digestlen)){
976 				ret = -1;
977 				failed_test = TEST_VERIF_ERROR;
978 				goto err;
979 			}
980 		}
981 #endif
982 #if defined(WITH_SIG_ECGDSA)
983 		if(c->sig_type == ECGDSA){
984 			if(ecgdsa_verify_raw(&verif_ctx, digest, digestlen)){
985 				ret = -1;
986 				failed_test = TEST_VERIF_ERROR;
987 				goto err;
988 			}
989 		}
990 #endif
991 #if defined(WITH_SIG_ECRDSA)
992 		if(c->sig_type == ECRDSA){
993 			if(ecrdsa_verify_raw(&verif_ctx, digest, digestlen)){
994 				ret = -1;
995 				failed_test = TEST_VERIF_ERROR;
996 				goto err;
997 			}
998 		}
999 #endif
1000 	}
1001 #endif
1002 	ret = 0;
1003 
1004  err:
1005 	if (ret) {
1006 		u32 ret_;
1007 		ret = encode_error_value(c, failed_test, &ret_); EG(ret, err);
1008 		ret = (int)ret_;
1009 	}
1010 
1011 	return ret;
1012 }
1013 
1014 #if defined(WITH_ECCCDH) || defined(WITH_X25519) || defined(WITH_X448)
1015 /*
1016  * ECC generic self tests (ecdh on known test vectors). Returns
1017  * 0 if given test succeeded, or a non-zero value otherwise. In that
1018  * case, the value encodes the information on what went wrong as
1019  * described above.
1020  */
1021 ATTRIBUTE_WARN_UNUSED_RET static int ecdh_known_vector_tests_one(const ecdh_test_case *c)
1022 {
1023 	test_err_kind failed_test = TEST_KEY_IMPORT_ERROR;
1024 	ec_params params;
1025 	ec_key_pair kp;
1026 	int ret, check;
1027 
1028 	MUST_HAVE((c != NULL), ret, err);
1029 
1030 	ret = local_memset(&kp, 0, sizeof(kp)); EG(ret, err);
1031 	ret = local_memset(&params, 0, sizeof(params)); EG(ret, err);
1032 
1033 	ret = import_params(&params, c->ec_str_p);
1034 	if (ret) {
1035 		ext_printf("Error importing params\n");
1036 		goto err;
1037 	}
1038 
1039 	/* Check what ECDH test we have to perform */
1040 	switch(c->ecdh_type){
1041 #if defined(WITH_ECCCDH)
1042 		case ECCCDH:{
1043 			u8 serialized_pub_key[EC_PUB_KEY_MAX_SIZE];
1044 			u8 serialized_pub_key_len;
1045 			/* This maximum size is way bigger than expected, but we ensure
1046 			 * that there is enough room for our shared secret.
1047 			 */
1048 			u8 shared_secret[EC_PUB_KEY_MAX_SIZE];
1049 			u8 shared_secret_len;
1050 
1051 			ret = local_memset(serialized_pub_key, 0, sizeof(serialized_pub_key)); EG(ret, err);
1052 			ret = local_memset(shared_secret, 0, sizeof(shared_secret)); EG(ret, err);
1053 
1054 			/* Import our ECDH key pair */
1055 			ret = ecccdh_import_key_pair_from_priv_key_buf(&kp, &params, c->our_priv_key,
1056 								   c->our_priv_key_len);
1057 			if (ret) {
1058 				failed_test = TEST_KEY_IMPORT_ERROR;
1059 				ret = -1;
1060 				goto err;
1061 			}
1062 			/* Serialize our public key */
1063 			ret = ecccdh_serialized_pub_key_size(&params, &serialized_pub_key_len); EG(ret, err);
1064 			MUST_HAVE((sizeof(serialized_pub_key) >= serialized_pub_key_len), ret, err);
1065 			ret = ecccdh_serialize_pub_key(&(kp.pub_key), serialized_pub_key, serialized_pub_key_len);
1066 			if (ret) {
1067 				failed_test = TEST_ECDH_ERROR;
1068 				ret = -1;
1069 				goto err;
1070 			}
1071 			/* Check it against the expected one */
1072 			MUST_HAVE((serialized_pub_key_len == c->exp_our_pub_key_len), ret, err);
1073 			ret = are_equal(serialized_pub_key, c->exp_our_pub_key, serialized_pub_key_len, &check); EG(ret, err);
1074 			if (!check) {
1075 				failed_test = TEST_ECDH_COMP_ERROR;
1076 				ret = -1;
1077 				goto err;
1078 			}
1079 			/* Now derive the shared secret */
1080 			ret = ecccdh_shared_secret_size(&params, &shared_secret_len); EG(ret, err);
1081 			MUST_HAVE((sizeof(shared_secret) >= shared_secret_len), ret, err);
1082 			ret = ecccdh_derive_secret(&(kp.priv_key), c->peer_pub_key, c->peer_pub_key_len, shared_secret, shared_secret_len);
1083 			if (ret) {
1084 				failed_test = TEST_ECDH_ERROR;
1085 				ret = -1;
1086 				goto err;
1087 			}
1088 			/* Check it against the expected one */
1089 			MUST_HAVE((shared_secret_len == c->exp_shared_secret_len), ret, err);
1090 			ret = are_equal(shared_secret, c->exp_shared_secret, shared_secret_len, &check); EG(ret, err);
1091 			if (!check) {
1092 				failed_test = TEST_ECDH_COMP_ERROR;
1093 				ret = -1;
1094 				goto err;
1095 			}
1096 
1097 			break;
1098 		}
1099 #endif
1100 #if defined(WITH_X25519)
1101 		case X25519:{
1102 			u8 pub_key[X25519_SIZE];
1103 			u8 shared_secret[X25519_SIZE];
1104 
1105 			ret = local_memset(pub_key, 0, sizeof(pub_key)); EG(ret, err);
1106 			ret = local_memset(shared_secret, 0, sizeof(shared_secret)); EG(ret, err);
1107 
1108 			/* Compute our public key */
1109 			MUST_HAVE((c->our_priv_key_len == X25519_SIZE), ret, err);
1110 			ret = x25519_init_pub_key(c->our_priv_key, pub_key);
1111 			if (ret) {
1112 				failed_test = TEST_KEY_IMPORT_ERROR;
1113 				ret = -1;
1114 				goto err;
1115 			}
1116 			/* Check it against the expected one */
1117 			MUST_HAVE((c->exp_our_pub_key_len == X25519_SIZE), ret, err);
1118 			ret = are_equal(pub_key, c->exp_our_pub_key, X25519_SIZE, &check); EG(ret, err);
1119 			if (!check) {
1120 				failed_test = TEST_ECDH_COMP_ERROR;
1121 				ret = -1;
1122 				goto err;
1123 			}
1124 			/* Now derive the shared secret */
1125 			MUST_HAVE((c->peer_pub_key_len == X25519_SIZE), ret, err);
1126 			ret = x25519_derive_secret(c->our_priv_key, c->peer_pub_key, shared_secret);
1127 			if (ret) {
1128 				failed_test = TEST_ECDH_ERROR;
1129 				ret = -1;
1130 				goto err;
1131 			}
1132 			/* Check it against the expected one */
1133 			MUST_HAVE((c->exp_shared_secret_len == X25519_SIZE), ret, err);
1134 			ret = are_equal(shared_secret, c->exp_shared_secret, X25519_SIZE, &check); EG(ret, err);
1135 			if (!check) {
1136 				failed_test = TEST_ECDH_COMP_ERROR;
1137 				ret = -1;
1138 				goto err;
1139 			}
1140 
1141 			break;
1142 		}
1143 #endif
1144 #if defined(WITH_X448)
1145 		case X448:{
1146 			u8 pub_key[X448_SIZE];
1147 			u8 shared_secret[X448_SIZE];
1148 
1149 			ret = local_memset(pub_key, 0, sizeof(pub_key)); EG(ret, err);
1150 			ret = local_memset(shared_secret, 0, sizeof(shared_secret)); EG(ret, err);
1151 
1152 			/* Compute our public key */
1153 			MUST_HAVE((c->our_priv_key_len == X448_SIZE), ret, err);
1154 			ret = x448_init_pub_key(c->our_priv_key, pub_key);
1155 			if (ret) {
1156 				failed_test = TEST_KEY_IMPORT_ERROR;
1157 				ret = -1;
1158 				goto err;
1159 			}
1160 			/* Check it against the expected one */
1161 			MUST_HAVE((c->exp_our_pub_key_len == X448_SIZE), ret, err);
1162 			ret = are_equal(pub_key, c->exp_our_pub_key, X448_SIZE, &check); EG(ret, err);
1163 			if (!check) {
1164 				failed_test = TEST_ECDH_COMP_ERROR;
1165 				ret = -1;
1166 				goto err;
1167 			}
1168 			/* Now derive the shared secret */
1169 			MUST_HAVE((c->peer_pub_key_len == X448_SIZE), ret, err);
1170 			ret = x448_derive_secret(c->our_priv_key, c->peer_pub_key, shared_secret);
1171 			if (ret) {
1172 				failed_test = TEST_ECDH_ERROR;
1173 				ret = -1;
1174 				goto err;
1175 			}
1176 			/* Check it against the expected one */
1177 			MUST_HAVE((c->exp_shared_secret_len == X448_SIZE), ret, err);
1178 			ret = are_equal(shared_secret, c->exp_shared_secret, X448_SIZE, &check); EG(ret, err);
1179 			if (!check) {
1180 				failed_test = TEST_ECDH_COMP_ERROR;
1181 				ret = -1;
1182 				goto err;
1183 			}
1184 
1185 			break;
1186 		}
1187 #endif
1188 		default:{
1189 			ext_printf("Error: not an ECDH test\n");
1190 			ret = -1;
1191 			goto err;
1192 		}
1193 	}
1194 
1195 err:
1196 	if (ret) {
1197 		u32 ret_;
1198 		ret = ecdh_encode_error_value(c, failed_test, &ret_); EG(ret, err);
1199 		ret = (int)ret_;
1200 	}
1201 
1202 	return ret;
1203 }
1204 #endif
1205 
1206 ATTRIBUTE_WARN_UNUSED_RET int perform_known_test_vectors_test(const char *sig, const char *hash, const char *curve)
1207 {
1208 	unsigned int i;
1209 	int ret = 0;
1210 
1211 	ext_printf("======= Known test vectors test =================\n");
1212 #ifdef WITH_OPENMP_SELF_TESTS
1213         #pragma omp parallel
1214         #pragma omp for schedule(static, 1) nowait
1215 #endif
1216 	for (i = 0; i < EC_FIXED_VECTOR_NUM_TESTS; i++) {
1217 		int check;
1218 		const ec_test_case *cur_test;
1219 		cur_test = ec_fixed_vector_tests[i];
1220 		if(cur_test == NULL){
1221 			continue;
1222 		}
1223 		/* If this is a dummy test case, skip it! */
1224 		if(cur_test->sig_type == UNKNOWN_ALG){
1225 			continue;
1226 		}
1227 		/* Filter out */
1228 		if(sig != NULL){
1229 			const ec_sig_mapping *sig_map;
1230 			ret = get_sig_by_type(cur_test->sig_type, &sig_map); OPENMP_EG(ret, err);
1231 			if(sig_map == NULL){
1232 				continue;
1233 			}
1234 			ret = are_str_equal(sig_map->name, sig, &check); OPENMP_EG(ret, err);
1235 			if(!check){
1236 				continue;
1237 			}
1238 		}
1239 		if(hash != NULL){
1240 			const hash_mapping *hash_map;
1241 			ret = get_hash_by_type(cur_test->hash_type, &hash_map); OPENMP_EG(ret, err);
1242 			if(hash_map == NULL){
1243 				continue;
1244 			}
1245 			ret = are_str_equal(hash_map->name, hash, &check); OPENMP_EG(ret, err);
1246 			if(!check){
1247 				continue;
1248 			}
1249 		}
1250 		if(curve != NULL){
1251 			if(cur_test->ec_str_p == NULL){
1252 				continue;
1253 			}
1254 			ret = are_str_equal((const char*)cur_test->ec_str_p->name->buf, curve, &check); OPENMP_EG(ret, err);
1255 			if(!check){
1256 				continue;
1257 			}
1258 		}
1259 		ret = ec_sig_known_vector_tests_one(cur_test);
1260 		OPENMP_LOCK();
1261 		ext_printf("[%s] %30s selftests: known test vectors "
1262 			   "sig/verif %s\n", ret ? "-" : "+",
1263 			   cur_test->name, ret ? "failed" : "ok");
1264 		check = 0;
1265 #if defined(WITH_SIG_ECDSA)
1266 		if(cur_test->sig_type == ECDSA){
1267 			check = 1;
1268 		}
1269 #endif
1270 #if defined(WITH_SIG_DECDSA)
1271 		if(cur_test->sig_type == DECDSA){
1272 			check = 1;
1273 		}
1274 #endif
1275 		if(check){
1276 			ext_printf("\t(ECDSA public key recovery also checked!)\n");
1277 		}
1278 #ifdef USE_CRYPTOFUZZ
1279 #if defined(WITH_SIG_ECDSA)
1280 		if(cur_test->sig_type == ECDSA){
1281 			ext_printf("\t(RAW ECDSA for CRYPTOFUZZ also checked!)\n");
1282 		}
1283 #endif
1284 #if defined(WITH_SIG_ECGDSA)
1285 		if(cur_test->sig_type == ECGDSA){
1286 			ext_printf("\t(RAW ECGDSA for CRYPTOFUZZ also checked!)\n");
1287 		}
1288 #endif
1289 #if defined(WITH_SIG_ECRDSA)
1290 		if(cur_test->sig_type == ECRDSA){
1291 			ext_printf("\t(RAW ECRDSA for CRYPTOFUZZ also checked!)\n");
1292 		}
1293 #endif
1294 #endif
1295 		OPENMP_UNLOCK();
1296 		OPENMP_EG(ret, err);
1297 	}
1298 #if defined(WITH_ECCCDH) || defined(WITH_X25519) || defined(WITH_X448)
1299 	/* Now take care of ECDH */
1300 	if((sig == NULL) && (hash == NULL)){
1301 #ifdef WITH_OPENMP_SELF_TESTS
1302 	        #pragma omp parallel
1303 		#pragma omp for schedule(static, 1) nowait
1304 #endif
1305 		for (i = 0; i < ECDH_FIXED_VECTOR_NUM_TESTS; i++) {
1306 			int check;
1307 			const ecdh_test_case *ecdh_cur_test;
1308 			ecdh_cur_test = ecdh_fixed_vector_tests[i];
1309 			if(ecdh_cur_test == NULL){
1310 				continue;
1311 			}
1312 			/* If this is not an ECDH test case, skip it! */
1313 			if(ecdh_cur_test->ecdh_type == UNKNOWN_ALG){
1314 				continue;
1315 			}
1316 			if(curve != NULL){
1317 				if(ecdh_cur_test->ec_str_p == NULL){
1318 					continue;
1319 				}
1320 				ret = are_str_equal((const char*)ecdh_cur_test->ec_str_p->name->buf, curve, &check); OPENMP_EG(ret, err);
1321 				if(!check){
1322 					continue;
1323 				}
1324 			}
1325 			ret = ecdh_known_vector_tests_one(ecdh_cur_test);
1326 			OPENMP_LOCK();
1327 			ext_printf("[%s] %30s selftests: known test vectors "
1328 				   "ecdh %s\n", ret ? "-" : "+",
1329 				   ecdh_cur_test->name, ret ? "failed" : "ok");
1330 			OPENMP_EG(ret, err);
1331 			OPENMP_UNLOCK();
1332 		}
1333 	}
1334 #endif
1335 
1336 #ifndef WITH_OPENMP_SELF_TESTS
1337 err:
1338 #endif
1339 	return ret;
1340 }
1341 
1342 ATTRIBUTE_WARN_UNUSED_RET static int rand_sig_verif_test_one(const ec_sig_mapping *sig,
1343 				   const hash_mapping *hash,
1344 				   const ec_mapping *ec)
1345 {
1346 	char test_name[MAX_CURVE_NAME_LEN + MAX_HASH_ALG_NAME_LEN +
1347 		       MAX_SIG_ALG_NAME_LEN + 2];
1348 	const unsigned int tn_size = sizeof(test_name) - 1; /* w/o trailing 0 */
1349 	const char *crv_name;
1350 	ec_test_case t;
1351 	int ret, check;
1352 	u32 len;
1353 
1354 #if defined(WITH_SIG_EDDSA25519) || defined(WITH_SIG_SM2) || defined(WITH_SIG_BIGN) || defined(WITH_SIG_DBIGN)
1355 	u8 rand_adata[255];
1356 	ret = local_memset(rand_adata, 0, sizeof(rand_adata)); EG(ret, err);
1357 	/* The case of EDDSA25519CTX and SM2 needs a non NULL context (ancillary data).
1358 	 * Create a random string of size <= 255 for this.
1359 	 */
1360 	/*
1361 	 * In the case of BIGN and DBIGN, the ancillary data have a structure containing the OID as well
1362 	 * as an optional generation token.
1363 	 */
1364 #endif
1365 	ret = local_memset(test_name, 0, sizeof(test_name)); EG(ret, err);
1366 
1367 	MUST_HAVE((sig != NULL), ret, err);
1368 	MUST_HAVE((hash != NULL), ret, err);
1369 	MUST_HAVE((ec != NULL), ret, err);
1370 
1371 	crv_name  = (const char *)PARAM_BUF_PTR((ec->params)->name);
1372 
1373 	/* Generate the test name */
1374 	ret = local_memset(test_name, 0, tn_size + 1); EG(ret, err);
1375 	ret = local_strncpy(test_name, sig->name, tn_size); EG(ret, err);
1376 	ret = local_strlen(test_name, &len); EG(ret, err);
1377 	ret = local_strncat(test_name, "-", tn_size - len); EG(ret, err);
1378 	ret = local_strlen(test_name, &len); EG(ret, err);
1379 	ret = local_strncat(test_name, hash->name, tn_size - len); EG(ret, err);
1380 	ret = local_strlen(test_name, &len); EG(ret, err);
1381 	ret = local_strncat(test_name, "/", tn_size - len); EG(ret, err);
1382 	ret = local_strlen(test_name, &len); EG(ret, err);
1383 	ret = local_strncat(test_name, crv_name, tn_size - len); EG(ret, err);
1384 
1385 	/* Create a test */
1386 	t.name = test_name;
1387 	t.ec_str_p = ec->params;
1388 	t.priv_key = NULL;
1389 	t.priv_key_len = 0;
1390 	t.nn_random = NULL;
1391 	t.hash_type = hash->type;
1392 	t.msg = NULL;
1393 	t.msglen = 0;
1394 	t.sig_type = sig->type;
1395 	t.exp_sig = NULL;
1396 	t.exp_siglen = 0;
1397 #if defined(WITH_SIG_EDDSA25519) || defined(WITH_SIG_SM2)
1398 #if defined(WITH_SIG_EDDSA25519) && !defined(WITH_SIG_SM2)
1399 	if(sig->type == EDDSA25519CTX)
1400 #endif
1401 #if !defined(WITH_SIG_EDDSA25519) && defined(WITH_SIG_SM2)
1402 	if(sig->type == SM2)
1403 #endif
1404 #if defined(WITH_SIG_EDDSA25519) && defined(WITH_SIG_SM2)
1405 	if((sig->type == EDDSA25519CTX) || (sig->type == SM2))
1406 #endif
1407 	{
1408 		u8 rand_len = 0;
1409 		ret = get_random((u8 *)&rand_len, sizeof(rand_len)); EG(ret, err);
1410 		ret = get_random((u8 *)rand_adata, (u16)(rand_len % sizeof(rand_adata))); EG(ret, err);
1411 		t.adata = rand_adata;
1412 		t.adata_len = rand_len;
1413 	}
1414 	else
1415 #endif
1416 	{
1417 #if defined(WITH_SIG_BIGN) || defined(WITH_SIG_DBIGN)
1418 #if defined(WITH_SIG_BIGN) && !defined(WITH_SIG_DBIGN)
1419 		if(sig->type == BIGN)
1420 #endif
1421 #if !defined(WITH_SIG_BIGN) && defined(WITH_SIG_DBIGN)
1422 		if(sig->type == DBIGN)
1423 #endif
1424 #if defined(WITH_SIG_BIGN) && defined(WITH_SIG_DBIGN)
1425 		if((sig->type == BIGN) || (sig->type == DBIGN))
1426 #endif
1427 		{
1428 			u16 oid_len = 0;
1429 			u16 t_len = 0;
1430 			ret = get_random((u8 *)rand_adata, sizeof(rand_adata)); EG(ret, err);
1431 
1432 			ret = get_random((u8 *)&oid_len, sizeof(oid_len)); EG(ret, err);
1433 			ret = get_random((u8 *)&t_len, sizeof(oid_len)); EG(ret, err);
1434 
1435 			oid_len = (u8)(oid_len % (sizeof(rand_adata) - 4));
1436 			t_len = (u8)(t_len % (sizeof(rand_adata) - 4 - oid_len));
1437 			rand_adata[0] = (u8)(oid_len >> 8);
1438 			rand_adata[1] = (u8)(oid_len & 0xff);
1439 			rand_adata[2] = (u8)(t_len >> 8);
1440 			rand_adata[3] = (u8)(t_len & 0xff);
1441 			t.adata = rand_adata;
1442 			t.adata_len = (u8)(oid_len + t_len + 4);
1443 		}
1444 		else
1445 #endif
1446 		{
1447 			t.adata = NULL;
1448 			t.adata_len = 0;
1449 		}
1450 	}
1451 
1452 	/* Execute the test */
1453 	ret = ec_import_export_test(&t);
1454 	OPENMP_LOCK();
1455 	ext_printf("[%s] %34s randtests: random import/export "
1456 		   "with sig/verif %s\n", ret ? "-" : "+", t.name,
1457 		   ret ? "failed" : "ok");
1458 	check = 0;
1459 #if defined(WITH_SIG_ECDSA)
1460 	if(t.sig_type == ECDSA){
1461 		check = 1;
1462 	}
1463 #endif
1464 #if defined(WITH_SIG_DECDSA)
1465 	if(t.sig_type == DECDSA){
1466 		check = 1;
1467 	}
1468 #endif
1469 	if(check){
1470 		ext_printf("\t(ECDSA public key recovery also checked!)\n");
1471 	}
1472 
1473 #ifdef USE_CRYPTOFUZZ
1474 #if defined(WITH_SIG_ECDSA)
1475 	if(t.sig_type == ECDSA){
1476 		ext_printf("\t(RAW ECDSA for CRYPTOFUZZ also checked!)\n");
1477 	}
1478 #endif
1479 #if defined(WITH_SIG_ECGDSA)
1480 	if(t.sig_type == ECGDSA){
1481 		ext_printf("\t(RAW ECGDSA for CRYPTOFUZZ also checked!)\n");
1482 	}
1483 #endif
1484 #if defined(WITH_SIG_ECRDSA)
1485 	if(t.sig_type == ECRDSA){
1486 		ext_printf("\t(RAW ECRDSA for CRYPTOFUZZ also checked!)\n");
1487 	}
1488 #endif
1489 #endif
1490 	OPENMP_UNLOCK();
1491 
1492 err:
1493 	return ret;
1494 }
1495 
1496 ATTRIBUTE_WARN_UNUSED_RET int perform_random_sig_verif_test(const char *sig, const char *hash, const char *curve)
1497 {
1498 	unsigned int num_sig_maps, num_hash_maps;
1499 	int ret = 0;
1500 
1501 	/* Compute number of sig and hash maps */
1502 	for (num_sig_maps = 0; ec_sig_maps[num_sig_maps].type != UNKNOWN_ALG; num_sig_maps++) {}
1503 	for (num_hash_maps = 0; hash_maps[num_hash_maps].type != UNKNOWN_HASH_ALG; num_hash_maps++) {}
1504 
1505 	/*
1506 	 * Perform basic sign/verify tests on all the cipher suites
1507 	 * (combination of sign algo/hash function/curve)
1508 	 */
1509 	ext_printf("======= Random sig/verif test ===================\n");
1510 	for (unsigned int i = 0; i < num_sig_maps; i++) {
1511 #ifdef WITH_OPENMP_SELF_TESTS
1512 		#pragma omp parallel for collapse(2)
1513 #endif
1514 		for (unsigned int j = 0; j < num_hash_maps; j++) {
1515 			for (unsigned int k = 0; k < EC_CURVES_NUM; k++) {
1516 				int check;
1517 				if(sig != NULL){
1518 					ret = are_str_equal(ec_sig_maps[i].name, sig, &check); OPENMP_EG(ret, err);
1519 					if(!check){
1520 						continue;
1521 					}
1522 				}
1523 				if(hash != NULL){
1524 					ret = are_str_equal(hash_maps[j].name, hash, &check); OPENMP_EG(ret, err);
1525 					if(!check){
1526 						continue;
1527 					}
1528 				}
1529 				if(curve != NULL){
1530 					ret = are_str_equal((const char*)ec_maps[k].params->name->buf, curve, &check); OPENMP_EG(ret, err);
1531 					if(!check){
1532 						continue;
1533 					}
1534 				}
1535 				/* If we have EDDSA25519 or EDDSA448, we only accept specific hash functions.
1536 				 * Skip the other tests.
1537 				 */
1538 #ifdef WITH_SIG_EDDSA25519
1539 				if((ec_sig_maps[i].type == EDDSA25519) && ((hash_maps[j].type != SHA512) || (ec_maps[k].type != WEI25519))){
1540 					continue;
1541 				}
1542 				if((ec_sig_maps[i].type == EDDSA25519CTX) && ((hash_maps[j].type != SHA512) || (ec_maps[k].type != WEI25519))){
1543 					continue;
1544 				}
1545 				if((ec_sig_maps[i].type == EDDSA25519PH) && ((hash_maps[j].type != SHA512) || (ec_maps[k].type != WEI25519))){
1546 					continue;
1547 				}
1548 #endif
1549 #ifdef WITH_SIG_EDDSA448
1550 				if((ec_sig_maps[i].type == EDDSA448) && ((hash_maps[j].type != SHAKE256) || (ec_maps[k].type != WEI448))){
1551 					continue;
1552 				}
1553 				if((ec_sig_maps[i].type == EDDSA448PH) && ((hash_maps[j].type != SHAKE256) || (ec_maps[k].type != WEI448))){
1554 					continue;
1555 				}
1556 #endif
1557 				ret = rand_sig_verif_test_one(&ec_sig_maps[i],
1558 							      &hash_maps[j],
1559 							      &ec_maps[k]);
1560 				OPENMP_EG(ret, err);
1561 			}
1562 		}
1563 	}
1564 
1565 #ifndef WITH_OPENMP_SELF_TESTS
1566 err:
1567 #endif
1568 	return ret;
1569 }
1570 
1571 #define PERF_NUM_OP		300
1572 #define PERF_BATCH_VERIFICATION 16
1573 
1574 /*
1575  * ECC generic performance test: Returns the number of signatures
1576  * and verifications per second
1577  */
1578 ATTRIBUTE_WARN_UNUSED_RET static int ec_performance_test(const ec_test_case *c,
1579 			       unsigned int *n_perf_sign,
1580 			       unsigned int *n_perf_verif,
1581 			       unsigned int *n_perf_batch_verif,
1582 			       unsigned char *batch_verify_ok)
1583 {
1584 	ec_key_pair kp;
1585 	ec_params params;
1586 	int ret, check;
1587 
1588 	MUST_HAVE(c != NULL, ret, err);
1589 	MUST_HAVE(n_perf_sign != NULL, ret, err);
1590 	MUST_HAVE(n_perf_verif != NULL, ret, err);
1591 	MUST_HAVE((n_perf_batch_verif != NULL) && (batch_verify_ok != NULL), ret, err);
1592 
1593 	ret = local_memset(&kp, 0, sizeof(kp)); EG(ret, err);
1594 
1595 	/* Import EC params from test case */
1596 	ret = import_params(&params, c->ec_str_p);
1597 	if (ret) {
1598 		ext_printf("Error when importing parameters\n");
1599 		goto err;
1600 	}
1601 
1602 	/* Generate, import/export a key pair */
1603 	ret = ec_gen_import_export_kp(&kp, &params, c);
1604 	if (ret) {
1605 		ext_printf("Error at key pair generation/import/export\n");
1606 		goto err;
1607 	}
1608 
1609 	/* Perform test */
1610 	{
1611 		u8 sig[EC_MAX_SIGLEN];
1612 		u8 siglen;
1613 		u8 msg[MAX_BLOCK_SIZE];
1614 		u16 msglen;
1615 		u8 hash_digest_size, hash_block_size;
1616 		/* Time related variables */
1617 		u64 time1, time2, cumulated_time_sign, cumulated_time_verify, cumulated_time_batch_verify;
1618 		unsigned int i;
1619 
1620 		ret = local_memset(sig, 0, sizeof(sig)); EG(ret, err);
1621 		ret = local_memset(msg, 0, sizeof(msg)); EG(ret, err);
1622 
1623 		ret = ec_get_sig_len(&params, c->sig_type, c->hash_type,
1624 			     (u8 *)&siglen);
1625 		if (ret) {
1626 			ext_printf("Error computing effective sig size\n");
1627 			goto err;
1628 		}
1629 
1630 		/*
1631 		 * Random tests to measure performance: We do it on small
1632 		 * messages to "absorb" the hash function cost
1633 		 */
1634 		ret = get_hash_sizes(c->hash_type, &hash_digest_size,
1635 			     &hash_block_size);
1636 		if (ret) {
1637 			ext_printf("Error when getting hash size\n");
1638 			goto err;
1639 		}
1640 		cumulated_time_sign = cumulated_time_verify = cumulated_time_batch_verify = 0;
1641 		for (i = 0; i < PERF_NUM_OP; i++) {
1642 			/* Generate a random message to sign */
1643 			ret = get_random((u8 *)&msglen, sizeof(msglen));
1644 			if (ret) {
1645 				ext_printf("Error when getting random\n");
1646 				goto err;
1647 			}
1648 			msglen = (u16)(msglen % hash_block_size);
1649 			ret = get_random(msg, msglen);
1650 			if (ret) {
1651 				ext_printf("Error when getting random\n");
1652 				goto err;
1653 			}
1654 
1655 			/***** Signature **********/
1656 			ret = get_ms_time(&time1);
1657 			if (ret) {
1658 				ext_printf("Error when getting time\n");
1659 				goto err;
1660 			}
1661 			ret = _ec_sign(sig, siglen, &kp, msg, msglen,
1662 			       c->nn_random, c->sig_type, c->hash_type, c->adata, c->adata_len);
1663 			if (ret) {
1664 				ext_printf("Error when signing\n");
1665 				goto err;
1666 			}
1667 			ret = get_ms_time(&time2);
1668 			if (ret) {
1669 				ext_printf("Error when getting time\n");
1670 				goto err;
1671 			}
1672 			if (time2 < time1) {
1673 				ext_printf("Error: time error (t2 < t1)\n");
1674 				goto err;
1675 			}
1676 			cumulated_time_sign += (time2 - time1);
1677 
1678 			/***** Verification **********/
1679 			ret = get_ms_time(&time1);
1680 			if (ret) {
1681 				ext_printf("Error when getting time\n");
1682 				goto err;
1683 			}
1684 			ret = ec_verify(sig, siglen, &(kp.pub_key), msg, msglen,
1685 					c->sig_type, c->hash_type, c->adata, c->adata_len);
1686 			if (ret) {
1687 				ext_printf("Error when verifying signature\n");
1688 				goto err;
1689 			}
1690 			ret = get_ms_time(&time2);
1691 			if (ret) {
1692 				ext_printf("Error when getting time\n");
1693 				goto err;
1694 			}
1695 			if (time2 < time1) {
1696 				ext_printf("Error: time error (time2 < time1)\n");
1697 				goto err;
1698 			}
1699 			cumulated_time_verify += (time2 - time1);
1700 
1701 			/***** Batch verification **********/
1702 			ret = is_verify_batch_mode_supported(c->sig_type, &check); EG(ret, err);
1703 			if(check){
1704 				unsigned int j;
1705 				const u8 *signatures[PERF_BATCH_VERIFICATION];
1706 				u8 signatures_len[PERF_BATCH_VERIFICATION];
1707 				const u8 *messages[PERF_BATCH_VERIFICATION];
1708 				u32 messages_len[PERF_BATCH_VERIFICATION];
1709 				const ec_pub_key *pub_keys[PERF_BATCH_VERIFICATION];
1710 				const u8 *adatas[PERF_BATCH_VERIFICATION];
1711 				u16 adatas_len[PERF_BATCH_VERIFICATION];
1712 				/* We need 2 * n + 1 scratch pad storage, compute this with max */
1713 				verify_batch_scratch_pad scratch_pad_area[(2 * PERF_BATCH_VERIFICATION) + 1];
1714 				u32 scratch_pad_area_len = sizeof(scratch_pad_area);
1715 
1716 				for(j = 0; j < PERF_BATCH_VERIFICATION; j++){
1717 					signatures[j] = sig;
1718 					signatures_len[j] = siglen;
1719 					messages[j] = msg;
1720 					messages_len[j] = msglen;
1721 					pub_keys[j] = &(kp.pub_key);
1722 					adatas[j] = c->adata;
1723 					adatas_len[j] = c->adata_len;
1724 				}
1725 				ret = get_ms_time(&time1);
1726 				if (ret) {
1727 					ext_printf("Error when getting time\n");
1728 					goto err;
1729 				}
1730 				ret = ec_verify_batch(signatures, signatures_len, pub_keys, messages, messages_len,
1731 						PERF_BATCH_VERIFICATION, c->sig_type, c->hash_type, adatas, adatas_len, scratch_pad_area, &scratch_pad_area_len);
1732 				if(ret){
1733 					ext_printf("Error when verifying signature ec_verify_batch with batch %d\n", PERF_BATCH_VERIFICATION);
1734 					goto err;
1735 				}
1736 				ret = get_ms_time(&time2);
1737 				if (ret) {
1738 					ext_printf("Error when getting time\n");
1739 					goto err;
1740 				}
1741 				if (time2 < time1) {
1742 					ext_printf("Error: time error (time2 < time1)\n");
1743 					goto err;
1744 				}
1745 				cumulated_time_batch_verify += (time2 - time1);
1746 				(*batch_verify_ok) = 1;
1747 			}
1748 			else{
1749 				(*batch_verify_ok) = 0;
1750 			}
1751 		}
1752 
1753 		if (n_perf_sign != NULL) {
1754 			(*n_perf_sign) = (unsigned int)((PERF_NUM_OP * 1000ULL) / cumulated_time_sign);
1755 		}
1756 		if (n_perf_verif != NULL) {
1757 			(*n_perf_verif) = (unsigned int)((PERF_NUM_OP * 1000ULL) / cumulated_time_verify);
1758 		}
1759 		if (n_perf_batch_verif != NULL) {
1760 			if((*batch_verify_ok) == 1){
1761 				(*n_perf_batch_verif) = (unsigned int)((PERF_NUM_OP * PERF_BATCH_VERIFICATION * 1000ULL) / cumulated_time_batch_verify);
1762 			}
1763 			else{
1764 				(*n_perf_batch_verif) = 0;
1765 			}
1766 		}
1767 	}
1768 	ret = 0;
1769  err:
1770 	return ret;
1771 }
1772 
1773 
1774 ATTRIBUTE_WARN_UNUSED_RET static int perf_test_one(const ec_sig_mapping *sig, const hash_mapping *hash,
1775 			 const ec_mapping *ec)
1776 {
1777 	char test_name[MAX_CURVE_NAME_LEN + MAX_HASH_ALG_NAME_LEN +
1778 		       MAX_SIG_ALG_NAME_LEN + 2];
1779 	const unsigned int tn_size = sizeof(test_name) - 1; /* w/o trailing 0 */
1780 	unsigned int n_perf_sign = 0, n_perf_verif = 0, n_perf_batch_verif = 0;
1781 	unsigned char batch_verify_ok = 0;
1782 	const char *crv_name;
1783 	ec_test_case t;
1784 	int ret;
1785 	u32 len;
1786 #if defined(WITH_SIG_EDDSA25519) || defined(WITH_SIG_SM2) || defined(WITH_SIG_BIGN) || defined(WITH_SIG_DBIGN)
1787 	u8 rand_adata[255];
1788 	ret = local_memset(rand_adata, 0, sizeof(rand_adata)); EG(ret, err);
1789 	/* The case of EDDSA25519CTX and SM2 needs a non NULL context (ancillary data).
1790 	 * Create a random string of size <= 255 for this.
1791 	 */
1792 	/*
1793 	 * In the case of BIGN and DBIGN, the ancillary data have a structure containing the OID as well
1794 	 * as an optional generation token.
1795 	 */
1796 #endif
1797 	MUST_HAVE((sig != NULL), ret, err);
1798 	MUST_HAVE((hash != NULL), ret, err);
1799 	MUST_HAVE((ec != NULL), ret, err);
1800 
1801 	ret = local_memset(test_name, 0, sizeof(test_name)); EG(ret, err);
1802 
1803 	crv_name = (const char *)PARAM_BUF_PTR((ec->params)->name);
1804 
1805 	/* Generate the test name */
1806 	ret = local_memset(test_name, 0, tn_size + 1); EG(ret, err);
1807 	ret = local_strncpy(test_name, sig->name, tn_size); EG(ret, err);
1808 	ret = local_strlen(test_name, &len); EG(ret, err);
1809 	ret = local_strncat(test_name, "-", tn_size - len); EG(ret, err);
1810 	ret = local_strlen(test_name, &len); EG(ret, err);
1811 	ret = local_strncat(test_name, hash->name, tn_size - len); EG(ret, err);
1812 	ret = local_strlen(test_name, &len); EG(ret, err);
1813 	ret = local_strncat(test_name, "/", tn_size - len); EG(ret, err);
1814 	ret = local_strlen(test_name, &len); EG(ret, err);
1815 	ret = local_strncat(test_name, crv_name, tn_size - len); EG(ret, err);
1816 
1817 	/* Create a test */
1818 	t.name = test_name;
1819 	t.ec_str_p = ec->params;
1820 	t.priv_key = NULL;
1821 	t.priv_key_len = 0;
1822 	t.nn_random = NULL;
1823 	t.hash_type = hash->type;
1824 	t.msg = NULL;
1825 	t.msglen = 0;
1826 	t.sig_type = sig->type;
1827 	t.exp_sig = NULL;
1828 	t.exp_siglen = 0;
1829 #if defined(WITH_SIG_EDDSA25519) || defined(WITH_SIG_SM2)
1830 #if defined(WITH_SIG_EDDSA25519) && !defined(WITH_SIG_SM2)
1831 	if(sig->type == EDDSA25519CTX)
1832 #endif
1833 #if !defined(WITH_SIG_EDDSA25519) && defined(WITH_SIG_SM2)
1834 	if(sig->type == SM2)
1835 #endif
1836 #if defined(WITH_SIG_EDDSA25519) && defined(WITH_SIG_SM2)
1837 	if((sig->type == EDDSA25519CTX) || (sig->type == SM2))
1838 #endif
1839 	{
1840 		u8 rand_len = 0;
1841 		ret = get_random((u8 *)&rand_len, sizeof(rand_len)); EG(ret, err);
1842 		ret = get_random((u8 *)rand_adata, (u16)(rand_len % sizeof(rand_adata))); EG(ret, err);
1843 		t.adata = rand_adata;
1844 		t.adata_len = rand_len;
1845 	}
1846 	else
1847 #endif
1848 	{
1849 #if defined(WITH_SIG_BIGN) || defined(WITH_SIG_DBIGN)
1850 #if defined(WITH_SIG_BIGN) && !defined(WITH_SIG_DBIGN)
1851 		if(sig->type == BIGN)
1852 #endif
1853 #if !defined(WITH_SIG_BIGN) && defined(WITH_SIG_DBIGN)
1854 		if(sig->type == DBIGN)
1855 #endif
1856 #if defined(WITH_SIG_BIGN) && defined(WITH_SIG_DBIGN)
1857 		if((sig->type == BIGN) || (sig->type == DBIGN))
1858 #endif
1859 		{
1860 			u16 oid_len = 0;
1861 			u16 t_len = 0;
1862 			ret = get_random((u8 *)rand_adata, sizeof(rand_adata)); EG(ret, err);
1863 
1864 			ret = get_random((u8 *)&oid_len, sizeof(oid_len)); EG(ret, err);
1865 			ret = get_random((u8 *)&t_len, sizeof(oid_len)); EG(ret, err);
1866 
1867 			oid_len = (u8)(oid_len % (sizeof(rand_adata) - 4));
1868 			t_len = (u8)(t_len % (sizeof(rand_adata) - 4 - oid_len));
1869 			rand_adata[0] = (u8)(oid_len >> 8);
1870 			rand_adata[1] = (u8)(oid_len & 0xff);
1871 			rand_adata[2] = (u8)(t_len >> 8);
1872 			rand_adata[3] = (u8)(t_len & 0xff);
1873 			t.adata = rand_adata;
1874 			t.adata_len = (u8)(oid_len + t_len + 4);
1875 		}
1876 		else
1877 #endif
1878 		{
1879 			t.adata = NULL;
1880 			t.adata_len = 0;
1881 		}
1882 	}
1883 
1884 	/* Sign and verify some random data during some time */
1885 	ret = ec_performance_test(&t, &n_perf_sign, &n_perf_verif, &n_perf_batch_verif, &batch_verify_ok);
1886 	OPENMP_LOCK();
1887 	if(batch_verify_ok == 1){
1888 		ext_printf("[%s] %30s perf: %u sign/s and %u verif/s, %u batch verif/s (for %u batch)\n",
1889 			   ret ? "-" : "+", t.name, n_perf_sign, n_perf_verif, n_perf_batch_verif, (unsigned int)PERF_BATCH_VERIFICATION);
1890 		if ((n_perf_sign == 0) || (n_perf_verif == 0) || (n_perf_batch_verif == 0)) {
1891 			ext_printf("\t(0 is less than one sig/verif per sec)\n");
1892 		}
1893 	}
1894 	else{
1895 		ext_printf("[%s] %30s perf: %u sign/s and %u verif/s\n",
1896 			   ret ? "-" : "+", t.name, n_perf_sign, n_perf_verif);
1897 		if ((n_perf_sign == 0) || (n_perf_verif == 0)) {
1898 			ext_printf("\t(0 is less than one sig/verif per sec)\n");
1899 		}
1900 	}
1901 	OPENMP_UNLOCK();
1902 
1903 err:
1904 	return ret;
1905 }
1906 
1907 ATTRIBUTE_WARN_UNUSED_RET int perform_performance_test(const char *sig, const char *hash, const char *curve)
1908 {
1909 	unsigned int i, j, k;
1910 	int ret, check;
1911 
1912 	/* Perform performance tests like "openssl speed" command */
1913 	ext_printf("======= Performance test ========================\n");
1914 #ifdef WITH_OPENMP_SELF_TESTS
1915 	ext_printf("== NOTE: OpenMP parallelization is not applied to performance tests ...\n");
1916 	ext_printf("== (because of CPU/cores shared ressources such as caches, BPU, etc.)\n");
1917 #endif
1918 	for (i = 0; ec_sig_maps[i].type != UNKNOWN_ALG; i++) {
1919 		for (j = 0; hash_maps[j].type != UNKNOWN_HASH_ALG; j++) {
1920 			for (k = 0; k < EC_CURVES_NUM; k++) {
1921 				if(sig != NULL){
1922 					ret = are_str_equal(ec_sig_maps[i].name, sig, &check); OPENMP_EG(ret, err);
1923 					if(!check){
1924 						continue;
1925 					}
1926 				}
1927 				if(hash != NULL){
1928 					ret = are_str_equal(hash_maps[j].name, hash, &check); OPENMP_EG(ret, err);
1929 					if(!check){
1930 						continue;
1931 					}
1932 				}
1933 				if(curve != NULL){
1934 					ret = are_str_equal((const char*)ec_maps[k].params->name->buf, curve, &check); OPENMP_EG(ret, err);
1935 					if(!check){
1936 						continue;
1937 					}
1938 				}
1939 				/* If we have EDDSA25519 or EDDSA448, we only accept specific hash functions.
1940 				 * Skip the other tests.
1941 				 */
1942 #ifdef WITH_SIG_EDDSA25519
1943 				if((ec_sig_maps[i].type == EDDSA25519) && ((hash_maps[j].type != SHA512) || (ec_maps[k].type != WEI25519))){
1944 					continue;
1945 				}
1946 				if((ec_sig_maps[i].type == EDDSA25519CTX) && ((hash_maps[j].type != SHA512) || (ec_maps[k].type != WEI25519))){
1947 					continue;
1948 				}
1949 				if((ec_sig_maps[i].type == EDDSA25519PH) && ((hash_maps[j].type != SHA512) || (ec_maps[k].type != WEI25519))){
1950 					continue;
1951 				}
1952 #endif
1953 #ifdef WITH_SIG_EDDSA448
1954 				if((ec_sig_maps[i].type == EDDSA448) && ((hash_maps[j].type != SHAKE256) || (ec_maps[k].type != WEI448))){
1955 					continue;
1956 				}
1957 				if((ec_sig_maps[i].type == EDDSA448PH) && ((hash_maps[j].type != SHAKE256) || (ec_maps[k].type != WEI448))){
1958 					continue;
1959 				}
1960 #endif
1961 				ret = perf_test_one(&ec_sig_maps[i],
1962 						    &hash_maps[j],
1963 						    &ec_maps[k]);
1964 				if (ret) {
1965 					goto err;
1966 				}
1967 			}
1968 		}
1969 	}
1970 
1971 	return 0;
1972 
1973 err:
1974 	return -1;
1975 }
1976