X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/acd7ccdbc9b98f2e10df25e7cf2a6d17824f1b7e..52f2df615b806434ec7017349d6920a5cb9ab1c2:/armsrc/mifarecmd.c diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index e51ae18b..1e42d5b4 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -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,174 @@ 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){ +// 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 - 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; + // params + uint8_t workFlags = arg0; + uint8_t blockNo = arg1; - // card commands - uint8_t wupC1[] = { 0x40 }; - uint8_t wupC2[] = { 0x43 }; - uint8_t wipeC[] = { 0x41 }; + 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; - }; - }; + // 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); + }; - // 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(wipeC, sizeof(wipeC), NULL); + if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wipeC error"); + OnErrorMagic(MAGIC_WIPE); + }; + }; - ReaderTransmit(wupC2, sizeof(wupC2), NULL); - if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { - if (MF_DBGLEVEL >= 1) Dbprintf("wupC2 error"); - break; - }; - } + // 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); + }; - 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; + ReaderTransmit(wupC2, sizeof(wupC2), NULL); + if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("wupC2 error"); + OnErrorMagic(MAGIC_WUPC); }; + } + + 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(d_block, datain, 16); - AppendCrc14443a(d_block, 16); + memcpy(data, datain, 16); + AppendCrc14443a(data, 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; - }; + 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 & 0x04) { - if (mifare_classic_halt(NULL, cuid)) { - if (MF_DBGLEVEL >= 4) Dbprintf("INFO - Tag answered the 'Halt' command"); - break; - }; - } - - isOK = 1; - break; - } + 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; + // 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; - }; - } + 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); + }; - // 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; + 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 +1192,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){ } //