Software APIs
ownership_activate_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 
5 #include "sw/device/silicon_creator/lib/ownership/ownership_activate.h"
6 
7 #include <stdint.h>
8 
9 #include "gmock/gmock.h"
10 #include "gtest/gtest.h"
11 #include "sw/device/lib/base/global_mock.h"
13 #include "sw/device/silicon_creator/lib/boot_data.h"
14 #include "sw/device/silicon_creator/lib/boot_svc/mock_boot_svc_header.h"
15 #include "sw/device/silicon_creator/lib/drivers/mock_flash_ctrl.h"
16 #include "sw/device/silicon_creator/lib/drivers/mock_hmac.h"
17 #include "sw/device/silicon_creator/lib/drivers/mock_lifecycle.h"
18 #include "sw/device/silicon_creator/lib/drivers/mock_rnd.h"
19 #include "sw/device/silicon_creator/lib/error.h"
20 #include "sw/device/silicon_creator/lib/nonce.h"
21 #include "sw/device/silicon_creator/lib/ownership/datatypes.h"
22 #include "sw/device/silicon_creator/lib/ownership/mock_ownership_key.h"
23 #include "sw/device/silicon_creator/lib/ownership/owner_block.h"
24 #include "sw/device/silicon_creator/testing/rom_test.h"
25 
26 namespace {
27 using ::testing::_;
28 using ::testing::Return;
29 using ::testing::SetArgPointee;
30 
31 constexpr nonce_t kDefaultNonce = {1, 2};
32 
34  protected:
35  void MakePage1StructValid() {
36  owner_page[1].header.tag = kTlvTagOwner;
37  owner_page[1].header.length = sizeof(owner_page[1]);
38  owner_page[1].header.version = (struct_version_t){0, 0};
39  owner_page[1].config_version = 0;
40  owner_page[1].min_security_version_bl0 = UINT32_MAX;
41  owner_page[1].lock_constraint = 0;
42  memset(owner_page[1].device_id, 0x7e, sizeof(owner_page[1].device_id));
43  memset(owner_page[1].data, 0x5a, sizeof(owner_page[1].data));
44  }
45 
46  void MakePage1Valid(bool valid) {
47  MakePage1StructValid();
48  ownership_state_t state =
49  static_cast<ownership_state_t>(bootdata_.ownership_state);
50  owner_page_valid[1] = kOwnerPageStatusSigned;
51  uint32_t modifier = valid ? 0 : 1;
52 
53  switch (state) {
54  case kOwnershipStateUnlockedEndorsed:
55  // In UnlockedEndorsed, the hash of the owner key in page1 must be equal
56  // to the value stored in boot_data.
57  EXPECT_CALL(hmac_, sha256(_, _, _))
58  .WillOnce(SetArgPointee<2>((hmac_digest_t){{
59  bootdata_.next_owner[0] + modifier,
60  bootdata_.next_owner[1],
61  bootdata_.next_owner[2],
62  bootdata_.next_owner[3],
63  bootdata_.next_owner[4],
64  bootdata_.next_owner[5],
65  bootdata_.next_owner[6],
66  bootdata_.next_owner[7],
67  }}));
68  case kOwnershipStateUnlockedSelf:
69  owner_page[1].owner_key = owner_page[0].owner_key;
70  owner_page[1].owner_key.raw[0] += modifier;
71  break;
72  case kOwnershipStateUnlockedAny:
73  // In UnlockedAny, there are no conditions that page1 must meet.
74  break;
75  case kOwnershipStateLockedOwner:
76  owner_page_valid[1] = kOwnerPageStatusSealed;
77  break;
78  case kOwnershipStateRecovery:
79  owner_page_valid[1] = kOwnerPageStatusInvalid;
80  break;
81  }
82  }
83 
84  boot_data_t bootdata_ = {
85  .nonce = kDefaultNonce,
86  .ownership_state = kOwnershipStateLockedOwner,
87  };
88  boot_svc_msg_t message_ = {
89  .ownership_activate_req =
90  {
91  .header =
92  {
93  .type = kBootSvcOwnershipActivateReqType,
94  },
95  .nonce = kDefaultNonce,
96  },
97  };
98 
99  rom_test::MockHmac hmac_;
100  rom_test::MockRnd rnd_;
101  rom_test::MockFlashCtrl flash_ctrl_;
102  rom_test::MockBootSvcHeader hdr_;
103  rom_test::MockLifecycle lifecycle_;
104  rom_test::MockOwnershipKey ownership_key_;
105 };
106 
108  : public OwnershipActivateTest,
109  public testing::WithParamInterface<ownership_state_t> {};
110 
112  : public OwnershipActivateTest,
113  public testing::WithParamInterface<ownership_state_t> {};
114 
115 // Tests that requesting Activate in all Locked non-Update states fails.
116 TEST_P(OwnershipActivateInvalidStateTest, InvalidState) {
117  bootdata_.ownership_state = static_cast<uint32_t>(GetParam());
118  EXPECT_CALL(hdr_, Finalize(_, _, _));
119 
120  rom_error_t error = ownership_activate_handler(&message_, &bootdata_);
121  EXPECT_EQ(error, kErrorOwnershipInvalidState);
122 }
123 
124 INSTANTIATE_TEST_SUITE_P(AllCases, OwnershipActivateInvalidStateTest,
125  testing::Values(kOwnershipStateLockedOwner,
126  kOwnershipStateRecovery));
127 
128 // Tests that an owner block with an invalid version fails.
129 TEST_P(OwnershipActivateValidStateTest, InvalidVersion) {
130  bootdata_.ownership_state = static_cast<uint32_t>(GetParam());
131  MakePage1Valid(true);
132  owner_page[1].header.version.major = 5;
133 
134  EXPECT_CALL(ownership_key_, validate(1, kOwnershipKeyActivate, _, _, _))
135  .WillOnce(Return(kHardenedBoolTrue));
136  EXPECT_CALL(lifecycle_, DeviceId(_))
137  .WillOnce(SetArgPointee<0>((lifecycle_device_id_t){0}));
138  EXPECT_CALL(hdr_, Finalize(_, _, _));
139 
140  rom_error_t error = ownership_activate_handler(&message_, &bootdata_);
141  EXPECT_EQ(error, kErrorOwnershipOWNRVersion);
142 }
143 
144 // Tests that an owner block with an invalid signature fails.
145 TEST_P(OwnershipActivateValidStateTest, InvalidSignature) {
146  bootdata_.ownership_state = static_cast<uint32_t>(GetParam());
147  // We want to pass the page 1 validity test to check the signature on the
148  // message.
149  MakePage1Valid(true);
150  EXPECT_CALL(ownership_key_, validate(1, kOwnershipKeyActivate, _, _, _))
151  .WillOnce(Return(kHardenedBoolFalse));
152  EXPECT_CALL(hdr_, Finalize(_, _, _));
153 
154  rom_error_t error = ownership_activate_handler(&message_, &bootdata_);
155  EXPECT_EQ(error, kErrorOwnershipInvalidSignature);
156 }
157 
158 // Tests that an ownership activate with an invalid nonce fails.
159 TEST_P(OwnershipActivateValidStateTest, InvalidNonce) {
160  bootdata_.ownership_state = static_cast<uint32_t>(GetParam());
161  bootdata_.nonce = {3, 4};
162  // We want to pass the page 1 validity test to check the nonce of the
163  // message.
164  MakePage1Valid(true);
165  EXPECT_CALL(ownership_key_, validate(1, kOwnershipKeyActivate, _, _, _))
166  .WillOnce(Return(kHardenedBoolTrue));
167  EXPECT_CALL(hdr_, Finalize(_, _, _));
168 
169  rom_error_t error = ownership_activate_handler(&message_, &bootdata_);
170  EXPECT_EQ(error, kErrorOwnershipInvalidNonce);
171 }
172 
173 // Tests that an ownership activate with an invalid DIN fails.
174 TEST_P(OwnershipActivateValidStateTest, InvalidActivateDin) {
175  bootdata_.ownership_state = static_cast<uint32_t>(GetParam());
176  // We want to pass the page 1 validity test to check the nonce of the
177  // message.
178  MakePage1Valid(true);
179  EXPECT_CALL(ownership_key_, validate(1, kOwnershipKeyActivate, _, _, _))
180  .WillOnce(Return(kHardenedBoolTrue));
181  EXPECT_CALL(lifecycle_, DeviceId(_))
182  .WillOnce(SetArgPointee<0>((lifecycle_device_id_t){0, 1, 1}));
183  EXPECT_CALL(hdr_, Finalize(_, _, _));
184 
185  rom_error_t error = ownership_activate_handler(&message_, &bootdata_);
186  EXPECT_EQ(error, kErrorOwnershipInvalidDin);
187 }
188 
189 // Tests that an owner block with an invalid owner page with respect to the
190 // current update state fails.
191 TEST_P(OwnershipActivateValidStateTest, OwnerPageInvalid) {
192  ownership_state_t state = GetParam();
193  if (state == kOwnershipStateUnlockedAny) {
194  SUCCEED() << "There are no invalid conditions for UnlockedAny";
195  return;
196  }
197  bootdata_.ownership_state = static_cast<uint32_t>(state);
198 
199  rom_error_t expected_result = kErrorOk;
200  owner_page[0].owner_key = {{1, 2, 3, 4, 5}};
201  bootdata_.next_owner[0] = 12345;
202  MakePage1Valid(false);
203 
204  switch (state) {
205  case kOwnershipStateUnlockedSelf:
206  case kOwnershipStateUnlockedEndorsed:
207  // Test should fail with "Invalid Info Page".
208  expected_result = kErrorOwnershipInvalidInfoPage;
209  break;
210  default:
211  FAIL() << "Invalid state for this test: " << state;
212  }
213 
214  EXPECT_CALL(hdr_, Finalize(_, _, _));
215 
216  rom_error_t error = ownership_activate_handler(&message_, &bootdata_);
217  EXPECT_EQ(error, expected_result);
218 }
219 
220 // Tests that an owner block with a valid owner page with respect to the current
221 // unlock state succeeds.
222 TEST_P(OwnershipActivateValidStateTest, OwnerPageValid) {
223  ownership_state_t state = GetParam();
224  bootdata_.ownership_state = static_cast<uint32_t>(state);
225 
226  owner_page[0].owner_key = {{1}};
227  memset(bootdata_.next_owner, 0, sizeof(bootdata_.next_owner));
228  bootdata_.next_owner[0] = 12345;
229  MakePage1Valid(true);
230 
231  EXPECT_CALL(ownership_key_, validate(1, kOwnershipKeyActivate, _, _, _))
232  .WillOnce(Return(kHardenedBoolTrue));
233  EXPECT_CALL(lifecycle_, DeviceId(_))
234  .WillOnce(SetArgPointee<0>((lifecycle_device_id_t){0}));
235 
236  switch (state) {
237  case kOwnershipStateUnlockedSelf:
238  case kOwnershipStateUnlockedAny:
239  case kOwnershipStateUnlockedEndorsed:
240  // Test should pass.
241  break;
242  default:
243  FAIL() << "Invalid state for this test: " << state;
244  }
245  // Once the new owner page is determined to be valid, the page will be sealed.
246  EXPECT_CALL(ownership_key_, seal_page(1));
247 
248  // The sealed page will be written into flash owner slot 1 first.
249  EXPECT_CALL(flash_ctrl_,
250  InfoErase(&kFlashCtrlInfoPageOwnerSlot1, kFlashCtrlEraseTypePage))
251  .WillOnce(Return(kErrorOk));
252  EXPECT_CALL(flash_ctrl_, InfoWrite(&kFlashCtrlInfoPageOwnerSlot1, 0,
253  sizeof(owner_page[1]) / sizeof(uint32_t),
254  &owner_page[1]))
255  .WillOnce(Return(kErrorOk));
256  // The sealed page will be written into flash owner slot 0 second.
257  EXPECT_CALL(flash_ctrl_,
258  InfoErase(&kFlashCtrlInfoPageOwnerSlot0, kFlashCtrlEraseTypePage))
259  .WillOnce(Return(kErrorOk));
260  EXPECT_CALL(flash_ctrl_, InfoWrite(&kFlashCtrlInfoPageOwnerSlot0, 0,
261  sizeof(owner_page[1]) / sizeof(uint32_t),
262  &owner_page[1]))
263  .WillOnce(Return(kErrorOk));
264 
265  if (state != kOwnershipStateUnlockedSelf) {
266  EXPECT_CALL(ownership_key_, secret_new()).WillOnce(Return(kErrorOk));
267  }
268 
269  // The nonce will be regenerated.
270  EXPECT_CALL(rnd_, Uint32()).WillRepeatedly(Return(99));
271  // The boot_svc response will be finalized.
272  EXPECT_CALL(hdr_, Finalize(_, _, _));
273 
274  rom_error_t error = ownership_activate_handler(&message_, &bootdata_);
275  EXPECT_EQ(error, kErrorWriteBootdataThenReboot);
276  // After succeeding, the page should be sealed, the nonce changed and the
277  // ownership state set to LockedOwner.
278  EXPECT_FALSE(nonce_equal(&bootdata_.nonce, &kDefaultNonce));
279  EXPECT_EQ(bootdata_.ownership_state, kOwnershipStateLockedOwner);
280  // The default value of `owner_page.min_security_version_bl0` should perform
281  // no update to the bootdata's minimum version.
282  EXPECT_EQ(bootdata_.min_security_version_bl0, 0);
283 }
284 
285 // Tests that an owner update with a non-default value of
286 // `min_security_version_bl0` updates bootdata's copy.
287 //
288 // TODO(cfrantz): Refactor this test as it is nearly a complete copy of the
289 // previous test except for the manipulation of the min_sec_ver.
290 TEST_P(OwnershipActivateValidStateTest, UpdateBootdataBl0) {
291  ownership_state_t state = GetParam();
292  bootdata_.ownership_state = static_cast<uint32_t>(state);
293 
294  owner_page[0].owner_key = {{1}};
295  memset(bootdata_.next_owner, 0, sizeof(bootdata_.next_owner));
296  bootdata_.next_owner[0] = 12345;
297  MakePage1Valid(true);
298  owner_page[1].min_security_version_bl0 = 5;
299 
300  EXPECT_CALL(ownership_key_, validate(1, kOwnershipKeyActivate, _, _, _))
301  .WillOnce(Return(kHardenedBoolTrue));
302  EXPECT_CALL(lifecycle_, DeviceId(_))
303  .WillOnce(SetArgPointee<0>((lifecycle_device_id_t){0}));
304 
305  switch (state) {
306  case kOwnershipStateUnlockedSelf:
307  case kOwnershipStateUnlockedAny:
308  case kOwnershipStateUnlockedEndorsed:
309  // Test should pass.
310  break;
311  default:
312  FAIL() << "Invalid state for this test: " << state;
313  }
314  // Once the new owner page is determined to be valid, the page will be sealed.
315  EXPECT_CALL(ownership_key_, seal_page(1));
316 
317  // The sealed page will be written into flash owner slot 1 first.
318  EXPECT_CALL(flash_ctrl_,
319  InfoErase(&kFlashCtrlInfoPageOwnerSlot1, kFlashCtrlEraseTypePage))
320  .WillOnce(Return(kErrorOk));
321  EXPECT_CALL(flash_ctrl_, InfoWrite(&kFlashCtrlInfoPageOwnerSlot1, 0,
322  sizeof(owner_page[1]) / sizeof(uint32_t),
323  &owner_page[1]))
324  .WillOnce(Return(kErrorOk));
325  // The sealed page will be written into flash owner slot 0 second.
326  EXPECT_CALL(flash_ctrl_,
327  InfoErase(&kFlashCtrlInfoPageOwnerSlot0, kFlashCtrlEraseTypePage))
328  .WillOnce(Return(kErrorOk));
329  EXPECT_CALL(flash_ctrl_, InfoWrite(&kFlashCtrlInfoPageOwnerSlot0, 0,
330  sizeof(owner_page[1]) / sizeof(uint32_t),
331  &owner_page[1]))
332  .WillOnce(Return(kErrorOk));
333 
334  if (state != kOwnershipStateUnlockedSelf) {
335  EXPECT_CALL(ownership_key_, secret_new()).WillOnce(Return(kErrorOk));
336  }
337 
338  // The nonce will be regenerated.
339  EXPECT_CALL(rnd_, Uint32()).WillRepeatedly(Return(99));
340  // The boot_svc response will be finalized.
341  EXPECT_CALL(hdr_, Finalize(_, _, _));
342 
343  rom_error_t error = ownership_activate_handler(&message_, &bootdata_);
344  EXPECT_EQ(error, kErrorWriteBootdataThenReboot);
345  // After succeeding, the page should be sealed, the nonce changed and the
346  // ownership state set to LockedOwner.
347  EXPECT_FALSE(nonce_equal(&bootdata_.nonce, &kDefaultNonce));
348  EXPECT_EQ(bootdata_.ownership_state, kOwnershipStateLockedOwner);
349  // Bootdata should receive the owner_block's minimum version upon activation.
350  EXPECT_EQ(bootdata_.min_security_version_bl0, 5);
351 }
352 
353 INSTANTIATE_TEST_SUITE_P(AllCases, OwnershipActivateValidStateTest,
354  testing::Values(kOwnershipStateUnlockedSelf,
355  kOwnershipStateUnlockedAny,
356  kOwnershipStateUnlockedEndorsed));
357 
358 } // namespace