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:
iceman1001
2015-11-09 21:46:15 +01:00
parent bb9796ba26
commit c2731f37be
13 changed files with 344 additions and 426 deletions

View File

@@ -34,6 +34,7 @@
// Craig Young - 14a stand-alone code
#ifdef WITH_ISO14443a_StandAlone
#include "iso14443a.h"
#include "protocols.h"
#endif
#define abs(x) ( ((x)<0) ? -(x) : (x) )
@@ -387,6 +388,8 @@ void StandAloneMode14a()
uint32_t uid_tmp2 = 0;
iso14a_card_select_t hi14a_card[OPTS];
uint8_t params = (MAGIC_SINGLE | MAGIC_DATAIN);
LED(selected + 1, 0);
for (;;)
@@ -480,87 +483,84 @@ void StandAloneMode14a()
else if (iGotoClone==1)
{
iGotoClone=0;
LEDsoff();
LED(selected + 1, 0);
LED(LED_ORANGE, 250);
LEDsoff();
LED(selected + 1, 0);
LED(LED_ORANGE, 250);
// record
Dbprintf("Preparing to Clone card [Bank: %x]; uid: %08x", selected, uid_1st[selected]);
// record
Dbprintf("Preparing to Clone card [Bank: %x]; uid: %08x", selected, uid_1st[selected]);
// wait for button to be released
// Delay cloning until card is in place
while(BUTTON_PRESS())
WDT_HIT();
// wait for button to be released
while(BUTTON_PRESS())
{
// Delay cloning until card is in place
WDT_HIT();
}
Dbprintf("Starting clone. [Bank: %u]", selected);
// need this delay to prevent catching some weird data
SpinDelay(500);
// Begin clone function here:
/* 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}};
memcpy(c.d.asBytes, data, 16);
SendCommand(&c);
Dbprintf("Starting clone. [Bank: %u]", selected);
// need this delay to prevent catching some weird data
SpinDelay(500);
// Begin clone function here:
/* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards:
UsbCommand c = {CMD_MIFARE_CSETBLOCK, {params & (0xFE | (uid == NULL ? 0:1)), blockNo, 0}};
memcpy(c.d.asBytes, data, 16);
SendCommand(&c);
Block read is similar:
UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, 0, blockNo}};
We need to imitate that call with blockNo 0 to set a uid.
Block read is similar:
UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, blockNo, 0}};
We need to imitate that call with blockNo 0 to set a uid.
The get and set commands are handled in this file:
// Work with "magic Chinese" card
case CMD_MIFARE_CSETBLOCK:
MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
break;
case CMD_MIFARE_CGETBLOCK:
MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
break;
The get and set commands are handled in this file:
// Work with "magic Chinese" card
case CMD_MIFARE_CSETBLOCK:
MifareCSetBlock(c->arg[0], c->arg[1], c->d.asBytes);
break;
case CMD_MIFARE_CGETBLOCK:
MifareCGetBlock(c->arg[0], c->arg[1], c->d.asBytes);
break;
mfCSetUID provides example logic for UID set workflow:
-Read block0 from card in field with MifareCGetBlock()
-Configure new values without replacing reserved bytes
memcpy(block0, uid, 4); // Copy UID bytes from byte array
// Mifare UID BCC
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
-Use mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER) to write it
*/
uint8_t oldBlock0[16] = {0}, newBlock0[16] = {0}, testBlock0[16] = {0};
// arg0 = Flags == CSETBLOCK_SINGLE_OPER=0x1F, arg1=returnSlot, arg2=blockNo
MifareCGetBlock(0x3F, 1, 0, oldBlock0);
mfCSetUID provides example logic for UID set workflow:
-Read block0 from card in field with MifareCGetBlock()
-Configure new values without replacing reserved bytes
memcpy(block0, uid, 4); // Copy UID bytes from byte array
// Mifare UID BCC
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
-Use mfCSetBlock(0, block0, oldUID, wantWipe, MAGIC_SINGLE) to write it
*/
uint8_t oldBlock0[16] = {0}, newBlock0[16] = {0}, testBlock0[16] = {0};
// arg0 = Flags, arg1=blockNo
MifareCGetBlock(params, 0, oldBlock0);
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);
playing = 1;
}
else {
Dbprintf("UID from target tag: %02X%02X%02X%02X", oldBlock0[0],oldBlock0[1],oldBlock0[2],oldBlock0[3]);
memcpy(newBlock0,oldBlock0,16);
// Copy uid_1st for bank (2nd is for longer UIDs not supported if classic)
Dbprintf("UID from target tag: %02X%02X%02X%02X", oldBlock0[0],oldBlock0[1],oldBlock0[2],oldBlock0[3]);
memcpy(newBlock0,oldBlock0,16);
// Copy uid_1st for bank (2nd is for longer UIDs not supported if classic)
newBlock0[0] = uid_1st[selected]>>24;
newBlock0[1] = 0xFF & (uid_1st[selected]>>16);
newBlock0[2] = 0xFF & (uid_1st[selected]>>8);
newBlock0[3] = 0xFF & (uid_1st[selected]);
newBlock0[4] = newBlock0[0]^newBlock0[1]^newBlock0[2]^newBlock0[3];
// arg0 = needWipe, arg1 = workFlags, arg2 = blockNo, datain
MifareCSetBlock(0, 0xFF,0, newBlock0);
MifareCGetBlock(0x3F, 1, 0, testBlock0);
if (memcmp(testBlock0,newBlock0,16)==0)
{
DbpString("Cloned successfull!");
cardRead[selected] = 0; // Only if the card was cloned successfully should we clear it
newBlock0[0] = uid_1st[selected]>>24;
newBlock0[1] = 0xFF & (uid_1st[selected]>>16);
newBlock0[2] = 0xFF & (uid_1st[selected]>>8);
newBlock0[3] = 0xFF & (uid_1st[selected]);
newBlock0[4] = newBlock0[0]^newBlock0[1]^newBlock0[2]^newBlock0[3];
// arg0 = workFlags, arg1 = blockNo, datain
MifareCSetBlock(params, 0, newBlock0);
MifareCGetBlock(params, 0, testBlock0);
if (memcmp(testBlock0, newBlock0, 16)==0) {
DbpString("Cloned successfull!");
cardRead[selected] = 0; // Only if the card was cloned successfully should we clear it
playing = 0;
iGotoRecord = 1;
selected = (selected + 1) % OPTS;
}
else {
selected = (selected + 1) % OPTS;
} else {
Dbprintf("Clone failed. Back to replay mode on bank[%d]", selected);
playing = 1;
}
}
LEDsoff();
LED(selected + 1, 0);
}
// Change where to record (or begin playing)
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
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;
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;
case CMD_MIFARE_CIDENT:
MifareCIdent();
@@ -1196,7 +1196,6 @@ void UsbPacketReceived(uint8_t *packet, int len)
break;
case CMD_MIFARE_COLLECT_NONCES:
MifareCollectNonces(c->arg[0], c->arg[1]);
break;
#endif

View File

@@ -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 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 MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain); // Work with "magic Chinese" card
void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain); // Work with "magic Chinese" card
void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain);
void MifareCIdent(); // is "magic chinese" card?
void MifareUSetPwd(uint8_t arg0, uint8_t *datain);
void OnSuccessMagic();
void OnErrorMagic(uint8_t reason);
void MifareCollectNonces(uint32_t arg0, uint32_t arg1);
//desfire

View File

@@ -17,6 +17,7 @@
#include "apps.h"
#include "util.h"
#include "crc.h"
#include "protocols.h"
//-----------------------------------------------------------------------------
// 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)
//
// 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){
// params
uint8_t needWipe = arg0;
// bit 0 - need get UID
// 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;
// magic uid card generation 1 commands
uint8_t wupC1[] = { MIFARE_MAGICWUPC1 };
uint8_t wupC2[] = { MIFARE_MAGICWUPC2 };
uint8_t wipeC[] = { MIFARE_MAGICWIPEC };
// card commands
uint8_t wupC1[] = { 0x40 };
uint8_t wupC2[] = { 0x43 };
uint8_t wipeC[] = { 0x41 };
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){
// params
uint8_t workFlags = arg0;
uint8_t blockNo = arg1;
Dbprintf("ICE :: CSetBlocks Flags %02x", workFlags);
// variables
byte_t isOK = 0;
uint8_t uid[10] = {0x00};
uint8_t d_block[18] = {0x00};
uint8_t data[18] = {0x00};
uint32_t cuid;
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
// reset FPGA and LED
if (workFlags & 0x08) {
if (workFlags & MAGIC_INIT) {
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
clear_trace();
set_tracing(TRUE);
}
while (true) {
// get UID from chip
if (workFlags & 0x01) {
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
//break;
};
if(mifare_classic_halt(NULL, cuid)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");
//break;
};
// read UID and return to client
if (workFlags & MAGIC_UID) {
if(!iso14443a_select_card(uid, NULL, &cuid)) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
OnErrorMagic(MAGIC_UID);
};
};
// reset chip
if (needWipe){
ReaderTransmitBitsPar(wupC1,7,0, NULL);
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");
break;
};
ReaderTransmit(wipeC, sizeof(wipeC), NULL);
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("wipeC error");
break;
};
if(mifare_classic_halt(NULL, cuid)) {
if (MF_DBGLEVEL >= 4) Dbprintf("INFO - Tag answered the 'Halt' command");
break;
};
};
// write block
if (workFlags & 0x02) {
ReaderTransmitBitsPar(wupC1,7,0, NULL);
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");
break;
};
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");
break;
};
}
if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("write block send command error");
break;
// wipe tag, fill it with zeros
if (workFlags & MAGIC_WIPE){
ReaderTransmitBitsPar(wupC1,7,0, NULL);
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC1 error");
OnErrorMagic(MAGIC_WIPE);
};
ReaderTransmit(wipeC, sizeof(wipeC), NULL);
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wipeC error");
OnErrorMagic(MAGIC_WIPE);
};
};
// write block
if (workFlags & MAGIC_WUPC) {
ReaderTransmitBitsPar(wupC1,7,0, NULL);
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC1 error");
OnErrorMagic(MAGIC_WUPC);
};
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC2 error");
OnErrorMagic(MAGIC_WUPC);
};
memcpy(d_block, datain, 16);
AppendCrc14443a(d_block, 16);
ReaderTransmit(d_block, sizeof(d_block), NULL);
if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("write block send data error");
break;
};
if (workFlags & 0x04) {
if (mifare_classic_halt(NULL, cuid)) {
if (MF_DBGLEVEL >= 4) Dbprintf("INFO - Tag answered the 'Halt' command");
break;
};
}
isOK = 1;
break;
}
if ((mifare_sendcmd_short(NULL, 0, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("write block send command error");
OnErrorMagic(4);
};
memcpy(data, datain, sizeof(data));
AppendCrc14443a(data, sizeof(data));
ReaderTransmit(data, sizeof(data), NULL);
if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("write block send data error");
OnErrorMagic(0);
};
if (workFlags & MAGIC_OFF)
mifare_classic_halt_ex(NULL);
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();
if ((workFlags & 0x10) || (!isOK)) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
set_tracing(FALSE);
}
if (workFlags & MAGIC_OFF)
OnSuccessMagic();
}
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)
void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){
uint8_t workFlags = arg0;
uint8_t blockNo = arg2;
// card commands
uint8_t wupC1[] = { 0x40 };
uint8_t wupC2[] = { 0x43 };
uint8_t blockNo = arg1;
Dbprintf("ICE :: CGetBlocks Flags %02x", workFlags);
// variables
byte_t isOK = 0;
uint8_t data[18] = {0x00};
uint32_t cuid = 0;
uint8_t data[MAX_MIFARE_FRAME_SIZE];
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
if (workFlags & 0x08) {
memset(data, 0x00, sizeof(data));
if (workFlags & MAGIC_INIT) {
LED_A_ON();
LED_B_OFF();
LED_C_OFF();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
clear_trace();
set_tracing(TRUE);
}
while (true) {
if (workFlags & 0x02) {
ReaderTransmitBitsPar(wupC1,7,0, NULL);
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");
break;
};
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");
break;
};
}
// read block
if ((mifare_sendcmd_short(NULL, 0, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) {
if (MF_DBGLEVEL >= 1) Dbprintf("read block send command error");
break;
if (workFlags & MAGIC_WUPC) {
ReaderTransmitBitsPar(wupC1,7,0, NULL);
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC1 error");
OnErrorMagic(MAGIC_WUPC);
};
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC2 error");
OnErrorMagic(MAGIC_WUPC);
};
memcpy(data, receivedAnswer, 18);
if (workFlags & 0x04) {
if (mifare_classic_halt(NULL, cuid)) {
if (MF_DBGLEVEL >= 4) Dbprintf("INFO - Tag answered the 'Halt' command");
break;
};
}
isOK = 1;
break;
}
// read block
if ((mifare_sendcmd_short(NULL, 0, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) {
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("read block send command error");
OnErrorMagic(0);
};
memcpy(data, receivedAnswer, sizeof(data));
// send HALT
if (workFlags & MAGIC_HALT)
mifare_classic_halt_ex(NULL);
LED_B_ON();
if (workFlags & 0x20) {
if (isOK)
memcpy(datain, data, 18);
}
// if MAGIC_DATAIN, the data stays on device side.
if (workFlags & MAGIC_DATAIN)
memcpy(datain, data, sizeof(data));
else
cmd_send(CMD_ACK,isOK,0,0,data,18);
cmd_send(CMD_ACK,1,0,0,data,sizeof(data));
LED_B_OFF();
if ((workFlags & 0x10) || (!isOK)) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
set_tracing(FALSE);
}
if (workFlags & MAGIC_OFF)
OnSuccessMagic();
}
void MifareCIdent(){
// card commands
uint8_t wupC1[] = { 0x40 };
uint8_t wupC2[] = { 0x43 };
// variables
byte_t isOK = 1;
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
byte_t isOK = 1;
uint8_t receivedAnswer[1];
uint8_t receivedAnswerPar[1];
ReaderTransmitBitsPar(wupC1,7,0, NULL);
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
@@ -1241,76 +1194,21 @@ void MifareCIdent(){
// removed the if, since some magic tags misbehavies and send an answer to it.
mifare_classic_halt(NULL, 0);
cmd_send(CMD_ACK,isOK,0,0,0,0);
}
void MifareCollectNonces(uint32_t arg0, uint32_t arg1){
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++;
}
void OnSuccessMagic(){
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
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){
}
//

View File

@@ -575,11 +575,6 @@ void OnSuccess(){
}
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);
LEDsoff();
set_tracing(FALSE);
OnSuccess();
}

View File

@@ -501,22 +501,21 @@ int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData)
}
return 0;
}
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
{
int mifare_classic_halt_ex(struct Crypto1State *pcs) {
uint16_t len;
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
uint8_t receivedAnswer[4];
uint8_t receivedAnswerPar[4];
len = mifare_sendcmd_short(pcs, pcs == NULL ? false:true, 0x50, 0x00, receivedAnswer, receivedAnswerPar, NULL);
if (len != 0) {
if (MF_DBGLEVEL >= MF_DBG_ERROR)
Dbprintf("halt error. response len: %x", len);
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("halt error. response len: %x", len);
return 1;
}
return 0;
}
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid) {
return mifare_classic_halt_ex(pcs);
}
int mifare_ultra_halt()
{

View File

@@ -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_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_ex(struct Crypto1State *pcs);
int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData);
// Ultralight/NTAG...