xref: /netbsd-src/crypto/external/cpl/tpm-tools/dist/src/tpm_mgmt/tpm_clearable.c (revision 431955c163a358f3111f7be0c1fa1643cab0b701)
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