xilinx: versal-net: Add support for timer and start it
[platform/kernel/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 = 74;
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), "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);
469         if (err)
470                 return err;
471         if (unpack_byte_string(response, response_length, "d",
472                                perm_offset, perm))
473                 return TPM_LIB_ERROR;
474
475         return 0;
476 }
477
478 #ifdef CONFIG_TPM_FLUSH_RESOURCES
479 u32 tpm1_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type)
480 {
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 */
487         };
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);
492         u32 err;
493
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;
499
500         err = tpm_sendrecv_command(dev, buf, response, &response_length);
501         if (err)
502                 return err;
503         return 0;
504 }
505 #endif /* CONFIG_TPM_FLUSH_RESOURCES */
506
507 #ifdef CONFIG_TPM_AUTH_SESSIONS
508
509 /**
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).
513  *
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)
520  */
521 static u32 create_request_auth(const void *request, size_t request_len0,
522                                size_t handles_len,
523                                struct session_data *auth_session,
524                                void *request_auth, const void *auth)
525 {
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;
532
533         if (!auth_session || !auth_session->valid)
534                 return TPM_LIB_ERROR;
535
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
542                             - handles_len);
543         sha1_finish(&hash_ctx, hmac_data);
544
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);
549
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,
553                              DIGEST_LENGTH,
554                              auth_continue_offset, 1))
555                 return TPM_LIB_ERROR;
556         if (pack_byte_string(hmac_data, sizeof(hmac_data), "ss",
557                              DIGEST_LENGTH,
558                              auth_session->nonce_even,
559                              DIGEST_LENGTH,
560                              2 * DIGEST_LENGTH,
561                              request_auth + auth_nonce_odd_offset,
562                              DIGEST_LENGTH + 1))
563                 return TPM_LIB_ERROR;
564         sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
565                   request_auth + auth_auth_offset);
566
567         return TPM_SUCCESS;
568 }
569
570 /**
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).
576  *
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)
583  */
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)
588 {
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;
595         u8 auth_continue;
596
597         if (!auth_session || !auth_session->valid)
598                 return TPM_AUTHFAIL;
599         if (pack_byte_string(hmac_data, sizeof(hmac_data), "d",
600                              0, command_code))
601                 return TPM_LIB_ERROR;
602         if (response_len0 < TPM_RESPONSE_HEADER_LENGTH)
603                 return TPM_LIB_ERROR;
604
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
612                             - handles_len);
613         sha1_finish(&hash_ctx, hmac_data);
614
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",
618                              DIGEST_LENGTH,
619                              response_auth,
620                              DIGEST_LENGTH,
621                              2 * DIGEST_LENGTH,
622                              auth_session->nonce_odd,
623                              DIGEST_LENGTH,
624                              3 * DIGEST_LENGTH,
625                              auth_continue))
626                 return TPM_LIB_ERROR;
627
628         sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
629                   computed_auth);
630
631         if (memcmp(computed_auth, response_auth + auth_auth_offset,
632                    DIGEST_LENGTH))
633                 return TPM_AUTHFAIL;
634
635         return TPM_SUCCESS;
636 }
637
638 u32 tpm1_terminate_auth_session(struct udevice *dev, u32 auth_handle)
639 {
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 */
646         };
647         const size_t req_handle_offset = TPM_REQUEST_HEADER_LENGTH;
648         u8 request[COMMAND_BUFFER_SIZE];
649
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;
656
657         return tpm_sendrecv_command(dev, request, NULL, NULL);
658 }
659
660 u32 tpm1_end_oiap(struct udevice *dev)
661 {
662         u32 err = TPM_SUCCESS;
663
664         if (oiap_session.valid)
665                 err = tpm1_terminate_auth_session(dev, oiap_session.handle);
666         return err;
667 }
668
669 u32 tpm1_oiap(struct udevice *dev, u32 *auth_handle)
670 {
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 */
675         };
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);
680         u32 err;
681
682         if (oiap_session.valid)
683                 tpm1_terminate_auth_session(dev, oiap_session.handle);
684
685         err = tpm_sendrecv_command(dev, command, response, &response_length);
686         if (err)
687                 return err;
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,
691                                (u32)DIGEST_LENGTH))
692                 return TPM_LIB_ERROR;
693         oiap_session.valid = 1;
694         if (auth_handle)
695                 *auth_handle = oiap_session.handle;
696         return 0;
697 }
698
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,
701                         u32 *key_handle)
702 {
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 */
708         };
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);
717         u32 err;
718
719         if (!oiap_session.valid) {
720                 err = tpm1_oiap(dev, NULL);
721                 if (err)
722                         return err;
723         }
724         if (pack_byte_string(request, sizeof(request), "sdds",
725                              0, command, sizeof(command),
726                              req_size_offset,
727                              sizeof(command) + key_length
728                              + TPM_REQUEST_AUTH_LENGTH,
729                              req_parent_handle_offset, parent_handle,
730                              req_key_offset, key, key_length
731                 ))
732                 return TPM_LIB_ERROR;
733
734         err = create_request_auth(request, sizeof(command) + key_length, 4,
735                                   &oiap_session,
736                                   request + sizeof(command) + key_length,
737                                   parent_key_usage_auth);
738         if (err)
739                 return err;
740         err = tpm_sendrecv_command(dev, request, response, &response_length);
741         if (err) {
742                 if (err == TPM_AUTHFAIL)
743                         oiap_session.valid = 0;
744                 return err;
745         }
746
747         err = verify_response_auth(0x00000041, response,
748                                    response_length - TPM_RESPONSE_AUTH_LENGTH,
749                                    4, &oiap_session,
750                                    response + response_length -
751                                    TPM_RESPONSE_AUTH_LENGTH,
752                                    parent_key_usage_auth);
753         if (err)
754                 return err;
755
756         if (key_handle) {
757                 if (unpack_byte_string(response, response_length, "d",
758                                        res_handle_offset, key_handle))
759                         return TPM_LIB_ERROR;
760         }
761
762         return 0;
763 }
764
765 u32 tpm1_get_pub_key_oiap(struct udevice *dev, u32 key_handle,
766                           const void *usage_auth, void *pubkey,
767                           size_t *pubkey_len)
768 {
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 */
774         };
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);
782         u32 err;
783
784         if (!oiap_session.valid) {
785                 err = tpm1_oiap(dev, NULL);
786                 if (err)
787                         return err;
788         }
789         if (pack_byte_string(request, sizeof(request), "sdd",
790                              0, command, sizeof(command),
791                              req_size_offset,
792                              (u32)(sizeof(command)
793                              + TPM_REQUEST_AUTH_LENGTH),
794                              req_key_handle_offset, key_handle
795                 ))
796                 return TPM_LIB_ERROR;
797         err = create_request_auth(request, sizeof(command), 4, &oiap_session,
798                                   request + sizeof(command), usage_auth);
799         if (err)
800                 return err;
801         err = tpm_sendrecv_command(dev, request, response, &response_length);
802         if (err) {
803                 if (err == TPM_AUTHFAIL)
804                         oiap_session.valid = 0;
805                 return err;
806         }
807         err = verify_response_auth(0x00000021, response,
808                                    response_length - TPM_RESPONSE_AUTH_LENGTH,
809                                    0, &oiap_session,
810                                    response + response_length -
811                                    TPM_RESPONSE_AUTH_LENGTH,
812                                    usage_auth);
813         if (err)
814                 return err;
815
816         if (pubkey) {
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);
825         }
826
827         return 0;
828 }
829
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)
833 {
834         u16 key_count;
835         u32 key_handles[10];
836         u8 buf[288];
837         u8 *ptr;
838         u32 err;
839         u8 digest[20];
840         size_t buf_len;
841         unsigned int i;
842
843         /* fetch list of already loaded keys in the TPM */
844         err = tpm1_get_capability(dev, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
845                                  sizeof(buf));
846         if (err)
847                 return -1;
848         key_count = get_unaligned_be16(buf);
849         ptr = buf + 2;
850         for (i = 0; i < key_count; ++i, ptr += 4)
851                 key_handles[i] = get_unaligned_be32(ptr);
852
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)
858                         return -1;
859                 if (err)
860                         continue;
861                 sha1_csum(buf, buf_len, digest);
862                 if (!memcmp(digest, pubkey_digest, 20)) {
863                         *handle = key_handles[i];
864                         return 0;
865                 }
866         }
867         return 1;
868 }
869 #endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
870
871 #endif /* CONFIG_TPM_AUTH_SESSIONS */
872
873 u32 tpm1_get_random(struct udevice *dev, void *data, u32 count)
874 {
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 */
879         };
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);
885         u32 data_size;
886         u8 *out = data;
887
888         while (count > 0) {
889                 u32 this_bytes = min((size_t)count,
890                                      sizeof(response) - data_offset);
891                 u32 err;
892
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,
898                                            &response_length);
899                 if (err)
900                         return err;
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;
909
910                 count -= data_size;
911                 out += data_size;
912         }
913
914         return 0;
915 }