tpm2-tss
tpm2-tss copied to clipboard
The value of TPM2_TRANSIENT_LAST is incorrect (off-by-one)
The value of TPM2_TRANSIENT_LAST
is defined as 0x80fffffe
in tss2/tss2_tpm2_types.h
. The defined value should be 0x80ffffff
.
The Linux kernel's TPM2 resource manager assigns transient handles counting from 0x80ffffff
downwards: https://github.com/torvalds/linux/blob/v6.10/drivers/char/tpm/tpm2-space.c#L374
Here is a program I wrote that asserts whether the TPM2 handle of a transient key (as created by Esys_CreatePrimary
) falls within the range of a transient handle.
The program crashes with an assertion failure:
$ gcc esys-transient.c -o esys-transient -ltss2-esys
$ sudo ./esys-transient
esys-transient: esys-transient.c:64: main: Assertion `esys_is_transient(ctx, primarykey_handle)' failed.
Aborted
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <tss2/tss2_esys.h>
const TPM2B_PUBLIC tpm2_template_null = {
.publicArea = {
.type = TPM2_ALG_ECC,
.nameAlg = TPM2_ALG_SHA256,
.objectAttributes =
TPMA_OBJECT_FIXEDTPM |
TPMA_OBJECT_FIXEDPARENT |
TPMA_OBJECT_SENSITIVEDATAORIGIN |
TPMA_OBJECT_USERWITHAUTH |
TPMA_OBJECT_NODA |
TPMA_OBJECT_RESTRICTED |
TPMA_OBJECT_DECRYPT,
.parameters.eccDetail = {
.symmetric = {
.algorithm = TPM2_ALG_AES,
.keyBits.aes = 128,
.mode.aes = TPM2_ALG_CFB,
},
.scheme.scheme = TPM2_ALG_NULL,
.curveID = TPM2_ECC_NIST_P256,
.kdf.scheme = TPM2_ALG_NULL,
},
},
};
static bool esys_is_transient(ESYS_CONTEXT *ctx, ESYS_TR handle) {
TPM2_HANDLE tpm2handle;
TSS2_RC rc = Esys_TR_GetTpmHandle(ctx, handle, &tpm2handle);
assert(!rc);
return tpm2handle >= TPM2_TRANSIENT_FIRST && tpm2handle <= TPM2_TRANSIENT_LAST;
}
int main(void) {
TSS2_RC rc;
ESYS_CONTEXT *ctx = NULL;
ESYS_TR primarykey_handle;
TPM2B_PUBLIC *primarykey_public = NULL;
rc = Esys_Initialize(&ctx, NULL, NULL);
if (rc) goto error;
rc = Esys_CreatePrimary(ctx,
/* primaryHandle */ ESYS_TR_RH_NULL,
/* shandleX */ ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE,
/* inSensitive */ &(const TPM2B_SENSITIVE_CREATE) { 0 },
/* inPublic */ &tpm2_template_null,
/* outsideInfo */ NULL,
/* creationPCR */ &(const TPML_PCR_SELECTION) { 0 },
/* objectHandle */ &primarykey_handle,
/* outPublic */ &primarykey_public,
/* creationData */ NULL,
/* creationHash */ NULL,
/* creationTicket */ NULL);
if (rc) goto error;
assert(esys_is_transient(ctx, primarykey_handle));
rc = Esys_FlushContext(ctx, primarykey_handle);
if (rc) goto error;
error:
printf("rc = %d\n", rc);
free(primarykey_public);
if (ctx) Esys_Finalize(&ctx);
return !!rc;
}