]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
More robust iso14443a sniffing/simulation functions by
authormicki.held@gmx.de <micki.held@gmx.de@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Sun, 23 Feb 2014 15:46:19 +0000 (15:46 +0000)
committermicki.held@gmx.de <micki.held@gmx.de@ef4ab9da-24cd-11de-8aaa-f3a34680c41f>
Sun, 23 Feb 2014 15:46:19 +0000 (15:46 +0000)
- iso14443a.c: less strict Miller/Manchester decoders
- FPGA hi_iso14443a.v: syncing on external readers' clock when simulating and sniffing.

armsrc/iso14443a.c
fpga/fpga.bit
fpga/hi_iso14443a.v

index ca888295a7c04c02ff5091d8a0bf98462f3d24df..b105e792d3af7f5d4ca7e672a378912764af7b1e 100644 (file)
@@ -236,6 +236,15 @@ bool RAMFUNC LogTrace(const uint8_t * btBytes, uint8_t iLen, uint32_t timestamp,
 //-----------------------------------------------------------------------------
 static tUart Uart;
 
+// Lookup-Table to decide if 4 raw bits are a modulation.
+// We accept two or three consecutive "0" in any position with the rest "1"
+const bool Mod_Miller_LUT[] = {
+       TRUE,  TRUE,  FALSE, TRUE,  FALSE, FALSE, FALSE, FALSE,
+       TRUE,  TRUE,  FALSE, FALSE, TRUE,  FALSE, FALSE, FALSE
+};
+#define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x00F0) >> 4])
+#define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x000F)])
+
 void UartReset()
 {
        Uart.state = STATE_UNSYNCD;
@@ -249,7 +258,7 @@ void UartReset()
        Uart.endTime = 0;
 }
 
-inline RAMFUNC Modulation_t MillerModulation(uint8_t b)
+/* inline RAMFUNC Modulation_t MillerModulation(uint8_t b)
 {
        // switch (b & 0x88) {
                // case 0x00:   return MILLER_MOD_BOTH_HALVES;
@@ -265,7 +274,7 @@ inline RAMFUNC Modulation_t MillerModulation(uint8_t b)
                default:        return MOD_NOMOD;
        }
 }
-
+ */
 // use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time
 static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
 {
@@ -293,14 +302,18 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
                        if (Uart.syncBit != 0xFFFF) {
                                Uart.startTime = non_real_time?non_real_time:(GetCountSspClk() & 0xfffffff8);
                                Uart.startTime -= Uart.syncBit;
+                               Uart.endTime = Uart.startTime;
                                Uart.state = STATE_START_OF_COMMUNICATION;
                        }
                }
 
        } else {
 
-               switch (MillerModulation(Uart.twoBits >> Uart.syncBit)) {
-                       case MOD_FIRST_HALF:                                                                                            // Sequence Z = 0
+               if (IsMillerModulationNibble1(Uart.twoBits >> Uart.syncBit)) {                  
+                       if (IsMillerModulationNibble2(Uart.twoBits >> Uart.syncBit)) {          // Modulation in both halves - error
+                               UartReset();
+                               Uart.highCnt = 6;
+                       } else {                                                                                                                        // Modulation in first half = Sequence Z = logic "0"
                                if (Uart.state == STATE_MILLER_X) {                                                             // error - must not follow after X
                                        UartReset();
                                        Uart.highCnt = 6;
@@ -317,8 +330,9 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
                                                Uart.shiftReg = 0;
                                        }
                                }
-                               break;
-                       case MOD_SECOND_HALF:                                                                                           // Sequence X = 1
+                       }
+               } else {
+                       if (IsMillerModulationNibble2(Uart.twoBits >> Uart.syncBit)) {          // Modulation second half = Sequence X = logic "1"
                                Uart.bitCount++;
                                Uart.shiftReg = (Uart.shiftReg >> 1) | 0x100;                                   // add a 1 to the shiftreg
                                Uart.state = STATE_MILLER_X;
@@ -330,15 +344,14 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
                                        Uart.bitCount = 0;
                                        Uart.shiftReg = 0;
                                }
-                               break;
-                       case MOD_NOMOD:                                                                                                         // no modulation in both halves - Sequence Y
+                       } else {                                                                                                                        // no modulation in both halves - Sequence Y
                                if (Uart.state == STATE_MILLER_Z || Uart.state == STATE_MILLER_Y) {     // Y after logic "0" - End of Communication
                                        Uart.state = STATE_UNSYNCD;
                                        if(Uart.len == 0 && Uart.bitCount > 0) {                                                                                // if we decoded some bits
                                                Uart.shiftReg >>= (9 - Uart.bitCount);                                  // add them to the output
                                                Uart.output[Uart.len++] = (Uart.shiftReg & 0xff);
                                                Uart.parityBits <<= 1;                                                                  // no parity bit - add "0"
-                                               Uart.bitCount--;                                                                                        // last "0" was part of the EOC sequence
+                                               Uart.bitCount--;                                                                                // last "0" was part of the EOC sequence
                                        }
                                        return TRUE;
                                }
@@ -357,11 +370,7 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
                                                Uart.shiftReg = 0;
                                        }
                                }
-                               break;
-                       case MOD_BOTH_HALVES:                                                                                           // Error
-                               UartReset();
-                               Uart.highCnt = 6;
-                               return FALSE;
+                       }
                }
                        
        } 
@@ -388,9 +397,11 @@ static RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
 // Note 2: parameter offset is used to determine the position of the parity bits (required for the anticollision command only)
 static tDemod Demod;
 
+// Lookup-Table to decide if 4 raw bits are a modulation.
+// We accept three or four consecutive "1" in any position
 const bool Mod_Manchester_LUT[] = {
-       FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE,
-       FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE
+       FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE,
+       FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE,  TRUE
 };
 
 #define IsManchesterModulationNibble1(b) (Mod_Manchester_LUT[(b & 0x00F0) >> 4])
@@ -434,7 +445,7 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non
                        else if ((Demod.twoBits & 0x03B8) == 0x0380) Demod.syncBit = 2;
                        else if ((Demod.twoBits & 0x01DC) == 0x01C0) Demod.syncBit = 1;
                        else if ((Demod.twoBits & 0x00EE) == 0x00E0) Demod.syncBit = 0;
-                       if (Demod.syncBit < 8) {
+                       if (Demod.syncBit != 0xFFFF) {
                                Demod.startTime = non_real_time?non_real_time:(GetCountSspClk() & 0xfffffff8);
                                Demod.startTime -= Demod.syncBit;
                                Demod.bitCount = offset;                        // number of decoded data bits
@@ -473,15 +484,17 @@ static RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non
                                }
                                Demod.endTime = Demod.startTime + 8*(9*Demod.len + Demod.bitCount + 1);
                        } else {                                                                                                        // no modulation in both halves - End of communication
-                               if(Demod.bitCount > 0) {                                                                // if we decoded bits
-                                       Demod.shiftReg >>= (9 - Demod.bitCount);                        // add the remaining decoded bits to the output
-                                       Demod.output[Demod.len++] = Demod.shiftReg & 0xff;
-                                       // No parity bit, so just shift a 0
-                                       Demod.parityBits <<= 1;
+                               if (Demod.len > 0 || Demod.bitCount > 0) {                              // received something
+                                       if(Demod.bitCount > 0) {                                                        // if we decoded bits
+                                               Demod.shiftReg >>= (9 - Demod.bitCount);                // add the remaining decoded bits to the output
+                                               Demod.output[Demod.len++] = Demod.shiftReg & 0xff;
+                                               // No parity bit, so just shift a 0
+                                               Demod.parityBits <<= 1;
+                                       }
+                                       return TRUE;                                                                            // we are finished with decoding the raw data sequence
+                               } else {                                                                                                // nothing received. Start over
+                                       DemodReset();
                                }
-                               Demod.state = DEMOD_UNSYNCD;                                                    // start from the beginning
-                               Demod.twoBits = 0;
-                               return TRUE;                                                                                    // we are finished with decoding the raw data sequence
                        }
                }
                        
index 97cdd23362dfe38359dd9066c57ad5b893fb225a..55dbfb8c361b8fcb54e3cdc3991e71cd88d0ff0d 100644 (file)
Binary files a/fpga/fpga.bit and b/fpga/fpga.bit differ
index 0f7325b681a920baba0f54f40dd30b7f408d7bc6..1ad485dd91c26542b3d45d92f64a5bdeb996c75e 100644 (file)
@@ -35,7 +35,7 @@ reg ssp_frame;
 wire adc_clk;
 assign adc_clk = ck_1356meg;
 
-reg after_hysteresis, after_hysteresis_prev1, after_hysteresis_prev2, after_hysteresis_prev3, after_hysteresis_prev4;
+reg after_hysteresis, pre_after_hysteresis, after_hysteresis_prev1, after_hysteresis_prev2, after_hysteresis_prev3, after_hysteresis_prev4;
 reg [11:0] has_been_low_for;
 reg [8:0] saw_deep_modulation;
 reg [2:0] deep_counter;
@@ -45,6 +45,8 @@ always @(negedge adc_clk)
 begin
        if(& adc_d[7:6]) after_hysteresis <= 1'b1;                      // adc_d >= 196 (U >= 3,28V) -> after_hysteris = 1
     else if(~(| adc_d[7:4])) after_hysteresis <= 1'b0;  // if adc_d <= 15 (U <= 1,13V) -> after_hysteresis = 0
+
+       pre_after_hysteresis <= after_hysteresis;
        
        if(~(| adc_d[7:0]))                                                                     // if adc_d == 0 (U <= 0,94V)
        begin
@@ -122,6 +124,7 @@ reg mod_sig, mod_sig_coil;
 reg temp_buffer_reset;
 reg sendbit;
 reg [3:0] sub_carrier_cnt;
+reg[3:0] reader_falling_edge_time;
 
 // ADC data appears on the rising edge, so sample it on the falling edge
 always @(negedge adc_clk)
@@ -244,13 +247,42 @@ begin
                        sendbit = 1'b0;
        end
 
+
+
+       // check timing of a falling edge in reader signal
+       if (pre_after_hysteresis && ~after_hysteresis)
+               reader_falling_edge_time[3:0] <= negedge_cnt[3:0];
+       else
+               reader_falling_edge_time[3:0] <= 4'd8;
+
+
+
+       // sync clock to external reader's clock:
+       if (negedge_cnt[3:0] == 4'd13 && (mod_type == `SNIFFER || mod_type == `TAGSIM_MOD || mod_type == `TAGSIM_LISTEN))
+       begin
+               // adjust clock if necessary:
+               if (reader_falling_edge_time < 4'd8 && reader_falling_edge_time > 4'd1)
+               begin
+                       negedge_cnt <= negedge_cnt;                             // freeze time
+               end     
+               else if (reader_falling_edge_time == 4'd8)
+               begin
+                       negedge_cnt <= negedge_cnt + 1;                 // the desired state. Advance as usual;
+               end
+               else
+               begin
+                       negedge_cnt[3:0] <= 4'd15;                              // time warp
+               end
+               reader_falling_edge_time <= 4'd8;                       // only once per detected rising edge
+       end
+       
+
+
        //------------------------------------------------------------------------------------------------------------------------------------------
        // Prepare 8 Bits to communicate to ARM
-
-       // in SNIFFER mode: 4 Bits data sniffed as Tag, 4 Bits data sniffed as Reader
-       if(mod_type == `SNIFFER)
+       if (negedge_cnt == 7'd63)
        begin
-               if (negedge_cnt == 7'd63)
+               if (mod_type == `SNIFFER)
                begin
                        if(deep_modulation) // a reader is sending (or there's no field at all)
                        begin
@@ -259,34 +291,32 @@ begin
                        else
                        begin
                                to_arm <= {after_hysteresis_prev1,after_hysteresis_prev2,after_hysteresis_prev3,after_hysteresis_prev4,bit1,bit2,bit3,bit4};
-                       end
+                       end                     
                        negedge_cnt <= 0;
                end
                else
                begin
                        negedge_cnt <= negedge_cnt + 1;
                end
-       end
-       else
-       // other modes: 8 Bits info on queue delay
+       end     
+       else if(negedge_cnt == 7'd127)
        begin
-               if(negedge_cnt == 7'd127)
+               if (mod_type == `TAGSIM_MOD)
                begin
-                       if (mod_type == `TAGSIM_MOD)
-                       begin
-                               to_arm[7:0] <= {mod_sig_ptr[4:0], mod_sig_flip[3:1]};
-                       end
-                       else
-                       begin
-                               to_arm[7:0] <= 8'd0;
-                       end
+                       to_arm[7:0] <= {mod_sig_ptr[4:0], mod_sig_flip[3:1]};
                        negedge_cnt <= 0;
                end
                else
                begin
-                               negedge_cnt <= negedge_cnt + 1;
+                       to_arm[7:0] <= 8'd0;
+                       negedge_cnt <= negedge_cnt + 1;
                end
        end
+       else
+       begin
+               negedge_cnt <= negedge_cnt + 1;
+       end
+
        
     if(negedge_cnt == 7'd1)
        begin
Impressum, Datenschutz