ATSAM4C32
Contents
Bypassing Lock - Microchip/Atmel SAM4C32
Hash Salehi
Introduction
This write-up will cover analysis of the Microchip (ATMEL) SAM4C32 microcontroller vulnerability that allows an attacker to gain unlocked JTAG access to a previously locked device. This attack appears to affect many devices (though not all) in the SAM family. It was discovered that essentially the same attack performed by 0x01 Team on the SAM E70/S70/V70/V71 works on many SAM processors. What's novel about this write-up is identification of the Reset pin as a side channel.
While the attack method used was voltage fault injection, I believe EMFI (electromagnetic fault injection) could also be a viable method to bypass security. EMFI generally permits attacks without the need to remove all the capacitors on the power rail. This is helpful when attacking devices where you don't want to alter the target board.
Why attack the SAM4C32?
The SAM4C32 is used in this Landis+Gyr Generation 5 smart meter. I have a long history analyzing various aspects of these smart meters, previously extracting the firmware from a Generation 4 smart meter which uses a Renesas (Mitsubishi) M30626FHPGP processor. It is a M16C architecture and the extracted firmware proved challenging to reverse engineer with tools like Binary Ninja and Ghidra.
ARM architecture is supported by more RE (reverse engineering) tools and has been analyzed by more people in the RE community. Therefore, I decided to extract the firmware from the SAM4C32 to further my analysis of smart meter technology.
Locking Mechanism
The SAM4C32 makes use of general-purpose non-volatile memory (GPNVM) bits to control locking, boot mode and memory plane selection as seen below.
Below is extracted from Microchip datasheet DS60001717B.
Security Bit
The SAM4C features a security bit based on a specific General-purpose NVM bit (GPNVM bit 0). When the security is enabled, any access to the Flash, SRAM, core registers and internal peripherals, either through the SW-DP/JTAG-DP interface or through the Fast Flash Programming Interface, is forbidden. This ensures the confidentiality of the code programmed in the Flash.
This security bit can only be enabled through the command “Set General-purpose NVM Bit 0” of the EEFC User Interface. Disabling the security bit can only be achieved by asserting the ERASE pin at 1, and after a full Flash erase is performed. When the security bit is deactivated, all accesses to the Flash, SRAM, Core registers, Internal Peripherals are permitted.
SAM-BA Boot
The SAM-BA Boot is a default Boot Program for the master processor (CM4P0) which provides an easy way to program in-situ the onchip Flash memory. The SAM-BA Boot Assistant supports serial communication via the UART0 or USB Port for the SAM4C32.
The SAM-BA Boot provides an interface with SAM-BA Graphic User Interface (GUI).
The SAM-BA Boot is in ROM and is mapped in Flash at address 0x0 when GPNVM bit 1 is set to 0.
While my attack focused on targeting the security bit GPNVM 0, it may also be possible to target GPNVM1 to enter the boot-loader and extract the flash memory that way. In that case, a JTAG programmer would not be necessary. I have not tested to see if this works as of April 1, 2025.
Reset vs Power Cycle
Some microcontrollers in the SAM series exhibit different behavior on the VDDCORE power rail when they are reset vs power cycled. I have verified the SAM4C32, SAM4S2A and 0x01 Teams SAM E70/S70/V70/V71 all exhibit the behavior shown below. My hypothesis is any Microchip SAM series processor that mentions GPNVM in the datasheet is susceptible to this attack.
Reset Capture
This is my baseline for activity when the SAM4C32 is restarted. The purple reset trace (nRST) is toggled by an external device and we see the yellow VDDCORE activity that results as the chip boots up.
Power Cycle Capture
The following images are progressively zoomed in so you can see the activity of the reset line. The first image you can see all three lines going from low to high since we are applying power to the processor. The device controlling the reset line is set to a High-Z state so we can see what the processor is doing.
The first thing I noticed is the reset line being toggled by the processor itself shortly after power-up. This was not observed when only resetting the processor. I also noticed a significant power fluctuation on VDDCORE at the same time.
Zooming in closer we can see this clearly falls within the window of time the processor has asserted its reset line. This same fluctuation on power-up is identified by 0x01 Team in their vulnerability write-up.
Reset Pin as a Side Channel
The most interesting part of this attack was the discovery that the reset pin goes low for the window of time you should insert a glitch to bypass security!
This seems to be the case for all Microchip/ATMEL SAM chips mentioning GPNVM in their datasheets. I have only verified the SAM4C32, SAM4S2A, and E70/S70/V70/V71 exhibit this behavior however.
The time from power-up to reset asserting itself varies by chip. The SAM4C32 takes about 17mS while the SAM4S2A only takes 600uS.
The SAM E70/S70/V70/V71 takes about 1mS as seen below. Blue (3.3V), Red (VDDCORE), Green (Reset)
I should note that I only discovered this while setting up a different test trying to glitch the processor after resetting it. I like to watch the oscilloscope as I perform glitch attacks to see if any anomalies pop up that could inform future attacks. When I found 0x01 Team's research and realized I should be power cycling instead of resetting, the scope was already configured to monitor VDDCORE & Reset. The first time I power cycled the chip it was clear the reset line activity was correlated in some way with the voltage fluctuation on VDDCORE.
Voltage Fault Injection
The video below shows faults being injected into the VDDCORE supply approaching the voltage fluctuation. When it lands in the correct place on top of the fluctuation the process stops. It stops because JTAG was enabled on the processor and OpenOCD was able to connect halting the glitching script.
The triggered traces jump around so much because I am triggering on the rising edge of VCC 3.3V and this rising edge varies for reasons such as the capacitance of the chipwhisperer breakout board being used and the power supply itself.
The image below shows the aggressive glitch parameters used. This value was initially guessed and worked, narrower or wider glitches were not tested.
JTAG Access
OpenOCD in Ubuntu and an ATMEL-ICE programmer were used to connect to the SAM4C32. Microchip Studio IDE in a Windows VM was used to set the security bit, although this functionality appears to be available in OpenOCD I never tested it.
When the security bit is bypassed the following commands can be run, shown with their associated output
at91sam4 info
> at91sam4 info CKGR_MOR: [0x400e0420] -> 0x00000008 MOSCXTEN: 0 [0x0000] (main xtal enabled: NO) MOSCXTBY: 0 [0x0000] (main osc bypass: NO) MOSCRCEN: 1 [0x0001] (onchip RC-OSC enabled: YES) MOSCRCF: 0 [0x0000] (onchip RC-OSC freq: 4 MHz) MOSCXTST: 0 [0x0000] (startup clks, time= 0.000000 uSecs) MOSCSEL: 0 [0x0000] (mainosc source: internal RC) CFDEN: 0 [0x0000] (clock failure enabled: NO) CKGR_MCFR: [0x400e0424] -> 0x000107a0 MAINFRDY: 1 [0x0001] (main ready: YES) MAINF: 1952 [0x07a0] (3.998 Mhz (32.768khz slowclk) CKGR_PLLAR: [0x400e0428] -> 0x00003f00 DIVA: 0 [0x0000] MULA: 0 [0x0000] PLLA Freq: (Disabled,mula = 0) CKGR_UCKR: [0x400e041c] -> 0x00000000 PMC_FSMR: [0x400e0470] -> 0x00000000 PMC_FSPR: [0x400e0474] -> 0x00000000 PMC_IMR: [0x400e046c] -> 0x00000000 PMC_MCKR: [0x400e0430] -> 0x00000001 CSS: 1 [0x0001] mainosc (3.998 Mhz) PRES: 0 [0x0000] (selected clock) Result CPU Freq: 3.998 PMC_PCK0: [0x400e0440] -> 0x00000000 PMC_PCK1: [0x400e0444] -> 0x00000000 PMC_PCK2: [0x400e0448] -> 0x00000000 PMC_PCSR: [0x400e0418] -> 0x00000000 PMC_SCSR: [0x400e0408] -> 0x00000003 PMC_SR: [0x400e0468] -> 0x00030018 CHIPID_CIDR: [0x400e0740] -> 0xa64d0ee0 Version: 0 [0x0000] EPROC: 7 [0x0007] Cortex-M4 NVPSIZE: 14 [0x000e] 2048K bytes NVPSIZE2: 0 [0x0000] none SRAMSIZE: 13 [0x000d] 256K Bytes ARCH: 100 [0x0064] SAM4CxxC (100-pin version) NVPTYP: 2 [0x0002] embedded flash memory EXTID: 1 [0x0001] (exists: YES) CHIPID_EXID: [0x400e0744] -> 0x00000000 rc-osc: 4.000 MHz mainosc: 3.998 MHz plla: 0.000 MHz cpu-freq: 3.998 MHz mclk-freq: 3.998 MHz UniqueId: 0x20000c00 0x01006df3 0x010046af 0x010046b3
reg
> reg ===== arm v7m registers (0) r0 (/32): 0x00000000 (1) r1 (/32): 0x00000000 (2) r2 (/32): 0x00000000 (3) r3 (/32): 0x00000000 (4) r4 (/32): 0x00000000 (5) r5 (/32): 0x00000000 (6) r6 (/32): 0x00000000 (7) r7 (/32): 0x00000000 (8) r8 (/32): 0x00000000 (9) r9 (/32): 0x00000000 (10) r10 (/32): 0x00000000 (11) r11 (/32): 0x00000000 (12) r12 (/32): 0x00000000 (13) sp (/32): 0xffffffd8 (14) lr (/32): 0xfffffff9 (15) pc (/32): 0xfffffffe (16) xPSR (/32): 0x01000003 (17) msp (/32): 0xffffffd8 (18) psp (/32): 0x00000000 (20) primask (/1): 0x00 (21) basepri (/8): 0x00 (22) faultmask (/1): 0x00 (23) control (/3): 0x00 ===== Cortex-M DWT registers
at91sam4 gpnvm
Note below GPNVM bit 0 says its current value is 0 due to the glitch, if the processor is reset we lose access and it goes back to 1.
> at91sam4 gpnvm sam4-gpnvm0: 0 sam4-gpnvm1: 1 sam4-gpnvm2: 1
Other Vulnerable Devices
Microchip (ATMEL) families
This list is not exhaustive, there may be more that are vulnerable and do not show up in this main overview of devices provided by Microchip. Only the bold ones are confirmed, the others are assumed vulnerable because the datasheet specifies the use of GPNVM bits for security.
- SAM E70/S70/V70/V71
- SAM 4C
- SAM 4E
- SAM 4N
- SAM 4S
- SAM G51/G54/G55
- SAM 3X/3A
The following datasheets were reviewed and did not show the use of GPNVM bits for security protection. This does not mean they are secure, but this specific vulnerability may not be present.
- SAM 4L
- SAM L10/L11
- SAM L21/L22
- SAM C20/C21
- SAM D10/D11/D21/DA1/D5x/E5x/D20
Conclusion
Many devices in the Microchip (ATMEL) SAM Family make use of GPNVM bits to secure access to the JTAG debug interface. This protection can be bypassed using voltage glitching allowing full access to the device. It appears this is a low-level hardware bug, likely not patchable in the field.
Disclosure
Full disclosure at time of discovery via YouTube. Enjoy!