xref: /openbmc/u-boot/lib/tpm-v1.c (revision 0e31666d)
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 
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 
50 u32 tpm_resume(struct udevice *dev)
51 {
52 	return tpm_startup(dev, TPM_ST_STATE);
53 }
54 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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
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  */
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  */
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 
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 
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 
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 
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 
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
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 
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