forked from lowRISC/opentitan
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdif_keymgr_dpe.h
309 lines (275 loc) · 8.79 KB
/
dif_keymgr_dpe.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
#ifndef OPENTITAN_SW_DEVICE_LIB_DIF_DIF_KEYMGR_DPE_H_
#define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_KEYMGR_DPE_H_
/**
* @file
* @brief <a href="/hw/ip/keymgr_dpe/doc/">Key Manager DPE</a> Device Interface
* Functions
*/
#include <stdint.h>
#include "sw/device/lib/base/macros.h"
#include "sw/device/lib/base/mmio.h"
#include "sw/device/lib/dif/dif_base.h"
#include "sw/device/lib/dif/autogen/dif_keymgr_dpe_autogen.h"
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
/**
* SW-visible key manager DPE states.
*
* Key manager RTL has more than 4 finite state machine (FSM) states, but it
* simply truncates the reported state into four states given below. The reason
* behind this truncation is that FSM lingers on some states temporarily (i.e.
* few clock cycles) and the transition into the next state does not require
* further invocation.
*
* From SW point of view, key manager FSM transitions follow a sequence
* sequential manner and these transitions are irreversible until a power cycle.
*/
typedef enum dif_keymgr_dpe_state {
kDifKeymgrDpeStateReset = 0,
kDifKeymgrDpeStateAvailable = 1,
kDifKeymgrDpeStateDisabled = 2,
kDifKeymgrDpeStateInvalid = 3
} dif_keymgr_dpe_state_t;
/**
* Input parameters for advancing a DPE context/slot.
*/
typedef struct dif_keymgr_dpe_advance_params {
/**
* This value is used by key manager as input to DICE computation and can be
* either a value that represents the measurement of a boot stage or simply a
* tag from a manifest.
*/
uint32_t binding_value[8];
/**
* Maximum allowed version for keys to be generated at a state. This value is
* stored inside keymgr slot so that it can later be compared against the
* `key_version` input provided along with generation request.
*/
uint32_t max_key_version;
/**
* The source slot to be used as parent DPE context.
*/
uint32_t slot_src_sel;
/**
* The destination slot which recieves the derived child DPE context.
*/
uint32_t slot_dst_sel;
/**
* The slot policy bits for the derived child DPE context.
*/
uint32_t slot_policy;
} dif_keymgr_dpe_advance_params_t;
/**
* Key destination of a versioned key generation operation.
*
* Regardless of whether the generated key is SW or sideload key, HW uses a
* unique diversification constant for each cryptographic use case. In the case
* of sideload key, this enum value is also used to determine the target
* peripheral port to which the generated key is loaded.
*/
typedef enum dif_keymgr_dpe_key_dest {
/**
* Diversify the generated key for no HW IP (and don't sideload it).
*/
kDifKeymgrDpeKeyDestNone = 0,
/**
* Diversify the generated key for AES (and load it to AES peripheral port if
* sideload key).
*/
kDifKeymgrDpeKeyDestAes = 1,
/**
* Diversify the generated key for KMAC (and load it to KMAC peripheral port
* if sideload key).
*/
kDifKeymgrDpeKeyDestKmac = 2,
/**
* Diversify the generated key for OTBN (and load it to OTBN peripheral port
* if sideload key).
*/
kDifKeymgrDpeKeyDestOtbn = 3,
} dif_keymgr_dpe_key_dest_t;
/**
* Input parameters for advancing a DPE context/slot.
*/
typedef struct dif_keymgr_dpe_generate_params {
/**
* Destination for {AES, KMAC, OTBN}, which is used for diversification.
*/
dif_keymgr_dpe_key_dest_t key_dest;
/**
* Set to true, if this is a sideload key, otherwise set to false.
*/
bool sideload_key;
/**
* Salt value used as input for key generation (i.e. becomes part of the
* message payload sent to KMAC during computation).
*/
uint32_t salt[8];
/**
* The key version used for generating versioned key. This value should not be
* greater than the `max_key_version` value stored inside the source slot that
* is used to generate the key.
*/
uint32_t version;
/**
* The source slot from which the key is derived.
*/
uint32_t slot_src_sel;
} dif_keymgr_dpe_generate_params_t;
/**
* Input parameters for erasing a DPE context/slot.
*/
typedef struct dif_keymgr_dpe_erase_params {
/**
* Index for the slot to be erased.
*/
uint32_t slot_dst_sel;
} dif_keymgr_dpe_erase_params_t;
/**
* Useed to represent the output of SW generated key.
*/
typedef struct dif_keymgr_dpe_output {
uint32_t value[2][8];
} dif_keymgr_dpe_output_t;
/**
* Status code bit flags.
*
* See also: `dif_keymgr_dpe_status_codes_t`.
*/
typedef enum dif_keymgr_dpe_status_code {
/**
* Key manager is idle.
*/
kDifKeymgrDpeStatusCodeIdle = 1 << 0,
/**
* Software invoked an invalid operation.
*/
kDifKeymgrDpeStatusCodeInvalidOperation = 1 << 1,
/**
* Key manager issued invalid data to KMAC interface.
*/
kDifKeymgrDpeStatusCodeInvalidKmacInput = 1 << 2,
/**
* Key manager encountered invalid state.
*/
kDifKeymgrDpeStatusCodeInvalidState = 1 << 3,
} dif_keymgr_dpe_status_code_t;
/**
* Define mask for error fields of `dif_keymgr_dpe_status_code_t`.
*/
static const bitfield_field32_t kIdleBitfield = (bitfield_field32_t){
.mask = 0x1,
.index = 0,
};
/**
* Define mask for idle field of `dif_keymgr_dpe_status_code_t`.
*/
static const bitfield_field32_t kErrorBitfield = (bitfield_field32_t){
.mask = 0x7,
.index = 1,
};
/**
* A bit vector of status codes.
*
* The following snippet can be used to check if key manager is idle:
*
* `bool is_idle = (status_codes & kDifKeymgrDpeStatusCodeIdle);`
*
* The following snippet can be used to check if key manager is idle and
* error-free:
*
* `bool is_idle_and_ok = (status_codes == kDifKeymgrDpeStatusCodeIdle);`
*
* See also: `dif_keymgr_dpe_status_code_t`.
*/
typedef uint8_t dif_keymgr_dpe_status_codes_t;
/**
* Initializes the keymgr_pde block by performing an advance operation.
*
* The hardware does not have an explicit initialize command. Initialization is
* simple the first advance call without software binding, max version or
* policy registers set. Use this call before calling
* `dif_keymgr_dpe_advance_state()`.
*
* @param keymgr_dpe A key manager handle.
* @param slot_dst_sel Target slot used to latch the UDS key.
* @return The result of the operation.
*/
dif_result_t dif_keymgr_dpe_initialize(const dif_keymgr_dpe_t *keymgr_dpe,
uint32_t slot_dst_sel);
/**
* Advances a keymgr_dpe slot with given parameters.
*
* @param keymgr_dpe A key manager handle.
* @param params Struct to pass inputs consumed by HW during advance.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_keymgr_dpe_advance_state(
const dif_keymgr_dpe_t *keymgr_dpe,
const dif_keymgr_dpe_advance_params_t *params);
/**
* Erases a given keymgr_dpe slot.
*
* @param keymgr_dpe A key manager handle.
* @param params A struct that selects the slot to be erased.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_keymgr_dpe_erase_slot(
const dif_keymgr_dpe_t *keymgr_dpe,
const dif_keymgr_dpe_erase_params_t *params);
/**
* Generate a SW/HW key from a chosen keymgr_dpe slot.
*
* @param keymgr_dpe A key manager handle.
* @param params Struct to pass inputs consumed by HW generate operation.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_keymgr_dpe_generate(
const dif_keymgr_dpe_t *keymgr_dpe,
const dif_keymgr_dpe_generate_params_t *params);
/**
* Gets the operational status of keymgr_dpe.
*
* This function also clears OP_STATUS and ERR_CODE registers after reading
* them.
*
* @param keymgr_dpe A key manager handle.
* @param[out] status_codes Out-param for key manager status codes.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_keymgr_dpe_get_status_codes(
const dif_keymgr_dpe_t *keymgr_dpe,
dif_keymgr_dpe_status_codes_t *status_codes);
/**
* Gets the current state of key manager.
*
* @param keymgr_dpe A key manager handle.
* @param[out] state Out-param for current key manager state.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_keymgr_dpe_get_state(const dif_keymgr_dpe_t *keymgr_dpe,
uint32_t *state);
/**
* Read the value of SW generated key from its related CSR. It is the
* responsibility of the caller to check that key generation has completed.
*
* @param keymgr_dpe A key manager handle.
* @param[out] output The key value in two shares.
* @return The result of the operation.
*/
OT_WARN_UNUSED_RESULT
dif_result_t dif_keymgr_dpe_read_output(const dif_keymgr_dpe_t *keymgr_dpe,
dif_keymgr_dpe_output_t *output);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_KEYMGR_DPE_H_