The SecBus Hardware Security Module (HSM) in transparent mode
This tutorial is specifically designed for the Xilinx [Zynq] cores and the ZedBoard prototyping board. Zynq cores embed a ARM processor and all its usual peripherals (USB, Ethernet, flash...) including external memory controllers. This part forms what is named Processing System (PS) in Xilinx terminology. Zynq cores also embed an FPGA matrix, the Programmable Logic (PL).
This page explains how to configure the PL with the SecBus HSM and how to run a Linux kernel with all accesses to the external DDR flowing through the HSM in transparent mode, that is, in a mode where the HSM simply forwards the PS requests to the DDR back and forth, without applying any cryptographic primitive. After testing the AXI simple bridge and experimenting attacks with the AXI bridge, this is the next step toward full SecBus operation.
In Zynq cores, the Processing System (PS) usually accesses its external DDR memory in the [0x0000_0000, 0x4000_0000[ address range (Regular Address Space or RAS in the following). In order to process the memory accesses it would be convenient to route them to the Programmable Logic (PL), instead. If this was possible, one could simply configure the PL to implement the desired processing and instruct the PS to access its DDR through the PL. Of course, in order for this to work, the PL would have to route the PS requests to the DDR and the DDR responses back to the PS. The kind of processing implemented in the PL can be anything from no processing, monitoring, tracing, cryptography...
Indeed, thanks to the Zynq architecture and its quite dense PS-PL interface, it is possible. The SecBus HSM uses this organization to implement cryptographic processing of the memory accesses (encryption, integrity checking). In this set-up the HSM is disabled and simply forwards the AXI requests from PS to DDR and the responses from DDR to PS.
The PS and the PL communicate through a set of AXI interfaces. The HSM uses 3 of them:
AXI_GP0: 32 bits, master: PS, slave: PL, mapped in the [0x4000_0000, 0x8000_0000[ address range (Control Address Space or CAS in the following). The PS uses this interface to access the HSM internal registers.
AXI_GP1: 32 bits, master: PS, slave: PL, mapped in the [0x8000_0000, 0xc000_0000[ address range (Alternate Address Space or AAS in the following). The PS uses this interface to access the DDR through the HSM.
AXI_HP0: 32 or 64 bits, master: PL, slave: PS. Configured in 32 bits width. The HSM routes all PS requests falling in the AAS, that is, received on the AXI_GP1 interface, to AXI_HP0, after shifting the addresses back in the RAS. This way, accessing an address A in the [0x8000_0000, 0xc000_0000[ range is the same as accessing A-0x8000_0000 in the [0x0000_0000, 0x4000_0000[ range, except that it is routed through the HSM.
Prepare a SDCard from which the ZedBoard will boot. Mount it on your host PC. In the following we assume its mount point is /media/SDCard.
Unmount the SDCard, plug it to the ZedBoard, configure the jumpers to boot from the SDCard and connect the USB-UART cable to your host PC.
Power on the ZedBoard and launch a serial console on your host PC (minicom, cu, putty...):
minicom -D /dev/ttyACM0
Wait until the Linux kernel boots.
You are done and you are running a minimal GNU/Linux OS with all accesses to the external memory routed to the PL.
Note: the bitstream embeds a Chipscope Integrated Logic Analyzer core allowing to observe the M_AXI signals from Vivado.
Building the whole example from scratch
If you have a SecBus distribution already installed:
cd secbus/vhdl/hsm/src/axi_secbus_bridgemake help
and follow the instructions.
Errors, crashes and freezes
If you play a bit with the HSM an perform read and write accesses randomly with devmem, you will probably encounter some problems (errors, crashes, freezes and other undesirable behaviours):
First, accessing unmapped addresses in CAS or writing a read-only register raises an error.
But you can also overwrite an important memory location, currently used by the Linux kernel. And you can do this using one or the other of the two equivalent AAS and RAS.
Last but not least, you can also fall in an address range that is mapped in RAS but not in AAS. Indeed, due to the specificities of the Zynq architecture, AAS and RAS are not strictly equivalent. This is explained in the Secure Boot section. Meanwhile, avoid accessing the first MB of AAS ([0x8000_0000..0x8010_0000[).