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_auto_start(struct udevice *dev)
76 rc = tpm1_startup(dev, TPM_ST_CLEAR);
77 /* continue on if the TPM is already inited */
78 if (rc && rc != TPM_INVALID_POSTINIT)
81 rc = tpm1_self_test_full(dev);
86 u32 tpm1_clear_and_reenable(struct udevice *dev)
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");
97 ret = tpm1_physical_enable(dev);
98 if (ret != TPM_SUCCESS) {
99 log_err("TPM: Can't set enabled state\n");
103 ret = tpm1_physical_set_deactivated(dev, 0);
104 if (ret != TPM_SUCCESS) {
105 log_err("TPM: Can't set deactivated state\n");
112 u32 tpm1_nv_define_space(struct udevice *dev, u32 index, u32 perm, u32 size)
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 */
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 */
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 */
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];
145 if (pack_byte_string(buf, sizeof(buf), "sddd",
146 0, command, sizeof(command),
150 return TPM_LIB_ERROR;
152 return tpm_sendrecv_command(dev, buf, NULL, NULL);
155 u32 tpm1_nv_set_locked(struct udevice *dev)
157 return tpm1_nv_define_space(dev, TPM_NV_INDEX_LOCK, 0, 0);
160 u32 tpm1_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count)
162 const u8 command[22] = {
163 0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0xcf,
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);
174 if (pack_byte_string(buf, sizeof(buf), "sdd",
175 0, command, sizeof(command),
177 length_offset, count))
178 return TPM_LIB_ERROR;
179 err = tpm_sendrecv_command(dev, buf, response, &response_length);
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;
194 u32 tpm1_nv_write_value(struct udevice *dev, u32 index, const void *data,
197 const u8 command[256] = {
198 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd,
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);
211 if (pack_byte_string(buf, sizeof(buf), "sddds",
212 0, command, sizeof(command),
213 command_size_offset, total_length,
215 length_offset, length,
216 data_offset, data, length))
217 return TPM_LIB_ERROR;
218 err = tpm_sendrecv_command(dev, buf, response, &response_length);
225 u32 tpm1_extend(struct udevice *dev, u32 index, const void *in_digest,
228 const u8 command[34] = {
229 0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x14,
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);
239 if (pack_byte_string(buf, sizeof(buf), "sds",
240 0, command, sizeof(command),
242 in_digest_offset, in_digest,
244 return TPM_LIB_ERROR;
245 err = tpm_sendrecv_command(dev, buf, response, &response_length);
249 if (unpack_byte_string(response, response_length, "s",
250 out_digest_offset, out_digest,
252 return TPM_LIB_ERROR;
257 u32 tpm1_pcr_read(struct udevice *dev, u32 index, void *data, size_t count)
259 const u8 command[14] = {
260 0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x15,
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);
268 if (count < PCR_DIGEST_LENGTH)
269 return TPM_LIB_ERROR;
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);
278 if (unpack_byte_string(response, response_length, "s",
279 out_digest_offset, data, PCR_DIGEST_LENGTH))
280 return TPM_LIB_ERROR;
285 u32 tpm1_tsc_physical_presence(struct udevice *dev, u16 presence)
287 const u8 command[12] = {
288 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x0,
290 const size_t presence_offset = 10;
291 u8 buf[COMMAND_BUFFER_SIZE];
293 if (pack_byte_string(buf, sizeof(buf), "sw",
294 0, command, sizeof(command),
295 presence_offset, presence))
296 return TPM_LIB_ERROR;
298 return tpm_sendrecv_command(dev, buf, NULL, NULL);
301 u32 tpm1_finalise_physical_presence(struct udevice *dev)
303 const u8 command[12] = {
304 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x2, 0xa0,
307 return tpm_sendrecv_command(dev, command, NULL, NULL);
310 u32 tpm1_read_pubek(struct udevice *dev, void *data, size_t count)
312 const u8 command[30] = {
313 0x0, 0xc1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x7c,
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);
323 err = tpm_sendrecv_command(dev, command, response, &response_length);
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;
341 u32 tpm1_force_clear(struct udevice *dev)
343 const u8 command[10] = {
344 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x5d,
347 return tpm_sendrecv_command(dev, command, NULL, NULL);
350 u32 tpm1_physical_enable(struct udevice *dev)
352 const u8 command[10] = {
353 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x6f,
356 return tpm_sendrecv_command(dev, command, NULL, NULL);
359 u32 tpm1_physical_disable(struct udevice *dev)
361 const u8 command[10] = {
362 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x70,
365 return tpm_sendrecv_command(dev, command, NULL, NULL);
368 u32 tpm1_physical_set_deactivated(struct udevice *dev, u8 state)
370 const u8 command[11] = {
371 0x0, 0xc1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72,
373 const size_t state_offset = 10;
374 u8 buf[COMMAND_BUFFER_SIZE];
376 if (pack_byte_string(buf, sizeof(buf), "sb",
377 0, command, sizeof(command),
378 state_offset, state))
379 return TPM_LIB_ERROR;
381 return tpm_sendrecv_command(dev, buf, NULL, NULL);
384 u32 tpm1_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap,
385 void *cap, size_t count)
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 */
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);
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);
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;
424 u32 tpm1_get_permanent_flags(struct udevice *dev,
425 struct tpm_permanent_flags *pflags)
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 */
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);
442 err = tpm_sendrecv_command(dev, command, response, &response_length);
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;
450 if (data_size < sizeof(*pflags)) {
451 log_err("Data size too small\n");
452 return TPM_LIB_ERROR;
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;
463 u32 tpm1_get_permissions(struct udevice *dev, u32 index, u32 *perm)
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 */
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);
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);
485 if (unpack_byte_string(response, response_length, "d",
487 return TPM_LIB_ERROR;
492 #ifdef CONFIG_TPM_FLUSH_RESOURCES
493 u32 tpm1_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type)
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 */
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);
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;
514 err = tpm_sendrecv_command(dev, buf, response, &response_length);
519 #endif /* CONFIG_TPM_FLUSH_RESOURCES */
521 #ifdef CONFIG_TPM_AUTH_SESSIONS
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).
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)
535 static u32 create_request_auth(const void *request, size_t request_len0,
537 struct session_data *auth_session,
538 void *request_auth, const void *auth)
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;
547 if (!auth_session || !auth_session->valid)
548 return TPM_LIB_ERROR;
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
557 sha1_finish(&hash_ctx, hmac_data);
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);
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,
568 auth_continue_offset, 1))
569 return TPM_LIB_ERROR;
570 if (pack_byte_string(hmac_data, sizeof(hmac_data), "ss",
572 auth_session->nonce_even,
575 request_auth + auth_nonce_odd_offset,
577 return TPM_LIB_ERROR;
578 sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
579 request_auth + auth_auth_offset);
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).
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)
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)
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;
611 if (!auth_session || !auth_session->valid)
613 if (pack_byte_string(hmac_data, sizeof(hmac_data), "d",
615 return TPM_LIB_ERROR;
616 if (response_len0 < TPM_RESPONSE_HEADER_LENGTH)
617 return TPM_LIB_ERROR;
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
627 sha1_finish(&hash_ctx, hmac_data);
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",
636 auth_session->nonce_odd,
640 return TPM_LIB_ERROR;
642 sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
645 if (memcmp(computed_auth, response_auth + auth_auth_offset,
652 u32 tpm1_terminate_auth_session(struct udevice *dev, u32 auth_handle)
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 */
661 const size_t req_handle_offset = TPM_REQUEST_HEADER_LENGTH;
662 u8 request[COMMAND_BUFFER_SIZE];
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;
671 return tpm_sendrecv_command(dev, request, NULL, NULL);
674 u32 tpm1_end_oiap(struct udevice *dev)
676 u32 err = TPM_SUCCESS;
678 if (oiap_session.valid)
679 err = tpm1_terminate_auth_session(dev, oiap_session.handle);
683 u32 tpm1_oiap(struct udevice *dev, u32 *auth_handle)
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 */
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);
696 if (oiap_session.valid)
697 tpm1_terminate_auth_session(dev, oiap_session.handle);
699 err = tpm_sendrecv_command(dev, command, response, &response_length);
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,
706 return TPM_LIB_ERROR;
707 oiap_session.valid = 1;
709 *auth_handle = oiap_session.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,
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 */
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);
733 if (!oiap_session.valid) {
734 err = tpm1_oiap(dev, NULL);
738 if (pack_byte_string(request, sizeof(request), "sdds",
739 0, command, sizeof(command),
741 sizeof(command) + key_length
742 + TPM_REQUEST_AUTH_LENGTH,
743 req_parent_handle_offset, parent_handle,
744 req_key_offset, key, key_length
746 return TPM_LIB_ERROR;
748 err = create_request_auth(request, sizeof(command) + key_length, 4,
750 request + sizeof(command) + key_length,
751 parent_key_usage_auth);
754 err = tpm_sendrecv_command(dev, request, response, &response_length);
756 if (err == TPM_AUTHFAIL)
757 oiap_session.valid = 0;
761 err = verify_response_auth(0x00000041, response,
762 response_length - TPM_RESPONSE_AUTH_LENGTH,
764 response + response_length -
765 TPM_RESPONSE_AUTH_LENGTH,
766 parent_key_usage_auth);
771 if (unpack_byte_string(response, response_length, "d",
772 res_handle_offset, key_handle))
773 return TPM_LIB_ERROR;
779 u32 tpm1_get_pub_key_oiap(struct udevice *dev, u32 key_handle,
780 const void *usage_auth, void *pubkey,
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 */
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);
798 if (!oiap_session.valid) {
799 err = tpm1_oiap(dev, NULL);
803 if (pack_byte_string(request, sizeof(request), "sdd",
804 0, command, sizeof(command),
806 (u32)(sizeof(command)
807 + TPM_REQUEST_AUTH_LENGTH),
808 req_key_handle_offset, key_handle
810 return TPM_LIB_ERROR;
811 err = create_request_auth(request, sizeof(command), 4, &oiap_session,
812 request + sizeof(command), usage_auth);
815 err = tpm_sendrecv_command(dev, request, response, &response_length);
817 if (err == TPM_AUTHFAIL)
818 oiap_session.valid = 0;
821 err = verify_response_auth(0x00000021, response,
822 response_length - TPM_RESPONSE_AUTH_LENGTH,
824 response + response_length -
825 TPM_RESPONSE_AUTH_LENGTH,
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);
844 #ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
845 u32 tpm1_find_key_sha1(struct udevice *dev, const u8 auth[20],
846 const u8 pubkey_digest[20], u32 *handle)
857 /* fetch list of already loaded keys in the TPM */
858 err = tpm1_get_capability(dev, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
862 key_count = get_unaligned_be16(buf);
864 for (i = 0; i < key_count; ++i, ptr += 4)
865 key_handles[i] = get_unaligned_be32(ptr);
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)
875 sha1_csum(buf, buf_len, digest);
876 if (!memcmp(digest, pubkey_digest, 20)) {
877 *handle = key_handles[i];
883 #endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
885 #endif /* CONFIG_TPM_AUTH_SESSIONS */
887 u32 tpm1_get_random(struct udevice *dev, void *data, u32 count)
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 */
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);
903 u32 this_bytes = min((size_t)count,
904 sizeof(response) - data_offset);
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,
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;