Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / char / tpm / tpm2-cmd.c
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 void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type)
461 {
462         struct tpm2_cmd cmd;
463         int rc;
464
465         cmd.header.in = tpm2_shutdown_header;
466         cmd.params.startup_in.startup_type = cpu_to_be16(shutdown_type);
467
468         rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), "stopping the TPM");
469
470         /* In places where shutdown command is sent there's no much we can do
471          * except print the error code on a system failure.
472          */
473         if (rc < 0)
474                 dev_warn(chip->pdev, "transmit returned %d while stopping the TPM",
475                          rc);
476 }
477 EXPORT_SYMBOL_GPL(tpm2_shutdown);
478
479 /*
480  * tpm2_calc_ordinal_duration() - maximum duration for a command
481  * @chip:       TPM chip to use.
482  * @ordinal:    command code number.
483  *
484  * 0 is returned when the operation is successful. If a negative number is
485  * returned it remarks a POSIX error code. If a positive number is returned
486  * it remarks a TPM error.
487  */
488 unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal)
489 {
490         int index = TPM_UNDEFINED;
491         int duration = 0;
492
493         if (ordinal >= TPM2_CC_FIRST && ordinal <= TPM2_CC_LAST)
494                 index = tpm2_ordinal_duration[ordinal - TPM2_CC_FIRST];
495
496         if (index != TPM_UNDEFINED)
497                 duration = chip->vendor.duration[index];
498
499         if (duration <= 0)
500                 duration = 2 * 60 * HZ;
501
502         return duration;
503 }
504 EXPORT_SYMBOL_GPL(tpm2_calc_ordinal_duration);
505
506 #define TPM2_SELF_TEST_IN_SIZE \
507         (sizeof(struct tpm_input_header) + \
508          sizeof(struct tpm2_self_test_in))
509
510 static const struct tpm_input_header tpm2_selftest_header = {
511         .tag = cpu_to_be16(TPM2_ST_NO_SESSIONS),
512         .length = cpu_to_be32(TPM2_SELF_TEST_IN_SIZE),
513         .ordinal = cpu_to_be32(TPM2_CC_SELF_TEST)
514 };
515
516 /**
517  * tpm2_continue_selftest() - start a self test
518  * @chip: TPM chip to use
519  * @full: test all commands instead of testing only those that were not
520  *        previously tested.
521  *
522  * 0 is returned when the operation is successful. If a negative number is
523  * returned it remarks a POSIX error code. If a positive number is returned
524  * it remarks a TPM error.
525  */
526 static int tpm2_start_selftest(struct tpm_chip *chip, bool full)
527 {
528         int rc;
529         struct tpm2_cmd cmd;
530
531         cmd.header.in = tpm2_selftest_header;
532         cmd.params.selftest_in.full_test = full;
533
534         rc = tpm_transmit_cmd(chip, &cmd, TPM2_SELF_TEST_IN_SIZE,
535                               "continue selftest");
536
537         /* At least some prototype chips seem to give RC_TESTING error
538          * immediately. This is a workaround for that.
539          */
540         if (rc == TPM2_RC_TESTING) {
541                 dev_warn(chip->pdev, "Got RC_TESTING, ignoring\n");
542                 rc = 0;
543         }
544
545         return rc;
546 }
547
548 /**
549  * tpm2_do_selftest() - run a full self test
550  * @chip: TPM chip to use
551  *
552  * During the self test TPM2 commands return with the error code RC_TESTING.
553  * Waiting is done by issuing PCR read until it executes successfully.
554  *
555  * 0 is returned when the operation is successful. If a negative number is
556  * returned it remarks a POSIX error code. If a positive number is returned
557  * it remarks a TPM error.
558  */
559 int tpm2_do_selftest(struct tpm_chip *chip)
560 {
561         int rc;
562         unsigned int loops;
563         unsigned int delay_msec = 100;
564         unsigned long duration;
565         struct tpm2_cmd cmd;
566         int i;
567
568         duration = tpm2_calc_ordinal_duration(chip, TPM2_CC_SELF_TEST);
569
570         loops = jiffies_to_msecs(duration) / delay_msec;
571
572         rc = tpm2_start_selftest(chip, true);
573         if (rc)
574                 return rc;
575
576         for (i = 0; i < loops; i++) {
577                 /* Attempt to read a PCR value */
578                 cmd.header.in = tpm2_pcrread_header;
579                 cmd.params.pcrread_in.pcr_selects_cnt = cpu_to_be32(1);
580                 cmd.params.pcrread_in.hash_alg = cpu_to_be16(TPM2_ALG_SHA1);
581                 cmd.params.pcrread_in.pcr_select_size = TPM2_PCR_SELECT_MIN;
582                 cmd.params.pcrread_in.pcr_select[0] = 0x01;
583                 cmd.params.pcrread_in.pcr_select[1] = 0x00;
584                 cmd.params.pcrread_in.pcr_select[2] = 0x00;
585
586                 rc = tpm_transmit_cmd(chip, (u8 *) &cmd, sizeof(cmd), NULL);
587                 if (rc < 0)
588                         break;
589
590                 rc = be32_to_cpu(cmd.header.out.return_code);
591                 if (rc != TPM2_RC_TESTING)
592                         break;
593
594                 msleep(delay_msec);
595         }
596
597         return rc;
598 }
599 EXPORT_SYMBOL_GPL(tpm2_do_selftest);
600
601 /**
602  * tpm2_gen_interrupt() - generate an interrupt
603  * @chip: TPM chip to use
604  *
605  * 0 is returned when the operation is successful. If a negative number is
606  * returned it remarks a POSIX error code. If a positive number is returned
607  * it remarks a TPM error.
608  */
609 int tpm2_gen_interrupt(struct tpm_chip *chip)
610 {
611         u32 dummy;
612
613         return tpm2_get_tpm_pt(chip, 0x100, &dummy,
614                                "attempting to generate an interrupt");
615 }
616 EXPORT_SYMBOL_GPL(tpm2_gen_interrupt);
617
618 /**
619  * tpm2_probe() - probe TPM 2.0
620  * @chip: TPM chip to use
621  *
622  * Send idempotent TPM 2.0 command and see whether TPM 2.0 chip replied based on
623  * the reply tag.
624  */
625 int tpm2_probe(struct tpm_chip *chip)
626 {
627         struct tpm2_cmd cmd;
628         int rc;
629
630         cmd.header.in = tpm2_get_tpm_pt_header;
631         cmd.params.get_tpm_pt_in.cap_id = cpu_to_be32(TPM2_CAP_TPM_PROPERTIES);
632         cmd.params.get_tpm_pt_in.property_id = cpu_to_be32(0x100);
633         cmd.params.get_tpm_pt_in.property_cnt = cpu_to_be32(1);
634
635         rc = tpm_transmit(chip, (const char *) &cmd, sizeof(cmd));
636         if (rc <  0)
637                 return rc;
638         else if (rc < TPM_HEADER_SIZE)
639                 return -EFAULT;
640
641         if (be16_to_cpu(cmd.header.out.tag) == TPM2_ST_NO_SESSIONS)
642                 chip->flags |= TPM_CHIP_FLAG_TPM2;
643
644         return 0;
645 }
646 EXPORT_SYMBOL_GPL(tpm2_probe);