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