2828#include <wolftpm/tpm2.h>
2929#include <wolftpm/tpm2_wrap.h>
3030#include <wolftpm/tpm2_param_enc.h>
31+ #include <wolftpm/tpm2_asn.h>
3132
3233#include <hal/tpm_io.h>
3334#include <examples/tpm_test.h>
@@ -100,7 +101,8 @@ static void test_wolfTPM2_Init(void)
100101 AssertIntNE (rc , 0 );
101102 /* Test second argument, TPM2 IO Callbacks */
102103 rc = wolfTPM2_Init (& dev , NULL , NULL );
103- #if defined(WOLFTPM_LINUX_DEV ) || defined(WOLFTPM_SWTPM ) || defined(WOLFTPM_WINAPI )
104+ #if defined(WOLFTPM_LINUX_DEV ) || defined(WOLFTPM_SWTPM ) || \
105+ defined(WOLFTPM_WINAPI )
104106 /* Custom IO Callbacks are not needed for Linux TIS driver */
105107 AssertIntEQ (rc , 0 );
106108#else
@@ -275,11 +277,12 @@ static void test_TPM2_PCRSel(void)
275277
276278 /* Test bad case - invalid PCR */
277279 XMEMSET (& pcr , 0 , sizeof (pcr ));
278- pcrArray [0 ] = PCR_SELECT_MAX + 1 ;
280+ pcrArray [0 ] = PCR_LAST + 1 ;
279281 TPM2_SetupPCRSelArray (& pcr , TPM_ALG_SHA256 , pcrArray , 1 );
280282 if (pcr .count != 0 ) {
281283 rc = BAD_FUNC_ARG ;
282284 }
285+ AssertIntEQ (rc , 0 );
283286
284287 /* Test bad case - too many hash algorithms */
285288 XMEMSET (& pcr , 0 , sizeof (pcr ));
@@ -294,6 +297,7 @@ static void test_TPM2_PCRSel(void)
294297 if (pcr .count != HASH_COUNT ) {
295298 rc = BAD_FUNC_ARG ;
296299 }
300+ AssertIntEQ (rc , 0 );
297301
298302 printf ("Test TPM Wrapper:\tPCR Select Array:\t%s\n" ,
299303 rc == 0 ? "Passed" : "Failed" );
@@ -345,7 +349,8 @@ static void test_TPM2_KDFa(void)
345349 0xd7 , 0x04 , 0xb6 , 0x9a , 0x90 , 0x2e , 0x9a , 0xde , 0x84 , 0xc4 };
346350#endif
347351
348- rc = TPM2_KDFa (TPM_ALG_SHA256 , & keyIn , label , & contextU , & contextV , key , keyIn .size );
352+ rc = TPM2_KDFa (TPM_ALG_SHA256 , & keyIn , label , & contextU , & contextV , key ,
353+ keyIn .size );
349354#ifdef WOLFTPM2_NO_WOLFCRYPT
350355 AssertIntEQ (NOT_COMPILED_IN , rc );
351356#else
@@ -396,6 +401,172 @@ static void test_wolfTPM2_CSR(void)
396401#endif
397402}
398403
404+ #if !defined(WOLFTPM2_NO_WOLFCRYPT ) && defined(HAVE_ECC ) && \
405+ !defined(WOLFTPM2_NO_ASN )
406+ static void test_wolfTPM2_EccSignVerifyDig (WOLFTPM2_DEV * dev ,
407+ WOLFTPM2_KEY * storageKey , const byte * digest , int digestSz ,
408+ TPM_ECC_CURVE curve , TPMI_ALG_HASH hashAlg )
409+ {
410+ int rc ;
411+ int verifyRes = 0 ;
412+ WOLFTPM2_KEY eccKey ;
413+ TPMT_PUBLIC publicTemplate ;
414+ byte sigRs [MAX_ECC_BYTES * 2 ];
415+ word32 sigRsSz = (word32 )sizeof (sigRs );
416+ byte sig [ECC_MAX_SIG_SIZE ];
417+ word32 sigSz ;
418+ byte * r , * s ;
419+ word32 rLen , sLen ;
420+ ecc_key wolfKey ;
421+ int curveSize = TPM2_GetCurveSize (curve );
422+
423+ /* -- Use TPM key to sign and verify with wolfCrypt -- */
424+ /* Create ECC key for signing */
425+ rc = wolfTPM2_GetKeyTemplate_ECC_ex (& publicTemplate , hashAlg ,
426+ (TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth |
427+ TPMA_OBJECT_sign | TPMA_OBJECT_noDA ),
428+ curve , TPM_ALG_ECDSA , hashAlg );
429+ AssertIntEQ (rc , 0 );
430+ rc = wolfTPM2_CreateAndLoadKey (dev , & eccKey , & storageKey -> handle ,
431+ & publicTemplate , (byte * )gKeyAuth , sizeof (gKeyAuth )- 1 );
432+ if ((rc & TPM_RC_HASH ) == TPM_RC_HASH ) {
433+ printf ("Hash type not supported... Skipping\n" );
434+ return ;
435+ }
436+ AssertIntEQ (rc , 0 );
437+
438+ /* Sign with TPM */
439+ rc = wolfTPM2_SignHashScheme (dev , & eccKey , digest , digestSz ,
440+ sigRs , (int * )& sigRsSz , TPM_ALG_ECDSA , hashAlg );
441+ AssertIntEQ (rc , 0 );
442+
443+ /* Make sure leading zero's not required are trimmed */
444+ rLen = sLen = sigRsSz / 2 ;
445+ r = & sigRs [0 ];
446+ s = & sigRs [rLen ];
447+ r = TPM2_ASN_TrimZeros (r , & rLen );
448+ s = TPM2_ASN_TrimZeros (s , & sLen );
449+
450+ /* Encode ECDSA Header */
451+ sigSz = (word32 )sizeof (sig );
452+ rc = wc_ecc_rs_raw_to_sig (r , rLen , s , sLen , sig , & sigSz );
453+ AssertIntEQ (rc , 0 );
454+
455+ /* Initialize wolfCrypt ECC key */
456+ rc = wc_ecc_init (& wolfKey );
457+ AssertIntEQ (rc , 0 );
458+
459+ /* Convert TPM key to wolfCrypt key for verification */
460+ rc = wolfTPM2_EccKey_TpmToWolf (dev , & eccKey , & wolfKey );
461+ AssertIntEQ (rc , 0 );
462+
463+ /* Verify TPM signature with wolfCrypt */
464+ rc = wc_ecc_verify_hash (sig , sigSz , digest , digestSz , & verifyRes , & wolfKey );
465+ AssertIntEQ (rc , 0 );
466+ AssertIntEQ (verifyRes , 1 ); /* 1 indicates successful verification */
467+
468+ /* Cleanup first wolfCrypt key */
469+ wc_ecc_free (& wolfKey );
470+ wolfTPM2_UnloadHandle (dev , & eccKey .handle );
471+
472+
473+ /* -- Use wolfCrypt key to sign and verify with TPM -- */
474+ /* Initialize new wolfCrypt ECC key */
475+ rc = wc_ecc_init (& wolfKey );
476+ AssertIntEQ (rc , 0 );
477+
478+ /* Generate new ECC key with wolfCrypt */
479+ rc = wc_ecc_make_key (wolfTPM2_GetRng (dev ), curveSize , & wolfKey );
480+ AssertIntEQ (rc , 0 );
481+
482+ /* Sign with wolfCrypt */
483+ sigSz = (word32 )sizeof (sig );
484+ rc = wc_ecc_sign_hash (digest , digestSz , sig , & sigSz , wolfTPM2_GetRng (dev ),
485+ & wolfKey );
486+ AssertIntEQ (rc , 0 );
487+
488+ /* Decode ECDSA Header */
489+ r = sigRs ;
490+ s = & sigRs [MAX_ECC_BYTES ];
491+ rLen = sLen = MAX_ECC_BYTES ;
492+ rc = wc_ecc_sig_to_rs (sig ,
493+ sigSz , r , & rLen , s , & sLen );
494+ AssertIntEQ (rc , 0 );
495+
496+ /* Convert wolfCrypt key to TPM key for verification */
497+ rc = wolfTPM2_EccKey_WolfToTpm (dev , & wolfKey , & eccKey );
498+ AssertIntEQ (rc , 0 );
499+
500+ /* combine R and S at key size (zero pad leading) */
501+ XMEMCPY (& sigRs [curveSize - rLen ], r , rLen );
502+ XMEMSET (& sigRs [0 ], 0 , curveSize - rLen );
503+ XMEMCPY (& sigRs [curveSize + (curveSize - sLen )], s , sLen );
504+ XMEMSET (& sigRs [curveSize ], 0 , curveSize - sLen );
505+
506+ /* Verify wolfCrypt signature with TPM */
507+ rc = wolfTPM2_VerifyHashScheme (dev , & eccKey , sigRs , curveSize * 2 ,
508+ digest , digestSz , TPM_ALG_ECDSA , hashAlg );
509+ AssertIntEQ (rc , 0 );
510+
511+ /* Cleanup */
512+ wc_ecc_free (& wolfKey );
513+ wolfTPM2_UnloadHandle (dev , & eccKey .handle );
514+
515+ printf ("Test TPM Wrapper:\t"
516+ "Sign/Verify (DigSz=%d, CurveSz=%d, Hash=%s):"
517+ "\t%s\n" ,
518+ digestSz , TPM2_GetCurveSize (curve ), TPM2_GetAlgName (hashAlg ),
519+ rc == 0 ? "Passed" : "Failed" );
520+ }
521+
522+ /* Test with smaller, same and larger digest sizes using different ECC curves.
523+ * Interop sign and verify with wolfCrypt and TPM */
524+ static void test_wolfTPM2_EccSignVerify (void )
525+ {
526+ int rc , i ;
527+ byte digest [TPM_MAX_DIGEST_SIZE ];
528+ WOLFTPM2_DEV dev ;
529+ WOLFTPM2_KEY storageKey ;
530+
531+ /* Initialize TPM */
532+ rc = wolfTPM2_Init (& dev , TPM2_IoCb , NULL );
533+ AssertIntEQ (rc , 0 );
534+
535+ /* Create storage key */
536+ rc = wolfTPM2_CreateSRK (& dev , & storageKey , TPM_ALG_ECC ,
537+ (byte * )gStorageKeyAuth , sizeof (gStorageKeyAuth )- 1 );
538+ AssertIntEQ (rc , 0 );
539+
540+
541+ for (i = 0 ; i < (int )sizeof (digest ); i ++ ) {
542+ digest [i ] = (byte )i ;
543+ }
544+
545+ test_wolfTPM2_EccSignVerifyDig (& dev , & storageKey , digest , 20 ,
546+ TPM_ECC_NIST_P256 , TPM_ALG_SHA256 );
547+ test_wolfTPM2_EccSignVerifyDig (& dev , & storageKey , digest , 32 ,
548+ TPM_ECC_NIST_P256 , TPM_ALG_SHA256 );
549+ test_wolfTPM2_EccSignVerifyDig (& dev , & storageKey , digest , 48 ,
550+ TPM_ECC_NIST_P256 , TPM_ALG_SHA256 );
551+ test_wolfTPM2_EccSignVerifyDig (& dev , & storageKey , digest , 64 ,
552+ TPM_ECC_NIST_P256 , TPM_ALG_SHA256 );
553+
554+ #if (defined(HAVE_ECC384 ) || defined(HAVE_ALL_CURVES )) && ECC_MIN_KEY_SZ <= 384
555+ test_wolfTPM2_EccSignVerifyDig (& dev , & storageKey , digest , 20 ,
556+ TPM_ECC_NIST_P384 , TPM_ALG_SHA384 );
557+ test_wolfTPM2_EccSignVerifyDig (& dev , & storageKey , digest , 32 ,
558+ TPM_ECC_NIST_P384 , TPM_ALG_SHA384 );
559+ test_wolfTPM2_EccSignVerifyDig (& dev , & storageKey , digest , 48 ,
560+ TPM_ECC_NIST_P384 , TPM_ALG_SHA384 );
561+ test_wolfTPM2_EccSignVerifyDig (& dev , & storageKey , digest , 64 ,
562+ TPM_ECC_NIST_P384 , TPM_ALG_SHA384 );
563+ #endif
564+
565+ wolfTPM2_UnloadHandle (& dev , & storageKey .handle );
566+ wolfTPM2_Cleanup (& dev );
567+ }
568+ #endif
569+
399570#if !defined(WOLFTPM2_NO_WOLFCRYPT ) && defined(WOLFTPM2_PEM_DECODE ) && \
400571 !defined(NO_RSA )
401572static WOLFTPM2_KEY authKey ; /* also used for test_wolfTPM2_PCRPolicy */
@@ -479,7 +650,8 @@ static void test_wolfTPM2_PCRPolicy(void)
479650 digest , & digestSz , NULL , 0 );
480651 AssertIntEQ (rc , 0 );
481652
482- AssertIntEQ (XMEMCMP (digest , expectedPolicyAuth , sizeof (expectedPolicyAuth )), 0 );
653+ AssertIntEQ (XMEMCMP (digest , expectedPolicyAuth , sizeof (expectedPolicyAuth )),
654+ 0 );
483655
484656 rc = wolfTPM2_ResetPCR (& dev , pcrIndex );
485657 AssertIntEQ (rc , 0 );
@@ -679,6 +851,10 @@ int unit_tests(int argc, char *argv[])
679851 #endif
680852 test_wolfTPM2_KeyBlob (TPM_ALG_RSA );
681853 test_wolfTPM2_KeyBlob (TPM_ALG_ECC );
854+ #if !defined(WOLFTPM2_NO_WOLFCRYPT ) && defined(HAVE_ECC ) && \
855+ !defined(WOLFTPM2_NO_ASN )
856+ test_wolfTPM2_EccSignVerify ();
857+ #endif
682858 test_wolfTPM2_Cleanup ();
683859 test_wolfTPM2_thread_local_storage ();
684860#endif /* !WOLFTPM2_NO_WRAPPER */
0 commit comments