mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
Merge branch 'master' of https://github.com/RfidResearchGroup/proxmark3 into RfidResearchGroup-master
This commit is contained in:
commit
f0ae164fdf
68 changed files with 40759 additions and 306 deletions
36
.coverity.conf.sample
Normal file
36
.coverity.conf.sample
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
COVLOGIN=myemail@corp.com
|
||||||
|
COVTOKEN=aAbBcCdDeEfFgGhHiIjJkK
|
||||||
|
# Toolchain available at https://scan.coverity.com/download
|
||||||
|
COVBINDIR="/opt/cov-analysis-linux64-2019.03/bin"
|
||||||
|
# Nickname included in scan description:
|
||||||
|
NICKNAME=myself
|
||||||
|
|
||||||
|
COVDIR=cov-int
|
||||||
|
COVBUILD="cov-build --dir $COVDIR"
|
||||||
|
|
||||||
|
# Depending if your kernel > 4.8.x, you might need to activate this to run Coverity executables
|
||||||
|
# (but latest tools with kernel 5.2 run fine)
|
||||||
|
#sysctl vsyscall=emulate
|
||||||
|
|
||||||
|
export PATH="$PATH:$COVBINDIR"
|
||||||
|
|
||||||
|
function pre_build_hook() {
|
||||||
|
# tmp dir will be /tmp/cov-$username/
|
||||||
|
# It's the good place if you need to redirect to elsewhere with a symlink
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function post_build_hook() {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function pre_submit_hook() {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
function post_submit_hook() {
|
||||||
|
# Clean up build folders?
|
||||||
|
rm -rf "$COVDIR"
|
||||||
|
echo "Coverity build cleaned"
|
||||||
|
return 0
|
||||||
|
}
|
10
README.md
10
README.md
|
@ -5,10 +5,9 @@ This repo is based on iceman fork for Proxmark3. It supports other Proxmark3 pl
|
||||||
It is dedicated to bringing the most out of the new features for Proxmark3 RDV4.0 new hardware and design.
|
It is dedicated to bringing the most out of the new features for Proxmark3 RDV4.0 new hardware and design.
|
||||||
|
|
||||||
|
|
||||||
| Releases | Linux & OSX CI | Windows CI |
|
| Releases | Linux & OSX CI | Windows CI | Coverity |
|
||||||
| ------------------- |:-------------------:| -------------------:|
|
| ------------------- |:-------------------:| -------------------:| -------------------:|
|
||||||
| [](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [](https://travis-ci.org/RfidResearchGroup/proxmark3) | [](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) |
|
| [](https://github.com/RfidResearchGroup/proxmark3/releases/latest) | [](https://travis-ci.org/RfidResearchGroup/proxmark3) | [](https://ci.appveyor.com/project/RfidResearchGroup/proxmark3/branch/master) | [](https://scan.coverity.com/projects/proxmark3-rrg-iceman-repo)|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# PROXMARK INSTALLATION AND OVERVIEW
|
# PROXMARK INSTALLATION AND OVERVIEW
|
||||||
|
@ -94,8 +93,9 @@ It's needed to have a good USB cable to connect Proxmark3 to USB. If you have st
|
||||||
|
|
||||||
## The end
|
## The end
|
||||||
|
|
||||||
- [@herrmann1001](https://mobile.twitter.com/herrmann1001) July 2018
|
- July 2018 [@herrmann1001](https://mobile.twitter.com/herrmann1001)
|
||||||
- updated Feb 2019 [@5w0rdfish](https://mobile.twitter.com/5w0rdFish)
|
- updated Feb 2019 [@5w0rdfish](https://mobile.twitter.com/5w0rdFish)
|
||||||
|
- updated 2019 [@doegox](https://mobile.twitter.com/doegox)
|
||||||
|
|
||||||
# Donations
|
# Donations
|
||||||
|
|
||||||
|
|
|
@ -804,6 +804,10 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
T55xxWriteBlock(packet->data.asBytes);
|
T55xxWriteBlock(packet->data.asBytes);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CMD_LF_T55XX_DANGERRAW: {
|
||||||
|
T55xxDangerousRawTest(packet->data.asBytes);
|
||||||
|
break;
|
||||||
|
}
|
||||||
case CMD_LF_T55XX_WAKEUP: {
|
case CMD_LF_T55XX_WAKEUP: {
|
||||||
struct p {
|
struct p {
|
||||||
uint32_t password;
|
uint32_t password;
|
||||||
|
@ -1564,9 +1568,10 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
BigBuf_Clear_ext(false);
|
BigBuf_Clear_ext(false);
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
}
|
}
|
||||||
|
uint16_t offset = MIN(BIGBUF_SIZE - PM3_CMD_DATA_SIZE - 3, payload->offset);
|
||||||
|
|
||||||
uint8_t *mem = BigBuf_get_addr();
|
uint8_t *mem = BigBuf_get_addr();
|
||||||
memcpy(mem + payload->offset, &payload->data, PM3_CMD_DATA_SIZE - 3);
|
memcpy(mem + offset, &payload->data, PM3_CMD_DATA_SIZE - 3);
|
||||||
reply_ng(CMD_LF_UPLOAD_SIM_SAMPLES, PM3_SUCCESS, NULL, 0);
|
reply_ng(CMD_LF_UPLOAD_SIM_SAMPLES, PM3_SUCCESS, NULL, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1678,33 +1683,33 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
}
|
}
|
||||||
case CMD_SPIFFS_RENAME: {
|
case CMD_SPIFFS_RENAME: {
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
uint8_t srcfilename[32];
|
uint8_t src[32];
|
||||||
uint8_t destfilename[32];
|
uint8_t dest[32];
|
||||||
uint8_t *pfilename = packet->data.asBytes;
|
uint8_t *pfilename = packet->data.asBytes;
|
||||||
char *token;
|
char *token;
|
||||||
token = strtok((char *)pfilename, ",");
|
token = strtok((char *)pfilename, ",");
|
||||||
strcpy((char *)srcfilename, token);
|
strncpy((char *)src, token, sizeof(src) - 1);
|
||||||
token = strtok(NULL, ",");
|
token = strtok(NULL, ",");
|
||||||
strcpy((char *)destfilename, token);
|
strncpy((char *)dest, token, sizeof(dest) - 1);
|
||||||
if (DBGLEVEL > 1) Dbprintf("> Filename received as source for spiffs RENAME : %s", srcfilename);
|
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", destfilename);
|
if (DBGLEVEL > 1) Dbprintf("> Filename received as destination for spiffs RENAME : %s", dest);
|
||||||
rdv40_spiffs_rename((char *) srcfilename, (char *)destfilename, RDV40_SPIFFS_SAFETY_SAFE);
|
rdv40_spiffs_rename((char *) src, (char *)dest, RDV40_SPIFFS_SAFETY_SAFE);
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_SPIFFS_COPY: {
|
case CMD_SPIFFS_COPY: {
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
uint8_t srcfilename[32];
|
uint8_t src[32];
|
||||||
uint8_t destfilename[32];
|
uint8_t dest[32];
|
||||||
uint8_t *pfilename = packet->data.asBytes;
|
uint8_t *pfilename = packet->data.asBytes;
|
||||||
char *token;
|
char *token;
|
||||||
token = strtok((char *)pfilename, ",");
|
token = strtok((char *)pfilename, ",");
|
||||||
strcpy((char *)srcfilename, token);
|
strncpy((char *)src, token, sizeof(src) - 1);
|
||||||
token = strtok(NULL, ",");
|
token = strtok(NULL, ",");
|
||||||
strcpy((char *)destfilename, token);
|
strncpy((char *)dest, token, sizeof(dest) - 1);
|
||||||
if (DBGLEVEL > 1) Dbprintf("> Filename received as source for spiffs COPY : %s", srcfilename);
|
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", destfilename);
|
if (DBGLEVEL > 1) Dbprintf("> Filename received as destination for spiffs COPY : %s", dest);
|
||||||
rdv40_spiffs_copy((char *) srcfilename, (char *)destfilename, RDV40_SPIFFS_SAFETY_SAFE);
|
rdv40_spiffs_copy((char *) src, (char *)dest, RDV40_SPIFFS_SAFETY_SAFE);
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,42 +22,42 @@
|
||||||
// Debug print functions, to go out over USB, to the usual PC-side client.
|
// Debug print functions, to go out over USB, to the usual PC-side client.
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
void DbpStringEx(uint32_t flags, char *str) {
|
void DbpStringEx(uint32_t flags, char *src, size_t srclen) {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
struct {
|
struct {
|
||||||
uint16_t flag;
|
uint16_t flag;
|
||||||
uint8_t buf[PM3_CMD_DATA_SIZE - sizeof(uint16_t)];
|
uint8_t buf[PM3_CMD_DATA_SIZE - sizeof(uint16_t)];
|
||||||
} PACKED data;
|
} PACKED data;
|
||||||
data.flag = flags;
|
data.flag = flags;
|
||||||
uint16_t len = MIN(strlen(str), sizeof(data.buf));
|
uint16_t len = MIN(srclen, sizeof(data.buf));
|
||||||
memcpy(data.buf, str, len);
|
memcpy(data.buf, src, len);
|
||||||
reply_ng(CMD_DEBUG_PRINT_STRING, PM3_SUCCESS, (uint8_t *)&data, sizeof(data.flag) + len);
|
reply_ng(CMD_DEBUG_PRINT_STRING, PM3_SUCCESS, (uint8_t *)&data, sizeof(data.flag) + len);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DbpString(char *str) {
|
void DbpString(char *str) {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
DbpStringEx(FLAG_LOG, str);
|
DbpStringEx(FLAG_LOG, str, strlen(str));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void DbprintfEx(uint32_t flags, const char *fmt, ...) {
|
void DbprintfEx(uint32_t flags, const char *fmt, ...) {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
// should probably limit size here; oh well, let's just use a big buffer
|
// should probably limit size here; oh well, let's just use a big buffer
|
||||||
char output_string[128] = {0x00};
|
char s[PM3_CMD_DATA_SIZE] = {0x00};
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
kvsprintf(fmt, output_string, 10, ap);
|
kvsprintf(fmt, s, 10, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
|
||||||
DbpStringEx(flags, output_string);
|
DbpStringEx(flags, s, strlen(s));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dbprintf(const char *fmt, ...) {
|
void Dbprintf(const char *fmt, ...) {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
// should probably limit size here; oh well, let's just use a big buffer
|
// should probably limit size here; oh well, let's just use a big buffer
|
||||||
char output_string[128] = {0x00};
|
char output_string[PM3_CMD_DATA_SIZE] = {0x00};
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
|
|
||||||
|
|
||||||
void DbpString(char *str);
|
void DbpString(char *str);
|
||||||
void DbpStringEx(uint32_t flags, char *str);
|
void DbpStringEx(uint32_t flags, char *src, size_t srclen);
|
||||||
void Dbprintf(const char *fmt, ...);
|
void Dbprintf(const char *fmt, ...);
|
||||||
void DbprintfEx(uint32_t flags, const char *fmt, ...);
|
void DbprintfEx(uint32_t flags, const char *fmt, ...);
|
||||||
void Dbhexdump(int len, uint8_t *d, bool bAsci);
|
void Dbhexdump(int len, uint8_t *d, bool bAsci);
|
||||||
|
|
|
@ -738,7 +738,7 @@ void SniffHitag(void) {
|
||||||
// Set up eavesdropping mode, frequency divisor which will drive the FPGA
|
// Set up eavesdropping mode, frequency divisor which will drive the FPGA
|
||||||
// and analog mux selection.
|
// and analog mux selection.
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_TOGGLE_MODE);
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95);
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125);
|
||||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||||
|
|
||||||
// Configure output pin that is connected to the FPGA (for modulating)
|
// Configure output pin that is connected to the FPGA (for modulating)
|
||||||
|
@ -967,7 +967,7 @@ void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data) {
|
||||||
// Set up simulator mode, frequency divisor which will drive the FPGA
|
// Set up simulator mode, frequency divisor which will drive the FPGA
|
||||||
// and analog mux selection.
|
// and analog mux selection.
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz
|
||||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||||
|
|
||||||
// Configure output pin that is connected to the FPGA (for modulating)
|
// Configure output pin that is connected to the FPGA (for modulating)
|
||||||
|
@ -1173,7 +1173,7 @@ void ReaderHitag(hitag_function htf, hitag_data *htd) {
|
||||||
|
|
||||||
// Set fpga in edge detect with reader field, we can modulate as reader now
|
// Set fpga in edge detect with reader field, we can modulate as reader now
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz
|
||||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||||
|
|
||||||
// Configure output and enable pin that is connected to the FPGA (for modulating)
|
// Configure output and enable pin that is connected to the FPGA (for modulating)
|
||||||
|
@ -1444,7 +1444,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
|
||||||
|
|
||||||
// Set fpga in edge detect with reader field, we can modulate as reader now
|
// Set fpga in edge detect with reader field, we can modulate as reader now
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz
|
||||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||||
|
|
||||||
// Disable modulation at default, which means enable the field
|
// Disable modulation at default, which means enable the field
|
||||||
|
|
|
@ -994,7 +994,7 @@ void SimulateHitagSTag(bool tag_mem_supplied, uint8_t *data) {
|
||||||
// and analog mux selection.
|
// and analog mux selection.
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz
|
||||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||||
|
|
||||||
// Configure output pin that is connected to the FPGA (for modulating)
|
// Configure output pin that is connected to the FPGA (for modulating)
|
||||||
|
@ -1193,7 +1193,7 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) {
|
||||||
|
|
||||||
// Set fpga in edge detect with reader field, we can modulate as reader now
|
// Set fpga in edge detect with reader field, we can modulate as reader now
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz
|
||||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||||
|
|
||||||
// Configure output and enable pin that is connected to the FPGA (for modulating)
|
// Configure output and enable pin that is connected to the FPGA (for modulating)
|
||||||
|
@ -1528,7 +1528,7 @@ void WritePageHitagS(hitag_function htf, hitag_data *htd, int page) {
|
||||||
|
|
||||||
// Set fpga in edge detect with reader field, we can modulate as reader now
|
// Set fpga in edge detect with reader field, we can modulate as reader now
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz
|
||||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||||
|
|
||||||
// Disable modulation at default, which means enable the field
|
// Disable modulation at default, which means enable the field
|
||||||
|
@ -1789,7 +1789,7 @@ void check_challenges(bool file_given, uint8_t *data) {
|
||||||
|
|
||||||
// Set fpga in edge detect with reader field, we can modulate as reader now
|
// Set fpga in edge detect with reader field, we can modulate as reader now
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT | FPGA_LF_EDGE_DETECT_READER_FIELD);
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz
|
||||||
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
|
||||||
|
|
||||||
// Disable modulation at default, which means enable the field
|
// Disable modulation at default, which means enable the field
|
||||||
|
|
|
@ -1765,7 +1765,7 @@ void CodeIClassCommand(const uint8_t *cmd, int len) {
|
||||||
for (k = 0; k < 4; k++) {
|
for (k = 0; k < 4; k++) {
|
||||||
|
|
||||||
if (k == (b & 3))
|
if (k == (b & 3))
|
||||||
ToSend[++ToSendMax] = 0xf0;
|
ToSend[++ToSendMax] = 0x0f;
|
||||||
else
|
else
|
||||||
ToSend[++ToSendMax] = 0x00;
|
ToSend[++ToSendMax] = 0x00;
|
||||||
}
|
}
|
||||||
|
|
|
@ -937,10 +937,9 @@ void BruteforceIso15693Afi(uint32_t speed) {
|
||||||
|
|
||||||
data[0] = ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_INVENTORY | ISO15_REQINV_SLOT1;
|
data[0] = ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_INVENTORY | ISO15_REQINV_SLOT1;
|
||||||
data[1] = ISO15_CMD_INVENTORY;
|
data[1] = ISO15_CMD_INVENTORY;
|
||||||
data[2] = 0; // mask length
|
data[2] = 0; // AFI
|
||||||
AddCrc15(data, 3);
|
AddCrc15(data, 3);
|
||||||
datalen += 2;
|
datalen = 5;
|
||||||
|
|
||||||
recvlen = SendDataTag(data, datalen, false, speed, buf);
|
recvlen = SendDataTag(data, datalen, false, speed, buf);
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
@ -955,10 +954,12 @@ void BruteforceIso15693Afi(uint32_t speed) {
|
||||||
data[2] = 0; // AFI
|
data[2] = 0; // AFI
|
||||||
data[3] = 0; // mask length
|
data[3] = 0; // mask length
|
||||||
|
|
||||||
|
// 4 + 2crc
|
||||||
|
datalen = 6;
|
||||||
|
|
||||||
for (uint16_t i = 0; i < 256; i++) {
|
for (uint16_t i = 0; i < 256; i++) {
|
||||||
data[2] = i & 0xFF;
|
data[2] = i & 0xFF;
|
||||||
AddCrc15(data, 4);
|
AddCrc15(data, 4);
|
||||||
datalen += 2;
|
|
||||||
recvlen = SendDataTag(data, datalen, false, speed, buf);
|
recvlen = SendDataTag(data, datalen, false, speed, buf);
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
if (recvlen >= 12) {
|
if (recvlen >= 12) {
|
||||||
|
|
|
@ -503,7 +503,7 @@ void ReadTItag(void) {
|
||||||
|
|
||||||
// TI tags charge at 134.2kHz
|
// TI tags charge at 134.2kHz
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8kHz
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_134); //~134kHz
|
||||||
|
|
||||||
// Place FPGA in passthrough mode, in this mode the CROSS_LO line
|
// Place FPGA in passthrough mode, in this mode the CROSS_LO line
|
||||||
// connects to SSP_DIN and the SSP_DOUT logic level controls
|
// connects to SSP_DIN and the SSP_DOUT logic level controls
|
||||||
|
@ -730,7 +730,7 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc) {
|
||||||
Dbprintf("Writing to tag: %x%08x, crc=%x", idhi, idlo, crc);
|
Dbprintf("Writing to tag: %x%08x, crc=%x", idhi, idlo, crc);
|
||||||
|
|
||||||
// TI tags charge at 134.2kHz
|
// TI tags charge at 134.2kHz
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8kHz
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_134); //~134kHz
|
||||||
// Place FPGA in passthrough mode, in this mode the CROSS_LO line
|
// Place FPGA in passthrough mode, in this mode the CROSS_LO line
|
||||||
// connects to SSP_DIN and the SSP_DOUT logic level controls
|
// connects to SSP_DIN and the SSP_DOUT logic level controls
|
||||||
// whether we're modulating the antenna (high)
|
// whether we're modulating the antenna (high)
|
||||||
|
@ -803,9 +803,9 @@ void SimulateTagLowFrequencyEx(int period, int gap, bool ledcontrol, int numcycl
|
||||||
sample_config *sc = getSamplingConfig();
|
sample_config *sc = getSamplingConfig();
|
||||||
|
|
||||||
if ((sc->divisor == 1) || (sc->divisor < 0) || (sc->divisor > 255))
|
if ((sc->divisor == 1) || (sc->divisor < 0) || (sc->divisor > 255))
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8kHz
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_134); //~134kHz
|
||||||
else if (sc->divisor == 0)
|
else if (sc->divisor == 0)
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz
|
||||||
else
|
else
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor);
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor);
|
||||||
|
|
||||||
|
@ -1145,7 +1145,7 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
|
||||||
uint32_t hi2 = 0, hi = 0, lo = 0;
|
uint32_t hi2 = 0, hi = 0, lo = 0;
|
||||||
int dummyIdx = 0;
|
int dummyIdx = 0;
|
||||||
// Configure to go in 125kHz listen mode
|
// Configure to go in 125kHz listen mode
|
||||||
LFSetupFPGAForADC(95, true);
|
LFSetupFPGAForADC(LF_DIVISOR_125, true);
|
||||||
|
|
||||||
//clear read buffer
|
//clear read buffer
|
||||||
BigBuf_Clear_keep_EM();
|
BigBuf_Clear_keep_EM();
|
||||||
|
@ -1242,7 +1242,7 @@ void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
|
||||||
|
|
||||||
BigBuf_Clear_keep_EM();
|
BigBuf_Clear_keep_EM();
|
||||||
|
|
||||||
LFSetupFPGAForADC(95, true);
|
LFSetupFPGAForADC(LF_DIVISOR_125, true);
|
||||||
|
|
||||||
while (!BUTTON_PRESS() && !data_available()) {
|
while (!BUTTON_PRESS() && !data_available()) {
|
||||||
|
|
||||||
|
@ -1334,7 +1334,7 @@ void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol)
|
||||||
|
|
||||||
BigBuf_Clear_keep_EM();
|
BigBuf_Clear_keep_EM();
|
||||||
|
|
||||||
LFSetupFPGAForADC(95, true);
|
LFSetupFPGAForADC(LF_DIVISOR_125, true);
|
||||||
|
|
||||||
while (!BUTTON_PRESS() && !data_available()) {
|
while (!BUTTON_PRESS() && !data_available()) {
|
||||||
|
|
||||||
|
@ -1400,7 +1400,7 @@ void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) {
|
||||||
BigBuf_Clear_keep_EM();
|
BigBuf_Clear_keep_EM();
|
||||||
|
|
||||||
// Configure to go in 125kHz listen mode
|
// Configure to go in 125kHz listen mode
|
||||||
LFSetupFPGAForADC(95, true);
|
LFSetupFPGAForADC(LF_DIVISOR_125, true);
|
||||||
|
|
||||||
while (!BUTTON_PRESS() && !data_available()) {
|
while (!BUTTON_PRESS() && !data_available()) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
@ -1651,7 +1651,7 @@ void T55xx_SendCMD(uint32_t data, uint32_t pwd, uint16_t arg) {
|
||||||
|
|
||||||
// Send Bits to T55xx
|
// Send Bits to T55xx
|
||||||
// Set up FPGA, 125kHz
|
// Set up FPGA, 125kHz
|
||||||
LFSetupFPGAForADC(95, true);
|
LFSetupFPGAForADC(LF_DIVISOR_125, true);
|
||||||
|
|
||||||
// make sure tag is fully powered up...
|
// make sure tag is fully powered up...
|
||||||
WaitMS(start_wait);
|
WaitMS(start_wait);
|
||||||
|
@ -1703,6 +1703,45 @@ void T55xxResetRead(uint8_t flags) {
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void T55xxDangerousRawTest(uint8_t *data) {
|
||||||
|
// supports only default downlink mode
|
||||||
|
t55xx_test_block_t *c = (t55xx_test_block_t *)data;
|
||||||
|
|
||||||
|
uint8_t start_wait = 4;
|
||||||
|
uint8_t bs[128/8];
|
||||||
|
memset(bs, 0x00, sizeof(bs));
|
||||||
|
uint8_t len = 0;
|
||||||
|
if (c->bitlen == 0 || c->bitlen > 128 || c->time == 0)
|
||||||
|
reply_ng(CMD_LF_T55XX_DANGERRAW, PM3_EINVARG, NULL, 0);
|
||||||
|
for (uint8_t i=0; i<c->bitlen; i++)
|
||||||
|
len = T55xx_SetBits(bs, len, c->data[i], 1, sizeof(bs));
|
||||||
|
|
||||||
|
if (DBGLEVEL > 1) {
|
||||||
|
Dbprintf("LEN %i, TIMING %i", len, c->time);
|
||||||
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
|
uint8_t sendbits = (bs[BITSTREAM_BYTE(i)] >> BITSTREAM_BIT(i));
|
||||||
|
Dbprintf("%02i: %i", i, sendbits & 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LED_A_ON();
|
||||||
|
LFSetupFPGAForADC(LF_DIVISOR_125, true);
|
||||||
|
// make sure tag is fully powered up...
|
||||||
|
WaitMS(start_wait);
|
||||||
|
// Trigger T55x7 in mode.
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
WaitUS(T55xx_Timing.m[0].start_gap);
|
||||||
|
uint8_t sendbits;
|
||||||
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
|
sendbits = (bs[BITSTREAM_BYTE(i)] >> BITSTREAM_BIT(i));
|
||||||
|
T55xxWriteBit(sendbits & 1, 0);
|
||||||
|
}
|
||||||
|
TurnReadLFOn(c->time);
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
reply_ng(CMD_LF_T55XX_DANGERRAW, PM3_SUCCESS, NULL, 0);
|
||||||
|
LED_A_OFF();
|
||||||
|
}
|
||||||
|
|
||||||
// Write one card block in page 0, no lock
|
// Write one card block in page 0, no lock
|
||||||
//void T55xxWriteBlockExt(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags) {
|
//void T55xxWriteBlockExt(uint32_t data, uint8_t blockno, uint32_t pwd, uint8_t flags) {
|
||||||
void T55xxWriteBlock(uint8_t *data) {
|
void T55xxWriteBlock(uint8_t *data) {
|
||||||
|
@ -2274,7 +2313,7 @@ void SendForward(uint8_t fwd_bit_count) {
|
||||||
fwd_bit_sz = fwd_bit_count;
|
fwd_bit_sz = fwd_bit_count;
|
||||||
|
|
||||||
// Set up FPGA, 125kHz or 95 divisor
|
// Set up FPGA, 125kHz or 95 divisor
|
||||||
LFSetupFPGAForADC(95, true);
|
LFSetupFPGAForADC(LF_DIVISOR_125, true);
|
||||||
|
|
||||||
// force 1st mod pulse (start gap must be longer for 4305)
|
// force 1st mod pulse (start gap must be longer for 4305)
|
||||||
fwd_bit_sz--; //prepare next bit modulation
|
fwd_bit_sz--; //prepare next bit modulation
|
||||||
|
@ -2372,18 +2411,37 @@ void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Reading a COTAG.
|
Reading COTAG.
|
||||||
|
|
||||||
COTAG needs the reader to send a startsequence and the card has an extreme slow datarate.
|
COTAG needs the reader to send a startsequence and the card has an extreme slow datarate.
|
||||||
because of this, we can "sample" the data signal but we interpreate it to Manchester direct.
|
because of this, we can "sample" the data signal but we interpreate it to Manchester direct.
|
||||||
|
|
||||||
READER START SEQUENCE:
|
This behavior looks very similar to old ancient Motorola Flexpass
|
||||||
burst 800 us, gap 2.2 msecs
|
|
||||||
burst 3.6 msecs gap 2.2 msecs
|
-----------------------------------------------------------------------
|
||||||
burst 800 us gap 2.2 msecs
|
According to patent:
|
||||||
pulse 3.6 msecs
|
Operating freq
|
||||||
|
reader 132 kHz
|
||||||
|
tag 66 kHz
|
||||||
|
|
||||||
|
Divide by 384 counter
|
||||||
|
|
||||||
|
PULSE repetition 5.82ms
|
||||||
|
LOW 2.91 ms
|
||||||
|
HIGH 2.91 ms
|
||||||
|
|
||||||
|
Also references to a half-bit format and leading zero.
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
|
||||||
|
READER START SEQUENCE:
|
||||||
|
|
||||||
|
burst 800 us gap 2.2 ms
|
||||||
|
burst 3.6 ms gap 2.2 ms
|
||||||
|
burst 800 us gap 2.2 ms
|
||||||
|
pulse 3.6 ms
|
||||||
|
|
||||||
|
This triggers COTAG tag to response
|
||||||
|
|
||||||
This triggers a COTAG tag to response
|
|
||||||
*/
|
*/
|
||||||
void Cotag(uint32_t arg0) {
|
void Cotag(uint32_t arg0) {
|
||||||
#ifndef OFF
|
#ifndef OFF
|
||||||
|
@ -2396,7 +2454,7 @@ void Cotag(uint32_t arg0) {
|
||||||
|
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
|
|
||||||
LFSetupFPGAForADC(89, true);
|
LFSetupFPGAForADC(LF_DIVISOR(132), true);
|
||||||
|
|
||||||
//clear buffer now so it does not interfere with timing later
|
//clear buffer now so it does not interfere with timing later
|
||||||
BigBuf_Clear_ext(false);
|
BigBuf_Clear_ext(false);
|
||||||
|
|
|
@ -52,6 +52,7 @@ void T55xxWriteBlock(uint8_t *data);
|
||||||
void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, uint32_t pwd, uint8_t downlink_mode);
|
void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block, uint32_t pwd, uint8_t downlink_mode);
|
||||||
void T55xxWakeUp(uint32_t pwd, uint8_t flags);
|
void T55xxWakeUp(uint32_t pwd, uint8_t flags);
|
||||||
void T55xx_ChkPwds(uint8_t flags);
|
void T55xx_ChkPwds(uint8_t flags);
|
||||||
|
void T55xxDangerousRawTest(uint8_t *data);
|
||||||
|
|
||||||
void TurnReadLFOn(uint32_t delay);
|
void TurnReadLFOn(uint32_t delay);
|
||||||
|
|
||||||
|
|
|
@ -95,9 +95,9 @@ void pushBit(BitstreamOut *stream, uint8_t bit) {
|
||||||
void LFSetupFPGAForADC(int divisor, bool lf_field) {
|
void LFSetupFPGAForADC(int divisor, bool lf_field) {
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||||
if ((divisor == 1) || (divisor < 0) || (divisor > 255))
|
if ((divisor == 1) || (divisor < 0) || (divisor > 255))
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8kHz
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_134); //~134kHz
|
||||||
else if (divisor == 0)
|
else if (divisor == 0)
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz
|
||||||
else
|
else
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
|
||||||
|
|
||||||
|
|
|
@ -585,7 +585,9 @@ size_t CreateAPDU(uint8_t *datain, size_t len, uint8_t *dataout) {
|
||||||
void OnSuccess() {
|
void OnSuccess() {
|
||||||
pcb_blocknum = 0;
|
pcb_blocknum = 0;
|
||||||
ReaderTransmit(deselect_cmd, 3, NULL);
|
ReaderTransmit(deselect_cmd, 3, NULL);
|
||||||
mifare_ultra_halt();
|
if (mifare_ultra_halt()) {
|
||||||
|
if (DBGLEVEL >= DBG_ERROR) Dbprintf("Halt error");
|
||||||
|
}
|
||||||
switch_off();
|
switch_off();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -495,10 +495,10 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
|
||||||
|
|
||||||
//allow collecting up to 7 sets of nonces to allow recovery of up to 7 keys
|
//allow collecting up to 7 sets of nonces to allow recovery of up to 7 keys
|
||||||
#define ATTACK_KEY_COUNT 7 // keep same as define in cmdhfmf.c -> readerAttack() (Cannot be more than 7)
|
#define ATTACK_KEY_COUNT 7 // keep same as define in cmdhfmf.c -> readerAttack() (Cannot be more than 7)
|
||||||
nonces_t ar_nr_resp[ATTACK_KEY_COUNT * 2]; //*2 for 2 separate attack types (nml, moebius) 36 * 7 * 2 bytes = 504 bytes
|
nonces_t ar_nr_resp[ATTACK_KEY_COUNT * 2]; // *2 for 2 separate attack types (nml, moebius) 36 * 7 * 2 bytes = 504 bytes
|
||||||
memset(ar_nr_resp, 0x00, sizeof(ar_nr_resp));
|
memset(ar_nr_resp, 0x00, sizeof(ar_nr_resp));
|
||||||
|
|
||||||
uint8_t ar_nr_collected[ATTACK_KEY_COUNT * 2]; //*2 for 2nd attack type (moebius)
|
uint8_t ar_nr_collected[ATTACK_KEY_COUNT * 2]; // *2 for 2nd attack type (moebius)
|
||||||
memset(ar_nr_collected, 0x00, sizeof(ar_nr_collected));
|
memset(ar_nr_collected, 0x00, sizeof(ar_nr_collected));
|
||||||
uint8_t nonce1_count = 0;
|
uint8_t nonce1_count = 0;
|
||||||
uint8_t nonce2_count = 0;
|
uint8_t nonce2_count = 0;
|
||||||
|
@ -588,9 +588,11 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
|
||||||
case MFEMUL_NOFIELD:
|
case MFEMUL_NOFIELD:
|
||||||
if (DBGLEVEL >= DBG_EXTENDED)
|
if (DBGLEVEL >= DBG_EXTENDED)
|
||||||
Dbprintf("MFEMUL_NOFIELD");
|
Dbprintf("MFEMUL_NOFIELD");
|
||||||
|
break;
|
||||||
case MFEMUL_HALTED:
|
case MFEMUL_HALTED:
|
||||||
if (DBGLEVEL >= DBG_EXTENDED)
|
if (DBGLEVEL >= DBG_EXTENDED)
|
||||||
Dbprintf("MFEMUL_HALTED");
|
Dbprintf("MFEMUL_HALTED");
|
||||||
|
break;
|
||||||
case MFEMUL_IDLE: {
|
case MFEMUL_IDLE: {
|
||||||
LogTrace(uart->output, uart->len, uart->startTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->endTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->parity, true);
|
LogTrace(uart->output, uart->len, uart->startTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->endTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->parity, true);
|
||||||
if (DBGLEVEL >= DBG_EXTENDED)
|
if (DBGLEVEL >= DBG_EXTENDED)
|
||||||
|
@ -719,8 +721,9 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
|
||||||
// RCV: 61 XX => Using KEY B
|
// RCV: 61 XX => Using KEY B
|
||||||
// XX: Block number
|
// XX: Block number
|
||||||
|
|
||||||
|
// iceman, u8 can never be larger than 256
|
||||||
// if authenticating to a block that shouldn't exist - as long as we are not doing the reader attack
|
// if authenticating to a block that shouldn't exist - as long as we are not doing the reader attack
|
||||||
if (receivedCmd_dec[1] > MIFARE_4K_MAXBLOCK && !((flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK)) {
|
if ( ((flags & FLAG_NR_AR_ATTACK) != FLAG_NR_AR_ATTACK) ) {
|
||||||
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
|
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
|
||||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Reader tried to operate (0x%02x) on out of range block: %d (0x%02x), nacking", receivedCmd_dec[0], receivedCmd_dec[1], receivedCmd_dec[1]);
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Reader tried to operate (0x%02x) on out of range block: %d (0x%02x), nacking", receivedCmd_dec[0], receivedCmd_dec[1], receivedCmd_dec[1]);
|
||||||
break;
|
break;
|
||||||
|
@ -796,12 +799,17 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain, uint1
|
||||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Commands must be encrypted (authenticated)");
|
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Commands must be encrypted (authenticated)");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// iceman, u8 can never be larger the MIFARE_4K_MAXBLOCK (256)
|
||||||
// Check if Block num is not too far
|
// Check if Block num is not too far
|
||||||
|
/*
|
||||||
if (receivedCmd_dec[1] > MIFARE_4K_MAXBLOCK) {
|
if (receivedCmd_dec[1] > MIFARE_4K_MAXBLOCK) {
|
||||||
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
|
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
|
||||||
if (DBGLEVEL >= DBG_ERROR) Dbprintf("[MFEMUL_WORK] Reader tried to operate (0x%02x) on out of range block: %d (0x%02x), nacking", receivedCmd_dec[0], receivedCmd_dec[1], receivedCmd_dec[1]);
|
if (DBGLEVEL >= DBG_ERROR) Dbprintf("[MFEMUL_WORK] Reader tried to operate (0x%02x) on out of range block: %d (0x%02x), nacking", receivedCmd_dec[0], receivedCmd_dec[1], receivedCmd_dec[1]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if (MifareBlockToSector(receivedCmd_dec[1]) != cardAUTHSC) {
|
if (MifareBlockToSector(receivedCmd_dec[1]) != cardAUTHSC) {
|
||||||
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
|
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA));
|
||||||
if (DBGLEVEL >= DBG_ERROR) Dbprintf("[MFEMUL_WORK] Reader tried to operate (0x%02x) on block (0x%02x) not authenticated for (0x%02x), nacking", receivedCmd_dec[0], receivedCmd_dec[1], cardAUTHSC);
|
if (DBGLEVEL >= DBG_ERROR) Dbprintf("[MFEMUL_WORK] Reader tried to operate (0x%02x) on block (0x%02x) not authenticated for (0x%02x), nacking", receivedCmd_dec[0], receivedCmd_dec[1], cardAUTHSC);
|
||||||
|
|
|
@ -32,7 +32,7 @@ size_t DemodPCF7931(uint8_t **outBlocks) {
|
||||||
uint8_t dir;
|
uint8_t dir;
|
||||||
|
|
||||||
BigBuf_Clear_keep_EM();
|
BigBuf_Clear_keep_EM();
|
||||||
LFSetupFPGAForADC(95, true);
|
LFSetupFPGAForADC(LF_DIVISOR_125, true);
|
||||||
DoAcquisition_default(0, true);
|
DoAcquisition_default(0, true);
|
||||||
|
|
||||||
/* Find first local max/min */
|
/* Find first local max/min */
|
||||||
|
@ -449,7 +449,7 @@ void SendCmdPCF7931(uint32_t *tab) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||||
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125kHz
|
FpgaSendCommand(FPGA_CMD_SET_DIVISOR, LF_DIVISOR_125); //125kHz
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU);
|
||||||
|
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
|
|
|
@ -749,7 +749,7 @@ static s32_t spiffs_stat_pix(spiffs *fs, spiffs_page_ix pix, spiffs_file fh, spi
|
||||||
s->type = objix_hdr.type;
|
s->type = objix_hdr.type;
|
||||||
s->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size;
|
s->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size;
|
||||||
s->pix = pix;
|
s->pix = pix;
|
||||||
strncpy((char *)s->name, (char *)objix_hdr.name, SPIFFS_OBJ_NAME_LEN);
|
strncpy((char *)s->name, (char *)objix_hdr.name, SPIFFS_OBJ_NAME_LEN - 1);
|
||||||
#if SPIFFS_OBJ_META_LEN
|
#if SPIFFS_OBJ_META_LEN
|
||||||
_SPIFFS_MEMCPY(s->meta, objix_hdr.meta, SPIFFS_OBJ_META_LEN);
|
_SPIFFS_MEMCPY(s->meta, objix_hdr.meta, SPIFFS_OBJ_META_LEN);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -944,7 +944,7 @@ s32_t spiffs_object_create(
|
||||||
oix_hdr.p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED);
|
oix_hdr.p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED);
|
||||||
oix_hdr.type = type;
|
oix_hdr.type = type;
|
||||||
oix_hdr.size = SPIFFS_UNDEFINED_LEN; // keep ones so we can update later without wasting this page
|
oix_hdr.size = SPIFFS_UNDEFINED_LEN; // keep ones so we can update later without wasting this page
|
||||||
strncpy((char *)oix_hdr.name, (const char *)name, SPIFFS_OBJ_NAME_LEN);
|
strncpy((char *)oix_hdr.name, (const char *)name, SPIFFS_OBJ_NAME_LEN - 1);
|
||||||
#if SPIFFS_OBJ_META_LEN
|
#if SPIFFS_OBJ_META_LEN
|
||||||
if (meta) {
|
if (meta) {
|
||||||
_SPIFFS_MEMCPY(oix_hdr.meta, meta, SPIFFS_OBJ_META_LEN);
|
_SPIFFS_MEMCPY(oix_hdr.meta, meta, SPIFFS_OBJ_META_LEN);
|
||||||
|
@ -1007,7 +1007,7 @@ s32_t spiffs_object_update_index_hdr(
|
||||||
|
|
||||||
// change name
|
// change name
|
||||||
if (name) {
|
if (name) {
|
||||||
strncpy((char *)objix_hdr->name, (const char *)name, SPIFFS_OBJ_NAME_LEN);
|
strncpy((char *)objix_hdr->name, (const char *)name, SPIFFS_OBJ_NAME_LEN - 1);
|
||||||
}
|
}
|
||||||
#if SPIFFS_OBJ_META_LEN
|
#if SPIFFS_OBJ_META_LEN
|
||||||
if (meta) {
|
if (meta) {
|
||||||
|
@ -1560,6 +1560,7 @@ s32_t spiffs_object_modify(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) {
|
||||||
res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG,
|
res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG,
|
||||||
&p_hdr, &data[written], to_write, page_offs, 1, &data_pix);
|
&p_hdr, &data[written], to_write, page_offs, 1, &data_pix);
|
||||||
SPIFFS_DBG("modify: store new data page, "_SPIPRIpg":"_SPIPRIsp" offset:"_SPIPRIi", len "_SPIPRIi", written "_SPIPRIi"\n", data_pix, data_spix, page_offs, to_write, written);
|
SPIFFS_DBG("modify: store new data page, "_SPIPRIpg":"_SPIPRIsp" offset:"_SPIPRIi", len "_SPIPRIi", written "_SPIPRIi"\n", data_pix, data_spix, page_offs, to_write, written);
|
||||||
|
if (res != SPIFFS_OK) break;
|
||||||
} else {
|
} else {
|
||||||
// write to existing page, allocate new and copy unmodified data
|
// write to existing page, allocate new and copy unmodified data
|
||||||
|
|
||||||
|
|
|
@ -250,11 +250,11 @@ void WaitTicks(uint32_t ticks) {
|
||||||
|
|
||||||
// Wait / Spindelay in us (microseconds)
|
// Wait / Spindelay in us (microseconds)
|
||||||
// 1us = 1.5ticks.
|
// 1us = 1.5ticks.
|
||||||
void WaitUS(uint16_t us) {
|
void WaitUS(uint32_t us) {
|
||||||
WaitTicks((uint32_t)us * 3 / 2);
|
WaitTicks((us & 0x3FFFFFFF) * 3 / 2);
|
||||||
}
|
}
|
||||||
void WaitMS(uint16_t ms) {
|
void WaitMS(uint32_t ms) {
|
||||||
WaitTicks((uint32_t)ms * 1500);
|
WaitTicks((ms & 0x1FFFFF) * 1500);
|
||||||
}
|
}
|
||||||
|
|
||||||
// stop clock
|
// stop clock
|
||||||
|
|
|
@ -38,8 +38,8 @@ uint32_t RAMFUNC GetCountSspClkDelta();
|
||||||
void StartTicks(void);
|
void StartTicks(void);
|
||||||
uint32_t GetTicks(void);
|
uint32_t GetTicks(void);
|
||||||
void WaitTicks(uint32_t ticks);
|
void WaitTicks(uint32_t ticks);
|
||||||
void WaitUS(uint16_t us);
|
void WaitUS(uint32_t us);
|
||||||
void WaitMS(uint16_t ms);
|
void WaitMS(uint32_t ms);
|
||||||
|
|
||||||
void StopTicks(void);
|
void StopTicks(void);
|
||||||
|
|
||||||
|
|
|
@ -77,22 +77,23 @@ else
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Check for correctly configured Qt5
|
ifneq ($(SKIPQT),1)
|
||||||
QTINCLUDES = $(shell pkg-config --cflags Qt5Core Qt5Widgets 2>/dev/null)
|
# Check for correctly configured Qt5
|
||||||
QTLDLIBS = $(shell pkg-config --libs Qt5Core Qt5Widgets 2>/dev/null)
|
QTINCLUDES = $(shell pkg-config --cflags Qt5Core Qt5Widgets 2>/dev/null)
|
||||||
MOC = $(shell pkg-config --variable=host_bins Qt5Core)/moc
|
QTLDLIBS = $(shell pkg-config --libs Qt5Core Qt5Widgets 2>/dev/null)
|
||||||
UIC = $(shell pkg-config --variable=host_bins Qt5Core)/uic
|
MOC = $(shell pkg-config --variable=host_bins Qt5Core)/moc
|
||||||
ifeq ($(QTINCLUDES), )
|
UIC = $(shell pkg-config --variable=host_bins Qt5Core)/uic
|
||||||
# if Qt5 not found check for correctly configured Qt4
|
ifeq ($(QTINCLUDES), )
|
||||||
|
# if Qt5 not found check for correctly configured Qt4
|
||||||
QTINCLUDES = $(shell pkg-config --cflags QtCore QtGui 2>/dev/null)
|
QTINCLUDES = $(shell pkg-config --cflags QtCore QtGui 2>/dev/null)
|
||||||
QTLDLIBS = $(shell pkg-config --libs QtCore QtGui 2>/dev/null)
|
QTLDLIBS = $(shell pkg-config --libs QtCore QtGui 2>/dev/null)
|
||||||
MOC = $(shell pkg-config --variable=moc_location QtCore)
|
MOC = $(shell pkg-config --variable=moc_location QtCore)
|
||||||
UIC = $(shell pkg-config --variable=uic_location QtCore)
|
UIC = $(shell pkg-config --variable=uic_location QtCore)
|
||||||
else
|
else
|
||||||
PM3CXXFLAGS += -std=c++11 -fPIC
|
PM3CXXFLAGS += -std=c++11 -fPIC
|
||||||
endif
|
endif
|
||||||
ifeq ($(QTINCLUDES), )
|
ifeq ($(QTINCLUDES), )
|
||||||
# if both pkg-config commands failed, search in common places
|
# if both pkg-config commands failed, search in common places
|
||||||
ifneq ($(QTDIR), )
|
ifneq ($(QTDIR), )
|
||||||
QTINCLUDES = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui
|
QTINCLUDES = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui
|
||||||
QTLDLIBS = -L$(QTDIR)/lib -lQtCore4 -lQtGui4
|
QTLDLIBS = -L$(QTDIR)/lib -lQtCore4 -lQtGui4
|
||||||
|
@ -104,9 +105,9 @@ ifeq ($(QTINCLUDES), )
|
||||||
MOC = $(QTDIR)/bin/moc
|
MOC = $(QTDIR)/bin/moc
|
||||||
UIC = $(QTDIR)/bin/uic
|
UIC = $(QTDIR)/bin/uic
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
ifneq ($(QTLDLIBS),)
|
ifneq ($(QTLDLIBS),)
|
||||||
QTGUIOBJS = $(OBJDIR)/proxgui.o $(OBJDIR)/proxguiqt.o $(OBJDIR)/proxguiqt.moc.o
|
QTGUIOBJS = $(OBJDIR)/proxgui.o $(OBJDIR)/proxguiqt.o $(OBJDIR)/proxguiqt.moc.o
|
||||||
PM3CFLAGS += -DHAVE_GUI
|
PM3CFLAGS += -DHAVE_GUI
|
||||||
|
@ -206,6 +207,7 @@ CMDSRCS = crapto1/crapto1.c \
|
||||||
cmdlfem4x.c \
|
cmdlfem4x.c \
|
||||||
cmdlffdx.c \
|
cmdlffdx.c \
|
||||||
cmdlfguard.c \
|
cmdlfguard.c \
|
||||||
|
cmdlfgallagher.c \
|
||||||
cmdlfhid.c \
|
cmdlfhid.c \
|
||||||
cmdlfhitag.c \
|
cmdlfhitag.c \
|
||||||
cmdlfio.c \
|
cmdlfio.c \
|
||||||
|
|
|
@ -137,16 +137,15 @@ bool nfc3d_amiibo_load_keys(nfc3d_amiibo_keys *amiiboKeys, const char *path) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fread(amiiboKeys, sizeof(*amiiboKeys), 1, f)) {
|
size_t len = fread(amiiboKeys, sizeof(*amiiboKeys), 1, f);
|
||||||
fclose(f);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
if (
|
if (len != sizeof(*amiiboKeys)) {
|
||||||
(amiiboKeys->data.magicBytesSize > 16) ||
|
return false;
|
||||||
(amiiboKeys->tag.magicBytesSize > 16)
|
}
|
||||||
) {
|
|
||||||
|
if ((amiiboKeys->data.magicBytesSize > 16) ||
|
||||||
|
(amiiboKeys->tag.magicBytesSize > 16)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -553,7 +553,7 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resp.oldarg[0] != 1 && resp.oldarg[0] != 2) {
|
if (resp.oldarg[0] != 1 && resp.oldarg[0] != 2) {
|
||||||
PrintAndLogEx(ERR, "Card not in iso14443-4. res=" PRId64 ".", resp.oldarg[0]);
|
PrintAndLogEx(ERR, "Card not in iso14443-4. res=%" PRId64 ".", resp.oldarg[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ static int CmdHFEPACollectPACENonces(const char *Cmd) {
|
||||||
|
|
||||||
// check if command failed
|
// check if command failed
|
||||||
if (resp.oldarg[0] != 0) {
|
if (resp.oldarg[0] != 0) {
|
||||||
PrintAndLogEx(FAILED, "Error in step %" PRId64 ", Return code: %" PRId64, resp.oldarg[0], (int)resp.oldarg[1]);
|
PrintAndLogEx(FAILED, "Error in step %" PRId64 ", Return code: %" PRId64, resp.oldarg[0], resp.oldarg[1]);
|
||||||
} else {
|
} else {
|
||||||
size_t nonce_length = resp.oldarg[1];
|
size_t nonce_length = resp.oldarg[1];
|
||||||
char *nonce = (char *) calloc(2 * nonce_length + 1, sizeof(uint8_t));
|
char *nonce = (char *) calloc(2 * nonce_length + 1, sizeof(uint8_t));
|
||||||
|
|
|
@ -408,7 +408,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "Recorded Activity (trace len = %"PRIu64" bytes)", tracelen);
|
PrintAndLogEx(SUCCESS, "Recorded Activity (trace len = %"PRIu32" bytes)", tracelen);
|
||||||
|
|
||||||
print_hex_break(trace, tracelen, 32);
|
print_hex_break(trace, tracelen, 32);
|
||||||
printSep();
|
printSep();
|
||||||
|
|
|
@ -870,6 +870,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) {
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
|
|
||||||
memcpy(key, keyptr, sizeof(key));
|
memcpy(key, keyptr, sizeof(key));
|
||||||
|
free(keyptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// tripledes
|
// tripledes
|
||||||
|
@ -2486,7 +2487,7 @@ static int CmdHFiClassLookUp(const char *Cmd) {
|
||||||
case 'u':
|
case 'u':
|
||||||
param_gethex_ex(Cmd, cmdp + 1, CSN, &len);
|
param_gethex_ex(Cmd, cmdp + 1, CSN, &len);
|
||||||
if (len >> 1 != sizeof(CSN)) {
|
if (len >> 1 != sizeof(CSN)) {
|
||||||
PrintAndLogEx(WARNING, "Wrong CSN length, expected %d got [%d]", sizeof(CSN), len >> 1);
|
PrintAndLogEx(WARNING, "Wrong CSN length, expected %zu got [%d]", sizeof(CSN), len >> 1);
|
||||||
errors = true;
|
errors = true;
|
||||||
}
|
}
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
|
@ -2494,7 +2495,7 @@ static int CmdHFiClassLookUp(const char *Cmd) {
|
||||||
case 'm':
|
case 'm':
|
||||||
param_gethex_ex(Cmd, cmdp + 1, MACS, &len);
|
param_gethex_ex(Cmd, cmdp + 1, MACS, &len);
|
||||||
if (len >> 1 != sizeof(MACS)) {
|
if (len >> 1 != sizeof(MACS)) {
|
||||||
PrintAndLogEx(WARNING, "Wrong MACS length, expected %d got [%d] ", sizeof(MACS), len >> 1);
|
PrintAndLogEx(WARNING, "Wrong MACS length, expected %zu got [%d] ", sizeof(MACS), len >> 1);
|
||||||
errors = true;
|
errors = true;
|
||||||
} else {
|
} else {
|
||||||
memcpy(MAC_TAG, MACS + 4, 4);
|
memcpy(MAC_TAG, MACS + 4, 4);
|
||||||
|
|
|
@ -363,7 +363,7 @@ void annotateIclass(char *exp, size_t size, uint8_t *cmd, uint8_t cmdsize) {
|
||||||
snprintf(exp, size, "UPDATE(%d)", cmd[1]);
|
snprintf(exp, size, "UPDATE(%d)", cmd[1]);
|
||||||
break;
|
break;
|
||||||
case ICLASS_CMD_READCHECK:
|
case ICLASS_CMD_READCHECK:
|
||||||
if (ICLASS_CREDIT(c)) {
|
if (ICLASS_CREDIT(cmd[0])) {
|
||||||
snprintf(exp, size, "READCHECK[Kc](%d)", cmd[1]);
|
snprintf(exp, size, "READCHECK[Kc](%d)", cmd[1]);
|
||||||
} else {
|
} else {
|
||||||
snprintf(exp, size, "READCHECK[Kd](%d)", cmd[1]);
|
snprintf(exp, size, "READCHECK[Kd](%d)", cmd[1]);
|
||||||
|
|
|
@ -1644,7 +1644,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
int block_cnt = MIFARE_1K_MAXBLOCK;
|
int block_cnt = MIFARE_1K_MAXBLOCK;
|
||||||
uint8_t tmp_key[6] = {0};
|
uint8_t tmp_key[6] = {0};
|
||||||
bool know_target_key = false;
|
bool know_target_key = false;
|
||||||
// For the timier
|
// For the timer
|
||||||
uint64_t t1;
|
uint64_t t1;
|
||||||
// Parameters and dictionary file
|
// Parameters and dictionary file
|
||||||
char filename[FILE_PATH_SIZE] = {0};
|
char filename[FILE_PATH_SIZE] = {0};
|
||||||
|
@ -1666,6 +1666,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
bool has_filename = false;
|
bool has_filename = false;
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
|
uint8_t num_found_keys = 0;
|
||||||
|
|
||||||
// Parse the options given by the user
|
// Parse the options given by the user
|
||||||
while ((ctmp = param_getchar(Cmd, cmdp)) && !errors) {
|
while ((ctmp = param_getchar(Cmd, cmdp)) && !errors) {
|
||||||
|
@ -1819,6 +1820,9 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
|
|
||||||
// Store the key for the nested / hardnested attack (if supplied by the user)
|
// Store the key for the nested / hardnested attack (if supplied by the user)
|
||||||
e_sector[blockNo].Key[keyType] = key64;
|
e_sector[blockNo].Key[keyType] = key64;
|
||||||
|
e_sector[blockNo].foundKey[keyType] = 'U';
|
||||||
|
|
||||||
|
++num_found_keys;
|
||||||
} else {
|
} else {
|
||||||
know_target_key = false;
|
know_target_key = false;
|
||||||
PrintAndLogEx(FAILED, "Key is wrong. Can't authenticate to sector:"_RED_("%3d") " key type: "_RED_("%c") " key: " _RED_("%s"),
|
PrintAndLogEx(FAILED, "Key is wrong. Can't authenticate to sector:"_RED_("%3d") " key type: "_RED_("%c") " key: " _RED_("%s"),
|
||||||
|
@ -1855,11 +1859,14 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
sprint_hex(key, sizeof(key))
|
sprint_hex(key, sizeof(key))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
++num_found_keys;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= STOP KNOWN KEY ATTACK ======================="));
|
if (verbose) PrintAndLogEx(INFO, _YELLOW_("======================= STOP KNOWN KEY ATTACK ======================="));
|
||||||
|
if (num_found_keys == sectors_cnt * 2)
|
||||||
|
goto all_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool load_success = true;
|
bool load_success = true;
|
||||||
|
@ -1873,7 +1880,6 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
|
|
||||||
load_success = false;
|
load_success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_filename == false || load_success == false) {
|
if (has_filename == false || load_success == false) {
|
||||||
|
@ -1905,6 +1911,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
if (mfCheckKeys(FirstBlockOfSector(i), j, true, 1, (keyBlock + (6 * k)), &key64) == PM3_SUCCESS) {
|
if (mfCheckKeys(FirstBlockOfSector(i), j, true, 1, (keyBlock + (6 * k)), &key64) == PM3_SUCCESS) {
|
||||||
e_sector[i].Key[j] = bytes_to_num((keyBlock + (6 * k)), 6);
|
e_sector[i].Key[j] = bytes_to_num((keyBlock + (6 * k)), 6);
|
||||||
e_sector[i].foundKey[j] = 'D';
|
e_sector[i].foundKey[j] = 'D';
|
||||||
|
++num_found_keys;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1960,7 +1967,7 @@ static int CmdHF14AMfAutoPWN(const char *Cmd) {
|
||||||
|
|
||||||
// Store valid credentials for the nested / hardnested attack if none exist
|
// Store valid credentials for the nested / hardnested attack if none exist
|
||||||
if (know_target_key == false) {
|
if (know_target_key == false) {
|
||||||
num_to_bytes(e_sector[i].Key[j], 6, key);
|
num_to_bytes(e_sector[i].Key[j], 6, tmp_key);
|
||||||
know_target_key = true;
|
know_target_key = true;
|
||||||
blockNo = i;
|
blockNo = i;
|
||||||
keyType = j;
|
keyType = j;
|
||||||
|
@ -2205,6 +2212,8 @@ tryHardnested: // If the nested attack fails then we try the hardnested attack
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
all_found:
|
||||||
|
|
||||||
// Show the results to the user
|
// Show the results to the user
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "found Keys:");
|
PrintAndLogEx(INFO, "found Keys:");
|
||||||
|
@ -2726,8 +2735,13 @@ static int CmdHF14AMfChk(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, "No key specified, trying default keys");
|
PrintAndLogEx(INFO, "No key specified, trying default keys");
|
||||||
for (; keycnt < ARRAYLEN(g_mifare_default_keys); keycnt++)
|
for (; keycnt < ARRAYLEN(g_mifare_default_keys); keycnt++)
|
||||||
PrintAndLogEx(NORMAL, "[%2d] %02x%02x%02x%02x%02x%02x", keycnt,
|
PrintAndLogEx(NORMAL, "[%2d] %02x%02x%02x%02x%02x%02x", keycnt,
|
||||||
(keyBlock + 6 * keycnt)[0], (keyBlock + 6 * keycnt)[1], (keyBlock + 6 * keycnt)[2],
|
(keyBlock + 6 * keycnt)[0],
|
||||||
(keyBlock + 6 * keycnt)[3], (keyBlock + 6 * keycnt)[4], (keyBlock + 6 * keycnt)[5], 6);
|
(keyBlock + 6 * keycnt)[1],
|
||||||
|
(keyBlock + 6 * keycnt)[2],
|
||||||
|
(keyBlock + 6 * keycnt)[3],
|
||||||
|
(keyBlock + 6 * keycnt)[4],
|
||||||
|
(keyBlock + 6 * keycnt)[5]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize storage for found keys
|
// initialize storage for found keys
|
||||||
|
@ -2852,18 +2866,21 @@ out:
|
||||||
PrintAndLogEx(SUCCESS, "Found keys have been transferred to the emulator memory");
|
PrintAndLogEx(SUCCESS, "Found keys have been transferred to the emulator memory");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable fast mode and send a dummy command to make it effective
|
|
||||||
conn.block_after_ACK = false;
|
|
||||||
SendCommandNG(CMD_PING, NULL, 0);
|
|
||||||
WaitForResponseTimeout(CMD_PING, NULL, 1000);
|
|
||||||
|
|
||||||
if (createDumpFile) {
|
if (createDumpFile) {
|
||||||
fptr = GenerateFilename("hf-mf-", "-key.bin");
|
fptr = GenerateFilename("hf-mf-", "-key.bin");
|
||||||
createMfcKeyDump(SectorsCnt, e_sector, fptr);
|
createMfcKeyDump(SectorsCnt, e_sector, fptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(keyBlock);
|
free(keyBlock);
|
||||||
free(e_sector);
|
free(e_sector);
|
||||||
|
|
||||||
|
// Disable fast mode and send a dummy command to make it effective
|
||||||
|
conn.block_after_ACK = false;
|
||||||
|
SendCommandNG(CMD_PING, NULL, 0);
|
||||||
|
if (!WaitForResponseTimeout(CMD_PING, NULL, 1000)) {
|
||||||
|
PrintAndLogEx(WARNING, "command execution time out");
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -282,7 +282,12 @@ static void init_bitflip_bitarrays(void) {
|
||||||
fclose(statesfile);
|
fclose(statesfile);
|
||||||
uint32_t count = 0;
|
uint32_t count = 0;
|
||||||
init_inflate(&compressed_stream, input_buffer, filesize, (uint8_t *)&count, sizeof(count));
|
init_inflate(&compressed_stream, input_buffer, filesize, (uint8_t *)&count, sizeof(count));
|
||||||
inflate(&compressed_stream, Z_SYNC_FLUSH);
|
int res = inflate(&compressed_stream, Z_SYNC_FLUSH);
|
||||||
|
if (res != Z_OK) {
|
||||||
|
PrintAndLogEx(ERR, "Inflate error. Aborting...\n");
|
||||||
|
inflateEnd(&compressed_stream);
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
if ((float)count / (1 << 24) < IGNORE_BITFLIP_THRESHOLD) {
|
if ((float)count / (1 << 24) < IGNORE_BITFLIP_THRESHOLD) {
|
||||||
uint32_t *bitset = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * (1 << 19));
|
uint32_t *bitset = (uint32_t *)malloc_bitarray(sizeof(uint32_t) * (1 << 19));
|
||||||
if (bitset == NULL) {
|
if (bitset == NULL) {
|
||||||
|
@ -292,7 +297,12 @@ static void init_bitflip_bitarrays(void) {
|
||||||
}
|
}
|
||||||
compressed_stream.next_out = (uint8_t *)bitset;
|
compressed_stream.next_out = (uint8_t *)bitset;
|
||||||
compressed_stream.avail_out = sizeof(uint32_t) * (1 << 19);
|
compressed_stream.avail_out = sizeof(uint32_t) * (1 << 19);
|
||||||
inflate(&compressed_stream, Z_SYNC_FLUSH);
|
res = inflate(&compressed_stream, Z_SYNC_FLUSH);
|
||||||
|
if (res != Z_OK && res != Z_STREAM_END) {
|
||||||
|
PrintAndLogEx(ERR, "Inflate error. Aborting...\n");
|
||||||
|
inflateEnd(&compressed_stream);
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
effective_bitflip[odd_even][num_effective_bitflips[odd_even]++] = bitflip;
|
effective_bitflip[odd_even][num_effective_bitflips[odd_even]++] = bitflip;
|
||||||
bitflip_bitarrays[odd_even][bitflip] = bitset;
|
bitflip_bitarrays[odd_even][bitflip] = bitset;
|
||||||
count_bitflip_bitarrays[odd_even][bitflip] = count;
|
count_bitflip_bitarrays[odd_even][bitflip] = count;
|
||||||
|
|
|
@ -791,8 +791,13 @@ static int ndef_print_CC(uint8_t *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int ul_print_type(uint32_t tagtype, uint8_t spaces) {
|
int ul_print_type(uint32_t tagtype, uint8_t spaces) {
|
||||||
|
|
||||||
char spc[11] = " ";
|
char spc[11] = " ";
|
||||||
spc[10] = 0x00;
|
spc[10] = 0x00;
|
||||||
|
|
||||||
|
if (spaces > 10)
|
||||||
|
spaces = 10;
|
||||||
|
|
||||||
char *spacer = spc + (10 - spaces);
|
char *spacer = spc + (10 - spaces);
|
||||||
|
|
||||||
if (tagtype & UL)
|
if (tagtype & UL)
|
||||||
|
@ -851,10 +856,10 @@ int ul_print_type(uint32_t tagtype, uint8_t spaces) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ulc_print_3deskey(uint8_t *data) {
|
static int ulc_print_3deskey(uint8_t *data) {
|
||||||
PrintAndLogEx(NORMAL, " deskey1 [44/0x2C] : %s [s]", sprint_hex(data, 4), sprint_ascii(data, 4));
|
PrintAndLogEx(NORMAL, " deskey1 [44/0x2C] : %s [%s]", sprint_hex(data, 4), sprint_ascii(data, 4));
|
||||||
PrintAndLogEx(NORMAL, " deskey1 [45/0x2D] : %s [s]", sprint_hex(data + 4, 4), sprint_ascii(data + 4, 4));
|
PrintAndLogEx(NORMAL, " deskey1 [45/0x2D] : %s [%s]", sprint_hex(data + 4, 4), sprint_ascii(data + 4, 4));
|
||||||
PrintAndLogEx(NORMAL, " deskey2 [46/0x2E] : %s [s]", sprint_hex(data + 8, 4), sprint_ascii(data + 8, 4));
|
PrintAndLogEx(NORMAL, " deskey2 [46/0x2E] : %s [%s]", sprint_hex(data + 8, 4), sprint_ascii(data + 8, 4));
|
||||||
PrintAndLogEx(NORMAL, " deskey2 [47/0x2F] : %s [s]", sprint_hex(data + 12, 4), sprint_ascii(data + 12, 4));
|
PrintAndLogEx(NORMAL, " deskey2 [47/0x2F] : %s [%s]", sprint_hex(data + 12, 4), sprint_ascii(data + 12, 4));
|
||||||
PrintAndLogEx(NORMAL, "\n 3des key : %s", sprint_hex(SwapEndian64(data, 16, 8), 16));
|
PrintAndLogEx(NORMAL, "\n 3des key : %s", sprint_hex(SwapEndian64(data, 16, 8), 16));
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1405,7 +1410,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
|
||||||
num_to_bytes(ul_ev1_pwdgenA(card.uid), 4, key);
|
num_to_bytes(ul_ev1_pwdgenA(card.uid), 4, key);
|
||||||
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
||||||
if (len > -1) {
|
if (len > -1) {
|
||||||
PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]);
|
PrintAndLogEx(SUCCESS, "Found a default password:" _GREEN_("%s") " || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1415,7 +1420,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
|
||||||
num_to_bytes(ul_ev1_pwdgenB(card.uid), 4, key);
|
num_to_bytes(ul_ev1_pwdgenB(card.uid), 4, key);
|
||||||
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
||||||
if (len > -1) {
|
if (len > -1) {
|
||||||
PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]);
|
PrintAndLogEx(SUCCESS, "Found a default password:" _GREEN_("%s") " || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1425,7 +1430,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
|
||||||
num_to_bytes(ul_ev1_pwdgenC(card.uid), 4, key);
|
num_to_bytes(ul_ev1_pwdgenC(card.uid), 4, key);
|
||||||
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
||||||
if (len > -1) {
|
if (len > -1) {
|
||||||
PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]);
|
PrintAndLogEx(SUCCESS, "Found a default password:" _GREEN_("%s") " || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1435,7 +1440,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
|
||||||
num_to_bytes(ul_ev1_pwdgenD(card.uid), 4, key);
|
num_to_bytes(ul_ev1_pwdgenD(card.uid), 4, key);
|
||||||
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
||||||
if (len > -1) {
|
if (len > -1) {
|
||||||
PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]);
|
PrintAndLogEx(SUCCESS, "Found a default password:" _GREEN_("%s") " || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1445,7 +1450,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
|
||||||
key = default_pwd_pack[i];
|
key = default_pwd_pack[i];
|
||||||
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
len = ulev1_requestAuthentication(key, pack, sizeof(pack));
|
||||||
if (len > -1) {
|
if (len > -1) {
|
||||||
PrintAndLogEx(SUCCESS, "Found a default password: %s || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]);
|
PrintAndLogEx(SUCCESS, "Found a default password:" _GREEN_("%s") " || Pack: %02X %02X", sprint_hex(key, 4), pack[0], pack[1]);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT;
|
if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT;
|
||||||
|
|
|
@ -532,7 +532,7 @@ static int CmdPing(const char *Cmd) {
|
||||||
error = memcmp(data, resp.data.asBytes, len) != 0;
|
error = memcmp(data, resp.data.asBytes, len) != 0;
|
||||||
PrintAndLogEx((error) ? ERR : SUCCESS, "Ping response " _GREEN_("received") "and content is %s", error ? _RED_("NOT ok") : _GREEN_("ok"));
|
PrintAndLogEx((error) ? ERR : SUCCESS, "Ping response " _GREEN_("received") "and content is %s", error ? _RED_("NOT ok") : _GREEN_("ok"));
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx((error) ? ERR : SUCCESS, "Ping response " _GREEN_("received"));
|
PrintAndLogEx(SUCCESS, "Ping response " _GREEN_("received"));
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
PrintAndLogEx(WARNING, "Ping response " _RED_("timeout"));
|
PrintAndLogEx(WARNING, "Ping response " _RED_("timeout"));
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include "cmdlfpac.h" // for pac menu
|
#include "cmdlfpac.h" // for pac menu
|
||||||
#include "cmdlfkeri.h" // for keri menu
|
#include "cmdlfkeri.h" // for keri menu
|
||||||
#include "cmdlfverichip.h" // for VeriChip menu
|
#include "cmdlfverichip.h" // for VeriChip menu
|
||||||
|
#include "cmdlfgallagher.h" // for GALLAGHER menu
|
||||||
|
|
||||||
bool g_lf_threshold_set = false;
|
bool g_lf_threshold_set = false;
|
||||||
|
|
||||||
|
@ -1138,18 +1139,17 @@ static bool CheckChipType(bool getDeviceData) {
|
||||||
//check for em4x05/em4x69 chips first
|
//check for em4x05/em4x69 chips first
|
||||||
uint32_t word = 0;
|
uint32_t word = 0;
|
||||||
if (EM4x05IsBlock0(&word)) {
|
if (EM4x05IsBlock0(&word)) {
|
||||||
PrintAndLogEx(SUCCESS, "\nChipset detection : " _GREEN_("EM4x05/EM4x69") "found");
|
PrintAndLogEx(SUCCESS, "Chipset detection: " _GREEN_("EM4x05/EM4x69"));
|
||||||
PrintAndLogEx(SUCCESS, "Try " _YELLOW_("`lf em 4x05`") " commands");
|
PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf em 4x05`") "commands");
|
||||||
retval = true;
|
retval = true;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check for t55xx chip...
|
//check for t55xx chip...
|
||||||
if (tryDetectP1(true)) {
|
if (tryDetectP1(true)) {
|
||||||
PrintAndLogEx(SUCCESS, "\nChipset detection : " _GREEN_("T55xx") "found");
|
PrintAndLogEx(SUCCESS, "Chipset detection: " _GREEN_("T55xx"));
|
||||||
PrintAndLogEx(SUCCESS, "Try " _YELLOW_("`lf t55xx`")"commands");
|
PrintAndLogEx(INFO, "Hint: try " _YELLOW_("`lf t55xx`") "commands");
|
||||||
retval = true;
|
retval = true;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -1183,7 +1183,8 @@ int CmdLFfind(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, "if it finds something that looks like a tag");
|
PrintAndLogEx(INFO, "if it finds something that looks like a tag");
|
||||||
PrintAndLogEx(INFO, "False Positives " _YELLOW_("ARE") "possible");
|
PrintAndLogEx(INFO, "False Positives " _YELLOW_("ARE") "possible");
|
||||||
PrintAndLogEx(INFO, "");
|
PrintAndLogEx(INFO, "");
|
||||||
PrintAndLogEx(INFO, "Checking for known tags...\n");
|
PrintAndLogEx(INFO, "Checking for known tags...");
|
||||||
|
PrintAndLogEx(INFO, "");
|
||||||
|
|
||||||
// only run these tests if device is online
|
// only run these tests if device is online
|
||||||
if (isOnline) {
|
if (isOnline) {
|
||||||
|
@ -1196,7 +1197,8 @@ int CmdLFfind(const char *Cmd) {
|
||||||
}
|
}
|
||||||
if (readCOTAGUid()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("COTAG ID") "found!"); return PM3_SUCCESS;}
|
if (readCOTAGUid()) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("COTAG ID") "found!"); return PM3_SUCCESS;}
|
||||||
|
|
||||||
PrintAndLogEx(FAILED, "\n" _YELLOW_("No data found!") " - Signal looks like noise. Maybe not an LF tag?");
|
PrintAndLogEx(FAILED, _RED_("No data found!"));
|
||||||
|
PrintAndLogEx(INFO, "Signal looks like noise. Maybe not an LF tag?");
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1225,6 +1227,7 @@ int CmdLFfind(const char *Cmd) {
|
||||||
if (demodSecurakey() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Securakey ID") "found!"); goto out;}
|
if (demodSecurakey() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Securakey ID") "found!"); goto out;}
|
||||||
if (demodViking() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Viking ID") "found!"); goto out;}
|
if (demodViking() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Viking ID") "found!"); goto out;}
|
||||||
if (demodVisa2k() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Visa2000 ID") "found!"); goto out;}
|
if (demodVisa2k() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Visa2000 ID") "found!"); goto out;}
|
||||||
|
if (demodGallagher() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("GALLAGHER ID") "found!"); goto out;}
|
||||||
// if (demodTI() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Texas Instrument ID") "found!"); goto out;}
|
// if (demodTI() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Texas Instrument ID") "found!"); goto out;}
|
||||||
// if (demodVerichip() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("VeriChip ID") "found!"); goto out;}
|
// if (demodVerichip() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("VeriChip ID") "found!"); goto out;}
|
||||||
//if (demodFermax() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Fermax ID") "found!"); goto out;}
|
//if (demodFermax() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Fermax ID") "found!"); goto out;}
|
||||||
|
@ -1283,6 +1286,7 @@ static command_t CommandTable[] = {
|
||||||
{"cotag", CmdLFCOTAG, AlwaysAvailable, "{ COTAG CHIPs... }"},
|
{"cotag", CmdLFCOTAG, AlwaysAvailable, "{ COTAG CHIPs... }"},
|
||||||
{"em", CmdLFEM4X, AlwaysAvailable, "{ EM4X CHIPs & RFIDs... }"},
|
{"em", CmdLFEM4X, AlwaysAvailable, "{ EM4X CHIPs & RFIDs... }"},
|
||||||
{"fdx", CmdLFFdx, AlwaysAvailable, "{ FDX-B RFIDs... }"},
|
{"fdx", CmdLFFdx, AlwaysAvailable, "{ FDX-B RFIDs... }"},
|
||||||
|
{"gallagher", CmdLFGallagher, AlwaysAvailable, "{ GALLAGHER RFIDs... }"},
|
||||||
{"gproxii", CmdLFGuard, AlwaysAvailable, "{ Guardall Prox II RFIDs... }"},
|
{"gproxii", CmdLFGuard, AlwaysAvailable, "{ Guardall Prox II RFIDs... }"},
|
||||||
{"hid", CmdLFHID, AlwaysAvailable, "{ HID RFIDs... }"},
|
{"hid", CmdLFHID, AlwaysAvailable, "{ HID RFIDs... }"},
|
||||||
{"hitag", CmdLFHitag, AlwaysAvailable, "{ Hitag CHIPs... }"},
|
{"hitag", CmdLFHitag, AlwaysAvailable, "{ Hitag CHIPs... }"},
|
||||||
|
|
|
@ -219,7 +219,7 @@ static int CmdAWIDDemod(const char *Cmd) {
|
||||||
else if (idx == -4)
|
else if (idx == -4)
|
||||||
PrintAndLogEx(DEBUG, "DEBUG: Error - AWID preamble not found");
|
PrintAndLogEx(DEBUG, "DEBUG: Error - AWID preamble not found");
|
||||||
else if (idx == -5)
|
else if (idx == -5)
|
||||||
PrintAndLogEx(DEBUG, "DEBUG: Error - AWID size not correct, size %d", size);
|
PrintAndLogEx(DEBUG, "DEBUG: Error - AWID size not correct, size %zu", size);
|
||||||
else
|
else
|
||||||
PrintAndLogEx(DEBUG, "DEBUG: Error - AWID error demoding fsk %d", idx);
|
PrintAndLogEx(DEBUG, "DEBUG: Error - AWID error demoding fsk %d", idx);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Authored by Iceman
|
// Iceman
|
||||||
//
|
//
|
||||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
@ -17,6 +17,7 @@
|
||||||
#include "lfdemod.h"
|
#include "lfdemod.h"
|
||||||
#include "cmddata.h" // getSamples
|
#include "cmddata.h" // getSamples
|
||||||
#include "ui.h" // PrintAndLog
|
#include "ui.h" // PrintAndLog
|
||||||
|
#include "ctype.h" // tolower
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
@ -78,7 +79,7 @@ static int CmdCOTAGDemod(const char *Cmd) {
|
||||||
// 2 = raw signal - maxlength bigbuff
|
// 2 = raw signal - maxlength bigbuff
|
||||||
static int CmdCOTAGRead(const char *Cmd) {
|
static int CmdCOTAGRead(const char *Cmd) {
|
||||||
|
|
||||||
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_cotag_read();
|
if ( tolower(Cmd[0]) == 'h') return usage_lf_cotag_read();
|
||||||
|
|
||||||
uint32_t rawsignal = 1;
|
uint32_t rawsignal = 1;
|
||||||
sscanf(Cmd, "%u", &rawsignal);
|
sscanf(Cmd, "%u", &rawsignal);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Authored by Iceman
|
// Iceman
|
||||||
//
|
//
|
||||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
|
|
@ -401,7 +401,7 @@ int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo) {
|
||||||
else if (ans == -4)
|
else if (ans == -4)
|
||||||
PrintAndLogEx(DEBUG, "DEBUG: Error - Em410x preamble not found");
|
PrintAndLogEx(DEBUG, "DEBUG: Error - Em410x preamble not found");
|
||||||
else if (ans == -5)
|
else if (ans == -5)
|
||||||
PrintAndLogEx(DEBUG, "DEBUG: Error - Em410x Size not correct: %d", size);
|
PrintAndLogEx(DEBUG, "DEBUG: Error - Em410x Size not correct: %zu", size);
|
||||||
else if (ans == -6)
|
else if (ans == -6)
|
||||||
PrintAndLogEx(DEBUG, "DEBUG: Error - Em410x parity failed");
|
PrintAndLogEx(DEBUG, "DEBUG: Error - Em410x parity failed");
|
||||||
|
|
||||||
|
@ -692,7 +692,7 @@ static int CmdEM410xWrite(const char *Cmd) {
|
||||||
// the clock rate in bits 8-15 of the card value
|
// the clock rate in bits 8-15 of the card value
|
||||||
card = (card & 0xFF) | ((clock1 << 8) & 0xFF00);
|
card = (card & 0xFF) | ((clock1 << 8) & 0xFF00);
|
||||||
} else if (card == 0) {
|
} else if (card == 0) {
|
||||||
PrintAndLogEx(SUCCESS, "Writing %s tag with UID 0x%010" PRIx64, "T5555", id, clock1);
|
PrintAndLogEx(SUCCESS, "Writing %s tag with UID 0x%010" PRIx64 "(clock rate: %d)", "T5555", id, clock1);
|
||||||
card = (card & 0xFF) | ((clock1 << 8) & 0xFF00);
|
card = (card & 0xFF) | ((clock1 << 8) & 0xFF00);
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(FAILED, "Error! Bad card type selected.\n");
|
PrintAndLogEx(FAILED, "Error! Bad card type selected.\n");
|
||||||
|
|
|
@ -204,7 +204,7 @@ static int CmdFdxDemod(const char *Cmd) {
|
||||||
else if (preambleIndex == -2)
|
else if (preambleIndex == -2)
|
||||||
PrintAndLogEx(DEBUG, "DEBUG: Error - FDX-B preamble not found");
|
PrintAndLogEx(DEBUG, "DEBUG: Error - FDX-B preamble not found");
|
||||||
else if (preambleIndex == -3)
|
else if (preambleIndex == -3)
|
||||||
PrintAndLogEx(DEBUG, "DEBUG: Error - FDX-B Size not correct: %d", size);
|
PrintAndLogEx(DEBUG, "DEBUG: Error - FDX-B Size not correct: %zu", size);
|
||||||
else
|
else
|
||||||
PrintAndLogEx(DEBUG, "DEBUG: Error - FDX-B ans: %d", preambleIndex);
|
PrintAndLogEx(DEBUG, "DEBUG: Error - FDX-B ans: %d", preambleIndex);
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
|
@ -216,7 +216,7 @@ static int CmdFdxDemod(const char *Cmd) {
|
||||||
// remove marker bits (1's every 9th digit after preamble) (pType = 2)
|
// remove marker bits (1's every 9th digit after preamble) (pType = 2)
|
||||||
size = removeParity(DemodBuffer, 11, 9, 2, 117);
|
size = removeParity(DemodBuffer, 11, 9, 2, 117);
|
||||||
if (size != 104) {
|
if (size != 104) {
|
||||||
PrintAndLogEx(DEBUG, "DEBUG: Error - FDX-B error removeParity: %d", size);
|
PrintAndLogEx(DEBUG, "DEBUG: Error - FDX-B error removeParity: %zu", size);
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
175
client/cmdlfgallagher.c
Normal file
175
client/cmdlfgallagher.c
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Iceman, 2019
|
||||||
|
//
|
||||||
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
// the license.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Low frequency GALLAGHER tag commands
|
||||||
|
// NRZ, RF/32, 128 bits long (unknown cs)
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
#include "cmdlfgallagher.h"
|
||||||
|
|
||||||
|
#include <ctype.h> //tolower
|
||||||
|
|
||||||
|
#include "commonutil.h" // ARRAYLEN
|
||||||
|
#include "common.h"
|
||||||
|
#include "cmdparser.h" // command_t
|
||||||
|
#include "comms.h"
|
||||||
|
#include "ui.h"
|
||||||
|
#include "cmddata.h"
|
||||||
|
#include "cmdlf.h"
|
||||||
|
#include "lfdemod.h" // preamble test
|
||||||
|
#include "protocols.h" // t55xx defines
|
||||||
|
#include "cmdlft55xx.h" // clone..
|
||||||
|
|
||||||
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
static int usage_lf_gallagher_clone(void) {
|
||||||
|
PrintAndLogEx(NORMAL, "clone a GALLAGHER tag to a T55x7 tag.");
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
PrintAndLogEx(NORMAL, "Usage: lf gallagher clone [h] [b <raw hex>]");
|
||||||
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
|
PrintAndLogEx(NORMAL, " h : this help");
|
||||||
|
PrintAndLogEx(NORMAL, " b <raw hex> : raw hex data. 12 bytes max");
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
|
PrintAndLogEx(NORMAL, " lf gallagher clone b 0FFD5461A9DA1346B2D1AC32 ");
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
//see ASK/MAN Demod for what args are accepted
|
||||||
|
static int CmdGallagherDemod(const char *Cmd) {
|
||||||
|
|
||||||
|
(void)Cmd;
|
||||||
|
bool st = true;
|
||||||
|
if (ASKDemod_ext("32 0 0 0", false, false, 1, &st) != PM3_SUCCESS) {
|
||||||
|
PrintAndLogEx(DEBUG, "DEBUG: Error - GALLAGHER: ASKDemod failed");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size = DemodBufferLen;
|
||||||
|
int ans = detectGallagher(DemodBuffer, &size);
|
||||||
|
if (ans < 0) {
|
||||||
|
if (ans == -1)
|
||||||
|
PrintAndLogEx(DEBUG, "DEBUG: Error - GALLAGHER: too few bits found");
|
||||||
|
else if (ans == -2)
|
||||||
|
PrintAndLogEx(DEBUG, "DEBUG: Error - GALLAGHER: preamble not found");
|
||||||
|
else if (ans == -3)
|
||||||
|
PrintAndLogEx(DEBUG, "DEBUG: Error - GALLAGHER: Size not correct: %zu", size);
|
||||||
|
else
|
||||||
|
PrintAndLogEx(DEBUG, "DEBUG: Error - GALLAGHER: ans: %d", ans);
|
||||||
|
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
setDemodBuff(DemodBuffer, 96, ans);
|
||||||
|
setClockGrid(g_DemodClock, g_DemodStartIdx + (ans * g_DemodClock));
|
||||||
|
|
||||||
|
//got a good demod
|
||||||
|
uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32);
|
||||||
|
uint32_t raw2 = bytebits_to_byte(DemodBuffer + 32, 32);
|
||||||
|
uint32_t raw3 = bytebits_to_byte(DemodBuffer + 64, 32);
|
||||||
|
|
||||||
|
// preamble CS?
|
||||||
|
|
||||||
|
PrintAndLogEx(SUCCESS, "GALLAGHER Tag Found -- Raw: %08X%08X%08X", raw1, raw2, raw3);
|
||||||
|
PrintAndLogEx(INFO, "How the Raw ID is translated by the reader is unknown. Share your trace file on forum");
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CmdGallagherRead(const char *Cmd) {
|
||||||
|
lf_read(true, 4096 * 2 + 20);
|
||||||
|
return CmdGallagherDemod(Cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CmdGallagherClone(const char *Cmd) {
|
||||||
|
|
||||||
|
uint32_t blocks[4];
|
||||||
|
bool errors = false;
|
||||||
|
uint8_t cmdp = 0;
|
||||||
|
int datalen = 0;
|
||||||
|
|
||||||
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
|
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||||
|
case 'h':
|
||||||
|
return usage_lf_gallagher_clone();
|
||||||
|
case 'b': {
|
||||||
|
// skip first block, 3*4 = 12 bytes left
|
||||||
|
uint8_t rawhex[12] = {0};
|
||||||
|
int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen);
|
||||||
|
if ( res != 0 )
|
||||||
|
errors = true;
|
||||||
|
|
||||||
|
for(uint8_t i = 1; i < ARRAYLEN(blocks); i++) {
|
||||||
|
blocks[i] = bytes_to_num(rawhex + ( (i - 1) * 4 ), sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
|
errors = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errors || cmdp == 0) return usage_lf_gallagher_clone();
|
||||||
|
|
||||||
|
//Pac - compat mode, NRZ, data rate 40, 3 data blocks
|
||||||
|
blocks[0] = T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 3 << T55x7_MAXBLOCK_SHIFT;
|
||||||
|
|
||||||
|
PrintAndLogEx(INFO, "Preparing to clone Gallagher to T55x7 with raw hex");
|
||||||
|
print_blocks(blocks, ARRAYLEN(blocks));
|
||||||
|
|
||||||
|
return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CmdGallagherSim(const char *Cmd) {
|
||||||
|
|
||||||
|
// ASK/MAN sim.
|
||||||
|
PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static command_t CommandTable[] = {
|
||||||
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
|
{"demod", CmdGallagherDemod, AlwaysAvailable, "Demodulate an GALLAGHER tag from the GraphBuffer"},
|
||||||
|
{"read", CmdGallagherRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
|
||||||
|
{"clone", CmdGallagherClone, IfPm3Lf, "clone GALLAGHER tag"},
|
||||||
|
{"sim", CmdGallagherSim, IfPm3Lf, "simulate GALLAGHER tag"},
|
||||||
|
{NULL, NULL, NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int CmdHelp(const char *Cmd) {
|
||||||
|
(void)Cmd; // Cmd is not used so far
|
||||||
|
CmdsHelp(CommandTable);
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdLFGallagher(const char *Cmd) {
|
||||||
|
clearCommandBuffer();
|
||||||
|
return CmdsParse(CommandTable, Cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
// by marshmellow
|
||||||
|
// find PAC preamble in already demoded data
|
||||||
|
int detectGallagher(uint8_t *dest, size_t *size) {
|
||||||
|
if (*size < 96) return -1; //make sure buffer has data
|
||||||
|
size_t startIdx = 0;
|
||||||
|
uint8_t preamble[] = {
|
||||||
|
0, 0, 0, 0, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 0, 1,
|
||||||
|
0, 1, 0, 1, 0, 1, 0, 0,
|
||||||
|
0, 1, 1, 0, 0 ,0 ,0 ,1
|
||||||
|
};
|
||||||
|
if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx))
|
||||||
|
return -2; //preamble not found
|
||||||
|
if (*size != 96) return -3; //wrong demoded size
|
||||||
|
//return start position
|
||||||
|
return (int)startIdx;
|
||||||
|
}
|
||||||
|
|
||||||
|
int demodGallagher(void) {
|
||||||
|
return CmdGallagherDemod("");
|
||||||
|
}
|
||||||
|
|
20
client/cmdlfgallagher.h
Normal file
20
client/cmdlfgallagher.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Iceman, 2019
|
||||||
|
//
|
||||||
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
// the license.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Low frequency GALLAGHER tag commands
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
#ifndef CMDLFGALLAGHER_H__
|
||||||
|
#define CMDLFGALLAGHER_H__
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
int CmdLFGallagher(const char *Cmd);
|
||||||
|
|
||||||
|
int demodGallagher(void);
|
||||||
|
int detectGallagher(uint8_t *dest, size_t *size);
|
||||||
|
#endif
|
||||||
|
|
|
@ -246,7 +246,7 @@ static int CmdHIDDemod(const char *Cmd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(DEBUG, "DEBUG: HID idx: %d, Len: %d, Printing Demod Buffer:", idx, size);
|
PrintAndLogEx(DEBUG, "DEBUG: HID idx: %d, Len: %zu, Printing Demod Buffer:", idx, size);
|
||||||
if (g_debugMode)
|
if (g_debugMode)
|
||||||
printDemodBuff();
|
printDemodBuff();
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,10 @@ static int CmdIndalaDemod(const char *Cmd) {
|
||||||
//convert UID to HEX
|
//convert UID to HEX
|
||||||
uint32_t uid1 = bytebits_to_byte(DemodBuffer, 32);
|
uint32_t uid1 = bytebits_to_byte(DemodBuffer, 32);
|
||||||
uint32_t uid2 = bytebits_to_byte(DemodBuffer + 32, 32);
|
uint32_t uid2 = bytebits_to_byte(DemodBuffer + 32, 32);
|
||||||
uint64_t foo = (((uint64_t)uid1 << 32) & 0x1FFFFFFF) | (uid2 & 0x7FFFFFFF);
|
// To be checked, what's this internal ID ?
|
||||||
|
// foo is only used for 64b ids and in that case uid1 must be only preamble, plus the following code is wrong as x<<32 & 0x1FFFFFFF is always zero
|
||||||
|
//uint64_t foo = (((uint64_t)uid1 << 32) & 0x1FFFFFFF) | (uid2 & 0x7FFFFFFF);
|
||||||
|
uint64_t foo = uid2 & 0x7FFFFFFF;
|
||||||
|
|
||||||
if (DemodBufferLen == 64) {
|
if (DemodBufferLen == 64) {
|
||||||
PrintAndLogEx(
|
PrintAndLogEx(
|
||||||
|
|
|
@ -41,7 +41,7 @@ static int usage_lf_nedap_gen(void) {
|
||||||
PrintAndLogEx(NORMAL, " l : optional - long (128), default to short (64)");
|
PrintAndLogEx(NORMAL, " l : optional - long (128), default to short (64)");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, " lf nedap generate s 1 c 123 i 112233");
|
PrintAndLogEx(NORMAL, " lf nedap generate s 1 c 123 i 12345");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ static int usage_lf_nedap_clone(void) {
|
||||||
// PrintAndLogEx(NORMAL, " Q5 : optional - clone to Q5 (T5555) instead of T55x7 chip");
|
// PrintAndLogEx(NORMAL, " Q5 : optional - clone to Q5 (T5555) instead of T55x7 chip");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, " lf nedap clone s 1 c 123 i 112233");
|
PrintAndLogEx(NORMAL, " lf nedap clone s 1 c 123 i 12345");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3635,7 +3635,7 @@ static command_t CommandTable[] = {
|
||||||
{"dangerraw", CmdT55xxDangerousRaw, IfPm3Lf, "Sends raw bitstream. Dangerous, do not use!! b <bitstream> t <timing>"},
|
{"dangerraw", CmdT55xxDangerousRaw, IfPm3Lf, "Sends raw bitstream. Dangerous, do not use!! b <bitstream> t <timing>"},
|
||||||
{"detect", CmdT55xxDetect, AlwaysAvailable, "[1] Try detecting the tag modulation from reading the configuration block."},
|
{"detect", CmdT55xxDetect, AlwaysAvailable, "[1] Try detecting the tag modulation from reading the configuration block."},
|
||||||
{"deviceconfig", CmdT55xxSetDeviceConfig, IfPm3Lf, "Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap"},
|
{"deviceconfig", CmdT55xxSetDeviceConfig, IfPm3Lf, "Set/Get T55XX device configuration (startgap, writegap, write0, write1, readgap"},
|
||||||
{"dump", CmdT55xxDump, IfPm3Lf, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"},
|
{"dump", CmdT55xxDump, IfPm3Lf, "[password] [o] Dump T55xx card Page 0 block 0-7. Optional [password], [override]"},
|
||||||
{"restore", CmdT55xxRestore, IfPm3Lf, "f <filename> [p <password>] -- Restore a dump file of a T55xx card"},
|
{"restore", CmdT55xxRestore, IfPm3Lf, "f <filename> [p <password>] -- Restore a dump file of a T55xx card"},
|
||||||
{"info", CmdT55xxInfo, AlwaysAvailable, "[1] Show T55x7 configuration data (page 0/ blk 0)"},
|
{"info", CmdT55xxInfo, AlwaysAvailable, "[1] Show T55x7 configuration data (page 0/ blk 0)"},
|
||||||
{"p1detect", CmdT55xxDetectPage1, IfPm3Lf, "[1] Try detecting if this is a t55xx tag by reading page 1"},
|
{"p1detect", CmdT55xxDetectPage1, IfPm3Lf, "[1] Try detecting if this is a t55xx tag by reading page 1"},
|
||||||
|
|
|
@ -38,11 +38,11 @@
|
||||||
#define T55X7_INDALA_224_CONFIG_BLOCK 0x000810E0 // emulate indala 224 bit - compat mode, PSK1, psk carrier FC * 2, data rate 32, maxblock 7
|
#define T55X7_INDALA_224_CONFIG_BLOCK 0x000810E0 // emulate indala 224 bit - compat mode, PSK1, psk carrier FC * 2, data rate 32, maxblock 7
|
||||||
#define T55X7_GUARDPROXII_CONFIG_BLOCK 0x00150060 // bitrate 64pcb, Direct modulation, Biphase, 3 data blocks
|
#define T55X7_GUARDPROXII_CONFIG_BLOCK 0x00150060 // bitrate 64pcb, Direct modulation, Biphase, 3 data blocks
|
||||||
#define T55X7_VIKING_CONFIG_BLOCK 0x00088040 // ASK, compat mode, data rate 32, Manchester, 2 data blocks
|
#define T55X7_VIKING_CONFIG_BLOCK 0x00088040 // ASK, compat mode, data rate 32, Manchester, 2 data blocks
|
||||||
#define T55X7_NORALYS_CONFIG_BLOCK 0x00088C6A // ASK, compat mode, (NORALYS - KCP3000)
|
#define T55X7_NORALYS_CONFIG_BLOCK 0x00088C6A // ASK, compat mode, (NORALYS - KCP3000), 3 data blocks
|
||||||
#define T55X7_IOPROX_CONFIG_BLOCK 0x00147040 // ioprox - FSK2a, data rate 64, 2 data blocks
|
#define T55X7_IOPROX_CONFIG_BLOCK 0x00147040 // ioprox - FSK2a, data rate 64, 2 data blocks
|
||||||
#define T55X7_PRESCO_CONFIG_BLOCK 0x00088088 // ASK, data rate 32, Manchester, 5 data blocks, STT
|
#define T55X7_PRESCO_CONFIG_BLOCK 0x00088088 // ASK, data rate 32, Manchester, 4 data blocks, STT
|
||||||
#define T55X7_NEDAP_64_CONFIG_BLOCK 0x907f0042 // BiPhase, data rate 64, 3 data blocks
|
#define T55X7_NEDAP_64_CONFIG_BLOCK 0x907f0042 // BiPhase, data rate 64, 2 data blocks
|
||||||
#define T55X7_NEDAP_128_CONFIG_BLOCK 0x907f0082 // BiPhase, data rate 64, 5 data blocks
|
#define T55X7_NEDAP_128_CONFIG_BLOCK 0x907f0082 // BiPhase, data rate 64, 4 data blocks
|
||||||
|
|
||||||
#define T55X7_bin 0b0010
|
#define T55X7_bin 0b0010
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ bool testKnownConfigBlock(uint32_t block0);
|
||||||
bool tryDetectP1(bool getData);
|
bool tryDetectP1(bool getData);
|
||||||
bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5);
|
bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5);
|
||||||
int special(const char *Cmd);
|
int special(const char *Cmd);
|
||||||
bool AquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password, uint8_t downlink_mode);
|
bool AcquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password, uint8_t downlink_mode);
|
||||||
uint8_t tryOnePassword(uint32_t password, uint8_t downlink_mode);
|
uint8_t tryOnePassword(uint32_t password, uint8_t downlink_mode);
|
||||||
|
|
||||||
void printT55x7Trace(t55x7_tracedata_t data, uint8_t repeat);
|
void printT55x7Trace(t55x7_tracedata_t data, uint8_t repeat);
|
||||||
|
|
|
@ -55,7 +55,7 @@ static int CmdScriptRun(const char *Cmd) {
|
||||||
static uint8_t luascriptfile_idx = 0;
|
static uint8_t luascriptfile_idx = 0;
|
||||||
sscanf(Cmd, "%127s%n %255[^\n\r]%n", preferredName, &name_len, arguments, &arg_len);
|
sscanf(Cmd, "%127s%n %255[^\n\r]%n", preferredName, &name_len, arguments, &arg_len);
|
||||||
|
|
||||||
char *script_path;
|
char *script_path = NULL;
|
||||||
if ((!str_endswith(preferredName, ".cmd")) && (searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", true) == PM3_SUCCESS)) {
|
if ((!str_endswith(preferredName, ".cmd")) && (searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", true) == PM3_SUCCESS)) {
|
||||||
int error;
|
int error;
|
||||||
if (luascriptfile_idx == MAX_NESTED_LUASCRIPT) {
|
if (luascriptfile_idx == MAX_NESTED_LUASCRIPT) {
|
||||||
|
@ -121,6 +121,7 @@ static int CmdScriptRun(const char *Cmd) {
|
||||||
int ret = PM3_EUNDEF;
|
int ret = PM3_EUNDEF;
|
||||||
if (!str_endswith(preferredName, ".cmd")) ret = searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", false);
|
if (!str_endswith(preferredName, ".cmd")) ret = searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", false);
|
||||||
if (!str_endswith(preferredName, ".lua")) ret = searchFile(&script_path, CMD_SCRIPTS_SUBDIR, preferredName, ".cmd", false);
|
if (!str_endswith(preferredName, ".lua")) ret = searchFile(&script_path, CMD_SCRIPTS_SUBDIR, preferredName, ".cmd", false);
|
||||||
|
free(script_path);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -153,6 +153,8 @@ static uint16_t printHexLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trac
|
||||||
return tracepos;
|
return tracepos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t ret;
|
||||||
|
|
||||||
switch (protocol) {
|
switch (protocol) {
|
||||||
case ISO_14443A: {
|
case ISO_14443A: {
|
||||||
/* https://www.kaiser.cx/pcap-iso14443.html defines a pseudo header:
|
/* https://www.kaiser.cx/pcap-iso14443.html defines a pseudo header:
|
||||||
|
@ -185,16 +187,16 @@ static uint16_t printHexLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trac
|
||||||
temp_str1,
|
temp_str1,
|
||||||
temp_str2,
|
temp_str2,
|
||||||
line);
|
line);
|
||||||
return tracepos;
|
ret = tracepos;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
PrintAndLogEx(NORMAL, "Currently only 14a supported");
|
PrintAndLogEx(NORMAL, "Currently only 14a supported");
|
||||||
return traceLen;
|
ret = traceLen;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_last_record(tracepos, trace, traceLen)) return traceLen;
|
return ret;
|
||||||
|
|
||||||
return tracepos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles, bool markCRCBytes) {
|
static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles, bool markCRCBytes) {
|
||||||
|
@ -840,8 +842,6 @@ int CmdTraceList(const char *Cmd) {
|
||||||
PrintAndLogEx(NORMAL, "ISO15693 - Timings are not as accurate");
|
PrintAndLogEx(NORMAL, "ISO15693 - Timings are not as accurate");
|
||||||
if (protocol == ISO_7816_4)
|
if (protocol == ISO_7816_4)
|
||||||
PrintAndLogEx(NORMAL, "ISO7816-4 / Smartcard - Timings N/A yet");
|
PrintAndLogEx(NORMAL, "ISO7816-4 / Smartcard - Timings N/A yet");
|
||||||
if (protocol == FELICA)
|
|
||||||
PrintAndLogEx(NORMAL, "Felica"); // Timings ?
|
|
||||||
if (protocol == PROTO_HITAG)
|
if (protocol == PROTO_HITAG)
|
||||||
PrintAndLogEx(NORMAL, "Hitag2 / HitagS - Timings in ETU (8us)");
|
PrintAndLogEx(NORMAL, "Hitag2 / HitagS - Timings in ETU (8us)");
|
||||||
|
|
||||||
|
|
|
@ -373,7 +373,7 @@ static int CmdUsartBtFactory(const char *Cmd) {
|
||||||
if (strcmp((char *)data, "OKsetname") == 0) {
|
if (strcmp((char *)data, "OKsetname") == 0) {
|
||||||
PrintAndLogEx(SUCCESS, "Name set to " _GREEN_("PM3_RDV4.0"));
|
PrintAndLogEx(SUCCESS, "Name set to " _GREEN_("PM3_RDV4.0"));
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(WARNING, "Unexpected response to AT+NAME: " _YELLOW_("%.*s"), len, data);
|
PrintAndLogEx(WARNING, "Unexpected response to AT+NAME: " _YELLOW_("%.*s"), (int)len, data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(WARNING, "Lost contact with add-on, please try again");
|
PrintAndLogEx(WARNING, "Lost contact with add-on, please try again");
|
||||||
|
@ -391,7 +391,7 @@ static int CmdUsartBtFactory(const char *Cmd) {
|
||||||
if (strcmp((char *)data, "OK+ROLE:S") == 0) {
|
if (strcmp((char *)data, "OK+ROLE:S") == 0) {
|
||||||
PrintAndLogEx(SUCCESS, "Role set to " _GREEN_("Slave"));
|
PrintAndLogEx(SUCCESS, "Role set to " _GREEN_("Slave"));
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(WARNING, "Unexpected response to AT+ROLE=S: " _YELLOW_("%.*s"), len, data);
|
PrintAndLogEx(WARNING, "Unexpected response to AT+ROLE=S: " _YELLOW_("%.*s"), (int)len, data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(WARNING, "Lost contact with add-on, please try again");
|
PrintAndLogEx(WARNING, "Lost contact with add-on, please try again");
|
||||||
|
@ -409,7 +409,7 @@ static int CmdUsartBtFactory(const char *Cmd) {
|
||||||
if (strcmp((char *)data, "OKsetPIN") == 0) {
|
if (strcmp((char *)data, "OKsetPIN") == 0) {
|
||||||
PrintAndLogEx(SUCCESS, "PIN set to " _GREEN_("1234"));
|
PrintAndLogEx(SUCCESS, "PIN set to " _GREEN_("1234"));
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(WARNING, "Unexpected response to AT+PIN: " _YELLOW_("%.*s"), len, data);
|
PrintAndLogEx(WARNING, "Unexpected response to AT+PIN: " _YELLOW_("%.*s"), (int)len, data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(WARNING, "Lost contact with add-on, please try again");
|
PrintAndLogEx(WARNING, "Lost contact with add-on, please try again");
|
||||||
|
@ -429,7 +429,7 @@ static int CmdUsartBtFactory(const char *Cmd) {
|
||||||
if (strcmp((char *)data, "OK None") == 0) {
|
if (strcmp((char *)data, "OK None") == 0) {
|
||||||
PrintAndLogEx(SUCCESS, "Parity set to " _GREEN_("None"));
|
PrintAndLogEx(SUCCESS, "Parity set to " _GREEN_("None"));
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(WARNING, "Unexpected response to AT+P: " _YELLOW_("%.*s"), len, data);
|
PrintAndLogEx(WARNING, "Unexpected response to AT+P: " _YELLOW_("%.*s"), (int)len, data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(WARNING, "Lost contact with add-on, please try again");
|
PrintAndLogEx(WARNING, "Lost contact with add-on, please try again");
|
||||||
|
@ -449,7 +449,7 @@ static int CmdUsartBtFactory(const char *Cmd) {
|
||||||
if (strcmp((char *)data, "OK" BTADDON_BAUD_NUM) == 0) {
|
if (strcmp((char *)data, "OK" BTADDON_BAUD_NUM) == 0) {
|
||||||
PrintAndLogEx(SUCCESS, "Baudrate set to " _GREEN_(BTADDON_BAUD_NUM));
|
PrintAndLogEx(SUCCESS, "Baudrate set to " _GREEN_(BTADDON_BAUD_NUM));
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(WARNING, "Unexpected response to AT+BAUD: " _YELLOW_("%.*s"), len, data);
|
PrintAndLogEx(WARNING, "Unexpected response to AT+BAUD: " _YELLOW_("%.*s"), (int)len, data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(WARNING, "Lost contact with add-on, please try again");
|
PrintAndLogEx(WARNING, "Lost contact with add-on, please try again");
|
||||||
|
@ -505,30 +505,33 @@ static int CmdUsartBtPin(const char *Cmd) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Validations
|
//Validations
|
||||||
if (errors || cmdp == 0) {
|
if (errors || cmdp == 0) {
|
||||||
usage_usart_bt_pin();
|
usage_usart_bt_pin();
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
char string[6 + sizeof(pin)] = {0};
|
char string[6 + sizeof(pin)] = {0};
|
||||||
sprintf(string, "AT+PIN%s", pin);
|
sprintf(string, "AT+PIN%s", pin);
|
||||||
uint8_t data[PM3_CMD_DATA_SIZE] = {0x00};
|
uint8_t data[PM3_CMD_DATA_SIZE] = {0x00};
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
// PrintAndLogEx(NORMAL, "TX (%3zu):%.*s", strlen(string), (int)strlen(string), string);
|
|
||||||
int ret = usart_txrx((uint8_t *)string, strlen(string), data, &len, 600);
|
int ret = usart_txrx((uint8_t *)string, strlen(string), data, &len, 600);
|
||||||
|
|
||||||
if (ret == PM3_ENODATA) {
|
if (ret == PM3_ENODATA) {
|
||||||
PrintAndLogEx(FAILED, "No response from add-on, is it ON and blinking?");
|
PrintAndLogEx(FAILED, "No response from add-on, is it ON and blinking?");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != PM3_SUCCESS) {
|
if (ret != PM3_SUCCESS) {
|
||||||
PrintAndLogEx(FAILED, "Command failed, ret=%i", ret);
|
PrintAndLogEx(FAILED, "Command failed, ret=%i", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
// PrintAndLogEx(NORMAL, "RX (%3zu):%.*s", len, (int)len, data);
|
|
||||||
if (strcmp((char *)data, "OKsetPIN") == 0) {
|
if (strcmp((char *)data, "OKsetPIN") == 0) {
|
||||||
PrintAndLogEx(NORMAL, "PIN changed " _GREEN_("successfully"));
|
PrintAndLogEx(NORMAL, "PIN changed " _GREEN_("successfully"));
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(WARNING, "Unexpected answer: %.*s", len, data);
|
PrintAndLogEx(WARNING, "Unexpected answer: %.*s", (int)len, data);
|
||||||
}
|
}
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -621,7 +624,7 @@ static int CmdUsartRX(const char *Cmd) {
|
||||||
int ret = usart_rx(data, &len, waittime);
|
int ret = usart_rx(data, &len, waittime);
|
||||||
if (ret != PM3_SUCCESS)
|
if (ret != PM3_SUCCESS)
|
||||||
return ret;
|
return ret;
|
||||||
PrintAndLogEx(NORMAL, "RX:%.*s", len, data);
|
PrintAndLogEx(NORMAL, "RX:%.*s", (int)len, data);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -260,6 +260,7 @@ static unsigned char *crypto_pk_polarssl_get_parameter(const struct crypto_pk *_
|
||||||
res = mbedtls_mpi_write_binary(&cp->ctx.N, result, *plen);
|
res = mbedtls_mpi_write_binary(&cp->ctx.N, result, *plen);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
printf("Error write_binary.");
|
printf("Error write_binary.");
|
||||||
|
free(result);
|
||||||
result = 0;
|
result = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -271,6 +272,7 @@ static unsigned char *crypto_pk_polarssl_get_parameter(const struct crypto_pk *_
|
||||||
res = mbedtls_mpi_write_binary(&cp->ctx.E, result, *plen);
|
res = mbedtls_mpi_write_binary(&cp->ctx.E, result, *plen);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
printf("Error write_binary.");
|
printf("Error write_binary.");
|
||||||
|
free(result);
|
||||||
result = 0;
|
result = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -42,14 +42,14 @@
|
||||||
|
|
||||||
#define TOHEX(v) ((v) < 10 ? (v) + '0' : (v) - 10 + 'a')
|
#define TOHEX(v) ((v) < 10 ? (v) + '0' : (v) - 10 + 'a')
|
||||||
|
|
||||||
static ssize_t emv_pk_read_bin(char *buf, unsigned char *bin, size_t size, size_t *read) {
|
static ssize_t emv_pk_read_bin(char *buf, size_t buflen, unsigned char *bin, size_t size, size_t *read) {
|
||||||
|
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
size_t left = size;
|
size_t left = size;
|
||||||
char *p = buf;
|
char *p = buf;
|
||||||
while (*p == ' ')
|
while ((*p == ' ') && (p < (buf + buflen - 1)))
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
while (left > 0) {
|
while (left > 0) {
|
||||||
|
@ -57,15 +57,19 @@ static ssize_t emv_pk_read_bin(char *buf, unsigned char *bin, size_t size, size_
|
||||||
c1 = HEX(*p);
|
c1 = HEX(*p);
|
||||||
if (c1 == -1)
|
if (c1 == -1)
|
||||||
return -(p - buf);
|
return -(p - buf);
|
||||||
|
if (p == (buf + buflen - 1))
|
||||||
|
return -(p - buf);
|
||||||
p++;
|
p++;
|
||||||
c2 = HEX(*p);
|
c2 = HEX(*p);
|
||||||
if (c2 == -1)
|
if (c2 == -1)
|
||||||
return -(p - buf);
|
return -(p - buf);
|
||||||
|
if (p == (buf + buflen - 1))
|
||||||
|
return -(p - buf);
|
||||||
p++;
|
p++;
|
||||||
*bin = (c1 * 16 + c2);
|
*bin = (c1 * 16 + c2);
|
||||||
bin ++;
|
bin ++;
|
||||||
left --;
|
left --;
|
||||||
if (*p == ':')
|
if ((*p == ':') && (p < (buf + buflen - 1)))
|
||||||
p++;
|
p++;
|
||||||
else if (read) {
|
else if (read) {
|
||||||
*read = (size - left);
|
*read = (size - left);
|
||||||
|
@ -76,7 +80,7 @@ static ssize_t emv_pk_read_bin(char *buf, unsigned char *bin, size_t size, size_
|
||||||
return -(p - buf);
|
return -(p - buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*p == ' ')
|
while ((*p == ' ') && (p < (buf + buflen - 1)))
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
p--;
|
p--;
|
||||||
|
@ -84,7 +88,7 @@ static ssize_t emv_pk_read_bin(char *buf, unsigned char *bin, size_t size, size_
|
||||||
return (p - buf);
|
return (p - buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t emv_pk_read_ymv(char *buf, unsigned *ymv) {
|
static ssize_t emv_pk_read_ymv(char *buf, size_t buflen, unsigned *ymv) {
|
||||||
|
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -95,7 +99,7 @@ static ssize_t emv_pk_read_ymv(char *buf, unsigned *ymv) {
|
||||||
|
|
||||||
*ymv = 0;
|
*ymv = 0;
|
||||||
|
|
||||||
while (*p == ' ')
|
while ((*p == ' ') && (p < (buf + buflen - 1)))
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
|
@ -103,15 +107,19 @@ static ssize_t emv_pk_read_ymv(char *buf, unsigned *ymv) {
|
||||||
c1 = BCD(*p);
|
c1 = BCD(*p);
|
||||||
if (c1 == -1)
|
if (c1 == -1)
|
||||||
return -(p - buf);
|
return -(p - buf);
|
||||||
|
if (p == (buf + buflen - 1))
|
||||||
|
return -(p - buf);
|
||||||
p++;
|
p++;
|
||||||
c2 = BCD(*p);
|
c2 = BCD(*p);
|
||||||
if (c2 == -1)
|
if (c2 == -1)
|
||||||
return -(p - buf);
|
return -(p - buf);
|
||||||
|
if (p == (buf + buflen - 1))
|
||||||
|
return -(p - buf);
|
||||||
p++;
|
p++;
|
||||||
temp[i] = (c1 * 16 + c2);
|
temp[i] = (c1 * 16 + c2);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (*p == ' ')
|
while ((*p == ' ') && (p < (buf + buflen - 1)))
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
p--;
|
p--;
|
||||||
|
@ -124,13 +132,13 @@ static ssize_t emv_pk_read_ymv(char *buf, unsigned *ymv) {
|
||||||
return (p - buf);
|
return (p - buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t emv_pk_read_string(char *buf, char *str, size_t size) {
|
static ssize_t emv_pk_read_string(char *buf, size_t buflen, char *str, size_t size) {
|
||||||
|
|
||||||
if (buf == NULL)
|
if (buf == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
char *p = buf;
|
char *p = buf;
|
||||||
while (*p == ' ')
|
while ((*p == ' ') && (p < (buf + buflen - 1)))
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
while (size > 1) {
|
while (size > 1) {
|
||||||
|
@ -139,6 +147,8 @@ static ssize_t emv_pk_read_string(char *buf, char *str, size_t size) {
|
||||||
else if (*p < 0x20 || *p >= 0x7f)
|
else if (*p < 0x20 || *p >= 0x7f)
|
||||||
return -(p - buf);
|
return -(p - buf);
|
||||||
*str = *p;
|
*str = *p;
|
||||||
|
if (p == (buf + buflen - 1))
|
||||||
|
return -(p - buf);
|
||||||
p++;
|
p++;
|
||||||
str ++;
|
str ++;
|
||||||
size --;
|
size --;
|
||||||
|
@ -146,7 +156,7 @@ static ssize_t emv_pk_read_string(char *buf, char *str, size_t size) {
|
||||||
|
|
||||||
*str = 0;
|
*str = 0;
|
||||||
|
|
||||||
while (*p == ' ')
|
while ((*p == ' ') && (p < (buf + buflen - 1)))
|
||||||
p++;
|
p++;
|
||||||
|
|
||||||
p--;
|
p--;
|
||||||
|
@ -155,27 +165,27 @@ static ssize_t emv_pk_read_string(char *buf, char *str, size_t size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct emv_pk *emv_pk_parse_pk(char *buf) {
|
struct emv_pk *emv_pk_parse_pk(char *buf, size_t buflen) {
|
||||||
struct emv_pk *r = calloc(1, sizeof(*r));
|
struct emv_pk *r = calloc(1, sizeof(*r));
|
||||||
ssize_t l;
|
ssize_t l;
|
||||||
char temp[10];
|
char temp[10];
|
||||||
|
|
||||||
l = emv_pk_read_bin(buf, r->rid, 5, NULL);
|
l = emv_pk_read_bin(buf, buflen, r->rid, 5, NULL);
|
||||||
if (l <= 0)
|
if (l <= 0)
|
||||||
goto out;
|
goto out;
|
||||||
buf += l;
|
buf += l;
|
||||||
|
|
||||||
l = emv_pk_read_bin(buf, &r->index, 1, NULL);
|
l = emv_pk_read_bin(buf, buflen, &r->index, 1, NULL);
|
||||||
if (l <= 0)
|
if (l <= 0)
|
||||||
goto out;
|
goto out;
|
||||||
buf += l;
|
buf += l;
|
||||||
|
|
||||||
l = emv_pk_read_ymv(buf, &r->expire);
|
l = emv_pk_read_ymv(buf, buflen, &r->expire);
|
||||||
if (l <= 0)
|
if (l <= 0)
|
||||||
goto out;
|
goto out;
|
||||||
buf += l;
|
buf += l;
|
||||||
|
|
||||||
l = emv_pk_read_string(buf, temp, sizeof(temp));
|
l = emv_pk_read_string(buf, buflen, temp, sizeof(temp));
|
||||||
if (l <= 0)
|
if (l <= 0)
|
||||||
goto out;
|
goto out;
|
||||||
buf += l;
|
buf += l;
|
||||||
|
@ -185,18 +195,18 @@ struct emv_pk *emv_pk_parse_pk(char *buf) {
|
||||||
else
|
else
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
l = emv_pk_read_bin(buf, r->exp, sizeof(r->exp), &r->elen);
|
l = emv_pk_read_bin(buf, buflen, r->exp, sizeof(r->exp), &r->elen);
|
||||||
if (l <= 0)
|
if (l <= 0)
|
||||||
goto out;
|
goto out;
|
||||||
buf += l;
|
buf += l;
|
||||||
|
|
||||||
r->modulus = malloc(2048 / 8);
|
r->modulus = malloc(2048 / 8);
|
||||||
l = emv_pk_read_bin(buf, r->modulus, 2048 / 8, &r->mlen);
|
l = emv_pk_read_bin(buf, buflen, r->modulus, 2048 / 8, &r->mlen);
|
||||||
if (l <= 0)
|
if (l <= 0)
|
||||||
goto out2;
|
goto out2;
|
||||||
buf += l;
|
buf += l;
|
||||||
|
|
||||||
l = emv_pk_read_string(buf, temp, sizeof(temp));
|
l = emv_pk_read_string(buf, buflen, temp, sizeof(temp));
|
||||||
if (l <= 0)
|
if (l <= 0)
|
||||||
goto out2;
|
goto out2;
|
||||||
buf += l;
|
buf += l;
|
||||||
|
@ -206,7 +216,7 @@ struct emv_pk *emv_pk_parse_pk(char *buf) {
|
||||||
else
|
else
|
||||||
goto out2;
|
goto out2;
|
||||||
|
|
||||||
l = emv_pk_read_bin(buf, r->hash, 20, NULL);
|
l = emv_pk_read_bin(buf, buflen, r->hash, 20, NULL);
|
||||||
if (l <= 0)
|
if (l <= 0)
|
||||||
goto out2;
|
goto out2;
|
||||||
|
|
||||||
|
@ -409,21 +419,20 @@ static struct emv_pk *emv_pk_get_ca_pk_from_file(const char *fname,
|
||||||
if (fgets(buf, sizeof(buf), f) == NULL)
|
if (fgets(buf, sizeof(buf), f) == NULL)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
struct emv_pk *pk = emv_pk_parse_pk(buf);
|
struct emv_pk *pk = emv_pk_parse_pk(buf, sizeof(buf));
|
||||||
if (!pk)
|
if (!pk)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (memcmp(pk->rid, rid, 5) || pk->index != idx) {
|
if (memcmp(pk->rid, rid, 5) || pk->index != idx) {
|
||||||
emv_pk_free(pk);
|
emv_pk_free(pk);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
return pk;
|
return pk;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ struct emv_pk {
|
||||||
|
|
||||||
#define EXPIRE(yy, mm, dd) 0x ## yy ## mm ## dd
|
#define EXPIRE(yy, mm, dd) 0x ## yy ## mm ## dd
|
||||||
|
|
||||||
struct emv_pk *emv_pk_parse_pk(char *buf);
|
struct emv_pk *emv_pk_parse_pk(char *bufm, size_t buflen);
|
||||||
struct emv_pk *emv_pk_new(size_t modlen, size_t explen);
|
struct emv_pk *emv_pk_new(size_t modlen, size_t explen);
|
||||||
void emv_pk_free(struct emv_pk *pk);
|
void emv_pk_free(struct emv_pk *pk);
|
||||||
char *emv_pk_dump_pk(const struct emv_pk *pk);
|
char *emv_pk_dump_pk(const struct emv_pk *pk);
|
||||||
|
|
|
@ -196,7 +196,6 @@ static struct tlvdb *emv_pki_sign_key(const struct crypto_pk *cp,
|
||||||
struct tlvdb *exp_db = tlvdb_fixed(exp_tag, ipk->elen, ipk->exp);
|
struct tlvdb *exp_db = tlvdb_fixed(exp_tag, ipk->elen, ipk->exp);
|
||||||
if (!exp_db) {
|
if (!exp_db) {
|
||||||
free(msg);
|
free(msg);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,8 +206,10 @@ static struct tlvdb *emv_pki_sign_key(const struct crypto_pk *cp,
|
||||||
add_tlv,
|
add_tlv,
|
||||||
NULL);
|
NULL);
|
||||||
free(msg);
|
free(msg);
|
||||||
if (!db)
|
if (!db) {
|
||||||
|
free(exp_db);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
tlvdb_add(db, exp_db);
|
tlvdb_add(db, exp_db);
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@ int JsonSaveJsonObject(json_t *root, const char *path, json_t *value) {
|
||||||
|
|
||||||
if (path[0] == '$') {
|
if (path[0] == '$') {
|
||||||
if (json_path_set(root, path, value, 0, &error)) {
|
if (json_path_set(root, path, value, 0, &error)) {
|
||||||
PrintAndLogEx(ERR, "ERROR: can't set json path: ", error.text);
|
PrintAndLogEx(ERR, "ERROR: can't set json path: %s", error.text);
|
||||||
return 2;
|
return 2;
|
||||||
} else {
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -157,7 +157,7 @@ int JsonSaveTLVElm(json_t *elm, const char *path, struct tlv *tlvelm, bool saveN
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (json_path_set(elm, path, obj, 0, &error)) {
|
if (json_path_set(elm, path, obj, 0, &error)) {
|
||||||
PrintAndLogEx(ERR, "ERROR: can't set json path: ", error.text);
|
PrintAndLogEx(ERR, "ERROR: can't set json path: %s", error.text);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -367,12 +367,14 @@ void tlvdb_change_or_add_node_ex(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len,
|
||||||
|
|
||||||
// replace tlv element
|
// replace tlv element
|
||||||
struct tlvdb *tnewelm = tlvdb_fixed(tag, len, value);
|
struct tlvdb *tnewelm = tlvdb_fixed(tag, len, value);
|
||||||
|
bool tnewelm_linked = false;
|
||||||
tnewelm->next = telm->next;
|
tnewelm->next = telm->next;
|
||||||
tnewelm->parent = telm->parent;
|
tnewelm->parent = telm->parent;
|
||||||
|
|
||||||
// if telm stayed first in children chain
|
// if telm stayed first in children chain
|
||||||
if (telm->parent && telm->parent->children == telm) {
|
if (telm->parent && telm->parent->children == telm) {
|
||||||
telm->parent->children = tnewelm;
|
telm->parent->children = tnewelm;
|
||||||
|
tnewelm_linked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if telm have previous element
|
// if telm have previous element
|
||||||
|
@ -387,6 +389,7 @@ void tlvdb_change_or_add_node_ex(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len,
|
||||||
for (; celm; celm = celm->next) {
|
for (; celm; celm = celm->next) {
|
||||||
if (celm->next == telm) {
|
if (celm->next == telm) {
|
||||||
celm->next = tnewelm;
|
celm->next = tnewelm;
|
||||||
|
tnewelm_linked = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -396,8 +399,13 @@ void tlvdb_change_or_add_node_ex(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len,
|
||||||
telm->next = NULL;
|
telm->next = NULL;
|
||||||
tlvdb_free(telm);
|
tlvdb_free(telm);
|
||||||
|
|
||||||
if (tlvdb_elm)
|
if (tlvdb_elm) {
|
||||||
*tlvdb_elm = tnewelm;
|
*tlvdb_elm = tnewelm;
|
||||||
|
tnewelm_linked = true;
|
||||||
|
}
|
||||||
|
if (! tnewelm_linked) {
|
||||||
|
tlvdb_free(tnewelm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -77,13 +77,15 @@ int fileExists(const char *filename) {
|
||||||
bool is_regular_file(const char *filename) {
|
bool is_regular_file(const char *filename) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
struct _stat st;
|
struct _stat st;
|
||||||
_stat(filename, &st);
|
if (_stat(filename, &st) == -1)
|
||||||
return S_ISREG(st.st_mode) != 0;
|
return false;
|
||||||
#else
|
#else
|
||||||
struct stat st;
|
struct stat st;
|
||||||
stat(filename, &st);
|
// stat(filename, &st);
|
||||||
return S_ISREG(st.st_mode) != 0;
|
if (lstat(filename, &st) == -1)
|
||||||
|
return false;
|
||||||
#endif
|
#endif
|
||||||
|
return S_ISREG(st.st_mode) != 0;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* @brief checks if path is directory.
|
* @brief checks if path is directory.
|
||||||
|
@ -93,13 +95,15 @@ bool is_regular_file(const char *filename) {
|
||||||
bool is_directory(const char *filename) {
|
bool is_directory(const char *filename) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
struct _stat st;
|
struct _stat st;
|
||||||
_stat(filename, &st);
|
if (_stat(filename, &st) == -1)
|
||||||
return S_ISDIR(st.st_mode) != 0;
|
return false;
|
||||||
#else
|
#else
|
||||||
struct stat st;
|
struct stat st;
|
||||||
stat(filename, &st);
|
// stat(filename, &st);
|
||||||
return S_ISDIR(st.st_mode) != 0;
|
if (lstat(filename, &st) == -1)
|
||||||
|
return false;
|
||||||
#endif
|
#endif
|
||||||
|
return S_ISDIR(st.st_mode) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -328,6 +332,25 @@ int saveFileJSON(const char *preferredName, JSONFileType ftype, uint8_t *data, s
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case jsfT55x7: {
|
||||||
|
JsonSaveStr(root, "FileType", "t55x7");
|
||||||
|
uint8_t id[4] = {0};
|
||||||
|
memcpy(id, data, 4);
|
||||||
|
JsonSaveBufAsHexCompact(root, "$.Card.ID", id, sizeof(id));
|
||||||
|
|
||||||
|
for (size_t i = 0; i < (datalen / 4); i++) {
|
||||||
|
char path[PATH_MAX_LENGTH] = {0};
|
||||||
|
sprintf(path, "$.blocks.%zu", i);
|
||||||
|
JsonSaveBufAsHexCompact(root, path, data + (i * 4), 4);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case jsf14b:
|
||||||
|
case jsf15:
|
||||||
|
case jsfLegic:
|
||||||
|
case jsfT5555:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int res = json_dump_file(root, fileName, JSON_INDENT(2));
|
int res = json_dump_file(root, fileName, JSON_INDENT(2));
|
||||||
|
@ -464,7 +487,7 @@ int loadFile_safe(const char *preferredName, const char *suffix, void **pdata, s
|
||||||
}
|
}
|
||||||
|
|
||||||
*pdata = calloc(fsize, sizeof(uint8_t));
|
*pdata = calloc(fsize, sizeof(uint8_t));
|
||||||
if (!pdata) {
|
if (!*pdata) {
|
||||||
PrintAndLogEx(FAILED, "error, cannot allocate memory");
|
PrintAndLogEx(FAILED, "error, cannot allocate memory");
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return PM3_EMALLOC;
|
return PM3_EMALLOC;
|
||||||
|
@ -660,6 +683,27 @@ int loadFileJSON(const char *preferredName, void *data, size_t maxdatalen, size_
|
||||||
*datalen = sptr;
|
*datalen = sptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!strcmp(ctype, "t55x7")) {
|
||||||
|
size_t sptr = 0;
|
||||||
|
for (size_t i = 0; i < (maxdatalen / 4); i++) {
|
||||||
|
if (sptr + 4 > maxdatalen) {
|
||||||
|
retval = PM3_EMALLOC;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
char path[30] = {0};
|
||||||
|
sprintf(path, "$.blocks.%zu", i);
|
||||||
|
|
||||||
|
size_t len = 0;
|
||||||
|
JsonLoadBufAsHex(root, path, &udata[sptr], 4, &len);
|
||||||
|
if (!len)
|
||||||
|
break;
|
||||||
|
|
||||||
|
sptr += len;
|
||||||
|
}
|
||||||
|
*datalen = sptr;
|
||||||
|
}
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "loaded from JSON file " _YELLOW_("%s"), fileName);
|
PrintAndLogEx(SUCCESS, "loaded from JSON file " _YELLOW_("%s"), fileName);
|
||||||
out:
|
out:
|
||||||
json_decref(root);
|
json_decref(root);
|
||||||
|
@ -759,9 +803,10 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key
|
||||||
|
|
||||||
// allocate some space for the dictionary
|
// allocate some space for the dictionary
|
||||||
*pdata = calloc(block_size, sizeof(uint8_t));
|
*pdata = calloc(block_size, sizeof(uint8_t));
|
||||||
if (*pdata == NULL)
|
if (*pdata == NULL) {
|
||||||
|
free(path);
|
||||||
return PM3_EFILE;
|
return PM3_EFILE;
|
||||||
|
}
|
||||||
mem_size = block_size;
|
mem_size = block_size;
|
||||||
|
|
||||||
FILE *f = fopen(path, "r");
|
FILE *f = fopen(path, "r");
|
||||||
|
@ -775,7 +820,7 @@ int loadFileDICTIONARY_safe(const char *preferredName, void **pdata, uint8_t key
|
||||||
while (fgets(line, sizeof(line), f)) {
|
while (fgets(line, sizeof(line), f)) {
|
||||||
|
|
||||||
// check if we have enough space (if not allocate more)
|
// check if we have enough space (if not allocate more)
|
||||||
if ((*keycnt * (keylen >> 1)) >= mem_size) {
|
if ((((size_t)(*keycnt)) * (keylen >> 1)) >= mem_size) {
|
||||||
|
|
||||||
mem_size += block_size;
|
mem_size += block_size;
|
||||||
*pdata = realloc(*pdata, mem_size);
|
*pdata = realloc(*pdata, mem_size);
|
||||||
|
@ -866,7 +911,7 @@ static int filelist(const char *path, const char *ext, bool last, bool tentative
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "%s── %s", last ? "└" : "├", path);
|
PrintAndLogEx(NORMAL, "%s── %s", last ? "└" : "├", path);
|
||||||
for (uint16_t i = 0; i < n; i++) {
|
for (uint16_t i = 0; i < n; i++) {
|
||||||
if (((ext == NULL) && (namelist[i]->d_name[0] != '.')) || (str_endswith(namelist[i]->d_name, ext))) {
|
if (((ext == NULL) && (namelist[i]->d_name[0] != '.')) || (ext && (str_endswith(namelist[i]->d_name, ext)))) {
|
||||||
PrintAndLogEx(NORMAL, "%s %s── %-21s", last ? " " : "│", i == n - 1 ? "└" : "├", namelist[i]->d_name);
|
PrintAndLogEx(NORMAL, "%s %s── %-21s", last ? " " : "│", i == n - 1 ? "└" : "├", namelist[i]->d_name);
|
||||||
}
|
}
|
||||||
free(namelist[i]);
|
free(namelist[i]);
|
||||||
|
@ -1019,7 +1064,7 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// try pm3 dirs in pm3 installation dir (install mode)
|
// try pm3 dirs in pm3 installation dir (install mode)
|
||||||
{
|
if (exec_path != NULL) {
|
||||||
char *path = calloc(strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char));
|
char *path = calloc(strlen(exec_path) + strlen(PM3_SHARE_RELPATH) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char));
|
||||||
if (path == NULL)
|
if (path == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1057,10 +1102,10 @@ int searchFile(char **foundpath, const char *pm3dir, const char *searchname, con
|
||||||
if (is_directory(searchname))
|
if (is_directory(searchname))
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
|
|
||||||
|
|
||||||
char *filename = filenamemcopy(searchname, suffix);
|
char *filename = filenamemcopy(searchname, suffix);
|
||||||
if (filename == NULL)
|
if (filename == NULL)
|
||||||
return PM3_EMALLOC;
|
return PM3_EMALLOC;
|
||||||
|
|
||||||
if (strlen(filename) == 0) {
|
if (strlen(filename) == 0) {
|
||||||
free(filename);
|
free(filename);
|
||||||
return PM3_EFILE;
|
return PM3_EFILE;
|
||||||
|
|
|
@ -56,10 +56,11 @@ typedef enum {
|
||||||
jsfMfuMemory,
|
jsfMfuMemory,
|
||||||
jsfHitag,
|
jsfHitag,
|
||||||
jsfIclass,
|
jsfIclass,
|
||||||
// jsf14b,
|
jsf14b,
|
||||||
// jsf15,
|
jsf15,
|
||||||
// jsfLegic,
|
jsfLegic,
|
||||||
// jsfT55xx,
|
jsfT55x7,
|
||||||
|
jsfT5555,
|
||||||
} JSONFileType;
|
} JSONFileType;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
|
@ -150,6 +150,8 @@ void reverse_arraycopy(uint8_t *arr, uint8_t *dest, size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void printarr(const char *name, uint8_t *arr, int len) {
|
void printarr(const char *name, uint8_t *arr, int len) {
|
||||||
|
if (name == NULL || arr == NULL) return;
|
||||||
|
|
||||||
int cx, i;
|
int cx, i;
|
||||||
size_t outsize = 40 + strlen(name) + len * 5;
|
size_t outsize = 40 + strlen(name) + len * 5;
|
||||||
char *output = calloc(outsize, sizeof(char));
|
char *output = calloc(outsize, sizeof(char));
|
||||||
|
|
|
@ -108,7 +108,7 @@ void permutekey_rev(uint8_t key[8], uint8_t dest[8]) {
|
||||||
* @param val
|
* @param val
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
inline uint8_t rr(uint8_t val) {
|
static inline uint8_t rr(uint8_t val) {
|
||||||
return val >> 1 | ((val & 1) << 7);
|
return val >> 1 | ((val & 1) << 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ inline uint8_t rr(uint8_t val) {
|
||||||
* @param val
|
* @param val
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
inline uint8_t rl(uint8_t val) {
|
static inline uint8_t rl(uint8_t val) {
|
||||||
return val << 1 | ((val & 0x80) >> 7);
|
return val << 1 | ((val & 0x80) >> 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +128,7 @@ inline uint8_t rl(uint8_t val) {
|
||||||
* @param val
|
* @param val
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
inline uint8_t swap(uint8_t val) {
|
static inline uint8_t swap(uint8_t val) {
|
||||||
return ((val >> 4) & 0xFF) | ((val & 0xFF) << 4);
|
return ((val >> 4) & 0xFF) | ((val & 0xFF) << 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -664,10 +664,12 @@ static bool readKeyFile(uint8_t *key, size_t keylen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keylen != len) {
|
if (keylen != len) {
|
||||||
|
free(keyptr);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(key, keyptr, keylen);
|
memcpy(key, keyptr, keylen);
|
||||||
|
free(keyptr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -186,7 +186,7 @@ static int ndefDecodeSig(uint8_t *sig, size_t siglen) {
|
||||||
if (sigURI) {
|
if (sigURI) {
|
||||||
size_t intsigurilen = (sig[indx] << 8) + sig[indx + 1];
|
size_t intsigurilen = (sig[indx] << 8) + sig[indx + 1];
|
||||||
indx += 2;
|
indx += 2;
|
||||||
PrintAndLogEx(NORMAL, "\tsignature uri [%zu]: %.*s", intsigurilen, intsigurilen, &sig[indx]);
|
PrintAndLogEx(NORMAL, "\tsignature uri [%zu]: %.*s", intsigurilen, (int)intsigurilen, &sig[indx]);
|
||||||
indx += intsigurilen;
|
indx += intsigurilen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ static int ndefDecodeSig(uint8_t *sig, size_t siglen) {
|
||||||
if ((indx <= siglen) && certURI) {
|
if ((indx <= siglen) && certURI) {
|
||||||
size_t inturilen = (sig[indx] << 8) + sig[indx + 1];
|
size_t inturilen = (sig[indx] << 8) + sig[indx + 1];
|
||||||
indx += 2;
|
indx += 2;
|
||||||
PrintAndLogEx(NORMAL, "\tcertificate uri [%zu]: %.*s", inturilen, inturilen, &sig[indx]);
|
PrintAndLogEx(NORMAL, "\tcertificate uri [%zu]: %.*s", inturilen, (int)inturilen, &sig[indx]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -157,7 +157,7 @@ check_script:
|
||||||
memset(script_cmd_buf, 0, sizeof(script_cmd_buf));
|
memset(script_cmd_buf, 0, sizeof(script_cmd_buf));
|
||||||
|
|
||||||
// read script file
|
// read script file
|
||||||
if (!fgets(script_cmd_buf, sizeof(script_cmd_buf), current_cmdscriptfile())) {
|
if (fgets(script_cmd_buf, sizeof(script_cmd_buf), current_cmdscriptfile()) == NULL) {
|
||||||
if (!pop_cmdscriptfile())
|
if (!pop_cmdscriptfile())
|
||||||
break;
|
break;
|
||||||
goto check_script;
|
goto check_script;
|
||||||
|
|
|
@ -69,7 +69,10 @@ static int l_fast_push_mode(lua_State *L) {
|
||||||
// Disable fast mode and send a dummy command to make it effective
|
// Disable fast mode and send a dummy command to make it effective
|
||||||
if (enable == false) {
|
if (enable == false) {
|
||||||
SendCommandNG(CMD_PING, NULL, 0);
|
SendCommandNG(CMD_PING, NULL, 0);
|
||||||
WaitForResponseTimeout(CMD_PING, NULL, 1000);
|
if (!WaitForResponseTimeout(CMD_PING, NULL, 1000)) {
|
||||||
|
PrintAndLogEx(WARNING, "command execution time out");
|
||||||
|
return returnToLuaWithError(L, "command execution time out");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Push the retval on the stack
|
//Push the retval on the stack
|
||||||
|
@ -926,7 +929,7 @@ static int l_T55xx_readblock(lua_State *L) {
|
||||||
// try reading the config block and verify that PWD bit is set before doing this!
|
// try reading the config block and verify that PWD bit is set before doing this!
|
||||||
if (!override) {
|
if (!override) {
|
||||||
|
|
||||||
if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, 0)) {
|
if (!AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0, 0)) {
|
||||||
return returnToLuaWithError(L, "Failed to read config block");
|
return returnToLuaWithError(L, "Failed to read config block");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -943,7 +946,7 @@ static int l_T55xx_readblock(lua_State *L) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!AquireData(usepage1, block, usepwd, password, 0)) {
|
if (!AcquireData(usepage1, block, usepwd, password, 0)) {
|
||||||
return returnToLuaWithError(L, "Failed to acquire data from card");
|
return returnToLuaWithError(L, "Failed to acquire data from card");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1000,7 +1003,7 @@ static int l_T55xx_detect(lua_State *L) {
|
||||||
|
|
||||||
if (!useGB) {
|
if (!useGB) {
|
||||||
|
|
||||||
isok = AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, 0);
|
isok = AcquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password, 0);
|
||||||
if (isok == false) {
|
if (isok == false) {
|
||||||
return returnToLuaWithError(L, "Failed to acquire LF signal data");
|
return returnToLuaWithError(L, "Failed to acquire LF signal data");
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,7 +118,10 @@ void computeSignalProperties(uint8_t *samples, uint32_t size) {
|
||||||
sum += samples[i];
|
sum += samples[i];
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
|
if (cnt > 0)
|
||||||
signalprop.mean = sum / cnt;
|
signalprop.mean = sum / cnt;
|
||||||
|
else
|
||||||
|
signalprop.mean = 0;
|
||||||
#else
|
#else
|
||||||
for (uint32_t i = SIGNAL_IGNORE_FIRST_SAMPLES; i < size; i++) {
|
for (uint32_t i = SIGNAL_IGNORE_FIRST_SAMPLES; i < size; i++) {
|
||||||
if (samples[i] < signalprop.low) signalprop.low = samples[i];
|
if (samples[i] < signalprop.low) signalprop.low = samples[i];
|
||||||
|
@ -161,7 +164,10 @@ void removeSignalOffset(uint8_t *samples, uint32_t size) {
|
||||||
acc_off += samples[i] - 128;
|
acc_off += samples[i] - 128;
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
|
if (cnt > 0)
|
||||||
acc_off /= cnt;
|
acc_off /= cnt;
|
||||||
|
else
|
||||||
|
acc_off = 0;
|
||||||
#else
|
#else
|
||||||
for (uint32_t i = SIGNAL_IGNORE_FIRST_SAMPLES; i < size; i++)
|
for (uint32_t i = SIGNAL_IGNORE_FIRST_SAMPLES; i < size; i++)
|
||||||
acc_off += samples[i] - 128;
|
acc_off += samples[i] - 128;
|
||||||
|
@ -324,13 +330,13 @@ bool preambleSearchEx(uint8_t *bits, uint8_t *preamble, size_t pLen, size_t *siz
|
||||||
//first index found
|
//first index found
|
||||||
foundCnt++;
|
foundCnt++;
|
||||||
if (foundCnt == 1) {
|
if (foundCnt == 1) {
|
||||||
if (g_debugMode >= 1) prnt("DEBUG: (preambleSearchEx) preamble found at %i", idx);
|
if (g_debugMode >= 1) prnt("DEBUG: (preambleSearchEx) preamble found at %zu", idx);
|
||||||
*startIdx = idx;
|
*startIdx = idx;
|
||||||
if (findone)
|
if (findone)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (foundCnt == 2) {
|
if (foundCnt == 2) {
|
||||||
if (g_debugMode >= 1) prnt("DEBUG: (preambleSearchEx) preamble 2 found at %i", idx);
|
if (g_debugMode >= 1) prnt("DEBUG: (preambleSearchEx) preamble 2 found at %zu", idx);
|
||||||
*size = idx - *startIdx;
|
*size = idx - *startIdx;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -361,7 +367,7 @@ static size_t findModStart(uint8_t *src, size_t size, uint8_t expWaveSize) {
|
||||||
}
|
}
|
||||||
if (thresholdCnt > 10) break;
|
if (thresholdCnt > 10) break;
|
||||||
}
|
}
|
||||||
if (g_debugMode == 2) prnt("DEBUG: threshold Count reached at index %u, count: %u", i, thresholdCnt);
|
if (g_debugMode == 2) prnt("DEBUG: threshold Count reached at index %zu, count: %u", i, thresholdCnt);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,7 +442,7 @@ size_t pskFindFirstPhaseShift(uint8_t *samples, size_t size, uint8_t *curPhase,
|
||||||
// find peak // was "samples[i] + fc" but why? must have been used to weed out some wave error... removed..
|
// find peak // was "samples[i] + fc" but why? must have been used to weed out some wave error... removed..
|
||||||
if (samples[i] < samples[i + 1] && samples[i + 1] >= samples[i + 2]) {
|
if (samples[i] < samples[i + 1] && samples[i + 1] >= samples[i + 2]) {
|
||||||
waveEnd = i + 1;
|
waveEnd = i + 1;
|
||||||
if (g_debugMode == 2) prnt("DEBUG PSK: waveEnd: %u, waveStart: %u", waveEnd, waveStart);
|
if (g_debugMode == 2) prnt("DEBUG PSK: waveEnd: %zu, waveStart: %zu", waveEnd, waveStart);
|
||||||
waveLenCnt = waveEnd - waveStart;
|
waveLenCnt = waveEnd - waveStart;
|
||||||
if (waveLenCnt > fc && waveStart > fc && !(waveLenCnt > fc + 8)) { //not first peak and is a large wave but not out of whack
|
if (waveLenCnt > fc && waveStart > fc && !(waveLenCnt > fc + 8)) { //not first peak and is a large wave but not out of whack
|
||||||
lastAvgWaveVal = avgWaveVal / (waveLenCnt);
|
lastAvgWaveVal = avgWaveVal / (waveLenCnt);
|
||||||
|
@ -1021,7 +1027,7 @@ uint16_t countFC(uint8_t *bits, size_t size, bool fskAdj) {
|
||||||
fcL = fcLens[best1];
|
fcL = fcLens[best1];
|
||||||
}
|
}
|
||||||
if ((size - 180) / fcH / 3 > fcCnts[best1] + fcCnts[best2]) {
|
if ((size - 180) / fcH / 3 > fcCnts[best1] + fcCnts[best2]) {
|
||||||
if (g_debugMode == 2) prnt("DEBUG countfc: fc is too large: %u > %u. Not psk or fsk", (size - 180) / fcH / 3, fcCnts[best1] + fcCnts[best2]);
|
if (g_debugMode == 2) prnt("DEBUG countfc: fc is too large: %zu > %u. Not psk or fsk", (size - 180) / fcH / 3, fcCnts[best1] + fcCnts[best2]);
|
||||||
return 0; //lots of waves not psk or fsk
|
return 0; //lots of waves not psk or fsk
|
||||||
}
|
}
|
||||||
// TODO: take top 3 answers and compare to known Field clocks to get top 2
|
// TODO: take top 3 answers and compare to known Field clocks to get top 2
|
||||||
|
@ -1072,7 +1078,7 @@ int DetectPSKClock(uint8_t *dest, size_t size, int clock, size_t *firstPhaseShif
|
||||||
}
|
}
|
||||||
|
|
||||||
*firstPhaseShift = firstFullWave;
|
*firstPhaseShift = firstFullWave;
|
||||||
if (g_debugMode == 2) prnt("DEBUG PSK: firstFullWave: %d, waveLen: %d", firstFullWave, fullWaveLen);
|
if (g_debugMode == 2) prnt("DEBUG PSK: firstFullWave: %zu, waveLen: %d", firstFullWave, fullWaveLen);
|
||||||
|
|
||||||
//test each valid clock from greatest to smallest to see which lines up
|
//test each valid clock from greatest to smallest to see which lines up
|
||||||
for (clkCnt = 7; clkCnt >= 1 ; clkCnt--) {
|
for (clkCnt = 7; clkCnt >= 1 ; clkCnt--) {
|
||||||
|
@ -1081,7 +1087,7 @@ int DetectPSKClock(uint8_t *dest, size_t size, int clock, size_t *firstPhaseShif
|
||||||
size_t waveStart = 0;
|
size_t waveStart = 0;
|
||||||
uint16_t errCnt = 0;
|
uint16_t errCnt = 0;
|
||||||
uint16_t peakcnt = 0;
|
uint16_t peakcnt = 0;
|
||||||
if (g_debugMode == 2) prnt("DEBUG PSK: clk: %d, lastClkBit: %d", clk[clkCnt], lastClkBit);
|
if (g_debugMode == 2) prnt("DEBUG PSK: clk: %d, lastClkBit: %zu", clk[clkCnt], lastClkBit);
|
||||||
|
|
||||||
for (i = firstFullWave + fullWaveLen - 1; i < loopCnt - 2; i++) {
|
for (i = firstFullWave + fullWaveLen - 1; i < loopCnt - 2; i++) {
|
||||||
//top edge of wave = start of new wave
|
//top edge of wave = start of new wave
|
||||||
|
@ -1093,7 +1099,7 @@ int DetectPSKClock(uint8_t *dest, size_t size, int clock, size_t *firstPhaseShif
|
||||||
waveLenCnt = waveEnd - waveStart;
|
waveLenCnt = waveEnd - waveStart;
|
||||||
if (waveLenCnt > *fc) {
|
if (waveLenCnt > *fc) {
|
||||||
//if this wave is a phase shift
|
//if this wave is a phase shift
|
||||||
if (g_debugMode == 2) prnt("DEBUG PSK: phase shift at: %d, len: %d, nextClk: %d, i: %d, fc: %d", waveStart, waveLenCnt, lastClkBit + clk[clkCnt] - tol, i + 1, *fc);
|
if (g_debugMode == 2) prnt("DEBUG PSK: phase shift at: %zu, len: %d, nextClk: %zu, i: %zu, fc: %d", waveStart, waveLenCnt, lastClkBit + clk[clkCnt] - tol, i + 1, *fc);
|
||||||
if (i + 1 >= lastClkBit + clk[clkCnt] - tol) { //should be a clock bit
|
if (i + 1 >= lastClkBit + clk[clkCnt] - tol) { //should be a clock bit
|
||||||
peakcnt++;
|
peakcnt++;
|
||||||
lastClkBit += clk[clkCnt];
|
lastClkBit += clk[clkCnt];
|
||||||
|
@ -1325,7 +1331,7 @@ bool DetectST(uint8_t *buffer, size_t *size, int *foundclock, size_t *ststart, s
|
||||||
// padd the amount off - could be problematic... but shouldn't happen often
|
// padd the amount off - could be problematic... but shouldn't happen often
|
||||||
datalen -= datalen % clk;
|
datalen -= datalen % clk;
|
||||||
} else {
|
} else {
|
||||||
if (g_debugMode == 2) prnt("DEBUG STT: datalen not divisible by clk: %u %% %d = %d - quitting", datalen, clk, datalen % clk);
|
if (g_debugMode == 2) prnt("DEBUG STT: datalen not divisible by clk: %zu %% %d = %zu - quitting", datalen, clk, datalen % clk);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// if datalen is less than one t55xx block - ERROR
|
// if datalen is less than one t55xx block - ERROR
|
||||||
|
@ -1346,7 +1352,7 @@ bool DetectST(uint8_t *buffer, size_t *size, int *foundclock, size_t *ststart, s
|
||||||
|
|
||||||
size_t newloc = 0;
|
size_t newloc = 0;
|
||||||
i = 0;
|
i = 0;
|
||||||
if (g_debugMode == 2) prnt("DEBUG STT: Starting STT trim - start: %d, datalen: %d ", dataloc, datalen);
|
if (g_debugMode == 2) prnt("DEBUG STT: Starting STT trim - start: %zu, datalen: %zu ", dataloc, datalen);
|
||||||
bool firstrun = true;
|
bool firstrun = true;
|
||||||
// warning - overwriting buffer given with raw wave data with ST removed...
|
// warning - overwriting buffer given with raw wave data with ST removed...
|
||||||
while (dataloc < bufsize - (clk / 2)) {
|
while (dataloc < bufsize - (clk / 2)) {
|
||||||
|
@ -1376,7 +1382,7 @@ bool DetectST(uint8_t *buffer, size_t *size, int *foundclock, size_t *ststart, s
|
||||||
}
|
}
|
||||||
newloc += i;
|
newloc += i;
|
||||||
//skip next ST - we just assume it will be there from now on...
|
//skip next ST - we just assume it will be there from now on...
|
||||||
if (g_debugMode == 2) prnt("DEBUG STT: skipping STT at %d to %d", dataloc, dataloc + (clk * 4));
|
if (g_debugMode == 2) prnt("DEBUG STT: skipping STT at %zu to %zu", dataloc, dataloc + (clk * 4));
|
||||||
dataloc += clk * 4;
|
dataloc += clk * 4;
|
||||||
}
|
}
|
||||||
*size = newloc;
|
*size = newloc;
|
||||||
|
@ -1479,10 +1485,10 @@ uint16_t manrawdecode(uint8_t *bits, size_t *size, uint8_t invert, uint8_t *alig
|
||||||
|
|
||||||
int errCnt = 0, bestErr = 1000;
|
int errCnt = 0, bestErr = 1000;
|
||||||
uint16_t bitnum = 0, maxBits = 512, bestRun = 0;
|
uint16_t bitnum = 0, maxBits = 512, bestRun = 0;
|
||||||
size_t i, k;
|
size_t i;
|
||||||
|
|
||||||
//find correct start position [alignment]
|
//find correct start position [alignment]
|
||||||
for (k = 0; k < 2; k++) {
|
for (uint8_t k = 0; k < 2; k++) {
|
||||||
|
|
||||||
for (i = k; i < *size - 1; i += 2) {
|
for (i = k; i < *size - 1; i += 2) {
|
||||||
|
|
||||||
|
@ -1549,7 +1555,7 @@ static uint16_t cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int inver
|
||||||
if (smplCnt > clk + cl_4 + 1) {
|
if (smplCnt > clk + cl_4 + 1) {
|
||||||
//too many samples
|
//too many samples
|
||||||
errCnt++;
|
errCnt++;
|
||||||
if (g_debugMode == 2) prnt("DEBUG ASK: cleanAskRawDemod ASK Modulation Error FULL at: %u [%u > %u]", i, smplCnt, clk + cl_4 + 1);
|
if (g_debugMode == 2) prnt("DEBUG ASK: cleanAskRawDemod ASK Modulation Error FULL at: %zu [%zu > %u]", i, smplCnt, clk + cl_4 + 1);
|
||||||
bits[bitCnt++] = 7;
|
bits[bitCnt++] = 7;
|
||||||
} else if (waveHigh) {
|
} else if (waveHigh) {
|
||||||
bits[bitCnt++] = invert;
|
bits[bitCnt++] = invert;
|
||||||
|
@ -1570,7 +1576,7 @@ static uint16_t cleanAskRawDemod(uint8_t *bits, size_t *size, int clk, int inver
|
||||||
|
|
||||||
if (smplCnt > cl_2 + cl_4 + 1) { //too many samples
|
if (smplCnt > cl_2 + cl_4 + 1) { //too many samples
|
||||||
errCnt++;
|
errCnt++;
|
||||||
if (g_debugMode == 2) prnt("DEBUG ASK: cleanAskRawDemod ASK Modulation Error HALF at: %u [%u]", i, smplCnt);
|
if (g_debugMode == 2) prnt("DEBUG ASK: cleanAskRawDemod ASK Modulation Error HALF at: %zu [%zu]", i, smplCnt);
|
||||||
bits[bitCnt++] = 7;
|
bits[bitCnt++] = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1645,7 +1651,7 @@ int askdemod_ext(uint8_t *bits, size_t *size, int *clk, int *invert, int maxErr,
|
||||||
errCnt = manrawdecode(bits, size, 0, &alignPos);
|
errCnt = manrawdecode(bits, size, 0, &alignPos);
|
||||||
*startIdx += ((*clk / 2) * alignPos);
|
*startIdx += ((*clk / 2) * alignPos);
|
||||||
|
|
||||||
prnt("DEBUG: (askdemod_ext) CLEAN: startIdx %i, alignPos %u , bestError %u", *startIdx, alignPos, errCnt);
|
prnt("DEBUG: (askdemod_ext) CLEAN: startIdx %i, alignPos %u , bestError %zu", *startIdx, alignPos, errCnt);
|
||||||
}
|
}
|
||||||
return errCnt;
|
return errCnt;
|
||||||
}
|
}
|
||||||
|
@ -1870,10 +1876,10 @@ static size_t aggregate_bits(uint8_t *dest, size_t size, uint8_t clk, uint8_t in
|
||||||
if (numBits == 0) {
|
if (numBits == 0) {
|
||||||
if (lastval == 1) { //high to low
|
if (lastval == 1) { //high to low
|
||||||
*startIdx += (fclow * i) - (n * clk);
|
*startIdx += (fclow * i) - (n * clk);
|
||||||
if (g_debugMode == 2) prnt("DEBUG (aggregate_bits) FSK startIdx %i, fclow*idx %i, n*clk %u", *startIdx, fclow * i, n * clk);
|
if (g_debugMode == 2) prnt("DEBUG (aggregate_bits) FSK startIdx %i, fclow*idx %zu, n*clk %u", *startIdx, fclow * i, n * clk);
|
||||||
} else {
|
} else {
|
||||||
*startIdx += (fchigh * i) - (n * clk);
|
*startIdx += (fchigh * i) - (n * clk);
|
||||||
if (g_debugMode == 2) prnt("DEBUG (aggregate_bits) FSK startIdx %i, fchigh*idx %i, n*clk %u", *startIdx, fchigh * i, n * clk);
|
if (g_debugMode == 2) prnt("DEBUG (aggregate_bits) FSK startIdx %i, fchigh*idx %zu, n*clk %u", *startIdx, fchigh * i, n * clk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1984,8 +1990,8 @@ int pskRawDemod_ext(uint8_t *dest, size_t *size, int *clock, int *invert, int *s
|
||||||
//set start of wave as clock align
|
//set start of wave as clock align
|
||||||
lastClkBit = firstFullWave;
|
lastClkBit = firstFullWave;
|
||||||
if (g_debugMode == 2) {
|
if (g_debugMode == 2) {
|
||||||
prnt("DEBUG PSK: firstFullWave: %u, waveLen: %u, startIdx %i", firstFullWave, fullWaveLen, *startIdx);
|
prnt("DEBUG PSK: firstFullWave: %zu, waveLen: %u, startIdx %i", firstFullWave, fullWaveLen, *startIdx);
|
||||||
prnt("DEBUG PSK: clk: %d, lastClkBit: %u, fc: %u", *clock, lastClkBit, fc);
|
prnt("DEBUG PSK: clk: %d, lastClkBit: %zu, fc: %u", *clock, lastClkBit, fc);
|
||||||
}
|
}
|
||||||
|
|
||||||
waveStart = 0;
|
waveStart = 0;
|
||||||
|
|
46
covbuild.sh
46
covbuild.sh
|
@ -1,36 +1,20 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
## 2016-01-16, Iceman
|
set -e
|
||||||
## build script for Coverity Scan of the proxmark3 source code
|
. .coverity.conf || exit 1
|
||||||
|
|
||||||
## clean up pre-compiled objects.
|
pre_build_hook
|
||||||
|
|
||||||
|
rm -rf "$COVDIR"
|
||||||
|
mkdir "$COVDIR"
|
||||||
make clean
|
make clean
|
||||||
|
$COVBUILD make -j 4 bootrom
|
||||||
|
$COVBUILD make -j 4 fullimage
|
||||||
|
$COVBUILD make -j 4 mfkey
|
||||||
|
$COVBUILD make -j 4 nonce2key
|
||||||
|
$COVBUILD make -j 4 fpga_compress
|
||||||
|
# make sure to do client after ARM because Coverity retains one build info per file
|
||||||
|
# and we want the client-side of the common/ analysis
|
||||||
|
$COVBUILD make -j 4 client
|
||||||
|
|
||||||
## coverity build
|
post_build_hook
|
||||||
/home/user/cov-analysis-linux-2017.07/bin/cov-build --dir cov-int make all
|
|
||||||
|
|
||||||
## delete all previous tarballs
|
|
||||||
rm proxmark3.all.*.tgz
|
|
||||||
|
|
||||||
##
|
|
||||||
VERSION="0.1.`date --date now +%H%M`"
|
|
||||||
TODAY="`date --date now +%Y%m%d.%H%M`"
|
|
||||||
DESCNAME="autoMango.$TODAY"
|
|
||||||
FILENAME=proxmark3.all.$TODAY.tgz
|
|
||||||
|
|
||||||
## create tarball
|
|
||||||
tar cfz $FILENAME cov-int
|
|
||||||
echo "Coverity build file is ready"
|
|
||||||
|
|
||||||
## clean up build folders
|
|
||||||
rm -rf cov-int
|
|
||||||
echo "Coverity build cleaned"
|
|
||||||
|
|
||||||
## upload tarball to Coverity.com
|
|
||||||
curl --form token=dY262wIFmfkcRkA5Pyw0eA \
|
|
||||||
--form email=herrmann1001@gmail.com \
|
|
||||||
--form file=@$FILENAME \
|
|
||||||
--form version="$VERSION" \
|
|
||||||
--form description="$DESCNAME" \
|
|
||||||
https://scan.coverity.com/builds?project=proxmark3_iceman_fork
|
|
||||||
echo "tarball uploaded to Coverity for analyse"
|
|
||||||
|
|
13
covconfig.sh
13
covconfig.sh
|
@ -1,13 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
## 20160116, iceman
|
set -e
|
||||||
## remove old
|
. .coverity.conf || exit 1
|
||||||
rm /home/user/cov-analysis-linux-2017.07/config/coverity_config.xml
|
|
||||||
rm -rf /home/user/cov-analysis-linux-2017.07/config/gcc-config-?
|
|
||||||
rm -rf /home/user/cov-analysis-linux-2017.07/config/g++-config-?
|
|
||||||
|
|
||||||
## Configure ARM , make sure you have the arm gcc in your $PATH variable.
|
cov-configure --template --compiler arm-none-eabi-gcc --comptype gcc
|
||||||
#/home/user/cov-analysis-linux-2017.07/bin/cov-configure -co arm-none-eabi-gcc -- -mthumb-interwork
|
|
||||||
/home/user/cov-analysis-linux-2017.07/bin/cov-configure -co arm-none-eabi-gcc -- -std=c99 -mthumb -mthumb-interwork
|
|
||||||
|
|
||||||
echo "Done."
|
|
||||||
|
|
31
covsubmit.sh
Executable file
31
covsubmit.sh
Executable file
|
@ -0,0 +1,31 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
. .coverity.conf || exit 1
|
||||||
|
|
||||||
|
pre_submit_hook
|
||||||
|
|
||||||
|
## delete all previous tarballs
|
||||||
|
rm proxmark3.all.*.tgz proxmark3.all.*.log
|
||||||
|
|
||||||
|
TODAY="$(date --date now +%Y%m%d.%H%M)"
|
||||||
|
VERSION="0.1.$TODAY"
|
||||||
|
DESCNAME="manual_by_$NICKNAME.$TODAY.$(git describe --dirty --always)"
|
||||||
|
FILENAME="proxmark3.all.$TODAY.tgz"
|
||||||
|
LOGFILENAME="${FILENAME/.tgz/.log}"
|
||||||
|
|
||||||
|
## create tarball
|
||||||
|
tar cfz "$FILENAME" "$COVDIR" || exit $?
|
||||||
|
echo "Coverity build file is ready"
|
||||||
|
|
||||||
|
## upload tarball to Coverity.com
|
||||||
|
curl --progress-bar --fail \
|
||||||
|
--form token="$COVTOKEN" \
|
||||||
|
--form email="$COVLOGIN" \
|
||||||
|
--form file="@$FILENAME" \
|
||||||
|
--form version="$VERSION" \
|
||||||
|
--form description="$DESCNAME" \
|
||||||
|
https://scan.coverity.com/builds?project=Proxmark3+RRG+Iceman+repo | tee -a "${LOGFILENAME}" ; test "${PIPESTATUS[0]}" -eq 0 || exit $?
|
||||||
|
echo "tarball uploaded to Coverity for analyse"
|
||||||
|
|
||||||
|
post_submit_hook
|
|
@ -12,6 +12,13 @@ Via some definitions, you can adjust the firmware for a given platform, but also
|
||||||
The client doesn't depend on the capabilities of the Proxmark3 it's connected to.
|
The client doesn't depend on the capabilities of the Proxmark3 it's connected to.
|
||||||
So you can use the same client for different Proxmark3 platforms, given that everything is running the same version.
|
So you can use the same client for different Proxmark3 platforms, given that everything is running the same version.
|
||||||
|
|
||||||
|
It's possible to explicitly skip the Qt support in the compilation even if Qt is present on the host, with:
|
||||||
|
|
||||||
|
```
|
||||||
|
make clean
|
||||||
|
make SKIPQT=1
|
||||||
|
```
|
||||||
|
|
||||||
## Firmware
|
## Firmware
|
||||||
|
|
||||||
By default, the firmware is of course tuned for the Proxmark3 Rdv4.0 device, which has built-in support for 256kb onboard flash SPI memory, Sim module (smart card support), FPC connector.
|
By default, the firmware is of course tuned for the Proxmark3 Rdv4.0 device, which has built-in support for 256kb onboard flash SPI memory, Sim module (smart card support), FPC connector.
|
||||||
|
|
|
@ -198,6 +198,12 @@ typedef struct {
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
} PACKED t55xx_write_block_t;
|
} PACKED t55xx_write_block_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t data[128];
|
||||||
|
uint8_t bitlen;
|
||||||
|
uint32_t time;
|
||||||
|
} PACKED t55xx_test_block_t;
|
||||||
|
|
||||||
// For CMD_LF_HID_SIMULATE (FSK)
|
// For CMD_LF_HID_SIMULATE (FSK)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t hi2;
|
uint32_t hi2;
|
||||||
|
@ -376,6 +382,7 @@ typedef struct {
|
||||||
#define CMD_LF_SAMPLING_GET_CONFIG 0x0227
|
#define CMD_LF_SAMPLING_GET_CONFIG 0x0227
|
||||||
|
|
||||||
#define CMD_LF_T55XX_CHK_PWDS 0x0230
|
#define CMD_LF_T55XX_CHK_PWDS 0x0230
|
||||||
|
#define CMD_LF_T55XX_DANGERRAW 0x0231
|
||||||
|
|
||||||
/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
|
/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
|
||||||
|
|
||||||
|
|
|
@ -133,8 +133,8 @@ ISO 7816-4 Basic interindustry commands. For command APDU's.
|
||||||
#define ICLASS_CMD_READ_OR_IDENTIFY 0xC
|
#define ICLASS_CMD_READ_OR_IDENTIFY 0xC
|
||||||
#define ICLASS_CMD_ACT 0xE
|
#define ICLASS_CMD_ACT 0xE
|
||||||
|
|
||||||
#define ICLASS_CREDIT(x) (((x) & 0x5) == 1)
|
#define ICLASS_CREDIT(x) (((x) & 0x10) == 0x10)
|
||||||
#define ICLASS_DEBIT(x) (((x) & 0x5) == 0)
|
#define ICLASS_DEBIT(x) !(ICLASS_CREDIT(x))
|
||||||
|
|
||||||
|
|
||||||
#define ISO14443A_CMD_REQA 0x26
|
#define ISO14443A_CMD_REQA 0x26
|
||||||
|
|
39999
traces/gallagher.pm3
Normal file
39999
traces/gallagher.pm3
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue