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[] = { 5347e946e7SWyllys Ingersoll { "status", "", cmd_status }, 5447e946e7SWyllys Ingersoll { "init", "", cmd_init }, 5547e946e7SWyllys Ingersoll { "clear", "[owner | lock]", cmd_clear }, 5647e946e7SWyllys Ingersoll { "auth", "", cmd_auth }, 5747e946e7SWyllys Ingersoll { "keyinfo", "[uuid]", cmd_keyinfo }, 5847e946e7SWyllys Ingersoll { "deletekey", "uuid", cmd_deletekey }, 5947e946e7SWyllys Ingersoll { 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 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 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 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 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 19147e946e7SWyllys Ingersoll cmd_status(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]) 19247e946e7SWyllys Ingersoll { 193*304d8f90SScott 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 * 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 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 * 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 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 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 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) { 43247e946e7SWyllys Ingersoll 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 45947e946e7SWyllys Ingersoll 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 47647e946e7SWyllys Ingersoll 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 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 51947e946e7SWyllys Ingersoll clearowner(TSS_HTPM hTPM) 52047e946e7SWyllys Ingersoll { 52147e946e7SWyllys Ingersoll TSS_RESULT ret; 52247e946e7SWyllys Ingersoll 523*304d8f90SScott Rotondo if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP, 524*304d8f90SScott 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 53647e946e7SWyllys Ingersoll resetlock(TSS_HTPM hTPM) 53747e946e7SWyllys Ingersoll { 53847e946e7SWyllys Ingersoll TSS_RESULT ret; 53947e946e7SWyllys Ingersoll 540*304d8f90SScott Rotondo if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP, 541*304d8f90SScott 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 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 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 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 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 649*304d8f90SScott Rotondo if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP, 650*304d8f90SScott 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 660*304d8f90SScott 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 66447e946e7SWyllys Ingersoll ret = Tspi_TPM_TakeOwnership(hTPM, hKeySRK, NULL); 66547e946e7SWyllys Ingersoll if (ret == TPM_E_NO_ENDORSEMENT) { 66647e946e7SWyllys Ingersoll if (createek(hContext, hTPM)) 66747e946e7SWyllys Ingersoll return (ERR_FAIL); 66847e946e7SWyllys Ingersoll ret = Tspi_TPM_TakeOwnership(hTPM, hKeySRK, NULL); 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 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 689*304d8f90SScott Rotondo if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP, 690*304d8f90SScott Rotondo gettext("= TPM owner passphrase ="), 0, NULL)) 69147e946e7SWyllys Ingersoll return (ERR_FAIL); 69247e946e7SWyllys Ingersoll 693*304d8f90SScott 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 } 700*304d8f90SScott Rotondo if (set_policy_options(hNewPolicy, TSS_SECRET_MODE_POPUP, 701*304d8f90SScott Rotondo gettext("= New TPM owner passphrase ="), 0, NULL)) 70247e946e7SWyllys Ingersoll return (ERR_FAIL); 70347e946e7SWyllys Ingersoll 70447e946e7SWyllys Ingersoll ret = Tspi_ChangeAuth(hTPM, NULL, hNewPolicy); 705*304d8f90SScott 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 } 709*304d8f90SScott Rotondo 71047e946e7SWyllys Ingersoll return (0); 71147e946e7SWyllys Ingersoll } 712