MifareUReadBlock(c->arg[0],c->d.asBytes);
break;
case CMD_MIFAREU_READCARD:
- MifareUReadCard(c->arg[0],c->d.asBytes);
+ MifareUReadCard(c->arg[0], c->arg[1], c->d.asBytes);
break;
case CMD_MIFARE_READSC:
MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
int32_t dist_nt(uint32_t nt1, uint32_t nt2);
void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *data);
void MifareUReadBlock(uint8_t arg0,uint8_t *datain);
-void MifareUReadCard(uint8_t arg0,uint8_t *datain);
+void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain);
void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
void MifareUWriteBlock(uint8_t arg0,uint8_t *datain);
// Set up eavesdropping mode, frequency divisor which will drive the FPGA
// and analog mux selection.
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
RELAY_OFF();
// Set up simulator mode, frequency divisor which will drive the FPGA
// and analog mux selection.
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
RELAY_OFF();
if (!ReaderReceive(resp, resp_par)) return 0;
sak = resp[0];
- // Test if more parts of the uid are comming
+ // Test if more parts of the uid are coming
if ((sak & 0x04) /* && uid_resp[0] == 0x88 */) {
// Remove first byte, 0x88 is not an UID byte, it CT, see page 3 of:
// http://www.nxp.com/documents/application_note/AN10927.pdf
*/
void DoAcquisition125k_internal(int trigger_threshold,bool silent)
{
- uint8_t *dest = (uint8_t *)BigBuf;
- int n = sizeof(BigBuf);
- int i;
-
- memset(dest, 0, n);
- 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;
- LED_D_OFF();
- if (trigger_threshold != -1 && dest[i] < trigger_threshold)
- continue;
- else
- trigger_threshold = -1;
- if (++i >= n) break;
- }
- }
- if(!silent)
- {
- Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...",
- dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
-
- }
+ uint8_t *dest = (uint8_t *)BigBuf;
+ int n = sizeof(BigBuf);
+ int i;
+
+ memset(dest, 0, n);
+ 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;
+ LED_D_OFF();
+ if (trigger_threshold != -1 && dest[i] < trigger_threshold)
+ continue;
+ else
+ trigger_threshold = -1;
+ if (++i >= n) break;
+ }
+ }
+ if(!silent)
+ {
+ Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...",
+ dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
+
+ }
}
/**
* Perform sample aquisition.
*/
void DoAcquisition125k(int trigger_threshold)
{
- DoAcquisition125k_internal(trigger_threshold, false);
+ DoAcquisition125k_internal(trigger_threshold, false);
}
/**
**/
void LFSetupFPGAForADC(int divisor, bool lf_field)
{
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- if ( (divisor == 1) || (divisor < 0) || (divisor > 255) )
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
- else if (divisor == 0)
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- else
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
-
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0));
-
- // Connect the A/D to the peak-detected low-frequency path.
- SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
- // Give it a bit of time for the resonant antenna to settle.
- SpinDelay(50);
- // Now set up the SSC to get the ADC samples that are now streaming at us.
- FpgaSetupSsc();
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ if ( (divisor == 1) || (divisor < 0) || (divisor > 255) )
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
+ else if (divisor == 0)
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+ else
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
+
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0));
+
+ // Connect the A/D to the peak-detected low-frequency path.
+ SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
+ // Give it a bit of time for the resonant antenna to settle.
+ SpinDelay(50);
+ // Now set up the SSC to get the ADC samples that are now streaming at us.
+ FpgaSetupSsc();
}
/**
* Initializes the FPGA, and acquires the samples.
**/
void AcquireRawAdcSamples125k(int divisor)
{
- LFSetupFPGAForADC(divisor, true);
- // Now call the acquisition routine
- DoAcquisition125k_internal(-1,false);
+ LFSetupFPGAForADC(divisor, true);
+ // Now call the acquisition routine
+ DoAcquisition125k_internal(-1,false);
}
/**
* Initializes the FPGA for snoop-mode, and acquires the samples.
void SnoopLFRawAdcSamples(int divisor, int trigger_threshold)
{
- LFSetupFPGAForADC(divisor, false);
- DoAcquisition125k(trigger_threshold);
+ LFSetupFPGAForADC(divisor, false);
+ DoAcquisition125k(trigger_threshold);
}
void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command)
{
- /* Make sure the tag is reset */
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- SpinDelay(2500);
+ /* Make sure the tag is reset */
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ SpinDelay(2500);
- int divisor_used = 95; // 125 KHz
- // see if 'h' was specified
+ int divisor_used = 95; // 125 KHz
+ // see if 'h' was specified
- if (command[strlen((char *) command) - 1] == 'h')
- divisor_used = 88; // 134.8 KHz
+ if (command[strlen((char *) command) - 1] == 'h')
+ divisor_used = 88; // 134.8 KHz
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
- // Give it a bit of time for the resonant antenna to settle.
- SpinDelay(50);
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+ // Give it a bit of time for the resonant antenna to settle.
+ SpinDelay(50);
- // And a little more time for the tag to fully power up
- SpinDelay(2000);
+ // And a little more time for the tag to fully power up
+ SpinDelay(2000);
- // Now set up the SSC to get the ADC samples that are now streaming at us.
- FpgaSetupSsc();
+ // Now set up the SSC to get the ADC samples that are now streaming at us.
+ FpgaSetupSsc();
- // now modulate the reader field
- while(*command != '\0' && *command != ' ') {
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- LED_D_OFF();
- SpinDelayUs(delay_off);
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
+ // now modulate the reader field
+ while(*command != '\0' && *command != ' ') {
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ LED_D_OFF();
+ SpinDelayUs(delay_off);
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
- LED_D_ON();
- if(*(command++) == '0')
- SpinDelayUs(period_0);
- else
- SpinDelayUs(period_1);
- }
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- LED_D_OFF();
- SpinDelayUs(delay_off);
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+ LED_D_ON();
+ if(*(command++) == '0')
+ SpinDelayUs(period_0);
+ else
+ SpinDelayUs(period_1);
+ }
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ LED_D_OFF();
+ SpinDelayUs(delay_off);
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
- // now do the read
- DoAcquisition125k(-1);
+ // now do the read
+ DoAcquisition125k(-1);
}
/* blank r/w tag data stream
*/
void ReadTItag(void)
{
- // some hardcoded initial params
- // when we read a TI tag we sample the zerocross line at 2Mhz
- // TI tags modulate a 1 as 16 cycles of 123.2Khz
- // TI tags modulate a 0 as 16 cycles of 134.2Khz
+ // some hardcoded initial params
+ // when we read a TI tag we sample the zerocross line at 2Mhz
+ // TI tags modulate a 1 as 16 cycles of 123.2Khz
+ // TI tags modulate a 0 as 16 cycles of 134.2Khz
#define FSAMPLE 2000000
#define FREQLO 123200
#define FREQHI 134200
- signed char *dest = (signed char *)BigBuf;
- int n = sizeof(BigBuf);
- // 128 bit shift register [shift3:shift2:shift1:shift0]
- uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0;
-
- int i, cycles=0, samples=0;
- // how many sample points fit in 16 cycles of each frequency
- uint32_t sampleslo = (FSAMPLE<<4)/FREQLO, sampleshi = (FSAMPLE<<4)/FREQHI;
- // when to tell if we're close enough to one freq or another
- uint32_t threshold = (sampleslo - sampleshi + 1)>>1;
-
- // TI tags charge at 134.2Khz
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
-
- // Place FPGA in passthrough mode, in this mode the CROSS_LO line
- // connects to SSP_DIN and the SSP_DOUT logic level controls
- // whether we're modulating the antenna (high)
- // or listening to the antenna (low)
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU);
-
- // get TI tag data into the buffer
- AcquireTiType();
-
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-
- for (i=0; i<n-1; i++) {
- // count cycles by looking for lo to hi zero crossings
- if ( (dest[i]<0) && (dest[i+1]>0) ) {
- cycles++;
- // after 16 cycles, measure the frequency
- if (cycles>15) {
- cycles=0;
- samples=i-samples; // number of samples in these 16 cycles
-
- // TI bits are coming to us lsb first so shift them
- // right through our 128 bit right shift register
- shift0 = (shift0>>1) | (shift1 << 31);
- shift1 = (shift1>>1) | (shift2 << 31);
- shift2 = (shift2>>1) | (shift3 << 31);
- shift3 >>= 1;
-
- // check if the cycles fall close to the number
- // expected for either the low or high frequency
- if ( (samples>(sampleslo-threshold)) && (samples<(sampleslo+threshold)) ) {
- // low frequency represents a 1
- shift3 |= (1<<31);
- } else if ( (samples>(sampleshi-threshold)) && (samples<(sampleshi+threshold)) ) {
- // high frequency represents a 0
- } else {
- // probably detected a gay waveform or noise
- // use this as gaydar or discard shift register and start again
- shift3 = shift2 = shift1 = shift0 = 0;
- }
- samples = i;
-
- // for each bit we receive, test if we've detected a valid tag
-
- // if we see 17 zeroes followed by 6 ones, we might have a tag
- // remember the bits are backwards
- if ( ((shift0 & 0x7fffff) == 0x7e0000) ) {
- // if start and end bytes match, we have a tag so break out of the loop
- if ( ((shift0>>16)&0xff) == ((shift3>>8)&0xff) ) {
- cycles = 0xF0B; //use this as a flag (ugly but whatever)
- break;
- }
- }
- }
- }
- }
-
- // if flag is set we have a tag
- if (cycles!=0xF0B) {
- DbpString("Info: No valid tag detected.");
- } else {
- // put 64 bit data into shift1 and shift0
- shift0 = (shift0>>24) | (shift1 << 8);
- shift1 = (shift1>>24) | (shift2 << 8);
-
- // align 16 bit crc into lower half of shift2
- shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff;
-
- // if r/w tag, check ident match
+ signed char *dest = (signed char *)BigBuf;
+ int n = sizeof(BigBuf);
+ // 128 bit shift register [shift3:shift2:shift1:shift0]
+ uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0;
+
+ int i, cycles=0, samples=0;
+ // how many sample points fit in 16 cycles of each frequency
+ uint32_t sampleslo = (FSAMPLE<<4)/FREQLO, sampleshi = (FSAMPLE<<4)/FREQHI;
+ // when to tell if we're close enough to one freq or another
+ uint32_t threshold = (sampleslo - sampleshi + 1)>>1;
+
+ // TI tags charge at 134.2Khz
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
+
+ // Place FPGA in passthrough mode, in this mode the CROSS_LO line
+ // connects to SSP_DIN and the SSP_DOUT logic level controls
+ // whether we're modulating the antenna (high)
+ // or listening to the antenna (low)
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU);
+
+ // get TI tag data into the buffer
+ AcquireTiType();
+
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+
+ for (i=0; i<n-1; i++) {
+ // count cycles by looking for lo to hi zero crossings
+ if ( (dest[i]<0) && (dest[i+1]>0) ) {
+ cycles++;
+ // after 16 cycles, measure the frequency
+ if (cycles>15) {
+ cycles=0;
+ samples=i-samples; // number of samples in these 16 cycles
+
+ // TI bits are coming to us lsb first so shift them
+ // right through our 128 bit right shift register
+ shift0 = (shift0>>1) | (shift1 << 31);
+ shift1 = (shift1>>1) | (shift2 << 31);
+ shift2 = (shift2>>1) | (shift3 << 31);
+ shift3 >>= 1;
+
+ // check if the cycles fall close to the number
+ // expected for either the low or high frequency
+ if ( (samples>(sampleslo-threshold)) && (samples<(sampleslo+threshold)) ) {
+ // low frequency represents a 1
+ shift3 |= (1<<31);
+ } else if ( (samples>(sampleshi-threshold)) && (samples<(sampleshi+threshold)) ) {
+ // high frequency represents a 0
+ } else {
+ // probably detected a gay waveform or noise
+ // use this as gaydar or discard shift register and start again
+ shift3 = shift2 = shift1 = shift0 = 0;
+ }
+ samples = i;
+
+ // for each bit we receive, test if we've detected a valid tag
+
+ // if we see 17 zeroes followed by 6 ones, we might have a tag
+ // remember the bits are backwards
+ if ( ((shift0 & 0x7fffff) == 0x7e0000) ) {
+ // if start and end bytes match, we have a tag so break out of the loop
+ if ( ((shift0>>16)&0xff) == ((shift3>>8)&0xff) ) {
+ cycles = 0xF0B; //use this as a flag (ugly but whatever)
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // if flag is set we have a tag
+ if (cycles!=0xF0B) {
+ DbpString("Info: No valid tag detected.");
+ } else {
+ // put 64 bit data into shift1 and shift0
+ shift0 = (shift0>>24) | (shift1 << 8);
+ shift1 = (shift1>>24) | (shift2 << 8);
+
+ // align 16 bit crc into lower half of shift2
+ shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff;
+
+ // if r/w tag, check ident match
if (shift3 & (1<<15) ) {
- DbpString("Info: TI tag is rewriteable");
- // only 15 bits compare, last bit of ident is not valid
+ DbpString("Info: TI tag is rewriteable");
+ // only 15 bits compare, last bit of ident is not valid
if (((shift3 >> 16) ^ shift0) & 0x7fff ) {
- DbpString("Error: Ident mismatch!");
- } else {
- DbpString("Info: TI tag ident is valid");
- }
- } else {
- DbpString("Info: TI tag is readonly");
- }
-
- // WARNING the order of the bytes in which we calc crc below needs checking
- // i'm 99% sure the crc algorithm is correct, but it may need to eat the
- // bytes in reverse or something
- // calculate CRC
- uint32_t crc=0;
-
- crc = update_crc16(crc, (shift0)&0xff);
- crc = update_crc16(crc, (shift0>>8)&0xff);
- crc = update_crc16(crc, (shift0>>16)&0xff);
- crc = update_crc16(crc, (shift0>>24)&0xff);
- crc = update_crc16(crc, (shift1)&0xff);
- crc = update_crc16(crc, (shift1>>8)&0xff);
- crc = update_crc16(crc, (shift1>>16)&0xff);
- crc = update_crc16(crc, (shift1>>24)&0xff);
-
- Dbprintf("Info: Tag data: %x%08x, crc=%x",
- (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF);
- if (crc != (shift2&0xffff)) {
- Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc);
- } else {
- DbpString("Info: CRC is good");
- }
- }
+ DbpString("Error: Ident mismatch!");
+ } else {
+ DbpString("Info: TI tag ident is valid");
+ }
+ } else {
+ DbpString("Info: TI tag is readonly");
+ }
+
+ // WARNING the order of the bytes in which we calc crc below needs checking
+ // i'm 99% sure the crc algorithm is correct, but it may need to eat the
+ // bytes in reverse or something
+ // calculate CRC
+ uint32_t crc=0;
+
+ crc = update_crc16(crc, (shift0)&0xff);
+ crc = update_crc16(crc, (shift0>>8)&0xff);
+ crc = update_crc16(crc, (shift0>>16)&0xff);
+ crc = update_crc16(crc, (shift0>>24)&0xff);
+ crc = update_crc16(crc, (shift1)&0xff);
+ crc = update_crc16(crc, (shift1>>8)&0xff);
+ crc = update_crc16(crc, (shift1>>16)&0xff);
+ crc = update_crc16(crc, (shift1>>24)&0xff);
+
+ Dbprintf("Info: Tag data: %x%08x, crc=%x",
+ (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF);
+ if (crc != (shift2&0xffff)) {
+ Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc);
+ } else {
+ DbpString("Info: CRC is good");
+ }
+ }
}
void WriteTIbyte(uint8_t b)
{
- int i = 0;
-
- // modulate 8 bits out to the antenna
- for (i=0; i<8; i++)
- {
- if (b&(1<<i)) {
- // stop modulating antenna
- LOW(GPIO_SSC_DOUT);
- SpinDelayUs(1000);
- // modulate antenna
- HIGH(GPIO_SSC_DOUT);
- SpinDelayUs(1000);
- } else {
- // stop modulating antenna
- LOW(GPIO_SSC_DOUT);
- SpinDelayUs(300);
- // modulate antenna
- HIGH(GPIO_SSC_DOUT);
- SpinDelayUs(1700);
- }
- }
+ int i = 0;
+
+ // modulate 8 bits out to the antenna
+ for (i=0; i<8; i++)
+ {
+ if (b&(1<<i)) {
+ // stop modulating antenna
+ LOW(GPIO_SSC_DOUT);
+ SpinDelayUs(1000);
+ // modulate antenna
+ HIGH(GPIO_SSC_DOUT);
+ SpinDelayUs(1000);
+ } else {
+ // stop modulating antenna
+ LOW(GPIO_SSC_DOUT);
+ SpinDelayUs(300);
+ // modulate antenna
+ HIGH(GPIO_SSC_DOUT);
+ SpinDelayUs(1700);
+ }
+ }
}
void AcquireTiType(void)
{
- int i, j, n;
- // tag transmission is <20ms, sampling at 2M gives us 40K samples max
- // each sample is 1 bit stuffed into a uint32_t so we need 1250 uint32_t
+ int i, j, n;
+ // tag transmission is <20ms, sampling at 2M gives us 40K samples max
+ // each sample is 1 bit stuffed into a uint32_t so we need 1250 uint32_t
#define TIBUFLEN 1250
- // clear buffer
- memset(BigBuf,0,sizeof(BigBuf));
-
- // Set up the synchronous serial port
- AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN;
- AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN;
-
- // steal this pin from the SSP and use it to control the modulation
- AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
- AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
-
- AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
- AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN;
-
- // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long
- // 48/2 = 24 MHz clock must be divided by 12
- AT91C_BASE_SSC->SSC_CMR = 12;
-
- AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(0);
- AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(32) | AT91C_SSC_MSBF;
- AT91C_BASE_SSC->SSC_TCMR = 0;
- AT91C_BASE_SSC->SSC_TFMR = 0;
-
- LED_D_ON();
-
- // modulate antenna
- HIGH(GPIO_SSC_DOUT);
-
- // Charge TI tag for 50ms.
- SpinDelay(50);
-
- // stop modulating antenna and listen
- LOW(GPIO_SSC_DOUT);
-
- LED_D_OFF();
-
- i = 0;
- for(;;) {
- if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
- BigBuf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer
- i++; if(i >= TIBUFLEN) break;
- }
- WDT_HIT();
- }
-
- // return stolen pin to SSP
- AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT;
- AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT;
-
- char *dest = (char *)BigBuf;
- n = TIBUFLEN*32;
- // unpack buffer
- for (i=TIBUFLEN-1; i>=0; i--) {
- for (j=0; j<32; j++) {
- if(BigBuf[i] & (1 << j)) {
- dest[--n] = 1;
- } else {
- dest[--n] = -1;
- }
- }
- }
+ // clear buffer
+ memset(BigBuf,0,sizeof(BigBuf));
+
+ // Set up the synchronous serial port
+ AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN;
+ AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN;
+
+ // steal this pin from the SSP and use it to control the modulation
+ AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
+ AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
+
+ AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
+ AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN;
+
+ // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long
+ // 48/2 = 24 MHz clock must be divided by 12
+ AT91C_BASE_SSC->SSC_CMR = 12;
+
+ AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(0);
+ AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(32) | AT91C_SSC_MSBF;
+ AT91C_BASE_SSC->SSC_TCMR = 0;
+ AT91C_BASE_SSC->SSC_TFMR = 0;
+
+ LED_D_ON();
+
+ // modulate antenna
+ HIGH(GPIO_SSC_DOUT);
+
+ // Charge TI tag for 50ms.
+ SpinDelay(50);
+
+ // stop modulating antenna and listen
+ LOW(GPIO_SSC_DOUT);
+
+ LED_D_OFF();
+
+ i = 0;
+ for(;;) {
+ if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
+ BigBuf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer
+ i++; if(i >= TIBUFLEN) break;
+ }
+ WDT_HIT();
+ }
+
+ // return stolen pin to SSP
+ AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT;
+ AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT;
+
+ char *dest = (char *)BigBuf;
+ n = TIBUFLEN*32;
+ // unpack buffer
+ for (i=TIBUFLEN-1; i>=0; i--) {
+ for (j=0; j<32; j++) {
+ if(BigBuf[i] & (1 << j)) {
+ dest[--n] = 1;
+ } else {
+ dest[--n] = -1;
+ }
+ }
+ }
}
// arguments: 64bit data split into 32bit idhi:idlo and optional 16bit crc
// 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);
- crc = update_crc16(crc, (idlo>>8)&0xff);
- crc = update_crc16(crc, (idlo>>16)&0xff);
- crc = update_crc16(crc, (idlo>>24)&0xff);
- crc = update_crc16(crc, (idhi)&0xff);
- crc = update_crc16(crc, (idhi>>8)&0xff);
- crc = update_crc16(crc, (idhi>>16)&0xff);
- crc = update_crc16(crc, (idhi>>24)&0xff);
- }
- Dbprintf("Writing to tag: %x%08x, crc=%x",
- (unsigned int) idhi, (unsigned int) idlo, crc);
-
- // TI tags charge at 134.2Khz
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
- // Place FPGA in passthrough mode, in this mode the CROSS_LO line
- // connects to SSP_DIN and the SSP_DOUT logic level controls
- // whether we're modulating the antenna (high)
- // or listening to the antenna (low)
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU);
- LED_A_ON();
-
- // steal this pin from the SSP and use it to control the modulation
- AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
- AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
-
- // writing algorithm:
- // a high bit consists of a field off for 1ms and field on for 1ms
- // a low bit consists of a field off for 0.3ms and field on for 1.7ms
- // initiate a charge time of 50ms (field on) then immediately start writing bits
- // start by writing 0xBB (keyword) and 0xEB (password)
- // then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer)
- // finally end with 0x0300 (write frame)
- // all data is sent lsb firts
- // finish with 15ms programming time
-
- // modulate antenna
- HIGH(GPIO_SSC_DOUT);
- SpinDelay(50); // charge time
-
- WriteTIbyte(0xbb); // keyword
- WriteTIbyte(0xeb); // password
- WriteTIbyte( (idlo )&0xff );
- WriteTIbyte( (idlo>>8 )&0xff );
- WriteTIbyte( (idlo>>16)&0xff );
- WriteTIbyte( (idlo>>24)&0xff );
- WriteTIbyte( (idhi )&0xff );
- WriteTIbyte( (idhi>>8 )&0xff );
- WriteTIbyte( (idhi>>16)&0xff );
- WriteTIbyte( (idhi>>24)&0xff ); // data hi to lo
- WriteTIbyte( (crc )&0xff ); // crc lo
- WriteTIbyte( (crc>>8 )&0xff ); // crc hi
- WriteTIbyte(0x00); // write frame lo
- WriteTIbyte(0x03); // write frame hi
- HIGH(GPIO_SSC_DOUT);
- SpinDelay(50); // programming time
-
- LED_A_OFF();
-
- // get TI tag data into the buffer
- AcquireTiType();
-
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- DbpString("Now use tiread to check");
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ if(crc == 0) {
+ crc = update_crc16(crc, (idlo)&0xff);
+ crc = update_crc16(crc, (idlo>>8)&0xff);
+ crc = update_crc16(crc, (idlo>>16)&0xff);
+ crc = update_crc16(crc, (idlo>>24)&0xff);
+ crc = update_crc16(crc, (idhi)&0xff);
+ crc = update_crc16(crc, (idhi>>8)&0xff);
+ crc = update_crc16(crc, (idhi>>16)&0xff);
+ crc = update_crc16(crc, (idhi>>24)&0xff);
+ }
+ Dbprintf("Writing to tag: %x%08x, crc=%x",
+ (unsigned int) idhi, (unsigned int) idlo, crc);
+
+ // TI tags charge at 134.2Khz
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
+ // Place FPGA in passthrough mode, in this mode the CROSS_LO line
+ // connects to SSP_DIN and the SSP_DOUT logic level controls
+ // whether we're modulating the antenna (high)
+ // or listening to the antenna (low)
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU);
+ LED_A_ON();
+
+ // steal this pin from the SSP and use it to control the modulation
+ AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
+ AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
+
+ // writing algorithm:
+ // a high bit consists of a field off for 1ms and field on for 1ms
+ // a low bit consists of a field off for 0.3ms and field on for 1.7ms
+ // initiate a charge time of 50ms (field on) then immediately start writing bits
+ // start by writing 0xBB (keyword) and 0xEB (password)
+ // then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer)
+ // finally end with 0x0300 (write frame)
+ // all data is sent lsb firts
+ // finish with 15ms programming time
+
+ // modulate antenna
+ HIGH(GPIO_SSC_DOUT);
+ SpinDelay(50); // charge time
+
+ WriteTIbyte(0xbb); // keyword
+ WriteTIbyte(0xeb); // password
+ WriteTIbyte( (idlo )&0xff );
+ WriteTIbyte( (idlo>>8 )&0xff );
+ WriteTIbyte( (idlo>>16)&0xff );
+ WriteTIbyte( (idlo>>24)&0xff );
+ WriteTIbyte( (idhi )&0xff );
+ WriteTIbyte( (idhi>>8 )&0xff );
+ WriteTIbyte( (idhi>>16)&0xff );
+ WriteTIbyte( (idhi>>24)&0xff ); // data hi to lo
+ WriteTIbyte( (crc )&0xff ); // crc lo
+ WriteTIbyte( (crc>>8 )&0xff ); // crc hi
+ WriteTIbyte(0x00); // write frame lo
+ WriteTIbyte(0x03); // write frame hi
+ HIGH(GPIO_SSC_DOUT);
+ SpinDelay(50); // programming time
+
+ LED_A_OFF();
+
+ // get TI tag data into the buffer
+ AcquireTiType();
+
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ DbpString("Now use tiread to check");
}
void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
{
- int i;
- uint8_t *tab = (uint8_t *)BigBuf;
+ int i;
+ uint8_t *tab = (uint8_t *)BigBuf;
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
- AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK;
+ AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK;
- AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
- AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK;
+ AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
+ AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK;
#define SHORT_COIL() LOW(GPIO_SSC_DOUT)
#define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
- i = 0;
- for(;;) {
- while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
- if(BUTTON_PRESS()) {
- DbpString("Stopped");
- return;
- }
- WDT_HIT();
- }
-
- if (ledcontrol)
- LED_D_ON();
-
- if(tab[i])
- OPEN_COIL();
- else
- SHORT_COIL();
-
- if (ledcontrol)
- LED_D_OFF();
-
- while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) {
- if(BUTTON_PRESS()) {
- DbpString("Stopped");
- return;
- }
- WDT_HIT();
- }
-
- i++;
- if(i == period) {
- i = 0;
- if (gap) {
- SHORT_COIL();
- SpinDelayUs(gap);
- }
- }
- }
+ i = 0;
+ for(;;) {
+ while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
+ if(BUTTON_PRESS()) {
+ DbpString("Stopped");
+ return;
+ }
+ WDT_HIT();
+ }
+
+ if (ledcontrol)
+ LED_D_ON();
+
+ if(tab[i])
+ OPEN_COIL();
+ else
+ SHORT_COIL();
+
+ if (ledcontrol)
+ LED_D_OFF();
+
+ while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) {
+ if(BUTTON_PRESS()) {
+ DbpString("Stopped");
+ return;
+ }
+ WDT_HIT();
+ }
+
+ i++;
+ if(i == period) {
+ i = 0;
+ if (gap) {
+ SHORT_COIL();
+ SpinDelayUs(gap);
+ }
+ }
+ }
}
#define DEBUG_FRAME_CONTENTS 1
// compose fc/8 fc/10 waveform
static void fc(int c, int *n) {
- uint8_t *dest = (uint8_t *)BigBuf;
- int idx;
-
- // for when we want an fc8 pattern every 4 logical bits
- if(c==0) {
- dest[((*n)++)]=1;
- dest[((*n)++)]=1;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- }
- // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples
- if(c==8) {
- for (idx=0; idx<6; idx++) {
- dest[((*n)++)]=1;
- dest[((*n)++)]=1;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- }
- }
-
- // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples
- if(c==10) {
- for (idx=0; idx<5; idx++) {
- dest[((*n)++)]=1;
- dest[((*n)++)]=1;
- dest[((*n)++)]=1;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- dest[((*n)++)]=0;
- }
- }
+ uint8_t *dest = (uint8_t *)BigBuf;
+ int idx;
+
+ // for when we want an fc8 pattern every 4 logical bits
+ if(c==0) {
+ dest[((*n)++)]=1;
+ dest[((*n)++)]=1;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ }
+ // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples
+ if(c==8) {
+ for (idx=0; idx<6; idx++) {
+ dest[((*n)++)]=1;
+ dest[((*n)++)]=1;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ }
+ }
+
+ // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples
+ if(c==10) {
+ for (idx=0; idx<5; idx++) {
+ dest[((*n)++)]=1;
+ dest[((*n)++)]=1;
+ dest[((*n)++)]=1;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ dest[((*n)++)]=0;
+ }
+ }
}
// prepare a waveform pattern in the buffer based on the ID given then
// simulate a HID tag until the button is pressed
void CmdHIDsimTAG(int hi, int lo, int ledcontrol)
{
- int n=0, i=0;
- /*
- HID tag bitstream format
- The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits
- A 1 bit is represented as 6 fc8 and 5 fc10 patterns
- A 0 bit is represented as 5 fc10 and 6 fc8 patterns
- A fc8 is inserted before every 4 bits
- A special start of frame pattern is used consisting a0b0 where a and b are neither 0
- nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10)
- */
-
- if (hi>0xFFF) {
- DbpString("Tags can only have 44 bits.");
- return;
- }
- fc(0,&n);
- // special start of frame marker containing invalid bit sequences
- fc(8, &n); fc(8, &n); // invalid
- fc(8, &n); fc(10, &n); // logical 0
- fc(10, &n); fc(10, &n); // invalid
- fc(8, &n); fc(10, &n); // logical 0
-
- WDT_HIT();
- // manchester encode bits 43 to 32
- for (i=11; i>=0; i--) {
- if ((i%4)==3) fc(0,&n);
- if ((hi>>i)&1) {
- fc(10, &n); fc(8, &n); // low-high transition
- } else {
- fc(8, &n); fc(10, &n); // high-low transition
- }
- }
-
- WDT_HIT();
- // manchester encode bits 31 to 0
- for (i=31; i>=0; i--) {
- if ((i%4)==3) fc(0,&n);
- if ((lo>>i)&1) {
- fc(10, &n); fc(8, &n); // low-high transition
- } else {
- fc(8, &n); fc(10, &n); // high-low transition
- }
- }
-
- if (ledcontrol)
- LED_A_ON();
- SimulateTagLowFrequency(n, 0, ledcontrol);
-
- if (ledcontrol)
- LED_A_OFF();
+ int n=0, i=0;
+ /*
+ HID tag bitstream format
+ The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits
+ A 1 bit is represented as 6 fc8 and 5 fc10 patterns
+ A 0 bit is represented as 5 fc10 and 6 fc8 patterns
+ A fc8 is inserted before every 4 bits
+ A special start of frame pattern is used consisting a0b0 where a and b are neither 0
+ nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10)
+ */
+
+ if (hi>0xFFF) {
+ DbpString("Tags can only have 44 bits.");
+ return;
+ }
+ fc(0,&n);
+ // special start of frame marker containing invalid bit sequences
+ fc(8, &n); fc(8, &n); // invalid
+ fc(8, &n); fc(10, &n); // logical 0
+ fc(10, &n); fc(10, &n); // invalid
+ fc(8, &n); fc(10, &n); // logical 0
+
+ WDT_HIT();
+ // manchester encode bits 43 to 32
+ for (i=11; i>=0; i--) {
+ if ((i%4)==3) fc(0,&n);
+ if ((hi>>i)&1) {
+ fc(10, &n); fc(8, &n); // low-high transition
+ } else {
+ fc(8, &n); fc(10, &n); // high-low transition
+ }
+ }
+
+ WDT_HIT();
+ // manchester encode bits 31 to 0
+ for (i=31; i>=0; i--) {
+ if ((i%4)==3) fc(0,&n);
+ if ((lo>>i)&1) {
+ fc(10, &n); fc(8, &n); // low-high transition
+ } else {
+ fc(8, &n); fc(10, &n); // high-low transition
+ }
+ }
+
+ if (ledcontrol)
+ LED_A_ON();
+ SimulateTagLowFrequency(n, 0, ledcontrol);
+
+ if (ledcontrol)
+ LED_A_OFF();
}
// loop to get raw HID waveform then FSK demodulate the TAG ID from it
void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
{
- uint8_t *dest = (uint8_t *)BigBuf;
+ uint8_t *dest = (uint8_t *)BigBuf;
- size_t size=0; //, found=0;
- uint32_t hi2=0, hi=0, lo=0;
+ size_t size=0; //, found=0;
+ uint32_t hi2=0, hi=0, lo=0;
- // Configure to go in 125Khz listen mode
- LFSetupFPGAForADC(95, true);
+ // Configure to go in 125Khz listen mode
+ LFSetupFPGAForADC(95, true);
- while(!BUTTON_PRESS()) {
+ while(!BUTTON_PRESS()) {
- WDT_HIT();
- if (ledcontrol) LED_A_ON();
+ WDT_HIT();
+ if (ledcontrol) LED_A_ON();
- DoAcquisition125k_internal(-1,true);
- // FSK demodulator
+ DoAcquisition125k_internal(-1,true);
+ // FSK demodulator
size = HIDdemodFSK(dest, sizeof(BigBuf), &hi2, &hi, &lo);
- WDT_HIT();
+ WDT_HIT();
if (size>0 && lo>0){
- // final loop, go over previously decoded manchester data and decode into usable tag ID
- // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
- if (hi2 != 0){ //extra large HID tags
- Dbprintf("TAG ID: %x%08x%08x (%d)",
- (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
- }else { //standard HID tags <38 bits
- //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd
- uint8_t bitlen = 0;
- uint32_t fc = 0;
- uint32_t cardnum = 0;
+ // final loop, go over previously decoded manchester data and decode into usable tag ID
+ // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
+ if (hi2 != 0){ //extra large HID tags
+ Dbprintf("TAG ID: %x%08x%08x (%d)",
+ (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
+ }else { //standard HID tags <38 bits
+ //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd
+ uint8_t bitlen = 0;
+ uint32_t fc = 0;
+ uint32_t cardnum = 0;
if (((hi>>5)&1) == 1){//if bit 38 is set then < 37 bit format is used
- uint32_t lo2=0;
- lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit
- uint8_t idx3 = 1;
+ uint32_t lo2=0;
+ lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit
+ uint8_t idx3 = 1;
while(lo2 > 1){ //find last bit set to 1 (format len bit)
lo2=lo2 >> 1;
- idx3++;
- }
+ idx3++;
+ }
bitlen = idx3+19;
- fc =0;
- cardnum=0;
+ fc =0;
+ cardnum=0;
if(bitlen == 26){
- cardnum = (lo>>1)&0xFFFF;
- fc = (lo>>17)&0xFF;
- }
+ cardnum = (lo>>1)&0xFFFF;
+ fc = (lo>>17)&0xFF;
+ }
if(bitlen == 37){
- cardnum = (lo>>1)&0x7FFFF;
- fc = ((hi&0xF)<<12)|(lo>>20);
- }
+ cardnum = (lo>>1)&0x7FFFF;
+ fc = ((hi&0xF)<<12)|(lo>>20);
+ }
if(bitlen == 34){
- cardnum = (lo>>1)&0xFFFF;
- fc= ((hi&1)<<15)|(lo>>17);
- }
+ cardnum = (lo>>1)&0xFFFF;
+ fc= ((hi&1)<<15)|(lo>>17);
+ }
if(bitlen == 35){
- cardnum = (lo>>1)&0xFFFFF;
- fc = ((hi&1)<<11)|(lo>>21);
- }
- }
- else { //if bit 38 is not set then 37 bit format is used
- bitlen= 37;
- fc =0;
- cardnum=0;
- if(bitlen==37){
- cardnum = (lo>>1)&0x7FFFF;
- fc = ((hi&0xF)<<12)|(lo>>20);
- }
- }
- //Dbprintf("TAG ID: %x%08x (%d)",
- // (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
- Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d",
- (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF,
- (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum);
- }
- if (findone){
- if (ledcontrol) LED_A_OFF();
- return;
- }
- // reset
- hi2 = hi = lo = 0;
- }
- WDT_HIT();
- }
- DbpString("Stopped");
- if (ledcontrol) LED_A_OFF();
+ cardnum = (lo>>1)&0xFFFFF;
+ fc = ((hi&1)<<11)|(lo>>21);
+ }
+ }
+ else { //if bit 38 is not set then 37 bit format is used
+ bitlen= 37;
+ fc =0;
+ cardnum=0;
+ if(bitlen==37){
+ cardnum = (lo>>1)&0x7FFFF;
+ fc = ((hi&0xF)<<12)|(lo>>20);
+ }
+ }
+ //Dbprintf("TAG ID: %x%08x (%d)",
+ // (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
+ Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d",
+ (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF,
+ (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum);
+ }
+ if (findone){
+ if (ledcontrol) LED_A_OFF();
+ return;
+ }
+ // reset
+ hi2 = hi = lo = 0;
+ }
+ WDT_HIT();
+ }
+ DbpString("Stopped");
+ if (ledcontrol) LED_A_OFF();
}
void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
{
- uint8_t *dest = (uint8_t *)BigBuf;
+ uint8_t *dest = (uint8_t *)BigBuf;
size_t size=0;
- int clk=0, invert=0, errCnt=0;
- uint64_t lo=0;
- // Configure to go in 125Khz listen mode
- LFSetupFPGAForADC(95, true);
+ int clk=0, invert=0, errCnt=0;
+ uint64_t lo=0;
+ // Configure to go in 125Khz listen mode
+ LFSetupFPGAForADC(95, true);
- while(!BUTTON_PRESS()) {
+ while(!BUTTON_PRESS()) {
- WDT_HIT();
- if (ledcontrol) LED_A_ON();
+ WDT_HIT();
+ if (ledcontrol) LED_A_ON();
- DoAcquisition125k_internal(-1,true);
- size = sizeof(BigBuf);
- //Dbprintf("DEBUG: Buffer got");
+ DoAcquisition125k_internal(-1,true);
+ size = sizeof(BigBuf);
+ //Dbprintf("DEBUG: Buffer got");
//askdemod and manchester decode
errCnt = askmandemod(dest, &size, &clk, &invert);
- //Dbprintf("DEBUG: ASK Got");
- WDT_HIT();
+ //Dbprintf("DEBUG: ASK Got");
+ WDT_HIT();
- if (errCnt>=0){
+ if (errCnt>=0){
lo = Em410xDecode(dest,size);
- //Dbprintf("DEBUG: EM GOT");
- if (lo>0){
+ //Dbprintf("DEBUG: EM GOT");
+ if (lo>0){
Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",
(uint32_t)(lo>>32),
(uint32_t)lo,
(uint32_t)(lo&0xFFFF),
(uint32_t)((lo>>16LL) & 0xFF),
(uint32_t)(lo & 0xFFFFFF));
- }
- if (findone){
- if (ledcontrol) LED_A_OFF();
- return;
- }
- } else{
- //Dbprintf("DEBUG: No Tag");
- }
- WDT_HIT();
- lo = 0;
- clk=0;
- invert=0;
- errCnt=0;
- size=0;
- }
- DbpString("Stopped");
- if (ledcontrol) LED_A_OFF();
+ }
+ if (findone){
+ if (ledcontrol) LED_A_OFF();
+ return;
+ }
+ } else{
+ //Dbprintf("DEBUG: No Tag");
+ }
+ WDT_HIT();
+ lo = 0;
+ clk=0;
+ invert=0;
+ errCnt=0;
+ size=0;
+ }
+ DbpString("Stopped");
+ if (ledcontrol) LED_A_OFF();
}
void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
{
- uint8_t *dest = (uint8_t *)BigBuf;
- int idx=0;
- uint32_t code=0, code2=0;
- uint8_t version=0;
- uint8_t facilitycode=0;
- uint16_t number=0;
- // Configure to go in 125Khz listen mode
- LFSetupFPGAForADC(95, true);
-
- while(!BUTTON_PRESS()) {
- WDT_HIT();
- if (ledcontrol) LED_A_ON();
- DoAcquisition125k_internal(-1,true);
- //fskdemod and get start index
- WDT_HIT();
- idx = IOdemodFSK(dest,sizeof(BigBuf));
- if (idx>0){
- //valid tag found
-
- //Index map
- //0 10 20 30 40 50 60
- //| | | | | | |
- //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
- //-----------------------------------------------------------------------------
- //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
- //
- //XSF(version)facility:codeone+codetwo
- //Handle the data
- if(findone){ //only print binary if we are doing one
- Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]);
- Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]);
- Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]);
- Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]);
- Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]);
- Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]);
- Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]);
- }
- code = bytebits_to_byte(dest+idx,32);
- code2 = bytebits_to_byte(dest+idx+32,32);
- version = bytebits_to_byte(dest+idx+27,8); //14,4
- facilitycode = bytebits_to_byte(dest+idx+18,8) ;
- number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9
-
- Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
- // if we're only looking for one tag
- if (findone){
- if (ledcontrol) LED_A_OFF();
- //LED_A_OFF();
- return;
- }
- code=code2=0;
- version=facilitycode=0;
- number=0;
- idx=0;
- }
- WDT_HIT();
- }
- DbpString("Stopped");
- if (ledcontrol) LED_A_OFF();
+ uint8_t *dest = (uint8_t *)BigBuf;
+ int idx=0;
+ uint32_t code=0, code2=0;
+ uint8_t version=0;
+ uint8_t facilitycode=0;
+ uint16_t number=0;
+ // Configure to go in 125Khz listen mode
+ LFSetupFPGAForADC(95, true);
+
+ while(!BUTTON_PRESS()) {
+ WDT_HIT();
+ if (ledcontrol) LED_A_ON();
+ DoAcquisition125k_internal(-1,true);
+ //fskdemod and get start index
+ WDT_HIT();
+ idx = IOdemodFSK(dest,sizeof(BigBuf));
+ if (idx>0){
+ //valid tag found
+
+ //Index map
+ //0 10 20 30 40 50 60
+ //| | | | | | |
+ //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
+ //-----------------------------------------------------------------------------
+ //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
+ //
+ //XSF(version)facility:codeone+codetwo
+ //Handle the data
+ if(findone){ //only print binary if we are doing one
+ Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]);
+ Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]);
+ Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]);
+ Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]);
+ Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]);
+ Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]);
+ Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]);
+ }
+ code = bytebits_to_byte(dest+idx,32);
+ code2 = bytebits_to_byte(dest+idx+32,32);
+ version = bytebits_to_byte(dest+idx+27,8); //14,4
+ facilitycode = bytebits_to_byte(dest+idx+18,8) ;
+ number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9
+
+ Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
+ // if we're only looking for one tag
+ if (findone){
+ if (ledcontrol) LED_A_OFF();
+ //LED_A_OFF();
+ return;
+ }
+ code=code2=0;
+ version=facilitycode=0;
+ number=0;
+ idx=0;
+ }
+ WDT_HIT();
+ }
+ DbpString("Stopped");
+ if (ledcontrol) LED_A_OFF();
}
/*------------------------------
// Write one bit to card
void T55xxWriteBit(int bit)
{
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
- if (bit == 0)
- SpinDelayUs(WRITE_0);
- else
- SpinDelayUs(WRITE_1);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- SpinDelayUs(WRITE_GAP);
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+ if (bit == 0)
+ SpinDelayUs(WRITE_0);
+ else
+ SpinDelayUs(WRITE_1);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ SpinDelayUs(WRITE_GAP);
}
// Write one card block in page 0, no lock
void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
{
- //unsigned int i; //enio adjustment 12/10/14
- uint32_t i;
-
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
-
- // Give it a bit of time for the resonant antenna to settle.
- // And for the tag to fully power up
- SpinDelay(150);
-
- // Now start writting
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- SpinDelayUs(START_GAP);
-
- // Opcode
- T55xxWriteBit(1);
- T55xxWriteBit(0); //Page 0
- if (PwdMode == 1){
- // Pwd
- for (i = 0x80000000; i != 0; i >>= 1)
- T55xxWriteBit(Pwd & i);
- }
- // Lock bit
- T55xxWriteBit(0);
-
- // Data
- for (i = 0x80000000; i != 0; i >>= 1)
- T55xxWriteBit(Data & i);
-
- // Block
- for (i = 0x04; i != 0; i >>= 1)
- T55xxWriteBit(Block & i);
-
- // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550,
- // so wait a little more)
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
- SpinDelay(20);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ //unsigned int i; //enio adjustment 12/10/14
+ uint32_t i;
+
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+
+ // Give it a bit of time for the resonant antenna to settle.
+ // And for the tag to fully power up
+ SpinDelay(150);
+
+ // Now start writting
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ SpinDelayUs(START_GAP);
+
+ // Opcode
+ T55xxWriteBit(1);
+ T55xxWriteBit(0); //Page 0
+ if (PwdMode == 1){
+ // Pwd
+ for (i = 0x80000000; i != 0; i >>= 1)
+ T55xxWriteBit(Pwd & i);
+ }
+ // Lock bit
+ T55xxWriteBit(0);
+
+ // Data
+ for (i = 0x80000000; i != 0; i >>= 1)
+ T55xxWriteBit(Data & i);
+
+ // Block
+ for (i = 0x04; i != 0; i >>= 1)
+ T55xxWriteBit(Block & i);
+
+ // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550,
+ // so wait a little more)
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+ SpinDelay(20);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
}
// Read one card block in page 0
void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
{
- uint8_t *dest = (uint8_t *)BigBuf;
- //int m=0, i=0; //enio adjustment 12/10/14
- uint32_t m=0, i=0;
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- m = sizeof(BigBuf);
- // Clear destination buffer before sending the command
- memset(dest, 128, m);
- // 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();
-
- LED_D_ON();
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
-
- // Give it a bit of time for the resonant antenna to settle.
- // And for the tag to fully power up
- SpinDelay(150);
-
- // Now start writting
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- SpinDelayUs(START_GAP);
-
- // Opcode
- T55xxWriteBit(1);
- T55xxWriteBit(0); //Page 0
- if (PwdMode == 1){
- // Pwd
- for (i = 0x80000000; i != 0; i >>= 1)
- T55xxWriteBit(Pwd & i);
- }
- // Lock bit
- T55xxWriteBit(0);
- // Block
- for (i = 0x04; i != 0; i >>= 1)
- T55xxWriteBit(Block & i);
-
- // Turn field on to read the response
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
-
- // Now do the acquisition
- i = 0;
- for(;;) {
- if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
- AT91C_BASE_SSC->SSC_THR = 0x43;
- }
- if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
- dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
- // we don't care about actual value, only if it's more or less than a
- // threshold essentially we capture zero crossings for later analysis
- // if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;
- i++;
- if (i >= m) break;
- }
- }
-
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
- LED_D_OFF();
- DbpString("DONE!");
+ uint8_t *dest = (uint8_t *)BigBuf;
+ //int m=0, i=0; //enio adjustment 12/10/14
+ uint32_t m=0, i=0;
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ m = sizeof(BigBuf);
+ // Clear destination buffer before sending the command
+ memset(dest, 128, m);
+ // 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();
+
+ LED_D_ON();
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+
+ // Give it a bit of time for the resonant antenna to settle.
+ // And for the tag to fully power up
+ SpinDelay(150);
+
+ // Now start writting
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ SpinDelayUs(START_GAP);
+
+ // Opcode
+ T55xxWriteBit(1);
+ T55xxWriteBit(0); //Page 0
+ if (PwdMode == 1){
+ // Pwd
+ for (i = 0x80000000; i != 0; i >>= 1)
+ T55xxWriteBit(Pwd & i);
+ }
+ // Lock bit
+ T55xxWriteBit(0);
+ // Block
+ for (i = 0x04; i != 0; i >>= 1)
+ T55xxWriteBit(Block & i);
+
+ // Turn field on to read the response
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+
+ // Now do the acquisition
+ i = 0;
+ for(;;) {
+ if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
+ AT91C_BASE_SSC->SSC_THR = 0x43;
+ }
+ if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
+ dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
+ // we don't care about actual value, only if it's more or less than a
+ // threshold essentially we capture zero crossings for later analysis
+ // if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;
+ i++;
+ if (i >= m) break;
+ }
+ }
+
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
+ LED_D_OFF();
+ DbpString("DONE!");
}
// Read card traceability data (page 1)
void T55xxReadTrace(void){
- uint8_t *dest = (uint8_t *)BigBuf;
- int m=0, i=0;
-
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- m = sizeof(BigBuf);
- // Clear destination buffer before sending the command
- memset(dest, 128, m);
- // 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();
-
- LED_D_ON();
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
-
- // Give it a bit of time for the resonant antenna to settle.
- // And for the tag to fully power up
- SpinDelay(150);
-
- // Now start writting
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- SpinDelayUs(START_GAP);
-
- // Opcode
- T55xxWriteBit(1);
- T55xxWriteBit(1); //Page 1
-
- // Turn field on to read the response
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
-
- // Now do the acquisition
- i = 0;
- for(;;) {
- if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
- AT91C_BASE_SSC->SSC_THR = 0x43;
- }
- if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
- dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
- i++;
- if (i >= m) break;
- }
- }
-
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
- LED_D_OFF();
- DbpString("DONE!");
+ uint8_t *dest = (uint8_t *)BigBuf;
+ int m=0, i=0;
+
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ m = sizeof(BigBuf);
+ // Clear destination buffer before sending the command
+ memset(dest, 128, m);
+ // 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();
+
+ LED_D_ON();
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+
+ // Give it a bit of time for the resonant antenna to settle.
+ // And for the tag to fully power up
+ SpinDelay(150);
+
+ // Now start writting
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ SpinDelayUs(START_GAP);
+
+ // Opcode
+ T55xxWriteBit(1);
+ T55xxWriteBit(1); //Page 1
+
+ // Turn field on to read the response
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+
+ // Now do the acquisition
+ i = 0;
+ for(;;) {
+ if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
+ AT91C_BASE_SSC->SSC_THR = 0x43;
+ }
+ if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
+ dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
+ i++;
+ if (i >= m) break;
+ }
+ }
+
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
+ LED_D_OFF();
+ DbpString("DONE!");
}
/*-------------- 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)
{
- int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format
- int last_block = 0;
-
- if (longFMT){
- // Ensure no more than 84 bits supplied
- if (hi2>0xFFFFF) {
- DbpString("Tags can only have 84 bits.");
- return;
- }
- // Build the 6 data blocks for supplied 84bit ID
- last_block = 6;
- data1 = 0x1D96A900; // load preamble (1D) & long format identifier (9E manchester encoded)
- for (int i=0;i<4;i++) {
- if (hi2 & (1<<(19-i)))
- data1 |= (1<<(((3-i)*2)+1)); // 1 -> 10
- else
- data1 |= (1<<((3-i)*2)); // 0 -> 01
- }
-
- data2 = 0;
- for (int i=0;i<16;i++) {
- if (hi2 & (1<<(15-i)))
- data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10
- else
- data2 |= (1<<((15-i)*2)); // 0 -> 01
- }
-
- data3 = 0;
- for (int i=0;i<16;i++) {
- if (hi & (1<<(31-i)))
- data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10
- else
- data3 |= (1<<((15-i)*2)); // 0 -> 01
- }
-
- data4 = 0;
- for (int i=0;i<16;i++) {
- if (hi & (1<<(15-i)))
- data4 |= (1<<(((15-i)*2)+1)); // 1 -> 10
- else
- data4 |= (1<<((15-i)*2)); // 0 -> 01
- }
-
- data5 = 0;
- for (int i=0;i<16;i++) {
- if (lo & (1<<(31-i)))
- data5 |= (1<<(((15-i)*2)+1)); // 1 -> 10
- else
- data5 |= (1<<((15-i)*2)); // 0 -> 01
- }
-
- data6 = 0;
- for (int i=0;i<16;i++) {
- if (lo & (1<<(15-i)))
- data6 |= (1<<(((15-i)*2)+1)); // 1 -> 10
- else
- data6 |= (1<<((15-i)*2)); // 0 -> 01
- }
- }
- else {
- // Ensure no more than 44 bits supplied
- if (hi>0xFFF) {
- DbpString("Tags can only have 44 bits.");
- return;
- }
-
- // Build the 3 data blocks for supplied 44bit ID
- last_block = 3;
-
- data1 = 0x1D000000; // load preamble
-
- for (int i=0;i<12;i++) {
- if (hi & (1<<(11-i)))
- data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10
- else
- data1 |= (1<<((11-i)*2)); // 0 -> 01
- }
-
- data2 = 0;
- for (int i=0;i<16;i++) {
- if (lo & (1<<(31-i)))
- data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10
- else
- data2 |= (1<<((15-i)*2)); // 0 -> 01
- }
-
- data3 = 0;
- for (int i=0;i<16;i++) {
- if (lo & (1<<(15-i)))
- data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10
- else
- data3 |= (1<<((15-i)*2)); // 0 -> 01
- }
- }
-
- LED_D_ON();
- // Program the data blocks for supplied ID
- // and the block 0 for HID format
- T55xxWriteBlock(data1,1,0,0);
- T55xxWriteBlock(data2,2,0,0);
- T55xxWriteBlock(data3,3,0,0);
-
- if (longFMT) { // if long format there are 6 blocks
- T55xxWriteBlock(data4,4,0,0);
- T55xxWriteBlock(data5,5,0,0);
- T55xxWriteBlock(data6,6,0,0);
- }
-
- // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long)
- T55xxWriteBlock(T55x7_BITRATE_RF_50 |
- T55x7_MODULATION_FSK2a |
- last_block << T55x7_MAXBLOCK_SHIFT,
- 0,0,0);
-
- LED_D_OFF();
-
- DbpString("DONE!");
+ int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format
+ int last_block = 0;
+
+ if (longFMT){
+ // Ensure no more than 84 bits supplied
+ if (hi2>0xFFFFF) {
+ DbpString("Tags can only have 84 bits.");
+ return;
+ }
+ // Build the 6 data blocks for supplied 84bit ID
+ last_block = 6;
+ data1 = 0x1D96A900; // load preamble (1D) & long format identifier (9E manchester encoded)
+ for (int i=0;i<4;i++) {
+ if (hi2 & (1<<(19-i)))
+ data1 |= (1<<(((3-i)*2)+1)); // 1 -> 10
+ else
+ data1 |= (1<<((3-i)*2)); // 0 -> 01
+ }
+
+ data2 = 0;
+ for (int i=0;i<16;i++) {
+ if (hi2 & (1<<(15-i)))
+ data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10
+ else
+ data2 |= (1<<((15-i)*2)); // 0 -> 01
+ }
+
+ data3 = 0;
+ for (int i=0;i<16;i++) {
+ if (hi & (1<<(31-i)))
+ data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10
+ else
+ data3 |= (1<<((15-i)*2)); // 0 -> 01
+ }
+
+ data4 = 0;
+ for (int i=0;i<16;i++) {
+ if (hi & (1<<(15-i)))
+ data4 |= (1<<(((15-i)*2)+1)); // 1 -> 10
+ else
+ data4 |= (1<<((15-i)*2)); // 0 -> 01
+ }
+
+ data5 = 0;
+ for (int i=0;i<16;i++) {
+ if (lo & (1<<(31-i)))
+ data5 |= (1<<(((15-i)*2)+1)); // 1 -> 10
+ else
+ data5 |= (1<<((15-i)*2)); // 0 -> 01
+ }
+
+ data6 = 0;
+ for (int i=0;i<16;i++) {
+ if (lo & (1<<(15-i)))
+ data6 |= (1<<(((15-i)*2)+1)); // 1 -> 10
+ else
+ data6 |= (1<<((15-i)*2)); // 0 -> 01
+ }
+ }
+ else {
+ // Ensure no more than 44 bits supplied
+ if (hi>0xFFF) {
+ DbpString("Tags can only have 44 bits.");
+ return;
+ }
+
+ // Build the 3 data blocks for supplied 44bit ID
+ last_block = 3;
+
+ data1 = 0x1D000000; // load preamble
+
+ for (int i=0;i<12;i++) {
+ if (hi & (1<<(11-i)))
+ data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10
+ else
+ data1 |= (1<<((11-i)*2)); // 0 -> 01
+ }
+
+ data2 = 0;
+ for (int i=0;i<16;i++) {
+ if (lo & (1<<(31-i)))
+ data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10
+ else
+ data2 |= (1<<((15-i)*2)); // 0 -> 01
+ }
+
+ data3 = 0;
+ for (int i=0;i<16;i++) {
+ if (lo & (1<<(15-i)))
+ data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10
+ else
+ data3 |= (1<<((15-i)*2)); // 0 -> 01
+ }
+ }
+
+ LED_D_ON();
+ // Program the data blocks for supplied ID
+ // and the block 0 for HID format
+ T55xxWriteBlock(data1,1,0,0);
+ T55xxWriteBlock(data2,2,0,0);
+ T55xxWriteBlock(data3,3,0,0);
+
+ if (longFMT) { // if long format there are 6 blocks
+ T55xxWriteBlock(data4,4,0,0);
+ T55xxWriteBlock(data5,5,0,0);
+ T55xxWriteBlock(data6,6,0,0);
+ }
+
+ // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long)
+ T55xxWriteBlock(T55x7_BITRATE_RF_50 |
+ T55x7_MODULATION_FSK2a |
+ last_block << T55x7_MAXBLOCK_SHIFT,
+ 0,0,0);
+
+ LED_D_OFF();
+
+ DbpString("DONE!");
}
void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT)
{
- int data1=0, data2=0; //up to six blocks for long format
+ int data1=0, data2=0; //up to six blocks for long format
- data1 = hi; // load preamble
- data2 = lo;
+ data1 = hi; // load preamble
+ data2 = lo;
- LED_D_ON();
- // Program the data blocks for supplied ID
- // and the block 0 for HID format
- T55xxWriteBlock(data1,1,0,0);
- T55xxWriteBlock(data2,2,0,0);
+ LED_D_ON();
+ // Program the data blocks for supplied ID
+ // and the block 0 for HID format
+ T55xxWriteBlock(data1,1,0,0);
+ T55xxWriteBlock(data2,2,0,0);
- //Config Block
- T55xxWriteBlock(0x00147040,0,0,0);
- LED_D_OFF();
+ //Config Block
+ T55xxWriteBlock(0x00147040,0,0,0);
+ LED_D_OFF();
- DbpString("DONE!");
+ DbpString("DONE!");
}
// Define 9bit header for EM410x tags
void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo)
{
- int i, id_bit;
- uint64_t id = EM410X_HEADER;
- uint64_t rev_id = 0; // reversed ID
- int c_parity[4]; // column parity
- int r_parity = 0; // row parity
- uint32_t clock = 0;
-
- // Reverse ID bits given as parameter (for simpler operations)
- for (i = 0; i < EM410X_ID_LENGTH; ++i) {
- if (i < 32) {
- rev_id = (rev_id << 1) | (id_lo & 1);
- id_lo >>= 1;
- } else {
- rev_id = (rev_id << 1) | (id_hi & 1);
- id_hi >>= 1;
- }
- }
-
- for (i = 0; i < EM410X_ID_LENGTH; ++i) {
- id_bit = rev_id & 1;
-
- if (i % 4 == 0) {
- // Don't write row parity bit at start of parsing
- if (i)
- id = (id << 1) | r_parity;
- // Start counting parity for new row
- r_parity = id_bit;
- } else {
- // Count row parity
- r_parity ^= id_bit;
- }
-
- // First elements in column?
- if (i < 4)
- // Fill out first elements
- c_parity[i] = id_bit;
- else
- // Count column parity
- c_parity[i % 4] ^= id_bit;
-
- // Insert ID bit
- id = (id << 1) | id_bit;
- rev_id >>= 1;
- }
-
- // Insert parity bit of last row
- id = (id << 1) | r_parity;
-
- // Fill out column parity at the end of tag
- for (i = 0; i < 4; ++i)
- id = (id << 1) | c_parity[i];
-
- // Add stop bit
- id <<= 1;
-
- Dbprintf("Started writing %s tag ...", card ? "T55x7":"T5555");
- LED_D_ON();
-
- // Write EM410x ID
- T55xxWriteBlock((uint32_t)(id >> 32), 1, 0, 0);
- T55xxWriteBlock((uint32_t)id, 2, 0, 0);
-
- // Config for EM410x (RF/64, Manchester, Maxblock=2)
- if (card) {
- // Clock rate is stored in bits 8-15 of the card value
- clock = (card & 0xFF00) >> 8;
- Dbprintf("Clock rate: %d", clock);
- switch (clock)
- {
- case 32:
- clock = T55x7_BITRATE_RF_32;
- break;
- case 16:
- clock = T55x7_BITRATE_RF_16;
- break;
- case 0:
- // A value of 0 is assumed to be 64 for backwards-compatibility
- // Fall through...
- case 64:
- clock = T55x7_BITRATE_RF_64;
- break;
- default:
- Dbprintf("Invalid clock rate: %d", clock);
- return;
- }
-
- // Writing configuration for T55x7 tag
- T55xxWriteBlock(clock |
- T55x7_MODULATION_MANCHESTER |
- 2 << T55x7_MAXBLOCK_SHIFT,
- 0, 0, 0);
- }
- else
- // Writing configuration for T5555(Q5) tag
- T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT |
- T5555_MODULATION_MANCHESTER |
- 2 << T5555_MAXBLOCK_SHIFT,
- 0, 0, 0);
-
- LED_D_OFF();
- Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555",
- (uint32_t)(id >> 32), (uint32_t)id);
+ int i, id_bit;
+ uint64_t id = EM410X_HEADER;
+ uint64_t rev_id = 0; // reversed ID
+ int c_parity[4]; // column parity
+ int r_parity = 0; // row parity
+ uint32_t clock = 0;
+
+ // Reverse ID bits given as parameter (for simpler operations)
+ for (i = 0; i < EM410X_ID_LENGTH; ++i) {
+ if (i < 32) {
+ rev_id = (rev_id << 1) | (id_lo & 1);
+ id_lo >>= 1;
+ } else {
+ rev_id = (rev_id << 1) | (id_hi & 1);
+ id_hi >>= 1;
+ }
+ }
+
+ for (i = 0; i < EM410X_ID_LENGTH; ++i) {
+ id_bit = rev_id & 1;
+
+ if (i % 4 == 0) {
+ // Don't write row parity bit at start of parsing
+ if (i)
+ id = (id << 1) | r_parity;
+ // Start counting parity for new row
+ r_parity = id_bit;
+ } else {
+ // Count row parity
+ r_parity ^= id_bit;
+ }
+
+ // First elements in column?
+ if (i < 4)
+ // Fill out first elements
+ c_parity[i] = id_bit;
+ else
+ // Count column parity
+ c_parity[i % 4] ^= id_bit;
+
+ // Insert ID bit
+ id = (id << 1) | id_bit;
+ rev_id >>= 1;
+ }
+
+ // Insert parity bit of last row
+ id = (id << 1) | r_parity;
+
+ // Fill out column parity at the end of tag
+ for (i = 0; i < 4; ++i)
+ id = (id << 1) | c_parity[i];
+
+ // Add stop bit
+ id <<= 1;
+
+ Dbprintf("Started writing %s tag ...", card ? "T55x7":"T5555");
+ LED_D_ON();
+
+ // Write EM410x ID
+ T55xxWriteBlock((uint32_t)(id >> 32), 1, 0, 0);
+ T55xxWriteBlock((uint32_t)id, 2, 0, 0);
+
+ // Config for EM410x (RF/64, Manchester, Maxblock=2)
+ if (card) {
+ // Clock rate is stored in bits 8-15 of the card value
+ clock = (card & 0xFF00) >> 8;
+ Dbprintf("Clock rate: %d", clock);
+ switch (clock)
+ {
+ case 32:
+ clock = T55x7_BITRATE_RF_32;
+ break;
+ case 16:
+ clock = T55x7_BITRATE_RF_16;
+ break;
+ case 0:
+ // A value of 0 is assumed to be 64 for backwards-compatibility
+ // Fall through...
+ case 64:
+ clock = T55x7_BITRATE_RF_64;
+ break;
+ default:
+ Dbprintf("Invalid clock rate: %d", clock);
+ return;
+ }
+
+ // Writing configuration for T55x7 tag
+ T55xxWriteBlock(clock |
+ T55x7_MODULATION_MANCHESTER |
+ 2 << T55x7_MAXBLOCK_SHIFT,
+ 0, 0, 0);
+ }
+ else
+ // Writing configuration for T5555(Q5) tag
+ T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT |
+ T5555_MODULATION_MANCHESTER |
+ 2 << T5555_MAXBLOCK_SHIFT,
+ 0, 0, 0);
+
+ LED_D_OFF();
+ Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555",
+ (uint32_t)(id >> 32), (uint32_t)id);
}
// Clone Indala 64-bit tag by UID to T55x7
void CopyIndala64toT55x7(int hi, int lo)
{
- //Program the 2 data blocks for supplied 64bit UID
- // and the block 0 for Indala64 format
- T55xxWriteBlock(hi,1,0,0);
- T55xxWriteBlock(lo,2,0,0);
- //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2)
- T55xxWriteBlock(T55x7_BITRATE_RF_32 |
- T55x7_MODULATION_PSK1 |
- 2 << T55x7_MAXBLOCK_SHIFT,
- 0, 0, 0);
- //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data)
- // T5567WriteBlock(0x603E1042,0);
+ //Program the 2 data blocks for supplied 64bit UID
+ // and the block 0 for Indala64 format
+ T55xxWriteBlock(hi,1,0,0);
+ T55xxWriteBlock(lo,2,0,0);
+ //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2)
+ T55xxWriteBlock(T55x7_BITRATE_RF_32 |
+ T55x7_MODULATION_PSK1 |
+ 2 << T55x7_MAXBLOCK_SHIFT,
+ 0, 0, 0);
+ //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data)
+ // T5567WriteBlock(0x603E1042,0);
- DbpString("DONE!");
+ DbpString("DONE!");
}
void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int uid6, int uid7)
{
- //Program the 7 data blocks for supplied 224bit UID
- // and the block 0 for Indala224 format
- T55xxWriteBlock(uid1,1,0,0);
- T55xxWriteBlock(uid2,2,0,0);
- T55xxWriteBlock(uid3,3,0,0);
- T55xxWriteBlock(uid4,4,0,0);
- T55xxWriteBlock(uid5,5,0,0);
- T55xxWriteBlock(uid6,6,0,0);
- T55xxWriteBlock(uid7,7,0,0);
- //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7)
- T55xxWriteBlock(T55x7_BITRATE_RF_32 |
- T55x7_MODULATION_PSK1 |
- 7 << T55x7_MAXBLOCK_SHIFT,
- 0,0,0);
- //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data)
- // T5567WriteBlock(0x603E10E2,0);
-
- DbpString("DONE!");
+ //Program the 7 data blocks for supplied 224bit UID
+ // and the block 0 for Indala224 format
+ T55xxWriteBlock(uid1,1,0,0);
+ T55xxWriteBlock(uid2,2,0,0);
+ T55xxWriteBlock(uid3,3,0,0);
+ T55xxWriteBlock(uid4,4,0,0);
+ T55xxWriteBlock(uid5,5,0,0);
+ T55xxWriteBlock(uid6,6,0,0);
+ T55xxWriteBlock(uid7,7,0,0);
+ //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7)
+ T55xxWriteBlock(T55x7_BITRATE_RF_32 |
+ T55x7_MODULATION_PSK1 |
+ 7 << T55x7_MAXBLOCK_SHIFT,
+ 0,0,0);
+ //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data)
+ // T5567WriteBlock(0x603E10E2,0);
+
+ DbpString("DONE!");
}
#define max(x,y) ( x<y ? y:x)
int DemodPCF7931(uint8_t **outBlocks) {
- uint8_t BitStream[256];
- uint8_t Blocks[8][16];
- uint8_t *GraphBuffer = (uint8_t *)BigBuf;
- int GraphTraceLen = sizeof(BigBuf);
- int i, j, lastval, bitidx, half_switch;
- int clock = 64;
- int tolerance = clock / 8;
- int pmc, block_done;
- int lc, warnings = 0;
- int num_blocks = 0;
- int lmin=128, lmax=128;
- uint8_t dir;
-
- AcquireRawAdcSamples125k(0);
-
- lmin = 64;
- lmax = 192;
-
- i = 2;
-
- /* Find first local max/min */
- if(GraphBuffer[1] > 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;
+ uint8_t BitStream[256];
+ uint8_t Blocks[8][16];
+ uint8_t *GraphBuffer = (uint8_t *)BigBuf;
+ int GraphTraceLen = sizeof(BigBuf);
+ int i, j, lastval, bitidx, half_switch;
+ int clock = 64;
+ int tolerance = clock / 8;
+ int pmc, block_done;
+ int lc, warnings = 0;
+ int num_blocks = 0;
+ int lmin=128, lmax=128;
+ uint8_t dir;
+
+ AcquireRawAdcSamples125k(0);
+
+ lmin = 64;
+ lmax = 192;
+
+ i = 2;
+
+ /* Find first local max/min */
+ if(GraphBuffer[1] > 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;
+ // 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;
+ // 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;
+ 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<n; i++)
- Dbprintf("(dbg) %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
- tmpBlocks[i][0], tmpBlocks[i][1], tmpBlocks[i][2], tmpBlocks[i][3], tmpBlocks[i][4], tmpBlocks[i][5], tmpBlocks[i][6], tmpBlocks[i][7],
- tmpBlocks[i][8], tmpBlocks[i][9], tmpBlocks[i][10], tmpBlocks[i][11], tmpBlocks[i][12], tmpBlocks[i][13], tmpBlocks[i][14], tmpBlocks[i][15]);
- if(!ident) {
- for(i=0; i<n; i++) {
- if(IsBlock0PCF7931(tmpBlocks[i])) {
- // Found block 0 ?
- if(i < n-1 && IsBlock1PCF7931(tmpBlocks[i+1])) {
- // Found block 1!
- // \o/
- ident = 1;
- memcpy(Blocks[0], tmpBlocks[i], 16);
- Blocks[0][ALLOC] = 1;
- memcpy(Blocks[1], tmpBlocks[i+1], 16);
- Blocks[1][ALLOC] = 1;
- max_blocks = max((Blocks[1][14] & 0x7f), Blocks[1][15]) + 1;
- // Debug print
- Dbprintf("(dbg) Max blocks: %d", max_blocks);
- num_blocks = 2;
- // Handle following blocks
- for(j=i+2, ind2=2; j!=i; j++, ind2++, num_blocks++) {
- if(j==n) j=0;
- if(j==i) break;
- memcpy(Blocks[ind2], tmpBlocks[j], 16);
- Blocks[ind2][ALLOC] = 1;
- }
- break;
- }
- }
- }
- }
- else {
- for(i=0; i<n; i++) { // Look for identical block in known blocks
- if(memcmp(tmpBlocks[i], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) { // Block is not full of 00
- for(j=0; j<max_blocks; j++) {
- if(Blocks[j][ALLOC] == 1 && !memcmp(tmpBlocks[i], Blocks[j], 16)) {
- // Found an identical block
- for(ind=i-1,ind2=j-1; ind >= 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);
+ 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<n; i++)
+ Dbprintf("(dbg) %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
+ tmpBlocks[i][0], tmpBlocks[i][1], tmpBlocks[i][2], tmpBlocks[i][3], tmpBlocks[i][4], tmpBlocks[i][5], tmpBlocks[i][6], tmpBlocks[i][7],
+ tmpBlocks[i][8], tmpBlocks[i][9], tmpBlocks[i][10], tmpBlocks[i][11], tmpBlocks[i][12], tmpBlocks[i][13], tmpBlocks[i][14], tmpBlocks[i][15]);
+ if(!ident) {
+ for(i=0; i<n; i++) {
+ if(IsBlock0PCF7931(tmpBlocks[i])) {
+ // Found block 0 ?
+ if(i < n-1 && IsBlock1PCF7931(tmpBlocks[i+1])) {
+ // Found block 1!
+ // \o/
+ ident = 1;
+ memcpy(Blocks[0], tmpBlocks[i], 16);
+ Blocks[0][ALLOC] = 1;
+ memcpy(Blocks[1], tmpBlocks[i+1], 16);
+ Blocks[1][ALLOC] = 1;
+ max_blocks = max((Blocks[1][14] & 0x7f), Blocks[1][15]) + 1;
+ // Debug print
+ Dbprintf("(dbg) Max blocks: %d", max_blocks);
+ num_blocks = 2;
+ // Handle following blocks
+ for(j=i+2, ind2=2; j!=i; j++, ind2++, num_blocks++) {
+ if(j==n) j=0;
+ if(j==i) break;
+ memcpy(Blocks[ind2], tmpBlocks[j], 16);
+ Blocks[ind2][ALLOC] = 1;
+ }
+ break;
+ }
+ }
+ }
+ }
+ else {
+ for(i=0; i<n; i++) { // Look for identical block in known blocks
+ if(memcmp(tmpBlocks[i], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) { // Block is not full of 00
+ for(j=0; j<max_blocks; j++) {
+ if(Blocks[j][ALLOC] == 1 && !memcmp(tmpBlocks[i], Blocks[j], 16)) {
+ // Found an identical block
+ for(ind=i-1,ind2=j-1; ind >= 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<max_blocks; i++) {
- if(Blocks[i][ALLOC]==1)
- Dbprintf("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
- Blocks[i][0], Blocks[i][1], Blocks[i][2], Blocks[i][3], Blocks[i][4], Blocks[i][5], Blocks[i][6], Blocks[i][7],
- Blocks[i][8], Blocks[i][9], Blocks[i][10], Blocks[i][11], Blocks[i][12], Blocks[i][13], Blocks[i][14], Blocks[i][15]);
- else
- Dbprintf("<missing block %d>", i);
- }
- Dbprintf("-----------------------------------------");
-
- return ;
+ Dbprintf("-----------------------------------------");
+ Dbprintf("Memory content:");
+ Dbprintf("-----------------------------------------");
+ for(i=0; i<max_blocks; i++) {
+ if(Blocks[i][ALLOC]==1)
+ Dbprintf("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
+ Blocks[i][0], Blocks[i][1], Blocks[i][2], Blocks[i][3], Blocks[i][4], Blocks[i][5], Blocks[i][6], Blocks[i][7],
+ Blocks[i][8], Blocks[i][9], Blocks[i][10], Blocks[i][11], Blocks[i][12], Blocks[i][13], Blocks[i][14], Blocks[i][15]);
+ else
+ Dbprintf("<missing block %d>", i);
+ }
+ Dbprintf("-----------------------------------------");
+
+ return ;
}
//====================================================================
//--------------------------------------------------------------------
uint8_t Prepare_Cmd( uint8_t cmd ) {
- //--------------------------------------------------------------------
+ //--------------------------------------------------------------------
- *forward_ptr++ = 0; //start bit
- *forward_ptr++ = 0; //second pause for 4050 code
+ *forward_ptr++ = 0; //start bit
+ *forward_ptr++ = 0; //second pause for 4050 code
- *forward_ptr++ = cmd;
- cmd >>= 1;
- *forward_ptr++ = cmd;
- cmd >>= 1;
- *forward_ptr++ = cmd;
- cmd >>= 1;
- *forward_ptr++ = cmd;
+ *forward_ptr++ = cmd;
+ cmd >>= 1;
+ *forward_ptr++ = cmd;
+ cmd >>= 1;
+ *forward_ptr++ = cmd;
+ cmd >>= 1;
+ *forward_ptr++ = cmd;
- return 6; //return number of emited bits
+ return 6; //return number of emited bits
}
//====================================================================
//--------------------------------------------------------------------
uint8_t Prepare_Addr( uint8_t addr ) {
- //--------------------------------------------------------------------
+ //--------------------------------------------------------------------
- register uint8_t line_parity;
+ register uint8_t line_parity;
- uint8_t i;
- line_parity = 0;
- for(i=0;i<6;i++) {
- *forward_ptr++ = addr;
- line_parity ^= addr;
- addr >>= 1;
- }
+ uint8_t i;
+ line_parity = 0;
+ for(i=0;i<6;i++) {
+ *forward_ptr++ = addr;
+ line_parity ^= addr;
+ addr >>= 1;
+ }
- *forward_ptr++ = (line_parity & 1);
+ *forward_ptr++ = (line_parity & 1);
- return 7; //return number of emited bits
+ return 7; //return number of emited bits
}
//====================================================================
//--------------------------------------------------------------------
uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) {
- //--------------------------------------------------------------------
-
- register uint8_t line_parity;
- register uint8_t column_parity;
- register uint8_t i, j;
- register uint16_t data;
-
- data = data_low;
- column_parity = 0;
-
- for(i=0; i<4; i++) {
- line_parity = 0;
- for(j=0; j<8; j++) {
- line_parity ^= data;
- column_parity ^= (data & 1) << j;
- *forward_ptr++ = data;
- data >>= 1;
- }
- *forward_ptr++ = line_parity;
- if(i == 1)
- data = data_hi;
- }
-
- for(j=0; j<8; j++) {
- *forward_ptr++ = column_parity;
- column_parity >>= 1;
- }
- *forward_ptr = 0;
-
- return 45; //return number of emited bits
+ //--------------------------------------------------------------------
+
+ register uint8_t line_parity;
+ register uint8_t column_parity;
+ register uint8_t i, j;
+ register uint16_t data;
+
+ data = data_low;
+ column_parity = 0;
+
+ for(i=0; i<4; i++) {
+ line_parity = 0;
+ for(j=0; j<8; j++) {
+ line_parity ^= data;
+ column_parity ^= (data & 1) << j;
+ *forward_ptr++ = data;
+ data >>= 1;
+ }
+ *forward_ptr++ = line_parity;
+ if(i == 1)
+ data = data_hi;
+ }
+
+ for(j=0; j<8; j++) {
+ *forward_ptr++ = column_parity;
+ column_parity >>= 1;
+ }
+ *forward_ptr = 0;
+
+ return 45; //return number of emited bits
}
//====================================================================
//====================================================================
void SendForward(uint8_t fwd_bit_count) {
- fwd_write_ptr = forwardLink_data;
- fwd_bit_sz = fwd_bit_count;
-
- LED_D_ON();
-
- //Field on
- FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
-
- // Give it a bit of time for the resonant antenna to settle.
- // And for the tag to fully power up
- SpinDelay(150);
-
- // force 1st mod pulse (start gap must be longer for 4305)
- fwd_bit_sz--; //prepare next bit modulation
- fwd_write_ptr++;
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
- SpinDelayUs(55*8); //55 cycles off (8us each)for 4305
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on
- SpinDelayUs(16*8); //16 cycles on (8us each)
-
- // now start writting
- while(fwd_bit_sz-- > 0) { //prepare next bit modulation
- if(((*fwd_write_ptr++) & 1) == 1)
- SpinDelayUs(32*8); //32 cycles at 125Khz (8us each)
- else {
- //These timings work for 4469/4269/4305 (with the 55*8 above)
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
- SpinDelayUs(23*8); //16-4 cycles off (8us each)
- FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
- FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on
- SpinDelayUs(9*8); //16 cycles on (8us each)
- }
- }
+ fwd_write_ptr = forwardLink_data;
+ fwd_bit_sz = fwd_bit_count;
+
+ LED_D_ON();
+
+ //Field on
+ FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+
+ // Give it a bit of time for the resonant antenna to settle.
+ // And for the tag to fully power up
+ SpinDelay(150);
+
+ // force 1st mod pulse (start gap must be longer for 4305)
+ fwd_bit_sz--; //prepare next bit modulation
+ fwd_write_ptr++;
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
+ SpinDelayUs(55*8); //55 cycles off (8us each)for 4305
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on
+ SpinDelayUs(16*8); //16 cycles on (8us each)
+
+ // now start writting
+ while(fwd_bit_sz-- > 0) { //prepare next bit modulation
+ if(((*fwd_write_ptr++) & 1) == 1)
+ SpinDelayUs(32*8); //32 cycles at 125Khz (8us each)
+ else {
+ //These timings work for 4469/4269/4305 (with the 55*8 above)
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
+ SpinDelayUs(23*8); //16-4 cycles off (8us each)
+ FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on
+ SpinDelayUs(9*8); //16 cycles on (8us each)
+ }
+ }
}
void EM4xLogin(uint32_t Password) {
- uint8_t fwd_bit_count;
+ uint8_t fwd_bit_count;
- forward_ptr = forwardLink_data;
- fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN );
- fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 );
+ forward_ptr = forwardLink_data;
+ fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN );
+ fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 );
- SendForward(fwd_bit_count);
+ SendForward(fwd_bit_count);
- //Wait for command to complete
- SpinDelay(20);
+ //Wait for command to complete
+ SpinDelay(20);
}
void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
- uint8_t fwd_bit_count;
- uint8_t *dest = (uint8_t *)BigBuf;
- int m=0, i=0;
-
- //If password mode do login
- if (PwdMode == 1) EM4xLogin(Pwd);
-
- forward_ptr = forwardLink_data;
- fwd_bit_count = Prepare_Cmd( FWD_CMD_READ );
- fwd_bit_count += Prepare_Addr( Address );
-
- m = sizeof(BigBuf);
- // Clear destination buffer before sending the command
- memset(dest, 128, m);
- // 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();
-
- SendForward(fwd_bit_count);
-
- // Now do the acquisition
- i = 0;
- for(;;) {
- if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
- AT91C_BASE_SSC->SSC_THR = 0x43;
- }
- if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
- dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
- i++;
- if (i >= m) break;
- }
- }
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
- LED_D_OFF();
+ uint8_t fwd_bit_count;
+ uint8_t *dest = (uint8_t *)BigBuf;
+ int m=0, i=0;
+
+ //If password mode do login
+ if (PwdMode == 1) EM4xLogin(Pwd);
+
+ forward_ptr = forwardLink_data;
+ fwd_bit_count = Prepare_Cmd( FWD_CMD_READ );
+ fwd_bit_count += Prepare_Addr( Address );
+
+ m = sizeof(BigBuf);
+ // Clear destination buffer before sending the command
+ memset(dest, 128, m);
+ // 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();
+
+ SendForward(fwd_bit_count);
+
+ // Now do the acquisition
+ i = 0;
+ for(;;) {
+ if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
+ AT91C_BASE_SSC->SSC_THR = 0x43;
+ }
+ if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
+ dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
+ i++;
+ if (i >= m) break;
+ }
+ }
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
+ LED_D_OFF();
}
void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
- uint8_t fwd_bit_count;
+ uint8_t fwd_bit_count;
- //If password mode do login
- if (PwdMode == 1) EM4xLogin(Pwd);
+ //If password mode do login
+ if (PwdMode == 1) EM4xLogin(Pwd);
- forward_ptr = forwardLink_data;
- fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE );
- fwd_bit_count += Prepare_Addr( Address );
- fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 );
+ forward_ptr = forwardLink_data;
+ fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE );
+ fwd_bit_count += Prepare_Addr( Address );
+ fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 );
- SendForward(fwd_bit_count);
+ SendForward(fwd_bit_count);
- //Wait for write to complete
- SpinDelay(20);
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
- LED_D_OFF();
+ //Wait for write to complete
+ SpinDelay(20);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
+ LED_D_OFF();
}
\r
#include "mifarecmd.h"\r
#include "apps.h"\r
+#include "util.h"\r
\r
//-----------------------------------------------------------------------------\r
// Select, Authenticate, Read a MIFARE tag. \r
\r
void MifareUReadBlock(uint8_t arg0,uint8_t *datain)\r
{\r
- // params\r
uint8_t blockNo = arg0;\r
- \r
- // variables\r
- byte_t isOK = 0;\r
- byte_t dataoutbuf[16];\r
- uint8_t uid[10];\r
+ byte_t dataout[16] = {0x00};\r
+ uint8_t uid[10] = {0x00};\r
uint32_t cuid;\r
\r
- // clear trace\r
- iso14a_clear_trace();\r
- iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
- \r
LED_A_ON();\r
LED_B_OFF();\r
LED_C_OFF();\r
\r
- while (true) {\r
- if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
- break;\r
+ iso14a_clear_trace();\r
+ iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
+ \r
+ int len = iso14443a_select_card(uid, NULL, &cuid);\r
+ if(!len) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");\r
+ //OnError(1);\r
+ return;\r
};\r
\r
- if(mifare_ultra_readblock(cuid, blockNo, dataoutbuf)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Read block error");\r
- break;\r
+ len = mifare_ultra_readblock(cuid, blockNo, dataout);\r
+ if(len) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error");\r
+ //OnError(2);\r
+ return;\r
};\r
\r
- if(mifare_ultra_halt(cuid)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
- break;\r
+ len = mifare_ultra_halt(cuid);\r
+ if(len) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error");\r
+ //OnError(3);\r
+ return;\r
};\r
\r
- isOK = 1;\r
- break;\r
- }\r
- \r
- if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED");\r
- \r
- LED_B_ON();\r
- cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);\r
- LED_B_OFF();\r
+ cmd_send(CMD_ACK,1,0,0,dataout,16);\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
}\r
LEDsoff();\r
}\r
\r
-\r
-void MifareUReadCard(uint8_t arg0, uint8_t *datain)\r
+void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)\r
{\r
// params\r
uint8_t sectorNo = arg0;\r
- \r
- // variables\r
- byte_t isOK = 0;\r
- byte_t dataoutbuf[16 * 4];\r
- uint8_t uid[10];\r
- uint32_t cuid;\r
-\r
- // clear trace\r
- iso14a_clear_trace();\r
-// iso14a_set_tracing(false);\r
-\r
- iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
-\r
- LED_A_ON();\r
- LED_B_OFF();\r
- LED_C_OFF();\r
+ int Pages = arg1;\r
+ int count_Pages = 0;\r
+ byte_t dataout[176] = {0x00};;\r
+ uint8_t uid[10] = {0x00};\r
+ uint32_t cuid;\r
\r
- while (true) {\r
- if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
- break;\r
- };\r
- for(int sec=0;sec<16;sec++){\r
- if(mifare_ultra_readblock(cuid, sectorNo * 4 + sec, dataoutbuf + 4 * sec)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Read block %d error",sec);\r
- break;\r
- };\r
- }\r
- if(mifare_ultra_halt(cuid)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
- break;\r
- };\r
+ LED_A_ON();\r
+ LED_B_OFF();\r
+ LED_C_OFF();\r
\r
- isOK = 1;\r
- break;\r
- }\r
- \r
- if (MF_DBGLEVEL >= 2) DbpString("READ CARD FINISHED");\r
+ if (MF_DBGLEVEL >= MF_DBG_ALL) \r
+ Dbprintf("Pages %d",Pages);\r
+ \r
+ iso14a_clear_trace();\r
+ iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
- LED_B_ON();\r
- cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,64);\r
- LED_B_OFF();\r
+ int len = iso14443a_select_card(uid, NULL, &cuid);\r
+ \r
+ if (!len) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("Can't select card");\r
+ //OnError(1);\r
+ return;\r
+ }\r
+ \r
+ for (int i = 0; i < Pages; i++){\r
+ \r
+ len = mifare_ultra_readblock(cuid, sectorNo * 4 + i, dataout + 4 * i);\r
+ \r
+ if (len) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("Read block %d error",i);\r
+ //OnError(2);\r
+ return;\r
+ } else {\r
+ count_Pages++;\r
+ }\r
+ }\r
+ \r
+ len = mifare_ultra_halt(cuid);\r
+ if (len) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("Halt error");\r
+ //OnError(3);\r
+ return;\r
+ }\r
+ \r
+ if (MF_DBGLEVEL >= MF_DBG_ALL) {\r
+ Dbprintf("Pages read %d", count_Pages);\r
+ }\r
\r
- // Thats it...\r
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
- LEDsoff();\r
+ len = 16*4; //64 bytes\r
+ \r
+ // Read a UL-C\r
+ if (Pages == 44 && count_Pages > 16) \r
+ len = 176;\r
\r
+ cmd_send(CMD_ACK, 1, 0, 0, dataout, len); \r
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+ LEDsoff();\r
}\r
\r
\r
{\r
// params\r
uint8_t blockNo = arg0;\r
- byte_t blockdata[16];\r
+ byte_t blockdata[16] = {0x00};\r
\r
- memset(blockdata,'\0',16);\r
memcpy(blockdata, datain,16);\r
\r
// variables\r
byte_t isOK = 0;\r
- uint8_t uid[10];\r
+ uint8_t uid[10] = {0x00};\r
uint32_t cuid;\r
\r
- // clear trace\r
iso14a_clear_trace();\r
-\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
LED_A_ON();\r
\r
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
\r
- LED_B_ON();\r
cmd_send(CMD_ACK,isOK,0,0,0,0);\r
- LED_B_OFF();\r
-\r
-\r
- // Thats it...\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
-// iso14a_set_tracing(TRUE);\r
}\r
\r
void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)\r
{\r
// params\r
uint8_t blockNo = arg0;\r
- byte_t blockdata[4];\r
+ byte_t blockdata[4] = {0x00};\r
\r
memcpy(blockdata, datain,4);\r
\r
// variables\r
byte_t isOK = 0;\r
- uint8_t uid[10];\r
+ uint8_t uid[10] = {0x00};\r
uint32_t cuid;\r
\r
- // clear trace\r
iso14a_clear_trace();\r
-\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
\r
LED_A_ON();\r
\r
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
\r
- LED_B_ON();\r
cmd_send(CMD_ACK,isOK,0,0,0,0);\r
- LED_B_OFF();\r
-\r
- // Thats it...\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
}\r
return len;\r
}\r
\r
-// mifare commands\r
+// mifare classic commands\r
int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested) \r
{\r
return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL);\r
int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
- // variables
uint16_t len;
uint8_t bt[2];
-
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();\r
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
// command MIFARE_CLASSIC_READBLOCK
len = mifare_sendcmd_short(NULL, 1, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL);
if (len == 1) {
- if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
return 1;
}
if (len != 18) {
- if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: card timeout. len: %x", len);
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("Cmd Error: card timeout. len: %x", len);
return 2;
}
memcpy(bt, receivedAnswer + 16, 2);
AppendCrc14443a(receivedAnswer, 16);
if (bt[0] != receivedAnswer[16] || bt[1] != receivedAnswer[17]) {
- if (MF_DBGLEVEL >= 1) Dbprintf("Cmd CRC response error.");
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("Cmd CRC response error.");
return 3;
}
int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
- // variables
uint16_t len;
uint8_t par[3] = {0}; // enough for 18 parity bits
- uint8_t d_block[18];
+ uint8_t d_block[18] = {0x00};
uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf();\r
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
len = mifare_sendcmd_short(NULL, true, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL);
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
- if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]);
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("Cmd Addr Error: %02x", receivedAnswer[0]);
return 1;
}
- memset(d_block,'\0',18);
memcpy(d_block, blockData, 16);
AppendCrc14443a(d_block, 16);
ReaderTransmitPar(d_block, sizeof(d_block), par, NULL);
- // Receive the response
len = ReaderReceive(receivedAnswer, receivedAnswerPar);
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
- if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("Cmd Data Error: %02x %d", receivedAnswer[0],len);
return 2;
}
-
return 0;
}
int mifare_ultra_special_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
uint16_t len;
- uint8_t d_block[8];
+ uint8_t d_block[8] = {0x00};
uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf();\r
uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
// command MIFARE_CLASSIC_WRITEBLOCK
- memset(d_block,'\0',8);
d_block[0]= blockNo;
memcpy(d_block+1,blockData,4);
AppendCrc14443a(d_block, 6);
- //i know the data send here is correct
len = mifare_sendcmd_short_special(NULL, 1, 0xA2, d_block, receivedAnswer, receivedAnswerPar, NULL);
if (receivedAnswer[0] != 0x0A) { // 0x0a - ACK
- if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);
return 1;
}
\r return 0;
\r
len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);\r
if (len != 0) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("halt error. response len: %x", len); \r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("halt error. response len: %x", len); \r
return 1;\r
}\r
\r
len = mifare_sendcmd_short(NULL, true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
if (len != 0) {
- if (MF_DBGLEVEL >= 1) Dbprintf("halt error. response len: %x", len);
+ if (MF_DBGLEVEL >= MF_DBG_ERROR)\r
+ Dbprintf("halt error. response len: %x", len);
return 1;
}
-
return 0;
}
return 0;
}
+void memxor(uint8_t * dest, uint8_t * src, size_t len) {
+ for( ; len > 0; len--,dest++,src++)
+ *dest ^= *src;
+}
+
int strlen(const char *str)
{
int l = 0;
RAMFUNC void *memcpy(void *dest, const void *src, int len);
void *memset(void *dest, int c, int len);
RAMFUNC int memcmp(const void *av, const void *bv, int len);
+void memxor(uint8_t * dest, uint8_t * src, size_t len);
char *strncat(char *dest, const char *src, unsigned int n);
char *strcat(char *dest, const char *src);
void strreverse(char s[]);
#include "string.h"
#include "apps.h"
+
+
+void print_result(char *name, uint8_t *buf, size_t len) {
+ uint8_t *p = buf;
+
+ if ( len % 16 == 0 ) {
+ for(; p-buf < len; p += 16)
+ Dbprintf("[%s:%d/%d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
+ name,
+ p-buf,
+ len,
+ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]
+ );
+ }
+ else {
+ for(; p-buf < len; p += 8)
+ Dbprintf("[%s:%d/%d] %02x %02x %02x %02x %02x %02x %02x %02x", name, p-buf, len, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+ }
+}
+
size_t nbytes(size_t nbits) {
return (nbits/8)+((nbits%8)>0);
}
return num;
}
+// RotateLeft - Ultralight, Desfire
+void rol(uint8_t *data, const size_t len){
+ uint8_t first = data[0];
+ for (size_t i = 0; i < len-1; i++) {
+ data[i] = data[i+1];
+ }
+ data[len-1] = first;
+}
+void lsl (uint8_t *data, size_t len) {
+ for (size_t n = 0; n < len - 1; n++) {
+ data[n] = (data[n] << 1) | (data[n+1] >> 7);
+ }
+ data[len - 1] <<= 1;
+}
+
+int32_t le24toh (uint8_t data[3])
+{
+ return (data[2] << 16) | (data[1] << 8) | data[0];
+}
+
void LEDsoff()
{
LED_A_OFF();
#define BUTTON_DOUBLE_CLICK -2
#define BUTTON_ERROR -99
+void print_result(char *name, uint8_t *buf, size_t len);
size_t nbytes(size_t nbits);
uint32_t SwapBits(uint32_t value, int nrbits);
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
uint64_t bytes_to_num(uint8_t* src, size_t len);
+void rol(uint8_t *data, const size_t len);
+void lsl (uint8_t *data, size_t len);
+int32_t le24toh (uint8_t data[3]);
void SpinDelay(int ms);
void SpinDelayUs(int us);
switch(c->cmd) {
case CMD_DEVICE_INFO: {
dont_ack = 1;
-// c->cmd = CMD_DEVICE_INFO;
arg0 = DEVICE_INFO_FLAG_BOOTROM_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM |
DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH;
if(common_area.flags.osimage_present) {
arg0 |= DEVICE_INFO_FLAG_OSIMAGE_PRESENT;
}
-// UsbSendPacket(packet, len);
cmd_send(CMD_DEVICE_INFO,arg0,1,2,0,0);
} break;
case CMD_FINISH_WRITE: {
uint32_t* flash_mem = (uint32_t*)(&_flash_start);
-// p = (volatile uint32_t *)&_flash_start;
for (size_t j=0; j<2; j++) {
for(i = 0+(64*j); i < 64+(64*j); i++) {
- //p[i+60] = c->d.asDwords[i];
flash_mem[i] = c->d.asDwords[i];
}
if( ((flash_address+AT91C_IFLASH_PAGE_SIZE-1) >= end_addr) || (flash_address < start_addr) ) {
/* Disallow write */
dont_ack = 1;
- // c->cmd = CMD_NACK;
- // UsbSendPacket(packet, len);
cmd_send(CMD_NACK,0,0,0,0,0);
} else {
uint32_t page_n = (flash_address - ((uint32_t)flash_mem)) / AT91C_IFLASH_PAGE_SIZE;
AT91C_BASE_EFC0->EFC_FCR = MC_FLASH_COMMAND_KEY |
MC_FLASH_COMMAND_PAGEN(page_n) |
AT91C_MC_FCMD_START_PROG;
- // arg0 = (address - ((uint32_t)flash_s));
}
// Wait until flashing of page finishes
while(!((sr = AT91C_BASE_EFC0->EFC_FSR) & AT91C_MC_FRDY));
if(sr & (AT91C_MC_LOCKE | AT91C_MC_PROGE)) {
dont_ack = 1;
- // c->cmd = CMD_NACK;
cmd_send(CMD_NACK,0,0,0,0,0);
- // UsbSendPacket(packet, len);
}
}
} break;
case CMD_HARDWARE_RESET: {
-// USB_D_PLUS_PULLUP_OFF();
usb_disable();
AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
} break;
} else {
start_addr = end_addr = 0;
dont_ack = 1;
-// c->cmd = CMD_NACK;
-// UsbSendPacket(packet, len);
cmd_send(CMD_NACK,0,0,0,0,0);
}
}
}
if(!dont_ack) {
-// c->cmd = CMD_ACK;
-// UsbSendPacket(packet, len);
cmd_send(CMD_ACK,arg0,0,0,0,0);
}
}
usb_enable();
for (volatile size_t i=0; i<0x100000; i++);
-// UsbStart();
for(;;) {
WDT_HIT();
if (usb_poll()) {
rx_len = usb_read(rx,sizeof(UsbCommand));
if (rx_len) {
-// DbpString("starting to flash");
UsbPacketReceived(rx,rx_len);
}
}
-// UsbPoll(TRUE);
-
if(!externally_entered && !BUTTON_PRESS()) {
/* Perform a reset to leave flash mode */
-// USB_D_PLUS_PULLUP_OFF();
usb_disable();
LED_B_ON();
AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
VPATH = ../common
OBJDIR = obj
-LDLIBS = -L/opt/local/lib -L/usr/local/lib ../liblua/liblua.a -lreadline -lpthread -lm -lcrypto
+LDLIBS = -L/opt/local/lib -L/usr/local/lib ../liblua/liblua.a -lreadline -lpthread -lm
LDFLAGS = $(COMMON_FLAGS)
-CFLAGS = -std=c99 -lcrypto -I. -I../include -I../common -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4
+CFLAGS = -std=c99 -I. -I../include -I../common -I/opt/local/include -I../liblua -Wall $(COMMON_FLAGS) -g -O4
LUAPLATFORM = generic
ifneq (,$(findstring MINGW,$(platform)))
scripting.c\
cmdscript.c\
pm3_bitlib.c\
+ aes.c\
COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
--- /dev/null
+/*
+ * FIPS-197 compliant AES implementation
+ *
+ * Copyright (C) 2006-2014, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+/*
+ * The AES block cipher was designed by Vincent Rijmen and Joan Daemen.
+ *
+ * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf
+ * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
+ */
+
+#if !defined(POLARSSL_CONFIG_FILE)
+#include "polarssl_config.h"
+#else
+#include POLARSSL_CONFIG_FILE
+#endif
+
+#if defined(POLARSSL_AES_C)
+
+#include "aes.h"
+#if defined(POLARSSL_PADLOCK_C)
+#include "polarssl/padlock.h"
+#endif
+#if defined(POLARSSL_AESNI_C)
+#include "polarssl/aesni.h"
+#endif
+
+#if defined(POLARSSL_PLATFORM_C)
+#include "polarssl/platform.h"
+#else
+#define polarssl_printf printf
+#endif
+
+#if !defined(POLARSSL_AES_ALT)
+
+/* Implementation that should never be optimized out by the compiler */
+static void polarssl_zeroize( void *v, size_t n ) {
+ volatile unsigned char *p = v; while( n-- ) *p++ = 0;
+}
+
+/*
+ * 32-bit integer manipulation macros (little endian)
+ */
+#ifndef GET_UINT32_LE
+#define GET_UINT32_LE(n,b,i) \
+{ \
+ (n) = ( (uint32_t) (b)[(i) ] ) \
+ | ( (uint32_t) (b)[(i) + 1] << 8 ) \
+ | ( (uint32_t) (b)[(i) + 2] << 16 ) \
+ | ( (uint32_t) (b)[(i) + 3] << 24 ); \
+}
+#endif
+
+#ifndef PUT_UINT32_LE
+#define PUT_UINT32_LE(n,b,i) \
+{ \
+ (b)[(i) ] = (unsigned char) ( (n) ); \
+ (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
+ (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
+ (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
+}
+#endif
+
+#if defined(POLARSSL_PADLOCK_C) && \
+ ( defined(POLARSSL_HAVE_X86) || defined(PADLOCK_ALIGN16) )
+static int aes_padlock_ace = -1;
+#endif
+
+#if defined(POLARSSL_AES_ROM_TABLES)
+/*
+ * Forward S-box
+ */
+static const unsigned char FSb[256] =
+{
+ 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
+ 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
+ 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
+ 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
+ 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
+ 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
+ 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
+ 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
+ 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
+ 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
+ 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
+ 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
+ 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
+ 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
+ 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
+ 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
+ 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
+ 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
+ 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
+ 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
+ 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
+ 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
+ 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
+ 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
+ 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
+ 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
+ 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
+ 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
+ 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
+ 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
+ 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
+ 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
+};
+
+/*
+ * Forward tables
+ */
+#define FT \
+\
+ V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \
+ V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \
+ V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \
+ V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \
+ V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \
+ V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \
+ V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \
+ V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \
+ V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \
+ V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \
+ V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \
+ V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \
+ V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \
+ V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \
+ V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \
+ V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \
+ V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \
+ V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \
+ V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \
+ V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \
+ V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \
+ V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \
+ V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \
+ V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \
+ V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \
+ V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \
+ V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \
+ V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \
+ V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \
+ V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \
+ V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \
+ V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \
+ V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \
+ V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \
+ V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \
+ V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \
+ V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \
+ V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \
+ V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \
+ V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \
+ V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \
+ V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \
+ V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \
+ V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \
+ V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \
+ V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \
+ V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \
+ V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \
+ V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \
+ V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \
+ V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \
+ V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \
+ V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \
+ V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \
+ V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \
+ V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \
+ V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \
+ V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \
+ V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \
+ V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \
+ V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \
+ V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \
+ V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \
+ V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C)
+
+#define V(a,b,c,d) 0x##a##b##c##d
+static const uint32_t FT0[256] = { FT };
+#undef V
+
+#define V(a,b,c,d) 0x##b##c##d##a
+static const uint32_t FT1[256] = { FT };
+#undef V
+
+#define V(a,b,c,d) 0x##c##d##a##b
+static const uint32_t FT2[256] = { FT };
+#undef V
+
+#define V(a,b,c,d) 0x##d##a##b##c
+static const uint32_t FT3[256] = { FT };
+#undef V
+
+#undef FT
+
+/*
+ * Reverse S-box
+ */
+static const unsigned char RSb[256] =
+{
+ 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
+ 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
+ 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
+ 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
+ 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
+ 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
+ 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
+ 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
+ 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
+ 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
+ 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
+ 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
+ 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
+ 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
+ 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
+ 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
+ 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
+ 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
+ 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
+ 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
+ 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
+ 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
+ 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
+ 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
+ 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
+ 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
+ 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
+ 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
+ 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
+ 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
+ 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
+ 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D
+};
+
+/*
+ * Reverse tables
+ */
+#define RT \
+\
+ V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \
+ V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \
+ V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \
+ V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \
+ V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \
+ V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \
+ V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \
+ V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \
+ V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \
+ V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \
+ V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \
+ V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \
+ V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \
+ V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \
+ V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \
+ V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \
+ V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \
+ V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \
+ V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \
+ V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \
+ V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \
+ V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \
+ V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \
+ V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \
+ V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \
+ V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \
+ V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \
+ V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \
+ V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \
+ V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \
+ V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \
+ V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \
+ V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \
+ V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \
+ V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \
+ V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \
+ V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \
+ V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \
+ V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \
+ V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \
+ V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \
+ V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \
+ V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \
+ V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \
+ V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \
+ V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \
+ V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \
+ V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \
+ V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \
+ V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \
+ V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \
+ V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \
+ V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \
+ V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \
+ V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \
+ V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \
+ V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \
+ V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \
+ V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \
+ V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \
+ V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \
+ V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \
+ V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \
+ V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0)
+
+#define V(a,b,c,d) 0x##a##b##c##d
+static const uint32_t RT0[256] = { RT };
+#undef V
+
+#define V(a,b,c,d) 0x##b##c##d##a
+static const uint32_t RT1[256] = { RT };
+#undef V
+
+#define V(a,b,c,d) 0x##c##d##a##b
+static const uint32_t RT2[256] = { RT };
+#undef V
+
+#define V(a,b,c,d) 0x##d##a##b##c
+static const uint32_t RT3[256] = { RT };
+#undef V
+
+#undef RT
+
+/*
+ * Round constants
+ */
+static const uint32_t RCON[10] =
+{
+ 0x00000001, 0x00000002, 0x00000004, 0x00000008,
+ 0x00000010, 0x00000020, 0x00000040, 0x00000080,
+ 0x0000001B, 0x00000036
+};
+
+#else /* POLARSSL_AES_ROM_TABLES */
+
+/*
+ * Forward S-box & tables
+ */
+static unsigned char FSb[256];
+static uint32_t FT0[256];
+static uint32_t FT1[256];
+static uint32_t FT2[256];
+static uint32_t FT3[256];
+
+/*
+ * Reverse S-box & tables
+ */
+static unsigned char RSb[256];
+static uint32_t RT0[256];
+static uint32_t RT1[256];
+static uint32_t RT2[256];
+static uint32_t RT3[256];
+
+/*
+ * Round constants
+ */
+static uint32_t RCON[10];
+
+/*
+ * Tables generation code
+ */
+#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 )
+#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) )
+#define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 )
+
+static int aes_init_done = 0;
+
+static void aes_gen_tables( void )
+{
+ int i, x, y, z;
+ int pow[256];
+ int log[256];
+
+ /*
+ * compute pow and log tables over GF(2^8)
+ */
+ for( i = 0, x = 1; i < 256; i++ )
+ {
+ pow[i] = x;
+ log[x] = i;
+ x = ( x ^ XTIME( x ) ) & 0xFF;
+ }
+
+ /*
+ * calculate the round constants
+ */
+ for( i = 0, x = 1; i < 10; i++ )
+ {
+ RCON[i] = (uint32_t) x;
+ x = XTIME( x ) & 0xFF;
+ }
+
+ /*
+ * generate the forward and reverse S-boxes
+ */
+ FSb[0x00] = 0x63;
+ RSb[0x63] = 0x00;
+
+ for( i = 1; i < 256; i++ )
+ {
+ x = pow[255 - log[i]];
+
+ y = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+ x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+ x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+ x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF;
+ x ^= y ^ 0x63;
+
+ FSb[i] = (unsigned char) x;
+ RSb[x] = (unsigned char) i;
+ }
+
+ /*
+ * generate the forward and reverse tables
+ */
+ for( i = 0; i < 256; i++ )
+ {
+ x = FSb[i];
+ y = XTIME( x ) & 0xFF;
+ z = ( y ^ x ) & 0xFF;
+
+ FT0[i] = ( (uint32_t) y ) ^
+ ( (uint32_t) x << 8 ) ^
+ ( (uint32_t) x << 16 ) ^
+ ( (uint32_t) z << 24 );
+
+ FT1[i] = ROTL8( FT0[i] );
+ FT2[i] = ROTL8( FT1[i] );
+ FT3[i] = ROTL8( FT2[i] );
+
+ x = RSb[i];
+
+ RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^
+ ( (uint32_t) MUL( 0x09, x ) << 8 ) ^
+ ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^
+ ( (uint32_t) MUL( 0x0B, x ) << 24 );
+
+ RT1[i] = ROTL8( RT0[i] );
+ RT2[i] = ROTL8( RT1[i] );
+ RT3[i] = ROTL8( RT2[i] );
+ }
+}
+
+#endif /* POLARSSL_AES_ROM_TABLES */
+
+void aes_init( aes_context *ctx )
+{
+ memset( ctx, 0, sizeof( aes_context ) );
+}
+
+void aes_free( aes_context *ctx )
+{
+ if( ctx == NULL )
+ return;
+
+ polarssl_zeroize( ctx, sizeof( aes_context ) );
+}
+
+/*
+ * AES key schedule (encryption)
+ */
+int aes_setkey_enc( aes_context *ctx, const unsigned char *key,
+ unsigned int keysize )
+{
+ unsigned int i;
+ uint32_t *RK;
+
+#if !defined(POLARSSL_AES_ROM_TABLES)
+ if( aes_init_done == 0 )
+ {
+ aes_gen_tables();
+ aes_init_done = 1;
+
+ }
+#endif
+
+ switch( keysize )
+ {
+ case 128: ctx->nr = 10; break;
+ case 192: ctx->nr = 12; break;
+ case 256: ctx->nr = 14; break;
+ default : return( POLARSSL_ERR_AES_INVALID_KEY_LENGTH );
+ }
+
+#if defined(POLARSSL_PADLOCK_C) && defined(PADLOCK_ALIGN16)
+ if( aes_padlock_ace == -1 )
+ aes_padlock_ace = padlock_supports( PADLOCK_ACE );
+
+ if( aes_padlock_ace )
+ ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf );
+ else
+#endif
+ ctx->rk = RK = ctx->buf;
+
+#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
+ if( aesni_supports( POLARSSL_AESNI_AES ) )
+ return( aesni_setkey_enc( (unsigned char *) ctx->rk, key, keysize ) );
+#endif
+
+ for( i = 0; i < ( keysize >> 5 ); i++ )
+ {
+ GET_UINT32_LE( RK[i], key, i << 2 );
+ }
+
+ switch( ctx->nr )
+ {
+ case 10:
+
+ for( i = 0; i < 10; i++, RK += 4 )
+ {
+ RK[4] = RK[0] ^ RCON[i] ^
+ ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^
+ ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 );
+
+ RK[5] = RK[1] ^ RK[4];
+ RK[6] = RK[2] ^ RK[5];
+ RK[7] = RK[3] ^ RK[6];
+ }
+ break;
+
+ case 12:
+
+ for( i = 0; i < 8; i++, RK += 6 )
+ {
+ RK[6] = RK[0] ^ RCON[i] ^
+ ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^
+ ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 );
+
+ RK[7] = RK[1] ^ RK[6];
+ RK[8] = RK[2] ^ RK[7];
+ RK[9] = RK[3] ^ RK[8];
+ RK[10] = RK[4] ^ RK[9];
+ RK[11] = RK[5] ^ RK[10];
+ }
+ break;
+
+ case 14:
+
+ for( i = 0; i < 7; i++, RK += 8 )
+ {
+ RK[8] = RK[0] ^ RCON[i] ^
+ ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^
+ ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 );
+
+ RK[9] = RK[1] ^ RK[8];
+ RK[10] = RK[2] ^ RK[9];
+ RK[11] = RK[3] ^ RK[10];
+
+ RK[12] = RK[4] ^
+ ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^
+ ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
+
+ RK[13] = RK[5] ^ RK[12];
+ RK[14] = RK[6] ^ RK[13];
+ RK[15] = RK[7] ^ RK[14];
+ }
+ break;
+ }
+
+ return( 0 );
+}
+
+/*
+ * AES key schedule (decryption)
+ */
+int aes_setkey_dec( aes_context *ctx, const unsigned char *key,
+ unsigned int keysize )
+{
+ int i, j, ret;
+ aes_context cty;
+ uint32_t *RK;
+ uint32_t *SK;
+
+ aes_init( &cty );
+
+#if defined(POLARSSL_PADLOCK_C) && defined(PADLOCK_ALIGN16)
+ if( aes_padlock_ace == -1 )
+ aes_padlock_ace = padlock_supports( PADLOCK_ACE );
+
+ if( aes_padlock_ace )
+ ctx->rk = RK = PADLOCK_ALIGN16( ctx->buf );
+ else
+#endif
+ ctx->rk = RK = ctx->buf;
+
+ /* Also checks keysize */
+ if( ( ret = aes_setkey_enc( &cty, key, keysize ) ) != 0 )
+ goto exit;
+
+ ctx->nr = cty.nr;
+
+#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
+ if( aesni_supports( POLARSSL_AESNI_AES ) )
+ {
+ aesni_inverse_key( (unsigned char *) ctx->rk,
+ (const unsigned char *) cty.rk, ctx->nr );
+ goto exit;
+ }
+#endif
+
+ SK = cty.rk + cty.nr * 4;
+
+ *RK++ = *SK++;
+ *RK++ = *SK++;
+ *RK++ = *SK++;
+ *RK++ = *SK++;
+
+ for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 )
+ {
+ for( j = 0; j < 4; j++, SK++ )
+ {
+ *RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^
+ RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^
+ RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^
+ RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ];
+ }
+ }
+
+ *RK++ = *SK++;
+ *RK++ = *SK++;
+ *RK++ = *SK++;
+ *RK++ = *SK++;
+
+exit:
+ aes_free( &cty );
+
+ return( ret );
+}
+
+#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
+{ \
+ X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \
+ FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \
+ FT2[ ( Y2 >> 16 ) & 0xFF ] ^ \
+ FT3[ ( Y3 >> 24 ) & 0xFF ]; \
+ \
+ X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \
+ FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \
+ FT2[ ( Y3 >> 16 ) & 0xFF ] ^ \
+ FT3[ ( Y0 >> 24 ) & 0xFF ]; \
+ \
+ X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \
+ FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \
+ FT2[ ( Y0 >> 16 ) & 0xFF ] ^ \
+ FT3[ ( Y1 >> 24 ) & 0xFF ]; \
+ \
+ X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \
+ FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \
+ FT2[ ( Y1 >> 16 ) & 0xFF ] ^ \
+ FT3[ ( Y2 >> 24 ) & 0xFF ]; \
+}
+
+#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \
+{ \
+ X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^ \
+ RT1[ ( Y3 >> 8 ) & 0xFF ] ^ \
+ RT2[ ( Y2 >> 16 ) & 0xFF ] ^ \
+ RT3[ ( Y1 >> 24 ) & 0xFF ]; \
+ \
+ X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^ \
+ RT1[ ( Y0 >> 8 ) & 0xFF ] ^ \
+ RT2[ ( Y3 >> 16 ) & 0xFF ] ^ \
+ RT3[ ( Y2 >> 24 ) & 0xFF ]; \
+ \
+ X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^ \
+ RT1[ ( Y1 >> 8 ) & 0xFF ] ^ \
+ RT2[ ( Y0 >> 16 ) & 0xFF ] ^ \
+ RT3[ ( Y3 >> 24 ) & 0xFF ]; \
+ \
+ X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^ \
+ RT1[ ( Y2 >> 8 ) & 0xFF ] ^ \
+ RT2[ ( Y1 >> 16 ) & 0xFF ] ^ \
+ RT3[ ( Y0 >> 24 ) & 0xFF ]; \
+}
+
+/*
+ * AES-ECB block encryption/decryption
+ */
+int aes_crypt_ecb( aes_context *ctx,
+ int mode,
+ const unsigned char input[16],
+ unsigned char output[16] )
+{
+ int i;
+ uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
+
+#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64)
+ if( aesni_supports( POLARSSL_AESNI_AES ) )
+ return( aesni_crypt_ecb( ctx, mode, input, output ) );
+#endif
+
+#if defined(POLARSSL_PADLOCK_C) && defined(POLARSSL_HAVE_X86)
+ if( aes_padlock_ace )
+ {
+ if( padlock_xcryptecb( ctx, mode, input, output ) == 0 )
+ return( 0 );
+
+ // If padlock data misaligned, we just fall back to
+ // unaccelerated mode
+ //
+ }
+#endif
+
+ RK = ctx->rk;
+
+ GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++;
+ GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++;
+ GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++;
+ GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++;
+
+ if( mode == AES_DECRYPT )
+ {
+ for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
+ {
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+ AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
+ }
+
+ AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+
+ X0 = *RK++ ^ \
+ ( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^
+ ( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
+
+ X1 = *RK++ ^ \
+ ( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^
+ ( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
+
+ X2 = *RK++ ^ \
+ ( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^
+ ( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
+
+ X3 = *RK++ ^ \
+ ( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^
+ ( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
+ }
+ else /* AES_ENCRYPT */
+ {
+ for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- )
+ {
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+ AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 );
+ }
+
+ AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 );
+
+ X0 = *RK++ ^ \
+ ( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^
+ ( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 );
+
+ X1 = *RK++ ^ \
+ ( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^
+ ( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 );
+
+ X2 = *RK++ ^ \
+ ( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^
+ ( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 );
+
+ X3 = *RK++ ^ \
+ ( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^
+ ( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^
+ ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^
+ ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 );
+ }
+
+ PUT_UINT32_LE( X0, output, 0 );
+ PUT_UINT32_LE( X1, output, 4 );
+ PUT_UINT32_LE( X2, output, 8 );
+ PUT_UINT32_LE( X3, output, 12 );
+
+ return( 0 );
+}
+
+#if defined(POLARSSL_CIPHER_MODE_CBC)
+/*
+ * AES-CBC buffer encryption/decryption
+ */
+int aes_crypt_cbc( aes_context *ctx,
+ int mode,
+ size_t length,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output )
+{
+ int i;
+ unsigned char temp[16];
+
+ if( length % 16 )
+ return( POLARSSL_ERR_AES_INVALID_INPUT_LENGTH );
+
+#if defined(POLARSSL_PADLOCK_C) && defined(POLARSSL_HAVE_X86)
+ if( aes_padlock_ace )
+ {
+ if( padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 )
+ return( 0 );
+
+ // If padlock data misaligned, we just fall back to
+ // unaccelerated mode
+ //
+ }
+#endif
+
+ if( mode == AES_DECRYPT )
+ {
+ while( length > 0 )
+ {
+ memcpy( temp, input, 16 );
+ aes_crypt_ecb( ctx, mode, input, output );
+
+ for( i = 0; i < 16; i++ )
+ output[i] = (unsigned char)( output[i] ^ iv[i] );
+
+ memcpy( iv, temp, 16 );
+
+ input += 16;
+ output += 16;
+ length -= 16;
+ }
+ }
+ else
+ {
+ while( length > 0 )
+ {
+ for( i = 0; i < 16; i++ )
+ output[i] = (unsigned char)( input[i] ^ iv[i] );
+
+ aes_crypt_ecb( ctx, mode, output, output );
+ memcpy( iv, output, 16 );
+
+ input += 16;
+ output += 16;
+ length -= 16;
+ }
+ }
+
+ return( 0 );
+}
+#endif /* POLARSSL_CIPHER_MODE_CBC */
+
+#if defined(POLARSSL_CIPHER_MODE_CFB)
+/*
+ * AES-CFB128 buffer encryption/decryption
+ */
+int aes_crypt_cfb128( aes_context *ctx,
+ int mode,
+ size_t length,
+ size_t *iv_off,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output )
+{
+ int c;
+ size_t n = *iv_off;
+
+ if( mode == AES_DECRYPT )
+ {
+ while( length-- )
+ {
+ if( n == 0 )
+ aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv );
+
+ c = *input++;
+ *output++ = (unsigned char)( c ^ iv[n] );
+ iv[n] = (unsigned char) c;
+
+ n = ( n + 1 ) & 0x0F;
+ }
+ }
+ else
+ {
+ while( length-- )
+ {
+ if( n == 0 )
+ aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv );
+
+ iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
+
+ n = ( n + 1 ) & 0x0F;
+ }
+ }
+
+ *iv_off = n;
+
+ return( 0 );
+}
+
+/*
+ * AES-CFB8 buffer encryption/decryption
+ */
+#include <stdio.h>
+int aes_crypt_cfb8( aes_context *ctx,
+ int mode,
+ size_t length,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output )
+{
+ unsigned char c;
+ unsigned char ov[17];
+
+ while( length-- )
+ {
+ memcpy( ov, iv, 16 );
+ aes_crypt_ecb( ctx, AES_ENCRYPT, iv, iv );
+
+ if( mode == AES_DECRYPT )
+ ov[16] = *input;
+
+ c = *output++ = (unsigned char)( iv[0] ^ *input++ );
+
+ if( mode == AES_ENCRYPT )
+ ov[16] = c;
+
+ memcpy( iv, ov + 1, 16 );
+ }
+
+ return( 0 );
+}
+#endif /*POLARSSL_CIPHER_MODE_CFB */
+
+#if defined(POLARSSL_CIPHER_MODE_CTR)
+/*
+ * AES-CTR buffer encryption/decryption
+ */
+int aes_crypt_ctr( aes_context *ctx,
+ size_t length,
+ size_t *nc_off,
+ unsigned char nonce_counter[16],
+ unsigned char stream_block[16],
+ const unsigned char *input,
+ unsigned char *output )
+{
+ int c, i;
+ size_t n = *nc_off;
+
+ while( length-- )
+ {
+ if( n == 0 ) {
+ aes_crypt_ecb( ctx, AES_ENCRYPT, nonce_counter, stream_block );
+
+ for( i = 16; i > 0; i-- )
+ if( ++nonce_counter[i - 1] != 0 )
+ break;
+ }
+ c = *input++;
+ *output++ = (unsigned char)( c ^ stream_block[n] );
+
+ n = ( n + 1 ) & 0x0F;
+ }
+
+ *nc_off = n;
+
+ return( 0 );
+}
+#endif /* POLARSSL_CIPHER_MODE_CTR */
+
+#endif /* !POLARSSL_AES_ALT */
+
+#if defined(POLARSSL_SELF_TEST)
+
+#include <stdio.h>
+
+/*
+ * AES test vectors from:
+ *
+ * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip
+ */
+static const unsigned char aes_test_ecb_dec[3][16] =
+{
+ { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58,
+ 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 },
+ { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2,
+ 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 },
+ { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D,
+ 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE }
+};
+
+static const unsigned char aes_test_ecb_enc[3][16] =
+{
+ { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73,
+ 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F },
+ { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11,
+ 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 },
+ { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D,
+ 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 }
+};
+
+#if defined(POLARSSL_CIPHER_MODE_CBC)
+static const unsigned char aes_test_cbc_dec[3][16] =
+{
+ { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73,
+ 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 },
+ { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75,
+ 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B },
+ { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75,
+ 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 }
+};
+
+static const unsigned char aes_test_cbc_enc[3][16] =
+{
+ { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84,
+ 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D },
+ { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB,
+ 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 },
+ { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5,
+ 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 }
+};
+#endif /* POLARSSL_CIPHER_MODE_CBC */
+
+#if defined(POLARSSL_CIPHER_MODE_CFB)
+/*
+ * AES-CFB128 test vectors from:
+ *
+ * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
+ */
+static const unsigned char aes_test_cfb128_key[3][32] =
+{
+ { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6,
+ 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C },
+ { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52,
+ 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5,
+ 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B },
+ { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE,
+ 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81,
+ 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7,
+ 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 }
+};
+
+static const unsigned char aes_test_cfb128_iv[16] =
+{
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
+};
+
+static const unsigned char aes_test_cfb128_pt[64] =
+{
+ 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
+ 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
+ 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C,
+ 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51,
+ 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11,
+ 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF,
+ 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17,
+ 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10
+};
+
+static const unsigned char aes_test_cfb128_ct[3][64] =
+{
+ { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20,
+ 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A,
+ 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F,
+ 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B,
+ 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40,
+ 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF,
+ 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E,
+ 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 },
+ { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB,
+ 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74,
+ 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21,
+ 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A,
+ 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1,
+ 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9,
+ 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0,
+ 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF },
+ { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B,
+ 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60,
+ 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8,
+ 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B,
+ 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92,
+ 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9,
+ 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8,
+ 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 }
+};
+#endif /* POLARSSL_CIPHER_MODE_CFB */
+
+#if defined(POLARSSL_CIPHER_MODE_CTR)
+/*
+ * AES-CTR test vectors from:
+ *
+ * http://www.faqs.org/rfcs/rfc3686.html
+ */
+
+static const unsigned char aes_test_ctr_key[3][16] =
+{
+ { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC,
+ 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E },
+ { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7,
+ 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 },
+ { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
+ 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC }
+};
+
+static const unsigned char aes_test_ctr_nonce_counter[3][16] =
+{
+ { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
+ { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59,
+ 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 },
+ { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F,
+ 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 }
+};
+
+static const unsigned char aes_test_ctr_pt[3][48] =
+{
+ { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62,
+ 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 },
+
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F },
+
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+ 0x20, 0x21, 0x22, 0x23 }
+};
+
+static const unsigned char aes_test_ctr_ct[3][48] =
+{
+ { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79,
+ 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 },
+ { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9,
+ 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88,
+ 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8,
+ 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 },
+ { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9,
+ 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7,
+ 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36,
+ 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53,
+ 0x25, 0xB2, 0x07, 0x2F }
+};
+
+static const int aes_test_ctr_len[3] =
+ { 16, 32, 36 };
+#endif /* POLARSSL_CIPHER_MODE_CTR */
+
+/*
+ * Checkup routine
+ */
+int aes_self_test( int verbose )
+{
+ int ret = 0, i, j, u, v;
+ unsigned char key[32];
+ unsigned char buf[64];
+ unsigned char iv[16];
+#if defined(POLARSSL_CIPHER_MODE_CBC)
+ unsigned char prv[16];
+#endif
+#if defined(POLARSSL_CIPHER_MODE_CTR) || defined(POLARSSL_CIPHER_MODE_CFB)
+ size_t offset;
+#endif
+#if defined(POLARSSL_CIPHER_MODE_CTR)
+ int len;
+ unsigned char nonce_counter[16];
+ unsigned char stream_block[16];
+#endif
+ aes_context ctx;
+
+ memset( key, 0, 32 );
+ aes_init( &ctx );
+
+ /*
+ * ECB mode
+ */
+ for( i = 0; i < 6; i++ )
+ {
+ u = i >> 1;
+ v = i & 1;
+
+ if( verbose != 0 )
+ polarssl_printf( " AES-ECB-%3d (%s): ", 128 + u * 64,
+ ( v == AES_DECRYPT ) ? "dec" : "enc" );
+
+ memset( buf, 0, 16 );
+
+ if( v == AES_DECRYPT )
+ {
+ aes_setkey_dec( &ctx, key, 128 + u * 64 );
+
+ for( j = 0; j < 10000; j++ )
+ aes_crypt_ecb( &ctx, v, buf, buf );
+
+ if( memcmp( buf, aes_test_ecb_dec[u], 16 ) != 0 )
+ {
+ if( verbose != 0 )
+ polarssl_printf( "failed\n" );
+
+ ret = 1;
+ goto exit;
+ }
+ }
+ else
+ {
+ aes_setkey_enc( &ctx, key, 128 + u * 64 );
+
+ for( j = 0; j < 10000; j++ )
+ aes_crypt_ecb( &ctx, v, buf, buf );
+
+ if( memcmp( buf, aes_test_ecb_enc[u], 16 ) != 0 )
+ {
+ if( verbose != 0 )
+ polarssl_printf( "failed\n" );
+
+ ret = 1;
+ goto exit;
+ }
+ }
+
+ if( verbose != 0 )
+ polarssl_printf( "passed\n" );
+ }
+
+ if( verbose != 0 )
+ polarssl_printf( "\n" );
+
+#if defined(POLARSSL_CIPHER_MODE_CBC)
+ /*
+ * CBC mode
+ */
+ for( i = 0; i < 6; i++ )
+ {
+ u = i >> 1;
+ v = i & 1;
+
+ if( verbose != 0 )
+ polarssl_printf( " AES-CBC-%3d (%s): ", 128 + u * 64,
+ ( v == AES_DECRYPT ) ? "dec" : "enc" );
+
+ memset( iv , 0, 16 );
+ memset( prv, 0, 16 );
+ memset( buf, 0, 16 );
+
+ if( v == AES_DECRYPT )
+ {
+ aes_setkey_dec( &ctx, key, 128 + u * 64 );
+
+ for( j = 0; j < 10000; j++ )
+ aes_crypt_cbc( &ctx, v, 16, iv, buf, buf );
+
+ if( memcmp( buf, aes_test_cbc_dec[u], 16 ) != 0 )
+ {
+ if( verbose != 0 )
+ polarssl_printf( "failed\n" );
+
+ ret = 1;
+ goto exit;
+ }
+ }
+ else
+ {
+ aes_setkey_enc( &ctx, key, 128 + u * 64 );
+
+ for( j = 0; j < 10000; j++ )
+ {
+ unsigned char tmp[16];
+
+ aes_crypt_cbc( &ctx, v, 16, iv, buf, buf );
+
+ memcpy( tmp, prv, 16 );
+ memcpy( prv, buf, 16 );
+ memcpy( buf, tmp, 16 );
+ }
+
+ if( memcmp( prv, aes_test_cbc_enc[u], 16 ) != 0 )
+ {
+ if( verbose != 0 )
+ polarssl_printf( "failed\n" );
+
+ ret = 1;
+ goto exit;
+ }
+ }
+
+ if( verbose != 0 )
+ polarssl_printf( "passed\n" );
+ }
+
+ if( verbose != 0 )
+ polarssl_printf( "\n" );
+#endif /* POLARSSL_CIPHER_MODE_CBC */
+
+#if defined(POLARSSL_CIPHER_MODE_CFB)
+ /*
+ * CFB128 mode
+ */
+ for( i = 0; i < 6; i++ )
+ {
+ u = i >> 1;
+ v = i & 1;
+
+ if( verbose != 0 )
+ polarssl_printf( " AES-CFB128-%3d (%s): ", 128 + u * 64,
+ ( v == AES_DECRYPT ) ? "dec" : "enc" );
+
+ memcpy( iv, aes_test_cfb128_iv, 16 );
+ memcpy( key, aes_test_cfb128_key[u], 16 + u * 8 );
+
+ offset = 0;
+ aes_setkey_enc( &ctx, key, 128 + u * 64 );
+
+ if( v == AES_DECRYPT )
+ {
+ memcpy( buf, aes_test_cfb128_ct[u], 64 );
+ aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf );
+
+ if( memcmp( buf, aes_test_cfb128_pt, 64 ) != 0 )
+ {
+ if( verbose != 0 )
+ polarssl_printf( "failed\n" );
+
+ ret = 1;
+ goto exit;
+ }
+ }
+ else
+ {
+ memcpy( buf, aes_test_cfb128_pt, 64 );
+ aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf );
+
+ if( memcmp( buf, aes_test_cfb128_ct[u], 64 ) != 0 )
+ {
+ if( verbose != 0 )
+ polarssl_printf( "failed\n" );
+
+ ret = 1;
+ goto exit;
+ }
+ }
+
+ if( verbose != 0 )
+ polarssl_printf( "passed\n" );
+ }
+
+ if( verbose != 0 )
+ polarssl_printf( "\n" );
+#endif /* POLARSSL_CIPHER_MODE_CFB */
+
+#if defined(POLARSSL_CIPHER_MODE_CTR)
+ /*
+ * CTR mode
+ */
+ for( i = 0; i < 6; i++ )
+ {
+ u = i >> 1;
+ v = i & 1;
+
+ if( verbose != 0 )
+ polarssl_printf( " AES-CTR-128 (%s): ",
+ ( v == AES_DECRYPT ) ? "dec" : "enc" );
+
+ memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 );
+ memcpy( key, aes_test_ctr_key[u], 16 );
+
+ offset = 0;
+ aes_setkey_enc( &ctx, key, 128 );
+
+ if( v == AES_DECRYPT )
+ {
+ len = aes_test_ctr_len[u];
+ memcpy( buf, aes_test_ctr_ct[u], len );
+
+ aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block,
+ buf, buf );
+
+ if( memcmp( buf, aes_test_ctr_pt[u], len ) != 0 )
+ {
+ if( verbose != 0 )
+ polarssl_printf( "failed\n" );
+
+ ret = 1;
+ goto exit;
+ }
+ }
+ else
+ {
+ len = aes_test_ctr_len[u];
+ memcpy( buf, aes_test_ctr_pt[u], len );
+
+ aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block,
+ buf, buf );
+
+ if( memcmp( buf, aes_test_ctr_ct[u], len ) != 0 )
+ {
+ if( verbose != 0 )
+ polarssl_printf( "failed\n" );
+
+ ret = 1;
+ goto exit;
+ }
+ }
+
+ if( verbose != 0 )
+ polarssl_printf( "passed\n" );
+ }
+
+ if( verbose != 0 )
+ polarssl_printf( "\n" );
+#endif /* POLARSSL_CIPHER_MODE_CTR */
+
+ ret = 0;
+
+exit:
+ aes_free( &ctx );
+
+ return( ret );
+}
+
+#endif /* POLARSSL_SELF_TEST */
+
+#endif /* POLARSSL_AES_C */
--- /dev/null
+/**
+ * \file aes.h
+ *
+ * \brief AES block cipher
+ *
+ * Copyright (C) 2006-2014, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#ifndef POLARSSL_AES_H
+#define POLARSSL_AES_H
+
+#if !defined(POLARSSL_CONFIG_FILE)
+#include "polarssl_config.h"
+#else
+#include POLARSSL_CONFIG_FILE
+#endif
+
+#include <string.h>
+
+#if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32)
+#include <basetsd.h>
+typedef UINT32 uint32_t;
+#else
+#include <inttypes.h>
+#endif
+
+/* padlock.c and aesni.c rely on these values! */
+#define AES_ENCRYPT 1
+#define AES_DECRYPT 0
+
+#define POLARSSL_ERR_AES_INVALID_KEY_LENGTH -0x0020 /**< Invalid key length. */
+#define POLARSSL_ERR_AES_INVALID_INPUT_LENGTH -0x0022 /**< Invalid data input length. */
+
+#if !defined(POLARSSL_AES_ALT)
+// Regular implementation
+//
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief AES context structure
+ *
+ * \note buf is able to hold 32 extra bytes, which can be used:
+ * - for alignment purposes if VIA padlock is used, and/or
+ * - to simplify key expansion in the 256-bit case by
+ * generating an extra round key
+ */
+typedef struct
+{
+ int nr; /*!< number of rounds */
+ uint32_t *rk; /*!< AES round keys */
+ uint32_t buf[68]; /*!< unaligned data */
+}
+aes_context;
+
+/**
+ * \brief Initialize AES context
+ *
+ * \param ctx AES context to be initialized
+ */
+void aes_init( aes_context *ctx );
+
+/**
+ * \brief Clear AES context
+ *
+ * \param ctx AES context to be cleared
+ */
+void aes_free( aes_context *ctx );
+
+/**
+ * \brief AES key schedule (encryption)
+ *
+ * \param ctx AES context to be initialized
+ * \param key encryption key
+ * \param keysize must be 128, 192 or 256
+ *
+ * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
+ */
+int aes_setkey_enc( aes_context *ctx, const unsigned char *key,
+ unsigned int keysize );
+
+/**
+ * \brief AES key schedule (decryption)
+ *
+ * \param ctx AES context to be initialized
+ * \param key decryption key
+ * \param keysize must be 128, 192 or 256
+ *
+ * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_KEY_LENGTH
+ */
+int aes_setkey_dec( aes_context *ctx, const unsigned char *key,
+ unsigned int keysize );
+
+/**
+ * \brief AES-ECB block encryption/decryption
+ *
+ * \param ctx AES context
+ * \param mode AES_ENCRYPT or AES_DECRYPT
+ * \param input 16-byte input block
+ * \param output 16-byte output block
+ *
+ * \return 0 if successful
+ */
+int aes_crypt_ecb( aes_context *ctx,
+ int mode,
+ const unsigned char input[16],
+ unsigned char output[16] );
+
+#if defined(POLARSSL_CIPHER_MODE_CBC)
+/**
+ * \brief AES-CBC buffer encryption/decryption
+ * Length should be a multiple of the block
+ * size (16 bytes)
+ *
+ * \param ctx AES context
+ * \param mode AES_ENCRYPT or AES_DECRYPT
+ * \param length length of the input data
+ * \param iv initialization vector (updated after use)
+ * \param input buffer holding the input data
+ * \param output buffer holding the output data
+ *
+ * \return 0 if successful, or POLARSSL_ERR_AES_INVALID_INPUT_LENGTH
+ */
+int aes_crypt_cbc( aes_context *ctx,
+ int mode,
+ size_t length,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output );
+#endif /* POLARSSL_CIPHER_MODE_CBC */
+
+#if defined(POLARSSL_CIPHER_MODE_CFB)
+/**
+ * \brief AES-CFB128 buffer encryption/decryption.
+ *
+ * Note: Due to the nature of CFB you should use the same key schedule for
+ * both encryption and decryption. So a context initialized with
+ * aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
+ *
+ * \param ctx AES context
+ * \param mode AES_ENCRYPT or AES_DECRYPT
+ * \param length length of the input data
+ * \param iv_off offset in IV (updated after use)
+ * \param iv initialization vector (updated after use)
+ * \param input buffer holding the input data
+ * \param output buffer holding the output data
+ *
+ * \return 0 if successful
+ */
+int aes_crypt_cfb128( aes_context *ctx,
+ int mode,
+ size_t length,
+ size_t *iv_off,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief AES-CFB8 buffer encryption/decryption.
+ *
+ * Note: Due to the nature of CFB you should use the same key schedule for
+ * both encryption and decryption. So a context initialized with
+ * aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
+ *
+ * \param ctx AES context
+ * \param mode AES_ENCRYPT or AES_DECRYPT
+ * \param length length of the input data
+ * \param iv initialization vector (updated after use)
+ * \param input buffer holding the input data
+ * \param output buffer holding the output data
+ *
+ * \return 0 if successful
+ */
+int aes_crypt_cfb8( aes_context *ctx,
+ int mode,
+ size_t length,
+ unsigned char iv[16],
+ const unsigned char *input,
+ unsigned char *output );
+#endif /*POLARSSL_CIPHER_MODE_CFB */
+
+#if defined(POLARSSL_CIPHER_MODE_CTR)
+/**
+ * \brief AES-CTR buffer encryption/decryption
+ *
+ * Warning: You have to keep the maximum use of your counter in mind!
+ *
+ * Note: Due to the nature of CTR you should use the same key schedule for
+ * both encryption and decryption. So a context initialized with
+ * aes_setkey_enc() for both AES_ENCRYPT and AES_DECRYPT.
+ *
+ * \param ctx AES context
+ * \param length The length of the data
+ * \param nc_off The offset in the current stream_block (for resuming
+ * within current cipher stream). The offset pointer to
+ * should be 0 at the start of a stream.
+ * \param nonce_counter The 128-bit nonce and counter.
+ * \param stream_block The saved stream-block for resuming. Is overwritten
+ * by the function.
+ * \param input The input data stream
+ * \param output The output data stream
+ *
+ * \return 0 if successful
+ */
+int aes_crypt_ctr( aes_context *ctx,
+ size_t length,
+ size_t *nc_off,
+ unsigned char nonce_counter[16],
+ unsigned char stream_block[16],
+ const unsigned char *input,
+ unsigned char *output );
+#endif /* POLARSSL_CIPHER_MODE_CTR */
+
+#ifdef __cplusplus
+}
+#endif
+
+#else /* POLARSSL_AES_ALT */
+#include "aes_alt.h"
+#endif /* POLARSSL_AES_ALT */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int aes_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* aes.h */
int CmdAmp(const char *Cmd)
{
- int i, rising, falling;
- int max = INT_MIN, min = INT_MAX;
-
- for (i = 10; i < GraphTraceLen; ++i) {
- if (GraphBuffer[i] > max)
- max = GraphBuffer[i];
- if (GraphBuffer[i] < min)
- min = GraphBuffer[i];
- }
-
- if (max != min) {
- rising = falling= 0;
- for (i = 0; i < GraphTraceLen; ++i) {
- if (GraphBuffer[i + 1] < GraphBuffer[i]) {
- if (rising) {
- GraphBuffer[i] = max;
- rising = 0;
- }
- falling = 1;
- }
- if (GraphBuffer[i + 1] > GraphBuffer[i]) {
- if (falling) {
- GraphBuffer[i] = min;
- falling = 0;
- }
- rising= 1;
- }
- }
- }
- RepaintGraphWindow();
- return 0;
+ int i, rising, falling;
+ int max = INT_MIN, min = INT_MAX;
+
+ for (i = 10; i < GraphTraceLen; ++i) {
+ if (GraphBuffer[i] > max)
+ max = GraphBuffer[i];
+ if (GraphBuffer[i] < min)
+ min = GraphBuffer[i];
+ }
+
+ if (max != min) {
+ rising = falling= 0;
+ for (i = 0; i < GraphTraceLen; ++i) {
+ if (GraphBuffer[i + 1] < GraphBuffer[i]) {
+ if (rising) {
+ GraphBuffer[i] = max;
+ rising = 0;
+ }
+ falling = 1;
+ }
+ if (GraphBuffer[i + 1] > GraphBuffer[i]) {
+ if (falling) {
+ GraphBuffer[i] = min;
+ falling = 0;
+ }
+ rising= 1;
+ }
+ }
+ }
+ RepaintGraphWindow();
+ return 0;
}
/*
//this method is dependant on all highs and lows to be the same(or clipped) this creates issues[marshmellow] it also ignores the clock
int Cmdaskdemod(const char *Cmd)
{
- int i;
- int c, high = 0, low = 0;
+ int i;
+ int c, high = 0, low = 0;
- // TODO: complain if we do not give 2 arguments here !
- // (AL - this doesn't make sense! we're only using one argument!!!)
- sscanf(Cmd, "%i", &c);
+ // TODO: complain if we do not give 2 arguments here !
+ // (AL - this doesn't make sense! we're only using one argument!!!)
+ sscanf(Cmd, "%i", &c);
- /* Detect high and lows and clock */
+ /* Detect high and lows and clock */
// (AL - clock???)
- for (i = 0; i < GraphTraceLen; ++i)
- {
- if (GraphBuffer[i] > high)
- high = GraphBuffer[i];
- else if (GraphBuffer[i] < low)
- low = GraphBuffer[i];
- }
- high=abs(high*.75);
- low=abs(low*.75);
- if (c != 0 && c != 1) {
- PrintAndLog("Invalid argument: %s", Cmd);
- return 0;
- }
- //prime loop
- if (GraphBuffer[0] > 0) {
- GraphBuffer[0] = 1-c;
- } else {
- GraphBuffer[0] = c;
- }
- for (i = 1; i < GraphTraceLen; ++i) {
- /* Transitions are detected at each peak
- * Transitions are either:
- * - we're low: transition if we hit a high
- * - we're high: transition if we hit a low
- * (we need to do it this way because some tags keep high or
- * low for long periods, others just reach the peak and go
- * down)
- */
- //[marhsmellow] change == to >= for high and <= for low for fuzz
- if ((GraphBuffer[i] == high) && (GraphBuffer[i - 1] == c)) {
- GraphBuffer[i] = 1 - c;
- } else if ((GraphBuffer[i] == low) && (GraphBuffer[i - 1] == (1 - c))){
- GraphBuffer[i] = c;
- } else {
- /* No transition */
- GraphBuffer[i] = GraphBuffer[i - 1];
- }
- }
- RepaintGraphWindow();
- return 0;
+ for (i = 0; i < GraphTraceLen; ++i)
+ {
+ if (GraphBuffer[i] > high)
+ high = GraphBuffer[i];
+ else if (GraphBuffer[i] < low)
+ low = GraphBuffer[i];
+ }
+ high=abs(high*.75);
+ low=abs(low*.75);
+ if (c != 0 && c != 1) {
+ PrintAndLog("Invalid argument: %s", Cmd);
+ return 0;
+ }
+ //prime loop
+ if (GraphBuffer[0] > 0) {
+ GraphBuffer[0] = 1-c;
+ } else {
+ GraphBuffer[0] = c;
+ }
+ for (i = 1; i < GraphTraceLen; ++i) {
+ /* Transitions are detected at each peak
+ * Transitions are either:
+ * - we're low: transition if we hit a high
+ * - we're high: transition if we hit a low
+ * (we need to do it this way because some tags keep high or
+ * low for long periods, others just reach the peak and go
+ * down)
+ */
+ //[marhsmellow] change == to >= for high and <= for low for fuzz
+ if ((GraphBuffer[i] == high) && (GraphBuffer[i - 1] == c)) {
+ GraphBuffer[i] = 1 - c;
+ } else if ((GraphBuffer[i] == low) && (GraphBuffer[i - 1] == (1 - c))){
+ GraphBuffer[i] = c;
+ } else {
+ /* No transition */
+ GraphBuffer[i] = GraphBuffer[i - 1];
+ }
+ }
+ RepaintGraphWindow();
+ return 0;
}
//by marshmellow
void printBitStream(uint8_t BitStream[], uint32_t bitLen)
{
- uint32_t i = 0;
- if (bitLen<16) {
- PrintAndLog("Too few bits found: %d",bitLen);
- return;
- }
- if (bitLen>512) bitLen=512;
- for (i = 0; i <= (bitLen-16); i+=16) {
- PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i",
- BitStream[i],
- BitStream[i+1],
- BitStream[i+2],
- BitStream[i+3],
- BitStream[i+4],
- BitStream[i+5],
- BitStream[i+6],
- BitStream[i+7],
- BitStream[i+8],
- BitStream[i+9],
- BitStream[i+10],
- BitStream[i+11],
- BitStream[i+12],
- BitStream[i+13],
- BitStream[i+14],
- BitStream[i+15]);
- }
+ uint32_t i = 0;
+ if (bitLen<16) {
+ PrintAndLog("Too few bits found: %d",bitLen);
+ return;
+ }
+ if (bitLen>512) bitLen=512;
+ for (i = 0; i <= (bitLen-16); i+=16) {
+ PrintAndLog("%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i%i",
+ BitStream[i],
+ BitStream[i+1],
+ BitStream[i+2],
+ BitStream[i+3],
+ BitStream[i+4],
+ BitStream[i+5],
+ BitStream[i+6],
+ BitStream[i+7],
+ BitStream[i+8],
+ BitStream[i+9],
+ BitStream[i+10],
+ BitStream[i+11],
+ BitStream[i+12],
+ BitStream[i+13],
+ BitStream[i+14],
+ BitStream[i+15]);
+ }
return;
}
//by marshmellow
//print EM410x ID in multiple formats
void printEM410x(uint64_t id)
{
- if (id !=0){
- uint64_t iii=1;
- uint64_t id2lo=0; //id2hi=0,
- uint32_t ii=0;
- uint32_t i=0;
- for (ii=5; ii>0;ii--){
- for (i=0;i<8;i++){
+ if (id !=0){
+ uint64_t iii=1;
+ uint64_t id2lo=0; //id2hi=0,
+ uint32_t ii=0;
+ uint32_t i=0;
+ for (ii=5; ii>0;ii--){
+ for (i=0;i<8;i++){
id2lo=(id2lo<<1LL) | ((id & (iii << (i+((ii-1)*8)))) >> (i+((ii-1)*8)));
- }
- }
- //output em id
- PrintAndLog("EM TAG ID : %010llx", id);
- PrintAndLog("Unique TAG ID: %010llx", id2lo); //id2hi,
- PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF);
- PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFF);
- PrintAndLog("DEZ 5.5 : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF));
- PrintAndLog("DEZ 3.5A : %03lld.%05lld",(id>>32ll),(id & 0xFFFF));
- PrintAndLog("DEZ 14/IK2 : %014lld",id);
- PrintAndLog("DEZ 15/IK3 : %015lld",id2lo);
- PrintAndLog("Other : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF));
+ }
+ }
+ //output em id
+ PrintAndLog("EM TAG ID : %010llx", id);
+ PrintAndLog("Unique TAG ID: %010llx", id2lo); //id2hi,
+ PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF);
+ PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFF);
+ PrintAndLog("DEZ 5.5 : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF));
+ PrintAndLog("DEZ 3.5A : %03lld.%05lld",(id>>32ll),(id & 0xFFFF));
+ PrintAndLog("DEZ 14/IK2 : %014lld",id);
+ PrintAndLog("DEZ 15/IK3 : %015lld",id2lo);
+ PrintAndLog("Other : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF));
}
- return;
+ return;
}
//by marshmellow
//take binary from demod buffer and see if we can find an EM410x ID
int CmdEm410xDecode(const char *Cmd)
{
- uint64_t id=0;
+ uint64_t id=0;
// uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
// uint32_t i=0;
// i=getFromGraphBuf(BitStream);
id = Em410xDecode(DemodBuffer,DemodBufferLen);
- printEM410x(id);
- if (id>0) return 1;
- return 0;
+ printEM410x(id);
+ if (id>0) return 1;
+ return 0;
}
{
int invert=0;
int clk=0;
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
sscanf(Cmd, "%i %i", &clk, &invert);
- if (invert != 0 && invert != 1) {
- PrintAndLog("Invalid argument: %s", Cmd);
- return 0;
- }
+ if (invert != 0 && invert != 1) {
+ PrintAndLog("Invalid argument: %s", Cmd);
+ return 0;
+ }
size_t BitLen = getFromGraphBuf(BitStream);
- // PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen);
- int errCnt=0;
- errCnt = askmandemod(BitStream, &BitLen,&clk,&invert);
+ // PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen);
+ int errCnt=0;
+ errCnt = askmandemod(BitStream, &BitLen,&clk,&invert);
if (errCnt<0||BitLen<16){ //if fatal error (or -1)
// PrintAndLog("no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk);
- return 0;
+ return 0;
}
- PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen);
+ PrintAndLog("\nUsing Clock: %d - Invert: %d - Bits Found: %d",clk,invert,BitLen);
- //output
- if (errCnt>0){
- PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
- }
- PrintAndLog("ASK/Manchester decoded bitstream:");
- // Now output the bitstream to the scrollback by line of 16 bits
+ //output
+ if (errCnt>0){
+ PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
+ }
+ PrintAndLog("ASK/Manchester decoded bitstream:");
+ // Now output the bitstream to the scrollback by line of 16 bits
setDemodBuf(BitStream,BitLen);
printDemodBuff();
- uint64_t lo =0;
- lo = Em410xDecode(BitStream,BitLen);
- if (lo>0){
- //set GraphBuffer for clone or sim command
- PrintAndLog("EM410x pattern found: ");
- printEM410x(lo);
- return 1;
- }
- //if (BitLen>16) return 1;
- return 0;
+ uint64_t lo =0;
+ lo = Em410xDecode(BitStream,BitLen);
+ if (lo>0){
+ //set GraphBuffer for clone or sim command
+ PrintAndLog("EM410x pattern found: ");
+ printEM410x(lo);
+ return 1;
+ }
+ //if (BitLen>16) return 1;
+ return 0;
}
//by marshmellow
//stricktly take 10 and 01 and convert to 0 and 1
int Cmdmandecoderaw(const char *Cmd)
{
- int i =0;
- int errCnt=0;
+ int i =0;
+ int errCnt=0;
size_t size=0;
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
- int high=0,low=0;
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+ int high=0,low=0;
for (;i<DemodBufferLen;++i){
if (DemodBuffer[i]>high) high=DemodBuffer[i];
else if(DemodBuffer[i]<low) low=DemodBuffer[i];
BitStream[i]=DemodBuffer[i];
- }
- if (high>1 || low <0 ){
- PrintAndLog("Error: please raw demod the wave first then mancheseter raw decode");
- return 0;
- }
+ }
+ if (high>1 || low <0 ){
+ PrintAndLog("Error: please raw demod the wave first then mancheseter raw decode");
+ return 0;
+ }
size=i;
errCnt=manrawdecode(BitStream, &size);
- if (errCnt>=20){
- PrintAndLog("Too many errors: %d",errCnt);
- return 0;
- }
- PrintAndLog("Manchester Decoded - # errors:%d - data:",errCnt);
+ if (errCnt>=20){
+ PrintAndLog("Too many errors: %d",errCnt);
+ return 0;
+ }
+ PrintAndLog("Manchester Decoded - # errors:%d - data:",errCnt);
printBitStream(BitStream, size);
- if (errCnt==0){
+ if (errCnt==0){
uint64_t id = 0;
id = Em410xDecode(BitStream, size);
if (id>0) setDemodBuf(BitStream, size);
printEM410x(id);
- }
- return 1;
+ }
+ return 1;
}
//by marshmellow
// width waves vs small width waves to help the decode positioning) or askbiphdemod
int CmdBiphaseDecodeRaw(const char *Cmd)
{
- int i = 0;
- int errCnt=0;
+ int i = 0;
+ int errCnt=0;
size_t size=0;
- int offset=0;
- int high=0, low=0;
+ int offset=0;
+ int high=0, low=0;
sscanf(Cmd, "%i", &offset);
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
- //get graphbuffer & high and low
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+ //get graphbuffer & high and low
for (;i<DemodBufferLen;++i){
if(DemodBuffer[i]>high)high=DemodBuffer[i];
else if(DemodBuffer[i]<low)low=DemodBuffer[i];
BitStream[i]=DemodBuffer[i];
- }
- if (high>1 || low <0){
- PrintAndLog("Error: please raw demod the wave first then decode");
- return 0;
- }
+ }
+ if (high>1 || low <0){
+ PrintAndLog("Error: please raw demod the wave first then decode");
+ return 0;
+ }
size=i;
errCnt=BiphaseRawDecode(BitStream, &size, offset);
- if (errCnt>=20){
- PrintAndLog("Too many errors attempting to decode: %d",errCnt);
- return 0;
- }
- PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt);
+ if (errCnt>=20){
+ PrintAndLog("Too many errors attempting to decode: %d",errCnt);
+ return 0;
+ }
+ PrintAndLog("Biphase Decoded using offset: %d - # errors:%d - data:",offset,errCnt);
printBitStream(BitStream, size);
- PrintAndLog("\nif bitstream does not look right try offset=1");
- return 1;
+ PrintAndLog("\nif bitstream does not look right try offset=1");
+ return 1;
}
{
int invert=0;
int clk=0;
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
sscanf(Cmd, "%i %i", &clk, &invert);
- if (invert != 0 && invert != 1) {
- PrintAndLog("Invalid argument: %s", Cmd);
- return 0;
- }
+ if (invert != 0 && invert != 1) {
+ PrintAndLog("Invalid argument: %s", Cmd);
+ return 0;
+ }
size_t BitLen = getFromGraphBuf(BitStream);
- int errCnt=0;
+ int errCnt=0;
errCnt = askrawdemod(BitStream, &BitLen,&clk,&invert);
if (errCnt==-1||BitLen<16){ //throw away static - allow 1 and -1 (in case of threshold command first)
PrintAndLog("no data found");
- return 0;
+ return 0;
}
- PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
- //PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum);
+ PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d",clk,invert,BitLen);
+ //PrintAndLog("Data start pos:%d, lastBit:%d, stop pos:%d, numBits:%d",iii,lastBit,i,bitnum);
//move BitStream back to DemodBuffer
setDemodBuf(BitStream,BitLen);
//output
- if (errCnt>0){
- PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
- }
- PrintAndLog("ASK demoded bitstream:");
- // Now output the bitstream to the scrollback by line of 16 bits
- printBitStream(BitStream,BitLen);
-
- return 1;
+ if (errCnt>0){
+ PrintAndLog("# Errors during Demoding (shown as 77 in bit stream): %d",errCnt);
+ }
+ PrintAndLog("ASK demoded bitstream:");
+ // Now output the bitstream to the scrollback by line of 16 bits
+ printBitStream(BitStream,BitLen);
+
+ return 1;
}
int CmdAutoCorr(const char *Cmd)
{
- static int CorrelBuffer[MAX_GRAPH_TRACE_LEN];
-
- int window = atoi(Cmd);
-
- if (window == 0) {
- PrintAndLog("needs a window");
- return 0;
- }
- if (window >= GraphTraceLen) {
- PrintAndLog("window must be smaller than trace (%d samples)",
- GraphTraceLen);
- return 0;
- }
-
- PrintAndLog("performing %d correlations", GraphTraceLen - window);
-
- for (int i = 0; i < GraphTraceLen - window; ++i) {
- int sum = 0;
- for (int j = 0; j < window; ++j) {
- sum += (GraphBuffer[j]*GraphBuffer[i + j]) / 256;
- }
- CorrelBuffer[i] = sum;
- }
- GraphTraceLen = GraphTraceLen - window;
- memcpy(GraphBuffer, CorrelBuffer, GraphTraceLen * sizeof (int));
-
- RepaintGraphWindow();
- return 0;
+ static int CorrelBuffer[MAX_GRAPH_TRACE_LEN];
+
+ int window = atoi(Cmd);
+
+ if (window == 0) {
+ PrintAndLog("needs a window");
+ return 0;
+ }
+ if (window >= GraphTraceLen) {
+ PrintAndLog("window must be smaller than trace (%d samples)",
+ GraphTraceLen);
+ return 0;
+ }
+
+ PrintAndLog("performing %d correlations", GraphTraceLen - window);
+
+ for (int i = 0; i < GraphTraceLen - window; ++i) {
+ int sum = 0;
+ for (int j = 0; j < window; ++j) {
+ sum += (GraphBuffer[j]*GraphBuffer[i + j]) / 256;
+ }
+ CorrelBuffer[i] = sum;
+ }
+ GraphTraceLen = GraphTraceLen - window;
+ memcpy(GraphBuffer, CorrelBuffer, GraphTraceLen * sizeof (int));
+
+ RepaintGraphWindow();
+ return 0;
}
int CmdBitsamples(const char *Cmd)
{
- int cnt = 0;
- uint8_t got[12288];
-
- GetFromBigBuf(got,sizeof(got),0);
- WaitForResponse(CMD_ACK,NULL);
-
- for (int j = 0; j < sizeof(got); j++) {
- for (int k = 0; k < 8; k++) {
- if(got[j] & (1 << (7 - k))) {
- GraphBuffer[cnt++] = 1;
- } else {
- GraphBuffer[cnt++] = 0;
- }
- }
- }
- GraphTraceLen = cnt;
- RepaintGraphWindow();
- return 0;
+ int cnt = 0;
+ uint8_t got[12288];
+
+ GetFromBigBuf(got,sizeof(got),0);
+ WaitForResponse(CMD_ACK,NULL);
+
+ for (int j = 0; j < sizeof(got); j++) {
+ for (int k = 0; k < 8; k++) {
+ if(got[j] & (1 << (7 - k))) {
+ GraphBuffer[cnt++] = 1;
+ } else {
+ GraphBuffer[cnt++] = 0;
+ }
+ }
+ }
+ GraphTraceLen = cnt;
+ RepaintGraphWindow();
+ return 0;
}
/*
*/
int CmdBitstream(const char *Cmd)
{
- int i, j;
- int bit;
- int gtl;
- int clock;
- int low = 0;
- int high = 0;
- int hithigh, hitlow, first;
-
- /* Detect high and lows and clock */
- for (i = 0; i < GraphTraceLen; ++i)
- {
- if (GraphBuffer[i] > high)
- high = GraphBuffer[i];
- else if (GraphBuffer[i] < low)
- low = GraphBuffer[i];
- }
-
- /* Get our clock */
- clock = GetClock(Cmd, high, 1);
- gtl = ClearGraph(0);
-
- bit = 0;
- for (i = 0; i < (int)(gtl / clock); ++i)
- {
- hithigh = 0;
- hitlow = 0;
- first = 1;
- /* Find out if we hit both high and low peaks */
- for (j = 0; j < clock; ++j)
- {
- if (GraphBuffer[(i * clock) + j] == high)
- hithigh = 1;
- else if (GraphBuffer[(i * clock) + j] == low)
- hitlow = 1;
- /* it doesn't count if it's the first part of our read
- because it's really just trailing from the last sequence */
- if (first && (hithigh || hitlow))
- hithigh = hitlow = 0;
- else
- first = 0;
-
- if (hithigh && hitlow)
- break;
- }
-
- /* If we didn't hit both high and low peaks, we had a bit transition */
- if (!hithigh || !hitlow)
- bit ^= 1;
-
- AppendGraph(0, clock, bit);
+ int i, j;
+ int bit;
+ int gtl;
+ int clock;
+ int low = 0;
+ int high = 0;
+ int hithigh, hitlow, first;
+
+ /* Detect high and lows and clock */
+ for (i = 0; i < GraphTraceLen; ++i)
+ {
+ if (GraphBuffer[i] > high)
+ high = GraphBuffer[i];
+ else if (GraphBuffer[i] < low)
+ low = GraphBuffer[i];
+ }
+
+ /* Get our clock */
+ clock = GetClock(Cmd, high, 1);
+ gtl = ClearGraph(0);
+
+ bit = 0;
+ for (i = 0; i < (int)(gtl / clock); ++i)
+ {
+ hithigh = 0;
+ hitlow = 0;
+ first = 1;
+ /* Find out if we hit both high and low peaks */
+ for (j = 0; j < clock; ++j)
+ {
+ if (GraphBuffer[(i * clock) + j] == high)
+ hithigh = 1;
+ else if (GraphBuffer[(i * clock) + j] == low)
+ hitlow = 1;
+ /* it doesn't count if it's the first part of our read
+ because it's really just trailing from the last sequence */
+ if (first && (hithigh || hitlow))
+ hithigh = hitlow = 0;
+ else
+ first = 0;
+
+ if (hithigh && hitlow)
+ break;
+ }
+
+ /* If we didn't hit both high and low peaks, we had a bit transition */
+ if (!hithigh || !hitlow)
+ bit ^= 1;
+
+ AppendGraph(0, clock, bit);
// for (j = 0; j < (int)(clock/2); j++)
// GraphBuffer[(i * clock) + j] = bit ^ 1;
// for (j = (int)(clock/2); j < clock; j++)
// GraphBuffer[(i * clock) + j] = bit;
- }
+ }
- RepaintGraphWindow();
- return 0;
+ RepaintGraphWindow();
+ return 0;
}
int CmdBuffClear(const char *Cmd)
{
- UsbCommand c = {CMD_BUFF_CLEAR};
- SendCommand(&c);
- ClearGraph(true);
- return 0;
+ UsbCommand c = {CMD_BUFF_CLEAR};
+ SendCommand(&c);
+ ClearGraph(true);
+ return 0;
}
int CmdDec(const char *Cmd)
{
- for (int i = 0; i < (GraphTraceLen / 2); ++i)
- GraphBuffer[i] = GraphBuffer[i * 2];
- GraphTraceLen /= 2;
- PrintAndLog("decimated by 2");
- RepaintGraphWindow();
- return 0;
+ for (int i = 0; i < (GraphTraceLen / 2); ++i)
+ GraphBuffer[i] = GraphBuffer[i * 2];
+ GraphTraceLen /= 2;
+ PrintAndLog("decimated by 2");
+ RepaintGraphWindow();
+ return 0;
}
/* Print our clock rate */
// uses data from graphbuffer
int CmdDetectClockRate(const char *Cmd)
{
- GetClock("",0,0);
+ GetClock("",0,0);
//int clock = DetectASKClock(0);
//PrintAndLog("Auto-detected clock rate: %d", clock);
- return 0;
+ return 0;
}
//by marshmellow
//defaults: clock = 50, invert=0, rchigh=10, rclow=8 (RF/10 RF/8 (fsk2a))
int CmdFSKrawdemod(const char *Cmd)
{
- //raw fsk demod no manchester decoding no start bit finding just get binary from wave
- //set defaults
- int rfLen = 50;
- int invert=0;
- int fchigh=10;
- int fclow=8;
- //set options from parameters entered with the command
+ //raw fsk demod no manchester decoding no start bit finding just get binary from wave
+ //set defaults
+ int rfLen = 50;
+ int invert=0;
+ int fchigh=10;
+ int fclow=8;
+ //set options from parameters entered with the command
sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow);
- if (strlen(Cmd)>0 && strlen(Cmd)<=2) {
- //rfLen=param_get8(Cmd, 0); //if rfLen option only is used
- if (rfLen==1){
- invert=1; //if invert option only is used
- rfLen = 50;
- } else if(rfLen==0) rfLen=50;
+ if (strlen(Cmd)>0 && strlen(Cmd)<=2) {
+ //rfLen=param_get8(Cmd, 0); //if rfLen option only is used
+ if (rfLen==1){
+ invert=1; //if invert option only is used
+ rfLen = 50;
+ } else if(rfLen==0) rfLen=50;
}
- PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow);
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+ PrintAndLog("Args invert: %d - Clock:%d - fchigh:%d - fclow: %d",invert,rfLen,fchigh, fclow);
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
size_t BitLen = getFromGraphBuf(BitStream);
int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow);
- if (size>0){
- PrintAndLog("FSK decoded bitstream:");
+ if (size>0){
+ PrintAndLog("FSK decoded bitstream:");
setDemodBuf(BitStream,size);
- // Now output the bitstream to the scrollback by line of 16 bits
- if(size > (8*32)+2) size = (8*32)+2; //only output a max of 8 blocks of 32 bits most tags will have full bit stream inside that sample size
- printBitStream(BitStream,size);
- } else{
- PrintAndLog("no FSK data found");
- }
- return 0;
+ // Now output the bitstream to the scrollback by line of 16 bits
+ if(size > (8*32)+2) size = (8*32)+2; //only output a max of 8 blocks of 32 bits most tags will have full bit stream inside that sample size
+ printBitStream(BitStream,size);
+ } else{
+ PrintAndLog("no FSK data found");
+ }
+ return 0;
}
//by marshmellow (based on existing demod + holiman's refactor)
//print full HID Prox ID and some bit format details if found
int CmdFSKdemodHID(const char *Cmd)
{
- //raw fsk demod no manchester decoding no start bit finding just get binary from wave
- uint32_t hi2=0, hi=0, lo=0;
+ //raw fsk demod no manchester decoding no start bit finding just get binary from wave
+ uint32_t hi2=0, hi=0, lo=0;
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
size_t BitLen = getFromGraphBuf(BitStream);
- //get binary from fsk wave
+ //get binary from fsk wave
size_t size = HIDdemodFSK(BitStream,BitLen,&hi2,&hi,&lo);
- if (size<0){
- PrintAndLog("Error demoding fsk");
- return 0;
- }
- if (hi2==0 && hi==0 && lo==0) return 0;
- if (hi2 != 0){ //extra large HID tags
+ if (size<0){
+ PrintAndLog("Error demoding fsk");
+ return 0;
+ }
+ if (hi2==0 && hi==0 && lo==0) return 0;
+ if (hi2 != 0){ //extra large HID tags
PrintAndLog("HID Prox TAG ID: %x%08x%08x (%d)",
- (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
+ (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
setDemodBuf(BitStream,BitLen);
- return 1;
- }
- else { //standard HID tags <38 bits
- //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd
- uint8_t fmtLen = 0;
- uint32_t fc = 0;
- uint32_t cardnum = 0;
- if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used
- uint32_t lo2=0;
- lo2=(((hi & 15) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit
- uint8_t idx3 = 1;
- while(lo2>1){ //find last bit set to 1 (format len bit)
- lo2=lo2>>1;
- idx3++;
- }
+ return 1;
+ }
+ else { //standard HID tags <38 bits
+ //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd
+ uint8_t fmtLen = 0;
+ uint32_t fc = 0;
+ uint32_t cardnum = 0;
+ if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used
+ uint32_t lo2=0;
+ lo2=(((hi & 15) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit
+ uint8_t idx3 = 1;
+ while(lo2>1){ //find last bit set to 1 (format len bit)
+ lo2=lo2>>1;
+ idx3++;
+ }
fmtLen =idx3+19;
- fc =0;
- cardnum=0;
- if(fmtLen==26){
- cardnum = (lo>>1)&0xFFFF;
- fc = (lo>>17)&0xFF;
- }
- if(fmtLen==37){
- cardnum = (lo>>1)&0x7FFFF;
- fc = ((hi&0xF)<<12)|(lo>>20);
- }
- if(fmtLen==34){
- cardnum = (lo>>1)&0xFFFF;
- fc= ((hi&1)<<15)|(lo>>17);
- }
- if(fmtLen==35){
- cardnum = (lo>>1)&0xFFFFF;
- fc = ((hi&1)<<11)|(lo>>21);
- }
- }
- else { //if bit 38 is not set then 37 bit format is used
- fmtLen= 37;
- fc =0;
- cardnum=0;
- if(fmtLen==37){
- cardnum = (lo>>1)&0x7FFFF;
- fc = ((hi&0xF)<<12)|(lo>>20);
- }
+ fc =0;
+ cardnum=0;
+ if(fmtLen==26){
+ cardnum = (lo>>1)&0xFFFF;
+ fc = (lo>>17)&0xFF;
+ }
+ if(fmtLen==37){
+ cardnum = (lo>>1)&0x7FFFF;
+ fc = ((hi&0xF)<<12)|(lo>>20);
+ }
+ if(fmtLen==34){
+ cardnum = (lo>>1)&0xFFFF;
+ fc= ((hi&1)<<15)|(lo>>17);
+ }
+ if(fmtLen==35){
+ cardnum = (lo>>1)&0xFFFFF;
+ fc = ((hi&1)<<11)|(lo>>21);
+ }
+ }
+ else { //if bit 38 is not set then 37 bit format is used
+ fmtLen= 37;
+ fc =0;
+ cardnum=0;
+ if(fmtLen==37){
+ cardnum = (lo>>1)&0x7FFFF;
+ fc = ((hi&0xF)<<12)|(lo>>20);
+ }
}
PrintAndLog("HID Prox TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d",
- (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF,
- (unsigned int) fmtLen, (unsigned int) fc, (unsigned int) cardnum);
+ (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF,
+ (unsigned int) fmtLen, (unsigned int) fc, (unsigned int) cardnum);
setDemodBuf(BitStream,BitLen);
- return 1;
- }
- return 0;
+ return 1;
+ }
+ return 0;
}
//by marshmellow
//print ioprox ID and some format details
int CmdFSKdemodIO(const char *Cmd)
{
- //raw fsk demod no manchester decoding no start bit finding just get binary from wave
- //set defaults
+ //raw fsk demod no manchester decoding no start bit finding just get binary from wave
+ //set defaults
int idx=0;
- //something in graphbuffer
- if (GraphTraceLen < 65) return 0;
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+ //something in graphbuffer
+ if (GraphTraceLen < 65) return 0;
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
size_t BitLen = getFromGraphBuf(BitStream);
- //get binary from fsk wave
- // PrintAndLog("DEBUG: got buff");
+ //get binary from fsk wave
+ // PrintAndLog("DEBUG: got buff");
idx = IOdemodFSK(BitStream,BitLen);
- if (idx<0){
- //PrintAndLog("Error demoding fsk");
- return 0;
- }
- // PrintAndLog("DEBUG: Got IOdemodFSK");
- if (idx==0){
- //PrintAndLog("IO Prox Data not found - FSK Data:");
- //if (BitLen > 92) printBitStream(BitStream,92);
- return 0;
- }
- //Index map
- //0 10 20 30 40 50 60
- //| | | | | | |
- //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
- //-----------------------------------------------------------------------------
- //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
- //
- //XSF(version)facility:codeone+codetwo (raw)
- //Handle the data
- if (idx+64>BitLen) return 0;
- PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx], BitStream[idx+1], BitStream[idx+2], BitStream[idx+3], BitStream[idx+4], BitStream[idx+5], BitStream[idx+6], BitStream[idx+7], BitStream[idx+8]);
+ if (idx<0){
+ //PrintAndLog("Error demoding fsk");
+ return 0;
+ }
+ // PrintAndLog("DEBUG: Got IOdemodFSK");
+ if (idx==0){
+ //PrintAndLog("IO Prox Data not found - FSK Data:");
+ //if (BitLen > 92) printBitStream(BitStream,92);
+ return 0;
+ }
+ //Index map
+ //0 10 20 30 40 50 60
+ //| | | | | | |
+ //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
+ //-----------------------------------------------------------------------------
+ //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
+ //
+ //XSF(version)facility:codeone+codetwo (raw)
+ //Handle the data
+ if (idx+64>BitLen) return 0;
+ PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx], BitStream[idx+1], BitStream[idx+2], BitStream[idx+3], BitStream[idx+4], BitStream[idx+5], BitStream[idx+6], BitStream[idx+7], BitStream[idx+8]);
PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx+9], BitStream[idx+10], BitStream[idx+11],BitStream[idx+12],BitStream[idx+13],BitStream[idx+14],BitStream[idx+15],BitStream[idx+16],BitStream[idx+17]);
- PrintAndLog("%d%d%d%d%d%d%d%d %d facility",BitStream[idx+18], BitStream[idx+19], BitStream[idx+20],BitStream[idx+21],BitStream[idx+22],BitStream[idx+23],BitStream[idx+24],BitStream[idx+25],BitStream[idx+26]);
- PrintAndLog("%d%d%d%d%d%d%d%d %d version",BitStream[idx+27], BitStream[idx+28], BitStream[idx+29],BitStream[idx+30],BitStream[idx+31],BitStream[idx+32],BitStream[idx+33],BitStream[idx+34],BitStream[idx+35]);
- PrintAndLog("%d%d%d%d%d%d%d%d %d code1",BitStream[idx+36], BitStream[idx+37], BitStream[idx+38],BitStream[idx+39],BitStream[idx+40],BitStream[idx+41],BitStream[idx+42],BitStream[idx+43],BitStream[idx+44]);
- PrintAndLog("%d%d%d%d%d%d%d%d %d code2",BitStream[idx+45], BitStream[idx+46], BitStream[idx+47],BitStream[idx+48],BitStream[idx+49],BitStream[idx+50],BitStream[idx+51],BitStream[idx+52],BitStream[idx+53]);
- PrintAndLog("%d%d%d%d%d%d%d%d %d%d checksum",BitStream[idx+54],BitStream[idx+55],BitStream[idx+56],BitStream[idx+57],BitStream[idx+58],BitStream[idx+59],BitStream[idx+60],BitStream[idx+61],BitStream[idx+62],BitStream[idx+63]);
+ PrintAndLog("%d%d%d%d%d%d%d%d %d facility",BitStream[idx+18], BitStream[idx+19], BitStream[idx+20],BitStream[idx+21],BitStream[idx+22],BitStream[idx+23],BitStream[idx+24],BitStream[idx+25],BitStream[idx+26]);
+ PrintAndLog("%d%d%d%d%d%d%d%d %d version",BitStream[idx+27], BitStream[idx+28], BitStream[idx+29],BitStream[idx+30],BitStream[idx+31],BitStream[idx+32],BitStream[idx+33],BitStream[idx+34],BitStream[idx+35]);
+ PrintAndLog("%d%d%d%d%d%d%d%d %d code1",BitStream[idx+36], BitStream[idx+37], BitStream[idx+38],BitStream[idx+39],BitStream[idx+40],BitStream[idx+41],BitStream[idx+42],BitStream[idx+43],BitStream[idx+44]);
+ PrintAndLog("%d%d%d%d%d%d%d%d %d code2",BitStream[idx+45], BitStream[idx+46], BitStream[idx+47],BitStream[idx+48],BitStream[idx+49],BitStream[idx+50],BitStream[idx+51],BitStream[idx+52],BitStream[idx+53]);
+ PrintAndLog("%d%d%d%d%d%d%d%d %d%d checksum",BitStream[idx+54],BitStream[idx+55],BitStream[idx+56],BitStream[idx+57],BitStream[idx+58],BitStream[idx+59],BitStream[idx+60],BitStream[idx+61],BitStream[idx+62],BitStream[idx+63]);
- uint32_t code = bytebits_to_byte(BitStream+idx,32);
+ uint32_t code = bytebits_to_byte(BitStream+idx,32);
uint32_t code2 = bytebits_to_byte(BitStream+idx+32,32);
- uint8_t version = bytebits_to_byte(BitStream+idx+27,8); //14,4
- uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ;
- uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9
+ uint8_t version = bytebits_to_byte(BitStream+idx+27,8); //14,4
+ uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ;
+ uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9
PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
int i;
for (i=0;i<64;++i)
DemodBuffer[i]=BitStream[idx++];
DemodBufferLen=64;
- return 1;
+ return 1;
}
int CmdFSKdemod(const char *Cmd) //old CmdFSKdemod needs updating
{
- static const int LowTone[] = {
- 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
- 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
- 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
- 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
- 1, 1, 1, 1, 1, -1, -1, -1, -1, -1
- };
- static const int HighTone[] = {
- 1, 1, 1, 1, 1, -1, -1, -1, -1,
- 1, 1, 1, 1, -1, -1, -1, -1,
- 1, 1, 1, 1, -1, -1, -1, -1,
- 1, 1, 1, 1, -1, -1, -1, -1,
- 1, 1, 1, 1, -1, -1, -1, -1,
- 1, 1, 1, 1, -1, -1, -1, -1, -1,
- };
-
- int lowLen = sizeof (LowTone) / sizeof (int);
- int highLen = sizeof (HighTone) / sizeof (int);
- int convLen = (highLen > lowLen) ? highLen : lowLen; //if highlen > lowLen then highlen else lowlen
- uint32_t hi = 0, lo = 0;
-
- int i, j;
- int minMark = 0, maxMark = 0;
-
- for (i = 0; i < GraphTraceLen - convLen; ++i) {
- int lowSum = 0, highSum = 0;
-
- for (j = 0; j < lowLen; ++j) {
- lowSum += LowTone[j]*GraphBuffer[i+j];
- }
- for (j = 0; j < highLen; ++j) {
- highSum += HighTone[j] * GraphBuffer[i + j];
- }
- lowSum = abs(100 * lowSum / lowLen);
- highSum = abs(100 * highSum / highLen);
- GraphBuffer[i] = (highSum << 16) | lowSum;
- }
-
- for(i = 0; i < GraphTraceLen - convLen - 16; ++i) {
- int lowTot = 0, highTot = 0;
- // 10 and 8 are f_s divided by f_l and f_h, rounded
- for (j = 0; j < 10; ++j) {
- lowTot += (GraphBuffer[i+j] & 0xffff);
- }
- for (j = 0; j < 8; j++) {
- highTot += (GraphBuffer[i + j] >> 16);
- }
- GraphBuffer[i] = lowTot - highTot;
- if (GraphBuffer[i] > maxMark) maxMark = GraphBuffer[i];
- if (GraphBuffer[i] < minMark) minMark = GraphBuffer[i];
- }
-
- GraphTraceLen -= (convLen + 16);
- RepaintGraphWindow();
-
- // Find bit-sync (3 lo followed by 3 high) (HID ONLY)
- int max = 0, maxPos = 0;
- for (i = 0; i < 6000; ++i) {
- int dec = 0;
- for (j = 0; j < 3 * lowLen; ++j) {
- dec -= GraphBuffer[i + j];
- }
- for (; j < 3 * (lowLen + highLen ); ++j) {
- dec += GraphBuffer[i + j];
- }
- if (dec > max) {
- max = dec;
- maxPos = i;
- }
- }
-
- // place start of bit sync marker in graph
- GraphBuffer[maxPos] = maxMark;
- GraphBuffer[maxPos + 1] = minMark;
-
- maxPos += j;
-
- // place end of bit sync marker in graph
- GraphBuffer[maxPos] = maxMark;
- GraphBuffer[maxPos+1] = minMark;
-
- PrintAndLog("actual data bits start at sample %d", maxPos);
- PrintAndLog("length %d/%d", highLen, lowLen);
+ static const int LowTone[] = {
+ 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
+ 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
+ 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
+ 1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
+ 1, 1, 1, 1, 1, -1, -1, -1, -1, -1
+ };
+ static const int HighTone[] = {
+ 1, 1, 1, 1, 1, -1, -1, -1, -1,
+ 1, 1, 1, 1, -1, -1, -1, -1,
+ 1, 1, 1, 1, -1, -1, -1, -1,
+ 1, 1, 1, 1, -1, -1, -1, -1,
+ 1, 1, 1, 1, -1, -1, -1, -1,
+ 1, 1, 1, 1, -1, -1, -1, -1, -1,
+ };
+
+ int lowLen = sizeof (LowTone) / sizeof (int);
+ int highLen = sizeof (HighTone) / sizeof (int);
+ int convLen = (highLen > lowLen) ? highLen : lowLen;
+ uint32_t hi = 0, lo = 0;
+
+ int i, j;
+ int minMark = 0, maxMark = 0;
+
+ for (i = 0; i < GraphTraceLen - convLen; ++i) {
+ int lowSum = 0, highSum = 0;
+
+ for (j = 0; j < lowLen; ++j) {
+ lowSum += LowTone[j]*GraphBuffer[i+j];
+ }
+ for (j = 0; j < highLen; ++j) {
+ highSum += HighTone[j] * GraphBuffer[i + j];
+ }
+ lowSum = abs(100 * lowSum / lowLen);
+ highSum = abs(100 * highSum / highLen);
+ GraphBuffer[i] = (highSum << 16) | lowSum;
+ }
+
+ for(i = 0; i < GraphTraceLen - convLen - 16; ++i) {
+ int lowTot = 0, highTot = 0;
+ // 10 and 8 are f_s divided by f_l and f_h, rounded
+ for (j = 0; j < 10; ++j) {
+ lowTot += (GraphBuffer[i+j] & 0xffff);
+ }
+ for (j = 0; j < 8; j++) {
+ highTot += (GraphBuffer[i + j] >> 16);
+ }
+ GraphBuffer[i] = lowTot - highTot;
+ if (GraphBuffer[i] > maxMark) maxMark = GraphBuffer[i];
+ if (GraphBuffer[i] < minMark) minMark = GraphBuffer[i];
+ }
+
+ GraphTraceLen -= (convLen + 16);
+ RepaintGraphWindow();
+
+ // Find bit-sync (3 lo followed by 3 high) (HID ONLY)
+ int max = 0, maxPos = 0;
+ for (i = 0; i < 6000; ++i) {
+ int dec = 0;
+ for (j = 0; j < 3 * lowLen; ++j) {
+ dec -= GraphBuffer[i + j];
+ }
+ for (; j < 3 * (lowLen + highLen ); ++j) {
+ dec += GraphBuffer[i + j];
+ }
+ if (dec > max) {
+ max = dec;
+ maxPos = i;
+ }
+ }
+
+ // place start of bit sync marker in graph
+ GraphBuffer[maxPos] = maxMark;
+ GraphBuffer[maxPos + 1] = minMark;
+
+ maxPos += j;
+
+ // place end of bit sync marker in graph
+ GraphBuffer[maxPos] = maxMark;
+ GraphBuffer[maxPos+1] = minMark;
+
+ PrintAndLog("actual data bits start at sample %d", maxPos);
+ PrintAndLog("length %d/%d", highLen, lowLen);
uint8_t bits[46];
bits[sizeof(bits)-1] = '\0';
- // find bit pairs and manchester decode them
- for (i = 0; i < arraylen(bits) - 1; ++i) {
- int dec = 0;
- for (j = 0; j < lowLen; ++j) {
- dec -= GraphBuffer[maxPos + j];
- }
- for (; j < lowLen + highLen; ++j) {
- dec += GraphBuffer[maxPos + j];
- }
- maxPos += j;
- // place inter bit marker in graph
- GraphBuffer[maxPos] = maxMark;
- GraphBuffer[maxPos + 1] = minMark;
-
- // hi and lo form a 64 bit pair
- hi = (hi << 1) | (lo >> 31);
- lo = (lo << 1);
- // store decoded bit as binary (in hi/lo) and text (in bits[])
- if(dec < 0) {
- bits[i] = '1';
- lo |= 1;
- } else {
- bits[i] = '0';
- }
- }
- PrintAndLog("bits: '%s'", bits);
- PrintAndLog("hex: %08x %08x", hi, lo);
- return 0;
+ // find bit pairs and manchester decode them
+ for (i = 0; i < arraylen(bits) - 1; ++i) {
+ int dec = 0;
+ for (j = 0; j < lowLen; ++j) {
+ dec -= GraphBuffer[maxPos + j];
+ }
+ for (; j < lowLen + highLen; ++j) {
+ dec += GraphBuffer[maxPos + j];
+ }
+ maxPos += j;
+ // place inter bit marker in graph
+ GraphBuffer[maxPos] = maxMark;
+ GraphBuffer[maxPos + 1] = minMark;
+
+ // hi and lo form a 64 bit pair
+ hi = (hi << 1) | (lo >> 31);
+ lo = (lo << 1);
+ // store decoded bit as binary (in hi/lo) and text (in bits[])
+ if(dec < 0) {
+ bits[i] = '1';
+ lo |= 1;
+ } else {
+ bits[i] = '0';
+ }
+ }
+ PrintAndLog("bits: '%s'", bits);
+ PrintAndLog("hex: %08x %08x", hi, lo);
+ return 0;
}
int CmdDetectNRZpskClockRate(const char *Cmd)
int CmdGrid(const char *Cmd)
{
- sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY);
- PlotGridXdefault= PlotGridX;
- PlotGridYdefault= PlotGridY;
- RepaintGraphWindow();
- return 0;
+ sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY);
+ PlotGridXdefault= PlotGridX;
+ PlotGridYdefault= PlotGridY;
+ RepaintGraphWindow();
+ return 0;
}
int CmdHexsamples(const char *Cmd)
{
- int i, j;
- int requested = 0;
- int offset = 0;
- char string_buf[25];
- char* string_ptr = string_buf;
- uint8_t got[40000];
-
- sscanf(Cmd, "%i %i", &requested, &offset);
-
- /* if no args send something */
- if (requested == 0) {
- requested = 8;
- }
- if (offset + requested > sizeof(got)) {
- PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > 40000");
- return 0;
+ int i, j;
+ int requested = 0;
+ int offset = 0;
+ char string_buf[25];
+ char* string_ptr = string_buf;
+ uint8_t got[40000];
+
+ sscanf(Cmd, "%i %i", &requested, &offset);
+
+ /* if no args send something */
+ if (requested == 0) {
+ requested = 8;
+ }
+ if (offset + requested > sizeof(got)) {
+ PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > 40000");
+ return 0;
+ }
+
+ GetFromBigBuf(got,requested,offset);
+ WaitForResponse(CMD_ACK,NULL);
+
+ i = 0;
+ for (j = 0; j < requested; j++) {
+ i++;
+ string_ptr += sprintf(string_ptr, "%02x ", got[j]);
+ if (i == 8) {
+ *(string_ptr - 1) = '\0'; // remove the trailing space
+ PrintAndLog("%s", string_buf);
+ string_buf[0] = '\0';
+ string_ptr = string_buf;
+ i = 0;
+ }
+ if (j == requested - 1 && string_buf[0] != '\0') { // print any remaining bytes
+ *(string_ptr - 1) = '\0';
+ PrintAndLog("%s", string_buf);
+ string_buf[0] = '\0';
+ }
}
-
- GetFromBigBuf(got,requested,offset);
- WaitForResponse(CMD_ACK,NULL);
-
- i = 0;
- for (j = 0; j < requested; j++) {
- i++;
- string_ptr += sprintf(string_ptr, "%02x ", got[j]);
- if (i == 8) {
- *(string_ptr - 1) = '\0'; // remove the trailing space
- PrintAndLog("%s", string_buf);
- string_buf[0] = '\0';
- string_ptr = string_buf;
- i = 0;
- }
- if (j == requested - 1 && string_buf[0] != '\0') { // print any remaining bytes
- *(string_ptr - 1) = '\0';
- PrintAndLog("%s", string_buf);
- string_buf[0] = '\0';
- }
- }
- return 0;
+ return 0;
}
int CmdHide(const char *Cmd)
{
- HideGraphWindow();
- return 0;
+ HideGraphWindow();
+ return 0;
}
int CmdHpf(const char *Cmd)
{
- int i;
- int accum = 0;
+ int i;
+ int accum = 0;
- for (i = 10; i < GraphTraceLen; ++i)
- accum += GraphBuffer[i];
- accum /= (GraphTraceLen - 10);
- for (i = 0; i < GraphTraceLen; ++i)
- GraphBuffer[i] -= accum;
+ for (i = 10; i < GraphTraceLen; ++i)
+ accum += GraphBuffer[i];
+ accum /= (GraphTraceLen - 10);
+ for (i = 0; i < GraphTraceLen; ++i)
+ GraphBuffer[i] -= accum;
- RepaintGraphWindow();
- return 0;
+ RepaintGraphWindow();
+ return 0;
}
int CmdSamples(const char *Cmd)
n = sizeof(got);
PrintAndLog("Reading %d samples from device memory\n", n);
- GetFromBigBuf(got,n,0);
- WaitForResponse(CMD_ACK,NULL);
+ GetFromBigBuf(got,n,0);
+ WaitForResponse(CMD_ACK,NULL);
for (int j = 0; j < n; j++) {
GraphBuffer[j] = ((int)got[j]) - 128;
- }
- GraphTraceLen = n;
- RepaintGraphWindow();
- return 0;
+ }
+ GraphTraceLen = n;
+ RepaintGraphWindow();
+ return 0;
}
int CmdTuneSamples(const char *Cmd)
GraphBuffer[i] = resp.d.asBytes[i] - 128;
}
- PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n");
- PrintAndLog("\n");
+ PrintAndLog("Done! Divisor 89 is 134khz, 95 is 125khz.\n");
+ PrintAndLog("\n");
GraphTraceLen = 256;
ShowGraphWindow();
int CmdLoad(const char *Cmd)
{
- FILE *f = fopen(Cmd, "r");
- if (!f) {
- PrintAndLog("couldn't open '%s'", Cmd);
- return 0;
- }
-
- GraphTraceLen = 0;
- char line[80];
- while (fgets(line, sizeof (line), f)) {
- GraphBuffer[GraphTraceLen] = atoi(line);
- GraphTraceLen++;
- }
- fclose(f);
- PrintAndLog("loaded %d samples", GraphTraceLen);
- RepaintGraphWindow();
- return 0;
+ char filename[FILE_PATH_SIZE] = {0x00};
+ int len = 0;
+
+ len = strlen(Cmd);
+ if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
+ memcpy(filename, Cmd, len);
+
+ FILE *f = fopen(filename, "r");
+ if (!f) {
+ PrintAndLog("couldn't open '%s'", filename);
+ return 0;
+ }
+
+ GraphTraceLen = 0;
+ char line[80];
+ while (fgets(line, sizeof (line), f)) {
+ GraphBuffer[GraphTraceLen] = atoi(line);
+ GraphTraceLen++;
+ }
+ fclose(f);
+ PrintAndLog("loaded %d samples", GraphTraceLen);
+ RepaintGraphWindow();
+ return 0;
}
int CmdLtrim(const char *Cmd)
{
- int ds = atoi(Cmd);
+ int ds = atoi(Cmd);
- for (int i = ds; i < GraphTraceLen; ++i)
- GraphBuffer[i-ds] = GraphBuffer[i];
- GraphTraceLen -= ds;
+ for (int i = ds; i < GraphTraceLen; ++i)
+ GraphBuffer[i-ds] = GraphBuffer[i];
+ GraphTraceLen -= ds;
- RepaintGraphWindow();
- return 0;
+ RepaintGraphWindow();
+ return 0;
}
int CmdRtrim(const char *Cmd)
{
- int ds = atoi(Cmd);
+ int ds = atoi(Cmd);
- GraphTraceLen = ds;
+ GraphTraceLen = ds;
- RepaintGraphWindow();
- return 0;
+ RepaintGraphWindow();
+ return 0;
}
/*
*/
int CmdManchesterDemod(const char *Cmd)
{
- int i, j, invert= 0;
- int bit;
- int clock;
- int lastval = 0;
- int low = 0;
- int high = 0;
- int hithigh, hitlow, first;
- int lc = 0;
- int bitidx = 0;
- int bit2idx = 0;
- int warnings = 0;
-
- /* check if we're inverting output */
- if (*Cmd == 'i')
- {
- PrintAndLog("Inverting output");
- invert = 1;
- ++Cmd;
- do
- ++Cmd;
- while(*Cmd == ' '); // in case a 2nd argument was given
- }
-
- /* Holds the decoded bitstream: each clock period contains 2 bits */
- /* later simplified to 1 bit after manchester decoding. */
- /* Add 10 bits to allow for noisy / uncertain traces without aborting */
- /* int BitStream[GraphTraceLen*2/clock+10]; */
-
- /* But it does not work if compiling on WIndows: therefore we just allocate a */
- /* large array */
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0};
-
- /* Detect high and lows */
- for (i = 0; i < GraphTraceLen; i++)
- {
- if (GraphBuffer[i] > high)
- high = GraphBuffer[i];
- else if (GraphBuffer[i] < low)
- low = GraphBuffer[i];
- }
-
- /* Get our clock */
- clock = GetClock(Cmd, high, 1);
-
- int tolerance = clock/4;
-
- /* Detect first transition */
- /* Lo-Hi (arbitrary) */
- /* skip to the first high */
- for (i= 0; i < GraphTraceLen; i++)
- if (GraphBuffer[i] == high)
- break;
- /* now look for the first low */
- for (; i < GraphTraceLen; i++)
- {
- if (GraphBuffer[i] == low)
- {
- lastval = i;
- break;
- }
- }
-
- /* If we're not working with 1/0s, demod based off clock */
- if (high != 1)
- {
- bit = 0; /* We assume the 1st bit is zero, it may not be
- * the case: this routine (I think) has an init problem.
- * Ed.
- */
- for (; i < (int)(GraphTraceLen / clock); i++)
- {
- hithigh = 0;
- hitlow = 0;
- first = 1;
-
- /* Find out if we hit both high and low peaks */
- for (j = 0; j < clock; j++)
- {
- if (GraphBuffer[(i * clock) + j] == high)
- hithigh = 1;
- else if (GraphBuffer[(i * clock) + j] == low)
- hitlow = 1;
-
- /* it doesn't count if it's the first part of our read
- because it's really just trailing from the last sequence */
- if (first && (hithigh || hitlow))
- hithigh = hitlow = 0;
- else
- first = 0;
-
- if (hithigh && hitlow)
- break;
- }
-
- /* If we didn't hit both high and low peaks, we had a bit transition */
- if (!hithigh || !hitlow)
- bit ^= 1;
-
- BitStream[bit2idx++] = bit ^ invert;
- }
- }
-
- /* standard 1/0 bitstream */
- else
- {
-
- /* Then detect duration between 2 successive transitions */
- for (bitidx = 1; i < GraphTraceLen; i++)
- {
- if (GraphBuffer[i-1] != GraphBuffer[i])
- {
- lc = i-lastval;
- lastval = i;
-
- // Error check: if bitidx becomes too large, we do not
- // have a Manchester encoded bitstream or the clock is really
- // wrong!
- if (bitidx > (GraphTraceLen*2/clock+8) ) {
- PrintAndLog("Error: the clock you gave is probably wrong, aborting.");
- return 0;
- }
- // Then switch depending on lc length:
- // Tolerance is 1/4 of clock rate (arbitrary)
- if (abs(lc-clock/2) < tolerance) {
- // Short pulse : either "1" or "0"
- BitStream[bitidx++]=GraphBuffer[i-1];
- } else if (abs(lc-clock) < tolerance) {
- // Long pulse: either "11" or "00"
- BitStream[bitidx++]=GraphBuffer[i-1];
- BitStream[bitidx++]=GraphBuffer[i-1];
- } else {
- // Error
- warnings++;
- PrintAndLog("Warning: Manchester decode error for pulse width detection.");
- PrintAndLog("(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)");
-
- if (warnings > 10)
- {
- PrintAndLog("Error: too many detection errors, aborting.");
- return 0;
- }
- }
- }
- }
-
- // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream
- // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful
- // to stop output at the final bitidx2 value, not bitidx
- for (i = 0; i < bitidx; i += 2) {
- if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) {
- BitStream[bit2idx++] = 1 ^ invert;
- } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) {
- BitStream[bit2idx++] = 0 ^ invert;
- } else {
- // We cannot end up in this state, this means we are unsynchronized,
- // move up 1 bit:
- i++;
- warnings++;
- PrintAndLog("Unsynchronized, resync...");
- PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)");
-
- if (warnings > 10)
- {
- PrintAndLog("Error: too many decode errors, aborting.");
- return 0;
- }
- }
- }
- }
-
- PrintAndLog("Manchester decoded bitstream");
- // Now output the bitstream to the scrollback by line of 16 bits
- for (i = 0; i < (bit2idx-16); i+=16) {
- PrintAndLog("%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i",
- BitStream[i],
- BitStream[i+1],
- BitStream[i+2],
- BitStream[i+3],
- BitStream[i+4],
- BitStream[i+5],
- BitStream[i+6],
- BitStream[i+7],
- BitStream[i+8],
- BitStream[i+9],
- BitStream[i+10],
- BitStream[i+11],
- BitStream[i+12],
- BitStream[i+13],
- BitStream[i+14],
- BitStream[i+15]);
- }
- return 0;
+ int i, j, invert= 0;
+ int bit;
+ int clock;
+ int lastval = 0;
+ int low = 0;
+ int high = 0;
+ int hithigh, hitlow, first;
+ int lc = 0;
+ int bitidx = 0;
+ int bit2idx = 0;
+ int warnings = 0;
+
+ /* check if we're inverting output */
+ if (*Cmd == 'i')
+ {
+ PrintAndLog("Inverting output");
+ invert = 1;
+ ++Cmd;
+ do
+ ++Cmd;
+ while(*Cmd == ' '); // in case a 2nd argument was given
+ }
+
+ /* Holds the decoded bitstream: each clock period contains 2 bits */
+ /* later simplified to 1 bit after manchester decoding. */
+ /* Add 10 bits to allow for noisy / uncertain traces without aborting */
+ /* int BitStream[GraphTraceLen*2/clock+10]; */
+
+ /* But it does not work if compiling on WIndows: therefore we just allocate a */
+ /* large array */
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0};
+
+ /* Detect high and lows */
+ for (i = 0; i < GraphTraceLen; i++)
+ {
+ if (GraphBuffer[i] > high)
+ high = GraphBuffer[i];
+ else if (GraphBuffer[i] < low)
+ low = GraphBuffer[i];
+ }
+
+ /* Get our clock */
+ clock = GetClock(Cmd, high, 1);
+
+ int tolerance = clock/4;
+
+ /* Detect first transition */
+ /* Lo-Hi (arbitrary) */
+ /* skip to the first high */
+ for (i= 0; i < GraphTraceLen; i++)
+ if (GraphBuffer[i] == high)
+ break;
+ /* now look for the first low */
+ for (; i < GraphTraceLen; i++)
+ {
+ if (GraphBuffer[i] == low)
+ {
+ lastval = i;
+ break;
+ }
+ }
+
+ /* If we're not working with 1/0s, demod based off clock */
+ if (high != 1)
+ {
+ bit = 0; /* We assume the 1st bit is zero, it may not be
+ * the case: this routine (I think) has an init problem.
+ * Ed.
+ */
+ for (; i < (int)(GraphTraceLen / clock); i++)
+ {
+ hithigh = 0;
+ hitlow = 0;
+ first = 1;
+
+ /* Find out if we hit both high and low peaks */
+ for (j = 0; j < clock; j++)
+ {
+ if (GraphBuffer[(i * clock) + j] == high)
+ hithigh = 1;
+ else if (GraphBuffer[(i * clock) + j] == low)
+ hitlow = 1;
+
+ /* it doesn't count if it's the first part of our read
+ because it's really just trailing from the last sequence */
+ if (first && (hithigh || hitlow))
+ hithigh = hitlow = 0;
+ else
+ first = 0;
+
+ if (hithigh && hitlow)
+ break;
+ }
+
+ /* If we didn't hit both high and low peaks, we had a bit transition */
+ if (!hithigh || !hitlow)
+ bit ^= 1;
+
+ BitStream[bit2idx++] = bit ^ invert;
+ }
+ }
+
+ /* standard 1/0 bitstream */
+ else
+ {
+
+ /* Then detect duration between 2 successive transitions */
+ for (bitidx = 1; i < GraphTraceLen; i++)
+ {
+ if (GraphBuffer[i-1] != GraphBuffer[i])
+ {
+ lc = i-lastval;
+ lastval = i;
+
+ // Error check: if bitidx becomes too large, we do not
+ // have a Manchester encoded bitstream or the clock is really
+ // wrong!
+ if (bitidx > (GraphTraceLen*2/clock+8) ) {
+ PrintAndLog("Error: the clock you gave is probably wrong, aborting.");
+ return 0;
+ }
+ // Then switch depending on lc length:
+ // Tolerance is 1/4 of clock rate (arbitrary)
+ if (abs(lc-clock/2) < tolerance) {
+ // Short pulse : either "1" or "0"
+ BitStream[bitidx++]=GraphBuffer[i-1];
+ } else if (abs(lc-clock) < tolerance) {
+ // Long pulse: either "11" or "00"
+ BitStream[bitidx++]=GraphBuffer[i-1];
+ BitStream[bitidx++]=GraphBuffer[i-1];
+ } else {
+ // Error
+ warnings++;
+ PrintAndLog("Warning: Manchester decode error for pulse width detection.");
+ PrintAndLog("(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)");
+
+ if (warnings > 10)
+ {
+ PrintAndLog("Error: too many detection errors, aborting.");
+ return 0;
+ }
+ }
+ }
+ }
+
+ // At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream
+ // Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful
+ // to stop output at the final bitidx2 value, not bitidx
+ for (i = 0; i < bitidx; i += 2) {
+ if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) {
+ BitStream[bit2idx++] = 1 ^ invert;
+ } else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) {
+ BitStream[bit2idx++] = 0 ^ invert;
+ } else {
+ // We cannot end up in this state, this means we are unsynchronized,
+ // move up 1 bit:
+ i++;
+ warnings++;
+ PrintAndLog("Unsynchronized, resync...");
+ PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)");
+
+ if (warnings > 10)
+ {
+ PrintAndLog("Error: too many decode errors, aborting.");
+ return 0;
+ }
+ }
+ }
+ }
+
+ PrintAndLog("Manchester decoded bitstream");
+ // Now output the bitstream to the scrollback by line of 16 bits
+ for (i = 0; i < (bit2idx-16); i+=16) {
+ PrintAndLog("%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i",
+ BitStream[i],
+ BitStream[i+1],
+ BitStream[i+2],
+ BitStream[i+3],
+ BitStream[i+4],
+ BitStream[i+5],
+ BitStream[i+6],
+ BitStream[i+7],
+ BitStream[i+8],
+ BitStream[i+9],
+ BitStream[i+10],
+ BitStream[i+11],
+ BitStream[i+12],
+ BitStream[i+13],
+ BitStream[i+14],
+ BitStream[i+15]);
+ }
+ return 0;
}
/* Modulate our data into manchester */
int CmdManchesterMod(const char *Cmd)
{
- int i, j;
- int clock;
- int bit, lastbit, wave;
-
- /* Get our clock */
- clock = GetClock(Cmd, 0, 1);
-
- wave = 0;
- lastbit = 1;
- for (i = 0; i < (int)(GraphTraceLen / clock); i++)
- {
- bit = GraphBuffer[i * clock] ^ 1;
-
- for (j = 0; j < (int)(clock/2); j++)
- GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave;
- for (j = (int)(clock/2); j < clock; j++)
- GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave ^ 1;
-
- /* Keep track of how we start our wave and if we changed or not this time */
- wave ^= bit ^ lastbit;
- lastbit = bit;
- }
-
- RepaintGraphWindow();
- return 0;
+ int i, j;
+ int clock;
+ int bit, lastbit, wave;
+
+ /* Get our clock */
+ clock = GetClock(Cmd, 0, 1);
+
+ wave = 0;
+ lastbit = 1;
+ for (i = 0; i < (int)(GraphTraceLen / clock); i++)
+ {
+ bit = GraphBuffer[i * clock] ^ 1;
+
+ for (j = 0; j < (int)(clock/2); j++)
+ GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave;
+ for (j = (int)(clock/2); j < clock; j++)
+ GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave ^ 1;
+
+ /* Keep track of how we start our wave and if we changed or not this time */
+ wave ^= bit ^ lastbit;
+ lastbit = bit;
+ }
+
+ RepaintGraphWindow();
+ return 0;
}
int CmdNorm(const char *Cmd)
{
- int i;
- int max = INT_MIN, min = INT_MAX;
-
- for (i = 10; i < GraphTraceLen; ++i) {
- if (GraphBuffer[i] > max)
- max = GraphBuffer[i];
- if (GraphBuffer[i] < min)
- min = GraphBuffer[i];
- }
-
- if (max != min) {
- for (i = 0; i < GraphTraceLen; ++i) {
+ int i;
+ int max = INT_MIN, min = INT_MAX;
+
+ for (i = 10; i < GraphTraceLen; ++i) {
+ if (GraphBuffer[i] > max)
+ max = GraphBuffer[i];
+ if (GraphBuffer[i] < min)
+ min = GraphBuffer[i];
+ }
+
+ if (max != min) {
+ for (i = 0; i < GraphTraceLen; ++i) {
GraphBuffer[i] = (GraphBuffer[i] - ((max + min) / 2)) * 256 /
- (max - min);
+ (max - min);
//marshmelow: adjusted *1000 to *256 to make +/- 128 so demod commands still work
- }
- }
- RepaintGraphWindow();
- return 0;
+ }
+ }
+ RepaintGraphWindow();
+ return 0;
}
int CmdPlot(const char *Cmd)
{
- ShowGraphWindow();
- return 0;
+ ShowGraphWindow();
+ return 0;
}
int CmdSave(const char *Cmd)
{
- FILE *f = fopen(Cmd, "w");
- if(!f) {
- PrintAndLog("couldn't open '%s'", Cmd);
- return 0;
- }
- int i;
- for (i = 0; i < GraphTraceLen; i++) {
- fprintf(f, "%d\n", GraphBuffer[i]);
- }
- fclose(f);
- PrintAndLog("saved to '%s'", Cmd);
- return 0;
+ char filename[FILE_PATH_SIZE] = {0x00};
+ int len = 0;
+
+ len = strlen(Cmd);
+ if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
+ memcpy(filename, Cmd, len);
+
+
+ FILE *f = fopen(filename, "w");
+ if(!f) {
+ PrintAndLog("couldn't open '%s'", filename);
+ return 0;
+ }
+ int i;
+ for (i = 0; i < GraphTraceLen; i++) {
+ fprintf(f, "%d\n", GraphBuffer[i]);
+ }
+ fclose(f);
+ PrintAndLog("saved to '%s'", Cmd);
+ return 0;
}
int CmdScale(const char *Cmd)
{
- CursorScaleFactor = atoi(Cmd);
- if (CursorScaleFactor == 0) {
- PrintAndLog("bad, can't have zero scale");
- CursorScaleFactor = 1;
- }
- RepaintGraphWindow();
- return 0;
+ CursorScaleFactor = atoi(Cmd);
+ if (CursorScaleFactor == 0) {
+ PrintAndLog("bad, can't have zero scale");
+ CursorScaleFactor = 1;
+ }
+ RepaintGraphWindow();
+ return 0;
}
int CmdThreshold(const char *Cmd)
{
- int threshold = atoi(Cmd);
-
- for (int i = 0; i < GraphTraceLen; ++i) {
- if (GraphBuffer[i] >= threshold)
- GraphBuffer[i] = 1;
- else
- GraphBuffer[i] = -1;
- }
- RepaintGraphWindow();
- return 0;
+ int threshold = atoi(Cmd);
+
+ for (int i = 0; i < GraphTraceLen; ++i) {
+ if (GraphBuffer[i] >= threshold)
+ GraphBuffer[i] = 1;
+ else
+ GraphBuffer[i] = -1;
+ }
+ RepaintGraphWindow();
+ return 0;
}
int CmdDirectionalThreshold(const char *Cmd)
int8_t upThres = param_get8(Cmd, 0);
int8_t downThres = param_get8(Cmd, 1);
- printf("Applying Up Threshold: %d, Down Threshold: %d\n", upThres, downThres);
-
- int lastValue = GraphBuffer[0];
- GraphBuffer[0] = 0; // Will be changed at the end, but init 0 as we adjust to last samples value if no threshold kicks in.
-
- for (int i = 1; i < GraphTraceLen; ++i) {
- // Apply first threshold to samples heading up
- if (GraphBuffer[i] >= upThres && GraphBuffer[i] > lastValue)
- {
- lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
- GraphBuffer[i] = 1;
- }
- // Apply second threshold to samples heading down
- else if (GraphBuffer[i] <= downThres && GraphBuffer[i] < lastValue)
- {
- lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
- GraphBuffer[i] = -1;
- }
- else
- {
- lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
- GraphBuffer[i] = GraphBuffer[i-1];
-
- }
- }
- GraphBuffer[0] = GraphBuffer[1]; // Aline with first edited sample.
- RepaintGraphWindow();
- return 0;
+ printf("Applying Up Threshold: %d, Down Threshold: %d\n", upThres, downThres);
+
+ int lastValue = GraphBuffer[0];
+ GraphBuffer[0] = 0; // Will be changed at the end, but init 0 as we adjust to last samples value if no threshold kicks in.
+
+ for (int i = 1; i < GraphTraceLen; ++i) {
+ // Apply first threshold to samples heading up
+ if (GraphBuffer[i] >= upThres && GraphBuffer[i] > lastValue)
+ {
+ lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
+ GraphBuffer[i] = 1;
+ }
+ // Apply second threshold to samples heading down
+ else if (GraphBuffer[i] <= downThres && GraphBuffer[i] < lastValue)
+ {
+ lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
+ GraphBuffer[i] = -1;
+ }
+ else
+ {
+ lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
+ GraphBuffer[i] = GraphBuffer[i-1];
+
+ }
+ }
+ GraphBuffer[0] = GraphBuffer[1]; // Aline with first edited sample.
+ RepaintGraphWindow();
+ return 0;
}
int CmdZerocrossings(const char *Cmd)
{
- // Zero-crossings aren't meaningful unless the signal is zero-mean.
- CmdHpf("");
-
- int sign = 1;
- int zc = 0;
- int lastZc = 0;
-
- for (int i = 0; i < GraphTraceLen; ++i) {
- if (GraphBuffer[i] * sign >= 0) {
- // No change in sign, reproduce the previous sample count.
- zc++;
- GraphBuffer[i] = lastZc;
- } else {
- // Change in sign, reset the sample count.
- sign = -sign;
- GraphBuffer[i] = lastZc;
- if (sign > 0) {
- lastZc = zc;
- zc = 0;
- }
- }
- }
-
- RepaintGraphWindow();
- return 0;
+ // Zero-crossings aren't meaningful unless the signal is zero-mean.
+ CmdHpf("");
+
+ int sign = 1;
+ int zc = 0;
+ int lastZc = 0;
+
+ for (int i = 0; i < GraphTraceLen; ++i) {
+ if (GraphBuffer[i] * sign >= 0) {
+ // No change in sign, reproduce the previous sample count.
+ zc++;
+ GraphBuffer[i] = lastZc;
+ } else {
+ // Change in sign, reset the sample count.
+ sign = -sign;
+ GraphBuffer[i] = lastZc;
+ if (sign > 0) {
+ lastZc = zc;
+ zc = 0;
+ }
+ }
+ }
+
+ RepaintGraphWindow();
+ return 0;
}
static command_t CommandTable[] =
{
- {"help", CmdHelp, 1, "This help"},
- {"amp", CmdAmp, 1, "Amplify peaks"},
- {"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"},
+ {"help", CmdHelp, 1, "This help"},
+ {"amp", CmdAmp, 1, "Amplify peaks"},
+ {"askdemod", Cmdaskdemod, 1, "<0 or 1> -- Attempt to demodulate simple ASK tags"},
{"askmandemod", Cmdaskmandemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional[clock will try Auto-detect])"},
{"askrawdemod", Cmdaskrawdemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK tags and output binary (args optional[clock will try Auto-detect])"},
- {"autocorr", CmdAutoCorr, 1, "<window length> -- Autocorrelation over window"},
- {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] Biphase decode binary stream already in graph buffer (offset = bit to start decode from)"},
- {"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"},
- {"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"},
- {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"},
- {"dec", CmdDec, 1, "Decimate samples"},
+ {"autocorr", CmdAutoCorr, 1, "<window length> -- Autocorrelation over window"},
+ {"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] Biphase decode binary stream already in graph buffer (offset = bit to start decode from)"},
+ {"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"},
+ {"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"},
+ {"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"},
+ {"dec", CmdDec, 1, "Decimate samples"},
{"detectclock", CmdDetectClockRate, 1, "Detect ASK clock rate"},
- {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"},
- {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate graph window as a HID FSK using raw"},
- {"fskiodemod", CmdFSKdemodIO, 1, "Demodulate graph window as an IO Prox FSK using raw"},
+ {"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"},
+ {"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate graph window as a HID FSK using raw"},
+ {"fskiodemod", CmdFSKdemodIO, 1, "Demodulate graph window as an IO Prox FSK using raw"},
{"fskrawdemod", CmdFSKrawdemod, 1, "[clock rate] [invert] [rchigh] [rclow] Demodulate graph window from FSK to binary (clock = 50)(invert = 1|0)(rchigh = 10)(rclow=8)"},
- {"grid", CmdGrid, 1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
+ {"grid", CmdGrid, 1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
{"hexsamples", CmdHexsamples, 0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
- {"hide", CmdHide, 1, "Hide graph window"},
- {"hpf", CmdHpf, 1, "Remove DC offset from trace"},
- {"load", CmdLoad, 1, "<filename> -- Load trace (to graph window"},
- {"ltrim", CmdLtrim, 1, "<samples> -- Trim samples from left of trace"},
- {"rtrim", CmdRtrim, 1, "<location to end trace> -- Trim samples from right of trace"},
- {"mandemod", CmdManchesterDemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"},
- {"manrawdecode", Cmdmandecoderaw, 1, "Manchester decode binary stream already in graph buffer"},
- {"manmod", CmdManchesterMod, 1, "[clock rate] -- Manchester modulate a binary stream"},
+ {"hide", CmdHide, 1, "Hide graph window"},
+ {"hpf", CmdHpf, 1, "Remove DC offset from trace"},
+ {"load", CmdLoad, 1, "<filename> -- Load trace (to graph window"},
+ {"ltrim", CmdLtrim, 1, "<samples> -- Trim samples from left of trace"},
+ {"rtrim", CmdRtrim, 1, "<location to end trace> -- Trim samples from right of trace"},
+ {"mandemod", CmdManchesterDemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"},
+ {"manrawdecode", Cmdmandecoderaw, 1, "Manchester decode binary stream already in graph buffer"},
+ {"manmod", CmdManchesterMod, 1, "[clock rate] -- Manchester modulate a binary stream"},
{"norm", CmdNorm, 1, "Normalize max/min to +/-128"},
- {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"},
+ {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"},
{"pskclean", CmdPskClean, 1, "Attempt to clean psk wave"},
{"pskdetectclock",CmdDetectNRZpskClockRate, 1, "Detect ASK, PSK, or NRZ clock rate"},
{"pskindalademod",CmdIndalaDecode, 1, "[clock] [invert<0|1>] -- Attempt to demodulate psk indala tags and output ID binary & hex (args optional[clock will try Auto-detect])"},
{"psknrzrawdemod",CmdpskNRZrawDemod, 1, "[clock] [invert<0|1>] -- Attempt to demodulate psk or nrz tags and output binary (args optional[clock will try Auto-detect])"},
- {"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window"},
- {"save", CmdSave, 1, "<filename> -- Save trace (from graph window)"},
- {"scale", CmdScale, 1, "<int> -- Set cursor display scale"},
- {"threshold", CmdThreshold, 1, "<threshold> -- Maximize/minimize every value in the graph window depending on threshold"},
+ {"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window"},
+ {"save", CmdSave, 1, "<filename> -- Save trace (from graph window)"},
+ {"scale", CmdScale, 1, "<int> -- Set cursor display scale"},
+ {"threshold", CmdThreshold, 1, "<threshold> -- Maximize/minimize every value in the graph window depending on threshold"},
{"dirthreshold", CmdDirectionalThreshold, 1, "<thres up> <thres down> -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."},
{"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"},
- {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"},
- {NULL, NULL, 0, NULL}
+ {"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"},
+ {NULL, NULL, 0, NULL}
};
int CmdData(const char *Cmd)
{
- CmdsParse(CommandTable, Cmd);
- return 0;
+ CmdsParse(CommandTable, Cmd);
+ return 0;
}
int CmdHelp(const char *Cmd)
{
- CmdsHelp(CommandTable);
- return 0;
+ CmdsHelp(CommandTable);
+ return 0;
}
// Rough guess that this is a command from the reader
// For iClass the command byte is not part of the CRC
ComputeCrc14443(CRC_ICLASS, &frame[1], data_len-3, &b1, &b2);
- }
- else {
+ } else {
// For other data.. CRC might not be applicable (UPDATE commands etc.)
ComputeCrc14443(CRC_ICLASS, frame, data_len-2, &b1, &b2);
}
}
}
}
-
}
char *crc = crcError ? "!crc" :" ";
if(!isResponse)
{
- if(iclass) annotateIclass(explanation,sizeof(explanation),frame,data_len);
- else annotateIso14443a(explanation,sizeof(explanation),frame,data_len);
+ if(iclass)
+ annotateIclass(explanation,sizeof(explanation),frame,data_len);
+ else
+ annotateIso14443a(explanation,sizeof(explanation),frame,data_len);
}
int num_lines = (data_len - 1)/16 + 1;
static int CmdHelp(const char *Cmd);
static void waitCmd(uint8_t iLen);
+// structure and database for uid -> tagtype lookups
+typedef struct {
+ uint8_t uid;
+ char* desc;
+} manufactureName;
+
+const manufactureName manufactureMapping[] = {
+ // ID, "Vendor Country"
+ { 0x01, "Motorola UK" },
+ { 0x02, "ST Microelectronics SA France" },
+ { 0x03, "Hitachi, Ltd Japan" },
+ { 0x04, "NXP Semiconductors Germany" },
+ { 0x05, "Infineon Technologies AG Germany" },
+ { 0x06, "Cylink USA" },
+ { 0x07, "Texas Instrument France" },
+ { 0x08, "Fujitsu Limited Japan" },
+ { 0x09, "Matsushita Electronics Corporation, Semiconductor Company Japan" },
+ { 0x0A, "NEC Japan" },
+ { 0x0B, "Oki Electric Industry Co. Ltd Japan" },
+ { 0x0C, "Toshiba Corp. Japan" },
+ { 0x0D, "Mitsubishi Electric Corp. Japan" },
+ { 0x0E, "Samsung Electronics Co. Ltd Korea" },
+ { 0x0F, "Hynix / Hyundai, Korea" },
+ { 0x10, "LG-Semiconductors Co. Ltd Korea" },
+ { 0x11, "Emosyn-EM Microelectronics USA" },
+ { 0x12, "INSIDE Technology France" },
+ { 0x13, "ORGA Kartensysteme GmbH Germany" },
+ { 0x14, "SHARP Corporation Japan" },
+ { 0x15, "ATMEL France" },
+ { 0x16, "EM Microelectronic-Marin SA Switzerland" },
+ { 0x17, "KSW Microtec GmbH Germany" },
+ { 0x18, "ZMD AG Germany" },
+ { 0x19, "XICOR, Inc. USA" },
+ { 0x1A, "Sony Corporation Japan Identifier Company Country" },
+ { 0x1B, "Malaysia Microelectronic Solutions Sdn. Bhd Malaysia" },
+ { 0x1C, "Emosyn USA" },
+ { 0x1D, "Shanghai Fudan Microelectronics Co. Ltd. P.R. China" },
+ { 0x1E, "Magellan Technology Pty Limited Australia" },
+ { 0x1F, "Melexis NV BO Switzerland" },
+ { 0x20, "Renesas Technology Corp. Japan" },
+ { 0x21, "TAGSYS France" },
+ { 0x22, "Transcore USA" },
+ { 0x23, "Shanghai belling corp., ltd. China" },
+ { 0x24, "Masktech Germany Gmbh Germany" },
+ { 0x25, "Innovision Research and Technology Plc UK" },
+ { 0x26, "Hitachi ULSI Systems Co., Ltd. Japan" },
+ { 0x27, "Cypak AB Sweden" },
+ { 0x28, "Ricoh Japan" },
+ { 0x29, "ASK France" },
+ { 0x2A, "Unicore Microsystems, LLC Russian Federation" },
+ { 0x2B, "Dallas Semiconductor/Maxim USA" },
+ { 0x2C, "Impinj, Inc. USA" },
+ { 0x2D, "RightPlug Alliance USA" },
+ { 0x2E, "Broadcom Corporation USA" },
+ { 0x2F, "MStar Semiconductor, Inc Taiwan, ROC" },
+ { 0x30, "BeeDar Technology Inc. USA" },
+ { 0x31, "RFIDsec Denmark" },
+ { 0x32, "Schweizer Electronic AG Germany" },
+ { 0x33, "AMIC Technology Corp Taiwan" },
+ { 0x34, "Mikron JSC Russia" },
+ { 0x35, "Fraunhofer Institute for Photonic Microsystems Germany" },
+ { 0x36, "IDS Microchip AG Switzerland" },
+ { 0x37, "Kovio USA" },
+ { 0x38, "HMT Microelectronic Ltd Switzerland Identifier Company Country" },
+ { 0x39, "Silicon Craft Technology Thailand" },
+ { 0x3A, "Advanced Film Device Inc. Japan" },
+ { 0x3B, "Nitecrest Ltd UK" },
+ { 0x3C, "Verayo Inc. USA" },
+ { 0x3D, "HID Global USA" },
+ { 0x3E, "Productivity Engineering Gmbh Germany" },
+ { 0x3F, "Austriamicrosystems AG (reserved) Austria" },
+ { 0x40, "Gemalto SA France" },
+ { 0x41, "Renesas Electronics Corporation Japan" },
+ { 0x42, "3Alogics Inc Korea" },
+ { 0x43, "Top TroniQ Asia Limited Hong Kong" },
+ { 0x44, "Gentag Inc (USA) USA" },
+ { 0x00, "no tag-info available" } // must be the last entry
+};
+
+
+// get a product description based on the UID
+// uid[8] tag uid
+// returns description of the best match
+char* getTagInfo(uint8_t uid) {
+
+ int i;
+ int len = sizeof(manufactureMapping) / sizeof(manufactureName);
+
+ for ( i = 0; i < len; ++i )
+ if ( uid == manufactureMapping[i].uid)
+ return manufactureMapping[i].desc;
+
+ //No match, return default
+ return manufactureMapping[len-1].desc;
+}
+
int CmdHF14AList(const char *Cmd)
{
PrintAndLog("Deprecated command, use 'hf list 14a' instead");
PrintAndLog(" UID : %s", sprint_hex(card.uid, card.uidlen));
PrintAndLog(" SAK : %02x [%d]", card.sak, resp.arg[0]);
+ // Double & triple sized UID, can be mapped to a manufacturer.
+ // HACK: does this apply for Ultralight cards?
+ if ( card.uidlen > 4 ) {
+ PrintAndLog("MANUFACTURER : %s", getTagInfo(card.uid[0]));
+ }
+
switch (card.sak) {
case 0x00: PrintAndLog("TYPE : NXP MIFARE Ultralight | Ultralight C"); break;
case 0x01: PrintAndLog("TYPE : NXP TNP3xxx Activision Game Appliance"); break;
default: ;
}
-
// try to request ATS even if tag claims not to support it
if (select_status == 2) {
uint8_t rats[] = { 0xE0, 0x80 }; // FSDI=8 (FSD=256), CID=0
card.ats_len = resp.arg[0]; // note: ats_len includes CRC Bytes
}
- // disconnect
- c.arg[0] = 0;
- c.arg[1] = 0;
- c.arg[2] = 0;
- SendCommand(&c);
-
-
if(card.ats_len >= 3) { // a valid ATS consists of at least the length byte (TL) and 2 CRC bytes
bool ta1 = 0, tb1 = 0, tc1 = 0;
int pos;
PrintAndLog("proprietary non iso14443-4 card found, RATS not supported");
}
+
+ // try to see if card responses to "chinese magic backdoor" commands.
+ c.cmd = CMD_MIFARE_CIDENT;
+ c.arg[0] = 0;
+ c.arg[1] = 0;
+ c.arg[2] = 0;
+ SendCommand(&c);
+ WaitForResponse(CMD_ACK,&resp);
+ uint8_t isOK = resp.arg[0] & 0xff;
+ PrintAndLog(" Answers to chinese magic backdoor commands: %s", (isOK ? "YES" : "NO") );
+
+ // disconnect
+ c.cmd = CMD_READER_ISO_14443a;
+ c.arg[0] = 0;
+ c.arg[1] = 0;
+ c.arg[2] = 0;
+ SendCommand(&c);
+
return select_status;
}
uint8_t active=0;
uint8_t active_select=0;
uint16_t numbits=0;
+ uint16_t timeout=0;
+ uint8_t bTimeout=0;
char buf[5]="";
int i=0;
- uint8_t data[100];
+ uint8_t data[USB_CMD_DATA_SIZE];
unsigned int datalen=0, temp;
if (strlen(cmd)<2) {
- PrintAndLog("Usage: hf 14a raw [-r] [-c] [-p] [-f] [-b] <number of bits> <0A 0B 0C ... hex>");
+ PrintAndLog("Usage: hf 14a raw [-r] [-c] [-p] [-f] [-b] [-t] <number of bits> <0A 0B 0C ... hex>");
PrintAndLog(" -r do not read response");
PrintAndLog(" -c calculate and append CRC");
PrintAndLog(" -p leave the signal field ON after receive");
PrintAndLog(" -a active signal field ON without select");
PrintAndLog(" -s active signal field ON with select");
PrintAndLog(" -b number of bits to send. Useful for send partial byte");
+ PrintAndLog(" -t timeout");
return 0;
}
while(cmd[i]!=' ' && cmd[i]!='\0') { i++; }
i-=2;
break;
+ case 't':
+ bTimeout=1;
+ sscanf(cmd+i+2,"%d",&temp);
+ timeout = temp & 0xFFFF;
+ i+=3;
+ while(cmd[i]!=' ' && cmd[i]!='\0') { i++; }
+ i+=2;
+ break;
default:
PrintAndLog("Invalid option");
return 0;
if (strlen(buf)>=2) {
sscanf(buf,"%x",&temp);
data[datalen]=(uint8_t)(temp & 0xff);
- datalen++;
*buf=0;
+ if (++datalen>sizeof(data)){
+ if (crc)
+ PrintAndLog("Buffer is full, we can't add CRC to your data");
+ break;
+ }
}
continue;
}
PrintAndLog("Invalid char on input");
return 0;
}
- if(crc && datalen>0)
+ if(crc && datalen>0 && datalen<sizeof(data)-2)
{
uint8_t first, second;
ComputeCrc14443(CRC_14443_A, data, datalen, &first, &second);
if(active)
c.arg[0] |= ISO14A_NO_SELECT;
}
+ if(bTimeout){
+ #define MAX_TIMEOUT 624*105 // max timeout is 624 ms
+ c.arg[0] |= ISO14A_SET_TIMEOUT;
+ c.arg[2] = timeout * 105; // each bit is about 9.4 us
+ if(c.arg[2]>MAX_TIMEOUT) {
+ c.arg[2] = MAX_TIMEOUT;
+ PrintAndLog("Set timeout to 624 ms. The max we can wait for response");
+ }
+ }
if(power)
c.arg[0] |= ISO14A_NO_DISCONNECT;
if(datalen>0)
c.arg[0] |= ISO14A_RAW;
- c.arg[1] = datalen;
- c.arg[2] = numbits;
+ // Max buffer is USB_CMD_DATA_SIZE
+ c.arg[1] = (datalen & 0xFFFF) | (numbits << 16);
memcpy(c.d.asBytes,data,datalen);
SendCommand(&c);
UsbCommand resp;
char *hexout;
- if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
+ if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
recv = resp.d.asBytes;
uint8_t iLen = iSelect ? resp.arg[1] : resp.arg[0];
PrintAndLog("received %i octets",iLen);
int CmdHF14ASim(const char *Cmd);
int CmdHF14ASnoop(const char *Cmd);
+char* getTagInfo(uint8_t uid);
#endif
#include "cmdhf14b.h"
#include "cmdmain.h"
-
static int CmdHelp(const char *Cmd);
int CmdHF14BDemod(const char *Cmd)
int CmdHF14BList(const char *Cmd)
{
- uint8_t got[960];
+ uint8_t got[TRACE_BUFFER_SIZE];
GetFromBigBuf(got,sizeof(got),0);
WaitForResponse(CMD_ACK,NULL);
int prev = -1;
for(;;) {
- if(i >= 900) {
- break;
- }
+
+ if(i >= TRACE_BUFFER_SIZE) { break; }
bool isResponse;
int timestamp = *((uint32_t *)(got+i));
if(len > 100) {
break;
}
- if(i + len >= 900) {
+ if(i + len >= TRACE_BUFFER_SIZE) {
break;
}
bool isSrix4k = true;
char str[20];
- if (cmdp == 'h' || cmdp == 'H') {
+ if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: hf 14b write <1|2> <BLOCK> <DATA>");
- PrintAndLog("");
- PrintAndLog(" sample: hf 14b write 1 127 11223344");
- PrintAndLog(" sample: hf 14b write 1 255 11223344");
- PrintAndLog(" sample: hf 14b write 2 15 11223344");
- PrintAndLog(" sample: hf 14b write 2 255 11223344");
+ PrintAndLog(" [1 = SRIX4K]");
+ PrintAndLog(" [2 = SRI512]");
+ PrintAndLog(" [BLOCK number depends on tag, special block == FF]");
+ PrintAndLog(" sample: hf 14b write 1 7F 11223344");
+ PrintAndLog(" : hf 14b write 1 FF 11223344");
+ PrintAndLog(" : hf 14b write 2 15 11223344");
+ PrintAndLog(" : hf 14b write 2 FF 11223344");
return 0;
}
- if ( param_getchar(Cmd, 0) == '2' )
+ if ( cmdp == '2' )
isSrix4k = false;
- blockno = param_get8(Cmd, 1);
+ //blockno = param_get8(Cmd, 1);
+
+ if ( param_gethex(Cmd,1, &blockno, 2) ) {
+ PrintAndLog("Block number must include 2 HEX symbols");
+ return 0;
+ }
if ( isSrix4k ){
if ( blockno > 0x7f && blockno != 0xff ){
}
if ( blockno == 0xff)
- PrintAndLog("Writing to special block %02X [ %s]", blockno, sprint_hex(data,4) );
+ PrintAndLog("[%s] Write special block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512" , blockno, sprint_hex(data,4) );
else
- PrintAndLog("Writing to block %02X [ %s]", blockno, sprint_hex(data,4) );
+ PrintAndLog("[%s] Write block %02X [ %s ]", (isSrix4k)?"SRIX4K":"SRI512", blockno, sprint_hex(data,4) );
sprintf(str, "-c -p 09 %02x %02x%02x%02x%02x", blockno, data[0], data[1], data[2], data[3]);
+
CmdHF14BCmdRaw(str);
return 0;
}
const productName uidmapping[] = {
+
// UID, #significant Bits, "Vendor(+Product)"
- { 0xE001000000000000LL, 16, "Motorola" },
- { 0xE002000000000000LL, 16, "ST Microelectronics" },
- { 0xE003000000000000LL, 16, "Hitachi" },
- { 0xE004000000000000LL, 16, "NXP(Philips)" },
+ { 0xE001000000000000LL, 16, "Motorola UK" },
+
+ // E0 02 xx
+ // 02 = ST Microelectronics
+ // XX = IC id (Chip ID Family)
+ { 0xE002000000000000LL, 16, "ST Microelectronics SA France" },
+ { 0xE002050000000000LL, 24, "ST Microelectronics; LRI64 [IC id = 05]"},
+ { 0xE002080000000000LL, 24, "ST Microelectronics; LRI2K [IC id = 08]"},
+ { 0xE0020A0000000000LL, 24, "ST Microelectronics; LRIS2K [IC id = 10]"},
+ { 0xE002440000000000LL, 24, "ST Microelectronics; LRIS64K [IC id = 68]"},
+
+ { 0xE003000000000000LL, 16, "Hitachi, Ltd Japan" },
+
+ // E0 04 xx
+ // 04 = Manufacturer code (Philips/NXP)
+ // XX = IC id (Chip ID Family)
+ //I-Code SLI SL2 ICS20 [IC id = 01]
+ //I-Code SLI-S [IC id = 02]
+ //I-Code SLI-L [IC id = 03]
+ //I-Code SLIX [IC id = 01 + bit36 set to 1 (starting from bit0 - different from normal SLI)]
+ //I-Code SLIX-S [IC id = 02 + bit36 set to 1]
+ //I-Code SLIX-L [IC id = 03 + bit36 set to 1]
+ { 0xE004000000000000LL, 16, "NXP Semiconductors Germany (Philips)" },
{ 0xE004010000000000LL, 24, "NXP(Philips); IC SL2 ICS20/ICS21(SLI) ICS2002/ICS2102(SLIX)" },
{ 0xE004020000000000LL, 24, "NXP(Philips); IC SL2 ICS53/ICS54(SLI-S) ICS5302/ICS5402(SLIX-S)" },
{ 0xE004030000000000LL, 24, "NXP(Philips); IC SL2 ICS50/ICS51(SLI-L) ICS5002/ICS5102(SLIX-L)" },
- { 0xE005000000000000LL, 16, "Infineon" },
- { 0xE005400000000000LL, 24, "Infineon; 56x32bit" },
- { 0xE006000000000000LL, 16, "Cylinc" },
- { 0xE007000000000000LL, 16, "Texas Instrument; " },
+
+ // E0 05 XX .. .. ..
+ // 05 = Manufacturer code (Infineon)
+ // XX = IC id (Chip ID Family)
+ { 0xE005000000000000LL, 16, "Infineon Technologies AG Germany" },
+ { 0xE005A10000000000LL, 24, "Infineon; SRF55V01P [IC id = 161] plain mode 1kBit"},
+ { 0xE005A80000000000LL, 24, "Infineon; SRF55V01P [IC id = 168] pilot series 1kBit"},
+ { 0xE005400000000000LL, 24, "Infineon; SRF55V02P [IC id = 64] plain mode 2kBit"},
+ { 0xE005000000000000LL, 24, "Infineon; SRF55V10P [IC id = 00] plain mode 10KBit"},
+ { 0xE005500000000000LL, 24, "Infineon; SRF55V02S [IC id = 80] secure mode 2kBit"},
+ { 0xE005100000000000LL, 24, "Infineon; SRF55V10S [IC id = 16] secure mode 10KBit"},
+ { 0xE0051E0000000000LL, 23, "Infineon; SLE66r01P [IC id = 3x = My-d Move or My-d move NFC]"},
+ { 0xE005200000000000LL, 21, "Infineon; SLE66r01P [IC id = 3x = My-d Move or My-d move NFC]"},
+
+ { 0xE006000000000000LL, 16, "Cylink USA" },
+
+
+ // E0 07 xx
+ // 07 = Texas Instruments
+ // XX = from bit 41 to bit 43 = product configuration - from bit 44 to bit 47 IC id (Chip ID Family)
+ //Tag IT RFIDType-I Plus, 2kBit, TI Inlay
+ //Tag-it HF-I Plus Inlay [IC id = 00] -> b'0000 000 2kBit
+ //Tag-it HF-I Plus Chip [IC id = 64] -> b'1000 000 2kBit
+ //Tag-it HF-I Standard Chip / Inlays [IC id = 96] -> b'1100 000 256Bit
+ //Tag-it HF-I Pro Chip / Inlays [IC id = 98] -> b'1100 010 256Bit, Password protection
+ { 0xE007000000000000LL, 16, "Texas Instrument France" },
{ 0xE007000000000000LL, 20, "Texas Instrument; Tag-it HF-I Plus Inlay; 64x32bit" },
{ 0xE007100000000000LL, 20, "Texas Instrument; Tag-it HF-I Plus Chip; 64x32bit" },
{ 0xE007800000000000LL, 23, "Texas Instrument; Tag-it HF-I Plus (RF-HDT-DVBB tag or Third Party Products)" },
{ 0xE007C00000000000LL, 23, "Texas Instrument; Tag-it HF-I Standard; 8x32bit" },
{ 0xE007C40000000000LL, 23, "Texas Instrument; Tag-it HF-I Pro; 8x23bit; password" },
- { 0xE008000000000000LL, 16, "Fujitsu" },
- { 0xE009000000000000LL, 16, "Matsushita" },
- { 0xE00A000000000000LL, 16, "NEC" },
- { 0xE00B000000000000LL, 16, "Oki Electric" },
- { 0xE00C000000000000LL, 16, "Toshiba" },
- { 0xE00D000000000000LL, 16, "Mitsubishi" },
- { 0xE00E000000000000LL, 16, "Samsung" },
- { 0xE00F000000000000LL, 16, "Hyundai" },
- { 0xE010000000000000LL, 16, "LG-Semiconductors" },
+
+ { 0xE008000000000000LL, 16, "Fujitsu Limited Japan" },
+ { 0xE009000000000000LL, 16, "Matsushita Electronics Corporation, Semiconductor Company Japan" },
+ { 0xE00A000000000000LL, 16, "NEC Japan" },
+ { 0xE00B000000000000LL, 16, "Oki Electric Industry Co. Ltd Japan" },
+ { 0xE00C000000000000LL, 16, "Toshiba Corp. Japan" },
+ { 0xE00D000000000000LL, 16, "Mitsubishi Electric Corp. Japan" },
+ { 0xE00E000000000000LL, 16, "Samsung Electronics Co. Ltd Korea" },
+ { 0xE00F000000000000LL, 16, "Hynix / Hyundai, Korea" },
+ { 0xE010000000000000LL, 16, "LG-Semiconductors Co. Ltd Korea" },
+ { 0xE011000000000000LL, 16, "Emosyn-EM Microelectronics USA" },
+
{ 0xE012000000000000LL, 16, "HID Corporation" },
- { 0xE016000000000000LL, 16, "EM-Marin SA (Skidata)" },
+ { 0xE012000000000000LL, 16, "INSIDE Technology France" },
+ { 0xE013000000000000LL, 16, "ORGA Kartensysteme GmbH Germany" },
+ { 0xE014000000000000LL, 16, "SHARP Corporation Japan" },
+ { 0xE015000000000000LL, 16, "ATMEL France" },
+
+ { 0xE016000000000000LL, 16, "EM Microelectronic-Marin SA Switzerland (Skidata)" },
{ 0xE016040000000000LL, 24, "EM-Marin SA (Skidata Keycard-eco); EM4034? no 'read', just 'readmulti'" },
{ 0xE0160c0000000000LL, 24, "EM-Marin SA; EM4035?" },
{ 0xE016100000000000LL, 24, "EM-Marin SA (Skidata); EM4135; 36x64bit start page 13" },
{ 0xE016940000000000LL, 24, "EM-Marin SA (Skidata); 51x64bit" },
+
+ { 0xE017000000000000LL, 16, "KSW Microtec GmbH Germany" },
+ { 0xE018000000000000LL, 16, "ZMD AG Germany" },
+ { 0xE019000000000000LL, 16, "XICOR, Inc. USA" },
+ { 0xE01A000000000000LL, 16, "Sony Corporation Japan Identifier Company Country" },
+ { 0xE01B000000000000LL, 16, "Malaysia Microelectronic Solutions Sdn. Bhd Malaysia" },
+ { 0xE01C000000000000LL, 16, "Emosyn USA" },
+ { 0xE01D000000000000LL, 16, "Shanghai Fudan Microelectronics Co. Ltd. P.R. China" },
+ { 0xE01E000000000000LL, 16, "Magellan Technology Pty Limited Australia" },
+ { 0xE01F000000000000LL, 16, "Melexis NV BO Switzerland" },
+ { 0xE020000000000000LL, 16, "Renesas Technology Corp. Japan" },
+ { 0xE021000000000000LL, 16, "TAGSYS France" },
+ { 0xE022000000000000LL, 16, "Transcore USA" },
+ { 0xE023000000000000LL, 16, "Shanghai belling corp., ltd. China" },
+ { 0xE024000000000000LL, 16, "Masktech Germany Gmbh Germany" },
+ { 0xE025000000000000LL, 16, "Innovision Research and Technology Plc UK" },
+ { 0xE026000000000000LL, 16, "Hitachi ULSI Systems Co., Ltd. Japan" },
+ { 0xE027000000000000LL, 16, "Cypak AB Sweden" },
+ { 0xE028000000000000LL, 16, "Ricoh Japan" },
+ { 0xE029000000000000LL, 16, "ASK France" },
+ { 0xE02A000000000000LL, 16, "Unicore Microsystems, LLC Russian Federation" },
+ { 0xE02B000000000000LL, 16, "Dallas Semiconductor/Maxim USA" },
+ { 0xE02C000000000000LL, 16, "Impinj, Inc. USA" },
+ { 0xE02D000000000000LL, 16, "RightPlug Alliance USA" },
+ { 0xE02E000000000000LL, 16, "Broadcom Corporation USA" },
+ { 0xE02F000000000000LL, 16, "MStar Semiconductor, Inc Taiwan, ROC" },
+ { 0xE030000000000000LL, 16, "BeeDar Technology Inc. USA" },
+ { 0xE031000000000000LL, 16, " RFIDsec Denmark" },
+ { 0xE032000000000000LL, 16, " Schweizer Electronic AG Germany" },
+ { 0xE033000000000000LL, 16, " AMIC Technology Corp Taiwan" },
+ { 0xE034000000000000LL, 16, "Mikron JSC Russia" },
+ { 0xE035000000000000LL, 16, "Fraunhofer Institute for Photonic Microsystems Germany" },
+ { 0xE036000000000000LL, 16, "IDS Microchip AG Switzerland" },
+ { 0xE037000000000000LL, 16, "Kovio USA" },
+ { 0xE038000000000000LL, 16, "HMT Microelectronic Ltd Switzerland Identifier Company Country" },
+ { 0xE039000000000000LL, 16, "Silicon Craft Technology Thailand" },
+ { 0xE03A000000000000LL, 16, "Advanced Film Device Inc. Japan" },
+ { 0xE03B000000000000LL, 16, "Nitecrest Ltd UK" },
+ { 0xE03C000000000000LL, 16, "Verayo Inc. USA" },
+ { 0xE03D000000000000LL, 16, "HID Global USA" },
+ { 0xE03E000000000000LL, 16, "Productivity Engineering Gmbh Germany" },
+ { 0xE03F000000000000LL, 16, "Austriamicrosystems AG (reserved) Austria" },
+ { 0xE040000000000000LL, 16, "Gemalto SA France" },
+ { 0xE041000000000000LL, 16, "Renesas Electronics Corporation Japan" },
+ { 0xE042000000000000LL, 16, "3Alogics Inc Korea" },
+ { 0xE043000000000000LL, 16, "Top TroniQ Asia Limited Hong Kong" },
+ { 0xE044000000000000LL, 16, "Gentag Inc (USA) USA" },
{ 0,0,"no tag-info available" } // must be the last entry
};
#include "cmdparser.h"
#include "cmdhflegic.h"
#include "cmdmain.h"
-
+#include "util.h"
static int CmdHelp(const char *Cmd);
static command_t CommandTable[] =
int CmdLegicLoad(const char *Cmd)
{
- FILE *f = fopen(Cmd, "r");
+ char filename[FILE_PATH_SIZE] = {0x00};
+ int len = 0;
+
+ if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {
+ PrintAndLog("It loads datasamples from the file `filename`");
+ PrintAndLog("Usage: hf legic load <file name>");
+ PrintAndLog(" sample: hf legic load filename");
+ return 0;
+ }
+
+ len = strlen(Cmd);
+ if (len > FILE_PATH_SIZE) {
+ PrintAndLog("Filepath too long (was %s bytes), max allowed is %s ", len, FILE_PATH_SIZE);
+ return 0;
+ }
+ memcpy(filename, Cmd, len);
+
+ FILE *f = fopen(filename, "r");
if(!f) {
PrintAndLog("couldn't open '%s'", Cmd);
return -1;
int requested = 1024;
int offset = 0;
int delivered = 0;
- char filename[1024];
+ char filename[FILE_PATH_SIZE];
uint8_t got[1024];
sscanf(Cmd, " %s %i %i", filename, &requested, &offset);
if (isOK != 1) return 1;\r
\r
// execute original function from util nonce2key\r
- if (nonce2key(uid, nt, nr, par_list, ks_list, &r_key))\r
- {\r
+ if (nonce2key(uid, nt, nr, par_list, ks_list, &r_key)) {\r
isOK = 2;\r
PrintAndLog("Key not found (lfsr_common_prefix list is null). Nt=%08x", nt); \r
} else {\r
return 2;\r
}\r
}\r
+ \r
fclose(fin);\r
- // Read access rights to sectors\r
\r
PrintAndLog("|-----------------------------------------|");\r
PrintAndLog("|------ Reading sector access bits...-----|");\r
}\r
}\r
\r
- // Read blocks and print to file\r
- \r
PrintAndLog("|-----------------------------------------|");\r
PrintAndLog("|----- Dumping all blocks to file... -----|");\r
PrintAndLog("|-----------------------------------------|");\r
{\r
uint8_t sectorNo,blockNo;\r
uint8_t keyType = 0;\r
- uint8_t key[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};\r
- uint8_t bldata[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};\r
+ uint8_t key[6] = {0xFF};\r
+ uint8_t bldata[16] = {0x00};\r
uint8_t keyA[40][6];\r
uint8_t keyB[40][6];\r
uint8_t numSectors;\r
return 0;\r
}\r
\r
- if ((fdump = fopen("dumpdata.bin","rb")) == NULL) {\r
- PrintAndLog("Could not find file dumpdata.bin");\r
- return 1;\r
- }\r
if ((fkeys = fopen("dumpkeys.bin","rb")) == NULL) {\r
PrintAndLog("Could not find file dumpkeys.bin");\r
- fclose(fdump);\r
return 1;\r
}\r
\r
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {\r
if (fread(keyA[sectorNo], 1, 6, fkeys) == 0) {\r
PrintAndLog("File reading error (dumpkeys.bin).");\r
- fclose(fdump);\r
+\r
fclose(fkeys);\r
return 2;\r
}\r
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {\r
if (fread(keyB[sectorNo], 1, 6, fkeys) == 0) {\r
PrintAndLog("File reading error (dumpkeys.bin).");\r
- fclose(fdump);\r
fclose(fkeys);\r
return 2;\r
}\r
}\r
+\r
fclose(fkeys);\r
\r
+ if ((fdump = fopen("dumpdata.bin","rb")) == NULL) {\r
+ PrintAndLog("Could not find file dumpdata.bin");\r
+ return 1;\r
+ } \r
PrintAndLog("Restoring dumpdata.bin to card");\r
\r
for (sectorNo = 0; sectorNo < numSectors; sectorNo++) {\r
uint8_t trgKeyType = 0;\r
uint8_t SectorsCnt = 0;\r
uint8_t key[6] = {0, 0, 0, 0, 0, 0};\r
- uint8_t keyBlock[6*6];\r
+ uint8_t keyBlock[13*6];\r
uint64_t key64 = 0;\r
bool transferToEml = false;\r
\r
cmdp = param_getchar(Cmd, 0);\r
blockNo = param_get8(Cmd, 1);\r
ctmp = param_getchar(Cmd, 2);\r
+ \r
if (ctmp != 'a' && ctmp != 'A' && ctmp != 'b' && ctmp != 'B') {\r
PrintAndLog("Key type must be A or B");\r
return 1;\r
}\r
- if (ctmp != 'A' && ctmp != 'a') keyType = 1;\r
+ \r
+ if (ctmp != 'A' && ctmp != 'a') \r
+ keyType = 1;\r
+ \r
if (param_gethex(Cmd, 3, key, 12)) {\r
PrintAndLog("Key must include 12 HEX symbols");\r
return 1;\r
PrintAndLog("Target key type must be A or B");\r
return 1;\r
}\r
- if (ctmp != 'A' && ctmp != 'a') trgKeyType = 1;\r
+ if (ctmp != 'A' && ctmp != 'a') \r
+ trgKeyType = 1;\r
} else {\r
+ \r
switch (cmdp) {\r
case '0': SectorsCnt = 05; break;\r
case '1': SectorsCnt = 16; break;\r
num_to_bytes(0xa0a1a2a3a4a5, 6, (uint8_t*)(keyBlock + 3 * 6));\r
num_to_bytes(0xb0b1b2b3b4b5, 6, (uint8_t*)(keyBlock + 4 * 6));\r
num_to_bytes(0xaabbccddeeff, 6, (uint8_t*)(keyBlock + 5 * 6));\r
+ num_to_bytes(0x4d3a99c351dd, 6, (uint8_t*)(keyBlock + 6 * 6));\r
+ num_to_bytes(0x1a982c7e459a, 6, (uint8_t*)(keyBlock + 7 * 6));\r
+ num_to_bytes(0xd3f7d3f7d3f7, 6, (uint8_t*)(keyBlock + 8 * 6));\r
+ num_to_bytes(0x714c5c886e97, 6, (uint8_t*)(keyBlock + 9 * 6));\r
+ num_to_bytes(0x587ee5f9350f, 6, (uint8_t*)(keyBlock + 10 * 6));\r
+ num_to_bytes(0xa0478cc39091, 6, (uint8_t*)(keyBlock + 11 * 6));\r
+ num_to_bytes(0x533cb6c723f6, 6, (uint8_t*)(keyBlock + 12 * 6));\r
+ num_to_bytes(0x8fd0a4f256e9, 6, (uint8_t*)(keyBlock + 13 * 6));\r
\r
PrintAndLog("Testing known keys. Sector count=%d", SectorsCnt);\r
for (i = 0; i < SectorsCnt; i++) {\r
}\r
}\r
\r
- \r
// nested sectors\r
iterations = 0;\r
PrintAndLog("nested...");\r
if(mfnested(blockNo, keyType, key, FirstBlockOfSector(sectorNo), trgKeyType, keyBlock, calibrate)) {\r
PrintAndLog("Nested error.\n");\r
free(e_sector);\r
- return 2;\r
- }\r
+ return 2; }\r
else {\r
calibrate = false;\r
}\r
} \r
\r
FILE * f;\r
- char filename[256]={0};\r
+ char filename[FILE_PATH_SIZE]={0};\r
char buf[13];\r
uint8_t *keyBlock = NULL, *p;\r
uint8_t stKeyBlock = 20;\r
keycnt++;\r
} else {\r
// May be a dic file\r
- if ( param_getstr(Cmd, 2 + i,filename) > 255 ) {\r
+ if ( param_getstr(Cmd, 2 + i,filename) >= FILE_PATH_SIZE ) {\r
PrintAndLog("File name too long");\r
free(keyBlock);\r
return 2;\r
int CmdHF14AMfELoad(const char *Cmd)\r
{\r
FILE * f;\r
- char filename[20];\r
+ char filename[FILE_PATH_SIZE];\r
char *fnameptr = filename;\r
char buf[64];\r
uint8_t buf8[64];\r
- int i, len, blockNum;\r
+ int i, len, blockNum, numBlocks;\r
+ int nameParamNo = 1;\r
\r
memset(filename, 0, sizeof(filename));\r
memset(buf, 0, sizeof(buf));\r
\r
- if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {\r
+ char ctmp = param_getchar(Cmd, 0);\r
+ \r
+ if ( ctmp == 'h' || ctmp == 0x00) {\r
PrintAndLog("It loads emul dump from the file `filename.eml`");\r
- PrintAndLog("Usage: hf mf eload <file name w/o `.eml`>");\r
+ PrintAndLog("Usage: hf mf eload [card memory] <file name w/o `.eml`>");\r
+ PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");\r
+ PrintAndLog("");\r
PrintAndLog(" sample: hf mf eload filename");\r
+ PrintAndLog(" hf mf eload 4 filename");\r
return 0;\r
} \r
\r
- len = strlen(Cmd);\r
- if (len > 14) len = 14;\r
+ switch (ctmp) {\r
+ case '0' : numBlocks = 5*4; break;\r
+ case '1' : \r
+ case '\0': numBlocks = 16*4; break;\r
+ case '2' : numBlocks = 32*4; break;\r
+ case '4' : numBlocks = 256; break;\r
+ default: {\r
+ numBlocks = 16*4;\r
+ nameParamNo = 0;\r
+ }\r
+ }\r
+\r
+ len = param_getstr(Cmd,nameParamNo,filename);\r
+ \r
+ if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;\r
\r
- memcpy(filename, Cmd, len);\r
fnameptr += len;\r
\r
sprintf(fnameptr, ".eml"); \r
blockNum = 0;\r
while(!feof(f)){\r
memset(buf, 0, sizeof(buf));\r
+ \r
if (fgets(buf, sizeof(buf), f) == NULL) {\r
- if((blockNum == 16*4) || (blockNum == 32*4 + 8*16)) { // supports both old (1K) and new (4K) .eml files)\r
- break;\r
- }\r
+ \r
+ if (blockNum >= numBlocks) break;\r
+ \r
PrintAndLog("File reading error.");\r
fclose(f);\r
return 2;\r
}\r
+ \r
if (strlen(buf) < 32){\r
if(strlen(buf) && feof(f))\r
break;\r
fclose(f);\r
return 2;\r
}\r
+ \r
for (i = 0; i < 32; i += 2) {\r
sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);\r
}\r
}\r
blockNum++;\r
\r
- if (blockNum >= 32*4 + 8*16) break;\r
+ if (blockNum >= numBlocks) break;\r
}\r
fclose(f);\r
\r
- if ((blockNum != 16*4) && (blockNum != 32*4 + 8*16)) {\r
- PrintAndLog("File content error. There must be 64 or 256 blocks.");\r
+ if ((blockNum != numBlocks)) {\r
+ PrintAndLog("File content error. Got %d must be %d blocks.",blockNum, numBlocks);\r
return 4;\r
}\r
PrintAndLog("Loaded %d blocks from file: %s", blockNum, filename);\r
int CmdHF14AMfESave(const char *Cmd)\r
{\r
FILE * f;\r
- char filename[20];\r
+ char filename[FILE_PATH_SIZE];\r
char * fnameptr = filename;\r
uint8_t buf[64];\r
- int i, j, len;\r
+ int i, j, len, numBlocks;\r
+ int nameParamNo = 1;\r
\r
memset(filename, 0, sizeof(filename));\r
memset(buf, 0, sizeof(buf));\r
\r
- if (param_getchar(Cmd, 0) == 'h') {\r
+ char ctmp = param_getchar(Cmd, 0);\r
+ \r
+ if ( ctmp == 'h' || ctmp == 'H') {\r
PrintAndLog("It saves emul dump into the file `filename.eml` or `cardID.eml`");\r
- PrintAndLog("Usage: hf mf esave [file name w/o `.eml`]");\r
+ PrintAndLog(" Usage: hf mf esave [card memory] [file name w/o `.eml`]");\r
+ PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");\r
+ PrintAndLog("");\r
PrintAndLog(" sample: hf mf esave ");\r
- PrintAndLog(" hf mf esave filename");\r
+ PrintAndLog(" hf mf esave 4");\r
+ PrintAndLog(" hf mf esave 4 filename");\r
return 0;\r
} \r
\r
- len = strlen(Cmd);\r
- if (len > 14) len = 14;\r
+ switch (ctmp) {\r
+ case '0' : numBlocks = 5*4; break;\r
+ case '1' : \r
+ case '\0': numBlocks = 16*4; break;\r
+ case '2' : numBlocks = 32*4; break;\r
+ case '4' : numBlocks = 256; break;\r
+ default: {\r
+ numBlocks = 16*4;\r
+ nameParamNo = 0;\r
+ }\r
+ }\r
+\r
+ len = param_getstr(Cmd,nameParamNo,filename);\r
+ \r
+ if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;\r
\r
+ // user supplied filename?\r
if (len < 1) {\r
- // get filename\r
+ // get filename (UID from memory)\r
if (mfEmlGetMem(buf, 0, 1)) {\r
- PrintAndLog("Cant get block: %d", 0);\r
- return 1;\r
+ PrintAndLog("Can\'t get UID from block: %d", 0);\r
+ sprintf(filename, "dump.eml"); \r
}\r
for (j = 0; j < 7; j++, fnameptr += 2)\r
- sprintf(fnameptr, "%02x", buf[j]); \r
+ sprintf(fnameptr, "%02X", buf[j]); \r
} else {\r
- memcpy(filename, Cmd, len);\r
fnameptr += len;\r
}\r
\r
+ // add file extension\r
sprintf(fnameptr, ".eml"); \r
\r
// open file\r
f = fopen(filename, "w+");\r
\r
+ if ( !f ) {\r
+ PrintAndLog("Can't open file %s ", filename);\r
+ return 1;\r
+ }\r
+ \r
// put hex\r
- for (i = 0; i < 32*4 + 8*16; i++) {\r
+ for (i = 0; i < numBlocks; i++) {\r
if (mfEmlGetMem(buf, i, 1)) {\r
PrintAndLog("Cant get block: %d", i);\r
break;\r
}\r
fclose(f);\r
\r
- PrintAndLog("Saved to file: %s", filename);\r
+ PrintAndLog("Saved %d blocks to file: %s", numBlocks, filename);\r
\r
return 0;\r
}\r
int CmdHF14AMfEKeyPrn(const char *Cmd)\r
{\r
int i;\r
+ uint8_t numSectors;\r
uint8_t data[16];\r
uint64_t keyA, keyB;\r
\r
+ if (param_getchar(Cmd, 0) == 'h') {\r
+ PrintAndLog("It prints the keys loaded in the emulator memory");\r
+ PrintAndLog("Usage: hf mf ekeyprn [card memory]");\r
+ PrintAndLog(" [card memory]: 0 = 320 bytes (Mifare Mini), 1 = 1K (default), 2 = 2K, 4 = 4K");\r
+ PrintAndLog("");\r
+ PrintAndLog(" sample: hf mf ekeyprn 1");\r
+ return 0;\r
+ } \r
+\r
+ char cmdp = param_getchar(Cmd, 0);\r
+ \r
+ switch (cmdp) {\r
+ case '0' : numSectors = 5; break;\r
+ case '1' : \r
+ case '\0': numSectors = 16; break;\r
+ case '2' : numSectors = 32; break;\r
+ case '4' : numSectors = 40; break;\r
+ default: numSectors = 16;\r
+ } \r
+ \r
PrintAndLog("|---|----------------|----------------|");\r
PrintAndLog("|sec|key A |key B |");\r
PrintAndLog("|---|----------------|----------------|");\r
- for (i = 0; i < 40; i++) {\r
+ for (i = 0; i < numSectors; i++) {\r
if (mfEmlGetMem(data, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1)) {\r
PrintAndLog("error get block %d", FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1);\r
break;\r
int CmdHF14AMfCLoad(const char *Cmd)\r
{\r
FILE * f;\r
- char filename[20];\r
+ char filename[FILE_PATH_SIZE] = {0x00};\r
char * fnameptr = filename;\r
- char buf[64];\r
- uint8_t buf8[64];\r
+ char buf[64] = {0x00};\r
+ uint8_t buf8[64] = {0x00};\r
uint8_t fillFromEmulator = 0;\r
int i, len, blockNum, flags;\r
\r
- memset(filename, 0, sizeof(filename));\r
- memset(buf, 0, sizeof(buf));\r
+ // memset(filename, 0, sizeof(filename));\r
+ // memset(buf, 0, sizeof(buf));\r
\r
if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {\r
PrintAndLog("It loads magic Chinese card (only works with!!!) from the file `filename.eml`");\r
return 0;\r
} else {\r
len = strlen(Cmd);\r
- if (len > 14) len = 14;\r
+ if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;\r
\r
memcpy(filename, Cmd, len);\r
fnameptr += len;\r
}\r
fclose(f);\r
\r
- if (blockNum != 16 * 4){\r
+ if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){\r
PrintAndLog("File content error. There must be 64 blocks");\r
return 4;\r
}\r
int CmdHF14AMfCSave(const char *Cmd) {\r
\r
FILE * f;\r
- char filename[20];\r
+ char filename[FILE_PATH_SIZE] = {0x00};\r
char * fnameptr = filename;\r
uint8_t fillFromEmulator = 0;\r
- uint8_t buf[64];\r
+ uint8_t buf[64] = {0x00};\r
int i, j, len, flags;\r
\r
- memset(filename, 0, sizeof(filename));\r
- memset(buf, 0, sizeof(buf));\r
+ // memset(filename, 0, sizeof(filename));\r
+ // memset(buf, 0, sizeof(buf));\r
\r
if (param_getchar(Cmd, 0) == 'h') {\r
PrintAndLog("It saves `magic Chinese` card dump into the file `filename.eml` or `cardID.eml`");\r
return 0;\r
} else {\r
len = strlen(Cmd);\r
- if (len > 14) len = 14;\r
+ if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;\r
\r
if (len < 1) {\r
// get filename\r
// open file\r
f = fopen(filename, "w+");\r
\r
+ if (f == NULL) {\r
+ PrintAndLog("File not found or locked.");\r
+ return 1;\r
+ }\r
+\r
// put hex\r
flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;\r
for (i = 0; i < 16 * 4; i++) {\r
{"ecfill", CmdHF14AMfECFill, 0, "Fill simulator memory with help of keys from simulator"},\r
{"ekeyprn", CmdHF14AMfEKeyPrn, 0, "Print keys from simulator memory"},\r
{"csetuid", CmdHF14AMfCSetUID, 0, "Set UID for magic Chinese card"},\r
- {"csetblk", CmdHF14AMfCSetBlk, 0, "Write block into magic Chinese card"},\r
- {"cgetblk", CmdHF14AMfCGetBlk, 0, "Read block from magic Chinese card"},\r
- {"cgetsc", CmdHF14AMfCGetSc, 0, "Read sector from magic Chinese card"},\r
+ {"csetblk", CmdHF14AMfCSetBlk, 0, "Write block - Magic Chinese card"},\r
+ {"cgetblk", CmdHF14AMfCGetBlk, 0, "Read block - Magic Chinese card"},\r
+ {"cgetsc", CmdHF14AMfCGetSc, 0, "Read sector - Magic Chinese card"},\r
{"cload", CmdHF14AMfCLoad, 0, "Load dump into magic Chinese card"},\r
{"csave", CmdHF14AMfCSave, 0, "Save dump from magic Chinese card into file or emulator"},\r
{NULL, NULL, 0, NULL}\r
#include <string.h>
#include <limits.h>
#include "ui.h"
-//#include "proxusb.h"
#include "proxmark3.h"
#include "cmdparser.h"
#include "cmdhw.h"
{"setlfdivisor", CmdSetDivisor, 0, "<19 - 255> -- Drive LF antenna at 12Mhz/(divisor+1)"},
{"setmux", CmdSetMux, 0, "<loraw|hiraw|lopkd|hipkd> -- Set the ADC mux to a specific value"},
{"tune", CmdTune, 0, "Measure antenna tuning"},
- {"version", CmdVersion, 0, "Show version inforation about the connected Proxmark"},
+ {"version", CmdVersion, 0, "Show version information about the connected Proxmark"},
{NULL, NULL, 0, NULL}
};
#include "cmdparser.h"
#include "cmdmain.h"
#include "cmddata.h"
+#include "util.h"
#include "cmdlf.h"
#include "cmdlfhid.h"
#include "cmdlfti.h"
int i;
/* convert to bitstream if necessary */
- for (i = 0; i < (int)(GraphTraceLen / 2); i++)
- {
- if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0)
- {
+ for (i = 0; i < (int)(GraphTraceLen / 2); i++){
+ if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0) {
CmdBitstream(str);
break;
}
int CmdLFSim(const char *Cmd)
{
- int i;
+ int i,j;
static int gap;
sscanf(Cmd, "%i", &gap);
/* convert to bitstream if necessary */
ChkBitstream(Cmd);
- PrintAndLog("Sending data, please wait...");
- for (i = 0; i < GraphTraceLen; i += 48) {
+ printf("Sending [%d bytes]", GraphTraceLen);
+ for (i = 0; i < GraphTraceLen; i += USB_CMD_DATA_SIZE) {
UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}};
- int j;
- for (j = 0; j < 48; j++) {
+
+ for (j = 0; j < USB_CMD_DATA_SIZE; j++) {
c.d.asBytes[j] = GraphBuffer[i+j];
}
SendCommand(&c);
WaitForResponse(CMD_ACK,NULL);
+ printf(".");
}
- PrintAndLog("Starting simulator...");
+ printf("\n");
+ PrintAndLog("Starting to simulate");
UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}};
SendCommand(&c);
return 0;
int CmdLFfind(const char *Cmd)
{
int ans=0;
- if (!offline){
+ char cmdp = param_getchar(Cmd, 0);
+
+ if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') {
+ PrintAndLog("Usage: lf search <0|1>");
+ PrintAndLog(" <use data from Graphbuffer>, if not set, try reading data from tag.");
+ PrintAndLog("");
+ PrintAndLog(" sample: lf search");
+ PrintAndLog(" : lf search 1");
+ return 0;
+ }
+
+ if (!offline || (cmdp != '1') ){
ans=CmdLFRead("");
- ans=CmdSamples("20000");
+ ans=CmdSamples("20000");
+ } else if (GraphTraceLen < 1000) {
+ PrintAndLog("Data in Graphbuffer was too small.");
+ return 0;
}
- if (GraphTraceLen<1000) return 0;
+
PrintAndLog("Checking for known tags:");
ans=Cmdaskmandemod("");
if (ans>0) return 1;
#include "cmddata.h"
#include "cmdlf.h"
#include "cmdlfem4x.h"
+char *global_em410xId;
static int CmdHelp(const char *Cmd);
parity[0] = parity[1] = parity[2] = parity[3] = 0;
header = rows = 0;
- /* manchester demodulate */
+ // manchester demodulate
bit = bit2idx = 0;
for (i = 0; i < (int)(GraphTraceLen / clock); i++)
{
/* Find out if we hit both high and low peaks */
for (j = 0; j < clock; j++)
{
- if (GraphBuffer[(i * clock) + j] == high)
+ if (GraphBuffer[(i * clock) + j] >= high)
hithigh = 1;
- else if (GraphBuffer[(i * clock) + j] == low)
+ else if (GraphBuffer[(i * clock) + j] <= low)
hitlow = 1;
/* it doesn't count if it's the first part of our read
PrintAndLog("EM410x Tag ID: %s", id);
PrintAndLog("Unique Tag ID: %s", id2);
+ global_em410xId = id;
+
/* Stop any loops */
return 1;
}
}
/* if we've already retested after flipping bits, return */
- if (retested++)
+ if (retested++){
+ PrintAndLog("Failed to decode");
return 0;
+ }
/* if this didn't work, try flipping bits */
for (i = 0; i < bit2idx; i++)
return 0;
}
+int CmdEM410xWatchnSpoof(const char *Cmd)
+{
+ CmdEM410xWatch(Cmd);
+ PrintAndLog("# Replaying : %s",global_em410xId);
+ CmdEM410xSim(global_em410xId);
+ return 0;
+}
+
/* Read the transmitted data of an EM4x50 tag
* Format:
*
int CmdReadWord(const char *Cmd)
{
- int Word = 16; //default to invalid word
+ int Word = -1; //default to invalid word
UsbCommand c;
sscanf(Cmd, "%d", &Word);
- if (Word > 15) {
+ if ( (Word > 15) | (Word < 0) ) {
PrintAndLog("Word must be between 0 and 15");
return 1;
}
int CmdReadWordPWD(const char *Cmd)
{
- int Word = 16; //default to invalid word
+ int Word = -1; //default to invalid word
int Password = 0xFFFFFFFF; //default to blank password
UsbCommand c;
sscanf(Cmd, "%d %x", &Word, &Password);
- if (Word > 15) {
+ if ( (Word > 15) | (Word < 0) ) {
PrintAndLog("Word must be between 0 and 15");
return 1;
}
return 1;
}
- PrintAndLog("Writting word %d with data %08X", Word, Data);
+ PrintAndLog("Writing word %d with data %08X", Word, Data);
c.cmd = CMD_EM4X_WRITE_WORD;
c.d.asBytes[0] = 0x0; //Normal mode
int CmdWriteWordPWD(const char *Cmd)
{
- int Word = 8; //default to invalid word
+ int Word = 16; //default to invalid word
int Data = 0xFFFFFFFF; //default to blank data
int Password = 0xFFFFFFFF; //default to blank password
UsbCommand c;
return 1;
}
- PrintAndLog("Writting word %d with data %08X and password %08X", Word, Data, Password);
+ PrintAndLog("Writing word %d with data %08X and password %08X", Word, Data, Password);
c.cmd = CMD_EM4X_WRITE_WORD;
c.d.asBytes[0] = 0x1; //Password mode
return 0;
}
-
-
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"em410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag"},
{"em410xsim", CmdEM410xSim, 0, "<UID> -- Simulate EM410x tag"},
{"em410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
+ {"em410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
{"em410xwrite", CmdEM410xWrite, 1, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"},
{"em4x50read", CmdEM4x50Read, 1, "Extract data from EM4x50 tag"},
{"readword", CmdReadWord, 1, "<Word> -- Read EM4xxx word data"},
int CmdEM410xRead(const char *Cmd);
int CmdEM410xSim(const char *Cmd);
int CmdEM410xWatch(const char *Cmd);
+int CmdEM410xWatchnSpoof(const char *Cmd);
int CmdEM410xWrite(const char *Cmd);
int CmdEM4x50Read(const char *Cmd);
int CmdReadWord(const char *Cmd);
int CmdLFHitagList(const char *Cmd)
{
- uint8_t got[3000];
+ uint8_t got[TRACE_BUFFER_SIZE];
GetFromBigBuf(got,sizeof(got),0);
WaitForResponse(CMD_ACK,NULL);
int i = 0;
int prev = -1;
+ int len = strlen(Cmd);
+
+ char filename[FILE_PATH_SIZE] = { 0x00 };
+ FILE* pf = NULL;
+
+ if (len > FILE_PATH_SIZE)
+ len = FILE_PATH_SIZE;
+ memcpy(filename, Cmd, len);
+
+ if (strlen(filename) > 0) {
+ if ((pf = fopen(filename,"wb")) == NULL) {
+ PrintAndLog("Error: Could not open file [%s]",filename);
+ return 1;
+ }
+ }
for (;;) {
- if(i >= 1900) {
- break;
- }
+
+ if(i >= TRACE_BUFFER_SIZE) { break; }
bool isResponse;
int timestamp = *((uint32_t *)(got+i));
if (len > 100) {
break;
}
- if (i + len >= 1900) {
- break;
- }
+ if (i + len >= TRACE_BUFFER_SIZE) { break;}
uint8_t *frame = (got+i+9);
line);
-// if (pf) {
-// fprintf(pf," +%7d: %3d: %s %s\n",
-// (prev < 0 ? 0 : (timestamp - prev)),
-// bits,
-// (isResponse ? "TAG" : " "),
-// line);
-// }
+ if (pf) {
+ fprintf(pf," +%7d: %3d: %s %s\n",
+ (prev < 0 ? 0 : (timestamp - prev)),
+ bits,
+ (isResponse ? "TAG" : " "),
+ line);
+ }
prev = timestamp;
i += (len + 9);
}
+ if (pf) {
+ fclose(pf);
+ PrintAndLog("Recorded activity succesfully written to file: %s", filename);
+ }
return 0;
}
}
int CmdLFHitagSim(const char *Cmd) {
+
UsbCommand c = {CMD_SIMULATE_HITAG};
- char filename[256] = { 0x00 };
+ char filename[FILE_PATH_SIZE] = { 0x00 };
FILE* pf;
bool tag_mem_supplied;
-
- param_getstr(Cmd,0,filename);
+ int len = strlen(Cmd);
+ if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
+ memcpy(filename, Cmd, len);
if (strlen(filename) > 0) {
if ((pf = fopen(filename,"rb+")) == NULL) {
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
- {"list", CmdLFHitagList, 1, "List Hitag trace history"},
+ {"list", CmdLFHitagList, 1, "<outfile> List Hitag trace history"},
{"reader", CmdLFHitagReader, 1, "Act like a Hitag Reader"},
- {"sim", CmdLFHitagSim, 1, "Simulate Hitag transponder"},
+ {"sim", CmdLFHitagSim, 1, "<infile> Simulate Hitag transponder"},
{"snoop", CmdLFHitagSnoop, 1, "Eavesdrop Hitag communication"},
{NULL, NULL, 0, NULL}
};
bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeout) {
UsbCommand resp;
-
+
if (response == NULL)
response = &resp;
#include <stdint.h>
+//trace buffer size as defined in armsrc/apps.h TRACE_SIZE
+#define TRACE_BUFFER_SIZE 4096
+#define FILE_PATH_SIZE 1000
#define SAMPLE_BUFFER_SIZE 64
extern uint8_t* sample_buf;
while (true) {
rxlen = sizeof(UsbCommand) - (prx-prxcmd);
if (uart_receive(sp,prx,&rxlen)) {
-// printf("received [%zd] bytes\n",rxlen);
prx += rxlen;
if ((prx-prxcmd) >= sizeof(UsbCommand)) {
-// printf("received: ");
-// cmd_debug(rxcmd);
return;
}
}
/* write a bit to the graph */
void AppendGraph(int redraw, int clock, int bit)
{
- int i;
+ int i;
- for (i = 0; i < (int)(clock / 2); ++i)
- GraphBuffer[GraphTraceLen++] = bit ^ 1;
+ for (i = 0; i < (int)(clock / 2); ++i)
+ GraphBuffer[GraphTraceLen++] = bit ^ 1;
- for (i = (int)(clock / 2); i < clock; ++i)
- GraphBuffer[GraphTraceLen++] = bit;
+ for (i = (int)(clock / 2); i < clock; ++i)
+ GraphBuffer[GraphTraceLen++] = bit;
- if (redraw)
- RepaintGraphWindow();
+ if (redraw)
+ RepaintGraphWindow();
}
// clear out our graph window
int ClearGraph(int redraw)
{
- int gtl = GraphTraceLen;
- GraphTraceLen = 0;
+ int gtl = GraphTraceLen;
+ memset(GraphBuffer, 0x00, GraphTraceLen);
- if (redraw)
- RepaintGraphWindow();
+ GraphTraceLen = 0;
- return gtl;
+ if (redraw)
+ RepaintGraphWindow();
+
+ return gtl;
}
// DETECT CLOCK NOW IN LFDEMOD.C
void setGraphBuf(uint8_t *buff, size_t size)
{
- int i=0;
- ClearGraph(0);
- for (; i < size; ++i){
+ int i=0;
+ ClearGraph(0);
+ for (; i < size; ++i){
GraphBuffer[i]=buff[i]-128;
- }
- GraphTraceLen=size;
- RepaintGraphWindow();
- return;
+ }
+ GraphTraceLen=size;
+ RepaintGraphWindow();
+ return;
}
size_t getFromGraphBuf(uint8_t *buff)
{
- uint32_t i;
- for (i=0;i<GraphTraceLen;++i){
- if (GraphBuffer[i]>127) GraphBuffer[i]=127; //trim
- if (GraphBuffer[i]<-127) GraphBuffer[i]=-127; //trim
- buff[i]=(uint8_t)(GraphBuffer[i]+128);
- }
- return i;
+ uint32_t i;
+ for (i=0;i<GraphTraceLen;++i){
+ if (GraphBuffer[i]>127) GraphBuffer[i]=127; //trim
+ if (GraphBuffer[i]<-127) GraphBuffer[i]=-127; //trim
+ buff[i]=(uint8_t)(GraphBuffer[i]+128);
+ }
+ return i;
}
// Get or auto-detect clock rate
int GetClock(const char *str, int peak, int verbose)
{
- int clock;
- sscanf(str, "%i", &clock);
- if (!strcmp(str, ""))
- clock = 0;
+ int clock;
+ sscanf(str, "%i", &clock);
+ if (!strcmp(str, ""))
+ clock = 0;
// Auto-detect clock
- if (!clock)
- {
- uint8_t grph[MAX_GRAPH_TRACE_LEN]={0};
+ if (!clock)
+ {
+ uint8_t grph[MAX_GRAPH_TRACE_LEN]={0};
size_t size = getFromGraphBuf(grph);
- clock = DetectASKClock(grph,size,0);
+ clock = DetectASKClock(grph,size,0);
// Only print this message if we're not looping something
- if (!verbose){
- PrintAndLog("Auto-detected clock rate: %d", clock);
- }
- }
+ if (!verbose){
+ PrintAndLog("Auto-detected clock rate: %d", clock);
+ }
+ }
- return clock;
+ return clock;
}
int GetNRZpskClock(const char *str, int peak, int verbose)
*/
int bruteforceFile(const char *filename, uint16_t keytable[])
{
-
FILE *f = fopen(filename, "rb");
if(!f) {
prnlog("Failed to read from file '%s'", filename);
int readKeyFile(uint8_t key[8])
{
-
FILE *f;
int retval = 1;
f = fopen("iclass_key.bin", "rb");
fclose(f);
}
return retval;
-
}
CMD_ISO_15693_COMMAND_DONE = 0x0314,
CMD_ISO_15693_FIND_AFI = 0x0315,
CMD_ISO_15693_DEBUG = 0x0316,
+ CMD_LF_SNOOP_RAW_ADC_SAMPLES = 0x0317,
--// For Hitag2 transponders
CMD_SNOOP_HITAG = 0x0370,
CMD_READER_LEGIC_RF = 0x0388,
CMD_WRITER_LEGIC_RF = 0x0389,
CMD_EPA_PACE_COLLECT_NONCE = 0x038A,
+ --//CMD_EPA_ = 0x038B,
CMD_SNOOP_ICLASS = 0x0392,
CMD_SIMULATE_TAG_ICLASS = 0x0393,
CMD_READER_ICLASS = 0x0394,
+ CMD_READER_ICLASS_REPLAY = 0x0395,
+ CMD_ICLASS_ISO14443A_WRITE = 0x0397,
--// For measurements of the antenna tuning
CMD_MEASURE_ANTENNA_TUNING = 0x0400,
CMD_MIFARE_EML_MEMSET = 0x0602,
CMD_MIFARE_EML_MEMGET = 0x0603,
CMD_MIFARE_EML_CARDLOAD = 0x0604,
- CMD_MIFARE_EML_CSETBLOCK = 0x0605,
- CMD_MIFARE_EML_CGETBLOCK = 0x0606,
+
+ --// magic chinese card commands
+ CMD_MIFARE_CSETBLOCK = 0x0605,
+ CMD_MIFARE_CGETBLOCK = 0x0606,
+ CMD_MIFARE_CIDENT = 0x0607,
CMD_SIMULATE_MIFARE_CARD = 0x0610,
CMD_MIFARE_NESTED = 0x0612,
CMD_MIFARE_READBL = 0x0620,
+ CMD_MIFAREU_READBL = 0x0720,
+
CMD_MIFARE_READSC = 0x0621,
+ CMD_MIFAREU_READCARD = 0x0721,
+
CMD_MIFARE_WRITEBL = 0x0622,
+ CMD_MIFAREU_WRITEBL = 0x0722,
+ CMD_MIFAREU_WRITEBL_COMPAT = 0x0723,
+
CMD_MIFARE_CHKKEYS = 0x0623,
CMD_MIFARE_SNIFFER = 0x0630,
+ --//ultralightC
+ CMD_MIFAREUC_AUTH1 = 0x0724,
+ CMD_MIFAREUC_AUTH2 = 0x0725,
+ CMD_MIFAREUC_READCARD = 0x0726,
+
+ --// mifare desfire
+ CMD_MIFARE_DESFIRE_READBL = 0x0728,
+ CMD_MIFARE_DESFIRE_WRITEBL = 0x0729,
+ CMD_MIFARE_DESFIRE_AUTH1 = 0x072a,
+ CMD_MIFARE_DESFIRE_AUTH2 = 0x072b,
+ CMD_MIFARE_DES_READER = 0x072c,
+ CMD_MIFARE_DESFIRE_INFO = 0x072d,
+ CMD_MIFARE_DESFIRE = 0x072e,
+
CMD_UNKNOWN = 0xFFFF,
}
local data = self.data
local cmd = self.cmd
local arg1, arg2, arg3 = self.arg1, self.arg2, self.arg3
-
return bin.pack("LLLLH",cmd, arg1, arg2, arg3,data);
end
--- /dev/null
+local _names = {
+ --[[
+ --]]
+ ["0400"]="BASH",
+ ["1600"]="BOOMER" ,
+ ["1800"]="CAMO",
+ ["3000"]="CHOPCHOP" ,
+ ["2000"]="CYNDER",
+ ["6400"]="JET-VAC",
+ ["6700"]="FLASHWING",
+ ["7000"]="TREE REX",
+ ["7100"]="LIGHTCORE SHROOMBOOM",
+ ["1C00"]="DARK SPYRO",
+ ["0600"]="DINORANG" ,
+ ["1200"]="DOUBLE TROUBLE" ,
+ ["1500"]="DRILLSERGEANT" ,
+ ["1400"]="DROBOT",
+ ["0900"]="LIGHTCORE ERUPTOR" ,
+ ["0B00"]="FLAMESLINGER" ,
+ ["1F00"]="GHOST ROASTER",
+ ["0E00"]="GILL GRUNT" ,
+ ["1D00"]="HEX",
+ ["0A00"]="IGNITOR",
+ ["0300"]="LIGHTNINGROD",
+ ["0700"]="LIGHTCORE PRISM BREAK",
+ ["1500"]="SLAMBAM",
+ ["0100"]="SONIC BOOM",
+ ["1000"]="SPYRO",
+ ["1A00"]="STEALTH ELF",
+ ["1B00"]="STUMP SMASH",
+ ["0800"]="SUNBURN",
+ ["0500"]="TERRAFIN",
+ ["1300"]="TRIGGER HAPPY",
+ ["1100"]="VOODOOD",
+ ["0200"]="WARNADO",
+ ["0D00"]="WHAM SHELL",
+ ["0000"]="WHIRLWIND",
+ ["1700"]="WRECKING BALL",
+ ["0C00"]="ZAP",
+ ["1900"]="ZOOK",
+ ["0300"]="DRAGON",
+ ["012D"]="ICE",
+ ["012E"]="PIRATE",
+ ["0130"]="PVPUNLOCK",
+ ["012F"]="UNDEAD",
+ ["0200"]="ANVIL" ,
+ ["CB00"]="CROSSED SWORDS",
+ ["CC00"]="HOURGLASS",
+ ["CA00"]="REGENERATION",
+ ["C900"]="SECRET STASH",
+ ["CD00"]="SHIELD",
+ ["CF00"]="SPARX",
+ ["CE00"]="SPEED BOOTS",
+ ["0194"]="LEGENDARY BASH",
+ ["0430"]="LEGENDARY CHOPCHOP",
+ ["01A0"]="LEGENDARY SPYRO",
+ ["01A3"]="LEGENDARY TRIGGER HAPPY",
+ ["0202"]="PET GILL GRUNT",
+ ["020E"]="PET STEALTH ELF",
+ ["01F9"]="PET TERRAFIN",
+ ["0207"]="PET TRIGGER HAPPY",
+}
+return _names
end
+local function save_TEXT(data,filename)
+ -- Open the output file
+ local outfile = io.open(filename, "w")
+ if outfile == nil then
+ return oops(string.format("Could not write to file %s",tostring(filename)))
+ end
+
+ outfile:write(data)
+ io.close(outfile)
+ return filename
+end
+
local function save_BIN(data, filename)
-- Open the output file
convert_bin_to_html = convert_bin_to_html,
convert_eml_to_html = convert_eml_to_html,
convert_eml_to_bin = convert_eml_to_bin,
+ SaveAsBinary = save_BIN,
+ SaveAsText = save_TEXT,
}
return "UNKNOWN"
}
+ add("04,,,Mifare TNP3xxx Activision 1K,0f01,01");
add("04,,,Mifare Mini,0004,09");
add("04,,,Mifare Classic 1k/Mifare Plus(4 byte UID) 2K SL1,0004,08");
add("04,,,Mifare Plus (4 byte UID) 2K SL2,0004,10");
'200000000000',
'a00000000000',
'b00000000000',
+
+ --[[
+ Should be for Mifare TNP3xxx tags A KEY.
+ --]]
+ '4b0b20107ccb',
+
+ --[[
+ Kiev metro cards
+ --]]
+ '8fe644038790',
+ 'f14ee7cae863',
+ '632193be1c3c',
+ '569369c5a0e5',
+ '9de89e070277',
+ 'eff603e1efe9',
+ '644672bd4afe',
+
+ 'b5ff67cba951',
}
---
local ISO14443a_TYPES = {}
ISO14443a_TYPES[0x00] = "NXP MIFARE Ultralight | Ultralight C"
+ISO14443a_TYPES[0x01] = "NXP MIFARE TNP3xxx Activision Game Appliance"
ISO14443a_TYPES[0x04] = "NXP MIFARE (various !DESFire !DESFire EV1)"
ISO14443a_TYPES[0x08] = "NXP MIFARE CLASSIC 1k | Plus 2k"
ISO14443a_TYPES[0x09] = "NXP MIFARE Mini 0.3k"
\r
return answer\r
end,\r
+ \r
+ ------------ FILE READING\r
+ ReadDumpFile = function (filename)\r
+ \r
+ if filename == nil then \r
+ return nil, 'Filename is empty'\r
+ end\r
+ if #filename == 0 then\r
+ return nil, 'Filename length is zero'\r
+ end\r
+\r
+ infile = io.open(filename, "rb")\r
+ if infile == nil then \r
+ return nil, string.format("Could not read file %s",filename)\r
+ end\r
+ local t = infile:read("*all")\r
+ len = string.len(t)\r
+ local _,hex = bin.unpack(("H%d"):format(len),t)\r
+ io.close(infile)\r
+ return hex\r
+ end,\r
+ \r
+ ------------ string split function\r
+ Split = function( inSplitPattern, outResults )\r
+ if not outResults then\r
+ outResults = {}\r
+ end\r
+ local start = 1\r
+ local splitStart, splitEnd = string.find( self, inSplitPattern, start )\r
+ while splitStart do\r
+ table.insert( outResults, string.sub( self, start, splitStart-1 ) )\r
+ start = splitEnd + 1\r
+ splitStart, splitEnd = string.find( self, inSplitPattern, start )\r
+ end\r
+ table.insert( outResults, string.sub( self, start ) )\r
+ return outResults\r
+ end,\r
+ \r
+ ------------ CRC-16 ccitt checksums\r
+ \r
+ -- Takes a hex string and calculates a crc16\r
+ Crc16 = function(s)\r
+ if s == nil then return nil end\r
+ if #s == 0 then return nil end\r
+ if type(s) == 'string' then\r
+ local utils = require('utils')\r
+ local asc = utils.ConvertHexToAscii(s)\r
+ local hash = core.crc16(asc)\r
+ return hash\r
+ end\r
+ return nil\r
+ end,\r
+\r
+ -- input parameter is a string\r
+ -- Swaps the endianess and returns a number, \r
+ -- IE: 'cd7a' -> '7acd' -> 0x7acd\r
+ SwapEndianness = function(s, len)\r
+ if s == nil then return nil end\r
+ if #s == 0 then return '' end\r
+ if type(s) ~= 'string' then return nil end\r
+ \r
+ local retval = 0\r
+ if len == 16 then\r
+ local t = s:sub(3,4)..s:sub(1,2)\r
+ retval = tonumber(t,16)\r
+ elseif len == 24 then\r
+ local t = s:sub(5,6)..s:sub(3,4)..s:sub(1,2)\r
+ retval = tonumber(t,16)\r
+ elseif len == 32 then\r
+ local t = s:sub(7,8)..s:sub(5,6)..s:sub(3,4)..s:sub(1,2)\r
+ retval = tonumber(t,16)\r
+ end\r
+ return retval\r
+ end,\r
+ \r
+ ------------ CONVERSIONS\r
+ \r
--\r
-- Converts DECIMAL to HEX\r
- ConvertDec2Hex = function(IN)\r
+ ConvertDecToHex = function(IN)\r
local B,K,OUT,I,D=16,"0123456789ABCDEF","",0\r
while IN>0 do\r
I=I+1\r
end,\r
---\r
-- Convert Byte array to string of hex\r
- ConvertBytes2String = function(bytes)\r
- s = {}\r
+ ConvertBytesToHex = function(bytes)\r
+ if #bytes == 0 then\r
+ return ''\r
+ end\r
+ local s={}\r
for i = 1, #(bytes) do\r
s[i] = string.format("%02X",bytes[i]) \r
end\r
return table.concat(s)\r
end, \r
+ -- Convert byte array to string with ascii\r
+ ConvertBytesToAscii = function(bytes)\r
+ if #bytes == 0 then\r
+ return ''\r
+ end\r
+ local s={}\r
+ for i = 1, #(bytes) do\r
+ s[i] = string.char(bytes[i]) \r
+ end\r
+ return table.concat(s) \r
+ end, \r
+ ConvertHexToBytes = function(s)\r
+ local t={}\r
+ if s == nil then return t end\r
+ if #s == 0 then return t end\r
+ for k in s:gmatch"(%x%x)" do\r
+ table.insert(t,tonumber(k,16))\r
+ end\r
+ return t\r
+ end,\r
+ ConvertAsciiToBytes = function(s)\r
+ local t={}\r
+ if s == nil then return t end\r
+ if #s == 0 then return t end\r
+ \r
+ for k in s:gmatch"(.)" do\r
+ table.insert(t, string.byte(k))\r
+ end\r
+ return t\r
+ end,\r
+ ConvertHexToAscii = function(s)\r
+ local t={}\r
+ if s == nil then return t end\r
+ if #s == 0 then return t end\r
+ for k in s:gmatch"(%x%x)" do\r
+ table.insert(t, string.char(tonumber(k,16)))\r
+ end\r
+ return table.concat(t) \r
+ end,\r
+ \r
+ -- function convertStringToBytes(str)\r
+ -- local bytes = {}\r
+ -- local strLength = string.len(str)\r
+ -- for i=1,strLength do\r
+ -- table.insert(bytes, string.byte(str, i))\r
+ -- end\r
+\r
+ -- return bytes\r
+-- end\r
+\r
+-- function convertBytesToString(bytes)\r
+ -- local bytesLength = table.getn(bytes)\r
+ -- local str = ""\r
+ -- for i=1,bytesLength do\r
+ -- str = str .. string.char(bytes[i])\r
+ -- end\r
+\r
+ -- return str\r
+-- end\r
+\r
+-- function convertHexStringToBytes(str)\r
+ -- local bytes = {}\r
+ -- local strLength = string.len(str)\r
+ -- for k=2,strLength,2 do\r
+ -- local hexString = "0x" .. string.sub(str, (k - 1), k)\r
+ -- table.insert(bytes, hex.to_dec(hexString))\r
+ -- end\r
+\r
+ -- return bytes\r
+-- end\r
+\r
+-- function convertBytesToHexString(bytes)\r
+ -- local str = ""\r
+ -- local bytesLength = table.getn(bytes)\r
+ -- for i=1,bytesLength do\r
+ -- local hexString = string.sub(hex.to_hex(bytes[i]), 3)\r
+ -- if string.len(hexString) == 1 then\r
+ -- hexString = "0" .. hexString\r
+ -- end\r
+ -- str = str .. hexString\r
+ -- end\r
+\r
+ -- return str\r
+-- end\r
+\r
}\r
return Utils
\ No newline at end of file
--- /dev/null
+/**
+ * \file config.h
+ *
+ * \brief Configuration options (set of defines)
+ *
+ * Copyright (C) 2006-2014, Brainspark B.V.
+ *
+ * This file is part of PolarSSL (http://www.polarssl.org)
+ * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * This set of compile-time options may be used to enable
+ * or disable features selectively, and reduce the global
+ * memory footprint.
+ */
+#ifndef POLARSSL_CONFIG_H
+#define POLARSSL_CONFIG_H
+
+#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+#define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+
+/**
+ * \name SECTION: System support
+ *
+ * This section sets system specific settings.
+ * \{
+ */
+
+/**
+ * \def POLARSSL_HAVE_INT8
+ *
+ * The system uses 8-bit wide native integers.
+ *
+ * Uncomment if native integers are 8-bit wide.
+ */
+//#define POLARSSL_HAVE_INT8
+
+/**
+ * \def POLARSSL_HAVE_INT16
+ *
+ * The system uses 16-bit wide native integers.
+ *
+ * Uncomment if native integers are 16-bit wide.
+ */
+//#define POLARSSL_HAVE_INT16
+
+/**
+ * \def POLARSSL_HAVE_LONGLONG
+ *
+ * The compiler supports the 'long long' type.
+ * (Only used on 32-bit platforms)
+ */
+#define POLARSSL_HAVE_LONGLONG
+
+/**
+ * \def POLARSSL_HAVE_ASM
+ *
+ * The compiler has support for asm().
+ *
+ * Requires support for asm() in compiler.
+ *
+ * Used in:
+ * library/timing.c
+ * library/padlock.c
+ * include/polarssl/bn_mul.h
+ *
+ * Comment to disable the use of assembly code.
+ */
+#define POLARSSL_HAVE_ASM
+
+/**
+ * \def POLARSSL_HAVE_SSE2
+ *
+ * CPU supports SSE2 instruction set.
+ *
+ * Uncomment if the CPU supports SSE2 (IA-32 specific).
+ */
+//#define POLARSSL_HAVE_SSE2
+
+/**
+ * \def POLARSSL_HAVE_TIME
+ *
+ * System has time.h and time() / localtime() / gettimeofday().
+ *
+ * Comment if your system does not support time functions
+ */
+#define POLARSSL_HAVE_TIME
+
+/**
+ * \def POLARSSL_HAVE_IPV6
+ *
+ * System supports the basic socket interface for IPv6 (RFC 3493),
+ * specifically getaddrinfo(), freeaddrinfo() and struct sockaddr_storage.
+ *
+ * Note: on Windows/MingW, XP or higher is required.
+ *
+ * Comment if your system does not support the IPv6 socket interface
+ */
+#define POLARSSL_HAVE_IPV6
+
+/**
+ * \def POLARSSL_PLATFORM_MEMORY
+ *
+ * Enable the memory allocation layer.
+ *
+ * By default PolarSSL uses the system-provided malloc() and free().
+ * This allows different allocators (self-implemented or provided) to be
+ * provided to the platform abstraction layer.
+ *
+ * Enabling POLARSSL_PLATFORM_MEMORY will provide "platform_set_malloc_free()"
+ * to allow you to set an alternative malloc() and free() function pointer.
+ *
+ * Requires: POLARSSL_PLATFORM_C
+ *
+ * Enable this layer to allow use of alternative memory allocators.
+ */
+//#define POLARSSL_PLATFORM_MEMORY
+
+/**
+ * \def POLARSSL_PLATFORM_NO_STD_FUNCTIONS
+ *
+ * Do not assign standard functions in the platform layer (e.g. malloc() to
+ * POLARSSL_PLATFORM_STD_MALLOC and printf() to POLARSSL_PLATFORM_STD_PRINTF)
+ *
+ * This makes sure there are no linking errors on platforms that do not support
+ * these functions. You will HAVE to provide alternatives, either at runtime
+ * via the platform_set_xxx() functions or at compile time by setting
+ * the POLARSSL_PLATFORM_STD_XXX defines.
+ *
+ * Requires: POLARSSL_PLATFORM_C
+ *
+ * Uncomment to prevent default assignment of standard functions in the
+ * platform layer.
+ */
+//#define POLARSSL_PLATFORM_NO_STD_FUNCTIONS
+
+/**
+ * \def POLARSSL_PLATFORM_XXX_ALT
+ *
+ * Uncomment a macro to let PolarSSL support the function in the platform
+ * abstraction layer.
+ *
+ * Example: In case you uncomment POLARSSL_PLATFORM_PRINTF_ALT, PolarSSL will
+ * provide a function "platform_set_printf()" that allows you to set an
+ * alternative printf function pointer.
+ *
+ * All these define require POLARSSL_PLATFORM_C to be defined!
+ *
+ * Uncomment a macro to enable alternate implementation of specific base
+ * platform function
+ */
+//#define POLARSSL_PLATFORM_PRINTF_ALT
+//#define POLARSSL_PLATFORM_FPRINTF_ALT
+/* \} name SECTION: System support */
+
+/**
+ * \name SECTION: PolarSSL feature support
+ *
+ * This section sets support for features that are or are not needed
+ * within the modules that are enabled.
+ * \{
+ */
+
+/**
+ * \def POLARSSL_TIMING_ALT
+ *
+ * Uncomment to provide your own alternate implementation for hardclock(),
+ * get_timer(), set_alarm() and m_sleep().
+ *
+ * Only works if you have POLARSSL_TIMING_C enabled.
+ *
+ * You will need to provide a header "timing_alt.h" and an implementation at
+ * compile time.
+ */
+//#define POLARSSL_TIMING_ALT
+
+/**
+ * \def POLARSSL_XXX_ALT
+ *
+ * Uncomment a macro to let PolarSSL use your alternate core implementation of
+ * a symmetric or hash algorithm (e.g. platform specific assembly optimized
+ * implementations). Keep in mind that the function prototypes should remain
+ * the same.
+ *
+ * Example: In case you uncomment POLARSSL_AES_ALT, PolarSSL will no longer
+ * provide the "struct aes_context" definition and omit the base function
+ * declarations and implementations. "aes_alt.h" will be included from
+ * "aes.h" to include the new function definitions.
+ *
+ * Uncomment a macro to enable alternate implementation for core algorithm
+ * functions
+ */
+//#define POLARSSL_AES_ALT
+//#define POLARSSL_ARC4_ALT
+//#define POLARSSL_BLOWFISH_ALT
+//#define POLARSSL_CAMELLIA_ALT
+//#define POLARSSL_DES_ALT
+//#define POLARSSL_XTEA_ALT
+//#define POLARSSL_MD2_ALT
+//#define POLARSSL_MD4_ALT
+//#define POLARSSL_MD5_ALT
+//#define POLARSSL_RIPEMD160_ALT
+//#define POLARSSL_SHA1_ALT
+//#define POLARSSL_SHA256_ALT
+//#define POLARSSL_SHA512_ALT
+
+/**
+ * \def POLARSSL_AES_ROM_TABLES
+ *
+ * Store the AES tables in ROM.
+ *
+ * Uncomment this macro to store the AES tables in ROM.
+ *
+ */
+//#define POLARSSL_AES_ROM_TABLES
+
+/**
+ * \def POLARSSL_CIPHER_MODE_CBC
+ *
+ * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers.
+ */
+#define POLARSSL_CIPHER_MODE_CBC
+
+/**
+ * \def POLARSSL_CIPHER_MODE_CFB
+ *
+ * Enable Cipher Feedback mode (CFB) for symmetric ciphers.
+ */
+#define POLARSSL_CIPHER_MODE_CFB
+
+/**
+ * \def POLARSSL_CIPHER_MODE_CTR
+ *
+ * Enable Counter Block Cipher mode (CTR) for symmetric ciphers.
+ */
+#define POLARSSL_CIPHER_MODE_CTR
+
+/**
+ * \def POLARSSL_CIPHER_NULL_CIPHER
+ *
+ * Enable NULL cipher.
+ * Warning: Only do so when you know what you are doing. This allows for
+ * encryption or channels without any security!
+ *
+ * Requires POLARSSL_ENABLE_WEAK_CIPHERSUITES as well to enable
+ * the following ciphersuites:
+ * TLS_ECDH_ECDSA_WITH_NULL_SHA
+ * TLS_ECDH_RSA_WITH_NULL_SHA
+ * TLS_ECDHE_ECDSA_WITH_NULL_SHA
+ * TLS_ECDHE_RSA_WITH_NULL_SHA
+ * TLS_ECDHE_PSK_WITH_NULL_SHA384
+ * TLS_ECDHE_PSK_WITH_NULL_SHA256
+ * TLS_ECDHE_PSK_WITH_NULL_SHA
+ * TLS_DHE_PSK_WITH_NULL_SHA384
+ * TLS_DHE_PSK_WITH_NULL_SHA256
+ * TLS_DHE_PSK_WITH_NULL_SHA
+ * TLS_RSA_WITH_NULL_SHA256
+ * TLS_RSA_WITH_NULL_SHA
+ * TLS_RSA_WITH_NULL_MD5
+ * TLS_RSA_PSK_WITH_NULL_SHA384
+ * TLS_RSA_PSK_WITH_NULL_SHA256
+ * TLS_RSA_PSK_WITH_NULL_SHA
+ * TLS_PSK_WITH_NULL_SHA384
+ * TLS_PSK_WITH_NULL_SHA256
+ * TLS_PSK_WITH_NULL_SHA
+ *
+ * Uncomment this macro to enable the NULL cipher and ciphersuites
+ */
+//#define POLARSSL_CIPHER_NULL_CIPHER
+
+/**
+ * \def POLARSSL_CIPHER_PADDING_XXX
+ *
+ * Uncomment or comment macros to add support for specific padding modes
+ * in the cipher layer with cipher modes that support padding (e.g. CBC)
+ *
+ * If you disable all padding modes, only full blocks can be used with CBC.
+ *
+ * Enable padding modes in the cipher layer.
+ */
+#define POLARSSL_CIPHER_PADDING_PKCS7
+#define POLARSSL_CIPHER_PADDING_ONE_AND_ZEROS
+#define POLARSSL_CIPHER_PADDING_ZEROS_AND_LEN
+#define POLARSSL_CIPHER_PADDING_ZEROS
+
+/**
+ * \def POLARSSL_ENABLE_WEAK_CIPHERSUITES
+ *
+ * Enable weak ciphersuites in SSL / TLS.
+ * Warning: Only do so when you know what you are doing. This allows for
+ * channels with virtually no security at all!
+ *
+ * This enables the following ciphersuites:
+ * TLS_RSA_WITH_DES_CBC_SHA
+ * TLS_DHE_RSA_WITH_DES_CBC_SHA
+ *
+ * Uncomment this macro to enable weak ciphersuites
+ */
+//#define POLARSSL_ENABLE_WEAK_CIPHERSUITES
+
+/**
+ * \def POLARSSL_REMOVE_ARC4_CIPHERSUITES
+ *
+ * Remove RC4 ciphersuites by default in SSL / TLS.
+ * This flag removes the ciphersuites based on RC4 from the default list as
+ * returned by ssl_list_ciphersuites(). However, it is still possible to
+ * enable (some of) them with ssl_set_ciphersuites() by including them
+ * explicitly.
+ *
+ * Uncomment this macro to remove RC4 ciphersuites by default.
+ */
+//#define POLARSSL_REMOVE_ARC4_CIPHERSUITES
+
+/**
+ * \def POLARSSL_ECP_XXXX_ENABLED
+ *
+ * Enables specific curves within the Elliptic Curve module.
+ * By default all supported curves are enabled.
+ *
+ * Comment macros to disable the curve and functions for it
+ */
+#define POLARSSL_ECP_DP_SECP192R1_ENABLED
+#define POLARSSL_ECP_DP_SECP224R1_ENABLED
+#define POLARSSL_ECP_DP_SECP256R1_ENABLED
+#define POLARSSL_ECP_DP_SECP384R1_ENABLED
+#define POLARSSL_ECP_DP_SECP521R1_ENABLED
+#define POLARSSL_ECP_DP_SECP192K1_ENABLED
+#define POLARSSL_ECP_DP_SECP224K1_ENABLED
+#define POLARSSL_ECP_DP_SECP256K1_ENABLED
+#define POLARSSL_ECP_DP_BP256R1_ENABLED
+#define POLARSSL_ECP_DP_BP384R1_ENABLED
+#define POLARSSL_ECP_DP_BP512R1_ENABLED
+//#define POLARSSL_ECP_DP_M221_ENABLED // Not implemented yet!
+#define POLARSSL_ECP_DP_M255_ENABLED
+//#define POLARSSL_ECP_DP_M383_ENABLED // Not implemented yet!
+//#define POLARSSL_ECP_DP_M511_ENABLED // Not implemented yet!
+
+/**
+ * \def POLARSSL_ECP_NIST_OPTIM
+ *
+ * Enable specific 'modulo p' routines for each NIST prime.
+ * Depending on the prime and architecture, makes operations 4 to 8 times
+ * faster on the corresponding curve.
+ *
+ * Comment this macro to disable NIST curves optimisation.
+ */
+#define POLARSSL_ECP_NIST_OPTIM
+
+/**
+ * \def POLARSSL_ECDSA_DETERMINISTIC
+ *
+ * Enable deterministic ECDSA (RFC 6979).
+ * Standard ECDSA is "fragile" in the sense that lack of entropy when signing
+ * may result in a compromise of the long-term signing key. This is avoided by
+ * the deterministic variant.
+ *
+ * Requires: POLARSSL_HMAC_DRBG_C
+ *
+ * Comment this macro to disable deterministic ECDSA.
+ */
+#define POLARSSL_ECDSA_DETERMINISTIC
+
+/**
+ * \def POLARSSL_KEY_EXCHANGE_PSK_ENABLED
+ *
+ * Enable the PSK based ciphersuite modes in SSL / TLS.
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * TLS_PSK_WITH_AES_256_GCM_SHA384
+ * TLS_PSK_WITH_AES_256_CBC_SHA384
+ * TLS_PSK_WITH_AES_256_CBC_SHA
+ * TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ * TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ * TLS_PSK_WITH_AES_128_GCM_SHA256
+ * TLS_PSK_WITH_AES_128_CBC_SHA256
+ * TLS_PSK_WITH_AES_128_CBC_SHA
+ * TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ * TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ * TLS_PSK_WITH_3DES_EDE_CBC_SHA
+ * TLS_PSK_WITH_RC4_128_SHA
+ */
+#define POLARSSL_KEY_EXCHANGE_PSK_ENABLED
+
+/**
+ * \def POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED
+ *
+ * Enable the DHE-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: POLARSSL_DHM_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+ * TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+ * TLS_DHE_PSK_WITH_AES_256_CBC_SHA
+ * TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ * TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ * TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+ * TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+ * TLS_DHE_PSK_WITH_AES_128_CBC_SHA
+ * TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ * TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ * TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
+ * TLS_DHE_PSK_WITH_RC4_128_SHA
+ */
+#define POLARSSL_KEY_EXCHANGE_DHE_PSK_ENABLED
+
+/**
+ * \def POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED
+ *
+ * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: POLARSSL_ECDH_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384
+ * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA
+ * TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+ * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA
+ * TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ * TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA
+ * TLS_ECDHE_PSK_WITH_RC4_128_SHA
+ */
+#define POLARSSL_KEY_EXCHANGE_ECDHE_PSK_ENABLED
+
+/**
+ * \def POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED
+ *
+ * Enable the RSA-PSK based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: POLARSSL_RSA_C, POLARSSL_PKCS1_V15,
+ * POLARSSL_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
+ * TLS_RSA_PSK_WITH_AES_256_CBC_SHA384
+ * TLS_RSA_PSK_WITH_AES_256_CBC_SHA
+ * TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ * TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ * TLS_RSA_PSK_WITH_AES_128_GCM_SHA256
+ * TLS_RSA_PSK_WITH_AES_128_CBC_SHA256
+ * TLS_RSA_PSK_WITH_AES_128_CBC_SHA
+ * TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ * TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ * TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA
+ * TLS_RSA_PSK_WITH_RC4_128_SHA
+ */
+#define POLARSSL_KEY_EXCHANGE_RSA_PSK_ENABLED
+
+/**
+ * \def POLARSSL_KEY_EXCHANGE_RSA_ENABLED
+ *
+ * Enable the RSA-only based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: POLARSSL_RSA_C, POLARSSL_PKCS1_V15,
+ * POLARSSL_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * TLS_RSA_WITH_AES_256_GCM_SHA384
+ * TLS_RSA_WITH_AES_256_CBC_SHA256
+ * TLS_RSA_WITH_AES_256_CBC_SHA
+ * TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+ * TLS_RSA_WITH_AES_128_GCM_SHA256
+ * TLS_RSA_WITH_AES_128_CBC_SHA256
+ * TLS_RSA_WITH_AES_128_CBC_SHA
+ * TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+ * TLS_RSA_WITH_3DES_EDE_CBC_SHA
+ * TLS_RSA_WITH_RC4_128_SHA
+ * TLS_RSA_WITH_RC4_128_MD5
+ */
+#define POLARSSL_KEY_EXCHANGE_RSA_ENABLED
+
+/**
+ * \def POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED
+ *
+ * Enable the DHE-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: POLARSSL_DHM_C, POLARSSL_RSA_C, POLARSSL_PKCS1_V15,
+ * POLARSSL_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+ * TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+ * TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ * TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+ * TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+ * TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+ * TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+ * TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+ * TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+ */
+#define POLARSSL_KEY_EXCHANGE_DHE_RSA_ENABLED
+
+/**
+ * \def POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+ *
+ * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: POLARSSL_ECDH_C, POLARSSL_RSA_C, POLARSSL_PKCS1_V15,
+ * POLARSSL_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+ * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+ * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+ * TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ * TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ * TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+ * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+ * TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ * TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ * TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+ * TLS_ECDHE_RSA_WITH_RC4_128_SHA
+ */
+#define POLARSSL_KEY_EXCHANGE_ECDHE_RSA_ENABLED
+
+/**
+ * \def POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+ *
+ * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: POLARSSL_ECDH_C, POLARSSL_ECDSA_C, POLARSSL_X509_CRT_PARSE_C,
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+ * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+ * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+ * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ * TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+ * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+ * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ * TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+ * TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+ */
+#define POLARSSL_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED
+
+/**
+ * \def POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+ *
+ * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: POLARSSL_ECDH_C, POLARSSL_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+ * TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+ * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+ * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+ * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+ * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+ * TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+ * TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+ * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ */
+#define POLARSSL_KEY_EXCHANGE_ECDH_ECDSA_ENABLED
+
+/**
+ * \def POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED
+ *
+ * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS.
+ *
+ * Requires: POLARSSL_ECDH_C, POLARSSL_X509_CRT_PARSE_C
+ *
+ * This enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * TLS_ECDH_RSA_WITH_RC4_128_SHA
+ * TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+ * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+ * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+ * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+ * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+ * TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+ * TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+ * TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ * TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ * TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ * TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ */
+#define POLARSSL_KEY_EXCHANGE_ECDH_RSA_ENABLED
+
+/**
+ * \def POLARSSL_PK_PARSE_EC_EXTENDED
+ *
+ * Enhance support for reading EC keys using variants of SEC1 not allowed by
+ * RFC 5915 and RFC 5480.
+ *
+ * Currently this means parsing the SpecifiedECDomain choice of EC
+ * parameters (only known groups are supported, not arbitrary domains, to
+ * avoid validation issues).
+ *
+ * Disable if you only need to support RFC 5915 + 5480 key formats.
+ */
+#define POLARSSL_PK_PARSE_EC_EXTENDED
+
+/**
+ * \def POLARSSL_ERROR_STRERROR_BC
+ *
+ * Make available the backward compatible error_strerror() next to the
+ * current polarssl_strerror().
+ *
+ * For new code, it is recommended to use polarssl_strerror() instead and
+ * disable this.
+ *
+ * Disable if you run into name conflicts and want to really remove the
+ * error_strerror()
+ */
+#define POLARSSL_ERROR_STRERROR_BC
+
+/**
+ * \def POLARSSL_ERROR_STRERROR_DUMMY
+ *
+ * Enable a dummy error function to make use of polarssl_strerror() in
+ * third party libraries easier when POLARSSL_ERROR_C is disabled
+ * (no effect when POLARSSL_ERROR_C is enabled).
+ *
+ * You can safely disable this if POLARSSL_ERROR_C is enabled, or if you're
+ * not using polarssl_strerror() or error_strerror() in your application.
+ *
+ * Disable if you run into name conflicts and want to really remove the
+ * polarssl_strerror()
+ */
+#define POLARSSL_ERROR_STRERROR_DUMMY
+
+/**
+ * \def POLARSSL_GENPRIME
+ *
+ * Enable the prime-number generation code.
+ *
+ * Requires: POLARSSL_BIGNUM_C
+ */
+#define POLARSSL_GENPRIME
+
+/**
+ * \def POLARSSL_FS_IO
+ *
+ * Enable functions that use the filesystem.
+ */
+#define POLARSSL_FS_IO
+
+/**
+ * \def POLARSSL_NO_DEFAULT_ENTROPY_SOURCES
+ *
+ * Do not add default entropy sources. These are the platform specific,
+ * hardclock and HAVEGE based poll functions.
+ *
+ * This is useful to have more control over the added entropy sources in an
+ * application.
+ *
+ * Uncomment this macro to prevent loading of default entropy functions.
+ */
+//#define POLARSSL_NO_DEFAULT_ENTROPY_SOURCES
+
+/**
+ * \def POLARSSL_NO_PLATFORM_ENTROPY
+ *
+ * Do not use built-in platform entropy functions.
+ * This is useful if your platform does not support
+ * standards like the /dev/urandom or Windows CryptoAPI.
+ *
+ * Uncomment this macro to disable the built-in platform entropy functions.
+ */
+//#define POLARSSL_NO_PLATFORM_ENTROPY
+
+/**
+ * \def POLARSSL_ENTROPY_FORCE_SHA256
+ *
+ * Force the entropy accumulator to use a SHA-256 accumulator instead of the
+ * default SHA-512 based one (if both are available).
+ *
+ * Requires: POLARSSL_SHA256_C
+ *
+ * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option
+ * if you have performance concerns.
+ *
+ * This option is only useful if both POLARSSL_SHA256_C and
+ * POLARSSL_SHA512_C are defined. Otherwise the available hash module is used.
+ */
+//#define POLARSSL_ENTROPY_FORCE_SHA256
+
+/**
+ * \def POLARSSL_MEMORY_DEBUG
+ *
+ * Enable debugging of buffer allocator memory issues. Automatically prints
+ * (to stderr) all (fatal) messages on memory allocation issues. Enables
+ * function for 'debug output' of allocated memory.
+ *
+ * Requires: POLARSSL_MEMORY_BUFFER_ALLOC_C
+ *
+ * Uncomment this macro to let the buffer allocator print out error messages.
+ */
+//#define POLARSSL_MEMORY_DEBUG
+
+/**
+ * \def POLARSSL_MEMORY_BACKTRACE
+ *
+ * Include backtrace information with each allocated block.
+ *
+ * Requires: POLARSSL_MEMORY_BUFFER_ALLOC_C
+ * GLIBC-compatible backtrace() an backtrace_symbols() support
+ *
+ * Uncomment this macro to include backtrace information
+ */
+//#define POLARSSL_MEMORY_BACKTRACE
+
+/**
+ * \def POLARSSL_PKCS1_V15
+ *
+ * Enable support for PKCS#1 v1.5 encoding.
+ *
+ * Requires: POLARSSL_RSA_C
+ *
+ * This enables support for PKCS#1 v1.5 operations.
+ */
+#define POLARSSL_PKCS1_V15
+
+/**
+ * \def POLARSSL_PKCS1_V21
+ *
+ * Enable support for PKCS#1 v2.1 encoding.
+ *
+ * Requires: POLARSSL_MD_C, POLARSSL_RSA_C
+ *
+ * This enables support for RSAES-OAEP and RSASSA-PSS operations.
+ */
+#define POLARSSL_PKCS1_V21
+
+/**
+ * \def POLARSSL_RSA_NO_CRT
+ *
+ * Do not use the Chinese Remainder Theorem for the RSA private operation.
+ *
+ * Uncomment this macro to disable the use of CRT in RSA.
+ *
+ */
+//#define POLARSSL_RSA_NO_CRT
+
+/**
+ * \def POLARSSL_SELF_TEST
+ *
+ * Enable the checkup functions (*_self_test).
+ */
+#define POLARSSL_SELF_TEST
+
+/**
+ * \def POLARSSL_SSL_ALL_ALERT_MESSAGES
+ *
+ * Enable sending of alert messages in case of encountered errors as per RFC.
+ * If you choose not to send the alert messages, PolarSSL can still communicate
+ * with other servers, only debugging of failures is harder.
+ *
+ * The advantage of not sending alert messages, is that no information is given
+ * about reasons for failures thus preventing adversaries of gaining intel.
+ *
+ * Enable sending of all alert messages
+ */
+#define POLARSSL_SSL_ALERT_MESSAGES
+
+/**
+ * \def POLARSSL_SSL_DEBUG_ALL
+ *
+ * Enable the debug messages in SSL module for all issues.
+ * Debug messages have been disabled in some places to prevent timing
+ * attacks due to (unbalanced) debugging function calls.
+ *
+ * If you need all error reporting you should enable this during debugging,
+ * but remove this for production servers that should log as well.
+ *
+ * Uncomment this macro to report all debug messages on errors introducing
+ * a timing side-channel.
+ *
+ */
+//#define POLARSSL_SSL_DEBUG_ALL
+
+/**
+ * \def POLARSSL_SSL_HW_RECORD_ACCEL
+ *
+ * Enable hooking functions in SSL module for hardware acceleration of
+ * individual records.
+ *
+ * Uncomment this macro to enable hooking functions.
+ */
+//#define POLARSSL_SSL_HW_RECORD_ACCEL
+
+/**
+ * \def POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
+ *
+ * Enable support for receiving and parsing SSLv2 Client Hello messages for the
+ * SSL Server module (POLARSSL_SSL_SRV_C).
+ *
+ * Comment this macro to disable support for SSLv2 Client Hello messages.
+ */
+#define POLARSSL_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO
+
+/**
+ * \def POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE
+ *
+ * Pick the ciphersuite according to the client's preferences rather than ours
+ * in the SSL Server module (POLARSSL_SSL_SRV_C).
+ *
+ * Uncomment this macro to respect client's ciphersuite order
+ */
+//#define POLARSSL_SSL_SRV_RESPECT_CLIENT_PREFERENCE
+
+/**
+ * \def POLARSSL_SSL_MAX_FRAGMENT_LENGTH
+ *
+ * Enable support for RFC 6066 max_fragment_length extension in SSL.
+ *
+ * Comment this macro to disable support for the max_fragment_length extension
+ */
+#define POLARSSL_SSL_MAX_FRAGMENT_LENGTH
+
+/**
+ * \def POLARSSL_SSL_PROTO_SSL3
+ *
+ * Enable support for SSL 3.0.
+ *
+ * Requires: POLARSSL_MD5_C
+ * POLARSSL_SHA1_C
+ *
+ * Comment this macro to disable support for SSL 3.0
+ */
+#define POLARSSL_SSL_PROTO_SSL3
+
+/**
+ * \def POLARSSL_SSL_PROTO_TLS1
+ *
+ * Enable support for TLS 1.0.
+ *
+ * Requires: POLARSSL_MD5_C
+ * POLARSSL_SHA1_C
+ *
+ * Comment this macro to disable support for TLS 1.0
+ */
+#define POLARSSL_SSL_PROTO_TLS1
+
+/**
+ * \def POLARSSL_SSL_PROTO_TLS1_1
+ *
+ * Enable support for TLS 1.1.
+ *
+ * Requires: POLARSSL_MD5_C
+ * POLARSSL_SHA1_C
+ *
+ * Comment this macro to disable support for TLS 1.1
+ */
+#define POLARSSL_SSL_PROTO_TLS1_1
+
+/**
+ * \def POLARSSL_SSL_PROTO_TLS1_2
+ *
+ * Enable support for TLS 1.2.
+ *
+ * Requires: POLARSSL_SHA1_C or POLARSSL_SHA256_C or POLARSSL_SHA512_C
+ * (Depends on ciphersuites)
+ *
+ * Comment this macro to disable support for TLS 1.2
+ */
+#define POLARSSL_SSL_PROTO_TLS1_2
+
+/**
+ * \def POLARSSL_SSL_ALPN
+ *
+ * Enable support for Application Layer Protocol Negotiation.
+ * draft-ietf-tls-applayerprotoneg-05
+ *
+ * Comment this macro to disable support for ALPN.
+ */
+#define POLARSSL_SSL_ALPN
+
+/**
+ * \def POLARSSL_SSL_SESSION_TICKETS
+ *
+ * Enable support for RFC 5077 session tickets in SSL.
+ *
+ * Requires: POLARSSL_AES_C
+ * POLARSSL_SHA256_C
+ * POLARSSL_CIPHER_MODE_CBC
+ *
+ * Comment this macro to disable support for SSL session tickets
+ */
+#define POLARSSL_SSL_SESSION_TICKETS
+
+/**
+ * \def POLARSSL_SSL_SERVER_NAME_INDICATION
+ *
+ * Enable support for RFC 6066 server name indication (SNI) in SSL.
+ *
+ * Comment this macro to disable support for server name indication in SSL
+ */
+#define POLARSSL_SSL_SERVER_NAME_INDICATION
+
+/**
+ * \def POLARSSL_SSL_TRUNCATED_HMAC
+ *
+ * Enable support for RFC 6066 truncated HMAC in SSL.
+ *
+ * Comment this macro to disable support for truncated HMAC in SSL
+ */
+#define POLARSSL_SSL_TRUNCATED_HMAC
+
+/**
+ * \def POLARSSL_SSL_SET_CURVES
+ *
+ * Enable ssl_set_curves().
+ *
+ * This is disabled by default since it breaks binary compatibility with the
+ * 1.3.x line. If you choose to enable it, you will need to rebuild your
+ * application against the new header files, relinking will not be enough.
+ * It will be enabled by default, or no longer an option, in the 1.4 branch.
+ *
+ * Uncomment to make ssl_set_curves() available.
+ */
+//#define POLARSSL_SSL_SET_CURVES
+
+/**
+ * \def POLARSSL_THREADING_ALT
+ *
+ * Provide your own alternate threading implementation.
+ *
+ * Requires: POLARSSL_THREADING_C
+ *
+ * Uncomment this to allow your own alternate threading implementation.
+ */
+//#define POLARSSL_THREADING_ALT
+
+/**
+ * \def POLARSSL_THREADING_PTHREAD
+ *
+ * Enable the pthread wrapper layer for the threading layer.
+ *
+ * Requires: POLARSSL_THREADING_C
+ *
+ * Uncomment this to enable pthread mutexes.
+ */
+//#define POLARSSL_THREADING_PTHREAD
+
+/**
+ * \def POLARSSL_VERSION_FEATURES
+ *
+ * Allow run-time checking of compile-time enabled features. Thus allowing users
+ * to check at run-time if the library is for instance compiled with threading
+ * support via version_check_feature().
+ *
+ * Requires: POLARSSL_VERSION_C
+ *
+ * Comment this to disable run-time checking and save ROM space
+ */
+#define POLARSSL_VERSION_FEATURES
+
+/**
+ * \def POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3
+ *
+ * If set, the X509 parser will not break-off when parsing an X509 certificate
+ * and encountering an extension in a v1 or v2 certificate.
+ *
+ * Uncomment to prevent an error.
+ */
+//#define POLARSSL_X509_ALLOW_EXTENSIONS_NON_V3
+
+/**
+ * \def POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+ *
+ * If set, the X509 parser will not break-off when parsing an X509 certificate
+ * and encountering an unknown critical extension.
+ *
+ * Uncomment to prevent an error.
+ */
+//#define POLARSSL_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION
+
+/**
+ * \def POLARSSL_X509_CHECK_KEY_USAGE
+ *
+ * Enable verification of the keyUsage extension (CA and leaf certificates).
+ *
+ * Disabling this avoids problems with mis-issued and/or misused
+ * (intermediate) CA and leaf certificates.
+ *
+ * \warning Depending on your PKI use, disabling this can be a security risk!
+ *
+ * Comment to skip keyUsage checking for both CA and leaf certificates.
+ */
+#define POLARSSL_X509_CHECK_KEY_USAGE
+
+/**
+ * \def POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE
+ *
+ * Enable verification of the extendedKeyUsage extension (leaf certificates).
+ *
+ * Disabling this avoids problems with mis-issued and/or misused certificates.
+ *
+ * \warning Depending on your PKI use, disabling this can be a security risk!
+ *
+ * Comment to skip extendedKeyUsage checking for certificates.
+ */
+#define POLARSSL_X509_CHECK_EXTENDED_KEY_USAGE
+
+/**
+ * \def POLARSSL_X509_RSASSA_PSS_SUPPORT
+ *
+ * Enable parsing and verification of X.509 certificates, CRLs and CSRS
+ * signed with RSASSA-PSS (aka PKCS#1 v2.1).
+ *
+ * Comment this macro to disallow using RSASSA-PSS in certificates.
+ */
+#define POLARSSL_X509_RSASSA_PSS_SUPPORT
+
+/**
+ * \def POLARSSL_ZLIB_SUPPORT
+ *
+ * If set, the SSL/TLS module uses ZLIB to support compression and
+ * decompression of packet data.
+ *
+ * \warning TLS-level compression MAY REDUCE SECURITY! See for example the
+ * CRIME attack. Before enabling this option, you should examine with care if
+ * CRIME or similar exploits may be a applicable to your use case.
+ *
+ * Used in: library/ssl_tls.c
+ * library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * This feature requires zlib library and headers to be present.
+ *
+ * Uncomment to enable use of ZLIB
+ */
+//#define POLARSSL_ZLIB_SUPPORT
+/* \} name SECTION: PolarSSL feature support */
+
+/**
+ * \name SECTION: PolarSSL modules
+ *
+ * This section enables or disables entire modules in PolarSSL
+ * \{
+ */
+
+/**
+ * \def POLARSSL_AESNI_C
+ *
+ * Enable AES-NI support on x86-64.
+ *
+ * Module: library/aesni.c
+ * Caller: library/aes.c
+ *
+ * Requires: POLARSSL_HAVE_ASM
+ *
+ * This modules adds support for the AES-NI instructions on x86-64
+ */
+//#define POLARSSL_AESNI_C
+
+/**
+ * \def POLARSSL_AES_C
+ *
+ * Enable the AES block cipher.
+ *
+ * Module: library/aes.c
+ * Caller: library/ssl_tls.c
+ * library/pem.c
+ * library/ctr_drbg.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
+ * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
+ * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
+ * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
+ * TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
+ * TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
+ * TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
+ * TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
+ * TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
+ * TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
+ * TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
+ * TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
+ * TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+ * TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+ * TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+ * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
+ * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
+ * TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+ * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
+ * TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
+ * TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ * TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ * TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
+ * TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
+ * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
+ * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
+ * TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+ * TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
+ * TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
+ * TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+ * TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
+ * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384
+ * TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
+ * TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA
+ * TLS_DHE_PSK_WITH_AES_256_CBC_SHA
+ * TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
+ * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256
+ * TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
+ * TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA
+ * TLS_DHE_PSK_WITH_AES_128_CBC_SHA
+ * TLS_RSA_WITH_AES_256_GCM_SHA384
+ * TLS_RSA_WITH_AES_256_CBC_SHA256
+ * TLS_RSA_WITH_AES_256_CBC_SHA
+ * TLS_RSA_WITH_AES_128_GCM_SHA256
+ * TLS_RSA_WITH_AES_128_CBC_SHA256
+ * TLS_RSA_WITH_AES_128_CBC_SHA
+ * TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
+ * TLS_RSA_PSK_WITH_AES_256_CBC_SHA384
+ * TLS_RSA_PSK_WITH_AES_256_CBC_SHA
+ * TLS_RSA_PSK_WITH_AES_128_GCM_SHA256
+ * TLS_RSA_PSK_WITH_AES_128_CBC_SHA256
+ * TLS_RSA_PSK_WITH_AES_128_CBC_SHA
+ * TLS_PSK_WITH_AES_256_GCM_SHA384
+ * TLS_PSK_WITH_AES_256_CBC_SHA384
+ * TLS_PSK_WITH_AES_256_CBC_SHA
+ * TLS_PSK_WITH_AES_128_GCM_SHA256
+ * TLS_PSK_WITH_AES_128_CBC_SHA256
+ * TLS_PSK_WITH_AES_128_CBC_SHA
+ *
+ * PEM_PARSE uses AES for decrypting encrypted keys.
+ */
+#define POLARSSL_AES_C
+
+/**
+ * \def POLARSSL_ARC4_C
+ *
+ * Enable the ARCFOUR stream cipher.
+ *
+ * Module: library/arc4.c
+ * Caller: library/ssl_tls.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * TLS_ECDH_ECDSA_WITH_RC4_128_SHA
+ * TLS_ECDH_RSA_WITH_RC4_128_SHA
+ * TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
+ * TLS_ECDHE_RSA_WITH_RC4_128_SHA
+ * TLS_ECDHE_PSK_WITH_RC4_128_SHA
+ * TLS_DHE_PSK_WITH_RC4_128_SHA
+ * TLS_RSA_WITH_RC4_128_SHA
+ * TLS_RSA_WITH_RC4_128_MD5
+ * TLS_RSA_PSK_WITH_RC4_128_SHA
+ * TLS_PSK_WITH_RC4_128_SHA
+ */
+#define POLARSSL_ARC4_C
+
+/**
+ * \def POLARSSL_ASN1_PARSE_C
+ *
+ * Enable the generic ASN1 parser.
+ *
+ * Module: library/asn1.c
+ * Caller: library/x509.c
+ * library/dhm.c
+ * library/pkcs12.c
+ * library/pkcs5.c
+ * library/pkparse.c
+ */
+#define POLARSSL_ASN1_PARSE_C
+
+/**
+ * \def POLARSSL_ASN1_WRITE_C
+ *
+ * Enable the generic ASN1 writer.
+ *
+ * Module: library/asn1write.c
+ * Caller: library/ecdsa.c
+ * library/pkwrite.c
+ * library/x509_create.c
+ * library/x509write_crt.c
+ * library/x509write_csr.c
+ */
+#define POLARSSL_ASN1_WRITE_C
+
+/**
+ * \def POLARSSL_BASE64_C
+ *
+ * Enable the Base64 module.
+ *
+ * Module: library/base64.c
+ * Caller: library/pem.c
+ *
+ * This module is required for PEM support (required by X.509).
+ */
+#define POLARSSL_BASE64_C
+
+/**
+ * \def POLARSSL_BIGNUM_C
+ *
+ * Enable the multi-precision integer library.
+ *
+ * Module: library/bignum.c
+ * Caller: library/dhm.c
+ * library/ecp.c
+ * library/ecdsa.c
+ * library/rsa.c
+ * library/ssl_tls.c
+ *
+ * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support.
+ */
+#define POLARSSL_BIGNUM_C
+
+/**
+ * \def POLARSSL_BLOWFISH_C
+ *
+ * Enable the Blowfish block cipher.
+ *
+ * Module: library/blowfish.c
+ */
+#define POLARSSL_BLOWFISH_C
+
+/**
+ * \def POLARSSL_CAMELLIA_C
+ *
+ * Enable the Camellia block cipher.
+ *
+ * Module: library/camellia.c
+ * Caller: library/ssl_tls.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ * TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ * TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ * TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ * TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ * TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ * TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
+ * TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ * TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ * TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
+ * TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384
+ * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ * TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
+ * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
+ * TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ * TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ * TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
+ * TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ * TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
+ * TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ * TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ * TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ * TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ * TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ * TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ * TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384
+ * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
+ * TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
+ * TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256
+ * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
+ * TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
+ * TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ * TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ * TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ * TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ * TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384
+ * TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384
+ * TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256
+ * TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256
+ */
+#define POLARSSL_CAMELLIA_C
+
+/**
+ * \def POLARSSL_CCM_C
+ *
+ * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher.
+ *
+ * Module: library/ccm.c
+ *
+ * Requires: POLARSSL_AES_C or POLARSSL_CAMELLIA_C
+ *
+ * This module enables the AES-CCM ciphersuites, if other requisites are
+ * enabled as well.
+ */
+#define POLARSSL_CCM_C
+
+/**
+ * \def POLARSSL_CERTS_C
+ *
+ * Enable the test certificates.
+ *
+ * Module: library/certs.c
+ * Caller:
+ *
+ * Requires: POLARSSL_PEM_PARSE_C
+ *
+ * This module is used for testing (ssl_client/server).
+ */
+#define POLARSSL_CERTS_C
+
+/**
+ * \def POLARSSL_CIPHER_C
+ *
+ * Enable the generic cipher layer.
+ *
+ * Module: library/cipher.c
+ * Caller: library/ssl_tls.c
+ *
+ * Uncomment to enable generic cipher wrappers.
+ */
+#define POLARSSL_CIPHER_C
+
+/**
+ * \def POLARSSL_CTR_DRBG_C
+ *
+ * Enable the CTR_DRBG AES-256-based random generator.
+ *
+ * Module: library/ctr_drbg.c
+ * Caller:
+ *
+ * Requires: POLARSSL_AES_C
+ *
+ * This module provides the CTR_DRBG AES-256 random number generator.
+ */
+#define POLARSSL_CTR_DRBG_C
+
+/**
+ * \def POLARSSL_DEBUG_C
+ *
+ * Enable the debug functions.
+ *
+ * Module: library/debug.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ *
+ * This module provides debugging functions.
+ */
+#define POLARSSL_DEBUG_C
+
+/**
+ * \def POLARSSL_DES_C
+ *
+ * Enable the DES block cipher.
+ *
+ * Module: library/des.c
+ * Caller: library/pem.c
+ * library/ssl_tls.c
+ *
+ * This module enables the following ciphersuites (if other requisites are
+ * enabled as well):
+ * TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
+ * TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
+ * TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
+ * TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
+ * TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+ * TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA
+ * TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
+ * TLS_RSA_WITH_3DES_EDE_CBC_SHA
+ * TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA
+ * TLS_PSK_WITH_3DES_EDE_CBC_SHA
+ *
+ * PEM_PARSE uses DES/3DES for decrypting encrypted keys.
+ */
+#define POLARSSL_DES_C
+
+/**
+ * \def POLARSSL_DHM_C
+ *
+ * Enable the Diffie-Hellman-Merkle module.
+ *
+ * Module: library/dhm.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * This module is used by the following key exchanges:
+ * DHE-RSA, DHE-PSK
+ */
+#define POLARSSL_DHM_C
+
+/**
+ * \def POLARSSL_ECDH_C
+ *
+ * Enable the elliptic curve Diffie-Hellman library.
+ *
+ * Module: library/ecdh.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * This module is used by the following key exchanges:
+ * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK
+ *
+ * Requires: POLARSSL_ECP_C
+ */
+#define POLARSSL_ECDH_C
+
+/**
+ * \def POLARSSL_ECDSA_C
+ *
+ * Enable the elliptic curve DSA library.
+ *
+ * Module: library/ecdsa.c
+ * Caller:
+ *
+ * This module is used by the following key exchanges:
+ * ECDHE-ECDSA
+ *
+ * Requires: POLARSSL_ECP_C, POLARSSL_ASN1_WRITE_C, POLARSSL_ASN1_PARSE_C
+ */
+#define POLARSSL_ECDSA_C
+
+/**
+ * \def POLARSSL_ECP_C
+ *
+ * Enable the elliptic curve over GF(p) library.
+ *
+ * Module: library/ecp.c
+ * Caller: library/ecdh.c
+ * library/ecdsa.c
+ *
+ * Requires: POLARSSL_BIGNUM_C and at least one POLARSSL_ECP_DP_XXX_ENABLED
+ */
+#define POLARSSL_ECP_C
+
+/**
+ * \def POLARSSL_ENTROPY_C
+ *
+ * Enable the platform-specific entropy code.
+ *
+ * Module: library/entropy.c
+ * Caller:
+ *
+ * Requires: POLARSSL_SHA512_C or POLARSSL_SHA256_C
+ *
+ * This module provides a generic entropy pool
+ */
+#define POLARSSL_ENTROPY_C
+
+/**
+ * \def POLARSSL_ERROR_C
+ *
+ * Enable error code to error string conversion.
+ *
+ * Module: library/error.c
+ * Caller:
+ *
+ * This module enables polarssl_strerror().
+ */
+#define POLARSSL_ERROR_C
+
+/**
+ * \def POLARSSL_GCM_C
+ *
+ * Enable the Galois/Counter Mode (GCM) for AES.
+ *
+ * Module: library/gcm.c
+ *
+ * Requires: POLARSSL_AES_C or POLARSSL_CAMELLIA_C
+ *
+ * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other
+ * requisites are enabled as well.
+ */
+#define POLARSSL_GCM_C
+
+/**
+ * \def POLARSSL_HAVEGE_C
+ *
+ * Enable the HAVEGE random generator.
+ *
+ * Warning: the HAVEGE random generator is not suitable for virtualized
+ * environments
+ *
+ * Warning: the HAVEGE random generator is dependent on timing and specific
+ * processor traits. It is therefore not advised to use HAVEGE as
+ * your applications primary random generator or primary entropy pool
+ * input. As a secondary input to your entropy pool, it IS able add
+ * the (limited) extra entropy it provides.
+ *
+ * Module: library/havege.c
+ * Caller:
+ *
+ * Requires: POLARSSL_TIMING_C
+ *
+ * Uncomment to enable the HAVEGE random generator.
+ */
+//#define POLARSSL_HAVEGE_C
+
+/**
+ * \def POLARSSL_HMAC_DRBG_C
+ *
+ * Enable the HMAC_DRBG random generator.
+ *
+ * Module: library/hmac_drbg.c
+ * Caller:
+ *
+ * Requires: POLARSSL_MD_C
+ *
+ * Uncomment to enable the HMAC_DRBG random number geerator.
+ */
+#define POLARSSL_HMAC_DRBG_C
+
+/**
+ * \def POLARSSL_MD_C
+ *
+ * Enable the generic message digest layer.
+ *
+ * Module: library/md.c
+ * Caller:
+ *
+ * Uncomment to enable generic message digest wrappers.
+ */
+#define POLARSSL_MD_C
+
+/**
+ * \def POLARSSL_MD2_C
+ *
+ * Enable the MD2 hash algorithm.
+ *
+ * Module: library/md2.c
+ * Caller:
+ *
+ * Uncomment to enable support for (rare) MD2-signed X.509 certs.
+ */
+//#define POLARSSL_MD2_C
+
+/**
+ * \def POLARSSL_MD4_C
+ *
+ * Enable the MD4 hash algorithm.
+ *
+ * Module: library/md4.c
+ * Caller:
+ *
+ * Uncomment to enable support for (rare) MD4-signed X.509 certs.
+ */
+//#define POLARSSL_MD4_C
+
+/**
+ * \def POLARSSL_MD5_C
+ *
+ * Enable the MD5 hash algorithm.
+ *
+ * Module: library/md5.c
+ * Caller: library/md.c
+ * library/pem.c
+ * library/ssl_tls.c
+ *
+ * This module is required for SSL/TLS and X.509.
+ * PEM_PARSE uses MD5 for decrypting encrypted keys.
+ */
+#define POLARSSL_MD5_C
+
+/**
+ * \def POLARSSL_MEMORY_C
+ * Deprecated since 1.3.5. Please use POLARSSL_PLATFORM_MEMORY instead.
+ */
+//#define POLARSSL_MEMORY_C
+
+/**
+ * \def POLARSSL_MEMORY_BUFFER_ALLOC_C
+ *
+ * Enable the buffer allocator implementation that makes use of a (stack)
+ * based buffer to 'allocate' dynamic memory. (replaces malloc() and free()
+ * calls)
+ *
+ * Module: library/memory_buffer_alloc.c
+ *
+ * Requires: POLARSSL_PLATFORM_C
+ * POLARSSL_PLATFORM_MEMORY (to use it within PolarSSL)
+ *
+ * Enable this module to enable the buffer memory allocator.
+ */
+//#define POLARSSL_MEMORY_BUFFER_ALLOC_C
+
+/**
+ * \def POLARSSL_NET_C
+ *
+ * Enable the TCP/IP networking routines.
+ *
+ * Module: library/net.c
+ *
+ * This module provides TCP/IP networking routines.
+ */
+#define POLARSSL_NET_C
+
+/**
+ * \def POLARSSL_OID_C
+ *
+ * Enable the OID database.
+ *
+ * Module: library/oid.c
+ * Caller: library/asn1write.c
+ * library/pkcs5.c
+ * library/pkparse.c
+ * library/pkwrite.c
+ * library/rsa.c
+ * library/x509.c
+ * library/x509_create.c
+ * library/x509_crl.c
+ * library/x509_crt.c
+ * library/x509_csr.c
+ * library/x509write_crt.c
+ * library/x509write_csr.c
+ *
+ * This modules translates between OIDs and internal values.
+ */
+#define POLARSSL_OID_C
+
+/**
+ * \def POLARSSL_PADLOCK_C
+ *
+ * Enable VIA Padlock support on x86.
+ *
+ * Module: library/padlock.c
+ * Caller: library/aes.c
+ *
+ * Requires: POLARSSL_HAVE_ASM
+ *
+ * This modules adds support for the VIA PadLock on x86.
+ */
+//#define POLARSSL_PADLOCK_C
+
+/**
+ * \def POLARSSL_PBKDF2_C
+ *
+ * Enable PKCS#5 PBKDF2 key derivation function.
+ * DEPRECATED: Use POLARSSL_PKCS5_C instead
+ *
+ * Module: library/pbkdf2.c
+ *
+ * Requires: POLARSSL_PKCS5_C
+ *
+ * This module adds support for the PKCS#5 PBKDF2 key derivation function.
+ */
+#define POLARSSL_PBKDF2_C
+
+/**
+ * \def POLARSSL_PEM_PARSE_C
+ *
+ * Enable PEM decoding / parsing.
+ *
+ * Module: library/pem.c
+ * Caller: library/dhm.c
+ * library/pkparse.c
+ * library/x509_crl.c
+ * library/x509_crt.c
+ * library/x509_csr.c
+ *
+ * Requires: POLARSSL_BASE64_C
+ *
+ * This modules adds support for decoding / parsing PEM files.
+ */
+#define POLARSSL_PEM_PARSE_C
+
+/**
+ * \def POLARSSL_PEM_WRITE_C
+ *
+ * Enable PEM encoding / writing.
+ *
+ * Module: library/pem.c
+ * Caller: library/pkwrite.c
+ * library/x509write_crt.c
+ * library/x509write_csr.c
+ *
+ * Requires: POLARSSL_BASE64_C
+ *
+ * This modules adds support for encoding / writing PEM files.
+ */
+#define POLARSSL_PEM_WRITE_C
+
+/**
+ * \def POLARSSL_PK_C
+ *
+ * Enable the generic public (asymetric) key layer.
+ *
+ * Module: library/pk.c
+ * Caller: library/ssl_tls.c
+ * library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * Requires: POLARSSL_RSA_C or POLARSSL_ECP_C
+ *
+ * Uncomment to enable generic public key wrappers.
+ */
+#define POLARSSL_PK_C
+
+/**
+ * \def POLARSSL_PK_PARSE_C
+ *
+ * Enable the generic public (asymetric) key parser.
+ *
+ * Module: library/pkparse.c
+ * Caller: library/x509_crt.c
+ * library/x509_csr.c
+ *
+ * Requires: POLARSSL_PK_C
+ *
+ * Uncomment to enable generic public key parse functions.
+ */
+#define POLARSSL_PK_PARSE_C
+
+/**
+ * \def POLARSSL_PK_WRITE_C
+ *
+ * Enable the generic public (asymetric) key writer.
+ *
+ * Module: library/pkwrite.c
+ * Caller: library/x509write.c
+ *
+ * Requires: POLARSSL_PK_C
+ *
+ * Uncomment to enable generic public key write functions.
+ */
+#define POLARSSL_PK_WRITE_C
+
+/**
+ * \def POLARSSL_PKCS5_C
+ *
+ * Enable PKCS#5 functions.
+ *
+ * Module: library/pkcs5.c
+ *
+ * Requires: POLARSSL_MD_C
+ *
+ * This module adds support for the PKCS#5 functions.
+ */
+#define POLARSSL_PKCS5_C
+
+/**
+ * \def POLARSSL_PKCS11_C
+ *
+ * Enable wrapper for PKCS#11 smartcard support.
+ *
+ * Module: library/pkcs11.c
+ * Caller: library/pk.c
+ *
+ * Requires: POLARSSL_PK_C
+ *
+ * This module enables SSL/TLS PKCS #11 smartcard support.
+ * Requires the presence of the PKCS#11 helper library (libpkcs11-helper)
+ */
+//#define POLARSSL_PKCS11_C
+
+/**
+ * \def POLARSSL_PKCS12_C
+ *
+ * Enable PKCS#12 PBE functions.
+ * Adds algorithms for parsing PKCS#8 encrypted private keys
+ *
+ * Module: library/pkcs12.c
+ * Caller: library/pkparse.c
+ *
+ * Requires: POLARSSL_ASN1_PARSE_C, POLARSSL_CIPHER_C, POLARSSL_MD_C
+ * Can use: POLARSSL_ARC4_C
+ *
+ * This module enables PKCS#12 functions.
+ */
+#define POLARSSL_PKCS12_C
+
+/**
+ * \def POLARSSL_PLATFORM_C
+ *
+ * Enable the platform abstraction layer that allows you to re-assign
+ * functions like malloc(), free(), printf(), fprintf()
+ *
+ * Module: library/platform.c
+ * Caller: Most other .c files
+ *
+ * This module enables abstraction of common (libc) functions.
+ */
+//#define POLARSSL_PLATFORM_C
+
+/**
+ * \def POLARSSL_RIPEMD160_C
+ *
+ * Enable the RIPEMD-160 hash algorithm.
+ *
+ * Module: library/ripemd160.c
+ * Caller: library/md.c
+ *
+ */
+#define POLARSSL_RIPEMD160_C
+
+/**
+ * \def POLARSSL_RSA_C
+ *
+ * Enable the RSA public-key cryptosystem.
+ *
+ * Module: library/rsa.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ * library/x509.c
+ *
+ * This module is used by the following key exchanges:
+ * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK
+ *
+ * Requires: POLARSSL_BIGNUM_C, POLARSSL_OID_C
+ */
+#define POLARSSL_RSA_C
+
+/**
+ * \def POLARSSL_SHA1_C
+ *
+ * Enable the SHA1 cryptographic hash algorithm.
+ *
+ * Module: library/sha1.c
+ * Caller: library/md.c
+ * library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ * library/x509write_crt.c
+ *
+ * This module is required for SSL/TLS and SHA1-signed certificates.
+ */
+#define POLARSSL_SHA1_C
+
+/**
+ * \def POLARSSL_SHA256_C
+ *
+ * Enable the SHA-224 and SHA-256 cryptographic hash algorithms.
+ * (Used to be POLARSSL_SHA2_C)
+ *
+ * Module: library/sha256.c
+ * Caller: library/entropy.c
+ * library/md.c
+ * library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ *
+ * This module adds support for SHA-224 and SHA-256.
+ * This module is required for the SSL/TLS 1.2 PRF function.
+ */
+#define POLARSSL_SHA256_C
+
+/**
+ * \def POLARSSL_SHA512_C
+ *
+ * Enable the SHA-384 and SHA-512 cryptographic hash algorithms.
+ * (Used to be POLARSSL_SHA4_C)
+ *
+ * Module: library/sha512.c
+ * Caller: library/entropy.c
+ * library/md.c
+ * library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * This module adds support for SHA-384 and SHA-512.
+ */
+#define POLARSSL_SHA512_C
+
+/**
+ * \def POLARSSL_SSL_CACHE_C
+ *
+ * Enable simple SSL cache implementation.
+ *
+ * Module: library/ssl_cache.c
+ * Caller:
+ *
+ * Requires: POLARSSL_SSL_CACHE_C
+ */
+#define POLARSSL_SSL_CACHE_C
+
+/**
+ * \def POLARSSL_SSL_CLI_C
+ *
+ * Enable the SSL/TLS client code.
+ *
+ * Module: library/ssl_cli.c
+ * Caller:
+ *
+ * Requires: POLARSSL_SSL_TLS_C
+ *
+ * This module is required for SSL/TLS client support.
+ */
+#define POLARSSL_SSL_CLI_C
+
+/**
+ * \def POLARSSL_SSL_SRV_C
+ *
+ * Enable the SSL/TLS server code.
+ *
+ * Module: library/ssl_srv.c
+ * Caller:
+ *
+ * Requires: POLARSSL_SSL_TLS_C
+ *
+ * This module is required for SSL/TLS server support.
+ */
+#define POLARSSL_SSL_SRV_C
+
+/**
+ * \def POLARSSL_SSL_TLS_C
+ *
+ * Enable the generic SSL/TLS code.
+ *
+ * Module: library/ssl_tls.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * Requires: POLARSSL_CIPHER_C, POLARSSL_MD_C
+ * and at least one of the POLARSSL_SSL_PROTO_* defines
+ *
+ * This module is required for SSL/TLS.
+ */
+#define POLARSSL_SSL_TLS_C
+
+/**
+ * \def POLARSSL_THREADING_C
+ *
+ * Enable the threading abstraction layer.
+ * By default PolarSSL assumes it is used in a non-threaded environment or that
+ * contexts are not shared between threads. If you do intend to use contexts
+ * between threads, you will need to enable this layer to prevent race
+ * conditions.
+ *
+ * Module: library/threading.c
+ *
+ * This allows different threading implementations (self-implemented or
+ * provided).
+ *
+ * You will have to enable either POLARSSL_THREADING_ALT or
+ * POLARSSL_THREADING_PTHREAD.
+ *
+ * Enable this layer to allow use of mutexes within PolarSSL
+ */
+//#define POLARSSL_THREADING_C
+
+/**
+ * \def POLARSSL_TIMING_C
+ *
+ * Enable the portable timing interface.
+ *
+ * Module: library/timing.c
+ * Caller: library/havege.c
+ *
+ * This module is used by the HAVEGE random number generator.
+ */
+#define POLARSSL_TIMING_C
+
+/**
+ * \def POLARSSL_VERSION_C
+ *
+ * Enable run-time version information.
+ *
+ * Module: library/version.c
+ *
+ * This module provides run-time version information.
+ */
+#define POLARSSL_VERSION_C
+
+/**
+ * \def POLARSSL_X509_USE_C
+ *
+ * Enable X.509 core for using certificates.
+ *
+ * Module: library/x509.c
+ * Caller: library/x509_crl.c
+ * library/x509_crt.c
+ * library/x509_csr.c
+ *
+ * Requires: POLARSSL_ASN1_PARSE_C, POLARSSL_BIGNUM_C, POLARSSL_OID_C,
+ * POLARSSL_PK_PARSE_C
+ *
+ * This module is required for the X.509 parsing modules.
+ */
+#define POLARSSL_X509_USE_C
+
+/**
+ * \def POLARSSL_X509_CRT_PARSE_C
+ *
+ * Enable X.509 certificate parsing.
+ *
+ * Module: library/x509_crt.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ *
+ * Requires: POLARSSL_X509_USE_C
+ *
+ * This module is required for X.509 certificate parsing.
+ */
+#define POLARSSL_X509_CRT_PARSE_C
+
+/**
+ * \def POLARSSL_X509_CRL_PARSE_C
+ *
+ * Enable X.509 CRL parsing.
+ *
+ * Module: library/x509_crl.c
+ * Caller: library/x509_crt.c
+ *
+ * Requires: POLARSSL_X509_USE_C
+ *
+ * This module is required for X.509 CRL parsing.
+ */
+#define POLARSSL_X509_CRL_PARSE_C
+
+/**
+ * \def POLARSSL_X509_CSR_PARSE_C
+ *
+ * Enable X.509 Certificate Signing Request (CSR) parsing.
+ *
+ * Module: library/x509_csr.c
+ * Caller: library/x509_crt_write.c
+ *
+ * Requires: POLARSSL_X509_USE_C
+ *
+ * This module is used for reading X.509 certificate request.
+ */
+#define POLARSSL_X509_CSR_PARSE_C
+
+/**
+ * \def POLARSSL_X509_CREATE_C
+ *
+ * Enable X.509 core for creating certificates.
+ *
+ * Module: library/x509_create.c
+ *
+ * Requires: POLARSSL_BIGNUM_C, POLARSSL_OID_C, POLARSSL_PK_WRITE_C
+ *
+ * This module is the basis for creating X.509 certificates and CSRs.
+ */
+#define POLARSSL_X509_CREATE_C
+
+/**
+ * \def POLARSSL_X509_CRT_WRITE_C
+ *
+ * Enable creating X.509 certificates.
+ *
+ * Module: library/x509_crt_write.c
+ *
+ * Requires: POLARSSL_CREATE_C
+ *
+ * This module is required for X.509 certificate creation.
+ */
+#define POLARSSL_X509_CRT_WRITE_C
+
+/**
+ * \def POLARSSL_X509_CSR_WRITE_C
+ *
+ * Enable creating X.509 Certificate Signing Requests (CSR).
+ *
+ * Module: library/x509_csr_write.c
+ *
+ * Requires: POLARSSL_CREATE_C
+ *
+ * This module is required for X.509 certificate request writing.
+ */
+#define POLARSSL_X509_CSR_WRITE_C
+
+/**
+ * \def POLARSSL_XTEA_C
+ *
+ * Enable the XTEA block cipher.
+ *
+ * Module: library/xtea.c
+ * Caller:
+ */
+#define POLARSSL_XTEA_C
+
+/* \} name SECTION: PolarSSL modules */
+
+/**
+ * \name SECTION: Module configuration options
+ *
+ * This section allows for the setting of module specific sizes and
+ * configuration options. The default values are already present in the
+ * relevant header files and should suffice for the regular use cases.
+ *
+ * Our advice is to enable options and change their values here
+ * only if you have a good reason and know the consequences.
+ *
+ * Please check the respective header file for documentation on these
+ * parameters (to prevent duplicate documentation).
+ * \{
+ */
+
+/* MPI / BIGNUM options */
+//#define POLARSSL_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */
+//#define POLARSSL_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */
+
+/* CTR_DRBG options */
+//#define CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */
+//#define CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */
+//#define CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */
+//#define CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */
+//#define CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */
+
+/* HMAC_DRBG options */
+//#define POLARSSL_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */
+//#define POLARSSL_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */
+//#define POLARSSL_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */
+//#define POLARSSL_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */
+
+/* ECP options */
+//#define POLARSSL_ECP_MAX_BITS 521 /**< Maximum bit size of groups */
+//#define POLARSSL_ECP_WINDOW_SIZE 6 /**< Maximum window size used */
+//#define POLARSSL_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */
+
+/* Entropy options */
+//#define ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */
+//#define ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */
+
+/* Memory buffer allocator options */
+//#define POLARSSL_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */
+
+/* Platform options */
+//#define POLARSSL_PLATFORM_STD_MEM_HDR <stdlib.h> /**< Header to include if POLARSSL_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */
+//#define POLARSSL_PLATFORM_STD_MALLOC malloc /**< Default allocator to use, can be undefined */
+//#define POLARSSL_PLATFORM_STD_FREE free /**< Default free to use, can be undefined */
+//#define POLARSSL_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */
+//#define POLARSSL_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */
+
+/* SSL Cache options */
+//#define SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */
+//#define SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */
+
+/* SSL options */
+//#define SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */
+//#define SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */
+//#define POLARSSL_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
+
+/**
+ * Complete list of ciphersuites to use, in order of preference.
+ *
+ * \warning No dependency checking is done on that field! This option can only
+ * be used to restrict the set of available ciphersuites. It is your
+ * responsibility to make sure the needed modules are active.
+ *
+ * Use this to save a few hundred bytes of ROM (default ordering of all
+ * available ciphersuites) and a few to a few hundred bytes of RAM.
+ *
+ * The value below is only an example, not the default.
+ */
+//#define SSL_CIPHERSUITES TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+
+/* Debug options */
+//#define POLARSSL_DEBUG_DFL_MODE POLARSSL_DEBUG_LOG_FULL /**< Default log: Full or Raw */
+
+/* \} name SECTION: Module configuration options */
+
+
+#endif /* POLARSSL_CONFIG_H */
#include "util.h"
#include "nonce2key/nonce2key.h"
#include "../common/iso15693tools.h"
+#include "../common/crc16.h"
+#include "aes.h"
/**
* The following params expected:
* UsbCommand c
return 1;
}
+/*
+ Simple AES 128 cbc hook up to OpenSSL.
+ params: key, input
+*/
+static int l_aes(lua_State *L)
+{
+ //Check number of arguments
+ int i;
+ size_t size;
+ const char *p_key = luaL_checklstring(L, 1, &size);
+ if(size != 32) return returnToLuaWithError(L,"Wrong size of key, got %d bytes, expected 32", (int) size);
+
+ const char *p_encTxt = luaL_checklstring(L, 2, &size);
+
+ unsigned char indata[16] = {0x00};
+ unsigned char outdata[16] = {0x00};
+ unsigned char aes_key[16] = {0x00};
+ unsigned char iv[16] = {0x00};
+
+ // convert key to bytearray
+ for (i = 0; i < 32; i += 2) {
+ sscanf(&p_encTxt[i], "%02x", (unsigned int *)&indata[i / 2]);
+ }
+
+ // convert input to bytearray
+ for (i = 0; i < 32; i += 2) {
+ sscanf(&p_key[i], "%02x", (unsigned int *)&aes_key[i / 2]);
+ }
+
+ //AES_KEY key;
+ //AES_set_decrypt_key(aes_key, 128, &key);
+ //AES_cbc_encrypt(indata, outdata, sizeof(indata), &key, iv, AES_DECRYPT);
+
+ aes_context ctx;
+ aes_init(&ctx);
+ aes_setkey_enc(&ctx,(const unsigned char *)p_key,128);
+ aes_crypt_cbc(&ctx,AES_DECRYPT,sizeof(indata), iv, indata,outdata );
+ //Push decrypted array as a string
+ lua_pushlstring(L,(const char *)&outdata, sizeof(outdata));
+ return 1;// return 1 to signal one return value
+}
+
+static int l_crc16(lua_State *L)
+{
+ size_t size;
+ const char *p_str = luaL_checklstring(L, 1, &size);
+
+ uint16_t retval = crc16_ccitt( (uint8_t*) p_str, size);
+ lua_pushinteger(L, (int) retval);
+ return 1;
+}
+
/**
* @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be
* able to do "require('foobar')" if foobar.lua is within lualibs folder.
{"clearCommandBuffer", l_clearCommandBuffer},
{"console", l_CmdConsole},
{"iso15693_crc", l_iso15693_crc},
+ {"aes", l_aes},
+ {"crc16", l_crc16},
{NULL, NULL}
};
--- /dev/null
+local cmds = require('commands')
+local getopt = require('getopt')
+local bin = require('bin')
+local lib14a = require('read14a')
+local utils = require('utils')
+local md5 = require('md5')
+local dumplib = require('html_dumplib')
+local toyNames = require('default_toys')
+
+example =[[
+ 1. script run tnp3dump
+ 2. script run tnp3dump -n
+ 3. script run tnp3dump -k aabbccddeeff
+ 4. script run tnp3dump -k aabbccddeeff -n
+ 5. script run tnp3dump -o myfile
+ 6. script run tnp3dump -n -o myfile
+ 7. script run tnp3dump -k aabbccddeeff -n -o myfile
+]]
+author = "Iceman"
+usage = "script run tnp3dump -k <key> -n -o <filename>"
+desc =[[
+This script will try to dump the contents of a Mifare TNP3xxx card.
+It will need a valid KeyA in order to find the other keys and decode the card.
+Arguments:
+ -h : this help
+ -k <key> : Sector 0 Key A.
+ -n : Use the nested cmd to find all keys
+ -o : filename for the saved dumps
+]]
+
+local HASHCONSTANT = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
+
+local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
+local DEBUG = false -- the debug flag
+local numBlocks = 64
+local numSectors = 16
+---
+-- A debug printout-function
+function dbg(args)
+ if not DEBUG then
+ return
+ end
+
+ if type(args) == "table" then
+ local i = 1
+ while result[i] do
+ dbg(result[i])
+ i = i+1
+ end
+ else
+ print("###", args)
+ end
+end
+---
+-- This is only meant to be used when errors occur
+function oops(err)
+ print("ERROR: ",err)
+end
+---
+-- Usage help
+function help()
+ print(desc)
+ print("Example usage")
+ print(example)
+end
+--
+-- Exit message
+function ExitMsg(msg)
+ print( string.rep('--',20) )
+ print( string.rep('--',20) )
+ print(msg)
+ print()
+end
+
+local function readdumpkeys(infile)
+ t = infile:read("*all")
+ len = string.len(t)
+ local len,hex = bin.unpack(("H%d"):format(len),t)
+ return hex
+end
+
+local function waitCmd()
+ local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
+ if response then
+ local count,cmd,arg0 = bin.unpack('LL',response)
+ if(arg0==1) then
+ local count,arg1,arg2,data = bin.unpack('LLH511',response,count)
+ return data:sub(1,32)
+ else
+ return nil, "Couldn't read block.."
+ end
+ end
+ return nil, "No response from device"
+end
+
+local function computeCrc16(s)
+ local hash = core.crc16(utils.ConvertHexToAscii(s))
+ return hash
+end
+
+local function reverseCrcBytes(crc)
+ crc2 = crc:sub(3,4)..crc:sub(1,2)
+ return tonumber(crc2,16)
+end
+
+local function main(args)
+
+ print( string.rep('--',20) )
+ print( string.rep('--',20) )
+
+ local keyA
+ local cmd
+ local err
+ local useNested = false
+ local cmdReadBlockString = 'hf mf rdbl %d A %s'
+ local input = "dumpkeys.bin"
+ local outputTemplate = os.date("toydump_%Y-%m-%d_%H%M%S");
+
+ -- Arguments for the script
+ for o, a in getopt.getopt(args, 'hk:no:') do
+ if o == "h" then return help() end
+ if o == "k" then keyA = a end
+ if o == "n" then useNested = true end
+ if o == "o" then outputTemplate = a end
+ end
+
+ -- validate input args.
+ keyA = keyA or '4b0b20107ccb'
+ if #(keyA) ~= 12 then
+ return oops( string.format('Wrong length of write key (was %d) expected 12', #keyA))
+ end
+
+ -- Turn off Debug
+ local cmdSetDbgOff = "hf mf dbg 0"
+ core.console( cmdSetDbgOff)
+
+ result, err = lib14a.read1443a(false)
+ if not result then
+ return oops(err)
+ end
+
+ core.clearCommandBuffer()
+
+ if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
+ return oops('This is not a TNP3xxx tag. aborting.')
+ end
+
+ -- Show tag info
+ print((' Found tag : %s'):format(result.name))
+ print(('Using keyA : %s'):format(keyA))
+
+ --Trying to find the other keys
+ if useNested then
+ core.console( ('hf mf nested 1 0 A %s d'):format(keyA) )
+ end
+
+ core.clearCommandBuffer()
+
+ -- Loading keyfile
+ print('Loading dumpkeys.bin')
+ local hex, err = utils.ReadDumpFile(input)
+ if not hex then
+ return oops(err)
+ end
+
+ local akeys = hex:sub(0,12*16)
+
+ -- Read block 0
+ cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 0,arg2 = 0,arg3 = 0, data = keyA}
+ err = core.SendCommand(cmd:getBytes())
+ if err then return oops(err) end
+ local block0, err = waitCmd()
+ if err then return oops(err) end
+
+ -- Read block 1
+ cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = 1,arg2 = 0,arg3 = 0, data = keyA}
+ err = core.SendCommand(cmd:getBytes())
+ if err then return oops(err) end
+ local block1, err = waitCmd()
+ if err then return oops(err) end
+
+ local key
+ local pos = 0
+ local blockNo
+ local blocks = {}
+
+ print('Reading card data')
+ core.clearCommandBuffer()
+
+ -- main loop
+ io.write('Decrypting blocks > ')
+ for blockNo = 0, numBlocks-1, 1 do
+
+ if core.ukbhit() then
+ print("aborted by user")
+ break
+ end
+
+ pos = (math.floor( blockNo / 4 ) * 12)+1
+ key = akeys:sub(pos, pos + 11 )
+ cmd = Command:new{cmd = cmds.CMD_MIFARE_READBL, arg1 = blockNo ,arg2 = 0,arg3 = 0, data = key}
+ local err = core.SendCommand(cmd:getBytes())
+ if err then return oops(err) end
+ local blockdata, err = waitCmd()
+ if err then return oops(err) end
+
+ if blockNo%4 ~= 3 then
+ if blockNo < 8 then
+ -- Block 0-7 not encrypted
+ blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,blockdata)
+ else
+ local base = ('%s%s%02x%s'):format(block0, block1, blockNo, HASHCONSTANT)
+ local baseStr = utils.ConvertHexToAscii(base)
+ local md5hash = md5.sumhexa(baseStr)
+ local aestest = core.aes(md5hash, blockdata)
+
+ local hex = utils.ConvertAsciiToBytes(aestest)
+ hex = utils.ConvertBytesToHex(hex)
+
+ -- blocks with zero not encrypted.
+ if string.find(blockdata, '^0+$') then
+ blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,blockdata)
+ else
+ blocks[blockNo+1] = ('%02d :: %s'):format(blockNo,hex)
+ io.write( blockNo..',')
+ end
+ end
+ else
+ -- Sectorblocks, not encrypted
+ blocks[blockNo+1] = ('%02d :: %s%s'):format(blockNo,key,blockdata:sub(13,32))
+ end
+ end
+ io.write('\n')
+
+ core.clearCommandBuffer()
+
+ -- Print results
+ local bindata = {}
+ local emldata = ''
+
+ for _,s in pairs(blocks) do
+ local slice = s:sub(8,#s)
+ local str = utils.ConvertBytesToAscii(
+ utils.ConvertHexToBytes(slice)
+ )
+ emldata = emldata..slice..'\n'
+ for c in (str):gmatch('.') do
+ bindata[#bindata+1] = c
+ end
+ end
+
+ -- Write dump to files
+ if not DEBUG then
+ local foo = dumplib.SaveAsBinary(bindata, outputTemplate..'.bin')
+ print(("Wrote a BIN dump to the file %s"):format(foo))
+ local bar = dumplib.SaveAsText(emldata, outputTemplate..'.eml')
+ print(("Wrote a EML dump to the file %s"):format(bar))
+ end
+
+ local uid = block0:sub(1,8)
+ local itemtype = block1:sub(1,4)
+ local cardid = block1:sub(9,24)
+
+ -- Show info
+ print( string.rep('--',20) )
+ print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, toyNames[itemtype]) )
+ print( (' UID : 0x%s'):format(uid) )
+ print( (' CARDID : 0x%s'):format(cardid ) )
+ print( string.rep('--',20) )
+
+end
+main(args)
\ No newline at end of file
--- /dev/null
+local cmds = require('commands')
+local getopt = require('getopt')
+local bin = require('bin')
+local lib14a = require('read14a')
+local utils = require('utils')
+local md5 = require('md5')
+local toyNames = require('default_toys')
+
+example =[[
+ 1. script run tnp3sim
+ 2. script run tnp3sim -m
+ 3. script run tnp3sim -m -i myfile
+]]
+author = "Iceman"
+usage = "script run tnp3sim -h -m -i <filename>"
+desc =[[
+This script will try to load a binary datadump of a Mifare TNP3xxx card.
+It vill try to validate all checksums and view some information stored in the dump
+For an experimental mode, it tries to manipulate some data.
+At last it sends all data to the PM3 device memory where it can be used in the command "hf mf sim"
+
+Arguments:
+ -h : this help
+ -m : Maxed out items (experimental)
+ -i : filename for the datadump to read (bin)
+]]
+
+local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
+local DEBUG = true -- the debug flag
+---
+-- A debug printout-function
+function dbg(args)
+ if not DEBUG then
+ return
+ end
+
+ if type(args) == "table" then
+ local i = 1
+ while result[i] do
+ dbg(result[i])
+ i = i+1
+ end
+ else
+ print("###", args)
+ end
+end
+---
+-- This is only meant to be used when errors occur
+function oops(err)
+ print("ERROR: ",err)
+end
+---
+-- Usage help
+function help()
+ print(desc)
+ print("Example usage")
+ print(example)
+end
+--
+-- Exit message
+function ExitMsg(msg)
+ print( string.rep('--',20) )
+ print( string.rep('--',20) )
+ print(msg)
+ print()
+end
+
+
+local function writedumpfile(infile)
+ t = infile:read("*all")
+ len = string.len(t)
+ local len,hex = bin.unpack(("H%d"):format(len),t)
+ return hex
+end
+-- blocks with data
+-- there are two dataareas, in block 8 or block 36, ( 1==8 ,
+-- checksum type = 0, 1, 2, 3
+local function GetCheckSum(blocks, dataarea, chksumtype)
+
+ local crc
+ local area = 36
+ if dataarea == 1 then
+ area = 8
+ end
+
+ if chksumtype == 0 then
+ crc = blocks[1]:sub(29,32)
+ elseif chksumtype == 1 then
+ crc = blocks[area]:sub(29,32)
+ elseif chksumtype == 2 then
+ crc = blocks[area]:sub(25,28)
+ elseif chksumtype == 3 then
+ crc = blocks[area]:sub(21,24)
+ end
+ return utils.SwapEndianness(crc,16)
+end
+
+local function SetCheckSum(blocks, chksumtype)
+
+ if blocks == nil then return nil, 'Argument \"blocks\" nil' end
+ local newcrc
+ local area1 = 8
+ local area2 = 36
+
+ if chksumtype == 0 then
+ newcrc = ('%04X'):format(CalcCheckSum(blocks,1,0))
+ blocks[1] = blocks[1]:sub(1,28)..newcrc:sub(3,4)..newcrc:sub(1,2)
+ elseif chksumtype == 1 then
+ newcrc = ('%04X'):format(CalcCheckSum(blocks,1,1))
+ blocks[area1] = blocks[area1]:sub(1,28)..newcrc:sub(3,4)..newcrc:sub(1,2)
+ newcrc = ('%04X'):format(CalcCheckSum(blocks,2,1))
+ blocks[area2] = blocks[area2]:sub(1,28)..newcrc:sub(3,4)..newcrc:sub(1,2)
+ elseif chksumtype == 2 then
+ newcrc = ('%04X'):format(CalcCheckSum(blocks,1,2))
+ blocks[area1] = blocks[area1]:sub(1,24)..newcrc:sub(3,4)..newcrc:sub(1,2)..blocks[area1]:sub(29,32)
+ newcrc = ('%04X'):format(CalcCheckSum(blocks,2,2))
+ blocks[area2] = blocks[area2]:sub(1,24)..newcrc:sub(3,4)..newcrc:sub(1,2)..blocks[area2]:sub(29,32)
+ elseif chksumtype == 3 then
+ newcrc = ('%04X'):format(CalcCheckSum(blocks,1,3))
+ blocks[area1] = blocks[area1]:sub(1,20)..newcrc:sub(3,4)..newcrc:sub(1,2)..blocks[area1]:sub(25,32)
+ newcrc = ('%04X'):format(CalcCheckSum(blocks,2,3))
+ blocks[area2] = blocks[area2]:sub(1,20)..newcrc:sub(3,4)..newcrc:sub(1,2)..blocks[area2]:sub(25,32)
+ end
+end
+
+function CalcCheckSum(blocks, dataarea, chksumtype)
+ local area = 36
+ if dataarea == 1 then
+ area = 8
+ end
+
+ if chksumtype == 0 then
+ data = blocks[0]..blocks[1]:sub(1,28)
+ elseif chksumtype == 1 then
+ data = blocks[area]:sub(1,28)..'0500'
+ elseif chksumtype == 2 then
+ data = blocks[area+1]..blocks[area+2]..blocks[area+4]
+ elseif chksumtype == 3 then
+ data = blocks[area+5]..blocks[area+6]..blocks[area+8]..string.rep('00',0xe0)
+ end
+ return utils.Crc16(data)
+end
+
+local function ValidateCheckSums(blocks)
+
+ local isOk, crc, calc
+ -- Checksum Type 0
+ crc = GetCheckSum(blocks,1,0)
+ calc = CalcCheckSum(blocks, 1, 0)
+ if crc == calc then isOk='Ok' else isOk = 'Error' end
+ io.write( ('TYPE 0 : %04x = %04x -- %s\n'):format(crc,calc,isOk))
+
+ -- Checksum Type 1 (DATAAREAHEADER 1)
+ crc = GetCheckSum(blocks,1,1)
+ calc = CalcCheckSum(blocks,1,1)
+ if crc == calc then isOk='Ok' else isOk = 'Error' end
+ io.write( ('TYPE 1 area 1: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+
+ -- Checksum Type 1 (DATAAREAHEADER 2)
+ crc = GetCheckSum(blocks,2,1)
+ calc = CalcCheckSum(blocks,2,1)
+ if crc == calc then isOk='Ok' else isOk = 'Error' end
+ io.write( ('TYPE 1 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+
+ -- Checksum Type 2 (DATAAREA 1)
+ crc = GetCheckSum(blocks,1,2)
+ calc = CalcCheckSum(blocks,1,2)
+ if crc == calc then isOk='Ok' else isOk = 'Error' end
+ io.write( ('TYPE 2 area 1: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+
+ -- Checksum Type 2 (DATAAREA 2)
+ crc = GetCheckSum(blocks,2,2)
+ calc = CalcCheckSum(blocks,2,2)
+ if crc == calc then isOk='Ok' else isOk = 'Error' end
+ io.write( ('TYPE 2 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+
+ -- Checksum Type 3 (DATAAREA 1)
+ crc = GetCheckSum(blocks,1,3)
+ calc = CalcCheckSum(blocks,1,3)
+ if crc == calc then isOk='Ok' else isOk = 'Error' end
+ io.write( ('TYPE 3 area 1: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+
+ -- Checksum Type 3 (DATAAREA 2)
+ crc = GetCheckSum(blocks,2,3)
+ calc = CalcCheckSum(blocks,2,3)
+ if crc == calc then isOk='Ok' else isOk = 'Error' end
+ io.write( ('TYPE 3 area 2: %04x = %04x -- %s\n'):format(crc,calc,isOk))
+end
+
+
+local function LoadEmulator(blocks)
+ local HASHCONSTANT = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20'
+ local cmd
+ local blockdata
+ for _,b in pairs(blocks) do
+
+ blockdata = b
+
+ if _%4 ~= 3 then
+ if (_ >= 8 and _<=21) or (_ >= 36 and _<=49) then
+ local base = ('%s%s%02x%s'):format(blocks[0], blocks[1], _ , HASHCONSTANT)
+ local baseStr = utils.ConvertHexToAscii(base)
+ local key = md5.sumhexa(baseStr)
+ local enc = core.aes(key, blockdata)
+ local hex = utils.ConvertAsciiToBytes(enc)
+ hex = utils.ConvertBytesToHex(hex)
+
+ blockdata = hex
+ io.write( _..',')
+ end
+ end
+
+ cmd = Command:new{cmd = cmds.CMD_MIFARE_EML_MEMSET, arg1 = _ ,arg2 = 1,arg3 = 0, data = blockdata}
+ local err = core.SendCommand(cmd:getBytes())
+ if err then
+ return err
+ end
+ end
+ io.write('\n')
+end
+
+local function main(args)
+
+ print( string.rep('--',20) )
+ print( string.rep('--',20) )
+
+ local result, err, hex
+ local maxed = false
+ local inputTemplate = "dumpdata.bin"
+ local outputTemplate = os.date("toydump_%Y-%m-%d_%H%M");
+
+ -- Arguments for the script
+ for o, a in getopt.getopt(args, 'hmi:o:') do
+ if o == "h" then return help() end
+ if o == "m" then maxed = true end
+ if o == "o" then outputTemplate = a end
+ if o == "i" then inputTemplate = a end
+ end
+
+ -- Turn off Debug
+ local cmdSetDbgOff = "hf mf dbg 0"
+ core.console( cmdSetDbgOff)
+
+ -- Look for tag present on reader,
+ result, err = lib14a.read1443a(false)
+ if not result then return oops(err) end
+
+ core.clearCommandBuffer()
+
+ if 0x01 ~= result.sak then -- NXP MIFARE TNP3xxx
+ return oops('This is not a TNP3xxx tag. aborting.')
+ end
+
+ -- Show tag info
+ print((' Found tag : %s'):format(result.name))
+
+ -- Load dump.bin file
+ print( (' Load data from %s'):format(inputTemplate))
+ hex, err = utils.ReadDumpFile(inputTemplate)
+ if not hex then return oops(err) end
+
+ local blocks = {}
+ local blockindex = 0
+ for i = 1, #hex, 32 do
+ blocks[blockindex] = hex:sub(i,i+31)
+ blockindex = blockindex + 1
+ end
+
+ if DEBUG then
+ print('Validating checksums in the loaded datadump')
+ ValidateCheckSums(blocks)
+ end
+
+ --
+ print( string.rep('--',20) )
+ print(' Gathering info')
+ local uid = blocks[0]:sub(1,8)
+ local itemtype = blocks[1]:sub(1,4)
+ local cardid = blocks[1]:sub(9,24)
+
+ -- Show info
+ print( string.rep('--',20) )
+ print( (' ITEM TYPE : 0x%s - %s'):format(itemtype, toyNames[itemtype]) )
+ print( (' UID : 0x%s'):format(uid) )
+ print( (' CARDID : 0x%s'):format(cardid ) )
+ print( string.rep('--',20) )
+
+ -- lets do something.
+ --
+ local experience = blocks[8]:sub(1,6)
+ print(('Experience : %d'):format(utils.SwapEndianness(experience,24)))
+ local money = blocks[8]:sub(7,10)
+ print(('Money : %d'):format(utils.SwapEndianness(money,16)))
+ local fairy = blocks[9]:sub(1,8)
+ --FD0F = Left, FF0F = Right
+ local path = 'not choosen'
+ if fairy:sub(2,2) == 'D' then
+ path = 'Left'
+ elseif fairy:sub(2,2) == 'F' then
+ path = 'Right'
+ end
+ print(('Fairy : %d [Path: %s] '):format(utils.SwapEndianness(fairy,24),path))
+
+ local hat = blocks[9]:sub(8,11)
+ print(('Hat : %d'):format(utils.SwapEndianness(hat,16)))
+
+ --0x0D 0x29 0x0A 0x02 16-bit hero points value. Maximum 100.
+ local heropoints = blocks[13]:sub(20,23)
+ print(('Hero points : %d'):format(utils.SwapEndianness(heropoints,16)))
+
+ --0x10 0x2C 0x0C 0x04 32 bit flag value indicating heroic challenges completed.
+ local challenges = blocks[16]:sub(25,32)
+ print(('Finished hero challenges : %d'):format(utils.SwapEndianness(challenges,32)))
+
+ if maxed then
+ print('Lets try to max out some values')
+ -- max out money, experience
+ --print (blocks[8])
+ blocks[8] = 'FFFFFF'..'FFFF'..blocks[8]:sub(11,32)
+ blocks[36] = 'FFFFFF'..'FFFF'..blocks[36]:sub(11,32)
+ --print (blocks[8])
+
+ -- max out hero challenges
+ --print (blocks[16])
+ blocks[16] = blocks[16]:sub(1,24)..'FFFFFFFF'
+ blocks[44] = blocks[44]:sub(1,24)..'FFFFFFFF'
+ --print (blocks[16])
+
+ -- max out heropoints
+ --print (blocks[13])
+ blocks[13] = blocks[13]:sub(1,19)..'0064'..blocks[13]:sub(24,32)
+ blocks[41] = blocks[41]:sub(1,19)..'0064'..blocks[41]:sub(24,32)
+ --print (blocks[13])
+
+ -- Update Checksums
+ print('Updating all checksums')
+ SetCheckSum(blocks, 3)
+ SetCheckSum(blocks, 2)
+ SetCheckSum(blocks, 1)
+ SetCheckSum(blocks, 0)
+
+ print('Validating all checksums')
+ ValidateCheckSums(blocks)
+ end
+
+ --Load dumpdata to emulator memory
+ if DEBUG then
+ print('Sending dumpdata to emulator memory')
+ err = LoadEmulator(blocks)
+ if err then return oops(err) end
+ core.clearCommandBuffer()
+ print('The simulation is now prepared.\n --> run \"hf mf sim 5 '..uid..'\" <--')
+ end
+end
+main(args)
\ No newline at end of file
#ifndef _WIN32
#include <termios.h>
#include <sys/ioctl.h>
+
int ukbhit(void)
{
int cnt = 0;
#endif
// log files functions
-void AddLogLine(char *fileName, char *extData, char *c) {
+void AddLogLine(char *file, char *extData, char *c) {
FILE *fLog = NULL;
-
- fLog = fopen(fileName, "a");
+ char filename[FILE_PATH_SIZE] = {0x00};
+ int len = 0;
+
+ len = strlen(file);
+ if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
+ memcpy(filename, file, len);
+
+ fLog = fopen(filename, "a");
if (!fLog) {
- printf("Could not append log file %s", fileName);
+ printf("Could not append log file %s", filename);
return;
}
}
char * sprint_hex(const uint8_t * data, const size_t len) {
+
+ int maxLen = ( len > 1024/3) ? 1024/3 : len;
static char buf[1024];
char * tmp = buf;
size_t i;
- for (i=0; i < len && i < 1024/3; i++, tmp += 3)
+ for (i=0; i < maxLen; ++i, tmp += 3)
sprintf(tmp, "%02x ", data[i]);
return buf;
}
+char * sprint_bin(const uint8_t * data, const size_t len) {
+
+ int maxLen = ( len > 1024) ? 1024 : len;
+ static char buf[1024];
+ char * tmp = buf;
+ size_t i;
+
+ for (i=0; i < maxLen; ++i, ++tmp)
+ sprintf(tmp, "%u", data[i]);
+
+ return buf;
+}
+
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest)
{
while (len--) {
return num;
}
+//assumes little endian
+char * printBits(size_t const size, void const * const ptr)
+{
+ unsigned char *b = (unsigned char*) ptr;
+ unsigned char byte;
+ static char buf[1024];
+ char * tmp = buf;
+ int i, j;
+
+ for (i=size-1;i>=0;i--)
+ {
+ for (j=7;j>=0;j--)
+ {
+ byte = b[i] & (1<<j);
+ byte >>= j;
+ sprintf(tmp, "%u", byte);
+ tmp++;
+ }
+ }
+ return buf;
+}
+
// -------------------------------------------------------------------------
// string parameters lib
// -------------------------------------------------------------------------
return en - bg + 1;
}
+
+/*
+The following methods comes from Rfidler sourcecode.
+https://github.com/ApertureLabsLtd/RFIDler/blob/master/firmware/Pic32/RFIDler.X/src/
+*/
+
+// convert hex to sequence of 0/1 bit values
+// returns number of bits converted
+int hextobinarray(char *target, char *source)
+{
+ int length, i, count= 0;
+ char x;
+
+ length = strlen(source);
+ // process 4 bits (1 hex digit) at a time
+ while(length--)
+ {
+ x= *(source++);
+ // capitalize
+ if (x >= 'a' && x <= 'f')
+ x -= 32;
+ // convert to numeric value
+ if (x >= '0' && x <= '9')
+ x -= '0';
+ else if (x >= 'A' && x <= 'F')
+ x -= 'A' - 10;
+ else
+ return 0;
+ // output
+ for(i= 0 ; i < 4 ; ++i, ++count)
+ *(target++)= (x >> (3 - i)) & 1;
+ }
+
+ return count;
+}
+
+// convert hex to human readable binary string
+int hextobinstring(char *target, char *source)
+{
+ int length;
+
+ if(!(length= hextobinarray(target, source)))
+ return 0;
+ binarraytobinstring(target, target, length);
+ return length;
+}
+
+// convert binary array of 0x00/0x01 values to hex (safe to do in place as target will always be shorter than source)
+// return number of bits converted
+int binarraytohex(char *target, char *source, int length)
+{
+ unsigned char i, x;
+ int j = length;
+
+ if(j % 4)
+ return 0;
+
+ while(j)
+ {
+ for(i= x= 0 ; i < 4 ; ++i)
+ x += ( source[i] << (3 - i));
+ sprintf(target,"%X", x);
+ ++target;
+ source += 4;
+ j -= 4;
+ }
+ return length;
+}
+
+// convert binary array to human readable binary
+void binarraytobinstring(char *target, char *source, int length)
+{
+ int i;
+
+ for(i= 0 ; i < length ; ++i)
+ *(target++)= *(source++) + '0';
+ *target= '\0';
+}
+
+// return parity bit required to match type
+uint8_t GetParity( char *bits, uint8_t type, int length)
+{
+ int x;
+
+ for(x= 0 ; length > 0 ; --length)
+ x += bits[length - 1];
+ x %= 2;
+
+ return x ^ type;
+}
+
+// add HID parity to binary array: EVEN prefix for 1st half of ID, ODD suffix for 2nd half
+void wiegand_add_parity(char *target, char *source, char length)
+{
+ *(target++)= GetParity(source, EVEN, length / 2);
+ memcpy(target, source, length);
+ target += length;
+ *(target)= GetParity(source + length / 2, ODD, length / 2);
+}
#include <string.h>
#include <ctype.h>
#include <time.h>
+#include "data.h"
#ifndef MIN
# define MIN(a, b) (((a) < (b)) ? (a) : (b))
#ifndef MAX
# define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
+#define TRUE 1
+#define FALSE 0
+#define EVEN 0
+#define ODD 1
int ukbhit(void);
void print_hex(const uint8_t * data, const size_t len);
char * sprint_hex(const uint8_t * data, const size_t len);
+char * sprint_bin(const uint8_t * data, const size_t len);
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
uint64_t bytes_to_num(uint8_t* src, size_t len);
+char * printBits(size_t const size, void const * const ptr);
char param_getchar(const char *line, int paramnum);
uint8_t param_get8(const char *line, int paramnum);
int param_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt);
int param_getstr(const char *line, int paramnum, char * str);
+ int hextobinarray( char *target, char *source);
+ int hextobinstring( char *target, char *source);
+ int binarraytohex( char *target, char *source, int length);
+void binarraytobinstring(char *target, char *source, int length);
+uint8_t GetParity( char *string, uint8_t type, int length);
+void wiegand_add_parity(char *target, char *source, char length);
+
MOVE=ren
COPY=copy
PATHSEP=\\#
-FLASH_TOOL=winsrc\\prox.exe
+#FLASH_TOOL=winsrc\\prox.exe
+FLASH_TOOL=winsrc\\flash.exe
DETECTED_OS=Windows
endif
CFLAGS = -c $(INCLUDE) -Wall -Werror -pedantic -std=c99 $(APP_CFLAGS) -Os
LDFLAGS = -nostartfiles -nodefaultlibs -Wl,-gc-sections -n
+
LIBS = -lgcc
THUMBOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(THUMBSRC))
#include "string.h"\r
#include "proxmark3.h"\r
\r
-//static UsbCommand txcmd;\r
-\r
bool cmd_receive(UsbCommand* cmd) {\r
\r
// Check if there is a usb packet available\r
#include "crc16.h"
+
unsigned short update_crc16( unsigned short crc, unsigned char c )
{
unsigned short i, v, tcrc = 0;
return ((crc >> 8) ^ tcrc)&0xffff;
}
+
+uint16_t crc16(uint8_t const *message, int length, uint16_t remainder, uint16_t polynomial) {
+
+ if (length == 0)
+ return (~remainder);
+
+ for (int byte = 0; byte < length; ++byte) {
+ remainder ^= (message[byte] << 8);
+ for (uint8_t bit = 8; bit > 0; --bit) {
+ if (remainder & 0x8000) {
+ remainder = (remainder << 1) ^ polynomial;
+ } else {
+ remainder = (remainder << 1);
+ }
+ }
+ }
+ return remainder;
+}
+
+uint16_t crc16_ccitt(uint8_t const *message, int length) {
+ return crc16(message, length, 0xffff, 0x1021);
+}
//-----------------------------------------------------------------------------
// CRC16
//-----------------------------------------------------------------------------
+#include <stdint.h>
#ifndef __CRC16_H
#define __CRC16_H
-
unsigned short update_crc16(unsigned short crc, unsigned char c);
-
+uint16_t crc16(uint8_t const *message, int length, uint16_t remainder, uint16_t polynomial);
+uint16_t crc16_ccitt(uint8_t const *message, int length);
#endif
--- /dev/null
+#include <stdint.h>
+#include <stddef.h>
+#include "crc32.h"
+
+#define htole32(x) (x)
+#define CRC32_PRESET 0xFFFFFFFF
+
+
+static void crc32_byte (uint32_t *crc, const uint8_t value);
+
+static void crc32_byte (uint32_t *crc, const uint8_t value) {
+ /* x32 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1 */
+ const uint32_t poly = 0xEDB88320;
+
+ *crc ^= value;
+ for (int current_bit = 7; current_bit >= 0; current_bit--) {
+ int bit_out = (*crc) & 0x00000001;
+ *crc >>= 1;
+ if (bit_out)
+ *crc ^= poly;
+ }
+}
+
+void crc32 (const uint8_t *data, const size_t len, uint8_t *crc) {
+ uint32_t desfire_crc = CRC32_PRESET;
+ for (size_t i = 0; i < len; i++) {
+ crc32_byte (&desfire_crc, data[i]);
+ }
+
+ *((uint32_t *)(crc)) = htole32 (desfire_crc);
+}
+
+void crc32_append (uint8_t *data, const size_t len) {
+ crc32 (data, len, data + len);
+}
--- /dev/null
+//-----------------------------------------------------------------------------
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
+// CRC32
+//-----------------------------------------------------------------------------
+
+#ifndef __CRC32_H
+#define __CRC32_H
+
+void crc32 (const uint8_t *data, const size_t len, uint8_t *crc);
+void crc32_append (uint8_t *data, const size_t len);
+
+#endif
void usb_disable() {\r
// Disconnect the USB device\r
AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU;\r
-// SpinDelay(100);\r
\r
// Clear all lingering interrupts\r
if(pUdp->UDP_ISR & AT91C_UDP_ENDBUSRES) {\r
\r
// Wait for a short while\r
for (volatile size_t i=0; i<0x100000; i++);\r
-// SpinDelay(100);\r
\r
// Reconnect USB reconnect\r
AT91C_BASE_PIOA->PIO_SODR = GPIO_USB_PU;\r
uint32_t packetSize, nbBytesRcv = 0;\r
uint32_t time_out = 0;\r
\r
- while (len)\r
- {\r
+ while (len) {\r
if (!usb_check()) break;\r
\r
if ( pUdp->UDP_CSR[AT91C_EP_OUT] & bank ) {\r
while(packetSize--)\r
data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT];\r
pUdp->UDP_CSR[AT91C_EP_OUT] &= ~(bank);\r
- if (bank == AT91C_UDP_RX_DATA_BK0)\r
- {\r
+ if (bank == AT91C_UDP_RX_DATA_BK0) {\r
bank = AT91C_UDP_RX_DATA_BK1;\r
} else {\r
bank = AT91C_UDP_RX_DATA_BK0;\r