blob: 905ae615282b4afe08d1a1ea95327f9e6588637e [file] [log] [blame]
Miguel Osoriobffbcad2021-04-15 19:46:14 -07001// Copyright lowRISC contributors.
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_EDN_H_
6#define OPENTITAN_SW_DEVICE_LIB_DIF_DIF_EDN_H_
7
8/**
9 * @file
10 * @brief <a href="/hw/ip/edn/doc/">Entropy Distribution Network</a> Device
11 * Interface Functions
12 *
13 * This API implements the interface for the Entropy Distribution Network (EDN)
14 * hardware.
15 *
16 * There are two main modes of operation:
17 *
18 * - boot-time: EDN configures the associated CSRNG instance to fetch pre-FIPS
19 * entropy immediately at boot-time or after reset.
20 * - auto refresh: EDN sends reseed and generate commands to the associated
21 * CSRNG instance. The API allows the user to set the CSRNG instantiate,
22 * reseed and generate para meters, as well as the reseed frequency.
Miguel Osoriobffbcad2021-04-15 19:46:14 -070023 */
24
25#include <stdint.h>
26
Timothy Trippele3f8a822021-09-17 06:09:28 +000027#include "sw/device/lib/base/macros.h"
Miguel Osoriobffbcad2021-04-15 19:46:14 -070028#include "sw/device/lib/base/mmio.h"
Timothy Trippel993bb2d2021-09-28 20:46:43 +000029#include "sw/device/lib/dif/dif_base.h"
30
31#include "sw/device/lib/dif/autogen/dif_edn_autogen.h"
Miguel Osoriobffbcad2021-04-15 19:46:14 -070032
33#ifdef __cplusplus
34extern "C" {
35#endif // __cplusplus
36
37enum {
38 /**
39 * Maximum seed material number of uint32_t words supported in CSRNG
40 * instantiate and seed commands.
41 */
42 kDifEntropySeedMaterialMaxWordLen = 12,
43};
44
Timothy Chendfad6c42022-07-18 20:43:35 -070045enum {
46 /**
47 * Csrng commands
48 */
49 kDifEdnCmdInstantiate = 1,
50 kDifEdnCmdReseed = 2,
51 kDifEdnCmdGenerate = 3
52};
53
Miguel Osoriobffbcad2021-04-15 19:46:14 -070054/**
Pirmin Vogel5e4f0a32022-10-10 23:18:36 +020055 * CSRNG seed material for instantiate, reseed and generate commands.
Miguel Osoriobffbcad2021-04-15 19:46:14 -070056 */
57typedef struct dif_edn_seed_material {
58 /**
59 * Number of uint32_t words in `data`. Up to
60 * `kDifEntropySeedMaterialMaxWordLen` words can be set to initialize or
61 * reseed the CSRNG. CSRNG will extend the `data` to zeros if the provided
62 * value is less than kDifEntropySeedMaterialMaxWordLen.
63 */
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -040064 size_t len;
Miguel Osoriobffbcad2021-04-15 19:46:14 -070065 /**
Pirmin Vogel5e4f0a32022-10-10 23:18:36 +020066 * Seed material used in CSRNG instantiate, reseed or generate call.
Miguel Osoriobffbcad2021-04-15 19:46:14 -070067 */
68 uint32_t data[kDifEntropySeedMaterialMaxWordLen];
69} dif_edn_seed_material_t;
70
71/**
Pirmin Vogel5e4f0a32022-10-10 23:18:36 +020072 * CSRNG command parameters for instantiate, reseed and generate commands.
73 */
74typedef struct dif_edn_cmd {
75 /**
76 * The CSRNG application interface command header. For details, refer to the
77 * CSRNG documentation.
78 */
79 uint32_t cmd;
80 /**
81 * Optional seed material.
82 */
83 dif_edn_seed_material_t seed_material;
84} dif_edn_cmd_t;
85
86/**
Miguel Osoriobffbcad2021-04-15 19:46:14 -070087 * Auto-generate EDN module configuration parameters.
88 */
89typedef struct dif_edn_auto_params {
90 /**
Pirmin Vogel5e4f0a32022-10-10 23:18:36 +020091 * CSRNG instantiate command material.
92 */
93 dif_edn_cmd_t instantiate_cmd;
94 /**
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -040095 * CSRNG reseed command material.
Miguel Osoriobffbcad2021-04-15 19:46:14 -070096 */
Pirmin Vogel5e4f0a32022-10-10 23:18:36 +020097 dif_edn_cmd_t reseed_cmd;
Miguel Osoriobffbcad2021-04-15 19:46:14 -070098 /**
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -040099 * CSRNG generate command material.
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700100 */
Pirmin Vogel5e4f0a32022-10-10 23:18:36 +0200101 dif_edn_cmd_t generate_cmd;
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700102 /**
103 * Number of generate calls that can be made before a reseed request is made.
104 */
105 uint32_t reseed_interval;
106} dif_edn_auto_params_t;
107
108/**
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400109 * EDN Status flags.
110 */
111typedef enum dif_edn_status {
112 /**
113 * Device is ready to receive a command.
114 */
115 kDifEdnStatusReady,
116 /**
117 * Device has recieved an ACK from the CSRNG block.
118 */
119 kDifEdnStatusCsrngAck,
120} dif_edn_status_t;
121
122/**
123 * Enumeration of EDN FIFOs, which indicates which part of the hardware
124 * produced an error.
125 */
126typedef enum dif_edn_fifo {
127 kDifEdnFifoReseedCmd,
128 kDifEdnFifoGenerateCmd,
129} dif_edn_fifo_t;
130
131/**
132 * Enumeration of EDN FIFO errors.
133 */
134typedef enum dif_edn_error {
135 /**
136 * Indicates an error in the command ack state machine.
137 */
138 kDifEdnErrorAckSm,
139 /**
140 * Indicates an error in the main state machine.
141 */
142 kDifEdnErrorMainSm,
143 /**
144 * Indicates an error in a hardened counter.
145 */
146 kDifEdnErrorCounterFault,
147 /**
148 * Indicates a write to a full FIFO occured.
149 */
150 kDifEdnErrorFifoWrite,
151 /**
152 * Indicates a read from an empty FIFO occured.
153 */
154 kDifEdnErrorFifoRead,
155 /**
156 * Indicates a FIFO was somehow both full and empty.
157 */
158 kDifEdnErrorFifoFullAndEmpty,
159} dif_edn_error_t;
160
161/**
162 * CSRNG consume seed from entropy source enable.
163 */
164typedef enum dif_edn_entropy_src_toggle {
165 /**
166 * Seed material used as the only seed material.
167 *
168 * This configuration option will toggle the hardware state of the
169 * CSRNG to non-FIPS compliant until it is re-instantiated.
170 *
171 * Note: Software may opt to XOR the seed material with a seed to implement
172 * a software assisted FIPS mode of operation.
173 */
174 kDifEdnEntropySrcToggleDisable = 1,
175 /**
176 * Entropy source XOR'ed with the provided seed material.
177 */
178 kDifEdnEntropySrcToggleEnable = 0,
179} dif_edn_entropy_src_toggle_t;
180
181/**
182 * Recoverable alerts emitted by the EDN.
183 */
184typedef enum dif_edn_recoverable_alert {
185 /**
186 * Indicates a bad value was written to the EDN_ENABLE field of the control
187 * register.
188 */
189 kDifEdnRecoverableAlertBadEnable,
190 /**
191 * Indicates a bad value was written to the BOOT_REQ_MODE field of the control
192 * register.
193 */
194 kDifEdnRecoverableAlertBadBootReqMode,
195 /**
196 * Indicates a bad value was written to the AUTO_REQ_MODE field of the
197 * control register.
198 */
199 kDifEdnRecoverableAlertBadAutoReqMode,
200 /**
201 * Indicates a bad value was written to the CMD_FIFO_RST field of the
202 * control register.
203 */
204 kDifEdnRecoverableAlertBadFifoClear,
205 /**
206 * Indicates the genbits bus saw two identical values, indicating a possible
207 * attack.
208 */
209 kDifEdnRecoverableAlertRepeatedGenBits,
210} dif_edn_recoverable_alert_t;
211
212/**
213 * Configures EDN with runtime information.
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700214 *
215 * This function should need to be called once for the lifetime of `handle`.
216 *
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400217 * @param edn An EDN handle.
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700218 * @return The result of the operation.
219 */
Timothy Trippele3f8a822021-09-17 06:09:28 +0000220OT_WARN_UNUSED_RESULT
Timothy Trippel993bb2d2021-09-28 20:46:43 +0000221dif_result_t dif_edn_configure(const dif_edn_t *edn);
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700222
223/**
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400224 * Locks out EDN functionality.
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700225 *
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400226 * This function is reentrant: calling it while functionality is locked will
227 * have no effect and return `kDifEdnOk`.
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700228 *
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400229 * @param edn An EDN handle.
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700230 * @return The result of the operation.
231 */
Timothy Trippele3f8a822021-09-17 06:09:28 +0000232OT_WARN_UNUSED_RESULT
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400233dif_result_t dif_edn_lock(const dif_edn_t *edn);
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700234
235/**
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400236 * Checks whether this EDN is locked.
237 *
238 * @param edn An EDN handle.
239 * @param[out] is_locked Out-param for the locked state.
240 * @return The result of the operation.
241 */
242OT_WARN_UNUSED_RESULT
243dif_result_t dif_edn_is_locked(const dif_edn_t *edn, bool *is_locked);
244
245/**
246 * Enables the EDN in boot-time mode.
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700247 *
248 * Each call to this function should be sequenced with a call to
249 * `dif_edn_stop()`.
250 *
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400251 * @param edn An EDN handle.
252 * @return The result of the operation.
253 */
254OT_WARN_UNUSED_RESULT
255dif_result_t dif_edn_set_boot_mode(const dif_edn_t *edn);
256
257/**
258 * Enables the EDN in auto refresh mode.
259 *
260 * Each call to this function should be sequenced with a call to
261 * `dif_edn_stop()`.
262 *
263 * @param edn An EDN handle.
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700264 * @param config Auto request configuration parameters.
265 * @return The result of the operation.
266 */
Timothy Trippele3f8a822021-09-17 06:09:28 +0000267OT_WARN_UNUSED_RESULT
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400268dif_result_t dif_edn_set_auto_mode(const dif_edn_t *edn,
269 dif_edn_auto_params_t config);
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700270
271/**
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400272 * Queries the EDN status flags.
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700273 *
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400274 * @param edn An EDN handle.
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700275 * @param flag Status flag to query.
276 * @param set Flag state (set/unset).
277 * @return The result of the operation.
278 */
Guillermo Maturana59bfc512022-07-22 11:43:58 -0700279OT_WARN_UNUSED_RESULT
Timothy Trippel993bb2d2021-09-28 20:46:43 +0000280dif_result_t dif_edn_get_status(const dif_edn_t *edn, dif_edn_status_t flag,
281 bool *set);
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700282
283/**
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400284 * Queries the EDN error flags.
285 *
286 * @param edn An EDN handle.
Miguel Osorioc984a6a2022-11-01 17:03:45 -0700287 * @param[out] unhealthy_fifos Bitset of FIFOs in an unhealthy state; indices
288 * are `dif_edn_fifo_t`.
289 * @param[out] errors Bitset of errors relating to the above FIFOs; indices are
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400290 * `dif_edn_error_t`.
291 * @return The result of the operation.
292 */
Guillermo Maturana59bfc512022-07-22 11:43:58 -0700293OT_WARN_UNUSED_RESULT
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400294dif_result_t dif_edn_get_errors(const dif_edn_t *edn, uint32_t *unhealthy_fifos,
295 uint32_t *errors);
296
297/**
298 * Forces the status registers to indicate `fifo` as being in an unhealthy
299 * state.
300 *
301 * @param edn An EDN handle
302 * @param fifo The FIFO to mark as unhealthy.
303 * @return The result of the operation.
304 */
305OT_WARN_UNUSED_RESULT
306dif_result_t dif_edn_get_cmd_unhealthy_fifo_force(const dif_edn_t *edn,
307 dif_edn_fifo_t fifo);
308
309/**
310 * Forces the status registers to indicate a particular error cause.
311 *
312 * @param edn An EDN handle
313 * @param error The error to force.
314 * @return The result of the operation.
315 */
316OT_WARN_UNUSED_RESULT
317dif_result_t dif_edn_get_cmd_error_force(const dif_edn_t *edn,
318 dif_edn_error_t error);
319
320/**
321 * Returns an opaque blob indicating the main state machine's current state.
322 *
323 * @param csrng An EDN handle
324 * @param state[out] The state machine state as an opaque blob.
325 * @return The result of the operation.
326 */
327OT_WARN_UNUSED_RESULT
328dif_result_t dif_edn_get_main_state_machine(const dif_edn_t *edn,
329 uint32_t *state);
330
331/**
332 * Initializes CSRNG instance with a new seed value.
333 *
334 * `seed_material` is used as specified in NIST SP 800-90Ar1 section
335 * 10.2.1.3.1.
336 *
337 * `seed_material` can be NULL, in which case CSRNG will use a zero
338 * vector instead.
339 *
340 * @param edn An EDN handle.
341 * @param entropy_src_enable Entropy source input enable.
342 * @param seed_material Seed initialization parameters.
343 * @return The result of the operation.
344 */
345OT_WARN_UNUSED_RESULT
346dif_result_t dif_edn_instantiate(
347 const dif_edn_t *edn, dif_edn_entropy_src_toggle_t entropy_src_enable,
348 const dif_edn_seed_material_t *seed_material);
349
350/**
351 * Reseeds CSRNG instance.
352 *
353 * When `seed_material.seed_material_len` is set to 0, only the entropy source
354 * seed is used to reseed the instance, otherwise it will be XOR'ed with the
355 * entropy source.
356 *
357 * @param edn An EDN handle.
358 * @param seed_material Reseed parameters.
359 * @return The result of the operation.
360 */
361OT_WARN_UNUSED_RESULT
362dif_result_t dif_edn_reseed(const dif_edn_t *edn,
363 const dif_edn_seed_material_t *seed_material);
364
365/**
366 * Updates CSRNG state.
367 *
368 * This function is similar to `dif_edn_reseed()`, except:
369 *
370 * - Only `seed_material.seed_material` is used in the update operation.
371 * - The update operation does not reset the internal CSRNG reseed
372 * counter.
373 *
374 * @param edn An EDN handle.
375 * @param seed_material Update parameters.
376 * @return The result of the operation.
377 */
378OT_WARN_UNUSED_RESULT
379dif_result_t dif_edn_update(const dif_edn_t *edn,
380 const dif_edn_seed_material_t *seed_material);
381
382/**
383 * Requests cryptographic entropy bits from the CSRNG.
384 *
385 * The prediction resistance flag as specified in SP 800-90Ar1 section
386 * 10.2.1.1 is not directly supported by the hardware. It is the
387 * responsibility of the caller to reseed as needed before calling
388 * this function.
389 *
390 * The CSRNG accepts generation requests with 128-bit granularity, with
391 * a minimum 128-bit request size. This function will increase the size
392 * of the request to align it to the nearest 128-bit boundary.
393 *
394 * @param edn An EDN handle.
395 * @param len Number of uint32_t words to generate.
396 */
397OT_WARN_UNUSED_RESULT
398dif_result_t dif_edn_generate_start(const dif_edn_t *edn, size_t len);
399
400/**
401 * Uninstantiates CSRNG.
402 *
403 * Resets the CSRNG instance. Values in the CSRNG are zeroed out. This
404 * command effectively resets the CSRNG, clearing any errors that it
405 * may have encountered due to processing or entropy source errors.
406 *
407 * @param edn An EDN handle.
408 * @return The result of the operation.
409 */
410OT_WARN_UNUSED_RESULT
411dif_result_t dif_edn_uninstantiate(const dif_edn_t *edn);
412
413/**
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700414 * Stops the current mode of operation and disables the entropy module.
415 *
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400416 * @param edn An EDN handle.
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700417 * @return The result of the operation.
418 */
Timothy Trippele3f8a822021-09-17 06:09:28 +0000419OT_WARN_UNUSED_RESULT
Timothy Trippel993bb2d2021-09-28 20:46:43 +0000420dif_result_t dif_edn_stop(const dif_edn_t *edn);
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700421
422/**
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400423 * Gets the recoverable alerts currently recorded in the EDN block.
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700424 *
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400425 * This function returns the alerts in a bitset whose indices are given by
426 * `dif_edn_recoverable_alert_t`.
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700427 *
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400428 * @param edn An EDN handle.
429 * @param[out] alerts Bitset of alerts currently recorded.
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700430 * @return The result of the operation.
431 */
Timothy Trippele3f8a822021-09-17 06:09:28 +0000432OT_WARN_UNUSED_RESULT
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400433dif_result_t dif_edn_get_recoverable_alerts(const dif_edn_t *edn,
434 uint32_t *alerts);
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700435
436/**
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400437 * Clears all recoverable alerts currently recorded in the EDN block.
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700438 *
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400439 * @param edn An EDN handle.
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700440 * @return The result of the operation.
441 */
Timothy Trippele3f8a822021-09-17 06:09:28 +0000442OT_WARN_UNUSED_RESULT
Miguel Young de la Sota5a6bc132022-05-11 14:04:26 -0400443dif_result_t dif_edn_clear_recoverable_alerts(const dif_edn_t *edn);
Miguel Osoriobffbcad2021-04-15 19:46:14 -0700444
445#ifdef __cplusplus
446} // extern "C"
447#endif // __cplusplus
448
449#endif // OPENTITAN_SW_DEVICE_LIB_DIF_DIF_EDN_H_