/src/dropbear/src/mlkem768.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2023 Markus Friedl. All rights reserved. |
3 | | * Copyright (c) 2025 Loganaden Velvindron. All rights reserved. |
4 | | * Copyright (c) 2025 Jaykishan Mutkawoa. All rights reserved. |
5 | | * Copyright (c) 2025 Keshwarsingh "Kavish" Nadan. All rights reserved. |
6 | | * Redistribution and use in source and binary forms, with or without |
7 | | * modification, are permitted provided that the following conditions |
8 | | * are met: |
9 | | * 1. Redistributions of source code must retain the above copyright |
10 | | * notice, this list of conditions and the following disclaimer. |
11 | | * 2. Redistributions in binary form must reproduce the above copyright |
12 | | * notice, this list of conditions and the following disclaimer in the |
13 | | * documentation and/or other materials provided with the distribution. |
14 | | * |
15 | | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
16 | | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
17 | | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
18 | | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
19 | | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
20 | | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
21 | | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
22 | | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
23 | | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
24 | | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
25 | | */ |
26 | | |
27 | | #include "includes.h" |
28 | | |
29 | | #include <sys/types.h> |
30 | | |
31 | | #include <stdio.h> |
32 | | #ifdef HAVE_STDINT_H |
33 | | #include <stdint.h> |
34 | | #endif |
35 | | #include <stdbool.h> |
36 | | #include <string.h> |
37 | | #include <signal.h> |
38 | | #ifdef HAVE_ENDIAN_H |
39 | | # include <endian.h> |
40 | | #endif |
41 | | |
42 | | #include "kex.h" |
43 | | |
44 | | #if DROPBEAR_MLKEM768 |
45 | | |
46 | | #include "dbutil.h" |
47 | | #include "compat.h" |
48 | | |
49 | | #pragma GCC diagnostic push |
50 | | #pragma GCC diagnostic ignored "-Wunused-parameter" |
51 | | #include "libcrux_mlkem768_sha3.h" |
52 | | #pragma GCC diagnostic pop |
53 | | |
54 | | #include "mlkem768.h" |
55 | | #include "dbrandom.h" |
56 | | |
57 | | int |
58 | | crypto_kem_mlkem768_keypair(unsigned char *pk, unsigned char *sk) |
59 | 0 | { |
60 | 0 | unsigned char rnd[LIBCRUX_ML_KEM_KEY_PAIR_PRNG_LEN]; |
61 | 0 | struct libcrux_mlkem768_keypair keypair; |
62 | |
|
63 | 0 | static_assert(sizeof(keypair.sk.value) == crypto_kem_mlkem768_SECRETKEYBYTES, "len"); |
64 | 0 | static_assert(sizeof(keypair.pk.value) == crypto_kem_mlkem768_PUBLICKEYBYTES, "len"); |
65 | |
|
66 | 0 | genrandom(rnd, sizeof(rnd)); |
67 | 0 | keypair = libcrux_ml_kem_mlkem768_portable_generate_key_pair(rnd); |
68 | 0 | memcpy(pk, keypair.pk.value, crypto_kem_mlkem768_PUBLICKEYBYTES); |
69 | 0 | memcpy(sk, keypair.sk.value, crypto_kem_mlkem768_SECRETKEYBYTES); |
70 | 0 | m_burn(rnd, sizeof(rnd)); |
71 | 0 | m_burn(&keypair, sizeof(keypair)); |
72 | 0 | return 0; |
73 | 0 | } |
74 | | |
75 | | int |
76 | | crypto_kem_mlkem768_enc(unsigned char *c, unsigned char *k, |
77 | | const unsigned char *pk) |
78 | 0 | { |
79 | 0 | unsigned char rnd[LIBCRUX_ML_KEM_ENC_PRNG_LEN]; |
80 | 0 | struct libcrux_mlkem768_enc_result enc; |
81 | 0 | struct libcrux_mlkem768_pk mlkem_pub; |
82 | |
|
83 | 0 | static_assert(sizeof(mlkem_pub.value) == crypto_kem_mlkem768_PUBLICKEYBYTES, "len"); |
84 | 0 | static_assert(sizeof(enc.fst.value) == crypto_kem_mlkem768_CIPHERTEXTBYTES, "len"); |
85 | 0 | static_assert(sizeof(enc.snd) == crypto_kem_mlkem768_BYTES, "len"); |
86 | |
|
87 | 0 | memcpy(mlkem_pub.value, pk, crypto_kem_mlkem768_PUBLICKEYBYTES); |
88 | | /* generate and encrypt KEM key with client key */ |
89 | 0 | genrandom(rnd, sizeof(rnd)); |
90 | 0 | enc = libcrux_ml_kem_mlkem768_portable_encapsulate(&mlkem_pub, rnd); |
91 | 0 | memcpy(c, enc.fst.value, sizeof(enc.fst.value)); |
92 | 0 | memcpy(k, enc.snd, sizeof(enc.snd)); |
93 | |
|
94 | 0 | m_burn(rnd, sizeof(rnd)); |
95 | 0 | m_burn(&enc, sizeof(enc)); |
96 | 0 | return 0; |
97 | 0 | } |
98 | | |
99 | | int |
100 | | crypto_kem_mlkem768_dec(unsigned char *k, const unsigned char *c, |
101 | | const unsigned char *sk) |
102 | 0 | { |
103 | 0 | struct libcrux_mlkem768_sk mlkem_priv; |
104 | 0 | struct libcrux_mlkem768_ciphertext mlkem_ciphertext; |
105 | |
|
106 | 0 | static_assert(sizeof(mlkem_priv.value) == crypto_kem_mlkem768_SECRETKEYBYTES, "len"); |
107 | 0 | static_assert(sizeof(mlkem_ciphertext.value) == crypto_kem_mlkem768_CIPHERTEXTBYTES, "len"); |
108 | |
|
109 | 0 | memcpy(mlkem_priv.value, sk, crypto_kem_mlkem768_SECRETKEYBYTES); |
110 | 0 | memcpy(mlkem_ciphertext.value, c, crypto_kem_mlkem768_CIPHERTEXTBYTES); |
111 | 0 | libcrux_ml_kem_mlkem768_portable_decapsulate(&mlkem_priv, |
112 | 0 | &mlkem_ciphertext, k); |
113 | 0 | m_burn(&mlkem_priv, sizeof(mlkem_priv)); |
114 | 0 | m_burn(&mlkem_ciphertext, sizeof(mlkem_ciphertext)); |
115 | 0 | return 0; |
116 | 0 | } |
117 | | |
118 | | #endif /* USE_MLKEM768 */ |