|
7 | 7 | #include "efi-api.h" |
8 | 8 | #include "efivars.h" |
9 | 9 | #include "fd-util.h" |
| 10 | +#include "fileio.h" |
10 | 11 | #include "sort-util.h" |
11 | 12 | #include "stat-util.h" |
12 | 13 | #include "stdio-util.h" |
@@ -481,37 +482,43 @@ int efi_get_boot_options(uint16_t **ret_options) { |
481 | 482 |
|
482 | 483 | bool efi_has_tpm2(void) { |
483 | 484 | static int cache = -1; |
| 485 | + int r; |
484 | 486 |
|
485 | 487 | /* Returns whether the system has a TPM2 chip which is known to the EFI firmware. */ |
486 | 488 |
|
487 | 489 | if (cache >= 0) |
488 | 490 | return cache; |
489 | 491 |
|
490 | 492 | /* First, check if we are on an EFI boot at all. */ |
491 | | - if (!is_efi_boot()) { |
492 | | - cache = 0; |
493 | | - return cache; |
494 | | - } |
| 493 | + if (!is_efi_boot()) |
| 494 | + return (cache = false); |
495 | 495 |
|
496 | 496 | /* Then, check if the ACPI table "TPM2" exists, which is the TPM2 event log table, see: |
497 | 497 | * https://trustedcomputinggroup.org/wp-content/uploads/TCG_ACPIGeneralSpecification_v1.20_r8.pdf |
498 | | - * This table exists whenever the firmware is hooked up to TPM2. */ |
499 | | - cache = access("/sys/firmware/acpi/tables/TPM2", F_OK) >= 0; |
500 | | - if (cache) |
501 | | - return cache; |
502 | | - |
| 498 | + * This table exists whenever the firmware knows ACPI and is hooked up to TPM2. */ |
| 499 | + if (access("/sys/firmware/acpi/tables/TPM2", F_OK) >= 0) |
| 500 | + return (cache = true); |
503 | 501 | if (errno != ENOENT) |
504 | 502 | log_debug_errno(errno, "Unable to test whether /sys/firmware/acpi/tables/TPM2 exists, assuming it doesn't: %m"); |
505 | 503 |
|
506 | 504 | /* As the last try, check if the EFI firmware provides the EFI_TCG2_FINAL_EVENTS_TABLE |
507 | 505 | * stored in EFI configuration table, see: |
508 | | - * https://trustedcomputinggroup.org/wp-content/uploads/EFI-Protocol-Specification-rev13-160330final.pdf |
509 | | - */ |
510 | | - cache = access("/sys/kernel/security/tpm0/binary_bios_measurements", F_OK) >= 0; |
511 | | - if (!cache && errno != ENOENT) |
512 | | - log_debug_errno(errno, "Unable to test whether /sys/kernel/security/tpm0/binary_bios_measurements exists, assuming it doesn't: %m"); |
| 506 | + * |
| 507 | + * https://trustedcomputinggroup.org/wp-content/uploads/EFI-Protocol-Specification-rev13-160330final.pdf */ |
| 508 | + if (access("/sys/kernel/security/tpm0/binary_bios_measurements", F_OK) >= 0) { |
| 509 | + _cleanup_free_ char *major = NULL; |
| 510 | + |
| 511 | + /* The EFI table might exist for TPM 1.2 as well, hence let's check explicitly which TPM version we are looking at here. */ |
| 512 | + r = read_virtual_file("/sys/class/tpm/tpm0/tpm_version_major", SIZE_MAX, &major, /* ret_size= */ NULL); |
| 513 | + if (r >= 0) |
| 514 | + return (cache = streq(strstrip(major), "2")); |
| 515 | + |
| 516 | + log_debug_errno(r, "Unable to read /sys/class/tpm/tpm0/tpm_version_major, assuming TPM does not qualify as TPM2: %m"); |
| 517 | + |
| 518 | + } else if (errno != ENOENT) |
| 519 | + log_debug_errno(errno, "Unable to test whether /sys/kernel/security/tpm0/binary_bios_measurements exists, assuming it doesn't: %m"); |
513 | 520 |
|
514 | | - return cache; |
| 521 | + return (cache = false); |
515 | 522 | } |
516 | 523 |
|
517 | 524 | #endif |
|
0 commit comments