Software APIs
dif_keymgr.h
Go to the documentation of this file.
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 #ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_KEYMGR_H_
6 #define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_KEYMGR_H_
7 
8 /**
9  * @file
10  * @brief <a href="/hw/ip/keymgr/doc/">Key Manager</a> Device Interface
11  * Functions
12  */
13 
14 #include <stdint.h>
15 
19 
20 #include "keymgr_regs.h"
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif // __cplusplus
26 
27 /**
28  * A typical usage of this library during different secure boot
29  * stages is as follows:
30  *
31  * - In ROM:
32  * - Create a new handle: `dif_keymgr_init()`.
33  * - Configure hardware: `dif_keymgr_configure()`.
34  * - Initialize state: `dif_keymgr_advance_state()`,
35  * `dif_keymgr_get_status_codes()`, `dif_keymgr_get_state()`.
36  * - Advance state: `dif_keymgr_advance_state()`,
37  * `dif_keymgr_get_status_codes()`, `dif_keymgr_get_state()`.
38  * - In subsequent boot stages, i.e. ROM_EXT, BL0, kernel:
39  * - Create a new handle: `dif_keymgr_init()`.
40  * - Generate keys and/or identity seeds:
41  * `dif_keymgr_generate_versioned_key()`,
42  * `dif_keymgr_generate_identity_seed()`, `dif_keymgr_get_status_codes()`.
43  * - Read output (if applicable): `dif_keymgr_read_output()`.
44  * - Advance state: `dif_keymgr_advance_state()`,
45  * `dif_keymgr_get_status_codes()`, `dif_keymgr_get_state()`.
46  */
47 
48 /**
49  * Enumeration for side load slot clearing.
50  */
52  kDifKeyMgrSideLoadClearNone = 0,
53  kDifKeyMgrSideLoadClearAes = 1,
54  kDifKeyMgrSideLoadClearKmac = 2,
55  kDifKeyMgrSideLoadClearOtbn = 3,
56  // Using different value than those enumerated above should clear all slots,
57  // so we can use the mask value of this field to denote ALL case. This was
58  // we can statically assert this value on the .c side of this DIF.
59  kDifKeyMgrSideLoadClearAll = 7,
61 
62 /**
63  * Runtime configuration for key manager.
64  *
65  * This struct describes runtime information for one-time configuration of the
66  * hardware.
67  */
68 typedef struct dif_keymgr_config {
69  /**
70  * Number of key manager cycles before the entropy is reseeded.
71  *
72  * Key manager uses random values generated by the entropy source for
73  * initializing its state and clearing sideload keys. This value determines
74  * the frequency at which this random value is updated.
75  */
78 
79 /**
80  * Key manager states.
81  *
82  * Key manager has seven states that control its operation. During secure boot,
83  * key manager transitions between these states sequentially and these
84  * transitions are irreversible until a power cycle.
85  *
86  * The secret value of key manager changes at each state transition in a
87  * well-defined manner, thus its meaning is tied to the current state of key
88  * manager.
89  *
90  * The functionality of key manager is directly tied to the life cycle
91  * controller peripheral and it is explicitly disabled during specific life
92  * cycle stages. If key manager has not been initialized, it cannot be
93  * initialized until it is enabled by life cycle controller. If key manager is
94  * disabled by life cycle controller while it is in an operational state, it
95  * immediately wipes its contents and transitions to Disabled state.
96  */
97 typedef enum dif_keymgr_state {
98  /**
99  * Reset state.
100  *
101  * This is the initial state of key manager after PoR. At this state, the
102  * secret value of key manager is non-deterministic, i.e. some value based on
103  * the physical characteristics of the device and environment conditions.
104  */
106  /**
107  * Initialized state.
108  *
109  * Secret value of key manager is initialized with random values generated by
110  * the entropy source. This is not an operational state and the key manager
111  * state must be advanced one more time before keys or identity seeds can be
112  * generated.
113  */
115  /**
116  * CreatorRootKey state.
117  *
118  * This is the first operational state of key manager. At this state, key
119  * manager can generate a versioned creator key or a creator identity seed
120  * that can be used to generate a creator identity using an asymmetric KDF.
121  */
123  /**
124  * OwnerIntermediateKey state.
125  *
126  * This is the second operational state of key manager. At this state, key
127  * manager can generate a versioned intermediate owner key or an intermediate
128  * owner identity seed that can be used to generate an intermediate owner
129  * identity using an asymmetric KDF.
130  */
132  /**
133  * OwnerRootKey state.
134  *
135  * This is the last operational state of key manager. At this state, key
136  * manager can generate a versioned owner key or an owner identity seed that
137  * can be used to generate an owner identity using an asymmetric KDF.
138  */
140  /**
141  * Disabled state.
142  *
143  * This is a terminal state where key manager is no longer operational. At
144  * this state, the secret value of key manager is a random value.
145  */
147  /**
148  * Invalid state.
149  *
150  * Keymgr is in an invalid state and must be reset.
151  */
154 
155 /**
156  * Compound Device Identifier type.
157  *
158  * The key manager supports the DICE open profile consisting of two Compound
159  * Device Identifiers (CDI):
160  *
161  * - Sealing
162  * - Attestation
163  *
164  * In every operational state of the key manager, it is possible to derive
165  * either sealing or attestation identifiers, software or hardware keys by
166  * setting the `CDI_SEL` bit in the `CONTROL_SHADOWED` register.
167  */
168 typedef enum dif_keymgr_cdi_type {
169  /**
170  * Sealing CDI.
171  *
172  * This is the default configuration, corresponding to an unset bit.
173  */
174  kDifKeymgrSealingCdi = KEYMGR_CONTROL_SHADOWED_CDI_SEL_VALUE_SEALING_CDI,
175  /**
176  * Attestation CDI.
177  */
179  KEYMGR_CONTROL_SHADOWED_CDI_SEL_VALUE_ATTESTATION_CDI
181 
182 /**
183  * Configures key manager with runtime information.
184  *
185  * This function should need to be called once for the lifetime of `keymgr`.
186  *
187  * @param keymgr A key manager handle.
188  * @param config Runtime configuration parameters.
189  * @return The result of the operation.
190  */
193  dif_keymgr_config_t config);
194 
195 /**
196  * Parameters for a key manager state.
197  */
198 typedef struct dif_keymgr_state_params {
199  /**
200  * This value is used by key manager to derive secret values and can be either
201  * a value that represents the contents of a boot stage, e.g. a (truncated)
202  * hash, or a tag.
203  *
204  * If it is a hash, changes in a boot stage will change the secret value, and
205  * consequently the versioned keys and identity seeds generated at subsequent
206  * boot stages. If it is a tag, those secret values, versioned keys, and
207  * identity seeds will be preserved across updates of the boot stage as long
208  * as the tag remains the same.
209  */
210  uint32_t binding_value[8];
211 
212  /**
213  * Maximum allowed version for keys generated at a state.
214  */
215  uint32_t max_key_version;
217 
218 /**
219  * Advances key manager state.
220  *
221  * This function instructs key manager to transition to the next state, i.e.
222  * Reset -> Initialized -> CreatorRootKey -> OwnerIntermediateKey ->
223  * OwnerRootKey -> Disabled. Once a state transition starts, key manager locks
224  * the control register until the transition is complete. State transitions are
225  * irreversible until a power cycle.
226  *
227  * The entropy source must be initialized before this function is called. After
228  * PoR, key manager is in Reset state with a non-deterministic secret value. The
229  * first call to this function after PoR causes key manager to initialize its
230  * secret value using the random values generated by the entropy source and
231  * transition to Initialized state.
232  *
233  * `params` is required when the next state is an operational state,
234  * i.e. `CreatorRootKey`, `OwnerIntermediateKey`, or `OwnerRootKey`. It must be
235  * `NULL` for all other cases.
236  *
237  * This is an asynchronous function because key manager state transitions
238  * involve KMAC operations that can take some time to complete. Clients must
239  * check the status of key manager using `dif_keymgr_get_status_codes()` before
240  * calling other functions in this library.
241  *
242  * @param keymgr A key manager handle.
243  * @param params The binding and max key version value for the next state.
244  * @return The result of the operation.
245  */
248  const dif_keymgr_state_params_t *params);
249 
250 /**
251  * Advances key manager state without setting any of the required inputs.
252  *
253  * This function instructs key manager to transition to the next state, i.e.
254  * Reset -> Initialized -> CreatorRootKey -> OwnerIntermediateKey ->
255  * OwnerRootKey -> Disabled. Once a state transition starts, key manager locks
256  * the control register until the transition is complete. State transitions are
257  * irreversible until a power cycle.
258  *
259  * This function does not have a `dif_keymgr_state_params_t` parameter since
260  * these inputs are expected to be set before this function is called, e.g. when
261  * the chip is using `rom` as opposed to `test_rom`. See
262  * `dif_keymgr_advance_state()` if you need to set the binding value and max key
263  * version before advancing the state.
264  *
265  * The entropy source must be initialized before this function is called. After
266  * PoR, key manager is in Reset state with a non-deterministic secret value. The
267  * first call to this function after PoR causes key manager to initialize its
268  * secret value using the random values generated by the entropy source and
269  * transition to Initialized state.
270  *
271  * This is an asynchronous function because key manager state transitions
272  * involve KMAC operations that can take some time to complete. Clients must
273  * check the status of key manager using `dif_keymgr_get_status_codes()` before
274  * calling other functions in this library.
275  *
276  * @param keymgr A key manager handle.
277  * @return The result of the operation.
278  */
281 
282 /**
283  * Disables key manager.
284  *
285  * This function disables key manager until the next power cycle by making it
286  * transition to Disabled state. Disabled state is a terminal state where key
287  * manager is no longer operational and its secret value is a random value.
288  *
289  * @param keymgr A key manager handle.
290  * @return The result of the operation.
291  */
294 
295 /**
296  * Status code bit flags.
297  *
298  * See also: `dif_keymgr_status_codes_t`.
299  */
301  /**
302  * Key manager is idle.
303  */
305  /**
306  * Software invoked an invalid operation.
307  */
309  /**
310  * Key manager issued invalid data to KMAC interface.
311  */
313  /**
314  * Software performed an invalid shadow update.
315  */
317  /**
318  * Key manager encountered invalid state
319  */
321 
323 
324 /**
325  * A bit vector of status codes.
326  *
327  * The following snippet can be used to check if key manager is idle:
328  *
329  * `bool is_idle = (status_codes & kDifKeymgrStatusCodeIdle);`
330  *
331  * The following snippet can be used to check if key manager is idle and
332  * error-free:
333  *
334  * `bool is_idle_and_ok = (status_codes == kDifKeymgrStatusCodeIdle);`
335  *
336  * See also: `dif_keymgr_status_code_t`.
337  */
339 
340 /**
341  * Gets the operational status of key manager.
342  *
343  * This function also clears OP_STATUS and ERR_CODE registers after reading
344  * them.
345  *
346  * @param keymgr A key manager handle.
347  * @param[out] status_codes Out-param for key manager status codes.
348  * @return The result of the operation.
349  */
352  const dif_keymgr_t *keymgr, dif_keymgr_status_codes_t *status_codes);
353 
354 /**
355  * Gets the current state of key manager.
356  *
357  * @param keymgr A key manager handle.
358  * @param[out] state Out-param for current key manager state.
359  * @return The result of the operation.
360  */
363  dif_keymgr_state_t *state);
364 
365 /**
366  * Parameters for generating an identity seed.
367  */
369  /**
370  * Compound Device Identifier type (sealing or attestation).
371  */
374 
375 /**
376  * Generates an identity seed.
377  *
378  * This function requests key manager to generate an identity seed using its
379  * current secret value. Clients must first verify that the operation was
380  * successful using `dif_keymgr_get_status_codes()` before reading the generated
381  * identity seed using `dif_keymgr_read_output()`.
382  *
383  * The generated seed can be used to generate an identity using an asymmetric
384  * KDF.
385  *
386  * @param keymgr A key manager handle.
387  * @param params Identity seed generation params.
388  * @return The result of the operation.
389  */
392  const dif_keymgr_t *keymgr, dif_keymgr_identity_seed_params_t params);
393 
394 /**
395  * Destination of a versioned key generation operation.
396  *
397  * Key manager can make the output of a versioned key generation operation
398  * available to software or sideload it directly to a peripheral device. When
399  * the destination is a peripheral device, the output of the operation is not
400  * visible to software and a different derivation constant is used for each
401  * peripheral.
402  */
404  /**
405  * Store the generated versioned key in software visible registers.
406  *
407  * The generated versioned key can be read by calling
408  * `dif_keymgr_read_output()` after verifying that the operation was
409  * successful using `dif_keymgr_get_status_codes()`.
410  */
412  /**
413  * Sideload the generated versioned key to AES device.
414  */
416  /**
417  * Sideload the generated versioned key to KMAC device.
418  */
420  /**
421  * Sideload the generated versioned key to Otbn device.
422  */
424  /**
425  * \internal Last key destination.
426  */
427  kDifKeymgrVersionedKeyDestLast = kDifKeymgrVersionedKeyDestOtbn,
429 
430 /**
431  * Parameters for generating a versioned key.
432  */
434  /**
435  * Destination of the generated versioned key.
436  *
437  * See also: `dif_keymgr_versioned_key_dest_t`.
438  */
440  /**
441  * Salt value to use for key generation.
442  */
443  uint32_t salt[8];
444  /**
445  * Version value to use for key generation.
446  */
447  uint32_t version;
448  /**
449  * Coumpund Device Identifier type (sealing or attestation).
450  */
453 
454 /**
455  * Generates a versioned key.
456  *
457  * This function requests key manager to generate a versioned key using its
458  * current secret value and the provided parameters. The generated key can be
459  * sideloaded directly to a peripheral device or made visible to software using
460  * `params.dest`. If the destination is software, clients must first verify that
461  * the operation was successful using `dif_keymgr_get_status_codes()` before
462  * reading the generated key using `dif_keymgr_read_output()`.
463  *
464  * @param keymgr A key manager handle.
465  * @param params Key generation parameters.
466  * @return The result of the operation.
467  */
470  const dif_keymgr_t *keymgr, dif_keymgr_versioned_key_params_t params);
471 
472 /**
473  * Starts or stops clearing of sideload keys.
474  *
475  * When a key is generated to be sideloaded to a hardware peripheral, key
476  * manager stores it in a set of storage registers. Calling this function with
477  * `state` set to `kDifKeymgrToggleEnabled` causes key manager to clear sideload
478  * keys continously using random values from the entropty source. Callers must
479  * disable clearing of sideload keys to resume normal sideload operation.
480  *
481  * @param keymgr A key manager handle.
482  * @param state The new toggle state for sideload clear.
483  * @return The result of the operation.
484  */
487  dif_toggle_t state);
488 
489 /**
490  * Checks whether clearing of sideload keys is enabled or not.
491  *
492  * @param keymgr A key manager handle.
493  * @param[out] Out-param for the current toggle state of sideload clear.
494  * @return The result of the operation.
495  */
498  dif_toggle_t *state);
499 
500 /**
501  * Output of a key manager operation.
502  *
503  * Key manager outputs are in two-shares.
504  */
505 typedef struct dif_keymgr_output {
506  uint32_t value[2][8];
508 
509 /**
510  * Reads the output of the last key manager operation.
511  *
512  * After starting a key manager operation, clients must verify that the
513  * operation was successful using `dif_keymgr_get_status_codes()` before calling
514  * this function.
515  *
516  * When key manager is used for versioned key generation, the output of this
517  * function is valid only if the destination of the operation was
518  * `kDifKeymgrVersionedKeyDestSw`.
519  *
520  * See also: `dif_keymgr_output_t`.
521  *
522  * @param keymgr A key manager handle.
523  * @param[out] output Out-param for key manager output.
524  * @return The result of the operation.
525  */
528  dif_keymgr_output_t *output);
529 /**
530  * Attestation and sealing binding value.
531  */
532 typedef struct dif_keymgr_binding_value {
533  /**
534  * Sealing binding value.
535  */
536  uint32_t sealing[8];
537  /**
538  * Attestation binding value.
539  */
540  uint32_t attestation[8];
542 
543 /**
544  * Reads both the attestation or the binding value set.
545  *
546  * @param keymgr A key manager handle.
547  * @param[out] output Value read.
548  * @return The result of the operation.
549  */
553 
555  /**
556  * Max creator key version.
557  */
559  /**
560  * Max owner intermediate key version.
561  */
563  /**
564  * Max owner key version.
565  */
568 
569 /**
570  * Reads the max key version of each stage.
571  *
572  * @param keymgr A key manager handle.
573  * @param version Struct with the max versions set.
574  * @return dif_result_t
575  */
578  const dif_keymgr_t *keymgr, dif_keymgr_max_key_version_t *versions);
579 #ifdef __cplusplus
580 } // extern "C"
581 #endif // __cplusplus
582 
583 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_KEYMGR_H_