xref: /openbmc/linux/drivers/char/tpm/tpm2-cmd.c (revision 961be665)
1 /*
2  * Copyright (C) 2014 Intel Corporation
3  *
4  * Authors:
5  * Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
6  *
7  * Maintained by: <tpmdd-devel@lists.sourceforge.net>
8  *
9  * This file contains TPM2 protocol implementations of the commands
10  * used by the kernel internally.
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; version 2
15  * of the License.
16  */
17 
18 #include "tpm.h"
19 
20 struct tpm2_startup_in {
21 	__be16	startup_type;
22 } __packed;
23 
24 struct tpm2_self_test_in {
25 	u8	full_test;
26 } __packed;
27 
28 struct tpm2_pcr_read_in {
29 	__be32	pcr_selects_cnt;
30 	__be16	hash_alg;
31 	u8	pcr_select_size;
32 	u8	pcr_select[TPM2_PCR_SELECT_MIN];
33 } __packed;
34 
35 struct tpm2_pcr_read_out {
36 	__be32	update_cnt;
37 	__be32	pcr_selects_cnt;
38 	__be16	hash_alg;
39 	u8	pcr_select_size;
40 	u8	pcr_select[TPM2_PCR_SELECT_MIN];
41 	__be32	digests_cnt;
42 	__be16	digest_size;
43 	u8	digest[TPM_DIGEST_SIZE];
44 } __packed;
45 
46 struct tpm2_null_auth_area {
47 	__be32			handle;
48 	__be16			nonce_size;
49 	u8			attributes;
50 	__be16			auth_size;
51 } __packed;
52 
53 struct tpm2_pcr_extend_in {
54 	__be32				pcr_idx;
55 	__be32				auth_area_size;
56 	struct tpm2_null_auth_area	auth_area;
57 	__be32				digest_cnt;
58 	__be16				hash_alg;
59 	u8				digest[TPM_DIGEST_SIZE];
60 } __packed;
61 
62 struct tpm2_get_tpm_pt_in {
63 	__be32	cap_id;
64 	__be32	property_id;
65 	__be32	property_cnt;
66 } __packed;
67 
68 struct tpm2_get_tpm_pt_out {
69 	u8	more_data;
70 	__be32	subcap_id;
71 	__be32	property_cnt;
72 	__be32	property_id;
73 	__be32	value;
74 } __packed;
75 
76 struct tpm2_get_random_in {
77 	__be16	size;
78 } __packed;
79 
80 struct tpm2_get_random_out {
81 	__be16	size;
82 	u8	buffer[TPM_MAX_RNG_DATA];
83 } __packed;
84 
85 union tpm2_cmd_params {
86 	struct	tpm2_startup_in		startup_in;
87 	struct	tpm2_self_test_in	selftest_in;
88 	struct	tpm2_pcr_read_in	pcrread_in;
89 	struct	tpm2_pcr_read_out	pcrread_out;
90 	struct	tpm2_pcr_extend_in	pcrextend_in;
91 	struct	tpm2_get_tpm_pt_in	get_tpm_pt_in;
92 	struct	tpm2_get_tpm_pt_out	get_tpm_pt_out;
93 	struct	tpm2_get_random_in	getrandom_in;
94 	struct	tpm2_get_random_out	getrandom_out;
95 };
96 
97 struct tpm2_cmd {
98 	tpm_cmd_header		header;
99 	union tpm2_cmd_params	params;
100 } __packed;
101 
102 /*
103  * Array with one entry per ordinal defining the maximum amount
104  * of time the chip could take to return the result. The values
105  * of the SHORT, MEDIUM, and LONG durations are taken from the
106  * PC Client Profile (PTP) specification.
107  */
108 static const u8 tpm2_ordinal_duration[TPM2_CC_LAST - TPM2_CC_FIRST + 1] = {
109 	TPM_UNDEFINED,		/* 11F */
110 	TPM_UNDEFINED,		/* 120 */
111 	TPM_LONG,		/* 121 */
112 	TPM_UNDEFINED,		/* 122 */
113 	TPM_UNDEFINED,		/* 123 */
114 	TPM_UNDEFINED,		/* 124 */
115 	TPM_UNDEFINED,		/* 125 */
116 	TPM_UNDEFINED,		/* 126 */
117 	TPM_UNDEFINED,		/* 127 */
118 	TPM_UNDEFINED,		/* 128 */
119 	TPM_LONG,		/* 129 */
120 	TPM_UNDEFINED,		/* 12a */
121 	TPM_UNDEFINED,		/* 12b */
122 	TPM_UNDEFINED,		/* 12c */
123 	TPM_UNDEFINED,		/* 12d */
124 	TPM_UNDEFINED,		/* 12e */
125 	TPM_UNDEFINED,		/* 12f */
126 	TPM_UNDEFINED,		/* 130 */
127 	TPM_UNDEFINED,		/* 131 */
128 	TPM_UNDEFINED,		/* 132 */
129 	TPM_UNDEFINED,		/* 133 */
130 	TPM_UNDEFINED,		/* 134 */
131 	TPM_UNDEFINED,		/* 135 */
132 	TPM_UNDEFINED,		/* 136 */
133 	TPM_UNDEFINED,		/* 137 */
134 	TPM_UNDEFINED,		/* 138 */
135 	TPM_UNDEFINED,		/* 139 */
136 	TPM_UNDEFINED,		/* 13a */
137 	TPM_UNDEFINED,		/* 13b */
138 	TPM_UNDEFINED,		/* 13c */
139 	TPM_UNDEFINED,		/* 13d */
140 	TPM_MEDIUM,		/* 13e */
141 	TPM_UNDEFINED,		/* 13f */
142 	TPM_UNDEFINED,		/* 140 */
143 	TPM_UNDEFINED,		/* 141 */
144 	TPM_UNDEFINED,		/* 142 */
145 	TPM_LONG,		/* 143 */
146 	TPM_MEDIUM,		/* 144 */
147 	TPM_UNDEFINED,		/* 145 */
148 	TPM_UNDEFINED,		/* 146 */
149 	TPM_UNDEFINED,		/* 147 */
150 	TPM_UNDEFINED,		/* 148 */
151 	TPM_UNDEFINED,		/* 149 */
152 	TPM_UNDEFINED,		/* 14a */
153 	TPM_UNDEFINED,		/* 14b */
154 	TPM_UNDEFINED,		/* 14c */
155 	TPM_UNDEFINED,		/* 14d */
156 	TPM_LONG,		/* 14e */
157 	TPM_UNDEFINED,		/* 14f */
158 	TPM_UNDEFINED,		/* 150 */
159 	TPM_UNDEFINED,		/* 151 */
160 	TPM_UNDEFINED,		/* 152 */
161 	TPM_UNDEFINED,		/* 153 */
162 	TPM_UNDEFINED,		/* 154 */
163 	TPM_UNDEFINED,		/* 155 */
164 	TPM_UNDEFINED,		/* 156 */
165 	TPM_UNDEFINED,		/* 157 */
166 	TPM_UNDEFINED,		/* 158 */
167 	TPM_UNDEFINED,		/* 159 */
168 	TPM_UNDEFINED,		/* 15a */
169 	TPM_UNDEFINED,		/* 15b */
170 	TPM_MEDIUM,		/* 15c */
171 	TPM_UNDEFINED,		/* 15d */
172 	TPM_UNDEFINED,		/* 15e */
173 	TPM_UNDEFINED,		/* 15f */
174 	TPM_UNDEFINED,		/* 160 */
175 	TPM_UNDEFINED,		/* 161 */
176 	TPM_UNDEFINED,		/* 162 */
177 	TPM_UNDEFINED,		/* 163 */
178 	TPM_UNDEFINED,		/* 164 */
179 	TPM_UNDEFINED,		/* 165 */
180 	TPM_UNDEFINED,		/* 166 */
181 	TPM_UNDEFINED,		/* 167 */
182 	TPM_UNDEFINED,		/* 168 */
183 	TPM_UNDEFINED,		/* 169 */
184 	TPM_UNDEFINED,		/* 16a */
185 	TPM_UNDEFINED,		/* 16b */
186 	TPM_UNDEFINED,		/* 16c */
187 	TPM_UNDEFINED,		/* 16d */
188 	TPM_UNDEFINED,		/* 16e */
189 	TPM_UNDEFINED,		/* 16f */
190 	TPM_UNDEFINED,		/* 170 */
191 	TPM_UNDEFINED,		/* 171 */
192 	TPM_UNDEFINED,		/* 172 */
193 	TPM_UNDEFINED,		/* 173 */
194 	TPM_UNDEFINED,		/* 174 */
195 	TPM_UNDEFINED,		/* 175 */
196 	TPM_UNDEFINED,		/* 176 */
197 	TPM_LONG,		/* 177 */
198 	TPM_UNDEFINED,		/* 178 */
199 	TPM_UNDEFINED,		/* 179 */
200 	TPM_MEDIUM,		/* 17a */
201 	TPM_LONG,		/* 17b */
202 	TPM_UNDEFINED,		/* 17c */
203 	TPM_UNDEFINED,		/* 17d */
204 	TPM_UNDEFINED,		/* 17e */
205 	TPM_UNDEFINED,		/* 17f */
206 	TPM_UNDEFINED,		/* 180 */
207 	TPM_UNDEFINED,		/* 181 */
208 	TPM_MEDIUM,		/* 182 */
209 	TPM_UNDEFINED,		/* 183 */
210 	TPM_UNDEFINED,		/* 184 */
211 	TPM_MEDIUM,		/* 185 */
212 	TPM_MEDIUM,		/* 186 */
213 	TPM_UNDEFINED,		/* 187 */
214 	TPM_UNDEFINED,		/* 188 */
215 	TPM_UNDEFINED,		/* 189 */
216 	TPM_UNDEFINED,		/* 18a */
217 	TPM_UNDEFINED,		/* 18b */
218 	TPM_UNDEFINED,		/* 18c */
219 	TPM_UNDEFINED,		/* 18d */
220 	TPM_UNDEFINED,		/* 18e */
221 	TPM_UNDEFINED		/* 18f */
222 };
223 
224 #define TPM2_PCR_READ_IN_SIZE \
225 	(sizeof(struct tpm_input_header) + \
226 	 sizeof(struct tpm2_pcr_read_in))
227 
228 static const struct tpm_input_header tpm2_pcrread_header = {
229 	.tag = cpu_to_be16(TPM2_ST_NO_SESSIONS),
230 	.length = cpu_to_be32(TPM2_PCR_READ_IN_SIZE),
231 	.ordinal = cpu_to_be32(TPM2_CC_PCR_READ)
232 };
233 
234 /**
235  * tpm2_pcr_read() - read a PCR value
236  * @chip:	TPM chip to use.
237  * @pcr_idx:	index of the PCR to read.
238  * @ref_buf:	buffer to store the resulting hash,
239  *
240  * 0 is returned when the operation is successful. If a negative number is
241  * returned it remarks a POSIX error code. If a positive number is returned
242  * it remarks a TPM error.
243  */
244 int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
245 {
246 	int rc;
247 	struct tpm2_cmd cmd;
248 	u8 *buf;
249 
250 	if (pcr_idx >= TPM2_PLATFORM_PCR)
251 		return -EINVAL;
252 
253 	cmd.header.in = tpm2_pcrread_header;
254 	cmd.params.pcrread_in.pcr_selects_cnt = cpu_to_be32(1);
255 	cmd.params.pcrread_in.hash_alg = cpu_to_be16(TPM2_ALG_SHA1);
256 	cmd.params.pcrread_in.pcr_select_size = TPM2_PCR_SELECT_MIN;
257 
258 	memset(cmd.params.pcrread_in.pcr_select, 0,
259 	       sizeof(cmd.params.pcrread_in.pcr_select));
260 	cmd.params.pcrread_in.pcr_select[pcr_idx >> 3] = 1 << (pcr_idx & 0x7);
261 
262 	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd),
263 			      "attempting to read a pcr value");
264 	if (rc == 0) {
265 		buf = cmd.params.pcrread_out.digest;
266 		memcpy(res_buf, buf, TPM_DIGEST_SIZE);
267 	}
268 
269 	return rc;
270 }
271 
272 #define TPM2_GET_PCREXTEND_IN_SIZE \
273 	(sizeof(struct tpm_input_header) + \
274 	 sizeof(struct tpm2_pcr_extend_in))
275 
276 static const struct tpm_input_header tpm2_pcrextend_header = {
277 	.tag = cpu_to_be16(TPM2_ST_SESSIONS),
278 	.length = cpu_to_be32(TPM2_GET_PCREXTEND_IN_SIZE),
279 	.ordinal = cpu_to_be32(TPM2_CC_PCR_EXTEND)
280 };
281 
282 /**
283  * tpm2_pcr_extend() - extend a PCR value
284  * @chip:	TPM chip to use.
285  * @pcr_idx:	index of the PCR.
286  * @hash:	hash value to use for the extend operation.
287  *
288  * 0 is returned when the operation is successful. If a negative number is
289  * returned it remarks a POSIX error code. If a positive number is returned
290  * it remarks a TPM error.
291  */
292 int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash)
293 {
294 	struct tpm2_cmd cmd;
295 	int rc;
296 
297 	cmd.header.in = tpm2_pcrextend_header;
298 	cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
299 	cmd.params.pcrextend_in.auth_area_size =
300 		cpu_to_be32(sizeof(struct tpm2_null_auth_area));
301 	cmd.params.pcrextend_in.auth_area.handle =
302 		cpu_to_be32(TPM2_RS_PW);
303 	cmd.params.pcrextend_in.auth_area.nonce_size = 0;
304 	cmd.params.pcrextend_in.auth_area.attributes = 0;
305 	cmd.params.pcrextend_in.auth_area.auth_size = 0;
306 	cmd.params.pcrextend_in.digest_cnt = cpu_to_be32(1);
307 	cmd.params.pcrextend_in.hash_alg = cpu_to_be16(TPM2_ALG_SHA1);
308 	memcpy(cmd.params.pcrextend_in.digest, hash, TPM_DIGEST_SIZE);
309 
310 	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd),
311 			      "attempting extend a PCR value");
312 
313 	return rc;
314 }
315 
316 #define TPM2_GETRANDOM_IN_SIZE \
317 	(sizeof(struct tpm_input_header) + \
318 	 sizeof(struct tpm2_get_random_in))
319 
320 static const struct tpm_input_header tpm2_getrandom_header = {
321 	.tag = cpu_to_be16(TPM2_ST_NO_SESSIONS),
322 	.length = cpu_to_be32(TPM2_GETRANDOM_IN_SIZE),
323 	.ordinal = cpu_to_be32(TPM2_CC_GET_RANDOM)
324 };
325 
326 /**
327  * tpm2_get_random() - get random bytes from the TPM RNG
328  * @chip: TPM chip to use
329  * @out: destination buffer for the random bytes
330  * @max: the max number of bytes to write to @out
331  *
332  * 0 is returned when the operation is successful. If a negative number is
333  * returned it remarks a POSIX error code. If a positive number is returned
334  * it remarks a TPM error.
335  */
336 int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max)
337 {
338 	struct tpm2_cmd cmd;
339 	u32 recd;
340 	u32 num_bytes;
341 	int err;
342 	int total = 0;
343 	int retries = 5;
344 	u8 *dest = out;
345 
346 	num_bytes = min_t(u32, max, sizeof(cmd.params.getrandom_out.buffer));
347 
348 	if (!out || !num_bytes ||
349 	    max > sizeof(cmd.params.getrandom_out.buffer))
350 		return -EINVAL;
351 
352 	do {
353 		cmd.header.in = tpm2_getrandom_header;
354 		cmd.params.getrandom_in.size = cpu_to_be16(num_bytes);
355 
356 		err = tpm_transmit_cmd(chip, &cmd, sizeof(cmd),
357 				       "attempting get random");
358 		if (err)
359 			break;
360 
361 		recd = min_t(u32, be16_to_cpu(cmd.params.getrandom_out.size),
362 			     num_bytes);
363 		memcpy(dest, cmd.params.getrandom_out.buffer, recd);
364 
365 		dest += recd;
366 		total += recd;
367 		num_bytes -= recd;
368 	} while (retries-- && total < max);
369 
370 	return total ? total : -EIO;
371 }
372 
373 #define TPM2_GET_TPM_PT_IN_SIZE \
374 	(sizeof(struct tpm_input_header) + \
375 	 sizeof(struct tpm2_get_tpm_pt_in))
376 
377 static const struct tpm_input_header tpm2_get_tpm_pt_header = {
378 	.tag = cpu_to_be16(TPM2_ST_NO_SESSIONS),
379 	.length = cpu_to_be32(TPM2_GET_TPM_PT_IN_SIZE),
380 	.ordinal = cpu_to_be32(TPM2_CC_GET_CAPABILITY)
381 };
382 
383 /**
384  * tpm2_get_tpm_pt() - get value of a TPM_CAP_TPM_PROPERTIES type property
385  * @chip:		TPM chip to use.
386  * @property_id:	property ID.
387  * @value:		output variable.
388  * @desc:		passed to tpm_transmit_cmd()
389  *
390  * 0 is returned when the operation is successful. If a negative number is
391  * returned it remarks a POSIX error code. If a positive number is returned
392  * it remarks a TPM error.
393  */
394 ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id,  u32 *value,
395 			const char *desc)
396 {
397 	struct tpm2_cmd cmd;
398 	int rc;
399 
400 	cmd.header.in = tpm2_get_tpm_pt_header;
401 	cmd.params.get_tpm_pt_in.cap_id = cpu_to_be32(TPM2_CAP_TPM_PROPERTIES);
402 	cmd.params.get_tpm_pt_in.property_id = cpu_to_be32(property_id);
403 	cmd.params.get_tpm_pt_in.property_cnt = cpu_to_be32(1);
404 
405 	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), desc);
406 	if (!rc)
407 		*value = cmd.params.get_tpm_pt_out.value;
408 
409 	return rc;
410 }
411 
412 #define TPM2_STARTUP_IN_SIZE \
413 	(sizeof(struct tpm_input_header) + \
414 	 sizeof(struct tpm2_startup_in))
415 
416 static const struct tpm_input_header tpm2_startup_header = {
417 	.tag = cpu_to_be16(TPM2_ST_NO_SESSIONS),
418 	.length = cpu_to_be32(TPM2_STARTUP_IN_SIZE),
419 	.ordinal = cpu_to_be32(TPM2_CC_STARTUP)
420 };
421 
422 /**
423  * tpm2_startup() - send startup command to the TPM chip
424  * @chip:		TPM chip to use.
425  * @startup_type	startup type. The value is either
426  *			TPM_SU_CLEAR or TPM_SU_STATE.
427  *
428  * 0 is returned when the operation is successful. If a negative number is
429  * returned it remarks a POSIX error code. If a positive number is returned
430  * it remarks a TPM error.
431  */
432 int tpm2_startup(struct tpm_chip *chip, u16 startup_type)
433 {
434 	struct tpm2_cmd cmd;
435 
436 	cmd.header.in = tpm2_startup_header;
437 
438 	cmd.params.startup_in.startup_type = cpu_to_be16(startup_type);
439 	return tpm_transmit_cmd(chip, &cmd, sizeof(cmd),
440 				"attempting to start the TPM");
441 }
442 EXPORT_SYMBOL_GPL(tpm2_startup);
443 
444 #define TPM2_SHUTDOWN_IN_SIZE \
445 	(sizeof(struct tpm_input_header) + \
446 	 sizeof(struct tpm2_startup_in))
447 
448 static const struct tpm_input_header tpm2_shutdown_header = {
449 	.tag = cpu_to_be16(TPM2_ST_NO_SESSIONS),
450 	.length = cpu_to_be32(TPM2_SHUTDOWN_IN_SIZE),
451 	.ordinal = cpu_to_be32(TPM2_CC_SHUTDOWN)
452 };
453 
454 /**
455  * tpm2_shutdown() - send shutdown command to the TPM chip
456  * @chip:		TPM chip to use.
457  * @shutdown_type	shutdown type. The value is either
458  *			TPM_SU_CLEAR or TPM_SU_STATE.
459  *
460  * 0 is returned when the operation is successful. If a negative number is
461  * returned it remarks a POSIX error code. If a positive number is returned
462  * it remarks a TPM error.
463  */
464 int tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type)
465 {
466 	struct tpm2_cmd cmd;
467 
468 	cmd.header.in = tpm2_shutdown_header;
469 
470 	cmd.params.startup_in.startup_type = cpu_to_be16(shutdown_type);
471 	return tpm_transmit_cmd(chip, &cmd, sizeof(cmd),
472 				"stopping the TPM");
473 }
474 EXPORT_SYMBOL_GPL(tpm2_shutdown);
475 
476 /*
477  * tpm2_calc_ordinal_duration() - maximum duration for a command
478  * @chip:	TPM chip to use.
479  * @ordinal:	command code number.
480  *
481  * 0 is returned when the operation is successful. If a negative number is
482  * returned it remarks a POSIX error code. If a positive number is returned
483  * it remarks a TPM error.
484  */
485 unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
486 {
487 	int index = TPM_UNDEFINED;
488 	int duration = 0;
489 
490 	if (ordinal >= TPM2_CC_FIRST && ordinal <= TPM2_CC_LAST)
491 		index = tpm2_ordinal_duration[ordinal - TPM2_CC_FIRST];
492 
493 	if (index != TPM_UNDEFINED)
494 		duration = chip->vendor.duration[index];
495 
496 	if (duration <= 0)
497 		duration = 2 * 60 * HZ;
498 
499 	return duration;
500 }
501 EXPORT_SYMBOL_GPL(tpm2_calc_ordinal_duration);
502 
503 #define TPM2_SELF_TEST_IN_SIZE \
504 	(sizeof(struct tpm_input_header) + \
505 	 sizeof(struct tpm2_self_test_in))
506 
507 static const struct tpm_input_header tpm2_selftest_header = {
508 	.tag = cpu_to_be16(TPM2_ST_NO_SESSIONS),
509 	.length = cpu_to_be32(TPM2_SELF_TEST_IN_SIZE),
510 	.ordinal = cpu_to_be32(TPM2_CC_SELF_TEST)
511 };
512 
513 /**
514  * tpm2_continue_selftest() - start a self test
515  * @chip: TPM chip to use
516  * @full: test all commands instead of testing only those that were not
517  *        previously tested.
518  *
519  * 0 is returned when the operation is successful. If a negative number is
520  * returned it remarks a POSIX error code. If a positive number is returned
521  * it remarks a TPM error.
522  */
523 static int tpm2_start_selftest(struct tpm_chip *chip, bool full)
524 {
525 	int rc;
526 	struct tpm2_cmd cmd;
527 
528 	cmd.header.in = tpm2_selftest_header;
529 	cmd.params.selftest_in.full_test = full;
530 
531 	rc = tpm_transmit_cmd(chip, &cmd, TPM2_SELF_TEST_IN_SIZE,
532 			      "continue selftest");
533 
534 	/* At least some prototype chips seem to give RC_TESTING error
535 	 * immediately. This is a workaround for that.
536 	 */
537 	if (rc == TPM2_RC_TESTING) {
538 		dev_warn(chip->pdev, "Got RC_TESTING, ignoring\n");
539 		rc = 0;
540 	}
541 
542 	return rc;
543 }
544 
545 /**
546  * tpm2_do_selftest() - run a full self test
547  * @chip: TPM chip to use
548  *
549  * During the self test TPM2 commands return with the error code RC_TESTING.
550  * Waiting is done by issuing PCR read until it executes successfully.
551  *
552  * 0 is returned when the operation is successful. If a negative number is
553  * returned it remarks a POSIX error code. If a positive number is returned
554  * it remarks a TPM error.
555  */
556 int tpm2_do_selftest(struct tpm_chip *chip)
557 {
558 	int rc;
559 	unsigned int loops;
560 	unsigned int delay_msec = 100;
561 	unsigned long duration;
562 	struct tpm2_cmd cmd;
563 	int i;
564 
565 	duration = tpm2_calc_ordinal_duration(chip, TPM2_CC_SELF_TEST);
566 
567 	loops = jiffies_to_msecs(duration) / delay_msec;
568 
569 	rc = tpm2_start_selftest(chip, true);
570 	if (rc)
571 		return rc;
572 
573 	for (i = 0; i < loops; i++) {
574 		/* Attempt to read a PCR value */
575 		cmd.header.in = tpm2_pcrread_header;
576 		cmd.params.pcrread_in.pcr_selects_cnt = cpu_to_be32(1);
577 		cmd.params.pcrread_in.hash_alg = cpu_to_be16(TPM2_ALG_SHA1);
578 		cmd.params.pcrread_in.pcr_select_size = TPM2_PCR_SELECT_MIN;
579 		cmd.params.pcrread_in.pcr_select[0] = 0x01;
580 		cmd.params.pcrread_in.pcr_select[1] = 0x00;
581 		cmd.params.pcrread_in.pcr_select[2] = 0x00;
582 
583 		rc = tpm_transmit_cmd(chip, (u8 *) &cmd, sizeof(cmd), NULL);
584 		if (rc < 0)
585 			break;
586 
587 		rc = be32_to_cpu(cmd.header.out.return_code);
588 		if (rc != TPM2_RC_TESTING)
589 			break;
590 
591 		msleep(delay_msec);
592 	}
593 
594 	return rc;
595 }
596 EXPORT_SYMBOL_GPL(tpm2_do_selftest);
597 
598 /**
599  * tpm2_gen_interrupt() - generate an interrupt
600  * @chip: TPM chip to use
601  * @quiet: surpress the error message
602  *
603  * 0 is returned when the operation is successful. If a negative number is
604  * returned it remarks a POSIX error code. If a positive number is returned
605  * it remarks a TPM error.
606  */
607 int tpm2_gen_interrupt(struct tpm_chip *chip, bool quiet)
608 {
609 	const char *desc = NULL;
610 	u32 dummy;
611 
612 	if (!quiet)
613 		desc = "attempting to generate an interrupt";
614 
615 	return tpm2_get_tpm_pt(chip, TPM2_CAP_TPM_PROPERTIES, &dummy, desc);
616 }
617 EXPORT_SYMBOL_GPL(tpm2_gen_interrupt);
618