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