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
16
#include "
sw/device/lib/base/macros.h
"
17
#include "
sw/device/lib/base/mmio.h
"
18
#include "
sw/device/lib/dif/dif_base.h
"
19
20
#include "
keymgr_regs.h
"
21
#include "
sw/device/lib/dif/autogen/dif_keymgr_autogen.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
*/
51
typedef
enum
dif_keymgr_sideload_clr
{
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,
60
}
dif_keymgr_sideload_clr_t
;
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
*/
76
uint16_t
entropy_reseed_interval
;
77
}
dif_keymgr_config_t
;
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
*/
105
kDifKeymgrStateReset
,
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
*/
114
kDifKeymgrStateInitialized
,
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
*/
122
kDifKeymgrStateCreatorRootKey
,
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
*/
131
kDifKeymgrStateOwnerIntermediateKey
,
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
*/
139
kDifKeymgrStateOwnerRootKey
,
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
*/
146
kDifKeymgrStateDisabled
,
147
/**
148
* Invalid state.
149
*
150
* Keymgr is in an invalid state and must be reset.
151
*/
152
kDifKeymgrStateInvalid
,
153
}
dif_keymgr_state_t
;
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
*/
178
kDifKeymgrAttestationCdi
=
179
KEYMGR_CONTROL_SHADOWED_CDI_SEL_VALUE_ATTESTATION_CDI
180
}
dif_keymgr_cdi_type_t
;
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
*/
191
OT_WARN_UNUSED_RESULT
192
dif_result_t
dif_keymgr_configure
(
const
dif_keymgr_t
*keymgr,
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
;
216
}
dif_keymgr_state_params_t
;
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
*/
246
OT_WARN_UNUSED_RESULT
247
dif_result_t
dif_keymgr_advance_state
(
const
dif_keymgr_t
*keymgr,
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
*/
279
OT_WARN_UNUSED_RESULT
280
dif_result_t
dif_keymgr_advance_state_raw
(
const
dif_keymgr_t
*keymgr);
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
*/
292
OT_WARN_UNUSED_RESULT
293
dif_result_t
dif_keymgr_disable
(
const
dif_keymgr_t
*keymgr);
294
295
/**
296
* Status code bit flags.
297
*
298
* See also: `dif_keymgr_status_codes_t`.
299
*/
300
typedef
enum
dif_keymgr_status_code
{
301
/**
302
* Key manager is idle.
303
*/
304
kDifKeymgrStatusCodeIdle
= 1 << 0,
305
/**
306
* Software invoked an invalid operation.
307
*/
308
kDifKeymgrStatusCodeInvalidOperation
= 1 << 1,
309
/**
310
* Key manager issued invalid data to KMAC interface.
311
*/
312
kDifKeymgrStatusCodeInvalidKmacInput
= 1 << 2,
313
/**
314
* Software performed an invalid shadow update.
315
*/
316
kDifKeymgrStatusCodeInvalidKmacOutput
= 1 << 3,
317
/**
318
* Key manager encountered invalid state
319
*/
320
kDifKeymgrStatusCodeInvalidState
= 1 << 4,
321
322
}
dif_keymgr_status_code_t
;
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
*/
338
typedef
uint8_t
dif_keymgr_status_codes_t
;
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
*/
350
OT_WARN_UNUSED_RESULT
351
dif_result_t
dif_keymgr_get_status_codes
(
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
*/
361
OT_WARN_UNUSED_RESULT
362
dif_result_t
dif_keymgr_get_state
(
const
dif_keymgr_t
*keymgr,
363
dif_keymgr_state_t
*state);
364
365
/**
366
* Parameters for generating an identity seed.
367
*/
368
typedef
struct
dif_keymgr_identity_seed_params
{
369
/**
370
* Compound Device Identifier type (sealing or attestation).
371
*/
372
dif_keymgr_cdi_type_t
cdi_type
;
373
}
dif_keymgr_identity_seed_params_t
;
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
*/
390
OT_WARN_UNUSED_RESULT
391
dif_result_t
dif_keymgr_generate_identity_seed
(
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
*/
403
typedef
enum
dif_keymgr_versioned_key_dest
{
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
*/
411
kDifKeymgrVersionedKeyDestSw
,
412
/**
413
* Sideload the generated versioned key to AES device.
414
*/
415
kDifKeymgrVersionedKeyDestAes
,
416
/**
417
* Sideload the generated versioned key to KMAC device.
418
*/
419
kDifKeymgrVersionedKeyDestKmac
,
420
/**
421
* Sideload the generated versioned key to Otbn device.
422
*/
423
kDifKeymgrVersionedKeyDestOtbn
,
424
/**
425
* \internal Last key destination.
426
*/
427
kDifKeymgrVersionedKeyDestLast =
kDifKeymgrVersionedKeyDestOtbn
,
428
}
dif_keymgr_versioned_key_dest_t
;
429
430
/**
431
* Parameters for generating a versioned key.
432
*/
433
typedef
struct
dif_keymgr_versioned_key_params
{
434
/**
435
* Destination of the generated versioned key.
436
*
437
* See also: `dif_keymgr_versioned_key_dest_t`.
438
*/
439
dif_keymgr_versioned_key_dest_t
dest
;
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
*/
451
dif_keymgr_cdi_type_t
cdi_type
;
452
}
dif_keymgr_versioned_key_params_t
;
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
*/
468
OT_WARN_UNUSED_RESULT
469
dif_result_t
dif_keymgr_generate_versioned_key
(
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
*/
485
OT_WARN_UNUSED_RESULT
486
dif_result_t
dif_keymgr_sideload_clear_set_enabled
(
const
dif_keymgr_t
*keymgr,
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
*/
496
OT_WARN_UNUSED_RESULT
497
dif_result_t
dif_keymgr_sideload_clear_get_enabled
(
const
dif_keymgr_t
*keymgr,
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];
507
}
dif_keymgr_output_t
;
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
*/
526
OT_WARN_UNUSED_RESULT
527
dif_result_t
dif_keymgr_read_output
(
const
dif_keymgr_t
*keymgr,
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];
541
}
dif_keymgr_binding_value_t
;
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
*/
550
OT_WARN_UNUSED_RESULT
551
dif_result_t
dif_keymgr_read_binding
(
const
dif_keymgr_t
*keymgr,
552
dif_keymgr_binding_value_t
*output);
553
554
typedef
struct
dif_keymgr_max_key_version
{
555
/**
556
* Max creator key version.
557
*/
558
uint32_t
creator_max_key_version
;
559
/**
560
* Max owner intermediate key version.
561
*/
562
uint32_t
owner_int_max_key_version
;
563
/**
564
* Max owner key version.
565
*/
566
uint32_t
owner_max_key_version
;
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
*/
576
OT_WARN_UNUSED_RESULT
577
dif_result_t
dif_keymgr_read_max_key_version
(
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_
sw
device
lib
dif
dif_keymgr.h
Return to
OpenTitan Documentation