diff --git a/armsrc/appmain.c b/armsrc/appmain.c index f8b675fa0..3a48e7b58 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1054,9 +1054,11 @@ static void PacketReceived(PacketCommandNG *packet) { case CMD_READER_MIFARE: ReaderMifare(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]); break; - case CMD_MIFARE_READBL: - MifareReadBlock(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); + case CMD_MIFARE_READBL: { + mf_readblock_t *payload = (mf_readblock_t *)packet->data.asBytes; + MifareReadBlock(payload->blockno, payload->keytype, payload->key); break; + } case CMD_MIFAREU_READBL: MifareUReadBlock(packet->oldarg[0], packet->oldarg[1], packet->data.asBytes); break; diff --git a/armsrc/apps.h b/armsrc/apps.h index a5866ebd5..561a08b0d 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -146,7 +146,8 @@ void EPA_PACE_Collect_Nonce(PacketCommandNG *c); void EPA_PACE_Replay(PacketCommandNG *c); // mifarecmd.h -void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); +void MifareReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *datain); + void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain); void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes); void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain); diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 8670beaca..7b5a6518a 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -38,18 +38,16 @@ static uint8_t dummy_answer = 0; // Select, Authenticate, Read a MIFARE tag. // read block //----------------------------------------------------------------------------- -void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { +void MifareReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *datain) { // params - uint8_t blockNo = arg0; - uint8_t keyType = arg1; uint64_t ui64Key = 0; ui64Key = bytes_to_num(datain, 6); // variables - uint8_t isOK = 0; uint8_t dataoutbuf[16] = {0x00}; uint8_t uid[10] = {0x00}; - uint32_t cuid = 0; + uint32_t cuid = 0, status = PM3_EOPABORTED; + struct Crypto1State mpcs = {0, 0}; struct Crypto1State *pcs; pcs = &mpcs; @@ -84,7 +82,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { break; }; - isOK = 1; + status = PM3_SUCCESS; break; } @@ -93,7 +91,7 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { if (MF_DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED"); LED_B_ON(); - reply_old(CMD_ACK, isOK, 0, 0, dataoutbuf, 16); + reply_ng(CMD_MIFARE_READBL, status, dataoutbuf, 16); LED_B_OFF(); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); @@ -129,7 +127,7 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); } - reply_old(CMD_ACK, 1, 0, 0, 0, 0); + reply_mix(CMD_ACK, 1, 0, 0, 0, 0); } // Arg0 = BlockNo, @@ -189,7 +187,7 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { return; } - reply_old(CMD_ACK, 1, 0, 0, dataout, 16); + reply_mix(CMD_ACK, 1, 0, 0, dataout, 16); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); } @@ -352,7 +350,7 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain) countblocks *= 4; - reply_old(CMD_ACK, 1, countblocks, BigBuf_max_traceLen(), 0, 0); + reply_mix(CMD_ACK, 1, countblocks, BigBuf_max_traceLen(), 0, 0); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); BigBuf_free(); @@ -419,7 +417,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED"); - reply_old(CMD_ACK, isOK, 0, 0, 0, 0); + reply_mix(CMD_ACK, isOK, 0, 0, 0, 0); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); @@ -461,7 +459,7 @@ void MifareUWriteBlockCompat(uint8_t arg0, uint8_t *datain) if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED"); - reply_old(CMD_ACK,1,0,0,0,0); + reply_mix(CMD_ACK,1,0,0,0,0); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); } @@ -530,7 +528,7 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) { if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED"); - reply_old(CMD_ACK, 1, 0, 0, 0, 0); + reply_mix(CMD_ACK, 1, 0, 0, 0, 0); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); set_tracing(false); @@ -603,7 +601,7 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain) { return; }; - reply_old(CMD_ACK, 1, 0, 0, 0, 0); + reply_mix(CMD_ACK, 1, 0, 0, 0, 0); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); set_tracing(false); @@ -1054,7 +1052,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) memcpy(buf + 16, &target_ks[1], 4); LED_B_ON(); - reply_old(CMD_ACK, isOK, 0, targetBlockNo + (targetKeyType * 0x100), buf, sizeof(buf)); + reply_mix(CMD_ACK, isOK, 0, targetBlockNo + (targetKeyType * 0x100), buf, sizeof(buf)); LED_B_OFF(); if (MF_DBGLEVEL >= 3) DbpString("NESTED FINISHED"); @@ -1512,7 +1510,7 @@ OUT: BigBuf_Clear_ext(false); } else { // partial/none keys found - reply_old(CMD_ACK, foundkeys, 0, 0, 0, 0); + reply_mix(CMD_ACK, foundkeys, 0, 0, 0, 0); } } @@ -1862,7 +1860,7 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) { } // end while if (isOK) - reply_old(CMD_ACK, 1, 0, 0, uid, sizeof(uid)); + reply_mix(CMD_ACK, 1, 0, 0, uid, sizeof(uid)); else OnErrorMagic(errormsg); @@ -2102,7 +2100,7 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain) { } if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 1 FINISHED"); - reply_old(CMD_ACK, 1, cuid, 0, dataout, sizeof(dataout)); + reply_mix(CMD_ACK, 1, cuid, 0, dataout, sizeof(dataout)); } void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain) { diff --git a/client/cmdhfmf.c b/client/cmdhfmf.c index 874005e34..d12a3356f 100644 --- a/client/cmdhfmf.c +++ b/client/cmdhfmf.c @@ -549,14 +549,14 @@ static int CmdHF14AMfRdBl(const char *Cmd) { PrintAndLogEx(NORMAL, "Usage: hf mf rdbl "); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf rdbl 0 A FFFFFFFFFFFF "); - return 0; + return PM3_SUCCESS; } blockNo = param_get8(Cmd, 0); cmdp = tolower(param_getchar(Cmd, 1)); if (cmdp == 0x00) { PrintAndLogEx(NORMAL, "Key type must be A or B"); - return 1; + return PM3_ESOFT; } if (cmdp != 'a') @@ -564,23 +564,27 @@ static int CmdHF14AMfRdBl(const char *Cmd) { if (param_gethex(Cmd, 2, key, 12)) { PrintAndLogEx(NORMAL, "Key must include 12 HEX symbols"); - return 1; + return PM3_ESOFT; } PrintAndLogEx(NORMAL, "--block no:%d, key type:%c, key:%s ", blockNo, keyType ? 'B' : 'A', sprint_hex(key, 6)); + mf_readblock_t payload; + payload.blockno = blockNo; + payload.keytype = keyType; + memcpy(payload.key, key, sizeof(payload.key)); + clearCommandBuffer(); - SendCommandOLD(CMD_MIFARE_READBL, blockNo, keyType, 0, key, 6); + SendCommandNG(CMD_MIFARE_READBL, (uint8_t*)&payload, sizeof(mf_readblock_t)); PacketResponseNG resp; - if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - uint8_t isOK = resp.oldarg[0] & 0xff; + if (WaitForResponseTimeout(CMD_MIFARE_READBL, &resp, 1500)) { uint8_t *data = resp.data.asBytes; - if (isOK) { - PrintAndLogEx(NORMAL, "isOk:%02x data:%s", isOK, sprint_hex(data, 16)); + if (resp.status == PM3_SUCCESS) { + PrintAndLogEx(NORMAL, "data: %s", sprint_hex(data, 16)); } else { - PrintAndLogEx(NORMAL, "isOk:%02x", isOK); - return 1; + PrintAndLogEx(FAILED, "failed reading block"); + return PM3_ESOFT; } if (mfIsSectorTrailer(blockNo) && (data[6] || data[7] || data[8])) { @@ -595,7 +599,7 @@ static int CmdHF14AMfRdBl(const char *Cmd) { } } else { PrintAndLogEx(WARNING, "Command execute timeout"); - return 2; + return PM3_ETIMEOUT; } return 0; @@ -612,19 +616,19 @@ static int CmdHF14AMfRdSc(const char *Cmd) { PrintAndLogEx(NORMAL, "Usage: hf mf rdsc "); PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, " hf mf rdsc 0 A FFFFFFFFFFFF "); - return 0; + return PM3_SUCCESS; } sectorNo = param_get8(Cmd, 0); if (sectorNo > MIFARE_4K_MAXSECTOR) { PrintAndLogEx(NORMAL, "Sector number must be less than 40"); - return 1; + return PM3_ESOFT; } cmdp = tolower(param_getchar(Cmd, 1)); if (cmdp != 'a' && cmdp != 'b') { PrintAndLogEx(NORMAL, "Key type must be A or B"); - return 1; + return PM3_ESOFT; } if (cmdp != 'a') @@ -632,7 +636,7 @@ static int CmdHF14AMfRdSc(const char *Cmd) { if (param_gethex(Cmd, 2, key, 12)) { PrintAndLogEx(NORMAL, "Key must include 12 HEX symbols"); - return 1; + return PM3_ESOFT; } PrintAndLogEx(NORMAL, "--sector no:%d key type:%c key:%s ", sectorNo, keyType ? 'B' : 'A', sprint_hex(key, 6)); @@ -665,7 +669,7 @@ static int CmdHF14AMfRdSc(const char *Cmd) { PrintAndLogEx(WARNING, "Command execute timeout"); } - return 0; + return PM3_SUCCESS; } static uint16_t NumOfBlocks(char card) { @@ -761,14 +765,14 @@ static int CmdHF14AMfDump(const char *Cmd) { if (keyFilename[0] == 0x00) { fptr = GenerateFilename("hf-mf-", "-key.bin"); if (fptr == NULL) - return 1; + return PM3_ESOFT; strcpy(keyFilename, fptr); } if ((f = fopen(keyFilename, "rb")) == NULL) { PrintAndLogEx(WARNING, "Could not find file " _YELLOW_("%s"), keyFilename); - return 1; + return PM3_EFILE; } // Read keys A from file @@ -778,7 +782,7 @@ static int CmdHF14AMfDump(const char *Cmd) { if (bytes_read != 6) { PrintAndLogEx(WARNING, "File reading error."); fclose(f); - return 2; + return PM3_EFILE; } } @@ -788,7 +792,7 @@ static int CmdHF14AMfDump(const char *Cmd) { if (bytes_read != 6) { PrintAndLogEx(WARNING, "File reading error."); fclose(f); - return 2; + return PM3_EFILE; } } @@ -799,14 +803,21 @@ static int CmdHF14AMfDump(const char *Cmd) { uint8_t tries; for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { for (tries = 0; tries < MIFARE_SECTOR_RETRY; tries++) { + printf("."); + fflush(NULL); + + mf_readblock_t payload; + payload.blockno = FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1; + payload.keytype = 0; + memcpy(payload.key, keyA[sectorNo], sizeof(payload.key)); clearCommandBuffer(); - SendCommandOLD(CMD_MIFARE_READBL, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 0, 0, keyA[sectorNo], 6); + SendCommandNG(CMD_MIFARE_READBL, (uint8_t*)&payload, sizeof(mf_readblock_t)); + + if (WaitForResponseTimeout(CMD_MIFARE_READBL, &resp, 1500)) { - if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { - uint8_t isOK = resp.oldarg[0] & 0xff; uint8_t *data = resp.data.asBytes; - if (isOK) { + if (resp.status == PM3_SUCCESS) { rights[sectorNo][0] = ((data[7] & 0x10) >> 2) | ((data[8] & 0x1) << 1) | ((data[8] & 0x10) >> 4); // C1C2C3 for data area 0 rights[sectorNo][1] = ((data[7] & 0x20) >> 3) | ((data[8] & 0x2) << 0) | ((data[8] & 0x20) >> 5); // C1C2C3 for data area 1 rights[sectorNo][2] = ((data[7] & 0x40) >> 4) | ((data[8] & 0x4) >> 1) | ((data[8] & 0x40) >> 6); // C1C2C3 for data area 2 @@ -824,43 +835,63 @@ static int CmdHF14AMfDump(const char *Cmd) { } } } - + printf("\n"); PrintAndLogEx(SUCCESS, "Finished reading sector access bits"); PrintAndLogEx(INFO, "Dumping all blocks from card..."); - bool isOK = true; - for (sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) { - for (blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) { + mf_readblock_t payload; + for (sectorNo = 0; sectorNo < numSectors; sectorNo++) { + for (blockNo = 0; blockNo < NumBlocksPerSector(sectorNo); blockNo++) { bool received = false; for (tries = 0; tries < MIFARE_SECTOR_RETRY; tries++) { if (blockNo == NumBlocksPerSector(sectorNo) - 1) { // sector trailer. At least the Access Conditions can always be read with key A. - clearCommandBuffer(); - SendCommandOLD(CMD_MIFARE_READBL, FirstBlockOfSector(sectorNo) + blockNo, 0, 0, keyA[sectorNo], 6); - received = WaitForResponseTimeout(CMD_ACK, &resp, 1500); + + payload.blockno = FirstBlockOfSector(sectorNo) + blockNo; + payload.keytype = 0; + memcpy(payload.key, keyA[sectorNo], sizeof(payload.key)); + + clearCommandBuffer(); + SendCommandNG(CMD_MIFARE_READBL, (uint8_t*)&payload, sizeof(mf_readblock_t)); + received = WaitForResponseTimeout(CMD_MIFARE_READBL, &resp, 1500); + printf("A\n"); } else { // data block. Check if it can be read with key A or key B uint8_t data_area = (sectorNo < 32) ? blockNo : blockNo / 5; if ((rights[sectorNo][data_area] == 0x03) || (rights[sectorNo][data_area] == 0x05)) { // only key B would work - SendCommandOLD(CMD_MIFARE_READBL, FirstBlockOfSector(sectorNo) + blockNo, 1, 0, keyB[sectorNo], 6); - received = WaitForResponseTimeout(CMD_ACK, &resp, 1500); - } else if (rights[sectorNo][data_area] == 0x07) { // no key would work - isOK = false; - PrintAndLogEx(WARNING, "access rights do not allow reading of sector %2d block %3d", sectorNo, blockNo); - tries = MIFARE_SECTOR_RETRY; - } else { // key A would work + + payload.blockno = FirstBlockOfSector(sectorNo) + blockNo; + payload.keytype = 1; + memcpy(payload.key, keyB[sectorNo], sizeof(payload.key)); + clearCommandBuffer(); - SendCommandOLD(CMD_MIFARE_READBL, FirstBlockOfSector(sectorNo) + blockNo, 0, 0, keyA[sectorNo], 6); - received = WaitForResponseTimeout(CMD_ACK, &resp, 1500); + SendCommandNG(CMD_MIFARE_READBL, (uint8_t*)&payload, sizeof(mf_readblock_t)); + received = WaitForResponseTimeout(CMD_MIFARE_READBL, &resp, 1500); + printf("B\n"); + } else if (rights[sectorNo][data_area] == 0x07) { // no key would work + PrintAndLogEx(WARNING, "access rights do not allow reading of sector %2d block %3d", sectorNo, blockNo); + // where do you want to go?? Next sector or block? + break; + } else { // key A would work + + payload.blockno = FirstBlockOfSector(sectorNo) + blockNo; + payload.keytype = 0; + memcpy(payload.key, keyA[sectorNo], sizeof(payload.key)); + + clearCommandBuffer(); + SendCommandNG(CMD_MIFARE_READBL, (uint8_t*)&payload, sizeof(mf_readblock_t)); + received = WaitForResponseTimeout(CMD_MIFARE_READBL, &resp, 1500); + printf("C\n"); } } if (received) { - isOK = resp.oldarg[0] & 0xff; - if (isOK) break; + if (resp.status == PM3_SUCCESS) { + // break the re-try loop + break; + } } } if (received) { - isOK = resp.oldarg[0] & 0xff; uint8_t *data = resp.data.asBytes; if (blockNo == NumBlocksPerSector(sectorNo) - 1) { // sector trailer. Fill in the keys. data[0] = (keyA[sectorNo][0]); @@ -876,7 +907,7 @@ static int CmdHF14AMfDump(const char *Cmd) { data[14] = (keyB[sectorNo][4]); data[15] = (keyB[sectorNo][5]); } - if (isOK) { + if (resp.status == PM3_SUCCESS) { memcpy(carddata[FirstBlockOfSector(sectorNo) + blockNo], data, 16); PrintAndLogEx(SUCCESS, "successfully read block %2d of sector %2d.", blockNo, sectorNo); } else { @@ -884,19 +915,13 @@ static int CmdHF14AMfDump(const char *Cmd) { break; } } else { - isOK = false; PrintAndLogEx(WARNING, "command execute timeout when trying to read block %2d of sector %2d.", blockNo, sectorNo); break; } } } - if (isOK == 0) { - PrintAndLogEx(FAILED, "Something went wrong"); - return 0; - } - - PrintAndLogEx(SUCCESS, "\nSuccedded in dumping all blocks"); + PrintAndLogEx(SUCCESS, "\nSucceded in dumping all blocks"); if (strlen(dataFilename) < 1) { fptr = dataFilename; @@ -909,7 +934,7 @@ static int CmdHF14AMfDump(const char *Cmd) { saveFile(dataFilename, ".bin", (uint8_t *)carddata, bytes); saveFileEML(dataFilename, (uint8_t *)carddata, bytes, MFBLOCK_SIZE); saveFileJSON(dataFilename, jsfCardMemory, (uint8_t *)carddata, bytes); - return 0; + return PM3_SUCCESS; } static int CmdHF14AMfRestore(const char *Cmd) { @@ -1051,7 +1076,7 @@ static int CmdHF14AMfRestore(const char *Cmd) { } fclose(fdump); PrintAndLogEx(INFO, "Finish restore"); - return 0; + return PM3_SUCCESS; } static int CmdHF14AMfNested(const char *Cmd) { @@ -1081,7 +1106,7 @@ static int CmdHF14AMfNested(const char *Cmd) { if (ctmp != 'a' && ctmp != 'b') { PrintAndLogEx(WARNING, "key type must be A or B"); - return 1; + return PM3_EINVARG; } if (ctmp != 'a') @@ -1089,7 +1114,7 @@ static int CmdHF14AMfNested(const char *Cmd) { if (param_gethex(Cmd, 3, key, 12)) { PrintAndLogEx(WARNING, "key must include 12 HEX symbols"); - return 1; + return PM3_EINVARG; } if (cmdp == 'o') { @@ -1097,7 +1122,7 @@ static int CmdHF14AMfNested(const char *Cmd) { ctmp = tolower(param_getchar(Cmd, 5)); if (ctmp != 'a' && ctmp != 'b') { PrintAndLogEx(WARNING, "target key type must be A or B"); - return 1; + return PM3_EINVARG; } if (ctmp != 'a') { trgKeyType = 1; @@ -1158,16 +1183,16 @@ static int CmdHF14AMfNested(const char *Cmd) { mfEmlSetMem(keyBlock, sectortrailer, 1); PrintAndLogEx(SUCCESS, "Key transferred to emulator memory."); } - return 0; + return PM3_SUCCESS; default : PrintAndLogEx(WARNING, "Unknown Error.\n"); } - return 2; + return PM3_SUCCESS; } else { // ------------------------------------ multiple sectors working uint64_t t1 = msclock(); e_sector = calloc(SectorsCnt, sizeof(sector_t)); - if (e_sector == NULL) return 1; + if (e_sector == NULL) return PM3_EMALLOC; //test current key and additional standard keys first // add parameter key @@ -1222,7 +1247,7 @@ static int CmdHF14AMfNested(const char *Cmd) { PrintAndLogEx(WARNING, "unknown Error.\n"); } free(e_sector); - return 2; + return PM3_ESOFT; } } } @@ -1241,16 +1266,19 @@ static int CmdHF14AMfNested(const char *Cmd) { PrintAndLogEx(SUCCESS, "reading block %d", sectrail); - uint8_t txdata[6]; - num_to_bytes(e_sector[i].Key[0], 6, txdata); // KEY A + mf_readblock_t payload; + payload.blockno = sectrail; + payload.keytype = 0; + + num_to_bytes(e_sector[i].Key[0], 6, payload.key); // KEY A + clearCommandBuffer(); - SendCommandOLD(CMD_MIFARE_READBL, sectrail, 0, 0, txdata, sizeof(txdata)); + SendCommandNG(CMD_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t) ); PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) continue; + if (!WaitForResponseTimeout(CMD_MIFARE_READBL, &resp, 1500)) continue; - uint8_t isOK = resp.oldarg[0] & 0xff; - if (!isOK) continue; + if (resp.status != PM3_SUCCESS) continue; uint8_t *data = resp.data.asBytes; key64 = bytes_to_num(data + 10, 6); @@ -1272,10 +1300,13 @@ static int CmdHF14AMfNested(const char *Cmd) { conn.block_after_ACK = true; for (i = 0; i < SectorsCnt; i++) { mfEmlGetMem(keyBlock, FirstBlockOfSector(i) + NumBlocksPerSector(i) - 1, 1); + if (e_sector[i].foundKey[0]) num_to_bytes(e_sector[i].Key[0], 6, keyBlock); + if (e_sector[i].foundKey[1]) num_to_bytes(e_sector[i].Key[1], 6, &keyBlock[10]); + if (i == SectorsCnt - 1) { // Disable fast mode on last packet conn.block_after_ACK = false; @@ -1290,13 +1321,13 @@ static int CmdHF14AMfNested(const char *Cmd) { fptr = GenerateFilename("hf-mf-", "-key.bin"); if (fptr == NULL) { free(e_sector); - return 1; + return PM3_ESOFT; } if ((fkeys = fopen(fptr, "wb")) == NULL) { PrintAndLogEx(WARNING, "could not create file " _YELLOW_("%s"), fptr); free(e_sector); - return 1; + return PM3_EFILE; } PrintAndLogEx(SUCCESS, "saving keys to binary file " _YELLOW_("%s"), fptr); @@ -1321,7 +1352,7 @@ static int CmdHF14AMfNested(const char *Cmd) { } free(e_sector); } - return 0; + return PM3_SUCCESS; } static int CmdHF14AMfNestedHard(const char *Cmd) { @@ -1997,16 +2028,19 @@ static int CmdHF14AMfChk(const char *Cmd) { PrintAndLogEx(NORMAL, "Reading block %d", sectrail); - uint8_t txdata[6]; - num_to_bytes(e_sector[i].Key[0], 6, txdata); // KEY A + mf_readblock_t payload; + payload.blockno = sectrail; + payload.keytype = 0; + + num_to_bytes(e_sector[i].Key[0], 6, payload.key); // KEY A + clearCommandBuffer(); - SendCommandOLD(CMD_MIFARE_READBL, sectrail, 0, 0, txdata, sizeof(txdata)); + SendCommandNG(CMD_MIFARE_READBL, (uint8_t *)&payload, sizeof(mf_readblock_t) ); PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) continue; + if (!WaitForResponseTimeout(CMD_MIFARE_READBL, &resp, 1500)) continue; - uint8_t isOK = resp.oldarg[0] & 0xff; - if (!isOK) continue; + if (resp.status != PM3_SUCCESS) continue; uint8_t *data = resp.data.asBytes; key64 = bytes_to_num(data + 10, 6); diff --git a/client/cmdhfmfdes.c b/client/cmdhfmfdes.c index daadf0cab..c36084ce6 100644 --- a/client/cmdhfmfdes.c +++ b/client/cmdhfmfdes.c @@ -90,14 +90,15 @@ static int CmdHF14ADesRb(const char *Cmd) { } PrintAndLogEx(NORMAL, "--block no:%02x key type:%02x key:%s ", blockNo, keyType, sprint_hex(key, 6)); - SendCommandOLD(CMD_MIFARE_READBL, blockNo, keyType, 0, key, 6); + + mf_readblock_t payload = { blockNo, keyType, key }; + SendCommandNG(CMD_MIFARE_READBL, (uint8_t *)payload, sizeof(mf_readblock_t) ); PacketResponseNG resp; - if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) { - uint8_t isOK = resp.oldarg[0] & 0xff; + if (WaitForResponseTimeout(CMD_MIFARE_READBL, &resp, 1500)) { uint8_t * data = resp.data.asBytes; - if (isOK) + if (resp.status == PM3_SUCCESS) PrintAndLogEx(NORMAL, "isOk:%02x data:%s", isOK, sprint_hex(data, 16)); else PrintAndLogEx(NORMAL, "isOk:%02x", isOK); diff --git a/client/scripts/didump.lua b/client/scripts/didump.lua index 9f3f51d71..e85ec8bb9 100644 --- a/client/scripts/didump.lua +++ b/client/scripts/didump.lua @@ -49,6 +49,7 @@ local lsh = bit32.lshift local rsh = bit32.rshift -- Some globals +local PM3_SUCCESS = 0 local FOO = 'AF62D2EC0491968CC52A1A7165F865FE' local BAR = '286329204469736E65792032303133' local MIS = '0A14FD0507FF4BCD026BA83F0A3B89A9' @@ -463,20 +464,19 @@ local function getblockdata(response) if not response then return nil, 'No response from device' end - - local count, cmd, arg0 = bin.unpack('LL', response) - if arg0 == 1 then - local count, arg1, arg2, data = bin.unpack('LLH511', response, count) - return data:sub(1, 32) + if response.Status == PM3_SUCCESS then + return response.Data else - return nil, "Couldn't read block.. ["..arg0.."]" + return nil, "Couldn't read block.. ["..response.Status.."]" end end -local function readblock( blocknum, key ) +local function readblock( blockno, key ) -- Read block N - local c = Command:newMIX{cmd = cmds.CMD_MIFARE_READBL, arg1 = blocknum, data = key} - local b, err = getblockdata(c:sendMIX()) + local keytype = '00' + local data = ('%02x%s%s'):format(blockno, keytype, key) + local c = Command:newNG{cmd = cmds.CMD_MIFARE_READBL, data = data} + local b, err = getblockdata(c:sendNG(false)) if not b then return oops(err) end return b end diff --git a/client/scripts/tnp3clone.lua b/client/scripts/tnp3clone.lua index b168c9d1a..18dd6edfb 100644 --- a/client/scripts/tnp3clone.lua +++ b/client/scripts/tnp3clone.lua @@ -40,6 +40,9 @@ Arguments: 023c - Special 0020 - Swapforce ]] + +local PM3_SUCCESS = 0 + --- -- This is only meant to be used when errors occur local function oops(err) @@ -63,20 +66,19 @@ local function getblockdata(response) if not response then return nil, 'No response from device' end - - local count, cmd, arg0 = bin.unpack('LL', response) - if arg0 == 1 then - local count, arg1, arg2, data = bin.unpack('LLH511', response, count) - return data:sub(1, 32) + if response.Status == PM3_SUCCESS then + return response.Data else - return nil, "Couldn't read block.. ["..arg0.."]" + return nil, "Couldn't read block.. ["..response.Status.."]" end end local function readblock( blocknum, keyA ) -- Read block N - local c = Command:newMIX{cmd = cmds.CMD_MIFARE_READBL, arg1 = blocknum, data = keyA} - local b, err = getblockdata(c:sendMIX()) + local keytype = '00' + local data = ('%02x%s%s'):format(blocknum, keytype, keyA) + local c = Command:newNG{cmd = cmds.CMD_MIFARE_READBL, data = data} + local b, err = getblockdata(c:sendNG(false)) if not b then return oops(err) end return b end diff --git a/client/scripts/tnp3dump.lua b/client/scripts/tnp3dump.lua index 7da530f7d..9e3c62519 100644 --- a/client/scripts/tnp3dump.lua +++ b/client/scripts/tnp3dump.lua @@ -35,6 +35,8 @@ Arguments: -p : Use the precalc to find all keys -o : filename for the saved dumps ]] + +local PM3_SUCCESS = 0 local RANDOM = '20436F707972696768742028432920323031302041637469766973696F6E2E20416C6C205269676874732052657365727665642E20' local DEBUG = false -- the debug flag local numBlocks = 64 @@ -91,13 +93,10 @@ local function getblockdata(response) if not response then return nil, 'No response from device' end - - local count, cmd, arg0 = bin.unpack('LL', response) - if arg0 == 1 then - local count, arg1, arg2, data = bin.unpack('LLH511', response, count) - return data:sub(1, 32) + if response.Status == PM3_SUCCESS then + return response.Data else - return nil, "Couldn't read block.. ["..arg0.."]" + return nil, "Couldn't read block.. ["..response.Status.."]" end end @@ -167,16 +166,21 @@ local function main(args) local block0, block1 -- Read block 0 dbg('Reading block 0') - cmd = Command:newMIX{cmd = cmds.CMD_MIFARE_READBL, arg1 = 0, data = keyA} - block0, err = getblockdata(cmd:sendMIX(false)) + local blockno = '00' + local keytype = '00' + local data = ('%s%s%s'):format(blockno, keytype, keyA) + cmd = Command:newNG{cmd = cmds.CMD_MIFARE_READBL, data = data} + block0, err = getblockdata(cmd:sendNG(false)) if not block0 then return oops(err) end core.clearCommandBuffer() -- Read block 1 dbg('Reading block 1') - cmd = Command:newMIX{cmd = cmds.CMD_MIFARE_READBL, arg1 = 1, data = keyA} - block1, err = getblockdata(cmd:sendMIX(false)) + local blockno = '01' + data = ('%s%s%s'):format(blockno, keytype, keyA) + cmd = Command:newNG{cmd = cmds.CMD_MIFARE_READBL, data = data} + block1, err = getblockdata(cmd:sendNG(false)) if not block1 then return oops(err) end core.clearCommandBuffer() @@ -203,8 +207,9 @@ local function main(args) pos = (math.floor( blockNo / 4 ) * 12)+1 key = akeys:sub(pos, pos + 11 ) - cmd = Command:newMIX{cmd = cmds.CMD_MIFARE_READBL, arg1 = blockNo, data = key} - local blockdata, err = getblockdata(cmd:sendMIX(false)) + data = ('%02x%s%s'):format(blockNo, keytype, key) + cmd = Command:newNG{cmd = cmds.CMD_MIFARE_READBL, data = data} + local blockdata, err = getblockdata(cmd:sendNG(false)) if not blockdata then return oops(err) end if blockNo%4 ~= 3 then diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index f0b20858f..4ff2add80 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -202,6 +202,12 @@ typedef struct { uint8_t data[]; } PACKED lf_psksim_t; +typedef struct { + uint8_t blockno; + uint8_t keytype; + uint8_t key[6]; +} PACKED mf_readblock_t; + // For the bootloader #define CMD_DEVICE_INFO 0x0000