mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 13:00:42 -07:00
CHG: a major remake of the "hf mf c*" commands. Ie chinese magic tags. Tried to make them consistent in parameter calls and simplified. And fixed the annoying gen1 tags that answers with a ACK/NACK on HALT commands..
This commit is contained in:
parent
bb9796ba26
commit
c2731f37be
13 changed files with 344 additions and 426 deletions
2
Makefile
2
Makefile
|
@ -22,7 +22,7 @@ help:
|
||||||
@echo + all - Make bootrom, armsrc and the OS-specific host directory
|
@echo + all - Make bootrom, armsrc and the OS-specific host directory
|
||||||
@echo + client - Make only the OS-specific host directory
|
@echo + client - Make only the OS-specific host directory
|
||||||
@echo + flash-bootrom - Make bootrom and flash it
|
@echo + flash-bootrom - Make bootrom and flash it
|
||||||
@echo + flash-os - Make armsrc and flash os (includes fpga)
|
@echo + flash-os - Make armsrc and flash os \(includes fpga\)
|
||||||
@echo + flash-all - Make bootrom and armsrc and flash bootrom and os image
|
@echo + flash-all - Make bootrom and armsrc and flash bootrom and os image
|
||||||
@echo + clean - Clean in bootrom, armsrc and the OS-specific host directory
|
@echo + clean - Clean in bootrom, armsrc and the OS-specific host directory
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
// Craig Young - 14a stand-alone code
|
// Craig Young - 14a stand-alone code
|
||||||
#ifdef WITH_ISO14443a_StandAlone
|
#ifdef WITH_ISO14443a_StandAlone
|
||||||
#include "iso14443a.h"
|
#include "iso14443a.h"
|
||||||
|
#include "protocols.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define abs(x) ( ((x)<0) ? -(x) : (x) )
|
#define abs(x) ( ((x)<0) ? -(x) : (x) )
|
||||||
|
@ -387,6 +388,8 @@ void StandAloneMode14a()
|
||||||
uint32_t uid_tmp2 = 0;
|
uint32_t uid_tmp2 = 0;
|
||||||
iso14a_card_select_t hi14a_card[OPTS];
|
iso14a_card_select_t hi14a_card[OPTS];
|
||||||
|
|
||||||
|
uint8_t params = (MAGIC_SINGLE | MAGIC_DATAIN);
|
||||||
|
|
||||||
LED(selected + 1, 0);
|
LED(selected + 1, 0);
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
|
@ -484,36 +487,34 @@ void StandAloneMode14a()
|
||||||
LED(selected + 1, 0);
|
LED(selected + 1, 0);
|
||||||
LED(LED_ORANGE, 250);
|
LED(LED_ORANGE, 250);
|
||||||
|
|
||||||
|
|
||||||
// record
|
// record
|
||||||
Dbprintf("Preparing to Clone card [Bank: %x]; uid: %08x", selected, uid_1st[selected]);
|
Dbprintf("Preparing to Clone card [Bank: %x]; uid: %08x", selected, uid_1st[selected]);
|
||||||
|
|
||||||
// wait for button to be released
|
// wait for button to be released
|
||||||
while(BUTTON_PRESS())
|
|
||||||
{
|
|
||||||
// Delay cloning until card is in place
|
// Delay cloning until card is in place
|
||||||
|
while(BUTTON_PRESS())
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
}
|
|
||||||
Dbprintf("Starting clone. [Bank: %u]", selected);
|
Dbprintf("Starting clone. [Bank: %u]", selected);
|
||||||
// need this delay to prevent catching some weird data
|
// need this delay to prevent catching some weird data
|
||||||
SpinDelay(500);
|
SpinDelay(500);
|
||||||
// Begin clone function here:
|
// Begin clone function here:
|
||||||
/* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards:
|
/* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards:
|
||||||
UsbCommand c = {CMD_MIFARE_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}};
|
UsbCommand c = {CMD_MIFARE_CSETBLOCK, {params & (0xFE | (uid == NULL ? 0:1)), blockNo, 0}};
|
||||||
memcpy(c.d.asBytes, data, 16);
|
memcpy(c.d.asBytes, data, 16);
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
|
|
||||||
Block read is similar:
|
Block read is similar:
|
||||||
UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, 0, blockNo}};
|
UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, blockNo, 0}};
|
||||||
We need to imitate that call with blockNo 0 to set a uid.
|
We need to imitate that call with blockNo 0 to set a uid.
|
||||||
|
|
||||||
The get and set commands are handled in this file:
|
The get and set commands are handled in this file:
|
||||||
// Work with "magic Chinese" card
|
// Work with "magic Chinese" card
|
||||||
case CMD_MIFARE_CSETBLOCK:
|
case CMD_MIFARE_CSETBLOCK:
|
||||||
MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
|
MifareCSetBlock(c->arg[0], c->arg[1], c->d.asBytes);
|
||||||
break;
|
break;
|
||||||
case CMD_MIFARE_CGETBLOCK:
|
case CMD_MIFARE_CGETBLOCK:
|
||||||
MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
|
MifareCGetBlock(c->arg[0], c->arg[1], c->d.asBytes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
mfCSetUID provides example logic for UID set workflow:
|
mfCSetUID provides example logic for UID set workflow:
|
||||||
|
@ -523,11 +524,11 @@ void StandAloneMode14a()
|
||||||
// Mifare UID BCC
|
// Mifare UID BCC
|
||||||
block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // BCC on byte 5
|
block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // BCC on byte 5
|
||||||
Bytes 5-7 are reserved SAK and ATQA for mifare classic
|
Bytes 5-7 are reserved SAK and ATQA for mifare classic
|
||||||
-Use mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER) to write it
|
-Use mfCSetBlock(0, block0, oldUID, wantWipe, MAGIC_SINGLE) to write it
|
||||||
*/
|
*/
|
||||||
uint8_t oldBlock0[16] = {0}, newBlock0[16] = {0}, testBlock0[16] = {0};
|
uint8_t oldBlock0[16] = {0}, newBlock0[16] = {0}, testBlock0[16] = {0};
|
||||||
// arg0 = Flags == CSETBLOCK_SINGLE_OPER=0x1F, arg1=returnSlot, arg2=blockNo
|
// arg0 = Flags, arg1=blockNo
|
||||||
MifareCGetBlock(0x3F, 1, 0, oldBlock0);
|
MifareCGetBlock(params, 0, oldBlock0);
|
||||||
if (oldBlock0[0] == 0 && oldBlock0[0] == oldBlock0[1] && oldBlock0[1] == oldBlock0[2] && oldBlock0[2] == oldBlock0[3]) {
|
if (oldBlock0[0] == 0 && oldBlock0[0] == oldBlock0[1] && oldBlock0[1] == oldBlock0[2] && oldBlock0[2] == oldBlock0[3]) {
|
||||||
Dbprintf("No changeable tag detected. Returning to replay mode for bank[%d]", selected);
|
Dbprintf("No changeable tag detected. Returning to replay mode for bank[%d]", selected);
|
||||||
playing = 1;
|
playing = 1;
|
||||||
|
@ -542,25 +543,24 @@ void StandAloneMode14a()
|
||||||
newBlock0[2] = 0xFF & (uid_1st[selected]>>8);
|
newBlock0[2] = 0xFF & (uid_1st[selected]>>8);
|
||||||
newBlock0[3] = 0xFF & (uid_1st[selected]);
|
newBlock0[3] = 0xFF & (uid_1st[selected]);
|
||||||
newBlock0[4] = newBlock0[0]^newBlock0[1]^newBlock0[2]^newBlock0[3];
|
newBlock0[4] = newBlock0[0]^newBlock0[1]^newBlock0[2]^newBlock0[3];
|
||||||
// arg0 = needWipe, arg1 = workFlags, arg2 = blockNo, datain
|
|
||||||
MifareCSetBlock(0, 0xFF,0, newBlock0);
|
// arg0 = workFlags, arg1 = blockNo, datain
|
||||||
MifareCGetBlock(0x3F, 1, 0, testBlock0);
|
MifareCSetBlock(params, 0, newBlock0);
|
||||||
if (memcmp(testBlock0,newBlock0,16)==0)
|
MifareCGetBlock(params, 0, testBlock0);
|
||||||
{
|
|
||||||
|
if (memcmp(testBlock0, newBlock0, 16)==0) {
|
||||||
DbpString("Cloned successfull!");
|
DbpString("Cloned successfull!");
|
||||||
cardRead[selected] = 0; // Only if the card was cloned successfully should we clear it
|
cardRead[selected] = 0; // Only if the card was cloned successfully should we clear it
|
||||||
playing = 0;
|
playing = 0;
|
||||||
iGotoRecord = 1;
|
iGotoRecord = 1;
|
||||||
selected = (selected + 1) % OPTS;
|
selected = (selected + 1) % OPTS;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
Dbprintf("Clone failed. Back to replay mode on bank[%d]", selected);
|
Dbprintf("Clone failed. Back to replay mode on bank[%d]", selected);
|
||||||
playing = 1;
|
playing = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
LED(selected + 1, 0);
|
LED(selected + 1, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
// Change where to record (or begin playing)
|
// Change where to record (or begin playing)
|
||||||
else if (playing==1) // button_pressed == BUTTON_SINGLE_CLICK && cardRead[selected])
|
else if (playing==1) // button_pressed == BUTTON_SINGLE_CLICK && cardRead[selected])
|
||||||
|
@ -1162,10 +1162,10 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
|
|
||||||
// Work with "magic Chinese" card
|
// Work with "magic Chinese" card
|
||||||
case CMD_MIFARE_CSETBLOCK:
|
case CMD_MIFARE_CSETBLOCK:
|
||||||
MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
|
MifareCSetBlock(c->arg[0], c->arg[1], c->d.asBytes);
|
||||||
break;
|
break;
|
||||||
case CMD_MIFARE_CGETBLOCK:
|
case CMD_MIFARE_CGETBLOCK:
|
||||||
MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
|
MifareCGetBlock(c->arg[0], c->arg[1], c->d.asBytes);
|
||||||
break;
|
break;
|
||||||
case CMD_MIFARE_CIDENT:
|
case CMD_MIFARE_CIDENT:
|
||||||
MifareCIdent();
|
MifareCIdent();
|
||||||
|
@ -1196,7 +1196,6 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_MIFARE_COLLECT_NONCES:
|
case CMD_MIFARE_COLLECT_NONCES:
|
||||||
MifareCollectNonces(c->arg[0], c->arg[1]);
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -139,11 +139,12 @@ void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
|
||||||
void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
||||||
void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
||||||
void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
||||||
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); // Work with "magic Chinese" card
|
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); // Work with "magic Chinese" card
|
||||||
void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain);
|
||||||
void MifareCIdent(); // is "magic chinese" card?
|
void MifareCIdent(); // is "magic chinese" card?
|
||||||
void MifareUSetPwd(uint8_t arg0, uint8_t *datain);
|
void MifareUSetPwd(uint8_t arg0, uint8_t *datain);
|
||||||
|
void OnSuccessMagic();
|
||||||
|
void OnErrorMagic(uint8_t reason);
|
||||||
void MifareCollectNonces(uint32_t arg0, uint32_t arg1);
|
void MifareCollectNonces(uint32_t arg0, uint32_t arg1);
|
||||||
|
|
||||||
//desfire
|
//desfire
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "apps.h"
|
#include "apps.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "crc.h"
|
#include "crc.h"
|
||||||
|
#include "protocols.h"
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Select, Authenticate, Read a MIFARE tag.
|
// Select, Authenticate, Read a MIFARE tag.
|
||||||
|
@ -1010,224 +1011,176 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Work with "magic Chinese" card (email him: ouyangweidaxian@live.cn)
|
// Work with "magic Chinese" card (email him: ouyangweidaxian@live.cn)
|
||||||
//
|
//
|
||||||
|
// PARAMS - workFlags
|
||||||
|
// bit 0 - need get UID
|
||||||
|
// bit 1 - need wupC
|
||||||
|
// bit 2 - need HALT after sequence
|
||||||
|
// bit 3 - need turn on FPGA before sequence
|
||||||
|
// bit 4 - need turn off FPGA
|
||||||
|
// bit 5 - need to set datain instead of issuing USB reply (called via ARM for StandAloneMode14a)
|
||||||
|
// bit 6 - wipe tag.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){
|
// magic uid card generation 1 commands
|
||||||
|
uint8_t wupC1[] = { MIFARE_MAGICWUPC1 };
|
||||||
|
uint8_t wupC2[] = { MIFARE_MAGICWUPC2 };
|
||||||
|
uint8_t wipeC[] = { MIFARE_MAGICWIPEC };
|
||||||
|
|
||||||
|
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){
|
||||||
|
|
||||||
// params
|
// params
|
||||||
uint8_t needWipe = arg0;
|
uint8_t workFlags = arg0;
|
||||||
// bit 0 - need get UID
|
uint8_t blockNo = arg1;
|
||||||
// bit 1 - need wupC
|
|
||||||
// bit 2 - need HALT after sequence
|
|
||||||
// bit 3 - need init FPGA and field before sequence
|
|
||||||
// bit 4 - need reset FPGA and LED
|
|
||||||
uint8_t workFlags = arg1;
|
|
||||||
uint8_t blockNo = arg2;
|
|
||||||
|
|
||||||
// card commands
|
Dbprintf("ICE :: CSetBlocks Flags %02x", workFlags);
|
||||||
uint8_t wupC1[] = { 0x40 };
|
|
||||||
uint8_t wupC2[] = { 0x43 };
|
|
||||||
uint8_t wipeC[] = { 0x41 };
|
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
byte_t isOK = 0;
|
|
||||||
uint8_t uid[10] = {0x00};
|
uint8_t uid[10] = {0x00};
|
||||||
uint8_t d_block[18] = {0x00};
|
uint8_t data[18] = {0x00};
|
||||||
uint32_t cuid;
|
uint32_t cuid;
|
||||||
|
|
||||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
// reset FPGA and LED
|
if (workFlags & MAGIC_INIT) {
|
||||||
if (workFlags & 0x08) {
|
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
LED_C_OFF();
|
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(TRUE);
|
set_tracing(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
// read UID and return to client
|
||||||
|
if (workFlags & MAGIC_UID) {
|
||||||
// get UID from chip
|
|
||||||
if (workFlags & 0x01) {
|
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
if(!iso14443a_select_card(uid, NULL, &cuid)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
|
||||||
//break;
|
OnErrorMagic(MAGIC_UID);
|
||||||
};
|
|
||||||
|
|
||||||
if(mifare_classic_halt(NULL, cuid)) {
|
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
|
|
||||||
//break;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// reset chip
|
// wipe tag, fill it with zeros
|
||||||
if (needWipe){
|
if (workFlags & MAGIC_WIPE){
|
||||||
ReaderTransmitBitsPar(wupC1,7,0, NULL);
|
ReaderTransmitBitsPar(wupC1,7,0, NULL);
|
||||||
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC1 error");
|
||||||
break;
|
OnErrorMagic(MAGIC_WIPE);
|
||||||
};
|
};
|
||||||
|
|
||||||
ReaderTransmit(wipeC, sizeof(wipeC), NULL);
|
ReaderTransmit(wipeC, sizeof(wipeC), NULL);
|
||||||
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("wipeC error");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wipeC error");
|
||||||
break;
|
OnErrorMagic(MAGIC_WIPE);
|
||||||
};
|
|
||||||
|
|
||||||
if(mifare_classic_halt(NULL, cuid)) {
|
|
||||||
if (MF_DBGLEVEL >= 4) Dbprintf("INFO - Tag answered the 'Halt' command");
|
|
||||||
break;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
// write block
|
// write block
|
||||||
if (workFlags & 0x02) {
|
if (workFlags & MAGIC_WUPC) {
|
||||||
ReaderTransmitBitsPar(wupC1,7,0, NULL);
|
ReaderTransmitBitsPar(wupC1,7,0, NULL);
|
||||||
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC1 error");
|
||||||
break;
|
OnErrorMagic(MAGIC_WUPC);
|
||||||
};
|
};
|
||||||
|
|
||||||
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
|
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
|
||||||
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC2 error");
|
||||||
break;
|
OnErrorMagic(MAGIC_WUPC);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {
|
if ((mifare_sendcmd_short(NULL, 0, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("write block send command error");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("write block send command error");
|
||||||
break;
|
OnErrorMagic(4);
|
||||||
};
|
};
|
||||||
|
|
||||||
memcpy(d_block, datain, 16);
|
memcpy(data, datain, sizeof(data));
|
||||||
AppendCrc14443a(d_block, 16);
|
AppendCrc14443a(data, sizeof(data));
|
||||||
|
|
||||||
ReaderTransmit(d_block, sizeof(d_block), NULL);
|
ReaderTransmit(data, sizeof(data), NULL);
|
||||||
if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {
|
if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("write block send data error");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("write block send data error");
|
||||||
break;
|
OnErrorMagic(0);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (workFlags & 0x04) {
|
if (workFlags & MAGIC_OFF)
|
||||||
if (mifare_classic_halt(NULL, cuid)) {
|
mifare_classic_halt_ex(NULL);
|
||||||
if (MF_DBGLEVEL >= 4) Dbprintf("INFO - Tag answered the 'Halt' command");
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
isOK = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
cmd_send(CMD_ACK,isOK,0,0,uid,4);
|
// check if uid is cuid?
|
||||||
|
cmd_send(CMD_ACK,1,0,0,uid,sizeof(uid));
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
|
|
||||||
if ((workFlags & 0x10) || (!isOK)) {
|
if (workFlags & MAGIC_OFF)
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
OnSuccessMagic();
|
||||||
LEDsoff();
|
|
||||||
set_tracing(FALSE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){
|
||||||
|
|
||||||
void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){
|
|
||||||
|
|
||||||
// params
|
|
||||||
// bit 1 - need wupC
|
|
||||||
// bit 2 - need HALT after sequence
|
|
||||||
// bit 3 - need init FPGA and field before sequence
|
|
||||||
// bit 4 - need reset FPGA and LED
|
|
||||||
// bit 5 - need to set datain instead of issuing USB reply (called via ARM for StandAloneMode14a)
|
|
||||||
uint8_t workFlags = arg0;
|
uint8_t workFlags = arg0;
|
||||||
uint8_t blockNo = arg2;
|
uint8_t blockNo = arg1;
|
||||||
|
|
||||||
// card commands
|
Dbprintf("ICE :: CGetBlocks Flags %02x", workFlags);
|
||||||
uint8_t wupC1[] = { 0x40 };
|
|
||||||
uint8_t wupC2[] = { 0x43 };
|
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
byte_t isOK = 0;
|
uint8_t data[MAX_MIFARE_FRAME_SIZE];
|
||||||
uint8_t data[18] = {0x00};
|
|
||||||
uint32_t cuid = 0;
|
|
||||||
|
|
||||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
||||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
||||||
|
|
||||||
if (workFlags & 0x08) {
|
memset(data, 0x00, sizeof(data));
|
||||||
|
|
||||||
|
if (workFlags & MAGIC_INIT) {
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
LED_C_OFF();
|
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(TRUE);
|
set_tracing(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
if (workFlags & MAGIC_WUPC) {
|
||||||
if (workFlags & 0x02) {
|
|
||||||
ReaderTransmitBitsPar(wupC1,7,0, NULL);
|
ReaderTransmitBitsPar(wupC1,7,0, NULL);
|
||||||
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC1 error");
|
||||||
break;
|
OnErrorMagic(MAGIC_WUPC);
|
||||||
};
|
};
|
||||||
|
|
||||||
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
|
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
|
||||||
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC2 error");
|
||||||
break;
|
OnErrorMagic(MAGIC_WUPC);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// read block
|
// read block
|
||||||
if ((mifare_sendcmd_short(NULL, 0, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) {
|
if ((mifare_sendcmd_short(NULL, 0, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("read block send command error");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("read block send command error");
|
||||||
break;
|
OnErrorMagic(0);
|
||||||
};
|
};
|
||||||
memcpy(data, receivedAnswer, 18);
|
|
||||||
|
|
||||||
if (workFlags & 0x04) {
|
memcpy(data, receivedAnswer, sizeof(data));
|
||||||
if (mifare_classic_halt(NULL, cuid)) {
|
|
||||||
if (MF_DBGLEVEL >= 4) Dbprintf("INFO - Tag answered the 'Halt' command");
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
isOK = 1;
|
// send HALT
|
||||||
break;
|
if (workFlags & MAGIC_HALT)
|
||||||
}
|
mifare_classic_halt_ex(NULL);
|
||||||
|
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
if (workFlags & 0x20) {
|
|
||||||
if (isOK)
|
// if MAGIC_DATAIN, the data stays on device side.
|
||||||
memcpy(datain, data, 18);
|
if (workFlags & MAGIC_DATAIN)
|
||||||
}
|
memcpy(datain, data, sizeof(data));
|
||||||
else
|
else
|
||||||
cmd_send(CMD_ACK,isOK,0,0,data,18);
|
cmd_send(CMD_ACK,1,0,0,data,sizeof(data));
|
||||||
|
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
|
|
||||||
if ((workFlags & 0x10) || (!isOK)) {
|
if (workFlags & MAGIC_OFF)
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
OnSuccessMagic();
|
||||||
LEDsoff();
|
|
||||||
set_tracing(FALSE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MifareCIdent(){
|
void MifareCIdent(){
|
||||||
|
|
||||||
// card commands
|
|
||||||
uint8_t wupC1[] = { 0x40 };
|
|
||||||
uint8_t wupC2[] = { 0x43 };
|
|
||||||
|
|
||||||
// variables
|
// variables
|
||||||
byte_t isOK = 1;
|
byte_t isOK = 1;
|
||||||
|
uint8_t receivedAnswer[1];
|
||||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
uint8_t receivedAnswerPar[1];
|
||||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
|
||||||
|
|
||||||
ReaderTransmitBitsPar(wupC1,7,0, NULL);
|
ReaderTransmitBitsPar(wupC1,7,0, NULL);
|
||||||
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
|
||||||
|
@ -1241,77 +1194,22 @@ void MifareCIdent(){
|
||||||
|
|
||||||
// removed the if, since some magic tags misbehavies and send an answer to it.
|
// removed the if, since some magic tags misbehavies and send an answer to it.
|
||||||
mifare_classic_halt(NULL, 0);
|
mifare_classic_halt(NULL, 0);
|
||||||
|
|
||||||
cmd_send(CMD_ACK,isOK,0,0,0,0);
|
cmd_send(CMD_ACK,isOK,0,0,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MifareCollectNonces(uint32_t arg0, uint32_t arg1){
|
void OnSuccessMagic(){
|
||||||
|
|
||||||
BigBuf_free();
|
|
||||||
|
|
||||||
uint32_t iterations = arg0;
|
|
||||||
uint8_t uid[10] = {0x00};
|
|
||||||
|
|
||||||
uint8_t *response = BigBuf_malloc(MAX_MIFARE_FRAME_SIZE);
|
|
||||||
uint8_t *responsePar = BigBuf_malloc(MAX_MIFARE_PARITY_SIZE);
|
|
||||||
|
|
||||||
uint8_t mf_auth[] = { 0x60,0x00,0xf5,0x7b };
|
|
||||||
|
|
||||||
// get memory from BigBuf.
|
|
||||||
uint8_t *nonces = BigBuf_malloc(iterations * 4);
|
|
||||||
|
|
||||||
LED_A_ON();
|
|
||||||
LED_B_OFF();
|
|
||||||
LED_C_OFF();
|
|
||||||
|
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
|
||||||
clear_trace();
|
|
||||||
set_tracing(TRUE);
|
|
||||||
|
|
||||||
for (int i = 0; i < iterations; i++) {
|
|
||||||
|
|
||||||
WDT_HIT();
|
|
||||||
|
|
||||||
// Test if the action was cancelled
|
|
||||||
if(BUTTON_PRESS()) break;
|
|
||||||
|
|
||||||
// if(mifare_classic_halt(pcs, cuid)) {
|
|
||||||
// if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
|
|
||||||
//}
|
|
||||||
|
|
||||||
if(!iso14443a_select_card(uid, NULL, NULL)) {
|
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Transmit MIFARE_CLASSIC_AUTH.
|
|
||||||
ReaderTransmit(mf_auth, sizeof(mf_auth), NULL);
|
|
||||||
|
|
||||||
// Receive the (4 Byte) "random" nonce
|
|
||||||
if (!ReaderReceive(response, responsePar)) {
|
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Couldn't receive tag nonce");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
nonces[i*4] = bytes_to_num(response, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
int packLen = iterations * 4;
|
|
||||||
int packSize = 0;
|
|
||||||
int packNum = 0;
|
|
||||||
while (packLen > 0) {
|
|
||||||
packSize = MIN(USB_CMD_DATA_SIZE, packLen);
|
|
||||||
LED_B_ON();
|
|
||||||
cmd_send(CMD_ACK, 77, 0, packSize, nonces - packLen, packSize);
|
|
||||||
LED_B_OFF();
|
|
||||||
|
|
||||||
packLen -= packSize;
|
|
||||||
packNum++;
|
|
||||||
}
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
set_tracing(FALSE);
|
set_tracing(FALSE);
|
||||||
}
|
}
|
||||||
|
void OnErrorMagic(uint8_t reason){
|
||||||
|
// ACK, ISOK, reason,0,0,0
|
||||||
|
cmd_send(CMD_ACK,0,reason,0,0,0);
|
||||||
|
OnSuccessMagic();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MifareCollectNonces(uint32_t arg0, uint32_t arg1){
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// DESFIRE
|
// DESFIRE
|
||||||
|
|
|
@ -575,11 +575,6 @@ void OnSuccess(){
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnError(uint8_t reason){
|
void OnError(uint8_t reason){
|
||||||
pcb_blocknum = 0;
|
|
||||||
ReaderTransmit(deselect_cmd, 3 , NULL);
|
|
||||||
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
|
||||||
cmd_send(CMD_ACK,0,reason,0,0,0);
|
cmd_send(CMD_ACK,0,reason,0,0,0);
|
||||||
LEDsoff();
|
OnSuccess();
|
||||||
set_tracing(FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -501,22 +501,21 @@ int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData)
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
int mifare_classic_halt_ex(struct Crypto1State *pcs) {
|
||||||
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
|
|
||||||
{
|
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
|
uint8_t receivedAnswer[4];
|
||||||
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
|
uint8_t receivedAnswerPar[4];
|
||||||
|
|
||||||
len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
|
len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
|
||||||
if (len != 0) {
|
if (len != 0) {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR)
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("halt error. response len: %x", len);
|
||||||
Dbprintf("halt error. response len: %x", len);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid) {
|
||||||
|
return mifare_classic_halt_ex(pcs);
|
||||||
|
}
|
||||||
|
|
||||||
int mifare_ultra_halt()
|
int mifare_ultra_halt()
|
||||||
{
|
{
|
||||||
|
|
|
@ -62,6 +62,7 @@ int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo,
|
||||||
int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t * ntptr, uint32_t *timing);
|
int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t * ntptr, uint32_t *timing);
|
||||||
int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);
|
int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);
|
||||||
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid);
|
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid);
|
||||||
|
int mifare_classic_halt_ex(struct Crypto1State *pcs);
|
||||||
int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);
|
int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);
|
||||||
|
|
||||||
// Ultralight/NTAG...
|
// Ultralight/NTAG...
|
||||||
|
|
|
@ -136,8 +136,8 @@ int CmdHF14AList(const char *Cmd)
|
||||||
int CmdHF14AReader(const char *Cmd)
|
int CmdHF14AReader(const char *Cmd)
|
||||||
{
|
{
|
||||||
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};
|
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};
|
||||||
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
|
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
WaitForResponse(CMD_ACK,&resp);
|
WaitForResponse(CMD_ACK,&resp);
|
||||||
|
|
||||||
|
@ -185,6 +185,7 @@ int CmdHF14AReader(const char *Cmd)
|
||||||
c.arg[1] = 0;
|
c.arg[1] = 0;
|
||||||
c.arg[2] = 0;
|
c.arg[2] = 0;
|
||||||
|
|
||||||
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
|
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
|
@ -248,6 +249,7 @@ int CmdHF14AReader(const char *Cmd)
|
||||||
c.arg[1] = 2;
|
c.arg[1] = 2;
|
||||||
c.arg[2] = 0;
|
c.arg[2] = 0;
|
||||||
memcpy(c.d.asBytes, rats, 2);
|
memcpy(c.d.asBytes, rats, 2);
|
||||||
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
WaitForResponse(CMD_ACK,&resp);
|
WaitForResponse(CMD_ACK,&resp);
|
||||||
|
|
||||||
|
@ -345,16 +347,16 @@ int CmdHF14AReader(const char *Cmd)
|
||||||
PrintAndLog(" x0 -> <1 kByte");
|
PrintAndLog(" x0 -> <1 kByte");
|
||||||
break;
|
break;
|
||||||
case 0x01:
|
case 0x01:
|
||||||
PrintAndLog(" x0 -> 1 kByte");
|
PrintAndLog(" x1 -> 1 kByte");
|
||||||
break;
|
break;
|
||||||
case 0x02:
|
case 0x02:
|
||||||
PrintAndLog(" x0 -> 2 kByte");
|
PrintAndLog(" x2 -> 2 kByte");
|
||||||
break;
|
break;
|
||||||
case 0x03:
|
case 0x03:
|
||||||
PrintAndLog(" x0 -> 4 kByte");
|
PrintAndLog(" x3 -> 4 kByte");
|
||||||
break;
|
break;
|
||||||
case 0x04:
|
case 0x04:
|
||||||
PrintAndLog(" x0 -> 8 kByte");
|
PrintAndLog(" x4 -> 8 kByte");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (card.ats[pos + 3] & 0xf0) {
|
switch (card.ats[pos + 3] & 0xf0) {
|
||||||
|
@ -395,14 +397,17 @@ int CmdHF14AReader(const char *Cmd)
|
||||||
|
|
||||||
|
|
||||||
// try to see if card responses to "chinese magic backdoor" commands.
|
// try to see if card responses to "chinese magic backdoor" commands.
|
||||||
|
uint8_t isOK = 0;
|
||||||
|
clearCommandBuffer();
|
||||||
c.cmd = CMD_MIFARE_CIDENT;
|
c.cmd = CMD_MIFARE_CIDENT;
|
||||||
c.arg[0] = 0;
|
c.arg[0] = 0;
|
||||||
c.arg[1] = 0;
|
c.arg[1] = 0;
|
||||||
c.arg[2] = 0;
|
c.arg[2] = 0;
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
WaitForResponse(CMD_ACK,&resp);
|
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500))
|
||||||
uint8_t isOK = resp.arg[0] & 0xff;
|
isOK = resp.arg[0] & 0xff;
|
||||||
PrintAndLog("Answers to chinese magic backdoor commands: %s", (isOK ? "YES" : "NO") );
|
|
||||||
|
PrintAndLog("Answers to magic commands (GEN1): %s", (isOK ? "YES" : "NO") );
|
||||||
|
|
||||||
// disconnect
|
// disconnect
|
||||||
c.cmd = CMD_READER_ISO_14443a;
|
c.cmd = CMD_READER_ISO_14443a;
|
||||||
|
|
|
@ -1543,7 +1543,7 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
|
||||||
{
|
{
|
||||||
uint8_t memBlock[16] = {0x00};
|
uint8_t memBlock[16] = {0x00};
|
||||||
uint8_t blockNo = 0;
|
uint8_t blockNo = 0;
|
||||||
bool wipeCard = FALSE;
|
uint8_t params = MAGIC_SINGLE;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
||||||
|
@ -1562,10 +1562,12 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
char ctmp = param_getchar(Cmd, 2);
|
char ctmp = param_getchar(Cmd, 2);
|
||||||
wipeCard = (ctmp == 'w' || ctmp == 'W');
|
if (ctmp == 'w' || ctmp == 'W')
|
||||||
|
params |= MAGIC_WIPE;
|
||||||
|
|
||||||
PrintAndLog("--block number:%2d data:%s", blockNo, sprint_hex(memBlock, 16));
|
PrintAndLog("--block number:%2d data:%s", blockNo, sprint_hex(memBlock, 16));
|
||||||
|
|
||||||
res = mfCSetBlock(blockNo, memBlock, NULL, wipeCard, CSETBLOCK_SINGLE_OPER);
|
res = mfCSetBlock(blockNo, memBlock, NULL, params);
|
||||||
if (res) {
|
if (res) {
|
||||||
PrintAndLog("Can't write block. error=%d", res);
|
PrintAndLog("Can't write block. error=%d", res);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1576,13 +1578,15 @@ int CmdHF14AMfCSetBlk(const char *Cmd)
|
||||||
int CmdHF14AMfCLoad(const char *Cmd)
|
int CmdHF14AMfCLoad(const char *Cmd)
|
||||||
{
|
{
|
||||||
FILE * f;
|
FILE * f;
|
||||||
char filename[FILE_PATH_SIZE] = {0x00};
|
char filename[FILE_PATH_SIZE];
|
||||||
char * fnameptr = filename;
|
char * fnameptr = filename;
|
||||||
char buf[64] = {0x00};
|
char buf[64] = {0x00};
|
||||||
uint8_t buf8[64] = {0x00};
|
uint8_t buf8[64] = {0x00};
|
||||||
uint8_t fillFromEmulator = 0;
|
uint8_t fillFromEmulator = 0;
|
||||||
int i, len, blockNum, flags=0;
|
int i, len, blockNum, flags=0;
|
||||||
|
|
||||||
|
memset(filename, 0, sizeof(filename));
|
||||||
|
|
||||||
char ctmp = param_getchar(Cmd, 0);
|
char ctmp = param_getchar(Cmd, 0);
|
||||||
|
|
||||||
if (ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) {
|
if (ctmp == 'h' || ctmp == 'H' || ctmp == 0x00) {
|
||||||
|
@ -1602,11 +1606,11 @@ int CmdHF14AMfCLoad(const char *Cmd)
|
||||||
PrintAndLog("Cant get block: %d", blockNum);
|
PrintAndLog("Cant get block: %d", blockNum);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
if (blockNum == 0) flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; // switch on field and send magic sequence
|
if (blockNum == 0) flags = MAGIC_INIT + MAGIC_WUPC; // switch on field and send magic sequence
|
||||||
if (blockNum == 1) flags = 0; // just write
|
if (blockNum == 1) flags = 0; // just write
|
||||||
if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; // Done. Magic Halt and switch off field.
|
if (blockNum == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; // Done. Magic Halt and switch off field.
|
||||||
|
|
||||||
if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) {
|
if (mfCSetBlock(blockNum, buf8, NULL, flags)) {
|
||||||
PrintAndLog("Cant set magic card block: %d", blockNum);
|
PrintAndLog("Cant set magic card block: %d", blockNum);
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
@ -1649,11 +1653,11 @@ int CmdHF14AMfCLoad(const char *Cmd)
|
||||||
for (i = 0; i < 32; i += 2)
|
for (i = 0; i < 32; i += 2)
|
||||||
sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);
|
sscanf(&buf[i], "%02x", (unsigned int *)&buf8[i / 2]);
|
||||||
|
|
||||||
if (blockNum == 0) flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC; // switch on field and send magic sequence
|
if (blockNum == 0) flags = MAGIC_INIT + MAGIC_WUPC; // switch on field and send magic sequence
|
||||||
if (blockNum == 1) flags = 0; // just write
|
if (blockNum == 1) flags = 0; // just write
|
||||||
if (blockNum == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD; // Done. Switch off field.
|
if (blockNum == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF; // Done. Switch off field.
|
||||||
|
|
||||||
if (mfCSetBlock(blockNum, buf8, NULL, 0, flags)) {
|
if (mfCSetBlock(blockNum, buf8, NULL, flags)) {
|
||||||
PrintAndLog("Can't set magic card block: %d", blockNum);
|
PrintAndLog("Can't set magic card block: %d", blockNum);
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
|
@ -1663,6 +1667,7 @@ int CmdHF14AMfCLoad(const char *Cmd)
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
|
// 64 or 256blocks.
|
||||||
if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){
|
if (blockNum != 16 * 4 && blockNum != 32 * 4 + 8 * 16){
|
||||||
PrintAndLog("File content error. There must be 64 blocks");
|
PrintAndLog("File content error. There must be 64 blocks");
|
||||||
return 4;
|
return 4;
|
||||||
|
@ -1674,12 +1679,13 @@ int CmdHF14AMfCLoad(const char *Cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHF14AMfCGetBlk(const char *Cmd) {
|
int CmdHF14AMfCGetBlk(const char *Cmd) {
|
||||||
uint8_t memBlock[16];
|
uint8_t data[16];
|
||||||
uint8_t blockNo = 0;
|
uint8_t blockNo = 0;
|
||||||
int res;
|
int res;
|
||||||
memset(memBlock, 0x00, sizeof(memBlock));
|
memset(data, 0x00, sizeof(data));
|
||||||
|
char ctmp = param_getchar(Cmd, 0);
|
||||||
|
|
||||||
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') {
|
||||||
PrintAndLog("Usage: hf mf cgetblk <block number>");
|
PrintAndLog("Usage: hf mf cgetblk <block number>");
|
||||||
PrintAndLog("sample: hf mf cgetblk 1");
|
PrintAndLog("sample: hf mf cgetblk 1");
|
||||||
PrintAndLog("Get block data from magic Chinese card (only works with such cards)\n");
|
PrintAndLog("Get block data from magic Chinese card (only works with such cards)\n");
|
||||||
|
@ -1690,22 +1696,24 @@ int CmdHF14AMfCGetBlk(const char *Cmd) {
|
||||||
|
|
||||||
PrintAndLog("--block number:%2d ", blockNo);
|
PrintAndLog("--block number:%2d ", blockNo);
|
||||||
|
|
||||||
res = mfCGetBlock(blockNo, memBlock, CSETBLOCK_SINGLE_OPER);
|
res = mfCGetBlock(blockNo, data, MAGIC_SINGLE);
|
||||||
if (res) {
|
if (res) {
|
||||||
PrintAndLog("Can't read block. error=%d", res);
|
PrintAndLog("Can't read block. error=%d", res);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLog("block data:%s", sprint_hex(memBlock, 16));
|
PrintAndLog("data:%s", sprint_hex(data, sizeof(data)));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHF14AMfCGetSc(const char *Cmd) {
|
int CmdHF14AMfCGetSc(const char *Cmd) {
|
||||||
uint8_t memBlock[16] = {0x00};
|
uint8_t data[16];
|
||||||
uint8_t sectorNo = 0;
|
uint8_t sectorNo = 0;
|
||||||
int i, res, flags;
|
int i, res, flags;
|
||||||
|
memset(data, 0x00, sizeof(data));
|
||||||
|
char ctmp = param_getchar(Cmd, 0);
|
||||||
|
|
||||||
if (strlen(Cmd) < 1 || param_getchar(Cmd, 0) == 'h') {
|
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') {
|
||||||
PrintAndLog("Usage: hf mf cgetsc <sector number>");
|
PrintAndLog("Usage: hf mf cgetsc <sector number>");
|
||||||
PrintAndLog("sample: hf mf cgetsc 0");
|
PrintAndLog("sample: hf mf cgetsc 0");
|
||||||
PrintAndLog("Get sector data from magic Chinese card (only works with such cards)\n");
|
PrintAndLog("Get sector data from magic Chinese card (only works with such cards)\n");
|
||||||
|
@ -1719,19 +1727,19 @@ int CmdHF14AMfCGetSc(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLog("--sector number:%d ", sectorNo);
|
PrintAndLog("--sector number:%d ", sectorNo);
|
||||||
|
PrintAndLog("block | data");
|
||||||
|
|
||||||
flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
|
flags = MAGIC_INIT + MAGIC_WUPC;
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
if (i == 1) flags = 0;
|
if (i == 1) flags = 0;
|
||||||
if (i == 3) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
|
if (i == 3) flags = MAGIC_HALT + MAGIC_OFF;
|
||||||
|
|
||||||
res = mfCGetBlock(sectorNo * 4 + i, memBlock, flags);
|
res = mfCGetBlock(sectorNo * 4 + i, data, flags);
|
||||||
if (res) {
|
if (res) {
|
||||||
PrintAndLog("Can't read block. %d error=%d", sectorNo * 4 + i, res);
|
PrintAndLog("Can't read block. %d error=%d", sectorNo * 4 + i, res);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
PrintAndLog(" %3d | %s", sectorNo * 4 + i, sprint_hex(data, sizeof(data)));
|
||||||
PrintAndLog("block %3d data:%s", sectorNo * 4 + i, sprint_hex(memBlock, 16));
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1739,14 +1747,14 @@ int CmdHF14AMfCGetSc(const char *Cmd) {
|
||||||
int CmdHF14AMfCSave(const char *Cmd) {
|
int CmdHF14AMfCSave(const char *Cmd) {
|
||||||
|
|
||||||
FILE * f;
|
FILE * f;
|
||||||
char filename[FILE_PATH_SIZE] = {0x00};
|
char filename[FILE_PATH_SIZE];
|
||||||
char * fnameptr = filename;
|
char * fnameptr = filename;
|
||||||
uint8_t fillFromEmulator = 0;
|
uint8_t fillFromEmulator = 0;
|
||||||
uint8_t buf[64] = {0x00};
|
uint8_t buf[64];
|
||||||
int i, j, len, flags;
|
int i, j, len, flags;
|
||||||
|
|
||||||
// memset(filename, 0, sizeof(filename));
|
memset(filename, 0, sizeof(filename));
|
||||||
// memset(buf, 0, sizeof(buf));
|
memset(buf, 0, sizeof(buf));
|
||||||
char ctmp = param_getchar(Cmd, 0);
|
char ctmp = param_getchar(Cmd, 0);
|
||||||
|
|
||||||
if ( ctmp == 'h' || ctmp == 'H' ) {
|
if ( ctmp == 'h' || ctmp == 'H' ) {
|
||||||
|
@ -1762,10 +1770,10 @@ int CmdHF14AMfCSave(const char *Cmd) {
|
||||||
|
|
||||||
if (fillFromEmulator) {
|
if (fillFromEmulator) {
|
||||||
// put into emulator
|
// put into emulator
|
||||||
flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
|
flags = MAGIC_INIT + MAGIC_WUPC;
|
||||||
for (i = 0; i < 16 * 4; i++) {
|
for (i = 0; i < 16 * 4; i++) {
|
||||||
if (i == 1) flags = 0;
|
if (i == 1) flags = 0;
|
||||||
if (i == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
|
if (i == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF;
|
||||||
|
|
||||||
if (mfCGetBlock(i, buf, flags)) {
|
if (mfCGetBlock(i, buf, flags)) {
|
||||||
PrintAndLog("Cant get block: %d", i);
|
PrintAndLog("Cant get block: %d", i);
|
||||||
|
@ -1782,9 +1790,10 @@ int CmdHF14AMfCSave(const char *Cmd) {
|
||||||
len = strlen(Cmd);
|
len = strlen(Cmd);
|
||||||
if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4;
|
if (len > FILE_PATH_SIZE - 4) len = FILE_PATH_SIZE - 4;
|
||||||
|
|
||||||
|
// get filename based on UID
|
||||||
if (len < 1) {
|
if (len < 1) {
|
||||||
// get filename
|
|
||||||
if (mfCGetBlock(0, buf, CSETBLOCK_SINGLE_OPER)) {
|
if (mfCGetBlock(0, buf, MAGIC_SINGLE)) {
|
||||||
PrintAndLog("Cant get block: %d", 0);
|
PrintAndLog("Cant get block: %d", 0);
|
||||||
len = sprintf(fnameptr, "dump");
|
len = sprintf(fnameptr, "dump");
|
||||||
fnameptr += len;
|
fnameptr += len;
|
||||||
|
@ -1797,6 +1806,7 @@ int CmdHF14AMfCSave(const char *Cmd) {
|
||||||
fnameptr += len;
|
fnameptr += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add .eml extension
|
||||||
sprintf(fnameptr, ".eml");
|
sprintf(fnameptr, ".eml");
|
||||||
|
|
||||||
// open file
|
// open file
|
||||||
|
@ -1808,10 +1818,10 @@ int CmdHF14AMfCSave(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// put hex
|
// put hex
|
||||||
flags = CSETBLOCK_INIT_FIELD + CSETBLOCK_WUPC;
|
flags = MAGIC_INIT + MAGIC_WUPC;
|
||||||
for (i = 0; i < 16 * 4; i++) {
|
for (i = 0; i < 16 * 4; i++) {
|
||||||
if (i == 1) flags = 0;
|
if (i == 1) flags = 0;
|
||||||
if (i == 16 * 4 - 1) flags = CSETBLOCK_HALT + CSETBLOCK_RESET_FIELD;
|
if (i == 16 * 4 - 1) flags = MAGIC_HALT + MAGIC_OFF;
|
||||||
|
|
||||||
if (mfCGetBlock(i, buf, flags)) {
|
if (mfCGetBlock(i, buf, flags)) {
|
||||||
PrintAndLog("Cant get block: %d", i);
|
PrintAndLog("Cant get block: %d", i);
|
||||||
|
@ -1821,10 +1831,9 @@ int CmdHF14AMfCSave(const char *Cmd) {
|
||||||
fprintf(f, "%02x", buf[j]);
|
fprintf(f, "%02x", buf[j]);
|
||||||
fprintf(f,"\n");
|
fprintf(f,"\n");
|
||||||
}
|
}
|
||||||
|
fflush(f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
PrintAndLog("Saved to file: %s", filename);
|
PrintAndLog("Saved to file: %s", filename);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2031,7 +2040,6 @@ int CmdHFMF(const char *Cmd)
|
||||||
{
|
{
|
||||||
// flush
|
// flush
|
||||||
WaitForResponseTimeout(CMD_ACK,NULL,100);
|
WaitForResponseTimeout(CMD_ACK,NULL,100);
|
||||||
|
|
||||||
CmdsParse(CommandTable, Cmd);
|
CmdsParse(CommandTable, Cmd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1222,7 +1222,7 @@ static command_t CommandTable[] =
|
||||||
{"simfsk", CmdLFfskSim, 0, "[c <clock>] [i] [H <fcHigh>] [L <fcLow>] [d <hexdata>] \n\t\t-- Simulate LF FSK tag from demodbuffer or input"},
|
{"simfsk", CmdLFfskSim, 0, "[c <clock>] [i] [H <fcHigh>] [L <fcLow>] [d <hexdata>] \n\t\t-- Simulate LF FSK tag from demodbuffer or input"},
|
||||||
{"simpsk", CmdLFpskSim, 0, "[1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>] \n\t\t-- Simulate LF PSK tag from demodbuffer or input"},
|
{"simpsk", CmdLFpskSim, 0, "[1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>] \n\t\t-- Simulate LF PSK tag from demodbuffer or input"},
|
||||||
{"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
|
{"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
|
||||||
{"snoop", CmdLFSnoop, 0, "['l'|'h'|<divisor>] [trigger threshold] -- Snoop LF (l:125khz, h:134khz)"},
|
{"snoop", CmdLFSnoop, 0, "Snoop LF"},
|
||||||
{"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"},
|
{"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
|
@ -237,14 +237,16 @@ int mfEmlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidt
|
||||||
|
|
||||||
// "MAGIC" CARD
|
// "MAGIC" CARD
|
||||||
|
|
||||||
int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, bool wantWipe) {
|
int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, uint8_t wipecard) {
|
||||||
uint8_t oldblock0[16] = {0x00};
|
|
||||||
uint8_t block0[16] = {0x00};
|
|
||||||
|
|
||||||
int old = mfCGetBlock(0, oldblock0, CSETBLOCK_SINGLE_OPER);
|
uint8_t params = MAGIC_SINGLE;
|
||||||
|
uint8_t block0[16];
|
||||||
|
memset(block0, 0x00, sizeof(block0));
|
||||||
|
|
||||||
|
|
||||||
|
int old = mfCGetBlock(0, block0, params);
|
||||||
if (old == 0) {
|
if (old == 0) {
|
||||||
memcpy(block0, oldblock0, 16);
|
PrintAndLog("old block 0: %s", sprint_hex(block0, sizeof(block0)));
|
||||||
PrintAndLog("old block 0: %s", sprint_hex(block0,16));
|
|
||||||
} else {
|
} else {
|
||||||
PrintAndLog("Couldn't get old data. Will write over the last bytes of Block 0.");
|
PrintAndLog("Couldn't get old data. Will write over the last bytes of Block 0.");
|
||||||
}
|
}
|
||||||
|
@ -255,26 +257,30 @@ int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, bool w
|
||||||
// Mifare UID BCC
|
// Mifare UID BCC
|
||||||
block0[4] = block0[0]^block0[1]^block0[2]^block0[3];
|
block0[4] = block0[0]^block0[1]^block0[2]^block0[3];
|
||||||
// mifare classic SAK(byte 5) and ATQA(byte 6 and 7, reversed)
|
// mifare classic SAK(byte 5) and ATQA(byte 6 and 7, reversed)
|
||||||
if (sak!=NULL)
|
if ( sak != NULL )
|
||||||
block0[5]=sak[0];
|
block0[5]=sak[0];
|
||||||
if (atqa!=NULL) {
|
|
||||||
|
if ( atqa != NULL ) {
|
||||||
block0[6]=atqa[1];
|
block0[6]=atqa[1];
|
||||||
block0[7]=atqa[0];
|
block0[7]=atqa[0];
|
||||||
}
|
}
|
||||||
PrintAndLog("new block 0: %s", sprint_hex(block0,16));
|
PrintAndLog("new block 0: %s", sprint_hex(block0,16));
|
||||||
return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER);
|
|
||||||
|
if ( wipecard ) params |= MAGIC_WIPE;
|
||||||
|
if ( oldUID == NULL) params |= MAGIC_UID;
|
||||||
|
|
||||||
|
return mfCSetBlock(0, block0, oldUID, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uint8_t params) {
|
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params) {
|
||||||
|
|
||||||
uint8_t isOK = 0;
|
uint8_t isOK = 0;
|
||||||
UsbCommand c = {CMD_MIFARE_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}};
|
UsbCommand c = {CMD_MIFARE_CSETBLOCK, {params, blockNo, 0}};
|
||||||
memcpy(c.d.asBytes, data, 16);
|
memcpy(c.d.asBytes, data, 16);
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
|
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
|
||||||
isOK = resp.arg[0] & 0xff;
|
isOK = resp.arg[0] & 0xff;
|
||||||
if (uid != NULL)
|
if (uid != NULL)
|
||||||
memcpy(uid, resp.d.asBytes, 4);
|
memcpy(uid, resp.d.asBytes, 4);
|
||||||
|
@ -289,9 +295,7 @@ int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uin
|
||||||
|
|
||||||
int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) {
|
int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) {
|
||||||
uint8_t isOK = 0;
|
uint8_t isOK = 0;
|
||||||
|
UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, blockNo, 0}};
|
||||||
UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, 0, blockNo}};
|
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
|
|
|
@ -19,18 +19,11 @@
|
||||||
#include "nonce2key/nonce2key.h"
|
#include "nonce2key/nonce2key.h"
|
||||||
#include "nonce2key/crapto1.h"
|
#include "nonce2key/crapto1.h"
|
||||||
#include "iso14443crc.h"
|
#include "iso14443crc.h"
|
||||||
|
#include "protocols.h"
|
||||||
|
|
||||||
#define MEM_CHUNK 1000000
|
#define MEM_CHUNK 1000000
|
||||||
#define NESTED_SECTOR_RETRY 10
|
#define NESTED_SECTOR_RETRY 10
|
||||||
|
|
||||||
// mfCSetBlock work flags
|
|
||||||
#define CSETBLOCK_UID 0x01
|
|
||||||
#define CSETBLOCK_WUPC 0x02
|
|
||||||
#define CSETBLOCK_HALT 0x04
|
|
||||||
#define CSETBLOCK_INIT_FIELD 0x08
|
|
||||||
#define CSETBLOCK_RESET_FIELD 0x10
|
|
||||||
#define CSETBLOCK_SINGLE_OPER 0x1F
|
|
||||||
|
|
||||||
// mifare tracer flags
|
// mifare tracer flags
|
||||||
#define TRACE_IDLE 0x00
|
#define TRACE_IDLE 0x00
|
||||||
#define TRACE_AUTH1 0x01
|
#define TRACE_AUTH1 0x01
|
||||||
|
@ -56,8 +49,8 @@ int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount);
|
||||||
int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);
|
int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount);
|
||||||
int mfEmlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidth);
|
int mfEmlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidth);
|
||||||
|
|
||||||
int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, bool wantWipe);
|
int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, uint8_t wipecard);
|
||||||
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uint8_t params);
|
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params);
|
||||||
int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params);
|
int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params);
|
||||||
|
|
||||||
int mfTraceInit(uint8_t *tuid, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile);
|
int mfTraceInit(uint8_t *tuid, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile);
|
||||||
|
|
|
@ -167,6 +167,21 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
||||||
#define MIFARE_ULEV1_VCSL 0x4B
|
#define MIFARE_ULEV1_VCSL 0x4B
|
||||||
|
|
||||||
|
|
||||||
|
// Magic Generation 1, parameter "work flags"
|
||||||
|
// bit 0 - need get UID
|
||||||
|
// bit 1 - send wupC (wakeup chinese)
|
||||||
|
// bit 2 - send HALT cmd after sequence
|
||||||
|
// bit 3 - turn on FPGA
|
||||||
|
// bit 4 - turn off FPGA
|
||||||
|
// bit 5 - set datain instead of issuing USB reply (called via ARM for StandAloneMode14a)
|
||||||
|
#define MAGIC_UID 0x01
|
||||||
|
#define MAGIC_WUPC 0x02
|
||||||
|
#define MAGIC_HALT 0x04
|
||||||
|
#define MAGIC_INIT 0x08
|
||||||
|
#define MAGIC_OFF 0x10
|
||||||
|
#define MAGIC_DATAIN 0x20
|
||||||
|
#define MAGIC_WIPE 0x40
|
||||||
|
#define MAGIC_SINGLE (MAGIC_WUPC | MAGIC_HALT | MAGIC_INIT | MAGIC_OFF) //0x1E
|
||||||
|
|
||||||
/**
|
/**
|
||||||
06 00 = INITIATE
|
06 00 = INITIATE
|
||||||
|
@ -313,7 +328,7 @@ void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *
|
||||||
#define T5555_PSK_RF_8 0x00000200
|
#define T5555_PSK_RF_8 0x00000200
|
||||||
#define T5555_USE_PWD 0x00000400
|
#define T5555_USE_PWD 0x00000400
|
||||||
#define T5555_USE_AOR 0x00000800
|
#define T5555_USE_AOR 0x00000800
|
||||||
#define T5555_BITRATE_SHIFT 12
|
#define T5555_BITRATE_SHIFT 12 //(RF=2n+2) ie 64=2*0x1F+2 or n = (RF-2)/2
|
||||||
#define T5555_FAST_WRITE 0x00004000
|
#define T5555_FAST_WRITE 0x00004000
|
||||||
#define T5555_PAGE_SELECT 0x00008000
|
#define T5555_PAGE_SELECT 0x00008000
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue