Software APIs
ownership_unlock.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_unlock.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/hmac.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 static hardened_bool_t is_locked_none(uint32_t ownership_state) {
18  if (ownership_state == kOwnershipStateLockedOwner ||
19  ownership_state == kOwnershipStateUnlockedSelf ||
20  ownership_state == kOwnershipStateUnlockedAny ||
21  ownership_state == kOwnershipStateUnlockedEndorsed) {
22  return kHardenedBoolFalse;
23  }
24  return kHardenedBoolTrue;
25 }
26 
27 static rom_error_t do_unlock(boot_svc_msg_t *msg, boot_data_t *bootdata) {
28  // Verify that the nonce is correct.
29  if (!nonce_equal(&msg->ownership_unlock_req.nonce, &bootdata->nonce)) {
30  return kErrorOwnershipInvalidNonce;
31  }
32 
33  // Verify the device identification number is correct.
34  lifecycle_device_id_t device_id;
35  lifecycle_device_id_get(&device_id);
36  if (lifecycle_din_eq(&device_id, msg->ownership_unlock_req.din) !=
38  return kErrorOwnershipInvalidDin;
39  }
40 
41  if (msg->ownership_unlock_req.unlock_mode == kBootSvcUnlockEndorsed) {
42  hmac_digest_t digest;
43  hmac_sha256(&msg->ownership_unlock_req.next_owner_key,
44  sizeof(msg->ownership_unlock_req.next_owner_key), &digest);
45  memcpy(&bootdata->next_owner, &digest, sizeof(digest));
46  bootdata->ownership_state = kOwnershipStateUnlockedEndorsed;
47  } else if (msg->ownership_unlock_req.unlock_mode == kBootSvcUnlockAny) {
48  bootdata->ownership_state = kOwnershipStateUnlockedAny;
49  } else if (msg->ownership_unlock_req.unlock_mode == kBootSvcUnlockUpdate) {
50  bootdata->ownership_state = kOwnershipStateUnlockedSelf;
51  } else {
52  return kErrorOwnershipInvalidMode;
53  }
54  nonce_new(&bootdata->nonce);
55  return kErrorWriteBootdataThenReboot;
56 }
57 
58 static rom_error_t unlock(boot_svc_msg_t *msg, boot_data_t *bootdata) {
59  size_t len = (uintptr_t)&msg->ownership_unlock_req.signature -
60  (uintptr_t)&msg->ownership_unlock_req.unlock_mode;
61  if (bootdata->ownership_state == kOwnershipStateLockedOwner) {
62  switch (owner_page[0].update_mode) {
63  case kOwnershipUpdateModeOpen:
64  // The Open mode allows unlock to any unlock state.
65  break;
66  case kOwnershipUpdateModeNewVersion:
67  // The NewVersion mode forbids all unlocks.
68  return kErrorOwnershipUnlockDenied;
69  case kOwnershipUpdateModeSelf:
70  case kOwnershipUpdateModeSelfVersion:
71  default:
72  // The `unlock` funciton services UnlockAny and UnlockEndorsed requests,
73  // neither of which are valid for the `Self` mode.
74  return kErrorOwnershipInvalidMode;
75  }
76  // Check the signature against the unlock key.
77  // TODO(cfrantz): Add a mechanism to control whether or not the
78  // recovery key is allowed here.
79  if (ownership_key_validate(
80  /*page=*/0, kOwnershipKeyUnlock | kOwnershipKeyRecovery,
81  &msg->ownership_unlock_req.signature,
82  &msg->ownership_unlock_req.unlock_mode,
83  len) == kHardenedBoolFalse) {
84  return kErrorOwnershipInvalidSignature;
85  }
86  return do_unlock(msg, bootdata);
87  } else if (is_locked_none(bootdata->ownership_state) == kHardenedBoolTrue) {
88  // In the No-Owner state, we check against the silicon_creator's
89  // no_owner_recovery_key.
90  if (ownership_key_validate(/*page=*/0, kOwnershipKeyRecovery,
91  &msg->ownership_unlock_req.signature,
92  &msg->ownership_unlock_req.unlock_mode,
93  len) == kHardenedBoolFalse) {
94  return kErrorOwnershipInvalidSignature;
95  }
96  return do_unlock(msg, bootdata);
97  } else {
98  return kErrorOwnershipInvalidState;
99  }
100 }
101 
102 static rom_error_t unlock_update(boot_svc_msg_t *msg, boot_data_t *bootdata) {
103  size_t len = (uintptr_t)&msg->ownership_unlock_req.signature -
104  (uintptr_t)&msg->ownership_unlock_req.unlock_mode;
105  if (bootdata->ownership_state == kOwnershipStateLockedOwner) {
106  switch (owner_page[0].update_mode) {
107  case kOwnershipUpdateModeNewVersion:
108  // The NewVersion mode forbids all unlocks.
109  return kErrorOwnershipUnlockDenied;
110  case kOwnershipUpdateModeSelf:
111  case kOwnershipUpdateModeSelfVersion:
112  case kOwnershipUpdateModeOpen:
113  default:
114  // The `unlock_update` funciton services UnlockUpdate update requests,
115  // which are valid for the `Open` and `Self` modes.
116  ;
117  }
118  // Check the signature against the unlock key.
119  if (ownership_key_validate(/*page=*/0, kOwnershipKeyUnlock,
120  &msg->ownership_unlock_req.signature,
121  &msg->ownership_unlock_req.unlock_mode,
122  len) == kHardenedBoolFalse) {
123  return kErrorOwnershipInvalidSignature;
124  }
125  return do_unlock(msg, bootdata);
126  }
127  return kErrorOwnershipInvalidState;
128 }
129 
130 static rom_error_t unlock_abort(boot_svc_msg_t *msg, boot_data_t *bootdata) {
131  size_t len = (uintptr_t)&msg->ownership_unlock_req.signature -
132  (uintptr_t)&msg->ownership_unlock_req.unlock_mode;
133  if (bootdata->ownership_state == kOwnershipStateUnlockedEndorsed ||
134  bootdata->ownership_state == kOwnershipStateUnlockedAny ||
135  bootdata->ownership_state == kOwnershipStateUnlockedSelf) {
136  // Check the signature against the unlock key.
137  if (ownership_key_validate(/*page=*/0, kOwnershipKeyUnlock,
138  &msg->ownership_unlock_req.signature,
139  &msg->ownership_unlock_req.unlock_mode,
140  len) == kHardenedBoolFalse) {
141  return kErrorOwnershipInvalidSignature;
142  }
143  if (!nonce_equal(&msg->ownership_unlock_req.nonce, &bootdata->nonce)) {
144  return kErrorOwnershipInvalidNonce;
145  }
146 
147  // Verify the device identification number is correct.
148  lifecycle_device_id_t device_id;
149  lifecycle_device_id_get(&device_id);
150  if (lifecycle_din_eq(&device_id, msg->ownership_unlock_req.din) !=
152  return kErrorOwnershipInvalidDin;
153  }
154  // Go back to locked owner.
155  bootdata->ownership_state = kOwnershipStateLockedOwner;
156  nonce_new(&bootdata->nonce);
157  return kErrorWriteBootdataThenReboot;
158  }
159  return kErrorOwnershipInvalidState;
160 }
161 
162 rom_error_t ownership_unlock_handler(boot_svc_msg_t *msg,
163  boot_data_t *bootdata) {
164  rom_error_t error = kErrorOwnershipInvalidRequest;
165  switch (msg->ownership_unlock_req.unlock_mode) {
166  case kBootSvcUnlockAny:
167  error = unlock(msg, bootdata);
168  break;
169  case kBootSvcUnlockEndorsed:
170  error = unlock(msg, bootdata);
171  break;
172  case kBootSvcUnlockUpdate:
173  error = unlock_update(msg, bootdata);
174  break;
175  case kBootSvcUnlockAbort:
176  error = unlock_abort(msg, bootdata);
177  break;
178  default:
179  /* nothing */;
180  }
181  boot_svc_ownership_unlock_res_init(
182  error == kErrorWriteBootdataThenReboot ? kErrorOk : error,
183  &msg->ownership_unlock_res);
184  return error;
185 }