xref: /openbmc/u-boot/lib/tpm-v1.c (revision ddca9f09)
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 = 74;
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), "sd",
465 			     0, command, sizeof(command),
466 			     index_offset, index))
467 		return TPM_LIB_ERROR;
468 	err = tpm_sendrecv_command(dev, buf, response, &response_length);
469 	if (err)
470 		return err;
471 	if (unpack_byte_string(response, response_length, "d",
472 			       perm_offset, perm))
473 		return TPM_LIB_ERROR;
474 
475 	return 0;
476 }
477 
478 #ifdef CONFIG_TPM_FLUSH_RESOURCES
tpm1_flush_specific(struct udevice * dev,u32 key_handle,u32 resource_type)479 u32 tpm1_flush_specific(struct udevice *dev, u32 key_handle, u32 resource_type)
480 {
481 	const u8 command[18] = {
482 		0x00, 0xc1,             /* TPM_TAG */
483 		0x00, 0x00, 0x00, 0x12, /* parameter size */
484 		0x00, 0x00, 0x00, 0xba, /* TPM_COMMAND_CODE */
485 		0x00, 0x00, 0x00, 0x00, /* key handle */
486 		0x00, 0x00, 0x00, 0x00, /* resource type */
487 	};
488 	const size_t key_handle_offset = 10;
489 	const size_t resource_type_offset = 14;
490 	u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
491 	size_t response_length = sizeof(response);
492 	u32 err;
493 
494 	if (pack_byte_string(buf, sizeof(buf), "sdd",
495 			     0, command, sizeof(command),
496 			     key_handle_offset, key_handle,
497 			     resource_type_offset, resource_type))
498 		return TPM_LIB_ERROR;
499 
500 	err = tpm_sendrecv_command(dev, buf, response, &response_length);
501 	if (err)
502 		return err;
503 	return 0;
504 }
505 #endif /* CONFIG_TPM_FLUSH_RESOURCES */
506 
507 #ifdef CONFIG_TPM_AUTH_SESSIONS
508 
509 /**
510  * Fill an authentication block in a request.
511  * This func can create the first as well as the second auth block (for
512  * double authorized commands).
513  *
514  * @param request	pointer to the request (w/ uninitialised auth data)
515  * @param request_len0	length of the request without auth data
516  * @param handles_len	length of the handles area in request
517  * @param auth_session	pointer to the (valid) auth session to be used
518  * @param request_auth	pointer to the auth block of the request to be filled
519  * @param auth		authentication data (HMAC key)
520  */
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)521 static u32 create_request_auth(const void *request, size_t request_len0,
522 			       size_t handles_len,
523 			       struct session_data *auth_session,
524 			       void *request_auth, const void *auth)
525 {
526 	u8 hmac_data[DIGEST_LENGTH * 3 + 1];
527 	sha1_context hash_ctx;
528 	const size_t command_code_offset = 6;
529 	const size_t auth_nonce_odd_offset = 4;
530 	const size_t auth_continue_offset = 24;
531 	const size_t auth_auth_offset = 25;
532 
533 	if (!auth_session || !auth_session->valid)
534 		return TPM_LIB_ERROR;
535 
536 	sha1_starts(&hash_ctx);
537 	sha1_update(&hash_ctx, request + command_code_offset, 4);
538 	if (request_len0 > TPM_REQUEST_HEADER_LENGTH + handles_len)
539 		sha1_update(&hash_ctx,
540 			    request + TPM_REQUEST_HEADER_LENGTH + handles_len,
541 			    request_len0 - TPM_REQUEST_HEADER_LENGTH
542 			    - handles_len);
543 	sha1_finish(&hash_ctx, hmac_data);
544 
545 	sha1_starts(&hash_ctx);
546 	sha1_update(&hash_ctx, auth_session->nonce_odd, DIGEST_LENGTH);
547 	sha1_update(&hash_ctx, hmac_data, sizeof(hmac_data));
548 	sha1_finish(&hash_ctx, auth_session->nonce_odd);
549 
550 	if (pack_byte_string(request_auth, TPM_REQUEST_AUTH_LENGTH, "dsb",
551 			     0, auth_session->handle,
552 			     auth_nonce_odd_offset, auth_session->nonce_odd,
553 			     DIGEST_LENGTH,
554 			     auth_continue_offset, 1))
555 		return TPM_LIB_ERROR;
556 	if (pack_byte_string(hmac_data, sizeof(hmac_data), "ss",
557 			     DIGEST_LENGTH,
558 			     auth_session->nonce_even,
559 			     DIGEST_LENGTH,
560 			     2 * DIGEST_LENGTH,
561 			     request_auth + auth_nonce_odd_offset,
562 			     DIGEST_LENGTH + 1))
563 		return TPM_LIB_ERROR;
564 	sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
565 		  request_auth + auth_auth_offset);
566 
567 	return TPM_SUCCESS;
568 }
569 
570 /**
571  * Verify an authentication block in a response.
572  * Since this func updates the nonce_even in the session data it has to be
573  * called when receiving a succesfull AUTH response.
574  * This func can verify the first as well as the second auth block (for
575  * double authorized commands).
576  *
577  * @param command_code	command code of the request
578  * @param response	pointer to the request (w/ uninitialised auth data)
579  * @param handles_len	length of the handles area in response
580  * @param auth_session	pointer to the (valid) auth session to be used
581  * @param response_auth	pointer to the auth block of the response to be verified
582  * @param auth		authentication data (HMAC key)
583  */
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)584 static u32 verify_response_auth(u32 command_code, const void *response,
585 				size_t response_len0, size_t handles_len,
586 				struct session_data *auth_session,
587 				const void *response_auth, const void *auth)
588 {
589 	u8 hmac_data[DIGEST_LENGTH * 3 + 1];
590 	u8 computed_auth[DIGEST_LENGTH];
591 	sha1_context hash_ctx;
592 	const size_t return_code_offset = 6;
593 	const size_t auth_continue_offset = 20;
594 	const size_t auth_auth_offset = 21;
595 	u8 auth_continue;
596 
597 	if (!auth_session || !auth_session->valid)
598 		return TPM_AUTHFAIL;
599 	if (pack_byte_string(hmac_data, sizeof(hmac_data), "d",
600 			     0, command_code))
601 		return TPM_LIB_ERROR;
602 	if (response_len0 < TPM_RESPONSE_HEADER_LENGTH)
603 		return TPM_LIB_ERROR;
604 
605 	sha1_starts(&hash_ctx);
606 	sha1_update(&hash_ctx, response + return_code_offset, 4);
607 	sha1_update(&hash_ctx, hmac_data, 4);
608 	if (response_len0 > TPM_RESPONSE_HEADER_LENGTH + handles_len)
609 		sha1_update(&hash_ctx,
610 			    response + TPM_RESPONSE_HEADER_LENGTH + handles_len,
611 			    response_len0 - TPM_RESPONSE_HEADER_LENGTH
612 			    - handles_len);
613 	sha1_finish(&hash_ctx, hmac_data);
614 
615 	memcpy(auth_session->nonce_even, response_auth, DIGEST_LENGTH);
616 	auth_continue = ((u8 *)response_auth)[auth_continue_offset];
617 	if (pack_byte_string(hmac_data, sizeof(hmac_data), "ssb",
618 			     DIGEST_LENGTH,
619 			     response_auth,
620 			     DIGEST_LENGTH,
621 			     2 * DIGEST_LENGTH,
622 			     auth_session->nonce_odd,
623 			     DIGEST_LENGTH,
624 			     3 * DIGEST_LENGTH,
625 			     auth_continue))
626 		return TPM_LIB_ERROR;
627 
628 	sha1_hmac(auth, DIGEST_LENGTH, hmac_data, sizeof(hmac_data),
629 		  computed_auth);
630 
631 	if (memcmp(computed_auth, response_auth + auth_auth_offset,
632 		   DIGEST_LENGTH))
633 		return TPM_AUTHFAIL;
634 
635 	return TPM_SUCCESS;
636 }
637 
tpm1_terminate_auth_session(struct udevice * dev,u32 auth_handle)638 u32 tpm1_terminate_auth_session(struct udevice *dev, u32 auth_handle)
639 {
640 	const u8 command[18] = {
641 		0x00, 0xc1,		/* TPM_TAG */
642 		0x00, 0x00, 0x00, 0x00,	/* parameter size */
643 		0x00, 0x00, 0x00, 0xba,	/* TPM_COMMAND_CODE */
644 		0x00, 0x00, 0x00, 0x00,	/* TPM_HANDLE */
645 		0x00, 0x00, 0x00, 0x02,	/* TPM_RESOURCE_TYPE */
646 	};
647 	const size_t req_handle_offset = TPM_REQUEST_HEADER_LENGTH;
648 	u8 request[COMMAND_BUFFER_SIZE];
649 
650 	if (pack_byte_string(request, sizeof(request), "sd",
651 			     0, command, sizeof(command),
652 			     req_handle_offset, auth_handle))
653 		return TPM_LIB_ERROR;
654 	if (oiap_session.valid && oiap_session.handle == auth_handle)
655 		oiap_session.valid = 0;
656 
657 	return tpm_sendrecv_command(dev, request, NULL, NULL);
658 }
659 
tpm1_end_oiap(struct udevice * dev)660 u32 tpm1_end_oiap(struct udevice *dev)
661 {
662 	u32 err = TPM_SUCCESS;
663 
664 	if (oiap_session.valid)
665 		err = tpm1_terminate_auth_session(dev, oiap_session.handle);
666 	return err;
667 }
668 
tpm1_oiap(struct udevice * dev,u32 * auth_handle)669 u32 tpm1_oiap(struct udevice *dev, u32 *auth_handle)
670 {
671 	const u8 command[10] = {
672 		0x00, 0xc1,		/* TPM_TAG */
673 		0x00, 0x00, 0x00, 0x0a,	/* parameter size */
674 		0x00, 0x00, 0x00, 0x0a,	/* TPM_COMMAND_CODE */
675 	};
676 	const size_t res_auth_handle_offset = TPM_RESPONSE_HEADER_LENGTH;
677 	const size_t res_nonce_even_offset = TPM_RESPONSE_HEADER_LENGTH + 4;
678 	u8 response[COMMAND_BUFFER_SIZE];
679 	size_t response_length = sizeof(response);
680 	u32 err;
681 
682 	if (oiap_session.valid)
683 		tpm1_terminate_auth_session(dev, oiap_session.handle);
684 
685 	err = tpm_sendrecv_command(dev, command, response, &response_length);
686 	if (err)
687 		return err;
688 	if (unpack_byte_string(response, response_length, "ds",
689 			       res_auth_handle_offset, &oiap_session.handle,
690 			       res_nonce_even_offset, &oiap_session.nonce_even,
691 			       (u32)DIGEST_LENGTH))
692 		return TPM_LIB_ERROR;
693 	oiap_session.valid = 1;
694 	if (auth_handle)
695 		*auth_handle = oiap_session.handle;
696 	return 0;
697 }
698 
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)699 u32 tpm1_load_key2_oiap(struct udevice *dev, u32 parent_handle, const void *key,
700 			size_t key_length, const void *parent_key_usage_auth,
701 			u32 *key_handle)
702 {
703 	const u8 command[14] = {
704 		0x00, 0xc2,		/* TPM_TAG */
705 		0x00, 0x00, 0x00, 0x00,	/* parameter size */
706 		0x00, 0x00, 0x00, 0x41,	/* TPM_COMMAND_CODE */
707 		0x00, 0x00, 0x00, 0x00,	/* parent handle */
708 	};
709 	const size_t req_size_offset = 2;
710 	const size_t req_parent_handle_offset = TPM_REQUEST_HEADER_LENGTH;
711 	const size_t req_key_offset = TPM_REQUEST_HEADER_LENGTH + 4;
712 	const size_t res_handle_offset = TPM_RESPONSE_HEADER_LENGTH;
713 	u8 request[sizeof(command) + TPM_KEY12_MAX_LENGTH +
714 		   TPM_REQUEST_AUTH_LENGTH];
715 	u8 response[COMMAND_BUFFER_SIZE];
716 	size_t response_length = sizeof(response);
717 	u32 err;
718 
719 	if (!oiap_session.valid) {
720 		err = tpm1_oiap(dev, NULL);
721 		if (err)
722 			return err;
723 	}
724 	if (pack_byte_string(request, sizeof(request), "sdds",
725 			     0, command, sizeof(command),
726 			     req_size_offset,
727 			     sizeof(command) + key_length
728 			     + TPM_REQUEST_AUTH_LENGTH,
729 			     req_parent_handle_offset, parent_handle,
730 			     req_key_offset, key, key_length
731 		))
732 		return TPM_LIB_ERROR;
733 
734 	err = create_request_auth(request, sizeof(command) + key_length, 4,
735 				  &oiap_session,
736 				  request + sizeof(command) + key_length,
737 				  parent_key_usage_auth);
738 	if (err)
739 		return err;
740 	err = tpm_sendrecv_command(dev, request, response, &response_length);
741 	if (err) {
742 		if (err == TPM_AUTHFAIL)
743 			oiap_session.valid = 0;
744 		return err;
745 	}
746 
747 	err = verify_response_auth(0x00000041, response,
748 				   response_length - TPM_RESPONSE_AUTH_LENGTH,
749 				   4, &oiap_session,
750 				   response + response_length -
751 				   TPM_RESPONSE_AUTH_LENGTH,
752 				   parent_key_usage_auth);
753 	if (err)
754 		return err;
755 
756 	if (key_handle) {
757 		if (unpack_byte_string(response, response_length, "d",
758 				       res_handle_offset, key_handle))
759 			return TPM_LIB_ERROR;
760 	}
761 
762 	return 0;
763 }
764 
tpm1_get_pub_key_oiap(struct udevice * dev,u32 key_handle,const void * usage_auth,void * pubkey,size_t * pubkey_len)765 u32 tpm1_get_pub_key_oiap(struct udevice *dev, u32 key_handle,
766 			  const void *usage_auth, void *pubkey,
767 			  size_t *pubkey_len)
768 {
769 	const u8 command[14] = {
770 		0x00, 0xc2,		/* TPM_TAG */
771 		0x00, 0x00, 0x00, 0x00,	/* parameter size */
772 		0x00, 0x00, 0x00, 0x21,	/* TPM_COMMAND_CODE */
773 		0x00, 0x00, 0x00, 0x00,	/* key handle */
774 	};
775 	const size_t req_size_offset = 2;
776 	const size_t req_key_handle_offset = TPM_REQUEST_HEADER_LENGTH;
777 	const size_t res_pubkey_offset = TPM_RESPONSE_HEADER_LENGTH;
778 	u8 request[sizeof(command) + TPM_REQUEST_AUTH_LENGTH];
779 	u8 response[TPM_RESPONSE_HEADER_LENGTH + TPM_PUBKEY_MAX_LENGTH +
780 		    TPM_RESPONSE_AUTH_LENGTH];
781 	size_t response_length = sizeof(response);
782 	u32 err;
783 
784 	if (!oiap_session.valid) {
785 		err = tpm1_oiap(dev, NULL);
786 		if (err)
787 			return err;
788 	}
789 	if (pack_byte_string(request, sizeof(request), "sdd",
790 			     0, command, sizeof(command),
791 			     req_size_offset,
792 			     (u32)(sizeof(command)
793 			     + TPM_REQUEST_AUTH_LENGTH),
794 			     req_key_handle_offset, key_handle
795 		))
796 		return TPM_LIB_ERROR;
797 	err = create_request_auth(request, sizeof(command), 4, &oiap_session,
798 				  request + sizeof(command), usage_auth);
799 	if (err)
800 		return err;
801 	err = tpm_sendrecv_command(dev, request, response, &response_length);
802 	if (err) {
803 		if (err == TPM_AUTHFAIL)
804 			oiap_session.valid = 0;
805 		return err;
806 	}
807 	err = verify_response_auth(0x00000021, response,
808 				   response_length - TPM_RESPONSE_AUTH_LENGTH,
809 				   0, &oiap_session,
810 				   response + response_length -
811 				   TPM_RESPONSE_AUTH_LENGTH,
812 				   usage_auth);
813 	if (err)
814 		return err;
815 
816 	if (pubkey) {
817 		if ((response_length - TPM_RESPONSE_HEADER_LENGTH
818 		     - TPM_RESPONSE_AUTH_LENGTH) > *pubkey_len)
819 			return TPM_LIB_ERROR;
820 		*pubkey_len = response_length - TPM_RESPONSE_HEADER_LENGTH
821 			- TPM_RESPONSE_AUTH_LENGTH;
822 		memcpy(pubkey, response + res_pubkey_offset,
823 		       response_length - TPM_RESPONSE_HEADER_LENGTH
824 		       - TPM_RESPONSE_AUTH_LENGTH);
825 	}
826 
827 	return 0;
828 }
829 
830 #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)831 u32 tpm1_find_key_sha1(struct udevice *dev, const u8 auth[20],
832 		       const u8 pubkey_digest[20], u32 *handle)
833 {
834 	u16 key_count;
835 	u32 key_handles[10];
836 	u8 buf[288];
837 	u8 *ptr;
838 	u32 err;
839 	u8 digest[20];
840 	size_t buf_len;
841 	unsigned int i;
842 
843 	/* fetch list of already loaded keys in the TPM */
844 	err = tpm1_get_capability(dev, TPM_CAP_HANDLE, TPM_RT_KEY, buf,
845 				 sizeof(buf));
846 	if (err)
847 		return -1;
848 	key_count = get_unaligned_be16(buf);
849 	ptr = buf + 2;
850 	for (i = 0; i < key_count; ++i, ptr += 4)
851 		key_handles[i] = get_unaligned_be32(ptr);
852 
853 	/* now search a(/ the) key which we can access with the given auth */
854 	for (i = 0; i < key_count; ++i) {
855 		buf_len = sizeof(buf);
856 		err = tpm1_get_pub_key_oiap(dev, key_handles[i], auth, buf, &buf_len);
857 		if (err && err != TPM_AUTHFAIL)
858 			return -1;
859 		if (err)
860 			continue;
861 		sha1_csum(buf, buf_len, digest);
862 		if (!memcmp(digest, pubkey_digest, 20)) {
863 			*handle = key_handles[i];
864 			return 0;
865 		}
866 	}
867 	return 1;
868 }
869 #endif /* CONFIG_TPM_LOAD_KEY_BY_SHA1 */
870 
871 #endif /* CONFIG_TPM_AUTH_SESSIONS */
872 
tpm1_get_random(struct udevice * dev,void * data,u32 count)873 u32 tpm1_get_random(struct udevice *dev, void *data, u32 count)
874 {
875 	const u8 command[14] = {
876 		0x0, 0xc1,		/* TPM_TAG */
877 		0x0, 0x0, 0x0, 0xe,	/* parameter size */
878 		0x0, 0x0, 0x0, 0x46,	/* TPM_COMMAND_CODE */
879 	};
880 	const size_t length_offset = 10;
881 	const size_t data_size_offset = 10;
882 	const size_t data_offset = 14;
883 	u8 buf[COMMAND_BUFFER_SIZE], response[COMMAND_BUFFER_SIZE];
884 	size_t response_length = sizeof(response);
885 	u32 data_size;
886 	u8 *out = data;
887 
888 	while (count > 0) {
889 		u32 this_bytes = min((size_t)count,
890 				     sizeof(response) - data_offset);
891 		u32 err;
892 
893 		if (pack_byte_string(buf, sizeof(buf), "sd",
894 				     0, command, sizeof(command),
895 				     length_offset, this_bytes))
896 			return TPM_LIB_ERROR;
897 		err = tpm_sendrecv_command(dev, buf, response,
898 					   &response_length);
899 		if (err)
900 			return err;
901 		if (unpack_byte_string(response, response_length, "d",
902 				       data_size_offset, &data_size))
903 			return TPM_LIB_ERROR;
904 		if (data_size > count)
905 			return TPM_LIB_ERROR;
906 		if (unpack_byte_string(response, response_length, "s",
907 				       data_offset, out, data_size))
908 			return TPM_LIB_ERROR;
909 
910 		count -= data_size;
911 		out += data_size;
912 	}
913 
914 	return 0;
915 }
916