From bfd4ce6005005256ea7297283ffe942a186f5a36 Mon Sep 17 00:00:00 2001 From: Chris Frantz Date: Wed, 7 Aug 2024 09:16:41 -0700 Subject: [PATCH] [boot_svc] Handle empty messages like other boot_svc messages 1. Add a `BootSvcEmptyResType` to represent empty message responses. 2. Create an empty response message that is the request message with only the `type` changed to the response type. 3. Handle the empty request in the ROM_EXT in a similar way to all other boot service messages. 4. Update the `empty_test` to confirm that the request message results in a response message. Signed-off-by: Chris Frantz (cherry picked from commit c8a493fed304aa3f8fbb24635ad873431a954900) --- .../silicon_creator/lib/boot_svc/boot_svc_empty.c | 15 +++++++++++---- .../silicon_creator/lib/boot_svc/boot_svc_empty.h | 15 ++++++++++++--- .../lib/boot_svc/boot_svc_empty_unittest.cc | 4 ++-- .../silicon_creator/rom_ext/e2e/boot_svc/BUILD | 4 ++-- .../rom_ext/e2e/boot_svc/boot_svc_empty_test.c | 4 ++-- .../e2e/boot_svc/boot_svc_min_sec_ver_test.c | 1 - sw/device/silicon_creator/rom_ext/rom_ext.c | 6 ++++-- 7 files changed, 33 insertions(+), 16 deletions(-) diff --git a/sw/device/silicon_creator/lib/boot_svc/boot_svc_empty.c b/sw/device/silicon_creator/lib/boot_svc/boot_svc_empty.c index 56c63d206e9db..8216214d1497e 100644 --- a/sw/device/silicon_creator/lib/boot_svc/boot_svc_empty.c +++ b/sw/device/silicon_creator/lib/boot_svc/boot_svc_empty.c @@ -4,15 +4,22 @@ #include "sw/device/silicon_creator/lib/boot_svc/boot_svc_empty.h" -void boot_svc_empty_init(boot_svc_empty_t *msg) { - size_t i = 0, j = kBootSvcEmptyPayloadWordCount - 1; +void boot_svc_empty_req_init(boot_svc_empty_t *msg) { + // We use `uint32_t` instead of `size_t` so that end-of-loop check passes both + // on- and off-target tests. + uint32_t i = 0, j = kBootSvcEmptyPayloadWordCount - 1; for (; launder32(i) < kBootSvcEmptyPayloadWordCount && launder32(j) < kBootSvcEmptyPayloadWordCount; ++i, --j) { msg->payload[i] = 0; } HARDENED_CHECK_EQ(i, kBootSvcEmptyPayloadWordCount); - HARDENED_CHECK_EQ(j, SIZE_MAX); - boot_svc_header_finalize(kBootSvcEmptyType, sizeof(boot_svc_empty_t), + HARDENED_CHECK_EQ(j, UINT32_MAX); + boot_svc_header_finalize(kBootSvcEmptyReqType, sizeof(boot_svc_empty_t), + &msg->header); +} + +void boot_svc_empty_res_init(boot_svc_empty_t *msg) { + boot_svc_header_finalize(kBootSvcEmptyResType, sizeof(boot_svc_empty_t), &msg->header); } diff --git a/sw/device/silicon_creator/lib/boot_svc/boot_svc_empty.h b/sw/device/silicon_creator/lib/boot_svc/boot_svc_empty.h index 99649a5e01679..1391ff626987b 100644 --- a/sw/device/silicon_creator/lib/boot_svc/boot_svc_empty.h +++ b/sw/device/silicon_creator/lib/boot_svc/boot_svc_empty.h @@ -16,7 +16,9 @@ extern "C" { enum { /** Empty boot services request: `EMPT`. */ - kBootSvcEmptyType = 0x54504d45, + kBootSvcEmptyReqType = 0x54504d45, + /** Empty boot services response: `TPME`. */ + kBootSvcEmptyResType = 0x454d5054, kBootSvcEmptyPayloadWordCount = CHIP_BOOT_SVC_MSG_PAYLOAD_SIZE_MAX / sizeof(uint32_t), }; @@ -48,11 +50,18 @@ OT_ASSERT_MEMBER_OFFSET(boot_svc_empty_t, payload, OT_ASSERT_SIZE(boot_svc_empty_t, CHIP_BOOT_SVC_MSG_SIZE_MAX); /** - * Initialize an empty boot services message. + * Initialize an empty boot services request. * * @param[out] msg Output buffer for the message. */ -void boot_svc_empty_init(boot_svc_empty_t *msg); +void boot_svc_empty_req_init(boot_svc_empty_t *msg); + +/** + * Initialize an empty boot services response. + * + * @param[inout] msg Buffer for the message. + */ +void boot_svc_empty_res_init(boot_svc_empty_t *msg); #ifdef __cplusplus } // extern "C" diff --git a/sw/device/silicon_creator/lib/boot_svc/boot_svc_empty_unittest.cc b/sw/device/silicon_creator/lib/boot_svc/boot_svc_empty_unittest.cc index d05926e71662b..a66ccaf38f283 100644 --- a/sw/device/silicon_creator/lib/boot_svc/boot_svc_empty_unittest.cc +++ b/sw/device/silicon_creator/lib/boot_svc/boot_svc_empty_unittest.cc @@ -31,9 +31,9 @@ TEST_F(BootSvcEmptyTest, Init) { boot_svc_empty_t msg{}; EXPECT_CALL(boot_svc_header_, - Finalize(kBootSvcEmptyType, sizeof(msg), &msg.header)); + Finalize(kBootSvcEmptyReqType, sizeof(msg), &msg.header)); - boot_svc_empty_init(&msg); + boot_svc_empty_req_init(&msg); EXPECT_THAT(msg.payload, ElementsAreArray(payload)); } diff --git a/sw/device/silicon_creator/rom_ext/e2e/boot_svc/BUILD b/sw/device/silicon_creator/rom_ext/e2e/boot_svc/BUILD index 41f70d4a73cf1..03907a9c801ff 100644 --- a/sw/device/silicon_creator/rom_ext/e2e/boot_svc/BUILD +++ b/sw/device/silicon_creator/rom_ext/e2e/boot_svc/BUILD @@ -124,12 +124,12 @@ opentitan_test( --exec="fpga clear-bitstream" --exec="fpga load-bitstream {bitstream}" --exec="bootstrap --clear-uart=true {firmware}" - --exec="console --non-interactive --exit-success='ownership_state = LockedNone\r\n' --exit-failure='{exit_failure}'" + --exec="console --non-interactive --exit-success='ownership_state = .x00.x00.x00.x00\r\n' --exit-failure='{exit_failure}'" --exec="rescue boot-svc ownership-unlock \ --mode Any \ --nonce 0 \ --sign $(location //sw/device/silicon_creator/lib/ownership/keys/fake:no_owner_recovery_key)" - --exec="console --non-interactive --exit-success='ownership_state = UnlockedAny\r\n' --exit-failure='{exit_failure}'" + --exec="console --non-interactive --exit-success='ownership_state = UANY\r\n' --exit-failure='{exit_failure}'" no-op """, ), diff --git a/sw/device/silicon_creator/rom_ext/e2e/boot_svc/boot_svc_empty_test.c b/sw/device/silicon_creator/rom_ext/e2e/boot_svc/boot_svc_empty_test.c index c673aa23d6c1d..9f0b9090723d4 100644 --- a/sw/device/silicon_creator/rom_ext/e2e/boot_svc/boot_svc_empty_test.c +++ b/sw/device/silicon_creator/rom_ext/e2e/boot_svc/boot_svc_empty_test.c @@ -16,7 +16,7 @@ OTTF_DEFINE_TEST_CONFIG(); static status_t initialize(retention_sram_t *retram, boot_svc_retram_t *state) { boot_svc_msg_t msg = {0}; - boot_svc_empty_init(&msg.empty); + boot_svc_empty_req_init(&msg.empty); retram->creator.boot_svc_msg = msg; state->state = kBootSvcTestStateCheckEmpty; rstmgr_reset(); @@ -27,7 +27,7 @@ static status_t check_empty(retention_sram_t *retram, boot_svc_retram_t *state) { boot_svc_msg_t msg = retram->creator.boot_svc_msg; TRY(boot_svc_header_check(&msg.header)); - TRY_CHECK(msg.header.type == kBootSvcEmptyType); + TRY_CHECK(msg.header.type == kBootSvcEmptyResType); state->state = kBootSvcTestStateFinal; return OK_STATUS(); } diff --git a/sw/device/silicon_creator/rom_ext/e2e/boot_svc/boot_svc_min_sec_ver_test.c b/sw/device/silicon_creator/rom_ext/e2e/boot_svc/boot_svc_min_sec_ver_test.c index fd164bff03c1d..dfe79e77a0d5d 100644 --- a/sw/device/silicon_creator/rom_ext/e2e/boot_svc/boot_svc_min_sec_ver_test.c +++ b/sw/device/silicon_creator/rom_ext/e2e/boot_svc/boot_svc_min_sec_ver_test.c @@ -17,7 +17,6 @@ OTTF_DEFINE_TEST_CONFIG(); static status_t initialize(retention_sram_t *retram, boot_svc_retram_t *state) { boot_svc_msg_t msg = {0}; - boot_svc_empty_init(&msg.empty); boot_svc_min_bl0_sec_ver_req_init(2, &msg.min_bl0_sec_ver_req); retram->creator.boot_svc_msg = msg; state->state = kBootSvcTestStateMinSecAdvance; diff --git a/sw/device/silicon_creator/rom_ext/rom_ext.c b/sw/device/silicon_creator/rom_ext/rom_ext.c index 0acefc169d245..9f9bf46387e03 100644 --- a/sw/device/silicon_creator/rom_ext/rom_ext.c +++ b/sw/device/silicon_creator/rom_ext/rom_ext.c @@ -757,8 +757,9 @@ static rom_error_t handle_boot_svc(boot_data_t *boot_data) { HARDENED_RETURN_IF_ERROR(boot_svc_header_check(&boot_svc_msg->header)); uint32_t msg_type = boot_svc_msg->header.type; switch (launder32(msg_type)) { - case kBootSvcEmptyType: - HARDENED_CHECK_EQ(msg_type, kBootSvcEmptyType); + case kBootSvcEmptyReqType: + HARDENED_CHECK_EQ(msg_type, kBootSvcEmptyReqType); + boot_svc_empty_res_init(&boot_svc_msg->empty); break; case kBootSvcNextBl0SlotReqType: HARDENED_CHECK_EQ(msg_type, kBootSvcNextBl0SlotReqType); @@ -772,6 +773,7 @@ static rom_error_t handle_boot_svc(boot_data_t *boot_data) { case kBootSvcOwnershipUnlockReqType: HARDENED_CHECK_EQ(msg_type, kBootSvcOwnershipUnlockReqType); return ownership_unlock_handler(boot_svc_msg, boot_data); + case kBootSvcEmptyResType: case kBootSvcNextBl0SlotResType: case kBootSvcPrimaryBl0SlotResType: case kBootSvcMinBl0SecVerResType: