^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2017 Google
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Thiebaud Weksteen <tweek@google.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/efi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/tpm_eventlog.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "../tpm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) /* read binary bios log from EFI configuration table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) int tpm_read_log_efi(struct tpm_chip *chip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct efi_tcg2_final_events_table *final_tbl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) int final_events_log_size = efi_tpm_final_log_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct linux_efi_tpm_eventlog *log_tbl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct tpm_bios_log *log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) u32 log_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) u8 tpm_log_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) void *tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) if (!(chip->flags & TPM_CHIP_FLAG_TPM2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) if (efi.tpm_log == EFI_INVALID_TABLE_ADDR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) log = &chip->log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) log_tbl = memremap(efi.tpm_log, sizeof(*log_tbl), MEMREMAP_WB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) if (!log_tbl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) pr_err("Could not map UEFI TPM log table !\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) log_size = log_tbl->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) memunmap(log_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (!log_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) pr_warn("UEFI TPM log area empty\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) log_tbl = memremap(efi.tpm_log, sizeof(*log_tbl) + log_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) MEMREMAP_WB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (!log_tbl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) pr_err("Could not map UEFI TPM log table payload!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /* malloc EventLog space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) log->bios_event_log = kmemdup(log_tbl->log, log_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (!log->bios_event_log) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) log->bios_event_log_end = log->bios_event_log + log_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) tpm_log_version = log_tbl->version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) ret = tpm_log_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (efi.tpm_final_log == EFI_INVALID_TABLE_ADDR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) final_events_log_size == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) tpm_log_version != EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) final_tbl = memremap(efi.tpm_final_log,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) sizeof(*final_tbl) + final_events_log_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) MEMREMAP_WB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (!final_tbl) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) pr_err("Could not map UEFI TPM final log\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) kfree(log->bios_event_log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * The 'final events log' size excludes the 'final events preboot log'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * at its beginning.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) final_events_log_size -= log_tbl->final_events_preboot_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * Allocate memory for the 'combined log' where we will append the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * 'final events log' to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) tmp = krealloc(log->bios_event_log,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) log_size + final_events_log_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (!tmp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) kfree(log->bios_event_log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) log->bios_event_log = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * Append any of the 'final events log' that didn't also end up in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * 'main log'. Events can be logged in both if events are generated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * between GetEventLog() and ExitBootServices().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) memcpy((void *)log->bios_event_log + log_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) final_tbl->events + log_tbl->final_events_preboot_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) final_events_log_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * The size of the 'combined log' is the size of the 'main log' plus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * the size of the 'final events log'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) log->bios_event_log_end = log->bios_event_log +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) log_size + final_events_log_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) memunmap(final_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) memunmap(log_tbl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }