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