X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/5f2cb31bcab1329dc6b1a2757da988b1e249c9b6..40762506601062bb79a0a081a7b508b8e02c29fa:/armsrc/mifarecmd.c?ds=sidebyside diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 1948848e..69b5b53c 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -16,8 +16,9 @@ #include "mifarecmd.h" #include "apps.h" #include "util.h" -#include "desfire.h" -#include "../common/crc.h" +//#include "../client/loclass/des.h" +#include "des.h" +#include "crc.h" //----------------------------------------------------------------------------- // Select, Authenticate, Read a MIFARE tag. @@ -41,7 +42,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) pcs = &mpcs; // clear trace - iso14a_clear_trace(); + clear_trace(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); LED_A_ON(); @@ -76,7 +77,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) // ----------------------------- crypto1 destroy crypto1_destroy(pcs); - if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED"); + if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED"); LED_B_ON(); cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16); @@ -98,7 +99,7 @@ void MifareUC_Auth1(uint8_t arg0, uint8_t *datain){ LED_B_OFF(); LED_C_OFF(); - iso14a_clear_trace(); + clear_trace(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); if(!iso14443a_select_card(uid, NULL, &cuid)) { @@ -151,40 +152,108 @@ void MifareUC_Auth2(uint32_t arg0, uint8_t *datain){ LEDsoff(); } -void MifareUReadBlock(uint8_t arg0,uint8_t *datain) +void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { uint8_t blockNo = arg0; byte_t dataout[16] = {0x00}; uint8_t uid[10] = {0x00}; + uint8_t key[8] = {0x00}; uint32_t cuid; - + bool usePwd = false; + + usePwd = (arg1 == 1); + + // use password + if ( usePwd ) + memcpy(key, datain, 8); + LED_A_ON(); LED_B_OFF(); LED_C_OFF(); - - iso14a_clear_trace(); + + 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"); + if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%d)",len); OnError(1); return; - }; + }; + + // authenticate here. + if ( usePwd ) { + + uint8_t a[8] = { 0x01 }; + uint8_t b[8] = { 0x00 }; + uint8_t enc_b[8] = { 0x00 }; + uint8_t ab[16] = { 0x00 }; + + uint8_t transKey[8] = { 0x00 }; + + uint16_t len; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; + len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,receivedAnswerPar ,NULL); + if (len == 1) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) + Dbprintf("Cmd Error: %02x", receivedAnswer[0]); + OnError(1); + return; + } + +// memcpy(dataout, receivedAnswer, 11); + + // tag nonce. + memcpy(enc_b,receivedAnswer+1,8); + + // decrypt nonce. + des_dec(enc_b, b, key ); + + Dbprintf("enc_B: %02x %02x %02x %02x %02x %02x %02x %02x", enc_b[0],enc_b[1],enc_b[2],enc_b[3],enc_b[4],enc_b[5],enc_b[6],enc_b[7] ); + + rol(b,8); + + memcpy(ab ,a,8); + memcpy(ab+8,b,8); + + Dbprintf("AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[0],ab[1],ab[2],ab[3],ab[4],ab[5],ab[6],ab[7] ); + Dbprintf("AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[8],ab[9],ab[10],ab[11],ab[12],ab[13],ab[14],ab[15] ); + + // encrypt + des_enc(ab, ab, key); + + Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[0],ab[1],ab[2],ab[3],ab[4],ab[5],ab[6],ab[7] ); + Dbprintf("e_AB: %02x %02x %02x %02x %02x %02x %02x %02x", ab[8],ab[9],ab[10],ab[11],ab[12],ab[13],ab[14],ab[15] ); + + len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, ab, receivedAnswer, receivedAnswerPar, NULL); + if (len == 1) { + if (MF_DBGLEVEL >= MF_DBG_ERROR) + Dbprintf("Cmd Error: %02x", receivedAnswer[0]); + OnError(1); + return; + } + + // + memcpy(transKey, receivedAnswer+1, 8); + Dbprintf("TRANSACTIONKEY: %02x %02x %02x %02x %02x %02x %02x %02x", transKey[0],transKey[1],transKey[2],transKey[3], + transKey[4],transKey[5],transKey[6],transKey[7] ); + } + len = mifare_ultra_readblock(cuid, blockNo, dataout); if(len) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error"); OnError(2); return; - }; - + }; + len = mifare_ultra_halt(cuid); if(len) { if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error"); OnError(3); return; - }; + }; cmd_send(CMD_ACK,1,0,0,dataout,16); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -213,7 +282,7 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) pcs = &mpcs; // clear trace - iso14a_clear_trace(); + clear_trace(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); @@ -268,7 +337,7 @@ void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain) byte_t dataout[176] = {0x00};; uint8_t uid[10] = {0x00}; uint32_t cuid; - + LED_A_ON(); LED_B_OFF(); LED_C_OFF(); @@ -276,14 +345,14 @@ void MifareUReadCard(uint8_t arg0, int arg1, uint8_t *datain) if (MF_DBGLEVEL >= MF_DBG_ALL) Dbprintf("Pages %d",Pages); - iso14a_clear_trace(); + 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"); + Dbprintf("Can't select card (RC:%d)",len); OnError(1); return; } @@ -350,7 +419,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) pcs = &mpcs; // clear trace - iso14a_clear_trace(); + clear_trace(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); @@ -400,49 +469,49 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) void MifareUWriteBlock(uint8_t arg0, uint8_t *datain) { - // params - uint8_t blockNo = arg0; + // params + uint8_t blockNo = arg0; byte_t blockdata[16] = {0x00}; - memcpy(blockdata, datain, 16); - - // variables - byte_t isOK = 0; + memcpy(blockdata, datain,16); + + // variables + byte_t isOK = 0; uint8_t uid[10] = {0x00}; - uint32_t cuid; - - iso14a_clear_trace(); - iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); + uint32_t cuid; - 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; - }; - - if(mifare_ultra_writeblock(cuid, blockNo, blockdata)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); - break; - }; + clear_trace(); + iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); - if(mifare_ultra_halt(cuid)) { - if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); - break; - }; - - isOK = 1; - break; - } + 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; + }; + + if(mifare_ultra_writeblock(cuid, blockNo, blockdata)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Write block error"); + break; + }; + + if(mifare_ultra_halt(cuid)) { + if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); + break; + }; + + isOK = 1; + break; + } - if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED"); + if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED"); - cmd_send(CMD_ACK,isOK,0,0,0,0); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); + cmd_send(CMD_ACK,isOK,0,0,0,0); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + LEDsoff(); } void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain) @@ -458,7 +527,7 @@ void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain) uint8_t uid[10] = {0x00}; uint32_t cuid; - iso14a_clear_trace(); + clear_trace(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); LED_A_ON(); @@ -493,7 +562,7 @@ void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain) } // 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) { +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))) & \ (oddparity((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity((NtEnc >> 16) & 0xFF) ^ BIT(Ks1,8))) & \ (oddparity((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity((NtEnc >> 8) & 0xFF) ^ BIT(Ks1,0)))) ? 1 : 0; @@ -529,14 +598,16 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat struct Crypto1State mpcs = {0, 0}; struct Crypto1State *pcs; pcs = &mpcs; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; uint32_t auth1_time, auth2_time; static uint16_t delta_time; + // free eventually allocated BigBuf memory + BigBuf_free(); // clear trace - iso14a_clear_trace(); - iso14a_set_tracing(false); + clear_trace(); + set_tracing(false); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); @@ -550,7 +621,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat WDT_HIT(); davg = dmax = 0; - dmin = 2000; + dmin = 2000; delta_time = 0; for (rtr = 0; rtr < 17; rtr++) { @@ -587,7 +658,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat }; nttmp = prng_successor(nt1, 100); //NXP Mifare is typical around 840,but for some unlicensed/compatible mifare card this can be 160 - for (i = 141; i < 1200; i++) { + for (i = 101; i < 1200; i++) { nttmp = prng_successor(nttmp, 1); if (nttmp == nt2) break; } @@ -605,7 +676,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat } } - if (rtr <= 1) return; + if (rtr <= 1) return; davg = (davg + (rtr - 1)/2) / (rtr - 1); @@ -624,18 +695,9 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat // get crypted nonces for target sector for(i=0; i < 2; i++) { // look for exactly two different nonces - WDT_HIT(); - if(BUTTON_PRESS()) { - DbpString("Nested: cancelled"); - crypto1_destroy(pcs); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); - LEDsoff(); - return; - } - target_nt[i] = 0; while(target_nt[i] == 0) { // continue until we have an unambiguous nonce - + // prepare next select. No need to power down the card. if(mifare_classic_halt(pcs, cuid)) { if (MF_DBGLEVEL >= 1) Dbprintf("Nested: Halt error"); @@ -695,7 +757,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat if (target_nt[i] == 0 && j == dmax+1 && MF_DBGLEVEL >= 3) Dbprintf("Nonce#%d: dismissed (all invalid)", i+1); } } - + LED_C_OFF(); // ----------------------------- crypto1 destroy @@ -716,7 +778,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); - iso14a_set_tracing(TRUE); + set_tracing(TRUE); } //----------------------------------------------------------------------------- @@ -745,8 +807,8 @@ void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) MF_DBGLEVEL = MF_DBG_NONE; // clear trace - iso14a_clear_trace(); - iso14a_set_tracing(TRUE); + clear_trace(); + set_tracing(TRUE); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); @@ -836,8 +898,8 @@ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai uint8_t uid[10]; // clear trace - iso14a_clear_trace(); - iso14a_set_tracing(false); + clear_trace(); + set_tracing(false); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); @@ -929,17 +991,17 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai uint8_t d_block[18] = {0x00}; uint32_t cuid; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; - + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; + // reset FPGA and LED if (workFlags & 0x08) { LED_A_ON(); LED_B_OFF(); LED_C_OFF(); - - iso14a_clear_trace(); - iso14a_set_tracing(TRUE); + + clear_trace(); + set_tracing(TRUE); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); } @@ -949,12 +1011,12 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai if (workFlags & 0x01) { if(!iso14443a_select_card(uid, NULL, &cuid)) { if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card"); - break; + //break; }; if(mifare_classic_halt(NULL, cuid)) { if (MF_DBGLEVEL >= 1) Dbprintf("Halt error"); - break; + //break; }; }; @@ -1048,16 +1110,16 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai uint8_t data[18] = {0x00}; uint32_t cuid = 0; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; if (workFlags & 0x08) { LED_A_ON(); LED_B_OFF(); LED_C_OFF(); - - iso14a_clear_trace(); - iso14a_set_tracing(TRUE); + + clear_trace(); + set_tracing(TRUE); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); } @@ -1113,8 +1175,8 @@ void MifareCIdent(){ // variables byte_t isOK = 1; - uint8_t* receivedAnswer = get_bigbufptr_recvrespbuf(); - uint8_t *receivedAnswerPar = receivedAnswer + MAX_FRAME_SIZE; + uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE]; + uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; ReaderTransmitBitsPar(wupC1,7,0, NULL); if(!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) { @@ -1133,7 +1195,7 @@ void MifareCIdent(){ cmd_send(CMD_ACK,isOK,0,0,0,0); } -// + // // DESFIRE // @@ -1143,7 +1205,7 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){ uint8_t uid[10] = {0x00}; uint32_t cuid; - iso14a_clear_trace(); + clear_trace(); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); int len = iso14443a_select_card(uid, NULL, &cuid); @@ -1190,4 +1252,4 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){ cmd_send(CMD_ACK, isOK, 0, 0, dataout, sizeof(dataout)); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); -} \ No newline at end of file +}