Software APIs
ownership_activate.c
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 
9 #include "sw/device/silicon_creator/lib/boot_data.h"
10 #include "sw/device/silicon_creator/lib/boot_svc/boot_svc_msg.h"
11 #include "sw/device/silicon_creator/lib/drivers/flash_ctrl.h"
12 #include "sw/device/silicon_creator/lib/drivers/lifecycle.h"
13 #include "sw/device/silicon_creator/lib/error.h"
14 #include "sw/device/silicon_creator/lib/ownership/owner_block.h"
15 #include "sw/device/silicon_creator/lib/ownership/ownership_key.h"
16 
17 rom_error_t ownership_activate(boot_data_t *bootdata,
18  hardened_bool_t write_both_pages) {
19  // Check if page1 parses correctly.
20  owner_config_t config;
22  HARDENED_RETURN_IF_ERROR(
23  owner_block_parse(&owner_page[1], &config, &keyring));
24 
25  // Seal page one to this chip.
26  ownership_seal_page(/*page=*/1);
27 
28  // If requested, reset the mim security version of the application firmware.
29  if (owner_page[1].min_security_version_bl0 != UINT32_MAX) {
30  bootdata->min_security_version_bl0 = owner_page[1].min_security_version_bl0;
31  }
32 
33  // TODO(cfrantz): Consider reading back the flash pages to check that the
34  // flash writes succeeded.
35  //
36  // Program the sealed page into slot 1.
37  HARDENED_RETURN_IF_ERROR(flash_ctrl_info_erase(&kFlashCtrlInfoPageOwnerSlot1,
38  kFlashCtrlEraseTypePage));
39  HARDENED_RETURN_IF_ERROR(flash_ctrl_info_write(
40  &kFlashCtrlInfoPageOwnerSlot1, 0,
41  sizeof(owner_page[1]) / sizeof(uint32_t), &owner_page[1]));
42 
43  if (write_both_pages == kHardenedBoolTrue) {
44  // Program the same data into slot 0.
45  HARDENED_RETURN_IF_ERROR(flash_ctrl_info_erase(
46  &kFlashCtrlInfoPageOwnerSlot0, kFlashCtrlEraseTypePage));
47  HARDENED_RETURN_IF_ERROR(flash_ctrl_info_write(
48  &kFlashCtrlInfoPageOwnerSlot0, 0,
49  sizeof(owner_page[1]) / sizeof(uint32_t), &owner_page[1]));
50  }
51 
52  return kErrorOk;
53 }
54 
55 static rom_error_t activate_handler(boot_svc_msg_t *msg,
56  boot_data_t *bootdata) {
57  // Check if page1 is in a valid state for a transfer (e.g. signature and owner
58  // requirements are met). We do this first (rather than parse) because if the
59  // signature requirements are not met, the RAM copy of the owner page will be
60  // destroyed.
61  if (owner_block_page1_valid_for_transfer(bootdata) != kHardenedBoolTrue) {
62  return kErrorOwnershipInvalidInfoPage;
63  }
64 
65  // Check the activation key and the nonce.
66  size_t len = (uintptr_t)&msg->ownership_activate_req.signature -
67  (uintptr_t)&msg->ownership_activate_req.primary_bl0_slot;
68  if (ownership_key_validate(/*page=*/1, kOwnershipKeyActivate,
69  &msg->ownership_activate_req.signature,
70  &msg->ownership_activate_req.primary_bl0_slot,
71  len) == kHardenedBoolFalse) {
72  return kErrorOwnershipInvalidSignature;
73  }
74  if (!nonce_equal(&msg->ownership_activate_req.nonce, &bootdata->nonce)) {
75  return kErrorOwnershipInvalidNonce;
76  }
77 
78  // Verify the device identification number is correct.
79  lifecycle_device_id_t device_id;
80  lifecycle_device_id_get(&device_id);
81  if (lifecycle_din_eq(&device_id, msg->ownership_activate_req.din) !=
83  return kErrorOwnershipInvalidDin;
84  }
85 
86  HARDENED_RETURN_IF_ERROR(
87  ownership_activate(bootdata, /*write_both_pages=*/kHardenedBoolTrue));
88 
89  // The requested primary_bl0_slot is user input. Validate and clamp it to
90  // legal values.
91  if (msg->ownership_activate_req.primary_bl0_slot == kBootSlotB) {
92  bootdata->primary_bl0_slot = kBootSlotB;
93  } else {
94  bootdata->primary_bl0_slot = kBootSlotA;
95  }
96 
97  if (bootdata->ownership_state == kOwnershipStateUnlockedSelf) {
98  // An activate from UnlockedSelf is not a transfer and should not
99  // regenerate the OwnerSecret page.
100  HARDENED_CHECK_EQ(bootdata->ownership_state, kOwnershipStateUnlockedSelf);
101  } else {
102  // All other activations are transfers and need to regenerate entropy stored
103  // in the OwnerSecret page.
104  HARDENED_RETURN_IF_ERROR(ownership_secret_new());
105  bootdata->ownership_transfers += 1;
106  }
107 
108  // Set the ownership state to LockedOwner.
109  nonce_new(&bootdata->nonce);
110  bootdata->ownership_state = kOwnershipStateLockedOwner;
111  memset(bootdata->next_owner, 0, sizeof(bootdata->next_owner));
112  return kErrorWriteBootdataThenReboot;
113 }
114 
115 rom_error_t ownership_activate_handler(boot_svc_msg_t *msg,
116  boot_data_t *bootdata) {
117  rom_error_t error = kErrorOwnershipInvalidState;
118  switch (bootdata->ownership_state) {
119  case kOwnershipStateUnlockedSelf:
120  case kOwnershipStateUnlockedAny:
121  case kOwnershipStateUnlockedEndorsed:
122  error = activate_handler(msg, bootdata);
123  break;
124  default:
125  /* nothing */;
126  }
127  boot_svc_ownership_activate_res_init(
128  error == kErrorWriteBootdataThenReboot ? kErrorOk : error,
129  &msg->ownership_activate_res);
130  return error;
131 }