Software APIs
rom_ctrl_integrity_check_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 
5 #include "dt/dt_lc_ctrl.h" // Generated
6 #include "dt/dt_rom_ctrl.h" // Generated
12 #include "sw/device/lib/testing/test_framework/check.h"
14 #include "sw/device/lib/testing/test_framework/status.h"
15 
16 static dif_lc_ctrl_t lc;
17 static dt_lc_ctrl_t kLcCtrlDt = (dt_lc_ctrl_t)0;
18 static_assert(kDtLcCtrlCount >= 1, "This test needs a lifecycle controller");
19 static dif_rom_ctrl_t rom_ctrl;
20 static dt_rom_ctrl_t kRomCtrlDt = (dt_rom_ctrl_t)0;
21 static_assert(kDtRomCtrlCount >= 1,
22  "This test requires at least one rom_ctrl instance");
23 
24 OTTF_DEFINE_TEST_CONFIG();
25 
26 // The testbench will start in a non-production LC state.
27 // It will use backdoor access to overwrite one of the expected
28 // digests present in the ROM image which will cause the integrity check
29 // to fail. Because we are in the non-production LC state we expect
30 // to still boot and run this code. Upon reaching the wait for interrupt
31 // the testbench will reset the system into production LC state. We should then
32 // not expect a successful boot with the failed integrity check.
33 
34 bool test_main(void) {
35  CHECK_DIF_OK(dif_lc_ctrl_init_from_dt(kLcCtrlDt, &lc));
36  CHECK_DIF_OK(dif_rom_ctrl_init_from_dt(kRomCtrlDt, &rom_ctrl));
37 
38  // Check that the LC_STATE is not PROD as the boot is not
39  // expected to be successful in that state.
40  dif_lc_ctrl_state_t lc_state;
41  CHECK_DIF_OK(dif_lc_ctrl_get_state(&lc, &lc_state));
42  CHECK(lc_state != kDifLcCtrlStateProd, "PROD LC_STATE not expected.");
43 
44  // Check that the upper expected digest in the ROM has been
45  // modified and no longer matches the calculated digest. If it matches
46  // then the testbench has not successfully overwritten the digest.
47  dif_rom_ctrl_digest_t computed_digest;
48  dif_rom_ctrl_digest_t expected_digest;
49  CHECK_DIF_OK(dif_rom_ctrl_get_digest(&rom_ctrl, &computed_digest));
50  CHECK_DIF_OK(dif_rom_ctrl_get_expected_digest(&rom_ctrl, &expected_digest));
51  CHECK_ARRAYS_NE(expected_digest.digest, computed_digest.digest,
52  ROM_CTRL_DIGEST_MULTIREG_COUNT);
53 
54  // set test_status to wfi and call wait_for_interrupt to make
55  // the cpu idle, the testbench sequence will wait for this test
56  // status and issue a reset once it gets this far.
57  LOG_INFO("Waiting for interrupt.");
58  test_status_set(kTestStatusInWfi);
60 
61  return true;
62 }