1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
4 #include <security/tpm/tspi/logs.h>
5 #include <security/tpm/tspi.h>
6 #include <region_file.h>
12 void *tpm_cb_log_cbmem_init(void)
14 static struct tpm_cb_log_table
*tclt
;
19 tclt
= cbmem_find(CBMEM_ID_TPM_CB_LOG
);
21 size_t tpm_log_len
= sizeof(struct tpm_cb_log_table
) +
22 MAX_TPM_LOG_ENTRIES
* sizeof(struct tpm_cb_log_entry
);
23 tclt
= cbmem_add(CBMEM_ID_TPM_CB_LOG
, tpm_log_len
);
25 tclt
->max_entries
= MAX_TPM_LOG_ENTRIES
;
26 tclt
->num_entries
= 0;
33 void tpm_cb_log_dump(void)
36 struct tpm_cb_log_table
*tclt
;
38 tclt
= tpm_log_init();
42 printk(BIOS_INFO
, "coreboot TPM log measurements:\n\n");
43 for (i
= 0; i
< tclt
->num_entries
; i
++) {
44 struct tpm_cb_log_entry
*tce
= &tclt
->entries
[i
];
46 printk(BIOS_INFO
, " PCR-%u ", tce
->pcr
);
48 for (j
= 0; j
< tce
->digest_length
; j
++)
49 printk(BIOS_INFO
, "%02x", tce
->digest
[j
]);
51 printk(BIOS_INFO
, " %s [%s]\n",
52 tce
->digest_type
, tce
->name
);
55 printk(BIOS_INFO
, "\n");
58 void tpm_cb_log_add_table_entry(const char *name
, const uint32_t pcr
,
59 enum vb2_hash_algorithm digest_algo
,
60 const uint8_t *digest
,
61 const size_t digest_len
)
63 struct tpm_cb_log_table
*tclt
= tpm_log_init();
65 printk(BIOS_WARNING
, "TPM LOG: Log non-existent!\n");
69 if (tclt
->num_entries
>= tclt
->max_entries
) {
70 printk(BIOS_WARNING
, "TPM LOG: log table is full\n");
75 printk(BIOS_WARNING
, "TPM LOG: entry name not set\n");
79 struct tpm_cb_log_entry
*tce
= &tclt
->entries
[tclt
->num_entries
++];
80 strncpy(tce
->name
, name
, TPM_CB_LOG_PCR_HASH_NAME
- 1);
81 tce
->name
[TPM_CB_LOG_PCR_HASH_NAME
- 1] = '\0';
85 if (digest_len
> TPM_CB_LOG_DIGEST_MAX_LENGTH
) {
86 printk(BIOS_WARNING
, "TPM LOG: PCR digest too long for log entry\n");
90 strncpy(tce
->digest_type
,
91 vb2_get_hash_algorithm_name(digest_algo
),
92 TPM_CB_LOG_PCR_HASH_LEN
- 1);
93 tce
->digest_length
= digest_len
;
94 memcpy(tce
->digest
, digest
, tce
->digest_length
);
97 void tpm_cb_preram_log_clear(void)
99 printk(BIOS_INFO
, "TPM LOG: clearing preram log\n");
100 struct tpm_cb_log_table
*tclt
= (struct tpm_cb_log_table
*)_tpm_log
;
101 tclt
->max_entries
= MAX_PRERAM_TPM_LOG_ENTRIES
;
102 tclt
->num_entries
= 0;
105 int tpm_cb_log_get(int entry_idx
, int *pcr
, const uint8_t **digest_data
,
106 enum vb2_hash_algorithm
*digest_algo
, const char **event_name
)
108 struct tpm_cb_log_table
*tclt
;
109 struct tpm_cb_log_entry
*tce
;
110 enum vb2_hash_algorithm algo
;
112 tclt
= tpm_log_init();
116 if (entry_idx
< 0 || entry_idx
>= tclt
->num_entries
)
119 tce
= &tclt
->entries
[entry_idx
];
122 *digest_data
= tce
->digest
;
123 *event_name
= tce
->name
;
125 *digest_algo
= VB2_HASH_INVALID
;
126 for (algo
= VB2_HASH_INVALID
; algo
!= VB2_HASH_ALG_COUNT
; ++algo
) {
127 if (strcmp(tce
->digest_type
, vb2_hash_names
[algo
]) == 0) {
135 uint16_t tpm_cb_log_get_size(const void *log_table
)
137 const struct tpm_cb_log_table
*tclt
= log_table
;
138 return tclt
->num_entries
;
141 void tpm_cb_log_copy_entries(const void *from
, void *to
)
143 const struct tpm_cb_log_table
*from_log
= from
;
144 struct tpm_cb_log_table
*to_log
= to
;
147 for (i
= 0; i
< from_log
->num_entries
; i
++) {
148 if (to_log
->num_entries
>= to_log
->max_entries
) {
149 printk(BIOS_ERR
, "TPM LOG: log table is full\n");
153 struct tpm_cb_log_entry
*tce
= &to_log
->entries
[to_log
->num_entries
++];
155 strncpy(tce
->name
, from_log
->entries
[i
].name
, TPM_CB_LOG_PCR_HASH_NAME
- 1);
156 tce
->name
[TPM_CB_LOG_PCR_HASH_NAME
- 1] = '\0';
158 tce
->pcr
= from_log
->entries
[i
].pcr
;
160 if (from_log
->entries
[i
].digest_length
> TPM_CB_LOG_DIGEST_MAX_LENGTH
) {
161 printk(BIOS_WARNING
, "TPM LOG: PCR digest too long for log entry\n");
165 strncpy(tce
->digest_type
, from_log
->entries
[i
].digest_type
,
166 TPM_CB_LOG_PCR_HASH_LEN
- 1);
167 tce
->digest_type
[TPM_CB_LOG_PCR_HASH_LEN
- 1] = '\0';
169 tce
->digest_length
= MIN(from_log
->entries
[i
].digest_length
,
170 TPM_CB_LOG_DIGEST_MAX_LENGTH
);
171 memcpy(tce
->digest
, from_log
->entries
[i
].digest
, tce
->digest_length
);