X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/6bfa18eab4750123d0e24090597b0d4c7bd58daf..8e863ab6411a1f4465c9530fcb22898cf6359509:/armsrc/mifarecmd.c diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 344b0f3e..2619a976 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -2,6 +2,9 @@ // Merlok - June 2011, 2012 // Gerhard de Koning Gans - May 2008 // Hagen Fritsch - June 2010 +// Midnitesnake - Dec 2013 +// Andy Davies - Apr 2014 +// Iceman - May 2014 // // This code is licensed to you under the terms of the GNU GPL, version 2 or, // at your option, any later version. See the LICENSE.txt file for the text of @@ -12,6 +15,7 @@ #include "mifarecmd.h" #include "apps.h" +#include "util.h" //----------------------------------------------------------------------------- // Select, Authenticate, Read a MIFARE tag. @@ -36,8 +40,6 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) // clear trace iso14a_clear_trace(); -// iso14a_set_tracing(false); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); LED_A_ON(); @@ -81,62 +83,48 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) // Thats it... FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); -// iso14a_set_tracing(TRUE); - } void MifareUReadBlock(uint8_t arg0,uint8_t *datain) { - // params uint8_t blockNo = arg0; - - // variables - byte_t isOK = 0; - byte_t dataoutbuf[16]; - uint8_t uid[10]; + byte_t dataout[16] = {0x00}; + uint8_t uid[10] = {0x00}; uint32_t cuid; - // clear trace - iso14a_clear_trace(); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - LED_A_ON(); LED_B_OFF(); LED_C_OFF(); - while (true) { - if(!iso14443a_select_card(uid, NULL, &cuid)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); - break; + iso14a_clear_trace(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + + int len = iso14443a_select_card(uid, NULL, &cuid); + if(!len) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card"); + OnError(1); + return; }; - if(mifare_ultra_readblock(cuid, blockNo, dataoutbuf)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Read block error"); - break; + len = mifare_ultra_readblock(cuid, blockNo, dataout); + if(len) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error"); + OnError(2); + return; }; - if(mifare_ultra_halt(cuid)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); - break; + len = mifare_ultra_halt(cuid); + if(len) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error"); + OnError(3); + return; }; - isOK = 1; - break; - } - - if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED"); - - LED_B_ON(); - cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16); - LED_B_OFF(); - - - // Thats it... + cmd_send(CMD_ACK,1,0,0,dataout,16); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); } - //----------------------------------------------------------------------------- // Select, Authenticate, Read a MIFARE tag. // read sector (data = 4 x 16 bytes = 64 bytes, or 16 x 16 bytes = 256 bytes) @@ -150,7 +138,7 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) ui64Key = bytes_to_num(datain, 6); // variables - byte_t isOK; + byte_t isOK = 0; byte_t dataoutbuf[16 * 16]; uint8_t uid[10]; uint32_t cuid; @@ -160,7 +148,6 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) // clear trace iso14a_clear_trace(); -// iso14a_set_tracing(false); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); @@ -192,7 +179,6 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); } - // ----------------------------- crypto1 destroy crypto1_destroy(pcs); @@ -205,61 +191,72 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) // Thats it... FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); -// iso14a_set_tracing(TRUE); } - -void MifareUReadCard(uint8_t arg0, uint8_t *datain) +void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain) { // params uint8_t sectorNo = arg0; - - // variables - byte_t isOK = 0; - byte_t dataoutbuf[16 * 4]; - uint8_t uid[10]; + int Pages = arg1; + int count_Pages = 0; + byte_t dataout[176] = {0x00};; + uint8_t uid[10] = {0x00}; uint32_t cuid; - // clear trace - iso14a_clear_trace(); -// iso14a_set_tracing(false); - - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - LED_A_ON(); LED_B_OFF(); LED_C_OFF(); - while (true) { - if(!iso14443a_select_card(uid, NULL, &cuid)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); - break; - }; - for(int sec=0;sec<16;sec++){ - if(mifare_ultra_readblock(cuid, sectorNo * 4 + sec, dataoutbuf + 4 * sec)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Read block %d error",sec); - break; - }; - } - if(mifare_ultra_halt(cuid)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); - break; - }; + if (MF_DBGLEVEL >= MF_DBG_ALL) + Dbprintf("Pages %d",Pages); + + iso14a_clear_trace(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - isOK = 1; - break; - } - - if (MF_DBGLEVEL >= 2) DbpString("READ CARD FINISHED"); + int len = iso14443a_select_card(uid, NULL, &cuid); + + if (!len) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) + Dbprintf("Can't select card"); + OnError(1); + return; + } + + for (int i = 0; i < Pages; i++){ + + len = mifare_ultra_readblock(cuid, sectorNo * 4 + i, dataout + 4 * i); + + if (len) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) + Dbprintf("Read block %d error",i); + OnError(2); + return; + } else { + count_Pages++; + } + } + + len = mifare_ultra_halt(cuid); + if (len) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) + Dbprintf("Halt error"); + OnError(3); + return; + } + + if (MF_DBGLEVEL >= MF_DBG_ALL) { + Dbprintf("Pages read %d", count_Pages); + } - LED_B_ON(); - cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,64); - LED_B_OFF(); + len = 16*4; //64 bytes + + // Read a UL-C + if (Pages == 44 && count_Pages > 16) + len = 176; - // Thats it... + cmd_send(CMD_ACK, 1, 0, 0, dataout, len); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); - } @@ -288,7 +285,6 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) // clear trace iso14a_clear_trace(); -// iso14a_set_tracing(false); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); @@ -334,29 +330,22 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) // Thats it... FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); -// iso14a_set_tracing(TRUE); - } - void MifareUWriteBlock(uint8_t arg0, uint8_t *datain) { // params uint8_t blockNo = arg0; - byte_t blockdata[16]; + byte_t blockdata[16] = {0x00}; - memset(blockdata,'\0',16); memcpy(blockdata, datain,16); // variables byte_t isOK = 0; - uint8_t uid[10]; + uint8_t uid[10] = {0x00}; uint32_t cuid; - // clear trace iso14a_clear_trace(); - // iso14a_set_tracing(false); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); LED_A_ON(); @@ -385,35 +374,25 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t *datain) if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED"); - LED_B_ON(); cmd_send(CMD_ACK,isOK,0,0,0,0); - LED_B_OFF(); - - - // Thats it... FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); -// iso14a_set_tracing(TRUE); } - void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain) { // params uint8_t blockNo = arg0; - byte_t blockdata[4]; + byte_t blockdata[4] = {0x00}; memcpy(blockdata, datain,4); // variables byte_t isOK = 0; - uint8_t uid[10]; + uint8_t uid[10] = {0x00}; uint32_t cuid; - // clear trace iso14a_clear_trace(); - // iso14a_set_tracing(false); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); LED_A_ON(); @@ -442,19 +421,11 @@ void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain) if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED"); - LED_B_ON(); cmd_send(CMD_ACK,isOK,0,0,0,0); - LED_B_OFF(); - - - // Thats it... FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); -// iso14a_set_tracing(TRUE); - } - // Return 1 if the nonce is invalid else return 0 int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity) { return ((oddparity((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity((NtEnc >> 24) & 0xFF) ^ BIT(Ks1,16))) & \ @@ -510,6 +481,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat // statistics on nonce distance if (calibrate) { // for first call only. Otherwise reuse previous calibration LED_B_ON(); + WDT_HIT(); davg = dmax = 0; dmin = 2000; @@ -733,7 +705,6 @@ void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) cmd_send(CMD_ACK,isOK,0,0,datain + i * 6,6); LED_B_OFF(); - // Thats it... FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); @@ -750,7 +721,6 @@ void MifareSetDbgLvl(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai Dbprintf("Debug level: %d", MF_DBGLEVEL); } - //----------------------------------------------------------------------------- // Work with emulator memory // @@ -759,23 +729,19 @@ void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) emlClearMem(); } - void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){ emlSetMem(datain, arg0, arg1); // data, block num, blocks count } - void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){ - - byte_t buf[48]; + byte_t buf[USB_CMD_DATA_SIZE]; emlGetMem(buf, arg0, arg1); // data, block num, blocks count (max 4) LED_B_ON(); - cmd_send(CMD_ACK,arg0,arg1,0,buf,48); + cmd_send(CMD_ACK,arg0,arg1,0,buf,USB_CMD_DATA_SIZE); LED_B_OFF(); } - //----------------------------------------------------------------------------- // Load a card into the emulator memory // @@ -884,32 +850,26 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai // variables byte_t isOK = 0; - uint8_t uid[10]; - uint8_t d_block[18]; + uint8_t uid[10] = {0x00}; + uint8_t d_block[18] = {0x00}; uint32_t cuid; - memset(uid, 0x00, 10); uint8_t *receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + // reset FPGA and LED if (workFlags & 0x08) { - // clear trace - iso14a_clear_trace(); - iso14a_set_tracing(TRUE); - - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - LED_A_ON(); LED_B_OFF(); LED_C_OFF(); - SpinDelay(300); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(100); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); + iso14a_clear_trace(); + iso14a_set_tracing(TRUE); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); } while (true) { + // get UID from chip if (workFlags & 0x01) { if(!iso14443a_select_card(uid, NULL, &cuid)) { @@ -988,7 +948,6 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai LED_B_OFF(); if ((workFlags & 0x10) || (!isOK)) { - // Thats it... FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); } @@ -1011,28 +970,20 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai // variables byte_t isOK = 0; - uint8_t data[18]; + uint8_t data[18] = {0x00}; uint32_t cuid = 0; - memset(data, 0x00, 18); uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; if (workFlags & 0x08) { - // clear trace - iso14a_clear_trace(); - iso14a_set_tracing(TRUE); - - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - LED_A_ON(); LED_B_OFF(); LED_C_OFF(); - SpinDelay(300); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - SpinDelay(100); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); + iso14a_clear_trace(); + iso14a_set_tracing(TRUE); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); } while (true) { @@ -1073,9 +1024,40 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai LED_B_OFF(); if ((workFlags & 0x10) || (!isOK)) { - // Thats it... FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); } } +void MifareCIdent(){ + + // card commands + uint8_t wupC1[] = { 0x40 }; + uint8_t wupC2[] = { 0x43 }; + + // variables + byte_t isOK = 1; + + uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); + uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + + ReaderTransmitBitsPar(wupC1,7,0, NULL); + if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { + isOK = 0; + }; + + ReaderTransmit(wupC2, sizeof(wupC2), NULL); + if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { + isOK = 0; + }; + + if (mifare_classic_halt(NULL, 0)) { + isOK = 0; + }; + + cmd_send(CMD_ACK,isOK,0,0,0,0); +} + + // +// DESFIRE +//