#include "apps.h"\r
#include "util.h"\r
#include "crc.h"\r
+#include "protocols.h"\r
\r
//-----------------------------------------------------------------------------\r
// Select, Authenticate, Read a MIFARE tag. \r
//-----------------------------------------------------------------------------\r
// Work with "magic Chinese" card (email him: ouyangweidaxian@live.cn)\r
// \r
+// PARAMS - workFlags\r
+// bit 0 - need get UID\r
+// bit 1 - need wupC\r
+// bit 2 - need HALT after sequence\r
+// bit 3 - need turn on FPGA before sequence\r
+// bit 4 - need turn off FPGA\r
+// bit 5 - need to set datain instead of issuing USB reply (called via ARM for StandAloneMode14a)\r
+// bit 6 - wipe tag.\r
//-----------------------------------------------------------------------------\r
-void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
+// magic uid card generation 1 commands\r
+uint8_t wupC1[] = { MIFARE_MAGICWUPC1 }; \r
+uint8_t wupC2[] = { MIFARE_MAGICWUPC2 }; \r
+uint8_t wipeC[] = { MIFARE_MAGICWIPEC }; \r
+ \r
+void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){\r
\r
- // params\r
- uint8_t needWipe = arg0;\r
- // bit 0 - need get UID\r
- // bit 1 - need wupC\r
- // bit 2 - need HALT after sequence\r
- // bit 3 - need init FPGA and field before sequence\r
- // bit 4 - need reset FPGA and LED\r
- uint8_t workFlags = arg1;\r
- uint8_t blockNo = arg2;\r
+ // params\r
+ uint8_t workFlags = arg0;\r
+ uint8_t blockNo = arg1;\r
\r
- // card commands\r
- uint8_t wupC1[] = { 0x40 }; \r
- uint8_t wupC2[] = { 0x43 }; \r
- uint8_t wipeC[] = { 0x41 }; \r
+ Dbprintf("ICE :: CSetBlocks Flags %02x", workFlags);\r
\r
// variables\r
- byte_t isOK = 0;\r
uint8_t uid[10] = {0x00};\r
- uint8_t d_block[18] = {0x00};\r
+ uint8_t data[18] = {0x00};\r
uint32_t cuid;\r
\r
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
\r
- // reset FPGA and LED\r
- if (workFlags & 0x08) {\r
+ if (workFlags & MAGIC_INIT) {\r
LED_A_ON();\r
LED_B_OFF();\r
- LED_C_OFF();\r
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
- \r
clear_trace();\r
set_tracing(TRUE);\r
}\r
\r
- while (true) {\r
-\r
- // get UID from chip\r
- if (workFlags & 0x01) {\r
- if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
- //break;\r
- };\r
-\r
- if(mifare_classic_halt(NULL, cuid)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
- //break;\r
- };\r
+ // read UID and return to client\r
+ if (workFlags & MAGIC_UID) {\r
+ if(!iso14443a_select_card(uid, NULL, &cuid)) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");\r
+ OnErrorMagic(MAGIC_UID);\r
};\r
+ };\r
\r
- // reset chip\r
- if (needWipe){\r
- ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
- if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
- break;\r
- };\r
-\r
- ReaderTransmit(wipeC, sizeof(wipeC), NULL);\r
- if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("wipeC error");\r
- break;\r
- };\r
-\r
- if(mifare_classic_halt(NULL, cuid)) {\r
- if (MF_DBGLEVEL >= 4) Dbprintf("INFO - Tag answered the 'Halt' command");\r
- break;\r
- };\r
- }; \r
+ // wipe tag, fill it with zeros\r
+ if (workFlags & MAGIC_WIPE){\r
+ ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC1 error");\r
+ OnErrorMagic(MAGIC_WIPE);\r
+ };\r
\r
- // write block\r
- if (workFlags & 0x02) {\r
- ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
- if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
- break;\r
- };\r
+ ReaderTransmit(wipeC, sizeof(wipeC), NULL);\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wipeC error");\r
+ OnErrorMagic(MAGIC_WIPE);\r
+ };\r
+ }; \r
\r
- ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
- if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");\r
- break;\r
- };\r
- }\r
+ // write block\r
+ if (workFlags & MAGIC_WUPC) {\r
+ ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC1 error");\r
+ OnErrorMagic(MAGIC_WUPC);\r
+ };\r
\r
- if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("write block send command error");\r
- break;\r
+ ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC2 error");\r
+ OnErrorMagic(MAGIC_WUPC);\r
};\r
+ }\r
+\r
+ if ((mifare_sendcmd_short(NULL, 0, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("write block send command error");\r
+ OnErrorMagic(4);\r
+ };\r
\r
- memcpy(d_block, datain, 16);\r
- AppendCrc14443a(d_block, 16);\r
+ memcpy(data, datain, 16);\r
+ AppendCrc14443a(data, 16);\r
\r
- ReaderTransmit(d_block, sizeof(d_block), NULL);\r
- if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("write block send data error");\r
- break;\r
- }; \r
+ ReaderTransmit(data, sizeof(data), NULL);\r
+ if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("write block send data error");\r
+ OnErrorMagic(0);\r
+ }; \r
\r
- if (workFlags & 0x04) {\r
- if (mifare_classic_halt(NULL, cuid)) {\r
- if (MF_DBGLEVEL >= 4) Dbprintf("INFO - Tag answered the 'Halt' command");\r
- break;\r
- };\r
- }\r
- \r
- isOK = 1;\r
- break;\r
- }\r
+ if (workFlags & MAGIC_OFF) \r
+ mifare_classic_halt_ex(NULL);\r
\r
LED_B_ON();\r
- cmd_send(CMD_ACK,isOK,0,0,uid,4);\r
+ // check if uid is cuid?\r
+ cmd_send(CMD_ACK,1,0,0,uid,sizeof(uid));\r
LED_B_OFF();\r
\r
- if ((workFlags & 0x10) || (!isOK)) {\r
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
- LEDsoff();\r
- set_tracing(FALSE);\r
- }\r
+ if (workFlags & MAGIC_OFF)\r
+ OnSuccessMagic();\r
}\r
\r
-\r
-void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
- \r
- // params\r
- // bit 1 - need wupC\r
- // bit 2 - need HALT after sequence\r
- // bit 3 - need init FPGA and field before sequence\r
- // bit 4 - need reset FPGA and LED\r
- // bit 5 - need to set datain instead of issuing USB reply (called via ARM for StandAloneMode14a)\r
+void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){\r
+ \r
uint8_t workFlags = arg0;\r
- uint8_t blockNo = arg2;\r
- \r
- // card commands\r
- uint8_t wupC1[] = { 0x40 }; \r
- uint8_t wupC2[] = { 0x43 }; \r
- \r
+ uint8_t blockNo = arg1;\r
+\r
// variables\r
- byte_t isOK = 0;\r
- uint8_t data[18] = {0x00};\r
- uint32_t cuid = 0;\r
- \r
+ uint8_t data[MAX_MIFARE_FRAME_SIZE];\r
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
\r
- if (workFlags & 0x08) {\r
+ memset(data, 0x00, sizeof(data));\r
+ \r
+ if (workFlags & MAGIC_INIT) {\r
LED_A_ON();\r
LED_B_OFF();\r
- LED_C_OFF();\r
- iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
- \r
+ iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); \r
clear_trace();\r
set_tracing(TRUE);\r
}\r
\r
- while (true) {\r
- if (workFlags & 0x02) {\r
- ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
- if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("wupC1 error");\r
- break;\r
- };\r
-\r
- ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
- if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error");\r
- break;\r
- };\r
- }\r
+ if (workFlags & MAGIC_WUPC) {\r
+ ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC1 error");\r
+ OnErrorMagic(MAGIC_WUPC);\r
+ };\r
\r
- // read block\r
- if ((mifare_sendcmd_short(NULL, 0, 0x30, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("read block send command error");\r
- break;\r
+ ReaderTransmit(wupC2, sizeof(wupC2), NULL);\r
+ if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC2 error");\r
+ OnErrorMagic(MAGIC_WUPC);\r
};\r
- memcpy(data, receivedAnswer, 18);\r
- \r
- if (workFlags & 0x04) {\r
- if (mifare_classic_halt(NULL, cuid)) {\r
- if (MF_DBGLEVEL >= 4) Dbprintf("INFO - Tag answered the 'Halt' command");\r
- break;\r
- };\r
- }\r
- \r
- isOK = 1;\r
- break;\r
}\r
+\r
+ // read block \r
+ if ((mifare_sendcmd_short(NULL, 0, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 18)) {\r
+ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("read block send command error");\r
+ OnErrorMagic(0);\r
+ };\r
+ \r
+ memcpy(data, receivedAnswer, sizeof(data));\r
+ \r
+ // send HALT\r
+ if (workFlags & MAGIC_HALT) \r
+ mifare_classic_halt_ex(NULL);\r
\r
LED_B_ON();\r
- if (workFlags & 0x20) {\r
- if (isOK)\r
- memcpy(datain, data, 18);\r
- }\r
+ \r
+ // if MAGIC_DATAIN, the data stays on device side.\r
+ if (workFlags & MAGIC_DATAIN)\r
+ memcpy(datain, data, sizeof(data));\r
else\r
- cmd_send(CMD_ACK,isOK,0,0,data,18);\r
+ cmd_send(CMD_ACK,1,0,0,data,sizeof(data));\r
+ \r
LED_B_OFF();\r
\r
- if ((workFlags & 0x10) || (!isOK)) {\r
- FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
- LEDsoff();\r
- set_tracing(FALSE);\r
- }\r
+ if (workFlags & MAGIC_OFF)\r
+ OnSuccessMagic();\r
}\r
\r
void MifareCIdent(){\r
- \r
- // card commands\r
- uint8_t wupC1[] = { 0x40 }; \r
- uint8_t wupC2[] = { 0x43 }; \r
\r
// variables\r
- byte_t isOK = 1;\r
- \r
- uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE];\r
- uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];\r
+ byte_t isOK = 1; \r
+ uint8_t receivedAnswer[1];\r
+ uint8_t receivedAnswerPar[1];\r
\r
ReaderTransmitBitsPar(wupC1,7,0, NULL);\r
if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {\r
\r
// removed the if, since some magic tags misbehavies and send an answer to it.\r
mifare_classic_halt(NULL, 0);\r
-\r
cmd_send(CMD_ACK,isOK,0,0,0,0);\r
}\r
\r
-void MifareCollectNonces(uint32_t arg0, uint32_t arg1){\r
-\r
- BigBuf_free();\r
-\r
- uint32_t iterations = arg0;\r
- uint8_t uid[10] = {0x00};\r
-\r
- uint8_t *response = BigBuf_malloc(MAX_MIFARE_FRAME_SIZE);\r
- uint8_t *responsePar = BigBuf_malloc(MAX_MIFARE_PARITY_SIZE);\r
-\r
- uint8_t mf_auth[] = { 0x60,0x00,0xf5,0x7b };\r
- \r
- // get memory from BigBuf.\r
- uint8_t *nonces = BigBuf_malloc(iterations * 4);\r
-\r
- LED_A_ON();\r
- LED_B_OFF();\r
- LED_C_OFF();\r
- \r
- iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);\r
- clear_trace();\r
- set_tracing(TRUE);\r
- \r
- for (int i = 0; i < iterations; i++) {\r
- \r
- WDT_HIT();\r
-\r
- // Test if the action was cancelled\r
- if(BUTTON_PRESS()) break;\r
- \r
- // if(mifare_classic_halt(pcs, cuid)) {\r
- // if (MF_DBGLEVEL >= 1) Dbprintf("Halt error");\r
- //}\r
-\r
- if(!iso14443a_select_card(uid, NULL, NULL)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");\r
- continue;\r
- };\r
-\r
- // Transmit MIFARE_CLASSIC_AUTH.\r
- ReaderTransmit(mf_auth, sizeof(mf_auth), NULL);\r
-\r
- // Receive the (4 Byte) "random" nonce\r
- if (!ReaderReceive(response, responsePar)) {\r
- if (MF_DBGLEVEL >= 1) Dbprintf("Couldn't receive tag nonce");\r
- continue;\r
- } \r
- \r
- nonces[i*4] = bytes_to_num(response, 4);\r
- }\r
- \r
- int packLen = iterations * 4;\r
- int packSize = 0;\r
- int packNum = 0;\r
- while (packLen > 0) {\r
- packSize = MIN(USB_CMD_DATA_SIZE, packLen);\r
- LED_B_ON();\r
- cmd_send(CMD_ACK, 77, 0, packSize, nonces - packLen, packSize);\r
- LED_B_OFF();\r
-\r
- packLen -= packSize;\r
- packNum++;\r
- }\r
+void OnSuccessMagic(){\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
LEDsoff();\r
- set_tracing(FALSE);\r
+ set_tracing(FALSE); \r
+}\r
+void OnErrorMagic(uint8_t reason){\r
+ // ACK, ISOK, reason,0,0,0\r
+ cmd_send(CMD_ACK,0,reason,0,0,0);\r
+ OnSuccessMagic();\r
+}\r
+\r
+void MifareCollectNonces(uint32_t arg0, uint32_t arg1){\r
}\r
\r
//\r