@@ -311,89 +311,333 @@ static int whTest_CryptoRsa(whClientContext* ctx, int devId, WC_RNG* rng)
311311#ifdef HAVE_ECC
312312static 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