@@ -186,6 +186,111 @@ static int sakke_xor_in_v_oob_test(void)
186186}
187187#endif
188188
189+ #ifdef WOLFCRYPT_HAVE_SAKKE
190+ /* Verify sakke_hash_to_range produces the full RFC 6508 5.1 mask for
191+ * ssvSz=48 with SHA-256, and that the public APIs reject ssvSz=0. The
192+ * old broken offset math left ssv[16..31] never XORed; encapsulating
193+ * an all-zero ssv exposes the gap (those bytes stay zero under the
194+ * bug, become random mask material once fixed). */
195+ static int sakke_mask_correctness_test (void )
196+ {
197+ SakkeKey key ;
198+ WC_RNG rng ;
199+ byte id [] = "user@example.com" ;
200+ word16 ssvSz = 48 ;
201+ word16 ssvSzZero = 0 ;
202+ word16 authSz = 0 ;
203+ byte ssv [48 ];
204+ byte * auth = NULL ;
205+ int ret ;
206+ int i ;
207+ int allZero = 1 ;
208+ int rc = 0 ;
209+
210+ if (wc_InitRng (& rng ) != 0 ) {
211+ printf ("sakke_correctness: SKIP (rng init)\n" );
212+ return 0 ;
213+ }
214+ if (wc_InitSakkeKey_ex (& key , 128 , ECC_SAKKE_1 , NULL , INVALID_DEVID ) != 0 ) {
215+ wc_FreeRng (& rng );
216+ printf ("sakke_correctness: SKIP (sakke key init)\n" );
217+ return 0 ;
218+ }
219+ if (wc_MakeSakkeKey (& key , & rng ) != 0 ) {
220+ wc_FreeSakkeKey (& key );
221+ wc_FreeRng (& rng );
222+ printf ("sakke_correctness: SKIP (sakke key gen)\n" );
223+ return 0 ;
224+ }
225+ if (wc_SetSakkeIdentity (& key , id , sizeof (id ) - 1 ) != 0 ) {
226+ wc_FreeSakkeKey (& key );
227+ wc_FreeRng (& rng );
228+ printf ("sakke_correctness: SKIP (set identity)\n" );
229+ return 0 ;
230+ }
231+
232+ ret = wc_MakeSakkeEncapsulatedSSV (& key , WC_HASH_TYPE_SHA256 , ssv , ssvSz ,
233+ NULL , & authSz );
234+ if (ret != WC_NO_ERR_TRACE (LENGTH_ONLY_E )) {
235+ printf ("sakke_correctness: SKIP (auth size query)\n" );
236+ goto cleanup ;
237+ }
238+ auth = (byte * )XMALLOC (authSz , NULL , DYNAMIC_TYPE_TMP_BUFFER );
239+ if (auth == NULL ) {
240+ printf ("sakke_correctness: SKIP (alloc)\n" );
241+ goto cleanup ;
242+ }
243+
244+ XMEMSET (ssv , 0 , ssvSz );
245+ ret = wc_MakeSakkeEncapsulatedSSV (& key , WC_HASH_TYPE_SHA256 , ssv , ssvSz ,
246+ auth , & authSz );
247+ if (ret != 0 ) {
248+ printf ("sakke_correctness: FAIL (encap ret=%d)\n" , ret );
249+ rc = -1 ;
250+ goto cleanup ;
251+ }
252+ for (i = 16 ; i < 32 ; i ++ ) {
253+ if (ssv [i ] != 0 ) { allZero = 0 ; break ; }
254+ }
255+ if (allZero ) {
256+ printf ("sakke_correctness: FAIL (ssv[16..31] not XORed)\n" );
257+ rc = -1 ;
258+ goto cleanup ;
259+ }
260+
261+ ret = wc_MakeSakkeEncapsulatedSSV (& key , WC_HASH_TYPE_SHA256 , ssv , ssvSzZero ,
262+ auth , & authSz );
263+ if (ret != WC_NO_ERR_TRACE (BAD_FUNC_ARG )) {
264+ printf ("sakke_correctness: FAIL (encap ssvSz=0 ret=%d)\n" , ret );
265+ rc = -1 ;
266+ goto cleanup ;
267+ }
268+ ret = wc_DeriveSakkeSSV (& key , WC_HASH_TYPE_SHA256 , ssv , ssvSzZero ,
269+ auth , authSz );
270+ if (ret != WC_NO_ERR_TRACE (BAD_FUNC_ARG )) {
271+ printf ("sakke_correctness: FAIL (derive ssvSz=0 ret=%d)\n" , ret );
272+ rc = -1 ;
273+ goto cleanup ;
274+ }
275+
276+ printf ("sakke_correctness: PASS\n" );
277+
278+ cleanup :
279+ if (auth != NULL ) {
280+ XFREE (auth , NULL , DYNAMIC_TYPE_TMP_BUFFER );
281+ }
282+ wc_FreeSakkeKey (& key );
283+ wc_FreeRng (& rng );
284+ return rc ;
285+ }
286+ #else
287+ static int sakke_mask_correctness_test (void )
288+ {
289+ printf ("sakke_correctness: SKIP (WOLFCRYPT_HAVE_SAKKE not defined)\n" );
290+ return 0 ;
291+ }
292+ #endif
293+
189294int allTesting = 1 ;
190295int apiTesting = 1 ;
191296int myoptind = 0 ;
@@ -422,6 +527,11 @@ int unit_test(int argc, char** argv)
422527 fflush (stdout );
423528 goto exit ;
424529 }
530+ if (sakke_mask_correctness_test () != 0 ) {
531+ ret = -1 ;
532+ fflush (stdout );
533+ goto exit ;
534+ }
425535 fflush (stdout );
426536
427537 XMEMSET (& wc_args , 0 , sizeof (wc_args ));
0 commit comments