Software APIs
power_virus_systemtest.c
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 #include "dt/dt_api.h" // Generated
6 #include "hw/ip/aes/model/aes_modes.h"
8 #include "sw/device/lib/base/multibits.h"
12 #include "sw/device/lib/dif/dif_csrng_shared.h"
29 #include "sw/device/lib/testing/aes_testutils.h"
30 #include "sw/device/lib/testing/entropy_testutils.h"
31 #include "sw/device/lib/testing/hmac_testutils.h"
32 #include "sw/device/lib/testing/i2c_testutils.h"
33 #include "sw/device/lib/testing/otbn_testutils_rsa.h"
34 #include "sw/device/lib/testing/pinmux_testutils.h"
35 #include "sw/device/lib/testing/spi_device_testutils.h"
36 #include "sw/device/lib/testing/spi_host_testutils.h"
37 #include "sw/device/lib/testing/test_framework/check.h"
38 #include "sw/device/lib/testing/test_framework/ottf_macros.h"
40 
41 #include "adc_ctrl_regs.h" // Generated.
42 #include "aes_regs.h" // Generated.
43 #include "csrng_regs.h" // Generated.
44 #include "entropy_src_regs.h" // Generated.
45 #include "gpio_regs.h" // Generated.
46 #include "hmac_regs.h" // Generated.
48 #include "i2c_regs.h" // Generated.
49 #include "kmac_regs.h" // Generated.
50 #include "pattgen_regs.h" // Generated.
51 #include "pwm_regs.h" // Generated.
52 #include "spi_host_regs.h" // Generated.
53 #include "uart_regs.h" // Generated.
54 
55 OTTF_DEFINE_TEST_CONFIG(.enable_concurrency = true,
56  .enable_uart_flow_control = true);
57 
58 /**
59  * Peripheral DIF Handles.
60  */
61 static dif_pinmux_t pinmux;
62 static dif_gpio_t gpio;
63 static dif_adc_ctrl_t adc_ctrl;
64 static dif_entropy_src_t entropy_src;
65 static dif_csrng_t csrng;
66 static dif_edn_t edn_0;
67 static dif_edn_t edn_1;
68 static dif_aes_t aes;
69 static dif_hmac_t hmac;
70 static dif_kmac_t kmac;
71 static dif_otbn_t otbn;
72 static dif_i2c_t i2c_0;
73 static dif_i2c_t i2c_1;
74 static dif_i2c_t i2c_2;
75 static dif_spi_device_handle_t spi_device;
76 static dif_spi_host_t spi_host_0;
77 static dif_spi_host_t spi_host_1;
78 static dif_uart_t uart_1;
79 static dif_uart_t uart_2;
80 static dif_uart_t uart_3;
81 static dif_pattgen_t pattgen;
82 static dif_pwm_t pwm;
83 static dif_flash_ctrl_state_t flash_ctrl;
84 static dif_rv_plic_t rv_plic;
85 
86 static const dif_i2c_t *i2c_handles[] = {&i2c_0, &i2c_1, &i2c_2};
87 static const dif_uart_t *uart_handles[] = {&uart_1, &uart_2, &uart_3};
88 static dif_kmac_operation_state_t kmac_operation_state;
89 static const dif_pattgen_channel_t pattgen_channels[] = {kDifPattgenChannel0,
90  kDifPattgenChannel1};
91 static const dif_pwm_channel_t pwm_channels[PWM_PARAM_N_OUTPUTS] = {
92  kDifPwmChannel0, kDifPwmChannel1, kDifPwmChannel2,
93  kDifPwmChannel3, kDifPwmChannel4, kDifPwmChannel5,
94 };
95 
96 /**
97  * Test configuration parameters.
98  */
99 enum {
100  /**
101  * Maximum number of test iterations in silicon targets.
102  */
103  kMaxIterationsSilicon = 1000,
104  /**
105  * Test timeout parameter.
106  */
107  kTestTimeoutMicros = 1000, // 1ms
108  /**
109  * ADC controller parameters.
110  */
111  kAdcCtrlPowerUpTimeAonCycles = 15, // maximum power-up time
112  /**
113  * Entropy Source parameters.
114  */
115  kEntropySrcHealthTestWindowSize = 0x60,
116  kEntropySrcAdaptiveProportionHealthTestHighThreshold = 0x50,
117  kEntropySrcAdaptiveProportionHealthTestLowThreshold = 0x10,
118  /**
119  * EDN parameters.
120  */
121  kEdn0SeedMaterialNumWords = 0,
122  kEdn1SeedMaterialNumWords = 12,
123  kEdn0ReseedInterval = 64,
124  kEdn1ReseedInterval = 16,
125  /**
126  * KMAC parameters.
127  */
128  kKmacEntropyReseedInterval = 1,
129  kKmacEntropyHashThreshold = 1, // KMAC operations between entropy requests
130  kKmacEntropyWaitTimer = 0xffff,
131  kKmacEntropyPrescaler = 0x3ff,
132  kKmacMessageLength = 200,
133  kKmacDigestLength = 16,
134  /**
135  * I2C parameters.
136  */
137  kI2CSpeedMode = kDifI2cSpeedFastPlus,
138  kI2cSclPeriodNs = 1000,
139  kI2cSdaRiseFallTimeNs = 10,
140  kI2cDeviceMask = 0x7f,
141  kI2c0DeviceAddress0 = 0x11,
142  kI2c0DeviceAddress1 = 0x22,
143  kI2c1DeviceAddress0 = 0x33,
144  kI2c1DeviceAddress1 = 0x44,
145  kI2c2DeviceAddress0 = 0x55,
146  kI2c2DeviceAddress1 = 0x66,
147  kI2c0TargetAddress = 0x01,
148  kI2c1TargetAddress = 0x02,
149  kI2c2TargetAddress = 0x03,
150  /**
151  * UART parameters.
152  */
153  kUartFifoDepth = 32,
154  /**
155  * Pattern Generator parameters.
156  */
157  kPattgenClockDivisor = 0,
158  kPattgenSeedPatternLowerWord = 0xaaaaaaaa,
159  kPattgenSeedPatternUpperWord = 0xaaaaaaaa,
160  kPattgenSeedPatternLength = 64,
161  kPattgenNumPatternRepetitions = 1024,
162  /**
163  * PWM parameters.
164  */
165  kPwmClockDivisor = 1,
166  kPwmBeatsPerCycle = 2,
167  kPwmOnBeats = 1,
168  kPwmPhaseDelayBeats = 0,
169  /**
170  * SPI Host parameters.
171  */
172  // In chip.sv, only csid[0] is connected to a mio, the other wires
173  // are fixed to 1'b1.
174  kSpiHost1Csid = 0x0,
175  kSpiHost1TxDataWord = 0xaaaaaaaa,
176 };
177 
178 typedef enum power_virus_test_stage {
179  kPowerVirusTestStageCryptoDataLoad,
180  kPowerVirusTestStageCommsDataLoad,
181  kPowerVirusTestStageMaxPower,
182  kPowerVirusTestStageComplete,
183 } power_virus_test_stage_t;
184 
185 power_virus_test_stage_t test_stage;
186 
187 static uint32_t csrng_instantiate_cmd_header;
188 
189 /**
190  * The peripheral clock of I2C IP (in nanoseconds)
191  * In the DV sequence and in test_main(),
192  * it is dynamically computed from kClockFreqPeripheralHz
193  */
194 static volatile uint32_t peripheral_clock_period_ns;
195 
196 /**
197  * The mask share, used to mask kAesKey.
198  */
199 static const uint8_t kAesKeyShare1[] = {
200  0x0f, 0x1f, 0x2f, 0x3f, 0x4f, 0x5f, 0x6f, 0x7f, 0x8f, 0x9f, 0xaf,
201  0xbf, 0xcf, 0xdf, 0xef, 0xff, 0x0a, 0x1a, 0x2a, 0x3a, 0x4a, 0x5a,
202  0x6a, 0x7a, 0x8a, 0x9a, 0xaa, 0xba, 0xca, 0xda, 0xea, 0xfa,
203 };
204 
205 static const dif_kmac_key_t kKmacKey = {
206  .share0 = {0x43424140, 0x47464544, 0x4B4A4948, 0x4F4E4D4C, 0x53525150,
207  0x57565554, 0x5B5A5958, 0x5F5E5D5C},
208  .share1 = {0},
209  .length = kDifKmacKeyLen256,
210 };
211 
212 static const char *kKmacMessage =
213  "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
214  "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
215  "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
216  "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
217  "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
218  "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
219  "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
220  "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
221  "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
222  "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
223  "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
224  "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
225  "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7";
226 
227 static const uint32_t kKmacDigest[] = {
228  0xF71886B5, 0xD5E1921F, 0x558C1B6C, 0x18CDD7DD, 0xCAB4978B, 0x1E83994D,
229  0x839A69B2, 0xD9E4A27D, 0xFDACFB70, 0xAE3300E5, 0xA2F185A5, 0xC3108570,
230  0x0888072D, 0x2818BD01, 0x6847FE98, 0x6589FC76};
231 
232 // Randomly generated public key modulus with public exponent 65537.
233 static uint32_t kRsa2KModulus[] = {
234  0x40d984b1, 0x3611356d, 0x9eb2f35c, 0x031a892c, 0x16354662, 0x6a260bad,
235  0xb2b807d6, 0xb7de7ccb, 0x278492e0, 0x41adab06, 0x9e60110f, 0x1414eeff,
236  0x8b80e14e, 0x5eb5ae79, 0x0d98fa5b, 0x58bece1f, 0xcf6bdca8, 0x82f5611f,
237  0x351e3869, 0x075005d6, 0xe813fe23, 0xdd967a37, 0x682d1c41, 0x9fdd2d8c,
238  0x21bdd5fc, 0x4fc459c7, 0x508c9293, 0x1f9ac759, 0x55aacb04, 0x58389f05,
239  0x0d0b00fb, 0x59bb4141, 0x68f9e0bf, 0xc2f1a546, 0x0a71ad19, 0x9c400301,
240  0xa4f8ecb9, 0xcdf39538, 0xaabe9cb0, 0xd9f7b2dc, 0x0e8b292d, 0x8ef6c717,
241  0x720e9520, 0xb0c6a23e, 0xda1e92b1, 0x8b6b4800, 0x2f25082b, 0x7f2d6711,
242  0x426fc94f, 0x9926ba5a, 0x89bd4d2b, 0x977718d5, 0x5a8406be, 0x87d090f3,
243  0x639f9975, 0x5948488b, 0x1d3d9cd7, 0x28c7956b, 0xebb97a3e, 0x1edbf4e2,
244  0x105cc797, 0x924ec514, 0x146810df, 0xb1ab4a49,
245 };
246 
247 // Valid PKCS1v1.5 signature of "Test message." using SHA-256 as the hash
248 // function.
249 static const uint32_t kRsa2KSignature[] = {
250  0xab66c6c7, 0x97effc0a, 0x9869cdba, 0x7b6c09fe, 0x2124d28f, 0x793084b3,
251  0x4da24b72, 0x4f6c8659, 0x63e3a27b, 0xbbe8d120, 0x8789190f, 0x1722fe46,
252  0x25573178, 0x3accbdb3, 0x1eb7ca00, 0xe8eb40aa, 0x1d3b21a8, 0x9997925e,
253  0x1793f81d, 0x12728f54, 0x66e40608, 0x4b1057a0, 0xba433eb3, 0x702c73b2,
254  0xa9391740, 0xf838710f, 0xf33cf109, 0x595cee1d, 0x07341be9, 0xcfce52b1,
255  0x5b48ba7a, 0xf70e5a0e, 0xdbb98c42, 0x85fd6979, 0xcdb760fc, 0xd2e09553,
256  0x70bba417, 0x04e52609, 0xc215420e, 0x2407242e, 0x4f19674b, 0x5d996a9d,
257  0xf2fb1d05, 0x88e0fc14, 0xe1a38f0c, 0xd111935d, 0xd23bf5b3, 0xdcd7a882,
258  0x0f242315, 0xd7247d51, 0xc247d6ec, 0xe2492739, 0x3dfb115c, 0x031aea7a,
259  0xcdcb09c0, 0x29318ddb, 0xd0a10dd8, 0x3307018e, 0xe13c5616, 0x98d4db80,
260  0x50692a42, 0x41e94a74, 0x0a6f79eb, 0x1c405c66,
261 };
262 
263 // PKCS1v1.5 encoding of "Test message." using SHA-256 as the hash function.
264 static const uint32_t kRsa2KEncodedMessage[] = {
265  0x20b50917, 0xdc72a118, 0xd13b02ca, 0x4bc0a4ca, 0x807ce588, 0x43e1f083,
266  0x966ee07c, 0xb2da997a, 0x05000420, 0x03040201, 0x86480165, 0x0d060960,
267  0x00303130, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
268  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
269  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
270  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
271  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
272  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
273  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
274  0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
275  0xffffffff, 0xffffffff, 0xffffffff, 0x0001ffff,
276 };
277 
278 static const uint8_t kUartMessage[] = {
279  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
280  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
281  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
282 };
283 
284 static const uint8_t kI2cMessage[] = {
285  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
286  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
287  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
288  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
289  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
290  0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
291 };
292 
293 static void log_entropy_src_alert_failures(void) {
295  CHECK_DIF_OK(dif_entropy_src_get_alert_fail_counts(&entropy_src, &counts));
296  LOG_INFO("Entropy source health test failure encountered.");
297  LOG_INFO("Total Fails: %d", counts.total_fails);
298  for (size_t i = 0; i < kDifEntropySrcTestNumVariants; ++i) {
299  switch (i) {
301  LOG_INFO("Fails (Repetition Count): %d", counts.high_fails[i]);
302  break;
304  LOG_INFO("Fails (Repetition Symbol Count): %d", counts.high_fails[i]);
305  break;
307  LOG_INFO("High Fails (Adaptive Proportion): %d", counts.high_fails[i]);
308  LOG_INFO("Low Fails (Adaptive Proportion): %d", counts.low_fails[i]);
309  break;
311  LOG_INFO("Fails (Bucket): %d", counts.high_fails[i]);
312  break;
314  LOG_INFO("High Fails (Markov): %d", counts.high_fails[i]);
315  LOG_INFO("Low Fails (Markov): %d", counts.low_fails[i]);
316  break;
318  LOG_INFO("High Fails (Mailbox): %d", counts.high_fails[i]);
319  LOG_INFO("Low Fails (Mailbox): %d", counts.low_fails[i]);
320  break;
321  }
322  }
323 }
324 
325 /**
326  * External (OTTF) ISR override.
327  */
328 void ottf_external_isr(uint32_t *exc_info) {
329  // Find which interrupt fired at PLIC by claiming it.
330  dif_rv_plic_irq_id_t irq_id;
331  CHECK_DIF_OK(
333 
336  switch (periph) {
338  log_entropy_src_alert_failures();
339  CHECK(false);
340  break;
341  default:
342  CHECK(false, "Unexpected IRQ fired with ID: %d", irq_id);
343  break;
344  }
345 }
346 
347 /**
348  * Initializes all DIF handles for each peripheral used in this test.
349  */
350 static void init_peripheral_handles(void) {
351  CHECK_DIF_OK(dif_adc_ctrl_init(
353  CHECK_DIF_OK(
355  CHECK_DIF_OK(dif_csrng_init(
357  CHECK_DIF_OK(
358  dif_edn_init(mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR), &edn_0));
359  CHECK_DIF_OK(
360  dif_edn_init(mmio_region_from_addr(TOP_EARLGREY_EDN1_BASE_ADDR), &edn_1));
361  CHECK_DIF_OK(dif_entropy_src_init(
363  CHECK_DIF_OK(
364  dif_hmac_init(mmio_region_from_addr(TOP_EARLGREY_HMAC_BASE_ADDR), &hmac));
365  CHECK_DIF_OK(
366  dif_gpio_init(mmio_region_from_addr(TOP_EARLGREY_GPIO_BASE_ADDR), &gpio));
367  CHECK_DIF_OK(
368  dif_kmac_init(mmio_region_from_addr(TOP_EARLGREY_KMAC_BASE_ADDR), &kmac));
369  CHECK_DIF_OK(dif_pinmux_init(
371  // UART 0 is already configured (and used) by the OTTF.
372  CHECK_DIF_OK(dif_uart_init(
374  CHECK_DIF_OK(dif_uart_init(
376  CHECK_DIF_OK(dif_uart_init(
378  CHECK_DIF_OK(
379  dif_i2c_init(mmio_region_from_addr(TOP_EARLGREY_I2C0_BASE_ADDR), &i2c_0));
380  CHECK_DIF_OK(
381  dif_i2c_init(mmio_region_from_addr(TOP_EARLGREY_I2C1_BASE_ADDR), &i2c_1));
382  CHECK_DIF_OK(
383  dif_i2c_init(mmio_region_from_addr(TOP_EARLGREY_I2C2_BASE_ADDR), &i2c_2));
384  CHECK_DIF_OK(dif_spi_device_init_handle(
386  CHECK_DIF_OK(dif_spi_host_init(
388  CHECK_DIF_OK(dif_spi_host_init(
390  CHECK_DIF_OK(
391  dif_otbn_init(mmio_region_from_addr(TOP_EARLGREY_OTBN_BASE_ADDR), &otbn));
392  CHECK_DIF_OK(dif_pattgen_init(
394  CHECK_DIF_OK(dif_pwm_init(
396  CHECK_DIF_OK(dif_flash_ctrl_init_state(
397  &flash_ctrl,
399  CHECK_DIF_OK(dif_rv_plic_init(
401 }
402 
403 static void configure_pinmux(void) {
404  // Configure UART0 (console) and SW strapping pins.
405  pinmux_testutils_init(&pinmux);
406 
407  // Configure GPIO max-power period indicator pin on IOB8.
410 
411  // UART1:
412  // RX on IOA4
413  // TX on IOA5
414  CHECK_DIF_OK(dif_pinmux_input_select(&pinmux,
421 
422  // Apply this configuration only for the FPGA.
423  // For the simulation, apply the config in configure_pinmux_sim().
425  // UART2:
426  // RX on IOB4
427  // TX on IOB5
428  CHECK_DIF_OK(dif_pinmux_input_select(&pinmux,
431  CHECK_DIF_OK(
436  }
437 
438  // UART3:
439  // RX on IOA0
440  // TX on IOA1
441  CHECK_DIF_OK(dif_pinmux_input_select(&pinmux,
448 
449  // I2C0:
450  // SDA on IOA7
451  // SCL on IOA8
452  CHECK_DIF_OK(dif_pinmux_input_select(&pinmux,
455  CHECK_DIF_OK(dif_pinmux_input_select(&pinmux,
462 
463  // I2C1:
464  // SCL on IOB9
465  // SDA on IOB10
466  CHECK_DIF_OK(dif_pinmux_input_select(&pinmux,
469  CHECK_DIF_OK(dif_pinmux_input_select(&pinmux,
476 
477  // I2C2:
478  // SCL on IOB11
479  // SDA on IOB12
480  CHECK_DIF_OK(dif_pinmux_input_select(&pinmux,
483  CHECK_DIF_OK(dif_pinmux_input_select(&pinmux,
490 
491  // PATTGEN:
492  // Channel 0 PDA on IOR0
493  // Channel 0 PCL on IOR1
494  // Channel 1 PDA on IOR2
495  // Channel 1 PCL on IOR3
504 
505  // PWM:
506  // Channel 0 on IOB1
507  // Channel 1 on IOB2
508  // Channel 2 on IOR5
509  // Channel 3 on IOR6
510  // Channel 4 on IOR7
511  // Channel 5 on IOR10
512  // Apply this channel 0 configuration only for the FPGA.
513  // For the simulation, apply the config in configure_pinmux_sim().
517  }
528 
529  // Apply this configuration only for the FPGA.
530  // For the simulation, apply the config in configure_pinmux_sim().
532  // SPI Host 1:
533  // CSB on IOB0
534  // SCK on IOB3
535  // SD0 on IOA2
536  // SD1 on IOR11
537  // SD2 on IOR12
538  // SD3 on IOR13
545  CHECK_DIF_OK(dif_pinmux_output_select(&pinmux,
548  CHECK_DIF_OK(dif_pinmux_output_select(&pinmux,
551  CHECK_DIF_OK(dif_pinmux_output_select(&pinmux,
554  CHECK_DIF_OK(dif_pinmux_input_select(
557  CHECK_DIF_OK(dif_pinmux_input_select(
560  CHECK_DIF_OK(dif_pinmux_input_select(
563  CHECK_DIF_OK(dif_pinmux_input_select(
566  }
567 }
568 
569 /**
570  * Configures pins for DVsim.
571  * In chip_if.sv, agents and interfaces are connected to fixed pins.
572  * To be able to use the agents (e.g, spi_device_agent1), the C code's pinmux
573  * settings must be compatible with the settings in chip_if.sv.
574  */
575 static void configure_pinmux_sim(void) {
576  /**
577  * Pinmux pad configurations for simulation.
578  */
580  // Enable pull-ups for spi_host_0 data pins to avoid floating inputs.
581  {
582  .pad = kDtPadSpiHost0Sd0,
583  .flags = kDifPinmuxPadAttrPullResistorEnable |
584  kDifPinmuxPadAttrPullResistorUp,
585  },
586  {
587  .pad = kDtPadSpiHost0Sd1,
588  .flags = kDifPinmuxPadAttrPullResistorEnable |
589  kDifPinmuxPadAttrPullResistorUp,
590  },
591  {
592  .pad = kDtPadSpiHost0Sd2,
593  .flags = kDifPinmuxPadAttrPullResistorEnable |
594  kDifPinmuxPadAttrPullResistorUp,
595  },
596  {
597  .pad = kDtPadSpiHost0Sd3,
598  .flags = kDifPinmuxPadAttrPullResistorEnable |
599  kDifPinmuxPadAttrPullResistorUp,
600  },
601  // Enable pull-ups for spi_host_1 data pins to avoid floating inputs.
602  {
603  .pad = kDtPadIob3, // SD0
604  .flags = kDifPinmuxPadAttrPullResistorEnable |
605  kDifPinmuxPadAttrPullResistorUp,
606  },
607  {
608  .pad = kDtPadIob4, // SD1
609  .flags = kDifPinmuxPadAttrPullResistorEnable |
610  kDifPinmuxPadAttrPullResistorUp,
611  },
612  {
613  .pad = kDtPadIob5, // SD2
614  .flags = kDifPinmuxPadAttrPullResistorEnable |
615  kDifPinmuxPadAttrPullResistorUp,
616  },
617  {
618  .pad = kDtPadIob6, // SD3
619  .flags = kDifPinmuxPadAttrPullResistorEnable |
620  kDifPinmuxPadAttrPullResistorUp,
621  },
622  };
623 
624  // Enable pull-ups for SPI_HOST_0/1 data pins to avoid floating inputs.
625  pinmux_testutils_configure_pads(&pinmux, pinmux_pad_attributes,
627 
628  // SPI Host 1 (from chip_if.sv):
629  // CSB on IOB1
630  // SCK on IOB0
631  // SD0 on IOB3
632  // SD1 on IOB4
633  // SD2 on IOB5
634  // SD3 on IOB6
647  CHECK_DIF_OK(dif_pinmux_input_select(
650  CHECK_DIF_OK(dif_pinmux_input_select(
653  CHECK_DIF_OK(dif_pinmux_input_select(
656  CHECK_DIF_OK(dif_pinmux_input_select(
659 
660  // UART2 (simulation):
661  // On FPGA, UART2 uses IOB4/IOB5 as RX/TX.
662  // In chip_if.sv, IOB4/IOB5 are connected to the spi_device_agent1.
663  // To prevent contamination in DVSIM, switch UART2 RX/TX to other MIOs.
664  // RX on IOR12
665  // TX on IOR11
666  CHECK_DIF_OK(dif_pinmux_input_select(&pinmux,
673 
674  // PWM (Simulation):
675  // On FPGA, PWM channel 0 uses IOB1.
676  // In chip_if.sv, IOB1 is connected to the spi_device_agent1.
677  // To prevent contamination in DVSIM, switch PWM 0 to another available MIO.
678  // Channel 0 on IOR11
681 
682  // Configure fast slew rate, strong drive strength, and weak pull-ups for SPI
683  // Host 0 pads.
684  CHECK_STATUS_OK(spi_host_testutils_configure_host0_pad_attrs(&pinmux));
685 
686  // Configure fast slew rate and strong drive strength for SPI device pads.
687  CHECK_STATUS_OK(spi_device_testutils_configure_pad_attrs(&pinmux));
688 }
689 
690 /**
691  * Configures adc_ctrl to continuously sample data (applying all filters across
692  * both channels) in normal power mode, which is the most power intensive
693  * sampling mode.
694  */
695 static void configure_adc_ctrl_to_continuously_sample(void) {
696  CHECK_DIF_OK(dif_adc_ctrl_configure(
697  &adc_ctrl,
700  .power_up_time_aon_cycles = kAdcCtrlPowerUpTimeAonCycles,
701  // Below configurations are unused, so set them to their reset
702  // values.
703  .wake_up_time_aon_cycles = ADC_CTRL_ADC_PD_CTL_WAKEUP_TIME_MASK,
704  .num_low_power_samples = ADC_CTRL_ADC_LP_SAMPLE_CTL_REG_RESVAL,
705  .num_normal_power_samples = ADC_CTRL_ADC_SAMPLE_CTL_REG_RESVAL,
706  }));
707  for (size_t filter = 0; filter < ADC_CTRL_PARAM_NUM_ADC_FILTER; ++filter) {
708  for (size_t channel = 0; channel < ADC_CTRL_PARAM_NUM_ADC_CHANNEL;
709  ++channel) {
710  CHECK_DIF_OK(dif_adc_ctrl_configure_filter(
711  &adc_ctrl, (dif_adc_ctrl_channel_t)channel,
713  .filter = (dif_adc_ctrl_filter_t)filter,
714  // Set max range.
715  .min_voltage = 0,
716  .max_voltage = ADC_CTRL_ADC_CHN0_FILTER_CTL_0_MAX_V_0_MASK,
717  .in_range = true,
718  .generate_wakeup_on_match = false,
719  .generate_irq_on_match = false,
720  },
722  }
723  }
724 }
725 
726 static void configure_entropy_complex(void) {
727  // The (test) ROM enables the entropy complex, and to reconfigure it
728  // requires temporarily disabling it.
729  CHECK_STATUS_OK(entropy_testutils_stop_all());
730 
731  // Enable entropy_src interrupts for health-test alert detection.
732  CHECK_DIF_OK(dif_rv_plic_irq_set_priority(
734  CHECK_DIF_OK(dif_rv_plic_irq_set_enabled(
737  CHECK_DIF_OK(dif_entropy_src_irq_set_enabled(
738  &entropy_src, kDifEntropySrcIrqEsHealthTestFailed, kDifToggleEnabled));
739 
740  // Configure entropy_src and health tests.
742  &entropy_src, (dif_entropy_src_health_test_config_t){
744  .high_threshold = 0xf,
745  .low_threshold = 0}));
747  &entropy_src, (dif_entropy_src_health_test_config_t){
749  .high_threshold = 0xf,
750  .low_threshold = 0}));
752  &entropy_src,
755  .high_threshold =
756  kEntropySrcAdaptiveProportionHealthTestHighThreshold,
757  .low_threshold =
758  kEntropySrcAdaptiveProportionHealthTestLowThreshold}));
760  &entropy_src, (dif_entropy_src_health_test_config_t){
761  .test_type = kDifEntropySrcTestBucket,
762  .high_threshold = 0xff,
763  .low_threshold = 0}));
765  &entropy_src, (dif_entropy_src_health_test_config_t){
766  .test_type = kDifEntropySrcTestMarkov,
767  .high_threshold = 0xff,
768  .low_threshold = 0}));
770  &entropy_src,
772  .entropy_insert_enable = false,
773  .buffer_threshold = ENTROPY_SRC_OBSERVE_FIFO_THRESH_REG_RESVAL,
774  },
776  CHECK_DIF_OK(dif_entropy_src_configure(
777  &entropy_src,
779  .fips_enable = true,
780  .fips_flag = true,
781  .rng_fips = true,
782  .route_to_firmware = false,
783  .bypass_conditioner = false,
784  .single_bit_mode = kDifEntropySrcSingleBitModeDisabled,
785  .health_test_threshold_scope = false,
786  .health_test_window_size = kEntropySrcHealthTestWindowSize,
787  .alert_threshold = UINT16_MAX},
789 
790  // Configure CSRNG and create instantiate command header for later use during
791  // max power epoch.
792  CHECK_DIF_OK(dif_csrng_configure(&csrng));
793  csrng_instantiate_cmd_header = csrng_cmd_header_build(
794  kCsrngAppCmdInstantiate, kDifCsrngEntropySrcToggleEnable, /*cmd_len=*/0,
795  /*generate_len=*/0);
796 
797  // Configure EDNs in auto mode.
798  dif_edn_seed_material_t edn_empty_seed = {
799  .len = kEdn0SeedMaterialNumWords,
800  };
801  dif_edn_seed_material_t edn_384_bit_seed = {
802  .len = kEdn1SeedMaterialNumWords,
803  .data = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
804  };
805  dif_edn_auto_params_t edn_auto_params = {
806  .instantiate_cmd =
807  {
808  .cmd = csrng_cmd_header_build(kCsrngAppCmdInstantiate,
810  /*cmd_len=*/edn_384_bit_seed.len,
811  /*generate_len=*/0),
812  .seed_material = edn_384_bit_seed,
813  },
814  .reseed_cmd =
815  {
816  .cmd = csrng_cmd_header_build(
817  kCsrngAppCmdReseed, kDifCsrngEntropySrcToggleEnable,
818  /*cmd_len=*/edn_384_bit_seed.len, /*generate_len=*/0),
819  .seed_material = edn_384_bit_seed,
820  },
821  .generate_cmd =
822  {
823  // The the generate_len to 1 to force CSRNG reseeds to occur more
824  // often. Setting this to a large value may cause the test case to
825  // fail. See `check_ip_activity()` in
826  // `chip_sw_power_virus_vseq.sv` for more details.
827  .cmd = csrng_cmd_header_build(kCsrngAppCmdGenerate,
829  /*cmd_len=*/0,
830  /*generate_len=*/1),
831  .seed_material = edn_empty_seed,
832  },
833  .reseed_interval = 0,
834  };
835  // EDN0 provides lower-quality entropy. Let one generate command return
836  // eight 128-bit blocks, and reseed every 128 generates.
837  edn_auto_params.reseed_interval = kEdn0ReseedInterval;
838  CHECK_DIF_OK(dif_edn_set_auto_mode(&edn_0, edn_auto_params));
839  // EDN1 provides higher-quality entropy. Let one generate command return
840  // eight 128-bit blocks, and reseed every 32 generates.
841  edn_auto_params.reseed_interval = kEdn1ReseedInterval;
842  CHECK_DIF_OK(dif_edn_set_auto_mode(&edn_1, edn_auto_params));
843  CHECK_DIF_OK(dif_edn_configure(&edn_0));
844  CHECK_DIF_OK(dif_edn_configure(&edn_1));
845 }
846 
847 static status_t configure_aes(void) {
848  // Prepare and load AES key shares.
849  uint8_t aes_key_share0[sizeof(kAesModesKey256)];
850  for (size_t i = 0; i < sizeof(kAesModesKey256); ++i) {
851  aes_key_share0[i] = kAesModesKey256[i] ^ kAesKeyShare1[i];
852  }
854  memcpy(aes_key.share0, aes_key_share0, sizeof(aes_key.share0));
855  memcpy(aes_key.share1, kAesKeyShare1, sizeof(aes_key.share1));
856 
857  // Prepare and load AES IV.
858  dif_aes_iv_t aes_iv;
859  memcpy(aes_iv.iv, kAesModesIvCbc, sizeof(aes_iv.iv));
860 
861  // Setup AES in automatic, 256-bit SW provided key, CBC encryption mode.
862  // Additionally, we want to keep the entropy complex busing by constantly
863  // reseeding PRNGs.
864  dif_aes_transaction_t aes_transaction_cfg = {
865  .operation = kDifAesOperationEncrypt,
866  .mode = kDifAesModeCbc,
867  .key_len = kDifAesKey256,
868  .key_provider = kDifAesKeySoftwareProvided,
869  .mask_reseeding = kDifAesReseedPerBlock,
870  .manual_operation = kDifAesManualOperationManual,
871  .reseed_on_key_change = false,
872  .ctrl_aux_lock = false,
873  };
874 
875  // Start the AES operation. Since we are in manual-mode, the encryption will
876  // not start until plain text data is loaded into the appropriate CSRs, and
877  // the encryption operation is triggered.
878  AES_TESTUTILS_WAIT_FOR_STATUS(&aes, kDifAesStatusIdle, true,
879  kTestTimeoutMicros);
880  CHECK_DIF_OK(dif_aes_start(&aes, &aes_transaction_cfg, &aes_key, &aes_iv));
881  return OK_STATUS();
882 }
883 
884 static void configure_hmac(void) {
885  dif_hmac_transaction_t hmac_transaction_cfg = {
887  .message_endianness = kDifHmacEndiannessLittle,
888  };
889  // Use HMAC in SHA256 mode to generate a 256bit key from `kHmacRefLongKey`.
890  CHECK_DIF_OK(dif_hmac_mode_sha256_start(&hmac, hmac_transaction_cfg));
891  CHECK_STATUS_OK(hmac_testutils_push_message(&hmac, (char *)kHmacRefLongKey,
892  sizeof(kHmacRefLongKey)));
893  CHECK_STATUS_OK(
894  hmac_testutils_check_message_length(&hmac, sizeof(kHmacRefLongKey) * 8));
895  CHECK_DIF_OK(dif_hmac_process(&hmac));
896  dif_hmac_digest_t hmac_key_digest;
897  CHECK_STATUS_OK(hmac_testutils_finish_polled(&hmac, &hmac_key_digest));
898 
899  // Configure the HMAC in HMAC mode.
900  CHECK_DIF_OK(dif_hmac_mode_hmac_start(
901  &hmac, (uint8_t *)&hmac_key_digest.digest[0], hmac_transaction_cfg));
902 }
903 
904 static void configure_kmac(void) {
906  .entropy_mode = kDifKmacEntropyModeEdn,
907  .entropy_fast_process = kDifToggleDisabled,
908  .entropy_hash_threshold = kKmacEntropyHashThreshold,
909  .entropy_wait_timer = kKmacEntropyWaitTimer,
910  .entropy_prescaler = kKmacEntropyPrescaler,
911  .message_big_endian = false,
912  .output_big_endian = false,
913  .sideload = false,
914  .msg_mask = false,
915  };
916  CHECK_DIF_OK(dif_kmac_configure(&kmac, kmac_cfg));
917 }
918 
919 static void configure_uart(dif_uart_t *uart) {
920  CHECK(kUartBaudrate <= UINT32_MAX, "kUartBaudrate must fit in uint32_t");
921  CHECK(kClockFreqPeripheralHz <= UINT32_MAX,
922  "kClockFreqPeripheralHz must fit in uint32_t");
923  CHECK_DIF_OK(dif_uart_configure(
924  uart, (dif_uart_config_t){
925  .baudrate = (uint32_t)kUartBaudrate,
926  .clk_freq_hz = (uint32_t)kClockFreqPeripheralHz,
927  .parity_enable = kDifToggleEnabled,
928  .parity = kDifUartParityEven,
929  .tx_enable = kDifToggleDisabled,
930  .rx_enable = kDifToggleDisabled,
931  }));
932  CHECK_DIF_OK(
934 }
935 
936 static void configure_i2c(dif_i2c_t *i2c, uint8_t device_addr_0,
937  uint8_t device_addr_1) {
938  dif_i2c_config_t config;
939 
940  CHECK_DIF_OK(dif_i2c_compute_timing(
942  .lowest_target_device_speed = kI2CSpeedMode,
943  .clock_period_nanos = peripheral_clock_period_ns,
944  .sda_rise_nanos = kI2cSdaRiseFallTimeNs,
945  .sda_fall_nanos = kI2cSdaRiseFallTimeNs,
946  .scl_period_nanos = kI2cSclPeriodNs},
947  &config));
948  CHECK_DIF_OK(dif_i2c_configure(i2c, config));
949  dif_i2c_id_t id_0 = {.mask = kI2cDeviceMask, .address = device_addr_0};
950  dif_i2c_id_t id_1 = {.mask = kI2cDeviceMask, .address = device_addr_1};
951  CHECK_DIF_OK(dif_i2c_set_device_id(i2c, &id_0, &id_1));
953 }
954 
955 static void configure_spi_host(const dif_spi_host_t *spi_host, bool enable) {
956  CHECK(kClockFreqHiSpeedPeripheralHz <= UINT32_MAX,
957  "kClockFreqHiSpeedPeripheralHz must fit in uint32_t");
958 
959  CHECK_DIF_OK(dif_spi_host_configure(
960  spi_host,
962  .spi_clock = (uint32_t)kClockFreqHiSpeedPeripheralHz / 2,
963  .peripheral_clock_freq_hz = (uint32_t)kClockFreqHiSpeedPeripheralHz,
964  .chip_select =
965  {
966  .idle = 2,
967  .trail = 2,
968  .lead = 2,
969  },
970  }));
971  CHECK_DIF_OK(dif_spi_host_output_set_enabled(spi_host, /*enabled=*/enable));
972  // dif_spi_host_configure() sets CTRL.SPIEN bit to true.
973  // Adding this explicit control to be able set CTRL.SPIEN pin later
974  // just before the max power epoch.
975  mmio_region_write32(
976  spi_host->base_addr, SPI_HOST_CONTROL_REG_OFFSET,
977  bitfield_bit32_write(0, SPI_HOST_CONTROL_SPIEN_BIT, enable));
978 }
979 
980 void configure_pattgen(void) {
981  for (size_t i = 0; i < ARRAYSIZE(pattgen_channels); ++i) {
982  CHECK_DIF_OK(dif_pattgen_channel_set_enabled(&pattgen, pattgen_channels[i],
984  CHECK_DIF_OK(dif_pattgen_configure_channel(
985  &pattgen, pattgen_channels[i],
987  .polarity = kDifPattgenPolarityHigh,
988  .clock_divisor = kPattgenClockDivisor,
989  .seed_pattern_lower_word = kPattgenSeedPatternLowerWord,
990  .seed_pattern_upper_word = kPattgenSeedPatternUpperWord,
991  .seed_pattern_length = kPattgenSeedPatternLength,
992  .num_pattern_repetitions = kPattgenNumPatternRepetitions,
993  .inactive_level_pda = false,
994  .inactive_level_pcl = false,
995  }));
996  }
997 }
998 
999 void configure_pwm(void) {
1000  CHECK_DIF_OK(
1002  .clock_divisor = kPwmClockDivisor,
1003  .beats_per_pulse_cycle = kPwmBeatsPerCycle,
1004  }));
1005  CHECK_DIF_OK(dif_pwm_channel_set_enabled(
1006  &pwm, (1u << PWM_PARAM_N_OUTPUTS) - 1, kDifToggleDisabled));
1007  for (size_t i = 0; i < PWM_PARAM_N_OUTPUTS; ++i) {
1008  CHECK_DIF_OK(
1009  dif_pwm_configure_channel(&pwm, pwm_channels[i],
1011  .duty_cycle_a = kPwmOnBeats,
1012  .duty_cycle_b = 0, // unused
1013  .phase_delay = kPwmPhaseDelayBeats,
1014  .mode = kDifPwmModeFirmware,
1015  .polarity = kDifPwmPolarityActiveHigh,
1016  .blink_parameter_x = 0, // unused
1017  .blink_parameter_y = 0, // unused
1018  }));
1019  }
1020 
1021  // Enable all the PWM channels. The outputs will start toggling
1022  // after the phase counter is enabled (i.e, PWM_CFG_REG.CNTR_EN = 1).
1023  CHECK_DIF_OK(dif_pwm_channel_set_enabled(
1024  &pwm,
1025  /*channels*/ (1u << PWM_PARAM_N_OUTPUTS) - 1, kDifToggleEnabled));
1026 }
1027 
1028 static void configure_otbn(void) {
1029  CHECK_STATUS_OK(otbn_testutils_rsa_load(&otbn));
1030 }
1031 
1032 static void check_crypto_blocks_idle(void) {
1033  // CSRNG
1034  CHECK(mmio_region_get_bit32(csrng.base_addr, CSRNG_SW_CMD_STS_REG_OFFSET,
1035  CSRNG_SW_CMD_STS_CMD_RDY_BIT));
1036  // AES
1037  CHECK(aes_testutils_get_status(&aes, kDifAesStatusIdle));
1038  // HMAC - no status register to check.
1039  // KMAC
1040  dif_kmac_status_t kmac_status;
1041  CHECK_DIF_OK(dif_kmac_get_status(&kmac, &kmac_status));
1042  CHECK(kmac_status.sha3_state == kDifKmacSha3StateAbsorbing);
1043  // OTBN
1044  dif_otbn_status_t otbn_status;
1045  CHECK_DIF_OK(dif_otbn_get_status(&otbn, &otbn_status));
1046  CHECK(otbn_status == kDifOtbnStatusIdle);
1047 }
1048 
1049 static void complete_kmac_operations(uint32_t *digest) {
1050  // Poll the status register until in the 'squeeze' state.
1051  CHECK_DIF_OK(dif_kmac_poll_status(&kmac, KMAC_STATUS_SHA3_SQUEEZE_BIT));
1052 
1053  // Read both shares of digest from state register and combine using XOR.
1054  ptrdiff_t digest_offset = KMAC_STATE_REG_OFFSET;
1055  for (size_t i = 0; i < kKmacDigestLength; ++i) {
1056  uint32_t share0 = mmio_region_read32(kmac.base_addr, digest_offset);
1057  uint32_t share1 = mmio_region_read32(
1058  kmac.base_addr, digest_offset + kDifKmacStateShareOffset);
1059  digest[i] = share0 ^ share1;
1060  digest_offset += sizeof(uint32_t);
1061  }
1062  kmac_operation_state.offset += kKmacDigestLength;
1063 
1064  // Complete KMAC operations and reset operation state.
1065  CHECK_DIF_OK(dif_kmac_end(&kmac, &kmac_operation_state));
1066 }
1067 
1068 /**
1069  * This function should be removed when we refactor the test to return
1070  * `status_t` to the ottf.
1071  */
1072 static status_t aes_wait_for_status_ready(dif_aes_t *aes) {
1073  AES_TESTUTILS_WAIT_FOR_STATUS(aes, kDifAesStatusInputReady, true,
1074  kTestTimeoutMicros);
1075  return OK_STATUS();
1076 }
1077 
1078 static void crypto_data_load(void) {
1079  LOG_INFO("Loading crypto block FIFOs with data ...");
1080 
1081  configure_hmac();
1082  configure_kmac();
1083  CHECK_STATUS_OK(configure_aes());
1084 
1085  // Load data into AES block.
1086  dif_aes_data_t aes_plain_text;
1087  memcpy(aes_plain_text.data, kAesModesPlainText, sizeof(aes_plain_text.data));
1088  CHECK_STATUS_OK(aes_wait_for_status_ready(&aes));
1089  CHECK_DIF_OK(dif_aes_load_data(&aes, aes_plain_text));
1090 
1091  // Load data into HMAC block.
1092  CHECK_STATUS_OK(
1093  hmac_testutils_push_message(&hmac, kHmacRefData, sizeof(kHmacRefData)));
1094  CHECK_STATUS_OK(
1095  hmac_testutils_check_message_length(&hmac, sizeof(kHmacRefData) * 8));
1096 
1097  // Load data into KMAC block.
1098  dif_kmac_customization_string_t kmac_customization_string;
1099  CHECK_DIF_OK(dif_kmac_customization_string_init("My Tagged Application", 21,
1100  &kmac_customization_string));
1101  CHECK_DIF_OK(dif_kmac_mode_kmac_start(
1102  &kmac, &kmac_operation_state, kDifKmacModeKmacLen256, kKmacDigestLength,
1103  &kKmacKey, &kmac_customization_string));
1104  CHECK_DIF_OK(dif_kmac_absorb(&kmac, &kmac_operation_state, kKmacMessage,
1105  kKmacMessageLength, NULL));
1106  // Prepare KMAC for squeeze command (to come later in max power epoch) by
1107  // formatting message for KMAC operation. Note, below code is derived from
1108  // the KMAC DIF: `dif_kmac_sqeeze()`.
1109  CHECK(!kmac_operation_state.squeezing);
1110  if (kmac_operation_state.append_d) {
1111  // The KMAC operation requires that the output length (d) in bits be
1112  // right encoded and appended to the end of the message.
1113  uint32_t kmac_output_length_bits = kmac_operation_state.d * 32;
1114  int len = 1 + (kmac_output_length_bits > 0xFF) +
1115  (kmac_output_length_bits > 0xFFFF) +
1116  (kmac_output_length_bits > 0xFFFFFF);
1117  int shift = (len - 1) * 8;
1118  while (shift >= 8) {
1119  mmio_region_write8(kmac.base_addr, KMAC_MSG_FIFO_REG_OFFSET,
1120  (uint8_t)(kmac_output_length_bits >> shift));
1121  shift -= 8;
1122  }
1123  mmio_region_write8(kmac.base_addr, KMAC_MSG_FIFO_REG_OFFSET,
1124  (uint8_t)kmac_output_length_bits);
1125  mmio_region_write8(kmac.base_addr, KMAC_MSG_FIFO_REG_OFFSET, (uint8_t)len);
1126  }
1127 }
1128 
1129 static void crypto_data_load_task(void *task_parameters) {
1130  while (test_stage != kPowerVirusTestStageComplete) {
1131  if (test_stage == kPowerVirusTestStageCryptoDataLoad) {
1132  crypto_data_load();
1133  test_stage = kPowerVirusTestStageCommsDataLoad;
1134  ottf_task_yield();
1135  }
1136  }
1137  OTTF_TASK_DELETE_SELF_OR_DIE;
1138 }
1139 
1140 static void comms_data_load(void) {
1141  LOG_INFO("Loading communication block FIFOs with data ...");
1142  size_t bytes_written;
1143  CHECK(ARRAYSIZE(kUartMessage) == kUartFifoDepth);
1144  CHECK(ARRAYSIZE(kI2cMessage) == (I2C_PARAM_FIFO_DEPTH - 1));
1145 
1146  // Load data into UART FIFOs.
1147  for (size_t i = 0; i < ARRAYSIZE(uart_handles); ++i) {
1148  bytes_written = 0;
1149  CHECK_DIF_OK(dif_uart_bytes_send(uart_handles[i], kUartMessage,
1150  ARRAYSIZE(kUartMessage), &bytes_written));
1151  CHECK(bytes_written == ARRAYSIZE(kUartMessage));
1152  }
1153 
1154  // Load data into I2C FIFOs.
1155  static_assert(ARRAYSIZE(i2c_handles) < UINT8_MAX,
1156  "Length of i2c_handles must fit in uint8_t");
1157  for (uint8_t i = 0; i < ARRAYSIZE(i2c_handles); ++i) {
1158  CHECK_STATUS_OK(i2c_testutils_write(i2c_handles[i], /*addr=*/i + 1,
1159  I2C_PARAM_FIFO_DEPTH - 1, kI2cMessage,
1160  /*skip_stop=*/false));
1161  }
1162 
1163  // Load data into SPI host (1; as 0 is used in passthrough mode) FIFO.
1164  uint32_t spi_host_tx_data[SPI_HOST_PARAM_TX_DEPTH];
1165  for (size_t i = 0; i < SPI_HOST_PARAM_TX_DEPTH; ++i) {
1166  spi_host_tx_data[i] = kSpiHost1TxDataWord;
1167  }
1168  dif_spi_host_segment_t spi_host_tx_segment = {
1170  .tx = {
1171  .width = kDifSpiHostWidthQuad,
1172  .buf = (void *)&spi_host_tx_data,
1173  .length = ARRAYSIZE(spi_host_tx_data) * sizeof(uint32_t),
1174  }};
1175  CHECK_DIF_OK(dif_spi_host_transaction(&spi_host_1, kSpiHost1Csid,
1176  &spi_host_tx_segment, 1));
1177 }
1178 
1179 static void comms_data_load_task(void *task_parameters) {
1180  while (test_stage != kPowerVirusTestStageComplete) {
1181  if (test_stage == kPowerVirusTestStageCommsDataLoad) {
1182  comms_data_load();
1183  test_stage = kPowerVirusTestStageMaxPower;
1184  ottf_task_yield();
1185  }
1186  }
1187  OTTF_TASK_DELETE_SELF_OR_DIE;
1188 }
1189 
1190 // Block until CSRNG is ready to accept the next command.
1191 static void csrng_wait_ready(void) {
1192  while (!mmio_region_get_bit32(csrng.base_addr, CSRNG_SW_CMD_STS_REG_OFFSET,
1193  CSRNG_SW_CMD_STS_CMD_RDY_BIT)) {
1194  }
1195 }
1196 
1197 static void max_power(void) {
1198  LOG_INFO("Starting the max power task ...");
1199  // ***************************************************************************
1200  // Trigger all chip operations.
1201  //
1202  // Note: We trigger the activations of each operation manually, rather than
1203  // use the DIFs, so that we can maximize the time overlap between all
1204  // operations.
1205  // ***************************************************************************
1206 
1207  // Prepare AES, HMAC, and KMAC trigger / process commands.
1208  uint32_t aes_trigger_reg = bitfield_bit32_write(0, kDifAesTriggerStart, true);
1209  uint32_t hmac_cmd_reg =
1210  mmio_region_read32(hmac.base_addr, HMAC_CMD_REG_OFFSET);
1211  hmac_cmd_reg =
1212  bitfield_bit32_write(hmac_cmd_reg, HMAC_CMD_HASH_PROCESS_BIT, true);
1213  uint32_t kmac_cmd_reg =
1214  bitfield_field32_write(0, KMAC_CMD_CMD_FIELD, KMAC_CMD_CMD_VALUE_PROCESS);
1215 
1216  // Prepare UART, I2C, SPI host enablement commands (note, all configurations
1217  // between each IP instance should be configured the same).
1218  uint32_t uart_ctrl_reg =
1219  mmio_region_read32(uart_1.base_addr, UART_CTRL_REG_OFFSET);
1220  uart_ctrl_reg = bitfield_bit32_write(uart_ctrl_reg, UART_CTRL_TX_BIT, true);
1221  uart_ctrl_reg = bitfield_bit32_write(uart_ctrl_reg, UART_CTRL_RX_BIT, true);
1222  uint32_t i2c_ctrl_reg =
1223  mmio_region_read32(i2c_0.base_addr, I2C_CTRL_REG_OFFSET);
1224  i2c_ctrl_reg =
1225  bitfield_bit32_write(i2c_ctrl_reg, I2C_CTRL_ENABLEHOST_BIT, true);
1226  uint32_t spi_host_1_ctrl_reg =
1227  mmio_region_read32(spi_host_1.base_addr, SPI_HOST_CONTROL_REG_OFFSET);
1228  spi_host_1_ctrl_reg = bitfield_bit32_write(
1229  spi_host_1_ctrl_reg, SPI_HOST_CONTROL_OUTPUT_EN_BIT, true);
1230  spi_host_1_ctrl_reg = bitfield_bit32_write(spi_host_1_ctrl_reg,
1231  SPI_HOST_CONTROL_SPIEN_BIT, true);
1232 
1233  // Prepare pattgen enablement command.
1234  uint32_t pattgen_ctrl_reg =
1235  mmio_region_read32(pattgen.base_addr, PATTGEN_CTRL_REG_OFFSET);
1236  pattgen_ctrl_reg =
1237  bitfield_bit32_write(pattgen_ctrl_reg, PATTGEN_CTRL_ENABLE_CH0_BIT, true);
1238  pattgen_ctrl_reg =
1239  bitfield_bit32_write(pattgen_ctrl_reg, PATTGEN_CTRL_ENABLE_CH1_BIT, true);
1240 
1241  // Prepare adc_ctrl enablement command
1242  uint32_t adc_ctrl_reg =
1243  mmio_region_read32(adc_ctrl.base_addr, ADC_CTRL_ADC_EN_CTL_REG_OFFSET);
1244  adc_ctrl_reg = bitfield_bit32_write(adc_ctrl_reg,
1245  ADC_CTRL_ADC_EN_CTL_ADC_ENABLE_BIT, true);
1246 
1247  // Prepare PWM channels for the enablement. The outputs will start toggling
1248  // after the phase counter is enabled (i.e, PWM_CFG_REG.CNTR_EN = 1).
1249  uint32_t pwm_cfg_reg = mmio_region_read32(pwm.base_addr, PWM_CFG_REG_OFFSET);
1250  pwm_cfg_reg = bitfield_bit32_write(pwm_cfg_reg, PWM_CFG_CNTR_EN_BIT, true);
1251 
1252  // Prepare GPIO register values (for max power indicator).
1253  const uint32_t gpio_on_reg_val = (1u << 16) | 1u;
1254  const uint32_t gpio_off_reg_val = 1u << 16;
1255 
1256  check_crypto_blocks_idle();
1257 
1258  LOG_INFO("Entering max power epoch ...");
1259 
1260  // Enable adc_ctrl
1261  mmio_region_write32(adc_ctrl.base_addr, ADC_CTRL_ADC_EN_CTL_REG_OFFSET,
1262  adc_ctrl_reg);
1263 
1264  // Enable toggling at all PWM channels by enabling the phase counter.
1265  mmio_region_write32(pwm.base_addr, PWM_CFG_REG_OFFSET, pwm_cfg_reg);
1266 
1267  // Enable all UARTs and I2Cs.
1268  mmio_region_write32(uart_1.base_addr, UART_CTRL_REG_OFFSET, uart_ctrl_reg);
1269  mmio_region_write32(uart_2.base_addr, UART_CTRL_REG_OFFSET, uart_ctrl_reg);
1270  mmio_region_write32(uart_3.base_addr, UART_CTRL_REG_OFFSET, uart_ctrl_reg);
1271  mmio_region_write32(i2c_0.base_addr, I2C_CTRL_REG_OFFSET, i2c_ctrl_reg);
1272  mmio_region_write32(i2c_1.base_addr, I2C_CTRL_REG_OFFSET, i2c_ctrl_reg);
1273  mmio_region_write32(i2c_2.base_addr, I2C_CTRL_REG_OFFSET, i2c_ctrl_reg);
1274 
1275  // Issue OTBN start command.
1276  CHECK_STATUS_OK(otbn_testutils_rsa_modexp_f4_start(
1277  &otbn, (unsigned char *)kRsa2KModulus, (unsigned char *)kRsa2KSignature,
1278  sizeof(kRsa2KModulus)));
1279 
1280  // Enable pattgen.
1281  mmio_region_write32(pattgen.base_addr, PATTGEN_CTRL_REG_OFFSET,
1282  pattgen_ctrl_reg);
1283 
1284  // Enable SPI host (1).
1285  mmio_region_write32(spi_host_1.base_addr, SPI_HOST_CONTROL_REG_OFFSET,
1286  spi_host_1_ctrl_reg);
1287 
1288  // Request entropy during max power epoch. Since AES is so fast, realistically
1289  // we will only be able to request a single block of entropy.
1290  csrng_wait_ready();
1291  mmio_region_write32(csrng.base_addr, CSRNG_CMD_REQ_REG_OFFSET,
1292  csrng_instantiate_cmd_header);
1293 
1294  uint32_t csrng_reseed_cmd = csrng_cmd_header_build(
1295  kCsrngAppCmdReseed, kDifCsrngEntropySrcToggleEnable, /*cmd_len=*/0,
1296  /*generate_len=*/0);
1297 
1298  csrng_wait_ready();
1299  mmio_region_write32(csrng.base_addr, CSRNG_CMD_REQ_REG_OFFSET,
1300  csrng_reseed_cmd);
1301 
1302  // Issue HMAC process and KMAC squeeze commands.
1303  kmac_operation_state.squeezing = true;
1304  mmio_region_write32(kmac.base_addr, KMAC_CMD_REG_OFFSET, kmac_cmd_reg);
1305 
1306  // Issue AES trigger commands.
1307  mmio_region_write32(aes.base_addr, AES_TRIGGER_REG_OFFSET, aes_trigger_reg);
1308 
1309  // Toggle GPIO pin to indicate we are in max power consumption epoch.
1310  mmio_region_write32(gpio.base_addr, GPIO_MASKED_OUT_LOWER_REG_OFFSET,
1311  gpio_on_reg_val);
1312 
1313  mmio_region_write32(hmac.base_addr, HMAC_CMD_REG_OFFSET,
1314  hmac_cmd_reg); // see note
1315  // moved HMAC activation here because it is too fast and returns to idle
1316  // before GPIO pin IOB8 is toggled.
1317 
1318  // Wait for AES to complete encryption, as this is the fastest block.
1319  while (!(mmio_region_read32(aes.base_addr, AES_STATUS_REG_OFFSET) &
1320  (1u << AES_STATUS_OUTPUT_VALID_BIT)))
1321  ;
1322 
1323  // Toggle GPIO pin to indicate we are out of max power consumption epoch.
1324  mmio_region_write32(gpio.base_addr, GPIO_MASKED_OUT_LOWER_REG_OFFSET,
1325  gpio_off_reg_val);
1326 
1327  LOG_INFO("Exited max power epoch.");
1328 
1329  // ***************************************************************************
1330  // Check operation results.
1331  // ***************************************************************************
1332  // Check AES operation.
1333  dif_aes_data_t aes_cipher_text;
1334  CHECK_DIF_OK(dif_aes_read_output(&aes, &aes_cipher_text));
1335  CHECK_ARRAYS_EQ((uint8_t *)aes_cipher_text.data, kAesModesCipherTextCbc256,
1336  ARRAYSIZE(aes_cipher_text.data));
1337 
1338  // Check HMAC operations.
1339  CHECK_STATUS_OK(
1340  hmac_testutils_finish_and_check_polled(&hmac, &kHmacRefExpectedDigest));
1341 
1342  // Check KMAC operations.
1343  uint32_t kmac_digest[kKmacDigestLength];
1344  complete_kmac_operations(kmac_digest);
1345  CHECK(kKmacDigestLength == ARRAYSIZE(kKmacDigest));
1346  CHECK_ARRAYS_EQ(kmac_digest, kKmacDigest, ARRAYSIZE(kKmacDigest));
1347 
1348  // Check OTBN operations.
1349  uint32_t rsa_recovered_message[ARRAYSIZE(kRsa2KEncodedMessage)];
1350  CHECK_STATUS_OK(otbn_testutils_rsa_modexp_f4_finalize(
1351  &otbn, (unsigned char *)rsa_recovered_message,
1352  sizeof(rsa_recovered_message)));
1353  CHECK_ARRAYS_EQ(rsa_recovered_message, kRsa2KEncodedMessage,
1354  ARRAYSIZE(kRsa2KEncodedMessage));
1355 
1356  // Check UART transactions.
1357  uint8_t received_uart_data[kUartFifoDepth];
1358  size_t num_uart_rx_bytes;
1359  for (size_t i = 0; i < ARRAYSIZE(uart_handles); ++i) {
1360  CHECK_DIF_OK(
1361  dif_uart_rx_bytes_available(uart_handles[i], &num_uart_rx_bytes));
1362  // Note, we don't care if all bytes have been transmitted out of the UART by
1363  // the time the fastest processing crypto block (i.e., the AES) has
1364  // completed. Likely, we won't have transmitted all data since the UART is
1365  // quite a bit slower. We just check that what was transmitted is correct.
1366  memset((void *)received_uart_data, 0, kUartFifoDepth);
1367  CHECK_DIF_OK(dif_uart_bytes_receive(uart_handles[i], num_uart_rx_bytes,
1368  received_uart_data, NULL));
1369  CHECK_ARRAYS_EQ(received_uart_data, kUartMessage, num_uart_rx_bytes);
1370  }
1371 
1372  // Check I2C bits TXed were echoed back by the DV agent. (Only for DV.)
1373  if (kDeviceType == kDeviceSimDV) {
1374  dif_i2c_level_t fmt_fifo_lvl, rx_fifo_lvl;
1375 
1376  // Make sure all TX FIFOs have been drained.
1377  for (size_t ii = 0; ii < ARRAYSIZE(i2c_handles); ++ii) {
1378  do {
1379  CHECK_DIF_OK(dif_i2c_get_fifo_levels(
1380  i2c_handles[ii], &fmt_fifo_lvl,
1381  /*rx_fifo_lvl=*/NULL, /*tx_fifo_lvl=*/NULL, /*acq_fifo_lvl=*/NULL));
1382  } while (fmt_fifo_lvl > 0);
1383  };
1384 
1385  // Read data from I2C RX FIFO.
1386  static_assert(ARRAYSIZE(i2c_handles) < UINT8_MAX,
1387  "Length of i2c_handles must fit in uint8_t");
1388  for (uint8_t ii = 0; ii < ARRAYSIZE(i2c_handles); ++ii) {
1389  CHECK_STATUS_OK(
1390  i2c_testutils_issue_read(i2c_handles[ii], /*addr=*/ii + 1,
1391  /*byte_count=*/I2C_PARAM_FIFO_DEPTH - 1));
1392  };
1393 
1394  // Make sure all data has been read back.
1395  for (size_t ii = 0; ii < ARRAYSIZE(i2c_handles); ++ii) {
1396  do {
1397  CHECK_DIF_OK(dif_i2c_get_fifo_levels(
1398  i2c_handles[ii], /*fmt_fifo_lvl=*/NULL, &rx_fifo_lvl,
1399  /*tx_fifo_lvl=*/NULL, /*acq_fifo_lvl=*/NULL));
1400  } while (rx_fifo_lvl < I2C_PARAM_FIFO_DEPTH - 1);
1401  };
1402 
1403  // Make sure read data is correct.
1404  for (size_t ii = 0; ii < ARRAYSIZE(i2c_handles); ++ii) {
1405  for (size_t jj = 0; jj < I2C_PARAM_FIFO_DEPTH - 1; ++jj) {
1406  uint8_t byte;
1407  CHECK_DIF_OK(dif_i2c_read_byte(i2c_handles[ii], &byte));
1408  CHECK(kI2cMessage[jj] == byte);
1409  };
1410  };
1411  }
1412 }
1413 
1414 static void max_power_task(void *task_parameters) {
1415  uint32_t max_iterations = 1;
1416  if (kDeviceType == kDeviceSilicon) {
1417  max_iterations = kMaxIterationsSilicon;
1418  }
1419 
1420  for (size_t i = 0; i < max_iterations; ++i) {
1421  if (test_stage == kPowerVirusTestStageMaxPower) {
1422  max_power();
1423  test_stage = (i + 1 == max_iterations)
1424  ? kPowerVirusTestStageComplete
1425  : kPowerVirusTestStageCryptoDataLoad;
1426  ottf_task_yield();
1427  }
1428  }
1429 
1430  OTTF_TASK_DELETE_SELF_OR_DIE;
1431 }
1432 
1433 static void check_otp_csr_configs(void) {
1434  dif_flash_ctrl_region_properties_t default_properties;
1436  &flash_ctrl, &default_properties));
1437  CHECK(default_properties.scramble_en == kMultiBitBool4True);
1438  CHECK(default_properties.ecc_en == kMultiBitBool4True);
1439  CHECK(default_properties.high_endurance_en == kMultiBitBool4False);
1440 }
1441 
1442 bool test_main(void) {
1443  peripheral_clock_period_ns =
1444  (uint32_t)udiv64_slow(1000000000, kClockFreqPeripheralHz, NULL);
1445  // Note: DO NOT change this message string without updating the DV testbench.
1446  LOG_INFO("Computed peripheral clock period.");
1447 
1448  // ***************************************************************************
1449  // Initialize and configure all IPs.
1450  // ***************************************************************************
1451  init_peripheral_handles();
1452  configure_pinmux();
1453  // To be compatible with the configs in chip_if.sv,
1454  // apply the additional pinmux settings.
1456  configure_pinmux_sim();
1457  }
1458  // Clear GPIO pin 0 (max power indicator pin).
1459  CHECK_DIF_OK(
1460  dif_gpio_output_set_enabled(&gpio, /*pin=*/0, kDifToggleEnabled));
1461  configure_adc_ctrl_to_continuously_sample();
1462  configure_entropy_complex();
1463  configure_otbn();
1464  configure_uart(&uart_1);
1465  configure_uart(&uart_2);
1466  configure_uart(&uart_3);
1467  configure_i2c(&i2c_0, kI2c0DeviceAddress0, kI2c0DeviceAddress1);
1468  configure_i2c(&i2c_1, kI2c1DeviceAddress0, kI2c1DeviceAddress1);
1469  configure_i2c(&i2c_2, kI2c2DeviceAddress0, kI2c2DeviceAddress1);
1470  configure_spi_host(&spi_host_0, /*enable=*/true);
1471  // We don't enable SPI host 1 just yet, as we want to pre-load its FIFO with
1472  // data before enabling it at the last moment, to initiate max power draw.
1473  configure_spi_host(&spi_host_1, /*enable=*/false);
1474  CHECK_STATUS_OK(spi_device_testutils_configure_passthrough(
1475  &spi_device, /*filters=*/0,
1476  /*upload_write_commands=*/false));
1477  configure_pattgen();
1478  configure_pwm();
1479  LOG_INFO("All IPs configured.");
1480 
1481  // ***************************************************************************
1482  // Check OTP configurations propagated to CSRs.
1483  // ***************************************************************************
1484  check_otp_csr_configs();
1485 
1486  // ***************************************************************************
1487  // Kick off test tasks.
1488  // ***************************************************************************
1489  test_stage = kPowerVirusTestStageCryptoDataLoad;
1490 
1491  CHECK(ottf_task_create(crypto_data_load_task, "CryptoDataLoadTask",
1492  kOttfFreeRtosMinStackSize, 1));
1493  CHECK(ottf_task_create(comms_data_load_task, "CommsDataLoadTask",
1494  kOttfFreeRtosMinStackSize, 1));
1495  CHECK(ottf_task_create(max_power_task, "MaxPowerTask",
1496  kOttfFreeRtosMinStackSize, 1));
1497 
1498  // ***************************************************************************
1499  // Yield control flow to the highest priority task in the run queue. Since
1500  // the tasks created above all have a higher priority level than the current
1501  // "test_main" task, and no tasks block, execution will not be returned to the
1502  // current task until the above tasks have been deleted.
1503  // ***************************************************************************
1504  LOG_INFO("Yielding execution to another task.");
1505  ottf_task_yield();
1506 
1507  return true;
1508 }