Show HN: Reverse-engineered the FPGA bitstream using Claude Code

hackernews | | 📦 오픈소스
#반도체 #altera #claude #cyclone iv #fpga #mistral #리버스 엔지니어링 #클로드 #하드웨어/반도체
원문 출처: hackernews · Genesis Park에서 요약 및 분석

요약

이 프로젝트는 인텔(구 알테라)의 사이클론 IV EP4CE6F17C8 칩에 대해 폐쇄적인 FPGA 비트스트림 포맷(.rbf)을 완전히 리버스 엔지니어링하는 것을 목표로 합니다. 기존 상용 도구인 쿼터터스(Quartus)에 대한 의존도를 낮추고 오픈소스 툴체인 구축을 가능하게 하기 위한 시도로, 6,272개의 로직 엘리먼트(LE)와 392개의 LAB을 포함하는 칩 내부 구조를 분석했습니다. 특히 기능이 아닌 특정 피쳐만 다른 두 설계의 비트스트림을 비교하여 원인을 규명하는 '페어-디프(Pair-diff)' 방식의 퍼징 기법을 핵심 알고리즘으로 활용했습니다. 이를 통해 특정 LUT의 진리표 제어 비트를 노이즈 없이 정확하게 추출해 내고 있으며, 궁극적으로 칩의 CRAM 구성 방식을 투명하게 파악할 수 있게 합니다.

본문

The goal of this project is to fully reverse-engineer the bitstream format of the Altera (now Intel) Cyclone IV FPGA chip EP4CE6F17C8. An FPGA (Field-Programmable Gate Array) is a chip that can be programmed to implement any digital circuit. Unlike a CPU, an FPGA does not execute "instructions" — instead, it physically "builds" a circuit at the hardware level. Think of it as a giant breadboard with thousands of programmable logic gates and interconnects; a configuration file decides how all those gates and wires connect. That "configuration file" is called a bitstream. For Altera chips, the specific format is .rbf (Raw Binary File). Commercial FPGA vendors (Intel/Altera, Xilinx/AMD) keep their bitstream formats proprietary. You must use their own tools (e.g., Quartus) to generate a bitstream. This means: - No open-source toolchain: You cannot use open-source synthesizers (like Yosys) or place-and-route tools (like NextPNR) to go all the way from Verilog to a bitstream. - No insight into chip internals: You don't know which part of the chip each bit in the bitstream controls. - Dependency on closed-source software: Quartus is free but not open-source, and only supports certain operating systems. Once we reverse-engineer the bitstream format we can: - Build a completely open-source FPGA toolchain for the EP4CE6 - Understand how the chip's CRAM (Configuration RAM) is organized internally - Directly read and write logic configuration and routing information in bitstream files | Project | Target chip | Method | Relation to this project | |---|---|---|---| | Project IceStorm | Lattice iCE40 | Black-box fuzzing | Identical methodology | | Project X-Ray | Xilinx 7-series | Vivado + specimen fuzzing | FASM format reference | | Project Mistral | Altera Cyclone V | quartus_cdb + Tcl | Same chip family — highest relevance | | Project Trellis | Lattice ECP5 | Diamond + fuzzing | Routing strategy reference | - Development board: Heijin AX301 - FPGA chip: EP4CE6F17C8 (Cyclone IV E series, 6,272 logic elements) - Programmer: USB-Blaster JTAG - Quartus Prime 21.1 Lite Edition: Intel's free FPGA development tool - Installation path: ~/intelFPGA_lite/21.1/quartus/bin/ - Command-line tools used: quartus_map (synthesis),quartus_fit (place & route),quartus_asm (generate .sof),quartus_cpf (convert to .rbf),quartus_sta (static timing analysis) - Installation path: - openFPGALoader: open-source FPGA programming tool (flashes bitstream to board); use $HOME/see_neorv32_run_linux/tools/openFPGALoader/build/openFPGALoader — the system version does not recognize the EP4CE6 IDCODE - Python 3: all fuzzing scripts are written in Python - SQLite: database for storing experiment results EP4CE6F17C8 internal layout (simplified): X=3 4 6 7 8 10 11 12 13 16 17 18 19 21 22 23 24 25 26 28 29 31 Y=21 [LAB][LAB][LAB][LAB][LAB][LAB]... [LAB] Y=19 [LAB][LAB][LAB][LAB][LAB][LAB]... [LAB] ... | | | | | | | Y=2 [LAB][LAB][LAB][LAB][LAB][LAB]... [LAB] ^ ^ ^ ^ X=5 X=9 X=14-15 X=20,27 M9K M9K DSP M9K RAM RAM Multiplier RAM - 392 LABs (Logic Array Blocks), each containing 16 LEs (Logic Elements) - LAB X coordinates: 22 values [3, 4, 6, 7, 8, 10, 11, 12, 13, 16, 17, 18, 19, 21, 22, 23, 24, 25, 26, 28, 29, 31] - Note that X is not contiguous! X=5, 9, 14, 15, 20, 27, 30 are occupied by M9K memory, DSP multipliers, or PLLs. - LAB Y coordinates: 18 values [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 21] - Y=15 and Y=20 do not exist ("ghost rows" in CRAM) - LE N index: 16 even values [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30] - Total: 392 × 16 = 6,272 LEs Each LE contains: - A 4-input lookup table (LUT4): can implement any 4-variable Boolean function - A D flip-flop (DFF): optionally used - Carry-chain logic (for arithmetic operations like addition) This is the core method of the entire reverse-engineering effort — simple yet powerful. If you want to know which bits in the bitstream control a specific feature, compile two designs that differ only in that feature, then compare their bitstreams. The differing bits are the ones that control that feature. Step 1: Compile a LUT with truth table set to all zeros (mask = 0x0000) → produces zero.rbf Step 2: Compile the same LUT at the same location with all ones (mask = 0xFFFF) → produces ones.rbf Step 3: Compare zero.rbf and ones.rbf bit by bit → the differences are the CRAM bits for this LE's truth table Because the two designs are identical in every way except the LUT's truth table — same routing, same I/O buffers, same global config. The differing bits can only be the truth-table encoding. | Method | What is compared | Effect | Noise | |---|---|---|---| | Design vs. empty | functional vs. non-functional | Finds all related bits | High (includes routing, etc.) | | Pair-diff | mask=0x0000 vs. mask=0xFFFF | Only finds LUT TT bits | Zero noise | | Multi-mask cross | multiple designs with different masks | Validates XOR-linear model | Zero | # rbf_diff.py — compare two RBF files def diff_r

Genesis Park 편집팀이 AI를 활용하여 작성한 분석입니다. 원문은 출처 링크를 통해 확인할 수 있습니다.

공유

관련 저널 읽기

전체 보기 →