diff options
author | Jason Gunthorpe <jgg@ziepe.ca> | 2017-11-17 08:24:03 -0500 |
---|---|---|
committer | Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> | 2018-01-08 05:58:36 -0500 |
commit | 6e592a065d51d26f9d62b8b7501a5114076af8b4 (patch) | |
tree | 7297d133dcf53bf910d7e3f16e8586b1426382cf | |
parent | aad887f6641145fec2a801da2ce4ed36cf99c6a5 (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/Kconfig | 13 | ||||
-rw-r--r-- | drivers/char/hw_random/Makefile | 1 | ||||
-rw-r--r-- | drivers/char/hw_random/tpm-rng.c | 50 | ||||
-rw-r--r-- | drivers/char/tpm/Kconfig | 11 | ||||
-rw-r--r-- | drivers/char/tpm/tpm-chip.c | 42 | ||||
-rw-r--r-- | drivers/char/tpm/tpm.h | 4 |
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 | ||
309 | config 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 | |||
322 | config HW_RANDOM_HISI | 309 | config 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 | |||
27 | obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o | 27 | obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o |
28 | obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o | 28 | obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o |
29 | obj-$(CONFIG_HW_RANDOM_HISI) += hisi-rng.o | 29 | obj-$(CONFIG_HW_RANDOM_HISI) += hisi-rng.o |
30 | obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o | ||
31 | obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o | 30 | obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o |
32 | obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o | 31 | obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o |
33 | obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o | 32 | obj-$(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 | |||
26 | static 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 | |||
31 | static struct hwrng tpm_rng = { | ||
32 | .name = MODULE_NAME, | ||
33 | .read = tpm_rng_read, | ||
34 | }; | ||
35 | |||
36 | static int __init rng_init(void) | ||
37 | { | ||
38 | return hwrng_register(&tpm_rng); | ||
39 | } | ||
40 | module_init(rng_init); | ||
41 | |||
42 | static void __exit rng_exit(void) | ||
43 | { | ||
44 | hwrng_unregister(&tpm_rng); | ||
45 | } | ||
46 | module_exit(rng_exit); | ||
47 | |||
48 | MODULE_LICENSE("GPL v2"); | ||
49 | MODULE_AUTHOR("Kent Yoder <key@linux.vnet.ibm.com>"); | ||
50 | MODULE_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 | ||
27 | if TCG_TPM | 27 | if TCG_TPM |
28 | 28 | ||
29 | config 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 | |||
29 | config TCG_TIS_CORE | 40 | config 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 | ||
33 | DEFINE_IDR(dev_nums_idr); | 33 | DEFINE_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 | |||
396 | static 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 | |||
403 | static 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 | |||
463 | out_hwrng: | ||
464 | if (IS_ENABLED(CONFIG_HW_RANDOM_TPM)) | ||
465 | hwrng_unregister(&chip->hwrng); | ||
466 | out_ppi: | ||
467 | tpm_bios_log_teardown(chip); | ||
468 | |||
469 | return rc; | ||
440 | } | 470 | } |
441 | EXPORT_SYMBOL_GPL(tpm_chip_register); | 471 | EXPORT_SYMBOL_GPL(tpm_chip_register); |
442 | 472 | ||
@@ -456,6 +486,8 @@ EXPORT_SYMBOL_GPL(tpm_chip_register); | |||
456 | void tpm_chip_unregister(struct tpm_chip *chip) | 486 | void 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 */ |