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