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 = 74;
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), "sd",
465 0, command, sizeof(command),
466 index_offset, index))
467 return TPM_LIB_ERROR;
468 err = tpm_sendrecv_command(dev, buf, response, &response_length);
471 if (unpack_byte_string(response, response_length, "d",
473 return TPM_LIB_ERROR;
478 #ifdef CONFIG_TPM_FLUSH_RESOURCES
479 u32 tpm1_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type)
481 const u8 command[18] = {
482 0x00, 0xc1, /* TPM_TAG */
483 0x00, 0x00, 0x00, 0x12, /* parameter size */
484 0x00, 0x00, 0x00, 0xba, /* TPM_COMMAND_CODE */
485 0x00, 0x00, 0x00, 0x00, /* key handle */
486 0x00, 0x00, 0x00, 0x00, /* resource type */
488 const size_t key_handle_offset = 10;
489 const size_t resource_type_offset = 14;
490 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
491 size_t response_length = sizeof(response);
494 if (pack_byte_string(buf, sizeof(buf), "sdd",
495 0, command, sizeof(command),
496 key_handle_offset, key_handle,
497 resource_type_offset, resource_type))
498 return TPM_LIB_ERROR;
500 err = tpm_sendrecv_command(dev, buf, response, &response_length);
505 #endif /* CONFIG_TPM_FLUSH_RESOURCES */
507 #ifdef CONFIG_TPM_AUTH_SESSIONS
510 * Fill an authentication block in a request.
511 * This func can create the first as well as the second auth block (for
512 * double authorized commands).
514 * @param request pointer to the request (w/ uninitialised auth data)
515 * @param request_len0 length of the request without auth data
516 * @param handles_len length of the handles area in request
517 * @param auth_session pointer to the (valid) auth session to be used
518 * @param request_auth pointer to the auth block of the request to be filled
519 * @param auth authentication data (HMAC key)
521 static u32 create_request_auth(const void *request, size_t request_len0,
523 struct session_data *auth_session,
524 void *request_auth, const void *auth)
526 u8 hmac_data[DIGEST_LENGTH * 3 + 1];
527 sha1_context hash_ctx;
528 const size_t command_code_offset = 6;
529 const size_t auth_nonce_odd_offset = 4;
530 const size_t auth_continue_offset = 24;
531 const size_t auth_auth_offset = 25;
533 if (!auth_session || !auth_session->valid)
534 return TPM_LIB_ERROR;
536 sha1_starts(&hash_ctx);
537 sha1_update(&hash_ctx, request + command_code_offset, 4);
538 if (request_len0 > TPM_REQUEST_HEADER_LENGTH + handles_len)
539 sha1_update(&hash_ctx,
540 request + TPM_REQUEST_HEADER_LENGTH + handles_len,
541 request_len0 - TPM_REQUEST_HEADER_LENGTH
543 sha1_finish(&hash_ctx, hmac_data);
545 sha1_starts(&hash_ctx);
546 sha1_update(&hash_ctx, auth_session->nonce_odd, DIGEST_LENGTH);
547 sha1_update(&hash_ctx, hmac_data, sizeof(hmac_data));
548 sha1_finish(&hash_ctx, auth_session->nonce_odd);
550 if (pack_byte_string(request_auth, TPM_REQUEST_AUTH_LENGTH, "dsb",
551 0, auth_session->handle,
552 auth_nonce_odd_offset, auth_session->nonce_odd,
554 auth_continue_offset, 1))
555 return TPM_LIB_ERROR;
556 if (pack_byte_string(hmac_data, sizeof(hmac_data), "ss",
558 auth_session->nonce_even,
561 request_auth + auth_nonce_odd_offset,
563 return TPM_LIB_ERROR;
564 sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
565 request_auth + auth_auth_offset);
571 * Verify an authentication block in a response.
572 * Since this func updates the nonce_even in the session data it has to be
573 * called when receiving a succesfull AUTH response.
574 * This func can verify the first as well as the second auth block (for
575 * double authorized commands).
577 * @param command_code command code of the request
578 * @param response pointer to the request (w/ uninitialised auth data)
579 * @param handles_len length of the handles area in response
580 * @param auth_session pointer to the (valid) auth session to be used
581 * @param response_auth pointer to the auth block of the response to be verified
582 * @param auth authentication data (HMAC key)
584 static u32 verify_response_auth(u32 command_code, const void *response,
585 size_t response_len0, size_t handles_len,
586 struct session_data *auth_session,
587 const void *response_auth, const void *auth)
589 u8 hmac_data[DIGEST_LENGTH * 3 + 1];
590 u8 computed_auth[DIGEST_LENGTH];
591 sha1_context hash_ctx;
592 const size_t return_code_offset = 6;
593 const size_t auth_continue_offset = 20;
594 const size_t auth_auth_offset = 21;
597 if (!auth_session || !auth_session->valid)
599 if (pack_byte_string(hmac_data, sizeof(hmac_data), "d",
601 return TPM_LIB_ERROR;
602 if (response_len0 < TPM_RESPONSE_HEADER_LENGTH)
603 return TPM_LIB_ERROR;
605 sha1_starts(&hash_ctx);
606 sha1_update(&hash_ctx, response + return_code_offset, 4);
607 sha1_update(&hash_ctx, hmac_data, 4);
608 if (response_len0 > TPM_RESPONSE_HEADER_LENGTH + handles_len)
609 sha1_update(&hash_ctx,
610 response + TPM_RESPONSE_HEADER_LENGTH + handles_len,
611 response_len0 - TPM_RESPONSE_HEADER_LENGTH
613 sha1_finish(&hash_ctx, hmac_data);
615 memcpy(auth_session->nonce_even, response_auth, DIGEST_LENGTH);
616 auth_continue = ((u8 *)response_auth)[auth_continue_offset];
617 if (pack_byte_string(hmac_data, sizeof(hmac_data), "ssb",
622 auth_session->nonce_odd,
626 return TPM_LIB_ERROR;
628 sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
631 if (memcmp(computed_auth, response_auth + auth_auth_offset,
638 u32 tpm1_terminate_auth_session(struct udevice *dev, u32 auth_handle)
640 const u8 command[18] = {
641 0x00, 0xc1, /* TPM_TAG */
642 0x00, 0x00, 0x00, 0x00, /* parameter size */
643 0x00, 0x00, 0x00, 0xba, /* TPM_COMMAND_CODE */
644 0x00, 0x00, 0x00, 0x00, /* TPM_HANDLE */
645 0x00, 0x00, 0x00, 0x02, /* TPM_RESOURCE_TYPE */
647 const size_t req_handle_offset = TPM_REQUEST_HEADER_LENGTH;
648 u8 request[COMMAND_BUFFER_SIZE];
650 if (pack_byte_string(request, sizeof(request), "sd",
651 0, command, sizeof(command),
652 req_handle_offset, auth_handle))
653 return TPM_LIB_ERROR;
654 if (oiap_session.valid && oiap_session.handle == auth_handle)
655 oiap_session.valid = 0;
657 return tpm_sendrecv_command(dev, request, NULL, NULL);
660 u32 tpm1_end_oiap(struct udevice *dev)
662 u32 err = TPM_SUCCESS;
664 if (oiap_session.valid)
665 err = tpm1_terminate_auth_session(dev, oiap_session.handle);
669 u32 tpm1_oiap(struct udevice *dev, u32 *auth_handle)
671 const u8 command[10] = {
672 0x00, 0xc1, /* TPM_TAG */
673 0x00, 0x00, 0x00, 0x0a, /* parameter size */
674 0x00, 0x00, 0x00, 0x0a, /* TPM_COMMAND_CODE */
676 const size_t res_auth_handle_offset = TPM_RESPONSE_HEADER_LENGTH;
677 const size_t res_nonce_even_offset = TPM_RESPONSE_HEADER_LENGTH + 4;
678 u8 response[COMMAND_BUFFER_SIZE];
679 size_t response_length = sizeof(response);
682 if (oiap_session.valid)
683 tpm1_terminate_auth_session(dev, oiap_session.handle);
685 err = tpm_sendrecv_command(dev, command, response, &response_length);
688 if (unpack_byte_string(response, response_length, "ds",
689 res_auth_handle_offset, &oiap_session.handle,
690 res_nonce_even_offset, &oiap_session.nonce_even,
692 return TPM_LIB_ERROR;
693 oiap_session.valid = 1;
695 *auth_handle = oiap_session.handle;
699 u32 tpm1_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key,
700 size_t key_length, const void *parent_key_usage_auth,
703 const u8 command[14] = {
704 0x00, 0xc2, /* TPM_TAG */
705 0x00, 0x00, 0x00, 0x00, /* parameter size */
706 0x00, 0x00, 0x00, 0x41, /* TPM_COMMAND_CODE */
707 0x00, 0x00, 0x00, 0x00, /* parent handle */
709 const size_t req_size_offset = 2;
710 const size_t req_parent_handle_offset = TPM_REQUEST_HEADER_LENGTH;
711 const size_t req_key_offset = TPM_REQUEST_HEADER_LENGTH + 4;
712 const size_t res_handle_offset = TPM_RESPONSE_HEADER_LENGTH;
713 u8 request[sizeof(command) + TPM_KEY12_MAX_LENGTH +
714 TPM_REQUEST_AUTH_LENGTH];
715 u8 response[COMMAND_BUFFER_SIZE];
716 size_t response_length = sizeof(response);
719 if (!oiap_session.valid) {
720 err = tpm1_oiap(dev, NULL);
724 if (pack_byte_string(request, sizeof(request), "sdds",
725 0, command, sizeof(command),
727 sizeof(command) + key_length
728 + TPM_REQUEST_AUTH_LENGTH,
729 req_parent_handle_offset, parent_handle,
730 req_key_offset, key, key_length
732 return TPM_LIB_ERROR;
734 err = create_request_auth(request, sizeof(command) + key_length, 4,
736 request + sizeof(command) + key_length,
737 parent_key_usage_auth);
740 err = tpm_sendrecv_command(dev, request, response, &response_length);
742 if (err == TPM_AUTHFAIL)
743 oiap_session.valid = 0;
747 err = verify_response_auth(0x00000041, response,
748 response_length - TPM_RESPONSE_AUTH_LENGTH,
750 response + response_length -
751 TPM_RESPONSE_AUTH_LENGTH,
752 parent_key_usage_auth);
757 if (unpack_byte_string(response, response_length, "d",
758 res_handle_offset, key_handle))
759 return TPM_LIB_ERROR;
765 u32 tpm1_get_pub_key_oiap(struct udevice *dev, u32 key_handle,
766 const void *usage_auth, void *pubkey,
769 const u8 command[14] = {
770 0x00, 0xc2, /* TPM_TAG */
771 0x00, 0x00, 0x00, 0x00, /* parameter size */
772 0x00, 0x00, 0x00, 0x21, /* TPM_COMMAND_CODE */
773 0x00, 0x00, 0x00, 0x00, /* key handle */
775 const size_t req_size_offset = 2;
776 const size_t req_key_handle_offset = TPM_REQUEST_HEADER_LENGTH;
777 const size_t res_pubkey_offset = TPM_RESPONSE_HEADER_LENGTH;
778 u8 request[sizeof(command) + TPM_REQUEST_AUTH_LENGTH];
779 u8 response[TPM_RESPONSE_HEADER_LENGTH + TPM_PUBKEY_MAX_LENGTH +
780 TPM_RESPONSE_AUTH_LENGTH];
781 size_t response_length = sizeof(response);
784 if (!oiap_session.valid) {
785 err = tpm1_oiap(dev, NULL);
789 if (pack_byte_string(request, sizeof(request), "sdd",
790 0, command, sizeof(command),
792 (u32)(sizeof(command)
793 + TPM_REQUEST_AUTH_LENGTH),
794 req_key_handle_offset, key_handle
796 return TPM_LIB_ERROR;
797 err = create_request_auth(request, sizeof(command), 4, &oiap_session,
798 request + sizeof(command), usage_auth);
801 err = tpm_sendrecv_command(dev, request, response, &response_length);
803 if (err == TPM_AUTHFAIL)
804 oiap_session.valid = 0;
807 err = verify_response_auth(0x00000021, response,
808 response_length - TPM_RESPONSE_AUTH_LENGTH,
810 response + response_length -
811 TPM_RESPONSE_AUTH_LENGTH,
817 if ((response_length - TPM_RESPONSE_HEADER_LENGTH
818 - TPM_RESPONSE_AUTH_LENGTH) > *pubkey_len)
819 return TPM_LIB_ERROR;
820 *pubkey_len = response_length - TPM_RESPONSE_HEADER_LENGTH
821 - TPM_RESPONSE_AUTH_LENGTH;
822 memcpy(pubkey, response + res_pubkey_offset,
823 response_length - TPM_RESPONSE_HEADER_LENGTH
824 - TPM_RESPONSE_AUTH_LENGTH);
830 #ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
831 u32 tpm1_find_key_sha1(struct udevice *dev, const u8 auth[20],
832 const u8 pubkey_digest[20], u32 *handle)
843 /* fetch list of already loaded keys in the TPM */
844 err = tpm1_get_capability(dev, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
848 key_count = get_unaligned_be16(buf);
850 for (i = 0; i < key_count; ++i, ptr += 4)
851 key_handles[i] = get_unaligned_be32(ptr);
853 /* now search a(/ the) key which we can access with the given auth */
854 for (i = 0; i < key_count; ++i) {
855 buf_len = sizeof(buf);
856 err = tpm1_get_pub_key_oiap(dev, key_handles[i], auth, buf, &buf_len);
857 if (err && err != TPM_AUTHFAIL)
861 sha1_csum(buf, buf_len, digest);
862 if (!memcmp(digest, pubkey_digest, 20)) {
863 *handle = key_handles[i];
869 #endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
871 #endif /* CONFIG_TPM_AUTH_SESSIONS */
873 u32 tpm1_get_random(struct udevice *dev, void *data, u32 count)
875 const u8 command[14] = {
876 0x0, 0xc1, /* TPM_TAG */
877 0x0, 0x0, 0x0, 0xe, /* parameter size */
878 0x0, 0x0, 0x0, 0x46, /* TPM_COMMAND_CODE */
880 const size_t length_offset = 10;
881 const size_t data_size_offset = 10;
882 const size_t data_offset = 14;
883 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
884 size_t response_length = sizeof(response);
889 u32 this_bytes = min((size_t)count,
890 sizeof(response) - data_offset);
893 if (pack_byte_string(buf, sizeof(buf), "sd",
894 0, command, sizeof(command),
895 length_offset, this_bytes))
896 return TPM_LIB_ERROR;
897 err = tpm_sendrecv_command(dev, buf, response,
901 if (unpack_byte_string(response, response_length, "d",
902 data_size_offset, &data_size))
903 return TPM_LIB_ERROR;
904 if (data_size > count)
905 return TPM_LIB_ERROR;
906 if (unpack_byte_string(response, response_length, "s",
907 data_offset, out, data_size))
908 return TPM_LIB_ERROR;