v1.9.6: ETU lock validation, hunt recovery, resync + ATR acceptance

The audit's P1 robustness findings:

- _etu_candidate() validates a measured burst: requires >=2 usable
  spacings, rejects a guard-dominated burst (all-zero data: 10-ETU LOW
  runs + a 2-5 ETU HIGH guard) and a lone 10-ETU spacing.  A failed
  measurement leaves bit_samples unset instead of committing the
  clock_skip*3 fallback.
- _confirm_etu() no longer counts a dropped frame (empty bits) as
  parity-OK, and a rejected measurement clears bit_samples,
  _etu_measured and _clock_skip_confident (was: kept sampling at the
  rejected rate).
- Hunt ETU recovery keys off _etu_measured: handle_atr pre-seeds
  bit_samples, so the old "bit_samples is None" condition never fired.
- resync_idle() waits on the DATA idle level (plus RST/VCC edges,
  bounded) instead of spinning on wait({'skip': 0}) at one sample.
- ATR acceptance: a DATA-state 0x3B/0x3F is a candidate only before the
  first APDU (_apdu_seen); a parsed ATR is ignored on any parity error
  or when it is a bare TS+T0.  A data run misread at a frame boundary
  could fabricate an ATR and force clock_skip=372 for the capture.
- Inverse convention per ISO 7816-3 7.1/8.1: idle HIGH and a falling
  start bit in both conventions, msb-first inverse data, raw moments
  5-7 TS-pattern detection (a real inverse TS reads as 0x03 through
  the direct reader), and a TS parity exemption (the inverse pattern
  is odd over moments 2-10).  Spec-verified; no inverse capture in the
  corpus.

Validation: 117/117 unit tests (18 new); the 10-trace suite is
unchanged from v1.9.5 (APDU/CHKSUM/CONCAT/BAD_FCS identical,
RESULT: OK everywhere); compare_baseline.sh reports IDENTICAL.
VERSION -> 1.9.6.
This commit is contained in:
catarrh committed 2026-10-20 18:02:14 +03:00
1 parent b574f900a1
commit 3e39032802
6 files changed
+540 -85

No files matched your search

+3
View File
@@ -56,6 +56,9 @@ this decoder's `pcap_file=<path>` option).
| VCC tracking (optional) | `vcc_detect=true`: emits power on/off events (sub_type 0x11) |
| Direct PCAP file | `pcap_file=<path>` writes PCAP without shell redirection |
| Start-bit deglitch | 2-sample deglitch in the start-bit detector eliminates sub-ETU LOW glitches from FX2LP pull-up artifacts, preventing byte misalignment on fast phone traces |
| Mid-session ETU lock | The DATA-edge ETU estimator rejects guard-only (all-zero) and single-spacing bursts and invalidates a rate that fails parity, so a capture at a non-default F/D locks safely |
| ATR / resync guards | A DATA-state `0x3B`/`0x3F` is an ATR candidate only before the first APDU; parity-dirty or bare (TS+T0) frames are ignored, and `resync_idle` really waits for the idle level |
| Inverse convention | TS=0x3F ATRs follow ISO 7816-3 7.1: inverted data, msb first, start bit still LOW from an idle-HIGH line |
## Decoder options