Coverage Report

Created: 2026-04-15 06:25

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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