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
help(const char * aCmd)25 static 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
39 enum {
40 owner = 0,
41 force
42 };
43
44 struct physFlag {
45 const char *name;
46 const TSS_FLAG property;
47 BOOL disable;
48 };
49
50 //Controlled by input options
51 static struct physFlag flags[] = { {N_("Owner Clear"),
52 TSS_TPMSTATUS_DISABLEOWNERCLEAR},
53 {N_("Force Clear"),
54 TSS_TPMSTATUS_DISABLEFORCECLEAR},
55 {0, 0, 0}
56 };
57 static BOOL bCheck = FALSE;
58 static BOOL bChangeRequested = FALSE;
59 static BOOL isWellKnown = FALSE;
60 TSS_HCONTEXT hContext = 0;
61
parse(const int aOpt,const char * aArg)62 static 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
main(int argc,char ** argv)94 int 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