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
25 //Controled by input options
26
27 #define STATUS_CHECK 0
28 #define ACTIVATE 1
29 #define DEACTIVATE 2
30 #define TEMP_DEACTIVATE 3
31
32 static int request = STATUS_CHECK;
33 static BOOL isWellKnown = FALSE;
34 TSS_HCONTEXT hContext = 0;
35
help(const char * aCmd)36 static void help(const char *aCmd)
37 {
38 logCmdHelp(aCmd);
39 logUnicodeCmdOption();
40 logCmdOption("-s, --status", _("Report current state"));
41 logCmdOption("-a, --active", _("Activate TPM, requires reboot"));
42 logCmdOption("-i, --inactive", _("Deactivate TPM, requires reboot"));
43 logCmdOption("-t, --temp",
44 _("Change state immediately but only for this boot.\n\t\tOnly valid in conjunction with the inactive parameter."));
45 logCmdOption("-z, --well-known",
46 _("Use 20 bytes of zeros (TSS_WELL_KNOWN_SECRET) as the TPM secret authorization data"));
47 }
48
parse(const int aOpt,const char * aArg)49 static int parse(const int aOpt, const char *aArg)
50 {
51
52 switch (aOpt) {
53 case 's':
54 logDebug(_("Changing mode to check status.\n"));
55 request = STATUS_CHECK;
56 break;
57 case 'a':
58 logDebug(_("Changing mode to activate the TPM.\n"));
59 request = ACTIVATE;
60 break;
61 case 'i':
62 logDebug(_("Changing mode to deactivate the TPM.\n"));
63 request = DEACTIVATE;
64 break;
65 case 't':
66 logDebug(_("Changing mode to temporarily deactivate the TPM\n"));
67 request = TEMP_DEACTIVATE;
68 break;
69 case 'z':
70 logDebug(_("Using TSS_WELL_KNOWN_SECRET to authorize the TPM command\n"));
71 isWellKnown = TRUE;
72 break;
73
74 default:
75 return -1;
76 }
77 return 0;
78 }
79
80 /*
81 * Affect: Change state of TPM between Active and Inactive
82 * Default: report status
83 * Requires: Physical presence unless --temp specified
84 */
main(int argc,char ** argv)85 int main(int argc, char **argv)
86 {
87
88 char *szTpmPasswd = NULL;
89 int tpm_len;
90 TSS_HTPM hTpm;
91 TSS_HPOLICY hTpmPolicy;
92 TSS_BOOL bValue;
93 int iRc = -1;
94 struct option opts[] = { {"active", no_argument, NULL, 'a'},
95 {"inactive", no_argument, NULL, 'i'},
96 {"temp", no_argument, NULL, 't'},
97 {"status", no_argument, NULL, 's'},
98 {"well-known", no_argument, NULL, 'z'},
99 };
100 BYTE well_known[] = TSS_WELL_KNOWN_SECRET;
101
102 initIntlSys();
103
104 if (genericOptHandler
105 (argc, argv, "aitsz", opts,
106 sizeof(opts) / sizeof(struct option), parse, help) != 0)
107 goto out;
108
109 if (contextCreate(&hContext) != TSS_SUCCESS)
110 goto out;
111
112 if (contextConnect(hContext) != TSS_SUCCESS)
113 goto out_close;
114
115 if (contextGetTpm(hContext, &hTpm) != TSS_SUCCESS)
116 goto out_close;
117
118 switch(request) {
119 case STATUS_CHECK:
120 logInfo(_("Checking status:\n"));
121 if (isWellKnown){
122 szTpmPasswd = (char *)well_known;
123 tpm_len = sizeof(well_known);
124 } else {
125 szTpmPasswd = GETPASSWD(_("Enter owner password: "), &tpm_len, FALSE);
126 if (!szTpmPasswd) {
127 logMsg(_("Failed to get password\n"));
128 goto out_close;
129 }
130 }
131
132 if (policyGet(hTpm, &hTpmPolicy) != TSS_SUCCESS)
133 goto out_close;
134
135 if (policySetSecret
136 (hTpmPolicy, tpm_len,
137 (BYTE *)szTpmPasswd) != TSS_SUCCESS)
138 goto out_close;
139 if (tpmGetStatus
140 (hTpm, TSS_TPMSTATUS_PHYSICALSETDEACTIVATED,
141 &bValue) != TSS_SUCCESS)
142 goto out_close;
143 logMsg(_("Persistent Deactivated Status: %s\n"),
144 logBool(mapTssBool(bValue)));
145
146 if (tpmGetStatus
147 (hTpm, TSS_TPMSTATUS_SETTEMPDEACTIVATED, &bValue))
148 goto out_close;
149 logMsg(_("Volatile Deactivated Status: %s\n"),
150 logBool(mapTssBool(bValue)));
151 break;
152 case ACTIVATE:
153 if (tpmSetStatus(hTpm, TSS_TPMSTATUS_PHYSICALSETDEACTIVATED, FALSE) != TSS_SUCCESS)
154 goto out_close;
155 logMsg(_("Action requires a reboot to take effect\n"));
156 break;
157 case DEACTIVATE:
158 if (tpmSetStatus(hTpm, TSS_TPMSTATUS_PHYSICALSETDEACTIVATED, TRUE) != TSS_SUCCESS)
159 goto out_close;
160 logMsg(_("Action requires a reboot to take effect\n"));
161 break;
162 case TEMP_DEACTIVATE:
163 if (tpmSetStatus(hTpm, TSS_TPMSTATUS_SETTEMPDEACTIVATED, TRUE) != TSS_SUCCESS)
164 goto out_close;
165 break;
166 }
167
168 //Command successful
169 iRc = 0;
170 logSuccess(argv[0]);
171 //Cleanup
172 out_close:
173 if (szTpmPasswd && !isWellKnown)
174 shredPasswd(szTpmPasswd);
175
176 contextClose(hContext);
177
178 out:
179 return iRc;
180 }
181