/ external / libecc / src / tests / ec_self_tests_core.c
ec_self_tests_core.c
   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  
  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   */
 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   */
 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   */
 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   */
 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  
 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   */
 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  }