mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-13 18:17:25 -07:00
commit
6e6b46c87a
45 changed files with 40765 additions and 260 deletions
armsrc
Standalone
appmain.cfelica.cfelica.hfrozen.hlfops.cmifarecmd.cmifaresim.cmifareutil.cspiffs.cthinfilm.cclient
cmddata.ccmddata.hcmdhf.ccmdhffelica.ccmdhffelica.hcmdhficlass.ccmdhfmfhard.ccmdhfmfu.ccmdlft55xx.ccmdlft55xx.hcmdmain.ccmdmain.hcmdsmartcard.ccmdwiegand.c
emv
fido
hardnested
luascripts
mifare
scripting.cwiegand_formats.cwiegand_formats.hcommon/crapto1
doc
include
traces
|
@ -217,12 +217,12 @@ void RAMFUNC SniffAndStore(uint8_t param) {
|
|||
if (DBGLEVEL > 1)
|
||||
Dbprintf("[!] Authentication attempts = %u", auth_attempts);
|
||||
size_t size = 4 * auth_attempts;
|
||||
uint8_t *data = BigBuf_malloc(size);
|
||||
uint8_t *buf = BigBuf_malloc(size);
|
||||
|
||||
if (!exists_in_spiffs((char *)HF_BOG_LOGFILE)) {
|
||||
rdv40_spiffs_write((char *)HF_BOG_LOGFILE, (uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
rdv40_spiffs_write((char *)HF_BOG_LOGFILE, buf, size, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
} else {
|
||||
rdv40_spiffs_append((char *)HF_BOG_LOGFILE, (uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
rdv40_spiffs_append((char *)HF_BOG_LOGFILE, buf, size, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -857,7 +857,7 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
|
|||
DbprintfEx(FLAG_NEWLINE, "Halt error");
|
||||
};
|
||||
|
||||
crypto1_destroy(pcs);
|
||||
crypto1_deinit(pcs);
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
|
||||
|
@ -894,12 +894,12 @@ int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
|
|||
SpinDelayUs(AUTHENTICATION_TIMEOUT);
|
||||
continue;
|
||||
}
|
||||
crypto1_destroy(pcs);
|
||||
crypto1_deinit(pcs);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
*key = ui64Key;
|
||||
return i;
|
||||
}
|
||||
crypto1_destroy(pcs);
|
||||
crypto1_deinit(pcs);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
|
||||
return -1;
|
||||
|
|
|
@ -195,12 +195,12 @@ static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
|
|||
SpinDelayUs(AUTHENTICATION_TIMEOUT);
|
||||
continue;
|
||||
}
|
||||
crypto1_destroy(pcs);
|
||||
crypto1_deinit(pcs);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
*key = ui64Key;
|
||||
return i;
|
||||
}
|
||||
crypto1_destroy(pcs);
|
||||
crypto1_deinit(pcs);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
|
||||
return -1;
|
||||
|
|
|
@ -65,7 +65,7 @@ void RunMod() {
|
|||
continue;
|
||||
|
||||
// Button was held for a second, begin recording
|
||||
if (button_pressed > 0 && cardRead == 0) {
|
||||
if (cardRead == 0) {
|
||||
LEDsoff();
|
||||
LED(selected + 1, 0);
|
||||
LED(LED_D, 0);
|
||||
|
|
|
@ -96,7 +96,7 @@ void RunMod() {
|
|||
if (data_available()) break;
|
||||
|
||||
// Was our button held down or pressed?
|
||||
int button_pressed = BUTTON_HELD(280);
|
||||
button_pressed = BUTTON_HELD(280);
|
||||
if (button_pressed != BUTTON_HOLD) break;
|
||||
|
||||
Dbprintf("[=] trying Facility = %08x ID %08x", high, i);
|
||||
|
|
|
@ -365,14 +365,14 @@ void SendStatus(void) {
|
|||
Dbprintf(" Slow clock..............%d Hz", (16 * MAINCK) / mainf);
|
||||
uint32_t delta_time = 0;
|
||||
uint32_t start_time = GetTickCount();
|
||||
#define SLCK_CHECK_MS 50
|
||||
#define SLCK_CHECK_MS 50
|
||||
SpinDelay(SLCK_CHECK_MS);
|
||||
delta_time = GetTickCountDelta(start_time);
|
||||
if ((delta_time < SLCK_CHECK_MS - 1) || (delta_time > SLCK_CHECK_MS + 1)) {
|
||||
// error > 2% with SLCK_CHECK_MS=50
|
||||
Dbprintf(_RED_(" Slow Clock speed change detected, TIA needed"));
|
||||
Dbprintf(_YELLOW_(" Slow Clock actual speed seems closer to %d kHz"),
|
||||
(16 * MAINCK / 1000) / mainf * delta_time / SLCK_CHECK_MS);
|
||||
(16 * MAINCK / 1000) / mainf * delta_time / SLCK_CHECK_MS);
|
||||
}
|
||||
DbpString(_BLUE_("Installed StandAlone Mode"));
|
||||
ModInfo();
|
||||
|
@ -1591,7 +1591,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
uint16_t offset = MIN(BIGBUF_SIZE - PM3_CMD_DATA_SIZE - 3, payload->offset);
|
||||
|
||||
uint8_t *mem = BigBuf_get_addr();
|
||||
memcpy(mem + offset, &payload->data, PM3_CMD_DATA_SIZE - 3);
|
||||
memcpy(mem + offset, &payload->data, PM3_CMD_DATA_SIZE - 3 - offset);
|
||||
reply_ng(CMD_LF_UPLOAD_SIM_SAMPLES, PM3_SUCCESS, NULL, 0);
|
||||
break;
|
||||
}
|
||||
|
@ -1711,8 +1711,10 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
strncpy((char *)src, token, sizeof(src) - 1);
|
||||
token = strtok(NULL, ",");
|
||||
strncpy((char *)dest, token, sizeof(dest) - 1);
|
||||
if (DBGLEVEL > 1) Dbprintf("> Filename received as source for spiffs RENAME : %s", src);
|
||||
if (DBGLEVEL > 1) Dbprintf("> Filename received as destination for spiffs RENAME : %s", dest);
|
||||
if (DBGLEVEL > 1) {
|
||||
Dbprintf("> Filename received as source for spiffs RENAME : %s", src);
|
||||
Dbprintf("> Filename received as destination for spiffs RENAME : %s", dest);
|
||||
}
|
||||
rdv40_spiffs_rename((char *) src, (char *)dest, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
LED_B_OFF();
|
||||
break;
|
||||
|
@ -1727,8 +1729,10 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
strncpy((char *)src, token, sizeof(src) - 1);
|
||||
token = strtok(NULL, ",");
|
||||
strncpy((char *)dest, token, sizeof(dest) - 1);
|
||||
if (DBGLEVEL > 1) Dbprintf("> Filename received as source for spiffs COPY : %s", src);
|
||||
if (DBGLEVEL > 1) Dbprintf("> Filename received as destination for spiffs COPY : %s", dest);
|
||||
if (DBGLEVEL > 1) {
|
||||
Dbprintf("> Filename received as source for spiffs COPY : %s", src);
|
||||
Dbprintf("> Filename received as destination for spiffs COPY : %s", dest);
|
||||
}
|
||||
rdv40_spiffs_copy((char *) src, (char *)dest, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
LED_B_OFF();
|
||||
break;
|
||||
|
@ -1899,9 +1903,13 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
break;
|
||||
}
|
||||
case CMD_TIA: {
|
||||
|
||||
while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available...
|
||||
uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF;
|
||||
Dbprintf(" Slow clock old measured value:.........%d Hz", (16 * MAINCK) / mainf);
|
||||
TimingIntervalAcquisition();
|
||||
|
||||
while ((AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINRDY) == 0); // Wait for MAINF value to become available...
|
||||
mainf = AT91C_BASE_PMC->PMC_MCFR & AT91C_CKGR_MAINF;
|
||||
Dbprintf(""); // first message gets lost
|
||||
Dbprintf(" Slow clock new measured value:.........%d Hz", (16 * MAINCK) / mainf);
|
||||
|
|
232
armsrc/felica.c
232
armsrc/felica.c
|
@ -111,7 +111,7 @@ static void shiftInByte(uint8_t bt) {
|
|||
static void Process18092Byte(uint8_t bt) {
|
||||
switch (FelicaFrame.state) {
|
||||
case STATE_UNSYNCD: {
|
||||
//almost any nonzero byte can be start of SYNC. SYNC should be preceded by zeros, but that is not alsways the case
|
||||
//almost any nonzero byte can be start of SYNC. SYNC should be preceded by zeros, but that is not always the case
|
||||
if (bt > 0) {
|
||||
FelicaFrame.shiftReg = reflect8(bt);
|
||||
FelicaFrame.state = STATE_TRYING_SYNC;
|
||||
|
@ -175,13 +175,11 @@ static void Process18092Byte(uint8_t bt) {
|
|||
}
|
||||
case STATE_GET_CRC: {
|
||||
shiftInByte(bt);
|
||||
|
||||
if (FelicaFrame.rem_len <= 0) {
|
||||
FelicaFrame.rem_len = 0;
|
||||
// skip sync 2bytes. IF ok, residue should be 0x0000
|
||||
FelicaFrame.crc_ok = check_crc(CRC_FELICA, FelicaFrame.framebytes + 2, FelicaFrame.len - 2);
|
||||
FelicaFrame.state = STATE_FULL;
|
||||
FelicaFrame.rem_len = 0;
|
||||
if (DBGLEVEL > 3) Dbprintf("[+] got 2 crc bytes [%s]", (FelicaFrame.crc_ok) ? "OK" : "No");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -194,6 +192,7 @@ static void Process18092Byte(uint8_t bt) {
|
|||
/* Perform FeliCa polling card
|
||||
* Currently does NOT do any collision handling.
|
||||
* It expects 0-1 cards in the device's range.
|
||||
* return 0 if selection was successful
|
||||
*/
|
||||
static uint8_t felica_select_card(felica_card_select_t *card) {
|
||||
|
||||
|
@ -201,9 +200,9 @@ static uint8_t felica_select_card(felica_card_select_t *card) {
|
|||
// 0xB2 0x4B = sync code
|
||||
// 0x06 = len
|
||||
// 0x00 = rfu
|
||||
// 0xff = system service
|
||||
// 0xff = system service
|
||||
// 0x00 =
|
||||
// 0xff = system code service
|
||||
// 0xff = system code service
|
||||
// 0x00 = request code
|
||||
// b7 = automatic switching of data rate
|
||||
// b6-b2 = reserved
|
||||
// b1 = fc/32 (414kbps)
|
||||
|
@ -211,7 +210,6 @@ static uint8_t felica_select_card(felica_card_select_t *card) {
|
|||
// 0x00 = timeslot
|
||||
// 0x09 0x21 = crc
|
||||
static uint8_t poll[10] = {0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xFF, 0xFF, 0x00, 0x00, 0x09, 0x21};
|
||||
|
||||
int len = 20;
|
||||
|
||||
// We try 20 times, or if answer was received.
|
||||
|
@ -222,7 +220,7 @@ static uint8_t felica_select_card(felica_card_select_t *card) {
|
|||
TransmitFor18092_AsReader(poll, sizeof(poll), NULL, 1, 0);
|
||||
|
||||
// polling card, break if success
|
||||
if (WaitForFelicaReply(512) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK)
|
||||
if (WaitForFelicaReply(1024) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK)
|
||||
break;
|
||||
|
||||
WDT_HIT();
|
||||
|
@ -230,17 +228,31 @@ static uint8_t felica_select_card(felica_card_select_t *card) {
|
|||
} while (--len);
|
||||
|
||||
// timed-out
|
||||
if (len == 0)
|
||||
if (len == 0) {
|
||||
if (DBGLEVEL > 3)
|
||||
Dbprintf("Error: Time out card selection!");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// wrong answer
|
||||
if (FelicaFrame.framebytes[3] != FELICA_POLL_ACK)
|
||||
if (FelicaFrame.framebytes[3] != FELICA_POLL_ACK) {
|
||||
if (DBGLEVEL > 3)
|
||||
Dbprintf("Error: Wrong answer selecting card!");
|
||||
return 2;
|
||||
}
|
||||
|
||||
// VALIDATE CRC residue is 0, hence if crc is a value it failed.
|
||||
if (!check_crc(CRC_FELICA, FelicaFrame.framebytes + 2, FelicaFrame.len - 2))
|
||||
if (!check_crc(CRC_FELICA, FelicaFrame.framebytes + 2, FelicaFrame.len - 2)) {
|
||||
if (DBGLEVEL > 3) {
|
||||
Dbprintf("Error: CRC check failed!");
|
||||
Dbprintf("CRC check was done on Frame: ");
|
||||
Dbhexdump(FelicaFrame.len - 2, FelicaFrame.framebytes + 2, 0);
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (DBGLEVEL > 3)
|
||||
Dbprintf("Card selection successful!");
|
||||
// copy UID
|
||||
// idm 8
|
||||
if (card) {
|
||||
|
@ -251,7 +263,10 @@ static uint8_t felica_select_card(felica_card_select_t *card) {
|
|||
memcpy(card->uid, card->IDm + 2, 6);
|
||||
memcpy(card->iccode, card->PMm, 2);
|
||||
memcpy(card->mrt, card->PMm + 2, 6);
|
||||
|
||||
if (DBGLEVEL > 3) {
|
||||
Dbprintf("Received Frame: ");
|
||||
Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes, 0);
|
||||
}
|
||||
}
|
||||
// more status bytes?
|
||||
return 0;
|
||||
|
@ -349,10 +364,13 @@ static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing,
|
|||
c++;
|
||||
}
|
||||
}
|
||||
// sending sync code
|
||||
|
||||
// sending data
|
||||
// sending data with sync bytes
|
||||
c = 0;
|
||||
if (DBGLEVEL > 3) {
|
||||
Dbprintf("Sending frame:");
|
||||
Dbhexdump(len, frame, 0);
|
||||
}
|
||||
|
||||
while (c < len) {
|
||||
|
||||
// Put byte into tx holding register as soon as it is ready
|
||||
|
@ -386,22 +404,22 @@ static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing,
|
|||
// stop when button is pressed
|
||||
// or return TRUE when command is captured
|
||||
bool WaitForFelicaReply(uint16_t maxbytes) {
|
||||
|
||||
if (DBGLEVEL > 3)
|
||||
Dbprintf("WaitForFelicaReply Start");
|
||||
uint32_t c = 0;
|
||||
|
||||
// power, no modulation
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_ISO18092 | FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD);
|
||||
|
||||
FelicaFrameReset();
|
||||
|
||||
// clear RXRDY:
|
||||
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
|
||||
(void)b;
|
||||
|
||||
uint32_t timeout = iso18092_get_timeout();
|
||||
if (DBGLEVEL > 3)
|
||||
Dbprintf("timeout set: %i", timeout);
|
||||
//TODO FIX THIS METHOD - Race Condition or something: TIMING/MEMORY ISSUES
|
||||
// If you add content here (dbprintf), timing problems appear?! Last Bytes (CRC) of frame will be cutoff.
|
||||
for (;;) {
|
||||
WDT_HIT();
|
||||
|
||||
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
|
||||
b = (uint8_t)(AT91C_BASE_SSC->SSC_RHR);
|
||||
Process18092Byte(b);
|
||||
|
@ -410,8 +428,7 @@ bool WaitForFelicaReply(uint16_t maxbytes) {
|
|||
MAX(
|
||||
felica_nexttransfertime,
|
||||
(GetCountSspClk() & 0xfffffff8) - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / 16 + FELICA_FRAME_DELAY_TIME
|
||||
)
|
||||
;
|
||||
);
|
||||
|
||||
LogTrace(
|
||||
FelicaFrame.framebytes,
|
||||
|
@ -421,22 +438,20 @@ bool WaitForFelicaReply(uint16_t maxbytes) {
|
|||
NULL,
|
||||
false
|
||||
);
|
||||
if (DBGLEVEL > 3) Dbprintf("All bytes received! STATE_FULL");
|
||||
return true;
|
||||
} else if (c++ > timeout && FelicaFrame.state == STATE_UNSYNCD) {
|
||||
if (DBGLEVEL > 3) Dbprintf("Error: Timeout! STATE_UNSYNCD");
|
||||
return false;
|
||||
} else if (FelicaFrame.state == STATE_GET_CRC) {
|
||||
Dbprintf(" Frame: ");
|
||||
Dbhexdump(16, FelicaFrame.framebytes, 0);
|
||||
//return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set up FeliCa communication (similar to iso14443a_setup)
|
||||
// field is setup for "Sending as Reader"
|
||||
static void iso18092_setup(uint8_t fpga_minor_mode) {
|
||||
if (DBGLEVEL > 3) Dbprintf("Start iso18092_setup");
|
||||
|
||||
LEDsoff();
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
|
@ -474,6 +489,14 @@ static void iso18092_setup(uint8_t fpga_minor_mode) {
|
|||
|
||||
LED_D_ON();
|
||||
}
|
||||
|
||||
void felica_reset_frame_mode() {
|
||||
switch_off();
|
||||
//Resetting Frame mode (First set in fpgaloader.c)
|
||||
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// RAW FeliCa commands. Send out commands and store answers.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -481,7 +504,6 @@ static void iso18092_setup(uint8_t fpga_minor_mode) {
|
|||
// arg1 len of commandbytes
|
||||
// d.asBytes command bytes to send
|
||||
void felica_sendraw(PacketCommandNG *c) {
|
||||
|
||||
if (DBGLEVEL > 3) Dbprintf("FeliCa_sendraw Enter");
|
||||
|
||||
felica_command_t param = c->oldarg[0];
|
||||
|
@ -492,21 +514,26 @@ void felica_sendraw(PacketCommandNG *c) {
|
|||
felica_card_select_t card;
|
||||
|
||||
if ((param & FELICA_CONNECT))
|
||||
clear_trace();
|
||||
if (DBGLEVEL > 3) Dbprintf("Clear trace");
|
||||
clear_trace();
|
||||
|
||||
set_tracing(true);
|
||||
iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD);
|
||||
|
||||
if ((param & FELICA_CONNECT)) {
|
||||
iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD);
|
||||
|
||||
// notify client selecting status.
|
||||
// if failed selecting, turn off antenna and quite.
|
||||
if (!(param & FELICA_NO_SELECT)) {
|
||||
arg0 = felica_select_card(&card);
|
||||
reply_old(CMD_ACK, arg0, sizeof(card.uid), 0, &card, sizeof(felica_card_select_t));
|
||||
if (arg0 > 0)
|
||||
goto OUT;
|
||||
reply_mix(CMD_ACK, arg0, sizeof(card.uid), 0, &card, sizeof(felica_card_select_t));
|
||||
if (arg0 > 0) {
|
||||
if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Error: Failed selecting card! ");
|
||||
felica_reset_frame_mode();
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (DBGLEVEL > 3) Dbprintf("No card selection");
|
||||
}
|
||||
|
||||
if ((param & FELICA_RAW)) {
|
||||
|
@ -527,22 +554,29 @@ void felica_sendraw(PacketCommandNG *c) {
|
|||
AddCrc(buf, len);
|
||||
}
|
||||
}
|
||||
|
||||
if (DBGLEVEL > 3) {
|
||||
Dbprintf("Transmit Frame (no CRC shown):");
|
||||
Dbhexdump(len, buf, 0);
|
||||
Dbprintf("Buffer Length: %i", buf[2] + 4);
|
||||
};
|
||||
TransmitFor18092_AsReader(buf, buf[2] + 4, NULL, 1, 0);
|
||||
arg0 = !WaitForFelicaReply(1024);
|
||||
reply_old(CMD_ACK, arg0, 0, 0, FelicaFrame.framebytes + 2, FelicaFrame.len - 2);
|
||||
arg0 = WaitForFelicaReply(1024);
|
||||
if (DBGLEVEL > 3) {
|
||||
Dbprintf("Received Frame Code: %d", arg0);
|
||||
Dbhexdump(FelicaFrame.len, FelicaFrame.framebytes, 0);
|
||||
};
|
||||
uint32_t result = reply_mix(CMD_ACK, FelicaFrame.len, arg0, 0, FelicaFrame.framebytes, FelicaFrame.len);
|
||||
if (result) {
|
||||
Dbprintf("Reply to Client Error Code: %i", result);
|
||||
}
|
||||
}
|
||||
|
||||
if ((param & FELICA_NO_DISCONNECT))
|
||||
return;
|
||||
|
||||
OUT:
|
||||
switch_off();
|
||||
|
||||
//Resetting Frame mode (First set in fpgaloader.c)
|
||||
AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(8) | AT91C_SSC_MSBF | SSC_FRAME_MODE_WORDS_PER_TRANSFER(0);
|
||||
|
||||
if (DBGLEVEL > 3) Dbprintf("FeliCa_sendraw Exit");
|
||||
if ((param & FELICA_NO_DISCONNECT)) {
|
||||
Dbprintf("Disconnect");
|
||||
}
|
||||
if (DBGLEVEL > 3)
|
||||
Dbprintf("FeliCa_sendraw Exit");
|
||||
felica_reset_frame_mode();
|
||||
return;
|
||||
}
|
||||
|
||||
void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) {
|
||||
|
@ -581,7 +615,7 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) {
|
|||
//crc NOT checked
|
||||
if (FelicaFrame.state == STATE_FULL) {
|
||||
endframe = GetCountSspClk();
|
||||
//*dest = FelicaFrame.crc_ok; //kind of wasteful
|
||||
// *dest = FelicaFrame.crc_ok; //kind of wasteful
|
||||
dest++;
|
||||
for (int i = 0; i < FelicaFrame.len; i++) {
|
||||
*dest = FelicaFrame.framebytes[i];
|
||||
|
@ -722,8 +756,102 @@ void felica_sim_lite(uint64_t uid) {
|
|||
DbpString("Felica Lite-S sim end");
|
||||
}
|
||||
|
||||
void felica_dump_lite_s() {
|
||||
#define RES_SVC_LEN 11 + 3
|
||||
|
||||
void felica_dump() {
|
||||
uint8_t ndef[8];
|
||||
uint8_t poll[10] = { 0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21}; // B24D0600FFFF00000921
|
||||
iso18092_setup(FPGA_HF_ISO18092_FLAG_READER | FPGA_HF_ISO18092_FLAG_NOMOD);
|
||||
|
||||
TransmitFor18092_AsReader(poll, 10, NULL, 1, 0);
|
||||
|
||||
// iceman, no exit path in this loop
|
||||
while (!BUTTON_PRESS() && !data_available()) {
|
||||
WDT_HIT();
|
||||
TransmitFor18092_AsReader(poll, 10, NULL, 1, 0);
|
||||
if (WaitForFelicaReply(512) && FelicaFrame.framebytes[3] == FELICA_POLL_ACK) {
|
||||
memcpy(ndef, FelicaFrame.framebytes + 4, 8);
|
||||
uint8_t *request_service = felica_create_request_service_frame(0x01, ndef);
|
||||
felica_send_request_service(request_service);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void felica_send_request_service(uint8_t *request_service) {
|
||||
Dbprintf("Send Service Request - len: d%", RES_SVC_LEN);
|
||||
TransmitFor18092_AsReader(request_service, RES_SVC_LEN, NULL, 1, 0);
|
||||
if (WaitForFelicaReply(512) && FelicaFrame.framebytes[3] == FELICA_REQSRV_ACK) {
|
||||
Dbprintf("Got Service Response!");
|
||||
}
|
||||
}
|
||||
|
||||
/* Create Request Service Frame
|
||||
// Use this command to verify the existence of Area and Service, and to acquire Key Version.
|
||||
// When the specified Area or Service exists, the card returns Key Version.
|
||||
// When the specified Area or Service does not exist, the card returns FFFFh as Key Version.
|
||||
*/
|
||||
uint8_t *felica_create_request_service_frame(uint8_t nodeNumber, uint8_t *idm) {
|
||||
if (nodeNumber < 1 && nodeNumber > 32) {
|
||||
Dbprintf("Node number out of range: 1 <= %d <= 32 - set node number to 1");
|
||||
nodeNumber = 1;
|
||||
}
|
||||
// Sync 2-Byte, Length 1-Byte, CMD 1-Byte, IDm 8-Byte, nodeNumber 1 <= n <= 32 1-Byte, Node Code List <Little Endian>
|
||||
uint8_t *request_service = BigBuf_malloc(sizeof(uint8_t) * RES_SVC_LEN);
|
||||
//{ 0xb2, 0x4d, 0x06, FELICA_REQSRV_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21};
|
||||
request_service[0] = 0xb2; //Sync
|
||||
request_service[1] = 0x4d; //Sync
|
||||
request_service[2] = 0x0B; // Length
|
||||
request_service[3] = FELICA_REQSRV_REQ; // CMD
|
||||
request_service[4] = idm[0];
|
||||
request_service[5] = idm[1];
|
||||
request_service[6] = idm[2];
|
||||
request_service[7] = idm[3];
|
||||
request_service[8] = idm[4];
|
||||
request_service[9] = idm[5];
|
||||
request_service[10] = idm[6];
|
||||
request_service[11] = idm[7];
|
||||
request_service[12] = nodeNumber; // Node we like to ask for services
|
||||
request_service[13] = 0x00; // Node Code List // TODO FIND OUT WHAT NEEDS TO BE IN HERE
|
||||
return request_service;
|
||||
}
|
||||
|
||||
// Create Frame for authentication1 CMD
|
||||
void felica_create_authentication1_frame() {
|
||||
|
||||
}
|
||||
|
||||
// Create Frame for authentication2 CMD
|
||||
void felica_create_authentication2_frame() {
|
||||
|
||||
}
|
||||
|
||||
// Create a Frame for Read without encryption CMD as Payload
|
||||
void felica_create_read_block_frame(uint16_t blockNr) {
|
||||
if (blockNr < 1 || blockNr > 567) {
|
||||
Dbprintf("Block number out of range!");
|
||||
return;
|
||||
}
|
||||
uint8_t c = 0;
|
||||
// First Byte of SYNC
|
||||
frameSpace[c++] = 0xb2;
|
||||
frameSpace[c++] = 0x4d;
|
||||
// skip Length of Frame
|
||||
c++;
|
||||
// Payload
|
||||
frameSpace[c++] = FELICA_RDBLK_REQ; //command number
|
||||
|
||||
// Set frame length
|
||||
|
||||
// CRC
|
||||
}
|
||||
|
||||
void felica_read_block(uint8_t *idm, uint16_t blockNr) {
|
||||
|
||||
|
||||
}
|
||||
|
||||
void felica_dump_lite_s() {
|
||||
uint8_t ndef[8];
|
||||
uint8_t poll[10] = { 0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21};
|
||||
uint16_t liteblks[28] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x90, 0x91, 0x92, 0xa0};
|
||||
|
|
|
@ -18,5 +18,12 @@ void felica_sendraw(PacketCommandNG *c);
|
|||
void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip);
|
||||
void felica_sim_lite(uint64_t uid);
|
||||
void felica_dump_lite_s();
|
||||
void felica_dump();
|
||||
void felica_create_read_block_frame(uint16_t blockNr);
|
||||
void felica_create_authentication1_frame();
|
||||
void felica_create_authentication2_frame();
|
||||
void felica_send_request_service(uint8_t *request_service);
|
||||
void felica_reset_frame_mode();
|
||||
uint8_t *felica_create_request_service_frame(uint8_t nodeNumber, uint8_t *idm);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -201,8 +201,8 @@ int json_printf_array(struct json_out *, va_list *ap);
|
|||
* Return number of elements successfully scanned & converted.
|
||||
* Negative number means scan error.
|
||||
*/
|
||||
int json_scanf(const char *str, int str_len, const char *fmt, ...);
|
||||
int json_vscanf(const char *str, int str_len, const char *fmt, va_list ap);
|
||||
int json_scanf(const char *str, int len, const char *fmt, ...);
|
||||
int json_vscanf(const char *str, int len, const char *fmt, va_list ap);
|
||||
|
||||
/* json_scanf's %M handler */
|
||||
typedef void (*json_scanner_t)(const char *str, int len, void *user_data);
|
||||
|
@ -234,7 +234,7 @@ int json_escape(struct json_out *out, const char *str, size_t str_len);
|
|||
* Read the whole file in memory.
|
||||
* Return malloc-ed file content, or NULL on error. The caller must free().
|
||||
*/
|
||||
char *json_fread(const char *file_name);
|
||||
char *json_fread(const char *path);
|
||||
|
||||
/*
|
||||
* Update given JSON string `s,len` by changing the value at given `json_path`.
|
||||
|
|
|
@ -1235,8 +1235,8 @@ void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
|
|||
|
||||
uint8_t *dest = BigBuf_get_addr();
|
||||
|
||||
//big enough to catch 2 sequences of largest format
|
||||
size_t size = 12800; //50 * 128 * 2;
|
||||
//big enough to catch 2 sequences of largest format but don't exeed whats available in bigbuff.
|
||||
size_t size = MIN(12800, BigBuf_max_traceLen()); //50 * 128 * 2;
|
||||
|
||||
int dummyIdx = 0;
|
||||
|
||||
|
@ -1544,13 +1544,12 @@ void T55xxWriteBit(uint8_t bit, uint8_t downlink_idx) {
|
|||
// max_len - how many bytes can the bit_array hold (ensure no buffer overflow)
|
||||
// returns "Next" bit offset / bits stored (for next store)
|
||||
uint8_t T55xx_SetBits(uint8_t *bs, uint8_t start_offset, uint32_t data, uint8_t num_bits, uint8_t max_len) {
|
||||
int8_t offset;
|
||||
int8_t next_offset = start_offset;
|
||||
|
||||
// Check if data will fit.
|
||||
if ((start_offset + num_bits) <= (max_len * 8)) {
|
||||
// Loop through the data and store
|
||||
for (offset = (num_bits - 1); offset >= 0; offset--) {
|
||||
for (int8_t offset = (num_bits - 1); offset >= 0; offset--) {
|
||||
|
||||
if ((data >> offset) & 1)
|
||||
bs[BITSTREAM_BYTE(next_offset)] |= (1 << BITSTREAM_BIT(next_offset)); // Set 1
|
||||
|
|
|
@ -103,7 +103,7 @@ void MifareReadBlock(uint8_t blockNo, uint8_t keyType, uint8_t *datain) {
|
|||
break;
|
||||
}
|
||||
|
||||
crypto1_destroy(pcs);
|
||||
crypto1_deinit(pcs);
|
||||
|
||||
if (DBGLEVEL >= 2) DbpString("READ BLOCK FINISHED");
|
||||
|
||||
|
@ -264,7 +264,7 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t *datain) {
|
|||
|
||||
if (DBGLEVEL >= 2) DbpString("READ SECTOR FINISHED");
|
||||
|
||||
crypto1_destroy(pcs);
|
||||
crypto1_deinit(pcs);
|
||||
|
||||
LED_B_ON();
|
||||
reply_old(CMD_ACK, isOK, 0, 0, dataoutbuf, 16 * NumBlocksPerSector(sectorNo));
|
||||
|
@ -430,7 +430,7 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain) {
|
|||
break;
|
||||
}
|
||||
|
||||
crypto1_destroy(pcs);
|
||||
crypto1_deinit(pcs);
|
||||
|
||||
if (DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");
|
||||
|
||||
|
@ -847,7 +847,7 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
|
|||
}
|
||||
|
||||
LED_C_OFF();
|
||||
crypto1_destroy(pcs);
|
||||
crypto1_deinit(pcs);
|
||||
LED_B_ON();
|
||||
reply_old(CMD_ACK, isOK, cuid, num_nonces, buf, sizeof(buf));
|
||||
LED_B_OFF();
|
||||
|
@ -1061,7 +1061,7 @@ void MifareNested(uint8_t blockNo, uint8_t keyType, uint8_t targetBlockNo, uint8
|
|||
|
||||
LED_C_OFF();
|
||||
|
||||
crypto1_destroy(pcs);
|
||||
crypto1_deinit(pcs);
|
||||
|
||||
struct p {
|
||||
int16_t isOK;
|
||||
|
@ -1510,7 +1510,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
|
|||
OUT:
|
||||
LEDsoff();
|
||||
|
||||
crypto1_destroy(pcs);
|
||||
crypto1_deinit(pcs);
|
||||
|
||||
// All keys found, send to client, or last keychunk from client
|
||||
if (foundkeys == allkeys || lastchunk) {
|
||||
|
@ -1660,7 +1660,7 @@ void MifareChkKeys(uint8_t *datain) {
|
|||
LEDsoff();
|
||||
|
||||
set_tracing(false);
|
||||
crypto1_destroy(pcs);
|
||||
crypto1_deinit(pcs);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -1780,7 +1780,7 @@ int MifareECardLoad(uint8_t numSectors, uint8_t keyType) {
|
|||
if (DBGLEVEL >= DBG_INFO) DbpString("Emulator fill sectors finished");
|
||||
|
||||
out:
|
||||
crypto1_destroy(pcs);
|
||||
crypto1_deinit(pcs);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
LEDsoff();
|
||||
set_tracing(false);
|
||||
|
@ -2110,7 +2110,7 @@ void MifareSetMod(uint8_t *datain) {
|
|||
break;
|
||||
}
|
||||
|
||||
crypto1_destroy(pcs);
|
||||
crypto1_deinit(pcs);
|
||||
|
||||
LED_B_ON();
|
||||
reply_ng(CMD_HF_MIFARE_SETMOD, isOK, NULL, 0);
|
||||
|
|
|
@ -571,7 +571,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
|
|||
EmSendPrecompiledCmd(&responses[ATQA]);
|
||||
|
||||
// init crypto block
|
||||
crypto1_destroy(pcs);
|
||||
crypto1_deinit(pcs);
|
||||
cardAUTHKEY = AUTHKEYNONE;
|
||||
nonce = prng_successor(selTimer, 32);
|
||||
// prepare NT for nested authentication
|
||||
|
@ -743,10 +743,10 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
|
|||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] KEY %c: %012" PRIx64, (cardAUTHKEY == 0) ? 'A' : 'B', emlGetKey(cardAUTHSC, cardAUTHKEY));
|
||||
|
||||
// first authentication
|
||||
crypto1_destroy(pcs);
|
||||
crypto1_deinit(pcs);
|
||||
|
||||
// Load key into crypto
|
||||
crypto1_create(pcs, emlGetKey(cardAUTHSC, cardAUTHKEY));
|
||||
crypto1_init(pcs, emlGetKey(cardAUTHSC, cardAUTHKEY));
|
||||
|
||||
if (!encrypted_data) {
|
||||
// Receive Cmd in clear txt
|
||||
|
|
|
@ -149,10 +149,10 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN
|
|||
|
||||
// ----------------------------- crypto1 create
|
||||
if (isNested)
|
||||
crypto1_destroy(pcs);
|
||||
crypto1_deinit(pcs);
|
||||
|
||||
// Init cipher with key
|
||||
crypto1_create(pcs, ui64Key);
|
||||
crypto1_init(pcs, ui64Key);
|
||||
|
||||
if (isNested == AUTH_NESTED) {
|
||||
// decrypt nt with help of new key
|
||||
|
@ -276,7 +276,7 @@ int mifare_ultra_auth(uint8_t *keybytes) {
|
|||
uint8_t respPar[3] = {0, 0, 0};
|
||||
|
||||
// REQUEST AUTHENTICATION
|
||||
len = mifare_sendcmd_short(NULL, 1, MIFARE_ULC_AUTH_1, 0x00, resp, respPar, NULL);
|
||||
len = mifare_sendcmd_short(NULL, CRYPT_NONE, MIFARE_ULC_AUTH_1, 0x00, resp, respPar, NULL);
|
||||
if (len != 11) {
|
||||
if (DBGLEVEL >= DBG_ERROR) Dbprintf("Cmd Error: %02x", resp[0]);
|
||||
return 0;
|
||||
|
@ -351,7 +351,7 @@ int mifare_ultra_readblockEx(uint8_t blockNo, uint8_t *blockData) {
|
|||
uint8_t receivedAnswer[MAX_FRAME_SIZE] = {0x00};
|
||||
uint8_t receivedAnswerPar[MAX_PARITY_SIZE] = {0x00};
|
||||
|
||||
len = mifare_sendcmd_short(NULL, 1, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
||||
len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_READBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
||||
if (len == 1) {
|
||||
if (DBGLEVEL >= DBG_ERROR) Dbprintf("Cmd Error: %02x", receivedAnswer[0]);
|
||||
return 1;
|
||||
|
@ -444,7 +444,7 @@ int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData) {
|
|||
uint8_t receivedAnswer[MAX_FRAME_SIZE];
|
||||
uint8_t receivedAnswerPar[MAX_PARITY_SIZE];
|
||||
|
||||
len = mifare_sendcmd_short(NULL, true, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
||||
len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_WRITEBLOCK, blockNo, receivedAnswer, receivedAnswerPar, NULL);
|
||||
|
||||
if ((len != 1) || (receivedAnswer[0] != 0x0A)) { // 0x0a - ACK
|
||||
if (DBGLEVEL >= DBG_ERROR)
|
||||
|
|
|
@ -543,7 +543,7 @@ void rdv40_spiffs_safe_print_fsinfo() {
|
|||
rdv40_spiffs_getfsinfo(&fsinfo, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
|
||||
DbpString(_BLUE_("Flash Memory FileSystem Info (SPIFFS)"));
|
||||
|
||||
|
||||
|
||||
Dbprintf(" Logical Block Size........." _YELLOW_("%d")"bytes", fsinfo.blockSize);
|
||||
Dbprintf(" Logical Page Size.........." _YELLOW_("%d")"bytes", fsinfo.pageSize);
|
||||
|
@ -573,7 +573,7 @@ void rdv40_spiffs_safe_print_tree(uint8_t banner) {
|
|||
DbpString(_BLUE_("Flash Memory FileSystem tree (SPIFFS)"));
|
||||
Dbprintf("-------------------------------------");
|
||||
}
|
||||
|
||||
|
||||
int changed = rdv40_spiffs_lazy_mount();
|
||||
spiffs_DIR d;
|
||||
struct spiffs_dirent e;
|
||||
|
@ -614,7 +614,7 @@ void test_spiffs() {
|
|||
|
||||
Dbprintf(" Printing tree..............");
|
||||
rdv40_spiffs_safe_print_tree(false);
|
||||
|
||||
|
||||
Dbprintf(" Writing 'I love Proxmark3 RDV4' in a testspiffs.txt");
|
||||
|
||||
// Since We lazy_mounted manually before hand, the wrte safety level will
|
||||
|
|
|
@ -63,7 +63,7 @@ static void CodeThinfilmAsTag(const uint8_t *cmd, uint16_t len) {
|
|||
for (uint16_t i = 0; i < len; i++) {
|
||||
uint8_t b = cmd[i];
|
||||
for (uint8_t j = 0; j < 8; j++) {
|
||||
ToSend[++ToSendMax] = b & 0x80 ? SEC_D : SEC_E;
|
||||
ToSend[++ToSendMax] = (b & 0x80) ? SEC_D : SEC_E;
|
||||
b <<= 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1872,7 +1872,7 @@ int CmdPlot(const char *Cmd) {
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdSave(const char *Cmd) {
|
||||
int CmdSave(const char *Cmd) {
|
||||
|
||||
int len = 0;
|
||||
char filename[FILE_PATH_SIZE] = {0x00};
|
||||
|
|
|
@ -53,6 +53,7 @@ int CmdHpf(const char *Cmd);
|
|||
int CmdLtrim(const char *Cmd); // used by cmd lf em4x, lf t55xx
|
||||
int CmdNorm(const char *Cmd); // used by cmd lf data (!)
|
||||
int CmdPlot(const char *Cmd); // used by cmd lf cotag
|
||||
int CmdSave(const char *Cmd); // used by cmd auto
|
||||
int CmdTuneSamples(const char *Cmd); // used by cmd lf hw
|
||||
int ASKbiphaseDemod(const char *Cmd, bool verbose); // used by cmd lf em4x, lf fdx, lf guard, lf jablotron, lf nedap, lf t55xx
|
||||
int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType); // used by cmd lf em4x, lf t55xx, lf viking
|
||||
|
|
|
@ -70,6 +70,8 @@ static int usage_hf_tune() {
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
#define PROMPT_CLEARLINE PrintAndLogEx(INPLACE, " ")
|
||||
|
||||
int CmdHFSearch(const char *Cmd) {
|
||||
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
|
@ -77,6 +79,7 @@ int CmdHFSearch(const char *Cmd) {
|
|||
|
||||
PrintAndLogEx(INFO, "Checking for known tags...\n");
|
||||
|
||||
PROMPT_CLEARLINE;
|
||||
PrintAndLogEx(INPLACE, "Searching for ThinFilm tag...");
|
||||
if (IfPm3NfcBarcode()) {
|
||||
if (infoThinFilm(false) == PM3_SUCCESS) {
|
||||
|
@ -85,6 +88,7 @@ int CmdHFSearch(const char *Cmd) {
|
|||
}
|
||||
}
|
||||
|
||||
PROMPT_CLEARLINE;
|
||||
PrintAndLogEx(INPLACE, "Searching for ISO14443-A tag...");
|
||||
if (IfPm3Iso14443a()) {
|
||||
if (infoHF14A(false, false) > 0) {
|
||||
|
@ -93,6 +97,7 @@ int CmdHFSearch(const char *Cmd) {
|
|||
}
|
||||
}
|
||||
|
||||
PROMPT_CLEARLINE;
|
||||
PrintAndLogEx(INPLACE, "Searching for ISO15693 tag...");
|
||||
if (IfPm3Iso15693()) {
|
||||
if (readHF15Uid(false) == 1) {
|
||||
|
@ -104,6 +109,7 @@ int CmdHFSearch(const char *Cmd) {
|
|||
DropField();
|
||||
}
|
||||
|
||||
PROMPT_CLEARLINE;
|
||||
PrintAndLogEx(INPLACE, "Searching for LEGIC tag...");
|
||||
if (IfPm3Legicrf()) {
|
||||
if (readLegicUid(false) == PM3_SUCCESS) {
|
||||
|
@ -112,6 +118,7 @@ int CmdHFSearch(const char *Cmd) {
|
|||
}
|
||||
}
|
||||
|
||||
PROMPT_CLEARLINE;
|
||||
PrintAndLogEx(INPLACE, "Searching for Topaz tag...");
|
||||
if (IfPm3Iso14443a()) {
|
||||
if (readTopazUid() == PM3_SUCCESS) {
|
||||
|
@ -120,7 +127,17 @@ int CmdHFSearch(const char *Cmd) {
|
|||
}
|
||||
}
|
||||
|
||||
PROMPT_CLEARLINE;
|
||||
PrintAndLogEx(INPLACE, "Searching for FeliCa tag...");
|
||||
if (IfPm3Felica()) {
|
||||
if (readFelicaUid(false) == PM3_SUCCESS) {
|
||||
PrintAndLogEx(NORMAL, "\nValid " _GREEN_("ISO18092 / FeliCa tag") " found\n");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
// 14b and iclass is the longest test (put last)
|
||||
PROMPT_CLEARLINE;
|
||||
PrintAndLogEx(INPLACE, "Searching for ISO14443-B tag...");
|
||||
if (IfPm3Iso14443a()) {
|
||||
if (readHF14B(false) == 1) {
|
||||
|
@ -129,6 +146,7 @@ int CmdHFSearch(const char *Cmd) {
|
|||
}
|
||||
}
|
||||
|
||||
PROMPT_CLEARLINE;
|
||||
PrintAndLogEx(INPLACE, "Searching for iClass / PicoPass tag...");
|
||||
if (IfPm3Iclass()) {
|
||||
if (readIclass(false, false) == 1) {
|
||||
|
@ -137,17 +155,6 @@ int CmdHFSearch(const char *Cmd) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// PrintAndLogEx(INPLACE, "Searching for FeliCa tag...");
|
||||
//if (IfPm3Felica()) {
|
||||
// ans = CmdHFFelicaReader("s");
|
||||
// if (ans) {
|
||||
// PrintAndLogEx(NORMAL, "\nValid " _GREEN_("ISO18092 / FeliCa tag") " found\n");
|
||||
// return ans;
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
PrintAndLogEx(INPLACE, "No known/supported 13.56 MHz tags found");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
return PM3_ESOFT;
|
||||
|
|
|
@ -36,9 +36,10 @@ static int usage_hf_felica_sim(void) {
|
|||
PrintAndLogEx(NORMAL, " v : (Optional) Verbose");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " hf felica sim t 1 ");
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
*/
|
||||
|
||||
static int usage_hf_felica_sniff(void) {
|
||||
PrintAndLogEx(NORMAL, "It get data from the field and saves it into command buffer.");
|
||||
PrintAndLogEx(NORMAL, "Buffer accessible from command 'hf list felica'");
|
||||
|
@ -47,7 +48,7 @@ static int usage_hf_felica_sniff(void) {
|
|||
PrintAndLogEx(NORMAL, " t triggers to skip (decimal)");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " hf felica sniff s 1000");
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
static int usage_hf_felica_simlite(void) {
|
||||
PrintAndLogEx(NORMAL, "\n Emulating ISO/18092 FeliCa Lite tag \n");
|
||||
|
@ -57,7 +58,7 @@ static int usage_hf_felica_simlite(void) {
|
|||
PrintAndLogEx(NORMAL, " uid : UID in hexsymbol");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " hf felica litesim 11223344556677");
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
static int usage_hf_felica_dumplite(void) {
|
||||
PrintAndLogEx(NORMAL, "\n Dump ISO/18092 FeliCa Lite tag \n");
|
||||
|
@ -67,7 +68,7 @@ static int usage_hf_felica_dumplite(void) {
|
|||
PrintAndLogEx(NORMAL, " h : This help");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " hf felica litedump");
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
static int usage_hf_felica_raw(void) {
|
||||
PrintAndLogEx(NORMAL, "Usage: hf felica raw [-h] [-r] [-c] [-p] [-a] <0A 0B 0C ... hex>");
|
||||
|
@ -77,20 +78,30 @@ static int usage_hf_felica_raw(void) {
|
|||
PrintAndLogEx(NORMAL, " -p leave the signal field ON after receive");
|
||||
PrintAndLogEx(NORMAL, " -a active signal field ON without select");
|
||||
PrintAndLogEx(NORMAL, " -s active signal field ON with select");
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int usage_hf_felica_dump(void) {
|
||||
PrintAndLogEx(NORMAL, "Usage: hf felica dump [-h] <outputfile>");
|
||||
PrintAndLogEx(NORMAL, " -h this help");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdHFFelicaList(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
//PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list felica' instead");
|
||||
CmdTraceList("felica");
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdHFFelicaReader(const char *Cmd) {
|
||||
bool verbose = !(Cmd[0] == 's' || Cmd[0] == 'S');
|
||||
readFelicaUid(verbose);
|
||||
return 0;
|
||||
bool verbose = !(tolower(Cmd[0]) == 's');
|
||||
return readFelicaUid(verbose);
|
||||
}
|
||||
|
||||
static int CmdHFFelicaDump(const char *Cmd) {
|
||||
if (strlen(Cmd) < 1) return usage_hf_felica_dump();
|
||||
return dump(*Cmd);
|
||||
}
|
||||
|
||||
// simulate iso18092 / FeliCa tag
|
||||
|
@ -156,7 +167,7 @@ static int CmdHFFelicaSim(const char *Cmd) {
|
|||
while (!kbd_enter_pressed()) {
|
||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) continue;
|
||||
}
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
*/
|
||||
|
||||
|
@ -193,7 +204,7 @@ static int CmdHFFelicaSniff(const char *Cmd) {
|
|||
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_FELICA_SNIFF, samples2skip, triggers2skip, 0, NULL, 0);
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// uid hex
|
||||
|
@ -206,7 +217,7 @@ static int CmdHFFelicaSimLite(const char *Cmd) {
|
|||
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_FELICALITE_SIMULATE, uid, 0, 0, NULL, 0);
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static void printSep() {
|
||||
|
@ -351,7 +362,7 @@ static uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace, uint16_t trac
|
|||
PrintAndLogEx(NORMAL, "Authenticated: %s", trace[3] ? "yes" : "no");
|
||||
break;
|
||||
case 0xa0:
|
||||
PrintAndLogEx(NORMAL, "CRC of all bloacks match : %s", (trace[3 + 2] == 0xff) ? "no" : "yes");
|
||||
PrintAndLogEx(NORMAL, "CRC of all blocks match : %s", (trace[3 + 2] == 0xff) ? "no" : "yes");
|
||||
break;
|
||||
default:
|
||||
PrintAndLogEx(WARNING, "INVALID %d: %s", blocknum, line);
|
||||
|
@ -379,36 +390,38 @@ static int CmdHFFelicaDumpLite(const char *Cmd) {
|
|||
if (kbd_enter_pressed()) {
|
||||
PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n");
|
||||
DropField();
|
||||
return 1;
|
||||
return PM3_EOPABORTED;
|
||||
}
|
||||
if (timeout > 100) {
|
||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||
DropField();
|
||||
return 1;
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
}
|
||||
if (resp.oldarg[0] == 0) {
|
||||
PrintAndLogEx(WARNING, "\nButton pressed. Aborted.");
|
||||
return 1;
|
||||
return PM3_EOPABORTED;
|
||||
}
|
||||
|
||||
uint32_t tracelen = resp.oldarg[1];
|
||||
if (tracelen == 0)
|
||||
return 1;
|
||||
if (tracelen == 0) {
|
||||
PrintAndLogEx(WARNING, "\nNo trace data! Maybe not a FeliCa Lite card?");
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
uint8_t *trace = calloc(tracelen, sizeof(uint8_t));
|
||||
if (trace == NULL) {
|
||||
PrintAndLogEx(WARNING, "Cannot allocate memory for trace");
|
||||
return 1;
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
|
||||
if (!GetFromDevice(BIG_BUF, trace, tracelen, 0, NULL, 0, NULL, 2500, false)) {
|
||||
PrintAndLogEx(WARNING, "command execution time out");
|
||||
free(trace);
|
||||
return 0;
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Recorded Activity (trace len = %"PRIu32" bytes)", tracelen);
|
||||
PrintAndLogEx(SUCCESS, "Recorded Activity (trace len = %"PRIu64" bytes)", tracelen);
|
||||
|
||||
print_hex_break(trace, tracelen, 32);
|
||||
printSep();
|
||||
|
@ -420,20 +433,19 @@ static int CmdHFFelicaDumpLite(const char *Cmd) {
|
|||
printSep();
|
||||
|
||||
free(trace);
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static void waitCmdFelica(uint8_t iSelect) {
|
||||
PacketResponseNG resp;
|
||||
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||
uint16_t len = iSelect ? (resp.oldarg[1] & 0xffff) : (resp.oldarg[0] & 0xffff);
|
||||
PrintAndLogEx(NORMAL, "received %i octets", len);
|
||||
uint16_t len = iSelect ? (resp.oldarg[1] & 0xffff) : (resp.oldarg[0] & 0xffff);
|
||||
PrintAndLogEx(NORMAL, "Client Received %i octets", len);
|
||||
if (!len)
|
||||
return;
|
||||
PrintAndLogEx(NORMAL, "%s", sprint_hex(resp.data.asBytes, len));
|
||||
} else {
|
||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||
PrintAndLogEx(WARNING, "Timeout while waiting for reply.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -510,14 +522,15 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) {
|
|||
continue;
|
||||
}
|
||||
PrintAndLogEx(WARNING, "Invalid char on input");
|
||||
return 0;
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
if (crc && datalen > 0 && datalen < sizeof(data) - 2) {
|
||||
uint8_t b1, b2;
|
||||
compute_crc(CRC_FELICA, data, datalen, &b1, &b2);
|
||||
data[datalen++] = b1;
|
||||
// TODO FIND OUT IF FeliCa Light has another CRC order - Order changed for FeliCa Standard cards
|
||||
data[datalen++] = b2;
|
||||
data[datalen++] = b1;
|
||||
}
|
||||
|
||||
uint8_t flags = 0;
|
||||
|
@ -539,39 +552,18 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) {
|
|||
datalen = (datalen > PM3_CMD_DATA_SIZE) ? PM3_CMD_DATA_SIZE : datalen;
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandOLD(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen);
|
||||
SendCommandMIX(CMD_HF_FELICA_COMMAND, flags, (datalen & 0xFFFF) | (uint32_t)(numbits << 16), 0, data, datalen);
|
||||
|
||||
if (reply) {
|
||||
if (active_select)
|
||||
if (active_select) {
|
||||
PrintAndLogEx(NORMAL, "Active select wait for FeliCa.");
|
||||
waitCmdFelica(1);
|
||||
if (datalen > 0)
|
||||
}
|
||||
if (datalen > 0) {
|
||||
waitCmdFelica(0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"list", CmdHFFelicaList, AlwaysAvailable, "List ISO 18092/FeliCa history"},
|
||||
{"reader", CmdHFFelicaReader, IfPm3Felica, "Act like an ISO18092/FeliCa reader"},
|
||||
// {"sim", CmdHFFelicaSim, IfPm3Felica, "<UID> -- Simulate ISO 18092/FeliCa tag"},
|
||||
{"sniff", CmdHFFelicaSniff, IfPm3Felica, "sniff ISO 18092/Felica traffic"},
|
||||
{"raw", CmdHFFelicaCmdRaw, IfPm3Felica, "Send raw hex data to tag"},
|
||||
|
||||
{"litesim", CmdHFFelicaSimLite, IfPm3Felica, "<NDEF2> - only reply to poll request"},
|
||||
{"litedump", CmdHFFelicaDumpLite, IfPm3Felica, "Wait for and try dumping FelicaLite"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
static int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHFFelica(const char *Cmd) {
|
||||
clearCommandBuffer();
|
||||
return CmdsParse(CommandTable, Cmd);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int readFelicaUid(bool verbose) {
|
||||
|
@ -582,7 +574,7 @@ int readFelicaUid(bool verbose) {
|
|||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) {
|
||||
if (verbose) PrintAndLogEx(WARNING, "FeliCa card select failed");
|
||||
//SendCommandMIX(CMD_HF_FELICA_COMMAND, 0, 0, 0, NULL, 0);
|
||||
return 0;
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
felica_card_select_t card;
|
||||
|
@ -593,19 +585,20 @@ int readFelicaUid(bool verbose) {
|
|||
case 1: {
|
||||
if (verbose)
|
||||
PrintAndLogEx(WARNING, "card timeout");
|
||||
break;
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
case 2: {
|
||||
if (verbose)
|
||||
PrintAndLogEx(WARNING, "card answered wrong");
|
||||
break;
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
case 3: {
|
||||
if (verbose)
|
||||
PrintAndLogEx(WARNING, "CRC check failed");
|
||||
break;
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
case 0: {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(SUCCESS, "FeliCa tag info");
|
||||
|
||||
PrintAndLogEx(NORMAL, "IDm %s", sprint_hex(card.IDm, sizeof(card.IDm)));
|
||||
|
@ -620,5 +613,40 @@ int readFelicaUid(bool verbose) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int dump(const char *Cmd) {
|
||||
clearCommandBuffer();
|
||||
char ctmp = tolower(param_getchar(Cmd, 0));
|
||||
if (ctmp == 'h') return usage_hf_felica_dumplite();
|
||||
|
||||
// TODO FINISH THIS METHOD
|
||||
PrintAndLogEx(SUCCESS, "NOT IMPLEMENTED YET!");
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"list", CmdHFFelicaList, AlwaysAvailable, "List ISO 18092/FeliCa history"},
|
||||
{"reader", CmdHFFelicaReader, IfPm3Felica, "Act like an ISO18092/FeliCa reader"},
|
||||
// {"sim", CmdHFFelicaSim, IfPm3Felica, "<UID> -- Simulate ISO 18092/FeliCa tag"},
|
||||
{"sniff", CmdHFFelicaSniff, IfPm3Felica, "sniff ISO 18092/Felica traffic"},
|
||||
{"raw", CmdHFFelicaCmdRaw, IfPm3Felica, "Send raw hex data to tag"},
|
||||
{"dump", CmdHFFelicaDump, IfPm3Felica, "Wait for and try dumping Felica"},
|
||||
{"litesim", CmdHFFelicaSimLite, IfPm3Felica, "<NDEF2> - only reply to poll request"},
|
||||
{"litedump", CmdHFFelicaDumpLite, IfPm3Felica, "Wait for and try dumping FelicaLite"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
static int CmdHelp(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CmdsHelp(CommandTable);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int CmdHFFelica(const char *Cmd) {
|
||||
clearCommandBuffer();
|
||||
return CmdsParse(CommandTable, Cmd);
|
||||
}
|
||||
|
|
|
@ -16,4 +16,6 @@
|
|||
int CmdHFFelica(const char *Cmd);
|
||||
|
||||
int readFelicaUid(bool verbose);
|
||||
|
||||
int dump();
|
||||
#endif
|
||||
|
|
|
@ -2330,7 +2330,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) {
|
|||
uint8_t found_offset = 0;
|
||||
uint32_t key_offset = 0;
|
||||
// main keychunk loop
|
||||
for (uint32_t key_offset = 0; key_offset < keycount; key_offset += chunksize) {
|
||||
for (key_offset = 0; key_offset < keycount; key_offset += chunksize) {
|
||||
|
||||
uint64_t t2 = msclock();
|
||||
uint8_t timeout = 0;
|
||||
|
@ -2806,16 +2806,18 @@ int readIclass(bool loop, bool verbose) {
|
|||
FLAG_ICLASS_READER_ONE_TRY;
|
||||
|
||||
// loop in client not device - else on windows have a communication error
|
||||
PacketResponseNG resp;
|
||||
while (!kbd_enter_pressed()) {
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_HF_ICLASS_READER, flags, 0, 0, NULL, 0);
|
||||
PacketResponseNG resp;
|
||||
|
||||
if (WaitForResponseTimeout(CMD_ACK, &resp, 4500)) {
|
||||
|
||||
uint8_t readStatus = resp.oldarg[0] & 0xff;
|
||||
uint8_t *data = resp.data.asBytes;
|
||||
|
||||
if (verbose) PrintAndLogEx(INFO, "Readstatus:%02x", readStatus);
|
||||
// if (verbose) PrintAndLogEx(INFO, "Readstatus:%02x", readStatus);
|
||||
|
||||
// no tag found or button pressed
|
||||
if ((readStatus == 0 && !loop) || readStatus == 0xFF) {
|
||||
|
@ -2837,18 +2839,29 @@ int readIclass(bool loop, bool verbose) {
|
|||
printIclassDumpInfo(data);
|
||||
}
|
||||
|
||||
// if CSN ends with FF12E0, it's inside HID CSN range.
|
||||
bool isHidRange = (memcmp((uint8_t *)(data + 5), "\xFF\x12\xE0", 3) == 0);
|
||||
|
||||
if (readStatus & FLAG_ICLASS_READER_AIA) {
|
||||
bool legacy = (memcmp((uint8_t *)(data + 8 * 5), "\xff\xff\xff\xff\xff\xff\xff\xff", 8) == 0);
|
||||
|
||||
bool se_enabled = (memcmp((uint8_t *)(data + 8 * 5), "\xff\xff\xff\x00\x06\xff\xff\xff", 8) == 0);
|
||||
|
||||
PrintAndLogEx(NORMAL, " App IA: %s", sprint_hex(data + 8 * 5, 8));
|
||||
if (legacy)
|
||||
PrintAndLogEx(SUCCESS, " : Possible iClass (legacy credential tag)");
|
||||
else if (se_enabled)
|
||||
PrintAndLogEx(SUCCESS, " : Possible iClass (SE credential tag)");
|
||||
else
|
||||
PrintAndLogEx(WARNING, " : Possible iClass (NOT legacy tag)");
|
||||
|
||||
if (isHidRange) {
|
||||
if (legacy)
|
||||
PrintAndLogEx(SUCCESS, " : Possible iClass - legacy credential tag");
|
||||
|
||||
if (se_enabled)
|
||||
PrintAndLogEx(SUCCESS, " : Possible iClass - SE credential tag");
|
||||
}
|
||||
|
||||
if (isHidRange) {
|
||||
PrintAndLogEx(SUCCESS, " : Tag is "_YELLOW_("iClass")", CSN is in HID range");
|
||||
} else {
|
||||
PrintAndLogEx(SUCCESS, " : Tag is "_YELLOW_("PicoPass")", CSN is not in HID range");
|
||||
}
|
||||
}
|
||||
|
||||
if (tagFound && !loop) {
|
||||
|
|
|
@ -1052,6 +1052,11 @@ static void estimate_sum_a8(void) {
|
|||
|
||||
|
||||
static int read_nonce_file(char *filename) {
|
||||
|
||||
if (filename == NULL) {
|
||||
PrintAndLogEx(WARNING, "Filename is NULL");
|
||||
return 1;
|
||||
}
|
||||
FILE *fnonces = NULL;
|
||||
char progress_text[80] = "";
|
||||
uint8_t read_buf[9];
|
||||
|
@ -1061,6 +1066,7 @@ static int read_nonce_file(char *filename) {
|
|||
PrintAndLogEx(WARNING, "Could not open file %s", filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
snprintf(progress_text, 80, "Reading nonces from file %s...", filename);
|
||||
hardnested_print_progress(0, progress_text, (float)(1LL << 47), 0);
|
||||
size_t bytes_read = fread(read_buf, 1, 6, fnonces);
|
||||
|
@ -1766,7 +1772,7 @@ static void add_matching_states(statelist_t *candidates, uint8_t part_sum_a0, ui
|
|||
}
|
||||
|
||||
static statelist_t *add_more_candidates(void) {
|
||||
statelist_t *new_candidates = candidates;
|
||||
statelist_t *new_candidates;
|
||||
if (candidates == NULL) {
|
||||
candidates = (statelist_t *)malloc(sizeof(statelist_t));
|
||||
new_candidates = candidates;
|
||||
|
|
|
@ -1991,7 +1991,7 @@ static int CmdHF14AMfUDump(const char *Cmd) {
|
|||
if (!(tagtype & UL_C || tagtype & UL)) {
|
||||
//attempt to read pack
|
||||
uint8_t get_pack[] = {0, 0};
|
||||
if (!ul_auth_select(&card, tagtype, true, authKeyPtr, get_pack, sizeof(get_pack))) {
|
||||
if (ul_auth_select(&card, tagtype, true, authKeyPtr, get_pack, sizeof(get_pack)) != PM3_SUCCESS) {
|
||||
//reset pack
|
||||
get_pack[0] = 0;
|
||||
get_pack[1] = 0;
|
||||
|
|
|
@ -371,7 +371,7 @@ static int usage_t55xx_dangerraw() {
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int usage_t55xx_clonehelp(){
|
||||
static int usage_t55xx_clonehelp() {
|
||||
PrintAndLogEx(NORMAL, "For cloning specific techs on T55xx tags, see commands available in corresponding LF sub-menus, e.g.:");
|
||||
PrintAndLogEx(NORMAL, _GREEN_("lf awid clone"));
|
||||
// todo: rename to clone
|
||||
|
@ -1083,7 +1083,7 @@ static int CmdT55xxDetect(const char *Cmd) {
|
|||
if (try_all_dl_modes) {
|
||||
for (uint8_t m = downlink_mode; m < 4; m++) {
|
||||
|
||||
if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, try_with_pwd & usepwd, password, m) == false)
|
||||
if (AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, try_with_pwd && usepwd, password, m) == false)
|
||||
continue;
|
||||
|
||||
// pre fill to save passing in.
|
||||
|
@ -1111,7 +1111,7 @@ static int CmdT55xxDetect(const char *Cmd) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!found & usepwd)
|
||||
if (!found && usepwd)
|
||||
try_with_pwd = !try_with_pwd; // toggle so we loop back if not found and try with pwd
|
||||
|
||||
if (found)
|
||||
|
|
|
@ -148,7 +148,7 @@ char *GetQ5ModulationStr(uint32_t id);
|
|||
char *GetModulationStr(uint32_t id, bool xmode);
|
||||
char *GetModelStrFromCID(uint32_t cid);
|
||||
char *GetSelectedModulationStr(uint8_t id);
|
||||
char *GetDownlinkModeStr(uint8_t dlmode);
|
||||
char *GetDownlinkModeStr(uint8_t downlink_mode);
|
||||
void printT5xxHeader(uint8_t page);
|
||||
void printT55xxBlock(uint8_t blockNum, bool page1);
|
||||
int printConfiguration(t55xx_conf_block_t b);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h> // MingW
|
||||
#include <stdlib.h> // calloc
|
||||
|
||||
#include "comms.h"
|
||||
#include "cmdhf.h"
|
||||
|
@ -38,20 +39,6 @@
|
|||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
static int CmdRem(const char *Cmd) {
|
||||
char buf[22] = {0};
|
||||
struct tm *ct, tm_buf;
|
||||
time_t now = time(NULL);
|
||||
#if defined(_WIN32)
|
||||
ct = gmtime_s(&tm_buf, &now) == 0 ? &tm_buf : NULL;
|
||||
#else
|
||||
ct = gmtime_r(&now, &tm_buf);
|
||||
#endif
|
||||
strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%SZ", ct); // ISO8601
|
||||
PrintAndLogEx(NORMAL, "%s remark: %s", buf, Cmd);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int usage_msleep(void) {
|
||||
PrintAndLogEx(NORMAL, "Sleep for given amount of milliseconds");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
|
@ -65,6 +52,63 @@ static int usage_msleep(void) {
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int usage_auto(void) {
|
||||
PrintAndLogEx(NORMAL, "Run LF SEARCH / HF SEARCH / DATA PLOT / DATA SAVE ");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Usage: auto <ms>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h This help");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " auto");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static void AppendDate(char *s, size_t slen, char *fmt) {
|
||||
struct tm *ct, tm_buf;
|
||||
time_t now = time(NULL);
|
||||
#if defined(_WIN32)
|
||||
ct = gmtime_s(&tm_buf, &now) == 0 ? &tm_buf : NULL;
|
||||
#else
|
||||
ct = gmtime_r(&now, &tm_buf);
|
||||
#endif
|
||||
if (fmt == NULL)
|
||||
strftime(s, slen, "%Y-%m-%dT%H:%M:%SZ", ct); // ISO8601
|
||||
else
|
||||
strftime(s, slen, fmt, ct);
|
||||
}
|
||||
|
||||
static int CmdAuto(const char *Cmd) {
|
||||
char ctmp = tolower(param_getchar(Cmd, 0));
|
||||
if (ctmp == 'h') return usage_auto();
|
||||
|
||||
int ret = CmdLFfind("");
|
||||
if (ret == PM3_SUCCESS)
|
||||
return ret;
|
||||
|
||||
ret = CmdHFSearch("");
|
||||
if (ret == PM3_SUCCESS)
|
||||
return ret;
|
||||
|
||||
PrintAndLogEx(INFO, "Failed both LF / HF SEARCH,");
|
||||
PrintAndLogEx(INFO, "Trying 'lf read' and save a trace for you...");
|
||||
|
||||
CmdPlot("");
|
||||
lf_read(true, 40000);
|
||||
char *fname = calloc(100, sizeof(uint8_t));
|
||||
AppendDate(fname, 100, "lf_unknown_%Y-%m-%d_%H:%M.pm3");
|
||||
CmdSave(fname);
|
||||
free(fname);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
int CmdRem(const char *Cmd) {
|
||||
char buf[22] = {0};
|
||||
AppendDate(buf, sizeof(buf), NULL);
|
||||
PrintAndLogEx(NORMAL, "%s remark: %s", buf, Cmd);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdMsleep(const char *Cmd) {
|
||||
uint32_t ms = 0;
|
||||
char ctmp = tolower(param_getchar(Cmd, 0));
|
||||
|
@ -90,6 +134,7 @@ static int CmdRev(const char *Cmd) {
|
|||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help. Use '<command> help' for details of a particular command."},
|
||||
{"auto", CmdAuto, IfPm3Present, "Automated detection process for unknown tags"},
|
||||
{"analyse", CmdAnalyse, AlwaysAvailable, "{ Analyse utils... }"},
|
||||
{"data", CmdData, AlwaysAvailable, "{ Plot window / data buffer manipulation... }"},
|
||||
{"emv", CmdEMV, AlwaysAvailable, "{ EMV ISO-14443 / ISO-7816... }"},
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "cmdparser.h" // command_t
|
||||
|
||||
int CommandReceived(char *Cmd);
|
||||
int CmdRem(const char *Cmd);
|
||||
command_t *getTopLevelCommandTable(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -548,7 +548,6 @@ static int CmdSmartUpgrade(const char *Cmd) {
|
|||
//Validations
|
||||
if (errors || cmdp == 0) return usage_sm_upgrade();
|
||||
|
||||
|
||||
char sha512filename[FILE_PATH_SIZE] = {'\0'};
|
||||
char *bin_extension = filename;
|
||||
char *dot_position = NULL;
|
||||
|
@ -556,11 +555,7 @@ static int CmdSmartUpgrade(const char *Cmd) {
|
|||
bin_extension = dot_position + 1;
|
||||
}
|
||||
|
||||
if (!strcmp(bin_extension, "BIN")
|
||||
#ifdef _WIN32
|
||||
|| !strcmp(bin_extension, "bin")
|
||||
#endif
|
||||
) {
|
||||
if (!strcmp(bin_extension, "BIN") || !strcmp(bin_extension, "bin")) {
|
||||
memcpy(sha512filename, filename, strlen(filename) - strlen("bin"));
|
||||
strcat(sha512filename, "sha512.txt");
|
||||
} else {
|
||||
|
|
|
@ -150,11 +150,11 @@ int CmdWiegandDecode(const char *Cmd) {
|
|||
bool errors = false;
|
||||
char cmdp = 0;
|
||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
uint32_t strlen = param_getlength(Cmd, cmdp);
|
||||
strlen++; // null termin
|
||||
if (strlen > 2) {
|
||||
char *s = calloc(strlen, sizeof(uint8_t));
|
||||
param_getstr(Cmd, cmdp, s, strlen);
|
||||
uint32_t slen = param_getlength(Cmd, cmdp);
|
||||
slen++; // null termin
|
||||
if (slen > 2) {
|
||||
char *s = calloc(slen, sizeof(uint8_t));
|
||||
param_getstr(Cmd, cmdp, s, slen);
|
||||
hexstring_to_u96(&top, &mid, &bot, s);
|
||||
free(s);
|
||||
gothex = true;
|
||||
|
|
|
@ -1089,7 +1089,7 @@ int RecoveryCertificates(struct tlvdb *tlvRoot, json_t *root) {
|
|||
char *icc_pk_c = emv_pk_dump_pk(icc_pk);
|
||||
JsonSaveStr(root, "$.ApplicationData.ICCPublicKeyDec", icc_pk_c);
|
||||
JsonSaveBufAsHex(root, "$.ApplicationData.ICCPublicKeyModulus", icc_pk->modulus, icc_pk->mlen);
|
||||
free(issuer_pk_c);
|
||||
free(icc_pk_c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -372,8 +372,8 @@ bool ParamLoadFromJson(struct tlvdb *tlv) {
|
|||
return false;
|
||||
}
|
||||
tlv_tag_t tag = 0;
|
||||
for (int i = 0; i < buflen; i++) {
|
||||
tag = (tag << 8) | buf[i];
|
||||
for (int j = 0; j < buflen; j++) {
|
||||
tag = (tag << 8) | buf[j];
|
||||
}
|
||||
|
||||
if (!HexToBuffer("TLV Error value:", tlvValue, buf, sizeof(buf) - 1, &buflen)) {
|
||||
|
|
|
@ -75,9 +75,9 @@ static CborError dumpelm(CborValue *it, bool *got_next, int nestingLevel) {
|
|||
}
|
||||
|
||||
case CborSimpleType: {
|
||||
uint8_t type;
|
||||
cbor_value_get_simple_type(it, &type);
|
||||
printf("simple(%u)", type);
|
||||
uint8_t t;
|
||||
cbor_value_get_simple_type(it, &t);
|
||||
printf("simple(%u)", t);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -206,7 +206,7 @@ int TinyCborPrintFIDOPackage(uint8_t cmdCode, bool isResponse, uint8_t *data, si
|
|||
|
||||
if (err) {
|
||||
fprintf(stderr,
|
||||
"CBOR parsing failure at offset %" PRId32 " : %s\n",
|
||||
"CBOR parsing failure at offset %" PRIu32 " : %s\n",
|
||||
(uint32_t)(cb.ptr - data),
|
||||
cbor_error_string(err)
|
||||
);
|
||||
|
|
|
@ -250,16 +250,16 @@ void prepare_bf_test_nonces(noncelist_t *nonces, uint8_t best_first_byte) {
|
|||
uint32_t bf_test_nonce_temp[4];
|
||||
uint8_t bf_test_nonce_par_temp[4];
|
||||
uint8_t bf_test_nonce_2nd_byte_temp[4];
|
||||
for (uint8_t i = 0; i < 4 && i < nonces_to_bruteforce; i++) {
|
||||
bf_test_nonce_temp[i] = bf_test_nonce[best_4[i]];
|
||||
for (uint8_t j = 0; j < 4 && j < nonces_to_bruteforce; j++) {
|
||||
bf_test_nonce_temp[j] = bf_test_nonce[best_4[j]];
|
||||
|
||||
bf_test_nonce_par_temp[i] = bf_test_nonce_par[best_4[i]];
|
||||
bf_test_nonce_2nd_byte_temp[i] = bf_test_nonce_2nd_byte[best_4[i]];
|
||||
bf_test_nonce_par_temp[j] = bf_test_nonce_par[best_4[j]];
|
||||
bf_test_nonce_2nd_byte_temp[j] = bf_test_nonce_2nd_byte[best_4[j]];
|
||||
}
|
||||
for (uint8_t i = 0; i < 4 && i < nonces_to_bruteforce; i++) {
|
||||
bf_test_nonce[i] = bf_test_nonce_temp[i];
|
||||
bf_test_nonce_par[i] = bf_test_nonce_par_temp[i];
|
||||
bf_test_nonce_2nd_byte[i] = bf_test_nonce_2nd_byte_temp[i];
|
||||
for (uint8_t j = 0; j < 4 && j < nonces_to_bruteforce; j++) {
|
||||
bf_test_nonce[j] = bf_test_nonce_temp[j];
|
||||
bf_test_nonce_par[j] = bf_test_nonce_par_temp[j];
|
||||
bf_test_nonce_2nd_byte[j] = bf_test_nonce_2nd_byte_temp[j];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
96
client/luascripts/init_rdv4.lua
Normal file
96
client/luascripts/init_rdv4.lua
Normal file
|
@ -0,0 +1,96 @@
|
|||
local getopt = require('getopt')
|
||||
|
||||
copyright = 'Copyright (c) 2019 IceSQL AB. All rights reserved.'
|
||||
author = 'Christian Herrmann'
|
||||
version = 'v1.0.0'
|
||||
desc = [[
|
||||
This script initialize a Proxmark3 RDV4.0 with
|
||||
- uploading dictionary files to flashmem
|
||||
- configuring the LF T55X7 device settings
|
||||
]]
|
||||
example = [[
|
||||
|
||||
script run init_rdv4
|
||||
]]
|
||||
usage = [[
|
||||
script run init_rdv4 -h
|
||||
|
||||
Arguments:
|
||||
-h : this help
|
||||
]]
|
||||
|
||||
local DEBUG = true
|
||||
---
|
||||
-- A debug printout-function
|
||||
local function dbg(args)
|
||||
if not DEBUG then return end
|
||||
if type(args) == 'table' then
|
||||
local i = 1
|
||||
while args[i] do
|
||||
dbg(args[i])
|
||||
i = i+1
|
||||
end
|
||||
else
|
||||
print('###', args)
|
||||
end
|
||||
end
|
||||
---
|
||||
-- This is only meant to be used when errors occur
|
||||
local function oops(err)
|
||||
print('ERROR:', err)
|
||||
core.clearCommandBuffer()
|
||||
return nil, err
|
||||
end
|
||||
---
|
||||
-- Usage help
|
||||
local function help()
|
||||
print(copyright)
|
||||
print(author)
|
||||
print(version)
|
||||
print(desc)
|
||||
print('Example usage')
|
||||
print(example)
|
||||
print(usage)
|
||||
end
|
||||
---
|
||||
-- The main entry point
|
||||
function main(args)
|
||||
local dash = string.rep('--', 20)
|
||||
|
||||
print( dash )
|
||||
print( dash )
|
||||
print()
|
||||
|
||||
-- Read the parameters
|
||||
for o, a in getopt.getopt(args, 'h') do
|
||||
if o == 'h' then return help() end
|
||||
end
|
||||
|
||||
print('Prepping your Proxmark3 RDV4')
|
||||
|
||||
-- Upload dictionaries
|
||||
print('Uploading dictionaries to RDV4 flashmemory')
|
||||
print(dash)
|
||||
core.console('mem load f mfc_default_keys m')
|
||||
core.console('mem load f t55xx_default_pwds t')
|
||||
core.console('mem load f iclass_default_keys i')
|
||||
print(dash)
|
||||
|
||||
-- T55x7 Device configuration
|
||||
print('Configure T55XX device side to match RDV4')
|
||||
print(dash)
|
||||
core.console('lf t55xx deviceconfig r 0 a 29 b 17 c 15 d 47 e 15 p')
|
||||
core.console('lf t55xx deviceconfig r 1 a 29 b 17 c 18 d 50 e 15 p')
|
||||
core.console('lf t55xx deviceconfig r 2 a 29 b 17 c 18 d 40 e 15 p')
|
||||
core.console('lf t55xx deviceconfig r 3 a 29 b 17 c 15 d 31 e 15 f 47 g 63 p')
|
||||
|
||||
print('')
|
||||
print('')
|
||||
core.console('hw status')
|
||||
print(dash)
|
||||
|
||||
print('all done!')
|
||||
|
||||
end
|
||||
|
||||
main(args)
|
|
@ -181,7 +181,7 @@ int MADCheck(uint8_t *sector0, uint8_t *sector10, bool verbose, bool *haveMAD2)
|
|||
if (!res)
|
||||
res = res2;
|
||||
|
||||
if (verbose & !res2)
|
||||
if (verbose && !res2)
|
||||
PrintAndLogEx(NORMAL, "CRC8-MAD2 OK.");
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "crc16.h"
|
||||
#include "protocols.h"
|
||||
#include "fileutils.h" // searchfile
|
||||
#include "cmdlf.h" // lf_config
|
||||
|
||||
static int returnToLuaWithError(lua_State *L, const char *fmt, ...) {
|
||||
char buffer[200];
|
||||
|
@ -1056,6 +1057,22 @@ static int l_ndefparse(lua_State *L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_remark(lua_State *L) {
|
||||
//Check number of arguments
|
||||
int n = lua_gettop(L);
|
||||
if (n != 1) {
|
||||
return returnToLuaWithError(L, "Only one string allowed");
|
||||
}
|
||||
|
||||
size_t size;
|
||||
// data
|
||||
const char *s = luaL_checklstring(L, 1, &size);
|
||||
|
||||
int res = CmdRem(s);
|
||||
lua_pushinteger(L, res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_searchfile(lua_State *L) {
|
||||
//Check number of arguments
|
||||
int n = lua_gettop(L);
|
||||
|
@ -1141,6 +1158,7 @@ int set_pm3_libraries(lua_State *L) {
|
|||
{"ndefparse", l_ndefparse},
|
||||
{"fast_push_mode", l_fast_push_mode},
|
||||
{"search_file", l_searchfile},
|
||||
{"rem", l_remark},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
// HID card format packing/unpacking routines
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "wiegand_formats.h"
|
||||
#include "commonutil.h"
|
||||
|
||||
bool Pack_H10301(wiegand_card_t *card, wiegand_message_t *packed) {
|
||||
memset(packed, 0, sizeof(wiegand_message_t));
|
||||
|
@ -643,7 +644,7 @@ int HIDFindCardFormat(const char *format) {
|
|||
bool HIDPack(int format_idx, wiegand_card_t *card, wiegand_message_t *packed) {
|
||||
memset(packed, 0, sizeof(wiegand_message_t));
|
||||
|
||||
if (format_idx < 0 || format_idx >= (sizeof(FormatTable) / sizeof(FormatTable[0])))
|
||||
if (format_idx < 0 || format_idx >= ARRAYLEN(FormatTable))
|
||||
return false;
|
||||
|
||||
return FormatTable[format_idx].Pack(card, packed);
|
||||
|
@ -672,16 +673,16 @@ void HIDDisplayUnpackedCard(wiegand_card_t *card, const cardformat_t format) {
|
|||
|
||||
char s[80] = {0};
|
||||
if (format.Fields.hasFacilityCode)
|
||||
snprintf(s, sizeof(s), "FC: %d", card->FacilityCode);
|
||||
snprintf(s, sizeof(s), "FC: %u", card->FacilityCode);
|
||||
|
||||
if (format.Fields.hasCardNumber)
|
||||
snprintf(s + strlen(s), sizeof(s) - strlen(s), " CN: %" PRIu64, card->CardNumber);
|
||||
|
||||
if (format.Fields.hasIssueLevel)
|
||||
snprintf(s + strlen(s), sizeof(s) - strlen(s), " Issue %d", card->IssueLevel);
|
||||
snprintf(s + strlen(s), sizeof(s) - strlen(s), " Issue %u", card->IssueLevel);
|
||||
|
||||
if (format.Fields.hasOEMCode)
|
||||
snprintf(s + strlen(s), sizeof(s) - strlen(s), " OEM: %d", card->OEM);
|
||||
snprintf(s + strlen(s), sizeof(s) - strlen(s), " OEM: %u", card->OEM);
|
||||
|
||||
if (format.Fields.hasParity)
|
||||
snprintf(s + strlen(s), sizeof(s) - strlen(s), " parity: %s", card->ParityValid ? "valid" : "invalid");
|
||||
|
|
|
@ -43,6 +43,6 @@ void HIDListFormats();
|
|||
int HIDFindCardFormat(const char *format);
|
||||
cardformat_t HIDGetCardFormat(int idx);
|
||||
bool HIDPack(int FormatIndex, wiegand_card_t *card, wiegand_message_t *packed);
|
||||
bool HIDTryUnpack(wiegand_message_t *packed, bool ignoreParity);
|
||||
bool HIDTryUnpack(wiegand_message_t *packed, bool ignore_parity);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -124,6 +124,9 @@ recover(uint32_t *o_head, uint32_t *o_tail, uint32_t oks,
|
|||
|
||||
return sl;
|
||||
}
|
||||
|
||||
|
||||
#if !defined(__arm__) || defined(__linux__) || defined(_WIN32) || defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
|
||||
/** lfsr_recovery
|
||||
* recover the state of the lfsr given 32 bits of the keystream
|
||||
* additionally you can use the in parameter to specify the value
|
||||
|
@ -286,6 +289,7 @@ continue2:
|
|||
}
|
||||
return statelist;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** lfsr_rollback_bit
|
||||
* Rollback the shift register in order to get previous states
|
||||
|
@ -465,7 +469,7 @@ static struct Crypto1State *check_pfx_parity(uint32_t prefix, uint32_t rresp, ui
|
|||
return sl + good;
|
||||
}
|
||||
|
||||
|
||||
#if !defined(__arm__) || defined(__linux__) || defined(_WIN32) || defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
|
||||
/** lfsr_common_prefix
|
||||
* Implentation of the common prefix attack.
|
||||
* Requires the 28 bit constant prefix used as reader nonce (pfx)
|
||||
|
@ -504,3 +508,4 @@ out:
|
|||
free(even);
|
||||
return statelist;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -25,23 +25,25 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
struct Crypto1State {uint32_t odd, even;};
|
||||
#if defined(__arm__) && !defined(__linux__) && !defined(_WIN32) && !defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
|
||||
void crypto1_create(struct Crypto1State *s, uint64_t key);
|
||||
#else
|
||||
void crypto1_init(struct Crypto1State *s, uint64_t key);
|
||||
void crypto1_deinit(struct Crypto1State *);
|
||||
#if !defined(__arm__) || defined(__linux__) || defined(_WIN32) || defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
|
||||
struct Crypto1State *crypto1_create(uint64_t key);
|
||||
#endif
|
||||
void crypto1_destroy(struct Crypto1State *);
|
||||
#endif
|
||||
void crypto1_get_lfsr(struct Crypto1State *, uint64_t *);
|
||||
uint8_t crypto1_bit(struct Crypto1State *, uint8_t, int);
|
||||
uint8_t crypto1_byte(struct Crypto1State *, uint8_t, int);
|
||||
uint32_t crypto1_word(struct Crypto1State *, uint32_t, int);
|
||||
uint32_t prng_successor(uint32_t x, uint32_t n);
|
||||
|
||||
#if !defined(__arm__) || defined(__linux__) || defined(_WIN32) || defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
|
||||
struct Crypto1State *lfsr_recovery32(uint32_t ks2, uint32_t in);
|
||||
struct Crypto1State *lfsr_recovery64(uint32_t ks2, uint32_t ks3);
|
||||
uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd);
|
||||
struct Crypto1State *
|
||||
lfsr_common_prefix(uint32_t pfx, uint32_t rr, uint8_t ks[8], uint8_t par[8][8], uint32_t no_par);
|
||||
#endif
|
||||
uint32_t *lfsr_prefix_ks(uint8_t ks[8], int isodd);
|
||||
|
||||
|
||||
uint8_t lfsr_rollback_bit(struct Crypto1State *s, uint32_t in, int fb);
|
||||
|
|
|
@ -25,38 +25,37 @@
|
|||
#define SWAPENDIAN(x)\
|
||||
(x = (x >> 8 & 0xff00ff) | (x & 0xff00ff) << 8, x = x >> 16 | x << 16)
|
||||
|
||||
#if defined(__arm__) && !defined(__linux__) && !defined(_WIN32) && !defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
|
||||
void crypto1_create(struct Crypto1State *s, uint64_t key) {
|
||||
void crypto1_init(struct Crypto1State *state, uint64_t key) {
|
||||
state->odd = 0;
|
||||
state->even = 0;
|
||||
|
||||
int i;
|
||||
|
||||
for (i = 47; s && i > 0; i -= 2) {
|
||||
s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7);
|
||||
s->even = s->even << 1 | BIT(key, i ^ 7);
|
||||
for (i = 47; state && i > 0; i -= 2) {
|
||||
state->odd = state->odd << 1 | BIT(key, (i - 1) ^ 7);
|
||||
state->even = state->even << 1 | BIT(key, i ^ 7);
|
||||
}
|
||||
return;
|
||||
}
|
||||
void crypto1_destroy(struct Crypto1State *state) {
|
||||
|
||||
void crypto1_deinit(struct Crypto1State *state) {
|
||||
state->odd = 0;
|
||||
state->even = 0;
|
||||
}
|
||||
#else
|
||||
|
||||
#if !defined(__arm__) || defined(__linux__) || defined(_WIN32) || defined(__APPLE__) // bare metal ARM Proxmark lacks malloc()/free()
|
||||
struct Crypto1State *crypto1_create(uint64_t key) {
|
||||
struct Crypto1State *s = malloc(sizeof(*s));
|
||||
if (!s) return NULL;
|
||||
|
||||
s->odd = s->even = 0;
|
||||
|
||||
int i;
|
||||
for (i = 47; i > 0; i -= 2) {
|
||||
s->odd = s->odd << 1 | BIT(key, (i - 1) ^ 7);
|
||||
s->even = s->even << 1 | BIT(key, i ^ 7);
|
||||
}
|
||||
return s;
|
||||
struct Crypto1State *state = malloc(sizeof(*state));
|
||||
if (!state) return NULL;
|
||||
crypto1_init(state, key);
|
||||
return state;
|
||||
}
|
||||
|
||||
void crypto1_destroy(struct Crypto1State *state) {
|
||||
free(state);
|
||||
}
|
||||
#endif
|
||||
|
||||
void crypto1_get_lfsr(struct Crypto1State *state, uint64_t *lfsr) {
|
||||
int i;
|
||||
for (*lfsr = 0, i = 23; i >= 0; --i) {
|
||||
|
|
144
doc/clocks.md
Normal file
144
doc/clocks.md
Normal file
|
@ -0,0 +1,144 @@
|
|||
## Slow clock
|
||||
|
||||
~32kHz internal RC clock
|
||||
|
||||
Can be between 22 and 42 kHz
|
||||
|
||||
## Main Oscillator / MAINCK
|
||||
|
||||
cf `PMC_MOR` register
|
||||
|
||||
16 MHz, based on external Xtal
|
||||
|
||||
## PLL clock
|
||||
|
||||
cf `PMC_PLLR` register
|
||||
|
||||
96 MHz (MAINCK * 12 / 2)
|
||||
|
||||
## Master Clock MCK, Processor Clock PCK, USB clock UDPCK
|
||||
|
||||
cf `common_arm/clocks.c`
|
||||
|
||||
cf `PMC_MCKR` and `PMC_SCER` registers
|
||||
|
||||
* MCK starts with RC slow clock (22 to 42 kHz).
|
||||
* Then MCK configured from PLL: 48 MHz (PLL / 2)
|
||||
|
||||
cf `bootrom.c`:
|
||||
|
||||
PCK can be disabled to enter idle mode, but on Proxmark3 it's always on, so PCK is also 48 MHz.
|
||||
|
||||
USB need to be clocked at 48 MHz from the PLL, so PLL / 2 (cf `CKGR_PLLR`).
|
||||
|
||||
|
||||
## Peripheral clocks
|
||||
|
||||
cf `bootrom.c`:
|
||||
|
||||
Distribute MCK/PCK? clock to Parallel I/O controller, ADC, SPI, Synchronous Serial controller, PWM controller, USB.
|
||||
|
||||
cf `appmain.c`
|
||||
|
||||
Activate PCK0 pin as clock output, based on PLL / 4 = 24 MHz, for the FPGA.
|
||||
|
||||
## 1 kHz RTC: TickCount functions
|
||||
|
||||
cf `armsrc/ticks.c`
|
||||
|
||||
cf `PMC_MCFR` and `RTTC_RTMR` registers for configuration, `RTTC_RTVR` register for reading value.
|
||||
|
||||
Characteristics:
|
||||
|
||||
* 1 kHz, 32b (49 days), if used with 16b: 65s
|
||||
* Configured at boot (or TIA) with `StartTickCount()`
|
||||
* Time events with `GetTickCount()`/`GetTickCountDeltaDelta()`, see example
|
||||
* Coarse, based on the ~32kHz RC slow clock with some adjustment factor computed by TIA
|
||||
* Maybe 2.5% error, can increase if temperature conditions change and no TIA is recomputed
|
||||
* If TimingIntervalAcquisition() is called later, StartTickCount() is called again and RTC is reset
|
||||
|
||||
Usage:
|
||||
|
||||
```
|
||||
uint32_t ti = GetTickCount();
|
||||
...do stuff...
|
||||
uint32_t delta = GetTickCountDelta(ti);
|
||||
```
|
||||
|
||||
Current usages:
|
||||
|
||||
* cheap random for nonces, e.g. `prng_successor(GetTickCount(), 32)`
|
||||
* rough timing of some operations, only for informative purposes
|
||||
* timeouts
|
||||
* USB connection speed measure
|
||||
|
||||
## Occasional PWM timer
|
||||
|
||||
* `void SpinDelayUs(int us)`
|
||||
* `void SpinDelay(int ms)` based on SpinDelayUs
|
||||
|
||||
Busy wait based on 46.875 kHz PWM Channel 0, 21.3 us precision
|
||||
|
||||
WARNING: timer can't measure more than 1.39 s
|
||||
|
||||
|
||||
## Occasional TC0+TC1 / CountUS functions
|
||||
|
||||
cf `armsrc/ticks.c`
|
||||
|
||||
About 1 us precision
|
||||
|
||||
* `void StartCountUS(void)`
|
||||
* `uint32_t RAMFUNC GetCountUS(void)`
|
||||
|
||||
Use two chainer timers TC0 and TC1.
|
||||
TC0 runs at 1.5 MHz and TC1 is clocked when TC0 reaches 0xC000.
|
||||
|
||||
Maximal value: 0x7fffffff = 2147 s
|
||||
|
||||
Can't be used at the same time as CountSspClk or Ticks functions.
|
||||
|
||||
## Occasional TC0+TC1 SSP_CLK from FPGA / CountSspClk functions
|
||||
|
||||
cf `armsrc/ticks.c`
|
||||
|
||||
About 1 cycle of 13.56 MHz? precision
|
||||
|
||||
* `void StartCountSspClk(void)`
|
||||
* `void ResetSspClk(void)`
|
||||
* `uint32_t RAMFUNC GetCountSspClk(void)`
|
||||
* `uint32_t RAMFUNC GetCountSspClkDelta(uint32_t start)` <= **TODO** could be used more often
|
||||
|
||||
Use two chainer timers TC0 and TC1.
|
||||
TC0 runs at SSP_CLK from FPGA (13.56 MHz?) and TC1 is clocked when TC0 loops.
|
||||
|
||||
Usage:
|
||||
|
||||
* for iso14443 commands to count field cycles
|
||||
* Also usable with FPGA in LF mode ?? cf `armsrc/legicrfsim.c` SSP Clock is clocked by the FPGA at 212 kHz (subcarrier frequency)
|
||||
|
||||
Can't be used at the same time as CountUS or Ticks functions.
|
||||
|
||||
## Occasional TC0+TC1 / Ticks functions
|
||||
|
||||
cf `armsrc/ticks.c`
|
||||
|
||||
1.5 MHz
|
||||
|
||||
* `void StartTicks(void)`
|
||||
* `uint32_t GetTicks(void)` <= **TODO** why no GetTicksDelta ?
|
||||
* `void WaitTicks(uint32_t ticks)`
|
||||
* `void WaitUS(uint32_t us)`
|
||||
* `void WaitMS(uint32_t ms)`
|
||||
* `void StopTicks(void)` <= **TODO** why a stop for this timer and not for CountUS / CountSspClk ?
|
||||
|
||||
Use two chainer timers TC0 and TC1.
|
||||
TC0 runs at 1.5 MHz and TC1 is clocked when TC0 loops.
|
||||
|
||||
Maximal value: 0xffffffff = 2863 s (but don't use high value with WaitTicks else you'll trigger WDT)
|
||||
|
||||
Usage:
|
||||
|
||||
* Timer for bitbanging, or LF stuff when you need a very precise timer
|
||||
|
||||
Can't be used at the same time as CountUS or CountSspClk functions.
|
|
@ -34,7 +34,7 @@ typedef struct {
|
|||
uint8_t signature[32];
|
||||
uint8_t counter_tearing[3][4]; // 3 bytes counter, 1 byte tearing flag
|
||||
uint8_t data[1024];
|
||||
} mfu_dump_t;
|
||||
} PACKED mfu_dump_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ISO 14443A
|
||||
|
@ -69,7 +69,7 @@ typedef struct {
|
|||
uint16_t modulation_n;
|
||||
uint32_t ProxToAirDuration;
|
||||
uint8_t par; // enough for precalculated parity of 8 Byte responses
|
||||
} tag_response_info_t;
|
||||
} PACKED tag_response_info_t;
|
||||
//-----------------------------------------------------------------------------
|
||||
// ISO 14443B
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -79,7 +79,7 @@ typedef struct {
|
|||
uint8_t atqb[7];
|
||||
uint8_t chipid;
|
||||
uint8_t cid;
|
||||
} __attribute__((__packed__)) iso14b_card_select_t;
|
||||
} PACKED iso14b_card_select_t;
|
||||
|
||||
typedef enum ISO14B_COMMAND {
|
||||
ISO14B_CONNECT = (1 << 0),
|
||||
|
@ -121,7 +121,7 @@ typedef struct {
|
|||
FIRST,
|
||||
SECOND,
|
||||
} state;
|
||||
} nonces_t;
|
||||
} PACKED nonces_t;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// ISO 7618 Smart Card
|
||||
|
|
|
@ -27,4 +27,5 @@ HID-weak-fob-11647.pm3: HID 32bit Prox Card#: 11647. very weak tag/read but jus
|
|||
visa2000.pm3: VISA2000 ASK/MAN RF/64, Card: 480518
|
||||
securakey-64169.pm3 Securakey Tag BitLen: 26, Card ID: 64169, FC: 0x35
|
||||
|
||||
motorola_0437_00072.pm3 - Motorola Grey clamshell card, old. (RAW: A0000000E308C0C1)
|
||||
motorola_0437_00072.pm3: Motorola Grey clamshell card, old. (RAW: A0000000E308C0C1)
|
||||
verichip_1022000000084146.pm3: VeriChip, epoxy encased glasschip (ID: 1022-00000000084146)
|
||||
|
|
39999
traces/verichip_1022000000084146.pm3
Normal file
39999
traces/verichip_1022000000084146.pm3
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue