From 92777efd3064ac6d4b89c8e95baca021b86e581c Mon Sep 17 00:00:00 2001 From: FallenSigh Date: Tue, 30 Jun 2026 02:00:50 +0800 Subject: [PATCH] fix: drive dbg_dk_idx_i only during full-dk readback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The core's ek_rd_addr/dkp_rd_addr muxes give dbg_dk_idx_i priority over dbg_byte_idx_i whenever it falls in the ek (768..1567) or dk_pke (<768) region. The wrapper drove both dbg_byte_idx_i and dbg_dk_idx_i from the same rdb_addr, so an ek readback of the rho tail (bytes 768..799) was hijacked to read ek[0..31] instead — corrupting the public key fed to Encaps and causing Decaps implicit rejection (full 32-byte ss mismatch). Present rdb_addr on dbg_dk_idx_i only when rdb_sel==2 (full-dk); hold it at 0xFFF otherwise so ek/dk_pke readbacks aren't corrupted. Verified by KeyGen->Encaps->Decaps round trip (MLKEM_RESULT=PASS). --- rtl/ip/mlkem/top/mlkem_axi_slave.v | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/rtl/ip/mlkem/top/mlkem_axi_slave.v b/rtl/ip/mlkem/top/mlkem_axi_slave.v index b58d407..e5c2363 100644 --- a/rtl/ip/mlkem/top/mlkem_axi_slave.v +++ b/rtl/ip/mlkem/top/mlkem_axi_slave.v @@ -191,6 +191,12 @@ module mlkem_axi_slave ( wire [7:0] dbg_byte_o, dbg_dk_o, dbg_ct_o; wire [255:0] ss_o; wire dbg_byte_sel = (rdb_sel == 2'd1); // 0=ek, 1=dk_pke + // The core's ek/dkp read-address muxes give dbg_dk_idx_i priority over + // dbg_byte_idx_i whenever it lands in the ek (768..1567) or dk_pke (<768) + // region (mlkem_top: ek_rd_addr / dkp_rd_addr). So only drive dbg_dk_idx_i + // with the real index during a full-dk readback (rdb_sel==2); otherwise hold + // it out of range (0xFFF) so an ek/dk_pke readback isn't corrupted. + wire [11:0] dbg_dk_idx = (rdb_sel == 2'd2) ? rdb_addr : 12'hFFF; // one-cycle write-enable pulses into the core (combinational off the synced // edge; pre_sel_l/pre_addr_l/pre_byte_l are stable in sys, sampled by core). @@ -235,7 +241,7 @@ module mlkem_axi_slave ( .dbg_byte_idx_i (rdb_addr[10:0]), .dbg_byte_o (dbg_byte_o), // full-dk byte readback - .dbg_dk_idx_i (rdb_addr), + .dbg_dk_idx_i (dbg_dk_idx), .dbg_dk_o (dbg_dk_o), // remaining debug taps unused .dbg_rho_o (/* unused */),