[fpga] Reduce noise for AES SCA
This commit contains the following changes to reduce the noise during
AES SCA experiments:
- A delay to the manual AES trigger is added to allow Ibex going into
sleep (wfi) before the measurement starts.
- The reseeding of AES-internal PRNGs is disabled using a parameter.
- In the aes_serial application, the entropy complex (ES, CSRNG, EDN0/1)
is disabled. This is only possible as the AES PRNGs aren't reseeded
in this setup anymore.
- USB, HMAC, KMAC and OTBN clocks are disabled in the aes_serial
application.
Signed-off-by: Pirmin Vogel <vogelpi@lowrisc.org>
diff --git a/hw/top_earlgrey/rtl/autogen/chip_earlgrey_cw310.sv b/hw/top_earlgrey/rtl/autogen/chip_earlgrey_cw310.sv
index 4870180..974b01f 100644
--- a/hw/top_earlgrey/rtl/autogen/chip_earlgrey_cw310.sv
+++ b/hw/top_earlgrey/rtl/autogen/chip_earlgrey_cw310.sv
@@ -748,6 +748,9 @@
top_earlgrey #(
.AesMasking(1'b1),
.AesSBoxImpl(aes_pkg::SBoxImplDom),
+ .SecAesStartTriggerDelay(40),
+ .SecAesAllowForcingMasks(1'b1),
+ .SecAesSkipPRNGReseeding(1'b1),
.KmacEnMasking(0),
.CsrngSBoxImpl(aes_pkg::SBoxImplLut),
.OtbnRegFile(otbn_pkg::RegFileFPGA),
diff --git a/sw/device/sca/aes_serial.c b/sw/device/sca/aes_serial.c
index a6cd8c0..50bee15 100644
--- a/sw/device/sca/aes_serial.c
+++ b/sw/device/sca/aes_serial.c
@@ -205,6 +205,9 @@
LOG_INFO("Running AES serial");
+ LOG_INFO("Disabling entropy complex and unneeded clocks to reduce noise.");
+ sca_reduce_noise();
+
LOG_INFO("Initializing simple serial interface to capture board.");
simple_serial_init(uart1);
simple_serial_register_handler('k', aes_serial_set_key);
diff --git a/sw/device/sca/lib/meson.build b/sw/device/sca/lib/meson.build
index 251aeed..3c9e9c9 100644
--- a/sw/device/sca/lib/meson.build
+++ b/sw/device/sca/lib/meson.build
@@ -5,8 +5,15 @@
sw_sca_lib_sca = declare_dependency(
link_with: static_library(
'lib_sca',
- sources: ['sca.c'],
+ sources: [
+ 'sca.c',
+ hw_ip_csrng_reg_h,
+ hw_ip_edn_reg_h,
+ hw_ip_clkmgr_reg_h,
+ ],
dependencies: [
+ sw_lib_dif_clkmgr,
+ sw_lib_dif_entropy,
sw_lib_dif_gpio,
sw_lib_dif_rv_timer,
sw_lib_dif_uart,
diff --git a/sw/device/sca/lib/sca.c b/sw/device/sca/lib/sca.c
index 758d330..9e732a8 100644
--- a/sw/device/sca/lib/sca.c
+++ b/sw/device/sca/lib/sca.c
@@ -5,6 +5,8 @@
#include "sw/device/sca/lib/sca.h"
#include "sw/device/lib/arch/device.h"
+#include "sw/device/lib/dif/dif_clkmgr.h"
+#include "sw/device/lib/dif/dif_entropy.h"
#include "sw/device/lib/dif/dif_gpio.h"
#include "sw/device/lib/dif/dif_rv_timer.h"
#include "sw/device/lib/dif/dif_uart.h"
@@ -14,6 +16,9 @@
#include "sw/device/lib/runtime/hart.h"
#include "sw/device/lib/runtime/print.h"
+#include "clkmgr_regs.h" // Generated
+#include "csrng_regs.h" // Generated
+#include "edn_regs.h" // Generated
#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
/**
@@ -131,6 +136,47 @@
sca_init_timer();
}
+void sca_reduce_noise() {
+ // Disable/stopping functionality not yet provided by EDN and CSRNG DIFs.
+ mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN0_BASE_ADDR),
+ EDN_CTRL_REG_OFFSET, EDN_CTRL_REG_RESVAL);
+ mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_EDN1_BASE_ADDR),
+ EDN_CTRL_REG_OFFSET, EDN_CTRL_REG_RESVAL);
+ mmio_region_write32(mmio_region_from_addr(TOP_EARLGREY_CSRNG_BASE_ADDR),
+ CSRNG_CTRL_REG_OFFSET, CSRNG_CTRL_REG_RESVAL);
+
+ // Disable entropy source through DIF.
+ const dif_entropy_params_t entropy_params = {
+ .base_addr = mmio_region_from_addr(TOP_EARLGREY_ENTROPY_SRC_BASE_ADDR),
+ };
+ dif_entropy_t entropy;
+ IGNORE_RESULT(dif_entropy_init(entropy_params, &entropy) == kDifEntropyOk);
+ IGNORE_RESULT(dif_entropy_disable(&entropy) == kDifEntropyOk);
+
+ // Disable HMAC, KMAC, OTBN and USB clocks through CLKMGR DIF.
+ const dif_clkmgr_params_t clkmgr_params = {
+ .base_addr = mmio_region_from_addr(TOP_EARLGREY_CLKMGR_AON_BASE_ADDR),
+ .last_gateable_clock = CLKMGR_CLK_ENABLES_CLK_USB_PERI_EN_BIT,
+ .last_hintable_clock = CLKMGR_CLK_HINTS_STATUS_CLK_MAIN_OTBN_VAL_BIT};
+ dif_clkmgr_t clkmgr;
+ IGNORE_RESULT(dif_clkmgr_init(clkmgr_params, &clkmgr) == kDifClkmgrOk);
+ IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
+ &clkmgr, CLKMGR_CLK_HINTS_CLK_MAIN_HMAC_HINT_BIT,
+ kDifClkmgrToggleDisabled) == kDifClkmgrOk);
+ IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
+ &clkmgr, CLKMGR_CLK_HINTS_CLK_MAIN_KMAC_HINT_BIT,
+ kDifClkmgrToggleDisabled) == kDifClkmgrOk);
+ IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
+ &clkmgr, CLKMGR_CLK_HINTS_CLK_IO_DIV4_OTBN_HINT_BIT,
+ kDifClkmgrToggleDisabled) == kDifClkmgrOk);
+ IGNORE_RESULT(dif_clkmgr_hintable_clock_set_hint(
+ &clkmgr, CLKMGR_CLK_HINTS_CLK_MAIN_OTBN_HINT_BIT,
+ kDifClkmgrToggleDisabled) == kDifClkmgrOk);
+ IGNORE_RESULT(dif_clkmgr_gateable_clock_set_enabled(
+ &clkmgr, CLKMGR_CLK_ENABLES_CLK_USB_PERI_EN_BIT,
+ kDifClkmgrToggleDisabled) == kDifClkmgrOk);
+}
+
void sca_get_uart(const dif_uart_t **uart_out) { *uart_out = &uart1; }
void sca_set_trigger_high() {
diff --git a/sw/device/sca/lib/sca.h b/sw/device/sca/lib/sca.h
index 6ade58b..cd007d9 100644
--- a/sw/device/sca/lib/sca.h
+++ b/sw/device/sca/lib/sca.h
@@ -5,10 +5,10 @@
#ifndef OPENTITAN_SW_DEVICE_SCA_LIB_SCA_H_
#define OPENTITAN_SW_DEVICE_SCA_LIB_SCA_H_
-#include "sw/device/lib/dif/dif_uart.h"
-
#include <stdint.h>
+#include "sw/device/lib/dif/dif_uart.h"
+
/**
* @file
* @brief Side-channel analysis support library.
@@ -20,6 +20,16 @@
void sca_init(void);
/**
+ * Disables the entropy complex and clocks of IPs not needed for SCA to reduce
+ * noise in the power traces.
+ *
+ * We can only disable the entropy complex as AES features a parameter to skip
+ * PRNG reseeding for SCA experiments. Without this parameter, AES would simply
+ * get stalled with a disabled entropy complex.
+ */
+void sca_reduce_noise(void);
+
+/**
* Returns a handle to the intialized UART device.
*
* @param[out] uart_out Handle to the initialized UART device.
diff --git a/util/topgen/templates/chiplevel.sv.tpl b/util/topgen/templates/chiplevel.sv.tpl
index 5426c00..e6ee5cc 100644
--- a/util/topgen/templates/chiplevel.sv.tpl
+++ b/util/topgen/templates/chiplevel.sv.tpl
@@ -1067,6 +1067,9 @@
% if target["name"] == "cw310":
.AesMasking(1'b1),
.AesSBoxImpl(aes_pkg::SBoxImplDom),
+ .SecAesStartTriggerDelay(40),
+ .SecAesAllowForcingMasks(1'b1),
+ .SecAesSkipPRNGReseeding(1'b1),
.KmacEnMasking(0),
.CsrngSBoxImpl(aes_pkg::SBoxImplLut),
.OtbnRegFile(otbn_pkg::RegFileFPGA),