cmd: boot: Update reset usage message
[pandora-u-boot.git] / lib / tpm-v1.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2013 The Chromium OS Authors.
4  * Coypright (c) 2013 Guntermann & Drunck GmbH
5  */
6
7 #define LOG_CATEGORY UCLASS_TPM
8
9 #include <common.h>
10 #include <dm.h>
11 #include <log.h>
12 #include <asm/unaligned.h>
13 #include <u-boot/sha1.h>
14 #include <tpm-common.h>
15 #include <tpm-v1.h>
16 #include "tpm-utils.h"
17
18 #ifdef CONFIG_TPM_AUTH_SESSIONS
19
20 #ifndef CONFIG_SHA1
21 #error "TPM_AUTH_SESSIONS require SHA1 to be configured, too"
22 #endif /* !CONFIG_SHA1 */
23
24 struct session_data {
25         int             valid;
26         u32     handle;
27         u8              nonce_even[DIGEST_LENGTH];
28         u8              nonce_odd[DIGEST_LENGTH];
29 };
30
31 static struct session_data oiap_session = {0, };
32
33 #endif /* CONFIG_TPM_AUTH_SESSIONS */
34
35 u32 tpm1_startup(struct udevice *dev, enum tpm_startup_type mode)
36 {
37         const u8 command[12] = {
38                 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x0,
39         };
40         const size_t mode_offset = 10;
41         u8 buf[COMMAND_BUFFER_SIZE];
42
43         if (pack_byte_string(buf, sizeof(buf), "sw",
44                              0, command, sizeof(command),
45                              mode_offset, mode))
46                 return TPM_LIB_ERROR;
47
48         return tpm_sendrecv_command(dev, buf, NULL, NULL);
49 }
50
51 u32 tpm1_resume(struct udevice *dev)
52 {
53         return tpm1_startup(dev, TPM_ST_STATE);
54 }
55
56 u32 tpm1_self_test_full(struct udevice *dev)
57 {
58         const u8 command[10] = {
59                 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50,
60         };
61         return tpm_sendrecv_command(dev, command, NULL, NULL);
62 }
63
64 u32 tpm1_continue_self_test(struct udevice *dev)
65 {
66         const u8 command[10] = {
67                 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x53,
68         };
69         return tpm_sendrecv_command(dev, command, NULL, NULL);
70 }
71
72 u32 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
98 u32 tpm1_nv_define_space(struct udevice *dev, u32 index, u32 perm, u32 size)
99 {
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 */
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                 /* TPM_NV_DATA_PUBLIC->TPM_PCR_INFO_SHORT */
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                 /* 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 */
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
141 u32 tpm1_nv_set_locked(struct udevice *dev)
142 {
143         return tpm1_nv_define_space(dev, TPM_NV_INDEX_LOCK, 0, 0);
144 }
145
146 u32 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
180 u32 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
211 u32 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
243 u32 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
271 u32 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
287 u32 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
296 u32 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
327 u32 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
336 u32 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
345 u32 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
354 u32 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
370 u32 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,              /* 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 */
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
410 u32 tpm1_get_permanent_flags(struct udevice *dev,
411                              struct tpm_permanent_flags *pflags)
412 {
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 */
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
449 u32 tpm1_get_permissions(struct udevice *dev, u32 index, u32 *perm)
450 {
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 */
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
478 u32 tpm1_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type)
479 {
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 */
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 /* CONFIG_TPM_FLUSH_RESOURCES */
505
506 #ifdef CONFIG_TPM_AUTH_SESSIONS
507
508 /**
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).
512  *
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)
519  */
520 static 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  * 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).
575  *
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)
582  */
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)
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
637 u32 tpm1_terminate_auth_session(struct udevice *dev, u32 auth_handle)
638 {
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 */
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
659 u32 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
668 u32 tpm1_oiap(struct udevice *dev, u32 *auth_handle)
669 {
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 */
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
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,
700                         u32 *key_handle)
701 {
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 */
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
764 u32 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,             /* TPM_TAG */
770                 0x00, 0x00, 0x00, 0x00, /* parameter size */
771                 0x00, 0x00, 0x00, 0x21, /* TPM_COMMAND_CODE */
772                 0x00, 0x00, 0x00, 0x00, /* key handle */
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
830 u32 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         /* fetch list of already loaded keys in the TPM */
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         /* 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 = 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 /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
869
870 #endif /* CONFIG_TPM_AUTH_SESSIONS */
871
872 u32 tpm1_get_random(struct udevice *dev, void *data, u32 count)
873 {
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 */
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 }