Skip to content

Commit

Permalink
Save Context: Add the possibility for autoflush.
Browse files Browse the repository at this point in the history
If the environment variable TPM2TOOLS_AUTOFLUSH exists transient
objects will be removed after they were saved and stored to disk.
Also a transient parent will be removed if a context file for
this parent was used by this command.
For the commands which will check the autoflush also an option
-R is added to enable the autoflush independent from the environment
variable.
-R was added to several commands in one integration test.
Addresses: tpm2-software#1511

Signed-off-by: Juergen Repp <juergen_repp@web.de>
  • Loading branch information
JuergenReppSIT authored and AndreasFuchsTPM committed Jan 24, 2024
1 parent 98ca6ba commit 30ae31a
Show file tree
Hide file tree
Showing 21 changed files with 192 additions and 39 deletions.
8 changes: 4 additions & 4 deletions lib/files.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,11 +273,11 @@ bool files_save_context(TPMS_CONTEXT *context, FILE *stream) {
}

tool_rc files_save_tpm_context_to_file(ESYS_CONTEXT *ectx, ESYS_TR handle,
FILE *stream) {
FILE *stream, bool autoflush) {

TPMS_CONTEXT *context = NULL;

tool_rc rc = tpm2_context_save(ectx, handle, &context);
tool_rc rc = tpm2_context_save(ectx, handle, autoflush, &context);
if (rc != tool_rc_success) {
return rc;
}
Expand All @@ -288,7 +288,7 @@ tool_rc files_save_tpm_context_to_file(ESYS_CONTEXT *ectx, ESYS_TR handle,
}

tool_rc files_save_tpm_context_to_path(ESYS_CONTEXT *context, ESYS_TR handle,
const char *path) {
const char *path, bool autoflush) {

FILE *f = fopen(path, "w+b");
if (!f) {
Expand All @@ -297,7 +297,7 @@ tool_rc files_save_tpm_context_to_path(ESYS_CONTEXT *context, ESYS_TR handle,
return tool_rc_general_error;
}

tool_rc rc = files_save_tpm_context_to_file(context, handle, f);
tool_rc rc = files_save_tpm_context_to_file(context, handle, f, autoflush);
fclose(f);
return rc;
}
Expand Down
8 changes: 6 additions & 2 deletions lib/files.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,14 @@ bool files_save_bytes_to_file(const char *path, UINT8 *buf, UINT16 size);
* The object handle for the object to save.
* @param path
* The output path of the file.
* @param autoflush
* Flush the tpm object after context save.
*
* @return
* tool_rc indicating status.
*/
tool_rc files_save_tpm_context_to_path(ESYS_CONTEXT *context, ESYS_TR handle,
const char *path);
const char *pathm, bool autoflush);

/**
* Like files_save_tpm_context_to_path() but saves a tpm session to a FILE stream.
Expand All @@ -99,11 +101,13 @@ tool_rc files_save_tpm_context_to_path(ESYS_CONTEXT *context, ESYS_TR handle,
* The object handle for the object to save.
* @param stream
* The FILE stream to save too.
* @param autoflush
* Flush the tpm object after context save.
* @return
* tool_rc indicating status.
*/
tool_rc files_save_tpm_context_to_file(ESYS_CONTEXT *context, ESYS_TR handle,
FILE *stream);
FILE *stream, bool autoflush);

/**
* Loads a ESAPI TPM object context from disk or an ESAPI serialized ESYS_TR object.
Expand Down
18 changes: 17 additions & 1 deletion lib/tpm2.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,14 +313,30 @@ tool_rc tpm2_nv_read(ESYS_CONTEXT *esys_context,
}

tool_rc tpm2_context_save(ESYS_CONTEXT *esys_context, ESYS_TR save_handle,
TPMS_CONTEXT **context) {
bool autoflush, TPMS_CONTEXT **context) {

TSS2_RC rval = Esys_ContextSave(esys_context, save_handle, context);
TPM2_HANDLE tpm_handle;
if (rval != TSS2_RC_SUCCESS) {
LOG_PERR(Esys_ContextSave, rval);
return tool_rc_from_tpm(rval);
}

if (autoflush || tpm2_util_env_yes(TPM2TOOLS_ENV_AUTOFLUSH)) {
rval = Esys_TR_GetTpmHandle(esys_context, save_handle, &tpm_handle);
if (rval != TSS2_RC_SUCCESS) {
LOG_PERR(Esys_TR_GetTpmHandle, rval);
return tool_rc_from_tpm(rval);
}
if ((tpm_handle & TPM2_HR_RANGE_MASK) == TPM2_HR_TRANSIENT) {
TSS2_RC rval = Esys_FlushContext(esys_context, save_handle);
if (rval != TPM2_RC_SUCCESS) {
LOG_PERR(Eys_ContextFlush, rval);
return false;
}
}
}

return tool_rc_success;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/tpm2.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ tool_rc tpm2_nv_read(ESYS_CONTEXT *esys_context,
TPMI_ALG_HASH parameter_hash_algorithm, ESYS_TR shandle2, ESYS_TR shandle3);

tool_rc tpm2_context_save(ESYS_CONTEXT *esys_context, ESYS_TR save_handle,
TPMS_CONTEXT **context);
bool autoflush, TPMS_CONTEXT **context);

tool_rc tpm2_context_load(ESYS_CONTEXT *esys_context,
const TPMS_CONTEXT *context, ESYS_TR *loaded_handle);
Expand Down
2 changes: 1 addition & 1 deletion lib/tpm2_options.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
#include <stdio.h>

#include <getopt.h>

#include <tss2/tss2_sys.h>

#define TPM2TOOLS_ENV_TCTI "TPM2TOOLS_TCTI"
#define TPM2TOOLS_ENV_AUTOFLUSH "TPM2TOOLS_AUTOFLUSH"

#define TPM2TOOLS_ENV_ENABLE_ERRATA "TPM2TOOLS_ENABLE_ERRATA"

Expand Down
2 changes: 1 addition & 1 deletion lib/tpm2_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ tool_rc tpm2_session_close(tpm2_session **s) {
ESYS_TR handle = tpm2_session_get_handle(session);
LOG_INFO("Saved session: ESYS_TR(0x%x)", handle);
rc = files_save_tpm_context_to_file(session->internal.ectx, handle,
session_file);
session_file, false);
if (rc != tool_rc_success) {
LOG_ERR("Could not write session context");
/* done, free session resources and use rc to indicate status */
Expand Down
8 changes: 8 additions & 0 deletions lib/tpm2_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,14 @@ char *tpm2_util_getenv(const char *name) {
return getenv(name);
}

bool tpm2_util_env_yes(const char *name) {

char *value = getenv(name);
return (value && (strcasecmp(name, "yes") == 0 ||
strcasecmp(name, "1") == 0 ||
strcasecmp(name, "true") == 0));
}

/**
* Parses a hierarchy value from an option argument.
* @param value
Expand Down
2 changes: 2 additions & 0 deletions lib/tpm2_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,8 @@ ESYS_TR tpm2_tpmi_hierarchy_to_esys_tr(TPMI_RH_PROVISION inh);

char *tpm2_util_getenv(const char *name);

bool tpm2_util_env_yes(const char *name);

typedef enum tpm2_handle_flags tpm2_handle_flags;
enum tpm2_handle_flags {
TPM2_HANDLE_FLAGS_NONE = 0,
Expand Down
5 changes: 5 additions & 0 deletions man/common/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@ information that many users may expect.
Enable the application of errata fixups. Useful if an errata fixup needs to be
applied to commands sent to the TPM. Defining the environment
TPM2TOOLS\_ENABLE\_ERRATA is equivalent.
* **-R**, **\--autoflush**:
Enable autoflush for transient objects created by the command. If a parent
object is loaded from a context file also the transient parent object will
be flushed. Autoflush can also be activated if the environment variable
TPM2TOOLS\_AUTOFLUSH is is set to yes or true.
6 changes: 3 additions & 3 deletions test/integration/tests/load.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ tpm2 clear

#####file test

tpm2 createprimary -Q -C e -g $alg_primary_obj -G $alg_primary_key \
tpm2 createprimary -R -Q -C e -g $alg_primary_obj -G $alg_primary_key \
-c $file_primary_key_ctx

tpm2 create -Q -g $alg_create_obj -G $alg_create_key -u $file_load_key_pub \
tpm2 create -R -Q -g $alg_create_obj -G $alg_create_key -u $file_load_key_pub \
-r $file_load_key_priv -C $file_primary_key_ctx

tpm2 load -Q -C $file_primary_key_ctx -u $file_load_key_pub \
tpm2 load -R -Q -C $file_primary_key_ctx -u $file_load_key_pub \
-r $file_load_key_priv -n $file_load_key_name -c $file_load_key_ctx

#####handle test
Expand Down
3 changes: 2 additions & 1 deletion test/unit/test_tpm2_session.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ static void test_tpm2_create_dummy_context(TPMS_CONTEXT *context) {
memset(context->contextBlob.buffer, '\0', context->contextBlob.size);
}

tool_rc __wrap_tpm2_context_save(ESYS_CONTEXT *esysContext, ESYS_TR saveHandle,
tool_rc __wrap_tpm2_context_save(ESYS_CONTEXT *esysContext, ESYS_TR saveHandle, bool autoflush,
TPMS_CONTEXT **context) {

UNUSED(esysContext);
UNUSED(autoflush);

// context should be non-null or bool files_save_tpm_context_to_file()
// segfaults
Expand Down
2 changes: 1 addition & 1 deletion tools/fapi/tss2_gettpm2object.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ static int tss2_tool_onrun (FAPI_CONTEXT *fctx) {
LOG_PERR("Esys_ContextLoad", e_rc);
goto error;
}
t_rc = files_save_tpm_context_to_file(esys_ctx, esys_handle, stream);
t_rc = files_save_tpm_context_to_file(esys_ctx, esys_handle, stream, false);
if (t_rc != tool_rc_success) {
goto error;
}
Expand Down
22 changes: 18 additions & 4 deletions tools/misc/tpm2_encodeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,12 @@ struct tpm_encodeobject_ctx {
} object;

char *output_path;
bool autoflush;
};

static tpm_encodeobject_ctx ctx;
static tpm_encodeobject_ctx ctx = {
.autoflush = false,
};

static bool on_option(char key, char *value) {
switch (key) {
Expand Down Expand Up @@ -76,9 +79,10 @@ static bool tpm2_tool_onstart(tpm2_options **opts) {
{ "parent-context", required_argument, NULL, 'C' },
{ "output", required_argument, NULL, 'o' },
{ "key-auth", no_argument, NULL, 'p' },
{ "autoflush", no_argument, NULL, 'R' },
};

*opts = tpm2_options_new("P:u:r:C:o:p", ARRAY_LEN(topts), topts, on_option,
*opts = tpm2_options_new("P:u:r:C:o:pR", ARRAY_LEN(topts), topts, on_option,
NULL, 0);

return *opts != NULL;
Expand Down Expand Up @@ -125,7 +129,7 @@ static tool_rc init(ESYS_CONTEXT *ectx) {
TPM2_HANDLE_ALL_W_NV);
}

static int encode(void) {
static int encode(ESYS_CONTEXT *ectx) {

uint8_t private_buf[sizeof(ctx.object.private)];
size_t private_len = 0;
Expand Down Expand Up @@ -186,6 +190,16 @@ static int encode(void) {
}

PEM_write_bio_TSSPRIVKEY_OBJ(bio, tpk);

if ((ctx.autoflush || tpm2_util_env_yes(TPM2TOOLS_ENV_AUTOFLUSH)) &&
ctx.parent.object.path &&
(ctx.parent.object.handle & TPM2_HR_RANGE_MASK) == TPM2_HR_TRANSIENT) {
rval = Esys_FlushContext(ectx, ctx.parent.object.tr_handle);
if (rval != TPM2_RC_SUCCESS) {
return tool_rc_general_error;
}
}

rc = tool_rc_success;

error:
Expand All @@ -210,7 +224,7 @@ static tool_rc tpm2_tool_onrun(ESYS_CONTEXT *ectx, tpm2_option_flags flags) {
return rc;
}

return encode();
return encode(ectx);
}

// Register this tool with tpm2_tool.c
Expand Down
26 changes: 24 additions & 2 deletions tools/tpm2_changeauth.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ struct changeauth_ctx {
tpm2_loaded_object obj;
} parent;

bool autoflush;

struct {
const char *auth_current;
const char *auth_new;
Expand Down Expand Up @@ -59,6 +61,7 @@ static changeauth_ctx ctx = {
.parameter_hash_algorithm = TPM2_ALG_ERROR,
.aux_session_handle[0] = ESYS_TR_NONE,
.aux_session_handle[1] = ESYS_TR_NONE,
.autoflush = false,
};

static tool_rc hierarchy_change_auth(ESYS_CONTEXT *ectx) {
Expand All @@ -77,15 +80,29 @@ static tool_rc nv_change_auth(ESYS_CONTEXT *ectx) {

static tool_rc object_change_auth(ESYS_CONTEXT *ectx) {

TSS2_RC rval;

if (!ctx.object.out_path) {
LOG_ERR("Require private output file path option -r");
return tool_rc_general_error;
}

return tpm2_object_change_auth(ectx, &ctx.parent.obj, &ctx.object.obj,
tool_rc rc = tpm2_object_change_auth(ectx, &ctx.parent.obj, &ctx.object.obj,
ctx.new_auth, &ctx.out_private, &ctx.cp_hash, &ctx.rp_hash,
ctx.parameter_hash_algorithm, ctx.aux_session_handle[0],
ctx.aux_session_handle[1]);
if (rc != tool_rc_success) {
return rc;
}
if ((ctx.autoflush || tpm2_util_env_yes(TPM2TOOLS_ENV_AUTOFLUSH)) &&
ctx.parent.obj.path &&
(ctx.parent.obj.handle & TPM2_HR_RANGE_MASK) == TPM2_HR_TRANSIENT) {
rval = Esys_FlushContext(ectx, ctx.parent.obj.tr_handle);
if (rval != TPM2_RC_SUCCESS) {
return tool_rc_general_error;
}
}
return tool_rc_success;
}

static tool_rc change_authorization(ESYS_CONTEXT *ectx) {
Expand Down Expand Up @@ -317,6 +334,10 @@ static bool on_option(char key, char *value) {
return false;
}
break;
case 'R':
ctx.autoflush = true;
break;

/*no default */
}

Expand All @@ -333,8 +354,9 @@ static bool tpm2_tool_onstart(tpm2_options **opts) {
{ "cphash", required_argument, NULL, 0 },
{ "rphash", required_argument, NULL, 1 },
{ "session", required_argument, NULL, 'S' },
{ "autoflush", no_argument, NULL, 'R' },
};
*opts = tpm2_options_new("p:c:C:r:S:", ARRAY_LEN(topts), topts,
*opts = tpm2_options_new("p:c:C:r:S:R", ARRAY_LEN(topts), topts,
on_option, on_arg, 0);

return *opts != NULL;
Expand Down
Loading

0 comments on commit 30ae31a

Please sign in to comment.