X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/9c0f13d5dd68761154694c71a8c4fba4f876ed2d..33443e7:/client/mifarehost.c diff --git a/client/mifarehost.c b/client/mifarehost.c index 7f784850..411a44c1 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -12,10 +12,43 @@ #include #include #include -#include "mifarehost.h" + +#include "crapto1/crapto1.h" #include "proxmark3.h" +#include "usb_cmd.h" +#include "cmdmain.h" +#include "ui.h" +#include "util.h" +#include "iso14443crc.h" +#include "mifarehost.h" + +// mifare tracer flags used in mfTraceDecode() +#define TRACE_IDLE 0x00 +#define TRACE_AUTH1 0x01 +#define TRACE_AUTH2 0x02 +#define TRACE_AUTH_OK 0x03 +#define TRACE_READ_DATA 0x04 +#define TRACE_WRITE_OK 0x05 +#define TRACE_WRITE_DATA 0x06 +#define TRACE_ERROR 0xFF + // MIFARE +int mfCheckKeys (uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key){ + + *key = 0; + + UsbCommand c = {CMD_MIFARE_CHKKEYS, {((blockNo & 0xff) | ((keyType&0xff)<<8)), clear_trace, keycnt}}; + memcpy(c.d.asBytes, keyBlock, 6 * keycnt); + SendCommand(&c); + + UsbCommand resp; + if (!WaitForResponseTimeout(CMD_ACK,&resp,3000)) return 1; + if ((resp.arg[0] & 0xff) != 0x01) return 2; + *key = bytes_to_num(resp.d.asBytes, 6); + return 0; +} + int compar_int(const void * a, const void * b) { // didn't work: (the result is truncated to 32 bits) //return (*(uint64_t*)b - *(uint64_t*)a); @@ -69,7 +102,7 @@ void* nested_worker_thread(void *arg) int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t * resultKey, bool calibrate) { - uint16_t i, len; + uint16_t i; uint32_t uid; UsbCommand resp; @@ -77,31 +110,29 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo struct Crypto1State *p1, *p2, *p3, *p4; // flush queue - WaitForResponseTimeout(CMD_ACK,NULL,100); + WaitForResponseTimeout(CMD_ACK, NULL, 100); UsbCommand c = {CMD_MIFARE_NESTED, {blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, calibrate}}; memcpy(c.d.asBytes, key, 6); SendCommand(&c); - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - len = resp.arg[1]; - if (len == 2) { - memcpy(&uid, resp.d.asBytes, 4); - PrintAndLog("uid:%08x len=%d trgbl=%d trgkey=%x", uid, len, (uint16_t)resp.arg[2] & 0xff, (uint16_t)resp.arg[2] >> 8); - - for (i = 0; i < 2; i++) { - statelists[i].blockNo = resp.arg[2] & 0xff; - statelists[i].keyType = (resp.arg[2] >> 8) & 0xff; - statelists[i].uid = uid; + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { + return -1; + } - memcpy(&statelists[i].nt, (void *)(resp.d.asBytes + 4 + i * 8 + 0), 4); - memcpy(&statelists[i].ks1, (void *)(resp.d.asBytes + 4 + i * 8 + 4), 4); - } - } - else { - PrintAndLog("Got 0 keys from proxmark."); - return 1; - } + if (resp.arg[0]) { + return resp.arg[0]; // error during nested + } + + memcpy(&uid, resp.d.asBytes, 4); + PrintAndLog("uid:%08x trgbl=%d trgkey=%x", uid, (uint16_t)resp.arg[2] & 0xff, (uint16_t)resp.arg[2] >> 8); + + for (i = 0; i < 2; i++) { + statelists[i].blockNo = resp.arg[2] & 0xff; + statelists[i].keyType = (resp.arg[2] >> 8) & 0xff; + statelists[i].uid = uid; + memcpy(&statelists[i].nt, (void *)(resp.d.asBytes + 4 + i * 8 + 0), 4); + memcpy(&statelists[i].ks1, (void *)(resp.d.asBytes + 4 + i * 8 + 4), 4); } // calc keys @@ -183,7 +214,7 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo crypto1_get_lfsr(statelists[0].head.slhead + i, &key64); num_to_bytes(key64, 6, keyBlock); key64 = 0; - if (!mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, 1, keyBlock, &key64)) { + if (!mfCheckKeys(statelists[0].blockNo, statelists[0].keyType, false, 1, keyBlock, &key64)) { num_to_bytes(key64, 6, resultKey); break; } @@ -195,21 +226,6 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t * key, uint8_t trgBlockNo return 0; } -int mfCheckKeys (uint8_t blockNo, uint8_t keyType, uint8_t keycnt, uint8_t * keyBlock, uint64_t * key){ - - *key = 0; - - UsbCommand c = {CMD_MIFARE_CHKKEYS, {blockNo, keyType, keycnt}}; - memcpy(c.d.asBytes, keyBlock, 6 * keycnt); - SendCommand(&c); - - UsbCommand resp; - if (!WaitForResponseTimeout(CMD_ACK,&resp,3000)) return 1; - if ((resp.arg[0] & 0xff) != 0x01) return 2; - *key = bytes_to_num(resp.d.asBytes, 6); - return 0; -} - // EMULATOR int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount) { @@ -231,29 +247,22 @@ int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount) { // "MAGIC" CARD -int mfCSetUID(uint8_t *uid, uint8_t *oldUID, bool wantWipe) { - - uint8_t oldblock0[16] = {0x00}; - uint8_t block0[16] = {0x00}; - memcpy(block0, uid, 4); - block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // Mifare UID BCC - // mifare classic SAK(byte 5) and ATQA(byte 6 and 7) - //block0[5] = 0x08; - //block0[6] = 0x04; - //block0[7] = 0x00; - - block0[5] = 0x01; //sak - block0[6] = 0x01; - block0[7] = 0x0f; - - int old = mfCGetBlock(0, oldblock0, CSETBLOCK_SINGLE_OPER); - if ( old == 0) { - memcpy(block0+8, oldblock0+8, 8); - PrintAndLog("block 0: %s", sprint_hex(block0,16)); +int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) { + uint8_t isOK = 0; + + UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, 0, blockNo}}; + SendCommand(&c); + + UsbCommand resp; + if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { + isOK = resp.arg[0] & 0xff; + memcpy(data, resp.d.asBytes, 16); + if (!isOK) return 2; } else { - PrintAndLog("Couldn't get olddata. Will write over the last bytes of Block 0."); + PrintAndLog("Command execute timeout"); + return 1; } - return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER); + return 0; } int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uint8_t params) { @@ -277,22 +286,32 @@ int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uin return 0; } -int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) { - uint8_t isOK = 0; - - UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, 0, blockNo}}; - SendCommand(&c); +int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, bool wantWipe) { + uint8_t oldblock0[16] = {0x00}; + uint8_t block0[16] = {0x00}; - UsbCommand resp; - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - isOK = resp.arg[0] & 0xff; - memcpy(data, resp.d.asBytes, 16); - if (!isOK) return 2; + int old = mfCGetBlock(0, oldblock0, CSETBLOCK_SINGLE_OPER); + if (old == 0) { + memcpy(block0, oldblock0, 16); + PrintAndLog("old block 0: %s", sprint_hex(block0,16)); } else { - PrintAndLog("Command execute timeout"); - return 1; + PrintAndLog("Couldn't get old data. Will write over the last bytes of Block 0."); } - return 0; + + // fill in the new values + // UID + memcpy(block0, uid, 4); + // Mifare UID BCC + block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; + // mifare classic SAK(byte 5) and ATQA(byte 6 and 7, reversed) + if (sak!=NULL) + block0[5]=sak[0]; + if (atqa!=NULL) { + block0[6]=atqa[1]; + block0[7]=atqa[0]; + } + PrintAndLog("new block 0: %s", sprint_hex(block0,16)); + return mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER); } // SNIFFER @@ -336,6 +355,23 @@ int isBlockTrailer(int blockN) { return ((blockN & 0x03) == 0x03); } +int saveTraceCard(void) { + FILE * f; + + if ((!strlen(traceFileName)) || (isTraceCardEmpty())) return 0; + + f = fopen(traceFileName, "w+"); + if ( !f ) return 1; + + for (int i = 0; i < 64; i++) { // blocks + for (int j = 0; j < 16; j++) // bytes + fprintf(f, "%02x", *(traceCard + i * 16 + j)); + fprintf(f,"\n"); + } + fclose(f); + return 0; +} + int loadTraceCard(uint8_t *tuid) { FILE * f; char buf[64] = {0x00}; @@ -351,10 +387,7 @@ int loadTraceCard(uint8_t *tuid) { FillFileNameByUID(traceFileName, tuid, ".eml", 7); f = fopen(traceFileName, "r"); - if (!f) { - fclose(f); - return 1; - } + if (!f) return 1; blockNum = 0; @@ -385,26 +418,6 @@ int loadTraceCard(uint8_t *tuid) { return 0; } -int saveTraceCard(void) { - FILE * f; - - if ((!strlen(traceFileName)) || (isTraceCardEmpty())) return 0; - - f = fopen(traceFileName, "w+"); - if ( !f ) { - fclose(f); - return 1; - } - - for (int i = 0; i < 64; i++) { // blocks - for (int j = 0; j < 16; j++) // bytes - fprintf(f, "%02x", *(traceCard + i * 16 + j)); - fprintf(f,"\n"); - } - fclose(f); - return 0; -} - int mfTraceInit(uint8_t *tuid, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile) { if (traceCrypto1) @@ -624,3 +637,23 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) { return 0; } + +int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len){ + /* + uint32_t nt; // tag challenge + uint32_t ar_enc; // encrypted reader response + uint32_t at_enc; // encrypted tag response + */ + if (traceCrypto1) { + crypto1_destroy(traceCrypto1); + } + ks2 = ar_enc ^ prng_successor(nt, 64); + ks3 = at_enc ^ prng_successor(nt, 96); + traceCrypto1 = lfsr_recovery64(ks2, ks3); + + mf_crypto1_decrypt(traceCrypto1, data, len, 0); + + PrintAndLog("Decrypted data: [%s]", sprint_hex(data,len) ); + crypto1_destroy(traceCrypto1); + return 0; +}