aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Gunthorpe <jgg@ziepe.ca>2017-11-17 08:24:03 -0500
committerJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>2018-01-08 05:58:36 -0500
commit6e592a065d51d26f9d62b8b7501a5114076af8b4 (patch)
tree7297d133dcf53bf910d7e3f16e8586b1426382cf
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>
-rw-r--r--drivers/char/hw_random/Kconfig13
-rw-r--r--drivers/char/hw_random/Makefile1
-rw-r--r--drivers/char/hw_random/tpm-rng.c50
-rw-r--r--drivers/char/tpm/Kconfig11
-rw-r--r--drivers/char/tpm/tpm-chip.c42
-rw-r--r--drivers/char/tpm/tpm.h4
6 files changed, 52 insertions, 69 deletions
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index f6e3e5abc117..88044eda0ac6 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -306,19 +306,6 @@ config HW_RANDOM_POWERNV
306 306
307 If unsure, say Y. 307 If unsure, say Y.
308 308
309config HW_RANDOM_TPM
310 tristate "TPM HW Random Number Generator support"
311 depends on TCG_TPM
312 default HW_RANDOM
313 ---help---
314 This driver provides kernel-side support for the Random Number
315 Generator in the Trusted Platform Module
316
317 To compile this driver as a module, choose M here: the
318 module will be called tpm-rng.
319
320 If unsure, say Y.
321
322config HW_RANDOM_HISI 309config HW_RANDOM_HISI
323 tristate "Hisilicon Random Number Generator support" 310 tristate "Hisilicon Random Number Generator support"
324 depends on HW_RANDOM && ARCH_HISI 311 depends on HW_RANDOM && ARCH_HISI
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index f3728d008fff..0ef05c61d9c8 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -27,7 +27,6 @@ obj-$(CONFIG_HW_RANDOM_NOMADIK) += nomadik-rng.o
27obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o 27obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o
28obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o 28obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o
29obj-$(CONFIG_HW_RANDOM_HISI) += hisi-rng.o 29obj-$(CONFIG_HW_RANDOM_HISI) += hisi-rng.o
30obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o
31obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o 30obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o
32obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o 31obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o
33obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o 32obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o
diff --git a/drivers/char/hw_random/tpm-rng.c b/drivers/char/hw_random/tpm-rng.c
deleted file mode 100644
index c5e363825af0..000000000000
--- a/drivers/char/hw_random/tpm-rng.c
+++ /dev/null
@@ -1,50 +0,0 @@
1/*
2 * Copyright (C) 2012 Kent Yoder IBM Corporation
3 *
4 * HWRNG interfaces to pull RNG data from a TPM
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/module.h>
21#include <linux/hw_random.h>
22#include <linux/tpm.h>
23
24#define MODULE_NAME "tpm-rng"
25
26static int tpm_rng_read(struct hwrng *rng, void *data, size_t max, bool wait)
27{
28 return tpm_get_random(NULL, data, max);
29}
30
31static struct hwrng tpm_rng = {
32 .name = MODULE_NAME,
33 .read = tpm_rng_read,
34};
35
36static int __init rng_init(void)
37{
38 return hwrng_register(&tpm_rng);
39}
40module_init(rng_init);
41
42static void __exit rng_exit(void)
43{
44 hwrng_unregister(&tpm_rng);
45}
46module_exit(rng_exit);
47
48MODULE_LICENSE("GPL v2");
49MODULE_AUTHOR("Kent Yoder <key@linux.vnet.ibm.com>");
50MODULE_DESCRIPTION("RNG driver for TPM devices");
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
index a30352202f1f..18c81cbe4704 100644
--- a/drivers/char/tpm/Kconfig
+++ b/drivers/char/tpm/Kconfig
@@ -26,6 +26,17 @@ menuconfig TCG_TPM
26 26
27if TCG_TPM 27if TCG_TPM
28 28
29config HW_RANDOM_TPM
30 bool "TPM HW Random Number Generator support"
31 depends on TCG_TPM && HW_RANDOM && !(TCG_TPM=y && HW_RANDOM=m)
32 default y
33 ---help---
34 This setting exposes the TPM's Random Number Generator as a hwrng
35 device. This allows the kernel to collect randomness from the TPM at
36 boot, and provides the TPM randomines in /dev/hwrng.
37
38 If unsure, say Y.
39
29config TCG_TIS_CORE 40config TCG_TIS_CORE
30 tristate 41 tristate
31 ---help--- 42 ---help---
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 @@
27#include <linux/freezer.h> 27#include <linux/freezer.h>
28#include <linux/major.h> 28#include <linux/major.h>
29#include <linux/tpm_eventlog.h> 29#include <linux/tpm_eventlog.h>
30 30#include <linux/hw_random.h>
31#include "tpm.h" 31#include "tpm.h"
32 32
33DEFINE_IDR(dev_nums_idr); 33DEFINE_IDR(dev_nums_idr);
@@ -392,6 +392,26 @@ static int tpm_add_legacy_sysfs(struct tpm_chip *chip)
392 392
393 return 0; 393 return 0;
394} 394}
395
396static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
397{
398 struct tpm_chip *chip = container_of(rng, struct tpm_chip, hwrng);
399
400 return tpm_get_random(chip, data, max);
401}
402
403static int tpm_add_hwrng(struct tpm_chip *chip)
404{
405 if (!IS_ENABLED(CONFIG_HW_RANDOM_TPM))
406 return 0;
407
408 snprintf(chip->hwrng_name, sizeof(chip->hwrng_name),
409 "tpm-rng-%d", chip->dev_num);
410 chip->hwrng.name = chip->hwrng_name;
411 chip->hwrng.read = tpm_hwrng_read;
412 return hwrng_register(&chip->hwrng);
413}
414
395/* 415/*
396 * tpm_chip_register() - create a character device for the TPM chip 416 * tpm_chip_register() - create a character device for the TPM chip
397 * @chip: TPM chip to use. 417 * @chip: TPM chip to use.
@@ -424,11 +444,13 @@ int tpm_chip_register(struct tpm_chip *chip)
424 444
425 tpm_add_ppi(chip); 445 tpm_add_ppi(chip);
426 446
447 rc = tpm_add_hwrng(chip);
448 if (rc)
449 goto out_ppi;
450
427 rc = tpm_add_char_device(chip); 451 rc = tpm_add_char_device(chip);
428 if (rc) { 452 if (rc)
429 tpm_bios_log_teardown(chip); 453 goto out_hwrng;
430 return rc;
431 }
432 454
433 rc = tpm_add_legacy_sysfs(chip); 455 rc = tpm_add_legacy_sysfs(chip);
434 if (rc) { 456 if (rc) {
@@ -437,6 +459,14 @@ int tpm_chip_register(struct tpm_chip *chip)
437 } 459 }
438 460
439 return 0; 461 return 0;
462
463out_hwrng:
464 if (IS_ENABLED(CONFIG_HW_RANDOM_TPM))
465 hwrng_unregister(&chip->hwrng);
466out_ppi:
467 tpm_bios_log_teardown(chip);
468
469 return rc;
440} 470}
441EXPORT_SYMBOL_GPL(tpm_chip_register); 471EXPORT_SYMBOL_GPL(tpm_chip_register);
442 472
@@ -456,6 +486,8 @@ EXPORT_SYMBOL_GPL(tpm_chip_register);
456void tpm_chip_unregister(struct tpm_chip *chip) 486void tpm_chip_unregister(struct tpm_chip *chip)
457{ 487{
458 tpm_del_legacy_sysfs(chip); 488 tpm_del_legacy_sysfs(chip);
489 if (IS_ENABLED(CONFIG_HW_RANDOM_TPM))
490 hwrng_unregister(&chip->hwrng);
459 tpm_bios_log_teardown(chip); 491 tpm_bios_log_teardown(chip);
460 if (chip->flags & TPM_CHIP_FLAG_TPM2) 492 if (chip->flags & TPM_CHIP_FLAG_TPM2)
461 cdev_device_del(&chip->cdevs, &chip->devs); 493 cdev_device_del(&chip->cdevs, &chip->devs);
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 6c189174c0d3..605c0be2b8dc 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -26,6 +26,7 @@
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/fs.h> 28#include <linux/fs.h>
29#include <linux/hw_random.h>
29#include <linux/mutex.h> 30#include <linux/mutex.h>
30#include <linux/sched.h> 31#include <linux/sched.h>
31#include <linux/platform_device.h> 32#include <linux/platform_device.h>
@@ -211,6 +212,9 @@ struct tpm_chip {
211 int dev_num; /* /dev/tpm# */ 212 int dev_num; /* /dev/tpm# */
212 unsigned long is_open; /* only one allowed */ 213 unsigned long is_open; /* only one allowed */
213 214
215 char hwrng_name[64];
216 struct hwrng hwrng;
217
214 struct mutex tpm_mutex; /* tpm is processing */ 218 struct mutex tpm_mutex; /* tpm is processing */
215 219
216 unsigned long timeout_a; /* jiffies */ 220 unsigned long timeout_a; /* jiffies */