1/* 2 * The Initial Developer of the Original Code is International 3 * Business Machines Corporation. Portions created by IBM 4 * Corporation are Copyright (C) 2005 International Business 5 * Machines Corporation. All Rights Reserved. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the Common Public License as published by 9 * IBM Corporation; either version 1 of the License, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * Common Public License for more details. 16 * 17 * You should have received a copy of the Common Public License 18 * along with this program; if not, a copy can be viewed at 19 * http://www.opensource.org/licenses/cpl1.0.php. 20 */ 21 22#include "tpm_tspi.h" 23#include "tpm_utils.h" 24 25static void help(const char *aCmd) 26{ 27 logCmdHelp(aCmd); 28 logUnicodeCmdOption(); 29 logCmdOption("-s, --status", 30 _("Report current status.")); 31 logCmdOption("-o, --owner", 32 _("Remove ability of the owner to clear TPM.")); 33 logCmdOption("-f, --force", 34 _("Remove ability to clear TPM with physical presence.\n\t\tThis action is not persistent")); 35 logCmdOption("-z, --well-known", 36 _("Use 20 bytes of zeros (TSS_WELL_KNOWN_SECRET) as the TPM secret authorization data")); 37} 38 39enum { 40 owner = 0, 41 force 42}; 43 44struct physFlag { 45 const char *name; 46 const TSS_FLAG property; 47 BOOL disable; 48}; 49 50//Controlled by input options 51static struct physFlag flags[] = { {N_("Owner Clear"), 52 TSS_TPMSTATUS_DISABLEOWNERCLEAR}, 53{N_("Force Clear"), 54 TSS_TPMSTATUS_DISABLEFORCECLEAR}, 55{0, 0, 0} 56}; 57static BOOL bCheck = FALSE; 58static BOOL bChangeRequested = FALSE; 59static BOOL isWellKnown = FALSE; 60TSS_HCONTEXT hContext = 0; 61 62static int parse(const int aOpt, const char *aArg) 63{ 64 65 switch (aOpt) { 66 case 's': 67 bCheck = TRUE; 68 break; 69 case 'o': 70 flags[owner].disable = TRUE; 71 bChangeRequested = TRUE; 72 break; 73 case 'f': 74 flags[force].disable = TRUE; 75 bChangeRequested = TRUE; 76 break; 77 case 'z': 78 logDebug(_("Using TSS_WELL_KNOWN_SECRET to authorize the TPM command\n")); 79 isWellKnown = TRUE; 80 break; 81 default: 82 return -1; 83 } 84 85 return 0; 86} 87 88/* 89 * Affect: Toggle OwnerClear and ForceClear from being available 90 * Default: Display current states 91 * Requires: Owner auth to set OwnerClear and display current states 92 */ 93 94int main(int argc, char **argv) 95{ 96 97 char *szTpmPasswd = NULL; 98 int pswd_len; 99 TSS_HTPM hTpm; 100 TSS_HPOLICY hTpmPolicy; 101 int iRc = -1; 102 int i = 0; 103 struct option opts[] = { {"status", no_argument, NULL, 's'}, 104 {"owner", no_argument, NULL, 'o'}, 105 {"force", no_argument, NULL, 'f'}, 106 {"well-known", no_argument, NULL, 'z'}, 107 }; 108 BYTE well_known[] = TSS_WELL_KNOWN_SECRET; 109 110 initIntlSys(); 111 112 if (genericOptHandler 113 (argc, argv, "ofsz", opts, sizeof(opts) / sizeof(struct option), 114 parse, help) != 0) 115 goto out; 116 117 //Connect to TSS and TPM 118 if (contextCreate(&hContext) != TSS_SUCCESS) 119 goto out; 120 121 if (contextConnect(hContext) != TSS_SUCCESS) 122 goto out_close; 123 124 if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS) 125 goto out_close; 126 127 if (bCheck || !bChangeRequested) { 128 logInfo(_("Checking current status: \n")); 129 if (isWellKnown){ 130 szTpmPasswd = (char *)well_known; 131 pswd_len = sizeof(well_known); 132 } else { 133 szTpmPasswd = GETPASSWD(_("Enter owner password: "), &pswd_len, FALSE); 134 if (!szTpmPasswd) { 135 logMsg(_("Failed to get password\n")); 136 goto out_close; 137 } 138 } 139 if (policyGet(hTpm, &hTpmPolicy) != TSS_SUCCESS) 140 goto out_close; 141 142 if (policySetSecret 143 (hTpmPolicy, 144 pswd_len, (BYTE *)szTpmPasswd) != TSS_SUCCESS) 145 goto out_close; 146 do { 147 TSS_BOOL bValue; 148 if (tpmGetStatus(hTpm, flags[i].property, &bValue) 149 != TSS_SUCCESS) 150 goto out_close; 151 152 logMsg("%s Disabled: %s\n", _(flags[i].name), 153 logBool(mapTssBool(bValue))); 154 155 } while (flags[++i].name); 156 goto out_success; 157 } 158 159 do { 160 if (flags[i].disable) { 161 logDebug(_("Requested to disable: %s ability.\n"), 162 _(flags[i].name)); 163 if (i == owner) { 164 if (isWellKnown){ 165 szTpmPasswd = (char *)well_known; 166 pswd_len = sizeof(well_known); 167 } else { 168 szTpmPasswd = GETPASSWD(_("Enter owner password: "), 169 &pswd_len, FALSE); 170 if (!szTpmPasswd) { 171 logMsg(_("Failed to get password\n")); 172 goto out_close; 173 } 174 } 175 if (policyGet(hTpm, &hTpmPolicy) != TSS_SUCCESS) 176 goto out_close; 177 178 if (policySetSecret 179 (hTpmPolicy, 180 pswd_len, 181 (BYTE *)szTpmPasswd) != TSS_SUCCESS) 182 goto out_close; 183 } 184 185 if (tpmSetStatus(hTpm, flags[i].property, 0) 186 != TSS_SUCCESS) 187 goto out_close; 188 logInfo(_("Disabling %s successful.\n"), 189 _(flags[i].name)); 190 } 191 } 192 while (flags[++i].name); 193 out_success: 194 logSuccess(argv[0]); 195 iRc = 0; 196 197 out_close: 198 contextClose(hContext); 199 out: 200 if (szTpmPasswd && !isWellKnown) 201 shredPasswd(szTpmPasswd); 202 return iRc; 203} 204