Messages in this thread Patch in this message | | | From | Jarkko Sakkinen <> | Subject | [PATCH v1 07/12] tpm: TPM2 support for tpm_get_random(). | Date | Wed, 24 Sep 2014 12:05:57 +0300 |
| |
Implemented TPM2 support for tpm_get_random().
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> --- drivers/char/tpm/tpm-interface.c | 6 ++++++ drivers/char/tpm/tpm.h | 11 ++++++++++ drivers/char/tpm/tpm2-commands.c | 45 ++++++++++++++++++++++++++++++++++++++++ drivers/char/tpm/tpm2.h | 2 ++ 4 files changed, 64 insertions(+)
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index ed23ba3..3d4a664 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -1002,6 +1002,12 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max) if (chip == NULL) return -ENODEV; + if (chip->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); diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 4637342..b4c0d5d 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -351,6 +351,15 @@ struct tpm2_get_tpm_pt_out { __be32 value; } __packed; +struct tpm2_get_random_in { + __be16 size; +} __packed; + +struct tpm2_get_random_out { + __be16 size; + u8 buffer[TPM_MAX_RNG_DATA]; +} __packed; + typedef union { struct tpm_getcap_params_out getcap_out; struct tpm_readpubek_params_out readpubek_out; @@ -368,6 +377,8 @@ typedef union { struct tpm2_self_test_in tpm2_selftest_in; struct tpm2_get_tpm_pt_in tpm2_get_tpm_pt_in; struct tpm2_get_tpm_pt_out tpm2_get_tpm_pt_out; + struct tpm2_get_random_in tpm2_getrandom_in; + struct tpm2_get_random_out tpm2_getrandom_out; } tpm_cmd_params; struct tpm_cmd_t { diff --git a/drivers/char/tpm/tpm2-commands.c b/drivers/char/tpm/tpm2-commands.c index b69999e..90cebb2 100644 --- a/drivers/char/tpm/tpm2-commands.c +++ b/drivers/char/tpm/tpm2-commands.c @@ -349,3 +349,48 @@ int tpm2_do_selftest(struct tpm_chip *chip) return rc; } + +static struct tpm_input_header tpm2_getrandom_header = { + .tag = cpu_to_be16(TPM2_ST_NO_SESSIONS), + .length = cpu_to_be32(sizeof(struct tpm_input_header) + + sizeof(struct tpm2_get_random_in)), + .ordinal = cpu_to_be32(TPM2_CC_GET_RANDOM) +}; + +/** + * tpm2_get_random() - get random bytes from the TPM RNG + * @chip: TPM chip to use + * @out: destination buffer for the random bytes + * @max: the max number of bytes to write to @out + * + * Returns < 0 on error and the number of bytes read on success + */ +int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max) +{ + struct tpm_cmd_t tpm_cmd; + u32 recd, num_bytes = min_t(u32, max, TPM_MAX_RNG_DATA); + int err, total = 0, retries = 5; + u8 *dest = out; + + if (!out || !num_bytes || max > TPM_MAX_RNG_DATA) + return -EINVAL; + + do { + tpm_cmd.header.in = tpm2_getrandom_header; + tpm_cmd.params.tpm2_getrandom_in.size = cpu_to_be16(num_bytes); + + err = tpm_transmit_cmd(chip, &tpm_cmd, sizeof(tpm_cmd), + "attempting get random"); + if (err) + break; + + recd = be16_to_cpu(tpm_cmd.params.tpm2_getrandom_out.size); + memcpy(dest, tpm_cmd.params.tpm2_getrandom_out.buffer, recd); + + dest += recd; + total += recd; + num_bytes -= recd; + } while (retries-- && total < max); + + return total ? total : -EIO; +} diff --git a/drivers/char/tpm/tpm2.h b/drivers/char/tpm/tpm2.h index e4ed2e5..6ec84bc 100644 --- a/drivers/char/tpm/tpm2.h +++ b/drivers/char/tpm/tpm2.h @@ -38,6 +38,7 @@ enum tpm2_algorithms { enum tpm2_command_codes { TPM2_CC_SELF_TEST = 0x0143, TPM2_CC_GET_CAPABILITY = 0x017A, + TPM2_CC_GET_RANDOM = 0x017B, TPM2_CC_PCR_READ = 0x017E, TPM2_CC_PCR_EXTEND = 0x0182, }; @@ -61,5 +62,6 @@ ssize_t tpm2_get_tpm_pt(struct device *dev, u32 property_id, u32* value, int tpm2_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf); int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash); int tpm2_do_selftest(struct tpm_chip *chip); +int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max); #endif /* __DRIVERS_CHAR_TPM2_H__ */ -- 2.1.0
| |