@@ -174,6 +174,109 @@ static int sakke_xor_in_v_oob_test(void)
174174}
175175#endif
176176
177+ #ifdef WOLFCRYPT_HAVE_SAKKE
178+ /* Verify sakke_hash_to_range produces the full RFC 6508 5.1 mask for
179+ * ssvSz=48 with SHA-256, and that the public APIs reject ssvSz=0. The
180+ * old broken offset math left ssv[16..31] never XORed; encapsulating
181+ * an all-zero ssv exposes the gap (those bytes stay zero under the
182+ * bug, become random mask material once fixed). */
183+ static int sakke_mask_correctness_test (void )
184+ {
185+ SakkeKey key ;
186+ WC_RNG rng ;
187+ unsigned char id [] = "user@example.com" ;
188+ word16 ssvSz = 48 ;
189+ word16 ssvSzZero = 0 ;
190+ word16 authSz = 0 ;
191+ unsigned char ssv [48 ];
192+ unsigned char * auth = NULL ;
193+ int ret ;
194+ int i ;
195+ int allZero = 1 ;
196+ int rc = 0 ;
197+
198+ if (wc_InitRng (& rng ) != 0 ) {
199+ printf ("sakke_correctness: SKIP (rng init)\n" );
200+ return 0 ;
201+ }
202+ if (wc_InitSakkeKey_ex (& key , 128 , ECC_SAKKE_1 , NULL , INVALID_DEVID ) != 0 ) {
203+ wc_FreeRng (& rng );
204+ printf ("sakke_correctness: SKIP (sakke key init)\n" );
205+ return 0 ;
206+ }
207+ if (wc_MakeSakkeKey (& key , & rng ) != 0 ) {
208+ wc_FreeSakkeKey (& key );
209+ wc_FreeRng (& rng );
210+ printf ("sakke_correctness: SKIP (sakke key gen)\n" );
211+ return 0 ;
212+ }
213+ if (wc_SetSakkeIdentity (& key , id , sizeof (id ) - 1 ) != 0 ) {
214+ wc_FreeSakkeKey (& key );
215+ wc_FreeRng (& rng );
216+ printf ("sakke_correctness: SKIP (set identity)\n" );
217+ return 0 ;
218+ }
219+
220+ ret = wc_MakeSakkeEncapsulatedSSV (& key , WC_HASH_TYPE_SHA256 , ssv , ssvSz ,
221+ NULL , & authSz );
222+ if (ret != WC_NO_ERR_TRACE (LENGTH_ONLY_E )) {
223+ printf ("sakke_correctness: SKIP (auth size query)\n" );
224+ goto cleanup ;
225+ }
226+ auth = (unsigned char * )malloc (authSz );
227+ if (auth == NULL ) {
228+ printf ("sakke_correctness: SKIP (alloc)\n" );
229+ goto cleanup ;
230+ }
231+
232+ XMEMSET (ssv , 0 , ssvSz );
233+ ret = wc_MakeSakkeEncapsulatedSSV (& key , WC_HASH_TYPE_SHA256 , ssv , ssvSz ,
234+ auth , & authSz );
235+ if (ret != 0 ) {
236+ printf ("sakke_correctness: FAIL (encap ret=%d)\n" , ret );
237+ rc = -1 ;
238+ goto cleanup ;
239+ }
240+ for (i = 16 ; i < 32 ; i ++ ) {
241+ if (ssv [i ] != 0 ) { allZero = 0 ; break ; }
242+ }
243+ if (allZero ) {
244+ printf ("sakke_correctness: FAIL (ssv[16..31] not XORed)\n" );
245+ rc = -1 ;
246+ goto cleanup ;
247+ }
248+
249+ ret = wc_MakeSakkeEncapsulatedSSV (& key , WC_HASH_TYPE_SHA256 , ssv , ssvSzZero ,
250+ auth , & authSz );
251+ if (ret != WC_NO_ERR_TRACE (BAD_FUNC_ARG )) {
252+ printf ("sakke_correctness: FAIL (encap ssvSz=0 ret=%d)\n" , ret );
253+ rc = -1 ;
254+ goto cleanup ;
255+ }
256+ ret = wc_DeriveSakkeSSV (& key , WC_HASH_TYPE_SHA256 , ssv , ssvSzZero ,
257+ auth , authSz );
258+ if (ret != WC_NO_ERR_TRACE (BAD_FUNC_ARG )) {
259+ printf ("sakke_correctness: FAIL (derive ssvSz=0 ret=%d)\n" , ret );
260+ rc = -1 ;
261+ goto cleanup ;
262+ }
263+
264+ printf ("sakke_correctness: PASS\n" );
265+
266+ cleanup :
267+ if (auth != NULL ) free (auth );
268+ wc_FreeSakkeKey (& key );
269+ wc_FreeRng (& rng );
270+ return rc ;
271+ }
272+ #else
273+ static int sakke_mask_correctness_test (void )
274+ {
275+ printf ("sakke_correctness: SKIP (WOLFCRYPT_HAVE_SAKKE not defined)\n" );
276+ return 0 ;
277+ }
278+ #endif
279+
177280int allTesting = 1 ;
178281int apiTesting = 1 ;
179282int myoptind = 0 ;
@@ -405,6 +508,11 @@ int unit_test(int argc, char** argv)
405508 fflush (stdout );
406509 goto exit ;
407510 }
511+ if (sakke_mask_correctness_test () != 0 ) {
512+ ret = -1 ;
513+ fflush (stdout );
514+ goto exit ;
515+ }
408516 fflush (stdout );
409517
410518 XMEMSET (& wc_args , 0 , sizeof (wc_args ));
0 commit comments