wolfSSL / wolfTPM

wolfTPM is a highly portable TPM 2.0 library, designed for embedded use.
https://www.wolfssl.com
GNU General Public License v2.0
230 stars 56 forks source link

Added example for NV counter increment and Fixes for NV auth handling #243

Closed dgarske closed 1 year ago

dgarske commented 1 year ago

Re: https://developers.tpm.dev/chats/1689646

haydenroche5 commented 1 year ago

Re: developers.tpm.dev/chats/1689646

This link just takes me to the TPM.dev homepage.

dgarske commented 1 year ago

Re: developers.tpm.dev/chats/1689646

This link just takes me to the TPM.dev homepage.

You'd probably need to register. This was in response to some issues with NV increment:

Hi everyone. I am struggling with hybrid NV counters. We are trying to use a hybrid NV counter to ensure the freshness of frequently changing data on the disk. We were able to create the hybrid NV counter using TPM2_NV_DefineSpace with the following NV index attributes:

TPMA_NV_AUTHWRITE |
TPMA_NV_AUTHREAD |
TPMA_NV_NO\_DA |
TPMA_NV_ORDERLY |
TPM_NT_COUNTER

yielding a total value of 0x06040014.

We are supplying a constant password for that NV index.

We are then able to increment the counter and read it using the constant password until the next TPM reset. After the TPM reset (power-off and power-on), we can still read the counter but no longer increment it using that password. Calling TPM2_NV_Increment then results in TPM_RC_ATTRIBUTES (0xA82). Has anyone a clue why we cannot increment the counter after a reset of the TPM?

if you do a nv_readpublic on the NV area after the TPM reset, what does the attributes say? The attributes of the NV index are 0x26040014 after TPM reset. So nothing changed except TPMA_NV_WRITTEN is now set as expected.

The wolftpm library we are using sets TPM2B_AUTH auth field of the TPM2_NV_DefineSpace command to set the password for the NV index.

Thanks for engaging with our problem.

We are using the wrapper wolfTPM2_NVCreateAuth to create the NV counter index, but unfortunately, there is no wrapper to increment the counter, so we are using TPM2_NV_Increment directly. As a quick hack, we copied and adapted the implementation of wolfTPM2_NVWriteAuth:

WOLFTPM2_HANDLE handle;
memset(&handle, 0, sizeof(handle));
handle.hndl = TPM2_NV_INDEX_TRUST_ANCHOR_HASH_COUNTER;
memcpy(handle.auth.buffer, "test", 4);
handle.auth.size = 4;

// TODO this check probably is not necessary:
if (_dev.ctx.session) {
    wolfTPM2_SetAuthHandle(&_dev, 0, &handle);
}

TPMS_NV_PUBLIC nv_public;
int result = wolfTPM2_NVReadPublic(&_dev, handle.hndl, &nv_public);
_assert_tpm_result("TPM NV read public:", result);

result = TPM2_HashNvPublic(&nv_public, (byte*)&handle.name.name, &handle.name.size);
_assert_tpm_result("TPM hash NV public:", result);

result = wolfTPM2_SetAuthHandleName(&_dev, 0, &handle);
_assert_tpm_result("TPM set auth handle name:", result);

result = wolfTPM2_SetAuthHandleName(&_dev, 1, &handle);
_assert_tpm_result("TPM set auth handle name:", result);

NV_Increment_In in;
memset(&in, 0, sizeof(in));
in.authHandle = handle.hndl;
in.nvIndex = TPM2_NV_INDEX_TRUST_ANCHOR_HASH_COUNTER;

result = TPM2_NV_Increment(&in);
_assert_tpm_result("TPM increment counter:", result); // This fails