[aes_serial] Change order of operations, reduce sleep time
This commit reorders the execution of some operations when performing SCA
captures (e.g. first provide input data, then start wakeup timer), and it
reduces the sleep time of Ibex from 5000 to 200 clock cycles. This should
slightly improve capture performance.
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
diff --git a/sw/device/sca/aes_serial/aes_serial.c b/sw/device/sca/aes_serial/aes_serial.c
index c883813..2ec2c4c 100644
--- a/sw/device/sca/aes_serial/aes_serial.c
+++ b/sw/device/sca/aes_serial/aes_serial.c
@@ -50,8 +50,12 @@
// RV Timer settings
static const uint32_t kHart = (uint32_t)kTopEarlgreyPlicTargetIbex0;
static const uint32_t kComparator = 0;
-static const uint64_t kTickFreqHz = 1000 * 1000; // 1 MHz.
-static const uint64_t kDeadline = 500; // 500us.
+static const uint64_t kDeadline = 200; // 200 clock cycles at kClockFreqCpuHz
+// Caution: This number should be chosen to provide enough time. Otherwise,
+// Ibex might wake up while AES is still busy and disturb the capture.
+// Currently, we use a start trigger delay of 40 clock cycles and the scope
+// captures 18 clock cycles at kClockFreqCpuHz (180 samples). The latter number
+// will likely increase as we improve the security hardening.
// TODO: Remove once there is a CHECK version that does not require test
// library dependencies.
@@ -198,7 +202,18 @@
return kSimpleSerialError;
}
- // start timer to wake up Ibex after AES is done.
+ // Provide input data to AES.
+ aes_data_put_wait(plain_text);
+
+ // Arm capture trigger. The actual trigger signal used for capture is a
+ // combination (logical AND) of:
+ // - GPIO15 enabled here, and
+ // - the busy signal of the AES unit. This signal will go high 40 cycles
+ // after aes_manual_trigger() is executed below and remain high until
+ // the operation has finished.
+ SS_CHECK(dif_gpio_write_all(&gpio, kGpioCaptureTriggerHigh) == kDifGpioOk);
+
+ // Start timer to wake up Ibex after AES is done.
uint64_t current_time;
SS_CHECK(dif_rv_timer_counter_read(&timer, kHart, ¤t_time) ==
kDifRvTimerOk);
@@ -207,13 +222,17 @@
SS_CHECK(dif_rv_timer_counter_set_enabled(
&timer, kHart, kDifRvTimerEnabled) == kDifRvTimerOk);
- aes_data_put_wait(plain_text);
- SS_CHECK(dif_gpio_write_all(&gpio, kGpioCaptureTriggerHigh) == kDifGpioOk);
-
+ // Start AES operation (this triggers the capture) and go to sleep.
+ // Using the SecAesStartTriggerDelay hardware parameter, the AES unit is
+ // configured to start operation 40 cycles after receiving the start trigger.
+ // This allows Ibex to go to sleep in order to not disturb the capture.
aes_manual_trigger();
wait_for_interrupt();
+ // Disable capture trigger.
SS_CHECK(dif_gpio_write_all(&gpio, kGpioCaptureTriggerLow) == kDifGpioOk);
+
+ // Retrieve output data from AES.
aes_data_get_wait(cipher_text);
print_cmd_response('r', cipher_text, plain_text_len);
@@ -290,7 +309,7 @@
&timer) == kDifRvTimerOk);
dif_rv_timer_tick_params_t tick_params;
CHECK(dif_rv_timer_approximate_tick_params(kClockFreqPeripheralHz,
- kTickFreqHz, &tick_params) ==
+ kClockFreqCpuHz, &tick_params) ==
kDifRvTimerApproximateTickParamsOk);
CHECK(dif_rv_timer_set_tick_params(&timer, kHart, tick_params) ==
kDifRvTimerOk);