Skip to content

Commit b0827a5

Browse files
committed
Fix for WP11_Object_WrapTpmKey that was incorrectly setting the WP11_FLAG_TPM for public keys. Improvement to immediately encrypt/wrap any RSA or ECC private keys with TPM and store them in NV that way. Fix to make sure the loaded RSA/ECC public keys have their devId set to allow crypto callback.
1 parent 51db7e7 commit b0827a5

1 file changed

Lines changed: 114 additions & 65 deletions

File tree

src/internal.c

Lines changed: 114 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -2530,10 +2530,12 @@ static int WP11_Object_DecodeTpmKey(WP11_Object* object)
25302530
return ret;
25312531
}
25322532

2533+
static int WP11_Object_WrapTpmKey(WP11_Object* object); /* forward declaration */
2534+
25332535
static int WP11_Object_EncodeTpmKey(WP11_Object* object, byte* keyData,
25342536
int keyDataLen)
25352537
{
2536-
int ret;
2538+
int ret = 0;
25372539
byte pubAreaBuffer[sizeof(TPM2B_PUBLIC)];
25382540
int pubAreaSize = 0;
25392541
int idx = 0;
@@ -2542,39 +2544,52 @@ static int WP11_Object_EncodeTpmKey(WP11_Object* object, byte* keyData,
25422544
return BAD_FUNC_ARG;
25432545
}
25442546

2545-
if (object->tpmKey.pub.size == 0 || object->tpmKey.priv.size == 0) {
2546-
return 0; /* not a TPM key */
2547+
2548+
/* if key is not already wrapped as a TPM key, wrap it */
2549+
if ((object->opFlag & WP11_FLAG_TPM) == 0) {
2550+
ret = WP11_Object_WrapTpmKey(object);
25472551
}
25482552

2549-
/* save off the public and private portion of the TPM key.
2550-
* Private is encrypted by a symmetric key only known by the TPM.
2551-
* Make publicArea in encoded format to eliminate empty fields */
2552-
ret = TPM2_AppendPublic(pubAreaBuffer, (word32)sizeof(pubAreaBuffer),
2553-
&pubAreaSize, &object->tpmKey.pub);
2554-
if (ret == 0) {
2555-
ret = sizeof(UINT16) +
2556-
sizeof(UINT16) + pubAreaSize +
2557-
sizeof(UINT16) + object->tpmKey.priv.size;
2558-
if (keyData != NULL) {
2559-
if (ret <= keyDataLen) {
2560-
/* Write size marker for the public part */
2561-
XMEMCPY(object->keyData, &pubAreaSize,
2562-
sizeof(UINT16));
2563-
idx += sizeof(UINT16);
2564-
/* Write the public part with bytes aligned */
2565-
XMEMCPY(object->keyData + idx, pubAreaBuffer,
2566-
sizeof(UINT16) + pubAreaSize);
2567-
idx += sizeof(UINT16) + pubAreaSize;
2568-
/* Write the private part, size marker is included */
2569-
XMEMCPY(object->keyData + idx, &object->tpmKey.priv,
2570-
sizeof(UINT16) + object->tpmKey.priv.size);
2571-
idx += sizeof(UINT16) + object->tpmKey.priv.size;
2553+
/* if this is not a TPM private key, return 0 and encode as DER */
2554+
if (ret == 0 &&
2555+
(object->tpmKey.pub.size == 0 ||
2556+
object->tpmKey.priv.size == 0)) {
2557+
return 0; /* not a TPM key */
2558+
}
25722559

2573-
/* set flag indicating this is TPM based key */
2574-
object->opFlag |= WP11_FLAG_TPM;
2560+
if (ret == 0) {
2561+
/* save off the public and private portion of the TPM key.
2562+
* Private is encrypted by a symmetric key only known by the TPM.
2563+
* Make publicArea in encoded format to eliminate empty fields */
2564+
ret = TPM2_AppendPublic(pubAreaBuffer, (word32)sizeof(pubAreaBuffer),
2565+
&pubAreaSize, &object->tpmKey.pub);
2566+
if (ret == 0) {
2567+
ret = sizeof(UINT16) +
2568+
sizeof(UINT16) + pubAreaSize +
2569+
sizeof(UINT16) + object->tpmKey.priv.size;
2570+
if (keyData != NULL) {
2571+
if (ret <= keyDataLen) {
2572+
/* Write size marker for the public part */
2573+
XMEMCPY(object->keyData, &pubAreaSize,
2574+
sizeof(UINT16));
2575+
idx += sizeof(UINT16);
2576+
/* Write the public part with bytes aligned */
2577+
XMEMCPY(object->keyData + idx, pubAreaBuffer,
2578+
sizeof(UINT16) + pubAreaSize);
2579+
idx += sizeof(UINT16) + pubAreaSize;
2580+
/* Write the private part, size marker is included */
2581+
XMEMCPY(object->keyData + idx, &object->tpmKey.priv,
2582+
sizeof(UINT16) + object->tpmKey.priv.size);
2583+
idx += sizeof(UINT16) + object->tpmKey.priv.size;
2584+
2585+
object->opFlag |= WP11_FLAG_TPM;
2586+
}
2587+
else {
2588+
ret = BUFFER_E;
2589+
}
25752590
}
25762591
else {
2577-
ret = BUFFER_E;
2592+
/* return size only */
25782593
}
25792594
}
25802595
}
@@ -2598,6 +2613,12 @@ static int wp11_Object_Decode_RsaKey(WP11_Object* object)
25982613
{
25992614
int ret = 0;
26002615
word32 idx = 0;
2616+
RsaKey* key = &object->data.rsaKey;
2617+
2618+
ret = wc_InitRsaKey_ex(key, NULL, object->slot->devId);
2619+
if (ret != 0) {
2620+
return ret;
2621+
}
26012622

26022623
#ifdef WOLFPKCS11_TPM
26032624
if (object->opFlag & WP11_FLAG_TPM) {
@@ -2621,15 +2642,15 @@ static int wp11_Object_Decode_RsaKey(WP11_Object* object)
26212642
}
26222643
if (ret == 0) {
26232644
/* Decode RSA private key. */
2624-
ret = wc_RsaPrivateKeyDecode(der, &idx, &object->data.rsaKey, len);
2645+
ret = wc_RsaPrivateKeyDecode(der, &idx, key, len);
26252646
XMEMSET(der, 0, len);
26262647
}
26272648
if (der != NULL)
26282649
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
26292650
}
26302651
else {
26312652
/* Decode RSA public key. */
2632-
ret = wc_RsaPublicKeyDecode(object->keyData, &idx, &object->data.rsaKey,
2653+
ret = wc_RsaPublicKeyDecode(object->keyData, &idx, key,
26332654
object->keyDataLen);
26342655
}
26352656
object->encoded = (ret != 0);
@@ -2938,6 +2959,12 @@ static int wp11_Object_Decode_EccKey(WP11_Object* object)
29382959
{
29392960
int ret = 0;
29402961
word32 idx = 0;
2962+
ecc_key* key = &object->data.ecKey;
2963+
2964+
ret = wc_ecc_init_ex(key, NULL, object->slot->devId);
2965+
if (ret != 0) {
2966+
return ret;
2967+
}
29412968

29422969
#ifdef WOLFPKCS11_TPM
29432970
if (object->opFlag & WP11_FLAG_TPM) {
@@ -2960,19 +2987,19 @@ static int wp11_Object_Decode_EccKey(WP11_Object* object)
29602987
sizeof(object->iv));
29612988
}
29622989
if (ret == 0) {
2963-
ret = wc_ecc_init_ex(&object->data.ecKey, NULL, object->slot->devId);
2990+
ret = wc_ecc_init_ex(key, NULL, object->slot->devId);
29642991
}
29652992
if (ret == 0) {
29662993
/* Decode ECC private key. */
2967-
ret = wc_EccPrivateKeyDecode(der, &idx, &object->data.ecKey, len);
2994+
ret = wc_EccPrivateKeyDecode(der, &idx, key, len);
29682995
XMEMSET(der, 0, len);
29692996
}
29702997
if (der != NULL)
29712998
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
29722999
}
29733000
else {
29743001
/* Decode ECC public key. */
2975-
ret = wc_EccPublicKeyDecode(object->keyData, &idx, &object->data.ecKey,
3002+
ret = wc_EccPublicKeyDecode(object->keyData, &idx, key,
29763003
object->keyDataLen);
29773004
}
29783005
object->encoded = (ret != 0);
@@ -4333,12 +4360,49 @@ static int wp11_Token_Store(WP11_Token* token, int tokenId)
43334360
int i;
43344361
void* storage = NULL;
43354362
WP11_Object* object;
4336-
const int variableSz = token->userPinLen + token->soPinLen +
4337-
(token->objCnt * FIELD_SIZE(WP11_Object, type));
4363+
int variableSz;
43384364

4339-
/* Open access to token object. */
4365+
#ifdef WOLFPKCS11_DEBUG_STORE
4366+
printf("wp11_Token_Store: tokenId %d, objCnt %d\n", tokenId, token->objCnt);
4367+
#endif
4368+
4369+
/* Reserve space for token object */
4370+
variableSz = token->userPinLen + token->soPinLen +
4371+
(token->objCnt * FIELD_SIZE(WP11_Object, type));
43404372
ret = wp11_storage_open(WOLFPKCS11_STORE_TOKEN, tokenId, 0, variableSz,
43414373
&storage);
4374+
if (ret == 0) {
4375+
wp11_storage_close(storage);
4376+
storage = NULL;
4377+
}
4378+
4379+
/* Store the objects */
4380+
object = token->object;
4381+
for (i = token->objCnt - 1; i >= 0; i--) {
4382+
/* Write the objects. */
4383+
ret = wp11_Object_Store(object, tokenId, i);
4384+
if (ret != 0) {
4385+
#ifdef DEBUG_WOLFPKCS11
4386+
printf("Failed to store object %d, token %d, ret: %d\n",
4387+
i, tokenId, ret);
4388+
#endif
4389+
token->objCnt = i; /* mark number of objects actually stored */
4390+
#ifdef WOLFPKCS11_TPM_STORE
4391+
if ((ret & RC_MAX_FM0) == TPM_RC_NV_SPACE) {
4392+
ret = 0; /* allow this error and continue */
4393+
}
4394+
#endif
4395+
break;
4396+
}
4397+
object = object->next;
4398+
}
4399+
4400+
if (ret == 0) {
4401+
variableSz = token->userPinLen + token->soPinLen +
4402+
(token->objCnt * FIELD_SIZE(WP11_Object, type));
4403+
ret = wp11_storage_open(WOLFPKCS11_STORE_TOKEN, tokenId, 0, variableSz,
4404+
&storage);
4405+
}
43424406
if (ret == 0) {
43434407
/* Write label of token. (32) */
43444408
ret = wp11_storage_write_string(storage, token->label,
@@ -4416,20 +4480,6 @@ static int wp11_Token_Store(WP11_Token* token, int tokenId)
44164480
}
44174481

44184482
wp11_storage_close(storage);
4419-
4420-
object = token->object;
4421-
for (i = token->objCnt - 1; i >= 0; i--) {
4422-
/* Write the objects. */
4423-
ret = wp11_Object_Store(object, tokenId, i);
4424-
if (ret != 0) {
4425-
#ifdef DEBUG_WOLFPKCS11
4426-
printf("Failed to store object %d, token %d, ret: %d\n",
4427-
i, tokenId, ret);
4428-
#endif
4429-
break;
4430-
}
4431-
object = object->next;
4432-
}
44334483
}
44344484
else if (ret == NOT_AVAILABLE_E) {
44354485
/* Not writing. */
@@ -8413,10 +8463,10 @@ static int WP11_Object_WrapTpmKey(WP11_Object* object)
84138463
}
84148464
(void)p;
84158465
#endif
8416-
}
8417-
if (ret == 0) {
8418-
/* set flag indicating this is TPM based key */
8419-
object->opFlag |= WP11_FLAG_TPM;
8466+
if (ret == 0) {
8467+
/* set flag indicating this is TPM based key */
8468+
object->opFlag |= WP11_FLAG_TPM;
8469+
}
84208470
}
84218471
break;
84228472
}
@@ -8495,10 +8545,10 @@ static int WP11_Object_WrapTpmKey(WP11_Object* object)
84958545
qx, qxSz, qy, qySz, d, dSz);
84968546
}
84978547
#endif
8498-
}
8499-
if (ret == 0) {
8500-
/* set flag indicating this is TPM based key */
8501-
object->opFlag |= WP11_FLAG_TPM;
8548+
if (ret == 0) {
8549+
/* set flag indicating this is TPM based key */
8550+
object->opFlag |= WP11_FLAG_TPM;
8551+
}
85028552
}
85038553
break;
85048554
}
@@ -8519,26 +8569,25 @@ static int WP11_Object_LoadTpmKey(WP11_Object* object)
85198569
return BAD_FUNC_ARG;
85208570
}
85218571

8522-
/* if key is not already wrapped as a TPM key, wrap it */
8523-
if ((object->opFlag & WP11_FLAG_TPM) == 0) {
8524-
ret = WP11_Object_WrapTpmKey(object);
8525-
}
8526-
8527-
if (ret == 0 && (object->opFlag & WP11_FLAG_TPM)) {
8572+
if (object->opFlag & WP11_FLAG_TPM) {
85288573
ret = wolfTPM2_LoadKey(&object->slot->tpmDev, &object->tpmKey,
85298574
&object->slot->tpmCtx.storageKey->handle);
85308575
if (ret == 0) {
85318576
if (object->tpmKey.pub.publicArea.type == TPM_ALG_RSA) {
8577+
#ifndef NO_RSA
85328578
/* tell crypto callback which RsaKey to use */
85338579
object->slot->tpmCtx.rsaKey = (WOLFTPM2_KEY*)&object->tpmKey;
8580+
#endif
85348581
}
85358582
else if (object->tpmKey.pub.publicArea.type == TPM_ALG_ECC) {
8583+
#ifdef HAVE_ECC
85368584
/* tell crypto callback which EccKey to use */
85378585
#if defined(LIBWOLFTPM_VERSION_HEX) && LIBWOLFTPM_VERSION_HEX > 0x03009000
85388586
object->slot->tpmCtx.ecdsaKey = &object->tpmKey;
85398587
#else
85408588
object->slot->tpmCtx.eccKey = (WOLFTPM2_KEY*)&object->tpmKey;
85418589
#endif
8590+
#endif
85428591
}
85438592
}
85448593
}

0 commit comments

Comments
 (0)