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