Software APIs
dif_keymgr.h
Go to the documentation of this file.
1 // Copyright lowRISC contributors.
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 
18 
19 #ifdef __cplusplus
20 extern "C" {
21 #endif // __cplusplus
22 
23 /**
24  * Enumeration for enabling/disabling various functionality.
25  */
26 typedef enum dif_keymgr_toggle {
27  /**
28  * Enabled state.
29  */
31  /**
32  * Disabled state.
33  */
36 
37 /**
38  * Hardware instantiation parameters for key manager.
39  *
40  * This struct describes information about the underlying hardware that is
41  * not determined until the hardware design is used as part of a top-level
42  * design.
43  */
44 typedef struct dif_keymgr_params {
45  /**
46  * Base address of key manager registers.
47  */
50 
51 /**
52  * Runtime configuration for key manager.
53  *
54  * This struct describes runtime information for one-time configuration of the
55  * hardware.
56  */
57 typedef struct dif_keymgr_config {
58  /**
59  * Number of key manager cycles before the entropy is reseeded.
60  *
61  * Key manager uses random values generated by the entropy source for
62  * initializing its state and clearing sideload keys. This value determines
63  * the frequency at which this random value is updated.
64  */
67 
68 /**
69  * A handle to a key manager.
70  *
71  * This type should be treated as opaque by users.
72  */
73 typedef struct dif_keymgr {
74  /**
75  * Hardware instantiation parameters.
76  */
78 } dif_keymgr_t;
79 
80 /**
81  * Result of a key manager operation.
82  */
83 typedef enum dif_keymgr_result {
84  /**
85  * The call succeeded.
86  */
88  /**
89  * A non-specific error occurred and the hardware is in an invalid or
90  * irrecoverable state.
91  */
93  /**
94  * The caller supplied invalid arguments but the call did not cause any
95  * side-effects and the hardware is in a valid and recoverable state.
96  */
99 
100 /**
101  * Result of a key manager operation that writes to lockable registers.
102  */
104  /**
105  * The call succeeded.
106  */
108  /**
109  * A non-specific error occurred and the hardware is in an invalid or
110  * irrecoverable state.
111  */
113  /**
114  * The caller supplied invalid arguments but the call did not cause any
115  * side-effects and the hardware is in a valid and recoverable state.
116  */
118  /**
119  * The register that needs to be written to is locked.
120  */
123 
124 /**
125  * Key manager interrupts.
126  */
127 typedef enum dif_keymgr_irq {
128  /**
129  * Operation was completed.
130  *
131  * This interrupt is triggered regardless of the outcome of the operation.
132  * Clients can use `dif_keymgr_get_status_codes()` to determine whether a key
133  * manager operation was successful or not.
134  */
136  /**
137  * \internal Last key manager interrupt.
138  */
139  kDifKeymgrIrqLast = kDifKeymgrIrqDone,
141 
142 /**
143  * A snapshot of the enablement state of key manager interrupts.
144  *
145  * This is an opaque type, to be used with the `dif_keymgr_irq_disable_all()`
146  * and `dif_keymgr_irq_restore_all()` functions.
147  */
148 typedef uint32_t dif_keymgr_irq_snapshot_t;
149 
150 /**
151  * Key manager alerts.
152  *
153  * Key manager generates alerts when it encounters a hardware or software
154  * error. Clients can use `dif_keymgr_get_status_codes()` to determine the type
155  * of error that occurred.
156  */
157 typedef enum dif_keymgr_alert {
158  /**
159  * A hardware error occurred.
160  *
161  * This alert is triggered when the hardware encounters an error condition
162  * that cannot be caused by the software, e.g. invalid KMAC commands, states,
163  * or outputs.
164  */
166  /**
167  * A software error occurred.
168  *
169  * This alert is triggered when the software attempts to start an invalid
170  * operation, e.g. attempting to generate keys when the key manager is at
171  * Initialized state, or use invalid inputs, e.g. a key with a forbidden
172  * version.
173  */
175 
176  /**
177  * \internal Last key manager alert.
178  */
179  kDifKeymgrAlertLast = kDifKeymgrAlertSoftware,
181 
182 /**
183  * Key manager states.
184  *
185  * Key manager has seven states that control its operation. During secure boot,
186  * key manager transitions between these states sequentially and these
187  * transitions are irreversible until a power cycle.
188  *
189  * The secret value of key manager changes at each state transition in a
190  * well-defined manner, thus its meaning is tied to the current state of key
191  * manager.
192  *
193  * The functionality of key manager is directly tied to the life cycle
194  * controller peripheral and it is explicitly disabled during specific life
195  * cycle stages. If key manager has not been initialized, it cannot be
196  * initialized until it is enabled by life cycle controller. If key manager is
197  * disabled by life cycle controller while it is in an operational state, it
198  * immediately wipes its contents and transitions to Disabled state.
199  */
200 typedef enum dif_keymgr_state {
201  /**
202  * Reset state.
203  *
204  * This is the initial state of key manager after PoR. At this state, the
205  * secret value of key manager is non-deterministic, i.e. some value based on
206  * the physical characteristics of the device and environment conditions.
207  */
209  /**
210  * Initialized state.
211  *
212  * Secret value of key manager is initialized with random values generated by
213  * the entropy source. This is not an operational state and the key manager
214  * state must be advanced one more time before keys or identity seeds can be
215  * generated.
216  */
218  /**
219  * CreatorRootKey state.
220  *
221  * This is the first operational state of key manager. At this state, key
222  * manager can generate a versioned creator key or a creator identity seed
223  * that can be used to generate a creator identity using an asymmetric KDF.
224  */
226  /**
227  * OwnerIntermediateKey state.
228  *
229  * This is the second operational state of key manager. At this state, key
230  * manager can generate a versioned intermediate owner key or an intermediate
231  * owner identity seed that can be used to generate an intermediate owner
232  * identity using an asymmetric KDF.
233  */
235  /**
236  * OwnerRootKey state.
237  *
238  * This is the last operational state of key manager. At this state, key
239  * manager can generate a versioned owner key or an owner identity seed that
240  * can be used to generate an owner identity using an asymmetric KDF.
241  */
243  /**
244  * Disabled state.
245  *
246  * This is a terminal state where key manager is no longer operational. At
247  * this state, the secret value of key manager is a random value.
248  */
250  /**
251  * Invalid state.
252  *
253  * Keymgr is in an invalid state and must be reset.
254  */
257 
258 /**
259  * Creates a new handle for key manager.
260  *
261  * This function does not actuate the hardware and must be called to initialize
262  * the handle that must be passed to other functions in this library in each
263  * boot stage. A typical usage of this library during different secure boot
264  * stages is as follows:
265  *
266  * - In Mask ROM:
267  * - Create a new handle: `dif_keymgr_init()`.
268  * - Configure hardware: `dif_keymgr_configure()`.
269  * - Initialize state: `dif_keymgr_advance_state()`,
270  * `dif_keymgr_get_status_codes()`, `dif_keymgr_get_state()`.
271  * - Advance state: `dif_keymgr_advance_state()`,
272  * `dif_keymgr_get_status_codes()`, `dif_keymgr_get_state()`.
273  * - In subsequent boot stages, i.e. ROM_EXT, BL0, kernel:
274  * - Create a new handle: `dif_keymgr_init()`.
275  * - Generate keys and/or identity seeds:
276  * `dif_keymgr_generate_versioned_key()`,
277  * `dif_keymgr_generate_identity_seed()`, `dif_keymgr_get_status_codes()`.
278  * - Read output (if applicable): `dif_keymgr_read_output()`.
279  * - Advance state: `dif_keymgr_advance_state()`,
280  * `dif_keymgr_get_status_codes()`, `dif_keymgr_get_state()`.
281  *
282  * @param params Hardware instantiation parameters.
283  * @param[out] keymgr Out-param for the initialized handle.
284  * @return The result of the operation.
285  */
288  dif_keymgr_t *keymgr);
289 
290 /**
291  * Configures key manager with runtime information.
292  *
293  * This function should need to be called once for the lifetime of `keymgr`.
294  *
295  * @param keymgr A key manager handle.
296  * @param config Runtime configuration parameters.
297  * @return The result of the operation.
298  */
301  dif_keymgr_config_t config);
302 
303 /**
304  * Parameters for a key manager state.
305  */
306 typedef struct dif_keymgr_state_params {
307  /**
308  * This value is used by key manager to derive secret values and can be either
309  * a value that represents the contents of a boot stage, e.g. a (truncated)
310  * hash, or a tag.
311  *
312  * If it is a hash, changes in a boot stage will change the secret value, and
313  * consequently the versioned keys and identity seeds generated at subsequent
314  * boot stages. If it is a tag, those secret values, versioned keys, and
315  * identity seeds will be preserved across updates of the boot stage as long
316  * as the tag remains the same.
317  */
318  uint32_t binding_value[8];
319 
320  /**
321  * Maximum allowed version for keys generated at a state.
322  */
323  uint32_t max_key_version;
325 
326 /**
327  * Advances key manager state.
328  *
329  * This function instructs key manager to transition to the next state, i.e.
330  * Reset -> Initialized -> CreatorRootKey -> OwnerIntermediateKey ->
331  * OwnerRootKey -> Disabled. Once a state transition starts, key manager locks
332  * the control register until the transition is complete. State transitions are
333  * irreversible until a power cycle.
334  *
335  * The entropy source must be initialized before this function is called. After
336  * PoR, key manager is in Reset state with a non-deterministic secret value. The
337  * first call to this function after PoR causes key manager to initialize its
338  * secret value using the random values generated by the entropy source and
339  * transition to Initialized state.
340  *
341  * `params` is required when the next state is an operational state,
342  * i.e. `CreatorRootKey`, `OwnerIntermediateKey`, or `OwnerRootKey`. It must be
343  * `NULL` for all other cases.
344  *
345  * This is an asynchronous function because key manager state transitions
346  * involve KMAC operations that can take some time to complete. Clients must
347  * check the status of key manager using `dif_keymgr_get_status_codes()` before
348  * calling other functions in this library.
349  *
350  * @param keymgr A key manager handle.
351  * @param params The binding and max key version value for the next state.
352  * @return The result of the operation.
353  */
355 dif_keymgr_lockable_result_t dif_keymgr_advance_state(
356  const dif_keymgr_t *keymgr, const dif_keymgr_state_params_t *params);
357 
358 /**
359  * Disables key manager.
360  *
361  * This function disables key manager until the next power cycle by making it
362  * transition to Disabled state. Disabled state is a terminal state where key
363  * manager is no longer operational and its secret value is a random value.
364  *
365  * @param keymgr A key manager handle.
366  * @return The result of the operation.
367  */
369 dif_keymgr_lockable_result_t dif_keymgr_disable(const dif_keymgr_t *keymgr);
370 
371 /**
372  * Status code bit flags.
373  *
374  * See also: `dif_keymgr_status_codes_t`.
375  */
377  /**
378  * Key manager is idle.
379  */
381  /**
382  * Software invoked an invalid operation.
383  */
385  /**
386  * Key manager issued an invalid command to KMAC interface.
387  */
389  /**
390  * Key manager issued invalid data to KMAC interface.
391  */
393  /**
394  * KMAC returned an invalid output.
395  */
398 
399 /**
400  * A bit vector of status codes.
401  *
402  * The following snippet can be used to check if key manager is idle:
403  *
404  * bool is_idle = (status_codes & kDifKeymgrStatusCodeIdle);
405  *
406  * The following snippet can be used to check if key manager is idle and
407  * error-free:
408  *
409  * bool is_idle_and_ok = (status_codes == kDifKeymgrStatusCodeIdle);
410  *
411  * See also: `dif_keymgr_status_code_t`.
412  */
414 
415 /**
416  * Gets the operational status of key manager.
417  *
418  * This function also clears OP_STATUS and ERR_CODE registers after reading
419  * them.
420  *
421  * @param keymgr A key manager handle.
422  * @param[out] status_codes Out-param for key manager status codes.
423  * @return The result of the operation.
424  */
427  const dif_keymgr_t *keymgr, dif_keymgr_status_codes_t *status_codes);
428 
429 /**
430  * Gets the current state of key manager.
431  *
432  * @param keymgr A key manager handle.
433  * @param[out] state Out-param for current key manager state.
434  * @return The result of the operation.
435  */
438  dif_keymgr_state_t *state);
439 
440 /**
441  * Generates an identity seed.
442  *
443  * This function requests key manager to generate an identity seed using its
444  * current secret value. Clients must first verify that the operation was
445  * successful using `dif_keymgr_get_status_codes()` before reading the generated
446  * identity seed using `dif_keymgr_read_output()`.
447  *
448  * The generated seed can be used to generate an identity using an asymmetric
449  * KDF.
450  *
451  * @param keymgr A key manager handle.
452  * @return The result of the operation.
453  */
455 dif_keymgr_lockable_result_t dif_keymgr_generate_identity_seed(
456  const dif_keymgr_t *keymgr);
457 
458 /**
459  * Destination of a versioned key generation operation.
460  *
461  * Key manager can make the output of a versioned key generation operation
462  * available to software or sideload it directly to a peripheral device. When
463  * the destination is a peripheral device, the output of the operation is not
464  * visible to software and a different derivation constant is used for each
465  * peripheral.
466  */
468  /**
469  * Store the generated versioned key in software visible registers.
470  *
471  * The generated versioned key can be read by calling
472  * `dif_keymgr_read_output()` after verifying that the operation was
473  * successful using `dif_keymgr_get_status_codes()`.
474  */
476  /**
477  * Sideload the generated versioned key to AES device.
478  */
480  /**
481  * Sideload the generated versioned key to HMAC device.
482  */
484  /**
485  * Sideload the generated versioned key to KMAC device.
486  */
488  /**
489  * \internal Last key destination.
490  */
491  kDifKeymgrVersionedKeyDestLast = kDifKeymgrVersionedKeyDestKmac,
493 
494 /**
495  * Parameters for generating a versioned key.
496  */
498  /**
499  * Destination of the generated versioned key.
500  *
501  * See also: `dif_keymgr_versioned_key_dest_t`.
502  */
503  dif_keymgr_versioned_key_dest_t dest;
504  /**
505  * Salt value to use for key generation.
506  */
507  uint32_t salt[8];
508  /**
509  * Version value to use for key generation.
510  */
511  uint32_t version;
513 
514 /**
515  * Generates a versioned key.
516  *
517  * This function requests key manager to generate a versioned key using its
518  * current secret value and the provided parameters. The generated key can be
519  * sideloaded directly to a peripheral device or made visible to software using
520  * `params.dest`. If the destination is software, clients must first verify that
521  * the operation was successful using `dif_keymgr_get_status_codes()` before
522  * reading the generated key using `dif_keymgr_read_output()`.
523  *
524  * @param keymgr A key manager handle.
525  * @param params Key generation parameters.
526  * @return The result of the operation.
527  */
529 dif_keymgr_lockable_result_t dif_keymgr_generate_versioned_key(
530  const dif_keymgr_t *keymgr, dif_keymgr_versioned_key_params_t params);
531 
532 /**
533  * Starts or stops clearing of sideload keys.
534  *
535  * When a key is generated to be sideloaded to a hardware peripheral, key
536  * manager stores it in a set of storage registers. Calling this function with
537  * `state` set to `kDifKeymgrToggleEnabled` causes key manager to clear sideload
538  * keys continously using random values from the entropty source. Callers must
539  * disable clearing of sideload keys to resume normal sideload operation.
540  *
541  * @param keymgr A key manager handle.
542  * @param state The new toggle state for sideload clear.
543  * @return The result of the operation.
544  */
547  const dif_keymgr_t *keymgr, dif_keymgr_toggle_t state);
548 
549 /**
550  * Checks whether clearing of sideload keys is enabled or not.
551  *
552  * @param keymgr A key manager handle.
553  * @param[out] Out-param for the current toggle state of sideload clear.
554  * @return The result of the operation.
555  */
558  const dif_keymgr_t *keymgr, dif_keymgr_toggle_t *state);
559 
560 /**
561  * Output of a key manager operation.
562  *
563  * Key manager outputs are in two-shares.
564  */
565 typedef struct dif_keymgr_output {
566  uint32_t value[2][8];
568 
569 /**
570  * Reads the output of the last key manager operation.
571  *
572  * After starting a key manager operation, clients must verify that the
573  * operation was successful using `dif_keymgr_get_status_codes()` before calling
574  * this function.
575  *
576  * When key manager is used for versioned key generation, the output of this
577  * function is valid only if the destination of the operation was
578  * `kDifKeymgrVersionedKeyDestSw`.
579  *
580  * See also: `dif_keymgr_output_t`.
581  *
582  * @param keymgr A key manager handle.
583  * @param[out] output Out-param for key manager output.
584  * @return The result of the operation.
585  */
588  dif_keymgr_output_t *output);
589 
590 /**
591  * Forces a particular alert as if hardware had asserted it.
592  *
593  * @param keymgr A key manager handle.
594  * @param alert An alert type.
595  * @return The result of the operation.
596  */
599  dif_keymgr_alert_t alert);
600 /**
601  * Returns whether a particular interrupt is currently pending.
602  *
603  * @param keymgr A key manager handle.
604  * @param irq An interrupt type.
605  * @param[out] is_pending Out-param for whether the interrupt is pending.
606  * @return The result of the operation.
607  */
610  dif_keymgr_irq_t irq,
611  bool *is_pending);
612 
613 /**
614  * Acknowledges a particular interrupt, indicating to the hardware that it has
615  * been successfully serviced.
616  *
617  * @param keymgr A key manager handle.
618  * @param irq An interrupt type.
619  * @return The result of the operation.
620  */
623  dif_keymgr_irq_t irq);
624 
625 /**
626  * Checks whether a particular interrupt is currently enabled or disabled.
627  *
628  * @param keymgr A key manager handle.
629  * @param irq An interrupt type.
630  * @param[out] state Out-param for toggle state of the interrupt.
631  * @return The result of the operation.
632  */
635  dif_keymgr_irq_t irq,
636  dif_keymgr_toggle_t *state);
637 
638 /**
639  * Sets whether a particular interrupt is currently enabled or disabled.
640  *
641  * @param keymgr A key manager handle.
642  * @param irq An interrupt type.
643  * @param state The new toggle state for the interrupt.
644  * @return The result of the operation.
645  */
648  dif_keymgr_irq_t irq,
649  dif_keymgr_toggle_t state);
650 
651 /**
652  * Forces a particular interrupt, causing it to be serviced as if hardware had
653  * asserted it.
654  *
655  * @param keymgr A key manager handle.
656  * @param irq An interrupt type.
657  * @return The result of the operation.
658  */
661  dif_keymgr_irq_t irq);
662 
663 /**
664  * Disables all interrupts, optionally snapshotting all toggle state for later
665  * restoration.
666  *
667  * @param keymgr A key manager handle.
668  * @param[out] snapshot Out-param for the snapshot; may be `NULL`.
669  * @return The result of the operation.
670  */
673  const dif_keymgr_t *keymgr, dif_keymgr_irq_snapshot_t *snapshot);
674 
675 /**
676  * Restores interrupts from the given snapshot.
677  *
678  * This function can be used with `dif_keymgr_irq_disable_all()` to temporary
679  * interrupt save-and-restore.
680  *
681  * @param keymgr A key manager handle.
682  * @param snapshot A snapshot to restore from.
683  * @return The result of the operation.
684  */
687  const dif_keymgr_t *keymgr, const dif_keymgr_irq_snapshot_t *snapshot);
688 
689 #ifdef __cplusplus
690 } // extern "C"
691 #endif // __cplusplus
692 
693 #endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_KEYMGR_H_