Software APIs
dif_keymgr_unittest.cc
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 
6 
7 #include <array>
8 
9 #include "gtest/gtest.h"
11 #include "sw/device/lib/base/mock_mmio.h"
14 
15 #include "keymgr_regs.h" // Generated
16 
17 namespace dif_keymgr_unittest {
18 namespace {
19 
20 /**
21  * Returns a `uint32_t` with a single zero bit.
22  */
23 uint32_t AllOnesExcept(uint32_t index) { return ~(1u << index); }
24 
25 /**
26  * Returns a vector of values for a given enum type.
27  *
28  * Assumes that the values are sequential and the first value is 0. `last` must
29  * be the last valid value for the given enum and is included in the returned
30  * vector.
31  */
32 template <typename T>
33 std::vector<T> CreateEnumVector(T last) {
34  using TT = typename std::underlying_type<T>::type;
35  std::vector<T> res;
36  for (TT i = 0; i <= static_cast<TT>(last); ++i) {
37  res.push_back(static_cast<T>(i));
38  }
39  return res;
40 }
41 
42 /**
43  * Returns a seemingly valid, i.e. nonzero, pointer for the given type or a
44  * `nullptr`.
45  */
46 template <typename T>
47 T *GetGoodBadPtrArg(bool is_good) {
48  if (is_good) {
49  return reinterpret_cast<T *>(alignof(T));
50  } else {
51  return nullptr;
52  }
53 }
54 
55 /**
56  * Returns a valid or invalid value for the given enum type.
57  *
58  * `last` must be the last valid value of the given enum type and `last+1` must
59  * be an invalid value.
60  */
61 template <typename T>
62 T GetGoodBadEnumArg(bool is_good, T last) {
63  if (is_good) {
64  return last;
65  } else {
66  return static_cast<T>(last + 1);
67  }
68 }
69 
70 /**
71  * Constants used in tests.
72  */
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,
77 };
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,
83 };
84 
85 class DifKeymgrTest : public testing::Test, public mock_mmio::MmioTest {};
86 
87 /**
88  * Class for parameterizing bad argument tests for functions with two arguments.
89  */
90 class BadArgsTwo : public DifKeymgrTest,
91  public testing::WithParamInterface<std::tuple<bool, bool>> {
92  protected:
93  bool AllParamsGood() {
94  return std::get<0>(GetParam()) && std::get<1>(GetParam());
95  }
96 
97  void SetUp() override {
98  if (AllParamsGood()) {
99  // Only test negative cases.
100  GTEST_SKIP();
101  }
102  }
103 };
104 
105 INSTANTIATE_TEST_SUITE_P(
106  BadArgsTwo, BadArgsTwo, testing::Combine(testing::Bool(), testing::Bool()),
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));
112  return ss.str();
113  });
114 
115 /**
116  * Base class for the rest of the tests in this file, provides a
117  * `dif_keymgr_t` instance and some methods for common expectations.
118  */
120  protected:
121  /**
122  * Expectations for an idle key manager.
123  */
124  void ExpectIdle() {
125  EXPECT_READ32(KEYMGR_OP_STATUS_REG_OFFSET,
126  {{
127  .offset = KEYMGR_OP_STATUS_STATUS_OFFSET,
128  .value = KEYMGR_OP_STATUS_STATUS_VALUE_IDLE,
129  }});
130  EXPECT_READ32(KEYMGR_CFG_REGWEN_REG_OFFSET,
131  {{
132  .offset = KEYMGR_CFG_REGWEN_EN_BIT,
133  .value = 1,
134  }});
135  }
136 
137  /**
138  * Expectations for an idle key manager at a given state.
139  */
140  void ExpectIdleAtState(uint32_t state) {
141  ExpectIdle();
142  EXPECT_READ32(KEYMGR_WORKING_STATE_REG_OFFSET,
143  {{
144  .offset = KEYMGR_WORKING_STATE_STATE_OFFSET,
145  .value = state,
146  }});
147  }
148 
149  /**
150  * Expectations for a busy key manager.
151  */
152  void ExpectBusy() {
153  EXPECT_READ32(KEYMGR_OP_STATUS_REG_OFFSET,
154  {{
155  .offset = KEYMGR_OP_STATUS_STATUS_OFFSET,
156  .value = KEYMGR_OP_STATUS_STATUS_VALUE_WIP,
157  }});
158  }
159 
160  /**
161  * Expectations for a locked CONFIG register.
162  */
164  EXPECT_READ32(KEYMGR_OP_STATUS_REG_OFFSET,
165  {{
166  .offset = KEYMGR_OP_STATUS_STATUS_OFFSET,
167  .value = KEYMGR_OP_STATUS_STATUS_VALUE_IDLE,
168  }});
169  EXPECT_READ32(KEYMGR_CFG_REGWEN_REG_OFFSET,
170  AllOnesExcept(KEYMGR_CFG_REGWEN_EN_BIT));
171  }
172 
174  uint32_t dest_sel;
175  uint32_t operation;
176  dif_keymgr_cdi_type_t cdi_type;
177  };
178 
179  /**
180  * Expectations for starting an operation.
181  */
183  EXPECT_WRITE32_SHADOWED(
184  KEYMGR_CONTROL_SHADOWED_REG_OFFSET,
185  {{
186  .offset = KEYMGR_CONTROL_SHADOWED_DEST_SEL_OFFSET,
187  .value = params.dest_sel,
188  },
189  {
190  .offset = KEYMGR_CONTROL_SHADOWED_OPERATION_OFFSET,
191  .value = params.operation,
192  },
193  {
194  .offset = KEYMGR_CONTROL_SHADOWED_CDI_SEL_BIT,
195  .value = params.cdi_type,
196  }});
197 
198  EXPECT_WRITE32(KEYMGR_START_REG_OFFSET, {{
199  .offset = KEYMGR_START_EN_BIT,
200  .value = 1,
201  }});
202  }
203 
204  /**
205  * Initialized `dif_keymgr_t` used in tests.
206  */
207  const dif_keymgr_t keymgr_ = {.base_addr = dev().region()};
208 };
209 
211 
212 TEST_F(ConfigureTest, BadArgs) {
214 }
215 
216 TEST_F(ConfigureTest, Configure) {
217  constexpr dif_keymgr_config_t kConfig = {.entropy_reseed_interval = 0xA5A5};
218 
219  EXPECT_WRITE32_SHADOWED(KEYMGR_RESEED_INTERVAL_SHADOWED_REG_OFFSET,
220  kConfig.entropy_reseed_interval);
221 
222  EXPECT_DIF_OK(dif_keymgr_configure(&keymgr_, kConfig));
223 }
224 
226  protected:
227  dif_keymgr_state_params_t kStateParams{
228  .binding_value = {0xFF, 0xC3, 0xB9, 0xA5, 0x00, 0x3C, 0x46, 0x5A},
229  .max_key_version = 0xA5A5A5A5,
230  };
231 
233  uint32_t offset;
234  uint32_t wen_offset;
235  uint32_t wen_bit_index;
236  };
237 
238  /**
239  * Returns max key version register information for the given state.
240  */
242  switch (state) {
243  case KEYMGR_WORKING_STATE_STATE_VALUE_INIT:
244  return {
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,
248  };
249  case KEYMGR_WORKING_STATE_STATE_VALUE_CREATOR_ROOT_KEY:
250  return {
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,
254  };
255  case KEYMGR_WORKING_STATE_STATE_VALUE_OWNER_INTERMEDIATE_KEY:
256  return {
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,
260  };
261  default:
262  ADD_FAILURE();
263  abort();
264  break;
265  }
266  }
267 };
268 
269 TEST_F(AdvanceStateTest, BadArgsNoKeymgr) {
270  EXPECT_DIF_BADARG(dif_keymgr_advance_state(nullptr, &kStateParams));
271  EXPECT_DIF_BADARG(dif_keymgr_advance_state(nullptr, nullptr));
272 }
273 
275  public testing::WithParamInterface<uint32_t> {};
276 
277 TEST_P(AdvanceToOperational, BadArgsToOperationalWithoutParams) {
278  ExpectIdleAtState(GetParam());
279 
280  EXPECT_DIF_BADARG(dif_keymgr_advance_state(&keymgr_, nullptr));
281 }
282 
283 INSTANTIATE_TEST_SUITE_P(AdvanceToOperational, AdvanceToOperational,
284  testing::ValuesIn(kStatesWithOperationalNextStates));
285 
287  public testing::WithParamInterface<uint32_t> {};
288 
289 TEST_P(AdvanceToNonOperational, BadArgsToNonOperationalWithParams) {
290  ExpectIdleAtState(GetParam());
291 
292  EXPECT_DIF_BADARG(dif_keymgr_advance_state(&keymgr_, &kStateParams));
293 }
294 
295 INSTANTIATE_TEST_SUITE_P(
296  AdvanceToNonOperational, AdvanceToNonOperational,
297  testing::ValuesIn(kStatesWithNonOperationalNextStates));
298 
299 TEST_F(AdvanceStateTest, LockedBusy) {
300  ExpectBusy();
301 
302  EXPECT_EQ(dif_keymgr_advance_state(&keymgr_, &kStateParams), kDifLocked);
303 }
304 
305 TEST_F(AdvanceStateTest, LockedConfig) {
306  ExpectLockedConfig();
307 
308  EXPECT_EQ(dif_keymgr_advance_state(&keymgr_, &kStateParams), kDifLocked);
309 }
310 
311 TEST_P(AdvanceToOperational, LockedBinding) {
312  ExpectIdleAtState(GetParam());
313  EXPECT_READ32(KEYMGR_SW_BINDING_REGWEN_REG_OFFSET, 0);
314 
315  EXPECT_EQ(dif_keymgr_advance_state(&keymgr_, &kStateParams), kDifLocked);
316 }
317 
318 TEST_P(AdvanceToOperational, LockedMaxKeyVersion) {
319  ExpectIdleAtState(GetParam());
320  EXPECT_READ32(KEYMGR_SW_BINDING_REGWEN_REG_OFFSET,
321  {{
322  .offset = KEYMGR_SW_BINDING_REGWEN_EN_BIT,
323  .value = 1,
324  }});
325  EXPECT_READ32(GetMaxKeyVersionRegInfo(GetParam()).wen_offset, 0);
326 
327  EXPECT_EQ(dif_keymgr_advance_state(&keymgr_, &kStateParams), kDifLocked);
328 }
329 
330 TEST_P(AdvanceToOperational, Success) {
331  ExpectIdleAtState(GetParam());
332  EXPECT_READ32(KEYMGR_SW_BINDING_REGWEN_REG_OFFSET,
333  {{
334  .offset = KEYMGR_SW_BINDING_REGWEN_EN_BIT,
335  .value = 1,
336  }});
337  auto reg_info = GetMaxKeyVersionRegInfo(GetParam());
338  EXPECT_READ32(reg_info.wen_offset, {{
339  .offset = reg_info.wen_bit_index,
340  .value = 1,
341  }});
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]);
347  }
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,
354  });
355 
356  EXPECT_DIF_OK(dif_keymgr_advance_state(&keymgr_, &kStateParams));
357 }
358 
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,
364  });
365 
366  EXPECT_DIF_OK(dif_keymgr_advance_state(&keymgr_, nullptr));
367 }
368 
370 
371 TEST_F(DisableTest, BadArgs) { EXPECT_DIF_BADARG(dif_keymgr_disable(nullptr)); }
372 
373 TEST_F(DisableTest, LockedBusy) {
374  ExpectBusy();
375  EXPECT_EQ(dif_keymgr_disable(&keymgr_), kDifLocked);
376 }
377 
378 TEST_F(DisableTest, LockedConfig) {
379  ExpectLockedConfig();
380 
381  EXPECT_EQ(dif_keymgr_disable(&keymgr_), kDifLocked);
382 }
383 
384 TEST_F(DisableTest, Disable) {
385  ExpectIdle();
386  ExpectOperationStart({
387  .dest_sel = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
388  .operation = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_DISABLE,
389  });
390 
392 }
393 
394 TEST_P(BadArgsTwo, GetStatusCodes) {
395  auto keymgr = GetGoodBadPtrArg<dif_keymgr_t>(std::get<0>(GetParam()));
396  auto status_codes =
397  GetGoodBadPtrArg<dif_keymgr_status_codes_t>(std::get<1>(GetParam()));
398 
399  EXPECT_DIF_BADARG(dif_keymgr_get_status_codes(keymgr, status_codes));
400 }
401 
403  /**
404  * Values of OP_STATUS or ERR_CODE registers.
405  */
406  std::vector<mock_mmio::BitField> reg_val;
407  /**
408  * Expected output of `dif_keymgr_get_status_codes()`.
409  */
411 };
412 
414  : public DifKeymgrInitialized,
415  public testing::WithParamInterface<GetStatusCodesTestCase> {};
416 
417 TEST_P(GetStatusCodesNoError, Success) {
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);
423  }
424 
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);
428  }
429 
431  EXPECT_DIF_OK(dif_keymgr_get_status_codes(&keymgr_, &act_val));
432  EXPECT_EQ(GetParam().exp_val, act_val);
433 }
434 
435 INSTANTIATE_TEST_SUITE_P(
436  GetStatusCodesNoError, GetStatusCodesNoError,
437  testing::Values(
438  GetStatusCodesTestCase{
439  .reg_val = {{
440  .offset = KEYMGR_OP_STATUS_STATUS_OFFSET,
441  .value = KEYMGR_OP_STATUS_STATUS_VALUE_IDLE,
442  }},
443  .exp_val = kDifKeymgrStatusCodeIdle,
444  },
445  GetStatusCodesTestCase{
446  .reg_val = {{
447  .offset = KEYMGR_OP_STATUS_STATUS_OFFSET,
448  .value = KEYMGR_OP_STATUS_STATUS_VALUE_DONE_SUCCESS,
449  }},
450  .exp_val = kDifKeymgrStatusCodeIdle,
451  },
452  GetStatusCodesTestCase{
453  .reg_val = {{
454  .offset = KEYMGR_OP_STATUS_STATUS_OFFSET,
455  .value = KEYMGR_OP_STATUS_STATUS_VALUE_DONE_ERROR,
456  }},
457  .exp_val = kDifKeymgrStatusCodeIdle |
460  },
461  GetStatusCodesTestCase{
462  .reg_val = {{
463  .offset = KEYMGR_OP_STATUS_STATUS_OFFSET,
464  .value = KEYMGR_OP_STATUS_STATUS_VALUE_WIP,
465  }},
466  .exp_val = 0,
467  }));
468 
470  : public DifKeymgrInitialized,
471  public testing::WithParamInterface<GetStatusCodesTestCase> {};
472 
473 TEST_P(GetStatusCodesWithError, Success) {
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);
480 
482  EXPECT_DIF_OK(dif_keymgr_get_status_codes(&keymgr_, &act_val));
483  EXPECT_EQ(GetParam().exp_val, act_val);
484 }
485 
486 INSTANTIATE_TEST_SUITE_P(
487  GetStatusCodesWithError, GetStatusCodesWithError,
488  testing::Values(
489  GetStatusCodesTestCase{
490  .reg_val = {{
491  .offset = KEYMGR_ERR_CODE_INVALID_OP_BIT,
492  .value = 1,
493  }},
494  .exp_val = kDifKeymgrStatusCodeIdle |
496  },
497  GetStatusCodesTestCase{
498  .reg_val = {{
499  .offset = KEYMGR_ERR_CODE_INVALID_KMAC_INPUT_BIT,
500  .value = 1,
501  }},
502  .exp_val = kDifKeymgrStatusCodeIdle |
504  },
505  GetStatusCodesTestCase{
506  .reg_val = {{
507  .offset = KEYMGR_ERR_CODE_INVALID_OP_BIT,
508  .value = 1,
509  },
510  {
511  .offset = KEYMGR_ERR_CODE_INVALID_KMAC_INPUT_BIT,
512  .value = 1,
513  }},
514  .exp_val = kDifKeymgrStatusCodeIdle |
517  }));
518 
520 
521 TEST_P(BadArgsTwo, GetState) {
522  auto keymgr = GetGoodBadPtrArg<dif_keymgr_t>(std::get<0>(GetParam()));
523  auto state = GetGoodBadPtrArg<dif_keymgr_state_t>(std::get<1>(GetParam()));
524 
525  EXPECT_DIF_BADARG(dif_keymgr_get_state(keymgr, state));
526 }
527 
529  /**
530  * Value of the WORKING_STATE register.
531  */
532  std::vector<mock_mmio::BitField> reg_val;
533  /**
534  * Expected output of `dif_keymgr_get_state()`.
535  */
537 };
538 
539 class GetState : public GetStateTest,
540  public testing::WithParamInterface<GetStateTestCase> {};
541 
542 TEST_P(GetState, Success) {
543  EXPECT_READ32(KEYMGR_WORKING_STATE_REG_OFFSET, GetParam().reg_val);
544 
545  dif_keymgr_state_t state;
546  EXPECT_DIF_OK(dif_keymgr_get_state(&keymgr_, &state));
547  EXPECT_EQ(state, GetParam().exp_output);
548 }
549 
550 INSTANTIATE_TEST_SUITE_P(
551  AllValidStates, GetState,
552  testing::Values(
553  GetStateTestCase{
554  .reg_val = {{
555  .offset = KEYMGR_WORKING_STATE_STATE_OFFSET,
556  .value = KEYMGR_WORKING_STATE_STATE_VALUE_RESET,
557  }},
558  .exp_output = kDifKeymgrStateReset,
559  },
560  GetStateTestCase{
561  .reg_val = {{
562  .offset = KEYMGR_WORKING_STATE_STATE_OFFSET,
563  .value = KEYMGR_WORKING_STATE_STATE_VALUE_INIT,
564  }},
565  .exp_output = kDifKeymgrStateInitialized,
566  },
567  GetStateTestCase{
568  .reg_val = {{
569  .offset = KEYMGR_WORKING_STATE_STATE_OFFSET,
570  .value = KEYMGR_WORKING_STATE_STATE_VALUE_CREATOR_ROOT_KEY,
571  }},
572  .exp_output = kDifKeymgrStateCreatorRootKey,
573  },
574  GetStateTestCase{
575  .reg_val = {{
576  .offset = KEYMGR_WORKING_STATE_STATE_OFFSET,
577  .value =
578  KEYMGR_WORKING_STATE_STATE_VALUE_OWNER_INTERMEDIATE_KEY,
579  }},
581  },
582  GetStateTestCase{
583  .reg_val = {{
584  .offset = KEYMGR_WORKING_STATE_STATE_OFFSET,
585  .value = KEYMGR_WORKING_STATE_STATE_VALUE_OWNER_KEY,
586  }},
587  .exp_output = kDifKeymgrStateOwnerRootKey,
588  },
589  GetStateTestCase{
590  .reg_val = {{
591  .offset = KEYMGR_WORKING_STATE_STATE_OFFSET,
592  .value = KEYMGR_WORKING_STATE_STATE_VALUE_DISABLED,
593  }},
594  .exp_output = kDifKeymgrStateDisabled,
595  },
596  GetStateTestCase{
597  .reg_val = {{
598  .offset = KEYMGR_WORKING_STATE_STATE_OFFSET,
599  .value = KEYMGR_WORKING_STATE_STATE_VALUE_INVALID,
600  }},
601  .exp_output = kDifKeymgrStateInvalid,
602  }));
603 
604 TEST_F(GetStateTest, UnexpectedState) {
605  EXPECT_READ32(KEYMGR_WORKING_STATE_REG_OFFSET,
606  KEYMGR_WORKING_STATE_STATE_MASK);
607 
608  dif_keymgr_state_t state;
609  EXPECT_EQ(dif_keymgr_get_state(&keymgr_, &state), kDifError);
610 }
611 
613 
614 TEST_F(GenerateIdentityTest, BadArgs) {
616 }
617 
618 TEST_F(GenerateIdentityTest, LockedBusy) {
619  ExpectBusy();
620 
621  EXPECT_EQ(dif_keymgr_generate_identity_seed(&keymgr_, {}), kDifLocked);
622 }
623 
624 TEST_F(GenerateIdentityTest, LockedConfig) {
625  ExpectLockedConfig();
626 
627  EXPECT_EQ(dif_keymgr_generate_identity_seed(&keymgr_, {}), kDifLocked);
628 }
629 
630 TEST_F(GenerateIdentityTest, GenerateSealing) {
631  ExpectIdle();
632  ExpectOperationStart({
633  .dest_sel = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
634  .operation = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_ID,
635  .cdi_type = kDifKeymgrSealingCdi,
636  });
637 
639  &keymgr_, {.cdi_type = kDifKeymgrSealingCdi}));
640 }
641 
642 TEST_F(GenerateIdentityTest, GenerateAttestation) {
643  ExpectIdle();
644  ExpectOperationStart({
645  .dest_sel = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
646  .operation = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_ID,
647  .cdi_type = kDifKeymgrAttestationCdi,
648  });
649 
651  &keymgr_, {.cdi_type = kDifKeymgrAttestationCdi}));
652 }
653 
655 
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);
660 
661  EXPECT_DIF_BADARG(dif_keymgr_generate_versioned_key(keymgr, {.dest = dest}));
662 }
663 
664 TEST_F(GenerateVersionedKeyTest, LockedBusy) {
665  ExpectBusy();
666 
667  EXPECT_EQ(dif_keymgr_generate_versioned_key(&keymgr_, {}), kDifLocked);
668 }
669 
670 TEST_F(GenerateVersionedKeyTest, LockedConfig) {
671  ExpectLockedConfig();
672 
673  EXPECT_EQ(dif_keymgr_generate_versioned_key(&keymgr_, {}), kDifLocked);
674 }
675 
677  /**
678  * Destination of the generated key.
679  */
681  /**
682  * Expected DEST_SEL value to be written to the CONTROL register.
683  */
684  uint32_t exp_dest_sel;
685  /**
686  * Expected OPERATION values to be written to the CONTROL register.
687  */
688  uint32_t exp_operation;
689  /**
690  * Expected CDI_SEL value to be written to the CONTROL register.
691  */
693 };
694 
696  : public GenerateVersionedKeyTest,
697  public testing::WithParamInterface<GenerateVersionedKeyTestCase> {};
698 
699 TEST_P(GenerateVersionedKey, Success) {
701  .dest = GetParam().dest,
702  .salt = {0x5A, 0x46, 0x3C, 0x00, 0xA5, 0xB9, 0xC3, 0xFF},
703  .version = 0xA5A5A5A5,
704  };
705 
706  ExpectIdle();
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]);
710  }
711  EXPECT_WRITE32(KEYMGR_KEY_VERSION_REG_OFFSET, params.version);
712  ExpectOperationStart({
713  .dest_sel = GetParam().exp_dest_sel,
714  .operation = GetParam().exp_operation,
715  });
716 
718 }
719 
720 INSTANTIATE_TEST_SUITE_P(
721  GenerateVersionedKeyAllDests, GenerateVersionedKey,
722  testing::Values(
723  GenerateVersionedKeyTestCase{
725  .exp_dest_sel = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
726  .exp_operation =
727  KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_SW_OUTPUT,
728  .cdi_type = kDifKeymgrSealingCdi,
729  },
730  GenerateVersionedKeyTestCase{
732  .exp_dest_sel = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_AES,
733  .exp_operation =
734  KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_HW_OUTPUT,
735  .cdi_type = kDifKeymgrSealingCdi,
736  },
737  GenerateVersionedKeyTestCase{
739  .exp_dest_sel = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_KMAC,
740  .exp_operation =
741  KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_HW_OUTPUT,
742  .cdi_type = kDifKeymgrSealingCdi,
743  },
744  GenerateVersionedKeyTestCase{
746  .exp_dest_sel = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
747  .exp_operation =
748  KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_SW_OUTPUT,
749  .cdi_type = kDifKeymgrAttestationCdi,
750  },
751  GenerateVersionedKeyTestCase{
753  .exp_dest_sel = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_AES,
754  .exp_operation =
755  KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_HW_OUTPUT,
756  .cdi_type = kDifKeymgrAttestationCdi,
757  },
758  GenerateVersionedKeyTestCase{
760  .exp_dest_sel = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_KMAC,
761  .exp_operation =
762  KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_HW_OUTPUT,
763  .cdi_type = kDifKeymgrAttestationCdi,
764  }));
765 
767 
768 TEST_P(BadArgsTwo, GetBadArg) {
769  auto keymgr = GetGoodBadPtrArg<dif_keymgr_t>(std::get<0>(GetParam()));
770  auto state = GetGoodBadPtrArg<dif_toggle_t>(std::get<1>(GetParam()));
771 
773 }
774 
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()),
779 
781 }
782 
783 TEST_F(SideloadClearTest, Set) {
784  EXPECT_WRITE32(KEYMGR_SIDELOAD_CLEAR_REG_OFFSET,
785  {{
786  .offset = KEYMGR_SIDELOAD_CLEAR_VAL_OFFSET,
787  .value = kDifKeyMgrSideLoadClearAll,
788  }});
791 
792  EXPECT_WRITE32(KEYMGR_SIDELOAD_CLEAR_REG_OFFSET,
793  {{
794  .offset = KEYMGR_SIDELOAD_CLEAR_VAL_OFFSET,
795  .value = kDifKeyMgrSideLoadClearNone,
796  }});
799 }
800 
801 TEST_F(SideloadClearTest, Get) {
802  EXPECT_READ32(KEYMGR_SIDELOAD_CLEAR_REG_OFFSET,
803  {{
804  .offset = KEYMGR_SIDELOAD_CLEAR_VAL_OFFSET,
805  .value = kDifKeyMgrSideLoadClearAll,
806  }});
809  EXPECT_EQ(state, kDifToggleEnabled);
810 
811  EXPECT_READ32(KEYMGR_SIDELOAD_CLEAR_REG_OFFSET,
812  {{
813  .offset = KEYMGR_SIDELOAD_CLEAR_VAL_OFFSET,
814  .value = kDifKeyMgrSideLoadClearNone,
815  }});
816  state = kDifToggleEnabled;
818  EXPECT_EQ(state, kDifToggleDisabled);
819 }
820 
822 
823 TEST_P(BadArgsTwo, ReadOutput) {
824  auto keymgr = GetGoodBadPtrArg<dif_keymgr_t>(std::get<0>(GetParam()));
825  auto output = GetGoodBadPtrArg<dif_keymgr_output_t>(std::get<1>(GetParam()));
826 
827  EXPECT_DIF_BADARG(dif_keymgr_read_output(keymgr, output));
828 }
829 
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}};
839 
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]);
843  }
844  }
845 
846  dif_keymgr_output_t output;
847  EXPECT_DIF_OK(dif_keymgr_read_output(&keymgr_, &output));
848  for (size_t i = 0; i < kNumShares; ++i) {
849  EXPECT_THAT(kExpected[i], ::testing::ElementsAreArray(output.value[i]));
850  }
851 }
852 
854 
855 TEST_P(BadArgsTwo, ReadBinding) {
856  auto keymgr = GetGoodBadPtrArg<dif_keymgr_t>(std::get<0>(GetParam()));
857  auto output =
858  GetGoodBadPtrArg<dif_keymgr_binding_value_t>(std::get<1>(GetParam()));
859 
861 }
862 
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}};
872 
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]);
876  }
877  }
878 
880  EXPECT_DIF_OK(dif_keymgr_read_binding(&keymgr_, &output));
881  EXPECT_THAT(kExpected[0], ::testing::ElementsAreArray(output.sealing));
882  EXPECT_THAT(kExpected[1], ::testing::ElementsAreArray(output.attestation));
883 }
884 
886 
887 TEST_P(BadArgsTwo, ReadMaxKeyVersion) {
888  auto keymgr = GetGoodBadPtrArg<dif_keymgr_t>(std::get<0>(GetParam()));
889  auto version =
890  GetGoodBadPtrArg<dif_keymgr_max_key_version_t>(std::get<1>(GetParam()));
891 
893 }
894 
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);
899 
901  EXPECT_DIF_OK(dif_keymgr_read_max_key_version(&keymgr_, &versions));
902  EXPECT_THAT(0xa093ed64, versions.creator_max_key_version);
903  EXPECT_THAT(0x874d53e, versions.owner_int_max_key_version);
904  EXPECT_THAT(0x874df4a, versions.owner_max_key_version);
905 }
906 } // namespace
907 } // namespace dif_keymgr_unittest