Skip to content

Commit 535e75e

Browse files
committed
API: add failure mode support for randombytes()
Change randombytes() to return int (0 on success, non-zero on failure) instead of void, allowing callers to detect and handle RNG failures. Updated function signature, all call sites to check return values and test files to use CHECK macro. Signed-off-by: Andreas Hatziiliou <[email protected]>
1 parent 9bad988 commit 535e75e

File tree

7 files changed

+73
-48
lines changed

7 files changed

+73
-48
lines changed

mldsa/src/randombytes.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313

1414
#if !defined(MLD_CONFIG_NO_RANDOMIZED_API)
1515
#if !defined(MLD_CONFIG_CUSTOM_RANDOMBYTES)
16-
void randombytes(uint8_t *out, size_t outlen);
17-
static MLD_INLINE void mld_randombytes(uint8_t *out, size_t outlen)
16+
int randombytes(uint8_t *out, size_t outlen);
17+
static MLD_INLINE int mld_randombytes(uint8_t *out, size_t outlen)
1818
__contract__(
1919
requires(memory_no_alias(out, outlen))
2020
assigns(memory_slice(out, outlen))
21-
) { randombytes(out, outlen); }
21+
) { return randombytes(out, outlen); }
2222
#endif /* !MLD_CONFIG_CUSTOM_RANDOMBYTES */
2323
#endif /* !MLD_CONFIG_NO_RANDOMIZED_API */
2424
#endif /* !MLD_RANDOMBYTES_H */

mldsa/src/sign.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,10 @@ int crypto_sign_keypair(uint8_t pk[CRYPTO_PUBLICKEYBYTES],
265265
{
266266
MLD_ALIGN uint8_t seed[MLDSA_SEEDBYTES];
267267
int result;
268-
mld_randombytes(seed, MLDSA_SEEDBYTES);
268+
if (mld_randombytes(seed, MLDSA_SEEDBYTES) != 0)
269+
{
270+
return -1;
271+
}
269272
MLD_CT_TESTING_SECRET(seed, sizeof(seed));
270273
result = crypto_sign_keypair_internal(pk, sk, seed);
271274

@@ -657,7 +660,11 @@ int crypto_sign_signature(uint8_t sig[CRYPTO_BYTES], size_t *siglen,
657660

658661
/* Randomized variant of ML-DSA. If you need the deterministic variant,
659662
* call crypto_sign_signature_internal directly with all-zero rnd. */
660-
mld_randombytes(rnd, MLDSA_RNDBYTES);
663+
if (mld_randombytes(rnd, MLDSA_RNDBYTES) != 0)
664+
{
665+
*siglen = 0;
666+
return -1;
667+
}
661668
MLD_CT_TESTING_SECRET(rnd, sizeof(rnd));
662669

663670
result = crypto_sign_signature_internal(sig, siglen, m, mlen, pre, 2 + ctxlen,
@@ -684,7 +691,11 @@ int crypto_sign_signature_extmu(uint8_t sig[CRYPTO_BYTES], size_t *siglen,
684691

685692
/* Randomized variant of ML-DSA. If you need the deterministic variant,
686693
* call crypto_sign_signature_internal directly with all-zero rnd. */
687-
mld_randombytes(rnd, MLDSA_RNDBYTES);
694+
if (mld_randombytes(rnd, MLDSA_RNDBYTES) != 0)
695+
{
696+
*siglen = 0;
697+
return -1;
698+
}
688699
MLD_CT_TESTING_SECRET(rnd, sizeof(rnd));
689700

690701
result = crypto_sign_signature_internal(sig, siglen, mu, MLDSA_CRHBYTES, NULL,

test/bench_components_mldsa.c

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,32 +18,45 @@
1818
#define NITERATIONS 300
1919
#define NTESTS 20
2020

21+
#define CHECK(x) \
22+
do \
23+
{ \
24+
int rc; \
25+
rc = (x); \
26+
if (!rc) \
27+
{ \
28+
fprintf(stderr, "ERROR (%s,%d)\n", __FILE__, __LINE__); \
29+
return 1; \
30+
} \
31+
} while (0)
32+
2133
static int cmp_uint64_t(const void *a, const void *b)
2234
{
2335
return (int)((*((const uint64_t *)a)) - (*((const uint64_t *)b)));
2436
}
2537

26-
#define BENCH(txt, code) \
27-
for (i = 0; i < NTESTS; i++) \
28-
{ \
29-
mld_randombytes((uint8_t *)data0, sizeof(data0)); \
30-
mld_randombytes((uint8_t *)&polyvecl_a, sizeof(polyvecl_a)); \
31-
mld_randombytes((uint8_t *)&polyvecl_b, sizeof(polyvecl_b)); \
32-
mld_randombytes((uint8_t *)polyvecl_mat, sizeof(polyvecl_mat)); \
33-
for (j = 0; j < NWARMUP; j++) \
34-
{ \
35-
code; \
36-
} \
37-
\
38-
t0 = get_cyclecounter(); \
39-
for (j = 0; j < NITERATIONS; j++) \
40-
{ \
41-
code; \
42-
} \
43-
t1 = get_cyclecounter(); \
44-
(cyc)[i] = t1 - t0; \
45-
} \
46-
qsort((cyc), NTESTS, sizeof(uint64_t), cmp_uint64_t); \
38+
#define BENCH(txt, code) \
39+
for (i = 0; i < NTESTS; i++) \
40+
{ \
41+
CHECK(mld_randombytes((uint8_t *)data0, sizeof(data0)) == 0); \
42+
CHECK(mld_randombytes((uint8_t *)&polyvecl_a, sizeof(polyvecl_a)) == 0); \
43+
CHECK(mld_randombytes((uint8_t *)&polyvecl_b, sizeof(polyvecl_b)) == 0); \
44+
CHECK(mld_randombytes((uint8_t *)polyvecl_mat, sizeof(polyvecl_mat)) == \
45+
0); \
46+
for (j = 0; j < NWARMUP; j++) \
47+
{ \
48+
code; \
49+
} \
50+
\
51+
t0 = get_cyclecounter(); \
52+
for (j = 0; j < NITERATIONS; j++) \
53+
{ \
54+
code; \
55+
} \
56+
t1 = get_cyclecounter(); \
57+
(cyc)[i] = t1 - t0; \
58+
} \
59+
qsort((cyc), NTESTS, sizeof(uint64_t), cmp_uint64_t); \
4760
printf(txt " cycles=%" PRIu64 "\n", (cyc)[NTESTS >> 1] / NITERATIONS);
4861

4962
static int bench(void)

test/bench_mldsa.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ static int bench(void)
9191
for (i = 0; i < NTESTS; i++)
9292
{
9393
int ret = 0;
94-
mld_randombytes(kg_rand, sizeof(kg_rand));
95-
mld_randombytes(sig_rand, sizeof(sig_rand));
94+
CHECK(mld_randombytes(kg_rand, sizeof(kg_rand)) == 0);
95+
CHECK(mld_randombytes(sig_rand, sizeof(sig_rand)) == 0);
9696

9797

9898
/* Key-pair generation */
@@ -111,8 +111,8 @@ static int bench(void)
111111

112112

113113
/* Signing */
114-
mld_randombytes(ctx, CTXLEN);
115-
mld_randombytes(m, MLEN);
114+
CHECK(mld_randombytes(ctx, CTXLEN) == 0);
115+
CHECK(mld_randombytes(m, MLEN) == 0);
116116

117117
pre[0] = 0;
118118
pre[1] = CTXLEN;

test/notrandombytes/notrandombytes.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ static void surf(void)
9090
}
9191
}
9292

93-
void randombytes(uint8_t *buf, size_t n)
93+
int randombytes(uint8_t *buf, size_t n)
9494
{
9595
#ifdef ENABLE_CT_TESTING
9696
uint8_t *buf_orig = buf;
@@ -126,4 +126,5 @@ void randombytes(uint8_t *buf, size_t n)
126126
*/
127127
VALGRIND_MAKE_MEM_UNDEFINED(buf_orig, n_orig);
128128
#endif /* ENABLE_CT_TESTING */
129+
return 0;
129130
}

test/notrandombytes/notrandombytes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@
2929
*/
3030

3131
void randombytes_reset(void);
32-
void randombytes(uint8_t *buf, size_t n);
32+
int randombytes(uint8_t *buf, size_t n);
3333

3434
#endif /* !NOTRANDOMBYTES_H */

test/test_mldsa.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ static int test_sign_core(uint8_t pk[CRYPTO_PUBLICKEYBYTES],
4040

4141

4242
CHECK(crypto_sign_keypair(pk, sk) == 0);
43-
randombytes(ctx, CTXLEN);
43+
CHECK(randombytes(ctx, CTXLEN) == 0);
4444
MLD_CT_TESTING_SECRET(ctx, CTXLEN);
45-
randombytes(m, MLEN);
45+
CHECK(randombytes(m, MLEN) == 0);
4646
MLD_CT_TESTING_SECRET(m, MLEN);
4747

4848
CHECK(crypto_sign(sm, &smlen, m, MLEN, ctx, CTXLEN, sk) == 0);
@@ -114,7 +114,7 @@ static int test_sign_extmu(void)
114114
size_t siglen;
115115

116116
CHECK(crypto_sign_keypair(pk, sk) == 0);
117-
randombytes(mu, MLDSA_CRHBYTES);
117+
CHECK(randombytes(mu, MLDSA_CRHBYTES) == 0);
118118
MLD_CT_TESTING_SECRET(mu, sizeof(mu));
119119

120120
CHECK(crypto_sign_signature_extmu(sig, &siglen, mu, sk) == 0);
@@ -136,11 +136,11 @@ static int test_sign_pre_hash(void)
136136

137137

138138
CHECK(crypto_sign_keypair(pk, sk) == 0);
139-
randombytes(ctx, CTXLEN);
139+
CHECK(randombytes(ctx, CTXLEN) == 0);
140140
MLD_CT_TESTING_SECRET(ctx, sizeof(ctx));
141-
randombytes(m, MLEN);
141+
CHECK(randombytes(m, MLEN) == 0);
142142
MLD_CT_TESTING_SECRET(m, sizeof(m));
143-
randombytes(rnd, MLDSA_RNDBYTES);
143+
CHECK(randombytes(rnd, MLDSA_RNDBYTES) == 0);
144144
MLD_CT_TESTING_SECRET(rnd, sizeof(rnd));
145145

146146
CHECK(crypto_sign_signature_pre_hash_shake256(sig, &siglen, m, MLEN, ctx,
@@ -166,15 +166,15 @@ static int test_wrong_pk(void)
166166
size_t i;
167167

168168
CHECK(crypto_sign_keypair(pk, sk) == 0);
169-
randombytes(ctx, CTXLEN);
169+
CHECK(randombytes(ctx, CTXLEN) == 0);
170170
MLD_CT_TESTING_SECRET(ctx, sizeof(ctx));
171-
randombytes(m, MLEN);
171+
CHECK(randombytes(m, MLEN) == 0);
172172
MLD_CT_TESTING_SECRET(m, sizeof(m));
173173

174174
CHECK(crypto_sign(sm, &smlen, m, MLEN, ctx, CTXLEN, sk) == 0);
175175

176176
/* flip bit in public key */
177-
randombytes((uint8_t *)&idx, sizeof(size_t));
177+
CHECK(randombytes((uint8_t *)&idx, sizeof(size_t)) == 0);
178178
idx %= CRYPTO_PUBLICKEYBYTES;
179179

180180
pk[idx] ^= 1;
@@ -217,15 +217,15 @@ static int test_wrong_sig(void)
217217
size_t i;
218218

219219
CHECK(crypto_sign_keypair(pk, sk) == 0);
220-
randombytes(ctx, CTXLEN);
220+
CHECK(randombytes(ctx, CTXLEN) == 0);
221221
MLD_CT_TESTING_SECRET(ctx, sizeof(ctx));
222-
randombytes(m, MLEN);
222+
CHECK(randombytes(m, MLEN) == 0);
223223
MLD_CT_TESTING_SECRET(m, sizeof(m));
224224

225225
CHECK(crypto_sign(sm, &smlen, m, MLEN, ctx, CTXLEN, sk) == 0);
226226

227227
/* flip bit in signed message */
228-
randombytes((uint8_t *)&idx, sizeof(size_t));
228+
CHECK(randombytes((uint8_t *)&idx, sizeof(size_t)) == 0);
229229
idx %= MLEN + CRYPTO_BYTES;
230230

231231
sm[idx] ^= 1;
@@ -269,15 +269,15 @@ static int test_wrong_ctx(void)
269269
size_t i;
270270

271271
CHECK(crypto_sign_keypair(pk, sk) == 0);
272-
randombytes(ctx, CTXLEN);
272+
CHECK(randombytes(ctx, CTXLEN) == 0);
273273
MLD_CT_TESTING_SECRET(ctx, sizeof(ctx));
274-
randombytes(m, MLEN);
274+
CHECK(randombytes(m, MLEN) == 0);
275275
MLD_CT_TESTING_SECRET(m, sizeof(m));
276276

277277
CHECK(crypto_sign(sm, &smlen, m, MLEN, ctx, CTXLEN, sk) == 0);
278278

279279
/* flip bit in ctx */
280-
randombytes((uint8_t *)&idx, sizeof(size_t));
280+
CHECK(randombytes((uint8_t *)&idx, sizeof(size_t)) == 0);
281281
idx %= CTXLEN;
282282

283283
ctx[idx] ^= 1;

0 commit comments

Comments
 (0)