Skip to content

Commit 1458001

Browse files
authored
Merge pull request #443 from dgarske/zd20777_ecdsa
Fix for wolfTPM2_SignHash to return padded r/s
2 parents ca6379e + 8c5c6cb commit 1458001

File tree

4 files changed

+122
-59
lines changed

4 files changed

+122
-59
lines changed

src/tpm2.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6111,6 +6111,12 @@ const char* TPM2_GetAlgName(TPM_ALG_ID alg)
61116111
return "SHA384";
61126112
case TPM_ALG_SHA512:
61136113
return "SHA512";
6114+
case TPM_ALG_SHA3_256:
6115+
return "SHA3_256";
6116+
case TPM_ALG_SHA3_384:
6117+
return "SHA3_384";
6118+
case TPM_ALG_SHA3_512:
6119+
return "SHA3_512";
61146120
case TPM_ALG_NULL:
61156121
return "NULL";
61166122
case TPM_ALG_SM3_256:

src/tpm2_cryptocb.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -328,8 +328,6 @@ int wolfTPM2_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
328328
rLen = sLen = rsLen / 2;
329329
r = &sigRS[0];
330330
s = &sigRS[rLen];
331-
r = TPM2_ASN_TrimZeros(r, &rLen);
332-
s = TPM2_ASN_TrimZeros(s, &sLen);
333331

334332
/* Encode ECDSA Header */
335333
rc = wc_ecc_rs_raw_to_sig(r, rLen, s, sLen,
@@ -355,9 +353,9 @@ int wolfTPM2_CryptoDevCb(int devId, wc_CryptoInfo* info, void* ctx)
355353
if (rc == 0) {
356354
/* combine R and S at key size (zero pad leading) */
357355
word32 keySz = wc_ecc_size(info->pk.eccverify.key);
358-
XMEMCPY(&sigRS[keySz-rLen], r, rLen);
356+
XMEMMOVE(&sigRS[keySz-rLen], r, rLen);
359357
XMEMSET(&sigRS[0], 0, keySz-rLen);
360-
XMEMCPY(&sigRS[keySz + (keySz-sLen)], s, sLen);
358+
XMEMMOVE(&sigRS[keySz + (keySz-sLen)], s, sLen);
361359
XMEMSET(&sigRS[keySz], 0, keySz-sLen);
362360
rc = wolfTPM2_VerifyHash(tlsCtx->dev, &eccPub,
363361
sigRS, keySz*2,

src/tpm2_wrap.c

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4080,32 +4080,37 @@ int wolfTPM2_SignHashScheme(WOLFTPM2_DEV* dev, WOLFTPM2_KEY* key,
40804080
}
40814081

40824082
if (key->pub.publicArea.type == TPM_ALG_ECC) {
4083+
TPMS_SIGNATURE_ECDSA* ecdsa = &signOut.signature.signature.ecdsa;
4084+
40834085
/* Assemble R and S into signature (R then S) */
4084-
sigOutSz = signOut.signature.signature.ecdsa.signatureR.size +
4085-
signOut.signature.signature.ecdsa.signatureS.size;
4086-
if (sigOutSz > *sigSz) {
4086+
sigOutSz = curveSize * 2;
4087+
if (sigOutSz > *sigSz ||
4088+
curveSize > ecdsa->signatureR.size ||
4089+
curveSize > ecdsa->signatureS.size) {
40874090
#ifdef DEBUG_WOLFTPM
4088-
printf("TPM2_Sign: ECC result truncated %d -> %d\n",
4091+
printf("TPM2_Sign: ECC result buffer too small %d -> %d\n",
40894092
sigOutSz, *sigSz);
40904093
#endif
4091-
sigOutSz = *sigSz;
4094+
return BUFFER_E;
40924095
}
4093-
XMEMCPY(sig,
4094-
signOut.signature.signature.ecdsa.signatureR.buffer,
4095-
signOut.signature.signature.ecdsa.signatureR.size);
4096-
XMEMCPY(sig + signOut.signature.signature.ecdsa.signatureR.size,
4097-
signOut.signature.signature.ecdsa.signatureS.buffer,
4098-
signOut.signature.signature.ecdsa.signatureS.size);
4096+
XMEMCPY(sig, ecdsa->signatureR.buffer,
4097+
ecdsa->signatureR.size);
4098+
XMEMSET(sig + ecdsa->signatureR.size, 0,
4099+
curveSize - ecdsa->signatureR.size);
4100+
XMEMCPY(sig + curveSize, ecdsa->signatureS.buffer,
4101+
ecdsa->signatureS.size);
4102+
XMEMSET(sig + curveSize + ecdsa->signatureS.size, 0,
4103+
curveSize - ecdsa->signatureS.size);
40994104
}
41004105
else if (key->pub.publicArea.type == TPM_ALG_RSA) {
41014106
/* RSA signature size and buffer (with padding depending on scheme) */
41024107
sigOutSz = signOut.signature.signature.rsassa.sig.size;
41034108
if (sigOutSz > *sigSz) {
41044109
#ifdef DEBUG_WOLFTPM
4105-
printf("TPM2_Sign: RSA result truncated %d -> %d\n",
4110+
printf("TPM2_Sign: RSA result buffer too small %d -> %d\n",
41064111
sigOutSz, *sigSz);
41074112
#endif
4108-
sigOutSz = *sigSz;
4113+
return BUFFER_E;
41094114
}
41104115
XMEMCPY(sig, signOut.signature.signature.rsassa.sig.buffer, sigOutSz);
41114116
}
@@ -7368,7 +7373,7 @@ static int CSR_MakeAndSign(WOLFTPM2_DEV* dev, WOLFTPM2_CSR* csr, CSRKey* key,
73687373
}
73697374
#else
73707375
#ifdef DEBUG_WOLFTPM
7371-
printf("CSR_MakeAndSign PEM not supported\n")
7376+
printf("CSR_MakeAndSign PEM not supported\n");
73727377
#endif
73737378
rc = NOT_COMPILED_IN;
73747379
#endif

tests/unit_tests.c

Lines changed: 95 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -409,13 +409,16 @@ static void test_wolfTPM2_CSR(void)
409409

410410
#if !defined(WOLFTPM2_NO_WOLFCRYPT) && defined(HAVE_ECC) && \
411411
!defined(WOLFTPM2_NO_ASN)
412+
#define FLAGS_USE_WOLFCRYPT (1 << 0)
413+
#define FLAGS_USE_CRYPTO_CB (1 << 1)
414+
#define FLAGS_USE_PK_CB (1 << 2) /* requires TLS layer to test */
412415
static void test_wolfTPM2_EccSignVerifyDig(WOLFTPM2_DEV* dev,
413416
WOLFTPM2_KEY* storageKey, const byte* digest, int digestSz,
414-
TPM_ECC_CURVE curve, TPMI_ALG_HASH hashAlg)
417+
TPM_ECC_CURVE curve, TPMI_ALG_HASH hashAlg, int flags)
415418
{
416419
int rc;
417420
int verifyRes = 0;
418-
WOLFTPM2_KEY eccKey;
421+
WOLFTPM2_KEYBLOB eccKey;
419422
TPMT_PUBLIC publicTemplate;
420423
byte sigRs[MAX_ECC_BYTES*2];
421424
word32 sigRsSz = (word32)sizeof(sigRs);
@@ -425,6 +428,21 @@ static void test_wolfTPM2_EccSignVerifyDig(WOLFTPM2_DEV* dev,
425428
word32 rLen, sLen;
426429
ecc_key wolfKey;
427430
int curveSize = TPM2_GetCurveSize(curve);
431+
#ifdef WOLF_CRYPTO_CB
432+
int tpmDevId = INVALID_DEVID;
433+
TpmCryptoDevCtx tpmCtx;
434+
435+
XMEMSET(&tpmCtx, 0, sizeof(tpmCtx));
436+
tpmCtx.dev = dev;
437+
tpmCtx.ecdsaKey = &eccKey;
438+
tpmCtx.storageKey = storageKey;
439+
440+
if (flags & FLAGS_USE_CRYPTO_CB) {
441+
rc = wolfTPM2_SetCryptoDevCb(dev, wolfTPM2_CryptoDevCb, &tpmCtx,
442+
&tpmDevId);
443+
AssertIntEQ(rc, 0);
444+
}
445+
#endif
428446

429447
/* -- Use TPM key to sign and verify with wolfCrypt -- */
430448
/* Create ECC key for signing */
@@ -433,37 +451,45 @@ static void test_wolfTPM2_EccSignVerifyDig(WOLFTPM2_DEV* dev,
433451
TPMA_OBJECT_sign | TPMA_OBJECT_noDA),
434452
curve, TPM_ALG_ECDSA, hashAlg);
435453
AssertIntEQ(rc, 0);
436-
rc = wolfTPM2_CreateAndLoadKey(dev, &eccKey, &storageKey->handle,
454+
455+
/* Use create key and load key directly instead to make
456+
* sure the private portion is populated */
457+
rc = wolfTPM2_CreateKey(dev, &eccKey, &storageKey->handle,
437458
&publicTemplate, (byte*)gKeyAuth, sizeof(gKeyAuth)-1);
459+
if (rc == TPM_RC_SUCCESS) {
460+
rc = wolfTPM2_LoadKey(dev, &eccKey, &storageKey->handle);
461+
}
438462
if ((rc & TPM_RC_HASH) == TPM_RC_HASH) {
439463
printf("Hash type not supported... Skipping\n");
440464
return;
441465
}
466+
if ((rc & TPM_RC_CURVE) == TPM_RC_CURVE) {
467+
printf("Curve not supported... Skipping\n");
468+
return;
469+
}
442470
AssertIntEQ(rc, 0);
443471

444472
/* Sign with TPM */
445-
rc = wolfTPM2_SignHashScheme(dev, &eccKey, digest, digestSz,
473+
rc = wolfTPM2_SignHashScheme(dev, (WOLFTPM2_KEY*)&eccKey, digest, digestSz,
446474
sigRs, (int*)&sigRsSz, TPM_ALG_ECDSA, hashAlg);
447475
AssertIntEQ(rc, 0);
448476

449477
/* Make sure leading zero's not required are trimmed */
450478
rLen = sLen = sigRsSz / 2;
451479
r = &sigRs[0];
452480
s = &sigRs[rLen];
453-
r = TPM2_ASN_TrimZeros(r, &rLen);
454-
s = TPM2_ASN_TrimZeros(s, &sLen);
455481

456482
/* Encode ECDSA Header */
457483
sigSz = (word32)sizeof(sig);
458484
rc = wc_ecc_rs_raw_to_sig(r, rLen, s, sLen, sig, &sigSz);
459485
AssertIntEQ(rc, 0);
460486

461487
/* Initialize wolfCrypt ECC key */
462-
rc = wc_ecc_init(&wolfKey);
488+
rc = wc_ecc_init_ex(&wolfKey, NULL, tpmDevId);
463489
AssertIntEQ(rc, 0);
464490

465491
/* Convert TPM key to wolfCrypt key for verification */
466-
rc = wolfTPM2_EccKey_TpmToWolf(dev, &eccKey, &wolfKey);
492+
rc = wolfTPM2_EccKey_TpmToWolf(dev, (WOLFTPM2_KEY*)&eccKey, &wolfKey);
467493
AssertIntEQ(rc, 0);
468494

469495
/* Verify TPM signature with wolfCrypt */
@@ -474,11 +500,13 @@ static void test_wolfTPM2_EccSignVerifyDig(WOLFTPM2_DEV* dev,
474500
/* Cleanup first wolfCrypt key */
475501
wc_ecc_free(&wolfKey);
476502
wolfTPM2_UnloadHandle(dev, &eccKey.handle);
477-
503+
#ifdef WOLF_CRYPTO_CB
504+
tpmCtx.ecdsaKey = NULL; /* create new one */
505+
#endif
478506

479507
/* -- Use wolfCrypt key to sign and verify with TPM -- */
480508
/* Initialize new wolfCrypt ECC key */
481-
rc = wc_ecc_init(&wolfKey);
509+
rc = wc_ecc_init_ex(&wolfKey, NULL, tpmDevId);
482510
AssertIntEQ(rc, 0);
483511

484512
/* Generate new ECC key with wolfCrypt */
@@ -490,17 +518,17 @@ static void test_wolfTPM2_EccSignVerifyDig(WOLFTPM2_DEV* dev,
490518
rc = wc_ecc_sign_hash(digest, digestSz, sig, &sigSz, wolfTPM2_GetRng(dev),
491519
&wolfKey);
492520
AssertIntEQ(rc, 0);
521+
wolfTPM2_UnloadHandle(dev, &eccKey.handle);
493522

494523
/* Decode ECDSA Header */
495524
r = sigRs;
496525
s = &sigRs[MAX_ECC_BYTES];
497526
rLen = sLen = MAX_ECC_BYTES;
498-
rc = wc_ecc_sig_to_rs(sig,
499-
sigSz, r, &rLen, s, &sLen);
527+
rc = wc_ecc_sig_to_rs(sig, sigSz, r, &rLen, s, &sLen);
500528
AssertIntEQ(rc, 0);
501529

502530
/* Convert wolfCrypt key to TPM key for verification */
503-
rc = wolfTPM2_EccKey_WolfToTpm(dev, &wolfKey, &eccKey);
531+
rc = wolfTPM2_EccKey_WolfToTpm(dev, &wolfKey, (WOLFTPM2_KEY*)&eccKey);
504532
AssertIntEQ(rc, 0);
505533

506534
/* combine R and S at key size (zero pad leading) */
@@ -510,27 +538,73 @@ static void test_wolfTPM2_EccSignVerifyDig(WOLFTPM2_DEV* dev,
510538
XMEMSET(&sigRs[curveSize], 0, curveSize-sLen);
511539

512540
/* Verify wolfCrypt signature with TPM */
513-
rc = wolfTPM2_VerifyHashScheme(dev, &eccKey, sigRs, curveSize*2,
514-
digest, digestSz, TPM_ALG_ECDSA, hashAlg);
541+
rc = wolfTPM2_VerifyHashScheme(dev, (WOLFTPM2_KEY*)&eccKey, sigRs,
542+
curveSize*2, digest, digestSz, TPM_ALG_ECDSA, hashAlg);
515543
AssertIntEQ(rc, 0);
516544

517545
/* Cleanup */
518546
wc_ecc_free(&wolfKey);
519547
wolfTPM2_UnloadHandle(dev, &eccKey.handle);
520548

521549
printf("Test TPM Wrapper:\t"
522-
"Sign/Verify (DigSz=%d, CurveSz=%d, Hash=%s):"
550+
"Sign/Verify (DigSz=%d, CurveSz=%d, Hash=%s, Flags=%s):"
523551
"\t%s\n",
524552
digestSz, TPM2_GetCurveSize(curve), TPM2_GetAlgName(hashAlg),
553+
(flags & FLAGS_USE_CRYPTO_CB) ? "Crypto CB" : "",
525554
rc == 0 ? "Passed" : "Failed");
555+
556+
if (flags & FLAGS_USE_CRYPTO_CB) {
557+
wolfTPM2_ClearCryptoDevCb(dev, tpmDevId);
558+
}
559+
}
560+
561+
static void test_wolfTPM2_EccSignVerify_All(WOLFTPM2_DEV* dev,
562+
WOLFTPM2_KEY* storageKey, int flags)
563+
{
564+
int i;
565+
byte digest[TPM_MAX_DIGEST_SIZE];
566+
567+
for (i = 0; i < (int)sizeof(digest); i++) {
568+
digest[i] = (byte)i;
569+
}
570+
571+
test_wolfTPM2_EccSignVerifyDig(dev, storageKey, digest, 20,
572+
TPM_ECC_NIST_P256, TPM_ALG_SHA256, flags);
573+
test_wolfTPM2_EccSignVerifyDig(dev, storageKey, digest, 32,
574+
TPM_ECC_NIST_P256, TPM_ALG_SHA256, flags);
575+
test_wolfTPM2_EccSignVerifyDig(dev, storageKey, digest, 48,
576+
TPM_ECC_NIST_P256, TPM_ALG_SHA256, flags);
577+
test_wolfTPM2_EccSignVerifyDig(dev, storageKey, digest, 64,
578+
TPM_ECC_NIST_P256, TPM_ALG_SHA256, flags);
579+
580+
#if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
581+
test_wolfTPM2_EccSignVerifyDig(dev, storageKey, digest, 20,
582+
TPM_ECC_NIST_P384, TPM_ALG_SHA384, flags);
583+
test_wolfTPM2_EccSignVerifyDig(dev, storageKey, digest, 32,
584+
TPM_ECC_NIST_P384, TPM_ALG_SHA384, flags);
585+
test_wolfTPM2_EccSignVerifyDig(dev, storageKey, digest, 48,
586+
TPM_ECC_NIST_P384, TPM_ALG_SHA384, flags);
587+
test_wolfTPM2_EccSignVerifyDig(dev, storageKey, digest, 64,
588+
TPM_ECC_NIST_P384, TPM_ALG_SHA384, flags);
589+
#endif
590+
591+
#if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 521
592+
test_wolfTPM2_EccSignVerifyDig(dev, storageKey, digest, 20,
593+
TPM_ECC_NIST_P521, TPM_ALG_SHA512, flags);
594+
test_wolfTPM2_EccSignVerifyDig(dev, storageKey, digest, 32,
595+
TPM_ECC_NIST_P521, TPM_ALG_SHA512, flags);
596+
test_wolfTPM2_EccSignVerifyDig(dev, storageKey, digest, 48,
597+
TPM_ECC_NIST_P521, TPM_ALG_SHA512, flags);
598+
test_wolfTPM2_EccSignVerifyDig(dev, storageKey, digest, 64,
599+
TPM_ECC_NIST_P521, TPM_ALG_SHA512, flags);
600+
#endif
526601
}
527602

528603
/* Test with smaller, same and larger digest sizes using different ECC curves.
529604
* Interop sign and verify with wolfCrypt and TPM */
530605
static void test_wolfTPM2_EccSignVerify(void)
531606
{
532-
int rc, i;
533-
byte digest[TPM_MAX_DIGEST_SIZE];
607+
int rc;
534608
WOLFTPM2_DEV dev;
535609
WOLFTPM2_KEY storageKey;
536610

@@ -543,29 +617,9 @@ static void test_wolfTPM2_EccSignVerify(void)
543617
(byte*)gStorageKeyAuth, sizeof(gStorageKeyAuth)-1);
544618
AssertIntEQ(rc, 0);
545619

546-
547-
for (i = 0; i < (int)sizeof(digest); i++) {
548-
digest[i] = (byte)i;
549-
}
550-
551-
test_wolfTPM2_EccSignVerifyDig(&dev, &storageKey, digest, 20,
552-
TPM_ECC_NIST_P256, TPM_ALG_SHA256);
553-
test_wolfTPM2_EccSignVerifyDig(&dev, &storageKey, digest, 32,
554-
TPM_ECC_NIST_P256, TPM_ALG_SHA256);
555-
test_wolfTPM2_EccSignVerifyDig(&dev, &storageKey, digest, 48,
556-
TPM_ECC_NIST_P256, TPM_ALG_SHA256);
557-
test_wolfTPM2_EccSignVerifyDig(&dev, &storageKey, digest, 64,
558-
TPM_ECC_NIST_P256, TPM_ALG_SHA256);
559-
560-
#if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 384
561-
test_wolfTPM2_EccSignVerifyDig(&dev, &storageKey, digest, 20,
562-
TPM_ECC_NIST_P384, TPM_ALG_SHA384);
563-
test_wolfTPM2_EccSignVerifyDig(&dev, &storageKey, digest, 32,
564-
TPM_ECC_NIST_P384, TPM_ALG_SHA384);
565-
test_wolfTPM2_EccSignVerifyDig(&dev, &storageKey, digest, 48,
566-
TPM_ECC_NIST_P384, TPM_ALG_SHA384);
567-
test_wolfTPM2_EccSignVerifyDig(&dev, &storageKey, digest, 64,
568-
TPM_ECC_NIST_P384, TPM_ALG_SHA384);
620+
test_wolfTPM2_EccSignVerify_All(&dev, &storageKey, 0);
621+
#ifdef WOLF_CRYPTO_CB
622+
test_wolfTPM2_EccSignVerify_All(&dev, &storageKey, FLAGS_USE_CRYPTO_CB);
569623
#endif
570624

571625
wolfTPM2_UnloadHandle(&dev, &storageKey.handle);

0 commit comments

Comments
 (0)