1*9126SWyllys.Ingersoll@Sun.COM /* 2*9126SWyllys.Ingersoll@Sun.COM * CDDL HEADER START 3*9126SWyllys.Ingersoll@Sun.COM * 4*9126SWyllys.Ingersoll@Sun.COM * The contents of this file are subject to the terms of the 5*9126SWyllys.Ingersoll@Sun.COM * Common Development and Distribution License (the "License"). 6*9126SWyllys.Ingersoll@Sun.COM * You may not use this file except in compliance with the License. 7*9126SWyllys.Ingersoll@Sun.COM * 8*9126SWyllys.Ingersoll@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*9126SWyllys.Ingersoll@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*9126SWyllys.Ingersoll@Sun.COM * See the License for the specific language governing permissions 11*9126SWyllys.Ingersoll@Sun.COM * and limitations under the License. 12*9126SWyllys.Ingersoll@Sun.COM * 13*9126SWyllys.Ingersoll@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*9126SWyllys.Ingersoll@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*9126SWyllys.Ingersoll@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*9126SWyllys.Ingersoll@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*9126SWyllys.Ingersoll@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*9126SWyllys.Ingersoll@Sun.COM * 19*9126SWyllys.Ingersoll@Sun.COM * CDDL HEADER END 20*9126SWyllys.Ingersoll@Sun.COM */ 21*9126SWyllys.Ingersoll@Sun.COM 22*9126SWyllys.Ingersoll@Sun.COM /* 23*9126SWyllys.Ingersoll@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*9126SWyllys.Ingersoll@Sun.COM * Use is subject to license terms. 25*9126SWyllys.Ingersoll@Sun.COM */ 26*9126SWyllys.Ingersoll@Sun.COM 27*9126SWyllys.Ingersoll@Sun.COM #include <unistd.h> 28*9126SWyllys.Ingersoll@Sun.COM #include <stdlib.h> 29*9126SWyllys.Ingersoll@Sun.COM #include <stdio.h> 30*9126SWyllys.Ingersoll@Sun.COM #include <strings.h> 31*9126SWyllys.Ingersoll@Sun.COM #include <fcntl.h> 32*9126SWyllys.Ingersoll@Sun.COM #include <sys/types.h> 33*9126SWyllys.Ingersoll@Sun.COM #include <netinet/in.h> 34*9126SWyllys.Ingersoll@Sun.COM #include <inttypes.h> 35*9126SWyllys.Ingersoll@Sun.COM #include <sha1.h> 36*9126SWyllys.Ingersoll@Sun.COM #include <uuid/uuid.h> 37*9126SWyllys.Ingersoll@Sun.COM #include <sys/stat.h> 38*9126SWyllys.Ingersoll@Sun.COM #include <libintl.h> 39*9126SWyllys.Ingersoll@Sun.COM 40*9126SWyllys.Ingersoll@Sun.COM #include <tss/tss_defines.h> 41*9126SWyllys.Ingersoll@Sun.COM #include <tss/tspi.h> 42*9126SWyllys.Ingersoll@Sun.COM 43*9126SWyllys.Ingersoll@Sun.COM #include "tpmadm.h" 44*9126SWyllys.Ingersoll@Sun.COM 45*9126SWyllys.Ingersoll@Sun.COM int cmd_status(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]); 46*9126SWyllys.Ingersoll@Sun.COM int cmd_init(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]); 47*9126SWyllys.Ingersoll@Sun.COM int cmd_clear(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]); 48*9126SWyllys.Ingersoll@Sun.COM int cmd_auth(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]); 49*9126SWyllys.Ingersoll@Sun.COM int cmd_keyinfo(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]); 50*9126SWyllys.Ingersoll@Sun.COM int cmd_deletekey(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]); 51*9126SWyllys.Ingersoll@Sun.COM 52*9126SWyllys.Ingersoll@Sun.COM cmdtable_t commands[] = { 53*9126SWyllys.Ingersoll@Sun.COM {"status", "", cmd_status}, 54*9126SWyllys.Ingersoll@Sun.COM {"init", "", cmd_init}, 55*9126SWyllys.Ingersoll@Sun.COM {"clear", "[owner | lock]", cmd_clear}, 56*9126SWyllys.Ingersoll@Sun.COM {"auth", "", cmd_auth}, 57*9126SWyllys.Ingersoll@Sun.COM {"keyinfo", "[uuid]", cmd_keyinfo}, 58*9126SWyllys.Ingersoll@Sun.COM {"deletekey", "uuid", cmd_deletekey}, 59*9126SWyllys.Ingersoll@Sun.COM {NULL, NULL, NULL}, 60*9126SWyllys.Ingersoll@Sun.COM }; 61*9126SWyllys.Ingersoll@Sun.COM 62*9126SWyllys.Ingersoll@Sun.COM BYTE well_known[] = TSS_WELL_KNOWN_SECRET; 63*9126SWyllys.Ingersoll@Sun.COM TSS_UUID srk_uuid = TSS_UUID_SRK; 64*9126SWyllys.Ingersoll@Sun.COM 65*9126SWyllys.Ingersoll@Sun.COM 66*9126SWyllys.Ingersoll@Sun.COM /* 67*9126SWyllys.Ingersoll@Sun.COM * TPM status 68*9126SWyllys.Ingersoll@Sun.COM */ 69*9126SWyllys.Ingersoll@Sun.COM 70*9126SWyllys.Ingersoll@Sun.COM static int 71*9126SWyllys.Ingersoll@Sun.COM print_tpm_version(TSS_HCONTEXT hContext, TSS_HOBJECT hTPM) 72*9126SWyllys.Ingersoll@Sun.COM { 73*9126SWyllys.Ingersoll@Sun.COM struct { 74*9126SWyllys.Ingersoll@Sun.COM TPM_CAP_VERSION_INFO vers_info; 75*9126SWyllys.Ingersoll@Sun.COM char extra[20]; /* vendor extensions */ 76*9126SWyllys.Ingersoll@Sun.COM } info; 77*9126SWyllys.Ingersoll@Sun.COM 78*9126SWyllys.Ingersoll@Sun.COM if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_VERSION_VAL, 79*9126SWyllys.Ingersoll@Sun.COM 0, &info, sizeof (info))) 80*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 81*9126SWyllys.Ingersoll@Sun.COM 82*9126SWyllys.Ingersoll@Sun.COM (void) printf(gettext("TPM Version: %d.%d (%c%c%c%c Rev: %d.%d, " 83*9126SWyllys.Ingersoll@Sun.COM "SpecLevel: %d, ErrataRev: %d)\n"), 84*9126SWyllys.Ingersoll@Sun.COM info.vers_info.version.major, 85*9126SWyllys.Ingersoll@Sun.COM info.vers_info.version.minor, 86*9126SWyllys.Ingersoll@Sun.COM info.vers_info.tpmVendorID[0], 87*9126SWyllys.Ingersoll@Sun.COM info.vers_info.tpmVendorID[1], 88*9126SWyllys.Ingersoll@Sun.COM info.vers_info.tpmVendorID[2], 89*9126SWyllys.Ingersoll@Sun.COM info.vers_info.tpmVendorID[3], 90*9126SWyllys.Ingersoll@Sun.COM info.vers_info.version.revMajor, 91*9126SWyllys.Ingersoll@Sun.COM info.vers_info.version.revMinor, 92*9126SWyllys.Ingersoll@Sun.COM (int)ntohs(info.vers_info.specLevel), 93*9126SWyllys.Ingersoll@Sun.COM info.vers_info.errataRev); 94*9126SWyllys.Ingersoll@Sun.COM 95*9126SWyllys.Ingersoll@Sun.COM return (0); 96*9126SWyllys.Ingersoll@Sun.COM } 97*9126SWyllys.Ingersoll@Sun.COM 98*9126SWyllys.Ingersoll@Sun.COM static int 99*9126SWyllys.Ingersoll@Sun.COM tpm_is_owned(TSS_HCONTEXT hContext, TSS_HOBJECT hTPM) 100*9126SWyllys.Ingersoll@Sun.COM { 101*9126SWyllys.Ingersoll@Sun.COM BYTE owned; 102*9126SWyllys.Ingersoll@Sun.COM 103*9126SWyllys.Ingersoll@Sun.COM if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY, 104*9126SWyllys.Ingersoll@Sun.COM TSS_TPMCAP_PROP_OWNER, &owned, sizeof (owned))) 105*9126SWyllys.Ingersoll@Sun.COM return (0); 106*9126SWyllys.Ingersoll@Sun.COM 107*9126SWyllys.Ingersoll@Sun.COM return (owned); 108*9126SWyllys.Ingersoll@Sun.COM } 109*9126SWyllys.Ingersoll@Sun.COM 110*9126SWyllys.Ingersoll@Sun.COM static int 111*9126SWyllys.Ingersoll@Sun.COM print_tpm_resources(TSS_HCONTEXT hContext, TSS_HOBJECT hTPM) 112*9126SWyllys.Ingersoll@Sun.COM { 113*9126SWyllys.Ingersoll@Sun.COM UINT32 avail, max; 114*9126SWyllys.Ingersoll@Sun.COM 115*9126SWyllys.Ingersoll@Sun.COM (void) printf(gettext("TPM resources\n")); 116*9126SWyllys.Ingersoll@Sun.COM 117*9126SWyllys.Ingersoll@Sun.COM if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY, 118*9126SWyllys.Ingersoll@Sun.COM TSS_TPMCAP_PROP_MAXCONTEXTS, &max, sizeof (max))) 119*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 120*9126SWyllys.Ingersoll@Sun.COM if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY, 121*9126SWyllys.Ingersoll@Sun.COM TSS_TPMCAP_PROP_CONTEXTS, &avail, sizeof (avail))) 122*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 123*9126SWyllys.Ingersoll@Sun.COM (void) printf(gettext("\tContexts: %d/%d available\n"), avail, max); 124*9126SWyllys.Ingersoll@Sun.COM 125*9126SWyllys.Ingersoll@Sun.COM if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY, 126*9126SWyllys.Ingersoll@Sun.COM TSS_TPMCAP_PROP_MAXSESSIONS, &max, sizeof (max))) 127*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 128*9126SWyllys.Ingersoll@Sun.COM if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY, 129*9126SWyllys.Ingersoll@Sun.COM TSS_TPMCAP_PROP_SESSIONS, &avail, sizeof (avail))) 130*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 131*9126SWyllys.Ingersoll@Sun.COM (void) printf(gettext("\tSessions: %d/%d available\n"), avail, max); 132*9126SWyllys.Ingersoll@Sun.COM 133*9126SWyllys.Ingersoll@Sun.COM if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY, 134*9126SWyllys.Ingersoll@Sun.COM TSS_TPMCAP_PROP_MAXAUTHSESSIONS, &max, sizeof (max))) 135*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 136*9126SWyllys.Ingersoll@Sun.COM if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY, 137*9126SWyllys.Ingersoll@Sun.COM TSS_TPMCAP_PROP_AUTHSESSIONS, &avail, sizeof (avail))) 138*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 139*9126SWyllys.Ingersoll@Sun.COM (void) printf(gettext("\tAuth Sessions: %d/%d available\n"), 140*9126SWyllys.Ingersoll@Sun.COM avail, max); 141*9126SWyllys.Ingersoll@Sun.COM 142*9126SWyllys.Ingersoll@Sun.COM if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY, 143*9126SWyllys.Ingersoll@Sun.COM TSS_TPMCAP_PROP_MAXKEYS, &max, sizeof (max))) 144*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 145*9126SWyllys.Ingersoll@Sun.COM if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY, 146*9126SWyllys.Ingersoll@Sun.COM TSS_TPMCAP_PROP_KEYS, &avail, sizeof (avail))) 147*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 148*9126SWyllys.Ingersoll@Sun.COM (void) printf(gettext("\tLoaded Keys: %d/%d available\n"), avail, max); 149*9126SWyllys.Ingersoll@Sun.COM 150*9126SWyllys.Ingersoll@Sun.COM return (0); 151*9126SWyllys.Ingersoll@Sun.COM } 152*9126SWyllys.Ingersoll@Sun.COM 153*9126SWyllys.Ingersoll@Sun.COM static int 154*9126SWyllys.Ingersoll@Sun.COM print_tpm_pcrs(TSS_HCONTEXT hContext, TSS_HOBJECT hTPM) 155*9126SWyllys.Ingersoll@Sun.COM { 156*9126SWyllys.Ingersoll@Sun.COM UINT32 num_pcrs; 157*9126SWyllys.Ingersoll@Sun.COM int i; 158*9126SWyllys.Ingersoll@Sun.COM 159*9126SWyllys.Ingersoll@Sun.COM if (get_tpm_capability(hContext, hTPM, TSS_TPMCAP_PROPERTY, 160*9126SWyllys.Ingersoll@Sun.COM TSS_TPMCAP_PROP_PCR, &num_pcrs, sizeof (num_pcrs))) 161*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 162*9126SWyllys.Ingersoll@Sun.COM (void) printf(gettext("Platform Configuration Registers (%u)\n"), 163*9126SWyllys.Ingersoll@Sun.COM num_pcrs); 164*9126SWyllys.Ingersoll@Sun.COM 165*9126SWyllys.Ingersoll@Sun.COM /* Print each PCR */ 166*9126SWyllys.Ingersoll@Sun.COM for (i = 0; i < num_pcrs; i++) { 167*9126SWyllys.Ingersoll@Sun.COM TSS_RESULT ret; 168*9126SWyllys.Ingersoll@Sun.COM UINT32 datalen; 169*9126SWyllys.Ingersoll@Sun.COM BYTE *data; 170*9126SWyllys.Ingersoll@Sun.COM 171*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_TPM_PcrRead(hTPM, i, &datalen, &data); 172*9126SWyllys.Ingersoll@Sun.COM if (ret) { 173*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Read PCR")); 174*9126SWyllys.Ingersoll@Sun.COM return (ret); 175*9126SWyllys.Ingersoll@Sun.COM } 176*9126SWyllys.Ingersoll@Sun.COM 177*9126SWyllys.Ingersoll@Sun.COM (void) printf("\tPCR %u:\t", i); 178*9126SWyllys.Ingersoll@Sun.COM print_bytes(data, datalen, FALSE); 179*9126SWyllys.Ingersoll@Sun.COM 180*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_Context_FreeMemory(hContext, data); 181*9126SWyllys.Ingersoll@Sun.COM if (ret) { 182*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Free PCR memory")); 183*9126SWyllys.Ingersoll@Sun.COM return (ret); 184*9126SWyllys.Ingersoll@Sun.COM } 185*9126SWyllys.Ingersoll@Sun.COM } 186*9126SWyllys.Ingersoll@Sun.COM return (0); 187*9126SWyllys.Ingersoll@Sun.COM } 188*9126SWyllys.Ingersoll@Sun.COM 189*9126SWyllys.Ingersoll@Sun.COM /*ARGSUSED*/ 190*9126SWyllys.Ingersoll@Sun.COM int 191*9126SWyllys.Ingersoll@Sun.COM cmd_status(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]) 192*9126SWyllys.Ingersoll@Sun.COM { 193*9126SWyllys.Ingersoll@Sun.COM if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP, 0, NULL)) 194*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 195*9126SWyllys.Ingersoll@Sun.COM 196*9126SWyllys.Ingersoll@Sun.COM (void) print_tpm_version(hContext, hTPM); 197*9126SWyllys.Ingersoll@Sun.COM if (tpm_is_owned(hContext, hTPM)) { 198*9126SWyllys.Ingersoll@Sun.COM (void) print_tpm_resources(hContext, hTPM); 199*9126SWyllys.Ingersoll@Sun.COM (void) print_tpm_pcrs(hContext, hTPM); 200*9126SWyllys.Ingersoll@Sun.COM } else { 201*9126SWyllys.Ingersoll@Sun.COM (void) printf(gettext("No TPM owner installed.\n")); 202*9126SWyllys.Ingersoll@Sun.COM } 203*9126SWyllys.Ingersoll@Sun.COM 204*9126SWyllys.Ingersoll@Sun.COM return (0); 205*9126SWyllys.Ingersoll@Sun.COM } 206*9126SWyllys.Ingersoll@Sun.COM 207*9126SWyllys.Ingersoll@Sun.COM 208*9126SWyllys.Ingersoll@Sun.COM /* 209*9126SWyllys.Ingersoll@Sun.COM * Key Information 210*9126SWyllys.Ingersoll@Sun.COM */ 211*9126SWyllys.Ingersoll@Sun.COM 212*9126SWyllys.Ingersoll@Sun.COM typedef struct { 213*9126SWyllys.Ingersoll@Sun.COM UINT32 code; 214*9126SWyllys.Ingersoll@Sun.COM char *str; 215*9126SWyllys.Ingersoll@Sun.COM } decode_map_t; 216*9126SWyllys.Ingersoll@Sun.COM 217*9126SWyllys.Ingersoll@Sun.COM decode_map_t key_usage[] = { 218*9126SWyllys.Ingersoll@Sun.COM { TSS_KEYUSAGE_SIGN, "Signing" }, 219*9126SWyllys.Ingersoll@Sun.COM { TSS_KEYUSAGE_STORAGE, "Storage" }, 220*9126SWyllys.Ingersoll@Sun.COM { TSS_KEYUSAGE_IDENTITY, "Identity" }, 221*9126SWyllys.Ingersoll@Sun.COM { TSS_KEYUSAGE_AUTHCHANGE, "Authchange" }, 222*9126SWyllys.Ingersoll@Sun.COM { TSS_KEYUSAGE_BIND, "Bind" }, 223*9126SWyllys.Ingersoll@Sun.COM { TSS_KEYUSAGE_LEGACY, "Legacy" }, 224*9126SWyllys.Ingersoll@Sun.COM { TSS_KEYUSAGE_MIGRATE, "Migrate" }, 225*9126SWyllys.Ingersoll@Sun.COM { 0, NULL }, 226*9126SWyllys.Ingersoll@Sun.COM }; 227*9126SWyllys.Ingersoll@Sun.COM 228*9126SWyllys.Ingersoll@Sun.COM decode_map_t key_algorithm[] = { 229*9126SWyllys.Ingersoll@Sun.COM { TSS_ALG_RSA, "RSA" }, 230*9126SWyllys.Ingersoll@Sun.COM { TSS_ALG_DES, "DES" }, 231*9126SWyllys.Ingersoll@Sun.COM { TSS_ALG_3DES, "3-DES" }, 232*9126SWyllys.Ingersoll@Sun.COM { TSS_ALG_SHA, "SHA" }, 233*9126SWyllys.Ingersoll@Sun.COM { TSS_ALG_HMAC, "HMAC" }, 234*9126SWyllys.Ingersoll@Sun.COM { TSS_ALG_AES, "AES" }, 235*9126SWyllys.Ingersoll@Sun.COM { TSS_ALG_MGF1, "MGF1" }, 236*9126SWyllys.Ingersoll@Sun.COM { TSS_ALG_AES192, "AES192" }, 237*9126SWyllys.Ingersoll@Sun.COM { TSS_ALG_AES256, "AES256" }, 238*9126SWyllys.Ingersoll@Sun.COM { TSS_ALG_XOR, "XOR" }, 239*9126SWyllys.Ingersoll@Sun.COM { 0, NULL }, 240*9126SWyllys.Ingersoll@Sun.COM }; 241*9126SWyllys.Ingersoll@Sun.COM 242*9126SWyllys.Ingersoll@Sun.COM decode_map_t key_sigscheme[] = { 243*9126SWyllys.Ingersoll@Sun.COM { TSS_SS_NONE, "None" }, 244*9126SWyllys.Ingersoll@Sun.COM { TSS_SS_RSASSAPKCS1V15_SHA1, "RSASSAPKCS1v15_SHA1" }, 245*9126SWyllys.Ingersoll@Sun.COM { TSS_SS_RSASSAPKCS1V15_DER, "RSASSAPKCS1v15_DER" }, 246*9126SWyllys.Ingersoll@Sun.COM { 0, NULL }, 247*9126SWyllys.Ingersoll@Sun.COM }; 248*9126SWyllys.Ingersoll@Sun.COM 249*9126SWyllys.Ingersoll@Sun.COM decode_map_t key_encscheme[] = { 250*9126SWyllys.Ingersoll@Sun.COM { TSS_ES_NONE, "None" }, 251*9126SWyllys.Ingersoll@Sun.COM { TSS_ES_RSAESPKCSV15, "RSAESPKCSv15" }, 252*9126SWyllys.Ingersoll@Sun.COM { TSS_ES_RSAESOAEP_SHA1_MGF1, "RSAESOAEP_SHA1_MGF1" }, 253*9126SWyllys.Ingersoll@Sun.COM { TSS_ES_SYM_CNT, "SYM_CNT" }, 254*9126SWyllys.Ingersoll@Sun.COM { TSS_ES_SYM_OFB, "SYM_OFB" }, 255*9126SWyllys.Ingersoll@Sun.COM { 0, NULL }, 256*9126SWyllys.Ingersoll@Sun.COM }; 257*9126SWyllys.Ingersoll@Sun.COM 258*9126SWyllys.Ingersoll@Sun.COM static char * 259*9126SWyllys.Ingersoll@Sun.COM decode(decode_map_t *table, UINT32 code) 260*9126SWyllys.Ingersoll@Sun.COM { 261*9126SWyllys.Ingersoll@Sun.COM static char buf[20]; 262*9126SWyllys.Ingersoll@Sun.COM int i; 263*9126SWyllys.Ingersoll@Sun.COM 264*9126SWyllys.Ingersoll@Sun.COM for (i = 0; table[i].str != NULL; i++) { 265*9126SWyllys.Ingersoll@Sun.COM if (table[i].code == code) 266*9126SWyllys.Ingersoll@Sun.COM return (table[i].str); 267*9126SWyllys.Ingersoll@Sun.COM } 268*9126SWyllys.Ingersoll@Sun.COM 269*9126SWyllys.Ingersoll@Sun.COM (void) snprintf(buf, sizeof (buf), gettext("Unknown (%u)"), code); 270*9126SWyllys.Ingersoll@Sun.COM return (buf); 271*9126SWyllys.Ingersoll@Sun.COM } 272*9126SWyllys.Ingersoll@Sun.COM 273*9126SWyllys.Ingersoll@Sun.COM static void 274*9126SWyllys.Ingersoll@Sun.COM print_key_info(TSS_HCONTEXT hContext, TSS_HOBJECT hKey) 275*9126SWyllys.Ingersoll@Sun.COM { 276*9126SWyllys.Ingersoll@Sun.COM TSS_RESULT ret; 277*9126SWyllys.Ingersoll@Sun.COM UINT32 attrib; 278*9126SWyllys.Ingersoll@Sun.COM UINT32 keyInfoSize; 279*9126SWyllys.Ingersoll@Sun.COM BYTE *keyInfo; 280*9126SWyllys.Ingersoll@Sun.COM 281*9126SWyllys.Ingersoll@Sun.COM /* Key size */ 282*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO, 283*9126SWyllys.Ingersoll@Sun.COM TSS_TSPATTRIB_KEYINFO_SIZE, &attrib); 284*9126SWyllys.Ingersoll@Sun.COM if (ret) { 285*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Get key size")); 286*9126SWyllys.Ingersoll@Sun.COM } 287*9126SWyllys.Ingersoll@Sun.COM (void) printf(gettext("Key Size: %d bits\n"), attrib); 288*9126SWyllys.Ingersoll@Sun.COM 289*9126SWyllys.Ingersoll@Sun.COM /* Key usage */ 290*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO, 291*9126SWyllys.Ingersoll@Sun.COM TSS_TSPATTRIB_KEYINFO_USAGE, &attrib); 292*9126SWyllys.Ingersoll@Sun.COM if (ret) { 293*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Get key usage")); 294*9126SWyllys.Ingersoll@Sun.COM } 295*9126SWyllys.Ingersoll@Sun.COM (void) printf(gettext("Key Usage: %s\n"), decode(key_usage, attrib)); 296*9126SWyllys.Ingersoll@Sun.COM 297*9126SWyllys.Ingersoll@Sun.COM /* Algorithm */ 298*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO, 299*9126SWyllys.Ingersoll@Sun.COM TSS_TSPATTRIB_KEYINFO_ALGORITHM, &attrib); 300*9126SWyllys.Ingersoll@Sun.COM if (ret) { 301*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Get key algorithm")); 302*9126SWyllys.Ingersoll@Sun.COM } 303*9126SWyllys.Ingersoll@Sun.COM (void) printf(gettext("Algorithm: %s\n"), 304*9126SWyllys.Ingersoll@Sun.COM decode(key_algorithm, attrib)); 305*9126SWyllys.Ingersoll@Sun.COM 306*9126SWyllys.Ingersoll@Sun.COM /* Authorization required */ 307*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO, 308*9126SWyllys.Ingersoll@Sun.COM TSS_TSPATTRIB_KEYINFO_AUTHUSAGE, &attrib); 309*9126SWyllys.Ingersoll@Sun.COM if (ret) { 310*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Get key authusage")); 311*9126SWyllys.Ingersoll@Sun.COM } 312*9126SWyllys.Ingersoll@Sun.COM (void) printf(gettext("Authorization required: %s\n"), 313*9126SWyllys.Ingersoll@Sun.COM attrib ? gettext("Yes") : gettext("No")); 314*9126SWyllys.Ingersoll@Sun.COM 315*9126SWyllys.Ingersoll@Sun.COM /* Signature scheme */ 316*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO, 317*9126SWyllys.Ingersoll@Sun.COM TSS_TSPATTRIB_KEYINFO_SIGSCHEME, &attrib); 318*9126SWyllys.Ingersoll@Sun.COM if (ret) { 319*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Get key signature scheme")); 320*9126SWyllys.Ingersoll@Sun.COM } 321*9126SWyllys.Ingersoll@Sun.COM (void) printf(gettext("Signature scheme: %s\n"), 322*9126SWyllys.Ingersoll@Sun.COM decode(key_sigscheme, attrib)); 323*9126SWyllys.Ingersoll@Sun.COM 324*9126SWyllys.Ingersoll@Sun.COM /* Encoding scheme */ 325*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_GetAttribUint32(hKey, TSS_TSPATTRIB_KEY_INFO, 326*9126SWyllys.Ingersoll@Sun.COM TSS_TSPATTRIB_KEYINFO_ENCSCHEME, &attrib); 327*9126SWyllys.Ingersoll@Sun.COM if (ret) { 328*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Get key encoding scheme")); 329*9126SWyllys.Ingersoll@Sun.COM } 330*9126SWyllys.Ingersoll@Sun.COM (void) printf(gettext("Encoding scheme: %s\n"), 331*9126SWyllys.Ingersoll@Sun.COM decode(key_encscheme, attrib)); 332*9126SWyllys.Ingersoll@Sun.COM 333*9126SWyllys.Ingersoll@Sun.COM /* Key blob */ 334*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_GetAttribData(hKey, TSS_TSPATTRIB_KEY_BLOB, 335*9126SWyllys.Ingersoll@Sun.COM TSS_TSPATTRIB_KEYBLOB_BLOB, &keyInfoSize, &keyInfo); 336*9126SWyllys.Ingersoll@Sun.COM if (ret) { 337*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Get key blob")); 338*9126SWyllys.Ingersoll@Sun.COM } 339*9126SWyllys.Ingersoll@Sun.COM (void) printf(gettext("TPM Key Blob:\n")); 340*9126SWyllys.Ingersoll@Sun.COM print_bytes(keyInfo, keyInfoSize, TRUE); 341*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_Context_FreeMemory(hContext, keyInfo); 342*9126SWyllys.Ingersoll@Sun.COM if (ret) { 343*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Free key info buffer")); 344*9126SWyllys.Ingersoll@Sun.COM } 345*9126SWyllys.Ingersoll@Sun.COM } 346*9126SWyllys.Ingersoll@Sun.COM 347*9126SWyllys.Ingersoll@Sun.COM typedef struct hash_node { 348*9126SWyllys.Ingersoll@Sun.COM struct hash_node *next, *sibling, *child; 349*9126SWyllys.Ingersoll@Sun.COM TSS_UUID uuid; 350*9126SWyllys.Ingersoll@Sun.COM TSS_KM_KEYINFO2 *key_data; 351*9126SWyllys.Ingersoll@Sun.COM } hash_node_t; 352*9126SWyllys.Ingersoll@Sun.COM 353*9126SWyllys.Ingersoll@Sun.COM #define HASHSIZE 17 354*9126SWyllys.Ingersoll@Sun.COM hash_node_t *hash_table[HASHSIZE]; 355*9126SWyllys.Ingersoll@Sun.COM 356*9126SWyllys.Ingersoll@Sun.COM static hash_node_t * 357*9126SWyllys.Ingersoll@Sun.COM hash_insert(TSS_UUID uuid, TSS_KM_KEYINFO2 *key_data) 358*9126SWyllys.Ingersoll@Sun.COM { 359*9126SWyllys.Ingersoll@Sun.COM UINT32 i, index = 0; 360*9126SWyllys.Ingersoll@Sun.COM hash_node_t *node; 361*9126SWyllys.Ingersoll@Sun.COM char *cp; 362*9126SWyllys.Ingersoll@Sun.COM 363*9126SWyllys.Ingersoll@Sun.COM cp = (char *)&uuid; 364*9126SWyllys.Ingersoll@Sun.COM for (i = 0; i < sizeof (TSS_UUID); i++) 365*9126SWyllys.Ingersoll@Sun.COM index += cp[i]; 366*9126SWyllys.Ingersoll@Sun.COM index = index % HASHSIZE; 367*9126SWyllys.Ingersoll@Sun.COM 368*9126SWyllys.Ingersoll@Sun.COM for (node = hash_table[index]; node != NULL; node = node->next) { 369*9126SWyllys.Ingersoll@Sun.COM if (memcmp(&(node->uuid), &uuid, sizeof (TSS_UUID)) == 0) 370*9126SWyllys.Ingersoll@Sun.COM break; 371*9126SWyllys.Ingersoll@Sun.COM } 372*9126SWyllys.Ingersoll@Sun.COM 373*9126SWyllys.Ingersoll@Sun.COM if (node == NULL) { 374*9126SWyllys.Ingersoll@Sun.COM node = calloc(1, sizeof (hash_node_t)); 375*9126SWyllys.Ingersoll@Sun.COM node->uuid = uuid; 376*9126SWyllys.Ingersoll@Sun.COM node->next = hash_table[index]; 377*9126SWyllys.Ingersoll@Sun.COM hash_table[index] = node; 378*9126SWyllys.Ingersoll@Sun.COM } 379*9126SWyllys.Ingersoll@Sun.COM if (node->key_data == NULL) 380*9126SWyllys.Ingersoll@Sun.COM node->key_data = key_data; 381*9126SWyllys.Ingersoll@Sun.COM 382*9126SWyllys.Ingersoll@Sun.COM return (node); 383*9126SWyllys.Ingersoll@Sun.COM } 384*9126SWyllys.Ingersoll@Sun.COM 385*9126SWyllys.Ingersoll@Sun.COM static void 386*9126SWyllys.Ingersoll@Sun.COM add_child(hash_node_t *parent, hash_node_t *child) 387*9126SWyllys.Ingersoll@Sun.COM { 388*9126SWyllys.Ingersoll@Sun.COM hash_node_t *node; 389*9126SWyllys.Ingersoll@Sun.COM 390*9126SWyllys.Ingersoll@Sun.COM for (node = parent->child; node != NULL; node = node->next) { 391*9126SWyllys.Ingersoll@Sun.COM if (node == child) 392*9126SWyllys.Ingersoll@Sun.COM return; 393*9126SWyllys.Ingersoll@Sun.COM } 394*9126SWyllys.Ingersoll@Sun.COM 395*9126SWyllys.Ingersoll@Sun.COM child->sibling = parent->child; 396*9126SWyllys.Ingersoll@Sun.COM parent->child = child; 397*9126SWyllys.Ingersoll@Sun.COM } 398*9126SWyllys.Ingersoll@Sun.COM 399*9126SWyllys.Ingersoll@Sun.COM static void 400*9126SWyllys.Ingersoll@Sun.COM print_all(hash_node_t *parent, int indent) 401*9126SWyllys.Ingersoll@Sun.COM { 402*9126SWyllys.Ingersoll@Sun.COM char uuidstr[UUID_PRINTABLE_STRING_LENGTH]; 403*9126SWyllys.Ingersoll@Sun.COM hash_node_t *node; 404*9126SWyllys.Ingersoll@Sun.COM char *type, *loaded; 405*9126SWyllys.Ingersoll@Sun.COM 406*9126SWyllys.Ingersoll@Sun.COM uuid_unparse(*(uuid_t *)&parent->uuid, uuidstr); 407*9126SWyllys.Ingersoll@Sun.COM type = (parent->key_data->persistentStorageType == TSS_PS_TYPE_USER) ? 408*9126SWyllys.Ingersoll@Sun.COM "USER" : "SYSTEM"; 409*9126SWyllys.Ingersoll@Sun.COM loaded = parent->key_data->fIsLoaded ? "(loaded)" : ""; 410*9126SWyllys.Ingersoll@Sun.COM (void) printf("%*s[%s] %s %s\n", indent, "", 411*9126SWyllys.Ingersoll@Sun.COM type, uuidstr, loaded); 412*9126SWyllys.Ingersoll@Sun.COM 413*9126SWyllys.Ingersoll@Sun.COM for (node = parent->child; node != NULL; node = node->sibling) 414*9126SWyllys.Ingersoll@Sun.COM print_all(node, indent + 4); 415*9126SWyllys.Ingersoll@Sun.COM } 416*9126SWyllys.Ingersoll@Sun.COM 417*9126SWyllys.Ingersoll@Sun.COM /*ARGSUSED*/ 418*9126SWyllys.Ingersoll@Sun.COM int 419*9126SWyllys.Ingersoll@Sun.COM cmd_keyinfo(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]) 420*9126SWyllys.Ingersoll@Sun.COM { 421*9126SWyllys.Ingersoll@Sun.COM TSS_RESULT ret; 422*9126SWyllys.Ingersoll@Sun.COM UINT32 i, num_keys; 423*9126SWyllys.Ingersoll@Sun.COM TSS_KM_KEYINFO2 *keys; 424*9126SWyllys.Ingersoll@Sun.COM hash_node_t *parent, *child, *srk = NULL; 425*9126SWyllys.Ingersoll@Sun.COM TSS_HKEY hKey; 426*9126SWyllys.Ingersoll@Sun.COM union { 427*9126SWyllys.Ingersoll@Sun.COM uuid_t arr_uuid; 428*9126SWyllys.Ingersoll@Sun.COM TSS_UUID tss_uuid; 429*9126SWyllys.Ingersoll@Sun.COM } uuid; 430*9126SWyllys.Ingersoll@Sun.COM 431*9126SWyllys.Ingersoll@Sun.COM switch (argc) { 432*9126SWyllys.Ingersoll@Sun.COM case 1: 433*9126SWyllys.Ingersoll@Sun.COM /* Print key hierarchy */ 434*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_Context_GetRegisteredKeysByUUID2(hContext, 435*9126SWyllys.Ingersoll@Sun.COM TSS_PS_TYPE_USER, NULL, &num_keys, &keys); 436*9126SWyllys.Ingersoll@Sun.COM if (ret) { 437*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Get key hierarchy")); 438*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 439*9126SWyllys.Ingersoll@Sun.COM } 440*9126SWyllys.Ingersoll@Sun.COM 441*9126SWyllys.Ingersoll@Sun.COM for (i = 0; i < num_keys; i++) { 442*9126SWyllys.Ingersoll@Sun.COM parent = hash_insert(keys[i].parentKeyUUID, NULL); 443*9126SWyllys.Ingersoll@Sun.COM child = hash_insert(keys[i].keyUUID, &keys[i]); 444*9126SWyllys.Ingersoll@Sun.COM add_child(parent, child); 445*9126SWyllys.Ingersoll@Sun.COM if (memcmp(&(keys[i].keyUUID), &srk_uuid, 446*9126SWyllys.Ingersoll@Sun.COM sizeof (TSS_UUID)) == 0) 447*9126SWyllys.Ingersoll@Sun.COM srk = child; 448*9126SWyllys.Ingersoll@Sun.COM } 449*9126SWyllys.Ingersoll@Sun.COM 450*9126SWyllys.Ingersoll@Sun.COM if (srk != NULL) 451*9126SWyllys.Ingersoll@Sun.COM print_all(srk, 0); 452*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_Context_FreeMemory(hContext, (BYTE *) keys); 453*9126SWyllys.Ingersoll@Sun.COM if (ret) { 454*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Free key list")); 455*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 456*9126SWyllys.Ingersoll@Sun.COM } 457*9126SWyllys.Ingersoll@Sun.COM return (0); 458*9126SWyllys.Ingersoll@Sun.COM 459*9126SWyllys.Ingersoll@Sun.COM case 2: 460*9126SWyllys.Ingersoll@Sun.COM /* Print detailed info about a single key */ 461*9126SWyllys.Ingersoll@Sun.COM if (uuid_parse(argv[1], uuid.arr_uuid)) 462*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 463*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_Context_GetKeyByUUID(hContext, TSS_PS_TYPE_USER, 464*9126SWyllys.Ingersoll@Sun.COM uuid.tss_uuid, &hKey); 465*9126SWyllys.Ingersoll@Sun.COM if (ret == TSP_ERROR(TSS_E_PS_KEY_NOTFOUND)) { 466*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_Context_GetKeyByUUID(hContext, 467*9126SWyllys.Ingersoll@Sun.COM TSS_PS_TYPE_SYSTEM, uuid.tss_uuid, &hKey); 468*9126SWyllys.Ingersoll@Sun.COM } 469*9126SWyllys.Ingersoll@Sun.COM if (ret) { 470*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Get key by UUID")); 471*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 472*9126SWyllys.Ingersoll@Sun.COM } 473*9126SWyllys.Ingersoll@Sun.COM print_key_info(hContext, hKey); 474*9126SWyllys.Ingersoll@Sun.COM return (0); 475*9126SWyllys.Ingersoll@Sun.COM 476*9126SWyllys.Ingersoll@Sun.COM default: 477*9126SWyllys.Ingersoll@Sun.COM (void) fprintf(stderr, gettext("Usage:\n")); 478*9126SWyllys.Ingersoll@Sun.COM (void) fprintf(stderr, "\tkeyinfo [uuid]\n"); 479*9126SWyllys.Ingersoll@Sun.COM return (ERR_USAGE); 480*9126SWyllys.Ingersoll@Sun.COM } 481*9126SWyllys.Ingersoll@Sun.COM } 482*9126SWyllys.Ingersoll@Sun.COM 483*9126SWyllys.Ingersoll@Sun.COM /*ARGSUSED*/ 484*9126SWyllys.Ingersoll@Sun.COM int 485*9126SWyllys.Ingersoll@Sun.COM cmd_deletekey(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]) 486*9126SWyllys.Ingersoll@Sun.COM { 487*9126SWyllys.Ingersoll@Sun.COM TSS_RESULT ret; 488*9126SWyllys.Ingersoll@Sun.COM TSS_HOBJECT hKey; 489*9126SWyllys.Ingersoll@Sun.COM union { 490*9126SWyllys.Ingersoll@Sun.COM uuid_t arr_uuid; 491*9126SWyllys.Ingersoll@Sun.COM TSS_UUID tss_uuid; 492*9126SWyllys.Ingersoll@Sun.COM } uuid; 493*9126SWyllys.Ingersoll@Sun.COM 494*9126SWyllys.Ingersoll@Sun.COM if (argc < 2) { 495*9126SWyllys.Ingersoll@Sun.COM (void) fprintf(stderr, gettext("Usage:\n")); 496*9126SWyllys.Ingersoll@Sun.COM (void) fprintf(stderr, "\tdeletekey [uuid]\n"); 497*9126SWyllys.Ingersoll@Sun.COM return (ERR_USAGE); 498*9126SWyllys.Ingersoll@Sun.COM } 499*9126SWyllys.Ingersoll@Sun.COM if (uuid_parse(argv[1], uuid.arr_uuid)) 500*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 501*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_Context_UnregisterKey(hContext, TSS_PS_TYPE_USER, 502*9126SWyllys.Ingersoll@Sun.COM uuid.tss_uuid, &hKey); 503*9126SWyllys.Ingersoll@Sun.COM if (ret == TSP_ERROR(TSS_E_PS_KEY_NOTFOUND)) { 504*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_Context_UnregisterKey(hContext, TSS_PS_TYPE_SYSTEM, 505*9126SWyllys.Ingersoll@Sun.COM uuid.tss_uuid, &hKey); 506*9126SWyllys.Ingersoll@Sun.COM } 507*9126SWyllys.Ingersoll@Sun.COM if (ret) { 508*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Unregister key")); 509*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 510*9126SWyllys.Ingersoll@Sun.COM } 511*9126SWyllys.Ingersoll@Sun.COM return (0); 512*9126SWyllys.Ingersoll@Sun.COM } 513*9126SWyllys.Ingersoll@Sun.COM 514*9126SWyllys.Ingersoll@Sun.COM /* 515*9126SWyllys.Ingersoll@Sun.COM * Clear 516*9126SWyllys.Ingersoll@Sun.COM */ 517*9126SWyllys.Ingersoll@Sun.COM 518*9126SWyllys.Ingersoll@Sun.COM static int 519*9126SWyllys.Ingersoll@Sun.COM clearowner(TSS_HTPM hTPM) 520*9126SWyllys.Ingersoll@Sun.COM { 521*9126SWyllys.Ingersoll@Sun.COM TSS_RESULT ret; 522*9126SWyllys.Ingersoll@Sun.COM 523*9126SWyllys.Ingersoll@Sun.COM if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP, 0, NULL)) 524*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 525*9126SWyllys.Ingersoll@Sun.COM 526*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_TPM_ClearOwner(hTPM, FALSE); 527*9126SWyllys.Ingersoll@Sun.COM if (ret) { 528*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Clear TPM owner")); 529*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 530*9126SWyllys.Ingersoll@Sun.COM } 531*9126SWyllys.Ingersoll@Sun.COM return (0); 532*9126SWyllys.Ingersoll@Sun.COM } 533*9126SWyllys.Ingersoll@Sun.COM 534*9126SWyllys.Ingersoll@Sun.COM static int 535*9126SWyllys.Ingersoll@Sun.COM resetlock(TSS_HTPM hTPM) 536*9126SWyllys.Ingersoll@Sun.COM { 537*9126SWyllys.Ingersoll@Sun.COM TSS_RESULT ret; 538*9126SWyllys.Ingersoll@Sun.COM 539*9126SWyllys.Ingersoll@Sun.COM if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP, 0, NULL)) 540*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 541*9126SWyllys.Ingersoll@Sun.COM 542*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_TPM_SetStatus(hTPM, TSS_TPMSTATUS_RESETLOCK, TRUE); 543*9126SWyllys.Ingersoll@Sun.COM if (ret) { 544*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Reset Lock")); 545*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 546*9126SWyllys.Ingersoll@Sun.COM } 547*9126SWyllys.Ingersoll@Sun.COM return (0); 548*9126SWyllys.Ingersoll@Sun.COM } 549*9126SWyllys.Ingersoll@Sun.COM 550*9126SWyllys.Ingersoll@Sun.COM /*ARGSUSED*/ 551*9126SWyllys.Ingersoll@Sun.COM int 552*9126SWyllys.Ingersoll@Sun.COM cmd_clear(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]) 553*9126SWyllys.Ingersoll@Sun.COM { 554*9126SWyllys.Ingersoll@Sun.COM char *subcmd = argv[1]; 555*9126SWyllys.Ingersoll@Sun.COM 556*9126SWyllys.Ingersoll@Sun.COM if (subcmd && strcmp(subcmd, "lock") == 0) { 557*9126SWyllys.Ingersoll@Sun.COM return (resetlock(hTPM)); 558*9126SWyllys.Ingersoll@Sun.COM } else if (subcmd && strcmp(subcmd, "owner") == 0) { 559*9126SWyllys.Ingersoll@Sun.COM return (clearowner(hTPM)); 560*9126SWyllys.Ingersoll@Sun.COM } else { 561*9126SWyllys.Ingersoll@Sun.COM (void) fprintf(stderr, gettext("Usage:\n")); 562*9126SWyllys.Ingersoll@Sun.COM (void) fprintf(stderr, "\tclear owner\n"); 563*9126SWyllys.Ingersoll@Sun.COM (void) fprintf(stderr, "\tclear lock\n"); 564*9126SWyllys.Ingersoll@Sun.COM return (ERR_USAGE); 565*9126SWyllys.Ingersoll@Sun.COM } 566*9126SWyllys.Ingersoll@Sun.COM } 567*9126SWyllys.Ingersoll@Sun.COM 568*9126SWyllys.Ingersoll@Sun.COM 569*9126SWyllys.Ingersoll@Sun.COM /* 570*9126SWyllys.Ingersoll@Sun.COM * TPM initialization 571*9126SWyllys.Ingersoll@Sun.COM */ 572*9126SWyllys.Ingersoll@Sun.COM 573*9126SWyllys.Ingersoll@Sun.COM static int 574*9126SWyllys.Ingersoll@Sun.COM get_random(UINT32 size, BYTE *randomBytes) 575*9126SWyllys.Ingersoll@Sun.COM { 576*9126SWyllys.Ingersoll@Sun.COM int fd, len; 577*9126SWyllys.Ingersoll@Sun.COM BYTE *buf; 578*9126SWyllys.Ingersoll@Sun.COM 579*9126SWyllys.Ingersoll@Sun.COM fd = open("/dev/random", O_RDONLY); 580*9126SWyllys.Ingersoll@Sun.COM if (fd == -1) { 581*9126SWyllys.Ingersoll@Sun.COM (void) fprintf(stderr, gettext("Unable to open /dev/random")); 582*9126SWyllys.Ingersoll@Sun.COM return (-1); 583*9126SWyllys.Ingersoll@Sun.COM } 584*9126SWyllys.Ingersoll@Sun.COM 585*9126SWyllys.Ingersoll@Sun.COM buf = randomBytes; 586*9126SWyllys.Ingersoll@Sun.COM while (size > 0) { 587*9126SWyllys.Ingersoll@Sun.COM len = read(fd, buf, size); 588*9126SWyllys.Ingersoll@Sun.COM if (len <= 0) { 589*9126SWyllys.Ingersoll@Sun.COM (void) close(fd); 590*9126SWyllys.Ingersoll@Sun.COM (void) fprintf(stderr, 591*9126SWyllys.Ingersoll@Sun.COM gettext("Error reading /dev/random")); 592*9126SWyllys.Ingersoll@Sun.COM return (-1); 593*9126SWyllys.Ingersoll@Sun.COM } 594*9126SWyllys.Ingersoll@Sun.COM size -= len; 595*9126SWyllys.Ingersoll@Sun.COM buf += len; 596*9126SWyllys.Ingersoll@Sun.COM } 597*9126SWyllys.Ingersoll@Sun.COM 598*9126SWyllys.Ingersoll@Sun.COM (void) close(fd); 599*9126SWyllys.Ingersoll@Sun.COM return (0); 600*9126SWyllys.Ingersoll@Sun.COM } 601*9126SWyllys.Ingersoll@Sun.COM 602*9126SWyllys.Ingersoll@Sun.COM static int 603*9126SWyllys.Ingersoll@Sun.COM createek(TSS_HCONTEXT hContext, TSS_HTPM hTPM) 604*9126SWyllys.Ingersoll@Sun.COM { 605*9126SWyllys.Ingersoll@Sun.COM TSS_RESULT ret; 606*9126SWyllys.Ingersoll@Sun.COM TSS_HOBJECT hKeyEK; 607*9126SWyllys.Ingersoll@Sun.COM TSS_VALIDATION ValidationData; 608*9126SWyllys.Ingersoll@Sun.COM TPM_NONCE nonce; 609*9126SWyllys.Ingersoll@Sun.COM TPM_DIGEST digest; 610*9126SWyllys.Ingersoll@Sun.COM 611*9126SWyllys.Ingersoll@Sun.COM /* Create the empty key struct for EK */ 612*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY, 613*9126SWyllys.Ingersoll@Sun.COM (TSS_KEY_NO_AUTHORIZATION | TSS_KEY_NON_VOLATILE | 614*9126SWyllys.Ingersoll@Sun.COM TSS_KEY_NOT_MIGRATABLE | TSS_KEY_TYPE_STORAGE | 615*9126SWyllys.Ingersoll@Sun.COM TSS_KEY_SIZE_2048 | TSS_KEY_NOT_CERTIFIED_MIGRATABLE | 616*9126SWyllys.Ingersoll@Sun.COM TSS_KEY_STRUCT_KEY12 | TSS_KEY_EMPTY_KEY), 617*9126SWyllys.Ingersoll@Sun.COM &hKeyEK); 618*9126SWyllys.Ingersoll@Sun.COM if (ret) { 619*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Create endorsement key object")); 620*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 621*9126SWyllys.Ingersoll@Sun.COM } 622*9126SWyllys.Ingersoll@Sun.COM 623*9126SWyllys.Ingersoll@Sun.COM ValidationData.ulExternalDataLength = sizeof (nonce); 624*9126SWyllys.Ingersoll@Sun.COM ValidationData.rgbExternalData = (BYTE *) &nonce; 625*9126SWyllys.Ingersoll@Sun.COM ret = get_random(sizeof (nonce), (BYTE *) &nonce); 626*9126SWyllys.Ingersoll@Sun.COM if (ret) 627*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 628*9126SWyllys.Ingersoll@Sun.COM ValidationData.ulValidationDataLength = sizeof (digest); 629*9126SWyllys.Ingersoll@Sun.COM ValidationData.rgbValidationData = (BYTE *) &digest; 630*9126SWyllys.Ingersoll@Sun.COM 631*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_TPM_CreateEndorsementKey(hTPM, hKeyEK, &ValidationData); 632*9126SWyllys.Ingersoll@Sun.COM if (ret) { 633*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Create endorsement key")); 634*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 635*9126SWyllys.Ingersoll@Sun.COM } 636*9126SWyllys.Ingersoll@Sun.COM 637*9126SWyllys.Ingersoll@Sun.COM return (0); 638*9126SWyllys.Ingersoll@Sun.COM } 639*9126SWyllys.Ingersoll@Sun.COM 640*9126SWyllys.Ingersoll@Sun.COM /*ARGSUSED*/ 641*9126SWyllys.Ingersoll@Sun.COM int 642*9126SWyllys.Ingersoll@Sun.COM cmd_init(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]) 643*9126SWyllys.Ingersoll@Sun.COM { 644*9126SWyllys.Ingersoll@Sun.COM TSS_RESULT ret; 645*9126SWyllys.Ingersoll@Sun.COM TSS_HOBJECT hKeySRK; 646*9126SWyllys.Ingersoll@Sun.COM 647*9126SWyllys.Ingersoll@Sun.COM if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP, 0, NULL)) 648*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 649*9126SWyllys.Ingersoll@Sun.COM 650*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_RSAKEY, 651*9126SWyllys.Ingersoll@Sun.COM TSS_KEY_TSP_SRK | TSS_KEY_AUTHORIZATION, &hKeySRK); 652*9126SWyllys.Ingersoll@Sun.COM if (ret) { 653*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Create storage root key")); 654*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 655*9126SWyllys.Ingersoll@Sun.COM } 656*9126SWyllys.Ingersoll@Sun.COM 657*9126SWyllys.Ingersoll@Sun.COM if (set_object_policy(hKeySRK, TSS_SECRET_MODE_SHA1, 658*9126SWyllys.Ingersoll@Sun.COM sizeof (well_known), well_known)) 659*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 660*9126SWyllys.Ingersoll@Sun.COM 661*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_TPM_TakeOwnership(hTPM, hKeySRK, NULL); 662*9126SWyllys.Ingersoll@Sun.COM if (ret == TPM_E_NO_ENDORSEMENT) { 663*9126SWyllys.Ingersoll@Sun.COM if (createek(hContext, hTPM)) 664*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 665*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_TPM_TakeOwnership(hTPM, hKeySRK, NULL); 666*9126SWyllys.Ingersoll@Sun.COM } 667*9126SWyllys.Ingersoll@Sun.COM if (ret) { 668*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Take ownership")); 669*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 670*9126SWyllys.Ingersoll@Sun.COM } 671*9126SWyllys.Ingersoll@Sun.COM 672*9126SWyllys.Ingersoll@Sun.COM return (0); 673*9126SWyllys.Ingersoll@Sun.COM } 674*9126SWyllys.Ingersoll@Sun.COM 675*9126SWyllys.Ingersoll@Sun.COM /* 676*9126SWyllys.Ingersoll@Sun.COM * Auth 677*9126SWyllys.Ingersoll@Sun.COM */ 678*9126SWyllys.Ingersoll@Sun.COM 679*9126SWyllys.Ingersoll@Sun.COM /*ARGSUSED*/ 680*9126SWyllys.Ingersoll@Sun.COM int 681*9126SWyllys.Ingersoll@Sun.COM cmd_auth(TSS_HCONTEXT hContext, TSS_HTPM hTPM, int argc, char *argv[]) 682*9126SWyllys.Ingersoll@Sun.COM { 683*9126SWyllys.Ingersoll@Sun.COM TSS_RESULT ret; 684*9126SWyllys.Ingersoll@Sun.COM TSS_HPOLICY hNewPolicy; 685*9126SWyllys.Ingersoll@Sun.COM 686*9126SWyllys.Ingersoll@Sun.COM if (set_object_policy(hTPM, TSS_SECRET_MODE_POPUP, 0, NULL)) 687*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 688*9126SWyllys.Ingersoll@Sun.COM 689*9126SWyllys.Ingersoll@Sun.COM /* new policy object */ 690*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_Context_CreateObject(hContext, TSS_OBJECT_TYPE_POLICY, 691*9126SWyllys.Ingersoll@Sun.COM TSS_POLICY_USAGE, &hNewPolicy); 692*9126SWyllys.Ingersoll@Sun.COM if (ret) { 693*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Create policy object")); 694*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 695*9126SWyllys.Ingersoll@Sun.COM } 696*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_Policy_SetSecret(hNewPolicy, TSS_SECRET_MODE_POPUP, 697*9126SWyllys.Ingersoll@Sun.COM 0, NULL); 698*9126SWyllys.Ingersoll@Sun.COM if (ret) { 699*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Set policy object secret")); 700*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 701*9126SWyllys.Ingersoll@Sun.COM } 702*9126SWyllys.Ingersoll@Sun.COM 703*9126SWyllys.Ingersoll@Sun.COM ret = Tspi_ChangeAuth(hTPM, NULL, hNewPolicy); 704*9126SWyllys.Ingersoll@Sun.COM if (ret) { 705*9126SWyllys.Ingersoll@Sun.COM print_error(ret, gettext("Change authorization")); 706*9126SWyllys.Ingersoll@Sun.COM return (ERR_FAIL); 707*9126SWyllys.Ingersoll@Sun.COM } 708*9126SWyllys.Ingersoll@Sun.COM return (0); 709*9126SWyllys.Ingersoll@Sun.COM } 710