Hack@CHES 2026 - Phase 1 Bug Submissions

Team KattangalSec

View on GitHub

Here we, KattangalSec, document the 17 bugs we managed to find for the challenge. We used a combination of methods for finding bugs. Initially, we relied on a fuzzing approach, trying to apply existing RISC-V based fuzzers and techniques, researching online via arXiv, and Connected Papers. Most of those attempts went in vain. However, we were able to find 3 bugs later on through fuzzing. We also modified Mjolnir and created Lightsaber and were able to be gather the majority of the bugs we have listed below.

Almost all of our work was done agentically, with us, the human, acting usually as a supervisor, and guiding the agent. Our preferred choice of harness was Hermes which acted as the principal orchestrator, documenting and writing exploits and testbenches. OpenCode was also used. We estimate our total AI related API costs to be less than $10 dollars, which was possible due to the generous limits of OpenCode’s Go subscription as well as AgentRouter’s promotional free offer granting $200 credits for GPT 5.6 Sol.

Bugs

  1. PMP error output always zero
  2. CTN access-range check overridden
  3. Key Manager source-key validity gate
  4. AES DPA masking forceable off
  5. Debug module auth hardwired to 1
  6. Lifecycle token compared on 32 bits
  7. LC transition check OR instead of AND
  8. LcStProd in two unique case branches
  9. AES output register reset bypass
  10. AES S-Box DOM counter fault, DFA key recovery
  11. KeyMgr EDN error path unconnected
  12. KeyMgr FSM illegal state silent recovery
  13. CSRNG unmasked AES (state leak)
  14. ROM controller single-bit digest compare
  15. Entropy Markov health test dead
  16. CSRNG key not zeroized after op
  17. OTBN URND reseed ignores EDN error

Note on testbenches

The module-level testbenches use the synthesizable stimulus-FSM + main_manual.cpp pattern (Verilator 4.210’s --main harness does not advance time, so the C++ harness toggles top-clk explicitly; reset is held 2 cycles, then the FSM runs to completion and prints the result):

verilator -Wno-fatal -Wno-WIDTH -Wno-UNUSED -Wno-IMPLICIT -Wno-CASEINCOMPLETE \
  -Wno-DECLFILENAME -Wno-PINMISSING -Wno-MODDUP -Wno-UNOPTFLAT -Wno-MULTIDRIVEN \
  --cc --exe --top-module tb +incdir+<ip>/rtl +incdir+... \
  <pkg/prim files in dependency order> <module>.sv <module>_tb.sv main_manual.cpp
make -C obj_dir -f Vtb.mk
./obj_dir/Vtb

Dependency notes: packages must precede modules (e.g. prim_util_pkg before prim_*); generated/abstract prims come from the fuseSoC/primgen build at hw/build.verilator_real/src/lowrisc_prim_abstract_*. All referenced RTL is the competition OpenTitan RTL at the given paths.