Skip to content

Commit eb669e4

Browse files
committed
Expand ECC tests to cover export and cache key cases
1 parent 76da7dd commit eb669e4

File tree

1 file changed

+239
-8
lines changed

1 file changed

+239
-8
lines changed

test/wh_test_crypto.c

Lines changed: 239 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -310,17 +310,24 @@ static int whTest_CryptoRsa(whClientContext* ctx, int devId, WC_RNG* rng)
310310
#ifdef HAVE_ECC
311311
static int whTest_CryptoEcc(whClientContext* ctx, int devId, WC_RNG* rng)
312312
{
313-
(void)ctx;
314-
315313
int ret = WH_ERROR_OK;
316314
ecc_key eccPrivate[1];
317315
ecc_key eccPublic[1];
318316
#define TEST_ECC_KEYSIZE 32
317+
#define TEST_ECC_CURVE_ID ECC_SECP256R1
319318
uint8_t shared_ab[TEST_ECC_KEYSIZE] = {0};
320319
uint8_t shared_ba[TEST_ECC_KEYSIZE] = {0};
321320
uint8_t hash[TEST_ECC_KEYSIZE] = {0};
322321
uint8_t sig[ECC_MAX_SIG_SIZE] = {0};
323-
322+
whKeyId keyIdPrivate = WH_KEYID_ERASED;
323+
whKeyId keyIdPublic = WH_KEYID_ERASED;
324+
whKeyId checkKeyId = WH_KEYID_ERASED;
325+
whNvmFlags flags = WH_NVM_FLAGS_USAGE_SIGN | WH_NVM_FLAGS_USAGE_VERIFY |
326+
WH_NVM_FLAGS_USAGE_DERIVE;
327+
uint8_t labelPrivate[WH_NVM_LABEL_LEN] = "ECC Private Key";
328+
uint8_t labelPublic[WH_NVM_LABEL_LEN] = "ECC Public Key";
329+
330+
/* Test Case 1: Using ephemeral key (normal wolfCrypt flow) */
324331
ret = wc_ecc_init_ex(eccPrivate, NULL, devId);
325332
if (ret != 0) {
326333
WH_ERROR_PRINT("Failed to wc_ecc_init_ex %d\n", ret);
@@ -350,15 +357,16 @@ static int whTest_CryptoEcc(whClientContext* ctx, int devId, WC_RNG* rng)
350357
ret);
351358
} else {
352359
if (memcmp(shared_ab, shared_ba, secLen) == 0) {
353-
WH_TEST_PRINT("ECDH SUCCESS\n");
360+
WH_TEST_PRINT("ECC ephemeral ECDH SUCCESS\n");
354361
}
355362
else {
356-
WH_ERROR_PRINT("ECDH FAILED TO MATCH\n");
363+
WH_ERROR_PRINT("ECC ephemeral ECDH FAILED TO MATCH\n");
364+
ret = -1;
357365
}
358366
}
359367
}
360368
if (ret == 0) {
361-
/*Use the shared secret as a random hash */
369+
/* Use the shared secret as a random hash */
362370
memcpy(hash, shared_ba, sizeof(hash));
363371
word32 sigLen = sizeof(sig);
364372
ret = wc_ecc_sign_hash((void*)hash, sizeof(hash),
@@ -379,10 +387,10 @@ static int whTest_CryptoEcc(whClientContext* ctx, int devId, WC_RNG* rng)
379387
}
380388
else {
381389
if (res == 1) {
382-
WH_TEST_PRINT("ECC SIGN/VERIFY SUCCESS\n");
390+
WH_TEST_PRINT("ECC ephemeral SIGN/VERIFY SUCCESS\n");
383391
}
384392
else {
385-
WH_ERROR_PRINT("ECC SIGN/VERIFY FAIL\n");
393+
WH_ERROR_PRINT("ECC ephemeral SIGN/VERIFY FAIL\n");
386394
ret = -1;
387395
}
388396
}
@@ -394,6 +402,229 @@ static int whTest_CryptoEcc(whClientContext* ctx, int devId, WC_RNG* rng)
394402
}
395403
wc_ecc_free(eccPrivate);
396404
}
405+
406+
/* Test Case 2: Using client export key */
407+
if (ret == 0) {
408+
memset(shared_ab, 0, sizeof(shared_ab));
409+
memset(shared_ba, 0, sizeof(shared_ba));
410+
memset(sig, 0, sizeof(sig));
411+
412+
ret = wc_ecc_init_ex(eccPrivate, NULL, WH_DEV_ID);
413+
if (ret != 0) {
414+
WH_ERROR_PRINT("Failed to wc_ecc_init_ex for export key %d\n", ret);
415+
} else {
416+
ret = wc_ecc_init_ex(eccPublic, NULL, WH_DEV_ID);
417+
if (ret != 0) {
418+
WH_ERROR_PRINT("Failed to wc_ecc_init_ex for export key %d\n", ret);
419+
} else {
420+
/* Server creates keys and exports them to client */
421+
ret = wh_Client_EccMakeExportKey(ctx, TEST_ECC_KEYSIZE,
422+
TEST_ECC_CURVE_ID, eccPrivate);
423+
if (ret != 0) {
424+
WH_ERROR_PRINT("Failed to wh_Client_EccMakeExportKey %d\n", ret);
425+
}
426+
if (ret == 0) {
427+
ret = wh_Client_EccMakeExportKey(ctx, TEST_ECC_KEYSIZE,
428+
TEST_ECC_CURVE_ID, eccPublic);
429+
if (ret != 0) {
430+
WH_ERROR_PRINT("Failed to wh_Client_EccMakeExportKey %d\n", ret);
431+
}
432+
}
433+
/* Test ECDH with exported keys */
434+
if (ret == 0) {
435+
word32 secLen = TEST_ECC_KEYSIZE;
436+
ret = wc_ecc_shared_secret(eccPrivate, eccPublic,
437+
(byte*)shared_ab, &secLen);
438+
if (ret != 0) {
439+
WH_ERROR_PRINT("Failed to compute export key secret %d\n", ret);
440+
}
441+
}
442+
if (ret == 0) {
443+
word32 secLen = TEST_ECC_KEYSIZE;
444+
ret = wc_ecc_shared_secret(eccPublic, eccPrivate,
445+
(byte*)shared_ba, &secLen);
446+
if (ret != 0) {
447+
WH_ERROR_PRINT("Failed to compute export key secret %d\n", ret);
448+
}
449+
}
450+
if (ret == 0) {
451+
if (memcmp(shared_ab, shared_ba, TEST_ECC_KEYSIZE) != 0) {
452+
WH_ERROR_PRINT("ECC export key ECDH FAILED TO MATCH\n");
453+
ret = -1;
454+
} else {
455+
WH_TEST_PRINT("ECC export key ECDH SUCCESS\n");
456+
}
457+
}
458+
/* Test ECDSA sign/verify with exported keys */
459+
if (ret == 0) {
460+
memcpy(hash, shared_ba, sizeof(hash));
461+
word32 sigLen = sizeof(sig);
462+
ret = wc_ecc_sign_hash((void*)hash, sizeof(hash),
463+
(void*)sig, &sigLen, rng,
464+
eccPrivate);
465+
if (ret != 0) {
466+
WH_ERROR_PRINT("Failed to sign with export key %d\n", ret);
467+
} else {
468+
int res = 0;
469+
ret = wc_ecc_verify_hash((void*)sig, sigLen,
470+
(void*)hash, sizeof(hash),
471+
&res, eccPrivate);
472+
if (ret != 0) {
473+
WH_ERROR_PRINT("Failed to verify with export key %d\n", ret);
474+
} else if (res != 1) {
475+
WH_ERROR_PRINT("ECC export key SIGN/VERIFY FAIL\n");
476+
ret = -1;
477+
} else {
478+
WH_TEST_PRINT("ECC export key SIGN/VERIFY SUCCESS\n");
479+
}
480+
}
481+
}
482+
wc_ecc_free(eccPublic);
483+
}
484+
wc_ecc_free(eccPrivate);
485+
}
486+
}
487+
488+
/* Test Case 3: Using keyCache key (key stays on server) */
489+
if (ret == 0) {
490+
memset(shared_ab, 0, sizeof(shared_ab));
491+
memset(shared_ba, 0, sizeof(shared_ba));
492+
memset(sig, 0, sizeof(sig));
493+
keyIdPrivate = WH_KEYID_ERASED;
494+
keyIdPublic = WH_KEYID_ERASED;
495+
496+
/* Server creates and caches keys */
497+
ret = wh_Client_EccMakeCacheKey(ctx, TEST_ECC_KEYSIZE, TEST_ECC_CURVE_ID,
498+
&keyIdPrivate, flags, sizeof(labelPrivate), labelPrivate);
499+
if (ret != 0) {
500+
WH_ERROR_PRINT("Failed to wh_Client_EccMakeCacheKey %d\n", ret);
501+
}
502+
if (ret == 0) {
503+
ret = wh_Client_EccMakeCacheKey(ctx, TEST_ECC_KEYSIZE, TEST_ECC_CURVE_ID,
504+
&keyIdPublic, flags, sizeof(labelPublic), labelPublic);
505+
if (ret != 0) {
506+
WH_ERROR_PRINT("Failed to wh_Client_EccMakeCacheKey %d\n", ret);
507+
}
508+
}
509+
if (ret == 0) {
510+
ret = wc_ecc_init_ex(eccPrivate, NULL, WH_DEV_ID);
511+
if (ret != 0) {
512+
WH_ERROR_PRINT("Failed to wc_ecc_init_ex for cache key %d\n", ret);
513+
}
514+
}
515+
if (ret == 0) {
516+
ret = wc_ecc_init_ex(eccPublic, NULL, WH_DEV_ID);
517+
if (ret != 0) {
518+
WH_ERROR_PRINT("Failed to wc_ecc_init_ex for cache key %d\n", ret);
519+
wc_ecc_free(eccPrivate);
520+
}
521+
}
522+
if (ret == 0) {
523+
/* Associate server key IDs with local key structs */
524+
ret = wh_Client_EccSetKeyId(eccPrivate, keyIdPrivate);
525+
if (ret != 0) {
526+
WH_ERROR_PRINT("Failed to wh_Client_EccSetKeyId %d\n", ret);
527+
}
528+
}
529+
if (ret == 0) {
530+
ret = wh_Client_EccSetKeyId(eccPublic, keyIdPublic);
531+
if (ret != 0) {
532+
WH_ERROR_PRINT("Failed to wh_Client_EccSetKeyId %d\n", ret);
533+
}
534+
}
535+
/* Verify key IDs were set correctly */
536+
if (ret == 0) {
537+
ret = wh_Client_EccGetKeyId(eccPrivate, &checkKeyId);
538+
if (ret != 0) {
539+
WH_ERROR_PRINT("Failed to wh_Client_EccGetKeyId %d\n", ret);
540+
} else if (checkKeyId != keyIdPrivate) {
541+
WH_ERROR_PRINT("ECC key ID mismatch: got %u, expected %u\n",
542+
checkKeyId, keyIdPrivate);
543+
ret = -1;
544+
}
545+
}
546+
if (ret == 0) {
547+
ret = wh_Client_EccGetKeyId(eccPublic, &checkKeyId);
548+
if (ret != 0) {
549+
WH_ERROR_PRINT("Failed to wh_Client_EccGetKeyId %d\n", ret);
550+
} else if (checkKeyId != keyIdPublic) {
551+
WH_ERROR_PRINT("ECC key ID mismatch: got %u, expected %u\n",
552+
checkKeyId, keyIdPublic);
553+
ret = -1;
554+
}
555+
}
556+
/* Set curve parameters (required since key data isn't exported) */
557+
if (ret == 0) {
558+
ret = wc_ecc_set_curve(eccPrivate, TEST_ECC_KEYSIZE, TEST_ECC_CURVE_ID);
559+
if (ret != 0) {
560+
WH_ERROR_PRINT("Failed to wc_ecc_set_curve %d\n", ret);
561+
}
562+
}
563+
if (ret == 0) {
564+
ret = wc_ecc_set_curve(eccPublic, TEST_ECC_KEYSIZE, TEST_ECC_CURVE_ID);
565+
if (ret != 0) {
566+
WH_ERROR_PRINT("Failed to wc_ecc_set_curve %d\n", ret);
567+
}
568+
}
569+
/* Test ECDH with cached keys */
570+
if (ret == 0) {
571+
word32 secLen = TEST_ECC_KEYSIZE;
572+
ret = wc_ecc_shared_secret(eccPrivate, eccPublic,
573+
(byte*)shared_ab, &secLen);
574+
if (ret != 0) {
575+
WH_ERROR_PRINT("Failed to compute cache key secret %d\n", ret);
576+
}
577+
}
578+
if (ret == 0) {
579+
word32 secLen = TEST_ECC_KEYSIZE;
580+
ret = wc_ecc_shared_secret(eccPublic, eccPrivate,
581+
(byte*)shared_ba, &secLen);
582+
if (ret != 0) {
583+
WH_ERROR_PRINT("Failed to compute cache key secret %d\n", ret);
584+
}
585+
}
586+
if (ret == 0) {
587+
if (memcmp(shared_ab, shared_ba, TEST_ECC_KEYSIZE) != 0) {
588+
WH_ERROR_PRINT("ECC cache key ECDH FAILED TO MATCH\n");
589+
ret = -1;
590+
} else {
591+
WH_TEST_PRINT("ECC cache key ECDH SUCCESS\n");
592+
}
593+
}
594+
/* Test ECDSA sign/verify with cached keys */
595+
if (ret == 0) {
596+
memcpy(hash, shared_ba, sizeof(hash));
597+
word32 sigLen = sizeof(sig);
598+
ret = wc_ecc_sign_hash((void*)hash, sizeof(hash),
599+
(void*)sig, &sigLen, rng,
600+
eccPrivate);
601+
if (ret != 0) {
602+
WH_ERROR_PRINT("Failed to sign with cache key %d\n", ret);
603+
} else {
604+
int res = 0;
605+
ret = wc_ecc_verify_hash((void*)sig, sigLen,
606+
(void*)hash, sizeof(hash),
607+
&res, eccPrivate);
608+
if (ret != 0) {
609+
WH_ERROR_PRINT("Failed to verify with cache key %d\n", ret);
610+
} else if (res != 1) {
611+
WH_ERROR_PRINT("ECC cache key SIGN/VERIFY FAIL\n");
612+
ret = -1;
613+
} else {
614+
WH_TEST_PRINT("ECC cache key SIGN/VERIFY SUCCESS\n");
615+
}
616+
}
617+
}
618+
/* Cleanup */
619+
wc_ecc_free(eccPublic);
620+
wc_ecc_free(eccPrivate);
621+
(void)wh_Client_KeyEvict(ctx, keyIdPrivate);
622+
(void)wh_Client_KeyEvict(ctx, keyIdPublic);
623+
}
624+
625+
if (ret == 0) {
626+
WH_TEST_PRINT("ECC SUCCESS\n");
627+
}
397628
return ret;
398629
}
399630
#endif /* HAVE_ECC */

0 commit comments

Comments
 (0)