root/drivers/firmware/efi/libstub/tpm.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. efi_enable_reset_attack_mitigation
  2. efi_retrieve_tpm2_eventlog

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * TPM handling.
   4  *
   5  * Copyright (C) 2016 CoreOS, Inc
   6  * Copyright (C) 2017 Google, Inc.
   7  *     Matthew Garrett <mjg59@google.com>
   8  *     Thiebaud Weksteen <tweek@google.com>
   9  */
  10 #include <linux/efi.h>
  11 #include <linux/tpm_eventlog.h>
  12 #include <asm/efi.h>
  13 
  14 #include "efistub.h"
  15 
  16 #ifdef CONFIG_RESET_ATTACK_MITIGATION
  17 static const efi_char16_t efi_MemoryOverWriteRequest_name[] =
  18         L"MemoryOverwriteRequestControl";
  19 
  20 #define MEMORY_ONLY_RESET_CONTROL_GUID \
  21         EFI_GUID(0xe20939be, 0x32d4, 0x41be, 0xa1, 0x50, 0x89, 0x7f, 0x85, 0xd4, 0x98, 0x29)
  22 
  23 #define get_efi_var(name, vendor, ...) \
  24         efi_call_runtime(get_variable, \
  25                          (efi_char16_t *)(name), (efi_guid_t *)(vendor), \
  26                          __VA_ARGS__)
  27 
  28 #define set_efi_var(name, vendor, ...) \
  29         efi_call_runtime(set_variable, \
  30                          (efi_char16_t *)(name), (efi_guid_t *)(vendor), \
  31                          __VA_ARGS__)
  32 
  33 /*
  34  * Enable reboot attack mitigation. This requests that the firmware clear the
  35  * RAM on next reboot before proceeding with boot, ensuring that any secrets
  36  * are cleared. If userland has ensured that all secrets have been removed
  37  * from RAM before reboot it can simply reset this variable.
  38  */
  39 void efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg)
  40 {
  41         u8 val = 1;
  42         efi_guid_t var_guid = MEMORY_ONLY_RESET_CONTROL_GUID;
  43         efi_status_t status;
  44         unsigned long datasize = 0;
  45 
  46         status = get_efi_var(efi_MemoryOverWriteRequest_name, &var_guid,
  47                              NULL, &datasize, NULL);
  48 
  49         if (status == EFI_NOT_FOUND)
  50                 return;
  51 
  52         set_efi_var(efi_MemoryOverWriteRequest_name, &var_guid,
  53                     EFI_VARIABLE_NON_VOLATILE |
  54                     EFI_VARIABLE_BOOTSERVICE_ACCESS |
  55                     EFI_VARIABLE_RUNTIME_ACCESS, sizeof(val), &val);
  56 }
  57 
  58 #endif
  59 
  60 void efi_retrieve_tpm2_eventlog(efi_system_table_t *sys_table_arg)
  61 {
  62         efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID;
  63         efi_guid_t linux_eventlog_guid = LINUX_EFI_TPM_EVENT_LOG_GUID;
  64         efi_status_t status;
  65         efi_physical_addr_t log_location = 0, log_last_entry = 0;
  66         struct linux_efi_tpm_eventlog *log_tbl = NULL;
  67         struct efi_tcg2_final_events_table *final_events_table = NULL;
  68         unsigned long first_entry_addr, last_entry_addr;
  69         size_t log_size, last_entry_size;
  70         efi_bool_t truncated;
  71         int version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_2;
  72         void *tcg2_protocol = NULL;
  73         int final_events_size = 0;
  74 
  75         status = efi_call_early(locate_protocol, &tcg2_guid, NULL,
  76                                 &tcg2_protocol);
  77         if (status != EFI_SUCCESS)
  78                 return;
  79 
  80         status = efi_call_proto(efi_tcg2_protocol, get_event_log,
  81                                 tcg2_protocol, version, &log_location,
  82                                 &log_last_entry, &truncated);
  83 
  84         if (status != EFI_SUCCESS || !log_location) {
  85                 version = EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2;
  86                 status = efi_call_proto(efi_tcg2_protocol, get_event_log,
  87                                         tcg2_protocol, version, &log_location,
  88                                         &log_last_entry, &truncated);
  89                 if (status != EFI_SUCCESS || !log_location)
  90                         return;
  91 
  92         }
  93 
  94         first_entry_addr = (unsigned long) log_location;
  95 
  96         /*
  97          * We populate the EFI table even if the logs are empty.
  98          */
  99         if (!log_last_entry) {
 100                 log_size = 0;
 101         } else {
 102                 last_entry_addr = (unsigned long) log_last_entry;
 103                 /*
 104                  * get_event_log only returns the address of the last entry.
 105                  * We need to calculate its size to deduce the full size of
 106                  * the logs.
 107                  */
 108                 if (version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2) {
 109                         /*
 110                          * The TCG2 log format has variable length entries,
 111                          * and the information to decode the hash algorithms
 112                          * back into a size is contained in the first entry -
 113                          * pass a pointer to the final entry (to calculate its
 114                          * size) and the first entry (so we know how long each
 115                          * digest is)
 116                          */
 117                         last_entry_size =
 118                                 __calc_tpm2_event_size((void *)last_entry_addr,
 119                                                     (void *)(long)log_location,
 120                                                     false);
 121                 } else {
 122                         last_entry_size = sizeof(struct tcpa_event) +
 123                            ((struct tcpa_event *) last_entry_addr)->event_size;
 124                 }
 125                 log_size = log_last_entry - log_location + last_entry_size;
 126         }
 127 
 128         /* Allocate space for the logs and copy them. */
 129         status = efi_call_early(allocate_pool, EFI_LOADER_DATA,
 130                                 sizeof(*log_tbl) + log_size,
 131                                 (void **) &log_tbl);
 132 
 133         if (status != EFI_SUCCESS) {
 134                 efi_printk(sys_table_arg,
 135                            "Unable to allocate memory for event log\n");
 136                 return;
 137         }
 138 
 139         /*
 140          * Figure out whether any events have already been logged to the
 141          * final events structure, and if so how much space they take up
 142          */
 143         if (version == EFI_TCG2_EVENT_LOG_FORMAT_TCG_2)
 144                 final_events_table = get_efi_config_table(sys_table_arg,
 145                                                 LINUX_EFI_TPM_FINAL_LOG_GUID);
 146         if (final_events_table && final_events_table->nr_events) {
 147                 struct tcg_pcr_event2_head *header;
 148                 int offset;
 149                 void *data;
 150                 int event_size;
 151                 int i = final_events_table->nr_events;
 152 
 153                 data = (void *)final_events_table;
 154                 offset = sizeof(final_events_table->version) +
 155                         sizeof(final_events_table->nr_events);
 156 
 157                 while (i > 0) {
 158                         header = data + offset + final_events_size;
 159                         event_size = __calc_tpm2_event_size(header,
 160                                                    (void *)(long)log_location,
 161                                                    false);
 162                         final_events_size += event_size;
 163                         i--;
 164                 }
 165         }
 166 
 167         memset(log_tbl, 0, sizeof(*log_tbl) + log_size);
 168         log_tbl->size = log_size;
 169         log_tbl->final_events_preboot_size = final_events_size;
 170         log_tbl->version = version;
 171         memcpy(log_tbl->log, (void *) first_entry_addr, log_size);
 172 
 173         status = efi_call_early(install_configuration_table,
 174                                 &linux_eventlog_guid, log_tbl);
 175         if (status != EFI_SUCCESS)
 176                 goto err_free;
 177         return;
 178 
 179 err_free:
 180         efi_call_early(free_pool, log_tbl);
 181 }

/* [<][>][^][v][top][bottom][index][help] */