Merge branch 'master' of https://github.com/mwalker33/proxmark3-rrg
This commit is contained in:
@@ -3,15 +3,16 @@ DEFAULT_STANDALONE=LF_SAMYRUN
|
||||
HELP_EXAMPLE_STANDALONE=HF_COLIN
|
||||
# (you can set explicitly STANDALONE= to disable standalone modes)
|
||||
STANDALONE?=$(DEFAULT_STANDALONE)
|
||||
STANDALONE_REQ_DEFS=
|
||||
|
||||
define KNOWN_STANDALONE_DEFINITIONS
|
||||
+==========================================================+
|
||||
| STANDALONE | DESCRIPTION |
|
||||
+==========================================================+
|
||||
| | No standalone mode |
|
||||
| (empty) | No standalone mode |
|
||||
+----------------------------------------------------------+
|
||||
| LF_SAMYRUN (def)| HID26 read/clone/sim |
|
||||
| | - Samy Kamkar |
|
||||
| LF_SAMYRUN | HID26 read/clone/sim |
|
||||
| (default) | - Samy Kamkar |
|
||||
+----------------------------------------------------------+
|
||||
| LF_ICERUN | standalone mode skeleton |
|
||||
| | - iceman |
|
||||
@@ -29,18 +30,26 @@ define KNOWN_STANDALONE_DEFINITIONS
|
||||
| | - Matías A. Ré Medina |
|
||||
+----------------------------------------------------------+
|
||||
| HF_COLIN | Mifare ultra fast sniff/sim/clone |
|
||||
| | - Colin Brigato |
|
||||
| (RDV4 only) | - Colin Brigato |
|
||||
+----------------------------------------------------------+
|
||||
| HF_BOG | 14a sniff with ULC/ULEV1/NTAG auth |
|
||||
| | storing in flashmem - Bogito |
|
||||
| (RDV4 only) | storing in flashmem - Bogito |
|
||||
+----------------------------------------------------------+
|
||||
|
||||
endef
|
||||
|
||||
STANDALONE_MODES := LF_SAMYRUN LF_ICERUN LF_PROXBRUTE LF_HIDBRUTE
|
||||
STANDALONE_MODES += HF_YOUNG HF_MATTYRUN HF_COLIN HF_BOG
|
||||
STANDALONE_MODES_REQ_SMARTCARD :=
|
||||
STANDALONE_MODES_REQ_FLASH := HF_COLIN HF_BOG
|
||||
ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES)),)
|
||||
STANDALONE_PLATFORM_DEFS += -DWITH_STANDALONE_$(STANDALONE)
|
||||
ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES_REQ_SMARTCARD)),)
|
||||
STANDALONE_REQ_DEFS += -DWITH_SMARTCARD
|
||||
endif
|
||||
ifneq ($(filter $(STANDALONE),$(STANDALONE_MODES_REQ_FLASH)),)
|
||||
STANDALONE_REQ_DEFS += -DWITH_FLASH
|
||||
endif
|
||||
else ifneq ($(STANDALONE),)
|
||||
$(error Invalid STANDALONE: $(STANDALONE). $(KNOWN_DEFINITIONS))
|
||||
endif
|
||||
|
||||
@@ -27,35 +27,7 @@ from the client to view the stored quadlets.
|
||||
// Maximum number of auth attempts per standalone session
|
||||
#define MAX_PWDS_PER_SESSION 64
|
||||
|
||||
uint8_t FindOffsetInFlash() {
|
||||
uint8_t mem[4] = { 0x00, 0x00, 0x00, 0x00 };
|
||||
uint8_t eom[4] = { 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
uint8_t memcnt = 0;
|
||||
|
||||
while (memcnt < 0xFF) {
|
||||
Flash_ReadData(memcnt, mem, 4);
|
||||
if (memcmp(mem, eom, 4) == 0) {
|
||||
return memcnt;
|
||||
}
|
||||
memcnt += 4;
|
||||
}
|
||||
|
||||
return 0; // wrap-around
|
||||
}
|
||||
|
||||
void EraseMemory() {
|
||||
if (!FlashInit()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||
Flash_WriteEnable();
|
||||
Flash_Erase4k(0, 0);
|
||||
|
||||
if (DBGLEVEL > 1) Dbprintf("[!] Erased flash!");
|
||||
FlashStop();
|
||||
SpinDelay(100);
|
||||
}
|
||||
#define HF_BOG_LOGFILE "hf_bog.log"
|
||||
|
||||
// This is actually copied from SniffIso14443a
|
||||
void RAMFUNC SniffAndStore(uint8_t param) {
|
||||
@@ -96,8 +68,9 @@ void RAMFUNC SniffAndStore(uint8_t param) {
|
||||
UartInit(receivedCmd, receivedCmdPar);
|
||||
|
||||
// Setup and start DMA.
|
||||
if (!FpgaSetupSscDma((uint8_t *) dmaBuf, DMA_BUFFER_SIZE)) {
|
||||
if (DBGLEVEL > 1) Dbprintf("FpgaSetupSscDma failed. Exiting");
|
||||
if (!FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE)) {
|
||||
if (DBGLEVEL > 1)
|
||||
Dbprintf("FpgaSetupSscDma failed. Exiting");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -134,17 +107,18 @@ void RAMFUNC SniffAndStore(uint8_t param) {
|
||||
Dbprintf("[!] blew circular buffer! | datalen %u", dataLen);
|
||||
break;
|
||||
}
|
||||
if (dataLen < 1) continue;
|
||||
if (dataLen < 1)
|
||||
continue;
|
||||
|
||||
// primary buffer was stopped( <-- we lost data!
|
||||
if (!AT91C_BASE_PDC_SSC->PDC_RCR) {
|
||||
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t) dmaBuf;
|
||||
AT91C_BASE_PDC_SSC->PDC_RPR = (uint32_t)dmaBuf;
|
||||
AT91C_BASE_PDC_SSC->PDC_RCR = DMA_BUFFER_SIZE;
|
||||
//Dbprintf("[-] RxEmpty ERROR | data length %d", dataLen); // temporary
|
||||
// Dbprintf("[-] RxEmpty ERROR | data length %d", dataLen); // temporary
|
||||
}
|
||||
// secondary buffer sets as primary, secondary buffer was stopped
|
||||
if (!AT91C_BASE_PDC_SSC->PDC_RNCR) {
|
||||
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) dmaBuf;
|
||||
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t)dmaBuf;
|
||||
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
@@ -159,23 +133,24 @@ void RAMFUNC SniffAndStore(uint8_t param) {
|
||||
LED_C_ON();
|
||||
|
||||
// check - if there is a short 7bit request from reader
|
||||
if ((!triggered) && (param & 0x02) && (uart->len == 1) && (uart->bitCount == 7)) triggered = true;
|
||||
if ((!triggered) && (param & 0x02) && (uart->len == 1) && (uart->bitCount == 7))
|
||||
triggered = true;
|
||||
|
||||
if (triggered) {
|
||||
if ((receivedCmd) && ((receivedCmd[0] == MIFARE_ULEV1_AUTH) || (receivedCmd[0] == MIFARE_ULC_AUTH_1))) {
|
||||
if (DBGLEVEL > 1) Dbprintf("PWD-AUTH KEY: 0x%02x%02x%02x%02x", receivedCmd[1], receivedCmd[2], receivedCmd[3], receivedCmd[4]);
|
||||
if ((receivedCmd) &&
|
||||
((receivedCmd[0] == MIFARE_ULEV1_AUTH) || (receivedCmd[0] == MIFARE_ULC_AUTH_1))) {
|
||||
if (DBGLEVEL > 1)
|
||||
Dbprintf("PWD-AUTH KEY: 0x%02x%02x%02x%02x", receivedCmd[1], receivedCmd[2],
|
||||
receivedCmd[3], receivedCmd[4]);
|
||||
|
||||
// temporarily save the captured pwd in our array
|
||||
memcpy(&capturedPwds[4 * auth_attempts], receivedCmd + 1, 4);
|
||||
auth_attempts++;
|
||||
}
|
||||
|
||||
if (!LogTrace(receivedCmd,
|
||||
uart->len,
|
||||
uart->startTime * 16 - DELAY_READER_AIR2ARM_AS_SNIFFER,
|
||||
uart->endTime * 16 - DELAY_READER_AIR2ARM_AS_SNIFFER,
|
||||
uart->parity,
|
||||
true)) break;
|
||||
if (!LogTrace(receivedCmd, uart->len, uart->startTime * 16 - DELAY_READER_AIR2ARM_AS_SNIFFER,
|
||||
uart->endTime * 16 - DELAY_READER_AIR2ARM_AS_SNIFFER, uart->parity, true))
|
||||
break;
|
||||
}
|
||||
/* ready to receive another command. */
|
||||
UartReset();
|
||||
@@ -193,20 +168,18 @@ void RAMFUNC SniffAndStore(uint8_t param) {
|
||||
if (ManchesterDecoding(tagdata, 0, (my_rsamples - 1) * 4)) {
|
||||
LED_B_ON();
|
||||
|
||||
if (!LogTrace(receivedResp,
|
||||
demod->len,
|
||||
demod->startTime * 16 - DELAY_TAG_AIR2ARM_AS_SNIFFER,
|
||||
demod->endTime * 16 - DELAY_TAG_AIR2ARM_AS_SNIFFER,
|
||||
demod->parity,
|
||||
false)) break;
|
||||
if (!LogTrace(receivedResp, demod->len, demod->startTime * 16 - DELAY_TAG_AIR2ARM_AS_SNIFFER,
|
||||
demod->endTime * 16 - DELAY_TAG_AIR2ARM_AS_SNIFFER, demod->parity, false))
|
||||
break;
|
||||
|
||||
if ((!triggered) && (param & 0x01)) triggered = true;
|
||||
if ((!triggered) && (param & 0x01))
|
||||
triggered = true;
|
||||
|
||||
// ready to receive another response.
|
||||
DemodReset();
|
||||
// reset the Miller decoder including its (now outdated) input buffer
|
||||
UartReset();
|
||||
//UartInit(receivedCmd, receivedCmdPar);
|
||||
// UartInit(receivedCmd, receivedCmdPar);
|
||||
LED_C_OFF();
|
||||
}
|
||||
TagIsActive = (demod->state != DEMOD_UNSYNCD);
|
||||
@@ -228,57 +201,25 @@ void RAMFUNC SniffAndStore(uint8_t param) {
|
||||
|
||||
SpinDelay(200);
|
||||
|
||||
// Write stuff to flash
|
||||
// Write stuff to spiffs logfile
|
||||
if (auth_attempts > 0) {
|
||||
if (DBGLEVEL > 1) Dbprintf("[!] Authentication attempts = %u", auth_attempts);
|
||||
if (DBGLEVEL > 1)
|
||||
Dbprintf("[!] Authentication attempts = %u", auth_attempts);
|
||||
size_t size = 4 * auth_attempts;
|
||||
uint8_t *data = BigBuf_malloc(size);
|
||||
|
||||
// Setting the SPI Baudrate to 48MHz to avoid the bit-flip issue (https://github.com/RfidResearchGroup/proxmark3/issues/34)
|
||||
FlashmemSetSpiBaudrate(48000000);
|
||||
|
||||
// Find the offset in flash mem to continue writing the auth attempts
|
||||
uint8_t memoffset = FindOffsetInFlash();
|
||||
if (DBGLEVEL > 1) Dbprintf("[!] Memory offset = %u", memoffset);
|
||||
|
||||
if ((memoffset + 4 * auth_attempts) > 0xFF) {
|
||||
// We opt to keep the new data only
|
||||
memoffset = 0;
|
||||
if (DBGLEVEL > 1) Dbprintf("[!] Size of total data > 256 bytes. Discarding the old data.");
|
||||
if (!exists_in_spiffs((char *)HF_BOG_LOGFILE)) {
|
||||
rdv40_spiffs_write((char *)HF_BOG_LOGFILE, (uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
} else {
|
||||
rdv40_spiffs_append((char *)HF_BOG_LOGFILE, (uint8_t *)data, size, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
}
|
||||
|
||||
// Get previous data from flash mem
|
||||
uint8_t *previousdata = BigBuf_malloc(memoffset);
|
||||
if (memoffset > 0) {
|
||||
uint16_t readlen = Flash_ReadData(0, previousdata, memoffset);
|
||||
if (DBGLEVEL > 1) Dbprintf("[!] Read %u bytes from flash mem", readlen);
|
||||
}
|
||||
|
||||
// create new bigbuf to hold all data
|
||||
size_t total_size = memoffset + 4 * auth_attempts;
|
||||
uint8_t *total_data = BigBuf_malloc(total_size);
|
||||
|
||||
// Add the previousdata array into total_data array
|
||||
memcpy(total_data, previousdata, memoffset);
|
||||
|
||||
// Copy bytes of capturedPwds immediately following bytes of previousdata
|
||||
memcpy(total_data + memoffset, capturedPwds, 4 * auth_attempts);
|
||||
|
||||
// Erase first page of flash mem
|
||||
EraseMemory();
|
||||
|
||||
// Write total data to flash mem
|
||||
uint16_t writelen = Flash_WriteData(0, total_data, memoffset + 4 * auth_attempts);
|
||||
if (DBGLEVEL > 1) Dbprintf("[!] Wrote %u bytes into flash mem", writelen);
|
||||
|
||||
// If pwd saved successfully, blink led A three times
|
||||
if (writelen > 0) {
|
||||
SpinErr(0, 200, 5); // blink led A
|
||||
}
|
||||
|
||||
SpinDelay(100);
|
||||
|
||||
// Reset the SPI Baudrate to the default value (24MHz)
|
||||
FlashmemSetSpiBaudrate(24000000);
|
||||
}
|
||||
|
||||
if (DBGLEVEL > 1)
|
||||
Dbprintf("[!] Wrote %u Authentification attempts into logfile", auth_attempts);
|
||||
|
||||
SpinErr(0, 200, 5); // blink led A
|
||||
SpinDelay(100);
|
||||
}
|
||||
|
||||
void ModInfo(void) {
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "apps.h"
|
||||
#include "printf.h"
|
||||
#include "parity.h"
|
||||
#include "spiffs.h"
|
||||
|
||||
|
||||
#endif /* __HF_BOG_H */
|
||||
|
||||
@@ -27,39 +27,78 @@ int curlline;
|
||||
|
||||
// Colin's VIGIKPWN sniff/simulate/clone repeat routine for HF Mifare
|
||||
|
||||
/*
|
||||
void cjPrintBigArray(const char *bigar, int len, uint8_t newlines, uint8_t debug)
|
||||
{
|
||||
uint32_t chunksize = (PM3_CMD_DATA_SIZE / 4);
|
||||
uint8_t totalchunks = len / chunksize;
|
||||
uint8_t last_chunksize = len - (totalchunks * chunksize);
|
||||
char chunk[chunksize + 1];
|
||||
memset(chunk, 0x00, sizeof(chunk));
|
||||
if (debug > 0)
|
||||
{
|
||||
Dbprintf("len : %d", len);
|
||||
Dbprintf("chunksize : %d bytes", chunksize);
|
||||
Dbprintf("totalchunks : %d", totalchunks);
|
||||
Dbprintf("last_chunksize: %d", last_chunksize);
|
||||
typedef struct MFC1KSchema {
|
||||
uint8_t name[32];
|
||||
uint64_t trigger;
|
||||
uint64_t keysA[16];
|
||||
uint64_t keysB[16];
|
||||
} MFC1KSchema;
|
||||
|
||||
#define MAX_SCHEMAS 4
|
||||
|
||||
MFC1KSchema Schemas[MAX_SCHEMAS];
|
||||
|
||||
MFC1KSchema Noralsy = {
|
||||
.name = "Noralsy",
|
||||
.trigger = 0x414c41524f4e,
|
||||
.keysA = {
|
||||
0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e,
|
||||
0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e,
|
||||
0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e, 0x414c41524f4e
|
||||
},
|
||||
.keysB = {
|
||||
0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e,
|
||||
0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e,
|
||||
0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e, 0x424c41524f4e
|
||||
}
|
||||
for (uint8_t i = 0; i < totalchunks; i++)
|
||||
{
|
||||
memset(chunk, 0x00, sizeof(chunk));
|
||||
memcpy(chunk, &bigar[i * chunksize], chunksize);
|
||||
DbprintfEx(FLAG_RAWPRINT, "%s", chunk);
|
||||
};
|
||||
|
||||
MFC1KSchema InfiHexact = {.name = "Infineon/Hexact",
|
||||
.trigger = 0x484558414354,
|
||||
.keysA = {0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354,
|
||||
0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354,
|
||||
0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354, 0x484558414354,
|
||||
0x484558414354
|
||||
},
|
||||
.keysB = {0xa22ae129c013, 0x49fae4e3849f, 0x38fcf33072e0, 0x8ad5517b4b18, 0x509359f131b1,
|
||||
0x6c78928e1317, 0xaa0720018738, 0xa6cac2886412, 0x62d0c424ed8e, 0xe64a986a5d94,
|
||||
0x8fa1d601d0a2, 0x89347350bd36, 0x66d2b7dc39ef, 0x6bc1e1ae547d, 0x22729a9bd40f
|
||||
}
|
||||
};
|
||||
|
||||
MFC1KSchema UrmetCaptive = {
|
||||
.name = "Urmet Captive",
|
||||
.trigger = 0x8829da9daf76,
|
||||
.keysA = {
|
||||
0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76,
|
||||
0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76,
|
||||
0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76
|
||||
},
|
||||
.keysB = {
|
||||
0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76,
|
||||
0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76,
|
||||
0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76, 0x8829da9daf76
|
||||
}
|
||||
if (last_chunksize > 0)
|
||||
{
|
||||
memset(chunk, 0x00, sizeof(chunk));
|
||||
memcpy(chunk, &bigar[totalchunks * chunksize], last_chunksize);
|
||||
DbprintfEx(FLAG_RAWPRINT, "%s", chunk);
|
||||
}
|
||||
if (newlines > 0)
|
||||
{
|
||||
DbprintfEx(FLAG_NEWLINE, " ");
|
||||
};
|
||||
|
||||
int total_schemas = 0;
|
||||
|
||||
void add_schema(MFC1KSchema *p, MFC1KSchema a, int *schemas_counter) {
|
||||
if (*schemas_counter < MAX_SCHEMAS) {
|
||||
p[*schemas_counter] = a;
|
||||
*schemas_counter += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void delete_schema(MFC1KSchema *p, int *schemas_counter, int index) {
|
||||
if (*schemas_counter > 0 && index < *schemas_counter && index > -1) {
|
||||
int last_index = *schemas_counter - 1;
|
||||
for (int i = index; i < last_index; i++) {
|
||||
p[i] = p[i + 1];
|
||||
}
|
||||
*schemas_counter -= 1;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void cjSetCursFRight() {
|
||||
vtsend_cursor_position(NULL, 98, (currfline));
|
||||
@@ -81,9 +120,8 @@ void cjTabulize() { DbprintfEx(FLAG_RAWPRINT, "\t\t\t"); }
|
||||
/*
|
||||
void cjPrintKey(uint64_t key, uint8_t *foundKey, uint16_t sectorNo, uint8_t type) {
|
||||
char tosendkey[13];
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[0], foundKey[1], foundKey[2], foundKey[3], foundKey[4], foundKey[5]);
|
||||
cjSetCursRight();
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x | KEY : %s | TYP: %d", sectorNo, tosendkey, type);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[0], foundKey[1], foundKey[2], foundKey[3], foundKey[4],
|
||||
foundKey[5]); cjSetCursRight(); DbprintfEx(FLAG_NEWLINE, "SEC: %02x | KEY : %s | TYP: %d", sectorNo, tosendkey, type);
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -101,7 +139,7 @@ void ReadLastTagFromFlash() {
|
||||
|
||||
uint8_t *mem = BigBuf_malloc(size);
|
||||
|
||||
//this one will handle filetype (symlink or not) and resolving by itself
|
||||
// this one will handle filetype (symlink or not) and resolving by itself
|
||||
rdv40_spiffs_read_as_filetype((char *)HFCOLIN_LASTTAG_SYMLINK, (uint8_t *)mem, len, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
|
||||
emlSetMem(mem, 0, 64);
|
||||
@@ -129,8 +167,9 @@ void WriteTagToFlash(uint32_t uid, size_t size) {
|
||||
num_to_bytes(uid, 4, buid);
|
||||
sprintf(dest, "hf_colin/mf_%02x%02x%02x%02x.bin", buid[0], buid[1], buid[2], buid[3]);
|
||||
|
||||
// TODO : by using safe function for multiple writes we are both breaking cache mecanisms and making useless and unoptimized mount operations
|
||||
// we should manage at out level the mount status before and after the whole standalone mode
|
||||
// TODO : by using safe function for multiple writes we are both breaking cache mecanisms and making useless and
|
||||
// unoptimized mount operations we should manage at out level the mount status before and after the whole standalone
|
||||
// mode
|
||||
rdv40_spiffs_write((char *)dest, (uint8_t *)data, len, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
// lastag will only contain filename/path to last written tag file so we don't loose time or space.
|
||||
rdv40_spiffs_make_symlink((char *)dest, (char *)HFCOLIN_LASTTAG_SYMLINK, RDV40_SPIFFS_SAFETY_SAFE);
|
||||
@@ -141,12 +180,15 @@ void WriteTagToFlash(uint32_t uid, size_t size) {
|
||||
return;
|
||||
}
|
||||
|
||||
void ModInfo(void) {
|
||||
DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)");
|
||||
}
|
||||
void ModInfo(void) { DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)"); }
|
||||
|
||||
void RunMod() {
|
||||
StandAloneMode();
|
||||
|
||||
add_schema(Schemas, Noralsy, &total_schemas);
|
||||
add_schema(Schemas, InfiHexact, &total_schemas);
|
||||
add_schema(Schemas, UrmetCaptive, &total_schemas);
|
||||
|
||||
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
|
||||
|
||||
currline = 20;
|
||||
@@ -155,7 +197,7 @@ void RunMod() {
|
||||
memset(cjuid, 0, sizeof(cjuid));
|
||||
cjcuid = 0;
|
||||
uint8_t sectorsCnt = (MF1KSZ / MF1KSZSIZE);
|
||||
uint64_t key64; // Defines current key
|
||||
uint64_t key64; // Defines current key
|
||||
uint8_t *keyBlock; // Where the keys will be held in memory.
|
||||
|
||||
/* VIGIK EXPIRED DUMP FOR STUDY
|
||||
@@ -194,11 +236,11 @@ void RunMod() {
|
||||
ACCBITS : 796788[00]+VALUE
|
||||
*/
|
||||
|
||||
//----------------------------
|
||||
// Set of keys to be used.
|
||||
// This should cover ~98% of
|
||||
// French VIGIK system @2017
|
||||
//----------------------------
|
||||
//----------------------------
|
||||
// Set of keys to be used.
|
||||
// This should cover ~98% of
|
||||
// French VIGIK system @2017
|
||||
//----------------------------
|
||||
|
||||
#define STKEYS 37
|
||||
|
||||
@@ -295,7 +337,7 @@ failtag:
|
||||
SpinOff(50);
|
||||
LED_A_ON();
|
||||
uint8_t ticker = 0;
|
||||
//while (!BUTTON_PRESS() && !iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true))
|
||||
// while (!BUTTON_PRESS() && !iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true))
|
||||
while (!iso14443a_select_card(cjuid, &p_card, &cjcuid, true, 0, true)) {
|
||||
WDT_HIT();
|
||||
|
||||
@@ -377,8 +419,8 @@ failtag:
|
||||
if (key == -1) {
|
||||
err = 1;
|
||||
allKeysFound = false;
|
||||
// used in portable imlementation on microcontroller: it reports back the fail and open the standalone lock
|
||||
// reply_old(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0);
|
||||
// used in portable imlementation on microcontroller: it reports back the fail and open the standalone
|
||||
// lock reply_old(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0);
|
||||
break;
|
||||
} else if (key == -2) {
|
||||
err = 1; // Can't select card.
|
||||
@@ -393,10 +435,10 @@ failtag:
|
||||
cjSetCursRight();
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %012" PRIx64 " ; TYP: %i", sec, key64, type);
|
||||
/*reply_old(CMD_CJB_INFORM_CLIENT_KEY, 12, sec, type, tosendkey, 12);*/
|
||||
switch (key64) {
|
||||
/////////////////////////////////////////////////////////
|
||||
// COMMON SCHEME 1 : INFINITRON/HEXACT
|
||||
case 0x484558414354:
|
||||
|
||||
for (int i = 0; i < total_schemas; i++) {
|
||||
if (key64 == Schemas[i].trigger) {
|
||||
|
||||
cjSetCursLeft();
|
||||
DbprintfEx(FLAG_NEWLINE, "%s>>>>>>>>>>>>!*STOP*!<<<<<<<<<<<<<<%s", _XRED_, _XWHITE_);
|
||||
cjSetCursLeft();
|
||||
@@ -404,232 +446,36 @@ failtag:
|
||||
DbprintfEx(FLAG_NEWLINE, " .TAG SEEMS %sDETERMINISTIC%s. ", _XGREEN_, _XWHITE_);
|
||||
cjSetCursLeft();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "%sDetected: %s INFI_HEXACT_VIGIK_TAG%s", _XORANGE_, _XCYAN_, _XWHITE_);
|
||||
DbprintfEx(FLAG_NEWLINE, "%sDetected: %s %s%s", _XORANGE_, _XCYAN_, Schemas[i].name, _XWHITE_);
|
||||
cjSetCursLeft();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "...%s[%sKey_derivation_schemeTest%s]%s...", _XYELLOW_, _XGREEN_, _XYELLOW_, _XGREEN_);
|
||||
DbprintfEx(FLAG_NEWLINE, "...%s[%sKey_derivation_schemeTest%s]%s...", _XYELLOW_, _XGREEN_,
|
||||
_XYELLOW_, _XGREEN_);
|
||||
cjSetCursLeft();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "%s>>>>>>>>>>>>!*DONE*!<<<<<<<<<<<<<<%s", _XGREEN_, _XWHITE_);
|
||||
;
|
||||
// Type 0 / A first
|
||||
|
||||
uint16_t t = 0;
|
||||
for (uint16_t s = 0; s < sectorsCnt; s++) {
|
||||
num_to_bytes(0x484558414354, 6, foundKey[t][s]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][s][0], foundKey[t][s][1], foundKey[t][s][2],
|
||||
foundKey[t][s][3], foundKey[t][s][4], foundKey[t][s][5]);
|
||||
num_to_bytes(Schemas[i].keysA[s], 6, foundKey[t][s]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][s][0], foundKey[t][s][1],
|
||||
foundKey[t][s][2], foundKey[t][s][3], foundKey[t][s][4], foundKey[t][s][5]);
|
||||
cjSetCursRight();
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", s, tosendkey, t);
|
||||
}
|
||||
t = 1;
|
||||
uint16_t sectorNo = 0;
|
||||
num_to_bytes(0xa22ae129c013, 6, foundKey[t][sectorNo]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
|
||||
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
|
||||
cjSetCursRight();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
|
||||
sectorNo = 1;
|
||||
num_to_bytes(0x49fae4e3849f, 6, foundKey[t][sectorNo]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
|
||||
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
|
||||
cjSetCursRight();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
|
||||
sectorNo = 2;
|
||||
num_to_bytes(0x38fcf33072e0, 6, foundKey[t][sectorNo]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
|
||||
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
|
||||
cjSetCursRight();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
|
||||
sectorNo = 3;
|
||||
num_to_bytes(0x8ad5517b4b18, 6, foundKey[t][sectorNo]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
|
||||
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
|
||||
cjSetCursRight();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
|
||||
sectorNo = 4;
|
||||
num_to_bytes(0x509359f131b1, 6, foundKey[t][sectorNo]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
|
||||
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
|
||||
cjSetCursRight();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
|
||||
sectorNo = 5;
|
||||
num_to_bytes(0x6c78928e1317, 6, foundKey[t][sectorNo]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
|
||||
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
|
||||
cjSetCursRight();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
|
||||
sectorNo = 6;
|
||||
num_to_bytes(0xaa0720018738, 6, foundKey[t][sectorNo]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
|
||||
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
|
||||
cjSetCursRight();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
|
||||
sectorNo = 7;
|
||||
num_to_bytes(0xa6cac2886412, 6, foundKey[t][sectorNo]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
|
||||
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
|
||||
cjSetCursRight();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
|
||||
sectorNo = 8;
|
||||
num_to_bytes(0x62d0c424ed8e, 6, foundKey[t][sectorNo]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
|
||||
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
|
||||
cjSetCursRight();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
|
||||
sectorNo = 9;
|
||||
num_to_bytes(0xe64a986a5d94, 6, foundKey[t][sectorNo]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
|
||||
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
|
||||
cjSetCursRight();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
|
||||
sectorNo = 10;
|
||||
num_to_bytes(0x8fa1d601d0a2, 6, foundKey[t][sectorNo]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
|
||||
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
|
||||
cjSetCursRight();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
|
||||
sectorNo = 11;
|
||||
num_to_bytes(0x89347350bd36, 6, foundKey[t][sectorNo]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
|
||||
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
|
||||
cjSetCursRight();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
|
||||
sectorNo = 12;
|
||||
num_to_bytes(0x66d2b7dc39ef, 6, foundKey[t][sectorNo]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
|
||||
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
|
||||
cjSetCursRight();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
|
||||
sectorNo = 13;
|
||||
num_to_bytes(0x6bc1e1ae547d, 6, foundKey[t][sectorNo]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
|
||||
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
|
||||
cjSetCursRight();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
|
||||
sectorNo = 14;
|
||||
num_to_bytes(0x22729a9bd40f, 6, foundKey[t][sectorNo]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
|
||||
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
|
||||
cjSetCursRight();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
|
||||
sectorNo = 15;
|
||||
num_to_bytes(0x484558414354, 6, foundKey[t][sectorNo]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2],
|
||||
foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
|
||||
cjSetCursRight();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", sectorNo, tosendkey, t);
|
||||
trapped = 1;
|
||||
break;
|
||||
////////////////END OF SCHEME 1//////////////////////////////
|
||||
|
||||
///////////////////////////////////////
|
||||
// COMMON SCHEME 2 : URMET CAPTIVE / COGELEC!/?
|
||||
case 0x8829da9daf76:
|
||||
cjSetCursLeft();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "%s>>>>>>>>>>>>!*STOP*!<<<<<<<<<<<<<<%s", _XRED_, _XWHITE_);
|
||||
cjSetCursLeft();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, " .TAG SEEMS %sDETERMINISTIC%s. ", _XGREEN_, _XWHITE_);
|
||||
cjSetCursLeft();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "%sDetected :%sURMET_CAPTIVE_VIGIK_TAG%s", _XORANGE_, _XCYAN_, _XWHITE_);
|
||||
cjSetCursLeft();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "...%s[%sKey_derivation_schemeTest%s]%s...", _XYELLOW_, _XGREEN_, _XYELLOW_, _XGREEN_);
|
||||
cjSetCursLeft();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "%s>>>>>>>>>>>>!*DONE*!<<<<<<<<<<<<<<%s", _XGREEN_, _XWHITE_);
|
||||
cjSetCursLeft();
|
||||
|
||||
// emlClearMem();
|
||||
// A very weak one...
|
||||
for (uint16_t i = 0; i < 2; i++) {
|
||||
for (uint16_t s = 0; s < sectorsCnt; s++) {
|
||||
num_to_bytes(key64, 6, foundKey[i][s]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x",
|
||||
foundKey[i][s][0],
|
||||
foundKey[i][s][1],
|
||||
foundKey[i][s][2],
|
||||
foundKey[i][s][3],
|
||||
foundKey[i][s][4],
|
||||
foundKey[i][s][5]
|
||||
);
|
||||
cjSetCursRight();
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", s, tosendkey, i);
|
||||
}
|
||||
}
|
||||
trapped = 1;
|
||||
break;
|
||||
////////////////END OF SCHEME 2//////////////////////////////
|
||||
|
||||
///////////////////////////////////////
|
||||
// COMMON SCHEME 3 : NORALSY "A-LARON & B-LARON . . . NORAL-B & NORAL-A"
|
||||
case 0x414c41524f4e: // Thumbs up to the guy who had the idea of such a "mnemotechnical" key pair
|
||||
case 0x424c41524f4e:
|
||||
cjSetCursLeft();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "%s>>>>>>>>>>>>!*STOP*!<<<<<<<<<<<<<<%s", _XRED_, _XWHITE_);
|
||||
cjSetCursLeft();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, " .TAG SEEMS %sDETERMINISTIC%s. ", _XGREEN_, _XWHITE_);
|
||||
cjSetCursLeft();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "%s Detected :%sNORALSY_VIGIK_TAG %s", _XORANGE_, _XCYAN_, _XWHITE_);
|
||||
cjSetCursLeft();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "...%s[%sKey_derivation_schemeTest%s]%s...", _XYELLOW_, _XGREEN_, _XYELLOW_, _XGREEN_);
|
||||
cjSetCursLeft();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "%s>>>>>>>>>>>>!*DONE*!<<<<<<<<<<<<<<%s", _XGREEN_, _XWHITE_);
|
||||
|
||||
t = 0;
|
||||
for (uint16_t s = 0; s < sectorsCnt; s++) {
|
||||
num_to_bytes(0x414c41524f4e, 6, foundKey[t][s]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x",
|
||||
foundKey[t][s][0],
|
||||
foundKey[t][s][1],
|
||||
foundKey[t][s][2],
|
||||
foundKey[t][s][3],
|
||||
foundKey[t][s][4],
|
||||
foundKey[t][s][5]);
|
||||
cjSetCursRight();
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", s, tosendkey, t);
|
||||
}
|
||||
|
||||
t = 1;
|
||||
for (uint16_t s = 0; s < sectorsCnt; s++) {
|
||||
num_to_bytes(0x424c41524f4e, 6, foundKey[t][s]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x",
|
||||
foundKey[t][s][0],
|
||||
foundKey[t][s][1],
|
||||
foundKey[t][s][2],
|
||||
foundKey[t][s][3],
|
||||
foundKey[t][s][4],
|
||||
foundKey[t][s][5]);
|
||||
num_to_bytes(Schemas[i].keysB[s], 6, foundKey[t][s]);
|
||||
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][s][0], foundKey[t][s][1],
|
||||
foundKey[t][s][2], foundKey[t][s][3], foundKey[t][s][4], foundKey[t][s][5]);
|
||||
cjSetCursRight();
|
||||
DbprintfEx(FLAG_NEWLINE, "SEC: %02x ; KEY : %s ; TYP: %d", s, tosendkey, t);
|
||||
}
|
||||
trapped = 1;
|
||||
break;
|
||||
////////////////END OF SCHEME 3//////////////////////////////
|
||||
}
|
||||
}
|
||||
|
||||
/* etc etc for testing schemes quick schemes */
|
||||
}
|
||||
}
|
||||
@@ -685,7 +531,8 @@ failtag:
|
||||
delta_time = GetTickCountDelta(start_time);
|
||||
cjSetCursLeft();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "%s>>%s Time for VIGIK break :%s%dms%s", _XGREEN_, _XWHITE_, _XYELLOW_, delta_time, _XWHITE_);
|
||||
DbprintfEx(FLAG_NEWLINE, "%s>>%s Time for VIGIK break :%s%dms%s", _XGREEN_, _XWHITE_, _XYELLOW_, delta_time,
|
||||
_XWHITE_);
|
||||
|
||||
vtsend_cursor_position_save(NULL);
|
||||
vtsend_set_attribute(NULL, 1);
|
||||
@@ -706,8 +553,9 @@ readysim:
|
||||
DbprintfEx(FLAG_NEWLINE, "%s!> HOLD ON : %s When you'll click, simm will stop", _XRED_, _XWHITE_);
|
||||
cjSetCursLeft();
|
||||
|
||||
DbprintfEx(FLAG_NEWLINE, "Then %s immediately %s we'll try to %s dump our emulator state%s \r\nin a %s chinese tag%s", _XRED_, _XWHITE_, _XYELLOW_, _XWHITE_,
|
||||
_XCYAN_, _XWHITE_);
|
||||
DbprintfEx(FLAG_NEWLINE,
|
||||
"Then %s immediately %s we'll try to %s dump our emulator state%s \r\nin a %s chinese tag%s", _XRED_,
|
||||
_XWHITE_, _XYELLOW_, _XWHITE_, _XCYAN_, _XWHITE_);
|
||||
cjSetCursLeft();
|
||||
cjSetCursLeft();
|
||||
|
||||
@@ -736,7 +584,7 @@ readysim:
|
||||
}
|
||||
|
||||
// Use UID, SAK, ATQA from EMUL, if uid not defined
|
||||
//if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) {
|
||||
// if ((flags & (FLAG_4B_UID_IN_DATA | FLAG_7B_UID_IN_DATA | FLAG_10B_UID_IN_DATA)) == 0) {
|
||||
flags |= FLAG_UID_IN_EMUL;
|
||||
//}
|
||||
Mifare1ksim(flags | FLAG_MF_1K, 0, cjuid);
|
||||
@@ -856,7 +704,8 @@ int e_MifareECardLoad(uint32_t numofsectors, uint8_t keytype) {
|
||||
|
||||
/* the chk function is a piwi'ed(tm) check that will try all keys for
|
||||
a particular sector. also no tracing no dbg */
|
||||
int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain, uint64_t *key) {
|
||||
int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain,
|
||||
uint64_t *key) {
|
||||
DBGLEVEL = DBG_NONE;
|
||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||
set_tracing(false);
|
||||
@@ -961,8 +810,7 @@ void saMifareMakeTag(void) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//TODO : make this work either for a Gen1a or for a block 0 direct write all transparently
|
||||
// TODO : make this work either for a Gen1a or for a block 0 direct write all transparently
|
||||
//-----------------------------------------------------------------------------
|
||||
// Matt's StandAlone mod.
|
||||
// Work with "magic Chinese" card (email him: ouyangweidaxian@live.cn)
|
||||
@@ -1049,7 +897,8 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
|
||||
};
|
||||
}
|
||||
|
||||
if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) || (receivedAnswer[0] != 0x0a)) {
|
||||
if ((mifare_sendcmd_short(NULL, 0, 0xA0, blockNo, receivedAnswer, receivedAnswerPar, NULL) != 1) ||
|
||||
(receivedAnswer[0] != 0x0a)) {
|
||||
DbprintfEx(FLAG_NEWLINE, "write block send command error");
|
||||
break;
|
||||
};
|
||||
|
||||
@@ -72,6 +72,13 @@ STANDALONE_MODES := LF_SAMYRUN LF_ICERUN LF_PROXBRUTE LF_HIDBRUTE LF_FOO
|
||||
STANDALONE_MODES += HF_YOUNG HF_MATTYRUN HF_COLIN HF_BOG
|
||||
```
|
||||
|
||||
If your mode is using one of the unique features of the RDV4, add it to the proper list:
|
||||
|
||||
```
|
||||
STANDALONE_MODES_REQ_SMARTCARD :=
|
||||
STANDALONE_MODES_REQ_FLASH := HF_COLIN HF_BOG
|
||||
```
|
||||
|
||||
## Update MAKEFILE.INC
|
||||
Add your source code files like the following sample in the `Makefile.inc`
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ typedef struct {
|
||||
#endif
|
||||
|
||||
#ifndef CheckCrc14A
|
||||
# define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len))
|
||||
# define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len))
|
||||
#endif
|
||||
|
||||
void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par);
|
||||
|
||||
@@ -11,57 +11,57 @@ INCLUDE ../common/ldscript.common
|
||||
|
||||
PHDRS
|
||||
{
|
||||
text PT_LOAD FLAGS(5);
|
||||
data PT_LOAD;
|
||||
bss PT_LOAD;
|
||||
text PT_LOAD FLAGS(5);
|
||||
data PT_LOAD;
|
||||
bss PT_LOAD;
|
||||
}
|
||||
|
||||
ENTRY(Vector)
|
||||
SECTIONS
|
||||
{
|
||||
.start : {
|
||||
*(.startos)
|
||||
} >osimage :text
|
||||
.start : {
|
||||
*(.startos)
|
||||
} >osimage :text
|
||||
|
||||
.text : {
|
||||
KEEP(*(stage1_image))
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.eh_frame)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
} >osimage :text
|
||||
.text : {
|
||||
KEEP(*(stage1_image))
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.eh_frame)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
} >osimage :text
|
||||
|
||||
.rodata : {
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(fpga_all_bit.data)
|
||||
KEEP(*(.version_information))
|
||||
. = ALIGN(8);
|
||||
} >osimage :text
|
||||
.rodata : {
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(fpga_all_bit.data)
|
||||
KEEP(*(.version_information))
|
||||
. = ALIGN(8);
|
||||
} >osimage :text
|
||||
|
||||
.data : {
|
||||
KEEP(*(compressed_data))
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.ramfunc)
|
||||
. = ALIGN(4);
|
||||
} >ram AT>osimage :data
|
||||
.data : {
|
||||
KEEP(*(compressed_data))
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.ramfunc)
|
||||
. = ALIGN(4);
|
||||
} >ram AT>osimage :data
|
||||
|
||||
__data_src_start__ = LOADADDR(.data);
|
||||
__data_start__ = ADDR(.data);
|
||||
__data_end__ = __data_start__ + SIZEOF(.data);
|
||||
__os_size__ = SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.rodata);
|
||||
|
||||
.bss : {
|
||||
__bss_start__ = .;
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
. = ALIGN(4);
|
||||
__bss_end__ = .;
|
||||
} >ram AT>ram :bss
|
||||
__data_src_start__ = LOADADDR(.data);
|
||||
__data_start__ = ADDR(.data);
|
||||
__data_end__ = __data_start__ + SIZEOF(.data);
|
||||
__os_size__ = SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.rodata);
|
||||
|
||||
.bss : {
|
||||
__bss_start__ = .;
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
. = ALIGN(4);
|
||||
__bss_end__ = .;
|
||||
} >ram AT>ram :bss
|
||||
|
||||
.commonarea (NOLOAD) : {
|
||||
*(.commonarea)
|
||||
} >commonarea :NONE
|
||||
.commonarea (NOLOAD) : {
|
||||
*(.commonarea)
|
||||
} >commonarea :NONE
|
||||
}
|
||||
|
||||
@@ -42,30 +42,36 @@ static bool IsTrailerAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t act
|
||||
| ((sector_trailer[8] >> 7) & 0x01);
|
||||
switch (action) {
|
||||
case AC_KEYA_READ: {
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsTrailerAccessAllowed: AC_KEYA_READ");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("IsTrailerAccessAllowed: AC_KEYA_READ");
|
||||
return false;
|
||||
}
|
||||
case AC_KEYA_WRITE: {
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsTrailerAccessAllowed: AC_KEYA_WRITE");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("IsTrailerAccessAllowed: AC_KEYA_WRITE");
|
||||
return ((keytype == AUTHKEYA && (AC == 0x00 || AC == 0x01))
|
||||
|| (keytype == AUTHKEYB && (AC == 0x04 || AC == 0x03)));
|
||||
}
|
||||
case AC_KEYB_READ: {
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsTrailerAccessAllowed: AC_KEYB_READ");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("IsTrailerAccessAllowed: AC_KEYB_READ");
|
||||
return (keytype == AUTHKEYA && (AC == 0x00 || AC == 0x02 || AC == 0x01));
|
||||
}
|
||||
case AC_KEYB_WRITE: {
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsTrailerAccessAllowed: AC_KEYB_WRITE");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("IsTrailerAccessAllowed: AC_KEYB_WRITE");
|
||||
return ((keytype == AUTHKEYA && (AC == 0x00 || AC == 0x01))
|
||||
|| (keytype == AUTHKEYB && (AC == 0x04 || AC == 0x03)));
|
||||
}
|
||||
case AC_AC_READ: {
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsTrailerAccessAllowed: AC_AC_READ");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("IsTrailerAccessAllowed: AC_AC_READ");
|
||||
return ((keytype == AUTHKEYA)
|
||||
|| (keytype == AUTHKEYB && !(AC == 0x00 || AC == 0x02 || AC == 0x01)));
|
||||
}
|
||||
case AC_AC_WRITE: {
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsTrailerAccessAllowed: AC_AC_WRITE");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("IsTrailerAccessAllowed: AC_AC_WRITE");
|
||||
return ((keytype == AUTHKEYA && (AC == 0x01))
|
||||
|| (keytype == AUTHKEYB && (AC == 0x03 || AC == 0x05)));
|
||||
}
|
||||
@@ -93,46 +99,54 @@ static bool IsDataAccessAllowed(uint8_t blockNo, uint8_t keytype, uint8_t action
|
||||
AC = ((sector_trailer[7] >> 2) & 0x04)
|
||||
| ((sector_trailer[8] << 1) & 0x02)
|
||||
| ((sector_trailer[8] >> 4) & 0x01);
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed: case 0x00 - %02x", AC);
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("IsDataAccessAllowed: case 0x00 - %02x", AC);
|
||||
break;
|
||||
}
|
||||
case 0x01: {
|
||||
AC = ((sector_trailer[7] >> 3) & 0x04)
|
||||
| ((sector_trailer[8] >> 0) & 0x02)
|
||||
| ((sector_trailer[8] >> 5) & 0x01);
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed: case 0x01 - %02x", AC);
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("IsDataAccessAllowed: case 0x01 - %02x", AC);
|
||||
break;
|
||||
}
|
||||
case 0x02: {
|
||||
AC = ((sector_trailer[7] >> 4) & 0x04)
|
||||
| ((sector_trailer[8] >> 1) & 0x02)
|
||||
| ((sector_trailer[8] >> 6) & 0x01);
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed: case 0x02 - %02x", AC);
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("IsDataAccessAllowed: case 0x02 - %02x", AC);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed: Error");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("IsDataAccessAllowed: Error");
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case AC_DATA_READ: {
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed - AC_DATA_READ: OK");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("IsDataAccessAllowed - AC_DATA_READ: OK");
|
||||
return ((keytype == AUTHKEYA && !(AC == 0x03 || AC == 0x05 || AC == 0x07))
|
||||
|| (keytype == AUTHKEYB && !(AC == 0x07)));
|
||||
}
|
||||
case AC_DATA_WRITE: {
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed - AC_DATA_WRITE: OK");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("IsDataAccessAllowed - AC_DATA_WRITE: OK");
|
||||
return ((keytype == AUTHKEYA && (AC == 0x00))
|
||||
|| (keytype == AUTHKEYB && (AC == 0x00 || AC == 0x04 || AC == 0x06 || AC == 0x03)));
|
||||
}
|
||||
case AC_DATA_INC: {
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("IsDataAccessAllowed - AC_DATA_INC: OK");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("IsDataAccessAllowed - AC_DATA_INC: OK");
|
||||
return ((keytype == AUTHKEYA && (AC == 0x00))
|
||||
|| (keytype == AUTHKEYB && (AC == 0x00 || AC == 0x06)));
|
||||
}
|
||||
case AC_DATA_DEC_TRANS_REST: {
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("AC_DATA_DEC_TRANS_REST: OK");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("AC_DATA_DEC_TRANS_REST: OK");
|
||||
return ((keytype == AUTHKEYA && (AC == 0x00 || AC == 0x06 || AC == 0x01))
|
||||
|| (keytype == AUTHKEYB && (AC == 0x00 || AC == 0x06 || AC == 0x01)));
|
||||
}
|
||||
@@ -160,25 +174,25 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t *
|
||||
|
||||
// SAK
|
||||
static uint8_t rSAK_Mini = 0x09; // mifare Mini
|
||||
static uint8_t rSAK_1k = 0x08; // mifare 1k
|
||||
static uint8_t rSAK_2k = 0x08; // mifare 2k with RATS support
|
||||
static uint8_t rSAK_4k = 0x18; // mifare 4k
|
||||
static uint8_t rSAK_1k = 0x08; // mifare 1k
|
||||
static uint8_t rSAK_2k = 0x08; // mifare 2k with RATS support
|
||||
static uint8_t rSAK_4k = 0x18; // mifare 4k
|
||||
|
||||
static uint8_t rUIDBCC1[] = {0x00, 0x00, 0x00, 0x00, 0x00}; // UID 1st cascade level
|
||||
static uint8_t rUIDBCC1b4[] = {0x00, 0x00, 0x00, 0x00}; // UID 1st cascade level, last 4 bytes
|
||||
static uint8_t rUIDBCC1b3[] = {0x00, 0x00, 0x00}; // UID 1st cascade level, last 3 bytes
|
||||
static uint8_t rUIDBCC1b2[] = {0x00, 0x00}; // UID 1st cascade level, last 2 bytes
|
||||
static uint8_t rUIDBCC1b1[] = {0x00}; // UID 1st cascade level, last byte
|
||||
static uint8_t rUIDBCC2[] = {0x00, 0x00, 0x00, 0x00, 0x00}; // UID 2nd cascade level
|
||||
static uint8_t rUIDBCC2b4[] = {0x00, 0x00, 0x00, 0x00}; // UID 2st cascade level, last 4 bytes
|
||||
static uint8_t rUIDBCC2b3[] = {0x00, 0x00, 0x00}; // UID 2st cascade level, last 3 bytes
|
||||
static uint8_t rUIDBCC2b2[] = {0x00, 0x00}; // UID 2st cascade level, last 2 bytes
|
||||
static uint8_t rUIDBCC2b1[] = {0x00}; // UID 2st cascade level, last byte
|
||||
static uint8_t rUIDBCC3[] = {0x00, 0x00, 0x00, 0x00, 0x00}; // UID 3nd cascade level
|
||||
static uint8_t rUIDBCC3b4[] = {0x00, 0x00, 0x00, 0x00}; // UID 3st cascade level, last 4 bytes
|
||||
static uint8_t rUIDBCC3b3[] = {0x00, 0x00, 0x00}; // UID 3st cascade level, last 3 bytes
|
||||
static uint8_t rUIDBCC3b2[] = {0x00, 0x00}; // UID 3st cascade level, last 2 bytes
|
||||
static uint8_t rUIDBCC3b1[] = {0x00}; // UID 3st cascade level, last byte
|
||||
static uint8_t rUIDBCC1[] = {0x00, 0x00, 0x00, 0x00, 0x00}; // UID 1st cascade level
|
||||
static uint8_t rUIDBCC1b4[] = {0x00, 0x00, 0x00, 0x00}; // UID 1st cascade level, last 4 bytes
|
||||
static uint8_t rUIDBCC1b3[] = {0x00, 0x00, 0x00}; // UID 1st cascade level, last 3 bytes
|
||||
static uint8_t rUIDBCC1b2[] = {0x00, 0x00}; // UID 1st cascade level, last 2 bytes
|
||||
static uint8_t rUIDBCC1b1[] = {0x00}; // UID 1st cascade level, last byte
|
||||
static uint8_t rUIDBCC2[] = {0x00, 0x00, 0x00, 0x00, 0x00}; // UID 2nd cascade level
|
||||
static uint8_t rUIDBCC2b4[] = {0x00, 0x00, 0x00, 0x00}; // UID 2st cascade level, last 4 bytes
|
||||
static uint8_t rUIDBCC2b3[] = {0x00, 0x00, 0x00}; // UID 2st cascade level, last 3 bytes
|
||||
static uint8_t rUIDBCC2b2[] = {0x00, 0x00}; // UID 2st cascade level, last 2 bytes
|
||||
static uint8_t rUIDBCC2b1[] = {0x00}; // UID 2st cascade level, last byte
|
||||
static uint8_t rUIDBCC3[] = {0x00, 0x00, 0x00, 0x00, 0x00}; // UID 3nd cascade level
|
||||
static uint8_t rUIDBCC3b4[] = {0x00, 0x00, 0x00, 0x00}; // UID 3st cascade level, last 4 bytes
|
||||
static uint8_t rUIDBCC3b3[] = {0x00, 0x00, 0x00}; // UID 3st cascade level, last 3 bytes
|
||||
static uint8_t rUIDBCC3b2[] = {0x00, 0x00}; // UID 3st cascade level, last 2 bytes
|
||||
static uint8_t rUIDBCC3b1[] = {0x00}; // UID 3st cascade level, last byte
|
||||
|
||||
static uint8_t rATQA[] = {0x00, 0x00}; // Current ATQA
|
||||
static uint8_t rSAK[] = {0x00, 0x00, 0x00}; // Current SAK, CRC
|
||||
@@ -254,17 +268,18 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t *
|
||||
}
|
||||
|
||||
// Prepare UID arrays
|
||||
if ((flags & FLAG_4B_UID_IN_DATA) == FLAG_4B_UID_IN_DATA) { // get UID from datain
|
||||
if ((flags & FLAG_4B_UID_IN_DATA) == FLAG_4B_UID_IN_DATA) { // get UID from datain
|
||||
memcpy(rUIDBCC1, datain, 4);
|
||||
*uid_len = 4;
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MifareSimInit - FLAG_4B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_4B_UID_IN_DATA, flags, rUIDBCC1);
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("MifareSimInit - FLAG_4B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_4B_UID_IN_DATA, flags, rUIDBCC1);
|
||||
|
||||
|
||||
// save CUID
|
||||
*cuid = bytes_to_num(rUIDBCC1, 4);
|
||||
// BCC
|
||||
rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3];
|
||||
if (DBGLEVEL >= DBG_NONE) {
|
||||
if (DBGLEVEL >= DBG_NONE) {
|
||||
Dbprintf("4B UID: %02x%02x%02x%02x", rUIDBCC1[0], rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3]);
|
||||
}
|
||||
|
||||
@@ -275,7 +290,8 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t *
|
||||
memcpy(&rUIDBCC1[1], datain, 3);
|
||||
memcpy(rUIDBCC2, datain + 3, 4);
|
||||
*uid_len = 7;
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MifareSimInit - FLAG_7B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_7B_UID_IN_DATA, flags, rUIDBCC1);
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("MifareSimInit - FLAG_7B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_7B_UID_IN_DATA, flags, rUIDBCC1);
|
||||
|
||||
// save CUID
|
||||
*cuid = bytes_to_num(rUIDBCC2, 4);
|
||||
@@ -284,7 +300,7 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t *
|
||||
// BCC
|
||||
rUIDBCC1[4] = rUIDBCC1[0] ^ rUIDBCC1[1] ^ rUIDBCC1[2] ^ rUIDBCC1[3];
|
||||
rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3];
|
||||
if (DBGLEVEL >= DBG_NONE) {
|
||||
if (DBGLEVEL >= DBG_NONE) {
|
||||
Dbprintf("7B UID: %02x %02x %02x %02x %02x %02x %02x",
|
||||
rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3], rUIDBCC2[0], rUIDBCC2[1], rUIDBCC2[2], rUIDBCC2[3]);
|
||||
}
|
||||
@@ -297,7 +313,8 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t *
|
||||
memcpy(&rUIDBCC2[1], datain + 3, 3);
|
||||
memcpy(rUIDBCC3, datain + 6, 4);
|
||||
*uid_len = 10;
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MifareSimInit - FLAG_10B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_10B_UID_IN_DATA, flags, rUIDBCC1);
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("MifareSimInit - FLAG_10B_UID_IN_DATA => Get UID from datain: %02X - Flag: %02X - UIDBCC1: %02X", FLAG_10B_UID_IN_DATA, flags, rUIDBCC1);
|
||||
|
||||
// save CUID
|
||||
*cuid = bytes_to_num(rUIDBCC3, 4);
|
||||
@@ -309,7 +326,7 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t *
|
||||
rUIDBCC2[4] = rUIDBCC2[0] ^ rUIDBCC2[1] ^ rUIDBCC2[2] ^ rUIDBCC2[3];
|
||||
rUIDBCC3[4] = rUIDBCC3[0] ^ rUIDBCC3[1] ^ rUIDBCC3[2] ^ rUIDBCC3[3];
|
||||
|
||||
if (DBGLEVEL >= DBG_NONE) {
|
||||
if (DBGLEVEL >= DBG_NONE) {
|
||||
Dbprintf("10B UID: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||
rUIDBCC1[1], rUIDBCC1[2], rUIDBCC1[3],
|
||||
rUIDBCC2[1], rUIDBCC2[2], rUIDBCC2[3],
|
||||
@@ -347,23 +364,23 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t *
|
||||
|
||||
#define TAG_RESPONSE_COUNT 18
|
||||
static tag_response_info_t responses_init[TAG_RESPONSE_COUNT] = {
|
||||
{ .response = rATQA, .response_n = sizeof(rATQA) }, // Answer to request - respond with card type
|
||||
{ .response = rATQA, .response_n = sizeof(rATQA) }, // Answer to request - respond with card type
|
||||
{ .response = rSAK, .response_n = sizeof(rSAK) }, //
|
||||
{ .response = rSAKuid, .response_n = sizeof(rSAKuid) }, //
|
||||
{ .response = rSAKuid, .response_n = sizeof(rSAKuid) }, //
|
||||
// Do not reorder. Block used via relative index of rUIDBCC1
|
||||
{ .response = rUIDBCC1, .response_n = sizeof(rUIDBCC1) }, // Anticollision cascade1 - respond with first part of uid
|
||||
{ .response = rUIDBCC1, .response_n = sizeof(rUIDBCC1) }, // Anticollision cascade1 - respond with first part of uid
|
||||
{ .response = rUIDBCC1b4, .response_n = sizeof(rUIDBCC1b4)},
|
||||
{ .response = rUIDBCC1b3, .response_n = sizeof(rUIDBCC1b3)},
|
||||
{ .response = rUIDBCC1b2, .response_n = sizeof(rUIDBCC1b2)},
|
||||
{ .response = rUIDBCC1b1, .response_n = sizeof(rUIDBCC1b1)},
|
||||
// Do not reorder. Block used via relative index of rUIDBCC2
|
||||
{ .response = rUIDBCC2, .response_n = sizeof(rUIDBCC2) }, // Anticollision cascade2 - respond with 2nd part of uid
|
||||
{ .response = rUIDBCC2, .response_n = sizeof(rUIDBCC2) }, // Anticollision cascade2 - respond with 2nd part of uid
|
||||
{ .response = rUIDBCC2b4, .response_n = sizeof(rUIDBCC2b4)},
|
||||
{ .response = rUIDBCC2b3, .response_n = sizeof(rUIDBCC2b3)},
|
||||
{ .response = rUIDBCC2b2, .response_n = sizeof(rUIDBCC2b2)},
|
||||
{ .response = rUIDBCC2b1, .response_n = sizeof(rUIDBCC2b1)},
|
||||
// Do not reorder. Block used via relative index of rUIDBCC3
|
||||
{ .response = rUIDBCC3, .response_n = sizeof(rUIDBCC3) }, // Anticollision cascade3 - respond with 3th part of uid
|
||||
{ .response = rUIDBCC3, .response_n = sizeof(rUIDBCC3) }, // Anticollision cascade3 - respond with 3th part of uid
|
||||
{ .response = rUIDBCC3b4, .response_n = sizeof(rUIDBCC3b4)},
|
||||
{ .response = rUIDBCC3b3, .response_n = sizeof(rUIDBCC3b3)},
|
||||
{ .response = rUIDBCC3b2, .response_n = sizeof(rUIDBCC3b2)},
|
||||
@@ -407,11 +424,11 @@ static bool MifareSimInit(uint16_t flags, uint8_t *datain, tag_response_info_t *
|
||||
*MIFARE 1K simulate.
|
||||
*
|
||||
*@param flags :
|
||||
* FLAG_INTERACTIVE - In interactive mode, we are expected to finish the operation with an ACK
|
||||
* FLAG_INTERACTIVE - In interactive mode, we are expected to finish the operation with an ACK
|
||||
* FLAG_4B_UID_IN_DATA - means that there is a 4-byte UID in the data-section, we're expected to use that
|
||||
* FLAG_7B_UID_IN_DATA - means that there is a 7-byte UID in the data-section, we're expected to use that
|
||||
* FLAG_10B_UID_IN_DATA - use 10-byte UID in the data-section not finished
|
||||
* FLAG_NR_AR_ATTACK - means we should collect NR_AR responses for bruteforcing later
|
||||
* FLAG_10B_UID_IN_DATA - use 10-byte UID in the data-section not finished
|
||||
* FLAG_NR_AR_ATTACK - means we should collect NR_AR responses for bruteforcing later
|
||||
*@param exitAfterNReads, exit simulation after n blocks have been read, 0 is infinite ...
|
||||
* (unless reader attack mode enabled then it runs util it gets enough nonces to recover all keys attmpted)
|
||||
*/
|
||||
@@ -421,7 +438,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
||||
uint8_t uid_len = 0; // 4,7, 10
|
||||
uint32_t cuid = 0;
|
||||
|
||||
int vHf = 0; // in mV
|
||||
int vHf = 0; // in mV
|
||||
|
||||
uint32_t selTimer = 0;
|
||||
uint32_t authTimer = 0;
|
||||
@@ -445,7 +462,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
||||
struct Crypto1State *pcs;
|
||||
pcs = &mpcs;
|
||||
|
||||
uint32_t numReads = 0; //Counts numer of times reader reads a block
|
||||
uint32_t numReads = 0; //Counts numer of times reader reads a block
|
||||
uint8_t receivedCmd[MAX_MIFARE_FRAME_SIZE] = {0x00};
|
||||
uint8_t receivedCmd_dec[MAX_MIFARE_FRAME_SIZE] = {0x00};
|
||||
uint8_t receivedCmd_par[MAX_MIFARE_PARITY_SIZE] = {0x00};
|
||||
@@ -467,11 +484,11 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
||||
|
||||
uint8_t ar_nr_collected[ATTACK_KEY_COUNT * 2]; //*2 for 2nd attack type (moebius)
|
||||
memset(ar_nr_collected, 0x00, sizeof(ar_nr_collected));
|
||||
uint8_t nonce1_count = 0;
|
||||
uint8_t nonce2_count = 0;
|
||||
uint8_t moebius_n_count = 0;
|
||||
uint8_t nonce1_count = 0;
|
||||
uint8_t nonce2_count = 0;
|
||||
uint8_t moebius_n_count = 0;
|
||||
bool gettingMoebius = false;
|
||||
uint8_t mM = 0; //moebius_modifier for collection storage
|
||||
uint8_t mM = 0; //moebius_modifier for collection storage
|
||||
|
||||
// Authenticate response - nonce
|
||||
uint8_t rAUTH_NT[4];
|
||||
@@ -520,18 +537,21 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
||||
if (res == 2) { //Field is off!
|
||||
LEDsoff();
|
||||
cardSTATE = MFEMUL_NOFIELD;
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("cardSTATE = MFEMUL_NOFIELD");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("cardSTATE = MFEMUL_NOFIELD");
|
||||
continue;
|
||||
} else if (res == 1) { // button pressed
|
||||
button_pushed = true;
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Button pressed");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("Button pressed");
|
||||
break;
|
||||
}
|
||||
|
||||
// WUPA in HALTED state or REQA or WUPA in any other state
|
||||
if (receivedCmd_len == 1 && ((receivedCmd[0] == ISO14443A_CMD_REQA && cardSTATE != MFEMUL_HALTED) || receivedCmd[0] == ISO14443A_CMD_WUPA)) {
|
||||
selTimer = GetTickCount();
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("EmSendPrecompiledCmd(&responses[ATQA]);");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("EmSendPrecompiledCmd(&responses[ATQA]);");
|
||||
EmSendPrecompiledCmd(&responses[ATQA]);
|
||||
|
||||
// init crypto block
|
||||
@@ -550,12 +570,15 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
||||
|
||||
switch (cardSTATE) {
|
||||
case MFEMUL_NOFIELD:
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MFEMUL_NOFIELD");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("MFEMUL_NOFIELD");
|
||||
case MFEMUL_HALTED:
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MFEMUL_HALTED");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("MFEMUL_HALTED");
|
||||
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);
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("MFEMUL_IDLE");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("MFEMUL_IDLE");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -649,7 +672,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
||||
// WORK
|
||||
case MFEMUL_WORK: {
|
||||
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] Enter in case");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("[MFEMUL_WORK] Enter in case");
|
||||
|
||||
if (receivedCmd_len == 0) {
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] NO CMD received");
|
||||
@@ -799,20 +823,20 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
||||
if (IsSectorTrailer(blockNo)) {
|
||||
|
||||
if (!IsAccessAllowed(blockNo, cardAUTHKEY, AC_KEYA_READ)) {
|
||||
memset(response, 0x00, 6); // keyA can never be read
|
||||
memset(response, 0x00, 6); // keyA can never be read
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK - IsSectorTrailer] keyA can never be read - block %d (0x%02x)", blockNo, blockNo);
|
||||
}
|
||||
if (!IsAccessAllowed(blockNo, cardAUTHKEY, AC_KEYB_READ)) {
|
||||
memset(response + 10, 0x00, 6); // keyB cannot be read
|
||||
memset(response + 10, 0x00, 6); // keyB cannot be read
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK - IsSectorTrailer] keyB cannot be read - block %d (0x%02x)", blockNo, blockNo);
|
||||
}
|
||||
if (!IsAccessAllowed(blockNo, cardAUTHKEY, AC_AC_READ)) {
|
||||
memset(response + 6, 0x00, 4); // AC bits cannot be read
|
||||
memset(response + 6, 0x00, 4); // AC bits cannot be read
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK - IsAccessAllowed] AC bits cannot be read - block %d (0x%02x)", blockNo, blockNo);
|
||||
}
|
||||
} else {
|
||||
if (!IsAccessAllowed(blockNo, cardAUTHKEY, AC_DATA_READ)) {
|
||||
memset(response, 0x00, 16); // datablock cannot be read
|
||||
memset(response, 0x00, 16); // datablock cannot be read
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK - IsAccessAllowed] Data block %d (0x%02x) cannot be read", blockNo, blockNo);
|
||||
}
|
||||
}
|
||||
@@ -898,7 +922,8 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
||||
LED_C_OFF();
|
||||
cardSTATE = MFEMUL_HALTED;
|
||||
cardAUTHKEY = AUTHKEYNONE;
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] cardSTATE = MFEMUL_HALTED");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("[MFEMUL_WORK] cardSTATE = MFEMUL_HALTED");
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -911,10 +936,12 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
||||
EmSendCmdPar(response, rats_len, response_par);
|
||||
} else
|
||||
EmSendCmd(rats, rats_len);
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RCV RATS => ACK");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("[MFEMUL_WORK] RCV RATS => ACK");
|
||||
} else {
|
||||
EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA);
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RCV RATS => NACK");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("[MFEMUL_WORK] RCV RATS => NACK");
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -929,28 +956,33 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
||||
EmSendCmdPar(response, receivedCmd_len, response_par);
|
||||
} else
|
||||
EmSendCmd(receivedCmd_dec, receivedCmd_len);
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RCV NXP DESELECT => ACK");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("[MFEMUL_WORK] RCV NXP DESELECT => ACK");
|
||||
} else {
|
||||
EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA);
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WORK] RCV NXP DESELECT => NACK");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("[MFEMUL_WORK] RCV NXP DESELECT => NACK");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// case MFEMUL_WORK => command not allowed
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Received command not allowed, nacking");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("Received command not allowed, nacking");
|
||||
EmSend4bit(encrypted_data ? mf_crypto1_encrypt4bit(pcs, CARD_NACK_NA) : CARD_NACK_NA);
|
||||
break;
|
||||
}
|
||||
|
||||
// AUTH1
|
||||
case MFEMUL_AUTH1: {
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_AUTH1] Enter case");
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("[MFEMUL_AUTH1] Enter case");
|
||||
|
||||
if (receivedCmd_len != 8) {
|
||||
cardSTATE_TO_IDLE();
|
||||
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) Dbprintf("MFEMUL_AUTH1: receivedCmd_len != 8 (%d) => cardSTATE_TO_IDLE())", receivedCmd_len);
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("MFEMUL_AUTH1: receivedCmd_len != 8 (%d) => cardSTATE_TO_IDLE())", receivedCmd_len);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1034,7 +1066,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
||||
, prng_successor(nonce, 64)
|
||||
);
|
||||
}
|
||||
cardAUTHKEY = AUTHKEYNONE; // not authenticated
|
||||
cardAUTHKEY = AUTHKEYNONE; // not authenticated
|
||||
cardSTATE_TO_IDLE();
|
||||
// Really tags not respond NACK on invalid authentication
|
||||
LogTrace(uart->output, uart->len, uart->startTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->endTime * 16 - DELAY_AIR2ARM_AS_TAG, uart->parity, true);
|
||||
@@ -1067,21 +1099,21 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
||||
if (IsSectorTrailer(cardWRBL)) {
|
||||
emlGetMem(response, cardWRBL, 1);
|
||||
if (!IsAccessAllowed(cardWRBL, cardAUTHKEY, AC_KEYA_WRITE)) {
|
||||
memcpy(receivedCmd_dec, response, 6); // don't change KeyA
|
||||
memcpy(receivedCmd_dec, response, 6); // don't change KeyA
|
||||
}
|
||||
if (!IsAccessAllowed(cardWRBL, cardAUTHKEY, AC_KEYB_WRITE)) {
|
||||
memcpy(receivedCmd_dec + 10, response + 10, 6); // don't change KeyA
|
||||
memcpy(receivedCmd_dec + 10, response + 10, 6); // don't change KeyA
|
||||
}
|
||||
if (!IsAccessAllowed(cardWRBL, cardAUTHKEY, AC_AC_WRITE)) {
|
||||
memcpy(receivedCmd_dec + 6, response + 6, 4); // don't change AC bits
|
||||
memcpy(receivedCmd_dec + 6, response + 6, 4); // don't change AC bits
|
||||
}
|
||||
} else {
|
||||
if (!IsAccessAllowed(cardWRBL, cardAUTHKEY, AC_DATA_WRITE)) {
|
||||
memcpy(receivedCmd_dec, response, 16); // don't change anything
|
||||
memcpy(receivedCmd_dec, response, 16); // don't change anything
|
||||
}
|
||||
}
|
||||
emlSetMem(receivedCmd_dec, cardWRBL, 1);
|
||||
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); // always ACK?
|
||||
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK)); // always ACK?
|
||||
cardSTATE = MFEMUL_WORK;
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("[MFEMUL_WRITEBL2] cardSTATE = MFEMUL_WORK");
|
||||
break;
|
||||
@@ -1152,7 +1184,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
||||
|
||||
// NR AR ATTACK
|
||||
if (((flags & FLAG_NR_AR_ATTACK) == FLAG_NR_AR_ATTACK) && (DBGLEVEL >= DBG_INFO)) {
|
||||
for (uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) {
|
||||
for (uint8_t i = 0; i < ATTACK_KEY_COUNT; i++) {
|
||||
if (ar_nr_collected[i] == 2) {
|
||||
Dbprintf("Collected two pairs of AR/NR which can be used to extract %s from reader for sector %d:", (i < ATTACK_KEY_COUNT / 2) ? "keyA" : "keyB", ar_nr_resp[i].sector);
|
||||
Dbprintf("../tools/mfkey/mfkey32 %08x %08x %08x %08x %08x %08x",
|
||||
@@ -1167,7 +1199,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t i = ATTACK_KEY_COUNT; i < ATTACK_KEY_COUNT * 2; i++) {
|
||||
for (uint8_t i = ATTACK_KEY_COUNT; i < ATTACK_KEY_COUNT * 2; i++) {
|
||||
if (ar_nr_collected[i] == 2) {
|
||||
Dbprintf("Collected two pairs of AR/NR which can be used to extract %s from reader for sector %d:", (i < ATTACK_KEY_COUNT / 2) ? "keyA" : "keyB", ar_nr_resp[i].sector);
|
||||
Dbprintf("../tools/mfkey/mfkey32v2 %08x %08x %08x %08x %08x %08x %08x",
|
||||
@@ -1182,7 +1214,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain) {
|
||||
}
|
||||
}
|
||||
|
||||
if (DBGLEVEL >= DBG_ERROR) {
|
||||
if (DBGLEVEL >= DBG_ERROR) {
|
||||
Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", get_tracing(), BigBuf_get_traceLen());
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef CheckCrc14A
|
||||
# define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len))
|
||||
# define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len))
|
||||
#endif
|
||||
|
||||
void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain);
|
||||
@@ -24,7 +24,7 @@ void Mifare1ksim(uint16_t flags, uint8_t exitAfterNReads, uint8_t *datain);
|
||||
#define AC_DATA_READ 0
|
||||
#define AC_DATA_WRITE 1
|
||||
#define AC_DATA_INC 2
|
||||
#define AC_DATA_DEC_TRANS_REST 3
|
||||
#define AC_DATA_DEC_TRANS_REST 3
|
||||
#define AC_KEYA_READ 0
|
||||
#define AC_KEYA_WRITE 1
|
||||
#define AC_KEYB_READ 2
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "mifaresniff.h"
|
||||
|
||||
#ifndef CheckCrc14A
|
||||
# define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len))
|
||||
# define CheckCrc14A(data, len) check_crc(CRC_14443_A, (data), (len))
|
||||
#endif
|
||||
|
||||
//static int sniffState = SNF_INIT;
|
||||
|
||||
@@ -602,10 +602,12 @@ void emlClearMem(void) {
|
||||
|
||||
uint8_t SectorTrailer(uint8_t blockNo) {
|
||||
if (blockNo <= MIFARE_2K_MAXBLOCK) {
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Sector Trailer for block %d : %d", blockNo, (blockNo | 0x03));
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("Sector Trailer for block %d : %d", blockNo, (blockNo | 0x03));
|
||||
return (blockNo | 0x03);
|
||||
} else {
|
||||
if (DBGLEVEL >= DBG_EXTENDED) Dbprintf("Sector Trailer for block %d : %d", blockNo, (blockNo | 0x0f));
|
||||
if (DBGLEVEL >= DBG_EXTENDED)
|
||||
Dbprintf("Sector Trailer for block %d : %d", blockNo, (blockNo | 0x0f));
|
||||
return (blockNo | 0x0f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,6 +56,7 @@ int rdv40_spiffs_copy(char *src, char *dst, RDV40SpiFFSSafetyLevel level);
|
||||
int rdv40_spiffs_append(char *filename, uint8_t *src, uint32_t size, RDV40SpiFFSSafetyLevel level);
|
||||
int rdv40_spiffs_stat(char *filename, uint32_t *buf, RDV40SpiFFSSafetyLevel level);
|
||||
uint32_t size_in_spiffs(const char *filename);
|
||||
int exists_in_spiffs(const char *filename);
|
||||
|
||||
#define SPIFFS_OK 0
|
||||
#define SPIFFS_ERR_NOT_MOUNTED -10000
|
||||
|
||||
Reference in New Issue
Block a user