X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/981bd4292e1f6d898453479c7bad86480d0c959f..7c756d68925891ec3d3aa0bec89ec215fd449bd1:/armsrc/mifareutil.c diff --git a/armsrc/mifareutil.c b/armsrc/mifareutil.c index b847043b..537720df 100644 --- a/armsrc/mifareutil.c +++ b/armsrc/mifareutil.c @@ -9,12 +9,12 @@ // Work with mifare cards. //----------------------------------------------------------------------------- -#include "proxmark3.h" +#include "../include/proxmark3.h" #include "apps.h" #include "util.h" #include "string.h" -#include "iso14443crc.h" +#include "../common/iso14443crc.h" #include "iso14443a.h" #include "crapto1.h" #include "mifareutil.h" @@ -84,26 +84,36 @@ int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, int mifare_sendcmd_short_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *timing) { - uint8_t dcmd[8];//, ecmd[4]; - //uint32_t par=0; - + uint8_t dcmd[8]; dcmd[0] = cmd; - dcmd[1] = data[0]; - dcmd[2] = data[1]; - dcmd[3] = data[2]; - dcmd[4] = data[3]; - dcmd[5] = data[4]; + memcpy(dcmd+1,data,5); AppendCrc14443a(dcmd, 6); - //Dbprintf("Data command: %02x", dcmd[0]); - //Dbprintf("Data R: %02x %02x %02x %02x %02x %02x %02x", dcmd[1],dcmd[2],dcmd[3],dcmd[4],dcmd[5],dcmd[6],dcmd[7]); - - //memcpy(ecmd, dcmd, sizeof(dcmd)); ReaderTransmit(dcmd, sizeof(dcmd), NULL); int len = ReaderReceive(answer); - if(!len) - { + if(!len) { if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout."); return 2; + } + return len; +} + +int mifare_sendcmd_short_mfucauth(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint32_t *timing) +{ + uint8_t dcmd[19]; + int len; + dcmd[0] = cmd; + memcpy(dcmd+1,data,16); + AppendCrc14443a(dcmd, 17); + + ReaderTransmit(dcmd, sizeof(dcmd), timing); + len = ReaderReceive(answer); + if(!len) { + if (MF_DBGLEVEL >= 1) Dbprintf("Authentication failed. Card timeout."); + len = ReaderReceive(answer); + } + if(len==1) { + if (MF_DBGLEVEL >= 1) Dbprintf("NAK - Authentication failed."); + return 1; } return len; } @@ -280,6 +290,55 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo memcpy(blockData, receivedAnswer, 16); return 0; +} + +int mifare_ultra_auth1(uint32_t uid, uint8_t *blockData){ + // variables + int len; + + uint8_t* receivedAnswer = mifare_get_bigbufptr(); + + // command MIFARE_CLASSIC_READBLOCK + len = mifare_sendcmd_short(NULL, 1, 0x1A, 0x00, receivedAnswer,NULL); + if (len == 1) { + if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); + return 1; + } + if (len == 11) { + if (MF_DBGLEVEL >= 1) Dbprintf("Auth1 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4], + receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9], + receivedAnswer[10]); + memcpy(blockData, receivedAnswer, 11); + return 0; + } + //else something went wrong??? + return 1; +} + +int mifare_ultra_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){ + // variables + int len; + + uint8_t* receivedAnswer = mifare_get_bigbufptr(); + + + // command MIFARE_CLASSIC_READBLOCK + len = mifare_sendcmd_short_mfucauth(NULL, 1, 0xAF, key, receivedAnswer,NULL); + if (len == 1) { + if (MF_DBGLEVEL >= 1) Dbprintf("Cmd Error: %02x", receivedAnswer[0]); + return 1; + } + if (len == 11){ + if (MF_DBGLEVEL >= 1) Dbprintf("Auth2 Resp: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + receivedAnswer[0],receivedAnswer[1],receivedAnswer[2],receivedAnswer[3],receivedAnswer[4], + receivedAnswer[5],receivedAnswer[6],receivedAnswer[7],receivedAnswer[8],receivedAnswer[9], + receivedAnswer[10]); + memcpy(blockData, receivedAnswer, 11); + return 0; + } + //something went wrong? + return 1; } int mifare_ultra_readblock(uint32_t uid, uint8_t blockNo, uint8_t *blockData) @@ -453,6 +512,27 @@ int mifare_ultra_halt(uint32_t uid) return 0; } + +// Mifare Memory Structure: up to 32 Sectors with 4 blocks each (1k and 2k cards), +// plus evtl. 8 sectors with 16 blocks each (4k cards) +uint8_t NumBlocksPerSector(uint8_t sectorNo) +{ + if (sectorNo < 32) + return 4; + else + return 16; +} + +uint8_t FirstBlockOfSector(uint8_t sectorNo) +{ + if (sectorNo < 32) + return sectorNo * 4; + else + return 32*4 + (sectorNo - 32) * 16; + +} + + // work with emulator memory void emlSetMem(uint8_t *data, int blockNum, int blocksCount) { uint8_t* emCARD = eml_get_bigbufptr_cardmem(); @@ -522,7 +602,7 @@ uint64_t emlGetKey(int sectorNum, int keyType) { uint8_t key[6]; uint8_t* emCARD = eml_get_bigbufptr_cardmem(); - memcpy(key, emCARD + 3 * 16 + sectorNum * 4 * 16 + keyType * 10, 6); + memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6); return bytes_to_num(key, 6); }