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
tpm1_startup(struct udevice * dev,enum tpm_startup_type mode)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
tpm1_resume(struct udevice * dev)51 u32 tpm1_resume(struct udevice *dev)
52 {
53 return tpm1_startup(dev, TPM_ST_STATE);
54 }
55
tpm1_self_test_full(struct udevice * dev)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
tpm1_continue_self_test(struct udevice * dev)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
tpm1_clear_and_reenable(struct udevice * dev)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
tpm1_nv_define_space(struct udevice * dev,u32 index,u32 perm,u32 size)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
tpm1_nv_set_locked(struct udevice * dev)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
tpm1_nv_read_value(struct udevice * dev,u32 index,void * data,u32 count)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
tpm1_nv_write_value(struct udevice * dev,u32 index,const void * data,u32 length)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
tpm1_extend(struct udevice * dev,u32 index,const void * in_digest,void * out_digest)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
tpm1_pcr_read(struct udevice * dev,u32 index,void * data,size_t count)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
tpm1_tsc_physical_presence(struct udevice * dev,u16 presence)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
tpm1_finalise_physical_presence(struct udevice * dev)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
tpm1_read_pubek(struct udevice * dev,void * data,size_t count)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
tpm1_force_clear(struct udevice * dev)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
tpm1_physical_enable(struct udevice * dev)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
tpm1_physical_disable(struct udevice * dev)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
tpm1_physical_set_deactivated(struct udevice * dev,u8 state)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
tpm1_get_capability(struct udevice * dev,u32 cap_area,u32 sub_cap,void * cap,size_t count)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
tpm1_get_permanent_flags(struct udevice * dev,struct tpm_permanent_flags * pflags)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
tpm1_get_permissions(struct udevice * dev,u32 index,u32 * perm)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
tpm1_flush_specific(struct udevice * dev,u32 key_handle,u32 resource_type)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 */
create_request_auth(const void * request,size_t request_len0,size_t handles_len,struct session_data * auth_session,void * request_auth,const void * auth)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 */
verify_response_auth(u32 command_code,const void * response,size_t response_len0,size_t handles_len,struct session_data * auth_session,const void * response_auth,const void * auth)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
tpm1_terminate_auth_session(struct udevice * dev,u32 auth_handle)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
tpm1_end_oiap(struct udevice * dev)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
tpm1_oiap(struct udevice * dev,u32 * auth_handle)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
tpm1_load_key2_oiap(struct udevice * dev,u32 parent_handle,const void * key,size_t key_length,const void * parent_key_usage_auth,u32 * key_handle)699 u32 tpm1_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key,
700 size_t key_length, const void *parent_key_usage_auth,
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
tpm1_get_pub_key_oiap(struct udevice * dev,u32 key_handle,const void * usage_auth,void * pubkey,size_t * pubkey_len)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
tpm1_find_key_sha1(struct udevice * dev,const u8 auth[20],const u8 pubkey_digest[20],u32 * handle)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
tpm1_get_random(struct udevice * dev,void * data,u32 count)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 }
916