@@ -118,6 +118,10 @@ class OwnershipActivateValidStateTest
118
118
: public OwnershipActivateTest,
119
119
public testing::WithParamInterface<ownership_state_t > {};
120
120
121
+ class OwnershipActivateNextBl0Slot
122
+ : public OwnershipActivateTest,
123
+ public testing::WithParamInterface<boot_slot_t > {};
124
+
121
125
// Tests that requesting Activate in all Locked non-Update states fails.
122
126
TEST_P (OwnershipActivateInvalidStateTest, InvalidState) {
123
127
bootdata_.ownership_state = static_cast <uint32_t >(GetParam ());
@@ -298,7 +302,7 @@ TEST_P(OwnershipActivateValidStateTest, OwnerPageValid) {
298
302
//
299
303
// TODO(cfrantz): Refactor this test as it is nearly a complete copy of the
300
304
// previous test except for the manipulation of the min_sec_ver.
301
- TEST_P (OwnershipActivateValidStateTest, UpdateBootdataBl0 ) {
305
+ TEST_P (OwnershipActivateValidStateTest, UpdateBootdataBl0MinSecVer ) {
302
306
ownership_state_t state = GetParam ();
303
307
bootdata_.ownership_state = static_cast <uint32_t >(state);
304
308
@@ -367,4 +371,80 @@ INSTANTIATE_TEST_SUITE_P(AllCases, OwnershipActivateValidStateTest,
367
371
kOwnershipStateUnlockedAny ,
368
372
kOwnershipStateUnlockedEndorsed ));
369
373
374
+ // TODO(cfrantz): Refactor this test as it is nearly a complete copy of the
375
+ // previous test except for the manipulation of the primary_bl0_slot.
376
+ TEST_P (OwnershipActivateNextBl0Slot, UpdateBootdataPrimaryBl0Slot) {
377
+ bootdata_.ownership_state = kOwnershipStateUnlockedAny ;
378
+ boot_slot_t next_slot = GetParam ();
379
+ message_.ownership_activate_req .primary_bl0_slot = next_slot;
380
+
381
+ // We initialize the primary slot with an invalid value so we can
382
+ // check later if the value is changed or unchanged according the
383
+ // requested next_slot value.
384
+ bootdata_.primary_bl0_slot = static_cast <boot_slot_t >(0 );
385
+
386
+ owner_page[0 ].owner_key = {{1 }};
387
+ memset (bootdata_.next_owner , 0 , sizeof (bootdata_.next_owner ));
388
+ MakePage1Valid (true );
389
+
390
+ EXPECT_CALL (ownership_key_,
391
+ validate (1 , kOwnershipKeyActivate , kActivate , _, _, _, _))
392
+ .WillOnce (Return (kErrorOk ));
393
+ EXPECT_CALL (lifecycle_, DeviceId (_))
394
+ .WillOnce (SetArgPointee<0 >((lifecycle_device_id_t ){0 }));
395
+
396
+ // Once the new owner page is determined to be valid, the page will be sealed.
397
+ EXPECT_CALL (ownership_key_, seal_page (1 ));
398
+
399
+ // The sealed page will be written into flash owner slot 1 first.
400
+ EXPECT_CALL (flash_ctrl_,
401
+ InfoErase (&kFlashCtrlInfoPageOwnerSlot1 , kFlashCtrlEraseTypePage ))
402
+ .WillOnce (Return (kErrorOk ));
403
+ EXPECT_CALL (flash_ctrl_, InfoWrite (&kFlashCtrlInfoPageOwnerSlot1 , 0 ,
404
+ sizeof (owner_page[1 ]) / sizeof (uint32_t ),
405
+ &owner_page[1 ]))
406
+ .WillOnce (Return (kErrorOk ));
407
+ // The sealed page will be written into flash owner slot 0 second.
408
+ EXPECT_CALL (flash_ctrl_,
409
+ InfoErase (&kFlashCtrlInfoPageOwnerSlot0 , kFlashCtrlEraseTypePage ))
410
+ .WillOnce (Return (kErrorOk ));
411
+ EXPECT_CALL (flash_ctrl_, InfoWrite (&kFlashCtrlInfoPageOwnerSlot0 , 0 ,
412
+ sizeof (owner_page[1 ]) / sizeof (uint32_t ),
413
+ &owner_page[1 ]))
414
+ .WillOnce (Return (kErrorOk ));
415
+
416
+ // The transfer will regenerate the owner secret.
417
+ EXPECT_CALL (ownership_key_, secret_new (_, _)).WillOnce (Return (kErrorOk ));
418
+
419
+ // The nonce will be regenerated.
420
+ EXPECT_CALL (rnd_, Uint32 ()).WillRepeatedly (Return (99 ));
421
+ // The boot_svc response will be finalized.
422
+ EXPECT_CALL (hdr_, Finalize (_, _, _));
423
+
424
+ rom_error_t error = ownership_activate_handler (&message_, &bootdata_);
425
+ EXPECT_EQ (error, kErrorWriteBootdataThenReboot );
426
+ // After succeeding, the page should be sealed, the nonce changed and the
427
+ // ownership state set to LockedOwner.
428
+ EXPECT_FALSE (nonce_equal (&bootdata_.nonce , &kDefaultNonce ));
429
+ EXPECT_EQ (bootdata_.ownership_state , kOwnershipStateLockedOwner );
430
+
431
+ switch (next_slot) {
432
+ case kBootSlotA :
433
+ case kBootSlotB :
434
+ // Bootdata primary_bl0_slot should be updated.
435
+ EXPECT_EQ (bootdata_.primary_bl0_slot , next_slot);
436
+ break ;
437
+ default :
438
+ // Bootdata primary_bl0_slot should be unchanged from the original value.
439
+ EXPECT_EQ (bootdata_.primary_bl0_slot , static_cast <boot_slot_t >(0 ));
440
+ }
441
+ }
442
+
443
+ INSTANTIATE_TEST_SUITE_P (AllCases, OwnershipActivateNextBl0Slot,
444
+ testing::Values (kBootSlotA , kBootSlotB ,
445
+ // Both `Unspecified` and all garbage
446
+ // values should result in no change.
447
+ kBootSlotUnspecified ,
448
+ static_cast <boot_slot_t >(12345 )));
449
+
370
450
} // namespace
0 commit comments