@@ -3628,6 +3628,8 @@ static int mldsa_rej_bound_poly(wc_Shake* shake256, byte* seed, sword32* s,
36283628 while (j < MLDSA_N );
36293629 }
36303630
3631+ /* z holds the secret s1/s2 bytes. */
3632+ ForceZero (z , sizeof (z ));
36313633 return ret ;
36323634#else
36333635 int ret ;
@@ -3656,6 +3658,8 @@ static int mldsa_rej_bound_poly(wc_Shake* shake256, byte* seed, sword32* s,
36563658 }
36573659 }
36583660
3661+ /* z holds the secret s1/s2 bytes. */
3662+ ForceZero (z , MLDSA_GEN_S_BYTES );
36593663 WC_FREE_VAR_EX (z , NULL , DYNAMIC_TYPE_MLDSA );
36603664 return ret ;
36613665#endif
@@ -3760,6 +3764,9 @@ static int wc_mldsa_gen_s_4_4_avx2(sword32* s[2], byte* seed)
37603764 (ctr3 < MLDSA_N ));
37613765 }
37623766
3767+ /* rand/state hold secret s-vector material. */
3768+ ForceZero (rand , 4 * MLDSA_GEN_S_BLOCK_BYTES );
3769+ ForceZero (state , sizeof (word64 ) * 25 * 4 );
37633770 WC_FREE_VAR_EX (rand , NULL , DYNAMIC_TYPE_TMP_BUFFER );
37643771 WC_FREE_VAR_EX (state , NULL , DYNAMIC_TYPE_TMP_BUFFER );
37653772
@@ -3913,6 +3920,9 @@ static int wc_mldsa_gen_s_5_6_avx2(sword32* s[2], byte* seed)
39133920 /* Create more blocks if too many rejected. */
39143921 while ((ctr0 < MLDSA_N ) || (ctr1 < MLDSA_N ) || (ctr2 < MLDSA_N ));
39153922
3923+ /* rand/state hold secret s-vector material. */
3924+ ForceZero (rand , 4 * MLDSA_GEN_S_BLOCK_BYTES );
3925+ ForceZero (state , sizeof (word64 ) * 25 * 4 );
39163926 WC_FREE_VAR_EX (rand , NULL , DYNAMIC_TYPE_TMP_BUFFER );
39173927 WC_FREE_VAR_EX (state , NULL , DYNAMIC_TYPE_TMP_BUFFER );
39183928
@@ -4068,6 +4078,9 @@ static int wc_mldsa_gen_s_7_8_avx2(sword32* s[2], byte* seed)
40684078 /* Create more blocks if too many rejected. */
40694079 while ((ctr0 < MLDSA_N ) || (ctr1 < MLDSA_N ) || (ctr2 < MLDSA_N ));
40704080
4081+ /* rand/state hold secret s-vector material. */
4082+ ForceZero (rand , 4 * MLDSA_GEN_S_BLOCK_BYTES );
4083+ ForceZero (state , sizeof (word64 ) * 25 * 4 );
40714084 WC_FREE_VAR_EX (rand , NULL , DYNAMIC_TYPE_TMP_BUFFER );
40724085 WC_FREE_VAR_EX (state , NULL , DYNAMIC_TYPE_TMP_BUFFER );
40734086
@@ -4257,6 +4270,9 @@ static int wc_mldsa_gen_y_4_avx2(sword32* y, byte* seed, word16 kappa)
42574270 wc_mldsa_decode_gamma1_17_avx2 (rand + 3 * MLDSA_MAX_V ,
42584271 y + 3 * MLDSA_N );
42594272
4273+ /* rand/state hold the secret mask y. */
4274+ ForceZero (rand , 4 * MLDSA_MAX_V );
4275+ ForceZero (state , sizeof (word64 ) * 25 * 4 );
42604276 WC_FREE_VAR_EX (rand , NULL , DYNAMIC_TYPE_TMP_BUFFER );
42614277 WC_FREE_VAR_EX (state , NULL , DYNAMIC_TYPE_TMP_BUFFER );
42624278
@@ -4337,6 +4353,9 @@ static int wc_mldsa_gen_y_5_avx2(sword32* y, byte* seed, word16 kappa,
43374353 wc_mldsa_decode_gamma1_19_avx2 (rand , y + 4 * MLDSA_N );
43384354 }
43394355
4356+ /* rand/state hold the secret mask y. */
4357+ ForceZero (rand , 4 * MLDSA_MAX_V );
4358+ ForceZero (state , sizeof (word64 ) * 25 * 4 );
43404359 WC_FREE_VAR_EX (rand , NULL , DYNAMIC_TYPE_TMP_BUFFER );
43414360 WC_FREE_VAR_EX (state , NULL , DYNAMIC_TYPE_TMP_BUFFER );
43424361
@@ -4432,6 +4451,9 @@ static int wc_mldsa_gen_y_7_avx2(sword32* y, byte* seed, word16 kappa)
44324451 wc_mldsa_decode_gamma1_19_avx2 (rand + 2 * MLDSA_MAX_V ,
44334452 y + 6 * MLDSA_N );
44344453
4454+ /* rand/state hold the secret mask y. */
4455+ ForceZero (rand , 4 * MLDSA_MAX_V );
4456+ ForceZero (state , sizeof (word64 ) * 25 * 4 );
44354457 WC_FREE_VAR_EX (rand , NULL , DYNAMIC_TYPE_TMP_BUFFER );
44364458 WC_FREE_VAR_EX (state , NULL , DYNAMIC_TYPE_TMP_BUFFER );
44374459
@@ -4490,6 +4512,8 @@ static int mldsa_vec_expand_mask_c(wc_Shake* shake256, byte* seed,
44904512 }
44914513 }
44924514
4515+ /* v holds the secret mask y. */
4516+ ForceZero (v , MLDSA_MAX_V );
44934517 WC_FREE_VAR_EX (v , NULL , DYNAMIC_TYPE_MLDSA );
44944518 return ret ;
44954519}
@@ -10934,6 +10958,9 @@ int wc_MlDsaKey_InitLabel(wc_MlDsaKey* key, const char* label, void* heap,
1093410958int wc_MlDsaKey_SetParams (wc_MlDsaKey * key , byte level )
1093510959{
1093610960 int ret = 0 ;
10961+ #if !defined(WC_MLDSA_FIXED_ARRAY ) && defined(WC_MLDSA_CACHE_PRIV_VECTORS )
10962+ const wc_MlDsaParams * oldParams = NULL ;
10963+ #endif
1093710964
1093810965 /* Validate parameters. */
1093910966 if (key == NULL ) {
@@ -10954,6 +10981,11 @@ int wc_MlDsaKey_SetParams(wc_MlDsaKey* key, byte level)
1095410981 }
1095510982
1095610983 if (ret == 0 ) {
10984+ #if !defined(WC_MLDSA_FIXED_ARRAY ) && defined(WC_MLDSA_CACHE_PRIV_VECTORS )
10985+ /* Save old params to size the cached-vector wipe below (key->params
10986+ * is about to change to the new level). */
10987+ oldParams = key -> params ;
10988+ #endif
1095710989 /* Get the parameters for level into key. */
1095810990 ret = mldsa_get_params (level , & key -> params );
1095910991 }
@@ -10966,6 +10998,11 @@ int wc_MlDsaKey_SetParams(wc_MlDsaKey* key, byte level)
1096610998 key -> aSet = 0 ;
1096710999 #endif
1096811000 #ifdef WC_MLDSA_CACHE_PRIV_VECTORS
11001+ /* Cached buffer holds secret s1/s2/t0; zeroize before free. */
11002+ if ((key -> s1 != NULL ) && (oldParams != NULL )) {
11003+ ForceZero (key -> s1 , (word32 )oldParams -> s1Sz +
11004+ 2U * (word32 )oldParams -> s2Sz );
11005+ }
1096911006 XFREE (key -> s1 , key -> heap , DYNAMIC_TYPE_MLDSA );
1097011007 key -> s1 = NULL ;
1097111008 key -> s2 = NULL ;
@@ -11050,6 +11087,12 @@ void wc_MlDsaKey_Free(wc_MlDsaKey* key)
1105011087 XFREE (key -> t1 , key -> heap , DYNAMIC_TYPE_MLDSA );
1105111088 #endif
1105211089 #ifdef WC_MLDSA_CACHE_PRIV_VECTORS
11090+ /* Cached buffer holds secret s1/s2/t0; zeroize before free (the
11091+ * ForceZero(key) below only clears the pointer). */
11092+ if ((key -> s1 != NULL ) && (key -> params != NULL )) {
11093+ ForceZero (key -> s1 , (word32 )key -> params -> s1Sz +
11094+ 2U * (word32 )key -> params -> s2Sz );
11095+ }
1105311096 XFREE (key -> s1 , key -> heap , DYNAMIC_TYPE_MLDSA );
1105411097 #endif
1105511098 #ifdef WC_MLDSA_CACHE_MATRIX_A
@@ -11433,6 +11476,10 @@ int wc_MlDsaKey_CheckKey(wc_MlDsaKey* key)
1143311476 }
1143411477
1143511478 if (key != NULL ) {
11479+ /* Zeroize secret s1/s2/t0 at the front (trailing t/t1/A are public). */
11480+ if ((s1 != NULL ) && (params != NULL )) {
11481+ ForceZero (s1 , (word32 )params -> s1Sz + 2U * (word32 )params -> s2Sz );
11482+ }
1143611483 /* Dispose of allocated memory. */
1143711484 XFREE (s1 , key -> heap , DYNAMIC_TYPE_MLDSA );
1143811485 }
0 commit comments