Software APIs
keymgr_dpe_testutils.h
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_TESTING_KEYMGR_DPE_TESTUTILS_H_
6#define OPENTITAN_SW_DEVICE_LIB_TESTING_KEYMGR_DPE_TESTUTILS_H_
7
8// This #if define ... ensures backwards compatibility with darjeeling. Either
9// both tops will get their own testutils or this define guard can be
10// implemented at a more granular level (i.e. at function level).
11// TODO(#30919): Split the keymgr_dpe_testutil on a finer level.
12#if defined(OPENTITAN_IS_DARJEELING)
13
14#include "sw/device/lib/base/status.h"
16
17/**
18 * Locks OTP, restarts and initializes keymgr_dpe with UDS (a.k.a. the OTP
19 * root key).
20 *
21 * This procedure essentially gets the keymgr_dpe into the stage where it
22 * can be used for tests. An example is given below:
23 *
24 * ```c
25 * void test_main(void) {
26 * // The following sets up keymgr_dpe and asks it to latch UDS.
27 * dif_keymgr_dpe_t keymgr_dpe;
28 * keymgr_dpe_testutils_startup(&keymgr_dpe);
29 *
30 * // Remainder of test; optionally advance to CreatorRootKey state, generate
31 * // keys and identities.
32 * ...
33 * }
34 * ```
35 *
36 * @param[out] keymgr_dpe A key manager handle, may be uninitialized.
37 * @return The result of the operation.
38 */
40status_t keymgr_dpe_testutils_startup(dif_keymgr_dpe_t *keymgr_dpe,
41 uint32_t slot_dst_sel);
42
43/**
44 * Issues a keymgr_dpe advance operation and wait for it to complete.
45 *
46 * @param keymgr_dpe A key manager handle.
47 * @param params Inputs that are consumed by HW during advance operation.
48 * @return The result of the operation.
49 */
51status_t keymgr_dpe_testutils_advance_state(
52 const dif_keymgr_dpe_t *keymgr_dpe,
54
55/**
56 * Issues a keymgr_dpe key generation operation and wait for it to complete.
57 *
58 * @param keymgr_dpe A key manager handle.
59 * @param params Inputs that are consumed by HW during generate operation.
60 * @return The result of the operation.
61 */
63status_t keymgr_dpe_testutils_generate(
64 const dif_keymgr_dpe_t *keymgr_dpe,
67
68/**
69 * Erase a keymgr_dpe slot.
70 *
71 * @param keymgr_dpe A key manager handle.
72 * @param params A wrapper struct that contains the destination slot to be
73 * erased.
74 * @return The result of the operation.
75 */
77status_t keymgr_dpe_testutils_erase_slot(
78 const dif_keymgr_dpe_t *keymgr_dpe,
79 const dif_keymgr_dpe_erase_params_t *params);
80
81/**
82 * Checks if the current keymgr_dpe state matches the expected state
83 *
84 * @param keymgr_dpe A key manager handle.
85 * @param exp_state The expected key manager state.
86 * @return The result of the operation.
87 */
89status_t keymgr_dpe_testutils_check_state(
90 const dif_keymgr_dpe_t *keymgr_dpe, const dif_keymgr_dpe_state_t exp_state);
91
92/**
93 * Polling keymgr_dpe status until it becomes idle.
94 * Fail the test if the status code indicates any error.
95 *
96 * @param keymgr_dpe A key manager handle.
97 * @return The result of the operation.
98 */
100status_t keymgr_dpe_testutils_wait_for_operation_done(
101 const dif_keymgr_dpe_t *keymgr_dpe);
102
103#elif defined(OPENTITAN_IS_EARLGREY) || defined(OPENTITAN_IS_ENGLISHBREAKFAST)
104
105#include "sw/device/lib/base/status.h"
108
109// Note: In the testutil only a single key derivation chain is generated,
110// rather than two key chains (attestation and sealing keys)
111
112/**
113 * Versioned key parameters for testing.
114 *
115 * Change destination in order to sideload keys to hardware.
116 */
117static const dif_keymgr_dpe_generate_params_t kKeyVersionedParams = {
118 .key_dest = kDifKeymgrDpeKeyDestNone,
119 .sideload_key = false,
120 .salt = {0xb6521d8f, 0x13a0e876, 0x1ca1567b, 0xb4fb0fdf, 0x9f89bc56,
121 0x4bd127c7, 0x322288d8, 0xde919d54},
122 .version = 0x0,
123 .slot_src_sel = 1,
124};
125
126/**
127 * Parameter list for the initial advancement. The slot_dst_sel determines in
128 * which slot the UDS is loaded. Any other parameters are discarded.
129 */
130static const dif_keymgr_dpe_advance_params_t kInitialParams = {
131 .binding_value = {0, 0, 0, 0, 0, 0, 0, 0},
132 .max_key_version = 0,
133 .slot_src_sel = 0,
134 .slot_dst_sel = 1,
135 .slot_policy = 0};
136
137/**
138 * Parameters for advancing: UDS > creator root key
139 */
140static const dif_keymgr_dpe_advance_params_t kCreatorRootKeyParams = {
141 .binding_value = {0xdc96c23d, 0xaf36e268, 0xcb68ff71, 0xe92f76e2,
142 0xb8a8379d, 0x426dc745, 0x19f5cff7, 0x4ec9c6d6},
143 .max_key_version = 0x11,
144 .slot_src_sel = 1,
145 .slot_dst_sel = 1,
146 .slot_policy = 1 // 0b001 Allow children without retaining the parent
147};
148
149/**
150 * Parameter for advancing: creator root key > owner int key
151 */
152static const dif_keymgr_dpe_advance_params_t kOwnerIntKeyParams = {
153 .binding_value = {0xe4987b39, 0x3f83d390, 0xc2f3bbaf, 0x3195dbfa,
154 0x23fb480c, 0xb012ae5e, 0xf1394d28, 0x1940ceeb},
155 .max_key_version = 0xaa,
156 .slot_src_sel = 1,
157 .slot_dst_sel = 1,
158 .slot_policy = 1 // 0b001 Allow children without retaining the parent
159};
160
161/**
162 * Parameter for advancing: owner int key > owner key
163 */
164static const dif_keymgr_dpe_advance_params_t kOwnerKeyParams = {
165 .binding_value = {0xd8a812ea, 0xb6ebe129, 0x217773d4, 0x35b37c77,
166 0xec8298be, 0x1f7dec77, 0x1803199e, 0xa02ad81d},
167 .max_key_version = 0xaa,
168 .slot_src_sel = 1,
169 .slot_dst_sel = 1,
170 .slot_policy = 5 // 0b101 Allow children with retaining the parent
171};
172
173/**
174 * Struct to hold the creator or owner secrets for the key manager dpe.
175 */
176typedef struct keymgr_dpe_testutils_secret {
177 uint32_t value[8];
178} keymgr_dpe_testutils_secret_t;
179
180/**
181 * Key manager dpe Creator Secret (seed) stored in info flash page.
182 */
183static const keymgr_dpe_testutils_secret_t kCreatorSecret = {
184 .value = {0x4e919d54, 0x322288d8, 0x4bd127c7, 0x9f89bc56, 0xb4fb0fdf,
185 0x1ca1567b, 0x13a0e876, 0xa6521d8f}};
186
187/**
188 * Key manager dpe Owner Secret (seed) stored in info flash page.
189 */
190static const keymgr_dpe_testutils_secret_t kOwnerSecret = {
191 .value = {0xa6521d8f, 0x13a0e876, 0x1ca1567b, 0xb4fb0fdf, 0x9f89bc56,
192 0x4bd127c7, 0x322288d8, 0x4e919d54}};
193
194/**
195 * Programs nvm with secrets so that the keymgr dpe can be advanced to
196 * CreatorRootKey state.
197 *
198 * This is normally a subfunction of keymgr_testutils_startup, but some tests
199 * use the function separately as well.
200 *
201 * @param creator_secret The creator secret to be programmed to flash, or NULL
202 * to skip writing the creator secret.
203 * @param owner_secret The owner secret to be programmed to flash.
204 *
205 */
207status_t keymgr_dpe_testutils_nvm_init(
208 const keymgr_dpe_testutils_secret_t *creator_secret,
209 const keymgr_dpe_testutils_secret_t *owner_secret);
210
211/**
212 * Initializes the key manager dpe and its dependencies for testing.
213 *
214 * This function initializes the key manager dpe and its dependencies for
215 * testing.
216 *
217 * This function will call `keymgr_dpe_testutils_try_startup()` if the boot
218 * stage is `kBootStageOwner`; otherwise, it will call
219 * `keymgr_testutils_startup()`. Additional checks are performed to ensure that
220 * the key manager is in a valid state, and ready to perform key derivations.
221 *
222 * @param keymgr_dpe A key manager dpe handle, may be uninitialized.
223 * @param kmac A KMAC handle, may be uninitialized.
224 * @return The result of the operation.
225 */
227status_t keymgr_dpe_testutils_initialize(dif_keymgr_dpe_t *keymgr_dpe,
228 dif_kmac_t *kmac);
229
230/**
231 * Wrapper function to `keymgr_testutils_startup()`.
232 *
233 * This function checks the state of the key manager before attempting to
234 * initialize its dependencies and state.
235 *
236 * The function will return an error if the keymgr is disabled or in invalid
237 * state.
238 *
239 * @param keymgr_dpe A key manager dpe handle, may be uninitialized.
240 * @param kmac A KMAC handle, may be uninitialized.
241 * @param[out] keymgr_dpe_state The state of the keymgr dpe after startup.
242 */
244status_t keymgr_dpe_testutils_try_startup(
245 dif_keymgr_dpe_t *keymgr_dpe, dif_kmac_t *kmac,
246 dif_keymgr_dpe_state_t *keymgr_dpe_state);
247
248/**
249 * Initialize non-volatile memory (flash and OTP) for keymgr dpe and then
250 * reset, so that the relevant OTP partitions become accessible to keymgr dpe.
251 * After calling this function, keymgr dpe can be initialized.
252 */
254status_t keymgr_dpe_testutils_init_nvm_then_reset(void);
255
256/**
257 * Programs flash, restarts, and advances keymgr to Available state.
258 * Afterwards the CreatorRootKey is generated in the slot defined by
259 * kCreatorRootKeyParams. Note that this function assumes that the keymgr dpe
260 * is in the initial reset state after ROM execution.
261 *
262 * This procedure essentially gets the keymgr into the first state where it can
263 * be used for tests. Tests should call it before anything else, like below:
264 *
265 * ```c
266 * void test_main(void) {
267 * // Set up and generate the CreatorRootKey.
268 * dif_keymgr_dpe_t keymgr_dpe;
269 * dif_kmac_t kmac;
270 * keymgr_dpe_testutils_startup(&keymgr_dpe, &kmac);
271 *
272 * // Remainder of test; optionally advance the CreatorRootKey to the
273 * // OwnerIntKey, generate keys and identities.
274 * ...
275 * }
276 * ```
277 *
278 * Because the key manager dpe uses KMAC, this procedure also initializes and
279 * configures KMAC. Software should not rely on the configuration here and
280 * should reconfigure KMAC if needed. The purpose of configuring KMAC in this
281 * procedure is so that the key manager dpe will not use KMAC with the default
282 * entropy settings.
283 *
284 * @param keymgr_dpe A key manager dpe handle, may be uninitialized.
285 * @param kmac A KMAC handle, may be uninitialized.
286 */
288status_t keymgr_dpe_testutils_startup(dif_keymgr_dpe_t *keymgr_dpe,
289 dif_kmac_t *kmac);
290
291/**
292 * Advances the DPE context of the keymgr_dpe and wait for it to complete
293 *
294 * @param keymgr_dpe A key manager dpe handle.
295 * @param params The binding and max key version value for the next state.
296 */
298status_t keymgr_dpe_testutils_advance_state(
299 const dif_keymgr_dpe_t *keymgr_dpe,
300 const dif_keymgr_dpe_advance_params_t *params);
301
302/**
303 * Loads the UDS into the keymgr dpe and move the state from `Reset`
304 * to `Available`.
305 *
306 * The first advance call is automatically mapped to latch the UDS into the
307 * designated destination slot rather than advancing any DPE context.
308 * Therefore most registers used in the regular advance call are ignored
309 * during initialization.
310 *
311 * @param keymgr_dpe A key manager dpe handle.
312 * @param params The .slot_dst_sel subfield determines the slot for the UDS
313 */
315status_t keymgr_dpe_testutils_initial_load_uds(
316 const dif_keymgr_dpe_t *keymgr_dpe,
317 const dif_keymgr_dpe_advance_params_t *params);
318
319/**
320 * Checks if the current keymgr dpe state matches the expected state
321 *
322 * @param keymgr_dpe A key manager dpe handle.
323 * @param exp_state The expected key manager state.
324 */
326status_t keymgr_dpe_testutils_check_state(
327 const dif_keymgr_dpe_t *keymgr_dpe, const dif_keymgr_dpe_state_t exp_state);
328
329/**
330 * Issues a keymgr dpe HW/SW versioned key generation and wait for it
331 * to complete.
332 *
333 * @param keymgr_dpe A key manager dpe handle.
334 * @param params Key generation parameters.
335 */
337status_t keymgr_dpe_testutils_generate_key(
338 const dif_keymgr_dpe_t *keymgr_dpe,
340
341/**
342 * Erase a keymgr_dpe slot.
343 *
344 * @param keymgr_dpe A key manager handle.
345 * @param params A wrapper struct that contains the destination slot to be
346 * erased.
347 * @return The result of the operation.
348 */
350status_t keymgr_dpe_testutils_erase_slot(
351 const dif_keymgr_dpe_t *keymgr_dpe,
352 const dif_keymgr_dpe_erase_params_t *params);
353
354/**
355 * Issues a keymgr dpe disable and wait for it to complete
356 */
358status_t keymgr_dpe_testutils_disable(const dif_keymgr_dpe_t *keymgr_dpe);
359
360/**
361 * Polling keymgr dpe status until it becomes idle.
362 * Fail the test if the status code indicates any error.
363 *
364 * @param keymgr_dpe A key manager dpe handle.
365 */
367status_t keymgr_dpe_testutils_wait_for_operation_done(
368 const dif_keymgr_dpe_t *keymgr_dpe);
369
370/**
371 * Get the current state of the key manager dpe.
372 *
373 * @param keymgr_dpe A key manager dpe handle.
374 * @param[out] state The current state of the key manager dpe in
375 * C string format.
376 *
377 * @return The result of the operation.
378 */
380status_t keymgr_dpe_testutils_state_string_get(
381 const dif_keymgr_dpe_t *keymgr_dpe, const char **stage_name);
382
383/**
384 * Clears the key from one sideload slot
385 *
386 * @param keymgr_dpe A key manager dpe handle.
387 * @param clear_dest Destination for the clear operation
388 *
389 * @return The result of the operation.
390 */
392status_t keymgr_dpe_testutils_clear_sideload_key(
393 const dif_keymgr_dpe_t *keymgr_dpe,
395
396#else
397#error "[Keymgr_dpe, testutils] None of the supported tops defined!"
398#endif
399
400#endif // OPENTITAN_SW_DEVICE_LIB_TESTING_KEYMGR_DPE_TESTUTILS_H_