Hack@CHES 2026 - Phase 1 Bug Submissions

Team KattangalSec

View on GitHub

Bug 10 - AES S-Box DOM Unhardened Stage Counter: Fault-Induced Stage Skipping - Full Key Recovery via DFA

Legacy reference: Bug #17 in the working set


Security feature bypassed

AES S-Box Domain-Oriented Masking (DOM) stage sequencing - the 5-stage masked-inversion schedule providing first-order DPA resistance

Attack type

Type 2 - physical attacker with fault injection capability

Finding

The entire five-cycle DOM schedule is governed by a plain 3-bit binary counter with no hardening whatsoever (no redundant encoding, Hamming-distance protection, parity, consistency check, or legal-transition validation, and no err_o output):

// aes_sbox_dom.sv:1050-1067
logic [2:0] count_d, count_q;
assign count_d = (out_req_o && out_ack_i) ? '0             :
                 out_req_o                ? count_q        :
                 en_i                     ? count_q + 3'd1 : count_q;

always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni)  count_q <= '0;
    else          count_q <= count_d;
  end

assign out_req_o = en_i & count_q == 3'd4;
assign we[0] = en_i & count_q == 3'd0;
assign we[1] = en_i & count_q == 3'd1;
assign we[2] = en_i & count_q == 3'd2;
assign we[3] = en_i & count_q == 3'd3;

Fault scenario 1 (skip all stages): a single-bit fault on count_q[2] flips 3'b000 - 3'b100; out_req_o asserts without executing any of the four inversion stages (we[0:3]). The unmasked S-Box output is consumed by the AES datapath.

Fault scenario 2 (skip/repeat stages): bit flips on count_q[1:0] skip or repeat individual we[] pulses, corrupting the masked computation order.

Location or code reference

New Tools

Yes - custom HWF-AFL pipeline. A minimal Verilator model replicated the counter logic with a fault_inject port; AFL mutated the fault value and discovered 0x40 (counter=3’d4) triggers immediate out_req_o with zero we[] stages completed. Crash in <10 s from a safe seed. Fault injection value 0x40 triggers the stage-skip; normal operation exits cleanly.

AI Tools

No.

LLM

No.

LLM Details

PLACEHOLDER - to be completed (model name/version, parameters, download link or API endpoint).

Online LLM Details

PLACEHOLDER - to be completed (input/output/total token counts, verification script).

LLM Prompts

PLACEHOLDER - to be completed (complete prompt, full model response, step-by-step explanation).

Detection method

Automated detection with the HWF-AFL pipeline (property: out_req_o must not fire before all four we[] stages complete - we_history != 4'b1111 - abort), then module-level FI confirmation on real RTL under VCS (fi17.v force of count_q - fault is SILENT, no error output), then full DFA key recovery on the real aes_cipher_core RTL (see below).

Security impact

Complete AES key extraction via Differential Fault Analysis. A single-bit flip on count_q[2] (~33% probability with an untargeted glitch, 1 of 3 counter bits) skips directly to output; the masked S-Box emits a faulty, unmasked value consumed by the AES datapath. 1-3 faulty ciphertexts suffice for full AES-128 key recovery (Piret-Quisquater DFA).

Full-chain proof on real RTL (VCS): fault injection on the real aes_cipher_core (counter stage-skip’s observable effect - one round-9 state byte forced to a known value) yields exactly-one-byte ciphertext faults; dfa_recover.py recovers the round-10 key from 256 faulted ciphertexts (16 positions × 4 values × 4 plaintexts) and the inverse key schedule recovers the master key exactly:

K10 (round-10 key) = 13111d7fe3944a17f307a78b4d2b30c5
master key        = 000102030405060708090a0b0c0d0e0f   - EXACT (FIPS-197 KAT key)
*** DFA SUCCESS: AES-128 MASTER KEY RECOVERED ***

See exploit/logs/dfa_run.log, run_good.log, run_fault5.log, fi17_run.log.

Adversary profile

Type 2 - physical attacker with fault injection equipment (ChipWhisperer-Lite ~$250, EM probe, or voltage glitcher), moderate knowledge of AES timing. Not exploitable via software alone - the counter is internal to the AES core.

Proposed mitigation

CVSSv3.1 score and severity

7.1 - HIGH

CVSSv3.1 Details

CVSS:3.1/AV:P/AC:H/PR:N/UI:N/S:C/C:H/I:N/A:N

Located in this repository (GitHub is the cloud storage for the submission):