coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
log.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <security/tpm/tspi.h>
5 #include <region_file.h>
6 #include <string.h>
7 #include <symbols.h>
8 #include <cbmem.h>
9 #include <bootstate.h>
10 #include <vb2_sha.h>
11 
12 static struct tcpa_table *tcpa_cbmem_init(void)
13 {
14  static struct tcpa_table *tclt;
15  if (tclt)
16  return tclt;
17 
18  if (cbmem_possibly_online()) {
20  if (!tclt) {
21  size_t tcpa_log_len = sizeof(struct tcpa_table) +
22  MAX_TCPA_LOG_ENTRIES * sizeof(struct tcpa_entry);
23  tclt = cbmem_add(CBMEM_ID_TCPA_LOG, tcpa_log_len);
24  if (tclt) {
26  tclt->num_entries = 0;
27  }
28  }
29  }
30  return tclt;
31 }
32 
34 {
35  static struct tcpa_table *tclt;
36 
37  /* We are dealing here with pre CBMEM environment.
38  * If cbmem isn't available use CAR or SRAM */
39  if (!cbmem_possibly_online() &&
40  !CONFIG(VBOOT_RETURN_FROM_VERSTAGE))
41  return (struct tcpa_table *)_tpm_tcpa_log;
42  else if (ENV_ROMSTAGE &&
43  !CONFIG(VBOOT_RETURN_FROM_VERSTAGE)) {
44  tclt = tcpa_cbmem_init();
45  if (!tclt)
46  return (struct tcpa_table *)_tpm_tcpa_log;
47  } else {
48  tclt = tcpa_cbmem_init();
49  }
50 
51  return tclt;
52 }
53 
54 void tcpa_log_dump(void *unused)
55 {
56  int i, j;
57  struct tcpa_table *tclt;
58 
59  tclt = tcpa_log_init();
60  if (!tclt)
61  return;
62 
63  printk(BIOS_INFO, "coreboot TCPA measurements:\n\n");
64  for (i = 0; i < tclt->num_entries; i++) {
65  struct tcpa_entry *tce = &tclt->entries[i];
66  if (tce) {
67  printk(BIOS_INFO, " PCR-%u ", tce->pcr);
68 
69  for (j = 0; j < tce->digest_length; j++)
70  printk(BIOS_INFO, "%02x", tce->digest[j]);
71 
72  printk(BIOS_INFO, " %s [%s]\n",
73  tce->digest_type, tce->name);
74  }
75  }
76  printk(BIOS_INFO, "\n");
77 }
78 
79 void tcpa_log_add_table_entry(const char *name, const uint32_t pcr,
80  enum vb2_hash_algorithm digest_algo,
81  const uint8_t *digest,
82  const size_t digest_len)
83 {
84  struct tcpa_table *tclt = tcpa_log_init();
85  if (!tclt) {
86  printk(BIOS_WARNING, "TCPA: Log non-existent!\n");
87  return;
88  }
89 
90  if (tclt->num_entries >= tclt->max_entries) {
91  printk(BIOS_WARNING, "TCPA: TCPA log table is full\n");
92  return;
93  }
94 
95  if (!name) {
96  printk(BIOS_WARNING, "TCPA: TCPA entry name not set\n");
97  return;
98  }
99 
100  struct tcpa_entry *tce = &tclt->entries[tclt->num_entries++];
101  strncpy(tce->name, name, TCPA_PCR_HASH_NAME - 1);
102  tce->pcr = pcr;
103 
104  if (digest_len > TCPA_DIGEST_MAX_LENGTH) {
105  printk(BIOS_WARNING, "TCPA: PCR digest too long for TCPA log entry\n");
106  return;
107  }
108 
109  strncpy(tce->digest_type,
110  vb2_get_hash_algorithm_name(digest_algo),
111  TCPA_PCR_HASH_LEN - 1);
112  tce->digest_length = digest_len;
113  memcpy(tce->digest, digest, tce->digest_length);
114 }
115 
117 {
118  printk(BIOS_INFO, "TCPA: Clearing coreboot TCPA log\n");
119  struct tcpa_table *tclt = (struct tcpa_table *)_tpm_tcpa_log;
121  tclt->num_entries = 0;
122 }
123 
124 #if !CONFIG(VBOOT_RETURN_FROM_VERSTAGE)
125 static void recover_tcpa_log(int is_recovery)
126 {
127  struct tcpa_table *preram_log = (struct tcpa_table *)_tpm_tcpa_log;
128  struct tcpa_table *ram_log = NULL;
129  int i;
130 
131  if (preram_log->num_entries > MAX_PRERAM_TCPA_LOG_ENTRIES) {
132  printk(BIOS_WARNING, "TCPA: Pre-RAM TCPA log is too full, possible corruption\n");
133  return;
134  }
135 
136  ram_log = tcpa_cbmem_init();
137  if (!ram_log) {
138  printk(BIOS_WARNING, "TCPA: CBMEM not available something went wrong\n");
139  return;
140  }
141 
142  for (i = 0; i < preram_log->num_entries; i++) {
143  struct tcpa_entry *tce = &ram_log->entries[ram_log->num_entries++];
144  strncpy(tce->name, preram_log->entries[i].name, TCPA_PCR_HASH_NAME - 1);
145  tce->pcr = preram_log->entries[i].pcr;
146 
147  if (preram_log->entries[i].digest_length > TCPA_DIGEST_MAX_LENGTH) {
148  printk(BIOS_WARNING, "TCPA: PCR digest too long for TCPA log entry\n");
149  return;
150  }
151 
152  strncpy(tce->digest_type, preram_log->entries[i].digest_type, TCPA_PCR_HASH_LEN - 1);
154  memcpy(tce->digest, preram_log->entries[i].digest, tce->digest_length);
155  }
156 }
158 #endif
159 
const char * name
Definition: mmu.c:92
void * memcpy(void *dest, const void *src, size_t n)
Definition: memcpy.c:7
@ BS_PAYLOAD_BOOT
Definition: bootstate.h:89
@ BS_ON_ENTRY
Definition: bootstate.h:95
#define MIN(a, b)
Definition: helpers.h:37
static int cbmem_possibly_online(void)
Definition: cbmem.h:158
void * cbmem_add(u32 id, u64 size)
Definition: imd_cbmem.c:144
void * cbmem_find(u32 id)
Definition: imd_cbmem.c:166
#define CBMEM_ID_TCPA_LOG
Definition: cbmem_id.h:60
#define printk(level,...)
Definition: stdlib.h:16
@ CONFIG
Definition: dsi_common.h:201
void tcpa_preram_log_clear(void)
Clears the pre-RAM tcpa log data and initializes any content with default values.
Definition: log.c:116
ROMSTAGE_CBMEM_INIT_HOOK(recover_tcpa_log)
BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, tcpa_log_dump, NULL)
void tcpa_log_dump(void *unused)
Dump TCPA log entries on console.
Definition: log.c:54
static struct tcpa_table * tcpa_cbmem_init(void)
Definition: log.c:12
struct tcpa_table * tcpa_log_init(void)
Get the pointer to the single instance of global tcpa log data, and initialize it when necessary.
Definition: log.c:33
void tcpa_log_add_table_entry(const char *name, const uint32_t pcr, enum vb2_hash_algorithm digest_algo, const uint8_t *digest, const size_t digest_len)
Add table entry for cbmem TCPA log.
Definition: log.c:79
static void recover_tcpa_log(int is_recovery)
Definition: log.c:125
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_WARNING
BIOS_WARNING - Bad configuration.
Definition: loglevel.h:86
#define ENV_ROMSTAGE
Definition: rules.h:149
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14
unsigned char uint8_t
Definition: stdint.h:8
char * strncpy(char *to, const char *from, int count)
Definition: string.c:72
uint8_t digest[TCPA_DIGEST_MAX_LENGTH]
uint32_t pcr
uint32_t digest_length
char name[TCPA_PCR_HASH_NAME]
char digest_type[TCPA_PCR_HASH_LEN]
uint16_t max_entries
uint16_t num_entries
struct tcpa_entry entries[0]
#define TCPA_DIGEST_MAX_LENGTH
#define MAX_PRERAM_TCPA_LOG_ENTRIES
#define MAX_TCPA_LOG_ENTRIES
#define TCPA_PCR_HASH_LEN
#define TCPA_PCR_HASH_NAME