X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/e98572a1e2dde603f31cc06f330c6abd295139de..c2dac3f8249ca25f14517b21508526719fae2c7d:/client/mifarehost.c?ds=sidebyside diff --git a/client/mifarehost.c b/client/mifarehost.c index 830b61cd..431db9dc 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -15,8 +15,6 @@ #include "mifarehost.h" #include "proxmark3.h" -#define llx PRIx64 - // MIFARE int compar_int(const void * a, const void * b) { // didn't work: (the result is truncated to 32 bits) @@ -79,22 +77,19 @@ 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); UsbCommand c = {CMD_MIFARE_NESTED, {blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, calibrate}}; memcpy(c.d.asBytes, key, 6); + clearCommandBuffer(); SendCommand(&c); - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - return -1; - } + if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1; - if (resp.arg[0]) { - return resp.arg[0]; // error during nested - } - + // error during nested + if (resp.arg[0]) return resp.arg[0]; + 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); + PrintAndLog("UID: %08x Block:%d Key: %c", uid, (uint16_t)resp.arg[2] & 0xff, (resp.arg[2] >> 8) ?'A':'B' ); for (i = 0; i < 2; i++) { statelists[i].blockNo = resp.arg[2] & 0xff; @@ -237,14 +232,16 @@ int mfEmlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidt // "MAGIC" CARD -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}; +int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, uint8_t wipecard) { - int old = mfCGetBlock(0, oldblock0, CSETBLOCK_SINGLE_OPER); + uint8_t params = MAGIC_SINGLE; + uint8_t block0[16]; + memset(block0, 0x00, sizeof(block0)); + + + int old = mfCGetBlock(0, block0, params); if (old == 0) { - memcpy(block0, oldblock0, 16); - PrintAndLog("old block 0: %s", sprint_hex(block0,16)); + PrintAndLog("old block 0: %s", sprint_hex(block0, sizeof(block0))); } else { PrintAndLog("Couldn't get old data. Will write over the last bytes of Block 0."); } @@ -255,26 +252,30 @@ int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, bool w // 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) + if ( sak != NULL ) block0[5]=sak[0]; - if (atqa!=NULL) { + + 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); + + if ( wipecard ) params |= MAGIC_WIPE; + if ( oldUID == NULL) params |= MAGIC_UID; + + return mfCSetBlock(0, block0, oldUID, params); } -int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uint8_t params) { +int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params) { uint8_t isOK = 0; - UsbCommand c = {CMD_MIFARE_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}}; + UsbCommand c = {CMD_MIFARE_CSETBLOCK, {params, blockNo, 0}}; memcpy(c.d.asBytes, data, 16); - clearCommandBuffer(); SendCommand(&c); UsbCommand resp; - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { + if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { isOK = resp.arg[0] & 0xff; if (uid != NULL) memcpy(uid, resp.d.asBytes, 4); @@ -289,9 +290,7 @@ int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, bool wantWipe, uin int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) { uint8_t isOK = 0; - - UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, 0, blockNo}}; - + UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, blockNo, 0}}; clearCommandBuffer(); SendCommand(&c); UsbCommand resp; @@ -634,19 +633,25 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) { 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 nr_enc; // encrypted reader challenge uint32_t ar_enc; // encrypted reader response uint32_t at_enc; // encrypted tag response */ - if (traceCrypto1) { - crypto1_destroy(traceCrypto1); - } + + struct Crypto1State *pcs = NULL; + 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("Decrypting data with:"); + PrintAndLog(" nt: %08x",nt); + PrintAndLog(" ar_enc: %08x",ar_enc); + PrintAndLog(" at_enc: %08x",at_enc); + PrintAndLog("\nEncrypted data: [%s]", sprint_hex(data,len) ); + + pcs = lfsr_recovery64(ks2, ks3); + mf_crypto1_decrypt(pcs, data, len, FALSE); PrintAndLog("Decrypted data: [%s]", sprint_hex(data,len) ); - crypto1_destroy(traceCrypto1); + crypto1_destroy(pcs); return 0; }