• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2024 The BoringSSL Authors
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_CRYPTO_BCM_INTERFACE_H
16 #define OPENSSL_HEADER_CRYPTO_BCM_INTERFACE_H
17 
18 #include <openssl/bcm_public.h>
19 
20 // This header will eventually become the interface between BCM and the
21 // rest of libcrypto. More cleanly separating the two is still a work in
22 // progress (see https://crbug.com/boringssl/722) so, at the moment, we
23 // consider this no different from any other header in BCM.
24 //
25 // Over time, calls from libcrypto to BCM will all move to this header
26 // and the separation will become more meaningful.
27 
28 #if defined(__cplusplus)
29 extern "C" {
30 #endif
31 
32 // Enumerated types for return values from bcm functions, both infallible
33 // and fallible functions. Two success values are used to correspond to the
34 // FIPS service indicator. For the moment, the official service indicator
35 // remains the counter, not these values. Once we fully transition to
36 // these return values from bcm we will change that.
37 enum class bcm_infallible_t {
38   approved,
39   not_approved,
40 };
41 
42 enum class bcm_status_t {
43   approved,
44   not_approved,
45   failure,
46 };
47 typedef enum bcm_status_t bcm_status;
48 typedef enum bcm_infallible_t bcm_infallible;
49 
bcm_success(bcm_status status)50 inline int bcm_success(bcm_status status) {
51   return status == bcm_status::approved || status == bcm_status::not_approved;
52 }
53 
bcm_as_approved_status(int result)54 inline bcm_status_t bcm_as_approved_status(int result) {
55   return result ? bcm_status::approved : bcm_status::failure;
56 }
57 
bcm_as_not_approved_status(int result)58 inline bcm_status_t bcm_as_not_approved_status(int result) {
59   return result ? bcm_status::not_approved : bcm_status::failure;
60 }
61 
62 // Random number generator.
63 
64 #if defined(BORINGSSL_FIPS)
65 
66 // We overread from /dev/urandom or RDRAND by a factor of 10 and XOR to whiten.
67 // TODO(bbe): disentangle this value which is used to calculate the size of the
68 // stack buffer in RAND_need entropy based on a calculation.
69 #define BORINGSSL_FIPS_OVERREAD 10
70 
71 #endif  // BORINGSSL_FIPS
72 
73 // BCM_rand_load_entropy supplies |entropy_len| bytes of entropy to the BCM
74 // module. The |want_additional_input| parameter is true iff the entropy was
75 // obtained from a source other than the system, e.g. directly from the CPU.
76 bcm_infallible BCM_rand_load_entropy(const uint8_t *entropy, size_t entropy_len,
77                                      int want_additional_input);
78 
79 // BCM_rand_bytes is the same as the public |RAND_bytes| function, other
80 // than returning a bcm_infallible status indicator.
81 OPENSSL_EXPORT bcm_infallible BCM_rand_bytes(uint8_t *out, size_t out_len);
82 
83 // BCM_rand_bytes_hwrng attempts to fill |out| with |len| bytes of entropy from
84 // the CPU hardware random number generator if one is present.
85 // bcm_status_approved is returned on success, and a failure status is
86 // returned otherwise.
87 bcm_status BCM_rand_bytes_hwrng(uint8_t *out, size_t len);
88 
89 // BCM_rand_bytes_with_additional_data samples from the RNG after mixing 32
90 // bytes from |user_additional_data| in.
91 bcm_infallible BCM_rand_bytes_with_additional_data(
92     uint8_t *out, size_t out_len, const uint8_t user_additional_data[32]);
93 
94 
95 // SHA-1
96 
97 // BCM_SHA_DIGEST_LENGTH is the length of a SHA-1 digest.
98 #define BCM_SHA_DIGEST_LENGTH 20
99 
100 // BCM_sha1_init initialises |sha|.
101 bcm_infallible BCM_sha1_init(SHA_CTX *sha);
102 
103 // BCM_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,
107                                   const uint8_t data[BCM_SHA_CBLOCK]);
108 
109 // BCM_sha1_update adds |len| bytes from |data| to |sha|.
110 bcm_infallible BCM_sha1_update(SHA_CTX *c, const void *data, size_t len);
111 
112 // BCM_sha1_final adds the final padding to |sha| and writes the resulting
113 // digest to |out|, which must have at least |SHA_DIGEST_LENGTH| bytes of space.
114 bcm_infallible BCM_sha1_final(uint8_t out[BCM_SHA_DIGEST_LENGTH], SHA_CTX *c);
115 
116 
117 // BCM_fips_186_2_prf derives |out_len| bytes from |xkey| using the PRF
118 // defined in FIPS 186-2, Appendix 3.1, with change notice 1 applied. The b
119 // parameter is 160 and seed, XKEY, is also 160 bits. The optional XSEED user
120 // input is all zeros.
121 //
122 // The PRF generates a sequence of 320-bit numbers. Each number is encoded as a
123 // 40-byte string in big-endian and then concatenated to form |out|. If
124 // |out_len| is not a multiple of 40, the result is truncated. This matches the
125 // construction used in Section 7 of RFC 4186 and Section 7 of RFC 4187.
126 //
127 // This PRF is based on SHA-1, a weak hash function, and should not be used
128 // in new protocols. It is provided for compatibility with some legacy EAP
129 // methods.
130 bcm_infallible BCM_fips_186_2_prf(uint8_t *out, size_t out_len,
131                                   const uint8_t xkey[BCM_SHA_DIGEST_LENGTH]);
132 
133 
134 // SHA-224
135 
136 // SHA224_DIGEST_LENGTH is the length of a SHA-224 digest.
137 #define BCM_SHA224_DIGEST_LENGTH 28
138 
139 // BCM_sha224_unit initialises |sha|.
140 bcm_infallible BCM_sha224_init(SHA256_CTX *sha);
141 
142 // BCM_sha224_update adds |len| bytes from |data| to |sha|.
143 bcm_infallible BCM_sha224_update(SHA256_CTX *sha, const void *data, size_t len);
144 
145 // BCM_sha224_final adds the final padding to |sha| and writes the resulting
146 // digest to |out|, which must have at least |SHA224_DIGEST_LENGTH| bytes of
147 // space. It aborts on programmer error.
148 bcm_infallible BCM_sha224_final(uint8_t out[BCM_SHA224_DIGEST_LENGTH],
149                                 SHA256_CTX *sha);
150 
151 
152 // SHA-256
153 
154 // BCM_SHA256_DIGEST_LENGTH is the length of a SHA-256 digest.
155 #define BCM_SHA256_DIGEST_LENGTH 32
156 
157 // BCM_sha256_init initialises |sha|.
158 bcm_infallible BCM_sha256_init(SHA256_CTX *sha);
159 
160 // BCM_sha256_update adds |len| bytes from |data| to |sha|.
161 bcm_infallible BCM_sha256_update(SHA256_CTX *sha, const void *data, size_t len);
162 
163 // BCM_sha256_final adds the final padding to |sha| and writes the resulting
164 // digest to |out|, which must have at least |BCM_SHA256_DIGEST_LENGTH| bytes of
165 // space. It aborts on programmer error.
166 bcm_infallible BCM_sha256_final(uint8_t out[BCM_SHA256_DIGEST_LENGTH],
167                                 SHA256_CTX *sha);
168 
169 // BCM_sha256_transform is a low-level function that performs a single, SHA-256
170 // block transformation using the state from |sha| and |BCM_SHA256_CBLOCK| bytes
171 // from |block|.
172 bcm_infallible BCM_sha256_transform(SHA256_CTX *sha,
173                                     const uint8_t block[BCM_SHA256_CBLOCK]);
174 
175 // BCM_sha256_transform_blocks is a low-level function that takes |num_blocks| *
176 // |BCM_SHA256_CBLOCK| bytes of data and performs SHA-256 transforms on it to
177 // update |state|.
178 bcm_infallible BCM_sha256_transform_blocks(uint32_t state[8],
179                                            const uint8_t *data,
180                                            size_t num_blocks);
181 
182 
183 // SHA-384.
184 
185 // BCM_SHA384_DIGEST_LENGTH is the length of a SHA-384 digest.
186 #define BCM_SHA384_DIGEST_LENGTH 48
187 
188 // BCM_sha384_init initialises |sha|.
189 bcm_infallible BCM_sha384_init(SHA512_CTX *sha);
190 
191 // BCM_sha384_update adds |len| bytes from |data| to |sha|.
192 bcm_infallible BCM_sha384_update(SHA512_CTX *sha, const void *data, size_t len);
193 
194 // BCM_sha384_final adds the final padding to |sha| and writes the resulting
195 // digest to |out|, which must have at least |BCM_sha384_DIGEST_LENGTH| bytes of
196 // space. It may abort on programmer error.
197 bcm_infallible BCM_sha384_final(uint8_t out[BCM_SHA384_DIGEST_LENGTH],
198                                 SHA512_CTX *sha);
199 
200 
201 // SHA-512.
202 
203 // BCM_SHA512_DIGEST_LENGTH is the length of a SHA-512 digest.
204 #define BCM_SHA512_DIGEST_LENGTH 64
205 
206 // BCM_sha512_init initialises |sha|.
207 bcm_infallible BCM_sha512_init(SHA512_CTX *sha);
208 
209 // BCM_sha512_update adds |len| bytes from |data| to |sha|.
210 bcm_infallible BCM_sha512_update(SHA512_CTX *sha, const void *data, size_t len);
211 
212 // BCM_sha512_final adds the final padding to |sha| and writes the resulting
213 // digest to |out|, which must have at least |BCM_sha512_DIGEST_LENGTH| bytes of
214 // space.
215 bcm_infallible BCM_sha512_final(uint8_t out[BCM_SHA512_DIGEST_LENGTH],
216                                 SHA512_CTX *sha);
217 
218 // BCM_sha512_transform is a low-level function that performs a single, SHA-512
219 // block transformation using the state from |sha| and |BCM_sha512_CBLOCK| bytes
220 // from |block|.
221 bcm_infallible BCM_sha512_transform(SHA512_CTX *sha,
222                                     const uint8_t block[BCM_SHA512_CBLOCK]);
223 
224 
225 // SHA-512-256
226 //
227 // See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf section 5.3.6
228 
229 #define BCM_SHA512_256_DIGEST_LENGTH 32
230 
231 // BCM_sha512_256_init initialises |sha|.
232 bcm_infallible BCM_sha512_256_init(SHA512_CTX *sha);
233 
234 // BCM_sha512_256_update adds |len| bytes from |data| to |sha|.
235 bcm_infallible BCM_sha512_256_update(SHA512_CTX *sha, const void *data,
236                                      size_t len);
237 
238 // BCM_sha512_256_final adds the final padding to |sha| and writes the resulting
239 // digest to |out|, which must have at least |BCM_sha512_256_DIGEST_LENGTH|
240 // bytes of space. It may abort on programmer error.
241 bcm_infallible BCM_sha512_256_final(uint8_t out[BCM_SHA512_256_DIGEST_LENGTH],
242                                     SHA512_CTX *sha);
243 
244 
245 // ML-DSA
246 //
247 // Where not commented, these functions have the same signature as the
248 // corresponding public function.
249 
250 // BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES is the number of bytes of uniformly
251 // random entropy necessary to generate a signature in randomized mode.
252 #define BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES 32
253 
254 // BCM_MLDSA_SEED_BYTES is the number of bytes in an ML-DSA seed value.
255 #define BCM_MLDSA_SEED_BYTES 32
256 
257 // BCM_MLDSA65_PRIVATE_KEY_BYTES is the number of bytes in an encoded ML-DSA-65
258 // private key.
259 #define BCM_MLDSA65_PRIVATE_KEY_BYTES 4032
260 
261 // BCM_MLDSA65_PUBLIC_KEY_BYTES is the number of bytes in an encoded ML-DSA-65
262 // public key.
263 #define BCM_MLDSA65_PUBLIC_KEY_BYTES 1952
264 
265 // BCM_MLDSA65_SIGNATURE_BYTES is the number of bytes in an encoded ML-DSA-65
266 // signature.
267 #define BCM_MLDSA65_SIGNATURE_BYTES 3309
268 
269 struct BCM_mldsa65_private_key {
270   union {
271     uint8_t bytes[32 + 32 + 64 + 256 * 4 * (5 + 6 + 6)];
272     uint32_t alignment;
273   } opaque;
274 };
275 
276 struct BCM_mldsa65_public_key {
277   union {
278     uint8_t bytes[32 + 64 + 256 * 4 * 6];
279     uint32_t alignment;
280   } opaque;
281 };
282 
283 OPENSSL_EXPORT bcm_status BCM_mldsa65_generate_key(
284     uint8_t out_encoded_public_key[BCM_MLDSA65_PUBLIC_KEY_BYTES],
285     uint8_t out_seed[BCM_MLDSA_SEED_BYTES],
286     struct BCM_mldsa65_private_key *out_private_key);
287 
288 OPENSSL_EXPORT bcm_status BCM_mldsa65_private_key_from_seed(
289     struct BCM_mldsa65_private_key *out_private_key,
290     const uint8_t seed[BCM_MLDSA_SEED_BYTES]);
291 
292 OPENSSL_EXPORT bcm_status BCM_mldsa65_public_from_private(
293     struct BCM_mldsa65_public_key *out_public_key,
294     const struct BCM_mldsa65_private_key *private_key);
295 
296 OPENSSL_EXPORT bcm_status
297 BCM_mldsa65_check_key_fips(struct BCM_mldsa65_private_key *private_key);
298 
299 OPENSSL_EXPORT bcm_status BCM_mldsa65_generate_key_fips(
300     uint8_t out_encoded_public_key[BCM_MLDSA65_PUBLIC_KEY_BYTES],
301     uint8_t out_seed[BCM_MLDSA_SEED_BYTES],
302     struct BCM_mldsa65_private_key *out_private_key);
303 
304 OPENSSL_EXPORT bcm_status BCM_mldsa65_private_key_from_seed_fips(
305     struct BCM_mldsa65_private_key *out_private_key,
306     const uint8_t seed[BCM_MLDSA_SEED_BYTES]);
307 
308 OPENSSL_EXPORT bcm_status BCM_mldsa65_sign(
309     uint8_t out_encoded_signature[BCM_MLDSA65_SIGNATURE_BYTES],
310     const struct BCM_mldsa65_private_key *private_key, const uint8_t *msg,
311     size_t msg_len, const uint8_t *context, size_t context_len);
312 
313 OPENSSL_EXPORT bcm_status BCM_mldsa65_verify(
314     const struct BCM_mldsa65_public_key *public_key,
315     const uint8_t signature[BCM_MLDSA65_SIGNATURE_BYTES], const uint8_t *msg,
316     size_t msg_len, const uint8_t *context, size_t context_len);
317 
318 OPENSSL_EXPORT bcm_status BCM_mldsa65_marshal_public_key(
319     CBB *out, const struct BCM_mldsa65_public_key *public_key);
320 
321 OPENSSL_EXPORT bcm_status BCM_mldsa65_parse_public_key(
322     struct BCM_mldsa65_public_key *public_key, CBS *in);
323 
324 OPENSSL_EXPORT bcm_status BCM_mldsa65_parse_private_key(
325     struct BCM_mldsa65_private_key *private_key, CBS *in);
326 
327 // BCM_mldsa65_generate_key_external_entropy generates a public/private key pair
328 // using the given seed, writes the encoded public key to
329 // |out_encoded_public_key| and sets |out_private_key| to the private key.
330 OPENSSL_EXPORT bcm_status BCM_mldsa65_generate_key_external_entropy(
331     uint8_t out_encoded_public_key[BCM_MLDSA65_PUBLIC_KEY_BYTES],
332     struct BCM_mldsa65_private_key *out_private_key,
333     const uint8_t entropy[BCM_MLDSA_SEED_BYTES]);
334 
335 OPENSSL_EXPORT bcm_status BCM_mldsa65_generate_key_external_entropy_fips(
336     uint8_t out_encoded_public_key[BCM_MLDSA65_PUBLIC_KEY_BYTES],
337     struct BCM_mldsa65_private_key *out_private_key,
338     const uint8_t entropy[BCM_MLDSA_SEED_BYTES]);
339 
340 // BCM_mldsa5_sign_internal signs |msg| using |private_key| and writes the
341 // signature to |out_encoded_signature|. The |context_prefix| and |context| are
342 // prefixed to the message, in that order, before signing. The |randomizer|
343 // value can be set to zero bytes in order to make a deterministic signature, or
344 // else filled with entropy for the usual |MLDSA_sign| behavior.
345 OPENSSL_EXPORT bcm_status BCM_mldsa65_sign_internal(
346     uint8_t out_encoded_signature[BCM_MLDSA65_SIGNATURE_BYTES],
347     const struct BCM_mldsa65_private_key *private_key, const uint8_t *msg,
348     size_t msg_len, const uint8_t *context_prefix, size_t context_prefix_len,
349     const uint8_t *context, size_t context_len,
350     const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]);
351 
352 // BCM_mldsa5_verify_internal verifies that |encoded_signature| is a valid
353 // signature of |msg| by |public_key|. The |context_prefix| and |context| are
354 // prefixed to the message before verification, in that order.
355 OPENSSL_EXPORT bcm_status BCM_mldsa65_verify_internal(
356     const struct BCM_mldsa65_public_key *public_key,
357     const uint8_t encoded_signature[BCM_MLDSA65_SIGNATURE_BYTES],
358     const uint8_t *msg, size_t msg_len, const uint8_t *context_prefix,
359     size_t context_prefix_len, const uint8_t *context, size_t context_len);
360 
361 // BCM_mldsa65_marshal_private_key serializes |private_key| to |out| in the
362 // NIST format for ML-DSA-65 private keys.
363 OPENSSL_EXPORT bcm_status BCM_mldsa65_marshal_private_key(
364     CBB *out, const struct BCM_mldsa65_private_key *private_key);
365 
366 
367 // BCM_MLDSA87_PRIVATE_KEY_BYTES is the number of bytes in an encoded ML-DSA-87
368 // private key.
369 #define BCM_MLDSA87_PRIVATE_KEY_BYTES 4896
370 
371 // BCM_MLDSA87_PUBLIC_KEY_BYTES is the number of bytes in an encoded ML-DSA-87
372 // public key.
373 #define BCM_MLDSA87_PUBLIC_KEY_BYTES 2592
374 
375 // BCM_MLDSA87_SIGNATURE_BYTES is the number of bytes in an encoded ML-DSA-87
376 // signature.
377 #define BCM_MLDSA87_SIGNATURE_BYTES 4627
378 
379 struct BCM_mldsa87_private_key {
380   union {
381     uint8_t bytes[32 + 32 + 64 + 256 * 4 * (7 + 8 + 8)];
382     uint32_t alignment;
383   } opaque;
384 };
385 
386 struct BCM_mldsa87_public_key {
387   union {
388     uint8_t bytes[32 + 64 + 256 * 4 * 8];
389     uint32_t alignment;
390   } opaque;
391 };
392 
393 OPENSSL_EXPORT bcm_status BCM_mldsa87_generate_key(
394     uint8_t out_encoded_public_key[BCM_MLDSA87_PUBLIC_KEY_BYTES],
395     uint8_t out_seed[BCM_MLDSA_SEED_BYTES],
396     struct BCM_mldsa87_private_key *out_private_key);
397 
398 OPENSSL_EXPORT bcm_status BCM_mldsa87_private_key_from_seed(
399     struct BCM_mldsa87_private_key *out_private_key,
400     const uint8_t seed[BCM_MLDSA_SEED_BYTES]);
401 
402 OPENSSL_EXPORT bcm_status BCM_mldsa87_public_from_private(
403     struct BCM_mldsa87_public_key *out_public_key,
404     const struct BCM_mldsa87_private_key *private_key);
405 
406 OPENSSL_EXPORT bcm_status
407 BCM_mldsa87_check_key_fips(struct BCM_mldsa87_private_key *private_key);
408 
409 OPENSSL_EXPORT bcm_status BCM_mldsa87_generate_key_fips(
410     uint8_t out_encoded_public_key[BCM_MLDSA87_PUBLIC_KEY_BYTES],
411     uint8_t out_seed[BCM_MLDSA_SEED_BYTES],
412     struct BCM_mldsa87_private_key *out_private_key);
413 
414 OPENSSL_EXPORT bcm_status BCM_mldsa87_private_key_from_seed_fips(
415     struct BCM_mldsa87_private_key *out_private_key,
416     const uint8_t seed[BCM_MLDSA_SEED_BYTES]);
417 
418 OPENSSL_EXPORT bcm_status BCM_mldsa87_sign(
419     uint8_t out_encoded_signature[BCM_MLDSA87_SIGNATURE_BYTES],
420     const struct BCM_mldsa87_private_key *private_key, const uint8_t *msg,
421     size_t msg_len, const uint8_t *context, size_t context_len);
422 
423 OPENSSL_EXPORT bcm_status
424 BCM_mldsa87_verify(const struct BCM_mldsa87_public_key *public_key,
425                    const uint8_t *signature, const uint8_t *msg, size_t msg_len,
426                    const uint8_t *context, size_t context_len);
427 
428 OPENSSL_EXPORT bcm_status BCM_mldsa87_marshal_public_key(
429     CBB *out, const struct BCM_mldsa87_public_key *public_key);
430 
431 OPENSSL_EXPORT bcm_status BCM_mldsa87_parse_public_key(
432     struct BCM_mldsa87_public_key *public_key, CBS *in);
433 
434 OPENSSL_EXPORT bcm_status BCM_mldsa87_parse_private_key(
435     struct BCM_mldsa87_private_key *private_key, CBS *in);
436 
437 // BCM_mldsa87_generate_key_external_entropy generates a public/private key pair
438 // using the given seed, writes the encoded public key to
439 // |out_encoded_public_key| and sets |out_private_key| to the private key.
440 OPENSSL_EXPORT bcm_status BCM_mldsa87_generate_key_external_entropy(
441     uint8_t out_encoded_public_key[BCM_MLDSA87_PUBLIC_KEY_BYTES],
442     struct BCM_mldsa87_private_key *out_private_key,
443     const uint8_t entropy[BCM_MLDSA_SEED_BYTES]);
444 
445 OPENSSL_EXPORT bcm_status BCM_mldsa87_generate_key_external_entropy_fips(
446     uint8_t out_encoded_public_key[BCM_MLDSA87_PUBLIC_KEY_BYTES],
447     struct BCM_mldsa87_private_key *out_private_key,
448     const uint8_t entropy[BCM_MLDSA_SEED_BYTES]);
449 
450 // BCM_mldsa87_sign_internal signs |msg| using |private_key| and writes the
451 // signature to |out_encoded_signature|. The |context_prefix| and |context| are
452 // prefixed to the message, in that order, before signing. The |randomizer|
453 // value can be set to zero bytes in order to make a deterministic signature, or
454 // else filled with entropy for the usual |MLDSA_sign| behavior.
455 OPENSSL_EXPORT bcm_status BCM_mldsa87_sign_internal(
456     uint8_t out_encoded_signature[BCM_MLDSA87_SIGNATURE_BYTES],
457     const struct BCM_mldsa87_private_key *private_key, const uint8_t *msg,
458     size_t msg_len, const uint8_t *context_prefix, size_t context_prefix_len,
459     const uint8_t *context, size_t context_len,
460     const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]);
461 
462 // BCM_mldsa87_verify_internal verifies that |encoded_signature| is a valid
463 // signature of |msg| by |public_key|. The |context_prefix| and |context| are
464 // prefixed to the message before verification, in that order.
465 OPENSSL_EXPORT bcm_status BCM_mldsa87_verify_internal(
466     const struct BCM_mldsa87_public_key *public_key,
467     const uint8_t encoded_signature[BCM_MLDSA87_SIGNATURE_BYTES],
468     const uint8_t *msg, size_t msg_len, const uint8_t *context_prefix,
469     size_t context_prefix_len, const uint8_t *context, size_t context_len);
470 
471 // BCM_mldsa87_marshal_private_key serializes |private_key| to |out| in the
472 // NIST format for ML-DSA-87 private keys.
473 OPENSSL_EXPORT bcm_status BCM_mldsa87_marshal_private_key(
474     CBB *out, const struct BCM_mldsa87_private_key *private_key);
475 
476 
477 // ML-KEM
478 //
479 // Where not commented, these functions have the same signature as the
480 // corresponding public function.
481 
482 // BCM_MLKEM_ENCAP_ENTROPY is the number of bytes of uniformly random entropy
483 // necessary to encapsulate a secret. The entropy will be leaked to the
484 // decapsulating party.
485 #define BCM_MLKEM_ENCAP_ENTROPY 32
486 
487 // BCM_MLKEM768_PUBLIC_KEY_BYTES is the number of bytes in an encoded ML-KEM-768
488 // public key.
489 #define BCM_MLKEM768_PUBLIC_KEY_BYTES 1184
490 
491 // BCM_MLKEM1024_PUBLIC_KEY_BYTES is the number of bytes in an encoded
492 // ML-KEM-1024 public key.
493 #define BCM_MLKEM1024_PUBLIC_KEY_BYTES 1568
494 
495 // BCM_MLKEM768_CIPHERTEXT_BYTES is number of bytes in the ML-KEM-768
496 // ciphertext.
497 #define BCM_MLKEM768_CIPHERTEXT_BYTES 1088
498 
499 // BCM_MLKEM1024_CIPHERTEXT_BYTES is number of bytes in the ML-KEM-1024
500 // ciphertext.
501 #define BCM_MLKEM1024_CIPHERTEXT_BYTES 1568
502 
503 // BCM_MLKEM768_PRIVATE_KEY_BYTES is the length of the data produced by
504 // |BCM_mlkem768_marshal_private_key|.
505 #define BCM_MLKEM768_PRIVATE_KEY_BYTES 2400
506 
507 // BCM_MLKEM1024_PRIVATE_KEY_BYTES is the length of the data produced by
508 // |BCM_mlkem1024_marshal_private_key|.
509 #define BCM_MLKEM1024_PRIVATE_KEY_BYTES 3168
510 
511 // BCM_MLKEM_SEED_BYTES is the number of bytes in an ML-KEM seed.
512 #define BCM_MLKEM_SEED_BYTES 64
513 
514 // BCM_mlkem_SHARED_SECRET_BYTES is the number of bytes in an ML-KEM shared
515 // secret.
516 #define BCM_MLKEM_SHARED_SECRET_BYTES 32
517 
518 struct BCM_mlkem768_public_key {
519   union {
520     uint8_t bytes[512 * (3 + 9) + 32 + 32];
521     uint16_t alignment;
522   } opaque;
523 };
524 
525 struct BCM_mlkem768_private_key {
526   union {
527     uint8_t bytes[512 * (3 + 3 + 9) + 32 + 32 + 32];
528     uint16_t alignment;
529   } opaque;
530 };
531 
532 
533 
534 OPENSSL_EXPORT bcm_infallible BCM_mlkem768_generate_key(
535     uint8_t out_encoded_public_key[BCM_MLKEM768_PUBLIC_KEY_BYTES],
536     uint8_t optional_out_seed[BCM_MLKEM_SEED_BYTES],
537     struct BCM_mlkem768_private_key *out_private_key);
538 
539 OPENSSL_EXPORT bcm_status BCM_mlkem768_private_key_from_seed(
540     struct BCM_mlkem768_private_key *out_private_key, const uint8_t *seed,
541     size_t seed_len);
542 
543 OPENSSL_EXPORT bcm_status BCM_mlkem768_generate_key_fips(
544     uint8_t out_encoded_public_key[BCM_MLKEM768_PUBLIC_KEY_BYTES],
545     uint8_t optional_out_seed[BCM_MLKEM_SEED_BYTES],
546     struct BCM_mlkem768_private_key *out_private_key);
547 
548 OPENSSL_EXPORT bcm_status
549 BCM_mlkem768_check_fips(const struct BCM_mlkem768_private_key *private_key);
550 
551 OPENSSL_EXPORT bcm_infallible BCM_mlkem768_public_from_private(
552     struct BCM_mlkem768_public_key *out_public_key,
553     const struct BCM_mlkem768_private_key *private_key);
554 
555 OPENSSL_EXPORT bcm_infallible
556 BCM_mlkem768_encap(uint8_t out_ciphertext[BCM_MLKEM768_CIPHERTEXT_BYTES],
557                    uint8_t out_shared_secret[BCM_MLKEM_SHARED_SECRET_BYTES],
558                    const struct BCM_mlkem768_public_key *public_key);
559 
560 OPENSSL_EXPORT bcm_status
561 BCM_mlkem768_decap(uint8_t out_shared_secret[BCM_MLKEM_SHARED_SECRET_BYTES],
562                    const uint8_t *ciphertext, size_t ciphertext_len,
563                    const struct BCM_mlkem768_private_key *private_key);
564 
565 OPENSSL_EXPORT bcm_status BCM_mlkem768_marshal_public_key(
566     CBB *out, const struct BCM_mlkem768_public_key *public_key);
567 
568 OPENSSL_EXPORT bcm_status BCM_mlkem768_parse_public_key(
569     struct BCM_mlkem768_public_key *out_public_key, CBS *in);
570 
571 // BCM_mlkem768_parse_private_key parses a private key, in NIST's format for
572 // private keys, from |in| and writes the result to |out_private_key|. It
573 // returns one on success or zero on parse error or if there are trailing bytes
574 // in |in|. This format is verbose and should be avoided. Private keys should be
575 // stored as seeds and parsed using |BCM_mlkem768_private_key_from_seed|.
576 OPENSSL_EXPORT bcm_status BCM_mlkem768_parse_private_key(
577     struct BCM_mlkem768_private_key *out_private_key, CBS *in);
578 
579 // BCM_mlkem768_generate_key_external_seed is a deterministic function to create
580 // a pair of ML-KEM-768 keys, using the supplied seed. The seed needs to be
581 // uniformly random. This function should only be used for tests; regular
582 // callers should use the non-deterministic |BCM_mlkem768_generate_key|
583 // directly.
584 OPENSSL_EXPORT bcm_infallible BCM_mlkem768_generate_key_external_seed(
585     uint8_t out_encoded_public_key[BCM_MLKEM768_PUBLIC_KEY_BYTES],
586     struct BCM_mlkem768_private_key *out_private_key,
587     const uint8_t seed[BCM_MLKEM_SEED_BYTES]);
588 
589 // BCM_mlkem768_encap_external_entropy behaves like |MLKEM768_encap|, but uses
590 // |MLKEM_ENCAP_ENTROPY| bytes of |entropy| for randomization. The decapsulating
591 // side will be able to recover |entropy| in full. This function should only be
592 // used for tests, regular callers should use the non-deterministic
593 // |BCM_mlkem768_encap| directly.
594 OPENSSL_EXPORT bcm_infallible BCM_mlkem768_encap_external_entropy(
595     uint8_t out_ciphertext[BCM_MLKEM768_CIPHERTEXT_BYTES],
596     uint8_t out_shared_secret[BCM_MLKEM_SHARED_SECRET_BYTES],
597     const struct BCM_mlkem768_public_key *public_key,
598     const uint8_t entropy[BCM_MLKEM_ENCAP_ENTROPY]);
599 
600 // BCM_mlkem768_marshal_private_key serializes |private_key| to |out| in the
601 // NIST format for ML-KEM-768 private keys. (Note that one can also save just
602 // the seed value produced by |BCM_mlkem768_generate_key|, which is
603 // significantly smaller.)
604 OPENSSL_EXPORT bcm_status BCM_mlkem768_marshal_private_key(
605     CBB *out, const struct BCM_mlkem768_private_key *private_key);
606 
607 struct BCM_mlkem1024_public_key {
608   union {
609     uint8_t bytes[512 * (4 + 16) + 32 + 32];
610     uint16_t alignment;
611   } opaque;
612 };
613 
614 struct BCM_mlkem1024_private_key {
615   union {
616     uint8_t bytes[512 * (4 + 4 + 16) + 32 + 32 + 32];
617     uint16_t alignment;
618   } opaque;
619 };
620 
621 OPENSSL_EXPORT bcm_infallible BCM_mlkem1024_generate_key(
622     uint8_t out_encoded_public_key[BCM_MLKEM1024_PUBLIC_KEY_BYTES],
623     uint8_t optional_out_seed[BCM_MLKEM_SEED_BYTES],
624     struct BCM_mlkem1024_private_key *out_private_key);
625 
626 OPENSSL_EXPORT bcm_status BCM_mlkem1024_generate_key_fips(
627     uint8_t out_encoded_public_key[BCM_MLKEM1024_PUBLIC_KEY_BYTES],
628     uint8_t optional_out_seed[BCM_MLKEM_SEED_BYTES],
629     struct BCM_mlkem1024_private_key *out_private_key);
630 
631 OPENSSL_EXPORT bcm_status
632 BCM_mlkem1024_check_fips(const struct BCM_mlkem1024_private_key *private_key);
633 
634 OPENSSL_EXPORT bcm_status BCM_mlkem1024_private_key_from_seed(
635     struct BCM_mlkem1024_private_key *out_private_key, const uint8_t *seed,
636     size_t seed_len);
637 
638 OPENSSL_EXPORT bcm_infallible BCM_mlkem1024_public_from_private(
639     struct BCM_mlkem1024_public_key *out_public_key,
640     const struct BCM_mlkem1024_private_key *private_key);
641 
642 OPENSSL_EXPORT bcm_infallible
643 BCM_mlkem1024_encap(uint8_t out_ciphertext[BCM_MLKEM1024_CIPHERTEXT_BYTES],
644                     uint8_t out_shared_secret[BCM_MLKEM_SHARED_SECRET_BYTES],
645                     const struct BCM_mlkem1024_public_key *public_key);
646 
647 OPENSSL_EXPORT bcm_status
648 BCM_mlkem1024_decap(uint8_t out_shared_secret[BCM_MLKEM_SHARED_SECRET_BYTES],
649                     const uint8_t *ciphertext, size_t ciphertext_len,
650                     const struct BCM_mlkem1024_private_key *private_key);
651 
652 OPENSSL_EXPORT bcm_status BCM_mlkem1024_marshal_public_key(
653     CBB *out, const struct BCM_mlkem1024_public_key *public_key);
654 
655 OPENSSL_EXPORT bcm_status BCM_mlkem1024_parse_public_key(
656     struct BCM_mlkem1024_public_key *out_public_key, CBS *in);
657 
658 // BCM_mlkem1024_parse_private_key parses a private key, in NIST's format for
659 // private keys, from |in| and writes the result to |out_private_key|. It
660 // returns one on success or zero on parse error or if there are trailing bytes
661 // in |in|. This format is verbose and should be avoided. Private keys should be
662 // stored as seeds and parsed using |BCM_mlkem1024_private_key_from_seed|.
663 OPENSSL_EXPORT bcm_status BCM_mlkem1024_parse_private_key(
664     struct BCM_mlkem1024_private_key *out_private_key, CBS *in);
665 
666 // BCM_mlkem1024_generate_key_external_seed is a deterministic function to
667 // create a pair of ML-KEM-1024 keys, using the supplied seed. The seed needs to
668 // be uniformly random. This function should only be used for tests, regular
669 // callers should use the non-deterministic |BCM_mlkem1024_generate_key|
670 // directly.
671 OPENSSL_EXPORT bcm_infallible BCM_mlkem1024_generate_key_external_seed(
672     uint8_t out_encoded_public_key[BCM_MLKEM1024_PUBLIC_KEY_BYTES],
673     struct BCM_mlkem1024_private_key *out_private_key,
674     const uint8_t seed[BCM_MLKEM_SEED_BYTES]);
675 
676 // BCM_mlkem1024_encap_external_entropy behaves like |MLKEM1024_encap|, but uses
677 // |MLKEM_ENCAP_ENTROPY| bytes of |entropy| for randomization. The
678 // decapsulating side will be able to recover |entropy| in full. This function
679 // should only be used for tests, regular callers should use the
680 // non-deterministic |BCM_mlkem1024_encap| directly.
681 OPENSSL_EXPORT bcm_infallible BCM_mlkem1024_encap_external_entropy(
682     uint8_t out_ciphertext[BCM_MLKEM1024_CIPHERTEXT_BYTES],
683     uint8_t out_shared_secret[BCM_MLKEM_SHARED_SECRET_BYTES],
684     const struct BCM_mlkem1024_public_key *public_key,
685     const uint8_t entropy[BCM_MLKEM_ENCAP_ENTROPY]);
686 
687 // BCM_mlkem1024_marshal_private_key serializes |private_key| to |out| in the
688 // NIST format for ML-KEM-1024 private keys. (Note that one can also save just
689 // the seed value produced by |BCM_mlkem1024_generate_key|, which is
690 // significantly smaller.)
691 OPENSSL_EXPORT bcm_status BCM_mlkem1024_marshal_private_key(
692     CBB *out, const struct BCM_mlkem1024_private_key *private_key);
693 
694 
695 // SLH-DSA
696 
697 // Output length of the hash function.
698 #define BCM_SLHDSA_SHA2_128S_N 16
699 
700 // The number of bytes at the beginning of M', the augmented message, before the
701 // context.
702 #define BCM_SLHDSA_M_PRIME_HEADER_LEN 2
703 
704 // SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES is the number of bytes in an
705 // SLH-DSA-SHA2-128s public key.
706 #define BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES 32
707 
708 // BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES is the number of bytes in an
709 // SLH-DSA-SHA2-128s private key.
710 #define BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES 64
711 
712 // BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES is the number of bytes in an
713 // SLH-DSA-SHA2-128s signature.
714 #define BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES 7856
715 
716 // SLHDSA_SHA2_128S_generate_key_from_seed generates an SLH-DSA-SHA2-128s key
717 // pair from a 48-byte seed and writes the result to |out_public_key| and
718 // |out_secret_key|.
719 OPENSSL_EXPORT bcm_infallible BCM_slhdsa_sha2_128s_generate_key_from_seed(
720     uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
721     uint8_t out_secret_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
722     const uint8_t seed[3 * BCM_SLHDSA_SHA2_128S_N]);
723 
724 // BCM_slhdsa_sha2_128s_sign_internal acts like |SLHDSA_SHA2_128S_sign| but
725 // accepts an explicit entropy input, which can be PK.seed (bytes 32..48 of
726 // the private key) to generate deterministic signatures. It also takes the
727 // input message in three parts so that the "internal" version of the signing
728 // function, from section 9.2, can be implemented. The |header| argument may be
729 // NULL to omit it.
730 OPENSSL_EXPORT bcm_infallible BCM_slhdsa_sha2_128s_sign_internal(
731     uint8_t out_signature[BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES],
732     const uint8_t secret_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
733     const uint8_t header[BCM_SLHDSA_M_PRIME_HEADER_LEN], const uint8_t *context,
734     size_t context_len, const uint8_t *msg, size_t msg_len,
735     const uint8_t entropy[BCM_SLHDSA_SHA2_128S_N]);
736 
737 // BCM_slhdsa_sha2_128s_verify_internal acts like |SLHDSA_SHA2_128S_verify| but
738 // takes the input message in three parts so that the "internal" version of the
739 // verification function, from section 9.3, can be implemented. The |header|
740 // argument may be NULL to omit it.
741 OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_verify_internal(
742     const uint8_t *signature, size_t signature_len,
743     const uint8_t public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
744     const uint8_t header[BCM_SLHDSA_M_PRIME_HEADER_LEN], const uint8_t *context,
745     size_t context_len, const uint8_t *msg, size_t msg_len);
746 
747 OPENSSL_EXPORT bcm_infallible BCM_slhdsa_sha2_128s_generate_key(
748     uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
749     uint8_t out_private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]);
750 
751 OPENSSL_EXPORT bcm_infallible BCM_slhdsa_sha2_128s_public_from_private(
752     uint8_t out_public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
753     const uint8_t private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES]);
754 
755 OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_sign(
756     uint8_t out_signature[BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES],
757     const uint8_t private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
758     const uint8_t *msg, size_t msg_len, const uint8_t *context,
759     size_t context_len);
760 
761 OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_verify(
762     const uint8_t *signature, size_t signature_len,
763     const uint8_t public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
764     const uint8_t *msg, size_t msg_len, const uint8_t *context,
765     size_t context_len);
766 
767 OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_prehash_sign(
768     uint8_t out_signature[BCM_SLHDSA_SHA2_128S_SIGNATURE_BYTES],
769     const uint8_t private_key[BCM_SLHDSA_SHA2_128S_PRIVATE_KEY_BYTES],
770     const uint8_t *hashed_msg, size_t hashed_msg_len, int hash_nid,
771     const uint8_t *context, size_t context_len);
772 
773 OPENSSL_EXPORT bcm_status BCM_slhdsa_sha2_128s_prehash_verify(
774     const uint8_t *signature, size_t signature_len,
775     const uint8_t public_key[BCM_SLHDSA_SHA2_128S_PUBLIC_KEY_BYTES],
776     const uint8_t *hashed_msg, size_t hashed_msg_len, int hash_nid,
777     const uint8_t *context, size_t context_len);
778 
779 
780 #if defined(__cplusplus)
781 }  // extern C
782 #endif
783 
784 #endif  // OPENSSL_HEADER_CRYPTO_BCM_INTERFACE_H
785