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 indexpendent from the environment
variable.
Addresses: #1511

Signed-off-by: Juergen Repp <[email protected]>
  • Loading branch information
JuergenReppSIT committed Oct 22, 2023
1 parent e7526e1 commit 0a8cb8c
Show file tree
Hide file tree
Showing 18 changed files with 203 additions and 36 deletions.
20 changes: 16 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 Expand Up @@ -887,3 +887,15 @@ tool_rc files_load_unique_data(const char *file_path, TPM2B_PUBLIC *public_data)

return tool_rc_success;
}


bool file_exists(const char *fname)
{
FILE *file;
if ((file = fopen(fname, "r")))
{
fclose(file);
return true;
}
return false;
}
20 changes: 18 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 Expand Up @@ -628,4 +632,16 @@ bool files_load_attest_file(FILE *f, const char *path, TPMS_ATTEST *attest);
tool_rc files_load_unique_data(const char *file_path,
TPM2B_PUBLIC *public_data);

/**
* @brief
* Check whether file can be read
*
* @param fname
* The file filename of the file to be read.
* @return
* bool signaling whether file can be read.
*
*/
bool file_exists(const char *fname);

#endif /* FILES_H */
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_getenv(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 @@ -398,7 +398,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
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.
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_getenv(TPM2TOOLS_ENV_AUTOFLUSH)) &&
file_exists(ctx.parent.ctx_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_getenv(TPM2TOOLS_ENV_AUTOFLUSH)) &&
file_exists(ctx.parent.ctx) &&
(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
23 changes: 19 additions & 4 deletions tools/tpm2_create.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ struct tpm_create_ctx {
} object;

bool is_createloaded;

bool autoflush;
/*
* Parameter hashes
*/
Expand Down Expand Up @@ -103,6 +103,7 @@ static tpm_create_ctx ctx = {
.is_command_dispatch = true,
.parameter_hash_algorithm = TPM2_ALG_ERROR,
.format = pubkey_format_tss,
.autoflush = false,
};

static bool load_outside_info(TPM2B_DATA *outside_info) {
Expand All @@ -125,6 +126,8 @@ static void print_help_message() {

static tool_rc create(ESYS_CONTEXT *ectx) {

TSS2_RC rval;

/*
* 1. TPM2_CC_<command> OR Retrieve cpHash
*/
Expand Down Expand Up @@ -179,6 +182,14 @@ static tool_rc create(ESYS_CONTEXT *ectx) {
}
}

if ((ctx.autoflush || tpm2_util_getenv(TPM2TOOLS_ENV_AUTOFLUSH)) &&
file_exists(ctx.parent.ctx_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;
}
}
return tool_rc_success;
}

Expand Down Expand Up @@ -311,14 +322,14 @@ static tool_rc process_output(ESYS_CONTEXT *ectx) {

if (ctx.object.ctx_path) {
rc = files_save_tpm_context_to_path(ectx, ctx.object.object_handle,
ctx.object.ctx_path);
ctx.object.ctx_path, ctx.autoflush);

if (rc != tool_rc_success) {
goto out;
}
}

if (ctx.rp_hash_path) {
if (ctx.rp_hash_path) {
is_file_op_success = files_save_digest(&ctx.rp_hash, ctx.rp_hash_path);

if (!is_file_op_success) {
Expand Down Expand Up @@ -559,6 +570,9 @@ static bool on_option(char key, char *value) {
case 'o':
ctx.output_path = value;
break;
case 'R':
ctx.autoflush = true;
break;
/* no default */
};

Expand Down Expand Up @@ -590,9 +604,10 @@ static bool tpm2_tool_onstart(tpm2_options **opts) {
{ "session", required_argument, NULL, 'S' },
{ "format", required_argument, NULL, 'f' },
{ "output", required_argument, NULL, 'o' },
{ "autoflush", no_argument, NULL, 'R' },
};

*opts = tpm2_options_new("P:p:g:G:a:i:L:u:r:C:c:t:d:q:l:S:o:f:",
*opts = tpm2_options_new("P:p:g:G:a:i:L:u:r:C:c:t:d:q:l:S:o:f:R",
ARRAY_LEN(topts), topts, on_option, NULL, 0);

return *opts != NULL;
Expand Down
Loading

0 comments on commit 0a8cb8c

Please sign in to comment.