root/drivers/char/tpm/eventlog/efi.c

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

DEFINITIONS

This source file includes following definitions.
  1. tpm_read_log_efi

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

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