/src/boringssl/crypto/fipsmodule/bcm_interface.h
Line | Count | Source |
1 | | // Copyright 2024 The BoringSSL Authors |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | #ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_BCM_INTERFACE_H |
16 | | #define OPENSSL_HEADER_CRYPTO_FIPSMODULE_BCM_INTERFACE_H |
17 | | |
18 | | #include <openssl/aes.h> |
19 | | #include <openssl/mldsa.h> |
20 | | #include <openssl/mlkem.h> |
21 | | #include <openssl/sha.h> |
22 | | #include <openssl/sha2.h> |
23 | | |
24 | | |
25 | | // This header will eventually become the interface between BCM and the |
26 | | // rest of libcrypto. More cleanly separating the two is still a work in |
27 | | // progress (see https://crbug.com/boringssl/722) so, at the moment, we |
28 | | // consider this no different from any other header in BCM. |
29 | | // |
30 | | // Over time, calls from libcrypto to BCM will all move to this header |
31 | | // and the separation will become more meaningful. |
32 | | |
33 | | BSSL_NAMESPACE_BEGIN |
34 | | |
35 | | // Enumerated types for return values from bcm functions, both infallible |
36 | | // and fallible functions. Two success values are used to correspond to the |
37 | | // FIPS service indicator. For the moment, the official service indicator |
38 | | // remains the counter, not these values. Once we fully transition to |
39 | | // these return values from bcm we will change that. |
40 | | enum class bcm_infallible_t { |
41 | | approved, |
42 | | not_approved, |
43 | | }; |
44 | | |
45 | | enum class bcm_status_t { |
46 | | approved, |
47 | | not_approved, |
48 | | failure, |
49 | | }; |
50 | | typedef enum bcm_status_t bcm_status; |
51 | | typedef enum bcm_infallible_t bcm_infallible; |
52 | | |
53 | 49.1k | inline int bcm_success(bcm_status status) { |
54 | 49.1k | return status == bcm_status::approved || status == bcm_status::not_approved; |
55 | 49.1k | } |
56 | | |
57 | 259 | inline bcm_status_t bcm_as_approved_status(int result) { |
58 | 259 | return result ? bcm_status::approved : bcm_status::failure; |
59 | 259 | } |
60 | | |
61 | 186 | inline bcm_status_t bcm_as_not_approved_status(int result) { |
62 | 186 | return result ? bcm_status::not_approved : bcm_status::failure; |
63 | 186 | } |
64 | | |
65 | | // Random number generator. |
66 | | |
67 | | #if defined(BORINGSSL_FIPS) |
68 | | |
69 | | // We overread from /dev/urandom or RDRAND by a factor of 10 and XOR to whiten. |
70 | | // TODO(bbe): disentangle this value which is used to calculate the size of the |
71 | | // stack buffer in RAND_need entropy based on a calculation. |
72 | | #define BORINGSSL_FIPS_OVERREAD 10 |
73 | | |
74 | | #endif // BORINGSSL_FIPS |
75 | | |
76 | | // BCM_rand_load_entropy supplies |entropy_len| bytes of entropy to the BCM |
77 | | // module. The |want_additional_input| parameter is true iff the entropy was |
78 | | // obtained from a source other than the system, e.g. directly from the CPU. |
79 | | bcm_infallible BCM_rand_load_entropy(const uint8_t *entropy, size_t entropy_len, |
80 | | int want_additional_input); |
81 | | |
82 | | // BCM_rand_bytes is the same as the public |RAND_bytes| function, other |
83 | | // than returning a bcm_infallible status indicator. |
84 | | bcm_infallible BCM_rand_bytes(uint8_t *out, size_t out_len); |
85 | | |
86 | | // BCM_rand_bytes_hwrng attempts to fill |out| with |len| bytes of entropy from |
87 | | // the CPU hardware random number generator if one is present. |
88 | | // bcm_status_approved is returned on success, and a failure status is |
89 | | // returned otherwise. |
90 | | bcm_status BCM_rand_bytes_hwrng(uint8_t *out, size_t len); |
91 | | |
92 | | // BCM_rand_bytes_with_additional_data samples from the RNG after mixing 32 |
93 | | // bytes from |user_additional_data| in. |
94 | | bcm_infallible BCM_rand_bytes_with_additional_data( |
95 | | uint8_t *out, size_t out_len, const uint8_t user_additional_data[32]); |
96 | | |
97 | | |
98 | | // SHA-1 |
99 | | |
100 | | // BCM_sha1_init initialises |sha|. |
101 | | bcm_infallible BCM_sha1_init(SHA_CTX *sha); |
102 | | |
103 | | // SHA1_transform is a low-level function that performs a single, SHA-1 |
104 | | // block transformation using the state from |sha| and |SHA_CBLOCK| bytes from |
105 | | // |block|. |
106 | | bcm_infallible BCM_sha1_transform(SHA_CTX *c, const uint8_t data[SHA_CBLOCK]); |
107 | | |
108 | | // BCM_sha1_update adds |len| bytes from |data| to |sha|. |
109 | | bcm_infallible BCM_sha1_update(SHA_CTX *c, const void *data, size_t len); |
110 | | |
111 | | // BCM_sha1_final adds the final padding to |sha| and writes the resulting |
112 | | // digest to |out|, which must have at least |SHA_DIGEST_LENGTH| bytes of space. |
113 | | bcm_infallible BCM_sha1_final(uint8_t out[SHA_DIGEST_LENGTH], SHA_CTX *c); |
114 | | |
115 | | |
116 | | // BCM_fips_186_2_prf derives |out_len| bytes from |xkey| using the PRF |
117 | | // defined in FIPS 186-2, Appendix 3.1, with change notice 1 applied. The b |
118 | | // parameter is 160 and seed, XKEY, is also 160 bits. The optional XSEED user |
119 | | // input is all zeros. |
120 | | // |
121 | | // The PRF generates a sequence of 320-bit numbers. Each number is encoded as a |
122 | | // 40-byte string in big-endian and then concatenated to form |out|. If |
123 | | // |out_len| is not a multiple of 40, the result is truncated. This matches the |
124 | | // construction used in Section 7 of RFC 4186 and Section 7 of RFC 4187. |
125 | | // |
126 | | // This PRF is based on SHA-1, a weak hash function, and should not be used |
127 | | // in new protocols. It is provided for compatibility with some legacy EAP |
128 | | // methods. |
129 | | bcm_infallible BCM_fips_186_2_prf(uint8_t *out, size_t out_len, |
130 | | const uint8_t xkey[SHA_DIGEST_LENGTH]); |
131 | | |
132 | | |
133 | | // SHA-224 |
134 | | |
135 | | // BCM_sha224_unit initialises |sha|. |
136 | | bcm_infallible BCM_sha224_init(SHA256_CTX *sha); |
137 | | |
138 | | // BCM_sha224_update adds |len| bytes from |data| to |sha|. |
139 | | bcm_infallible BCM_sha224_update(SHA256_CTX *sha, const void *data, size_t len); |
140 | | |
141 | | // BCM_sha224_final adds the final padding to |sha| and writes the resulting |
142 | | // digest to |out|, which must have at least |SHA224_DIGEST_LENGTH| bytes of |
143 | | // space. It aborts on programmer error. |
144 | | bcm_infallible BCM_sha224_final(uint8_t out[SHA224_DIGEST_LENGTH], |
145 | | SHA256_CTX *sha); |
146 | | |
147 | | |
148 | | // SHA-256 |
149 | | |
150 | | // BCM_sha256_init initialises |sha|. |
151 | | bcm_infallible BCM_sha256_init(SHA256_CTX *sha); |
152 | | |
153 | | // BCM_sha256_update adds |len| bytes from |data| to |sha|. |
154 | | bcm_infallible BCM_sha256_update(SHA256_CTX *sha, const void *data, size_t len); |
155 | | |
156 | | // BCM_sha256_final adds the final padding to |sha| and writes the resulting |
157 | | // digest to |out|, which must have at least |SHA256_DIGEST_LENGTH| bytes of |
158 | | // space. It aborts on programmer error. |
159 | | bcm_infallible BCM_sha256_final(uint8_t out[SHA256_DIGEST_LENGTH], |
160 | | SHA256_CTX *sha); |
161 | | |
162 | | // BCM_sha256_transform is a low-level function that performs a single, SHA-256 |
163 | | // block transformation using the state from |sha| and |SHA256_CBLOCK| bytes |
164 | | // from |block|. |
165 | | bcm_infallible BCM_sha256_transform(SHA256_CTX *sha, |
166 | | const uint8_t block[SHA256_CBLOCK]); |
167 | | |
168 | | // BCM_sha256_transform_blocks is a low-level function that takes |num_blocks| * |
169 | | // |SHA256_CBLOCK| bytes of data and performs SHA-256 transforms on it to update |
170 | | // |state|. |
171 | | bcm_infallible BCM_sha256_transform_blocks(uint32_t state[8], |
172 | | const uint8_t *data, |
173 | | size_t num_blocks); |
174 | | |
175 | | |
176 | | // SHA-384. |
177 | | |
178 | | // BCM_sha384_init initialises |sha|. |
179 | | bcm_infallible BCM_sha384_init(SHA512_CTX *sha); |
180 | | |
181 | | // BCM_sha384_update adds |len| bytes from |data| to |sha|. |
182 | | bcm_infallible BCM_sha384_update(SHA512_CTX *sha, const void *data, size_t len); |
183 | | |
184 | | // BCM_sha384_final adds the final padding to |sha| and writes the resulting |
185 | | // digest to |out|, which must have at least |SHA384_DIGEST_LENGTH| bytes of |
186 | | // space. It may abort on programmer error. |
187 | | bcm_infallible BCM_sha384_final(uint8_t out[SHA384_DIGEST_LENGTH], |
188 | | SHA512_CTX *sha); |
189 | | |
190 | | |
191 | | // SHA-512. |
192 | | |
193 | | // BCM_sha512_init initialises |sha|. |
194 | | bcm_infallible BCM_sha512_init(SHA512_CTX *sha); |
195 | | |
196 | | // BCM_sha512_update adds |len| bytes from |data| to |sha|. |
197 | | bcm_infallible BCM_sha512_update(SHA512_CTX *sha, const void *data, size_t len); |
198 | | |
199 | | // BCM_sha512_final adds the final padding to |sha| and writes the resulting |
200 | | // digest to |out|, which must have at least |SHA512_DIGEST_LENGTH| bytes of |
201 | | // space. |
202 | | bcm_infallible BCM_sha512_final(uint8_t out[SHA512_DIGEST_LENGTH], |
203 | | SHA512_CTX *sha); |
204 | | |
205 | | // BCM_sha512_transform is a low-level function that performs a single, SHA-512 |
206 | | // block transformation using the state from |sha| and |SHA512_CBLOCK| bytes |
207 | | // from |block|. |
208 | | bcm_infallible BCM_sha512_transform(SHA512_CTX *sha, |
209 | | const uint8_t block[SHA512_CBLOCK]); |
210 | | |
211 | | |
212 | | // SHA-512-256 |
213 | | // |
214 | | // See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf section 5.3.6 |
215 | | |
216 | | // BCM_sha512_256_init initialises |sha|. |
217 | | bcm_infallible BCM_sha512_256_init(SHA512_CTX *sha); |
218 | | |
219 | | // BCM_sha512_256_update adds |len| bytes from |data| to |sha|. |
220 | | bcm_infallible BCM_sha512_256_update(SHA512_CTX *sha, const void *data, |
221 | | size_t len); |
222 | | |
223 | | // BCM_sha512_256_final adds the final padding to |sha| and writes the resulting |
224 | | // digest to |out|, which must have at least |SHA512_256_DIGEST_LENGTH| bytes of |
225 | | // space. It may abort on programmer error. |
226 | | bcm_infallible BCM_sha512_256_final(uint8_t out[SHA512_256_DIGEST_LENGTH], |
227 | | SHA512_CTX *sha); |
228 | | |
229 | | |
230 | | // ML-DSA |
231 | | // |
232 | | // Where not commented, these functions have the same signature as the |
233 | | // corresponding public function. |
234 | | |
235 | | // BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES is the number of bytes of uniformly |
236 | | // random entropy necessary to generate a signature in randomized mode. |
237 | 0 | #define BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES 32 |
238 | | |
239 | | // BCM_MLDSA65_PRIVATE_KEY_BYTES is the number of bytes in an encoded ML-DSA-65 |
240 | | // private key. |
241 | | #define BCM_MLDSA65_PRIVATE_KEY_BYTES 4032 |
242 | | |
243 | | OPENSSL_EXPORT bcm_status BCM_mldsa65_generate_key( |
244 | | uint8_t out_encoded_public_key[MLDSA65_PUBLIC_KEY_BYTES], |
245 | | uint8_t out_seed[MLDSA_SEED_BYTES], MLDSA65_private_key *out_private_key); |
246 | | |
247 | | OPENSSL_EXPORT bcm_status BCM_mldsa65_private_key_from_seed( |
248 | | MLDSA65_private_key *out_private_key, const uint8_t seed[MLDSA_SEED_BYTES]); |
249 | | |
250 | | OPENSSL_EXPORT bcm_status BCM_mldsa65_public_from_private( |
251 | | MLDSA65_public_key *out_public_key, const MLDSA65_private_key *private_key); |
252 | | |
253 | | // BCM_mldsa65_public_of_private returns the public half of |private_key|. |
254 | | const MLDSA65_public_key *BCM_mldsa65_public_of_private( |
255 | | const MLDSA65_private_key *private_key); |
256 | | |
257 | | OPENSSL_EXPORT bcm_status |
258 | | BCM_mldsa65_check_key_fips(MLDSA65_private_key *private_key); |
259 | | |
260 | | OPENSSL_EXPORT bcm_status BCM_mldsa65_generate_key_fips( |
261 | | uint8_t out_encoded_public_key[MLDSA65_PUBLIC_KEY_BYTES], |
262 | | uint8_t out_seed[MLDSA_SEED_BYTES], MLDSA65_private_key *out_private_key); |
263 | | |
264 | | OPENSSL_EXPORT bcm_status BCM_mldsa65_private_key_from_seed_fips( |
265 | | MLDSA65_private_key *out_private_key, const uint8_t seed[MLDSA_SEED_BYTES]); |
266 | | |
267 | | OPENSSL_EXPORT bcm_status |
268 | | BCM_mldsa65_sign(uint8_t out_encoded_signature[MLDSA65_SIGNATURE_BYTES], |
269 | | const MLDSA65_private_key *private_key, const uint8_t *msg, |
270 | | size_t msg_len, const uint8_t *context, size_t context_len); |
271 | | |
272 | | OPENSSL_EXPORT bcm_status BCM_mldsa65_verify( |
273 | | const MLDSA65_public_key *public_key, |
274 | | const uint8_t signature[MLDSA65_SIGNATURE_BYTES], const uint8_t *msg, |
275 | | size_t msg_len, const uint8_t *context, size_t context_len); |
276 | | |
277 | | OPENSSL_EXPORT void BCM_mldsa65_prehash_init( |
278 | | MLDSA65_prehash *out_prehash_ctx, const MLDSA65_public_key *public_key, |
279 | | const uint8_t *context, size_t context_len); |
280 | | |
281 | | OPENSSL_EXPORT void BCM_mldsa65_prehash_update( |
282 | | MLDSA65_prehash *inout_prehash_ctx, const uint8_t *msg, size_t msg_len); |
283 | | |
284 | | OPENSSL_EXPORT void BCM_mldsa65_prehash_finalize( |
285 | | uint8_t out_msg_rep[MLDSA_MU_BYTES], MLDSA65_prehash *inout_prehash_ctx); |
286 | | |
287 | | OPENSSL_EXPORT bcm_status BCM_mldsa65_sign_message_representative( |
288 | | uint8_t out_encoded_signature[MLDSA65_SIGNATURE_BYTES], |
289 | | const MLDSA65_private_key *private_key, |
290 | | const uint8_t msg_rep[MLDSA_MU_BYTES]); |
291 | | |
292 | | OPENSSL_EXPORT bcm_status BCM_mldsa65_verify_message_representative( |
293 | | const MLDSA65_public_key *public_key, |
294 | | const uint8_t signature[MLDSA65_SIGNATURE_BYTES], |
295 | | const uint8_t msg_rep[MLDSA_MU_BYTES]); |
296 | | |
297 | | OPENSSL_EXPORT bcm_status |
298 | | BCM_mldsa65_marshal_public_key(CBB *out, const MLDSA65_public_key *public_key); |
299 | | |
300 | | OPENSSL_EXPORT bcm_status |
301 | | BCM_mldsa65_parse_public_key(MLDSA65_public_key *public_key, CBS *in); |
302 | | |
303 | | OPENSSL_EXPORT bcm_status |
304 | | BCM_mldsa65_parse_private_key(MLDSA65_private_key *private_key, CBS *in); |
305 | | |
306 | | // BCM_mldsa65_generate_key_external_entropy generates a public/private key pair |
307 | | // using the given seed, writes the encoded public key to |
308 | | // |out_encoded_public_key| and sets |out_private_key| to the private key. |
309 | | OPENSSL_EXPORT bcm_status BCM_mldsa65_generate_key_external_entropy( |
310 | | uint8_t out_encoded_public_key[MLDSA65_PUBLIC_KEY_BYTES], |
311 | | MLDSA65_private_key *out_private_key, |
312 | | const uint8_t entropy[MLDSA_SEED_BYTES]); |
313 | | |
314 | | OPENSSL_EXPORT bcm_status BCM_mldsa65_generate_key_external_entropy_fips( |
315 | | uint8_t out_encoded_public_key[MLDSA65_PUBLIC_KEY_BYTES], |
316 | | MLDSA65_private_key *out_private_key, |
317 | | const uint8_t entropy[MLDSA_SEED_BYTES]); |
318 | | |
319 | | // BCM_mldsa5_sign_internal signs |msg| using |private_key| and writes the |
320 | | // signature to |out_encoded_signature|. The |context_prefix| and |context| are |
321 | | // prefixed to the message, in that order, before signing. The |randomizer| |
322 | | // value can be set to zero bytes in order to make a deterministic signature, or |
323 | | // else filled with entropy for the usual |MLDSA_sign| behavior. |
324 | | OPENSSL_EXPORT bcm_status BCM_mldsa65_sign_internal( |
325 | | uint8_t out_encoded_signature[MLDSA65_SIGNATURE_BYTES], |
326 | | const MLDSA65_private_key *private_key, const uint8_t *msg, size_t msg_len, |
327 | | const uint8_t *context_prefix, size_t context_prefix_len, |
328 | | const uint8_t *context, size_t context_len, |
329 | | const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]); |
330 | | |
331 | | OPENSSL_EXPORT bcm_status BCM_mldsa65_sign_mu_internal( |
332 | | uint8_t out_encoded_signature[MLDSA65_SIGNATURE_BYTES], |
333 | | const MLDSA65_private_key *private_key, |
334 | | const uint8_t msg_rep[MLDSA_MU_BYTES], |
335 | | const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]); |
336 | | |
337 | | // BCM_mldsa5_verify_internal verifies that |encoded_signature| is a valid |
338 | | // signature of |msg| by |public_key|. The |context_prefix| and |context| are |
339 | | // prefixed to the message before verification, in that order. |
340 | | OPENSSL_EXPORT bcm_status BCM_mldsa65_verify_internal( |
341 | | const MLDSA65_public_key *public_key, |
342 | | const uint8_t encoded_signature[MLDSA65_SIGNATURE_BYTES], |
343 | | const uint8_t *msg, size_t msg_len, const uint8_t *context_prefix, |
344 | | size_t context_prefix_len, const uint8_t *context, size_t context_len); |
345 | | |
346 | | // BCM_mldsa65_marshal_private_key serializes |private_key| to |out| in the |
347 | | // NIST format for ML-DSA-65 private keys. |
348 | | OPENSSL_EXPORT bcm_status BCM_mldsa65_marshal_private_key( |
349 | | CBB *out, const MLDSA65_private_key *private_key); |
350 | | |
351 | | // BCM_mldsa65_public_keys_equal returns one if |a| and |b| are equal and zero |
352 | | // otherwise. |
353 | | int BCM_mldsa65_public_keys_equal(const MLDSA65_public_key *a, |
354 | | const MLDSA65_public_key *b); |
355 | | |
356 | | |
357 | | // BCM_MLDSA87_PRIVATE_KEY_BYTES is the number of bytes in an encoded ML-DSA-87 |
358 | | // private key. |
359 | | #define BCM_MLDSA87_PRIVATE_KEY_BYTES 4896 |
360 | | |
361 | | OPENSSL_EXPORT bcm_status BCM_mldsa87_generate_key( |
362 | | uint8_t out_encoded_public_key[MLDSA87_PUBLIC_KEY_BYTES], |
363 | | uint8_t out_seed[MLDSA_SEED_BYTES], MLDSA87_private_key *out_private_key); |
364 | | |
365 | | OPENSSL_EXPORT bcm_status BCM_mldsa87_private_key_from_seed( |
366 | | MLDSA87_private_key *out_private_key, const uint8_t seed[MLDSA_SEED_BYTES]); |
367 | | |
368 | | OPENSSL_EXPORT bcm_status BCM_mldsa87_public_from_private( |
369 | | MLDSA87_public_key *out_public_key, const MLDSA87_private_key *private_key); |
370 | | |
371 | | // BCM_mldsa87_public_of_private returns the public half of |private_key|. |
372 | | const MLDSA87_public_key *BCM_mldsa87_public_of_private( |
373 | | const MLDSA87_private_key *private_key); |
374 | | |
375 | | OPENSSL_EXPORT bcm_status |
376 | | BCM_mldsa87_check_key_fips(MLDSA87_private_key *private_key); |
377 | | |
378 | | OPENSSL_EXPORT bcm_status BCM_mldsa87_generate_key_fips( |
379 | | uint8_t out_encoded_public_key[MLDSA87_PUBLIC_KEY_BYTES], |
380 | | uint8_t out_seed[MLDSA_SEED_BYTES], MLDSA87_private_key *out_private_key); |
381 | | |
382 | | OPENSSL_EXPORT bcm_status BCM_mldsa87_private_key_from_seed_fips( |
383 | | MLDSA87_private_key *out_private_key, const uint8_t seed[MLDSA_SEED_BYTES]); |
384 | | |
385 | | OPENSSL_EXPORT bcm_status |
386 | | BCM_mldsa87_sign(uint8_t out_encoded_signature[MLDSA87_SIGNATURE_BYTES], |
387 | | const MLDSA87_private_key *private_key, const uint8_t *msg, |
388 | | size_t msg_len, const uint8_t *context, size_t context_len); |
389 | | |
390 | | OPENSSL_EXPORT bcm_status |
391 | | BCM_mldsa87_verify(const MLDSA87_public_key *public_key, |
392 | | const uint8_t *signature, const uint8_t *msg, size_t msg_len, |
393 | | const uint8_t *context, size_t context_len); |
394 | | |
395 | | OPENSSL_EXPORT void BCM_mldsa87_prehash_init( |
396 | | MLDSA87_prehash *out_prehash_ctx, const MLDSA87_public_key *public_key, |
397 | | const uint8_t *context, size_t context_len); |
398 | | |
399 | | OPENSSL_EXPORT void BCM_mldsa87_prehash_update( |
400 | | MLDSA87_prehash *inout_prehash_ctx, const uint8_t *msg, size_t msg_len); |
401 | | |
402 | | OPENSSL_EXPORT void BCM_mldsa87_prehash_finalize( |
403 | | uint8_t out_msg_rep[MLDSA_MU_BYTES], MLDSA87_prehash *inout_prehash_ctx); |
404 | | |
405 | | OPENSSL_EXPORT bcm_status BCM_mldsa87_sign_message_representative( |
406 | | uint8_t out_encoded_signature[MLDSA87_SIGNATURE_BYTES], |
407 | | const MLDSA87_private_key *private_key, |
408 | | const uint8_t msg_rep[MLDSA_MU_BYTES]); |
409 | | |
410 | | OPENSSL_EXPORT bcm_status BCM_mldsa87_verify_message_representative( |
411 | | const MLDSA87_public_key *public_key, |
412 | | const uint8_t signature[MLDSA87_SIGNATURE_BYTES], |
413 | | const uint8_t msg_rep[MLDSA_MU_BYTES]); |
414 | | |
415 | | OPENSSL_EXPORT bcm_status |
416 | | BCM_mldsa87_marshal_public_key(CBB *out, const MLDSA87_public_key *public_key); |
417 | | |
418 | | OPENSSL_EXPORT bcm_status |
419 | | BCM_mldsa87_parse_public_key(MLDSA87_public_key *public_key, CBS *in); |
420 | | |
421 | | OPENSSL_EXPORT bcm_status |
422 | | BCM_mldsa87_parse_private_key(MLDSA87_private_key *private_key, CBS *in); |
423 | | |
424 | | // BCM_mldsa87_generate_key_external_entropy generates a public/private key pair |
425 | | // using the given seed, writes the encoded public key to |
426 | | // |out_encoded_public_key| and sets |out_private_key| to the private key. |
427 | | OPENSSL_EXPORT bcm_status BCM_mldsa87_generate_key_external_entropy( |
428 | | uint8_t out_encoded_public_key[MLDSA87_PUBLIC_KEY_BYTES], |
429 | | MLDSA87_private_key *out_private_key, |
430 | | const uint8_t entropy[MLDSA_SEED_BYTES]); |
431 | | |
432 | | OPENSSL_EXPORT bcm_status BCM_mldsa87_generate_key_external_entropy_fips( |
433 | | uint8_t out_encoded_public_key[MLDSA87_PUBLIC_KEY_BYTES], |
434 | | MLDSA87_private_key *out_private_key, |
435 | | const uint8_t entropy[MLDSA_SEED_BYTES]); |
436 | | |
437 | | // BCM_mldsa87_sign_internal signs |msg| using |private_key| and writes the |
438 | | // signature to |out_encoded_signature|. The |context_prefix| and |context| are |
439 | | // prefixed to the message, in that order, before signing. The |randomizer| |
440 | | // value can be set to zero bytes in order to make a deterministic signature, or |
441 | | // else filled with entropy for the usual |MLDSA_sign| behavior. |
442 | | OPENSSL_EXPORT bcm_status BCM_mldsa87_sign_internal( |
443 | | uint8_t out_encoded_signature[MLDSA87_SIGNATURE_BYTES], |
444 | | const MLDSA87_private_key *private_key, const uint8_t *msg, size_t msg_len, |
445 | | const uint8_t *context_prefix, size_t context_prefix_len, |
446 | | const uint8_t *context, size_t context_len, |
447 | | const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]); |
448 | | |
449 | | OPENSSL_EXPORT bcm_status BCM_mldsa87_sign_mu_internal( |
450 | | uint8_t out_encoded_signature[MLDSA87_SIGNATURE_BYTES], |
451 | | const MLDSA87_private_key *private_key, |
452 | | const uint8_t msg_rep[MLDSA_MU_BYTES], |
453 | | const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]); |
454 | | |
455 | | // BCM_mldsa87_verify_internal verifies that |encoded_signature| is a valid |
456 | | // signature of |msg| by |public_key|. The |context_prefix| and |context| are |
457 | | // prefixed to the message before verification, in that order. |
458 | | OPENSSL_EXPORT bcm_status BCM_mldsa87_verify_internal( |
459 | | const MLDSA87_public_key *public_key, |
460 | | const uint8_t encoded_signature[MLDSA87_SIGNATURE_BYTES], |
461 | | const uint8_t *msg, size_t msg_len, const uint8_t *context_prefix, |
462 | | size_t context_prefix_len, const uint8_t *context, size_t context_len); |
463 | | |
464 | | // BCM_mldsa87_marshal_private_key serializes |private_key| to |out| in the |
465 | | // NIST format for ML-DSA-87 private keys. |
466 | | OPENSSL_EXPORT bcm_status BCM_mldsa87_marshal_private_key( |
467 | | CBB *out, const MLDSA87_private_key *private_key); |
468 | | |
469 | | // BCM_mldsa87_public_keys_equal returns one if |a| and |b| are equal and zero |
470 | | // otherwise. |
471 | | int BCM_mldsa87_public_keys_equal(const MLDSA87_public_key *a, |
472 | | const MLDSA87_public_key *b); |
473 | | |
474 | | // BCM_MLDSA44_PRIVATE_KEY_BYTES is the number of bytes in an encoded ML-DSA-44 |
475 | | // private key. |
476 | | #define BCM_MLDSA44_PRIVATE_KEY_BYTES 2560 |
477 | | |
478 | | OPENSSL_EXPORT bcm_status BCM_mldsa44_generate_key( |
479 | | uint8_t out_encoded_public_key[MLDSA44_PUBLIC_KEY_BYTES], |
480 | | uint8_t out_seed[MLDSA_SEED_BYTES], MLDSA44_private_key *out_private_key); |
481 | | |
482 | | OPENSSL_EXPORT bcm_status BCM_mldsa44_private_key_from_seed( |
483 | | MLDSA44_private_key *out_private_key, const uint8_t seed[MLDSA_SEED_BYTES]); |
484 | | |
485 | | OPENSSL_EXPORT bcm_status BCM_mldsa44_public_from_private( |
486 | | MLDSA44_public_key *out_public_key, const MLDSA44_private_key *private_key); |
487 | | |
488 | | // BCM_mldsa44_public_of_private returns the public half of |private_key|. |
489 | | const MLDSA44_public_key *BCM_mldsa44_public_of_private( |
490 | | const MLDSA44_private_key *private_key); |
491 | | |
492 | | OPENSSL_EXPORT bcm_status |
493 | | BCM_mldsa44_check_key_fips(MLDSA44_private_key *private_key); |
494 | | |
495 | | OPENSSL_EXPORT bcm_status BCM_mldsa44_generate_key_fips( |
496 | | uint8_t out_encoded_public_key[MLDSA44_PUBLIC_KEY_BYTES], |
497 | | uint8_t out_seed[MLDSA_SEED_BYTES], MLDSA44_private_key *out_private_key); |
498 | | |
499 | | OPENSSL_EXPORT bcm_status BCM_mldsa44_private_key_from_seed_fips( |
500 | | MLDSA44_private_key *out_private_key, const uint8_t seed[MLDSA_SEED_BYTES]); |
501 | | |
502 | | OPENSSL_EXPORT bcm_status |
503 | | BCM_mldsa44_sign(uint8_t out_encoded_signature[MLDSA44_SIGNATURE_BYTES], |
504 | | const MLDSA44_private_key *private_key, const uint8_t *msg, |
505 | | size_t msg_len, const uint8_t *context, size_t context_len); |
506 | | |
507 | | OPENSSL_EXPORT bcm_status |
508 | | BCM_mldsa44_verify(const MLDSA44_public_key *public_key, |
509 | | const uint8_t *signature, const uint8_t *msg, size_t msg_len, |
510 | | const uint8_t *context, size_t context_len); |
511 | | |
512 | | OPENSSL_EXPORT void BCM_mldsa44_prehash_init( |
513 | | MLDSA44_prehash *out_prehash_ctx, const MLDSA44_public_key *public_key, |
514 | | const uint8_t *context, size_t context_len); |
515 | | |
516 | | OPENSSL_EXPORT void BCM_mldsa44_prehash_update( |
517 | | MLDSA44_prehash *inout_prehash_ctx, const uint8_t *msg, size_t msg_len); |
518 | | |
519 | | OPENSSL_EXPORT void BCM_mldsa44_prehash_finalize( |
520 | | uint8_t out_msg_rep[MLDSA_MU_BYTES], MLDSA44_prehash *inout_prehash_ctx); |
521 | | |
522 | | OPENSSL_EXPORT bcm_status BCM_mldsa44_sign_message_representative( |
523 | | uint8_t out_encoded_signature[MLDSA44_SIGNATURE_BYTES], |
524 | | const MLDSA44_private_key *private_key, |
525 | | const uint8_t msg_rep[MLDSA_MU_BYTES]); |
526 | | |
527 | | OPENSSL_EXPORT bcm_status BCM_mldsa44_verify_message_representative( |
528 | | const MLDSA44_public_key *public_key, |
529 | | const uint8_t signature[MLDSA44_SIGNATURE_BYTES], |
530 | | const uint8_t msg_rep[MLDSA_MU_BYTES]); |
531 | | |
532 | | OPENSSL_EXPORT bcm_status |
533 | | BCM_mldsa44_marshal_public_key(CBB *out, const MLDSA44_public_key *public_key); |
534 | | |
535 | | OPENSSL_EXPORT bcm_status |
536 | | BCM_mldsa44_parse_public_key(MLDSA44_public_key *public_key, CBS *in); |
537 | | |
538 | | OPENSSL_EXPORT bcm_status |
539 | | BCM_mldsa44_parse_private_key(MLDSA44_private_key *private_key, CBS *in); |
540 | | |
541 | | // BCM_mldsa44_generate_key_external_entropy generates a public/private key pair |
542 | | // using the given seed, writes the encoded public key to |
543 | | // |out_encoded_public_key| and sets |out_private_key| to the private key. |
544 | | OPENSSL_EXPORT bcm_status BCM_mldsa44_generate_key_external_entropy( |
545 | | uint8_t out_encoded_public_key[MLDSA44_PUBLIC_KEY_BYTES], |
546 | | MLDSA44_private_key *out_private_key, |
547 | | const uint8_t entropy[MLDSA_SEED_BYTES]); |
548 | | |
549 | | OPENSSL_EXPORT bcm_status BCM_mldsa44_generate_key_external_entropy_fips( |
550 | | uint8_t out_encoded_public_key[MLDSA44_PUBLIC_KEY_BYTES], |
551 | | MLDSA44_private_key *out_private_key, |
552 | | const uint8_t entropy[MLDSA_SEED_BYTES]); |
553 | | |
554 | | // BCM_mldsa44_sign_internal signs |msg| using |private_key| and writes the |
555 | | // signature to |out_encoded_signature|. The |context_prefix| and |context| are |
556 | | // prefixed to the message, in that order, before signing. The |randomizer| |
557 | | // value can be set to zero bytes in order to make a deterministic signature, or |
558 | | // else filled with entropy for the usual |MLDSA_sign| behavior. |
559 | | OPENSSL_EXPORT bcm_status BCM_mldsa44_sign_internal( |
560 | | uint8_t out_encoded_signature[MLDSA44_SIGNATURE_BYTES], |
561 | | const MLDSA44_private_key *private_key, const uint8_t *msg, size_t msg_len, |
562 | | const uint8_t *context_prefix, size_t context_prefix_len, |
563 | | const uint8_t *context, size_t context_len, |
564 | | const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]); |
565 | | |
566 | | OPENSSL_EXPORT bcm_status BCM_mldsa44_sign_mu_internal( |
567 | | uint8_t out_encoded_signature[MLDSA44_SIGNATURE_BYTES], |
568 | | const MLDSA44_private_key *private_key, |
569 | | const uint8_t msg_rep[MLDSA_MU_BYTES], |
570 | | const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]); |
571 | | |
572 | | // BCM_mldsa44_verify_internal verifies that |encoded_signature| is a valid |
573 | | // signature of |msg| by |public_key|. The |context_prefix| and |context| are |
574 | | // prefixed to the message before verification, in that order. |
575 | | OPENSSL_EXPORT bcm_status BCM_mldsa44_verify_internal( |
576 | | const MLDSA44_public_key *public_key, |
577 | | const uint8_t encoded_signature[MLDSA44_SIGNATURE_BYTES], |
578 | | const uint8_t *msg, size_t msg_len, const uint8_t *context_prefix, |
579 | | size_t context_prefix_len, const uint8_t *context, size_t context_len); |
580 | | |
581 | | // BCM_mldsa44_marshal_private_key serializes |private_key| to |out| in the |
582 | | // NIST format for ML-DSA-44 private keys. |
583 | | OPENSSL_EXPORT bcm_status BCM_mldsa44_marshal_private_key( |
584 | | CBB *out, const MLDSA44_private_key *private_key); |
585 | | |
586 | | // BCM_mldsa44_public_keys_equal returns one if |a| and |b| are equal and zero |
587 | | // otherwise. |
588 | | int BCM_mldsa44_public_keys_equal(const MLDSA44_public_key *a, |
589 | | const MLDSA44_public_key *b); |
590 | | |
591 | | |
592 | | // ML-KEM |
593 | | // |
594 | | // Where not commented, these functions have the same signature as the |
595 | | // corresponding public function. |
596 | | |
597 | | // BCM_MLKEM_ENCAP_ENTROPY is the number of bytes of uniformly random entropy |
598 | | // necessary to encapsulate a secret. The entropy will be leaked to the |
599 | | // decapsulating party. |
600 | 868 | #define BCM_MLKEM_ENCAP_ENTROPY 32 |
601 | | |
602 | | // BCM_MLKEM768_PRIVATE_KEY_BYTES is the length of the data produced by |
603 | | // |BCM_mlkem768_marshal_private_key|. |
604 | | #define BCM_MLKEM768_PRIVATE_KEY_BYTES 2400 |
605 | | |
606 | | // BCM_MLKEM1024_PRIVATE_KEY_BYTES is the length of the data produced by |
607 | | // |BCM_mlkem1024_marshal_private_key|. |
608 | | #define BCM_MLKEM1024_PRIVATE_KEY_BYTES 3168 |
609 | | |
610 | | OPENSSL_EXPORT bcm_infallible BCM_mlkem768_generate_key( |
611 | | uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES], |
612 | | uint8_t optional_out_seed[MLKEM_SEED_BYTES], |
613 | | MLKEM768_private_key *out_private_key); |
614 | | |
615 | | OPENSSL_EXPORT bcm_status |
616 | | BCM_mlkem768_private_key_from_seed(MLKEM768_private_key *out_private_key, |
617 | | const uint8_t *seed, size_t seed_len); |
618 | | |
619 | | OPENSSL_EXPORT bcm_status BCM_mlkem768_generate_key_fips( |
620 | | uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES], |
621 | | uint8_t optional_out_seed[MLKEM_SEED_BYTES], |
622 | | MLKEM768_private_key *out_private_key); |
623 | | |
624 | | OPENSSL_EXPORT bcm_status |
625 | | BCM_mlkem768_check_fips(const MLKEM768_private_key *private_key); |
626 | | |
627 | | OPENSSL_EXPORT bcm_infallible |
628 | | BCM_mlkem768_public_from_private(MLKEM768_public_key *out_public_key, |
629 | | const MLKEM768_private_key *private_key); |
630 | | |
631 | | OPENSSL_EXPORT const MLKEM768_public_key *BCM_mlkem768_public_of_private( |
632 | | const MLKEM768_private_key *private_key); |
633 | | |
634 | | OPENSSL_EXPORT bcm_infallible |
635 | | BCM_mlkem768_encap(uint8_t out_ciphertext[MLKEM768_CIPHERTEXT_BYTES], |
636 | | uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], |
637 | | const MLKEM768_public_key *public_key); |
638 | | |
639 | | OPENSSL_EXPORT bcm_status |
640 | | BCM_mlkem768_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], |
641 | | const uint8_t *ciphertext, size_t ciphertext_len, |
642 | | const MLKEM768_private_key *private_key); |
643 | | |
644 | | OPENSSL_EXPORT bcm_status BCM_mlkem768_marshal_public_key( |
645 | | CBB *out, const MLKEM768_public_key *public_key); |
646 | | |
647 | | // BCM_mlkem768_public_keys_equal returns one if |a| and |b| are equal and zero |
648 | | // otherwise. |
649 | | int BCM_mlkem768_public_keys_equal(const MLKEM768_public_key *a, |
650 | | const MLKEM768_public_key *b); |
651 | | |
652 | | OPENSSL_EXPORT bcm_status |
653 | | BCM_mlkem768_parse_public_key(MLKEM768_public_key *out_public_key, CBS *in); |
654 | | |
655 | | // BCM_mlkem768_parse_private_key parses a private key, in NIST's format for |
656 | | // private keys, from |in| and writes the result to |out_private_key|. It |
657 | | // returns one on success or zero on parse error or if there are trailing bytes |
658 | | // in |in|. This format is verbose and should be avoided. Private keys should be |
659 | | // stored as seeds and parsed using |BCM_mlkem768_private_key_from_seed|. |
660 | | OPENSSL_EXPORT bcm_status |
661 | | BCM_mlkem768_parse_private_key(MLKEM768_private_key *out_private_key, CBS *in); |
662 | | |
663 | | // BCM_mlkem768_generate_key_external_seed is a deterministic function to create |
664 | | // a pair of ML-KEM-768 keys, using the supplied seed. The seed needs to be |
665 | | // uniformly random. This function should only be used for tests; regular |
666 | | // callers should use the non-deterministic |BCM_mlkem768_generate_key| |
667 | | // directly. |
668 | | OPENSSL_EXPORT bcm_infallible BCM_mlkem768_generate_key_external_seed( |
669 | | uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES], |
670 | | MLKEM768_private_key *out_private_key, |
671 | | const uint8_t seed[MLKEM_SEED_BYTES]); |
672 | | |
673 | | // BCM_mlkem768_encap_external_entropy behaves like |MLKEM768_encap|, but uses |
674 | | // |MLKEM_ENCAP_ENTROPY| bytes of |entropy| for randomization. The decapsulating |
675 | | // side will be able to recover |entropy| in full. This function should only be |
676 | | // used for tests, regular callers should use the non-deterministic |
677 | | // |BCM_mlkem768_encap| directly. |
678 | | OPENSSL_EXPORT bcm_infallible BCM_mlkem768_encap_external_entropy( |
679 | | uint8_t out_ciphertext[MLKEM768_CIPHERTEXT_BYTES], |
680 | | uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], |
681 | | const MLKEM768_public_key *public_key, |
682 | | const uint8_t entropy[BCM_MLKEM_ENCAP_ENTROPY]); |
683 | | |
684 | | // BCM_mlkem768_marshal_private_key serializes |private_key| to |out| in the |
685 | | // NIST format for ML-KEM-768 private keys. (Note that one can also save just |
686 | | // the seed value produced by |BCM_mlkem768_generate_key|, which is |
687 | | // significantly smaller.) |
688 | | OPENSSL_EXPORT bcm_status BCM_mlkem768_marshal_private_key( |
689 | | CBB *out, const MLKEM768_private_key *private_key); |
690 | | |
691 | | OPENSSL_EXPORT bcm_infallible BCM_mlkem1024_generate_key( |
692 | | uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES], |
693 | | uint8_t optional_out_seed[MLKEM_SEED_BYTES], |
694 | | MLKEM1024_private_key *out_private_key); |
695 | | |
696 | | OPENSSL_EXPORT bcm_status BCM_mlkem1024_generate_key_fips( |
697 | | uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES], |
698 | | uint8_t optional_out_seed[MLKEM_SEED_BYTES], |
699 | | MLKEM1024_private_key *out_private_key); |
700 | | |
701 | | OPENSSL_EXPORT bcm_status |
702 | | BCM_mlkem1024_check_fips(const MLKEM1024_private_key *private_key); |
703 | | |
704 | | OPENSSL_EXPORT bcm_status |
705 | | BCM_mlkem1024_private_key_from_seed(MLKEM1024_private_key *out_private_key, |
706 | | const uint8_t *seed, size_t seed_len); |
707 | | |
708 | | OPENSSL_EXPORT bcm_infallible |
709 | | BCM_mlkem1024_public_from_private(MLKEM1024_public_key *out_public_key, |
710 | | const MLKEM1024_private_key *private_key); |
711 | | |
712 | | OPENSSL_EXPORT const MLKEM1024_public_key *BCM_mlkem1024_public_of_private( |
713 | | const MLKEM1024_private_key *private_key); |
714 | | |
715 | | OPENSSL_EXPORT bcm_infallible |
716 | | BCM_mlkem1024_encap(uint8_t out_ciphertext[MLKEM1024_CIPHERTEXT_BYTES], |
717 | | uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], |
718 | | const MLKEM1024_public_key *public_key); |
719 | | |
720 | | OPENSSL_EXPORT bcm_status |
721 | | BCM_mlkem1024_decap(uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], |
722 | | const uint8_t *ciphertext, size_t ciphertext_len, |
723 | | const MLKEM1024_private_key *private_key); |
724 | | |
725 | | OPENSSL_EXPORT bcm_status BCM_mlkem1024_marshal_public_key( |
726 | | CBB *out, const MLKEM1024_public_key *public_key); |
727 | | |
728 | | // BCM_mlkem1024_public_keys_equal returns one if |a| and |b| are equal and zero |
729 | | // otherwise. |
730 | | int BCM_mlkem1024_public_keys_equal(const MLKEM1024_public_key *a, |
731 | | const MLKEM1024_public_key *b); |
732 | | |
733 | | OPENSSL_EXPORT bcm_status |
734 | | BCM_mlkem1024_parse_public_key(MLKEM1024_public_key *out_public_key, CBS *in); |
735 | | |
736 | | // BCM_mlkem1024_parse_private_key parses a private key, in NIST's format for |
737 | | // private keys, from |in| and writes the result to |out_private_key|. It |
738 | | // returns one on success or zero on parse error or if there are trailing bytes |
739 | | // in |in|. This format is verbose and should be avoided. Private keys should be |
740 | | // stored as seeds and parsed using |BCM_mlkem1024_private_key_from_seed|. |
741 | | OPENSSL_EXPORT bcm_status BCM_mlkem1024_parse_private_key( |
742 | | MLKEM1024_private_key *out_private_key, CBS *in); |
743 | | |
744 | | // BCM_mlkem1024_generate_key_external_seed is a deterministic function to |
745 | | // create a pair of ML-KEM-1024 keys, using the supplied seed. The seed needs to |
746 | | // be uniformly random. This function should only be used for tests, regular |
747 | | // callers should use the non-deterministic |BCM_mlkem1024_generate_key| |
748 | | // directly. |
749 | | OPENSSL_EXPORT bcm_infallible BCM_mlkem1024_generate_key_external_seed( |
750 | | uint8_t out_encoded_public_key[MLKEM1024_PUBLIC_KEY_BYTES], |
751 | | MLKEM1024_private_key *out_private_key, |
752 | | const uint8_t seed[MLKEM_SEED_BYTES]); |
753 | | |
754 | | // BCM_mlkem1024_encap_external_entropy behaves like |MLKEM1024_encap|, but uses |
755 | | // |MLKEM_ENCAP_ENTROPY| bytes of |entropy| for randomization. The |
756 | | // decapsulating side will be able to recover |entropy| in full. This function |
757 | | // should only be used for tests, regular callers should use the |
758 | | // non-deterministic |BCM_mlkem1024_encap| directly. |
759 | | OPENSSL_EXPORT bcm_infallible BCM_mlkem1024_encap_external_entropy( |
760 | | uint8_t out_ciphertext[MLKEM1024_CIPHERTEXT_BYTES], |
761 | | uint8_t out_shared_secret[MLKEM_SHARED_SECRET_BYTES], |
762 | | const MLKEM1024_public_key *public_key, |
763 | | const uint8_t entropy[BCM_MLKEM_ENCAP_ENTROPY]); |
764 | | |
765 | | // BCM_mlkem1024_marshal_private_key serializes |private_key| to |out| in the |
766 | | // NIST format for ML-KEM-1024 private keys. (Note that one can also save just |
767 | | // the seed value produced by |BCM_mlkem1024_generate_key|, which is |
768 | | // significantly smaller.) |
769 | | OPENSSL_EXPORT bcm_status BCM_mlkem1024_marshal_private_key( |
770 | | CBB *out, const MLKEM1024_private_key *private_key); |
771 | | |
772 | | |
773 | | // SLH-DSA |
774 | | |
775 | | // Output length of the hash function. |
776 | 0 | #define BCM_SLHDSA_SHA2_128S_N 16 |
777 | 0 | #define BCM_SLHDSA_SHAKE_256F_N 32 |
778 | | |
779 | | // The number of bytes at the beginning of M', the augmented message, before the |
780 | | // context. |
781 | 0 | #define BCM_SLHDSA_M_PRIME_HEADER_LEN 2 |
782 | | |
783 | | // SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES is the number of bytes in an |
784 | | // SLH-DSA-SHA2-128s public key. |
785 | | #define BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES 32 |
786 | | #define BCM_SLHDSA_SHAKE_256F_PUBLIC_KEY_BYTES 64 |
787 | | |
788 | | // BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES is the number of bytes in an |
789 | | // SLH-DSA-SHA2-128s private key. |
790 | | #define BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES 64 |
791 | | #define BCM_SLHDSA_SHAKE_256F_PRIVATE_KEY_BYTES 128 |
792 | | |
793 | | // BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES is the number of bytes in an |
794 | | // SLH-DSA-SHA2-128s signature. |
795 | | #define BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES 7856 |
796 | | #define BCM_SLHDSA_SHAKE_256F_SIGNATURE_BYTES 49856 |
797 | | |
798 | | // BCM_slhdsa_sha2_128s_generate_key_from_seed generates an SLH-DSA-SHA2-128s |
799 | | // key pair from a 48-byte seed and writes the result to |out_public_key| and |
800 | | // |out_secret_key|. |
801 | | OPENSSL_EXPORT bcm_infallible BCM_slhdsa_sha2_128s_generate_key_from_seed( |
802 | | uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], |
803 | | uint8_t out_secret_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES], |
804 | | const uint8_t seed[3 * BCM_SLHDSA_SHA2_128S_N]); |
805 | | |
806 | | OPENSSL_EXPORT bcm_infallible BCM_slhdsa_shake_256f_generate_key_from_seed( |
807 | | uint8_t out_public_key[BCM_SLHDSA_SHAKE_256F_PUBLIC_KEY_BYTES], |
808 | | uint8_t out_secret_key[BCM_SLHDSA_SHAKE_256F_PRIVATE_KEY_BYTES], |
809 | | const uint8_t seed[3 * BCM_SLHDSA_SHAKE_256F_N]); |
810 | | |
811 | | // BCM_slhdsa_sha2_128s_generate_key_from_seed_fips does the same thing as |
812 | | // `BCM_slhdsa_sha2_128s_generate_key_from_seed` but implements the required |
813 | | // second check before generating a key by testing for nullptr arguments. |
814 | | OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_generate_key_from_seed_fips( |
815 | | uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], |
816 | | uint8_t out_secret_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES], |
817 | | const uint8_t seed[3 * BCM_SLHDSA_SHA2_128S_N]); |
818 | | |
819 | | OPENSSL_EXPORT bcm_status BCM_slhdsa_shake_256f_generate_key_from_seed_fips( |
820 | | uint8_t out_public_key[BCM_SLHDSA_SHAKE_256F_PUBLIC_KEY_BYTES], |
821 | | uint8_t out_secret_key[BCM_SLHDSA_SHAKE_256F_PRIVATE_KEY_BYTES], |
822 | | const uint8_t seed[3 * BCM_SLHDSA_SHAKE_256F_N]); |
823 | | |
824 | | // BCM_slhdsa_sha2_128s_sign_internal acts like |SLHDSA_SHA2_128S_sign| but |
825 | | // accepts an explicit entropy input, which can be PK.seed (bytes 32..48 of |
826 | | // the private key) to generate deterministic signatures. It also takes the |
827 | | // input message in three parts so that the "internal" version of the signing |
828 | | // function, from section 9.2, can be implemented. The |header| argument may be |
829 | | // NULL to omit it. |
830 | | OPENSSL_EXPORT bcm_infallible BCM_slhdsa_sha2_128s_sign_internal( |
831 | | uint8_t out_signature[BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES], |
832 | | const uint8_t secret_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES], |
833 | | const uint8_t header[BCM_SLHDSA_M_PRIME_HEADER_LEN], const uint8_t *context, |
834 | | size_t context_len, const uint8_t *msg, size_t msg_len, |
835 | | const uint8_t entropy[BCM_SLHDSA_SHA2_128S_N]); |
836 | | |
837 | | OPENSSL_EXPORT bcm_infallible BCM_slhdsa_shake_256f_sign_internal( |
838 | | uint8_t out_signature[BCM_SLHDSA_SHAKE_256F_SIGNATURE_BYTES], |
839 | | const uint8_t secret_key[BCM_SLHDSA_SHAKE_256F_PRIVATE_KEY_BYTES], |
840 | | const uint8_t header[BCM_SLHDSA_M_PRIME_HEADER_LEN], const uint8_t *context, |
841 | | size_t context_len, const uint8_t *msg, size_t msg_len, |
842 | | const uint8_t entropy[BCM_SLHDSA_SHAKE_256F_N]); |
843 | | |
844 | | // BCM_slhdsa_sha2_128s_verify_internal acts like |SLHDSA_SHA2_128S_verify| but |
845 | | // takes the input message in three parts so that the "internal" version of the |
846 | | // verification function, from section 9.3, can be implemented. The |header| |
847 | | // argument may be NULL to omit it. |
848 | | OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_verify_internal( |
849 | | const uint8_t *signature, size_t signature_len, |
850 | | const uint8_t public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], |
851 | | const uint8_t header[BCM_SLHDSA_M_PRIME_HEADER_LEN], const uint8_t *context, |
852 | | size_t context_len, const uint8_t *msg, size_t msg_len); |
853 | | |
854 | | OPENSSL_EXPORT bcm_status BCM_slhdsa_shake_256f_verify_internal( |
855 | | const uint8_t *signature, size_t signature_len, |
856 | | const uint8_t public_key[BCM_SLHDSA_SHAKE_256F_PUBLIC_KEY_BYTES], |
857 | | const uint8_t header[BCM_SLHDSA_M_PRIME_HEADER_LEN], const uint8_t *context, |
858 | | size_t context_len, const uint8_t *msg, size_t msg_len); |
859 | | |
860 | | OPENSSL_EXPORT bcm_infallible BCM_slhdsa_sha2_128s_generate_key( |
861 | | uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], |
862 | | uint8_t out_private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]); |
863 | | |
864 | | OPENSSL_EXPORT bcm_infallible BCM_slhdsa_shake_256f_generate_key( |
865 | | uint8_t out_public_key[BCM_SLHDSA_SHAKE_256F_PUBLIC_KEY_BYTES], |
866 | | uint8_t out_private_key[BCM_SLHDSA_SHAKE_256F_PRIVATE_KEY_BYTES]); |
867 | | |
868 | | OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_generate_key_fips( |
869 | | uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], |
870 | | uint8_t out_private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]); |
871 | | |
872 | | OPENSSL_EXPORT bcm_status BCM_slhdsa_shake_256f_generate_key_fips( |
873 | | uint8_t out_public_key[BCM_SLHDSA_SHAKE_256F_PUBLIC_KEY_BYTES], |
874 | | uint8_t out_private_key[BCM_SLHDSA_SHAKE_256F_PRIVATE_KEY_BYTES]); |
875 | | |
876 | | OPENSSL_EXPORT bcm_infallible BCM_slhdsa_sha2_128s_public_from_private( |
877 | | uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], |
878 | | const uint8_t private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]); |
879 | | |
880 | | OPENSSL_EXPORT bcm_infallible BCM_slhdsa_shake_256f_public_from_private( |
881 | | uint8_t out_public_key[BCM_SLHDSA_SHAKE_256F_PUBLIC_KEY_BYTES], |
882 | | const uint8_t private_key[BCM_SLHDSA_SHAKE_256F_PRIVATE_KEY_BYTES]); |
883 | | |
884 | | OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_sign( |
885 | | uint8_t out_signature[BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES], |
886 | | const uint8_t private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES], |
887 | | const uint8_t *msg, size_t msg_len, const uint8_t *context, |
888 | | size_t context_len); |
889 | | |
890 | | OPENSSL_EXPORT bcm_status BCM_slhdsa_shake_256f_sign( |
891 | | uint8_t out_signature[BCM_SLHDSA_SHAKE_256F_SIGNATURE_BYTES], |
892 | | const uint8_t private_key[BCM_SLHDSA_SHAKE_256F_PRIVATE_KEY_BYTES], |
893 | | const uint8_t *msg, size_t msg_len, const uint8_t *context, |
894 | | size_t context_len); |
895 | | |
896 | | OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_verify( |
897 | | const uint8_t *signature, size_t signature_len, |
898 | | const uint8_t public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], |
899 | | const uint8_t *msg, size_t msg_len, const uint8_t *context, |
900 | | size_t context_len); |
901 | | |
902 | | OPENSSL_EXPORT bcm_status BCM_slhdsa_shake_256f_verify( |
903 | | const uint8_t *signature, size_t signature_len, |
904 | | const uint8_t public_key[BCM_SLHDSA_SHAKE_256F_PUBLIC_KEY_BYTES], |
905 | | const uint8_t *msg, size_t msg_len, const uint8_t *context, |
906 | | size_t context_len); |
907 | | |
908 | | OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_prehash_sign( |
909 | | uint8_t out_signature[BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES], |
910 | | const uint8_t private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES], |
911 | | const uint8_t *hashed_msg, size_t hashed_msg_len, int hash_nid, |
912 | | const uint8_t *context, size_t context_len); |
913 | | |
914 | | OPENSSL_EXPORT bcm_status BCM_slhdsa_shake_256f_prehash_sign( |
915 | | uint8_t out_signature[BCM_SLHDSA_SHAKE_256F_SIGNATURE_BYTES], |
916 | | const uint8_t private_key[BCM_SLHDSA_SHAKE_256F_PRIVATE_KEY_BYTES], |
917 | | const uint8_t *hashed_msg, size_t hashed_msg_len, int hash_nid, |
918 | | const uint8_t *context, size_t context_len); |
919 | | |
920 | | OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_prehash_verify( |
921 | | const uint8_t *signature, size_t signature_len, |
922 | | const uint8_t public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES], |
923 | | const uint8_t *hashed_msg, size_t hashed_msg_len, int hash_nid, |
924 | | const uint8_t *context, size_t context_len); |
925 | | |
926 | | OPENSSL_EXPORT bcm_status BCM_slhdsa_shake_256f_prehash_verify( |
927 | | const uint8_t *signature, size_t signature_len, |
928 | | const uint8_t public_key[BCM_SLHDSA_SHAKE_256F_PUBLIC_KEY_BYTES], |
929 | | const uint8_t *hashed_msg, size_t hashed_msg_len, int hash_nid, |
930 | | const uint8_t *context, size_t context_len); |
931 | | |
932 | | |
933 | | // AES |
934 | | |
935 | | // BCM_aes_encrypt encrypts a single block from |in| to |out| with |key|. The |
936 | | // |in| and |out| pointers may overlap. |
937 | | bcm_infallible BCM_aes_encrypt(const uint8_t *in, uint8_t *out, |
938 | | const AES_KEY *key); |
939 | | // BCM_aes_decrypt decrypts a single block from |in| to |out| with |key|. The |
940 | | // |in| and |out| pointers may overlap. |
941 | | bcm_infallible BCM_aes_decrypt(const uint8_t *in, uint8_t *out, |
942 | | const AES_KEY *key); |
943 | | |
944 | | // BCM_aes_set_encrypt_key configures |aeskey| to encrypt with the |bits|-bit |
945 | | // key, |key|. |key| must point to |bits|/8 bytes. It will return failure if |
946 | | // |bits| is an invalid AES key size. |
947 | | bcm_status BCM_aes_set_encrypt_key(const uint8_t *key, unsigned bits, |
948 | | AES_KEY *aeskey); |
949 | | |
950 | | // BCM_aes_set_decrypt_key configures |aeskey| to decrypt with the |bits|-bit |
951 | | // key, |key|. |key| must point to |bits|/8 bytes. It will return failure if |
952 | | // |bits| is an invalid AES key size. |
953 | | bcm_status BCM_aes_set_decrypt_key(const uint8_t *key, unsigned bits, |
954 | | AES_KEY *aeskey); |
955 | | |
956 | | BSSL_NAMESPACE_END |
957 | | |
958 | | |
959 | | #endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_BCM_INTERFACE_H |