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;
226 
227 /**
228  * Starts a key manager operation.
229  */
230 static void start_operation(const dif_keymgr_t *keymgr,
231  start_operation_params_t params) {
232  uint32_t reg_control = bitfield_field32_write(
233  0, KEYMGR_CONTROL_SHADOWED_DEST_SEL_FIELD, params.dest);
234  reg_control = bitfield_field32_write(
235  reg_control, KEYMGR_CONTROL_SHADOWED_OPERATION_FIELD, params.op);
236  mmio_region_write32_shadowed(keymgr->base_addr,
237  KEYMGR_CONTROL_SHADOWED_REG_OFFSET, reg_control);
238  mmio_region_write32(keymgr->base_addr, KEYMGR_START_REG_OFFSET,
239  1 << KEYMGR_START_EN_BIT);
240 }
241 
243  dif_keymgr_config_t config) {
244  if (keymgr == NULL) {
245  return kDifBadArg;
246  }
247 
248  uint32_t reg_val =
249  bitfield_field32_write(0, KEYMGR_RESEED_INTERVAL_SHADOWED_VAL_FIELD,
250  config.entropy_reseed_interval);
251  mmio_region_write32_shadowed(
252  keymgr->base_addr, KEYMGR_RESEED_INTERVAL_SHADOWED_REG_OFFSET, reg_val);
253 
254  return kDifOk;
255 }
256 
258  const dif_keymgr_state_params_t *params) {
259  if (keymgr == NULL) {
260  return kDifBadArg;
261  }
262 
263  if (!is_ready(keymgr)) {
264  return kDifLocked;
265  }
266 
267  // Get current state and determine if we need to set the max key version and
268  // sw binding value.
269  max_key_version_reg_info_t max_key_ver_reg_info;
270  uint32_t reg_working_state =
271  mmio_region_read32(keymgr->base_addr, KEYMGR_WORKING_STATE_REG_OFFSET);
272  if (!get_max_key_version_reg_info_for_next_state(
273  (bitfield_field32_read(reg_working_state,
274  KEYMGR_WORKING_STATE_STATE_FIELD)),
275  &max_key_ver_reg_info)) {
276  return kDifError;
277  }
278 
279  // Set the binding value and max key version if keymgr is going to
280  // transition to an operational state.
281  if (max_key_ver_reg_info.is_required) {
282  if (params == NULL) {
283  return kDifBadArg;
284  }
285 
286  // Check if SEALING_SW_BINDING_N registers are locked
287  uint32_t reg_sw_binding_wen = mmio_region_read32(
288  keymgr->base_addr, KEYMGR_SW_BINDING_REGWEN_REG_OFFSET);
289  if (!bitfield_bit32_read(reg_sw_binding_wen,
290  KEYMGR_SW_BINDING_REGWEN_EN_BIT)) {
291  return kDifLocked;
292  }
293 
294  // Check if MAX_*_KEY_VER register is locked.
295  uint32_t reg_max_key_ver_wen = mmio_region_read32(
296  keymgr->base_addr, (ptrdiff_t)max_key_ver_reg_info.wen_reg_offset);
297  if (!bitfield_bit32_read(reg_max_key_ver_wen,
298  max_key_ver_reg_info.wen_bit_index)) {
299  return kDifLocked;
300  }
301 
302  // Write and lock (rw0c) the software binding value. This register is
303  // unlocked by hardware upon a successful state transition.
305  keymgr->base_addr, KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET,
306  params->binding_value, sizeof(params->binding_value));
307  mmio_region_write32(keymgr->base_addr, KEYMGR_SW_BINDING_REGWEN_REG_OFFSET,
308  0);
309 
310  // Write and lock (rw0c) the max key version.
311  mmio_region_write32_shadowed(keymgr->base_addr,
312  (ptrdiff_t)max_key_ver_reg_info.reg_offset,
313  params->max_key_version);
314  mmio_region_write32(keymgr->base_addr,
315  (ptrdiff_t)max_key_ver_reg_info.wen_reg_offset, 0);
316  } else if (params != NULL) {
317  return kDifBadArg;
318  }
319 
320  // Advance state.
321  start_operation(keymgr,
323  .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
324  .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_ADVANCE,
325  });
326 
327  return kDifOk;
328 }
329 
331  if (keymgr == NULL) {
332  return kDifBadArg;
333  }
334 
335  if (!is_ready(keymgr)) {
336  return kDifLocked;
337  }
338 
339  // Advance state.
340  start_operation(keymgr,
342  .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
343  .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_ADVANCE,
344  });
345 
346  return kDifOk;
347 }
348 
350  if (keymgr == NULL) {
351  return kDifBadArg;
352  }
353 
354  if (!is_ready(keymgr)) {
355  return kDifLocked;
356  }
357 
358  // Disable key manager.
359  start_operation(keymgr,
361  .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
362  .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_DISABLE,
363  });
364 
365  return kDifOk;
366 }
367 
369  const dif_keymgr_t *keymgr, dif_keymgr_status_codes_t *status_codes) {
370  if (keymgr == NULL || status_codes == NULL) {
371  return kDifBadArg;
372  }
373 
374  // Read and clear OP_STATUS register (rw1c).
375  uint32_t reg_op_status =
376  mmio_region_read32(keymgr->base_addr, KEYMGR_OP_STATUS_REG_OFFSET);
377 
378  bool is_idle = false;
379  bool has_error = false;
380  switch (reg_op_status) {
381  case KEYMGR_OP_STATUS_STATUS_VALUE_IDLE:
382  is_idle = true;
383  break;
384  case KEYMGR_OP_STATUS_STATUS_VALUE_DONE_SUCCESS:
385  is_idle = true;
386  mmio_region_write32(keymgr->base_addr, KEYMGR_OP_STATUS_REG_OFFSET,
387  reg_op_status);
388  break;
389  case KEYMGR_OP_STATUS_STATUS_VALUE_DONE_ERROR:
390  is_idle = true;
391  has_error = true;
392  mmio_region_write32(keymgr->base_addr, KEYMGR_OP_STATUS_REG_OFFSET,
393  reg_op_status);
394  break;
395  case KEYMGR_OP_STATUS_STATUS_VALUE_WIP:
396  break;
397  default:
398  return kDifError;
399  }
400 
401  // Bit 0 of `dif_keymgr_status_codes_t` indicates whether the key manager is
402  // idle or not.
403  *status_codes =
405 
406  if (has_error) {
407  // Read and clear ERR_CODE register (rw1c).
408  uint32_t reg_err_code =
409  mmio_region_read32(keymgr->base_addr, KEYMGR_ERR_CODE_REG_OFFSET);
410  mmio_region_write32(keymgr->base_addr, KEYMGR_ERR_CODE_REG_OFFSET,
411  reg_err_code);
412  // Error bits start from bit 1 in `dif_keymgr_status_codes_t`.
413  // Note: The mask is hardcoded since it is not auto generated yet.
414  const bitfield_field32_t kErrorBitfield = (bitfield_field32_t){
415  .mask = 0xF,
416  .index = 1,
417  };
418  if (reg_err_code > kErrorBitfield.mask || reg_err_code == 0) {
419  return kDifError;
420  }
422  *status_codes, kErrorBitfield, reg_err_code);
423  }
424 
425  return kDifOk;
426 }
427 
429  dif_keymgr_state_t *state) {
430  if (keymgr == NULL || state == NULL) {
431  return kDifBadArg;
432  }
433 
434  uint32_t reg_state =
435  mmio_region_read32(keymgr->base_addr, KEYMGR_WORKING_STATE_REG_OFFSET);
436 
437  switch (bitfield_field32_read(reg_state, KEYMGR_WORKING_STATE_STATE_FIELD)) {
438  case KEYMGR_WORKING_STATE_STATE_VALUE_RESET:
439  *state = kDifKeymgrStateReset;
440  return kDifOk;
441  case KEYMGR_WORKING_STATE_STATE_VALUE_INIT:
443  return kDifOk;
444  case KEYMGR_WORKING_STATE_STATE_VALUE_CREATOR_ROOT_KEY:
446  return kDifOk;
447  case KEYMGR_WORKING_STATE_STATE_VALUE_OWNER_INTERMEDIATE_KEY:
449  return kDifOk;
450  case KEYMGR_WORKING_STATE_STATE_VALUE_OWNER_KEY:
452  return kDifOk;
453  case KEYMGR_WORKING_STATE_STATE_VALUE_DISABLED:
454  *state = kDifKeymgrStateDisabled;
455  return kDifOk;
456  case KEYMGR_WORKING_STATE_STATE_VALUE_INVALID:
457  *state = kDifKeymgrStateInvalid;
458  return kDifOk;
459  default:
460  return kDifError;
461  }
462 }
463 
465  if (keymgr == NULL) {
466  return kDifBadArg;
467  }
468 
469  if (!is_ready(keymgr)) {
470  return kDifLocked;
471  }
472 
473  start_operation(keymgr,
475  .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
476  .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_ID,
477  });
478 
479  return kDifOk;
480 }
481 
483  const dif_keymgr_t *keymgr, dif_keymgr_versioned_key_params_t params) {
484  if (keymgr == NULL) {
485  return kDifBadArg;
486  }
487 
488  start_operation_params_t hw_op_params;
489  switch (params.dest) {
491  hw_op_params = (start_operation_params_t){
492  .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_NONE,
493  .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_SW_OUTPUT,
494  };
495  break;
497  hw_op_params = (start_operation_params_t){
498  .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_AES,
499  .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_HW_OUTPUT,
500  };
501  break;
503  hw_op_params = (start_operation_params_t){
504  .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_KMAC,
505  .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_HW_OUTPUT,
506  };
507  break;
509  hw_op_params = (start_operation_params_t){
510  .dest = KEYMGR_CONTROL_SHADOWED_DEST_SEL_VALUE_OTBN,
511  .op = KEYMGR_CONTROL_SHADOWED_OPERATION_VALUE_GENERATE_HW_OUTPUT,
512  };
513  break;
514  default:
515  return kDifBadArg;
516  }
517 
518  if (!is_ready(keymgr)) {
519  return kDifLocked;
520  }
521 
522  // Set salt and version
523  mmio_region_memcpy_to_mmio32(keymgr->base_addr, KEYMGR_SALT_0_REG_OFFSET,
524  params.salt, sizeof(params.salt));
525  mmio_region_write32(keymgr->base_addr, KEYMGR_KEY_VERSION_REG_OFFSET,
526  params.version);
527 
528  start_operation(keymgr, hw_op_params);
529 
530  return kDifOk;
531 }
532 
534  dif_toggle_t state) {
535  if (keymgr == NULL || !dif_is_valid_toggle(state)) {
536  return kDifBadArg;
537  }
538 
540  ? kDifKeyMgrSideLoadClearAll
541  : kDifKeyMgrSideLoadClearNone;
542 
543  mmio_region_write32(keymgr->base_addr, KEYMGR_SIDELOAD_CLEAR_REG_OFFSET, val);
544 
545  return kDifOk;
546 }
547 
549  dif_toggle_t *state) {
550  if (keymgr == NULL || state == NULL) {
551  return kDifBadArg;
552  }
553 
554  uint32_t reg_val =
555  mmio_region_read32(keymgr->base_addr, KEYMGR_SIDELOAD_CLEAR_REG_OFFSET);
556  *state = dif_bool_to_toggle(reg_val == kDifKeyMgrSideLoadClearAll);
557 
558  return kDifOk;
559 }
560 
562  dif_keymgr_output_t *output) {
563  if (keymgr == NULL || output == NULL) {
564  return kDifBadArg;
565  }
566 
568  KEYMGR_SW_SHARE0_OUTPUT_0_REG_OFFSET,
569  output->value[0], sizeof(output->value[0]));
571  KEYMGR_SW_SHARE1_OUTPUT_0_REG_OFFSET,
572  output->value[1], sizeof(output->value[1]));
573 
574  return kDifOk;
575 }
576 
578  dif_keymgr_binding_value_t *output) {
579  if (keymgr == NULL || output == NULL) {
580  return kDifBadArg;
581  }
582 
584  KEYMGR_SEALING_SW_BINDING_0_REG_OFFSET,
585  output->sealing, sizeof(output->sealing));
586 
588  keymgr->base_addr, KEYMGR_ATTEST_SW_BINDING_0_REG_OFFSET,
589  output->attestation, sizeof(output->attestation));
590 
591  return kDifOk;
592 }
593 
595  const dif_keymgr_t *keymgr, dif_keymgr_max_key_version_t *versions) {
596  if (keymgr == NULL || versions == NULL) {
597  return kDifBadArg;
598  }
599 
600  versions->creator_max_key_version = mmio_region_read32(
601  keymgr->base_addr, KEYMGR_MAX_CREATOR_KEY_VER_SHADOWED_REG_OFFSET);
602  versions->owner_int_max_key_version = mmio_region_read32(
603  keymgr->base_addr, KEYMGR_MAX_OWNER_INT_KEY_VER_SHADOWED_REG_OFFSET);
604  versions->owner_max_key_version = mmio_region_read32(
605  keymgr->base_addr, KEYMGR_MAX_OWNER_KEY_VER_SHADOWED_REG_OFFSET);
606 
607  return kDifOk;
608 }