tpm: TPM 2.0 baseline support
TPM 2.0 devices are separated by adding a field 'flags' to struct
tpm_chip and defining a flag TPM_CHIP_FLAG_TPM2 for tagging them.
This patch adds the following internal functions:
- tpm2_get_random()
- tpm2_get_tpm_pt()
- tpm2_pcr_extend()
- tpm2_pcr_read()
- tpm2_startup()
Additionally, the following exported functions are implemented for
implementing TPM 2.0 device drivers:
- tpm2_do_selftest()
- tpm2_calc_ordinal_durations()
- tpm2_gen_interrupt()
The existing functions that are exported for the use for existing
subsystems have been changed to check the flags field in struct
tpm_chip and use appropriate TPM 2.0 counterpart if
TPM_CHIP_FLAG_TPM2 is est.
The code for tpm2_calc_ordinal_duration() and tpm2_startup() were
originally written by Will Arthur.
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: Will Arthur <will.c.arthur@intel.com>
Reviewed-by: Jasob Gunthorpe <jason.gunthorpe@obsidianresearch.com>
Reviewed-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Reviewed-by: Peter Huewe <peterhuewe@gmx.de>
Tested-by: Peter Huewe <peterhuewe@gmx.de>
[phuewe: Fixed copy paste error * 2]
Signed-off-by: Peter Huewe <peterhuewe@gmx.de>
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index b6f6b17..20cf94d 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -360,7 +360,10 @@
if (chip->vendor.irq)
goto out_recv;
- stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal);
+ if (chip->flags & TPM_CHIP_FLAG_TPM2)
+ stop = jiffies + tpm2_calc_ordinal_duration(chip, ordinal);
+ else
+ stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal);
do {
u8 status = chip->ops->status(chip);
if ((status & chip->ops->req_complete_mask) ==
@@ -484,6 +487,7 @@
{
struct tpm_cmd_t start_cmd;
start_cmd.header.in = tpm_startup_header;
+
start_cmd.params.startup_in.startup_type = startup_type;
return tpm_transmit_cmd(chip, &start_cmd, TPM_INTERNAL_RESULT_SIZE,
"attempting to start the TPM");
@@ -680,7 +684,10 @@
chip = tpm_chip_find_get(chip_num);
if (chip == NULL)
return -ENODEV;
- rc = tpm_pcr_read_dev(chip, pcr_idx, res_buf);
+ if (chip->flags & TPM_CHIP_FLAG_TPM2)
+ rc = tpm2_pcr_read(chip, pcr_idx, res_buf);
+ else
+ rc = tpm_pcr_read_dev(chip, pcr_idx, res_buf);
tpm_chip_put(chip);
return rc;
}
@@ -714,6 +721,12 @@
if (chip == NULL)
return -ENODEV;
+ if (chip->flags & TPM_CHIP_FLAG_TPM2) {
+ rc = tpm2_pcr_extend(chip, pcr_idx, hash);
+ tpm_chip_put(chip);
+ return rc;
+ }
+
cmd.header.in = pcrextend_header;
cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE);
@@ -974,6 +987,12 @@
if (chip == NULL)
return -ENODEV;
+ if (chip->flags & TPM_CHIP_FLAG_TPM2) {
+ err = tpm2_get_random(chip, out, max);
+ tpm_chip_put(chip);
+ return err;
+ }
+
do {
tpm_cmd.header.in = tpm_getrandom_header;
tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes);