/*
 * 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_SHA256),
			},
		},
	};

	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_IncrementalSelfTest 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;
}
