Skip to content

Commit 2b87423

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

File tree

1 file changed

+264
-22
lines changed

1 file changed

+264
-22
lines changed

test/wh_test_crypto.c

Lines changed: 264 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -310,89 +310,331 @@ 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;
316-
ecc_key eccPrivate[1];
317-
ecc_key eccPublic[1];
314+
ecc_key bonnieKey[1];
315+
ecc_key clydeKey[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-
324-
ret = wc_ecc_init_ex(eccPrivate, NULL, devId);
322+
whKeyId keyIdPrivate = WH_KEYID_ERASED;
323+
whKeyId checkKeyId = WH_KEYID_ERASED;
324+
whNvmFlags flags = WH_NVM_FLAGS_USAGE_SIGN | WH_NVM_FLAGS_USAGE_VERIFY |
325+
WH_NVM_FLAGS_USAGE_DERIVE;
326+
uint8_t labelPrivate[WH_NVM_LABEL_LEN] = "ECC Private Key";
327+
328+
/* Test Case 1: Using ephemeral key (normal wolfCrypt flow) */
329+
ret = wc_ecc_init_ex(bonnieKey, NULL, devId);
325330
if (ret != 0) {
326331
WH_ERROR_PRINT("Failed to wc_ecc_init_ex %d\n", ret);
327332
} else {
328-
ret = wc_ecc_init_ex(eccPublic, NULL, devId);
333+
ret = wc_ecc_init_ex(clydeKey, NULL, devId);
329334
if (ret != 0) {
330335
WH_ERROR_PRINT("Failed to wc_ecc_init_ex %d\n", ret);
331336
} else {
332-
ret = wc_ecc_make_key(rng, TEST_ECC_KEYSIZE, eccPrivate);
337+
ret = wc_ecc_make_key(rng, TEST_ECC_KEYSIZE, bonnieKey);
333338
if (ret != 0) {
334339
WH_ERROR_PRINT("Failed to wc_ecc_make_key %d\n", ret);
335340
} else {
336-
ret = wc_ecc_make_key(rng, TEST_ECC_KEYSIZE, eccPublic);
341+
ret = wc_ecc_make_key(rng, TEST_ECC_KEYSIZE, clydeKey);
337342
if (ret != 0) {
338343
WH_ERROR_PRINT("Failed to wc_ecc_make_key %d\n", ret);
339344
} else {
340345
word32 secLen = TEST_ECC_KEYSIZE;
341-
ret = wc_ecc_shared_secret(eccPrivate, eccPublic,
342-
(byte*)shared_ab, &secLen);
346+
ret = wc_ecc_shared_secret(bonnieKey, clydeKey,
347+
(byte*)shared_ab, &secLen);
343348
if (ret != 0) {
344349
WH_ERROR_PRINT("Failed to compute secret %d\n", ret);
345350
} else {
346-
ret = wc_ecc_shared_secret(eccPublic, eccPrivate,
347-
(byte*)shared_ba, &secLen);
351+
ret = wc_ecc_shared_secret(clydeKey, bonnieKey,
352+
(byte*)shared_ba, &secLen);
348353
if (ret != 0) {
349354
WH_ERROR_PRINT("Failed to compute secret %d\n",
350355
ret);
351356
} else {
352357
if (memcmp(shared_ab, shared_ba, secLen) == 0) {
353-
WH_TEST_PRINT("ECDH SUCCESS\n");
358+
WH_TEST_PRINT("ECC ephemeral ECDH SUCCESS\n");
354359
}
355360
else {
356-
WH_ERROR_PRINT("ECDH FAILED TO MATCH\n");
361+
WH_ERROR_PRINT(
362+
"ECC ephemeral ECDH FAILED TO MATCH\n");
363+
ret = -1;
357364
}
358365
}
359366
}
360367
if (ret == 0) {
361-
/*Use the shared secret as a random hash */
368+
/* Use the shared secret as a random hash */
362369
memcpy(hash, shared_ba, sizeof(hash));
363370
word32 sigLen = sizeof(sig);
364371
ret = wc_ecc_sign_hash((void*)hash, sizeof(hash),
365372
(void*)sig, &sigLen, rng,
366-
eccPrivate);
373+
bonnieKey);
367374
if (ret != 0) {
368375
WH_ERROR_PRINT("Failed to wc_ecc_sign_hash %d\n",
369376
ret);
370377
} else {
371378
int res = 0;
372379
ret = wc_ecc_verify_hash((void*)sig, sigLen,
373380
(void*)hash, sizeof(hash),
374-
&res, eccPrivate);
381+
&res, bonnieKey);
375382
if (ret != 0) {
376383
WH_ERROR_PRINT("Failed to wc_ecc_verify_hash"
377384
" %d\n",
378385
ret);
379386
}
380387
else {
381388
if (res == 1) {
382-
WH_TEST_PRINT("ECC SIGN/VERIFY SUCCESS\n");
389+
WH_TEST_PRINT(
390+
"ECC ephemeral SIGN/VERIFY SUCCESS\n");
383391
}
384392
else {
385-
WH_ERROR_PRINT("ECC SIGN/VERIFY FAIL\n");
393+
WH_ERROR_PRINT(
394+
"ECC ephemeral SIGN/VERIFY FAIL\n");
386395
ret = -1;
387396
}
388397
}
389398
}
390399
}
391400
}
392401
}
393-
wc_ecc_free(eccPublic);
402+
wc_ecc_free(clydeKey);
403+
}
404+
wc_ecc_free(bonnieKey);
405+
}
406+
407+
/* Test Case 2: Using client export key */
408+
if (ret == 0) {
409+
memset(shared_ab, 0, sizeof(shared_ab));
410+
memset(shared_ba, 0, sizeof(shared_ba));
411+
memset(sig, 0, sizeof(sig));
412+
413+
ret = wc_ecc_init_ex(bonnieKey, NULL, WH_DEV_ID);
414+
if (ret != 0) {
415+
WH_ERROR_PRINT("Failed to wc_ecc_init_ex for export key %d\n", ret);
416+
}
417+
else {
418+
ret = wc_ecc_init_ex(clydeKey, NULL, WH_DEV_ID);
419+
if (ret != 0) {
420+
WH_ERROR_PRINT("Failed to wc_ecc_init_ex for export key %d\n",
421+
ret);
422+
}
423+
else {
424+
/* Server creates keys and exports them to client */
425+
ret = wh_Client_EccMakeExportKey(ctx, TEST_ECC_KEYSIZE,
426+
TEST_ECC_CURVE_ID, bonnieKey);
427+
if (ret != 0) {
428+
WH_ERROR_PRINT("Failed to wh_Client_EccMakeExportKey %d\n",
429+
ret);
430+
}
431+
if (ret == 0) {
432+
ret = wh_Client_EccMakeExportKey(
433+
ctx, TEST_ECC_KEYSIZE, TEST_ECC_CURVE_ID, clydeKey);
434+
if (ret != 0) {
435+
WH_ERROR_PRINT(
436+
"Failed to wh_Client_EccMakeExportKey %d\n", ret);
437+
}
438+
}
439+
/* Test ECDH with exported keys */
440+
if (ret == 0) {
441+
word32 secLen = TEST_ECC_KEYSIZE;
442+
ret = wc_ecc_shared_secret(bonnieKey, clydeKey,
443+
(byte*)shared_ab, &secLen);
444+
if (ret != 0) {
445+
WH_ERROR_PRINT(
446+
"Failed to compute export key secret %d\n", ret);
447+
}
448+
}
449+
if (ret == 0) {
450+
word32 secLen = TEST_ECC_KEYSIZE;
451+
ret = wc_ecc_shared_secret(clydeKey, bonnieKey,
452+
(byte*)shared_ba, &secLen);
453+
if (ret != 0) {
454+
WH_ERROR_PRINT(
455+
"Failed to compute export key secret %d\n", ret);
456+
}
457+
}
458+
if (ret == 0) {
459+
if (memcmp(shared_ab, shared_ba, TEST_ECC_KEYSIZE) != 0) {
460+
WH_ERROR_PRINT("ECC export key ECDH FAILED TO MATCH\n");
461+
ret = -1;
462+
}
463+
else {
464+
WH_TEST_PRINT("ECC export key ECDH SUCCESS\n");
465+
}
466+
}
467+
/* Test ECDSA sign/verify with exported keys */
468+
if (ret == 0) {
469+
memcpy(hash, shared_ba, sizeof(hash));
470+
word32 sigLen = sizeof(sig);
471+
ret = wc_ecc_sign_hash((void*)hash, sizeof(hash),
472+
(void*)sig, &sigLen, rng, bonnieKey);
473+
if (ret != 0) {
474+
WH_ERROR_PRINT("Failed to sign with export key %d\n",
475+
ret);
476+
}
477+
else {
478+
int res = 0;
479+
ret =
480+
wc_ecc_verify_hash((void*)sig, sigLen, (void*)hash,
481+
sizeof(hash), &res, bonnieKey);
482+
if (ret != 0) {
483+
WH_ERROR_PRINT(
484+
"Failed to verify with export key %d\n", ret);
485+
}
486+
else if (res != 1) {
487+
WH_ERROR_PRINT("ECC export key SIGN/VERIFY FAIL\n");
488+
ret = -1;
489+
}
490+
else {
491+
WH_TEST_PRINT(
492+
"ECC export key SIGN/VERIFY SUCCESS\n");
493+
}
494+
}
495+
}
496+
wc_ecc_free(clydeKey);
497+
}
498+
wc_ecc_free(bonnieKey);
499+
}
500+
}
501+
502+
/* Test Case 3: Using keyCache key (key stays on server)
503+
* Use only ONE cached key to avoid key cache space issues.
504+
* For ECDH, use an ephemeral peer key. */
505+
if (ret == 0) {
506+
memset(shared_ab, 0, sizeof(shared_ab));
507+
memset(shared_ba, 0, sizeof(shared_ba));
508+
memset(sig, 0, sizeof(sig));
509+
keyIdPrivate = WH_KEYID_ERASED;
510+
511+
/* Server creates and caches one key */
512+
ret = wh_Client_EccMakeCacheKey(ctx, TEST_ECC_KEYSIZE,
513+
TEST_ECC_CURVE_ID, &keyIdPrivate, flags,
514+
sizeof(labelPrivate), labelPrivate);
515+
if (ret != 0) {
516+
WH_ERROR_PRINT("Failed to wh_Client_EccMakeCacheKey %d\n", ret);
517+
}
518+
if (ret == 0) {
519+
/* Init the cached key struct and associate with server key ID */
520+
ret = wc_ecc_init_ex(bonnieKey, NULL, WH_DEV_ID);
521+
if (ret != 0) {
522+
WH_ERROR_PRINT("Failed to wc_ecc_init_ex for cache key %d\n",
523+
ret);
524+
}
525+
else {
526+
ret = wh_Client_EccSetKeyId(bonnieKey, keyIdPrivate);
527+
if (ret != 0) {
528+
WH_ERROR_PRINT("Failed to wh_Client_EccSetKeyId %d\n", ret);
529+
}
530+
/* Verify key ID was set correctly */
531+
if (ret == 0) {
532+
ret = wh_Client_EccGetKeyId(bonnieKey, &checkKeyId);
533+
if (ret != 0) {
534+
WH_ERROR_PRINT("Failed to wh_Client_EccGetKeyId %d\n",
535+
ret);
536+
}
537+
else if (checkKeyId != keyIdPrivate) {
538+
WH_ERROR_PRINT(
539+
"ECC key ID mismatch: got %u, expected %u\n",
540+
checkKeyId, keyIdPrivate);
541+
ret = -1;
542+
}
543+
}
544+
/* Set curve parameters (required since key data isn't exported)
545+
*/
546+
if (ret == 0) {
547+
ret = wc_ecc_set_curve(bonnieKey, TEST_ECC_KEYSIZE,
548+
TEST_ECC_CURVE_ID);
549+
if (ret != 0) {
550+
WH_ERROR_PRINT("Failed to wc_ecc_set_curve %d\n", ret);
551+
}
552+
}
553+
/* Create ephemeral peer key for ECDH test */
554+
if (ret == 0) {
555+
ret = wc_ecc_init_ex(clydeKey, NULL, WH_DEV_ID);
556+
if (ret != 0) {
557+
WH_ERROR_PRINT(
558+
"Failed to wc_ecc_init_ex for peer key %d\n", ret);
559+
}
560+
else {
561+
ret = wc_ecc_make_key(rng, TEST_ECC_KEYSIZE, clydeKey);
562+
if (ret != 0) {
563+
WH_ERROR_PRINT(
564+
"Failed to wc_ecc_make_key for peer %d\n", ret);
565+
}
566+
/* Test ECDH: cached key with ephemeral peer */
567+
if (ret == 0) {
568+
word32 secLen = TEST_ECC_KEYSIZE;
569+
ret = wc_ecc_shared_secret(
570+
bonnieKey, clydeKey, (byte*)shared_ab, &secLen);
571+
if (ret != 0) {
572+
WH_ERROR_PRINT(
573+
"Failed to compute cache key secret %d\n",
574+
ret);
575+
}
576+
}
577+
if (ret == 0) {
578+
word32 secLen = TEST_ECC_KEYSIZE;
579+
ret = wc_ecc_shared_secret(
580+
clydeKey, bonnieKey, (byte*)shared_ba, &secLen);
581+
if (ret != 0) {
582+
WH_ERROR_PRINT(
583+
"Failed to compute peer secret %d\n", ret);
584+
}
585+
}
586+
if (ret == 0) {
587+
if (memcmp(shared_ab, shared_ba,
588+
TEST_ECC_KEYSIZE) != 0) {
589+
WH_ERROR_PRINT(
590+
"ECC cache key ECDH FAILED TO MATCH\n");
591+
ret = -1;
592+
}
593+
else {
594+
WH_TEST_PRINT("ECC cache key ECDH SUCCESS\n");
595+
}
596+
}
597+
wc_ecc_free(clydeKey);
598+
}
599+
}
600+
/* Test ECDSA sign/verify with cached key */
601+
if (ret == 0) {
602+
memcpy(hash, shared_ba, sizeof(hash));
603+
word32 sigLen = sizeof(sig);
604+
ret = wc_ecc_sign_hash((void*)hash, sizeof(hash),
605+
(void*)sig, &sigLen, rng, bonnieKey);
606+
if (ret != 0) {
607+
WH_ERROR_PRINT("Failed to sign with cache key %d\n",
608+
ret);
609+
}
610+
else {
611+
int res = 0;
612+
ret =
613+
wc_ecc_verify_hash((void*)sig, sigLen, (void*)hash,
614+
sizeof(hash), &res, bonnieKey);
615+
if (ret != 0) {
616+
WH_ERROR_PRINT(
617+
"Failed to verify with cache key %d\n", ret);
618+
}
619+
else if (res != 1) {
620+
WH_ERROR_PRINT("ECC cache key SIGN/VERIFY FAIL\n");
621+
ret = -1;
622+
}
623+
else {
624+
WH_TEST_PRINT(
625+
"ECC cache key SIGN/VERIFY SUCCESS\n");
626+
}
627+
}
628+
}
629+
wc_ecc_free(bonnieKey);
630+
}
394631
}
395-
wc_ecc_free(eccPrivate);
632+
/* Evict server key regardless of test success */
633+
(void)wh_Client_KeyEvict(ctx, keyIdPrivate);
634+
}
635+
636+
if (ret == 0) {
637+
WH_TEST_PRINT("ECC SUCCESS\n");
396638
}
397639
return ret;
398640
}

0 commit comments

Comments
 (0)