160 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright (C) 2016 IBM Corporation4 *5 * Authors:6 * Nayna Jain <nayna@linux.vnet.ibm.com>7 *8 * Access to TPM 2.0 event log as written by Firmware.9 * It assumes that writer of event log has followed TCG Specification10 * for Family "2.0" and written the event data in little endian.11 * With that, it doesn't need any endian conversion for structure12 * content.13 */14 15#include <linux/seq_file.h>16#include <linux/fs.h>17#include <linux/security.h>18#include <linux/module.h>19#include <linux/slab.h>20#include <linux/tpm_eventlog.h>21 22#include "../tpm.h"23#include "common.h"24 25/*26 * calc_tpm2_event_size() - calculate the event size, where event27 * is an entry in the TPM 2.0 event log. The event is of type Crypto28 * Agile Log Entry Format as defined in TCG EFI Protocol Specification29 * Family "2.0".30 31 * @event: event whose size is to be calculated.32 * @event_header: the first event in the event log.33 *34 * Returns size of the event. If it is an invalid event, returns 0.35 */36static size_t calc_tpm2_event_size(struct tcg_pcr_event2_head *event,37 struct tcg_pcr_event *event_header)38{39 return __calc_tpm2_event_size(event, event_header, false);40}41 42static void *tpm2_bios_measurements_start(struct seq_file *m, loff_t *pos)43{44 struct tpm_chip *chip = m->private;45 struct tpm_bios_log *log = &chip->log;46 void *addr = log->bios_event_log;47 void *limit = log->bios_event_log_end;48 struct tcg_pcr_event *event_header;49 struct tcg_pcr_event2_head *event;50 size_t size;51 int i;52 53 event_header = addr;54 size = struct_size(event_header, event, event_header->event_size);55 56 if (*pos == 0) {57 if (addr + size < limit) {58 if ((event_header->event_type == 0) &&59 (event_header->event_size == 0))60 return NULL;61 return SEQ_START_TOKEN;62 }63 }64 65 if (*pos > 0) {66 addr += size;67 event = addr;68 size = calc_tpm2_event_size(event, event_header);69 if ((addr + size >= limit) || (size == 0))70 return NULL;71 }72 73 for (i = 0; i < (*pos - 1); i++) {74 event = addr;75 size = calc_tpm2_event_size(event, event_header);76 77 if ((addr + size >= limit) || (size == 0))78 return NULL;79 addr += size;80 }81 82 return addr;83}84 85static void *tpm2_bios_measurements_next(struct seq_file *m, void *v,86 loff_t *pos)87{88 struct tcg_pcr_event *event_header;89 struct tcg_pcr_event2_head *event;90 struct tpm_chip *chip = m->private;91 struct tpm_bios_log *log = &chip->log;92 void *limit = log->bios_event_log_end;93 size_t event_size;94 void *marker;95 96 (*pos)++;97 event_header = log->bios_event_log;98 99 if (v == SEQ_START_TOKEN) {100 event_size = struct_size(event_header, event,101 event_header->event_size);102 marker = event_header;103 } else {104 event = v;105 event_size = calc_tpm2_event_size(event, event_header);106 if (event_size == 0)107 return NULL;108 marker = event;109 }110 111 marker = marker + event_size;112 if (marker >= limit)113 return NULL;114 v = marker;115 event = v;116 117 event_size = calc_tpm2_event_size(event, event_header);118 if (((v + event_size) >= limit) || (event_size == 0))119 return NULL;120 121 return v;122}123 124static void tpm2_bios_measurements_stop(struct seq_file *m, void *v)125{126}127 128static int tpm2_binary_bios_measurements_show(struct seq_file *m, void *v)129{130 struct tpm_chip *chip = m->private;131 struct tpm_bios_log *log = &chip->log;132 struct tcg_pcr_event *event_header = log->bios_event_log;133 struct tcg_pcr_event2_head *event = v;134 void *temp_ptr;135 size_t size;136 137 if (v == SEQ_START_TOKEN) {138 size = struct_size(event_header, event,139 event_header->event_size);140 temp_ptr = event_header;141 142 if (size > 0)143 seq_write(m, temp_ptr, size);144 } else {145 size = calc_tpm2_event_size(event, event_header);146 temp_ptr = event;147 if (size > 0)148 seq_write(m, temp_ptr, size);149 }150 151 return 0;152}153 154const struct seq_operations tpm2_binary_b_measurements_seqops = {155 .start = tpm2_bios_measurements_start,156 .next = tpm2_bios_measurements_next,157 .stop = tpm2_bios_measurements_stop,158 .show = tpm2_binary_bios_measurements_show,159};160