X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/cdc9a7562d70ec1b4c58841acc64150774e377b6..c8a0f5503172f25620670a9ba992d8c923b5df95:/client/mifare4.c diff --git a/client/mifare4.c b/client/mifare4.c index 3489c857..e1021196 100644 --- a/client/mifare4.c +++ b/client/mifare4.c @@ -16,6 +16,18 @@ #include "ui.h" #include "polarssl/libpcrypto.h" +int CalculateMAC(mf4Session *session, uint8_t *data, int datalen, uint8_t *mac, bool verbose) { + if (!session || !session->Authenticated || !mac || !data || !datalen) + return 1; + + memset(mac, 0x00, 8); + + if (verbose) + PrintAndLog("MAC data[%d]: %s", datalen, sprint_hex(data, datalen)); + + return aes_cmac8(NULL, session->Key, data, mac, datalen); +} + int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateField, bool leaveSignalON, bool verbose) { uint8_t data[257] = {0}; int datalen = 0; @@ -71,7 +83,7 @@ int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateF if (verbose) PrintAndLog(">phase2: %s", sprint_hex(cmd2, 33)); - res = ExchangeRAW14a(cmd2, sizeof(cmd2), false, false, data, sizeof(data), &datalen); + res = ExchangeRAW14a(cmd2, sizeof(cmd2), false, true, data, sizeof(data), &datalen); if (res) { PrintAndLog("ERROR exchande raw error: %d", res); DropField(); @@ -109,6 +121,7 @@ int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateF session->KeyNum = keyn[1] + (keyn[0] << 8); memmove(session->Rnd1, Rnd1, 16); memmove(session->Rnd2, Rnd2, 16); + memmove(session->Key, key, 16); } PrintAndLog("Authentication OK"); @@ -116,3 +129,38 @@ int MifareAuth4(mf4Session *session, uint8_t *keyn, uint8_t *key, bool activateF 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 mfNumBlocksPerSector(uint8_t sectorNo) { + if (sectorNo < 32) + return 4; + else + return 16; +} + +uint8_t mfFirstBlockOfSector(uint8_t sectorNo) { + if (sectorNo < 32) + return sectorNo * 4; + else + return 32 * 4 + (sectorNo - 32) * 16; +} + +uint8_t mfSectorTrailer(uint8_t blockNo) { + if (blockNo < 32*4) { + return (blockNo | 0x03); + } else { + return (blockNo | 0x0f); + } +} + +bool mfIsSectorTrailer(uint8_t blockNo) { + return (blockNo == mfSectorTrailer(blockNo)); +} + +uint8_t mfSectorNum(uint8_t blockNo) { + if (blockNo < 32 * 4) + return blockNo / 4; + else + return 32 + (blockNo - 32 * 4) / 16; + +}