Merge remote-tracking branch 'upstream/master'

Conflicts:
	client/cmdlf.c
This commit is contained in:
marshmellow42
2015-01-13 16:02:23 -05:00
54 changed files with 8139 additions and 2647 deletions
+1 -1
View File
@@ -802,7 +802,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
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);
+1 -1
View File
@@ -177,7 +177,7 @@ void ReaderMifare(bool first_try);
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);
+2 -2
View File
@@ -744,7 +744,7 @@ void SnoopHitag(uint32_t type) {
// 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();
@@ -968,7 +968,7 @@ void SimulateHitagTag(bool tag_mem_supplied, byte_t* data) {
// 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();
+1 -1
View File
@@ -1812,7 +1812,7 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, u
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
+1319 -1319
View File
File diff suppressed because it is too large Load Diff
+82 -92
View File
@@ -15,6 +15,7 @@
#include "mifarecmd.h"
#include "apps.h"
#include "util.h"
//-----------------------------------------------------------------------------
// Select, Authenticate, Read a MIFARE tag.
@@ -86,48 +87,40 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
void MifareUReadBlock(uint8_t arg0,uint8_t *datain)
{
// params
uint8_t blockNo = arg0;
// variables
byte_t isOK = 0;
byte_t dataoutbuf[16];
uint8_t uid[10];
byte_t dataout[16] = {0x00};
uint8_t uid[10] = {0x00};
uint32_t cuid;
// clear trace
iso14a_clear_trace();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
while (true) {
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
break;
iso14a_clear_trace();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
int len = iso14443a_select_card(uid, NULL, &cuid);
if(!len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
//OnError(1);
return;
};
if(mifare_ultra_readblock(cuid, blockNo, dataoutbuf)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Read block error");
break;
len = mifare_ultra_readblock(cuid, blockNo, dataout);
if(len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error");
//OnError(2);
return;
};
if(mifare_ultra_halt(cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
break;
len = mifare_ultra_halt(cuid);
if(len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error");
//OnError(3);
return;
};
isOK = 1;
break;
}
if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED");
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);
LED_B_OFF();
cmd_send(CMD_ACK,1,0,0,dataout,16);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
@@ -200,58 +193,70 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
LEDsoff();
}
void MifareUReadCard(uint8_t arg0, uint8_t *datain)
void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain)
{
// params
uint8_t sectorNo = arg0;
// variables
byte_t isOK = 0;
byte_t dataoutbuf[16 * 4];
uint8_t uid[10];
uint32_t cuid;
int Pages = arg1;
int count_Pages = 0;
byte_t dataout[176] = {0x00};;
uint8_t uid[10] = {0x00};
uint32_t cuid;
// clear trace
iso14a_clear_trace();
// iso14a_set_tracing(false);
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
if (MF_DBGLEVEL >= MF_DBG_ALL)
Dbprintf("Pages %d",Pages);
iso14a_clear_trace();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
int len = iso14443a_select_card(uid, NULL, &cuid);
if (!len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Can't select card");
//OnError(1);
return;
}
for (int i = 0; i < Pages; i++){
len = mifare_ultra_readblock(cuid, sectorNo * 4 + i, dataout + 4 * i);
if (len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Read block %d error",i);
//OnError(2);
return;
} else {
count_Pages++;
}
}
len = mifare_ultra_halt(cuid);
if (len) {
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("Halt error");
//OnError(3);
return;
}
if (MF_DBGLEVEL >= MF_DBG_ALL) {
Dbprintf("Pages read %d", count_Pages);
}
while (true) {
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
break;
};
for(int sec=0;sec<16;sec++){
if(mifare_ultra_readblock(cuid, sectorNo * 4 + sec, dataoutbuf + 4 * sec)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Read block %d error",sec);
break;
};
}
if(mifare_ultra_halt(cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
break;
};
isOK = 1;
break;
}
if (MF_DBGLEVEL >= 2) DbpString("READ CARD FINISHED");
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,64);
LED_B_OFF();
// Thats it...
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
len = 16*4; //64 bytes
// Read a UL-C
if (Pages == 44 && count_Pages > 16)
len = 176;
cmd_send(CMD_ACK, 1, 0, 0, dataout, len);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
@@ -331,19 +336,16 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)
{
// params
uint8_t blockNo = arg0;
byte_t blockdata[16];
byte_t blockdata[16] = {0x00};
memset(blockdata,'\0',16);
memcpy(blockdata, datain,16);
// variables
byte_t isOK = 0;
uint8_t uid[10];
uint8_t uid[10] = {0x00};
uint32_t cuid;
// clear trace
iso14a_clear_trace();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
LED_A_ON();
@@ -372,33 +374,25 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,0,0);
LED_B_OFF();
// Thats it...
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
// iso14a_set_tracing(TRUE);
}
void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)
{
// params
uint8_t blockNo = arg0;
byte_t blockdata[4];
byte_t blockdata[4] = {0x00};
memcpy(blockdata, datain,4);
// variables
byte_t isOK = 0;
uint8_t uid[10];
uint8_t uid[10] = {0x00};
uint32_t cuid;
// clear trace
iso14a_clear_trace();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
LED_A_ON();
@@ -427,11 +421,7 @@ void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)
if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
LED_B_ON();
cmd_send(CMD_ACK,isOK,0,0,0,0);
LED_B_OFF();
// Thats it...
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
}
+19 -20
View File
@@ -149,7 +149,7 @@ int mifare_sendcmd_shortex(struct Crypto1State *pcs, uint8_t crypted, uint8_t cm
return len;
}
// mifare commands
// mifare classic commands
int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested)
{
return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL);
@@ -280,10 +280,8 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
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();
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
@@ -291,18 +289,21 @@ int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
// 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)
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)
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)
Dbprintf("Cmd CRC response error.");
return 3;
}
@@ -360,10 +361,9 @@ int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
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();
uint8_t* receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE;
@@ -371,45 +371,43 @@ int mifare_ultra_writeblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData)
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)
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)
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();
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)
Dbprintf("Cmd Send Error: %02x %d", receivedAnswer[0],len);
return 1;
}
return 0;
@@ -423,7 +421,8 @@ int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
len = mifare_sendcmd_short(pcs, pcs == NULL ? false: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)
Dbprintf("halt error. response len: %x", len);
return 1;
}
@@ -438,10 +437,10 @@ int mifare_ultra_halt(uint32_t uid)
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)
Dbprintf("halt error. response len: %x", len);
return 1;
}
return 0;
}
+5
View File
@@ -48,6 +48,11 @@ int memcmp(const void *av, const void *bv, int len)
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;
+1
View File
@@ -19,6 +19,7 @@ int strlen(const char *str);
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[]);
+40
View File
@@ -13,6 +13,26 @@
#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);
}
@@ -45,6 +65,26 @@ uint64_t bytes_to_num(uint8_t* src, size_t len)
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();
+4
View File
@@ -27,10 +27,14 @@
#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);
-19
View File
@@ -103,13 +103,11 @@ void UsbPacketReceived(uint8_t *packet, int len) {
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;
@@ -125,10 +123,8 @@ void UsbPacketReceived(uint8_t *packet, int len) {
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];
}
@@ -138,8 +134,6 @@ void UsbPacketReceived(uint8_t *packet, int len) {
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;
@@ -147,7 +141,6 @@ void UsbPacketReceived(uint8_t *packet, int len) {
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
@@ -155,15 +148,12 @@ void UsbPacketReceived(uint8_t *packet, int len) {
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;
@@ -189,8 +179,6 @@ void UsbPacketReceived(uint8_t *packet, int len) {
} 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);
}
}
@@ -202,8 +190,6 @@ void UsbPacketReceived(uint8_t *packet, int len) {
}
if(!dont_ack) {
// c->cmd = CMD_ACK;
// UsbSendPacket(packet, len);
cmd_send(CMD_ACK,arg0,0,0,0,0);
}
}
@@ -219,23 +205,18 @@ static void flash_mode(int externally_entered)
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;
+3 -2
View File
@@ -13,9 +13,9 @@ CXX=g++
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)))
@@ -94,6 +94,7 @@ CMDSRCS = nonce2key/crapto1.c\
scripting.c\
cmdscript.c\
pm3_bitlib.c\
aes.c\
COREOBJS = $(CORESRCS:%.c=$(OBJDIR)/%.o)
+1454
View File
File diff suppressed because it is too large Load Diff
+257
View File
@@ -0,0 +1,257 @@
/**
* \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 */
+931 -916
View File
File diff suppressed because it is too large Load Diff
+5 -5
View File
@@ -342,8 +342,7 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool sho
// 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);
}
@@ -363,7 +362,6 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool sho
}
}
}
}
char *crc = crcError ? "!crc" :" ";
@@ -371,8 +369,10 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, bool iclass, bool sho
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;
+151 -15
View File
@@ -27,6 +27,102 @@
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");
@@ -65,6 +161,12 @@ int CmdHF14AReader(const char *Cmd)
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;
@@ -83,7 +185,6 @@ int CmdHF14AReader(const char *Cmd)
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
@@ -98,13 +199,6 @@ int CmdHF14AReader(const char *Cmd)
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;
@@ -243,6 +337,24 @@ int CmdHF14AReader(const char *Cmd)
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;
}
@@ -397,19 +509,22 @@ int CmdHF14ACmdRaw(const char *cmd) {
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;
}
@@ -442,6 +557,14 @@ int CmdHF14ACmdRaw(const char *cmd) {
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;
@@ -459,15 +582,19 @@ int CmdHF14ACmdRaw(const char *cmd) {
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);
@@ -481,13 +608,22 @@ int CmdHF14ACmdRaw(const char *cmd) {
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);
@@ -507,7 +643,7 @@ static void waitCmd(uint8_t iSelect)
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);
+1
View File
@@ -20,4 +20,5 @@ int CmdHF14AReader(const char *Cmd);
int CmdHF14ASim(const char *Cmd);
int CmdHF14ASnoop(const char *Cmd);
char* getTagInfo(uint8_t uid);
#endif
+22 -16
View File
@@ -23,7 +23,6 @@
#include "cmdhf14b.h"
#include "cmdmain.h"
static int CmdHelp(const char *Cmd);
int CmdHF14BDemod(const char *Cmd)
@@ -146,7 +145,7 @@ demodError:
int CmdHF14BList(const char *Cmd)
{
uint8_t got[960];
uint8_t got[TRACE_BUFFER_SIZE];
GetFromBigBuf(got,sizeof(got),0);
WaitForResponse(CMD_ACK,NULL);
@@ -158,9 +157,8 @@ int CmdHF14BList(const char *Cmd)
int prev = -1;
for(;;) {
if(i >= 900) {
break;
}
if(i >= TRACE_BUFFER_SIZE) { break; }
bool isResponse;
int timestamp = *((uint32_t *)(got+i));
@@ -177,7 +175,7 @@ int CmdHF14BList(const char *Cmd)
if(len > 100) {
break;
}
if(i + len >= 900) {
if(i + len >= TRACE_BUFFER_SIZE) {
break;
}
@@ -406,20 +404,27 @@ int CmdHF14BWrite( const char *Cmd){
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 ){
@@ -439,11 +444,12 @@ int CmdHF14BWrite( const char *Cmd){
}
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;
}

Some files were not shown because too many files have changed in this diff Show More