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