OLD | NEW |
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 * |
| 8 * The exit code is 0 for success, the TPM error code for TPM errors, and 255 |
| 9 * for other errors. |
7 */ | 10 */ |
8 | 11 |
9 #include <stdio.h> | 12 #include <stdio.h> |
10 #include <string.h> | 13 #include <string.h> |
11 #include <syslog.h> | 14 #include <syslog.h> |
12 | 15 |
13 #include "tlcl.h" | 16 #include "tlcl.h" |
14 #include "tpm_error_messages.h" | 17 #include "tpm_error_messages.h" |
15 #include "tss_constants.h" | 18 #include "tss_constants.h" |
16 | 19 |
| 20 #define OTHER_ERROR 255 |
| 21 |
17 typedef struct command_record { | 22 typedef struct command_record { |
18 const char* name; | 23 const char* name; |
19 const char* abbr; | 24 const char* abbr; |
20 const char* description; | 25 const char* description; |
21 uint32_t (*handler)(void); | 26 uint32_t (*handler)(void); |
22 } command_record; | 27 } command_record; |
23 | 28 |
24 /* Set in main, consumed by handler functions below. We use global variables | 29 /* 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 | 30 * so we can also choose to call Tlcl*() functions directly; they don't take |
26 * argv/argc. | 31 * argv/argc. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 if (result == 0) { | 65 if (result == 0) { |
61 return 0; | 66 return 0; |
62 } else { | 67 } else { |
63 int i; | 68 int i; |
64 int n = sizeof(tpm_error_table) / sizeof(tpm_error_table[0]); | 69 int n = sizeof(tpm_error_table) / sizeof(tpm_error_table[0]); |
65 fprintf(stderr, "command \"%s\" failed with code 0x%x\n", cmd, result); | 70 fprintf(stderr, "command \"%s\" failed with code 0x%x\n", cmd, result); |
66 for (i = 0; i < n; i++) { | 71 for (i = 0; i < n; i++) { |
67 if (tpm_error_table[i].code == result) { | 72 if (tpm_error_table[i].code == result) { |
68 fprintf(stderr, "%s\n%s\n", tpm_error_table[i].name, | 73 fprintf(stderr, "%s\n%s\n", tpm_error_table[i].name, |
69 tpm_error_table[i].description); | 74 tpm_error_table[i].description); |
70 return 1; | 75 return result; |
71 } | 76 } |
72 } | 77 } |
73 fprintf(stderr, "the TPM error code is unknown to this program\n"); | 78 fprintf(stderr, "the TPM error code is unknown to this program\n"); |
74 return 1; | 79 return result; |
75 } | 80 } |
76 } | 81 } |
77 | 82 |
78 /* Handler functions. These wouldn't exist if C had closures. | 83 /* Handler functions. These wouldn't exist if C had closures. |
79 */ | 84 */ |
80 static uint32_t HandlerGetFlags(void) { | 85 static uint32_t HandlerGetFlags(void) { |
81 uint8_t disabled; | 86 uint8_t disabled; |
82 uint8_t deactivated; | 87 uint8_t deactivated; |
83 uint8_t nvlocked; | 88 uint8_t nvlocked; |
84 uint32_t result = TlclGetFlags(&disabled, &deactivated, &nvlocked); | 89 uint32_t result = TlclGetFlags(&disabled, &deactivated, &nvlocked); |
85 if (result == 0) { | 90 if (result == 0) { |
86 printf("disabled: %d\ndeactivated: %d\nnvlocked: %d\n", | 91 printf("disabled: %d\ndeactivated: %d\nnvlocked: %d\n", |
87 disabled, deactivated, nvlocked); | 92 disabled, deactivated, nvlocked); |
88 } | 93 } |
89 return result; | 94 return result; |
90 } | 95 } |
91 | 96 |
92 static uint32_t HandlerActivate(void) { | 97 static uint32_t HandlerActivate(void) { |
93 return TlclSetDeactivated(0); | 98 return TlclSetDeactivated(0); |
94 } | 99 } |
95 | 100 |
96 static uint32_t HandlerDeactivate(void) { | 101 static uint32_t HandlerDeactivate(void) { |
97 return TlclSetDeactivated(1); | 102 return TlclSetDeactivated(1); |
98 } | 103 } |
99 | 104 |
100 static uint32_t HandlerDefineSpace(void) { | 105 static uint32_t HandlerDefineSpace(void) { |
101 uint32_t index, size, perm; | 106 uint32_t index, size, perm; |
102 if (nargs != 5) { | 107 if (nargs != 5) { |
103 fprintf(stderr, "usage: tpmc def <index> <size> <perm>\n"); | 108 fprintf(stderr, "usage: tpmc def <index> <size> <perm>\n"); |
104 exit(1); | 109 exit(OTHER_ERROR); |
105 } | 110 } |
106 if (HexStringToUint32(args[2], &index) != 0 || | 111 if (HexStringToUint32(args[2], &index) != 0 || |
107 HexStringToUint32(args[3], &size) != 0 || | 112 HexStringToUint32(args[3], &size) != 0 || |
108 HexStringToUint32(args[4], &perm) != 0) { | 113 HexStringToUint32(args[4], &perm) != 0) { |
109 fprintf(stderr, "<index>, <size>, and <perm> must be " | 114 fprintf(stderr, "<index>, <size>, and <perm> must be " |
110 "32-bit hex (0x[0-9a-f]+)\n"); | 115 "32-bit hex (0x[0-9a-f]+)\n"); |
111 exit(1); | 116 exit(OTHER_ERROR); |
112 } | 117 } |
113 return TlclDefineSpace(index, perm, size); | 118 return TlclDefineSpace(index, perm, size); |
114 } | 119 } |
115 | 120 |
116 static uint32_t HandlerWrite(void) { | 121 static uint32_t HandlerWrite(void) { |
117 uint32_t index, size; | 122 uint32_t index, size; |
118 uint8_t value[TPM_MAX_COMMAND_SIZE]; | 123 uint8_t value[TPM_MAX_COMMAND_SIZE]; |
119 char** byteargs; | 124 char** byteargs; |
120 int i; | 125 int i; |
121 if (nargs < 3) { | 126 if (nargs < 3) { |
122 fprintf(stderr, "usage: tpmc write <index> [<byte0> <byte1> ...]\n"); | 127 fprintf(stderr, "usage: tpmc write <index> [<byte0> <byte1> ...]\n"); |
123 exit(1); | 128 exit(OTHER_ERROR); |
124 } | 129 } |
125 if (HexStringToUint32(args[2], &index) != 0) { | 130 if (HexStringToUint32(args[2], &index) != 0) { |
126 fprintf(stderr, "<index> must be 32-bit hex (0x[0-9a-f]+)\n"); | 131 fprintf(stderr, "<index> must be 32-bit hex (0x[0-9a-f]+)\n"); |
127 exit(1); | 132 exit(OTHER_ERROR); |
128 } | 133 } |
129 size = nargs - 3; | 134 size = nargs - 3; |
130 if (size > sizeof(value)) { | 135 if (size > sizeof(value)) { |
131 fprintf(stderr, "byte array too large\n"); | 136 fprintf(stderr, "byte array too large\n"); |
132 exit(1); | 137 exit(OTHER_ERROR); |
133 } | 138 } |
134 | 139 |
135 byteargs = args + 3; | 140 byteargs = args + 3; |
136 for (i = 0; i < size; i++) { | 141 for (i = 0; i < size; i++) { |
137 if (HexStringToUint8(byteargs[i], &value[i]) != 0) { | 142 if (HexStringToUint8(byteargs[i], &value[i]) != 0) { |
138 fprintf(stderr, "invalid byte %s, should be [0-9a-f][0-9a-f]?\n", | 143 fprintf(stderr, "invalid byte %s, should be [0-9a-f][0-9a-f]?\n", |
139 byteargs[i]); | 144 byteargs[i]); |
140 exit(1); | 145 exit(OTHER_ERROR); |
141 } | 146 } |
142 } | 147 } |
143 | 148 |
144 if (size == 0) { | 149 if (size == 0) { |
145 if (index == TPM_NV_INDEX_LOCK) { | 150 if (index == TPM_NV_INDEX_LOCK) { |
146 fprintf(stderr, "This would set the nvLocked bit. " | 151 fprintf(stderr, "This would set the nvLocked bit. " |
147 "Use \"tpmc setnv\" instead.\n"); | 152 "Use \"tpmc setnv\" instead.\n"); |
148 exit(1); | 153 exit(OTHER_ERROR); |
149 } | 154 } |
150 printf("warning: zero-length write\n"); | 155 printf("warning: zero-length write\n"); |
151 } else { | 156 } else { |
152 printf("writing %d byte%s\n", size, size > 1 ? "s" : ""); | 157 printf("writing %d byte%s\n", size, size > 1 ? "s" : ""); |
153 } | 158 } |
154 | 159 |
155 return TlclWrite(index, value, size); | 160 return TlclWrite(index, value, size); |
156 } | 161 } |
157 | 162 |
158 static uint32_t HandlerRead(void) { | 163 static uint32_t HandlerRead(void) { |
159 uint32_t index, size; | 164 uint32_t index, size; |
160 uint8_t value[4096]; | 165 uint8_t value[4096]; |
161 uint32_t result; | 166 uint32_t result; |
162 int i; | 167 int i; |
163 if (nargs != 4) { | 168 if (nargs != 4) { |
164 fprintf(stderr, "usage: tpmc read <index> <size>\n"); | 169 fprintf(stderr, "usage: tpmc read <index> <size>\n"); |
165 exit(1); | 170 exit(OTHER_ERROR); |
166 } | 171 } |
167 if (HexStringToUint32(args[2], &index) != 0 || | 172 if (HexStringToUint32(args[2], &index) != 0 || |
168 HexStringToUint32(args[3], &size) != 0) { | 173 HexStringToUint32(args[3], &size) != 0) { |
169 fprintf(stderr, "<index> and <size> must be 32-bit hex (0x[0-9a-f]+)\n"); | 174 fprintf(stderr, "<index> and <size> must be 32-bit hex (0x[0-9a-f]+)\n"); |
170 exit(1); | 175 exit(OTHER_ERROR); |
171 } | 176 } |
172 if (size > sizeof(value)) { | 177 if (size > sizeof(value)) { |
173 fprintf(stderr, "size of read (0x%x) is too big\n", size); | 178 fprintf(stderr, "size of read (0x%x) is too big\n", size); |
174 exit(1); | 179 exit(OTHER_ERROR); |
175 } | 180 } |
176 result = TlclRead(index, value, size); | 181 result = TlclRead(index, value, size); |
177 if (result == 0 && size > 0) { | 182 if (result == 0 && size > 0) { |
178 for (i = 0; i < size - 1; i++) { | 183 for (i = 0; i < size - 1; i++) { |
179 printf("%x ", value[i]); | 184 printf("%x ", value[i]); |
180 } | 185 } |
181 printf("%x\n", value[i]); | 186 printf("%x\n", value[i]); |
182 } | 187 } |
183 return result; | 188 return result; |
184 } | 189 } |
185 | 190 |
186 static uint32_t HandlerGetPermissions(void) { | 191 static uint32_t HandlerGetPermissions(void) { |
187 uint32_t index, permissions, result; | 192 uint32_t index, permissions, result; |
188 if (nargs != 3) { | 193 if (nargs != 3) { |
189 fprintf(stderr, "usage: tpmc getp <index>\n"); | 194 fprintf(stderr, "usage: tpmc getp <index>\n"); |
190 exit(1); | 195 exit(OTHER_ERROR); |
191 } | 196 } |
192 if (HexStringToUint32(args[2], &index) != 0) { | 197 if (HexStringToUint32(args[2], &index) != 0) { |
193 fprintf(stderr, "<index> must be 32-bit hex (0x[0-9a-f]+)\n"); | 198 fprintf(stderr, "<index> must be 32-bit hex (0x[0-9a-f]+)\n"); |
194 exit(1); | 199 exit(OTHER_ERROR); |
195 } | 200 } |
196 result = TlclGetPermissions(index, &permissions); | 201 result = TlclGetPermissions(index, &permissions); |
197 if (result == 0) { | 202 if (result == 0) { |
198 printf("space 0x%x has permissions 0x%x\n", index, permissions); | 203 printf("space 0x%x has permissions 0x%x\n", index, permissions); |
199 } | 204 } |
200 return result; | 205 return result; |
201 } | 206 } |
202 | 207 |
203 static uint32_t HandlerGetPermanentFlags(void) { | 208 static uint32_t HandlerGetPermanentFlags(void) { |
204 TPM_PERMANENT_FLAGS pflags; | 209 TPM_PERMANENT_FLAGS pflags; |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 { "getstclearflags", "getvf", "print all volatile (ST_CLEAR) flags", | 290 { "getstclearflags", "getvf", "print all volatile (ST_CLEAR) flags", |
286 HandlerGetSTClearFlags }, | 291 HandlerGetSTClearFlags }, |
287 }; | 292 }; |
288 | 293 |
289 static int n_commands = sizeof(command_table) / sizeof(command_table[0]); | 294 static int n_commands = sizeof(command_table) / sizeof(command_table[0]); |
290 | 295 |
291 int main(int argc, char* argv[]) { | 296 int main(int argc, char* argv[]) { |
292 if (argc < 2) { | 297 if (argc < 2) { |
293 fprintf(stderr, "usage: %s <TPM command> [args]\n or: %s help\n", | 298 fprintf(stderr, "usage: %s <TPM command> [args]\n or: %s help\n", |
294 argv[0], argv[0]); | 299 argv[0], argv[0]); |
295 exit(1); | 300 return OTHER_ERROR; |
296 } else { | 301 } else { |
297 command_record* c; | 302 command_record* c; |
298 const char* cmd = argv[1]; | 303 const char* cmd = argv[1]; |
299 nargs = argc; | 304 nargs = argc; |
300 args = argv; | 305 args = argv; |
301 | 306 |
302 if (strcmp(cmd, "help") == 0) { | 307 if (strcmp(cmd, "help") == 0) { |
303 printf("%26s %7s %s\n\n", "command", "abbr.", "description"); | 308 printf("%26s %7s %s\n\n", "command", "abbr.", "description"); |
304 for (c = command_table; c < command_table + n_commands; c++) { | 309 for (c = command_table; c < command_table + n_commands; c++) { |
305 printf("%26s %7s %s\n", c->name, c->abbr, c->description); | 310 printf("%26s %7s %s\n", c->name, c->abbr, c->description); |
306 } | 311 } |
307 return 0; | 312 return 0; |
308 } | 313 } |
309 | 314 |
310 TlclLibInit(); | 315 TlclLibInit(); |
311 | 316 |
312 for (c = command_table; c < command_table + n_commands; c++) { | 317 for (c = command_table; c < command_table + n_commands; c++) { |
313 if (strcmp(cmd, c->name) == 0 || strcmp(cmd, c->abbr) == 0) { | 318 if (strcmp(cmd, c->name) == 0 || strcmp(cmd, c->abbr) == 0) { |
314 return ErrorCheck(c->handler(), cmd); | 319 return ErrorCheck(c->handler(), cmd); |
315 } | 320 } |
316 } | 321 } |
317 | 322 |
318 /* No command matched. */ | 323 /* No command matched. */ |
319 fprintf(stderr, "%s: unknown command: %s\n", argv[0], cmd); | 324 fprintf(stderr, "%s: unknown command: %s\n", argv[0], cmd); |
320 return 1; | 325 return OTHER_ERROR; |
321 } | 326 } |
322 } | 327 } |
OLD | NEW |