From 7de60c942373c5b5b617daf84c8f202e7ce5e01c Mon Sep 17 00:00:00 2001 From: William Roberts Date: Wed, 1 Sep 2021 17:26:15 -0500 Subject: [PATCH 1/6] [RFC] tools: add tpm2_policy tool for invoking libpolicy UPDATE: Working: Initial test working: If you get the tpm2_policy tool from the tss pr, this should work: tpm2 policy /path/to/tpm2-tss/test/data/fapi/policy/pol_pcr16_0.json Their are still many todo's to go through, but let's figure out the interface into the library and go from there. Create a tpm2_policy tool that can read the FAPI JSON style policies and: 1. Instantiate them -> This process fills in anything missing in the template. TODO: How does this get handled, do we need to tweak any of the callbacks? 2. Calculate them -> This process produces a list of hashes... TODO: Why? Is this a list of all the subordinate policies or can the json file have N policies where N > 1? 3. Execute them -> Execute the policy on a session. TODO: Who is supposed to start the policy session as it seems to be 0? Their are a lot of TODO items in this code. I'm looking for how we want to use this, different tools, like tpm2_policyinit tpm2_policycalc and tpm2_policyexec? Or an all in-one tool. Currently note that ONLY the Execute needs an ESYS context, but instantiate should be filling stuff in so it likely needs a context or the callbacks handled? Signed-off-by: William Roberts --- Makefile.am | 5 +- configure.ac | 1 + tools/misc/tpm2_policy.c | 165 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 tools/misc/tpm2_policy.c diff --git a/Makefile.am b/Makefile.am index d02e78353..2e3bfc362 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,13 +19,13 @@ LIB_COMMON := lib/libcommon.a AM_CFLAGS := \ $(INCLUDE_DIRS) $(EXTRA_CFLAGS) $(TSS2_ESYS_CFLAGS) $(TSS2_MU_CFLAGS) \ $(CRYPTO_CFLAGS) $(CODE_COVERAGE_CFLAGS) $(TSS2_TCTILDR_CFLAGS) \ - $(TSS2_RC_CFLAGS) $(TSS2_SYS_CFLAGS) + $(TSS2_RC_CFLAGS) $(TSS2_SYS_CFLAGS) $(TSS2_POLICY_CFLAGS) AM_LDFLAGS := $(EXTRA_LDFLAGS) $(CODE_COVERAGE_LIBS) LDADD = \ $(LIB_COMMON) $(TSS2_ESYS_LIBS) $(TSS2_MU_LIBS) $(CRYPTO_LIBS) $(TSS2_TCTILDR_LIBS) \ - $(TSS2_RC_LIBS) $(TSS2_SYS_LIBS) $(EFIVAR_LIBS) + $(TSS2_RC_LIBS) $(TSS2_SYS_LIBS) $(EFIVAR_LIBS) $(TSS2_POLICY_LIBS) AM_DISTCHECK_CONFIGURE_FLAGS = --with-bashcompdir='$$(datarootdir)/bash-completion/completions' @@ -105,6 +105,7 @@ tpm2_tools = \ tools/misc/tpm2_checkquote.c \ tools/misc/tpm2_encodeobject.c \ tools/misc/tpm2_eventlog.c \ + tools/misc/tpm2_policy.c \ tools/misc/tpm2_print.c \ tools/misc/tpm2_rc_decode.c \ tools/tpm2_activatecredential.c \ diff --git a/configure.ac b/configure.ac index f1c171168..a71f9a001 100644 --- a/configure.ac +++ b/configure.ac @@ -58,6 +58,7 @@ PKG_CHECK_MODULES([TSS2_TCTILDR], [tss2-tctildr]) PKG_CHECK_MODULES([TSS2_MU], [tss2-mu]) PKG_CHECK_MODULES([TSS2_RC], [tss2-rc]) PKG_CHECK_MODULES([TSS2_SYS], [tss2-sys]) +PKG_CHECK_MODULES([TSS2_POLICY], [tss2-policy]) PKG_CHECK_MODULES([CRYPTO], [libcrypto >= 1.1.0]) PKG_CHECK_MODULES([CURL], [libcurl]) diff --git a/tools/misc/tpm2_policy.c b/tools/misc/tpm2_policy.c new file mode 100644 index 000000000..72583d837 --- /dev/null +++ b/tools/misc/tpm2_policy.c @@ -0,0 +1,165 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ + +#include +#include +#include +#include + +#include + +#include "log.h" +#include "tpm2_tool.h" +#include "tpm2_util.h" + +typedef struct tpm2_policy_ctx tpm2_policy_ctx; +struct tpm2_policy_ctx { + ifapi_policyeval_INST_CB cb; + const char *policy_file; +}; + +static tpm2_policy_ctx ctx; + +static bool on_arg(int argc, char *argv[]) { + + if (argc != 1) { + LOG_ERR("Expected single file path argument"); + return false; + } + + ctx.policy_file = argv[0]; + + return true; +} + +static bool tpm2_tool_onstart(tpm2_options **opts) { +// static const struct option topts[] = { +// { "type", required_argument, NULL, 't' }, +// { "format", required_argument, NULL, 'f' }, +// }; + + *opts = tpm2_options_new(NULL, 0, NULL, NULL, on_arg, + 0); + + return *opts != NULL; +} + +static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { + UNUSED(flags); + + TPMS_POLICY *policy_ctx; + + TSS2_RC rc = Tss2_PolicyInstantiate( + ctx.policy_file, + &ctx.cb, + &policy_ctx); + if (rc) { + LOG_ERR("Instantiate failed"); + return tool_rc_general_error; + } + + rc = Tss2_PolicyCalculate( + policy_ctx->policy, /* could we just pass context and drop these? */ + &policy_ctx->policyDigests, /* same as above */ + TPM2_ALG_SHA256, + 32, /* this could be computed from alg... */ + 0); /* I can't figure out what this is for, looks like some kind of recursion in the tss2 lib */ + if (rc) { + LOG_ERR("Calculate failed"); + return tool_rc_general_error; + } + + /* Why doesn't calculate give us the aggregate hash? */ + printf("hash: "); + tpm2_util_hexdump2(stdout, policy_ctx->policyDigests.digests[0].digest.sha256, 32); + printf("\n"); + + /* TODO TAKE USER INPUTS */ + TPM2B_SENSITIVE_CREATE inSensitivePrimary = { 0 }; + + TPM2B_PUBLIC inPublic = { + .size = 0, + .publicArea = { + .type = TPM2_ALG_RSA, + .nameAlg = TPM2_ALG_SHA256, + .objectAttributes = (TPMA_OBJECT_USERWITHAUTH | + TPMA_OBJECT_RESTRICTED | + TPMA_OBJECT_DECRYPT | + TPMA_OBJECT_FIXEDTPM | + TPMA_OBJECT_FIXEDPARENT | + TPMA_OBJECT_SENSITIVEDATAORIGIN), + .authPolicy = { + .size = 0, + }, + .parameters.rsaDetail = { + .symmetric = { + .algorithm = TPM2_ALG_AES, + .keyBits.aes = 128, + .mode.aes = TPM2_ALG_CFB}, + .scheme = { + .scheme = TPM2_ALG_NULL + }, + .keyBits = 2048, + .exponent = 0, + }, + .unique.rsa = { + .size = 0, + .buffer = {}, + }, + }, + }; + + TPMT_SYM_DEF symmetric = {.algorithm = TPM2_ALG_AES, + .keyBits = {.aes = 128}, + .mode = {.aes = TPM2_ALG_CFB} + }; + + TPM2B_NONCE nonceCaller = { + .size = 32, + .buffer = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32} + }; + + TPM2B_DATA outsideInfo = { 0 }; + TPML_PCR_SELECTION creationPCR = { 0 }; + ESYS_TR primaryHandle = ESYS_TR_NONE; + TPM2B_PUBLIC *outPublic = NULL; + TPM2B_CREATION_DATA *creationData = NULL; + TPM2B_DIGEST *creationHash = NULL; + TPMT_TK_CREATION *creationTicket = NULL; + ESYS_TR session = ESYS_TR_NONE; + + rc = Esys_CreatePrimary(ectx, ESYS_TR_RH_OWNER, ESYS_TR_PASSWORD, + ESYS_TR_NONE, ESYS_TR_NONE, &inSensitivePrimary, &inPublic, + &outsideInfo, &creationPCR, &primaryHandle, + &outPublic, &creationData, &creationHash, + &creationTicket); + if (rc) { + LOG_ERR("CreatePrimary failed"); + return tool_rc_general_error; + } + + rc = Esys_StartAuthSession(ectx, + primaryHandle, // tpm key + ESYS_TR_NONE, // bind key + ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, // sessions + &nonceCaller, TPM2_SE_POLICY, &symmetric, TPM2_ALG_SHA256, &session); + if (rc) { + LOG_ERR("StartAuthSession failed"); + return tool_rc_general_error; + } + + rc = Tss2_PolicyExecute( + TPM2_ALG_SHA256, + policy_ctx, + ectx, + session); + if (rc) { + LOG_ERR("Execute failed"); + return tool_rc_general_error; + } + + return tool_rc_success; +} + +// Register this tool with tpm2_tool.c +TPM2_TOOL_REGISTER("policy", tpm2_tool_onstart, tpm2_tool_onrun, NULL, NULL) From ad5f8ee108196137eabb0b54fecd7a0dbfe9a692 Mon Sep 17 00:00:00 2001 From: William Roberts Date: Wed, 12 Jan 2022 17:00:05 -0600 Subject: [PATCH 2/6] factor out PolicyCalculate policy and policyDigest args to just policy ctx Signed-off-by: William Roberts --- tools/misc/tpm2_policy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/misc/tpm2_policy.c b/tools/misc/tpm2_policy.c index 72583d837..f5347e101 100644 --- a/tools/misc/tpm2_policy.c +++ b/tools/misc/tpm2_policy.c @@ -58,8 +58,7 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { } rc = Tss2_PolicyCalculate( - policy_ctx->policy, /* could we just pass context and drop these? */ - &policy_ctx->policyDigests, /* same as above */ + policy_ctx, TPM2_ALG_SHA256, 32, /* this could be computed from alg... */ 0); /* I can't figure out what this is for, looks like some kind of recursion in the tss2 lib */ @@ -158,6 +157,7 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { return tool_rc_general_error; } + printf("success\n"); return tool_rc_success; } From d9f4c525b9528b182a19f66f4b23f58eeddaa3c2 Mon Sep 17 00:00:00 2001 From: William Roberts Date: Wed, 12 Jan 2022 18:20:24 -0600 Subject: [PATCH 3/6] drop blocking fapi, use fapi io module Signed-off-by: William Roberts --- tools/misc/tpm2_policy.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tools/misc/tpm2_policy.c b/tools/misc/tpm2_policy.c index f5347e101..798311b5e 100644 --- a/tools/misc/tpm2_policy.c +++ b/tools/misc/tpm2_policy.c @@ -46,7 +46,7 @@ static bool tpm2_tool_onstart(tpm2_options **opts) { static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { UNUSED(flags); - TPMS_POLICY *policy_ctx; + TSS2_POLICY *policy_ctx = NULL; TSS2_RC rc = Tss2_PolicyInstantiate( ctx.policy_file, @@ -68,8 +68,11 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { } /* Why doesn't calculate give us the aggregate hash? */ + TPMU_HA digest = { 0 }; + Tss2_PolicyGetDigest(policy_ctx, &digest); + printf("hash: "); - tpm2_util_hexdump2(stdout, policy_ctx->policyDigests.digests[0].digest.sha256, 32); + tpm2_util_hexdump2(stdout, digest.sha256, 32); printf("\n"); /* TODO TAKE USER INPUTS */ From 3b4343168cc2269541b6b30f49b2992bde1b42be Mon Sep 17 00:00:00 2001 From: William Roberts Date: Thu, 13 Jan 2022 16:15:07 -0600 Subject: [PATCH 4/6] test that policy digests match Signed-off-by: William Roberts --- tools/misc/tpm2_policy.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tools/misc/tpm2_policy.c b/tools/misc/tpm2_policy.c index 798311b5e..8ff215f0e 100644 --- a/tools/misc/tpm2_policy.c +++ b/tools/misc/tpm2_policy.c @@ -160,6 +160,28 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { return tool_rc_general_error; } + /* AFter execute hashes should match */ + TPM2B_DIGEST *digest2 = NULL; + rc = Esys_PolicyGetDigest(ectx, session, ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, &digest2); + if (rc) { + LOG_ERR("Esys_PolicyGetDigest failed"); + return tool_rc_general_error; + } + + printf("hash: "); + tpm2_util_hexdump2(stdout, digest2->buffer, digest2->size); + printf("\n"); + Esys_Free(digest2); + + const char *description = NULL; + rc = Tss2_PolicyGetDescription(policy_ctx, &description); + if (rc) { + LOG_ERR("Tss2_PolicyGetDescription failed"); + return tool_rc_general_error; + } + + printf("description: \"%s\"\n", description); + printf("success\n"); return tool_rc_success; } From 23c8ba62c341bbda6b017fbaa86f1d36f209ed9a Mon Sep 17 00:00:00 2001 From: William Roberts Date: Fri, 14 Jan 2022 09:23:26 -0600 Subject: [PATCH 5/6] update to refactoring Signed-off-by: William Roberts --- tools/misc/tpm2_policy.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tools/misc/tpm2_policy.c b/tools/misc/tpm2_policy.c index 8ff215f0e..f56244382 100644 --- a/tools/misc/tpm2_policy.c +++ b/tools/misc/tpm2_policy.c @@ -13,7 +13,7 @@ typedef struct tpm2_policy_ctx tpm2_policy_ctx; struct tpm2_policy_ctx { - ifapi_policyeval_INST_CB cb; + TSS2_POLICY_CALLBACKS cb; const char *policy_file; }; @@ -57,20 +57,16 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { return tool_rc_general_error; } + TPMU_HA digest = { 0 }; rc = Tss2_PolicyCalculate( policy_ctx, TPM2_ALG_SHA256, - 32, /* this could be computed from alg... */ - 0); /* I can't figure out what this is for, looks like some kind of recursion in the tss2 lib */ + &digest); if (rc) { LOG_ERR("Calculate failed"); return tool_rc_general_error; } - /* Why doesn't calculate give us the aggregate hash? */ - TPMU_HA digest = { 0 }; - Tss2_PolicyGetDigest(policy_ctx, &digest); - printf("hash: "); tpm2_util_hexdump2(stdout, digest.sha256, 32); printf("\n"); From 04b43921381cb1877c4e87133d98a59dd1189694 Mon Sep 17 00:00:00 2001 From: William Roberts Date: Tue, 18 Jan 2022 13:47:03 -0600 Subject: [PATCH 6/6] update for newest api Signed-off-by: William Roberts --- tools/misc/tpm2_policy.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/misc/tpm2_policy.c b/tools/misc/tpm2_policy.c index f56244382..3826f2943 100644 --- a/tools/misc/tpm2_policy.c +++ b/tools/misc/tpm2_policy.c @@ -57,7 +57,7 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { return tool_rc_general_error; } - TPMU_HA digest = { 0 }; + TPM2B_DIGEST digest = { 0 }; rc = Tss2_PolicyCalculate( policy_ctx, TPM2_ALG_SHA256, @@ -68,7 +68,7 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { } printf("hash: "); - tpm2_util_hexdump2(stdout, digest.sha256, 32); + tpm2_util_hexdump2(stdout, digest.buffer, digest.size); printf("\n"); /* TODO TAKE USER INPUTS */