aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/tpm/tpm-chip.c
diff options
context:
space:
mode:
authorJason Gunthorpe <jgg@ziepe.ca>2017-11-17 15:24:03 +0200
committerJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>2018-01-08 12:58:36 +0200
commit6e592a065d51d26f9d62b8b7501a5114076af8b4 (patch)
tree7297d133dcf53bf910d7e3f16e8586b1426382cf /drivers/char/tpm/tpm-chip.c
parentaad887f6641145fec2a801da2ce4ed36cf99c6a5 (diff)
tpm: Move Linux RNG connection to hwrng
The tpm-rng.c approach is completely inconsistent with how the kernel handles hotplug. Instead manage a hwrng device for each TPM. This will cause the kernel to read entropy from the TPM when it is plugged in, and allow access to the TPM rng via /dev/hwrng. Signed-off-by: Jason Gunthorpe <jgg@ziepe.ca> Tested-by: PrasannaKumar Muralidharan <prasannatsmkumar@gmail.com> Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Diffstat (limited to 'drivers/char/tpm/tpm-chip.c')
-rw-r--r--drivers/char/tpm/tpm-chip.c42
1 files changed, 37 insertions, 5 deletions
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index bab9c14e040c..0a62c19937b6 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -27,7 +27,7 @@
#include <linux/freezer.h>
#include <linux/major.h>
#include <linux/tpm_eventlog.h>
-
+#include <linux/hw_random.h>
#include "tpm.h"
DEFINE_IDR(dev_nums_idr);
@@ -392,6 +392,26 @@ static int tpm_add_legacy_sysfs(struct tpm_chip *chip)
return 0;
}
+
+static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
+{
+ struct tpm_chip *chip = container_of(rng, struct tpm_chip, hwrng);
+
+ return tpm_get_random(chip, data, max);
+}
+
+static int tpm_add_hwrng(struct tpm_chip *chip)
+{
+ if (!IS_ENABLED(CONFIG_HW_RANDOM_TPM))
+ return 0;
+
+ snprintf(chip->hwrng_name, sizeof(chip->hwrng_name),
+ "tpm-rng-%d", chip->dev_num);
+ chip->hwrng.name = chip->hwrng_name;
+ chip->hwrng.read = tpm_hwrng_read;
+ return hwrng_register(&chip->hwrng);
+}
+
/*
* tpm_chip_register() - create a character device for the TPM chip
* @chip: TPM chip to use.
@@ -424,11 +444,13 @@ int tpm_chip_register(struct tpm_chip *chip)
tpm_add_ppi(chip);
+ rc = tpm_add_hwrng(chip);
+ if (rc)
+ goto out_ppi;
+
rc = tpm_add_char_device(chip);
- if (rc) {
- tpm_bios_log_teardown(chip);
- return rc;
- }
+ if (rc)
+ goto out_hwrng;
rc = tpm_add_legacy_sysfs(chip);
if (rc) {
@@ -437,6 +459,14 @@ int tpm_chip_register(struct tpm_chip *chip)
}
return 0;
+
+out_hwrng:
+ if (IS_ENABLED(CONFIG_HW_RANDOM_TPM))
+ hwrng_unregister(&chip->hwrng);
+out_ppi:
+ tpm_bios_log_teardown(chip);
+
+ return rc;
}
EXPORT_SYMBOL_GPL(tpm_chip_register);
@@ -456,6 +486,8 @@ EXPORT_SYMBOL_GPL(tpm_chip_register);
void tpm_chip_unregister(struct tpm_chip *chip)
{
tpm_del_legacy_sysfs(chip);
+ if (IS_ENABLED(CONFIG_HW_RANDOM_TPM))
+ hwrng_unregister(&chip->hwrng);
tpm_bios_log_teardown(chip);
if (chip->flags & TPM_CHIP_FLAG_TPM2)
cdev_device_del(&chip->cdevs, &chip->devs);

Privacy Policy