1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2013 The Chromium OS Authors.
4 * Coypright (c) 2013 Guntermann & Drunck GmbH
7 #define LOG_CATEGORY UCLASS_TPM
12 #include <asm/unaligned.h>
13 #include <u-boot/sha1.h>
14 #include <tpm-common.h>
16 #include "tpm-utils.h"
18 #ifdef CONFIG_TPM_AUTH_SESSIONS
21 #error "TPM_AUTH_SESSIONS require SHA1 to be configured, too"
22 #endif /* !CONFIG_SHA1 */
27 u8 nonce_even[DIGEST_LENGTH];
28 u8 nonce_odd[DIGEST_LENGTH];
31 static struct session_data oiap_session = {0, };
33 #endif /* CONFIG_TPM_AUTH_SESSIONS */
35 u32 tpm1_startup(struct udevice *dev, enum tpm_startup_type mode)
37 const u8 command[12] = {
38 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x0,
40 const size_t mode_offset = 10;
41 u8 buf[COMMAND_BUFFER_SIZE];
43 if (pack_byte_string(buf, sizeof(buf), "sw",
44 0, command, sizeof(command),
48 return tpm_sendrecv_command(dev, buf, NULL, NULL);
51 u32 tpm1_resume(struct udevice *dev)
53 return tpm1_startup(dev, TPM_ST_STATE);
56 u32 tpm1_self_test_full(struct udevice *dev)
58 const u8 command[10] = {
59 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50,
61 return tpm_sendrecv_command(dev, command, NULL, NULL);
64 u32 tpm1_continue_self_test(struct udevice *dev)
66 const u8 command[10] = {
67 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x53,
69 return tpm_sendrecv_command(dev, command, NULL, NULL);
72 u32 tpm1_clear_and_reenable(struct udevice *dev)
76 log_info("TPM: Clear and re-enable\n");
77 ret = tpm1_force_clear(dev);
78 if (ret != TPM_SUCCESS) {
79 log_err("Can't initiate a force clear\n");
83 ret = tpm1_physical_enable(dev);
84 if (ret != TPM_SUCCESS) {
85 log_err("TPM: Can't set enabled state\n");
89 ret = tpm1_physical_set_deactivated(dev, 0);
90 if (ret != TPM_SUCCESS) {
91 log_err("TPM: Can't set deactivated state\n");
98 u32 tpm1_nv_define_space(struct udevice *dev, u32 index, u32 perm, u32 size)
100 const u8 command[101] = {
101 0x0, 0xc1, /* TPM_TAG */
102 0x0, 0x0, 0x0, 0x65, /* parameter size */
103 0x0, 0x0, 0x0, 0xcc, /* TPM_COMMAND_CODE */
104 /* TPM_NV_DATA_PUBLIC->... */
105 0x0, 0x18, /* ...->TPM_STRUCTURE_TAG */
106 0, 0, 0, 0, /* ...->TPM_NV_INDEX */
107 /* TPM_NV_DATA_PUBLIC->TPM_PCR_INFO_SHORT */
111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112 /* TPM_NV_DATA_PUBLIC->TPM_PCR_INFO_SHORT */
116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
117 /* TPM_NV_ATTRIBUTES->... */
118 0x0, 0x17, /* ...->TPM_STRUCTURE_TAG */
119 0, 0, 0, 0, /* ...->attributes */
120 /* End of TPM_NV_ATTRIBUTES */
121 0, /* bReadSTClear */
122 0, /* bWriteSTClear */
123 0, /* bWriteDefine */
124 0, 0, 0, 0, /* size */
126 const size_t index_offset = 12;
127 const size_t perm_offset = 70;
128 const size_t size_offset = 77;
129 u8 buf[COMMAND_BUFFER_SIZE];
131 if (pack_byte_string(buf, sizeof(buf), "sddd",
132 0, command, sizeof(command),
136 return TPM_LIB_ERROR;
138 return tpm_sendrecv_command(dev, buf, NULL, NULL);
141 u32 tpm1_nv_set_locked(struct udevice *dev)
143 return tpm1_nv_define_space(dev, TPM_NV_INDEX_LOCK, 0, 0);
146 u32 tpm1_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count)
148 const u8 command[22] = {
149 0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0xcf,
151 const size_t index_offset = 10;
152 const size_t length_offset = 18;
153 const size_t data_size_offset = 10;
154 const size_t data_offset = 14;
155 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
156 size_t response_length = sizeof(response);
160 if (pack_byte_string(buf, sizeof(buf), "sdd",
161 0, command, sizeof(command),
163 length_offset, count))
164 return TPM_LIB_ERROR;
165 err = tpm_sendrecv_command(dev, buf, response, &response_length);
168 if (unpack_byte_string(response, response_length, "d",
169 data_size_offset, &data_size))
170 return TPM_LIB_ERROR;
171 if (data_size > count)
172 return TPM_LIB_ERROR;
173 if (unpack_byte_string(response, response_length, "s",
174 data_offset, data, data_size))
175 return TPM_LIB_ERROR;
180 u32 tpm1_nv_write_value(struct udevice *dev, u32 index, const void *data,
183 const u8 command[256] = {
184 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd,
186 const size_t command_size_offset = 2;
187 const size_t index_offset = 10;
188 const size_t length_offset = 18;
189 const size_t data_offset = 22;
190 const size_t write_info_size = 12;
191 const u32 total_length =
192 TPM_REQUEST_HEADER_LENGTH + write_info_size + length;
193 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
194 size_t response_length = sizeof(response);
197 if (pack_byte_string(buf, sizeof(buf), "sddds",
198 0, command, sizeof(command),
199 command_size_offset, total_length,
201 length_offset, length,
202 data_offset, data, length))
203 return TPM_LIB_ERROR;
204 err = tpm_sendrecv_command(dev, buf, response, &response_length);
211 u32 tpm1_extend(struct udevice *dev, u32 index, const void *in_digest,
214 const u8 command[34] = {
215 0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x14,
217 const size_t index_offset = 10;
218 const size_t in_digest_offset = 14;
219 const size_t out_digest_offset = 10;
220 u8 buf[COMMAND_BUFFER_SIZE];
221 u8 response[TPM_RESPONSE_HEADER_LENGTH + PCR_DIGEST_LENGTH];
222 size_t response_length = sizeof(response);
225 if (pack_byte_string(buf, sizeof(buf), "sds",
226 0, command, sizeof(command),
228 in_digest_offset, in_digest,
230 return TPM_LIB_ERROR;
231 err = tpm_sendrecv_command(dev, buf, response, &response_length);
235 if (unpack_byte_string(response, response_length, "s",
236 out_digest_offset, out_digest,
238 return TPM_LIB_ERROR;
243 u32 tpm1_pcr_read(struct udevice *dev, u32 index, void *data, size_t count)
245 const u8 command[14] = {
246 0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x15,
248 const size_t index_offset = 10;
249 const size_t out_digest_offset = 10;
250 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
251 size_t response_length = sizeof(response);
254 if (count < PCR_DIGEST_LENGTH)
255 return TPM_LIB_ERROR;
257 if (pack_byte_string(buf, sizeof(buf), "sd",
258 0, command, sizeof(command),
259 index_offset, index))
260 return TPM_LIB_ERROR;
261 err = tpm_sendrecv_command(dev, buf, response, &response_length);
264 if (unpack_byte_string(response, response_length, "s",
265 out_digest_offset, data, PCR_DIGEST_LENGTH))
266 return TPM_LIB_ERROR;
271 u32 tpm1_tsc_physical_presence(struct udevice *dev, u16 presence)
273 const u8 command[12] = {
274 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x0,
276 const size_t presence_offset = 10;
277 u8 buf[COMMAND_BUFFER_SIZE];
279 if (pack_byte_string(buf, sizeof(buf), "sw",
280 0, command, sizeof(command),
281 presence_offset, presence))
282 return TPM_LIB_ERROR;
284 return tpm_sendrecv_command(dev, buf, NULL, NULL);
287 u32 tpm1_finalise_physical_presence(struct udevice *dev)
289 const u8 command[12] = {
290 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x2, 0xa0,
293 return tpm_sendrecv_command(dev, command, NULL, NULL);
296 u32 tpm1_read_pubek(struct udevice *dev, void *data, size_t count)
298 const u8 command[30] = {
299 0x0, 0xc1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x7c,
301 const size_t response_size_offset = 2;
302 const size_t data_offset = 10;
303 const size_t header_and_checksum_size = TPM_RESPONSE_HEADER_LENGTH + 20;
304 u8 response[COMMAND_BUFFER_SIZE + TPM_PUBEK_SIZE];
305 size_t response_length = sizeof(response);
309 err = tpm_sendrecv_command(dev, command, response, &response_length);
312 if (unpack_byte_string(response, response_length, "d",
313 response_size_offset, &data_size))
314 return TPM_LIB_ERROR;
315 if (data_size < header_and_checksum_size)
316 return TPM_LIB_ERROR;
317 data_size -= header_and_checksum_size;
318 if (data_size > count)
319 return TPM_LIB_ERROR;
320 if (unpack_byte_string(response, response_length, "s",
321 data_offset, data, data_size))
322 return TPM_LIB_ERROR;
327 u32 tpm1_force_clear(struct udevice *dev)
329 const u8 command[10] = {
330 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x5d,
333 return tpm_sendrecv_command(dev, command, NULL, NULL);
336 u32 tpm1_physical_enable(struct udevice *dev)
338 const u8 command[10] = {
339 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x6f,
342 return tpm_sendrecv_command(dev, command, NULL, NULL);
345 u32 tpm1_physical_disable(struct udevice *dev)
347 const u8 command[10] = {
348 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x70,
351 return tpm_sendrecv_command(dev, command, NULL, NULL);
354 u32 tpm1_physical_set_deactivated(struct udevice *dev, u8 state)
356 const u8 command[11] = {
357 0x0, 0xc1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72,
359 const size_t state_offset = 10;
360 u8 buf[COMMAND_BUFFER_SIZE];
362 if (pack_byte_string(buf, sizeof(buf), "sb",
363 0, command, sizeof(command),
364 state_offset, state))
365 return TPM_LIB_ERROR;
367 return tpm_sendrecv_command(dev, buf, NULL, NULL);
370 u32 tpm1_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap,
371 void *cap, size_t count)
373 const u8 command[22] = {
374 0x0, 0xc1, /* TPM_TAG */
375 0x0, 0x0, 0x0, 0x16, /* parameter size */
376 0x0, 0x0, 0x0, 0x65, /* TPM_COMMAND_CODE */
377 0x0, 0x0, 0x0, 0x0, /* TPM_CAPABILITY_AREA */
378 0x0, 0x0, 0x0, 0x4, /* subcap size */
379 0x0, 0x0, 0x0, 0x0, /* subcap value */
381 const size_t cap_area_offset = 10;
382 const size_t sub_cap_offset = 18;
383 const size_t cap_offset = 14;
384 const size_t cap_size_offset = 10;
385 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
386 size_t response_length = sizeof(response);
390 if (pack_byte_string(buf, sizeof(buf), "sdd",
391 0, command, sizeof(command),
392 cap_area_offset, cap_area,
393 sub_cap_offset, sub_cap))
394 return TPM_LIB_ERROR;
395 err = tpm_sendrecv_command(dev, buf, response, &response_length);
398 if (unpack_byte_string(response, response_length, "d",
399 cap_size_offset, &cap_size))
400 return TPM_LIB_ERROR;
401 if (cap_size > response_length || cap_size > count)
402 return TPM_LIB_ERROR;
403 if (unpack_byte_string(response, response_length, "s",
404 cap_offset, cap, cap_size))
405 return TPM_LIB_ERROR;
410 u32 tpm1_get_permanent_flags(struct udevice *dev,
411 struct tpm_permanent_flags *pflags)
413 const u8 command[22] = {
414 0x0, 0xc1, /* TPM_TAG */
415 0x0, 0x0, 0x0, 0x16, /* parameter size */
416 0x0, 0x0, 0x0, 0x65, /* TPM_COMMAND_CODE */
417 0x0, 0x0, 0x0, 0x4, /* TPM_CAP_FLAG_PERM */
418 0x0, 0x0, 0x0, 0x4, /* subcap size */
419 0x0, 0x0, 0x1, 0x8, /* subcap value */
421 const size_t data_size_offset = TPM_HEADER_SIZE;
422 const size_t data_offset = TPM_HEADER_SIZE + sizeof(u32);
423 u8 response[COMMAND_BUFFER_SIZE];
424 size_t response_length = sizeof(response);
428 err = tpm_sendrecv_command(dev, command, response, &response_length);
431 if (unpack_byte_string(response, response_length, "d",
432 data_size_offset, &data_size)) {
433 log_err("Cannot unpack data size\n");
434 return TPM_LIB_ERROR;
436 if (data_size < sizeof(*pflags)) {
437 log_err("Data size too small\n");
438 return TPM_LIB_ERROR;
440 if (unpack_byte_string(response, response_length, "s",
441 data_offset, pflags, sizeof(*pflags))) {
442 log_err("Cannot unpack pflags\n");
443 return TPM_LIB_ERROR;
449 u32 tpm1_get_permissions(struct udevice *dev, u32 index, u32 *perm)
451 const u8 command[22] = {
452 0x0, 0xc1, /* TPM_TAG */
453 0x0, 0x0, 0x0, 0x16, /* parameter size */
454 0x0, 0x0, 0x0, 0x65, /* TPM_COMMAND_CODE */
458 const size_t index_offset = 18;
459 const size_t perm_offset = 60;
460 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
461 size_t response_length = sizeof(response);
464 if (pack_byte_string(buf, sizeof(buf), "d", 0, command, sizeof(command),
465 index_offset, index))
466 return TPM_LIB_ERROR;
467 err = tpm_sendrecv_command(dev, buf, response, &response_length);
470 if (unpack_byte_string(response, response_length, "d",
472 return TPM_LIB_ERROR;
477 #ifdef CONFIG_TPM_FLUSH_RESOURCES
478 u32 tpm1_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type)
480 const u8 command[18] = {
481 0x00, 0xc1, /* TPM_TAG */
482 0x00, 0x00, 0x00, 0x12, /* parameter size */
483 0x00, 0x00, 0x00, 0xba, /* TPM_COMMAND_CODE */
484 0x00, 0x00, 0x00, 0x00, /* key handle */
485 0x00, 0x00, 0x00, 0x00, /* resource type */
487 const size_t key_handle_offset = 10;
488 const size_t resource_type_offset = 14;
489 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
490 size_t response_length = sizeof(response);
493 if (pack_byte_string(buf, sizeof(buf), "sdd",
494 0, command, sizeof(command),
495 key_handle_offset, key_handle,
496 resource_type_offset, resource_type))
497 return TPM_LIB_ERROR;
499 err = tpm_sendrecv_command(dev, buf, response, &response_length);
504 #endif /* CONFIG_TPM_FLUSH_RESOURCES */
506 #ifdef CONFIG_TPM_AUTH_SESSIONS
509 * Fill an authentication block in a request.
510 * This func can create the first as well as the second auth block (for
511 * double authorized commands).
513 * @param request pointer to the request (w/ uninitialised auth data)
514 * @param request_len0 length of the request without auth data
515 * @param handles_len length of the handles area in request
516 * @param auth_session pointer to the (valid) auth session to be used
517 * @param request_auth pointer to the auth block of the request to be filled
518 * @param auth authentication data (HMAC key)
520 static u32 create_request_auth(const void *request, size_t request_len0,
522 struct session_data *auth_session,
523 void *request_auth, const void *auth)
525 u8 hmac_data[DIGEST_LENGTH * 3 + 1];
526 sha1_context hash_ctx;
527 const size_t command_code_offset = 6;
528 const size_t auth_nonce_odd_offset = 4;
529 const size_t auth_continue_offset = 24;
530 const size_t auth_auth_offset = 25;
532 if (!auth_session || !auth_session->valid)
533 return TPM_LIB_ERROR;
535 sha1_starts(&hash_ctx);
536 sha1_update(&hash_ctx, request + command_code_offset, 4);
537 if (request_len0 > TPM_REQUEST_HEADER_LENGTH + handles_len)
538 sha1_update(&hash_ctx,
539 request + TPM_REQUEST_HEADER_LENGTH + handles_len,
540 request_len0 - TPM_REQUEST_HEADER_LENGTH
542 sha1_finish(&hash_ctx, hmac_data);
544 sha1_starts(&hash_ctx);
545 sha1_update(&hash_ctx, auth_session->nonce_odd, DIGEST_LENGTH);
546 sha1_update(&hash_ctx, hmac_data, sizeof(hmac_data));
547 sha1_finish(&hash_ctx, auth_session->nonce_odd);
549 if (pack_byte_string(request_auth, TPM_REQUEST_AUTH_LENGTH, "dsb",
550 0, auth_session->handle,
551 auth_nonce_odd_offset, auth_session->nonce_odd,
553 auth_continue_offset, 1))
554 return TPM_LIB_ERROR;
555 if (pack_byte_string(hmac_data, sizeof(hmac_data), "ss",
557 auth_session->nonce_even,
560 request_auth + auth_nonce_odd_offset,
562 return TPM_LIB_ERROR;
563 sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
564 request_auth + auth_auth_offset);
570 * Verify an authentication block in a response.
571 * Since this func updates the nonce_even in the session data it has to be
572 * called when receiving a succesfull AUTH response.
573 * This func can verify the first as well as the second auth block (for
574 * double authorized commands).
576 * @param command_code command code of the request
577 * @param response pointer to the request (w/ uninitialised auth data)
578 * @param handles_len length of the handles area in response
579 * @param auth_session pointer to the (valid) auth session to be used
580 * @param response_auth pointer to the auth block of the response to be verified
581 * @param auth authentication data (HMAC key)
583 static u32 verify_response_auth(u32 command_code, const void *response,
584 size_t response_len0, size_t handles_len,
585 struct session_data *auth_session,
586 const void *response_auth, const void *auth)
588 u8 hmac_data[DIGEST_LENGTH * 3 + 1];
589 u8 computed_auth[DIGEST_LENGTH];
590 sha1_context hash_ctx;
591 const size_t return_code_offset = 6;
592 const size_t auth_continue_offset = 20;
593 const size_t auth_auth_offset = 21;
596 if (!auth_session || !auth_session->valid)
598 if (pack_byte_string(hmac_data, sizeof(hmac_data), "d",
600 return TPM_LIB_ERROR;
601 if (response_len0 < TPM_RESPONSE_HEADER_LENGTH)
602 return TPM_LIB_ERROR;
604 sha1_starts(&hash_ctx);
605 sha1_update(&hash_ctx, response + return_code_offset, 4);
606 sha1_update(&hash_ctx, hmac_data, 4);
607 if (response_len0 > TPM_RESPONSE_HEADER_LENGTH + handles_len)
608 sha1_update(&hash_ctx,
609 response + TPM_RESPONSE_HEADER_LENGTH + handles_len,
610 response_len0 - TPM_RESPONSE_HEADER_LENGTH
612 sha1_finish(&hash_ctx, hmac_data);
614 memcpy(auth_session->nonce_even, response_auth, DIGEST_LENGTH);
615 auth_continue = ((u8 *)response_auth)[auth_continue_offset];
616 if (pack_byte_string(hmac_data, sizeof(hmac_data), "ssb",
621 auth_session->nonce_odd,
625 return TPM_LIB_ERROR;
627 sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
630 if (memcmp(computed_auth, response_auth + auth_auth_offset,
637 u32 tpm1_terminate_auth_session(struct udevice *dev, u32 auth_handle)
639 const u8 command[18] = {
640 0x00, 0xc1, /* TPM_TAG */
641 0x00, 0x00, 0x00, 0x00, /* parameter size */
642 0x00, 0x00, 0x00, 0xba, /* TPM_COMMAND_CODE */
643 0x00, 0x00, 0x00, 0x00, /* TPM_HANDLE */
644 0x00, 0x00, 0x00, 0x02, /* TPM_RESOURCE_TYPE */
646 const size_t req_handle_offset = TPM_REQUEST_HEADER_LENGTH;
647 u8 request[COMMAND_BUFFER_SIZE];
649 if (pack_byte_string(request, sizeof(request), "sd",
650 0, command, sizeof(command),
651 req_handle_offset, auth_handle))
652 return TPM_LIB_ERROR;
653 if (oiap_session.valid && oiap_session.handle == auth_handle)
654 oiap_session.valid = 0;
656 return tpm_sendrecv_command(dev, request, NULL, NULL);
659 u32 tpm1_end_oiap(struct udevice *dev)
661 u32 err = TPM_SUCCESS;
663 if (oiap_session.valid)
664 err = tpm1_terminate_auth_session(dev, oiap_session.handle);
668 u32 tpm1_oiap(struct udevice *dev, u32 *auth_handle)
670 const u8 command[10] = {
671 0x00, 0xc1, /* TPM_TAG */
672 0x00, 0x00, 0x00, 0x0a, /* parameter size */
673 0x00, 0x00, 0x00, 0x0a, /* TPM_COMMAND_CODE */
675 const size_t res_auth_handle_offset = TPM_RESPONSE_HEADER_LENGTH;
676 const size_t res_nonce_even_offset = TPM_RESPONSE_HEADER_LENGTH + 4;
677 u8 response[COMMAND_BUFFER_SIZE];
678 size_t response_length = sizeof(response);
681 if (oiap_session.valid)
682 tpm1_terminate_auth_session(dev, oiap_session.handle);
684 err = tpm_sendrecv_command(dev, command, response, &response_length);
687 if (unpack_byte_string(response, response_length, "ds",
688 res_auth_handle_offset, &oiap_session.handle,
689 res_nonce_even_offset, &oiap_session.nonce_even,
691 return TPM_LIB_ERROR;
692 oiap_session.valid = 1;
694 *auth_handle = oiap_session.handle;
698 u32 tpm1_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key,
699 size_t key_length, const void *parent_key_usage_auth,
702 const u8 command[14] = {
703 0x00, 0xc2, /* TPM_TAG */
704 0x00, 0x00, 0x00, 0x00, /* parameter size */
705 0x00, 0x00, 0x00, 0x41, /* TPM_COMMAND_CODE */
706 0x00, 0x00, 0x00, 0x00, /* parent handle */
708 const size_t req_size_offset = 2;
709 const size_t req_parent_handle_offset = TPM_REQUEST_HEADER_LENGTH;
710 const size_t req_key_offset = TPM_REQUEST_HEADER_LENGTH + 4;
711 const size_t res_handle_offset = TPM_RESPONSE_HEADER_LENGTH;
712 u8 request[sizeof(command) + TPM_KEY12_MAX_LENGTH +
713 TPM_REQUEST_AUTH_LENGTH];
714 u8 response[COMMAND_BUFFER_SIZE];
715 size_t response_length = sizeof(response);
718 if (!oiap_session.valid) {
719 err = tpm1_oiap(dev, NULL);
723 if (pack_byte_string(request, sizeof(request), "sdds",
724 0, command, sizeof(command),
726 sizeof(command) + key_length
727 + TPM_REQUEST_AUTH_LENGTH,
728 req_parent_handle_offset, parent_handle,
729 req_key_offset, key, key_length
731 return TPM_LIB_ERROR;
733 err = create_request_auth(request, sizeof(command) + key_length, 4,
735 request + sizeof(command) + key_length,
736 parent_key_usage_auth);
739 err = tpm_sendrecv_command(dev, request, response, &response_length);
741 if (err == TPM_AUTHFAIL)
742 oiap_session.valid = 0;
746 err = verify_response_auth(0x00000041, response,
747 response_length - TPM_RESPONSE_AUTH_LENGTH,
749 response + response_length -
750 TPM_RESPONSE_AUTH_LENGTH,
751 parent_key_usage_auth);
756 if (unpack_byte_string(response, response_length, "d",
757 res_handle_offset, key_handle))
758 return TPM_LIB_ERROR;
764 u32 tpm1_get_pub_key_oiap(struct udevice *dev, u32 key_handle,
765 const void *usage_auth, void *pubkey,
768 const u8 command[14] = {
769 0x00, 0xc2, /* TPM_TAG */
770 0x00, 0x00, 0x00, 0x00, /* parameter size */
771 0x00, 0x00, 0x00, 0x21, /* TPM_COMMAND_CODE */
772 0x00, 0x00, 0x00, 0x00, /* key handle */
774 const size_t req_size_offset = 2;
775 const size_t req_key_handle_offset = TPM_REQUEST_HEADER_LENGTH;
776 const size_t res_pubkey_offset = TPM_RESPONSE_HEADER_LENGTH;
777 u8 request[sizeof(command) + TPM_REQUEST_AUTH_LENGTH];
778 u8 response[TPM_RESPONSE_HEADER_LENGTH + TPM_PUBKEY_MAX_LENGTH +
779 TPM_RESPONSE_AUTH_LENGTH];
780 size_t response_length = sizeof(response);
783 if (!oiap_session.valid) {
784 err = tpm1_oiap(dev, NULL);
788 if (pack_byte_string(request, sizeof(request), "sdd",
789 0, command, sizeof(command),
791 (u32)(sizeof(command)
792 + TPM_REQUEST_AUTH_LENGTH),
793 req_key_handle_offset, key_handle
795 return TPM_LIB_ERROR;
796 err = create_request_auth(request, sizeof(command), 4, &oiap_session,
797 request + sizeof(command), usage_auth);
800 err = tpm_sendrecv_command(dev, request, response, &response_length);
802 if (err == TPM_AUTHFAIL)
803 oiap_session.valid = 0;
806 err = verify_response_auth(0x00000021, response,
807 response_length - TPM_RESPONSE_AUTH_LENGTH,
809 response + response_length -
810 TPM_RESPONSE_AUTH_LENGTH,
816 if ((response_length - TPM_RESPONSE_HEADER_LENGTH
817 - TPM_RESPONSE_AUTH_LENGTH) > *pubkey_len)
818 return TPM_LIB_ERROR;
819 *pubkey_len = response_length - TPM_RESPONSE_HEADER_LENGTH
820 - TPM_RESPONSE_AUTH_LENGTH;
821 memcpy(pubkey, response + res_pubkey_offset,
822 response_length - TPM_RESPONSE_HEADER_LENGTH
823 - TPM_RESPONSE_AUTH_LENGTH);
829 #ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
830 u32 tpm1_find_key_sha1(struct udevice *dev, const u8 auth[20],
831 const u8 pubkey_digest[20], u32 *handle)
842 /* fetch list of already loaded keys in the TPM */
843 err = tpm1_get_capability(dev, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
847 key_count = get_unaligned_be16(buf);
849 for (i = 0; i < key_count; ++i, ptr += 4)
850 key_handles[i] = get_unaligned_be32(ptr);
852 /* now search a(/ the) key which we can access with the given auth */
853 for (i = 0; i < key_count; ++i) {
854 buf_len = sizeof(buf);
855 err = tpm1_get_pub_key_oiap(dev, key_handles[i], auth, buf, &buf_len);
856 if (err && err != TPM_AUTHFAIL)
860 sha1_csum(buf, buf_len, digest);
861 if (!memcmp(digest, pubkey_digest, 20)) {
862 *handle = key_handles[i];
868 #endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
870 #endif /* CONFIG_TPM_AUTH_SESSIONS */
872 u32 tpm1_get_random(struct udevice *dev, void *data, u32 count)
874 const u8 command[14] = {
875 0x0, 0xc1, /* TPM_TAG */
876 0x0, 0x0, 0x0, 0xe, /* parameter size */
877 0x0, 0x0, 0x0, 0x46, /* TPM_COMMAND_CODE */
879 const size_t length_offset = 10;
880 const size_t data_size_offset = 10;
881 const size_t data_offset = 14;
882 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
883 size_t response_length = sizeof(response);
888 u32 this_bytes = min((size_t)count,
889 sizeof(response) - data_offset);
892 if (pack_byte_string(buf, sizeof(buf), "sd",
893 0, command, sizeof(command),
894 length_offset, this_bytes))
895 return TPM_LIB_ERROR;
896 err = tpm_sendrecv_command(dev, buf, response,
900 if (unpack_byte_string(response, response_length, "d",
901 data_size_offset, &data_size))
902 return TPM_LIB_ERROR;
903 if (data_size > count)
904 return TPM_LIB_ERROR;
905 if (unpack_byte_string(response, response_length, "s",
906 data_offset, out, data_size))
907 return TPM_LIB_ERROR;