diff --git a/lib/pcr.c b/lib/pcr.c index 9aa5fbf05..f9e3de5c4 100644 --- a/lib/pcr.c +++ b/lib/pcr.c @@ -605,7 +605,9 @@ bool pcr_check_pcr_selection(TPMS_CAPABILITY_DATA *cap_data, tool_rc pcr_read_pcr_values(ESYS_CONTEXT *esys_context, TPML_PCR_SELECTION *pcr_select, tpm2_pcrs *pcrs, TPM2B_DIGEST *cp_hash, - TPMI_ALG_HASH parameter_hash_algorithm) { + TPMI_ALG_HASH parameter_hash_algorithm, + ESYS_TR session_handle_1, ESYS_TR session_handle_2, + ESYS_TR session_handle_3) { TPML_PCR_SELECTION pcr_selection_tmp; TPML_PCR_SELECTION *pcr_selection_out; @@ -618,8 +620,8 @@ tool_rc pcr_read_pcr_values(ESYS_CONTEXT *esys_context, pcrs->count = 0; do { TPML_DIGEST *v; - tool_rc rc = tpm2_pcr_read(esys_context, ESYS_TR_NONE, ESYS_TR_NONE, - ESYS_TR_NONE, &pcr_selection_tmp, &pcr_update_counter, + tool_rc rc = tpm2_pcr_read(esys_context, session_handle_1, session_handle_2, + session_handle_3, &pcr_selection_tmp, &pcr_update_counter, &pcr_selection_out, &v, cp_hash, parameter_hash_algorithm); if (rc != tool_rc_success || (cp_hash && cp_hash->size)) { diff --git a/lib/pcr.h b/lib/pcr.h index c584c7d43..63b352340 100644 --- a/lib/pcr.h +++ b/lib/pcr.h @@ -114,6 +114,8 @@ bool pcr_check_pcr_selection(TPMS_CAPABILITY_DATA *cap_data, tool_rc pcr_read_pcr_values(ESYS_CONTEXT *esys_context, TPML_PCR_SELECTION *pcr_selections, tpm2_pcrs *pcrs, - TPM2B_DIGEST *cp_hash, TPMI_ALG_HASH parameter_hash_algorithm); + TPM2B_DIGEST *cp_hash, TPMI_ALG_HASH parameter_hash_algorithm, + ESYS_TR session_handle_1, ESYS_TR session_handle_2, + ESYS_TR session_handle_3); #endif /* SRC_PCR_H_ */ diff --git a/lib/tpm2.c b/lib/tpm2.c index 6098f7a9e..501458fde 100644 --- a/lib/tpm2.c +++ b/lib/tpm2.c @@ -5115,10 +5115,21 @@ tool_rc tpm2_loadexternal(ESYS_CONTEXT *ectx, const TPM2B_SENSITIVE *private, } tool_rc tpm2_pcr_extend(ESYS_CONTEXT *ectx, TPMI_DH_PCR pcr_index, - TPML_DIGEST_VALUES *digests) { + tpm2_session *session, + TPML_DIGEST_VALUES *digests, + ESYS_TR session_handle_2, + ESYS_TR session_handle_3) { - TSS2_RC rval = Esys_PCR_Extend(ectx, pcr_index, ESYS_TR_PASSWORD, - ESYS_TR_NONE, ESYS_TR_NONE, digests); + ESYS_TR shandle1 = ESYS_TR_NONE; + tool_rc rc = tpm2_auth_util_get_shandle(ectx, pcr_index, session, + &shandle1); + if (rc != tool_rc_success) { + return rc; + } + + + TSS2_RC rval = Esys_PCR_Extend(ectx, pcr_index, shandle1, + session_handle_2, session_handle_3, digests); if (rval != TSS2_RC_SUCCESS) { LOG_PERR(Esys_PCR_Extend, rval); return tool_rc_from_tpm(rval); @@ -5129,7 +5140,8 @@ tool_rc tpm2_pcr_extend(ESYS_CONTEXT *ectx, TPMI_DH_PCR pcr_index, tool_rc tpm2_pcr_event(ESYS_CONTEXT *ectx, ESYS_TR pcr, tpm2_session *session, const TPM2B_EVENT *event_data, TPML_DIGEST_VALUES **digests, - TPM2B_DIGEST *cp_hash, TPMI_ALG_HASH parameter_hash_algorithm) { + TPM2B_DIGEST *cp_hash, TPMI_ALG_HASH parameter_hash_algorithm, + ESYS_TR session_handle_2, ESYS_TR session_handle_3) { TSS2_RC rval = TSS2_RC_SUCCESS; tool_rc rc = tool_rc_success; @@ -5176,8 +5188,8 @@ tool_rc tpm2_pcr_event(ESYS_CONTEXT *ectx, ESYS_TR pcr, tpm2_session *session, return rc; } - rval = Esys_PCR_Event(ectx, pcr, shandle1, ESYS_TR_NONE, - ESYS_TR_NONE, event_data, digests); + rval = Esys_PCR_Event(ectx, pcr, shandle1, session_handle_2, + session_handle_3, event_data, digests); if (rval != TSS2_RC_SUCCESS) { LOG_PERR(Esys_PCR_Event, rval); return tool_rc_from_tpm(rval); diff --git a/lib/tpm2.h b/lib/tpm2.h index 67940c0ed..46a9aa677 100644 --- a/lib/tpm2.h +++ b/lib/tpm2.h @@ -430,11 +430,14 @@ tool_rc tpm2_loadexternal(ESYS_CONTEXT *ectx, const TPM2B_SENSITIVE *private, TPMI_ALG_HASH parameter_hash_algorithm); tool_rc tpm2_pcr_extend(ESYS_CONTEXT *ectx, TPMI_DH_PCR pcr_index, - TPML_DIGEST_VALUES *digests); + tpm2_session *session, + TPML_DIGEST_VALUES *digests, + ESYS_TR session_handle_2, ESYS_TR session_handle_3); tool_rc tpm2_pcr_event(ESYS_CONTEXT *ectx, ESYS_TR pcr, tpm2_session *session, const TPM2B_EVENT *event_data, TPML_DIGEST_VALUES **digests, - TPM2B_DIGEST *cp_hash, TPMI_ALG_HASH parameter_hash_algorithm); + TPM2B_DIGEST *cp_hash, TPMI_ALG_HASH parameter_hash_algorithm, + ESYS_TR session_handle_2, ESYS_TR session_handle_3); tool_rc tpm2_getrandom(ESYS_CONTEXT *ectx, UINT16 count, TPM2B_DIGEST **random, TPM2B_DIGEST *cp_hash, TPM2B_DIGEST *rp_hash, diff --git a/lib/tpm2_policy.c b/lib/tpm2_policy.c index 5f8ad45fa..27d009f52 100644 --- a/lib/tpm2_policy.c +++ b/lib/tpm2_policy.c @@ -212,7 +212,8 @@ tool_rc tpm2_policy_build_pcr(ESYS_CONTEXT *ectx, tpm2_session *policy_session, } else { // Read PCRs tool_rc rc = pcr_read_pcr_values(ectx, pcr_selections, &pcrs, - NULL, TPM2_ALG_ERROR); + NULL, TPM2_ALG_ERROR, ESYS_TR_NONE, + ESYS_TR_NONE, ESYS_TR_NONE); if (rc != tool_rc_success) { return rc; } diff --git a/man/tpm2_pcrevent.1.md b/man/tpm2_pcrevent.1.md index 79ff29384..d05110886 100644 --- a/man/tpm2_pcrevent.1.md +++ b/man/tpm2_pcrevent.1.md @@ -36,15 +36,23 @@ These options control extending the pcr: Specifies the authorization value for PCR. + * **-S**, **\--session**=_FILE_: + + Specifies the auxiliary sessions for the command. + * **\--cphash**=_FILE_ File path to record the hash of the command parameters. This is commonly termed as cpHash. NOTE: When this option is selected, The tool will not actually execute the command, it simply returns a cpHash. -[common options](common/options.md) +## References + +[common options](common/options.md) collection of common options that provide +information many users may expect. -[common tcti options](common/tcti.md) +[common tcti options](common/tcti.md) collection of options used to configure +the various known TCTI modules. [authorization formatting](common/authorizations.md) diff --git a/man/tpm2_pcrextend.1.md b/man/tpm2_pcrextend.1.md index a57d1bd84..dd6f22d37 100644 --- a/man/tpm2_pcrextend.1.md +++ b/man/tpm2_pcrextend.1.md @@ -36,7 +36,13 @@ supported. This is to keep the parser simple. # OPTIONS -This tool accepts no tool specific options. +* **-P**, **\--auth**=_AUTH_: + +The authorization value of the used PCR register. + +* **-S**, **\--session**=_FILE_: + +Specifies the auxiliary sessions for the command. [common options](common/options.md) diff --git a/man/tpm2_pcrread.1.md b/man/tpm2_pcrread.1.md index 4cc59da2f..0c55d3838 100644 --- a/man/tpm2_pcrread.1.md +++ b/man/tpm2_pcrread.1.md @@ -48,6 +48,10 @@ sha256 : termed as cpHash. NOTE: When this option is selected, The tool will not actually execute the command, it simply returns a cpHash. + * **-S**, **\--session**=_FILE_: + + Specifies the auxiliary sessions for the command. + [PCR output file format specifiers](common/pcrs_format.md) Default is 'values'. diff --git a/test/integration/tests/pcrevent.sh b/test/integration/tests/pcrevent.sh index d71667895..49ad80ee1 100644 --- a/test/integration/tests/pcrevent.sh +++ b/test/integration/tests/pcrevent.sh @@ -10,7 +10,7 @@ yaml_out_file=pcr_list.yaml cleanup() { rm -f $hash_in_file $hash_out_file $yaml_out_file - + rm -f audit_session.ctx hmac_session.ctx eventfile shut_down } trap cleanup EXIT @@ -83,4 +83,9 @@ if [ $? -eq 0 ]; then exit 1; fi +echo event > eventfile +tpm2 startauthsession -Q --session hmac_session.ctx --hmac +tpm2 startauthsession -Q --session audit_session.ctx --audit +tpm2 pcrevent -S audit_session.ctx -P session:hmac_session.ctx 10 eventfile + exit 0 diff --git a/test/integration/tests/pcrextend.sh b/test/integration/tests/pcrextend.sh index ffc9c22da..fead71d11 100644 --- a/test/integration/tests/pcrextend.sh +++ b/test/integration/tests/pcrextend.sh @@ -2,6 +2,12 @@ source helpers.sh +cleanup() { + rm -f audit_session.ctx hmac_session.ctx + shut_down +} +trap cleanup EXIT + start_up declare -A alg_hashes=( @@ -46,4 +52,9 @@ else true fi +tpm2 startauthsession -Q --session hmac_session.ctx --hmac +tpm2 startauthsession -Q --session audit_session.ctx --audit +tpm2 pcrextend -S audit_session.ctx -P session:hmac_session.ctx \ + 16:sha256=b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c + exit 0 diff --git a/tools/tpm2_pcrevent.c b/tools/tpm2_pcrevent.c index c2651928e..7972deaee 100644 --- a/tools/tpm2_pcrevent.c +++ b/tools/tpm2_pcrevent.c @@ -15,6 +15,7 @@ #include "tpm2_auth_util.h" #include "tpm2_tool.h" +#define MAX_AUX_SESSIONS 2 #define MAX_SESSIONS 3 typedef struct tpm_pcrevent_ctx tpm_pcrevent_ctx; struct tpm_pcrevent_ctx { @@ -37,6 +38,13 @@ struct tpm_pcrevent_ctx { * Outputs */ TPML_DIGEST_VALUES *digests; + /* + * Aux Sessions + */ + uint8_t aux_session_cnt; + tpm2_session *aux_session[MAX_AUX_SESSIONS]; + const char *aux_session_path[MAX_AUX_SESSIONS]; + ESYS_TR aux_session_handle[MAX_AUX_SESSIONS]; /* * Parameter hashes */ @@ -49,6 +57,8 @@ struct tpm_pcrevent_ctx { static tpm_pcrevent_ctx ctx = { .parameter_hash_algorithm = TPM2_ALG_ERROR, .pcr = ESYS_TR_RH_NULL, + .aux_session_handle[0] = ESYS_TR_NONE, + .aux_session_handle[1] = ESYS_TR_NONE, }; static tool_rc pcr_hashsequence(ESYS_CONTEXT *ectx) { @@ -121,13 +131,14 @@ static tool_rc pcr_hashsequence(ESYS_CONTEXT *ectx) { ctx.auth.session, &data, &ctx.digests); } -static tool_rc pcrevent(ESYS_CONTEXT *ectx) { +static tool_rc pcrevent(ESYS_CONTEXT *ectx, ESYS_TR session_handle_2, + ESYS_TR session_handle_3) { tool_rc rc = tool_rc_success; if (!ctx.is_hashsequence_needed) { rc = tpm2_pcr_event(ectx, ctx.pcr, ctx.auth.session, &ctx.pcrevent_buffer, &ctx.digests, &ctx.cp_hash, - ctx.parameter_hash_algorithm); + ctx.parameter_hash_algorithm, session_handle_2, session_handle_3); } else { /* * Note: We must not calculate pHash in this case to avoid overwriting @@ -240,6 +251,11 @@ static tool_rc process_inputs(ESYS_CONTEXT *ectx) { /* * 2. Restore auxiliary sessions */ + rc = tpm2_util_aux_sessions_setup(ectx, ctx.aux_session_cnt, + ctx.aux_session_path, ctx.aux_session_handle, ctx.aux_session); + if (rc != tool_rc_success) { + return rc; + } /* * 3. Command specific initializations @@ -358,6 +374,16 @@ static bool on_option(char key, char *value) { ctx.auth.auth_str = value; break; /* no default */ + case 'S': + ctx.aux_session_path[ctx.aux_session_cnt] = value; + if (ctx.aux_session_cnt < MAX_AUX_SESSIONS) { + ctx.aux_session_cnt++; + } else { + LOG_ERR("Specify a max of 3 sessions"); + return false; + } + break; + /* no default */ case 0: ctx.cp_hash_path = value; break; @@ -369,12 +395,13 @@ static bool on_option(char key, char *value) { static bool tpm2_tool_onstart(tpm2_options **opts) { static const struct option topts[] = { - { "auth", required_argument, NULL, 'P' }, - { "cphash", required_argument, 0, 0 }, + { "auth", required_argument, NULL, 'P' }, + { "cphash", required_argument, 0, 0 }, + { "session", required_argument, NULL, 'S' } }; - *opts = tpm2_options_new("P:", ARRAY_LEN(topts), topts, on_option, on_arg, + *opts = tpm2_options_new("P:S:", ARRAY_LEN(topts), topts, on_option, on_arg, 0); return *opts != NULL; @@ -403,7 +430,8 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { /* * 3. TPM2_CC_ call */ - rc = pcrevent(ectx); + rc = pcrevent(ectx, ctx.aux_session_handle[0], + ctx.aux_session_handle[1]); if (rc != tool_rc_success) { return rc; } diff --git a/tools/tpm2_pcrextend.c b/tools/tpm2_pcrextend.c index 27990b202..490cdee7a 100644 --- a/tools/tpm2_pcrextend.c +++ b/tools/tpm2_pcrextend.c @@ -7,28 +7,53 @@ #include "tpm2_tool.h" #include "tpm2_alg_util.h" #include "tpm2_options.h" +#include "tpm2_auth_util.h" typedef struct tpm_pcr_extend_ctx tpm_pcr_extend_ctx; +#define MAX_AUX_SESSIONS 2 +#define MAX_SESSIONS 3 struct tpm_pcr_extend_ctx { /* * Inputs */ + struct { + const char *auth_str; + tpm2_session *session; + } auth; + size_t digest_spec_len; tpm2_pcr_digest_spec *digest_spec; /* * Outputs */ + + /* + * Aux Sessions + */ + uint8_t aux_session_cnt; + tpm2_session *aux_session[MAX_AUX_SESSIONS]; + const char *aux_session_path[MAX_AUX_SESSIONS]; + ESYS_TR aux_session_handle[MAX_AUX_SESSIONS]; }; static tpm_pcr_extend_ctx ctx; -static tool_rc pcr_extend(ESYS_CONTEXT *ectx) { +static tpm_pcr_extend_ctx ctx = { + .aux_session_handle[0] = ESYS_TR_NONE, + .aux_session_handle[1] = ESYS_TR_NONE, +}; + +static tool_rc pcr_extend(ESYS_CONTEXT *ectx, + ESYS_TR session_handle_2, + ESYS_TR session_handle_3) { size_t i; for (i = 0; i < ctx.digest_spec_len; i++) { tpm2_pcr_digest_spec *dspec = &ctx.digest_spec[i]; - tool_rc rc = tpm2_pcr_extend(ectx, dspec->pcr_index, &dspec->digests); + tool_rc rc = tpm2_pcr_extend(ectx, dspec->pcr_index, ctx.auth.session, + &dspec->digests, + session_handle_2, session_handle_3); if (rc != tool_rc_success) { LOG_ERR("Could not extend pcr index: 0x%X", dspec->pcr_index); return rc; @@ -67,10 +92,21 @@ static tool_rc process_inputs(ESYS_CONTEXT *ectx) { /* * 1.b Add object names and their auth sessions */ + tool_rc rc = tpm2_auth_util_from_optarg(ectx, ctx.auth.auth_str, + &ctx.auth.session, false); + if (rc != tool_rc_success) { + LOG_ERR("Invalid key handle authorization"); + return rc; + } /* * 2. Restore auxiliary sessions */ + rc = tpm2_util_aux_sessions_setup(ectx, ctx.aux_session_cnt, + ctx.aux_session_path, ctx.aux_session_handle, ctx.aux_session); + if (rc != tool_rc_success) { + return rc; + } /* * 3. Command specific initializations @@ -96,6 +132,31 @@ static tool_rc check_options(void) { return tool_rc_success; } +static bool on_options(char key, char *value) { + + UNUSED(key); + + switch (key) { + case 'P': + ctx.auth.auth_str = value; + break; + /* no default */ + case 'S': + ctx.aux_session_path[ctx.aux_session_cnt] = value; + if (ctx.aux_session_cnt < MAX_AUX_SESSIONS) { + ctx.aux_session_cnt++; + } else { + LOG_ERR("Specify a max of 3 sessions"); + return false; + } + break; + /* no default */ + } + + return true; +} + + static bool on_arg(int argc, char **argv) { if (argc < 1) { @@ -118,7 +179,12 @@ static bool on_arg(int argc, char **argv) { static bool tpm2_tool_onstart(tpm2_options **opts) { - *opts = tpm2_options_new(NULL, 0, NULL, NULL, on_arg, 0); + const struct option topts[] = { + { "auth", required_argument, NULL, 'P' }, + { "session", required_argument, NULL, 'S' }, + }; + + *opts = tpm2_options_new("P:S:", ARRAY_LEN(topts), topts, on_options, on_arg, 0); return *opts != NULL; } @@ -146,7 +212,9 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { /* * 3. TPM2_CC_ call */ - rc = pcr_extend(ectx); + rc = pcr_extend(ectx, + ctx.aux_session_handle[0], + ctx.aux_session_handle[1]); if (rc != tool_rc_success) { return rc; } diff --git a/tools/tpm2_pcrread.c b/tools/tpm2_pcrread.c index 4248cbef5..50d232a64 100644 --- a/tools/tpm2_pcrread.c +++ b/tools/tpm2_pcrread.c @@ -11,6 +11,7 @@ #include "tpm2_tool.h" #include "files.h" +#define MAX_AUX_SESSIONS 3 #define MAX_SESSIONS 3 typedef struct listpcr_context listpcr_context; struct listpcr_context { @@ -29,6 +30,13 @@ struct listpcr_context { */ char *output_file_path; FILE *output_file; + /* + * Aux Sessions + */ + uint8_t aux_session_cnt; + tpm2_session *aux_session[MAX_AUX_SESSIONS]; + const char *aux_session_path[MAX_AUX_SESSIONS]; + ESYS_TR aux_session_handle[MAX_AUX_SESSIONS]; /* * Parameter hashes */ @@ -40,13 +48,18 @@ struct listpcr_context { static listpcr_context ctx = { .parameter_hash_algorithm = TPM2_ALG_ERROR, - .format = pcrs_output_format_values + .format = pcrs_output_format_values, + .aux_session_handle[0] = ESYS_TR_NONE, + .aux_session_handle[1] = ESYS_TR_NONE, + .aux_session_handle[2] = ESYS_TR_NONE, }; -static tool_rc pcrread(ESYS_CONTEXT *ectx) { +static tool_rc pcrread(ESYS_CONTEXT *ectx, ESYS_TR session_handle_1, + ESYS_TR session_handle_2, ESYS_TR session_handle_3) { tool_rc rc = pcr_read_pcr_values(ectx, &ctx.pcr_selections, &ctx.pcrs, - &ctx.cp_hash, ctx.parameter_hash_algorithm); + &ctx.cp_hash, ctx.parameter_hash_algorithm, + session_handle_1, session_handle_2, session_handle_3); if (rc != tool_rc_success) { LOG_ERR("Failed TPM2_CC_PCR_Read"); } @@ -111,11 +124,16 @@ static tool_rc process_inputs(ESYS_CONTEXT *ectx) { /* * 2. Restore auxiliary sessions */ + tool_rc rc = tpm2_util_aux_sessions_setup(ectx, ctx.aux_session_cnt, + ctx.aux_session_path, ctx.aux_session_handle, ctx.aux_session); + if (rc != tool_rc_success) { + return rc; + } /* * 3. Command specific initializations */ - tool_rc rc = pcr_get_banks(ectx, &ctx.capdata, &ctx.algs); + rc = pcr_get_banks(ectx, &ctx.capdata, &ctx.algs); if (rc != tool_rc_success) { return rc; } @@ -184,6 +202,16 @@ static bool on_option(char key, char *value) { } break; /* no default */ + case 'S': + ctx.aux_session_path[ctx.aux_session_cnt] = value; + if (ctx.aux_session_cnt < MAX_AUX_SESSIONS) { + ctx.aux_session_cnt++; + } else { + LOG_ERR("Specify a max of 3 sessions"); + return false; + } + break; + /* no default */ case 0: ctx.cp_hash_path = value; break; @@ -218,9 +246,10 @@ static bool tpm2_tool_onstart(tpm2_options **opts) { { "output", required_argument, NULL, 'o' }, { "pcrs_format", required_argument, NULL, 'F' }, { "cphash", required_argument, 0, 0 }, + { "session", required_argument, NULL, 'S' } }; - *opts = tpm2_options_new("o:F:", ARRAY_LEN(topts), topts, on_option, on_arg, + *opts = tpm2_options_new("o:F:S:", ARRAY_LEN(topts), topts, on_option, on_arg, 0); return *opts != NULL; @@ -249,7 +278,10 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) { /* * 3. TPM2_CC_ call */ - rc = pcrread(ectx); + rc = pcrread(ectx, + ctx.aux_session_handle[0], + ctx.aux_session_handle[1], + ctx.aux_session_handle[2]); if (rc != tool_rc_success) { return rc; } diff --git a/tools/tpm2_quote.c b/tools/tpm2_quote.c index 55c3ef978..ba8729153 100644 --- a/tools/tpm2_quote.c +++ b/tools/tpm2_quote.c @@ -159,7 +159,8 @@ static tool_rc process_output(ESYS_CONTEXT *ectx) { // Gather PCR values from the TPM (the quote doesn't have them!) rc = pcr_read_pcr_values(ectx, &ctx.pcr_selections, &ctx.pcrs, - NULL, TPM2_ALG_ERROR); + NULL, TPM2_ALG_ERROR, ESYS_TR_NONE, + ESYS_TR_NONE, ESYS_TR_NONE); if (rc != tool_rc_success) { LOG_ERR("Failed to retrieve PCR values related to quote!"); return rc;