SendCommandOLD & errors retval: mifarehost

This commit is contained in:
Philippe Teuwen 2019-04-19 01:45:45 +02:00
commit 2ac5482d9c

View file

@ -15,8 +15,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
uint32_t nt = 0, nr = 0, ar = 0; uint32_t nt = 0, nr = 0, ar = 0;
uint64_t par_list = 0, ks_list = 0; uint64_t par_list = 0, ks_list = 0;
uint64_t *keylist = NULL, *last_keylist = NULL; uint64_t *keylist = NULL, *last_keylist = NULL;
bool arg0 = true;
PacketCommandOLD c = {CMD_READER_MIFARE, {true, blockno, key_type}, {{0}}};
// message // message
PrintAndLogEx(NORMAL, "--------------------------------------------------------------------------------\n"); PrintAndLogEx(NORMAL, "--------------------------------------------------------------------------------\n");
@ -26,13 +25,13 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
while (true) { while (true) {
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommandOLD(CMD_READER_MIFARE, arg0, blockno, key_type, NULL, 0);
//flush queue //flush queue
while (ukbhit()) { while (ukbhit()) {
int gc = getchar(); int gc = getchar();
(void)gc; (void)gc;
return -5; return PM3_EOPABORTED;
} }
// wait cycle // wait cycle
@ -42,7 +41,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
if (ukbhit()) { if (ukbhit()) {
int gc = getchar(); int gc = getchar();
(void)gc; (void)gc;
return -5; return PM3_EOPABORTED;
} }
PacketResponseNG resp; PacketResponseNG resp;
@ -62,10 +61,10 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
} }
PrintAndLogEx(NORMAL, "\n"); PrintAndLogEx(NORMAL, "\n");
if (par_list == 0 && c.arg[0] == true) { if (par_list == 0 && arg0 == true) {
PrintAndLogEx(SUCCESS, "Parity is all zero. Most likely this card sends NACK on every authentication."); PrintAndLogEx(SUCCESS, "Parity is all zero. Most likely this card sends NACK on every authentication.");
} }
c.arg[0] = false; arg0 = false;
uint32_t keycount = nonce2key(uid, nt, nr, ar, par_list, ks_list, &keylist); uint32_t keycount = nonce2key(uid, nt, nr, ar, par_list, ks_list, &keylist);
@ -114,24 +113,22 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
PrintAndLogEx(FAILED, "all candidate keys failed. Restarting darkside attack"); PrintAndLogEx(FAILED, "all candidate keys failed. Restarting darkside attack");
free(last_keylist); free(last_keylist);
last_keylist = keylist; last_keylist = keylist;
c.arg[0] = true; arg0 = true;
} }
} }
free(last_keylist); free(last_keylist);
free(keylist); free(keylist);
return 0; return PM3_SUCCESS;
} }
int mfCheckKeys(uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t *keyBlock, uint64_t *key) { int mfCheckKeys(uint8_t blockNo, uint8_t keyType, bool clear_trace, uint8_t keycnt, uint8_t *keyBlock, uint64_t *key) {
*key = -1; *key = -1;
PacketCommandOLD c = {CMD_MIFARE_CHKKEYS, { (blockNo | (keyType << 8)), clear_trace, keycnt}, {{0}}};
memcpy(c.d.asBytes, keyBlock, 6 * keycnt);
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommandOLD(CMD_MIFARE_CHKKEYS, (blockNo | (keyType << 8)), clear_trace, keycnt, keyBlock, 6 * keycnt);
PacketResponseNG resp; PacketResponseNG resp;
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) return 1; if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) return PM3_ETIMEOUT;
if ((resp.oldarg[0] & 0xff) != 0x01) return 2; if ((resp.oldarg[0] & 0xff) != 0x01) return PM3_EUNDEF;
*key = bytes_to_num(resp.data.asBytes, 6); *key = bytes_to_num(resp.data.asBytes, 6);
return 0; return PM3_SUCCESS;
} }
// Sends chunks of keys to device. // Sends chunks of keys to device.
@ -145,10 +142,8 @@ int mfCheckKeys_fast(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk,
uint32_t timeout = 0; uint32_t timeout = 0;
// send keychunk // send keychunk
PacketCommandOLD c = {CMD_MIFARE_CHKKEYS_FAST, { (sectorsCnt | (firstChunk << 8) | (lastChunk << 12)), ((use_flashmemory << 8) | strategy), size}, {{0}}};
memcpy(c.d.asBytes, keyBlock, 6 * size);
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommandOLD(CMD_MIFARE_CHKKEYS_FAST, (sectorsCnt | (firstChunk << 8) | (lastChunk << 12)), ((use_flashmemory << 8) | strategy), size, keyBlock, 6 * size);
PacketResponseNG resp; PacketResponseNG resp;
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
@ -160,7 +155,7 @@ int mfCheckKeys_fast(uint8_t sectorsCnt, uint8_t firstChunk, uint8_t lastChunk,
// takes about 97s, still some margin before abort // takes about 97s, still some margin before abort
if (timeout > 180) { if (timeout > 180) {
PrintAndLogEx(WARNING, "\nNo response from Proxmark3. Aborting..."); PrintAndLogEx(WARNING, "\nNo response from Proxmark3. Aborting...");
return 2; return PM3_ETIMEOUT;
} }
} }
t2 = msclock() - t2; t2 = msclock() - t2;
@ -297,11 +292,9 @@ int mfnested(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo,
StateList_t statelists[2]; StateList_t statelists[2];
struct Crypto1State *p1, *p2, *p3, *p4; struct Crypto1State *p1, *p2, *p3, *p4;
PacketCommandOLD c = {CMD_MIFARE_NESTED, {blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, calibrate}, {{0}}};
memcpy(c.d.asBytes, key, 6);
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommandOLD(CMD_MIFARE_NESTED, blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, calibrate, key, 6);
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return -1; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return PM3_ETIMEOUT;
// error during nested // error during nested
if (resp.oldarg[0]) return resp.oldarg[0]; if (resp.oldarg[0]) return resp.oldarg[0];
@ -419,10 +412,8 @@ out:
// MIFARE // MIFARE
int mfReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data) { int mfReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data) {
PacketCommandOLD c = {CMD_MIFARE_READSC, {sectorNo, keyType, 0}, {{0}}};
memcpy(c.d.asBytes, key, 6);
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommandOLD(CMD_MIFARE_READSC, sectorNo, keyType, 0, key, 6);
PacketResponseNG resp; PacketResponseNG resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
@ -430,27 +421,26 @@ int mfReadSector(uint8_t sectorNo, uint8_t keyType, uint8_t *key, uint8_t *data)
if (isOK) { if (isOK) {
memcpy(data, resp.data.asBytes, mfNumBlocksPerSector(sectorNo) * 16); memcpy(data, resp.data.asBytes, mfNumBlocksPerSector(sectorNo) * 16);
return 0; return PM3_SUCCESS;
} else { } else {
return 1; return PM3_EUNDEF;
} }
} else { } else {
PrintAndLogEx(ERR, "Command execute timeout"); PrintAndLogEx(ERR, "Command execute timeout");
return 2; return PM3_ETIMEOUT;
} }
return 0; return PM3_SUCCESS;
} }
// EMULATOR // EMULATOR
int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount) { int mfEmlGetMem(uint8_t *data, int blockNum, int blocksCount) {
PacketCommandOLD c = {CMD_MIFARE_EML_MEMGET, {blockNum, blocksCount, 0}, {{0}}};
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommandOLD(CMD_MIFARE_EML_MEMGET, blockNum, blocksCount, 0, NULL, 0);
PacketResponseNG resp; PacketResponseNG resp;
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return 1; if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) return PM3_ETIMEOUT;
memcpy(data, resp.data.asBytes, blocksCount * 16); memcpy(data, resp.data.asBytes, blocksCount * 16);
return 0; return PM3_SUCCESS;
} }
int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount) { int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
@ -458,11 +448,9 @@ int mfEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
} }
int mfEmlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidth) { int mfEmlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidth) {
PacketCommandOLD c = {CMD_MIFARE_EML_MEMSET, {blockNum, blocksCount, blockBtWidth}, {{0}}};
memcpy(c.d.asBytes, data, blocksCount * blockBtWidth);
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommandOLD(CMD_MIFARE_EML_MEMSET, blockNum, blocksCount, blockBtWidth, data, blocksCount * blockBtWidth);
return 0; return PM3_SUCCESS;
} }
// "MAGIC" CARD // "MAGIC" CARD
@ -501,39 +489,36 @@ int mfCSetUID(uint8_t *uid, uint8_t *atqa, uint8_t *sak, uint8_t *oldUID, uint8_
int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params) { int mfCSetBlock(uint8_t blockNo, uint8_t *data, uint8_t *uid, uint8_t params) {
PacketCommandOLD c = {CMD_MIFARE_CSETBLOCK, {params, blockNo, 0}, {{0}}};
memcpy(c.d.asBytes, data, 16);
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommandOLD(CMD_MIFARE_CSETBLOCK, params, blockNo, 0, data, 16);
PacketResponseNG resp; PacketResponseNG resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
uint8_t isOK = resp.oldarg[0] & 0xff; uint8_t isOK = resp.oldarg[0] & 0xff;
if (uid != NULL) if (uid != NULL)
memcpy(uid, resp.data.asBytes, 4); memcpy(uid, resp.data.asBytes, 4);
if (!isOK) if (!isOK)
return 2; return PM3_EUNDEF;
} else { } else {
PrintAndLogEx(WARNING, "command execute timeout"); PrintAndLogEx(WARNING, "command execute timeout");
return 1; return PM3_ETIMEOUT;
} }
return 0; return PM3_SUCCESS;
} }
int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) { int mfCGetBlock(uint8_t blockNo, uint8_t *data, uint8_t params) {
PacketCommandOLD c = {CMD_MIFARE_CGETBLOCK, {params, blockNo, 0}, {{0}}};
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommandOLD(CMD_MIFARE_CGETBLOCK, params, blockNo, 0, NULL, 0);
PacketResponseNG resp; PacketResponseNG resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
uint8_t isOK = resp.oldarg[0] & 0xff; uint8_t isOK = resp.oldarg[0] & 0xff;
if (!isOK) if (!isOK)
return 2; return PM3_EUNDEF;
memcpy(data, resp.data.asBytes, 16); memcpy(data, resp.data.asBytes, 16);
} else { } else {
PrintAndLogEx(WARNING, "command execute timeout"); PrintAndLogEx(WARNING, "command execute timeout");
return 1; return PM3_ETIMEOUT;
} }
return 0; return PM3_SUCCESS;
} }
// SNIFFER // SNIFFER
@ -586,7 +571,7 @@ int loadTraceCard(uint8_t *tuid, uint8_t uidlen) {
FillFileNameByUID(traceFileName, tuid, ".eml", uidlen); FillFileNameByUID(traceFileName, tuid, ".eml", uidlen);
f = fopen(traceFileName, "r"); f = fopen(traceFileName, "r");
if (!f) return 1; if (!f) return PM3_EFILE;
blockNum = 0; blockNum = 0;
@ -596,14 +581,14 @@ int loadTraceCard(uint8_t *tuid, uint8_t uidlen) {
if (fgets(buf, sizeof(buf), f) == NULL) { if (fgets(buf, sizeof(buf), f) == NULL) {
PrintAndLogEx(FAILED, "No trace file found or reading error."); PrintAndLogEx(FAILED, "No trace file found or reading error.");
fclose(f); fclose(f);
return 2; return PM3_EFILE;
} }
if (strlen(buf) < 32) { if (strlen(buf) < 32) {
if (feof(f)) break; if (feof(f)) break;
PrintAndLogEx(FAILED, "File content error. Block data must include 32 HEX symbols"); PrintAndLogEx(FAILED, "File content error. Block data must include 32 HEX symbols");
fclose(f); fclose(f);
return 2; return PM3_EFILE;
} }
for (i = 0; i < 32; i += 2) { for (i = 0; i < 32; i += 2) {
sscanf(&buf[i], "%02X", &tmp); sscanf(&buf[i], "%02X", &tmp);
@ -615,16 +600,16 @@ int loadTraceCard(uint8_t *tuid, uint8_t uidlen) {
blockNum++; blockNum++;
} }
fclose(f); fclose(f);
return 0; return PM3_SUCCESS;
} }
int saveTraceCard(void) { int saveTraceCard(void) {
if ((!strlen(traceFileName)) || (isTraceCardEmpty())) return 0; if ((!strlen(traceFileName)) || (isTraceCardEmpty())) return PM3_ESOFT;
FILE *f; FILE *f;
f = fopen(traceFileName, "w+"); f = fopen(traceFileName, "w+");
if (!f) return 1; if (!f) return PM3_EFILE;
// given 4096 tracecard size, these loop will only match a 1024, 1kb card memory // given 4096 tracecard size, these loop will only match a 1024, 1kb card memory
// 4086/16 == 256blocks. // 4086/16 == 256blocks.
@ -638,7 +623,7 @@ int saveTraceCard(void) {
} }
fflush(f); fflush(f);
fclose(f); fclose(f);
return 0; return PM3_SUCCESS;
} }
// //
int mfTraceInit(uint8_t *tuid, uint8_t uidlen, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile) { int mfTraceInit(uint8_t *tuid, uint8_t uidlen, uint8_t *atqa, uint8_t sak, bool wantSaveToEmlFile) {
@ -657,7 +642,7 @@ int mfTraceInit(uint8_t *tuid, uint8_t uidlen, uint8_t *atqa, uint8_t sak, bool
traceCurBlock = 0; traceCurBlock = 0;
cuid = bytes_to_num(tuid + (uidlen - 4), 4); cuid = bytes_to_num(tuid + (uidlen - 4), 4);
traceState = TRACE_IDLE; traceState = TRACE_IDLE;
return 0; return PM3_SUCCESS;
} }
void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool isEncrypted) { void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len, bool isEncrypted) {
@ -680,11 +665,11 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
uint32_t ar_enc = 0; // encrypted reader response uint32_t ar_enc = 0; // encrypted reader response
uint32_t at_enc = 0; // encrypted tag response uint32_t at_enc = 0; // encrypted tag response
if (traceState == TRACE_ERROR) if (traceState == TRACE_ERROR)
return 1; return PM3_ESOFT;
if (len > 255) { if (len > 255) {
traceState = TRACE_ERROR; traceState = TRACE_ERROR;
return 1; return PM3_ESOFT;
} }
uint8_t data[255]; uint8_t data[255];
@ -705,7 +690,7 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
PrintAndLogEx(NORMAL, "DEC| CRC ERROR!!!"); PrintAndLogEx(NORMAL, "DEC| CRC ERROR!!!");
AddLogLine(logHexFileName, "DEC| ", "CRC ERROR!!!"); AddLogLine(logHexFileName, "DEC| ", "CRC ERROR!!!");
traceState = TRACE_ERROR; // do not decrypt the next commands traceState = TRACE_ERROR; // do not decrypt the next commands
return 1; return PM3_ESOFT;
} }
// AUTHENTICATION // AUTHENTICATION
@ -713,29 +698,29 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
traceState = TRACE_AUTH1; traceState = TRACE_AUTH1;
traceCurBlock = data[1]; traceCurBlock = data[1];
traceCurKey = data[0] == 60 ? 1 : 0; traceCurKey = data[0] == 60 ? 1 : 0;
return 0; return PM3_SUCCESS;
} }
// READ // READ
if ((len == 4) && ((data[0] == ISO14443A_CMD_READBLOCK))) { if ((len == 4) && ((data[0] == ISO14443A_CMD_READBLOCK))) {
traceState = TRACE_READ_DATA; traceState = TRACE_READ_DATA;
traceCurBlock = data[1]; traceCurBlock = data[1];
return 0; return PM3_SUCCESS;
} }
// WRITE // WRITE
if ((len == 4) && ((data[0] == ISO14443A_CMD_WRITEBLOCK))) { if ((len == 4) && ((data[0] == ISO14443A_CMD_WRITEBLOCK))) {
traceState = TRACE_WRITE_OK; traceState = TRACE_WRITE_OK;
traceCurBlock = data[1]; traceCurBlock = data[1];
return 0; return PM3_SUCCESS;
} }
// HALT // HALT
if ((len == 4) && ((data[0] == ISO14443A_CMD_HALT) && (data[1] == 0x00))) { if ((len == 4) && ((data[0] == ISO14443A_CMD_HALT) && (data[1] == 0x00))) {
traceState = TRACE_ERROR; // do not decrypt the next commands traceState = TRACE_ERROR; // do not decrypt the next commands
return 0; return PM3_SUCCESS;
} }
return 0; return PM3_SUCCESS;
case TRACE_READ_DATA: case TRACE_READ_DATA:
if (len == 18) { if (len == 18) {
@ -747,19 +732,19 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
memcpy(traceCard + traceCurBlock * 16, data, 16); memcpy(traceCard + traceCurBlock * 16, data, 16);
} }
if (wantSaveToEmlFile) saveTraceCard(); if (wantSaveToEmlFile) saveTraceCard();
return 0; return PM3_SUCCESS;
} else { } else {
traceState = TRACE_ERROR; traceState = TRACE_ERROR;
return 1; return PM3_ESOFT;
} }
break; break;
case TRACE_WRITE_OK: case TRACE_WRITE_OK:
if ((len == 1) && (data[0] == 0x0a)) { if ((len == 1) && (data[0] == 0x0a)) {
traceState = TRACE_WRITE_DATA; traceState = TRACE_WRITE_DATA;
return 0; return PM3_SUCCESS;
} else { } else {
traceState = TRACE_ERROR; traceState = TRACE_ERROR;
return 1; return PM3_ESOFT;
} }
break; break;
case TRACE_WRITE_DATA: case TRACE_WRITE_DATA:
@ -767,20 +752,20 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
traceState = TRACE_IDLE; traceState = TRACE_IDLE;
memcpy(traceCard + traceCurBlock * 16, data, 16); memcpy(traceCard + traceCurBlock * 16, data, 16);
if (wantSaveToEmlFile) saveTraceCard(); if (wantSaveToEmlFile) saveTraceCard();
return 0; return PM3_SUCCESS;
} else { } else {
traceState = TRACE_ERROR; traceState = TRACE_ERROR;
return 1; return PM3_ESOFT;
} }
break; break;
case TRACE_AUTH1: case TRACE_AUTH1:
if (len == 4) { if (len == 4) {
traceState = TRACE_AUTH2; traceState = TRACE_AUTH2;
//nt = bytes_to_num(data, 4); //nt = bytes_to_num(data, 4);
return 0; return PM3_SUCCESS;
} else { } else {
traceState = TRACE_ERROR; traceState = TRACE_ERROR;
return 1; return PM3_ESOFT;
} }
break; break;
case TRACE_AUTH2: case TRACE_AUTH2:
@ -788,10 +773,10 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
traceState = TRACE_AUTH_OK; traceState = TRACE_AUTH_OK;
//nr_enc = bytes_to_num(data, 4); //nr_enc = bytes_to_num(data, 4);
//ar_enc = bytes_to_num(data + 4, 4); //ar_enc = bytes_to_num(data + 4, 4);
return 0; return PM3_SUCCESS;
} else { } else {
traceState = TRACE_ERROR; traceState = TRACE_ERROR;
return 1; return PM3_ESOFT;
} }
break; break;
case TRACE_AUTH_OK: case TRACE_AUTH_OK:
@ -843,9 +828,9 @@ int mfTraceDecode(uint8_t *data_src, int len, bool wantSaveToEmlFile) {
break; break;
default: default:
traceState = TRACE_ERROR; traceState = TRACE_ERROR;
return 1; return PM3_ESOFT;
} }
return 0; return PM3_SUCCESS;
} }
int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len) { int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data, int len) {
@ -857,7 +842,7 @@ int tryDecryptWord(uint32_t nt, uint32_t ar_enc, uint32_t at_enc, uint8_t *data,
mf_crypto1_decrypt(s, data, len, false); mf_crypto1_decrypt(s, data, len, false);
PrintAndLogEx(SUCCESS, "decrypted data: [%s]", sprint_hex(data, len)); PrintAndLogEx(SUCCESS, "decrypted data: [%s]", sprint_hex(data, len));
crypto1_destroy(s); crypto1_destroy(s);
return 0; return PM3_SUCCESS;
} }
/* Detect Tag Prng, /* Detect Tag Prng,
@ -873,31 +858,28 @@ int detect_classic_prng(void) {
uint8_t cmd[] = {MIFARE_AUTH_KEYA, 0x00}; uint8_t cmd[] = {MIFARE_AUTH_KEYA, 0x00};
uint32_t flags = ISO14A_CONNECT | ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_RATS; uint32_t flags = ISO14A_CONNECT | ISO14A_RAW | ISO14A_APPEND_CRC | ISO14A_NO_RATS;
PacketCommandOLD c = {CMD_READER_ISO_14443a, {flags, sizeof(cmd), 0}, {{0}}};
memcpy(c.d.asBytes, cmd, sizeof(cmd));
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommandOLD(CMD_READER_ISO_14443a, flags, sizeof(cmd), 0, cmd, sizeof(cmd));
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
PrintAndLogEx(WARNING, "PRNG UID: Reply timeout."); PrintAndLogEx(WARNING, "PRNG UID: Reply timeout.");
return -1; return PM3_ETIMEOUT;
} }
// if select tag failed. // if select tag failed.
if (resp.oldarg[0] == 0) { if (resp.oldarg[0] == 0) {
PrintAndLogEx(WARNING, "error: selecting tag failed, can't detect prng\n"); PrintAndLogEx(WARNING, "error: selecting tag failed, can't detect prng\n");
return -2; return PM3_ERFTRANS;
} }
if (!WaitForResponseTimeout(CMD_ACK, &respA, 2500)) { if (!WaitForResponseTimeout(CMD_ACK, &respA, 2500)) {
PrintAndLogEx(WARNING, "PRNG data: Reply timeout."); PrintAndLogEx(WARNING, "PRNG data: Reply timeout.");
return -3; return PM3_ETIMEOUT;
} }
// check respA // check respA
if (respA.oldarg[0] != 4) { if (respA.oldarg[0] != 4) {
PrintAndLogEx(WARNING, "PRNG data error: Wrong length: %d", respA.oldarg[0]); PrintAndLogEx(WARNING, "PRNG data error: Wrong length: %d", respA.oldarg[0]);
return -4; return PM3_ESOFT;
} }
uint32_t nonce = bytes_to_num(respA.data.asBytes, respA.oldarg[0]); uint32_t nonce = bytes_to_num(respA.data.asBytes, respA.oldarg[0]);
@ -913,9 +895,8 @@ returns:
*/ */
int detect_classic_nackbug(bool verbose) { int detect_classic_nackbug(bool verbose) {
PacketCommandOLD c = {CMD_MIFARE_NACK_DETECT, {0, 0, 0}, {{0}}};
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommandOLD(CMD_MIFARE_NACK_DETECT, 0, 0, 0, NULL, 0);
PacketResponseNG resp; PacketResponseNG resp;
if (verbose) if (verbose)
@ -945,7 +926,7 @@ int detect_classic_nackbug(bool verbose) {
if (ukbhit()) { if (ukbhit()) {
int gc = getchar(); int gc = getchar();
(void)gc; (void)gc;
return -1; return PM3_EOPABORTED;
} }
if (WaitForResponseTimeout(CMD_ACK, &resp, 500)) { if (WaitForResponseTimeout(CMD_ACK, &resp, 500)) {
@ -961,47 +942,46 @@ int detect_classic_nackbug(bool verbose) {
switch (ok) { switch (ok) {
case 99 : case 99 :
PrintAndLogEx(WARNING, "button pressed. Aborted."); PrintAndLogEx(WARNING, "button pressed. Aborted.");
return 0; return PM3_EOPABORTED;
case 96 : case 96 :
case 98 : { case 98 : {
if (verbose) if (verbose)
PrintAndLogEx(FAILED, "card random number generator is not predictable."); PrintAndLogEx(FAILED, "card random number generator is not predictable.");
PrintAndLogEx(WARNING, "detection failed"); PrintAndLogEx(WARNING, "detection failed");
return 2; return PM3_SUCCESS;
} }
case 97 : { case 97 : {
if (verbose) { if (verbose) {
PrintAndLogEx(FAILED, "card random number generator seems to be based on the well-known generating polynomial"); PrintAndLogEx(FAILED, "card random number generator seems to be based on the well-known generating polynomial");
PrintAndLogEx(NORMAL, "[- ]with 16 effective bits only, but shows unexpected behavior, try again."); PrintAndLogEx(NORMAL, "[- ]with 16 effective bits only, but shows unexpected behavior, try again.");
} }
return 2; return PM3_SUCCESS;
} }
case 2 : case 2 :
PrintAndLogEx(SUCCESS, _GREEN_("always leak NACK detected")); PrintAndLogEx(SUCCESS, _GREEN_("always leak NACK detected"));
return 3; return PM3_SUCCESS;
case 1 : case 1 :
PrintAndLogEx(SUCCESS, _GREEN_("NACK bug detected")); PrintAndLogEx(SUCCESS, _GREEN_("NACK bug detected"));
return 1; return PM3_SUCCESS;
case 0 : case 0 :
PrintAndLogEx(SUCCESS, "No NACK bug detected"); PrintAndLogEx(SUCCESS, "No NACK bug detected");
return 2; return PM3_SUCCESS;
default : default :
PrintAndLogEx(WARNING, "errorcode from device [%i]", ok); PrintAndLogEx(WARNING, "errorcode from device [%i]", ok);
return 0; return PM3_EUNDEF;
} }
break; break;
} }
} }
return 0; return PM3_SUCCESS;
} }
/* try to see if card responses to "chinese magic backdoor" commands. */ /* try to see if card responses to "chinese magic backdoor" commands. */
void detect_classic_magic(void) { void detect_classic_magic(void) {
uint8_t isGeneration = 0; uint8_t isGeneration = 0;
PacketResponseNG resp; PacketResponseNG resp;
PacketCommandOLD c = {CMD_MIFARE_CIDENT, {0, 0, 0}, {{0}}};
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommandOLD(CMD_MIFARE_CIDENT, 0, 0, 0, NULL, 0);
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) if (WaitForResponseTimeout(CMD_ACK, &resp, 1500))
isGeneration = resp.oldarg[0] & 0xff; isGeneration = resp.oldarg[0] & 0xff;