Coverage Report

Created: 2026-09-12 06:55

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssl35/crypto/ml_kem/ml_kem.c
Line
Count
Source
1
/*
2
 * Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (the "License").  You may not use
5
 * this file except in compliance with the License.  You can obtain a copy
6
 * in the file LICENSE in the source distribution or at
7
 * https://www.openssl.org/source/license.html
8
 */
9
10
#include <openssl/byteorder.h>
11
#include <openssl/rand.h>
12
#include <openssl/proverr.h>
13
#include "crypto/ml_kem.h"
14
#include "internal/common.h"
15
#include "internal/constant_time.h"
16
#include "internal/sha3.h"
17
18
#if defined(OPENSSL_CONSTANT_TIME_VALIDATION)
19
#include <valgrind/memcheck.h>
20
#endif
21
22
#if ML_KEM_SEED_BYTES != ML_KEM_SHARED_SECRET_BYTES + ML_KEM_RANDOM_BYTES
23
#error "ML-KEM keygen seed length != shared secret + random bytes length"
24
#endif
25
#if ML_KEM_SHARED_SECRET_BYTES != ML_KEM_RANDOM_BYTES
26
#error "Invalid unequal lengths of ML-KEM shared secret and random inputs"
27
#endif
28
29
#if UINT_MAX < UINT32_MAX
30
#error "Unsupported compiler: sizeof(unsigned int) < sizeof(uint32_t)"
31
#endif
32
33
/* Handy function-like bit-extraction macros */
34
49.3M
#define bit0(b) ((b) & 1)
35
344M
#define bitn(n, b) (((b) >> n) & 1)
36
37
/*
38
 * 12 bits are sufficient to losslessly represent values in [0, q-1].
39
 * INVERSE_DEGREE is (n/2)^-1 mod q; used in inverse NTT.
40
 */
41
4.03M
#define DEGREE ML_KEM_DEGREE
42
#define INVERSE_DEGREE (ML_KEM_PRIME - 2 * 13)
43
#define LOG2PRIME 12
44
#define BARRETT_SHIFT (2 * LOG2PRIME)
45
46
#ifdef SHA3_BLOCKSIZE
47
#define SHAKE128_BLOCKSIZE SHA3_BLOCKSIZE(128)
48
#endif
49
50
/*
51
 * Return whether a value that can only be 0 or 1 is non-zero, in constant time
52
 * in practice!  The return value is a mask that is all ones if true, and all
53
 * zeros otherwise (twos-complement arithmetic assumed for unsigned values).
54
 *
55
 * Although this is used in constant-time selects, we omit a value barrier
56
 * here.  Value barriers impede auto-vectorization (likely because it forces
57
 * the value to transit through a general-purpose register). On AArch64, this
58
 * is a difference of 2x.
59
 *
60
 * We usually add value barriers to selects because Clang turns consecutive
61
 * selects with the same condition into a branch instead of CMOV/CSEL. This
62
 * condition does not occur in Kyber, so omitting it seems to be safe so far,
63
 * but see |cbd_2|, |cbd_3|, where reduction needs to be specialised to the
64
 * sign of the input, rather than adding |q| in advance, and using the generic
65
 * |reduce_once|.  (David Benjamin, Chromium)
66
 */
67
#if 0
68
#define constish_time_non_zero(b) (~constant_time_is_zero(b));
69
#else
70
1.35G
#define constish_time_non_zero(b) (0u - (b))
71
#endif
72
73
/*
74
 * The scalar rejection-sampling buffer size needs to be a multiple of 12, but
75
 * is otherwise arbitrary, the preferred block size matches the internal buffer
76
 * size of SHAKE128, avoiding internal buffering and copying in SHAKE128. That
77
 * block size of (1600 - 256)/8 bytes, or 168, just happens to divide by 12!
78
 *
79
 * If the blocksize is unknown, or is not divisible by 12, 168 is used as a
80
 * fallback.
81
 */
82
#if defined(SHAKE128_BLOCKSIZE) && (SHAKE128_BLOCKSIZE) % 12 == 0
83
#define SCALAR_SAMPLING_BUFSIZE (SHAKE128_BLOCKSIZE)
84
#else
85
#define SCALAR_SAMPLING_BUFSIZE 168
86
#endif
87
88
/*
89
 * Structure of keys
90
 */
91
typedef struct ossl_ml_kem_scalar_st {
92
    /* On every function entry and exit, 0 <= c[i] < ML_KEM_PRIME. */
93
    uint16_t c[ML_KEM_DEGREE];
94
} scalar;
95
96
/* Key material allocation layout */
97
#define DECLARE_ML_KEM_KEYDATA(name, rank, private_sz)               \
98
    struct name##_alloc {                                            \
99
        /* Public vector |t| */                                      \
100
        scalar tbuf[(rank)];                                         \
101
        /* Pre-computed matrix |m| (FIPS 203 |A| transpose) */       \
102
        scalar mbuf[(rank) * (rank)] /* optional private key data */ \
103
            private_sz                                               \
104
    }
105
106
/* Declare variant-specific public and private storage */
107
#define DECLARE_ML_KEM_VARIANT_KEYDATA(bits)                        \
108
    DECLARE_ML_KEM_KEYDATA(pubkey_##bits, ML_KEM_##bits##_RANK, ;); \
109
    DECLARE_ML_KEM_KEYDATA(prvkey_##bits, ML_KEM_##bits##_RANK, ; scalar sbuf[ML_KEM_##bits##_RANK]; uint8_t zbuf[2 * ML_KEM_RANDOM_BYTES];)
110
DECLARE_ML_KEM_VARIANT_KEYDATA(512);
111
DECLARE_ML_KEM_VARIANT_KEYDATA(768);
112
DECLARE_ML_KEM_VARIANT_KEYDATA(1024);
113
#undef DECLARE_ML_KEM_VARIANT_KEYDATA
114
#undef DECLARE_ML_KEM_KEYDATA
115
116
typedef __owur int (*CBD_FUNC)(scalar *out, uint8_t in[ML_KEM_RANDOM_BYTES + 1],
117
    EVP_MD_CTX *mdctx, const ML_KEM_KEY *key);
118
static void scalar_encode(uint8_t *out, const scalar *s, int bits);
119
120
/*
121
 * The wire-form of a losslessly encoded vector uses 12-bits per element.
122
 *
123
 * The wire-form public key consists of the lossless encoding of the public
124
 * vector |t|, followed by the public seed |rho|.
125
 *
126
 * Our serialised private key concatenates serialisations of the private vector
127
 * |s|, the public key, the public key hash, and the failure secret |z|.
128
 */
129
#define VECTOR_BYTES(b) ((3 * DEGREE / 2) * ML_KEM_##b##_RANK)
130
#define PUBKEY_BYTES(b) (VECTOR_BYTES(b) + ML_KEM_RANDOM_BYTES)
131
#define PRVKEY_BYTES(b) (2 * PUBKEY_BYTES(b) + ML_KEM_PKHASH_BYTES)
132
133
/*
134
 * Encapsulation produces a vector "u" and a scalar "v", whose coordinates
135
 * (numbers modulo the ML-KEM prime "q") are lossily encoded using as "du" and
136
 * "dv" bits, respectively.  This encoding is the ciphertext input for
137
 * decapsulation.
138
 */
139
#define U_VECTOR_BYTES(b) ((DEGREE / 8) * ML_KEM_##b##_DU * ML_KEM_##b##_RANK)
140
#define V_SCALAR_BYTES(b) ((DEGREE / 8) * ML_KEM_##b##_DV)
141
#define CTEXT_BYTES(b) (U_VECTOR_BYTES(b) + V_SCALAR_BYTES(b))
142
143
#if defined(OPENSSL_CONSTANT_TIME_VALIDATION)
144
145
/*
146
 * CONSTTIME_SECRET takes a pointer and a number of bytes and marks that region
147
 * of memory as secret. Secret data is tracked as it flows to registers and
148
 * other parts of a memory. If secret data is used as a condition for a branch,
149
 * or as a memory index, it will trigger warnings in valgrind.
150
 */
151
#define CONSTTIME_SECRET(ptr, len) VALGRIND_MAKE_MEM_UNDEFINED(ptr, len)
152
153
/*
154
 * CONSTTIME_DECLASSIFY takes a pointer and a number of bytes and marks that
155
 * region of memory as public. Public data is not subject to constant-time
156
 * rules.
157
 */
158
#define CONSTTIME_DECLASSIFY(ptr, len) VALGRIND_MAKE_MEM_DEFINED(ptr, len)
159
160
#else
161
162
#define CONSTTIME_SECRET(ptr, len)
163
#define CONSTTIME_DECLASSIFY(ptr, len)
164
165
#endif
166
167
/*
168
 * Indices of slots in the vinfo tables below
169
 */
170
61.5k
#define ML_KEM_512_VINFO 0
171
180k
#define ML_KEM_768_VINFO 1
172
57.8k
#define ML_KEM_1024_VINFO 2
173
174
/*
175
 * Per-variant fixed parameters
176
 */
177
static const ML_KEM_VINFO vinfo_map[3] = {
178
    { "ML-KEM-512",
179
        PRVKEY_BYTES(512),
180
        sizeof(struct prvkey_512_alloc),
181
        PUBKEY_BYTES(512),
182
        sizeof(struct pubkey_512_alloc),
183
        CTEXT_BYTES(512),
184
        VECTOR_BYTES(512),
185
        U_VECTOR_BYTES(512),
186
        EVP_PKEY_ML_KEM_512,
187
        ML_KEM_512_BITS,
188
        ML_KEM_512_RANK,
189
        ML_KEM_512_DU,
190
        ML_KEM_512_DV,
191
        ML_KEM_512_SECBITS },
192
    { "ML-KEM-768",
193
        PRVKEY_BYTES(768),
194
        sizeof(struct prvkey_768_alloc),
195
        PUBKEY_BYTES(768),
196
        sizeof(struct pubkey_768_alloc),
197
        CTEXT_BYTES(768),
198
        VECTOR_BYTES(768),
199
        U_VECTOR_BYTES(768),
200
        EVP_PKEY_ML_KEM_768,
201
        ML_KEM_768_BITS,
202
        ML_KEM_768_RANK,
203
        ML_KEM_768_DU,
204
        ML_KEM_768_DV,
205
        ML_KEM_768_SECBITS },
206
    { "ML-KEM-1024",
207
        PRVKEY_BYTES(1024),
208
        sizeof(struct prvkey_1024_alloc),
209
        PUBKEY_BYTES(1024),
210
        sizeof(struct pubkey_1024_alloc),
211
        CTEXT_BYTES(1024),
212
        VECTOR_BYTES(1024),
213
        U_VECTOR_BYTES(1024),
214
        EVP_PKEY_ML_KEM_1024,
215
        ML_KEM_1024_BITS,
216
        ML_KEM_1024_RANK,
217
        ML_KEM_1024_DU,
218
        ML_KEM_1024_DV,
219
        ML_KEM_1024_SECBITS }
220
};
221
222
/*
223
 * Remainders modulo `kPrime`, for sufficiently small inputs, are computed in
224
 * constant time via Barrett reduction, and a final call to reduce_once(),
225
 * which reduces inputs that are at most 2*kPrime and is also constant-time.
226
 */
227
static const int kPrime = ML_KEM_PRIME;
228
static const unsigned int kBarrettShift = BARRETT_SHIFT;
229
static const size_t kBarrettMultiplier = (1 << BARRETT_SHIFT) / ML_KEM_PRIME;
230
static const uint16_t kHalfPrime = (ML_KEM_PRIME - 1) / 2;
231
static const uint16_t kInverseDegree = INVERSE_DEGREE;
232
233
/*
234
 * Python helper:
235
 *
236
 * p = 3329
237
 * def bitreverse(i):
238
 *     ret = 0
239
 *     for n in range(7):
240
 *         bit = i & 1
241
 *         ret <<= 1
242
 *         ret |= bit
243
 *         i >>= 1
244
 *     return ret
245
 */
246
247
/*-
248
 * First precomputed array from Appendix A of FIPS 203, or else Python:
249
 * kNTTRoots = [pow(17, bitreverse(i), p) for i in range(128)]
250
 */
251
static const uint16_t kNTTRoots[128] = {
252
    1,
253
    1729,
254
    2580,
255
    3289,
256
    2642,
257
    630,
258
    1897,
259
    848,
260
    1062,
261
    1919,
262
    193,
263
    797,
264
    2786,
265
    3260,
266
    569,
267
    1746,
268
    296,
269
    2447,
270
    1339,
271
    1476,
272
    3046,
273
    56,
274
    2240,
275
    1333,
276
    1426,
277
    2094,
278
    535,
279
    2882,
280
    2393,
281
    2879,
282
    1974,
283
    821,
284
    289,
285
    331,
286
    3253,
287
    1756,
288
    1197,
289
    2304,
290
    2277,
291
    2055,
292
    650,
293
    1977,
294
    2513,
295
    632,
296
    2865,
297
    33,
298
    1320,
299
    1915,
300
    2319,
301
    1435,
302
    807,
303
    452,
304
    1438,
305
    2868,
306
    1534,
307
    2402,
308
    2647,
309
    2617,
310
    1481,
311
    648,
312
    2474,
313
    3110,
314
    1227,
315
    910,
316
    17,
317
    2761,
318
    583,
319
    2649,
320
    1637,
321
    723,
322
    2288,
323
    1100,
324
    1409,
325
    2662,
326
    3281,
327
    233,
328
    756,
329
    2156,
330
    3015,
331
    3050,
332
    1703,
333
    1651,
334
    2789,
335
    1789,
336
    1847,
337
    952,
338
    1461,
339
    2687,
340
    939,
341
    2308,
342
    2437,
343
    2388,
344
    733,
345
    2337,
346
    268,
347
    641,
348
    1584,
349
    2298,
350
    2037,
351
    3220,
352
    375,
353
    2549,
354
    2090,
355
    1645,
356
    1063,
357
    319,
358
    2773,
359
    757,
360
    2099,
361
    561,
362
    2466,
363
    2594,
364
    2804,
365
    1092,
366
    403,
367
    1026,
368
    1143,
369
    2150,
370
    2775,
371
    886,
372
    1722,
373
    1212,
374
    1874,
375
    1029,
376
    2110,
377
    2935,
378
    885,
379
    2154,
380
};
381
382
/*
383
 * InverseNTTRoots = [pow(17, -bitreverse(i), p) for i in range(128)]
384
 * Listed in order of use in the inverse NTT loop (index 0 is skipped):
385
 *
386
 *  0, 64, 65, ..., 127, 32, 33, ..., 63, 16, 17, ..., 31, 8, 9, ...
387
 */
388
static const uint16_t kInverseNTTRoots[128] = {
389
    1,
390
    1175,
391
    2444,
392
    394,
393
    1219,
394
    2300,
395
    1455,
396
    2117,
397
    1607,
398
    2443,
399
    554,
400
    1179,
401
    2186,
402
    2303,
403
    2926,
404
    2237,
405
    525,
406
    735,
407
    863,
408
    2768,
409
    1230,
410
    2572,
411
    556,
412
    3010,
413
    2266,
414
    1684,
415
    1239,
416
    780,
417
    2954,
418
    109,
419
    1292,
420
    1031,
421
    1745,
422
    2688,
423
    3061,
424
    992,
425
    2596,
426
    941,
427
    892,
428
    1021,
429
    2390,
430
    642,
431
    1868,
432
    2377,
433
    1482,
434
    1540,
435
    540,
436
    1678,
437
    1626,
438
    279,
439
    314,
440
    1173,
441
    2573,
442
    3096,
443
    48,
444
    667,
445
    1920,
446
    2229,
447
    1041,
448
    2606,
449
    1692,
450
    680,
451
    2746,
452
    568,
453
    3312,
454
    2419,
455
    2102,
456
    219,
457
    855,
458
    2681,
459
    1848,
460
    712,
461
    682,
462
    927,
463
    1795,
464
    461,
465
    1891,
466
    2877,
467
    2522,
468
    1894,
469
    1010,
470
    1414,
471
    2009,
472
    3296,
473
    464,
474
    2697,
475
    816,
476
    1352,
477
    2679,
478
    1274,
479
    1052,
480
    1025,
481
    2132,
482
    1573,
483
    76,
484
    2998,
485
    3040,
486
    2508,
487
    1355,
488
    450,
489
    936,
490
    447,
491
    2794,
492
    1235,
493
    1903,
494
    1996,
495
    1089,
496
    3273,
497
    283,
498
    1853,
499
    1990,
500
    882,
501
    3033,
502
    1583,
503
    2760,
504
    69,
505
    543,
506
    2532,
507
    3136,
508
    1410,
509
    2267,
510
    2481,
511
    1432,
512
    2699,
513
    687,
514
    40,
515
    749,
516
    1600,
517
};
518
519
/*
520
 * Second precomputed array from Appendix A of FIPS 203 (normalised positive),
521
 * or else Python:
522
 * ModRoots = [pow(17, 2*bitreverse(i) + 1, p) for i in range(128)]
523
 */
524
static const uint16_t kModRoots[128] = {
525
    17,
526
    3312,
527
    2761,
528
    568,
529
    583,
530
    2746,
531
    2649,
532
    680,
533
    1637,
534
    1692,
535
    723,
536
    2606,
537
    2288,
538
    1041,
539
    1100,
540
    2229,
541
    1409,
542
    1920,
543
    2662,
544
    667,
545
    3281,
546
    48,
547
    233,
548
    3096,
549
    756,
550
    2573,
551
    2156,
552
    1173,
553
    3015,
554
    314,
555
    3050,
556
    279,
557
    1703,
558
    1626,
559
    1651,
560
    1678,
561
    2789,
562
    540,
563
    1789,
564
    1540,
565
    1847,
566
    1482,
567
    952,
568
    2377,
569
    1461,
570
    1868,
571
    2687,
572
    642,
573
    939,
574
    2390,
575
    2308,
576
    1021,
577
    2437,
578
    892,
579
    2388,
580
    941,
581
    733,
582
    2596,
583
    2337,
584
    992,
585
    268,
586
    3061,
587
    641,
588
    2688,
589
    1584,
590
    1745,
591
    2298,
592
    1031,
593
    2037,
594
    1292,
595
    3220,
596
    109,
597
    375,
598
    2954,
599
    2549,
600
    780,
601
    2090,
602
    1239,
603
    1645,
604
    1684,
605
    1063,
606
    2266,
607
    319,
608
    3010,
609
    2773,
610
    556,
611
    757,
612
    2572,
613
    2099,
614
    1230,
615
    561,
616
    2768,
617
    2466,
618
    863,
619
    2594,
620
    735,
621
    2804,
622
    525,
623
    1092,
624
    2237,
625
    403,
626
    2926,
627
    1026,
628
    2303,
629
    1143,
630
    2186,
631
    2150,
632
    1179,
633
    2775,
634
    554,
635
    886,
636
    2443,
637
    1722,
638
    1607,
639
    1212,
640
    2117,
641
    1874,
642
    1455,
643
    1029,
644
    2300,
645
    2110,
646
    1219,
647
    2935,
648
    394,
649
    885,
650
    2444,
651
    2154,
652
    1175,
653
};
654
655
/*
656
 * single_keccak hashes |inlen| bytes from |in| and writes |outlen| bytes of
657
 * output to |out|. If the |md| specifies a fixed-output function, like
658
 * SHA3-256, then |outlen| must be the correct length for that function.
659
 */
660
static __owur int single_keccak(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen,
661
    EVP_MD_CTX *mdctx)
662
448k
{
663
448k
    unsigned int sz = (unsigned int)outlen;
664
665
448k
    if (!EVP_DigestUpdate(mdctx, in, inlen))
666
0
        return 0;
667
448k
    if (EVP_MD_xof(EVP_MD_CTX_get0_md(mdctx)))
668
384k
        return EVP_DigestFinalXOF(mdctx, out, outlen);
669
64.2k
    return EVP_DigestFinal_ex(mdctx, out, &sz)
670
64.2k
        && ossl_assert((size_t)sz == outlen);
671
448k
}
672
673
/*
674
 * FIPS 203, Section 4.1, equation (4.3): PRF. Takes 32+1 input bytes, and uses
675
 * SHAKE256 to produce the input to SamplePolyCBD_eta: FIPS 203, algorithm 8.
676
 */
677
static __owur int prf(uint8_t *out, size_t len, const uint8_t in[ML_KEM_RANDOM_BYTES + 1],
678
    EVP_MD_CTX *mdctx, const ML_KEM_KEY *key)
679
384k
{
680
384k
    return EVP_DigestInit_ex(mdctx, key->shake256_md, NULL)
681
384k
        && single_keccak(out, len, in, ML_KEM_RANDOM_BYTES + 1, mdctx);
682
384k
}
683
684
/*
685
 * FIPS 203, Section 4.1, equation (4.4): H.  SHA3-256 hash of a variable
686
 * length input, producing 32 bytes of output.
687
 */
688
static __owur int hash_h(uint8_t out[ML_KEM_PKHASH_BYTES], const uint8_t *in, size_t len,
689
    EVP_MD_CTX *mdctx, const ML_KEM_KEY *key)
690
360
{
691
360
    return EVP_DigestInit_ex(mdctx, key->sha3_256_md, NULL)
692
360
        && single_keccak(out, ML_KEM_PKHASH_BYTES, in, len, mdctx);
693
360
}
694
695
/* Incremental hash_h of expanded public key */
696
static int
697
hash_h_pubkey(uint8_t pkhash[ML_KEM_PKHASH_BYTES],
698
    EVP_MD_CTX *mdctx, ML_KEM_KEY *key)
699
63.5k
{
700
63.5k
    const ML_KEM_VINFO *vinfo = key->vinfo;
701
63.5k
    const scalar *t = key->t, *end = t + vinfo->rank;
702
63.5k
    unsigned int sz;
703
704
63.5k
    if (!EVP_DigestInit_ex(mdctx, key->sha3_256_md, NULL))
705
0
        return 0;
706
707
190k
    do {
708
190k
        uint8_t buf[3 * DEGREE / 2];
709
710
190k
        scalar_encode(buf, t++, 12);
711
190k
        if (!EVP_DigestUpdate(mdctx, buf, sizeof(buf)))
712
0
            return 0;
713
190k
    } while (t < end);
714
715
63.5k
    if (!EVP_DigestUpdate(mdctx, key->rho, ML_KEM_RANDOM_BYTES))
716
0
        return 0;
717
63.5k
    return EVP_DigestFinal_ex(mdctx, pkhash, &sz)
718
63.5k
        && ossl_assert(sz == ML_KEM_PKHASH_BYTES);
719
63.5k
}
720
721
/*
722
 * FIPS 203, Section 4.1, equation (4.5): G.  SHA3-512 hash of a variable
723
 * length input, producing 64 bytes of output, in particular the seeds
724
 * (d,z) for key generation.
725
 */
726
static __owur int hash_g(uint8_t out[ML_KEM_SEED_BYTES], const uint8_t *in, size_t len,
727
    EVP_MD_CTX *mdctx, const ML_KEM_KEY *key)
728
63.9k
{
729
63.9k
    return EVP_DigestInit_ex(mdctx, key->sha3_512_md, NULL)
730
63.9k
        && single_keccak(out, ML_KEM_SEED_BYTES, in, len, mdctx);
731
63.9k
}
732
733
/*
734
 * FIPS 203, Section 4.1, equation (4.4): J. SHAKE256 taking a variable length
735
 * input to compute a 32-byte implicit rejection shared secret, of the same
736
 * length as the expected shared secret.  (Computed even on success to avoid
737
 * side-channel leaks).
738
 */
739
static __owur int kdf(uint8_t out[ML_KEM_SHARED_SECRET_BYTES],
740
    const uint8_t z[ML_KEM_RANDOM_BYTES],
741
    const uint8_t *ctext, size_t len,
742
    EVP_MD_CTX *mdctx, const ML_KEM_KEY *key)
743
189
{
744
189
    return EVP_DigestInit_ex(mdctx, key->shake256_md, NULL)
745
189
        && EVP_DigestUpdate(mdctx, z, ML_KEM_RANDOM_BYTES)
746
189
        && EVP_DigestUpdate(mdctx, ctext, len)
747
189
        && EVP_DigestFinalXOF(mdctx, out, ML_KEM_SHARED_SECRET_BYTES);
748
189
}
749
750
/*
751
 * FIPS 203, Section 4.2.2, Algorithm 7: "SampleNTT" (steps 3-17, steps 1, 2
752
 * are performed by the caller). Rejection-samples a Keccak stream to get
753
 * uniformly distributed elements in the range [0,q). This is used for matrix
754
 * expansion and only operates on public inputs.
755
 */
756
static __owur int sample_scalar(scalar *out, EVP_MD_CTX *mdctx)
757
574k
{
758
574k
    uint16_t *curr = out->c, *endout = curr + DEGREE;
759
574k
    uint8_t buf[SCALAR_SAMPLING_BUFSIZE], *in;
760
574k
    uint8_t *endin = buf + sizeof(buf);
761
574k
    uint16_t d;
762
574k
    uint8_t b1, b2, b3;
763
764
1.72M
    do {
765
1.72M
        if (!EVP_DigestSqueeze(mdctx, in = buf, sizeof(buf)))
766
0
            return 0;
767
90.0M
        do {
768
90.0M
            b1 = *in++;
769
90.0M
            b2 = *in++;
770
90.0M
            b3 = *in++;
771
772
90.0M
            if (curr >= endout)
773
192k
                break;
774
89.8M
            if ((d = ((b2 & 0x0f) << 8) + b1) < kPrime)
775
74.1M
                *curr++ = d;
776
89.8M
            if (curr >= endout)
777
381k
                break;
778
89.4M
            if ((d = (b3 << 4) + (b2 >> 4)) < kPrime)
779
72.8M
                *curr++ = d;
780
89.4M
        } while (in < endin);
781
1.72M
    } while (curr < endout);
782
574k
    return 1;
783
574k
}
784
785
/*-
786
 * reduce_once reduces 0 <= x < 2*kPrime, mod kPrime.
787
 *
788
 * Subtract |q| if the input is larger, without exposing a side-channel,
789
 * avoiding the "clangover" attack.  See |constish_time_non_zero| for a
790
 * discussion on why the value barrier is by default omitted.
791
 */
792
static __owur uint16_t reduce_once(uint16_t x)
793
1.25G
{
794
1.25G
    const uint16_t subtracted = x - kPrime;
795
1.25G
    uint16_t mask = constish_time_non_zero(subtracted >> 15);
796
797
1.25G
    return (mask & x) | (~mask & subtracted);
798
1.25G
}
799
800
/*
801
 * Constant-time reduce x mod kPrime using Barrett reduction. x must be less
802
 * than kPrime + 2 * kPrime^2.  This is sufficient to reduce a product of
803
 * two already reduced u_int16 values, in fact it is sufficient for each
804
 * to be less than 2^12, because (kPrime * (2 * kPrime + 1)) > 2^24.
805
 */
806
static __owur uint16_t reduce(uint32_t x)
807
566M
{
808
566M
    uint64_t product = (uint64_t)x * kBarrettMultiplier;
809
566M
    uint32_t quotient = (uint32_t)(product >> kBarrettShift);
810
566M
    uint32_t remainder = x - quotient * kPrime;
811
812
566M
    return reduce_once(remainder);
813
566M
}
814
815
/* Multiply a scalar by a constant. */
816
static void scalar_mult_const(scalar *s, uint16_t a)
817
1.78k
{
818
1.78k
    uint16_t *curr = s->c, *end = curr + DEGREE, tmp;
819
820
457k
    do {
821
457k
        tmp = reduce(*curr * a);
822
457k
        *curr++ = tmp;
823
457k
    } while (curr < end);
824
1.78k
}
825
826
/*-
827
 * FIPS 203, Section 4.3, Algorithm 9: "NTT".
828
 * In-place number theoretic transform of a given scalar.  Note that ML-KEM's
829
 * kPrime 3329 does not have a 512th root of unity, so this transform leaves
830
 * off the last iteration of the usual FFT code, with the 128 relevant roots of
831
 * unity being stored in NTTRoots.  This means the output should be seen as 128
832
 * elements in GF(3329^2), with the coefficients of the elements being
833
 * consecutive entries in |s->c|.
834
 */
835
static void scalar_ntt(scalar *s)
836
383k
{
837
383k
    const uint16_t *roots = kNTTRoots;
838
383k
    uint16_t *end = s->c + DEGREE;
839
383k
    int offset = DEGREE / 2;
840
841
2.68M
    do {
842
2.68M
        uint16_t *curr = s->c, *peer;
843
844
48.6M
        do {
845
48.6M
            uint16_t *pause = curr + offset, even, odd;
846
48.6M
            uint32_t zeta = *++roots;
847
848
48.6M
            peer = pause;
849
343M
            do {
850
343M
                even = *curr;
851
343M
                odd = reduce(*peer * zeta);
852
343M
                *peer++ = reduce_once(even - odd + kPrime);
853
343M
                *curr++ = reduce_once(odd + even);
854
343M
            } while (curr < pause);
855
48.6M
        } while ((curr = peer) < end);
856
2.68M
    } while ((offset >>= 1) >= 2);
857
383k
}
858
859
/*-
860
 * FIPS 203, Section 4.3, Algorithm 10: "NTT^(-1)".
861
 * In-place inverse number theoretic transform of a given scalar, with pairs of
862
 * entries of s->v being interpreted as elements of GF(3329^2). Just as with
863
 * the number theoretic transform, this leaves off the first step of the normal
864
 * iFFT to account for the fact that 3329 does not have a 512th root of unity,
865
 * using the precomputed 128 roots of unity stored in InverseNTTRoots.
866
 */
867
static void scalar_inverse_ntt(scalar *s)
868
1.78k
{
869
1.78k
    const uint16_t *roots = kInverseNTTRoots;
870
1.78k
    uint16_t *end = s->c + DEGREE;
871
1.78k
    int offset = 2;
872
873
12.5k
    do {
874
12.5k
        uint16_t *curr = s->c, *peer;
875
876
227k
        do {
877
227k
            uint16_t *pause = curr + offset, even, odd;
878
227k
            uint32_t zeta = *++roots;
879
880
227k
            peer = pause;
881
1.60M
            do {
882
1.60M
                even = *curr;
883
1.60M
                odd = *peer;
884
1.60M
                *peer++ = reduce(zeta * (even - odd + kPrime));
885
1.60M
                *curr++ = reduce_once(odd + even);
886
1.60M
            } while (curr < pause);
887
227k
        } while ((curr = peer) < end);
888
12.5k
    } while ((offset <<= 1) < DEGREE);
889
1.78k
    scalar_mult_const(s, kInverseDegree);
890
1.78k
}
891
892
/* Addition updating the LHS scalar in-place. */
893
static void scalar_add(scalar *lhs, const scalar *rhs)
894
1.60k
{
895
1.60k
    int i;
896
897
411k
    for (i = 0; i < DEGREE; i++)
898
409k
        lhs->c[i] = reduce_once(lhs->c[i] + rhs->c[i]);
899
1.60k
}
900
901
/* Subtraction updating the LHS scalar in-place. */
902
static void scalar_sub(scalar *lhs, const scalar *rhs)
903
189
{
904
189
    int i;
905
906
48.5k
    for (i = 0; i < DEGREE; i++)
907
48.3k
        lhs->c[i] = reduce_once(lhs->c[i] - rhs->c[i] + kPrime);
908
189
}
909
910
/*
911
 * Multiplying two scalars in the number theoretically transformed state. Since
912
 * 3329 does not have a 512th root of unity, this means we have to interpret
913
 * the 2*ith and (2*i+1)th entries of the scalar as elements of
914
 * GF(3329)[X]/(X^2 - 17^(2*bitreverse(i)+1)).
915
 *
916
 * The value of 17^(2*bitreverse(i)+1) mod 3329 is stored in the precomputed
917
 * ModRoots table. Note that our Barrett transform only allows us to multiply
918
 * two reduced numbers together, so we need some intermediate reduction steps,
919
 * even if an uint64_t could hold 3 multiplied numbers.
920
 */
921
static void scalar_mult(scalar *out, const scalar *lhs,
922
    const scalar *rhs)
923
1.78k
{
924
1.78k
    uint16_t *curr = out->c, *end = curr + DEGREE;
925
1.78k
    const uint16_t *lc = lhs->c, *rc = rhs->c;
926
1.78k
    const uint16_t *roots = kModRoots;
927
928
228k
    do {
929
228k
        uint32_t l0 = *lc++, r0 = *rc++;
930
228k
        uint32_t l1 = *lc++, r1 = *rc++;
931
228k
        uint32_t zetapow = *roots++;
932
933
228k
        *curr++ = reduce(l0 * r0 + reduce(l1 * r1) * zetapow);
934
228k
        *curr++ = reduce(l0 * r1 + l1 * r0);
935
228k
    } while (curr < end);
936
1.78k
}
937
938
/* Above, but add the result to an existing scalar */
939
static ossl_inline void scalar_mult_add(scalar *out, const scalar *lhs,
940
    const scalar *rhs)
941
575k
{
942
575k
    uint16_t *curr = out->c, *end = curr + DEGREE;
943
575k
    const uint16_t *lc = lhs->c, *rc = rhs->c;
944
575k
    const uint16_t *roots = kModRoots;
945
946
73.6M
    do {
947
73.6M
        uint32_t l0 = *lc++, r0 = *rc++;
948
73.6M
        uint32_t l1 = *lc++, r1 = *rc++;
949
73.6M
        uint16_t *c0 = curr++;
950
73.6M
        uint16_t *c1 = curr++;
951
73.6M
        uint32_t zetapow = *roots++;
952
953
73.6M
        *c0 = reduce(*c0 + l0 * r0 + reduce(l1 * r1) * zetapow);
954
73.6M
        *c1 = reduce(*c1 + l0 * r1 + l1 * r0);
955
73.6M
    } while (curr < end);
956
575k
}
957
958
/*-
959
 * FIPS 203, Section 4.2.1, Algorithm 5: "ByteEncode_d", for 2<=d<=12.
960
 * Here |bits| is |d|.  For efficiency, we handle the d=1 case separately.
961
 */
962
static void scalar_encode(uint8_t *out, const scalar *s, int bits)
963
384k
{
964
384k
    const uint16_t *curr = s->c, *end = curr + DEGREE;
965
384k
    uint64_t accum = 0, element;
966
384k
    int used = 0;
967
968
98.4M
    do {
969
98.4M
        element = *curr++;
970
98.4M
        if (used + bits < 64) {
971
80.0M
            accum |= element << used;
972
80.0M
            used += bits;
973
80.0M
        } else if (used + bits > 64) {
974
12.3M
            out = OPENSSL_store_u64_le(out, accum | (element << used));
975
12.3M
            accum = element >> (64 - used);
976
12.3M
            used = (used + bits) - 64;
977
12.3M
        } else {
978
6.14M
            out = OPENSSL_store_u64_le(out, accum | (element << used));
979
6.14M
            accum = 0;
980
6.14M
            used = 0;
981
6.14M
        }
982
98.4M
    } while (curr < end);
983
384k
}
984
985
/*
986
 * scalar_encode_1 is |scalar_encode| specialised for |bits| == 1.
987
 */
988
static void scalar_encode_1(uint8_t out[DEGREE / 8], const scalar *s)
989
189
{
990
189
    int i, j;
991
189
    uint8_t out_byte;
992
993
6.23k
    for (i = 0; i < DEGREE; i += 8) {
994
6.04k
        out_byte = 0;
995
54.4k
        for (j = 0; j < 8; j++)
996
48.3k
            out_byte |= bit0(s->c[i + j]) << j;
997
6.04k
        *out = out_byte;
998
6.04k
        out++;
999
6.04k
    }
1000
189
}
1001
1002
/*-
1003
 * FIPS 203, Section 4.2.1, Algorithm 6: "ByteDecode_d", for 2<=d<12.
1004
 * Here |bits| is |d|.  For efficiency, we handle the d=1 and d=12 cases
1005
 * separately.
1006
 *
1007
 * scalar_decode parses |DEGREE * bits| bits from |in| into |DEGREE| values in
1008
 * |out|.
1009
 */
1010
static void scalar_decode(scalar *out, const uint8_t *in, int bits)
1011
752
{
1012
752
    uint16_t *curr = out->c, *end = curr + DEGREE;
1013
752
    uint64_t accum = 0;
1014
752
    int accum_bits = 0, todo = bits;
1015
752
    uint16_t bitmask = (((uint16_t)1) << bits) - 1, mask = bitmask;
1016
752
    uint16_t element = 0;
1017
1018
213k
    do {
1019
213k
        if (accum_bits == 0) {
1020
26.7k
            in = OPENSSL_load_u64_le(&accum, in);
1021
26.7k
            accum_bits = 64;
1022
26.7k
        }
1023
213k
        if (todo == bits && accum_bits >= bits) {
1024
            /* No partial "element", and all the required bits available */
1025
171k
            *curr++ = ((uint16_t)accum) & mask;
1026
171k
            accum >>= bits;
1027
171k
            accum_bits -= bits;
1028
171k
        } else if (accum_bits >= todo) {
1029
            /* A partial "element", and all the required bits available */
1030
20.8k
            *curr++ = element | ((((uint16_t)accum) & mask) << (bits - todo));
1031
20.8k
            accum >>= todo;
1032
20.8k
            accum_bits -= todo;
1033
20.8k
            element = 0;
1034
20.8k
            todo = bits;
1035
20.8k
            mask = bitmask;
1036
20.8k
        } else {
1037
            /*
1038
             * Only some of the requisite bits accumulated, store |accum_bits|
1039
             * of these in |element|.  The accumulated bitcount becomes 0, but
1040
             * as soon as we have more bits we'll want to merge accum_bits
1041
             * fewer of them into the final |element|.
1042
             *
1043
             * Note that with a 64-bit accumulator and |bits| always 12 or
1044
             * less, if we're here, the previous iteration had all the
1045
             * requisite bits, and so there are no kept bits in |element|.
1046
             */
1047
20.8k
            element = ((uint16_t)accum) & mask;
1048
20.8k
            todo -= accum_bits;
1049
20.8k
            mask = bitmask >> accum_bits;
1050
20.8k
            accum_bits = 0;
1051
20.8k
        }
1052
213k
    } while (curr < end);
1053
752
}
1054
1055
static __owur int scalar_decode_12(scalar *out, const uint8_t in[3 * DEGREE / 2])
1056
1.39k
{
1057
1.39k
    int i;
1058
1.39k
    uint16_t *c = out->c;
1059
1060
143k
    for (i = 0; i < DEGREE / 2; ++i) {
1061
142k
        uint8_t b1 = *in++;
1062
142k
        uint8_t b2 = *in++;
1063
142k
        uint8_t b3 = *in++;
1064
142k
        int outOfRange1 = (*c++ = b1 | ((b2 & 0x0f) << 8)) >= kPrime;
1065
142k
        int outOfRange2 = (*c++ = (b2 >> 4) | (b3 << 4)) >= kPrime;
1066
1067
142k
        if (outOfRange1 | outOfRange2)
1068
341
            return 0;
1069
142k
    }
1070
1.05k
    return 1;
1071
1.39k
}
1072
1073
/*-
1074
 * scalar_decode_decompress_add is a combination of decoding and decompression
1075
 * both specialised for |bits| == 1, with the result added (and sum reduced) to
1076
 * the output scalar.
1077
 *
1078
 * NOTE: this function MUST not leak an input-data-depedennt timing signal.
1079
 * A timing leak in a related function in the reference Kyber implementation
1080
 * made the "clangover" attack (CVE-2024-37880) possible, giving key recovery
1081
 * for ML-KEM-512 in minutes, provided the attacker has access to precise
1082
 * timing of a CPU performing chosen-ciphertext decap.  Admittedly this is only
1083
 * a risk when private keys are reused (perhaps KEMTLS servers).
1084
 */
1085
static void
1086
scalar_decode_decompress_add(scalar *out, const uint8_t in[DEGREE / 8])
1087
402
{
1088
402
    static const uint16_t half_q_plus_1 = (ML_KEM_PRIME >> 1) + 1;
1089
402
    uint16_t *curr = out->c, *end = curr + DEGREE;
1090
402
    uint16_t mask;
1091
402
    uint8_t b;
1092
1093
    /*
1094
     * Add |half_q_plus_1| if the bit is set, without exposing a side-channel,
1095
     * avoiding the "clangover" attack.  See |constish_time_non_zero| for a
1096
     * discussion on why the value barrier is by default omitted.
1097
     */
1098
402
#define decode_decompress_add_bit                        \
1099
102k
    mask = constish_time_non_zero(bit0(b));              \
1100
102k
    *curr = reduce_once(*curr + (mask & half_q_plus_1)); \
1101
102k
    curr++;                                              \
1102
102k
    b >>= 1
1103
1104
    /* Unrolled to process each byte in one iteration */
1105
12.8k
    do {
1106
12.8k
        b = *in++;
1107
12.8k
        decode_decompress_add_bit;
1108
12.8k
        decode_decompress_add_bit;
1109
12.8k
        decode_decompress_add_bit;
1110
12.8k
        decode_decompress_add_bit;
1111
1112
12.8k
        decode_decompress_add_bit;
1113
12.8k
        decode_decompress_add_bit;
1114
12.8k
        decode_decompress_add_bit;
1115
12.8k
        decode_decompress_add_bit;
1116
12.8k
    } while (curr < end);
1117
402
#undef decode_decompress_add_bit
1118
402
}
1119
1120
/*
1121
 * FIPS 203, Section 4.2.1, Equation (4.7): Compress_d.
1122
 *
1123
 * Compresses (lossily) an input |x| mod 3329 into |bits| many bits by grouping
1124
 * numbers close to each other together. The formula used is
1125
 * round(2^|bits|/kPrime*x) mod 2^|bits|.
1126
 * Uses Barrett reduction to achieve constant time. Since we need both the
1127
 * remainder (for rounding) and the quotient (as the result), we cannot use
1128
 * |reduce| here, but need to do the Barrett reduction directly.
1129
 */
1130
static __owur uint16_t compress(uint16_t x, int bits)
1131
457k
{
1132
457k
    uint32_t shifted = (uint32_t)x << bits;
1133
457k
    uint64_t product = (uint64_t)shifted * kBarrettMultiplier;
1134
457k
    uint32_t quotient = (uint32_t)(product >> kBarrettShift);
1135
457k
    uint32_t remainder = shifted - quotient * kPrime;
1136
1137
    /*
1138
     * Adjust the quotient to round correctly:
1139
     *   0 <= remainder <= kHalfPrime round to 0
1140
     *   kHalfPrime < remainder <= kPrime + kHalfPrime round to 1
1141
     *   kPrime + kHalfPrime < remainder < 2 * kPrime round to 2
1142
     */
1143
457k
    quotient += 1 & constant_time_lt_32(kHalfPrime, remainder);
1144
457k
    quotient += 1 & constant_time_lt_32(kPrime + kHalfPrime, remainder);
1145
457k
    return quotient & ((1 << bits) - 1);
1146
457k
}
1147
1148
/*
1149
 * FIPS 203, Section 4.2.1, Equation (4.8): Decompress_d.
1150
1151
 * Decompresses |x| by using a close equi-distant representative. The formula
1152
 * is round(kPrime/2^|bits|*x). Note that 2^|bits| being the divisor allows us
1153
 * to implement this logic using only bit operations.
1154
 */
1155
static __owur uint16_t decompress(uint16_t x, int bits)
1156
192k
{
1157
192k
    uint32_t product = (uint32_t)x * kPrime;
1158
192k
    uint32_t power = 1 << bits;
1159
    /* This is |product| % power, since |power| is a power of 2. */
1160
192k
    uint32_t remainder = product & (power - 1);
1161
    /* This is |product| / power, since |power| is a power of 2. */
1162
192k
    uint32_t lower = product >> bits;
1163
1164
    /*
1165
     * The rounding logic works since the first half of numbers mod |power|
1166
     * have a 0 as first bit, and the second half has a 1 as first bit, since
1167
     * |power| is a power of 2. As a 12 bit number, |remainder| is always
1168
     * positive, so we will shift in 0s for a right shift.
1169
     */
1170
192k
    return lower + (remainder >> (bits - 1));
1171
192k
}
1172
1173
/*-
1174
 * FIPS 203, Section 4.2.1, Equation (4.7): "Compress_d".
1175
 * In-place lossy rounding of scalars to 2^d bits.
1176
 */
1177
static void scalar_compress(scalar *s, int bits)
1178
1.78k
{
1179
1.78k
    int i;
1180
1181
459k
    for (i = 0; i < DEGREE; i++)
1182
457k
        s->c[i] = compress(s->c[i], bits);
1183
1.78k
}
1184
1185
/*
1186
 * FIPS 203, Section 4.2.1, Equation (4.8): "Decompress_d".
1187
 * In-place approximate recovery of scalars from 2^d bit compression.
1188
 */
1189
static void scalar_decompress(scalar *s, int bits)
1190
752
{
1191
752
    int i;
1192
1193
193k
    for (i = 0; i < DEGREE; i++)
1194
192k
        s->c[i] = decompress(s->c[i], bits);
1195
752
}
1196
1197
/* Addition updating the LHS vector in-place. */
1198
static void vector_add(scalar *lhs, const scalar *rhs, int rank)
1199
402
{
1200
1.19k
    do {
1201
1.19k
        scalar_add(lhs++, rhs++);
1202
1.19k
    } while (--rank > 0);
1203
402
}
1204
1205
/*
1206
 * Encodes an entire vector into 32*|rank|*|bits| bytes. Note that since 256
1207
 * (DEGREE) is divisible by 8, the individual vector entries will always fill a
1208
 * whole number of bytes, so we do not need to worry about bit packing here.
1209
 */
1210
static void vector_encode(uint8_t *out, const scalar *a, int bits, int rank)
1211
64.5k
{
1212
64.5k
    int stride = bits * DEGREE / 8;
1213
1214
258k
    for (; rank-- > 0; out += stride)
1215
193k
        scalar_encode(out, a++, bits);
1216
64.5k
}
1217
1218
/*
1219
 * Decodes 32*|rank|*|bits| bytes from |in| into |out|. It returns early
1220
 * if any parsed value is >= |ML_KEM_PRIME|.  The resulting scalars are
1221
 * then decompressed and transformed via the NTT.
1222
 *
1223
 * Note: Used only in decrypt_cpa(), which returns void and so does not check
1224
 * the return value of this function.  Side-channels are fine when the input
1225
 * ciphertext to decap() is simply syntactically invalid.
1226
 */
1227
static void
1228
vector_decode_decompress_ntt(scalar *out, const uint8_t *in, int bits, int rank)
1229
189
{
1230
189
    int stride = bits * DEGREE / 8;
1231
1232
752
    for (; rank-- > 0; in += stride, ++out) {
1233
563
        scalar_decode(out, in, bits);
1234
563
        scalar_decompress(out, bits);
1235
563
        scalar_ntt(out);
1236
563
    }
1237
189
}
1238
1239
/* vector_decode(), specialised to bits == 12. */
1240
static __owur int vector_decode_12(scalar *out, const uint8_t in[3 * DEGREE / 2], int rank)
1241
723
{
1242
723
    int stride = 3 * DEGREE / 2;
1243
1244
1.78k
    for (; rank-- > 0; in += stride)
1245
1.39k
        if (!scalar_decode_12(out++, in))
1246
341
            return 0;
1247
382
    return 1;
1248
723
}
1249
1250
/* In-place compression of each scalar component */
1251
static void vector_compress(scalar *a, int bits, int rank)
1252
402
{
1253
1.19k
    do {
1254
1.19k
        scalar_compress(a++, bits);
1255
1.19k
    } while (--rank > 0);
1256
402
}
1257
1258
/* The output scalar must not overlap with the inputs */
1259
static void inner_product(scalar *out, const scalar *lhs, const scalar *rhs,
1260
    int rank)
1261
591
{
1262
591
    scalar_mult(out, lhs, rhs);
1263
1.76k
    while (--rank > 0)
1264
1.17k
        scalar_mult_add(out, ++lhs, ++rhs);
1265
591
}
1266
1267
/*
1268
 * Here, the output vector must not overlap with the inputs, the result is
1269
 * directly subjected to inverse NTT.
1270
 */
1271
static void
1272
matrix_mult_intt(scalar *out, const scalar *m, const scalar *a, int rank)
1273
402
{
1274
402
    const scalar *ar;
1275
402
    int i, j;
1276
1277
1.60k
    for (i = rank; i-- > 0; ++out) {
1278
1.19k
        scalar_mult(out, m++, ar = a);
1279
3.81k
        for (j = rank - 1; j > 0; --j)
1280
2.61k
            scalar_mult_add(out, m++, ++ar);
1281
1.19k
        scalar_inverse_ntt(out);
1282
1.19k
    }
1283
402
}
1284
1285
/* Here, the output vector must not overlap with the inputs */
1286
static void
1287
matrix_mult_transpose_add(scalar *out, const scalar *m, const scalar *a, int rank)
1288
63.5k
{
1289
63.5k
    const scalar *mc = m, *mr, *ar;
1290
63.5k
    int i, j;
1291
1292
254k
    for (i = rank; i-- > 0; ++out) {
1293
190k
        scalar_mult_add(out, mr = mc++, ar = a);
1294
571k
        for (j = rank; --j > 0;)
1295
381k
            scalar_mult_add(out, (mr += rank), ++ar);
1296
190k
    }
1297
63.5k
}
1298
1299
/*-
1300
 * Expands the matrix from a seed for key generation and for encaps-CPA.
1301
 * NOTE: FIPS 203 matrix "A" is the transpose of this matrix, computed
1302
 * by appending the (i,j) indices to the seed in the opposite order!
1303
 *
1304
 * Where FIPS 203 computes t = A * s + e, we use the transpose of "m".
1305
 */
1306
static __owur int matrix_expand(EVP_MD_CTX *mdctx, ML_KEM_KEY *key)
1307
63.9k
{
1308
63.9k
    scalar *out = key->m;
1309
63.9k
    uint8_t input[ML_KEM_RANDOM_BYTES + 2];
1310
63.9k
    int rank = key->vinfo->rank;
1311
63.9k
    int i, j;
1312
1313
    /*
1314
     * The seeds derived below and the sampling buffers in sample_scalar()
1315
     * are not cleansed: per FIPS 203 section 3.3 the matrix A is easily
1316
     * computed from the public encapsulation key and does not require any
1317
     * special protections.
1318
     */
1319
63.9k
    memcpy(input, key->rho, ML_KEM_RANDOM_BYTES);
1320
255k
    for (i = 0; i < rank; i++) {
1321
765k
        for (j = 0; j < rank; j++) {
1322
574k
            input[ML_KEM_RANDOM_BYTES] = i;
1323
574k
            input[ML_KEM_RANDOM_BYTES + 1] = j;
1324
574k
            if (!EVP_DigestInit_ex(mdctx, key->shake128_md, NULL)
1325
574k
                || !EVP_DigestUpdate(mdctx, input, sizeof(input))
1326
574k
                || !sample_scalar(out++, mdctx))
1327
0
                return 0;
1328
574k
        }
1329
191k
    }
1330
63.9k
    return 1;
1331
63.9k
}
1332
1333
/*
1334
 * Algorithm 7 from the spec, with eta fixed to two and the PRF call
1335
 * included. Creates binominally distributed elements by sampling 2*|eta| bits,
1336
 * and setting the coefficient to the count of the first bits minus the count of
1337
 * the second bits, resulting in a centered binomial distribution. Since eta is
1338
 * two this gives -2/2 with a probability of 1/16, -1/1 with probability 1/4,
1339
 * and 0 with probability 3/8.
1340
 */
1341
static __owur int cbd_2(scalar *out, uint8_t in[ML_KEM_RANDOM_BYTES + 1],
1342
    EVP_MD_CTX *mdctx, const ML_KEM_KEY *key)
1343
382k
{
1344
382k
    uint16_t *curr = out->c, *end = curr + DEGREE;
1345
382k
    uint8_t randbuf[4 * DEGREE / 8], *r = randbuf; /* 64 * eta slots */
1346
382k
    uint16_t value, mask;
1347
382k
    uint8_t b;
1348
1349
382k
    if (!prf(randbuf, sizeof(randbuf), in, mdctx, key)) {
1350
0
        OPENSSL_cleanse((void *)randbuf, sizeof(randbuf));
1351
0
        return 0;
1352
0
    }
1353
1354
48.9M
    do {
1355
48.9M
        b = *r++;
1356
1357
        /*
1358
         * Add |kPrime| if |value| underflowed.  See |constish_time_non_zero|
1359
         * for a discussion on why the value barrier is by default omitted.
1360
         * While this could have been written reduce_once(value + kPrime), this
1361
         * is one extra addition and small range of |value| tempts some
1362
         * versions of Clang to emit a branch.
1363
         */
1364
48.9M
        value = bit0(b) + bitn(1, b);
1365
48.9M
        value -= bitn(2, b) + bitn(3, b);
1366
48.9M
        mask = constish_time_non_zero(value >> 15);
1367
48.9M
        *curr++ = value + (kPrime & mask);
1368
1369
48.9M
        value = bitn(4, b) + bitn(5, b);
1370
48.9M
        value -= bitn(6, b) + bitn(7, b);
1371
48.9M
        mask = constish_time_non_zero(value >> 15);
1372
48.9M
        *curr++ = value + (kPrime & mask);
1373
48.9M
    } while (curr < end);
1374
1375
382k
    OPENSSL_cleanse((void *)randbuf, sizeof(randbuf));
1376
382k
    return 1;
1377
382k
}
1378
1379
/*
1380
 * Algorithm 7 from the spec, with eta fixed to three and the PRF call
1381
 * included. Creates binominally distributed elements by sampling 3*|eta| bits,
1382
 * and setting the coefficient to the count of the first bits minus the count of
1383
 * the second bits, resulting in a centered binomial distribution.
1384
 */
1385
static __owur int cbd_3(scalar *out, uint8_t in[ML_KEM_RANDOM_BYTES + 1],
1386
    EVP_MD_CTX *mdctx, const ML_KEM_KEY *key)
1387
1.52k
{
1388
1.52k
    uint16_t *curr = out->c, *end = curr + DEGREE;
1389
1.52k
    uint8_t randbuf[6 * DEGREE / 8], *r = randbuf; /* 64 * eta slots */
1390
1.52k
    uint8_t b1, b2, b3;
1391
1.52k
    uint16_t value, mask;
1392
1393
1.52k
    if (!prf(randbuf, sizeof(randbuf), in, mdctx, key)) {
1394
0
        OPENSSL_cleanse((void *)randbuf, sizeof(randbuf));
1395
0
        return 0;
1396
0
    }
1397
1398
97.7k
    do {
1399
97.7k
        b1 = *r++;
1400
97.7k
        b2 = *r++;
1401
97.7k
        b3 = *r++;
1402
1403
        /*
1404
         * Add |kPrime| if |value| underflowed.  See |constish_time_non_zero|
1405
         * for a discussion on why the value barrier is by default omitted.
1406
         * While this could have been written reduce_once(value + kPrime), this
1407
         * is one extra addition and small range of |value| tempts some
1408
         * versions of Clang to emit a branch.
1409
         */
1410
97.7k
        value = bit0(b1) + bitn(1, b1) + bitn(2, b1);
1411
97.7k
        value -= bitn(3, b1) + bitn(4, b1) + bitn(5, b1);
1412
97.7k
        mask = constish_time_non_zero(value >> 15);
1413
97.7k
        *curr++ = value + (kPrime & mask);
1414
1415
97.7k
        value = bitn(6, b1) + bitn(7, b1) + bit0(b2);
1416
97.7k
        value -= bitn(1, b2) + bitn(2, b2) + bitn(3, b2);
1417
97.7k
        mask = constish_time_non_zero(value >> 15);
1418
97.7k
        *curr++ = value + (kPrime & mask);
1419
1420
97.7k
        value = bitn(4, b2) + bitn(5, b2) + bitn(6, b2);
1421
97.7k
        value -= bitn(7, b2) + bit0(b3) + bitn(1, b3);
1422
97.7k
        mask = constish_time_non_zero(value >> 15);
1423
97.7k
        *curr++ = value + (kPrime & mask);
1424
1425
97.7k
        value = bitn(2, b3) + bitn(3, b3) + bitn(4, b3);
1426
97.7k
        value -= bitn(5, b3) + bitn(6, b3) + bitn(7, b3);
1427
97.7k
        mask = constish_time_non_zero(value >> 15);
1428
97.7k
        *curr++ = value + (kPrime & mask);
1429
97.7k
    } while (curr < end);
1430
1431
1.52k
    OPENSSL_cleanse((void *)randbuf, sizeof(randbuf));
1432
1.52k
    return 1;
1433
1.52k
}
1434
1435
/*
1436
 * Generates a secret vector by using |cbd| with the given seed to generate
1437
 * scalar elements and incrementing |counter| for each slot of the vector.
1438
 */
1439
static __owur int gencbd_vector(scalar *out, CBD_FUNC cbd, uint8_t *counter,
1440
    const uint8_t seed[ML_KEM_RANDOM_BYTES], int rank,
1441
    EVP_MD_CTX *mdctx, const ML_KEM_KEY *key)
1442
402
{
1443
402
    uint8_t input[ML_KEM_RANDOM_BYTES + 1];
1444
402
    int ret = 0;
1445
1446
402
    memcpy(input, seed, ML_KEM_RANDOM_BYTES);
1447
1.19k
    do {
1448
1.19k
        input[ML_KEM_RANDOM_BYTES] = (*counter)++;
1449
1.19k
        if (!cbd(out++, input, mdctx, key))
1450
0
            goto end;
1451
1.19k
    } while (--rank > 0);
1452
402
    ret = 1;
1453
1454
402
end:
1455
402
    OPENSSL_cleanse((void *)input, sizeof(input));
1456
402
    return ret;
1457
402
}
1458
1459
/*
1460
 * As above plus NTT transform.
1461
 */
1462
static __owur int gencbd_vector_ntt(scalar *out, CBD_FUNC cbd, uint8_t *counter,
1463
    const uint8_t seed[ML_KEM_RANDOM_BYTES], int rank,
1464
    EVP_MD_CTX *mdctx, const ML_KEM_KEY *key)
1465
127k
{
1466
127k
    uint8_t input[ML_KEM_RANDOM_BYTES + 1];
1467
127k
    int ret = 0;
1468
1469
127k
    memcpy(input, seed, ML_KEM_RANDOM_BYTES);
1470
382k
    do {
1471
382k
        input[ML_KEM_RANDOM_BYTES] = (*counter)++;
1472
382k
        if (!cbd(out, input, mdctx, key))
1473
0
            goto end;
1474
382k
        scalar_ntt(out++);
1475
382k
    } while (--rank > 0);
1476
127k
    ret = 1;
1477
1478
127k
end:
1479
127k
    OPENSSL_cleanse((void *)input, sizeof(input));
1480
127k
    return ret;
1481
127k
}
1482
1483
/* The |ETA1| value for ML-KEM-512 is 3, the rest and all ETA2 values are 2. */
1484
30.5k
#define CBD1(evp_type) ((evp_type) == EVP_PKEY_ML_KEM_512 ? cbd_3 : cbd_2)
1485
1486
/*
1487
 * FIPS 203, Section 5.2, Algorithm 14: K-PKE.Encrypt.
1488
 *
1489
 * Encrypts a message with given randomness to the ciphertext in |out|. Without
1490
 * applying the Fujisaki-Okamoto transform this would not result in a CCA
1491
 * secure scheme, since lattice schemes are vulnerable to decryption failure
1492
 * oracles.
1493
 *
1494
 * The steps are re-ordered to make more efficient/localised use of storage.
1495
 *
1496
 * Note also that the input public key is assumed to hold a precomputed matrix
1497
 * |A| (our key->m, with the public key holding an expanded (16-bit per scalar
1498
 * coefficient) key->t vector).
1499
 *
1500
 * Caller passes storage in |tmp| for for two temporary vectors.
1501
 */
1502
static __owur int encrypt_cpa(uint8_t out[ML_KEM_SHARED_SECRET_BYTES],
1503
    const uint8_t message[DEGREE / 8],
1504
    const uint8_t r[ML_KEM_RANDOM_BYTES], scalar *tmp,
1505
    EVP_MD_CTX *mdctx, const ML_KEM_KEY *key)
1506
402
{
1507
402
    const ML_KEM_VINFO *vinfo = key->vinfo;
1508
402
    CBD_FUNC cbd_1 = CBD1(vinfo->evp_type);
1509
402
    int rank = vinfo->rank;
1510
    /* We can use tmp[0..rank-1] as storage for |y|, then |e1|, ... */
1511
402
    scalar *y = &tmp[0], *e1 = y, *e2 = y;
1512
    /* We can use tmp[rank]..tmp[2*rank - 1] for |u| */
1513
402
    scalar *u = &tmp[rank];
1514
402
    scalar v;
1515
402
    uint8_t input[ML_KEM_RANDOM_BYTES + 1];
1516
402
    uint8_t counter = 0;
1517
402
    int du = vinfo->du;
1518
402
    int dv = vinfo->dv;
1519
402
    int ret = 0;
1520
1521
    /* FIPS 203 "y" vector */
1522
402
    if (!gencbd_vector_ntt(y, cbd_1, &counter, r, rank, mdctx, key))
1523
0
        goto end;
1524
    /* FIPS 203 "v" scalar */
1525
402
    inner_product(&v, key->t, y, rank);
1526
402
    scalar_inverse_ntt(&v);
1527
    /* FIPS 203 "u" vector */
1528
402
    matrix_mult_intt(u, key->m, y, rank);
1529
1530
    /* All done with |y|, now free to reuse tmp[0] for FIPS 203 |e1| */
1531
402
    if (!gencbd_vector(e1, cbd_2, &counter, r, rank, mdctx, key))
1532
0
        goto end;
1533
402
    vector_add(u, e1, rank);
1534
402
    vector_compress(u, du, rank);
1535
402
    vector_encode(out, u, du, rank);
1536
1537
    /* All done with |e1|, now free to reuse tmp[0] for FIPS 203 |e2| */
1538
402
    memcpy(input, r, ML_KEM_RANDOM_BYTES);
1539
402
    input[ML_KEM_RANDOM_BYTES] = counter;
1540
402
    if (!cbd_2(e2, input, mdctx, key))
1541
0
        goto end;
1542
402
    scalar_add(&v, e2);
1543
1544
    /* Combine message with |v| */
1545
402
    scalar_decode_decompress_add(&v, message);
1546
402
    scalar_compress(&v, dv);
1547
402
    scalar_encode(out + vinfo->u_vector_bytes, &v, dv);
1548
402
    ret = 1;
1549
1550
402
end:
1551
402
    OPENSSL_cleanse((void *)input, sizeof(input));
1552
402
    OPENSSL_cleanse((void *)&v, sizeof(v));
1553
402
    return ret;
1554
402
}
1555
1556
/*
1557
 * FIPS 203, Section 5.3, Algorithm 15: K-PKE.Decrypt.
1558
 */
1559
static void
1560
decrypt_cpa(uint8_t out[ML_KEM_SHARED_SECRET_BYTES],
1561
    const uint8_t *ctext, scalar *u, const ML_KEM_KEY *key)
1562
189
{
1563
189
    const ML_KEM_VINFO *vinfo = key->vinfo;
1564
189
    scalar v, mask;
1565
189
    int rank = vinfo->rank;
1566
189
    int du = vinfo->du;
1567
189
    int dv = vinfo->dv;
1568
1569
189
    vector_decode_decompress_ntt(u, ctext, du, rank);
1570
189
    scalar_decode(&v, ctext + vinfo->u_vector_bytes, dv);
1571
189
    scalar_decompress(&v, dv);
1572
189
    inner_product(&mask, key->s, u, rank);
1573
189
    scalar_inverse_ntt(&mask);
1574
189
    scalar_sub(&v, &mask);
1575
189
    scalar_compress(&v, 1);
1576
189
    scalar_encode_1(out, &v);
1577
1578
189
    OPENSSL_cleanse((void *)&v, sizeof(v));
1579
189
    OPENSSL_cleanse((void *)&mask, sizeof(mask));
1580
189
}
1581
1582
/*-
1583
 * FIPS 203, Section 7.1, Algorithm 19: "ML-KEM.KeyGen".
1584
 * FIPS 203, Section 7.2, Algorithm 20: "ML-KEM.Encaps".
1585
 *
1586
 * Fills the |out| buffer with the |ek| output of "ML-KEM.KeyGen", or,
1587
 * equivalently, the |ek| input of "ML-KEM.Encaps", i.e. returns the
1588
 * wire-format of an ML-KEM public key.
1589
 */
1590
static void encode_pubkey(uint8_t *out, const ML_KEM_KEY *key)
1591
64.0k
{
1592
64.0k
    const uint8_t *rho = key->rho;
1593
64.0k
    const ML_KEM_VINFO *vinfo = key->vinfo;
1594
1595
64.0k
    vector_encode(out, key->t, 12, vinfo->rank);
1596
64.0k
    memcpy(out + vinfo->vector_bytes, rho, ML_KEM_RANDOM_BYTES);
1597
64.0k
}
1598
1599
/*-
1600
 * FIPS 203, Section 7.1, Algorithm 19: "ML-KEM.KeyGen".
1601
 *
1602
 * Fills the |out| buffer with the |dk| output of "ML-KEM.KeyGen".
1603
 * This matches the input format of parse_prvkey() below.
1604
 */
1605
static void encode_prvkey(uint8_t *out, const ML_KEM_KEY *key)
1606
144
{
1607
144
    const ML_KEM_VINFO *vinfo = key->vinfo;
1608
1609
144
    vector_encode(out, key->s, 12, vinfo->rank);
1610
144
    out += vinfo->vector_bytes;
1611
144
    encode_pubkey(out, key);
1612
144
    out += vinfo->pubkey_bytes;
1613
144
    memcpy(out, key->pkhash, ML_KEM_PKHASH_BYTES);
1614
144
    out += ML_KEM_PKHASH_BYTES;
1615
144
    memcpy(out, key->z, ML_KEM_RANDOM_BYTES);
1616
144
}
1617
1618
/*-
1619
 * FIPS 203, Section 7.1, Algorithm 19: "ML-KEM.KeyGen".
1620
 * FIPS 203, Section 7.2, Algorithm 20: "ML-KEM.Encaps".
1621
 *
1622
 * This function parses the |in| buffer as the |ek| output of "ML-KEM.KeyGen",
1623
 * or, equivalently, the |ek| input of "ML-KEM.Encaps", i.e. decodes the
1624
 * wire-format of the ML-KEM public key.
1625
 */
1626
static int parse_pubkey(const uint8_t *in, EVP_MD_CTX *mdctx, ML_KEM_KEY *key)
1627
612
{
1628
612
    const ML_KEM_VINFO *vinfo = key->vinfo;
1629
1630
    /* Decode and check |t| */
1631
612
    if (!vector_decode_12(key->t, in, vinfo->rank)) {
1632
252
        ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY,
1633
252
            "%s invalid public 't' vector",
1634
252
            vinfo->algorithm_name);
1635
252
        return 0;
1636
252
    }
1637
    /* Save the matrix |m| recovery seed |rho| */
1638
360
    memcpy(key->rho, in + vinfo->vector_bytes, ML_KEM_RANDOM_BYTES);
1639
    /*
1640
     * Pre-compute the public key hash, needed for both encap and decap.
1641
     * Also pre-compute the matrix expansion, stored with the public key.
1642
     */
1643
360
    if (!hash_h(key->pkhash, in, vinfo->pubkey_bytes, mdctx, key)
1644
360
        || !matrix_expand(mdctx, key)) {
1645
0
        ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR,
1646
0
            "internal error while parsing %s public key",
1647
0
            vinfo->algorithm_name);
1648
0
        return 0;
1649
0
    }
1650
360
    return 1;
1651
360
}
1652
1653
/*
1654
 * FIPS 203, Section 7.1, Algorithm 19: "ML-KEM.KeyGen".
1655
 *
1656
 * Parses the |in| buffer as a |dk| output of "ML-KEM.KeyGen".
1657
 * This matches the output format of encode_prvkey() above.
1658
 */
1659
static int parse_prvkey(const uint8_t *in, EVP_MD_CTX *mdctx, ML_KEM_KEY *key)
1660
111
{
1661
111
    const ML_KEM_VINFO *vinfo = key->vinfo;
1662
1663
    /* Decode and check |s|. */
1664
111
    if (!vector_decode_12(key->s, in, vinfo->rank)) {
1665
89
        ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY,
1666
89
            "%s invalid private 's' vector",
1667
89
            vinfo->algorithm_name);
1668
89
        return 0;
1669
89
    }
1670
22
    in += vinfo->vector_bytes;
1671
1672
22
    if (!parse_pubkey(in, mdctx, key))
1673
11
        return 0;
1674
11
    in += vinfo->pubkey_bytes;
1675
1676
    /* Check public key hash. */
1677
11
    if (memcmp(key->pkhash, in, ML_KEM_PKHASH_BYTES) != 0) {
1678
11
        ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY,
1679
11
            "%s public key hash mismatch",
1680
11
            vinfo->algorithm_name);
1681
11
        return 0;
1682
11
    }
1683
0
    in += ML_KEM_PKHASH_BYTES;
1684
1685
0
    memcpy(key->z, in, ML_KEM_RANDOM_BYTES);
1686
0
    return 1;
1687
11
}
1688
1689
/*
1690
 * FIPS 203, Section 6.1, Algorithm 16: "ML-KEM.KeyGen_internal".
1691
 *
1692
 * The implementation of Section 5.1, Algorithm 13, "K-PKE.KeyGen(d)" is
1693
 * inlined.
1694
 *
1695
 * The caller MUST pass a pre-allocated digest context that is not shared with
1696
 * any concurrent computation.
1697
 *
1698
 * This function optionally outputs the serialised wire-form |ek| public key
1699
 * into the provided |pubenc| buffer, and generates the content of the |rho|,
1700
 * |pkhash|, |t|, |m|, |s| and |z| components of the private |key| (which must
1701
 * have preallocated space for these).
1702
 *
1703
 * Keys are computed from a 32-byte random |d| plus the 1 byte rank for
1704
 * domain separation.  These are concatenated and hashed to produce a pair of
1705
 * 32-byte seeds public "rho", used to generate the matrix, and private "sigma",
1706
 * used to generate the secret vector |s|.
1707
 *
1708
 * The second random input |z| is copied verbatim into the Fujisaki-Okamoto
1709
 * (FO) transform "implicit-rejection" secret (the |z| component of the private
1710
 * key), which thwarts chosen-ciphertext attacks, provided decap() runs in
1711
 * constant time, with no side channel leaks, on all well-formed (valid length,
1712
 * and correctly encoded) ciphertext inputs.
1713
 */
1714
static __owur int genkey(const uint8_t seed[ML_KEM_SEED_BYTES],
1715
    EVP_MD_CTX *mdctx, uint8_t *pubenc, ML_KEM_KEY *key)
1716
30.1k
{
1717
30.1k
    uint8_t hashed[2 * ML_KEM_RANDOM_BYTES];
1718
30.1k
    const uint8_t *const sigma = hashed + ML_KEM_RANDOM_BYTES;
1719
30.1k
    uint8_t augmented_seed[ML_KEM_RANDOM_BYTES + 1];
1720
30.1k
    const ML_KEM_VINFO *vinfo = key->vinfo;
1721
30.1k
    CBD_FUNC cbd_1 = CBD1(vinfo->evp_type);
1722
30.1k
    int rank = vinfo->rank;
1723
30.1k
    uint8_t counter = 0;
1724
30.1k
    int ret = 0;
1725
1726
    /*
1727
     * Use the "d" seed salted with the rank to derive the public and private
1728
     * seeds rho and sigma.
1729
     */
1730
30.1k
    memcpy(augmented_seed, seed, ML_KEM_RANDOM_BYTES);
1731
30.1k
    augmented_seed[ML_KEM_RANDOM_BYTES] = (uint8_t)rank;
1732
30.1k
    if (!hash_g(hashed, augmented_seed, sizeof(augmented_seed), mdctx, key))
1733
0
        goto end;
1734
30.1k
    memcpy(key->rho, hashed, ML_KEM_RANDOM_BYTES);
1735
    /* The |rho| matrix seed is public */
1736
30.1k
    CONSTTIME_DECLASSIFY(key->rho, ML_KEM_RANDOM_BYTES);
1737
1738
    /* FIPS 203 |e| vector is initial value of key->t */
1739
30.1k
    if (!matrix_expand(mdctx, key)
1740
30.1k
        || !gencbd_vector_ntt(key->s, cbd_1, &counter, sigma, rank, mdctx, key)
1741
30.1k
        || !gencbd_vector_ntt(key->t, cbd_1, &counter, sigma, rank, mdctx, key))
1742
0
        goto end;
1743
1744
    /* To |e| we now add the product of transpose |m| and |s|, giving |t|. */
1745
30.1k
    matrix_mult_transpose_add(key->t, key->m, key->s, rank);
1746
    /* The |t| vector is public */
1747
30.1k
    CONSTTIME_DECLASSIFY(key->t, vinfo->rank * sizeof(scalar));
1748
1749
30.1k
    if (pubenc == NULL) {
1750
        /* Incremental digest of public key without in-full serialisation. */
1751
30.1k
        if (!hash_h_pubkey(key->pkhash, mdctx, key))
1752
0
            goto end;
1753
30.1k
    } else {
1754
0
        encode_pubkey(pubenc, key);
1755
0
        if (!hash_h(key->pkhash, pubenc, vinfo->pubkey_bytes, mdctx, key))
1756
0
            goto end;
1757
0
    }
1758
1759
    /* Save |z| portion of seed for "implicit rejection" on failure. */
1760
30.1k
    memcpy(key->z, seed + ML_KEM_RANDOM_BYTES, ML_KEM_RANDOM_BYTES);
1761
1762
    /* Optionally save the |d| portion of the seed */
1763
30.1k
    key->d = key->z + ML_KEM_RANDOM_BYTES;
1764
30.1k
    if (key->prov_flags & ML_KEM_KEY_RETAIN_SEED) {
1765
30.1k
        memcpy(key->d, seed, ML_KEM_RANDOM_BYTES);
1766
30.1k
    } else {
1767
0
        OPENSSL_cleanse(key->d, ML_KEM_RANDOM_BYTES);
1768
0
        key->d = NULL;
1769
0
    }
1770
1771
30.1k
    ret = 1;
1772
30.1k
end:
1773
30.1k
    OPENSSL_cleanse((void *)augmented_seed, sizeof(augmented_seed));
1774
30.1k
    OPENSSL_cleanse((void *)hashed, sizeof(hashed));
1775
30.1k
    if (ret == 0) {
1776
0
        ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR,
1777
0
            "internal error while generating %s private key",
1778
0
            vinfo->algorithm_name);
1779
0
    }
1780
30.1k
    return ret;
1781
30.1k
}
1782
1783
/*-
1784
 * FIPS 203, Section 6.2, Algorithm 17: "ML-KEM.Encaps_internal".
1785
 * This is the deterministic version with randomness supplied externally.
1786
 *
1787
 * The caller must pass space for two vectors in |tmp|.
1788
 * The |ctext| buffer have space for the ciphertext of the ML-KEM variant
1789
 * of the provided key.
1790
 */
1791
static int encap(uint8_t *ctext, uint8_t secret[ML_KEM_SHARED_SECRET_BYTES],
1792
    const uint8_t entropy[ML_KEM_RANDOM_BYTES],
1793
    scalar *tmp, EVP_MD_CTX *mdctx, const ML_KEM_KEY *key)
1794
213
{
1795
213
    uint8_t input[ML_KEM_RANDOM_BYTES + ML_KEM_PKHASH_BYTES];
1796
213
    uint8_t Kr[ML_KEM_SHARED_SECRET_BYTES + ML_KEM_RANDOM_BYTES];
1797
213
    uint8_t *r = Kr + ML_KEM_SHARED_SECRET_BYTES;
1798
213
    int ret;
1799
1800
213
    memcpy(input, entropy, ML_KEM_RANDOM_BYTES);
1801
213
    memcpy(input + ML_KEM_RANDOM_BYTES, key->pkhash, ML_KEM_PKHASH_BYTES);
1802
213
    ret = hash_g(Kr, input, sizeof(input), mdctx, key)
1803
213
        && encrypt_cpa(ctext, entropy, r, tmp, mdctx, key);
1804
213
    OPENSSL_cleanse((void *)input, sizeof(input));
1805
1806
213
    if (ret)
1807
213
        memcpy(secret, Kr, ML_KEM_SHARED_SECRET_BYTES);
1808
0
    else
1809
0
        ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR,
1810
0
            "internal error while performing %s encapsulation",
1811
0
            key->vinfo->algorithm_name);
1812
213
    OPENSSL_cleanse((void *)Kr, sizeof(Kr));
1813
213
    return ret;
1814
213
}
1815
1816
/*
1817
 * FIPS 203, Section 6.3, Algorithm 18: ML-KEM.Decaps_internal
1818
 *
1819
 * Barring failure of the supporting SHA3/SHAKE primitives, this is fully
1820
 * deterministic, the randomness for the FO transform is extracted during
1821
 * private key generation.
1822
 *
1823
 * The caller must pass space for two vectors in |tmp|.
1824
 * The |ctext| and |tmp_ctext| buffers must each have space for the ciphertext
1825
 * of the key's ML-KEM variant.
1826
 */
1827
static int decap(uint8_t secret[ML_KEM_SHARED_SECRET_BYTES],
1828
    const uint8_t *ctext, uint8_t *tmp_ctext, scalar *tmp,
1829
    EVP_MD_CTX *mdctx, const ML_KEM_KEY *key)
1830
97
{
1831
97
    uint8_t decrypted[ML_KEM_SHARED_SECRET_BYTES + ML_KEM_PKHASH_BYTES];
1832
97
    uint8_t failure_key[ML_KEM_RANDOM_BYTES];
1833
97
    uint8_t Kr[ML_KEM_SHARED_SECRET_BYTES + ML_KEM_RANDOM_BYTES];
1834
97
    uint8_t *r = Kr + ML_KEM_SHARED_SECRET_BYTES;
1835
97
    const uint8_t *pkhash = key->pkhash;
1836
97
    const ML_KEM_VINFO *vinfo = key->vinfo;
1837
97
    int i;
1838
97
    uint8_t mask;
1839
1840
    /*
1841
     * If our KDF is unavailable, fail early! Otherwise, keep going ignoring
1842
     * any further errors, returning success, and whatever we got for a shared
1843
     * secret.  The decrypt_cpa() function is just arithmetic on secret data,
1844
     * so should not be subject to failure that makes its output predictable.
1845
     *
1846
     * We guard against "should never happen" catastrophic failure of the
1847
     * "pure" function |hash_g| by overwriting the shared secret with the
1848
     * content of the failure key and returning early, if nevertheless hash_g
1849
     * fails.  This is not constant-time, but a failure of |hash_g| already
1850
     * implies loss of side-channel resistance.
1851
     *
1852
     * The same action is taken, if also |encrypt_cpa| should catastrophically
1853
     * fail, due to failure of the |PRF| underlying the CBD functions.
1854
     */
1855
97
    if (!kdf(failure_key, key->z, ctext, vinfo->ctext_bytes, mdctx, key)) {
1856
0
        ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR,
1857
0
            "internal error while performing %s decapsulation",
1858
0
            vinfo->algorithm_name);
1859
0
        OPENSSL_cleanse(failure_key, sizeof(failure_key));
1860
0
        return 0;
1861
0
    }
1862
97
    decrypt_cpa(decrypted, ctext, tmp, key);
1863
97
    memcpy(decrypted + ML_KEM_SHARED_SECRET_BYTES, pkhash, ML_KEM_PKHASH_BYTES);
1864
97
    if (!hash_g(Kr, decrypted, sizeof(decrypted), mdctx, key)
1865
97
        || !encrypt_cpa(tmp_ctext, decrypted, r, tmp, mdctx, key)) {
1866
0
        memcpy(secret, failure_key, ML_KEM_SHARED_SECRET_BYTES);
1867
0
        OPENSSL_cleanse(decrypted, ML_KEM_SHARED_SECRET_BYTES);
1868
0
        OPENSSL_cleanse(Kr, sizeof(Kr));
1869
0
        OPENSSL_cleanse(failure_key, sizeof(failure_key));
1870
0
        return 1;
1871
0
    }
1872
97
    mask = constant_time_eq_int_8(0,
1873
97
        CRYPTO_memcmp(ctext, tmp_ctext, vinfo->ctext_bytes));
1874
3.20k
    for (i = 0; i < ML_KEM_SHARED_SECRET_BYTES; i++)
1875
3.10k
        secret[i] = constant_time_select_8(mask, Kr[i], failure_key[i]);
1876
97
    OPENSSL_cleanse(decrypted, ML_KEM_SHARED_SECRET_BYTES);
1877
97
    OPENSSL_cleanse(Kr, sizeof(Kr));
1878
97
    OPENSSL_cleanse(failure_key, sizeof(failure_key));
1879
97
    return 1;
1880
97
}
1881
1882
/*
1883
 * After allocating storage for public or private key data, update the key
1884
 * component pointers to reference that storage.
1885
 */
1886
static __owur int add_storage(scalar *p, int private, int dup, ML_KEM_KEY *key)
1887
15.2k
{
1888
15.2k
    int rank = key->vinfo->rank;
1889
1890
15.2k
    if (p == NULL)
1891
0
        return 0;
1892
1893
    /*
1894
     * We're adding key material, the seed buffer will now hold |rho| and
1895
     * |pkhash|.  Zero the key hash when creating fresh keys; when
1896
     * duplicating, |key| was memdup'd from the source so |seedbuf|
1897
     * already carries the correct |rho|/|pkhash| bytes — preserve them.
1898
     */
1899
15.2k
    if (dup == 0)
1900
15.2k
        memset(key->seedbuf, 0, sizeof(key->seedbuf));
1901
15.2k
    key->rho = key->seedbuf;
1902
15.2k
    key->pkhash = key->seedbuf + ML_KEM_RANDOM_BYTES;
1903
15.2k
    key->d = key->z = NULL;
1904
1905
    /* A public key needs space for |t| and |m| */
1906
15.2k
    key->m = (key->t = p) + rank;
1907
1908
    /*
1909
     * A private key also needs space for |s| and |z|.
1910
     * The |z| buffer always includes additional space for |d|, but a key's |d|
1911
     * pointer is left NULL when parsed from the NIST format, which omits that
1912
     * information.  Only keys generated from a (d, z) seed pair will have a
1913
     * non-NULL |d| pointer.
1914
     */
1915
15.2k
    if (private)
1916
15.1k
        key->z = (uint8_t *)(rank + (key->s = key->m + rank * rank));
1917
15.2k
    return 1;
1918
15.2k
}
1919
1920
/*
1921
 * After freeing the storage associated with a key that failed to be
1922
 * constructed, reset the internal pointers back to NULL.
1923
 */
1924
void ossl_ml_kem_key_reset(ML_KEM_KEY *key)
1925
15.3k
{
1926
15.3k
    if (key->t == NULL)
1927
125
        return;
1928
    /*-
1929
     * Cleanse any sensitive data:
1930
     * - The private vector |s| is immediately followed by the FO failure
1931
     *   secret |z|, and seed |d|, we can cleanse all three in one call.
1932
     *
1933
     * - Otherwise, when key->d is set, cleanse the stashed seed.
1934
     */
1935
15.2k
    if (ossl_ml_kem_have_prvkey(key))
1936
15.1k
        OPENSSL_cleanse(key->s,
1937
15.1k
            key->vinfo->rank * sizeof(scalar) + 2 * ML_KEM_RANDOM_BYTES);
1938
15.2k
    OPENSSL_free(key->t);
1939
15.2k
    key->d = key->z = (uint8_t *)(key->s = key->m = key->t = NULL);
1940
15.2k
}
1941
1942
/*
1943
 * ----- API exported to the provider
1944
 *
1945
 * Parameters with an implicit fixed length in the internal static API of each
1946
 * variant have an explicit checked length argument at this layer.
1947
 */
1948
1949
/* Retrieve the parameters of one of the ML-KEM variants */
1950
const ML_KEM_VINFO *ossl_ml_kem_get_vinfo(int evp_type)
1951
299k
{
1952
299k
    switch (evp_type) {
1953
61.5k
    case EVP_PKEY_ML_KEM_512:
1954
61.5k
        return &vinfo_map[ML_KEM_512_VINFO];
1955
180k
    case EVP_PKEY_ML_KEM_768:
1956
180k
        return &vinfo_map[ML_KEM_768_VINFO];
1957
57.8k
    case EVP_PKEY_ML_KEM_1024:
1958
57.8k
        return &vinfo_map[ML_KEM_1024_VINFO];
1959
299k
    }
1960
0
    return NULL;
1961
299k
}
1962
1963
ML_KEM_KEY *ossl_ml_kem_key_new(OSSL_LIB_CTX *libctx, const char *properties,
1964
    int evp_type)
1965
44.0k
{
1966
44.0k
    const ML_KEM_VINFO *vinfo = ossl_ml_kem_get_vinfo(evp_type);
1967
44.0k
    ML_KEM_KEY *key;
1968
1969
44.0k
    if (vinfo == NULL) {
1970
0
        ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT,
1971
0
            "unsupported ML-KEM key type: %d", evp_type);
1972
0
        return NULL;
1973
0
    }
1974
1975
44.0k
    if ((key = OPENSSL_malloc(sizeof(*key))) == NULL)
1976
0
        return NULL;
1977
1978
44.0k
    key->vinfo = vinfo;
1979
44.0k
    key->libctx = libctx;
1980
44.0k
    key->prov_flags = ML_KEM_KEY_PROV_FLAGS_DEFAULT;
1981
44.0k
    key->shake128_md = EVP_MD_fetch(libctx, "SHAKE128", properties);
1982
44.0k
    key->shake256_md = EVP_MD_fetch(libctx, "SHAKE256", properties);
1983
44.0k
    key->sha3_256_md = EVP_MD_fetch(libctx, "SHA3-256", properties);
1984
44.0k
    key->sha3_512_md = EVP_MD_fetch(libctx, "SHA3-512", properties);
1985
44.0k
    key->d = key->z = key->rho = key->pkhash = key->encoded_dk = NULL;
1986
44.0k
    key->s = key->m = key->t = NULL;
1987
1988
44.0k
    if (key->shake128_md != NULL
1989
44.0k
        && key->shake256_md != NULL
1990
44.0k
        && key->sha3_256_md != NULL
1991
44.0k
        && key->sha3_512_md != NULL)
1992
44.0k
        return key;
1993
1994
0
    ossl_ml_kem_key_free(key);
1995
0
    ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR,
1996
0
        "missing SHA3 digest algorithms while creating %s key",
1997
0
        vinfo->algorithm_name);
1998
0
    return NULL;
1999
44.0k
}
2000
2001
ML_KEM_KEY *ossl_ml_kem_key_dup(const ML_KEM_KEY *key, int selection)
2002
32
{
2003
32
    int ok = 0;
2004
32
    ML_KEM_KEY *ret;
2005
2006
    /*
2007
     * Partially decoded keys, not yet imported or loaded, should never be
2008
     * duplicated.
2009
     */
2010
32
    if (ossl_ml_kem_decoded_key(key))
2011
0
        return NULL;
2012
2013
32
    if (key == NULL
2014
32
        || (ret = OPENSSL_memdup(key, sizeof(*key))) == NULL)
2015
0
        return NULL;
2016
32
    ret->d = ret->z = ret->rho = ret->pkhash = NULL;
2017
32
    ret->s = ret->m = ret->t = NULL;
2018
2019
    /* Clear selection bits we can't fulfill */
2020
32
    if (!ossl_ml_kem_have_pubkey(key))
2021
0
        selection = 0;
2022
32
    else if (!ossl_ml_kem_have_prvkey(key))
2023
2
        selection &= ~OSSL_KEYMGMT_SELECT_PRIVATE_KEY;
2024
30
    else if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0)
2025
30
        selection &= ~OSSL_KEYMGMT_SELECT_PUBLIC_KEY;
2026
2027
32
    switch (selection & OSSL_KEYMGMT_SELECT_KEYPAIR) {
2028
0
    case 0:
2029
0
        ok = 1;
2030
0
        break;
2031
2
    case OSSL_KEYMGMT_SELECT_PUBLIC_KEY:
2032
2
        ok = add_storage(OPENSSL_memdup(key->t, key->vinfo->puballoc), 0, 1, ret);
2033
2
        break;
2034
30
    case OSSL_KEYMGMT_SELECT_PRIVATE_KEY:
2035
30
        ok = add_storage(OPENSSL_memdup(key->t, key->vinfo->prvalloc), 1, 1, ret);
2036
        /* Duplicated keys retain |d|, if available */
2037
30
        if (key->d != NULL)
2038
30
            ret->d = ret->z + ML_KEM_RANDOM_BYTES;
2039
30
        break;
2040
32
    }
2041
2042
32
    if (!ok) {
2043
0
        OPENSSL_free(ret);
2044
0
        return NULL;
2045
0
    }
2046
2047
32
    EVP_MD_up_ref(ret->shake128_md);
2048
32
    EVP_MD_up_ref(ret->shake256_md);
2049
32
    EVP_MD_up_ref(ret->sha3_256_md);
2050
32
    EVP_MD_up_ref(ret->sha3_512_md);
2051
2052
32
    return ret;
2053
32
}
2054
2055
void ossl_ml_kem_key_free(ML_KEM_KEY *key)
2056
80.2k
{
2057
80.2k
    if (key == NULL)
2058
64.9k
        return;
2059
2060
15.2k
    EVP_MD_free(key->shake128_md);
2061
15.2k
    EVP_MD_free(key->shake256_md);
2062
15.2k
    EVP_MD_free(key->sha3_256_md);
2063
15.2k
    EVP_MD_free(key->sha3_512_md);
2064
2065
15.2k
    if (ossl_ml_kem_decoded_key(key)) {
2066
0
        OPENSSL_cleanse(key->seedbuf, sizeof(key->seedbuf));
2067
0
        if (ossl_ml_kem_have_dkenc(key)) {
2068
0
            OPENSSL_cleanse(key->encoded_dk, key->vinfo->prvkey_bytes);
2069
0
            OPENSSL_free(key->encoded_dk);
2070
0
        }
2071
0
    }
2072
15.2k
    ossl_ml_kem_key_reset(key);
2073
15.2k
    OPENSSL_free(key);
2074
15.2k
}
2075
2076
/* Serialise the public component of an ML-KEM key */
2077
int ossl_ml_kem_encode_public_key(uint8_t *out, size_t len,
2078
    const ML_KEM_KEY *key)
2079
63.8k
{
2080
63.8k
    if (!ossl_ml_kem_have_pubkey(key)
2081
63.8k
        || len != key->vinfo->pubkey_bytes)
2082
0
        return 0;
2083
63.8k
    encode_pubkey(out, key);
2084
63.8k
    return 1;
2085
63.8k
}
2086
2087
/* Serialise an ML-KEM private key */
2088
int ossl_ml_kem_encode_private_key(uint8_t *out, size_t len,
2089
    const ML_KEM_KEY *key)
2090
144
{
2091
144
    if (!ossl_ml_kem_have_prvkey(key)
2092
144
        || len != key->vinfo->prvkey_bytes)
2093
0
        return 0;
2094
144
    encode_prvkey(out, key);
2095
144
    return 1;
2096
144
}
2097
2098
int ossl_ml_kem_encode_seed(uint8_t *out, size_t len,
2099
    const ML_KEM_KEY *key)
2100
267
{
2101
267
    if (key == NULL || key->d == NULL || len != ML_KEM_SEED_BYTES)
2102
47
        return 0;
2103
    /*
2104
     * Both in the seed buffer, and in the allocated storage, the |d| component
2105
     * of the seed is stored last, so we must copy each separately.
2106
     */
2107
220
    memcpy(out, key->d, ML_KEM_RANDOM_BYTES);
2108
220
    out += ML_KEM_RANDOM_BYTES;
2109
220
    memcpy(out, key->z, ML_KEM_RANDOM_BYTES);
2110
220
    return 1;
2111
267
}
2112
2113
/*
2114
 * Stash the seed without (yet) performing a keygen, used during decoding, to
2115
 * avoid an extra keygen if we're only going to export the key again to load
2116
 * into another provider.
2117
 */
2118
ML_KEM_KEY *ossl_ml_kem_set_seed(const uint8_t *seed, size_t seedlen, ML_KEM_KEY *key)
2119
56
{
2120
56
    if (key == NULL
2121
56
        || ossl_ml_kem_have_pubkey(key)
2122
56
        || ossl_ml_kem_have_seed(key)
2123
56
        || seedlen != ML_KEM_SEED_BYTES)
2124
0
        return NULL;
2125
    /*
2126
     * With no public or private key material on hand, we can use the seed
2127
     * buffer for |z| and |d|, in that order.
2128
     */
2129
56
    key->z = key->seedbuf;
2130
56
    key->d = key->z + ML_KEM_RANDOM_BYTES;
2131
56
    memcpy(key->d, seed, ML_KEM_RANDOM_BYTES);
2132
56
    seed += ML_KEM_RANDOM_BYTES;
2133
56
    memcpy(key->z, seed, ML_KEM_RANDOM_BYTES);
2134
56
    return key;
2135
56
}
2136
2137
/* Parse input as a public key */
2138
int ossl_ml_kem_parse_public_key(const uint8_t *in, size_t len, ML_KEM_KEY *key)
2139
590
{
2140
590
    EVP_MD_CTX *mdctx = NULL;
2141
590
    const ML_KEM_VINFO *vinfo;
2142
590
    int ret = 0;
2143
2144
    /* Keys with key material are immutable */
2145
590
    if (key == NULL
2146
590
        || ossl_ml_kem_have_pubkey(key)
2147
590
        || ossl_ml_kem_have_dkenc(key))
2148
0
        return 0;
2149
590
    vinfo = key->vinfo;
2150
2151
590
    if (len != vinfo->pubkey_bytes
2152
590
        || (mdctx = EVP_MD_CTX_new()) == NULL)
2153
0
        return 0;
2154
2155
590
    if (add_storage(OPENSSL_malloc(vinfo->puballoc), 0, 0, key))
2156
590
        ret = parse_pubkey(in, mdctx, key);
2157
2158
590
    if (!ret)
2159
241
        ossl_ml_kem_key_reset(key);
2160
590
    EVP_MD_CTX_free(mdctx);
2161
590
    return ret;
2162
590
}
2163
2164
/* Parse input as a new private key */
2165
int ossl_ml_kem_parse_private_key(const uint8_t *in, size_t len,
2166
    ML_KEM_KEY *key)
2167
111
{
2168
111
    EVP_MD_CTX *mdctx = NULL;
2169
111
    const ML_KEM_VINFO *vinfo;
2170
111
    int ret = 0;
2171
2172
    /* Keys with key material are immutable */
2173
111
    if (key == NULL
2174
111
        || ossl_ml_kem_have_pubkey(key)
2175
111
        || ossl_ml_kem_have_dkenc(key))
2176
0
        return 0;
2177
111
    vinfo = key->vinfo;
2178
2179
111
    if (len != vinfo->prvkey_bytes
2180
111
        || (mdctx = EVP_MD_CTX_new()) == NULL)
2181
0
        return 0;
2182
2183
111
    if (add_storage(OPENSSL_malloc(vinfo->prvalloc), 1, 0, key))
2184
111
        ret = parse_prvkey(in, mdctx, key);
2185
2186
111
    if (!ret)
2187
111
        ossl_ml_kem_key_reset(key);
2188
111
    EVP_MD_CTX_free(mdctx);
2189
111
    return ret;
2190
111
}
2191
2192
/*
2193
 * Generate a new keypair, either from the saved seed (when non-null), or from
2194
 * the RNG.
2195
 */
2196
int ossl_ml_kem_genkey(uint8_t *pubenc, size_t publen, ML_KEM_KEY *key)
2197
63.5k
{
2198
63.5k
    uint8_t seed[ML_KEM_SEED_BYTES];
2199
63.5k
    EVP_MD_CTX *mdctx = NULL;
2200
63.5k
    const ML_KEM_VINFO *vinfo;
2201
63.5k
    int ret = 0;
2202
2203
63.5k
    if (key == NULL
2204
63.5k
        || ossl_ml_kem_have_pubkey(key)
2205
63.5k
        || ossl_ml_kem_have_dkenc(key))
2206
0
        return 0;
2207
63.5k
    vinfo = key->vinfo;
2208
2209
63.5k
    if (pubenc != NULL && publen != vinfo->pubkey_bytes)
2210
0
        return 0;
2211
2212
63.5k
    if (ossl_ml_kem_have_seed(key)) {
2213
76
        if (!ossl_ml_kem_encode_seed(seed, sizeof(seed), key))
2214
0
            return 0;
2215
76
        key->d = key->z = NULL;
2216
63.5k
    } else if (RAND_priv_bytes_ex(key->libctx, seed, sizeof(seed),
2217
63.5k
                   key->vinfo->secbits)
2218
63.5k
        <= 0) {
2219
0
        return 0;
2220
0
    }
2221
2222
63.5k
    if ((mdctx = EVP_MD_CTX_new()) == NULL)
2223
0
        return 0;
2224
2225
    /*
2226
     * Data derived from (d, z) defaults secret, and to avoid side-channel
2227
     * leaks should not influence control flow.
2228
     */
2229
63.5k
    CONSTTIME_SECRET(seed, ML_KEM_SEED_BYTES);
2230
2231
63.5k
    if (add_storage(OPENSSL_malloc(vinfo->prvalloc), 1, 0, key))
2232
63.5k
        ret = genkey(seed, mdctx, pubenc, key);
2233
63.5k
    OPENSSL_cleanse(seed, sizeof(seed));
2234
2235
    /* Declassify secret inputs and derived outputs before returning control */
2236
63.5k
    CONSTTIME_DECLASSIFY(seed, ML_KEM_SEED_BYTES);
2237
2238
63.5k
    EVP_MD_CTX_free(mdctx);
2239
63.5k
    if (!ret) {
2240
        /* Erase any partial public key output */
2241
0
        if (pubenc != NULL)
2242
0
            OPENSSL_cleanse(pubenc, vinfo->pubkey_bytes);
2243
0
        ossl_ml_kem_key_reset(key);
2244
0
        return 0;
2245
0
    }
2246
2247
    /* The public components are already declassified */
2248
63.5k
    CONSTTIME_DECLASSIFY(key->s, vinfo->rank * sizeof(scalar));
2249
63.5k
    CONSTTIME_DECLASSIFY(key->z, 2 * ML_KEM_RANDOM_BYTES);
2250
63.5k
    return 1;
2251
63.5k
}
2252
2253
/*
2254
 * FIPS 203, Section 6.2, Algorithm 17: ML-KEM.Encaps_internal
2255
 * This is the deterministic version with randomness supplied externally.
2256
 */
2257
int ossl_ml_kem_encap_seed(uint8_t *ctext, size_t clen,
2258
    uint8_t *shared_secret, size_t slen,
2259
    const uint8_t *entropy, size_t elen,
2260
    const ML_KEM_KEY *key)
2261
213
{
2262
213
    const ML_KEM_VINFO *vinfo;
2263
213
    EVP_MD_CTX *mdctx;
2264
213
    int ret = 0;
2265
2266
213
    if (key == NULL || !ossl_ml_kem_have_pubkey(key))
2267
0
        return 0;
2268
213
    vinfo = key->vinfo;
2269
2270
213
    if (ctext == NULL || clen != vinfo->ctext_bytes
2271
213
        || shared_secret == NULL || slen != ML_KEM_SHARED_SECRET_BYTES
2272
213
        || entropy == NULL || elen != ML_KEM_RANDOM_BYTES
2273
213
        || (mdctx = EVP_MD_CTX_new()) == NULL)
2274
0
        return 0;
2275
    /*
2276
     * Data derived from the encap entropy defaults secret, and to avoid
2277
     * side-channel leaks should not influence control flow.
2278
     */
2279
213
    CONSTTIME_SECRET(entropy, elen);
2280
2281
    /*-
2282
     * This avoids the need to handle allocation failures for two (max 2KB
2283
     * each) vectors, that are never retained on return from this function.
2284
     * We stack-allocate these.
2285
     */
2286
213
#define case_encap_seed(bits)                                        \
2287
213
    case EVP_PKEY_ML_KEM_##bits: {                                   \
2288
213
        scalar tmp[2 * ML_KEM_##bits##_RANK];                        \
2289
213
                                                                     \
2290
213
        ret = encap(ctext, shared_secret, entropy, tmp, mdctx, key); \
2291
213
        OPENSSL_cleanse((void *)tmp, sizeof(tmp));                   \
2292
213
        break;                                                       \
2293
213
    }
2294
213
    switch (vinfo->evp_type) {
2295
62
        case_encap_seed(512);
2296
93
        case_encap_seed(768);
2297
58
        case_encap_seed(1024);
2298
213
    }
2299
213
#undef case_encap_seed
2300
2301
    /* Erase any partial ciphertext output on failure */
2302
213
    if (!ret)
2303
0
        OPENSSL_cleanse(ctext, clen);
2304
2305
    /* Declassify secret inputs and derived outputs before returning control */
2306
213
    CONSTTIME_DECLASSIFY(entropy, elen);
2307
213
    CONSTTIME_DECLASSIFY(ctext, clen);
2308
213
    CONSTTIME_DECLASSIFY(shared_secret, slen);
2309
2310
213
    EVP_MD_CTX_free(mdctx);
2311
213
    return ret;
2312
213
}
2313
2314
int ossl_ml_kem_encap_rand(uint8_t *ctext, size_t clen,
2315
    uint8_t *shared_secret, size_t slen,
2316
    const ML_KEM_KEY *key)
2317
213
{
2318
213
    uint8_t r[ML_KEM_RANDOM_BYTES];
2319
213
    int ret;
2320
2321
213
    if (key == NULL)
2322
0
        return 0;
2323
2324
213
    if (RAND_bytes_ex(key->libctx, r, ML_KEM_RANDOM_BYTES,
2325
213
            key->vinfo->secbits)
2326
213
        < 1)
2327
0
        return 0;
2328
2329
213
    ret = ossl_ml_kem_encap_seed(ctext, clen, shared_secret, slen,
2330
213
        r, sizeof(r), key);
2331
2332
213
    OPENSSL_cleanse((void *)r, sizeof(r));
2333
213
    return ret;
2334
213
}
2335
2336
int ossl_ml_kem_decap(uint8_t *shared_secret, size_t slen,
2337
    const uint8_t *ctext, size_t clen,
2338
    const ML_KEM_KEY *key)
2339
189
{
2340
189
    const ML_KEM_VINFO *vinfo;
2341
189
    EVP_MD_CTX *mdctx;
2342
189
    int ret = 0;
2343
#if defined(OPENSSL_CONSTANT_TIME_VALIDATION)
2344
    int classify_bytes;
2345
#endif
2346
2347
    /* Need a private key here */
2348
189
    if (!ossl_ml_kem_have_prvkey(key)
2349
189
        || shared_secret == NULL
2350
189
        || slen < ML_KEM_SHARED_SECRET_BYTES)
2351
0
        return 0;
2352
189
    vinfo = key->vinfo;
2353
2354
189
    if (slen != ML_KEM_SHARED_SECRET_BYTES
2355
189
        || ctext == NULL || clen != vinfo->ctext_bytes
2356
189
        || (mdctx = EVP_MD_CTX_new()) == NULL) {
2357
0
        (void)RAND_bytes_ex(key->libctx, shared_secret,
2358
0
            ML_KEM_SHARED_SECRET_BYTES, vinfo->secbits);
2359
0
        return 0;
2360
0
    }
2361
#if defined(OPENSSL_CONSTANT_TIME_VALIDATION)
2362
    /*
2363
     * Data derived from |s| and |z| defaults secret, and to avoid side-channel
2364
     * leaks should not influence control flow.
2365
     */
2366
    classify_bytes = 2 * sizeof(scalar) + ML_KEM_RANDOM_BYTES;
2367
    CONSTTIME_SECRET(key->s, classify_bytes);
2368
#endif
2369
2370
    /*-
2371
     * This avoids the need to handle allocation failures for two (max 2KB
2372
     * each) vectors and an encoded ciphertext (max 1568 bytes), that are never
2373
     * retained on return from this function.
2374
     * We stack-allocate these.
2375
     */
2376
189
#define case_decap(bits)                                          \
2377
189
    case EVP_PKEY_ML_KEM_##bits: {                                \
2378
189
        uint8_t cbuf[CTEXT_BYTES(bits)];                          \
2379
189
        scalar tmp[2 * ML_KEM_##bits##_RANK];                     \
2380
189
                                                                  \
2381
189
        ret = decap(shared_secret, ctext, cbuf, tmp, mdctx, key); \
2382
189
        OPENSSL_cleanse((void *)tmp, sizeof(tmp));                \
2383
189
        OPENSSL_cleanse((void *)cbuf, sizeof(cbuf));              \
2384
189
        break;                                                    \
2385
189
    }
2386
189
    switch (vinfo->evp_type) {
2387
62
        case_decap(512);
2388
69
        case_decap(768);
2389
58
        case_decap(1024);
2390
189
    }
2391
2392
    /* Declassify secret inputs and derived outputs before returning control */
2393
189
    CONSTTIME_DECLASSIFY(key->s, classify_bytes);
2394
189
    CONSTTIME_DECLASSIFY(shared_secret, slen);
2395
189
    EVP_MD_CTX_free(mdctx);
2396
2397
189
    return ret;
2398
189
#undef case_decap
2399
189
}
2400
2401
int ossl_ml_kem_pubkey_cmp(const ML_KEM_KEY *key1, const ML_KEM_KEY *key2)
2402
150
{
2403
    /*
2404
     * This handles any unexpected differences in the ML-KEM variant rank,
2405
     * giving different key component structures, barring SHA3-256 hash
2406
     * collisions, the keys are the same size.
2407
     */
2408
150
    if (ossl_ml_kem_have_pubkey(key1) && ossl_ml_kem_have_pubkey(key2))
2409
150
        return memcmp(key1->pkhash, key2->pkhash, ML_KEM_PKHASH_BYTES) == 0;
2410
2411
    /*
2412
     * No match if just one of the public keys is not available, otherwise both
2413
     * are unavailable, and for now such keys are considered equal.
2414
     */
2415
0
    return (!(ossl_ml_kem_have_pubkey(key1) ^ ossl_ml_kem_have_pubkey(key2)));
2416
150
}