ADD: @marshmellows "diphase" definition for T55x7.
MOV: extracted the aquisition from the t55x7 methods and put them inside lfsampling.c
FIX: pcf7931 write, there is 16bytes in a block.. not 4 as I thought before.
FIX: t55x7 lowered the WRITE_0 to 16. Even bigger gap.
cmd_send(CMD_ACK,0,0,0,0,0);
break;
case CMD_PCF7931_WRITE:
- WritePCF7931(c->d.asDwords[0],c->d.asDwords[1],c->d.asDwords[2],c->d.asDwords[3],c->d.asDwords[4],c->d.asDwords[5],c->d.asDwords[6], c->d.asDwords[9], c->d.asDwords[7]-128,c->d.asDwords[8]-128, c->arg[0], c->arg[1], c->arg[2]);
+ WritePCF7931(c->d.asBytes[0],c->d.asBytes[1],c->d.asBytes[2],c->d.asBytes[3],c->d.asBytes[4],c->d.asBytes[5],c->d.asBytes[6], c->d.asBytes[9], c->d.asBytes[7]-128,c->d.asBytes[8]-128, c->arg[0], c->arg[1], c->arg[2]);
break;
case CMD_EM4X_READ_WORD:
EM4xReadWord(c->arg[1], c->arg[2],c->d.asBytes[0]);
void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
void CopyViKingtoT55x7(uint32_t block1,uint32_t block2);
-/// pcf7931.h
-int DemodPCF7931(uint8_t **outBlocks);
-int IsBlock0PCF7931(uint8_t *Block);
-int IsBlock1PCF7931(uint8_t *Block);
-void ReadPCF7931();
-void SendCmdPCF7931(uint32_t * tab);
-bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p);
-bool AddBitPCF7931(bool b, uint32_t * tab, int32_t l, int32_t p);
-bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t * tab);
-void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data);
/// iso14443.h
void SimulateIso14443bTag(void);
#define T55x7_MODULATION_FSK2a 0x00007000
#define T55x7_MODULATION_MANCHESTER 0x00008000
#define T55x7_MODULATION_BIPHASE 0x00010000
+#define T55x7_MODULATION_DIPHASE 0x00018000
//#define T55x7_MODULATION_BIPHASE57 0x00011000
#define T55x7_BITRATE_RF_8 0
#define T55x7_BITRATE_RF_16 0x00040000
#define START_GAP 50*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (or 15fc)
#define WRITE_GAP 20*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (or 10fc)
-#define WRITE_0 18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (or 24fc)
+#define WRITE_0 16*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (or 24fc)
#define WRITE_1 50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (or 56fc) 432 for T55x7; 448 for E5550
// VALUES TAKEN FROM EM4x function: SendForward
// T0 = TIMER_CLOCK1 / 125000 = 192
// 1 Cycle = 8 microseconds(us)
-#define T55xx_SAMPLES_SIZE 12000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..)
// Write one bit to card
void T55xxWriteBit(int bit)
// 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);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
}
-void TurnReadLFOn(){
+void TurnReadLFOn(int delay){
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// Give it a bit of time for the resonant antenna to settle.
- SpinDelayUs(300);
+ SpinDelayUs(delay);
}
-
// Read one card block in page 0
void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
{
uint32_t i = 0;
- uint8_t *dest = BigBuf_get_addr();
- uint16_t bufferlength = BigBuf_max_traceLen();
- if ( bufferlength > T55xx_SAMPLES_SIZE )
- bufferlength = T55xx_SAMPLES_SIZE;
-
- // Clear destination buffer before sending the command
- memset(dest, 0x80, bufferlength);
+
+ //make sure block is at max 7
+ Block &= 0x7;
// Set up FPGA, 125kHz
- // Wait for config.. (192+8190xPOW)x8 == 67ms
- //LFSetupFPGAForADC(0, true);
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- 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);
+ LFSetupFPGAForADC(95, true);
+ // Trigger T55x7 in mode.
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- //SpinDelayUs(START_GAP);
-
- // Opcode
+ SpinDelayUs(START_GAP);
+
+ // Opcode 10
T55xxWriteBit(1);
T55xxWriteBit(0); //Page 0
+
if (PwdMode == 1){
// Pwd
for (i = 0x80000000; i != 0; i >>= 1)
T55xxWriteBit(Pwd & i);
}
- // Lock bit
+ // zero bit to seperate
T55xxWriteBit(0);
+
// Block
- for (i = 0x04; i != 0; i >>= 1)
+ for (i = 0x04; i != 0; i >>= 1) {
T55xxWriteBit(Block & i);
-
- // Turn field on to read the response
- TurnReadLFOn();
- // Now do the acquisition
- i = 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;
- }
+ Dbprintf("ice %d",i);
}
+ // Turn field on to read the response
+ TurnReadLFOn(START_GAP);
+
+ // Acquisition
+ doT55x7Acquisition();
+
+ // field off
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
cmd_send(CMD_ACK,0,0,0,0,0);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
}
+
// Read card traceability data (page 1)
void T55xxReadTrace(void){
- uint32_t i = 0;
- uint8_t *dest = BigBuf_get_addr();
- uint16_t bufferlength = BigBuf_max_traceLen();
- if ( bufferlength > T55xx_SAMPLES_SIZE )
- bufferlength= T55xx_SAMPLES_SIZE;
-
- // Clear destination buffer before sending the command
- memset(dest, 0x80, bufferlength);
-
LFSetupFPGAForADC(0, true);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelayUs(START_GAP);
- // Opcode
+ // Opcode 11
T55xxWriteBit(1);
T55xxWriteBit(1); //Page 1
// Turn field on to read the response
- TurnReadLFOn();
-
- // Now do the acquisition
- 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();
+ TurnReadLFOn(START_GAP);
- if (i >= bufferlength) break;
- }
- }
+ // Acquisition
+ doT55x7Acquisition();
+ // field off
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
cmd_send(CMD_ACK,0,0,0,0,0);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
}
+
/*-------------- Cloning routines -----------*/
// Copy HID id to card and setup block 0 config
void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT)
* @return number of bits sampled
**/
-uint32_t SnoopLF()
-{
+uint32_t SnoopLF() {
return ReadLF(false, true);
}
+
+/**
+* acquisition of T55x7 LF signal. Similart to other LF, but adjusted with @marshmellows thresholds
+* the data is collected in BigBuf.
+**/
+void doT55x7Acquisition(void){
+
+ #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
+
+ uint8_t *dest = BigBuf_get_addr();
+ uint16_t bufsize = BigBuf_max_traceLen();
+
+ if ( bufsize > T55xx_SAMPLES_SIZE )
+ bufsize = T55xx_SAMPLES_SIZE;
+
+ memset(dest, 0, bufsize);
+
+ uint16_t 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) {
+ 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 >= bufsize) break;
+ }
+ }
+ }
+}
\ No newline at end of file
#ifndef LFSAMPLING_H
#define LFSAMPLING_H
+/**
+* acquisition of T55x7 LF signal. Similart to other LF, but adjusted with @marshmellows thresholds
+* the data is collected in BigBuf.
+**/
+void doT55x7Acquisition(void);
+
/**
* Initializes the FPGA for reader-mode (field on), and acquires the samples.
* @return number of bits sampled
+#include "proxmark3.h"
+#include "apps.h"
+#include "lfsampling.h"
#include "pcf7931.h"
+#include "string.h"
#define T0_PCF 8 //period for the pcf7931 in us
#define ALLOC 16
#ifndef __PCF7931_H
#define __PCF7931_H
-#include "proxmark3.h"
-#include "apps.h"
-#include "lfsampling.h"
+int DemodPCF7931(uint8_t **outBlocks);
+int IsBlock0PCF7931(uint8_t *Block);
+int IsBlock1PCF7931(uint8_t *Block);
+void ReadPCF7931();
+void SendCmdPCF7931(uint32_t * tab);
+bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p);
+bool AddBitPCF7931(bool b, uint32_t * tab, int32_t l, int32_t p);
+bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t * tab);
+void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data);
#endif
\ No newline at end of file
PrintAndLog("Options:");
PrintAndLog(" h This help");
PrintAndLog(" blockaddress Block to save [0-7]");
- PrintAndLog(" byteaddress Index of byte inside block to write [0-3]");
+ PrintAndLog(" byteaddress Index of byte inside block to write [0-16]");
PrintAndLog(" data one byte of data (hex)");
PrintAndLog("Examples:");
PrintAndLog(" lf pcf7931 write 2 1 FF");
if ( param_getdec(Cmd, 0, &block) ) return usage_pcf7931_write();
if ( param_getdec(Cmd, 1, &bytepos) ) return usage_pcf7931_write();
- if ( (block > 7) || (bytepos > 3) ) return usage_pcf7931_write();
+ if ( (block > 7) || (bytepos > 16) ) return usage_pcf7931_write();
data = param_get8ex(Cmd, 2, 0, 16);
DemodBufferLen = 0x00;\r
\r
//trim 1/2 a clock from beginning\r
- snprintf(cmdStr, sizeof(buf),"%d", bitRate[config.bitrate]/2 );\r
- CmdLtrim(cmdStr);\r
+ //snprintf(cmdStr, sizeof(buf),"%d", bitRate[config.bitrate]/2 );\r
+ //CmdLtrim(cmdStr);\r
switch( config.modulation ){\r
case DEMOD_FSK:\r
snprintf(cmdStr, sizeof(buf),"%d %d", bitRate[config.bitrate], config.inverted );\r
\r
// detect configuration?\r
bool tryDetectModulation(){\r
- char cmdStr[8] = {0};\r
+ //char cmdStr[8] = {0};\r
uint8_t hits = 0;\r
t55xx_conf_block_t tests[15];\r
int bitRate=0;\r
save_restoreGB(1);\r
if (GetFskClock("", FALSE, FALSE)){ \r
fskClocks(&fc1, &fc2, &clk, FALSE);\r
- sprintf(cmdStr,"%d", clk/2);\r
- CmdLtrim(cmdStr);\r
+ //sprintf(cmdStr,"%d", clk/2);\r
+ //CmdLtrim(cmdStr);\r
if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate)){\r
tests[hits].modulation = DEMOD_FSK;\r
if (fc1==8 && fc2 == 5)\r
}\r
} else {\r
clk = GetAskClock("", FALSE, FALSE);\r
- \r
if (clk>0) {\r
- sprintf(cmdStr,"%d", clk/2);\r
- CmdLtrim(cmdStr);\r
+ //sprintf(cmdStr,"%d", clk/2);\r
+ //CmdLtrim(cmdStr);\r
if ( ASKDemod("0 0 0", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) {\r
tests[hits].modulation = DEMOD_ASK;\r
tests[hits].bitrate = bitRate;\r
save_restoreGB(0);\r
clk = GetNrzClock("", FALSE, FALSE);\r
if (clk>0) {\r
- sprintf(cmdStr,"%d", clk/2);\r
- CmdLtrim(cmdStr);\r
+ //sprintf(cmdStr,"%d", clk/2);\r
+ //CmdLtrim(cmdStr);\r
if ( NRZrawDemod("0 0 1", FALSE) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate)) {\r
tests[hits].modulation = DEMOD_NRZ;\r
tests[hits].bitrate = bitRate;\r
save_restoreGB(0);\r
clk = GetPskClock("", FALSE, FALSE);\r
if (clk>0) {\r
- PrintAndLog("clk %d",clk);\r
- sprintf(cmdStr,"%d", clk/2);\r
- CmdLtrim(cmdStr); \r
+ //PrintAndLog("clk %d",clk);\r
+ //sprintf(cmdStr,"%d", clk/2);\r
+ //CmdLtrim(cmdStr); \r
if ( PSKDemod("0 0 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate)) {\r
tests[hits].modulation = DEMOD_PSK1;\r
tests[hits].bitrate = bitRate;\r
\r
if (block > 7) {\r
PrintAndLog("Block number must be between 0 and 7");\r
- return 2;\r
+ return 1;\r
}\r
\r
UsbCommand resp;\r
if (fclow==0) fclow=8;
//set the threshold close to 0 (graph) or 128 std to avoid static
uint8_t threshold_value = 123;
-
+ size_t preLastSample = 0;
+ size_t LastSample = 0;
+ size_t currSample = 0;
// sync to first lo-hi transition, and threshold
// Need to threshold first sample
// Check for 0->1 transition
if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition
- if ((idx-last_transition)<(fclow-2)){ //0-5 = garbage noise
+ preLastSample = LastSample;
+ LastSample = currSample;
+ currSample = idx-last_transition;
+ if (currSample < (fclow-2)){ //0-5 = garbage noise
//do nothing with extra garbage
- } else if ((idx-last_transition) < (fchigh-1)) { //6-8 = 8 waves
+ } else if (currSample < (fchigh-1)) { //6-8 = 8 sample waves
+ if (LastSample > (fchigh-2) && preLastSample < (fchigh-1)){
+ dest[numBits-1]=1; //correct last 9 wave surrounded by 8 waves
+ }
dest[numBits++]=1;
- } else if ((idx-last_transition) > (fchigh+1) && !numBits) { //12 + and first bit = garbage
+
+ } else if (currSample > (fchigh+1) && !numBits) { //12 + and first bit = garbage
//do nothing with beginning garbage
- } else { //9+ = 10 waves
+ } else if (currSample == (fclow+1) && LastSample == (fclow-1)) { // had a 7 then a 9 should be two 8's
+ dest[numBits++]=1;
+ } else { //9+ = 10 sample waves
dest[numBits++]=0;
}
last_transition = idx;
// by marshmellow
// takes a array of binary values, start position, length of bits per parity (includes parity bit),
-// Parity Type (1 for odd; 0 for even; 2 for just drop it), and binary Length (length to run)
+// Parity Type (1 for odd; 0 for even; 2 Always 1's), and binary Length (length to run)
size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen)
{
uint32_t parityWd = 0;
parityWd = (parityWd << 1) | BitStream[startIdx+word+bit];
BitStream[j++] = (BitStream[startIdx+word+bit]);
}
- j--;
+ j--; // overwrite parity with next data
// if parity fails then return 0
- if (pType != 2) {
- if (parityTest(parityWd, pLen, pType) == 0) return -1;
+ if (pType == 2) { // then marker bit which should be a 1
+ if (!BitStream[j]) return 0;
+ } else {
+ if (parityTest(parityWd, pLen, pType) == 0) return 0;
}
bitCnt+=(pLen-1);
parityWd = 0;