Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions wolfcrypt/src/wc_mldsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -3628,6 +3628,8 @@ static int mldsa_rej_bound_poly(wc_Shake* shake256, byte* seed, sword32* s,
while (j < MLDSA_N);
}

/* z holds the secret s1/s2 bytes. */
ForceZero(z, sizeof(z));
return ret;
#else
int ret;
Expand Down Expand Up @@ -3656,6 +3658,8 @@ static int mldsa_rej_bound_poly(wc_Shake* shake256, byte* seed, sword32* s,
}
}

/* z holds the secret s1/s2 bytes. */
ForceZero(z, MLDSA_GEN_S_BYTES);
WC_FREE_VAR_EX(z, NULL, DYNAMIC_TYPE_MLDSA);
return ret;
#endif
Expand Down Expand Up @@ -3760,6 +3764,9 @@ static int wc_mldsa_gen_s_4_4_avx2(sword32* s[2], byte* seed)
(ctr3 < MLDSA_N));
}

/* rand/state hold secret s-vector material. */
ForceZero(rand, 4 * MLDSA_GEN_S_BLOCK_BYTES);
ForceZero(state, sizeof(word64) * 25 * 4);
WC_FREE_VAR_EX(rand, NULL, DYNAMIC_TYPE_TMP_BUFFER);
WC_FREE_VAR_EX(state, NULL, DYNAMIC_TYPE_TMP_BUFFER);

Expand Down Expand Up @@ -3913,6 +3920,9 @@ static int wc_mldsa_gen_s_5_6_avx2(sword32* s[2], byte* seed)
/* Create more blocks if too many rejected. */
while ((ctr0 < MLDSA_N) || (ctr1 < MLDSA_N) || (ctr2 < MLDSA_N));

/* rand/state hold secret s-vector material. */
ForceZero(rand, 4 * MLDSA_GEN_S_BLOCK_BYTES);
ForceZero(state, sizeof(word64) * 25 * 4);
WC_FREE_VAR_EX(rand, NULL, DYNAMIC_TYPE_TMP_BUFFER);
WC_FREE_VAR_EX(state, NULL, DYNAMIC_TYPE_TMP_BUFFER);

Expand Down Expand Up @@ -4068,6 +4078,9 @@ static int wc_mldsa_gen_s_7_8_avx2(sword32* s[2], byte* seed)
/* Create more blocks if too many rejected. */
while ((ctr0 < MLDSA_N) || (ctr1 < MLDSA_N) || (ctr2 < MLDSA_N));

/* rand/state hold secret s-vector material. */
ForceZero(rand, 4 * MLDSA_GEN_S_BLOCK_BYTES);
ForceZero(state, sizeof(word64) * 25 * 4);
WC_FREE_VAR_EX(rand, NULL, DYNAMIC_TYPE_TMP_BUFFER);
WC_FREE_VAR_EX(state, NULL, DYNAMIC_TYPE_TMP_BUFFER);

Expand Down Expand Up @@ -4257,6 +4270,9 @@ static int wc_mldsa_gen_y_4_avx2(sword32* y, byte* seed, word16 kappa)
wc_mldsa_decode_gamma1_17_avx2(rand + 3 * MLDSA_MAX_V,
y + 3 * MLDSA_N);

/* rand/state hold the secret mask y. */
ForceZero(rand, 4 * MLDSA_MAX_V);
ForceZero(state, sizeof(word64) * 25 * 4);
WC_FREE_VAR_EX(rand, NULL, DYNAMIC_TYPE_TMP_BUFFER);
WC_FREE_VAR_EX(state, NULL, DYNAMIC_TYPE_TMP_BUFFER);

Expand Down Expand Up @@ -4337,6 +4353,9 @@ static int wc_mldsa_gen_y_5_avx2(sword32* y, byte* seed, word16 kappa,
wc_mldsa_decode_gamma1_19_avx2(rand, y + 4 * MLDSA_N);
}

/* rand/state hold the secret mask y. */
ForceZero(rand, 4 * MLDSA_MAX_V);
ForceZero(state, sizeof(word64) * 25 * 4);
WC_FREE_VAR_EX(rand, NULL, DYNAMIC_TYPE_TMP_BUFFER);
WC_FREE_VAR_EX(state, NULL, DYNAMIC_TYPE_TMP_BUFFER);

Expand Down Expand Up @@ -4432,6 +4451,9 @@ static int wc_mldsa_gen_y_7_avx2(sword32* y, byte* seed, word16 kappa)
wc_mldsa_decode_gamma1_19_avx2(rand + 2 * MLDSA_MAX_V,
y + 6 * MLDSA_N);

/* rand/state hold the secret mask y. */
ForceZero(rand, 4 * MLDSA_MAX_V);
ForceZero(state, sizeof(word64) * 25 * 4);
WC_FREE_VAR_EX(rand, NULL, DYNAMIC_TYPE_TMP_BUFFER);
WC_FREE_VAR_EX(state, NULL, DYNAMIC_TYPE_TMP_BUFFER);

Expand Down Expand Up @@ -4490,6 +4512,8 @@ static int mldsa_vec_expand_mask_c(wc_Shake* shake256, byte* seed,
}
}

/* v holds the secret mask y. */
ForceZero(v, MLDSA_MAX_V);
WC_FREE_VAR_EX(v, NULL, DYNAMIC_TYPE_MLDSA);
return ret;
}
Expand Down Expand Up @@ -10934,6 +10958,9 @@ int wc_MlDsaKey_InitLabel(wc_MlDsaKey* key, const char* label, void* heap,
int wc_MlDsaKey_SetParams(wc_MlDsaKey* key, byte level)
{
int ret = 0;
#if !defined(WC_MLDSA_FIXED_ARRAY) && defined(WC_MLDSA_CACHE_PRIV_VECTORS)
const wc_MlDsaParams* oldParams = NULL;
#endif

/* Validate parameters. */
if (key == NULL) {
Expand All @@ -10954,6 +10981,11 @@ int wc_MlDsaKey_SetParams(wc_MlDsaKey* key, byte level)
}

if (ret == 0) {
#if !defined(WC_MLDSA_FIXED_ARRAY) && defined(WC_MLDSA_CACHE_PRIV_VECTORS)
/* Save old params to size the cached-vector wipe below (key->params
* is about to change to the new level). */
oldParams = key->params;
#endif
/* Get the parameters for level into key. */
ret = mldsa_get_params(level, &key->params);
}
Expand All @@ -10966,6 +10998,11 @@ int wc_MlDsaKey_SetParams(wc_MlDsaKey* key, byte level)
key->aSet = 0;
#endif
#ifdef WC_MLDSA_CACHE_PRIV_VECTORS
/* Cached buffer holds secret s1/s2/t0; zeroize before free. */
if ((key->s1 != NULL) && (oldParams != NULL)) {
ForceZero(key->s1, (word32)oldParams->s1Sz +
2U * (word32)oldParams->s2Sz);
}
XFREE(key->s1, key->heap, DYNAMIC_TYPE_MLDSA);
key->s1 = NULL;
key->s2 = NULL;
Expand Down Expand Up @@ -11050,6 +11087,12 @@ void wc_MlDsaKey_Free(wc_MlDsaKey* key)
XFREE(key->t1, key->heap, DYNAMIC_TYPE_MLDSA);
#endif
#ifdef WC_MLDSA_CACHE_PRIV_VECTORS
/* Cached buffer holds secret s1/s2/t0; zeroize before free (the
* ForceZero(key) below only clears the pointer). */
if ((key->s1 != NULL) && (key->params != NULL)) {
ForceZero(key->s1, (word32)key->params->s1Sz +
2U * (word32)key->params->s2Sz);
}
XFREE(key->s1, key->heap, DYNAMIC_TYPE_MLDSA);
#endif
#ifdef WC_MLDSA_CACHE_MATRIX_A
Expand Down Expand Up @@ -11433,6 +11476,10 @@ int wc_MlDsaKey_CheckKey(wc_MlDsaKey* key)
}

if (key != NULL) {
/* Zeroize secret s1/s2/t0 at the front (trailing t/t1/A are public). */
if ((s1 != NULL) && (params != NULL)) {
ForceZero(s1, (word32)params->s1Sz + 2U * (word32)params->s2Sz);
}
/* Dispose of allocated memory. */
XFREE(s1, key->heap, DYNAMIC_TYPE_MLDSA);
}
Expand Down
38 changes: 38 additions & 0 deletions wolfcrypt/src/wc_mlkem_poly.c
Original file line number Diff line number Diff line change
Expand Up @@ -3101,6 +3101,8 @@ static int mlkem_prf(wc_Shake* shake256, byte* out, unsigned int outLen,
outLen -= len;
}

/* state holds secret PRF output. */
ForceZero(state, sizeof(state));
return 0;
#else
int ret;
Expand Down Expand Up @@ -3152,6 +3154,8 @@ int mlkem_kdf(const byte* seed, int seedLen, byte* out, int outLen)
}
XMEMCPY(out, state, outLen);

/* state holds secret KDF output. */
ForceZero(state, sizeof(state));
return 0;
}
#endif
Expand All @@ -3178,6 +3182,8 @@ int mlkem_kdf(const byte* seed, int seedLen, byte* out, int outLen)
BlockSha3(state);
XMEMCPY(out, state, outLen);

/* state holds secret KDF output. */
ForceZero(state, sizeof(state));
return 0;
}
#endif
Expand Down Expand Up @@ -4038,6 +4044,8 @@ static int mlkem_get_noise_eta1_c(MLKEM_PRF_T* prf, sword16* p,
/* Sample for values in range -3..3 from 3 bits of random. */
mlkem_cbd_eta3(p, rand);
}
/* rand holds secret noise. */
ForceZero(rand, sizeof(rand));
}
else
#endif
Expand All @@ -4050,6 +4058,8 @@ static int mlkem_get_noise_eta1_c(MLKEM_PRF_T* prf, sword16* p,
/* Sample for values in range -2..2 from 2 bits of random. */
mlkem_cbd_eta2(p, rand);
}
/* rand holds secret noise. */
ForceZero(rand, sizeof(rand));
}

return ret;
Expand Down Expand Up @@ -4082,6 +4092,8 @@ static int mlkem_get_noise_eta2_c(MLKEM_PRF_T* prf, sword16* p,
mlkem_cbd_eta2(p, rand);
}

/* rand holds secret noise. */
ForceZero(rand, sizeof(rand));
return ret;
}

Expand Down Expand Up @@ -4118,6 +4130,9 @@ static void mlkem_get_noise_x4_eta2_avx2(byte* rand, byte* seed, byte o)
mlkem_redistribute_16_rand_avx2(state, rand + 0 * ETA2_RAND_SIZE,
rand + 1 * ETA2_RAND_SIZE, rand + 2 * ETA2_RAND_SIZE,
rand + 3 * ETA2_RAND_SIZE);

/* state is secret-seeded; caller zeroizes rand. */
ForceZero(state, sizeof(state));
}
#endif

Expand Down Expand Up @@ -4171,6 +4186,8 @@ static int mlkem_get_noise_eta2_avx2(MLKEM_PRF_T* prf, sword16* p,
}
mlkem_cbd_eta2_avx2(p, (byte*)state);

/* state holds secret noise. */
ForceZero(state, sizeof(state));
return 0;
}
#endif
Expand Down Expand Up @@ -4211,6 +4228,9 @@ static void mlkem_get_noise_x4_eta3_avx2(byte* rand, byte* seed)
mlkem_redistribute_8_rand_avx2(state, rand + i + 0 * PRF_RAND_SZ,
rand + i + 1 * PRF_RAND_SZ, rand + i + 2 * PRF_RAND_SZ,
rand + i + 3 * PRF_RAND_SZ);

/* state is secret-seeded; caller zeroizes rand. */
ForceZero(state, sizeof(state));
}

/* Get the noise/error by calculating random bytes and sampling to a binomial
Expand Down Expand Up @@ -4249,6 +4269,8 @@ static int mlkem_get_noise_k2_avx2(MLKEM_PRF_T* prf, sword16* vec1,
ret = mlkem_get_noise_eta2_avx2(prf, poly, seed);
}

/* rand holds secret noise. */
ForceZero(rand, 4 * PRF_RAND_SZ);
WC_FREE_VAR_EX(rand, NULL, DYNAMIC_TYPE_TMP_BUFFER);

return ret;
Expand Down Expand Up @@ -4282,6 +4304,8 @@ static int mlkem_get_noise_k3_avx2(sword16* vec1, sword16* vec2, sword16* poly,
mlkem_cbd_eta2_avx2(poly, rand + 2 * ETA2_RAND_SIZE);
}

/* rand holds secret noise. */
ForceZero(rand, sizeof(rand));
return 0;
}
#endif
Expand Down Expand Up @@ -4320,6 +4344,8 @@ static int mlkem_get_noise_k4_avx2(MLKEM_PRF_T* prf, sword16* vec1,
ret = mlkem_get_noise_eta2_avx2(prf, poly, seed);
}

/* rand holds secret noise. */
ForceZero(rand, sizeof(rand));
return ret;
}
#endif
Expand Down Expand Up @@ -4391,6 +4417,9 @@ static void mlkem_get_noise_x3_eta3_aarch64(byte* rand, byte* seed, byte o)
ETA3_RAND_SIZE - SHA3_256_BYTES);
XMEMCPY(rand + 2 * ETA3_RAND_SIZE, state + 2*25,
ETA3_RAND_SIZE - SHA3_256_BYTES);

/* state is secret-seeded; caller zeroizes rand. */
ForceZero(state, sizeof(state));
}

/* Get the noise/error by calculating random bytes.
Expand Down Expand Up @@ -4419,6 +4448,9 @@ static void mlkem_get_noise_eta3_aarch64(byte* rand, byte* seed, byte o)
XMEMCPY(rand , state, SHA3_256_BYTES);
BlockSha3(state);
XMEMCPY(rand + SHA3_256_BYTES, state, ETA3_RAND_SIZE - SHA3_256_BYTES);

/* state is secret-seeded; caller zeroizes rand. */
ForceZero(state, sizeof(state));
}

/* Get the noise/error by calculating random bytes and sampling to a binomial
Expand Down Expand Up @@ -4451,6 +4483,8 @@ static int mlkem_get_noise_k2_aarch64(sword16* vec1, sword16* vec2,
mlkem_cbd_eta2(poly , rand + 2 * 25 * 8);
}

/* rand holds secret noise. */
ForceZero(rand, sizeof(rand));
return ret;
}
#endif
Expand Down Expand Up @@ -4511,6 +4545,8 @@ static int mlkem_get_noise_k3_aarch64(sword16* vec1, sword16* vec2,
mlkem_cbd_eta2(poly , rand + 0 * 25 * 8);
}

/* rand holds secret noise. */
ForceZero(rand, sizeof(rand));
return 0;
}
#endif
Expand Down Expand Up @@ -4546,6 +4582,8 @@ static int mlkem_get_noise_k4_aarch64(sword16* vec1, sword16* vec2,
mlkem_cbd_eta2(poly, rand + 2 * 25 * 8);
}

/* rand holds secret noise. */
ForceZero(rand, sizeof(rand));
return ret;
}
#endif
Expand Down
Loading