48ee413c9b
New protocols (from ProtoPirate): - Mazda V0: 433MHz, pair-based decoding, XOR deobfuscation - Mitsubishi V0: 868MHz, PWM, bit negation + XOR unscrambling - Porsche Touareg: 433/868MHz, sync preamble, 24-bit rotate cipher - Fiat V1 (Magneti Marelli BSI): 433MHz, auto-detected timing variants Protocol fixes aligned with ProtoPirate reference: - Kia V1: Fix Manchester level mapping (inverted convention), off-by-one bit count, CRC4 simplified to 7 bytes + offset 1 - Kia V2: Fix CRC byte layout (was double-counting nibbles), off-by-one bit count, preamble short-HIGH handling - Fiat V0: Fix endbyte transform (remove (<<1)|1), standard Manchester encoder (was differential), 7 btn bits (was 6), gap path fallback - PSA: Fix modified TEA (XTEA-like dynamic key selection), XOR decrypt byte mapping, critical key2_low construction bug, encoder polarity and preamble, add key1_high nibble validation, dual preamble patterns - Ford V0: Add calculate_checksum (sums all serial+count bytes) for encoder Kia V6 encoder ported: - Forward AES-128 (SubBytes, ShiftRows, MixColumns, encrypt) - encrypt_payload: build plaintext, AES encrypt, pack into 3 parts - Two-pass Manchester upload (640 + 38 preamble pairs) - fx_field extraction stored in DecodedSignal.extra for encode roundtrip Updated README, protocol docs, and version bump to 1.2.0.
2.4 KiB
2.4 KiB
layout
| layout |
|---|
| default |
Porsche Touareg Protocol
Rust module: src/protocols/porsche_touareg.rs
Reference: REFERENCES/ProtoPirate/protocols/porsche_touareg.c
Overview
Porsche Touareg uses PWM encoding with very long timing (1680/3370 us). 64-bit frame with a sync preamble (at least 15 sync pulses at 3370 us). Counter is recovered via brute-force using a 24-bit rotation cipher. Originally designed for the Porsche Cayenne.
Timing
| Parameter | Value | Notes |
|---|---|---|
| Short | 1680 us | +/-500 us |
| Long | 3370 us | +/-500 us |
| Sync | 3370 us | Same as long |
| Gap | 5930 us | +/-500 us |
| Sync min | 15 pulses | |
| Min bits | 64 |
PWM Bit Encoding
| Pair (LOW, HIGH) | Bit |
|---|---|
| Short LOW + Long HIGH | 0 |
| Long LOW + Short HIGH | 1 |
Frame Layout (64 bits = 8 bytes)
| Byte | Content |
|---|---|
| pkt[0] | (button << 4) | (frame_type & 0x07) |
| pkt[1] | serial bits [23:16] |
| pkt[2] | serial bits [15:8] |
| pkt[3] | serial bits [7:0] |
| pkt[4..7] | Encrypted counter/rolling code |
- Serial: 24 bits from pkt[1..3]
- Button: 4 bits (pkt[0] >> 4)
- Frame type: 3 bits (pkt[0] & 0x07): 0x02=First, 0x01=Cont, 0x04=Final
Counter Recovery (Brute-Force)
Counter is not in plaintext. The decoder tries counter values 1-256, calling compute_frame() for each, and checks if computed bytes [4..7] match received bytes [4..7].
Compute Frame Algorithm (24-bit Rotate Cipher)
- Initialize 24-bit rotate register from serial bytes: r_h=b3, r_m=b1, r_l=b2.
- ROTATE24: circular left shift across 3 bytes (h<-m, m<-l, l<-h).
- Rotate 4 times + counter_low more times.
- Compute encrypted bytes a9a/a9b/a9c from rotated values XOR'd with inverted counter bits.
- Assemble pkt[4..7] using bitfield packing.
Decoder Steps
- Reset -- Wait for LOW pulse matching sync (3370 us).
- Sync -- Count sync pulses (both HIGH and LOW). When count >= 15 and gap detected (5930 us), transition to GapHigh or GapLow.
- GapHigh -- Expect HIGH gap (5930 us); init data on match.
- GapLow -- Expect LOW gap (5930 us); init data on match.
- Data -- Decode bit pairs (LOW saved, HIGH completes). At 64 bits, parse data and brute-force counter.
Encoder
Not supported (decode-only).
Frequencies
433.92 MHz, 868.35 MHz.