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