Last time, and roughly speaking, we presented how to induce faults through electromagnetic pulses into an MCU. If you have missed it, go ahead and read the previous tutorial, FaultyCat: Induction Through Electromagnetic Pulses.
Now, you will learn how to create a controlled environment where the magnitude of the induced faults might change according to the power settings of FaultyCat and the sensitivity settings of a Training Board.
From now on, we will call the TrainingBoard a "victim board" that will receive a glitch from a fault injection tool (FaultyCat). By changing the power of the electromagnetic shockwave produced by FaultyCat and setting the sensitivity of the Training Board to different levels, the glitch's effects over the last one will be different.
The RP2350RP2350 is Raspberry Pi’s new microcontroller family that offers significant enhancements over RP2040. Among the most important, we have the Security features, which include:
- Optional boot signing, enforced by on-chip mask ROM, with key fingerprint in OTP.
- Protected OTP storage for optional boot decryption key.
- Global bus filtering based on Arm or RISC-V security/privilege levels.
- Peripherals, GPIOs, and DMA channels are individually assignable to security domains.
- Hardware mitigations for fault injection attacks.
- Hardware SHA-256 accelerator.
- New chip reset sources: glitch detector, watchdog, debugger.
In this context, we were interested in testing the new chip reset sources, because they involve both the MCU and our FaultyCat. Here, we found the Glitch Detector.
Glitch DetectorWhat is a glitch detector, and how does it work?
"The Glitch Detector detects loss of setup and hold margin in the system clock domain, which may be caused by deliberate external manipulation of the system clock or core supply voltage. When it detects loss, the glitch detector triggers a system reset rather than allowing software to continue to execute in a possibly undefined state. It responds RP2350 Datasheet 10.8. OTP 866 within one system clock cycle, unlike the brownout detector, which has much more limited analog bandwidth." [1].
The glitch detector comprises four identical detector circuits, based on a pair of D flip-flops. These detector circuits are each placed in different, physically distant locations within the core voltage domain.
The detector gets triggered when the D-flops pair has different values, which is impossible under normal circumstances. The delay line is programmable from 75% to 120% of the minimum system clock period in increments of 15%. Higher delays make the circuit more sensitive to loss of setup margin.
Glitch Detectorsregisters
- ARM: Forcibly arm the glitch detectors, if they are not already armed by OTP. When armed, any individual detector trigger will cause a restart of the switched core power domain’s power-on reset state machine. Glitch detector triggers are recorded accumulatively in TRIG_STATUS. If the system is reset by a glitch detector trigger, this is recorded in the POWMAN_CHIP_RESET register.
- DISARM: Disarms the glitch detectors.
- SENSITIVITY: Adjust the sensitivity of glitch detectors to values other than their OTP-provided defaults.
- LOCK: Write any nonzero value to disable writes to ARM, DISARM, SENSITIVITY, and LOCK.
- TRIG_STATUS: Set when a detector output triggers. Write-1-clear. Detectors can only be cleared by a full reset of the switched core power domain.
- TRIG_FORCE: Simulate the firing of one or more detectors.
To see the complete information about these registers, refer to the official RP2350's Datasheet [1], Chapter 10. Security, subsection > 10.9. Glitch Detector.
Preparing a "Victim Board"We recommend using the firmware from Hextreeio[2] team, which was created along with a training board powered by the Raspberry Pi RP2350 MCU. The board and the firmware are available on its official GitHub repository: RP2350 Security Playground Demo.
Working on Ubuntu is recommended, as it is easier to install dependencies and, for instance, compile binaries, but the OS is optional to you.
Installing the Raspberry Pi Pico extension and the pico-sdk tool
1. In Visual Studio Code, go to the Extensions section and search for the official Raspberry Pi Pico extension and install it.
2. Using the terminal (Ctrl + Alt + T on Ubuntu), we cloned the repository for the pico-sdk tool and installed the modules.
3. The RP2350 Security Playground Demo repository was cloned as well.
What is the code about?
Let us talk about the most important instructions in the code.
First, the main.c code.
These are the required header files for the system to work.
There are 5 states of sensitivity for each glitch detector:
- Off. No sensitivity to glitch.
- 0 to 3. Different sensitivity levels, where 0 is the least sensitive and 3 is the most sensitive level.
The sensitivity will depend on the programmable delay line, as explained in the section “What is a glitch detector and how does it work?”.
The glitch detector has been triggered if the chip_reset register of the powman_hw domain matches the HAD_GLITCH_DETECT option (0x04000000).
By default, the sensitivity of all glitch detectors will be set to the same level (0, 1, 2, or 3) according to the one selected.
If any glitch detector was triggered, this portion of the code will specify which ones were activated.
It is possible to go to:
- Bootmode: Main Menu (part 2) to select between the Glitch Challenge or OTP Challenge.
- Menu Glitch Sensitivity: to configure the sensitivity for the glitch detectors.
- Restart: resets the board.
It is possible to choose between running the Glitch Challenge (by setting the sensitivity and throwing an electromagnetic shockwave at the victim board) or the OTP Challenge, explained in a few lines latter.
In the Glitch Sensitivity Menu, it is possible to configure the sensitivity for the glitch detectors.
This section aims to glitch the OTP (One Time Programming) values in the register CRIT1. This register covers:
- Glitch detectors sensitivity
- Glitch detectors enablement
- Boot architecture
- Debug disable
- Secure debug disable
- Secure boot enable
Initializes the peripherals and periodically executes the routines described before.
This header file includes functions for watchdog, UART, and GPIOs. The physical inputs are assigned to move on the menu. Other functions related to the Glitch detector are defined with default values.
Finally, the rp2350_playground.c file includes code for controlling the general inputs, setting the UART parameters, arm, and locking the glitch detector.
Our “Victim Board”
Since we could not get the original board created by Hextreeio, and we did not have a Raspberry Pi Pico 2 development board, we used the Badge of DEFCON 32[3] we had.
In general, this badge can be customized in many different ways, according to the user's application.
Its general features are the following:
- ABS injection molded case to protect your badge from weekend shenanigans
- Screen Flip / Orientation Sensor for wearable gameplay
- Customizable RGB LEDs
- SAO support
- USB-C & rechargeable Li-ion battery
- SD Card (also holds some goodies for your PC)
- IR communication
- Real-Time Clock
- Touch Screen
We had to make some modifications to the firmware to make it work on our board. Mostly related to using an additional display (SSD1306) to deploy the menu and the buttons for navigating through it.
We tested the continuity of the buttons and the I2C pins to find out which GPIO they were connected to.
We selected the buttons we were going to use and, finally, the setup came as follows:
Modifications to the code
Our modifications to the code:
We had to uncomment line 4 on the rp2350_playgroung.c file and line 5 in the main.c file to include the glitch_detector features.
We added a #define GLITCH_DETECTOR_ON line to allow the execution of the instructions to set the sensitivity levels.
We commented on the instructions related to UART, as we did not use them. This also applied to any instructions in the main.c and rp2350_playground.c files. The GPIO numbers for the joystick pins were also modified. After all, we only needed to use JOY_S, JOY_N, JOY_W, and JOY_PUSH.
The display.c file was modified to specify which I2C instance and pins we will use. In this case, we enabled the I2C default, instead of using other pins as I2C.
Compiling the modified code
1. To compile the code and get the new UF2 file to be loaded to the board, we created the pico-sdk path, and then, used the commands to set the board that will run this application. Finally, we ran the command make.
2. Once compiled, we set the RP2350 in bootloader mode, so it can be recognized as a storage device.
3. The UF2 file was dragged and dropped (or copied and pasted) into the RP2350 storage device.
Now, this application will enable the RP2350’s glitch detector features.
Application overviewTo change the victim board’s sensitivity, we use the buttons to move inside the menu:
On the other hand, the distance between the MCU and the antenna, and the power of the pulse matter in the final behavior. It is possible to change the FaultyCat’s parameters so that the intensity of the electromagnetic wave may affect the behavior of a victim MCU on different levels. In this case, the power is the most important parameter we can change to notice the glitch's effects.
To change the power of the electromagnetic shockwave we produced, we used the command c:
A few tries later, these were some of the outcomes we got:
The power set is inversely proportional to the voltage stored in the capacitor, which collects the energy to be discharged in every pulse. That means, a power of 0.0150 will produce a stronger pulse than a power of 0.025.
Live action!Check out the application, running alive!
Happy hacking! 😼
References
[1] Raspberry Pi. RP2350 Datasheet. [Online]. Available at: https://datasheets.raspberrypi.com/rp2350/rp2350-datasheet.pdf
[2] Hextreeio. [Online]. Available at: https://www.hextree.io/
[3] DEFCON. DC32 Human Badge. [Online]. Available at: https://shop.defcon.org/products/dc32-badge?srsltid=AfmBOor4tePQ8LTQstWfl9qX4kXKYSXcj5mCefbIlq8GmVvcj_-bKCNd
Comments