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