fiddled with pm3 client informative text

This commit is contained in:
iceman1001 2025-03-22 13:09:55 +01:00
commit c0af6cd7d2
6 changed files with 248 additions and 164 deletions

View file

@ -79,21 +79,24 @@ static bool mifare_wakeup_auth(struct Crypto1State *pcs, MifareWakeupType wakeup
LED_C_OFF();
switch (wakeup) {
case MF_WAKE_NONE:
case MF_WAKE_NONE: {
break;
case MF_WAKE_WUPA:
if (!iso14443a_select_cardEx(NULL, NULL, &cuid, true, 0, true, &WUPA_POLLING_PARAMETERS)) {
}
case MF_WAKE_WUPA: {
if (iso14443a_select_cardEx(NULL, NULL, &cuid, true, 0, true, &WUPA_POLLING_PARAMETERS) == 0) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
return false;
};
break;
case MF_WAKE_REQA:
if (!iso14443a_select_cardEx(NULL, NULL, &cuid, true, 0, true, &REQA_POLLING_PARAMETERS)) {
}
case MF_WAKE_REQA: {
if (iso14443a_select_cardEx(NULL, NULL, &cuid, true, 0, true, &REQA_POLLING_PARAMETERS) == 0) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
return false;
};
break;
case MF_WAKE_GEN1A:
}
case MF_WAKE_GEN1A: {
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupC1 error");
@ -105,14 +108,16 @@ static bool mifare_wakeup_auth(struct Crypto1State *pcs, MifareWakeupType wakeup
if (g_dbglevel >= DBG_INFO) Dbprintf("Assuming Magic Gen 1B tag. [wupC2 failed]");
}
break;
case MF_WAKE_GEN1B:
}
case MF_WAKE_GEN1B: {
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupC1 error");
return false;
}
break;
case MF_WAKE_GDM_ALT:
}
case MF_WAKE_GDM_ALT: {
ReaderTransmitBitsPar(wupGDM1, 7, NULL, NULL);
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupGDM1 error");
@ -125,6 +130,7 @@ static bool mifare_wakeup_auth(struct Crypto1State *pcs, MifareWakeupType wakeup
}
break;
}
}
if (key_auth_cmd != 0) {
uint64_t ui64key = bytes_to_num(key, 6);
@ -158,9 +164,9 @@ int16_t mifare_cmd_readblocks(MifareWakeupType wakeup, uint8_t key_auth_cmd, uin
goto OUT;
}
// frame waiting time (FWT) in 1/fc
// frame waiting time (FWT) in 1/fc (524288)
uint32_t fwt = 256 * 16 * (1 << 7);
iso14a_set_timeout(fwt / (8 * 16));
iso14a_set_timeout(fwt / (8 * 16)); // 4096
for (uint8_t i = 0; i < count; i++) {
if (mifare_classic_readblock_ex(pcs, block_no + i, block_data + (i * 16), read_cmd)) {
@ -262,7 +268,7 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes) {
clear_trace();
set_tracing(true);
if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) {
if (iso14443a_select_card(NULL, NULL, NULL, true, 0, true) == 0) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
OnError(0);
return;
@ -292,7 +298,7 @@ void MifareUL_AES_Auth(bool turn_off_field, uint8_t keyno, uint8_t *keybytes) {
clear_trace();
set_tracing(true);
if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) {
if (iso14443a_select_card(NULL, NULL, NULL, true, 0, true) == 0) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
OnErrorNG(CMD_HF_MIFAREULAES_AUTH, PM3_ESOFT);
return;
@ -327,9 +333,8 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) {
clear_trace();
set_tracing(true);
int len = iso14443a_select_card(NULL, NULL, NULL, true, 0, true);
if (!len) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card (RC:%02X)", len);
if (iso14443a_select_card(NULL, NULL, NULL, true, 0, true) == 0) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
OnError(1);
return;
}
@ -401,8 +406,8 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
}
int len = iso14443a_select_card(NULL, NULL, NULL, true, 0, true);
if (!len) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card (RC:%d)", len);
if (len == 0) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
OnError(1);
return;
}
@ -412,7 +417,7 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
uint8_t key[16] = {0x00};
memcpy(key, datain, sizeof(key));
if (!mifare_ultra_auth(key)) {
if (mifare_ultra_auth(key) == 0) {
OnError(1);
return;
}
@ -424,7 +429,7 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
memcpy(pwd, datain, sizeof(pwd));
uint8_t pack[4] = {0, 0, 0, 0};
if (!mifare_ul_ev1_auth(pwd, pack)) {
if (mifare_ul_ev1_auth(pwd, pack) == 0) {
OnError(1);
return;
}
@ -507,7 +512,8 @@ void MifareValue(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) {
LED_C_OFF();
while (true) {
if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
if (iso14443a_select_card(uid, NULL, &cuid, true, 0, true) == 0) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
break;
};
@ -578,7 +584,7 @@ static void MifareUWriteBlockEx(uint8_t arg0, uint8_t arg1, uint8_t *datain, boo
clear_trace();
set_tracing(true);
if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) {
if (iso14443a_select_card(NULL, NULL, NULL, true, 0, true) == 0) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
OnError(0);
return;
@ -589,7 +595,7 @@ static void MifareUWriteBlockEx(uint8_t arg0, uint8_t arg1, uint8_t *datain, boo
uint8_t key[16] = {0x00};
memcpy(key, datain + 4, sizeof(key));
if (!mifare_ultra_auth(key)) {
if (mifare_ultra_auth(key) == 0) {
OnError(1);
return;
}
@ -600,7 +606,7 @@ static void MifareUWriteBlockEx(uint8_t arg0, uint8_t arg1, uint8_t *datain, boo
uint8_t pwd[4] = {0x00};
memcpy(pwd, datain + 4, 4);
uint8_t pack[4] = {0, 0, 0, 0};
if (!mifare_ul_ev1_auth(pwd, pack)) {
if (mifare_ul_ev1_auth(pwd, pack) == 0) {
OnError(1);
return;
}
@ -620,8 +626,9 @@ static void MifareUWriteBlockEx(uint8_t arg0, uint8_t arg1, uint8_t *datain, boo
if (g_dbglevel >= 2) DbpString("WRITE BLOCK FINISHED");
if (reply)
if (reply) {
reply_mix(CMD_ACK, 1, 0, 0, 0, 0);
}
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
set_tracing(false);
@ -652,7 +659,7 @@ void MifareUWriteBlockCompat(uint8_t arg0, uint8_t arg1, uint8_t *datain) {
clear_trace();
set_tracing(true);
if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) {
if (iso14443a_select_card(NULL, NULL, NULL, true, 0, true) == 0) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
OnError(0);
return;
@ -663,7 +670,7 @@ void MifareUWriteBlockCompat(uint8_t arg0, uint8_t arg1, uint8_t *datain) {
uint8_t key[16] = {0x00};
memcpy(key, datain + 16, sizeof(key));
if (!mifare_ultra_auth(key)) {
if (mifare_ultra_auth(key) == 0) {
OnError(1);
return;
}
@ -715,7 +722,7 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain) {
clear_trace();
set_tracing(true);
if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) {
if (iso14443a_select_card(NULL, NULL, NULL, true, 0, true) == 0) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
OnError(0);
return;
@ -805,8 +812,9 @@ void MifareAcquireNonces(uint32_t arg0, uint32_t flags) {
BigBuf_Clear_ext(false);
set_tracing(true);
if (initialize)
if (initialize) {
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
}
LED_C_ON();
@ -918,8 +926,9 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
BigBuf_Clear_ext(false);
set_tracing(false);
if (initialize)
if (initialize) {
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
}
LED_C_ON();
@ -1730,16 +1739,18 @@ typedef struct chk_t {
// fast select, tries 5 times to select
//
// return:
// 2 = failed to select.
// 1 = wrong key
// 0 = correct key
// 4 = failed to select
// 3 = failed auth
// 2 = timeout
// 1 = failed auth
// 0 = correct
static uint8_t chkKey(struct chk_t *c) {
uint8_t i = 0, res = 2;
bool selected = false;
while (i < 5) {
// this part is from Piwi's faster nonce collecting part in Hardnested.
// assume: fast select
if (!iso14443a_fast_select_card(c->uid, c->cl)) {
if (iso14443a_fast_select_card(c->uid, c->cl) == 0) {
++i;
continue;
}
@ -1755,27 +1766,29 @@ static uint8_t chkKey(struct chk_t *c) {
}
if (selected == false) {
Dbprintf("chkKey: Failed at fast selecting the card!");
res = 4;
}
return res;
}
static uint8_t chkKey_readb(struct chk_t *c, uint8_t *keyb) {
if (!iso14443a_fast_select_card(c->uid, c->cl))
if (iso14443a_fast_select_card(c->uid, c->cl) == 0) {
return 2;
}
if (mifare_classic_authex(c->pcs, c->cuid, c->block, 0, c->key, AUTH_FIRST, NULL, NULL))
if (mifare_classic_authex(c->pcs, c->cuid, c->block, 0, c->key, AUTH_FIRST, NULL, NULL)) {
return 1;
}
uint8_t data[16] = {0x00};
uint8_t res = mifare_classic_readblock(c->pcs, c->block, data);
// successful read
if (!res) {
if (res == 0) {
// data was something else than zeros.
if (memcmp(data + 10, "\x00\x00\x00\x00\x00\x00", 6) != 0) {
memcpy(keyb, data + 10, 6);
res = 0;
} else {
res = 3;
}
@ -1788,11 +1801,19 @@ static void chkKey_scanA(struct chk_t *c, struct sector_t *k_sector, uint8_t *fo
for (uint8_t s = 0; s < *sectorcnt; s++) {
// skip already found A keys
if (found[(s * 2)])
if (found[(s * 2)]) {
continue;
}
c->block = FirstBlockOfSector(s);
if (chkKey(c) == 0) {
uint8_t res = chkKey(c);
if (res == 4) {
// failed to select, return immediately
return;
}
if (res == 0) {
num_to_bytes(c->key, 6, k_sector[s].keyA);
found[(s * 2)] = 1;
++*foundkeys;
@ -1806,11 +1827,19 @@ static void chkKey_scanB(struct chk_t *c, struct sector_t *k_sector, uint8_t *fo
for (uint8_t s = 0; s < *sectorcnt; s++) {
// skip already found B keys
if (found[(s * 2) + 1])
if (found[(s * 2) + 1]) {
continue;
}
c->block = FirstBlockOfSector(s);
if (chkKey(c) == 0) {
uint8_t res = chkKey(c);
if (res == 4) {
// failed to select, return immediately
return;
}
if (res == 0) {
num_to_bytes(c->key, 6, k_sector[s].keyB);
found[(s * 2) + 1] = 1;
++*foundkeys;
@ -1827,8 +1856,9 @@ static void chkKey_loopBonly(struct chk_t *c, struct sector_t *k_sector, uint8_t
// read Block B, if A is found.
for (uint8_t s = 0; s < *sectorcnt; ++s) {
if (found[(s * 2)] && found[(s * 2) + 1])
if (found[(s * 2)] && found[(s * 2) + 1]) {
continue;
}
c->block = (FirstBlockOfSector(s) + NumBlocksPerSector(s) - 1);
@ -1885,7 +1915,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
static uint8_t foundkeys = 0;
static sector_t k_sector[80];
static uint8_t found[80];
static uint8_t *uid;
static uint8_t uid[10] = {0};
int oldbg = g_dbglevel;
@ -1896,29 +1926,31 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
if (exists_in_spiffs(MF_KEYS_FILE)) {
size = size_in_spiffs(MF_KEYS_FILE);
}
if ((size == 0) || (size < MF_KEY_LENGTH)) {
Dbprintf("Spiffs file: %s does not exists or empty.", MF_KEYS_FILE);
Dbprintf("Spiffs file `" _RED_("%s") "` does not exists or empty", MF_KEYS_FILE);
goto OUT;
}
// Compute how many keys can fit in bigbuff
// a key is 6bytes
uint16_t key_mem_available = MIN(BigBuf_get_size() / MF_KEY_LENGTH, keyCount + (size / MF_KEY_LENGTH));
// Compute how many keys can fit in bigbuf
// a key is 6 bytes
uint16_t key_mem_available = MIN( (BigBuf_get_size() / MF_KEY_LENGTH), (keyCount + (size / MF_KEY_LENGTH)));
uint8_t *dictkeys = BigBuf_malloc(key_mem_available * MF_KEY_LENGTH);
if (dictkeys == NULL)
uint8_t *dictkeys = BigBuf_calloc(key_mem_available * MF_KEY_LENGTH);
if (dictkeys == NULL) {
goto OUT;
}
// Put user and hard-coded keys first
memcpy(dictkeys, datain, keyCount * MF_KEY_LENGTH);
// Now append the SPI flash dictionnary
if (SPIFFS_OK == rdv40_spiffs_read_as_filetype(MF_KEYS_FILE, dictkeys + keyCount * MF_KEY_LENGTH, (key_mem_available - keyCount) * MF_KEY_LENGTH, RDV40_SPIFFS_SAFETY_SAFE)) {
if (SPIFFS_OK == rdv40_spiffs_read_as_filetype(MF_KEYS_FILE, dictkeys + (keyCount * MF_KEY_LENGTH), (key_mem_available - keyCount) * MF_KEY_LENGTH, RDV40_SPIFFS_SAFETY_SAFE)) {
if (g_dbglevel >= DBG_ERROR) {
Dbprintf("Loaded %u keys from spiffs file: %s", key_mem_available, MF_KEYS_FILE);
Dbprintf("loaded " _GREEN_("%u") " keys from spiffs file `" _YELLOW_("%s") "`", key_mem_available, MF_KEYS_FILE);
}
} else {
Dbprintf("Spiffs file: %s cannot be read.", MF_KEYS_FILE);
Dbprintf("Spiffs file `" _RED_("%s") "` cannot be read", MF_KEYS_FILE);
goto OUT;
}
// Replace client provided keys
@ -1926,12 +1958,6 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
}
#endif
if (uid == NULL || firstchunk) {
uid = BigBuf_malloc(10);
if (uid == NULL)
goto OUT;
}
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
LEDsoff();
@ -1946,7 +1972,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
foundkeys = 0;
iso14a_card_select_t card_info;
if (!iso14443a_select_card(uid, &card_info, &cuid, true, 0, true)) {
if (iso14443a_select_card(uid, &card_info, &cuid, true, 0, true) == 0) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("ChkKeys_fast: Can't select card (ALL)");
goto OUT;
}
@ -1991,10 +2017,10 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
WDT_HIT();
chk_data.key = bytes_to_num(datain + i * 6, 6);
chk_data.key = bytes_to_num(datain + (i * MF_KEY_LENGTH), MF_KEY_LENGTH);
if (chkKey(&chk_data) == 0) {
foundkeys++;
reply_old(CMD_ACK, 1, 0, 0, datain + i * 6, 6);
reply_old(CMD_ACK, 1, 0, 0, datain + (i * MF_KEY_LENGTH), MF_KEY_LENGTH);
goto out;
}
}
@ -2024,8 +2050,9 @@ out:
// keep track of how many sectors on card.
for (uint8_t s = 0; s < sectorcnt; ++s) {
if (found[(s * 2)] && found[(s * 2) + 1])
if (found[(s * 2)] && found[(s * 2) + 1]) {
continue;
}
for (uint16_t i = s_point; i < keyCount; ++i) {
@ -2035,8 +2062,9 @@ out:
}
// found all keys?
if (foundkeys == allkeys)
if (foundkeys == allkeys) {
goto OUT;
}
WDT_HIT();
@ -2044,14 +2072,21 @@ out:
chk_data.block = FirstBlockOfSector(s);
// new key
chk_data.key = bytes_to_num(datain + i * 6, 6);
chk_data.key = bytes_to_num(datain + (i * MF_KEY_LENGTH), MF_KEY_LENGTH);
// skip already found A keys
if (!found[(s * 2)]) {
chk_data.keyType = 0;
status = chkKey(&chk_data);
if (status == 4) {
// failed to select, return immediately
goto OUT;
}
if (status == 0) {
memcpy(k_sector[s].keyA, datain + i * 6, 6);
memcpy(k_sector[s].keyA, datain + (i * MF_KEY_LENGTH), MF_KEY_LENGTH);
found[(s * 2)] = 1;
++foundkeys;
@ -2080,10 +2115,17 @@ out:
// skip already found B keys
if (!found[(s * 2) + 1]) {
chk_data.keyType = 1;
status = chkKey(&chk_data);
if (status == 4) {
// failed to select, return immediately
goto OUT;
}
if (status == 0) {
memcpy(k_sector[s].keyB, datain + i * 6, 6);
memcpy(k_sector[s].keyB, datain + (i * MF_KEY_LENGTH), MF_KEY_LENGTH);
found[(s * 2) + 1] = 1;
++foundkeys;
@ -2101,20 +2143,23 @@ out:
}
}
if (found[(s * 2)] && found[(s * 2) + 1])
if (found[(s * 2)] && found[(s * 2) + 1]) {
break;
}
} // end keys test loop - depth first
// assume1. if no keys found in first sector, get next keychunk from client
if (!use_flashmem && (newfound - foundkeys == 0))
if (!use_flashmem && (newfound - foundkeys == 0)) {
goto OUT;
}
} // end loop - sector
} // end strategy 1
if (foundkeys == allkeys)
if (foundkeys == allkeys) {
goto OUT;
}
if (strategy == 2 || use_flashmem) {
@ -2122,36 +2167,43 @@ out:
for (uint16_t i = 0; i < keyCount; i++) {
// Allow button press / usb cmd to interrupt device
if (BUTTON_PRESS() || data_available()) break;
if (BUTTON_PRESS() || data_available()) {
break;
}
// found all keys?
if (foundkeys == allkeys)
if (foundkeys == allkeys) {
goto OUT;
}
WDT_HIT();
// new key
chk_data.key = bytes_to_num(datain + i * 6, 6);
chk_data.key = bytes_to_num(datain + (i * MF_KEY_LENGTH), MF_KEY_LENGTH);
// Sector main loop
// keep track of how many sectors on card.
for (uint8_t s = 0; s < sectorcnt; ++s) {
if (found[(s * 2)] && found[(s * 2) + 1]) continue;
if (found[(s * 2)] && found[(s * 2) + 1]) {
continue;
}
// found all keys?
if (foundkeys == allkeys)
if (foundkeys == allkeys) {
goto OUT;
}
// assume: block0,1,2 has more read rights in accessbits than the sectortrailer. authenticating against block0 in each sector
chk_data.block = FirstBlockOfSector(s);
// skip already found A keys
if (!found[(s * 2)]) {
chk_data.keyType = 0;
if (found[(s * 2)] == 0) {
chk_data.keyType = MF_KEY_A;
status = chkKey(&chk_data);
if (status == 0) {
memcpy(k_sector[s].keyA, datain + i * 6, 6);
memcpy(k_sector[s].keyA, datain + (i * MF_KEY_LENGTH), MF_KEY_LENGTH);
found[(s * 2)] = 1;
++foundkeys;
@ -2165,11 +2217,12 @@ out:
}
// skip already found B keys
if (!found[(s * 2) + 1]) {
chk_data.keyType = 1;
if (found[(s * 2) + 1] == 0) {
chk_data.keyType = MF_KEY_B;
status = chkKey(&chk_data);
if (status == 0) {
memcpy(k_sector[s].keyB, datain + i * 6, 6);
memcpy(k_sector[s].keyB, datain + (i * MF_KEY_LENGTH), MF_KEY_LENGTH);
found[(s * 2) + 1] = 1;
++foundkeys;
@ -2226,8 +2279,8 @@ OUT:
// get ST
emlGetMem_xt(block, blockno, 1, MIFARE_BLOCK_SIZE);
memcpy(block, k_sector[i].keyA, 6);
memcpy(block + 10, k_sector[i].keyB, 6);
memcpy(block, k_sector[i].keyA, MF_KEY_LENGTH);
memcpy(block + 10, k_sector[i].keyB, MF_KEY_LENGTH);
emlSetMem_xt(block, blockno, 1, sizeof(block));
}
@ -2257,7 +2310,7 @@ void MifareChkKeys(uint8_t *datain, uint8_t reserved_mem) {
uint32_t cuid = 0;
uint8_t cascade_levels = 0;
struct {
uint8_t key[6];
uint8_t key[MF_KEY_LENGTH];
bool found;
} PACKED keyresult;
keyresult.found = false;
@ -2272,11 +2325,11 @@ void MifareChkKeys(uint8_t *datain, uint8_t reserved_mem) {
uint16_t key_mem_available;
if (reserved_mem)
key_mem_available = key_count * 6;
key_mem_available = key_count * MF_KEY_LENGTH;
else
key_mem_available = MIN((PM3_CMD_DATA_SIZE - 5), key_count * 6);
key_mem_available = MIN((PM3_CMD_DATA_SIZE - 5), (key_count * MF_KEY_LENGTH));
key_count = key_mem_available / 6;
key_count = (key_mem_available / MF_KEY_LENGTH);
datain += 5;
@ -2331,7 +2384,7 @@ void MifareChkKeys(uint8_t *datain, uint8_t reserved_mem) {
continue;
}
memcpy(keyresult.key, datain + i * 6, 6);
memcpy(keyresult.key, datain + (i * MF_KEY_LENGTH), MF_KEY_LENGTH);
keyresult.found = true;
break;
}
@ -2471,7 +2524,7 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype, uint8_t *key) {
// increase time-out. Magic card etc are slow
uint32_t timeout = iso14a_get_timeout();
// frame waiting time (FWT) in 1/fc
uint32_t fwt = 256 * 16 * (1 << 6);
uint32_t fwt = 256 * 16 * (1 << 7);
iso14a_set_timeout(fwt / (8 * 16));
for (uint8_t s = 0; s < sectorcnt; s++) {
@ -2873,15 +2926,19 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain) {
}
// if MAGIC_DATAIN, the data stays on device side.
if (workFlags & MAGIC_DATAIN) {
if (isOK) {
memcpy(datain, data, sizeof(data));
}
} else {
if (isOK) {
reply_old(CMD_ACK, 1, 0, 0, data, sizeof(data));
} else {
OnErrorMagic(errormsg);
}
}
if (workFlags & MAGIC_OFF) {
@ -2908,13 +2965,12 @@ void MifareCIdent(bool is_mfc, uint8_t keytype, uint8_t *key) {
uint8_t gen4gdmGetMagicBlock[4] = {MIFARE_MAGIC_GDM_READBLOCK, 0x00, 0xC2, 0x66};
uint8_t gen4GetConf[8] = {GEN_4GTU_CMD, 0x00, 0x00, 0x00, 0x00, GEN_4GTU_GETCNF, 0, 0};
uint8_t superGen1[9] = {0x0A, 0x00, 0x00, 0xA6, 0xB0, 0x00, 0x10, 0x14, 0x1D};
bool isGen2 = false;
uint8_t uid[10];
uint8_t *par = BigBuf_calloc(MAX_PARITY_SIZE);
uint8_t *buf = BigBuf_calloc(PM3_CMD_DATA_SIZE);
uint8_t *uid = BigBuf_calloc(10);
iso14a_card_select_t *card = (iso14a_card_select_t *) BigBuf_calloc(sizeof(iso14a_card_select_t));
bool isGen2 = false;
uint16_t flag = MAGIC_FLAG_NONE;
uint32_t cuid = 0;
int res = 0;
@ -3121,9 +3177,7 @@ void MifareHasStaticNonce(void) {
// variables
int retval = PM3_SUCCESS;
uint32_t nt = 0;
uint8_t *uid = BigBuf_malloc(10);
memset(uid, 0x00, 10);
uint8_t uid[10] = {0};
uint8_t data[1] = { NONCE_FAIL };
struct Crypto1State mpcs = {0, 0};
@ -3135,7 +3189,7 @@ void MifareHasStaticNonce(void) {
uint8_t counter = 0;
for (uint8_t i = 0; i < 3; i++) {
if (!iso14443a_select_card(uid, NULL, NULL, true, 0, true)) {
if (iso14443a_select_card(uid, NULL, NULL, true, 0, true) == 0) {
retval = PM3_ESOFT;
goto OUT;
}
@ -3219,6 +3273,7 @@ void MifareHasStaticEncryptedNonce(uint8_t block_no, uint8_t key_type, uint8_t *
uint32_t ntenc = 0;
uint8_t ntencpar = 0;
bool is_last_auth_first_auth = true;
if (nr_nested == 0) {
cuid = 0;
if (iso14443a_select_card(NULL, NULL, &cuid, true, 0, true) == false) {
@ -3232,8 +3287,11 @@ void MifareHasStaticEncryptedNonce(uint8_t block_no, uint8_t key_type, uint8_t *
goto OUT;
};
first_nt_counter++;
} else {
for (uint8_t i = 0; i < nr_nested; i++) {
if (need_first_auth) {
cuid = 0;
@ -3246,43 +3304,55 @@ void MifareHasStaticEncryptedNonce(uint8_t block_no, uint8_t key_type, uint8_t *
SpinDelay(150);
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
}
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("select");
}
if (iso14443a_select_card(NULL, NULL, &cuid, true, 0, true) == false) {
retval = PM3_ESOFT;
goto OUT;
}
if (mifare_classic_authex_cmd(pcs, cuid, block_no, key_auth_cmd, ui64key, AUTH_FIRST, &nt_first, NULL, NULL, NULL, corruptnrar, corruptnrarparity)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Auth error");
retval = PM3_ESOFT;
goto OUT;
};
is_last_auth_first_auth = true;
first_nt_counter++;
if ((first_nt_counter > 1) && (old_nt_first == nt_first)) {
first_nt_repetition_counter++;
}
old_nt_first = nt_first;
if (!reset && !hardreset) {
need_first_auth = false;
}
if (addread) {
uint8_t dataread[16] = {0x00};
mifare_classic_readblock(pcs, block_no, dataread);
}
if (addauth) {
if (mifare_classic_authex_cmd(pcs, cuid, block_no, key_auth_cmd, ui64key, AUTH_NESTED, &nt, NULL, NULL, NULL, false, false)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Auth error");
retval = PM3_ESOFT;
goto OUT;
} else if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("Nonce distance: %5i (first nonce <> nested nonce)", nonce_distance(nt_first, nt));
}
is_last_auth_first_auth = false;
if (nt == nt_first) {
first_and_nested_nt_repetition_counter++;
}
old_nt = nt;
}
}
@ -3290,21 +3360,26 @@ void MifareHasStaticEncryptedNonce(uint8_t block_no, uint8_t key_type, uint8_t *
nt = 0;
ntenc = 0;
if (mifare_classic_authex_cmd(pcs, cuid, incblk2 ? block_no_nested + (i * 4) : block_no_nested, key_auth_cmd_nested, ui64key_nested, AUTH_NESTED, &nt, &ntenc, &ntencpar, NULL, false, false)) {
if (g_dbglevel >= DBG_ERROR) Dbprintf("Nested auth error");
need_first_auth = true;
} else if (g_dbglevel >= DBG_EXTENDED) {
if (is_last_auth_first_auth) {
Dbprintf("Nonce distance: %5i (first nonce <> nested nonce)", nonce_distance(nt_first, nt));
} else {
Dbprintf("Nonce distance: %5i", nonce_distance(old_nt, nt));
}
}
nested_nt_session_counter++;
is_last_auth_first_auth = false;
old_nt = nt;
if (nt == nt_first) {
first_and_nested_nt_repetition_counter++;
}
if ((nested_nt_session_counter > 1) && (oldntenc == ntenc)) {
nested_nt_repetition_counter++;
}
@ -3316,18 +3391,21 @@ void MifareHasStaticEncryptedNonce(uint8_t block_no, uint8_t key_type, uint8_t *
data[2] = (cuid >> 16) & 0xFF;
data[3] = (cuid >> 8) & 0xFF;
data[4] = (cuid >> 0) & 0xFF;
if (first_and_nested_nt_repetition_counter) {
data[0] = NONCE_SUPERSTATIC;
data[5] = (nt >> 24) & 0xFF;
data[6] = (nt >> 16) & 0xFF;
data[7] = (nt >> 8) & 0xFF;
data[8] = (nt >> 0) & 0xFF;
} else if (first_nt_repetition_counter) {
data[0] = NONCE_STATIC;
data[5] = (nt_first >> 24) & 0xFF;
data[6] = (nt_first >> 16) & 0xFF;
data[7] = (nt_first >> 8) & 0xFF;
data[8] = (nt_first >> 0) & 0xFF;
} else if (nested_nt_repetition_counter) {
data[0] = NONCE_STATIC_ENC;
data[5] = (nt >> 24) & 0xFF;
@ -3339,6 +3417,7 @@ void MifareHasStaticEncryptedNonce(uint8_t block_no, uint8_t key_type, uint8_t *
data[11] = (ntenc >> 8) & 0xFF;
data[12] = (ntenc >> 0) & 0xFF;
data[13] = ntencpar;
} else {
data[0] = NONCE_NORMAL;
data[5] = (nt >> 24) & 0xFF;

View file

@ -156,7 +156,9 @@ int mifare_classic_authex_cmd(struct Crypto1State *pcs, uint32_t uid, uint8_t bl
// Transmit MIFARE_CLASSIC_AUTH, 0x60 for key A, 0x61 for key B, or 0x80 for GDM backdoor
int len = mifare_sendcmd_short(pcs, isNested, cmd, blockNo, receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar, timing);
if (len != 4) return 1;
if (len != 4) {
return 1;
}
// Save the tag nonce (nt)
uint32_t nt = bytes_to_num(receivedAnswer, 4);
@ -334,8 +336,9 @@ int mifare_ul_ev1_auth(uint8_t *keybytes, uint8_t *pack) {
return 0;
}
if (g_dbglevel >= DBG_EXTENDED)
if (g_dbglevel >= DBG_EXTENDED) {
Dbprintf("Auth Resp: %02x%02x%02x%02x", resp[0], resp[1], resp[2], resp[3]);
}
memcpy(pack, resp, 4);
return 1;
@ -490,6 +493,7 @@ int mifare_ultra_aes_auth(uint8_t keyno, uint8_t *keybytes) {
memset(IV, 0, 16);
mbedtls_aes_setkey_dec(&actx, key, 128);
mbedtls_aes_crypt_cbc(&actx, MBEDTLS_AES_DECRYPT, sizeof(random_b), IV, resp + 1, random_b);
mbedtls_aes_free(&actx);
if (memcmp(random_b, random_a, 16) != 0) {
if (g_dbglevel >= DBG_INFO) Dbprintf("failed authentication");
@ -507,8 +511,6 @@ int mifare_ultra_aes_auth(uint8_t keyno, uint8_t *keybytes) {
Dbprintf("B:");
Dbhexdump(16, random_b, false);
}
mbedtls_aes_free(&actx);
return 1;
}

View file

@ -577,20 +577,26 @@ int rdv40_spiffs_make_symlink(const char *linkdest, const char *filename, RDV40S
// preexistence, avoiding a link being created if filename exists, or avoiding a file being created if
// symlink exists with same name
int rdv40_spiffs_read_as_filetype(const char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level) {
RDV40_SPIFFS_SAFE_FUNCTION(
RDV40SpiFFSFileType filetype = filetype_in_spiffs((char *)filename);
switch (filetype) {
case RDV40_SPIFFS_FILETYPE_REAL:
case RDV40_SPIFFS_FILETYPE_REAL: {
rdv40_spiffs_read(filename, dst, size, level);
break;
case RDV40_SPIFFS_FILETYPE_SYMLINK:
}
case RDV40_SPIFFS_FILETYPE_SYMLINK: {
rdv40_spiffs_read_as_symlink(filename, dst, size, level);
break;
}
case RDV40_SPIFFS_FILETYPE_BOTH:
case RDV40_SPIFFS_FILETYPE_UNKNOWN:
default:
default: {
break;
}
}
)
}

View file

@ -240,47 +240,47 @@ int CmdHFSearch(const char *Cmd) {
// no need to print 14A hints, since it will print itself
if (success[THINFILM]) {
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf thinfilm") "` commands\n");
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf thinfilm") "` commands\n");
}
if (success[LTO]) {
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf lto") "` commands\n");
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf lto") "` commands\n");
}
if (success[LEGIC]) {
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf legic") "` commands\n");
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf legic") "` commands\n");
}
if (success[TOPAZ]) {
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf topaz") "` commands\n");
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf topaz") "` commands\n");
}
if (success[PROTO_TEXKOM]) {
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf texkom") "` commands\n");
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf texkom") "` commands\n");
}
if (success[PROTO_XEROX]) {
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf xerox") "` commands\n");
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf xerox") "` commands\n");
}
if (success[ISO_14443B]) {
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf 14b") "` commands\n");
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf 14b") "` commands\n");
}
if (success[ISO_15693]) {
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf 15") "` commands\n");
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf 15") "` commands\n");
}
if (success[ICLASS]) {
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf iclass") "` commands\n");
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf iclass") "` commands\n");
}
if (success[FELICA]) {
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf felica") "` commands\n");
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf felica") "` commands\n");
}
if (success[PROTO_CRYPTORF]) {
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf cryptorf") "` commands\n");
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf cryptorf") "` commands\n");
}
}

View file

@ -520,7 +520,7 @@ int Hf14443_4aGetCardData(iso14a_card_select_t *card) {
PrintAndLogEx(INFO, "Card doesn't support standard iso14443-3 anticollision");
// identify TOPAZ
if (card->atqa[1] == 0x0C && card->atqa[0] == 0x00) {
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf topaz info`"));
PrintAndLogEx(HINT, "Hint: Try " _YELLOW_("`hf topaz info`"));
} else {
PrintAndLogEx(SUCCESS, "\tATQA : %02X %02X", card->atqa[1], card->atqa[0]);
}
@ -685,7 +685,7 @@ static int CmdHF14AReader(const char *Cmd) {
// identify TOPAZ
if (card.atqa[1] == 0x0C && card.atqa[0] == 0x00) {
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf topaz info`"));
PrintAndLogEx(HINT, "Hint: Try " _YELLOW_("`hf topaz info`"));
} else {
PrintAndLogEx(SUCCESS, "ATQA: %02X %02X", card.atqa[1], card.atqa[0]);
}
@ -2161,7 +2161,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
// identify TOPAZ
if (card.atqa[1] == 0x0C && card.atqa[0] == 0x00) {
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf topaz info`"));
PrintAndLogEx(HINT, "Hint: Try " _YELLOW_("`hf topaz info`"));
}
DropField();
@ -2746,42 +2746,42 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
if (isMifareUltralight) {
if (((isMagic & MAGIC_FLAG_GEN_1A) == MAGIC_FLAG_GEN_1A) || ((isMagic & MAGIC_FLAG_GEN_1B) == MAGIC_FLAG_GEN_1B)) {
PrintAndLogEx(HINT, "Hint: use `" _YELLOW_("hf mfu *") "` magic commands");
PrintAndLogEx(HINT, "Hint: Use `" _YELLOW_("hf mfu *") "` magic commands");
}
if ((isMagic & MAGIC_FLAG_NTAG21X) == MAGIC_FLAG_NTAG21X) {
PrintAndLogEx(HINT, "Hint: use `" _YELLOW_("hf mfu *") "` magic commands");
PrintAndLogEx(HINT, "Hint: Use `" _YELLOW_("hf mfu *") "` magic commands");
}
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf mfu info") "`");
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf mfu info") "`");
}
if (isMifarePlus && (isMagic == MAGIC_FLAG_NONE)) {
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf mfp info") "`");
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf mfp info") "`");
}
if (isMifareDESFire && (isMagic == MAGIC_FLAG_NONE) && isEMV == false) {
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf mfdes info") "`");
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf mfdes info") "`");
}
if (isST) {
if (card.ats_len > 0) {
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf st25ta info") "`");
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf st25ta info") "`");
} else {
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf mfu info") "`");
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf mfu info") "`");
}
}
if (isEMV) {
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("emv reader") "`");
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("emv reader") "`");
}
if (isSEOS) {
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf seos info") "`");
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf seos info") "`");
}
if (isFUDAN) {
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf fudan dump") "`");
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf fudan dump") "`");
/*
PrintAndLogEx(HINT, " hf 14a raw -a -b 7 -k 26");
PrintAndLogEx(HINT, " hf 14a raw -k -c 3000");
@ -2796,7 +2796,7 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
}
if (isNTAG424) {
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf ntag424 info") "`");
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf ntag424 info") "`");
}
if (isMifareClassic || isMifareMini) {

View file

@ -151,8 +151,6 @@ static void lookup_chipid_short(uint32_t iChipID, uint32_t mem_used) {
, mem_avail
, mem_avail == 0 ? 0.0f : (float)mem_used / (mem_avail * 1024) * 100
);
PrintAndLogEx(NORMAL, "");
}
static void lookupChipID(uint32_t iChipID, uint32_t mem_used) {
@ -1571,6 +1569,23 @@ void pm3_version_short(void) {
lookup_chipid_short(payload->id, payload->section_size);
if (IfPm3Rdv4Fw()) {
bool is_genuine_rdv4 = false;
// validate signature data
rdv40_validation_t mem;
if (rdv4_get_signature(&mem) == PM3_SUCCESS) {
if (rdv4_validate(&mem) == PM3_SUCCESS) {
is_genuine_rdv4 = true;
}
}
PrintAndLogEx(NORMAL, " Target.... %s", (is_genuine_rdv4) ? _YELLOW_("RDV4") : _RED_("device / fw mismatch"));
} else {
PrintAndLogEx(NORMAL, " Target.... %s", _YELLOW_("PM3 GENERIC"));
}
PrintAndLogEx(NORMAL, "");
// client
char temp[PM3_CMD_DATA_SIZE - 12]; // same limit as for ARM image
format_version_information_short(temp, sizeof(temp), &g_version_information);
@ -1588,42 +1603,24 @@ void pm3_version_short(void) {
}
// bootrom
ptr = strstr(payload->versionstr, " bootrom: ");
ptr = strstr(payload->versionstr, "Bootrom.... ");
if (ptr != NULL) {
char *ptr_end = strstr(ptr, "\n");
if (ptr_end != NULL) {
uint8_t len = ptr_end - 19 - ptr;
PrintAndLogEx(NORMAL, " Bootrom... %.*s", len, ptr + 10);
PrintAndLogEx(NORMAL, " Bootrom... %.*s", len, ptr + 12);
}
}
// os:
ptr = strstr(payload->versionstr, " os: ");
ptr = strstr(payload->versionstr, "OS......... ");
if (ptr != NULL) {
char *ptr_end = strstr(ptr, "\n");
if (ptr_end != NULL) {
uint8_t len = ptr_end - 14 - ptr;
PrintAndLogEx(NORMAL, " OS........ %.*s", len, ptr + 5);
PrintAndLogEx(NORMAL, " OS........ %.*s", len, ptr + 12);
}
}
if (IfPm3Rdv4Fw()) {
bool is_genuine_rdv4 = false;
// validate signature data
rdv40_validation_t mem;
if (rdv4_get_signature(&mem) == PM3_SUCCESS) {
if (rdv4_validate(&mem) == PM3_SUCCESS) {
is_genuine_rdv4 = true;
}
}
PrintAndLogEx(NORMAL, " Target.... %s", (is_genuine_rdv4) ? _YELLOW_("RDV4") : _RED_("device / fw mismatch"));
} else {
PrintAndLogEx(NORMAL, " Target.... %s", _YELLOW_("PM3 GENERIC"));
}
PrintAndLogEx(NORMAL, "");
if (armsrc_mismatch) {
@ -1643,7 +1640,7 @@ void pm3_version(bool verbose, bool oneliner) {
if (oneliner) {
// For "proxmark3 -v", simple printf, avoid logging
FormatVersionInformation(temp, sizeof(temp), "Client: ", &g_version_information);
PrintAndLogEx(NORMAL, "%s compiled with " PM3CLIENTCOMPILER __VERSION__ " OS:" PM3HOSTOS " ARCH:" PM3HOSTARCH "\n", temp);
PrintAndLogEx(NORMAL, "%s compiler: " PM3CLIENTCOMPILER __VERSION__ " OS:" PM3HOSTOS " ARCH:" PM3HOSTARCH "\n", temp);
return;
}
@ -1655,8 +1652,8 @@ void pm3_version(bool verbose, bool oneliner) {
PrintAndLogEx(NORMAL, "\n [ " _YELLOW_("Client") " ]");
FormatVersionInformation(temp, sizeof(temp), " ", &g_version_information);
PrintAndLogEx(NORMAL, "%s", temp);
PrintAndLogEx(NORMAL, " compiled with............. " PM3CLIENTCOMPILER __VERSION__);
PrintAndLogEx(NORMAL, " platform.................. " PM3HOSTOS " / " PM3HOSTARCH);
PrintAndLogEx(NORMAL, " Compiler.................. " PM3CLIENTCOMPILER __VERSION__);
PrintAndLogEx(NORMAL, " Platform.................. " PM3HOSTOS " / " PM3HOSTARCH);
#if defined(HAVE_READLINE)
PrintAndLogEx(NORMAL, " Readline support.......... " _GREEN_("present"));
#elif defined(HAVE_LINENOISE)
@ -1670,9 +1667,9 @@ void pm3_version(bool verbose, bool oneliner) {
PrintAndLogEx(NORMAL, " QT GUI support............ " _YELLOW_("absent"));
#endif
#ifdef HAVE_BLUEZ
PrintAndLogEx(NORMAL, " native BT support......... " _GREEN_("present"));
PrintAndLogEx(NORMAL, " Native BT support......... " _GREEN_("present"));
#else
PrintAndLogEx(NORMAL, " native BT support......... " _YELLOW_("absent"));
PrintAndLogEx(NORMAL, " Native BT support......... " _YELLOW_("absent"));
#endif
#ifdef HAVE_PYTHON
PrintAndLogEx(NORMAL, " Python script support..... " _GREEN_("present") " ( " _YELLOW_(PY_VERSION) " )");
@ -1692,7 +1689,7 @@ void pm3_version(bool verbose, bool oneliner) {
#endif
if (g_session.pm3_present) {
PrintAndLogEx(NORMAL, "\n [ " _YELLOW_("Proxmark3") " ]");
PrintAndLogEx(NORMAL, "\n [ " _YELLOW_("Model") " ]");
PacketResponseNG resp;
clearCommandBuffer();
@ -1710,15 +1707,15 @@ void pm3_version(bool verbose, bool oneliner) {
}
}
PrintAndLogEx(NORMAL, " device.................... %s", (is_genuine_rdv4) ? _GREEN_("RDV4") : _RED_("device / fw mismatch"));
PrintAndLogEx(NORMAL, " firmware.................. %s", (is_genuine_rdv4) ? _GREEN_("RDV4") : _YELLOW_("RDV4"));
PrintAndLogEx(NORMAL, " external flash............ %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent"));
PrintAndLogEx(NORMAL, " smartcard reader.......... %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent"));
PrintAndLogEx(NORMAL, " Device.................... %s", (is_genuine_rdv4) ? _GREEN_("RDV4") : _RED_("device / fw mismatch"));
PrintAndLogEx(NORMAL, " Firmware.................. %s", (is_genuine_rdv4) ? _GREEN_("RDV4") : _YELLOW_("RDV4"));
PrintAndLogEx(NORMAL, " External flash............ %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent"));
PrintAndLogEx(NORMAL, " Smartcard reader.......... %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent"));
PrintAndLogEx(NORMAL, " FPC USART for BT add-on... %s", IfPm3FpcUsartHost() ? _GREEN_("present") : _YELLOW_("absent"));
} else {
PrintAndLogEx(NORMAL, " firmware.................. %s", _YELLOW_("PM3 GENERIC"));
PrintAndLogEx(NORMAL, " Firmware.................. %s", _YELLOW_("PM3 GENERIC"));
if (IfPm3Flash()) {
PrintAndLogEx(NORMAL, " external flash............ %s", _GREEN_("present"));
PrintAndLogEx(NORMAL, " External flash............ %s", _GREEN_("present"));
}
if (IfPm3FpcUsartHost()) {
@ -1742,7 +1739,7 @@ void pm3_version(bool verbose, bool oneliner) {
struct p *payload = (struct p *)&resp.data.asBytes;
bool armsrc_mismatch = false;
char *ptr = strstr(payload->versionstr, " os: ");
char *ptr = strstr(payload->versionstr, "OS......... ");
if (ptr != NULL) {
ptr = strstr(ptr, "\n");
if ((ptr != NULL) && (strlen(g_version_information.armsrc) == 9)) {