mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
fiddled with pm3 client informative text
This commit is contained in:
parent
12ba14fa58
commit
c0af6cd7d2
6 changed files with 248 additions and 164 deletions
|
@ -79,21 +79,24 @@ static bool mifare_wakeup_auth(struct Crypto1State *pcs, MifareWakeupType wakeup
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
|
|
||||||
switch (wakeup) {
|
switch (wakeup) {
|
||||||
case MF_WAKE_NONE:
|
case MF_WAKE_NONE: {
|
||||||
break;
|
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");
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
break;
|
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");
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case MF_WAKE_GEN1A:
|
}
|
||||||
|
case MF_WAKE_GEN1A: {
|
||||||
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
|
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
|
||||||
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
|
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
|
||||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupC1 error");
|
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]");
|
if (g_dbglevel >= DBG_INFO) Dbprintf("Assuming Magic Gen 1B tag. [wupC2 failed]");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MF_WAKE_GEN1B:
|
}
|
||||||
|
case MF_WAKE_GEN1B: {
|
||||||
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
|
ReaderTransmitBitsPar(wupC1, 7, NULL, NULL);
|
||||||
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
|
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
|
||||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupC1 error");
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupC1 error");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MF_WAKE_GDM_ALT:
|
}
|
||||||
|
case MF_WAKE_GDM_ALT: {
|
||||||
ReaderTransmitBitsPar(wupGDM1, 7, NULL, NULL);
|
ReaderTransmitBitsPar(wupGDM1, 7, NULL, NULL);
|
||||||
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
|
if ((ReaderReceive(receivedAnswer, sizeof(receivedAnswer), receivedAnswerPar) == 0) || (receivedAnswer[0] != 0x0a)) {
|
||||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupGDM1 error");
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("wupGDM1 error");
|
||||||
|
@ -125,6 +130,7 @@ static bool mifare_wakeup_auth(struct Crypto1State *pcs, MifareWakeupType wakeup
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (key_auth_cmd != 0) {
|
if (key_auth_cmd != 0) {
|
||||||
uint64_t ui64key = bytes_to_num(key, 6);
|
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;
|
goto OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// frame waiting time (FWT) in 1/fc
|
// frame waiting time (FWT) in 1/fc (524288)
|
||||||
uint32_t fwt = 256 * 16 * (1 << 7);
|
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++) {
|
for (uint8_t i = 0; i < count; i++) {
|
||||||
if (mifare_classic_readblock_ex(pcs, block_no + i, block_data + (i * 16), read_cmd)) {
|
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();
|
clear_trace();
|
||||||
set_tracing(true);
|
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");
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
|
||||||
OnError(0);
|
OnError(0);
|
||||||
return;
|
return;
|
||||||
|
@ -292,7 +298,7 @@ void MifareUL_AES_Auth(bool turn_off_field, uint8_t keyno, uint8_t *keybytes) {
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(true);
|
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");
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
|
||||||
OnErrorNG(CMD_HF_MIFAREULAES_AUTH, PM3_ESOFT);
|
OnErrorNG(CMD_HF_MIFAREULAES_AUTH, PM3_ESOFT);
|
||||||
return;
|
return;
|
||||||
|
@ -327,9 +333,8 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) {
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(true);
|
set_tracing(true);
|
||||||
|
|
||||||
int len = iso14443a_select_card(NULL, NULL, NULL, true, 0, true);
|
if (iso14443a_select_card(NULL, NULL, NULL, true, 0, true) == 0) {
|
||||||
if (!len) {
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
|
||||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card (RC:%02X)", len);
|
|
||||||
OnError(1);
|
OnError(1);
|
||||||
return;
|
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);
|
int len = iso14443a_select_card(NULL, NULL, NULL, true, 0, true);
|
||||||
if (!len) {
|
if (len == 0) {
|
||||||
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card (RC:%d)", len);
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
|
||||||
OnError(1);
|
OnError(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -412,7 +417,7 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
uint8_t key[16] = {0x00};
|
uint8_t key[16] = {0x00};
|
||||||
memcpy(key, datain, sizeof(key));
|
memcpy(key, datain, sizeof(key));
|
||||||
|
|
||||||
if (!mifare_ultra_auth(key)) {
|
if (mifare_ultra_auth(key) == 0) {
|
||||||
OnError(1);
|
OnError(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -424,7 +429,7 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
memcpy(pwd, datain, sizeof(pwd));
|
memcpy(pwd, datain, sizeof(pwd));
|
||||||
uint8_t pack[4] = {0, 0, 0, 0};
|
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);
|
OnError(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -507,7 +512,8 @@ void MifareValue(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) {
|
||||||
LED_C_OFF();
|
LED_C_OFF();
|
||||||
|
|
||||||
while (true) {
|
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");
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
@ -578,7 +584,7 @@ static void MifareUWriteBlockEx(uint8_t arg0, uint8_t arg1, uint8_t *datain, boo
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(true);
|
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");
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
|
||||||
OnError(0);
|
OnError(0);
|
||||||
return;
|
return;
|
||||||
|
@ -589,7 +595,7 @@ static void MifareUWriteBlockEx(uint8_t arg0, uint8_t arg1, uint8_t *datain, boo
|
||||||
uint8_t key[16] = {0x00};
|
uint8_t key[16] = {0x00};
|
||||||
memcpy(key, datain + 4, sizeof(key));
|
memcpy(key, datain + 4, sizeof(key));
|
||||||
|
|
||||||
if (!mifare_ultra_auth(key)) {
|
if (mifare_ultra_auth(key) == 0) {
|
||||||
OnError(1);
|
OnError(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -600,7 +606,7 @@ static void MifareUWriteBlockEx(uint8_t arg0, uint8_t arg1, uint8_t *datain, boo
|
||||||
uint8_t pwd[4] = {0x00};
|
uint8_t pwd[4] = {0x00};
|
||||||
memcpy(pwd, datain + 4, 4);
|
memcpy(pwd, datain + 4, 4);
|
||||||
uint8_t pack[4] = {0, 0, 0, 0};
|
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);
|
OnError(1);
|
||||||
return;
|
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 (g_dbglevel >= 2) DbpString("WRITE BLOCK FINISHED");
|
||||||
|
|
||||||
if (reply)
|
if (reply) {
|
||||||
reply_mix(CMD_ACK, 1, 0, 0, 0, 0);
|
reply_mix(CMD_ACK, 1, 0, 0, 0, 0);
|
||||||
|
}
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
set_tracing(false);
|
set_tracing(false);
|
||||||
|
@ -652,7 +659,7 @@ void MifareUWriteBlockCompat(uint8_t arg0, uint8_t arg1, uint8_t *datain) {
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(true);
|
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");
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
|
||||||
OnError(0);
|
OnError(0);
|
||||||
return;
|
return;
|
||||||
|
@ -663,7 +670,7 @@ void MifareUWriteBlockCompat(uint8_t arg0, uint8_t arg1, uint8_t *datain) {
|
||||||
uint8_t key[16] = {0x00};
|
uint8_t key[16] = {0x00};
|
||||||
memcpy(key, datain + 16, sizeof(key));
|
memcpy(key, datain + 16, sizeof(key));
|
||||||
|
|
||||||
if (!mifare_ultra_auth(key)) {
|
if (mifare_ultra_auth(key) == 0) {
|
||||||
OnError(1);
|
OnError(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -715,7 +722,7 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain) {
|
||||||
clear_trace();
|
clear_trace();
|
||||||
set_tracing(true);
|
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");
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("Can't select card");
|
||||||
OnError(0);
|
OnError(0);
|
||||||
return;
|
return;
|
||||||
|
@ -805,8 +812,9 @@ void MifareAcquireNonces(uint32_t arg0, uint32_t flags) {
|
||||||
BigBuf_Clear_ext(false);
|
BigBuf_Clear_ext(false);
|
||||||
set_tracing(true);
|
set_tracing(true);
|
||||||
|
|
||||||
if (initialize)
|
if (initialize) {
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
}
|
||||||
|
|
||||||
LED_C_ON();
|
LED_C_ON();
|
||||||
|
|
||||||
|
@ -918,8 +926,9 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
|
||||||
BigBuf_Clear_ext(false);
|
BigBuf_Clear_ext(false);
|
||||||
set_tracing(false);
|
set_tracing(false);
|
||||||
|
|
||||||
if (initialize)
|
if (initialize) {
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
}
|
||||||
|
|
||||||
LED_C_ON();
|
LED_C_ON();
|
||||||
|
|
||||||
|
@ -1730,16 +1739,18 @@ typedef struct chk_t {
|
||||||
// fast select, tries 5 times to select
|
// fast select, tries 5 times to select
|
||||||
//
|
//
|
||||||
// return:
|
// return:
|
||||||
// 2 = failed to select.
|
// 4 = failed to select
|
||||||
// 1 = wrong key
|
// 3 = failed auth
|
||||||
// 0 = correct key
|
// 2 = timeout
|
||||||
|
// 1 = failed auth
|
||||||
|
// 0 = correct
|
||||||
static uint8_t chkKey(struct chk_t *c) {
|
static uint8_t chkKey(struct chk_t *c) {
|
||||||
uint8_t i = 0, res = 2;
|
uint8_t i = 0, res = 2;
|
||||||
bool selected = false;
|
bool selected = false;
|
||||||
while (i < 5) {
|
while (i < 5) {
|
||||||
// this part is from Piwi's faster nonce collecting part in Hardnested.
|
// this part is from Piwi's faster nonce collecting part in Hardnested.
|
||||||
// assume: fast select
|
// assume: fast select
|
||||||
if (!iso14443a_fast_select_card(c->uid, c->cl)) {
|
if (iso14443a_fast_select_card(c->uid, c->cl) == 0) {
|
||||||
++i;
|
++i;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1755,27 +1766,29 @@ static uint8_t chkKey(struct chk_t *c) {
|
||||||
}
|
}
|
||||||
if (selected == false) {
|
if (selected == false) {
|
||||||
Dbprintf("chkKey: Failed at fast selecting the card!");
|
Dbprintf("chkKey: Failed at fast selecting the card!");
|
||||||
|
res = 4;
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t chkKey_readb(struct chk_t *c, uint8_t *keyb) {
|
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;
|
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;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t data[16] = {0x00};
|
uint8_t data[16] = {0x00};
|
||||||
uint8_t res = mifare_classic_readblock(c->pcs, c->block, data);
|
uint8_t res = mifare_classic_readblock(c->pcs, c->block, data);
|
||||||
|
|
||||||
// successful read
|
// successful read
|
||||||
if (!res) {
|
if (res == 0) {
|
||||||
// data was something else than zeros.
|
// data was something else than zeros.
|
||||||
if (memcmp(data + 10, "\x00\x00\x00\x00\x00\x00", 6) != 0) {
|
if (memcmp(data + 10, "\x00\x00\x00\x00\x00\x00", 6) != 0) {
|
||||||
memcpy(keyb, data + 10, 6);
|
memcpy(keyb, data + 10, 6);
|
||||||
res = 0;
|
|
||||||
} else {
|
} else {
|
||||||
res = 3;
|
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++) {
|
for (uint8_t s = 0; s < *sectorcnt; s++) {
|
||||||
|
|
||||||
// skip already found A keys
|
// skip already found A keys
|
||||||
if (found[(s * 2)])
|
if (found[(s * 2)]) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
c->block = FirstBlockOfSector(s);
|
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);
|
num_to_bytes(c->key, 6, k_sector[s].keyA);
|
||||||
found[(s * 2)] = 1;
|
found[(s * 2)] = 1;
|
||||||
++*foundkeys;
|
++*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++) {
|
for (uint8_t s = 0; s < *sectorcnt; s++) {
|
||||||
|
|
||||||
// skip already found B keys
|
// skip already found B keys
|
||||||
if (found[(s * 2) + 1])
|
if (found[(s * 2) + 1]) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
c->block = FirstBlockOfSector(s);
|
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);
|
num_to_bytes(c->key, 6, k_sector[s].keyB);
|
||||||
found[(s * 2) + 1] = 1;
|
found[(s * 2) + 1] = 1;
|
||||||
++*foundkeys;
|
++*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.
|
// read Block B, if A is found.
|
||||||
for (uint8_t s = 0; s < *sectorcnt; ++s) {
|
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;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
c->block = (FirstBlockOfSector(s) + NumBlocksPerSector(s) - 1);
|
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 uint8_t foundkeys = 0;
|
||||||
static sector_t k_sector[80];
|
static sector_t k_sector[80];
|
||||||
static uint8_t found[80];
|
static uint8_t found[80];
|
||||||
static uint8_t *uid;
|
static uint8_t uid[10] = {0};
|
||||||
|
|
||||||
int oldbg = g_dbglevel;
|
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)) {
|
if (exists_in_spiffs(MF_KEYS_FILE)) {
|
||||||
size = size_in_spiffs(MF_KEYS_FILE);
|
size = size_in_spiffs(MF_KEYS_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((size == 0) || (size < MF_KEY_LENGTH)) {
|
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;
|
goto OUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute how many keys can fit in bigbuff
|
// Compute how many keys can fit in bigbuf
|
||||||
// a key is 6bytes
|
// a key is 6 bytes
|
||||||
uint16_t key_mem_available = MIN(BigBuf_get_size() / MF_KEY_LENGTH, keyCount + (size / MF_KEY_LENGTH));
|
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);
|
uint8_t *dictkeys = BigBuf_calloc(key_mem_available * MF_KEY_LENGTH);
|
||||||
if (dictkeys == NULL)
|
if (dictkeys == NULL) {
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
}
|
||||||
|
|
||||||
// Put user and hard-coded keys first
|
// Put user and hard-coded keys first
|
||||||
memcpy(dictkeys, datain, keyCount * MF_KEY_LENGTH);
|
memcpy(dictkeys, datain, keyCount * MF_KEY_LENGTH);
|
||||||
|
|
||||||
// Now append the SPI flash dictionnary
|
// 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) {
|
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 {
|
} else {
|
||||||
Dbprintf("Spiffs file: %s cannot be read.", MF_KEYS_FILE);
|
Dbprintf("Spiffs file `" _RED_("%s") "` cannot be read", MF_KEYS_FILE);
|
||||||
goto OUT;
|
goto OUT;
|
||||||
}
|
}
|
||||||
// Replace client provided keys
|
// Replace client provided keys
|
||||||
|
@ -1926,12 +1958,6 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (uid == NULL || firstchunk) {
|
|
||||||
uid = BigBuf_malloc(10);
|
|
||||||
if (uid == NULL)
|
|
||||||
goto OUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
|
@ -1946,7 +1972,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
|
||||||
foundkeys = 0;
|
foundkeys = 0;
|
||||||
|
|
||||||
iso14a_card_select_t card_info;
|
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)");
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("ChkKeys_fast: Can't select card (ALL)");
|
||||||
goto OUT;
|
goto OUT;
|
||||||
}
|
}
|
||||||
|
@ -1991,10 +2017,10 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
|
||||||
|
|
||||||
WDT_HIT();
|
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) {
|
if (chkKey(&chk_data) == 0) {
|
||||||
foundkeys++;
|
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;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2024,8 +2050,9 @@ out:
|
||||||
// keep track of how many sectors on card.
|
// keep track of how many sectors on card.
|
||||||
for (uint8_t s = 0; s < sectorcnt; ++s) {
|
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;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (uint16_t i = s_point; i < keyCount; ++i) {
|
for (uint16_t i = s_point; i < keyCount; ++i) {
|
||||||
|
|
||||||
|
@ -2035,8 +2062,9 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
// found all keys?
|
// found all keys?
|
||||||
if (foundkeys == allkeys)
|
if (foundkeys == allkeys) {
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
}
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
|
@ -2044,14 +2072,21 @@ out:
|
||||||
chk_data.block = FirstBlockOfSector(s);
|
chk_data.block = FirstBlockOfSector(s);
|
||||||
|
|
||||||
// new key
|
// 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
|
// skip already found A keys
|
||||||
if (!found[(s * 2)]) {
|
if (!found[(s * 2)]) {
|
||||||
|
|
||||||
chk_data.keyType = 0;
|
chk_data.keyType = 0;
|
||||||
status = chkKey(&chk_data);
|
status = chkKey(&chk_data);
|
||||||
|
|
||||||
|
if (status == 4) {
|
||||||
|
// failed to select, return immediately
|
||||||
|
goto OUT;
|
||||||
|
}
|
||||||
|
|
||||||
if (status == 0) {
|
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;
|
found[(s * 2)] = 1;
|
||||||
++foundkeys;
|
++foundkeys;
|
||||||
|
|
||||||
|
@ -2080,10 +2115,17 @@ out:
|
||||||
|
|
||||||
// skip already found B keys
|
// skip already found B keys
|
||||||
if (!found[(s * 2) + 1]) {
|
if (!found[(s * 2) + 1]) {
|
||||||
|
|
||||||
chk_data.keyType = 1;
|
chk_data.keyType = 1;
|
||||||
status = chkKey(&chk_data);
|
status = chkKey(&chk_data);
|
||||||
|
|
||||||
|
if (status == 4) {
|
||||||
|
// failed to select, return immediately
|
||||||
|
goto OUT;
|
||||||
|
}
|
||||||
|
|
||||||
if (status == 0) {
|
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;
|
found[(s * 2) + 1] = 1;
|
||||||
++foundkeys;
|
++foundkeys;
|
||||||
|
|
||||||
|
@ -2101,20 +2143,23 @@ out:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found[(s * 2)] && found[(s * 2) + 1])
|
if (found[(s * 2)] && found[(s * 2) + 1]) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
} // end keys test loop - depth first
|
} // end keys test loop - depth first
|
||||||
|
|
||||||
// assume1. if no keys found in first sector, get next keychunk from client
|
// 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;
|
goto OUT;
|
||||||
|
}
|
||||||
|
|
||||||
} // end loop - sector
|
} // end loop - sector
|
||||||
} // end strategy 1
|
} // end strategy 1
|
||||||
|
|
||||||
if (foundkeys == allkeys)
|
if (foundkeys == allkeys) {
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
}
|
||||||
|
|
||||||
if (strategy == 2 || use_flashmem) {
|
if (strategy == 2 || use_flashmem) {
|
||||||
|
|
||||||
|
@ -2122,36 +2167,43 @@ out:
|
||||||
for (uint16_t i = 0; i < keyCount; i++) {
|
for (uint16_t i = 0; i < keyCount; i++) {
|
||||||
|
|
||||||
// Allow button press / usb cmd to interrupt device
|
// Allow button press / usb cmd to interrupt device
|
||||||
if (BUTTON_PRESS() || data_available()) break;
|
if (BUTTON_PRESS() || data_available()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// found all keys?
|
// found all keys?
|
||||||
if (foundkeys == allkeys)
|
if (foundkeys == allkeys) {
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
}
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
// new key
|
// 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
|
// Sector main loop
|
||||||
// keep track of how many sectors on card.
|
// keep track of how many sectors on card.
|
||||||
for (uint8_t s = 0; s < sectorcnt; ++s) {
|
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?
|
// found all keys?
|
||||||
if (foundkeys == allkeys)
|
if (foundkeys == allkeys) {
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
}
|
||||||
|
|
||||||
// assume: block0,1,2 has more read rights in accessbits than the sectortrailer. authenticating against block0 in each sector
|
// assume: block0,1,2 has more read rights in accessbits than the sectortrailer. authenticating against block0 in each sector
|
||||||
chk_data.block = FirstBlockOfSector(s);
|
chk_data.block = FirstBlockOfSector(s);
|
||||||
|
|
||||||
// skip already found A keys
|
// skip already found A keys
|
||||||
if (!found[(s * 2)]) {
|
if (found[(s * 2)] == 0) {
|
||||||
chk_data.keyType = 0;
|
|
||||||
|
chk_data.keyType = MF_KEY_A;
|
||||||
status = chkKey(&chk_data);
|
status = chkKey(&chk_data);
|
||||||
if (status == 0) {
|
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;
|
found[(s * 2)] = 1;
|
||||||
++foundkeys;
|
++foundkeys;
|
||||||
|
|
||||||
|
@ -2165,11 +2217,12 @@ out:
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip already found B keys
|
// skip already found B keys
|
||||||
if (!found[(s * 2) + 1]) {
|
if (found[(s * 2) + 1] == 0) {
|
||||||
chk_data.keyType = 1;
|
|
||||||
|
chk_data.keyType = MF_KEY_B;
|
||||||
status = chkKey(&chk_data);
|
status = chkKey(&chk_data);
|
||||||
if (status == 0) {
|
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;
|
found[(s * 2) + 1] = 1;
|
||||||
++foundkeys;
|
++foundkeys;
|
||||||
|
|
||||||
|
@ -2226,8 +2279,8 @@ OUT:
|
||||||
// get ST
|
// get ST
|
||||||
emlGetMem_xt(block, blockno, 1, MIFARE_BLOCK_SIZE);
|
emlGetMem_xt(block, blockno, 1, MIFARE_BLOCK_SIZE);
|
||||||
|
|
||||||
memcpy(block, k_sector[i].keyA, 6);
|
memcpy(block, k_sector[i].keyA, MF_KEY_LENGTH);
|
||||||
memcpy(block + 10, k_sector[i].keyB, 6);
|
memcpy(block + 10, k_sector[i].keyB, MF_KEY_LENGTH);
|
||||||
|
|
||||||
emlSetMem_xt(block, blockno, 1, sizeof(block));
|
emlSetMem_xt(block, blockno, 1, sizeof(block));
|
||||||
}
|
}
|
||||||
|
@ -2257,7 +2310,7 @@ void MifareChkKeys(uint8_t *datain, uint8_t reserved_mem) {
|
||||||
uint32_t cuid = 0;
|
uint32_t cuid = 0;
|
||||||
uint8_t cascade_levels = 0;
|
uint8_t cascade_levels = 0;
|
||||||
struct {
|
struct {
|
||||||
uint8_t key[6];
|
uint8_t key[MF_KEY_LENGTH];
|
||||||
bool found;
|
bool found;
|
||||||
} PACKED keyresult;
|
} PACKED keyresult;
|
||||||
keyresult.found = false;
|
keyresult.found = false;
|
||||||
|
@ -2272,11 +2325,11 @@ void MifareChkKeys(uint8_t *datain, uint8_t reserved_mem) {
|
||||||
|
|
||||||
uint16_t key_mem_available;
|
uint16_t key_mem_available;
|
||||||
if (reserved_mem)
|
if (reserved_mem)
|
||||||
key_mem_available = key_count * 6;
|
key_mem_available = key_count * MF_KEY_LENGTH;
|
||||||
else
|
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;
|
datain += 5;
|
||||||
|
|
||||||
|
@ -2331,7 +2384,7 @@ void MifareChkKeys(uint8_t *datain, uint8_t reserved_mem) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(keyresult.key, datain + i * 6, 6);
|
memcpy(keyresult.key, datain + (i * MF_KEY_LENGTH), MF_KEY_LENGTH);
|
||||||
keyresult.found = true;
|
keyresult.found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2471,7 +2524,7 @@ int MifareECardLoad(uint8_t sectorcnt, uint8_t keytype, uint8_t *key) {
|
||||||
// increase time-out. Magic card etc are slow
|
// increase time-out. Magic card etc are slow
|
||||||
uint32_t timeout = iso14a_get_timeout();
|
uint32_t timeout = iso14a_get_timeout();
|
||||||
// frame waiting time (FWT) in 1/fc
|
// 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));
|
iso14a_set_timeout(fwt / (8 * 16));
|
||||||
|
|
||||||
for (uint8_t s = 0; s < sectorcnt; s++) {
|
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 MAGIC_DATAIN, the data stays on device side.
|
||||||
if (workFlags & MAGIC_DATAIN) {
|
if (workFlags & MAGIC_DATAIN) {
|
||||||
|
|
||||||
if (isOK) {
|
if (isOK) {
|
||||||
memcpy(datain, data, sizeof(data));
|
memcpy(datain, data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (isOK) {
|
if (isOK) {
|
||||||
reply_old(CMD_ACK, 1, 0, 0, data, sizeof(data));
|
reply_old(CMD_ACK, 1, 0, 0, data, sizeof(data));
|
||||||
} else {
|
} else {
|
||||||
OnErrorMagic(errormsg);
|
OnErrorMagic(errormsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (workFlags & MAGIC_OFF) {
|
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 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 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};
|
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 *par = BigBuf_calloc(MAX_PARITY_SIZE);
|
||||||
uint8_t *buf = BigBuf_calloc(PM3_CMD_DATA_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));
|
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;
|
uint16_t flag = MAGIC_FLAG_NONE;
|
||||||
uint32_t cuid = 0;
|
uint32_t cuid = 0;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
@ -3121,9 +3177,7 @@ void MifareHasStaticNonce(void) {
|
||||||
// variables
|
// variables
|
||||||
int retval = PM3_SUCCESS;
|
int retval = PM3_SUCCESS;
|
||||||
uint32_t nt = 0;
|
uint32_t nt = 0;
|
||||||
uint8_t *uid = BigBuf_malloc(10);
|
uint8_t uid[10] = {0};
|
||||||
|
|
||||||
memset(uid, 0x00, 10);
|
|
||||||
|
|
||||||
uint8_t data[1] = { NONCE_FAIL };
|
uint8_t data[1] = { NONCE_FAIL };
|
||||||
struct Crypto1State mpcs = {0, 0};
|
struct Crypto1State mpcs = {0, 0};
|
||||||
|
@ -3135,7 +3189,7 @@ void MifareHasStaticNonce(void) {
|
||||||
uint8_t counter = 0;
|
uint8_t counter = 0;
|
||||||
for (uint8_t i = 0; i < 3; i++) {
|
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;
|
retval = PM3_ESOFT;
|
||||||
goto OUT;
|
goto OUT;
|
||||||
}
|
}
|
||||||
|
@ -3219,6 +3273,7 @@ void MifareHasStaticEncryptedNonce(uint8_t block_no, uint8_t key_type, uint8_t *
|
||||||
uint32_t ntenc = 0;
|
uint32_t ntenc = 0;
|
||||||
uint8_t ntencpar = 0;
|
uint8_t ntencpar = 0;
|
||||||
bool is_last_auth_first_auth = true;
|
bool is_last_auth_first_auth = true;
|
||||||
|
|
||||||
if (nr_nested == 0) {
|
if (nr_nested == 0) {
|
||||||
cuid = 0;
|
cuid = 0;
|
||||||
if (iso14443a_select_card(NULL, NULL, &cuid, true, 0, true) == false) {
|
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;
|
goto OUT;
|
||||||
};
|
};
|
||||||
first_nt_counter++;
|
first_nt_counter++;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
for (uint8_t i = 0; i < nr_nested; i++) {
|
for (uint8_t i = 0; i < nr_nested; i++) {
|
||||||
|
|
||||||
if (need_first_auth) {
|
if (need_first_auth) {
|
||||||
cuid = 0;
|
cuid = 0;
|
||||||
|
|
||||||
|
@ -3246,43 +3304,55 @@ void MifareHasStaticEncryptedNonce(uint8_t block_no, uint8_t key_type, uint8_t *
|
||||||
SpinDelay(150);
|
SpinDelay(150);
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_dbglevel >= DBG_EXTENDED) {
|
if (g_dbglevel >= DBG_EXTENDED) {
|
||||||
Dbprintf("select");
|
Dbprintf("select");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iso14443a_select_card(NULL, NULL, &cuid, true, 0, true) == false) {
|
if (iso14443a_select_card(NULL, NULL, &cuid, true, 0, true) == false) {
|
||||||
retval = PM3_ESOFT;
|
retval = PM3_ESOFT;
|
||||||
goto OUT;
|
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 (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");
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("Auth error");
|
||||||
retval = PM3_ESOFT;
|
retval = PM3_ESOFT;
|
||||||
goto OUT;
|
goto OUT;
|
||||||
};
|
};
|
||||||
|
|
||||||
is_last_auth_first_auth = true;
|
is_last_auth_first_auth = true;
|
||||||
first_nt_counter++;
|
first_nt_counter++;
|
||||||
if ((first_nt_counter > 1) && (old_nt_first == nt_first)) {
|
if ((first_nt_counter > 1) && (old_nt_first == nt_first)) {
|
||||||
first_nt_repetition_counter++;
|
first_nt_repetition_counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
old_nt_first = nt_first;
|
old_nt_first = nt_first;
|
||||||
if (!reset && !hardreset) {
|
if (!reset && !hardreset) {
|
||||||
need_first_auth = false;
|
need_first_auth = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addread) {
|
if (addread) {
|
||||||
uint8_t dataread[16] = {0x00};
|
uint8_t dataread[16] = {0x00};
|
||||||
mifare_classic_readblock(pcs, block_no, dataread);
|
mifare_classic_readblock(pcs, block_no, dataread);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addauth) {
|
if (addauth) {
|
||||||
|
|
||||||
if (mifare_classic_authex_cmd(pcs, cuid, block_no, key_auth_cmd, ui64key, AUTH_NESTED, &nt, NULL, NULL, NULL, false, false)) {
|
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");
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("Auth error");
|
||||||
retval = PM3_ESOFT;
|
retval = PM3_ESOFT;
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
|
||||||
} else if (g_dbglevel >= DBG_EXTENDED) {
|
} else if (g_dbglevel >= DBG_EXTENDED) {
|
||||||
Dbprintf("Nonce distance: %5i (first nonce <> nested nonce)", nonce_distance(nt_first, nt));
|
Dbprintf("Nonce distance: %5i (first nonce <> nested nonce)", nonce_distance(nt_first, nt));
|
||||||
}
|
}
|
||||||
|
|
||||||
is_last_auth_first_auth = false;
|
is_last_auth_first_auth = false;
|
||||||
if (nt == nt_first) {
|
if (nt == nt_first) {
|
||||||
first_and_nested_nt_repetition_counter++;
|
first_and_nested_nt_repetition_counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
old_nt = nt;
|
old_nt = nt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3290,21 +3360,26 @@ void MifareHasStaticEncryptedNonce(uint8_t block_no, uint8_t key_type, uint8_t *
|
||||||
nt = 0;
|
nt = 0;
|
||||||
ntenc = 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 (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");
|
if (g_dbglevel >= DBG_ERROR) Dbprintf("Nested auth error");
|
||||||
need_first_auth = true;
|
need_first_auth = true;
|
||||||
|
|
||||||
} else if (g_dbglevel >= DBG_EXTENDED) {
|
} else if (g_dbglevel >= DBG_EXTENDED) {
|
||||||
|
|
||||||
if (is_last_auth_first_auth) {
|
if (is_last_auth_first_auth) {
|
||||||
Dbprintf("Nonce distance: %5i (first nonce <> nested nonce)", nonce_distance(nt_first, nt));
|
Dbprintf("Nonce distance: %5i (first nonce <> nested nonce)", nonce_distance(nt_first, nt));
|
||||||
} else {
|
} else {
|
||||||
Dbprintf("Nonce distance: %5i", nonce_distance(old_nt, nt));
|
Dbprintf("Nonce distance: %5i", nonce_distance(old_nt, nt));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nested_nt_session_counter++;
|
nested_nt_session_counter++;
|
||||||
is_last_auth_first_auth = false;
|
is_last_auth_first_auth = false;
|
||||||
old_nt = nt;
|
old_nt = nt;
|
||||||
if (nt == nt_first) {
|
if (nt == nt_first) {
|
||||||
first_and_nested_nt_repetition_counter++;
|
first_and_nested_nt_repetition_counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((nested_nt_session_counter > 1) && (oldntenc == ntenc)) {
|
if ((nested_nt_session_counter > 1) && (oldntenc == ntenc)) {
|
||||||
nested_nt_repetition_counter++;
|
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[2] = (cuid >> 16) & 0xFF;
|
||||||
data[3] = (cuid >> 8) & 0xFF;
|
data[3] = (cuid >> 8) & 0xFF;
|
||||||
data[4] = (cuid >> 0) & 0xFF;
|
data[4] = (cuid >> 0) & 0xFF;
|
||||||
|
|
||||||
if (first_and_nested_nt_repetition_counter) {
|
if (first_and_nested_nt_repetition_counter) {
|
||||||
data[0] = NONCE_SUPERSTATIC;
|
data[0] = NONCE_SUPERSTATIC;
|
||||||
data[5] = (nt >> 24) & 0xFF;
|
data[5] = (nt >> 24) & 0xFF;
|
||||||
data[6] = (nt >> 16) & 0xFF;
|
data[6] = (nt >> 16) & 0xFF;
|
||||||
data[7] = (nt >> 8) & 0xFF;
|
data[7] = (nt >> 8) & 0xFF;
|
||||||
data[8] = (nt >> 0) & 0xFF;
|
data[8] = (nt >> 0) & 0xFF;
|
||||||
|
|
||||||
} else if (first_nt_repetition_counter) {
|
} else if (first_nt_repetition_counter) {
|
||||||
data[0] = NONCE_STATIC;
|
data[0] = NONCE_STATIC;
|
||||||
data[5] = (nt_first >> 24) & 0xFF;
|
data[5] = (nt_first >> 24) & 0xFF;
|
||||||
data[6] = (nt_first >> 16) & 0xFF;
|
data[6] = (nt_first >> 16) & 0xFF;
|
||||||
data[7] = (nt_first >> 8) & 0xFF;
|
data[7] = (nt_first >> 8) & 0xFF;
|
||||||
data[8] = (nt_first >> 0) & 0xFF;
|
data[8] = (nt_first >> 0) & 0xFF;
|
||||||
|
|
||||||
} else if (nested_nt_repetition_counter) {
|
} else if (nested_nt_repetition_counter) {
|
||||||
data[0] = NONCE_STATIC_ENC;
|
data[0] = NONCE_STATIC_ENC;
|
||||||
data[5] = (nt >> 24) & 0xFF;
|
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[11] = (ntenc >> 8) & 0xFF;
|
||||||
data[12] = (ntenc >> 0) & 0xFF;
|
data[12] = (ntenc >> 0) & 0xFF;
|
||||||
data[13] = ntencpar;
|
data[13] = ntencpar;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
data[0] = NONCE_NORMAL;
|
data[0] = NONCE_NORMAL;
|
||||||
data[5] = (nt >> 24) & 0xFF;
|
data[5] = (nt >> 24) & 0xFF;
|
||||||
|
|
|
@ -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
|
// 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);
|
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)
|
// Save the tag nonce (nt)
|
||||||
uint32_t nt = bytes_to_num(receivedAnswer, 4);
|
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;
|
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]);
|
Dbprintf("Auth Resp: %02x%02x%02x%02x", resp[0], resp[1], resp[2], resp[3]);
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(pack, resp, 4);
|
memcpy(pack, resp, 4);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -490,6 +493,7 @@ int mifare_ultra_aes_auth(uint8_t keyno, uint8_t *keybytes) {
|
||||||
memset(IV, 0, 16);
|
memset(IV, 0, 16);
|
||||||
mbedtls_aes_setkey_dec(&actx, key, 128);
|
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_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 (memcmp(random_b, random_a, 16) != 0) {
|
||||||
if (g_dbglevel >= DBG_INFO) Dbprintf("failed authentication");
|
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:");
|
Dbprintf("B:");
|
||||||
Dbhexdump(16, random_b, false);
|
Dbhexdump(16, random_b, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
mbedtls_aes_free(&actx);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -577,19 +577,25 @@ 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
|
// preexistence, avoiding a link being created if filename exists, or avoiding a file being created if
|
||||||
// symlink exists with same name
|
// symlink exists with same name
|
||||||
int rdv40_spiffs_read_as_filetype(const char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level) {
|
int rdv40_spiffs_read_as_filetype(const char *filename, uint8_t *dst, uint32_t size, RDV40SpiFFSSafetyLevel level) {
|
||||||
|
|
||||||
RDV40_SPIFFS_SAFE_FUNCTION(
|
RDV40_SPIFFS_SAFE_FUNCTION(
|
||||||
|
|
||||||
RDV40SpiFFSFileType filetype = filetype_in_spiffs((char *)filename);
|
RDV40SpiFFSFileType filetype = filetype_in_spiffs((char *)filename);
|
||||||
|
|
||||||
switch (filetype) {
|
switch (filetype) {
|
||||||
case RDV40_SPIFFS_FILETYPE_REAL:
|
case RDV40_SPIFFS_FILETYPE_REAL: {
|
||||||
rdv40_spiffs_read(filename, dst, size, level);
|
rdv40_spiffs_read(filename, dst, size, level);
|
||||||
break;
|
break;
|
||||||
case RDV40_SPIFFS_FILETYPE_SYMLINK:
|
}
|
||||||
|
case RDV40_SPIFFS_FILETYPE_SYMLINK: {
|
||||||
rdv40_spiffs_read_as_symlink(filename, dst, size, level);
|
rdv40_spiffs_read_as_symlink(filename, dst, size, level);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case RDV40_SPIFFS_FILETYPE_BOTH:
|
case RDV40_SPIFFS_FILETYPE_BOTH:
|
||||||
case RDV40_SPIFFS_FILETYPE_UNKNOWN:
|
case RDV40_SPIFFS_FILETYPE_UNKNOWN:
|
||||||
default:
|
default: {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,47 +240,47 @@ int CmdHFSearch(const char *Cmd) {
|
||||||
// no need to print 14A hints, since it will print itself
|
// no need to print 14A hints, since it will print itself
|
||||||
|
|
||||||
if (success[THINFILM]) {
|
if (success[THINFILM]) {
|
||||||
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf thinfilm") "` commands\n");
|
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf thinfilm") "` commands\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success[LTO]) {
|
if (success[LTO]) {
|
||||||
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf lto") "` commands\n");
|
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf lto") "` commands\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success[LEGIC]) {
|
if (success[LEGIC]) {
|
||||||
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf legic") "` commands\n");
|
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf legic") "` commands\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success[TOPAZ]) {
|
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]) {
|
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]) {
|
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]) {
|
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]) {
|
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]) {
|
if (success[ICLASS]) {
|
||||||
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf iclass") "` commands\n");
|
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf iclass") "` commands\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success[FELICA]) {
|
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]) {
|
if (success[PROTO_CRYPTORF]) {
|
||||||
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf cryptorf") "` commands\n");
|
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf cryptorf") "` commands\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -520,7 +520,7 @@ int Hf14443_4aGetCardData(iso14a_card_select_t *card) {
|
||||||
PrintAndLogEx(INFO, "Card doesn't support standard iso14443-3 anticollision");
|
PrintAndLogEx(INFO, "Card doesn't support standard iso14443-3 anticollision");
|
||||||
// identify TOPAZ
|
// identify TOPAZ
|
||||||
if (card->atqa[1] == 0x0C && card->atqa[0] == 0x00) {
|
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 {
|
} else {
|
||||||
PrintAndLogEx(SUCCESS, "\tATQA : %02X %02X", card->atqa[1], card->atqa[0]);
|
PrintAndLogEx(SUCCESS, "\tATQA : %02X %02X", card->atqa[1], card->atqa[0]);
|
||||||
}
|
}
|
||||||
|
@ -685,7 +685,7 @@ static int CmdHF14AReader(const char *Cmd) {
|
||||||
|
|
||||||
// identify TOPAZ
|
// identify TOPAZ
|
||||||
if (card.atqa[1] == 0x0C && card.atqa[0] == 0x00) {
|
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 {
|
} else {
|
||||||
PrintAndLogEx(SUCCESS, "ATQA: %02X %02X", card.atqa[1], card.atqa[0]);
|
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
|
// identify TOPAZ
|
||||||
if (card.atqa[1] == 0x0C && card.atqa[0] == 0x00) {
|
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();
|
DropField();
|
||||||
|
@ -2746,42 +2746,42 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
|
||||||
if (isMifareUltralight) {
|
if (isMifareUltralight) {
|
||||||
|
|
||||||
if (((isMagic & MAGIC_FLAG_GEN_1A) == MAGIC_FLAG_GEN_1A) || ((isMagic & MAGIC_FLAG_GEN_1B) == MAGIC_FLAG_GEN_1B)) {
|
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) {
|
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)) {
|
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) {
|
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 (isST) {
|
||||||
if (card.ats_len > 0) {
|
if (card.ats_len > 0) {
|
||||||
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf st25ta info") "`");
|
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf st25ta info") "`");
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf mfu info") "`");
|
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf mfu info") "`");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isEMV) {
|
if (isEMV) {
|
||||||
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("emv reader") "`");
|
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("emv reader") "`");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isSEOS) {
|
if (isSEOS) {
|
||||||
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf seos info") "`");
|
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf seos info") "`");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isFUDAN) {
|
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 -a -b 7 -k 26");
|
||||||
PrintAndLogEx(HINT, " hf 14a raw -k -c 3000");
|
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) {
|
if (isNTAG424) {
|
||||||
PrintAndLogEx(HINT, "Hint: try `" _YELLOW_("hf ntag424 info") "`");
|
PrintAndLogEx(HINT, "Hint: Try `" _YELLOW_("hf ntag424 info") "`");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isMifareClassic || isMifareMini) {
|
if (isMifareClassic || isMifareMini) {
|
||||||
|
|
|
@ -151,8 +151,6 @@ static void lookup_chipid_short(uint32_t iChipID, uint32_t mem_used) {
|
||||||
, mem_avail
|
, mem_avail
|
||||||
, mem_avail == 0 ? 0.0f : (float)mem_used / (mem_avail * 1024) * 100
|
, mem_avail == 0 ? 0.0f : (float)mem_used / (mem_avail * 1024) * 100
|
||||||
);
|
);
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lookupChipID(uint32_t iChipID, uint32_t mem_used) {
|
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);
|
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
|
// client
|
||||||
char temp[PM3_CMD_DATA_SIZE - 12]; // same limit as for ARM image
|
char temp[PM3_CMD_DATA_SIZE - 12]; // same limit as for ARM image
|
||||||
format_version_information_short(temp, sizeof(temp), &g_version_information);
|
format_version_information_short(temp, sizeof(temp), &g_version_information);
|
||||||
|
@ -1588,42 +1603,24 @@ void pm3_version_short(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// bootrom
|
// bootrom
|
||||||
ptr = strstr(payload->versionstr, " bootrom: ");
|
ptr = strstr(payload->versionstr, "Bootrom.... ");
|
||||||
if (ptr != NULL) {
|
if (ptr != NULL) {
|
||||||
char *ptr_end = strstr(ptr, "\n");
|
char *ptr_end = strstr(ptr, "\n");
|
||||||
if (ptr_end != NULL) {
|
if (ptr_end != NULL) {
|
||||||
uint8_t len = ptr_end - 19 - ptr;
|
uint8_t len = ptr_end - 19 - ptr;
|
||||||
PrintAndLogEx(NORMAL, " Bootrom... %.*s", len, ptr + 10);
|
PrintAndLogEx(NORMAL, " Bootrom... %.*s", len, ptr + 12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// os:
|
// os:
|
||||||
ptr = strstr(payload->versionstr, " os: ");
|
ptr = strstr(payload->versionstr, "OS......... ");
|
||||||
if (ptr != NULL) {
|
if (ptr != NULL) {
|
||||||
char *ptr_end = strstr(ptr, "\n");
|
char *ptr_end = strstr(ptr, "\n");
|
||||||
if (ptr_end != NULL) {
|
if (ptr_end != NULL) {
|
||||||
uint8_t len = ptr_end - 14 - ptr;
|
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, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
|
||||||
if (armsrc_mismatch) {
|
if (armsrc_mismatch) {
|
||||||
|
@ -1643,7 +1640,7 @@ void pm3_version(bool verbose, bool oneliner) {
|
||||||
if (oneliner) {
|
if (oneliner) {
|
||||||
// For "proxmark3 -v", simple printf, avoid logging
|
// For "proxmark3 -v", simple printf, avoid logging
|
||||||
FormatVersionInformation(temp, sizeof(temp), "Client: ", &g_version_information);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1655,8 +1652,8 @@ void pm3_version(bool verbose, bool oneliner) {
|
||||||
PrintAndLogEx(NORMAL, "\n [ " _YELLOW_("Client") " ]");
|
PrintAndLogEx(NORMAL, "\n [ " _YELLOW_("Client") " ]");
|
||||||
FormatVersionInformation(temp, sizeof(temp), " ", &g_version_information);
|
FormatVersionInformation(temp, sizeof(temp), " ", &g_version_information);
|
||||||
PrintAndLogEx(NORMAL, "%s", temp);
|
PrintAndLogEx(NORMAL, "%s", temp);
|
||||||
PrintAndLogEx(NORMAL, " compiled with............. " PM3CLIENTCOMPILER __VERSION__);
|
PrintAndLogEx(NORMAL, " Compiler.................. " PM3CLIENTCOMPILER __VERSION__);
|
||||||
PrintAndLogEx(NORMAL, " platform.................. " PM3HOSTOS " / " PM3HOSTARCH);
|
PrintAndLogEx(NORMAL, " Platform.................. " PM3HOSTOS " / " PM3HOSTARCH);
|
||||||
#if defined(HAVE_READLINE)
|
#if defined(HAVE_READLINE)
|
||||||
PrintAndLogEx(NORMAL, " Readline support.......... " _GREEN_("present"));
|
PrintAndLogEx(NORMAL, " Readline support.......... " _GREEN_("present"));
|
||||||
#elif defined(HAVE_LINENOISE)
|
#elif defined(HAVE_LINENOISE)
|
||||||
|
@ -1670,9 +1667,9 @@ void pm3_version(bool verbose, bool oneliner) {
|
||||||
PrintAndLogEx(NORMAL, " QT GUI support............ " _YELLOW_("absent"));
|
PrintAndLogEx(NORMAL, " QT GUI support............ " _YELLOW_("absent"));
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_BLUEZ
|
#ifdef HAVE_BLUEZ
|
||||||
PrintAndLogEx(NORMAL, " native BT support......... " _GREEN_("present"));
|
PrintAndLogEx(NORMAL, " Native BT support......... " _GREEN_("present"));
|
||||||
#else
|
#else
|
||||||
PrintAndLogEx(NORMAL, " native BT support......... " _YELLOW_("absent"));
|
PrintAndLogEx(NORMAL, " Native BT support......... " _YELLOW_("absent"));
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_PYTHON
|
#ifdef HAVE_PYTHON
|
||||||
PrintAndLogEx(NORMAL, " Python script support..... " _GREEN_("present") " ( " _YELLOW_(PY_VERSION) " )");
|
PrintAndLogEx(NORMAL, " Python script support..... " _GREEN_("present") " ( " _YELLOW_(PY_VERSION) " )");
|
||||||
|
@ -1692,7 +1689,7 @@ void pm3_version(bool verbose, bool oneliner) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (g_session.pm3_present) {
|
if (g_session.pm3_present) {
|
||||||
PrintAndLogEx(NORMAL, "\n [ " _YELLOW_("Proxmark3") " ]");
|
PrintAndLogEx(NORMAL, "\n [ " _YELLOW_("Model") " ]");
|
||||||
|
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
clearCommandBuffer();
|
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, " Device.................... %s", (is_genuine_rdv4) ? _GREEN_("RDV4") : _RED_("device / fw mismatch"));
|
||||||
PrintAndLogEx(NORMAL, " firmware.................. %s", (is_genuine_rdv4) ? _GREEN_("RDV4") : _YELLOW_("RDV4"));
|
PrintAndLogEx(NORMAL, " Firmware.................. %s", (is_genuine_rdv4) ? _GREEN_("RDV4") : _YELLOW_("RDV4"));
|
||||||
PrintAndLogEx(NORMAL, " external flash............ %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent"));
|
PrintAndLogEx(NORMAL, " External flash............ %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent"));
|
||||||
PrintAndLogEx(NORMAL, " smartcard reader.......... %s", IfPm3Smartcard() ? _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"));
|
PrintAndLogEx(NORMAL, " FPC USART for BT add-on... %s", IfPm3FpcUsartHost() ? _GREEN_("present") : _YELLOW_("absent"));
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(NORMAL, " firmware.................. %s", _YELLOW_("PM3 GENERIC"));
|
PrintAndLogEx(NORMAL, " Firmware.................. %s", _YELLOW_("PM3 GENERIC"));
|
||||||
if (IfPm3Flash()) {
|
if (IfPm3Flash()) {
|
||||||
PrintAndLogEx(NORMAL, " external flash............ %s", _GREEN_("present"));
|
PrintAndLogEx(NORMAL, " External flash............ %s", _GREEN_("present"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IfPm3FpcUsartHost()) {
|
if (IfPm3FpcUsartHost()) {
|
||||||
|
@ -1742,7 +1739,7 @@ void pm3_version(bool verbose, bool oneliner) {
|
||||||
struct p *payload = (struct p *)&resp.data.asBytes;
|
struct p *payload = (struct p *)&resp.data.asBytes;
|
||||||
|
|
||||||
bool armsrc_mismatch = false;
|
bool armsrc_mismatch = false;
|
||||||
char *ptr = strstr(payload->versionstr, " os: ");
|
char *ptr = strstr(payload->versionstr, "OS......... ");
|
||||||
if (ptr != NULL) {
|
if (ptr != NULL) {
|
||||||
ptr = strstr(ptr, "\n");
|
ptr = strstr(ptr, "\n");
|
||||||
if ((ptr != NULL) && (strlen(g_version_information.armsrc) == 9)) {
|
if ((ptr != NULL) && (strlen(g_version_information.armsrc) == 9)) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue