Skip to content

Commit e8e1b98

Browse files
committed
Add SAKKE mask correctness regression test
1 parent 1c8d039 commit e8e1b98

1 file changed

Lines changed: 150 additions & 0 deletions

File tree

tests/unit.c

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,151 @@ static int sakke_xor_in_v_oob_test(void)
209209
}
210210
#endif
211211

212+
#ifdef WOLFCRYPT_HAVE_SAKKE
213+
/* Verify sakke_hash_to_range produces the full RFC 6508 5.1 mask for
214+
* ssvSz=48 with SHA-256, and that the public APIs reject ssvSz=0. The
215+
* old broken offset math left ssv[16..31] never XORed; encapsulating
216+
* an all-zero ssv exposes the gap (those bytes stay zero under the
217+
* bug, become random mask material once fixed). */
218+
static int sakke_mask_correctness_test(void)
219+
{
220+
SakkeKey key;
221+
WC_RNG rng;
222+
byte id[] = "user@example.com";
223+
word16 ssvSz = 48;
224+
word16 ssvSzZero = 0;
225+
word16 ssvSzTooBig = 0xFFFF; /* exceeds n for any supported curve */
226+
word16 authSz = 0;
227+
byte ssv[48];
228+
byte* auth = NULL;
229+
ecc_point* rsk = NULL;
230+
int ret;
231+
int i;
232+
int allZero = 1;
233+
int rc = 0;
234+
235+
if (wc_InitRng(&rng) != 0) {
236+
printf("sakke_correctness: SKIP (rng init)\n");
237+
return 0;
238+
}
239+
if (wc_InitSakkeKey_ex(&key, 128, ECC_SAKKE_1, NULL, INVALID_DEVID) != 0) {
240+
wc_FreeRng(&rng);
241+
printf("sakke_correctness: SKIP (sakke key init)\n");
242+
return 0;
243+
}
244+
if (wc_MakeSakkeKey(&key, &rng) != 0) {
245+
wc_FreeSakkeKey(&key);
246+
wc_FreeRng(&rng);
247+
printf("sakke_correctness: SKIP (sakke key gen)\n");
248+
return 0;
249+
}
250+
if (wc_SetSakkeIdentity(&key, id, sizeof(id) - 1) != 0) {
251+
wc_FreeSakkeKey(&key);
252+
wc_FreeRng(&rng);
253+
printf("sakke_correctness: SKIP (set identity)\n");
254+
return 0;
255+
}
256+
257+
ret = wc_MakeSakkeEncapsulatedSSV(&key, WC_HASH_TYPE_SHA256, ssv, ssvSz,
258+
NULL, &authSz);
259+
if (ret != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
260+
printf("sakke_correctness: SKIP (auth size query)\n");
261+
goto cleanup;
262+
}
263+
auth = (byte*)XMALLOC(authSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
264+
if (auth == NULL) {
265+
printf("sakke_correctness: SKIP (alloc)\n");
266+
goto cleanup;
267+
}
268+
269+
XMEMSET(ssv, 0, ssvSz);
270+
ret = wc_MakeSakkeEncapsulatedSSV(&key, WC_HASH_TYPE_SHA256, ssv, ssvSz,
271+
auth, &authSz);
272+
if (ret != 0) {
273+
printf("sakke_correctness: FAIL (encap ret=%d)\n", ret);
274+
rc = -1;
275+
goto cleanup;
276+
}
277+
for (i = 16; i < 32; i++) {
278+
if (ssv[i] != 0) { allZero = 0; break; }
279+
}
280+
if (allZero) {
281+
printf("sakke_correctness: FAIL (ssv[16..31] not XORed)\n");
282+
rc = -1;
283+
goto cleanup;
284+
}
285+
286+
ret = wc_MakeSakkeEncapsulatedSSV(&key, WC_HASH_TYPE_SHA256, ssv, ssvSzZero,
287+
auth, &authSz);
288+
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) {
289+
printf("sakke_correctness: FAIL (encap ssvSz=0 ret=%d)\n", ret);
290+
rc = -1;
291+
goto cleanup;
292+
}
293+
ret = wc_DeriveSakkeSSV(&key, WC_HASH_TYPE_SHA256, ssv, ssvSzZero,
294+
auth, authSz);
295+
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) {
296+
printf("sakke_correctness: FAIL (derive ssvSz=0 ret=%d)\n", ret);
297+
rc = -1;
298+
goto cleanup;
299+
}
300+
301+
/* ssvSz > n on encap: reachable directly because encap doesn't
302+
* require RSK to be set. */
303+
ret = wc_MakeSakkeEncapsulatedSSV(&key, WC_HASH_TYPE_SHA256, ssv,
304+
ssvSzTooBig, auth, &authSz);
305+
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) {
306+
printf("sakke_correctness: FAIL (encap ssvSz>n ret=%d)\n", ret);
307+
rc = -1;
308+
goto cleanup;
309+
}
310+
311+
/* ssvSz > n on derive: the check sits below the !rsk.set gate, so
312+
* we must populate RSK first or derive returns BAD_STATE_E and the
313+
* range check is never reached. Use this key as both KMS and
314+
* recipient. */
315+
rsk = wc_ecc_new_point();
316+
if (rsk == NULL) {
317+
printf("sakke_correctness: SKIP (rsk alloc)\n");
318+
goto cleanup;
319+
}
320+
if (wc_MakeSakkeRsk(&key, id, sizeof(id) - 1, rsk) != 0) {
321+
printf("sakke_correctness: SKIP (make rsk)\n");
322+
goto cleanup;
323+
}
324+
if (wc_SetSakkeRsk(&key, rsk, NULL, 0) != 0) {
325+
printf("sakke_correctness: SKIP (set rsk)\n");
326+
goto cleanup;
327+
}
328+
ret = wc_DeriveSakkeSSV(&key, WC_HASH_TYPE_SHA256, ssv, ssvSzTooBig,
329+
auth, authSz);
330+
if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) {
331+
printf("sakke_correctness: FAIL (derive ssvSz>n ret=%d)\n", ret);
332+
rc = -1;
333+
goto cleanup;
334+
}
335+
336+
printf("sakke_correctness: PASS\n");
337+
338+
cleanup:
339+
if (rsk != NULL) {
340+
wc_ecc_del_point(rsk);
341+
}
342+
if (auth != NULL) {
343+
XFREE(auth, NULL, DYNAMIC_TYPE_TMP_BUFFER);
344+
}
345+
wc_FreeSakkeKey(&key);
346+
wc_FreeRng(&rng);
347+
return rc;
348+
}
349+
#else
350+
static int sakke_mask_correctness_test(void)
351+
{
352+
printf("sakke_correctness: SKIP (WOLFCRYPT_HAVE_SAKKE not defined)\n");
353+
return 0;
354+
}
355+
#endif
356+
212357
int allTesting = 1;
213358
int apiTesting = 1;
214359
int myoptind = 0;
@@ -444,6 +589,11 @@ int unit_test(int argc, char** argv)
444589
fflush(stdout);
445590
goto exit;
446591
}
592+
if (sakke_mask_correctness_test() != 0) {
593+
ret = -1;
594+
fflush(stdout);
595+
goto exit;
596+
}
447597
fflush(stdout);
448598

449599
XMEMSET(&wc_args, 0, sizeof(wc_args));

0 commit comments

Comments
 (0)