diff options
author | Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> | 2017-06-21 09:31:34 +0200 |
---|---|---|
committer | James Morris <james.l.morris@oracle.com> | 2017-07-07 09:49:25 +1000 |
commit | 19cbe4f680b48f950246815b891a66eeb67f7410 (patch) | |
tree | 8b1e0fc6a59db5b4e95171522fac6d7f9439defb /drivers/char/tpm/tpm-interface.c | |
parent | 5e572cab92f0bb56ca1e6e5ee4d807663a7ccbad (diff) |
tpm: consolidate the TPM startup code
Consolidated all the "manual" TPM startup code to a single function
in order to make code flows a bit cleaner and migrate to tpm_buf.
Tested-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: James Morris <james.l.morris@oracle.com>
Diffstat (limited to 'drivers/char/tpm/tpm-interface.c')
-rw-r--r-- | drivers/char/tpm/tpm-interface.c | 67 |
1 files changed, 42 insertions, 25 deletions
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index d2b4df6d9894..3123a6e44687 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -540,6 +540,47 @@ ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_space *space, } EXPORT_SYMBOL_GPL(tpm_transmit_cmd); +#define TPM_ORD_STARTUP 153 +#define TPM_ST_CLEAR 1 + +/** + * tpm_startup - turn on the TPM + * @chip: TPM chip to use + * + * Normally the firmware should start the TPM. This function is provided as a + * workaround if this does not happen. A legal case for this could be for + * example when a TPM emulator is used. + * + * Return: same as tpm_transmit_cmd() + */ +int tpm_startup(struct tpm_chip *chip) +{ + struct tpm_buf buf; + int rc; + + dev_info(&chip->dev, "starting up the TPM manually\n"); + + if (chip->flags & TPM_CHIP_FLAG_TPM2) { + rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_STARTUP); + if (rc < 0) + return rc; + + tpm_buf_append_u16(&buf, TPM2_SU_CLEAR); + } else { + rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_STARTUP); + if (rc < 0) + return rc; + + tpm_buf_append_u16(&buf, TPM_ST_CLEAR); + } + + rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, 0, 0, + "attempting to start the TPM"); + + tpm_buf_destroy(&buf); + return rc; +} + #define TPM_DIGEST_SIZE 20 #define TPM_RET_CODE_IDX 6 #define TPM_INTERNAL_RESULT_SIZE 200 @@ -586,27 +627,6 @@ ssize_t tpm_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap, } EXPORT_SYMBOL_GPL(tpm_getcap); -#define TPM_ORD_STARTUP 153 -#define TPM_ST_CLEAR cpu_to_be16(1) -#define TPM_ST_STATE cpu_to_be16(2) -#define TPM_ST_DEACTIVATED cpu_to_be16(3) -static const struct tpm_input_header tpm_startup_header = { - .tag = cpu_to_be16(TPM_TAG_RQU_COMMAND), - .length = cpu_to_be32(12), - .ordinal = cpu_to_be32(TPM_ORD_STARTUP) -}; - -static int tpm_startup(struct tpm_chip *chip, __be16 startup_type) -{ - 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, NULL, &start_cmd, - TPM_INTERNAL_RESULT_SIZE, 0, - 0, "attempting to start the TPM"); -} - int tpm_get_timeouts(struct tpm_chip *chip) { cap_t cap; @@ -636,10 +656,7 @@ int tpm_get_timeouts(struct tpm_chip *chip) rc = tpm_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, NULL, sizeof(cap.timeout)); if (rc == TPM_ERR_INVALID_POSTINIT) { - /* The TPM is not started, we are the first to talk to it. - Execute a startup command. */ - dev_info(&chip->dev, "Issuing TPM_STARTUP\n"); - if (tpm_startup(chip, TPM_ST_CLEAR)) + if (tpm_startup(chip)) return rc; rc = tpm_getcap(chip, TPM_CAP_PROP_TIS_TIMEOUT, &cap, |