9 #include "gtest/gtest.h"
11 #include "sw/device/lib/base/mock_mmio.h"
15 #include "keymgr_regs.h"
17 namespace dif_keymgr_unittest {
23 uint32_t AllOnesExcept(uint32_t index) {
return ~(1u << index); }
34 using TT =
typename std::underlying_type<T>::type;
36 for (TT i = 0; i <= static_cast<TT>(last); ++i) {
37 res.push_back(
static_cast<T
>(i));
49 return reinterpret_cast<T *
>(
alignof(T));
66 return static_cast<T
>(last + 1);
73 static constexpr std::array<uint32_t, 3> kStatesWithOperationalNextStates{
74 KEYMGR_WORKING_STATE_STATE_VALUE_INIT,
75 KEYMGR_WORKING_STATE_STATE_VALUE_CREATOR_ROOT_KEY,
76 KEYMGR_WORKING_STATE_STATE_VALUE_OWNER_INTERMEDIATE_KEY,
78 static constexpr std::array<uint32_t, 4> kStatesWithNonOperationalNextStates{
79 KEYMGR_WORKING_STATE_STATE_VALUE_RESET,
80 KEYMGR_WORKING_STATE_STATE_VALUE_OWNER_KEY,
81 KEYMGR_WORKING_STATE_STATE_VALUE_DISABLED,
82 KEYMGR_WORKING_STATE_STATE_VALUE_INVALID,
91 public testing::WithParamInterface<std::tuple<bool, bool>> {
93 bool AllParamsGood() {
94 return std::get<0>(GetParam()) && std::get<1>(GetParam());
97 void SetUp()
override {
98 if (AllParamsGood()) {
105 INSTANTIATE_TEST_SUITE_P(
107 [&](testing::TestParamInfo<std::tuple<bool, bool>> info) {
108 auto stringify = [](
bool foo) {
return foo ?
"Good" :
"Bad"; };
109 std::stringstream ss;
110 ss << stringify(std::get<0>(info.param))
111 << stringify(std::get<1>(info.param));
125 EXPECT_READ32(KEYMGR_OP_STATUS_REG_OFFSET,
127 .offset = KEYMGR_OP_STATUS_STATUS_OFFSET,
128 .value = KEYMGR_OP_STATUS_STATUS_VALUE_IDLE,
130 EXPECT_READ32(KEYMGR_CFG_REGWEN_REG_OFFSET,
132 .offset = KEYMGR_CFG_REGWEN_EN_BIT,
142 EXPECT_READ32(KEYMGR_WORKING_STATE_REG_OFFSET,
144 .offset = KEYMGR_WORKING_STATE_STATE_OFFSET,
153 EXPECT_READ32(KEYMGR_OP_STATUS_REG_OFFSET,
155 .offset = KEYMGR_OP_STATUS_STATUS_OFFSET,
156 .value = KEYMGR_OP_STATUS_STATUS_VALUE_WIP,
164 EXPECT_READ32(KEYMGR_OP_STATUS_REG_OFFSET,
166 .offset = KEYMGR_OP_STATUS_STATUS_OFFSET,
167 .value = KEYMGR_OP_STATUS_STATUS_VALUE_IDLE,
169 EXPECT_READ32(KEYMGR_CFG_REGWEN_REG_OFFSET,
170 AllOnesExcept(KEYMGR_CFG_REGWEN_EN_BIT));
183 EXPECT_WRITE32_SHADOWED(
184 KEYMGR_CONTROL_SHADOWED_REG_OFFSET,
186 .offset = KEYMGR_CONTROL_SHADOWED_DEST_SEL_OFFSET,
187 .value = params.dest_sel,
190 .offset = KEYMGR_CONTROL_SHADOWED_OPERATION_OFFSET,
191 .value = params.operation,
194 .offset = KEYMGR_CONTROL_SHADOWED_CDI_SEL_BIT,
195 .value = params.cdi_type,
198 EXPECT_WRITE32(KEYMGR_START_REG_OFFSET, {{
199 .offset = KEYMGR_START_EN_BIT,
207 const dif_keymgr_t keymgr_ = {.base_addr = dev().region()};
216 TEST_F(ConfigureTest, Configure) {
219 EXPECT_WRITE32_SHADOWED(KEYMGR_RESEED_INTERVAL_SHADOWED_REG_OFFSET,
220 kConfig.entropy_reseed_interval);
228 .
binding_value = {0xFF, 0xC3, 0xB9, 0xA5, 0x00, 0x3C, 0x46, 0x5A},
229 .max_key_version = 0xA5A5A5A5,
235 uint32_t wen_bit_index;
243 case KEYMGR_WORKING_STATE_STATE_VALUE_INIT:
245 .offset = KEYMGR_MAX_CREATOR_KEY_VER_SHADOWED_REG_OFFSET,
246 .wen_offset = KEYMGR_MAX_CREATOR_KEY_VER_REGWEN_REG_OFFSET,
247 .wen_bit_index = KEYMGR_MAX_CREATOR_KEY_VER_REGWEN_EN_BIT,
249 case KEYMGR_WORKING_STATE_STATE_VALUE_CREATOR_ROOT_KEY:
251 .offset = KEYMGR_MAX_OWNER_INT_KEY_VER_SHADOWED_REG_OFFSET,
252 .wen_offset = KEYMGR_MAX_OWNER_INT_KEY_VER_REGWEN_REG_OFFSET,
253 .wen_bit_index = KEYMGR_MAX_OWNER_INT_KEY_VER_REGWEN_EN_BIT,
255 case KEYMGR_WORKING_STATE_STATE_VALUE_OWNER_INTERMEDIATE_KEY:
257 .offset = KEYMGR_MAX_OWNER_KEY_VER_SHADOWED_REG_OFFSET,
258 .wen_offset = KEYMGR_MAX_OWNER_KEY_VER_REGWEN_REG_OFFSET,
259 .wen_bit_index = KEYMGR_MAX_OWNER_KEY_VER_REGWEN_EN_BIT,
269 TEST_F(AdvanceStateTest, BadArgsNoKeymgr) {
275 public testing::WithParamInterface<uint32_t> {};
278 ExpectIdleAtState(GetParam());
283 INSTANTIATE_TEST_SUITE_P(AdvanceToOperational, AdvanceToOperational,
284 testing::ValuesIn(kStatesWithOperationalNextStates));
287 public testing::WithParamInterface<uint32_t> {};
290 ExpectIdleAtState(GetParam());
295 INSTANTIATE_TEST_SUITE_P(
296 AdvanceToNonOperational, AdvanceToNonOperational,
297 testing::ValuesIn(kStatesWithNonOperationalNextStates));
299 TEST_F(AdvanceStateTest, LockedBusy) {
305 TEST_F(AdvanceStateTest, LockedConfig) {
306 ExpectLockedConfig();
311 TEST_P(AdvanceToOperational, LockedBinding) {
312 ExpectIdleAtState(GetParam());
313 EXPECT_READ32(KEYMGR_SW_BINDING_REGWEN_REG_OFFSET, 0);
318 TEST_P(AdvanceToOperational, LockedMaxKeyVersion) {
319 ExpectIdleAtState(GetParam());
320 EXPECT_READ32(KEYMGR_SW_BINDING_REGWEN_REG_OFFSET,
322 .offset = KEYMGR_SW_BINDING_REGWEN_EN_BIT,
325 EXPECT_READ32(GetMaxKeyVersionRegInfo(GetParam()).wen_offset, 0);
330 TEST_P(AdvanceToOperational, Success) {
331 ExpectIdleAtState(GetParam());
332 EXPECT_READ32(KEYMGR_SW_BINDING_REGWEN_REG_OFFSET,
334 .offset = KEYMGR_SW_BINDING_REGWEN_EN_BIT,
337 auto reg_info = GetMaxKeyVersionRegInfo(GetParam());
338 EXPECT_READ32(reg_info.wen_offset, {{
339 .offset = reg_info.wen_bit_index,
342 size_t binding_len =
sizeof(kStateParams.binding_value) /
343 sizeof(kStateParams.binding_value[0]);
344 for (
size_t i = 0; i < binding_len; ++i) {
345 EXPECT_WRITE32(KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET + i * 4,
346 kStateParams.binding_value[i]);
348 EXPECT_WRITE32(KEYMGR_SW_BINDING_REGWEN_REG_OFFSET, 0);
349 EXPECT_WRITE32_SHADOWED(reg_info.offset, kStateParams.max_key_version);
350 EXPECT_WRITE32(reg_info.wen_offset, 0);
351 ExpectOperationStart({
352 .dest_sel = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
353 .operation = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_ADVANCE,
359 TEST_P(AdvanceToNonOperational, Success) {
360 ExpectIdleAtState(GetParam());
361 ExpectOperationStart({
362 .dest_sel = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
363 .operation = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_ADVANCE,
373 TEST_F(DisableTest, LockedBusy) {
378 TEST_F(DisableTest, LockedConfig) {
379 ExpectLockedConfig();
384 TEST_F(DisableTest, Disable) {
386 ExpectOperationStart({
387 .dest_sel = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
388 .operation = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_DISABLE,
394 TEST_P(BadArgsTwo, GetStatusCodes) {
395 auto keymgr = GetGoodBadPtrArg<dif_keymgr_t>(std::get<0>(GetParam()));
397 GetGoodBadPtrArg<dif_keymgr_status_codes_t>(std::get<1>(GetParam()));
415 public testing::WithParamInterface<GetStatusCodesTestCase> {};
418 uint32_t reg_val = mock_mmio::ToInt<uint32_t>(GetParam().reg_val);
419 EXPECT_READ32(KEYMGR_OP_STATUS_REG_OFFSET, reg_val);
420 if (reg_val == KEYMGR_OP_STATUS_STATUS_VALUE_DONE_SUCCESS ||
421 reg_val == KEYMGR_OP_STATUS_STATUS_VALUE_DONE_ERROR) {
422 EXPECT_WRITE32(KEYMGR_OP_STATUS_REG_OFFSET, reg_val);
425 if (reg_val == KEYMGR_OP_STATUS_STATUS_VALUE_DONE_ERROR) {
426 EXPECT_READ32(KEYMGR_ERR_CODE_REG_OFFSET, 5);
427 EXPECT_WRITE32(KEYMGR_ERR_CODE_REG_OFFSET, 5);
432 EXPECT_EQ(GetParam().exp_val, act_val);
435 INSTANTIATE_TEST_SUITE_P(
436 GetStatusCodesNoError, GetStatusCodesNoError,
438 GetStatusCodesTestCase{
440 .offset = KEYMGR_OP_STATUS_STATUS_OFFSET,
441 .value = KEYMGR_OP_STATUS_STATUS_VALUE_IDLE,
445 GetStatusCodesTestCase{
447 .offset = KEYMGR_OP_STATUS_STATUS_OFFSET,
448 .value = KEYMGR_OP_STATUS_STATUS_VALUE_DONE_SUCCESS,
452 GetStatusCodesTestCase{
454 .offset = KEYMGR_OP_STATUS_STATUS_OFFSET,
455 .value = KEYMGR_OP_STATUS_STATUS_VALUE_DONE_ERROR,
461 GetStatusCodesTestCase{
463 .offset = KEYMGR_OP_STATUS_STATUS_OFFSET,
464 .value = KEYMGR_OP_STATUS_STATUS_VALUE_WIP,
471 public testing::WithParamInterface<GetStatusCodesTestCase> {};
474 EXPECT_READ32(KEYMGR_OP_STATUS_REG_OFFSET,
475 KEYMGR_OP_STATUS_STATUS_VALUE_DONE_ERROR);
476 EXPECT_WRITE32(KEYMGR_OP_STATUS_REG_OFFSET,
477 KEYMGR_OP_STATUS_STATUS_VALUE_DONE_ERROR);
478 EXPECT_READ32(KEYMGR_ERR_CODE_REG_OFFSET, GetParam().reg_val);
479 EXPECT_WRITE32(KEYMGR_ERR_CODE_REG_OFFSET, GetParam().reg_val);
483 EXPECT_EQ(GetParam().exp_val, act_val);
486 INSTANTIATE_TEST_SUITE_P(
487 GetStatusCodesWithError, GetStatusCodesWithError,
489 GetStatusCodesTestCase{
491 .offset = KEYMGR_ERR_CODE_INVALID_OP_BIT,
497 GetStatusCodesTestCase{
499 .offset = KEYMGR_ERR_CODE_INVALID_KMAC_INPUT_BIT,
505 GetStatusCodesTestCase{
507 .offset = KEYMGR_ERR_CODE_INVALID_OP_BIT,
511 .offset = KEYMGR_ERR_CODE_INVALID_KMAC_INPUT_BIT,
522 auto keymgr = GetGoodBadPtrArg<dif_keymgr_t>(std::get<0>(GetParam()));
523 auto state = GetGoodBadPtrArg<dif_keymgr_state_t>(std::get<1>(GetParam()));
540 public testing::WithParamInterface<GetStateTestCase> {};
543 EXPECT_READ32(KEYMGR_WORKING_STATE_REG_OFFSET, GetParam().reg_val);
547 EXPECT_EQ(state, GetParam().exp_output);
550 INSTANTIATE_TEST_SUITE_P(
551 AllValidStates, GetState,
555 .offset = KEYMGR_WORKING_STATE_STATE_OFFSET,
556 .value = KEYMGR_WORKING_STATE_STATE_VALUE_RESET,
562 .offset = KEYMGR_WORKING_STATE_STATE_OFFSET,
563 .value = KEYMGR_WORKING_STATE_STATE_VALUE_INIT,
569 .offset = KEYMGR_WORKING_STATE_STATE_OFFSET,
570 .value = KEYMGR_WORKING_STATE_STATE_VALUE_CREATOR_ROOT_KEY,
576 .offset = KEYMGR_WORKING_STATE_STATE_OFFSET,
578 KEYMGR_WORKING_STATE_STATE_VALUE_OWNER_INTERMEDIATE_KEY,
584 .offset = KEYMGR_WORKING_STATE_STATE_OFFSET,
585 .value = KEYMGR_WORKING_STATE_STATE_VALUE_OWNER_KEY,
591 .offset = KEYMGR_WORKING_STATE_STATE_OFFSET,
592 .value = KEYMGR_WORKING_STATE_STATE_VALUE_DISABLED,
598 .offset = KEYMGR_WORKING_STATE_STATE_OFFSET,
599 .value = KEYMGR_WORKING_STATE_STATE_VALUE_INVALID,
604 TEST_F(GetStateTest, UnexpectedState) {
605 EXPECT_READ32(KEYMGR_WORKING_STATE_REG_OFFSET,
606 KEYMGR_WORKING_STATE_STATE_MASK);
618 TEST_F(GenerateIdentityTest, LockedBusy) {
624 TEST_F(GenerateIdentityTest, LockedConfig) {
625 ExpectLockedConfig();
630 TEST_F(GenerateIdentityTest, GenerateSealing) {
632 ExpectOperationStart({
633 .dest_sel = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
634 .operation = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_ID,
642 TEST_F(GenerateIdentityTest, GenerateAttestation) {
644 ExpectOperationStart({
645 .dest_sel = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
646 .operation = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_ID,
657 auto keymgr = GetGoodBadPtrArg<dif_keymgr_t>(std::get<0>(GetParam()));
658 auto dest = GetGoodBadEnumArg<dif_keymgr_versioned_key_dest_t>(
659 std::get<1>(GetParam()), kDifKeymgrVersionedKeyDestLast);
664 TEST_F(GenerateVersionedKeyTest, LockedBusy) {
670 TEST_F(GenerateVersionedKeyTest, LockedConfig) {
671 ExpectLockedConfig();
697 public testing::WithParamInterface<GenerateVersionedKeyTestCase> {};
701 .
dest = GetParam().dest,
702 .salt = {0x5A, 0x46, 0x3C, 0x00, 0xA5, 0xB9, 0xC3, 0xFF},
703 .version = 0xA5A5A5A5,
707 size_t salt_len =
sizeof(params.salt) /
sizeof(params.salt[0]);
708 for (
size_t i = 0; i < salt_len; ++i) {
709 EXPECT_WRITE32(KEYMGR_SALT_0_REG_OFFSET + i * 4, params.salt[i]);
711 EXPECT_WRITE32(KEYMGR_KEY_VERSION_REG_OFFSET, params.version);
712 ExpectOperationStart({
713 .dest_sel = GetParam().exp_dest_sel,
714 .operation = GetParam().exp_operation,
720 INSTANTIATE_TEST_SUITE_P(
721 GenerateVersionedKeyAllDests, GenerateVersionedKey,
723 GenerateVersionedKeyTestCase{
725 .exp_dest_sel = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
727 KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_SW_OUTPUT,
730 GenerateVersionedKeyTestCase{
732 .exp_dest_sel = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_AES,
734 KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_HW_OUTPUT,
737 GenerateVersionedKeyTestCase{
739 .exp_dest_sel = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_KMAC,
741 KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_HW_OUTPUT,
744 GenerateVersionedKeyTestCase{
746 .exp_dest_sel = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
748 KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_SW_OUTPUT,
751 GenerateVersionedKeyTestCase{
753 .exp_dest_sel = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_AES,
755 KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_HW_OUTPUT,
758 GenerateVersionedKeyTestCase{
760 .exp_dest_sel = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_KMAC,
762 KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_HW_OUTPUT,
769 auto keymgr = GetGoodBadPtrArg<dif_keymgr_t>(std::get<0>(GetParam()));
770 auto state = GetGoodBadPtrArg<dif_toggle_t>(std::get<1>(GetParam()));
775 TEST_P(BadArgsTwo, SetBadArg) {
776 auto keymgr = GetGoodBadPtrArg<dif_keymgr_t>(std::get<0>(GetParam()));
777 auto state = GetGoodBadEnumArg<dif_toggle_t>(std::get<1>(GetParam()),
783 TEST_F(SideloadClearTest, Set) {
784 EXPECT_WRITE32(KEYMGR_SIDELOAD_CLEAR_REG_OFFSET,
786 .offset = KEYMGR_SIDELOAD_CLEAR_VAL_OFFSET,
787 .value = kDifKeyMgrSideLoadClearAll,
792 EXPECT_WRITE32(KEYMGR_SIDELOAD_CLEAR_REG_OFFSET,
794 .offset = KEYMGR_SIDELOAD_CLEAR_VAL_OFFSET,
795 .value = kDifKeyMgrSideLoadClearNone,
801 TEST_F(SideloadClearTest, Get) {
802 EXPECT_READ32(KEYMGR_SIDELOAD_CLEAR_REG_OFFSET,
804 .offset = KEYMGR_SIDELOAD_CLEAR_VAL_OFFSET,
805 .value = kDifKeyMgrSideLoadClearAll,
811 EXPECT_READ32(KEYMGR_SIDELOAD_CLEAR_REG_OFFSET,
813 .offset = KEYMGR_SIDELOAD_CLEAR_VAL_OFFSET,
814 .value = kDifKeyMgrSideLoadClearNone,
824 auto keymgr = GetGoodBadPtrArg<dif_keymgr_t>(std::get<0>(GetParam()));
825 auto output = GetGoodBadPtrArg<dif_keymgr_output_t>(std::get<1>(GetParam()));
830 TEST_F(ReadOutputTest, Read) {
831 constexpr
size_t kNumShares = 2;
832 constexpr
size_t kNumShareWords = 8;
833 constexpr std::array<std::array<uint32_t, kNumShareWords>, kNumShares>
834 kExpected{{{0x8D, 0x25, 0x44, 0x0A, 0xEC, 0x1C, 0xAC, 0x0E},
835 {0x44, 0x5B, 0x90, 0x39, 0x24, 0x72, 0xA7, 0xCB}}};
836 constexpr std::array<uint32_t, kNumShares> kShareRegOffsets{
837 {KEYMGR_SW_SHARE0_OUTPUT_0_REG_OFFSET,
838 KEYMGR_SW_SHARE1_OUTPUT_0_REG_OFFSET}};
840 for (
size_t i = 0; i < kNumShares; ++i) {
841 for (
size_t j = 0; j < kNumShareWords; ++j) {
842 EXPECT_READ32(kShareRegOffsets[i] + j * 4, kExpected[i][j]);
848 for (
size_t i = 0; i < kNumShares; ++i) {
849 EXPECT_THAT(kExpected[i], ::testing::ElementsAreArray(output.value[i]));
856 auto keymgr = GetGoodBadPtrArg<dif_keymgr_t>(std::get<0>(GetParam()));
858 GetGoodBadPtrArg<dif_keymgr_binding_value_t>(std::get<1>(GetParam()));
863 TEST_F(ReadBindingTest, Read) {
864 constexpr
size_t kNumBindingWords = 8;
865 constexpr
size_t kNumBindings = 2;
866 constexpr std::array<std::array<uint32_t, kNumBindingWords>, kNumBindings>
867 kExpected{{{0x8D, 0x25, 0x44, 0x0A, 0xEC, 0x1C, 0xAC, 0x0E},
868 {0x44, 0x5B, 0x90, 0x39, 0x24, 0x72, 0xA7, 0xCB}}};
869 constexpr std::array<uint32_t, kNumBindings> kShareRegOffsets{
870 {KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET,
871 KEYMGR_ATTEST_SW_BINDING_0_REG_OFFSET}};
873 for (
size_t i = 0; i < kNumBindings; ++i) {
874 for (
size_t j = 0; j < kNumBindingWords; ++j) {
875 EXPECT_READ32(kShareRegOffsets[i] + j * 4, kExpected[i][j]);
881 EXPECT_THAT(kExpected[0], ::testing::ElementsAreArray(output.
sealing));
882 EXPECT_THAT(kExpected[1], ::testing::ElementsAreArray(output.
attestation));
888 auto keymgr = GetGoodBadPtrArg<dif_keymgr_t>(std::get<0>(GetParam()));
890 GetGoodBadPtrArg<dif_keymgr_max_key_version_t>(std::get<1>(GetParam()));
895 TEST_F(ReadMaxKeyVersionTest, Read) {
896 EXPECT_READ32(KEYMGR_MAX_CREATOR_KEY_VER_SHADOWED_REG_OFFSET, 0xa093ed64);
897 EXPECT_READ32(KEYMGR_MAX_OWNER_INT_KEY_VER_SHADOWED_REG_OFFSET, 0x874d53e);
898 EXPECT_READ32(KEYMGR_MAX_OWNER_KEY_VER_SHADOWED_REG_OFFSET, 0x874df4a);