123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- /* SPDX-License-Identifier: BSD-3-Clause */
- #include <stdlib.h>
- #include "log.h"
- #include "object.h"
- #include "tpm2.h"
- #include "tpm2_tool.h"
- #include "tpm2_capability.h"
- #include "tpm2_options.h"
- struct tpm_flush_context_ctx {
- TPM2_HANDLE property;
- char *context_arg;
- unsigned encountered_option;
- };
- static struct tpm_flush_context_ctx ctx;
- static const char *get_property_name(TPM2_HANDLE handle) {
- switch (handle & TPM2_HR_RANGE_MASK) {
- case TPM2_HR_TRANSIENT:
- return "transient";
- case TPM2_HT_LOADED_SESSION << TPM2_HR_SHIFT:
- return "loaded session";
- case TPM2_HT_SAVED_SESSION << TPM2_HR_SHIFT:
- return "saved session";
- }
- return "invalid";
- }
- static tool_rc flush_contexts_tpm2(ESYS_CONTEXT *ectx, TPM2_HANDLE handles[],
- UINT32 count) {
- UINT32 i;
- for (i = 0; i < count; ++i) {
- ESYS_TR handle;
- tool_rc rc = tpm2_util_sys_handle_to_esys_handle(ectx, handles[i],
- &handle);
- if (rc != tool_rc_success) {
- return rc;
- }
- rc = tpm2_flush_context(ectx, handle);
- if (rc != tool_rc_success) {
- LOG_ERR("Failed Flush Context for %s handle 0x%x",
- get_property_name(handles[i]), handles[i]);
- return rc;
- }
- }
- return tool_rc_success;
- }
- static bool flush_contexts_tr(ESYS_CONTEXT *ectx, ESYS_TR handles[],
- UINT32 count) {
- UINT32 i;
- for (i = 0; i < count; ++i) {
- tool_rc rc = tpm2_flush_context(ectx, handles[i]);
- if (rc != tool_rc_success) {
- return rc;
- }
- }
- return tool_rc_success;
- }
- static bool on_option(char key, char *value) {
- UNUSED(value);
- if (ctx.encountered_option) {
- LOG_ERR("Options -t, -l and -s are mutually exclusive");
- return false;
- }
- ctx.encountered_option = true;
- switch (key) {
- case 't':
- ctx.property = TPM2_TRANSIENT_FIRST;
- break;
- case 'l':
- ctx.property = TPM2_LOADED_SESSION_FIRST;
- break;
- case 's':
- ctx.property = TPM2_ACTIVE_SESSION_FIRST;
- break;
- }
- return true;
- }
- static bool on_arg(int argc, char *argv[]) {
- if (ctx.encountered_option && argc != 0) {
- LOG_ERR("Options are mutually exclusive of an argument");
- return false;
- }
- ctx.context_arg = argv[0];
- return true;
- }
- static bool tpm2_tool_onstart(tpm2_options **opts) {
- static const struct option topts[] = {
- { "transient-object", no_argument, NULL, 't' },
- { "loaded-session", no_argument, NULL, 'l' },
- { "saved-session", no_argument, NULL, 's' },
- };
- *opts = tpm2_options_new("tls", ARRAY_LEN(topts), topts, on_option, on_arg,
- 0);
- return *opts != NULL;
- }
- static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) {
- UNUSED(flags);
- if (ctx.property) {
- TPMS_CAPABILITY_DATA *capability_data;
- tool_rc rc = tpm2_capability_get(ectx, TPM2_CAP_HANDLES, ctx.property,
- TPM2_MAX_CAP_HANDLES, &capability_data);
- if (rc != tool_rc_success) {
- return rc;
- }
- TPML_HANDLE *handles = &capability_data->data.handles;
- rc = flush_contexts_tpm2(ectx, handles->handle, handles->count);
- free(capability_data);
- return rc;
- }
- if (!ctx.context_arg) {
- LOG_ERR("Specify options to evict handles or a session context.");
- return tool_rc_option_error;
- }
- TPM2_HANDLE handle;
- bool result = tpm2_util_string_to_uint32(ctx.context_arg, &handle);
- if (!result) {
- /* hmm not a handle, try a session */
- tpm2_session *s = NULL;
- tool_rc rc = tpm2_session_restore(ectx, ctx.context_arg, true, &s);
- if (rc != tool_rc_success) {
- return rc;
- }
- tpm2_session_close(&s);
- return tool_rc_success;
- }
- /* its a handle, call flush */
- ESYS_TR tr_handle = ESYS_TR_NONE;
- tool_rc rc = tpm2_util_sys_handle_to_esys_handle(ectx, handle, &tr_handle);
- if (rc != tool_rc_success) {
- return rc;
- }
- return flush_contexts_tr(ectx, &tr_handle, 1);
- }
- // Register this tool with tpm2_tool.c
- TPM2_TOOL_REGISTER("flushcontext", tpm2_tool_onstart, tpm2_tool_onrun, NULL, NULL)
|