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