X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/932af56ea0f7e931aa39020c4af46ab81f4ca845..666fa6e1cfdc81acd1525ff4153c077535aa205a:/client/cmdhfmf.c diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 4956df8c..eb85b8c5 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -15,9 +15,10 @@ #include #include #include -#include "proxmark3.h" +#include "comms.h" #include "cmdmain.h" #include "cmdhfmfhard.h" +#include "parity.h" #include "util.h" #include "util_posix.h" #include "usb_cmd.h" @@ -26,6 +27,9 @@ #include "mifare.h" #include "mfkey.h" #include "hardnested/hardnested_bf_core.h" +#include "cliparser/cliparser.h" +#include "cmdhf14a.h" +#include #define NESTED_SECTOR_RETRY 10 // how often we try mfested() until we give up @@ -683,9 +687,9 @@ int CmdHF14AMfNested(const char *Cmd) if (transferToEml) { uint8_t sectortrailer; if (trgBlockNo < 32*4) { // 4 block sector - sectortrailer = (trgBlockNo & 0x03) + 3; + sectortrailer = trgBlockNo | 0x03; } else { // 16 block sector - sectortrailer = (trgBlockNo & 0x0f) + 15; + sectortrailer = trgBlockNo | 0x0f; } mfEmlGetMem(keyBlock, sectortrailer, 1); @@ -725,7 +729,6 @@ int CmdHF14AMfNested(const char *Cmd) blockNo = i * 4; keyType = j; num_to_bytes(e_sector[i].Key[j], 6, key); - keyFound = true; break; } @@ -736,6 +739,7 @@ int CmdHF14AMfNested(const char *Cmd) // Can't found a key.... if (!keyFound) { PrintAndLog("Can't found any of the known keys."); + free(e_sector); return 4; } PrintAndLog("--auto key. block no:%3d, key type:%c key:%s", blockNo, keyType?'B':'A', sprint_hex(key, 6)); @@ -1186,7 +1190,10 @@ int CmdHF14AMfChk(const char *Cmd) // initialize storage for found keys e_sector = calloc(SectorsCnt, sizeof(sector_t)); - if (e_sector == NULL) return 1; + if (e_sector == NULL) { + free(keyBlock); + return 1; + } for (uint8_t keyAB = 0; keyAB < 2; keyAB++) { for (uint16_t sectorNo = 0; sectorNo < SectorsCnt; sectorNo++) { e_sector[sectorNo].Key[keyAB] = 0xffffffffffff; @@ -1685,10 +1692,7 @@ int CmdHF14AMfESet(const char *Cmd) } // 1 - blocks count - UsbCommand c = {CMD_MIFARE_EML_MEMSET, {blockNo, 1, 0}}; - memcpy(c.d.asBytes, memBlock, 16); - SendCommand(&c); - return 0; + return mfEmlSetMem(memBlock, blockNo, 1); } @@ -1907,7 +1911,7 @@ int CmdHF14AMfECFill(const char *Cmd) default: numSectors = 16; } - printf("--params: numSectors: %d, keyType:%d", numSectors, keyType); + printf("--params: numSectors: %d, keyType:%d\n", numSectors, keyType); UsbCommand c = {CMD_MIFARE_EML_CARDLOAD, {numSectors, keyType, 0}}; SendCommand(&c); return 0; @@ -2473,6 +2477,7 @@ int CmdHF14AMfSniff(const char *Cmd){ //var int res = 0; int len = 0; + int parlen = 0; int blockLen = 0; int pckNum = 0; int num = 0; @@ -2484,6 +2489,7 @@ int CmdHF14AMfSniff(const char *Cmd){ uint8_t *buf = NULL; uint16_t bufsize = 0; uint8_t *bufPtr = NULL; + uint8_t parity[16]; char ctmp = param_getchar(Cmd, 0); if ( ctmp == 'h' || ctmp == 'H' ) { @@ -2527,14 +2533,13 @@ int CmdHF14AMfSniff(const char *Cmd){ } UsbCommand resp; - if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) { + if (WaitForResponseTimeoutW(CMD_ACK, &resp, 2000, false)) { res = resp.arg[0] & 0xff; uint16_t traceLen = resp.arg[1]; len = resp.arg[2]; if (res == 0) { // we are done - free(buf); - return 0; + break; } if (res == 1) { // there is (more) data to be transferred @@ -2576,6 +2581,7 @@ int CmdHF14AMfSniff(const char *Cmd){ } else { isTag = false; } + parlen = (len - 1) / 8 + 1; bufPtr += 2; if ((len == 14) && (bufPtr[0] == 0xff) && (bufPtr[1] == 0xff) && (bufPtr[12] == 0xff) && (bufPtr[13] == 0xff)) { memcpy(uid, bufPtr + 2, 7); @@ -2594,15 +2600,22 @@ int CmdHF14AMfSniff(const char *Cmd){ if (wantDecrypt) mfTraceInit(uid, atqa, sak, wantSaveToEmlFile); } else { - PrintAndLog("%s(%d):%s", isTag ? "TAG":"RDR", num, sprint_hex(bufPtr, len)); + oddparitybuf(bufPtr, len, parity); + PrintAndLog("%s(%d):%s [%s] c[%s]%c", + isTag ? "TAG":"RDR", + num, + sprint_hex(bufPtr, len), + printBitsPar(bufPtr + len, len), + printBitsPar(parity, len), + memcmp(bufPtr + len, parity, len / 8 + 1) ? '!' : ' '); if (wantLogToFile) AddLogHex(logHexFileName, isTag ? "TAG: ":"RDR: ", bufPtr, len); if (wantDecrypt) - mfTraceDecode(bufPtr, len, wantSaveToEmlFile); + mfTraceDecode(bufPtr, len, bufPtr[len], wantSaveToEmlFile); num++; } bufPtr += len; - bufPtr += ((len-1)/8+1); // ignore parity + bufPtr += parlen; // ignore parity } pckNum = 0; } @@ -2610,6 +2623,9 @@ int CmdHF14AMfSniff(const char *Cmd){ } // while (true) free(buf); + + msleep(300); // wait for exiting arm side. + PrintAndLog("Done."); return 0; } @@ -2621,6 +2637,146 @@ int CmdDecryptTraceCmds(const char *Cmd){ return tryDecryptWord(param_get32ex(Cmd,0,0,16),param_get32ex(Cmd,1,0,16),param_get32ex(Cmd,2,0,16),data,len/2); } +int aes_encode(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *output, int length){ + uint8_t iiv[16] = {0}; + if (iv) + memcpy(iiv, iv, 16); + + aes_context aes; + aes_init(&aes); + if (aes_setkey_enc(&aes, key, 128)) + return 1; + if (aes_crypt_cbc(&aes, AES_ENCRYPT, length, iiv, input, output)) + return 2; + aes_free(&aes); + + return 0; +} + +int aes_decode(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *output, int length){ + uint8_t iiv[16] = {0}; + if (iv) + memcpy(iiv, iv, 16); + + aes_context aes; + aes_init(&aes); + if (aes_setkey_dec(&aes, key, 128)) + return 1; + if (aes_crypt_cbc(&aes, AES_DECRYPT, length, iiv, input, output)) + return 2; + aes_free(&aes); + + return 0; +} + +int CmdHF14AMfAuth4(const char *cmd) { + uint8_t keyn[20] = {0}; + int keynlen = 0; + uint8_t key[16] = {0}; + int keylen = 0; + uint8_t data[257] = {0}; + int datalen = 0; + + uint8_t Rnd1[17] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00}; + uint8_t Rnd2[17] = {0}; + + + CLIParserInit("hf mf auth4", + "Executes AES authentication command in ISO14443-4", + "Usage:\n\thf mf auth4 4000 000102030405060708090a0b0c0d0e0f -> executes authentication\n" + "\thf mf auth4 9003 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> executes authentication\n"); + + void* argtable[] = { + arg_param_begin, + arg_str1(NULL, NULL, "", NULL), + arg_str1(NULL, NULL, "", NULL), + arg_param_end + }; + CLIExecWithReturn(cmd, argtable, true); + + CLIGetStrWithReturn(1, keyn, &keynlen); + CLIGetStrWithReturn(2, key, &keylen); + CLIParserFree(); + + if (keynlen != 2) { + PrintAndLog("ERROR: must be 2 bytes long instead of: %d", keynlen); + return 1; + } + + if (keylen != 16) { + PrintAndLog("ERROR: must be 16 bytes long instead of: %d", keylen); + return 1; + } + + uint8_t cmd1[] = {0x70, keyn[1], keyn[0], 0x00}; + int res = ExchangeRAW14a(cmd1, sizeof(cmd1), true, true, data, sizeof(data), &datalen); + if (res) { + PrintAndLog("ERROR exchande raw error: %d", res); + DropField(); + return 2; + } + + PrintAndLog("phase2: %s", sprint_hex(cmd2, 33)); + + res = ExchangeRAW14a(cmd2, sizeof(cmd2), false, false, data, sizeof(data), &datalen); + if (res) { + PrintAndLog("ERROR exchande raw error: %d", res); + DropField(); + return 4; + } + + PrintAndLog("