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 <asm/unaligned.h>
12 #include <u-boot/sha1.h>
13 #include <tpm-common.h>
14 #include <tpm-v1.h>
15 #include "tpm-utils.h"
16
17 #ifdef CONFIG_TPM_AUTH_SESSIONS
18
19 #ifndef CONFIG_SHA1
20 #error "TPM_AUTH_SESSIONS require SHA1 to be configured, too"
21 #endif /* !CONFIG_SHA1 */
22
23 struct session_data {
24 int valid;
25 u32 handle;
26 u8 nonce_even[DIGEST_LENGTH];
27 u8 nonce_odd[DIGEST_LENGTH];
28 };
29
30 static struct session_data oiap_session = {0, };
31
32 #endif /* CONFIG_TPM_AUTH_SESSIONS */
33
tpm_startup(struct udevice * dev,enum tpm_startup_type mode)34 u32 tpm_startup(struct udevice *dev, enum tpm_startup_type mode)
35 {
36 const u8 command[12] = {
37 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0x99, 0x0, 0x0,
38 };
39 const size_t mode_offset = 10;
40 u8 buf[COMMAND_BUFFER_SIZE];
41
42 if (pack_byte_string(buf, sizeof(buf), "sw",
43 0, command, sizeof(command),
44 mode_offset, mode))
45 return TPM_LIB_ERROR;
46
47 return tpm_sendrecv_command(dev, buf, NULL, NULL);
48 }
49
tpm_resume(struct udevice * dev)50 u32 tpm_resume(struct udevice *dev)
51 {
52 return tpm_startup(dev, TPM_ST_STATE);
53 }
54
tpm_self_test_full(struct udevice * dev)55 u32 tpm_self_test_full(struct udevice *dev)
56 {
57 const u8 command[10] = {
58 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x50,
59 };
60 return tpm_sendrecv_command(dev, command, NULL, NULL);
61 }
62
tpm_continue_self_test(struct udevice * dev)63 u32 tpm_continue_self_test(struct udevice *dev)
64 {
65 const u8 command[10] = {
66 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x53,
67 };
68 return tpm_sendrecv_command(dev, command, NULL, NULL);
69 }
70
tpm_clear_and_reenable(struct udevice * dev)71 u32 tpm_clear_and_reenable(struct udevice *dev)
72 {
73 u32 ret;
74
75 log_info("TPM: Clear and re-enable\n");
76 ret = tpm_force_clear(dev);
77 if (ret != TPM_SUCCESS) {
78 log_err("Can't initiate a force clear\n");
79 return ret;
80 }
81
82 if (tpm_get_version(dev) == TPM_V1) {
83 ret = tpm_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 = tpm_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
96 return TPM_SUCCESS;
97 }
98
tpm_nv_define_space(struct udevice * dev,u32 index,u32 perm,u32 size)99 u32 tpm_nv_define_space(struct udevice *dev, u32 index, u32 perm, u32 size)
100 {
101 const u8 command[101] = {
102 0x0, 0xc1, /* TPM_TAG */
103 0x0, 0x0, 0x0, 0x65, /* parameter size */
104 0x0, 0x0, 0x0, 0xcc, /* TPM_COMMAND_CODE */
105 /* TPM_NV_DATA_PUBLIC->... */
106 0x0, 0x18, /* ...->TPM_STRUCTURE_TAG */
107 0, 0, 0, 0, /* ...->TPM_NV_INDEX */
108 /* TPM_NV_DATA_PUBLIC->TPM_PCR_INFO_SHORT */
109 0x0, 0x3,
110 0, 0, 0,
111 0x1f,
112 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
113 /* TPM_NV_DATA_PUBLIC->TPM_PCR_INFO_SHORT */
114 0x0, 0x3,
115 0, 0, 0,
116 0x1f,
117 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
118 /* TPM_NV_ATTRIBUTES->... */
119 0x0, 0x17, /* ...->TPM_STRUCTURE_TAG */
120 0, 0, 0, 0, /* ...->attributes */
121 /* End of TPM_NV_ATTRIBUTES */
122 0, /* bReadSTClear */
123 0, /* bWriteSTClear */
124 0, /* bWriteDefine */
125 0, 0, 0, 0, /* size */
126 };
127 const size_t index_offset = 12;
128 const size_t perm_offset = 70;
129 const size_t size_offset = 77;
130 u8 buf[COMMAND_BUFFER_SIZE];
131
132 if (pack_byte_string(buf, sizeof(buf), "sddd",
133 0, command, sizeof(command),
134 index_offset, index,
135 perm_offset, perm,
136 size_offset, size))
137 return TPM_LIB_ERROR;
138
139 return tpm_sendrecv_command(dev, buf, NULL, NULL);
140 }
141
tpm_nv_set_locked(struct udevice * dev)142 u32 tpm_nv_set_locked(struct udevice *dev)
143 {
144 return tpm_nv_define_space(dev, TPM_NV_INDEX_LOCK, 0, 0);
145 }
146
tpm_nv_read_value(struct udevice * dev,u32 index,void * data,u32 count)147 u32 tpm_nv_read_value(struct udevice *dev, u32 index, void *data, u32 count)
148 {
149 const u8 command[22] = {
150 0x0, 0xc1, 0x0, 0x0, 0x0, 0x16, 0x0, 0x0, 0x0, 0xcf,
151 };
152 const size_t index_offset = 10;
153 const size_t length_offset = 18;
154 const size_t data_size_offset = 10;
155 const size_t data_offset = 14;
156 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
157 size_t response_length = sizeof(response);
158 u32 data_size;
159 u32 err;
160
161 if (pack_byte_string(buf, sizeof(buf), "sdd",
162 0, command, sizeof(command),
163 index_offset, index,
164 length_offset, count))
165 return TPM_LIB_ERROR;
166 err = tpm_sendrecv_command(dev, buf, response, &response_length);
167 if (err)
168 return err;
169 if (unpack_byte_string(response, response_length, "d",
170 data_size_offset, &data_size))
171 return TPM_LIB_ERROR;
172 if (data_size > count)
173 return TPM_LIB_ERROR;
174 if (unpack_byte_string(response, response_length, "s",
175 data_offset, data, data_size))
176 return TPM_LIB_ERROR;
177
178 return 0;
179 }
180
tpm_nv_write_value(struct udevice * dev,u32 index,const void * data,u32 length)181 u32 tpm_nv_write_value(struct udevice *dev, u32 index, const void *data,
182 u32 length)
183 {
184 const u8 command[256] = {
185 0x0, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xcd,
186 };
187 const size_t command_size_offset = 2;
188 const size_t index_offset = 10;
189 const size_t length_offset = 18;
190 const size_t data_offset = 22;
191 const size_t write_info_size = 12;
192 const u32 total_length =
193 TPM_REQUEST_HEADER_LENGTH + write_info_size + length;
194 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
195 size_t response_length = sizeof(response);
196 u32 err;
197
198 if (pack_byte_string(buf, sizeof(buf), "sddds",
199 0, command, sizeof(command),
200 command_size_offset, total_length,
201 index_offset, index,
202 length_offset, length,
203 data_offset, data, length))
204 return TPM_LIB_ERROR;
205 err = tpm_sendrecv_command(dev, buf, response, &response_length);
206 if (err)
207 return err;
208
209 return 0;
210 }
211
tpm_set_global_lock(struct udevice * dev)212 uint32_t tpm_set_global_lock(struct udevice *dev)
213 {
214 u32 x;
215
216 return tpm_nv_write_value(dev, TPM_NV_INDEX_0, (uint8_t *)&x, 0);
217 }
218
tpm_extend(struct udevice * dev,u32 index,const void * in_digest,void * out_digest)219 u32 tpm_extend(struct udevice *dev, u32 index, const void *in_digest,
220 void *out_digest)
221 {
222 const u8 command[34] = {
223 0x0, 0xc1, 0x0, 0x0, 0x0, 0x22, 0x0, 0x0, 0x0, 0x14,
224 };
225 const size_t index_offset = 10;
226 const size_t in_digest_offset = 14;
227 const size_t out_digest_offset = 10;
228 u8 buf[COMMAND_BUFFER_SIZE];
229 u8 response[TPM_RESPONSE_HEADER_LENGTH + PCR_DIGEST_LENGTH];
230 size_t response_length = sizeof(response);
231 u32 err;
232
233 if (pack_byte_string(buf, sizeof(buf), "sds",
234 0, command, sizeof(command),
235 index_offset, index,
236 in_digest_offset, in_digest,
237 PCR_DIGEST_LENGTH))
238 return TPM_LIB_ERROR;
239 err = tpm_sendrecv_command(dev, buf, response, &response_length);
240 if (err)
241 return err;
242
243 if (unpack_byte_string(response, response_length, "s",
244 out_digest_offset, out_digest,
245 PCR_DIGEST_LENGTH))
246 return TPM_LIB_ERROR;
247
248 return 0;
249 }
250
tpm_pcr_read(struct udevice * dev,u32 index,void * data,size_t count)251 u32 tpm_pcr_read(struct udevice *dev, u32 index, void *data, size_t count)
252 {
253 const u8 command[14] = {
254 0x0, 0xc1, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0x15,
255 };
256 const size_t index_offset = 10;
257 const size_t out_digest_offset = 10;
258 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
259 size_t response_length = sizeof(response);
260 u32 err;
261
262 if (count < PCR_DIGEST_LENGTH)
263 return TPM_LIB_ERROR;
264
265 if (pack_byte_string(buf, sizeof(buf), "sd",
266 0, command, sizeof(command),
267 index_offset, index))
268 return TPM_LIB_ERROR;
269 err = tpm_sendrecv_command(dev, buf, response, &response_length);
270 if (err)
271 return err;
272 if (unpack_byte_string(response, response_length, "s",
273 out_digest_offset, data, PCR_DIGEST_LENGTH))
274 return TPM_LIB_ERROR;
275
276 return 0;
277 }
278
tpm_tsc_physical_presence(struct udevice * dev,u16 presence)279 u32 tpm_tsc_physical_presence(struct udevice *dev, u16 presence)
280 {
281 const u8 command[12] = {
282 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x0, 0x0,
283 };
284 const size_t presence_offset = 10;
285 u8 buf[COMMAND_BUFFER_SIZE];
286
287 if (pack_byte_string(buf, sizeof(buf), "sw",
288 0, command, sizeof(command),
289 presence_offset, presence))
290 return TPM_LIB_ERROR;
291
292 return tpm_sendrecv_command(dev, buf, NULL, NULL);
293 }
294
tpm_finalise_physical_presence(struct udevice * dev)295 u32 tpm_finalise_physical_presence(struct udevice *dev)
296 {
297 const u8 command[12] = {
298 0x0, 0xc1, 0x0, 0x0, 0x0, 0xc, 0x40, 0x0, 0x0, 0xa, 0x2, 0xa0,
299 };
300
301 return tpm_sendrecv_command(dev, command, NULL, NULL);
302 }
303
tpm_read_pubek(struct udevice * dev,void * data,size_t count)304 u32 tpm_read_pubek(struct udevice *dev, void *data, size_t count)
305 {
306 const u8 command[30] = {
307 0x0, 0xc1, 0x0, 0x0, 0x0, 0x1e, 0x0, 0x0, 0x0, 0x7c,
308 };
309 const size_t response_size_offset = 2;
310 const size_t data_offset = 10;
311 const size_t header_and_checksum_size = TPM_RESPONSE_HEADER_LENGTH + 20;
312 u8 response[COMMAND_BUFFER_SIZE + TPM_PUBEK_SIZE];
313 size_t response_length = sizeof(response);
314 u32 data_size;
315 u32 err;
316
317 err = tpm_sendrecv_command(dev, command, response, &response_length);
318 if (err)
319 return err;
320 if (unpack_byte_string(response, response_length, "d",
321 response_size_offset, &data_size))
322 return TPM_LIB_ERROR;
323 if (data_size < header_and_checksum_size)
324 return TPM_LIB_ERROR;
325 data_size -= header_and_checksum_size;
326 if (data_size > count)
327 return TPM_LIB_ERROR;
328 if (unpack_byte_string(response, response_length, "s",
329 data_offset, data, data_size))
330 return TPM_LIB_ERROR;
331
332 return 0;
333 }
334
tpm_force_clear(struct udevice * dev)335 u32 tpm_force_clear(struct udevice *dev)
336 {
337 const u8 command[10] = {
338 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x5d,
339 };
340
341 return tpm_sendrecv_command(dev, command, NULL, NULL);
342 }
343
tpm_physical_enable(struct udevice * dev)344 u32 tpm_physical_enable(struct udevice *dev)
345 {
346 const u8 command[10] = {
347 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x6f,
348 };
349
350 return tpm_sendrecv_command(dev, command, NULL, NULL);
351 }
352
tpm_physical_disable(struct udevice * dev)353 u32 tpm_physical_disable(struct udevice *dev)
354 {
355 const u8 command[10] = {
356 0x0, 0xc1, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0x70,
357 };
358
359 return tpm_sendrecv_command(dev, command, NULL, NULL);
360 }
361
tpm_physical_set_deactivated(struct udevice * dev,u8 state)362 u32 tpm_physical_set_deactivated(struct udevice *dev, u8 state)
363 {
364 const u8 command[11] = {
365 0x0, 0xc1, 0x0, 0x0, 0x0, 0xb, 0x0, 0x0, 0x0, 0x72,
366 };
367 const size_t state_offset = 10;
368 u8 buf[COMMAND_BUFFER_SIZE];
369
370 if (pack_byte_string(buf, sizeof(buf), "sb",
371 0, command, sizeof(command),
372 state_offset, state))
373 return TPM_LIB_ERROR;
374
375 return tpm_sendrecv_command(dev, buf, NULL, NULL);
376 }
377
tpm_get_capability(struct udevice * dev,u32 cap_area,u32 sub_cap,void * cap,size_t count)378 u32 tpm_get_capability(struct udevice *dev, u32 cap_area, u32 sub_cap,
379 void *cap, size_t count)
380 {
381 const u8 command[22] = {
382 0x0, 0xc1, /* TPM_TAG */
383 0x0, 0x0, 0x0, 0x16, /* parameter size */
384 0x0, 0x0, 0x0, 0x65, /* TPM_COMMAND_CODE */
385 0x0, 0x0, 0x0, 0x0, /* TPM_CAPABILITY_AREA */
386 0x0, 0x0, 0x0, 0x4, /* subcap size */
387 0x0, 0x0, 0x0, 0x0, /* subcap value */
388 };
389 const size_t cap_area_offset = 10;
390 const size_t sub_cap_offset = 18;
391 const size_t cap_offset = 14;
392 const size_t cap_size_offset = 10;
393 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
394 size_t response_length = sizeof(response);
395 u32 cap_size;
396 u32 err;
397
398 if (pack_byte_string(buf, sizeof(buf), "sdd",
399 0, command, sizeof(command),
400 cap_area_offset, cap_area,
401 sub_cap_offset, sub_cap))
402 return TPM_LIB_ERROR;
403 err = tpm_sendrecv_command(dev, buf, response, &response_length);
404 if (err)
405 return err;
406 if (unpack_byte_string(response, response_length, "d",
407 cap_size_offset, &cap_size))
408 return TPM_LIB_ERROR;
409 if (cap_size > response_length || cap_size > count)
410 return TPM_LIB_ERROR;
411 if (unpack_byte_string(response, response_length, "s",
412 cap_offset, cap, cap_size))
413 return TPM_LIB_ERROR;
414
415 return 0;
416 }
417
tpm_get_permanent_flags(struct udevice * dev,struct tpm_permanent_flags * pflags)418 u32 tpm_get_permanent_flags(struct udevice *dev,
419 struct tpm_permanent_flags *pflags)
420 {
421 const u8 command[22] = {
422 0x0, 0xc1, /* TPM_TAG */
423 0x0, 0x0, 0x0, 0x16, /* parameter size */
424 0x0, 0x0, 0x0, 0x65, /* TPM_COMMAND_CODE */
425 0x0, 0x0, 0x0, 0x4, /* TPM_CAP_FLAG_PERM */
426 0x0, 0x0, 0x0, 0x4, /* subcap size */
427 0x0, 0x0, 0x1, 0x8, /* subcap value */
428 };
429 const size_t data_size_offset = TPM_HEADER_SIZE;
430 const size_t data_offset = TPM_HEADER_SIZE + sizeof(u32);
431 u8 response[COMMAND_BUFFER_SIZE];
432 size_t response_length = sizeof(response);
433 u32 err;
434 u32 data_size;
435
436 err = tpm_sendrecv_command(dev, command, response, &response_length);
437 if (err)
438 return err;
439 if (unpack_byte_string(response, response_length, "d",
440 data_size_offset, &data_size)) {
441 log_err("Cannot unpack data size\n");
442 return TPM_LIB_ERROR;
443 }
444 if (data_size < sizeof(*pflags)) {
445 log_err("Data size too small\n");
446 return TPM_LIB_ERROR;
447 }
448 if (unpack_byte_string(response, response_length, "s",
449 data_offset, pflags, sizeof(*pflags))) {
450 log_err("Cannot unpack pflags\n");
451 return TPM_LIB_ERROR;
452 }
453
454 return 0;
455 }
456
tpm_get_permissions(struct udevice * dev,u32 index,u32 * perm)457 u32 tpm_get_permissions(struct udevice *dev, u32 index, u32 *perm)
458 {
459 const u8 command[22] = {
460 0x0, 0xc1, /* TPM_TAG */
461 0x0, 0x0, 0x0, 0x16, /* parameter size */
462 0x0, 0x0, 0x0, 0x65, /* TPM_COMMAND_CODE */
463 0x0, 0x0, 0x0, 0x11,
464 0x0, 0x0, 0x0, 0x4,
465 };
466 const size_t index_offset = 18;
467 const size_t perm_offset = 60;
468 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
469 size_t response_length = sizeof(response);
470 u32 err;
471
472 if (pack_byte_string(buf, sizeof(buf), "d", 0, command, sizeof(command),
473 index_offset, index))
474 return TPM_LIB_ERROR;
475 err = tpm_sendrecv_command(dev, buf, response, &response_length);
476 if (err)
477 return err;
478 if (unpack_byte_string(response, response_length, "d",
479 perm_offset, perm))
480 return TPM_LIB_ERROR;
481
482 return 0;
483 }
484
485 #ifdef CONFIG_TPM_FLUSH_RESOURCES
tpm_flush_specific(struct udevice * dev,u32 key_handle,u32 resource_type)486 u32 tpm_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type)
487 {
488 const u8 command[18] = {
489 0x00, 0xc1, /* TPM_TAG */
490 0x00, 0x00, 0x00, 0x12, /* parameter size */
491 0x00, 0x00, 0x00, 0xba, /* TPM_COMMAND_CODE */
492 0x00, 0x00, 0x00, 0x00, /* key handle */
493 0x00, 0x00, 0x00, 0x00, /* resource type */
494 };
495 const size_t key_handle_offset = 10;
496 const size_t resource_type_offset = 14;
497 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
498 size_t response_length = sizeof(response);
499 u32 err;
500
501 if (pack_byte_string(buf, sizeof(buf), "sdd",
502 0, command, sizeof(command),
503 key_handle_offset, key_handle,
504 resource_type_offset, resource_type))
505 return TPM_LIB_ERROR;
506
507 err = tpm_sendrecv_command(dev, buf, response, &response_length);
508 if (err)
509 return err;
510 return 0;
511 }
512 #endif /* CONFIG_TPM_FLUSH_RESOURCES */
513
514 #ifdef CONFIG_TPM_AUTH_SESSIONS
515
516 /**
517 * Fill an authentication block in a request.
518 * This func can create the first as well as the second auth block (for
519 * double authorized commands).
520 *
521 * @param request pointer to the request (w/ uninitialised auth data)
522 * @param request_len0 length of the request without auth data
523 * @param handles_len length of the handles area in request
524 * @param auth_session pointer to the (valid) auth session to be used
525 * @param request_auth pointer to the auth block of the request to be filled
526 * @param auth authentication data (HMAC key)
527 */
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)528 static u32 create_request_auth(const void *request, size_t request_len0,
529 size_t handles_len,
530 struct session_data *auth_session,
531 void *request_auth, const void *auth)
532 {
533 u8 hmac_data[DIGEST_LENGTH * 3 + 1];
534 sha1_context hash_ctx;
535 const size_t command_code_offset = 6;
536 const size_t auth_nonce_odd_offset = 4;
537 const size_t auth_continue_offset = 24;
538 const size_t auth_auth_offset = 25;
539
540 if (!auth_session || !auth_session->valid)
541 return TPM_LIB_ERROR;
542
543 sha1_starts(&hash_ctx);
544 sha1_update(&hash_ctx, request + command_code_offset, 4);
545 if (request_len0 > TPM_REQUEST_HEADER_LENGTH + handles_len)
546 sha1_update(&hash_ctx,
547 request + TPM_REQUEST_HEADER_LENGTH + handles_len,
548 request_len0 - TPM_REQUEST_HEADER_LENGTH
549 - handles_len);
550 sha1_finish(&hash_ctx, hmac_data);
551
552 sha1_starts(&hash_ctx);
553 sha1_update(&hash_ctx, auth_session->nonce_odd, DIGEST_LENGTH);
554 sha1_update(&hash_ctx, hmac_data, sizeof(hmac_data));
555 sha1_finish(&hash_ctx, auth_session->nonce_odd);
556
557 if (pack_byte_string(request_auth, TPM_REQUEST_AUTH_LENGTH, "dsb",
558 0, auth_session->handle,
559 auth_nonce_odd_offset, auth_session->nonce_odd,
560 DIGEST_LENGTH,
561 auth_continue_offset, 1))
562 return TPM_LIB_ERROR;
563 if (pack_byte_string(hmac_data, sizeof(hmac_data), "ss",
564 DIGEST_LENGTH,
565 auth_session->nonce_even,
566 DIGEST_LENGTH,
567 2 * DIGEST_LENGTH,
568 request_auth + auth_nonce_odd_offset,
569 DIGEST_LENGTH + 1))
570 return TPM_LIB_ERROR;
571 sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
572 request_auth + auth_auth_offset);
573
574 return TPM_SUCCESS;
575 }
576
577 /**
578 * Verify an authentication block in a response.
579 * Since this func updates the nonce_even in the session data it has to be
580 * called when receiving a succesfull AUTH response.
581 * This func can verify the first as well as the second auth block (for
582 * double authorized commands).
583 *
584 * @param command_code command code of the request
585 * @param response pointer to the request (w/ uninitialised auth data)
586 * @param handles_len length of the handles area in response
587 * @param auth_session pointer to the (valid) auth session to be used
588 * @param response_auth pointer to the auth block of the response to be verified
589 * @param auth authentication data (HMAC key)
590 */
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)591 static u32 verify_response_auth(u32 command_code, const void *response,
592 size_t response_len0, size_t handles_len,
593 struct session_data *auth_session,
594 const void *response_auth, const void *auth)
595 {
596 u8 hmac_data[DIGEST_LENGTH * 3 + 1];
597 u8 computed_auth[DIGEST_LENGTH];
598 sha1_context hash_ctx;
599 const size_t return_code_offset = 6;
600 const size_t auth_continue_offset = 20;
601 const size_t auth_auth_offset = 21;
602 u8 auth_continue;
603
604 if (!auth_session || !auth_session->valid)
605 return TPM_AUTHFAIL;
606 if (pack_byte_string(hmac_data, sizeof(hmac_data), "d",
607 0, command_code))
608 return TPM_LIB_ERROR;
609 if (response_len0 < TPM_RESPONSE_HEADER_LENGTH)
610 return TPM_LIB_ERROR;
611
612 sha1_starts(&hash_ctx);
613 sha1_update(&hash_ctx, response + return_code_offset, 4);
614 sha1_update(&hash_ctx, hmac_data, 4);
615 if (response_len0 > TPM_RESPONSE_HEADER_LENGTH + handles_len)
616 sha1_update(&hash_ctx,
617 response + TPM_RESPONSE_HEADER_LENGTH + handles_len,
618 response_len0 - TPM_RESPONSE_HEADER_LENGTH
619 - handles_len);
620 sha1_finish(&hash_ctx, hmac_data);
621
622 memcpy(auth_session->nonce_even, response_auth, DIGEST_LENGTH);
623 auth_continue = ((u8 *)response_auth)[auth_continue_offset];
624 if (pack_byte_string(hmac_data, sizeof(hmac_data), "ssb",
625 DIGEST_LENGTH,
626 response_auth,
627 DIGEST_LENGTH,
628 2 * DIGEST_LENGTH,
629 auth_session->nonce_odd,
630 DIGEST_LENGTH,
631 3 * DIGEST_LENGTH,
632 auth_continue))
633 return TPM_LIB_ERROR;
634
635 sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
636 computed_auth);
637
638 if (memcmp(computed_auth, response_auth + auth_auth_offset,
639 DIGEST_LENGTH))
640 return TPM_AUTHFAIL;
641
642 return TPM_SUCCESS;
643 }
644
tpm_terminate_auth_session(struct udevice * dev,u32 auth_handle)645 u32 tpm_terminate_auth_session(struct udevice *dev, u32 auth_handle)
646 {
647 const u8 command[18] = {
648 0x00, 0xc1, /* TPM_TAG */
649 0x00, 0x00, 0x00, 0x00, /* parameter size */
650 0x00, 0x00, 0x00, 0xba, /* TPM_COMMAND_CODE */
651 0x00, 0x00, 0x00, 0x00, /* TPM_HANDLE */
652 0x00, 0x00, 0x00, 0x02, /* TPM_RESOURCE_TYPE */
653 };
654 const size_t req_handle_offset = TPM_REQUEST_HEADER_LENGTH;
655 u8 request[COMMAND_BUFFER_SIZE];
656
657 if (pack_byte_string(request, sizeof(request), "sd",
658 0, command, sizeof(command),
659 req_handle_offset, auth_handle))
660 return TPM_LIB_ERROR;
661 if (oiap_session.valid && oiap_session.handle == auth_handle)
662 oiap_session.valid = 0;
663
664 return tpm_sendrecv_command(dev, request, NULL, NULL);
665 }
666
tpm_end_oiap(struct udevice * dev)667 u32 tpm_end_oiap(struct udevice *dev)
668 {
669 u32 err = TPM_SUCCESS;
670
671 if (oiap_session.valid)
672 err = tpm_terminate_auth_session(dev, oiap_session.handle);
673 return err;
674 }
675
tpm_oiap(struct udevice * dev,u32 * auth_handle)676 u32 tpm_oiap(struct udevice *dev, u32 *auth_handle)
677 {
678 const u8 command[10] = {
679 0x00, 0xc1, /* TPM_TAG */
680 0x00, 0x00, 0x00, 0x0a, /* parameter size */
681 0x00, 0x00, 0x00, 0x0a, /* TPM_COMMAND_CODE */
682 };
683 const size_t res_auth_handle_offset = TPM_RESPONSE_HEADER_LENGTH;
684 const size_t res_nonce_even_offset = TPM_RESPONSE_HEADER_LENGTH + 4;
685 u8 response[COMMAND_BUFFER_SIZE];
686 size_t response_length = sizeof(response);
687 u32 err;
688
689 if (oiap_session.valid)
690 tpm_terminate_auth_session(dev, oiap_session.handle);
691
692 err = tpm_sendrecv_command(dev, command, response, &response_length);
693 if (err)
694 return err;
695 if (unpack_byte_string(response, response_length, "ds",
696 res_auth_handle_offset, &oiap_session.handle,
697 res_nonce_even_offset, &oiap_session.nonce_even,
698 (u32)DIGEST_LENGTH))
699 return TPM_LIB_ERROR;
700 oiap_session.valid = 1;
701 if (auth_handle)
702 *auth_handle = oiap_session.handle;
703 return 0;
704 }
705
tpm_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)706 u32 tpm_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key,
707 size_t key_length, const void *parent_key_usage_auth,
708 u32 *key_handle)
709 {
710 const u8 command[14] = {
711 0x00, 0xc2, /* TPM_TAG */
712 0x00, 0x00, 0x00, 0x00, /* parameter size */
713 0x00, 0x00, 0x00, 0x41, /* TPM_COMMAND_CODE */
714 0x00, 0x00, 0x00, 0x00, /* parent handle */
715 };
716 const size_t req_size_offset = 2;
717 const size_t req_parent_handle_offset = TPM_REQUEST_HEADER_LENGTH;
718 const size_t req_key_offset = TPM_REQUEST_HEADER_LENGTH + 4;
719 const size_t res_handle_offset = TPM_RESPONSE_HEADER_LENGTH;
720 u8 request[sizeof(command) + TPM_KEY12_MAX_LENGTH +
721 TPM_REQUEST_AUTH_LENGTH];
722 u8 response[COMMAND_BUFFER_SIZE];
723 size_t response_length = sizeof(response);
724 u32 err;
725
726 if (!oiap_session.valid) {
727 err = tpm_oiap(dev, NULL);
728 if (err)
729 return err;
730 }
731 if (pack_byte_string(request, sizeof(request), "sdds",
732 0, command, sizeof(command),
733 req_size_offset,
734 sizeof(command) + key_length
735 + TPM_REQUEST_AUTH_LENGTH,
736 req_parent_handle_offset, parent_handle,
737 req_key_offset, key, key_length
738 ))
739 return TPM_LIB_ERROR;
740
741 err = create_request_auth(request, sizeof(command) + key_length, 4,
742 &oiap_session,
743 request + sizeof(command) + key_length,
744 parent_key_usage_auth);
745 if (err)
746 return err;
747 err = tpm_sendrecv_command(dev, request, response, &response_length);
748 if (err) {
749 if (err == TPM_AUTHFAIL)
750 oiap_session.valid = 0;
751 return err;
752 }
753
754 err = verify_response_auth(0x00000041, response,
755 response_length - TPM_RESPONSE_AUTH_LENGTH,
756 4, &oiap_session,
757 response + response_length -
758 TPM_RESPONSE_AUTH_LENGTH,
759 parent_key_usage_auth);
760 if (err)
761 return err;
762
763 if (key_handle) {
764 if (unpack_byte_string(response, response_length, "d",
765 res_handle_offset, key_handle))
766 return TPM_LIB_ERROR;
767 }
768
769 return 0;
770 }
771
tpm_get_pub_key_oiap(struct udevice * dev,u32 key_handle,const void * usage_auth,void * pubkey,size_t * pubkey_len)772 u32 tpm_get_pub_key_oiap(struct udevice *dev, u32 key_handle,
773 const void *usage_auth, void *pubkey,
774 size_t *pubkey_len)
775 {
776 const u8 command[14] = {
777 0x00, 0xc2, /* TPM_TAG */
778 0x00, 0x00, 0x00, 0x00, /* parameter size */
779 0x00, 0x00, 0x00, 0x21, /* TPM_COMMAND_CODE */
780 0x00, 0x00, 0x00, 0x00, /* key handle */
781 };
782 const size_t req_size_offset = 2;
783 const size_t req_key_handle_offset = TPM_REQUEST_HEADER_LENGTH;
784 const size_t res_pubkey_offset = TPM_RESPONSE_HEADER_LENGTH;
785 u8 request[sizeof(command) + TPM_REQUEST_AUTH_LENGTH];
786 u8 response[TPM_RESPONSE_HEADER_LENGTH + TPM_PUBKEY_MAX_LENGTH +
787 TPM_RESPONSE_AUTH_LENGTH];
788 size_t response_length = sizeof(response);
789 u32 err;
790
791 if (!oiap_session.valid) {
792 err = tpm_oiap(dev, NULL);
793 if (err)
794 return err;
795 }
796 if (pack_byte_string(request, sizeof(request), "sdd",
797 0, command, sizeof(command),
798 req_size_offset,
799 (u32)(sizeof(command)
800 + TPM_REQUEST_AUTH_LENGTH),
801 req_key_handle_offset, key_handle
802 ))
803 return TPM_LIB_ERROR;
804 err = create_request_auth(request, sizeof(command), 4, &oiap_session,
805 request + sizeof(command), usage_auth);
806 if (err)
807 return err;
808 err = tpm_sendrecv_command(dev, request, response, &response_length);
809 if (err) {
810 if (err == TPM_AUTHFAIL)
811 oiap_session.valid = 0;
812 return err;
813 }
814 err = verify_response_auth(0x00000021, response,
815 response_length - TPM_RESPONSE_AUTH_LENGTH,
816 0, &oiap_session,
817 response + response_length -
818 TPM_RESPONSE_AUTH_LENGTH,
819 usage_auth);
820 if (err)
821 return err;
822
823 if (pubkey) {
824 if ((response_length - TPM_RESPONSE_HEADER_LENGTH
825 - TPM_RESPONSE_AUTH_LENGTH) > *pubkey_len)
826 return TPM_LIB_ERROR;
827 *pubkey_len = response_length - TPM_RESPONSE_HEADER_LENGTH
828 - TPM_RESPONSE_AUTH_LENGTH;
829 memcpy(pubkey, response + res_pubkey_offset,
830 response_length - TPM_RESPONSE_HEADER_LENGTH
831 - TPM_RESPONSE_AUTH_LENGTH);
832 }
833
834 return 0;
835 }
836
837 #ifdef CONFIG_TPM_LOAD_KEY_BY_SHA1
tpm_find_key_sha1(struct udevice * dev,const u8 auth[20],const u8 pubkey_digest[20],u32 * handle)838 u32 tpm_find_key_sha1(struct udevice *dev, const u8 auth[20],
839 const u8 pubkey_digest[20], u32 *handle)
840 {
841 u16 key_count;
842 u32 key_handles[10];
843 u8 buf[288];
844 u8 *ptr;
845 u32 err;
846 u8 digest[20];
847 size_t buf_len;
848 unsigned int i;
849
850 /* fetch list of already loaded keys in the TPM */
851 err = tpm_get_capability(dev, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
852 sizeof(buf));
853 if (err)
854 return -1;
855 key_count = get_unaligned_be16(buf);
856 ptr = buf + 2;
857 for (i = 0; i < key_count; ++i, ptr += 4)
858 key_handles[i] = get_unaligned_be32(ptr);
859
860 /* now search a(/ the) key which we can access with the given auth */
861 for (i = 0; i < key_count; ++i) {
862 buf_len = sizeof(buf);
863 err = tpm_get_pub_key_oiap(key_handles[i], auth, buf, &buf_len);
864 if (err && err != TPM_AUTHFAIL)
865 return -1;
866 if (err)
867 continue;
868 sha1_csum(buf, buf_len, digest);
869 if (!memcmp(digest, pubkey_digest, 20)) {
870 *handle = key_handles[i];
871 return 0;
872 }
873 }
874 return 1;
875 }
876 #endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
877
878 #endif /* CONFIG_TPM_AUTH_SESSIONS */
879
tpm_get_random(struct udevice * dev,void * data,u32 count)880 u32 tpm_get_random(struct udevice *dev, void *data, u32 count)
881 {
882 const u8 command[14] = {
883 0x0, 0xc1, /* TPM_TAG */
884 0x0, 0x0, 0x0, 0xe, /* parameter size */
885 0x0, 0x0, 0x0, 0x46, /* TPM_COMMAND_CODE */
886 };
887 const size_t length_offset = 10;
888 const size_t data_size_offset = 10;
889 const size_t data_offset = 14;
890 u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
891 size_t response_length = sizeof(response);
892 u32 data_size;
893 u8 *out = data;
894
895 while (count > 0) {
896 u32 this_bytes = min((size_t)count,
897 sizeof(response) - data_offset);
898 u32 err;
899
900 if (pack_byte_string(buf, sizeof(buf), "sd",
901 0, command, sizeof(command),
902 length_offset, this_bytes))
903 return TPM_LIB_ERROR;
904 err = tpm_sendrecv_command(dev, buf, response,
905 &response_length);
906 if (err)
907 return err;
908 if (unpack_byte_string(response, response_length, "d",
909 data_size_offset, &data_size))
910 return TPM_LIB_ERROR;
911 if (data_size > count)
912 return TPM_LIB_ERROR;
913 if (unpack_byte_string(response, response_length, "s",
914 data_offset, out, data_size))
915 return TPM_LIB_ERROR;
916
917 count -= data_size;
918 out += data_size;
919 }
920
921 return 0;
922 }
923