{
  "finding_id": "DF-3564",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "none",
  "confidence": "certain",
  "verdict": "SipHash_SetKey (sys/crypto/siphash/siphash.c:69-85) leaves a verbatim 16-byte copy of the callers key in stack local k[2] (line 71) after returning, while the rest of the file wipes even the derived context state (SipHash_End bzero, line 188). Demonstrated in a same-source userland build of the exact audited file: the raw key bytes are found on the dead stack at offset -112 below the caller frame. WireGuard computes SipHash with long-term secret keys on the network-reachable handshake path (wg_noise.c:457,498; wg_cookie.c:136), so the residue appears at attacker-driven rates on kernel thread stacks. No standalone disclosure path exists in-tree, so impact is hardening-only (any future kernel-stack info leak would harvest it); one-line explicit_bzero eliminates it with no behavior change (KAT suite 2111/2111 before and after).",
  "exploit_chain": "",
  "evidence": "run.log lines under ############ sip_keyscan (DF-3564) ############: RETAINED: verbatim 16-byte key found on the dead stack, offset -112 below caller frame. fix_run.log: patched copy -> NOT FOUND + RESULT: PASS: 2111 checks, 0 failures. Scanning is call-free (inline byte loop) so the probe cannot clobber the dead frame.",
  "kernel_refs": [
    "sys/crypto/siphash/siphash.c:71",
    "sys/crypto/siphash/siphash.c:79",
    "sys/crypto/siphash/siphash.c:188",
    "sys/net/wg/wg_noise.c:240",
    "sys/net/wg/wg_noise.c:457",
    "sys/net/wg/wg_cookie.c:136"
  ],
  "poc_changes": "Initial seed sketch upgraded: (1) the naive memcmp(3)-based stack scan self-clobbered the dead SetKey frame (libc call frame landed on it) and always reported NOT FOUND; replaced with an inline call-free byte-compare loop which finds the key at offset -112. (2) scan window reduced to 32KB to stay inside the main-thread stack mapping. (3) correctness harness sip_kat.c written from scratch: 64 in-tree official vectors + independent from-paper reference for both SipHash-2-4 and the wg SipHash-1-3 variant + chunked-update equivalence.",
  "attempts": 3,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026     root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64",
  "runtime_sec": 412,
  "guest_dirty": 0,
  "build_cmd": "cd findings/poc/DF-3564 && ./build.sh",
  "run_cmd": "cd findings/poc/DF-3564 && ./run.sh",
  "code_hash": "f4a4bb20fb0bb81b95be4bc6dc928435c517e259156ab9c273f754777d22edb3",
  "notes": "Batch context: pass-2 audit of four crypto primitives; sha1 1859/0, siphash 2111/0, des 8916/0, blake2s 6878/0 KAT checks all PASS in the same run.log (guest /usr/src byte-identical to audited tree, hashes in env.txt). Guest left clean (no kernel changes; userland scratch only).",
  "recommended_fix": "Add explicit_bzero(k, sizeof(k)) after the last XOR use of k in SipHash_SetKey (see fix.diff).",
  "fix_status": "fixed",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "One-line explicit_bzero(k, sizeof(k)) in SipHash_SetKey. Baseline: verbatim key found on dead stack at -112. Patched copy of the same source: NOT FOUND (residue eliminated). Full SipHash KAT suite on the patched copy: 2111/2111 PASS, so hashing behavior is unchanged.",
  "fix_evidence": "fix_run.log: === DF-3564 fix validation === -> NOT FOUND ... exit=1 (1 = retention GONE = fix effective) and RESULT: PASS: 2111 checks, 0 failures.",
  "fix_kernel_uname": "DragonFly dfbsd 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026 (userland same-source validation; kernel unchanged)"
}