Software APIs
boot_log_unittest.cc
1 // Copyright lowRISC contributors (OpenTitan project).
2 // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3 // SPDX-License-Identifier: Apache-2.0
4 
5 #include "sw/device/silicon_creator/lib/boot_log.h"
6 
7 #include <cstring>
8 
9 #include "gtest/gtest.h"
10 #include "sw/device/silicon_creator/lib/chip_info.h"
11 #include "sw/device/silicon_creator/lib/drivers/hmac.h"
12 #include "sw/device/silicon_creator/lib/drivers/mock_hmac.h"
13 
14 bool operator==(hmac_digest_t lhs, hmac_digest_t rhs) {
15  return std::memcmp(&lhs, &rhs, sizeof(hmac_digest_t)) == 0;
16 }
17 
18 bool operator!=(hmac_digest_t lhs, hmac_digest_t rhs) {
19  return std::memcmp(&lhs, &rhs, sizeof(hmac_digest_t)) != 0;
20 }
21 
22 bool operator==(chip_info_scm_revision_t lhs, chip_info_scm_revision_t rhs) {
23  return std::memcmp(&lhs, &rhs, sizeof(chip_info_scm_revision_t)) == 0;
24 }
25 
26 namespace boot_log_unittest {
27 namespace {
28 
29 using ::testing::_;
30 
32  protected:
33  rom_test::MockHmac hmac_sha256_;
34 
35  hmac_digest_t expected_digest = {
36  .digest =
37  {
38  0x11111111,
39  0x22222222,
40  0x33333333,
41  0x44444444,
42  0xaaaaaaaa,
43  0xbbbbbbbb,
44  0xcccccccc,
45  0xdddddddd,
46  },
47  };
48 
49  chip_info_scm_revision_t expected_chip_version = {
50  .scm_revision_low = 0x76543210,
51  .scm_revision_high = 0xcafecafe,
52  };
53 
54  uint32_t expected_rom_ext_slot = kBootSlotA;
55  uint32_t expected_bl0_slot = kBootSlotB;
56 
58  .digest = expected_digest,
59  .identifier = kBootLogIdentifier,
60  .chip_version = expected_chip_version,
61  .rom_ext_slot = expected_rom_ext_slot,
62  .bl0_slot = expected_bl0_slot,
63  };
64 };
65 
66 TEST_F(BootLogTest, DigestUpdate) {
67  // Have the HMAC function return a different digest
68  hmac_digest_t new_digest = {
69  .digest =
70  {
71  0xffffffff,
72  0xeeeeeeee,
73  0xdddddddd,
74  0xcccccccc,
75  0x00000000,
76  0x11111111,
77  0x22222222,
78  0x33333333,
79  },
80  };
81  EXPECT_NE(new_digest, expected_digest);
82 
83  void *expected_digest_region_start =
84  (char *)&boot_log + sizeof(hmac_digest_t);
85  size_t expected_digest_region_len =
86  sizeof(boot_log_t) - sizeof(hmac_digest_t);
87  EXPECT_CALL(hmac_sha256_, sha256(expected_digest_region_start,
88  expected_digest_region_len, _))
89  .WillOnce(testing::SetArgPointee<2>(new_digest));
90 
91  boot_log_digest_update(&boot_log);
92 
93  // Check that the digest field in boot_log has been updated correctly
94  EXPECT_EQ(new_digest, boot_log.digest);
95  // Ensure no other fields changed
96  EXPECT_EQ(kBootLogIdentifier, boot_log.identifier);
97  EXPECT_EQ(expected_rom_ext_slot, boot_log.rom_ext_slot);
98  EXPECT_EQ(expected_bl0_slot, boot_log.bl0_slot);
99  EXPECT_EQ(expected_chip_version, boot_log.chip_version);
100 }
101 
102 TEST_F(BootLogTest, BootLogCheckSuccess) {
103  // Have the HMAC function return a matching digest
104  hmac_digest_t new_digest = {
105  .digest =
106  {
107  0x11111111,
108  0x22222222,
109  0x33333333,
110  0x44444444,
111  0xaaaaaaaa,
112  0xbbbbbbbb,
113  0xcccccccc,
114  0xdddddddd,
115  },
116  };
117  EXPECT_EQ(new_digest, expected_digest);
118 
119  void *expected_digest_region_start =
120  (char *)&boot_log + sizeof(hmac_digest_t);
121  size_t expected_digest_region_len =
122  sizeof(boot_log_t) - sizeof(hmac_digest_t);
123  EXPECT_CALL(hmac_sha256_, sha256(expected_digest_region_start,
124  expected_digest_region_len, _))
125  .WillOnce(testing::SetArgPointee<2>(new_digest));
126 
127  uint32_t error = boot_log_check(&boot_log);
128  EXPECT_EQ(error, kErrorOk);
129 
130  // Ensure no fields have been changed
131  EXPECT_EQ(expected_digest, boot_log.digest);
132  EXPECT_EQ(kBootLogIdentifier, boot_log.identifier);
133  EXPECT_EQ(expected_rom_ext_slot, boot_log.rom_ext_slot);
134  EXPECT_EQ(expected_bl0_slot, boot_log.bl0_slot);
135  EXPECT_EQ(expected_chip_version, boot_log.chip_version);
136 }
137 
138 TEST_F(BootLogTest, BootLogCheckFailure) {
139  // Have the HMAC function return a non-matching digest
140  hmac_digest_t new_digest = {
141  .digest =
142  {
143  0x21111111,
144  0x22222222,
145  0x33333333,
146  0x44444444,
147  0xaaaaaaaa,
148  0xbbbbbbbb,
149  0xcccccccc,
150  0xdddddddd,
151  },
152  };
153  EXPECT_NE(new_digest, expected_digest);
154 
155  void *expected_digest_region_start =
156  (char *)&boot_log + sizeof(hmac_digest_t);
157  size_t expected_digest_region_len =
158  sizeof(boot_log_t) - sizeof(hmac_digest_t);
159  EXPECT_CALL(hmac_sha256_, sha256(expected_digest_region_start,
160  expected_digest_region_len, _))
161  .WillOnce(testing::SetArgPointee<2>(new_digest));
162 
163  uint32_t error = boot_log_check(&boot_log);
164  EXPECT_EQ(error, kErrorBootLogInvalid);
165 
166  // Ensure no fields have been changed
167  EXPECT_EQ(expected_digest, boot_log.digest);
168  EXPECT_EQ(kBootLogIdentifier, boot_log.identifier);
169  EXPECT_EQ(expected_rom_ext_slot, boot_log.rom_ext_slot);
170  EXPECT_EQ(expected_bl0_slot, boot_log.bl0_slot);
171  EXPECT_EQ(expected_chip_version, boot_log.chip_version);
172 }
173 
174 } // namespace
175 } // namespace boot_log_unittest