Skip to content

Commit 09a134e

Browse files
authored
Merge pull request #369 from pq-code-package/mldsa-zeroize
Destruct intermediate buffers on the stack
2 parents 616ca6d + 76ea290 commit 09a134e

File tree

21 files changed

+278
-28
lines changed

21 files changed

+278
-28
lines changed

mldsa/common.h

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#ifndef MLD_COMMON_H
77
#define MLD_COMMON_H
88

9+
#include "cbmc.h"
910
#include "params.h"
1011
#include "sys.h"
1112

@@ -51,4 +52,54 @@
5152
#if defined(MLD_CONFIG_USE_NATIVE_BACKEND_FIPS202)
5253
#include MLD_CONFIG_FIPS202_BACKEND_FILE
5354
#endif
55+
56+
#if !defined(__ASSEMBLER__)
57+
#include <string.h>
58+
59+
/*************************************************
60+
* Name: mld_zeroize
61+
*
62+
* Description: Force-zeroize a buffer.
63+
* FIPS 204. Section 3.6.3 Destruction of intermediate values.
64+
*
65+
* Arguments: void *ptr: pointer to buffer to be zeroed
66+
* size_t len: Amount of bytes to be zeroed
67+
**************************************************/
68+
static MLD_INLINE void mld_zeroize(void *ptr, size_t len)
69+
__contract__(
70+
requires(memory_no_alias(ptr, len))
71+
assigns(memory_slice(ptr, len))
72+
);
73+
74+
#if defined(MLD_CONFIG_CUSTOM_ZEROIZE)
75+
static MLD_INLINE void mld_zeroize(void *ptr, size_t len)
76+
{
77+
mld_zeroize_native(ptr, len);
78+
}
79+
#elif defined(MLD_SYS_WINDOWS)
80+
#include <windows.h>
81+
static MLD_INLINE void mld_zeroize(void *ptr, size_t len)
82+
{
83+
SecureZeroMemory(ptr, len);
84+
}
85+
#elif defined(MLD_HAVE_INLINE_ASM)
86+
static MLD_INLINE void mld_zeroize(void *ptr, size_t len)
87+
{
88+
memset(ptr, 0, len);
89+
/* This follows OpenSSL and seems sufficient to prevent the compiler
90+
* from optimizing away the memset.
91+
*
92+
* If there was a reliable way to detect availability of memset_s(),
93+
* that would be preferred. */
94+
__asm__ __volatile__("" : : "r"(ptr) : "memory");
95+
}
96+
#else /* !MLD_CONFIG_CUSTOM_ZEROIZE && !MLD_SYS_WINDOWS && MLD_HAVE_INLINE_ASM \
97+
*/
98+
#error No plausibly-secure implementation of mld_zeroize available. Please provide your own using MLD_CONFIG_CUSTOM_ZEROIZE.
99+
#endif /* !MLD_CONFIG_CUSTOM_ZEROIZE && !MLD_SYS_WINDOWS && \
100+
!MLD_HAVE_INLINE_ASM */
101+
102+
#endif /* !__ASSEMBLER__ */
103+
104+
54105
#endif /* !MLD_COMMON_H */

mldsa/config.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,46 @@
5959
#define MLD_CONFIG_FIPS202_BACKEND_FILE "fips202/native/auto.h"
6060
#endif
6161

62+
/******************************************************************************
63+
* Name: MLD_CONFIG_CUSTOM_ZEROIZE
64+
*
65+
* Description: In compliance with FIPS 204 Section 3.6.3, mldsa-native zeroizes
66+
* intermediate stack buffers before returning from function calls.
67+
*
68+
* Set this option and define `mld_zeroize_native` if you want to
69+
* use a custom method to zeroize intermediate stack buffers.
70+
* The default implementation uses SecureZeroMemory on Windows
71+
* and a memset + compiler barrier otherwise. If neither of those
72+
* is available on the target platform, compilation will fail,
73+
* and you will need to use MLD_CONFIG_CUSTOM_ZEROIZE to provide
74+
* a custom implementation of `mld_zeroize_native()`.
75+
*
76+
* WARNING:
77+
* The explicit stack zeroization conducted by mldsa-native
78+
* reduces the likelihood of data leaking on the stack, but
79+
* does not eliminate it! The C standard makes no guarantee about
80+
* where a compiler allocates structures and whether/where it makes
81+
* copies of them. Also, in addition to entire structures, there
82+
* may also be potentially exploitable leakage of individual values
83+
* on the stack.
84+
*
85+
* If you need bullet-proof zeroization of the stack, you need to
86+
* consider additional measures instead of what this feature
87+
* provides. In this case, you can set mld_zeroize_native to a
88+
* no-op.
89+
*
90+
*****************************************************************************/
91+
/* #define MLD_CONFIG_CUSTOM_ZEROIZE
92+
#if !defined(__ASSEMBLER__)
93+
#include <stdint.h>
94+
#include "sys.h"
95+
static MLD_INLINE void mld_zeroize_native(void *ptr, size_t len)
96+
{
97+
... your implementation ...
98+
}
99+
#endif
100+
*/
101+
62102
/******************************************************************************
63103
* Name: MLD_CONFIG_KEYGEN_PCT
64104
*

mldsa/fips202/fips202.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -437,8 +437,8 @@ void shake128_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state)
437437

438438
void shake128_release(keccak_state *state)
439439
{
440-
(void)state;
441-
/* TODO: add secure zeroization*/
440+
/* FIPS 204. Section 3.6.3 Destruction of intermediate values. */
441+
mld_zeroize(state, sizeof(keccak_state));
442442
}
443443

444444
/*************************************************
@@ -535,8 +535,8 @@ void shake256_squeezeblocks(uint8_t *out, size_t nblocks, keccak_state *state)
535535

536536
void shake256_release(keccak_state *state)
537537
{
538-
(void)state;
539-
/* TODO: add secure zeroization*/
538+
/* FIPS 204. Section 3.6.3 Destruction of intermediate values. */
539+
mld_zeroize(state, sizeof(keccak_state));
540540
}
541541

542542
/*************************************************
@@ -560,6 +560,9 @@ void shake128(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen)
560560
outlen -= nblocks * SHAKE128_RATE;
561561
out += nblocks * SHAKE128_RATE;
562562
shake128_squeeze(out, outlen, &state);
563+
564+
/* FIPS 204. Section 3.6.3 Destruction of intermediate values. */
565+
mld_zeroize(&state, sizeof(state));
563566
}
564567

565568
/*************************************************
@@ -583,6 +586,9 @@ void shake256(uint8_t *out, size_t outlen, const uint8_t *in, size_t inlen)
583586
outlen -= nblocks * SHAKE256_RATE;
584587
out += nblocks * SHAKE256_RATE;
585588
shake256_squeeze(out, outlen, &state);
589+
590+
/* FIPS 204. Section 3.6.3 Destruction of intermediate values. */
591+
mld_zeroize(&state, sizeof(state));
586592
}
587593

588594
/*************************************************
@@ -606,6 +612,9 @@ void sha3_256(uint8_t h[SHA3_256_HASHBYTES], const uint8_t *in, size_t inlen)
606612
{
607613
store64(h + 8 * i, s[i]);
608614
}
615+
616+
/* FIPS 204. Section 3.6.3 Destruction of intermediate values. */
617+
mld_zeroize(s, sizeof(s));
609618
}
610619

611620
/*************************************************
@@ -629,4 +638,7 @@ void sha3_512(uint8_t h[SHA3_512_HASHBYTES], const uint8_t *in, size_t inlen)
629638
{
630639
store64(h + 8 * i, s[i]);
631640
}
641+
642+
/* FIPS 204. Section 3.6.3 Destruction of intermediate values. */
643+
mld_zeroize(s, sizeof(s));
632644
}

mldsa/fips202/fips202x4.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,8 @@ void mld_shake128x4_squeezeblocks(uint8_t *out0, uint8_t *out1, uint8_t *out2,
123123
void mld_shake128x4_init(mld_shake128x4ctx *state) { (void)state; }
124124
void mld_shake128x4_release(mld_shake128x4ctx *state)
125125
{
126-
/* Specification: Partially implements
127-
* @[FIPS203, Section 3.3, Destruction of intermediate values] */
128-
(void)state;
129-
/*mld_zeroize(state, sizeof(mld_shake128x4ctx));*/
126+
/* FIPS 204. Section 3.6.3 Destruction of intermediate values. */
127+
mld_zeroize(state, sizeof(mld_shake128x4ctx));
130128
}
131129

132130

@@ -150,8 +148,6 @@ void mld_shake256x4_squeezeblocks(uint8_t *out0, uint8_t *out1, uint8_t *out2,
150148
void mld_shake256x4_init(mld_shake256x4ctx *state) { (void)state; }
151149
void mld_shake256x4_release(mld_shake256x4ctx *state)
152150
{
153-
/* Specification: Partially implements
154-
* @[FIPS203, Section 3.3, Destruction of intermediate values] */
155-
(void)state;
156-
/*mld_zeroize(state, sizeof(mld_shake256x4ctx));*/
151+
/* FIPS 204. Section 3.6.3 Destruction of intermediate values. */
152+
mld_zeroize(state, sizeof(mld_shake256x4ctx));
157153
}

mldsa/poly.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,9 @@ void mld_poly_uniform(mld_poly *a, const uint8_t seed[MLDSA_SEEDBYTES + 2])
376376
ctr = mld_rej_uniform(a->coeffs, MLDSA_N, ctr, buf, buflen);
377377
}
378378
mld_xof128_release(&state);
379+
380+
/* FIPS 204. Section 3.6.3 Destruction of intermediate values. */
381+
mld_zeroize(buf, sizeof(buf));
379382
}
380383

381384
void mld_poly_uniform_4x(mld_poly *vec0, mld_poly *vec1, mld_poly *vec2,
@@ -431,6 +434,9 @@ void mld_poly_uniform_4x(mld_poly *vec0, mld_poly *vec1, mld_poly *vec2,
431434
ctr[3] = mld_rej_uniform(vec3->coeffs, MLDSA_N, ctr[3], buf[3], buflen);
432435
}
433436
mld_xof128_x4_release(&state);
437+
438+
/* FIPS 204. Section 3.6.3 Destruction of intermediate values. */
439+
mld_zeroize(buf, sizeof(buf));
434440
}
435441

436442
/*************************************************
@@ -628,6 +634,10 @@ void mld_poly_uniform_eta_4x(mld_poly *r0, mld_poly *r1, mld_poly *r2,
628634
}
629635

630636
mld_xof256_x4_release(&state);
637+
638+
/* FIPS 204. Section 3.6.3 Destruction of intermediate values. */
639+
mld_zeroize(buf, sizeof(buf));
640+
mld_zeroize(extseed, sizeof(extseed));
631641
}
632642

633643

@@ -651,6 +661,10 @@ void mld_poly_uniform_gamma1(mld_poly *a, const uint8_t seed[MLDSA_CRHBYTES],
651661
mld_polyz_unpack(a, buf);
652662

653663
mld_xof256_release(&state);
664+
665+
/* FIPS 204. Section 3.6.3 Destruction of intermediate values. */
666+
mld_zeroize(buf, sizeof(buf));
667+
mld_zeroize(extseed, sizeof(extseed));
654668
}
655669

656670
void mld_poly_uniform_gamma1_4x(mld_poly *r0, mld_poly *r1, mld_poly *r2,
@@ -690,6 +704,10 @@ void mld_poly_uniform_gamma1_4x(mld_poly *r0, mld_poly *r1, mld_poly *r2,
690704
mld_polyz_unpack(r2, buf[2]);
691705
mld_polyz_unpack(r3, buf[3]);
692706
mld_xof256_x4_release(&state);
707+
708+
/* FIPS 204. Section 3.6.3 Destruction of intermediate values. */
709+
mld_zeroize(buf, sizeof(buf));
710+
mld_zeroize(extseed, sizeof(extseed));
693711
}
694712

695713

@@ -764,6 +782,10 @@ void mld_poly_challenge(mld_poly *c, const uint8_t seed[MLDSA_CTILDEBYTES])
764782
signs >>= 1;
765783
}
766784

785+
/* FIPS 204. Section 3.6.3 Destruction of intermediate values. */
786+
mld_zeroize(buf, sizeof(buf));
787+
mld_zeroize(&signs, sizeof(signs));
788+
767789
mld_assert_bound(c->coeffs, MLDSA_N, -1, 2);
768790
}
769791

mldsa/polyvec.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,9 @@ void mld_polyvec_matrix_expand(mld_polyvecl mat[MLDSA_K],
110110
mld_poly_permute_bitrev_to_custom(mat[i].vec[j].coeffs);
111111
}
112112
}
113+
114+
/* FIPS 204. Section 3.6.3 Destruction of intermediate values. */
115+
mld_zeroize(seed_ext, sizeof(seed_ext));
113116
}
114117

115118
void mld_polyvec_matrix_pointwise_montgomery(mld_polyveck *t,

0 commit comments

Comments
 (0)