diff options
Diffstat (limited to 'src')
-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 */ | ||