Skip to content

Commit 233bd33

Browse files
authored
Merge pull request #315 from dgarske/keyblob_tests
Added tests for keyblob buffer export/import and support for getting sizes
2 parents c1930a4 + 4a48fb3 commit 233bd33

File tree

4 files changed

+129
-19
lines changed

4 files changed

+129
-19
lines changed

examples/tpm_test_keys.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ int writeBin(const char* filename, const byte *buf, word32 bufSz)
5252
XFILE fp = NULL;
5353
size_t fileSz = 0;
5454

55-
fp = XFOPEN(filename, "wt");
55+
fp = XFOPEN(filename, "wb");
5656
if (fp != XBADFILE) {
5757
fileSz = XFWRITE(buf, 1, bufSz, fp);
5858
/* sanity check */

src/tpm2_wrap.c

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -310,14 +310,14 @@ TPM_HANDLE wolfTPM2_GetHandleValue(WOLFTPM2_HANDLE* handle)
310310
}
311311

312312
int wolfTPM2_GetKeyBlobAsBuffer(byte *buffer, word32 bufferSz,
313-
WOLFTPM2_KEYBLOB* key)
313+
WOLFTPM2_KEYBLOB* key)
314314
{
315315
int rc = 0;
316316
int sz = 0;
317317
byte pubAreaBuffer[sizeof(TPM2B_PUBLIC)];
318318
int pubAreaSize;
319319

320-
if ((buffer == NULL) || (bufferSz <= 0) || (key == NULL)) {
320+
if (key == NULL) {
321321
return BAD_FUNC_ARG;
322322
}
323323

@@ -335,14 +335,22 @@ int wolfTPM2_GetKeyBlobAsBuffer(byte *buffer, word32 bufferSz,
335335
return BUFFER_E;
336336
}
337337

338-
if (bufferSz < sizeof(key->pub.size) + sizeof(UINT16) + key->pub.size +
339-
sizeof(UINT16) + key->priv.size) {
338+
/* calculate actual size */
339+
sz = sizeof(key->pub.size) + sizeof(UINT16) + key->pub.size +
340+
sizeof(UINT16) + key->priv.size;
341+
342+
/* return size only */
343+
if (buffer == NULL) {
344+
return sz;
345+
346+
}
347+
if ((int)bufferSz < sz) {
340348
return BUFFER_E;
341349
}
342350

343351
/* Write size marker for the public part */
344-
XMEMCPY(buffer + sz, &key->pub.size, sizeof(key->pub.size));
345-
sz += sizeof(key->pub.size);
352+
XMEMCPY(buffer, &key->pub.size, sizeof(key->pub.size));
353+
sz = sizeof(key->pub.size);
346354

347355
/* Write the public part with bytes aligned */
348356
XMEMCPY(buffer + sz, pubAreaBuffer, sizeof(UINT16) + key->pub.size);
@@ -353,8 +361,8 @@ int wolfTPM2_GetKeyBlobAsBuffer(byte *buffer, word32 bufferSz,
353361
sz += sizeof(UINT16) + key->priv.size;
354362

355363
#ifdef WOLFTPM_DEBUG_VERBOSE
364+
printf("Get KeyBlob: %d bytes\n", (int)sz);
356365
TPM2_PrintBin(buffer, sz);
357-
printf("Getting %d bytes\n", (int)sz);
358366
#endif
359367

360368
return sz;
@@ -364,13 +372,10 @@ int wolfTPM2_GetKeyBlobAsSeparateBuffers(byte* pubBuffer, word32* pubBufferSz,
364372
byte* privBuffer, word32* privBufferSz, WOLFTPM2_KEYBLOB* key)
365373
{
366374
int rc = 0;
367-
int sz = 0;
368375
byte pubAreaBuffer[sizeof(TPM2B_PUBLIC)];
369376
int pubAreaSize;
370377

371-
if (pubBuffer == NULL || pubBufferSz == NULL || (*pubBufferSz <= 0) ||
372-
privBuffer == NULL || privBufferSz == NULL || (*privBufferSz <= 0) ||
373-
(key == NULL)) {
378+
if (key == NULL || pubBufferSz == NULL || privBufferSz == NULL) {
374379
return BAD_FUNC_ARG;
375380
}
376381

@@ -388,6 +393,12 @@ int wolfTPM2_GetKeyBlobAsSeparateBuffers(byte* pubBuffer, word32* pubBufferSz,
388393
return BUFFER_E;
389394
}
390395

396+
if (pubBuffer == NULL || privBuffer == NULL) {
397+
*privBufferSz = sizeof(UINT16) + key->priv.size;
398+
*pubBufferSz = sizeof(key->pub.size) + sizeof(UINT16) + key->pub.size;
399+
return LENGTH_ONLY_E;
400+
}
401+
391402
if (*pubBufferSz < sizeof(key->pub.size) + sizeof(UINT16) + key->pub.size ||
392403
*privBufferSz < sizeof(UINT16) + key->priv.size) {
393404
return BUFFER_E;
@@ -410,14 +421,14 @@ int wolfTPM2_GetKeyBlobAsSeparateBuffers(byte* pubBuffer, word32* pubBufferSz,
410421
*privBufferSz += sizeof(UINT16) + key->priv.size;
411422

412423
#ifdef WOLFTPM_DEBUG_VERBOSE
424+
printf("Get KeyBlob public: %d bytes\n", (int)*pubBufferSz);
413425
TPM2_PrintBin(pubBuffer, *pubBufferSz);
414-
printf("Getting %d bytes for public buffer\n", (int)*pubBufferSz);
415426

427+
printf("Get KeyBlob private: %d bytes\n", (int)*privBufferSz);
416428
TPM2_PrintBin(privBuffer, *privBufferSz);
417-
printf("Getting %d bytes for private buffer\n", (int)*privBufferSz);
418429
#endif
419430

420-
return sz;
431+
return TPM_RC_SUCCESS;
421432
}
422433

423434
int wolfTPM2_SetKeyBlobFromBuffer(WOLFTPM2_KEYBLOB* key, byte *buffer,
@@ -436,8 +447,8 @@ int wolfTPM2_SetKeyBlobFromBuffer(WOLFTPM2_KEYBLOB* key, byte *buffer,
436447
XMEMSET(key, 0, sizeof(WOLFTPM2_KEYBLOB));
437448

438449
#ifdef WOLFTPM_DEBUG_VERBOSE
450+
printf("Set KeyBlob: %d bytes\n", (int)bufferSz);
439451
TPM2_PrintBin(buffer, bufferSz);
440-
printf("Setting %d bytes\n", (int)bufferSz);
441452
#endif
442453

443454
if (bufferSz < done_reading + sizeof(key->pub.size)) {

tests/unit_tests.c

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,101 @@ static void test_wolfTPM2_thread_local_storage(void)
486486
#endif /* HAVE_THREAD_LS && HAVE_PTHREAD */
487487
}
488488

489+
/* Test creating key and exporting keyblob as buffer,
490+
* importing and loading key. */
491+
static void test_wolfTPM2_KeyBlob(TPM_ALG_ID alg)
492+
{
493+
int rc;
494+
TPM_HANDLE handle;
495+
WOLFTPM2_DEV dev;
496+
WOLFTPM2_KEY srk;
497+
WOLFTPM2_KEYBLOB key;
498+
WOLFTPM2_BUFFER blob;
499+
TPMT_PUBLIC publicTemplate;
500+
word32 privBufferSz, pubBufferSz;
501+
502+
XMEMSET(&srk, 0, sizeof(srk));
503+
XMEMSET(&key, 0, sizeof(key));
504+
XMEMSET(&publicTemplate, 0, sizeof(publicTemplate));
505+
506+
rc = wolfTPM2_Init(&dev, TPM2_IoCb, NULL);
507+
AssertIntEQ(rc, 0);
508+
509+
if (alg == TPM_ALG_ECC)
510+
handle = TPM2_DEMO_STORAGE_KEY_HANDLE;
511+
else /* RSA */
512+
handle = TPM2_DEMO_STORAGE_EC_KEY_HANDLE;
513+
514+
/* Load or create the SRK */
515+
rc = wolfTPM2_ReadPublicKey(&dev, &srk, handle);
516+
if ((rc & RC_MAX_FMT1) == TPM_RC_HANDLE) {
517+
rc = wolfTPM2_CreateSRK(&dev, &srk, alg,
518+
(byte*)gStorageKeyAuth, sizeof(gStorageKeyAuth)-1);
519+
AssertIntEQ(rc, 0);
520+
}
521+
else {
522+
srk.handle.auth.size = sizeof(gStorageKeyAuth)-1;
523+
XMEMCPY(srk.handle.auth.buffer, gStorageKeyAuth, srk.handle.auth.size);
524+
}
525+
526+
if (alg == TPM_ALG_ECC) {
527+
rc = wolfTPM2_GetKeyTemplate_ECC(&publicTemplate,
528+
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth |
529+
TPMA_OBJECT_decrypt | TPMA_OBJECT_sign | TPMA_OBJECT_noDA,
530+
TPM_ECC_NIST_P256, TPM_ALG_NULL);
531+
}
532+
else { /* RSA */
533+
rc = wolfTPM2_GetKeyTemplate_RSA(&publicTemplate,
534+
TPMA_OBJECT_sensitiveDataOrigin | TPMA_OBJECT_userWithAuth |
535+
TPMA_OBJECT_decrypt | TPMA_OBJECT_sign | TPMA_OBJECT_noDA);
536+
}
537+
AssertIntEQ(rc, 0);
538+
539+
/* Create key under SRK and get encrypted private and public from TPM */
540+
rc = wolfTPM2_CreateKey(&dev, &key, &srk.handle, &publicTemplate,
541+
(byte*)gKeyAuth, sizeof(gKeyAuth)-1);
542+
AssertIntEQ(rc, 0);
543+
544+
/* Test getting size only */
545+
rc = wolfTPM2_GetKeyBlobAsSeparateBuffers(NULL, &pubBufferSz,
546+
NULL, &privBufferSz, &key);
547+
AssertIntEQ(rc, LENGTH_ONLY_E);
548+
549+
/* Test exporting private and public parts separately */
550+
rc = wolfTPM2_GetKeyBlobAsSeparateBuffers(blob.buffer, &pubBufferSz,
551+
&blob.buffer[pubBufferSz], &privBufferSz, &key);
552+
AssertIntEQ(rc, 0);
553+
554+
/* Test getting size only */
555+
rc = wolfTPM2_GetKeyBlobAsBuffer(NULL, sizeof(blob.buffer), &key);
556+
AssertIntGT(rc, 0);
557+
558+
/* Export private and public key */
559+
rc = wolfTPM2_GetKeyBlobAsBuffer(blob.buffer, sizeof(blob.buffer), &key);
560+
AssertIntGT(rc, 0);
561+
blob.size = rc;
562+
563+
/* Reset the originally created key */
564+
XMEMSET(&key, 0, sizeof(key));
565+
566+
/* Load key blob (private/public) from buffer */
567+
rc = wolfTPM2_SetKeyBlobFromBuffer(&key, blob.buffer, blob.size);
568+
AssertIntEQ(rc, 0);
569+
key.handle.auth.size = sizeof(gKeyAuth)-1;
570+
XMEMCPY(key.handle.auth.buffer, gKeyAuth, key.handle.auth.size);
571+
572+
/* Load key to TPM and get temp handle */
573+
rc = wolfTPM2_LoadKey(&dev, &key, &srk.handle);
574+
AssertIntEQ(rc, 0);
575+
576+
wolfTPM2_UnloadHandle(&dev, &key.handle);
577+
wolfTPM2_UnloadHandle(&dev, &srk.handle);
578+
wolfTPM2_Cleanup(&dev);
579+
580+
printf("Test TPM Wrapper:\tKeyBlob %s:\t%s\n",
581+
TPM2_GetAlgName(alg), rc == 0 ? "Passed" : "Failed");
582+
}
583+
489584
#endif /* !WOLFTPM2_NO_WRAPPER */
490585

491586
#ifndef NO_MAIN_DRIVER
@@ -509,6 +604,8 @@ int unit_tests(int argc, char *argv[])
509604
test_wolfTPM_ImportPublicKey();
510605
test_wolfTPM2_PCRPolicy();
511606
#endif
607+
test_wolfTPM2_KeyBlob(TPM_ALG_RSA);
608+
test_wolfTPM2_KeyBlob(TPM_ALG_ECC);
512609
test_wolfTPM2_Cleanup();
513610
test_wolfTPM2_thread_local_storage();
514611
#endif /* !WOLFTPM2_NO_WRAPPER */

wolftpm/tpm2_wrap.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3148,7 +3148,7 @@ WOLFTPM_API int wolfTPM2_SetKeyAuthPassword(WOLFTPM2_KEY *key, const byte* auth,
31483148
31493149
\brief Marshal data from a keyblob to a binary buffer. This can be
31503150
stored to disk for loading in a separate process or after power
3151-
cycling.
3151+
cycling. If buffer is not provided then size only will be returned.
31523152
31533153
\return Positive integer (size of the output)
31543154
\return BUFFER_E: insufficient space in provided buffer
@@ -3168,11 +3168,13 @@ WOLFTPM_API int wolfTPM2_GetKeyBlobAsBuffer(byte *buffer, word32 bufferSz,
31683168
31693169
\brief Marshal data from a keyblob to a binary buffer. This can be
31703170
stored to disk for loading in a separate process or after power
3171-
cycling.
3171+
cycling. If either buffer is NULL then the size will be returned for
3172+
each part.
31723173
3173-
\return Positive integer (size of the output)
3174+
\return TPM_RC_SUCCESS: successful
31743175
\return BUFFER_E: insufficient space in provided buffer
31753176
\return BAD_FUNC_ARG: check the provided arguments
3177+
\return LENGTH_ONLY_E: Returning length only (when either of the buffers is NULL)
31763178
31773179
\param pubBuffer pointer to buffer in which to store the public part of the marshaled keyblob
31783180
\param pubBufferSz pointer to the size of the above buffer

0 commit comments

Comments
 (0)