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

Side by Side Diff: src/platform/tpm_lite/src/tlcl/tlcl.c

Issue 870004: Many upgrades to tpm_lite. (Closed)
Patch Set: Fix makefile comment. Created 10 years, 9 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
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 5
6 /* A lightweight TPM command library. 6 /* A lightweight TPM command library.
7 * 7 *
8 * The general idea is that TPM commands are array of bytes whose fields are 8 * The general idea is that TPM commands are array of bytes whose fields are
9 * mostly compile-time constant. The goal is to build much of the commands at 9 * mostly compile-time constant. The goal is to build much of the commands at
10 * compile time (or build time) and change some of the fields at run time as 10 * compile time (or build time) and change some of the fields at run time as
11 * needed. The code in generator.c builds structures containing the commands, 11 * needed. The code in generator.c builds structures containing the commands,
12 * as well as the offsets of the fields that need to be set at run time. 12 * as well as the offsets of the fields that need to be set at run time.
13 */ 13 */
14 14
15 #include "tlcl.h" 15 #include "tlcl.h"
16 16
17 #include <errno.h>
18 #include <fcntl.h>
17 #include <string.h> 19 #include <string.h>
20 #include <sys/types.h>
21 #include <sys/stat.h>
18 #include <tss/tcs.h> 22 #include <tss/tcs.h>
23 #include <unistd.h>
19 24
20 #include "structures.h" 25 #include "structures.h"
21 #include "tlcl_internal.h" 26 #include "tlcl_internal.h"
27 #if USE_TPM_EMULATOR
22 #include "tpmemu.h" 28 #include "tpmemu.h"
29 #endif
23 #include "tpmextras.h" 30 #include "tpmextras.h"
24 31
32 /* The file descriptor for the TPM device.
33 */
34 int tpm_fd = -1;
35
36 /* Print |n| bytes from array |a|, with newlines.
37 */
38 static void PrintBytes(uint8_t* a, int n) {
39 int i;
40 for (i = 0; i < n; i++) {
41 printf("%02x ", a[i]);
42 if ((i + 1) % 16 == 0) {
43 printf("\n");
44 }
45 }
46 if (i % 16 != 0) {
47 printf("\n");
48 }
49 }
50
25 /* Gets the tag field of a TPM command. 51 /* Gets the tag field of a TPM command.
26 */ 52 */
27 static INLINE int TpmTag(uint8_t* buffer) { 53 static INLINE int TpmTag(uint8_t* buffer) {
28 uint16_t tag; 54 uint16_t tag;
29 FromTpmUint16(buffer, &tag); 55 FromTpmUint16(buffer, &tag);
30 return (int) tag; 56 return (int) tag;
31 } 57 }
32 58
33 /* Sets the size field of a TPM command. 59 /* Sets the size field of a TPM command.
34 */ 60 */
35 static INLINE void SetTpmCommandSize(uint8_t* buffer, uint32_t size) { 61 static INLINE void SetTpmCommandSize(uint8_t* buffer, uint32_t size) {
36 ToTpmUint32(buffer + 2, size); 62 ToTpmUint32(buffer + sizeof(uint16_t), size);
37 } 63 }
38 64
39 /* Gets the size field of a TPM command. 65 /* Gets the size field of a TPM command.
40 */ 66 */
41 static INLINE int TpmCommandSize(const uint8_t* buffer) { 67 static INLINE int TpmCommandSize(const uint8_t* buffer) {
42 uint32_t size; 68 uint32_t size;
43 FromTpmUint32(buffer + 2, &size); 69 FromTpmUint32(buffer + sizeof(uint16_t), &size);
44 return (int) size; 70 return (int) size;
45 } 71 }
46 72
47 /* Gets the code field of a TPM command. 73 /* Gets the code field of a TPM command.
48 */ 74 */
49 static INLINE int TpmCommandCode(const uint8_t* buffer) { 75 static INLINE int TpmCommandCode(const uint8_t* buffer) {
50 uint32_t code; 76 uint32_t code;
51 FromTpmUint32(buffer + 6, &code); 77 FromTpmUint32(buffer + sizeof(uint16_t) + sizeof(uint32_t), &code);
52 return code; 78 return code;
53 } 79 }
54 80
55 /* Gets the code field of a TPM result. 81 /* Gets the return code field of a TPM result.
56 */ 82 */
57 static INLINE int TpmReturnCode(const uint8_t* buffer) { 83 static INLINE int TpmReturnCode(const uint8_t* buffer) {
58 return TpmCommandCode(buffer); 84 return TpmCommandCode(buffer);
59 } 85 }
60 86
61 /* Checks for errors in a TPM response. 87 /* Checks for errors in a TPM response.
62 */ 88 */
63 static void CheckResult(uint8_t* request, uint8_t* response, bool warn_only) { 89 static void CheckResult(uint8_t* request, uint8_t* response, bool warn_only) {
64 int command = TpmCommandCode(request); 90 int command = TpmCommandCode(request);
65 int result = TpmReturnCode(response); 91 int result = TpmReturnCode(response);
66 if (result != TPM_SUCCESS) { 92 if (result != TPM_SUCCESS) {
67 (warn_only? warning : error)("command 0x%x failed: 0x%x\n", 93 (warn_only? warning : error)("command %d 0x%x failed: %d 0x%x\n",
68 command, result); 94 command, command, result, result);
69 } 95 }
70 } 96 }
71 97
98 /* Executes a command on the TPM.
99 */
100 void TpmExecute(const uint8_t *in, const uint32_t in_len,
101 uint8_t *out, uint32_t *pout_len) {
102 uint8_t response[TPM_MAX_COMMAND_SIZE];
103 if (in_len <= 0) {
104 error("invalid command length %d\n", in_len);
105 } else if (tpm_fd < 0) {
106 error("the TPM device was not opened. Forgot to call TlclLibinit?\n");
107 } else {
108 int n = write(tpm_fd, in, in_len);
109 if (n != in_len) {
110 error("write failure to TPM device: %s\n", strerror(errno));
111 }
112 n = read(tpm_fd, response, sizeof(response));
113 if (n == 0) {
114 error("null read from TPM device\n");
115 } else if (n < 0) {
116 error("read failure from TPM device: %s\n", strerror(errno));
117 } else {
118 if (n > *pout_len) {
119 error("TPM response too long for output buffer\n");
120 } else {
121 *pout_len = n;
122 memcpy(out, response, n);
123 }
124 }
125 }
126 }
127
72 /* Sends a request and receive a response. 128 /* Sends a request and receive a response.
73 */ 129 */
74 static void SendReceive(uint8_t* request, uint8_t* response, int max_length) { 130 static void SendReceive(uint8_t* request, uint8_t* response, int max_length) {
75 uint32_t response_length = max_length; 131 uint32_t response_length = max_length;
76 int tag, response_tag; 132 int tag, response_tag;
77 133
134 #if USE_TPM_EMULATOR
78 tpmemu_execute(request, TpmCommandSize(request), response, &response_length); 135 tpmemu_execute(request, TpmCommandSize(request), response, &response_length);
136 #else
137 TpmExecute(request, TpmCommandSize(request), response, &response_length);
138 #endif
139
140 {
141 int x = TpmCommandSize(request);
142 int y = response_length;
143 printf("request (%d bytes): ", x);
144 PrintBytes(request, 10);
145 PrintBytes(request + 10, x - 10);
146 printf("response (%d bytes): ", y);
147 PrintBytes(response, 10);
148 PrintBytes(response + 10, y - 10);
149 }
79 150
80 /* sanity checks */ 151 /* sanity checks */
81 tag = TpmTag(request); 152 tag = TpmTag(request);
82 response_tag = TpmTag(response); 153 response_tag = TpmTag(response);
83 assert( 154 assert(
84 (tag == TPM_TAG_RQU_COMMAND && 155 (tag == TPM_TAG_RQU_COMMAND &&
85 response_tag == TPM_TAG_RSP_COMMAND) || 156 response_tag == TPM_TAG_RSP_COMMAND) ||
86 (tag == TPM_TAG_RQU_AUTH1_COMMAND && 157 (tag == TPM_TAG_RQU_AUTH1_COMMAND &&
87 response_tag == TPM_TAG_RSP_AUTH1_COMMAND) || 158 response_tag == TPM_TAG_RSP_AUTH1_COMMAND) ||
88 (tag == TPM_TAG_RQU_AUTH2_COMMAND && 159 (tag == TPM_TAG_RQU_AUTH2_COMMAND &&
89 response_tag == TPM_TAG_RSP_AUTH2_COMMAND)); 160 response_tag == TPM_TAG_RSP_AUTH2_COMMAND));
90 assert(response_length == TpmCommandSize(response)); 161 assert(response_length == TpmCommandSize(response));
91 } 162 }
92 163
93 /* Sends a command and checks the result for errors. Note that this error 164 /* Sends a command and checks the result for errors. Note that this error
94 * checking is only meaningful when running in user mode. TODO: The entire 165 * checking is only meaningful when running in user mode. TODO: The entire
95 * error recovery strategy in the firmware needs more work. 166 * error recovery strategy in the firmware needs more work.
96 */ 167 */
97 static void Send(uint8_t* command) { 168 static void Send(uint8_t* command) {
98 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE]; 169 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE];
99 SendReceive(command, response, sizeof(response)); 170 SendReceive(command, response, sizeof(response));
100 CheckResult(command, response, false); 171 CheckResult(command, response, false);
101 } 172 }
102 173
103 174
104 /* Exported functions. 175 /* Exported functions.
105 */ 176 */
106 177
107 void TlclLibinit(void) { 178 void TlclLibinit(void) {
179 #if USE_TPM_EMULATOR
108 tpmemu_init(); 180 tpmemu_init();
181 #else
182 tpm_fd = open("/dev/tpm0", O_RDWR);
183 if (tpm_fd < 0) {
184 error("cannot open TPM device: %s\n", strerror(errno));
185 }
186 #endif
109 } 187 }
110 188
111 void TlclStartup(void) { 189 void TlclStartup(void) {
112 Send(tpm_startup_cmd.buffer); 190 Send(tpm_startup_cmd.buffer);
113 } 191 }
114 192
115 void TlclSelftestfull(void) { 193 void TlclSelftestfull(void) {
116 Send(tpm_selftestfull_cmd.buffer); 194 Send(tpm_selftestfull_cmd.buffer);
117 } 195 }
118 196
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 uint8_t* nv_read_cursor = response + kTpmResponseHeaderLength; 233 uint8_t* nv_read_cursor = response + kTpmResponseHeaderLength;
156 FromTpmUint32(nv_read_cursor, &result_length); 234 FromTpmUint32(nv_read_cursor, &result_length);
157 nv_read_cursor += sizeof(uint32_t); 235 nv_read_cursor += sizeof(uint32_t);
158 memcpy(data, nv_read_cursor, result_length); 236 memcpy(data, nv_read_cursor, result_length);
159 } 237 }
160 238
161 return result; 239 return result;
162 } 240 }
163 241
164 void TlclWriteLock(uint32_t index) { 242 void TlclWriteLock(uint32_t index) {
165 (void) TlclWrite(index, NULL, 0); 243 if (TlclWrite(index, NULL, 0) != TPM_SUCCESS) {
244 error("failed to write lock space 0x%x\n", index);
245 }
166 } 246 }
167 247
168 void TlclReadLock(uint32_t index) { 248 void TlclReadLock(uint32_t index) {
169 (void) TlclRead(index, NULL, 0); 249 if (TlclRead(index, NULL, 0) != TPM_SUCCESS) {
250 error("failed to read lock space 0x%x\n", index);
251 }
170 } 252 }
171 253
172 void TlclAssertPhysicalPresence(void) { 254 void TlclAssertPhysicalPresence(void) {
173 Send(tpm_physicalpresence_cmd.buffer); 255 Send(tpm_physicalpresence_cmd.buffer);
174 } 256 }
175 257
176 void TlclSetNvLocked(void) { 258 void TlclSetNvLocked(void) {
177 TlclDefineSpace(TPM_NV_INDEX_LOCK, 0, 0); 259 TlclDefineSpace(TPM_NV_INDEX_LOCK, 0, 0);
178 } 260 }
261
262 int TlclIsOwned(void) {
263 uint8_t response[TPM_LARGE_ENOUGH_COMMAND_SIZE + TPM_PUBEK_SIZE];
264 uint32_t result;
265 SendReceive(tpm_readpubek_cmd.buffer, response, sizeof(response));
266 result = TpmReturnCode(response);
267 return (result != TPM_SUCCESS);
268 }
OLDNEW
« no previous file with comments | « src/platform/tpm_lite/src/tlcl/generator.c ('k') | src/platform/tpm_lite/src/tlcl/tlcl_internal.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698