Merge pull request from RfidResearchGroup/master

Update
This commit is contained in:
mwalker33 2019-10-23 22:34:34 +11:00 committed by GitHub
commit 6e6b46c87a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
45 changed files with 40765 additions and 260 deletions

View file

@ -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);
}
}

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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};

View file

@ -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

View file

@ -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`.

View file

@ -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

View file

@ -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);

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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;
}
}

View file

@ -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};

View file

@ -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

View file

@ -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;

View file

@ -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);
}

View file

@ -16,4 +16,6 @@
int CmdHFFelica(const char *Cmd);
int readFelicaUid(bool verbose);
int dump();
#endif

View file

@ -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) {

View file

@ -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;

View file

@ -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;

View file

@ -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)

View file

@ -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);

View file

@ -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... }"},

View file

@ -15,6 +15,7 @@
#include "cmdparser.h" // command_t
int CommandReceived(char *Cmd);
int CmdRem(const char *Cmd);
command_t *getTopLevelCommandTable(void);
#endif

View file

@ -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 {

View file

@ -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;

View file

@ -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;
}

View file

@ -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)) {

View file

@ -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)
);

View file

@ -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];
}
}

View 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)

View file

@ -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.");
}

View file

@ -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}
};

View file

@ -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");

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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
View 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.

View file

@ -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

View file

@ -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)

File diff suppressed because it is too large Load diff