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
24extern "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 */
68typedef 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 */
97typedef 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 */
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 */
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 */
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 */
505typedef 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 */
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 */
567} dif_keymgr_max_key_version_t;
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_