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/sig/sig_algs.h> 17 18 /* 19 * Generic private key generation (generate a scalar in ]0,q[ 20 * Common accross many schemes, but might diverge for some. 21 */ 22 int generic_gen_priv_key(ec_priv_key *priv_key) 23 { 24 nn_src_t q; 25 int ret; 26 27 ret = priv_key_check_initialized(priv_key); EG(ret, err); 28 29 q = &(priv_key->params->ec_gen_order); 30 31 /* Get a random value in ]0,q[ where q is the group generator order */ 32 ret = nn_get_random_mod(&(priv_key->x), q); 33 34 err: 35 return ret; 36 } 37 38 /* Private key generation function per signature scheme */ 39 int gen_priv_key(ec_priv_key *priv_key) 40 { 41 const ec_sig_mapping *sm; 42 int ret; 43 u8 i; 44 45 ret = priv_key_check_initialized(priv_key); EG(ret, err); 46 47 ret = -1; 48 for (i = 0, sm = &ec_sig_maps[i]; 49 sm->type != UNKNOWN_ALG; sm = &ec_sig_maps[++i]) { 50 if (sm->type == priv_key->key_type) { 51 /* NOTE: since sm is initalized with a structure 52 * coming from a const source, we can safely call 53 * the callback here, but better safe than sorry. 54 */ 55 MUST_HAVE((sm->gen_priv_key != NULL), ret, err); 56 ret = sm->gen_priv_key(priv_key); 57 break; 58 } 59 } 60 61 err: 62 return ret; 63 } 64 65 /* 66 * Generic function to init a uninitialized public key from an initialized 67 * private key. The function uses the expected logic to derive the key 68 * (e.g. Y=xG, Y=(x^-1)G, etc). It returns -1 on error (i.e. if the signature 69 * alg is unknown) in which case the public key has not been initialized. 70 * It returns 0 on success. 71 */ 72 int init_pubkey_from_privkey(ec_pub_key *pub_key, ec_priv_key *priv_key) 73 { 74 const ec_sig_mapping *sm; 75 int ret; 76 u8 i; 77 78 ret = priv_key_check_initialized(priv_key); EG(ret, err); 79 80 ret = -1; 81 for (i = 0, sm = &ec_sig_maps[i]; 82 sm->type != UNKNOWN_ALG; sm = &ec_sig_maps[++i]) { 83 if (sm->type == priv_key->key_type) { 84 /* NOTE: since sm is initalized with a structure 85 * coming from a const source, we can safely call 86 * the callback here, but better safe than sorry. 87 */ 88 MUST_HAVE((sm->init_pub_key != NULL), ret, err); 89 ret = sm->init_pub_key(pub_key, priv_key); 90 break; 91 } 92 } 93 94 err: 95 return ret; 96 } 97 98 /* 99 * On success, 0 is returned and out parameter 'sig_mapping' provides a 100 * pointer to the ec_sig_mapping matching given input parameter 101 * 'sig_name' (a null-terminated string, e.g. "ECDSA"). -1 is returned on error 102 * in which case 'sig_mapping' is not meaningful. 103 */ 104 int get_sig_by_name(const char *ec_sig_name, const ec_sig_mapping **sig_mapping) 105 { 106 const ec_sig_mapping *sm; 107 int ret, check; 108 u8 i; 109 110 MUST_HAVE((ec_sig_name != NULL), ret, err); 111 MUST_HAVE((sig_mapping != NULL), ret, err); 112 113 ret = -1; 114 for (i = 0, sm = &ec_sig_maps[i]; 115 sm->type != UNKNOWN_ALG; sm = &ec_sig_maps[++i]) { 116 if((!are_str_equal(ec_sig_name, sm->name, &check)) && check){ 117 (*sig_mapping) = sm; 118 ret = 0; 119 break; 120 } 121 } 122 123 err: 124 return ret; 125 } 126 127 /* 128 * On success, 0 is returned and out parameter 'sig_mapping' provides a 129 * pointer to the ec_sig_mapping matching given input parameter 130 * 'sig_type' (e.g. ECDSA, ECSDA). -1 is returned on error in which 131 * case 'sig_mapping' is not meaningful. 132 */ 133 int get_sig_by_type(ec_alg_type sig_type, const ec_sig_mapping **sig_mapping) 134 { 135 const ec_sig_mapping *sm; 136 int ret; 137 u8 i; 138 139 MUST_HAVE((sig_mapping != NULL), ret, err); 140 141 ret = -1; 142 for (i = 0, sm = &ec_sig_maps[i]; 143 sm->type != UNKNOWN_ALG; sm = &ec_sig_maps[++i]) { 144 if (sm->type == sig_type) { 145 (*sig_mapping) = sm; 146 ret = 0; 147 break; 148 } 149 } 150 151 err: 152 return ret; 153 } 154 155 /* 156 * Here, we provide a helper that sanity checks the provided signature 157 * mapping against the constant ones. 0 is returned on success, -1 on 158 * error. 159 */ 160 int ec_sig_mapping_callbacks_sanity_check(const ec_sig_mapping *sig) 161 { 162 const ec_sig_mapping *sm; 163 int ret = -1, check; 164 u8 i; 165 166 MUST_HAVE((sig != NULL), ret, err); 167 168 /* We just check is our mapping is indeed 169 * one of the registered mappings. 170 */ 171 for (i = 0, sm = &ec_sig_maps[i]; 172 sm->type != UNKNOWN_ALG; sm = &ec_sig_maps[++i]) { 173 if (sm->type == sig->type){ 174 if ((!are_str_equal_nlen(sm->name, sig->name, MAX_SIG_ALG_NAME_LEN, &check)) && (!check)){ 175 goto err; 176 } else if (sm->siglen != sig->siglen){ 177 goto err; 178 } else if (sm->gen_priv_key != sig->gen_priv_key){ 179 goto err; 180 } else if (sm->init_pub_key != sig->init_pub_key){ 181 goto err; 182 } else if (sm->sign_init != sig->sign_init){ 183 goto err; 184 } else if (sm->sign_update != sig->sign_update){ 185 goto err; 186 } else if (sm->sign_finalize != sig->sign_finalize){ 187 goto err; 188 } else if (sm->sign != sig->sign){ 189 goto err; 190 } else if (sm->verify_init != sig->verify_init){ 191 goto err; 192 } else if (sm->verify_update != sig->verify_update){ 193 goto err; 194 } else if (sm->verify_finalize != sig->verify_finalize){ 195 goto err; 196 } else if (sm->verify != sig->verify){ 197 goto err; 198 } else{ 199 ret = 0; 200 } 201 } 202 } 203 204 err: 205 return ret; 206 } 207 208 /* 209 * Sanity checks of a signature context to see if everything seems OK. 0 is 210 * returned on cucces, -1 on error. 211 */ 212 int ec_sig_ctx_callbacks_sanity_check(const struct ec_sign_context *sig_ctx) 213 { 214 int ret; 215 216 MUST_HAVE((sig_ctx != NULL) && (sig_ctx->ctx_magic == SIG_SIGN_MAGIC), ret, err); 217 218 ret = hash_mapping_callbacks_sanity_check(sig_ctx->h); EG(ret, err); 219 ret = ec_sig_mapping_callbacks_sanity_check(sig_ctx->sig); 220 221 err: 222 return ret; 223 } 224 225 /* 226 * Sanity check of a verification context to see if everything seems 227 * OK. 0 is returned on success, -1 on error. 228 */ 229 int ec_verify_ctx_callbacks_sanity_check(const struct ec_verify_context *verify_ctx) 230 { 231 int ret; 232 233 MUST_HAVE((verify_ctx != NULL) && (verify_ctx->ctx_magic == SIG_VERIFY_MAGIC), ret, err); 234 235 ret = hash_mapping_callbacks_sanity_check(verify_ctx->h); EG(ret, err); 236 ret = ec_sig_mapping_callbacks_sanity_check(verify_ctx->sig); 237 238 err: 239 return ret; 240 } 241 242 243 /* 244 * Compute generic effective signature length (in bytes) depending on the curve 245 * parameters, the signature algorithm and the hash function. On success, 0 is 246 * returned and The signature length is returned using 'siglen' parameter. -1 is 247 * returned on error. 248 */ 249 int ec_get_sig_len(const ec_params *params, ec_alg_type sig_type, 250 hash_alg_type hash_type, u8 *siglen) 251 { 252 const ec_sig_mapping *sm; 253 u8 digest_size = 0; 254 u8 block_size = 0; 255 int ret; 256 u8 i; 257 258 MUST_HAVE(((params != NULL) && (siglen != NULL)), ret, err); 259 260 ret = get_hash_sizes(hash_type, &digest_size, &block_size); EG(ret, err); 261 262 ret = -1; 263 for (i = 0, sm = &ec_sig_maps[i]; 264 sm->type != UNKNOWN_ALG; sm = &ec_sig_maps[++i]) { 265 if (sm->type == sig_type) { 266 /* NOTE: since sm is initalized with a structure 267 * coming from a const source, we can safely call 268 * the callback here, but better safe than sorry. 269 */ 270 MUST_HAVE((sm->siglen != NULL), ret, err); 271 ret = sm->siglen(params->ec_fp.p_bitlen, 272 params->ec_gen_order_bitlen, 273 digest_size, block_size, siglen); 274 break; 275 } 276 } 277 278 err: 279 return ret; 280 } 281 282 /* Generic signature */ 283 284 /* 285 * Core version of generic signature initialization function. Its purpose 286 * is to initialize given sign context structure 'ctx' based on given key pair, 287 * nn random function, signature and hash types. This version allows passing 288 * a specific nn random function. It returns 0 on success, -1 on error. 289 * 290 * The random function is expected to initialize a nn 'out' with a value taken 291 * uniformly at random in [1, q-1]. It returns 0 on success and -1 on error. See 292 * nn_get_random_mod() in nn_rand.c for a function that fits the dscription. 293 */ 294 int _ec_sign_init(struct ec_sign_context *ctx, 295 const ec_key_pair *key_pair, 296 int (*rand) (nn_t out, nn_src_t q), 297 ec_alg_type sig_type, hash_alg_type hash_type, 298 const u8 *adata, u16 adata_len) 299 { 300 const ec_sig_mapping *sm; 301 const hash_mapping *hm; 302 int ret; 303 u8 i; 304 305 MUST_HAVE((ctx != NULL), ret, err); 306 307 ret = key_pair_check_initialized_and_type(key_pair, sig_type); EG(ret, err); 308 309 /* We first need to get the specific hash structure */ 310 ret = -1; 311 for (i = 0, hm = &hash_maps[i]; 312 hm->type != UNKNOWN_HASH_ALG; hm = &hash_maps[++i]) { 313 if (hm->type == hash_type) { 314 ret = 0; 315 break; 316 } 317 } 318 if (ret) { 319 goto err; 320 } 321 322 /* Now, let's try and get the specific key alg which was requested */ 323 ret = -1; 324 for (i = 0, sm = &ec_sig_maps[i]; 325 sm->type != UNKNOWN_ALG; sm = &ec_sig_maps[++i]) { 326 if ((sm->type == sig_type) && (sm->sign_init != NULL)) { 327 ret = 0; 328 break; 329 } 330 } 331 if (ret) { 332 goto err; 333 } 334 335 #ifdef NO_KNOWN_VECTORS 336 /* 337 * NOTE: when we do not need self tests for known vectors, 338 * we can be strict about random function handler! 339 * We only use our internal method to provide random integers 340 * (which avoids honest mistakes ...). 341 * 342 * This also allows us to avoid the corruption of such a pointer 343 * in our signature contexts. 344 */ 345 if (rand) { 346 MUST_HAVE((rand == nn_get_random_mod), ret, err); 347 } 348 rand = nn_get_random_mod; 349 #else 350 /* Use given random function if provided or fallback to ours */ 351 if (!rand) { 352 rand = nn_get_random_mod; 353 } 354 #endif 355 /* Sanity checks on our mappings */ 356 ret = hash_mapping_sanity_check(hm); EG(ret, err); 357 ret = sig_mapping_sanity_check(sm); EG(ret, err); 358 359 /* Initialize context for specific signature function */ 360 ret = local_memset(ctx, 0, sizeof(struct ec_sign_context)); EG(ret, err); 361 ctx->key_pair = key_pair; 362 ctx->rand = rand; 363 ctx->h = hm; 364 ctx->sig = sm; 365 ctx->adata = adata; 366 ctx->adata_len = adata_len; 367 ctx->ctx_magic = SIG_SIGN_MAGIC; 368 369 /* 370 * NOTE: since sm has been previously initalized with a structure 371 * coming from a const source, we can safely call the callback here. 372 */ 373 ret = sm->sign_init(ctx); 374 375 err: 376 if (ret && (ctx != NULL)) { 377 /* Clear the whole context to prevent future reuse */ 378 IGNORE_RET_VAL(local_memset(ctx, 0, sizeof(struct ec_sign_context))); 379 } 380 381 return ret; 382 } 383 384 /* 385 * Same as previous but for public use; it forces our internal nn random 386 * function (nn_get_random_mod()). Returns 0 on success, -1 on error. 387 */ 388 int ec_sign_init(struct ec_sign_context *ctx, const ec_key_pair *key_pair, 389 ec_alg_type sig_type, hash_alg_type hash_type, 390 const u8 *adata, u16 adata_len) 391 { 392 return _ec_sign_init(ctx, key_pair, NULL, sig_type, hash_type, 393 adata, adata_len); 394 } 395 396 /* 397 * Signature update function. Returns 0 on success, -1 on error. On error, 398 * signature context is zeroized and is no more usable. 399 */ 400 int ec_sign_update(struct ec_sign_context *ctx, const u8 *chunk, u32 chunklen) 401 { 402 int ret; 403 404 /* Sanity checks */ 405 ret = sig_sign_check_initialized(ctx); EG(ret, err); 406 ret = sig_mapping_sanity_check(ctx->sig); EG(ret, err); 407 ret = hash_mapping_sanity_check(ctx->h); EG(ret, err); 408 ret = ec_sig_ctx_callbacks_sanity_check(ctx); EG(ret, err); 409 ret = ctx->sig->sign_update(ctx, chunk, chunklen); 410 411 err: 412 if (ret && (ctx != NULL)) { 413 /* Clear the whole context to prevent future reuse */ 414 IGNORE_RET_VAL(local_memset(ctx, 0, sizeof(struct ec_sign_context))); 415 } 416 417 return ret; 418 } 419 420 /* 421 * Signature finalization function. Returns 0 on success, -1 on error. 422 * Upon call, the signature context is cleared to prevent future use. 423 */ 424 int ec_sign_finalize(struct ec_sign_context *ctx, u8 *sig, u8 siglen) 425 { 426 int ret; 427 428 /* Sanity checks */ 429 ret = sig_sign_check_initialized(ctx); EG(ret, err); 430 ret = sig_mapping_sanity_check(ctx->sig); EG(ret, err); 431 ret = hash_mapping_sanity_check(ctx->h); EG(ret, err); 432 ret = ec_sig_ctx_callbacks_sanity_check(ctx); EG(ret, err); 433 ret = ctx->sig->sign_finalize(ctx, sig, siglen); 434 435 err: 436 if (ctx != NULL) { 437 /* Clear the whole context to prevent future reuse */ 438 IGNORE_RET_VAL(local_memset(ctx, 0, sizeof(struct ec_sign_context))); 439 } 440 441 return ret; 442 } 443 444 /* 445 * Single call version of signature function (init, update and finalize). It 446 * returns 0 on success, -1 on error. This version allows passing a custom 447 * random function. This is useful for test vectors but should be done with 448 * care. 449 * 450 * The random function is expected to initialize a nn 'out' with a value taken 451 * uniformly at random in [1, q-1]. It returns 0 on success and -1 on error. See 452 * nn_get_random_mod() in nn_rand.c for a function that fits the dscription. 453 */ 454 int generic_ec_sign(u8 *sig, u8 siglen, const ec_key_pair *key_pair, 455 const u8 *m, u32 mlen, 456 int (*rand) (nn_t out, nn_src_t q), 457 ec_alg_type sig_type, hash_alg_type hash_type, 458 const u8 *adata, u16 adata_len) 459 { 460 struct ec_sign_context ctx; 461 int ret; 462 463 ret = _ec_sign_init(&ctx, key_pair, rand, sig_type, 464 hash_type, adata, adata_len); EG(ret, err); 465 ret = ec_sign_update(&ctx, m, mlen); EG(ret, err); 466 ret = ec_sign_finalize(&ctx, sig, siglen); 467 468 err: 469 return ret; 470 } 471 472 473 int _ec_sign(u8 *sig, u8 siglen, const ec_key_pair *key_pair, 474 const u8 *m, u32 mlen, 475 int (*rand) (nn_t out, nn_src_t q), 476 ec_alg_type sig_type, hash_alg_type hash_type, 477 const u8 *adata, u16 adata_len) 478 { 479 const ec_sig_mapping *sm; 480 int ret; 481 482 ret = get_sig_by_type(sig_type, &sm); EG(ret, err); 483 MUST_HAVE(((sm != NULL) && (sm->sign != NULL)), ret, err); 484 485 ret = sm->sign(sig, siglen, key_pair, m, mlen, rand, 486 sig_type, hash_type, adata, adata_len); 487 488 err: 489 return ret; 490 } 491 492 /* 493 * Same as previous but for public use; it forces our internal nn random 494 * function (nn_get_random_mod()) by pasing NULL for 'rand' argument 495 * _ec_sign(). Returns 0 on success, -1 on error. 496 */ 497 int ec_sign(u8 *sig, u8 siglen, const ec_key_pair *key_pair, 498 const u8 *m, u32 mlen, 499 ec_alg_type sig_type, hash_alg_type hash_type, 500 const u8 *adata, u16 adata_len) 501 { 502 return _ec_sign(sig, siglen, key_pair, m, mlen, 503 NULL, sig_type, hash_type, adata, adata_len); 504 } 505 506 /* 507 * Generic signature verification initialization function. Returns 0 on success, 508 * -1 on error. On error, verification context is cleared to prevent further 509 * reuse. 510 */ 511 int ec_verify_init(struct ec_verify_context *ctx, const ec_pub_key *pub_key, 512 const u8 *sig, u8 siglen, 513 ec_alg_type sig_type, hash_alg_type hash_type, 514 const u8 *adata, u16 adata_len) 515 { 516 const ec_sig_mapping *sm; 517 const hash_mapping *hm; 518 u8 i; 519 int ret; 520 521 MUST_HAVE((ctx != NULL), ret, err); 522 523 ret = pub_key_check_initialized_and_type(pub_key, sig_type); EG(ret, err); 524 525 /* We first need to get the specific hash structure */ 526 ret = -1; 527 for (i = 0, hm = &hash_maps[i]; 528 hm->type != UNKNOWN_HASH_ALG; hm = &hash_maps[++i]) { 529 if (hm->type == hash_type) { 530 ret = 0; 531 break; 532 } 533 } 534 if (ret) { 535 goto err; 536 } 537 538 /* 539 * Now, let's try and get the specific key algorithm which was 540 * requested 541 */ 542 ret = -1; 543 for (i = 0, sm = &ec_sig_maps[i]; 544 sm->type != UNKNOWN_ALG; sm = &ec_sig_maps[++i]) { 545 if ((sm->type == sig_type) && (sm->verify_init != NULL)) { 546 ret = 0; 547 break; 548 } 549 } 550 if (ret) { 551 goto err; 552 } 553 554 /* Sanity checks on our mappings */ 555 ret = hash_mapping_sanity_check(hm); EG(ret, err); 556 ret = sig_mapping_sanity_check(sm); EG(ret, err); 557 558 /* Initialize context for specific signature function */ 559 ret = local_memset(ctx, 0, sizeof(struct ec_verify_context)); EG(ret, err); 560 ctx->pub_key = pub_key; 561 ctx->h = hm; 562 ctx->sig = sm; 563 ctx->adata = adata; 564 ctx->adata_len = adata_len; 565 ctx->ctx_magic = SIG_VERIFY_MAGIC; 566 567 /* 568 * NOTE: since sm has been previously initalized with a structure 569 * coming from a const source, we can safely call the callback 570 * here. 571 */ 572 ret = sm->verify_init(ctx, sig, siglen); 573 574 err: 575 576 if (ret && (ctx != NULL)) { 577 /* Clear the whole context to prevent future reuse */ 578 IGNORE_RET_VAL(local_memset(ctx, 0, sizeof(struct ec_verify_context))); 579 } 580 581 return ret; 582 } 583 584 /* 585 * Signature verification update function. Returns 0 on success, -1 on error. 586 * On error, verification context is cleared to prevent further reuse. 587 */ 588 int ec_verify_update(struct ec_verify_context *ctx, 589 const u8 *chunk, u32 chunklen) 590 { 591 int ret; 592 593 ret = sig_verify_check_initialized(ctx); EG(ret, err); 594 ret = sig_mapping_sanity_check(ctx->sig); EG(ret, err); 595 ret = hash_mapping_sanity_check(ctx->h); EG(ret, err); 596 597 /* Since we call a callback, sanity check our contexts */ 598 ret = ec_verify_ctx_callbacks_sanity_check(ctx); EG(ret, err); 599 ret = ctx->sig->verify_update(ctx, chunk, chunklen); 600 601 err: 602 if (ret && (ctx != NULL)) { 603 /* Clear the whole context to prevent future reuse */ 604 IGNORE_RET_VAL(local_memset(ctx, 0, sizeof(struct ec_verify_context))); 605 } 606 607 return ret; 608 } 609 610 /* 611 * Signature verification finalize function. Returns 0 on success, -1 on error. 612 * On error, verification context is cleared to prevent further reuse. 613 */ 614 int ec_verify_finalize(struct ec_verify_context *ctx) 615 { 616 int ret; 617 618 ret = sig_verify_check_initialized(ctx); EG(ret, err); 619 ret = sig_mapping_sanity_check(ctx->sig); EG(ret, err); 620 ret = hash_mapping_sanity_check(ctx->h); EG(ret, err); 621 622 /* Since we call a callback, sanity check our contexts */ 623 ret = ec_verify_ctx_callbacks_sanity_check(ctx); EG(ret, err); 624 ret = ctx->sig->verify_finalize(ctx); 625 626 err: 627 if (ret && (ctx != NULL)) { 628 /* Clear the whole context to prevent future reuse */ 629 IGNORE_RET_VAL(local_memset(ctx, 0, sizeof(struct ec_verify_context))); 630 } 631 return ret; 632 } 633 634 /* 635 * Single call version of signature verification function (init, update and 636 * finalize). It returns 0 on success, -1 on error. 637 */ 638 int generic_ec_verify(const u8 *sig, u8 siglen, const ec_pub_key *pub_key, 639 const u8 *m, u32 mlen, 640 ec_alg_type sig_type, hash_alg_type hash_type, 641 const u8 *adata, u16 adata_len) 642 { 643 struct ec_verify_context ctx; 644 int ret; 645 646 ret = ec_verify_init(&ctx, pub_key, sig, siglen, sig_type, 647 hash_type, adata, adata_len); EG(ret, err); 648 ret = ec_verify_update(&ctx, m, mlen); EG(ret, err); 649 ret = ec_verify_finalize(&ctx); 650 651 err: 652 return ret; 653 } 654 655 int ec_verify(const u8 *sig, u8 siglen, const ec_pub_key *pub_key, 656 const u8 *m, u32 mlen, 657 ec_alg_type sig_type, hash_alg_type hash_type, 658 const u8 *adata, u16 adata_len) 659 { 660 661 const ec_sig_mapping *sm; 662 int ret; 663 664 ret = get_sig_by_type(sig_type, &sm); EG(ret, err); 665 666 MUST_HAVE((sm != NULL) && (sm->verify != NULL), ret, err); 667 668 ret = sm->verify(sig, siglen, pub_key, m, mlen, sig_type, 669 hash_type, adata, adata_len); 670 671 err: 672 return ret; 673 } 674 675 int ec_verify_batch(const u8 **s, const u8 *s_len, const ec_pub_key **pub_keys, 676 const u8 **m, const u32 *m_len, u32 num, ec_alg_type sig_type, 677 hash_alg_type hash_type, const u8 **adata, const u16 *adata_len, 678 verify_batch_scratch_pad *scratch_pad_area, u32 *scratch_pad_area_len) 679 { 680 681 const ec_sig_mapping *sm; 682 int ret; 683 684 ret = get_sig_by_type(sig_type, &sm); EG(ret, err); 685 686 MUST_HAVE((sm != NULL) && (sm->verify_batch != NULL), ret, err); 687 688 ret = sm->verify_batch(s, s_len, pub_keys, m, m_len, num, sig_type, 689 hash_type, adata, adata_len, 690 scratch_pad_area, scratch_pad_area_len); 691 692 err: 693 return ret; 694 } 695 696 /* 697 * Import a signature with structured data containing information about the EC 698 * algorithm type as well as the hash function used to produce the signature. 699 * The function returns 0 on success, -1 on error. out parameters (sig_type, 700 * hash_type, curve_name should only be considered on success. 701 */ 702 int ec_structured_sig_import_from_buf(u8 *sig, u32 siglen, 703 const u8 *out_buf, u32 outlen, 704 ec_alg_type * sig_type, 705 hash_alg_type * hash_type, 706 u8 curve_name[MAX_CURVE_NAME_LEN]) 707 { 708 u32 metadata_len = (3 * sizeof(u8)); 709 int ret; 710 711 MUST_HAVE((out_buf != NULL) && (sig_type != NULL) && 712 (hash_type != NULL) && (curve_name != NULL), ret, err); 713 /* We only deal with signatures of length < 256 */ 714 MUST_HAVE((siglen <= EC_MAX_SIGLEN) && (sig != NULL), ret, err); 715 716 /* We first import the metadata consisting of: 717 * - One byte = the EC algorithm type 718 * - One byte = the hash algorithm type 719 * - One byte = the curve type (FRP256V1, ...) 720 */ 721 MUST_HAVE((outlen <= (siglen + metadata_len)), ret, err); 722 723 *sig_type = (ec_alg_type)out_buf[0]; 724 *hash_type = (hash_alg_type)out_buf[1]; 725 ret = ec_get_curve_name_by_type((ec_curve_type) out_buf[2], 726 curve_name, MAX_CURVE_NAME_LEN); EG(ret, err); 727 728 /* Copy the raw signature */ 729 ret = local_memcpy(sig, out_buf + metadata_len, siglen); 730 731 err: 732 return ret; 733 } 734 735 /* 736 * Export a signature with structured data containing information about the 737 * EC algorithm type as well as the hash function used to produce it. The 738 * function returns 0 on success, -1 on error. 739 */ 740 int ec_structured_sig_export_to_buf(const u8 *sig, u32 siglen, 741 u8 *out_buf, u32 outlen, 742 ec_alg_type sig_type, 743 hash_alg_type hash_type, 744 const u8 745 curve_name[MAX_CURVE_NAME_LEN]) 746 { 747 u32 metadata_len = (3 * sizeof(u8)); 748 u32 len; 749 u8 curve_name_len; 750 ec_curve_type curve_type; 751 int ret; 752 753 MUST_HAVE((out_buf != NULL) && (curve_name != NULL), ret, err); 754 /* We only deal with signatures of length < 256 */ 755 MUST_HAVE((siglen <= EC_MAX_SIGLEN) && (sig != NULL), ret, err); 756 757 /* We first export the metadata consisting of: 758 * - One byte = the EC algorithm type 759 * - One byte = the hash algorithm type 760 * - One byte = the curve type (FRP256V1, ...) 761 * 762 */ 763 MUST_HAVE(outlen >= (siglen + metadata_len), ret, err); 764 765 out_buf[0] = (u8)sig_type; 766 out_buf[1] = (u8)hash_type; 767 ret = local_strlen((const char *)curve_name, &len); EG(ret, err); 768 len += 1; 769 MUST_HAVE((len < 256), ret, err); 770 curve_name_len = (u8)len; 771 ret = ec_get_curve_type_by_name(curve_name, curve_name_len, &curve_type); EG(ret, err); 772 out_buf[2] = (u8)curve_type; 773 MUST_HAVE((out_buf[2] != UNKNOWN_CURVE), ret, err); 774 775 /* Copy the raw signature */ 776 ret = local_memcpy(out_buf + metadata_len, sig, siglen); 777 778 err: 779 return ret; 780 } 781 782 783 /* Signature finalization function */ 784 int unsupported_sign_init(struct ec_sign_context * ctx) 785 { 786 /* Quirk to avoid unused variables */ 787 FORCE_USED_VAR(ctx); 788 789 /* Return an error in any case here */ 790 return -1; 791 } 792 793 int unsupported_sign_update(struct ec_sign_context * ctx, 794 const u8 *chunk, u32 chunklen) 795 { 796 /* Quirk to avoid unused variables */ 797 FORCE_USED_VAR(ctx); 798 FORCE_USED_VAR(chunk); 799 FORCE_USED_VAR(chunklen); 800 801 /* Return an error in any case here */ 802 return -1; 803 } 804 805 int unsupported_sign_finalize(struct ec_sign_context *ctx, u8 *sig, u8 siglen) 806 { 807 /* Quirk to avoid unused variables */ 808 FORCE_USED_VAR(ctx); 809 FORCE_USED_VAR(sig); 810 FORCE_USED_VAR(siglen); 811 812 /* Return an error in any case here */ 813 return -1; 814 } 815 816 int unsupported_verify_init(struct ec_verify_context * ctx, 817 const u8 *sig, u8 siglen) 818 { 819 /* Quirk to avoid unused variables */ 820 FORCE_USED_VAR(ctx); 821 FORCE_USED_VAR(sig); 822 FORCE_USED_VAR(siglen); 823 824 /* Return an error in any case here */ 825 return -1; 826 } 827 828 int unsupported_verify_update(struct ec_verify_context * ctx, 829 const u8 *chunk, u32 chunklen) 830 { 831 /* Quirk to avoid unused variables */ 832 FORCE_USED_VAR(ctx); 833 FORCE_USED_VAR(chunk); 834 FORCE_USED_VAR(chunklen); 835 836 /* Return an error in any case here */ 837 return -1; 838 } 839 840 int unsupported_verify_finalize(struct ec_verify_context * ctx) 841 { 842 /* Quirk to avoid unused variables */ 843 FORCE_USED_VAR(ctx); 844 845 /* Return an error in any case here */ 846 return -1; 847 } 848 849 /* Unsupported batch verification */ 850 int unsupported_verify_batch(const u8 **s, const u8 *s_len, const ec_pub_key **pub_keys, 851 const u8 **m, const u32 *m_len, u32 num, ec_alg_type sig_type, 852 hash_alg_type hash_type, const u8 **adata, const u16 *adata_len, 853 verify_batch_scratch_pad *scratch_pad_area, u32 *scratch_pad_area_len) 854 { 855 /* Quirk to avoid unused variables */ 856 FORCE_USED_VAR(s); 857 FORCE_USED_VAR(pub_keys); 858 FORCE_USED_VAR(m); 859 FORCE_USED_VAR(num); 860 FORCE_USED_VAR(sig_type); 861 FORCE_USED_VAR(hash_type); 862 FORCE_USED_VAR(adata); 863 FORCE_USED_VAR(s_len); 864 FORCE_USED_VAR(m_len); 865 FORCE_USED_VAR(adata_len); 866 FORCE_USED_VAR(scratch_pad_area); 867 FORCE_USED_VAR(scratch_pad_area_len); 868 869 /* Return an error in any case here */ 870 return -1; 871 } 872 873 /* This function returns 1 in 'check' if the init/update/finalize mode 874 * is supported by the signature algorithm, 0 otherwise. 875 * 876 * Return value is 0 on success, -1 on error. 'check' is only meaningful on 877 * success. 878 */ 879 int is_sign_streaming_mode_supported(ec_alg_type sig_type, int *check) 880 { 881 int ret; 882 const ec_sig_mapping *sig; 883 884 MUST_HAVE((check != NULL), ret, err); 885 886 ret = get_sig_by_type(sig_type, &sig); EG(ret, err); 887 MUST_HAVE((sig != NULL), ret, err); 888 889 if ((sig->sign_init == unsupported_sign_init) || 890 (sig->sign_update == unsupported_sign_update) || 891 (sig->sign_finalize == unsupported_sign_finalize)) { 892 (*check) = 0; 893 } 894 else{ 895 (*check) = 1; 896 } 897 898 err: 899 return ret; 900 } 901 902 /* This function returns 1 in 'check' if the init/update/finalize mode 903 * is supported by the verification algorithm, 0 otherwise. 904 * 905 * Return value is 0 on success, -1 on error. 'check' is only meaningful on 906 * success. 907 */ 908 int is_verify_streaming_mode_supported(ec_alg_type sig_type, int *check) 909 { 910 int ret; 911 const ec_sig_mapping *sig; 912 913 MUST_HAVE((check != NULL), ret, err); 914 915 ret = get_sig_by_type(sig_type, &sig); EG(ret, err); 916 MUST_HAVE((sig != NULL), ret, err); 917 918 if ((sig->verify_init == unsupported_verify_init) || 919 (sig->verify_update == unsupported_verify_update) || 920 (sig->verify_finalize == unsupported_verify_finalize)) { 921 (*check) = 0; 922 } 923 else{ 924 (*check) = 1; 925 } 926 927 err: 928 return ret; 929 } 930 931 /* This function returns 1 in 'check' if the batch verification mode 932 * is supported by the verification algorithm, 0 otherwise. 933 * 934 * Return value is 0 on success, -1 on error. 'check' is only meaningful on 935 * success. 936 */ 937 int is_verify_batch_mode_supported(ec_alg_type sig_type, int *check) 938 { 939 int ret; 940 const ec_sig_mapping *sig; 941 942 MUST_HAVE((check != NULL), ret, err); 943 944 ret = get_sig_by_type(sig_type, &sig); EG(ret, err); 945 MUST_HAVE((sig != NULL), ret, err); 946 947 if (sig->verify_batch == unsupported_verify_batch) { 948 (*check) = 0; 949 } 950 else{ 951 (*check) = 1; 952 } 953 954 err: 955 return ret; 956 } 957 958 /* Tells if the signature scheme is deterministic or not, 959 * e.g. if random nonces are used to produce signatures. 960 * 961 * 'check' is set to 1 if deterministic, 0 otherwise. 962 * 963 * Return value is 0 on success, -1 on error. 'check' is only meaningful on 964 * success. 965 966 */ 967 int is_sign_deterministic(ec_alg_type sig_type, int *check) 968 { 969 int ret; 970 const ec_sig_mapping *sig; 971 972 MUST_HAVE((check != NULL), ret, err); 973 974 ret = get_sig_by_type(sig_type, &sig); EG(ret, err); 975 MUST_HAVE((sig != NULL), ret, err); 976 977 switch(sig_type) { 978 #if defined(WITH_SIG_EDDSA25519) 979 case EDDSA25519: 980 case EDDSA25519CTX: 981 case EDDSA25519PH: 982 (*check) = 1; 983 break; 984 #endif 985 #if defined(WITH_SIG_EDDSA448) 986 case EDDSA448: 987 case EDDSA448PH: 988 (*check) = 1; 989 break; 990 #endif 991 #if defined(WITH_SIG_DECDSA) 992 case DECDSA: 993 (*check) = 1; 994 break; 995 #endif 996 default: 997 (*check) = 0; 998 break; 999 } 1000 1001 err: 1002 return ret; 1003 } 1004 1005 1006 /* 1007 * Bubble sort the table of numbers and the table of projective points 1008 * accordingly in ascending order. We only work on index numbers in the table 1009 * to avoid useless copies. 1010 */ 1011 ATTRIBUTE_WARN_UNUSED_RET static int _bubble_sort(verify_batch_scratch_pad *elements, u32 num) 1012 { 1013 u32 i, j; 1014 int ret, swapped; 1015 1016 MUST_HAVE((elements != NULL), ret, err); 1017 MUST_HAVE((num >= 1), ret, err); 1018 for(i = 0; i < (num - 1); i++){ 1019 swapped = 0; 1020 for(j = 0; j < (num - i - 1); j++){ 1021 int check; 1022 u32 indexj, indexj_next; 1023 indexj = elements[j].index; 1024 indexj_next = elements[j + 1].index; 1025 ret = nn_cmp(&elements[indexj].number, &elements[indexj_next].number, &check); EG(ret, err); 1026 if(check < 0){ 1027 /* Swap the two elements */ 1028 elements[j].index = indexj_next; 1029 elements[j + 1].index = indexj; 1030 swapped = 1; 1031 } 1032 } 1033 /* If no swap occured in the inner loop, get out */ 1034 if(!swapped){ 1035 break; 1036 } 1037 } 1038 1039 ret = 0; 1040 err: 1041 return ret; 1042 } 1043 1044 /* 1045 * Bos-Coster algorithm, presented e.g. in https://ed25519.cr.yp.to/ed25519-20110705.pdf 1046 * 1047 * The Bos-Coster algorithm allows to optimize a sum of multi-scalar multiplications using 1048 * addition chains. This is used for example in batch signature verification of schemes 1049 * that support it. 1050 * 1051 */ 1052 int ec_verify_bos_coster(verify_batch_scratch_pad *elements, u32 num, bitcnt_t bits) 1053 { 1054 int ret, check; 1055 u32 i, index0, index1, max_bos_coster_iterations; 1056 1057 MUST_HAVE((elements != NULL), ret, err); 1058 MUST_HAVE((num > 1), ret, err); 1059 1060 /* We fix our maximum attempts here. 1061 * 1062 * NOTE: this avoids "denial of service" when 1063 * providing scalars with too big discrepancies, as 1064 * the Bos-Coster algorithm supposes uniformly randomized 1065 * numbers ... 1066 * If we are provided with scalars with too big differences, 1067 * we end up looping for a very long time. In this case, we 1068 * rather quit with a specific error. 1069 * 1070 * The limit hereafter is fixed using the mean asymptotic complexity 1071 * of the algorithm in the nominal case (multiplied by the bit size 1072 * of num to be lax). 1073 */ 1074 MUST_HAVE((num * bits) >= num, ret, err); 1075 MUST_HAVE((num * bits) >= bits, ret, err); 1076 max_bos_coster_iterations = (num * bits); 1077 1078 /********************************************/ 1079 /****** Bos-Coster algorithm ****************/ 1080 for(i = 0; i < num; i++){ 1081 elements[i].index = i; 1082 } 1083 i = 0; 1084 do { 1085 /* Sort the elements in descending order */ 1086 ret = _bubble_sort(elements, num); EG(ret, err); 1087 /* Perform the addition */ 1088 index0 = elements[0].index; 1089 index1 = elements[1].index; 1090 ret = prj_pt_add(&elements[index1].point, &elements[index0].point, 1091 &elements[index1].point); EG(ret, err); 1092 /* Check the two first integers */ 1093 ret = nn_cmp(&elements[index0].number, &elements[index1].number, &check); 1094 /* Subtract the two first numbers */ 1095 ret = nn_sub(&elements[index0].number, &elements[index0].number, 1096 &elements[index1].number); EG(ret, err); 1097 i++; 1098 if(i > max_bos_coster_iterations){ 1099 /* Give up with specific error code */ 1100 ret = -2; 1101 goto err; 1102 } 1103 } while(check > 0); 1104 1105 index0 = elements[0].index; 1106 /* Proceed with the last scalar multiplication */ 1107 ret = _prj_pt_unprotected_mult(&elements[index0].point, &elements[index0].number, &elements[index0].point); 1108 1109 /* The result is in point [0] of elements */ 1110 err: 1111 return ret; 1112 } 1113