Software APIs
dif_keymgr.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 
6 
7 #include <assert.h>
8 
10 
11 #include "keymgr_regs.h" // Generated.
13 
14 /**
15  * Make sure dif_keymgr_sideload_clr_t enum is in sync with autogenarated
16  * values.
17  */
18 OT_ASSERT_ENUM_VALUE(kDifKeyMgrSideLoadClearNone,
19  KEYMGR_SIDELOAD_CLEAR_VAL_VALUE_NONE);
20 OT_ASSERT_ENUM_VALUE(kDifKeyMgrSideLoadClearAes,
21  KEYMGR_SIDELOAD_CLEAR_VAL_VALUE_AES);
22 OT_ASSERT_ENUM_VALUE(kDifKeyMgrSideLoadClearKmac,
23  KEYMGR_SIDELOAD_CLEAR_VAL_VALUE_KMAC);
24 OT_ASSERT_ENUM_VALUE(kDifKeyMgrSideLoadClearOtbn,
25  KEYMGR_SIDELOAD_CLEAR_VAL_VALUE_OTBN);
26 OT_ASSERT_ENUM_VALUE(kDifKeyMgrSideLoadClearAll,
27  KEYMGR_SIDELOAD_CLEAR_VAL_MASK);
28 
29 /**
30  * Address spaces of SEALING_SW_BINDING_N, SALT_N, SW_SHARE0_OUTPUT_N, and
31  * SW_SHARE1_OUTPUT_N registers must be contiguous to be able to use
32  * `mmio_region_memcpy_to/from_mmio32()`.
33  */
34 static_assert(KEYMGR_SEALING_SW_BINDING_1_REG_OFFSET ==
35  KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET + 4,
36  "SEALING_SW_BINDING_N registers must be contiguous.");
37 static_assert(KEYMGR_SEALING_SW_BINDING_2_REG_OFFSET ==
38  KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET + 8,
39  "SEALING_SW_BINDING_N registers must be contiguous.");
40 static_assert(KEYMGR_SEALING_SW_BINDING_3_REG_OFFSET ==
41  KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET + 12,
42  "SEALING_SW_BINDING_N registers must be contiguous.");
43 static_assert(KEYMGR_SEALING_SW_BINDING_4_REG_OFFSET ==
44  KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET + 16,
45  "SEALING_SW_BINDING_N registers must be contiguous.");
46 static_assert(KEYMGR_SEALING_SW_BINDING_5_REG_OFFSET ==
47  KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET + 20,
48  "SEALING_SW_BINDING_N registers must be contiguous.");
49 static_assert(KEYMGR_SEALING_SW_BINDING_6_REG_OFFSET ==
50  KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET + 24,
51  "SEALING_SW_BINDING_N registers must be contiguous.");
52 static_assert(KEYMGR_SEALING_SW_BINDING_7_REG_OFFSET ==
53  KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET + 28,
54  "SEALING_SW_BINDING_N registers must be contiguous.");
55 
56 static_assert(KEYMGR_SALT_1_REG_OFFSET == KEYMGR_SALT_0_REG_OFFSET + 4,
57  "SALT_N registers must be contiguous.");
58 static_assert(KEYMGR_SALT_2_REG_OFFSET == KEYMGR_SALT_0_REG_OFFSET + 8,
59  "SALT_N registers must be contiguous.");
60 static_assert(KEYMGR_SALT_3_REG_OFFSET == KEYMGR_SALT_0_REG_OFFSET + 12,
61  "SALT_N registers must be contiguous.");
62 static_assert(KEYMGR_SALT_4_REG_OFFSET == KEYMGR_SALT_0_REG_OFFSET + 16,
63  "SALT_N registers must be contiguous.");
64 static_assert(KEYMGR_SALT_5_REG_OFFSET == KEYMGR_SALT_0_REG_OFFSET + 20,
65  "SALT_N registers must be contiguous.");
66 static_assert(KEYMGR_SALT_6_REG_OFFSET == KEYMGR_SALT_0_REG_OFFSET + 24,
67  "SALT_N registers must be contiguous.");
68 static_assert(KEYMGR_SALT_7_REG_OFFSET == KEYMGR_SALT_0_REG_OFFSET + 28,
69  "SALT_N registers must be contiguous.");
70 
71 static_assert(KEYMGR_SW_SHARE0_OUTPUT_1_REG_OFFSET ==
72  KEYMGR_SW_SHARE0_OUTPUT_0_REG_OFFSET + 4,
73  "SW_SHARE0_OUTPUT_N registers must be contiguous.");
74 static_assert(KEYMGR_SW_SHARE0_OUTPUT_2_REG_OFFSET ==
75  KEYMGR_SW_SHARE0_OUTPUT_0_REG_OFFSET + 8,
76  "SW_SHARE0_OUTPUT_N registers must be contiguous.");
77 static_assert(KEYMGR_SW_SHARE0_OUTPUT_3_REG_OFFSET ==
78  KEYMGR_SW_SHARE0_OUTPUT_0_REG_OFFSET + 12,
79  "SW_SHARE0_OUTPUT_N registers must be contiguous.");
80 static_assert(KEYMGR_SW_SHARE0_OUTPUT_4_REG_OFFSET ==
81  KEYMGR_SW_SHARE0_OUTPUT_0_REG_OFFSET + 16,
82  "SW_SHARE0_OUTPUT_N registers must be contiguous.");
83 static_assert(KEYMGR_SW_SHARE0_OUTPUT_5_REG_OFFSET ==
84  KEYMGR_SW_SHARE0_OUTPUT_0_REG_OFFSET + 20,
85  "SW_SHARE0_OUTPUT_N registers must be contiguous.");
86 static_assert(KEYMGR_SW_SHARE0_OUTPUT_6_REG_OFFSET ==
87  KEYMGR_SW_SHARE0_OUTPUT_0_REG_OFFSET + 24,
88  "SW_SHARE0_OUTPUT_N registers must be contiguous.");
89 static_assert(KEYMGR_SW_SHARE0_OUTPUT_7_REG_OFFSET ==
90  KEYMGR_SW_SHARE0_OUTPUT_0_REG_OFFSET + 28,
91  "SW_SHARE0_OUTPUT_N registers must be contiguous.");
92 
93 static_assert(KEYMGR_SW_SHARE1_OUTPUT_1_REG_OFFSET ==
94  KEYMGR_SW_SHARE1_OUTPUT_0_REG_OFFSET + 4,
95  "SW_SHARE1_OUTPUT_N registers must be contiguous.");
96 static_assert(KEYMGR_SW_SHARE1_OUTPUT_2_REG_OFFSET ==
97  KEYMGR_SW_SHARE1_OUTPUT_0_REG_OFFSET + 8,
98  "SW_SHARE1_OUTPUT_N registers must be contiguous.");
99 static_assert(KEYMGR_SW_SHARE1_OUTPUT_3_REG_OFFSET ==
100  KEYMGR_SW_SHARE1_OUTPUT_0_REG_OFFSET + 12,
101  "SW_SHARE1_OUTPUT_N registers must be contiguous.");
102 static_assert(KEYMGR_SW_SHARE1_OUTPUT_4_REG_OFFSET ==
103  KEYMGR_SW_SHARE1_OUTPUT_0_REG_OFFSET + 16,
104  "SW_SHARE1_OUTPUT_N registers must be contiguous.");
105 static_assert(KEYMGR_SW_SHARE1_OUTPUT_5_REG_OFFSET ==
106  KEYMGR_SW_SHARE1_OUTPUT_0_REG_OFFSET + 20,
107  "SW_SHARE1_OUTPUT_N registers must be contiguous.");
108 static_assert(KEYMGR_SW_SHARE1_OUTPUT_6_REG_OFFSET ==
109  KEYMGR_SW_SHARE1_OUTPUT_0_REG_OFFSET + 24,
110  "SW_SHARE1_OUTPUT_N registers must be contiguous.");
111 static_assert(KEYMGR_SW_SHARE1_OUTPUT_7_REG_OFFSET ==
112  KEYMGR_SW_SHARE1_OUTPUT_0_REG_OFFSET + 28,
113  "SW_SHARE1_OUTPUT_N registers must be contiguous.");
114 
115 /**
116  * Error code constants of `dif_keymgr_status_code_t` are masks for the bits of
117  * ERR_CODE register shifted left by 1.
118  */
119 static_assert(kDifKeymgrStatusCodeInvalidOperation >> 1 ==
120  1 << KEYMGR_ERR_CODE_INVALID_OP_BIT,
121  "Layout of ERR_CODE register changed.");
122 static_assert(kDifKeymgrStatusCodeInvalidKmacInput >> 1 ==
123  1 << KEYMGR_ERR_CODE_INVALID_KMAC_INPUT_BIT,
124  "Layout of ERR_CODE register changed.");
125 
126 /**
127  * Checks if the key manager is ready for a new operation, i.e. it is idle and
128  * the CONFIG register is unlocked.
129  */
131 static bool is_ready(const dif_keymgr_t *keymgr) {
132  // Keymgr must be idle and the CONTROL register must be writable.
133  uint32_t reg_op_status =
134  mmio_region_read32(keymgr->base_addr, KEYMGR_OP_STATUS_REG_OFFSET);
135  if (bitfield_field32_read(reg_op_status, KEYMGR_OP_STATUS_STATUS_FIELD) !=
136  KEYMGR_OP_STATUS_STATUS_VALUE_IDLE) {
137  return false;
138  }
139  uint32_t reg_cfg_regwen =
140  mmio_region_read32(keymgr->base_addr, KEYMGR_CFG_REGWEN_REG_OFFSET);
141  return bitfield_bit32_read(reg_cfg_regwen, KEYMGR_CFG_REGWEN_EN_BIT);
142 }
143 
144 /**
145  * Max key version register information for a state transition.
146  */
147 typedef struct max_key_version_reg_info {
148  /**
149  * Whether max key version must be set for this transition or not.
150  */
152  /**
153  * Max key version register offset to use.
154  */
155  uint32_t reg_offset;
156  /**
157  * Write-enable register offset to use.
158  */
159  uint32_t wen_reg_offset;
160  /**
161  * Write-enable bit index.
162  */
165 
166 /**
167  * Returns max key version register information for transitioning from a state.
168  */
170 static bool get_max_key_version_reg_info_for_next_state(
171  uint32_t cur_state, max_key_version_reg_info_t *reg_info) {
172  switch (cur_state) {
173  case KEYMGR_WORKING_STATE_STATE_VALUE_INIT:
174  *reg_info = (max_key_version_reg_info_t){
175  .is_required = true,
176  .reg_offset = KEYMGR_MAX_CREATOR_KEY_VER_SHADOWED_REG_OFFSET,
177  .wen_reg_offset = KEYMGR_MAX_CREATOR_KEY_VER_REGWEN_REG_OFFSET,
178  .wen_bit_index = KEYMGR_MAX_CREATOR_KEY_VER_REGWEN_EN_BIT,
179  };
180  return true;
181  case KEYMGR_WORKING_STATE_STATE_VALUE_CREATOR_ROOT_KEY:
182  *reg_info = (max_key_version_reg_info_t){
183  .is_required = true,
184  .reg_offset = KEYMGR_MAX_OWNER_INT_KEY_VER_SHADOWED_REG_OFFSET,
185  .wen_reg_offset = KEYMGR_MAX_OWNER_INT_KEY_VER_REGWEN_REG_OFFSET,
186  .wen_bit_index = KEYMGR_MAX_OWNER_INT_KEY_VER_REGWEN_EN_BIT,
187  };
188  return true;
189  case KEYMGR_WORKING_STATE_STATE_VALUE_OWNER_INTERMEDIATE_KEY:
190  *reg_info = (max_key_version_reg_info_t){
191  .is_required = true,
192  .reg_offset = KEYMGR_MAX_OWNER_KEY_VER_SHADOWED_REG_OFFSET,
193  .wen_reg_offset = KEYMGR_MAX_OWNER_KEY_VER_REGWEN_REG_OFFSET,
194  .wen_bit_index = KEYMGR_MAX_OWNER_KEY_VER_REGWEN_EN_BIT,
195  };
196  return true;
197  case KEYMGR_WORKING_STATE_STATE_VALUE_RESET:
198  case KEYMGR_WORKING_STATE_STATE_VALUE_OWNER_KEY:
199  case KEYMGR_WORKING_STATE_STATE_VALUE_DISABLED:
200  case KEYMGR_WORKING_STATE_STATE_VALUE_INVALID:
201  *reg_info = (max_key_version_reg_info_t){
202  .is_required = false,
203  };
204  return true;
205  default:
206  return false;
207  }
208 }
209 
210 /**
211  * Parameters for starting a key manager operation.
212  *
213  * Values of the members must be the actual values that will be written to the
214  * CONTROL register.
215  */
216 typedef struct start_operation_params {
217  /**
218  * Destination for this operation.
219  */
220  uint32_t dest;
221  /**
222  * Operation to start.
223  */
224  uint32_t op;
225  /**
226  * Compound Device Identifier type (sealing or attestation).
227  *
228  * Only relevant for the creation of identities, software and sideload keys,
229  * otherwise the key manager operations are identical for both types.
230  */
233 
234 /**
235  * Starts a key manager operation.
236  */
237 static void start_operation(const dif_keymgr_t *keymgr,
238  start_operation_params_t params) {
239  uint32_t reg_control = bitfield_field32_write(
240  0, KEYMGR_CONTROL_SHADOWED_DEST_SEL_FIELD, params.dest);
241  reg_control = bitfield_field32_write(
242  reg_control, KEYMGR_CONTROL_SHADOWED_OPERATION_FIELD, params.op);
243  reg_control = bitfield_field32_write(
244  reg_control,
245  (bitfield_field32_t){.mask = 0x1u,
246  .index = KEYMGR_CONTROL_SHADOWED_CDI_SEL_BIT},
247  params.cdi_type);
248  mmio_region_write32_shadowed(keymgr->base_addr,
249  KEYMGR_CONTROL_SHADOWED_REG_OFFSET, reg_control);
250  mmio_region_write32(keymgr->base_addr, KEYMGR_START_REG_OFFSET,
251  1 << KEYMGR_START_EN_BIT);
252 }
253 
255  dif_keymgr_config_t config) {
256  if (keymgr == NULL) {
257  return kDifBadArg;
258  }
259 
260  uint32_t reg_val =
261  bitfield_field32_write(0, KEYMGR_RESEED_INTERVAL_SHADOWED_VAL_FIELD,
262  config.entropy_reseed_interval);
263  mmio_region_write32_shadowed(
264  keymgr->base_addr, KEYMGR_RESEED_INTERVAL_SHADOWED_REG_OFFSET, reg_val);
265 
266  return kDifOk;
267 }
268 
270  const dif_keymgr_state_params_t *params) {
271  if (keymgr == NULL) {
272  return kDifBadArg;
273  }
274 
275  if (!is_ready(keymgr)) {
276  return kDifLocked;
277  }
278 
279  // Get current state and determine if we need to set the max key version and
280  // sw binding value.
281  max_key_version_reg_info_t max_key_ver_reg_info;
282  uint32_t reg_working_state =
283  mmio_region_read32(keymgr->base_addr, KEYMGR_WORKING_STATE_REG_OFFSET);
284  if (!get_max_key_version_reg_info_for_next_state(
285  (bitfield_field32_read(reg_working_state,
286  KEYMGR_WORKING_STATE_STATE_FIELD)),
287  &max_key_ver_reg_info)) {
288  return kDifError;
289  }
290 
291  // Set the binding value and max key version if keymgr is going to
292  // transition to an operational state.
293  if (max_key_ver_reg_info.is_required) {
294  if (params == NULL) {
295  return kDifBadArg;
296  }
297 
298  // Check if SEALING_SW_BINDING_N registers are locked
299  uint32_t reg_sw_binding_wen = mmio_region_read32(
300  keymgr->base_addr, KEYMGR_SW_BINDING_REGWEN_REG_OFFSET);
301  if (!bitfield_bit32_read(reg_sw_binding_wen,
302  KEYMGR_SW_BINDING_REGWEN_EN_BIT)) {
303  return kDifLocked;
304  }
305 
306  // Check if MAX_*_KEY_VER register is locked.
307  uint32_t reg_max_key_ver_wen = mmio_region_read32(
308  keymgr->base_addr, (ptrdiff_t)max_key_ver_reg_info.wen_reg_offset);
309  if (!bitfield_bit32_read(reg_max_key_ver_wen,
310  max_key_ver_reg_info.wen_bit_index)) {
311  return kDifLocked;
312  }
313 
314  // Write and lock (rw0c) the software binding value. This register is
315  // unlocked by hardware upon a successful state transition.
317  keymgr->base_addr, KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET,
318  params->binding_value, sizeof(params->binding_value));
319  mmio_region_write32(keymgr->base_addr, KEYMGR_SW_BINDING_REGWEN_REG_OFFSET,
320  0);
321 
322  // Write and lock (rw0c) the max key version.
323  mmio_region_write32_shadowed(keymgr->base_addr,
324  (ptrdiff_t)max_key_ver_reg_info.reg_offset,
325  params->max_key_version);
326  mmio_region_write32(keymgr->base_addr,
327  (ptrdiff_t)max_key_ver_reg_info.wen_reg_offset, 0);
328  } else if (params != NULL) {
329  return kDifBadArg;
330  }
331 
332  // Advance state.
333  start_operation(keymgr,
335  .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
336  .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_ADVANCE,
337  });
338 
339  return kDifOk;
340 }
341 
343  if (keymgr == NULL) {
344  return kDifBadArg;
345  }
346 
347  if (!is_ready(keymgr)) {
348  return kDifLocked;
349  }
350 
351  // Advance state.
352  start_operation(keymgr,
354  .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
355  .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_ADVANCE,
356  });
357 
358  return kDifOk;
359 }
360 
362  if (keymgr == NULL) {
363  return kDifBadArg;
364  }
365 
366  if (!is_ready(keymgr)) {
367  return kDifLocked;
368  }
369 
370  // Disable key manager.
371  start_operation(keymgr,
373  .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
374  .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_DISABLE,
375  });
376 
377  return kDifOk;
378 }
379 
381  const dif_keymgr_t *keymgr, dif_keymgr_status_codes_t *status_codes) {
382  if (keymgr == NULL || status_codes == NULL) {
383  return kDifBadArg;
384  }
385 
386  // Read and clear OP_STATUS register (rw1c).
387  uint32_t reg_op_status =
388  mmio_region_read32(keymgr->base_addr, KEYMGR_OP_STATUS_REG_OFFSET);
389 
390  bool is_idle = false;
391  bool has_error = false;
392  switch (reg_op_status) {
393  case KEYMGR_OP_STATUS_STATUS_VALUE_IDLE:
394  is_idle = true;
395  break;
396  case KEYMGR_OP_STATUS_STATUS_VALUE_DONE_SUCCESS:
397  is_idle = true;
398  mmio_region_write32(keymgr->base_addr, KEYMGR_OP_STATUS_REG_OFFSET,
399  reg_op_status);
400  break;
401  case KEYMGR_OP_STATUS_STATUS_VALUE_DONE_ERROR:
402  is_idle = true;
403  has_error = true;
404  mmio_region_write32(keymgr->base_addr, KEYMGR_OP_STATUS_REG_OFFSET,
405  reg_op_status);
406  break;
407  case KEYMGR_OP_STATUS_STATUS_VALUE_WIP:
408  break;
409  default:
410  return kDifError;
411  }
412 
413  // Bit 0 of `dif_keymgr_status_codes_t` indicates whether the key manager is
414  // idle or not.
415  *status_codes =
417 
418  if (has_error) {
419  // Read and clear ERR_CODE register (rw1c).
420  uint32_t reg_err_code =
421  mmio_region_read32(keymgr->base_addr, KEYMGR_ERR_CODE_REG_OFFSET);
422  mmio_region_write32(keymgr->base_addr, KEYMGR_ERR_CODE_REG_OFFSET,
423  reg_err_code);
424  // Error bits start from bit 1 in `dif_keymgr_status_codes_t`.
425  // Note: The mask is hardcoded since it is not auto generated yet.
426  const bitfield_field32_t kErrorBitfield = (bitfield_field32_t){
427  .mask = 0xF,
428  .index = 1,
429  };
430  if (reg_err_code > kErrorBitfield.mask || reg_err_code == 0) {
431  return kDifError;
432  }
434  *status_codes, kErrorBitfield, reg_err_code);
435  }
436 
437  return kDifOk;
438 }
439 
441  dif_keymgr_state_t *state) {
442  if (keymgr == NULL || state == NULL) {
443  return kDifBadArg;
444  }
445 
446  uint32_t reg_state =
447  mmio_region_read32(keymgr->base_addr, KEYMGR_WORKING_STATE_REG_OFFSET);
448 
449  switch (bitfield_field32_read(reg_state, KEYMGR_WORKING_STATE_STATE_FIELD)) {
450  case KEYMGR_WORKING_STATE_STATE_VALUE_RESET:
451  *state = kDifKeymgrStateReset;
452  return kDifOk;
453  case KEYMGR_WORKING_STATE_STATE_VALUE_INIT:
455  return kDifOk;
456  case KEYMGR_WORKING_STATE_STATE_VALUE_CREATOR_ROOT_KEY:
458  return kDifOk;
459  case KEYMGR_WORKING_STATE_STATE_VALUE_OWNER_INTERMEDIATE_KEY:
461  return kDifOk;
462  case KEYMGR_WORKING_STATE_STATE_VALUE_OWNER_KEY:
464  return kDifOk;
465  case KEYMGR_WORKING_STATE_STATE_VALUE_DISABLED:
466  *state = kDifKeymgrStateDisabled;
467  return kDifOk;
468  case KEYMGR_WORKING_STATE_STATE_VALUE_INVALID:
469  *state = kDifKeymgrStateInvalid;
470  return kDifOk;
471  default:
472  return kDifError;
473  }
474 }
475 
477  const dif_keymgr_t *keymgr, dif_keymgr_identity_seed_params_t params) {
478  if (keymgr == NULL) {
479  return kDifBadArg;
480  }
481 
482  if (!is_ready(keymgr)) {
483  return kDifLocked;
484  }
485 
486  start_operation(keymgr,
488  .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
489  .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_ID,
490  .cdi_type = params.cdi_type});
491 
492  return kDifOk;
493 }
494 
496  const dif_keymgr_t *keymgr, dif_keymgr_versioned_key_params_t params) {
497  if (keymgr == NULL) {
498  return kDifBadArg;
499  }
500 
501  start_operation_params_t hw_op_params;
502  switch (params.dest) {
504  hw_op_params = (start_operation_params_t){
505  .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
506  .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_SW_OUTPUT,
507  .cdi_type = params.cdi_type};
508  break;
510  hw_op_params = (start_operation_params_t){
511  .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_AES,
512  .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_HW_OUTPUT,
513  .cdi_type = params.cdi_type};
514  break;
516  hw_op_params = (start_operation_params_t){
517  .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_KMAC,
518  .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_HW_OUTPUT,
519  .cdi_type = params.cdi_type};
520  break;
522  hw_op_params = (start_operation_params_t){
523  .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_OTBN,
524  .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_HW_OUTPUT,
525  .cdi_type = params.cdi_type};
526  break;
527  default:
528  return kDifBadArg;
529  }
530 
531  if (!is_ready(keymgr)) {
532  return kDifLocked;
533  }
534 
535  // Set salt and version
536  mmio_region_memcpy_to_mmio32(keymgr->base_addr, KEYMGR_SALT_0_REG_OFFSET,
537  params.salt, sizeof(params.salt));
538  mmio_region_write32(keymgr->base_addr, KEYMGR_KEY_VERSION_REG_OFFSET,
539  params.version);
540 
541  start_operation(keymgr, hw_op_params);
542 
543  return kDifOk;
544 }
545 
547  dif_toggle_t state) {
548  if (keymgr == NULL || !dif_is_valid_toggle(state)) {
549  return kDifBadArg;
550  }
551 
553  ? kDifKeyMgrSideLoadClearAll
554  : kDifKeyMgrSideLoadClearNone;
555 
556  mmio_region_write32(keymgr->base_addr, KEYMGR_SIDELOAD_CLEAR_REG_OFFSET, val);
557 
558  return kDifOk;
559 }
560 
562  dif_toggle_t *state) {
563  if (keymgr == NULL || state == NULL) {
564  return kDifBadArg;
565  }
566 
567  uint32_t reg_val =
568  mmio_region_read32(keymgr->base_addr, KEYMGR_SIDELOAD_CLEAR_REG_OFFSET);
569  *state = dif_bool_to_toggle(reg_val == kDifKeyMgrSideLoadClearAll);
570 
571  return kDifOk;
572 }
573 
575  dif_keymgr_output_t *output) {
576  if (keymgr == NULL || output == NULL) {
577  return kDifBadArg;
578  }
579 
581  KEYMGR_SW_SHARE0_OUTPUT_0_REG_OFFSET,
582  output->value[0], sizeof(output->value[0]));
584  KEYMGR_SW_SHARE1_OUTPUT_0_REG_OFFSET,
585  output->value[1], sizeof(output->value[1]));
586 
587  return kDifOk;
588 }
589 
591  dif_keymgr_binding_value_t *output) {
592  if (keymgr == NULL || output == NULL) {
593  return kDifBadArg;
594  }
595 
597  KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET,
598  output->sealing, sizeof(output->sealing));
599 
601  keymgr->base_addr, KEYMGR_ATTEST_SW_BINDING_0_REG_OFFSET,
602  output->attestation, sizeof(output->attestation));
603 
604  return kDifOk;
605 }
606 
608  const dif_keymgr_t *keymgr, dif_keymgr_max_key_version_t *versions) {
609  if (keymgr == NULL || versions == NULL) {
610  return kDifBadArg;
611  }
612 
613  versions->creator_max_key_version = mmio_region_read32(
614  keymgr->base_addr, KEYMGR_MAX_CREATOR_KEY_VER_SHADOWED_REG_OFFSET);
615  versions->owner_int_max_key_version = mmio_region_read32(
616  keymgr->base_addr, KEYMGR_MAX_OWNER_INT_KEY_VER_SHADOWED_REG_OFFSET);
617  versions->owner_max_key_version = mmio_region_read32(
618  keymgr->base_addr, KEYMGR_MAX_OWNER_KEY_VER_SHADOWED_REG_OFFSET);
619 
620  return kDifOk;
621 }