{"article":{"slug":"laser-fault-injection-on-a-budget-rp2350-edition","title":"Laser Fault Injection on a Budget: RP2350 Edition","subtitle":null,"summary":"Courk details a custom, low-cost laser fault injection platform built to beat the Raspberry Pi RP2350 Hacking Challenge, including die imaging, boot ROM analysis, FPGA and laser driver design, and how a single laser-induced fault bypasses the RP2350's Secure Boot.","content_type":"research","language":"en","canonical_url":"https://courk.cc/rp2350-challenge-laser","author":{"name":"Courk","url":"https://courk.cc/","person_slug":null,"person_url":null},"authored_by":"human","publisher":{"name":"Courk's Blog","url":"https://courk.cc/","listing_slug":null,"listing":null},"topics":[{"name":"Hardware Security","slug":"hardware-security","url":"https://listedarticles.com/topics/hardware-security"},{"name":"Embedded Systems","slug":"embedded-systems","url":"https://listedarticles.com/topics/embedded-systems"},{"name":"Electronics","slug":"electronics","url":"https://listedarticles.com/topics/electronics"}],"about_listings":[],"cover_image_url":null,"license":"CC-BY-SA-4.0","word_count":8307,"reading_minutes":36,"published_at":"2025-01-14T15:00:00.000Z","added_at":"2026-10-18T05:17:02.827Z","updated_at":"2026-10-18T05:17:02.827Z","added_via":"api","contributor":{"type":"agent","name":"ListedStartups Using Bot","registered":true},"profile_url":"https://listedarticles.com/articles/laser-fault-injection-on-a-budget-rp2350-edition","markdown_url":"https://listedarticles.com/articles/laser-fault-injection-on-a-budget-rp2350-edition.md","example":false,"citation":"Courk, Courk's Blog. \"Laser Fault Injection on a Budget: RP2350 Edition.\" 14 Jan 2025. https://courk.cc/rp2350-challenge-laser (CC-BY-SA-4.0)","access":{"human_view":"preview","full_text_available":true,"source_url":"https://courk.cc/rp2350-challenge-laser"},"body_markdown":"# Laser Fault Injection on a Budget: RP2350 Edition\n\n# Introduction\n\nIn August 2024, *Raspberry Pi* [introduced the `RP2350` microcontroller](https://www.raspberrypi.com/news/raspberry-pi-pico-2-our-new-5-microcontroller-board-on-sale-now/). This part iterates over the `RP2040` and comes with numerous new features. These include security-related capabilities, such as a *Secure Boot* implementation.\n\nA couple of days after this announcement, during [*DEFCON* 2024](https://defcon.org/), an interesting challenge targeted at these new features was launched: the [*RP2350 Hacking Challenge*](https://www.raspberrypi.com/news/can-you-hack-our-new-chip/).\n\nAfter some work and the development of a fully custom *“Laser Fault Injection Platform”*, I managed to beat this challenge and submitted my findings to *Raspberry Pi*.\n\nThis article will provide technical details about this custom platform, including [manufacturing files](https://courk.cc/laser-fault-injection-platform-hardware-files) for those interested in building their own. Additionally, I will explain how injecting a single laser-induced fault can bypass the *Secure Boot* feature of the `RP2350`.\n\nWarning\n\nThe *“Laser Fault Injection Platform”* introduced in this article makes use of an infrared high-power laser source. Such a component can be hazardous; be careful if you attempt to reproduce this work.\n\n---\n\n# Hacking Challenge & RP2350 Security Features\n\n## Objectives of the Challenge\n\nThe target of this challenge is a [*Pico 2* board](https://www.raspberrypi.com/products/raspberry-pi-pico-2/), which hosts a `RP2350` microcontroller. It must be configured according to the instructions provided in the [challenge’s GitHub repository](https://github.com/raspberrypi/rp2350_hacking_challenge/).\n\nFollowing the instructions from the repository will:\n\n- Write “secret” data into one of the *OTP* areas of the `RP2350`.- Configure and enable the *Secure Boot* feature, locking the chip as much as possible. This includes disabling debug interfaces (*SWD*) and enabling various security features, such as glitch detectors.- Flash a signed firmware that primarily restricts even more access to the *OTP* area where the secret is stored.\n\nThe goal of the challenge is to find a way to recover the secret data, potentially bypassing the *Secure Boot* feature in the process.\n\n## Security Features\n\nThe *Secure Boot* feature is enforced by code contained in the *Boot ROM* of the `RP2350`. This code is hardened in several ways, going beyond software methods; the *Boot ROM* leverages hardware-specific features.\n\nThese features are primarily related to an innovative component called the “Redundancy Co-Processor.” Quoting the [RP2350 Datasheet](https://datasheets.raspberrypi.com/rp2350/rp2350-datasheet.pdf):\n> The redundancy coprocessor (RCP) is used in the RP2350 bootrom to provide hardware-assisted mitigation against fault injection and return-oriented programming attacks. This includes the following instructions:\n>\n> - generate and validate stack canary values based on a per-boot random seed- assert that certain points in the program are executed in the correct order without missing steps- validate booleans stored as one of two valid bit patterns in a 32-bit word- validate 32-bit integers stored redundantly in two words with an XOR parity mask- halt the processor upon reaching a software-detected panic condition\n>\n> […]\n>\n> Each core’s RCP has a 64-bit seed value (Section 3.6.3.1). The RCP uses this value to generate stack canary values and to add short pseudorandom delays to RCP instructions.\n\nAdditionally, the `RP2350` is capable of detecting fault injection attempts using glitch detectors. These configurable circuits respond to voltage or electromagnetic fault-injection attempts and reset the system. For this challenge, these detectors are set to their maximum sensitivity level.\n\n---\n\n# Article Overview\n\nBelow is a brief, high-level summary of the article’s content.\n\n## Why choosing Laser Fault Injection\n\nConsidering that the *Boot ROM* of the `RP2350` has been audited before the opening of the challenge, I did not attempt to find logic bugs in it and quickly considered a hardware attack, such as a fault injection attack.\n\nHowever, [online comments](https://xcancel.com/barsteward/status/1831365943169270077) tend to show that the glitch detector system implemented in the `RP2350` was rather efficient in mitigating simple voltage fault injection attacks.\n\nHence, I quickly decided to tackle the challenge with laser fault injection, assuming that focusing a laser beam away from the glitch detector circuits could allow for injecting faults without triggering them.\n\nNow, the thing is, while I did have some experience with [“classic” voltage fault injection attacks](https://courk.cc/esp32-c3-c6-fault-injection), I knew nothing about laser fault injections.\n\nThis challenge was then used as an opportunity to build a fully custom, cheap laser fault injection platform.\n\nNote that while traditionally known to be expensive to implement, several “cheap” platforms aimed at injecting faults with a laser have emerged over the past few months:\n\n- [Laser Fault Injection for The Masses](https://blog.fraktal.fi/laser-fault-injection-for-the-masses-1860afde5a26) is repurposing laser engraving hardware.- The [*“RayV-Lite”* from *NetSPI*](https://www.wired.com/story/rayv-lite-laser-chip-hacking-tool/). ~~However, at the time of writing, very few publicly available technical details are available regarding this project.~~\n\nNote\n\nMy mistake, after some research, I actually managed to find [this presentation of the *“RayV-Lite”*](https://vimeo.com/998515104) introduced at [Blackhat 2024](https://www.blackhat.com/us-24/briefings/schedule/#laser-beams--light-streams-letting-hackers-go-pew-pew-building-affordable-light-based-hardware-security-tooling-39708). Their project presents various similarities with my *“Laser Fault Injection Platform”*, but also interesting differences. I’ll highlight some of these differences in this article and encourage you to check out their work.\n\n**August 2025 update:** Even more material is now publicly available! This includes [an article on *NetSPI*’s website](https://www.netspi.com/blog/technical-blog/hardware-and-embedded-systems-penetration-testing/rayv-lite-open-source-laser-injection-tool/).\n\n## Sample Preparation\n\nThe idea being *LFI* is reasonably simple. A focused laser beam is directed at the silicon die of the target component. Transistors are sensitive to photoelectric effects, meaning the emitted light can be enough to induce temporary faults or malfunctions. When precisely timed, these faults could be leveraged to bypass security features.\n\nA major downside of such an attack compared to voltage or clock glitching is that the silicon die of the target has to be exposed. Of course, the circuit must still be able to operate normally after the die has been exposed.\n\nAccessing the silicon can either be attempted from the top, or the bottom side of the packaged chip.\n\n![Simplified Top and Bottom Sides Render of a Packaged Integrated Circuit](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/top_bottom_ic.webp)\n\nSimplified Top and Bottom Sides Render of a Packaged Integrated Circuit\n\nI chose to expose performed from the backside of the die. This choice has been made for two reasons:\n\n- Accessing the backside can be achieved with cheap mechanical tools. However, exposing the top of the die would have required chemicals I would rather not deal with, such as [concentrated nitric acid](https://jcjc-dev.com/2020/10/20/learning-to-decap-ics/).- Based on [images available online](https://electronupdate.blogspot.com/2024/08/pi-pico-2-extreme-teardown.html), it seems the top of the die is fully covered by a metal layer, likely complicating fault injection.\n\nThe process I developed to expose the backside of the silicon die is detailed in the relevant sections of this article.\n\n## Die Imaging & Laser Focusing\n\n*LFI* requires targeting with a focused laser beam relatively precise areas of the die. A custom, cheap *Laser Fault Injection platform* has been designed for this purpose.\n\n![The Laser Fault Injection Platform](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-large/1x/platform_global_view.jpg)\n\nThe Laser Fault Injection Platform\n\nBecause the design of this platform is very budget oriented, corners had to be cut in multiple paces, resulting in various limitations. These limitations, alongside various technical details and working principles, are detailed in the corresponding sections of this article.\n\nTo enable others to reproduce my results, I will also be sharing the relevant manufacturing files and source code.\n\n## Fault Injection & Secure Boot Bypass\n\nBeing able to inject faults is just the first step in attacking the `RP2350`. As previously mentioned, the glitch detectors are not the only security feature that *Raspberry Pi* developed to protect the system.\n\nIt is also necessary to identify a weakness in the *Boot ROM* of the component, where the *Secure Boot* feature is implemented. The specific sequence of instructions I targeted will be discussed in the relevant sections of this article.\n\n---\n\n# Sample Preparation\n\nThis section describes the initial steps required to execute the attack. The backside of the die of the target `RP2350` must be carefully exposed, ensuring that the chip’s functionality remains intact.\n\n## Die Exposure\n\nThe target `RP2350` first has to be desoldered from the *Pico 2* board. This can be achieved with a simple hot air reflow station.\n\nNext, a cheap (€30) dremel-like tool, advertised as an “Engraving Tool” (Amazon Part Number: `UKH062_FR`), has been used to carefully remove material around the ground pad.\n\n![The tool used to expose the die](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/dremel_tool.jpg)\n\nThe tool used to expose the die\n\nAfter enough material has been removed, the metallic ground pad can be taken off, exposing a layer of what looks like silver (heat-conductive?) paste. This paste can easily be scratched out, revealing the backside of the die.\n\n![Exposed Backside after Mechanical Grinding](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/backside_dremel.jpg)\n\nExposed Backside after Mechanical Grinding\n\n## Main Carrier Board\n\nThe prepared sample can then be soldered on a custom *PCB*, designed to integrate with the *Laser Fault Injection Platform*.\n\n![RP2350 Backside Carrier Board](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/carrier_board.jpg)\n\nRP2350 Backside Carrier Board\n\nA hole in the middle exposes the backside of the `RP2350` die.\n\n![Backside view of the board, the die is visible](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/backside_before_glue.jpg)\n\nBackside view of the board, the die is visible\n\nThe board doesn’t include anything more, apart from a small *LDO* used to power the core. Power and control signals are routed away to an *FFC* connector.\n\n```\n        flowchart LR\n            B{{FFC Connector}} &LT-->|UART| A(RP2350)\n            A &LT-->|SWD| B\n            A &LT-->|USB| B\n            A &LT-->|QSPI| B\n            A &LT-->|Control Signals| B\n            B .->|3V3| A\n            B .->|3V3| C((LDO))\n            C .->|1V1|A\n```\n\nMain Carrier Board Architecture Diagram\n\nThis *PCB* can be hand-assembled, and the total unit *BOM* cost for small quantities is estimated at less than €10.\n\n[![Interactive 3D Render & Design Files](https://courk.cc/rp2350-challenge-laser/assets/main_carrier_board_icon.webp)   \nInteractive 3D Render & Design Files](https://courk.cc/laser-fault-injection-platform-main-carrier-board \"Interactive 3D Render & Design Files\") \n\n## I/O Board\n\nThe *Main Carrier Board* detailed above connects to the *I/O Board* through a *FFC* cable.\n\n![I/O Board and Main Carrier Board, placed in a 3D-printed holder](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/backside_boards.jpg)\n\nI/O Board and Main Carrier Board, placed in a 3D-printed holder\n\nThe assembly of these two boards is designed to integrate with the *Laser Fault Injection Platform*.\n\n![I/O Board and Main Carrier Board, placed in the Laser Fault Injection Platform](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/backside_boards_in_system.jpg)\n\nI/O Board and Main Carrier Board, placed in the Laser Fault Injection Platform\n\nThe *I/O Board* breaks out the various control signals over:\n\n- A *USB* connector- Pin headers that are connected to a *FPGA* board, later used to implement the attack’s logic- A few test points used for *SWD* debugging (seldom used, especially considering *SWD* needs to be disabled for this challenge)\n\n```\n        flowchart TB\n            A((LDO)) .->|3V3| B((Power Switch))\n            C{{USB Connector}} .->|5V| A\n            C &LT-->|USB| D{{FFC Connector}}\n            B .->|3V3| D\n            E{{Pin Headers}} -->|Enable| B\n            D &LT-->|Control Signals| E\n            D &LT-->|QSPI| E\n            D &LT-->|UART| E\n            D &LT-->|SWD| F(Test Points)\n            D &LT-->|QSPI| G(QSPI Flash #0)\n            D &LT-->|QSPI| H(QSPI Flash #1)\n```\n\nI/O Board Architecture Diagram\n\nAdditionally, two *QSPI* flashes are mounted to the board. The “active” flash, *i.e.* the one connected to the `~CS` line of the `RP2350`, can be selected from the *FPGA*. This means the “active” flash can be swapped between each request from the `RP2350` to the external memory.\n\nThis feature, detailed in the following diagram, is instrumental for the attack described in this article.\n\n```\n        flowchart LR\n            A(RP2350) -->|CS| B(FPGA)\n            B -->|CS#0| C(QSPI Flash #0)\n            B -->|CS#1| D(QSPI Flash #1)\n```\n\nDual Flash System\n\nHere again, the board can be hand-assembled. The total unit *BOM* cost for small quantities is estimated to be less than €15.\n\n[![Interactive 3D Render & Design Files](https://courk.cc/rp2350-challenge-laser/assets/io_board_icon.webp)   \nInteractive 3D Render & Design Files](https://courk.cc/laser-fault-injection-platform-io-board \"Interactive 3D Render & Design Files\") \n\n## Ground Connection Repair\n\nNote\n\n**August 2025 update:** The method detailed here is overcomplicated. See [Laser Fault Injection on a Budget: DEFCON 33 Showcase](https://courk.cc/lfi-defcon-content) for a simpler method.\n\nAn obvious issue with removing the ground pad to access the die is that the only ground connection to the integrated circuit is destroyed.\n\nThe `RP2350` has a `PGND` pin connected to its internal *DC/DC* converter, but it doesn’t seem to have a low-impedance internal connection to ground. Instead, a method to restore a sufficient ground connection has been implemented.\n\nIt’s a bit challenging to see, but specks of exposed copper (or gold?), as well as “holes” where severed bond wires likely passed, are visible. Slightly scratching these areas can sometimes reveal more conductive material.\n\n![Visible metal specks near the exposed die](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/copper_view_1.jpg)\n\nVisible metal specks near the exposed die\n\nMagnified views of areas `1` and `2` are shown below.\n\nNote\n\nNote that these magnified images have been captured thanks to the imaging capabilities of the *Laser Fault Injection Platform*. This results in unusual colors, as the camera sensor of the platform lacks an *IR* filter.\n\n![Magnified view of Area 1](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/copper_view_2.jpg)\n\nMagnified view of Area 1\n\n![Magnified view of Area 2](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/copper_view_3.jpg)\n\nMagnified view of Area 2\n\nApplying conductive epoxy between these small exposed metal bits and purposefully arranged copper pads located on the *Carrier Board* was, thankfully, enough to restore a sufficient ground connection.\n\n![View of the applied epoxy glue, after curing](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/backside_after_glue.jpg)\n\nView of the applied epoxy glue, after curing\n\nThe reference for the product I used is [`MG CHEMICALS 9410`](https://fr.farnell.com/en-FR/mg-chemicals/9410-3ml/thermally-conductive-adhesive/dp/2889799). It’s a one-part, temperature-activated epoxy. I used a hot air station at 150°C150°C150°C for about 10 minutes to cure it.\n\n## Limitations\n\nThis process is, of course, a bit risky. While I’ve gotten better at it after a few attempts, I don’t think I can claim a 100% success rate.\n\nAdditionally, the ground connection restored thanks to the conductive epoxy is far from perfect. For instance, I’m usually not able to run such a modified `RP2350` at high clock speeds, as it results in higher current being drawn.\n\nFinally, I found that some *I/O* pads can sometimes stop working, or are facing signal integrity issues. I’m not sure all ground bond wires are internally connected on the die; I may not restore a good enough connection for all of them.\n\nHowever, the target of the attack is the *Boot ROM*. The hardware is configured very conservatively by this *ROM*: clock speeds are low, etc. In this context, the “ground connection repair” method appears to be good enough.\n\nTo overcome these issues, it may be possible to mill only the very center of the ground pad, exposing the die while keeping the bond wires intact. This would likely require access to a *CNC* milling machine and fine bits, which I currently do not have.\n\n---\n\n# Laser Fault Injection Platform\n\n## Platform Overview\n\nAs explained above, a custom fault injection platform has been designed for this project. While this hardware setup may not compete with more professional systems in terms of repeatability, it is likely an order of magnitude cheaper.\n\n![The Platform, fitted with the custom RP2350 Electronics](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-large/1x/platform_global_view_alt.jpg)\n\nThe Platform, fitted with the custom RP2350 Electronics\n\nThe platform can be divided into two subsystems, each of which will be detailed separately:\n\n- A positioning stage, used to precisely displace the die of the target `RP2350` for observation and laser focusing.- An optical subsystem, utilized for visualizing this die and focusing high-power laser pulses onto it.\n\n[![Interactive 3D Render](https://courk.cc/rp2350-challenge-laser/assets/entire_system_icon.webp)   \nInteractive 3D Render](https://courk.cc/laser-fault-injection-platform-3d-render \"Interactive 3D Render\") \n\n## Positioning Stage\n\nThe positioning stage is based on the [*OpenFlexure* Delta Stage](https://build.openflexure.org/openflexure-delta-stage/v1.2.2/) [(McDermott et al., 2022)](#McDermott:22). *OpenFlexure* projects are impressive, and I would not have achieved much without them. High-precision mechanical positioning is made possible with simple 3D printed parts and affordable stepper motors.\n\nNote\n\nThe [*“RayV-Lite”* system](https://www.blackhat.com/us-24/briefings/schedule/#laser-beams--light-streams-letting-hackers-go-pew-pew-building-affordable-light-based-hardware-security-tooling-39708) is also based on an *OpenFlexure* project, but not on the *Delta Stage* I selected here.\n\nMinor modifications have been made to the official *OpenFlexure* Delta Stage:\n\n- The base of the stage was raised to accommodate the custom optical subsystem.- Heat-set threaded inserts have been added in various locations to support the custom electronics introduced in the previous sections of this article.\n\n[![Interactive 3D Render & Design Files](https://courk.cc/rp2350-challenge-laser/assets/delta_stage_icon.webp)   \nInteractive 3D Render & Design Files](https://courk.cc/laser-fault-injection-delta-stage \"Interactive 3D Render & Design Files\") \n\n## Optical Subsystem\n\nThe optical subsystem is utilized for visualizing the die and focusing high-power laser pulses onto it. This subsystem is inspired from the [reflection illumination subsystem](https://build.openflexure.org/openflexure-delta-stage/v1.2.2/pages/index_reflection.html) from the *OpenFlexure project*. However, unlike the positioning stage, significant modifications have been implemented.\n\n[![Interactive 3D Render & Design Files](https://courk.cc/rp2350-challenge-laser/assets/optical_assembly_icon.webp)   \nInteractive 3D Render & Design Files](https://courk.cc/laser-fault-injection-optical-assembly \"Interactive 3D Render & Design Files\") \n\n### The Necessity of Using Infrared Light\n\nOne of the downsides of attacking the die from its backside is that infrared light has to be used. Indeed, silicon is almost fully opaque to visible light, preventing both visualization and fault injection.\n\nInstead, infrared light with a wavelength of 1064nm1064nm1064nm is utilized. This wavelength is traditionally employed for backside fault injection and can also, as demonstrated in *Infra-Red, In Situ (IRIS) Inspection of Silicon* [(bunnieHuang, 2023)](#huang2023infraredinsituirisinspection), be used for visualization of the die’s features.\n\n### Optical Components\n\nThe 3D render available below is extracted from the complete [Laser Fault Injection Platform 3D Render](https://courk.cc/laser-fault-injection-platform-3d-render). Only the components relevant to the imaging and laser focusing features are displayed and annotated.\n\n![Optical Components](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/optical_3d_render.webp)\n\nOptical Components\n\nThe following items are visible. Refer to the [Optical Assembly page](https://courk.cc/laser-fault-injection-optical-assembly) for exact part numbers or sourcing details.\n\n1. **The Laser Driver Board** - This custom *PCB* is used to drive a laser diode, emitting short but powerful pulses of light. This piece of hardware will be detailed later in this article.- **Objective Lens** - This is an off-the-shelf microscope objective lens. I wanted an infinity-corrected one to make focusing the laser beam easier. Unfortunately, these are typically more costly than finite-corrected ones. I obtained one for about €90 from *AliExpress*.- **Oblique Illumination System** - This is a simple 1064nm1064 \\text{nm}1064nm *LED*, used for imaging the die. During my tests, I noticed that illuminating the sample from its side, with a rather narrow angle, resulted in the best image contrast.- **Imaging Camera** - This is a *Raspberry Pi Camera v2 “NoIR”*. As it does not have an *IR* filter, it remains a bit sensitive to the wavelength of interest.\n\nRemoving even more objects, including the 3D-printed parts that are holding things together, the following new optical elements become visible.\n\n![Optical Components, Without 3D-printer Parts](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/optical_elements.webp)\n\nOptical Components, Without 3D-printer Parts\n\n1. **Laser Diode** - A 1064nm1064 \\text{nm}1064nm laser diode. This tiny component was by far the most challenging part to source. I negotiated five pieces on *Alibaba* for about €300.- **Adjustable Collimating Lens** - A screwable lens used to collimate the output of the laser diode. It can be purchased in bulk for a low price on *AliExpress*.- **Beam Splitter** - This piece of glass is specially coated to reflect a fraction of the incoming light while transmitting the other part. Purchased for a reasonable price on *AliExpress*.- **Tube Lens** - Once again, purchased for a reasonable price on *AliExpress*.\n\nAs explained, most of these components are off-the-shelf and have been sourced cheaply from *Aliexpress*. However, there is still a cost: these parts are often poorly specified or designed primarily for traditional microscopy applications, where only visible light is considered. As a result, I suspect that some infrared laser light is wasted and that the imaging may suffer from chromatic aberrations.\n\n### Optical Paths\n\n#### Imaging\n\nThe path followed by the light to ensure the “Imaging” feature of the assembly is highlighted below.\n\n![Path followed by the light leaving the oblique imaging LED](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/imaging_optical_path.webp)\n\nPath followed by the light leaving the oblique imaging LED\n\nThe sample is first illuminated by the 1064nm1064 \\text{nm}1064nm Oblique Illumination *LED*. This wavelength passes through the silicon and reflects off the features of the die.\n\nNote\n\nWhile not as powerful as the laser, this *LED* still seems to interact with the circuit in some way.\n\nIn particular, I noticed that it was sometimes impossible for the system to boot when the die was illuminated by the *LED*. I suspect that analog circuits, which may be more sensitive than digital ones, are affected.\n\nTo avoid this problem, the *LED* is only turned on to image the die and align the laser beam. It is turned off during the attack process.\n\nNext, this light passes through the infinity-corrected lens before being imaged back to the camera sensor thanks to the tube lens.\n\nIn between, the light goes through the beam splitter. A fraction of the light will be transmitted and continue in the same direction. The reflected fraction of the light is lost.\n\nThe selected beam splitter has the following properties:\n\n- Reflection coefficient: 90%- Transmission coefficient: 10%\n\nThis prioritizes the light coming from the laser beam, whose path is detailed below.\n\n#### Laser Focusing\n\nThe path followed by the light to implement the “Laser Focusing” feature of the assembly is highlighted below.\n\n![Path followed by the light leaving the laser diode](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/laser_diode_optical_path.webp)\n\nPath followed by the light leaving the laser diode\n\nA pulse of light is emitted from the laser diode. This light is diverging and is collimated with the Adjustable Collimating Lens.\n\nMost (90%) of the collimated light is reflected by the beam splitter and sent through the objective lens, where it is focused on the target sample.\n\n### Imaging Results\n\nBelow are a couple of slightly processed images of the die obtained from the setup.\n\n![Imaging Result Example 1](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/die_imaging_1.jpg)\n\nImaging Result Example 1\n\n![Imaging Result Example 2](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/die_imaging_2.jpg)\n\nImaging Result Example 2\n\nAdditionally, you will find a zoomable stitched view of the entire die.\n\nNote\n\nThe quality of the stitching is obviously very poor; the processing tool I used struggles with the low-contrast images I provided.\n\nFor completeness, the following video demonstrates what is visible in real-time through the *OpenFlexure* web-based interface.\n\nWhile these images may definitely not match the quality produced by a professional setup, they are sufficient to align a laser beam with specific features of the die.\n\nThe limiting factor may be the *CMOS* camera sensor, which is only marginally sensitive to 1064nm1064nm1064nm. Unfortunately, cameras that are sensitive to these wavelengths tend to be quite expensive.\n\nFor a much better view of the backside of the die, check-out [the one shared by @LennertWo](https://xcancel.com/LennertWo/status/1826891922679476283).\n\n### Laser Focusing Results\n\nThe properties of the focused beam aren’t great, and the resulting spot is rather large and elliptical. That’s not ideal, as the goal is to achieve a high-power density to inject a fault.\n\nAn example of the resulting spot is available below. Note that here, the laser was pulsed at a reduced power to avoid blinding the camera sensor.\n\n![Focused laser beam, as seen from the camera sensor](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/focused_beam_example.jpg)\n\nFocused laser beam, as seen from the camera sensor\n\nThis problem has been mitigated by increasing the power supplied to the laser diode from the *Laser Driver Board*.\n\nMultiple factors can explain the poor shape of the laser spot:\n\n- The lenses I used are only specified for visible light.- The focusing method is simple and possibly a bit naive; I’m no optical expert.- Most importantly, the laser diode I used is a high-power one; the emitting element is large, and the light coming out of it is very diverging, with large differences between the [fast and slow axes](https://en.wikipedia.org/wiki/Laser_diode#Formation_of_laser_beam).\n\n---\n\n# Laser Driving\n\nWarning\n\nThis is where things can get dangerous. Although the custom board described here produces only very short pulses, working with a high-power laser can be hazardous, particularly when the emitted light falls outside the visible spectrum.\n\nBe careful if you attempt to reproduce this work.\n\nLaser fault injection requires short, high-power light pulses to be transmitted. A custom board has been designed for this purpose.\n\n![Laser Driver Board, Top View](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/laser_pulser_top.jpg)\n\nLaser Driver Board, Top View\n\nMost of the electronics are located on the top side of the board, with a laser diode installed on the bottom side.\n\n![Laser Driver Board, Bottom View](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/laser_pulser_bottom.jpg)\n\nLaser Driver Board, Bottom View\n\nWhile designing such a board was not overly complicated, finding a suitable laser diode turned out to be more challenging.\n\n![Laser Driver Board, installed in the Fault Injection Platform](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium-plus/1x/laser_pulser_in_use.jpg)\n\nLaser Driver Board, installed in the Fault Injection Platform\n\nNote\n\nAs visible in the pictures of the boards, a section of the circuit has been reworked. This has been done to adjust the laser pulse parameters, as detailed below. The shared schematics have been updated to reflect this rework.\n\n[![Interactive 3D Render & Design Files](https://courk.cc/rp2350-challenge-laser/assets/laser_driver_icon.webp)   \nInteractive 3D Render & Design Files](https://courk.cc/laser-fault-injection-platform-laser-driver-board \"Interactive 3D Render & Design Files\") \n\n## Board Architecture\n\nThe architecture of the *Laser Driver Board* is outlined below.\n\n```\n        flowchart TB\n            A{{USB Connector}} &LT--> B(USB to I2C Bridge)\n            B -->|Configure| C(Digital Potentiometer)\n            B -->|Trigger| E\n            C .-> D(High Voltage Power Supply Circuit)\n            D .-> E(Pulse Generator Circuit)\n            E .-> F(Laser Diode)\n            G{{Pin Header}} -->|Trigger| E\n            F -->|Current Sense| H{{SMA Connector}}\n```\n\nLaser Driver Board Architecture\n\nThe board is powered and configured from a *USB* port. The host computer connected to this port can be used to:\n\n- Configure the output level of a high-voltage (up to 75V75V75V) power supply. This high supply is needed for the pulse generator circuit to operate.- Manually send laser pulses.\n\nHowever, because *USB* cannot be used for anything time-critical, laser pulses can also be generated from a simple pin header connector. This connector is interfaced with a *FPGA* board during the attack.\n\nAn *SMA* connector can be used to monitor the shape and intensity of the current pulses passing through the laser diode.\n\n## Pulse Generation Principle\n\nA simplified schematic of the pulse generation circuit is outlined below.\n\n![Simplified Pulse Generator Circuit](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/RLC_driver.webp)\n\nSimplified Pulse Generator Circuit\n\nThe capacitor `C` is first charged from the high-voltage power supply. To trigger a current pulse through the laser diode, the switching element `SW` is closed.\n\nThe current response is close to the one observed with a typical `RLC` circuit. The value of `R` is chosen to ensure the response of the circuit is critically damped.\n\n`C` and `L` can be fine-tuned to change the duration of the pulse, while the high-voltage level can be used to set the peak current.\n\nUnfortunately, this means that changing the pulse duration is only possible by soldering new components onto the board. I had to perform this rework several times, gradually increasing the peak current until faults were successfully injected.\n\nThe values that have been used to successfully exploit the `RP2350` are:\n\n- R=1.4ΩR = 1.4 \\OmegaR=1.4Ω- L=33nHL = 33 \\text{nH}L=33nH- C=60nFC = 60 \\text{nF}C=60nF\n\nNote that the selected resistor must be able to handle high current pulses. After having destroyed several parts, I ended up using [Vishay’s `CMB 0207` family](https://www.vishay.com/en/product/28956/).\n\nThe selected `RLC` values result in the following theoretical current pulses.\n\nIn practice, the pulses generated by the hardware are reasonably close to these theoretical curves.\n\n![Voltage Measured from the SMA Connector of the Laser Driver Board](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/sma_voltage.webp)\n\nVoltage Measured from the SMA Connector of the Laser Driver Board\n\nUnfortunately, in part because the optical components (lenses, beam splitter) I used are not specified for infrared light, I’m not sure how these current curves translate to the actual optical power received on the die surface.\n\nFinally, note that the switching element `SW` is implemented with a fancy *GaN* *FET*. This choice was initially made to experiment with ultra-short pulses. However, it turns out that this wasn’t particularly useful. The *BOM* cost could be reduced by opting for a simpler *MOSFET* instead.\n\nDespite this, the price of this *BOM* for small quantities does not exceed €30, excluding the cost of the laser diode.\n\n## Laser Diode Sourcing\n\nFinding a suitable laser diode was challenging. It turns out high-power 1064nm1064 \\text{nm}1064nm laser diodes are difficult to find and expensive!\n\nAfter a few unsuccessful attempts (*i.e.* not enough power to inject a fault without damaging the diode first) with low-power parts (below 300mW300 \\text{mW}300mW), I contacted a manufacturer on *Alibaba* and was able to order, for about €300, five pieces of a part rated for 3W3 \\text{W}3W. The datasheet for this part is available [here](https://courk.cc/rp2350-challenge-laser/assets/TO5_3W_1064nm_laser_diode.pdf).\n\nThis datasheet clearly states that the maximum operating current is 3.8A3.8 \\text{A}3.8A. Based on the current curves shared above, it’s very obvious the part is used well above its rating.\n\nWhile I anticipated encountering [catastrophic optical damage issues](https://en.wikipedia.org/wiki/Catastrophic_optical_damage), even after several thousand pulses, I don’t think I have harmed these diodes yet! This might be due to the short duration of the current pulses.\n\nThis surprising result matches the observation of *Continuous wave laser diodes enable fast optoacoustic imaging* [(Stylogiannis et al., 2018)](#STYLOGIANNIS201831):\n> We investigated whether continuous wave (CW) laser diodes, which are available in visible and near-infrared regions, can be good optoacoustic light sources when overdriven with a peak current >40-fold higher than the CW absolute maximum.\n\nNote\n\nA major difference between my work and that of the team behind the [*“RayV-Lite”* system](https://www.blackhat.com/us-24/briefings/schedule/#laser-beams--light-streams-letting-hackers-go-pew-pew-building-affordable-light-based-hardware-security-tooling-39708) is that they used a widely available laser diode marketed as a “green” one.\n\nThat’s a clever choice, as it seems that, because of the way green light is actually generated, such diodes typically emit a significant amount of power at 1064nm1064 \\text{nm}1064nm. [(Galang et al., 2010)](#galang2010greenlaserpointerhazard)\n\n---\n\n# Fault Injection Results\n\n## Identification of Sensitive Areas\n\nAfter developing the *Laser Fault Injection Platform*, it was time to actually attempt to inject faults into a `RP2350`.\n\nI first began studying the effect of laser pulses on a dummy firmware, similar to the one proposed by [*Hextree.io*](https://www.hextree.io/) in their [RP2350 Security Playground Demo](https://github.com/hextreeio/rp2350-security-playground-demo).\n\nI slowly scanned various areas of the die, varying laser power, focus, and other parameters. However, I did not attempt to comprehensively characterize the behavior of the system over the entire die surface area for the following reasons:\n\n- It’s a slow process; in the interest of time, I stopped as soon after I was able to disturb the *ARM* core execution flow without triggering the *Glitch Detectors*.- I hit a couple of areas that resulted in a full crash of the system and high power consumption. Considering that preparing samples is a bit tedious, I would rather not damage parts this way.\n\nThe sensitive surfaces I exploited are roughly located within the area highlighted below. Because the positioning repeatability of the *Laser Fault Injection Platform* isn’t perfect, while attempting to exploit the chip, I typically moved the beam slowly around these locations.\n\n![Rough location of the area that is usually targeted to inject faults](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/sensitive_area.jpg)\n\nRough location of the area that is usually targeted to inject faults\n\nI found that depending on where the code is running from (*SRAM*, *Flash*, or *ROM*), or possibly based on the type of instructions being executed, it appears that slightly different locations had to be targeted to obtain interesting results.\n\n## Targeting for Secure Boot Bypass\n\nThe exact beam location used for the first *Secure Boot* bypass I achieved is displayed below. Here, the laser is pulsed at a low power to avoid blinding the camera.\n\n![Laser beam position that led to the first Secure Boot bypass](https://courk.cc/rp2350-challenge-laser/assets/laser_pulse_animation_x1.webp)\n\nLaser beam position that led to the first Secure Boot bypass\n\n---\n\n# Secure Boot Feature Bypass\n\n## Constraints\n\nThanks to the *Laser Fault Injection Platform*, injecting faults without triggering the glitch detectors is now possible! However, this alone is not enough to bypass the *Secure Boot* feature implemented in the *Boot ROM* of the `RP2350`. Indeed, as highlighted earlier, the *Boot ROM* is hardened and uses various features to resist faults. Trivial methods, such as glitching a conditional branch choosing between a valid or invalid signature, aren’t directly possible.\n\nFurthermore, when searching for a way to bypass the *Secure Boot* feature, the following constraints must be considered:\n\n- With my custom hardware, I can only hope to inject a single fault at a time; complicated schemes with multiple glitches in a row aren’t possible. The limiting factor is the *Laser Driver Board*: the capacitor bank needs a bit of time to be recharged after each pulse.- The laser pulse should be triggered following an observable external event, such as the activity of the *QSPI* bus.- Random delays can be introduced by some instructions executed by the redundancy co-processor. Ideally, to target specific instructions, few to none of these special instructions should be executed between the trigger event and the fault injection.\n\n## Boot ROM Analysis Method\n\nThe source code of the *Boot ROM* of the `RP2350` is [publicly available](https://github.com/raspberrypi/pico-bootrom-rp2350). That’s **really** nice, and it makes high-level analysis of the *Secure Boot* way easier! Kudos to *Raspberry Pi*!\n\nHowever, to study the possible impact of fault injections, I found it much easier to reflect directly against the actual *ARM* assembly code. Hence, after a quick read of the source code, I spent most of my time in [Ghidra](https://ghidra-sre.org/), looking at the content of the [*Boot ROM ELF* file, also shared by Raspberry Pi](https://github.com/raspberrypi/pico-bootrom-rp2350/releases/tag/A2).\n\nIn doing so, I managed to find a way to bypass the *Secure Boot* that addressed the previously listed constraints:\n\n- Things could work out with a single instruction “skip” (though “skip” may be a misnomer, “mutation” is maybe a better word).- The instruction to target closely follows an observable *QSPI* transfer.- At worst, a single random delay co-processor instruction is executed between the trigger and the instruction to target.\n\n## High-Level Idea\n\nLet’s consider the [`s_varm_crit_ram_trash_verify_block`](https://github.com/raspberrypi/pico-bootrom-rp2350/blob/451edbcd769770f92ce265c05d6c36ad040994fa/src/main/arm/varm_blocks.c#L587) function. This function is at the core of the *Secure Boot* implementation. A very stripped-down version of its implementation is available below.\n\n```\n// Start computing a hash\nsb_sha256_init(&sha);\n\n// Load the data from the flash to the RAM\ns_varm_crit_mem_copy_by_words((uint32_t *)to_storage_addr,\n                              resolve_ram_or_absolute_flash_addr(\n                                  from_storage_addr),\n                              (size + 3u) & ~3u);\n\n// Feed the hash engine with the data, obtained from RAM\nuint32_t *src = resolve_ram_or_absolute_flash_addr(to_storage_addr);\nsb_sha256_update_32(&sha, src, size & ~3u);\n\n// Include block data (containing source address, dest address and size)\n// to the SHA-256 hash\nsb_sha256_update_32(&sha, block_data, parsed_block->hash_def_block_words_included * 4);\n\n// Finalize the hash\nsb_sha256_finish(&sha, signature_workspace->hash.bytes);\n\n// Do the complicated & well protected signature validation\nsig_matches_image_keyx = s_arm8_verify_signature_secp256k1(signature_workspace->sig_context_buffer,\n                                                           &public_key[0],\n                                                           &signature_workspace->hash,\n                                                           &signature[0]);\n```\n\nThis code implements a very usual signature verification scheme: the firmware to validate is reduced down to a hash, which is fed to the signature verification algorithm.\n\n```\n        flowchart TD\n            A[(Firmware Data in Flash)] --> B(\"`Memory Copy\n            _s_varm_crit_mem_copy_by_words_`\")\n            B --> C[(Firmware Data in RAM)]\n            C --> D(\"`SHA-256\n            _sb_sha256_update_32_`\")\n            D --> E(\"`ECDSA Signature Verification\n            _s_arm8_verify_signature_secp256k1_`\")\n            F[[Public Key]] --> E\n            E -->|Signature Valid| R(Execute Firmware Data from RAM)\n            E -->|Signature Invalid| S(Failure)\n```\n\nNominal Firmware Verification Process\n\nThe idea is to inject a fault after the call to `s_varm_crit_mem_copy_by_words` and before the call to `sb_sha256_update_32`. This could result in the *SHA-256* hash being computed against different data than the one that was previously loaded into *RAM*.\n\n```\n        flowchart TD\n            A[(Firmware Data in Flash)] --> B(\"`Memory Copy\n            _s_varm_crit_mem_copy_by_words_`\")\n            B --> C[(Firmware Data in RAM)]\n            C --x Z@{ shape: bolt }\n            Z --> D(\"`SHA-256\n            _sb_sha256_update_32_`\")\n            D --> E(\"`ECDSA Signature Verification\n            _s_arm8_verify_signature_secp256k1_`\")\n            F[[Public Key]] --> E\n            E -->|Signature Valid| R(Execute Firmware Data from RAM)\n            E -->|Signature Invalid| S(Failure)\n            X[(Unexpected Data)] --> Z\n            style X fill:#f9f,stroke:#333\n            style Z fill:#f9f,stroke:#333\n```\n\nGlitched Firmware Verification Process\n\nIf the “unexpected data” used to compute the *SHA-256* hash can match the one corresponding to a valid firmware, the signature verification will succeed, no matter the data loaded into *RAM*.\n\n## Fault Injection Scenarios\n\nThis section explores the impact of possibly interesting faults against various instructions located between the call to `s_varm_crit_mem_copy_by_words` and the call to `sb_sha256_update_32`.\n\n### Scenario #1 - Single Instruction “Skip”\n\nNote\n\n“Skip” is possibly a misnomer. In practice, the targeted instruction here could be mutated. However, for this specific scenario, the exact result of the mutation doesn’t matter too much.\n\nThe *C* code listed above translates to the following assembly pieces.\n\n`s_varm_crit_mem_copy_by_words` is first called.\n\n```\n00001d5c: 1a 00              movs          r2,r3\n00001d5e: 20 00              movs          r0,r4\n00001d60: 0d 93              str           r3,[sp,#local_24]\n00001d62: 01 f0 82 fb        bl            varm_to_s_native_crit_mem_copy_by_words_impl\n00001d66: 0d 9b              ldr           r3,[sp,#local_24]\n00001d68: 43 ec 70 07        mcrr          p7,0x7,r0,r3,cr0\n00001d6c: ac e7              b             LAB_00001cc8\n```\n\nThe implementation of the function, listed below, increments `R1` until the target size has been reached.\n\n```\n0000346c: 19 fe 3a c7        mrc2          p7,0x0,r12,cr9,cr10,0x1\n00003470: 10 b5              push          {r4,lr}\n00003472: 03 46              mov           r3,r0\n00003474: 22 b1              cbz           r2,LAB_00003480\n00003476: 1a 44              add           r2,r3\n    LAB_00003478:\n00003478: 10 c9              ldmia         r1!,{r4}\n0000347a: 10 c0              stmia         r0!,{r4}\n0000347c: 90 42              cmp           r0,r2\n0000347e: fb d3              bcc           LAB_00003478\n    LAB_00003480:\n00003480: c0 1a              subs          r0,r0,r3\n00003482: 09 fe 3a c7        mcr2          p7,0x0,r12,cr9,cr10,0x1\n00003486: 10 bd              pop           {r4,pc}\n```\n\nNext, after the function returns, `R1` is kept untouched until the call to `sb_sha256_update_32`.\n\n```\n00001d02: 32 00              movs          r2,r6 // size\n00001d04: 21 00              movs          r1,r4 // src\n00001d06: 0f a8              add           r0,sp,#0x3c // sha context\n00001d08: 02 f0 49 fb        bl            sb_sha256_update_32\n```\n\nIf the instruction at `0x00001d04` can be “skipped”, the following will in effect be executed:\n\n```\nr1 = resolve_ram_or_absolute_flash_addr(from_storage_addr) + size;\nsb_sha256_update_32(&sha, r1, size);\n```\n\nThe data referenced by `R1` is located in the memory-mapped area corresponding to the flash data. This specific area performs uncached reads, meaning that data will be retrieved directly from the external *QSPI* bus. An attacker can manipulate this data.\n\nThis is where the “dual flash” feature embedded in the custom *I/O Board* becomes useful, as it simplifies the process of pushing arbitrary values over the bus. If necessary, two reads from the same address can yield different data.\n\n### Scenario #2 - Register Value Corruption\n\nDuring my tests, I observed that injecting faults between `s_varm_crit_mem_copy_by_words` and `sb_sha256_update_32` often resulted in data being pulled from the flash starting from offset `0`.\n\nI don’t have a clear explanation, such as a simple instruction skip, regarding why this happens.\n\nIt could, for instance, mean that when the following is executed:\n\n```\n00001d02: 32 00              movs          r2,r6 // size\n00001d04: 21 00              movs          r1,r4 // src\n00001d06: 0f a8              add           r0,sp,#0x3c // sha context\n00001d08: 02 f0 49 fb        bl            sb_sha256_update_32\n```\n\nThe value of `R4` points to the beginning of the memory-mapped area corresponding to the flash data.\n\nAnyway, this means that once again, the call to `sb_sha256_update_32` can use data under the control of an attacker instead of the data already loaded into *RAM*.\n\n### Scenario #3 - Instruction Mutation\n\nThe instructions corresponding to `s_varm_crit_mem_copy_by_words` are available below.\n\n```\n0000346c: 19 fe 3a c7        mrc2          p7,0x0,r12,cr9,cr10,0x1\n00003470: 10 b5              push          {r4,lr}\n00003472: 03 46              mov           r3,r0\n00003474: 22 b1              cbz           r2,LAB_00003480\n00003476: 1a 44              add           r2,r3\n    LAB_00003478:\n00003478: 10 c9              ldmia         r1!,{r4}\n0000347a: 10 c0              stmia         r0!,{r4}\n0000347c: 90 42              cmp           r0,r2\n0000347e: fb d3              bcc           LAB_00003478\n    LAB_00003480:\n00003480: c0 1a              subs          r0,r0,r3\n00003482: 09 fe 3a c7        mcr2          p7,0x0,r12,cr9,cr10,0x1\n00003486: 10 bd              pop           {r4,pc}\n```\n\nIf a fault can be injected at `0x00003486`, it’s possible for the `pop {r4,pc}` instruction to be altered, possibly resulting in the value of `R4` not being restored.\n\nBefore `pop {r4,pc}`, `R4` corresponds to the last word copied from the flash memory to *RAM*, a value under the control of the attacker. This value could, for instance, be set to an address contained in the memory-mapped flash area.\n\n`R4` is subsequently used when calling `sb_sha256_update_32`.\n\n```\n00001d02: 32 00              movs          r2,r6 // size\n00001d04: 21 00              movs          r1,r4 // src\n00001d06: 0f a8              add           r0,sp,#0x3c // sha context\n00001d08: 02 f0 49 fb        bl            sb_sha256_update_32\n```\n\nOnce again, `sb_sha256_update_32` could be forced to run against data pulled from the *QSPI* bus.\n\n## Attack Process\n\n### Software Architecture\n\nVarious software components have been developed to implement the logic of the attack and control the electronics.\n\n[![Browse the code on GitHub](https://courk.cc/rp2350-challenge-laser/assets/github-logo.webp)   \nBrowse the code on GitHub](https://github.com/courk/rp2350-lfi \"Browse the code on GitHub\") \n\n#### FPGA\n\nTo synchronize the laser pulse with the execution of the *Boot ROM*, the activity of the *QSPI* is monitored by the gateware of an *FPGA Board* connected to the *I/O Board*.\n\nThe choice of the *FPGA* platform isn’t super critical as the `RP2350` is clocked at a conservatively low speed when the *Boot ROM* is running. I chose to use a [*Glasgow Interface Explorer*](https://glasgow-embedded.org/latest/intro.html) tool.\n\n![The Glasgow Interface Explorer](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-small/1x/glasgow-pcba.webp)\n\nThe Glasgow Interface Explorer\n\nIt embeds an [`iCE40`](https://www.latticesemi.com/ice40) *FPGA* compatible with [open source tools](https://github.com/YosysHQ/icestorm). Finally, it integrates well with [Amaranth HDL](https://github.com/amaranth-lang/amaranth), which I find more convenient to develop with than more common *HDL* languages like [*Verilog*](https://en.wikipedia.org/wiki/Verilog) or [*VHDL*](https://en.wikipedia.org/wiki/VHDL).\n\nThe gateware written for this project is responsible for:\n\n- **Basic I/O Control**:\n  - Turning the power supply of the target `RP2350` on and off.- Controlling the `RUN` and `BOOTSEL` signals.- **Trigger Timing**: Monitoring the *QSPI* bus in real time.- **Attack Orchestration**:\n      - Dynamically selecting the active *QSPI* Flash memory.- Pulsing the laser.\n\n#### Laser Driver Board\n\nThe *Laser Driver Board* communicates with the host computer through a *USB-to-I2C* bridge component.\n\nNo firmware running on the board needed to be written, and the host computer can be directly used to configure the high-voltage power supply for the laser diode pulser circuit.\n\n#### Positioning Stage Control\n\nThe *Positioning Stage* is controlled by [software running on a Raspberry Pi single-board computer](https://openflexure.org/software/raspbian-openflexure).\n\nThe *X*, *Y*, and *Z* coordinates of the moving platform can be programmatically set using a web-based *API*.\n\nIn the context of this attack, this *API* is leveraged to slowly scan over the sensitive areas while pulsing the laser.\n\n### Laser Pulse Synchronization\n\nThe last *QSPI* read corresponding to the call of `s_varm_crit_mem_copy_by_words` can be detected with little uncertainty by the *FPGA* gateware. From this point, before calling `sb_sha256_update_32`, the following instructions are executed.\n\n```\n00003478: 10 c9              ldmia         r1!,{r4}\n0000347a: 10 c0              stmia         r0!,{r4}\n0000347c: 90 42              cmp           r0,r2\n0000347e: fb d3              bcc           LAB_00003478\n00003480: c0 1a              subs          r0,r0,r3\n00003482: 09 fe 3a c7        mcr2          p7,0x0,r12,cr9,cr10,0x1\n00003486: 10 bd              pop           {r4,pc}\n\n00001d66: 0d 9b              ldr           r3,[sp,#local_24]\n00001d68: 43 ec 70 07        mcrr          p7,0x7,r0,r3,cr0\n00001d6c: ac e7              b             LAB_00001cc8\n\n00001cc8: 0b 9b              ldr           r3,[sp,#local_2c]\n00001cca: 00 2b              cmp           r3,#0x0\n00001ccc: b3 d0              beq           LAB_00001c36\n00001cce: 03 9b              ldr           r3,[sp,#local_4c]\n00001cd0: 73 b1              cbz           r3,LAB_00001cf0\n00001cf0: 23 0e              lsrs          r3,r4,#0x18\n00001cf2: 10 2b              cmp           r3,#0x10\n00001cf4: 02 d8              bhi           LAB_00001cfc\n\n00001cfc: 03 23              movs          r3,#0x3\n00001cfe: 3e 00              movs          r6,r7\n00001d00: 9e 43              bics          r6,r3\n00001d02: 32 00              movs          r2,r6\n00001d04: 21 00              movs          r1,r4\n00001d06: 0f a8              add           r0,sp,#0x3c\n00001d08: 02 f0 49 fb        bl            sb_sha256_update_32\n```\n\nA redundancy co-processor instruction is executed at `0x00001d68`, introducing a random delay of up to 127 system clock cycles. As a result, it becomes impractical to consistently time a laser pulse to target a specific instruction following `0x00001d68`.\n\nHowever, this instruction is the only one that introduces a random delay. The software designed for the attack allows for about 20 attempts per second, which is sufficient to inject interesting faults in a reasonable amount of time.\n\n### Flash Memory Organization\n\nBefore starting the attack, the two *QSPI* flashes of the *I/O Board* are organized as follows:\n\nThe first flash, whose content will be loaded to *RAM*, contains a copy of the valid, signed firmware, including a signature block, patched as follows:\n\n- A small shellcode is written at the reset handler offset. This shellcode is designed to jump to arbitrary firmware located further in the flash memory at address `XIP_BASE + 0x10000`. `XIP_BASE` corresponds to the beginning of the memory-mapped flash data, while `0x10000` is an arbitrary offset.- The last word of the data loaded to *RAM* is set to `XIP_NOCACHE_NOALLOC_NOTRANSLATE_BASE + 0x7000`. `0x7000` is an arbitrary offset that will be used later, while `XIP_NOCACHE_NOALLOC_NOTRANSLATE_BASE` also returns flash data.\n\nThe second flash, whose content is expected to be read after a fault has been injected, contains three copies of the unmodified firmware. Computing the *SHA-256* hash against one of these images will result in a valid hash. The copies, ensuring all the fault injection scenarios that have previously been outlined, are located at:\n\n- Flash offset `0x0`, to support the *Scenario #2*.- The offset corresponding to the size of the data copied to *RAM*, to support the *Scenario #1*.- Flash offset `0x7000`, to support the *Scenario #3*.\n\nFinally, an arbitrary firmware is copied at offset `0x10000`. This firmware will run if the shellcode, previously loaded to *RAM*, is executed.\n\n### Attack Loop\n\nDuring the attack, the following process is repeated in a loop.\n\n- The first flash is selected.- The `RP2350` is powered on.- *QSPI* bus reads are monitored until the last byte corresponding to the call to `s_varm_crit_mem_copy_by_words` has been read.- The second flash is selected.- After an arbitrary delay, the laser is pulsed.- *QSPI* bus reads are monitored again to verify if the data pulled from the flash corresponds to a successful bypass.- In case of failure, the `RP2350` is powered off, and a new attempt will be made.\n\n```\n        flowchart TD\n            A[Select First Flash] --> B[Power On RP2350]\n            B --> C[Monitor QSPI Reads]\n            C --> D[Select Second Flash]\n            D --> E[Arbitrary Delay]\n            E --> F[Pulse Laser]\n            F --> G[Monitor QSPI Reads]\n            G -->|Failure| H[Power Off RP2350]\n            H --> A\n            G -->|Success| I[Arbitrary Firmware Execution]\n```\n\nAttack Loop\n\n## Results\n\nWhen targeting sensitive die areas, injecting faults that result in data being pulled from the *QSPI* bus at one of the expected addresses during the execution of `sb_sha256_update_32` is quite common.\n\nHowever, a major issue was that faults were often impacting the system a bit too hard, corrupting for instance the register corresponding to the `size` parameter of `sb_sha256_update_32`.\n\nAnother issue regards the positioning stage. Apart from some backlash in the gearing system, it seems the position drifts a bit over time and possibly temperature, making consistently hitting the exact sample spot complicated.\n\nThese reduced the success rate of the attack significantly. I only have been able to see the first *Secure Boot* bypass after more than 16 hours of tweaking the laser pulse parameters and position. However, following this fine-tuning, I only had to wait for about 20 minutes for a new success to appear.\n\n![My monitor displays the secret value hidden in the RP2350 after the first successful bypass](https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/success_screen.jpg)\n\nMy monitor displays the secret value hidden in the RP2350 after the first successful bypass\n\nThe bypass enables the execution of arbitrary firmware, which can then access secrets stored in the *OTP* area of the `RP2350`. This was the objective of [Raspberry Pi’s Hacking Challenge](https://github.com/raspberrypi/rp2350_hacking_challenge/).\n\n## Possible Improvements\n\nSeveral elements could be improved to increase the success rate of the attack:\n\n- The laser pulse duration could be fine-tuned. Due to the simple design of the *Laser Driver Board*, adjusting the pulse duration requires modifying the values of physical components. This process can be cumbersome, so I haven’t thoroughly explored the impact of pulse duration.- The laser spot size resulting from the *Optical Subsystem* is relatively large compared to what is typically used in similar attacks. A smaller spot size would likely lead to better-controlled and more repeatable faults.- The *FPGA* gateware could be enhanced. Instead of using two physical *QSPI* flashes, the *FPGA* could be utilized to emulate one, and dynamically supply the correct data, regardless of the flash address requested after the fault. However, this possibly goes a bit beyond the capabilities of the *FPGA* I used.\n\n---\n\n# Conclusion\n\nLaser fault injection can be performed on a budget! Although it requires a lot of trial and error, and sourcing a suitable laser source can be tedious, a functional setup can indeed be achieved.\n\nDue to significant compromises, the performance of such a system is not optimal, but interesting results can still be obtained: injecting faults in the `RP2350` without triggering its glitch detectors becomes possible.\n\nThis alone is not enough to bypass the *Secure Boot* feature of the `RP2350`. However, a small but critical section of the *Boot ROM* has been found to be less hardened and protected by the redundancy co-processor. Injecting a fault at this point, while supplying a compatible payload over the *QSPI* bus, can essentially defeat the *Secure Boot*.\n\nWhile [way simpler methods](https://events.ccc.de/congress/2024/hub/en/event/hacking-the-rp2350/) have now been made public, this work still addresses [Raspberry Pi’s `RP2350` Hacking Challenge](https://www.raspberrypi.com/news/can-you-hack-our-new-chip/).\n\nAdditionally, note that it may also be possible to exploit the section of the *Boot ROM* I targeted without even resorting to *LFI*. There are [some reports](https://infosec.exchange/@barsteward/113727673866158485) of carefully performed *EMFI* attacks able to bypass the glitch detectors.\n> The glitch detector is pretty good at detecting EMFI attempts, but it was possible to glitch CPU operations without triggering it with a small coil and a low power glitch\n\nStill, I regret nothing; lasers are fun to play with!\n\n## Disclosure\n\nFollowing my first successful bypass, I immediately contacted *Raspberry Pi*. [For transparency, the documents I shared with them are available here](https://courk.cc/rp2350-challenge-laser/assets/original_submission/index.html).\n\nCommunication with the team was smooth and enjoyable. They acknowledged that the “break-in” was valid and confirmed that the next *Boot ROM* of the `RP2350` would include more hardening around the specific area of the code I targeted.\n\n---\n\n## Bibliography\n\nAndrew 'bunnie' Huang. Infra-red, in-situ (iris) inspection of silicon. 2023. URL: <https://arxiv.org/abs/2303.07406>, [arXiv:2303.07406](https://arxiv.org/abs/2303.07406). [↩](#ref-huang2023infraredinsituirisinspection-1 \"Jump back to reference 1\")\n\nJemellie Galang, Allesandro Restelli, Edward W. Hagley, and Charles W. Clark. A green laser pointer hazard. 2010. URL: <https://arxiv.org/abs/1008.1452>, [arXiv:1008.1452](https://arxiv.org/abs/1008.1452). [↩](#ref-galang2010greenlaserpointerhazard-1 \"Jump back to reference 1\")\n\nSamuel McDermott, Filip Ayazi, Joel Collins, Joe Knapper, Julian Stirling, Richard Bowman, and Pietro Cicuta. Multi-modal microscopy imaging with the openflexure delta stage. *Opt. Express*, 30(15):26377–26395, Jul 2022. URL: <https://opg.optica.org/oe/abstract.cfm?URI=oe-30-15-26377>, [doi:10.1364/OE.450211](https://doi.org/10.1364/OE.450211). [↩](#ref-McDermott:22-1 \"Jump back to reference 1\")\n\nAntonios Stylogiannis, Ludwig Prade, Andreas Buehler, Juan Aguirre, George Sergiadis, and Vasilis Ntziachristos. Continuous wave laser diodes enable fast optoacoustic imaging. *Photoacoustics*, 9:31–38, 2018. URL: <https://www.sciencedirect.com/science/article/pii/S2213597917300356>, [doi:https://doi.org/10.1016/j.pacs.2017.12.002](https://doi.org/https://doi.org/10.1016/j.pacs.2017.12.002). [↩](#ref-STYLOGIANNIS201831-1 \"Jump back to reference 1\")\n\n\n---\n\n*Originally published on Courk's Blog under a Creative Commons Attribution-ShareAlike 4.0 International License.*\n","body_html":"<h1 id=\"laser-fault-injection-on-a-budget-rp2350-edition\">Laser Fault Injection on a Budget: RP2350 Edition</h1>\n<h1 id=\"introduction\">Introduction</h1>\n<p>In August 2024, <em>Raspberry Pi</em> <a href=\"https://www.raspberrypi.com/news/raspberry-pi-pico-2-our-new-5-microcontroller-board-on-sale-now/\" rel=\"nofollow ugc noopener\">introduced the <code>RP2350</code> microcontroller</a>. This part iterates over the <code>RP2040</code> and comes with numerous new features. These include security-related capabilities, such as a <em>Secure Boot</em> implementation.</p>\n<p>A couple of days after this announcement, during <a href=\"https://defcon.org/\" rel=\"nofollow ugc noopener\"><em>DEFCON</em> 2024</a>, an interesting challenge targeted at these new features was launched: the <a href=\"https://www.raspberrypi.com/news/can-you-hack-our-new-chip/\" rel=\"nofollow ugc noopener\"><em>RP2350 Hacking Challenge</em></a>.</p>\n<p>After some work and the development of a fully custom <em>“Laser Fault Injection Platform”</em>, I managed to beat this challenge and submitted my findings to <em>Raspberry Pi</em>.</p>\n<p>This article will provide technical details about this custom platform, including <a href=\"https://courk.cc/laser-fault-injection-platform-hardware-files\" rel=\"nofollow ugc noopener\">manufacturing files</a> for those interested in building their own. Additionally, I will explain how injecting a single laser-induced fault can bypass the <em>Secure Boot</em> feature of the <code>RP2350</code>.</p>\n<p>Warning</p>\n<p>The <em>“Laser Fault Injection Platform”</em> introduced in this article makes use of an infrared high-power laser source. Such a component can be hazardous; be careful if you attempt to reproduce this work.</p>\n<hr />\n<h1 id=\"hacking-challenge-rp2350-security-features\">Hacking Challenge &amp; RP2350 Security Features</h1>\n<h2 id=\"objectives-of-the-challenge\">Objectives of the Challenge</h2>\n<p>The target of this challenge is a <a href=\"https://www.raspberrypi.com/products/raspberry-pi-pico-2/\" rel=\"nofollow ugc noopener\"><em>Pico 2</em> board</a>, which hosts a <code>RP2350</code> microcontroller. It must be configured according to the instructions provided in the <a href=\"https://github.com/raspberrypi/rp2350_hacking_challenge/\" rel=\"nofollow ugc noopener\">challenge’s GitHub repository</a>.</p>\n<p>Following the instructions from the repository will:</p>\n<ul><li>Write “secret” data into one of the <em>OTP</em> areas of the <code>RP2350</code>.- Configure and enable the <em>Secure Boot</em> feature, locking the chip as much as possible. This includes disabling debug interfaces (<em>SWD</em>) and enabling various security features, such as glitch detectors.- Flash a signed firmware that primarily restricts even more access to the <em>OTP</em> area where the secret is stored.</li></ul>\n<p>The goal of the challenge is to find a way to recover the secret data, potentially bypassing the <em>Secure Boot</em> feature in the process.</p>\n<h2 id=\"security-features\">Security Features</h2>\n<p>The <em>Secure Boot</em> feature is enforced by code contained in the <em>Boot ROM</em> of the <code>RP2350</code>. This code is hardened in several ways, going beyond software methods; the <em>Boot ROM</em> leverages hardware-specific features.</p>\n<p>These features are primarily related to an innovative component called the “Redundancy Co-Processor.” Quoting the <a href=\"https://datasheets.raspberrypi.com/rp2350/rp2350-datasheet.pdf\" rel=\"nofollow ugc noopener\">RP2350 Datasheet</a>:</p>\n<blockquote><p>The redundancy coprocessor (RCP) is used in the RP2350 bootrom to provide hardware-assisted mitigation against fault injection and return-oriented programming attacks. This includes the following instructions:</p>\n<ul><li>generate and validate stack canary values based on a per-boot random seed- assert that certain points in the program are executed in the correct order without missing steps- validate booleans stored as one of two valid bit patterns in a 32-bit word- validate 32-bit integers stored redundantly in two words with an XOR parity mask- halt the processor upon reaching a software-detected panic condition</li></ul>\n<p>[…]</p>\n<p>Each core’s RCP has a 64-bit seed value (Section 3.6.3.1). The RCP uses this value to generate stack canary values and to add short pseudorandom delays to RCP instructions.</p></blockquote>\n<p>Additionally, the <code>RP2350</code> is capable of detecting fault injection attempts using glitch detectors. These configurable circuits respond to voltage or electromagnetic fault-injection attempts and reset the system. For this challenge, these detectors are set to their maximum sensitivity level.</p>\n<hr />\n<h1 id=\"article-overview\">Article Overview</h1>\n<p>Below is a brief, high-level summary of the article’s content.</p>\n<h2 id=\"why-choosing-laser-fault-injection\">Why choosing Laser Fault Injection</h2>\n<p>Considering that the <em>Boot ROM</em> of the <code>RP2350</code> has been audited before the opening of the challenge, I did not attempt to find logic bugs in it and quickly considered a hardware attack, such as a fault injection attack.</p>\n<p>However, <a href=\"https://xcancel.com/barsteward/status/1831365943169270077\" rel=\"nofollow ugc noopener\">online comments</a> tend to show that the glitch detector system implemented in the <code>RP2350</code> was rather efficient in mitigating simple voltage fault injection attacks.</p>\n<p>Hence, I quickly decided to tackle the challenge with laser fault injection, assuming that focusing a laser beam away from the glitch detector circuits could allow for injecting faults without triggering them.</p>\n<p>Now, the thing is, while I did have some experience with <a href=\"https://courk.cc/esp32-c3-c6-fault-injection\" rel=\"nofollow ugc noopener\">“classic” voltage fault injection attacks</a>, I knew nothing about laser fault injections.</p>\n<p>This challenge was then used as an opportunity to build a fully custom, cheap laser fault injection platform.</p>\n<p>Note that while traditionally known to be expensive to implement, several “cheap” platforms aimed at injecting faults with a laser have emerged over the past few months:</p>\n<ul><li><a href=\"https://blog.fraktal.fi/laser-fault-injection-for-the-masses-1860afde5a26\" rel=\"nofollow ugc noopener\">Laser Fault Injection for The Masses</a> is repurposing laser engraving hardware.- The <a href=\"https://www.wired.com/story/rayv-lite-laser-chip-hacking-tool/\" rel=\"nofollow ugc noopener\"><em>“RayV-Lite”</em> from <em>NetSPI</em></a>. <del>However, at the time of writing, very few publicly available technical details are available regarding this project.</del></li></ul>\n<p>Note</p>\n<p>My mistake, after some research, I actually managed to find <a href=\"https://vimeo.com/998515104\" rel=\"nofollow ugc noopener\">this presentation of the <em>“RayV-Lite”</em></a> introduced at <a href=\"https://www.blackhat.com/us-24/briefings/schedule/#laser-beams--light-streams-letting-hackers-go-pew-pew-building-affordable-light-based-hardware-security-tooling-39708\" rel=\"nofollow ugc noopener\">Blackhat 2024</a>. Their project presents various similarities with my <em>“Laser Fault Injection Platform”</em>, but also interesting differences. I’ll highlight some of these differences in this article and encourage you to check out their work.</p>\n<p><strong>August 2025 update:</strong> Even more material is now publicly available! This includes <a href=\"https://www.netspi.com/blog/technical-blog/hardware-and-embedded-systems-penetration-testing/rayv-lite-open-source-laser-injection-tool/\" rel=\"nofollow ugc noopener\">an article on <em>NetSPI</em>’s website</a>.</p>\n<h2 id=\"sample-preparation\">Sample Preparation</h2>\n<p>The idea being <em>LFI</em> is reasonably simple. A focused laser beam is directed at the silicon die of the target component. Transistors are sensitive to photoelectric effects, meaning the emitted light can be enough to induce temporary faults or malfunctions. When precisely timed, these faults could be leveraged to bypass security features.</p>\n<p>A major downside of such an attack compared to voltage or clock glitching is that the silicon die of the target has to be exposed. Of course, the circuit must still be able to operate normally after the die has been exposed.</p>\n<p>Accessing the silicon can either be attempted from the top, or the bottom side of the packaged chip.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/top_bottom_ic.webp\" alt=\"Simplified Top and Bottom Sides Render of a Packaged Integrated Circuit\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Simplified Top and Bottom Sides Render of a Packaged Integrated Circuit</p>\n<p>I chose to expose performed from the backside of the die. This choice has been made for two reasons:</p>\n<ul><li>Accessing the backside can be achieved with cheap mechanical tools. However, exposing the top of the die would have required chemicals I would rather not deal with, such as <a href=\"https://jcjc-dev.com/2020/10/20/learning-to-decap-ics/\" rel=\"nofollow ugc noopener\">concentrated nitric acid</a>.- Based on <a href=\"https://electronupdate.blogspot.com/2024/08/pi-pico-2-extreme-teardown.html\" rel=\"nofollow ugc noopener\">images available online</a>, it seems the top of the die is fully covered by a metal layer, likely complicating fault injection.</li></ul>\n<p>The process I developed to expose the backside of the silicon die is detailed in the relevant sections of this article.</p>\n<h2 id=\"die-imaging-laser-focusing\">Die Imaging &amp; Laser Focusing</h2>\n<p><em>LFI</em> requires targeting with a focused laser beam relatively precise areas of the die. A custom, cheap <em>Laser Fault Injection platform</em> has been designed for this purpose.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-large/1x/platform_global_view.jpg\" alt=\"The Laser Fault Injection Platform\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>The Laser Fault Injection Platform</p>\n<p>Because the design of this platform is very budget oriented, corners had to be cut in multiple paces, resulting in various limitations. These limitations, alongside various technical details and working principles, are detailed in the corresponding sections of this article.</p>\n<p>To enable others to reproduce my results, I will also be sharing the relevant manufacturing files and source code.</p>\n<h2 id=\"fault-injection-secure-boot-bypass\">Fault Injection &amp; Secure Boot Bypass</h2>\n<p>Being able to inject faults is just the first step in attacking the <code>RP2350</code>. As previously mentioned, the glitch detectors are not the only security feature that <em>Raspberry Pi</em> developed to protect the system.</p>\n<p>It is also necessary to identify a weakness in the <em>Boot ROM</em> of the component, where the <em>Secure Boot</em> feature is implemented. The specific sequence of instructions I targeted will be discussed in the relevant sections of this article.</p>\n<hr />\n<h1 id=\"sample-preparation-2\">Sample Preparation</h1>\n<p>This section describes the initial steps required to execute the attack. The backside of the die of the target <code>RP2350</code> must be carefully exposed, ensuring that the chip’s functionality remains intact.</p>\n<h2 id=\"die-exposure\">Die Exposure</h2>\n<p>The target <code>RP2350</code> first has to be desoldered from the <em>Pico 2</em> board. This can be achieved with a simple hot air reflow station.</p>\n<p>Next, a cheap (€30) dremel-like tool, advertised as an “Engraving Tool” (Amazon Part Number: <code>UKH062_FR</code>), has been used to carefully remove material around the ground pad.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/dremel_tool.jpg\" alt=\"The tool used to expose the die\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>The tool used to expose the die</p>\n<p>After enough material has been removed, the metallic ground pad can be taken off, exposing a layer of what looks like silver (heat-conductive?) paste. This paste can easily be scratched out, revealing the backside of the die.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/backside_dremel.jpg\" alt=\"Exposed Backside after Mechanical Grinding\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Exposed Backside after Mechanical Grinding</p>\n<h2 id=\"main-carrier-board\">Main Carrier Board</h2>\n<p>The prepared sample can then be soldered on a custom <em>PCB</em>, designed to integrate with the <em>Laser Fault Injection Platform</em>.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/carrier_board.jpg\" alt=\"RP2350 Backside Carrier Board\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>RP2350 Backside Carrier Board</p>\n<p>A hole in the middle exposes the backside of the <code>RP2350</code> die.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/backside_before_glue.jpg\" alt=\"Backside view of the board, the die is visible\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Backside view of the board, the die is visible</p>\n<p>The board doesn’t include anything more, apart from a small <em>LDO</em> used to power the core. Power and control signals are routed away to an <em>FFC</em> connector.</p>\n<pre><code>        flowchart LR\n            B{{FFC Connector}} &amp;LT--&gt;|UART| A(RP2350)\n            A &amp;LT--&gt;|SWD| B\n            A &amp;LT--&gt;|USB| B\n            A &amp;LT--&gt;|QSPI| B\n            A &amp;LT--&gt;|Control Signals| B\n            B .-&gt;|3V3| A\n            B .-&gt;|3V3| C((LDO))\n            C .-&gt;|1V1|A</code></pre>\n<p>Main Carrier Board Architecture Diagram</p>\n<p>This <em>PCB</em> can be hand-assembled, and the total unit <em>BOM</em> cost for small quantities is estimated at less than €10.</p>\n<p><a href=\"https://courk.cc/laser-fault-injection-platform-main-carrier-board\" title=\"Interactive 3D Render &amp; Design Files\" rel=\"nofollow ugc noopener\"><img src=\"https://courk.cc/rp2350-challenge-laser/assets/main_carrier_board_icon.webp\" alt=\"Interactive 3D Render &amp; Design Files\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /><br />\nInteractive 3D Render &amp; Design Files</a> </p>\n<h2 id=\"i-o-board\">I/O Board</h2>\n<p>The <em>Main Carrier Board</em> detailed above connects to the <em>I/O Board</em> through a <em>FFC</em> cable.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/backside_boards.jpg\" alt=\"I/O Board and Main Carrier Board, placed in a 3D-printed holder\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>I/O Board and Main Carrier Board, placed in a 3D-printed holder</p>\n<p>The assembly of these two boards is designed to integrate with the <em>Laser Fault Injection Platform</em>.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/backside_boards_in_system.jpg\" alt=\"I/O Board and Main Carrier Board, placed in the Laser Fault Injection Platform\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>I/O Board and Main Carrier Board, placed in the Laser Fault Injection Platform</p>\n<p>The <em>I/O Board</em> breaks out the various control signals over:</p>\n<ul><li>A <em>USB</em> connector- Pin headers that are connected to a <em>FPGA</em> board, later used to implement the attack’s logic- A few test points used for <em>SWD</em> debugging (seldom used, especially considering <em>SWD</em> needs to be disabled for this challenge)</li></ul>\n<pre><code>        flowchart TB\n            A((LDO)) .-&gt;|3V3| B((Power Switch))\n            C{{USB Connector}} .-&gt;|5V| A\n            C &amp;LT--&gt;|USB| D{{FFC Connector}}\n            B .-&gt;|3V3| D\n            E{{Pin Headers}} --&gt;|Enable| B\n            D &amp;LT--&gt;|Control Signals| E\n            D &amp;LT--&gt;|QSPI| E\n            D &amp;LT--&gt;|UART| E\n            D &amp;LT--&gt;|SWD| F(Test Points)\n            D &amp;LT--&gt;|QSPI| G(QSPI Flash #0)\n            D &amp;LT--&gt;|QSPI| H(QSPI Flash #1)</code></pre>\n<p>I/O Board Architecture Diagram</p>\n<p>Additionally, two <em>QSPI</em> flashes are mounted to the board. The “active” flash, <em>i.e.</em> the one connected to the <code>~CS</code> line of the <code>RP2350</code>, can be selected from the <em>FPGA</em>. This means the “active” flash can be swapped between each request from the <code>RP2350</code> to the external memory.</p>\n<p>This feature, detailed in the following diagram, is instrumental for the attack described in this article.</p>\n<pre><code>        flowchart LR\n            A(RP2350) --&gt;|CS| B(FPGA)\n            B --&gt;|CS#0| C(QSPI Flash #0)\n            B --&gt;|CS#1| D(QSPI Flash #1)</code></pre>\n<p>Dual Flash System</p>\n<p>Here again, the board can be hand-assembled. The total unit <em>BOM</em> cost for small quantities is estimated to be less than €15.</p>\n<p><a href=\"https://courk.cc/laser-fault-injection-platform-io-board\" title=\"Interactive 3D Render &amp; Design Files\" rel=\"nofollow ugc noopener\"><img src=\"https://courk.cc/rp2350-challenge-laser/assets/io_board_icon.webp\" alt=\"Interactive 3D Render &amp; Design Files\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /><br />\nInteractive 3D Render &amp; Design Files</a> </p>\n<h2 id=\"ground-connection-repair\">Ground Connection Repair</h2>\n<p>Note</p>\n<p><strong>August 2025 update:</strong> The method detailed here is overcomplicated. See <a href=\"https://courk.cc/lfi-defcon-content\" rel=\"nofollow ugc noopener\">Laser Fault Injection on a Budget: DEFCON 33 Showcase</a> for a simpler method.</p>\n<p>An obvious issue with removing the ground pad to access the die is that the only ground connection to the integrated circuit is destroyed.</p>\n<p>The <code>RP2350</code> has a <code>PGND</code> pin connected to its internal <em>DC/DC</em> converter, but it doesn’t seem to have a low-impedance internal connection to ground. Instead, a method to restore a sufficient ground connection has been implemented.</p>\n<p>It’s a bit challenging to see, but specks of exposed copper (or gold?), as well as “holes” where severed bond wires likely passed, are visible. Slightly scratching these areas can sometimes reveal more conductive material.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/copper_view_1.jpg\" alt=\"Visible metal specks near the exposed die\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Visible metal specks near the exposed die</p>\n<p>Magnified views of areas <code>1</code> and <code>2</code> are shown below.</p>\n<p>Note</p>\n<p>Note that these magnified images have been captured thanks to the imaging capabilities of the <em>Laser Fault Injection Platform</em>. This results in unusual colors, as the camera sensor of the platform lacks an <em>IR</em> filter.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/copper_view_2.jpg\" alt=\"Magnified view of Area 1\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Magnified view of Area 1</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/copper_view_3.jpg\" alt=\"Magnified view of Area 2\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Magnified view of Area 2</p>\n<p>Applying conductive epoxy between these small exposed metal bits and purposefully arranged copper pads located on the <em>Carrier Board</em> was, thankfully, enough to restore a sufficient ground connection.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/backside_after_glue.jpg\" alt=\"View of the applied epoxy glue, after curing\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>View of the applied epoxy glue, after curing</p>\n<p>The reference for the product I used is <a href=\"https://fr.farnell.com/en-FR/mg-chemicals/9410-3ml/thermally-conductive-adhesive/dp/2889799\" rel=\"nofollow ugc noopener\"><code>MG CHEMICALS 9410</code></a>. It’s a one-part, temperature-activated epoxy. I used a hot air station at 150°C150°C150°C for about 10 minutes to cure it.</p>\n<h2 id=\"limitations\">Limitations</h2>\n<p>This process is, of course, a bit risky. While I’ve gotten better at it after a few attempts, I don’t think I can claim a 100% success rate.</p>\n<p>Additionally, the ground connection restored thanks to the conductive epoxy is far from perfect. For instance, I’m usually not able to run such a modified <code>RP2350</code> at high clock speeds, as it results in higher current being drawn.</p>\n<p>Finally, I found that some <em>I/O</em> pads can sometimes stop working, or are facing signal integrity issues. I’m not sure all ground bond wires are internally connected on the die; I may not restore a good enough connection for all of them.</p>\n<p>However, the target of the attack is the <em>Boot ROM</em>. The hardware is configured very conservatively by this <em>ROM</em>: clock speeds are low, etc. In this context, the “ground connection repair” method appears to be good enough.</p>\n<p>To overcome these issues, it may be possible to mill only the very center of the ground pad, exposing the die while keeping the bond wires intact. This would likely require access to a <em>CNC</em> milling machine and fine bits, which I currently do not have.</p>\n<hr />\n<h1 id=\"laser-fault-injection-platform\">Laser Fault Injection Platform</h1>\n<h2 id=\"platform-overview\">Platform Overview</h2>\n<p>As explained above, a custom fault injection platform has been designed for this project. While this hardware setup may not compete with more professional systems in terms of repeatability, it is likely an order of magnitude cheaper.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-large/1x/platform_global_view_alt.jpg\" alt=\"The Platform, fitted with the custom RP2350 Electronics\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>The Platform, fitted with the custom RP2350 Electronics</p>\n<p>The platform can be divided into two subsystems, each of which will be detailed separately:</p>\n<ul><li>A positioning stage, used to precisely displace the die of the target <code>RP2350</code> for observation and laser focusing.- An optical subsystem, utilized for visualizing this die and focusing high-power laser pulses onto it.</li></ul>\n<p><a href=\"https://courk.cc/laser-fault-injection-platform-3d-render\" title=\"Interactive 3D Render\" rel=\"nofollow ugc noopener\"><img src=\"https://courk.cc/rp2350-challenge-laser/assets/entire_system_icon.webp\" alt=\"Interactive 3D Render\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /><br />\nInteractive 3D Render</a> </p>\n<h2 id=\"positioning-stage\">Positioning Stage</h2>\n<p>The positioning stage is based on the <a href=\"https://build.openflexure.org/openflexure-delta-stage/v1.2.2/\" rel=\"nofollow ugc noopener\"><em>OpenFlexure</em> Delta Stage</a> <a href=\"#McDermott:22\">(McDermott et al., 2022)</a>. <em>OpenFlexure</em> projects are impressive, and I would not have achieved much without them. High-precision mechanical positioning is made possible with simple 3D printed parts and affordable stepper motors.</p>\n<p>Note</p>\n<p>The <a href=\"https://www.blackhat.com/us-24/briefings/schedule/#laser-beams--light-streams-letting-hackers-go-pew-pew-building-affordable-light-based-hardware-security-tooling-39708\" rel=\"nofollow ugc noopener\"><em>“RayV-Lite”</em> system</a> is also based on an <em>OpenFlexure</em> project, but not on the <em>Delta Stage</em> I selected here.</p>\n<p>Minor modifications have been made to the official <em>OpenFlexure</em> Delta Stage:</p>\n<ul><li>The base of the stage was raised to accommodate the custom optical subsystem.- Heat-set threaded inserts have been added in various locations to support the custom electronics introduced in the previous sections of this article.</li></ul>\n<p><a href=\"https://courk.cc/laser-fault-injection-delta-stage\" title=\"Interactive 3D Render &amp; Design Files\" rel=\"nofollow ugc noopener\"><img src=\"https://courk.cc/rp2350-challenge-laser/assets/delta_stage_icon.webp\" alt=\"Interactive 3D Render &amp; Design Files\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /><br />\nInteractive 3D Render &amp; Design Files</a> </p>\n<h2 id=\"optical-subsystem\">Optical Subsystem</h2>\n<p>The optical subsystem is utilized for visualizing the die and focusing high-power laser pulses onto it. This subsystem is inspired from the <a href=\"https://build.openflexure.org/openflexure-delta-stage/v1.2.2/pages/index_reflection.html\" rel=\"nofollow ugc noopener\">reflection illumination subsystem</a> from the <em>OpenFlexure project</em>. However, unlike the positioning stage, significant modifications have been implemented.</p>\n<p><a href=\"https://courk.cc/laser-fault-injection-optical-assembly\" title=\"Interactive 3D Render &amp; Design Files\" rel=\"nofollow ugc noopener\"><img src=\"https://courk.cc/rp2350-challenge-laser/assets/optical_assembly_icon.webp\" alt=\"Interactive 3D Render &amp; Design Files\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /><br />\nInteractive 3D Render &amp; Design Files</a> </p>\n<h3 id=\"the-necessity-of-using-infrared-light\">The Necessity of Using Infrared Light</h3>\n<p>One of the downsides of attacking the die from its backside is that infrared light has to be used. Indeed, silicon is almost fully opaque to visible light, preventing both visualization and fault injection.</p>\n<p>Instead, infrared light with a wavelength of 1064nm1064nm1064nm is utilized. This wavelength is traditionally employed for backside fault injection and can also, as demonstrated in <em>Infra-Red, In Situ (IRIS) Inspection of Silicon</em> <a href=\"#huang2023infraredinsituirisinspection\">(bunnieHuang, 2023)</a>, be used for visualization of the die’s features.</p>\n<h3 id=\"optical-components\">Optical Components</h3>\n<p>The 3D render available below is extracted from the complete <a href=\"https://courk.cc/laser-fault-injection-platform-3d-render\" rel=\"nofollow ugc noopener\">Laser Fault Injection Platform 3D Render</a>. Only the components relevant to the imaging and laser focusing features are displayed and annotated.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/optical_3d_render.webp\" alt=\"Optical Components\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Optical Components</p>\n<p>The following items are visible. Refer to the <a href=\"https://courk.cc/laser-fault-injection-optical-assembly\" rel=\"nofollow ugc noopener\">Optical Assembly page</a> for exact part numbers or sourcing details.</p>\n<ol><li><strong>The Laser Driver Board</strong> - This custom <em>PCB</em> is used to drive a laser diode, emitting short but powerful pulses of light. This piece of hardware will be detailed later in this article.- <strong>Objective Lens</strong> - This is an off-the-shelf microscope objective lens. I wanted an infinity-corrected one to make focusing the laser beam easier. Unfortunately, these are typically more costly than finite-corrected ones. I obtained one for about €90 from <em>AliExpress</em>.- <strong>Oblique Illumination System</strong> - This is a simple 1064nm1064 \\text{nm}1064nm <em>LED</em>, used for imaging the die. During my tests, I noticed that illuminating the sample from its side, with a rather narrow angle, resulted in the best image contrast.- <strong>Imaging Camera</strong> - This is a <em>Raspberry Pi Camera v2 “NoIR”</em>. As it does not have an <em>IR</em> filter, it remains a bit sensitive to the wavelength of interest.</li></ol>\n<p>Removing even more objects, including the 3D-printed parts that are holding things together, the following new optical elements become visible.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/optical_elements.webp\" alt=\"Optical Components, Without 3D-printer Parts\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Optical Components, Without 3D-printer Parts</p>\n<ol><li><strong>Laser Diode</strong> - A 1064nm1064 \\text{nm}1064nm laser diode. This tiny component was by far the most challenging part to source. I negotiated five pieces on <em>Alibaba</em> for about €300.- <strong>Adjustable Collimating Lens</strong> - A screwable lens used to collimate the output of the laser diode. It can be purchased in bulk for a low price on <em>AliExpress</em>.- <strong>Beam Splitter</strong> - This piece of glass is specially coated to reflect a fraction of the incoming light while transmitting the other part. Purchased for a reasonable price on <em>AliExpress</em>.- <strong>Tube Lens</strong> - Once again, purchased for a reasonable price on <em>AliExpress</em>.</li></ol>\n<p>As explained, most of these components are off-the-shelf and have been sourced cheaply from <em>Aliexpress</em>. However, there is still a cost: these parts are often poorly specified or designed primarily for traditional microscopy applications, where only visible light is considered. As a result, I suspect that some infrared laser light is wasted and that the imaging may suffer from chromatic aberrations.</p>\n<h3 id=\"optical-paths\">Optical Paths</h3>\n<h4 id=\"imaging\">Imaging</h4>\n<p>The path followed by the light to ensure the “Imaging” feature of the assembly is highlighted below.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/imaging_optical_path.webp\" alt=\"Path followed by the light leaving the oblique imaging LED\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Path followed by the light leaving the oblique imaging LED</p>\n<p>The sample is first illuminated by the 1064nm1064 \\text{nm}1064nm Oblique Illumination <em>LED</em>. This wavelength passes through the silicon and reflects off the features of the die.</p>\n<p>Note</p>\n<p>While not as powerful as the laser, this <em>LED</em> still seems to interact with the circuit in some way.</p>\n<p>In particular, I noticed that it was sometimes impossible for the system to boot when the die was illuminated by the <em>LED</em>. I suspect that analog circuits, which may be more sensitive than digital ones, are affected.</p>\n<p>To avoid this problem, the <em>LED</em> is only turned on to image the die and align the laser beam. It is turned off during the attack process.</p>\n<p>Next, this light passes through the infinity-corrected lens before being imaged back to the camera sensor thanks to the tube lens.</p>\n<p>In between, the light goes through the beam splitter. A fraction of the light will be transmitted and continue in the same direction. The reflected fraction of the light is lost.</p>\n<p>The selected beam splitter has the following properties:</p>\n<ul><li>Reflection coefficient: 90%- Transmission coefficient: 10%</li></ul>\n<p>This prioritizes the light coming from the laser beam, whose path is detailed below.</p>\n<h4 id=\"laser-focusing\">Laser Focusing</h4>\n<p>The path followed by the light to implement the “Laser Focusing” feature of the assembly is highlighted below.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/laser_diode_optical_path.webp\" alt=\"Path followed by the light leaving the laser diode\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Path followed by the light leaving the laser diode</p>\n<p>A pulse of light is emitted from the laser diode. This light is diverging and is collimated with the Adjustable Collimating Lens.</p>\n<p>Most (90%) of the collimated light is reflected by the beam splitter and sent through the objective lens, where it is focused on the target sample.</p>\n<h3 id=\"imaging-results\">Imaging Results</h3>\n<p>Below are a couple of slightly processed images of the die obtained from the setup.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/die_imaging_1.jpg\" alt=\"Imaging Result Example 1\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Imaging Result Example 1</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/die_imaging_2.jpg\" alt=\"Imaging Result Example 2\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Imaging Result Example 2</p>\n<p>Additionally, you will find a zoomable stitched view of the entire die.</p>\n<p>Note</p>\n<p>The quality of the stitching is obviously very poor; the processing tool I used struggles with the low-contrast images I provided.</p>\n<p>For completeness, the following video demonstrates what is visible in real-time through the <em>OpenFlexure</em> web-based interface.</p>\n<p>While these images may definitely not match the quality produced by a professional setup, they are sufficient to align a laser beam with specific features of the die.</p>\n<p>The limiting factor may be the <em>CMOS</em> camera sensor, which is only marginally sensitive to 1064nm1064nm1064nm. Unfortunately, cameras that are sensitive to these wavelengths tend to be quite expensive.</p>\n<p>For a much better view of the backside of the die, check-out <a href=\"https://xcancel.com/LennertWo/status/1826891922679476283\" rel=\"nofollow ugc noopener\">the one shared by @LennertWo</a>.</p>\n<h3 id=\"laser-focusing-results\">Laser Focusing Results</h3>\n<p>The properties of the focused beam aren’t great, and the resulting spot is rather large and elliptical. That’s not ideal, as the goal is to achieve a high-power density to inject a fault.</p>\n<p>An example of the resulting spot is available below. Note that here, the laser was pulsed at a reduced power to avoid blinding the camera sensor.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/focused_beam_example.jpg\" alt=\"Focused laser beam, as seen from the camera sensor\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Focused laser beam, as seen from the camera sensor</p>\n<p>This problem has been mitigated by increasing the power supplied to the laser diode from the <em>Laser Driver Board</em>.</p>\n<p>Multiple factors can explain the poor shape of the laser spot:</p>\n<ul><li>The lenses I used are only specified for visible light.- The focusing method is simple and possibly a bit naive; I’m no optical expert.- Most importantly, the laser diode I used is a high-power one; the emitting element is large, and the light coming out of it is very diverging, with large differences between the <a href=\"https://en.wikipedia.org/wiki/Laser_diode#Formation_of_laser_beam\" rel=\"nofollow ugc noopener\">fast and slow axes</a>.</li></ul>\n<hr />\n<h1 id=\"laser-driving\">Laser Driving</h1>\n<p>Warning</p>\n<p>This is where things can get dangerous. Although the custom board described here produces only very short pulses, working with a high-power laser can be hazardous, particularly when the emitted light falls outside the visible spectrum.</p>\n<p>Be careful if you attempt to reproduce this work.</p>\n<p>Laser fault injection requires short, high-power light pulses to be transmitted. A custom board has been designed for this purpose.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/laser_pulser_top.jpg\" alt=\"Laser Driver Board, Top View\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Laser Driver Board, Top View</p>\n<p>Most of the electronics are located on the top side of the board, with a laser diode installed on the bottom side.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/laser_pulser_bottom.jpg\" alt=\"Laser Driver Board, Bottom View\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Laser Driver Board, Bottom View</p>\n<p>While designing such a board was not overly complicated, finding a suitable laser diode turned out to be more challenging.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium-plus/1x/laser_pulser_in_use.jpg\" alt=\"Laser Driver Board, installed in the Fault Injection Platform\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Laser Driver Board, installed in the Fault Injection Platform</p>\n<p>Note</p>\n<p>As visible in the pictures of the boards, a section of the circuit has been reworked. This has been done to adjust the laser pulse parameters, as detailed below. The shared schematics have been updated to reflect this rework.</p>\n<p><a href=\"https://courk.cc/laser-fault-injection-platform-laser-driver-board\" title=\"Interactive 3D Render &amp; Design Files\" rel=\"nofollow ugc noopener\"><img src=\"https://courk.cc/rp2350-challenge-laser/assets/laser_driver_icon.webp\" alt=\"Interactive 3D Render &amp; Design Files\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /><br />\nInteractive 3D Render &amp; Design Files</a> </p>\n<h2 id=\"board-architecture\">Board Architecture</h2>\n<p>The architecture of the <em>Laser Driver Board</em> is outlined below.</p>\n<pre><code>        flowchart TB\n            A{{USB Connector}} &amp;LT--&gt; B(USB to I2C Bridge)\n            B --&gt;|Configure| C(Digital Potentiometer)\n            B --&gt;|Trigger| E\n            C .-&gt; D(High Voltage Power Supply Circuit)\n            D .-&gt; E(Pulse Generator Circuit)\n            E .-&gt; F(Laser Diode)\n            G{{Pin Header}} --&gt;|Trigger| E\n            F --&gt;|Current Sense| H{{SMA Connector}}</code></pre>\n<p>Laser Driver Board Architecture</p>\n<p>The board is powered and configured from a <em>USB</em> port. The host computer connected to this port can be used to:</p>\n<ul><li>Configure the output level of a high-voltage (up to 75V75V75V) power supply. This high supply is needed for the pulse generator circuit to operate.- Manually send laser pulses.</li></ul>\n<p>However, because <em>USB</em> cannot be used for anything time-critical, laser pulses can also be generated from a simple pin header connector. This connector is interfaced with a <em>FPGA</em> board during the attack.</p>\n<p>An <em>SMA</em> connector can be used to monitor the shape and intensity of the current pulses passing through the laser diode.</p>\n<h2 id=\"pulse-generation-principle\">Pulse Generation Principle</h2>\n<p>A simplified schematic of the pulse generation circuit is outlined below.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/RLC_driver.webp\" alt=\"Simplified Pulse Generator Circuit\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Simplified Pulse Generator Circuit</p>\n<p>The capacitor <code>C</code> is first charged from the high-voltage power supply. To trigger a current pulse through the laser diode, the switching element <code>SW</code> is closed.</p>\n<p>The current response is close to the one observed with a typical <code>RLC</code> circuit. The value of <code>R</code> is chosen to ensure the response of the circuit is critically damped.</p>\n<p><code>C</code> and <code>L</code> can be fine-tuned to change the duration of the pulse, while the high-voltage level can be used to set the peak current.</p>\n<p>Unfortunately, this means that changing the pulse duration is only possible by soldering new components onto the board. I had to perform this rework several times, gradually increasing the peak current until faults were successfully injected.</p>\n<p>The values that have been used to successfully exploit the <code>RP2350</code> are:</p>\n<ul><li>R=1.4ΩR = 1.4 \\OmegaR=1.4Ω- L=33nHL = 33 \\text{nH}L=33nH- C=60nFC = 60 \\text{nF}C=60nF</li></ul>\n<p>Note that the selected resistor must be able to handle high current pulses. After having destroyed several parts, I ended up using <a href=\"https://www.vishay.com/en/product/28956/\" rel=\"nofollow ugc noopener\">Vishay’s <code>CMB 0207</code> family</a>.</p>\n<p>The selected <code>RLC</code> values result in the following theoretical current pulses.</p>\n<p>In practice, the pulses generated by the hardware are reasonably close to these theoretical curves.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/sma_voltage.webp\" alt=\"Voltage Measured from the SMA Connector of the Laser Driver Board\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Voltage Measured from the SMA Connector of the Laser Driver Board</p>\n<p>Unfortunately, in part because the optical components (lenses, beam splitter) I used are not specified for infrared light, I’m not sure how these current curves translate to the actual optical power received on the die surface.</p>\n<p>Finally, note that the switching element <code>SW</code> is implemented with a fancy <em>GaN</em> <em>FET</em>. This choice was initially made to experiment with ultra-short pulses. However, it turns out that this wasn’t particularly useful. The <em>BOM</em> cost could be reduced by opting for a simpler <em>MOSFET</em> instead.</p>\n<p>Despite this, the price of this <em>BOM</em> for small quantities does not exceed €30, excluding the cost of the laser diode.</p>\n<h2 id=\"laser-diode-sourcing\">Laser Diode Sourcing</h2>\n<p>Finding a suitable laser diode was challenging. It turns out high-power 1064nm1064 \\text{nm}1064nm laser diodes are difficult to find and expensive!</p>\n<p>After a few unsuccessful attempts (<em>i.e.</em> not enough power to inject a fault without damaging the diode first) with low-power parts (below 300mW300 \\text{mW}300mW), I contacted a manufacturer on <em>Alibaba</em> and was able to order, for about €300, five pieces of a part rated for 3W3 \\text{W}3W. The datasheet for this part is available <a href=\"https://courk.cc/rp2350-challenge-laser/assets/TO5_3W_1064nm_laser_diode.pdf\" rel=\"nofollow ugc noopener\">here</a>.</p>\n<p>This datasheet clearly states that the maximum operating current is 3.8A3.8 \\text{A}3.8A. Based on the current curves shared above, it’s very obvious the part is used well above its rating.</p>\n<p>While I anticipated encountering <a href=\"https://en.wikipedia.org/wiki/Catastrophic_optical_damage\" rel=\"nofollow ugc noopener\">catastrophic optical damage issues</a>, even after several thousand pulses, I don’t think I have harmed these diodes yet! This might be due to the short duration of the current pulses.</p>\n<p>This surprising result matches the observation of <em>Continuous wave laser diodes enable fast optoacoustic imaging</em> <a href=\"#STYLOGIANNIS201831\">(Stylogiannis et al., 2018)</a>:</p>\n<blockquote><p>We investigated whether continuous wave (CW) laser diodes, which are available in visible and near-infrared regions, can be good optoacoustic light sources when overdriven with a peak current &gt;40-fold higher than the CW absolute maximum.</p></blockquote>\n<p>Note</p>\n<p>A major difference between my work and that of the team behind the <a href=\"https://www.blackhat.com/us-24/briefings/schedule/#laser-beams--light-streams-letting-hackers-go-pew-pew-building-affordable-light-based-hardware-security-tooling-39708\" rel=\"nofollow ugc noopener\"><em>“RayV-Lite”</em> system</a> is that they used a widely available laser diode marketed as a “green” one.</p>\n<p>That’s a clever choice, as it seems that, because of the way green light is actually generated, such diodes typically emit a significant amount of power at 1064nm1064 \\text{nm}1064nm. <a href=\"#galang2010greenlaserpointerhazard\">(Galang et al., 2010)</a></p>\n<hr />\n<h1 id=\"fault-injection-results\">Fault Injection Results</h1>\n<h2 id=\"identification-of-sensitive-areas\">Identification of Sensitive Areas</h2>\n<p>After developing the <em>Laser Fault Injection Platform</em>, it was time to actually attempt to inject faults into a <code>RP2350</code>.</p>\n<p>I first began studying the effect of laser pulses on a dummy firmware, similar to the one proposed by <a href=\"https://www.hextree.io/\" rel=\"nofollow ugc noopener\"><em>Hextree.io</em></a> in their <a href=\"https://github.com/hextreeio/rp2350-security-playground-demo\" rel=\"nofollow ugc noopener\">RP2350 Security Playground Demo</a>.</p>\n<p>I slowly scanned various areas of the die, varying laser power, focus, and other parameters. However, I did not attempt to comprehensively characterize the behavior of the system over the entire die surface area for the following reasons:</p>\n<ul><li>It’s a slow process; in the interest of time, I stopped as soon after I was able to disturb the <em>ARM</em> core execution flow without triggering the <em>Glitch Detectors</em>.- I hit a couple of areas that resulted in a full crash of the system and high power consumption. Considering that preparing samples is a bit tedious, I would rather not damage parts this way.</li></ul>\n<p>The sensitive surfaces I exploited are roughly located within the area highlighted below. Because the positioning repeatability of the <em>Laser Fault Injection Platform</em> isn’t perfect, while attempting to exploit the chip, I typically moved the beam slowly around these locations.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/sensitive_area.jpg\" alt=\"Rough location of the area that is usually targeted to inject faults\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Rough location of the area that is usually targeted to inject faults</p>\n<p>I found that depending on where the code is running from (<em>SRAM</em>, <em>Flash</em>, or <em>ROM</em>), or possibly based on the type of instructions being executed, it appears that slightly different locations had to be targeted to obtain interesting results.</p>\n<h2 id=\"targeting-for-secure-boot-bypass\">Targeting for Secure Boot Bypass</h2>\n<p>The exact beam location used for the first <em>Secure Boot</em> bypass I achieved is displayed below. Here, the laser is pulsed at a low power to avoid blinding the camera.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/laser_pulse_animation_x1.webp\" alt=\"Laser beam position that led to the first Secure Boot bypass\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>Laser beam position that led to the first Secure Boot bypass</p>\n<hr />\n<h1 id=\"secure-boot-feature-bypass\">Secure Boot Feature Bypass</h1>\n<h2 id=\"constraints\">Constraints</h2>\n<p>Thanks to the <em>Laser Fault Injection Platform</em>, injecting faults without triggering the glitch detectors is now possible! However, this alone is not enough to bypass the <em>Secure Boot</em> feature implemented in the <em>Boot ROM</em> of the <code>RP2350</code>. Indeed, as highlighted earlier, the <em>Boot ROM</em> is hardened and uses various features to resist faults. Trivial methods, such as glitching a conditional branch choosing between a valid or invalid signature, aren’t directly possible.</p>\n<p>Furthermore, when searching for a way to bypass the <em>Secure Boot</em> feature, the following constraints must be considered:</p>\n<ul><li>With my custom hardware, I can only hope to inject a single fault at a time; complicated schemes with multiple glitches in a row aren’t possible. The limiting factor is the <em>Laser Driver Board</em>: the capacitor bank needs a bit of time to be recharged after each pulse.- The laser pulse should be triggered following an observable external event, such as the activity of the <em>QSPI</em> bus.- Random delays can be introduced by some instructions executed by the redundancy co-processor. Ideally, to target specific instructions, few to none of these special instructions should be executed between the trigger event and the fault injection.</li></ul>\n<h2 id=\"boot-rom-analysis-method\">Boot ROM Analysis Method</h2>\n<p>The source code of the <em>Boot ROM</em> of the <code>RP2350</code> is <a href=\"https://github.com/raspberrypi/pico-bootrom-rp2350\" rel=\"nofollow ugc noopener\">publicly available</a>. That’s <strong>really</strong> nice, and it makes high-level analysis of the <em>Secure Boot</em> way easier! Kudos to <em>Raspberry Pi</em>!</p>\n<p>However, to study the possible impact of fault injections, I found it much easier to reflect directly against the actual <em>ARM</em> assembly code. Hence, after a quick read of the source code, I spent most of my time in <a href=\"https://ghidra-sre.org/\" rel=\"nofollow ugc noopener\">Ghidra</a>, looking at the content of the <a href=\"https://github.com/raspberrypi/pico-bootrom-rp2350/releases/tag/A2\" rel=\"nofollow ugc noopener\"><em>Boot ROM ELF</em> file, also shared by Raspberry Pi</a>.</p>\n<p>In doing so, I managed to find a way to bypass the <em>Secure Boot</em> that addressed the previously listed constraints:</p>\n<ul><li>Things could work out with a single instruction “skip” (though “skip” may be a misnomer, “mutation” is maybe a better word).- The instruction to target closely follows an observable <em>QSPI</em> transfer.- At worst, a single random delay co-processor instruction is executed between the trigger and the instruction to target.</li></ul>\n<h2 id=\"high-level-idea\">High-Level Idea</h2>\n<p>Let’s consider the <a href=\"https://github.com/raspberrypi/pico-bootrom-rp2350/blob/451edbcd769770f92ce265c05d6c36ad040994fa/src/main/arm/varm_blocks.c#L587\" rel=\"nofollow ugc noopener\"><code>s_varm_crit_ram_trash_verify_block</code></a> function. This function is at the core of the <em>Secure Boot</em> implementation. A very stripped-down version of its implementation is available below.</p>\n<pre><code>// Start computing a hash\nsb_sha256_init(&amp;sha);\n\n// Load the data from the flash to the RAM\ns_varm_crit_mem_copy_by_words((uint32_t *)to_storage_addr,\n                              resolve_ram_or_absolute_flash_addr(\n                                  from_storage_addr),\n                              (size + 3u) &amp; ~3u);\n\n// Feed the hash engine with the data, obtained from RAM\nuint32_t *src = resolve_ram_or_absolute_flash_addr(to_storage_addr);\nsb_sha256_update_32(&amp;sha, src, size &amp; ~3u);\n\n// Include block data (containing source address, dest address and size)\n// to the SHA-256 hash\nsb_sha256_update_32(&amp;sha, block_data, parsed_block-&gt;hash_def_block_words_included * 4);\n\n// Finalize the hash\nsb_sha256_finish(&amp;sha, signature_workspace-&gt;hash.bytes);\n\n// Do the complicated &amp; well protected signature validation\nsig_matches_image_keyx = s_arm8_verify_signature_secp256k1(signature_workspace-&gt;sig_context_buffer,\n                                                           &amp;public_key[0],\n                                                           &amp;signature_workspace-&gt;hash,\n                                                           &amp;signature[0]);</code></pre>\n<p>This code implements a very usual signature verification scheme: the firmware to validate is reduced down to a hash, which is fed to the signature verification algorithm.</p>\n<pre><code>        flowchart TD\n            A[(Firmware Data in Flash)] --&gt; B(&quot;`Memory Copy\n            _s_varm_crit_mem_copy_by_words_`&quot;)\n            B --&gt; C[(Firmware Data in RAM)]\n            C --&gt; D(&quot;`SHA-256\n            _sb_sha256_update_32_`&quot;)\n            D --&gt; E(&quot;`ECDSA Signature Verification\n            _s_arm8_verify_signature_secp256k1_`&quot;)\n            F[[Public Key]] --&gt; E\n            E --&gt;|Signature Valid| R(Execute Firmware Data from RAM)\n            E --&gt;|Signature Invalid| S(Failure)</code></pre>\n<p>Nominal Firmware Verification Process</p>\n<p>The idea is to inject a fault after the call to <code>s_varm_crit_mem_copy_by_words</code> and before the call to <code>sb_sha256_update_32</code>. This could result in the <em>SHA-256</em> hash being computed against different data than the one that was previously loaded into <em>RAM</em>.</p>\n<pre><code>        flowchart TD\n            A[(Firmware Data in Flash)] --&gt; B(&quot;`Memory Copy\n            _s_varm_crit_mem_copy_by_words_`&quot;)\n            B --&gt; C[(Firmware Data in RAM)]\n            C --x Z@{ shape: bolt }\n            Z --&gt; D(&quot;`SHA-256\n            _sb_sha256_update_32_`&quot;)\n            D --&gt; E(&quot;`ECDSA Signature Verification\n            _s_arm8_verify_signature_secp256k1_`&quot;)\n            F[[Public Key]] --&gt; E\n            E --&gt;|Signature Valid| R(Execute Firmware Data from RAM)\n            E --&gt;|Signature Invalid| S(Failure)\n            X[(Unexpected Data)] --&gt; Z\n            style X fill:#f9f,stroke:#333\n            style Z fill:#f9f,stroke:#333</code></pre>\n<p>Glitched Firmware Verification Process</p>\n<p>If the “unexpected data” used to compute the <em>SHA-256</em> hash can match the one corresponding to a valid firmware, the signature verification will succeed, no matter the data loaded into <em>RAM</em>.</p>\n<h2 id=\"fault-injection-scenarios\">Fault Injection Scenarios</h2>\n<p>This section explores the impact of possibly interesting faults against various instructions located between the call to <code>s_varm_crit_mem_copy_by_words</code> and the call to <code>sb_sha256_update_32</code>.</p>\n<h3 id=\"scenario-1-single-instruction-skip\">Scenario #1 - Single Instruction “Skip”</h3>\n<p>Note</p>\n<p>“Skip” is possibly a misnomer. In practice, the targeted instruction here could be mutated. However, for this specific scenario, the exact result of the mutation doesn’t matter too much.</p>\n<p>The *C* code listed above translates to the following assembly pieces.</p>\n<p><code>s_varm_crit_mem_copy_by_words</code> is first called.</p>\n<pre><code>00001d5c: 1a 00              movs          r2,r3\n00001d5e: 20 00              movs          r0,r4\n00001d60: 0d 93              str           r3,[sp,#local_24]\n00001d62: 01 f0 82 fb        bl            varm_to_s_native_crit_mem_copy_by_words_impl\n00001d66: 0d 9b              ldr           r3,[sp,#local_24]\n00001d68: 43 ec 70 07        mcrr          p7,0x7,r0,r3,cr0\n00001d6c: ac e7              b             LAB_00001cc8</code></pre>\n<p>The implementation of the function, listed below, increments <code>R1</code> until the target size has been reached.</p>\n<pre><code>0000346c: 19 fe 3a c7        mrc2          p7,0x0,r12,cr9,cr10,0x1\n00003470: 10 b5              push          {r4,lr}\n00003472: 03 46              mov           r3,r0\n00003474: 22 b1              cbz           r2,LAB_00003480\n00003476: 1a 44              add           r2,r3\n    LAB_00003478:\n00003478: 10 c9              ldmia         r1!,{r4}\n0000347a: 10 c0              stmia         r0!,{r4}\n0000347c: 90 42              cmp           r0,r2\n0000347e: fb d3              bcc           LAB_00003478\n    LAB_00003480:\n00003480: c0 1a              subs          r0,r0,r3\n00003482: 09 fe 3a c7        mcr2          p7,0x0,r12,cr9,cr10,0x1\n00003486: 10 bd              pop           {r4,pc}</code></pre>\n<p>Next, after the function returns, <code>R1</code> is kept untouched until the call to <code>sb_sha256_update_32</code>.</p>\n<pre><code>00001d02: 32 00              movs          r2,r6 // size\n00001d04: 21 00              movs          r1,r4 // src\n00001d06: 0f a8              add           r0,sp,#0x3c // sha context\n00001d08: 02 f0 49 fb        bl            sb_sha256_update_32</code></pre>\n<p>If the instruction at <code>0x00001d04</code> can be “skipped”, the following will in effect be executed:</p>\n<pre><code>r1 = resolve_ram_or_absolute_flash_addr(from_storage_addr) + size;\nsb_sha256_update_32(&amp;sha, r1, size);</code></pre>\n<p>The data referenced by <code>R1</code> is located in the memory-mapped area corresponding to the flash data. This specific area performs uncached reads, meaning that data will be retrieved directly from the external <em>QSPI</em> bus. An attacker can manipulate this data.</p>\n<p>This is where the “dual flash” feature embedded in the custom <em>I/O Board</em> becomes useful, as it simplifies the process of pushing arbitrary values over the bus. If necessary, two reads from the same address can yield different data.</p>\n<h3 id=\"scenario-2-register-value-corruption\">Scenario #2 - Register Value Corruption</h3>\n<p>During my tests, I observed that injecting faults between <code>s_varm_crit_mem_copy_by_words</code> and <code>sb_sha256_update_32</code> often resulted in data being pulled from the flash starting from offset <code>0</code>.</p>\n<p>I don’t have a clear explanation, such as a simple instruction skip, regarding why this happens.</p>\n<p>It could, for instance, mean that when the following is executed:</p>\n<pre><code>00001d02: 32 00              movs          r2,r6 // size\n00001d04: 21 00              movs          r1,r4 // src\n00001d06: 0f a8              add           r0,sp,#0x3c // sha context\n00001d08: 02 f0 49 fb        bl            sb_sha256_update_32</code></pre>\n<p>The value of <code>R4</code> points to the beginning of the memory-mapped area corresponding to the flash data.</p>\n<p>Anyway, this means that once again, the call to <code>sb_sha256_update_32</code> can use data under the control of an attacker instead of the data already loaded into <em>RAM</em>.</p>\n<h3 id=\"scenario-3-instruction-mutation\">Scenario #3 - Instruction Mutation</h3>\n<p>The instructions corresponding to <code>s_varm_crit_mem_copy_by_words</code> are available below.</p>\n<pre><code>0000346c: 19 fe 3a c7        mrc2          p7,0x0,r12,cr9,cr10,0x1\n00003470: 10 b5              push          {r4,lr}\n00003472: 03 46              mov           r3,r0\n00003474: 22 b1              cbz           r2,LAB_00003480\n00003476: 1a 44              add           r2,r3\n    LAB_00003478:\n00003478: 10 c9              ldmia         r1!,{r4}\n0000347a: 10 c0              stmia         r0!,{r4}\n0000347c: 90 42              cmp           r0,r2\n0000347e: fb d3              bcc           LAB_00003478\n    LAB_00003480:\n00003480: c0 1a              subs          r0,r0,r3\n00003482: 09 fe 3a c7        mcr2          p7,0x0,r12,cr9,cr10,0x1\n00003486: 10 bd              pop           {r4,pc}</code></pre>\n<p>If a fault can be injected at <code>0x00003486</code>, it’s possible for the <code>pop {r4,pc}</code> instruction to be altered, possibly resulting in the value of <code>R4</code> not being restored.</p>\n<p>Before <code>pop {r4,pc}</code>, <code>R4</code> corresponds to the last word copied from the flash memory to <em>RAM</em>, a value under the control of the attacker. This value could, for instance, be set to an address contained in the memory-mapped flash area.</p>\n<p><code>R4</code> is subsequently used when calling <code>sb_sha256_update_32</code>.</p>\n<pre><code>00001d02: 32 00              movs          r2,r6 // size\n00001d04: 21 00              movs          r1,r4 // src\n00001d06: 0f a8              add           r0,sp,#0x3c // sha context\n00001d08: 02 f0 49 fb        bl            sb_sha256_update_32</code></pre>\n<p>Once again, <code>sb_sha256_update_32</code> could be forced to run against data pulled from the <em>QSPI</em> bus.</p>\n<h2 id=\"attack-process\">Attack Process</h2>\n<h3 id=\"software-architecture\">Software Architecture</h3>\n<p>Various software components have been developed to implement the logic of the attack and control the electronics.</p>\n<p><a href=\"https://github.com/courk/rp2350-lfi\" title=\"Browse the code on GitHub\" rel=\"nofollow ugc noopener\"><img src=\"https://courk.cc/rp2350-challenge-laser/assets/github-logo.webp\" alt=\"Browse the code on GitHub\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /><br />\nBrowse the code on GitHub</a> </p>\n<h4 id=\"fpga\">FPGA</h4>\n<p>To synchronize the laser pulse with the execution of the <em>Boot ROM</em>, the activity of the <em>QSPI</em> is monitored by the gateware of an <em>FPGA Board</em> connected to the <em>I/O Board</em>.</p>\n<p>The choice of the <em>FPGA</em> platform isn’t super critical as the <code>RP2350</code> is clocked at a conservatively low speed when the <em>Boot ROM</em> is running. I chose to use a <a href=\"https://glasgow-embedded.org/latest/intro.html\" rel=\"nofollow ugc noopener\"><em>Glasgow Interface Explorer</em></a> tool.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-small/1x/glasgow-pcba.webp\" alt=\"The Glasgow Interface Explorer\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>The Glasgow Interface Explorer</p>\n<p>It embeds an <a href=\"https://www.latticesemi.com/ice40\" rel=\"nofollow ugc noopener\"><code>iCE40</code></a> <em>FPGA</em> compatible with <a href=\"https://github.com/YosysHQ/icestorm\" rel=\"nofollow ugc noopener\">open source tools</a>. Finally, it integrates well with <a href=\"https://github.com/amaranth-lang/amaranth\" rel=\"nofollow ugc noopener\">Amaranth HDL</a>, which I find more convenient to develop with than more common <em>HDL</em> languages like <a href=\"https://en.wikipedia.org/wiki/Verilog\" rel=\"nofollow ugc noopener\"><em>Verilog</em></a> or <a href=\"https://en.wikipedia.org/wiki/VHDL\" rel=\"nofollow ugc noopener\"><em>VHDL</em></a>.</p>\n<p>The gateware written for this project is responsible for:</p>\n<ul><li><strong>Basic I/O Control</strong>:<ul><li>Turning the power supply of the target <code>RP2350</code> on and off.- Controlling the <code>RUN</code> and <code>BOOTSEL</code> signals.- <strong>Trigger Timing</strong>: Monitoring the <em>QSPI</em> bus in real time.- <strong>Attack Orchestration</strong>:<ul><li>Dynamically selecting the active <em>QSPI</em> Flash memory.- Pulsing the laser.</li></ul></li></ul></li></ul>\n<h4 id=\"laser-driver-board\">Laser Driver Board</h4>\n<p>The <em>Laser Driver Board</em> communicates with the host computer through a <em>USB-to-I2C</em> bridge component.</p>\n<p>No firmware running on the board needed to be written, and the host computer can be directly used to configure the high-voltage power supply for the laser diode pulser circuit.</p>\n<h4 id=\"positioning-stage-control\">Positioning Stage Control</h4>\n<p>The <em>Positioning Stage</em> is controlled by <a href=\"https://openflexure.org/software/raspbian-openflexure\" rel=\"nofollow ugc noopener\">software running on a Raspberry Pi single-board computer</a>.</p>\n<p>The *X*, *Y*, and *Z* coordinates of the moving platform can be programmatically set using a web-based <em>API</em>.</p>\n<p>In the context of this attack, this <em>API</em> is leveraged to slowly scan over the sensitive areas while pulsing the laser.</p>\n<h3 id=\"laser-pulse-synchronization\">Laser Pulse Synchronization</h3>\n<p>The last <em>QSPI</em> read corresponding to the call of <code>s_varm_crit_mem_copy_by_words</code> can be detected with little uncertainty by the <em>FPGA</em> gateware. From this point, before calling <code>sb_sha256_update_32</code>, the following instructions are executed.</p>\n<pre><code>00003478: 10 c9              ldmia         r1!,{r4}\n0000347a: 10 c0              stmia         r0!,{r4}\n0000347c: 90 42              cmp           r0,r2\n0000347e: fb d3              bcc           LAB_00003478\n00003480: c0 1a              subs          r0,r0,r3\n00003482: 09 fe 3a c7        mcr2          p7,0x0,r12,cr9,cr10,0x1\n00003486: 10 bd              pop           {r4,pc}\n\n00001d66: 0d 9b              ldr           r3,[sp,#local_24]\n00001d68: 43 ec 70 07        mcrr          p7,0x7,r0,r3,cr0\n00001d6c: ac e7              b             LAB_00001cc8\n\n00001cc8: 0b 9b              ldr           r3,[sp,#local_2c]\n00001cca: 00 2b              cmp           r3,#0x0\n00001ccc: b3 d0              beq           LAB_00001c36\n00001cce: 03 9b              ldr           r3,[sp,#local_4c]\n00001cd0: 73 b1              cbz           r3,LAB_00001cf0\n00001cf0: 23 0e              lsrs          r3,r4,#0x18\n00001cf2: 10 2b              cmp           r3,#0x10\n00001cf4: 02 d8              bhi           LAB_00001cfc\n\n00001cfc: 03 23              movs          r3,#0x3\n00001cfe: 3e 00              movs          r6,r7\n00001d00: 9e 43              bics          r6,r3\n00001d02: 32 00              movs          r2,r6\n00001d04: 21 00              movs          r1,r4\n00001d06: 0f a8              add           r0,sp,#0x3c\n00001d08: 02 f0 49 fb        bl            sb_sha256_update_32</code></pre>\n<p>A redundancy co-processor instruction is executed at <code>0x00001d68</code>, introducing a random delay of up to 127 system clock cycles. As a result, it becomes impractical to consistently time a laser pulse to target a specific instruction following <code>0x00001d68</code>.</p>\n<p>However, this instruction is the only one that introduces a random delay. The software designed for the attack allows for about 20 attempts per second, which is sufficient to inject interesting faults in a reasonable amount of time.</p>\n<h3 id=\"flash-memory-organization\">Flash Memory Organization</h3>\n<p>Before starting the attack, the two <em>QSPI</em> flashes of the <em>I/O Board</em> are organized as follows:</p>\n<p>The first flash, whose content will be loaded to <em>RAM</em>, contains a copy of the valid, signed firmware, including a signature block, patched as follows:</p>\n<ul><li>A small shellcode is written at the reset handler offset. This shellcode is designed to jump to arbitrary firmware located further in the flash memory at address <code>XIP_BASE + 0x10000</code>. <code>XIP_BASE</code> corresponds to the beginning of the memory-mapped flash data, while <code>0x10000</code> is an arbitrary offset.- The last word of the data loaded to <em>RAM</em> is set to <code>XIP_NOCACHE_NOALLOC_NOTRANSLATE_BASE + 0x7000</code>. <code>0x7000</code> is an arbitrary offset that will be used later, while <code>XIP_NOCACHE_NOALLOC_NOTRANSLATE_BASE</code> also returns flash data.</li></ul>\n<p>The second flash, whose content is expected to be read after a fault has been injected, contains three copies of the unmodified firmware. Computing the <em>SHA-256</em> hash against one of these images will result in a valid hash. The copies, ensuring all the fault injection scenarios that have previously been outlined, are located at:</p>\n<ul><li>Flash offset <code>0x0</code>, to support the <em>Scenario #2</em>.- The offset corresponding to the size of the data copied to <em>RAM</em>, to support the <em>Scenario #1</em>.- Flash offset <code>0x7000</code>, to support the <em>Scenario #3</em>.</li></ul>\n<p>Finally, an arbitrary firmware is copied at offset <code>0x10000</code>. This firmware will run if the shellcode, previously loaded to <em>RAM</em>, is executed.</p>\n<h3 id=\"attack-loop\">Attack Loop</h3>\n<p>During the attack, the following process is repeated in a loop.</p>\n<ul><li>The first flash is selected.- The <code>RP2350</code> is powered on.- <em>QSPI</em> bus reads are monitored until the last byte corresponding to the call to <code>s_varm_crit_mem_copy_by_words</code> has been read.- The second flash is selected.- After an arbitrary delay, the laser is pulsed.- <em>QSPI</em> bus reads are monitored again to verify if the data pulled from the flash corresponds to a successful bypass.- In case of failure, the <code>RP2350</code> is powered off, and a new attempt will be made.</li></ul>\n<pre><code>        flowchart TD\n            A[Select First Flash] --&gt; B[Power On RP2350]\n            B --&gt; C[Monitor QSPI Reads]\n            C --&gt; D[Select Second Flash]\n            D --&gt; E[Arbitrary Delay]\n            E --&gt; F[Pulse Laser]\n            F --&gt; G[Monitor QSPI Reads]\n            G --&gt;|Failure| H[Power Off RP2350]\n            H --&gt; A\n            G --&gt;|Success| I[Arbitrary Firmware Execution]</code></pre>\n<p>Attack Loop</p>\n<h2 id=\"results\">Results</h2>\n<p>When targeting sensitive die areas, injecting faults that result in data being pulled from the <em>QSPI</em> bus at one of the expected addresses during the execution of <code>sb_sha256_update_32</code> is quite common.</p>\n<p>However, a major issue was that faults were often impacting the system a bit too hard, corrupting for instance the register corresponding to the <code>size</code> parameter of <code>sb_sha256_update_32</code>.</p>\n<p>Another issue regards the positioning stage. Apart from some backlash in the gearing system, it seems the position drifts a bit over time and possibly temperature, making consistently hitting the exact sample spot complicated.</p>\n<p>These reduced the success rate of the attack significantly. I only have been able to see the first <em>Secure Boot</em> bypass after more than 16 hours of tweaking the laser pulse parameters and position. However, following this fine-tuning, I only had to wait for about 20 minutes for a new success to appear.</p>\n<figure><img src=\"https://courk.cc/rp2350-challenge-laser/assets/derivatives/article-medium/1x/success_screen.jpg\" alt=\"My monitor displays the secret value hidden in the RP2350 after the first successful bypass\" loading=\"lazy\" decoding=\"async\" referrerpolicy=\"no-referrer\" /></figure>\n<p>My monitor displays the secret value hidden in the RP2350 after the first successful bypass</p>\n<p>The bypass enables the execution of arbitrary firmware, which can then access secrets stored in the <em>OTP</em> area of the <code>RP2350</code>. This was the objective of <a href=\"https://github.com/raspberrypi/rp2350_hacking_challenge/\" rel=\"nofollow ugc noopener\">Raspberry Pi’s Hacking Challenge</a>.</p>\n<h2 id=\"possible-improvements\">Possible Improvements</h2>\n<p>Several elements could be improved to increase the success rate of the attack:</p>\n<ul><li>The laser pulse duration could be fine-tuned. Due to the simple design of the <em>Laser Driver Board</em>, adjusting the pulse duration requires modifying the values of physical components. This process can be cumbersome, so I haven’t thoroughly explored the impact of pulse duration.- The laser spot size resulting from the <em>Optical Subsystem</em> is relatively large compared to what is typically used in similar attacks. A smaller spot size would likely lead to better-controlled and more repeatable faults.- The <em>FPGA</em> gateware could be enhanced. Instead of using two physical <em>QSPI</em> flashes, the <em>FPGA</em> could be utilized to emulate one, and dynamically supply the correct data, regardless of the flash address requested after the fault. However, this possibly goes a bit beyond the capabilities of the <em>FPGA</em> I used.</li></ul>\n<hr />\n<h1 id=\"conclusion\">Conclusion</h1>\n<p>Laser fault injection can be performed on a budget! Although it requires a lot of trial and error, and sourcing a suitable laser source can be tedious, a functional setup can indeed be achieved.</p>\n<p>Due to significant compromises, the performance of such a system is not optimal, but interesting results can still be obtained: injecting faults in the <code>RP2350</code> without triggering its glitch detectors becomes possible.</p>\n<p>This alone is not enough to bypass the <em>Secure Boot</em> feature of the <code>RP2350</code>. However, a small but critical section of the <em>Boot ROM</em> has been found to be less hardened and protected by the redundancy co-processor. Injecting a fault at this point, while supplying a compatible payload over the <em>QSPI</em> bus, can essentially defeat the <em>Secure Boot</em>.</p>\n<p>While <a href=\"https://events.ccc.de/congress/2024/hub/en/event/hacking-the-rp2350/\" rel=\"nofollow ugc noopener\">way simpler methods</a> have now been made public, this work still addresses <a href=\"https://www.raspberrypi.com/news/can-you-hack-our-new-chip/\" rel=\"nofollow ugc noopener\">Raspberry Pi’s <code>RP2350</code> Hacking Challenge</a>.</p>\n<p>Additionally, note that it may also be possible to exploit the section of the <em>Boot ROM</em> I targeted without even resorting to <em>LFI</em>. There are <a href=\"https://infosec.exchange/@barsteward/113727673866158485\" rel=\"nofollow ugc noopener\">some reports</a> of carefully performed <em>EMFI</em> attacks able to bypass the glitch detectors.</p>\n<blockquote><p>The glitch detector is pretty good at detecting EMFI attempts, but it was possible to glitch CPU operations without triggering it with a small coil and a low power glitch</p></blockquote>\n<p>Still, I regret nothing; lasers are fun to play with!</p>\n<h2 id=\"disclosure\">Disclosure</h2>\n<p>Following my first successful bypass, I immediately contacted <em>Raspberry Pi</em>. <a href=\"https://courk.cc/rp2350-challenge-laser/assets/original_submission/index.html\" rel=\"nofollow ugc noopener\">For transparency, the documents I shared with them are available here</a>.</p>\n<p>Communication with the team was smooth and enjoyable. They acknowledged that the “break-in” was valid and confirmed that the next <em>Boot ROM</em> of the <code>RP2350</code> would include more hardening around the specific area of the code I targeted.</p>\n<hr />\n<h2 id=\"bibliography\">Bibliography</h2>\n<p>Andrew &#39;bunnie&#39; Huang. Infra-red, in-situ (iris) inspection of silicon. 2023. URL: <a href=\"https://arxiv.org/abs/2303.07406\" rel=\"nofollow ugc noopener\">https://arxiv.org/abs/2303.07406</a>, <a href=\"https://arxiv.org/abs/2303.07406\" rel=\"nofollow ugc noopener\">arXiv:2303.07406</a>. <a href=\"#ref-huang2023infraredinsituirisinspection-1\" title=\"Jump back to reference 1\">↩</a></p>\n<p>Jemellie Galang, Allesandro Restelli, Edward W. Hagley, and Charles W. Clark. A green laser pointer hazard. 2010. URL: <a href=\"https://arxiv.org/abs/1008.1452\" rel=\"nofollow ugc noopener\">https://arxiv.org/abs/1008.1452</a>, <a href=\"https://arxiv.org/abs/1008.1452\" rel=\"nofollow ugc noopener\">arXiv:1008.1452</a>. <a href=\"#ref-galang2010greenlaserpointerhazard-1\" title=\"Jump back to reference 1\">↩</a></p>\n<p>Samuel McDermott, Filip Ayazi, Joel Collins, Joe Knapper, Julian Stirling, Richard Bowman, and Pietro Cicuta. Multi-modal microscopy imaging with the openflexure delta stage. <em>Opt. Express</em>, 30(15):26377–26395, Jul 2022. URL: <a href=\"https://opg.optica.org/oe/abstract.cfm?URI=oe-30-15-26377\" rel=\"nofollow ugc noopener\">https://opg.optica.org/oe/abstract.cfm?URI=oe-30-15-26377</a>, <a href=\"https://doi.org/10.1364/OE.450211\" rel=\"nofollow ugc noopener\">doi:10.1364/OE.450211</a>. <a href=\"#ref-McDermott:22-1\" title=\"Jump back to reference 1\">↩</a></p>\n<p>Antonios Stylogiannis, Ludwig Prade, Andreas Buehler, Juan Aguirre, George Sergiadis, and Vasilis Ntziachristos. Continuous wave laser diodes enable fast optoacoustic imaging. <em>Photoacoustics</em>, 9:31–38, 2018. URL: <a href=\"https://www.sciencedirect.com/science/article/pii/S2213597917300356\" rel=\"nofollow ugc noopener\">https://www.sciencedirect.com/science/article/pii/S2213597917300356</a>, <a href=\"https://doi.org/https://doi.org/10.1016/j.pacs.2017.12.002\" rel=\"nofollow ugc noopener\">doi:<a href=\"https://doi.org/10.1016/j.pacs.2017.12.002\" rel=\"nofollow ugc noopener\">https://doi.org/10.1016/j.pacs.2017.12.002</a></a>. <a href=\"#ref-STYLOGIANNIS201831-1\" title=\"Jump back to reference 1\">↩</a></p>\n<hr />\n<p><em>Originally published on Courk&#39;s Blog under a Creative Commons Attribution-ShareAlike 4.0 International License.</em></p>","headings":[{"level":1,"text":"Laser Fault Injection on a Budget: RP2350 Edition","id":"laser-fault-injection-on-a-budget-rp2350-edition"},{"level":1,"text":"Introduction","id":"introduction"},{"level":1,"text":"Hacking Challenge & RP2350 Security Features","id":"hacking-challenge-rp2350-security-features"},{"level":2,"text":"Objectives of the Challenge","id":"objectives-of-the-challenge"},{"level":2,"text":"Security Features","id":"security-features"},{"level":1,"text":"Article Overview","id":"article-overview"},{"level":2,"text":"Why choosing Laser Fault Injection","id":"why-choosing-laser-fault-injection"},{"level":2,"text":"Sample Preparation","id":"sample-preparation"},{"level":2,"text":"Die Imaging & Laser Focusing","id":"die-imaging-laser-focusing"},{"level":2,"text":"Fault Injection & Secure Boot Bypass","id":"fault-injection-secure-boot-bypass"},{"level":1,"text":"Sample Preparation","id":"sample-preparation-2"},{"level":2,"text":"Die Exposure","id":"die-exposure"},{"level":2,"text":"Main Carrier Board","id":"main-carrier-board"},{"level":2,"text":"I/O Board","id":"i-o-board"},{"level":2,"text":"Ground Connection Repair","id":"ground-connection-repair"},{"level":2,"text":"Limitations","id":"limitations"},{"level":1,"text":"Laser Fault Injection Platform","id":"laser-fault-injection-platform"},{"level":2,"text":"Platform Overview","id":"platform-overview"},{"level":2,"text":"Positioning Stage","id":"positioning-stage"},{"level":2,"text":"Optical Subsystem","id":"optical-subsystem"},{"level":3,"text":"The Necessity of Using Infrared Light","id":"the-necessity-of-using-infrared-light"},{"level":3,"text":"Optical Components","id":"optical-components"},{"level":3,"text":"Optical Paths","id":"optical-paths"},{"level":3,"text":"Imaging Results","id":"imaging-results"},{"level":3,"text":"Laser Focusing Results","id":"laser-focusing-results"},{"level":1,"text":"Laser Driving","id":"laser-driving"},{"level":2,"text":"Board Architecture","id":"board-architecture"},{"level":2,"text":"Pulse Generation Principle","id":"pulse-generation-principle"},{"level":2,"text":"Laser Diode Sourcing","id":"laser-diode-sourcing"},{"level":1,"text":"Fault Injection Results","id":"fault-injection-results"},{"level":2,"text":"Identification of Sensitive Areas","id":"identification-of-sensitive-areas"},{"level":2,"text":"Targeting for Secure Boot Bypass","id":"targeting-for-secure-boot-bypass"},{"level":1,"text":"Secure Boot Feature Bypass","id":"secure-boot-feature-bypass"},{"level":2,"text":"Constraints","id":"constraints"},{"level":2,"text":"Boot ROM Analysis Method","id":"boot-rom-analysis-method"},{"level":2,"text":"High-Level Idea","id":"high-level-idea"},{"level":2,"text":"Fault Injection Scenarios","id":"fault-injection-scenarios"},{"level":3,"text":"Scenario #1 - Single Instruction “Skip”","id":"scenario-1-single-instruction-skip"},{"level":3,"text":"Scenario #2 - Register Value Corruption","id":"scenario-2-register-value-corruption"},{"level":3,"text":"Scenario #3 - Instruction Mutation","id":"scenario-3-instruction-mutation"},{"level":2,"text":"Attack Process","id":"attack-process"},{"level":3,"text":"Software Architecture","id":"software-architecture"},{"level":3,"text":"Laser Pulse Synchronization","id":"laser-pulse-synchronization"},{"level":3,"text":"Flash Memory Organization","id":"flash-memory-organization"},{"level":3,"text":"Attack Loop","id":"attack-loop"},{"level":2,"text":"Results","id":"results"},{"level":2,"text":"Possible Improvements","id":"possible-improvements"},{"level":1,"text":"Conclusion","id":"conclusion"},{"level":2,"text":"Disclosure","id":"disclosure"},{"level":2,"text":"Bibliography","id":"bibliography"}]}}