X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/4a3f1a379314368330fab879a616cf7b9e5e25c4..f4eadf8a50c4eed513fcb93b05c21ddadbddb2ed:/armsrc/lfops.c diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 7e53d4a5..0be81bc2 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -16,8 +16,7 @@ #include "string.h" #include "lfdemod.h" #include "lfsampling.h" -#include "usb_cdc.h" - +#include "usb_cdc.h" //test /** * Function to do a modulation and then get samples. @@ -214,6 +213,8 @@ void ReadTItag(void) } } + + void WriteTIbyte(uint8_t b) { int i = 0; @@ -310,11 +311,16 @@ void AcquireTiType(void) } } + + + // arguments: 64bit data split into 32bit idhi:idlo and optional 16bit crc // if crc provided, it will be written with the data verbatim (even if bogus) // if not provided a valid crc will be computed from the data and written. void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc) { + + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); if(crc == 0) { crc = update_crc16(crc, (idlo)&0xff); @@ -402,7 +408,7 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) for(;;) { //wait until SSC_CLK goes HIGH while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { - if(BUTTON_PRESS() || usb_poll()) { + if(BUTTON_PRESS() || (usb_poll_validate_length() )) { DbpString("Stopped"); return; } @@ -762,7 +768,7 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) // Configure to go in 125Khz listen mode LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS() && !usb_poll_validate_length()) { WDT_HIT(); if (ledcontrol) LED_A_ON(); @@ -841,6 +847,96 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) if (ledcontrol) LED_A_OFF(); } +// loop to get raw HID waveform then FSK demodulate the TAG ID from it +void CmdAWIDdemodFSK(int findone, int *high, int *low, int ledcontrol) +{ + uint8_t *dest = BigBuf_get_addr(); + //const size_t sizeOfBigBuff = BigBuf_max_traceLen(); + size_t size; + int idx=0; + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); + + while(!BUTTON_PRESS() && !usb_poll_validate_length()) { + + WDT_HIT(); + if (ledcontrol) LED_A_ON(); + + DoAcquisition_default(-1,true); + // FSK demodulator + //size = sizeOfBigBuff; //variable size will change after demod so re initialize it before use + size = 50*128*2; //big enough to catch 2 sequences of largest format + idx = AWIDdemodFSK(dest, &size); + + if (idx>0 && size==96){ + // Index map + // 0 10 20 30 40 50 60 + // | | | | | | | + // 01234567 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 - to 96 + // ----------------------------------------------------------------------------- + // 00000001 000 1 110 1 101 1 011 1 101 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1 + // premable bbb o bbb o bbw o fff o fff o ffc o ccc o ccc o ccc o ccc o ccc o wxx o xxx o xxx o - to 96 + // |---26 bit---| |-----117----||-------------142-------------| + // b = format bit len, o = odd parity of last 3 bits + // f = facility code, c = card number + // w = wiegand parity + // (26 bit format shown) + + //get raw ID before removing parities + uint32_t rawLo = bytebits_to_byte(dest+idx+64,32); + uint32_t rawHi = bytebits_to_byte(dest+idx+32,32); + uint32_t rawHi2 = bytebits_to_byte(dest+idx,32); + + size = removeParity(dest, idx+8, 4, 1, 88); + // ok valid card found! + + // Index map + // 0 10 20 30 40 50 60 + // | | | | | | | + // 01234567 8 90123456 7890123456789012 3 456789012345678901234567890123456 + // ----------------------------------------------------------------------------- + // 00011010 1 01110101 0000000010001110 1 000000000000000000000000000000000 + // bbbbbbbb w ffffffff cccccccccccccccc w xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + // |26 bit| |-117--| |-----142------| + // b = format bit len, o = odd parity of last 3 bits + // f = facility code, c = card number + // w = wiegand parity + // (26 bit format shown) + + uint32_t fc = 0; + uint32_t cardnum = 0; + uint32_t code1 = 0; + uint32_t code2 = 0; + uint8_t fmtLen = bytebits_to_byte(dest,8); + if (fmtLen==26){ + fc = bytebits_to_byte(dest+9, 8); + cardnum = bytebits_to_byte(dest+17, 16); + code1 = bytebits_to_byte(dest+8,fmtLen); + Dbprintf("AWID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo); + } else { + cardnum = bytebits_to_byte(dest+8+(fmtLen-17), 16); + if (fmtLen>32){ + code1 = bytebits_to_byte(dest+8,fmtLen-32); + code2 = bytebits_to_byte(dest+8+(fmtLen-32),32); + Dbprintf("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo); + } else{ + code1 = bytebits_to_byte(dest+8,fmtLen); + Dbprintf("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo); + } + } + if (findone){ + if (ledcontrol) LED_A_OFF(); + return; + } + // reset + } + idx = 0; + WDT_HIT(); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); +} + void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) { uint8_t *dest = BigBuf_get_addr(); @@ -852,7 +948,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) // Configure to go in 125Khz listen mode LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS() && !usb_poll_validate_length()) { WDT_HIT(); if (ledcontrol) LED_A_ON(); @@ -911,7 +1007,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) // Configure to go in 125Khz listen mode LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS() && !usb_poll_validate_length()) { WDT_HIT(); if (ledcontrol) LED_A_ON(); DoAcquisition_default(-1,true); @@ -989,6 +1085,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) #define T55x7_MODULATION_FSK2a 0x00007000 #define T55x7_MODULATION_MANCHESTER 0x00008000 #define T55x7_MODULATION_BIPHASE 0x00010000 +#define T55x7_MODULATION_DIPHASE 0x00018000 #define T55x7_BITRATE_RF_8 0 #define T55x7_BITRATE_RF_16 0x00040000 #define T55x7_BITRATE_RF_32 0x00080000 @@ -1030,7 +1127,9 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) #define WRITE_1 50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (or 56fc) 432 for T55x7; 448 for E5550 #define T55xx_SAMPLES_SIZE 12000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..) - +#define T55xx_READ_UPPER_THRESHOLD 128+40 // 50 +#define T55xx_READ_TOL 5 +//#define T55xx_READ_LOWER_THRESHOLD 128-40 //-50 // Write one bit to card void T55xxWriteBit(int bit) { @@ -1052,7 +1151,7 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod // Set up FPGA, 125kHz // Wait for config.. (192+8190xPOW)x8 == 67ms - LFSetupFPGAForADC(0, true); + LFSetupFPGAForADC(95, true); // Now start writting FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -1088,7 +1187,7 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod void TurnReadLFOn(){ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); // Give it a bit of time for the resonant antenna to settle. - SpinDelayUs(8*150); + SpinDelayUs(50*8); //155*8 } @@ -1100,13 +1199,26 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) uint16_t bufferlength = BigBuf_max_traceLen(); if ( bufferlength > T55xx_SAMPLES_SIZE ) bufferlength = T55xx_SAMPLES_SIZE; - + Block &= 0x7; //make sure block is at max 7 // Clear destination buffer before sending the command memset(dest, 0x80, bufferlength); // Set up FPGA, 125kHz // Wait for config.. (192+8190xPOW)x8 == 67ms - LFSetupFPGAForADC(0, true); + + LFSetupFPGAForADC(95, true); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); + + // Give it a bit of time for the resonant antenna to settle. + //SpinDelayUs(8*200); //192FC + SpinDelay(50); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelayUs(START_GAP); @@ -1128,16 +1240,34 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) TurnReadLFOn(); // Now do the acquisition i = 0; + bool startFound = false; + bool highFound = false; + uint8_t curSample = 0; + uint8_t firstSample = 0; for(;;) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { AT91C_BASE_SSC->SSC_THR = 0x43; LED_D_ON(); } if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; - LED_D_OFF(); - if (i >= bufferlength) break; + curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + + // find first high sample + if (!startFound && curSample > T55xx_READ_UPPER_THRESHOLD) { + if (curSample > firstSample) firstSample = curSample; + highFound = true; + } else if (!highFound) { + continue; + } + + // skip until samples begin to change + if (startFound || curSample < firstSample-T55xx_READ_TOL){ + if (!startFound) dest[i++] = firstSample; + startFound = true; + dest[i++] = curSample; + LED_D_OFF(); + if (i >= bufferlength) break; + } } } @@ -1170,17 +1300,34 @@ void T55xxReadTrace(void){ TurnReadLFOn(); // Now do the acquisition + bool startFound = false;// false; + bool highFound = false; + uint8_t curSample = 0; + uint8_t firstSample = 0; for(;;) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { AT91C_BASE_SSC->SSC_THR = 0x43; LED_D_ON(); } if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; - LED_D_OFF(); + curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + + // find first high sample + if (!startFound && curSample > T55xx_READ_UPPER_THRESHOLD) { + if (curSample > firstSample) firstSample = curSample; + highFound = true; + } else if (!highFound) { + continue; + } - if (i >= bufferlength) break; + // skip until samples begin to change + if (startFound || curSample < firstSample-T55xx_READ_TOL){ + if (!startFound) dest[i++] = firstSample; + startFound = true; + dest[i++] = curSample; + LED_D_OFF(); + if (i >= bufferlength) break; + } } } @@ -1486,271 +1633,6 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int } - -#define abs(x) ( ((x)<0) ? -(x) : (x) ) -#define max(x,y) ( x GraphBuffer[0]) { - while(i < GraphTraceLen) { - if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax) - break; - i++; - } - dir = 0; - } - else { - while(i < GraphTraceLen) { - if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin) - break; - i++; - } - dir = 1; - } - - lastval = i++; - half_switch = 0; - pmc = 0; - block_done = 0; - - for (bitidx = 0; i < GraphTraceLen; i++) - { - if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin)) - { - lc = i - lastval; - lastval = i; - - // Switch depending on lc length: - // Tolerance is 1/8 of clock rate (arbitrary) - if (abs(lc-clock/4) < tolerance) { - // 16T0 - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33+16)-1; - lastval = i; - pmc = 0; - block_done = 1; - } - else { - pmc = i; - } - } else if (abs(lc-clock/2) < tolerance) { - // 32TO - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33)-1; - lastval = i; - pmc = 0; - block_done = 1; - } - else if(half_switch == 1) { - BitStream[bitidx++] = 0; - half_switch = 0; - } - else - half_switch++; - } else if (abs(lc-clock) < tolerance) { - // 64TO - BitStream[bitidx++] = 1; - } else { - // Error - warnings++; - if (warnings > 10) - { - Dbprintf("Error: too many detection errors, aborting."); - return 0; - } - } - - if(block_done == 1) { - if(bitidx == 128) { - for(j=0; j<16; j++) { - Blocks[num_blocks][j] = 128*BitStream[j*8+7]+ - 64*BitStream[j*8+6]+ - 32*BitStream[j*8+5]+ - 16*BitStream[j*8+4]+ - 8*BitStream[j*8+3]+ - 4*BitStream[j*8+2]+ - 2*BitStream[j*8+1]+ - BitStream[j*8]; - } - num_blocks++; - } - bitidx = 0; - block_done = 0; - half_switch = 0; - } - if(i < GraphTraceLen) - { - if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0; - else dir = 1; - } - } - if(bitidx==255) - bitidx=0; - warnings = 0; - if(num_blocks == 4) break; - } - memcpy(outBlocks, Blocks, 16*num_blocks); - return num_blocks; -} - -int IsBlock0PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled - return 1; - if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ? - return 1; - return 0; -} - -int IsBlock1PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0) - if((Block[14] & 0x7f) <= 9 && Block[15] <= 9) - return 1; - - return 0; -} - -#define ALLOC 16 - -void ReadPCF7931() { - uint8_t Blocks[8][17]; - uint8_t tmpBlocks[4][16]; - int i, j, ind, ind2, n; - int num_blocks = 0; - int max_blocks = 8; - int ident = 0; - int error = 0; - int tries = 0; - - memset(Blocks, 0, 8*17*sizeof(uint8_t)); - - do { - memset(tmpBlocks, 0, 4*16*sizeof(uint8_t)); - n = DemodPCF7931((uint8_t**)tmpBlocks); - if(!n) - error++; - if(error==10 && num_blocks == 0) { - Dbprintf("Error, no tag or bad tag"); - return; - } - else if (tries==20 || error==10) { - Dbprintf("Error reading the tag"); - Dbprintf("Here is the partial content"); - goto end; - } - - for(i=0; i= 0; ind--,ind2--) { - if(ind2 < 0) - ind2 = max_blocks; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) { - if(ind2 > max_blocks) - ind2 = 0; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - } - } - } - } - } - tries++; - if (BUTTON_PRESS()) return; - } while (num_blocks != max_blocks); - end: - Dbprintf("-----------------------------------------"); - Dbprintf("Memory content:"); - Dbprintf("-----------------------------------------"); - for(i=0; i", i); - } - Dbprintf("-----------------------------------------"); - - return ; -} - - //----------------------------------- // EM4469 / EM4305 routines //-----------------------------------