277 changes: 0 additions & 277 deletions lib/context-util.c

This file was deleted.

47 changes: 0 additions & 47 deletions lib/context-util.h

This file was deleted.

421 changes: 0 additions & 421 deletions lib/options.c

This file was deleted.

163 changes: 0 additions & 163 deletions lib/options.h

This file was deleted.

66 changes: 66 additions & 0 deletions lib/tcti/tpm2_tools_tcti_abrmd.c
@@ -0,0 +1,66 @@
//**********************************************************************;
// Copyright (c) 2015, Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
//**********************************************************************;
#include <inttypes.h>
#include <stdlib.h>
#include <tcti/tcti-tabrmd.h>

#include <sapi/tpm20.h>

#include "log.h"
#include "tpm2_tools_tcti_abrmd.h"
#include "tpm2_util.h"

TSS2_TCTI_CONTEXT *tpm2_tools_tcti_abrmd_init(char *opts) {

UNUSED(opts);

size_t size;
TSS2_RC rc = tss2_tcti_tabrmd_init(NULL, &size);
if (rc != TSS2_RC_SUCCESS) {
LOG_ERR("Failed to get size for TABRMD TCTI context: 0x%" PRIx32, rc);
return NULL;
}

TSS2_TCTI_CONTEXT *tcti_ctx = (TSS2_TCTI_CONTEXT*) calloc(1, size);
if (tcti_ctx == NULL) {
LOG_ERR("Allocation for TABRMD TCTI context failed: oom");
return NULL;
}

rc = tss2_tcti_tabrmd_init(tcti_ctx, &size);
if (rc != TSS2_RC_SUCCESS) {
LOG_ERR ("Failed to initialize TABRMD TCTI context: 0x%" PRIx32, rc);
free(tcti_ctx);
return NULL;
}

return tcti_ctx;
}
48 changes: 48 additions & 0 deletions lib/tcti/tpm2_tools_tcti_abrmd.h
@@ -0,0 +1,48 @@
//**********************************************************************;
// Copyright (c) 2015, Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
//**********************************************************************;
#ifndef LIB_TCTI_TPM2_TOOLS_TCTI_ABRMD_H_
#define LIB_TCTI_TPM2_TOOLS_TCTI_ABRMD_H_

#include <sapi/tpm20.h>

/**
* Initializes a abrmd TCTI from an option string.
@note
* abrmd currently accepts no options.
*
* @param opts
* The option string, ignored.
* @return
* NULL on error or an initialized abrmd TCTI.
*/
TSS2_TCTI_CONTEXT *tpm2_tools_tcti_abrmd_init(char *opts);

#endif /* LIB_TCTI_TPM2_TOOLS_TCTI_ABRMD_H_ */
83 changes: 83 additions & 0 deletions lib/tcti/tpm2_tools_tcti_device.c
@@ -0,0 +1,83 @@
//**********************************************************************;
// Copyright (c) 2015, Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
//**********************************************************************;
#include <inttypes.h>
#include <stdlib.h>

#include <sapi/tpm20.h>
#include <tcti/tcti_device.h>

#include "log.h"
#include "tpm2_tools_tcti_device.h"
#include "tpm2_util.h"

#define TPM2TOOLS_ENV_DEVICE_FILE "TPM2TOOLS_DEVICE_FILE"
#define TCTI_DEVICE_DEFAULT_PATH "/dev/tpm0"

TSS2_TCTI_CONTEXT *tpm2_tools_tcti_device_init(char *opts) {

TCTI_DEVICE_CONF conf = {
.device_path = TCTI_DEVICE_DEFAULT_PATH,
.logCallback = NULL,
.logData = NULL,
};

char *env_path = getenv(TPM2TOOLS_ENV_DEVICE_FILE);
if (env_path) {
conf.device_path = env_path;
}

if (opts) {
conf.device_path = opts;
}

size_t size;
TSS2_RC rc;
TSS2_TCTI_CONTEXT *tcti_ctx;

rc = InitDeviceTcti(NULL, &size, 0);
if (rc != TSS2_RC_SUCCESS) {
LOG_ERR("Failed to get allocation size for device tcti context: "
"0x%x", rc);
return NULL;
}
tcti_ctx = (TSS2_TCTI_CONTEXT*) calloc(1, size);
if (tcti_ctx == NULL) {
LOG_ERR("Allocation for device TCTI context failed: oom");
return NULL;
}
rc = InitDeviceTcti(tcti_ctx, &size, &conf);
if (rc != TSS2_RC_SUCCESS) {
LOG_ERR("Failed to initialize device TCTI context: 0x%x", rc);
free(tcti_ctx);
return NULL;
}
return tcti_ctx;
}
47 changes: 47 additions & 0 deletions lib/tcti/tpm2_tools_tcti_device.h
@@ -0,0 +1,47 @@
//**********************************************************************;
// Copyright (c) 2017, Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
//**********************************************************************;
#ifndef LIB_TCTI_TPM2_TOOLS_TCTI_DEVICE_H_
#define LIB_TCTI_TPM2_TOOLS_TCTI_DEVICE_H_

#include <sapi/tpm20.h>

/**
* Initializes a device tcti from opts. opts can be a filepath
* to a tpm device file or NULL. On NULL, it uses the environment
* value or, if not set, the default path.
* @param opts
* The option string, which can be a file path or NULL.
* @return
* NULL on error or an initialized device tcti.
*/
TSS2_TCTI_CONTEXT *tpm2_tools_tcti_device_init(char *opts);

#endif /* LIB_TCTI_TPM2_TOOLS_TCTI_DEVICE_H_ */
111 changes: 111 additions & 0 deletions lib/tcti/tpm2_tools_tcti_socket.c
@@ -0,0 +1,111 @@
//**********************************************************************;
// Copyright (c) 2015, Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
//**********************************************************************;
#include <inttypes.h>
#include <stdlib.h>

#include <tcti/tcti_socket.h>
#include <sapi/tpm20.h>

#include "log.h"
#include "tpm2_tools_tcti_socket.h"
#include "tpm2_util.h"

#define TCTI_SOCKET_DEFAULT_ADDRESS "127.0.0.1"
#define TCTI_SOCKET_DEFAULT_PORT 2321

#define TPM2TOOLS_ENV_SOCKET_ADDRESS "TPM2TOOLS_SOCKET_ADDRESS"
#define TPM2TOOLS_ENV_SOCKET_PORT "TPM2TOOLS_SOCKET_PORT"

TSS2_TCTI_CONTEXT*
tpm2_tools_tcti_socket_init (char *opts)
{
TCTI_SOCKET_CONF conf = {
.hostname = TCTI_SOCKET_DEFAULT_ADDRESS,
.port = TCTI_SOCKET_DEFAULT_PORT,
.logCallback = NULL,
.logBufferCallback = NULL,
.logData = NULL,
};

char *addr_env = getenv(TPM2TOOLS_ENV_SOCKET_ADDRESS);
if (addr_env) {
conf.hostname = addr_env;
}

char *port_env = getenv(TPM2TOOLS_ENV_SOCKET_PORT);
if (port_env) {
bool res = tpm2_util_string_to_uint16(port_env, &conf.port);
if (!res) {
LOG_ERR("Error getting env var\""TPM2TOOLS_ENV_SOCKET_PORT"\","
"got: \"%s\", expected a number!", port_env);
return NULL;
}
}

/* opts should be something like: "hostname:port" */
if (opts) {
char *port_sep = strrchr(opts, ':');
if (port_sep) {
port_sep[0] = '\0';
port_sep++;
bool res = tpm2_util_string_to_uint16(port_sep, &conf.port);
if (!res) {
LOG_ERR("Error getting env var\""TPM2TOOLS_ENV_SOCKET_PORT"\","
"got: \"%s\", expected a number!", port_sep);
return NULL;
}
}
conf.hostname = opts;
}

size_t size;
TSS2_RC rc;
TSS2_TCTI_CONTEXT *tcti_ctx;

rc = InitSocketTcti (NULL, &size, &conf, 0);
if (rc != TSS2_RC_SUCCESS) {
LOG_ERR("Faled to get allocation size for tcti context: "
"0x%x", rc);
return NULL;
}
tcti_ctx = (TSS2_TCTI_CONTEXT*)calloc (1, size);
if (tcti_ctx == NULL) {
LOG_ERR("Allocation for tcti context failed: oom");
return NULL;
}
rc = InitSocketTcti (tcti_ctx, &size, &conf, 0);
if (rc != TSS2_RC_SUCCESS) {
LOG_ERR("Failed to initialize tcti context: 0x%x\n", rc);
free (tcti_ctx);
return NULL;
}
return tcti_ctx;
}
47 changes: 47 additions & 0 deletions lib/tcti/tpm2_tools_tcti_socket.h
@@ -0,0 +1,47 @@
//**********************************************************************;
// Copyright (c) 2017, Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software without
// specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
// THE POSSIBILITY OF SUCH DAMAGE.
//**********************************************************************;
#ifndef LIB_TCTI_TPM2_TOOLS_TCTI_SOCKET_H_
#define LIB_TCTI_TPM2_TOOLS_TCTI_SOCKET_H_

#include <sapi/tpm20.h>

/**
* Initializes a socket tcti from opts. opts can be either NULL or a
* <hostname>:<port> string.
*
* @param opts
* The option string, which can be a <hostname>:<port> specifier or NULL.
* @return
* NULL on error or an initialized socket tcti.
*/
TSS2_TCTI_CONTEXT *tpm2_tools_tcti_socket_init(char *opts);

#endif /* LIB_TCTI_TPM2_TOOLS_TCTI_SOCKET_H_ */
372 changes: 372 additions & 0 deletions lib/tpm2_options.c
@@ -0,0 +1,372 @@
/*
* Copyright (c) 2016, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>

#include <getopt.h>
#include <unistd.h>

#include "log.h"
#include "tpm2_options.h"
#include "tpm2_util.h"

#ifdef HAVE_TCTI_DEV
#include "tpm2_tools_tcti_device.h"
#endif
#ifdef HAVE_TCTI_SOCK
#include "tpm2_tools_tcti_socket.h"
#endif
#ifdef HAVE_TCTI_TABRMD
#include "tpm2_tools_tcti_abrmd.h"
#endif

/*
* Default TCTI: this is a bit awkward since we allow users to enable /
* disable TCTIs using ./configure --with/--without magic.
* As simply put as possible:
* if the tabrmd TCTI is enabled, it's the default.
* else if the socket TCTI is enabled it's the default.
* else if the device TCTI is enabled it's the default.
* We do this to preserve the current default / expected behavior (use of
* the socket TCTI).
*/
#ifdef HAVE_TCTI_TABRMD
#define TCTI_DEFAULT_STR "abrmd"
#elif HAVE_TCTI_SOCK
#define TCTI_DEFAULT_STR "socket"
#elif HAVE_TCTI_DEV
#define TCTI_DEFAULT_STR "device"
#endif

#ifndef VERSION
#warning "VERSION Not known at compile time, not embedding..."
#define VERSION "UNKNOWN"
#endif

#define TPM2TOOLS_ENV_TCTI_NAME "TPM2TOOLS_TCTI_NAME"

struct tpm2_options {
struct {
tpm2_option_handler on_opt;
tpm2_arg_handler on_arg;
} callbacks;
char *short_opts;
size_t len;
struct option long_opts[];
};

tpm2_options *tpm2_options_new(const char *short_opts, size_t len,
const struct option *long_opts, tpm2_option_handler on_opt,
tpm2_arg_handler on_arg) {

tpm2_options *opts = calloc(1, sizeof(*opts) + (sizeof(*long_opts) * len));
if (!opts) {
LOG_ERR("oom");
return NULL;
}

/*
* On NULL, just make it a zero length string so we don't have to keep
* checking it for NULL.
*/
if (!short_opts) {
short_opts = "";
}

opts->short_opts = strdup(short_opts);
if (!opts->short_opts) {
LOG_ERR("oom");
free(opts);
return NULL;
}

opts->callbacks.on_opt = on_opt;
opts->callbacks.on_arg = on_arg;
opts->len = len;
memcpy(opts->long_opts, long_opts, len * sizeof(*long_opts));

return opts;
}

bool tpm2_options_cat(tpm2_options **dest, tpm2_options *src) {

tpm2_options *d = *dest;

/* move the nested char * pointer first */
size_t opts_len = strlen(d->short_opts) + strlen(src->short_opts) + 1;
char *tmp_short = realloc(d->short_opts, opts_len);
if (!tmp_short) {
LOG_ERR("oom");
return false;
}

strcat(tmp_short, src->short_opts);

d->short_opts = tmp_short;

/* now move the eclosing structure */
size_t long_opts_len = d->len + src->len;
/* +1 for a terminating NULL at the end of options array for getopt_long */
tpm2_options *tmp = realloc(d, sizeof(*d) + ((long_opts_len + 1) * sizeof(d->long_opts[0])));
if (!tmp) {
LOG_ERR("oom");
return false;
}

*dest = d = tmp;

d->callbacks.on_arg = src->callbacks.on_arg;
d->callbacks.on_opt = src->callbacks.on_opt;

memcpy(&d->long_opts[d->len], src->long_opts, src->len * sizeof(src->long_opts[0]));

/* length must be updated post memcpy as we need d->len to be the original offest */
d->len = long_opts_len;

/* NULL term for getopt_long */
memset(&d->long_opts[d->len], 0, sizeof(d->long_opts[0]));

return true;
}

void tpm2_options_free(tpm2_options *opts) {
free(opts->short_opts);
free(opts);
}

#define ADD_TCTI(xname, xinit) { .name = xname, .init = xinit }

/*
* map a string "nice" name of a tcti to a tcti initialization
* routine.
*/
struct {
char *name;
tcti_init init;
} tcti_map_table[] = {
#ifdef HAVE_TCTI_DEV
ADD_TCTI("device", tpm2_tools_tcti_device_init),
#endif
#ifdef HAVE_TCTI_SOCK
ADD_TCTI("socket", tpm2_tools_tcti_socket_init),
#endif
#ifdef HAVE_TCTI_TABRMD
ADD_TCTI("abrmd", tpm2_tools_tcti_abrmd_init)
#endif
};

static char *tcti_get_opts(char *optstr) {

char *split = strchr(optstr, ':');
if (!split) {
return NULL;
}

split[0] = '\0';

/*
* make it so downstream consumers don't need to deal with the empty
* string, ie "". They can just check NULL.
*/
if (!split[1]) {
return NULL;
}

return &split[1];
}

static void execute_man (char *prog_name, char *envp[]) {

char *manpage = basename(prog_name);
char *argv[] = {
"/man", // ARGv[0] needs to be something.
manpage,
NULL
};
execvpe ("man", argv, envp);
LOG_ERR("Could not execute \"man %s\" error: %s", manpage,
strerror(errno));
}

static void show_version (const char *name) {
#ifdef HAVE_TCTI_TABRMD
#define TCTI_TABRMD_CONF "tabrmd,"
#else
#define TCTI_TABRMD_CONF ""
#endif

#ifdef HAVE_TCTI_SOCK
#define TCTI_SOCK_CONF "socket,"
#else
#define TCTI_SOCK_CONF ""
#endif

#ifdef HAVE_TCTI_DEV
#define TCTI_DEV_CONF "device,"
#else
#define TCTI_DEV_CONF ""
#endif

static const char *tcti_conf = TCTI_TABRMD_CONF TCTI_SOCK_CONF TCTI_DEV_CONF;
printf("tool=\"%s\" version=\"%s\" tctis=\"%s\"\n", name, VERSION,
tcti_conf);
}

tpm2_option_code tpm2_handle_options (int argc, char **argv, char **envp,
tpm2_options *tool_opts, tpm2_option_flags *flags,
TSS2_TCTI_CONTEXT **tcti) {

tpm2_option_code rc = tpm2_option_code_err;
bool result = false;

UNUSED(envp);

struct option long_options [] = {
{ "tcti", required_argument, NULL, 'T' },
{ "help", no_argument, NULL, 'h' },
{ "verbose", no_argument, NULL, 'v' },
{ "quiet", no_argument, NULL, 'Q' },
{ "version", no_argument, NULL, 'V' },
};

char *tcti_opts = NULL;
char *tcti_name = TCTI_DEFAULT_STR;
char *env_str = getenv (TPM2TOOLS_ENV_TCTI_NAME);
tcti_name = env_str ? env_str : tcti_name;

/* handle any options */
tpm2_options *opts = tpm2_options_new("T:hvVQ",
ARRAY_LEN(long_options), long_options, NULL, NULL);
if (!opts) {
return tpm2_option_code_err;
}

/* Get the options from the tool */
if (tool_opts) {
result = tpm2_options_cat(&opts, tool_opts);
if (!result) {
goto out;
}
}

/* Parse the options, calling the tool callback if unknown */
int c;
while ((c = getopt_long (argc, argv, opts->short_opts, opts->long_opts, NULL))
!= -1)
{
switch (c) {
case 'T':
/* only attempt to get options from tcti option string */
tcti_name = optarg;
tcti_opts = tcti_get_opts(optarg);
break;
case 'h':
execute_man(argv[0], envp);
result = false;
goto out;
break;
case 'V':
flags->verbose = 1;
break;
case 'Q':
flags->quiet = 1;
break;
case 'v':
show_version(argv[0]);
rc = tpm2_option_code_stop;
goto out;
break;
case ':':
LOG_ERR("Argument %c needs a value!", optopt);
goto out;
case '?':
LOG_ERR("Unknown Argument: %c", optopt);
result = false;
goto out;
default:
/* NULL on_opt handler and unkown option specified is an error */
if (!tool_opts->callbacks.on_opt) {
LOG_ERR("Unknown options found: %c", c);
goto out;
}
result = tool_opts->callbacks.on_opt(c, optarg);
if (!result) {
goto out;
}
}
}

char **tool_args = &argv[optind];
int tool_argc = argc - optind;

/* have args and a handler to process */
if (tool_argc && tool_opts->callbacks.on_arg) {
result = tool_opts->callbacks.on_arg(tool_argc, tool_args);
if (!result) {
goto out;
}
/* have args and no handler, error condition */
} else if (tool_argc && !tool_opts->callbacks.on_arg) {
goto out;
}

size_t i;
bool found = false;
for(i=0; i < ARRAY_LEN(tcti_map_table); i++) {

char *name = tcti_map_table[i].name;
tcti_init init = tcti_map_table[i].init;
if (!strcmp(tcti_name, name)) {
found = true;
*tcti = init(tcti_opts);
if (!*tcti) {
result = false;
goto out;
}
}
}

if (!found) {
LOG_ERR("Unknown tcti, got: \"%s\"", tcti_name);
result = false;
goto out;
}

rc = tpm2_option_code_continue;

out:
tpm2_options_free(opts);

return rc;
}
176 changes: 176 additions & 0 deletions lib/tpm2_options.h
@@ -0,0 +1,176 @@
/*
* Copyright (c) 2016, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef OPTIONS_H
#define OPTIONS_H

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>

#include <getopt.h>

#include <sapi/tpm20.h>

typedef struct tpm2_options tpm2_options;

typedef union tpm2_option_flags tpm2_option_flags;
union tpm2_option_flags {
struct {
UINT8 verbose : 1;
UINT8 quiet : 1;
UINT8 unused : 6;
};
UINT8 all;
};

/**
* This function pointer defines the interface for tcti initialization.
* ALL tool supported TCTIs should implement this interface.
* @param opts
* An option string, that is defined by the tcti, and is passed
* via the --tcti= or -T options.
*
* Anything following the : in the --tcti option is provides as opts.
* @return
* NULL on error or an initialized TCTI.
*/
typedef TSS2_TCTI_CONTEXT *(*tcti_init)(char *opts);

/**
* Tools may implement this optional interface if they need
* to handle options.
* @param key
* The key of the option, ie short option return value from getopt_long().
* @param value
* The getopt_long optarg value.
* @return
* true on success, false on error.
* @note
* LOG_INFO and TOOL_OUTPUT will not work correctly during this callback.
* This is called after onstart() finishes, but before
* onrun() is invoked.
*
*/
typedef bool (*tpm2_option_handler)(char key, char *value);

/**
* Called after option handling to process arguments, if specified.
* @param argc
* The number of args in argv.
* @param argv
* The arguments.
* @return
* true on success, false otherwise.
* @note
* LOG_INFO adn TOOL_OUTPUT will not work correctly during this callback.
* This is called after onstart() and tpm2_option_handler() (if specified),
* but before onrun() is invoked.
*
*/
typedef bool (*tpm2_arg_handler)(int argc, char **argv);

/**
* The onstart() routine expects a return of NULL or a tpm2_options structure.
* This routine initializes said object.
* @param short_opts
* Any short options you wish to specify to getopt_long.
* @param len
* The length of the long_opts array.
* @param long_opts
* Any long options you wish to specify to getopt_long().
* @param on_opt
* An option handling callback, which may be null if you don't wish
* to handle options.
* @param on_arg
* An argument handling callback, which may be null if you don't wish
* to handle arguments.
* @return
* NULL on failure or an initialized tpm2_options object.
*/
tpm2_options *tpm2_options_new(const char *short_opts, size_t len,
const struct option *long_opts, tpm2_option_handler on_opt,
tpm2_arg_handler on_arg);

/**
* Concatenates two tpm2_options objects, with src appended on
* dest. The internal callbacks for tpm2_arg_handler and tpm2_option_handler
* which were specified during tpm2_options_new() are copied from src to
* dest, thus overwriting dest. Short and long options are concatenated.
* @param dest
* The tpm2_options object to append to.
* @param src
* The source tpm2_options to append onto dest.
* @return
* true on success, false otherwise.
*/
bool tpm2_options_cat(tpm2_options **dest, tpm2_options *src);

/**
* Free's a tpm2_options created via tpm2_options_new().
* @param opts
* The tpm2_options object to deallocate.
*/
void tpm2_options_free(tpm2_options *opts);

typedef enum tpm2_option_code tpm2_option_code;
enum tpm2_option_code {
tpm2_option_code_continue,
tpm2_option_code_stop,
tpm2_option_code_err
};

/**
* Parses the tpm2_tool command line.
*
* @param argc
* The argc from main.
* @param argv
* The argv from main.
* @param envp
* The envp from main.
* @param tool_opts
* The tool options gathered during onstart() lifecycle call.
* @param flags
* The tpm2_option_flags to set during parsing.
* @param tcti
* The tcti initialized from the tcti options.
* @return
* A tpm option code indicating if an error, further processing
* or an immediate exit is desired.
* @note
* Used by tpm2_tool, and likely should only be used there.
*
*/
tpm2_option_code tpm2_handle_options (int argc, char **argv, char **envp,
tpm2_options *tool_opts, tpm2_option_flags *flags,
TSS2_TCTI_CONTEXT **tcti);

#endif /* OPTIONS_H */
2 changes: 2 additions & 0 deletions lib/tpm2_util.h
Expand Up @@ -36,6 +36,8 @@

#include <sapi/tpm20.h>

#define UNUSED(x) (void)x

#define ARRAY_LEN(x) (sizeof(x)/sizeof(x[0]))

#define BUFFER_SIZE(type, field) (sizeof((((type *)NULL)->t.field)))
Expand Down
17 changes: 4 additions & 13 deletions man/tpm2_startup.8.in
Expand Up @@ -32,24 +32,15 @@
tpm2_startup \- Send a TPM2_Startup command with either TPM_SU_CLEAR or
TPM_SU_STATE.
.SH SYNOPSIS
.B tpm2_startup [ \fBCOMMON OPTIONS\fR ] [ \fBTCTI OPTIONS\fR ] [ \fB\-\-clear\fR|\fB\-\-state\fR ]
.B tpm2_startup [ \fBCOMMON OPTIONS\fR ] [ \fBTCTI OPTIONS\fR ] [ \fB\-\-clear\fR ]
.PP
Send a TPM2_Startup command, with the startupType set to TPM_SU_CLEAR using
the specified TCTI.
Send a TPM2_Startup command.
.SH DESCRIPTION
.B tpm2_send_command
is a command line tool used to send a TPM command to the TPM. The command is
read from stdin as a binary stream and transmitted to the TPM using the TCTI
specified by the caller. The response received from the TPM is written to
stdout. Likely the caller will want to redirect this to a file or into a
program to decode and display the response in a human readable form.
Send a startup command to the tpm.
.SH OPTIONS
.TP
\fB\-c,\ \-\-clear\fR
Startup type sent will be TPM_SU_CLEAR.
.TP
\fB\-s,\ \-\-state\fR
Startup type sent will be TPM2_SU_STATE.
Startup type sent will be TPM_SU_CLEAR instead of TPM2_SU_STATE.
@COMMON_OPTIONS_INCLUDE@
@TCTI_OPTIONS_INCLUDE@
.SH ENVIRONMENT
Expand Down
4 changes: 2 additions & 2 deletions test/system/test_tpm2_startup.sh
Expand Up @@ -37,9 +37,9 @@ if [ $? -ne 0 ]; then
exit 1
fi

tpm2_startup --state
tpm2_startup
if [ $? -ne 0 ]; then
echo "tpm2_startup --state failed."
echo "tpm2_startup default failed."
exit 1
fi

Expand Down
104 changes: 0 additions & 104 deletions tools/main.c

This file was deleted.

232 changes: 103 additions & 129 deletions tools/tpm2_activatecredential.c
Expand Up @@ -37,21 +37,30 @@

#include <limits.h>
#include <ctype.h>
#include <getopt.h>

#include <sapi/tpm20.h>

#include "tpm2_options.h"
#include "tpm2_password_util.h"
#include "files.h"
#include "log.h"
#include "main.h"
#include "options.h"
#include "tpm2_util.h"
#include "tpm_session.h"
#include "tpm2_tool.h"

typedef struct tpm_activatecred_ctx tpm_activatecred_ctx;
struct tpm_activatecred_ctx {

struct {
UINT8 H : 1;
UINT8 c : 1;
UINT8 k : 1;
UINT8 C : 1;
UINT8 f : 1;
UINT8 o : 1;
UINT8 unused : 2;
} flags;

struct {
TPMI_DH_OBJECT activate;
TPMI_DH_OBJECT key;
Expand All @@ -70,6 +79,8 @@ struct tpm_activatecred_ctx {
} file ;
};

static tpm_activatecred_ctx ctx;

static bool read_cert_secret(const char *path, TPM2B_ID_OBJECT *credentialBlob,
TPM2B_ENCRYPTED_SECRET *secret) {

Expand Down Expand Up @@ -117,19 +128,18 @@ static bool read_cert_secret(const char *path, TPM2B_ID_OBJECT *credentialBlob,

static bool output_and_save(TPM2B_DIGEST *digest, const char *path) {

printf("\nCertInfoData :\n");
tpm2_tool_output("certinfodata:");

unsigned k;
for (k = 0; k < digest->t.size; k++) {
printf("0x%.2x ", digest->t.buffer[k]);
tpm2_tool_output("%.2x", digest->t.buffer[k]);
}
printf("\n\n");
tpm2_tool_output("\n");

return files_save_bytes_to_file(path, digest->t.buffer, digest->t.size);
}

static bool activate_credential_and_output(TSS2_SYS_CONTEXT *sapi_context,
tpm_activatecred_ctx *ctx) {
static bool activate_credential_and_output(TSS2_SYS_CONTEXT *sapi_context) {

TPM2B_DIGEST certInfoData = TPM2B_TYPE_INIT(TPM2B_DIGEST, buffer);
TPMS_AUTH_COMMAND tmp_auth = {
Expand All @@ -139,11 +149,11 @@ static bool activate_credential_and_output(TSS2_SYS_CONTEXT *sapi_context,
.sessionAttributes = { .val = 0 },
};

ctx->password.sessionHandle = TPM_RS_PW;
ctx->endorse_password.sessionHandle = TPM_RS_PW;
ctx.password.sessionHandle = TPM_RS_PW;
ctx.endorse_password.sessionHandle = TPM_RS_PW;

TPMS_AUTH_COMMAND *cmd_session_array_password[2] = {
&ctx->password,
&ctx.password,
&tmp_auth
};

Expand All @@ -152,7 +162,7 @@ static bool activate_credential_and_output(TSS2_SYS_CONTEXT *sapi_context,
};

TPMS_AUTH_COMMAND *cmd_session_array_endorse[1] = {
&ctx->endorse_password
&ctx.endorse_password
};

TSS2_SYS_CMD_AUTHS cmd_auth_array_endorse = {
Expand Down Expand Up @@ -188,8 +198,8 @@ static bool activate_credential_and_output(TSS2_SYS_CONTEXT *sapi_context,
tmp_auth.sessionAttributes.continueSession = 1;
tmp_auth.hmac.t.size = 0;

rval = Tss2_Sys_ActivateCredential(sapi_context, ctx->handle.activate,
ctx->handle.key, &cmd_auth_array_password, &ctx->credentialBlob, &ctx->secret,
rval = Tss2_Sys_ActivateCredential(sapi_context, ctx.handle.activate,
ctx.handle.key, &cmd_auth_array_password, &ctx.credentialBlob, &ctx.secret,
&certInfoData, 0);
if (rval != TPM_RC_SUCCESS) {
LOG_ERR("ActivateCredential failed. TPM Error:0x%x", rval);
Expand All @@ -205,130 +215,99 @@ static bool activate_credential_and_output(TSS2_SYS_CONTEXT *sapi_context,

tpm_session_auth_end(session);

return output_and_save(&certInfoData, ctx->file.output);
return output_and_save(&certInfoData, ctx.file.output);
}

static bool init(int argc, char *argv[], tpm_activatecred_ctx *ctx) {

static const char *optstring = "H:c:k:C:P:e:f:o:X";
static const struct option long_options[] = {
{"handle", required_argument, NULL, 'H'},
{"context", required_argument, NULL, 'c'},
{"keyHandle", required_argument, NULL, 'k'},
{"keyContext", required_argument, NULL, 'C'},
{"Password", required_argument, NULL, 'P'},
{"endorsePasswd", required_argument, NULL, 'e'},
{"inFile", required_argument, NULL, 'f'},
{"outFile", required_argument, NULL, 'o'},
{"passwdInHex", no_argument, NULL, 'X'},
{NULL, no_argument, NULL, '\0'},
};

if (argc == 1) {
showArgMismatch(argv[0]);
return false;
}
static bool on_option(char key, char *value) {

int H_flag = 0, c_flag = 0, k_flag = 0, C_flag = 0,
f_flag = 0, o_flag = 0;

int opt;
bool result;
while ((opt = getopt_long(argc, argv, optstring, long_options, NULL))
!= -1) {
switch (opt) {
case 'H':
result = tpm2_util_string_to_uint32(optarg, &ctx->handle.activate);
if (!result) {
LOG_ERR("Could not convert -H argument to a number, "
"got \"%s\"!", optarg);
return false;
}
H_flag = 1;
break;
case 'c':
ctx->file.context = optarg;
c_flag = 1;
break;
case 'k':
result = tpm2_util_string_to_uint32(optarg, &ctx->handle.key);
if (!result) {
return false;
}
k_flag = 1;
break;
case 'C':
ctx->file.key_context = optarg;
C_flag = 1;
break;
case 'P':
result = tpm2_password_util_from_optarg(optarg, &ctx->password.hmac);
if (!result) {
LOG_ERR("Invalid handle password, got\"%s\"", optarg);
return false;
}
//P_flag = 1;
break;
case 'e':
result = tpm2_password_util_from_optarg(optarg, &ctx->endorse_password.hmac);
if (!result) {
LOG_ERR("Invalid endorse password, got\"%s\"", optarg);
return false;
}
break;
case 'f':
/* logs errors */
result = read_cert_secret(optarg, &ctx->credentialBlob,
&ctx->secret);
if (!result) {
return false;
}
f_flag = 1;
break;
case 'o':
ctx->file.output = optarg;
o_flag = 1;
break;
case ':':
LOG_ERR("Argument %c needs a value!", optopt);
switch (key) {
case 'H':
result = tpm2_util_string_to_uint32(value, &ctx.handle.activate);
if (!result) {
LOG_ERR("Could not convert -H argument to a number, "
"got \"%s\"!", value);
return false;
case '?':
LOG_ERR("Unknown Argument: %c", optopt);
}
ctx.flags.H = 1;
break;
case 'c':
ctx.file.context = value;
ctx.flags.c = 1;
break;
case 'k':
result = tpm2_util_string_to_uint32(value, &ctx.handle.key);
if (!result) {
return false;
default:
LOG_ERR("?? getopt returned character code 0%o ??", opt);
}
ctx.flags.k = 1;
break;
case 'C':
ctx.file.key_context = value;
ctx.flags.C = 1;
break;
case 'P':
result = tpm2_password_util_from_optarg(value, &ctx.password.hmac);
if (!result) {
LOG_ERR("Invalid handle password, got\"%s\"", value);
return false;
}
};

if ((!H_flag && !c_flag )
&& (!k_flag || !C_flag) && !f_flag && !o_flag) {
showArgMismatch(argv[0]);
return false;
break;
case 'e':
result = tpm2_password_util_from_optarg(value, &ctx.endorse_password.hmac);
if (!result) {
LOG_ERR("Invalid endorse password, got\"%s\"", value);
return false;
}
break;
case 'f':
/* logs errors */
result = read_cert_secret(value, &ctx.credentialBlob,
&ctx.secret);
if (!result) {
return false;
}
ctx.flags.f = 1;
break;
case 'o':
ctx.file.output = value;
ctx.flags.o = 1;
break;
}

return true;
}

int execute_tool(int argc, char *argv[], char *envp[], common_opts_t *opts,
TSS2_SYS_CONTEXT *sapi_context) {
bool tpm2_tool_onstart(tpm2_options **opts) {

static const struct option topts[] = {
{"handle", required_argument, NULL, 'H'},
{"context", required_argument, NULL, 'c'},
{"keyHandle", required_argument, NULL, 'k'},
{"keyContext", required_argument, NULL, 'C'},
{"Password", required_argument, NULL, 'P'},
{"endorsePasswd", required_argument, NULL, 'e'},
{"inFile", required_argument, NULL, 'f'},
{"outFile", required_argument, NULL, 'o'},
{"passwdInHex", no_argument, NULL, 'X'},
};

*opts = tpm2_options_new("H:c:k:C:P:e:f:o:X", ARRAY_LEN(topts), topts,
on_option, NULL);

return *opts != NULL;
}

int tpm2_tool_onrun(TSS2_SYS_CONTEXT *sapi_context, tpm2_option_flags flags) {

/* opts is unused, avoid compiler warning */
(void) opts;
(void) envp;

/*
* A bug in certain gcc versions prevents us from using = { 0 };
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119
*
* Declare it static since we don't need thread safety.
*/
static tpm_activatecred_ctx ctx;

bool result = init(argc, argv, &ctx);
if (!result) {
LOG_ERR("Initialization failed");
return 1;
UNUSED(flags);

if ((!ctx.flags.H && !ctx.flags.c)
&& (!ctx.flags.k || !ctx.flags.C) && !ctx.flags.f
&& !ctx.flags.o) {
LOG_ERR("Expected options (H or c) and (k or C) and f and o");
return false;
}

if (ctx.file.context) {
Expand All @@ -347,10 +326,5 @@ int execute_tool(int argc, char *argv[], char *envp[], common_opts_t *opts,
}
}

result = activate_credential_and_output(sapi_context, &ctx);
if (!result) {
return 1;
}

return 0;
return activate_credential_and_output(sapi_context) != true;
}
84 changes: 30 additions & 54 deletions tools/tpm2_akparse.c
Expand Up @@ -39,18 +39,21 @@
#include <getopt.h>
#include <sapi/tpm20.h>

#include "tpm2_options.h"
#include "files.h"
#include "log.h"
#include "main.h"
#include "options.h"
#include "tpm2_tool.h"
#include "tpm2_util.h"

typedef struct tpm_akparse_ctx tpm_akparse_ctx;
struct tpm_akparse_ctx {
char *ak_data_file_path;
char *ak_key_file_path;
TSS2_SYS_CONTEXT *sapi_context;
};

static tpm_akparse_ctx ctx;

static bool save_alg_and_key_to_file(const char *key_file, UINT16 alg_type,
TPM2B **key_data, size_t key_data_len) {

Expand Down Expand Up @@ -101,12 +104,12 @@ static bool save_alg_and_key_to_file(const char *key_file, UINT16 alg_type,
return true;
}

static bool parse_and_save_ak_public(tpm_akparse_ctx *ctx) {
static bool parse_and_save_ak_public() {

TPM2B_PUBLIC outPublic;
UINT16 size = sizeof(outPublic);

bool result = files_load_bytes_from_path(ctx->ak_data_file_path, (UINT8 *)&outPublic, &size);
bool result = files_load_bytes_from_path(ctx.ak_data_file_path, (UINT8 *)&outPublic, &size);
if (!result) {
/* loadDataFromFile prints error */
return false;
Expand Down Expand Up @@ -135,69 +138,42 @@ static bool parse_and_save_ak_public(tpm_akparse_ctx *ctx) {
return false;
}

return save_alg_and_key_to_file(ctx->ak_key_file_path, outPublic.t.publicArea.type,
return save_alg_and_key_to_file(ctx.ak_key_file_path, outPublic.t.publicArea.type,
key_data, key_data_len);
}

static bool init(int argc, char *argv[], tpm_akparse_ctx *ctx) {
static bool on_option(char key, char *value) {

switch (key) {
case 'f':
ctx.ak_data_file_path = value;
break;
case 'k':
ctx.ak_key_file_path = value;
break;
}

return true;
}

bool tpm2_tool_onstart(tpm2_options **opts) {

struct option options[] = {
const struct option topts[] = {
{ "file", required_argument, NULL, 'f' },
{ "keyFile", required_argument, NULL, 'k' },
{ NULL, no_argument, NULL, '\0' }
};

if (argc <=1 || argc > (int) (2 * sizeof(options) / sizeof(struct option))) {
showArgMismatch(argv[0]);
return false;
}
*opts = tpm2_options_new("f:k:", ARRAY_LEN(topts), topts, on_option, NULL);

int opt;
while ((opt = getopt_long(argc, argv, "f:k:hv", options, NULL)) != -1) {
switch (opt) {
case 'f':
if (!optarg) {
LOG_ERR("Please input the file that used to be parsed.");
return false;
}
ctx->ak_data_file_path = optarg;
break;
case 'k':
if (!optarg) {
LOG_ERR("Please input the file that used to save ak key.");
return false;
}
ctx->ak_key_file_path = optarg;
break;
case ':':
LOG_ERR("Argument %c needs a value!", optopt);
return false;
case '?':
LOG_ERR("Unknown Argument: %c", optopt);
return false;
default:
LOG_ERR("?? getopt returned character code 0%o ??", opt);
return false;
}
}
return true;
return *opts != NULL;
}

int execute_tool(int argc, char *argv[], char *envp[], common_opts_t *opts,
TSS2_SYS_CONTEXT *sapi_context) {

/* opts is unused, avoid compiler warning */
(void)opts;
(void)sapi_context;
(void)envp;
int tpm2_tool_onrun(TSS2_SYS_CONTEXT *sapi_context, tpm2_option_flags flags) {

struct tpm_akparse_ctx ctx;
UNUSED(flags);

bool result = init(argc, argv, &ctx);
if (!result) {
return 1;
}
ctx.sapi_context = sapi_context;

/* 0 on success 1 on error */
return parse_and_save_ak_public(&ctx) != true;
return parse_and_save_ak_public() != true;
}
291 changes: 126 additions & 165 deletions tools/tpm2_certify.c
Expand Up @@ -38,13 +38,13 @@
#include <limits.h>
#include <sapi/tpm20.h>

#include "tpm2_options.h"
#include "tpm2_password_util.h"
#include "tpm2_util.h"
#include "log.h"
#include "files.h"
#include "main.h"
#include "options.h"
#include "tpm2_alg_util.h"
#include "tpm2_tool.h"

typedef struct tpm_certify_ctx tpm_certify_ctx;
struct tpm_certify_ctx {
Expand All @@ -60,6 +60,26 @@ struct tpm_certify_ctx {
char *sig;
} file_path;
TSS2_SYS_CONTEXT *sapi_context;
struct {
UINT16 H : 1;
UINT16 k : 1;
UINT16 P : 1;
UINT16 K : 1;
UINT16 g : 1;
UINT16 a : 1;
UINT16 s : 1;
UINT16 C : 1;
UINT16 c : 1;
} flags;
char *context_file;
char *context_key_file;
};

static tpm_certify_ctx ctx = {
.cmd_auth = {
TPMS_AUTH_COMMAND_INIT(TPM_RS_PW),
TPMS_AUTH_COMMAND_INIT(TPM_RS_PW),
},
};

static bool get_key_type(TSS2_SYS_CONTEXT *sapi_context, TPMI_DH_OBJECT object_handle, TPMI_ALG_PUBLIC *type) {
Expand Down Expand Up @@ -123,19 +143,19 @@ static bool set_scheme(TSS2_SYS_CONTEXT *sapi_context, TPMI_DH_OBJECT key_handle
return true;
}

static bool certify_and_save_data(tpm_certify_ctx *ctx) {
static bool certify_and_save_data(void) {

TPMS_AUTH_COMMAND *cmd_session_array[ARRAY_LEN(ctx->cmd_auth)] = {
&ctx->cmd_auth[0],
&ctx->cmd_auth[1]
TPMS_AUTH_COMMAND *cmd_session_array[ARRAY_LEN(ctx.cmd_auth)] = {
&ctx.cmd_auth[0],
&ctx.cmd_auth[1]
};

TSS2_SYS_CMD_AUTHS cmd_auth_array = {
.cmdAuthsCount = ARRAY_LEN(cmd_session_array),
.cmdAuths = cmd_session_array
};

TPMS_AUTH_RESPONSE session_data_out[ARRAY_LEN(ctx->cmd_auth)];
TPMS_AUTH_RESPONSE session_data_out[ARRAY_LEN(ctx.cmd_auth)];
TPMS_AUTH_RESPONSE *session_data_array[] = {
&session_data_out[0],
&session_data_out[1]
Expand All @@ -154,7 +174,7 @@ static bool certify_and_save_data(tpm_certify_ctx *ctx) {
};

TPMT_SIG_SCHEME scheme;
bool result = set_scheme(ctx->sapi_context, ctx->handle.key, ctx->halg, &scheme);
bool result = set_scheme(ctx.sapi_context, ctx.handle.key, ctx.halg, &scheme);
if (!result) {
LOG_ERR("No suitable signing scheme!");
return false;
Expand All @@ -168,35 +188,102 @@ static bool certify_and_save_data(tpm_certify_ctx *ctx) {

TPMT_SIGNATURE signature;

TPM_RC rval = Tss2_Sys_Certify(ctx->sapi_context, ctx->handle.obj,
ctx->handle.key, &cmd_auth_array, &qualifying_data, &scheme,
TPM_RC rval = Tss2_Sys_Certify(ctx.sapi_context, ctx.handle.obj,
ctx.handle.key, &cmd_auth_array, &qualifying_data, &scheme,
&certify_info, &signature, &sessions_data_out);
if (rval != TPM_RC_SUCCESS) {
LOG_ERR("TPM2_Certify failed. Error Code: 0x%x", rval);
return false;
}

/* serialization is safe here, since it's just a byte array */
result = files_save_bytes_to_file(ctx->file_path.attest,
result = files_save_bytes_to_file(ctx.file_path.attest,
(UINT8 *) certify_info.t.attestationData, certify_info.t.size);
if (!result) {
return false;
}

/* TODO serialization is not safe here */
return files_save_bytes_to_file(ctx->file_path.sig, (UINT8 *) &signature,
return files_save_bytes_to_file(ctx.file_path.sig, (UINT8 *) &signature,
sizeof(signature));
}

static bool init(int argc, char *argv[], tpm_certify_ctx *ctx) {
static bool on_option(char key, char *value) {

bool result;

char *context_file = NULL;
char *context_key_file = NULL;
switch (key) {
case 'H':
result = tpm2_util_string_to_uint32(value, &ctx.handle.obj);
if (!result) {
return false;
}
ctx.flags.H = 1;
break;
case 'k':
result = tpm2_util_string_to_uint32(value, &ctx.handle.key);
if (!result) {
return false;
}
ctx.flags.k = 1;
break;
case 'P':
result = tpm2_password_util_from_optarg(value, &ctx.cmd_auth[0].hmac);
if (!result) {
return false;
}
ctx.flags.P = 1;
break;
case 'K':
result = tpm2_password_util_from_optarg(value, &ctx.cmd_auth[1].hmac);
if (!result) {
return false;
}
ctx.flags.K = 1;
break;
case 'g':
ctx.halg = tpm2_alg_util_from_optarg(value);
if (ctx.halg == TPM_ALG_ERROR) {
return false;
}
ctx.flags.g = 1;
break;
case 'a':
if (files_does_file_exist(value)) {
return false;
}
ctx.file_path.attest = value;
ctx.flags.a = 1;
break;
case 's':
if (files_does_file_exist(value)) {
return false;
}
ctx.file_path.sig = optarg;
ctx.flags.s = 1;
break;
case 'c':
if (ctx.context_key_file) {
return false;
}
ctx.context_key_file = value;
ctx.flags.c = 1;
break;
case 'C':
if (ctx.context_file) {
return false;
}
ctx.context_file = optarg;
ctx.flags.C = 1;
break;
}

return true;
}

const char *optstring = "H:k:P:K:g:a:s:C:c:";
static struct option long_options[] = {
bool tpm2_tool_onstart(tpm2_options **opts) {

const struct option topts[] = {
{"objectHandle", required_argument, NULL, 'H'},
{"keyHandle", required_argument, NULL, 'k'},
{"pwdo", required_argument, NULL, 'P'},
Expand All @@ -209,165 +296,39 @@ static bool init(int argc, char *argv[], tpm_certify_ctx *ctx) {
{NULL, no_argument, NULL, '\0'}
};

union {
struct {
UINT16 H : 1;
UINT16 k : 1;
UINT16 P : 1;
UINT16 K : 1;
UINT16 g : 1;
UINT16 a : 1;
UINT16 s : 1;
UINT16 C : 1;
UINT16 c : 1;
UINT16 unused : 7;
};
UINT16 all;
} flags = { .all = 0 };


if (argc == 1) {
showArgMismatch(argv[0]);
return false;
}
*opts = tpm2_options_new("H:k:P:K:g:a:s:C:c:", ARRAY_LEN(topts), topts, on_option, NULL);

int opt = -1;

while ((opt = getopt_long(argc, argv, optstring, long_options, NULL))
!= -1) {
switch (opt) {
case 'H':
result = tpm2_util_string_to_uint32(optarg, &ctx->handle.obj);
if (!result) {
LOG_ERR("Could not format object handle to number, got: \"%s\"",
optarg);
return false;
}
flags.H = 1;
break;
case 'k':
result = tpm2_util_string_to_uint32(optarg, &ctx->handle.key);
if (!result) {
LOG_ERR("Could not format key handle to number, got: \"%s\"",
optarg);
return false;
}
flags.k = 1;
break;
case 'P':
result = tpm2_password_util_from_optarg(optarg, &ctx->cmd_auth[0].hmac);
if (!result) {
LOG_ERR("Invalid object key password, got\"%s\"", optarg);
return false;
}
flags.P = 1;
break;
case 'K':
result = tpm2_password_util_from_optarg(optarg, &ctx->cmd_auth[1].hmac);
if (!result) {
LOG_ERR("Invalid key handle password, got\"%s\"", optarg);
return false;
}
flags.K = 1;
break;
case 'g':
ctx->halg = tpm2_alg_util_from_optarg(optarg);
if (ctx->halg == TPM_ALG_ERROR) {
LOG_ERR("Could not format algorithm to number, got: \"%s\"",
optarg);
return false;
}
flags.g = 1;
break;
case 'a':
if (files_does_file_exist(optarg)) {
return false;
}
ctx->file_path.attest = optarg;
flags.a = 1;
break;
case 's':
if (files_does_file_exist(optarg)) {
return false;
}
ctx->file_path.sig = optarg;
flags.s = 1;
break;
case 'c':
if (context_key_file) {
LOG_ERR("Multiple specifications of -c");
return false;
}
context_key_file = optarg;
flags.c = 1;
break;
case 'C':
if (context_file) {
LOG_ERR("Multiple specifications of -C");
return false;
}
context_file = optarg;
flags.C = 1;
break;
case ':':
LOG_ERR("Argument %c needs a value!", optopt);
result = false;
return false;
case '?':
LOG_ERR("Unknown Argument: %c", optopt);
result = false;
return false;
default:
LOG_ERR("?? getopt returned character code 0%o ??", opt);
result = false;
return false;
}
};
return *opts != NULL;
}

if (!(flags.H || flags.C) && (flags.k || flags.c) && (flags.g) && (flags.a)
&& (flags.s)) {
return false;
int tpm2_tool_onrun(TSS2_SYS_CONTEXT *sapi_context, tpm2_option_flags flags) {

bool result;

UNUSED(flags);
ctx.sapi_context = sapi_context;

if (!(ctx.flags.H || ctx.flags.C) && (ctx.flags.k || ctx.flags.c) && (ctx.flags.g) && (ctx.flags.a)
&& (ctx.flags.s)) {
return 1;
}

/* Load input files */
if (flags.C) {
result = files_load_tpm_context_from_file(ctx->sapi_context, &ctx->handle.obj,
context_file);
if (ctx.flags.C) {
result = files_load_tpm_context_from_file(ctx.sapi_context, &ctx.handle.obj,
ctx.context_file);
if (!result) {
return false;
return 1;
}
}

if (flags.c) {
result = files_load_tpm_context_from_file(ctx->sapi_context, &ctx->handle.key,
context_key_file);
if (ctx.flags.c) {
result = files_load_tpm_context_from_file(ctx.sapi_context, &ctx.handle.key,
ctx.context_key_file);
if (!result) {
return false;
return 1;
}
}

return true;
}

int execute_tool(int argc, char *argv[], char *envp[], common_opts_t *opts,
TSS2_SYS_CONTEXT *sapi_context) {

(void)opts;
(void)envp;

tpm_certify_ctx ctx = {
.cmd_auth = {
TPMS_AUTH_COMMAND_INIT(TPM_RS_PW),
TPMS_AUTH_COMMAND_INIT(TPM_RS_PW),
},
.file_path = { .attest = NULL, .sig = NULL },
.sapi_context = sapi_context
};

bool result = init(argc, argv, &ctx);
if (!result) {
return 1;
}

return certify_and_save_data(&ctx) != true;
return certify_and_save_data() != true;
}
491 changes: 232 additions & 259 deletions tools/tpm2_create.c

Large diffs are not rendered by default.

197 changes: 84 additions & 113 deletions tools/tpm2_createpolicy.c
Expand Up @@ -36,13 +36,13 @@
#include <getopt.h>
#include <sapi/tpm20.h>

#include "tpm2_options.h"
#include "files.h"
#include "log.h"
#include "main.h"
#include "options.h"
#include "pcr.h"
#include "tpm2_policy.h"
#include "tpm2_alg_util.h"
#include "tpm2_tool.h"

//Records the type of policy and if one is selected
typedef struct {
Expand Down Expand Up @@ -85,164 +85,135 @@ struct create_policy_ctx {
.policy_digest_hash_alg = TPM_ALG_SHA256, \
}

static TPM_RC parse_policy_type_specific_command (create_policy_ctx *pctx) {
static create_policy_ctx pctx = {
.common_policy_options = TPM2_COMMON_POLICY_INIT
};

static TPM_RC parse_policy_type_specific_command (void) {
TPM_RC rval = TPM_RC_SUCCESS;
if (!pctx->common_policy_options.policy_type.is_policy_type_selected){
if (!pctx.common_policy_options.policy_type.is_policy_type_selected){
LOG_ERR("No Policy type chosen.");
return rval;
}

if (pctx->common_policy_options.policy_type.PolicyPCR) {
if (pctx.common_policy_options.policy_type.PolicyPCR) {
//PCR inputs validation
if (pctx->pcr_policy_options.is_set_list == false) {
if (pctx.pcr_policy_options.is_set_list == false) {
LOG_ERR("Need the pcr list to account for in the policy.");
return TPM_RC_NO_RESULT;
}
rval = tpm2_policy_build(pctx->sapi_context,
&pctx->common_policy_options.policy_session,
pctx->common_policy_options.policy_session_type,
pctx->common_policy_options.policy_digest_hash_alg,
pctx->pcr_policy_options.pcr_selections,
pctx->pcr_policy_options.raw_pcrs_file,
&pctx->common_policy_options.policy_digest,
pctx->common_policy_options.extend_policy_session,
rval = tpm2_policy_build(pctx.sapi_context,
&pctx.common_policy_options.policy_session,
pctx.common_policy_options.policy_session_type,
pctx.common_policy_options.policy_digest_hash_alg,
pctx.pcr_policy_options.pcr_selections,
pctx.pcr_policy_options.raw_pcrs_file,
&pctx.common_policy_options.policy_digest,
pctx.common_policy_options.extend_policy_session,
tpm2_policy_pcr_build);
if (rval != TPM_RC_SUCCESS) {
return rval;
}

// Display the policy digest during real policy session.
if (pctx->common_policy_options.policy_session_type == TPM_SE_POLICY) {
printf("TPM_SE_POLICY: 0x");
if (pctx.common_policy_options.policy_session_type == TPM_SE_POLICY) {
tpm2_tool_output("TPM_SE_POLICY: 0x");
int i;
for(i = 0; i < pctx->common_policy_options.policy_digest.t.size; i++) {
printf("%02X", pctx->common_policy_options.policy_digest.t.buffer[i]);
for(i = 0; i < pctx.common_policy_options.policy_digest.t.size; i++) {
tpm2_tool_output("%02X", pctx.common_policy_options.policy_digest.t.buffer[i]);
}
printf("\n");
tpm2_tool_output("\n");
}

// Additional operations when session if a trial policy session
if (pctx->common_policy_options.policy_session_type == TPM_SE_TRIAL) {
if (pctx.common_policy_options.policy_session_type == TPM_SE_TRIAL) {
//save the policy buffer in a file for use later
bool result = files_save_bytes_to_file(pctx->common_policy_options.policy_file,
(UINT8 *) &pctx->common_policy_options.policy_digest.t.buffer,
pctx->common_policy_options.policy_digest.t.size);
bool result = files_save_bytes_to_file(pctx.common_policy_options.policy_file,
(UINT8 *) &pctx.common_policy_options.policy_digest.t.buffer,
pctx.common_policy_options.policy_digest.t.size);
if (!result) {
LOG_ERR("Failed to save policy digest into file \"%s\"",
pctx->common_policy_options.policy_file);
pctx.common_policy_options.policy_file);
return TPM_RC_NO_RESULT;
}
}
}

if (pctx->common_policy_options.extend_policy_session) {
printf("EXTENDED_POLICY_SESSION_HANDLE: 0x%08X",
pctx->common_policy_options.policy_session->sessionHandle );
if (pctx.common_policy_options.extend_policy_session) {
tpm2_tool_output("EXTENDED_POLICY_SESSION_HANDLE: 0x%08X",
pctx.common_policy_options.policy_session->sessionHandle );
}

return rval;
}

static bool init(int argc, char *argv[], create_policy_ctx *pctx) {
struct option sOpts[] = {
static bool on_option(char key, char *value) {

switch (key) {
case 'f':
pctx.common_policy_options.policy_file_flag = true;
pctx.common_policy_options.policy_file = value;
break;
case 'F':
pctx.pcr_policy_options.raw_pcrs_file = value;
break;
case 'g':
pctx.common_policy_options.policy_digest_hash_alg
= tpm2_alg_util_from_optarg(value);
if(pctx.common_policy_options.policy_digest_hash_alg == TPM_ALG_ERROR) {
return false;
}
break;
case 'L':
if (!pcr_parse_selections(value, &pctx.pcr_policy_options.pcr_selections)) {
return false;
}
pctx.pcr_policy_options.is_set_list = true;
break;
case 'P':
pctx.common_policy_options.policy_type.PolicyPCR = true;
pctx.common_policy_options.policy_type.is_policy_type_selected= true;
break;
case 'a':
pctx.common_policy_options.policy_session_type = TPM_SE_POLICY;
pctx.common_policy_options.extend_policy_session = true;
break;
case 'e':
pctx.common_policy_options.extend_policy_session = true;
break;
}

return true;
}

bool tpm2_tool_onstart(tpm2_options **opts) {

const struct option topts[] = {
{ "policy-file", required_argument, NULL, 'f' },
{ "policy-digest-alg", required_argument, NULL, 'g'},
{ "set-list", required_argument, NULL, 'L' },
{ "pcr-input-file", required_argument, NULL, 'F' },
{ "policy-pcr", no_argument, NULL, 'P' },
{ "auth-policy-session", no_argument, NULL, 'a'},
{ "extend-policy-session", no_argument, NULL, 'e'},
{ NULL, no_argument, NULL, '\0'},
};
if (argc == 1) {
showArgMismatch(argv[0]);
return false;
}

int opt;
while ((opt = getopt_long(argc, argv, "f:g:L:F:Pae", sOpts, NULL)) != -1) {
switch (opt) {
case 'f':
pctx->common_policy_options.policy_file_flag = true;
pctx->common_policy_options.policy_file = optarg;
break;
case 'F':
pctx->pcr_policy_options.raw_pcrs_file = optarg;
break;
case 'g':
pctx->common_policy_options.policy_digest_hash_alg
= tpm2_alg_util_from_optarg(optarg);
if(pctx->common_policy_options.policy_digest_hash_alg
== TPM_ALG_ERROR) {
showArgError(optarg, argv[0]);
LOG_ERR("Invalid choice for policy digest hash algorithm");
return false;
}
break;
case 'L':
if (!pcr_parse_selections(optarg,
&pctx->pcr_policy_options.pcr_selections)) {
showArgError(optarg, argv[0]);
return false;
}
pctx->pcr_policy_options.is_set_list = true;
break;
case 'P':
pctx->common_policy_options.policy_type.PolicyPCR = true;
pctx->common_policy_options.policy_type.is_policy_type_selected= true;
LOG_INFO("Policy type chosen is policyPCR.");
break;
case 'a':
pctx->common_policy_options.policy_session_type = TPM_SE_POLICY;
pctx->common_policy_options.extend_policy_session = true;
LOG_INFO("Policy session setup for auth.");
break;
case 'e':
pctx->common_policy_options.extend_policy_session = true;
LOG_INFO("Policy session setup to extend after operation.");
break;
case ':':
LOG_ERR("Argument %c needs a value!", optopt);
return false;
case '?':
LOG_ERR("Unknown Argument: %c", optopt);
return false;
default:
LOG_ERR("?? getopt returned character code 0%o ??", opt);
return false;
}
}
if (pctx->common_policy_options.policy_file_flag == false &&
pctx->common_policy_options.policy_session_type == TPM_SE_TRIAL) {
LOG_ERR("Provide the file name to store the resulting "
"policy digest");
return false;
}
return true;
}

int execute_tool(int argc, char *argv[], char *envp[], common_opts_t *opts,
TSS2_SYS_CONTEXT *sapi_context) {
*opts = tpm2_options_new("f:g:L:F:Pae", ARRAY_LEN(topts), topts, on_option, NULL);

/* opts and envp are unused */
(void) opts;
(void) envp;
return *opts != NULL;
}

create_policy_ctx pctx = {
.sapi_context = sapi_context,
.common_policy_options = TPM2_COMMON_POLICY_INIT
};
int tpm2_tool_onrun(TSS2_SYS_CONTEXT *sapi_context, tpm2_option_flags flags) {

bool result = init(argc, argv, &pctx);
if (!result) {
return 1;
}
UNUSED(flags);
pctx.sapi_context = sapi_context;

TPM_RC rval = parse_policy_type_specific_command(&pctx);
if (rval != TPM_RC_SUCCESS) {
if (pctx.common_policy_options.policy_file_flag == false &&
pctx.common_policy_options.policy_session_type == TPM_SE_TRIAL) {
LOG_ERR("Provide the file name to store the resulting "
"policy digest");
return 1;
}

/* true is success, coerce to 0 for program success */
return 0;
return parse_policy_type_specific_command() != TPM_RC_SUCCESS;
}