diff options
Diffstat (limited to 'src/lib/libcrypto/mlkem/mlkem.h')
-rw-r--r-- | src/lib/libcrypto/mlkem/mlkem.h | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/src/lib/libcrypto/mlkem/mlkem.h b/src/lib/libcrypto/mlkem/mlkem.h new file mode 100644 index 0000000000..8040f4844b --- /dev/null +++ b/src/lib/libcrypto/mlkem/mlkem.h | |||
@@ -0,0 +1,168 @@ | |||
1 | /* Copyright (c) 2024, Google Inc. | ||
2 | * | ||
3 | * Permission to use, copy, modify, and/or distribute this software for any | ||
4 | * purpose with or without fee is hereby granted, provided that the above | ||
5 | * copyright notice and this permission notice appear in all copies. | ||
6 | * | ||
7 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
8 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
9 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY | ||
10 | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
11 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION | ||
12 | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||
13 | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ | ||
14 | |||
15 | #ifndef OPENSSL_HEADER_MLKEM_H | ||
16 | #define OPENSSL_HEADER_MLKEM_H | ||
17 | |||
18 | #include <sys/types.h> | ||
19 | #include <stdint.h> | ||
20 | |||
21 | #ifdef LIBRESSL_HAS_MLKEM | ||
22 | /* This needs to become public */ | ||
23 | #include <openssl/bytestring.h> | ||
24 | #else | ||
25 | /* Hack for now */ | ||
26 | struct cbs_st; | ||
27 | struct cbb_st; | ||
28 | #endif | ||
29 | |||
30 | #if defined(__cplusplus) | ||
31 | extern "C" { | ||
32 | #endif | ||
33 | |||
34 | /* | ||
35 | * ML-KEM-768 | ||
36 | * | ||
37 | * This implements the Module-Lattice-Based Key-Encapsulation Mechanism from | ||
38 | * https://csrc.nist.gov/pubs/fips/204/final | ||
39 | */ | ||
40 | |||
41 | /* | ||
42 | * MLKEM768_public_key contains a ML-KEM-768 public key. The contents of this | ||
43 | * object should never leave the address space since the format is unstable. | ||
44 | */ | ||
45 | struct MLKEM768_public_key { | ||
46 | union { | ||
47 | uint8_t bytes[512 * (3 + 9) + 32 + 32]; | ||
48 | uint16_t alignment; | ||
49 | } opaque; | ||
50 | }; | ||
51 | |||
52 | /* | ||
53 | * MLKEM768_private_key contains a ML-KEM-768 private key. The contents of this | ||
54 | * object should never leave the address space since the format is unstable. | ||
55 | */ | ||
56 | struct MLKEM768_private_key { | ||
57 | union { | ||
58 | uint8_t bytes[512 * (3 + 3 + 9) + 32 + 32 + 32]; | ||
59 | uint16_t alignment; | ||
60 | } opaque; | ||
61 | }; | ||
62 | |||
63 | /* | ||
64 | * MLKEM768_PUBLIC_KEY_BYTES is the number of bytes in an encoded ML-KEM768 public | ||
65 | * key. | ||
66 | */ | ||
67 | #define MLKEM768_PUBLIC_KEY_BYTES 1184 | ||
68 | |||
69 | /* MLKEM_SEED_BYTES is the number of bytes in an ML-KEM seed. */ | ||
70 | #define MLKEM_SEED_BYTES 64 | ||
71 | |||
72 | /* | ||
73 | * MLKEM_SHARED_SECRET_BYTES is the number of bytes in the ML-KEM768 shared | ||
74 | * secret. Although the round-3 specification has a variable-length output, the | ||
75 | * final ML-KEM construction is expected to use a fixed 32-byte output. To | ||
76 | * simplify the future transition, we apply the same restriction. | ||
77 | */ | ||
78 | #define MLKEM_SHARED_SECRET_BYTES 32 | ||
79 | |||
80 | /* | ||
81 | * MLKEM_generate_key generates a random public/private key pair, writes the | ||
82 | * encoded public key to |out_encoded_public_key| and sets |out_private_key| to | ||
83 | * the private key. If |optional_out_seed| us not NULL then te seed used to | ||
84 | * generate te private key is written to it. | ||
85 | */ | ||
86 | void MLKEM768_generate_key( | ||
87 | uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES], | ||
88 | uint8_t optional_out_seed[MLKEM_SEED_BYTES], | ||
89 | struct MLKEM768_private_key *out_private_key); | ||
90 | |||
91 | /* | ||
92 | * MLKEM768_private_key_from_seed derives a private key from a seed that was | ||
93 | * generated by |MLKEM768_generate_key|. It fails and returns 0 if |seed_len| is | ||
94 | * incorrect, otherwise it writes |*out_private_key| and returns 1. | ||
95 | */ | ||
96 | int MLKEM768_private_key_from_seed(struct MLKEM768_private_key *out_private_key, | ||
97 | const uint8_t *seed, size_t seed_len); | ||
98 | |||
99 | /* | ||
100 | * MLKEM_public_from_private sets |*out_public_key| to the public key that | ||
101 | * corresponds to |private_key|. (This is faster than parsing the output of | ||
102 | * |MLKEM_generate_key| if, for some reason, you need to encapsulate to a key | ||
103 | * that was just generated.) | ||
104 | */ | ||
105 | void MLKEM768_public_from_private(struct MLKEM768_public_key *out_public_key, | ||
106 | const struct MLKEM768_private_key *private_key); | ||
107 | |||
108 | /* MLKEM768_CIPHERTEXT_BYTES is number of bytes in the ML-KEM768 ciphertext. */ | ||
109 | #define MLKEM768_CIPHERTEXT_BYTES 1088 | ||
110 | |||
111 | /* | ||
112 | * MLKEM768_encap encrypts a random shared secret for |public_key|, writes the | ||
113 | * ciphertext to |out_ciphertext|, and writes the random shared secret to | ||
114 | * |out_shared_secret|. | ||
115 | */ | ||
116 | void MLKEM768_encap(uint8_t out_ciphertext[MLKEM768_CIPHERTEXT_BYTES], | ||
117 | uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], | ||
118 | const struct MLKEM768_public_key *public_key); | ||
119 | |||
120 | /* | ||
121 | * MLKEM768_decap decrypts a shared secret from |ciphertext| using |private_key| | ||
122 | * and writes it to |out_shared_secret|. If |ciphertext_len| is incorrect it | ||
123 | * returns 0, otherwise it rreturns 1. If |ciphertext| is invalid, | ||
124 | * |out_shared_secret| is filled with a key that will always be the same for the | ||
125 | * same |ciphertext| and |private_key|, but which appears to be random unless | ||
126 | * one has access to |private_key|. These alternatives occur in constant time. | ||
127 | * Any subsequent symmetric encryption using |out_shared_secret| must use an | ||
128 | * authenticated encryption scheme in order to discover the decapsulation | ||
129 | * failure. | ||
130 | */ | ||
131 | int MLKEM768_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], | ||
132 | const uint8_t *ciphertext, size_t ciphertext_len, | ||
133 | const struct MLKEM768_private_key *private_key); | ||
134 | |||
135 | /* Serialisation of keys. */ | ||
136 | |||
137 | /* | ||
138 | * MLKEM768_marshal_public_key serializes |public_key| to |out| in the standard | ||
139 | * format for ML-KEM public keys. It returns one on success or zero on allocation | ||
140 | * error. | ||
141 | */ | ||
142 | int MLKEM768_marshal_public_key(struct cbb_st *out, | ||
143 | const struct MLKEM768_public_key *public_key); | ||
144 | |||
145 | /* | ||
146 | * MLKEM768_parse_public_key parses a public key, in the format generated by | ||
147 | * |MLKEM_marshal_public_key|, from |in| and writes the result to | ||
148 | * |out_public_key|. It returns one on success or zero on parse error or if | ||
149 | * there are trailing bytes in |in|. | ||
150 | */ | ||
151 | int MLKEM768_parse_public_key(struct MLKEM768_public_key *out_public_key, | ||
152 | struct cbs_st *in); | ||
153 | |||
154 | /* | ||
155 | * MLKEM_parse_private_key parses a private key, in the format generated by | ||
156 | * |MLKEM_marshal_private_key|, from |in| and writes the result to | ||
157 | * |out_private_key|. It returns one on success or zero on parse error or if | ||
158 | * there are trailing bytes in |in|. This formate is verbose and should be avoided. | ||
159 | * Private keys should be stored as seeds and parsed using |MLKEM768_private_key_from_seed|. | ||
160 | */ | ||
161 | int MLKEM768_parse_private_key(struct MLKEM768_private_key *out_private_key, | ||
162 | struct cbs_st *in); | ||
163 | |||
164 | #if defined(__cplusplus) | ||
165 | } | ||
166 | #endif | ||
167 | |||
168 | #endif /* OPENSSL_HEADER_MLKEM_H */ | ||