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