Skip to content

Commit 54cf494

Browse files
authored
Merge pull request #257 from wolfSSL/ECC-test
Expand ECC tests to cover export and cache key cases
2 parents 6de59e0 + c9153e3 commit 54cf494

File tree

1 file changed

+266
-22
lines changed

1 file changed

+266
-22
lines changed

test/wh_test_crypto.c

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

0 commit comments

Comments
 (0)