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

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

DEFINITIONS

This source file includes following definitions.
  1. tpm1_bios_measurements_start
  2. tpm1_bios_measurements_next
  3. tpm1_bios_measurements_stop
  4. get_event_name
  5. tpm1_binary_bios_measurements_show
  6. tpm1_ascii_bios_measurements_show

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright (C) 2005, 2012 IBM Corporation
   4  *
   5  * Authors:
   6  *      Kent Yoder <key@linux.vnet.ibm.com>
   7  *      Seiji Munetoh <munetoh@jp.ibm.com>
   8  *      Stefan Berger <stefanb@us.ibm.com>
   9  *      Reiner Sailer <sailer@watson.ibm.com>
  10  *      Kylene Hall <kjhall@us.ibm.com>
  11  *      Nayna Jain <nayna@linux.vnet.ibm.com>
  12  *
  13  * Maintained by: <tpmdd-devel@lists.sourceforge.net>
  14  *
  15  * Access to the event log created by a system's firmware / BIOS
  16  */
  17 
  18 #include <linux/seq_file.h>
  19 #include <linux/efi.h>
  20 #include <linux/fs.h>
  21 #include <linux/security.h>
  22 #include <linux/module.h>
  23 #include <linux/slab.h>
  24 #include <linux/tpm_eventlog.h>
  25 
  26 #include "../tpm.h"
  27 #include "common.h"
  28 
  29 
  30 static const char* tcpa_event_type_strings[] = {
  31         "PREBOOT",
  32         "POST CODE",
  33         "",
  34         "NO ACTION",
  35         "SEPARATOR",
  36         "ACTION",
  37         "EVENT TAG",
  38         "S-CRTM Contents",
  39         "S-CRTM Version",
  40         "CPU Microcode",
  41         "Platform Config Flags",
  42         "Table of Devices",
  43         "Compact Hash",
  44         "IPL",
  45         "IPL Partition Data",
  46         "Non-Host Code",
  47         "Non-Host Config",
  48         "Non-Host Info"
  49 };
  50 
  51 static const char* tcpa_pc_event_id_strings[] = {
  52         "",
  53         "SMBIOS",
  54         "BIS Certificate",
  55         "POST BIOS ",
  56         "ESCD ",
  57         "CMOS",
  58         "NVRAM",
  59         "Option ROM",
  60         "Option ROM config",
  61         "",
  62         "Option ROM microcode ",
  63         "S-CRTM Version",
  64         "S-CRTM Contents ",
  65         "POST Contents ",
  66         "Table of Devices",
  67 };
  68 
  69 /* returns pointer to start of pos. entry of tcg log */
  70 static void *tpm1_bios_measurements_start(struct seq_file *m, loff_t *pos)
  71 {
  72         loff_t i = 0;
  73         struct tpm_chip *chip = m->private;
  74         struct tpm_bios_log *log = &chip->log;
  75         void *addr = log->bios_event_log;
  76         void *limit = log->bios_event_log_end;
  77         struct tcpa_event *event;
  78         u32 converted_event_size;
  79         u32 converted_event_type;
  80 
  81         /* read over *pos measurements */
  82         do {
  83                 event = addr;
  84 
  85                 /* check if current entry is valid */
  86                 if (addr + sizeof(struct tcpa_event) > limit)
  87                         return NULL;
  88 
  89                 converted_event_size =
  90                     do_endian_conversion(event->event_size);
  91                 converted_event_type =
  92                     do_endian_conversion(event->event_type);
  93 
  94                 if (((converted_event_type == 0) && (converted_event_size == 0))
  95                     || ((addr + sizeof(struct tcpa_event) + converted_event_size)
  96                         > limit))
  97                         return NULL;
  98 
  99                 if (i++ == *pos)
 100                         break;
 101 
 102                 addr += (sizeof(struct tcpa_event) + converted_event_size);
 103         } while (1);
 104 
 105         return addr;
 106 }
 107 
 108 static void *tpm1_bios_measurements_next(struct seq_file *m, void *v,
 109                                         loff_t *pos)
 110 {
 111         struct tcpa_event *event = v;
 112         struct tpm_chip *chip = m->private;
 113         struct tpm_bios_log *log = &chip->log;
 114         void *limit = log->bios_event_log_end;
 115         u32 converted_event_size;
 116         u32 converted_event_type;
 117 
 118         (*pos)++;
 119         converted_event_size = do_endian_conversion(event->event_size);
 120 
 121         v += sizeof(struct tcpa_event) + converted_event_size;
 122 
 123         /* now check if current entry is valid */
 124         if ((v + sizeof(struct tcpa_event)) > limit)
 125                 return NULL;
 126 
 127         event = v;
 128 
 129         converted_event_size = do_endian_conversion(event->event_size);
 130         converted_event_type = do_endian_conversion(event->event_type);
 131 
 132         if (((converted_event_type == 0) && (converted_event_size == 0)) ||
 133             ((v + sizeof(struct tcpa_event) + converted_event_size) > limit))
 134                 return NULL;
 135 
 136         return v;
 137 }
 138 
 139 static void tpm1_bios_measurements_stop(struct seq_file *m, void *v)
 140 {
 141 }
 142 
 143 static int get_event_name(char *dest, struct tcpa_event *event,
 144                         unsigned char * event_entry)
 145 {
 146         const char *name = "";
 147         /* 41 so there is room for 40 data and 1 nul */
 148         char data[41] = "";
 149         int i, n_len = 0, d_len = 0;
 150         struct tcpa_pc_event *pc_event;
 151 
 152         switch (do_endian_conversion(event->event_type)) {
 153         case PREBOOT:
 154         case POST_CODE:
 155         case UNUSED:
 156         case NO_ACTION:
 157         case SCRTM_CONTENTS:
 158         case SCRTM_VERSION:
 159         case CPU_MICROCODE:
 160         case PLATFORM_CONFIG_FLAGS:
 161         case TABLE_OF_DEVICES:
 162         case COMPACT_HASH:
 163         case IPL:
 164         case IPL_PARTITION_DATA:
 165         case NONHOST_CODE:
 166         case NONHOST_CONFIG:
 167         case NONHOST_INFO:
 168                 name = tcpa_event_type_strings[do_endian_conversion
 169                                                 (event->event_type)];
 170                 n_len = strlen(name);
 171                 break;
 172         case SEPARATOR:
 173         case ACTION:
 174                 if (MAX_TEXT_EVENT >
 175                     do_endian_conversion(event->event_size)) {
 176                         name = event_entry;
 177                         n_len = do_endian_conversion(event->event_size);
 178                 }
 179                 break;
 180         case EVENT_TAG:
 181                 pc_event = (struct tcpa_pc_event *)event_entry;
 182 
 183                 /* ToDo Row data -> Base64 */
 184 
 185                 switch (do_endian_conversion(pc_event->event_id)) {
 186                 case SMBIOS:
 187                 case BIS_CERT:
 188                 case CMOS:
 189                 case NVRAM:
 190                 case OPTION_ROM_EXEC:
 191                 case OPTION_ROM_CONFIG:
 192                 case S_CRTM_VERSION:
 193                         name = tcpa_pc_event_id_strings[do_endian_conversion
 194                                                         (pc_event->event_id)];
 195                         n_len = strlen(name);
 196                         break;
 197                 /* hash data */
 198                 case POST_BIOS_ROM:
 199                 case ESCD:
 200                 case OPTION_ROM_MICROCODE:
 201                 case S_CRTM_CONTENTS:
 202                 case POST_CONTENTS:
 203                         name = tcpa_pc_event_id_strings[do_endian_conversion
 204                                                         (pc_event->event_id)];
 205                         n_len = strlen(name);
 206                         for (i = 0; i < 20; i++)
 207                                 d_len += sprintf(&data[2*i], "%02x",
 208                                                 pc_event->event_data[i]);
 209                         break;
 210                 default:
 211                         break;
 212                 }
 213         default:
 214                 break;
 215         }
 216 
 217         return snprintf(dest, MAX_TEXT_EVENT, "[%.*s%.*s]",
 218                         n_len, name, d_len, data);
 219 
 220 }
 221 
 222 static int tpm1_binary_bios_measurements_show(struct seq_file *m, void *v)
 223 {
 224         struct tcpa_event *event = v;
 225         struct tcpa_event temp_event;
 226         char *temp_ptr;
 227         int i;
 228 
 229         memcpy(&temp_event, event, sizeof(struct tcpa_event));
 230 
 231         /* convert raw integers for endianness */
 232         temp_event.pcr_index = do_endian_conversion(event->pcr_index);
 233         temp_event.event_type = do_endian_conversion(event->event_type);
 234         temp_event.event_size = do_endian_conversion(event->event_size);
 235 
 236         temp_ptr = (char *) &temp_event;
 237 
 238         for (i = 0; i < (sizeof(struct tcpa_event) - 1) ; i++)
 239                 seq_putc(m, temp_ptr[i]);
 240 
 241         temp_ptr = (char *) v;
 242 
 243         for (i = (sizeof(struct tcpa_event) - 1);
 244              i < (sizeof(struct tcpa_event) + temp_event.event_size); i++)
 245                 seq_putc(m, temp_ptr[i]);
 246 
 247         return 0;
 248 
 249 }
 250 
 251 static int tpm1_ascii_bios_measurements_show(struct seq_file *m, void *v)
 252 {
 253         int len = 0;
 254         char *eventname;
 255         struct tcpa_event *event = v;
 256         unsigned char *event_entry =
 257             (unsigned char *)(v + sizeof(struct tcpa_event));
 258 
 259         eventname = kmalloc(MAX_TEXT_EVENT, GFP_KERNEL);
 260         if (!eventname) {
 261                 printk(KERN_ERR "%s: ERROR - No Memory for event name\n ",
 262                        __func__);
 263                 return -EFAULT;
 264         }
 265 
 266         /* 1st: PCR */
 267         seq_printf(m, "%2d ", do_endian_conversion(event->pcr_index));
 268 
 269         /* 2nd: SHA1 */
 270         seq_printf(m, "%20phN", event->pcr_value);
 271 
 272         /* 3rd: event type identifier */
 273         seq_printf(m, " %02x", do_endian_conversion(event->event_type));
 274 
 275         len += get_event_name(eventname, event, event_entry);
 276 
 277         /* 4th: eventname <= max + \'0' delimiter */
 278         seq_printf(m, " %s\n", eventname);
 279 
 280         kfree(eventname);
 281         return 0;
 282 }
 283 
 284 const struct seq_operations tpm1_ascii_b_measurements_seqops = {
 285         .start = tpm1_bios_measurements_start,
 286         .next = tpm1_bios_measurements_next,
 287         .stop = tpm1_bios_measurements_stop,
 288         .show = tpm1_ascii_bios_measurements_show,
 289 };
 290 
 291 const struct seq_operations tpm1_binary_b_measurements_seqops = {
 292         .start = tpm1_bios_measurements_start,
 293         .next = tpm1_bios_measurements_next,
 294         .stop = tpm1_bios_measurements_stop,
 295         .show = tpm1_binary_bios_measurements_show,
 296 };

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