1 /* SPDX-License-Identifier: GPL-2.0-only */
4 * Unlike log.c this implements TPM log according to TPM1.2 specification
5 * rather than using coreboot-specific log format.
9 #include <console/console.h>
10 #include <security/tpm/tspi/logs.h>
11 #include <security/tpm/tspi.h>
17 void *tpm1_log_cbmem_init(void)
19 static struct tpm_1_log_table
*tclt
;
25 struct spec_id_event_data
*hdr
;
27 tclt
= cbmem_find(CBMEM_ID_TCPA_TCG_LOG
);
31 tpm_log_len
= sizeof(*tclt
) + MAX_TPM_LOG_ENTRIES
* sizeof(tclt
->entries
[0]);
32 tclt
= cbmem_add(CBMEM_ID_TCPA_TCG_LOG
, tpm_log_len
);
36 memset(tclt
, 0, sizeof(*tclt
));
39 /* Fill in first "header" entry. */
40 tclt
->event_type
= htole32(EV_NO_ACTION
);
41 tclt
->spec_id_size
= htole32(sizeof(tclt
->spec_id
) + sizeof(tclt
->vendor
));
42 strcpy(hdr
->signature
, TCPA_SPEC_ID_EVENT_SIGNATURE
);
43 hdr
->platform_class
= htole32(0x00); // client platform
44 hdr
->spec_version_minor
= 0x02;
45 hdr
->spec_version_major
= 0x01;
46 hdr
->spec_errata
= 0x01;
47 hdr
->vendor_info_size
= sizeof(tclt
->vendor
);
49 tclt
->vendor
.reserved
= 0;
50 tclt
->vendor
.version_major
= TPM_1_LOG_VI_MAJOR
;
51 tclt
->vendor
.version_minor
= TPM_1_LOG_VI_MINOR
;
52 tclt
->vendor
.magic
= htole32(TPM_1_LOG_VI_MAGIC
);
53 tclt
->vendor
.max_entries
= htole16(MAX_TPM_LOG_ENTRIES
);
54 tclt
->vendor
.num_entries
= htole16(0);
55 tclt
->vendor
.entry_size
= htole32(sizeof(tclt
->entries
[0]));
61 void tpm1_log_dump(void)
64 struct tpm_1_log_table
*tclt
;
66 tclt
= tpm_log_init();
70 printk(BIOS_INFO
, "coreboot TPM 1.2 measurements:\n\n");
71 for (i
= 0; i
< le16toh(tclt
->vendor
.num_entries
); i
++) {
72 struct tpm_1_log_entry
*tce
= &tclt
->entries
[i
];
74 printk(BIOS_INFO
, " PCR-%u ", le32toh(tce
->pcr
));
76 for (j
= 0; j
< TPM_1_LOG_DIGEST_MAX_LENGTH
; j
++)
77 printk(BIOS_INFO
, "%02x", tce
->digest
[j
]);
79 printk(BIOS_INFO
, " %s [%s]\n", "SHA1", (char *)tce
->data
);
81 printk(BIOS_INFO
, "\n");
84 void tpm1_log_add_table_entry(const char *name
, const uint32_t pcr
,
85 enum vb2_hash_algorithm digest_algo
,
86 const uint8_t *digest
,
87 const size_t digest_len
)
89 struct tpm_1_log_table
*tclt
;
90 struct tpm_1_log_entry
*tce
;
92 tclt
= tpm_log_init();
94 printk(BIOS_WARNING
, "TPM LOG: non-existent!\n");
99 printk(BIOS_WARNING
, "TPM LOG: entry name not set\n");
103 if (digest_algo
!= VB2_HASH_SHA1
) {
104 printk(BIOS_WARNING
, "TPM LOG: unsupported hash algorithm\n");
108 if (le16toh(tclt
->vendor
.num_entries
) >= le16toh(tclt
->vendor
.max_entries
)) {
109 printk(BIOS_WARNING
, "TPM LOG: log table is full\n");
113 tce
= &tclt
->entries
[le16toh(tclt
->vendor
.num_entries
)];
114 tclt
->vendor
.num_entries
= htole16(le16toh(tclt
->vendor
.num_entries
) + 1);
116 tce
->pcr
= htole32(pcr
);
117 tce
->event_type
= htole32(EV_ACTION
);
119 memcpy(tce
->digest
, digest
, digest_len
);
121 tce
->data_length
= htole32(TPM_1_LOG_DATA_MAX_LENGTH
);
122 strncpy((char *)tce
->data
, name
, sizeof(tce
->data
) - 1);
123 tce
->data
[sizeof(tce
->data
) - 1] = '\0';
126 void tpm1_preram_log_clear(void)
128 printk(BIOS_INFO
, "TPM LOG: clearing the log\n");
130 * Pre-RAM log is only for internal use and isn't exported anywhere, hence it's header
131 * is not initialized.
133 struct tpm_1_log_table
*tclt
= (struct tpm_1_log_table
*)_tpm_log
;
134 tclt
->vendor
.max_entries
= htole16(MAX_TPM_LOG_ENTRIES
);
135 tclt
->vendor
.num_entries
= htole16(0);
138 int tpm1_log_get(int entry_idx
, int *pcr
, const uint8_t **digest_data
,
139 enum vb2_hash_algorithm
*digest_algo
, const char **event_name
)
141 struct tpm_1_log_table
*tclt
;
142 struct tpm_1_log_entry
*tce
;
144 tclt
= tpm_log_init();
148 if (entry_idx
< 0 || entry_idx
>= le16toh(tclt
->vendor
.num_entries
))
151 tce
= &tclt
->entries
[entry_idx
];
153 *pcr
= le32toh(tce
->pcr
);
154 *digest_data
= tce
->digest
;
155 *digest_algo
= VB2_HASH_SHA1
;
156 *event_name
= (char *)tce
->data
;
160 uint16_t tpm1_log_get_size(const void *log_table
)
162 const struct tpm_1_log_table
*tclt
= log_table
;
163 return le16toh(tclt
->vendor
.num_entries
);
166 void tpm1_log_copy_entries(const void *from
, void *to
)
168 const struct tpm_1_log_table
*from_log
= from
;
169 struct tpm_1_log_table
*to_log
= to
;
172 for (i
= 0; i
< le16toh(from_log
->vendor
.num_entries
); i
++) {
173 if (le16toh(to_log
->vendor
.num_entries
) >= le16toh(to_log
->vendor
.max_entries
)) {
174 printk(BIOS_WARNING
, "TPM LOG: log table is full\n");
178 struct tpm_1_log_entry
*tce
=
179 &to_log
->entries
[le16toh(to_log
->vendor
.num_entries
)];
180 memcpy(tce
, &from_log
->entries
[i
], sizeof(*tce
));
182 to_log
->vendor
.num_entries
= htole16(le16toh(to_log
->vendor
.num_entries
) + 1);