coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
mrc_cache_hash_tpm.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
4 #include <program_loading.h>
6 #include <vb2_api.h>
7 #include <security/tpm/tss.h>
9 #include <console/console.h>
10 #include <string.h>
11 
12 void mrc_cache_update_hash(uint32_t index, const uint8_t *data, size_t size)
13 {
14  uint8_t data_hash[VB2_SHA256_DIGEST_SIZE];
15  static const uint8_t dead_hash[VB2_SHA256_DIGEST_SIZE] = {
16  0xba, 0xad, 0xda, 0x1a, /* BAADDA1A */
17  0xde, 0xad, 0xde, 0xad, /* DEADDEAD */
18  0xde, 0xad, 0xda, 0x1a, /* DEADDA1A */
19  0xba, 0xad, 0xba, 0xad, /* BAADBAAD */
20  0xba, 0xad, 0xda, 0x1a, /* BAADDA1A */
21  0xde, 0xad, 0xde, 0xad, /* DEADDEAD */
22  0xde, 0xad, 0xda, 0x1a, /* DEADDA1A */
23  0xba, 0xad, 0xba, 0xad, /* BAADBAAD */
24  };
25  const uint8_t *hash_ptr = data_hash;
26 
27  /* Initialize TPM driver. */
28  if (tlcl_lib_init() != VB2_SUCCESS) {
29  printk(BIOS_ERR, "MRC: TPM driver initialization failed.\n");
30  return;
31  }
32 
33  /* Calculate hash of data generated by MRC. */
34  if (vb2_digest_buffer(data, size, VB2_HASH_SHA256, data_hash,
35  sizeof(data_hash))) {
36  printk(BIOS_ERR, "MRC: SHA-256 calculation failed for data. "
37  "Not updating TPM hash space.\n");
38  /*
39  * Since data is being updated in mrc cache, the hash
40  * currently stored in TPM hash space is no longer
41  * valid. If we are not able to calculate hash of the
42  * data being updated, reset all the bits in TPM hash
43  * space to pre-defined hash pattern.
44  */
45  hash_ptr = dead_hash;
46  }
47 
48  /* Write hash of data to TPM space. */
49  if (antirollback_write_space_mrc_hash(index, hash_ptr, VB2_SHA256_DIGEST_SIZE)
50  != TPM_SUCCESS) {
51  printk(BIOS_ERR, "MRC: Could not save hash to TPM.\n");
52  return;
53  }
54 
55  printk(BIOS_INFO, "MRC: TPM MRC hash idx 0x%x updated successfully.\n", index);
56 }
57 
58 int mrc_cache_verify_hash(uint32_t index, const uint8_t *data, size_t size)
59 {
60  uint8_t data_hash[VB2_SHA256_DIGEST_SIZE];
61  uint8_t tpm_hash[VB2_SHA256_DIGEST_SIZE];
62 
63  /* Calculate hash of data read from MRC_CACHE. */
64  if (vb2_digest_buffer(data, size, VB2_HASH_SHA256, data_hash,
65  sizeof(data_hash))) {
66  printk(BIOS_ERR, "MRC: SHA-256 calculation failed for data.\n");
67  return 0;
68  }
69 
70  /* Initialize TPM driver. */
71  if (tlcl_lib_init() != VB2_SUCCESS) {
72  printk(BIOS_ERR, "MRC: TPM driver initialization failed.\n");
73  return 0;
74  }
75 
76  /* Read hash of MRC data saved in TPM. */
77  if (antirollback_read_space_mrc_hash(index, tpm_hash, sizeof(tpm_hash))
78  != TPM_SUCCESS) {
79  printk(BIOS_ERR, "MRC: Could not read hash from TPM.\n");
80  return 0;
81  }
82 
83  if (memcmp(tpm_hash, data_hash, sizeof(tpm_hash))) {
84  printk(BIOS_ERR, "MRC: Hash comparison failed.\n");
85  return 0;
86  }
87 
88  printk(BIOS_INFO, "MRC: Hash idx 0x%x comparison successful.\n", index);
89 
90  return 1;
91 }
uint32_t antirollback_read_space_mrc_hash(uint32_t index, uint8_t *data, uint32_t size)
Definition: secdata_mock.c:62
uint32_t antirollback_write_space_mrc_hash(uint32_t index, const uint8_t *data, uint32_t size)
Definition: secdata_mock.c:67
#define printk(level,...)
Definition: stdlib.h:16
#define BIOS_INFO
BIOS_INFO - Expected events.
Definition: loglevel.h:113
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
void mrc_cache_update_hash(uint32_t index, const uint8_t *data, size_t size)
int mrc_cache_verify_hash(uint32_t index, const uint8_t *data, size_t size)
unsigned int uint32_t
Definition: stdint.h:14
unsigned char uint8_t
Definition: stdint.h:8
int memcmp(const void *s1, const void *s2, size_t n)
Definition: memcmp.c:3
uint32_t tlcl_lib_init(void)
Call this first.
Definition: tss.c:145
#define TPM_SUCCESS
Definition: tss_common.h:9