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_ */
364 changes: 364 additions & 0 deletions lib/tpm2_options.c
@@ -0,0 +1,364 @@
/*
* 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;
}

opts->short_opts = strdup(short_opts);
if (!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
104 changes: 0 additions & 104 deletions tools/main.c

This file was deleted.

213 changes: 90 additions & 123 deletions tools/tpm2_activatecredential.c
Expand Up @@ -37,17 +37,16 @@

#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 {
Expand All @@ -70,6 +69,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 +118,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("0x%.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 +139,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 +152,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 +188,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,131 +205,103 @@ 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);
}
H_flag = 1;
break;
case 'c':
ctx.file.context = value;
c_flag = 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);
}
k_flag = 1;
break;
case 'C':
ctx.file.key_context = value;
C_flag = 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;
}
};
//P_flag = 1;
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;
}
f_flag = 1;
break;
case 'o':
ctx.file.output = value;
o_flag = 1;
break;
}

if ((!H_flag && !c_flag )
&& (!k_flag || !C_flag) && !f_flag && !o_flag) {
showArgMismatch(argv[0]);
LOG_ERR("Expected options (H or c) and (k or C) and f and o");
return false;
}

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.file.context) {
bool res = files_load_tpm_context_from_file(sapi_context, &ctx.handle.activate,
Expand All @@ -347,10 +319,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) != false;
}
4 changes: 2 additions & 2 deletions tools/tpm2_akparse.c
Expand Up @@ -39,10 +39,10 @@
#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;
Expand Down
4 changes: 2 additions & 2 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 Down
26 changes: 9 additions & 17 deletions tools/tpm2_create.c
Expand Up @@ -41,13 +41,13 @@

#include <sapi/tpm20.h>

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

TSS2_SYS_CONTEXT *sysContext;
TPMS_AUTH_COMMAND sessionData = {
Expand Down Expand Up @@ -174,7 +174,7 @@ int create(TPMI_DH_OBJECT parentHandle, TPM2B_PUBLIC *inPublic, TPM2B_SENSITIVE_

if(A_flag == 1)
inPublic->t.publicArea.objectAttributes.val = objectAttributes;
TOOL_OUTPUT("ObjectAttribute: 0x%08X\n",inPublic->t.publicArea.objectAttributes.val);
tpm2_tool_output("ObjectAttribute: 0x%08X\n",inPublic->t.publicArea.objectAttributes.val);

creationPCR.count = 0;

Expand All @@ -186,7 +186,7 @@ int create(TPMI_DH_OBJECT parentHandle, TPM2B_PUBLIC *inPublic, TPM2B_SENSITIVE_
LOG_ERR("\nCreate Object Failed ! ErrorCode: 0x%0x\n",rval);
return -2;
}
TOOL_OUTPUT("\nCreate Object Succeed !\n");
tpm2_tool_output("\nCreate Object Succeed !\n");

/*
* TODO These public and private serializations are not safe since its outputting size as well.
Expand All @@ -205,15 +205,7 @@ int create(TPMI_DH_OBJECT parentHandle, TPM2B_PUBLIC *inPublic, TPM2B_SENSITIVE_
return 0;
}

int
execute_tool (int argc,
char *argv[],
char *envp[],
common_opts_t *opts,
TSS2_SYS_CONTEXT *sapi_context)
{
(void)envp;
(void)opts;
int tpm2_tool_onrun(TSS2_SYS_CONTEXT *sapi_context, tpm2_option_flags flags) {

sysContext = sapi_context;

Expand Down Expand Up @@ -302,7 +294,7 @@ execute_tool (int argc,
showArgError(optarg, argv[0]);
return 1;
}
TOOL_OUTPUT("nameAlg = 0x%4.4x\n", nameAlg);
tpm2_tool_output("nameAlg = 0x%4.4x\n", nameAlg);
g_flag = 1;
break;
case 'G':
Expand All @@ -312,7 +304,7 @@ execute_tool (int argc,
showArgError(optarg, argv[0]);
return 1;
}
TOOL_OUTPUT("type = 0x%4.4x\n", type);
tpm2_tool_output("type = 0x%4.4x\n", type);
G_flag = 1;
break;
case 'A':
Expand All @@ -335,7 +327,7 @@ execute_tool (int argc,
return 1;
}
I_flag = 1;
TOOL_OUTPUT("inSensitive.t.sensitive.data.t.size = %d\n",inSensitive.t.sensitive.data.t.size);
tpm2_tool_output("inSensitive.t.sensitive.data.t.size = %d\n",inSensitive.t.sensitive.data.t.size);
break;
case 'L':
inPublic.t.publicArea.authPolicy.t.size = sizeof(inPublic.t.publicArea.authPolicy) - 2;
Expand Down Expand Up @@ -377,7 +369,7 @@ execute_tool (int argc,
{
return 1;
}
TOOL_OUTPUT("contextParentFile = %s\n", contextParentFilePath);
tpm2_tool_output("contextParentFile = %s\n", contextParentFilePath);
c_flag = 1;
break;
case ':':
Expand Down
4 changes: 2 additions & 2 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
12 changes: 6 additions & 6 deletions tools/tpm2_createprimary.c
Expand Up @@ -42,13 +42,13 @@
#include <sapi/tpm20.h>
#include <tcti/tcti_socket.h>

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

TPMS_AUTH_COMMAND sessionData = {
.sessionHandle = TPM_RS_PW,
Expand Down Expand Up @@ -171,7 +171,7 @@ int createPrimary(TSS2_SYS_CONTEXT *sysContext, TPMI_RH_HIERARCHY hierarchy,
LOG_ERR("\nCreatePrimary Failed ! ErrorCode: 0x%0x\n", rval);
return -2;
}
TOOL_OUTPUT("\nCreatePrimary Succeed ! Handle: 0x%8.8x\n\n", handle2048rsa);
tpm2_tool_output("\nCreatePrimary Succeed ! Handle: 0x%8.8x\n\n", handle2048rsa);
return 0;
}

Expand Down Expand Up @@ -260,7 +260,7 @@ execute_tool (int argc,
showArgError(optarg, argv[0]);
return 1;
}
TOOL_OUTPUT("nameAlg = 0x%4.4x\n", nameAlg);
tpm2_tool_output("nameAlg = 0x%4.4x\n", nameAlg);
g_flag = 1;
break;
case 'G':
Expand All @@ -270,7 +270,7 @@ execute_tool (int argc,
showArgError(optarg, argv[0]);
return 1;
}
TOOL_OUTPUT("type = 0x%4.4x\n", type);
tpm2_tool_output("type = 0x%4.4x\n", type);
G_flag = 1;
break;
case 'C':
Expand All @@ -279,7 +279,7 @@ execute_tool (int argc,
{
return 1;
}
TOOL_OUTPUT("contextFile = %s\n", contextFile);
tpm2_tool_output("contextFile = %s\n", contextFile);
C_flag = 1;
break;
case 'L':
Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_dictionarylockout.c
Expand Up @@ -38,10 +38,10 @@

#include <sapi/tpm20.h>

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

typedef struct dictionarylockout_ctx dictionarylockout_ctx;
Expand Down
2 changes: 1 addition & 1 deletion tools/tpm2_dump_capability.c
Expand Up @@ -34,8 +34,8 @@
#include <sapi/tpm20.h>
#include <tcti/tcti_socket.h>

#include "main.h"
#include "tpm2_alg_util.h"
#include "tpm2_tool.h"
#include "tpm2_util.h"

/* convenience macro to convert flags into "set" / "clear" strings */
Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_encryptdecrypt.c
Expand Up @@ -40,11 +40,11 @@

#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_tool.h"
#include "tpm2_util.h"

typedef struct tpm_encrypt_decrypt_ctx tpm_encrypt_decrypt_ctx;
Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_evictcontrol.c
Expand Up @@ -41,11 +41,11 @@

#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_tool.h"
#include "tpm2_util.h"

typedef struct tpm_evictcontrol_ctx tpm_evictcontrol_ctx;
Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_getmanufec.c
Expand Up @@ -46,12 +46,12 @@
#include <openssl/sha.h>
#include <sapi/tpm20.h>

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

char *outputFile;
Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_getpubak.c
Expand Up @@ -39,14 +39,14 @@

#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_alg_util.h"
#include "tpm2_tool.h"

typedef struct getpubak_context getpubak_context;
struct getpubak_context {
Expand Down
2 changes: 1 addition & 1 deletion tools/tpm2_getpubek.c
Expand Up @@ -41,9 +41,9 @@
#include "tpm2_password_util.h"
#include "files.h"
#include "log.h"
#include "main.h"
#include "tpm2_util.h"
#include "tpm2_alg_util.h"
#include "tpm2_tool.h"

typedef struct getpubek_context getpubek_context;
struct getpubek_context {
Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_getrandom.c
Expand Up @@ -38,10 +38,10 @@
#include <limits.h>
#include <sapi/tpm20.h>

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

typedef struct tpm_random_ctx tpm_random_ctx;
Expand Down
159 changes: 72 additions & 87 deletions tools/tpm2_hash.c
Expand Up @@ -41,10 +41,10 @@

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

typedef struct tpm_hash_ctx tpm_hash_ctx;
Expand All @@ -57,6 +57,11 @@ struct tpm_hash_ctx {
TSS2_SYS_CONTEXT *sapi_context;
};

static tpm_hash_ctx ctx = {
.hierarchyValue = TPM_RH_NULL,
.halg = TPM_ALG_SHA1,
};

static bool get_hierarchy_value(const char *hiearchy_code,
TPMI_RH_HIERARCHY *hierarchy_value) {

Expand Down Expand Up @@ -87,140 +92,120 @@ static bool get_hierarchy_value(const char *hiearchy_code,
return true;
}

static bool hash_and_save(tpm_hash_ctx *ctx) {
static bool hash_and_save(void) {

TPM2B_DIGEST outHash = TPM2B_TYPE_INIT(TPM2B_DIGEST, buffer);
TPMT_TK_HASHCHECK validation;

TPM_RC rval = tpm_hash_file(ctx->sapi_context, ctx->halg, ctx->hierarchyValue, ctx->input_file, &outHash, &validation);
TPM_RC rval = tpm_hash_file(ctx.sapi_context, ctx.halg, ctx.hierarchyValue, ctx.input_file, &outHash, &validation);
if (rval != TPM_RC_SUCCESS) {
LOG_ERR("tpm_hash_files() failed with error: 0x%X", rval);
return false;
}

if (outHash.t.size) {
UINT16 i;
TOOL_OUTPUT("hash(%s):", tpm2_alg_util_algtostr(ctx->halg));
tpm2_tool_output("hash(%s):", tpm2_alg_util_algtostr(ctx.halg));
for (i = 0; i < outHash.t.size; i++) {
TOOL_OUTPUT("%02x", outHash.t.buffer[i]);
tpm2_tool_output("%02x", outHash.t.buffer[i]);
}
TOOL_OUTPUT("\n");
tpm2_tool_output("\n");
}

if (validation.digest.t.size) {
UINT16 i;
TOOL_OUTPUT("ticket:");
tpm2_tool_output("ticket:");
for (i = 0; i < validation.digest.t.size; i++) {
TOOL_OUTPUT("%02x", validation.digest.t.buffer[i]);
tpm2_tool_output("%02x", validation.digest.t.buffer[i]);
}
TOOL_OUTPUT("\n");
tpm2_tool_output("\n");
}

if (ctx->outHashFilePath) {
bool result = files_save_bytes_to_file(ctx->outHashFilePath, (UINT8 *) &outHash,
if (ctx.outHashFilePath) {
bool result = files_save_bytes_to_file(ctx.outHashFilePath, (UINT8 *) &outHash,
sizeof(outHash));
if (!result) {
return false;
}
}

if (ctx->outTicketFilePath) {
return files_save_bytes_to_file(ctx->outTicketFilePath, (UINT8 *) &validation,
if (ctx.outTicketFilePath) {
return files_save_bytes_to_file(ctx.outTicketFilePath, (UINT8 *) &validation,
sizeof(validation));
}

return true;
}

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

static struct option long_options[] = {
{"hierachy", required_argument, NULL, 'H'},
{"halg", required_argument, NULL, 'g'},
{"outfile", required_argument, NULL, 'o'},
{"ticket", required_argument, NULL, 't'},
{NULL, no_argument, NULL, '\0'}
};
if (argc > 1) {
LOG_ERR("Only supports one hash input file, got: %d", argc);
return false;
}

ctx.input_file = fopen(argv[0], "rb");
if (!ctx.input_file) {
LOG_ERR("Could not open input file \"%s\", error: %s",
argv[0], strerror(errno));
return false;
}

return true;
}

static bool on_option(char key, char *value) {

int opt;
bool res;
while ((opt = getopt_long(argc, argv, "H:g:o:t:", long_options, NULL))
!= -1) {
switch (opt) {
case 'H':
res = get_hierarchy_value(optarg, &ctx->hierarchyValue);
if (!res) {
return false;
}
break;
case 'g':
ctx->halg = tpm2_alg_util_from_optarg(optarg);
if (ctx->halg == TPM_ALG_ERROR) {
showArgError(optarg, argv[0]);
return false;
}
break;
case 'o':
ctx->outHashFilePath = optarg;
break;
case 't':
ctx->outTicketFilePath = optarg;
break;
case ':':
LOG_ERR("Argument %c needs a value!", optopt);
return false;
case '?':
LOG_ERR("Unknown Argument: %c", optopt);
switch (key) {
case 'H':
res = get_hierarchy_value(value, &ctx.hierarchyValue);
if (!res) {
return false;
default:
LOG_ERR("?? getopt returned character code 0%o ??", opt);
}
break;
case 'g':
ctx.halg = tpm2_alg_util_from_optarg(value);
if (ctx.halg == TPM_ALG_ERROR) {
return false;
}
break;
case 'o':
ctx.outHashFilePath = value;
break;
case 't':
ctx.outTicketFilePath = value;
break;
}

int cnt = argc - optind;
if (cnt == 0) {
return true;
}
return true;
}

if (cnt > 1) {
LOG_ERR("Only supports one hash input file, got: %d", cnt);
return false;
}
bool tpm2_tool_onstart(tpm2_options **opts) {

ctx->input_file = fopen(argv[optind], "rb");
if (!ctx->input_file) {
LOG_ERR("Could not open input file \"%s\", error: %s",
argv[optind], strerror(errno));
return false;
}
static struct option topts[] = {

This comment has been minimized.

Copy link
@martinezjavier

martinezjavier Sep 1, 2017

Contributor

@williamcroberts why this is a static variable? Instead I would change it to const struct option topts[]

This comment has been minimized.

Copy link
@williamcroberts

williamcroberts Sep 4, 2017

Author Member

read only variable that doesn't really need to be allocated on each stack, although I'm not sure what the compiler is doing with it.

{"hierachy", required_argument, NULL, 'H'},
{"halg", required_argument, NULL, 'g'},
{"outfile", required_argument, NULL, 'o'},
{"ticket", required_argument, NULL, 't'},
};

return true;
/* set up non-static defaults here */
ctx.input_file = stdin;

*opts = tpm2_options_new("H:g:o:t:", ARRAY_LEN(topts), topts, on_option, on_args);

return *opts != NULL;
}

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

/* opts is unused, avoid compiler warning */
(void)opts;
(void)envp;
UNUSED(flags);
ctx.sapi_context = sapi_context;

int rc = 1;
tpm_hash_ctx ctx = {
.outHashFilePath = NULL,
.outTicketFilePath = NULL,
.input_file = stdin,
.hierarchyValue = TPM_RH_NULL,
.halg = TPM_ALG_SHA1,
.sapi_context = sapi_context,
};

bool res = init(argc, argv, &ctx);
if (!res) {
goto out;
}

res = hash_and_save(&ctx);
bool res = hash_and_save();
if (!res) {
goto out;
}
Expand Down
10 changes: 5 additions & 5 deletions tools/tpm2_hmac.c
Expand Up @@ -39,13 +39,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_hmac_ctx tpm_hmac_ctx;
struct tpm_hmac_ctx {
Expand Down Expand Up @@ -180,11 +180,11 @@ static bool do_hmac_and_output(tpm_hmac_ctx *ctx) {

if (hmac_out.t.size) {
UINT16 i;
TOOL_OUTPUT("hmac(%s):", tpm2_alg_util_algtostr(ctx->algorithm));
tpm2_tool_output("hmac(%s):", tpm2_alg_util_algtostr(ctx->algorithm));
for (i = 0; i < hmac_out.t.size; i++) {
TOOL_OUTPUT("%02x", hmac_out.t.buffer[i]);
tpm2_tool_output("%02x", hmac_out.t.buffer[i]);
}
TOOL_OUTPUT("\n");
tpm2_tool_output("\n");
}

if (ctx->hmac_output_file_path) {
Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_listpersistent.c
Expand Up @@ -40,9 +40,9 @@

#include <sapi/tpm20.h>

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

int readPublic(TSS2_SYS_CONTEXT *sapi_context,
Expand Down
12 changes: 6 additions & 6 deletions tools/tpm2_load.c
Expand Up @@ -41,12 +41,12 @@

#include <sapi/tpm20.h>

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

TPM_HANDLE handle2048rsa;
TPMS_AUTH_COMMAND sessionData = {
Expand Down Expand Up @@ -94,7 +94,7 @@ load (TSS2_SYS_CONTEXT *sapi_context,
LOG_ERR("\nLoad Object Failed ! ErrorCode: 0x%0x\n",rval);
return -1;
}
TOOL_OUTPUT("\nLoad succ.\nLoadedHandle: 0x%08x\n\n",handle2048rsa);
tpm2_tool_output("\nLoad succ.\nLoadedHandle: 0x%08x\n\n",handle2048rsa);

/* TODO fix serialization */
if(!files_save_bytes_to_file(outFileName, (UINT8 *)&nameExt, sizeof(nameExt)))
Expand Down Expand Up @@ -159,7 +159,7 @@ execute_tool (int argc,
{
return 1;
}
TOOL_OUTPUT("\nparentHandle: 0x%x\n\n",parentHandle);
tpm2_tool_output("\nparentHandle: 0x%x\n\n",parentHandle);
H_flag = 1;
break;
case 'P': {
Expand Down Expand Up @@ -200,7 +200,7 @@ execute_tool (int argc,
{
return 1;
}
TOOL_OUTPUT("contextParentFile = %s\n", contextParentFilePath);
tpm2_tool_output("contextParentFile = %s\n", contextParentFilePath);
c_flag = 1;
break;
case 'C':
Expand All @@ -209,7 +209,7 @@ execute_tool (int argc,
{
return 1;
}
TOOL_OUTPUT("contextFile = %s\n", contextFile);
tpm2_tool_output("contextFile = %s\n", contextFile);
C_flag = 1;
break;
case 'S':
Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_loadexternal.c
Expand Up @@ -38,10 +38,10 @@
#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_loadexternal_ctx tpm_loadexternal_ctx;
Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_makecredential.c
Expand Up @@ -39,10 +39,10 @@

#include <sapi/tpm20.h>

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

#define tpm_makecred_ctx_empty_init { \
Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_nvdefine.c
Expand Up @@ -38,12 +38,12 @@

#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_nv_util.h"
#include "tpm2_tool.h"
#include "tpm2_util.h"

typedef struct tpm_nvdefine_ctx tpm_nvdefine_ctx;
Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_nvlist.c
Expand Up @@ -35,11 +35,11 @@

#include <sapi/tpm20.h>

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

static void print_nv_public(TPM2B_NV_PUBLIC *nv_public) {

Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_nvread.c
Expand Up @@ -38,11 +38,11 @@

#include <sapi/tpm20.h>

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

typedef struct tpm_nvread_ctx tpm_nvread_ctx;
Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_nvreadlock.c
Expand Up @@ -39,10 +39,10 @@

#include <sapi/tpm20.h>

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

typedef struct tpm_nvreadlock_ctx tpm_nvreadlock_ctx;
Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_nvrelease.c
Expand Up @@ -37,10 +37,10 @@

#include <sapi/tpm20.h>

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

typedef struct tpm_nvrelease_ctx tpm_nvrelease_ctx;
Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_nvwrite.c
Expand Up @@ -39,11 +39,11 @@

#include <sapi/tpm20.h>

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

typedef struct tpm_nvwrite_ctx tpm_nvwrite_ctx;
Expand Down
10 changes: 5 additions & 5 deletions tools/tpm2_pcrevent.c
Expand Up @@ -39,12 +39,12 @@

#include <sapi/tpm20.h>

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

typedef struct tpm_pcrevent_ctx tpm_pcrevent_ctx;
Expand Down Expand Up @@ -201,7 +201,7 @@ static bool do_hmac_and_output(tpm_pcrevent_ctx *ctx) {
for (i = 0; i < digests.count; i++) {
TPMT_HA *d = &digests.digests[i];

TOOL_OUTPUT("%s:", tpm2_alg_util_algtostr(d->hashAlg));
tpm2_tool_output("%s:", tpm2_alg_util_algtostr(d->hashAlg));

BYTE *bytes;
size_t size;
Expand Down Expand Up @@ -238,10 +238,10 @@ static bool do_hmac_and_output(tpm_pcrevent_ctx *ctx) {

size_t j;
for (j = 0; j < size; j++) {
TOOL_OUTPUT("%02x", bytes[j]);
tpm2_tool_output("%02x", bytes[j]);
}

TOOL_OUTPUT("\n");
tpm2_tool_output("\n");

}

Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_pcrextend.c
Expand Up @@ -33,10 +33,10 @@

#include <sapi/tpm20.h>

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

typedef struct tpm_pcr_extend_ctx tpm_pcr_extend_ctx;
Expand Down
22 changes: 11 additions & 11 deletions tools/tpm2_pcrlist.c
Expand Up @@ -38,12 +38,12 @@
#include <getopt.h>
#include <sapi/tpm20.h>

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

typedef struct tpm2_algorithm tpm2_algorithm;
struct tpm2_algorithm {
Expand Down Expand Up @@ -243,10 +243,10 @@ static bool show_pcr_values(listpcr_context *context) {
context->pcr_selections.pcrSelections[i].hash);

if (context->format.yaml) {
TOOL_OUTPUT("%s :\n", alg_name);
tpm2_tool_output("%s :\n", alg_name);

} else {
TOOL_OUTPUT("\nBank/Algorithm: %s(0x%04x)\n", alg_name,
tpm2_tool_output("\nBank/Algorithm: %s(0x%04x)\n", alg_name,
context->pcr_selections.pcrSelections[i].hash);
}

Expand All @@ -262,15 +262,15 @@ static bool show_pcr_values(listpcr_context *context) {
}

if (context->format.yaml) {
TOOL_OUTPUT(" %-2d : ", pcr_id);
tpm2_tool_output(" %-2d : ", pcr_id);
} else {
TOOL_OUTPUT("PCR_%02d:", pcr_id);
tpm2_tool_output("PCR_%02d:", pcr_id);
}
int k;
for (k = 0; k < context->pcrs.pcr_values[vi].digests[di].t.size; k++) {
TOOL_OUTPUT("%02x", context->pcrs.pcr_values[vi].digests[di].t.buffer[k]);
tpm2_tool_output("%02x", context->pcrs.pcr_values[vi].digests[di].t.buffer[k]);
}
TOOL_OUTPUT("\n");
tpm2_tool_output("\n");

if (context->output_file != NULL
&& fwrite(context->pcrs.pcr_values[vi].digests[di].t.buffer,
Expand Down Expand Up @@ -351,13 +351,13 @@ static bool get_banks(listpcr_context *context) {

static void show_banks(tpm2_algorithm *g_banks) {

TOOL_OUTPUT("Supported Bank/Algorithm:");
tpm2_tool_output("Supported Bank/Algorithm:");
int i;
for (i = 0; i < g_banks->count; i++) {
const char *alg_name = tpm2_alg_util_algtostr(g_banks->alg[i]);
TOOL_OUTPUT(" %s(0x%04x)", alg_name, g_banks->alg[i]);
tpm2_tool_output(" %s(0x%04x)", alg_name, g_banks->alg[i]);
}
TOOL_OUTPUT("\n");
tpm2_tool_output("\n");
}

static format_flags get_format(const char *optarg) {
Expand Down
2 changes: 1 addition & 1 deletion tools/tpm2_quote.c
Expand Up @@ -46,9 +46,9 @@
#include "tpm2_util.h"
#include "files.h"
#include "log.h"
#include "main.h"
#include "pcr.h"
#include "tpm2_alg_util.h"
#include "tpm2_tool.h"

typedef struct {
int size;
Expand Down
2 changes: 1 addition & 1 deletion tools/tpm2_rc_decode.c
Expand Up @@ -34,7 +34,7 @@

#include <sapi/tpm20.h>

#include "options.h"
#include "tpm2_options.h"
#include "log.h"
#include "rc-decode.h"

Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_readpublic.c
Expand Up @@ -38,10 +38,10 @@
#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_readpub_ctx tpm_readpub_ctx;
Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_rsadecrypt.c
Expand Up @@ -38,11 +38,11 @@
#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_tool.h"
#include "tpm2_util.h"

typedef struct tpm_rsadecrypt_ctx tpm_rsadecrypt_ctx;
Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_rsaencrypt.c
Expand Up @@ -38,10 +38,10 @@
#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_rsaencrypt_ctx tpm_rsaencrypt_ctx;
Expand Down
2 changes: 1 addition & 1 deletion tools/tpm2_send_command.c
Expand Up @@ -40,8 +40,8 @@

#include "tpm2_header.h"
#include "files.h"
#include "main.h"
#include "log.h"
#include "tpm2_tool.h"

typedef struct tpm2_send_command_ctx tpm2_send_command_ctx;
struct tpm2_send_command_ctx {
Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_sign.c
Expand Up @@ -38,14 +38,14 @@
#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_hash.h"
#include "tpm2_alg_util.h"
#include "tpm2_tool.h"

typedef struct tpm_sign_ctx tpm_sign_ctx;
struct tpm_sign_ctx {
Expand Down
2 changes: 1 addition & 1 deletion tools/tpm2_startup.c
Expand Up @@ -33,8 +33,8 @@
#include <getopt.h>
#include <stdlib.h>

#include "main.h"
#include "log.h"
#include "tpm2_tool.h"

/*
* Both the Microsoft and IBM TPM2 simulators require some specific setup
Expand Down
4 changes: 2 additions & 2 deletions tools/tpm2_takeownership.c
Expand Up @@ -41,10 +41,10 @@

#include <sapi/tpm20.h>

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

typedef struct password password;
Expand Down
156 changes: 156 additions & 0 deletions tools/tpm2_tool.c
@@ -0,0 +1,156 @@
/*
* 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 <stdbool.h>

#include <unistd.h>

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

bool output_enabled = true;

static void tcti_teardown (TSS2_TCTI_CONTEXT *tcti_context) {

tss2_tcti_finalize (tcti_context);
free (tcti_context);
}

static void sapi_teardown (TSS2_SYS_CONTEXT *sapi_context) {

if (sapi_context == NULL)
return;
Tss2_Sys_Finalize (sapi_context);
free (sapi_context);
}

static void sapi_teardown_full (TSS2_SYS_CONTEXT *sapi_context) {

TSS2_TCTI_CONTEXT *tcti_context = NULL;
TSS2_RC rc;

rc = Tss2_Sys_GetTctiContext (sapi_context, &tcti_context);
if (rc != TSS2_RC_SUCCESS)
return;
sapi_teardown (sapi_context);
tcti_teardown (tcti_context);
}

static TSS2_SYS_CONTEXT* sapi_ctx_init(TSS2_TCTI_CONTEXT *tcti_ctx) {

TSS2_ABI_VERSION abi_version = {
.tssCreator = TSSWG_INTEROP,
.tssFamily = TSS_SAPI_FIRST_FAMILY,
.tssLevel = TSS_SAPI_FIRST_LEVEL,
.tssVersion = TSS_SAPI_FIRST_VERSION,
};

size_t size = Tss2_Sys_GetContextSize(0);
TSS2_SYS_CONTEXT *sapi_ctx = (TSS2_SYS_CONTEXT*) calloc(1, size);
if (sapi_ctx == NULL) {
LOG_ERR("Failed to allocate 0x%zx bytes for the SAPI context\n",
size);
return NULL;
}

TSS2_RC rc = Tss2_Sys_Initialize(sapi_ctx, size, tcti_ctx, &abi_version);
if (rc != TSS2_RC_SUCCESS) {
LOG_ERR("Failed to initialize SAPI context: 0x%x\n", rc);
free(sapi_ctx);
return NULL;
}

return sapi_ctx;
}

/*
* This program is a template for TPM2 tools that use the SAPI. It does
* nothing more than parsing command line options that allow the caller to
* specify which TCTI to use for the test.
*/
int main(int argc, char *argv[], char *envp[]) {

int ret = 1;

tpm2_options *tool_opts = NULL;
if (tpm2_tool_onstart) {
bool res = tpm2_tool_onstart(&tool_opts);
if (!res) {
LOG_ERR("retrieving tool options");
return 1;
}
}

tpm2_option_flags flags = { .all = 0 };
TSS2_TCTI_CONTEXT *tcti;
tpm2_option_code rc = tpm2_handle_options(argc, argv, envp, tool_opts, &flags, &tcti);
if (rc != tpm2_option_code_continue) {
ret = rc == tpm2_option_code_err ? 1 : 0;
goto free_opts;
}

/*
* We don't want a cyclic dependency between tools/options. Resolving those
* works well on linux/elf based systems, but darwin and windows tend to
* fall flat on there face. This is why we set quiet mode outside of
* option and argument life-cycle. Thus TOOL_OUTPUT is only guaranteed
* to respect quiet from here on out (onrun and onexit).
*/
if (flags.quiet) {
output_enabled = false;
}

/* figure out the tcti */

/* TODO SAPI INIT */
TSS2_SYS_CONTEXT *sapi_context = sapi_ctx_init(tcti);

/*
* Call the specific tool, all tools implement this function instead of
* 'main'.
*/
ret = tpm2_tool_onrun(sapi_context, flags) ? 1 : 0;
/*
* Cleanup contexts & memory allocated for the modified argument vector
* passed to execute_tool.
*/
sapi_teardown_full(sapi_context);

free_opts:
tpm2_options_free(tool_opts);

if (tpm2_tool_onexit) {
tpm2_tool_onexit();
}

exit(ret);
}