I'm trying to Define/Undefine NV Index for TPM 2.0 using SAPI (part of this code stolen from tpm2-tss tests) at 0x01500020
as in tests, but this fails for unknown reasons as for me:
#include <tss2/tss2_sys.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TEST_NV_INDEX 0x01500020
#define MAX_PSWD_LEN 8
static TSS2_RC tcti_transmit(TSS2_TCTI_CONTEXT *tctiContext,
size_t size, uint8_t const *command) {
(void) tctiContext;
(void) size;
(void) command;
return TPM2_RC_SUCCESS;
}
static TSS2_RC tcti_receive(TSS2_TCTI_CONTEXT *tctiContext,
size_t *size, uint8_t *response, int32_t timeout) {
(void) tctiContext;
(void) size;
(void) response;
(void) timeout;
return TPM2_RC_SUCCESS;
}
static TSS2_ABI_VERSION g_ver = TSS2_ABI_VERSION_CURRENT;
static TSS2_TCTI_CONTEXT_COMMON_V1 g_tcti_ctx_v1;
int main(void) {
char passwd[] = { "password" };
UINT32 rc;
TSS2L_SYS_AUTH_RESPONSE sessionsDataOut;
TPM2B_NV_PUBLIC publicInfo;
TPM2B_AUTH nvAuth;
size_t ctx_size = Tss2_Sys_GetContextSize(0);
TSS2_SYS_CONTEXT *ctx = calloc(1, ctx_size);
TSS2_TCTI_CONTEXT *tcti_ctx = (TSS2_TCTI_CONTEXT *) &g_tcti_ctx_v1;
TSS2L_SYS_AUTH_COMMAND sessionsData = { .count = 1, .auths = {{
.sessionHandle = TPM2_RH_PW,
.sessionAttributes = 0,
.nonce = { .size = 0 },
.hmac = { .size = 0 }
}}};
nvAuth.size = strnlen(passwd, MAX_PSWD_LEN);
memcpy(&nvAuth.buffer[0], &passwd[0], nvAuth.size);
publicInfo.size = 0;
publicInfo.nvPublic.nvIndex = TEST_NV_INDEX;
publicInfo.nvPublic.nameAlg = TPM2_ALG_SHA256;
*(UINT32 *)&(publicInfo.nvPublic.attributes) = 0;
publicInfo.nvPublic.attributes |= TPMA_NV_AUTHREAD;
publicInfo.nvPublic.attributes |= TPMA_NV_AUTHWRITE;
publicInfo.nvPublic.attributes |= TPMA_NV_PLATFORMCREATE;
publicInfo.nvPublic.attributes |= TPMA_NV_ORDERLY;
publicInfo.nvPublic.authPolicy.size = 0;
publicInfo.nvPublic.dataSize = 32;
g_tcti_ctx_v1.version = 1;
g_tcti_ctx_v1.transmit = tcti_transmit;
g_tcti_ctx_v1.receive = tcti_receive;
if (ctx == NULL) {
fprintf(stderr, "Sys Context NULL\n");
exit(1);
}
printf("Context's size = %ld\n", ctx_size);
rc = Tss2_Sys_Initialize(ctx, ctx_size,
tcti_ctx, &g_ver);
if (rc != TPM2_RC_SUCCESS) {
fprintf(stderr, "Failed to Tss2_Sys_Initialize: rc = 0x%x\n", rc);
exit(1);
}
rc = Tss2_Sys_NV_DefineSpace(ctx, TPM2_RH_PLATFORM,
&sessionsData, &nvAuth, &publicInfo, &sessionsDataOut);
if (rc != TPM2_RC_SUCCESS) {
fprintf(stderr, "Failed to Tss2_Sys_NV_DefineSpace: rc = 0x%x\n", rc);
goto free_ctx;
}
rc = Tss2_Sys_NV_UndefineSpace(ctx, TPM2_RH_PLATFORM,
TEST_NV_INDEX, &sessionsData, 0);
if (rc != TPM2_RC_SUCCESS) {
fprintf(stderr, "Failed to Tss2_Sys_NV_UndefineSpace: rc = 0x%x", rc);
goto free_ctx;
}
Tss2_Sys_Finalize(ctx);
exit(0);
free_ctx:
Tss2_Sys_Finalize(ctx);
exit(1);
}
After compiling it and executing I got an error:
$ gcc -o nvdefine nvdefine.c -ltss2-sys && ./nvdefine
Failed to Tss2_Sys_NV_DefineSpace: rc = 0x80013
I tried to use TPM2_RH_PLATFORM
and TPM2_RH_OWNER
, but this had no effect, what I'm doing wrong? Can anybody help with this?
I found a solution for my problem, that was because of a wrong TCTI Context, I replaced that code by this:
#include <tss2/tss2_tctildr.h>
...
int main(void) {
...
TPM2_RC rc;
TSS2_TCTI_CONTEXT *tcti_ctx = NULL;
...
rc = Tss2_Sys_TctiLdr_Initialize(NULL, &tcti_ctx);
...
}
Another moment is that for TPM2_RH_PLATFORM
I need a session, so I replaced it by TPM2_RH_OWNER
according to NV Public Attributes:
...
int main(void) {
...
publicInfo.nvPublic.attributes |= TPMA_NV_AUTHREAD;
publicInfo.nvPublic.attributes |= TPMA_NV_AUTHWRITE;
publicInfo.nvPublic.attributes |= TPMA_NV_OWNERWRITE;
publicInfo.nvPublic.attributes |= TPMA_NV_OWNERREAD;
publicInfo.nvPublic.attributes |= TPMA_NV_WRITE_STCLEAR;
publicInfo.nvPublic.attributes |= TPMA_NV_READ_STCLEAR;
...
rc = Tss2_Sys_NV_DefineSpace(ctx, TPM2_RH_OWNER,
&sessionsData, &nvAuth, &publicInfo, &sessionsDataOut);
...
rc = Tss2_Sys_NV_UndefineSpace(ctx, TPM2_RH_OWNER,
TEST_NV_INDEX, &sessionsData, 0);
...
}
And compile this with TctiLdr
:
$ gcc -o nvdefine nvdefine.c -ltss2-sys -ltss2-tctildr
The whole code listing:
#include <tss2/tss2_sys.h>
#include <tss2/tss2_tctildr.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define TEST_NV_INDEX 0x01500020
int main(void) {
char passwd[] = { "password" };
UINT32 rc;
TSS2L_SYS_AUTH_RESPONSE sessionsDataOut;
TPM2B_NV_PUBLIC publicInfo;
TPM2B_AUTH nvAuth;
size_t ctx_size = Tss2_Sys_GetContextSize(0);
TSS2_SYS_CONTEXT *ctx = calloc(1, ctx_size);
TSS2_TCTI_CONTEXT *tcti_ctx = NULL;
TSS2_ABI_VERSION abiVersion = TSS2_ABI_VERSION_CURRENT;
TSS2L_SYS_AUTH_COMMAND sessionsData = { .count = 1, .auths = {{
.sessionHandle = TPM2_RH_PW,
.sessionAttributes = 0,
.nonce = { .size = 0 },
.hmac = { .size = 0 }
}}};
nvAuth.size = strlen(passwd);
memcpy(&nvAuth.buffer[0], &passwd[0], nvAuth.size);
publicInfo.size = 0;
publicInfo.nvPublic.nvIndex = TEST_NV_INDEX;
publicInfo.nvPublic.nameAlg = TPM2_ALG_SHA256;
*(UINT32 *)&(publicInfo.nvPublic.attributes) = 0;
publicInfo.nvPublic.attributes |= TPMA_NV_AUTHREAD;
publicInfo.nvPublic.attributes |= TPMA_NV_AUTHWRITE;
publicInfo.nvPublic.attributes |= TPMA_NV_OWNERWRITE;
publicInfo.nvPublic.attributes |= TPMA_NV_OWNERREAD;
publicInfo.nvPublic.attributes |= TPMA_NV_WRITE_STCLEAR;
publicInfo.nvPublic.attributes |= TPMA_NV_READ_STCLEAR;
publicInfo.nvPublic.authPolicy.size = 0;
publicInfo.nvPublic.dataSize = 32;
if (!ctx) {
fprintf(stderr, "Sys Context NULL\n");
exit(1);
}
rc = Tss2_TctiLdr_Initialize(NULL, &tcti_ctx);
if (rc != TPM2_RC_SUCCESS) {
fprintf(stderr, "Failed to Tss2_TctiLdr_Initialize: 0x%x\n", rc);
exit(1);
}
rc = Tss2_Sys_Initialize(ctx, ctx_size,
tcti_ctx, &abiVersion);
if (rc != TPM2_RC_SUCCESS) {
fprintf(stderr, "Failed to Tss2_Sys_Initialize: rc = 0x%x\n", rc);
exit(1);
}
rc = Tss2_Sys_NV_DefineSpace(ctx, TPM2_RH_OWNER,
&sessionsData, &nvAuth, &publicInfo, &sessionsDataOut);
if (rc != TPM2_RC_SUCCESS) {
fprintf(stderr, "Failed to Tss2_Sys_NV_DefineSpace: rc = 0x%x\n", rc);
goto free_ctx;
}
rc = Tss2_Sys_NV_UndefineSpace(ctx, TPM2_RH_OWNER,
TEST_NV_INDEX, &sessionsData, 0);
if (rc != TPM2_RC_SUCCESS) {
fprintf(stderr, "Failed to Tss2_Sys_NV_UndefineSpace: rc = 0x%x", rc);
goto free_ctx;
}
Tss2_Sys_Finalize(ctx);
exit(0);
free_ctx:
Tss2_Sys_Finalize(ctx);
exit(1);
}
This works!