/*
 * tpm_bios  --  
 *
 * Authors: Ken Goldman <kgoldman@us.ibm.com>
 *          Stefan Berger <stefanb@us.ibm.com>
 *
 * (c) Copyright IBM Corporation 2014.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 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.
 *
 * Neither the names of the IBM 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 <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/un.h>
#include <getopt.h>
#include <signal.h>

#include "sys_dependencies.h"
#include "swtpm.h"
#include "tpm_bios.h"

/*
 * durations of the commands
 * On slow machines with much concurrency short timeouts may result in
 * errors; so we scale them up by 10.
 */
#define TPM_DURATION_SHORT   (2 * 10) /* seconds */
#define TPM_DURATION_MEDIUM (20 * 10) /* seconds */
#define TPM_DURATION_LONG   (60 * 10) /* seconds */

#define MIN(A, B) ((A) < (B) ? (A) : (B))

#define DEFAULT_TCP_PORT 6545

static char *tpm_device; /* e.g., /dev/tpm0 */

static char *tcp_hostname;
static unsigned int tcp_port = DEFAULT_TCP_PORT;

static char *unix_path;

static int parse_tcp_optarg(char *optarg, char **tcp_hostname,
                            unsigned int *tcp_port)
{
	char *pos = strrchr(optarg, ':');
	int n;

	*tcp_port = DEFAULT_TCP_PORT;

	if (!pos) {
		/* <server> */
		*tcp_hostname = strdup(optarg);
		if (*tcp_hostname == NULL) {
			fprintf(stderr, "Out of memory.\n");
			return -1;
		}
		return 0;
	} else if (pos == optarg) {
		if (strlen(&pos[1]) != 0) {
			/* :<port>  (not just ':') */
			n = sscanf(&pos[1], "%u", tcp_port);
			if (n != 1) {
				fprintf(stderr, "Invalid port '%s'\n", &pos[1]);
				return -1;
			}
			if (*tcp_port >= 65536) {
				fprintf(stderr, "Port '%s' outside valid range.\n",
					&optarg[1]);
				return -1;
			}
		}

		*tcp_hostname = strdup("127.0.0.1");
		if (*tcp_hostname == NULL) {
			fprintf(stderr, "Out of memory.\n");
			return -1;
		}
	} else {
		/* <server>:<port> */
		n = sscanf(&pos[1], "%u", tcp_port);
		if (n != 1) {
			fprintf(stderr, "Invalid port '%s'\n", &pos[1]);
			return -1;
		}
		if (*tcp_port >= 65536) {
			fprintf(stderr, "Port '%s' outside valid range.\n",
				&optarg[1]);
			return -1;
		}

		*tcp_hostname = strndup(optarg, pos - optarg);
		if (*tcp_hostname == NULL) {
			fprintf(stderr, "Out of memory.\n");
			return -1;
		}
	}
	return 0;
}

static int open_connection(char *devname, char *tcp_device_hostname,
                           unsigned int tcp_device_port, const char *unix_path)
{
	int fd = -1;
	char *tcp_device_port_string = NULL;

	if (devname)
		goto use_device;

	if (tcp_device_hostname)
		goto use_tcp;

	if (unix_path) {
		struct sockaddr_un addr;
		size_t unix_path_len = strlen(unix_path) + 1;

		if (unix_path_len > sizeof(addr.sun_path)) {
			fprintf(stderr, "Socket path is too long.\n");
			return -1;
		}

		fd = socket(AF_UNIX, SOCK_STREAM, 0);
		if (fd > 0) {
			addr.sun_family = AF_UNIX;
			strncpy(addr.sun_path, unix_path, unix_path_len);

			if (connect(fd,
				    (struct sockaddr*)&addr, sizeof(addr)) < 0) {
				close(fd);
				fd = -1;
			}
		}

		if (fd < 0) {
			fprintf(stderr, "Could not connect using UnixIO socket.\n");
		}
		return fd;
	}

	if (getenv("TCSD_USE_TCP_DEVICE")) {
		struct addrinfo hints;
		struct addrinfo *ais = NULL, *ai;
		char portstr[10];
		int err;

		if ((tcp_device_hostname = getenv("TCSD_TCP_DEVICE_HOSTNAME")) == NULL)
			tcp_device_hostname = "localhost";
		if ((tcp_device_port_string = getenv("TCSD_TCP_DEVICE_PORT")) != NULL)
			tcp_device_port = atoi(tcp_device_port_string);
		else
			tcp_device_port = DEFAULT_TCP_PORT;

use_tcp:
		memset(&hints, 0, sizeof(hints));
		hints.ai_family = AF_UNSPEC;
		hints.ai_socktype = SOCK_STREAM;

		snprintf(portstr, sizeof(portstr), "%u", tcp_device_port);

		err = getaddrinfo(tcp_device_hostname, portstr, &hints, &ais);
		if (err != 0) {
			fprintf(stderr, "getaddrinfo failed on host '%s': %s\n",
			        tcp_device_hostname, gai_strerror(err));
			return -1;
		}

		for (ai = ais; ai != NULL; ai = ai->ai_next) {
			fd = socket(ai->ai_family, ai->ai_socktype, 0);
			if (fd < 0)
				continue;

			if (connect(fd, (struct sockaddr *)ai->ai_addr,
			            ai->ai_addrlen) == 0)
				break;

			close(fd);
			fd = -1;
		}
		freeaddrinfo(ais);

		if (fd < 0) {
			fprintf(stderr, "Could not connect using TCP socket.\n");
		}
	} else {
use_device:
		if (!devname)
			devname = getenv("TPM_DEVICE");
		if (!devname)
			devname = "/dev/tpm0";

		fd = open(devname, O_RDWR);
		if (fd < 0) {
			fprintf(stderr, "Unable to open device '%s'.\n", devname );
		}
	}

	return fd;
}


static int talk(const void *cmd, size_t count, int *tpm_errcode,
		unsigned int to_seconds,
		struct tpm_resp_header *res, size_t res_size)
{
	ssize_t len;
	size_t pkt_len;
	int rc = -1;
	int fd, n;
	unsigned char buffer[1024];
	struct timeval timeout = {
		.tv_sec = to_seconds,
		.tv_usec = 0,
	};
	fd_set rfds;
	struct tpm_resp_header *hdr;

	fd = open_connection(tpm_device, tcp_hostname, tcp_port, unix_path);
	if (fd < 0) {
		goto err_exit;
	}

	len = write(fd, cmd, count);
	if (len < 0 || (size_t)len != count) {
		fprintf(stderr, "Write to file descriptor failed.\n");
		goto err_close_fd;
	}

	FD_ZERO(&rfds);
	FD_SET(fd, &rfds);

	n = select(fd + 1, &rfds, NULL, NULL, &timeout);
	if (n == 0) {
		fprintf(stderr, "TPM did not respond after %u seconds.\n",
			to_seconds);
		goto err_close_fd;
	} else if (n < 0) {
		fprintf(stderr, "Error on select call: %s\n", strerror(errno));
		goto err_close_fd;
	}

	len = read(fd, buffer, sizeof(buffer));
	if (len < 0) {
		fprintf(stderr, "Read from file descriptor failed.\n");
		goto err_close_fd;
	}

	if (len < 10) {
		fprintf(stderr, "Returned packet is too short.\n");
		goto err_close_fd;
	}

	hdr = (struct tpm_resp_header *)buffer;
	pkt_len = be32toh(hdr->length);
	if ((unsigned int)len != pkt_len) {
		fprintf(stderr, "Malformed response.\n");
		goto err_close_fd;
	}

	if (res)
		memcpy(res, buffer, MIN(pkt_len, res_size));

	*tpm_errcode = be32toh(hdr->result);

	rc = 0;

err_close_fd:
	close(fd);

err_exit:
	return rc;
}

static int TPM_Startup(unsigned char parm, int *tpm_errcode)
{
	struct tpm_startup tss  = {
		.hdr = {
			.tag = htobe16(TPM_TAG_RQU_COMMAND),
			.length = htobe32(sizeof(tss)),
			.ordinal = htobe32(TPM_ORD_Startup),
		},
		.startup_type = htobe16(parm),
	};

	return talk(&tss, sizeof(tss), tpm_errcode, TPM_DURATION_SHORT,
		    NULL, 0);
}

static int TSC_PhysicalPresence(unsigned short physical_presence,
				int *tpm_errcode)
{
	struct tsc_physical_presence tpp = {
		.hdr = {
			.tag = htobe16(TPM_TAG_RQU_COMMAND),
			.length = htobe32(sizeof(tpp)),
			.ordinal = htobe32(TPM_ORD_PhysicalPresence),
		},
		.physical_presence = htobe16(physical_presence),
	};

	return talk(&tpp, sizeof(tpp), tpm_errcode, TPM_DURATION_SHORT,
		    NULL, 0);
}

static int TPM_GetCapability_Subcap(uint32_t cap, uint32_t subcap,
				    struct tpm_resp_header *res, size_t res_size,
				    int *tpm_errcode)
{
	struct tpm_get_capability_subcap tgc = {
		.hdr = {
			.tag = htobe16(TPM_TAG_RQU_COMMAND),
			.length = htobe32(sizeof(tgc)),
			.ordinal = htobe32(TPM_ORD_GetCapability),
		},
		.cap = htobe32(cap),
		.subcap_size = htobe32(sizeof(tgc.subcap)),
		.subcap = htobe32(subcap),
	};

	return talk(&tgc, sizeof(tgc), tpm_errcode, TPM_DURATION_SHORT,
		    res, res_size);
}

static int TPM_PhysicalEnable(int *tpm_errcode)
{
	struct tpm_physical_enable tpe = {
		.hdr = {
			.tag = htobe16(TPM_TAG_RQU_COMMAND),
			.length = htobe32(sizeof(tpe)),
			.ordinal = htobe32(TPM_ORD_PhysicalEnable),
		},
	};

	return talk(&tpe, sizeof(tpe), tpm_errcode, TPM_DURATION_SHORT,
		    NULL, 0);
}

static int TPM_PhysicalSetDeactivated(unsigned char parm, int *tpm_errcode)
{
	struct tpm_physical_set_deactivated tpsd = {
		.hdr = {
			.tag = htobe16(TPM_TAG_RQU_COMMAND),
			.length = htobe32(sizeof(tpsd)),
			.ordinal = htobe32(TPM_ORD_PhysicalSetDeactivated),
		},
		.state = parm,
	};

	return talk(&tpsd, sizeof(tpsd), tpm_errcode, TPM_DURATION_SHORT,
		    NULL, 0);
}

static int TPM_ContinueSelfTest(int *tpm_errcode)
{
	struct tpm_continue_selftest tcs = {
		.hdr = {
			.tag = htobe16(TPM_TAG_RQU_COMMAND),
			.length = htobe32(sizeof(tcs)),
			.ordinal = htobe32(TPM_ORD_ContinueSelfTest),
		},
	};

	return talk(&tcs, sizeof(tcs), tpm_errcode, TPM_DURATION_LONG,
		    NULL, 0);
}

static int TPM2_Startup(unsigned short startup_type, int *tpm_errcode)
{
	struct tpm2_startup ts = {
		.hdr = {
			.tag = htobe16(TPM2_ST_NO_SESSIONS),
			.length = htobe32(sizeof(ts)),
			.ordinal = htobe32(TPM2_CC_Startup),
		},
		.startup_type = htobe16(startup_type),
	};

	return talk(&ts, sizeof(ts), tpm_errcode,
		    TPM_DURATION_SHORT, NULL, 0);
}

static int TPM2_IncrementalSelfTest(int *tpm_errcode)
{
	struct tpm2_incremental_selftest ts = {
		.hdr = {
			.tag = htobe16(TPM2_ST_NO_SESSIONS),
			.length = htobe32(sizeof(ts)),
			.ordinal = htobe32(TPM2_CC_IncrementalSelfTest),
		},
		.to_test = {
			.num_entries = htobe32(1),
			.algids = {
				htobe16(TPM2_ALG_SHA1),
			},
		},
	};

	return talk(&ts, sizeof(ts), tpm_errcode,
		    TPM_DURATION_SHORT, NULL, 0);
}

static int TPM2_HierarchyChangeAuth(int *tpm_errcode)
{
	struct tpm2_hierarchy_change_auth thca = {
		.hdr = {
			.tag = htobe16(TPM2_ST_SESSIONS),
			.length = htobe32(sizeof(thca)),
			.ordinal = htobe32(TPM2_CC_HierarchyChangeAuth),
		},
		.authhandle = htobe32(TPM2_RH_PLATFORM),
		.authblock_size = htobe32(sizeof(thca.authblock)),
		.authblock = {
			.handle = htobe32(TPM2_RS_PW),
			.nonce_size = htobe16(0),
			.cont = 1,
			.password_size = htobe16(0),
		},
		.newauth = {
			.size = htobe16(sizeof(thca.newauth.buffer)),
		},
	};

	int fd = open("/dev/urandom", O_RDONLY);
	if (fd >= 0) {
		ssize_t n = read(fd, &thca.newauth.buffer,
				sizeof(thca.newauth.buffer));
		close(fd);
		if (n != sizeof(thca.newauth.buffer)) {
				printf("Read of bytes from /dev/urandom failed");
			if (n < 0)
				printf(": %s", strerror(errno));
			printf("\n");
			return -1;
		}
	} else {
		printf("Could not open /dev/urandom: %s\n", strerror(errno));
		return -1;
	}

	return talk(&thca, sizeof(thca), tpm_errcode,
		    TPM_DURATION_SHORT, NULL, 0);
}

static int tpm12_bios(int do_more, int contselftest, unsigned char startupparm,
		      int unassert_pp, int ensure_activated)
{
	int ret = 0;
	int tpm_errcode = 0;
	int tpm_error = 0;
	unsigned short physical_presence;
	struct tpm_get_capability_permflags_res perm_flags;

	if (ret == 0) {
		if (0xff != startupparm) {
			ret = TPM_Startup(startupparm, &tpm_errcode);
			if (tpm_errcode != 0) {
				tpm_error = 1;
				fprintf(stderr, "TPM_Startup(0x%02x) returned "
					"error code 0x%08x\n",
					startupparm, tpm_errcode);
			}
		}
	}

	/* Sends the TSC_PhysicalPresence command to turn on physicalPresenceCMDEnable */
	if ((ret == 0) && do_more) {
		physical_presence = TPM_PHYSICAL_PRESENCE_CMD_ENABLE;
		ret = TSC_PhysicalPresence(physical_presence, &tpm_errcode);
		if (tpm_errcode != 0) {
			tpm_error = 1;
			fprintf(stderr, "TSC_PhysicalPresence(CMD_ENABLE) "
				"returned error code 0x%08x\n", tpm_errcode);
		}
	}

	/* Sends the TSC_PhysicalPresence command to turn on physicalPresence */
	if ((ret == 0) && do_more) {
		physical_presence = TPM_PHYSICAL_PRESENCE_PRESENT;
		ret = TSC_PhysicalPresence(physical_presence, &tpm_errcode);
		if (tpm_errcode != 0) {
			tpm_error = 1;
			fprintf(stderr, "TSC_PhysicalPresence(PRESENT) "
				"returned error code 0x%08x\n", tpm_errcode);
		}
	}
	/* Determine the permanent flags */
	if ((ret == 0) && do_more && ensure_activated) {
		ret = TPM_GetCapability_Subcap(TPM_CAP_FLAG, TPM_CAP_FLAG_PERMANENT,
					       &perm_flags.hdr, sizeof(perm_flags),
					       &tpm_errcode);
		if (tpm_errcode != 0) {
			tpm_error = 1;
			fprintf(stderr, "TPM_GetCapability() returned error "
				"code 0x%08x\n", tpm_errcode);
		}
	}
	/* Sends the TPM_Process_PhysicalEnable command to clear disabled */
	if ((ret == 0) && do_more) {
		ret = TPM_PhysicalEnable(&tpm_errcode);
		if (tpm_errcode != 0) {
			tpm_error = 1;
			fprintf(stderr, "TPM_PhysicalEnable returned error "
				"code 0x%08x\n", tpm_errcode);
		}
	}
	/* Sends the TPM_Process_PhysicalSetDeactivated command to clear deactivated */
	if ((ret == 0) && do_more) {
		ret = TPM_PhysicalSetDeactivated(0, &tpm_errcode);
		if (tpm_errcode != 0) {
			tpm_error = 1;
			fprintf(stderr, "TPM_PhysicalSetDeactivated returned "
				"error code 0x%08x\n", tpm_errcode);
		}
		if (ensure_activated) {
			/* activation will require resetting the TPM */
			if (perm_flags.flags[TPM_PERM_FLAG_DEACTIVATED_IDX]) {
				ret = 0x81;
				printf("TPM requires a reset\n");
			}
		}
	}

	if ((ret == 0) && contselftest) {
		ret = TPM_ContinueSelfTest(&tpm_errcode);
		if (tpm_errcode != 0) {
			tpm_error = 1;
			fprintf(stderr, "TPM_ContinueSelfTest returned error "
				"code 0x%08x\n", tpm_errcode);
		}
	}

	/* Sends the TSC_PhysicalPresence command to turn on physicalPresenceCMDEnable */
	if ((ret == 0) && unassert_pp) {
		physical_presence = TPM_PHYSICAL_PRESENCE_CMD_ENABLE;
		ret = TSC_PhysicalPresence(physical_presence, &tpm_errcode);
		if (tpm_errcode != 0) {
			tpm_error = 1;
			fprintf(stderr,
				"TSC_PhysicalPresence(CMD_ENABLE) returned "
				"error code 0x%08x\n", tpm_errcode);
		}
	}

	/* Sends the TSC_PhysicalPresence command to unassert physical presence and lock it */
	if ((ret == 0) && unassert_pp) {
		physical_presence = TPM_PHYSICAL_PRESENCE_NOTPRESENT |
				    TPM_PHYSICAL_PRESENCE_LOCK;
		ret = TSC_PhysicalPresence(physical_presence, &tpm_errcode);
		if (tpm_errcode != 0) {
			tpm_error = 1;
			fprintf(stderr, "TSC_PhysicalPresence(NOT_PRESENT|LOCK) "
				"returned error code 0x%08x\n", tpm_errcode);
		}
	}

	if (!ret && tpm_error)
		ret = 0x80;

	return ret;
}

static int tpm2_bios(int contselftest, unsigned char startupparm,
		     int set_password)
{
	int ret = 0;
	int tpm_errcode = 0;
	int tpm_error = 0;

	if (ret == 0) {
		if (0xff != startupparm) {
			ret = TPM2_Startup(startupparm, &tpm_errcode);
			if (tpm_errcode != 0) {
				tpm_error = 1;
				printf("TPM2_Startup returned error code "
				       "0x%08x\n", tpm_errcode);
			}
		}
	}

	if ((ret == 0) && contselftest) {
		ret = TPM2_IncrementalSelfTest(&tpm_errcode);
		if (tpm_errcode != 0) {
			tpm_error = 1;
			printf("TPM2_ImcrementalSelfTest returned error "
			       "code 0x%08x\n", tpm_errcode);
		}
	}

	if ((ret == 0) && set_password) {
		ret = TPM2_HierarchyChangeAuth(&tpm_errcode);
		if (tpm_errcode != 0) {
			tpm_error = 1;
			printf("TPM2_HierarchyChangeAuth returned error "
			       "code 0x%08x\n", tpm_errcode);
		}
	}

	if (!ret && tpm_error)
		ret = 0x80;

	return ret;
}

static void versioninfo(void)
{
	printf(
"TPM emulator BIOS emulator version %d.%d.%d, Copyright (c) 2015 IBM Corp.\n"
,SWTPM_VER_MAJOR, SWTPM_VER_MINOR, SWTPM_VER_MICRO);
}

static void print_usage(const char *prgname)
{
	versioninfo();
	printf(
"\n"
"%s [options]\n"
"\n"
"Runs TPM_Startup (unless -n), then (unless -o) sets PP, enable, activate \n"
"and finally (using -u) gives up physical presence (PP)\n"
"\n"
"The following options are supported:\n"
"\t--tpm-device <device>  use the given device; default is /dev/tpm0\n"
"\t--tcp [<host>]:[<prt>] connect to TPM on given host and port;\n"
"\t                       default host is 127.0.0.1, default port is %u\n"
"\t--unix <path>          connect to TPM using UnixIO socket\n"
"\t--tpm2                 initialize a TPM2\n"
"\t-c                     startup clear (default)\n"
"\t-s                     startup state\n"
"\t-d                     startup deactivate (no effect on TPM2)\n"
"\t-n                     no startup\n"
"\t-o                     startup only\n"
"\t-cs                    run TPM_ContinueSelfTest on TPM1.2\n"
"\t                       run TPM2_IncrementalSelfTest on TPM2\n"
"\t-ea                    make sure that the TPM 1.2 is activated;\n"
"\t                       terminate with exit code 129 if the TPM\n"
"\t                       needs to be reset\n"
"\t-u                     give up physical presence\n"
"\t                       on TPM 2 set the platform hierarchy to a\n"
"\t                       random password\n"
"\t-v                     display version and exit\n"
"\t-h                     display this help screen and exit\n"
, prgname, DEFAULT_TCP_PORT);
}

int main(int argc, char *argv[])
{
	int   ret = 0;
	int   do_more = 1;
	int   ensure_activated = 0;
	int   contselftest = 0;
	unsigned char  startupparm = 0x1;      /* parameter for TPM_Startup(); */
	unsigned char  startupparm_tpm2 = 0x00;
	int   unassert_pp = 0;
	int   tpm2 = 0;
	static struct option long_options[] = {
		{"tpm-device", required_argument, NULL, 'D'},
		{"tcp", required_argument, NULL, 'T'},
		{"unix", required_argument, NULL, 'U'},
		{"c", no_argument, NULL, 'c'},
		{"d", no_argument, NULL, 'd'},
		{"h", no_argument, NULL, 'h'},
		{"v", no_argument, NULL, 'v'},
		{"n", no_argument, NULL, 'n'},
		{"s", no_argument, NULL, 's'},
		{"o", no_argument, NULL, 'o'},
		{"cs", no_argument, NULL, 'C'},
		{"ea", no_argument, NULL, 'E'},
		{"u", no_argument, NULL, 'u'},
		{"tpm2", no_argument, NULL, '2'},
		{NULL, 0, NULL, 0},
	};
	int opt, option_index = 0;

#ifdef __NetBSD__
	while ((opt = getopt_long(argc, argv, "D:T:U:cdhvnsoCEu2", long_options,
				&option_index)) != -1) {
#else
	while ((opt = getopt_long_only(argc, argv, "", long_options,
				&option_index)) != -1) {
#endif
		switch (opt) {
		case 'D':
			free(tpm_device);
			tpm_device = strdup(optarg);
			if (!tpm_device) {
				fprintf(stderr, "Out of memory.");
				return EXIT_FAILURE;
			}
			break;
		case 'T':
			free(tcp_hostname);
			if (parse_tcp_optarg(optarg, &tcp_hostname, &tcp_port) < 0) {
				return EXIT_FAILURE;
			}
			break;
		case 'U':
			free(unix_path);
			unix_path = strdup(optarg);
			if (!unix_path) {
				fprintf(stderr, "Out of memory.\n");
				return EXIT_FAILURE;
			}
			break;
		case 'c':
			startupparm = TPM_ST_CLEAR;
			startupparm_tpm2 = TPM2_SU_CLEAR;
			do_more = 1;
			break;
		case 'd':
			startupparm = TPM_ST_DEACTIVATED;
			startupparm_tpm2 = 0xff;
			do_more = 0;
			break;
		case 'h':
			print_usage(argv[0]);
			return EXIT_SUCCESS;
		case 'n':
			startupparm = 0xff;
			startupparm_tpm2 = 0xff;
			do_more = 1;
			break;
		case 's':
			startupparm = TPM_ST_STATE;
			startupparm_tpm2 = TPM2_SU_STATE;
			do_more = 1;
			break;
		case 'o':
			do_more = 0;
			break;
		case 'C':
			contselftest = 1;
			break;
		case 'E':
			ensure_activated = 1;
			break;
		case 'u':
			unassert_pp = 1;
			break;
                case '2':
                        tpm2 = 1;
                        break;
		default:
			print_usage(argv[0]);
			return EXIT_FAILURE;
		}
	}

	if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
		fprintf(stderr, "Could not install signal handler for SIGPIPE.");
		return EXIT_FAILURE;
	}

	if (tpm2) {
		ret = tpm2_bios(contselftest, startupparm_tpm2,
				unassert_pp);
	} else {
		ret = tpm12_bios(do_more, contselftest, startupparm,
				 unassert_pp, ensure_activated);
	}

	return ret;
}
