1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Copyright (c) 2013 The Chromium OS Authors.
4 * Coypright (c) 2013 Guntermann & Drunck GmbH
5 */
6
7 #define LOG_CATEGORY UCLASS_TPM
8
9 #include <common.h>
10 #include <dm.h>
11 #include <log.h>
12 #include <asm/unaligned.h>
13 #include <u-boot/sha1.h>
14 #include <tpm-common.h>
15 #include <tpm-v1.h>
16 #include "tpm-utils.h"
17
18 #ifdef CONFIG_TPM_AUTH_SESSIONS
19
20 #ifndef CONFIG_SHA1
21 #error "TPM_AUTH_SESSIONS require SHA1 to be configured, too"
22 #endif /* !CONFIG_SHA1 */
23
24 struct session_data {
25 int valid;
26 u32 handle;
27 u8 nonce_even[DIGEST_LENGTH];
28 u8 nonce_odd[DIGEST_LENGTH];
29 };
30
31 static struct session_data oiap_session = {0, };
32
33 #endif /* CONFIG_TPM_AUTH_SESSIONS */
34
tpm1_startup(struct udevice * dev,enum tpm_startup_type mode)35 u32 tpm1_startup(struct udevice *dev, enum tpm_startup_type mode)
36 {
37 const u8 command[12] = {
38 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x0,
39 };
40 const size_t mode_offset = 10;
41 u8 buf[COMMAND_BUFFER_SIZE];
42
43 if (pack_byte_string(buf, sizeof(buf), "sw",
44 0, command, sizeof(command),
45 mode_offset, mode))
46 return TPM_LIB_ERROR;
47
48 return tpm_sendrecv_command(dev, buf, NULL, NULL);
49 }
50
tpm1_resume(struct udevice * dev)51 u32 tpm1_resume(struct udevice *dev)
52 {
53 return tpm1_startup(dev, TPM_ST_STATE);
54 }
55
tpm1_self_test_full(struct udevice * dev)56 u32 tpm1_self_test_full(struct udevice *dev)
57 {
58 const u8 command[10] = {
59 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50,
60 };
61 return tpm_sendrecv_command(dev, command, NULL, NULL);
62 }
63
tpm1_continue_self_test(struct udevice * dev)64 u32 tpm1_continue_self_test(struct udevice *dev)
65 {
66 const u8 command[10] = {
67 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x53,
68 };
69 return tpm_sendrecv_command(dev, command, NULL, NULL);
70 }
71
tpm1_auto_start(struct udevice * dev)72 u32 tpm1_auto_start(struct udevice *dev)
73 {
74 u32 rc;
75
76 rc = tpm1_startup(dev, TPM_ST_CLEAR);
77 /* continue on if the TPM is already inited */
78 if (rc && rc != TPM_INVALID_POSTINIT)
79 return rc;
80
81 rc = tpm1_self_test_full(dev);
82
83 return rc;
84 }
85
tpm1_clear_and_reenable(struct udevice * dev)86 u32 tpm1_clear_and_reenable(struct udevice *dev)
87 {
88 u32 ret;
89
90 log_info("TPM: Clear and re-enable\n");
91 ret = tpm1_force_clear(dev);
92 if (ret != TPM_SUCCESS) {
93 log_err("Can't initiate a force clear\n");
94 return ret;
95 }
96
97 ret = tpm1_physical_enable(dev);
98 if (ret != TPM_SUCCESS) {
99 log_err("TPM: Can't set enabled state\n");
100 return ret;
101 }
102
103 ret = tpm1_physical_set_deactivated(dev, 0);
104 if (ret != TPM_SUCCESS) {
105 log_err("TPM: Can't set deactivated state\n");
106 return ret;
107 }
108
109 return TPM_SUCCESS;
110 }
111
tpm1_nv_define_space(struct udevice * dev,u32 index,u32 perm,u32 size)112 u32 tpm1_nv_define_space(struct udevice *dev, u32 index, u32 perm, u32 size)
113 {
114 const u8 command[101] = {
115 0x0, 0xc1, /* TPM_TAG */
116 0x0, 0x0, 0x0, 0x65, /* parameter size */
117 0x0, 0x0, 0x0, 0xcc, /* TPM_COMMAND_CODE */
118 /* TPM_NV_DATA_PUBLIC->... */
119 0x0, 0x18, /* ...->TPM_STRUCTURE_TAG */
120 0, 0, 0, 0, /* ...->TPM_NV_INDEX */
121 /* TPM_NV_DATA_PUBLIC->TPM_PCR_INFO_SHORT */
122 0x0, 0x3,
123 0, 0, 0,
124 0x1f,
125 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
126 /* TPM_NV_DATA_PUBLIC->TPM_PCR_INFO_SHORT */
127 0x0, 0x3,
128 0, 0, 0,
129 0x1f,
130 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
131 /* TPM_NV_ATTRIBUTES->... */
132 0x0, 0x17, /* ...->TPM_STRUCTURE_TAG */
133 0, 0, 0, 0, /* ...->attributes */
134 /* End of TPM_NV_ATTRIBUTES */
135 0, /* bReadSTClear */
136 0, /* bWriteSTClear */
137 0, /* bWriteDefine */
138 0, 0, 0, 0, /* size */
139 };
140 const size_t index_offset = 12;
141 const size_t perm_offset = 70;
142 const size_t size_offset = 77;
143 u8 buf[COMMAND_BUFFER_SIZE];
144
145 if (pack_byte_string(buf, sizeof(buf), "sddd",
146 0, command, sizeof(command),
147 index_offset, index,
148 perm_offset, perm,
149 size_offset, size))
150 return TPM_LIB_ERROR;
151
152 return tpm_sendrecv_command(dev, buf, NULL, NULL);
153 }
154
tpm1_nv_set_locked(struct udevice * dev)155 u32 tpm1_nv_set_locked(struct udevice *dev)
156 {
157 return tpm1_nv_define_space(dev, TPM_NV_INDEX_LOCK, 0, 0);
158 }
159
tpm1_nv_read_value(struct udevice * dev,u32 index,void * data,u32 count)160 u32 tpm1_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count)
161 {
162 const u8 command[22] = {
163 0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0xcf,
164 };
165 const size_t index_offset = 10;
166 const size_t length_offset = 18;
167 const size_t data_size_offset = 10;
168 const size_t data_offset = 14;
169 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
170 size_t response_length = sizeof(response);
171 u32 data_size;
172 u32 err;
173
174 if (pack_byte_string(buf, sizeof(buf), "sdd",
175 0, command, sizeof(command),
176 index_offset, index,
177 length_offset, count))
178 return TPM_LIB_ERROR;
179 err = tpm_sendrecv_command(dev, buf, response, &response_length);
180 if (err)
181 return err;
182 if (unpack_byte_string(response, response_length, "d",
183 data_size_offset, &data_size))
184 return TPM_LIB_ERROR;
185 if (data_size > count)
186 return TPM_LIB_ERROR;
187 if (unpack_byte_string(response, response_length, "s",
188 data_offset, data, data_size))
189 return TPM_LIB_ERROR;
190
191 return 0;
192 }
193
tpm1_nv_write_value(struct udevice * dev,u32 index,const void * data,u32 length)194 u32 tpm1_nv_write_value(struct udevice *dev, u32 index, const void *data,
195 u32 length)
196 {
197 const u8 command[256] = {
198 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd,
199 };
200 const size_t command_size_offset = 2;
201 const size_t index_offset = 10;
202 const size_t length_offset = 18;
203 const size_t data_offset = 22;
204 const size_t write_info_size = 12;
205 const u32 total_length =
206 TPM_REQUEST_HEADER_LENGTH + write_info_size + length;
207 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
208 size_t response_length = sizeof(response);
209 u32 err;
210
211 if (pack_byte_string(buf, sizeof(buf), "sddds",
212 0, command, sizeof(command),
213 command_size_offset, total_length,
214 index_offset, index,
215 length_offset, length,
216 data_offset, data, length))
217 return TPM_LIB_ERROR;
218 err = tpm_sendrecv_command(dev, buf, response, &response_length);
219 if (err)
220 return err;
221
222 return 0;
223 }
224
tpm1_extend(struct udevice * dev,u32 index,const void * in_digest,void * out_digest)225 u32 tpm1_extend(struct udevice *dev, u32 index, const void *in_digest,
226 void *out_digest)
227 {
228 const u8 command[34] = {
229 0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x14,
230 };
231 const size_t index_offset = 10;
232 const size_t in_digest_offset = 14;
233 const size_t out_digest_offset = 10;
234 u8 buf[COMMAND_BUFFER_SIZE];
235 u8 response[TPM_RESPONSE_HEADER_LENGTH + PCR_DIGEST_LENGTH];
236 size_t response_length = sizeof(response);
237 u32 err;
238
239 if (pack_byte_string(buf, sizeof(buf), "sds",
240 0, command, sizeof(command),
241 index_offset, index,
242 in_digest_offset, in_digest,
243 PCR_DIGEST_LENGTH))
244 return TPM_LIB_ERROR;
245 err = tpm_sendrecv_command(dev, buf, response, &response_length);
246 if (err)
247 return err;
248
249 if (unpack_byte_string(response, response_length, "s",
250 out_digest_offset, out_digest,
251 PCR_DIGEST_LENGTH))
252 return TPM_LIB_ERROR;
253
254 return 0;
255 }
256
tpm1_pcr_read(struct udevice * dev,u32 index,void * data,size_t count)257 u32 tpm1_pcr_read(struct udevice *dev, u32 index, void *data, size_t count)
258 {
259 const u8 command[14] = {
260 0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x15,
261 };
262 const size_t index_offset = 10;
263 const size_t out_digest_offset = 10;
264 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
265 size_t response_length = sizeof(response);
266 u32 err;
267
268 if (count < PCR_DIGEST_LENGTH)
269 return TPM_LIB_ERROR;
270
271 if (pack_byte_string(buf, sizeof(buf), "sd",
272 0, command, sizeof(command),
273 index_offset, index))
274 return TPM_LIB_ERROR;
275 err = tpm_sendrecv_command(dev, buf, response, &response_length);
276 if (err)
277 return err;
278 if (unpack_byte_string(response, response_length, "s",
279 out_digest_offset, data, PCR_DIGEST_LENGTH))
280 return TPM_LIB_ERROR;
281
282 return 0;
283 }
284
tpm1_tsc_physical_presence(struct udevice * dev,u16 presence)285 u32 tpm1_tsc_physical_presence(struct udevice *dev, u16 presence)
286 {
287 const u8 command[12] = {
288 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x0,
289 };
290 const size_t presence_offset = 10;
291 u8 buf[COMMAND_BUFFER_SIZE];
292
293 if (pack_byte_string(buf, sizeof(buf), "sw",
294 0, command, sizeof(command),
295 presence_offset, presence))
296 return TPM_LIB_ERROR;
297
298 return tpm_sendrecv_command(dev, buf, NULL, NULL);
299 }
300
tpm1_finalise_physical_presence(struct udevice * dev)301 u32 tpm1_finalise_physical_presence(struct udevice *dev)
302 {
303 const u8 command[12] = {
304 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x2, 0xa0,
305 };
306
307 return tpm_sendrecv_command(dev, command, NULL, NULL);
308 }
309
tpm1_read_pubek(struct udevice * dev,void * data,size_t count)310 u32 tpm1_read_pubek(struct udevice *dev, void *data, size_t count)
311 {
312 const u8 command[30] = {
313 0x0, 0xc1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x7c,
314 };
315 const size_t response_size_offset = 2;
316 const size_t data_offset = 10;
317 const size_t header_and_checksum_size = TPM_RESPONSE_HEADER_LENGTH + 20;
318 u8 response[COMMAND_BUFFER_SIZE + TPM_PUBEK_SIZE];
319 size_t response_length = sizeof(response);
320 u32 data_size;
321 u32 err;
322
323 err = tpm_sendrecv_command(dev, command, response, &response_length);
324 if (err)
325 return err;
326 if (unpack_byte_string(response, response_length, "d",
327 response_size_offset, &data_size))
328 return TPM_LIB_ERROR;
329 if (data_size < header_and_checksum_size)
330 return TPM_LIB_ERROR;
331 data_size -= header_and_checksum_size;
332 if (data_size > count)
333 return TPM_LIB_ERROR;
334 if (unpack_byte_string(response, response_length, "s",
335 data_offset, data, data_size))
336 return TPM_LIB_ERROR;
337
338 return 0;
339 }
340
tpm1_force_clear(struct udevice * dev)341 u32 tpm1_force_clear(struct udevice *dev)
342 {
343 const u8 command[10] = {
344 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x5d,
345 };
346
347 return tpm_sendrecv_command(dev, command, NULL, NULL);
348 }
349
tpm1_physical_enable(struct udevice * dev)350 u32 tpm1_physical_enable(struct udevice *dev)
351 {
352 const u8 command[10] = {
353 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x6f,
354 };
355
356 return tpm_sendrecv_command(dev, command, NULL, NULL);
357 }
358
tpm1_physical_disable(struct udevice * dev)359 u32 tpm1_physical_disable(struct udevice *dev)
360 {
361 const u8 command[10] = {
362 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x70,
363 };
364
365 return tpm_sendrecv_command(dev, command, NULL, NULL);
366 }
367
tpm1_physical_set_deactivated(struct udevice * dev,u8 state)368 u32 tpm1_physical_set_deactivated(struct udevice *dev, u8 state)
369 {
370 const u8 command[11] = {
371 0x0, 0xc1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72,
372 };
373 const size_t state_offset = 10;
374 u8 buf[COMMAND_BUFFER_SIZE];
375
376 if (pack_byte_string(buf, sizeof(buf), "sb",
377 0, command, sizeof(command),
378 state_offset, state))
379 return TPM_LIB_ERROR;
380
381 return tpm_sendrecv_command(dev, buf, NULL, NULL);
382 }
383
tpm1_get_capability(struct udevice * dev,u32 cap_area,u32 sub_cap,void * cap,size_t count)384 u32 tpm1_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap,
385 void *cap, size_t count)
386 {
387 const u8 command[22] = {
388 0x0, 0xc1, /* TPM_TAG */
389 0x0, 0x0, 0x0, 0x16, /* parameter size */
390 0x0, 0x0, 0x0, 0x65, /* TPM_COMMAND_CODE */
391 0x0, 0x0, 0x0, 0x0, /* TPM_CAPABILITY_AREA */
392 0x0, 0x0, 0x0, 0x4, /* subcap size */
393 0x0, 0x0, 0x0, 0x0, /* subcap value */
394 };
395 const size_t cap_area_offset = 10;
396 const size_t sub_cap_offset = 18;
397 const size_t cap_offset = 14;
398 const size_t cap_size_offset = 10;
399 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
400 size_t response_length = sizeof(response);
401 u32 cap_size;
402 u32 err;
403
404 if (pack_byte_string(buf, sizeof(buf), "sdd",
405 0, command, sizeof(command),
406 cap_area_offset, cap_area,
407 sub_cap_offset, sub_cap))
408 return TPM_LIB_ERROR;
409 err = tpm_sendrecv_command(dev, buf, response, &response_length);
410 if (err)
411 return err;
412 if (unpack_byte_string(response, response_length, "d",
413 cap_size_offset, &cap_size))
414 return TPM_LIB_ERROR;
415 if (cap_size > response_length || cap_size > count)
416 return TPM_LIB_ERROR;
417 if (unpack_byte_string(response, response_length, "s",
418 cap_offset, cap, cap_size))
419 return TPM_LIB_ERROR;
420
421 return 0;
422 }
423
tpm1_get_permanent_flags(struct udevice * dev,struct tpm_permanent_flags * pflags)424 u32 tpm1_get_permanent_flags(struct udevice *dev,
425 struct tpm_permanent_flags *pflags)
426 {
427 const u8 command[22] = {
428 0x0, 0xc1, /* TPM_TAG */
429 0x0, 0x0, 0x0, 0x16, /* parameter size */
430 0x0, 0x0, 0x0, 0x65, /* TPM_COMMAND_CODE */
431 0x0, 0x0, 0x0, 0x4, /* TPM_CAP_FLAG_PERM */
432 0x0, 0x0, 0x0, 0x4, /* subcap size */
433 0x0, 0x0, 0x1, 0x8, /* subcap value */
434 };
435 const size_t data_size_offset = TPM_HEADER_SIZE;
436 const size_t data_offset = TPM_HEADER_SIZE + sizeof(u32);
437 u8 response[COMMAND_BUFFER_SIZE];
438 size_t response_length = sizeof(response);
439 u32 err;
440 u32 data_size;
441
442 err = tpm_sendrecv_command(dev, command, response, &response_length);
443 if (err)
444 return err;
445 if (unpack_byte_string(response, response_length, "d",
446 data_size_offset, &data_size)) {
447 log_err("Cannot unpack data size\n");
448 return TPM_LIB_ERROR;
449 }
450 if (data_size < sizeof(*pflags)) {
451 log_err("Data size too small\n");
452 return TPM_LIB_ERROR;
453 }
454 if (unpack_byte_string(response, response_length, "s",
455 data_offset, pflags, sizeof(*pflags))) {
456 log_err("Cannot unpack pflags\n");
457 return TPM_LIB_ERROR;
458 }
459
460 return 0;
461 }
462
tpm1_get_permissions(struct udevice * dev,u32 index,u32 * perm)463 u32 tpm1_get_permissions(struct udevice *dev, u32 index, u32 *perm)
464 {
465 const u8 command[22] = {
466 0x0, 0xc1, /* TPM_TAG */
467 0x0, 0x0, 0x0, 0x16, /* parameter size */
468 0x0, 0x0, 0x0, 0x65, /* TPM_COMMAND_CODE */
469 0x0, 0x0, 0x0, 0x11,
470 0x0, 0x0, 0x0, 0x4,
471 };
472 const size_t index_offset = 18;
473 const size_t perm_offset = 74;
474 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
475 size_t response_length = sizeof(response);
476 u32 err;
477
478 if (pack_byte_string(buf, sizeof(buf), "sd",
479 0, command, sizeof(command),
480 index_offset, index))
481 return TPM_LIB_ERROR;
482 err = tpm_sendrecv_command(dev, buf, response, &response_length);
483 if (err)
484 return err;
485 if (unpack_byte_string(response, response_length, "d",
486 perm_offset, perm))
487 return TPM_LIB_ERROR;
488
489 return 0;
490 }
491
492 #ifdef CONFIG_TPM_FLUSH_RESOURCES
tpm1_flush_specific(struct udevice * dev,u32 key_handle,u32 resource_type)493 u32 tpm1_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type)
494 {
495 const u8 command[18] = {
496 0x00, 0xc1, /* TPM_TAG */
497 0x00, 0x00, 0x00, 0x12, /* parameter size */
498 0x00, 0x00, 0x00, 0xba, /* TPM_COMMAND_CODE */
499 0x00, 0x00, 0x00, 0x00, /* key handle */
500 0x00, 0x00, 0x00, 0x00, /* resource type */
501 };
502 const size_t key_handle_offset = 10;
503 const size_t resource_type_offset = 14;
504 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
505 size_t response_length = sizeof(response);
506 u32 err;
507
508 if (pack_byte_string(buf, sizeof(buf), "sdd",
509 0, command, sizeof(command),
510 key_handle_offset, key_handle,
511 resource_type_offset, resource_type))
512 return TPM_LIB_ERROR;
513
514 err = tpm_sendrecv_command(dev, buf, response, &response_length);
515 if (err)
516 return err;
517 return 0;
518 }
519 #endif /* CONFIG_TPM_FLUSH_RESOURCES */
520
521 #ifdef CONFIG_TPM_AUTH_SESSIONS
522
523 /**
524 * Fill an authentication block in a request.
525 * This func can create the first as well as the second auth block (for
526 * double authorized commands).
527 *
528 * @param request pointer to the request (w/ uninitialised auth data)
529 * @param request_len0 length of the request without auth data
530 * @param handles_len length of the handles area in request
531 * @param auth_session pointer to the (valid) auth session to be used
532 * @param request_auth pointer to the auth block of the request to be filled
533 * @param auth authentication data (HMAC key)
534 */
create_request_auth(const void * request,size_t request_len0,size_t handles_len,struct session_data * auth_session,void * request_auth,const void * auth)535 static u32 create_request_auth(const void *request, size_t request_len0,
536 size_t handles_len,
537 struct session_data *auth_session,
538 void *request_auth, const void *auth)
539 {
540 u8 hmac_data[DIGEST_LENGTH * 3 + 1];
541 sha1_context hash_ctx;
542 const size_t command_code_offset = 6;
543 const size_t auth_nonce_odd_offset = 4;
544 const size_t auth_continue_offset = 24;
545 const size_t auth_auth_offset = 25;
546
547 if (!auth_session || !auth_session->valid)
548 return TPM_LIB_ERROR;
549
550 sha1_starts(&hash_ctx);
551 sha1_update(&hash_ctx, request + command_code_offset, 4);
552 if (request_len0 > TPM_REQUEST_HEADER_LENGTH + handles_len)
553 sha1_update(&hash_ctx,
554 request + TPM_REQUEST_HEADER_LENGTH + handles_len,
555 request_len0 - TPM_REQUEST_HEADER_LENGTH
556 - handles_len);
557 sha1_finish(&hash_ctx, hmac_data);
558
559 sha1_starts(&hash_ctx);
560 sha1_update(&hash_ctx, auth_session->nonce_odd, DIGEST_LENGTH);
561 sha1_update(&hash_ctx, hmac_data, sizeof(hmac_data));
562 sha1_finish(&hash_ctx, auth_session->nonce_odd);
563
564 if (pack_byte_string(request_auth, TPM_REQUEST_AUTH_LENGTH, "dsb",
565 0, auth_session->handle,
566 auth_nonce_odd_offset, auth_session->nonce_odd,
567 DIGEST_LENGTH,
568 auth_continue_offset, 1))
569 return TPM_LIB_ERROR;
570 if (pack_byte_string(hmac_data, sizeof(hmac_data), "ss",
571 DIGEST_LENGTH,
572 auth_session->nonce_even,
573 DIGEST_LENGTH,
574 2 * DIGEST_LENGTH,
575 request_auth + auth_nonce_odd_offset,
576 DIGEST_LENGTH + 1))
577 return TPM_LIB_ERROR;
578 sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
579 request_auth + auth_auth_offset);
580
581 return TPM_SUCCESS;
582 }
583
584 /**
585 * Verify an authentication block in a response.
586 * Since this func updates the nonce_even in the session data it has to be
587 * called when receiving a succesfull AUTH response.
588 * This func can verify the first as well as the second auth block (for
589 * double authorized commands).
590 *
591 * @param command_code command code of the request
592 * @param response pointer to the request (w/ uninitialised auth data)
593 * @param handles_len length of the handles area in response
594 * @param auth_session pointer to the (valid) auth session to be used
595 * @param response_auth pointer to the auth block of the response to be verified
596 * @param auth authentication data (HMAC key)
597 */
verify_response_auth(u32 command_code,const void * response,size_t response_len0,size_t handles_len,struct session_data * auth_session,const void * response_auth,const void * auth)598 static u32 verify_response_auth(u32 command_code, const void *response,
599 size_t response_len0, size_t handles_len,
600 struct session_data *auth_session,
601 const void *response_auth, const void *auth)
602 {
603 u8 hmac_data[DIGEST_LENGTH * 3 + 1];
604 u8 computed_auth[DIGEST_LENGTH];
605 sha1_context hash_ctx;
606 const size_t return_code_offset = 6;
607 const size_t auth_continue_offset = 20;
608 const size_t auth_auth_offset = 21;
609 u8 auth_continue;
610
611 if (!auth_session || !auth_session->valid)
612 return TPM_AUTHFAIL;
613 if (pack_byte_string(hmac_data, sizeof(hmac_data), "d",
614 0, command_code))
615 return TPM_LIB_ERROR;
616 if (response_len0 < TPM_RESPONSE_HEADER_LENGTH)
617 return TPM_LIB_ERROR;
618
619 sha1_starts(&hash_ctx);
620 sha1_update(&hash_ctx, response + return_code_offset, 4);
621 sha1_update(&hash_ctx, hmac_data, 4);
622 if (response_len0 > TPM_RESPONSE_HEADER_LENGTH + handles_len)
623 sha1_update(&hash_ctx,
624 response + TPM_RESPONSE_HEADER_LENGTH + handles_len,
625 response_len0 - TPM_RESPONSE_HEADER_LENGTH
626 - handles_len);
627 sha1_finish(&hash_ctx, hmac_data);
628
629 memcpy(auth_session->nonce_even, response_auth, DIGEST_LENGTH);
630 auth_continue = ((u8 *)response_auth)[auth_continue_offset];
631 if (pack_byte_string(hmac_data, sizeof(hmac_data), "ssb",
632 DIGEST_LENGTH,
633 response_auth,
634 DIGEST_LENGTH,
635 2 * DIGEST_LENGTH,
636 auth_session->nonce_odd,
637 DIGEST_LENGTH,
638 3 * DIGEST_LENGTH,
639 auth_continue))
640 return TPM_LIB_ERROR;
641
642 sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
643 computed_auth);
644
645 if (memcmp(computed_auth, response_auth + auth_auth_offset,
646 DIGEST_LENGTH))
647 return TPM_AUTHFAIL;
648
649 return TPM_SUCCESS;
650 }
651
tpm1_terminate_auth_session(struct udevice * dev,u32 auth_handle)652 u32 tpm1_terminate_auth_session(struct udevice *dev, u32 auth_handle)
653 {
654 const u8 command[18] = {
655 0x00, 0xc1, /* TPM_TAG */
656 0x00, 0x00, 0x00, 0x00, /* parameter size */
657 0x00, 0x00, 0x00, 0xba, /* TPM_COMMAND_CODE */
658 0x00, 0x00, 0x00, 0x00, /* TPM_HANDLE */
659 0x00, 0x00, 0x00, 0x02, /* TPM_RESOURCE_TYPE */
660 };
661 const size_t req_handle_offset = TPM_REQUEST_HEADER_LENGTH;
662 u8 request[COMMAND_BUFFER_SIZE];
663
664 if (pack_byte_string(request, sizeof(request), "sd",
665 0, command, sizeof(command),
666 req_handle_offset, auth_handle))
667 return TPM_LIB_ERROR;
668 if (oiap_session.valid && oiap_session.handle == auth_handle)
669 oiap_session.valid = 0;
670
671 return tpm_sendrecv_command(dev, request, NULL, NULL);
672 }
673
tpm1_end_oiap(struct udevice * dev)674 u32 tpm1_end_oiap(struct udevice *dev)
675 {
676 u32 err = TPM_SUCCESS;
677
678 if (oiap_session.valid)
679 err = tpm1_terminate_auth_session(dev, oiap_session.handle);
680 return err;
681 }
682
tpm1_oiap(struct udevice * dev,u32 * auth_handle)683 u32 tpm1_oiap(struct udevice *dev, u32 *auth_handle)
684 {
685 const u8 command[10] = {
686 0x00, 0xc1, /* TPM_TAG */
687 0x00, 0x00, 0x00, 0x0a, /* parameter size */
688 0x00, 0x00, 0x00, 0x0a, /* TPM_COMMAND_CODE */
689 };
690 const size_t res_auth_handle_offset = TPM_RESPONSE_HEADER_LENGTH;
691 const size_t res_nonce_even_offset = TPM_RESPONSE_HEADER_LENGTH + 4;
692 u8 response[COMMAND_BUFFER_SIZE];
693 size_t response_length = sizeof(response);
694 u32 err;
695
696 if (oiap_session.valid)
697 tpm1_terminate_auth_session(dev, oiap_session.handle);
698
699 err = tpm_sendrecv_command(dev, command, response, &response_length);
700 if (err)
701 return err;
702 if (unpack_byte_string(response, response_length, "ds",
703 res_auth_handle_offset, &oiap_session.handle,
704 res_nonce_even_offset, &oiap_session.nonce_even,
705 (u32)DIGEST_LENGTH))
706 return TPM_LIB_ERROR;
707 oiap_session.valid = 1;
708 if (auth_handle)
709 *auth_handle = oiap_session.handle;
710 return 0;
711 }
712
tpm1_load_key2_oiap(struct udevice * dev,u32 parent_handle,const void * key,size_t key_length,const void * parent_key_usage_auth,u32 * key_handle)713 u32 tpm1_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key,
714 size_t key_length, const void *parent_key_usage_auth,
715 u32 *key_handle)
716 {
717 const u8 command[14] = {
718 0x00, 0xc2, /* TPM_TAG */
719 0x00, 0x00, 0x00, 0x00, /* parameter size */
720 0x00, 0x00, 0x00, 0x41, /* TPM_COMMAND_CODE */
721 0x00, 0x00, 0x00, 0x00, /* parent handle */
722 };
723 const size_t req_size_offset = 2;
724 const size_t req_parent_handle_offset = TPM_REQUEST_HEADER_LENGTH;
725 const size_t req_key_offset = TPM_REQUEST_HEADER_LENGTH + 4;
726 const size_t res_handle_offset = TPM_RESPONSE_HEADER_LENGTH;
727 u8 request[sizeof(command) + TPM_KEY12_MAX_LENGTH +
728 TPM_REQUEST_AUTH_LENGTH];
729 u8 response[COMMAND_BUFFER_SIZE];
730 size_t response_length = sizeof(response);
731 u32 err;
732
733 if (!oiap_session.valid) {
734 err = tpm1_oiap(dev, NULL);
735 if (err)
736 return err;
737 }
738 if (pack_byte_string(request, sizeof(request), "sdds",
739 0, command, sizeof(command),
740 req_size_offset,
741 sizeof(command) + key_length
742 + TPM_REQUEST_AUTH_LENGTH,
743 req_parent_handle_offset, parent_handle,
744 req_key_offset, key, key_length
745 ))
746 return TPM_LIB_ERROR;
747
748 err = create_request_auth(request, sizeof(command) + key_length, 4,
749 &oiap_session,
750 request + sizeof(command) + key_length,
751 parent_key_usage_auth);
752 if (err)
753 return err;
754 err = tpm_sendrecv_command(dev, request, response, &response_length);
755 if (err) {
756 if (err == TPM_AUTHFAIL)
757 oiap_session.valid = 0;
758 return err;
759 }
760
761 err = verify_response_auth(0x00000041, response,
762 response_length - TPM_RESPONSE_AUTH_LENGTH,
763 4, &oiap_session,
764 response + response_length -
765 TPM_RESPONSE_AUTH_LENGTH,
766 parent_key_usage_auth);
767 if (err)
768 return err;
769
770 if (key_handle) {
771 if (unpack_byte_string(response, response_length, "d",
772 res_handle_offset, key_handle))
773 return TPM_LIB_ERROR;
774 }
775
776 return 0;
777 }
778
tpm1_get_pub_key_oiap(struct udevice * dev,u32 key_handle,const void * usage_auth,void * pubkey,size_t * pubkey_len)779 u32 tpm1_get_pub_key_oiap(struct udevice *dev, u32 key_handle,
780 const void *usage_auth, void *pubkey,
781 size_t *pubkey_len)
782 {
783 const u8 command[14] = {
784 0x00, 0xc2, /* TPM_TAG */
785 0x00, 0x00, 0x00, 0x00, /* parameter size */
786 0x00, 0x00, 0x00, 0x21, /* TPM_COMMAND_CODE */
787 0x00, 0x00, 0x00, 0x00, /* key handle */
788 };
789 const size_t req_size_offset = 2;
790 const size_t req_key_handle_offset = TPM_REQUEST_HEADER_LENGTH;
791 const size_t res_pubkey_offset = TPM_RESPONSE_HEADER_LENGTH;
792 u8 request[sizeof(command) + TPM_REQUEST_AUTH_LENGTH];
793 u8 response[TPM_RESPONSE_HEADER_LENGTH + TPM_PUBKEY_MAX_LENGTH +
794 TPM_RESPONSE_AUTH_LENGTH];
795 size_t response_length = sizeof(response);
796 u32 err;
797
798 if (!oiap_session.valid) {
799 err = tpm1_oiap(dev, NULL);
800 if (err)
801 return err;
802 }
803 if (pack_byte_string(request, sizeof(request), "sdd",
804 0, command, sizeof(command),
805 req_size_offset,
806 (u32)(sizeof(command)
807 + TPM_REQUEST_AUTH_LENGTH),
808 req_key_handle_offset, key_handle
809 ))
810 return TPM_LIB_ERROR;
811 err = create_request_auth(request, sizeof(command), 4, &oiap_session,
812 request + sizeof(command), usage_auth);
813 if (err)
814 return err;
815 err = tpm_sendrecv_command(dev, request, response, &response_length);
816 if (err) {
817 if (err == TPM_AUTHFAIL)
818 oiap_session.valid = 0;
819 return err;
820 }
821 err = verify_response_auth(0x00000021, response,
822 response_length - TPM_RESPONSE_AUTH_LENGTH,
823 0, &oiap_session,
824 response + response_length -
825 TPM_RESPONSE_AUTH_LENGTH,
826 usage_auth);
827 if (err)
828 return err;
829
830 if (pubkey) {
831 if ((response_length - TPM_RESPONSE_HEADER_LENGTH
832 - TPM_RESPONSE_AUTH_LENGTH) > *pubkey_len)
833 return TPM_LIB_ERROR;
834 *pubkey_len = response_length - TPM_RESPONSE_HEADER_LENGTH
835 - TPM_RESPONSE_AUTH_LENGTH;
836 memcpy(pubkey, response + res_pubkey_offset,
837 response_length - TPM_RESPONSE_HEADER_LENGTH
838 - TPM_RESPONSE_AUTH_LENGTH);
839 }
840
841 return 0;
842 }
843
844 #ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
tpm1_find_key_sha1(struct udevice * dev,const u8 auth[20],const u8 pubkey_digest[20],u32 * handle)845 u32 tpm1_find_key_sha1(struct udevice *dev, const u8 auth[20],
846 const u8 pubkey_digest[20], u32 *handle)
847 {
848 u16 key_count;
849 u32 key_handles[10];
850 u8 buf[288];
851 u8 *ptr;
852 u32 err;
853 u8 digest[20];
854 size_t buf_len;
855 unsigned int i;
856
857 /* fetch list of already loaded keys in the TPM */
858 err = tpm1_get_capability(dev, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
859 sizeof(buf));
860 if (err)
861 return -1;
862 key_count = get_unaligned_be16(buf);
863 ptr = buf + 2;
864 for (i = 0; i < key_count; ++i, ptr += 4)
865 key_handles[i] = get_unaligned_be32(ptr);
866
867 /* now search a(/ the) key which we can access with the given auth */
868 for (i = 0; i < key_count; ++i) {
869 buf_len = sizeof(buf);
870 err = tpm1_get_pub_key_oiap(dev, key_handles[i], auth, buf, &buf_len);
871 if (err && err != TPM_AUTHFAIL)
872 return -1;
873 if (err)
874 continue;
875 sha1_csum(buf, buf_len, digest);
876 if (!memcmp(digest, pubkey_digest, 20)) {
877 *handle = key_handles[i];
878 return 0;
879 }
880 }
881 return 1;
882 }
883 #endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
884
885 #endif /* CONFIG_TPM_AUTH_SESSIONS */
886
tpm1_get_random(struct udevice * dev,void * data,u32 count)887 u32 tpm1_get_random(struct udevice *dev, void *data, u32 count)
888 {
889 const u8 command[14] = {
890 0x0, 0xc1, /* TPM_TAG */
891 0x0, 0x0, 0x0, 0xe, /* parameter size */
892 0x0, 0x0, 0x0, 0x46, /* TPM_COMMAND_CODE */
893 };
894 const size_t length_offset = 10;
895 const size_t data_size_offset = 10;
896 const size_t data_offset = 14;
897 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
898 size_t response_length = sizeof(response);
899 u32 data_size;
900 u8 *out = data;
901
902 while (count > 0) {
903 u32 this_bytes = min((size_t)count,
904 sizeof(response) - data_offset);
905 u32 err;
906
907 if (pack_byte_string(buf, sizeof(buf), "sd",
908 0, command, sizeof(command),
909 length_offset, this_bytes))
910 return TPM_LIB_ERROR;
911 err = tpm_sendrecv_command(dev, buf, response,
912 &response_length);
913 if (err)
914 return err;
915 if (unpack_byte_string(response, response_length, "d",
916 data_size_offset, &data_size))
917 return TPM_LIB_ERROR;
918 if (data_size > count)
919 return TPM_LIB_ERROR;
920 if (unpack_byte_string(response, response_length, "s",
921 data_offset, out, data_size))
922 return TPM_LIB_ERROR;
923
924 count -= data_size;
925 out += data_size;
926 }
927
928 return 0;
929 }
930