147e946e7SWyllys Ingersoll /*
247e946e7SWyllys Ingersoll  * CDDL HEADER START
347e946e7SWyllys Ingersoll  *
447e946e7SWyllys Ingersoll  * The contents of this file are subject to the terms of the
547e946e7SWyllys Ingersoll  * Common Development and Distribution License (the "License").
647e946e7SWyllys Ingersoll  * You may not use this file except in compliance with the License.
747e946e7SWyllys Ingersoll  *
847e946e7SWyllys Ingersoll  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
947e946e7SWyllys Ingersoll  * or http://www.opensolaris.org/os/licensing.
1047e946e7SWyllys Ingersoll  * See the License for the specific language governing permissions
1147e946e7SWyllys Ingersoll  * and limitations under the License.
1247e946e7SWyllys Ingersoll  *
1347e946e7SWyllys Ingersoll  * When distributing Covered Code, include this CDDL HEADER in each
1447e946e7SWyllys Ingersoll  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1547e946e7SWyllys Ingersoll  * If applicable, add the following below this CDDL HEADER, with the
1647e946e7SWyllys Ingersoll  * fields enclosed by brackets "[]" replaced with your own identifying
1747e946e7SWyllys Ingersoll  * information: Portions Copyright [yyyy] [name of copyright owner]
1847e946e7SWyllys Ingersoll  *
1947e946e7SWyllys Ingersoll  * CDDL HEADER END
2047e946e7SWyllys Ingersoll  */
2147e946e7SWyllys Ingersoll 
2247e946e7SWyllys Ingersoll /*
2347e946e7SWyllys Ingersoll  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
2447e946e7SWyllys Ingersoll  * Use is subject to license terms.
2547e946e7SWyllys Ingersoll  */
2647e946e7SWyllys Ingersoll 
2747e946e7SWyllys Ingersoll #include <unistd.h>
2847e946e7SWyllys Ingersoll #include <stdlib.h>
2947e946e7SWyllys Ingersoll #include <stdio.h>
3047e946e7SWyllys Ingersoll #include <strings.h>
3147e946e7SWyllys Ingersoll #include <fcntl.h>
3247e946e7SWyllys Ingersoll #include <sys/types.h>
3347e946e7SWyllys Ingersoll #include <netinet/in.h>
3447e946e7SWyllys Ingersoll #include <inttypes.h>
3547e946e7SWyllys Ingersoll #include <sha1.h>
3647e946e7SWyllys Ingersoll #include <uuid/uuid.h>
3747e946e7SWyllys Ingersoll #include <sys/stat.h>
3847e946e7SWyllys Ingersoll #include <libintl.h>
3947e946e7SWyllys Ingersoll 
4047e946e7SWyllys Ingersoll #include <tss/tss_defines.h>
4147e946e7SWyllys Ingersoll #include <tss/tspi.h>
4247e946e7SWyllys Ingersoll 
4347e946e7SWyllys Ingersoll #include "tpmadm.h"
4447e946e7SWyllys Ingersoll 
4547e946e7SWyllys Ingersoll int cmd_status(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]);
4647e946e7SWyllys Ingersoll int cmd_init(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]);
4747e946e7SWyllys Ingersoll int cmd_clear(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]);
4847e946e7SWyllys Ingersoll int cmd_auth(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]);
4947e946e7SWyllys Ingersoll int cmd_keyinfo(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]);
5047e946e7SWyllys Ingersoll int cmd_deletekey(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]);
5147e946e7SWyllys Ingersoll 
5247e946e7SWyllys Ingersoll cmdtable_t commands[] = {
536b35cb3cSRichard PALO 	{ "status", "", cmd_status },
546b35cb3cSRichard PALO 	{ "init", "", cmd_init },
556b35cb3cSRichard PALO 	{ "clear", "[owner | lock]", cmd_clear },
566b35cb3cSRichard PALO 	{ "auth", "", cmd_auth },
576b35cb3cSRichard PALO 	{ "keyinfo", "[uuid]", cmd_keyinfo },
586b35cb3cSRichard PALO 	{ "deletekey", "uuid", cmd_deletekey },
596b35cb3cSRichard PALO 	{ NULL, NULL, NULL },
6047e946e7SWyllys Ingersoll };
6147e946e7SWyllys Ingersoll 
6247e946e7SWyllys Ingersoll BYTE well_known[] = TSS_WELL_KNOWN_SECRET;
6347e946e7SWyllys Ingersoll TSS_UUID srk_uuid = TSS_UUID_SRK;
6447e946e7SWyllys Ingersoll 
6547e946e7SWyllys Ingersoll 
6647e946e7SWyllys Ingersoll /*
6747e946e7SWyllys Ingersoll  * TPM status
6847e946e7SWyllys Ingersoll  */
6947e946e7SWyllys Ingersoll 
7047e946e7SWyllys Ingersoll static int
print_tpm_version(TSS_HCONTEXT hContext,TSS_HOBJECT hTPM)7147e946e7SWyllys Ingersoll print_tpm_version(TSS_HCONTEXT hContext, TSS_HOBJECT hTPM)
7247e946e7SWyllys Ingersoll {
7347e946e7SWyllys Ingersoll 	struct {
7447e946e7SWyllys Ingersoll 		TPM_CAP_VERSION_INFO vers_info;
7547e946e7SWyllys Ingersoll 		char extra[20]; /* vendor extensions */
7647e946e7SWyllys Ingersoll 	} info;
7747e946e7SWyllys Ingersoll 
7847e946e7SWyllys Ingersoll 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_VERSION_VAL,
7947e946e7SWyllys Ingersoll 	    0, &info, sizeof (info)))
8047e946e7SWyllys Ingersoll 		return (ERR_FAIL);
8147e946e7SWyllys Ingersoll 
8247e946e7SWyllys Ingersoll 	(void) printf(gettext("TPM Version: %d.%d (%c%c%c%c Rev: %d.%d, "
8347e946e7SWyllys Ingersoll 	    "SpecLevel: %d, ErrataRev: %d)\n"),
8447e946e7SWyllys Ingersoll 	    info.vers_info.version.major,
8547e946e7SWyllys Ingersoll 	    info.vers_info.version.minor,
8647e946e7SWyllys Ingersoll 	    info.vers_info.tpmVendorID[0],
8747e946e7SWyllys Ingersoll 	    info.vers_info.tpmVendorID[1],
8847e946e7SWyllys Ingersoll 	    info.vers_info.tpmVendorID[2],
8947e946e7SWyllys Ingersoll 	    info.vers_info.tpmVendorID[3],
9047e946e7SWyllys Ingersoll 	    info.vers_info.version.revMajor,
9147e946e7SWyllys Ingersoll 	    info.vers_info.version.revMinor,
9247e946e7SWyllys Ingersoll 	    (int)ntohs(info.vers_info.specLevel),
9347e946e7SWyllys Ingersoll 	    info.vers_info.errataRev);
9447e946e7SWyllys Ingersoll 
9547e946e7SWyllys Ingersoll 	return (0);
9647e946e7SWyllys Ingersoll }
9747e946e7SWyllys Ingersoll 
9847e946e7SWyllys Ingersoll static int
tpm_is_owned(TSS_HCONTEXT hContext,TSS_HOBJECT hTPM)9947e946e7SWyllys Ingersoll tpm_is_owned(TSS_HCONTEXT hContext, TSS_HOBJECT hTPM)
10047e946e7SWyllys Ingersoll {
10147e946e7SWyllys Ingersoll 	BYTE owned;
10247e946e7SWyllys Ingersoll 
10347e946e7SWyllys Ingersoll 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY,
10447e946e7SWyllys Ingersoll 	    TSS_TPMCAP_PROP_OWNER, &owned, sizeof (owned)))
10547e946e7SWyllys Ingersoll 		return (0);
10647e946e7SWyllys Ingersoll 
10747e946e7SWyllys Ingersoll 	return (owned);
10847e946e7SWyllys Ingersoll }
10947e946e7SWyllys Ingersoll 
11047e946e7SWyllys Ingersoll static int
print_tpm_resources(TSS_HCONTEXT hContext,TSS_HOBJECT hTPM)11147e946e7SWyllys Ingersoll print_tpm_resources(TSS_HCONTEXT hContext, TSS_HOBJECT hTPM)
11247e946e7SWyllys Ingersoll {
11347e946e7SWyllys Ingersoll 	UINT32 avail, max;
11447e946e7SWyllys Ingersoll 
11547e946e7SWyllys Ingersoll 	(void) printf(gettext("TPM resources\n"));
11647e946e7SWyllys Ingersoll 
11747e946e7SWyllys Ingersoll 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY,
11847e946e7SWyllys Ingersoll 	    TSS_TPMCAP_PROP_MAXCONTEXTS, &max, sizeof (max)))
11947e946e7SWyllys Ingersoll 		return (ERR_FAIL);
12047e946e7SWyllys Ingersoll 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY,
12147e946e7SWyllys Ingersoll 	    TSS_TPMCAP_PROP_CONTEXTS, &avail, sizeof (avail)))
12247e946e7SWyllys Ingersoll 		return (ERR_FAIL);
12347e946e7SWyllys Ingersoll 	(void) printf(gettext("\tContexts: %d/%d available\n"), avail, max);
12447e946e7SWyllys Ingersoll 
12547e946e7SWyllys Ingersoll 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY,
12647e946e7SWyllys Ingersoll 	    TSS_TPMCAP_PROP_MAXSESSIONS, &max, sizeof (max)))
12747e946e7SWyllys Ingersoll 		return (ERR_FAIL);
12847e946e7SWyllys Ingersoll 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY,
12947e946e7SWyllys Ingersoll 	    TSS_TPMCAP_PROP_SESSIONS, &avail, sizeof (avail)))
13047e946e7SWyllys Ingersoll 		return (ERR_FAIL);
13147e946e7SWyllys Ingersoll 	(void) printf(gettext("\tSessions: %d/%d available\n"), avail, max);
13247e946e7SWyllys Ingersoll 
13347e946e7SWyllys Ingersoll 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY,
13447e946e7SWyllys Ingersoll 	    TSS_TPMCAP_PROP_MAXAUTHSESSIONS, &max, sizeof (max)))
13547e946e7SWyllys Ingersoll 		return (ERR_FAIL);
13647e946e7SWyllys Ingersoll 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY,
13747e946e7SWyllys Ingersoll 	    TSS_TPMCAP_PROP_AUTHSESSIONS, &avail, sizeof (avail)))
13847e946e7SWyllys Ingersoll 		return (ERR_FAIL);
13947e946e7SWyllys Ingersoll 	(void) printf(gettext("\tAuth Sessions: %d/%d available\n"),
14047e946e7SWyllys Ingersoll 	    avail, max);
14147e946e7SWyllys Ingersoll 
14247e946e7SWyllys Ingersoll 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY,
14347e946e7SWyllys Ingersoll 	    TSS_TPMCAP_PROP_MAXKEYS, &max, sizeof (max)))
14447e946e7SWyllys Ingersoll 		return (ERR_FAIL);
14547e946e7SWyllys Ingersoll 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY,
14647e946e7SWyllys Ingersoll 	    TSS_TPMCAP_PROP_KEYS, &avail, sizeof (avail)))
14747e946e7SWyllys Ingersoll 		return (ERR_FAIL);
14847e946e7SWyllys Ingersoll 	(void) printf(gettext("\tLoaded Keys: %d/%d available\n"), avail, max);
14947e946e7SWyllys Ingersoll 
15047e946e7SWyllys Ingersoll 	return (0);
15147e946e7SWyllys Ingersoll }
15247e946e7SWyllys Ingersoll 
15347e946e7SWyllys Ingersoll static int
print_tpm_pcrs(TSS_HCONTEXT hContext,TSS_HOBJECT hTPM)15447e946e7SWyllys Ingersoll print_tpm_pcrs(TSS_HCONTEXT hContext, TSS_HOBJECT hTPM)
15547e946e7SWyllys Ingersoll {
15647e946e7SWyllys Ingersoll 	UINT32 num_pcrs;
15747e946e7SWyllys Ingersoll 	int i;
15847e946e7SWyllys Ingersoll 
15947e946e7SWyllys Ingersoll 	if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY,
16047e946e7SWyllys Ingersoll 	    TSS_TPMCAP_PROP_PCR, &num_pcrs, sizeof (num_pcrs)))
16147e946e7SWyllys Ingersoll 		return (ERR_FAIL);
16247e946e7SWyllys Ingersoll 	(void) printf(gettext("Platform Configuration Registers (%u)\n"),
16347e946e7SWyllys Ingersoll 	    num_pcrs);
16447e946e7SWyllys Ingersoll 
16547e946e7SWyllys Ingersoll 	/* Print each PCR */
16647e946e7SWyllys Ingersoll 	for (i = 0; i < num_pcrs; i++) {
16747e946e7SWyllys Ingersoll 		TSS_RESULT ret;
16847e946e7SWyllys Ingersoll 		UINT32 datalen;
16947e946e7SWyllys Ingersoll 		BYTE *data;
17047e946e7SWyllys Ingersoll 
17147e946e7SWyllys Ingersoll 		ret = Tspi_TPM_PcrRead(hTPM, i, &datalen, &data);
17247e946e7SWyllys Ingersoll 		if (ret) {
17347e946e7SWyllys Ingersoll 			print_error(ret, gettext("Read PCR"));
17447e946e7SWyllys Ingersoll 			return (ret);
17547e946e7SWyllys Ingersoll 		}
17647e946e7SWyllys Ingersoll 
17747e946e7SWyllys Ingersoll 		(void) printf("\tPCR %u:\t", i);
17847e946e7SWyllys Ingersoll 		print_bytes(data, datalen, FALSE);
17947e946e7SWyllys Ingersoll 
18047e946e7SWyllys Ingersoll 		ret = Tspi_Context_FreeMemory(hContext, data);
18147e946e7SWyllys Ingersoll 		if (ret) {
18247e946e7SWyllys Ingersoll 			print_error(ret, gettext("Free PCR memory"));
18347e946e7SWyllys Ingersoll 			return (ret);
18447e946e7SWyllys Ingersoll 		}
18547e946e7SWyllys Ingersoll 	}
18647e946e7SWyllys Ingersoll 	return (0);
18747e946e7SWyllys Ingersoll }
18847e946e7SWyllys Ingersoll 
18947e946e7SWyllys Ingersoll /*ARGSUSED*/
19047e946e7SWyllys Ingersoll int
cmd_status(TSS_HCONTEXT hContext,TSS_HTPM hTPM,int argc,char * argv[])19147e946e7SWyllys Ingersoll cmd_status(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[])
19247e946e7SWyllys Ingersoll {
193304d8f90SScott Rotondo 	if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP, NULL, 0, NULL))
19447e946e7SWyllys Ingersoll 		return (ERR_FAIL);
19547e946e7SWyllys Ingersoll 
19647e946e7SWyllys Ingersoll 	(void) print_tpm_version(hContext, hTPM);
19747e946e7SWyllys Ingersoll 	if (tpm_is_owned(hContext, hTPM)) {
19847e946e7SWyllys Ingersoll 		(void) print_tpm_resources(hContext, hTPM);
19947e946e7SWyllys Ingersoll 		(void) print_tpm_pcrs(hContext, hTPM);
20047e946e7SWyllys Ingersoll 	} else {
20147e946e7SWyllys Ingersoll 		(void) printf(gettext("No TPM owner installed.\n"));
20247e946e7SWyllys Ingersoll 	}
20347e946e7SWyllys Ingersoll 
20447e946e7SWyllys Ingersoll 	return (0);
20547e946e7SWyllys Ingersoll }
20647e946e7SWyllys Ingersoll 
20747e946e7SWyllys Ingersoll 
20847e946e7SWyllys Ingersoll /*
20947e946e7SWyllys Ingersoll  * Key Information
21047e946e7SWyllys Ingersoll  */
21147e946e7SWyllys Ingersoll 
21247e946e7SWyllys Ingersoll typedef struct {
21347e946e7SWyllys Ingersoll 	UINT32 code;
21447e946e7SWyllys Ingersoll 	char *str;
21547e946e7SWyllys Ingersoll } decode_map_t;
21647e946e7SWyllys Ingersoll 
21747e946e7SWyllys Ingersoll decode_map_t key_usage[] = {
21847e946e7SWyllys Ingersoll 	{ TSS_KEYUSAGE_SIGN, "Signing" },
21947e946e7SWyllys Ingersoll 	{ TSS_KEYUSAGE_STORAGE, "Storage" },
22047e946e7SWyllys Ingersoll 	{ TSS_KEYUSAGE_IDENTITY, "Identity" },
22147e946e7SWyllys Ingersoll 	{ TSS_KEYUSAGE_AUTHCHANGE, "Authchange" },
22247e946e7SWyllys Ingersoll 	{ TSS_KEYUSAGE_BIND, "Bind" },
22347e946e7SWyllys Ingersoll 	{ TSS_KEYUSAGE_LEGACY, "Legacy" },
22447e946e7SWyllys Ingersoll 	{ TSS_KEYUSAGE_MIGRATE, "Migrate" },
22547e946e7SWyllys Ingersoll 	{ 0, NULL },
22647e946e7SWyllys Ingersoll };
22747e946e7SWyllys Ingersoll 
22847e946e7SWyllys Ingersoll decode_map_t key_algorithm[] = {
22947e946e7SWyllys Ingersoll 	{ TSS_ALG_RSA, "RSA" },
23047e946e7SWyllys Ingersoll 	{ TSS_ALG_DES, "DES" },
23147e946e7SWyllys Ingersoll 	{ TSS_ALG_3DES, "3-DES" },
23247e946e7SWyllys Ingersoll 	{ TSS_ALG_SHA, "SHA" },
23347e946e7SWyllys Ingersoll 	{ TSS_ALG_HMAC, "HMAC" },
23447e946e7SWyllys Ingersoll 	{ TSS_ALG_AES, "AES" },
23547e946e7SWyllys Ingersoll 	{ TSS_ALG_MGF1, "MGF1" },
23647e946e7SWyllys Ingersoll 	{ TSS_ALG_AES192, "AES192" },
23747e946e7SWyllys Ingersoll 	{ TSS_ALG_AES256, "AES256" },
23847e946e7SWyllys Ingersoll 	{ TSS_ALG_XOR, "XOR" },
23947e946e7SWyllys Ingersoll 	{ 0, NULL },
24047e946e7SWyllys Ingersoll };
24147e946e7SWyllys Ingersoll 
24247e946e7SWyllys Ingersoll decode_map_t key_sigscheme[] = {
24347e946e7SWyllys Ingersoll 	{ TSS_SS_NONE, "None" },
24447e946e7SWyllys Ingersoll 	{ TSS_SS_RSASSAPKCS1V15_SHA1, "RSASSAPKCS1v15_SHA1" },
24547e946e7SWyllys Ingersoll 	{ TSS_SS_RSASSAPKCS1V15_DER, "RSASSAPKCS1v15_DER" },
24647e946e7SWyllys Ingersoll 	{ 0, NULL },
24747e946e7SWyllys Ingersoll };
24847e946e7SWyllys Ingersoll 
24947e946e7SWyllys Ingersoll decode_map_t key_encscheme[] = {
25047e946e7SWyllys Ingersoll 	{ TSS_ES_NONE, "None" },
25147e946e7SWyllys Ingersoll 	{ TSS_ES_RSAESPKCSV15, "RSAESPKCSv15" },
25247e946e7SWyllys Ingersoll 	{ TSS_ES_RSAESOAEP_SHA1_MGF1, "RSAESOAEP_SHA1_MGF1" },
25347e946e7SWyllys Ingersoll 	{ TSS_ES_SYM_CNT, "SYM_CNT" },
25447e946e7SWyllys Ingersoll 	{ TSS_ES_SYM_OFB, "SYM_OFB" },
25547e946e7SWyllys Ingersoll 	{ 0, NULL },
25647e946e7SWyllys Ingersoll };
25747e946e7SWyllys Ingersoll 
25847e946e7SWyllys Ingersoll static char *
decode(decode_map_t * table,UINT32 code)25947e946e7SWyllys Ingersoll decode(decode_map_t *table, UINT32 code)
26047e946e7SWyllys Ingersoll {
26147e946e7SWyllys Ingersoll 	static char buf[20];
26247e946e7SWyllys Ingersoll 	int i;
26347e946e7SWyllys Ingersoll 
26447e946e7SWyllys Ingersoll 	for (i = 0; table[i].str != NULL; i++) {
26547e946e7SWyllys Ingersoll 		if (table[i].code == code)
26647e946e7SWyllys Ingersoll 			return (table[i].str);
26747e946e7SWyllys Ingersoll 	}
26847e946e7SWyllys Ingersoll 
26947e946e7SWyllys Ingersoll 	(void) snprintf(buf, sizeof (buf), gettext("Unknown (%u)"), code);
27047e946e7SWyllys Ingersoll 	return (buf);
27147e946e7SWyllys Ingersoll }
27247e946e7SWyllys Ingersoll 
27347e946e7SWyllys Ingersoll static void
print_key_info(TSS_HCONTEXT hContext,TSS_HOBJECT hKey)27447e946e7SWyllys Ingersoll print_key_info(TSS_HCONTEXT hContext, TSS_HOBJECT hKey)
27547e946e7SWyllys Ingersoll {
27647e946e7SWyllys Ingersoll 	TSS_RESULT ret;
27747e946e7SWyllys Ingersoll 	UINT32 attrib;
27847e946e7SWyllys Ingersoll 	UINT32 keyInfoSize;
27947e946e7SWyllys Ingersoll 	BYTE *keyInfo;
28047e946e7SWyllys Ingersoll 
28147e946e7SWyllys Ingersoll 	/* Key size */
28247e946e7SWyllys Ingersoll 	ret = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO,
28347e946e7SWyllys Ingersoll 	    TSS_TSPATTRIB_KEYINFO_SIZE, &attrib);
28447e946e7SWyllys Ingersoll 	if (ret) {
28547e946e7SWyllys Ingersoll 		print_error(ret, gettext("Get key size"));
28647e946e7SWyllys Ingersoll 	}
28747e946e7SWyllys Ingersoll 	(void) printf(gettext("Key Size: %d bits\n"), attrib);
28847e946e7SWyllys Ingersoll 
28947e946e7SWyllys Ingersoll 	/* Key usage */
29047e946e7SWyllys Ingersoll 	ret = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO,
29147e946e7SWyllys Ingersoll 	    TSS_TSPATTRIB_KEYINFO_USAGE, &attrib);
29247e946e7SWyllys Ingersoll 	if (ret) {
29347e946e7SWyllys Ingersoll 		print_error(ret, gettext("Get key usage"));
29447e946e7SWyllys Ingersoll 	}
29547e946e7SWyllys Ingersoll 	(void) printf(gettext("Key Usage: %s\n"), decode(key_usage, attrib));
29647e946e7SWyllys Ingersoll 
29747e946e7SWyllys Ingersoll 	/* Algorithm */
29847e946e7SWyllys Ingersoll 	ret = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO,
29947e946e7SWyllys Ingersoll 	    TSS_TSPATTRIB_KEYINFO_ALGORITHM, &attrib);
30047e946e7SWyllys Ingersoll 	if (ret) {
30147e946e7SWyllys Ingersoll 		print_error(ret, gettext("Get key algorithm"));
30247e946e7SWyllys Ingersoll 	}
30347e946e7SWyllys Ingersoll 	(void) printf(gettext("Algorithm: %s\n"),
30447e946e7SWyllys Ingersoll 	    decode(key_algorithm, attrib));
30547e946e7SWyllys Ingersoll 
30647e946e7SWyllys Ingersoll 	/* Authorization required */
30747e946e7SWyllys Ingersoll 	ret = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO,
30847e946e7SWyllys Ingersoll 	    TSS_TSPATTRIB_KEYINFO_AUTHUSAGE, &attrib);
30947e946e7SWyllys Ingersoll 	if (ret) {
31047e946e7SWyllys Ingersoll 		print_error(ret, gettext("Get key authusage"));
31147e946e7SWyllys Ingersoll 	}
31247e946e7SWyllys Ingersoll 	(void) printf(gettext("Authorization required: %s\n"),
31347e946e7SWyllys Ingersoll 	    attrib ? gettext("Yes") : gettext("No"));
31447e946e7SWyllys Ingersoll 
31547e946e7SWyllys Ingersoll 	/* Signature scheme */
31647e946e7SWyllys Ingersoll 	ret = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO,
31747e946e7SWyllys Ingersoll 	    TSS_TSPATTRIB_KEYINFO_SIGSCHEME, &attrib);
31847e946e7SWyllys Ingersoll 	if (ret) {
31947e946e7SWyllys Ingersoll 		print_error(ret, gettext("Get key signature scheme"));
32047e946e7SWyllys Ingersoll 	}
32147e946e7SWyllys Ingersoll 	(void) printf(gettext("Signature scheme: %s\n"),
32247e946e7SWyllys Ingersoll 	    decode(key_sigscheme, attrib));
32347e946e7SWyllys Ingersoll 
32447e946e7SWyllys Ingersoll 	/* Encoding scheme */
32547e946e7SWyllys Ingersoll 	ret = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO,
32647e946e7SWyllys Ingersoll 	    TSS_TSPATTRIB_KEYINFO_ENCSCHEME, &attrib);
32747e946e7SWyllys Ingersoll 	if (ret) {
32847e946e7SWyllys Ingersoll 		print_error(ret, gettext("Get key encoding scheme"));
32947e946e7SWyllys Ingersoll 	}
33047e946e7SWyllys Ingersoll 	(void) printf(gettext("Encoding scheme: %s\n"),
33147e946e7SWyllys Ingersoll 	    decode(key_encscheme, attrib));
33247e946e7SWyllys Ingersoll 
33347e946e7SWyllys Ingersoll 	/* Key blob */
33447e946e7SWyllys Ingersoll 	ret = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB,
33547e946e7SWyllys Ingersoll 	    TSS_TSPATTRIB_KEYBLOB_BLOB, &keyInfoSize, &keyInfo);
33647e946e7SWyllys Ingersoll 	if (ret) {
33747e946e7SWyllys Ingersoll 		print_error(ret, gettext("Get key blob"));
33847e946e7SWyllys Ingersoll 	}
33947e946e7SWyllys Ingersoll 	(void) printf(gettext("TPM Key Blob:\n"));
34047e946e7SWyllys Ingersoll 	print_bytes(keyInfo, keyInfoSize, TRUE);
34147e946e7SWyllys Ingersoll 	ret = Tspi_Context_FreeMemory(hContext, keyInfo);
34247e946e7SWyllys Ingersoll 	if (ret) {
34347e946e7SWyllys Ingersoll 		print_error(ret, gettext("Free key info buffer"));
34447e946e7SWyllys Ingersoll 	}
34547e946e7SWyllys Ingersoll }
34647e946e7SWyllys Ingersoll 
34747e946e7SWyllys Ingersoll typedef struct hash_node {
34847e946e7SWyllys Ingersoll 	struct hash_node *next, *sibling, *child;
34947e946e7SWyllys Ingersoll 	TSS_UUID uuid;
35047e946e7SWyllys Ingersoll 	TSS_KM_KEYINFO2 *key_data;
35147e946e7SWyllys Ingersoll } hash_node_t;
35247e946e7SWyllys Ingersoll 
35347e946e7SWyllys Ingersoll #define	HASHSIZE 17
35447e946e7SWyllys Ingersoll hash_node_t *hash_table[HASHSIZE];
35547e946e7SWyllys Ingersoll 
35647e946e7SWyllys Ingersoll static hash_node_t *
hash_insert(TSS_UUID uuid,TSS_KM_KEYINFO2 * key_data)35747e946e7SWyllys Ingersoll hash_insert(TSS_UUID uuid, TSS_KM_KEYINFO2 *key_data)
35847e946e7SWyllys Ingersoll {
35947e946e7SWyllys Ingersoll 	UINT32 i, index = 0;
36047e946e7SWyllys Ingersoll 	hash_node_t *node;
36147e946e7SWyllys Ingersoll 	char *cp;
36247e946e7SWyllys Ingersoll 
36347e946e7SWyllys Ingersoll 	cp = (char *)&uuid;
36447e946e7SWyllys Ingersoll 	for (i = 0; i < sizeof (TSS_UUID); i++)
36547e946e7SWyllys Ingersoll 		index += cp[i];
36647e946e7SWyllys Ingersoll 	index = index % HASHSIZE;
36747e946e7SWyllys Ingersoll 
36847e946e7SWyllys Ingersoll 	for (node = hash_table[index]; node != NULL; node = node->next) {
36947e946e7SWyllys Ingersoll 		if (memcmp(&(node->uuid), &uuid, sizeof (TSS_UUID)) == 0)
37047e946e7SWyllys Ingersoll 			break;
37147e946e7SWyllys Ingersoll 	}
37247e946e7SWyllys Ingersoll 
37347e946e7SWyllys Ingersoll 	if (node == NULL) {
37447e946e7SWyllys Ingersoll 		node = calloc(1, sizeof (hash_node_t));
37547e946e7SWyllys Ingersoll 		node->uuid = uuid;
37647e946e7SWyllys Ingersoll 		node->next = hash_table[index];
37747e946e7SWyllys Ingersoll 		hash_table[index] = node;
37847e946e7SWyllys Ingersoll 	}
37947e946e7SWyllys Ingersoll 	if (node->key_data == NULL)
38047e946e7SWyllys Ingersoll 		node->key_data = key_data;
38147e946e7SWyllys Ingersoll 
38247e946e7SWyllys Ingersoll 	return (node);
38347e946e7SWyllys Ingersoll }
38447e946e7SWyllys Ingersoll 
38547e946e7SWyllys Ingersoll static void
add_child(hash_node_t * parent,hash_node_t * child)38647e946e7SWyllys Ingersoll add_child(hash_node_t *parent, hash_node_t *child)
38747e946e7SWyllys Ingersoll {
38847e946e7SWyllys Ingersoll 	hash_node_t *node;
38947e946e7SWyllys Ingersoll 
39047e946e7SWyllys Ingersoll 	for (node = parent->child; node != NULL; node = node->next) {
39147e946e7SWyllys Ingersoll 		if (node == child)
39247e946e7SWyllys Ingersoll 			return;
39347e946e7SWyllys Ingersoll 	}
39447e946e7SWyllys Ingersoll 
39547e946e7SWyllys Ingersoll 	child->sibling = parent->child;
39647e946e7SWyllys Ingersoll 	parent->child = child;
39747e946e7SWyllys Ingersoll }
39847e946e7SWyllys Ingersoll 
39947e946e7SWyllys Ingersoll static void
print_all(hash_node_t * parent,int indent)40047e946e7SWyllys Ingersoll print_all(hash_node_t *parent, int indent)
40147e946e7SWyllys Ingersoll {
40247e946e7SWyllys Ingersoll 	char uuidstr[UUID_PRINTABLE_STRING_LENGTH];
40347e946e7SWyllys Ingersoll 	hash_node_t *node;
40447e946e7SWyllys Ingersoll 	char *type, *loaded;
40547e946e7SWyllys Ingersoll 
40647e946e7SWyllys Ingersoll 	uuid_unparse(*(uuid_t *)&parent->uuid, uuidstr);
40747e946e7SWyllys Ingersoll 	type = (parent->key_data->persistentStorageType == TSS_PS_TYPE_USER) ?
40847e946e7SWyllys Ingersoll 	    "USER" : "SYSTEM";
40947e946e7SWyllys Ingersoll 	loaded = parent->key_data->fIsLoaded ? "(loaded)" : "";
41047e946e7SWyllys Ingersoll 	(void) printf("%*s[%s] %s %s\n", indent, "",
41147e946e7SWyllys Ingersoll 	    type, uuidstr, loaded);
41247e946e7SWyllys Ingersoll 
41347e946e7SWyllys Ingersoll 	for (node = parent->child; node != NULL; node = node->sibling)
41447e946e7SWyllys Ingersoll 		print_all(node, indent + 4);
41547e946e7SWyllys Ingersoll }
41647e946e7SWyllys Ingersoll 
41747e946e7SWyllys Ingersoll /*ARGSUSED*/
41847e946e7SWyllys Ingersoll int
cmd_keyinfo(TSS_HCONTEXT hContext,TSS_HTPM hTPM,int argc,char * argv[])41947e946e7SWyllys Ingersoll cmd_keyinfo(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[])
42047e946e7SWyllys Ingersoll {
42147e946e7SWyllys Ingersoll 	TSS_RESULT ret;
42247e946e7SWyllys Ingersoll 	UINT32 i, num_keys;
42347e946e7SWyllys Ingersoll 	TSS_KM_KEYINFO2 *keys;
42447e946e7SWyllys Ingersoll 	hash_node_t *parent, *child, *srk = NULL;
42547e946e7SWyllys Ingersoll 	TSS_HKEY hKey;
42647e946e7SWyllys Ingersoll 	union {
42747e946e7SWyllys Ingersoll 		uuid_t arr_uuid;
42847e946e7SWyllys Ingersoll 		TSS_UUID tss_uuid;
42947e946e7SWyllys Ingersoll 	} uuid;
43047e946e7SWyllys Ingersoll 
43147e946e7SWyllys Ingersoll 	switch (argc) {
432304d8f90SScott Rotondo 	case 1:
43347e946e7SWyllys Ingersoll 		/* Print key hierarchy */
43447e946e7SWyllys Ingersoll 		ret = Tspi_Context_GetRegisteredKeysByUUID2(hContext,
43547e946e7SWyllys Ingersoll 		    TSS_PS_TYPE_USER, NULL, &num_keys, &keys);
43647e946e7SWyllys Ingersoll 		if (ret) {
43747e946e7SWyllys Ingersoll 			print_error(ret, gettext("Get key hierarchy"));
43847e946e7SWyllys Ingersoll 			return (ERR_FAIL);
43947e946e7SWyllys Ingersoll 		}
44047e946e7SWyllys Ingersoll 
44147e946e7SWyllys Ingersoll 		for (i = 0; i < num_keys; i++) {
44247e946e7SWyllys Ingersoll 			parent = hash_insert(keys[i].parentKeyUUID, NULL);
44347e946e7SWyllys Ingersoll 			child = hash_insert(keys[i].keyUUID, &keys[i]);
44447e946e7SWyllys Ingersoll 			add_child(parent, child);
44547e946e7SWyllys Ingersoll 			if (memcmp(&(keys[i].keyUUID), &srk_uuid,
44647e946e7SWyllys Ingersoll 			    sizeof (TSS_UUID)) == 0)
44747e946e7SWyllys Ingersoll 				srk = child;
44847e946e7SWyllys Ingersoll 		}
44947e946e7SWyllys Ingersoll 
45047e946e7SWyllys Ingersoll 		if (srk != NULL)
45147e946e7SWyllys Ingersoll 			print_all(srk, 0);
45247e946e7SWyllys Ingersoll 		ret = Tspi_Context_FreeMemory(hContext, (BYTE *) keys);
45347e946e7SWyllys Ingersoll 		if (ret) {
45447e946e7SWyllys Ingersoll 			print_error(ret, gettext("Free key list"));
45547e946e7SWyllys Ingersoll 			return (ERR_FAIL);
45647e946e7SWyllys Ingersoll 		}
45747e946e7SWyllys Ingersoll 		return (0);
45847e946e7SWyllys Ingersoll 
459304d8f90SScott Rotondo 	case 2:
46047e946e7SWyllys Ingersoll 		/* Print detailed info about a single key */
46147e946e7SWyllys Ingersoll 		if (uuid_parse(argv[1], uuid.arr_uuid))
46247e946e7SWyllys Ingersoll 			return (ERR_FAIL);
46347e946e7SWyllys Ingersoll 		ret = Tspi_Context_GetKeyByUUID(hContext, TSS_PS_TYPE_USER,
46447e946e7SWyllys Ingersoll 		    uuid.tss_uuid, &hKey);
46547e946e7SWyllys Ingersoll 		if (ret == TSP_ERROR(TSS_E_PS_KEY_NOTFOUND)) {
46647e946e7SWyllys Ingersoll 			ret = Tspi_Context_GetKeyByUUID(hContext,
46747e946e7SWyllys Ingersoll 			    TSS_PS_TYPE_SYSTEM, uuid.tss_uuid, &hKey);
46847e946e7SWyllys Ingersoll 		}
46947e946e7SWyllys Ingersoll 		if (ret) {
47047e946e7SWyllys Ingersoll 			print_error(ret, gettext("Get key by UUID"));
47147e946e7SWyllys Ingersoll 			return (ERR_FAIL);
47247e946e7SWyllys Ingersoll 		}
47347e946e7SWyllys Ingersoll 		print_key_info(hContext, hKey);
47447e946e7SWyllys Ingersoll 		return (0);
47547e946e7SWyllys Ingersoll 
476304d8f90SScott Rotondo 	default:
47747e946e7SWyllys Ingersoll 		(void) fprintf(stderr, gettext("Usage:\n"));
47847e946e7SWyllys Ingersoll 		(void) fprintf(stderr, "\tkeyinfo [uuid]\n");
47947e946e7SWyllys Ingersoll 		return (ERR_USAGE);
48047e946e7SWyllys Ingersoll 	}
48147e946e7SWyllys Ingersoll }
48247e946e7SWyllys Ingersoll 
48347e946e7SWyllys Ingersoll /*ARGSUSED*/
48447e946e7SWyllys Ingersoll int
cmd_deletekey(TSS_HCONTEXT hContext,TSS_HTPM hTPM,int argc,char * argv[])48547e946e7SWyllys Ingersoll cmd_deletekey(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[])
48647e946e7SWyllys Ingersoll {
48747e946e7SWyllys Ingersoll 	TSS_RESULT ret;
48847e946e7SWyllys Ingersoll 	TSS_HOBJECT hKey;
48947e946e7SWyllys Ingersoll 	union {
49047e946e7SWyllys Ingersoll 		uuid_t arr_uuid;
49147e946e7SWyllys Ingersoll 		TSS_UUID tss_uuid;
49247e946e7SWyllys Ingersoll 	} uuid;
49347e946e7SWyllys Ingersoll 
49447e946e7SWyllys Ingersoll 	if (argc < 2) {
49547e946e7SWyllys Ingersoll 		(void) fprintf(stderr, gettext("Usage:\n"));
49647e946e7SWyllys Ingersoll 		(void) fprintf(stderr, "\tdeletekey [uuid]\n");
49747e946e7SWyllys Ingersoll 		return (ERR_USAGE);
49847e946e7SWyllys Ingersoll 	}
49947e946e7SWyllys Ingersoll 	if (uuid_parse(argv[1], uuid.arr_uuid))
50047e946e7SWyllys Ingersoll 		return (ERR_FAIL);
50147e946e7SWyllys Ingersoll 	ret = Tspi_Context_UnregisterKey(hContext, TSS_PS_TYPE_USER,
50247e946e7SWyllys Ingersoll 	    uuid.tss_uuid, &hKey);
50347e946e7SWyllys Ingersoll 	if (ret == TSP_ERROR(TSS_E_PS_KEY_NOTFOUND)) {
50447e946e7SWyllys Ingersoll 		ret = Tspi_Context_UnregisterKey(hContext, TSS_PS_TYPE_SYSTEM,
50547e946e7SWyllys Ingersoll 		    uuid.tss_uuid, &hKey);
50647e946e7SWyllys Ingersoll 	}
50747e946e7SWyllys Ingersoll 	if (ret) {
50847e946e7SWyllys Ingersoll 		print_error(ret, gettext("Unregister key"));
50947e946e7SWyllys Ingersoll 		return (ERR_FAIL);
51047e946e7SWyllys Ingersoll 	}
51147e946e7SWyllys Ingersoll 	return (0);
51247e946e7SWyllys Ingersoll }
51347e946e7SWyllys Ingersoll 
51447e946e7SWyllys Ingersoll /*
51547e946e7SWyllys Ingersoll  * Clear
51647e946e7SWyllys Ingersoll  */
51747e946e7SWyllys Ingersoll 
51847e946e7SWyllys Ingersoll static int
clearowner(TSS_HTPM hTPM)51947e946e7SWyllys Ingersoll clearowner(TSS_HTPM hTPM)
52047e946e7SWyllys Ingersoll {
52147e946e7SWyllys Ingersoll 	TSS_RESULT ret;
52247e946e7SWyllys Ingersoll 
523304d8f90SScott Rotondo 	if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP,
524304d8f90SScott Rotondo 	    gettext("= TPM owner passphrase ="), 0, NULL))
52547e946e7SWyllys Ingersoll 		return (ERR_FAIL);
52647e946e7SWyllys Ingersoll 
52747e946e7SWyllys Ingersoll 	ret = Tspi_TPM_ClearOwner(hTPM, FALSE);
52847e946e7SWyllys Ingersoll 	if (ret) {
52947e946e7SWyllys Ingersoll 		print_error(ret, gettext("Clear TPM owner"));
53047e946e7SWyllys Ingersoll 		return (ERR_FAIL);
53147e946e7SWyllys Ingersoll 	}
53247e946e7SWyllys Ingersoll 	return (0);
53347e946e7SWyllys Ingersoll }
53447e946e7SWyllys Ingersoll 
53547e946e7SWyllys Ingersoll static int
resetlock(TSS_HTPM hTPM)53647e946e7SWyllys Ingersoll resetlock(TSS_HTPM hTPM)
53747e946e7SWyllys Ingersoll {
53847e946e7SWyllys Ingersoll 	TSS_RESULT ret;
53947e946e7SWyllys Ingersoll 
540304d8f90SScott Rotondo 	if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP,
541304d8f90SScott Rotondo 	    gettext("= TPM owner passphrase ="), 0, NULL))
54247e946e7SWyllys Ingersoll 		return (ERR_FAIL);
54347e946e7SWyllys Ingersoll 
54447e946e7SWyllys Ingersoll 	ret = Tspi_TPM_SetStatus(hTPM, TSS_TPMSTATUS_RESETLOCK, TRUE);
54547e946e7SWyllys Ingersoll 	if (ret) {
54647e946e7SWyllys Ingersoll 		print_error(ret, gettext("Reset Lock"));
54747e946e7SWyllys Ingersoll 		return (ERR_FAIL);
54847e946e7SWyllys Ingersoll 	}
54947e946e7SWyllys Ingersoll 	return (0);
55047e946e7SWyllys Ingersoll }
55147e946e7SWyllys Ingersoll 
55247e946e7SWyllys Ingersoll /*ARGSUSED*/
55347e946e7SWyllys Ingersoll int
cmd_clear(TSS_HCONTEXT hContext,TSS_HTPM hTPM,int argc,char * argv[])55447e946e7SWyllys Ingersoll cmd_clear(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[])
55547e946e7SWyllys Ingersoll {
55647e946e7SWyllys Ingersoll 	char *subcmd = argv[1];
55747e946e7SWyllys Ingersoll 
55847e946e7SWyllys Ingersoll 	if (subcmd && strcmp(subcmd, "lock") == 0) {
55947e946e7SWyllys Ingersoll 		return (resetlock(hTPM));
56047e946e7SWyllys Ingersoll 	} else if (subcmd && strcmp(subcmd, "owner") == 0) {
56147e946e7SWyllys Ingersoll 		return (clearowner(hTPM));
56247e946e7SWyllys Ingersoll 	} else {
56347e946e7SWyllys Ingersoll 		(void) fprintf(stderr, gettext("Usage:\n"));
56447e946e7SWyllys Ingersoll 		(void) fprintf(stderr, "\tclear owner\n");
56547e946e7SWyllys Ingersoll 		(void) fprintf(stderr, "\tclear lock\n");
56647e946e7SWyllys Ingersoll 		return (ERR_USAGE);
56747e946e7SWyllys Ingersoll 	}
56847e946e7SWyllys Ingersoll }
56947e946e7SWyllys Ingersoll 
57047e946e7SWyllys Ingersoll 
57147e946e7SWyllys Ingersoll /*
57247e946e7SWyllys Ingersoll  * TPM initialization
57347e946e7SWyllys Ingersoll  */
57447e946e7SWyllys Ingersoll 
57547e946e7SWyllys Ingersoll static int
get_random(UINT32 size,BYTE * randomBytes)57647e946e7SWyllys Ingersoll get_random(UINT32 size,	BYTE *randomBytes)
57747e946e7SWyllys Ingersoll {
57847e946e7SWyllys Ingersoll 	int fd, len;
57947e946e7SWyllys Ingersoll 	BYTE *buf;
58047e946e7SWyllys Ingersoll 
58147e946e7SWyllys Ingersoll 	fd = open("/dev/random", O_RDONLY);
58247e946e7SWyllys Ingersoll 	if (fd == -1) {
58347e946e7SWyllys Ingersoll 		(void) fprintf(stderr, gettext("Unable to open /dev/random"));
58447e946e7SWyllys Ingersoll 		return (-1);
58547e946e7SWyllys Ingersoll 	}
58647e946e7SWyllys Ingersoll 
58747e946e7SWyllys Ingersoll 	buf = randomBytes;
58847e946e7SWyllys Ingersoll 	while (size > 0) {
58947e946e7SWyllys Ingersoll 		len = read(fd, buf, size);
59047e946e7SWyllys Ingersoll 		if (len <= 0) {
59147e946e7SWyllys Ingersoll 			(void) close(fd);
59247e946e7SWyllys Ingersoll 			(void) fprintf(stderr,
59347e946e7SWyllys Ingersoll 			    gettext("Error reading /dev/random"));
59447e946e7SWyllys Ingersoll 			return (-1);
59547e946e7SWyllys Ingersoll 		}
59647e946e7SWyllys Ingersoll 		size -= len;
59747e946e7SWyllys Ingersoll 		buf += len;
59847e946e7SWyllys Ingersoll 	}
59947e946e7SWyllys Ingersoll 
60047e946e7SWyllys Ingersoll 	(void) close(fd);
60147e946e7SWyllys Ingersoll 	return (0);
60247e946e7SWyllys Ingersoll }
60347e946e7SWyllys Ingersoll 
60447e946e7SWyllys Ingersoll static int
createek(TSS_HCONTEXT hContext,TSS_HTPM hTPM)60547e946e7SWyllys Ingersoll createek(TSS_HCONTEXT hContext, TSS_HTPM hTPM)
60647e946e7SWyllys Ingersoll {
60747e946e7SWyllys Ingersoll 	TSS_RESULT ret;
60847e946e7SWyllys Ingersoll 	TSS_HOBJECT hKeyEK;
60947e946e7SWyllys Ingersoll 	TSS_VALIDATION ValidationData;
61047e946e7SWyllys Ingersoll 	TPM_NONCE nonce;
61147e946e7SWyllys Ingersoll 	TPM_DIGEST digest;
61247e946e7SWyllys Ingersoll 
61347e946e7SWyllys Ingersoll 	/* Create the empty key struct for EK */
61447e946e7SWyllys Ingersoll 	ret = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY,
61547e946e7SWyllys Ingersoll 	    (TSS_KEY_NO_AUTHORIZATION | TSS_KEY_NON_VOLATILE |
61647e946e7SWyllys Ingersoll 	    TSS_KEY_NOT_MIGRATABLE | TSS_KEY_TYPE_STORAGE |
61747e946e7SWyllys Ingersoll 	    TSS_KEY_SIZE_2048 | TSS_KEY_NOT_CERTIFIED_MIGRATABLE |
61847e946e7SWyllys Ingersoll 	    TSS_KEY_STRUCT_KEY12 | TSS_KEY_EMPTY_KEY),
61947e946e7SWyllys Ingersoll 	    &hKeyEK);
62047e946e7SWyllys Ingersoll 	if (ret) {
62147e946e7SWyllys Ingersoll 		print_error(ret, gettext("Create endorsement key object"));
62247e946e7SWyllys Ingersoll 		return (ERR_FAIL);
62347e946e7SWyllys Ingersoll 	}
62447e946e7SWyllys Ingersoll 
62547e946e7SWyllys Ingersoll 	ValidationData.ulExternalDataLength = sizeof (nonce);
62647e946e7SWyllys Ingersoll 	ValidationData.rgbExternalData = (BYTE *) &nonce;
62747e946e7SWyllys Ingersoll 	ret = get_random(sizeof (nonce), (BYTE *) &nonce);
62847e946e7SWyllys Ingersoll 	if (ret)
62947e946e7SWyllys Ingersoll 		return (ERR_FAIL);
63047e946e7SWyllys Ingersoll 	ValidationData.ulValidationDataLength = sizeof (digest);
63147e946e7SWyllys Ingersoll 	ValidationData.rgbValidationData = (BYTE *) &digest;
63247e946e7SWyllys Ingersoll 
63347e946e7SWyllys Ingersoll 	ret = Tspi_TPM_CreateEndorsementKey(hTPM, hKeyEK, &ValidationData);
63447e946e7SWyllys Ingersoll 	if (ret) {
63547e946e7SWyllys Ingersoll 		print_error(ret, gettext("Create endorsement key"));
63647e946e7SWyllys Ingersoll 		return (ERR_FAIL);
63747e946e7SWyllys Ingersoll 	}
63847e946e7SWyllys Ingersoll 
63947e946e7SWyllys Ingersoll 	return (0);
64047e946e7SWyllys Ingersoll }
64147e946e7SWyllys Ingersoll 
64247e946e7SWyllys Ingersoll /*ARGSUSED*/
64347e946e7SWyllys Ingersoll int
cmd_init(TSS_HCONTEXT hContext,TSS_HTPM hTPM,int argc,char * argv[])64447e946e7SWyllys Ingersoll cmd_init(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[])
64547e946e7SWyllys Ingersoll {
64647e946e7SWyllys Ingersoll 	TSS_RESULT ret;
64747e946e7SWyllys Ingersoll 	TSS_HOBJECT hKeySRK;
64847e946e7SWyllys Ingersoll 
649304d8f90SScott Rotondo 	if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP,
650304d8f90SScott Rotondo 	    gettext("= TPM owner passphrase ="), 0, NULL))
65147e946e7SWyllys Ingersoll 		return (ERR_FAIL);
65247e946e7SWyllys Ingersoll 
65347e946e7SWyllys Ingersoll 	ret = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY,
65447e946e7SWyllys Ingersoll 	    TSS_KEY_TSP_SRK | TSS_KEY_AUTHORIZATION, &hKeySRK);
65547e946e7SWyllys Ingersoll 	if (ret) {
65647e946e7SWyllys Ingersoll 		print_error(ret, gettext("Create storage root key"));
65747e946e7SWyllys Ingersoll 		return (ERR_FAIL);
65847e946e7SWyllys Ingersoll 	}
65947e946e7SWyllys Ingersoll 
660304d8f90SScott Rotondo 	if (set_object_policy(hKeySRK, TSS_SECRET_MODE_SHA1, NULL,
66147e946e7SWyllys Ingersoll 	    sizeof (well_known), well_known))
66247e946e7SWyllys Ingersoll 		return (ERR_FAIL);
66347e946e7SWyllys Ingersoll 
664*6f2b04a2SToomas Soome 	ret = Tspi_TPM_TakeOwnership(hTPM, hKeySRK, 0);
66547e946e7SWyllys Ingersoll 	if (ret == TPM_E_NO_ENDORSEMENT) {
66647e946e7SWyllys Ingersoll 		if (createek(hContext, hTPM))
66747e946e7SWyllys Ingersoll 			return (ERR_FAIL);
668*6f2b04a2SToomas Soome 		ret = Tspi_TPM_TakeOwnership(hTPM, hKeySRK, 0);
66947e946e7SWyllys Ingersoll 	}
67047e946e7SWyllys Ingersoll 	if (ret) {
67147e946e7SWyllys Ingersoll 		print_error(ret, gettext("Take ownership"));
67247e946e7SWyllys Ingersoll 		return (ERR_FAIL);
67347e946e7SWyllys Ingersoll 	}
67447e946e7SWyllys Ingersoll 
67547e946e7SWyllys Ingersoll 	return (0);
67647e946e7SWyllys Ingersoll }
67747e946e7SWyllys Ingersoll 
67847e946e7SWyllys Ingersoll /*
67947e946e7SWyllys Ingersoll  * Auth
68047e946e7SWyllys Ingersoll  */
68147e946e7SWyllys Ingersoll 
68247e946e7SWyllys Ingersoll /*ARGSUSED*/
68347e946e7SWyllys Ingersoll int
cmd_auth(TSS_HCONTEXT hContext,TSS_HTPM hTPM,int argc,char * argv[])68447e946e7SWyllys Ingersoll cmd_auth(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[])
68547e946e7SWyllys Ingersoll {
68647e946e7SWyllys Ingersoll 	TSS_RESULT ret;
68747e946e7SWyllys Ingersoll 	TSS_HPOLICY hNewPolicy;
68847e946e7SWyllys Ingersoll 
689304d8f90SScott Rotondo 	if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP,
690304d8f90SScott Rotondo 	    gettext("= TPM owner passphrase ="), 0, NULL))
69147e946e7SWyllys Ingersoll 		return (ERR_FAIL);
69247e946e7SWyllys Ingersoll 
693304d8f90SScott Rotondo 	/* policy object for new passphrase */
69447e946e7SWyllys Ingersoll 	ret = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_POLICY,
69547e946e7SWyllys Ingersoll 	    TSS_POLICY_USAGE, &hNewPolicy);
69647e946e7SWyllys Ingersoll 	if (ret) {
69747e946e7SWyllys Ingersoll 		print_error(ret, gettext("Create policy object"));
69847e946e7SWyllys Ingersoll 		return (ERR_FAIL);
69947e946e7SWyllys Ingersoll 	}
700304d8f90SScott Rotondo 	if (set_policy_options(hNewPolicy, TSS_SECRET_MODE_POPUP,
701304d8f90SScott Rotondo 	    gettext("= New TPM owner passphrase ="), 0, NULL))
70247e946e7SWyllys Ingersoll 		return (ERR_FAIL);
70347e946e7SWyllys Ingersoll 
704*6f2b04a2SToomas Soome 	ret = Tspi_ChangeAuth(hTPM, 0, hNewPolicy);
705304d8f90SScott Rotondo 	if (ret && ret != TSP_ERROR(TSS_E_POLICY_NO_SECRET)) {
70647e946e7SWyllys Ingersoll 		print_error(ret, gettext("Change authorization"));
70747e946e7SWyllys Ingersoll 		return (ERR_FAIL);
70847e946e7SWyllys Ingersoll 	}
709304d8f90SScott Rotondo 
71047e946e7SWyllys Ingersoll 	return (0);
71147e946e7SWyllys Ingersoll }
712