diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index a5d8bcb..4c3963b 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -579,6 +579,31 @@ void tpm_continue_selftest(struct tpm_chip *chip) } EXPORT_SYMBOL_GPL(tpm_continue_selftest); +int tpm_getrandom(struct tpm_chip *chip, void *buf, size_t buflen) +{ + u8 rng_cmd[] = { + 0, 193, /* TPM_TAG_RQU_COMMAND */ + 0, 0, 0, 14, /* length */ + 0, 0, 0, 70, /* TPM_ORD_GetRandom */ + 0, 0, 0, 0, /* number of bytes to return */ + }; + size_t tmp; + + if (buflen <= sizeof(rng_cmd)) + return -ENOSPC; + + /* patch in requested/returned byte count. TODO: more than 8-bit */ + tmp = buflen - sizeof(rng_cmd); + if (tmp > 255) + tmp = 255; + rng_cmd[13] = tmp; + + memcpy(buf, rng_cmd, sizeof(rng_cmd)); + + return tpm_transmit(chip, buf, buflen); +} +EXPORT_SYMBOL_GPL(tpm_getrandom); + ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr, char *buf) { diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index e885148..bbab3c8 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -127,6 +127,7 @@ static inline void tpm_write_index(int base, int index, int value) extern void tpm_get_timeouts(struct tpm_chip *); extern void tpm_gen_interrupt(struct tpm_chip *); extern void tpm_continue_selftest(struct tpm_chip *); +extern int tpm_getrandom(struct tpm_chip *, void *, size_t); extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32); extern struct tpm_chip* tpm_register_hardware(struct device *, const struct tpm_vendor_specific *);