Software APIs
pentest_lib.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_TESTS_PENETRATIONTESTS_FIRMWARE_LIB_PENTEST_LIB_H_
6 #define OPENTITAN_SW_DEVICE_TESTS_PENETRATIONTESTS_FIRMWARE_LIB_PENTEST_LIB_H_
7 
9 #include "sw/device/lib/ujson/ujson.h"
10 #include "sw/device/tests/penetrationtests/json/pentest_lib_commands.h"
11 
12 typedef struct pentest_registered_alerts {
13  uint32_t alerts[3];
15 
16 typedef struct pentest_sensor_alerts {
17  uint32_t alerts[2];
19 
20 /**
21  * Trigger sources.
22  *
23  * The trigger signal for a peripheral is based on its clkmgr_aon_idle signal.
24  * These values must match the values in chiplevel.sv.tpl.
25  */
26 typedef enum pentest_trigger_source {
27  /**
28  * Use AES for capture trigger.
29  *
30  * The trigger signal will go high 320 cycles after `dif_aes_trigger()` is
31  * called and remain high until the operation is complete.
32  */
33  kPentestTriggerSourceAes = 0,
34  /**
35  * Use HMAC for capture trigger.
36  */
37  kPentestTriggerSourceHmac = 1,
38  /**
39  * Use KMAC for capture trigger.
40  */
41  kPentestTriggerSourceKmac = 2,
42  /**
43  * Use OTBN for capture trigger.
44  */
45  kPentestTriggerSourceOtbn = 3,
46 } pentest_trigger_source_t;
47 
48 /**
49  * Trigger type.
50  */
51 typedef enum pentest_trigger_type {
52  /**
53  * Use the precise hardware capture trigger gateable by software. If selected,
54  * the actual capture trigger is generated based on the clkmgr_aon_idle signal
55  * of the peripheral corresponding to selected trigger source.
56  *
57  * Note that this is available on FPGA only.
58  */
59  kPentestTriggerTypeHwGated = 0,
60  /**
61  * Use the fully software controlled capture trigger. If selected, the
62  * configured trigger source is not relevant.
63  */
64  kPentestTriggerTypeSw = 1,
65 } pentest_trigger_type_t;
66 
67 /**
68  * Peripherals.
69  *
70  * Constants below are bitmasks that can be used to specify a set of
71  * peripherals.
72  *
73  * See also: `pentest_peripherals_t`.
74  */
75 typedef enum pentest_peripheral {
76  /**
77  * EDN.
78  */
79  kPentestPeripheralEdn = 1 << 0,
80  /**
81  * CSRNG.
82  */
83  kPentestPeripheralCsrng = 1 << 1,
84  /**
85  * Entropy source.
86  */
87  kPentestPeripheralEntropy = 1 << 2,
88  /**
89  * AES.
90  */
91  kPentestPeripheralAes = 1 << 3,
92  /**
93  * HMAC.
94  */
95  kPentestPeripheralHmac = 1 << 4,
96  /**
97  * KMAC.
98  */
99  kPentestPeripheralKmac = 1 << 5,
100  /**
101  * OTBN.
102  */
103  kPentestPeripheralOtbn = 1 << 6,
104  /**
105  * Peripherals using the IO_DIV4_PERI clock (UART, GPIO, I2C, SPI Dev, ...)
106  */
107  kPentestPeripheralIoDiv4 = 1 << 7,
108  /**
109  * Peripherals using the IO_DIV2_PERI clock (SPI Host 1)
110  */
111  kPentestPeripheralIoDiv2 = 1 << 8,
112  /**
113  * USB.
114  */
115  kPentestPeripheralUsb = 1 << 9,
116  /**
117  * Peripherals using the IO_PERI clock (SPI Host 0)
118  */
119  kPentestPeripheralIo = 1 << 10,
120 } pentest_peripheral_t;
121 
122 /**
123  * A set of peripherals.
124  *
125  * This type is used for specifying which peripherals should be enabled when
126  * calling `pentest_init()`. Remaining peripherals will be disabled to reduce
127  * noise during SCA.
128  *
129  * See also: `pentest_peripheral_t`, `pentest_init()`.
130  */
131 typedef uint32_t pentest_peripherals_t;
132 
133 /**
134  * A set of contexts for SW LFSR
135  *
136  * This type is used for specifying the context of the LFSR, with each context
137  * corresponding to a different state variable
138  */
139 typedef enum pentest_lfsr_context {
140  /**
141  * PRNG used for initial data sharing
142  */
143  kPentestLfsrMasking = 0,
144  /**
145  * PRNG used for determining the order of fixed and random measurements
146  */
147  kPentestLfsrOrder = 1,
148 
149 } pentest_lfsr_context_t;
150 
151 /**
152  * Configures the entropy complex for OTBN tests.
153  *
154  * Similar to entropy_testutils_auto_mode_init(), this function inits the
155  * entropy complex. However, in comparison to the function available in the
156  * testutils, this function maximizes the reseed intervall to 0xffffffff.
157  * This is necessary to guarantee a fixed trigger window for OTBN tests.
158  *
159  * @return OK or error.
160  */
161 status_t pentest_configure_entropy_source_max_reseed_interval(void);
162 
163 /**
164  * Returns the registered alerts in the sensor controller.
165  *
166  * This function reads out the recov_alert and fatal_alert registers of the
167  * sensor controller. This controller collects the alerts of the AST.
168  *
169  * @return A struct containing which of the alerts were triggered during the
170  * test.
171  */
172 pentest_sensor_alerts_t pentest_get_sensor_alerts(void);
173 
174 /**
175  * Clears the recoverable AST alerts in the sensor controller.
176  */
177 void pentest_clear_sensor_recov_alerts(void);
178 
179 /**
180  * Returns the registered alerts.
181  *
182  * If a fault injection triggered an alert, this function returns the alert ID
183  * back to the host. Afterwards, the alert is cleared.
184  *
185  * @return A struct containing which of the alerts were triggered during the
186  * test.
187  */
188 pentest_registered_alerts_t pentest_get_triggered_alerts(void);
189 
190 /**
191  * Configures the alert handler for FI.
192  *
193  * Register all alerts and let them escalate to Phase0 only.
194  */
195 void pentest_configure_alert_handler(void);
196 
197 /**
198  * Reads the device ID from the LC.
199  *
200  * Can be used to categorize different SCA and FI runs.
201  *
202  * @param device_id A buffer available to store the device id.
203  * @return OK or error.
204  */
205 status_t pentest_read_device_id(uint32_t device_id[]);
206 
207 /**
208  * Configures CPU for SCA and FI penetration tests.
209  *
210  * If disable_icache is True, this functions disables the instruction cache. If
211  * disable_icache is False, the instruction cache config remains at
212  * enabled/disabled based on the ROM configuration. This implies that the iCache
213  * could be disabled even though disable_icache is False.
214  *
215  * If disable_dummy_instr is True, this functions disables the dummy
216  * instructions. If disable_dummy_instr is False, the dummy instruction config
217  * remains at the original config that was set in the ROM. This implies that
218  * dummy instructions could disabled even though disable_dummy_instr is False.
219  *
220  * For enable_jittery_clock, the function first checks if the write protection
221  * for this register is enabled. Then, by setting enable_jittery_clock True or
222  * False, the jittery clock is enabled or disabled. When regwen is active, no
223  * change happens.
224  *
225  * For enable_sram_readback, the function first checks if the write protection
226  * for this register is enabled. Then, by setting enable_sram_readback True or
227  * False, the SRAM readback feature for the main and ret SRAM iss enabled or
228  * disabled. When regwen is active, no change happens.
229  *
230  * @param disable_icache Disable the instruction cache.
231  * @param disable_dummy_instr Disable the dummy instructions.
232  * @param enable_jittery_clock: Enable/disable the jittery clock.
233  * @param enable_sram_readback: Enable/disable the SRAM readback feature.
234  * @param clock_jitter_locked: Jittery clock register is locked.
235  * @param clock_jitter_en: Jittery clock feature is enabled.
236  * @param sram_main_readback_locked: SRAM main readback register is locked.
237  * @param sram_ret_readback_locked: SRAM ret readback register is locked.
238  * @param sram_main_readback_en: SRAM main readback feature is enabled.
239  * @param sram_ret_readback_en: SRAM ret readback feature is enabled.
240  * @return OK or error.
241  */
242 status_t pentest_configure_cpu(
243  bool disable_icache, bool disable_dummy_instr, bool enable_jittery_clock,
244  bool enable_sram_readback, bool *clock_jitter_locked, bool *clock_jitter_en,
245  bool *sram_main_readback_locked, bool *sram_ret_readback_locked,
246  bool *sram_main_readback_en, bool *sram_ret_readback_en);
247 
248 /**
249  * Initializes the peripherals (pinmux, uart, gpio, and timer) used by SCA code.
250  *
251  * @param trigger Peripheral to use for the trigger signal.
252  * @param enable Set of peripherals to enable. Remaining peripherals will
253  * be disabled to reduce noise during SCA.
254  */
255 void pentest_init(pentest_trigger_source_t trigger,
256  pentest_peripherals_t enable);
257 
258 /**
259  * Returns a handle to the intialized UART device.
260  *
261  * @return Handle to the initialized UART device.
262  */
263 const dif_uart_t *pentest_get_uart(void);
264 
265 /**
266  * Select the capture trigger type.
267  *
268  * @param trigger_type The trigger type to select.
269  */
270 void pentest_select_trigger_type(pentest_trigger_type_t trigger_type);
271 
272 /**
273  * Sets capture trigger high.
274  *
275  * The actual trigger signal used for capture is a combination (logical AND) of:
276  * - the trigger gate enabled here, and
277  * - the busy signal of the peripheral of interest.
278  */
279 void pentest_set_trigger_high(void);
280 
281 /**
282  * Sets capture trigger low.
283  */
284 void pentest_set_trigger_low(void);
285 
286 /**
287  * Functions called by `pentest_call_and_sleep()` must conform to this
288  * prototype.
289  */
290 typedef void (*sca_callee)(void);
291 
292 /**
293  * Calls the given function and puts Ibex to sleep.
294  *
295  * This function can be used to minimize noise while capturing power traces for
296  * side-channel attacks, in which case `callee` would trigger the operation of
297  * interest, typically a crypto operation, on the target device.
298  *
299  * @param callee Function to call before putting Ibex to sleep.
300  * @param sleep_cycles Number of cycles to sleep.
301  * @param sw_trigger Raise trigger before calling the target function.
302  * @param otbn Wait until OTBN execution has finished. Not supported in
303  * ENGLISH_BREAKFAST.
304  */
305 void pentest_call_and_sleep(sca_callee callee, uint32_t sleep_cycles,
306  bool sw_trigger, bool otbn);
307 
308 /**
309  * Seeds the software LFSR usable e.g. for key masking.
310  *
311  * This functions seeds the Galois XOR type LFSR with the provided seed value.
312  * Note that the LFSR itself has very low diffusion.
313  *
314  * @param seed The new seed value.
315  * @param context Specifies which LFSR to seed.
316  */
317 void pentest_seed_lfsr(uint32_t seed, pentest_lfsr_context_t context);
318 
319 /**
320  * Steps the software LFSR usable e.g. for key masking `num_steps` times.
321  *
322  * This function steps the Galois XOR type LFSR n times. Note that the LFSR
323  * itself has very low diffusion. To improve the statistical properties, the
324  * multiple steps can be run. For example, by running 32 steps it can be
325  * ensured that each state bit depends on at least two previous state bits.
326  *
327  * @param num_steps The number of steps to run.
328  * @param context Specifies which LFSR to run.
329 
330  * @return The current state of the LFSR.
331  */
332 uint32_t pentest_next_lfsr(uint16_t num_steps, pentest_lfsr_context_t context);
333 
334 /**
335  * Applies a linear layer.
336  *
337  * This function feeds the input through a linear permutation layer. This is
338  * suitable to ensure 1) that adjacent output bits of the software LFSR do not
339  * go into the same S-Box (see `pentest_non_linear_layer()`) and 2) that the
340  * output of S-Box(n) is not always going to be equal to the output of
341  * S-Box(n+1) in the subsequent cycle. For details on how this can be achieved,
342  * refer to the corresponding hardware implementation in
343  * hw/ip/prim/rtl/prim_lfsr.sv.
344  *
345  * @param input The input value.
346  *
347  * @return The output of the linear layer.
348  *
349  */
350 uint32_t pentest_linear_layer(uint32_t input);
351 
352 /**
353  * Applies a non-linear layer.
354  *
355  * This function feeds the input through a non-linear layer. It is suitable to
356  * improve the statistical properties of the software LFSR usable for key
357  * masking, see `pentest_seed_lfsr()` and `pentest_next_lfsr()`. Internally, a
358  * LUT-based AES S-Box is applied to the invididual bytes of the input word.
359  *
360  * In addition, the ouput bytes are XORed with the sbox[0]. This is useful to
361  * ensure an all-zero seed (used to switch off key masking) also results in an
362  * all-zero output of the non-linear layer.
363  *
364  * @param input The input value.
365  *
366  * @return The output of the non-linear layer.
367  *
368  */
369 uint32_t pentest_non_linear_layer(uint32_t input);
370 
371 #endif // OPENTITAN_SW_DEVICE_TESTS_PENETRATIONTESTS_FIRMWARE_LIB_PENTEST_LIB_H_