Software APIs
keymgr_functest.c
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 <stdbool.h>
6 #include <stdint.h>
7 
17 #include "sw/device/lib/testing/keymgr_testutils.h"
18 #include "sw/device/lib/testing/otp_ctrl_testutils.h"
19 #include "sw/device/lib/testing/pwrmgr_testutils.h"
20 #include "sw/device/lib/testing/rstmgr_testutils.h"
21 #include "sw/device/lib/testing/test_framework/check.h"
25 #include "sw/device/silicon_creator/lib/drivers/keymgr.h"
26 #include "sw/device/silicon_creator/lib/drivers/kmac.h"
27 #include "sw/device/silicon_creator/lib/drivers/lifecycle.h"
28 #include "sw/device/silicon_creator/lib/drivers/retention_sram.h"
29 #include "sw/device/silicon_creator/lib/error.h"
30 #include "sw/device/silicon_creator/lib/keymgr_binding_value.h"
31 
33 #include "keymgr_regs.h"
34 #include "kmac_regs.h"
35 
36 #define ASSERT_OK(expr_) \
37  do { \
38  rom_error_t local_error_ = expr_; \
39  if (local_error_ != kErrorOk) { \
40  LOG_ERROR("Error at line: %d", __LINE__); \
41  return local_error_; \
42  } \
43  } while (0)
44 
45 #define ASSERT_EQZ(x) CHECK((x) == 0)
46 
47 enum {
48  /** Flash Secret partition ID. */
49  kFlashInfoPartitionId = 0,
50 
51  /** Secret partition flash bank ID. */
52  kFlashInfoBankId = 0,
53 
54  /** Creator Secret flash info page ID. */
55  kFlashInfoPageIdCreatorSecret = 1,
56 
57  /** Owner Secret flash info page ID. */
58  kFlashInfoPageIdOwnerSecret = 2,
59 
60  /** Key manager secret word size. */
61  kSecretWordSize = 16,
62 
63  /** KMAC prefix word size. */
64  kKmacPrefixSize = 11,
65 };
66 
67 /**
68  * Software binding value associated with the ROM. Programmed by the ROM.
69  */
70 const keymgr_binding_value_t kBindingValueRom = {
71  .data = {0x7c9b2405, 0x1841a738, 0xdb24005d, 0x4dbd6a17, 0x362f1673,
72  0x1d8ede70, 0x0104d346, 0x1a0806c2},
73 };
74 
75 /**
76  * Software binding value associated with the ROM_EXT. Programmed by ROM.
77  */
78 const keymgr_binding_value_t kBindingValueRomExt = {
79  .data = {0xdc96c23d, 0xaf36e268, 0xcb68ff71, 0xe92f76e2, 0xb8a8379d,
80  0x426dc745, 0x19f5cff7, 0x4ec9c6d6},
81 };
82 
83 /**
84  * Software binding value associated with BL0. Programmed by ROM_EXT.
85  */
86 const keymgr_binding_value_t kBindingValueBl0 = {
87  .data = {0xe4987b39, 0x3f83d390, 0xc2f3bbaf, 0x3195dbfa, 0x23fb480c,
88  0xb012ae5e, 0xf1394d28, 0x1940ceeb},
89 };
90 
91 /**
92  * Kmac prefix "KMAC" with empty custom string
93  */
94 const uint32_t kKmacPrefix[kKmacPrefixSize] = {
95  0x4d4b2001, 0x00014341, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
96 };
97 
98 /** ROM key manager maximum version. */
99 const uint32_t kMaxVerRom = 1;
100 
101 /** ROM_EXT key manager maximum version. */
102 const uint32_t kMaxVerRomExt = 2;
103 
104 /** BL0 key manager maximum version. */
105 const uint32_t kMaxVerBl0 = 3;
106 
107 OTTF_DEFINE_TEST_CONFIG();
108 
109 static void init_flash(void) {
111 
112  CHECK_DIF_OK(dif_flash_ctrl_init_state(
114 
115  // Initialize flash secrets.
116  CHECK_STATUS_OK(
117  keymgr_testutils_flash_init(&flash, &kCreatorSecret, &kOwnerSecret));
118 }
119 
120 static void check_lock_otp_partition(const dif_otp_ctrl_t *otp) {
121  bool is_computed;
123  &is_computed));
124  if (is_computed) {
125  uint64_t digest;
126  CHECK_DIF_OK(
128  LOG_INFO("OTP partition locked. Digest: %x-%x", ((uint32_t *)&digest)[0],
129  ((uint32_t *)&digest)[1]);
130  return;
131  }
132  CHECK_STATUS_OK(
133  otp_ctrl_testutils_lock_partition(otp, kDifOtpCtrlPartitionSecret2, 0));
134 }
135 
136 /** Key manager configuration steps performed in ROM. */
137 rom_error_t keymgr_rom_test(void) {
138  ASSERT_OK(sc_keymgr_state_check(kScKeymgrStateReset));
139  if (retention_sram_get()
140  ->creator
141  .reserved[ARRAYSIZE((retention_sram_t){0}.creator.reserved) - 1] ==
143  // Test ROM does not set the binding / max key registers, like the ROM does.
144  sc_keymgr_sw_binding_set(&kBindingValueRom, &kBindingValueRom);
145  sc_keymgr_creator_max_ver_set(kMaxVerRom);
146  SEC_MMIO_WRITE_INCREMENT(kScKeymgrSecMmioSwBindingSet +
147  kScKeymgrSecMmioCreatorMaxVerSet);
148  }
149  sec_mmio_check_values(/*rnd_offset=*/0);
150  CHECK(abs_mmio_read32(TOP_EARLGREY_KEYMGR_BASE_ADDR +
151  KEYMGR_SW_BINDING_REGWEN_REG_OFFSET) == 0,
152  "Keymgr SW binding should be locked in Reset state.");
153 
154  const uint16_t kEntropyReseedInterval = 0x1234;
155  sc_keymgr_entropy_reseed_interval_set(kEntropyReseedInterval);
156  SEC_MMIO_WRITE_INCREMENT(kScKeymgrSecMmioEntropyReseedIntervalSet);
157  sec_mmio_check_values(/*rnd_offset=*/0);
158 
159  // Advance keymgr to Initialized state.
160  sc_keymgr_advance_state();
161  ASSERT_OK(sc_keymgr_state_check(kScKeymgrStateInit));
162  LOG_INFO("Keymgr State: Init");
163  CHECK(abs_mmio_read32(TOP_EARLGREY_KEYMGR_BASE_ADDR +
164  KEYMGR_SW_BINDING_REGWEN_REG_OFFSET) == 0,
165  "Keymgr SW binding should be locked in Initialized state.");
166  if (retention_sram_get()
167  ->creator
168  .reserved[ARRAYSIZE((retention_sram_t){0}.creator.reserved) - 1] ==
170  CHECK(abs_mmio_read32(TOP_EARLGREY_KEYMGR_BASE_ADDR +
171  KEYMGR_ATTEST_SW_BINDING_0_REG_OFFSET) ==
172  kBindingValueRom.data[0],
173  "Keymgr Attestation SW Binding value should be value set by ROM "
174  "during Initialized state.");
175  CHECK(abs_mmio_read32(TOP_EARLGREY_KEYMGR_BASE_ADDR +
176  KEYMGR_ATTEST_SW_BINDING_7_REG_OFFSET) ==
177  kBindingValueRom.data[7],
178  "Keymgr Attestation SW Binding value should be value set by ROM "
179  "during Initialized state.");
180  CHECK(abs_mmio_read32(TOP_EARLGREY_KEYMGR_BASE_ADDR +
181  KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET) ==
182  kBindingValueRom.data[0],
183  "Keymgr Sealing SW Binding value should be value set by ROM "
184  "during Initialized state.");
185  CHECK(abs_mmio_read32(TOP_EARLGREY_KEYMGR_BASE_ADDR +
186  KEYMGR_SEALING_SW_BINDING_7_REG_OFFSET) ==
187  kBindingValueRom.data[7],
188  "Keymgr Sealing SW Binding value should be value set by ROM "
189  "during Initialized state.");
190  }
191 
192  // Advance keymgr to CreatorRootKey state.
193  sc_keymgr_advance_state();
194  ASSERT_OK(sc_keymgr_state_check(kScKeymgrStateCreatorRootKey));
195  LOG_INFO("Keymgr State: CreatorRootKey");
196  CHECK(abs_mmio_read32(TOP_EARLGREY_KEYMGR_BASE_ADDR +
197  KEYMGR_SW_BINDING_REGWEN_REG_OFFSET) == 1,
198  "Keymgr SW binding should be unlocked after transitioning to "
199  "CreatorRootKey state.");
200 
201  // The software binding register lock is reset after advancing the key
202  // manager, so we need to call this function to update sec_mmio expectation
203  // table.
204  sc_keymgr_sw_binding_unlock_wait();
205  sec_mmio_check_values(/*rnd_offset=*/0);
206 
207  // Advance keymgr to OwnerIntermediateKey state.
208  sc_keymgr_sw_binding_set(&kBindingValueRomExt, &kBindingValueRomExt);
209  sc_keymgr_owner_int_max_ver_set(kMaxVerRomExt);
210  SEC_MMIO_WRITE_INCREMENT(kScKeymgrSecMmioSwBindingSet +
211  kScKeymgrSecMmioOwnerIntMaxVerSet);
212  sec_mmio_check_values(/*rnd_offset=*/0);
213  CHECK(abs_mmio_read32(TOP_EARLGREY_KEYMGR_BASE_ADDR +
214  KEYMGR_SW_BINDING_REGWEN_REG_OFFSET) == 0,
215  "Keymgr SW binding should be locked before transitioning to "
216  "OwnerIntermediateKey state.");
217  sc_keymgr_advance_state();
218  ASSERT_OK(sc_keymgr_state_check(kScKeymgrStateOwnerIntermediateKey));
219  LOG_INFO("Keymgr State: OwnerIntermediateKey");
220  CHECK(abs_mmio_read32(TOP_EARLGREY_KEYMGR_BASE_ADDR +
221  KEYMGR_SW_BINDING_REGWEN_REG_OFFSET) == 1,
222  "Keymgr SW binding should be unlocked after transitioning to "
223  "OwnerIntermediateKey state.");
224 
225  sec_mmio_check_counters(/*expected_check_count=*/4);
226  return kErrorOk;
227 }
228 
229 /** Key manager configuration steps performed in ROM_EXT. */
230 rom_error_t keymgr_rom_ext_test(void) {
231  // The software binding register lock is reset after advancing the key
232  // manager, so we need to call this function to update sec_mmio expectation
233  // table.
234  sc_keymgr_sw_binding_unlock_wait();
235  sec_mmio_check_values(/*rnd_offset=*/0);
236 
237  // Advance keymgr to OwnerKey state.
238  sc_keymgr_sw_binding_set(&kBindingValueBl0, &kBindingValueBl0);
239  CHECK(abs_mmio_read32(TOP_EARLGREY_KEYMGR_BASE_ADDR +
240  KEYMGR_SW_BINDING_REGWEN_REG_OFFSET) == 0,
241  "Keymgr SW binding should be locked before transitioning to "
242  "OwnerKey state.");
243  sc_keymgr_owner_max_ver_set(kMaxVerBl0);
244  SEC_MMIO_WRITE_INCREMENT(kScKeymgrSecMmioSwBindingSet +
245  kScKeymgrSecMmioOwnerMaxVerSet);
246  sec_mmio_check_values(/*rnd_offset=*/0);
247  sc_keymgr_advance_state();
248  ASSERT_OK(sc_keymgr_state_check(kScKeymgrStateOwnerKey));
249  LOG_INFO("Keymgr State: OwnerKey");
250  CHECK(abs_mmio_read32(TOP_EARLGREY_KEYMGR_BASE_ADDR +
251  KEYMGR_SW_BINDING_REGWEN_REG_OFFSET) == 1,
252  "Keymgr SW binding should be unlocked after transitioning to "
253  "Owner state.");
254 
255  sec_mmio_check_counters(/*expected_check_count=*/7);
256  return kErrorOk;
257 }
258 
259 bool test_main(void) {
260  status_t result = OK_STATUS();
261  dif_rstmgr_t rstmgr;
263 
264  lifecycle_state_t lc_state = lifecycle_state_get();
265  CHECK(lc_state == kLcStateRma || lc_state == kLcStateDev ||
266  lc_state == kLcStateProd || lc_state == kLcStateProdEnd,
267  "The test is configured to run in RMA mode.");
268 
269  CHECK_DIF_OK(dif_rstmgr_init(
271  info = rstmgr_testutils_reason_get();
272 
273  dif_otp_ctrl_t otp;
274  CHECK_DIF_OK(dif_otp_ctrl_init(
276 
277  if (info & kDifRstmgrResetInfoPor) {
278  LOG_INFO("Powered up for the first time, program flash");
279  init_flash();
280 
281  // This is done after `init_flash()` because in DEV and PROD stages the
282  // info flash secret partition becomes unavailable.
283  check_lock_otp_partition(&otp);
284 
285  // Issue and wait for reset.
286  rstmgr_testutils_reason_clear();
287  CHECK_DIF_OK(dif_rstmgr_software_device_reset(&rstmgr));
289  } else if (info == kDifRstmgrResetInfoSw) {
290  LOG_INFO("Powered up for the second time, actuate keymgr");
291 
292  check_lock_otp_partition(&otp);
293  sec_mmio_init();
294  kmac_keymgr_configure();
295 
296  EXECUTE_TEST(result, keymgr_rom_test);
297  EXECUTE_TEST(result, keymgr_rom_ext_test);
298  return status_ok(result);
299  } else {
300  LOG_FATAL("Unexpected reset reason unexpected: %08x", info);
301  }
302 
303  return false;
304 }