X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/275d9e61c245e65fe09ccb5c49f09dfe505a642d..f98702bace48fde3ec1492d1c732e23cd2eb8613:/armsrc/mifarecmd.c diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index edafe0a3..8fe502ca 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -15,29 +15,50 @@ #include "mifarecmd.h" -#include "apps.h" #include "util.h" #include "parity.h" #include "crc.h" +#include "fpgaloader.h" +#define HARDNESTED_AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation) +#define HARDNESTED_PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication + +/* // the block number for the ISO14443-4 PCB static uint8_t pcb_blocknum = 0; // Deselect card by sending a s-block. the crc is precalced for speed static uint8_t deselect_cmd[] = {0xc2,0xe0,0xb4}; +static void OnSuccess(){ + pcb_blocknum = 0; + ReaderTransmit(deselect_cmd, 3 , NULL); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); +} +*/ + +static void OnError(uint8_t reason){ + // pcb_blocknum = 0; + // ReaderTransmit(deselect_cmd, 3 , NULL); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LED_D_OFF(); + cmd_send(CMD_ACK,0,reason,0,0,0); + LED_A_OFF(); +} + //----------------------------------------------------------------------------- // Select, Authenticate, Read a MIFARE tag. // read block //----------------------------------------------------------------------------- void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) { - // params + LED_A_ON(); + uint8_t blockNo = arg0; uint8_t keyType = arg1; uint64_t ui64Key = 0; ui64Key = bytes_to_num(datain, 6); - // variables byte_t isOK = 0; byte_t dataoutbuf[16]; uint8_t uid[10]; @@ -50,10 +71,6 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) clear_trace(); - LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); - while (true) { if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) { if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); @@ -94,21 +111,18 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){ + LED_A_ON(); bool turnOffField = (arg0 == 1); - LED_A_ON(); LED_B_OFF(); LED_C_OFF(); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - - if(!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) { + if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card"); OnError(0); return; }; - if(!mifare_ultra_auth(keybytes)){ + if (!mifare_ultra_auth(keybytes)){ if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed"); OnError(1); return; @@ -116,9 +130,11 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){ if (turnOffField) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); + LED_D_OFF(); } + cmd_send(CMD_ACK,1,0,0,0,0); + LED_A_OFF(); } // Arg0 = BlockNo, @@ -126,17 +142,15 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){ // datain = PWD bytes, void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { + LED_A_ON(); + uint8_t blockNo = arg0; byte_t dataout[16] = {0x00}; bool useKey = (arg1 == 1); //UL_C bool usePwd = (arg1 == 2); //UL_EV1/NTAG - LEDsoff(); - LED_A_ON(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - clear_trace(); - int len = iso14443a_select_card(NULL, NULL, NULL, true, 0, true); if(!len) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len); @@ -145,7 +159,7 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) } // UL-C authentication - if ( useKey ) { + if (useKey) { uint8_t key[16] = {0x00}; memcpy(key, datain, sizeof(key) ); @@ -156,7 +170,7 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) } // UL-EV1 / NTAG authentication - if ( usePwd ) { + if (usePwd) { uint8_t pwd[4] = {0x00}; memcpy(pwd, datain, 4); uint8_t pack[4] = {0,0,0,0}; @@ -166,13 +180,13 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) } } - if( mifare_ultra_readblock(blockNo, dataout) ) { + if (mifare_ultra_readblock(blockNo, dataout)) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error"); OnError(2); return; } - if( mifare_ultra_halt() ) { + if (mifare_ultra_halt()) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error"); OnError(3); return; @@ -180,7 +194,8 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) cmd_send(CMD_ACK,1,0,0,dataout,16); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); + LED_D_OFF(); + LED_A_OFF(); } //----------------------------------------------------------------------------- @@ -256,13 +271,11 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) // datain = KEY bytes void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) { - LEDsoff(); LED_A_ON(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); // free eventually allocated BigBuf memory BigBuf_free(); - clear_trace(); // params uint8_t blockNo = arg0; @@ -285,7 +298,7 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) } // UL-C authentication - if ( useKey ) { + if (useKey) { uint8_t key[16] = {0x00}; memcpy(key, datain, sizeof(key) ); @@ -337,14 +350,14 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) return; } - if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Blocks read %d", countblocks); + if (MF_DBGLEVEL >= MF_DBG_DEBUG) Dbprintf("Blocks read %d", countblocks); - countblocks *= 4; + cmd_send(CMD_ACK, 1, countblocks*4, BigBuf_max_traceLen(), 0, 0); - cmd_send(CMD_ACK, 1, countblocks, BigBuf_max_traceLen(), 0, 0); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); + LED_D_OFF(); BigBuf_free(); + LED_A_OFF(); } //----------------------------------------------------------------------------- @@ -677,7 +690,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, } if (slow) { - timeout = GetCountSspClk() + PRE_AUTHENTICATION_LEADTIME; + timeout = GetCountSspClk() + HARDNESTED_PRE_AUTHENTICATION_LEADTIME; while(GetCountSspClk() < timeout); } @@ -694,11 +707,12 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, continue; } - // send a dummy byte as reader response in order to trigger the cards authentication timeout - uint8_t dummy_answer = 0; - ReaderTransmit(&dummy_answer, 1, NULL); - timeout = GetCountSspClk() + AUTHENTICATION_TIMEOUT; + // send an incomplete dummy response in order to trigger the card's authentication failure timeout + uint8_t dummy_answer[1] = {0}; + ReaderTransmit(dummy_answer, 1, NULL); + timeout = GetCountSspClk() + HARDNESTED_AUTHENTICATION_TIMEOUT; + num_nonces++; if (num_nonces % 2) { memcpy(buf+i, receivedAnswer, 4); @@ -966,16 +980,17 @@ void MifareChkKeys(uint16_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) uint8_t set14aTimeout = (arg1 >> 8) & 0xff; uint8_t keyCount = arg2; + LED_A_ON(); + // clear debug level int OLD_MF_DBGLEVEL = MF_DBGLEVEL; MF_DBGLEVEL = MF_DBG_NONE; - LED_A_ON(); - LED_B_OFF(); - LED_C_OFF(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - if (clearTrace) clear_trace(); + if (clearTrace) { + clear_trace(); + } set_tracing(true); if (set14aTimeout){ @@ -987,30 +1002,28 @@ void MifareChkKeys(uint16_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) uint8_t sectorCnt = blockNo; int res = MifareMultisectorChk(datain, keyCount, sectorCnt, keyType, OLD_MF_DBGLEVEL, &keyIndex); - LED_B_ON(); if (res >= 0) { cmd_send(CMD_ACK, 1, 0, 0, keyIndex, 80); } else { cmd_send(CMD_ACK, 0, 0, 0, NULL, 0); } - LED_B_OFF(); } else { int res = MifareChkBlockKeys(datain, keyCount, blockNo, keyType, OLD_MF_DBGLEVEL); - LED_B_ON(); if (res > 0) { cmd_send(CMD_ACK, 1, 0, 0, datain + (res - 1) * 6, 6); } else { cmd_send(CMD_ACK, 0, 0, 0, NULL, 0); } - LED_B_OFF(); } FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); + LED_D_OFF(); // restore debug level MF_DBGLEVEL = OLD_MF_DBGLEVEL; + + LED_A_OFF(); } //----------------------------------------------------------------------------- @@ -1145,7 +1158,7 @@ static bool isBlockTrailer(int blockN) { if (blockN >= 128 && blockN <= 256) { return ((blockN & 0x0F) == 0x0F); } - return FALSE; + return false; } void MifareCWipe(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){ @@ -1510,6 +1523,14 @@ void MifareCIdent(){ uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; + + LED_A_ON(); + LED_B_OFF(); + LED_C_OFF(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + + clear_trace(); + set_tracing(true); ReaderTransmitBitsPar(wupC1,7,0, NULL); if(ReaderReceive(receivedAnswer, receivedAnswerPar) && (receivedAnswer[0] == 0x0a)) { @@ -1523,8 +1544,13 @@ void MifareCIdent(){ // From iceman1001: removed the if, since some magic tags misbehavies and send an answer to it. mifare_classic_halt(NULL, 0); - + + LED_B_ON(); cmd_send(CMD_ACK,isOK,0,0,0,0); + LED_B_OFF(); + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); } // @@ -1581,17 +1607,3 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){ LEDsoff(); } -void OnSuccess(){ - pcb_blocknum = 0; - ReaderTransmit(deselect_cmd, 3 , NULL); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); -} - -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(); -}