1
2
3
4
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
23
24struct session_data {
25 int valid;
26 u32 handle;
27 u8 nonce_even[DIGEST_LENGTH];
28 u8 nonce_odd[DIGEST_LENGTH];
29};
30
31static struct session_data oiap_session = {0, };
32
33#endif
34
35u32 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
51u32 tpm1_resume(struct udevice *dev)
52{
53 return tpm1_startup(dev, TPM_ST_STATE);
54}
55
56u32 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
64u32 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
72u32 tpm1_clear_and_reenable(struct udevice *dev)
73{
74 u32 ret;
75
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");
80 return ret;
81 }
82
83 ret = tpm1_physical_enable(dev);
84 if (ret != TPM_SUCCESS) {
85 log_err("TPM: Can't set enabled state\n");
86 return ret;
87 }
88
89 ret = tpm1_physical_set_deactivated(dev, 0);
90 if (ret != TPM_SUCCESS) {
91 log_err("TPM: Can't set deactivated state\n");
92 return ret;
93 }
94
95 return TPM_SUCCESS;
96}
97
98u32 tpm1_nv_define_space(struct udevice *dev, u32 index, u32 perm, u32 size)
99{
100 const u8 command[101] = {
101 0x0, 0xc1,
102 0x0, 0x0, 0x0, 0x65,
103 0x0, 0x0, 0x0, 0xcc,
104
105 0x0, 0x18,
106 0, 0, 0, 0,
107
108 0x0, 0x3,
109 0, 0, 0,
110 0x1f,
111 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112
113 0x0, 0x3,
114 0, 0, 0,
115 0x1f,
116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
117
118 0x0, 0x17,
119 0, 0, 0, 0,
120
121 0,
122 0,
123 0,
124 0, 0, 0, 0,
125 };
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];
130
131 if (pack_byte_string(buf, sizeof(buf), "sddd",
132 0, command, sizeof(command),
133 index_offset, index,
134 perm_offset, perm,
135 size_offset, size))
136 return TPM_LIB_ERROR;
137
138 return tpm_sendrecv_command(dev, buf, NULL, NULL);
139}
140
141u32 tpm1_nv_set_locked(struct udevice *dev)
142{
143 return tpm1_nv_define_space(dev, TPM_NV_INDEX_LOCK, 0, 0);
144}
145
146u32 tpm1_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count)
147{
148 const u8 command[22] = {
149 0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0xcf,
150 };
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);
157 u32 data_size;
158 u32 err;
159
160 if (pack_byte_string(buf, sizeof(buf), "sdd",
161 0, command, sizeof(command),
162 index_offset, index,
163 length_offset, count))
164 return TPM_LIB_ERROR;
165 err = tpm_sendrecv_command(dev, buf, response, &response_length);
166 if (err)
167 return err;
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;
176
177 return 0;
178}
179
180u32 tpm1_nv_write_value(struct udevice *dev, u32 index, const void *data,
181 u32 length)
182{
183 const u8 command[256] = {
184 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd,
185 };
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);
195 u32 err;
196
197 if (pack_byte_string(buf, sizeof(buf), "sddds",
198 0, command, sizeof(command),
199 command_size_offset, total_length,
200 index_offset, index,
201 length_offset, length,
202 data_offset, data, length))
203 return TPM_LIB_ERROR;
204 err = tpm_sendrecv_command(dev, buf, response, &response_length);
205 if (err)
206 return err;
207
208 return 0;
209}
210
211u32 tpm1_extend(struct udevice *dev, u32 index, const void *in_digest,
212 void *out_digest)
213{
214 const u8 command[34] = {
215 0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x14,
216 };
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);
223 u32 err;
224
225 if (pack_byte_string(buf, sizeof(buf), "sds",
226 0, command, sizeof(command),
227 index_offset, index,
228 in_digest_offset, in_digest,
229 PCR_DIGEST_LENGTH))
230 return TPM_LIB_ERROR;
231 err = tpm_sendrecv_command(dev, buf, response, &response_length);
232 if (err)
233 return err;
234
235 if (unpack_byte_string(response, response_length, "s",
236 out_digest_offset, out_digest,
237 PCR_DIGEST_LENGTH))
238 return TPM_LIB_ERROR;
239
240 return 0;
241}
242
243u32 tpm1_pcr_read(struct udevice *dev, u32 index, void *data, size_t count)
244{
245 const u8 command[14] = {
246 0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x15,
247 };
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);
252 u32 err;
253
254 if (count < PCR_DIGEST_LENGTH)
255 return TPM_LIB_ERROR;
256
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);
262 if (err)
263 return err;
264 if (unpack_byte_string(response, response_length, "s",
265 out_digest_offset, data, PCR_DIGEST_LENGTH))
266 return TPM_LIB_ERROR;
267
268 return 0;
269}
270
271u32 tpm1_tsc_physical_presence(struct udevice *dev, u16 presence)
272{
273 const u8 command[12] = {
274 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x0,
275 };
276 const size_t presence_offset = 10;
277 u8 buf[COMMAND_BUFFER_SIZE];
278
279 if (pack_byte_string(buf, sizeof(buf), "sw",
280 0, command, sizeof(command),
281 presence_offset, presence))
282 return TPM_LIB_ERROR;
283
284 return tpm_sendrecv_command(dev, buf, NULL, NULL);
285}
286
287u32 tpm1_finalise_physical_presence(struct udevice *dev)
288{
289 const u8 command[12] = {
290 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x2, 0xa0,
291 };
292
293 return tpm_sendrecv_command(dev, command, NULL, NULL);
294}
295
296u32 tpm1_read_pubek(struct udevice *dev, void *data, size_t count)
297{
298 const u8 command[30] = {
299 0x0, 0xc1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x7c,
300 };
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);
306 u32 data_size;
307 u32 err;
308
309 err = tpm_sendrecv_command(dev, command, response, &response_length);
310 if (err)
311 return err;
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;
323
324 return 0;
325}
326
327u32 tpm1_force_clear(struct udevice *dev)
328{
329 const u8 command[10] = {
330 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x5d,
331 };
332
333 return tpm_sendrecv_command(dev, command, NULL, NULL);
334}
335
336u32 tpm1_physical_enable(struct udevice *dev)
337{
338 const u8 command[10] = {
339 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x6f,
340 };
341
342 return tpm_sendrecv_command(dev, command, NULL, NULL);
343}
344
345u32 tpm1_physical_disable(struct udevice *dev)
346{
347 const u8 command[10] = {
348 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x70,
349 };
350
351 return tpm_sendrecv_command(dev, command, NULL, NULL);
352}
353
354u32 tpm1_physical_set_deactivated(struct udevice *dev, u8 state)
355{
356 const u8 command[11] = {
357 0x0, 0xc1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72,
358 };
359 const size_t state_offset = 10;
360 u8 buf[COMMAND_BUFFER_SIZE];
361
362 if (pack_byte_string(buf, sizeof(buf), "sb",
363 0, command, sizeof(command),
364 state_offset, state))
365 return TPM_LIB_ERROR;
366
367 return tpm_sendrecv_command(dev, buf, NULL, NULL);
368}
369
370u32 tpm1_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap,
371 void *cap, size_t count)
372{
373 const u8 command[22] = {
374 0x0, 0xc1,
375 0x0, 0x0, 0x0, 0x16,
376 0x0, 0x0, 0x0, 0x65,
377 0x0, 0x0, 0x0, 0x0,
378 0x0, 0x0, 0x0, 0x4,
379 0x0, 0x0, 0x0, 0x0,
380 };
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);
387 u32 cap_size;
388 u32 err;
389
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);
396 if (err)
397 return err;
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;
406
407 return 0;
408}
409
410u32 tpm1_get_permanent_flags(struct udevice *dev,
411 struct tpm_permanent_flags *pflags)
412{
413 const u8 command[22] = {
414 0x0, 0xc1,
415 0x0, 0x0, 0x0, 0x16,
416 0x0, 0x0, 0x0, 0x65,
417 0x0, 0x0, 0x0, 0x4,
418 0x0, 0x0, 0x0, 0x4,
419 0x0, 0x0, 0x1, 0x8,
420 };
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);
425 u32 err;
426 u32 data_size;
427
428 err = tpm_sendrecv_command(dev, command, response, &response_length);
429 if (err)
430 return err;
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;
435 }
436 if (data_size < sizeof(*pflags)) {
437 log_err("Data size too small\n");
438 return TPM_LIB_ERROR;
439 }
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;
444 }
445
446 return 0;
447}
448
449u32 tpm1_get_permissions(struct udevice *dev, u32 index, u32 *perm)
450{
451 const u8 command[22] = {
452 0x0, 0xc1,
453 0x0, 0x0, 0x0, 0x16,
454 0x0, 0x0, 0x0, 0x65,
455 0x0, 0x0, 0x0, 0x11,
456 0x0, 0x0, 0x0, 0x4,
457 };
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);
462 u32 err;
463
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);
468 if (err)
469 return err;
470 if (unpack_byte_string(response, response_length, "d",
471 perm_offset, perm))
472 return TPM_LIB_ERROR;
473
474 return 0;
475}
476
477#ifdef CONFIG_TPM_FLUSH_RESOURCES
478u32 tpm1_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type)
479{
480 const u8 command[18] = {
481 0x00, 0xc1,
482 0x00, 0x00, 0x00, 0x12,
483 0x00, 0x00, 0x00, 0xba,
484 0x00, 0x00, 0x00, 0x00,
485 0x00, 0x00, 0x00, 0x00,
486 };
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);
491 u32 err;
492
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;
498
499 err = tpm_sendrecv_command(dev, buf, response, &response_length);
500 if (err)
501 return err;
502 return 0;
503}
504#endif
505
506#ifdef CONFIG_TPM_AUTH_SESSIONS
507
508
509
510
511
512
513
514
515
516
517
518
519
520static u32 create_request_auth(const void *request, size_t request_len0,
521 size_t handles_len,
522 struct session_data *auth_session,
523 void *request_auth, const void *auth)
524{
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;
531
532 if (!auth_session || !auth_session->valid)
533 return TPM_LIB_ERROR;
534
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
541 - handles_len);
542 sha1_finish(&hash_ctx, hmac_data);
543
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);
548
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,
552 DIGEST_LENGTH,
553 auth_continue_offset, 1))
554 return TPM_LIB_ERROR;
555 if (pack_byte_string(hmac_data, sizeof(hmac_data), "ss",
556 DIGEST_LENGTH,
557 auth_session->nonce_even,
558 DIGEST_LENGTH,
559 2 * DIGEST_LENGTH,
560 request_auth + auth_nonce_odd_offset,
561 DIGEST_LENGTH + 1))
562 return TPM_LIB_ERROR;
563 sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
564 request_auth + auth_auth_offset);
565
566 return TPM_SUCCESS;
567}
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583static 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)
587{
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;
594 u8 auth_continue;
595
596 if (!auth_session || !auth_session->valid)
597 return TPM_AUTHFAIL;
598 if (pack_byte_string(hmac_data, sizeof(hmac_data), "d",
599 0, command_code))
600 return TPM_LIB_ERROR;
601 if (response_len0 < TPM_RESPONSE_HEADER_LENGTH)
602 return TPM_LIB_ERROR;
603
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
611 - handles_len);
612 sha1_finish(&hash_ctx, hmac_data);
613
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",
617 DIGEST_LENGTH,
618 response_auth,
619 DIGEST_LENGTH,
620 2 * DIGEST_LENGTH,
621 auth_session->nonce_odd,
622 DIGEST_LENGTH,
623 3 * DIGEST_LENGTH,
624 auth_continue))
625 return TPM_LIB_ERROR;
626
627 sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
628 computed_auth);
629
630 if (memcmp(computed_auth, response_auth + auth_auth_offset,
631 DIGEST_LENGTH))
632 return TPM_AUTHFAIL;
633
634 return TPM_SUCCESS;
635}
636
637u32 tpm1_terminate_auth_session(struct udevice *dev, u32 auth_handle)
638{
639 const u8 command[18] = {
640 0x00, 0xc1,
641 0x00, 0x00, 0x00, 0x00,
642 0x00, 0x00, 0x00, 0xba,
643 0x00, 0x00, 0x00, 0x00,
644 0x00, 0x00, 0x00, 0x02,
645 };
646 const size_t req_handle_offset = TPM_REQUEST_HEADER_LENGTH;
647 u8 request[COMMAND_BUFFER_SIZE];
648
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;
655
656 return tpm_sendrecv_command(dev, request, NULL, NULL);
657}
658
659u32 tpm1_end_oiap(struct udevice *dev)
660{
661 u32 err = TPM_SUCCESS;
662
663 if (oiap_session.valid)
664 err = tpm1_terminate_auth_session(dev, oiap_session.handle);
665 return err;
666}
667
668u32 tpm1_oiap(struct udevice *dev, u32 *auth_handle)
669{
670 const u8 command[10] = {
671 0x00, 0xc1,
672 0x00, 0x00, 0x00, 0x0a,
673 0x00, 0x00, 0x00, 0x0a,
674 };
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);
679 u32 err;
680
681 if (oiap_session.valid)
682 tpm1_terminate_auth_session(dev, oiap_session.handle);
683
684 err = tpm_sendrecv_command(dev, command, response, &response_length);
685 if (err)
686 return err;
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,
690 (u32)DIGEST_LENGTH))
691 return TPM_LIB_ERROR;
692 oiap_session.valid = 1;
693 if (auth_handle)
694 *auth_handle = oiap_session.handle;
695 return 0;
696}
697
698u32 tpm1_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key,
699 size_t key_length, const void *parent_key_usage_auth,
700 u32 *key_handle)
701{
702 const u8 command[14] = {
703 0x00, 0xc2,
704 0x00, 0x00, 0x00, 0x00,
705 0x00, 0x00, 0x00, 0x41,
706 0x00, 0x00, 0x00, 0x00,
707 };
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);
716 u32 err;
717
718 if (!oiap_session.valid) {
719 err = tpm1_oiap(dev, NULL);
720 if (err)
721 return err;
722 }
723 if (pack_byte_string(request, sizeof(request), "sdds",
724 0, command, sizeof(command),
725 req_size_offset,
726 sizeof(command) + key_length
727 + TPM_REQUEST_AUTH_LENGTH,
728 req_parent_handle_offset, parent_handle,
729 req_key_offset, key, key_length
730 ))
731 return TPM_LIB_ERROR;
732
733 err = create_request_auth(request, sizeof(command) + key_length, 4,
734 &oiap_session,
735 request + sizeof(command) + key_length,
736 parent_key_usage_auth);
737 if (err)
738 return err;
739 err = tpm_sendrecv_command(dev, request, response, &response_length);
740 if (err) {
741 if (err == TPM_AUTHFAIL)
742 oiap_session.valid = 0;
743 return err;
744 }
745
746 err = verify_response_auth(0x00000041, response,
747 response_length - TPM_RESPONSE_AUTH_LENGTH,
748 4, &oiap_session,
749 response + response_length -
750 TPM_RESPONSE_AUTH_LENGTH,
751 parent_key_usage_auth);
752 if (err)
753 return err;
754
755 if (key_handle) {
756 if (unpack_byte_string(response, response_length, "d",
757 res_handle_offset, key_handle))
758 return TPM_LIB_ERROR;
759 }
760
761 return 0;
762}
763
764u32 tpm1_get_pub_key_oiap(struct udevice *dev, u32 key_handle,
765 const void *usage_auth, void *pubkey,
766 size_t *pubkey_len)
767{
768 const u8 command[14] = {
769 0x00, 0xc2,
770 0x00, 0x00, 0x00, 0x00,
771 0x00, 0x00, 0x00, 0x21,
772 0x00, 0x00, 0x00, 0x00,
773 };
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);
781 u32 err;
782
783 if (!oiap_session.valid) {
784 err = tpm1_oiap(dev, NULL);
785 if (err)
786 return err;
787 }
788 if (pack_byte_string(request, sizeof(request), "sdd",
789 0, command, sizeof(command),
790 req_size_offset,
791 (u32)(sizeof(command)
792 + TPM_REQUEST_AUTH_LENGTH),
793 req_key_handle_offset, key_handle
794 ))
795 return TPM_LIB_ERROR;
796 err = create_request_auth(request, sizeof(command), 4, &oiap_session,
797 request + sizeof(command), usage_auth);
798 if (err)
799 return err;
800 err = tpm_sendrecv_command(dev, request, response, &response_length);
801 if (err) {
802 if (err == TPM_AUTHFAIL)
803 oiap_session.valid = 0;
804 return err;
805 }
806 err = verify_response_auth(0x00000021, response,
807 response_length - TPM_RESPONSE_AUTH_LENGTH,
808 0, &oiap_session,
809 response + response_length -
810 TPM_RESPONSE_AUTH_LENGTH,
811 usage_auth);
812 if (err)
813 return err;
814
815 if (pubkey) {
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);
824 }
825
826 return 0;
827}
828
829#ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
830u32 tpm1_find_key_sha1(struct udevice *dev, const u8 auth[20],
831 const u8 pubkey_digest[20], u32 *handle)
832{
833 u16 key_count;
834 u32 key_handles[10];
835 u8 buf[288];
836 u8 *ptr;
837 u32 err;
838 u8 digest[20];
839 size_t buf_len;
840 unsigned int i;
841
842
843 err = tpm_get_capability(dev, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
844 sizeof(buf));
845 if (err)
846 return -1;
847 key_count = get_unaligned_be16(buf);
848 ptr = buf + 2;
849 for (i = 0; i < key_count; ++i, ptr += 4)
850 key_handles[i] = get_unaligned_be32(ptr);
851
852
853 for (i = 0; i < key_count; ++i) {
854 buf_len = sizeof(buf);
855 err = tpm_get_pub_key_oiap(key_handles[i], auth, buf, &buf_len);
856 if (err && err != TPM_AUTHFAIL)
857 return -1;
858 if (err)
859 continue;
860 sha1_csum(buf, buf_len, digest);
861 if (!memcmp(digest, pubkey_digest, 20)) {
862 *handle = key_handles[i];
863 return 0;
864 }
865 }
866 return 1;
867}
868#endif
869
870#endif
871
872u32 tpm1_get_random(struct udevice *dev, void *data, u32 count)
873{
874 const u8 command[14] = {
875 0x0, 0xc1,
876 0x0, 0x0, 0x0, 0xe,
877 0x0, 0x0, 0x0, 0x46,
878 };
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);
884 u32 data_size;
885 u8 *out = data;
886
887 while (count > 0) {
888 u32 this_bytes = min((size_t)count,
889 sizeof(response) - data_offset);
890 u32 err;
891
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,
897 &response_length);
898 if (err)
899 return err;
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;
908
909 count -= data_size;
910 out += data_size;
911 }
912
913 return 0;
914}
915