Software APIs
otp_ctrl_lc_signals_test.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 
13 #include "sw/device/lib/testing/keymgr_testutils.h"
14 #include "sw/device/lib/testing/kmac_testutils.h"
15 #include "sw/device/lib/testing/lc_ctrl_testutils.h"
16 #include "sw/device/lib/testing/otp_ctrl_testutils.h"
17 #include "sw/device/lib/testing/rstmgr_testutils.h"
18 #include "sw/device/lib/testing/test_framework/check.h"
19 #include "sw/device/lib/testing/test_framework/ottf_test_config.h"
21 #include "sw/device/silicon_creator/lib/drivers/retention_sram.h"
22 
24 #include "otp_ctrl_regs.h"
25 
26 static dif_lc_ctrl_t lc;
27 static dif_otp_ctrl_t otp;
28 static dif_rstmgr_t rstmgr;
29 static dif_keymgr_t keymgr;
30 static dif_kmac_t kmac;
31 static dif_flash_ctrl_state_t flash;
32 
33 // LC RMA token value in OTP SECRET2 partition.
34 static const uint8_t kOtpRmaToken[OTP_CTRL_PARAM_RMA_TOKEN_SIZE] = {
35  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
36  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
37 };
38 
39 // Root key share 0 in OTP SECRET2 partition.
40 static const uint8_t
41  kOtpRootKeyShare0[OTP_CTRL_PARAM_CREATOR_ROOT_KEY_SHARE0_SIZE] = {
42  0x6e, 0x70, 0x48, 0x68, 0xa3, 0x2f, 0xfa, 0x1b, 0xd8, 0x36, 0x4d,
43  0x00, 0x79, 0xbd, 0x04, 0xe6, 0x53, 0x18, 0xfc, 0xc3, 0xc9, 0xdd,
44  0x39, 0xfa, 0xe0, 0x18, 0x49, 0x69, 0xc9, 0x81, 0x05, 0x17,
45 };
46 
47 // Root key share 1 in OTP SECRET2 partition.
48 static const uint8_t
49  kOtpRootKeyShare1[OTP_CTRL_PARAM_CREATOR_ROOT_KEY_SHARE1_SIZE] = {
50  0x2f, 0x78, 0x6f, 0x93, 0x9a, 0xc4, 0xcf, 0x95, 0xb6, 0xec, 0x61,
51  0x76, 0xbd, 0x08, 0x05, 0x0c, 0x09, 0x89, 0xe1, 0x73, 0x4b, 0x0a,
52  0x59, 0x1b, 0xdd, 0x34, 0x84, 0x82, 0x32, 0x9a, 0x93, 0x31};
53 
54 // Enum that encodes the possible test modes.
55 typedef enum { kWriteMode, kReadMode, kWriteReadMode } test_mode_t;
56 
57 OTTF_DEFINE_TEST_CONFIG();
58 
59 /**
60  * Initialize the peripherals used in this test.
61  */
62 static void init_peripherals(void) {
63  dif_otp_ctrl_config_t config = {
64  .check_timeout = 100000,
65  .integrity_period_mask = 0x3ffff,
66  .consistency_period_mask = 0x3ffffff,
67  };
68  // Life cycle
69  CHECK_DIF_OK(dif_lc_ctrl_init(
71  // OTP
72  CHECK_DIF_OK(dif_otp_ctrl_init(
74  CHECK_DIF_OK(dif_otp_ctrl_configure(&otp, config));
75  // Rstmgr
76  CHECK_DIF_OK(dif_rstmgr_init(
78  // KMAC (init for Keymgr use)
79  CHECK_DIF_OK(
80  dif_kmac_init(mmio_region_from_addr(TOP_EARLGREY_KMAC_BASE_ADDR), &kmac));
81  CHECK_STATUS_OK(kmac_testutils_config(&kmac, true));
82  // Keymgr
83  CHECK_DIF_OK(dif_keymgr_init(
85  // Flash
86  CHECK_DIF_OK(dif_flash_ctrl_init_state(
88 }
89 
90 /**
91  * Attempt to write the buffer to the specified address within the SECRET2
92  * partition. If exp_result is set to kExpectFailed, the test expects the
93  * access to fail with a DAI access error. If exp_result is set to
94  * kExpectPassed, the test expects the test to pass without errors.
95  */
96 static void otp_write_test(uint32_t address, const uint8_t *buffer,
97  uint32_t size, exp_test_result_t exp_result) {
98  CHECK_STATUS_OK(otp_ctrl_testutils_wait_for_dai(&otp));
99  for (uint32_t i = address; i < address + size; i += sizeof(uint64_t)) {
100  uint64_t word;
101  memcpy(&word, &buffer[i], sizeof(word));
102  CHECK_DIF_OK(
104  CHECK_STATUS_OK(otp_ctrl_testutils_wait_for_dai(&otp));
105  CHECK(address <= INT32_MAX, "address must fit into int32_t");
106  CHECK_STATUS_OK(otp_ctrl_testutils_dai_access_error_check(
107  &otp, exp_result, (int32_t)address));
108  }
109 }
110 
111 /**
112  * Attempt to read the OTP contents at the specified address within the SECRET2
113  * partition, and compares the read data to the data in the buffer. If
114  * exp_result is set to kExpectFailed, the test expects the access to fail
115  * with a DAI access error, and it also expects the read data to NOT match with
116  * the data in the buffer. If exp_result is set to kExpectPassed, the test
117  * expects the test to pass without errors and the read data to match with the
118  * data in the buffer.
119  */
120 static void otp_read_test(uint32_t address, const uint8_t *buffer,
121  uint32_t size, exp_test_result_t exp_result) {
122  CHECK_STATUS_OK(otp_ctrl_testutils_wait_for_dai(&otp));
123  for (uint32_t i = address; i < address + size; i += sizeof(uint64_t)) {
124  uint64_t got, exp;
125  CHECK_DIF_OK(
127  CHECK_STATUS_OK(otp_ctrl_testutils_wait_for_dai(&otp));
128  CHECK(address <= INT32_MAX, "address must fit into int32_t");
129  CHECK_STATUS_OK(otp_ctrl_testutils_dai_access_error_check(
130  &otp, exp_result, (int32_t)address));
131 
132  // Check whether the read data matches.
133  memcpy(&exp, &buffer[i], sizeof(exp));
134  CHECK_DIF_OK(dif_otp_ctrl_dai_read64_end(&otp, &got));
135  if (exp_result == kExpectFailed) {
136  CHECK(got != exp,
137  "0x%x == 0x%x (got == exp) is not expected at address 0x%x",
138  (uint32_t)got, (uint32_t)exp, address);
139  } else {
140  CHECK(got == exp,
141  "0x%x != 0x%x (got != exp) is not expected at address 0x%x",
142  (uint32_t)got, (uint32_t)exp, address);
143  }
144  }
145 }
146 
147 /**
148  * Test wrapper function that first calls the write and then the read test.
149  */
150 static void otp_write_read_test(test_mode_t test_mode, uint32_t address,
151  const uint8_t *buffer, uint32_t size,
152  exp_test_result_t exp_result) {
153  if (test_mode == kWriteMode || test_mode == kWriteReadMode) {
154  LOG_INFO("Write test at 0x%x...", address);
155  otp_write_test(address, buffer, size, exp_result);
156  }
157  if (test_mode == kReadMode || test_mode == kWriteReadMode) {
158  LOG_INFO("Read test at 0x%x...", address);
159  otp_read_test(address, buffer, size, exp_result);
160  }
161 }
162 
163 /**
164  * Test wrapper function that calls the write and read tests above for all
165  * objects within the SECRET2 partition.
166  */
167 static void run_otp_access_tests(test_mode_t test_mode,
168  exp_test_result_t exp_result) {
169  otp_write_read_test(
170  test_mode,
171  OTP_CTRL_PARAM_RMA_TOKEN_OFFSET - OTP_CTRL_PARAM_SECRET2_OFFSET,
172  (uint8_t *)kOtpRmaToken, OTP_CTRL_PARAM_RMA_TOKEN_SIZE, exp_result);
173  otp_write_read_test(test_mode,
174  OTP_CTRL_PARAM_CREATOR_ROOT_KEY_SHARE0_OFFSET -
175  OTP_CTRL_PARAM_SECRET2_OFFSET,
176  (uint8_t *)kOtpRootKeyShare0,
177  OTP_CTRL_PARAM_CREATOR_ROOT_KEY_SHARE0_SIZE, exp_result);
178  otp_write_read_test(test_mode,
179  OTP_CTRL_PARAM_CREATOR_ROOT_KEY_SHARE1_OFFSET -
180  OTP_CTRL_PARAM_SECRET2_OFFSET,
181  (uint8_t *)kOtpRootKeyShare1,
182  OTP_CTRL_PARAM_CREATOR_ROOT_KEY_SHARE1_SIZE, exp_result);
183 }
184 
185 /**
186  * Try to initialize and advance to kDifKeymgrStateCreatorRootKey state.
187  *
188  * @param expect_init_fail Whether initialization is expected to fail.
189  */
190 static void keymgr_advance_to_creator_root_key(bool expect_init_fail) {
191  // Check the last word of the retention SRAM creator area to determine the
192  // type of the ROM.
193  bool is_using_test_rom =
194  retention_sram_get()
195  ->creator
196  .reserved[ARRAYSIZE((retention_sram_t){0}.creator.reserved) - 1] ==
198 
199  // Advance from Reset to Initialized state (or expect it to fail).
200  CHECK_STATUS_OK(keymgr_testutils_check_state(&keymgr, kDifKeymgrStateReset));
201  CHECK_STATUS_OK(keymgr_testutils_advance_state(&keymgr, NULL));
202  const dif_keymgr_state_t exp_state =
204  CHECK_STATUS_OK(keymgr_testutils_check_state(&keymgr, exp_state));
205 
206  // Advance to Creator Root Key state (or expect it to fail as well).
207  if (is_using_test_rom) {
208  LOG_INFO("Using test_rom, setting inputs and advancing state...");
209  CHECK((kDifOk == dif_keymgr_advance_state(&keymgr, &kCreatorParams)) ^
210  expect_init_fail);
211  } else {
212  LOG_INFO("Using rom, only advancing state...");
213  CHECK((kDifOk == dif_keymgr_advance_state_raw(&keymgr)) ^ expect_init_fail);
214  }
215 }
216 
217 /**
218  * Checks that the first advance command does not complete.
219  */
220 static void keymgr_check_cannot_advance(void) {
221  LOG_INFO("Check that the Keymgr cannot advance...");
222  CHECK_STATUS_OK(keymgr_testutils_check_state(&keymgr, kDifKeymgrStateReset));
223  // Try to initialize the key manager. We expect this call to fail with
224  // a "kDifLocked" code, since the key manager is not enabled.
225  CHECK(kDifLocked == dif_keymgr_advance_state(&keymgr, NULL),
226  "Keymgr is not expected to be available in this LC state.");
227 }
228 
229 /**
230  * Check that the key manager flags the KMAC inputs as invalid. This happens
231  * when the root keys are not valid and hence tied to all-zero inside the key
232  * manager.
233  */
234 static void keymgr_check_root_key_is_invalid(void) {
235  LOG_INFO("Trying to advance to Creator Root Key and expecting failure...");
236  keymgr_advance_to_creator_root_key(/*expect_init_fail=*/true);
237 }
238 
239 /**
240  * Generate a SW key and store it within the retention SRAM.
241  */
242 static void keymgr_check_can_generate_key(void) {
243  LOG_INFO("Trying to advance to Creator Root Key and expecting success...");
244  keymgr_advance_to_creator_root_key(/*expect_init_fail=*/false);
245  LOG_INFO("Check that the Keymgr can generate a key...");
246  CHECK_STATUS_OK(keymgr_testutils_wait_for_operation_done(&keymgr));
247  CHECK_STATUS_OK(
248  keymgr_testutils_check_state(&keymgr, kDifKeymgrStateCreatorRootKey));
249  CHECK_STATUS_OK(
250  keymgr_testutils_generate_versioned_key(&keymgr, kKeyVersionedParams));
251 }
252 
253 /**
254  * Resets the chip.
255  */
256 static void reset_chip(void) {
257  CHECK_DIF_OK(dif_rstmgr_software_device_reset(&rstmgr));
258  busy_spin_micros(100);
259  CHECK(false, "Should have reset before this line");
260 }
261 
262 /**
263  * This tests the impact of the lc_creator_seed_sw_rw_en and lc_seed_hw_rd_en
264  * life cycle access control signals on the SECRET2 partition. Since it uses
265  * the key manager to perform some of the testing, this test also checks the
266  * impact of lc_keymgr_en on the key manager.
267  *
268  * The SECRETT2 partition should only be readable/writable by SW in
269  * PROD/RMA/DEV. Once it is locked, the partition is not accessible by SW
270  * anymore, but becomes accessible to HW (key manager).
271  *
272  * The test can be run in different life cycle states and figure out what to
273  * check based on the state exposed in the life cycle controller.
274  *
275  * PROD/DEV/RMA:
276  * 1) Provision non-constant creator/owner secrets to flash
277  * 2) Program SECRET2 partition and read it back
278  * 3) Check that the key manager advance errors out due to all-zero root key
279  * 4) Reset the chip
280  * 5) Check that the SECRET2 partition can still be read
281  * 6) Check that the key manager advance errors out due to all-zero root key
282  * 7) Lock the SECRET2 partition
283  * 8) Reset the chip
284  * 9) Check that the SECRET2 partition is not accessible anymore
285  * 10) Check that the key manager can generate a SW key without errors
286  *
287  * All other life cycle states:
288  * 1) Check that key manager cannot be initialized because it is disabled
289  * 2) Check the SECRET2 partition is not accessible
290  *
291  */
292 bool test_main(void) {
293  bool is_computed;
294  dif_lc_ctrl_state_t state;
296  init_peripherals();
297 
298  rst_info = rstmgr_testutils_reason_get();
299  rstmgr_testutils_reason_clear();
300 
301  CHECK_DIF_OK(dif_lc_ctrl_get_state(&lc, &state));
302  CHECK_STATUS_OK(lc_ctrl_testutils_lc_state_log(&state));
303 
304  switch (state) {
305  case kDifLcCtrlStateDev:
306  case kDifLcCtrlStateProd:
308  case kDifLcCtrlStateRma:
309  if (rst_info & kDifRstmgrResetInfoPor) {
310  LOG_INFO("First access test iteration...");
311  // Make sure the secrets in flash are non-zero.
312  CHECK_STATUS_OK(keymgr_testutils_flash_init(&flash, &kCreatorSecret,
313  &kOwnerSecret));
314  // Program the SECRET2 partition and perform read back test.
315  run_otp_access_tests(kWriteReadMode, kExpectPassed);
316  // We expect the root key to be invalid at this point.
317  keymgr_check_root_key_is_invalid();
318  reset_chip();
319 
320  } else if (rst_info == kDifRstmgrResetInfoSw) {
321  CHECK_DIF_OK(dif_otp_ctrl_is_digest_computed(
322  &otp, kDifOtpCtrlPartitionSecret2, &is_computed));
323 
324  if (!is_computed) {
325  LOG_INFO("Second access test iteration...");
326  // SECRET2 partition should still be readable.
327  run_otp_access_tests(kReadMode, kExpectPassed);
328  // We expect the root key to still be invalid at this point, since
329  // SECRET2 has not been locked yet.
330  keymgr_check_root_key_is_invalid();
331  // Lock the SECRET2 partition.
332  CHECK_STATUS_OK(otp_ctrl_testutils_lock_partition(
333  &otp, kDifOtpCtrlPartitionSecret2, 0));
334  reset_chip();
335  } else {
336  LOG_INFO("Third access test iteration...");
337  // All accesses are disallowed.
338  run_otp_access_tests(kWriteReadMode, kExpectFailed);
339  // At this point we expect that the key manager can generate keys
340  // without errors.
341  keymgr_check_can_generate_key();
342  // Test passed.
343  return true;
344  }
345  } else {
346  LOG_ERROR("Unexpected reset info 0x%02X", rst_info);
347  }
348 
349  break;
350  default: // this covers all TEST_UNLOCKED* states.
351  // Accesses to the SECRET2 partition should error out.
352  run_otp_access_tests(kWriteReadMode, kExpectFailed);
353  // Keymgr initialization should not work in this state.
354  keymgr_check_cannot_advance();
355  // Test passed.
356  return true;
357  }
358 
359  return false;
360 }