123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684 |
- /* SPDX-License-Identifier: BSD-3-Clause */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "files.h"
- #include "log.h"
- #include "tpm2.h"
- #include "tpm2_alg_util.h"
- #include "tpm2_openssl.h"
- #include "tpm2_policy.h"
- #include "tpm2_tool.h"
- #include "tpm2_util.h"
- static bool evaluate_populate_pcr_digests(TPML_PCR_SELECTION *pcr_selections,
- const char *raw_pcrs_file, TPML_DIGEST *pcr_values) {
- unsigned expected_pcr_input_file_size = 0;
- unsigned dgst_cnt = 0;
- //Iterating the number of pcr banks selected
- UINT32 i;
- for (i = 0; i < pcr_selections->count; i++) {
- UINT8 total_indices_for_this_alg = 0;
- //Looping to check total pcr select bits in the pcr-select-octets for a bank
- UINT32 j;
- for (j = 0; j < pcr_selections->pcrSelections[i].sizeofSelect; j++) {
- UINT8 group_val = pcr_selections->pcrSelections[i].pcrSelect[j];
- total_indices_for_this_alg += tpm2_util_pop_count(group_val);
- }
- if (pcr_values->count
- + total_indices_for_this_alg> ARRAY_LEN(pcr_values->digests)) {
- LOG_ERR("Number of PCR is limited to %zu",
- ARRAY_LEN(pcr_values->digests));
- return false;
- }
- //digest size returned per the hashAlg type
- unsigned dgst_size = tpm2_alg_util_get_hash_size(
- pcr_selections->pcrSelections[i].hash);
- if (!dgst_size) {
- return false;
- }
- expected_pcr_input_file_size +=
- (total_indices_for_this_alg * dgst_size);
- //Cumulative total of all the pcr indices across banks selected in setlist
- pcr_values->count += total_indices_for_this_alg;
- /*
- * Populating the digest sizes in the PCR digest list per algorithm bank
- * Once iterated through all banks, creates an file offsets map for all pcr indices
- */
- UINT8 k;
- for (k = 0; k < total_indices_for_this_alg; k++) {
- pcr_values->digests[dgst_cnt].size = dgst_size;
- dgst_cnt++;
- }
- }
- //Check if the input pcrs file size is the same size as the pcr selection setlist
- if (raw_pcrs_file) {
- unsigned long filesize = 0;
- bool result = files_get_file_size_path(raw_pcrs_file, &filesize);
- if (!result) {
- LOG_ERR("Could not retrieve raw_pcrs_file size");
- return false;
- }
- if (filesize != expected_pcr_input_file_size) {
- LOG_ERR("pcr-input-file filesize does not match pcr set-list");
- return false;
- }
- }
- return true;
- }
- tool_rc tpm2_policy_build_pcr(ESYS_CONTEXT *ectx, tpm2_session *policy_session,
- const char *raw_pcrs_file, TPML_PCR_SELECTION *pcr_selections,
- TPM2B_DIGEST *raw_pcr_digest) {
- TPML_DIGEST pcr_values = { .count = 0 };
- if (!pcr_selections->count) {
- LOG_ERR("No pcr selection data specified!");
- return tool_rc_general_error;
- }
- TPM2B_DIGEST pcr_digest = TPM2B_TYPE_INIT(TPM2B_DIGEST, buffer);
- TPMI_ALG_HASH auth_hash = tpm2_session_get_authhash(policy_session);
- ESYS_TR handle = tpm2_session_get_handle(policy_session);
- /*
- * If digest of all PCRs is directly given, handle it here.
- */
- if (raw_pcr_digest &&
- raw_pcr_digest->size != tpm2_alg_util_get_hash_size(auth_hash)) {
- LOG_ERR("Specified PCR digest length not suitable with the policy session digest");
- return tool_rc_general_error;
- }
- // Call the PolicyPCR command
- if (raw_pcr_digest) {
- return tpm2_policy_pcr(ectx, handle, ESYS_TR_NONE, ESYS_TR_NONE,
- ESYS_TR_NONE, raw_pcr_digest, pcr_selections);
- }
- bool result = evaluate_populate_pcr_digests(pcr_selections, raw_pcrs_file,
- &pcr_values);
- if (!result) {
- return tool_rc_general_error;
- }
- //If PCR input for policy is from raw pcrs file
- if (raw_pcrs_file) {
- FILE *fp = fopen(raw_pcrs_file, "rb");
- if (fp == NULL) {
- LOG_ERR("Cannot open pcr-input-file %s", raw_pcrs_file);
- return tool_rc_general_error;
- }
- // Bank hashAlg values dictates the order of the list of digests
- unsigned i;
- for (i = 0; i < pcr_values.count; i++) {
- size_t sz = fread(&pcr_values.digests[i].buffer, 1,
- pcr_values.digests[i].size, fp);
- if (sz != pcr_values.digests[i].size) {
- const char *msg =
- ferror(fp) ? strerror(errno) : "end of file reached";
- LOG_ERR("Reading from file \"%s\" failed: %s", raw_pcrs_file,
- msg);
- fclose(fp);
- return tool_rc_general_error;
- }
- }
- fclose(fp);
- } else {
- UINT32 pcr_update_counter;
- TPML_DIGEST *pcr_val = NULL;
- // Read PCRs
- tool_rc rc = tpm2_pcr_read(ectx, ESYS_TR_NONE, ESYS_TR_NONE,
- ESYS_TR_NONE, pcr_selections, &pcr_update_counter,
- NULL, &pcr_val);
- if (rc != tool_rc_success) {
- return rc;
- }
- UINT32 i;
- pcr_val->count = pcr_values.count;
- for (i = 0; i < pcr_val->count; i++) {
- memcpy(pcr_values.digests[i].buffer, pcr_val->digests[i].buffer,
- pcr_val->digests[i].size);
- pcr_values.digests[i].size = pcr_val->digests[i].size;
- }
- free(pcr_val);
- }
- // Calculate hashes
- result = tpm2_openssl_hash_pcr_values(auth_hash, &pcr_values, &pcr_digest);
- if (!result) {
- LOG_ERR("Could not hash pcr values");
- return tool_rc_general_error;
- }
- // Call the PolicyPCR command
- return tpm2_policy_pcr(ectx, handle, ESYS_TR_NONE, ESYS_TR_NONE,
- ESYS_TR_NONE, &pcr_digest, pcr_selections);
- }
- tool_rc tpm2_policy_build_policyauthorize(ESYS_CONTEXT *ectx,
- tpm2_session *policy_session, const char *policy_digest_path,
- const char *qualifying_data,
- const char *verifying_pubkey_name_path, const char *ticket_path) {
- bool result = true;
- TPM2B_DIGEST approved_policy = { .size = 0 };
- if (policy_digest_path) {
- approved_policy.size = sizeof(TPMU_HA);
- result = files_load_bytes_from_path(policy_digest_path,
- approved_policy.buffer, &approved_policy.size);
- }
- if (!result) {
- return tool_rc_general_error;
- }
- /*
- * Qualifier data is optional. If not specified default to 0
- */
- TPM2B_NONCE policy_qualifier = { .size = 0 };
- if (qualifying_data) {
- policy_qualifier.size = sizeof(policy_qualifier.buffer);
- result = tpm2_util_bin_from_hex_or_file(qualifying_data,
- &policy_qualifier.size, policy_qualifier.buffer);
- if (!result) {
- return tool_rc_general_error;
- }
- }
- unsigned long file_size = 0;
- result = files_get_file_size_path(verifying_pubkey_name_path, &file_size);
- if (!result) {
- return tool_rc_general_error;
- }
- if (!file_size) {
- LOG_ERR("Verifying public key name file \"%s\", cannot be empty",
- verifying_pubkey_name_path);
- return tool_rc_general_error;
- }
- TPM2B_NAME key_sign = { .size = (uint16_t) file_size };
- result = files_load_bytes_from_path(verifying_pubkey_name_path,
- key_sign.name, &key_sign.size);
- if (!result) {
- return tool_rc_general_error;
- }
- TPMT_TK_VERIFIED check_ticket = { .tag = TPM2_ST_VERIFIED, .hierarchy =
- TPM2_RH_OWNER, .digest = { 0 } };
- result = tpm2_session_is_trial(policy_session);
- if (!result) {
- result = files_load_ticket(ticket_path, &check_ticket);
- if (!result) {
- LOG_ERR("Could not load verification ticket file");
- return tool_rc_general_error;
- }
- }
- ESYS_TR sess_handle = tpm2_session_get_handle(policy_session);
- return tpm2_policy_authorize(ectx, sess_handle, ESYS_TR_NONE, ESYS_TR_NONE,
- ESYS_TR_NONE, &approved_policy, &policy_qualifier, &key_sign,
- &check_ticket);
- }
- tool_rc tpm2_policy_build_policyor(ESYS_CONTEXT *ectx,
- tpm2_session *policy_session, TPML_DIGEST *policy_list) {
- ESYS_TR sess_handle = tpm2_session_get_handle(policy_session);
- return tpm2_policy_or(ectx, sess_handle, ESYS_TR_NONE, ESYS_TR_NONE,
- ESYS_TR_NONE, policy_list);
- }
- tool_rc tpm2_policy_build_policypassword(ESYS_CONTEXT *ectx,
- tpm2_session *session) {
- ESYS_TR policy_session_handle = tpm2_session_get_handle(session);
- return tpm2_policy_password(ectx, policy_session_handle, ESYS_TR_NONE,
- ESYS_TR_NONE, ESYS_TR_NONE);
- }
- tool_rc tpm2_policy_build_policynamehash(ESYS_CONTEXT *ectx,
- tpm2_session *session, const TPM2B_DIGEST *name_hash) {
- ESYS_TR policy_session_handle = tpm2_session_get_handle(session);
- return tpm2_policy_namehash(ectx, policy_session_handle, name_hash);
- }
- tool_rc tpm2_policy_build_policytemplate(ESYS_CONTEXT *ectx,
- tpm2_session *session, const TPM2B_DIGEST *template_hash) {
- ESYS_TR policy_session_handle = tpm2_session_get_handle(session);
- return tpm2_policy_template(ectx, policy_session_handle, template_hash);
- }
- tool_rc tpm2_policy_build_policycphash(ESYS_CONTEXT *ectx,
- tpm2_session *session, const TPM2B_DIGEST *cphash) {
- ESYS_TR policy_session_handle = tpm2_session_get_handle(session);
- return tpm2_policy_cphash(ectx, policy_session_handle, cphash);
- }
- tool_rc tpm2_policy_build_policyauthvalue(ESYS_CONTEXT *ectx,
- tpm2_session *session) {
- ESYS_TR policy_session_handle = tpm2_session_get_handle(session);
- return tpm2_policy_authvalue(ectx, policy_session_handle, ESYS_TR_NONE,
- ESYS_TR_NONE, ESYS_TR_NONE);
- }
- tool_rc tpm2_policy_build_policysecret(ESYS_CONTEXT *ectx,
- tpm2_session *policy_session, tpm2_loaded_object *auth_entity_obj,
- INT32 expiration, TPMT_TK_AUTH **policy_ticket,
- TPM2B_TIMEOUT **timeout, bool is_nonce_tpm,
- const char *policy_qualifier_data, TPM2B_DIGEST *cp_hash) {
- /*
- * Qualifier data is optional. If not specified default to 0
- */
- TPM2B_NONCE policy_qualifier = TPM2B_EMPTY_INIT;
- if (policy_qualifier_data) {
- policy_qualifier.size = sizeof(policy_qualifier.buffer);
- bool result = tpm2_util_bin_from_hex_or_file(policy_qualifier_data,
- &policy_qualifier.size,
- policy_qualifier.buffer);
- if (!result) {
- return tool_rc_general_error;
- }
- }
- ESYS_TR policy_session_handle = tpm2_session_get_handle(policy_session);
- TPM2B_NONCE *nonce_tpm = NULL;
- tool_rc rc = tool_rc_success;
- if (is_nonce_tpm) {
- rc = tpm2_sess_get_noncetpm(ectx, policy_session_handle, &nonce_tpm);
- if (rc != tool_rc_success) {
- goto tpm2_policy_build_policysecret_out;
- }
- }
- rc = tpm2_policy_secret(ectx, auth_entity_obj, policy_session_handle,
- expiration, policy_ticket, timeout, nonce_tpm, &policy_qualifier,
- cp_hash);
- tpm2_policy_build_policysecret_out:
- Esys_Free(nonce_tpm);
- return rc;
- }
- tool_rc tpm2_policy_build_policyticket(ESYS_CONTEXT *ectx,
- tpm2_session *policy_session, char *policy_timeout_path,
- const char *qualifier_data, char *policy_ticket_path,
- const char *auth_name_path) {
- unsigned long file_size = 0;
- bool result = files_get_file_size_path(policy_timeout_path, &file_size);
- if (!result) {
- return tool_rc_general_error;
- }
- TPM2B_TIMEOUT policy_timeout = { .size = (uint16_t) file_size };
- if (policy_timeout.size) {
- result = files_load_bytes_from_path(policy_timeout_path,
- policy_timeout.buffer, &policy_timeout.size);
- if (!result) {
- return tool_rc_general_error;
- }
- }
- result = files_get_file_size_path(auth_name_path, &file_size);
- if (!result) {
- return tool_rc_general_error;
- }
- TPM2B_NAME auth_name = { .size = (uint16_t) file_size };
- if (auth_name.size) {
- result = files_load_bytes_from_path(auth_name_path,
- auth_name.name, &auth_name.size);
- if (!result) {
- return tool_rc_general_error;
- }
- }
- TPM2B_NONCE policyref = TPM2B_EMPTY_INIT;
- if (qualifier_data) {
- policyref.size = sizeof(policyref.buffer);
- result = tpm2_util_bin_from_hex_or_file(qualifier_data, &policyref.size,
- policyref.buffer);
- if (!result) {
- return tool_rc_general_error;
- }
- }
- TPMT_TK_AUTH ticket = { 0 };
- result = files_load_authorization_ticket(policy_ticket_path, &ticket);
- if (!result) {
- LOG_ERR("Failed loading authorization ticket.");
- return tool_rc_general_error;
- }
- ESYS_TR policy_session_handle = tpm2_session_get_handle(policy_session);
- return tpm2_policy_ticket(ectx, policy_session_handle, &policy_timeout,
- &policyref, &auth_name, &ticket);
- return tool_rc_success;
- }
- tool_rc tpm2_policy_build_policysigned(ESYS_CONTEXT *ectx,
- tpm2_session *policy_session, tpm2_loaded_object *auth_entity_obj,
- TPMT_SIGNATURE *signature, INT32 expiration, TPM2B_TIMEOUT **timeout,
- TPMT_TK_AUTH **policy_ticket, const char *policy_qualifier_data,
- bool is_nonce_tpm, const char *raw_data_path,
- const char *cphash_path) {
- bool result = true;
- /*
- * Qualifier data is optional. If not specified default to 0
- */
- TPM2B_NONCE policy_qualifier = TPM2B_EMPTY_INIT;
- if (policy_qualifier_data) {
- policy_qualifier.size = sizeof(policy_qualifier.buffer);
- result = tpm2_util_bin_from_hex_or_file(policy_qualifier_data,
- &policy_qualifier.size,
- policy_qualifier.buffer);
- if (!result) {
- return tool_rc_general_error;
- }
- }
- /*
- * CpHashA (digest of command parameters for approved command) optional.
- * If not specified default to NULL
- */
- TPM2B_DIGEST cphash = TPM2B_EMPTY_INIT;
- if (cphash_path) {
- bool result = files_load_digest(cphash_path, &cphash);
- if (!result) {
- return tool_rc_general_error;
- }
- }
- ESYS_TR policy_session_handle = tpm2_session_get_handle(policy_session);
- TPM2B_NONCE *nonce_tpm = NULL;
- tool_rc rc = tool_rc_success;
- if (is_nonce_tpm) {
- rc = tpm2_sess_get_noncetpm(ectx, policy_session_handle, &nonce_tpm);
- if (rc != tool_rc_success) {
- goto tpm2_policy_build_policysigned_out;
- }
- }
- /*
- * TPM-Rev-2.0-Part-3-Commands-01.38.pdf
- * aHash ≔ HauthAlg(nonceTPM || expiration || cpHashA || policyRef)
- */
- if (raw_data_path) {
- uint16_t raw_data_len = (nonce_tpm ? nonce_tpm->size : 0) +
- sizeof(INT32) + cphash.size + policy_qualifier.size;
- uint8_t *raw_data = malloc(raw_data_len);
- if (!raw_data) {
- LOG_ERR("oom");
- rc = tool_rc_general_error;
- goto tpm2_policy_build_policysigned_out;
- }
- /* nonceTPM */
- uint16_t offset = 0;
- if (nonce_tpm) {
- memcpy(raw_data, nonce_tpm->buffer, nonce_tpm->size);
- offset += nonce_tpm->size;
- }
- /* expiration */
- UINT32 endswap_data = tpm2_util_endian_swap_32(expiration);
- memcpy(raw_data + offset, (UINT8 *)&endswap_data, sizeof(INT32));
- offset += sizeof(INT32);
- /* cpHash */
- if (cphash_path) {
- memcpy(raw_data + offset, cphash.buffer, cphash.size);
- offset += cphash.size;
- }
- /* policyRef */
- memcpy(raw_data + offset, policy_qualifier.buffer,
- policy_qualifier.size);
- bool result = files_save_bytes_to_file(raw_data_path, raw_data,
- raw_data_len);
- free(raw_data);
- if (!result) {
- rc = tool_rc_general_error;
- }
- /*
- * We return since we only need to generate the raw signing data
- */
- goto tpm2_policy_build_policysigned_out;
- }
- rc = tpm2_policy_signed(ectx, auth_entity_obj, policy_session_handle,
- signature, expiration, timeout, policy_ticket, &policy_qualifier,
- nonce_tpm, &cphash);
- tpm2_policy_build_policysigned_out:
- Esys_Free(nonce_tpm);
- return rc;
- }
- tool_rc tpm2_policy_get_digest(ESYS_CONTEXT *ectx, tpm2_session *session,
- TPM2B_DIGEST **policy_digest) {
- ESYS_TR handle = tpm2_session_get_handle(session);
- return tpm2_policy_getdigest(ectx, handle, ESYS_TR_NONE, ESYS_TR_NONE,
- ESYS_TR_NONE, policy_digest);
- }
- tool_rc tpm2_policy_build_policycommandcode(ESYS_CONTEXT *ectx,
- tpm2_session *session, uint32_t command_code) {
- ESYS_TR handle = tpm2_session_get_handle(session);
- return tpm2_policy_command_code(ectx, handle, ESYS_TR_NONE, ESYS_TR_NONE,
- ESYS_TR_NONE, command_code);
- }
- tool_rc tpm2_policy_build_policynvwritten(ESYS_CONTEXT *ectx,
- tpm2_session *session, TPMI_YES_NO written_set) {
- ESYS_TR handle = tpm2_session_get_handle(session);
- return tpm2_policy_nv_written(ectx, handle, ESYS_TR_NONE, ESYS_TR_NONE,
- ESYS_TR_NONE, written_set);
- }
- tool_rc tpm2_policy_build_policylocality(ESYS_CONTEXT *ectx,
- tpm2_session *session, TPMA_LOCALITY locality) {
- ESYS_TR handle = tpm2_session_get_handle(session);
- return tpm2_policy_locality(ectx, handle, ESYS_TR_NONE, ESYS_TR_NONE,
- ESYS_TR_NONE, locality);
- }
- tool_rc tpm2_policy_build_policyduplicationselect(ESYS_CONTEXT *ectx,
- tpm2_session *session, const char *obj_name_path,
- const char *new_parent_name_path, TPMI_YES_NO is_include_obj) {
- TPM2B_NAME obj_name;
- bool result = true;
- if (obj_name_path) {
- obj_name.size = sizeof(obj_name.name);
- result = files_load_bytes_from_path(obj_name_path, obj_name.name,
- &obj_name.size);
- } else {
- obj_name.size = 0;
- }
- if (!result) {
- LOG_ERR("Failed to load duplicable object name.");
- return tool_rc_general_error;
- }
- TPM2B_NAME new_parent_name = { .size = sizeof(new_parent_name.name) };
- result = files_load_bytes_from_path(new_parent_name_path,
- new_parent_name.name, &new_parent_name.size);
- if (!result) {
- return tool_rc_general_error;
- }
- ESYS_TR handle = tpm2_session_get_handle(session);
- return tpm2_policy_duplication_select(ectx, handle, ESYS_TR_NONE,
- ESYS_TR_NONE, ESYS_TR_NONE, &obj_name, &new_parent_name,
- is_include_obj);
- }
- static bool tpm2_policy_populate_digest_list(char *buf,
- TPML_DIGEST *policy_list, TPMI_ALG_HASH hash) {
- uint8_t hash_len = tpm2_alg_util_get_hash_size(hash);
- if (!hash_len) {
- return false;
- }
- unsigned long file_size;
- bool retval = files_get_file_size_path(buf, &file_size);
- if (!retval) {
- return false;
- }
- if (file_size != hash_len) {
- return false;
- }
- policy_list->digests[policy_list->count].size = hash_len;
- /* All policy digests are expected to be of same hash len */
- if (policy_list->count > 0
- && policy_list->digests[policy_list->count].size
- != policy_list->digests[policy_list->count - 1].size) {
- return false;
- }
- uint16_t policy_digest_size = hash_len;
- retval = files_load_bytes_from_path(buf,
- policy_list->digests[policy_list->count].buffer,
- &policy_digest_size);
- if (!retval) {
- return false;
- }
- policy_list->count++;
- return true;
- }
- bool tpm2_policy_parse_policy_list(char *str, TPML_DIGEST *policy_list) {
- char *str1;
- char *str2;
- char *token;
- char *subtoken;
- char *saveptr1;
- char *saveptr2;
- const char *delimiter1 = ":";
- const char *delimiter2 = ",";
- unsigned int j;
- bool retval;
- TPMI_ALG_HASH hash = TPM2_ALG_ERROR;
- for (j = 1, str1 = str;; j++, str1 = NULL) {
- token = strtok_r(str1, delimiter1, &saveptr1);
- if (token == NULL) {
- break;
- }
- for (str2 = token;; str2 = NULL) {
- subtoken = strtok_r(str2, delimiter2, &saveptr2);
- if (subtoken == NULL) {
- break;
- }
- //Expecting one policy digest of same hash alg type for all policies
- if (j == 1) {
- hash = tpm2_alg_util_from_optarg(subtoken,
- tpm2_alg_util_flags_hash);
- if (hash == TPM2_ALG_ERROR) {
- LOG_ERR("Invalid/ Unspecified policy digest algorithm.");
- return false;
- }
- }
- //Multiple valid policy files
- if (j > 1) {
- retval = tpm2_policy_populate_digest_list(subtoken, policy_list,
- hash);
- if (!retval) {
- return false;
- }
- }
- }
- }
- return true;
- }
- tool_rc tpm2_policy_tool_finish(ESYS_CONTEXT *ectx, tpm2_session *session,
- const char *save_path) {
- TPM2B_DIGEST *policy_digest = NULL;
- tool_rc rc = tpm2_policy_get_digest(ectx, session, &policy_digest);
- if (rc != tool_rc_success) {
- LOG_ERR("Could not build tpm policy");
- return rc;
- }
- tpm2_util_hexdump(policy_digest->buffer, policy_digest->size);
- tpm2_tool_output("\n");
- rc = tool_rc_general_error;
- if (save_path) {
- bool result = files_save_bytes_to_file(save_path, policy_digest->buffer,
- policy_digest->size);
- if (!result) {
- LOG_ERR("Failed to save policy digest into file \"%s\"", save_path);
- goto error;
- }
- }
- rc = tool_rc_success;
- error:
- free(policy_digest);
- return rc;
- }
|