1 /* falcon.c 2 * 3 * Copyright (C) 2006-2021 wolfSSL Inc. 4 * 5 * This file is part of wolfSSL. 6 * 7 * wolfSSL is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * wolfSSL is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 20 */ 21 22 /* Based on ed448.c and Reworked for Falcon by Anthony Hu. */ 23 24 #ifdef HAVE_CONFIG_H 25 #include <config.h> 26 #endif 27 28 /* in case user set HAVE_PQC there */ 29 #include <wolfssl/wolfcrypt/settings.h> 30 31 #include <wolfssl/wolfcrypt/asn.h> 32 33 #ifdef HAVE_PQC 34 35 #ifdef HAVE_LIBOQS 36 #include <oqs/oqs.h> 37 #endif 38 39 #include <wolfssl/wolfcrypt/falcon.h> 40 #include <wolfssl/wolfcrypt/error-crypt.h> 41 #ifdef NO_INLINE 42 #include <wolfssl/wolfcrypt/misc.h> 43 #else 44 #define WOLFSSL_MISC_INCLUDED 45 #include <wolfcrypt/src/misc.c> 46 #endif 47 48 /* Sign the message using the falcon private key. 49 * 50 * in [in] Message to sign. 51 * inLen [in] Length of the message in bytes. 52 * out [in] Buffer to write signature into. 53 * outLen [in/out] On in, size of buffer. 54 * On out, the length of the signature in bytes. 55 * key [in] Falcon key to use when signing 56 * returns BAD_FUNC_ARG when a parameter is NULL or public key not set, 57 * BUFFER_E when outLen is less than FALCON_LEVEL1_SIG_SIZE, 58 * 0 otherwise. 59 */ 60 int wc_falcon_sign_msg(const byte* in, word32 inLen, 61 byte* out, word32 *outLen, 62 falcon_key* key) 63 { 64 int ret = 0; 65 #ifdef HAVE_LIBOQS 66 OQS_SIG *oqssig = NULL; 67 size_t localOutLen = 0; 68 69 /* sanity check on arguments */ 70 if ((in == NULL) || (out == NULL) || (outLen == NULL) || (key == NULL)) { 71 ret = BAD_FUNC_ARG; 72 } 73 74 if ((ret == 0) && (!key->prvKeySet)) { 75 ret = BAD_FUNC_ARG; 76 } 77 78 if (ret == 0) { 79 if (key->level == 1) { 80 oqssig = OQS_SIG_new(OQS_SIG_alg_falcon_512); 81 } 82 else if (key->level == 5) { 83 oqssig = OQS_SIG_new(OQS_SIG_alg_falcon_1024); 84 } 85 86 if (oqssig == NULL) { 87 ret = SIG_TYPE_E; 88 } 89 } 90 91 /* check and set up out length */ 92 if (ret == 0) { 93 if ((key->level == 1) && (*outLen < FALCON_LEVEL1_SIG_SIZE)) { 94 *outLen = FALCON_LEVEL1_SIG_SIZE; 95 ret = BUFFER_E; 96 } 97 else if ((key->level == 5) && (*outLen < FALCON_LEVEL5_SIG_SIZE)) { 98 *outLen = FALCON_LEVEL5_SIG_SIZE; 99 ret = BUFFER_E; 100 } 101 localOutLen = *outLen; 102 } 103 104 if ((ret == 0) && 105 (OQS_SIG_sign(oqssig, out, &localOutLen, in, inLen, key->k) 106 == OQS_ERROR)) { 107 ret = BAD_FUNC_ARG; 108 } 109 110 if (ret == 0) { 111 *outLen = (word32)localOutLen; 112 } 113 114 if (oqssig != NULL) { 115 OQS_SIG_free(oqssig); 116 } 117 #endif 118 return ret; 119 } 120 121 /* Verify the message using the falcon public key. 122 * 123 * sig [in] Signature to verify. 124 * sigLen [in] Size of signature in bytes. 125 * msg [in] Message to verify. 126 * msgLen [in] Length of the message in bytes. 127 * res [out] *res is set to 1 on successful verification. 128 * key [in] Falcon key to use to verify. 129 * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and 130 * BUFFER_E when sigLen is less than FALCON_LEVEL1_SIG_SIZE, 131 * 0 otherwise. 132 */ 133 int wc_falcon_verify_msg(const byte* sig, word32 sigLen, const byte* msg, 134 word32 msgLen, int* res, falcon_key* key) 135 { 136 int ret = 0; 137 #ifdef HAVE_LIBOQS 138 OQS_SIG *oqssig = NULL; 139 140 if (key == NULL || sig == NULL || msg == NULL || res == NULL) { 141 ret = BAD_FUNC_ARG; 142 } 143 144 if ((ret == 0) && (!key->pubKeySet)) { 145 ret = BAD_FUNC_ARG; 146 } 147 148 if (ret == 0) { 149 if (key->level == 1) { 150 oqssig = OQS_SIG_new(OQS_SIG_alg_falcon_512); 151 } 152 else if (key->level == 5) { 153 oqssig = OQS_SIG_new(OQS_SIG_alg_falcon_1024); 154 } 155 156 if (oqssig == NULL) { 157 ret = SIG_TYPE_E; 158 } 159 } 160 161 if ((ret == 0) && 162 (OQS_SIG_verify(oqssig, msg, msgLen, sig, sigLen, key->p) 163 == OQS_ERROR)) { 164 ret = SIG_VERIFY_E; 165 } 166 167 if (ret == 0) { 168 *res = 1; 169 } 170 171 if (oqssig != NULL) { 172 OQS_SIG_free(oqssig); 173 } 174 #endif 175 176 return ret; 177 } 178 179 /* Initialize the falcon private/public key. 180 * 181 * key [in] Falcon key. 182 * returns BAD_FUNC_ARG when key is NULL 183 */ 184 int wc_falcon_init(falcon_key* key) 185 { 186 if (key == NULL) { 187 return BAD_FUNC_ARG; 188 } 189 190 ForceZero(key, sizeof(key)); 191 return 0; 192 } 193 194 /* Set the level of the falcon private/public key. 195 * 196 * key [out] Falcon key. 197 * level [in] Either 1 or 5. 198 * returns BAD_FUNC_ARG when key is NULL or level is not 1 and not 5. 199 */ 200 int wc_falcon_set_level(falcon_key* key, byte level) 201 { 202 if (key == NULL) { 203 return BAD_FUNC_ARG; 204 } 205 206 if (level != 1 && level != 5) { 207 return BAD_FUNC_ARG; 208 } 209 210 key->level = level; 211 key->pubKeySet = 0; 212 key->prvKeySet = 0; 213 return 0; 214 } 215 216 /* Get the level of the falcon private/public key. 217 * 218 * key [in] Falcon key. 219 * level [out] The level. 220 * returns BAD_FUNC_ARG when key is NULL or level has not been set. 221 */ 222 int wc_falcon_get_level(falcon_key* key, byte* level) 223 { 224 if (key == NULL || level == NULL) { 225 return BAD_FUNC_ARG; 226 } 227 228 if (key->level != 1 && key->level != 5) { 229 return BAD_FUNC_ARG; 230 } 231 232 *level = key->level; 233 return 0; 234 } 235 236 /* Clears the falcon key data 237 * 238 * key [in] Falcon key. 239 */ 240 void wc_falcon_free(falcon_key* key) 241 { 242 if (key != NULL) { 243 ForceZero(key, sizeof(key)); 244 } 245 } 246 247 /* Export the falcon public key. 248 * 249 * key [in] Falcon public key. 250 * out [in] Array to hold public key. 251 * outLen [in/out] On in, the number of bytes in array. 252 * On out, the number bytes put into array. 253 * returns BAD_FUNC_ARG when a parameter is NULL, 254 * ECC_BAD_ARG_E when outLen is less than FALCON_LEVEL1_PUB_KEY_SIZE, 255 * 0 otherwise. 256 */ 257 int wc_falcon_export_public(falcon_key* key, 258 byte* out, word32* outLen) 259 { 260 /* sanity check on arguments */ 261 if ((key == NULL) || (out == NULL) || (outLen == NULL)) { 262 return BAD_FUNC_ARG; 263 } 264 265 if ((key->level != 1) && (key->level != 5)) { 266 return BAD_FUNC_ARG; 267 } 268 269 if (!key->pubKeySet) { 270 return BAD_FUNC_ARG; 271 } 272 273 /* check and set up out length */ 274 if ((key->level == 1) && (*outLen < FALCON_LEVEL1_PUB_KEY_SIZE)) { 275 *outLen = FALCON_LEVEL1_PUB_KEY_SIZE; 276 return BUFFER_E; 277 } 278 else if ((key->level == 5) && (*outLen < FALCON_LEVEL5_PUB_KEY_SIZE)) { 279 *outLen = FALCON_LEVEL5_PUB_KEY_SIZE; 280 return BUFFER_E; 281 } 282 283 if (key->level == 1) { 284 *outLen = FALCON_LEVEL1_PUB_KEY_SIZE; 285 XMEMCPY(out, key->p, FALCON_LEVEL1_PUB_KEY_SIZE); 286 } 287 else if (key->level == 5) { 288 *outLen = FALCON_LEVEL5_PUB_KEY_SIZE; 289 XMEMCPY(out, key->p, FALCON_LEVEL5_PUB_KEY_SIZE); 290 } 291 292 return 0; 293 } 294 295 /* Import a falcon public key from a byte array. 296 * Public key encoded in big-endian. 297 * 298 * in [in] Array holding public key. 299 * inLen [in] Number of bytes of data in array. 300 * key [in] Falcon public key. 301 * returns BAD_FUNC_ARG when a parameter is NULL or key format is not supported, 302 * 0 otherwise. 303 */ 304 int wc_falcon_import_public(const byte* in, word32 inLen, 305 falcon_key* key) 306 { 307 /* sanity check on arguments */ 308 if ((in == NULL) || (key == NULL)) { 309 return BAD_FUNC_ARG; 310 } 311 312 if ((key->level != 1) && (key->level != 5)) { 313 return BAD_FUNC_ARG; 314 } 315 316 if ((key->level == 1) && (inLen != FALCON_LEVEL1_PUB_KEY_SIZE)) { 317 return BAD_FUNC_ARG; 318 } 319 else if ((key->level == 5) && (inLen != FALCON_LEVEL5_PUB_KEY_SIZE)) { 320 return BAD_FUNC_ARG; 321 } 322 323 XMEMCPY(key->p, in, inLen); 324 key->pubKeySet = 1; 325 326 return 0; 327 } 328 329 static int parse_private_key(const byte* priv, word32 privSz, 330 byte** out, word32 *outSz, 331 falcon_key* key) { 332 word32 idx = 0; 333 int ret = 0; 334 int length = 0; 335 336 /* sanity check on arguments */ 337 if ((priv == NULL) || (key == NULL)) { 338 return BAD_FUNC_ARG; 339 } 340 341 if ((key->level != 1) && (key->level != 5)) { 342 return BAD_FUNC_ARG; 343 } 344 345 /* At this point, it is still a PKCS8 private key. */ 346 if ((ret = ToTraditionalInline(priv, &idx, privSz)) < 0) { 347 return ret; 348 } 349 350 /* Now it is a octet_string(concat(priv,pub)) */ 351 if ((ret = GetOctetString(priv, &idx, &length, privSz)) < 0) { 352 return ret; 353 } 354 355 *out = (byte *)priv + idx; 356 *outSz = privSz - idx; 357 358 /* And finally it is concat(priv,pub). Key size check. */ 359 if ((key->level == 1) && (*outSz != FALCON_LEVEL1_KEY_SIZE + 360 FALCON_LEVEL1_PUB_KEY_SIZE)) { 361 return BAD_FUNC_ARG; 362 } 363 else if ((key->level == 5) && (*outSz != FALCON_LEVEL5_KEY_SIZE + 364 FALCON_LEVEL5_PUB_KEY_SIZE)) { 365 return BAD_FUNC_ARG; 366 } 367 368 return 0; 369 } 370 371 /* Import a falcon private key from a byte array. 372 * 373 * priv [in] Array holding private key. 374 * privSz [in] Number of bytes of data in array. 375 * key [in] Falcon private key. 376 * returns BAD_FUNC_ARG when a parameter is NULL or privSz is less than 377 * FALCON_LEVEL1_KEY_SIZE, 378 * 0 otherwise. 379 */ 380 int wc_falcon_import_private_only(const byte* priv, word32 privSz, 381 falcon_key* key) 382 { 383 int ret = 0; 384 byte *newPriv = NULL; 385 word32 newPrivSz = 0; 386 387 if ((ret = parse_private_key(priv, privSz, &newPriv, &newPrivSz, key)) 388 != 0) { 389 return ret; 390 } 391 392 if (key->level == 1) { 393 XMEMCPY(key->k, newPriv, FALCON_LEVEL1_KEY_SIZE); 394 } 395 else if (key->level == 5) { 396 XMEMCPY(key->k, newPriv, FALCON_LEVEL5_KEY_SIZE); 397 } 398 key->prvKeySet = 1; 399 400 return 0; 401 } 402 403 /* Import a falcon private and public keys from byte array(s). 404 * 405 * priv [in] Array holding private key or private+public keys 406 * privSz [in] Number of bytes of data in private key array. 407 * pub [in] Array holding public key (or NULL). 408 * pubSz [in] Number of bytes of data in public key array (or 0). 409 * key [in] Falcon private/public key. 410 * returns BAD_FUNC_ARG when a required parameter is NULL or an invalid 411 * combination of keys/lengths is supplied, 0 otherwise. 412 */ 413 int wc_falcon_import_private_key(const byte* priv, word32 privSz, 414 const byte* pub, word32 pubSz, 415 falcon_key* key) 416 { 417 int ret = 0; 418 byte *newPriv = NULL; 419 word32 newPrivSz = 0; 420 421 if ((ret = parse_private_key(priv, privSz, &newPriv, &newPrivSz, key)) 422 != 0) { 423 return ret; 424 } 425 426 if (pub == NULL) { 427 if (pubSz != 0) { 428 return BAD_FUNC_ARG; 429 } 430 431 if ((newPrivSz != FALCON_LEVEL1_PRV_KEY_SIZE) && 432 (newPrivSz != FALCON_LEVEL5_PRV_KEY_SIZE)) { 433 return BAD_FUNC_ARG; 434 } 435 436 if (key->level == 1) { 437 pub = newPriv + FALCON_LEVEL1_KEY_SIZE; 438 pubSz = FALCON_LEVEL1_PUB_KEY_SIZE; 439 } 440 else if (key->level == 5) { 441 pub = newPriv + FALCON_LEVEL5_KEY_SIZE; 442 pubSz = FALCON_LEVEL5_PUB_KEY_SIZE; 443 } 444 } 445 else if ((pubSz != FALCON_LEVEL1_PUB_KEY_SIZE) && 446 (pubSz != FALCON_LEVEL5_PUB_KEY_SIZE)) { 447 return BAD_FUNC_ARG; 448 } 449 450 /* import public key */ 451 ret = wc_falcon_import_public(pub, pubSz, key); 452 453 if (ret == 0) { 454 /* make the private key (priv + pub) */ 455 if (key->level == 1) { 456 XMEMCPY(key->k, newPriv, FALCON_LEVEL1_KEY_SIZE); 457 } 458 else if (key->level == 5) { 459 XMEMCPY(key->k, newPriv, FALCON_LEVEL5_KEY_SIZE); 460 } 461 key->prvKeySet = 1; 462 } 463 464 return ret; 465 } 466 467 /* Export the falcon private key. 468 * 469 * key [in] Falcon private key. 470 * out [in] Array to hold private key. 471 * outLen [in/out] On in, the number of bytes in array. 472 * On out, the number bytes put into array. 473 * returns BAD_FUNC_ARG when a parameter is NULL, 474 * ECC_BAD_ARG_E when outLen is less than FALCON_LEVEL1_KEY_SIZE, 475 * 0 otherwise. 476 */ 477 int wc_falcon_export_private_only(falcon_key* key, byte* out, word32* outLen) 478 { 479 /* sanity checks on arguments */ 480 if ((key == NULL) || (out == NULL) || (outLen == NULL)) { 481 return BAD_FUNC_ARG; 482 } 483 484 if ((key->level != 1) && (key->level != 5)) { 485 return BAD_FUNC_ARG; 486 } 487 488 /* check and set up out length */ 489 if ((key->level == 1) && (*outLen < FALCON_LEVEL1_KEY_SIZE)) { 490 *outLen = FALCON_LEVEL1_KEY_SIZE; 491 return BUFFER_E; 492 } 493 else if ((key->level == 5) && (*outLen < FALCON_LEVEL5_KEY_SIZE)) { 494 *outLen = FALCON_LEVEL5_KEY_SIZE; 495 return BUFFER_E; 496 } 497 498 if (key->level == 1) { 499 *outLen = FALCON_LEVEL1_KEY_SIZE; 500 } 501 else if (key->level == 5) { 502 *outLen = FALCON_LEVEL5_KEY_SIZE; 503 } 504 505 XMEMCPY(out, key->k, *outLen); 506 507 return 0; 508 } 509 510 /* Export the falcon private and public key. 511 * 512 * key [in] Falcon private/public key. 513 * out [in] Array to hold private and public key. 514 * outLen [in/out] On in, the number of bytes in array. 515 * On out, the number bytes put into array. 516 * returns BAD_FUNC_ARG when a parameter is NULL, 517 * BUFFER_E when outLen is less than FALCON_LEVEL1_PRV_KEY_SIZE, 518 * 0 otherwise. 519 */ 520 int wc_falcon_export_private(falcon_key* key, byte* out, word32* outLen) 521 { 522 /* sanity checks on arguments */ 523 if ((key == NULL) || (out == NULL) || (outLen == NULL)) { 524 return BAD_FUNC_ARG; 525 } 526 527 if ((key->level != 1) && (key->level != 5)) { 528 return BAD_FUNC_ARG; 529 } 530 531 if ((key->level == 1) && (*outLen < FALCON_LEVEL1_PRV_KEY_SIZE)) { 532 *outLen = FALCON_LEVEL1_PRV_KEY_SIZE; 533 return BUFFER_E; 534 } 535 else if ((key->level == 5) && (*outLen < FALCON_LEVEL5_PRV_KEY_SIZE)) { 536 *outLen = FALCON_LEVEL5_PRV_KEY_SIZE; 537 return BUFFER_E; 538 } 539 540 541 if (key->level == 1) { 542 *outLen = FALCON_LEVEL1_PRV_KEY_SIZE; 543 XMEMCPY(out, key->k, FALCON_LEVEL1_PRV_KEY_SIZE); 544 XMEMCPY(out + FALCON_LEVEL1_PRV_KEY_SIZE, key->p, 545 FALCON_LEVEL1_PUB_KEY_SIZE); 546 } 547 else if (key->level == 5) { 548 *outLen = FALCON_LEVEL5_PRV_KEY_SIZE; 549 XMEMCPY(out, key->k, FALCON_LEVEL5_PRV_KEY_SIZE); 550 XMEMCPY(out + FALCON_LEVEL5_PRV_KEY_SIZE, key->p, 551 FALCON_LEVEL5_PUB_KEY_SIZE); 552 } 553 554 return 0; 555 } 556 557 /* Export the falcon private and public key. 558 * 559 * key [in] Falcon private/public key. 560 * priv [in] Array to hold private key. 561 * privSz [in/out] On in, the number of bytes in private key array. 562 * pub [in] Array to hold public key. 563 * pubSz [in/out] On in, the number of bytes in public key array. 564 * On out, the number bytes put into array. 565 * returns BAD_FUNC_ARG when a parameter is NULL, 566 * BUFFER_E when privSz is less than FALCON_LEVEL1_PRV_KEY_SIZE or pubSz is less 567 * than FALCON_LEVEL1_PUB_KEY_SIZE, 568 * 0 otherwise. 569 */ 570 int wc_falcon_export_key(falcon_key* key, byte* priv, word32 *privSz, 571 byte* pub, word32 *pubSz) 572 { 573 int ret = 0; 574 575 /* export private part */ 576 ret = wc_falcon_export_private(key, priv, privSz); 577 if (ret == 0) { 578 /* export public part */ 579 ret = wc_falcon_export_public(key, pub, pubSz); 580 } 581 582 return ret; 583 } 584 585 /* Check the public key of the falcon key matches the private key. 586 * 587 * key [in] Falcon private/public key. 588 * returns BAD_FUNC_ARG when key is NULL, 589 * PUBLIC_KEY_E when the public key is not set or doesn't match, 590 * other -ve value on hash failure, 591 * 0 otherwise. 592 */ 593 int wc_falcon_check_key(falcon_key* key) 594 { 595 if (key == NULL) { 596 return BAD_FUNC_ARG; 597 } 598 599 /* Assume everything is fine. */ 600 return 0; 601 } 602 603 /* Returns the size of a falcon private key. 604 * 605 * key [in] Falcon private/public key. 606 * returns BAD_FUNC_ARG when key is NULL, 607 * FALCON_LEVEL1_KEY_SIZE otherwise. 608 */ 609 int wc_falcon_size(falcon_key* key) 610 { 611 if (key == NULL) { 612 return BAD_FUNC_ARG; 613 } 614 615 if (key->level == 1) { 616 return FALCON_LEVEL1_KEY_SIZE; 617 } 618 else if (key->level == 5) { 619 return FALCON_LEVEL5_KEY_SIZE; 620 } 621 622 return BAD_FUNC_ARG; 623 } 624 625 /* Returns the size of a falcon private plus public key. 626 * 627 * key [in] Falcon private/public key. 628 * returns BAD_FUNC_ARG when key is NULL, 629 * FALCON_LEVEL1_PRV_KEY_SIZE otherwise. 630 */ 631 int wc_falcon_priv_size(falcon_key* key) 632 { 633 if (key == NULL) { 634 return BAD_FUNC_ARG; 635 } 636 637 if (key->level == 1) { 638 return FALCON_LEVEL1_PRV_KEY_SIZE; 639 } 640 else if (key->level == 5) { 641 return FALCON_LEVEL5_PRV_KEY_SIZE; 642 } 643 644 return BAD_FUNC_ARG; 645 } 646 647 /* Returns the size of a falcon public key. 648 * 649 * key [in] Falcon private/public key. 650 * returns BAD_FUNC_ARG when key is NULL, 651 * FALCON_LEVEL1_PUB_KEY_SIZE otherwise. 652 */ 653 int wc_falcon_pub_size(falcon_key* key) 654 { 655 if (key == NULL) { 656 return BAD_FUNC_ARG; 657 } 658 659 if (key->level == 1) { 660 return FALCON_LEVEL1_PUB_KEY_SIZE; 661 } 662 else if (key->level == 5) { 663 return FALCON_LEVEL5_PUB_KEY_SIZE; 664 } 665 666 return BAD_FUNC_ARG; 667 } 668 669 /* Returns the size of a falcon signature. 670 * 671 * key [in] Falcon private/public key. 672 * returns BAD_FUNC_ARG when key is NULL, 673 * FALCON_LEVEL1_SIG_SIZE otherwise. 674 */ 675 int wc_falcon_sig_size(falcon_key* key) 676 { 677 if (key == NULL) { 678 return BAD_FUNC_ARG; 679 } 680 681 if (key->level == 1) { 682 return FALCON_LEVEL1_SIG_SIZE; 683 } 684 else if (key->level == 5) { 685 return FALCON_LEVEL5_SIG_SIZE; 686 } 687 688 return BAD_FUNC_ARG; 689 } 690 #endif /* HAVE_PQC */ 691