diff options
33 files changed, 789 insertions, 443 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 82ad0eabce4f..40413abcc624 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -13809,9 +13809,10 @@ F: drivers/platform/x86/toshiba-wmi.c | |||
| 13809 | TPM DEVICE DRIVER | 13809 | TPM DEVICE DRIVER |
| 13810 | M: Peter Huewe <peterhuewe@gmx.de> | 13810 | M: Peter Huewe <peterhuewe@gmx.de> |
| 13811 | M: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> | 13811 | M: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> |
| 13812 | R: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> | 13812 | R: Jason Gunthorpe <jgg@ziepe.ca> |
| 13813 | L: linux-integrity@vger.kernel.org | 13813 | L: linux-integrity@vger.kernel.org |
| 13814 | Q: https://patchwork.kernel.org/project/linux-integrity/list/ | 13814 | Q: https://patchwork.kernel.org/project/linux-integrity/list/ |
| 13815 | W: https://kernsec.org/wiki/index.php/Linux_Kernel_Integrity | ||
| 13815 | T: git git://git.infradead.org/users/jjs/linux-tpmdd.git | 13816 | T: git git://git.infradead.org/users/jjs/linux-tpmdd.git |
| 13816 | S: Maintained | 13817 | S: Maintained |
| 13817 | F: drivers/char/tpm/ | 13818 | F: drivers/char/tpm/ |
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index e56dbc67e837..353e20c3f114 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c | |||
| @@ -999,6 +999,7 @@ struct boot_params *efi_main(struct efi_config *c, | |||
| 999 | 999 | ||
| 1000 | /* Ask the firmware to clear memory on unclean shutdown */ | 1000 | /* Ask the firmware to clear memory on unclean shutdown */ |
| 1001 | efi_enable_reset_attack_mitigation(sys_table); | 1001 | efi_enable_reset_attack_mitigation(sys_table); |
| 1002 | efi_retrieve_tpm2_eventlog(sys_table); | ||
| 1002 | 1003 | ||
| 1003 | setup_graphics(boot_params); | 1004 | setup_graphics(boot_params); |
| 1004 | 1005 | ||
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 d6d448266f07..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(TPM_ANY_NUM, 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/Makefile b/drivers/char/tpm/Makefile index 34b4bcf46f43..acd758381c58 100644 --- a/drivers/char/tpm/Makefile +++ b/drivers/char/tpm/Makefile | |||
| @@ -6,8 +6,9 @@ obj-$(CONFIG_TCG_TPM) += tpm.o | |||
| 6 | tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o tpm-chip.o tpm2-cmd.o \ | 6 | tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o tpm-chip.o tpm2-cmd.o \ |
| 7 | tpm-dev-common.o tpmrm-dev.o tpm1_eventlog.o tpm2_eventlog.o \ | 7 | tpm-dev-common.o tpmrm-dev.o tpm1_eventlog.o tpm2_eventlog.o \ |
| 8 | tpm2-space.o | 8 | tpm2-space.o |
| 9 | tpm-$(CONFIG_ACPI) += tpm_ppi.o tpm_acpi.o | 9 | tpm-$(CONFIG_ACPI) += tpm_ppi.o tpm_eventlog_acpi.o |
| 10 | tpm-$(CONFIG_OF) += tpm_of.o | 10 | tpm-$(CONFIG_EFI) += tpm_eventlog_efi.o |
| 11 | tpm-$(CONFIG_OF) += tpm_eventlog_of.o | ||
| 11 | obj-$(CONFIG_TCG_TIS_CORE) += tpm_tis_core.o | 12 | obj-$(CONFIG_TCG_TIS_CORE) += tpm_tis_core.o |
| 12 | obj-$(CONFIG_TCG_TIS) += tpm_tis.o | 13 | obj-$(CONFIG_TCG_TIS) += tpm_tis.o |
| 13 | obj-$(CONFIG_TCG_TIS_SPI) += tpm_tis_spi.o | 14 | obj-$(CONFIG_TCG_TIS_SPI) += tpm_tis_spi.o |
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c index 0eca20c5a80c..0a62c19937b6 100644 --- a/drivers/char/tpm/tpm-chip.c +++ b/drivers/char/tpm/tpm-chip.c | |||
| @@ -26,8 +26,9 @@ | |||
| 26 | #include <linux/spinlock.h> | 26 | #include <linux/spinlock.h> |
| 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> | ||
| 30 | #include <linux/hw_random.h> | ||
| 29 | #include "tpm.h" | 31 | #include "tpm.h" |
| 30 | #include "tpm_eventlog.h" | ||
| 31 | 32 | ||
| 32 | DEFINE_IDR(dev_nums_idr); | 33 | DEFINE_IDR(dev_nums_idr); |
| 33 | static DEFINE_MUTEX(idr_lock); | 34 | static DEFINE_MUTEX(idr_lock); |
| @@ -80,21 +81,26 @@ void tpm_put_ops(struct tpm_chip *chip) | |||
| 80 | EXPORT_SYMBOL_GPL(tpm_put_ops); | 81 | EXPORT_SYMBOL_GPL(tpm_put_ops); |
| 81 | 82 | ||
| 82 | /** | 83 | /** |
| 83 | * tpm_chip_find_get() - return tpm_chip for a given chip number | 84 | * tpm_chip_find_get() - find and reserve a TPM chip |
| 84 | * @chip_num: id to find | 85 | * @chip: a &struct tpm_chip instance, %NULL for the default chip |
| 85 | * | 86 | * |
| 86 | * The return'd chip has been tpm_try_get_ops'd and must be released via | 87 | * Finds a TPM chip and reserves its class device and operations. The chip must |
| 87 | * tpm_put_ops | 88 | * be released with tpm_chip_put_ops() after use. |
| 89 | * | ||
| 90 | * Return: | ||
| 91 | * A reserved &struct tpm_chip instance. | ||
| 92 | * %NULL if a chip is not found. | ||
| 93 | * %NULL if the chip is not available. | ||
| 88 | */ | 94 | */ |
| 89 | struct tpm_chip *tpm_chip_find_get(int chip_num) | 95 | struct tpm_chip *tpm_chip_find_get(struct tpm_chip *chip) |
| 90 | { | 96 | { |
| 91 | struct tpm_chip *chip, *res = NULL; | 97 | struct tpm_chip *res = NULL; |
| 98 | int chip_num = 0; | ||
| 92 | int chip_prev; | 99 | int chip_prev; |
| 93 | 100 | ||
| 94 | mutex_lock(&idr_lock); | 101 | mutex_lock(&idr_lock); |
| 95 | 102 | ||
| 96 | if (chip_num == TPM_ANY_NUM) { | 103 | if (!chip) { |
| 97 | chip_num = 0; | ||
| 98 | do { | 104 | do { |
| 99 | chip_prev = chip_num; | 105 | chip_prev = chip_num; |
| 100 | chip = idr_get_next(&dev_nums_idr, &chip_num); | 106 | chip = idr_get_next(&dev_nums_idr, &chip_num); |
| @@ -104,8 +110,7 @@ struct tpm_chip *tpm_chip_find_get(int chip_num) | |||
| 104 | } | 110 | } |
| 105 | } while (chip_prev != chip_num); | 111 | } while (chip_prev != chip_num); |
| 106 | } else { | 112 | } else { |
| 107 | chip = idr_find(&dev_nums_idr, chip_num); | 113 | if (!tpm_try_get_ops(chip)) |
| 108 | if (chip && !tpm_try_get_ops(chip)) | ||
| 109 | res = chip; | 114 | res = chip; |
| 110 | } | 115 | } |
| 111 | 116 | ||
| @@ -387,6 +392,26 @@ static int tpm_add_legacy_sysfs(struct tpm_chip *chip) | |||
| 387 | 392 | ||
| 388 | return 0; | 393 | return 0; |
| 389 | } | 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 | |||
| 390 | /* | 415 | /* |
| 391 | * tpm_chip_register() - create a character device for the TPM chip | 416 | * tpm_chip_register() - create a character device for the TPM chip |
| 392 | * @chip: TPM chip to use. | 417 | * @chip: TPM chip to use. |
| @@ -419,11 +444,13 @@ int tpm_chip_register(struct tpm_chip *chip) | |||
| 419 | 444 | ||
| 420 | tpm_add_ppi(chip); | 445 | tpm_add_ppi(chip); |
| 421 | 446 | ||
| 447 | rc = tpm_add_hwrng(chip); | ||
| 448 | if (rc) | ||
| 449 | goto out_ppi; | ||
| 450 | |||
| 422 | rc = tpm_add_char_device(chip); | 451 | rc = tpm_add_char_device(chip); |
| 423 | if (rc) { | 452 | if (rc) |
| 424 | tpm_bios_log_teardown(chip); | 453 | goto out_hwrng; |
| 425 | return rc; | ||
| 426 | } | ||
| 427 | 454 | ||
| 428 | rc = tpm_add_legacy_sysfs(chip); | 455 | rc = tpm_add_legacy_sysfs(chip); |
| 429 | if (rc) { | 456 | if (rc) { |
| @@ -432,6 +459,14 @@ int tpm_chip_register(struct tpm_chip *chip) | |||
| 432 | } | 459 | } |
| 433 | 460 | ||
| 434 | 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; | ||
| 435 | } | 470 | } |
| 436 | EXPORT_SYMBOL_GPL(tpm_chip_register); | 471 | EXPORT_SYMBOL_GPL(tpm_chip_register); |
| 437 | 472 | ||
| @@ -451,6 +486,8 @@ EXPORT_SYMBOL_GPL(tpm_chip_register); | |||
| 451 | void tpm_chip_unregister(struct tpm_chip *chip) | 486 | void tpm_chip_unregister(struct tpm_chip *chip) |
| 452 | { | 487 | { |
| 453 | tpm_del_legacy_sysfs(chip); | 488 | tpm_del_legacy_sysfs(chip); |
| 489 | if (IS_ENABLED(CONFIG_HW_RANDOM_TPM)) | ||
| 490 | hwrng_unregister(&chip->hwrng); | ||
| 454 | tpm_bios_log_teardown(chip); | 491 | tpm_bios_log_teardown(chip); |
| 455 | if (chip->flags & TPM_CHIP_FLAG_TPM2) | 492 | if (chip->flags & TPM_CHIP_FLAG_TPM2) |
| 456 | cdev_device_del(&chip->cdevs, &chip->devs); | 493 | cdev_device_del(&chip->cdevs, &chip->devs); |
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index 1d6729be4cd6..76df4fbcf089 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c | |||
| @@ -30,9 +30,9 @@ | |||
| 30 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
| 31 | #include <linux/freezer.h> | 31 | #include <linux/freezer.h> |
| 32 | #include <linux/pm_runtime.h> | 32 | #include <linux/pm_runtime.h> |
| 33 | #include <linux/tpm_eventlog.h> | ||
| 33 | 34 | ||
| 34 | #include "tpm.h" | 35 | #include "tpm.h" |
| 35 | #include "tpm_eventlog.h" | ||
| 36 | 36 | ||
| 37 | #define TPM_MAX_ORDINAL 243 | 37 | #define TPM_MAX_ORDINAL 243 |
| 38 | #define TSC_MAX_ORDINAL 12 | 38 | #define TSC_MAX_ORDINAL 12 |
| @@ -328,7 +328,7 @@ unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, | |||
| 328 | } | 328 | } |
| 329 | EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration); | 329 | EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration); |
| 330 | 330 | ||
| 331 | static bool tpm_validate_command(struct tpm_chip *chip, | 331 | static int tpm_validate_command(struct tpm_chip *chip, |
| 332 | struct tpm_space *space, | 332 | struct tpm_space *space, |
| 333 | const u8 *cmd, | 333 | const u8 *cmd, |
| 334 | size_t len) | 334 | size_t len) |
| @@ -340,10 +340,10 @@ static bool tpm_validate_command(struct tpm_chip *chip, | |||
| 340 | unsigned int nr_handles; | 340 | unsigned int nr_handles; |
| 341 | 341 | ||
| 342 | if (len < TPM_HEADER_SIZE) | 342 | if (len < TPM_HEADER_SIZE) |
| 343 | return false; | 343 | return -EINVAL; |
| 344 | 344 | ||
| 345 | if (!space) | 345 | if (!space) |
| 346 | return true; | 346 | return 0; |
| 347 | 347 | ||
| 348 | if (chip->flags & TPM_CHIP_FLAG_TPM2 && chip->nr_commands) { | 348 | if (chip->flags & TPM_CHIP_FLAG_TPM2 && chip->nr_commands) { |
| 349 | cc = be32_to_cpu(header->ordinal); | 349 | cc = be32_to_cpu(header->ordinal); |
| @@ -352,7 +352,7 @@ static bool tpm_validate_command(struct tpm_chip *chip, | |||
| 352 | if (i < 0) { | 352 | if (i < 0) { |
| 353 | dev_dbg(&chip->dev, "0x%04X is an invalid command\n", | 353 | dev_dbg(&chip->dev, "0x%04X is an invalid command\n", |
| 354 | cc); | 354 | cc); |
| 355 | return false; | 355 | return -EOPNOTSUPP; |
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | attrs = chip->cc_attrs_tbl[i]; | 358 | attrs = chip->cc_attrs_tbl[i]; |
| @@ -362,11 +362,11 @@ static bool tpm_validate_command(struct tpm_chip *chip, | |||
| 362 | goto err_len; | 362 | goto err_len; |
| 363 | } | 363 | } |
| 364 | 364 | ||
| 365 | return true; | 365 | return 0; |
| 366 | err_len: | 366 | err_len: |
| 367 | dev_dbg(&chip->dev, | 367 | dev_dbg(&chip->dev, |
| 368 | "%s: insufficient command length %zu", __func__, len); | 368 | "%s: insufficient command length %zu", __func__, len); |
| 369 | return false; | 369 | return -EINVAL; |
| 370 | } | 370 | } |
| 371 | 371 | ||
| 372 | /** | 372 | /** |
| @@ -391,8 +391,20 @@ ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, | |||
| 391 | unsigned long stop; | 391 | unsigned long stop; |
| 392 | bool need_locality; | 392 | bool need_locality; |
| 393 | 393 | ||
| 394 | if (!tpm_validate_command(chip, space, buf, bufsiz)) | 394 | rc = tpm_validate_command(chip, space, buf, bufsiz); |
| 395 | return -EINVAL; | 395 | if (rc == -EINVAL) |
| 396 | return rc; | ||
| 397 | /* | ||
| 398 | * If the command is not implemented by the TPM, synthesize a | ||
| 399 | * response with a TPM2_RC_COMMAND_CODE return for user-space. | ||
| 400 | */ | ||
| 401 | if (rc == -EOPNOTSUPP) { | ||
| 402 | header->length = cpu_to_be32(sizeof(*header)); | ||
| 403 | header->tag = cpu_to_be16(TPM2_ST_NO_SESSIONS); | ||
| 404 | header->return_code = cpu_to_be32(TPM2_RC_COMMAND_CODE | | ||
| 405 | TSS2_RESMGR_TPM_RC_LAYER); | ||
| 406 | return bufsiz; | ||
| 407 | } | ||
| 396 | 408 | ||
| 397 | if (bufsiz > TPM_BUFSIZE) | 409 | if (bufsiz > TPM_BUFSIZE) |
| 398 | bufsiz = TPM_BUFSIZE; | 410 | bufsiz = TPM_BUFSIZE; |
| @@ -413,6 +425,9 @@ ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, | |||
| 413 | if (chip->dev.parent) | 425 | if (chip->dev.parent) |
| 414 | pm_runtime_get_sync(chip->dev.parent); | 426 | pm_runtime_get_sync(chip->dev.parent); |
| 415 | 427 | ||
| 428 | if (chip->ops->clk_enable != NULL) | ||
| 429 | chip->ops->clk_enable(chip, true); | ||
| 430 | |||
| 416 | /* Store the decision as chip->locality will be changed. */ | 431 | /* Store the decision as chip->locality will be changed. */ |
| 417 | need_locality = chip->locality == -1; | 432 | need_locality = chip->locality == -1; |
| 418 | 433 | ||
| @@ -489,6 +504,9 @@ out: | |||
| 489 | chip->locality = -1; | 504 | chip->locality = -1; |
| 490 | } | 505 | } |
| 491 | out_no_locality: | 506 | out_no_locality: |
| 507 | if (chip->ops->clk_enable != NULL) | ||
| 508 | chip->ops->clk_enable(chip, false); | ||
| 509 | |||
| 492 | if (chip->dev.parent) | 510 | if (chip->dev.parent) |
| 493 | pm_runtime_put_sync(chip->dev.parent); | 511 | pm_runtime_put_sync(chip->dev.parent); |
| 494 | 512 | ||
| @@ -809,19 +827,20 @@ int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf) | |||
| 809 | } | 827 | } |
| 810 | 828 | ||
| 811 | /** | 829 | /** |
| 812 | * tpm_is_tpm2 - is the chip a TPM2 chip? | 830 | * tpm_is_tpm2 - do we a have a TPM2 chip? |
| 813 | * @chip_num: tpm idx # or ANY | 831 | * @chip: a &struct tpm_chip instance, %NULL for the default chip |
| 814 | * | 832 | * |
| 815 | * Returns < 0 on error, and 1 or 0 on success depending whether the chip | 833 | * Return: |
| 816 | * is a TPM2 chip. | 834 | * 1 if we have a TPM2 chip. |
| 835 | * 0 if we don't have a TPM2 chip. | ||
| 836 | * A negative number for system errors (errno). | ||
| 817 | */ | 837 | */ |
| 818 | int tpm_is_tpm2(u32 chip_num) | 838 | int tpm_is_tpm2(struct tpm_chip *chip) |
| 819 | { | 839 | { |
| 820 | struct tpm_chip *chip; | ||
| 821 | int rc; | 840 | int rc; |
| 822 | 841 | ||
| 823 | chip = tpm_chip_find_get(chip_num); | 842 | chip = tpm_chip_find_get(chip); |
| 824 | if (chip == NULL) | 843 | if (!chip) |
| 825 | return -ENODEV; | 844 | return -ENODEV; |
| 826 | 845 | ||
| 827 | rc = (chip->flags & TPM_CHIP_FLAG_TPM2) != 0; | 846 | rc = (chip->flags & TPM_CHIP_FLAG_TPM2) != 0; |
| @@ -833,23 +852,19 @@ int tpm_is_tpm2(u32 chip_num) | |||
| 833 | EXPORT_SYMBOL_GPL(tpm_is_tpm2); | 852 | EXPORT_SYMBOL_GPL(tpm_is_tpm2); |
| 834 | 853 | ||
| 835 | /** | 854 | /** |
| 836 | * tpm_pcr_read - read a pcr value | 855 | * tpm_pcr_read - read a PCR value from SHA1 bank |
| 837 | * @chip_num: tpm idx # or ANY | 856 | * @chip: a &struct tpm_chip instance, %NULL for the default chip |
| 838 | * @pcr_idx: pcr idx to retrieve | 857 | * @pcr_idx: the PCR to be retrieved |
| 839 | * @res_buf: TPM_PCR value | 858 | * @res_buf: the value of the PCR |
| 840 | * size of res_buf is 20 bytes (or NULL if you don't care) | ||
| 841 | * | 859 | * |
| 842 | * The TPM driver should be built-in, but for whatever reason it | 860 | * Return: same as with tpm_transmit_cmd() |
| 843 | * isn't, protect against the chip disappearing, by incrementing | ||
| 844 | * the module usage count. | ||
| 845 | */ | 861 | */ |
| 846 | int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf) | 862 | int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf) |
| 847 | { | 863 | { |
| 848 | struct tpm_chip *chip; | ||
| 849 | int rc; | 864 | int rc; |
| 850 | 865 | ||
| 851 | chip = tpm_chip_find_get(chip_num); | 866 | chip = tpm_chip_find_get(chip); |
| 852 | if (chip == NULL) | 867 | if (!chip) |
| 853 | return -ENODEV; | 868 | return -ENODEV; |
| 854 | if (chip->flags & TPM_CHIP_FLAG_TPM2) | 869 | if (chip->flags & TPM_CHIP_FLAG_TPM2) |
| 855 | rc = tpm2_pcr_read(chip, pcr_idx, res_buf); | 870 | rc = tpm2_pcr_read(chip, pcr_idx, res_buf); |
| @@ -889,25 +904,26 @@ static int tpm1_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash, | |||
| 889 | } | 904 | } |
| 890 | 905 | ||
| 891 | /** | 906 | /** |
| 892 | * tpm_pcr_extend - extend pcr value with hash | 907 | * tpm_pcr_extend - extend a PCR value in SHA1 bank. |
| 893 | * @chip_num: tpm idx # or AN& | 908 | * @chip: a &struct tpm_chip instance, %NULL for the default chip |
| 894 | * @pcr_idx: pcr idx to extend | 909 | * @pcr_idx: the PCR to be retrieved |
| 895 | * @hash: hash value used to extend pcr value | 910 | * @hash: the hash value used to extend the PCR value |
| 896 | * | 911 | * |
| 897 | * The TPM driver should be built-in, but for whatever reason it | 912 | * Note: with TPM 2.0 extends also those banks with a known digest size to the |
| 898 | * isn't, protect against the chip disappearing, by incrementing | 913 | * cryto subsystem in order to prevent malicious use of those PCR banks. In the |
| 899 | * the module usage count. | 914 | * future we should dynamically determine digest sizes. |
| 915 | * | ||
| 916 | * Return: same as with tpm_transmit_cmd() | ||
| 900 | */ | 917 | */ |
| 901 | int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash) | 918 | int tpm_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash) |
| 902 | { | 919 | { |
| 903 | int rc; | 920 | int rc; |
| 904 | struct tpm_chip *chip; | ||
| 905 | struct tpm2_digest digest_list[ARRAY_SIZE(chip->active_banks)]; | 921 | struct tpm2_digest digest_list[ARRAY_SIZE(chip->active_banks)]; |
| 906 | u32 count = 0; | 922 | u32 count = 0; |
| 907 | int i; | 923 | int i; |
| 908 | 924 | ||
| 909 | chip = tpm_chip_find_get(chip_num); | 925 | chip = tpm_chip_find_get(chip); |
| 910 | if (chip == NULL) | 926 | if (!chip) |
| 911 | return -ENODEV; | 927 | return -ENODEV; |
| 912 | 928 | ||
| 913 | if (chip->flags & TPM_CHIP_FLAG_TPM2) { | 929 | if (chip->flags & TPM_CHIP_FLAG_TPM2) { |
| @@ -1019,82 +1035,29 @@ out: | |||
| 1019 | return rc; | 1035 | return rc; |
| 1020 | } | 1036 | } |
| 1021 | 1037 | ||
| 1022 | int tpm_send(u32 chip_num, void *cmd, size_t buflen) | 1038 | /** |
| 1039 | * tpm_send - send a TPM command | ||
| 1040 | * @chip: a &struct tpm_chip instance, %NULL for the default chip | ||
| 1041 | * @cmd: a TPM command buffer | ||
| 1042 | * @buflen: the length of the TPM command buffer | ||
| 1043 | * | ||
| 1044 | * Return: same as with tpm_transmit_cmd() | ||
| 1045 | */ | ||
| 1046 | int tpm_send(struct tpm_chip *chip, void *cmd, size_t buflen) | ||
| 1023 | { | 1047 | { |
| 1024 | struct tpm_chip *chip; | ||
| 1025 | int rc; | 1048 | int rc; |
| 1026 | 1049 | ||
| 1027 | chip = tpm_chip_find_get(chip_num); | 1050 | chip = tpm_chip_find_get(chip); |
| 1028 | if (chip == NULL) | 1051 | if (!chip) |
| 1029 | return -ENODEV; | 1052 | return -ENODEV; |
| 1030 | 1053 | ||
| 1031 | rc = tpm_transmit_cmd(chip, NULL, cmd, buflen, 0, 0, | 1054 | rc = tpm_transmit_cmd(chip, NULL, cmd, buflen, 0, 0, |
| 1032 | "attempting tpm_cmd"); | 1055 | "attempting to a send a command"); |
| 1033 | tpm_put_ops(chip); | 1056 | tpm_put_ops(chip); |
| 1034 | return rc; | 1057 | return rc; |
| 1035 | } | 1058 | } |
| 1036 | EXPORT_SYMBOL_GPL(tpm_send); | 1059 | EXPORT_SYMBOL_GPL(tpm_send); |
| 1037 | 1060 | ||
| 1038 | static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask, | ||
| 1039 | bool check_cancel, bool *canceled) | ||
| 1040 | { | ||
| 1041 | u8 status = chip->ops->status(chip); | ||
| 1042 | |||
| 1043 | *canceled = false; | ||
| 1044 | if ((status & mask) == mask) | ||
| 1045 | return true; | ||
| 1046 | if (check_cancel && chip->ops->req_canceled(chip, status)) { | ||
| 1047 | *canceled = true; | ||
| 1048 | return true; | ||
| 1049 | } | ||
| 1050 | return false; | ||
| 1051 | } | ||
| 1052 | |||
| 1053 | int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout, | ||
| 1054 | wait_queue_head_t *queue, bool check_cancel) | ||
| 1055 | { | ||
| 1056 | unsigned long stop; | ||
| 1057 | long rc; | ||
| 1058 | u8 status; | ||
| 1059 | bool canceled = false; | ||
| 1060 | |||
| 1061 | /* check current status */ | ||
| 1062 | status = chip->ops->status(chip); | ||
| 1063 | if ((status & mask) == mask) | ||
| 1064 | return 0; | ||
| 1065 | |||
| 1066 | stop = jiffies + timeout; | ||
| 1067 | |||
| 1068 | if (chip->flags & TPM_CHIP_FLAG_IRQ) { | ||
| 1069 | again: | ||
| 1070 | timeout = stop - jiffies; | ||
| 1071 | if ((long)timeout <= 0) | ||
| 1072 | return -ETIME; | ||
| 1073 | rc = wait_event_interruptible_timeout(*queue, | ||
| 1074 | wait_for_tpm_stat_cond(chip, mask, check_cancel, | ||
| 1075 | &canceled), | ||
| 1076 | timeout); | ||
| 1077 | if (rc > 0) { | ||
| 1078 | if (canceled) | ||
| 1079 | return -ECANCELED; | ||
| 1080 | return 0; | ||
| 1081 | } | ||
| 1082 | if (rc == -ERESTARTSYS && freezing(current)) { | ||
| 1083 | clear_thread_flag(TIF_SIGPENDING); | ||
| 1084 | goto again; | ||
| 1085 | } | ||
| 1086 | } else { | ||
| 1087 | do { | ||
| 1088 | tpm_msleep(TPM_TIMEOUT); | ||
| 1089 | status = chip->ops->status(chip); | ||
| 1090 | if ((status & mask) == mask) | ||
| 1091 | return 0; | ||
| 1092 | } while (time_before(jiffies, stop)); | ||
| 1093 | } | ||
| 1094 | return -ETIME; | ||
| 1095 | } | ||
| 1096 | EXPORT_SYMBOL_GPL(wait_for_tpm_stat); | ||
| 1097 | |||
| 1098 | #define TPM_ORD_SAVESTATE 152 | 1061 | #define TPM_ORD_SAVESTATE 152 |
| 1099 | #define SAVESTATE_RESULT_SIZE 10 | 1062 | #define SAVESTATE_RESULT_SIZE 10 |
| 1100 | 1063 | ||
| @@ -1187,16 +1150,15 @@ static const struct tpm_input_header tpm_getrandom_header = { | |||
| 1187 | }; | 1150 | }; |
| 1188 | 1151 | ||
| 1189 | /** | 1152 | /** |
| 1190 | * tpm_get_random() - Get random bytes from the tpm's RNG | 1153 | * tpm_get_random() - get random bytes from the TPM's RNG |
| 1191 | * @chip_num: A specific chip number for the request or TPM_ANY_NUM | 1154 | * @chip: a &struct tpm_chip instance, %NULL for the default chip |
| 1192 | * @out: destination buffer for the random bytes | 1155 | * @out: destination buffer for the random bytes |
| 1193 | * @max: the max number of bytes to write to @out | 1156 | * @max: the max number of bytes to write to @out |
| 1194 | * | 1157 | * |
| 1195 | * Returns < 0 on error and the number of bytes read on success | 1158 | * Return: same as with tpm_transmit_cmd() |
| 1196 | */ | 1159 | */ |
| 1197 | int tpm_get_random(u32 chip_num, u8 *out, size_t max) | 1160 | int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max) |
| 1198 | { | 1161 | { |
| 1199 | struct tpm_chip *chip; | ||
| 1200 | struct tpm_cmd_t tpm_cmd; | 1162 | struct tpm_cmd_t tpm_cmd; |
| 1201 | u32 recd, num_bytes = min_t(u32, max, TPM_MAX_RNG_DATA), rlength; | 1163 | u32 recd, num_bytes = min_t(u32, max, TPM_MAX_RNG_DATA), rlength; |
| 1202 | int err, total = 0, retries = 5; | 1164 | int err, total = 0, retries = 5; |
| @@ -1205,8 +1167,8 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max) | |||
| 1205 | if (!out || !num_bytes || max > TPM_MAX_RNG_DATA) | 1167 | if (!out || !num_bytes || max > TPM_MAX_RNG_DATA) |
| 1206 | return -EINVAL; | 1168 | return -EINVAL; |
| 1207 | 1169 | ||
| 1208 | chip = tpm_chip_find_get(chip_num); | 1170 | chip = tpm_chip_find_get(chip); |
| 1209 | if (chip == NULL) | 1171 | if (!chip) |
| 1210 | return -ENODEV; | 1172 | return -ENODEV; |
| 1211 | 1173 | ||
| 1212 | if (chip->flags & TPM_CHIP_FLAG_TPM2) { | 1174 | if (chip->flags & TPM_CHIP_FLAG_TPM2) { |
| @@ -1248,22 +1210,23 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max) | |||
| 1248 | EXPORT_SYMBOL_GPL(tpm_get_random); | 1210 | EXPORT_SYMBOL_GPL(tpm_get_random); |
| 1249 | 1211 | ||
| 1250 | /** | 1212 | /** |
| 1251 | * tpm_seal_trusted() - seal a trusted key | 1213 | * tpm_seal_trusted() - seal a trusted key payload |
| 1252 | * @chip_num: A specific chip number for the request or TPM_ANY_NUM | 1214 | * @chip: a &struct tpm_chip instance, %NULL for the default chip |
| 1253 | * @options: authentication values and other options | 1215 | * @options: authentication values and other options |
| 1254 | * @payload: the key data in clear and encrypted form | 1216 | * @payload: the key data in clear and encrypted form |
| 1255 | * | 1217 | * |
| 1256 | * Returns < 0 on error and 0 on success. At the moment, only TPM 2.0 chips | 1218 | * Note: only TPM 2.0 chip are supported. TPM 1.x implementation is located in |
| 1257 | * are supported. | 1219 | * the keyring subsystem. |
| 1220 | * | ||
| 1221 | * Return: same as with tpm_transmit_cmd() | ||
| 1258 | */ | 1222 | */ |
| 1259 | int tpm_seal_trusted(u32 chip_num, struct trusted_key_payload *payload, | 1223 | int tpm_seal_trusted(struct tpm_chip *chip, struct trusted_key_payload *payload, |
| 1260 | struct trusted_key_options *options) | 1224 | struct trusted_key_options *options) |
| 1261 | { | 1225 | { |
| 1262 | struct tpm_chip *chip; | ||
| 1263 | int rc; | 1226 | int rc; |
| 1264 | 1227 | ||
| 1265 | chip = tpm_chip_find_get(chip_num); | 1228 | chip = tpm_chip_find_get(chip); |
| 1266 | if (chip == NULL || !(chip->flags & TPM_CHIP_FLAG_TPM2)) | 1229 | if (!chip || !(chip->flags & TPM_CHIP_FLAG_TPM2)) |
| 1267 | return -ENODEV; | 1230 | return -ENODEV; |
| 1268 | 1231 | ||
| 1269 | rc = tpm2_seal_trusted(chip, payload, options); | 1232 | rc = tpm2_seal_trusted(chip, payload, options); |
| @@ -1275,21 +1238,23 @@ EXPORT_SYMBOL_GPL(tpm_seal_trusted); | |||
| 1275 | 1238 | ||
| 1276 | /** | 1239 | /** |
| 1277 | * tpm_unseal_trusted() - unseal a trusted key | 1240 | * tpm_unseal_trusted() - unseal a trusted key |
| 1278 | * @chip_num: A specific chip number for the request or TPM_ANY_NUM | 1241 | * @chip: a &struct tpm_chip instance, %NULL for the default chip |
| 1279 | * @options: authentication values and other options | 1242 | * @options: authentication values and other options |
| 1280 | * @payload: the key data in clear and encrypted form | 1243 | * @payload: the key data in clear and encrypted form |
| 1244 | * | ||
| 1245 | * Note: only TPM 2.0 chip are supported. TPM 1.x implementation is located in | ||
| 1246 | * the keyring subsystem. | ||
| 1281 | * | 1247 | * |
| 1282 | * Returns < 0 on error and 0 on success. At the moment, only TPM 2.0 chips | 1248 | * Return: same as with tpm_transmit_cmd() |
| 1283 | * are supported. | ||
| 1284 | */ | 1249 | */ |
| 1285 | int tpm_unseal_trusted(u32 chip_num, struct trusted_key_payload *payload, | 1250 | int tpm_unseal_trusted(struct tpm_chip *chip, |
| 1251 | struct trusted_key_payload *payload, | ||
| 1286 | struct trusted_key_options *options) | 1252 | struct trusted_key_options *options) |
| 1287 | { | 1253 | { |
| 1288 | struct tpm_chip *chip; | ||
| 1289 | int rc; | 1254 | int rc; |
| 1290 | 1255 | ||
| 1291 | chip = tpm_chip_find_get(chip_num); | 1256 | chip = tpm_chip_find_get(chip); |
| 1292 | if (chip == NULL || !(chip->flags & TPM_CHIP_FLAG_TPM2)) | 1257 | if (!chip || !(chip->flags & TPM_CHIP_FLAG_TPM2)) |
| 1293 | return -ENODEV; | 1258 | return -ENODEV; |
| 1294 | 1259 | ||
| 1295 | rc = tpm2_unseal_trusted(chip, payload, options); | 1260 | rc = tpm2_unseal_trusted(chip, payload, options); |
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 528cffbd49d3..f895fba4e20d 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> |
| @@ -34,6 +35,7 @@ | |||
| 34 | #include <linux/acpi.h> | 35 | #include <linux/acpi.h> |
| 35 | #include <linux/cdev.h> | 36 | #include <linux/cdev.h> |
| 36 | #include <linux/highmem.h> | 37 | #include <linux/highmem.h> |
| 38 | #include <linux/tpm_eventlog.h> | ||
| 37 | #include <crypto/hash_info.h> | 39 | #include <crypto/hash_info.h> |
| 38 | 40 | ||
| 39 | #ifdef CONFIG_X86 | 41 | #ifdef CONFIG_X86 |
| @@ -93,12 +95,17 @@ enum tpm2_structures { | |||
| 93 | TPM2_ST_SESSIONS = 0x8002, | 95 | TPM2_ST_SESSIONS = 0x8002, |
| 94 | }; | 96 | }; |
| 95 | 97 | ||
| 98 | /* Indicates from what layer of the software stack the error comes from */ | ||
| 99 | #define TSS2_RC_LAYER_SHIFT 16 | ||
| 100 | #define TSS2_RESMGR_TPM_RC_LAYER (11 << TSS2_RC_LAYER_SHIFT) | ||
| 101 | |||
| 96 | enum tpm2_return_codes { | 102 | enum tpm2_return_codes { |
| 97 | TPM2_RC_SUCCESS = 0x0000, | 103 | TPM2_RC_SUCCESS = 0x0000, |
| 98 | TPM2_RC_HASH = 0x0083, /* RC_FMT1 */ | 104 | TPM2_RC_HASH = 0x0083, /* RC_FMT1 */ |
| 99 | TPM2_RC_HANDLE = 0x008B, | 105 | TPM2_RC_HANDLE = 0x008B, |
| 100 | TPM2_RC_INITIALIZE = 0x0100, /* RC_VER1 */ | 106 | TPM2_RC_INITIALIZE = 0x0100, /* RC_VER1 */ |
| 101 | TPM2_RC_DISABLED = 0x0120, | 107 | TPM2_RC_DISABLED = 0x0120, |
| 108 | TPM2_RC_COMMAND_CODE = 0x0143, | ||
| 102 | TPM2_RC_TESTING = 0x090A, /* RC_WARN */ | 109 | TPM2_RC_TESTING = 0x090A, /* RC_WARN */ |
| 103 | TPM2_RC_REFERENCE_H0 = 0x0910, | 110 | TPM2_RC_REFERENCE_H0 = 0x0910, |
| 104 | }; | 111 | }; |
| @@ -210,6 +217,9 @@ struct tpm_chip { | |||
| 210 | int dev_num; /* /dev/tpm# */ | 217 | int dev_num; /* /dev/tpm# */ |
| 211 | unsigned long is_open; /* only one allowed */ | 218 | unsigned long is_open; /* only one allowed */ |
| 212 | 219 | ||
| 220 | char hwrng_name[64]; | ||
| 221 | struct hwrng hwrng; | ||
| 222 | |||
| 213 | struct mutex tpm_mutex; /* tpm is processing */ | 223 | struct mutex tpm_mutex; /* tpm is processing */ |
| 214 | 224 | ||
| 215 | unsigned long timeout_a; /* jiffies */ | 225 | unsigned long timeout_a; /* jiffies */ |
| @@ -385,10 +395,6 @@ struct tpm_cmd_t { | |||
| 385 | tpm_cmd_params params; | 395 | tpm_cmd_params params; |
| 386 | } __packed; | 396 | } __packed; |
| 387 | 397 | ||
| 388 | struct tpm2_digest { | ||
| 389 | u16 alg_id; | ||
| 390 | u8 digest[SHA512_DIGEST_SIZE]; | ||
| 391 | } __packed; | ||
| 392 | 398 | ||
| 393 | /* A string buffer type for constructing TPM commands. This is based on the | 399 | /* A string buffer type for constructing TPM commands. This is based on the |
| 394 | * ideas of string buffer code in security/keys/trusted.h but is heap based | 400 | * ideas of string buffer code in security/keys/trusted.h but is heap based |
| @@ -512,16 +518,14 @@ int tpm_do_selftest(struct tpm_chip *chip); | |||
| 512 | unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal); | 518 | unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal); |
| 513 | int tpm_pm_suspend(struct device *dev); | 519 | int tpm_pm_suspend(struct device *dev); |
| 514 | int tpm_pm_resume(struct device *dev); | 520 | int tpm_pm_resume(struct device *dev); |
| 515 | int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout, | ||
| 516 | wait_queue_head_t *queue, bool check_cancel); | ||
| 517 | 521 | ||
| 518 | static inline void tpm_msleep(unsigned int delay_msec) | 522 | static inline void tpm_msleep(unsigned int delay_msec) |
| 519 | { | 523 | { |
| 520 | usleep_range(delay_msec * 1000, | 524 | usleep_range((delay_msec * 1000) - TPM_TIMEOUT_RANGE_US, |
| 521 | (delay_msec * 1000) + TPM_TIMEOUT_RANGE_US); | 525 | delay_msec * 1000); |
| 522 | }; | 526 | }; |
| 523 | 527 | ||
| 524 | struct tpm_chip *tpm_chip_find_get(int chip_num); | 528 | struct tpm_chip *tpm_chip_find_get(struct tpm_chip *chip); |
| 525 | __must_check int tpm_try_get_ops(struct tpm_chip *chip); | 529 | __must_check int tpm_try_get_ops(struct tpm_chip *chip); |
| 526 | void tpm_put_ops(struct tpm_chip *chip); | 530 | void tpm_put_ops(struct tpm_chip *chip); |
| 527 | 531 | ||
| @@ -575,4 +579,34 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u32 cc, | |||
| 575 | u8 *cmd); | 579 | u8 *cmd); |
| 576 | int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space, | 580 | int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space, |
| 577 | u32 cc, u8 *buf, size_t *bufsiz); | 581 | u32 cc, u8 *buf, size_t *bufsiz); |
| 582 | |||
| 583 | extern const struct seq_operations tpm2_binary_b_measurements_seqops; | ||
| 584 | |||
| 585 | #if defined(CONFIG_ACPI) | ||
| 586 | int tpm_read_log_acpi(struct tpm_chip *chip); | ||
| 587 | #else | ||
| 588 | static inline int tpm_read_log_acpi(struct tpm_chip *chip) | ||
| 589 | { | ||
| 590 | return -ENODEV; | ||
| 591 | } | ||
| 592 | #endif | ||
| 593 | #if defined(CONFIG_OF) | ||
| 594 | int tpm_read_log_of(struct tpm_chip *chip); | ||
| 595 | #else | ||
| 596 | static inline int tpm_read_log_of(struct tpm_chip *chip) | ||
| 597 | { | ||
| 598 | return -ENODEV; | ||
| 599 | } | ||
| 600 | #endif | ||
| 601 | #if defined(CONFIG_EFI) | ||
| 602 | int tpm_read_log_efi(struct tpm_chip *chip); | ||
| 603 | #else | ||
| 604 | static inline int tpm_read_log_efi(struct tpm_chip *chip) | ||
| 605 | { | ||
| 606 | return -ENODEV; | ||
| 607 | } | ||
| 608 | #endif | ||
| 609 | |||
| 610 | int tpm_bios_log_setup(struct tpm_chip *chip); | ||
| 611 | void tpm_bios_log_teardown(struct tpm_chip *chip); | ||
| 578 | #endif | 612 | #endif |
diff --git a/drivers/char/tpm/tpm1_eventlog.c b/drivers/char/tpm/tpm1_eventlog.c index 9a8605e500b5..add798bd69d0 100644 --- a/drivers/char/tpm/tpm1_eventlog.c +++ b/drivers/char/tpm/tpm1_eventlog.c | |||
| @@ -21,13 +21,14 @@ | |||
| 21 | */ | 21 | */ |
| 22 | 22 | ||
| 23 | #include <linux/seq_file.h> | 23 | #include <linux/seq_file.h> |
| 24 | #include <linux/efi.h> | ||
| 24 | #include <linux/fs.h> | 25 | #include <linux/fs.h> |
| 25 | #include <linux/security.h> | 26 | #include <linux/security.h> |
| 26 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 27 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
| 29 | #include <linux/tpm_eventlog.h> | ||
| 28 | 30 | ||
| 29 | #include "tpm.h" | 31 | #include "tpm.h" |
| 30 | #include "tpm_eventlog.h" | ||
| 31 | 32 | ||
| 32 | 33 | ||
| 33 | static const char* tcpa_event_type_strings[] = { | 34 | static const char* tcpa_event_type_strings[] = { |
| @@ -371,6 +372,10 @@ static int tpm_read_log(struct tpm_chip *chip) | |||
| 371 | if (rc != -ENODEV) | 372 | if (rc != -ENODEV) |
| 372 | return rc; | 373 | return rc; |
| 373 | 374 | ||
| 375 | rc = tpm_read_log_efi(chip); | ||
| 376 | if (rc != -ENODEV) | ||
| 377 | return rc; | ||
| 378 | |||
| 374 | return tpm_read_log_of(chip); | 379 | return tpm_read_log_of(chip); |
| 375 | } | 380 | } |
| 376 | 381 | ||
| @@ -388,11 +393,13 @@ int tpm_bios_log_setup(struct tpm_chip *chip) | |||
| 388 | { | 393 | { |
| 389 | const char *name = dev_name(&chip->dev); | 394 | const char *name = dev_name(&chip->dev); |
| 390 | unsigned int cnt; | 395 | unsigned int cnt; |
| 396 | int log_version; | ||
| 391 | int rc = 0; | 397 | int rc = 0; |
| 392 | 398 | ||
| 393 | rc = tpm_read_log(chip); | 399 | rc = tpm_read_log(chip); |
| 394 | if (rc) | 400 | if (rc < 0) |
| 395 | return rc; | 401 | return rc; |
| 402 | log_version = rc; | ||
| 396 | 403 | ||
| 397 | cnt = 0; | 404 | cnt = 0; |
| 398 | chip->bios_dir[cnt] = securityfs_create_dir(name, NULL); | 405 | chip->bios_dir[cnt] = securityfs_create_dir(name, NULL); |
| @@ -404,7 +411,7 @@ int tpm_bios_log_setup(struct tpm_chip *chip) | |||
| 404 | cnt++; | 411 | cnt++; |
| 405 | 412 | ||
| 406 | chip->bin_log_seqops.chip = chip; | 413 | chip->bin_log_seqops.chip = chip; |
| 407 | if (chip->flags & TPM_CHIP_FLAG_TPM2) | 414 | if (log_version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) |
| 408 | chip->bin_log_seqops.seqops = | 415 | chip->bin_log_seqops.seqops = |
| 409 | &tpm2_binary_b_measurements_seqops; | 416 | &tpm2_binary_b_measurements_seqops; |
| 410 | else | 417 | else |
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index f40d20671a78..c17e75348a99 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c | |||
| @@ -849,28 +849,26 @@ static const struct tpm_input_header tpm2_selftest_header = { | |||
| 849 | static int tpm2_do_selftest(struct tpm_chip *chip) | 849 | static int tpm2_do_selftest(struct tpm_chip *chip) |
| 850 | { | 850 | { |
| 851 | int rc; | 851 | int rc; |
| 852 | unsigned int delay_msec = 20; | 852 | unsigned int delay_msec = 10; |
| 853 | long duration; | 853 | long duration; |
| 854 | struct tpm2_cmd cmd; | 854 | struct tpm2_cmd cmd; |
| 855 | 855 | ||
| 856 | duration = jiffies_to_msecs( | 856 | duration = jiffies_to_msecs( |
| 857 | tpm2_calc_ordinal_duration(chip, TPM2_CC_SELF_TEST)); | 857 | tpm2_calc_ordinal_duration(chip, TPM2_CC_SELF_TEST)); |
| 858 | 858 | ||
| 859 | while (duration > 0) { | 859 | while (1) { |
| 860 | cmd.header.in = tpm2_selftest_header; | 860 | cmd.header.in = tpm2_selftest_header; |
| 861 | cmd.params.selftest_in.full_test = 0; | 861 | cmd.params.selftest_in.full_test = 0; |
| 862 | 862 | ||
| 863 | rc = tpm_transmit_cmd(chip, NULL, &cmd, TPM2_SELF_TEST_IN_SIZE, | 863 | rc = tpm_transmit_cmd(chip, NULL, &cmd, TPM2_SELF_TEST_IN_SIZE, |
| 864 | 0, 0, "continue selftest"); | 864 | 0, 0, "continue selftest"); |
| 865 | 865 | ||
| 866 | if (rc != TPM2_RC_TESTING) | 866 | if (rc != TPM2_RC_TESTING || delay_msec >= duration) |
| 867 | break; | 867 | break; |
| 868 | 868 | ||
| 869 | tpm_msleep(delay_msec); | 869 | /* wait longer than before */ |
| 870 | duration -= delay_msec; | ||
| 871 | |||
| 872 | /* wait longer the next round */ | ||
| 873 | delay_msec *= 2; | 870 | delay_msec *= 2; |
| 871 | tpm_msleep(delay_msec); | ||
| 874 | } | 872 | } |
| 875 | 873 | ||
| 876 | return rc; | 874 | return rc; |
diff --git a/drivers/char/tpm/tpm2_eventlog.c b/drivers/char/tpm/tpm2_eventlog.c index 34a8afa69138..1ce4411292ba 100644 --- a/drivers/char/tpm/tpm2_eventlog.c +++ b/drivers/char/tpm/tpm2_eventlog.c | |||
| @@ -21,9 +21,9 @@ | |||
| 21 | #include <linux/security.h> | 21 | #include <linux/security.h> |
| 22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
| 23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
| 24 | #include <linux/tpm_eventlog.h> | ||
| 24 | 25 | ||
| 25 | #include "tpm.h" | 26 | #include "tpm.h" |
| 26 | #include "tpm_eventlog.h" | ||
| 27 | 27 | ||
| 28 | /* | 28 | /* |
| 29 | * calc_tpm2_event_size() - calculate the event size, where event | 29 | * calc_tpm2_event_size() - calculate the event size, where event |
diff --git a/drivers/char/tpm/tpm_acpi.c b/drivers/char/tpm/tpm_eventlog_acpi.c index 169edf3ce86d..66f19e93c216 100644 --- a/drivers/char/tpm/tpm_acpi.c +++ b/drivers/char/tpm/tpm_eventlog_acpi.c | |||
| @@ -25,9 +25,9 @@ | |||
| 25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
| 26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 27 | #include <linux/acpi.h> | 27 | #include <linux/acpi.h> |
| 28 | #include <linux/tpm_eventlog.h> | ||
| 28 | 29 | ||
| 29 | #include "tpm.h" | 30 | #include "tpm.h" |
| 30 | #include "tpm_eventlog.h" | ||
| 31 | 31 | ||
| 32 | struct acpi_tcpa { | 32 | struct acpi_tcpa { |
| 33 | struct acpi_table_header hdr; | 33 | struct acpi_table_header hdr; |
| @@ -102,7 +102,7 @@ int tpm_read_log_acpi(struct tpm_chip *chip) | |||
| 102 | memcpy_fromio(log->bios_event_log, virt, len); | 102 | memcpy_fromio(log->bios_event_log, virt, len); |
| 103 | 103 | ||
| 104 | acpi_os_unmap_iomem(virt, len); | 104 | acpi_os_unmap_iomem(virt, len); |
| 105 | return 0; | 105 | return EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2; |
| 106 | 106 | ||
| 107 | err: | 107 | err: |
| 108 | kfree(log->bios_event_log); | 108 | kfree(log->bios_event_log); |
diff --git a/drivers/char/tpm/tpm_eventlog_efi.c b/drivers/char/tpm/tpm_eventlog_efi.c new file mode 100644 index 000000000000..e3f9ffd341d2 --- /dev/null +++ b/drivers/char/tpm/tpm_eventlog_efi.c | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2017 Google | ||
| 3 | * | ||
| 4 | * Authors: | ||
| 5 | * Thiebaud Weksteen <tweek@google.com> | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License | ||
| 9 | * as published by the Free Software Foundation; either version | ||
| 10 | * 2 of the License, or (at your option) any later version. | ||
| 11 | * | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/efi.h> | ||
| 15 | #include <linux/tpm_eventlog.h> | ||
| 16 | |||
| 17 | #include "tpm.h" | ||
| 18 | |||
| 19 | /* read binary bios log from EFI configuration table */ | ||
| 20 | int tpm_read_log_efi(struct tpm_chip *chip) | ||
| 21 | { | ||
| 22 | |||
| 23 | struct linux_efi_tpm_eventlog *log_tbl; | ||
| 24 | struct tpm_bios_log *log; | ||
| 25 | u32 log_size; | ||
| 26 | u8 tpm_log_version; | ||
| 27 | |||
| 28 | if (!(chip->flags & TPM_CHIP_FLAG_TPM2)) | ||
| 29 | return -ENODEV; | ||
| 30 | |||
| 31 | if (efi.tpm_log == EFI_INVALID_TABLE_ADDR) | ||
| 32 | return -ENODEV; | ||
| 33 | |||
| 34 | log = &chip->log; | ||
| 35 | |||
| 36 | log_tbl = memremap(efi.tpm_log, sizeof(*log_tbl), MEMREMAP_WB); | ||
| 37 | if (!log_tbl) { | ||
| 38 | pr_err("Could not map UEFI TPM log table !\n"); | ||
| 39 | return -ENOMEM; | ||
| 40 | } | ||
| 41 | |||
| 42 | log_size = log_tbl->size; | ||
| 43 | memunmap(log_tbl); | ||
| 44 | |||
| 45 | log_tbl = memremap(efi.tpm_log, sizeof(*log_tbl) + log_size, | ||
| 46 | MEMREMAP_WB); | ||
| 47 | if (!log_tbl) { | ||
| 48 | pr_err("Could not map UEFI TPM log table payload!\n"); | ||
| 49 | return -ENOMEM; | ||
| 50 | } | ||
| 51 | |||
| 52 | /* malloc EventLog space */ | ||
| 53 | log->bios_event_log = kmalloc(log_size, GFP_KERNEL); | ||
| 54 | if (!log->bios_event_log) | ||
| 55 | goto err_memunmap; | ||
| 56 | memcpy(log->bios_event_log, log_tbl->log, log_size); | ||
| 57 | log->bios_event_log_end = log->bios_event_log + log_size; | ||
| 58 | |||
| 59 | tpm_log_version = log_tbl->version; | ||
| 60 | memunmap(log_tbl); | ||
| 61 | return tpm_log_version; | ||
| 62 | |||
| 63 | err_memunmap: | ||
| 64 | memunmap(log_tbl); | ||
| 65 | return -ENOMEM; | ||
| 66 | } | ||
diff --git a/drivers/char/tpm/tpm_of.c b/drivers/char/tpm/tpm_eventlog_of.c index aadb7f464076..96fd5646f866 100644 --- a/drivers/char/tpm/tpm_of.c +++ b/drivers/char/tpm/tpm_eventlog_of.c | |||
| @@ -17,9 +17,9 @@ | |||
| 17 | 17 | ||
| 18 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
| 19 | #include <linux/of.h> | 19 | #include <linux/of.h> |
| 20 | #include <linux/tpm_eventlog.h> | ||
| 20 | 21 | ||
| 21 | #include "tpm.h" | 22 | #include "tpm.h" |
| 22 | #include "tpm_eventlog.h" | ||
| 23 | 23 | ||
| 24 | int tpm_read_log_of(struct tpm_chip *chip) | 24 | int tpm_read_log_of(struct tpm_chip *chip) |
| 25 | { | 25 | { |
| @@ -76,5 +76,7 @@ int tpm_read_log_of(struct tpm_chip *chip) | |||
| 76 | 76 | ||
| 77 | memcpy(log->bios_event_log, __va(base), size); | 77 | memcpy(log->bios_event_log, __va(base), size); |
| 78 | 78 | ||
| 79 | return 0; | 79 | if (chip->flags & TPM_CHIP_FLAG_TPM2) |
| 80 | return EFI_TCG2_EVENT_LOG_FORMAT_TCG_2; | ||
| 81 | return EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2; | ||
| 80 | } | 82 | } |
diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c index 79d6bbb58e39..c1dd39eaaeeb 100644 --- a/drivers/char/tpm/tpm_i2c_infineon.c +++ b/drivers/char/tpm/tpm_i2c_infineon.c | |||
| @@ -665,9 +665,9 @@ out_err: | |||
| 665 | } | 665 | } |
| 666 | 666 | ||
| 667 | static const struct i2c_device_id tpm_tis_i2c_table[] = { | 667 | static const struct i2c_device_id tpm_tis_i2c_table[] = { |
| 668 | {"tpm_i2c_infineon", 0}, | 668 | {"tpm_i2c_infineon"}, |
| 669 | {"slb9635tt", 0}, | 669 | {"slb9635tt"}, |
| 670 | {"slb9645tt", 1}, | 670 | {"slb9645tt"}, |
| 671 | {}, | 671 | {}, |
| 672 | }; | 672 | }; |
| 673 | 673 | ||
| @@ -675,24 +675,9 @@ MODULE_DEVICE_TABLE(i2c, tpm_tis_i2c_table); | |||
| 675 | 675 | ||
| 676 | #ifdef CONFIG_OF | 676 | #ifdef CONFIG_OF |
| 677 | static const struct of_device_id tpm_tis_i2c_of_match[] = { | 677 | static const struct of_device_id tpm_tis_i2c_of_match[] = { |
| 678 | { | 678 | {.compatible = "infineon,tpm_i2c_infineon"}, |
| 679 | .name = "tpm_i2c_infineon", | 679 | {.compatible = "infineon,slb9635tt"}, |
| 680 | .type = "tpm", | 680 | {.compatible = "infineon,slb9645tt"}, |
| 681 | .compatible = "infineon,tpm_i2c_infineon", | ||
| 682 | .data = (void *)0 | ||
| 683 | }, | ||
| 684 | { | ||
| 685 | .name = "slb9635tt", | ||
| 686 | .type = "tpm", | ||
| 687 | .compatible = "infineon,slb9635tt", | ||
| 688 | .data = (void *)0 | ||
| 689 | }, | ||
| 690 | { | ||
| 691 | .name = "slb9645tt", | ||
| 692 | .type = "tpm", | ||
| 693 | .compatible = "infineon,slb9645tt", | ||
| 694 | .data = (void *)1 | ||
| 695 | }, | ||
| 696 | {}, | 681 | {}, |
| 697 | }; | 682 | }; |
| 698 | MODULE_DEVICE_TABLE(of, tpm_tis_i2c_of_match); | 683 | MODULE_DEVICE_TABLE(of, tpm_tis_i2c_of_match); |
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index e2d1055fb814..f08949a5f678 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
| @@ -133,93 +133,14 @@ static int check_acpi_tpm2(struct device *dev) | |||
| 133 | } | 133 | } |
| 134 | #endif | 134 | #endif |
| 135 | 135 | ||
| 136 | #ifdef CONFIG_X86 | ||
| 137 | #define INTEL_LEGACY_BLK_BASE_ADDR 0xFED08000 | ||
| 138 | #define ILB_REMAP_SIZE 0x100 | ||
| 139 | #define LPC_CNTRL_REG_OFFSET 0x84 | ||
| 140 | #define LPC_CLKRUN_EN (1 << 2) | ||
| 141 | |||
| 142 | static void __iomem *ilb_base_addr; | ||
| 143 | |||
| 144 | static inline bool is_bsw(void) | ||
| 145 | { | ||
| 146 | return ((boot_cpu_data.x86_model == INTEL_FAM6_ATOM_AIRMONT) ? 1 : 0); | ||
| 147 | } | ||
| 148 | |||
| 149 | /** | ||
| 150 | * tpm_platform_begin_xfer() - clear LPC CLKRUN_EN i.e. clocks will be running | ||
| 151 | */ | ||
| 152 | static void tpm_platform_begin_xfer(void) | ||
| 153 | { | ||
| 154 | u32 clkrun_val; | ||
| 155 | |||
| 156 | if (!is_bsw()) | ||
| 157 | return; | ||
| 158 | |||
| 159 | clkrun_val = ioread32(ilb_base_addr + LPC_CNTRL_REG_OFFSET); | ||
| 160 | |||
| 161 | /* Disable LPC CLKRUN# */ | ||
| 162 | clkrun_val &= ~LPC_CLKRUN_EN; | ||
| 163 | iowrite32(clkrun_val, ilb_base_addr + LPC_CNTRL_REG_OFFSET); | ||
| 164 | |||
| 165 | /* | ||
| 166 | * Write any random value on port 0x80 which is on LPC, to make | ||
| 167 | * sure LPC clock is running before sending any TPM command. | ||
| 168 | */ | ||
| 169 | outb(0xCC, 0x80); | ||
| 170 | |||
| 171 | } | ||
| 172 | |||
| 173 | /** | ||
| 174 | * tpm_platform_end_xfer() - set LPC CLKRUN_EN i.e. clocks can be turned off | ||
| 175 | */ | ||
| 176 | static void tpm_platform_end_xfer(void) | ||
| 177 | { | ||
| 178 | u32 clkrun_val; | ||
| 179 | |||
| 180 | if (!is_bsw()) | ||
| 181 | return; | ||
| 182 | |||
| 183 | clkrun_val = ioread32(ilb_base_addr + LPC_CNTRL_REG_OFFSET); | ||
| 184 | |||
| 185 | /* Enable LPC CLKRUN# */ | ||
| 186 | clkrun_val |= LPC_CLKRUN_EN; | ||
| 187 | iowrite32(clkrun_val, ilb_base_addr + LPC_CNTRL_REG_OFFSET); | ||
| 188 | |||
| 189 | /* | ||
| 190 | * Write any random value on port 0x80 which is on LPC, to make | ||
| 191 | * sure LPC clock is running before sending any TPM command. | ||
| 192 | */ | ||
| 193 | outb(0xCC, 0x80); | ||
| 194 | |||
| 195 | } | ||
| 196 | #else | ||
| 197 | static inline bool is_bsw(void) | ||
| 198 | { | ||
| 199 | return false; | ||
| 200 | } | ||
| 201 | |||
| 202 | static void tpm_platform_begin_xfer(void) | ||
| 203 | { | ||
| 204 | } | ||
| 205 | |||
| 206 | static void tpm_platform_end_xfer(void) | ||
| 207 | { | ||
| 208 | } | ||
| 209 | #endif | ||
| 210 | |||
| 211 | static int tpm_tcg_read_bytes(struct tpm_tis_data *data, u32 addr, u16 len, | 136 | static int tpm_tcg_read_bytes(struct tpm_tis_data *data, u32 addr, u16 len, |
| 212 | u8 *result) | 137 | u8 *result) |
| 213 | { | 138 | { |
| 214 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); | 139 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); |
| 215 | 140 | ||
| 216 | tpm_platform_begin_xfer(); | ||
| 217 | |||
| 218 | while (len--) | 141 | while (len--) |
| 219 | *result++ = ioread8(phy->iobase + addr); | 142 | *result++ = ioread8(phy->iobase + addr); |
| 220 | 143 | ||
| 221 | tpm_platform_end_xfer(); | ||
| 222 | |||
| 223 | return 0; | 144 | return 0; |
| 224 | } | 145 | } |
| 225 | 146 | ||
| @@ -228,13 +149,9 @@ static int tpm_tcg_write_bytes(struct tpm_tis_data *data, u32 addr, u16 len, | |||
| 228 | { | 149 | { |
| 229 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); | 150 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); |
| 230 | 151 | ||
| 231 | tpm_platform_begin_xfer(); | ||
| 232 | |||
| 233 | while (len--) | 152 | while (len--) |
| 234 | iowrite8(*value++, phy->iobase + addr); | 153 | iowrite8(*value++, phy->iobase + addr); |
| 235 | 154 | ||
| 236 | tpm_platform_end_xfer(); | ||
| 237 | |||
| 238 | return 0; | 155 | return 0; |
| 239 | } | 156 | } |
| 240 | 157 | ||
| @@ -242,12 +159,8 @@ static int tpm_tcg_read16(struct tpm_tis_data *data, u32 addr, u16 *result) | |||
| 242 | { | 159 | { |
| 243 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); | 160 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); |
| 244 | 161 | ||
| 245 | tpm_platform_begin_xfer(); | ||
| 246 | |||
| 247 | *result = ioread16(phy->iobase + addr); | 162 | *result = ioread16(phy->iobase + addr); |
| 248 | 163 | ||
| 249 | tpm_platform_end_xfer(); | ||
| 250 | |||
| 251 | return 0; | 164 | return 0; |
| 252 | } | 165 | } |
| 253 | 166 | ||
| @@ -255,12 +168,8 @@ static int tpm_tcg_read32(struct tpm_tis_data *data, u32 addr, u32 *result) | |||
| 255 | { | 168 | { |
| 256 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); | 169 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); |
| 257 | 170 | ||
| 258 | tpm_platform_begin_xfer(); | ||
| 259 | |||
| 260 | *result = ioread32(phy->iobase + addr); | 171 | *result = ioread32(phy->iobase + addr); |
| 261 | 172 | ||
| 262 | tpm_platform_end_xfer(); | ||
| 263 | |||
| 264 | return 0; | 173 | return 0; |
| 265 | } | 174 | } |
| 266 | 175 | ||
| @@ -268,12 +177,8 @@ static int tpm_tcg_write32(struct tpm_tis_data *data, u32 addr, u32 value) | |||
| 268 | { | 177 | { |
| 269 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); | 178 | struct tpm_tis_tcg_phy *phy = to_tpm_tis_tcg_phy(data); |
| 270 | 179 | ||
| 271 | tpm_platform_begin_xfer(); | ||
| 272 | |||
| 273 | iowrite32(value, phy->iobase + addr); | 180 | iowrite32(value, phy->iobase + addr); |
| 274 | 181 | ||
| 275 | tpm_platform_end_xfer(); | ||
| 276 | |||
| 277 | return 0; | 182 | return 0; |
| 278 | } | 183 | } |
| 279 | 184 | ||
| @@ -461,11 +366,6 @@ static int __init init_tis(void) | |||
| 461 | if (rc) | 366 | if (rc) |
| 462 | goto err_force; | 367 | goto err_force; |
| 463 | 368 | ||
| 464 | #ifdef CONFIG_X86 | ||
| 465 | if (is_bsw()) | ||
| 466 | ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR, | ||
| 467 | ILB_REMAP_SIZE); | ||
| 468 | #endif | ||
| 469 | rc = platform_driver_register(&tis_drv); | 369 | rc = platform_driver_register(&tis_drv); |
| 470 | if (rc) | 370 | if (rc) |
| 471 | goto err_platform; | 371 | goto err_platform; |
| @@ -484,10 +384,6 @@ err_pnp: | |||
| 484 | err_platform: | 384 | err_platform: |
| 485 | if (force_pdev) | 385 | if (force_pdev) |
| 486 | platform_device_unregister(force_pdev); | 386 | platform_device_unregister(force_pdev); |
| 487 | #ifdef CONFIG_X86 | ||
| 488 | if (is_bsw()) | ||
| 489 | iounmap(ilb_base_addr); | ||
| 490 | #endif | ||
| 491 | err_force: | 387 | err_force: |
| 492 | return rc; | 388 | return rc; |
| 493 | } | 389 | } |
| @@ -497,10 +393,6 @@ static void __exit cleanup_tis(void) | |||
| 497 | pnp_unregister_driver(&tis_pnp_driver); | 393 | pnp_unregister_driver(&tis_pnp_driver); |
| 498 | platform_driver_unregister(&tis_drv); | 394 | platform_driver_unregister(&tis_drv); |
| 499 | 395 | ||
| 500 | #ifdef CONFIG_X86 | ||
| 501 | if (is_bsw()) | ||
| 502 | iounmap(ilb_base_addr); | ||
| 503 | #endif | ||
| 504 | if (force_pdev) | 396 | if (force_pdev) |
| 505 | platform_device_unregister(force_pdev); | 397 | platform_device_unregister(force_pdev); |
| 506 | } | 398 | } |
diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c index fdde971bc810..183a5f54d875 100644 --- a/drivers/char/tpm/tpm_tis_core.c +++ b/drivers/char/tpm/tpm_tis_core.c | |||
| @@ -31,6 +31,74 @@ | |||
| 31 | #include "tpm.h" | 31 | #include "tpm.h" |
| 32 | #include "tpm_tis_core.h" | 32 | #include "tpm_tis_core.h" |
| 33 | 33 | ||
| 34 | /* This is a polling delay to check for status and burstcount. | ||
| 35 | * As per ddwg input, expectation is that status check and burstcount | ||
| 36 | * check should return within few usecs. | ||
| 37 | */ | ||
| 38 | #define TPM_POLL_SLEEP 1 /* msec */ | ||
| 39 | |||
| 40 | static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value); | ||
| 41 | |||
| 42 | static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask, | ||
| 43 | bool check_cancel, bool *canceled) | ||
| 44 | { | ||
| 45 | u8 status = chip->ops->status(chip); | ||
| 46 | |||
| 47 | *canceled = false; | ||
| 48 | if ((status & mask) == mask) | ||
| 49 | return true; | ||
| 50 | if (check_cancel && chip->ops->req_canceled(chip, status)) { | ||
| 51 | *canceled = true; | ||
| 52 | return true; | ||
| 53 | } | ||
| 54 | return false; | ||
| 55 | } | ||
| 56 | |||
| 57 | static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, | ||
| 58 | unsigned long timeout, wait_queue_head_t *queue, | ||
| 59 | bool check_cancel) | ||
| 60 | { | ||
| 61 | unsigned long stop; | ||
| 62 | long rc; | ||
| 63 | u8 status; | ||
| 64 | bool canceled = false; | ||
| 65 | |||
| 66 | /* check current status */ | ||
| 67 | status = chip->ops->status(chip); | ||
| 68 | if ((status & mask) == mask) | ||
| 69 | return 0; | ||
| 70 | |||
| 71 | stop = jiffies + timeout; | ||
| 72 | |||
| 73 | if (chip->flags & TPM_CHIP_FLAG_IRQ) { | ||
| 74 | again: | ||
| 75 | timeout = stop - jiffies; | ||
| 76 | if ((long)timeout <= 0) | ||
| 77 | return -ETIME; | ||
| 78 | rc = wait_event_interruptible_timeout(*queue, | ||
| 79 | wait_for_tpm_stat_cond(chip, mask, check_cancel, | ||
| 80 | &canceled), | ||
| 81 | timeout); | ||
| 82 | if (rc > 0) { | ||
| 83 | if (canceled) | ||
| 84 | return -ECANCELED; | ||
| 85 | return 0; | ||
| 86 | } | ||
| 87 | if (rc == -ERESTARTSYS && freezing(current)) { | ||
| 88 | clear_thread_flag(TIF_SIGPENDING); | ||
| 89 | goto again; | ||
| 90 | } | ||
| 91 | } else { | ||
| 92 | do { | ||
| 93 | tpm_msleep(TPM_POLL_SLEEP); | ||
| 94 | status = chip->ops->status(chip); | ||
| 95 | if ((status & mask) == mask) | ||
| 96 | return 0; | ||
| 97 | } while (time_before(jiffies, stop)); | ||
| 98 | } | ||
| 99 | return -ETIME; | ||
| 100 | } | ||
| 101 | |||
| 34 | /* Before we attempt to access the TPM we must see that the valid bit is set. | 102 | /* Before we attempt to access the TPM we must see that the valid bit is set. |
| 35 | * The specification says that this bit is 0 at reset and remains 0 until the | 103 | * The specification says that this bit is 0 at reset and remains 0 until the |
| 36 | * 'TPM has gone through its self test and initialization and has established | 104 | * 'TPM has gone through its self test and initialization and has established |
| @@ -164,7 +232,7 @@ static int get_burstcount(struct tpm_chip *chip) | |||
| 164 | burstcnt = (value >> 8) & 0xFFFF; | 232 | burstcnt = (value >> 8) & 0xFFFF; |
| 165 | if (burstcnt) | 233 | if (burstcnt) |
| 166 | return burstcnt; | 234 | return burstcnt; |
| 167 | tpm_msleep(TPM_TIMEOUT); | 235 | tpm_msleep(TPM_POLL_SLEEP); |
| 168 | } while (time_before(jiffies, stop)); | 236 | } while (time_before(jiffies, stop)); |
| 169 | return -EBUSY; | 237 | return -EBUSY; |
| 170 | } | 238 | } |
| @@ -421,19 +489,28 @@ static bool tpm_tis_update_timeouts(struct tpm_chip *chip, | |||
| 421 | int i, rc; | 489 | int i, rc; |
| 422 | u32 did_vid; | 490 | u32 did_vid; |
| 423 | 491 | ||
| 492 | if (chip->ops->clk_enable != NULL) | ||
| 493 | chip->ops->clk_enable(chip, true); | ||
| 494 | |||
| 424 | rc = tpm_tis_read32(priv, TPM_DID_VID(0), &did_vid); | 495 | rc = tpm_tis_read32(priv, TPM_DID_VID(0), &did_vid); |
| 425 | if (rc < 0) | 496 | if (rc < 0) |
| 426 | return rc; | 497 | goto out; |
| 427 | 498 | ||
| 428 | for (i = 0; i != ARRAY_SIZE(vendor_timeout_overrides); i++) { | 499 | for (i = 0; i != ARRAY_SIZE(vendor_timeout_overrides); i++) { |
| 429 | if (vendor_timeout_overrides[i].did_vid != did_vid) | 500 | if (vendor_timeout_overrides[i].did_vid != did_vid) |
| 430 | continue; | 501 | continue; |
| 431 | memcpy(timeout_cap, vendor_timeout_overrides[i].timeout_us, | 502 | memcpy(timeout_cap, vendor_timeout_overrides[i].timeout_us, |
| 432 | sizeof(vendor_timeout_overrides[i].timeout_us)); | 503 | sizeof(vendor_timeout_overrides[i].timeout_us)); |
| 433 | return true; | 504 | rc = true; |
| 434 | } | 505 | } |
| 435 | 506 | ||
| 436 | return false; | 507 | rc = false; |
| 508 | |||
| 509 | out: | ||
| 510 | if (chip->ops->clk_enable != NULL) | ||
| 511 | chip->ops->clk_enable(chip, false); | ||
| 512 | |||
| 513 | return rc; | ||
| 437 | } | 514 | } |
| 438 | 515 | ||
| 439 | /* | 516 | /* |
| @@ -653,14 +730,73 @@ void tpm_tis_remove(struct tpm_chip *chip) | |||
| 653 | u32 interrupt; | 730 | u32 interrupt; |
| 654 | int rc; | 731 | int rc; |
| 655 | 732 | ||
| 733 | tpm_tis_clkrun_enable(chip, true); | ||
| 734 | |||
| 656 | rc = tpm_tis_read32(priv, reg, &interrupt); | 735 | rc = tpm_tis_read32(priv, reg, &interrupt); |
| 657 | if (rc < 0) | 736 | if (rc < 0) |
| 658 | interrupt = 0; | 737 | interrupt = 0; |
| 659 | 738 | ||
| 660 | tpm_tis_write32(priv, reg, ~TPM_GLOBAL_INT_ENABLE & interrupt); | 739 | tpm_tis_write32(priv, reg, ~TPM_GLOBAL_INT_ENABLE & interrupt); |
| 740 | |||
| 741 | tpm_tis_clkrun_enable(chip, false); | ||
| 742 | |||
| 743 | if (priv->ilb_base_addr) | ||
| 744 | iounmap(priv->ilb_base_addr); | ||
| 661 | } | 745 | } |
| 662 | EXPORT_SYMBOL_GPL(tpm_tis_remove); | 746 | EXPORT_SYMBOL_GPL(tpm_tis_remove); |
| 663 | 747 | ||
| 748 | /** | ||
| 749 | * tpm_tis_clkrun_enable() - Keep clkrun protocol disabled for entire duration | ||
| 750 | * of a single TPM command | ||
| 751 | * @chip: TPM chip to use | ||
| 752 | * @value: 1 - Disable CLKRUN protocol, so that clocks are free running | ||
| 753 | * 0 - Enable CLKRUN protocol | ||
| 754 | * Call this function directly in tpm_tis_remove() in error or driver removal | ||
| 755 | * path, since the chip->ops is set to NULL in tpm_chip_unregister(). | ||
| 756 | */ | ||
| 757 | static void tpm_tis_clkrun_enable(struct tpm_chip *chip, bool value) | ||
| 758 | { | ||
| 759 | struct tpm_tis_data *data = dev_get_drvdata(&chip->dev); | ||
| 760 | u32 clkrun_val; | ||
| 761 | |||
| 762 | if (!IS_ENABLED(CONFIG_X86) || !is_bsw() || | ||
| 763 | !data->ilb_base_addr) | ||
| 764 | return; | ||
| 765 | |||
| 766 | if (value) { | ||
| 767 | data->clkrun_enabled++; | ||
| 768 | if (data->clkrun_enabled > 1) | ||
| 769 | return; | ||
| 770 | clkrun_val = ioread32(data->ilb_base_addr + LPC_CNTRL_OFFSET); | ||
| 771 | |||
| 772 | /* Disable LPC CLKRUN# */ | ||
| 773 | clkrun_val &= ~LPC_CLKRUN_EN; | ||
| 774 | iowrite32(clkrun_val, data->ilb_base_addr + LPC_CNTRL_OFFSET); | ||
| 775 | |||
| 776 | /* | ||
| 777 | * Write any random value on port 0x80 which is on LPC, to make | ||
| 778 | * sure LPC clock is running before sending any TPM command. | ||
| 779 | */ | ||
| 780 | outb(0xCC, 0x80); | ||
| 781 | } else { | ||
| 782 | data->clkrun_enabled--; | ||
| 783 | if (data->clkrun_enabled) | ||
| 784 | return; | ||
| 785 | |||
| 786 | clkrun_val = ioread32(data->ilb_base_addr + LPC_CNTRL_OFFSET); | ||
| 787 | |||
| 788 | /* Enable LPC CLKRUN# */ | ||
| 789 | clkrun_val |= LPC_CLKRUN_EN; | ||
| 790 | iowrite32(clkrun_val, data->ilb_base_addr + LPC_CNTRL_OFFSET); | ||
| 791 | |||
| 792 | /* | ||
| 793 | * Write any random value on port 0x80 which is on LPC, to make | ||
| 794 | * sure LPC clock is running before sending any TPM command. | ||
| 795 | */ | ||
| 796 | outb(0xCC, 0x80); | ||
| 797 | } | ||
| 798 | } | ||
| 799 | |||
| 664 | static const struct tpm_class_ops tpm_tis = { | 800 | static const struct tpm_class_ops tpm_tis = { |
| 665 | .flags = TPM_OPS_AUTO_STARTUP, | 801 | .flags = TPM_OPS_AUTO_STARTUP, |
| 666 | .status = tpm_tis_status, | 802 | .status = tpm_tis_status, |
| @@ -673,13 +809,17 @@ static const struct tpm_class_ops tpm_tis = { | |||
| 673 | .req_canceled = tpm_tis_req_canceled, | 809 | .req_canceled = tpm_tis_req_canceled, |
| 674 | .request_locality = request_locality, | 810 | .request_locality = request_locality, |
| 675 | .relinquish_locality = release_locality, | 811 | .relinquish_locality = release_locality, |
| 812 | .clk_enable = tpm_tis_clkrun_enable, | ||
| 676 | }; | 813 | }; |
| 677 | 814 | ||
| 678 | int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, | 815 | int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, |
| 679 | const struct tpm_tis_phy_ops *phy_ops, | 816 | const struct tpm_tis_phy_ops *phy_ops, |
| 680 | acpi_handle acpi_dev_handle) | 817 | acpi_handle acpi_dev_handle) |
| 681 | { | 818 | { |
| 682 | u32 vendor, intfcaps, intmask; | 819 | u32 vendor; |
| 820 | u32 intfcaps; | ||
| 821 | u32 intmask; | ||
| 822 | u32 clkrun_val; | ||
| 683 | u8 rid; | 823 | u8 rid; |
| 684 | int rc, probe; | 824 | int rc, probe; |
| 685 | struct tpm_chip *chip; | 825 | struct tpm_chip *chip; |
| @@ -700,6 +840,23 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, | |||
| 700 | priv->phy_ops = phy_ops; | 840 | priv->phy_ops = phy_ops; |
| 701 | dev_set_drvdata(&chip->dev, priv); | 841 | dev_set_drvdata(&chip->dev, priv); |
| 702 | 842 | ||
| 843 | if (is_bsw()) { | ||
| 844 | priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR, | ||
| 845 | ILB_REMAP_SIZE); | ||
| 846 | if (!priv->ilb_base_addr) | ||
| 847 | return -ENOMEM; | ||
| 848 | |||
| 849 | clkrun_val = ioread32(priv->ilb_base_addr + LPC_CNTRL_OFFSET); | ||
| 850 | /* Check if CLKRUN# is already not enabled in the LPC bus */ | ||
| 851 | if (!(clkrun_val & LPC_CLKRUN_EN)) { | ||
| 852 | iounmap(priv->ilb_base_addr); | ||
| 853 | priv->ilb_base_addr = NULL; | ||
| 854 | } | ||
| 855 | } | ||
| 856 | |||
| 857 | if (chip->ops->clk_enable != NULL) | ||
| 858 | chip->ops->clk_enable(chip, true); | ||
| 859 | |||
| 703 | if (wait_startup(chip, 0) != 0) { | 860 | if (wait_startup(chip, 0) != 0) { |
| 704 | rc = -ENODEV; | 861 | rc = -ENODEV; |
| 705 | goto out_err; | 862 | goto out_err; |
| @@ -790,9 +947,20 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, | |||
| 790 | } | 947 | } |
| 791 | } | 948 | } |
| 792 | 949 | ||
| 793 | return tpm_chip_register(chip); | 950 | rc = tpm_chip_register(chip); |
| 951 | if (rc) | ||
| 952 | goto out_err; | ||
| 953 | |||
| 954 | if (chip->ops->clk_enable != NULL) | ||
| 955 | chip->ops->clk_enable(chip, false); | ||
| 956 | |||
| 957 | return 0; | ||
| 794 | out_err: | 958 | out_err: |
| 959 | if ((chip->ops != NULL) && (chip->ops->clk_enable != NULL)) | ||
| 960 | chip->ops->clk_enable(chip, false); | ||
| 961 | |||
| 795 | tpm_tis_remove(chip); | 962 | tpm_tis_remove(chip); |
| 963 | |||
| 796 | return rc; | 964 | return rc; |
| 797 | } | 965 | } |
| 798 | EXPORT_SYMBOL_GPL(tpm_tis_core_init); | 966 | EXPORT_SYMBOL_GPL(tpm_tis_core_init); |
| @@ -804,22 +972,31 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip) | |||
| 804 | u32 intmask; | 972 | u32 intmask; |
| 805 | int rc; | 973 | int rc; |
| 806 | 974 | ||
| 975 | if (chip->ops->clk_enable != NULL) | ||
| 976 | chip->ops->clk_enable(chip, true); | ||
| 977 | |||
| 807 | /* reenable interrupts that device may have lost or | 978 | /* reenable interrupts that device may have lost or |
| 808 | * BIOS/firmware may have disabled | 979 | * BIOS/firmware may have disabled |
| 809 | */ | 980 | */ |
| 810 | rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), priv->irq); | 981 | rc = tpm_tis_write8(priv, TPM_INT_VECTOR(priv->locality), priv->irq); |
| 811 | if (rc < 0) | 982 | if (rc < 0) |
| 812 | return; | 983 | goto out; |
| 813 | 984 | ||
| 814 | rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask); | 985 | rc = tpm_tis_read32(priv, TPM_INT_ENABLE(priv->locality), &intmask); |
| 815 | if (rc < 0) | 986 | if (rc < 0) |
| 816 | return; | 987 | goto out; |
| 817 | 988 | ||
| 818 | intmask |= TPM_INTF_CMD_READY_INT | 989 | intmask |= TPM_INTF_CMD_READY_INT |
| 819 | | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT | 990 | | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT |
| 820 | | TPM_INTF_STS_VALID_INT | TPM_GLOBAL_INT_ENABLE; | 991 | | TPM_INTF_STS_VALID_INT | TPM_GLOBAL_INT_ENABLE; |
| 821 | 992 | ||
| 822 | tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); | 993 | tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); |
| 994 | |||
| 995 | out: | ||
| 996 | if (chip->ops->clk_enable != NULL) | ||
| 997 | chip->ops->clk_enable(chip, false); | ||
| 998 | |||
| 999 | return; | ||
| 823 | } | 1000 | } |
| 824 | 1001 | ||
| 825 | int tpm_tis_resume(struct device *dev) | 1002 | int tpm_tis_resume(struct device *dev) |
diff --git a/drivers/char/tpm/tpm_tis_core.h b/drivers/char/tpm/tpm_tis_core.h index 6bbac319ff3b..d5c6a2e952b3 100644 --- a/drivers/char/tpm/tpm_tis_core.h +++ b/drivers/char/tpm/tpm_tis_core.h | |||
| @@ -79,6 +79,11 @@ enum tis_defaults { | |||
| 79 | #define TPM_DID_VID(l) (0x0F00 | ((l) << 12)) | 79 | #define TPM_DID_VID(l) (0x0F00 | ((l) << 12)) |
| 80 | #define TPM_RID(l) (0x0F04 | ((l) << 12)) | 80 | #define TPM_RID(l) (0x0F04 | ((l) << 12)) |
| 81 | 81 | ||
| 82 | #define LPC_CNTRL_OFFSET 0x84 | ||
| 83 | #define LPC_CLKRUN_EN (1 << 2) | ||
| 84 | #define INTEL_LEGACY_BLK_BASE_ADDR 0xFED08000 | ||
| 85 | #define ILB_REMAP_SIZE 0x100 | ||
| 86 | |||
| 82 | enum tpm_tis_flags { | 87 | enum tpm_tis_flags { |
| 83 | TPM_TIS_ITPM_WORKAROUND = BIT(0), | 88 | TPM_TIS_ITPM_WORKAROUND = BIT(0), |
| 84 | }; | 89 | }; |
| @@ -89,6 +94,8 @@ struct tpm_tis_data { | |||
| 89 | int irq; | 94 | int irq; |
| 90 | bool irq_tested; | 95 | bool irq_tested; |
| 91 | unsigned int flags; | 96 | unsigned int flags; |
| 97 | void __iomem *ilb_base_addr; | ||
| 98 | u16 clkrun_enabled; | ||
| 92 | wait_queue_head_t int_queue; | 99 | wait_queue_head_t int_queue; |
| 93 | wait_queue_head_t read_queue; | 100 | wait_queue_head_t read_queue; |
| 94 | const struct tpm_tis_phy_ops *phy_ops; | 101 | const struct tpm_tis_phy_ops *phy_ops; |
| @@ -144,6 +151,15 @@ static inline int tpm_tis_write32(struct tpm_tis_data *data, u32 addr, | |||
| 144 | return data->phy_ops->write32(data, addr, value); | 151 | return data->phy_ops->write32(data, addr, value); |
| 145 | } | 152 | } |
| 146 | 153 | ||
| 154 | static inline bool is_bsw(void) | ||
| 155 | { | ||
| 156 | #ifdef CONFIG_X86 | ||
| 157 | return ((boot_cpu_data.x86_model == INTEL_FAM6_ATOM_AIRMONT) ? 1 : 0); | ||
| 158 | #else | ||
| 159 | return false; | ||
| 160 | #endif | ||
| 161 | } | ||
| 162 | |||
| 147 | void tpm_tis_remove(struct tpm_chip *chip); | 163 | void tpm_tis_remove(struct tpm_chip *chip); |
| 148 | int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, | 164 | int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, |
| 149 | const struct tpm_tis_phy_ops *phy_ops, | 165 | const struct tpm_tis_phy_ops *phy_ops, |
diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c index 656e8af95d52..911475d36800 100644 --- a/drivers/char/tpm/xen-tpmfront.c +++ b/drivers/char/tpm/xen-tpmfront.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
| 11 | #include <linux/err.h> | 11 | #include <linux/err.h> |
| 12 | #include <linux/interrupt.h> | 12 | #include <linux/interrupt.h> |
| 13 | #include <linux/freezer.h> | ||
| 13 | #include <xen/xen.h> | 14 | #include <xen/xen.h> |
| 14 | #include <xen/events.h> | 15 | #include <xen/events.h> |
| 15 | #include <xen/interface/io/tpmif.h> | 16 | #include <xen/interface/io/tpmif.h> |
| @@ -39,6 +40,66 @@ enum status_bits { | |||
| 39 | VTPM_STATUS_CANCELED = 0x8, | 40 | VTPM_STATUS_CANCELED = 0x8, |
| 40 | }; | 41 | }; |
| 41 | 42 | ||
| 43 | static bool wait_for_tpm_stat_cond(struct tpm_chip *chip, u8 mask, | ||
| 44 | bool check_cancel, bool *canceled) | ||
| 45 | { | ||
| 46 | u8 status = chip->ops->status(chip); | ||
| 47 | |||
| 48 | *canceled = false; | ||
| 49 | if ((status & mask) == mask) | ||
| 50 | return true; | ||
| 51 | if (check_cancel && chip->ops->req_canceled(chip, status)) { | ||
| 52 | *canceled = true; | ||
| 53 | return true; | ||
| 54 | } | ||
| 55 | return false; | ||
| 56 | } | ||
| 57 | |||
| 58 | static int wait_for_tpm_stat(struct tpm_chip *chip, u8 mask, | ||
| 59 | unsigned long timeout, wait_queue_head_t *queue, | ||
| 60 | bool check_cancel) | ||
| 61 | { | ||
| 62 | unsigned long stop; | ||
| 63 | long rc; | ||
| 64 | u8 status; | ||
| 65 | bool canceled = false; | ||
| 66 | |||
| 67 | /* check current status */ | ||
| 68 | status = chip->ops->status(chip); | ||
| 69 | if ((status & mask) == mask) | ||
| 70 | return 0; | ||
| 71 | |||
| 72 | stop = jiffies + timeout; | ||
| 73 | |||
| 74 | if (chip->flags & TPM_CHIP_FLAG_IRQ) { | ||
| 75 | again: | ||
| 76 | timeout = stop - jiffies; | ||
| 77 | if ((long)timeout <= 0) | ||
| 78 | return -ETIME; | ||
| 79 | rc = wait_event_interruptible_timeout(*queue, | ||
| 80 | wait_for_tpm_stat_cond(chip, mask, check_cancel, | ||
| 81 | &canceled), | ||
| 82 | timeout); | ||
| 83 | if (rc > 0) { | ||
| 84 | if (canceled) | ||
| 85 | return -ECANCELED; | ||
| 86 | return 0; | ||
| 87 | } | ||
| 88 | if (rc == -ERESTARTSYS && freezing(current)) { | ||
| 89 | clear_thread_flag(TIF_SIGPENDING); | ||
| 90 | goto again; | ||
| 91 | } | ||
| 92 | } else { | ||
| 93 | do { | ||
| 94 | tpm_msleep(TPM_TIMEOUT); | ||
| 95 | status = chip->ops->status(chip); | ||
| 96 | if ((status & mask) == mask) | ||
| 97 | return 0; | ||
| 98 | } while (time_before(jiffies, stop)); | ||
| 99 | } | ||
| 100 | return -ETIME; | ||
| 101 | } | ||
| 102 | |||
| 42 | static u8 vtpm_status(struct tpm_chip *chip) | 103 | static u8 vtpm_status(struct tpm_chip *chip) |
| 43 | { | 104 | { |
| 44 | struct tpm_private *priv = dev_get_drvdata(&chip->dev); | 105 | struct tpm_private *priv = dev_get_drvdata(&chip->dev); |
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile index 269501dfba53..1d7226fb7d2f 100644 --- a/drivers/firmware/efi/Makefile +++ b/drivers/firmware/efi/Makefile | |||
| @@ -11,7 +11,7 @@ | |||
| 11 | KASAN_SANITIZE_runtime-wrappers.o := n | 11 | KASAN_SANITIZE_runtime-wrappers.o := n |
| 12 | 12 | ||
| 13 | obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o | 13 | obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o |
| 14 | obj-$(CONFIG_EFI) += efi.o vars.o reboot.o memattr.o | 14 | obj-$(CONFIG_EFI) += efi.o vars.o reboot.o memattr.o tpm.o |
| 15 | obj-$(CONFIG_EFI) += capsule.o memmap.o | 15 | obj-$(CONFIG_EFI) += capsule.o memmap.o |
| 16 | obj-$(CONFIG_EFI_VARS) += efivars.o | 16 | obj-$(CONFIG_EFI_VARS) += efivars.o |
| 17 | obj-$(CONFIG_EFI_ESRT) += esrt.o | 17 | obj-$(CONFIG_EFI_ESRT) += esrt.o |
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c index 557a47829d03..cfa6fe786ab6 100644 --- a/drivers/firmware/efi/efi.c +++ b/drivers/firmware/efi/efi.c | |||
| @@ -52,6 +52,7 @@ struct efi __read_mostly efi = { | |||
| 52 | .properties_table = EFI_INVALID_TABLE_ADDR, | 52 | .properties_table = EFI_INVALID_TABLE_ADDR, |
| 53 | .mem_attr_table = EFI_INVALID_TABLE_ADDR, | 53 | .mem_attr_table = EFI_INVALID_TABLE_ADDR, |
| 54 | .rng_seed = EFI_INVALID_TABLE_ADDR, | 54 | .rng_seed = EFI_INVALID_TABLE_ADDR, |
| 55 | .tpm_log = EFI_INVALID_TABLE_ADDR | ||
| 55 | }; | 56 | }; |
| 56 | EXPORT_SYMBOL(efi); | 57 | EXPORT_SYMBOL(efi); |
| 57 | 58 | ||
| @@ -464,6 +465,7 @@ static __initdata efi_config_table_type_t common_tables[] = { | |||
| 464 | {EFI_PROPERTIES_TABLE_GUID, "PROP", &efi.properties_table}, | 465 | {EFI_PROPERTIES_TABLE_GUID, "PROP", &efi.properties_table}, |
| 465 | {EFI_MEMORY_ATTRIBUTES_TABLE_GUID, "MEMATTR", &efi.mem_attr_table}, | 466 | {EFI_MEMORY_ATTRIBUTES_TABLE_GUID, "MEMATTR", &efi.mem_attr_table}, |
| 466 | {LINUX_EFI_RANDOM_SEED_TABLE_GUID, "RNG", &efi.rng_seed}, | 467 | {LINUX_EFI_RANDOM_SEED_TABLE_GUID, "RNG", &efi.rng_seed}, |
| 468 | {LINUX_EFI_TPM_EVENT_LOG_GUID, "TPMEventLog", &efi.tpm_log}, | ||
| 467 | {NULL_GUID, NULL, NULL}, | 469 | {NULL_GUID, NULL, NULL}, |
| 468 | }; | 470 | }; |
| 469 | 471 | ||
| @@ -552,6 +554,8 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz, | |||
| 552 | if (efi_enabled(EFI_MEMMAP)) | 554 | if (efi_enabled(EFI_MEMMAP)) |
| 553 | efi_memattr_init(); | 555 | efi_memattr_init(); |
| 554 | 556 | ||
| 557 | efi_tpm_eventlog_init(); | ||
| 558 | |||
| 555 | /* Parse the EFI Properties table if it exists */ | 559 | /* Parse the EFI Properties table if it exists */ |
| 556 | if (efi.properties_table != EFI_INVALID_TABLE_ADDR) { | 560 | if (efi.properties_table != EFI_INVALID_TABLE_ADDR) { |
| 557 | efi_properties_table_t *tbl; | 561 | efi_properties_table_t *tbl; |
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index adaa4a964f0c..7b3ba40f0745 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile | |||
| @@ -30,8 +30,7 @@ OBJECT_FILES_NON_STANDARD := y | |||
| 30 | # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in. | 30 | # Prevents link failures: __sanitizer_cov_trace_pc() is not linked in. |
| 31 | KCOV_INSTRUMENT := n | 31 | KCOV_INSTRUMENT := n |
| 32 | 32 | ||
| 33 | lib-y := efi-stub-helper.o gop.o secureboot.o | 33 | lib-y := efi-stub-helper.o gop.o secureboot.o tpm.o |
| 34 | lib-$(CONFIG_RESET_ATTACK_MITIGATION) += tpm.o | ||
| 35 | 34 | ||
| 36 | # include the stub's generic dependencies from lib/ when building for ARM/arm64 | 35 | # include the stub's generic dependencies from lib/ when building for ARM/arm64 |
| 37 | arm-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c | 36 | arm-deps-y := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c |
diff --git a/drivers/firmware/efi/libstub/tpm.c b/drivers/firmware/efi/libstub/tpm.c index 6224cdbc9669..da661bf8cb96 100644 --- a/drivers/firmware/efi/libstub/tpm.c +++ b/drivers/firmware/efi/libstub/tpm.c | |||
| @@ -4,15 +4,18 @@ | |||
| 4 | * Copyright (C) 2016 CoreOS, Inc | 4 | * Copyright (C) 2016 CoreOS, Inc |
| 5 | * Copyright (C) 2017 Google, Inc. | 5 | * Copyright (C) 2017 Google, Inc. |
| 6 | * Matthew Garrett <mjg59@google.com> | 6 | * Matthew Garrett <mjg59@google.com> |
| 7 | * Thiebaud Weksteen <tweek@google.com> | ||
| 7 | * | 8 | * |
| 8 | * This file is part of the Linux kernel, and is made available under the | 9 | * This file is part of the Linux kernel, and is made available under the |
| 9 | * terms of the GNU General Public License version 2. | 10 | * terms of the GNU General Public License version 2. |
| 10 | */ | 11 | */ |
| 11 | #include <linux/efi.h> | 12 | #include <linux/efi.h> |
| 13 | #include <linux/tpm_eventlog.h> | ||
| 12 | #include <asm/efi.h> | 14 | #include <asm/efi.h> |
| 13 | 15 | ||
| 14 | #include "efistub.h" | 16 | #include "efistub.h" |
| 15 | 17 | ||
| 18 | #ifdef CONFIG_RESET_ATTACK_MITIGATION | ||
| 16 | static const efi_char16_t efi_MemoryOverWriteRequest_name[] = { | 19 | static const efi_char16_t efi_MemoryOverWriteRequest_name[] = { |
| 17 | 'M', 'e', 'm', 'o', 'r', 'y', 'O', 'v', 'e', 'r', 'w', 'r', 'i', 't', | 20 | 'M', 'e', 'm', 'o', 'r', 'y', 'O', 'v', 'e', 'r', 'w', 'r', 'i', 't', |
| 18 | 'e', 'R', 'e', 'q', 'u', 'e', 's', 't', 'C', 'o', 'n', 't', 'r', 'o', | 21 | 'e', 'R', 'e', 'q', 'u', 'e', 's', 't', 'C', 'o', 'n', 't', 'r', 'o', |
| @@ -56,3 +59,81 @@ void efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg) | |||
| 56 | EFI_VARIABLE_BOOTSERVICE_ACCESS | | 59 | EFI_VARIABLE_BOOTSERVICE_ACCESS | |
| 57 | EFI_VARIABLE_RUNTIME_ACCESS, sizeof(val), &val); | 60 | EFI_VARIABLE_RUNTIME_ACCESS, sizeof(val), &val); |
| 58 | } | 61 | } |
| 62 | |||
| 63 | #endif | ||
| 64 | |||
| 65 | void efi_retrieve_tpm2_eventlog_1_2(efi_system_table_t *sys_table_arg) | ||
| 66 | { | ||
| 67 | efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID; | ||
| 68 | efi_guid_t linux_eventlog_guid = LINUX_EFI_TPM_EVENT_LOG_GUID; | ||
| 69 | efi_status_t status; | ||
| 70 | efi_physical_addr_t log_location, log_last_entry; | ||
| 71 | struct linux_efi_tpm_eventlog *log_tbl; | ||
| 72 | unsigned long first_entry_addr, last_entry_addr; | ||
| 73 | size_t log_size, last_entry_size; | ||
| 74 | efi_bool_t truncated; | ||
| 75 | void *tcg2_protocol; | ||
| 76 | |||
| 77 | status = efi_call_early(locate_protocol, &tcg2_guid, NULL, | ||
| 78 | &tcg2_protocol); | ||
| 79 | if (status != EFI_SUCCESS) | ||
| 80 | return; | ||
| 81 | |||
| 82 | status = efi_call_proto(efi_tcg2_protocol, get_event_log, tcg2_protocol, | ||
| 83 | EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2, | ||
| 84 | &log_location, &log_last_entry, &truncated); | ||
| 85 | if (status != EFI_SUCCESS) | ||
| 86 | return; | ||
| 87 | |||
| 88 | if (!log_location) | ||
| 89 | return; | ||
| 90 | first_entry_addr = (unsigned long) log_location; | ||
| 91 | |||
| 92 | /* | ||
| 93 | * We populate the EFI table even if the logs are empty. | ||
| 94 | */ | ||
| 95 | if (!log_last_entry) { | ||
| 96 | log_size = 0; | ||
| 97 | } else { | ||
| 98 | last_entry_addr = (unsigned long) log_last_entry; | ||
| 99 | /* | ||
| 100 | * get_event_log only returns the address of the last entry. | ||
| 101 | * We need to calculate its size to deduce the full size of | ||
| 102 | * the logs. | ||
| 103 | */ | ||
| 104 | last_entry_size = sizeof(struct tcpa_event) + | ||
| 105 | ((struct tcpa_event *) last_entry_addr)->event_size; | ||
| 106 | log_size = log_last_entry - log_location + last_entry_size; | ||
| 107 | } | ||
| 108 | |||
| 109 | /* Allocate space for the logs and copy them. */ | ||
| 110 | status = efi_call_early(allocate_pool, EFI_LOADER_DATA, | ||
| 111 | sizeof(*log_tbl) + log_size, | ||
| 112 | (void **) &log_tbl); | ||
| 113 | |||
| 114 | if (status != EFI_SUCCESS) { | ||
| 115 | efi_printk(sys_table_arg, | ||
| 116 | "Unable to allocate memory for event log\n"); | ||
| 117 | return; | ||
| 118 | } | ||
| 119 | |||
| 120 | memset(log_tbl, 0, sizeof(*log_tbl) + log_size); | ||
| 121 | log_tbl->size = log_size; | ||
| 122 | log_tbl->version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2; | ||
| 123 | memcpy(log_tbl->log, (void *) first_entry_addr, log_size); | ||
| 124 | |||
| 125 | status = efi_call_early(install_configuration_table, | ||
| 126 | &linux_eventlog_guid, log_tbl); | ||
| 127 | if (status != EFI_SUCCESS) | ||
| 128 | goto err_free; | ||
| 129 | return; | ||
| 130 | |||
| 131 | err_free: | ||
| 132 | efi_call_early(free_pool, log_tbl); | ||
| 133 | } | ||
| 134 | |||
| 135 | void efi_retrieve_tpm2_eventlog(efi_system_table_t *sys_table_arg) | ||
| 136 | { | ||
| 137 | /* Only try to retrieve the logs in 1.2 format. */ | ||
| 138 | efi_retrieve_tpm2_eventlog_1_2(sys_table_arg); | ||
| 139 | } | ||
diff --git a/drivers/firmware/efi/tpm.c b/drivers/firmware/efi/tpm.c new file mode 100644 index 000000000000..0cbeb3d46b18 --- /dev/null +++ b/drivers/firmware/efi/tpm.c | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2017 Google, Inc. | ||
| 3 | * Thiebaud Weksteen <tweek@google.com> | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License version 2 as | ||
| 7 | * published by the Free Software Foundation. | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <linux/efi.h> | ||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/memblock.h> | ||
| 13 | |||
| 14 | #include <asm/early_ioremap.h> | ||
| 15 | |||
| 16 | /* | ||
| 17 | * Reserve the memory associated with the TPM Event Log configuration table. | ||
| 18 | */ | ||
| 19 | int __init efi_tpm_eventlog_init(void) | ||
| 20 | { | ||
| 21 | struct linux_efi_tpm_eventlog *log_tbl; | ||
| 22 | unsigned int tbl_size; | ||
| 23 | |||
| 24 | if (efi.tpm_log == EFI_INVALID_TABLE_ADDR) | ||
| 25 | return 0; | ||
| 26 | |||
| 27 | log_tbl = early_memremap(efi.tpm_log, sizeof(*log_tbl)); | ||
| 28 | if (!log_tbl) { | ||
| 29 | pr_err("Failed to map TPM Event Log table @ 0x%lx\n", | ||
| 30 | efi.tpm_log); | ||
| 31 | efi.tpm_log = EFI_INVALID_TABLE_ADDR; | ||
| 32 | return -ENOMEM; | ||
| 33 | } | ||
| 34 | |||
| 35 | tbl_size = sizeof(*log_tbl) + log_tbl->size; | ||
| 36 | memblock_reserve(efi.tpm_log, tbl_size); | ||
| 37 | early_memunmap(log_tbl, sizeof(*log_tbl)); | ||
| 38 | return 0; | ||
| 39 | } | ||
| 40 | |||
diff --git a/include/linux/efi.h b/include/linux/efi.h index d813f7b04da7..dcea82dc4b89 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h | |||
| @@ -473,6 +473,39 @@ typedef struct { | |||
| 473 | u64 get_all; | 473 | u64 get_all; |
| 474 | } apple_properties_protocol_64_t; | 474 | } apple_properties_protocol_64_t; |
| 475 | 475 | ||
| 476 | typedef struct { | ||
| 477 | u32 get_capability; | ||
| 478 | u32 get_event_log; | ||
| 479 | u32 hash_log_extend_event; | ||
| 480 | u32 submit_command; | ||
| 481 | u32 get_active_pcr_banks; | ||
| 482 | u32 set_active_pcr_banks; | ||
| 483 | u32 get_result_of_set_active_pcr_banks; | ||
| 484 | } efi_tcg2_protocol_32_t; | ||
| 485 | |||
| 486 | typedef struct { | ||
| 487 | u64 get_capability; | ||
| 488 | u64 get_event_log; | ||
| 489 | u64 hash_log_extend_event; | ||
| 490 | u64 submit_command; | ||
| 491 | u64 get_active_pcr_banks; | ||
| 492 | u64 set_active_pcr_banks; | ||
| 493 | u64 get_result_of_set_active_pcr_banks; | ||
| 494 | } efi_tcg2_protocol_64_t; | ||
| 495 | |||
| 496 | typedef u32 efi_tcg2_event_log_format; | ||
| 497 | |||
| 498 | typedef struct { | ||
| 499 | void *get_capability; | ||
| 500 | efi_status_t (*get_event_log)(efi_handle_t, efi_tcg2_event_log_format, | ||
| 501 | efi_physical_addr_t *, efi_physical_addr_t *, efi_bool_t *); | ||
| 502 | void *hash_log_extend_event; | ||
| 503 | void *submit_command; | ||
| 504 | void *get_active_pcr_banks; | ||
| 505 | void *set_active_pcr_banks; | ||
| 506 | void *get_result_of_set_active_pcr_banks; | ||
| 507 | } efi_tcg2_protocol_t; | ||
| 508 | |||
| 476 | /* | 509 | /* |
| 477 | * Types and defines for EFI ResetSystem | 510 | * Types and defines for EFI ResetSystem |
| 478 | */ | 511 | */ |
| @@ -623,6 +656,7 @@ void efi_native_runtime_setup(void); | |||
| 623 | #define EFI_MEMORY_ATTRIBUTES_TABLE_GUID EFI_GUID(0xdcfa911d, 0x26eb, 0x469f, 0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20) | 656 | #define EFI_MEMORY_ATTRIBUTES_TABLE_GUID EFI_GUID(0xdcfa911d, 0x26eb, 0x469f, 0xa2, 0x20, 0x38, 0xb7, 0xdc, 0x46, 0x12, 0x20) |
| 624 | #define EFI_CONSOLE_OUT_DEVICE_GUID EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d) | 657 | #define EFI_CONSOLE_OUT_DEVICE_GUID EFI_GUID(0xd3b36f2c, 0xd551, 0x11d4, 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d) |
| 625 | #define APPLE_PROPERTIES_PROTOCOL_GUID EFI_GUID(0x91bd12fe, 0xf6c3, 0x44fb, 0xa5, 0xb7, 0x51, 0x22, 0xab, 0x30, 0x3a, 0xe0) | 658 | #define APPLE_PROPERTIES_PROTOCOL_GUID EFI_GUID(0x91bd12fe, 0xf6c3, 0x44fb, 0xa5, 0xb7, 0x51, 0x22, 0xab, 0x30, 0x3a, 0xe0) |
| 659 | #define EFI_TCG2_PROTOCOL_GUID EFI_GUID(0x607f766c, 0x7455, 0x42be, 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f) | ||
| 626 | 660 | ||
| 627 | #define EFI_IMAGE_SECURITY_DATABASE_GUID EFI_GUID(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f) | 661 | #define EFI_IMAGE_SECURITY_DATABASE_GUID EFI_GUID(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f) |
| 628 | #define EFI_SHIM_LOCK_GUID EFI_GUID(0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23) | 662 | #define EFI_SHIM_LOCK_GUID EFI_GUID(0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23) |
| @@ -635,6 +669,7 @@ void efi_native_runtime_setup(void); | |||
| 635 | #define LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID EFI_GUID(0xe03fc20a, 0x85dc, 0x406e, 0xb9, 0x0e, 0x4a, 0xb5, 0x02, 0x37, 0x1d, 0x95) | 669 | #define LINUX_EFI_ARM_SCREEN_INFO_TABLE_GUID EFI_GUID(0xe03fc20a, 0x85dc, 0x406e, 0xb9, 0x0e, 0x4a, 0xb5, 0x02, 0x37, 0x1d, 0x95) |
| 636 | #define LINUX_EFI_LOADER_ENTRY_GUID EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf, 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f) | 670 | #define LINUX_EFI_LOADER_ENTRY_GUID EFI_GUID(0x4a67b082, 0x0a4c, 0x41cf, 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f) |
| 637 | #define LINUX_EFI_RANDOM_SEED_TABLE_GUID EFI_GUID(0x1ce1e5bc, 0x7ceb, 0x42f2, 0x81, 0xe5, 0x8a, 0xad, 0xf1, 0x80, 0xf5, 0x7b) | 671 | #define LINUX_EFI_RANDOM_SEED_TABLE_GUID EFI_GUID(0x1ce1e5bc, 0x7ceb, 0x42f2, 0x81, 0xe5, 0x8a, 0xad, 0xf1, 0x80, 0xf5, 0x7b) |
| 672 | #define LINUX_EFI_TPM_EVENT_LOG_GUID EFI_GUID(0xb7799cb0, 0xeca2, 0x4943, 0x96, 0x67, 0x1f, 0xae, 0x07, 0xb7, 0x47, 0xfa) | ||
| 638 | 673 | ||
| 639 | typedef struct { | 674 | typedef struct { |
| 640 | efi_guid_t guid; | 675 | efi_guid_t guid; |
| @@ -909,6 +944,7 @@ extern struct efi { | |||
| 909 | unsigned long properties_table; /* properties table */ | 944 | unsigned long properties_table; /* properties table */ |
| 910 | unsigned long mem_attr_table; /* memory attributes table */ | 945 | unsigned long mem_attr_table; /* memory attributes table */ |
| 911 | unsigned long rng_seed; /* UEFI firmware random seed */ | 946 | unsigned long rng_seed; /* UEFI firmware random seed */ |
| 947 | unsigned long tpm_log; /* TPM2 Event Log table */ | ||
| 912 | efi_get_time_t *get_time; | 948 | efi_get_time_t *get_time; |
| 913 | efi_set_time_t *set_time; | 949 | efi_set_time_t *set_time; |
| 914 | efi_get_wakeup_time_t *get_wakeup_time; | 950 | efi_get_wakeup_time_t *get_wakeup_time; |
| @@ -1534,6 +1570,8 @@ static inline void | |||
| 1534 | efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg) { } | 1570 | efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg) { } |
| 1535 | #endif | 1571 | #endif |
| 1536 | 1572 | ||
| 1573 | void efi_retrieve_tpm2_eventlog(efi_system_table_t *sys_table); | ||
| 1574 | |||
| 1537 | /* | 1575 | /* |
| 1538 | * Arch code can implement the following three template macros, avoiding | 1576 | * Arch code can implement the following three template macros, avoiding |
| 1539 | * reptition for the void/non-void return cases of {__,}efi_call_virt(): | 1577 | * reptition for the void/non-void return cases of {__,}efi_call_virt(): |
| @@ -1601,4 +1639,12 @@ struct linux_efi_random_seed { | |||
| 1601 | u8 bits[]; | 1639 | u8 bits[]; |
| 1602 | }; | 1640 | }; |
| 1603 | 1641 | ||
| 1642 | struct linux_efi_tpm_eventlog { | ||
| 1643 | u32 size; | ||
| 1644 | u8 version; | ||
| 1645 | u8 log[]; | ||
| 1646 | }; | ||
| 1647 | |||
| 1648 | extern int efi_tpm_eventlog_init(void); | ||
| 1649 | |||
| 1604 | #endif /* _LINUX_EFI_H */ | 1650 | #endif /* _LINUX_EFI_H */ |
diff --git a/include/linux/tpm.h b/include/linux/tpm.h index 5a090f5ab335..bcdd3790e94d 100644 --- a/include/linux/tpm.h +++ b/include/linux/tpm.h | |||
| @@ -24,11 +24,6 @@ | |||
| 24 | 24 | ||
| 25 | #define TPM_DIGEST_SIZE 20 /* Max TPM v1.2 PCR size */ | 25 | #define TPM_DIGEST_SIZE 20 /* Max TPM v1.2 PCR size */ |
| 26 | 26 | ||
| 27 | /* | ||
| 28 | * Chip num is this value or a valid tpm idx | ||
| 29 | */ | ||
| 30 | #define TPM_ANY_NUM 0xFFFF | ||
| 31 | |||
| 32 | struct tpm_chip; | 27 | struct tpm_chip; |
| 33 | struct trusted_key_payload; | 28 | struct trusted_key_payload; |
| 34 | struct trusted_key_options; | 29 | struct trusted_key_options; |
| @@ -50,46 +45,52 @@ struct tpm_class_ops { | |||
| 50 | unsigned long *timeout_cap); | 45 | unsigned long *timeout_cap); |
| 51 | int (*request_locality)(struct tpm_chip *chip, int loc); | 46 | int (*request_locality)(struct tpm_chip *chip, int loc); |
| 52 | void (*relinquish_locality)(struct tpm_chip *chip, int loc); | 47 | void (*relinquish_locality)(struct tpm_chip *chip, int loc); |
| 48 | void (*clk_enable)(struct tpm_chip *chip, bool value); | ||
| 53 | }; | 49 | }; |
| 54 | 50 | ||
| 55 | #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE) | 51 | #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE) |
| 56 | 52 | ||
| 57 | extern int tpm_is_tpm2(u32 chip_num); | 53 | extern int tpm_is_tpm2(struct tpm_chip *chip); |
| 58 | extern int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf); | 54 | extern int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf); |
| 59 | extern int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash); | 55 | extern int tpm_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash); |
| 60 | extern int tpm_send(u32 chip_num, void *cmd, size_t buflen); | 56 | extern int tpm_send(struct tpm_chip *chip, void *cmd, size_t buflen); |
| 61 | extern int tpm_get_random(u32 chip_num, u8 *data, size_t max); | 57 | extern int tpm_get_random(struct tpm_chip *chip, u8 *data, size_t max); |
| 62 | extern int tpm_seal_trusted(u32 chip_num, | 58 | extern int tpm_seal_trusted(struct tpm_chip *chip, |
| 63 | struct trusted_key_payload *payload, | 59 | struct trusted_key_payload *payload, |
| 64 | struct trusted_key_options *options); | 60 | struct trusted_key_options *options); |
| 65 | extern int tpm_unseal_trusted(u32 chip_num, | 61 | extern int tpm_unseal_trusted(struct tpm_chip *chip, |
| 66 | struct trusted_key_payload *payload, | 62 | struct trusted_key_payload *payload, |
| 67 | struct trusted_key_options *options); | 63 | struct trusted_key_options *options); |
| 68 | #else | 64 | #else |
| 69 | static inline int tpm_is_tpm2(u32 chip_num) | 65 | static inline int tpm_is_tpm2(struct tpm_chip *chip) |
| 70 | { | 66 | { |
| 71 | return -ENODEV; | 67 | return -ENODEV; |
| 72 | } | 68 | } |
| 73 | static inline int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf) { | 69 | static inline int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf) |
| 70 | { | ||
| 74 | return -ENODEV; | 71 | return -ENODEV; |
| 75 | } | 72 | } |
| 76 | static inline int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash) { | 73 | static inline int tpm_pcr_extend(struct tpm_chip *chip, int pcr_idx, |
| 74 | const u8 *hash) | ||
| 75 | { | ||
| 77 | return -ENODEV; | 76 | return -ENODEV; |
| 78 | } | 77 | } |
| 79 | static inline int tpm_send(u32 chip_num, void *cmd, size_t buflen) { | 78 | static inline int tpm_send(struct tpm_chip *chip, void *cmd, size_t buflen) |
| 79 | { | ||
| 80 | return -ENODEV; | 80 | return -ENODEV; |
| 81 | } | 81 | } |
| 82 | static inline int tpm_get_random(u32 chip_num, u8 *data, size_t max) { | 82 | static inline int tpm_get_random(struct tpm_chip *chip, u8 *data, size_t max) |
| 83 | { | ||
| 83 | return -ENODEV; | 84 | return -ENODEV; |
| 84 | } | 85 | } |
| 85 | 86 | ||
| 86 | static inline int tpm_seal_trusted(u32 chip_num, | 87 | static inline int tpm_seal_trusted(struct tpm_chip *chip, |
| 87 | struct trusted_key_payload *payload, | 88 | struct trusted_key_payload *payload, |
| 88 | struct trusted_key_options *options) | 89 | struct trusted_key_options *options) |
| 89 | { | 90 | { |
| 90 | return -ENODEV; | 91 | return -ENODEV; |
| 91 | } | 92 | } |
| 92 | static inline int tpm_unseal_trusted(u32 chip_num, | 93 | static inline int tpm_unseal_trusted(struct tpm_chip *chip, |
| 93 | struct trusted_key_payload *payload, | 94 | struct trusted_key_payload *payload, |
| 94 | struct trusted_key_options *options) | 95 | struct trusted_key_options *options) |
| 95 | { | 96 | { |
diff --git a/drivers/char/tpm/tpm_eventlog.h b/include/linux/tpm_eventlog.h index 204466cc4d05..20d9da77fc11 100644 --- a/drivers/char/tpm/tpm_eventlog.h +++ b/include/linux/tpm_eventlog.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | 2 | ||
| 3 | #ifndef __TPM_EVENTLOG_H__ | 3 | #ifndef __LINUX_TPM_EVENTLOG_H__ |
| 4 | #define __TPM_EVENTLOG_H__ | 4 | #define __LINUX_TPM_EVENTLOG_H__ |
| 5 | 5 | ||
| 6 | #include <crypto/hash_info.h> | 6 | #include <crypto/hash_info.h> |
| 7 | 7 | ||
| @@ -10,6 +10,9 @@ | |||
| 10 | #define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */ | 10 | #define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */ |
| 11 | #define TPM2_ACTIVE_PCR_BANKS 3 | 11 | #define TPM2_ACTIVE_PCR_BANKS 3 |
| 12 | 12 | ||
| 13 | #define EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2 0x1 | ||
| 14 | #define EFI_TCG2_EVENT_LOG_FORMAT_TCG_2 0x2 | ||
| 15 | |||
| 13 | #ifdef CONFIG_PPC64 | 16 | #ifdef CONFIG_PPC64 |
| 14 | #define do_endian_conversion(x) be32_to_cpu(x) | 17 | #define do_endian_conversion(x) be32_to_cpu(x) |
| 15 | #else | 18 | #else |
| @@ -105,6 +108,11 @@ struct tcg_event_field { | |||
| 105 | u8 event[0]; | 108 | u8 event[0]; |
| 106 | } __packed; | 109 | } __packed; |
| 107 | 110 | ||
| 111 | struct tpm2_digest { | ||
| 112 | u16 alg_id; | ||
| 113 | u8 digest[SHA512_DIGEST_SIZE]; | ||
| 114 | } __packed; | ||
| 115 | |||
| 108 | struct tcg_pcr_event2 { | 116 | struct tcg_pcr_event2 { |
| 109 | u32 pcr_idx; | 117 | u32 pcr_idx; |
| 110 | u32 event_type; | 118 | u32 event_type; |
| @@ -113,26 +121,4 @@ struct tcg_pcr_event2 { | |||
| 113 | struct tcg_event_field event; | 121 | struct tcg_event_field event; |
| 114 | } __packed; | 122 | } __packed; |
| 115 | 123 | ||
| 116 | extern const struct seq_operations tpm2_binary_b_measurements_seqops; | ||
| 117 | |||
| 118 | #if defined(CONFIG_ACPI) | ||
| 119 | int tpm_read_log_acpi(struct tpm_chip *chip); | ||
| 120 | #else | ||
| 121 | static inline int tpm_read_log_acpi(struct tpm_chip *chip) | ||
| 122 | { | ||
| 123 | return -ENODEV; | ||
| 124 | } | ||
| 125 | #endif | ||
| 126 | #if defined(CONFIG_OF) | ||
| 127 | int tpm_read_log_of(struct tpm_chip *chip); | ||
| 128 | #else | ||
| 129 | static inline int tpm_read_log_of(struct tpm_chip *chip) | ||
| 130 | { | ||
| 131 | return -ENODEV; | ||
| 132 | } | ||
| 133 | #endif | ||
| 134 | |||
| 135 | int tpm_bios_log_setup(struct tpm_chip *chip); | ||
| 136 | void tpm_bios_log_teardown(struct tpm_chip *chip); | ||
| 137 | |||
| 138 | #endif | 124 | #endif |
diff --git a/security/integrity/ima/ima_crypto.c b/security/integrity/ima/ima_crypto.c index 9057b163c378..205bc69361ea 100644 --- a/security/integrity/ima/ima_crypto.c +++ b/security/integrity/ima/ima_crypto.c | |||
| @@ -632,7 +632,7 @@ static void __init ima_pcrread(int idx, u8 *pcr) | |||
| 632 | if (!ima_used_chip) | 632 | if (!ima_used_chip) |
| 633 | return; | 633 | return; |
| 634 | 634 | ||
| 635 | if (tpm_pcr_read(TPM_ANY_NUM, idx, pcr) != 0) | 635 | if (tpm_pcr_read(NULL, idx, pcr) != 0) |
| 636 | pr_err("Error Communicating to TPM chip\n"); | 636 | pr_err("Error Communicating to TPM chip\n"); |
| 637 | } | 637 | } |
| 638 | 638 | ||
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index 2967d497a665..29b72cd2502e 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c | |||
| @@ -110,7 +110,7 @@ int __init ima_init(void) | |||
| 110 | int rc; | 110 | int rc; |
| 111 | 111 | ||
| 112 | ima_used_chip = 0; | 112 | ima_used_chip = 0; |
| 113 | rc = tpm_pcr_read(TPM_ANY_NUM, 0, pcr_i); | 113 | rc = tpm_pcr_read(NULL, 0, pcr_i); |
| 114 | if (rc == 0) | 114 | if (rc == 0) |
| 115 | ima_used_chip = 1; | 115 | ima_used_chip = 1; |
| 116 | 116 | ||
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index a02a86d51102..418f35e38015 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c | |||
| @@ -145,7 +145,7 @@ static int ima_pcr_extend(const u8 *hash, int pcr) | |||
| 145 | if (!ima_used_chip) | 145 | if (!ima_used_chip) |
| 146 | return result; | 146 | return result; |
| 147 | 147 | ||
| 148 | result = tpm_pcr_extend(TPM_ANY_NUM, pcr, hash); | 148 | result = tpm_pcr_extend(NULL, pcr, hash); |
| 149 | if (result != 0) | 149 | if (result != 0) |
| 150 | pr_err("Error Communicating to TPM chip, result: %d\n", result); | 150 | pr_err("Error Communicating to TPM chip, result: %d\n", result); |
| 151 | return result; | 151 | return result; |
diff --git a/security/keys/trusted.c b/security/keys/trusted.c index 98aa89ff7bfd..423776682025 100644 --- a/security/keys/trusted.c +++ b/security/keys/trusted.c | |||
| @@ -355,13 +355,12 @@ out: | |||
| 355 | * For key specific tpm requests, we will generate and send our | 355 | * For key specific tpm requests, we will generate and send our |
| 356 | * own TPM command packets using the drivers send function. | 356 | * own TPM command packets using the drivers send function. |
| 357 | */ | 357 | */ |
| 358 | static int trusted_tpm_send(const u32 chip_num, unsigned char *cmd, | 358 | static int trusted_tpm_send(unsigned char *cmd, size_t buflen) |
| 359 | size_t buflen) | ||
| 360 | { | 359 | { |
| 361 | int rc; | 360 | int rc; |
| 362 | 361 | ||
| 363 | dump_tpm_buf(cmd); | 362 | dump_tpm_buf(cmd); |
| 364 | rc = tpm_send(chip_num, cmd, buflen); | 363 | rc = tpm_send(NULL, cmd, buflen); |
| 365 | dump_tpm_buf(cmd); | 364 | dump_tpm_buf(cmd); |
| 366 | if (rc > 0) | 365 | if (rc > 0) |
| 367 | /* Can't return positive return codes values to keyctl */ | 366 | /* Can't return positive return codes values to keyctl */ |
| @@ -382,10 +381,10 @@ static int pcrlock(const int pcrnum) | |||
| 382 | 381 | ||
| 383 | if (!capable(CAP_SYS_ADMIN)) | 382 | if (!capable(CAP_SYS_ADMIN)) |
| 384 | return -EPERM; | 383 | return -EPERM; |
| 385 | ret = tpm_get_random(TPM_ANY_NUM, hash, SHA1_DIGEST_SIZE); | 384 | ret = tpm_get_random(NULL, hash, SHA1_DIGEST_SIZE); |
| 386 | if (ret != SHA1_DIGEST_SIZE) | 385 | if (ret != SHA1_DIGEST_SIZE) |
| 387 | return ret; | 386 | return ret; |
| 388 | return tpm_pcr_extend(TPM_ANY_NUM, pcrnum, hash) ? -EINVAL : 0; | 387 | return tpm_pcr_extend(NULL, pcrnum, hash) ? -EINVAL : 0; |
| 389 | } | 388 | } |
| 390 | 389 | ||
| 391 | /* | 390 | /* |
| @@ -398,7 +397,7 @@ static int osap(struct tpm_buf *tb, struct osapsess *s, | |||
| 398 | unsigned char ononce[TPM_NONCE_SIZE]; | 397 | unsigned char ononce[TPM_NONCE_SIZE]; |
| 399 | int ret; | 398 | int ret; |
| 400 | 399 | ||
| 401 | ret = tpm_get_random(TPM_ANY_NUM, ononce, TPM_NONCE_SIZE); | 400 | ret = tpm_get_random(NULL, ononce, TPM_NONCE_SIZE); |
| 402 | if (ret != TPM_NONCE_SIZE) | 401 | if (ret != TPM_NONCE_SIZE) |
| 403 | return ret; | 402 | return ret; |
| 404 | 403 | ||
| @@ -410,7 +409,7 @@ static int osap(struct tpm_buf *tb, struct osapsess *s, | |||
| 410 | store32(tb, handle); | 409 | store32(tb, handle); |
| 411 | storebytes(tb, ononce, TPM_NONCE_SIZE); | 410 | storebytes(tb, ononce, TPM_NONCE_SIZE); |
| 412 | 411 | ||
| 413 | ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, MAX_BUF_SIZE); | 412 | ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE); |
| 414 | if (ret < 0) | 413 | if (ret < 0) |
| 415 | return ret; | 414 | return ret; |
| 416 | 415 | ||
| @@ -434,7 +433,7 @@ static int oiap(struct tpm_buf *tb, uint32_t *handle, unsigned char *nonce) | |||
| 434 | store16(tb, TPM_TAG_RQU_COMMAND); | 433 | store16(tb, TPM_TAG_RQU_COMMAND); |
| 435 | store32(tb, TPM_OIAP_SIZE); | 434 | store32(tb, TPM_OIAP_SIZE); |
| 436 | store32(tb, TPM_ORD_OIAP); | 435 | store32(tb, TPM_ORD_OIAP); |
| 437 | ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, MAX_BUF_SIZE); | 436 | ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE); |
| 438 | if (ret < 0) | 437 | if (ret < 0) |
| 439 | return ret; | 438 | return ret; |
| 440 | 439 | ||
| @@ -493,7 +492,7 @@ static int tpm_seal(struct tpm_buf *tb, uint16_t keytype, | |||
| 493 | if (ret < 0) | 492 | if (ret < 0) |
| 494 | goto out; | 493 | goto out; |
| 495 | 494 | ||
| 496 | ret = tpm_get_random(TPM_ANY_NUM, td->nonceodd, TPM_NONCE_SIZE); | 495 | ret = tpm_get_random(NULL, td->nonceodd, TPM_NONCE_SIZE); |
| 497 | if (ret != TPM_NONCE_SIZE) | 496 | if (ret != TPM_NONCE_SIZE) |
| 498 | goto out; | 497 | goto out; |
| 499 | ordinal = htonl(TPM_ORD_SEAL); | 498 | ordinal = htonl(TPM_ORD_SEAL); |
| @@ -542,7 +541,7 @@ static int tpm_seal(struct tpm_buf *tb, uint16_t keytype, | |||
| 542 | store8(tb, cont); | 541 | store8(tb, cont); |
| 543 | storebytes(tb, td->pubauth, SHA1_DIGEST_SIZE); | 542 | storebytes(tb, td->pubauth, SHA1_DIGEST_SIZE); |
| 544 | 543 | ||
| 545 | ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, MAX_BUF_SIZE); | 544 | ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE); |
| 546 | if (ret < 0) | 545 | if (ret < 0) |
| 547 | goto out; | 546 | goto out; |
| 548 | 547 | ||
| @@ -603,7 +602,7 @@ static int tpm_unseal(struct tpm_buf *tb, | |||
| 603 | 602 | ||
| 604 | ordinal = htonl(TPM_ORD_UNSEAL); | 603 | ordinal = htonl(TPM_ORD_UNSEAL); |
| 605 | keyhndl = htonl(SRKHANDLE); | 604 | keyhndl = htonl(SRKHANDLE); |
| 606 | ret = tpm_get_random(TPM_ANY_NUM, nonceodd, TPM_NONCE_SIZE); | 605 | ret = tpm_get_random(NULL, nonceodd, TPM_NONCE_SIZE); |
| 607 | if (ret != TPM_NONCE_SIZE) { | 606 | if (ret != TPM_NONCE_SIZE) { |
| 608 | pr_info("trusted_key: tpm_get_random failed (%d)\n", ret); | 607 | pr_info("trusted_key: tpm_get_random failed (%d)\n", ret); |
| 609 | return ret; | 608 | return ret; |
| @@ -635,7 +634,7 @@ static int tpm_unseal(struct tpm_buf *tb, | |||
| 635 | store8(tb, cont); | 634 | store8(tb, cont); |
| 636 | storebytes(tb, authdata2, SHA1_DIGEST_SIZE); | 635 | storebytes(tb, authdata2, SHA1_DIGEST_SIZE); |
| 637 | 636 | ||
| 638 | ret = trusted_tpm_send(TPM_ANY_NUM, tb->data, MAX_BUF_SIZE); | 637 | ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE); |
| 639 | if (ret < 0) { | 638 | if (ret < 0) { |
| 640 | pr_info("trusted_key: authhmac failed (%d)\n", ret); | 639 | pr_info("trusted_key: authhmac failed (%d)\n", ret); |
| 641 | return ret; | 640 | return ret; |
| @@ -748,7 +747,7 @@ static int getoptions(char *c, struct trusted_key_payload *pay, | |||
| 748 | int i; | 747 | int i; |
| 749 | int tpm2; | 748 | int tpm2; |
| 750 | 749 | ||
| 751 | tpm2 = tpm_is_tpm2(TPM_ANY_NUM); | 750 | tpm2 = tpm_is_tpm2(NULL); |
| 752 | if (tpm2 < 0) | 751 | if (tpm2 < 0) |
| 753 | return tpm2; | 752 | return tpm2; |
| 754 | 753 | ||
| @@ -917,7 +916,7 @@ static struct trusted_key_options *trusted_options_alloc(void) | |||
| 917 | struct trusted_key_options *options; | 916 | struct trusted_key_options *options; |
| 918 | int tpm2; | 917 | int tpm2; |
| 919 | 918 | ||
| 920 | tpm2 = tpm_is_tpm2(TPM_ANY_NUM); | 919 | tpm2 = tpm_is_tpm2(NULL); |
| 921 | if (tpm2 < 0) | 920 | if (tpm2 < 0) |
| 922 | return NULL; | 921 | return NULL; |
| 923 | 922 | ||
| @@ -967,7 +966,7 @@ static int trusted_instantiate(struct key *key, | |||
| 967 | size_t key_len; | 966 | size_t key_len; |
| 968 | int tpm2; | 967 | int tpm2; |
| 969 | 968 | ||
| 970 | tpm2 = tpm_is_tpm2(TPM_ANY_NUM); | 969 | tpm2 = tpm_is_tpm2(NULL); |
| 971 | if (tpm2 < 0) | 970 | if (tpm2 < 0) |
| 972 | return tpm2; | 971 | return tpm2; |
| 973 | 972 | ||
| @@ -1008,7 +1007,7 @@ static int trusted_instantiate(struct key *key, | |||
| 1008 | switch (key_cmd) { | 1007 | switch (key_cmd) { |
| 1009 | case Opt_load: | 1008 | case Opt_load: |
| 1010 | if (tpm2) | 1009 | if (tpm2) |
| 1011 | ret = tpm_unseal_trusted(TPM_ANY_NUM, payload, options); | 1010 | ret = tpm_unseal_trusted(NULL, payload, options); |
| 1012 | else | 1011 | else |
| 1013 | ret = key_unseal(payload, options); | 1012 | ret = key_unseal(payload, options); |
| 1014 | dump_payload(payload); | 1013 | dump_payload(payload); |
| @@ -1018,13 +1017,13 @@ static int trusted_instantiate(struct key *key, | |||
| 1018 | break; | 1017 | break; |
| 1019 | case Opt_new: | 1018 | case Opt_new: |
| 1020 | key_len = payload->key_len; | 1019 | key_len = payload->key_len; |
| 1021 | ret = tpm_get_random(TPM_ANY_NUM, payload->key, key_len); | 1020 | ret = tpm_get_random(NULL, payload->key, key_len); |
| 1022 | if (ret != key_len) { | 1021 | if (ret != key_len) { |
| 1023 | pr_info("trusted_key: key_create failed (%d)\n", ret); | 1022 | pr_info("trusted_key: key_create failed (%d)\n", ret); |
| 1024 | goto out; | 1023 | goto out; |
| 1025 | } | 1024 | } |
| 1026 | if (tpm2) | 1025 | if (tpm2) |
| 1027 | ret = tpm_seal_trusted(TPM_ANY_NUM, payload, options); | 1026 | ret = tpm_seal_trusted(NULL, payload, options); |
| 1028 | else | 1027 | else |
| 1029 | ret = key_seal(payload, options); | 1028 | ret = key_seal(payload, options); |
| 1030 | if (ret < 0) | 1029 | if (ret < 0) |
