mirror of https://github.com/wolfSSL/wolfTPM.git
Make NVRAM and Keygen examples store the encoded public key part to save space
Before examples were always storing the maximum public key part size, using sizeof(TPM2B_PUBLIC), with many empty fields. This meant, always storing 616 bytes of public part, even if the public key part was less. * writekeyBlob/readKeyBlob use the actual size of public key part * NVRAM store/read use the actual size of the public key part * Minor fixes from peer review * Added comment to nvram/store about Host Endianness, per peer review * Added public API for appending/parsing TPM2B_PUBLIC to byte streams Signed-off-by: Dimitar Tomov <dimi@wolfssl.com>pull/143/head
parent
56db5fe67c
commit
f0540d688e
|
@ -70,7 +70,7 @@ static void usage(void)
|
||||||
static int symChoice(const char* arg, TPM_ALG_ID* algSym, int* keyBits,
|
static int symChoice(const char* arg, TPM_ALG_ID* algSym, int* keyBits,
|
||||||
char* symMode)
|
char* symMode)
|
||||||
{
|
{
|
||||||
unsigned long len = XSTRLEN(arg);
|
size_t len = XSTRLEN(arg);
|
||||||
|
|
||||||
if (len != SYM_EXTRA_OPTS_LEN) {
|
if (len != SYM_EXTRA_OPTS_LEN) {
|
||||||
return TPM_RC_FAILURE;
|
return TPM_RC_FAILURE;
|
||||||
|
@ -96,7 +96,7 @@ static int symChoice(const char* arg, TPM_ALG_ID* algSym, int* keyBits,
|
||||||
}
|
}
|
||||||
|
|
||||||
*keyBits = atoi(&arg[SYM_EXTRA_OPTS_KEY_BITS_POS]);
|
*keyBits = atoi(&arg[SYM_EXTRA_OPTS_KEY_BITS_POS]);
|
||||||
if(*keyBits != 128 && *keyBits != 256) {
|
if(*keyBits != 128 && *keyBits != 192 && *keyBits != 256) {
|
||||||
return TPM_RC_FAILURE;
|
return TPM_RC_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,7 +119,7 @@ int TPM2_Keygen_Example(void* userCtx, int argc, char *argv[])
|
||||||
int bAIK = 1;
|
int bAIK = 1;
|
||||||
int keyBits = 256;
|
int keyBits = 256;
|
||||||
const char* outputFile = "keyblob.bin";
|
const char* outputFile = "keyblob.bin";
|
||||||
unsigned long len = 0;
|
size_t len = 0;
|
||||||
char symMode[] = "aesctr";
|
char symMode[] = "aesctr";
|
||||||
|
|
||||||
if (argc >= 2) {
|
if (argc >= 2) {
|
||||||
|
|
|
@ -67,6 +67,9 @@ int TPM2_NVRAM_Read_Example(void* userCtx, int argc, char *argv[])
|
||||||
int paramEncAlg = TPM_ALG_NULL;
|
int paramEncAlg = TPM_ALG_NULL;
|
||||||
int partialRead = 0;
|
int partialRead = 0;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
/* Needed for TPM2_ParsePublic */
|
||||||
|
byte pubAreaBuffer[sizeof(TPM2B_PUBLIC)];
|
||||||
|
int pubAreaSize;
|
||||||
|
|
||||||
if (argc >= 2) {
|
if (argc >= 2) {
|
||||||
if (XSTRNCMP(argv[1], "-?", 2) == 0 ||
|
if (XSTRNCMP(argv[1], "-?", 2) == 0 ||
|
||||||
|
@ -137,16 +140,32 @@ int TPM2_NVRAM_Read_Example(void* userCtx, int argc, char *argv[])
|
||||||
XMEMCPY(nv.handle.auth.buffer, auth.buffer, auth.size);
|
XMEMCPY(nv.handle.auth.buffer, auth.buffer, auth.size);
|
||||||
|
|
||||||
if (partialRead != PRIVATE_PART_ONLY) {
|
if (partialRead != PRIVATE_PART_ONLY) {
|
||||||
readSize = sizeof(keyBlob.pub);
|
readSize = sizeof(keyBlob.pub.size);
|
||||||
printf("Trying to read %d bytes of public key part from NV\n", readSize);
|
printf("Trying to read %d bytes of public key size marker\n", readSize);
|
||||||
rc = wolfTPM2_NVReadAuth(&dev, &nv, TPM2_DEMO_NVRAM_STORE_INDEX,
|
rc = wolfTPM2_NVReadAuth(&dev, &nv, TPM2_DEMO_NVRAM_STORE_INDEX,
|
||||||
(byte*)&keyBlob.pub, &readSize, 0);
|
(byte*)&keyBlob.pub.size, &readSize, 0);
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
printf("Was a public key part written? (see nvram/store)\n");
|
printf("Was a public key part written? (see nvram/store)\n");
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
printf("Successfully read public key part from NV\n\n");
|
printf("Successfully read public key part from NV\n\n");
|
||||||
offset = readSize;
|
offset += readSize;
|
||||||
|
|
||||||
|
readSize = sizeof(UINT16) + keyBlob.pub.size; /* account for TPM2B size marker */
|
||||||
|
printf("Trying to read %d bytes of public key part from NV\n", keyBlob.pub.size);
|
||||||
|
rc = wolfTPM2_NVReadAuth(&dev, &nv, TPM2_DEMO_NVRAM_STORE_INDEX,
|
||||||
|
pubAreaBuffer, &readSize, offset);
|
||||||
|
if (rc != 0) goto exit;
|
||||||
|
printf("Successfully read public key part from NV\n\n");
|
||||||
|
offset += readSize;
|
||||||
|
|
||||||
|
/* Necessary for storing the publicArea with the correct encoding */
|
||||||
|
rc = TPM2_ParsePublic(&keyBlob.pub, pubAreaBuffer, sizeof(pubAreaBuffer), &pubAreaSize);
|
||||||
|
if (rc != TPM_RC_SUCCESS) {
|
||||||
|
printf("Decoding of PublicArea failed. Unable to extract correctly.\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef WOLFTPM_DEBUG_VERBOSE
|
#ifdef WOLFTPM_DEBUG_VERBOSE
|
||||||
TPM2_PrintPublicArea(&keyBlob.pub);
|
TPM2_PrintPublicArea(&keyBlob.pub);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
|
@ -68,6 +68,9 @@ int TPM2_NVRAM_Store_Example(void* userCtx, int argc, char *argv[])
|
||||||
int paramEncAlg = TPM_ALG_NULL;
|
int paramEncAlg = TPM_ALG_NULL;
|
||||||
int partialStore = 0;
|
int partialStore = 0;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
/* Needed for TPM2_AppendPublic */
|
||||||
|
byte pubAreaBuffer[sizeof(TPM2B_PUBLIC)];
|
||||||
|
int pubAreaSize;
|
||||||
|
|
||||||
if (argc >= 2) {
|
if (argc >= 2) {
|
||||||
if (XSTRNCMP(argv[1], "-?", 2) == 0 ||
|
if (XSTRNCMP(argv[1], "-?", 2) == 0 ||
|
||||||
|
@ -147,12 +150,32 @@ int TPM2_NVRAM_Store_Example(void* userCtx, int argc, char *argv[])
|
||||||
TPM2_DEMO_NVRAM_STORE_INDEX);
|
TPM2_DEMO_NVRAM_STORE_INDEX);
|
||||||
|
|
||||||
if (partialStore != PRIVATE_PART_ONLY) {
|
if (partialStore != PRIVATE_PART_ONLY) {
|
||||||
printf("Public part = %lu bytes\n", sizeof(keyBlob.pub));
|
printf("Public part = %hu bytes\n", keyBlob.pub.size);
|
||||||
rc = wolfTPM2_NVWriteAuth(&dev, &nv, TPM2_DEMO_NVRAM_STORE_INDEX,
|
rc = wolfTPM2_NVWriteAuth(&dev, &nv, TPM2_DEMO_NVRAM_STORE_INDEX,
|
||||||
(byte*)&keyBlob.pub, sizeof(keyBlob.pub), 0);
|
(byte*)&keyBlob.pub.size, sizeof(keyBlob.pub.size), 0);
|
||||||
|
if (rc != 0) goto exit;
|
||||||
|
printf("Stored 2-byte size marker before the private part\n");
|
||||||
|
offset += sizeof(keyBlob.pub.size);
|
||||||
|
|
||||||
|
/* Necessary for storing the publicArea with the correct byte encoding */
|
||||||
|
rc = TPM2_AppendPublic(pubAreaBuffer, sizeof(pubAreaBuffer), &pubAreaSize, &keyBlob.pub);
|
||||||
|
/* Note:
|
||||||
|
* Public Area is the only part of a TPM key that can be stored encoded
|
||||||
|
* Private Area is stored as-is, because TPM2B_PRIVATE is byte buffer
|
||||||
|
* and UINT16 size field, while Public Area is a complex TCG structure.
|
||||||
|
*/
|
||||||
|
if (rc != TPM_RC_SUCCESS) {
|
||||||
|
printf("Encoding of the publicArea failed. Unable to store.\n");
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The buffer holds pub.publicArea and also pub.size(UINT16) */
|
||||||
|
rc = wolfTPM2_NVWriteAuth(&dev, &nv, TPM2_DEMO_NVRAM_STORE_INDEX,
|
||||||
|
pubAreaBuffer, sizeof(UINT16) + keyBlob.pub.size, offset);
|
||||||
if (rc != 0) goto exit;
|
if (rc != 0) goto exit;
|
||||||
printf("NV write of public part succeeded\n\n");
|
printf("NV write of public part succeeded\n\n");
|
||||||
offset = sizeof(keyBlob.pub);
|
offset += sizeof(UINT16) + keyBlob.pub.size;
|
||||||
|
|
||||||
#ifdef WOLFTPM_DEBUG_VERBOSE
|
#ifdef WOLFTPM_DEBUG_VERBOSE
|
||||||
TPM2_PrintPublicArea(&keyBlob.pub);
|
TPM2_PrintPublicArea(&keyBlob.pub);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
|
@ -42,11 +42,26 @@ int writeKeyBlob(const char* filename,
|
||||||
#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES)
|
#if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES)
|
||||||
XFILE fp = NULL;
|
XFILE fp = NULL;
|
||||||
size_t fileSz = 0;
|
size_t fileSz = 0;
|
||||||
|
byte pubAreaBuffer[sizeof(TPM2B_PUBLIC)];
|
||||||
|
int pubAreaSize;
|
||||||
|
|
||||||
fp = XFOPEN(filename, "wb");
|
fp = XFOPEN(filename, "wb");
|
||||||
if (fp != XBADFILE) {
|
if (fp != XBADFILE) {
|
||||||
key->pub.size = sizeof(key->pub);
|
/* Make publicArea in encoded format to eliminate empty fields, save space */
|
||||||
fileSz += XFWRITE(&key->pub, 1, sizeof(key->pub), fp);
|
rc = TPM2_AppendPublic(pubAreaBuffer, sizeof(pubAreaBuffer), &pubAreaSize, &key->pub);
|
||||||
|
if (rc != TPM_RC_SUCCESS) return rc;
|
||||||
|
if (pubAreaSize != (key->pub.size + sizeof(key->pub.size))) {
|
||||||
|
#ifdef DEBUG_WOLFTPM
|
||||||
|
printf("writeKeyBlob: Sanity check for publicArea size failed\n");
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
TPM2_PrintBin(pubAreaBuffer, pubAreaSize);
|
||||||
|
/* Write size marker for the public part */
|
||||||
|
fileSz += XFWRITE(&key->pub.size, 1, sizeof(key->pub.size), fp);
|
||||||
|
/* Write the public part with bytes aligned */
|
||||||
|
fileSz += XFWRITE(pubAreaBuffer, 1, sizeof(UINT16) + key->pub.size, fp);
|
||||||
|
/* Write the private part, size marker is included */
|
||||||
fileSz += XFWRITE(&key->priv, 1, sizeof(UINT16) + key->priv.size, fp);
|
fileSz += XFWRITE(&key->priv, 1, sizeof(UINT16) + key->priv.size, fp);
|
||||||
XFCLOSE(fp);
|
XFCLOSE(fp);
|
||||||
}
|
}
|
||||||
|
@ -65,6 +80,8 @@ int readKeyBlob(const char* filename, WOLFTPM2_KEYBLOB* key)
|
||||||
XFILE fp = NULL;
|
XFILE fp = NULL;
|
||||||
size_t fileSz = 0;
|
size_t fileSz = 0;
|
||||||
size_t bytes_read = 0;
|
size_t bytes_read = 0;
|
||||||
|
byte pubAreaBuffer[sizeof(TPM2B_PUBLIC)];
|
||||||
|
int pubAreaSize;
|
||||||
|
|
||||||
XMEMSET(key, 0, sizeof(WOLFTPM2_KEYBLOB));
|
XMEMSET(key, 0, sizeof(WOLFTPM2_KEYBLOB));
|
||||||
|
|
||||||
|
@ -79,13 +96,29 @@ int readKeyBlob(const char* filename, WOLFTPM2_KEYBLOB* key)
|
||||||
}
|
}
|
||||||
printf("Reading %d bytes from %s\n", (int)fileSz, filename);
|
printf("Reading %d bytes from %s\n", (int)fileSz, filename);
|
||||||
|
|
||||||
bytes_read = XFREAD(&key->pub, 1, sizeof(key->pub), fp);
|
bytes_read = XFREAD(&key->pub.size, 1, sizeof(key->pub.size), fp);
|
||||||
if (bytes_read != sizeof(key->pub)) {
|
if (bytes_read != sizeof(key->pub.size)) {
|
||||||
printf("Read %zu, expected public blob %zu bytes\n", bytes_read, sizeof(key->pub));
|
printf("Read %zu, expected size marker of %zu bytes\n", bytes_read, sizeof(key->pub.size));
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
if (fileSz > sizeof(key->pub)) {
|
fileSz -= bytes_read;
|
||||||
fileSz -= sizeof(key->pub);
|
|
||||||
|
bytes_read = XFREAD(pubAreaBuffer, 1, sizeof(UINT16) + key->pub.size, fp);
|
||||||
|
if (bytes_read != sizeof(UINT16) + key->pub.size) {
|
||||||
|
printf("Read %zu, expected public blob %lu bytes\n", bytes_read, sizeof(UINT16) + key->pub.size);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
fileSz -= bytes_read; /* Reminder bytes for private key part */
|
||||||
|
|
||||||
|
/* Decode the byte stream into a publicArea structure ready for use */
|
||||||
|
rc = TPM2_ParsePublic(&key->pub, pubAreaBuffer, sizeof(pubAreaBuffer), &pubAreaSize);
|
||||||
|
if (rc != TPM_RC_SUCCESS) return rc;
|
||||||
|
#ifdef DEBUG_WOLFTPM
|
||||||
|
TPM2_PrintPublicArea(&key->pub);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (fileSz > 0) {
|
||||||
|
printf("Reading the private part of the key\n");
|
||||||
bytes_read = XFREAD(&key->priv, 1, fileSz, fp);
|
bytes_read = XFREAD(&key->priv, 1, fileSz, fp);
|
||||||
if (bytes_read != fileSz) {
|
if (bytes_read != fileSz) {
|
||||||
printf("Read %zu, expected private blob %zu bytes\n", bytes_read, fileSz);
|
printf("Read %zu, expected private blob %zu bytes\n", bytes_read, fileSz);
|
||||||
|
@ -95,7 +128,8 @@ int readKeyBlob(const char* filename, WOLFTPM2_KEYBLOB* key)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sanity check the sizes */
|
/* sanity check the sizes */
|
||||||
if (key->pub.size != sizeof(key->pub) || key->priv.size > sizeof(key->priv.buffer)) {
|
if (pubAreaSize != (key->pub.size + sizeof(key->pub.size)) ||
|
||||||
|
key->priv.size > sizeof(key->priv.buffer)) {
|
||||||
printf("Struct size check failed (pub %d, priv %d)\n",
|
printf("Struct size check failed (pub %d, priv %d)\n",
|
||||||
key->pub.size, key->priv.size);
|
key->pub.size, key->priv.size);
|
||||||
rc = BUFFER_E;
|
rc = BUFFER_E;
|
||||||
|
|
48
src/tpm2.c
48
src/tpm2.c
|
@ -5733,6 +5733,52 @@ int TPM2_HashNvPublic(TPMS_NV_PUBLIC* nvPublic, byte* buffer, UINT16* size)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WOLFTPM_API int TPM2_AppendPublic(byte* buf, size_t size, int* sizeUsed, TPM2B_PUBLIC* pub)
|
||||||
|
{
|
||||||
|
TPM2_Packet packet;
|
||||||
|
|
||||||
|
if (buf == NULL || sizeUsed == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
if (size < sizeof(TPM2B_PUBLIC)) {
|
||||||
|
printf("Insufficient buffer size for TPM2B_PUBLIC operations\n");
|
||||||
|
return TPM_RC_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare temporary buffer */
|
||||||
|
packet.buf = buf;
|
||||||
|
packet.pos = 0;
|
||||||
|
packet.size = (int)size;
|
||||||
|
|
||||||
|
TPM2_Packet_AppendPublic(&packet, pub);
|
||||||
|
*sizeUsed = packet.pos;
|
||||||
|
|
||||||
|
return TPM_RC_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
WOLFTPM_API int TPM2_ParsePublic(TPM2B_PUBLIC* pub, byte* buf, size_t size, int* sizeUsed)
|
||||||
|
{
|
||||||
|
TPM2_Packet packet;
|
||||||
|
|
||||||
|
if (buf == NULL || sizeUsed == NULL)
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
|
if (size < sizeof(TPM2B_PUBLIC)) {
|
||||||
|
printf("Insufficient buffer size for TPM2B_PUBLIC operations\n");
|
||||||
|
return TPM_RC_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare temporary buffer */
|
||||||
|
packet.buf = buf;
|
||||||
|
packet.pos = 0;
|
||||||
|
packet.size = (int)size;
|
||||||
|
|
||||||
|
TPM2_Packet_ParsePublic(&packet, pub);
|
||||||
|
*sizeUsed = packet.pos;
|
||||||
|
|
||||||
|
return TPM_RC_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_WOLFTPM
|
#ifdef DEBUG_WOLFTPM
|
||||||
#define LINE_LEN 16
|
#define LINE_LEN 16
|
||||||
void TPM2_PrintBin(const byte* buffer, word32 length)
|
void TPM2_PrintBin(const byte* buffer, word32 length)
|
||||||
|
@ -5864,7 +5910,7 @@ void TPM2_PrintPublicArea(const TPM2B_PUBLIC* pub)
|
||||||
TPM2_PrintBin(pub->publicArea.unique.derive.context.buffer, pub->publicArea.unique.derive.context.size);
|
TPM2_PrintBin(pub->publicArea.unique.derive.context.buffer, pub->publicArea.unique.derive.context.size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
printf("\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -2800,8 +2800,10 @@ WOLFTPM_API int TPM2_GetTpmCurve(int curveID);
|
||||||
WOLFTPM_API int TPM2_GetWolfCurve(int curve_id);
|
WOLFTPM_API int TPM2_GetWolfCurve(int curve_id);
|
||||||
|
|
||||||
WOLFTPM_API int TPM2_ParseAttest(const TPM2B_ATTEST* in, TPMS_ATTEST* out);
|
WOLFTPM_API int TPM2_ParseAttest(const TPM2B_ATTEST* in, TPMS_ATTEST* out);
|
||||||
WOLFTPM_LOCAL int TPM2_GetName(TPM2_CTX* ctx, UINT32 handleValue, int handleCnt, int idx, TPM2B_NAME* name);
|
|
||||||
WOLFTPM_API int TPM2_HashNvPublic(TPMS_NV_PUBLIC* nvPublic, byte* buffer, UINT16* size);
|
WOLFTPM_API int TPM2_HashNvPublic(TPMS_NV_PUBLIC* nvPublic, byte* buffer, UINT16* size);
|
||||||
|
WOLFTPM_API int TPM2_AppendPublic(byte* buf, size_t size, int* sizeUsed, TPM2B_PUBLIC* pub);
|
||||||
|
WOLFTPM_API int TPM2_ParsePublic(TPM2B_PUBLIC* pub, byte* buf, size_t size, int* sizeUsed);
|
||||||
|
WOLFTPM_LOCAL int TPM2_GetName(TPM2_CTX* ctx, UINT32 handleValue, int handleCnt, int idx, TPM2B_NAME* name);
|
||||||
|
|
||||||
#ifdef WOLFTPM2_USE_WOLF_RNG
|
#ifdef WOLFTPM2_USE_WOLF_RNG
|
||||||
WOLFTPM_API int TPM2_GetWolfRng(WC_RNG** rng);
|
WOLFTPM_API int TPM2_GetWolfRng(WC_RNG** rng);
|
||||||
|
|
Loading…
Reference in New Issue