DF-3569 / verdict.json
{ "finding_id": "DF-3569", "status": "reproduced", "reproduced": 1, "impact": "none", "confidence": "certain", "verdict": "camellia_set_key (camellia-api.c:36-42) is a void wrapper that passes `bits` to Camellia_Ekeygen unvalidated and stores ctx->bits unconditionally; the only guard is the KASSERT at camellia.c:1253-1254, compiled out on production kernels. Demonstrated in-guest with the real kernel sources built userland (-DNDEBUG == production semantics, per camellia.c:40-43s KASSERT->assert mapping): for bits in {64,0,-1,129} nothing traps, ctx->bits records the invalid length, the 0xA5A5A5A5 schedule sentinel survives intact (schedule NEVER generated), and camellia_encrypt copies the 16-byte block unchanged - encryption degenerates to the identity function (BUG-CONFIRMED, exit 42). Debug build aborts at camellia.c:1254, proving the guard is INVARIANTS-only. Unlike the rijndael twin DF-3568 there is NO memory-safety violation - the default paths read neither key nor schedule - the failure is purely cryptographic (silent plaintext pass-through). RFC 3713 Appendix A KATs for 128/192/256 pass and a canary after subkey[68] proves schedule writes stay in bounds (ctx-layout interplay clean). Impact is none today: zero in-tree consumers (only conf/files:2259 and crypto/Makefile:20 reference camellia outside the directory); the code ships as dead code in option-crypto kernels and crypto.ko. Filed Info hardening of the API contract for future callers, matching the DF-3560/DF-3568 batch precedent.", "exploit_chain": "", "evidence": "run.log: ciphertext0123456789abcdeffedcba9876543210 == plaintext, schedule : UNTOUCHED -- never generated, BUG-CONFIRMED ... exit=42, and dbg Assertion failed ... camellia.c, line 1254. exit=134; fixval.log: RESULT-PASS: 0 failures + REJECTED (ctx untouched, encrypt refused) + BUG-NOT-PRESENT ... exit=0", "kernel_refs": [ "sys/crypto/camellia/camellia-api.c:36", "sys/crypto/camellia/camellia-api.c:40", "sys/crypto/camellia/camellia-api.c:41", "sys/crypto/camellia/camellia-api.c:48", "sys/crypto/camellia/camellia-api.c:55", "sys/crypto/camellia/camellia.h:41", "sys/crypto/camellia/camellia.c:1253", "sys/crypto/camellia/camellia.c:1266", "sys/conf/files:2259", "sys/crypto/Makefile:20" ], "poc_changes": "No seed PoC existed; authored guard_cam_badbits.c (kat + guard modes). Guest /bin/sh truncates long command lines (no base64(1) either) - file transfer switched to scp with vm.shs ssh config.", "attempts": 2, "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": 300, "guest_dirty": 0, "build_cmd": "cc -O2 -DNDEBUG -I /usr/src/sys -o guard_prod guard_cam_badbits.c /usr/src/sys/crypto/camellia/camellia-api.c /usr/src/sys/crypto/camellia/camellia.c (+ guard_dbg w/o -DNDEBUG, + guard_fix from fix.diff-patched copy; see build.sh)", "run_cmd": "./guard_prod kat; ./guard_prod guard; ./guard_dbg guard; ./guard_fix kat; ./guard_fix guard # expect 0 / BUG-CONFIRMED-42 / assert-abort-134 / 0 / BUG-NOT-PRESENT-0", "code_hash": "d3b7dd87fc96fdfd5159297d2ada009f538bf17fce3518bd180d16b890050005", "notes": "Info hardening per batch precedent - full guest Phase V not contractually required for Info, but the same-source in-guest demonstration and harness-level fix validation were cheap and strengthen the claim (matches DF-3568 treatment). Guest /usr/src cksum-matched to the audited tree (env.txt). Guest left clean (harness tree removed; no kernel change, no panic). camellia.c-side unzeroed-schedule residue is DF-3560s claim and is NOT re-reported here.", "recommended_fix": "camellia-api.c: have camellia_set_key return int and reject bits not in {128,192,256} before touching key material or ctx; camellia_encrypt/decrypt refuse invalid ctx->bits leaving dst untouched (see fix.diff).", "fix_status": "fixed", "fix_baseline_reproduced": 1, "fix_patched_reproduced": 0, "fix_verdict": "fix.diff applied to a pristine source copy on the guest (both hunks OK, patch output in build.log) and rebuilt with -DNDEBUG: invalid lengths are rejected before any key access (ctx marker preserved, schedule sentinel intact) and encrypt refuses leaving dst untouched (BUG-NOT-PRESENT, exit 0), while RFC 3713 128/192/256 KATs still pass (RESULT-PASS: 0 failures). Harness-level validation only (no kernel build) - justified because no in-tree caller can deliver an invalid length today.", "fix_evidence": "fixval.log: bits=64 : REJECTED (ctx untouched, encrypt refused) ... BUG-NOT-PRESENT ... exit=0 and === [4] FIXED build KAT === ... RESULT-PASS: 0 failures" } |