Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: utility/tpmc.c

Issue 3165023: Add some commands to tpmc. (Closed) Base URL: ssh://git@chromiumos-git/vboot_reference.git
Patch Set: White space fix. Created 10 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « firmware/version.c ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved. 1 /* Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be 2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file. 3 * found in the LICENSE file.
4 * 4 *
5 * TPM command utility. Runs simple TPM commands. Mostly useful when physical 5 * TPM command utility. Runs simple TPM commands. Mostly useful when physical
6 * presence has not been locked. 6 * presence has not been locked.
7 */ 7 */
8 8
9 #include <stdio.h> 9 #include <stdio.h>
10 #include <string.h> 10 #include <string.h>
11 #include <syslog.h> 11 #include <syslog.h>
12 12
13 #include "tlcl.h" 13 #include "tlcl.h"
14 #include "tpm_error_messages.h" 14 #include "tpm_error_messages.h"
15 #include "tss_constants.h"
15 16
16 typedef struct command_record { 17 typedef struct command_record {
17 const char* name; 18 const char* name;
18 const char* abbr; 19 const char* abbr;
19 const char* description; 20 const char* description;
20 uint32_t (*handler)(void); 21 uint32_t (*handler)(void);
21 } command_record; 22 } command_record;
22 23
24 /* Set in main, consumed by handler functions below. We use global variables
25 * so we can also choose to call Tlcl*() functions directly; they don't take
26 * argv/argc.
27 */
28 int nargs;
29 char** args;
30
31 /* Converts a string in the form 0x[0-9a-f]+ to a 32-bit value. Returns 0 for
32 * success, non-zero for failure.
33 */
34 int HexStringToUint32(const char* string, uint32_t* value) {
35 char tail[1];
36 /* strtoul is not as good because it overflows silently */
37 char* format = strncmp(string, "0x", 2) ? "%8x%s" : "0x%8x%s";
38 int n = sscanf(string, format, value, tail);
39 return n != 1;
40 }
41
42 /* Converts a string in the form [0-9a-f]+ to an 8-bit value. Returns 0 for
43 * success, non-zero for failure.
44 */
45 int HexStringToUint8(const char* string, uint8_t* value) {
46 char* end;
47 uint32_t large_value = strtoul(string, &end, 16);
48 if (*end != '\0' || large_value > 0xff) {
49 return 1;
50 }
51 *value = large_value;
52 return 0;
53 }
54
55 /* TPM error check and reporting. Returns 0 if |result| is 0 (TPM_SUCCESS).
56 * Otherwise looks up a TPM error in the error table and prints the error if
57 * found.
58 */
59 uint32_t ErrorCheck(uint32_t result, const char* cmd) {
60 if (result == 0) {
61 return 0;
62 } else {
63 int i;
64 int n = sizeof(tpm_error_table) / sizeof(tpm_error_table[0]);
65 fprintf(stderr, "command \"%s\" failed with code 0x%x\n", cmd, result);
66 for (i = 0; i < n; i++) {
67 if (tpm_error_table[i].code == result) {
68 fprintf(stderr, "%s\n%s\n", tpm_error_table[i].name,
69 tpm_error_table[i].description);
70 return 1;
71 }
72 }
73 fprintf(stderr, "the TPM error code is unknown to this program\n");
74 return 1;
75 }
76 }
77
23 /* Handler functions. These wouldn't exist if C had closures. 78 /* Handler functions. These wouldn't exist if C had closures.
24 */ 79 */
25
26 static uint32_t HandlerGetFlags(void) { 80 static uint32_t HandlerGetFlags(void) {
27 uint8_t disabled; 81 uint8_t disabled;
28 uint8_t deactivated; 82 uint8_t deactivated;
29 uint8_t nvlocked; 83 uint8_t nvlocked;
30 uint32_t result = TlclGetFlags(&disabled, &deactivated, &nvlocked); 84 uint32_t result = TlclGetFlags(&disabled, &deactivated, &nvlocked);
31 if (result == 0) { 85 if (result == 0) {
32 printf("disabled: %d\ndeactivated: %d\nnvlocked: %d\n", 86 printf("disabled: %d\ndeactivated: %d\nnvlocked: %d\n",
33 disabled, deactivated, nvlocked); 87 disabled, deactivated, nvlocked);
34 } 88 }
35 return result; 89 return result;
36 } 90 }
37 91
38 static uint32_t HandlerActivate(void) { 92 static uint32_t HandlerActivate(void) {
39 return TlclSetDeactivated(0); 93 return TlclSetDeactivated(0);
40 } 94 }
41 95
42 static uint32_t HandlerDeactivate(void) { 96 static uint32_t HandlerDeactivate(void) {
43 return TlclSetDeactivated(1); 97 return TlclSetDeactivated(1);
44 } 98 }
45 99
100 static uint32_t HandlerDefineSpace(void) {
101 uint32_t index, size, perm;
102 if (nargs != 5) {
103 fprintf(stderr, "usage: tpmc def <index> <size> <perm>\n");
104 exit(1);
105 }
106 if (HexStringToUint32(args[2], &index) != 0 ||
107 HexStringToUint32(args[3], &size) != 0 ||
108 HexStringToUint32(args[4], &perm) != 0) {
109 fprintf(stderr, "<index>, <size>, and <perm> must be "
110 "32-bit hex (0x[0-9a-f]+)\n");
111 exit(1);
112 }
113 return TlclDefineSpace(index, perm, size);
114 }
115
116 static uint32_t HandlerWrite(void) {
117 uint32_t index, size;
118 uint8_t value[TPM_MAX_COMMAND_SIZE];
119 char** byteargs;
120 int i;
121 if (nargs < 3) {
122 fprintf(stderr, "usage: tpmc write <index> [<byte0> <byte1> ...]\n");
123 exit(1);
124 }
125 if (HexStringToUint32(args[2], &index) != 0) {
126 fprintf(stderr, "<index> must be 32-bit hex (0x[0-9a-f]+)\n");
127 exit(1);
128 }
129 size = nargs - 3;
130 if (size > sizeof(value)) {
131 fprintf(stderr, "byte array too large\n");
132 exit(1);
133 }
134
135 byteargs = args + 3;
136 for (i = 0; i < size; i++) {
137 if (HexStringToUint8(byteargs[i], &value[i]) != 0) {
138 fprintf(stderr, "invalid byte %s, should be [0-9a-f][0-9a-f]?\n",
139 byteargs[i]);
140 exit(1);
141 }
142 }
143
144 if (size == 0) {
145 if (index == TPM_NV_INDEX_LOCK) {
146 fprintf(stderr, "This would set the nvLocked bit. "
147 "Use \"tpmc setnv\" instead.\n");
148 exit(1);
149 }
150 printf("warning: zero-length write\n");
151 } else {
152 printf("writing %d byte%s\n", size, size > 1 ? "s" : "");
153 }
154
155 return TlclWrite(index, value, size);
156 }
157
158 static uint32_t HandlerRead(void) {
159 uint32_t index, size;
160 uint8_t value[4096];
161 uint32_t result;
162 int i;
163 if (nargs != 4) {
164 fprintf(stderr, "usage: tpmc read <index> <size>\n");
165 exit(1);
166 }
167 if (HexStringToUint32(args[2], &index) != 0 ||
168 HexStringToUint32(args[3], &size) != 0) {
169 fprintf(stderr, "<index> and <size> must be 32-bit hex (0x[0-9a-f]+)\n");
170 exit(1);
171 }
172 if (size > sizeof(value)) {
173 fprintf(stderr, "size of read (0x%x) is too big\n", size);
174 exit(1);
175 }
176 result = TlclRead(index, value, size);
177 if (result == 0 && size > 0) {
178 for (i = 0; i < size - 1; i++) {
179 printf("%x ", value[i]);
180 }
181 printf("%x\n", value[i]);
182 }
183 return result;
184 }
185
186 static uint32_t HandlerGetPermissions(void) {
187 uint32_t index, permissions, result;
188 if (nargs != 3) {
189 fprintf(stderr, "usage: tpmc getp <index>\n");
190 exit(1);
191 }
192 if (HexStringToUint32(args[2], &index) != 0) {
193 fprintf(stderr, "<index> must be 32-bit hex (0x[0-9a-f]+)\n");
194 exit(1);
195 }
196 result = TlclGetPermissions(index, &permissions);
197 if (result == 0) {
198 printf("space 0x%x has permissions 0x%x\n", index, permissions);
199 }
200 return result;
201 }
202
46 /* Table of TPM commands. 203 /* Table of TPM commands.
47 */ 204 */
48 command_record command_table[] = { 205 command_record command_table[] = {
49 { "getflags", "getf", "read and print the value of selected flags", 206 { "getflags", "getf", "read and print the value of selected flags",
50 HandlerGetFlags }, 207 HandlerGetFlags },
51 { "startup", "sta", "issue a Startup command", TlclStartup }, 208 { "startup", "sta", "issue a Startup command", TlclStartup },
52 { "selftestfull", "test", "issue a SelfTestFull command", TlclSelfTestFull }, 209 { "selftestfull", "test", "issue a SelfTestFull command", TlclSelfTestFull },
53 { "continueselftest", "ctest", "issue a ContinueSelfTest command", 210 { "continueselftest", "ctest", "issue a ContinueSelfTest command",
54 TlclContinueSelfTest }, 211 TlclContinueSelfTest },
55 { "assertphysicalpresence", "ppon", "assert Physical Presence", 212 { "assertphysicalpresence", "ppon", "assert Physical Presence",
56 TlclAssertPhysicalPresence }, 213 TlclAssertPhysicalPresence },
57 { "enable", "ena", "enable the TPM (needs PP)", TlclSetEnable }, 214 { "enable", "ena", "enable the TPM (needs PP)", TlclSetEnable },
58 { "disable", "dis", "disable the TPM (needs PP)", TlclClearEnable }, 215 { "disable", "dis", "disable the TPM (needs PP)", TlclClearEnable },
59 { "activate", "act", "activate the TPM (needs PP, maybe reboot)", 216 { "activate", "act", "activate the TPM (needs PP, maybe reboot)",
60 HandlerActivate }, 217 HandlerActivate },
61 { "deactivate", "deact", "deactivate the TPM (needs PP, maybe reboot)", 218 { "deactivate", "deact", "deactivate the TPM (needs PP, maybe reboot)",
62 HandlerDeactivate }, 219 HandlerDeactivate },
63 { "clear", "clr", "clear the TPM owner (needs PP)", TlclForceClear }, 220 { "clear", "clr", "clear the TPM owner (needs PP)", TlclForceClear },
221 { "setnvlocked", "setnv", "set the nvLocked flag permanently (IRREVERSIBLE!)",
222 TlclSetNvLocked },
223 { "lockphysicalpresence", "pplock", "lock PP to current value until reboot",
224 TlclLockPhysicalPresence },
225 { "setbgloballock", "block", "set the bGlobalLock until reboot",
226 TlclSetGlobalLock },
227 { "definespace", "def", "define a space (def <index> <size> <perm>)",
228 HandlerDefineSpace },
229 { "write", "write", "write to a space (write <index> [<byte0> <byte1> ...])",
230 HandlerWrite },
231 { "read", "read", "read from a space (read <index> <size>)",
232 HandlerRead },
233 { "getpermissions", "getp", "print space permissions (getp <index>)",
234 HandlerGetPermissions },
64 }; 235 };
65 236
66 static int n_commands = sizeof(command_table) / sizeof(command_table[0]); 237 static int n_commands = sizeof(command_table) / sizeof(command_table[0]);
67 238
68 int main(int argc, char* argv[]) { 239 int main(int argc, char* argv[]) {
69 if (argc < 2) { 240 if (argc < 2) {
70 fprintf(stderr, "usage: %s <TPM command>\n or: %s help\n", 241 fprintf(stderr, "usage: %s <TPM command> [args]\n or: %s help\n",
71 argv[0], argv[0]); 242 argv[0], argv[0]);
72 exit(1); 243 exit(1);
73 } else { 244 } else {
74 command_record* c; 245 command_record* c;
75 const char* cmd = argv[1]; 246 const char* cmd = argv[1];
247 nargs = argc;
248 args = argv;
76 249
77 if (strcmp(cmd, "help") == 0) { 250 if (strcmp(cmd, "help") == 0) {
78 printf("%23s %7s %s\n\n", "command", "abbr.", "description"); 251 printf("%23s %7s %s\n\n", "command", "abbr.", "description");
79 for (c = command_table; c < command_table + n_commands; c++) { 252 for (c = command_table; c < command_table + n_commands; c++) {
80 printf("%23s %7s %s\n", c->name, c->abbr, c->description); 253 printf("%23s %7s %s\n", c->name, c->abbr, c->description);
81 } 254 }
82 return 0; 255 return 0;
83 } 256 }
84 257
85 TlclLibInit(); 258 TlclLibInit();
86 259
87 for (c = command_table; c < command_table + n_commands; c++) { 260 for (c = command_table; c < command_table + n_commands; c++) {
88 if (strcmp(cmd, c->name) == 0 || strcmp(cmd, c->abbr) == 0) { 261 if (strcmp(cmd, c->name) == 0 || strcmp(cmd, c->abbr) == 0) {
89 uint32_t result; 262 return ErrorCheck(c->handler(), cmd);
90 result = c->handler();
91 if (result == 0) {
92 return 0;
93 } else {
94 int i;
95 int n = sizeof(tpm_error_table) / sizeof(tpm_error_table[0]);
96 fprintf(stderr, "command \"%s\" failed with code 0x%x\n",
97 cmd, result);
98 for (i = 0; i < n; i++) {
99 if (tpm_error_table[i].code == result) {
100 fprintf(stderr, "%s\n%s\n", tpm_error_table[i].name,
101 tpm_error_table[i].description);
102 return 1;
103 }
104 }
105 fprintf(stderr, "the error code is unknown to this program\n");
106 return 1;
107 }
108 } 263 }
109 } 264 }
110 265
111 /* No command matched. */ 266 /* No command matched. */
112 fprintf(stderr, "%s: unknown command: %s\n", argv[0], cmd); 267 fprintf(stderr, "%s: unknown command: %s\n", argv[0], cmd);
113 return 1; 268 return 1;
114 } 269 }
115 } 270 }
OLDNEW
« no previous file with comments | « firmware/version.c ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698