diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/mlkem/mlkem.c | 224 |
1 files changed, 1 insertions, 223 deletions
diff --git a/src/lib/libcrypto/mlkem/mlkem.c b/src/lib/libcrypto/mlkem/mlkem.c index 3202656dfd..bf53e5d77a 100644 --- a/src/lib/libcrypto/mlkem/mlkem.c +++ b/src/lib/libcrypto/mlkem/mlkem.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: mlkem.c,v 1.1 2025/08/14 15:48:48 beck Exp $ */ | 1 | /* $OpenBSD: mlkem.c,v 1.2 2025/08/14 16:04:01 beck Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2025, Bob Beck <beck@obtuse.com> | 3 | * Copyright (c) 2025, Bob Beck <beck@obtuse.com> |
| 4 | * | 4 | * |
| @@ -414,225 +414,3 @@ MLKEM_parse_private_key(MLKEM_private_key *private_key, const uint8_t *in, | |||
| 414 | return 1; | 414 | return 1; |
| 415 | } | 415 | } |
| 416 | LCRYPTO_ALIAS(MLKEM_parse_private_key); | 416 | LCRYPTO_ALIAS(MLKEM_parse_private_key); |
| 417 | /* $OpenBSD: mlkem.c,v 1.1 2025/08/14 15:48:48 beck Exp $ */ | ||
| 418 | /* | ||
| 419 | * Copyright (c) 2025, Bob Beck <beck@obtuse.com> | ||
| 420 | * | ||
| 421 | * Permission to use, copy, modify, and/or distribute this software for any | ||
| 422 | * purpose with or without fee is hereby granted, provided that the above | ||
| 423 | * copyright notice and this permission notice appear in all copies. | ||
| 424 | * | ||
| 425 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 426 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 427 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
| 428 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 429 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
| 430 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
| 431 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 432 | */ | ||
| 433 | |||
| 434 | #include <openssl/mlkem.h> | ||
| 435 | |||
| 436 | |||
| 437 | int MLKEM768_generate_key( | ||
| 438 | uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES], | ||
| 439 | uint8_t optional_out_seed[MLKEM_SEED_BYTES], | ||
| 440 | struct MLKEM768_private_key *out_private_key); | ||
| 441 | |||
| 442 | /* | ||
| 443 | * MLKEM768_private_key_from_seed derives a private key from a seed that was | ||
| 444 | * generated by |MLKEM768_generate_key|. It fails and returns 0 if |seed_len| is | ||
| 445 | * incorrect, otherwise it writes |*out_private_key| and returns 1. | ||
| 446 | */ | ||
| 447 | int MLKEM768_private_key_from_seed(struct MLKEM768_private_key *out_private_key, | ||
| 448 | const uint8_t *seed, size_t seed_len); | ||
| 449 | |||
| 450 | /* | ||
| 451 | * MLKEM_public_from_private sets |*out_public_key| to the public key that | ||
| 452 | * corresponds to |private_key|. (This is faster than parsing the output of | ||
| 453 | * |MLKEM_generate_key| if, for some reason, you need to encapsulate to a key | ||
| 454 | * that was just generated.) | ||
| 455 | */ | ||
| 456 | void MLKEM768_public_from_private(struct MLKEM768_public_key *out_public_key, | ||
| 457 | const struct MLKEM768_private_key *private_key); | ||
| 458 | |||
| 459 | /* MLKEM768_CIPHERTEXT_BYTES is number of bytes in the ML-KEM768 ciphertext. */ | ||
| 460 | #define MLKEM768_CIPHERTEXT_BYTES 1088 | ||
| 461 | |||
| 462 | /* | ||
| 463 | * MLKEM768_encap encrypts a random shared secret for |public_key|, writes the | ||
| 464 | * ciphertext to |out_ciphertext|, and writes the random shared secret to | ||
| 465 | * |out_shared_secret|. | ||
| 466 | */ | ||
| 467 | void MLKEM768_encap(uint8_t out_ciphertext[MLKEM768_CIPHERTEXT_BYTES], | ||
| 468 | uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], | ||
| 469 | const struct MLKEM768_public_key *public_key); | ||
| 470 | |||
| 471 | /* | ||
| 472 | * MLKEM768_decap decrypts a shared secret from |ciphertext| using |private_key| | ||
| 473 | * and writes it to |out_shared_secret|. If |ciphertext_len| is incorrect it | ||
| 474 | * returns 0, otherwise it rreturns 1. If |ciphertext| is invalid, | ||
| 475 | * |out_shared_secret| is filled with a key that will always be the same for the | ||
| 476 | * same |ciphertext| and |private_key|, but which appears to be random unless | ||
| 477 | * one has access to |private_key|. These alternatives occur in constant time. | ||
| 478 | * Any subsequent symmetric encryption using |out_shared_secret| must use an | ||
| 479 | * authenticated encryption scheme in order to discover the decapsulation | ||
| 480 | * failure. | ||
| 481 | */ | ||
| 482 | int MLKEM768_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], | ||
| 483 | const uint8_t *ciphertext, size_t ciphertext_len, | ||
| 484 | const struct MLKEM768_private_key *private_key); | ||
| 485 | |||
| 486 | /* Serialisation of keys. */ | ||
| 487 | |||
| 488 | /* | ||
| 489 | * MLKEM768_marshal_public_key serializes |public_key| to |out| in the standard | ||
| 490 | * format for ML-KEM public keys. It returns one on success or zero on allocation | ||
| 491 | * error. | ||
| 492 | */ | ||
| 493 | int MLKEM768_marshal_public_key(uint8_t **output, size_t *output_len, | ||
| 494 | const struct MLKEM768_public_key *public_key); | ||
| 495 | |||
| 496 | /* | ||
| 497 | * MLKEM768_parse_public_key parses a public key, in the format generated by | ||
| 498 | * |MLKEM_marshal_public_key|, from |in| and writes the result to | ||
| 499 | * |out_public_key|. It returns one on success or zero on parse error or if | ||
| 500 | * there are trailing bytes in |in|. | ||
| 501 | */ | ||
| 502 | int MLKEM768_parse_public_key(struct MLKEM768_public_key *out_public_key, | ||
| 503 | const uint8_t *input, size_t input_len); | ||
| 504 | |||
| 505 | /* | ||
| 506 | * MLKEM_parse_private_key parses a private key, in the format generated by | ||
| 507 | * |MLKEM_marshal_private_key|, from |in| and writes the result to | ||
| 508 | * |out_private_key|. It returns one on success or zero on parse error or if | ||
| 509 | * there are trailing bytes in |in|. This formate is verbose and should be avoided. | ||
| 510 | * Private keys should be stored as seeds and parsed using |MLKEM768_private_key_from_seed|. | ||
| 511 | */ | ||
| 512 | int MLKEM768_parse_private_key(struct MLKEM768_private_key *out_private_key, | ||
| 513 | const uint8_t *input, size_t input_len); | ||
| 514 | |||
| 515 | /* | ||
| 516 | * ML-KEM-1024 | ||
| 517 | * | ||
| 518 | * ML-KEM-1024 also exists. You should prefer ML-KEM-768 where possible. | ||
| 519 | */ | ||
| 520 | |||
| 521 | /* | ||
| 522 | * MLKEM1024_public_key contains an ML-KEM-1024 public key. The contents of this | ||
| 523 | * object should never leave the address space since the format is unstable. | ||
| 524 | */ | ||
| 525 | struct MLKEM1024_public_key { | ||
| 526 | union { | ||
| 527 | uint8_t bytes[512 * (4 + 16) + 32 + 32]; | ||
| 528 | uint16_t alignment; | ||
| 529 | } opaque; | ||
| 530 | }; | ||
| 531 | |||
| 532 | /* | ||
| 533 | * MLKEM1024_private_key contains a ML-KEM-1024 private key. The contents of | ||
| 534 | * this object should never leave the address space since the format is | ||
| 535 | * unstable. | ||
| 536 | */ | ||
| 537 | struct MLKEM1024_private_key { | ||
| 538 | union { | ||
| 539 | uint8_t bytes[512 * (4 + 4 + 16) + 32 + 32 + 32]; | ||
| 540 | uint16_t alignment; | ||
| 541 | } opaque; | ||
| 542 | }; | ||
| 543 | |||
| 544 | /* | ||
| 545 | * MLKEM1024_PUBLIC_KEY_BYTES is the number of bytes in an encoded ML-KEM-1024 | ||
| 546 | * public key. | ||
| 547 | */ | ||
| 548 | #define MLKEM1024_PUBLIC_KEY_BYTES 1568 | ||
| 549 | |||
| 550 | /* | ||
| 551 | * MLKEM1024_generate_key generates a random public/private key pair, writes the | ||
| 552 | * encoded public key to |out_encoded_public_key| and sets |out_private_key| to | ||
| 553 | * the private key. If |optional_out_seed| is not NULL then the seed used to | ||
| 554 | * generate the private key is written to it. | ||
| 555 | */ | ||
| 556 | int MLKEM1024_generate_key( | ||
| 557 | uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES], | ||
| 558 | uint8_t optional_out_seed[MLKEM_SEED_BYTES], | ||
| 559 | struct MLKEM1024_private_key *out_private_key); | ||
| 560 | |||
| 561 | /* | ||
| 562 | * MLKEM1024_private_key_from_seed derives a private key from a seed that was | ||
| 563 | * generated by |MLKEM1024_generate_key|. It fails and returns 0 if |seed_len| | ||
| 564 | * is incorrect, otherwise it writes |*out_private_key| and returns 1. | ||
| 565 | */ | ||
| 566 | int MLKEM1024_private_key_from_seed( | ||
| 567 | struct MLKEM1024_private_key *out_private_key, const uint8_t *seed, | ||
| 568 | size_t seed_len); | ||
| 569 | |||
| 570 | /* | ||
| 571 | * MLKEM1024_public_from_private sets |*out_public_key| to the public key that | ||
| 572 | * corresponds to |private_key|. (This is faster than parsing the output of | ||
| 573 | * |MLKEM1024_generate_key| if, for some reason, you need to encapsulate to a | ||
| 574 | * key that was just generated.) | ||
| 575 | */ | ||
| 576 | void MLKEM1024_public_from_private(struct MLKEM1024_public_key *out_public_key, | ||
| 577 | const struct MLKEM1024_private_key *private_key); | ||
| 578 | |||
| 579 | /* MLKEM1024_CIPHERTEXT_BYTES is number of bytes in the ML-KEM-1024 ciphertext. */ | ||
| 580 | #define MLKEM1024_CIPHERTEXT_BYTES 1568 | ||
| 581 | |||
| 582 | /* | ||
| 583 | * MLKEM1024_encap encrypts a random shared secret for |public_key|, writes the | ||
| 584 | * ciphertext to |out_ciphertext|, and writes the random shared secret to | ||
| 585 | * |out_shared_secret|. | ||
| 586 | */ | ||
| 587 | void MLKEM1024_encap(uint8_t out_ciphertext[MLKEM1024_CIPHERTEXT_BYTES], | ||
| 588 | uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], | ||
| 589 | const struct MLKEM1024_public_key *public_key); | ||
| 590 | |||
| 591 | /* | ||
| 592 | * MLKEM1024_decap decrypts a shared secret from |ciphertext| using | ||
| 593 | * |private_key| and writes it to |out_shared_secret|. If |ciphertext_len| is | ||
| 594 | * incorrect it returns 0, otherwise it returns 1. If |ciphertext| is invalid | ||
| 595 | * (but of the correct length), |out_shared_secret| is filled with a key that | ||
| 596 | * will always be the same for the same |ciphertext| and |private_key|, but | ||
| 597 | * which appears to be random unless one has access to |private_key|. These | ||
| 598 | * alternatives occur in constant time. Any subsequent symmetric encryption | ||
| 599 | * using |out_shared_secret| must use an authenticated encryption scheme in | ||
| 600 | * order to discover the decapsulation failure. | ||
| 601 | */ | ||
| 602 | int MLKEM1024_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], | ||
| 603 | const uint8_t *ciphertext, size_t ciphertext_len, | ||
| 604 | const struct MLKEM1024_private_key *private_key); | ||
| 605 | |||
| 606 | /* | ||
| 607 | * Serialisation of ML-KEM-1024 keys. | ||
| 608 | * MLKEM1024_marshal_public_key serializes |public_key| to |out| in the standard | ||
| 609 | * format for ML-KEM-1024 public keys. It returns one on success or zero on | ||
| 610 | * allocation error. | ||
| 611 | */ | ||
| 612 | int MLKEM1024_marshal_public_key(uint8_t **output, size_t *output_len, | ||
| 613 | const struct MLKEM1024_public_key *public_key); | ||
| 614 | |||
| 615 | /* | ||
| 616 | * MLKEM1024_parse_public_key parses a public key, in the format generated by | ||
| 617 | * |MLKEM1024_marshal_public_key|, from |in| and writes the result to | ||
| 618 | * |out_public_key|. It returns one on success or zero on parse error or if | ||
| 619 | * there are trailing bytes in |in|. | ||
| 620 | */ | ||
| 621 | int MLKEM1024_parse_public_key(struct MLKEM1024_public_key *out_public_key, | ||
| 622 | const uint8_t *input, size_t input_len); | ||
| 623 | |||
| 624 | /* | ||
| 625 | * MLKEM1024_parse_private_key parses a private key, in NIST's format for | ||
| 626 | * private keys, from |in| and writes the result to |out_private_key|. It | ||
| 627 | * returns one on success or zero on parse error or if there are trailing bytes | ||
| 628 | * in |in|. This format is verbose and should be avoided. Private keys should be | ||
| 629 | * stored as seeds and parsed using |MLKEM1024_private_key_from_seed|. | ||
| 630 | */ | ||
| 631 | int MLKEM1024_parse_private_key(struct MLKEM1024_private_key *out_private_key, | ||
| 632 | const uint8_t *input, size_t input_len); | ||
| 633 | |||
| 634 | #if defined(__cplusplus) | ||
| 635 | } | ||
| 636 | #endif | ||
| 637 | |||
| 638 | #endif /* OPENSSL_HEADER_MLKEM_H */ | ||
