Software APIs
sw
device
lib
dif
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 "
sw/device/lib/dif/autogen/dif_keymgr_autogen.h
"
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
*/
50
typedef
enum
dif_keymgr_sideload_clr
{
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,
59
}
dif_keymgr_sideload_clr_t
;
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
*/
75
uint16_t
entropy_reseed_interval
;
76
}
dif_keymgr_config_t
;
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
*/
104
kDifKeymgrStateReset
,
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
*/
113
kDifKeymgrStateInitialized
,
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
*/
121
kDifKeymgrStateCreatorRootKey
,
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
*/
130
kDifKeymgrStateOwnerIntermediateKey
,
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
*/
138
kDifKeymgrStateOwnerRootKey
,
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
*/
145
kDifKeymgrStateDisabled
,
146
/**
147
* Invalid state.
148
*
149
* Keymgr is in an invalid state and must be reset.
150
*/
151
kDifKeymgrStateInvalid
,
152
}
dif_keymgr_state_t
;
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
*/
163
OT_WARN_UNUSED_RESULT
164
dif_result_t
dif_keymgr_configure
(
const
dif_keymgr_t
*keymgr,
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
;
188
}
dif_keymgr_state_params_t
;
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
*/
218
OT_WARN_UNUSED_RESULT
219
dif_result_t
dif_keymgr_advance_state
(
const
dif_keymgr_t
*keymgr,
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
*/
251
OT_WARN_UNUSED_RESULT
252
dif_result_t
dif_keymgr_advance_state_raw
(
const
dif_keymgr_t
*keymgr);
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
*/
264
OT_WARN_UNUSED_RESULT
265
dif_result_t
dif_keymgr_disable
(
const
dif_keymgr_t
*keymgr);
266
267
/**
268
* Status code bit flags.
269
*
270
* See also: `dif_keymgr_status_codes_t`.
271
*/
272
typedef
enum
dif_keymgr_status_code
{
273
/**
274
* Key manager is idle.
275
*/
276
kDifKeymgrStatusCodeIdle
= 1 << 0,
277
/**
278
* Software invoked an invalid operation.
279
*/
280
kDifKeymgrStatusCodeInvalidOperation
= 1 << 1,
281
/**
282
* Key manager issued invalid data to KMAC interface.
283
*/
284
kDifKeymgrStatusCodeInvalidKmacInput
= 1 << 2,
285
/**
286
* Software performed an invalid shadow update.
287
*/
288
kDifKeymgrStatusCodeInvalidKmacOutput
= 1 << 3,
289
/**
290
* Key manager encountered invalid state
291
*/
292
kDifKeymgrStatusCodeInvalidState
= 1 << 4,
293
294
}
dif_keymgr_status_code_t
;
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
*/
310
typedef
uint8_t
dif_keymgr_status_codes_t
;
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
*/
322
OT_WARN_UNUSED_RESULT
323
dif_result_t
dif_keymgr_get_status_codes
(
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
*/
333
OT_WARN_UNUSED_RESULT
334
dif_result_t
dif_keymgr_get_state
(
const
dif_keymgr_t
*keymgr,
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
*/
351
OT_WARN_UNUSED_RESULT
352
dif_result_t
dif_keymgr_generate_identity_seed
(
const
dif_keymgr_t
*keymgr);
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
*/
363
typedef
enum
dif_keymgr_versioned_key_dest
{
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
*/
371
kDifKeymgrVersionedKeyDestSw
,
372
/**
373
* Sideload the generated versioned key to AES device.
374
*/
375
kDifKeymgrVersionedKeyDestAes
,
376
/**
377
* Sideload the generated versioned key to KMAC device.
378
*/
379
kDifKeymgrVersionedKeyDestKmac
,
380
/**
381
* Sideload the generated versioned key to Otbn device.
382
*/
383
kDifKeymgrVersionedKeyDestOtbn
,
384
/**
385
* \internal Last key destination.
386
*/
387
kDifKeymgrVersionedKeyDestLast =
kDifKeymgrVersionedKeyDestOtbn
,
388
}
dif_keymgr_versioned_key_dest_t
;
389
390
/**
391
* Parameters for generating a versioned key.
392
*/
393
typedef
struct
dif_keymgr_versioned_key_params
{
394
/**
395
* Destination of the generated versioned key.
396
*
397
* See also: `dif_keymgr_versioned_key_dest_t`.
398
*/
399
dif_keymgr_versioned_key_dest_t
dest
;
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
;
408
}
dif_keymgr_versioned_key_params_t
;
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
*/
424
OT_WARN_UNUSED_RESULT
425
dif_result_t
dif_keymgr_generate_versioned_key
(
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
*/
441
OT_WARN_UNUSED_RESULT
442
dif_result_t
dif_keymgr_sideload_clear_set_enabled
(
const
dif_keymgr_t
*keymgr,
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
*/
452
OT_WARN_UNUSED_RESULT
453
dif_result_t
dif_keymgr_sideload_clear_get_enabled
(
const
dif_keymgr_t
*keymgr,
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];
463
}
dif_keymgr_output_t
;
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
*/
482
OT_WARN_UNUSED_RESULT
483
dif_result_t
dif_keymgr_read_output
(
const
dif_keymgr_t
*keymgr,
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];
497
}
dif_keymgr_binding_value_t
;
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
*/
506
OT_WARN_UNUSED_RESULT
507
dif_result_t
dif_keymgr_read_binding
(
const
dif_keymgr_t
*keymgr,
508
dif_keymgr_binding_value_t
*output);
509
510
typedef
struct
dif_keymgr_max_key_version
{
511
/**
512
* Max creator key version.
513
*/
514
uint32_t
creator_max_key_version
;
515
/**
516
* Max owner intermediate key version.
517
*/
518
uint32_t
owner_int_max_key_version
;
519
/**
520
* Max owner key version.
521
*/
522
uint32_t
owner_max_key_version
;
523
}
dif_keymgr_max_key_version_t
;
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
*/
532
OT_WARN_UNUSED_RESULT
533
dif_result_t
dif_keymgr_read_max_key_version
(
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_
Return to
OpenTitan Documentation