make style

This commit is contained in:
Philippe Teuwen 2019-03-10 00:00:59 +01:00
parent 0d9223a547
commit 0373696662
483 changed files with 56514 additions and 52451 deletions

View file

@ -90,6 +90,11 @@ print-%: ; @echo $* = $($*)
style: style:
find . \( -name "*.[ch]" -or -name "*.cpp" -or -name "*.lua" \) -exec perl -pi -e 's/[ \t\r]+$$//' {} \; find . \( -name "*.[ch]" -or -name "*.cpp" -or -name "*.lua" \) -exec perl -pi -e 's/[ \t\r]+$$//' {} \;
find . \( -name "*.[ch]" -or -name "*.cpp" \) -exec astyle --formatted --mode=c --suffix=none \
--indent=spaces=4 --indent-switches --indent-preprocessor \
--keep-one-line-blocks --max-instatement-indent=60 \
--style=linux --pad-oper --unpad-paren --pad-header \
--align-pointer=name {} \;
# Dummy target to test for GNU make availability # Dummy target to test for GNU make availability
_test: _test:

View file

@ -34,12 +34,14 @@ static uint32_t traceLen = 0;
static bool tracing = true; //todo static? static bool tracing = true; //todo static?
// get the address of BigBuf // get the address of BigBuf
uint8_t *BigBuf_get_addr(void) { uint8_t *BigBuf_get_addr(void)
{
return (uint8_t *)BigBuf; return (uint8_t *)BigBuf;
} }
// get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done // get the address of the emulator memory. Allocate part of Bigbuf for it, if not yet done
uint8_t *BigBuf_get_EM_addr(void) { uint8_t *BigBuf_get_EM_addr(void)
{
// not yet allocated // not yet allocated
if (emulator_memory == NULL) if (emulator_memory == NULL)
emulator_memory = BigBuf_malloc(CARD_MEMORY_SIZE); emulator_memory = BigBuf_malloc(CARD_MEMORY_SIZE);
@ -48,28 +50,33 @@ uint8_t *BigBuf_get_EM_addr(void) {
} }
// clear ALL of BigBuf // clear ALL of BigBuf
void BigBuf_Clear(void) { void BigBuf_Clear(void)
{
BigBuf_Clear_ext(true); BigBuf_Clear_ext(true);
} }
// clear ALL of BigBuf // clear ALL of BigBuf
void BigBuf_Clear_ext(bool verbose) { void BigBuf_Clear_ext(bool verbose)
{
memset(BigBuf, 0, BIGBUF_SIZE); memset(BigBuf, 0, BIGBUF_SIZE);
if (verbose) if (verbose)
Dbprintf("Buffer cleared (%i bytes)", BIGBUF_SIZE); Dbprintf("Buffer cleared (%i bytes)", BIGBUF_SIZE);
} }
void BigBuf_Clear_EM(void) { void BigBuf_Clear_EM(void)
{
memset(BigBuf_get_EM_addr(), 0, CARD_MEMORY_SIZE); memset(BigBuf_get_EM_addr(), 0, CARD_MEMORY_SIZE);
} }
void BigBuf_Clear_keep_EM(void) { void BigBuf_Clear_keep_EM(void)
{
memset(BigBuf, 0, BigBuf_hi); memset(BigBuf, 0, BigBuf_hi);
} }
// allocate a chunk of memory from BigBuf. We allocate high memory first. The unallocated memory // allocate a chunk of memory from BigBuf. We allocate high memory first. The unallocated memory
// at the beginning of BigBuf is always for traces/samples // at the beginning of BigBuf is always for traces/samples
uint8_t *BigBuf_malloc(uint16_t chunksize) { uint8_t *BigBuf_malloc(uint16_t chunksize)
{
if (BigBuf_hi - chunksize < 0) if (BigBuf_hi - chunksize < 0)
return NULL; // no memory left return NULL; // no memory left
@ -79,14 +86,16 @@ uint8_t *BigBuf_malloc(uint16_t chunksize) {
} }
// free ALL allocated chunks. The whole BigBuf is available for traces or samples again. // free ALL allocated chunks. The whole BigBuf is available for traces or samples again.
void BigBuf_free(void){ void BigBuf_free(void)
{
BigBuf_hi = BIGBUF_SIZE; BigBuf_hi = BIGBUF_SIZE;
emulator_memory = NULL; emulator_memory = NULL;
// shouldn't this empty BigBuf also? // shouldn't this empty BigBuf also?
} }
// free allocated chunks EXCEPT the emulator memory // free allocated chunks EXCEPT the emulator memory
void BigBuf_free_keep_EM(void) { void BigBuf_free_keep_EM(void)
{
if (emulator_memory != NULL) if (emulator_memory != NULL)
BigBuf_hi = emulator_memory - (uint8_t *)BigBuf; BigBuf_hi = emulator_memory - (uint8_t *)BigBuf;
else else
@ -95,7 +104,8 @@ void BigBuf_free_keep_EM(void) {
// shouldn't this empty BigBuf also? // shouldn't this empty BigBuf also?
} }
void BigBuf_print_status(void) { void BigBuf_print_status(void)
{
Dbprintf("Memory"); Dbprintf("Memory");
Dbprintf(" BIGBUF_SIZE.............%d", BIGBUF_SIZE); Dbprintf(" BIGBUF_SIZE.............%d", BIGBUF_SIZE);
Dbprintf(" Available memory........%d", BigBuf_hi); Dbprintf(" Available memory........%d", BigBuf_hi);
@ -105,21 +115,26 @@ void BigBuf_print_status(void) {
} }
// return the maximum trace length (i.e. the unallocated size of BigBuf) // return the maximum trace length (i.e. the unallocated size of BigBuf)
uint16_t BigBuf_max_traceLen(void) { uint16_t BigBuf_max_traceLen(void)
{
return BigBuf_hi; return BigBuf_hi;
} }
void clear_trace(void) { void clear_trace(void)
{
traceLen = 0; traceLen = 0;
} }
void set_tracelen(uint32_t value) { void set_tracelen(uint32_t value)
{
traceLen = value; traceLen = value;
} }
void set_tracing(bool enable) { void set_tracing(bool enable)
{
tracing = enable; tracing = enable;
} }
bool get_tracing(void) { bool get_tracing(void)
{
return tracing; return tracing;
} }
@ -127,7 +142,8 @@ bool get_tracing(void) {
* Get the number of bytes traced * Get the number of bytes traced
* @return * @return
*/ */
uint32_t BigBuf_get_traceLen(void) { uint32_t BigBuf_get_traceLen(void)
{
return traceLen; return traceLen;
} }
@ -137,7 +153,8 @@ uint32_t BigBuf_get_traceLen(void) {
by 'hf list raw', alternatively 'hf list <proto>' for protocol-specific by 'hf list raw', alternatively 'hf list <proto>' for protocol-specific
annotation of commands/responses. annotation of commands/responses.
**/ **/
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag) { bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag)
{
if (!tracing) return false; if (!tracing) return false;
uint8_t *trace = BigBuf_get_addr(); uint8_t *trace = BigBuf_get_addr();
@ -195,7 +212,8 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
return true; return true;
} }
int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwParity, int readerToTag) { int LogTraceHitag(const uint8_t *btBytes, int iBits, int iSamples, uint32_t dwParity, int readerToTag)
{
/** /**
Todo, rewrite the logger to use the generic functionality instead. It should be noted, however, Todo, rewrite the logger to use the generic functionality instead. It should be noted, however,
that this logger takes number of bits as argument, not number of bytes. that this logger takes number of bits as argument, not number of bytes.
@ -237,7 +255,8 @@ int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwP
} }
// Emulator memory // Emulator memory
uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length){ uint8_t emlSet(uint8_t *data, uint32_t offset, uint32_t length)
{
uint8_t *mem = BigBuf_get_EM_addr(); uint8_t *mem = BigBuf_get_EM_addr();
if (offset + length < CARD_MEMORY_SIZE) { if (offset + length < CARD_MEMORY_SIZE) {
memcpy(mem + offset, data, length); memcpy(mem + offset, data, length);

View file

@ -38,8 +38,7 @@ void LCDFill (unsigned char xs,unsigned char ys,unsigned char width,unsigned cha
{ {
unsigned char i, j; unsigned char i, j;
for (i=0;i < height;i++) // Number of horizontal lines for (i = 0; i < height; i++) { // Number of horizontal lines
{
LCDSetXY(xs, ys + i); // Goto start of fill area (Top Left) LCDSetXY(xs, ys + i); // Goto start of fill area (Top Left)
LCDSend(PRAMWR); // Write to display LCDSend(PRAMWR); // Write to display
@ -62,8 +61,7 @@ void LCDString (char *lcd_string, const char *font_style,unsigned char x, unsign
data++; data++;
offset = *data; // get data bytes per font offset = *data; // get data bytes per font
do do {
{
// point to data in table to be loaded // point to data in table to be loaded
data = (font_style + offset) + (offset * (int)(*lcd_string - 32)); data = (font_style + offset) + (offset * (int)(*lcd_string - 32));

View file

@ -27,13 +27,13 @@ from the client to view the stored quadlets.
// Maximum number of auth attempts per standalone session // Maximum number of auth attempts per standalone session
#define MAX_PWDS_PER_SESSION 64 #define MAX_PWDS_PER_SESSION 64
uint8_t FindOffsetInFlash() { uint8_t FindOffsetInFlash()
{
uint8_t mem[4] = { 0x00, 0x00, 0x00, 0x00 }; uint8_t mem[4] = { 0x00, 0x00, 0x00, 0x00 };
uint8_t eom[4] = { 0xFF, 0xFF, 0xFF, 0xFF }; uint8_t eom[4] = { 0xFF, 0xFF, 0xFF, 0xFF };
uint8_t memcnt = 0; uint8_t memcnt = 0;
while (memcnt < 0xFF) while (memcnt < 0xFF) {
{
Flash_ReadData(memcnt, mem, 4); Flash_ReadData(memcnt, mem, 4);
if (memcmp(mem, eom, 4) == 0) { if (memcmp(mem, eom, 4) == 0) {
return memcnt; return memcnt;
@ -44,7 +44,8 @@ uint8_t FindOffsetInFlash() {
return 0; // wrap-around return 0; // wrap-around
} }
void EraseMemory() { void EraseMemory()
{
if (!FlashInit()) { if (!FlashInit()) {
return; return;
} }
@ -59,13 +60,15 @@ void EraseMemory() {
} }
// This is actually copied from SniffIso14443a // This is actually copied from SniffIso14443a
void RAMFUNC SniffAndStore(uint8_t param) { void RAMFUNC SniffAndStore(uint8_t param)
{
iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER); iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER);
// Allocate memory from BigBuf for some buffers // Allocate memory from BigBuf for some buffers
// free all previous allocations first // free all previous allocations first
BigBuf_free(); BigBuf_Clear_ext(false); BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace(); clear_trace();
set_tracing(true); set_tracing(true);
@ -239,8 +242,7 @@ void RAMFUNC SniffAndStore(uint8_t param) {
uint8_t memoffset = FindOffsetInFlash(); uint8_t memoffset = FindOffsetInFlash();
if (MF_DBGLEVEL > 1) Dbprintf("[!] Memory offset = %u", memoffset); if (MF_DBGLEVEL > 1) Dbprintf("[!] Memory offset = %u", memoffset);
if ((memoffset + 4 * auth_attempts) > 0xFF) if ((memoffset + 4 * auth_attempts) > 0xFF) {
{
// We opt to keep the new data only // We opt to keep the new data only
memoffset = 0; memoffset = 0;
if (MF_DBGLEVEL > 1) Dbprintf("[!] Size of total data > 256 bytes. Discarding the old data."); if (MF_DBGLEVEL > 1) Dbprintf("[!] Size of total data > 256 bytes. Discarding the old data.");
@ -248,8 +250,7 @@ void RAMFUNC SniffAndStore(uint8_t param) {
// Get previous data from flash mem // Get previous data from flash mem
uint8_t *previousdata = BigBuf_malloc(memoffset); uint8_t *previousdata = BigBuf_malloc(memoffset);
if (memoffset > 0) if (memoffset > 0) {
{
uint16_t readlen = Flash_ReadData(0, previousdata, memoffset); uint16_t readlen = Flash_ReadData(0, previousdata, memoffset);
if (MF_DBGLEVEL > 1) Dbprintf("[!] Read %u bytes from flash mem", readlen); if (MF_DBGLEVEL > 1) Dbprintf("[!] Read %u bytes from flash mem", readlen);
} }
@ -283,7 +284,8 @@ void RAMFUNC SniffAndStore(uint8_t param) {
} }
} }
void RunMod() { void RunMod()
{
StandAloneMode(); StandAloneMode();

View file

@ -112,16 +112,12 @@ void ReadLastTagFromFlash()
uint32_t end_time; uint32_t end_time;
uint32_t start_time = end_time = GetTickCount(); uint32_t start_time = end_time = GetTickCount();
for (size_t i = 0; i < len; i += size) for (size_t i = 0; i < len; i += size) {
{
len = MIN((len - i), size); len = MIN((len - i), size);
isok = Flash_ReadDataCont(startidx + i, mem, len); isok = Flash_ReadDataCont(startidx + i, mem, len);
if (isok == len) if (isok == len) {
{
emlSetMem(mem, 0, 64); emlSetMem(mem, 0, 64);
} } else {
else
{
DbprintfEx(FLAG_NOLOG, "FlashMem reading failed | %d | %d", len, isok); DbprintfEx(FLAG_NOLOG, "FlashMem reading failed | %d | %d", len, isok);
cjSetCursLeft(); cjSetCursLeft();
FlashStop(); FlashStop();
@ -169,8 +165,7 @@ void WriteTagToFlash(uint8_t index, size_t size)
uint32_t end_time; uint32_t end_time;
uint32_t start_time = end_time = GetTickCount(); uint32_t start_time = end_time = GetTickCount();
while (bytes_remaining > 0) while (bytes_remaining > 0) {
{
Flash_CheckBusy(BUSY_TIMEOUT); Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable(); Flash_WriteEnable();
@ -184,8 +179,7 @@ void WriteTagToFlash(uint8_t index, size_t size)
isok = (res == bytes_in_packet) ? 1 : 0; isok = (res == bytes_in_packet) ? 1 : 0;
if (!isok) if (!isok) {
{
DbprintfEx(FLAG_NOLOG, "FlashMem write FAILEd [offset %u]", bytes_sent); DbprintfEx(FLAG_NOLOG, "FlashMem write FAILEd [offset %u]", bytes_sent);
cjSetCursLeft(); cjSetCursLeft();
SpinOff(100); SpinOff(100);
@ -310,8 +304,7 @@ ACCBITS : 796788[00]+VALUE
keyBlock = BigBuf_malloc(STKEYS * 6); keyBlock = BigBuf_malloc(STKEYS * 6);
int mfKeysCnt = sizeof(mfKeys) / sizeof(uint64_t); int mfKeysCnt = sizeof(mfKeys) / sizeof(uint64_t);
for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) for (int mfKeyCounter = 0; mfKeyCounter < mfKeysCnt; mfKeyCounter++) {
{
num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t *)(keyBlock + mfKeyCounter * 6)); num_to_bytes(mfKeys[mfKeyCounter], 6, (uint8_t *)(keyBlock + mfKeyCounter * 6));
} }
@ -319,10 +312,8 @@ ACCBITS : 796788[00]+VALUE
// and why not a simple memset abuse to 0xffize the whole space in one go ? // and why not a simple memset abuse to 0xffize the whole space in one go ?
// uint8_t foundKey[2][40][6]; //= [ {0xff} ]; /* C99 abusal 6.7.8.21 // uint8_t foundKey[2][40][6]; //= [ {0xff} ]; /* C99 abusal 6.7.8.21
uint8_t foundKey[2][40][6]; uint8_t foundKey[2][40][6];
for (uint16_t t = 0; t < 2; t++) for (uint16_t t = 0; t < 2; t++) {
{ for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++)
{
foundKey[t][sectorNo][0] = 0xFF; foundKey[t][sectorNo][0] = 0xFF;
foundKey[t][sectorNo][1] = 0xFF; foundKey[t][sectorNo][1] = 0xFF;
foundKey[t][sectorNo][2] = 0xFF; foundKey[t][sectorNo][2] = 0xFF;
@ -363,18 +354,15 @@ failtag:
LED_A_ON(); LED_A_ON();
uint8_t ticker = 0; 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, NULL, &cjcuid, true, 0, true)) while (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) {
{
WDT_HIT(); WDT_HIT();
ticker++; ticker++;
if (ticker % 64 == 0) if (ticker % 64 == 0) {
{
LED_A_INV(); LED_A_INV();
} }
if (BUTTON_HELD(10) > 0) if (BUTTON_HELD(10) > 0) {
{
WDT_HIT(); WDT_HIT();
DbprintfEx(FLAG_NOLOG, "\t\t\t[ READING FLASH ]"); DbprintfEx(FLAG_NOLOG, "\t\t\t[ READING FLASH ]");
ReadLastTagFromFlash(); ReadLastTagFromFlash();
@ -393,8 +381,7 @@ failtag:
DbprintfEx(FLAG_NOLOG, "\t%sGOT TAG :%s %08x%s", _RED_, _CYAN_, cjcuid, _WHITE_); DbprintfEx(FLAG_NOLOG, "\t%sGOT TAG :%s %08x%s", _RED_, _CYAN_, cjcuid, _WHITE_);
if (cjcuid == 0) if (cjcuid == 0) {
{
cjSetCursLeft(); cjSetCursLeft();
DbprintfEx(FLAG_NOLOG, "%s>>%s BUG: 0000_CJCUID! Retrying...", _RED_, _WHITE_); DbprintfEx(FLAG_NOLOG, "%s>>%s BUG: 0000_CJCUID! Retrying...", _RED_, _WHITE_);
SpinErr(0, 100, 8); SpinErr(0, 100, 8);
@ -441,29 +428,22 @@ failtag:
// also we could avoid first UID check for every block // also we could avoid first UID check for every block
// then lets expose this “optimal case” of “well known vigik schemes” : // then lets expose this “optimal case” of “well known vigik schemes” :
for (uint8_t type = 0; type < 2 && !err && !trapped; type++) for (uint8_t type = 0; type < 2 && !err && !trapped; type++) {
{ for (int sec = 0; sec < sectorsCnt && !err && !trapped; ++sec) {
for (int sec = 0; sec < sectorsCnt && !err && !trapped; ++sec)
{
key = cjat91_saMifareChkKeys(sec * 4, type, NULL, size, &keyBlock[0], &key64); key = cjat91_saMifareChkKeys(sec * 4, type, NULL, size, &keyBlock[0], &key64);
if (key == -1) if (key == -1) {
{
err = 1; err = 1;
allKeysFound = false; allKeysFound = false;
// used in “portable” imlementation on microcontroller: it reports back the fail and open the standalone lock // used in “portable” imlementation on microcontroller: it reports back the fail and open the standalone lock
// cmd_send(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0); // cmd_send(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0);
break; break;
} } else if (key == -2) {
else if (key == -2)
{
err = 1; // Can't select card. err = 1; // Can't select card.
allKeysFound = false; allKeysFound = false;
// cmd_send(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0); // cmd_send(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0);
break; break;
} } else {
else
{
/* BRACE YOURSELF : AS LONG AS WE TRAP A KNOWN KEY, WE STOP CHECKING AND ENFORCE KNOWN SCHEMES */ /* BRACE YOURSELF : AS LONG AS WE TRAP A KNOWN KEY, WE STOP CHECKING AND ENFORCE KNOWN SCHEMES */
// uint8_t tosendkey[13]; // uint8_t tosendkey[13];
char tosendkey[13]; char tosendkey[13];
@ -471,8 +451,7 @@ failtag:
cjSetCursRight(); cjSetCursRight();
DbprintfEx(FLAG_NOLOG, "SEC: %02x ; KEY : %012" PRIx64 " ; TYP: %i", sec, key64, type); DbprintfEx(FLAG_NOLOG, "SEC: %02x ; KEY : %012" PRIx64 " ; TYP: %i", sec, key64, type);
/*cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sec, type, tosendkey, 12);*/ /*cmd_send(CMD_CJB_INFORM_CLIENT_KEY, 12, sec, type, tosendkey, 12);*/
switch (key64) switch (key64) {
{
///////////////////////////////////////////////////////// /////////////////////////////////////////////////////////
// COMMON SCHEME 1 : INFINITRON/HEXACT // COMMON SCHEME 1 : INFINITRON/HEXACT
case 0x484558414354: case 0x484558414354:
@ -493,8 +472,7 @@ failtag:
; ;
// Type 0 / A first // Type 0 / A first
uint16_t t = 0; uint16_t t = 0;
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
{
num_to_bytes(0x484558414354, 6, foundKey[t][sectorNo]); 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], 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]); foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
@ -640,10 +618,8 @@ failtag:
// emlClearMem(); // emlClearMem();
// A very weak one... // A very weak one...
for (uint16_t t = 0; t < 2; t++) for (uint16_t t = 0; t < 2; t++) {
{ for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++)
{
num_to_bytes(key64, 6, foundKey[t][sectorNo]); num_to_bytes(key64, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], 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]); foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
@ -677,8 +653,7 @@ failtag:
DbprintfEx(FLAG_NOLOG, "%s>>>>>>>>>>>>!*DONE*!<<<<<<<<<<<<<<%s", _GREEN_, _WHITE_); DbprintfEx(FLAG_NOLOG, "%s>>>>>>>>>>>>!*DONE*!<<<<<<<<<<<<<<%s", _GREEN_, _WHITE_);
; ;
t = 0; t = 0;
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
{
num_to_bytes(0x414c41524f4e, 6, foundKey[t][sectorNo]); num_to_bytes(0x414c41524f4e, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], 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]); foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
@ -688,8 +663,7 @@ failtag:
; ;
} }
t = 1; t = 1;
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
{
num_to_bytes(0x424c41524f4e, 6, foundKey[t][sectorNo]); num_to_bytes(0x424c41524f4e, 6, foundKey[t][sectorNo]);
sprintf(tosendkey, "%02x%02x%02x%02x%02x%02x", foundKey[t][sectorNo][0], foundKey[t][sectorNo][1], foundKey[t][sectorNo][2], 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]); foundKey[t][sectorNo][3], foundKey[t][sectorNo][4], foundKey[t][sectorNo][5]);
@ -706,8 +680,7 @@ failtag:
} }
} }
if (!allKeysFound) if (!allKeysFound) {
{
cjSetCursLeft(); cjSetCursLeft();
cjTabulize(); cjTabulize();
DbprintfEx(FLAG_NOLOG, "%s[ FAIL ]%s\r\n->did not found all the keys :'(", _RED_, _WHITE_); DbprintfEx(FLAG_NOLOG, "%s[ FAIL ]%s\r\n->did not found all the keys :'(", _RED_, _WHITE_);
@ -720,11 +693,9 @@ failtag:
/* Settings keys to emulator */ /* Settings keys to emulator */
emlClearMem(); emlClearMem();
uint8_t mblock[16]; uint8_t mblock[16];
for (uint8_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) for (uint8_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
{
emlGetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1); emlGetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);
for (uint8_t t = 0; t < 2; t++) for (uint8_t t = 0; t < 2; t++) {
{
memcpy(mblock + t * 10, foundKey[t][sectorNo], 6); memcpy(mblock + t * 10, foundKey[t][sectorNo], 6);
} }
emlSetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1); emlSetMem(mblock, FirstBlockOfSector(sectorNo) + NumBlocksPerSector(sectorNo) - 1, 1);
@ -739,16 +710,14 @@ failtag:
DbprintfEx(FLAG_NOLOG, "%s>>%s Filling Emulator <- from A keys...", _YELLOW_, _WHITE_); DbprintfEx(FLAG_NOLOG, "%s>>%s Filling Emulator <- from A keys...", _YELLOW_, _WHITE_);
e_MifareECardLoad(sectorsCnt, 0, 0, &filled); e_MifareECardLoad(sectorsCnt, 0, 0, &filled);
if (filled != 1) if (filled != 1) {
{
cjSetCursLeft(); cjSetCursLeft();
DbprintfEx(FLAG_NOLOG, "%s>>%s W_FAILURE ! %sTrying fallback B keys....", _RED_, _ORANGE_, _WHITE_); DbprintfEx(FLAG_NOLOG, "%s>>%s W_FAILURE ! %sTrying fallback B keys....", _RED_, _ORANGE_, _WHITE_);
/* no trace, no dbg */ /* no trace, no dbg */
e_MifareECardLoad(sectorsCnt, 1, 0, &filled); e_MifareECardLoad(sectorsCnt, 1, 0, &filled);
if (filled != 1) if (filled != 1) {
{
cjSetCursLeft(); cjSetCursLeft();
DbprintfEx(FLAG_NOLOG, "FATAL:EML_FALLBACKFILL_B"); DbprintfEx(FLAG_NOLOG, "FATAL:EML_FALLBACKFILL_B");
@ -856,30 +825,23 @@ void e_MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *dat
bool isOK = true; bool isOK = true;
if (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) if (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) {
{
isOK = false; isOK = false;
if (MF_DBGLEVEL >= 1) if (MF_DBGLEVEL >= 1)
DbprintfEx(FLAG_RAWPRINT, "Can't select card"); DbprintfEx(FLAG_RAWPRINT, "Can't select card");
} }
for (uint8_t sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) for (uint8_t sectorNo = 0; isOK && sectorNo < numSectors; sectorNo++) {
{
ui64Key = emlGetKey(sectorNo, keyType); ui64Key = emlGetKey(sectorNo, keyType);
if (sectorNo == 0) if (sectorNo == 0) {
{ if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) {
if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST))
{
isOK = false; isOK = false;
if (MF_DBGLEVEL >= 1) if (MF_DBGLEVEL >= 1)
DbprintfEx(FLAG_NOLOG, "Sector[%2d]. Auth error", sectorNo); DbprintfEx(FLAG_NOLOG, "Sector[%2d]. Auth error", sectorNo);
break; break;
} }
} } else {
else if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_NESTED)) {
{
if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_NESTED))
{
isOK = false; isOK = false;
if (MF_DBGLEVEL >= 1) if (MF_DBGLEVEL >= 1)
DbprintfEx(FLAG_NOLOG, "Sector[%2d]. Auth nested error", sectorNo); DbprintfEx(FLAG_NOLOG, "Sector[%2d]. Auth nested error", sectorNo);
@ -887,38 +849,30 @@ void e_MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *dat
} }
} }
for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) {
{ if (isOK && mifare_classic_readblock(pcs, cjcuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) {
if (isOK && mifare_classic_readblock(pcs, cjcuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf))
{
isOK = false; isOK = false;
if (MF_DBGLEVEL >= 1) if (MF_DBGLEVEL >= 1)
DbprintfEx(FLAG_NOLOG, "Error reading sector %2d block %2d", sectorNo, blockNo); DbprintfEx(FLAG_NOLOG, "Error reading sector %2d block %2d", sectorNo, blockNo);
break; break;
}; };
if (isOK) if (isOK) {
{
*datain = 1; *datain = 1;
if (blockNo < NumBlocksPerSector(sectorNo) - 1) if (blockNo < NumBlocksPerSector(sectorNo) - 1) {
{
emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1); emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1);
} } else {
else // sector trailer, keep the keys, set only the AC
{ // sector trailer, keep the keys, set only the AC
emlGetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1); emlGetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);
memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4); memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);
emlSetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1); emlSetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);
} }
} } else {
else
{
*datain = 0; *datain = 0;
} }
} }
} }
if (mifare_classic_halt(pcs, cjcuid)) if (mifare_classic_halt(pcs, cjcuid)) {
{
if (MF_DBGLEVEL >= 1) if (MF_DBGLEVEL >= 1)
DbprintfEx(FLAG_NOLOG, "Halt error"); DbprintfEx(FLAG_NOLOG, "Halt error");
}; };
@ -944,21 +898,18 @@ int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
struct Crypto1State *pcs; struct Crypto1State *pcs;
pcs = &mpcs; pcs = &mpcs;
for (int i = 0; i < keyCount; ++i) for (int i = 0; i < keyCount; ++i) {
{
/* no need for anticollision. just verify tag is still here */ /* no need for anticollision. just verify tag is still here */
// if (!iso14443a_fast_select_card(cjuid, 0)) { // if (!iso14443a_fast_select_card(cjuid, 0)) {
if (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) if (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) {
{
cjSetCursLeft(); cjSetCursLeft();
DbprintfEx(FLAG_NOLOG, "%sFATAL%s : E_MF_LOSTTAG", _RED_, _WHITE_); DbprintfEx(FLAG_NOLOG, "%sFATAL%s : E_MF_LOSTTAG", _RED_, _WHITE_);
return -1; return -1;
} }
uint64_t ui64Key = bytes_to_num(datain + i * 6, 6); uint64_t ui64Key = bytes_to_num(datain + i * 6, 6);
if (mifare_classic_auth(pcs, cjcuid, blockNo, keyType, ui64Key, AUTH_FIRST)) if (mifare_classic_auth(pcs, cjcuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {
{
uint8_t dummy_answer = 0; uint8_t dummy_answer = 0;
ReaderTransmit(&dummy_answer, 1, NULL); ReaderTransmit(&dummy_answer, 1, NULL);
// wait for the card to become ready again // wait for the card to become ready again
@ -990,8 +941,7 @@ void saMifareMakeTag(void)
DbprintfEx(FLAG_NOLOG, ">> Write to Special:"); DbprintfEx(FLAG_NOLOG, ">> Write to Special:");
int flags = 0; int flags = 0;
for (int blockNum = 0; blockNum < 16 * 4; blockNum++) for (int blockNum = 0; blockNum < 16 * 4; blockNum++) {
{
uint8_t mblock[16]; uint8_t mblock[16];
// cnt = 0; // cnt = 0;
emlGetMem(mblock, blockNum, 1); emlGetMem(mblock, blockNum, 1);
@ -1007,12 +957,11 @@ void saMifareMakeTag(void)
if (blockNum == 16 * 4 - 1) if (blockNum == 16 * 4 - 1)
flags = 0x04 + 0x10; flags = 0x04 + 0x10;
if (saMifareCSetBlock(0, flags & 0xFE, blockNum, mblock)) if (saMifareCSetBlock(0, flags & 0xFE, blockNum, mblock)) {
{ //&& cnt <= retry) { //&& cnt <= retry) {
// cnt++; // cnt++;
cjSetCursFRight(); cjSetCursFRight();
if (currfline > 53) if (currfline > 53) {
{
currfline = 54; currfline = 54;
} }
DbprintfEx(FLAG_NOLOG, "Block :%02x %sOK%s", blockNum, _GREEN_, _WHITE_); DbprintfEx(FLAG_NOLOG, "Block :%02x %sOK%s", blockNum, _GREEN_, _WHITE_);
@ -1020,9 +969,7 @@ void saMifareMakeTag(void)
// cfail=1; // cfail=1;
// return; // return;
continue; continue;
} } else {
else
{
cjSetCursLeft(); cjSetCursLeft();
cjSetCursLeft(); cjSetCursLeft();
@ -1041,8 +988,7 @@ void saMifareMakeTag(void)
break; break;
} */ } */
} }
if (cfail == 0) if (cfail == 0) {
{
SpinUp(50); SpinUp(50);
SpinUp(50); SpinUp(50);
SpinUp(50); SpinUp(50);
@ -1078,52 +1024,43 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
// reset FPGA and LED // reset FPGA and LED
if (workFlags & 0x08) if (workFlags & 0x08) {
{
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
// clear_trace(); // clear_trace();
set_tracing(FALSE); set_tracing(FALSE);
} }
while (true) while (true) {
{
cjSetCursLeft(); cjSetCursLeft();
// get UID from chip // get UID from chip
if (workFlags & 0x01) if (workFlags & 0x01) {
{ if (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) {
if (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true))
{
DbprintfEx(FLAG_NOLOG, "Can't select card"); DbprintfEx(FLAG_NOLOG, "Can't select card");
break; break;
}; };
if (mifare_classic_halt(NULL, cjcuid)) if (mifare_classic_halt(NULL, cjcuid)) {
{
DbprintfEx(FLAG_NOLOG, "Halt error"); DbprintfEx(FLAG_NOLOG, "Halt error");
break; break;
}; };
}; };
// reset chip // reset chip
if (needWipe) if (needWipe) {
{
ReaderTransmitBitsPar(wupC1, 7, 0, NULL); ReaderTransmitBitsPar(wupC1, 7, 0, NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
{
DbprintfEx(FLAG_NOLOG, "wupC1 error"); DbprintfEx(FLAG_NOLOG, "wupC1 error");
break; break;
}; };
ReaderTransmit(wipeC, sizeof(wipeC), NULL); ReaderTransmit(wipeC, sizeof(wipeC), NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
{
DbprintfEx(FLAG_NOLOG, "wipeC error"); DbprintfEx(FLAG_NOLOG, "wipeC error");
break; break;
}; };
if (mifare_classic_halt(NULL, cjcuid)) if (mifare_classic_halt(NULL, cjcuid)) {
{
DbprintfEx(FLAG_NOLOG, "Halt error"); DbprintfEx(FLAG_NOLOG, "Halt error");
break; break;
}; };
@ -1131,25 +1068,21 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
// chaud // chaud
// write block // write block
if (workFlags & 0x02) if (workFlags & 0x02) {
{
ReaderTransmitBitsPar(wupC1, 7, 0, NULL); ReaderTransmitBitsPar(wupC1, 7, 0, NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
{
DbprintfEx(FLAG_NOLOG, "wupC1 error"); DbprintfEx(FLAG_NOLOG, "wupC1 error");
break; break;
}; };
ReaderTransmit(wupC2, sizeof(wupC2), NULL); ReaderTransmit(wupC2, sizeof(wupC2), NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
{
DbprintfEx(FLAG_NOLOG, "wupC2 errorv"); DbprintfEx(FLAG_NOLOG, "wupC2 errorv");
break; break;
}; };
} }
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_NOLOG, "write block send command error"); DbprintfEx(FLAG_NOLOG, "write block send command error");
break; break;
}; };
@ -1157,16 +1090,13 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
memcpy(d_block, datain, 16); memcpy(d_block, datain, 16);
AddCrc14A(d_block, 16); AddCrc14A(d_block, 16);
ReaderTransmit(d_block, sizeof(d_block), NULL); ReaderTransmit(d_block, sizeof(d_block), NULL);
if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {
{
DbprintfEx(FLAG_NOLOG, "write block send data error"); DbprintfEx(FLAG_NOLOG, "write block send data error");
break; break;
}; };
if (workFlags & 0x04) if (workFlags & 0x04) {
{ if (mifare_classic_halt(NULL, cjcuid)) {
if (mifare_classic_halt(NULL, cjcuid))
{
cjSetCursFRight(); cjSetCursFRight();
DbprintfEx(FLAG_NOLOG, "Halt error"); DbprintfEx(FLAG_NOLOG, "Halt error");
@ -1178,8 +1108,7 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
break; break;
} }
if ((workFlags & 0x10) || (!isOK)) if ((workFlags & 0x10) || (!isOK)) {
{
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
} }

View file

@ -67,49 +67,40 @@ static int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_
uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE]; uint8_t receivedAnswerPar[MAX_MIFARE_PARITY_SIZE];
// reset FPGA and LED // reset FPGA and LED
if (workFlags & 0x08) if (workFlags & 0x08) {
{
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
set_tracing(false); set_tracing(false);
} }
while (true) while (true) {
{
// get UID from chip // get UID from chip
if (workFlags & 0x01) if (workFlags & 0x01) {
{ if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true))
{
DbprintfEx(FLAG_NOLOG, "Can't select card"); DbprintfEx(FLAG_NOLOG, "Can't select card");
break; break;
}; };
if (mifare_classic_halt(NULL, cuid)) if (mifare_classic_halt(NULL, cuid)) {
{
DbprintfEx(FLAG_NOLOG, "Halt error"); DbprintfEx(FLAG_NOLOG, "Halt error");
break; break;
}; };
}; };
// reset chip // reset chip
if (needWipe) if (needWipe) {
{
ReaderTransmitBitsPar(wupC1, 7, 0, NULL); ReaderTransmitBitsPar(wupC1, 7, 0, NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
{
DbprintfEx(FLAG_NOLOG, "wupC1 error"); DbprintfEx(FLAG_NOLOG, "wupC1 error");
break; break;
}; };
ReaderTransmit(wipeC, sizeof(wipeC), NULL); ReaderTransmit(wipeC, sizeof(wipeC), NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
{
DbprintfEx(FLAG_NOLOG, "wipeC error"); DbprintfEx(FLAG_NOLOG, "wipeC error");
break; break;
}; };
if (mifare_classic_halt(NULL, cuid)) if (mifare_classic_halt(NULL, cuid)) {
{
DbprintfEx(FLAG_NOLOG, "Halt error"); DbprintfEx(FLAG_NOLOG, "Halt error");
break; break;
}; };
@ -117,25 +108,21 @@ static int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_
// chaud // chaud
// write block // write block
if (workFlags & 0x02) if (workFlags & 0x02) {
{
ReaderTransmitBitsPar(wupC1, 7, 0, NULL); ReaderTransmitBitsPar(wupC1, 7, 0, NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
{
DbprintfEx(FLAG_NOLOG, "wupC1 error"); DbprintfEx(FLAG_NOLOG, "wupC1 error");
break; break;
}; };
ReaderTransmit(wupC2, sizeof(wupC2), NULL); ReaderTransmit(wupC2, sizeof(wupC2), NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
{
DbprintfEx(FLAG_NOLOG, "wupC2 errorv"); DbprintfEx(FLAG_NOLOG, "wupC2 errorv");
break; break;
}; };
} }
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_NOLOG, "write block send command error"); DbprintfEx(FLAG_NOLOG, "write block send command error");
break; break;
}; };
@ -143,16 +130,13 @@ static int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_
memcpy(d_block, datain, 16); memcpy(d_block, datain, 16);
AddCrc14A(d_block, 16); AddCrc14A(d_block, 16);
ReaderTransmit(d_block, sizeof(d_block), NULL); ReaderTransmit(d_block, sizeof(d_block), NULL);
if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) if ((ReaderReceive(receivedAnswer, receivedAnswerPar) != 1) || (receivedAnswer[0] != 0x0a)) {
{
DbprintfEx(FLAG_NOLOG, "write block send data error"); DbprintfEx(FLAG_NOLOG, "write block send data error");
break; break;
}; };
if (workFlags & 0x04) if (workFlags & 0x04) {
{ if (mifare_classic_halt(NULL, cuid)) {
if (mifare_classic_halt(NULL, cuid))
{
DbprintfEx(FLAG_NOLOG, "Halt error"); DbprintfEx(FLAG_NOLOG, "Halt error");
break; break;
}; };
@ -162,8 +146,7 @@ static int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_
break; break;
} }
if ((workFlags & 0x10) || (!isOK)) if ((workFlags & 0x10) || (!isOK)) {
{
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
} }
@ -182,20 +165,17 @@ static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
struct Crypto1State *pcs; struct Crypto1State *pcs;
pcs = &mpcs; pcs = &mpcs;
for (int i = 0; i < keyCount; ++i) for (int i = 0; i < keyCount; ++i) {
{
/* no need for anticollision. just verify tag is still here */ /* no need for anticollision. just verify tag is still here */
// if (!iso14443a_fast_select_card(cjuid, 0)) { // if (!iso14443a_fast_select_card(cjuid, 0)) {
if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
{
DbprintfEx(FLAG_NOLOG, "FATAL : E_MF_LOSTTAG"); DbprintfEx(FLAG_NOLOG, "FATAL : E_MF_LOSTTAG");
return -1; return -1;
} }
uint64_t ui64Key = bytes_to_num(datain + i * 6, 6); uint64_t ui64Key = bytes_to_num(datain + i * 6, 6);
if (mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) if (mifare_classic_auth(pcs, cuid, blockNo, keyType, ui64Key, AUTH_FIRST)) {
{
uint8_t dummy_answer = 0; uint8_t dummy_answer = 0;
ReaderTransmit(&dummy_answer, 1, NULL); ReaderTransmit(&dummy_answer, 1, NULL);
// wait for the card to become ready again // wait for the card to become ready again
@ -214,7 +194,8 @@ static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
} }
void RunMod() { void RunMod()
{
StandAloneMode(); StandAloneMode();
Dbprintf(">> Matty mifare chk/dump/sim a.k.a MattyRun Started <<"); Dbprintf(">> Matty mifare chk/dump/sim a.k.a MattyRun Started <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);

View file

@ -18,7 +18,8 @@ typedef struct {
} __attribute__((__packed__)) card_clone_t; } __attribute__((__packed__)) card_clone_t;
void RunMod() { void RunMod()
{
StandAloneMode(); StandAloneMode();
Dbprintf(">> Craig Young Mifare sniff UID/clone uid 2 magic/sim a.k.a YoungRun Started <<"); Dbprintf(">> Craig Young Mifare sniff UID/clone uid 2 magic/sim a.k.a YoungRun Started <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);

View file

@ -27,7 +27,8 @@
#include "lf_hidbrute.h" #include "lf_hidbrute.h"
// samy's sniff and repeat routine for LF // samy's sniff and repeat routine for LF
void RunMod() { void RunMod()
{
StandAloneMode(); StandAloneMode();
Dbprintf(">> LF HID corporate bruteforce a.k.a CorporateBrute Started <<"); Dbprintf(">> LF HID corporate bruteforce a.k.a CorporateBrute Started <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
@ -76,8 +77,7 @@ void RunMod() {
// so next button push begins playing what we recorded // so next button push begins playing what we recorded
playing = 0; playing = 0;
cardRead = 1; cardRead = 1;
} } else if (button_pressed > 0 && cardRead == 1) {
else if (button_pressed > 0 && cardRead == 1) {
LEDsoff(); LEDsoff();
LED(selected + 1, 0); LED(selected + 1, 0);
LED(LED_ORANGE, 0); LED(LED_ORANGE, 0);
@ -141,9 +141,7 @@ void RunMod() {
playing = !playing; playing = !playing;
LEDsoff(); LEDsoff();
LED(selected + 1, 0); LED(selected + 1, 0);
} } else if (playing && selected == 2) {
else if (playing && selected == 2)
{
// Now it work only with HID Corporate 1000 (35bit), but is easily extensible to others RFID. // Now it work only with HID Corporate 1000 (35bit), but is easily extensible to others RFID.
// It is necessary only to calculate the correct parity. // It is necessary only to calculate the correct parity.
@ -247,7 +245,8 @@ out:
} }
// Function that calculate next value for the brutforce of HID corporate 1000 // Function that calculate next value for the brutforce of HID corporate 1000
void hid_corporate_1000_calculate_checksum_and_set( uint32_t *high, uint32_t *low, uint32_t cardnum, uint32_t fc) { void hid_corporate_1000_calculate_checksum_and_set(uint32_t *high, uint32_t *low, uint32_t cardnum, uint32_t fc)
{
uint32_t new_high = 0; uint32_t new_high = 0;
uint32_t new_low = 0; uint32_t new_low = 0;

View file

@ -12,7 +12,8 @@
#include "lf_proxbrute.h" #include "lf_proxbrute.h"
// samy's sniff and repeat routine for LF // samy's sniff and repeat routine for LF
void RunMod() { void RunMod()
{
StandAloneMode(); StandAloneMode();
Dbprintf(">> LF HID proxII bruteforce a.k.a ProxBrute Started (Brad Antoniewicz) <<"); Dbprintf(">> LF HID proxII bruteforce a.k.a ProxBrute Started (Brad Antoniewicz) <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
@ -61,8 +62,7 @@ void RunMod() {
// so next button push begins playing what we recorded // so next button push begins playing what we recorded
playing = 0; playing = 0;
cardRead = 1; cardRead = 1;
} } else if (button_pressed > 0 && cardRead == 1) {
else if (button_pressed > 0 && cardRead == 1) {
LEDsoff(); LEDsoff();
LED(selected + 1, 0); LED(selected + 1, 0);
LED(LED_ORANGE, 0); LED(LED_ORANGE, 0);
@ -156,8 +156,7 @@ void RunMod() {
playing = !playing; playing = !playing;
LEDsoff(); LEDsoff();
LED(selected + 1, 0); LED(selected + 1, 0);
} } else {
else {
while (BUTTON_PRESS()) while (BUTTON_PRESS())
WDT_HIT(); WDT_HIT();
} }

View file

@ -11,7 +11,8 @@
#include "lf_samyrun.h" #include "lf_samyrun.h"
// samy's sniff and repeat routine for LF // samy's sniff and repeat routine for LF
void RunMod() { void RunMod()
{
StandAloneMode(); StandAloneMode();
Dbprintf(">> LF HID Read/Clone/Sim a.k.a SamyRun Started <<"); Dbprintf(">> LF HID Read/Clone/Sim a.k.a SamyRun Started <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
@ -64,8 +65,7 @@ void RunMod() {
cardRead = 1; cardRead = 1;
gotCard = true; gotCard = true;
} } else if (button_pressed > 0 && cardRead == 1) {
else if (button_pressed > 0 && cardRead == 1) {
LEDsoff(); LEDsoff();
LED(selected + 1, 0); LED(selected + 1, 0);
LED(LED_ORANGE, 0); LED(LED_ORANGE, 0);
@ -129,8 +129,7 @@ void RunMod() {
playing = !playing; playing = !playing;
LEDsoff(); LEDsoff();
LED(selected + 1, 0); LED(selected + 1, 0);
} } else {
else {
while (BUTTON_PRESS()) while (BUTTON_PRESS())
WDT_HIT(); WDT_HIT();
} }

View file

@ -959,10 +959,14 @@ void AesDecBlk(AesCtx *pCtx, const unsigned char ct[], unsigned char pt[])
* map byte array block to cipher state * map byte array block to cipher state
* and add initial round key: * and add initial round key:
*/ */
v0 = GETU32(ct ); s0 = v0 ^ rk[0]; v0 = GETU32(ct);
v1 = GETU32(ct + 4); s1 = v1 ^ rk[1]; s0 = v0 ^ rk[0];
v2 = GETU32(ct + 8); s2 = v2 ^ rk[2]; v1 = GETU32(ct + 4);
v3 = GETU32(ct + 12); s3 = v3 ^ rk[3]; s1 = v1 ^ rk[1];
v2 = GETU32(ct + 8);
s2 = v2 ^ rk[2];
v3 = GETU32(ct + 12);
s3 = v3 ^ rk[3];
/* /*
* Nr - 1 full rounds: * Nr - 1 full rounds:
*/ */
@ -1053,10 +1057,14 @@ void AesDecBlk(AesCtx *pCtx, const unsigned char ct[], unsigned char pt[])
rk[3]; rk[3];
if (pCtx->Mode) { if (pCtx->Mode) {
s0 = s0 ^ iv[0]; iv[0] = v0; s0 = s0 ^ iv[0];
s1 = s1 ^ iv[1]; iv[1] = v1; iv[0] = v0;
s2 = s2 ^ iv[2]; iv[2] = v2; s1 = s1 ^ iv[1];
s3 = s3 ^ iv[3]; iv[3] = v3; iv[1] = v1;
s2 = s2 ^ iv[2];
iv[2] = v2;
s3 = s3 ^ iv[3];
iv[3] = v3;
} }
PUTU32(pt, s0); PUTU32(pt, s0);

View file

@ -54,12 +54,14 @@ int ToSendMax = -1;
static int ToSendBit; static int ToSendBit;
struct common_area common_area __attribute__((section(".commonarea"))); struct common_area common_area __attribute__((section(".commonarea")));
void ToSendReset(void) { void ToSendReset(void)
{
ToSendMax = -1; ToSendMax = -1;
ToSendBit = 8; ToSendBit = 8;
} }
void ToSendStuffBit(int b) { void ToSendStuffBit(int b)
{
if (ToSendBit >= 8) { if (ToSendBit >= 8) {
ToSendMax++; ToSendMax++;
ToSend[ToSendMax] = 0; ToSend[ToSendMax] = 0;
@ -77,12 +79,14 @@ void ToSendStuffBit(int b) {
} }
} }
void PrintToSendBuffer(void) { void PrintToSendBuffer(void)
{
DbpString("Printing ToSendBuffer:"); DbpString("Printing ToSendBuffer:");
Dbhexdump(ToSendMax, ToSend, 0); Dbhexdump(ToSendMax, ToSend, 0);
} }
void print_result(char *name, uint8_t *buf, size_t len) { void print_result(char *name, uint8_t *buf, size_t len)
{
uint8_t *p = buf; uint8_t *p = buf;
uint16_t tmp = len & 0xFFF0; uint16_t tmp = len & 0xFFF0;
@ -110,25 +114,29 @@ void print_result(char *name, uint8_t *buf, size_t len) {
// 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(char *str, uint32_t cmd) { void DbpStringEx(char *str, uint32_t cmd)
{
#if DEBUG #if DEBUG
uint8_t len = strlen(str); uint8_t len = strlen(str);
cmd_send(CMD_DEBUG_PRINT_STRING, len, cmd, 0, (uint8_t *)str, len); cmd_send(CMD_DEBUG_PRINT_STRING, len, cmd, 0, (uint8_t *)str, len);
#endif #endif
} }
void DbpString(char *str) { void DbpString(char *str)
{
#if DEBUG #if DEBUG
DbpStringEx(str, 0); DbpStringEx(str, 0);
#endif #endif
} }
#if 0 #if 0
void DbpIntegers(int x1, int x2, int x3) { void DbpIntegers(int x1, int x2, int x3)
{
cmd_send(CMD_DEBUG_PRINT_INTEGERS, x1, x2, x3, 0, 0); cmd_send(CMD_DEBUG_PRINT_INTEGERS, x1, x2, x3, 0, 0);
} }
#endif #endif
void DbprintfEx(uint32_t cmd, const char *fmt, ...) { void DbprintfEx(uint32_t cmd, 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[128] = {0x00};
@ -141,7 +149,8 @@ void DbprintfEx(uint32_t cmd, const char *fmt, ...) {
#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[128] = {0x00};
@ -156,7 +165,8 @@ void Dbprintf(const char *fmt, ...) {
} }
// prints HEX & ASCII // prints HEX & ASCII
void Dbhexdump(int len, uint8_t *d, bool bAsci) { void Dbhexdump(int len, uint8_t *d, bool bAsci)
{
#if DEBUG #if DEBUG
int l = 0, i; int l = 0, i;
char ascii[9]; char ascii[9];
@ -191,7 +201,8 @@ void Dbhexdump(int len, uint8_t *d, bool bAsci) {
// in ADC units (0 to 1023). Also a routine to average 32 samples and // in ADC units (0 to 1023). Also a routine to average 32 samples and
// return that. // return that.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static uint16_t ReadAdc(int ch) { static uint16_t ReadAdc(int ch)
{
// Note: ADC_MODE_PRESCALE and ADC_MODE_SAMPLE_HOLD_TIME are set to the maximum allowed value. // Note: ADC_MODE_PRESCALE and ADC_MODE_SAMPLE_HOLD_TIME are set to the maximum allowed value.
// AMPL_HI is are high impedance (10MOhm || 1MOhm) output, the input capacitance of the ADC is 12pF (typical). This results in a time constant // AMPL_HI is are high impedance (10MOhm || 1MOhm) output, the input capacitance of the ADC is 12pF (typical). This results in a time constant
@ -217,7 +228,8 @@ static uint16_t ReadAdc(int ch) {
} }
// was static - merlok // was static - merlok
uint16_t AvgAdc(int ch) { uint16_t AvgAdc(int ch)
{
uint16_t a = 0; uint16_t a = 0;
for (uint8_t i = 0; i < 32; i++) for (uint8_t i = 0; i < 32; i++)
a += ReadAdc(ch); a += ReadAdc(ch);
@ -226,7 +238,8 @@ uint16_t AvgAdc(int ch) {
return (a + 15) >> 5; return (a + 15) >> 5;
} }
void MeasureAntennaTuning(void) { void MeasureAntennaTuning(void)
{
uint8_t LF_Results[256]; uint8_t LF_Results[256];
uint32_t i, adcval = 0, peak = 0, peakv = 0, peakf = 0; uint32_t i, adcval = 0, peak = 0, peakv = 0, peakf = 0;
@ -291,7 +304,8 @@ void MeasureAntennaTuning(void) {
LEDsoff(); LEDsoff();
} }
void MeasureAntennaTuningHf(void) { void MeasureAntennaTuningHf(void)
{
uint16_t volt = 0; // in mV uint16_t volt = 0; // in mV
// Let the FPGA drive the high-frequency antenna around 13.56 MHz. // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
@ -313,7 +327,8 @@ void MeasureAntennaTuningHf(void) {
DbprintfEx(FLAG_NOOPT, "\n[+] cancelled", 1); DbprintfEx(FLAG_NOOPT, "\n[+] cancelled", 1);
} }
void ReadMem(int addr) { void ReadMem(int addr)
{
const uint8_t *data = ((uint8_t *)addr); const uint8_t *data = ((uint8_t *)addr);
Dbprintf("%x: %02x %02x %02x %02x %02x %02x %02x %02x", addr, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); Dbprintf("%x: %02x %02x %02x %02x %02x %02x %02x %02x", addr, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
@ -323,7 +338,8 @@ void ReadMem(int addr) {
extern struct version_information version_information; extern struct version_information version_information;
/* bootrom version information is pointed to from _bootphase1_version_pointer */ /* bootrom version information is pointed to from _bootphase1_version_pointer */
extern char *_bootphase1_version_pointer, _flash_start, _flash_end, _bootrom_start, _bootrom_end, __data_src_start__; extern char *_bootphase1_version_pointer, _flash_start, _flash_end, _bootrom_start, _bootrom_end, __data_src_start__;
void SendVersion(void) { void SendVersion(void)
{
char temp[USB_CMD_DATA_SIZE]; /* Limited data payload in USB packets */ char temp[USB_CMD_DATA_SIZE]; /* Limited data payload in USB packets */
char VersionString[USB_CMD_DATA_SIZE] = { '\0' }; char VersionString[USB_CMD_DATA_SIZE] = { '\0' };
@ -361,7 +377,8 @@ void SendVersion(void) {
// measure the USB Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time. // measure the USB Speed by sending SpeedTestBufferSize bytes to client and measuring the elapsed time.
// Note: this mimics GetFromBigbuf(), i.e. we have the overhead of the UsbCommand structure included. // Note: this mimics GetFromBigbuf(), i.e. we have the overhead of the UsbCommand structure included.
void printUSBSpeed(void) { void printUSBSpeed(void)
{
Dbprintf("USB Speed"); Dbprintf("USB Speed");
Dbprintf(" Sending USB packets to client..."); Dbprintf(" Sending USB packets to client...");
@ -388,7 +405,8 @@ void printUSBSpeed(void) {
/** /**
* Prints runtime information about the PM3. * Prints runtime information about the PM3.
**/ **/
void SendStatus(void) { void SendStatus(void)
{
BigBuf_print_status(); BigBuf_print_status();
Fpga_print_status(); Fpga_print_status();
#ifdef WITH_FLASH #ifdef WITH_FLASH
@ -412,7 +430,8 @@ void SendStatus(void) {
} }
// Show some leds in a pattern to identify StandAlone mod is running // Show some leds in a pattern to identify StandAlone mod is running
void StandAloneMode(void) { void StandAloneMode(void)
{
DbpString("Stand-alone mode! No PC necessary."); DbpString("Stand-alone mode! No PC necessary.");
@ -425,7 +444,8 @@ void StandAloneMode(void) {
} }
// detection of which Standalone Modes is installed // detection of which Standalone Modes is installed
// (iceman) // (iceman)
void printStandAloneModes(void) { void printStandAloneModes(void)
{
DbpString("Installed StandAlone Mode"); DbpString("Installed StandAlone Mode");
@ -503,7 +523,8 @@ static const char LIGHT_SCHEME[] = {
}; };
static const int LIGHT_LEN = sizeof(LIGHT_SCHEME) / sizeof(LIGHT_SCHEME[0]); static const int LIGHT_LEN = sizeof(LIGHT_SCHEME) / sizeof(LIGHT_SCHEME[0]);
void ListenReaderField(int limit) { void ListenReaderField(int limit)
{
#define LF_ONLY 1 #define LF_ONLY 1
#define HF_ONLY 2 #define HF_ONLY 2
#define REPORT_CHANGE 10 // report new values only if they have changed at least by REPORT_CHANGE #define REPORT_CHANGE 10 // report new values only if they have changed at least by REPORT_CHANGE
@ -614,10 +635,14 @@ void ListenReaderField(int limit) {
} }
for (i = 0; i < LIGHT_LEN; i++) { for (i = 0; i < LIGHT_LEN; i++) {
if (display_val >= ((display_max / LIGHT_LEN)*i) && display_val <= ((display_max / LIGHT_LEN) * (i + 1))) { if (display_val >= ((display_max / LIGHT_LEN)*i) && display_val <= ((display_max / LIGHT_LEN) * (i + 1))) {
if (LIGHT_SCHEME[i] & 0x1) LED_C_ON(); else LED_C_OFF(); if (LIGHT_SCHEME[i] & 0x1) LED_C_ON();
if (LIGHT_SCHEME[i] & 0x2) LED_A_ON(); else LED_A_OFF(); else LED_C_OFF();
if (LIGHT_SCHEME[i] & 0x4) LED_B_ON(); else LED_B_OFF(); if (LIGHT_SCHEME[i] & 0x2) LED_A_ON();
if (LIGHT_SCHEME[i] & 0x8) LED_D_ON(); else LED_D_OFF(); else LED_A_OFF();
if (LIGHT_SCHEME[i] & 0x4) LED_B_ON();
else LED_B_OFF();
if (LIGHT_SCHEME[i] & 0x8) LED_D_ON();
else LED_D_OFF();
break; break;
} }
} }
@ -625,7 +650,8 @@ void ListenReaderField(int limit) {
} }
} }
void UsbPacketReceived(uint8_t *packet, int len) { void UsbPacketReceived(uint8_t *packet, int len)
{
UsbCommand *c = (UsbCommand *)packet; UsbCommand *c = (UsbCommand *)packet;
//Dbprintf("received %d bytes, with command: 0x%04x and args: %d %d %d", len, c->cmd, c->arg[0], c->arg[1], c->arg[2]); //Dbprintf("received %d bytes, with command: 0x%04x and args: %d %d %d", len, c->cmd, c->arg[0], c->arg[1], c->arg[2]);
@ -1413,11 +1439,19 @@ void UsbPacketReceived(uint8_t *packet, int len) {
case CMD_SET_ADC_MUX: case CMD_SET_ADC_MUX:
switch (c->arg[0]) { switch (c->arg[0]) {
case 0: SetAdcMuxFor(GPIO_MUXSEL_LOPKD); break; case 0:
case 2: SetAdcMuxFor(GPIO_MUXSEL_HIPKD); break; SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
break;
case 2:
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
break;
#ifndef WITH_FPC #ifndef WITH_FPC
case 1: SetAdcMuxFor(GPIO_MUXSEL_LORAW); break; case 1:
case 3: SetAdcMuxFor(GPIO_MUXSEL_HIRAW); break; SetAdcMuxFor(GPIO_MUXSEL_LORAW);
break;
case 3:
SetAdcMuxFor(GPIO_MUXSEL_HIRAW);
break;
#endif #endif
} }
break; break;
@ -1475,7 +1509,8 @@ void UsbPacketReceived(uint8_t *packet, int len) {
} }
} }
void __attribute__((noreturn)) AppMain(void) { void __attribute__((noreturn)) AppMain(void)
{
SpinDelay(100); SpinDelay(100);
clear_trace(); clear_trace();

View file

@ -1,23 +1,27 @@
#include "buzzer.h" #include "buzzer.h"
void Ring_BEE_ONCE(uint16_t music_note) { void Ring_BEE_ONCE(uint16_t music_note)
{
BEE_ON(); BEE_ON();
SpinDelayUs(music_note); SpinDelayUs(music_note);
BEE_OFF(); BEE_OFF();
SpinDelayUs(music_note); SpinDelayUs(music_note);
} }
void ring_2_7khz(uint16_t count) { void ring_2_7khz(uint16_t count)
{
Ring_BEE_TIME(n_2_7khz, count); Ring_BEE_TIME(n_2_7khz, count);
} }
void Ring_BEE_TIME(uint16_t music_note,uint16_t count) { void Ring_BEE_TIME(uint16_t music_note, uint16_t count)
{
for (uint16_t i = 0 ; i < count; i++) for (uint16_t i = 0 ; i < count; i++)
Ring_BEE_ONCE(music_note); Ring_BEE_ONCE(music_note);
SpinDelay(9); SpinDelay(9);
} }
void Ring_ALL(uint16_t count) { void Ring_ALL(uint16_t count)
{
Ring_BEE_TIME(note_1, count); Ring_BEE_TIME(note_1, count);
Ring_BEE_TIME(note_2, count); Ring_BEE_TIME(note_2, count);
Ring_BEE_TIME(note_3, count); Ring_BEE_TIME(note_3, count);
@ -28,7 +32,8 @@ void Ring_ALL(uint16_t count) {
SpinDelay(10); SpinDelay(10);
} }
void Ring_Little_Star(uint16_t count) { void Ring_Little_Star(uint16_t count)
{
Ring_BEE_TIME(note_1, count); Ring_BEE_TIME(note_1, count);
Ring_BEE_TIME(note_1, count); Ring_BEE_TIME(note_1, count);
Ring_BEE_TIME(note_5, count); Ring_BEE_TIME(note_5, count);

View file

@ -202,7 +202,8 @@ const uint8_t shiftkeyinv_permtab[] = {
#define ROTTABLE_INV 0x3F7E #define ROTTABLE_INV 0x3F7E
/******************************************************************************/ /******************************************************************************/
void permute(const uint8_t *ptable, const uint8_t *in, uint8_t *out){ void permute(const uint8_t *ptable, const uint8_t *in, uint8_t *out)
{
uint8_t ob; /* in-bytes and out-bytes */ uint8_t ob; /* in-bytes and out-bytes */
uint8_t byte, bit; /* counter for bit and byte */ uint8_t byte, bit; /* counter for bit and byte */
ob = ptable[1]; ob = ptable[1];
@ -222,7 +223,8 @@ void permute(const uint8_t *ptable, const uint8_t *in, uint8_t *out){
/******************************************************************************/ /******************************************************************************/
void changeendian32(uint32_t * a){ void changeendian32(uint32_t *a)
{
*a = (*a & 0x000000FF) << 24 | *a = (*a & 0x000000FF) << 24 |
(*a & 0x0000FF00) << 8 | (*a & 0x0000FF00) << 8 |
(*a & 0x00FF0000) >> 8 | (*a & 0x00FF0000) >> 8 |
@ -231,7 +233,8 @@ void changeendian32(uint32_t * a){
/******************************************************************************/ /******************************************************************************/
static inline static inline
void shiftkey(uint8_t *key){ void shiftkey(uint8_t *key)
{
uint8_t k[7]; uint8_t k[7];
memcpy(k, key, 7); memcpy(k, key, 7);
permute((uint8_t *)shiftkey_permtab, k, key); permute((uint8_t *)shiftkey_permtab, k, key);
@ -239,7 +242,8 @@ void shiftkey(uint8_t *key){
/******************************************************************************/ /******************************************************************************/
static inline static inline
void shiftkey_inv(uint8_t *key){ void shiftkey_inv(uint8_t *key)
{
uint8_t k[7]; uint8_t k[7];
memcpy(k, key, 7); memcpy(k, key, 7);
permute((uint8_t *)shiftkeyinv_permtab, k, key); permute((uint8_t *)shiftkeyinv_permtab, k, key);
@ -248,7 +252,8 @@ void shiftkey_inv(uint8_t *key){
/******************************************************************************/ /******************************************************************************/
static inline static inline
uint64_t splitin6bitwords(uint64_t a){ uint64_t splitin6bitwords(uint64_t a)
{
uint64_t ret = 0; uint64_t ret = 0;
a &= 0x0000ffffffffffffLL; a &= 0x0000ffffffffffffLL;
permute((uint8_t *)splitin6bitword_permtab, (uint8_t *)&a, (uint8_t *)&ret); permute((uint8_t *)splitin6bitword_permtab, (uint8_t *)&a, (uint8_t *)&ret);
@ -258,7 +263,8 @@ uint64_t splitin6bitwords(uint64_t a){
/******************************************************************************/ /******************************************************************************/
static inline static inline
uint8_t substitute(uint8_t a, uint8_t * sbp){ uint8_t substitute(uint8_t a, uint8_t *sbp)
{
uint8_t x; uint8_t x;
x = sbp[a >> 1]; x = sbp[a >> 1];
x = (a & 1) ? x & 0x0F : x >> 4; x = (a & 1) ? x & 0x0F : x >> 4;
@ -268,7 +274,8 @@ uint8_t substitute(uint8_t a, uint8_t * sbp){
/******************************************************************************/ /******************************************************************************/
uint32_t des_f(uint32_t r, uint8_t* kr){ uint32_t des_f(uint32_t r, uint8_t *kr)
{
uint8_t i; uint8_t i;
uint32_t t = 0, ret; uint32_t t = 0, ret;
uint64_t data; uint64_t data;
@ -305,7 +312,8 @@ typedef struct {
#define R (data.d.v32[1]) #define R (data.d.v32[1])
#define L (data.d.v32[0]) #define L (data.d.v32[0])
void des_enc(void* out, const void* in, const void* key){ void des_enc(void *out, const void *in, const void *key)
{
uint8_t kr[6], k[7]; uint8_t kr[6], k[7];
uint8_t i; uint8_t i;
@ -338,7 +346,8 @@ void des_enc(void* out, const void* in, const void* key){
/******************************************************************************/ /******************************************************************************/
void des_dec(void* out, const void* in, const uint8_t* key){ void des_dec(void *out, const void *in, const uint8_t *key)
{
uint8_t kr[6], k[7]; uint8_t kr[6], k[7];
int8_t i; int8_t i;
@ -373,7 +382,8 @@ void des_dec(void* out, const void* in, const uint8_t* key){
/******************************************************************************/ /******************************************************************************/
void tdes_enc(void* out, void* in, const void* key){ void tdes_enc(void *out, void *in, const void *key)
{
des_enc(out, in, (uint8_t *)key + 0); des_enc(out, in, (uint8_t *)key + 0);
des_dec(out, out, (uint8_t *)key + 8); des_dec(out, out, (uint8_t *)key + 8);
des_enc(out, out, (uint8_t *)key + 16); des_enc(out, out, (uint8_t *)key + 16);
@ -381,13 +391,15 @@ void tdes_enc(void* out, void* in, const void* key){
/******************************************************************************/ /******************************************************************************/
void tdes_dec(void* out, void* in, const uint8_t* key){ void tdes_dec(void *out, void *in, const uint8_t *key)
{
des_dec(out, in, (uint8_t *)key + 16); des_dec(out, in, (uint8_t *)key + 16);
des_enc(out, out, (uint8_t *)key + 8); des_enc(out, out, (uint8_t *)key + 8);
des_dec(out, out, (uint8_t *)key + 0); des_dec(out, out, (uint8_t *)key + 0);
} }
void tdes_2key_enc(void* out, const void* in, size_t length, const void* key, unsigned char iv[8]){ void tdes_2key_enc(void *out, const void *in, size_t length, const void *key, unsigned char iv[8])
{
if (length % 8) return; if (length % 8) return;
@ -395,8 +407,7 @@ void tdes_dec(void* out, void* in, const uint8_t* key){
uint8_t *tin = (uint8_t *) in; uint8_t *tin = (uint8_t *) in;
uint8_t *tout = (uint8_t *) out; uint8_t *tout = (uint8_t *) out;
while( length > 0 ) while (length > 0) {
{
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
tout[i] = (unsigned char)(tin[i] ^ iv[i]); tout[i] = (unsigned char)(tin[i] ^ iv[i]);
@ -412,7 +423,8 @@ void tdes_dec(void* out, void* in, const uint8_t* key){
} }
} }
void tdes_2key_dec(void* out, const void* in, size_t length, const void* key, unsigned char iv[8]){ void tdes_2key_dec(void *out, const void *in, size_t length, const void *key, unsigned char iv[8])
{
if (length % 8) return; if (length % 8) return;
@ -421,8 +433,7 @@ void tdes_dec(void* out, void* in, const uint8_t* key){
uint8_t *tin = (uint8_t *) in; uint8_t *tin = (uint8_t *) in;
uint8_t *tout = (uint8_t *) out; uint8_t *tout = (uint8_t *) out;
while( length > 0 ) while (length > 0) {
{
memcpy(temp, tin, 8); memcpy(temp, tin, 8);
des_dec(tout, tin, (uint8_t *)key + 0); des_dec(tout, tin, (uint8_t *)key + 0);

View file

@ -31,13 +31,15 @@ static void xor (const uint8_t *ivect, uint8_t *data, const size_t len);
static size_t key_macing_length(desfirekey_t key); static size_t key_macing_length(desfirekey_t key);
// iceman, see memxor inside string.c, dest/src swapped.. // iceman, see memxor inside string.c, dest/src swapped..
static void xor (const uint8_t *ivect, uint8_t *data, const size_t len) { static void xor(const uint8_t *ivect, uint8_t *data, const size_t len)
{
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
data[i] ^= ivect[i]; data[i] ^= ivect[i];
} }
} }
void cmac_generate_subkeys ( desfirekey_t key) { void cmac_generate_subkeys(desfirekey_t key)
{
int kbs = key_block_size(key); int kbs = key_block_size(key);
const uint8_t R = (kbs == 8) ? 0x1B : 0x87; const uint8_t R = (kbs == 8) ? 0x1B : 0x87;
@ -66,7 +68,8 @@ void cmac_generate_subkeys ( desfirekey_t key) {
key->cmac_sk2[kbs - 1] ^= R; key->cmac_sk2[kbs - 1] ^= R;
} }
void cmac (const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac) { void cmac(const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t len, uint8_t *cmac)
{
int kbs = key_block_size(key); int kbs = key_block_size(key);
uint8_t *buffer = malloc(padded_data_length(len, kbs)); uint8_t *buffer = malloc(padded_data_length(len, kbs));
@ -88,7 +91,8 @@ void cmac (const desfirekey_t key, uint8_t *ivect, const uint8_t *data, size_t l
free(buffer); free(buffer);
} }
size_t key_block_size (const desfirekey_t key) { size_t key_block_size(const desfirekey_t key)
{
size_t block_size = 8; size_t block_size = 8;
switch (key->type) { switch (key->type) {
case T_DES: case T_DES:
@ -106,7 +110,8 @@ size_t key_block_size (const desfirekey_t key) {
/* /*
* Size of MACing produced with the key. * Size of MACing produced with the key.
*/ */
static size_t key_macing_length (const desfirekey_t key) { static size_t key_macing_length(const desfirekey_t key)
{
size_t mac_length = MAC_LENGTH; size_t mac_length = MAC_LENGTH;
switch (key->type) { switch (key->type) {
case T_DES: case T_DES:
@ -124,7 +129,8 @@ static size_t key_macing_length (const desfirekey_t key) {
/* /*
* Size required to store nbytes of data in a buffer of size n*block_size. * Size required to store nbytes of data in a buffer of size n*block_size.
*/ */
size_t padded_data_length (const size_t nbytes, const size_t block_size) { size_t padded_data_length(const size_t nbytes, const size_t block_size)
{
if ((!nbytes) || (nbytes % block_size)) if ((!nbytes) || (nbytes % block_size))
return ((nbytes / block_size) + 1) * block_size; return ((nbytes / block_size) + 1) * block_size;
else else
@ -134,13 +140,15 @@ size_t padded_data_length (const size_t nbytes, const size_t block_size) {
/* /*
* Buffer size required to MAC nbytes of data * Buffer size required to MAC nbytes of data
*/ */
size_t maced_data_length (const desfirekey_t key, const size_t nbytes) { size_t maced_data_length(const desfirekey_t key, const size_t nbytes)
{
return nbytes + key_macing_length(key); return nbytes + key_macing_length(key);
} }
/* /*
* Buffer size required to encipher nbytes of data and a two bytes CRC. * Buffer size required to encipher nbytes of data and a two bytes CRC.
*/ */
size_t enciphered_data_length (const desfiretag_t tag, const size_t nbytes, int communication_settings) { size_t enciphered_data_length(const desfiretag_t tag, const size_t nbytes, int communication_settings)
{
size_t crc_length = 0; size_t crc_length = 0;
if (!(communication_settings & NO_CRC)) { if (!(communication_settings & NO_CRC)) {
switch (DESFIRE(tag)->authentication_scheme) { switch (DESFIRE(tag)->authentication_scheme) {
@ -158,7 +166,8 @@ size_t enciphered_data_length (const desfiretag_t tag, const size_t nbytes, int
return padded_data_length(nbytes + crc_length, block_size); return padded_data_length(nbytes + crc_length, block_size);
} }
void* mifare_cryto_preprocess_data (desfiretag_t tag, void *data, size_t *nbytes, size_t offset, int communication_settings) { void *mifare_cryto_preprocess_data(desfiretag_t tag, void *data, size_t *nbytes, size_t offset, int communication_settings)
{
uint8_t *res = data; uint8_t *res = data;
uint8_t mac[4]; uint8_t mac[4];
size_t edl; size_t edl;
@ -570,17 +579,14 @@ void mifare_cypher_single_block (desfirekey_t key, uint8_t *data, uint8_t *ivect
} }
break; break;
case T_AES: case T_AES:
switch (operation) switch (operation) {
{ case MCO_ENCYPHER: {
case MCO_ENCYPHER:
{
AesCtx ctx; AesCtx ctx;
AesCtxIni(&ctx, ivect, key->data, KEY128, CBC); AesCtxIni(&ctx, ivect, key->data, KEY128, CBC);
AesEncrypt(&ctx, data, edata, sizeof(edata)); AesEncrypt(&ctx, data, edata, sizeof(edata));
break; break;
} }
case MCO_DECYPHER: case MCO_DECYPHER: {
{
AesCtx ctx; AesCtx ctx;
AesCtxIni(&ctx, ivect, key->data, KEY128, CBC); AesCtxIni(&ctx, ivect, key->data, KEY128, CBC);
AesDecrypt(&ctx, edata, data, sizeof(edata)); AesDecrypt(&ctx, edata, data, sizeof(edata));
@ -610,7 +616,8 @@ void mifare_cypher_single_block (desfirekey_t key, uint8_t *data, uint8_t *ivect
* Because the tag may contain additional data, one may need to call this * Because the tag may contain additional data, one may need to call this
* function with tag, key and ivect defined. * function with tag, key and ivect defined.
*/ */
void mifare_cypher_blocks_chained (desfiretag_t tag, desfirekey_t key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation) { void mifare_cypher_blocks_chained(desfiretag_t tag, desfirekey_t key, uint8_t *ivect, uint8_t *data, size_t data_size, MifareCryptoDirection direction, MifareCryptoOperation operation)
{
size_t block_size; size_t block_size;
if (tag) { if (tag) {

View file

@ -21,7 +21,8 @@
static inline void update_key_schedules(desfirekey_t key); static inline void update_key_schedules(desfirekey_t key);
static inline void update_key_schedules (desfirekey_t key) { static inline void update_key_schedules(desfirekey_t key)
{
// DES_set_key ((DES_cblock *)key->data, &(key->ks1)); // DES_set_key ((DES_cblock *)key->data, &(key->ks1));
// DES_set_key ((DES_cblock *)(key->data + 8), &(key->ks2)); // DES_set_key ((DES_cblock *)(key->data + 8), &(key->ks2));
// if (T_3K3DES == key->type) { // if (T_3K3DES == key->type) {
@ -29,7 +30,8 @@ static inline void update_key_schedules (desfirekey_t key) {
// } // }
} }
void Desfire_des_key_new (const uint8_t value[8], desfirekey_t key) { void Desfire_des_key_new(const uint8_t value[8], desfirekey_t key)
{
uint8_t data[8]; uint8_t data[8];
memcpy(data, value, 8); memcpy(data, value, 8);
for (int n = 0; n < 8; n++) for (int n = 0; n < 8; n++)
@ -37,7 +39,8 @@ void Desfire_des_key_new (const uint8_t value[8], desfirekey_t key) {
Desfire_des_key_new_with_version(data, key); Desfire_des_key_new_with_version(data, key);
} }
void Desfire_des_key_new_with_version (const uint8_t value[8], desfirekey_t key) { void Desfire_des_key_new_with_version(const uint8_t value[8], desfirekey_t key)
{
if (key != NULL) { if (key != NULL) {
key->type = T_DES; key->type = T_DES;
memcpy(key->data, value, 8); memcpy(key->data, value, 8);
@ -46,7 +49,8 @@ void Desfire_des_key_new_with_version (const uint8_t value[8], desfirekey_t key)
} }
} }
void Desfire_3des_key_new (const uint8_t value[16], desfirekey_t key) { void Desfire_3des_key_new(const uint8_t value[16], desfirekey_t key)
{
uint8_t data[16]; uint8_t data[16];
memcpy(data, value, 16); memcpy(data, value, 16);
for (int n = 0; n < 8; n++) for (int n = 0; n < 8; n++)
@ -56,7 +60,8 @@ void Desfire_3des_key_new (const uint8_t value[16], desfirekey_t key) {
Desfire_3des_key_new_with_version(data, key); Desfire_3des_key_new_with_version(data, key);
} }
void Desfire_3des_key_new_with_version (const uint8_t value[16], desfirekey_t key) { void Desfire_3des_key_new_with_version(const uint8_t value[16], desfirekey_t key)
{
if (key != NULL) { if (key != NULL) {
key->type = T_3DES; key->type = T_3DES;
memcpy(key->data, value, 16); memcpy(key->data, value, 16);
@ -65,7 +70,8 @@ void Desfire_3des_key_new_with_version (const uint8_t value[16], desfirekey_t ke
} }
} }
void Desfire_3k3des_key_new (const uint8_t value[24], desfirekey_t key) { void Desfire_3k3des_key_new(const uint8_t value[24], desfirekey_t key)
{
uint8_t data[24]; uint8_t data[24];
memcpy(data, value, 24); memcpy(data, value, 24);
for (int n = 0; n < 8; n++) for (int n = 0; n < 8; n++)
@ -73,7 +79,8 @@ void Desfire_3k3des_key_new (const uint8_t value[24], desfirekey_t key) {
Desfire_3k3des_key_new_with_version(data, key); Desfire_3k3des_key_new_with_version(data, key);
} }
void Desfire_3k3des_key_new_with_version (const uint8_t value[24], desfirekey_t key) { void Desfire_3k3des_key_new_with_version(const uint8_t value[24], desfirekey_t key)
{
if (key != NULL) { if (key != NULL) {
key->type = T_3K3DES; key->type = T_3K3DES;
memcpy(key->data, value, 24); memcpy(key->data, value, 24);
@ -81,11 +88,13 @@ void Desfire_3k3des_key_new_with_version (const uint8_t value[24], desfirekey_t
} }
} }
void Desfire_aes_key_new (const uint8_t value[16], desfirekey_t key) { void Desfire_aes_key_new(const uint8_t value[16], desfirekey_t key)
{
Desfire_aes_key_new_with_version(value, 0, key); Desfire_aes_key_new_with_version(value, 0, key);
} }
void Desfire_aes_key_new_with_version (const uint8_t value[16], uint8_t version, desfirekey_t key) { void Desfire_aes_key_new_with_version(const uint8_t value[16], uint8_t version, desfirekey_t key)
{
if (key != NULL) { if (key != NULL) {
memcpy(key->data, value, 16); memcpy(key->data, value, 16);
@ -94,7 +103,8 @@ void Desfire_3k3des_key_new_with_version (const uint8_t value[24], desfirekey_t
} }
} }
uint8_t Desfire_key_get_version (desfirekey_t key) { uint8_t Desfire_key_get_version(desfirekey_t key)
{
uint8_t version = 0; uint8_t version = 0;
for (int n = 0; n < 8; n++) { for (int n = 0; n < 8; n++) {
@ -119,7 +129,8 @@ void Desfire_key_set_version (desfirekey_t key, uint8_t version)
} }
} }
void Desfire_session_key_new (const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key) { void Desfire_session_key_new(const uint8_t rnda[], const uint8_t rndb[], desfirekey_t authkey, desfirekey_t key)
{
uint8_t buffer[24]; uint8_t buffer[24];

View file

@ -105,8 +105,7 @@ static char iso_type = 0;
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response) int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response)
{ {
switch(iso_type) switch (iso_type) {
{
case 'a': case 'a':
return iso14_apdu(apdu, (uint16_t) length, false, response, NULL); return iso14_apdu(apdu, (uint16_t) length, false, response, NULL);
break; break;
@ -166,8 +165,7 @@ size_t EPA_Parse_CardAccess(uint8_t *data,
&& memcmp(data + index + 2, && memcmp(data + index + 2,
oid_pace_start, oid_pace_start,
sizeof(oid_pace_start)) == 0 // content matches sizeof(oid_pace_start)) == 0 // content matches
&& pace_info != NULL) && pace_info != NULL) {
{
// first, clear the pace_info struct // first, clear the pace_info struct
memset(pace_info, 0, sizeof(pace_version_info_t)); memset(pace_info, 0, sizeof(pace_version_info_t));
memcpy(pace_info->oid, data + index + 2, sizeof(pace_info->oid)); memcpy(pace_info->oid, data + index + 2, sizeof(pace_info->oid));
@ -176,8 +174,7 @@ size_t EPA_Parse_CardAccess(uint8_t *data,
if (data[index] == 02 && data[index + 1] == 01) { if (data[index] == 02 && data[index + 1] == 01) {
pace_info->version = data[index + 2]; pace_info->version = data[index + 2];
index += 3; index += 3;
} } else {
else {
return index; return index;
} }
// after that there might(!) be the parameter ID // after that there might(!) be the parameter ID
@ -185,8 +182,7 @@ size_t EPA_Parse_CardAccess(uint8_t *data,
pace_info->parameter_id = data[index + 2]; pace_info->parameter_id = data[index + 2];
index += 3; index += 3;
} }
} } else {
else {
// skip this OID // skip this OID
index += 2 + data[index + 1]; index += 2 + data[index + 1];
} }
@ -195,8 +191,7 @@ size_t EPA_Parse_CardAccess(uint8_t *data,
// TODO: This needs to be extended to support long tags // TODO: This needs to be extended to support long tags
else if (data[index + 1] == 0) { else if (data[index + 1] == 0) {
return index; return index;
} } else {
else {
// skip this part // skip this part
// TODO: This needs to be extended to support long tags // TODO: This needs to be extended to support long tags
// TODO: This needs to be extended to support unknown elements with // TODO: This needs to be extended to support unknown elements with
@ -229,8 +224,7 @@ int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length)
response_apdu); response_apdu);
if (rapdu_length < 6 if (rapdu_length < 6
|| response_apdu[rapdu_length - 4] != 0x90 || response_apdu[rapdu_length - 4] != 0x90
|| response_apdu[rapdu_length - 3] != 0x00) || response_apdu[rapdu_length - 3] != 0x00) {
{
DbpString("Failed to select EF.CardAccess!"); DbpString("Failed to select EF.CardAccess!");
return -1; return -1;
} }
@ -241,8 +235,7 @@ int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length)
response_apdu); response_apdu);
if (rapdu_length <= 6 if (rapdu_length <= 6
|| response_apdu[rapdu_length - 4] != 0x90 || response_apdu[rapdu_length - 4] != 0x90
|| response_apdu[rapdu_length - 3] != 0x00) || response_apdu[rapdu_length - 3] != 0x00) {
{
Dbprintf("Failed to read EF.CardAccess!"); Dbprintf("Failed to read EF.CardAccess!");
return -1; return -1;
} }
@ -324,8 +317,7 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c)
uint8_t requested_size = (uint8_t)c->arg[0]; uint8_t requested_size = (uint8_t)c->arg[0];
func_return = EPA_PACE_Get_Nonce(requested_size, nonce); func_return = EPA_PACE_Get_Nonce(requested_size, nonce);
// check if the command succeeded // check if the command succeeded
if (func_return < 0) if (func_return < 0) {
{
EPA_PACE_Collect_Nonce_Abort(4, func_return); EPA_PACE_Collect_Nonce_Abort(4, func_return);
return; return;
} }
@ -364,21 +356,18 @@ int EPA_PACE_Get_Nonce(uint8_t requested_length, uint8_t *nonce)
// check if the command succeeded // check if the command succeeded
if (send_return < 6 if (send_return < 6
|| response_apdu[send_return - 4] != 0x90 || response_apdu[send_return - 4] != 0x90
|| response_apdu[send_return - 3] != 0x00) || response_apdu[send_return - 3] != 0x00) {
{
return -1; return -1;
} }
// if there is no nonce in the RAPDU, return here // if there is no nonce in the RAPDU, return here
if (send_return < 10) if (send_return < 10) {
{
// no error // no error
return 0; return 0;
} }
// get the actual length of the nonce // get the actual length of the nonce
uint8_t nonce_length = response_apdu[5]; uint8_t nonce_length = response_apdu[5];
if (nonce_length > send_return - 10) if (nonce_length > send_return - 10) {
{
nonce_length = send_return - 10; nonce_length = send_return - 10;
} }
// copy the nonce // copy the nonce
@ -435,8 +424,7 @@ int EPA_PACE_MSE_Set_AT(pace_version_info_t pace_version_info, uint8_t password)
// check if the command succeeded // check if the command succeeded
if (send_return != 6 if (send_return != 6
|| response_apdu[send_return - 4] != 0x90 || response_apdu[send_return - 4] != 0x90
|| response_apdu[send_return - 3] != 0x00) || response_apdu[send_return - 3] != 0x00) {
{
return 1; return 1;
} }
return 0; return 0;
@ -452,8 +440,7 @@ void EPA_PACE_Replay(UsbCommand *c)
// if an APDU has been passed, save it // if an APDU has been passed, save it
if (c->arg[0] != 0) { if (c->arg[0] != 0) {
// make sure it's not too big // make sure it's not too big
if(c->arg[2] > apdus_replay[c->arg[0] - 1].len) if (c->arg[2] > apdus_replay[c->arg[0] - 1].len) {
{
cmd_send(CMD_ACK, 1, 0, 0, NULL, 0); cmd_send(CMD_ACK, 1, 0, 0, NULL, 0);
} }
memcpy(apdus_replay[c->arg[0] - 1].data + c->arg[1], memcpy(apdus_replay[c->arg[0] - 1].data + c->arg[1],
@ -497,8 +484,7 @@ void EPA_PACE_Replay(UsbCommand *c)
if (i < sizeof(apdu_lengths_replay) - 1 if (i < sizeof(apdu_lengths_replay) - 1
&& (func_return < 6 && (func_return < 6
|| response_apdu[func_return - 4] != 0x90 || response_apdu[func_return - 4] != 0x90
|| response_apdu[func_return - 3] != 0x00)) || response_apdu[func_return - 3] != 0x00)) {
{
EPA_Finish(); EPA_Finish();
cmd_send(CMD_ACK, 3 + i, func_return, 0, timings, 20); cmd_send(CMD_ACK, 3 + i, func_return, 0, timings, 20);
return; return;

View file

@ -34,11 +34,13 @@ static uint8_t felica_select_card(felica_card_select_t *card);
static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, uint8_t power, uint8_t highspeed); static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, uint8_t power, uint8_t highspeed);
bool WaitForFelicaReply(uint16_t maxbytes); bool WaitForFelicaReply(uint16_t maxbytes);
void iso18092_set_timeout(uint32_t timeout) { void iso18092_set_timeout(uint32_t timeout)
{
felica_timeout = timeout + (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / (16 * 8) + 2; felica_timeout = timeout + (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / (16 * 8) + 2;
} }
uint32_t iso18092_get_timeout(void) { uint32_t iso18092_get_timeout(void)
{
return felica_timeout - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / (16 * 8) - 2; return felica_timeout - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / (16 * 8) - 2;
} }
@ -77,19 +79,22 @@ static struct {
# define SYNC_16BIT 0xB24D # define SYNC_16BIT 0xB24D
#endif #endif
static void FelicaFrameReset() { static void FelicaFrameReset()
{
FelicaFrame.state = STATE_UNSYNCD; FelicaFrame.state = STATE_UNSYNCD;
FelicaFrame.posCnt = 0; FelicaFrame.posCnt = 0;
FelicaFrame.crc_ok = false; FelicaFrame.crc_ok = false;
FelicaFrame.byte_offset = 0; FelicaFrame.byte_offset = 0;
} }
static void FelicaFrameinit(uint8_t *data) { static void FelicaFrameinit(uint8_t *data)
{
FelicaFrame.framebytes = data; FelicaFrame.framebytes = data;
FelicaFrameReset(); FelicaFrameReset();
} }
//shift byte into frame, reversing it at the same time //shift byte into frame, reversing it at the same time
static void shiftInByte(uint8_t bt) { static void shiftInByte(uint8_t bt)
{
uint8_t j; uint8_t j;
for (j = 0; j < FelicaFrame.byte_offset; j++) { for (j = 0; j < FelicaFrame.byte_offset; j++) {
FelicaFrame.framebytes[FelicaFrame.posCnt] = (FelicaFrame.framebytes[FelicaFrame.posCnt] << 1) + (bt & 1); FelicaFrame.framebytes[FelicaFrame.posCnt] = (FelicaFrame.framebytes[FelicaFrame.posCnt] << 1) + (bt & 1);
@ -103,7 +108,8 @@ static void shiftInByte(uint8_t bt) {
} }
} }
static void Process18092Byte(uint8_t bt) { static void Process18092Byte(uint8_t bt)
{
switch (FelicaFrame.state) { switch (FelicaFrame.state) {
case STATE_UNSYNCD: { case STATE_UNSYNCD: {
//almost any nonzero byte can be start of SYNC. SYNC should be preceded by zeros, but that is not alsways the case //almost any nonzero byte can be start of SYNC. SYNC should be preceded by zeros, but that is not alsways the case
@ -190,7 +196,8 @@ static void Process18092Byte(uint8_t bt) {
* Currently does NOT do any collision handling. * Currently does NOT do any collision handling.
* It expects 0-1 cards in the device's range. * It expects 0-1 cards in the device's range.
*/ */
static uint8_t felica_select_card(felica_card_select_t *card) { static uint8_t felica_select_card(felica_card_select_t *card)
{
// POLL command // POLL command
// 0xB2 0x4B = sync code // 0xB2 0x4B = sync code
@ -264,7 +271,8 @@ static uint8_t felica_select_card(felica_card_select_t *card) {
// Felica standard has a different file system, AFAIK, // Felica standard has a different file system, AFAIK,
// 8-byte IDm, number of blocks, blocks numbers // 8-byte IDm, number of blocks, blocks numbers
// number of blocks limited to 4 for FelicaLite(S) // number of blocks limited to 4 for FelicaLite(S)
static void BuildFliteRdblk(uint8_t* idm, int blocknum, uint16_t *blocks ) { static void BuildFliteRdblk(uint8_t *idm, int blocknum, uint16_t *blocks)
{
if (blocknum > 4 || blocknum <= 0) if (blocknum > 4 || blocknum <= 0)
Dbprintf("Invalid number of blocks, %d != 4", blocknum); Dbprintf("Invalid number of blocks, %d != 4", blocknum);
@ -316,7 +324,8 @@ static void BuildFliteRdblk(uint8_t* idm, int blocknum, uint16_t *blocks ) {
AddCrc(frameSpace, c - 2); AddCrc(frameSpace, c - 2);
} }
static void TransmitFor18092_AsReader(uint8_t * frame, int len, uint32_t *timing, uint8_t power, uint8_t highspeed) { static void TransmitFor18092_AsReader(uint8_t *frame, int len, uint32_t *timing, uint8_t power, uint8_t highspeed)
{
uint8_t flags = FPGA_MAJOR_MODE_ISO18092; uint8_t flags = FPGA_MAJOR_MODE_ISO18092;
@ -380,7 +389,8 @@ static void TransmitFor18092_AsReader(uint8_t * frame, int len, uint32_t *timing
// Wait for tag reply // Wait for tag reply
// stop when button is pressed // stop when button is pressed
// or return TRUE when command is captured // or return TRUE when command is captured
bool WaitForFelicaReply(uint16_t maxbytes) { bool WaitForFelicaReply(uint16_t maxbytes)
{
uint32_t c = 0; uint32_t c = 0;
@ -430,13 +440,15 @@ bool WaitForFelicaReply(uint16_t maxbytes) {
// Set up FeliCa communication (similar to iso14443a_setup) // Set up FeliCa communication (similar to iso14443a_setup)
// field is setup for "Sending as Reader" // field is setup for "Sending as Reader"
static void iso18092_setup(uint8_t fpga_minor_mode) { static void iso18092_setup(uint8_t fpga_minor_mode)
{
LEDsoff(); LEDsoff();
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// allocate command receive buffer // allocate command receive buffer
BigBuf_free(); BigBuf_Clear_ext(false); BigBuf_free();
BigBuf_Clear_ext(false);
// Initialize Demod and Uart structs // Initialize Demod and Uart structs
//DemodInit(BigBuf_malloc(MAX_FRAME_SIZE)); //DemodInit(BigBuf_malloc(MAX_FRAME_SIZE));
@ -473,7 +485,8 @@ static void iso18092_setup(uint8_t fpga_minor_mode) {
// arg0 FeliCa flags // arg0 FeliCa flags
// arg1 len of commandbytes // arg1 len of commandbytes
// d.asBytes command bytes to send // d.asBytes command bytes to send
void felica_sendraw(UsbCommand *c) { void felica_sendraw(UsbCommand *c)
{
if (MF_DBGLEVEL > 3) Dbprintf("FeliCa_sendraw Enter"); if (MF_DBGLEVEL > 3) Dbprintf("FeliCa_sendraw Enter");
@ -539,7 +552,8 @@ OUT:
if (MF_DBGLEVEL > 3) Dbprintf("FeliCa_sendraw Exit"); if (MF_DBGLEVEL > 3) Dbprintf("FeliCa_sendraw Exit");
} }
void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) { void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip)
{
int remFrames = (samplesToSkip) ? samplesToSkip : 0; int remFrames = (samplesToSkip) ? samplesToSkip : 0;
@ -610,7 +624,8 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) {
#define R_READBLK_LEN 0x21 #define R_READBLK_LEN 0x21
//simulate NFC Tag3 card - for now only poll response works //simulate NFC Tag3 card - for now only poll response works
// second half (4 bytes) of NDEF2 goes into nfcid2_0, first into nfcid2_1 // second half (4 bytes) of NDEF2 goes into nfcid2_0, first into nfcid2_1
void felica_sim_lite(uint64_t nfcid) { void felica_sim_lite(uint64_t nfcid)
{
int i, curlen = 0; int i, curlen = 0;
uint8_t *curresp = 0; uint8_t *curresp = 0;
@ -716,7 +731,8 @@ void felica_sim_lite(uint64_t nfcid) {
DbpString("Felica Lite-S sim end"); DbpString("Felica Lite-S sim end");
} }
void felica_dump_lite_s() { void felica_dump_lite_s()
{
uint8_t ndef[8]; uint8_t ndef[8];
uint8_t poll[10] = { 0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21}; uint8_t poll[10] = { 0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21};

View file

@ -13,13 +13,15 @@
uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD; uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD;
void FlashmemSetSpiBaudrate(uint32_t baudrate){ void FlashmemSetSpiBaudrate(uint32_t baudrate)
{
FLASHMEM_SPIBAUDRATE = baudrate; FLASHMEM_SPIBAUDRATE = baudrate;
Dbprintf("Spi Baudrate : %dMhz", FLASHMEM_SPIBAUDRATE / 1000000); Dbprintf("Spi Baudrate : %dMhz", FLASHMEM_SPIBAUDRATE / 1000000);
} }
// initialize // initialize
bool FlashInit() { bool FlashInit()
{
FlashSetup(FLASHMEM_SPIBAUDRATE); FlashSetup(FLASHMEM_SPIBAUDRATE);
StartTicks(); StartTicks();
@ -32,7 +34,8 @@ bool FlashInit() {
return true; return true;
} }
void FlashSetup(uint32_t baudrate){ void FlashSetup(uint32_t baudrate)
{
//WDT_DISABLE //WDT_DISABLE
AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS; AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
@ -127,7 +130,8 @@ void FlashSetup(uint32_t baudrate){
if (AT91C_BASE_SPI->SPI_RDR == 0) {}; if (AT91C_BASE_SPI->SPI_RDR == 0) {};
} }
void FlashStop(void) { void FlashStop(void)
{
//Bof //Bof
//* Reset all the Chip Select register //* Reset all the Chip Select register
AT91C_BASE_SPI->SPI_CSR[0] = 0; AT91C_BASE_SPI->SPI_CSR[0] = 0;
@ -150,7 +154,8 @@ void FlashStop(void) {
} }
// send one byte over SPI // send one byte over SPI
uint16_t FlashSendByte(uint32_t data) { uint16_t FlashSendByte(uint32_t data)
{
// wait until SPI is ready for transfer // wait until SPI is ready for transfer
//if you are checking for incoming data returned then the TXEMPTY flag is redundant //if you are checking for incoming data returned then the TXEMPTY flag is redundant
@ -169,12 +174,14 @@ uint16_t FlashSendByte(uint32_t data) {
} }
// send last byte over SPI // send last byte over SPI
uint16_t FlashSendLastByte(uint32_t data) { uint16_t FlashSendLastByte(uint32_t data)
{
return FlashSendByte(data | AT91C_SPI_LASTXFER); return FlashSendByte(data | AT91C_SPI_LASTXFER);
} }
// read state register 1 // read state register 1
uint8_t Flash_ReadStat1(void) { uint8_t Flash_ReadStat1(void)
{
FlashSendByte(READSTAT1); FlashSendByte(READSTAT1);
return FlashSendLastByte(0xFF); return FlashSendLastByte(0xFF);
} }
@ -187,16 +194,13 @@ bool Flash_CheckBusy(uint32_t timeout)
if (MF_DBGLEVEL > 3) Dbprintf("Checkbusy in..."); if (MF_DBGLEVEL > 3) Dbprintf("Checkbusy in...");
do do {
{ if (!(Flash_ReadStat1() & BUSY)) {
if (!(Flash_ReadStat1() & BUSY))
{
return false; return false;
} }
} while ((GetCountUS() - _time) < timeout); } while ((GetCountUS() - _time) < timeout);
if (timeout <= (GetCountUS() - _time)) if (timeout <= (GetCountUS() - _time)) {
{
return true; return true;
} }
@ -204,7 +208,8 @@ bool Flash_CheckBusy(uint32_t timeout)
} }
// read ID out // read ID out
uint8_t Flash_ReadID(void) { uint8_t Flash_ReadID(void)
{
if (Flash_CheckBusy(BUSY_TIMEOUT)) return 0; if (Flash_CheckBusy(BUSY_TIMEOUT)) return 0;
@ -226,7 +231,8 @@ uint8_t Flash_ReadID(void) {
} }
// read unique id for chip. // read unique id for chip.
void Flash_UniqueID(uint8_t *uid) { void Flash_UniqueID(uint8_t *uid)
{
if (Flash_CheckBusy(BUSY_TIMEOUT)) return; if (Flash_CheckBusy(BUSY_TIMEOUT)) return;
@ -247,7 +253,8 @@ void Flash_UniqueID(uint8_t *uid) {
uid[0] = FlashSendLastByte(0xFF); uid[0] = FlashSendLastByte(0xFF);
} }
uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) { uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len)
{
if (!FlashInit()) return 0; if (!FlashInit()) return 0;
@ -272,14 +279,16 @@ uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
return len; return len;
} }
void Flash_TransferAdresse(uint32_t address){ void Flash_TransferAdresse(uint32_t address)
{
FlashSendByte((address >> 16) & 0xFF); FlashSendByte((address >> 16) & 0xFF);
FlashSendByte((address >> 8) & 0xFF); FlashSendByte((address >> 8) & 0xFF);
FlashSendByte((address >> 0) & 0xFF); FlashSendByte((address >> 0) & 0xFF);
} }
/* This ensure we can ReadData without having to cycle through initialization everytime */ /* This ensure we can ReadData without having to cycle through initialization everytime */
uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len) { uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len)
{
// length should never be zero // length should never be zero
if (!len) return 0; if (!len) return 0;
@ -305,7 +314,8 @@ uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len) {
//////////////////////////////////////// ////////////////////////////////////////
// Write data can only program one page. A page has 256 bytes. // Write data can only program one page. A page has 256 bytes.
// if len > 256, it might wrap around and overwrite pos 0. // if len > 256, it might wrap around and overwrite pos 0.
uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) { uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len)
{
// length should never be zero // length should never be zero
if (!len) if (!len)
@ -351,7 +361,8 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
// length should never be zero // length should never be zero
// Max 256 bytes write // Max 256 bytes write
// out-of-range // out-of-range
uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len) { uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len)
{
if (!len) if (!len)
return 0; return 0;
@ -381,7 +392,8 @@ uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len) {
// assumes valid start 256 based 00 address // assumes valid start 256 based 00 address
// //
uint16_t Flash_Write(uint32_t address, uint8_t *in, uint16_t len) { uint16_t Flash_Write(uint32_t address, uint8_t *in, uint16_t len)
{
bool isok; bool isok;
uint16_t res, bytes_sent = 0, bytes_remaining = len; uint16_t res, bytes_sent = 0, bytes_remaining = len;
@ -412,7 +424,8 @@ out:
} }
bool Flash_WipeMemoryPage(uint8_t page) { bool Flash_WipeMemoryPage(uint8_t page)
{
if (!FlashInit()) { if (!FlashInit()) {
if (MF_DBGLEVEL > 3) Dbprintf("Flash_WriteData init fail"); if (MF_DBGLEVEL > 3) Dbprintf("Flash_WriteData init fail");
return false; return false;
@ -420,13 +433,16 @@ bool Flash_WipeMemoryPage(uint8_t page) {
Flash_ReadStat1(); Flash_ReadStat1();
// Each block is 64Kb. One block erase takes 1s ( 1000ms ) // Each block is 64Kb. One block erase takes 1s ( 1000ms )
Flash_WriteEnable(); Flash_Erase64k(page); Flash_CheckBusy(BUSY_TIMEOUT); Flash_WriteEnable();
Flash_Erase64k(page);
Flash_CheckBusy(BUSY_TIMEOUT);
FlashStop(); FlashStop();
return true; return true;
} }
// Wipes flash memory completely, fills with 0xFF // Wipes flash memory completely, fills with 0xFF
bool Flash_WipeMemory() { bool Flash_WipeMemory()
{
if (!FlashInit()) { if (!FlashInit()) {
if (MF_DBGLEVEL > 3) Dbprintf("Flash_WriteData init fail"); if (MF_DBGLEVEL > 3) Dbprintf("Flash_WriteData init fail");
return false; return false;
@ -435,24 +451,34 @@ bool Flash_WipeMemory() {
// Each block is 64Kb. Four blocks // Each block is 64Kb. Four blocks
// one block erase takes 1s ( 1000ms ) // one block erase takes 1s ( 1000ms )
Flash_WriteEnable(); Flash_Erase64k(0); Flash_CheckBusy(BUSY_TIMEOUT); Flash_WriteEnable();
Flash_WriteEnable(); Flash_Erase64k(1); Flash_CheckBusy(BUSY_TIMEOUT); Flash_Erase64k(0);
Flash_WriteEnable(); Flash_Erase64k(2); Flash_CheckBusy(BUSY_TIMEOUT); Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable(); Flash_Erase64k(3); Flash_CheckBusy(BUSY_TIMEOUT); Flash_WriteEnable();
Flash_Erase64k(1);
Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable();
Flash_Erase64k(2);
Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable();
Flash_Erase64k(3);
Flash_CheckBusy(BUSY_TIMEOUT);
FlashStop(); FlashStop();
return true; return true;
} }
// enable the flash write // enable the flash write
void Flash_WriteEnable() { void Flash_WriteEnable()
{
FlashSendLastByte(WRITEENABLE); FlashSendLastByte(WRITEENABLE);
if (MF_DBGLEVEL > 3) Dbprintf("Flash Write enabled"); if (MF_DBGLEVEL > 3) Dbprintf("Flash Write enabled");
} }
// erase 4K at one time // erase 4K at one time
// execution time: 0.8ms / 800us // execution time: 0.8ms / 800us
bool Flash_Erase4k(uint8_t block, uint8_t sector) { bool Flash_Erase4k(uint8_t block, uint8_t sector)
{
if (block > MAX_BLOCKS || sector > MAX_SECTORS) return false; if (block > MAX_BLOCKS || sector > MAX_SECTORS) return false;
@ -487,7 +513,8 @@ bool Flash_Erase32k(uint32_t address) {
// 0x01 00 00 -- 0x 01 FF FF == block 1 // 0x01 00 00 -- 0x 01 FF FF == block 1
// 0x02 00 00 -- 0x 02 FF FF == block 2 // 0x02 00 00 -- 0x 02 FF FF == block 2
// 0x03 00 00 -- 0x 03 FF FF == block 3 // 0x03 00 00 -- 0x 03 FF FF == block 3
bool Flash_Erase64k(uint8_t block) { bool Flash_Erase64k(uint8_t block)
{
if (block > MAX_BLOCKS) return false; if (block > MAX_BLOCKS) return false;
@ -499,11 +526,13 @@ bool Flash_Erase64k(uint8_t block) {
} }
// Erase chip // Erase chip
void Flash_EraseChip(void) { void Flash_EraseChip(void)
{
FlashSendLastByte(CHIPERASE); FlashSendLastByte(CHIPERASE);
} }
void Flashmem_print_status(void) { void Flashmem_print_status(void)
{
DbpString("Flash memory"); DbpString("Flash memory");
Dbprintf(" Baudrate................%dMHz", FLASHMEM_SPIBAUDRATE / 1000000); Dbprintf(" Baudrate................%dMHz", FLASHMEM_SPIBAUDRATE / 1000000);

View file

@ -28,7 +28,8 @@ static uint32_t uncompressed_bytes_cnt;
// Used to write the FPGA config word // Used to write the FPGA config word
// May also be used to write to other SPI attached devices like an LCD // May also be used to write to other SPI attached devices like an LCD
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void DisableSpi(void) { static void DisableSpi(void)
{
//* Reset all the Chip Select register //* Reset all the Chip Select register
AT91C_BASE_SPI->SPI_CSR[0] = 0; AT91C_BASE_SPI->SPI_CSR[0] = 0;
AT91C_BASE_SPI->SPI_CSR[1] = 0; AT91C_BASE_SPI->SPI_CSR[1] = 0;
@ -45,7 +46,8 @@ static void DisableSpi(void) {
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS; AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS;
} }
void SetupSpi(int mode) { void SetupSpi(int mode)
{
// PA1 -> SPI_NCS3 chip select (MEM) // PA1 -> SPI_NCS3 chip select (MEM)
// PA10 -> SPI_NCS2 chip select (LCD) // PA10 -> SPI_NCS2 chip select (LCD)
// PA11 -> SPI_NCS0 chip select (FPGA) // PA11 -> SPI_NCS0 chip select (FPGA)
@ -118,7 +120,8 @@ void SetupSpi(int mode) {
// Set up the synchronous serial port, with the one set of options that we // Set up the synchronous serial port, with the one set of options that we
// always use when we are talking to the FPGA. Both RX and TX are enabled. // always use when we are talking to the FPGA. Both RX and TX are enabled.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void FpgaSetupSsc(void) { void FpgaSetupSsc(void)
{
// First configure the GPIOs, and get ourselves a clock. // First configure the GPIOs, and get ourselves a clock.
AT91C_BASE_PIOA->PIO_ASR = AT91C_BASE_PIOA->PIO_ASR =
GPIO_SSC_FRAME | GPIO_SSC_FRAME |
@ -156,7 +159,8 @@ void FpgaSetupSsc(void) {
// ourselves, not to another buffer). The stuff to manipulate those buffers // ourselves, not to another buffer). The stuff to manipulate those buffers
// is in apps.h, because it should be inlined, for speed. // is in apps.h, because it should be inlined, for speed.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool FpgaSetupSscDma(uint8_t *buf, int len) { bool FpgaSetupSscDma(uint8_t *buf, int len)
{
if (buf == NULL) return false; if (buf == NULL) return false;
FpgaDisableSscDma(); FpgaDisableSscDma();
@ -172,7 +176,8 @@ bool FpgaSetupSscDma(uint8_t *buf, int len) {
// Uncompress (inflate) the FPGA data. Returns one decompressed byte with // Uncompress (inflate) the FPGA data. Returns one decompressed byte with
// each call. // each call.
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8_t *output_buffer) { static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8_t *output_buffer)
{
if (fpga_image_ptr == compressed_fpga_stream->next_out) { // need more data if (fpga_image_ptr == compressed_fpga_stream->next_out) { // need more data
compressed_fpga_stream->next_out = output_buffer; compressed_fpga_stream->next_out = output_buffer;
compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN; compressed_fpga_stream->avail_out = OUTPUT_BUFFER_LEN;
@ -194,7 +199,8 @@ static int get_from_fpga_combined_stream(z_streamp compressed_fpga_stream, uint8
// are combined into one big file: // are combined into one big file:
// 288 bytes from FPGA file 1, followed by 288 bytes from FGPA file 2, etc. // 288 bytes from FPGA file 1, followed by 288 bytes from FGPA file 2, etc.
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static int get_from_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { static int get_from_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer)
{
while ((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % fpga_bitstream_num != (bitstream_version - 1)) { while ((uncompressed_bytes_cnt / FPGA_INTERLEAVE_SIZE) % fpga_bitstream_num != (bitstream_version - 1)) {
// skip undesired data belonging to other bitstream_versions // skip undesired data belonging to other bitstream_versions
get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer); get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
@ -203,19 +209,23 @@ static int get_from_fpga_stream(int bitstream_version, z_streamp compressed_fpga
return get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer); return get_from_fpga_combined_stream(compressed_fpga_stream, output_buffer);
} }
static voidpf fpga_inflate_malloc(voidpf opaque, uInt items, uInt size) { static voidpf fpga_inflate_malloc(voidpf opaque, uInt items, uInt size)
{
return BigBuf_malloc(items * size); return BigBuf_malloc(items * size);
} }
// free eventually allocated BigBuf memory // free eventually allocated BigBuf memory
static void fpga_inflate_free(voidpf opaque, voidpf address) { static void fpga_inflate_free(voidpf opaque, voidpf address)
BigBuf_free(); BigBuf_Clear_ext(false); {
BigBuf_free();
BigBuf_Clear_ext(false);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// Initialize decompression of the respective (HF or LF) FPGA stream // Initialize decompression of the respective (HF or LF) FPGA stream
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static bool reset_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { static bool reset_fpga_stream(int bitstream_version, z_streamp compressed_fpga_stream, uint8_t *output_buffer)
{
uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE]; uint8_t header[FPGA_BITSTREAM_FIXED_HEADER_SIZE];
uncompressed_bytes_cnt = 0; uncompressed_bytes_cnt = 0;
@ -242,7 +252,8 @@ static bool reset_fpga_stream(int bitstream_version, z_streamp compressed_fpga_s
return false; return false;
} }
static void DownloadFPGA_byte( uint8_t w) { static void DownloadFPGA_byte(uint8_t w)
{
#define SEND_BIT(x) { if(w & (1<<x) ) HIGH(GPIO_FPGA_DIN); else LOW(GPIO_FPGA_DIN); HIGH(GPIO_FPGA_CCLK); LOW(GPIO_FPGA_CCLK); } #define SEND_BIT(x) { if(w & (1<<x) ) HIGH(GPIO_FPGA_DIN); else LOW(GPIO_FPGA_DIN); HIGH(GPIO_FPGA_CCLK); LOW(GPIO_FPGA_CCLK); }
SEND_BIT(7); SEND_BIT(7);
SEND_BIT(6); SEND_BIT(6);
@ -255,7 +266,8 @@ static void DownloadFPGA_byte( uint8_t w) {
} }
// Download the fpga image starting at current stream position with length FpgaImageLen bytes // Download the fpga image starting at current stream position with length FpgaImageLen bytes
static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp compressed_fpga_stream, uint8_t *output_buffer)
{
int i = 0; int i = 0;
AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON; AT91C_BASE_PIOA->PIO_OER = GPIO_FPGA_ON;
@ -337,7 +349,8 @@ static void DownloadFPGA(int bitstream_version, int FpgaImageLen, z_streamp comp
* (big endian), <length> bytes content. Except for section 'e' which has 4 bytes * (big endian), <length> bytes content. Except for section 'e' which has 4 bytes
* length. * length.
*/ */
static int bitparse_find_section(int bitstream_version, char section_name, uint32_t *section_length, z_streamp compressed_fpga_stream, uint8_t *output_buffer) { static int bitparse_find_section(int bitstream_version, char section_name, uint32_t *section_length, z_streamp compressed_fpga_stream, uint8_t *output_buffer)
{
int result = 0; int result = 0;
#define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section #define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section
uint16_t numbytes = 0; uint16_t numbytes = 0;
@ -386,7 +399,8 @@ static int bitparse_find_section(int bitstream_version, char section_name, uint3
// Check which FPGA image is currently loaded (if any). If necessary // Check which FPGA image is currently loaded (if any). If necessary
// decompress and load the correct (HF or LF) image to the FPGA // decompress and load the correct (HF or LF) image to the FPGA
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void FpgaDownloadAndGo(int bitstream_version) { void FpgaDownloadAndGo(int bitstream_version)
{
// check whether or not the bitstream is already loaded // check whether or not the bitstream is already loaded
if (downloaded_bitstream == bitstream_version) if (downloaded_bitstream == bitstream_version)
@ -398,7 +412,8 @@ void FpgaDownloadAndGo(int bitstream_version) {
bool verbose = (MF_DBGLEVEL > 3); bool verbose = (MF_DBGLEVEL > 3);
// make sure that we have enough memory to decompress // make sure that we have enough memory to decompress
BigBuf_free(); BigBuf_Clear_ext(verbose); BigBuf_free();
BigBuf_Clear_ext(verbose);
if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer)) if (!reset_fpga_stream(bitstream_version, &compressed_fpga_stream, output_buffer))
return; return;
@ -415,7 +430,8 @@ void FpgaDownloadAndGo(int bitstream_version) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
// free eventually allocated BigBuf memory // free eventually allocated BigBuf memory
BigBuf_free(); BigBuf_Clear_ext(false); BigBuf_free();
BigBuf_Clear_ext(false);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -423,7 +439,8 @@ void FpgaDownloadAndGo(int bitstream_version) {
// The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0 // The bit format is: C3 C2 C1 C0 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0
// where C is the 4 bit command and D is the 12 bit data // where C is the 4 bit command and D is the 12 bit data
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void FpgaSendCommand(uint16_t cmd, uint16_t v) { void FpgaSendCommand(uint16_t cmd, uint16_t v)
{
SetupSpi(SPI_FPGA_MODE); SetupSpi(SPI_FPGA_MODE);
while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // wait for the transfer to complete while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0); // wait for the transfer to complete
AT91C_BASE_SPI->SPI_TDR = AT91C_SPI_LASTXFER | cmd | v; // send the data AT91C_BASE_SPI->SPI_TDR = AT91C_SPI_LASTXFER | cmd | v; // send the data
@ -434,7 +451,8 @@ void FpgaSendCommand(uint16_t cmd, uint16_t v) {
// vs. clone vs. etc.). This is now a special case of FpgaSendCommand() to // vs. clone vs. etc.). This is now a special case of FpgaSendCommand() to
// avoid changing this function's occurence everywhere in the source code. // avoid changing this function's occurence everywhere in the source code.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void FpgaWriteConfWord(uint8_t v) { void FpgaWriteConfWord(uint8_t v)
{
FpgaSendCommand(FPGA_CMD_SET_CONFREG, v); FpgaSendCommand(FPGA_CMD_SET_CONFREG, v);
} }
@ -443,7 +461,8 @@ void FpgaWriteConfWord(uint8_t v) {
// closable, but should only close one at a time. Not an FPGA thing, but // closable, but should only close one at a time. Not an FPGA thing, but
// the samples from the ADC always flow through the FPGA. // the samples from the ADC always flow through the FPGA.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void SetAdcMuxFor(uint32_t whichGpio) { void SetAdcMuxFor(uint32_t whichGpio)
{
AT91C_BASE_PIOA->PIO_OER = AT91C_BASE_PIOA->PIO_OER =
GPIO_MUXSEL_HIPKD | GPIO_MUXSEL_HIPKD |
GPIO_MUXSEL_LOPKD | GPIO_MUXSEL_LOPKD |
@ -466,12 +485,14 @@ void SetAdcMuxFor(uint32_t whichGpio) {
HIGH(whichGpio); HIGH(whichGpio);
} }
void Fpga_print_status(void) { void Fpga_print_status(void)
{
Dbprintf("Currently loaded FPGA image"); Dbprintf("Currently loaded FPGA image");
Dbprintf(" mode....................%s", fpga_version_information[downloaded_bitstream - 1]); Dbprintf(" mode....................%s", fpga_version_information[downloaded_bitstream - 1]);
} }
int FpgaGetCurrent(void) { int FpgaGetCurrent(void)
{
return downloaded_bitstream; return downloaded_bitstream;
} }
@ -479,7 +500,8 @@ int FpgaGetCurrent(void) {
// log message // log message
// if HF, Disable SSC DMA // if HF, Disable SSC DMA
// turn off trace and leds off. // turn off trace and leds off.
void switch_off(void) { void switch_off(void)
{
if (MF_DBGLEVEL > 3) Dbprintf("switch_off"); if (MF_DBGLEVEL > 3) Dbprintf("switch_off");
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
if (downloaded_bitstream == FPGA_BITSTREAM_HF) if (downloaded_bitstream == FPGA_BITSTREAM_HF)

View file

@ -26,7 +26,8 @@ static void RAMFUNC optimizedSnoop(void)
void HfSnoop(int samplesToSkip, int triggersToSkip) void HfSnoop(int samplesToSkip, int triggersToSkip)
{ {
BigBuf_free(); BigBuf_Clear(); BigBuf_free();
BigBuf_Clear();
Dbprintf("Skipping first %d sample pairs, Skipping %d triggers.\n", samplesToSkip, triggersToSkip); Dbprintf("Skipping first %d sample pairs, Skipping %d triggers.\n", samplesToSkip, triggersToSkip);
int trigger_cnt = 0; int trigger_cnt = 0;

View file

@ -126,8 +126,7 @@ static u64 _hitag2_init (const u64 key, const u32 serial, const u32 IV)
u32 i; u32 i;
u64 x = ((key & 0xFFFF) << 32) + serial; u64 x = ((key & 0xFFFF) << 32) + serial;
for (i = 0; i < 32; i++) for (i = 0; i < 32; i++) {
{
x >>= 1; x >>= 1;
x += (u64)(_f20(x) ^ (((IV >> i) ^ (key >> (i + 16))) & 1)) << 47; x += (u64)(_f20(x) ^ (((IV >> i) ^ (key >> (i + 16))) & 1)) << 47;
} }
@ -166,13 +165,15 @@ static u32 _hitag2_byte (u64 * x)
return c; return c;
} }
static int hitag2_reset(void) { static int hitag2_reset(void)
{
tag.state = TAG_STATE_RESET; tag.state = TAG_STATE_RESET;
tag.crypto_active = 0; tag.crypto_active = 0;
return 0; return 0;
} }
static int hitag2_init(void) { static int hitag2_init(void)
{
hitag2_reset(); hitag2_reset();
return 0; return 0;
} }
@ -249,7 +250,8 @@ static int hitag2_cipher_transcrypt(uint64_t* cs, uint8_t *data, unsigned int by
#define HITAG_T_TAG_CAPTURE_FOUR_HALF 57 #define HITAG_T_TAG_CAPTURE_FOUR_HALF 57
static void hitag_send_bit(int bit) { static void hitag_send_bit(int bit)
{
LED_A_ON(); LED_A_ON();
// Reset clock for the next bit // Reset clock for the next bit
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
@ -415,7 +417,8 @@ static void hitag2_handle_reader_command(uint8_t* rx, const size_t rxlen, uint8_
} }
} }
static void hitag_reader_send_bit(int bit) { static void hitag_reader_send_bit(int bit)
{
LED_A_ON(); LED_A_ON();
// Reset clock for the next bit // Reset clock for the next bit
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
@ -463,7 +466,8 @@ static void hitag_reader_send_frame(const uint8_t* frame, size_t frame_len)
size_t blocknr; size_t blocknr;
static bool hitag2_password(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen) { static bool hitag2_password(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen)
{
// Reset the transmission frame length // Reset the transmission frame length
*txlen = 0; *txlen = 0;
@ -478,7 +482,8 @@ static bool hitag2_password(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t
} }
*txlen = 5; *txlen = 5;
memcpy(tx, "\xc0", nbytes(*txlen)); memcpy(tx, "\xc0", nbytes(*txlen));
} break; }
break;
// Received UID, tag password // Received UID, tag password
case 32: { case 32: {
@ -507,13 +512,15 @@ static bool hitag2_password(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t
tx[0] = 0xc0 | (blocknr << 3) | ((blocknr ^ 7) >> 2); tx[0] = 0xc0 | (blocknr << 3) | ((blocknr ^ 7) >> 2);
tx[1] = ((blocknr ^ 7) << 6); tx[1] = ((blocknr ^ 7) << 6);
} }
} break; }
break;
// Unexpected response // Unexpected response
default: { default: {
Dbprintf("Uknown frame length: %d", rxlen); Dbprintf("Uknown frame length: %d", rxlen);
return false; return false;
} break; }
break;
} }
return true; return true;
} }
@ -560,7 +567,8 @@ static bool hitag2_write_page(uint8_t* rx, const size_t rxlen, uint8_t* tx, size
return true; return true;
} }
static bool hitag2_crypto(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen, bool write) { static bool hitag2_crypto(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen, bool write)
{
// Reset the transmission frame length // Reset the transmission frame length
*txlen = 0; *txlen = 0;
@ -646,13 +654,15 @@ static bool hitag2_crypto(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t*
tx[1] = ((blocknr ^ 7) << 6); tx[1] = ((blocknr ^ 7) << 6);
} }
} }
} break; }
break;
// Unexpected response // Unexpected response
default: { default: {
Dbprintf("Uknown frame length: %d", rxlen); Dbprintf("Uknown frame length: %d", rxlen);
return false; return false;
} break; }
break;
} }
} }
@ -667,7 +677,8 @@ static bool hitag2_crypto(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t*
} }
static bool hitag2_authenticate(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen) { static bool hitag2_authenticate(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen)
{
// Reset the transmission frame length // Reset the transmission frame length
*txlen = 0; *txlen = 0;
@ -682,7 +693,8 @@ static bool hitag2_authenticate(uint8_t* rx, const size_t rxlen, uint8_t* tx, si
} }
*txlen = 5; *txlen = 5;
memcpy(tx, "\xc0", nbytes(*txlen)); memcpy(tx, "\xc0", nbytes(*txlen));
} break; }
break;
// Received UID, crypto tag answer // Received UID, crypto tag answer
case 32: { case 32: {
@ -694,20 +706,23 @@ static bool hitag2_authenticate(uint8_t* rx, const size_t rxlen, uint8_t* tx, si
DbpString("Authentication succesful!"); DbpString("Authentication succesful!");
return true; return true;
} }
} break; }
break;
// Unexpected response // Unexpected response
default: { default: {
Dbprintf("Uknown frame length: %d", rxlen); Dbprintf("Uknown frame length: %d", rxlen);
return false; return false;
} break; }
break;
} }
return true; return true;
} }
static bool hitag2_test_auth_attempts(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen) { static bool hitag2_test_auth_attempts(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen)
{
// Reset the transmission frame length // Reset the transmission frame length
*txlen = 0; *txlen = 0;
@ -735,7 +750,8 @@ static bool hitag2_test_auth_attempts(uint8_t* rx, const size_t rxlen, uint8_t*
} }
*txlen = 5; *txlen = 5;
memcpy(tx, "\xc0", nbytes(*txlen)); memcpy(tx, "\xc0", nbytes(*txlen));
} break; }
break;
// Received UID, crypto tag answer, or read block response // Received UID, crypto tag answer, or read block response
case 32: { case 32: {
@ -752,18 +768,21 @@ static bool hitag2_test_auth_attempts(uint8_t* rx, const size_t rxlen, uint8_t*
auth_table_pos += 8; auth_table_pos += 8;
memcpy(NrAr, auth_table + auth_table_pos, 8); memcpy(NrAr, auth_table + auth_table_pos, 8);
} }
} break; }
break;
default: { default: {
Dbprintf("Uknown frame length: %d", rxlen); Dbprintf("Uknown frame length: %d", rxlen);
return false; return false;
} break; }
break;
} }
return true; return true;
} }
static bool hitag2_read_uid(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t* txlen) { static bool hitag2_read_uid(uint8_t *rx, const size_t rxlen, uint8_t *tx, size_t *txlen)
{
// Reset the transmission frame length // Reset the transmission frame length
*txlen = 0; *txlen = 0;
@ -774,7 +793,8 @@ static bool hitag2_read_uid(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t
// Just starting or if there is no answer // Just starting or if there is no answer
*txlen = 5; *txlen = 5;
memcpy(tx, "\xC0", nbytes(*txlen)); memcpy(tx, "\xC0", nbytes(*txlen));
} break; }
break;
// Received UID // Received UID
case 32: { case 32: {
// Check if we received answer tag (at) // Check if we received answer tag (at)
@ -790,17 +810,20 @@ static bool hitag2_read_uid(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t
bSuccessful = true; bSuccessful = true;
return false; return false;
} }
} break; }
break;
// Unexpected response // Unexpected response
default: { default: {
Dbprintf("Uknown frame length: %d", rxlen); Dbprintf("Uknown frame length: %d", rxlen);
return false; return false;
} break; }
break;
} }
return true; return true;
} }
void SnoopHitag(uint32_t type) { void SnoopHitag(uint32_t type)
{
int frame_count; int frame_count;
int response; int response;
int overflow; int overflow;
@ -815,7 +838,8 @@ void SnoopHitag(uint32_t type) {
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
// free eventually allocated BigBuf memory // free eventually allocated BigBuf memory
BigBuf_free(); BigBuf_Clear_ext(false); BigBuf_free();
BigBuf_Clear_ext(false);
// Clean up trace and prepare it for storing frames // Clean up trace and prepare it for storing frames
clear_trace(); clear_trace();
@ -1017,7 +1041,8 @@ void SnoopHitag(uint32_t type) {
// DbpString("All done"); // DbpString("All done");
} }
void SimulateHitagTag(bool tag_mem_supplied, uint8_t* data) { void SimulateHitagTag(bool tag_mem_supplied, uint8_t *data)
{
int frame_count; int frame_count;
int response; int response;
int overflow; int overflow;
@ -1031,7 +1056,8 @@ void SimulateHitagTag(bool tag_mem_supplied, uint8_t* data) {
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
// free eventually allocated BigBuf memory // free eventually allocated BigBuf memory
BigBuf_free(); BigBuf_Clear_ext(false); BigBuf_free();
BigBuf_Clear_ext(false);
// Clean up trace and prepare it for storing frames // Clean up trace and prepare it for storing frames
clear_trace(); clear_trace();
@ -1207,7 +1233,8 @@ void SimulateHitagTag(bool tag_mem_supplied, uint8_t* data) {
set_tracing(false); set_tracing(false);
} }
void ReaderHitag(hitag_function htf, hitag_data* htd) { void ReaderHitag(hitag_function htf, hitag_data *htd)
{
int frame_count = 0; int frame_count = 0;
int response = 0; int response = 0;
uint8_t rx[HITAG_FRAME_LEN]; uint8_t rx[HITAG_FRAME_LEN];
@ -1242,7 +1269,8 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
bQuitTraceFull = false; bQuitTraceFull = false;
bQuiet = false; bQuiet = false;
bPwd = false; bPwd = false;
} break; }
break;
case RHT2F_AUTHENTICATE: { case RHT2F_AUTHENTICATE: {
DbpString("Authenticating using nr,ar pair:"); DbpString("Authenticating using nr,ar pair:");
@ -1252,7 +1280,8 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
bCrypto = false; bCrypto = false;
bAuthenticating = false; bAuthenticating = false;
bQuitTraceFull = true; bQuitTraceFull = true;
} break; }
break;
case RHT2F_CRYPTO: { case RHT2F_CRYPTO: {
DbpString("Authenticating using key:"); DbpString("Authenticating using key:");
@ -1263,7 +1292,8 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
bCrypto = false; bCrypto = false;
bAuthenticating = false; bAuthenticating = false;
bQuitTraceFull = true; bQuitTraceFull = true;
} break; }
break;
case RHT2F_TEST_AUTH_ATTEMPTS: { case RHT2F_TEST_AUTH_ATTEMPTS: {
Dbprintf("Testing %d authentication attempts", (auth_table_len / 8)); Dbprintf("Testing %d authentication attempts", (auth_table_len / 8));
@ -1272,19 +1302,22 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
bQuitTraceFull = false; bQuitTraceFull = false;
bQuiet = false; bQuiet = false;
bCrypto = false; bCrypto = false;
} break; }
break;
case RHT2F_UID_ONLY: { case RHT2F_UID_ONLY: {
blocknr = 0; blocknr = 0;
bQuiet = false; bQuiet = false;
bCrypto = false; bCrypto = false;
bAuthenticating = false; bAuthenticating = false;
bQuitTraceFull = true; bQuitTraceFull = true;
} break; }
break;
default: { default: {
Dbprintf("Error, unknown function: %d", htf); Dbprintf("Error, unknown function: %d", htf);
set_tracing(false); set_tracing(false);
return; return;
} break; }
break;
} }
LED_D_ON(); LED_D_ON();
@ -1373,28 +1406,34 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
switch (htf) { switch (htf) {
case RHT2F_PASSWORD: { case RHT2F_PASSWORD: {
bStop = !hitag2_password(rx, rxlen, tx, &txlen); bStop = !hitag2_password(rx, rxlen, tx, &txlen);
} break; }
break;
case RHT2F_AUTHENTICATE: { case RHT2F_AUTHENTICATE: {
bStop = !hitag2_authenticate(rx, rxlen, tx, &txlen); bStop = !hitag2_authenticate(rx, rxlen, tx, &txlen);
} break; }
break;
case RHT2F_CRYPTO: { case RHT2F_CRYPTO: {
bStop = !hitag2_crypto(rx, rxlen, tx, &txlen, false); bStop = !hitag2_crypto(rx, rxlen, tx, &txlen, false);
} break; }
break;
case RHT2F_TEST_AUTH_ATTEMPTS: { case RHT2F_TEST_AUTH_ATTEMPTS: {
bStop = !hitag2_test_auth_attempts(rx, rxlen, tx, &txlen); bStop = !hitag2_test_auth_attempts(rx, rxlen, tx, &txlen);
} break; }
break;
case RHT2F_UID_ONLY: { case RHT2F_UID_ONLY: {
bStop = !hitag2_read_uid(rx, rxlen, tx, &txlen); bStop = !hitag2_read_uid(rx, rxlen, tx, &txlen);
attempt_count++; //attempt 3 times to get uid then quit attempt_count++; //attempt 3 times to get uid then quit
if (!bStop && attempt_count == 3) if (!bStop && attempt_count == 3)
bStop = true; bStop = true;
} break; }
break;
default: { default: {
Dbprintf("Error, unknown function: %d", htf); Dbprintf("Error, unknown function: %d", htf);
set_tracing(false); set_tracing(false);
LED_D_OFF(); LED_D_OFF();
return; return;
} break; }
break;
} }
// Send and store the reader command // Send and store the reader command
@ -1509,7 +1548,8 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
cmd_send(CMD_ACK, bSuccessful, 0, 0, 0, 0); cmd_send(CMD_ACK, bSuccessful, 0, 0, 0, 0);
} }
void WriterHitag(hitag_function htf, hitag_data* htd, int page) { void WriterHitag(hitag_function htf, hitag_data *htd, int page)
{
int frame_count; int frame_count;
int response; int response;
uint8_t rx[HITAG_FRAME_LEN]; uint8_t rx[HITAG_FRAME_LEN];
@ -1548,11 +1588,13 @@ void WriterHitag(hitag_function htf, hitag_data* htd, int page) {
bAuthenticating = false; bAuthenticating = false;
bQuitTraceFull = true; bQuitTraceFull = true;
writestate = WRITE_STATE_START; writestate = WRITE_STATE_START;
} break; }
break;
default: { default: {
Dbprintf("Error, unknown function: %d", htf); Dbprintf("Error, unknown function: %d", htf);
return; return;
} break; }
break;
} }
LED_D_ON(); LED_D_ON();
@ -1644,11 +1686,13 @@ void WriterHitag(hitag_function htf, hitag_data* htd, int page) {
switch (htf) { switch (htf) {
case WHT2F_CRYPTO: { case WHT2F_CRYPTO: {
bStop = !hitag2_crypto(rx, rxlen, tx, &txlen, true); bStop = !hitag2_crypto(rx, rxlen, tx, &txlen, true);
} break; }
break;
default: { default: {
Dbprintf("Error, unknown function: %d", htf); Dbprintf("Error, unknown function: %d", htf);
return; return;
} break; }
break;
} }
// Send and store the reader command // Send and store the reader command
@ -1772,8 +1816,7 @@ void WriterHitag(hitag_function htf, hitag_data* htd, int page) {
} }
// Wait some extra time for flash to be programmed // Wait some extra time for flash to be programmed
if ((rxlen == 0) && (writestate == WRITE_STATE_PROG)) if ((rxlen == 0) && (writestate == WRITE_STATE_PROG)) {
{
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
while (AT91C_BASE_TC0->TC_CV < T0 * (HITAG_T_PROG - HITAG_T_WAIT_MAX)); while (AT91C_BASE_TC0->TC_CV < T0 * (HITAG_T_PROG - HITAG_T_WAIT_MAX));
} }

View file

@ -65,7 +65,8 @@ static const u32 ht2_f5c = 0x7907287B; // 0111 1001 0000 0111 0010 1000 0
#define ht2bs_5c(a,b,c,d,e) (~((((((c^e)|d)&a)^b)&(c^b))^(((d^e)|a)&((d^b)|c)))) #define ht2bs_5c(a,b,c,d,e) (~((((((c^e)|d)&a)^b)&(c^b))^(((d^e)|a)&((d^b)|c))))
#define uf20bs u32 #define uf20bs u32
static u32 f20(const u64 x) { static u32 f20(const u64 x)
{
u32 i5; u32 i5;
i5 = ((ht2_f4a >> i4(x, 1, 2, 4, 5)) & 1) * 1 i5 = ((ht2_f4a >> i4(x, 1, 2, 4, 5)) & 1) * 1
@ -76,7 +77,8 @@ static u32 f20(const u64 x) {
return (ht2_f5c >> i5) & 1; return (ht2_f5c >> i5) & 1;
} }
static u64 hitag2_round(u64 *state) { static u64 hitag2_round(u64 *state)
{
u64 x = *state; u64 x = *state;
x = (x >> 1) x = (x >> 1)
@ -88,7 +90,8 @@ static u64 hitag2_round(u64 *state) {
*state = x; *state = x;
return f20(x); return f20(x);
} }
static u64 hitag2_init(const u64 key, const u32 serial, const u32 IV) { static u64 hitag2_init(const u64 key, const u32 serial, const u32 IV)
{
u32 i; u32 i;
u64 x = ((key & 0xFFFF) << 32) + serial; u64 x = ((key & 0xFFFF) << 32) + serial;
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
@ -97,7 +100,8 @@ static u64 hitag2_init(const u64 key, const u32 serial, const u32 IV) {
} }
return x; return x;
} }
static u32 hitag2_byte(u64 *x) { static u32 hitag2_byte(u64 *x)
{
u32 i, c; u32 i, c;
for (i = 0, c = 0; i < 8; i++) for (i = 0, c = 0; i < 8; i++)
@ -144,11 +148,11 @@ static u32 hitag2_byte(u64 *x) {
* Implementation of the crc8 calculation from Hitag S * Implementation of the crc8 calculation from Hitag S
* from http://www.proxmark.org/files/Documents/125%20kHz%20-%20Hitag/HitagS.V11.pdf * from http://www.proxmark.org/files/Documents/125%20kHz%20-%20Hitag/HitagS.V11.pdf
*/ */
void calc_crc(unsigned char * crc, unsigned char data, unsigned char Bitcount) { void calc_crc(unsigned char *crc, unsigned char data, unsigned char Bitcount)
{
*crc ^= data; // crc = crc (exor) data *crc ^= data; // crc = crc (exor) data
do { do {
if (*crc & 0x80) // if (MSB-CRC == 1) if (*crc & 0x80) { // if (MSB-CRC == 1)
{
*crc <<= 1; // CRC = CRC Bit-shift left *crc <<= 1; // CRC = CRC Bit-shift left
*crc ^= CRC_POLYNOM; // CRC = CRC (exor) CRC_POLYNOM *crc ^= CRC_POLYNOM; // CRC = CRC (exor) CRC_POLYNOM
} else { } else {
@ -157,7 +161,8 @@ void calc_crc(unsigned char * crc, unsigned char data, unsigned char Bitcount) {
} while (--Bitcount); } while (--Bitcount);
} }
static void hitag_send_bit(int bit) { static void hitag_send_bit(int bit)
{
LED_A_ON(); LED_A_ON();
// Reset clock for the next bit // Reset clock for the next bit
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG; AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
@ -259,7 +264,8 @@ static void hitag_send_bit(int bit) {
} }
} }
static void hitag_send_frame(const byte_t* frame, size_t frame_len) { static void hitag_send_frame(const byte_t *frame, size_t frame_len)
{
// Send start of frame // Send start of frame
for (size_t i = 0; i < sof_bits; i++) { for (size_t i = 0; i < sof_bits; i++) {
@ -274,7 +280,8 @@ static void hitag_send_frame(const byte_t* frame, size_t frame_len) {
LOW(GPIO_SSC_DOUT); LOW(GPIO_SSC_DOUT);
} }
static void hitag_reader_send_bit(int bit) { static void hitag_reader_send_bit(int bit)
{
//Dbprintf("BIT: %d",bit); //Dbprintf("BIT: %d",bit);
LED_A_ON(); LED_A_ON();
// Reset clock for the next bit // Reset clock for the next bit
@ -330,7 +337,8 @@ static void hitag_reader_send_bit(int bit) {
LED_A_OFF(); LED_A_OFF();
} }
static void hitag_reader_send_frame(const byte_t* frame, size_t frame_len) { static void hitag_reader_send_frame(const byte_t *frame, size_t frame_len)
{
// Send the content of the frame // Send the content of the frame
for (size_t i = 0; i < frame_len; i++) { for (size_t i = 0; i < frame_len; i++) {
if (frame[0] == 0xf8) { if (frame[0] == 0xf8) {
@ -352,7 +360,8 @@ static void hitag_reader_send_frame(const byte_t* frame, size_t frame_len) {
/* /*
* to check if the right uid was selected * to check if the right uid was selected
*/ */
static int check_select(byte_t* rx, uint32_t uid) { static int check_select(byte_t *rx, uint32_t uid)
{
unsigned char resp[48]; unsigned char resp[48];
int i; int i;
uint32_t ans = 0x0; uint32_t ans = 0x0;
@ -373,7 +382,8 @@ static int check_select(byte_t* rx, uint32_t uid) {
* handles all commands from a reader * handles all commands from a reader
*/ */
static void hitagS_handle_reader_command(byte_t *rx, const size_t rxlen, static void hitagS_handle_reader_command(byte_t *rx, const size_t rxlen,
byte_t* tx, size_t* txlen) { byte_t *tx, size_t *txlen)
{
byte_t rx_air[HITAG_FRAME_LEN]; byte_t rx_air[HITAG_FRAME_LEN];
byte_t page; byte_t page;
int i; int i;
@ -565,8 +575,7 @@ static void hitagS_handle_reader_command(byte_t* rx, const size_t rxlen,
break; break;
case 20: { case 20: {
//write page, write block, read page or read block command received //write page, write block, read page or read block command received
if ((rx[0] & 0xf0) == 0xc0) //read page if ((rx[0] & 0xf0) == 0xc0) { //read page
{
//send page data //send page data
page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16); page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16);
*txlen = 32; *txlen = 32;
@ -608,8 +617,7 @@ static void hitagS_handle_reader_command(byte_t* rx, const size_t rxlen,
sof_bits = 0; sof_bits = 0;
*txlen = 0; *txlen = 0;
} }
} else if ((rx[0] & 0xf0) == 0xd0) //read block } else if ((rx[0] & 0xf0) == 0xd0) { //read block
{
page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16); page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16);
*txlen = 32 * 4; *txlen = 32 * 4;
//send page,...,page+3 data //send page,...,page+3 data
@ -651,8 +659,7 @@ static void hitagS_handle_reader_command(byte_t* rx, const size_t rxlen,
sof_bits = 0; sof_bits = 0;
*txlen = 0; *txlen = 0;
} }
} else if ((rx[0] & 0xf0) == 0x80) //write page } else if ((rx[0] & 0xf0) == 0x80) { //write page
{
page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16); page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16);
switch (tag.mode) { switch (tag.mode) {
@ -683,8 +690,7 @@ static void hitagS_handle_reader_command(byte_t* rx, const size_t rxlen,
tag.tstate = HT_WRITING_PAGE_DATA; tag.tstate = HT_WRITING_PAGE_DATA;
} }
} else if ((rx[0] & 0xf0) == 0x90) //write block } else if ((rx[0] & 0xf0) == 0x90) { //write block
{
page = ((rx[0] & 0x0f) * 6) + ((rx[1] & 0xf0) / 16); page = ((rx[0] & 0x0f) * 6) + ((rx[1] & 0xf0) / 16);
switch (tag.mode) { switch (tag.mode) {
case HT_STANDARD: case HT_STANDARD:
@ -726,7 +732,8 @@ static void hitagS_handle_reader_command(byte_t* rx, const size_t rxlen,
* to autenticate to a tag with the given key or challenge * to autenticate to a tag with the given key or challenge
*/ */
static int hitagS_handle_tag_auth(hitag_function htf, uint64_t key, uint64_t NrAr, byte_t *rx, const size_t rxlen, byte_t *tx, static int hitagS_handle_tag_auth(hitag_function htf, uint64_t key, uint64_t NrAr, byte_t *rx, const size_t rxlen, byte_t *tx,
size_t* txlen) { size_t *txlen)
{
byte_t rx_air[HITAG_FRAME_LEN]; byte_t rx_air[HITAG_FRAME_LEN];
int response_bit[200]; int response_bit[200];
int i, j, z, k; int i, j, z, k;
@ -938,7 +945,8 @@ static int hitagS_handle_tag_auth(hitag_function htf,uint64_t key, uint64_t NrAr
/* /*
* Emulates a Hitag S Tag with the given data from the .hts file * Emulates a Hitag S Tag with the given data from the .hts file
*/ */
void SimulateHitagSTag(bool tag_mem_supplied, byte_t* data) { void SimulateHitagSTag(bool tag_mem_supplied, byte_t *data)
{
int frame_count; int frame_count;
int response; int response;
int overflow; int overflow;
@ -951,7 +959,8 @@ void SimulateHitagSTag(bool tag_mem_supplied, byte_t* data) {
byte_t *tx = txbuf; byte_t *tx = txbuf;
size_t txlen = 0; size_t txlen = 0;
// free eventually allocated BigBuf memory // free eventually allocated BigBuf memory
BigBuf_free(); BigBuf_Clear_ext(false); BigBuf_free();
BigBuf_Clear_ext(false);
// Clean up trace and prepare it for storing frames // Clean up trace and prepare it for storing frames
set_tracing(true); set_tracing(true);
@ -1163,7 +1172,8 @@ void SimulateHitagSTag(bool tag_mem_supplied, byte_t* data) {
* If the key was given the password will be decrypted. * If the key was given the password will be decrypted.
* Reads every page of a hitag S transpoder. * Reads every page of a hitag S transpoder.
*/ */
void ReadHitagS(hitag_function htf, hitag_data* htd) { void ReadHitagS(hitag_function htf, hitag_data *htd)
{
int i, j, z, k; int i, j, z, k;
int frame_count; int frame_count;
int response_bit[200]; int response_bit[200];
@ -1198,17 +1208,20 @@ void ReadHitagS(hitag_function htf, hitag_data* htd) {
Dbhexdump(8, NrAr_, false); Dbhexdump(8, NrAr_, false);
NrAr = NrAr_[7] | ((uint64_t)NrAr_[6]) << 8 | ((uint64_t)NrAr_[5]) << 16 | ((uint64_t)NrAr_[4]) << 24 | ((uint64_t)NrAr_[3]) << 32 | NrAr = NrAr_[7] | ((uint64_t)NrAr_[6]) << 8 | ((uint64_t)NrAr_[5]) << 16 | ((uint64_t)NrAr_[4]) << 24 | ((uint64_t)NrAr_[3]) << 32 |
((uint64_t)NrAr_[2]) << 40 | ((uint64_t)NrAr_[1]) << 48 | ((uint64_t)NrAr_[0]) << 56; ((uint64_t)NrAr_[2]) << 40 | ((uint64_t)NrAr_[1]) << 48 | ((uint64_t)NrAr_[0]) << 56;
} break; }
break;
case 02: { //RHTS_KEY case 02: { //RHTS_KEY
DbpString("Authenticating using key:"); DbpString("Authenticating using key:");
memcpy(key_, htd->crypto.key, 6); memcpy(key_, htd->crypto.key, 6);
Dbhexdump(6, key_, false); Dbhexdump(6, key_, false);
key = key_[5] | ((uint64_t)key_[4]) << 8 | ((uint64_t)key_[3]) << 16 | ((uint64_t)key_[2]) << 24 | ((uint64_t)key_[1]) << 32 | ((uint64_t)key_[0]) << 40; key = key_[5] | ((uint64_t)key_[4]) << 8 | ((uint64_t)key_[3]) << 16 | ((uint64_t)key_[2]) << 24 | ((uint64_t)key_[1]) << 32 | ((uint64_t)key_[0]) << 40;
} break; }
break;
default: { default: {
Dbprintf("Error , unknown function: %d", htf); Dbprintf("Error , unknown function: %d", htf);
return; return;
} break; }
break;
} }
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
@ -1505,7 +1518,8 @@ void ReadHitagS(hitag_function htf, hitag_data* htd) {
* Authenticates to the Tag with the given Key or Challenge. * Authenticates to the Tag with the given Key or Challenge.
* Writes the given 32Bit data into page_ * Writes the given 32Bit data into page_
*/ */
void WritePageHitagS(hitag_function htf, hitag_data* htd,int page_) { void WritePageHitagS(hitag_function htf, hitag_data *htd, int page_)
{
int frame_count; int frame_count;
int response; int response;
byte_t rx[HITAG_FRAME_LEN]; byte_t rx[HITAG_FRAME_LEN];
@ -1537,18 +1551,21 @@ void WritePageHitagS(hitag_function htf, hitag_data* htd,int page_) {
Dbhexdump(8, NrAr_, false); Dbhexdump(8, NrAr_, false);
NrAr = NrAr_[7] | ((uint64_t)NrAr_[6]) << 8 | ((uint64_t)NrAr_[5]) << 16 | ((uint64_t)NrAr_[4]) << 24 | ((uint64_t)NrAr_[3]) << 32 | NrAr = NrAr_[7] | ((uint64_t)NrAr_[6]) << 8 | ((uint64_t)NrAr_[5]) << 16 | ((uint64_t)NrAr_[4]) << 24 | ((uint64_t)NrAr_[3]) << 32 |
((uint64_t)NrAr_[2]) << 40 | ((uint64_t)NrAr_[1]) << 48 | ((uint64_t)NrAr_[0]) << 56; ((uint64_t)NrAr_[2]) << 40 | ((uint64_t)NrAr_[1]) << 48 | ((uint64_t)NrAr_[0]) << 56;
} break; }
break;
case 04: { //WHTS_KEY case 04: { //WHTS_KEY
memcpy(data, htd->crypto.data, 4); memcpy(data, htd->crypto.data, 4);
DbpString("Authenticating using key:"); DbpString("Authenticating using key:");
memcpy(key_, htd->crypto.key, 6); memcpy(key_, htd->crypto.key, 6);
Dbhexdump(6, key_, false); Dbhexdump(6, key_, false);
key = key_[5] | ((uint64_t)key_[4]) << 8 | ((uint64_t)key_[3]) << 16 | ((uint64_t)key_[2]) << 24 | ((uint64_t)key_[1]) << 32 | ((uint64_t)key_[0]) << 40; key = key_[5] | ((uint64_t)key_[4]) << 8 | ((uint64_t)key_[3]) << 16 | ((uint64_t)key_[2]) << 24 | ((uint64_t)key_[1]) << 32 | ((uint64_t)key_[0]) << 40;
} break; }
break;
default: { default: {
Dbprintf("Error , unknown function: %d", htf); Dbprintf("Error , unknown function: %d", htf);
return; return;
} break; }
break;
} }
Dbprintf("Page: %d", page_); Dbprintf("Page: %d", page_);
@ -1818,7 +1835,8 @@ void WritePageHitagS(hitag_function htf, hitag_data* htd,int page_) {
* is not received correctly due to Antenna problems. This function * is not received correctly due to Antenna problems. This function
* detects these challenges. * detects these challenges.
*/ */
void check_challenges(bool file_given, byte_t* data) { void check_challenges(bool file_given, byte_t *data)
{
int i, j, z, k; int i, j, z, k;
byte_t uid_byte[4]; byte_t uid_byte[4];
int frame_count; int frame_count;

View file

@ -141,16 +141,19 @@ typedef struct {
} tUart; } tUart;
static tUart Uart; static tUart Uart;
static void uart_reset(void){ static void uart_reset(void)
{
Uart.frame_done = false; Uart.frame_done = false;
Uart.synced = false; Uart.synced = false;
Uart.frame = false; Uart.frame = false;
} }
static void uart_init(uint8_t *data){ static void uart_init(uint8_t *data)
{
Uart.buf = data; Uart.buf = data;
uart_reset(); uart_reset();
} }
static void uart_bit(uint8_t bit) { static void uart_bit(uint8_t bit)
{
static uint8_t buf = 0xff; static uint8_t buf = 0xff;
static uint8_t n_buf; static uint8_t n_buf;
static uint8_t msg_byte; static uint8_t msg_byte;
@ -205,7 +208,8 @@ static void uart_bit(uint8_t bit) {
} }
} }
static void uart_samples(uint8_t byte) { static void uart_samples(uint8_t byte)
{
static uint32_t buf; static uint32_t buf;
static int window; static int window;
static int drop_next = 0; static int drop_next = 0;
@ -500,7 +504,8 @@ static RAMFUNC int OutOfNDecoding(int bit) {
// Manchester // Manchester
//============================================================================= //=============================================================================
static tDemod Demod; static tDemod Demod;
static void DemodReset() { static void DemodReset()
{
Demod.bitCount = 0; Demod.bitCount = 0;
Demod.posCount = 0; Demod.posCount = 0;
Demod.syncBit = 0; Demod.syncBit = 0;
@ -514,7 +519,8 @@ static void DemodReset() {
Demod.sub = SUB_NONE; Demod.sub = SUB_NONE;
Demod.state = DEMOD_UNSYNCD; Demod.state = DEMOD_UNSYNCD;
} }
static void DemodInit(uint8_t *data) { static void DemodInit(uint8_t *data)
{
Demod.output = data; Demod.output = data;
DemodReset(); DemodReset();
} }
@ -540,7 +546,8 @@ Recorded Activity (TraceLen = 162 bytes)
2720 | 2720 | Rdr |0c | | IDENTIFY 2720 | 2720 | Rdr |0c | | IDENTIFY
3232 | 3232 | Tag |bb! d4! bb! 02 02 08 04 bb! | ok | 3232 | 3232 | Tag |bb! d4! bb! 02 02 08 04 bb! | ok |
*/ */
static void uart_debug(int error, int bit) { static void uart_debug(int error, int bit)
{
Demod.output[Demod.len] = 0xBB; Demod.output[Demod.len] = 0xBB;
Demod.len++; Demod.len++;
Demod.output[Demod.len] = error & 0xFF; Demod.output[Demod.len] = error & 0xFF;
@ -576,7 +583,8 @@ static void uart_debug(int error, int bit) {
* *
* So for current implementation in ISO15693, its 330 µs from end of reader, to start of card. * So for current implementation in ISO15693, its 330 µs from end of reader, to start of card.
*/ */
static RAMFUNC int ManchesterDecoding_iclass( uint32_t v) { static RAMFUNC int ManchesterDecoding_iclass(uint32_t v)
{
int bit; int bit;
int modulation; int modulation;
int error = 0; int error = 0;
@ -629,10 +637,18 @@ static RAMFUNC int ManchesterDecoding_iclass( uint32_t v) {
if (Demod.posCount) { if (Demod.posCount) {
switch (Demod.syncBit) { switch (Demod.syncBit) {
case 0x08: Demod.samples = 3; break; case 0x08:
case 0x04: Demod.samples = 2; break; Demod.samples = 3;
case 0x02: Demod.samples = 1; break; break;
case 0x01: Demod.samples = 0; break; case 0x04:
Demod.samples = 2;
break;
case 0x02:
Demod.samples = 1;
break;
case 0x01:
Demod.samples = 0;
break;
} }
// SOF must be long burst... otherwise stay unsynced!!! // SOF must be long burst... otherwise stay unsynced!!!
if (!(Demod.buffer & Demod.syncBit) || !(Demod.buffer2 & Demod.syncBit)) if (!(Demod.buffer & Demod.syncBit) || !(Demod.buffer2 & Demod.syncBit))
@ -790,7 +806,8 @@ static RAMFUNC int ManchesterDecoding_iclass( uint32_t v) {
// Finally, a `sniffer' for iClass communication // Finally, a `sniffer' for iClass communication
// Both sides of communication! // Both sides of communication!
//============================================================================= //=============================================================================
static void iclass_setup_sniff(void){ static void iclass_setup_sniff(void)
{
if (MF_DBGLEVEL > 3) Dbprintf("iclass_setup_sniff Enter"); if (MF_DBGLEVEL > 3) Dbprintf("iclass_setup_sniff Enter");
LEDsoff(); LEDsoff();
@ -805,7 +822,8 @@ static void iclass_setup_sniff(void){
// Set up the synchronous serial port // Set up the synchronous serial port
FpgaSetupSsc(); FpgaSetupSsc();
BigBuf_free(); BigBuf_Clear_ext(false); BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace(); clear_trace();
set_tracing(true); set_tracing(true);
@ -842,7 +860,8 @@ static void iclass_setup_sniff(void){
// near the reader. // near the reader.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// turn off afterwards // turn off afterwards
void RAMFUNC SniffIClass(void) { void RAMFUNC SniffIClass(void)
{
//int datalen = 0; //int datalen = 0;
uint32_t previous_data = 0; uint32_t previous_data = 0;
@ -964,7 +983,8 @@ void RAMFUNC SniffIClass(void) {
switch_off(); switch_off();
} }
void rotateCSN(uint8_t* originalCSN, uint8_t* rotatedCSN) { void rotateCSN(uint8_t *originalCSN, uint8_t *rotatedCSN)
{
int i; int i;
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
rotatedCSN[i] = (originalCSN[i] >> 3) | (originalCSN[(i + 1) % 8] << 5); rotatedCSN[i] = (originalCSN[i] >> 3) | (originalCSN[(i + 1) % 8] << 5);
@ -976,7 +996,8 @@ void rotateCSN(uint8_t* originalCSN, uint8_t* rotatedCSN) {
// Stop when button is pressed // Stop when button is pressed
// Or return TRUE when command is captured // Or return TRUE when command is captured
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static bool GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen) { static bool GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen)
{
// Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen
// only, since we are receiving, not transmitting). // only, since we are receiving, not transmitting).
// Signal field is off with the appropriate LED // Signal field is off with the appropriate LED
@ -1008,7 +1029,8 @@ static bool GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen)
return false; return false;
} }
static uint8_t encode4Bits(const uint8_t b) { static uint8_t encode4Bits(const uint8_t b)
{
// OTA, the least significant bits first // OTA, the least significant bits first
// Manchester encoding added // Manchester encoding added
// The columns are // The columns are
@ -1020,29 +1042,46 @@ static uint8_t encode4Bits(const uint8_t b) {
uint8_t c = b & 0xF; uint8_t c = b & 0xF;
switch (c) { switch (c) {
// 1 2 3 4 // 1 2 3 4
case 15: return 0x55; // 1111 -> 1111 -> 01010101 -> 0x55 case 15:
case 14: return 0x95; // 1110 -> 0111 -> 10010101 -> 0x95 return 0x55; // 1111 -> 1111 -> 01010101 -> 0x55
case 13: return 0x65; // 1101 -> 1011 -> 01100101 -> 0x65 case 14:
case 12: return 0xa5; // 1100 -> 0011 -> 10100101 -> 0xa5 return 0x95; // 1110 -> 0111 -> 10010101 -> 0x95
case 11: return 0x59; // 1011 -> 1101 -> 01011001 -> 0x59 case 13:
case 10: return 0x99; // 1010 -> 0101 -> 10011001 -> 0x99 return 0x65; // 1101 -> 1011 -> 01100101 -> 0x65
case 9: return 0x69; // 1001 -> 1001 -> 01101001 -> 0x69 case 12:
case 8: return 0xa9; // 1000 -> 0001 -> 10101001 -> 0xa9 return 0xa5; // 1100 -> 0011 -> 10100101 -> 0xa5
case 7: return 0x56; // 0111 -> 1110 -> 01010110 -> 0x56 case 11:
case 6: return 0x96; // 0110 -> 0110 -> 10010110 -> 0x96 return 0x59; // 1011 -> 1101 -> 01011001 -> 0x59
case 5: return 0x66; // 0101 -> 1010 -> 01100110 -> 0x66 case 10:
case 4: return 0xa6; // 0100 -> 0010 -> 10100110 -> 0xa6 return 0x99; // 1010 -> 0101 -> 10011001 -> 0x99
case 3: return 0x5a; // 0011 -> 1100 -> 01011010 -> 0x5a case 9:
case 2: return 0x9a; // 0010 -> 0100 -> 10011010 -> 0x9a return 0x69; // 1001 -> 1001 -> 01101001 -> 0x69
case 1: return 0x6a; // 0001 -> 1000 -> 01101010 -> 0x6a case 8:
default: return 0xaa; // 0000 -> 0000 -> 10101010 -> 0xaa return 0xa9; // 1000 -> 0001 -> 10101001 -> 0xa9
case 7:
return 0x56; // 0111 -> 1110 -> 01010110 -> 0x56
case 6:
return 0x96; // 0110 -> 0110 -> 10010110 -> 0x96
case 5:
return 0x66; // 0101 -> 1010 -> 01100110 -> 0x66
case 4:
return 0xa6; // 0100 -> 0010 -> 10100110 -> 0xa6
case 3:
return 0x5a; // 0011 -> 1100 -> 01011010 -> 0x5a
case 2:
return 0x9a; // 0010 -> 0100 -> 10011010 -> 0x9a
case 1:
return 0x6a; // 0001 -> 1000 -> 01101010 -> 0x6a
default:
return 0xaa; // 0000 -> 0000 -> 10101010 -> 0xaa
} }
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Prepare tag messages // Prepare tag messages
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void CodeIClassTagAnswer(const uint8_t *cmd, int len) { static void CodeIClassTagAnswer(const uint8_t *cmd, int len)
{
/* /*
* SOF comprises 3 parts; * SOF comprises 3 parts;
* * An unmodulated time of 56.64 us * * An unmodulated time of 56.64 us
@ -1096,7 +1135,8 @@ static void CodeIClassTagAnswer(const uint8_t *cmd, int len) {
} }
// Only SOF // Only SOF
static void CodeIClassTagSOF() { static void CodeIClassTagSOF()
{
//So far a dummy implementation, not used //So far a dummy implementation, not used
//int lastProxToAirDuration =0; //int lastProxToAirDuration =0;
@ -1122,7 +1162,8 @@ static void CodeIClassTagSOF() {
* @param datain * @param datain
*/ */
// turn off afterwards // turn off afterwards
void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) { void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
{
if (MF_DBGLEVEL > 3) Dbprintf("[+] iClass_simulate Enter"); if (MF_DBGLEVEL > 3) Dbprintf("[+] iClass_simulate Enter");
@ -1232,7 +1273,8 @@ out:
* @param csn - csn to use * @param csn - csn to use
* @param breakAfterMacReceived if true, returns after reader MAC has been received. * @param breakAfterMacReceived if true, returns after reader MAC has been received.
*/ */
int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) { int doIClassSimulation(int simulationMode, uint8_t *reader_mac_buf)
{
// free eventually allocated BigBuf memory // free eventually allocated BigBuf memory
BigBuf_free_keep_EM(); BigBuf_free_keep_EM();
@ -1327,27 +1369,33 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
// First card answer: SOF // First card answer: SOF
CodeIClassTagSOF(); CodeIClassTagSOF();
memcpy(resp_sof, ToSend, ToSendMax); resp_sof_Len = ToSendMax; memcpy(resp_sof, ToSend, ToSendMax);
resp_sof_Len = ToSendMax;
// Anticollision CSN // Anticollision CSN
CodeIClassTagAnswer(anticoll_data, sizeof(anticoll_data)); CodeIClassTagAnswer(anticoll_data, sizeof(anticoll_data));
memcpy(resp_anticoll, ToSend, ToSendMax); resp_anticoll_len = ToSendMax; memcpy(resp_anticoll, ToSend, ToSendMax);
resp_anticoll_len = ToSendMax;
// CSN // CSN
CodeIClassTagAnswer(csn_data, sizeof(csn_data)); CodeIClassTagAnswer(csn_data, sizeof(csn_data));
memcpy(resp_csn, ToSend, ToSendMax); resp_csn_len = ToSendMax; memcpy(resp_csn, ToSend, ToSendMax);
resp_csn_len = ToSendMax;
// Configuration // Configuration
CodeIClassTagAnswer(conf_data, sizeof(conf_data)); CodeIClassTagAnswer(conf_data, sizeof(conf_data));
memcpy(resp_conf, ToSend, ToSendMax); resp_conf_len = ToSendMax; memcpy(resp_conf, ToSend, ToSendMax);
resp_conf_len = ToSendMax;
// e-Purse // e-Purse
CodeIClassTagAnswer(card_challenge_data, sizeof(card_challenge_data)); CodeIClassTagAnswer(card_challenge_data, sizeof(card_challenge_data));
memcpy(resp_cc, ToSend, ToSendMax); resp_cc_len = ToSendMax; memcpy(resp_cc, ToSend, ToSendMax);
resp_cc_len = ToSendMax;
// Application Issuer Area // Application Issuer Area
CodeIClassTagAnswer(aia_data, sizeof(aia_data)); CodeIClassTagAnswer(aia_data, sizeof(aia_data));
memcpy(resp_aia, ToSend, ToSendMax); resp_aia_len = ToSendMax; memcpy(resp_aia, ToSend, ToSendMax);
resp_aia_len = ToSendMax;
//This is used for responding to READ-block commands or other data which is dynamically generated //This is used for responding to READ-block commands or other data which is dynamically generated
//First the 'trace'-data, not encoded for FPGA //First the 'trace'-data, not encoded for FPGA
@ -1373,7 +1421,8 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
WDT_HIT(); WDT_HIT();
//Signal tracer, can be used to get a trigger for an oscilloscope.. //Signal tracer, can be used to get a trigger for an oscilloscope..
LED_B_OFF(); LED_C_OFF(); LED_B_OFF();
LED_C_OFF();
r2t_stime = (GetCountSspClk() - time_0) << 4; r2t_stime = (GetCountSspClk() - time_0) << 4;
if (!GetIClassCommandFromReader(receivedCmd, &len, 0)) { if (!GetIClassCommandFromReader(receivedCmd, &len, 0)) {
@ -1389,7 +1438,8 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
if (receivedCmd[0] == ICLASS_CMD_ACTALL) { // 0x0A if (receivedCmd[0] == ICLASS_CMD_ACTALL) { // 0x0A
// Reader in anticollission phase // Reader in anticollission phase
modulated_response = resp_sof; modulated_response_size = resp_sof_Len; //order = 1; modulated_response = resp_sof;
modulated_response_size = resp_sof_Len; //order = 1;
trace_data = sof_data; trace_data = sof_data;
trace_data_size = sizeof(sof_data); trace_data_size = sizeof(sof_data);
// adjusted for 330 + (160*num of slot) // adjusted for 330 + (160*num of slot)
@ -1397,7 +1447,8 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
} else if (receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY) { // 0x0C } else if (receivedCmd[0] == ICLASS_CMD_READ_OR_IDENTIFY) { // 0x0C
if (len == 1) { if (len == 1) {
// Reader asks for anticollission CSN // Reader asks for anticollission CSN
modulated_response = resp_anticoll; modulated_response_size = resp_anticoll_len; //order = 2; modulated_response = resp_anticoll;
modulated_response_size = resp_anticoll_len; //order = 2;
trace_data = anticoll_data; trace_data = anticoll_data;
trace_data_size = sizeof(anticoll_data); trace_data_size = sizeof(anticoll_data);
goto send; goto send;
@ -1406,17 +1457,20 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
// block0,1,2,5 is always readable. // block0,1,2,5 is always readable.
switch (receivedCmd[1]) { switch (receivedCmd[1]) {
case 0: // csn (0c 00) case 0: // csn (0c 00)
modulated_response = resp_csn; modulated_response_size = resp_csn_len; modulated_response = resp_csn;
modulated_response_size = resp_csn_len;
trace_data = csn_data; trace_data = csn_data;
trace_data_size = sizeof(csn_data); trace_data_size = sizeof(csn_data);
break; break;
case 1: // configuration (0c 01) case 1: // configuration (0c 01)
modulated_response = resp_conf; modulated_response_size = resp_conf_len; modulated_response = resp_conf;
modulated_response_size = resp_conf_len;
trace_data = conf_data; trace_data = conf_data;
trace_data_size = sizeof(conf_data); trace_data_size = sizeof(conf_data);
break; break;
case 2: // e-purse (0c 02) case 2: // e-purse (0c 02)
modulated_response = resp_cc; modulated_response_size = resp_cc_len; modulated_response = resp_cc;
modulated_response_size = resp_cc_len;
trace_data = card_challenge_data; trace_data = card_challenge_data;
trace_data_size = sizeof(card_challenge_data); trace_data_size = sizeof(card_challenge_data);
// set epurse of sim2,4 attack // set epurse of sim2,4 attack
@ -1425,11 +1479,13 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
} }
break; break;
case 5:// Application Issuer Area (0c 05) case 5:// Application Issuer Area (0c 05)
modulated_response = resp_aia; modulated_response_size = resp_aia_len; modulated_response = resp_aia;
modulated_response_size = resp_aia_len;
trace_data = aia_data; trace_data = aia_data;
trace_data_size = sizeof(aia_data); trace_data_size = sizeof(aia_data);
break; break;
default: break; default:
break;
} }
goto send; goto send;
} }
@ -1437,20 +1493,23 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
} else if (receivedCmd[0] == ICLASS_CMD_SELECT) { // 0x81 } else if (receivedCmd[0] == ICLASS_CMD_SELECT) { // 0x81
// Reader selects anticollission CSN. // Reader selects anticollission CSN.
// Tag sends the corresponding real CSN // Tag sends the corresponding real CSN
modulated_response = resp_csn; modulated_response_size = resp_csn_len; //order = 3; modulated_response = resp_csn;
modulated_response_size = resp_csn_len; //order = 3;
trace_data = csn_data; trace_data = csn_data;
trace_data_size = sizeof(csn_data); trace_data_size = sizeof(csn_data);
goto send; goto send;
} else if (receivedCmd[0] == ICLASS_CMD_READCHECK_KD) { // 0x88 } else if (receivedCmd[0] == ICLASS_CMD_READCHECK_KD) { // 0x88
// Read e-purse (88 02) // Read e-purse (88 02)
modulated_response = resp_cc; modulated_response_size = resp_cc_len; //order = 4; modulated_response = resp_cc;
modulated_response_size = resp_cc_len; //order = 4;
trace_data = card_challenge_data; trace_data = card_challenge_data;
trace_data_size = sizeof(card_challenge_data); trace_data_size = sizeof(card_challenge_data);
LED_B_ON(); LED_B_ON();
goto send; goto send;
} else if (receivedCmd[0] == ICLASS_CMD_READCHECK_KC) { // 0x18 } else if (receivedCmd[0] == ICLASS_CMD_READCHECK_KC) { // 0x18
// Read e-purse (18 02) // Read e-purse (18 02)
modulated_response = resp_cc; modulated_response_size = resp_cc_len; //order = 4; modulated_response = resp_cc;
modulated_response_size = resp_cc_len; //order = 4;
trace_data = card_challenge_data; trace_data = card_challenge_data;
trace_data_size = sizeof(card_challenge_data); trace_data_size = sizeof(card_challenge_data);
LED_B_ON(); LED_B_ON();
@ -1470,7 +1529,8 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
} else { } else {
// Not fullsim, we don't respond // Not fullsim, we don't respond
// We do not know what to answer, so lets keep quiet // We do not know what to answer, so lets keep quiet
modulated_response = resp_sof; modulated_response_size = 0; modulated_response = resp_sof;
modulated_response_size = 0;
trace_data = NULL; trace_data = NULL;
trace_data_size = 0; trace_data_size = 0;
@ -1494,7 +1554,8 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
goto send; goto send;
} else if (receivedCmd[0] == ICLASS_CMD_HALT && len == 1) { } else if (receivedCmd[0] == ICLASS_CMD_HALT && len == 1) {
// Reader ends the session // Reader ends the session
modulated_response = resp_sof; modulated_response_size = 0; //order = 0; modulated_response = resp_sof;
modulated_response_size = 0; //order = 0;
trace_data = NULL; trace_data = NULL;
trace_data_size = 0; trace_data_size = 0;
goto send; goto send;
@ -1580,7 +1641,8 @@ send:
* @param respLen * @param respLen
* @param delay * @param delay
*/ */
static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) { static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay)
{
int i = 0; int i = 0;
volatile uint8_t b = 0; volatile uint8_t b = 0;
@ -1592,7 +1654,8 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) {
// Prevent rx holding register from overflowing // Prevent rx holding register from overflowing
if ((AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) { if ((AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) {
b = AT91C_BASE_SSC->SSC_RHR; (void) b; b = AT91C_BASE_SSC->SSC_RHR;
(void) b;
} }
// Put byte into tx holding register as soon as it is ready // Put byte into tx holding register as soon as it is ready
@ -1617,7 +1680,8 @@ static int SendIClassAnswer(uint8_t *resp, int respLen, uint16_t delay) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Transmit the command (to the tag) that was placed in ToSend[]. // Transmit the command (to the tag) that was placed in ToSend[].
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int *wait) { static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int *wait)
{
int c = 0; int c = 0;
volatile uint32_t b; volatile uint32_t b;
@ -1657,7 +1721,8 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int
// Prevent rx holding register from overflowing // Prevent rx holding register from overflowing
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
b = AT91C_BASE_SSC->SSC_RHR; (void)b; b = AT91C_BASE_SSC->SSC_RHR;
(void)b;
} }
} }
@ -1672,7 +1737,8 @@ static void TransmitIClassCommand(const uint8_t *cmd, int len, int *samples, int
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Prepare iClass reader command to send to FPGA // Prepare iClass reader command to send to FPGA
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CodeIClassCommand(const uint8_t* cmd, int len) { void CodeIClassCommand(const uint8_t *cmd, int len)
{
int i, j, k; int i, j, k;
uint8_t b; uint8_t b;
@ -1709,7 +1775,8 @@ void CodeIClassCommand(const uint8_t* cmd, int len) {
ToSendMax++; ToSendMax++;
} }
void ReaderTransmitIClass_ext(uint8_t* frame, int len, int wait) { void ReaderTransmitIClass_ext(uint8_t *frame, int len, int wait)
{
int samples = 0; int samples = 0;
@ -1725,7 +1792,8 @@ void ReaderTransmitIClass_ext(uint8_t* frame, int len, int wait) {
LogTrace(frame, len, rsamples, rsamples, NULL, true); LogTrace(frame, len, rsamples, rsamples, NULL, true);
} }
void ReaderTransmitIClass(uint8_t* frame, int len) { void ReaderTransmitIClass(uint8_t *frame, int len)
{
ReaderTransmitIClass_ext(frame, len, 330); ReaderTransmitIClass_ext(frame, len, 330);
} }
@ -1734,7 +1802,8 @@ void ReaderTransmitIClass(uint8_t* frame, int len) {
// If a response is captured return TRUE // If a response is captured return TRUE
// If it takes too long return FALSE // If it takes too long return FALSE
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static int GetIClassAnswer(uint8_t* receivedResponse, int maxLen, int *samples, int *elapsed) { static int GetIClassAnswer(uint8_t *receivedResponse, int maxLen, int *samples, int *elapsed)
{
// buffer needs to be 512 bytes // buffer needs to be 512 bytes
// maxLen is not used... // maxLen is not used...
@ -1785,7 +1854,8 @@ static int GetIClassAnswer(uint8_t* receivedResponse, int maxLen, int *samples,
return false; return false;
} }
int ReaderReceiveIClass(uint8_t* receivedAnswer) { int ReaderReceiveIClass(uint8_t *receivedAnswer)
{
int samples = 0; int samples = 0;
if (!GetIClassAnswer(receivedAnswer, 0, &samples, NULL)) if (!GetIClassAnswer(receivedAnswer, 0, &samples, NULL))
@ -1801,7 +1871,8 @@ int ReaderReceiveIClass(uint8_t* receivedAnswer) {
return Demod.len; return Demod.len;
} }
void setupIclassReader() { void setupIclassReader()
{
LEDsoff(); LEDsoff();
@ -1828,7 +1899,8 @@ void setupIclassReader() {
LED_A_ON(); LED_A_ON();
} }
bool sendCmdGetResponseWithRetries(uint8_t* command, size_t cmdsize, uint8_t* resp, uint8_t expected_size, uint8_t retries) { bool sendCmdGetResponseWithRetries(uint8_t *command, size_t cmdsize, uint8_t *resp, uint8_t expected_size, uint8_t retries)
{
uint8_t got_n = 0; uint8_t got_n = 0;
while (retries-- > 0) { while (retries-- > 0) {
@ -1857,7 +1929,8 @@ bool sendCmdGetResponseWithRetries(uint8_t* command, size_t cmdsize, uint8_t* re
* 1 = Got CSN * 1 = Got CSN
* 2 = Got CSN and CC * 2 = Got CSN and CC
*/ */
uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) { uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key)
{
// act_all... // act_all...
static uint8_t act_all[] = { ICLASS_CMD_ACTALL }; static uint8_t act_all[] = { ICLASS_CMD_ACTALL };
@ -1916,13 +1989,15 @@ uint8_t handshakeIclassTag_ext(uint8_t *card_data, bool use_credit_key) {
read_status++; read_status++;
return read_status; return read_status;
} }
uint8_t handshakeIclassTag(uint8_t *card_data){ uint8_t handshakeIclassTag(uint8_t *card_data)
{
return handshakeIclassTag_ext(card_data, false); return handshakeIclassTag_ext(card_data, false);
} }
// Reader iClass Anticollission // Reader iClass Anticollission
// turn off afterwards // turn off afterwards
void ReaderIClass(uint8_t arg0) { void ReaderIClass(uint8_t arg0)
{
uint8_t card_data[6 * 8] = {0}; uint8_t card_data[6 * 8] = {0};
uint8_t last_csn[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t last_csn[8] = {0, 0, 0, 0, 0, 0, 0, 0};
@ -2061,7 +2136,8 @@ void ReaderIClass(uint8_t arg0) {
} }
// turn off afterwards // turn off afterwards
void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) { void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC)
{
uint8_t cardsize = 0; uint8_t cardsize = 0;
uint8_t mem = 0; uint8_t mem = 0;
@ -2181,7 +2257,8 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
// not used. ?!? ( CMD_ICLASS_READCHECK) // not used. ?!? ( CMD_ICLASS_READCHECK)
// turn off afterwards // turn off afterwards
void iClass_ReadCheck(uint8_t blockNo, uint8_t keyType) { void iClass_ReadCheck(uint8_t blockNo, uint8_t keyType)
{
uint8_t readcheck[] = { keyType, blockNo }; uint8_t readcheck[] = { keyType, blockNo };
uint8_t resp[] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t resp[] = {0, 0, 0, 0, 0, 0, 0, 0};
size_t isOK = 0; size_t isOK = 0;
@ -2192,7 +2269,8 @@ void iClass_ReadCheck(uint8_t blockNo, uint8_t keyType) {
// used with function select_and_auth (cmdhficlass.c) // used with function select_and_auth (cmdhficlass.c)
// which needs to authenticate before doing more things like read/write // which needs to authenticate before doing more things like read/write
void iClass_Authentication(uint8_t *mac) { void iClass_Authentication(uint8_t *mac)
{
uint8_t check[] = { ICLASS_CMD_CHECK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t check[] = { ICLASS_CMD_CHECK, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
uint8_t resp[ICLASS_BUFFER_SIZE]; uint8_t resp[ICLASS_BUFFER_SIZE];
@ -2219,7 +2297,8 @@ typedef struct iclass_premac {
* - key loop only test one type of authtication key. Ie two calls needed * - key loop only test one type of authtication key. Ie two calls needed
* to cover debit and credit key. (AA1/AA2) * to cover debit and credit key. (AA1/AA2)
*/ */
void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain) { void iClass_Authentication_fast(uint64_t arg0, uint64_t arg1, uint8_t *datain)
{
uint8_t i = 0, isOK = 0; uint8_t i = 0, isOK = 0;
uint8_t lastChunk = ((arg0 >> 8) & 0xFF); uint8_t lastChunk = ((arg0 >> 8) & 0xFF);
bool use_credit_key = ((arg0 >> 16) & 0xFF); bool use_credit_key = ((arg0 >> 16) & 0xFF);
@ -2302,7 +2381,8 @@ out:
// Tries to read block. // Tries to read block.
// retries 10times. // retries 10times.
bool iClass_ReadBlock(uint8_t blockNo, uint8_t *data, uint8_t len) { bool iClass_ReadBlock(uint8_t blockNo, uint8_t *data, uint8_t len)
{
uint8_t resp[10]; uint8_t resp[10];
uint8_t cmd[] = {ICLASS_CMD_READ_OR_IDENTIFY, blockNo, 0x00, 0x00}; uint8_t cmd[] = {ICLASS_CMD_READ_OR_IDENTIFY, blockNo, 0x00, 0x00};
AddCrc(cmd + 1, 1); AddCrc(cmd + 1, 1);
@ -2314,7 +2394,8 @@ bool iClass_ReadBlock(uint8_t blockNo, uint8_t *data, uint8_t len) {
// turn off afterwards // turn off afterwards
// readblock 8 + 2. only want 8. // readblock 8 + 2. only want 8.
void iClass_ReadBlk(uint8_t blockno) { void iClass_ReadBlk(uint8_t blockno)
{
uint8_t data[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t data[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
bool isOK = iClass_ReadBlock(blockno, data, sizeof(data)); bool isOK = iClass_ReadBlock(blockno, data, sizeof(data));
cmd_send(CMD_ACK, isOK, 0, 0, data, sizeof(data)); cmd_send(CMD_ACK, isOK, 0, 0, data, sizeof(data));
@ -2322,7 +2403,8 @@ void iClass_ReadBlk(uint8_t blockno) {
} }
// turn off afterwards // turn off afterwards
void iClass_Dump(uint8_t blockno, uint8_t numblks) { void iClass_Dump(uint8_t blockno, uint8_t numblks)
{
uint8_t blockdata[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t blockdata[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
bool isOK = false; bool isOK = false;
uint8_t blkCnt = 0; uint8_t blkCnt = 0;
@ -2356,7 +2438,8 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) {
BigBuf_free(); BigBuf_free();
} }
bool iClass_WriteBlock_ext(uint8_t blockNo, uint8_t *data) { bool iClass_WriteBlock_ext(uint8_t blockNo, uint8_t *data)
{
uint8_t resp[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t resp[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t write[] = { ICLASS_CMD_UPDATE, blockNo, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; uint8_t write[] = { ICLASS_CMD_UPDATE, blockNo, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
@ -2379,14 +2462,16 @@ bool iClass_WriteBlock_ext(uint8_t blockNo, uint8_t *data) {
} }
// turn off afterwards // turn off afterwards
void iClass_WriteBlock(uint8_t blockNo, uint8_t *data) { void iClass_WriteBlock(uint8_t blockNo, uint8_t *data)
{
bool isOK = iClass_WriteBlock_ext(blockNo, data); bool isOK = iClass_WriteBlock_ext(blockNo, data);
cmd_send(CMD_ACK, isOK, 0, 0, 0, 0); cmd_send(CMD_ACK, isOK, 0, 0, 0, 0);
switch_off(); switch_off();
} }
// turn off afterwards // turn off afterwards
void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data) { void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data)
{
int i, written = 0; int i, written = 0;
int total_block = (endblock - startblock) + 1; int total_block = (endblock - startblock) + 1;
for (i = 0; i < total_block; i++) { for (i = 0; i < total_block; i++) {

View file

@ -120,22 +120,26 @@ static uint32_t LastProxToAirDuration;
#define SEC_Y 0x00 #define SEC_Y 0x00
#define SEC_Z 0xc0 #define SEC_Z 0xc0
void iso14a_set_trigger(bool enable) { void iso14a_set_trigger(bool enable)
{
trigger = enable; trigger = enable;
} }
void iso14a_set_timeout(uint32_t timeout) { void iso14a_set_timeout(uint32_t timeout)
{
iso14a_timeout = timeout + (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / (16 * 8) + 2; iso14a_timeout = timeout + (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / (16 * 8) + 2;
} }
uint32_t iso14a_get_timeout(void) { uint32_t iso14a_get_timeout(void)
{
return iso14a_timeout - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / (16 * 8) - 2; return iso14a_timeout - (DELAY_AIR2ARM_AS_READER + DELAY_ARM2AIR_AS_READER) / (16 * 8) - 2;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Generate the parity value for a byte sequence // Generate the parity value for a byte sequence
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void GetParity(const uint8_t *pbtCmd, uint16_t iLen, uint8_t *par) { void GetParity(const uint8_t *pbtCmd, uint16_t iLen, uint8_t *par)
{
uint16_t paritybit_cnt = 0; uint16_t paritybit_cnt = 0;
uint16_t paritybyte_cnt = 0; uint16_t paritybyte_cnt = 0;
uint8_t parityBits = 0; uint8_t parityBits = 0;
@ -189,11 +193,13 @@ const bool Mod_Miller_LUT[] = {
#define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x000000F0) >> 4]) #define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x000000F0) >> 4])
#define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x0000000F)]) #define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x0000000F)])
tUart* GetUart() { tUart *GetUart()
{
return &Uart; return &Uart;
} }
void UartReset(void) { void UartReset(void)
{
Uart.state = STATE_UNSYNCD; Uart.state = STATE_UNSYNCD;
Uart.bitCount = 0; Uart.bitCount = 0;
Uart.len = 0; // number of decoded data bytes Uart.len = 0; // number of decoded data bytes
@ -207,14 +213,16 @@ void UartReset(void) {
Uart.syncBit = 9999; Uart.syncBit = 9999;
} }
void UartInit(uint8_t *data, uint8_t *parity) { void UartInit(uint8_t *data, uint8_t *parity)
{
Uart.output = data; Uart.output = data;
Uart.parity = parity; Uart.parity = parity;
UartReset(); UartReset();
} }
// use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time // use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time
RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time) { RAMFUNC bool MillerDecoding(uint8_t bit, uint32_t non_real_time)
{
Uart.fourBits = (Uart.fourBits << 8) | bit; Uart.fourBits = (Uart.fourBits << 8) | bit;
if (Uart.state == STATE_UNSYNCD) { // not yet synced if (Uart.state == STATE_UNSYNCD) { // not yet synced
@ -361,10 +369,12 @@ const bool Mod_Manchester_LUT[] = {
#define IsManchesterModulationNibble1(b) (Mod_Manchester_LUT[(b & 0x00F0) >> 4]) #define IsManchesterModulationNibble1(b) (Mod_Manchester_LUT[(b & 0x00F0) >> 4])
#define IsManchesterModulationNibble2(b) (Mod_Manchester_LUT[(b & 0x000F)]) #define IsManchesterModulationNibble2(b) (Mod_Manchester_LUT[(b & 0x000F)])
tDemod* GetDemod() { tDemod *GetDemod()
{
return &Demod; return &Demod;
} }
void DemodReset(void) { void DemodReset(void)
{
Demod.state = DEMOD_UNSYNCD; Demod.state = DEMOD_UNSYNCD;
Demod.len = 0; // number of decoded data bytes Demod.len = 0; // number of decoded data bytes
Demod.parityLen = 0; Demod.parityLen = 0;
@ -380,14 +390,16 @@ void DemodReset(void) {
Demod.samples = 0; Demod.samples = 0;
} }
void DemodInit(uint8_t *data, uint8_t *parity) { void DemodInit(uint8_t *data, uint8_t *parity)
{
Demod.output = data; Demod.output = data;
Demod.parity = parity; Demod.parity = parity;
DemodReset(); DemodReset();
} }
// use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time // use parameter non_real_time to provide a timestamp. Set to 0 if the decoder should measure real time
RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time) { RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_time)
{
Demod.twoBits = (Demod.twoBits << 8) | bit; Demod.twoBits = (Demod.twoBits << 8) | bit;
if (Demod.state == DEMOD_UNSYNCD) { if (Demod.state == DEMOD_UNSYNCD) {
@ -487,7 +499,8 @@ RAMFUNC int ManchesterDecoding(uint8_t bit, uint16_t offset, uint32_t non_real_t
// near the reader. // near the reader.
// "hf 14a sniff" // "hf 14a sniff"
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void RAMFUNC SniffIso14443a(uint8_t param) { void RAMFUNC SniffIso14443a(uint8_t param)
{
LEDsoff(); LEDsoff();
// param: // param:
// bit 0 - trigger from first card answer // bit 0 - trigger from first card answer
@ -496,7 +509,8 @@ void RAMFUNC SniffIso14443a(uint8_t param) {
// Allocate memory from BigBuf for some buffers // Allocate memory from BigBuf for some buffers
// free all previous allocations first // free all previous allocations first
BigBuf_free(); BigBuf_Clear_ext(false); BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace(); clear_trace();
set_tracing(true); set_tracing(true);
@ -649,7 +663,8 @@ void RAMFUNC SniffIso14443a(uint8_t param) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Prepare tag messages // Prepare tag messages
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *parity, bool collision) { static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *parity, bool collision)
{
//uint8_t localCol = 0; //uint8_t localCol = 0;
ToSendReset(); ToSendReset();
@ -709,16 +724,19 @@ static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *par
ToSendMax++; ToSendMax++;
} }
static void CodeIso14443aAsTagEx(const uint8_t *cmd, uint16_t len, bool collision) { static void CodeIso14443aAsTagEx(const uint8_t *cmd, uint16_t len, bool collision)
{
uint8_t par[MAX_PARITY_SIZE] = {0}; uint8_t par[MAX_PARITY_SIZE] = {0};
GetParity(cmd, len, par); GetParity(cmd, len, par);
CodeIso14443aAsTagPar(cmd, len, par, collision); CodeIso14443aAsTagPar(cmd, len, par, collision);
} }
static void CodeIso14443aAsTag(const uint8_t *cmd, uint16_t len) { static void CodeIso14443aAsTag(const uint8_t *cmd, uint16_t len)
{
CodeIso14443aAsTagEx(cmd, len, false); CodeIso14443aAsTagEx(cmd, len, false);
} }
static void Code4bitAnswerAsTag(uint8_t cmd) { static void Code4bitAnswerAsTag(uint8_t cmd)
{
uint8_t b = cmd; uint8_t b = cmd;
ToSendReset(); ToSendReset();
@ -759,7 +777,8 @@ static void Code4bitAnswerAsTag(uint8_t cmd) {
// stop when button is pressed // stop when button is pressed
// or return TRUE when command is captured // or return TRUE when command is captured
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int *len) { int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int *len)
{
// Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen // Set FPGA mode to "simulated ISO 14443 tag", no modulation (listen
// only, since we are receiving, not transmitting). // only, since we are receiving, not transmitting).
// Signal field is off with the appropriate LED // Signal field is off with the appropriate LED
@ -786,7 +805,8 @@ int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int *len)
return false; return false;
} }
bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffer_size) { bool prepare_tag_modulation(tag_response_info_t *response_info, size_t max_buffer_size)
{
// Example response, answer to MIFARE Classic read block will be 16 bytes + 2 CRC = 18 bytes // Example response, answer to MIFARE Classic read block will be 16 bytes + 2 CRC = 18 bytes
// This will need the following byte array for a modulation sequence // This will need the following byte array for a modulation sequence
// 144 data bits (18 * 8) // 144 data bits (18 * 8)
@ -824,7 +844,8 @@ bool prepare_tag_modulation(tag_response_info_t* response_info, size_t max_buffe
// 47 * 8 data bits, 47 * 1 parity bits, 10 start bits, 10 stop bits, 10 correction bits // 47 * 8 data bits, 47 * 1 parity bits, 10 start bits, 10 stop bits, 10 correction bits
#define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 453 #define ALLOCATED_TAG_MODULATION_BUFFER_SIZE 453
bool prepare_allocated_tag_modulation(tag_response_info_t* response_info) { bool prepare_allocated_tag_modulation(tag_response_info_t *response_info)
{
// Retrieve and store the current buffer index // Retrieve and store the current buffer index
response_info->modulation = free_buffer_pointer; response_info->modulation = free_buffer_pointer;
@ -846,7 +867,8 @@ bool prepare_allocated_tag_modulation(tag_response_info_t* response_info) {
// response to send, and send it. // response to send, and send it.
// 'hf 14a sim' // 'hf 14a sim'
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) { void SimulateIso14443aTag(int tagType, int flags, uint8_t *data)
{
#define ATTACK_KEY_COUNT 8 // keep same as define in cmdhfmf.c -> readerAttack() #define ATTACK_KEY_COUNT 8 // keep same as define in cmdhfmf.c -> readerAttack()
@ -876,29 +898,35 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) {
case 1: { // MIFARE Classic 1k case 1: { // MIFARE Classic 1k
response1[0] = 0x04; response1[0] = 0x04;
sak = 0x08; sak = 0x08;
} break; }
break;
case 2: { // MIFARE Ultralight case 2: { // MIFARE Ultralight
response1[0] = 0x44; response1[0] = 0x44;
sak = 0x00; sak = 0x00;
} break; }
break;
case 3: { // MIFARE DESFire case 3: { // MIFARE DESFire
response1[0] = 0x04; response1[0] = 0x04;
response1[1] = 0x03; response1[1] = 0x03;
sak = 0x20; sak = 0x20;
} break; }
break;
case 4: { // ISO/IEC 14443-4 - javacard (JCOP) case 4: { // ISO/IEC 14443-4 - javacard (JCOP)
response1[0] = 0x04; response1[0] = 0x04;
sak = 0x28; sak = 0x28;
} break; }
break;
case 5: { // MIFARE TNP3XXX case 5: { // MIFARE TNP3XXX
response1[0] = 0x01; response1[0] = 0x01;
response1[1] = 0x0f; response1[1] = 0x0f;
sak = 0x01; sak = 0x01;
} break; }
break;
case 6: { // MIFARE Mini 320b case 6: { // MIFARE Mini 320b
response1[0] = 0x44; response1[0] = 0x44;
sak = 0x09; sak = 0x09;
} break; }
break;
case 7: { // NTAG case 7: { // NTAG
response1[0] = 0x44; response1[0] = 0x44;
sak = 0x00; sak = 0x00;
@ -915,11 +943,13 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) {
memcpy(data + 3, emdata + 4, 4); // uid bytes 3-7 memcpy(data + 3, emdata + 4, 4); // uid bytes 3-7
flags |= FLAG_7B_UID_IN_DATA; flags |= FLAG_7B_UID_IN_DATA;
} }
} break; }
break;
case 8: { // MIFARE Classic 4k case 8: { // MIFARE Classic 4k
response1[0] = 0x02; response1[0] = 0x02;
sak = 0x18; sak = 0x18;
} break; }
break;
case 9 : { // FM11RF005SH (Shanghai Metro) case 9 : { // FM11RF005SH (Shanghai Metro)
response1[0] = 0x03; response1[0] = 0x03;
response1[1] = 0x00; response1[1] = 0x00;
@ -928,7 +958,8 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) {
default: { default: {
Dbprintf("Error: unkown tagtype (%d)", tagType); Dbprintf("Error: unkown tagtype (%d)", tagType);
return; return;
} break; }
break;
} }
// The second response contains the (mandatory) first 24 bits of the UID // The second response contains the (mandatory) first 24 bits of the UID
@ -1063,17 +1094,23 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) {
// Okay, look at the command now. // Okay, look at the command now.
lastorder = order; lastorder = order;
if (receivedCmd[0] == ISO14443A_CMD_REQA) { // Received a REQUEST if (receivedCmd[0] == ISO14443A_CMD_REQA) { // Received a REQUEST
p_response = &responses[0]; order = 1; p_response = &responses[0];
order = 1;
} else if (receivedCmd[0] == ISO14443A_CMD_WUPA) { // Received a WAKEUP } else if (receivedCmd[0] == ISO14443A_CMD_WUPA) { // Received a WAKEUP
p_response = &responses[0]; order = 6; p_response = &responses[0];
order = 6;
} else if (receivedCmd[1] == 0x20 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { // Received request for UID (cascade 1) } else if (receivedCmd[1] == 0x20 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { // Received request for UID (cascade 1)
p_response = &responses[1]; order = 2; p_response = &responses[1];
order = 2;
} else if (receivedCmd[1] == 0x20 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) { // Received request for UID (cascade 2) } else if (receivedCmd[1] == 0x20 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) { // Received request for UID (cascade 2)
p_response = &responses[2]; order = 20; p_response = &responses[2];
order = 20;
} else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { // Received a SELECT (cascade 1) } else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT) { // Received a SELECT (cascade 1)
p_response = &responses[3]; order = 3; p_response = &responses[3];
order = 3;
} else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) { // Received a SELECT (cascade 2) } else if (receivedCmd[1] == 0x70 && receivedCmd[0] == ISO14443A_CMD_ANTICOLL_OR_SELECT_2) { // Received a SELECT (cascade 2)
p_response = &responses[4]; order = 30; p_response = &responses[4];
order = 30;
} else if (receivedCmd[0] == ISO14443A_CMD_READBLOCK) { // Received a (plain) READ } else if (receivedCmd[0] == ISO14443A_CMD_READBLOCK) { // Received a (plain) READ
uint8_t block = receivedCmd[1]; uint8_t block = receivedCmd[1];
// if Ultralight or NTAG (4 byte blocks) // if Ultralight or NTAG (4 byte blocks)
@ -1200,7 +1237,8 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) {
EmSend4bit(CARD_NACK_NA); EmSend4bit(CARD_NACK_NA);
p_response = NULL; p_response = NULL;
} else { } else {
p_response = &responses[6]; order = 70; p_response = &responses[6];
order = 70;
} }
} else if (order == 7 && len == 8) { // Received {nr] and {ar} (part of authentication) } else if (order == 7 && len == 8) { // Received {nr] and {ar} (part of authentication)
LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true); LogTrace(receivedCmd, Uart.len, Uart.startTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.endTime * 16 - DELAY_AIR2ARM_AS_TAG, Uart.parity, true);
@ -1260,7 +1298,8 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) {
moebius_count++; moebius_count++;
break; break;
} }
default: break; default:
break;
} }
} }
p_response = NULL; p_response = NULL;
@ -1287,7 +1326,8 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) {
dynamic_response_info.response[1] = 0x90; dynamic_response_info.response[1] = 0x90;
dynamic_response_info.response[2] = 0x00; dynamic_response_info.response[2] = 0x00;
dynamic_response_info.response_n = 3; dynamic_response_info.response_n = 3;
} break; }
break;
case 0x0B: case 0x0B:
case 0x0A: { // IBlock (command CID) case 0x0A: { // IBlock (command CID)
dynamic_response_info.response[0] = receivedCmd[0]; dynamic_response_info.response[0] = receivedCmd[0];
@ -1295,32 +1335,37 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) {
dynamic_response_info.response[2] = 0x90; dynamic_response_info.response[2] = 0x90;
dynamic_response_info.response[3] = 0x00; dynamic_response_info.response[3] = 0x00;
dynamic_response_info.response_n = 4; dynamic_response_info.response_n = 4;
} break; }
break;
case 0x1A: case 0x1A:
case 0x1B: { // Chaining command case 0x1B: { // Chaining command
dynamic_response_info.response[0] = 0xaa | ((receivedCmd[0]) & 1); dynamic_response_info.response[0] = 0xaa | ((receivedCmd[0]) & 1);
dynamic_response_info.response_n = 2; dynamic_response_info.response_n = 2;
} break; }
break;
case 0xAA: case 0xAA:
case 0xBB: { case 0xBB: {
dynamic_response_info.response[0] = receivedCmd[0] ^ 0x11; dynamic_response_info.response[0] = receivedCmd[0] ^ 0x11;
dynamic_response_info.response_n = 2; dynamic_response_info.response_n = 2;
} break; }
break;
case 0xBA: { // ping / pong case 0xBA: { // ping / pong
dynamic_response_info.response[0] = 0xAB; dynamic_response_info.response[0] = 0xAB;
dynamic_response_info.response[1] = 0x00; dynamic_response_info.response[1] = 0x00;
dynamic_response_info.response_n = 2; dynamic_response_info.response_n = 2;
} break; }
break;
case 0xCA: case 0xCA:
case 0xC2: { // Readers sends deselect command case 0xC2: { // Readers sends deselect command
dynamic_response_info.response[0] = 0xCA; dynamic_response_info.response[0] = 0xCA;
dynamic_response_info.response[1] = 0x00; dynamic_response_info.response[1] = 0x00;
dynamic_response_info.response_n = 2; dynamic_response_info.response_n = 2;
} break; }
break;
default: { default: {
// Never seen this command before // Never seen this command before
@ -1329,7 +1374,8 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) {
Dbhexdump(len, receivedCmd, false); Dbhexdump(len, receivedCmd, false);
// Do not respond // Do not respond
dynamic_response_info.response_n = 0; dynamic_response_info.response_n = 0;
} break; }
break;
} }
if (dynamic_response_info.response_n > 0) { if (dynamic_response_info.response_n > 0) {
@ -1391,7 +1437,8 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) {
// prepare a delayed transfer. This simply shifts ToSend[] by a number // prepare a delayed transfer. This simply shifts ToSend[] by a number
// of bits specified in the delay parameter. // of bits specified in the delay parameter.
void PrepareDelayedTransfer(uint16_t delay) { void PrepareDelayedTransfer(uint16_t delay)
{
delay &= 0x07; delay &= 0x07;
if (!delay) return; if (!delay) return;
@ -1422,7 +1469,8 @@ void PrepareDelayedTransfer(uint16_t delay) {
// if == 0: transfer immediately and return time of transfer // if == 0: transfer immediately and return time of transfer
// if != 0: delay transfer until time specified // if != 0: delay transfer until time specified
//------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------
static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing) { static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing)
{
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
@ -1457,7 +1505,8 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing
} }
//iceman test //iceman test
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); (void)b; b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR);
(void)b;
} }
} }
@ -1467,7 +1516,8 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Prepare reader command (in bits, support short frames) to send to FPGA // Prepare reader command (in bits, support short frames) to send to FPGA
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, const uint8_t *parity) { void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, const uint8_t *parity)
{
int i, j; int i, j;
int last = 0; int last = 0;
uint8_t b; uint8_t b;
@ -1546,7 +1596,8 @@ void CodeIso14443aBitsAsReaderPar(const uint8_t *cmd, uint16_t bits, const uint8
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Prepare reader command to send to FPGA // Prepare reader command to send to FPGA
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void CodeIso14443aAsReaderPar(const uint8_t *cmd, uint16_t len, const uint8_t *parity) { void CodeIso14443aAsReaderPar(const uint8_t *cmd, uint16_t len, const uint8_t *parity)
{
CodeIso14443aBitsAsReaderPar(cmd, len * 8, parity); CodeIso14443aBitsAsReaderPar(cmd, len * 8, parity);
} }
@ -1555,7 +1606,8 @@ void CodeIso14443aAsReaderPar(const uint8_t *cmd, uint16_t len, const uint8_t *p
// Stop when button is pressed (return 1) or field was gone (return 2) // Stop when button is pressed (return 1) or field was gone (return 2)
// Or return 0 when command is captured // Or return 0 when command is captured
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity) { int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity)
{
*len = 0; *len = 0;
uint32_t timer = 0, vtime = 0; uint32_t timer = 0, vtime = 0;
@ -1600,8 +1652,7 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity) {
if (!timer) timer = vtime; if (!timer) timer = vtime;
// 50ms no field --> card to idle state // 50ms no field --> card to idle state
if (vtime - timer > 50) return 2; if (vtime - timer > 50) return 2;
} else } else if (timer) timer = 0;
if (timer) timer = 0;
analogCnt = 0; analogCnt = 0;
analogAVG = 0; analogAVG = 0;
} }
@ -1618,7 +1669,8 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity) {
} }
} }
int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen) { int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen)
{
volatile uint8_t b; volatile uint8_t b;
uint16_t i = 0; uint16_t i = 0;
uint32_t ThisTransferTime; uint32_t ThisTransferTime;
@ -1628,13 +1680,10 @@ int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD);
// Include correction bit if necessary // Include correction bit if necessary
if (Uart.bitCount == 7) if (Uart.bitCount == 7) {
{
// Short tags (7 bits) don't have parity, determine the correct value from MSB // Short tags (7 bits) don't have parity, determine the correct value from MSB
correctionNeeded = Uart.output[0] & 0x40; correctionNeeded = Uart.output[0] & 0x40;
} } else {
else
{
// The parity bits are left-aligned // The parity bits are left-aligned
correctionNeeded = Uart.parity[(Uart.len - 1) / 8] & (0x80 >> ((Uart.len - 1) & 7)); correctionNeeded = Uart.parity[(Uart.len - 1) / 8] & (0x80 >> ((Uart.len - 1) & 7));
} }
@ -1643,9 +1692,11 @@ int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen) {
// clear receiving shift register and holding register // clear receiving shift register and holding register
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)); while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY));
b = AT91C_BASE_SSC->SSC_RHR; (void) b; b = AT91C_BASE_SSC->SSC_RHR;
(void) b;
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)); while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY));
b = AT91C_BASE_SSC->SSC_RHR; (void) b; b = AT91C_BASE_SSC->SSC_RHR;
(void) b;
// wait for the FPGA to signal fdt_indicator == 1 (the FPGA is ready to queue new data in its delay line) // wait for the FPGA to signal fdt_indicator == 1 (the FPGA is ready to queue new data in its delay line)
for (uint8_t j = 0; j < 5; j++) { // allow timeout - better late than never for (uint8_t j = 0; j < 5; j++) { // allow timeout - better late than never
@ -1666,7 +1717,8 @@ int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen) {
} }
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); (void)b; b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR);
(void)b;
} }
if (BUTTON_PRESS()) break; if (BUTTON_PRESS()) break;
} }
@ -1684,7 +1736,8 @@ int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen) {
return 0; return 0;
} }
int EmSend4bit(uint8_t resp){ int EmSend4bit(uint8_t resp)
{
Code4bitAnswerAsTag(resp); Code4bitAnswerAsTag(resp);
int res = EmSendCmd14443aRaw(ToSend, ToSendMax); int res = EmSendCmd14443aRaw(ToSend, ToSendMax);
// do the tracing for the previous reader request and this tag answer: // do the tracing for the previous reader request and this tag answer:
@ -1702,10 +1755,12 @@ int EmSend4bit(uint8_t resp){
par); par);
return res; return res;
} }
int EmSendCmdPar(uint8_t *resp, uint16_t respLen, uint8_t *par) { int EmSendCmdPar(uint8_t *resp, uint16_t respLen, uint8_t *par)
{
return EmSendCmdParEx(resp, respLen, par, false); return EmSendCmdParEx(resp, respLen, par, false);
} }
int EmSendCmdParEx(uint8_t *resp, uint16_t respLen, uint8_t *par, bool collision){ int EmSendCmdParEx(uint8_t *resp, uint16_t respLen, uint8_t *par, bool collision)
{
CodeIso14443aAsTagPar(resp, respLen, par, collision); CodeIso14443aAsTagPar(resp, respLen, par, collision);
int res = EmSendCmd14443aRaw(ToSend, ToSendMax); int res = EmSendCmd14443aRaw(ToSend, ToSendMax);
// do the tracing for the previous reader request and this tag answer: // do the tracing for the previous reader request and this tag answer:
@ -1721,10 +1776,12 @@ int EmSendCmdParEx(uint8_t *resp, uint16_t respLen, uint8_t *par, bool collision
par); par);
return res; return res;
} }
int EmSendCmd(uint8_t *resp, uint16_t respLen){ int EmSendCmd(uint8_t *resp, uint16_t respLen)
{
return EmSendCmdEx(resp, respLen, false); return EmSendCmdEx(resp, respLen, false);
} }
int EmSendCmdEx(uint8_t *resp, uint16_t respLen, bool collision){ int EmSendCmdEx(uint8_t *resp, uint16_t respLen, bool collision)
{
uint8_t par[MAX_PARITY_SIZE] = {0x00}; uint8_t par[MAX_PARITY_SIZE] = {0x00};
GetParity(resp, respLen, par); GetParity(resp, respLen, par);
return EmSendCmdParEx(resp, respLen, par, collision); return EmSendCmdParEx(resp, respLen, par, collision);
@ -1754,7 +1811,8 @@ bool EmLogTrace(uint8_t *reader_data, uint16_t reader_len, uint32_t reader_Start
// If a response is captured return TRUE // If a response is captured return TRUE
// If it takes too long return FALSE // If it takes too long return FALSE
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset) { static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receivedResponsePar, uint16_t offset)
{
uint32_t c = 0; uint32_t c = 0;
// Set FPGA mode to "reader listen mode", no modulation (listen // Set FPGA mode to "reader listen mode", no modulation (listen
@ -1785,7 +1843,8 @@ static int GetIso14443aAnswerFromTag(uint8_t *receivedResponse, uint8_t *receive
} }
} }
void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t *timing) { void ReaderTransmitBitsPar(uint8_t *frame, uint16_t bits, uint8_t *par, uint32_t *timing)
{
CodeIso14443aBitsAsReaderPar(frame, bits, par); CodeIso14443aBitsAsReaderPar(frame, bits, par);
// Send command to tag // Send command to tag
@ -1795,32 +1854,37 @@ void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t
LogTrace(frame, nbytes(bits), (LastTimeProxToAirStart << 4) + DELAY_ARM2AIR_AS_READER, ((LastTimeProxToAirStart + LastProxToAirDuration) << 4) + DELAY_ARM2AIR_AS_READER, par, true); LogTrace(frame, nbytes(bits), (LastTimeProxToAirStart << 4) + DELAY_ARM2AIR_AS_READER, ((LastTimeProxToAirStart + LastProxToAirDuration) << 4) + DELAY_ARM2AIR_AS_READER, par, true);
} }
void ReaderTransmitPar(uint8_t* frame, uint16_t len, uint8_t *par, uint32_t *timing) { void ReaderTransmitPar(uint8_t *frame, uint16_t len, uint8_t *par, uint32_t *timing)
{
ReaderTransmitBitsPar(frame, len * 8, par, timing); ReaderTransmitBitsPar(frame, len * 8, par, timing);
} }
void ReaderTransmitBits(uint8_t* frame, uint16_t len, uint32_t *timing) { void ReaderTransmitBits(uint8_t *frame, uint16_t len, uint32_t *timing)
{
// Generate parity and redirect // Generate parity and redirect
uint8_t par[MAX_PARITY_SIZE] = {0x00}; uint8_t par[MAX_PARITY_SIZE] = {0x00};
GetParity(frame, len / 8, par); GetParity(frame, len / 8, par);
ReaderTransmitBitsPar(frame, len, par, timing); ReaderTransmitBitsPar(frame, len, par, timing);
} }
void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing) { void ReaderTransmit(uint8_t *frame, uint16_t len, uint32_t *timing)
{
// Generate parity and redirect // Generate parity and redirect
uint8_t par[MAX_PARITY_SIZE] = {0x00}; uint8_t par[MAX_PARITY_SIZE] = {0x00};
GetParity(frame, len, par); GetParity(frame, len, par);
ReaderTransmitBitsPar(frame, len * 8, par, timing); ReaderTransmitBitsPar(frame, len * 8, par, timing);
} }
int ReaderReceiveOffset(uint8_t* receivedAnswer, uint16_t offset, uint8_t *parity) { int ReaderReceiveOffset(uint8_t *receivedAnswer, uint16_t offset, uint8_t *parity)
{
if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, offset)) if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, offset))
return false; return false;
LogTrace(receivedAnswer, Demod.len, Demod.startTime * 16 - DELAY_AIR2ARM_AS_READER, Demod.endTime * 16 - DELAY_AIR2ARM_AS_READER, parity, false); LogTrace(receivedAnswer, Demod.len, Demod.startTime * 16 - DELAY_AIR2ARM_AS_READER, Demod.endTime * 16 - DELAY_AIR2ARM_AS_READER, parity, false);
return Demod.len; return Demod.len;
} }
int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity) { int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity)
{
if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, 0)) if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, 0))
return false; return false;
LogTrace(receivedAnswer, Demod.len, Demod.startTime * 16 - DELAY_AIR2ARM_AS_READER, Demod.endTime * 16 - DELAY_AIR2ARM_AS_READER, parity, false); LogTrace(receivedAnswer, Demod.len, Demod.startTime * 16 - DELAY_AIR2ARM_AS_READER, Demod.endTime * 16 - DELAY_AIR2ARM_AS_READER, parity, false);
@ -1830,7 +1894,8 @@ int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity) {
// This function misstreats the ISO 14443a anticollision procedure. // This function misstreats the ISO 14443a anticollision procedure.
// by fooling the reader there is a collision and forceing the reader to // by fooling the reader there is a collision and forceing the reader to
// increase the uid bytes. The might be an overflow, DoS will occure. // increase the uid bytes. The might be an overflow, DoS will occure.
void iso14443a_antifuzz(uint32_t flags){ void iso14443a_antifuzz(uint32_t flags)
{
// We need to listen to the high-frequency, peak-detected path. // We need to listen to the high-frequency, peak-detected path.
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN); iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
@ -1903,7 +1968,8 @@ void iso14443a_antifuzz(uint32_t flags){
BigBuf_free_keep_EM(); BigBuf_free_keep_EM();
} }
static void iso14a_set_ATS_times(uint8_t *ats) { static void iso14a_set_ATS_times(uint8_t *ats)
{
uint8_t tb1; uint8_t tb1;
uint8_t fwi, sfgi; uint8_t fwi, sfgi;
@ -1930,7 +1996,8 @@ static void iso14a_set_ATS_times(uint8_t *ats) {
} }
} }
static int GetATQA(uint8_t *resp, uint8_t *resp_par) { static int GetATQA(uint8_t *resp, uint8_t *resp_par)
{
#define WUPA_RETRY_TIMEOUT 10 // 10ms #define WUPA_RETRY_TIMEOUT 10 // 10ms
uint8_t wupa[] = { ISO14443A_CMD_WUPA }; // 0x26 - REQA 0x52 - WAKE-UP uint8_t wupa[] = { ISO14443A_CMD_WUPA }; // 0x26 - REQA 0x52 - WAKE-UP
@ -1959,7 +2026,8 @@ static int GetATQA(uint8_t *resp, uint8_t *resp_par) {
// if anticollision is false, then the UID must be provided in uid_ptr[] // if anticollision is false, then the UID must be provided in uid_ptr[]
// and num_cascades must be set (1: 4 Byte UID, 2: 7 Byte UID, 3: 10 Byte UID) // and num_cascades must be set (1: 4 Byte UID, 2: 7 Byte UID, 3: 10 Byte UID)
// requests ATS unless no_rats is true // requests ATS unless no_rats is true
int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats) { int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats)
{
uint8_t sel_all[] = { ISO14443A_CMD_ANTICOLL_OR_SELECT, 0x20 }; uint8_t sel_all[] = { ISO14443A_CMD_ANTICOLL_OR_SELECT, 0x20 };
uint8_t sel_uid[] = { ISO14443A_CMD_ANTICOLL_OR_SELECT, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t sel_uid[] = { ISO14443A_CMD_ANTICOLL_OR_SELECT, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@ -2116,7 +2184,8 @@ int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_card, uint32_
return 1; return 1;
} }
int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades) { int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades)
{
uint8_t sel_all[] = { ISO14443A_CMD_ANTICOLL_OR_SELECT, 0x20 }; uint8_t sel_all[] = { ISO14443A_CMD_ANTICOLL_OR_SELECT, 0x20 };
uint8_t sel_uid[] = { ISO14443A_CMD_ANTICOLL_OR_SELECT, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t sel_uid[] = { ISO14443A_CMD_ANTICOLL_OR_SELECT, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t resp[5] = {0}; // theoretically. A usual RATS will be much smaller uint8_t resp[5] = {0}; // theoretically. A usual RATS will be much smaller
@ -2168,7 +2237,8 @@ int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades) {
return 1; return 1;
} }
void iso14443a_setup(uint8_t fpga_minor_mode) { void iso14443a_setup(uint8_t fpga_minor_mode)
{
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Set up the synchronous serial port // Set up the synchronous serial port
@ -2219,7 +2289,8 @@ b8 b7 b6 b5 b4 b3 b2 b1
b5,b6 = 00 - DESELECT b5,b6 = 00 - DESELECT
11 - WTX 11 - WTX
*/ */
int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, uint8_t *res) { int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, uint8_t *res)
{
uint8_t parity[MAX_PARITY_SIZE] = {0x00}; uint8_t parity[MAX_PARITY_SIZE] = {0x00};
uint8_t real_cmd[cmd_len + 4]; uint8_t real_cmd[cmd_len + 4];
@ -2271,8 +2342,7 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, u
if (len >= 3 // PCB+CRC = 3 bytes if (len >= 3 // PCB+CRC = 3 bytes
&& ((data_bytes[0] & 0xC0) == 0 // I-Block && ((data_bytes[0] & 0xC0) == 0 // I-Block
|| (data_bytes[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0 || (data_bytes[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0
&& (data_bytes[0] & 0x01) == iso14_pcb_blocknum) // equal block numbers && (data_bytes[0] & 0x01) == iso14_pcb_blocknum) { // equal block numbers
{
iso14_pcb_blocknum ^= 1; iso14_pcb_blocknum ^= 1;
} }
@ -2306,7 +2376,8 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, u
// low :: len of commandbytes // low :: len of commandbytes
// arg2 timeout // arg2 timeout
// d.asBytes command bytes to send // d.asBytes command bytes to send
void ReaderIso14443a(UsbCommand *c) { void ReaderIso14443a(UsbCommand *c)
{
iso14a_command_t param = c->arg[0]; iso14a_command_t param = c->arg[0];
size_t len = c->arg[1] & 0xffff; size_t len = c->arg[1] & 0xffff;
size_t lenbits = c->arg[1] >> 16; size_t lenbits = c->arg[1] >> 16;
@ -2406,7 +2477,8 @@ OUT:
// Determine the distance between two nonces. // Determine the distance between two nonces.
// Assume that the difference is small, but we don't know which is first. // Assume that the difference is small, but we don't know which is first.
// Therefore try in alternating directions. // Therefore try in alternating directions.
int32_t dist_nt(uint32_t nt1, uint32_t nt2) { int32_t dist_nt(uint32_t nt1, uint32_t nt2)
{
if (nt1 == nt2) return 0; if (nt1 == nt2) return 0;
@ -2435,11 +2507,13 @@ int32_t dist_nt(uint32_t nt1, uint32_t nt2) {
// Cloning MiFare Classic Rail and Building Passes, Anywhere, Anytime" // Cloning MiFare Classic Rail and Building Passes, Anywhere, Anytime"
// (article by Nicolas T. Courtois, 2009) // (article by Nicolas T. Courtois, 2009)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype ) { void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype)
{
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD); iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
BigBuf_free(); BigBuf_Clear_ext(false); BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace(); clear_trace();
set_tracing(true); set_tracing(true);
@ -2512,10 +2586,17 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype ) {
continue; continue;
} }
switch (card_info.uidlen) { switch (card_info.uidlen) {
case 4 : cascade_levels = 1; break; case 4 :
case 7 : cascade_levels = 2; break; cascade_levels = 1;
case 10: cascade_levels = 3; break; break;
default: break; case 7 :
cascade_levels = 2;
break;
case 10:
cascade_levels = 3;
break;
default:
break;
} }
have_uid = true; have_uid = true;
} else { // no need for anticollision. We can directly select the card } else { // no need for anticollision. We can directly select the card
@ -2696,7 +2777,8 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype ) {
* Mifare Classic NACK-bug detection * Mifare Classic NACK-bug detection
* Thanks to @doegox for the feedback and new approaches. * Thanks to @doegox for the feedback and new approaches.
*/ */
void DetectNACKbug() { void DetectNACKbug()
{
uint8_t mf_auth[] = {0x60, 0x00, 0xF5, 0x7B}; uint8_t mf_auth[] = {0x60, 0x00, 0xF5, 0x7B};
uint8_t mf_nr_ar[] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t mf_nr_ar[] = {0, 0, 0, 0, 0, 0, 0, 0};
uint8_t uid[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t uid[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@ -2718,7 +2800,8 @@ void DetectNACKbug() {
// Mifare Classic's random generator repeats every 2^16 cycles (and so do the nonces). // Mifare Classic's random generator repeats every 2^16 cycles (and so do the nonces).
uint32_t sync_cycles = PRNG_SEQUENCE_LENGTH; uint32_t sync_cycles = PRNG_SEQUENCE_LENGTH;
BigBuf_free(); BigBuf_Clear_ext(false); BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace(); clear_trace();
set_tracing(true); set_tracing(true);
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD); iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
@ -2753,10 +2836,17 @@ void DetectNACKbug() {
continue; continue;
} }
switch (card_info.uidlen) { switch (card_info.uidlen) {
case 4 : cascade_levels = 1; break; case 4 :
case 7 : cascade_levels = 2; break; cascade_levels = 1;
case 10: cascade_levels = 3; break; break;
default: break; case 7 :
cascade_levels = 2;
break;
case 10:
cascade_levels = 3;
break;
default:
break;
} }
have_uid = true; have_uid = true;
} else { // no need for anticollision. We can directly select the card } else { // no need for anticollision. We can directly select the card
@ -2923,7 +3013,8 @@ void DetectNACKbug() {
*@param exitAfterNReads, exit simulation after n blocks have been read, 0 is inifite *@param exitAfterNReads, exit simulation after n blocks have been read, 0 is inifite
* (unless reader attack mode enabled then it runs util it gets enough nonces to recover all keys attmpted) * (unless reader attack mode enabled then it runs util it gets enough nonces to recover all keys attmpted)
*/ */
void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *datain) { void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *datain)
{
int cardSTATE = MFEMUL_NOFIELD; int cardSTATE = MFEMUL_NOFIELD;
int _UID_LEN = 0; // 4, 7, 10 int _UID_LEN = 0; // 4, 7, 10
@ -3142,7 +3233,8 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
case 10: case 10:
cardSTATE = MFEMUL_SELECT2; cardSTATE = MFEMUL_SELECT2;
continue; continue;
default:break; default:
break;
} }
} else { } else {
cardSTATE_TO_IDLE(); cardSTATE_TO_IDLE();
@ -3173,7 +3265,8 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
case 10: case 10:
cardSTATE = MFEMUL_SELECT3; cardSTATE = MFEMUL_SELECT3;
continue; continue;
default:break; default:
break;
} }
} }
cardSTATE_TO_IDLE(); cardSTATE_TO_IDLE();
@ -3263,7 +3356,8 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
ar_nr_nonces[index].keytype = 0; ar_nr_nonces[index].keytype = 0;
break; break;
} }
default: break; default:
break;
} }
} }

View file

@ -77,7 +77,8 @@ static struct {
uint8_t *output; uint8_t *output;
} Uart; } Uart;
static void UartReset() { static void UartReset()
{
Uart.state = STATE_UNSYNCD; Uart.state = STATE_UNSYNCD;
Uart.shiftReg = 0; Uart.shiftReg = 0;
Uart.bitCnt = 0; Uart.bitCnt = 0;
@ -86,7 +87,8 @@ static void UartReset() {
Uart.posCnt = 0; Uart.posCnt = 0;
} }
static void UartInit(uint8_t *data) { static void UartInit(uint8_t *data)
{
Uart.output = data; Uart.output = data;
UartReset(); UartReset();
// memset(Uart.output, 0x00, MAX_FRAME_SIZE); // memset(Uart.output, 0x00, MAX_FRAME_SIZE);
@ -120,7 +122,8 @@ static struct {
} Demod; } Demod;
// Clear out the state of the "UART" that receives from the tag. // Clear out the state of the "UART" that receives from the tag.
static void DemodReset() { static void DemodReset()
{
Demod.state = DEMOD_UNSYNCD; Demod.state = DEMOD_UNSYNCD;
Demod.bitCount = 0; Demod.bitCount = 0;
Demod.posCount = 0; Demod.posCount = 0;
@ -133,7 +136,8 @@ static void DemodReset() {
Demod.endTime = 0; Demod.endTime = 0;
} }
static void DemodInit(uint8_t *data) { static void DemodInit(uint8_t *data)
{
Demod.output = data; Demod.output = data;
DemodReset(); DemodReset();
// memset(Demod.output, 0x00, MAX_FRAME_SIZE); // memset(Demod.output, 0x00, MAX_FRAME_SIZE);
@ -153,7 +157,8 @@ static void DemodInit(uint8_t *data) {
* 13560000000 / 384000 = 35312 FWT * 13560000000 / 384000 = 35312 FWT
* @param timeout is in frame wait time, fwt, measured in ETUs * @param timeout is in frame wait time, fwt, measured in ETUs
*/ */
static void iso14b_set_timeout(uint32_t timeout) { static void iso14b_set_timeout(uint32_t timeout)
{
#define MAX_TIMEOUT 40542464 // 13560000Hz * 1000ms / (2^32-1) * (8*16) #define MAX_TIMEOUT 40542464 // 13560000Hz * 1000ms / (2^32-1) * (8*16)
if (timeout > MAX_TIMEOUT) if (timeout > MAX_TIMEOUT)
timeout = MAX_TIMEOUT; timeout = MAX_TIMEOUT;
@ -161,7 +166,8 @@ static void iso14b_set_timeout(uint32_t timeout) {
iso14b_timeout = timeout; iso14b_timeout = timeout;
if (MF_DBGLEVEL >= 3) Dbprintf("ISO14443B Timeout set to %ld fwt", iso14b_timeout); if (MF_DBGLEVEL >= 3) Dbprintf("ISO14443B Timeout set to %ld fwt", iso14b_timeout);
} }
static void iso14b_set_maxframesize(uint16_t size) { static void iso14b_set_maxframesize(uint16_t size)
{
if (size > 256) if (size > 256)
size = MAX_FRAME_SIZE; size = MAX_FRAME_SIZE;
@ -174,7 +180,8 @@ static void iso14b_set_maxframesize(uint16_t size) {
// that here) so that they can be transmitted to the reader. Doesn't transmit // that here) so that they can be transmitted to the reader. Doesn't transmit
// them yet, just leaves them ready to send in ToSend[]. // them yet, just leaves them ready to send in ToSend[].
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void CodeIso14443bAsTag(const uint8_t *cmd, int len) { static void CodeIso14443bAsTag(const uint8_t *cmd, int len)
{
/* ISO 14443 B /* ISO 14443 B
* *
* Reader to card | ASK - Amplitude Shift Keying Modulation (PCD to PICC for Type B) (NRZ-L encodig) * Reader to card | ASK - Amplitude Shift Keying Modulation (PCD to PICC for Type B) (NRZ-L encodig)
@ -316,7 +323,8 @@ static void CodeIso14443bAsTag(const uint8_t *cmd, int len) {
* Returns: true if we received a EOF * Returns: true if we received a EOF
* false if we are still waiting for some more * false if we are still waiting for some more
*/ */
static RAMFUNC int Handle14443bReaderUartBit(uint8_t bit) { static RAMFUNC int Handle14443bReaderUartBit(uint8_t bit)
{
switch (Uart.state) { switch (Uart.state) {
case STATE_UNSYNCD: case STATE_UNSYNCD:
if (!bit) { if (!bit) {
@ -385,8 +393,7 @@ static RAMFUNC int Handle14443bReaderUartBit(uint8_t bit) {
Uart.posCnt = 0; Uart.posCnt = 0;
} }
if (Uart.bitCnt == 10) { if (Uart.bitCnt == 10) {
if ((Uart.shiftReg & 0x200) && !(Uart.shiftReg & 0x001)) if ((Uart.shiftReg & 0x200) && !(Uart.shiftReg & 0x001)) {
{
// this is a data byte, with correct // this is a data byte, with correct
// start and stop bits // start and stop bits
Uart.output[Uart.byteCnt] = (Uart.shiftReg >> 1) & 0xff; Uart.output[Uart.byteCnt] = (Uart.shiftReg >> 1) & 0xff;
@ -433,7 +440,8 @@ static RAMFUNC int Handle14443bReaderUartBit(uint8_t bit) {
// Assume that we're called with the SSC (to the FPGA) and ADC path set // Assume that we're called with the SSC (to the FPGA) and ADC path set
// correctly. // correctly.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static int GetIso14443bCommandFromReader(uint8_t *received, uint16_t *len) { static int GetIso14443bCommandFromReader(uint8_t *received, uint16_t *len)
{
// Set FPGA mode to "simulated ISO 14443B tag", no modulation (listen // Set FPGA mode to "simulated ISO 14443B tag", no modulation (listen
// only, since we are receiving, not transmitting). // only, since we are receiving, not transmitting).
// Signal field is off with the appropriate LED // Signal field is off with the appropriate LED
@ -485,18 +493,21 @@ static int GetIso14443bCommandFromReader(uint8_t *received, uint16_t *len) {
return false; return false;
} }
void ClearFpgaShiftingRegisters(void){ void ClearFpgaShiftingRegisters(void)
{
volatile uint8_t b; volatile uint8_t b;
// clear receiving shift register and holding register // clear receiving shift register and holding register
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) {}; while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) {};
b = AT91C_BASE_SSC->SSC_RHR; (void) b; b = AT91C_BASE_SSC->SSC_RHR;
(void) b;
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) {}; while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY)) {};
b = AT91C_BASE_SSC->SSC_RHR; (void) b; b = AT91C_BASE_SSC->SSC_RHR;
(void) b;
// wait for the FPGA to signal fdt_indicator == 1 (the FPGA is ready to queue new data in its delay line) // wait for the FPGA to signal fdt_indicator == 1 (the FPGA is ready to queue new data in its delay line)
for (uint8_t j = 0; j < 5; j++) { // allow timeout - better late than never for (uint8_t j = 0; j < 5; j++) { // allow timeout - better late than never
@ -508,7 +519,8 @@ void ClearFpgaShiftingRegisters(void){
//AT91C_BASE_SSC->SSC_THR = 0xFF; //AT91C_BASE_SSC->SSC_THR = 0xFF;
} }
void WaitForFpgaDelayQueueIsEmpty( uint16_t delay ){ void WaitForFpgaDelayQueueIsEmpty(uint16_t delay)
{
// Ensure that the FPGA Delay Queue is empty before we switch to TAGSIM_LISTEN again: // Ensure that the FPGA Delay Queue is empty before we switch to TAGSIM_LISTEN again:
uint8_t fpga_queued_bits = delay >> 3; // twich /8 ?? >>3, uint8_t fpga_queued_bits = delay >> 3; // twich /8 ?? >>3,
for (uint8_t i = 0; i <= fpga_queued_bits / 8 + 1;) { for (uint8_t i = 0; i <= fpga_queued_bits / 8 + 1;) {
@ -519,7 +531,8 @@ void WaitForFpgaDelayQueueIsEmpty( uint16_t delay ){
} }
} }
static void TransmitFor14443b_AsTag( uint8_t *response, uint16_t len) { static void TransmitFor14443b_AsTag(uint8_t *response, uint16_t len)
{
volatile uint32_t b; volatile uint32_t b;
@ -545,7 +558,8 @@ static void TransmitFor14443b_AsTag( uint8_t *response, uint16_t len) {
// Prevent rx holding register from overflowing // Prevent rx holding register from overflowing
if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { if (AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
b = AT91C_BASE_SSC->SSC_RHR;(void)b; b = AT91C_BASE_SSC->SSC_RHR;
(void)b;
} }
} }
@ -556,7 +570,8 @@ static void TransmitFor14443b_AsTag( uint8_t *response, uint16_t len) {
// Main loop of simulated tag: receive commands from reader, decide what // Main loop of simulated tag: receive commands from reader, decide what
// response to send, and send it. // response to send, and send it.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void SimulateIso14443bTag(uint32_t pupi) { void SimulateIso14443bTag(uint32_t pupi)
{
// setup device. // setup device.
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
@ -566,7 +581,8 @@ void SimulateIso14443bTag(uint32_t pupi) {
FpgaSetupSsc(); FpgaSetupSsc();
// allocate command receive buffer // allocate command receive buffer
BigBuf_free(); BigBuf_Clear_ext(false); BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace(); //sim clear_trace(); //sim
set_tracing(true); set_tracing(true);
@ -590,7 +606,8 @@ void SimulateIso14443bTag(uint32_t pupi) {
// supports only 106kBit/s in both directions, max frame size = 32Bytes, // supports only 106kBit/s in both directions, max frame size = 32Bytes,
// supports ISO14443-4, FWI=8 (77ms), NAD supported, CID not supported: // supports ISO14443-4, FWI=8 (77ms), NAD supported, CID not supported:
uint8_t respATQB[] = { 0x50, 0x82, 0x0d, 0xe1, 0x74, 0x20, 0x38, 0x19, uint8_t respATQB[] = { 0x50, 0x82, 0x0d, 0xe1, 0x74, 0x20, 0x38, 0x19,
0x22, 0x00, 0x21, 0x85, 0x5e, 0xd7 }; 0x22, 0x00, 0x21, 0x85, 0x5e, 0xd7
};
// response to HLTB and ATTRIB // response to HLTB and ATTRIB
static const uint8_t respOK[] = {0x00, 0x78, 0xF0}; static const uint8_t respOK[] = {0x00, 0x78, 0xF0};
@ -704,7 +721,8 @@ void SimulateIso14443bTag(uint32_t pupi) {
} }
break; break;
} }
default: break; default:
break;
} }
++cmdsReceived; ++cmdsReceived;
@ -735,7 +753,8 @@ void SimulateIso14443bTag(uint32_t pupi) {
* false if we are still waiting for some more * false if we are still waiting for some more
* *
*/ */
static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) { static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq)
{
int v = 0, myI = ABS(ci), myQ = ABS(cq); int v = 0, myI = ABS(ci), myQ = ABS(cq);
// The soft decision on the bit uses an estimate of just the // The soft decision on the bit uses an estimate of just the
@ -939,7 +958,8 @@ static RAMFUNC int Handle14443bTagSamplesDemod(int ci, int cq) {
* Demodulate the samples we received from the tag, also log to tracebuffer * Demodulate the samples we received from the tag, also log to tracebuffer
* quiet: set to 'TRUE' to disable debug output * quiet: set to 'TRUE' to disable debug output
*/ */
static void GetTagSamplesFor14443bDemod() { static void GetTagSamplesFor14443bDemod()
{
bool gotFrame = false, finished = false; bool gotFrame = false, finished = false;
int lastRxCounter = ISO14443B_DMA_BUFFER_SIZE; int lastRxCounter = ISO14443B_DMA_BUFFER_SIZE;
int ci = 0, cq = 0; int ci = 0, cq = 0;
@ -1005,7 +1025,8 @@ static void GetTagSamplesFor14443bDemod() {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Transmit the command (to the tag) that was placed in ToSend[]. // Transmit the command (to the tag) that was placed in ToSend[].
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void TransmitFor14443b_AsReader(void) { static void TransmitFor14443b_AsReader(void)
{
int c; int c;
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX | FPGA_HF_READER_TX_SHALLOW_MOD);
@ -1039,7 +1060,8 @@ static void TransmitFor14443b_AsReader(void) {
// Code a layer 2 command (string of octets, including CRC) into ToSend[], // Code a layer 2 command (string of octets, including CRC) into ToSend[],
// so that it is ready to transmit to the tag using TransmitFor14443b(). // so that it is ready to transmit to the tag using TransmitFor14443b().
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void CodeIso14443bAsReader(const uint8_t *cmd, int len) { static void CodeIso14443bAsReader(const uint8_t *cmd, int len)
{
/* /*
* Reader data transmission: * Reader data transmission:
* - no modulation ONES * - no modulation ONES
@ -1120,7 +1142,8 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len) {
/* /*
* Convenience function to encode, transmit and trace iso 14443b comms * Convenience function to encode, transmit and trace iso 14443b comms
*/ */
static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len) { static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len)
{
uint32_t time_start = GetCountSspClk(); uint32_t time_start = GetCountSspClk();
@ -1136,7 +1159,8 @@ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len) {
/* Sends an APDU to the tag /* Sends an APDU to the tag
* TODO: check CRC and preamble * TODO: check CRC and preamble
*/ */
uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response) { uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response)
{
uint8_t message_frame[message_length + 4]; uint8_t message_frame[message_length + 4];
// PCB // PCB
@ -1170,7 +1194,8 @@ uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *r
/** /**
* SRx Initialise. * SRx Initialise.
*/ */
uint8_t iso14443b_select_srx_card(iso14b_card_select_t *card ) { uint8_t iso14443b_select_srx_card(iso14b_card_select_t *card)
{
// INITIATE command: wake up the tag using the INITIATE // INITIATE command: wake up the tag using the INITIATE
static const uint8_t init_srx[] = { ISO14443B_INITIATE, 0x00, 0x97, 0x5b }; static const uint8_t init_srx[] = { ISO14443B_INITIATE, 0x00, 0x97, 0x5b };
// SELECT command (with space for CRC) // SELECT command (with space for CRC)
@ -1230,7 +1255,8 @@ uint8_t iso14443b_select_srx_card(iso14b_card_select_t *card ) {
* TODO: Support multiple cards (perform anticollision) * TODO: Support multiple cards (perform anticollision)
* TODO: Verify CRC checksums * TODO: Verify CRC checksums
*/ */
uint8_t iso14443b_select_card(iso14b_card_select_t *card ) { uint8_t iso14443b_select_card(iso14b_card_select_t *card)
{
// WUPB command (including CRC) // WUPB command (including CRC)
// Note: WUPB wakes up all tags, REQB doesn't wake up tags in HALT state // Note: WUPB wakes up all tags, REQB doesn't wake up tags in HALT state
static const uint8_t wupb[] = { ISO14443B_REQB, 0x00, 0x08, 0x39, 0x73 }; static const uint8_t wupb[] = { ISO14443B_REQB, 0x00, 0x08, 0x39, 0x73 };
@ -1302,7 +1328,8 @@ uint8_t iso14443b_select_card(iso14b_card_select_t *card ) {
// Set up ISO 14443 Type B communication (similar to iso14443a_setup) // Set up ISO 14443 Type B communication (similar to iso14443a_setup)
// field is setup for "Sending as Reader" // field is setup for "Sending as Reader"
void iso14443b_setup() { void iso14443b_setup()
{
LEDsoff(); LEDsoff();
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
@ -1335,7 +1362,8 @@ void iso14443b_setup() {
// //
// I tried to be systematic and check every answer of the tag, every CRC, etc... // I tried to be systematic and check every answer of the tag, every CRC, etc...
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static bool ReadSTBlock(uint8_t block) { static bool ReadSTBlock(uint8_t block)
{
uint8_t cmd[] = {ISO14443B_READ_BLK, block, 0x00, 0x00}; uint8_t cmd[] = {ISO14443B_READ_BLK, block, 0x00, 0x00};
AddCrc14B(cmd, 2); AddCrc14B(cmd, 2);
CodeAndTransmit14443bAsReader(cmd, sizeof(cmd)); CodeAndTransmit14443bAsReader(cmd, sizeof(cmd));
@ -1353,7 +1381,8 @@ static bool ReadSTBlock(uint8_t block) {
} }
return true; return true;
} }
void ReadSTMemoryIso14443b(uint8_t numofblocks) { void ReadSTMemoryIso14443b(uint8_t numofblocks)
{
// Make sure that we start from off, since the tags are stateful; // Make sure that we start from off, since the tags are stateful;
// confusing things will happen if we don't reset them between reads. // confusing things will happen if we don't reset them between reads.
//switch_off(); //switch_off();
@ -1402,7 +1431,8 @@ out:
SpinDelay(20); SpinDelay(20);
} }
static void iso1444b_setup_sniff(void){ static void iso1444b_setup_sniff(void)
{
LEDsoff(); LEDsoff();
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
@ -1455,7 +1485,8 @@ static void iso1444b_setup_sniff(void){
* DMA Buffer - ISO14443B_DMA_BUFFER_SIZE * DMA Buffer - ISO14443B_DMA_BUFFER_SIZE
* Demodulated samples received - all the rest * Demodulated samples received - all the rest
*/ */
void RAMFUNC SniffIso14443b(void) { void RAMFUNC SniffIso14443b(void)
{
uint32_t time_0 = 0, time_start = 0, time_stop = 0; uint32_t time_0 = 0, time_start = 0, time_stop = 0;
int ci = 0, cq = 0; int ci = 0, cq = 0;
@ -1547,7 +1578,8 @@ void RAMFUNC SniffIso14443b(void) {
switch_off(); switch_off();
} }
void iso14b_set_trigger(bool enable) { void iso14b_set_trigger(bool enable)
{
trigger = enable; trigger = enable;
} }
@ -1562,7 +1594,8 @@ void iso14b_set_trigger(bool enable) {
* none * none
* *
*/ */
void SendRawCommand14443B_Ex(UsbCommand *c) { void SendRawCommand14443B_Ex(UsbCommand *c)
{
iso14b_command_t param = c->arg[0]; iso14b_command_t param = c->arg[0];
size_t len = c->arg[1] & 0xffff; size_t len = c->arg[1] & 0xffff;
uint8_t *cmd = c->d.asBytes; uint8_t *cmd = c->d.asBytes;

View file

@ -99,7 +99,8 @@ static void BuildInventoryResponse(uint8_t *cmdout, uint8_t *uid);
// resulting data rate is 26,48 kbit/s (fc/512) // resulting data rate is 26,48 kbit/s (fc/512)
// cmd ... data // cmd ... data
// n ... length of data // n ... length of data
static void CodeIso15693AsReader(uint8_t *cmd, int n) { static void CodeIso15693AsReader(uint8_t *cmd, int n)
{
int i, j; int i, j;
ToSendReset(); ToSendReset();
@ -178,7 +179,8 @@ static void CodeIso15693AsReader(uint8_t *cmd, int n) {
// encode data using "1 out of 256" sheme // encode data using "1 out of 256" sheme
// data rate is 1,66 kbit/s (fc/8192) // data rate is 1,66 kbit/s (fc/8192)
// is designed for more robust communication over longer distances // is designed for more robust communication over longer distances
static void CodeIso15693AsReader256(uint8_t *cmd, int n) { static void CodeIso15693AsReader256(uint8_t *cmd, int n)
{
int i, j; int i, j;
ToSendReset(); ToSendReset();
@ -220,7 +222,8 @@ static void CodeIso15693AsReader256(uint8_t *cmd, int n) {
} }
// Transmit the command (to the tag) that was placed in ToSend[]. // Transmit the command (to the tag) that was placed in ToSend[].
static void TransmitTo15693Tag(const uint8_t *cmd, int len, int *samples, int *wait) { static void TransmitTo15693Tag(const uint8_t *cmd, int len, int *samples, int *wait)
{
int c; int c;
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
@ -255,7 +258,8 @@ static void TransmitTo15693Tag(const uint8_t *cmd, int len, int *samples, int *w
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Transmit the command (to the reader) that was placed in ToSend[]. // Transmit the command (to the reader) that was placed in ToSend[].
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void TransmitTo15693Reader(const uint8_t *cmd, int len, int *samples, int *wait) { static void TransmitTo15693Reader(const uint8_t *cmd, int len, int *samples, int *wait)
{
int c = 0; int c = 0;
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_424K); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_MODULATE_424K);
@ -288,7 +292,8 @@ static void TransmitTo15693Reader(const uint8_t *cmd, int len, int *samples, int
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// DEMODULATE tag answer // DEMODULATE tag answer
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static int DemodAnswer(uint8_t *received, uint8_t *dest, uint16_t samplecount) { static int DemodAnswer(uint8_t *received, uint8_t *dest, uint16_t samplecount)
{
int i, j; int i, j;
int max = 0, maxPos = 0, skip = 4; int max = 0, maxPos = 0, skip = 4;
@ -381,7 +386,8 @@ static int DemodAnswer(uint8_t *received, uint8_t *dest, uint16_t samplecount) {
// returns: // returns:
// number of decoded bytes // number of decoded bytes
// logging enabled // logging enabled
static int GetIso15693AnswerFromTag(uint8_t *received, int *elapsed) { static int GetIso15693AnswerFromTag(uint8_t *received, int *elapsed)
{
#define SIGNAL_BUFF_SIZE 15000 #define SIGNAL_BUFF_SIZE 15000
// get current clock // get current clock
@ -435,7 +441,8 @@ static int GetIso15693AnswerFromTag(uint8_t *received, int *elapsed) {
// Now the GetISO15693 message from sniffing command // Now the GetISO15693 message from sniffing command
// logging enable, // logging enable,
static int GetIso15693AnswerFromSniff(uint8_t *received, int *samples, int *elapsed) { static int GetIso15693AnswerFromSniff(uint8_t *received, int *samples, int *elapsed)
{
bool getNext = false; bool getNext = false;
int counter = 0, ci = 0, cq = 0; int counter = 0, ci = 0, cq = 0;
@ -483,7 +490,8 @@ static int GetIso15693AnswerFromSniff(uint8_t *received, int *samples, int *elap
// for the response. The response is not demodulated, just left in the buffer // for the response. The response is not demodulated, just left in the buffer
// so that it can be downloaded to a PC and processed there. // so that it can be downloaded to a PC and processed there.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void AcquireRawAdcSamplesIso15693(void) { void AcquireRawAdcSamplesIso15693(void)
{
int c = 0, getNext = false; int c = 0, getNext = false;
int ci = 0, cq = 0; int ci = 0, cq = 0;
@ -549,7 +557,8 @@ void AcquireRawAdcSamplesIso15693(void) {
} }
// switch_off, initreader, no logging // switch_off, initreader, no logging
void RecordRawAdcSamplesIso15693(void) { void RecordRawAdcSamplesIso15693(void)
{
int c = 0, getNext = false; int c = 0, getNext = false;
int ci = 0, cq = 0; int ci = 0, cq = 0;
@ -589,7 +598,8 @@ void RecordRawAdcSamplesIso15693(void) {
// Initialize the proxmark as iso15k reader // Initialize the proxmark as iso15k reader
// (this might produces glitches that confuse some tags // (this might produces glitches that confuse some tags
void Iso15693InitReader(void) { void Iso15693InitReader(void)
{
LEDsoff(); LEDsoff();
clear_trace(); clear_trace();
set_tracing(true); set_tracing(true);
@ -621,7 +631,8 @@ void Iso15693InitReader(void) {
// Encode (into the ToSend buffers) an identify request, which is the first // Encode (into the ToSend buffers) an identify request, which is the first
// thing that you must send to a tag to get a response. // thing that you must send to a tag to get a response.
static void BuildIdentifyRequest(uint8_t *out) { static void BuildIdentifyRequest(uint8_t *out)
{
uint8_t cmd[CMD_ID_RESP] = {0, ISO15_CMD_INVENTORY, 0, 0, 0}; uint8_t cmd[CMD_ID_RESP] = {0, ISO15_CMD_INVENTORY, 0, 0, 0};
// flags // flags
@ -665,7 +676,8 @@ static void BuildReadBlockRequest(uint8_t **out, uint8_t *uid, uint8_t blockNumb
*/ */
// Now the VICC>VCD responses when we are simulating a tag // Now the VICC>VCD responses when we are simulating a tag
static void BuildInventoryResponse(uint8_t *out, uint8_t *uid) { static void BuildInventoryResponse(uint8_t *out, uint8_t *uid)
{
uint8_t cmd[CMD_INV_RESP] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t cmd[CMD_INV_RESP] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@ -696,7 +708,8 @@ static void BuildInventoryResponse(uint8_t *out, uint8_t *uid) {
// If you do not need the answer use NULL for *recv[] // If you do not need the answer use NULL for *recv[]
// return: lenght of received data // return: lenght of received data
// logging enabled // logging enabled
int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *outdata) { int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *outdata)
{
int t_samples = 0, wait = 0, elapsed = 0, answer_len = 0; int t_samples = 0, wait = 0, elapsed = 0, answer_len = 0;
@ -734,7 +747,8 @@ int SendDataTag(uint8_t *send, int sendlen, bool init, int speed, uint8_t *outda
// Decodes a message from a tag and displays its metadata and content // Decodes a message from a tag and displays its metadata and content
#define DBD15STATLEN 48 #define DBD15STATLEN 48
void DbdecodeIso15693Answer(int len, uint8_t *d) { void DbdecodeIso15693Answer(int len, uint8_t *d)
{
char status[DBD15STATLEN + 1] = {0}; char status[DBD15STATLEN + 1] = {0};
if (len > 3) { if (len > 3) {
@ -798,7 +812,8 @@ void DbdecodeIso15693Answer(int len, uint8_t *d) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// ok // ok
// parameter is unused !?! // parameter is unused !?!
void ReaderIso15693(uint32_t parameter) { void ReaderIso15693(uint32_t parameter)
{
int answerLen1 = 0; int answerLen1 = 0;
int tsamples = 0, wait = 0, elapsed = 0; int tsamples = 0, wait = 0, elapsed = 0;
@ -862,7 +877,8 @@ void ReaderIso15693(uint32_t parameter) {
// Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands // Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands
// all demodulation performed in arm rather than host. - greg // all demodulation performed in arm rather than host. - greg
void SimTagIso15693(uint32_t parameter, uint8_t *uid) { void SimTagIso15693(uint32_t parameter, uint8_t *uid)
{
LEDsoff(); LEDsoff();
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
@ -916,7 +932,8 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid) {
// Since there is no standardized way of reading the AFI out of a tag, we will brute force it // Since there is no standardized way of reading the AFI out of a tag, we will brute force it
// (some manufactures offer a way to read the AFI, though) // (some manufactures offer a way to read the AFI, though)
void BruteforceIso15693Afi(uint32_t speed) { void BruteforceIso15693Afi(uint32_t speed)
{
uint8_t data[7] = {0, 0, 0, 0, 0, 0, 0}; uint8_t data[7] = {0, 0, 0, 0, 0, 0, 0};
uint8_t buf[ISO15_MAX_FRAME]; uint8_t buf[ISO15_MAX_FRAME];
@ -970,7 +987,8 @@ void BruteforceIso15693Afi(uint32_t speed) {
// Allows to directly send commands to the tag via the client // Allows to directly send commands to the tag via the client
// Has to increase dialog between device and client. // Has to increase dialog between device and client.
void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t *data) { void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t *data)
{
bool init = true; bool init = true;
int buflen = 0; int buflen = 0;

View file

@ -56,7 +56,8 @@ static uint32_t last_frame_end; /* ts of last bit of previews rx or tx frame */
// I/O interface abstraction (FPGA -> ARM) // I/O interface abstraction (FPGA -> ARM)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static inline uint8_t rx_byte_from_fpga() { static inline uint8_t rx_byte_from_fpga()
{
for (;;) { for (;;) {
WDT_HIT(); WDT_HIT();
@ -83,9 +84,12 @@ static inline uint8_t rx_byte_from_fpga() {
// //
// Note: The SSC receiver is never synchronized the calculation may be performed // Note: The SSC receiver is never synchronized the calculation may be performed
// on a i/q pair from two subsequent correlations, but does not matter. // on a i/q pair from two subsequent correlations, but does not matter.
static inline int32_t sample_power() { static inline int32_t sample_power()
int32_t q = (int8_t)rx_byte_from_fpga(); q = ABS(q); {
int32_t i = (int8_t)rx_byte_from_fpga(); i = ABS(i); int32_t q = (int8_t)rx_byte_from_fpga();
q = ABS(q);
int32_t i = (int8_t)rx_byte_from_fpga();
i = ABS(i);
return MAX(i, q) + (MIN(i, q) >> 1); return MAX(i, q) + (MIN(i, q) >> 1);
} }
@ -97,7 +101,8 @@ static inline int32_t sample_power() {
// //
// Note: The demodulator would be drifting (18.9us * 5 != 100us), rx_frame // Note: The demodulator would be drifting (18.9us * 5 != 100us), rx_frame
// has a delay loop that aligns rx_bit calls to the TAG tx timeslots. // has a delay loop that aligns rx_bit calls to the TAG tx timeslots.
static inline bool rx_bit() { static inline bool rx_bit()
{
int32_t power; int32_t power;
for (size_t i = 0; i < 5; ++i) { for (size_t i = 0; i < 5; ++i) {
@ -116,7 +121,8 @@ static inline bool rx_bit() {
// be circumvented, but the adventage over bitbang would be little. // be circumvented, but the adventage over bitbang would be little.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static inline void tx_bit(bool bit) { static inline void tx_bit(bool bit)
{
// insert pause // insert pause
LOW(GPIO_SSC_DOUT); LOW(GPIO_SSC_DOUT);
last_frame_end += RWD_TIME_PAUSE; last_frame_end += RWD_TIME_PAUSE;
@ -138,7 +144,8 @@ static inline void tx_bit(bool bit) {
// present. // present.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void tx_frame(uint32_t frame, uint8_t len) { static void tx_frame(uint32_t frame, uint8_t len)
{
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
// wait for next tx timeslot // wait for next tx timeslot
@ -166,7 +173,8 @@ static void tx_frame(uint32_t frame, uint8_t len) {
LogTrace(cmdbytes, sizeof(cmdbytes), last_frame_start, last_frame_end, NULL, true); LogTrace(cmdbytes, sizeof(cmdbytes), last_frame_start, last_frame_end, NULL, true);
} }
static uint32_t rx_frame(uint8_t len) { static uint32_t rx_frame(uint8_t len)
{
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
| FPGA_HF_READER_RX_XCORR_848_KHZ | FPGA_HF_READER_RX_XCORR_848_KHZ
| FPGA_HF_READER_RX_XCORR_QUARTER); | FPGA_HF_READER_RX_XCORR_QUARTER);
@ -195,7 +203,8 @@ static uint32_t rx_frame(uint8_t len) {
return frame; return frame;
} }
static bool rx_ack() { static bool rx_ack()
{
// change fpga into rx mode // change fpga into rx mode
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
| FPGA_HF_READER_RX_XCORR_848_KHZ | FPGA_HF_READER_RX_XCORR_848_KHZ
@ -235,7 +244,8 @@ static bool rx_ack() {
// Legic Reader // Legic Reader
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static int init_card(uint8_t cardtype, legic_card_select_t *p_card) { static int init_card(uint8_t cardtype, legic_card_select_t *p_card)
{
p_card->tagtype = cardtype; p_card->tagtype = cardtype;
switch (p_card->tagtype) { switch (p_card->tagtype) {
@ -263,7 +273,8 @@ static int init_card(uint8_t cardtype, legic_card_select_t *p_card) {
return 0; return 0;
} }
static void init_reader(bool clear_mem) { static void init_reader(bool clear_mem)
{
// configure FPGA // configure FPGA
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
@ -303,7 +314,8 @@ static void init_reader(bool clear_mem) {
// - Transmit initialisation vector 7 bits // - Transmit initialisation vector 7 bits
// - Receive card type 6 bits // - Receive card type 6 bits
// - Transmit Acknowledge 6 bits // - Transmit Acknowledge 6 bits
static uint32_t setup_phase(uint8_t iv) { static uint32_t setup_phase(uint8_t iv)
{
// init coordination timestamp // init coordination timestamp
last_frame_end = GET_TICKS; last_frame_end = GET_TICKS;
@ -336,13 +348,15 @@ static uint32_t setup_phase(uint8_t iv) {
return card_type; return card_type;
} }
static uint8_t calc_crc4(uint16_t cmd, uint8_t cmd_sz, uint8_t value) { static uint8_t calc_crc4(uint16_t cmd, uint8_t cmd_sz, uint8_t value)
{
crc_clear(&legic_crc); crc_clear(&legic_crc);
crc_update(&legic_crc, (value << cmd_sz) | cmd, 8 + cmd_sz); crc_update(&legic_crc, (value << cmd_sz) | cmd, 8 + cmd_sz);
return crc_finish(&legic_crc); return crc_finish(&legic_crc);
} }
static int16_t read_byte(uint16_t index, uint8_t cmd_sz) { static int16_t read_byte(uint16_t index, uint8_t cmd_sz)
{
uint16_t cmd = (index << 1) | LEGIC_READ; uint16_t cmd = (index << 1) | LEGIC_READ;
// read one byte // read one byte
@ -371,7 +385,8 @@ static int16_t read_byte(uint16_t index, uint8_t cmd_sz) {
// Transmit write command, wait until (3.6ms) the tag sends back an unencrypted // Transmit write command, wait until (3.6ms) the tag sends back an unencrypted
// ACK ('1' bit) and forward the prng time based. // ACK ('1' bit) and forward the prng time based.
bool write_byte(uint16_t index, uint8_t byte, uint8_t addr_sz) { bool write_byte(uint16_t index, uint8_t byte, uint8_t addr_sz)
{
uint32_t cmd = index << 1 | LEGIC_WRITE; // prepare command uint32_t cmd = index << 1 | LEGIC_WRITE; // prepare command
uint8_t crc = calc_crc4(cmd, addr_sz + 1, byte); // calculate crc uint8_t crc = calc_crc4(cmd, addr_sz + 1, byte); // calculate crc
cmd |= byte << (addr_sz + 1); // append value cmd |= byte << (addr_sz + 1); // append value
@ -393,7 +408,8 @@ bool write_byte(uint16_t index, uint8_t byte, uint8_t addr_sz) {
// //
// Only this functions are public / called from appmain.c // Only this functions are public / called from appmain.c
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void LegicRfInfo(void) { void LegicRfInfo(void)
{
// configure ARM and FPGA // configure ARM and FPGA
init_reader(false); init_reader(false);
@ -430,7 +446,8 @@ OUT:
StopTicks(); StopTicks();
} }
void LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv) { void LegicRfReader(uint16_t offset, uint16_t len, uint8_t iv)
{
// configure ARM and FPGA // configure ARM and FPGA
init_reader(false); init_reader(false);
@ -463,7 +480,8 @@ OUT:
StopTicks(); StopTicks();
} }
void LegicRfWriter(uint16_t offset, uint16_t len, uint8_t iv, uint8_t *data) { void LegicRfWriter(uint16_t offset, uint16_t len, uint8_t iv, uint8_t *data)
{
// configure ARM and FPGA // configure ARM and FPGA
init_reader(false); init_reader(false);

View file

@ -58,7 +58,8 @@ static uint32_t last_frame_end; /* ts of last bit of previews rx or tx frame */
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Returns true if a pulse/pause is received within timeout // Returns true if a pulse/pause is received within timeout
static inline bool wait_for(bool value, const uint32_t timeout) { static inline bool wait_for(bool value, const uint32_t timeout)
{
while ((bool)(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN) != value) { while ((bool)(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_DIN) != value) {
if (GetCountSspClk() > timeout) { if (GetCountSspClk() > timeout) {
return false; return false;
@ -76,7 +77,8 @@ static inline bool wait_for(bool value, const uint32_t timeout) {
// - A bit length >80.2us is a 1 // - A bit length >80.2us is a 1
// - A bit length <80.2us is a 0 // - A bit length <80.2us is a 0
// - A bit length >148.6us is a code violation // - A bit length >148.6us is a code violation
static inline int8_t rx_bit() { static inline int8_t rx_bit()
{
// backup ts for threshold calculation // backup ts for threshold calculation
uint32_t bit_start = last_frame_end; uint32_t bit_start = last_frame_end;
@ -119,7 +121,8 @@ static inline int8_t rx_bit() {
// Note: The Subcarrier is not disabled during bits to prevent glitches. This is // Note: The Subcarrier is not disabled during bits to prevent glitches. This is
// not mandatory but results in a cleaner signal. tx_frame will disable // not mandatory but results in a cleaner signal. tx_frame will disable
// the subcarrier when the frame is done. // the subcarrier when the frame is done.
static inline void tx_bit(bool bit) { static inline void tx_bit(bool bit)
{
LED_C_ON(); LED_C_ON();
if (bit) { if (bit) {
@ -146,7 +149,8 @@ static inline void tx_bit(bool bit) {
// and depends only the command received (IV, ACK, READ or WRITE). // and depends only the command received (IV, ACK, READ or WRITE).
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static void tx_frame(uint32_t frame, uint8_t len) { static void tx_frame(uint32_t frame, uint8_t len)
{
// wait for next tx timeslot // wait for next tx timeslot
last_frame_end += TAG_FRAME_WAIT; last_frame_end += TAG_FRAME_WAIT;
legic_prng_forward(TAG_FRAME_WAIT / TAG_BIT_PERIOD - 1); legic_prng_forward(TAG_FRAME_WAIT / TAG_BIT_PERIOD - 1);
@ -170,7 +174,8 @@ static void tx_frame(uint32_t frame, uint8_t len) {
LogTrace(cmdbytes, sizeof(cmdbytes), last_frame_start, last_frame_end, NULL, false); LogTrace(cmdbytes, sizeof(cmdbytes), last_frame_start, last_frame_end, NULL, false);
} }
static void tx_ack() { static void tx_ack()
{
// wait for ack timeslot // wait for ack timeslot
last_frame_end += TAG_ACK_WAIT; last_frame_end += TAG_ACK_WAIT;
legic_prng_forward(TAG_ACK_WAIT / TAG_BIT_PERIOD - 1); legic_prng_forward(TAG_ACK_WAIT / TAG_BIT_PERIOD - 1);
@ -198,7 +203,8 @@ static void tx_ack() {
// - forward prng based on ts/TAG_BIT_PERIOD // - forward prng based on ts/TAG_BIT_PERIOD
// - receive the frame // - receive the frame
// - detect end of frame (last pause) // - detect end of frame (last pause)
static int32_t rx_frame(uint8_t *len) { static int32_t rx_frame(uint8_t *len)
{
int32_t frame = 0; int32_t frame = 0;
// add 2 SSP clock cycles (1 for tx and 1 for rx pipeline delay) // add 2 SSP clock cycles (1 for tx and 1 for rx pipeline delay)
@ -263,7 +269,8 @@ static int32_t rx_frame(uint8_t *len) {
// Legic Simulator // Legic Simulator
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
static int32_t init_card(uint8_t cardtype, legic_card_select_t *p_card) { static int32_t init_card(uint8_t cardtype, legic_card_select_t *p_card)
{
p_card->tagtype = cardtype; p_card->tagtype = cardtype;
switch (p_card->tagtype) { switch (p_card->tagtype) {
@ -291,7 +298,8 @@ static int32_t init_card(uint8_t cardtype, legic_card_select_t *p_card) {
return 0; return 0;
} }
static void init_tag() { static void init_tag()
{
// configure FPGA // configure FPGA
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR
@ -326,7 +334,8 @@ static void init_tag() {
// - Receive initialisation vector 7 bits // - Receive initialisation vector 7 bits
// - Transmit card type 6 bits // - Transmit card type 6 bits
// - Receive Acknowledge 6 bits // - Receive Acknowledge 6 bits
static int32_t setup_phase(legic_card_select_t *p_card) { static int32_t setup_phase(legic_card_select_t *p_card)
{
uint8_t len = 0; uint8_t len = 0;
// init coordination timestamp // init coordination timestamp
@ -387,13 +396,15 @@ static int32_t setup_phase(legic_card_select_t *p_card) {
return 0; return 0;
} }
static uint8_t calc_crc4(uint16_t cmd, uint8_t cmd_sz, uint8_t value) { static uint8_t calc_crc4(uint16_t cmd, uint8_t cmd_sz, uint8_t value)
{
crc_clear(&legic_crc); crc_clear(&legic_crc);
crc_update(&legic_crc, (value << cmd_sz) | cmd, 8 + cmd_sz); crc_update(&legic_crc, (value << cmd_sz) | cmd, 8 + cmd_sz);
return crc_finish(&legic_crc); return crc_finish(&legic_crc);
} }
static int32_t connected_phase(legic_card_select_t *p_card) { static int32_t connected_phase(legic_card_select_t *p_card)
{
uint8_t len = 0; uint8_t len = 0;
// wait for command // wait for command
@ -447,7 +458,8 @@ static int32_t connected_phase(legic_card_select_t *p_card) {
// Only this function is public / called from appmain.c // Only this function is public / called from appmain.c
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void LegicRfSimulate(uint8_t cardtype) { void LegicRfSimulate(uint8_t cardtype)
{
// configure ARM and FPGA // configure ARM and FPGA
init_tag(); init_tag();

View file

@ -61,7 +61,8 @@ Default LF T55xx config is set to:
*/ */
t55xx_config t_config = { 29 * 8, 17 * 8, 15 * 8, 47 * 8, 15 * 8 } ; t55xx_config t_config = { 29 * 8, 17 * 8, 15 * 8, 47 * 8, 15 * 8 } ;
void printT55xxConfig(void) { void printT55xxConfig(void)
{
Dbprintf("LF T55XX config"); Dbprintf("LF T55XX config");
Dbprintf(" [a] startgap............%d*8 (%d)", t_config.start_gap / 8, t_config.start_gap); Dbprintf(" [a] startgap............%d*8 (%d)", t_config.start_gap / 8, t_config.start_gap);
Dbprintf(" [b] writegap............%d*8 (%d)", t_config.write_gap / 8, t_config.write_gap); Dbprintf(" [b] writegap............%d*8 (%d)", t_config.write_gap / 8, t_config.write_gap);
@ -70,7 +71,8 @@ void printT55xxConfig(void) {
Dbprintf(" [e] readgap.............%d*8 (%d)", t_config.read_gap / 8, t_config.read_gap); Dbprintf(" [e] readgap.............%d*8 (%d)", t_config.read_gap / 8, t_config.read_gap);
} }
void setT55xxConfig(uint8_t arg0, t55xx_config *c) { void setT55xxConfig(uint8_t arg0, t55xx_config *c)
{
if (c->start_gap != 0) t_config.start_gap = c->start_gap; if (c->start_gap != 0) t_config.start_gap = c->start_gap;
if (c->write_gap != 0) t_config.write_gap = c->write_gap; if (c->write_gap != 0) t_config.write_gap = c->write_gap;
@ -114,11 +116,13 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) {
#endif #endif
} }
t55xx_config* getT55xxConfig(void) { t55xx_config *getT55xxConfig(void)
{
return &t_config; return &t_config;
} }
void loadT55xxConfig(void) { void loadT55xxConfig(void)
{
#ifdef WITH_FLASH #ifdef WITH_FLASH
if (!FlashInit()) { if (!FlashInit()) {
return; return;
@ -156,7 +160,8 @@ void loadT55xxConfig(void) {
* @param period_1 * @param period_1
* @param command (in binary char array) * @param command (in binary char array)
*/ */
void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command) { void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command)
{
// start timer // start timer
StartTicks(); StartTicks();
@ -397,8 +402,7 @@ void WriteTIbyte(uint8_t b)
int i = 0; int i = 0;
// modulate 8 bits out to the antenna // modulate 8 bits out to the antenna
for (i=0; i<8; i++) for (i = 0; i < 8; i++) {
{
if (b & (1 << i)) { if (b & (1 << i)) {
// stop modulating antenna 1ms // stop modulating antenna 1ms
LOW(GPIO_SSC_DOUT); LOW(GPIO_SSC_DOUT);
@ -573,7 +577,8 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc)
// note: a call to FpgaDownloadAndGo(FPGA_BITSTREAM_LF) must be done before, but // note: a call to FpgaDownloadAndGo(FPGA_BITSTREAM_LF) must be done before, but
// this may destroy the bigbuf so be sure this is called before calling SimulateTagLowFrequencyEx // this may destroy the bigbuf so be sure this is called before calling SimulateTagLowFrequencyEx
void SimulateTagLowFrequencyEx(int period, int gap, int ledcontrol, int numcycles) { void SimulateTagLowFrequencyEx(int period, int gap, int ledcontrol, int numcycles)
{
// start us timer // start us timer
StartTicks(); StartTicks();
@ -657,7 +662,8 @@ OUT:
LED_D_OFF(); LED_D_OFF();
} }
void SimulateTagLowFrequency(int period, int gap, int ledcontrol) { void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
{
SimulateTagLowFrequencyEx(period, gap, ledcontrol, -1); SimulateTagLowFrequencyEx(period, gap, ledcontrol, -1);
} }
@ -720,11 +726,16 @@ static void fc(int c, int *n)
// special start of frame marker containing invalid bit sequences // special start of frame marker containing invalid bit sequences
// this one is focused on HID, with manchester encoding. // this one is focused on HID, with manchester encoding.
static void fcSTT(int *n) { static void fcSTT(int *n)
fc(8, n); fc(8, n); // invalid {
fc(8, n); fc(10, n); // logical 0 fc(8, n);
fc(10, n); fc(10, n); // invalid fc(8, n); // invalid
fc(8, n); fc(10, n); // logical 0 fc(8, n);
fc(10, n); // logical 0
fc(10, n);
fc(10, n); // invalid
fc(8, n);
fc(10, n); // logical 0
} }
// compose fc/X fc/Y waveform (FSKx) // compose fc/X fc/Y waveform (FSKx)
@ -762,7 +773,8 @@ static void fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt)
// prepare a waveform pattern in the buffer based on the ID given then // prepare a waveform pattern in the buffer based on the ID given then
// simulate a HID tag until the button is pressed // simulate a HID tag until the button is pressed
void CmdHIDsimTAGEx( uint32_t hi, uint32_t lo, int ledcontrol, int numcycles) { void CmdHIDsimTAGEx(uint32_t hi, uint32_t lo, int ledcontrol, int numcycles)
{
if (hi > 0xFFF) { if (hi > 0xFFF) {
DbpString("[!] tags can only have 44 bits. - USE lf simfsk for larger tags"); DbpString("[!] tags can only have 44 bits. - USE lf simfsk for larger tags");
@ -798,9 +810,11 @@ void CmdHIDsimTAGEx( uint32_t hi, uint32_t lo, int ledcontrol, int numcycles) {
if ((i % 4) == 3) fc(0, &n); if ((i % 4) == 3) fc(0, &n);
if ((hi >> i) & 1) { if ((hi >> i) & 1) {
fc(10, &n); fc(8, &n); // low-high transition fc(10, &n);
fc(8, &n); // low-high transition
} else { } else {
fc(8, &n); fc(10, &n); // high-low transition fc(8, &n);
fc(10, &n); // high-low transition
} }
} }
@ -810,9 +824,11 @@ void CmdHIDsimTAGEx( uint32_t hi, uint32_t lo, int ledcontrol, int numcycles) {
if ((i % 4) == 3) fc(0, &n); if ((i % 4) == 3) fc(0, &n);
if ((lo >> i) & 1) { if ((lo >> i) & 1) {
fc(10, &n); fc(8, &n); // low-high transition fc(10, &n);
fc(8, &n); // low-high transition
} else { } else {
fc(8, &n); fc(10, &n); // high-low transition fc(8, &n);
fc(10, &n); // high-low transition
} }
} }
@ -821,7 +837,8 @@ void CmdHIDsimTAGEx( uint32_t hi, uint32_t lo, int ledcontrol, int numcycles) {
if (ledcontrol) LED_A_OFF(); if (ledcontrol) LED_A_OFF();
} }
void CmdHIDsimTAG( uint32_t hi, uint32_t lo, int ledcontrol) { void CmdHIDsimTAG(uint32_t hi, uint32_t lo, int ledcontrol)
{
CmdHIDsimTAGEx(hi, lo, ledcontrol, -1); CmdHIDsimTAGEx(hi, lo, ledcontrol, -1);
DbpString("[!] simulation finished"); DbpString("[!] simulation finished");
} }
@ -829,11 +846,13 @@ void CmdHIDsimTAG( uint32_t hi, uint32_t lo, int ledcontrol) {
// prepare a waveform pattern in the buffer based on the ID given then // prepare a waveform pattern in the buffer based on the ID given then
// simulate a FSK tag until the button is pressed // simulate a FSK tag until the button is pressed
// arg1 contains fcHigh and fcLow, arg2 contains STT marker and clock // arg1 contains fcHigh and fcLow, arg2 contains STT marker and clock
void CmdFSKsimTAG(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *bits) { void CmdFSKsimTAG(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *bits)
{
FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
// free eventually allocated BigBuf memory // free eventually allocated BigBuf memory
BigBuf_free(); BigBuf_Clear_ext(false); BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace(); clear_trace();
set_tracing(false); set_tracing(false);
@ -894,7 +913,8 @@ static void biphaseSimBit(uint8_t c, int *n, uint8_t clock, uint8_t *phase)
*n += clock; *n += clock;
} }
static void stAskSimBit(int *n, uint8_t clock) { static void stAskSimBit(int *n, uint8_t clock)
{
uint8_t *dest = BigBuf_get_addr(); uint8_t *dest = BigBuf_get_addr();
uint8_t halfClk = clock / 2; uint8_t halfClk = clock / 2;
//ST = .5 high .5 low 1.5 high .5 low 1 high //ST = .5 high .5 low 1.5 high .5 low 1 high
@ -1004,7 +1024,8 @@ void CmdPSKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream)
} }
// loop to get raw HID waveform then FSK demodulate the TAG ID from it // loop to get raw HID waveform then FSK demodulate the TAG ID from it
void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) { void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
{
uint8_t *dest = BigBuf_get_addr(); uint8_t *dest = BigBuf_get_addr();
size_t size = 0; size_t size = 0;
uint32_t hi2 = 0, hi = 0, lo = 0; uint32_t hi2 = 0, hi = 0, lo = 0;
@ -1068,8 +1089,7 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
cardnum = (lo >> 1) & 0xFFFFF; cardnum = (lo >> 1) & 0xFFFFF;
fc = ((hi & 1) << 11) | (lo >> 21); fc = ((hi & 1) << 11) | (lo >> 21);
} }
} } else { //if bit 38 is not set then 37 bit format is used
else { //if bit 38 is not set then 37 bit format is used
bitlen = 37; bitlen = 37;
fc = 0; fc = 0;
cardnum = 0; cardnum = 0;
@ -1102,7 +1122,8 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
} }
// loop to get raw HID waveform then FSK demodulate the TAG ID from it // loop to get raw HID waveform then FSK demodulate the TAG ID from it
void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) { void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
{
uint8_t *dest = BigBuf_get_addr(); uint8_t *dest = BigBuf_get_addr();
@ -1197,7 +1218,8 @@ void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
if (ledcontrol) LED_A_OFF(); if (ledcontrol) LED_A_OFF();
} }
void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol) { void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol)
{
uint8_t *dest = BigBuf_get_addr(); uint8_t *dest = BigBuf_get_addr();
size_t size = 0, idx = 0; size_t size = 0, idx = 0;
@ -1259,7 +1281,8 @@ void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol)
if (ledcontrol) LED_A_OFF(); if (ledcontrol) LED_A_OFF();
} }
void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) { void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
{
uint8_t *dest = BigBuf_get_addr(); uint8_t *dest = BigBuf_get_addr();
@ -1359,20 +1382,23 @@ void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) {
* Q5 tags seems to have issues when these values changes. * Q5 tags seems to have issues when these values changes.
*/ */
void TurnReadLFOn(uint32_t delay) { void TurnReadLFOn(uint32_t delay)
{
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// measure antenna strength. // measure antenna strength.
//int adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); //int adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10);
WaitUS(delay); WaitUS(delay);
} }
void TurnReadLF_off(uint32_t delay) { void TurnReadLF_off(uint32_t delay)
{
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
WaitUS(delay); WaitUS(delay);
} }
// Write one bit to card // Write one bit to card
void T55xxWriteBit(int bit) { void T55xxWriteBit(int bit)
{
if (!bit) if (!bit)
TurnReadLFOn(t_config.write_0); TurnReadLFOn(t_config.write_0);
else else
@ -1382,7 +1408,8 @@ void T55xxWriteBit(int bit) {
} }
// Send T5577 reset command then read stream (see if we can identify the start of the stream) // Send T5577 reset command then read stream (see if we can identify the start of the stream)
void T55xxResetRead(void) { void T55xxResetRead(void)
{
LED_A_ON(); LED_A_ON();
//clear buffer now so it does not interfere with timing later //clear buffer now so it does not interfere with timing later
BigBuf_Clear_keep_EM(); BigBuf_Clear_keep_EM();
@ -1414,7 +1441,8 @@ void T55xxResetRead(void) {
} }
// 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 Block, uint32_t Pwd, uint8_t arg) { void T55xxWriteBlockExt(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg)
{
LED_A_ON(); LED_A_ON();
bool PwdMode = arg & 0x1; bool PwdMode = arg & 0x1;
uint8_t Page = (arg & 0x2) >> 1; uint8_t Page = (arg & 0x2) >> 1;
@ -1488,13 +1516,15 @@ void T55xxWriteBlockExt(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg)
} }
// Write one card block in page 0, no lock // Write one card block in page 0, no lock
void T55xxWriteBlock(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) { void T55xxWriteBlock(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg)
{
T55xxWriteBlockExt(Data, Block, Pwd, arg); T55xxWriteBlockExt(Data, Block, Pwd, arg);
cmd_send(CMD_ACK, 0, 0, 0, 0, 0); cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
} }
// Read one card block in page [page] // Read one card block in page [page]
void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) { void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd)
{
LED_A_ON(); LED_A_ON();
bool PwdMode = arg0 & 0x1; bool PwdMode = arg0 & 0x1;
uint8_t Page = (arg0 & 0x2) >> 1; uint8_t Page = (arg0 & 0x2) >> 1;
@ -1563,7 +1593,8 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
} }
} }
void T55xx_ChkPwds() { void T55xx_ChkPwds()
{
DbpString("[+] T55XX Check pwds using flashmemory starting"); DbpString("[+] T55XX Check pwds using flashmemory starting");
@ -1662,7 +1693,8 @@ OUT:
LEDsoff(); LEDsoff();
} }
void T55xxWakeUp(uint32_t Pwd){ void T55xxWakeUp(uint32_t Pwd)
{
LED_B_ON(); LED_B_ON();
uint32_t i = 0; uint32_t i = 0;
@ -1690,14 +1722,16 @@ void T55xxWakeUp(uint32_t Pwd){
} }
/*-------------- Cloning routines -----------*/ /*-------------- Cloning routines -----------*/
void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) { void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks)
{
// write last block first and config block last (if included) // write last block first and config block last (if included)
for (uint8_t i = numblocks + startblock; i > startblock; i--) for (uint8_t i = numblocks + startblock; i > startblock; i--)
T55xxWriteBlockExt(blockdata[i - 1], i - 1, 0, 0); T55xxWriteBlockExt(blockdata[i - 1], i - 1, 0, 0);
} }
// Copy HID id to card and setup block 0 config // Copy HID id to card and setup block 0 config
void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) { void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT)
{
uint32_t data[] = {0, 0, 0, 0, 0, 0, 0}; uint32_t data[] = {0, 0, 0, 0, 0, 0, 0};
uint8_t last_block = 0; uint8_t last_block = 0;
@ -1741,7 +1775,8 @@ void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) {
LED_D_OFF(); LED_D_OFF();
} }
void CopyIOtoT55x7(uint32_t hi, uint32_t lo) { void CopyIOtoT55x7(uint32_t hi, uint32_t lo)
{
uint32_t data[] = {T55x7_BITRATE_RF_64 | T55x7_MODULATION_FSK2a | (2 << T55x7_MAXBLOCK_SHIFT), hi, lo}; uint32_t data[] = {T55x7_BITRATE_RF_64 | T55x7_MODULATION_FSK2a | (2 << T55x7_MAXBLOCK_SHIFT), hi, lo};
//TODO add selection of chip for Q5 or T55x7 //TODO add selection of chip for Q5 or T55x7
// data[0] = T5555_SET_BITRATE(64) | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | 2 << T5555_MAXBLOCK_SHIFT; // data[0] = T5555_SET_BITRATE(64) | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | 2 << T5555_MAXBLOCK_SHIFT;
@ -1754,7 +1789,8 @@ void CopyIOtoT55x7(uint32_t hi, uint32_t lo) {
} }
// Clone Indala 64-bit tag by UID to T55x7 // Clone Indala 64-bit tag by UID to T55x7
void CopyIndala64toT55x7(uint32_t hi, uint32_t lo) { void CopyIndala64toT55x7(uint32_t hi, uint32_t lo)
{
//Program the 2 data blocks for supplied 64bit UID //Program the 2 data blocks for supplied 64bit UID
// and the Config for Indala 64 format (RF/32;PSK2 with RF/2;Maxblock=2) // and the Config for Indala 64 format (RF/32;PSK2 with RF/2;Maxblock=2)
uint32_t data[] = { T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK2 | (2 << T55x7_MAXBLOCK_SHIFT), hi, lo}; uint32_t data[] = { T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK2 | (2 << T55x7_MAXBLOCK_SHIFT), hi, lo};
@ -1766,7 +1802,8 @@ void CopyIndala64toT55x7(uint32_t hi, uint32_t lo) {
// T5567WriteBlock(0x603E1042,0); // T5567WriteBlock(0x603E1042,0);
} }
// Clone Indala 224-bit tag by UID to T55x7 // Clone Indala 224-bit tag by UID to T55x7
void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7) { void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7)
{
//Program the 7 data blocks for supplied 224bit UID //Program the 7 data blocks for supplied 224bit UID
uint32_t data[] = {0, uid1, uid2, uid3, uid4, uid5, uid6, uid7}; uint32_t data[] = {0, uid1, uid2, uid3, uid4, uid5, uid6, uid7};
// and the block 0 for Indala224 format // and the block 0 for Indala224 format
@ -1779,7 +1816,8 @@ void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t
// T5567WriteBlock(0x603E10E2,0); // T5567WriteBlock(0x603E10E2,0);
} }
// clone viking tag to T55xx // clone viking tag to T55xx
void CopyVikingtoT55xx(uint32_t block1, uint32_t block2, uint8_t Q5) { void CopyVikingtoT55xx(uint32_t block1, uint32_t block2, uint8_t Q5)
{
uint32_t data[] = {T55x7_BITRATE_RF_32 | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT), block1, block2}; uint32_t data[] = {T55x7_BITRATE_RF_32 | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT), block1, block2};
if (Q5) data[0] = T5555_SET_BITRATE(32) | T5555_MODULATION_MANCHESTER | 2 << T5555_MAXBLOCK_SHIFT; if (Q5) data[0] = T5555_SET_BITRATE(32) | T5555_MODULATION_MANCHESTER | 2 << T5555_MAXBLOCK_SHIFT;
// Program the data blocks for supplied ID and the block 0 config // Program the data blocks for supplied ID and the block 0 config
@ -1792,7 +1830,8 @@ void CopyVikingtoT55xx(uint32_t block1, uint32_t block2, uint8_t Q5) {
#define EM410X_HEADER 0x1FF #define EM410X_HEADER 0x1FF
#define EM410X_ID_LENGTH 40 #define EM410X_ID_LENGTH 40
void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) { void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo)
{
int i, id_bit; int i, id_bit;
uint64_t id = EM410X_HEADER; uint64_t id = EM410X_HEADER;
uint64_t rev_id = 0; // reversed ID uint64_t rev_id = 0; // reversed ID
@ -1905,7 +1944,8 @@ uint8_t * fwd_write_ptr; //forwardlink bit pointer
// These timings work for 4469/4269/4305 (with the 55*8 above) // These timings work for 4469/4269/4305 (with the 55*8 above)
// WRITE_0 = 23*8 , 9*8 // WRITE_0 = 23*8 , 9*8
uint8_t Prepare_Cmd( uint8_t cmd ) { uint8_t Prepare_Cmd(uint8_t cmd)
{
*forward_ptr++ = 0; //start bit *forward_ptr++ = 0; //start bit
*forward_ptr++ = 0; //second pause for 4050 code *forward_ptr++ = 0; //second pause for 4050 code
@ -1925,7 +1965,8 @@ uint8_t Prepare_Cmd( uint8_t cmd ) {
// prepares address bits // prepares address bits
// see EM4469 spec // see EM4469 spec
//==================================================================== //====================================================================
uint8_t Prepare_Addr( uint8_t addr ) { uint8_t Prepare_Addr(uint8_t addr)
{
register uint8_t line_parity; register uint8_t line_parity;
@ -1946,7 +1987,8 @@ uint8_t Prepare_Addr( uint8_t addr ) {
// prepares data bits intreleaved with parity bits // prepares data bits intreleaved with parity bits
// see EM4469 spec // see EM4469 spec
//==================================================================== //====================================================================
uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) { uint8_t Prepare_Data(uint16_t data_low, uint16_t data_hi)
{
register uint8_t line_parity; register uint8_t line_parity;
register uint8_t column_parity; register uint8_t column_parity;
@ -1983,7 +2025,8 @@ uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) {
// Requires: forwarLink_data filled with valid bits (1 bit per byte) // Requires: forwarLink_data filled with valid bits (1 bit per byte)
// fwd_bit_count set with number of bits to be sent // fwd_bit_count set with number of bits to be sent
//==================================================================== //====================================================================
void SendForward(uint8_t fwd_bit_count) { void SendForward(uint8_t fwd_bit_count)
{
// iceman, 21.3us increments for the USclock verification. // iceman, 21.3us increments for the USclock verification.
// 55FC * 8us == 440us / 21.3 === 20.65 steps. could be too short. Go for 56FC instead // 55FC * 8us == 440us / 21.3 === 20.65 steps. could be too short. Go for 56FC instead
@ -2017,7 +2060,8 @@ void SendForward(uint8_t fwd_bit_count) {
} }
} }
void EM4xLogin(uint32_t pwd) { void EM4xLogin(uint32_t pwd)
{
uint8_t len; uint8_t len;
forward_ptr = forwardLink_data; forward_ptr = forwardLink_data;
len = Prepare_Cmd(FWD_CMD_LOGIN); len = Prepare_Cmd(FWD_CMD_LOGIN);
@ -2029,7 +2073,8 @@ void EM4xLogin(uint32_t pwd) {
// 0000 0001 fail // 0000 0001 fail
} }
void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd) { void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd)
{
LED_A_ON(); LED_A_ON();
uint8_t len; uint8_t len;
@ -2061,7 +2106,8 @@ void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd) {
LED_A_OFF(); LED_A_OFF();
} }
void EM4xWriteWord(uint32_t flag, uint32_t data, uint32_t pwd) { void EM4xWriteWord(uint32_t flag, uint32_t data, uint32_t pwd)
{
LED_A_ON(); LED_A_ON();
@ -2111,7 +2157,8 @@ pulse 3.6 msecs
This triggers a 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
# define OFF(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS((x)); } # define OFF(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS((x)); }
#endif #endif
@ -2134,9 +2181,15 @@ void Cotag(uint32_t arg0) {
ON(1000) ON(1000)
switch (rawsignal) { switch (rawsignal) {
case 0: doCotagAcquisition(50000); break; case 0:
case 1: doCotagAcquisitionManchester(); break; doCotagAcquisition(50000);
case 2: DoAcquisition_config(true, 0); break; break;
case 1:
doCotagAcquisitionManchester();
break;
case 2:
DoAcquisition_config(true, 0);
break;
} }
// Turn the field off // Turn the field off

View file

@ -18,7 +18,8 @@ Default LF config is set to:
*/ */
sample_config config = { 1, 8, 1, 95, 0 } ; sample_config config = { 1, 8, 1, 95, 0 } ;
void printConfig() { void printConfig()
{
Dbprintf("LF Sampling config"); Dbprintf("LF Sampling config");
Dbprintf(" [q] divisor.............%d (%d KHz)", config.divisor, 12000 / (config.divisor + 1)); Dbprintf(" [q] divisor.............%d (%d KHz)", config.divisor, 12000 / (config.divisor + 1));
Dbprintf(" [b] bps.................%d", config.bits_per_sample); Dbprintf(" [b] bps.................%d", config.bits_per_sample);
@ -38,7 +39,8 @@ void printConfig() {
* @brief setSamplingConfig * @brief setSamplingConfig
* @param sc * @param sc
*/ */
void setSamplingConfig(sample_config *sc) { void setSamplingConfig(sample_config *sc)
{
if (sc->divisor != 0) config.divisor = sc->divisor; if (sc->divisor != 0) config.divisor = sc->divisor;
if (sc->bits_per_sample != 0) config.bits_per_sample = sc->bits_per_sample; if (sc->bits_per_sample != 0) config.bits_per_sample = sc->bits_per_sample;
if (sc->trigger_threshold != -1) config.trigger_threshold = sc->trigger_threshold; if (sc->trigger_threshold != -1) config.trigger_threshold = sc->trigger_threshold;
@ -50,7 +52,8 @@ void setSamplingConfig(sample_config *sc) {
printConfig(); printConfig();
} }
sample_config* getSamplingConfig() { sample_config *getSamplingConfig()
{
return &config; return &config;
} }
@ -65,7 +68,8 @@ struct BitstreamOut {
* @param stream * @param stream
* @param bit * @param bit
*/ */
void pushBit( BitstreamOut* stream, uint8_t bit) { void pushBit(BitstreamOut *stream, uint8_t bit)
{
int bytepos = stream->position >> 3; // divide by 8 int bytepos = stream->position >> 3; // divide by 8
int bitpos = stream->position & 7; int bitpos = stream->position & 7;
*(stream->buffer + bytepos) |= (bit > 0) << (7 - bitpos); *(stream->buffer + bytepos) |= (bit > 0) << (7 - bitpos);
@ -80,7 +84,8 @@ void pushBit( BitstreamOut* stream, uint8_t bit) {
* 0 or 95 ==> 125 KHz * 0 or 95 ==> 125 KHz
* *
**/ **/
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, 88); //134.8Khz
@ -116,7 +121,8 @@ void LFSetupFPGAForADC(int divisor, bool lf_field) {
* @param silent - is true, now outputs are made. If false, dbprints the status * @param silent - is true, now outputs are made. If false, dbprints the status
* @return the number of bits occupied by the samples. * @return the number of bits occupied by the samples.
*/ */
uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold, bool silent, int bufsize, uint32_t cancel_after) { uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold, bool silent, int bufsize, uint32_t cancel_after)
{
uint8_t *dest = BigBuf_get_addr(); uint8_t *dest = BigBuf_get_addr();
bufsize = (bufsize > 0 && bufsize < BigBuf_max_traceLen()) ? bufsize : BigBuf_max_traceLen(); bufsize = (bufsize > 0 && bufsize < BigBuf_max_traceLen()) ? bufsize : BigBuf_max_traceLen();
@ -218,10 +224,12 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
* @param silent * @param silent
* @return number of bits sampled * @return number of bits sampled
*/ */
uint32_t DoAcquisition_default(int trigger_threshold, bool silent) { uint32_t DoAcquisition_default(int trigger_threshold, bool silent)
{
return DoAcquisition(1, 8, 0, trigger_threshold, silent, 0, 0); return DoAcquisition(1, 8, 0, trigger_threshold, silent, 0, 0);
} }
uint32_t DoAcquisition_config( bool silent, int sample_size) { uint32_t DoAcquisition_config(bool silent, int sample_size)
{
return DoAcquisition(config.decimation return DoAcquisition(config.decimation
, config.bits_per_sample , config.bits_per_sample
, config.averaging , config.averaging
@ -231,11 +239,13 @@ uint32_t DoAcquisition_config( bool silent, int sample_size) {
, 0); , 0);
} }
uint32_t DoPartialAcquisition(int trigger_threshold, bool silent, int sample_size, uint32_t cancel_after) { uint32_t DoPartialAcquisition(int trigger_threshold, bool silent, int sample_size, uint32_t cancel_after)
{
return DoAcquisition(1, 8, 0, trigger_threshold, silent, sample_size, cancel_after); return DoAcquisition(1, 8, 0, trigger_threshold, silent, sample_size, cancel_after);
} }
uint32_t ReadLF(bool activeField, bool silent, int sample_size) { uint32_t ReadLF(bool activeField, bool silent, int sample_size)
{
if (!silent) if (!silent)
printConfig(); printConfig();
LFSetupFPGAForADC(config.divisor, activeField); LFSetupFPGAForADC(config.divisor, activeField);
@ -246,7 +256,8 @@ uint32_t ReadLF(bool activeField, bool silent, int sample_size) {
* Initializes the FPGA for reader-mode (field on), and acquires the samples. * Initializes the FPGA for reader-mode (field on), and acquires the samples.
* @return number of bits sampled * @return number of bits sampled
**/ **/
uint32_t SampleLF(bool printCfg, int sample_size) { uint32_t SampleLF(bool printCfg, int sample_size)
{
BigBuf_Clear_ext(false); BigBuf_Clear_ext(false);
uint32_t ret = ReadLF(true, printCfg, sample_size); uint32_t ret = ReadLF(true, printCfg, sample_size);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@ -256,7 +267,8 @@ uint32_t SampleLF(bool printCfg, int sample_size) {
* Initializes the FPGA for snoop-mode (field off), and acquires the samples. * Initializes the FPGA for snoop-mode (field off), and acquires the samples.
* @return number of bits sampled * @return number of bits sampled
**/ **/
uint32_t SnoopLF() { uint32_t SnoopLF()
{
BigBuf_Clear_ext(false); BigBuf_Clear_ext(false);
uint32_t ret = ReadLF(false, true, 0); uint32_t ret = ReadLF(false, true, 0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@ -267,7 +279,8 @@ uint32_t SnoopLF() {
* acquisition of T55x7 LF signal. Similar to other LF, but adjusted with @marshmellows thresholds * acquisition of T55x7 LF signal. Similar to other LF, but adjusted with @marshmellows thresholds
* the data is collected in BigBuf. * the data is collected in BigBuf.
**/ **/
void doT55x7Acquisition(size_t sample_size) { void doT55x7Acquisition(size_t sample_size)
{
#define T55xx_READ_UPPER_THRESHOLD 128+60 // 60 grph #define T55xx_READ_UPPER_THRESHOLD 128+60 // 60 grph
#define T55xx_READ_LOWER_THRESHOLD 128-60 // -60 grph #define T55xx_READ_LOWER_THRESHOLD 128-60 // -60 grph
@ -337,7 +350,8 @@ void doT55x7Acquisition(size_t sample_size) {
#ifndef COTAG_BITS #ifndef COTAG_BITS
#define COTAG_BITS 264 #define COTAG_BITS 264
#endif #endif
void doCotagAcquisition(size_t sample_size) { void doCotagAcquisition(size_t sample_size)
{
uint8_t *dest = BigBuf_get_addr(); uint8_t *dest = BigBuf_get_addr();
uint16_t bufsize = BigBuf_max_traceLen(); uint16_t bufsize = BigBuf_max_traceLen();
@ -387,7 +401,8 @@ void doCotagAcquisition(size_t sample_size) {
} }
} }
uint32_t doCotagAcquisitionManchester() { uint32_t doCotagAcquisitionManchester()
{
uint8_t *dest = BigBuf_get_addr(); uint8_t *dest = BigBuf_get_addr();
uint16_t bufsize = BigBuf_max_traceLen(); uint16_t bufsize = BigBuf_max_traceLen();
@ -431,12 +446,10 @@ uint32_t doCotagAcquisitionManchester() {
if (sample > COTAG_ONE_THRESHOLD) { if (sample > COTAG_ONE_THRESHOLD) {
prev = curr; prev = curr;
curr = 1; curr = 1;
} } else if (sample < COTAG_ZERO_THRESHOLD) {
else if ( sample < COTAG_ZERO_THRESHOLD) {
prev = curr; prev = curr;
curr = 0; curr = 0;
} } else {
else {
curr = prev; curr = prev;
} }

View file

@ -101,11 +101,14 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
LEDsoff(); LEDsoff();
} }
void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes)
{
bool turnOffField = (arg0 == 1); bool turnOffField = (arg0 == 1);
LED_A_ON(); LED_B_OFF(); LED_C_OFF(); LED_A_ON();
LED_B_OFF();
LED_C_OFF();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
@ -272,7 +275,8 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
// free eventually allocated BigBuf memory // free eventually allocated BigBuf memory
BigBuf_free(); BigBuf_Clear_ext(false); BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace(); clear_trace();
set_tracing(true); set_tracing(true);
@ -539,14 +543,17 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
set_tracing(false); set_tracing(false);
} }
void MifareUSetPwd(uint8_t arg0, uint8_t *datain){ void MifareUSetPwd(uint8_t arg0, uint8_t *datain)
{
uint8_t pwd[16] = {0x00}; uint8_t pwd[16] = {0x00};
byte_t blockdata[4] = {0x00}; byte_t blockdata[4] = {0x00};
memcpy(pwd, datain, 16); memcpy(pwd, datain, 16);
LED_A_ON(); LED_B_OFF(); LED_C_OFF(); LED_A_ON();
LED_B_OFF();
LED_C_OFF();
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
clear_trace(); clear_trace();
@ -611,13 +618,15 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain){
} }
// Return 1 if the nonce is invalid else return 0 // Return 1 if the nonce is invalid else return 0
int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity) { int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, uint8_t *parity)
{
return ((oddparity8((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity8((NtEnc >> 24) & 0xFF) ^ BIT(Ks1, 16))) & \ return ((oddparity8((Nt >> 24) & 0xFF) == ((parity[0]) ^ oddparity8((NtEnc >> 24) & 0xFF) ^ BIT(Ks1, 16))) & \
(oddparity8((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity8((NtEnc >> 16) & 0xFF) ^ BIT(Ks1, 8))) & \ (oddparity8((Nt >> 16) & 0xFF) == ((parity[1]) ^ oddparity8((NtEnc >> 16) & 0xFF) ^ BIT(Ks1, 8))) & \
(oddparity8((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity8((NtEnc >> 8) & 0xFF) ^ BIT(Ks1, 0)))) ? 1 : 0; (oddparity8((Nt >> 8) & 0xFF) == ((parity[2]) ^ oddparity8((NtEnc >> 8) & 0xFF) ^ BIT(Ks1, 0)))) ? 1 : 0;
} }
void MifareAcquireNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain) { void MifareAcquireNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain)
{
uint8_t uid[10] = {0x00}; uint8_t uid[10] = {0x00};
uint8_t answer[MAX_MIFARE_FRAME_SIZE] = {0x00}; uint8_t answer[MAX_MIFARE_FRAME_SIZE] = {0x00};
@ -636,7 +645,8 @@ void MifareAcquireNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *
LED_A_ON(); LED_A_ON();
LED_C_OFF(); LED_C_OFF();
BigBuf_free(); BigBuf_Clear_ext(false); BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace(); clear_trace();
set_tracing(true); set_tracing(true);
@ -661,10 +671,17 @@ void MifareAcquireNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *
continue; continue;
} }
switch (card_info.uidlen) { switch (card_info.uidlen) {
case 4 : cascade_levels = 1; break; case 4 :
case 7 : cascade_levels = 2; break; cascade_levels = 1;
case 10: cascade_levels = 3; break; break;
default: break; case 7 :
cascade_levels = 2;
break;
case 10:
cascade_levels = 3;
break;
default:
break;
} }
have_uid = true; have_uid = true;
} else { // no need for anticollision. We can directly select the card } else { // no need for anticollision. We can directly select the card
@ -717,7 +734,8 @@ void MifareAcquireNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *
// Mifare Classic Cards" in Proceedings of the 22nd ACM SIGSAC Conference on // Mifare Classic Cards" in Proceedings of the 22nd ACM SIGSAC Conference on
// Computer and Communications Security, 2015 // Computer and Communications Security, 2015
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain) { void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *datain)
{
struct Crypto1State mpcs = {0, 0}; struct Crypto1State mpcs = {0, 0};
struct Crypto1State *pcs; struct Crypto1State *pcs;
@ -746,7 +764,8 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
LED_A_ON(); LED_A_ON();
LED_C_OFF(); LED_C_OFF();
BigBuf_free(); BigBuf_Clear_ext(false); BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace(); clear_trace();
set_tracing(false); set_tracing(false);
@ -771,10 +790,17 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
continue; continue;
} }
switch (card_info.uidlen) { switch (card_info.uidlen) {
case 4 : cascade_levels = 1; break; case 4 :
case 7 : cascade_levels = 2; break; cascade_levels = 1;
case 10: cascade_levels = 3; break; break;
default: break; case 7 :
cascade_levels = 2;
break;
case 10:
cascade_levels = 3;
break;
default:
break;
} }
have_uid = true; have_uid = true;
} else { // no need for anticollision. We can directly select the card } else { // no need for anticollision. We can directly select the card
@ -871,7 +897,8 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN); iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
// free eventually allocated BigBuf memory // free eventually allocated BigBuf memory
BigBuf_free(); BigBuf_Clear_ext(false); BigBuf_free();
BigBuf_Clear_ext(false);
if (calibrate) clear_trace(); if (calibrate) clear_trace();
set_tracing(true); set_tracing(true);
@ -934,8 +961,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
davg += i; davg += i;
dmin = MIN(dmin, i); dmin = MIN(dmin, i);
dmax = MAX(dmax, i); dmax = MAX(dmax, i);
} } else {
else {
delta_time = auth2_time - auth1_time + 32; // allow some slack for proper timing delta_time = auth2_time - auth1_time + 32; // allow some slack for proper timing
} }
if (MF_DBGLEVEL >= 3) Dbprintf("Nested: calibrating... ntdist=%d", i); if (MF_DBGLEVEL >= 3) Dbprintf("Nested: calibrating... ntdist=%d", i);
@ -1075,7 +1101,8 @@ typedef struct chk_t {
// 2 = failed to select. // 2 = failed to select.
// 1 = wrong key // 1 = wrong key
// 0 = correct key // 0 = correct key
uint8_t chkKey( struct chk_t *c ) { uint8_t chkKey(struct chk_t *c)
{
uint8_t i = 0, res = 2; uint8_t i = 0, res = 2;
while (i < 5) { while (i < 5) {
// this part is from Piwi's faster nonce collecting part in Hardnested. // this part is from Piwi's faster nonce collecting part in Hardnested.
@ -1096,7 +1123,8 @@ uint8_t chkKey( struct chk_t *c ) {
return res; return res;
} }
uint8_t chkKey_readb(struct chk_t *c, uint8_t *keyb) { uint8_t chkKey_readb(struct chk_t *c, uint8_t *keyb)
{
if (!iso14443a_fast_select_card(c->uid, c->cl)) if (!iso14443a_fast_select_card(c->uid, c->cl))
return 2; return 2;
@ -1121,7 +1149,8 @@ uint8_t chkKey_readb(struct chk_t *c, uint8_t *keyb) {
return res; return res;
} }
void chkKey_scanA(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) { void chkKey_scanA(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys)
{
for (uint8_t s = 0; s < *sectorcnt; s++) { for (uint8_t s = 0; s < *sectorcnt; s++) {
// skip already found A keys // skip already found A keys
@ -1139,7 +1168,8 @@ void chkKey_scanA(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, ui
} }
} }
void chkKey_scanB(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) { void chkKey_scanB(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys)
{
for (uint8_t s = 0; s < *sectorcnt; s++) { for (uint8_t s = 0; s < *sectorcnt; s++) {
// skip already found B keys // skip already found B keys
@ -1159,7 +1189,8 @@ void chkKey_scanB(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, ui
// loop all A keys, // loop all A keys,
// when A is found but not B, try to read B. // when A is found but not B, try to read B.
void chkKey_loopBonly(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys) { void chkKey_loopBonly(struct chk_t *c, struct sector_t *k_sector, uint8_t *found, uint8_t *sectorcnt, uint8_t *foundkeys)
{
// read Block B, if A is found. // read Block B, if A is found.
for (uint8_t s = 0; s < *sectorcnt; ++s) { for (uint8_t s = 0; s < *sectorcnt; ++s) {
@ -1197,7 +1228,8 @@ void chkKey_loopBonly(struct chk_t *c, struct sector_t *k_sector, uint8_t *found
// arg1 = clear trace // arg1 = clear trace
// arg2 = antal nycklar i keychunk // arg2 = antal nycklar i keychunk
// datain = keys as array // datain = keys as array
void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain) { void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
{
// first call or // first call or
uint8_t sectorcnt = arg0 & 0xFF; // 16; uint8_t sectorcnt = arg0 & 0xFF; // 16;
@ -1273,10 +1305,17 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
} }
switch (card_info.uidlen) { switch (card_info.uidlen) {
case 4 : cascade_levels = 1; break; case 4 :
case 7 : cascade_levels = 2; break; cascade_levels = 1;
case 10: cascade_levels = 3; break; break;
default: break; case 7 :
cascade_levels = 2;
break;
case 10:
cascade_levels = 3;
break;
default:
break;
} }
CHK_TIMEOUT(); CHK_TIMEOUT();
@ -1486,14 +1525,16 @@ OUT:
set_tracing(false); set_tracing(false);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
BigBuf_free(); BigBuf_Clear_ext(false); BigBuf_free();
BigBuf_Clear_ext(false);
} else { } else {
// partial/none keys found // partial/none keys found
cmd_send(CMD_ACK, foundkeys, 0, 0, 0, 0); cmd_send(CMD_ACK, foundkeys, 0, 0, 0, 0);
} }
} }
void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) { void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
{
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@ -1535,10 +1576,17 @@ void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) {
continue; continue;
} }
switch (card_info.uidlen) { switch (card_info.uidlen) {
case 4 : cascade_levels = 1; break; case 4 :
case 7 : cascade_levels = 2; break; cascade_levels = 1;
case 10: cascade_levels = 3; break; break;
default: break; case 7 :
cascade_levels = 2;
break;
case 10:
cascade_levels = 3;
break;
default:
break;
} }
have_uid = true; have_uid = true;
} else { // no need for anticollision. We can directly select the card } else { // no need for anticollision. We can directly select the card
@ -1575,7 +1623,8 @@ void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) {
// MIFARE commands set debug level // MIFARE commands set debug level
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void MifareSetDbgLvl(uint16_t arg0){ void MifareSetDbgLvl(uint16_t arg0)
{
MF_DBGLEVEL = arg0; MF_DBGLEVEL = arg0;
Dbprintf("Debug level: %d", MF_DBGLEVEL); Dbprintf("Debug level: %d", MF_DBGLEVEL);
} }
@ -1588,18 +1637,21 @@ void MifareSetDbgLvl(uint16_t arg0){
// destroy the Emulator Memory. // destroy the Emulator Memory.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){ void MifareEMemClr(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
{
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
emlClearMem(); emlClearMem();
} }
void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){ void MifareEMemSet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
{
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
if (arg2 == 0) arg2 = 16; // backwards compat... default bytewidth if (arg2 == 0) arg2 = 16; // backwards compat... default bytewidth
emlSetMem_xt(datain, arg0, arg1, arg2); // data, block num, blocks count, block byte width emlSetMem_xt(datain, arg0, arg1, arg2); // data, block num, blocks count, block byte width
} }
void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){ void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
{
FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
byte_t buf[USB_CMD_DATA_SIZE] = {0x00}; byte_t buf[USB_CMD_DATA_SIZE] = {0x00};
emlGetMem(buf, arg0, arg1); // data, block num, blocks count (max 4) emlGetMem(buf, arg0, arg1); // data, block num, blocks count (max 4)
@ -1613,7 +1665,8 @@ void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
// Load a card into the emulator memory // Load a card into the emulator memory
// //
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){ void MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain)
{
uint8_t numSectors = arg0; uint8_t numSectors = arg0;
uint8_t keyType = arg1; uint8_t keyType = arg1;
uint64_t ui64Key = 0; uint64_t ui64Key = 0;
@ -1710,7 +1763,8 @@ uint8_t wupC1[] = { MIFARE_MAGICWUPC1 };
uint8_t wupC2[] = { MIFARE_MAGICWUPC2 }; uint8_t wupC2[] = { MIFARE_MAGICWUPC2 };
uint8_t wipeC[] = { MIFARE_MAGICWIPEC }; uint8_t wipeC[] = { MIFARE_MAGICWIPEC };
void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain)
{
// params // params
uint8_t workFlags = arg0; uint8_t workFlags = arg0;
@ -1820,7 +1874,8 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){
OnSuccessMagic(); OnSuccessMagic();
} }
void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain)
{
uint8_t workFlags = arg0; uint8_t workFlags = arg0;
uint8_t blockNo = arg1; uint8_t blockNo = arg1;
@ -1896,7 +1951,8 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){
OnSuccessMagic(); OnSuccessMagic();
} }
void MifareCIdent(){ void MifareCIdent()
{
#define GEN_1A 1 #define GEN_1A 1
#define GEN_1B 2 #define GEN_1B 2
#define GEN_2 4 #define GEN_2 4
@ -1921,7 +1977,8 @@ void MifareCIdent(){
isGen = GEN_1A; isGen = GEN_1A;
goto OUT; goto OUT;
TEST2:; TEST2:
;
/* /*
// Generation 2 test // Generation 2 test
@ -1940,7 +1997,8 @@ TEST2:;
isGen = GEN_2; isGen = GEN_2;
}; };
*/ */
OUT:; OUT:
;
// removed the if, since some magic tags misbehavies and send an answer to it. // removed the if, since some magic tags misbehavies and send an answer to it.
mifare_classic_halt_ex(NULL); mifare_classic_halt_ex(NULL);
cmd_send(CMD_ACK, isGen, 0, 0, 0, 0); cmd_send(CMD_ACK, isGen, 0, 0, 0, 0);
@ -1948,18 +2006,21 @@ OUT:;
OnSuccessMagic(); OnSuccessMagic();
} }
void OnSuccessMagic(){ void OnSuccessMagic()
{
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff(); LEDsoff();
set_tracing(false); set_tracing(false);
} }
void OnErrorMagic(uint8_t reason){ void OnErrorMagic(uint8_t reason)
{
// ACK, ISOK, reason,0,0,0 // ACK, ISOK, reason,0,0,0
cmd_send(CMD_ACK, 0, reason, 0, 0, 0); cmd_send(CMD_ACK, 0, reason, 0, 0, 0);
OnSuccessMagic(); OnSuccessMagic();
} }
void MifareSetMod(uint8_t mod, uint8_t *key) { void MifareSetMod(uint8_t mod, uint8_t *key)
{
uint64_t ui64Key = bytes_to_num(key, 6); uint64_t ui64Key = bytes_to_num(key, 6);
// variables // variables
@ -2019,7 +2080,8 @@ void MifareSetMod(uint8_t mod, uint8_t *key) {
// //
// DESFIRE // DESFIRE
// //
void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain)
{
byte_t dataout[12] = {0x00}; byte_t dataout[12] = {0x00};
uint8_t uid[10] = {0x00}; uint8_t uid[10] = {0x00};
uint32_t cuid = 0; uint32_t cuid = 0;
@ -2045,7 +2107,8 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){
cmd_send(CMD_ACK, 1, cuid, 0, dataout, sizeof(dataout)); cmd_send(CMD_ACK, 1, cuid, 0, dataout, sizeof(dataout));
} }
void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain)
{
uint32_t cuid = arg0; uint32_t cuid = arg0;
uint8_t key[16] = {0x00}; uint8_t key[16] = {0x00};
byte_t dataout[12] = {0x00}; byte_t dataout[12] = {0x00};

View file

@ -16,7 +16,8 @@ static uint8_t deselect_cmd[] = {0xc2,0xe0,0xb4};
/* PCB CID CMD PAYLOAD */ /* PCB CID CMD PAYLOAD */
//static uint8_t __res[MAX_FRAME_SIZE]; //static uint8_t __res[MAX_FRAME_SIZE];
bool InitDesfireCard(){ bool InitDesfireCard()
{
iso14a_card_select_t card; iso14a_card_select_t card;
@ -40,7 +41,8 @@ enum {
BAR = 0x08, BAR = 0x08,
} CmdOptions ; } CmdOptions ;
void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain){ void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain)
{
/* ARG0 contains flags. /* ARG0 contains flags.
0x01 = init card. 0x01 = init card.
@ -84,7 +86,8 @@ void MifareSendCommand(uint8_t arg0, uint8_t arg1, uint8_t *datain){
cmd_send(CMD_ACK, 1, len, 0, resp, len); cmd_send(CMD_ACK, 1, len, 0, resp, len);
} }
void MifareDesfireGetInformation(){ void MifareDesfireGetInformation()
{
int len = 0; int len = 0;
iso14a_card_select_t card; iso14a_card_select_t card;
@ -167,7 +170,8 @@ void MifareDesfireGetInformation(){
OnSuccess(); OnSuccess();
} }
void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain){ void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain)
{
int len = 0; int len = 0;
//uint8_t PICC_MASTER_KEY8[8] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47}; //uint8_t PICC_MASTER_KEY8[8] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47};
@ -499,7 +503,8 @@ void MifareDES_Auth1(uint8_t mode, uint8_t algo, uint8_t keyno, uint8_t *datain
// cmd = cmd bytes to send // cmd = cmd bytes to send
// cmd_len = length of cmd // cmd_len = length of cmd
// dataout = pointer to response data array // dataout = pointer to response data array
int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){ int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout)
{
size_t len = 0; size_t len = 0;
size_t wrappedLen = 0; size_t wrappedLen = 0;
@ -524,8 +529,7 @@ int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){
else if (len >= 4 // PCB+CID+CRC = 4 bytes else if (len >= 4 // PCB+CID+CRC = 4 bytes
&& ((resp[0] & 0xC0) == 0 // I-Block && ((resp[0] & 0xC0) == 0 // I-Block
|| (resp[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0 || (resp[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0
&& (resp[0] & 0x01) == pcb_blocknum) // equal block numbers && (resp[0] & 0x01) == pcb_blocknum) { // equal block numbers
{
pcb_blocknum ^= 1; //toggle next block pcb_blocknum ^= 1; //toggle next block
} }
@ -534,7 +538,8 @@ int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){
} }
// CreateAPDU // CreateAPDU
size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout){ size_t CreateAPDU(uint8_t *datain, size_t len, uint8_t *dataout)
{
size_t cmdlen = MIN(len + 4, USB_CMD_DATA_SIZE - 1); size_t cmdlen = MIN(len + 4, USB_CMD_DATA_SIZE - 1);
@ -558,14 +563,16 @@ size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout){
// crc_update(&desfire_crc32, byte, 8); // crc_update(&desfire_crc32, byte, 8);
// uint32_t crc = crc_finish(&desfire_crc32); // uint32_t crc = crc_finish(&desfire_crc32);
void OnSuccess(){ void OnSuccess()
{
pcb_blocknum = 0; pcb_blocknum = 0;
ReaderTransmit(deselect_cmd, 3, NULL); ReaderTransmit(deselect_cmd, 3, NULL);
mifare_ultra_halt(); mifare_ultra_halt();
switch_off(); switch_off();
} }
void OnError(uint8_t reason){ void OnError(uint8_t reason)
{
cmd_send(CMD_ACK, 0, reason, 0, 0, 0); cmd_send(CMD_ACK, 0, reason, 0, 0, 0);
OnSuccess(); OnSuccess();
} }

View file

@ -24,7 +24,8 @@ static uint32_t timerData = 0;
// if no activity for 2sec, it sends the collected data to the client. // if no activity for 2sec, it sends the collected data to the client.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// "hf mf sniff" // "hf mf sniff"
void RAMFUNC SniffMifare(uint8_t param) { void RAMFUNC SniffMifare(uint8_t param)
{
// param: // param:
// bit 0 - trigger from first card answer // bit 0 - trigger from first card answer
// bit 1 - trigger from first reader 7-bit request // bit 1 - trigger from first reader 7-bit request
@ -35,7 +36,8 @@ void RAMFUNC SniffMifare(uint8_t param) {
// Allocate memory from BigBuf for some buffers // Allocate memory from BigBuf for some buffers
// free all previous allocations first // free all previous allocations first
BigBuf_free(); BigBuf_Clear_ext(false); BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace(); clear_trace();
set_tracing(true); set_tracing(true);
@ -175,7 +177,8 @@ void RAMFUNC SniffMifare(uint8_t param) {
switch_off(); switch_off();
} }
void MfSniffInit(void){ void MfSniffInit(void)
{
memset(sniffUID, 0x00, sizeof(sniffUID)); memset(sniffUID, 0x00, sizeof(sniffUID));
memset(sniffATQA, 0x00, sizeof(sniffATQA)); memset(sniffATQA, 0x00, sizeof(sniffATQA));
memset(sniffBuf, 0x00, sizeof(sniffBuf)); memset(sniffBuf, 0x00, sizeof(sniffBuf));
@ -184,7 +187,8 @@ void MfSniffInit(void){
timerData = 0; timerData = 0;
} }
void MfSniffEnd(void){ void MfSniffEnd(void)
{
LED_B_ON(); LED_B_ON();
cmd_send(CMD_ACK, 0, 0, 0, 0, 0); cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
LED_B_OFF(); LED_B_OFF();
@ -304,7 +308,8 @@ bool RAMFUNC MfSniffLogic(const uint8_t *data, uint16_t len, uint8_t *parity, ui
} }
*/ */
void RAMFUNC MfSniffSend() { void RAMFUNC MfSniffSend()
{
uint16_t tracelen = BigBuf_get_traceLen(); uint16_t tracelen = BigBuf_get_traceLen();
uint16_t chunksize = 0; uint16_t chunksize = 0;
int packlen = tracelen; // total number of bytes to send int packlen = tracelen; // total number of bytes to send

View file

@ -13,7 +13,8 @@
int MF_DBGLEVEL = MF_DBG_ERROR; int MF_DBGLEVEL = MF_DBG_ERROR;
// crypto1 helpers // crypto1 helpers
void mf_crypto1_decryptEx(struct Crypto1State *pcs, uint8_t *data_in, int len, uint8_t *data_out){ void mf_crypto1_decryptEx(struct Crypto1State *pcs, uint8_t *data_in, int len, uint8_t *data_out)
{
uint8_t bt = 0; uint8_t bt = 0;
int i; int i;
@ -30,11 +31,13 @@ void mf_crypto1_decryptEx(struct Crypto1State *pcs, uint8_t *data_in, int len, u
return; return;
} }
void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len){ void mf_crypto1_decrypt(struct Crypto1State *pcs, uint8_t *data, int len)
{
mf_crypto1_decryptEx(pcs, data, len, data); mf_crypto1_decryptEx(pcs, data, len, data);
} }
void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, uint16_t len, uint8_t *par) { void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, uint16_t len, uint8_t *par)
{
uint8_t bt = 0; uint8_t bt = 0;
int i; int i;
par[0] = 0; par[0] = 0;
@ -48,7 +51,8 @@ void mf_crypto1_encrypt(struct Crypto1State *pcs, uint8_t *data, uint16_t len, u
} }
} }
uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data) { uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data)
{
uint8_t bt = 0; uint8_t bt = 0;
bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data, 0)) << 0; bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data, 0)) << 0;
bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data, 1)) << 1; bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data, 1)) << 1;
@ -58,7 +62,8 @@ uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data) {
} }
// send X byte basic commands // send X byte basic commands
int mifare_sendcmd(uint8_t cmd, uint8_t* data, uint8_t data_size, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing) { int mifare_sendcmd(uint8_t cmd, uint8_t *data, uint8_t data_size, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing)
{
uint8_t dcmd[data_size + 3]; uint8_t dcmd[data_size + 3];
dcmd[0] = cmd; dcmd[0] = cmd;
memcpy(dcmd + 1, data, data_size); memcpy(dcmd + 1, data, data_size);
@ -73,7 +78,8 @@ int mifare_sendcmd(uint8_t cmd, uint8_t* data, uint8_t data_size, uint8_t* answe
} }
// send 2 byte commands // send 2 byte commands
int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing) { int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing)
{
uint16_t pos, res; uint16_t pos, res;
uint8_t dcmd[4] = {cmd, data, 0x00, 0x00}; uint8_t dcmd[4] = {cmd, data, 0x00, 0x00};
uint8_t ecmd[4] = {0x00, 0x00, 0x00, 0x00}; uint8_t ecmd[4] = {0x00, 0x00, 0x00, 0x00};
@ -113,11 +119,13 @@ int mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd,
} }
// mifare classic commands // mifare classic commands
int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested) { int mifare_classic_auth(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested)
{
return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL); return mifare_classic_authex(pcs, uid, blockNo, keyType, ui64Key, isNested, NULL, NULL);
} }
int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing) { int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t keyType, uint64_t ui64Key, uint8_t isNested, uint32_t *ntptr, uint32_t *timing)
{
int len; int len;
uint32_t pos, nt, ntpp; // Supplied tag nonce uint32_t pos, nt, ntpp; // Supplied tag nonce
uint8_t par[1] = {0x00}; uint8_t par[1] = {0x00};
@ -195,7 +203,8 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN
return 0; return 0;
} }
int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) { int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
int len; int len;
uint8_t bt[2] = {0x00, 0x00}; uint8_t bt[2] = {0x00, 0x00};
@ -224,7 +233,8 @@ int mifare_classic_readblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blo
} }
// mifare ultralight commands // mifare ultralight commands
int mifare_ul_ev1_auth(uint8_t *keybytes, uint8_t *pack){ int mifare_ul_ev1_auth(uint8_t *keybytes, uint8_t *pack)
{
uint16_t len = 0; uint16_t len = 0;
uint8_t resp[4] = {0x00, 0x00, 0x00, 0x00}; uint8_t resp[4] = {0x00, 0x00, 0x00, 0x00};
@ -249,7 +259,8 @@ int mifare_ul_ev1_auth(uint8_t *keybytes, uint8_t *pack){
return 1; return 1;
} }
int mifare_ultra_auth(uint8_t *keybytes){ int mifare_ultra_auth(uint8_t *keybytes)
{
/// 3des2k /// 3des2k
uint8_t random_a[8] = {1, 1, 1, 1, 1, 1, 1, 1}; uint8_t random_a[8] = {1, 1, 1, 1, 1, 1, 1, 1};
@ -334,7 +345,8 @@ int mifare_ultra_auth(uint8_t *keybytes){
return 1; return 1;
} }
int mifare_ultra_readblockEx(uint8_t blockNo, uint8_t *blockData) { int mifare_ultra_readblockEx(uint8_t blockNo, uint8_t *blockData)
{
uint16_t len = 0; uint16_t len = 0;
uint8_t bt[2] = {0x00, 0x00}; uint8_t bt[2] = {0x00, 0x00};
uint8_t receivedAnswer[MAX_FRAME_SIZE] = {0x00}; uint8_t receivedAnswer[MAX_FRAME_SIZE] = {0x00};
@ -360,7 +372,8 @@ int mifare_ultra_readblockEx(uint8_t blockNo, uint8_t *blockData) {
memcpy(blockData, receivedAnswer, 14); memcpy(blockData, receivedAnswer, 14);
return 0; return 0;
} }
int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData) { int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData)
{
#define MFU_MAX_RETRIES 5 #define MFU_MAX_RETRIES 5
uint8_t res; uint8_t res;
@ -379,7 +392,8 @@ int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData) {
return res; return res;
} }
int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData) { int mifare_classic_writeblock(struct Crypto1State *pcs, uint32_t uid, uint8_t blockNo, uint8_t *blockData)
{
// variables // variables
uint16_t len = 0; uint16_t len = 0;
uint32_t pos = 0; uint32_t pos = 0;
@ -457,7 +471,8 @@ int mifare_ultra_writeblock_compat(uint8_t blockNo, uint8_t *blockData) {
} }
*/ */
int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) { int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData)
{
uint16_t len = 0; uint16_t len = 0;
uint8_t block[5] = {blockNo, 0x00, 0x00, 0x00, 0x00 }; uint8_t block[5] = {blockNo, 0x00, 0x00, 0x00, 0x00 };
uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00}; uint8_t receivedAnswer[MAX_MIFARE_FRAME_SIZE] = {0x00};
@ -475,7 +490,8 @@ int mifare_ultra_writeblock(uint8_t blockNo, uint8_t *blockData) {
} }
return 0; return 0;
} }
int mifare_classic_halt_ex(struct Crypto1State *pcs) { int mifare_classic_halt_ex(struct Crypto1State *pcs)
{
uint8_t receivedAnswer[4] = {0x00, 0x00, 0x00, 0x00}; uint8_t receivedAnswer[4] = {0x00, 0x00, 0x00, 0x00};
uint16_t len = mifare_sendcmd_short(pcs, (pcs == NULL) ? CRYPT_NONE : CRYPT_ALL, ISO14443A_CMD_HALT, 0x00, receivedAnswer, NULL, NULL); uint16_t len = mifare_sendcmd_short(pcs, (pcs == NULL) ? CRYPT_NONE : CRYPT_ALL, ISO14443A_CMD_HALT, 0x00, receivedAnswer, NULL, NULL);
if (len != 0) { if (len != 0) {
@ -484,11 +500,13 @@ int mifare_classic_halt_ex(struct Crypto1State *pcs) {
} }
return 0; return 0;
} }
int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid) { int mifare_classic_halt(struct Crypto1State *pcs, uint32_t uid)
{
return mifare_classic_halt_ex(pcs); return mifare_classic_halt_ex(pcs);
} }
int mifare_ultra_halt() { int mifare_ultra_halt()
{
uint16_t len = 0; uint16_t len = 0;
uint8_t receivedAnswer[4] = {0x00, 0x00, 0x00, 0x00}; uint8_t receivedAnswer[4] = {0x00, 0x00, 0x00, 0x00};
len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_HALT, 0x00, receivedAnswer, NULL, NULL); len = mifare_sendcmd_short(NULL, CRYPT_NONE, ISO14443A_CMD_HALT, 0x00, receivedAnswer, NULL, NULL);
@ -502,11 +520,13 @@ int mifare_ultra_halt() {
// Mifare Memory Structure: up to 32 Sectors with 4 blocks each (1k and 2k cards), // Mifare Memory Structure: up to 32 Sectors with 4 blocks each (1k and 2k cards),
// plus evtl. 8 sectors with 16 blocks each (4k cards) // plus evtl. 8 sectors with 16 blocks each (4k cards)
uint8_t NumBlocksPerSector(uint8_t sectorNo) { uint8_t NumBlocksPerSector(uint8_t sectorNo)
{
return (sectorNo < 32) ? 4 : 16; return (sectorNo < 32) ? 4 : 16;
} }
uint8_t FirstBlockOfSector(uint8_t sectorNo) { uint8_t FirstBlockOfSector(uint8_t sectorNo)
{
if (sectorNo < 32) if (sectorNo < 32)
return sectorNo * 4; return sectorNo * 4;
else else
@ -515,26 +535,31 @@ uint8_t FirstBlockOfSector(uint8_t sectorNo) {
} }
// work with emulator memory // work with emulator memory
void emlSetMem(uint8_t *data, int blockNum, int blocksCount) { void emlSetMem(uint8_t *data, int blockNum, int blocksCount)
{
emlSetMem_xt(data, blockNum, blocksCount, 16); emlSetMem_xt(data, blockNum, blocksCount, 16);
} }
void emlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidth) { void emlSetMem_xt(uint8_t *data, int blockNum, int blocksCount, int blockBtWidth)
{
uint8_t *emCARD = BigBuf_get_EM_addr(); uint8_t *emCARD = BigBuf_get_EM_addr();
memcpy(emCARD + blockNum * blockBtWidth, data, blocksCount * blockBtWidth); memcpy(emCARD + blockNum * blockBtWidth, data, blocksCount * blockBtWidth);
} }
void emlGetMem(uint8_t *data, int blockNum, int blocksCount) { void emlGetMem(uint8_t *data, int blockNum, int blocksCount)
{
uint8_t *emCARD = BigBuf_get_EM_addr(); uint8_t *emCARD = BigBuf_get_EM_addr();
memcpy(data, emCARD + blockNum * 16, blocksCount * 16); memcpy(data, emCARD + blockNum * 16, blocksCount * 16);
} }
void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount) { void emlGetMemBt(uint8_t *data, int bytePtr, int byteCount)
{
uint8_t *emCARD = BigBuf_get_EM_addr(); uint8_t *emCARD = BigBuf_get_EM_addr();
memcpy(data, emCARD + bytePtr, byteCount); memcpy(data, emCARD + bytePtr, byteCount);
} }
int emlCheckValBl(int blockNum) { int emlCheckValBl(int blockNum)
{
uint8_t *emCARD = BigBuf_get_EM_addr(); uint8_t *emCARD = BigBuf_get_EM_addr();
uint8_t *data = emCARD + blockNum * 16; uint8_t *data = emCARD + blockNum * 16;
@ -549,7 +574,8 @@ int emlCheckValBl(int blockNum) {
return 0; return 0;
} }
int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) { int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum)
{
uint8_t *emCARD = BigBuf_get_EM_addr(); uint8_t *emCARD = BigBuf_get_EM_addr();
uint8_t *data = emCARD + blockNum * 16; uint8_t *data = emCARD + blockNum * 16;
@ -561,7 +587,8 @@ int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) {
return 0; return 0;
} }
int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) { int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum)
{
uint8_t *emCARD = BigBuf_get_EM_addr(); uint8_t *emCARD = BigBuf_get_EM_addr();
uint8_t *data = emCARD + blockNum * 16; uint8_t *data = emCARD + blockNum * 16;
@ -578,14 +605,16 @@ int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) {
return 0; return 0;
} }
uint64_t emlGetKey(int sectorNum, int keyType) { uint64_t emlGetKey(int sectorNum, int keyType)
{
uint8_t key[6] = {0x00}; uint8_t key[6] = {0x00};
uint8_t *emCARD = BigBuf_get_EM_addr(); uint8_t *emCARD = BigBuf_get_EM_addr();
memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6); memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 6);
return bytes_to_num(key, 6); return bytes_to_num(key, 6);
} }
void emlClearMem(void) { void emlClearMem(void)
{
const uint8_t trailer[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x80, 0x69, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; const uint8_t trailer[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, 0x80, 0x69, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
const uint8_t uid[] = {0xe6, 0x84, 0x87, 0xf3, 0x16, 0x88, 0x04, 0x00, 0x46, 0x8e, 0x45, 0x55, 0x4d, 0x70, 0x41, 0x04}; const uint8_t uid[] = {0xe6, 0x84, 0x87, 0xf3, 0x16, 0x88, 0x04, 0x00, 0x46, 0x8e, 0x45, 0x55, 0x4d, 0x70, 0x41, 0x04};
uint8_t *emCARD = BigBuf_get_EM_addr(); uint8_t *emCARD = BigBuf_get_EM_addr();
@ -602,7 +631,8 @@ void emlClearMem(void) {
// Mifare desfire commands // Mifare desfire commands
int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer, uint8_t *answer_parity, uint32_t *timing) { int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing)
{
uint8_t dcmd[5] = {cmd, data[0], data[1], 0x00, 0x00}; uint8_t dcmd[5] = {cmd, data[0], data[1], 0x00, 0x00};
AddCrc14A(dcmd, 3); AddCrc14A(dcmd, 3);
@ -615,7 +645,8 @@ int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cm
return len; return len;
} }
int mifare_sendcmd_special2(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t* data, uint8_t* answer,uint8_t *answer_parity, uint32_t *timing) { int mifare_sendcmd_special2(struct Crypto1State *pcs, uint8_t crypted, uint8_t cmd, uint8_t *data, uint8_t *answer, uint8_t *answer_parity, uint32_t *timing)
{
uint8_t dcmd[20] = {0x00}; uint8_t dcmd[20] = {0x00};
dcmd[0] = cmd; dcmd[0] = cmd;
memcpy(dcmd + 1, data, 17); memcpy(dcmd + 1, data, 17);
@ -630,7 +661,8 @@ int mifare_sendcmd_special2(struct Crypto1State *pcs, uint8_t crypted, uint8_t c
return len; return len;
} }
int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData){ int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData)
{
int len; int len;
// load key, keynumber // load key, keynumber
@ -658,7 +690,8 @@ int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData){
return 1; return 1;
} }
int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData){ int mifare_desfire_des_auth2(uint32_t uid, uint8_t *key, uint8_t *blockData)
{
int len; int len;
uint8_t data[17] = {MFDES_AUTHENTICATION_FRAME}; uint8_t data[17] = {MFDES_AUTHENTICATION_FRAME};

View file

@ -96,7 +96,8 @@ uint8_t xopt__select(bool x, bool y, uint8_t r)
} }
*/ */
void opt_successor(const uint8_t* k, State *s, bool y, State* successor) { void opt_successor(const uint8_t *k, State *s, bool y, State *successor)
{
uint8_t Tt = 1 & opt_T(s); uint8_t Tt = 1 & opt_T(s);
successor->t = (s->t >> 1); successor->t = (s->t >> 1);
@ -109,7 +110,8 @@ void opt_successor(const uint8_t* k, State *s, bool y, State* successor) {
successor->l = successor->r + s->r; successor->l = successor->r + s->r;
} }
void opt_suc(const uint8_t* k,State* s, uint8_t *in, uint8_t length, bool add32Zeroes) { void opt_suc(const uint8_t *k, State *s, uint8_t *in, uint8_t length, bool add32Zeroes)
{
State x2; State x2;
int i; int i;
uint8_t head = 0; uint8_t head = 0;
@ -148,7 +150,8 @@ void opt_suc(const uint8_t* k,State* s, uint8_t *in, uint8_t length, bool add32Z
} }
} }
void opt_output(const uint8_t* k,State* s, uint8_t *buffer) { void opt_output(const uint8_t *k, State *s, uint8_t *buffer)
{
uint8_t times = 0; uint8_t times = 0;
uint8_t bout = 0; uint8_t bout = 0;
State temp = {0, 0, 0, 0}; State temp = {0, 0, 0, 0};
@ -174,7 +177,8 @@ void opt_output(const uint8_t* k,State* s, uint8_t *buffer) {
} }
} }
void opt_MAC(uint8_t* k, uint8_t* input, uint8_t* out) { void opt_MAC(uint8_t *k, uint8_t *input, uint8_t *out)
{
State _init = { State _init = {
((k[0] ^ 0x4c) + 0xEC) & 0xFF,// l ((k[0] ^ 0x4c) + 0xEC) & 0xFF,// l
((k[0] ^ 0x4c) + 0x21) & 0xFF,// r ((k[0] ^ 0x4c) + 0x21) & 0xFF,// r
@ -186,20 +190,23 @@ void opt_MAC(uint8_t* k, uint8_t* input, uint8_t* out) {
opt_output(k, &_init, out); opt_output(k, &_init, out);
} }
uint8_t rev_byte(uint8_t b) { uint8_t rev_byte(uint8_t b)
{
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2; b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1; b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
return b; return b;
} }
void opt_reverse_arraybytecpy(uint8_t* dest, uint8_t *src, size_t len) { void opt_reverse_arraybytecpy(uint8_t *dest, uint8_t *src, size_t len)
{
uint8_t i; uint8_t i;
for (i = 0; i < len ; i++) for (i = 0; i < len ; i++)
dest[i] = rev_byte(src[i]); dest[i] = rev_byte(src[i]);
} }
void opt_doReaderMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) { void opt_doReaderMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4])
{
static uint8_t cc_nr[12]; static uint8_t cc_nr[12];
opt_reverse_arraybytecpy(cc_nr, cc_nr_p, 12); opt_reverse_arraybytecpy(cc_nr, cc_nr_p, 12);
uint8_t dest [] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t dest [] = {0, 0, 0, 0, 0, 0, 0, 0};
@ -208,7 +215,8 @@ void opt_doReaderMAC(uint8_t *cc_nr_p, uint8_t *div_key_p, uint8_t mac[4]) {
opt_reverse_arraybytecpy(mac, dest, 4); opt_reverse_arraybytecpy(mac, dest, 4);
return; return;
} }
void opt_doTagMAC(uint8_t *cc_p, const uint8_t *div_key_p, uint8_t mac[4]) { void opt_doTagMAC(uint8_t *cc_p, const uint8_t *div_key_p, uint8_t mac[4])
{
static uint8_t cc_nr[8 + 4 + 4]; static uint8_t cc_nr[8 + 4 + 4];
opt_reverse_arraybytecpy(cc_nr, cc_p, 12); opt_reverse_arraybytecpy(cc_nr, cc_p, 12);
State _init = { State _init = {
@ -233,7 +241,8 @@ void opt_doTagMAC(uint8_t *cc_p, const uint8_t *div_key_p, uint8_t mac[4]) {
* @param div_key_p * @param div_key_p
* @return the cipher state * @return the cipher state
*/ */
State opt_doTagMAC_1(uint8_t *cc_p, const uint8_t *div_key_p) { State opt_doTagMAC_1(uint8_t *cc_p, const uint8_t *div_key_p)
{
static uint8_t cc_nr[8]; static uint8_t cc_nr[8];
opt_reverse_arraybytecpy(cc_nr, cc_p, 8); opt_reverse_arraybytecpy(cc_nr, cc_p, 8);
State _init = { State _init = {
@ -254,7 +263,8 @@ State opt_doTagMAC_1(uint8_t *cc_p, const uint8_t *div_key_p) {
* @param mac - where to store the MAC * @param mac - where to store the MAC
* @param div_key_p - the key to use * @param div_key_p - the key to use
*/ */
void opt_doTagMAC_2(State _init, uint8_t* nr, uint8_t mac[4], const uint8_t* div_key_p) { void opt_doTagMAC_2(State _init, uint8_t *nr, uint8_t mac[4], const uint8_t *div_key_p)
{
static uint8_t _nr[4]; static uint8_t _nr[4];
opt_reverse_arraybytecpy(_nr, nr, 4); opt_reverse_arraybytecpy(_nr, nr, 4);
opt_suc(div_key_p, &_init, _nr, 4, true); opt_suc(div_key_p, &_init, _nr, 4, true);

View file

@ -3,7 +3,8 @@
#define T0_PCF 8 //period for the pcf7931 in us #define T0_PCF 8 //period for the pcf7931 in us
#define ALLOC 16 #define ALLOC 16
size_t DemodPCF7931(uint8_t **outBlocks) { size_t DemodPCF7931(uint8_t **outBlocks)
{
uint8_t bits[256] = {0x00}; uint8_t bits[256] = {0x00};
uint8_t blocks[8][16]; uint8_t blocks[8][16];
uint8_t *dest = BigBuf_get_addr(); uint8_t *dest = BigBuf_get_addr();
@ -82,8 +83,7 @@ size_t DemodPCF7931(uint8_t **outBlocks) {
} else if (half_switch == 1) { } else if (half_switch == 1) {
bits[bitidx++] = 0; bits[bitidx++] = 0;
half_switch = 0; half_switch = 0;
} } else
else
half_switch++; half_switch++;
} else if (ABS(lc - clock) < tolerance) { } else if (ABS(lc - clock) < tolerance) {
// 64TO // 64TO
@ -128,23 +128,22 @@ size_t DemodPCF7931(uint8_t **outBlocks) {
return num_blocks; return num_blocks;
} }
bool IsBlock0PCF7931(uint8_t *block) { bool IsBlock0PCF7931(uint8_t *block)
{
// assuming all RFU bits are set to 0 // assuming all RFU bits are set to 0
// if PAC is enabled password is set to 0 // if PAC is enabled password is set to 0
if (block[7] == 0x01) if (block[7] == 0x01) {
{
if (!memcmp(block, "\x00\x00\x00\x00\x00\x00\x00", 7) && !memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7)) if (!memcmp(block, "\x00\x00\x00\x00\x00\x00\x00", 7) && !memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7))
return true; return true;
} } else if (block[7] == 0x00) {
else if (block[7] == 0x00)
{
if (!memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7)) if (!memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7))
return true; return true;
} }
return false; return false;
} }
bool IsBlock1PCF7931(uint8_t *block) { bool IsBlock1PCF7931(uint8_t *block)
{
// assuming all RFU bits are set to 0 // assuming all RFU bits are set to 0
if (block[10] == 0 && block[11] == 0 && block[12] == 0 && block[13] == 0) if (block[10] == 0 && block[11] == 0 && block[12] == 0 && block[13] == 0)
if ((block[14] & 0x7f) <= 9 && block[15] <= 9) if ((block[14] & 0x7f) <= 9 && block[15] <= 9)
@ -153,7 +152,8 @@ bool IsBlock1PCF7931(uint8_t *block) {
return false; return false;
} }
void ReadPCF7931() { void ReadPCF7931()
{
int found_blocks = 0; // successfully read blocks int found_blocks = 0; // successfully read blocks
int max_blocks = 8; // readable blocks int max_blocks = 8; // readable blocks
uint8_t memory_blocks[8][17]; // PCF content uint8_t memory_blocks[8][17]; // PCF content
@ -277,8 +277,7 @@ void ReadPCF7931() {
Dbprintf("Button pressed, stopping."); Dbprintf("Button pressed, stopping.");
goto end; goto end;
} }
} } while (found_blocks != max_blocks);
while (found_blocks != max_blocks);
end: end:
Dbprintf("-----------------------------------------"); Dbprintf("-----------------------------------------");
@ -304,7 +303,8 @@ void ReadPCF7931() {
cmd_send(CMD_ACK, 0, 0, 0, 0, 0); cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
} }
static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) { static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data)
{
uint32_t tab[1024] = {0}; // data times frame uint32_t tab[1024] = {0}; // data times frame
uint32_t u = 0; uint32_t u = 0;
uint8_t parity = 0; uint8_t parity = 0;
@ -338,24 +338,20 @@ static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int3
} }
//byte address on 4 bits //byte address on 4 bits
for (u = 0; u < 4; ++u) for (u = 0; u < 4; ++u) {
{
if (byte & (1 << u)) { // bit 1 if (byte & (1 << u)) { // bit 1
parity++; parity++;
AddBitPCF7931(1, tab, l, p); AddBitPCF7931(1, tab, l, p);
} } else // bit 0
else // bit 0
AddBitPCF7931(0, tab, l, p); AddBitPCF7931(0, tab, l, p);
} }
//data on 8 bits //data on 8 bits
for (u=0; u<8; u++) for (u = 0; u < 8; u++) {
{
if (data & (1 << u)) { // bit 1 if (data & (1 << u)) { // bit 1
parity++; parity++;
AddBitPCF7931(1, tab, l, p); AddBitPCF7931(1, tab, l, p);
} } else //bit 0
else //bit 0
AddBitPCF7931(0, tab, l, p); AddBitPCF7931(0, tab, l, p);
} }
@ -390,7 +386,8 @@ static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int3
@param byte : address of the byte to write @param byte : address of the byte to write
@param data : data to write @param data : data to write
*/ */
void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) { void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data)
{
Dbprintf("Initialization delay : %d us", init_delay); Dbprintf("Initialization delay : %d us", init_delay);
Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p); Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p);
Dbprintf("Password (LSB first on each byte): %02x %02x %02x %02x %02x %02x %02x", pass1, pass2, pass3, pass4, pass5, pass6, pass7); Dbprintf("Password (LSB first on each byte): %02x %02x %02x %02x %02x %02x %02x", pass1, pass2, pass3, pass4, pass5, pass6, pass7);
@ -408,7 +405,8 @@ void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, ui
* @param tab : array of the data frame * @param tab : array of the data frame
*/ */
void SendCmdPCF7931(uint32_t * tab){ void SendCmdPCF7931(uint32_t *tab)
{
uint16_t u = 0, tempo = 0; uint16_t u = 0, tempo = 0;
Dbprintf("Sending data frame..."); Dbprintf("Sending data frame...");
@ -464,7 +462,8 @@ void SendCmdPCF7931(uint32_t * tab){
* @param l : offset on low pulse width * @param l : offset on low pulse width
* @param p : offset on low pulse positioning * @param p : offset on low pulse positioning
*/ */
bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p){ bool AddBytePCF7931(uint8_t byte, uint32_t *tab, int32_t l, int32_t p)
{
uint32_t u; uint32_t u;
for (u = 0; u < 8; ++u) { for (u = 0; u < 8; ++u) {
if (byte & (1 << u)) { //bit is 1 if (byte & (1 << u)) { //bit is 1
@ -483,7 +482,8 @@ bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p){
* @param l : offset on low pulse width * @param l : offset on low pulse width
* @param p : offset on low pulse positioning * @param p : offset on low pulse positioning
*/ */
bool AddBitPCF7931(bool b, uint32_t * tab, int32_t l, int32_t p){ bool AddBitPCF7931(bool b, uint32_t *tab, int32_t l, int32_t p)
{
uint8_t u = 0; uint8_t u = 0;
//we put the cursor at the last value of the array //we put the cursor at the last value of the array
@ -518,7 +518,8 @@ bool AddBitPCF7931(bool b, uint32_t * tab, int32_t l, int32_t p){
* @param c : delay of the last high pulse * @param c : delay of the last high pulse
* @param tab : array of the data frame * @param tab : array of the data frame
*/ */
bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t * tab){ bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t *tab)
{
uint32_t u = 0; uint32_t u = 0;
for (u = 0; tab[u] != 0; u += 3) {} //we put the cursor at the last value of the array for (u = 0; tab[u] != 0; u += 3) {} //we put the cursor at the last value of the array

View file

@ -134,10 +134,22 @@ kvsprintf(char const *fmt, void *arg, int radix, va_list ap)
return (retval); return (retval);
} }
percent = fmt - 1; percent = fmt - 1;
qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0; qflag = 0;
sign = 0; dot = 0; dwidth = 0; upper = 0; lflag = 0;
cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0; ladjust = 0;
reswitch: switch (ch = (u_char)*fmt++) { sharpflag = 0;
neg = 0;
sign = 0;
dot = 0;
dwidth = 0;
upper = 0;
cflag = 0;
hflag = 0;
jflag = 0;
tflag = 0;
zflag = 0;
reswitch:
switch (ch = (u_char) * fmt++) {
case '.': case '.':
dot = 1; dot = 1;
goto reswitch; goto reswitch;
@ -169,8 +181,15 @@ reswitch: switch (ch = (u_char)*fmt++) {
padc = '0'; padc = '0';
goto reswitch; goto reswitch;
} }
case '1': case '2': case '3': case '4': case '1':
case '5': case '6': case '7': case '8': case '9': case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
for (n = 0;; ++fmt) { for (n = 0;; ++fmt) {
n = n * 10 + ch - '0'; n = n * 10 + ch - '0';
ch = *fmt; ch = *fmt;

View file

@ -46,7 +46,8 @@ int memcmp(const void *av, const void *bv, int len)
return 0; return 0;
} }
void memxor(uint8_t * dest, uint8_t * src, size_t len) { void memxor(uint8_t *dest, uint8_t *src, size_t len)
{
for (; len > 0; len--, dest++, src++) for (; len > 0; len--, dest++, src++)
*dest ^= *src; *dest ^= *src;
} }

View file

@ -11,7 +11,8 @@
#include "ticks.h" #include "ticks.h"
// attempt at high resolution microsecond timer // attempt at high resolution microsecond timer
// beware: timer counts in 21.3uS increments (1024/48Mhz) // beware: timer counts in 21.3uS increments (1024/48Mhz)
void SpinDelayUs(int us) { void SpinDelayUs(int us)
{
int ticks = (48 * us) >> 10; int ticks = (48 * us) >> 10;
// Borrow a PWM unit for my real-time clock // Borrow a PWM unit for my real-time clock
@ -33,7 +34,8 @@ void SpinDelayUs(int us) {
} }
} }
void SpinDelay(int ms) { void SpinDelay(int ms)
{
// convert to uS and call microsecond delay function // convert to uS and call microsecond delay function
SpinDelayUs(ms * 1000); SpinDelayUs(ms * 1000);
} }
@ -46,7 +48,8 @@ void SpinDelay(int ms) {
// SpinDelay(1000); // SpinDelay(1000);
// ti = GetTickCount() - ti; // ti = GetTickCount() - ti;
// Dbprintf("timer(1s): %d t=%d", ti, GetTickCount()); // Dbprintf("timer(1s): %d t=%d", ti, GetTickCount());
void StartTickCount(void) { void StartTickCount(void)
{
// This timer is based on the slow clock. The slow clock frequency is between 22kHz and 40kHz. // This timer is based on the slow clock. The slow clock frequency is between 22kHz and 40kHz.
// We can determine the actual slow clock frequency by looking at the Main Clock Frequency Register. // We can determine the actual slow clock frequency by looking at the Main Clock Frequency Register.
uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & 0xffff; // = 16 * main clock frequency (16MHz) / slow clock frequency uint16_t mainf = AT91C_BASE_PMC->PMC_MCFR & 0xffff; // = 16 * main clock frequency (16MHz) / slow clock frequency
@ -58,14 +61,16 @@ void StartTickCount(void) {
/* /*
* Get the current count. * Get the current count.
*/ */
uint32_t RAMFUNC GetTickCount(void){ uint32_t RAMFUNC GetTickCount(void)
{
return AT91C_BASE_RTTC->RTTC_RTVR;// was * 2; return AT91C_BASE_RTTC->RTTC_RTVR;// was * 2;
} }
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// microseconds timer // microseconds timer
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void StartCountUS(void) { void StartCountUS(void)
{
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1); AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE; AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
@ -88,7 +93,8 @@ void StartCountUS(void) {
while (AT91C_BASE_TC1->TC_CV > 0); while (AT91C_BASE_TC1->TC_CV > 0);
} }
uint32_t RAMFUNC GetCountUS(void){ uint32_t RAMFUNC GetCountUS(void)
{
//return (AT91C_BASE_TC1->TC_CV * 0x8000) + ((AT91C_BASE_TC0->TC_CV / 15) * 10); //return (AT91C_BASE_TC1->TC_CV * 0x8000) + ((AT91C_BASE_TC0->TC_CV / 15) * 10);
// By suggestion from PwPiwi, http://www.proxmark.org/forum/viewtopic.php?pid=17548#p17548 // By suggestion from PwPiwi, http://www.proxmark.org/forum/viewtopic.php?pid=17548#p17548
return ((uint32_t)AT91C_BASE_TC1->TC_CV) * 0x8000 + (((uint32_t)AT91C_BASE_TC0->TC_CV) * 2) / 3; return ((uint32_t)AT91C_BASE_TC1->TC_CV) * 0x8000 + (((uint32_t)AT91C_BASE_TC0->TC_CV) * 2) / 3;
@ -97,7 +103,8 @@ uint32_t RAMFUNC GetCountUS(void){
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Timer for iso14443 commands. Uses ssp_clk from FPGA // Timer for iso14443 commands. Uses ssp_clk from FPGA
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void StartCountSspClk(void) { void StartCountSspClk(void)
{
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1) | (1 << AT91C_ID_TC2); // Enable Clock to all timers AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1) | (1 << AT91C_ID_TC2); // Enable Clock to all timers
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_TIOA1 // XC0 Clock = TIOA1 AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_TIOA1 // XC0 Clock = TIOA1
| AT91C_TCB_TC1XC1S_NONE // XC1 Clock = none | AT91C_TCB_TC1XC1S_NONE // XC1 Clock = none
@ -154,14 +161,16 @@ void StartCountSspClk(void) {
// Therefore need to wait quite some time before we can use the counter. // Therefore need to wait quite some time before we can use the counter.
while (AT91C_BASE_TC2->TC_CV > 0); while (AT91C_BASE_TC2->TC_CV > 0);
} }
void ResetSspClk(void) { void ResetSspClk(void)
{
//enable clock of timer and software trigger //enable clock of timer and software trigger
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG; AT91C_BASE_TC2->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
while (AT91C_BASE_TC2->TC_CV > 0); while (AT91C_BASE_TC2->TC_CV > 0);
} }
uint32_t RAMFUNC GetCountSspClk(void) { uint32_t RAMFUNC GetCountSspClk(void)
{
uint32_t tmp_count = (AT91C_BASE_TC2->TC_CV << 16) | AT91C_BASE_TC0->TC_CV; uint32_t tmp_count = (AT91C_BASE_TC2->TC_CV << 16) | AT91C_BASE_TC0->TC_CV;
if ((tmp_count & 0x0000ffff) == 0) //small chance that we may have missed an increment in TC2 if ((tmp_count & 0x0000ffff) == 0) //small chance that we may have missed an increment in TC2
return (AT91C_BASE_TC2->TC_CV << 16); return (AT91C_BASE_TC2->TC_CV << 16);
@ -172,7 +181,8 @@ uint32_t RAMFUNC GetCountSspClk(void) {
// Timer for bitbanging, or LF stuff when you need a very precis timer // Timer for bitbanging, or LF stuff when you need a very precis timer
// 1us = 1.5ticks // 1us = 1.5ticks
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
void StartTicks(void){ void StartTicks(void)
{
// initialization of the timer // initialization of the timer
AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1); AT91C_BASE_PMC->PMC_PCER |= (1 << AT91C_ID_TC0) | (1 << AT91C_ID_TC1);
AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE; AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
@ -205,7 +215,8 @@ void StartTicks(void){
while (AT91C_BASE_TC0->TC_CV > 0); while (AT91C_BASE_TC0->TC_CV > 0);
} }
uint32_t GetTicks(void) { uint32_t GetTicks(void)
{
uint32_t hi, lo; uint32_t hi, lo;
do { do {
@ -218,7 +229,8 @@ uint32_t GetTicks(void) {
// Wait - Spindelay in ticks. // Wait - Spindelay in ticks.
// if called with a high number, this will trigger the WDT... // if called with a high number, this will trigger the WDT...
void WaitTicks(uint32_t ticks){ void WaitTicks(uint32_t ticks)
{
if (ticks == 0) return; if (ticks == 0) return;
ticks += GetTicks(); ticks += GetTicks();
while (GetTicks() < ticks); while (GetTicks() < ticks);
@ -226,15 +238,18 @@ 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(uint16_t us)
{
WaitTicks((uint32_t)us * 3 / 2); WaitTicks((uint32_t)us * 3 / 2);
} }
void WaitMS(uint16_t ms){ void WaitMS(uint16_t ms)
{
WaitTicks((uint32_t)ms * 1500); WaitTicks((uint32_t)ms * 1500);
} }
// stop clock // stop clock
void StopTicks(void){ void StopTicks(void)
{
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS; AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
} }

View file

@ -9,7 +9,8 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "util.h" #include "util.h"
size_t nbytes(size_t nbits) { size_t nbytes(size_t nbits)
{
return (nbits >> 3) + ((nbits % 8) > 0); return (nbits >> 3) + ((nbits % 8) > 0);
} }
@ -18,7 +19,8 @@ size_t nbytes(size_t nbits) {
Returns the value v with the bottom b [0,32] bits reflected. Returns the value v with the bottom b [0,32] bits reflected.
Example: reflect(0x3e23L,3) == 0x3e26 Example: reflect(0x3e23L,3) == 0x3e26
*/ */
uint32_t reflect(uint32_t v, int b) { uint32_t reflect(uint32_t v, int b)
{
uint32_t t = v; uint32_t t = v;
for (int i = 0; i < b; ++i) { for (int i = 0; i < b; ++i) {
if (t & 1) if (t & 1)
@ -30,10 +32,12 @@ uint32_t reflect(uint32_t v, int b) {
return v; return v;
} }
uint8_t reflect8(uint8_t b) { uint8_t reflect8(uint8_t b)
{
return ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32; return ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32;
} }
uint16_t reflect16(uint16_t b) { uint16_t reflect16(uint16_t b)
{
uint16_t v = 0; uint16_t v = 0;
v |= (b & 0x8000) >> 15; v |= (b & 0x8000) >> 15;
v |= (b & 0x4000) >> 13; v |= (b & 0x4000) >> 13;
@ -55,14 +59,16 @@ uint16_t reflect16(uint16_t b) {
return v; return v;
} }
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest) { void num_to_bytes(uint64_t n, size_t len, uint8_t *dest)
{
while (len--) { while (len--) {
dest[len] = (uint8_t) n; dest[len] = (uint8_t) n;
n >>= 8; n >>= 8;
} }
} }
uint64_t bytes_to_num(uint8_t* src, size_t len) { uint64_t bytes_to_num(uint8_t *src, size_t len)
{
uint64_t num = 0; uint64_t num = 0;
while (len--) { while (len--) {
num = (num << 8) | (*src); num = (num << 8) | (*src);
@ -72,7 +78,8 @@ uint64_t bytes_to_num(uint8_t* src, size_t len) {
} }
// RotateLeft - Ultralight, Desfire // RotateLeft - Ultralight, Desfire
void rol(uint8_t *data, const size_t len) { void rol(uint8_t *data, const size_t len)
{
uint8_t first = data[0]; uint8_t first = data[0];
for (size_t i = 0; i < len - 1; i++) { for (size_t i = 0; i < len - 1; i++) {
data[i] = data[i + 1]; data[i] = data[i + 1];
@ -80,48 +87,84 @@ void rol(uint8_t *data, const size_t len) {
data[len - 1] = first; data[len - 1] = first;
} }
void lsl (uint8_t *data, size_t len) { void lsl(uint8_t *data, size_t len)
{
for (size_t n = 0; n < len - 1; n++) { for (size_t n = 0; n < len - 1; n++) {
data[n] = (data[n] << 1) | (data[n + 1] >> 7); data[n] = (data[n] << 1) | (data[n + 1] >> 7);
} }
data[len - 1] <<= 1; data[len - 1] <<= 1;
} }
int32_t le24toh (uint8_t data[3]) { int32_t le24toh(uint8_t data[3])
{
return (data[2] << 16) | (data[1] << 8) | data[0]; return (data[2] << 16) | (data[1] << 8) | data[0];
} }
//convert hex digit to integer //convert hex digit to integer
uint8_t hex2int(char hexchar){ uint8_t hex2int(char hexchar)
{
switch (hexchar) { switch (hexchar) {
case '0': return 0; break; case '0':
case '1': return 1; break; return 0;
case '2': return 2; break; break;
case '3': return 3; break; case '1':
case '4': return 4; break; return 1;
case '5': return 5; break; break;
case '6': return 6; break; case '2':
case '7': return 7; break; return 2;
case '8': return 8; break; break;
case '9': return 9; break; case '3':
return 3;
break;
case '4':
return 4;
break;
case '5':
return 5;
break;
case '6':
return 6;
break;
case '7':
return 7;
break;
case '8':
return 8;
break;
case '9':
return 9;
break;
case 'a': case 'a':
case 'A': return 10; break; case 'A':
return 10;
break;
case 'b': case 'b':
case 'B': return 11; break; case 'B':
return 11;
break;
case 'c': case 'c':
case 'C': return 12; break; case 'C':
return 12;
break;
case 'd': case 'd':
case 'D': return 13; break; case 'D':
return 13;
break;
case 'e': case 'e':
case 'E': return 14; break; case 'E':
return 14;
break;
case 'f': case 'f':
case 'F': return 15; break; case 'F':
return 15;
break;
default: default:
return 0; return 0;
} }
} }
void LEDsoff() { void LEDsoff()
{
LED_A_OFF(); LED_A_OFF();
LED_B_OFF(); LED_B_OFF();
LED_C_OFF(); LED_C_OFF();
@ -129,7 +172,8 @@ void LEDsoff() {
} }
// LEDs: R(C) O(A) G(B) -- R(D) [1, 2, 4 and 8] // LEDs: R(C) O(A) G(B) -- R(D) [1, 2, 4 and 8]
void LED(int led, int ms) { void LED(int led, int ms)
{
if (led & LED_RED) if (led & LED_RED)
LED_C_ON(); LED_C_ON();
if (led & LED_ORANGE) if (led & LED_ORANGE)
@ -154,7 +198,8 @@ void LED(int led, int ms) {
LED_D_OFF(); LED_D_OFF();
} }
void SpinOff(uint32_t pause) { void SpinOff(uint32_t pause)
{
LED_A_OFF(); LED_A_OFF();
LED_B_OFF(); LED_B_OFF();
LED_C_OFF(); LED_C_OFF();
@ -163,10 +208,10 @@ void SpinOff(uint32_t pause) {
} }
// 0=A, 1=B, 2=C, 3=D // 0=A, 1=B, 2=C, 3=D
void SpinErr(uint8_t led, uint32_t speed, uint8_t times) { void SpinErr(uint8_t led, uint32_t speed, uint8_t times)
SpinOff(speed);
NTIME(times)
{ {
SpinOff(speed);
NTIME(times) {
switch (led) { switch (led) {
case 0: case 0:
LED_A_INV(); LED_A_INV();
@ -185,7 +230,8 @@ void SpinErr(uint8_t led, uint32_t speed, uint8_t times) {
} }
} }
void SpinDown(uint32_t speed) { void SpinDown(uint32_t speed)
{
SpinOff(speed); SpinOff(speed);
LED_D_ON(); LED_D_ON();
SpinDelay(speed); SpinDelay(speed);
@ -201,7 +247,8 @@ void SpinDown(uint32_t speed) {
LED_A_OFF(); LED_A_OFF();
} }
void SpinUp(uint32_t speed) { void SpinUp(uint32_t speed)
{
SpinOff(speed); SpinOff(speed);
LED_A_ON(); LED_A_ON();
SpinDelay(speed); SpinDelay(speed);
@ -222,7 +269,8 @@ void SpinUp(uint32_t speed) {
// not clicked, or held down (for ms || 1sec) // not clicked, or held down (for ms || 1sec)
// In general, don't use this function unless you expect a // In general, don't use this function unless you expect a
// double click, otherwise it will waste 500ms -- use BUTTON_HELD instead // double click, otherwise it will waste 500ms -- use BUTTON_HELD instead
int BUTTON_CLICKED(int ms) { int BUTTON_CLICKED(int ms)
{
// Up to 500ms in between clicks to mean a double click // Up to 500ms in between clicks to mean a double click
int ticks = (48000 * (ms ? ms : 1000)) >> 10; int ticks = (48000 * (ms ? ms : 1000)) >> 10;
@ -240,16 +288,13 @@ int BUTTON_CLICKED(int ms) {
uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
int letoff = 0; int letoff = 0;
for(;;) for (;;) {
{
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
// We haven't let off the button yet // We haven't let off the button yet
if (!letoff) if (!letoff) {
{
// We just let it off! // We just let it off!
if (!BUTTON_PRESS()) if (!BUTTON_PRESS()) {
{
letoff = 1; letoff = 1;
// reset our timer for 500ms // reset our timer for 500ms
@ -271,8 +316,7 @@ int BUTTON_CLICKED(int ms) {
return BUTTON_DOUBLE_CLICK; return BUTTON_DOUBLE_CLICK;
// Have we ran out of time to double click? // Have we ran out of time to double click?
else else if (now == (uint16_t)(start + ticks))
if (now == (uint16_t)(start + ticks))
// At least we did a single click // At least we did a single click
return BUTTON_SINGLE_CLICK; return BUTTON_SINGLE_CLICK;
@ -284,7 +328,8 @@ int BUTTON_CLICKED(int ms) {
} }
// Determine if a button is held down // Determine if a button is held down
int BUTTON_HELD(int ms) { int BUTTON_HELD(int ms)
{
// If button is held for one second // If button is held for one second
int ticks = (48000 * (ms ? ms : 1000)) >> 10; int ticks = (48000 * (ms ? ms : 1000)) >> 10;
@ -301,8 +346,7 @@ int BUTTON_HELD(int ms) {
uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; uint16_t start = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
for(;;) for (;;) {
{
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR; uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
// As soon as our button let go, we didn't hold long enough // As soon as our button let go, we didn't hold long enough
@ -310,8 +354,7 @@ int BUTTON_HELD(int ms) {
return BUTTON_SINGLE_CLICK; return BUTTON_SINGLE_CLICK;
// Have we waited the full second? // Have we waited the full second?
else else if (now == (uint16_t)(start + ticks))
if (now == (uint16_t)(start + ticks))
return BUTTON_HOLD; return BUTTON_HOLD;
WDT_HIT(); WDT_HIT();
@ -326,7 +369,8 @@ int BUTTON_HELD(int ms) {
* verifies the magic properties, then stores a formatted string, prefixed by * verifies the magic properties, then stores a formatted string, prefixed by
* prefix in dst. * prefix in dst.
*/ */
void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information) { void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information)
{
struct version_information *v = (struct version_information *)version_information; struct version_information *v = (struct version_information *)version_information;
dst[0] = 0; dst[0] = 0;
strncat(dst, prefix, len - 1); strncat(dst, prefix, len - 1);

View file

@ -37,13 +37,15 @@
//#define UART_WRITE(P, BUF, SIZ) (P)->uart_write(BUF, SIZ, (P)->extobj) //#define UART_WRITE(P, BUF, SIZ) (P)->uart_write(BUF, SIZ, (P)->extobj)
#define UART_WRITE(BUF) DbprintfEx(FLAG_RAWPRINT, "%s", BUF) #define UART_WRITE(BUF) DbprintfEx(FLAG_RAWPRINT, "%s", BUF)
int vtsend_init(vtsend_t *p, VTSEND_SERIAL_WRITE uart_write, void *extobj) { int vtsend_init(vtsend_t *p, VTSEND_SERIAL_WRITE uart_write, void *extobj)
{
p->uart_write = uart_write; p->uart_write = uart_write;
p->extobj = extobj; p->extobj = extobj;
return 0; return 0;
} }
int vtsend_cursor_position(vtsend_t *p, const int column, const int line) { int vtsend_cursor_position(vtsend_t *p, const int column, const int line)
{
char buf[1 + 8]; char buf[1 + 8];
buf[0] = ESC; buf[0] = ESC;
buf[1] = '['; buf[1] = '[';
@ -58,7 +60,8 @@ int vtsend_cursor_position(vtsend_t *p, const int column, const int line) {
return 0; return 0;
} }
int vtsend_cursor_up(vtsend_t *p, const int n) { int vtsend_cursor_up(vtsend_t *p, const int n)
{
char buf[1 + 5]; char buf[1 + 5];
buf[0] = ESC; buf[0] = ESC;
buf[1] = '['; buf[1] = '[';
@ -71,7 +74,8 @@ int vtsend_cursor_up(vtsend_t *p, const int n) {
return 0; return 0;
} }
int vtsend_cursor_down(vtsend_t *p, const int n) { int vtsend_cursor_down(vtsend_t *p, const int n)
{
char buf[1 + 5]; char buf[1 + 5];
buf[0] = ESC; buf[0] = ESC;
buf[1] = '['; buf[1] = '[';
@ -84,7 +88,8 @@ int vtsend_cursor_down(vtsend_t *p, const int n) {
return 0; return 0;
} }
int vtsend_cursor_forward(vtsend_t *p, const int n) { int vtsend_cursor_forward(vtsend_t *p, const int n)
{
char buf[1 + 5]; char buf[1 + 5];
buf[0] = ESC; buf[0] = ESC;
buf[1] = '['; buf[1] = '[';
@ -97,7 +102,8 @@ int vtsend_cursor_forward(vtsend_t *p, const int n) {
return 0; return 0;
} }
int vtsend_cursor_backward(vtsend_t *p, const int n) { int vtsend_cursor_backward(vtsend_t *p, const int n)
{
char buf[1 + 5]; char buf[1 + 5];
buf[0] = ESC; buf[0] = ESC;
buf[1] = '['; buf[1] = '[';
@ -110,7 +116,8 @@ int vtsend_cursor_backward(vtsend_t *p, const int n) {
return 0; return 0;
} }
int vtsend_cursor_position_save(vtsend_t *p) { int vtsend_cursor_position_save(vtsend_t *p)
{
char buf[1 + 3]; char buf[1 + 3];
buf[0] = ESC; buf[0] = ESC;
buf[1] = '['; buf[1] = '[';
@ -121,7 +128,8 @@ int vtsend_cursor_position_save(vtsend_t *p) {
return 0; return 0;
} }
int vtsend_cursor_position_restore(vtsend_t *p) { int vtsend_cursor_position_restore(vtsend_t *p)
{
char buf[1 + 3]; char buf[1 + 3];
buf[0] = ESC; buf[0] = ESC;
buf[1] = '['; buf[1] = '[';
@ -132,7 +140,8 @@ int vtsend_cursor_position_restore(vtsend_t *p) {
return 0; return 0;
} }
int vtsend_erase_display(vtsend_t *p) { int vtsend_erase_display(vtsend_t *p)
{
char buf[1 + 4]; char buf[1 + 4];
buf[0] = ESC; buf[0] = ESC;
buf[1] = '['; buf[1] = '[';
@ -144,7 +153,8 @@ int vtsend_erase_display(vtsend_t *p) {
return 0; return 0;
} }
int vtsend_erase_line(vtsend_t *p) { int vtsend_erase_line(vtsend_t *p)
{
char buf[1 + 4]; char buf[1 + 4];
buf[0] = ESC; buf[0] = ESC;
buf[1] = '['; buf[1] = '[';
@ -156,7 +166,8 @@ int vtsend_erase_line(vtsend_t *p) {
return 0; return 0;
} }
int vtsend_set_color_foreground(vtsend_t *p, const int color) { int vtsend_set_color_foreground(vtsend_t *p, const int color)
{
char buf[1 + 5]; char buf[1 + 5];
buf[0] = ESC; buf[0] = ESC;
buf[1] = '['; buf[1] = '[';
@ -169,7 +180,8 @@ int vtsend_set_color_foreground(vtsend_t *p, const int color) {
return 0; return 0;
} }
int vtsend_set_color_background(vtsend_t *p, const int color) { int vtsend_set_color_background(vtsend_t *p, const int color)
{
char buf[1 + 5]; char buf[1 + 5];
buf[0] = ESC; buf[0] = ESC;
buf[1] = '['; buf[1] = '[';
@ -182,7 +194,8 @@ int vtsend_set_color_background(vtsend_t *p, const int color) {
return 0; return 0;
} }
int vtsend_set_attribute(vtsend_t *p, const int attr) { int vtsend_set_attribute(vtsend_t *p, const int attr)
{
char buf[1 + 5]; char buf[1 + 5];
buf[0] = ESC; buf[0] = ESC;
buf[1] = '['; buf[1] = '[';
@ -195,7 +208,8 @@ int vtsend_set_attribute(vtsend_t *p, const int attr) {
return 0; return 0;
} }
int vtsend_set_scroll_region(vtsend_t *p, const int top, const int bottom) { int vtsend_set_scroll_region(vtsend_t *p, const int top, const int bottom)
{
char buf[1 + 8]; char buf[1 + 8];
buf[0] = ESC; buf[0] = ESC;
buf[1] = '['; buf[1] = '[';
@ -211,7 +225,8 @@ int vtsend_set_scroll_region(vtsend_t *p, const int top, const int bottom) {
return 0; return 0;
} }
int vtsend_set_cursor(vtsend_t *p, const int visible) { int vtsend_set_cursor(vtsend_t *p, const int visible)
{
if (visible) { if (visible) {
char buf[1 + 6]; char buf[1 + 6];
buf[0] = ESC; buf[0] = ESC;
@ -238,7 +253,8 @@ int vtsend_set_cursor(vtsend_t *p, const int visible) {
return 0; return 0;
} }
int vtsend_reset(vtsend_t *p) { int vtsend_reset(vtsend_t *p)
{
char buf[1 + 2]; char buf[1 + 2];
buf[0] = ESC; buf[0] = ESC;
buf[1] = 'c'; buf[1] = 'c';
@ -248,7 +264,8 @@ int vtsend_reset(vtsend_t *p) {
return 0; return 0;
} }
int vtsend_draw_box(vtsend_t *p, const int x1, const int y1, const int x2, const int y2) { int vtsend_draw_box(vtsend_t *p, const int x1, const int y1, const int x2, const int y2)
{
int i; int i;
vtsend_cursor_position(p, x1, y1); vtsend_cursor_position(p, x1, y1);
@ -268,7 +285,8 @@ int vtsend_draw_box(vtsend_t *p, const int x1, const int y1, const int x2, const
return 0; return 0;
} }
int vtsend_fill_box(vtsend_t *p, const int x1, const int y1, const int x2, const int y2) { int vtsend_fill_box(vtsend_t *p, const int x1, const int y1, const int x2, const int y2)
{
int i, j; int i, j;
for (i = y1; i <= y2; i++) { for (i = y1; i <= y2; i++) {
vtsend_cursor_position(p, x1, i); vtsend_cursor_position(p, x1, i);

View file

@ -15,7 +15,8 @@ unsigned int start_addr, end_addr, bootrom_unlocked;
extern char _bootrom_start, _bootrom_end, _flash_start, _flash_end; extern char _bootrom_start, _bootrom_end, _flash_start, _flash_end;
extern uint32_t _osimage_entry; extern uint32_t _osimage_entry;
void DbpString(char *str) { void DbpString(char *str)
{
byte_t len = 0; byte_t len = 0;
while (str[len] != 0x00) while (str[len] != 0x00)
len++; len++;
@ -23,7 +24,8 @@ void DbpString(char *str) {
cmd_send(CMD_DEBUG_PRINT_STRING, len, 0, 0, (byte_t *)str, len); cmd_send(CMD_DEBUG_PRINT_STRING, len, 0, 0, (byte_t *)str, len);
} }
static void ConfigClocks(void) { static void ConfigClocks(void)
{
// we are using a 16 MHz crystal as the basis for everything // we are using a 16 MHz crystal as the basis for everything
// slow clock runs at 32Khz typical regardless of crystal // slow clock runs at 32Khz typical regardless of crystal
@ -80,11 +82,13 @@ static void ConfigClocks(void) {
while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)) {}; while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)) {};
} }
static void Fatal(void) { static void Fatal(void)
{
for (;;) {}; for (;;) {};
} }
void UsbPacketReceived(uint8_t *packet, int len) { void UsbPacketReceived(uint8_t *packet, int len)
{
int i, dont_ack = 0; int i, dont_ack = 0;
UsbCommand *c = (UsbCommand *)packet; UsbCommand *c = (UsbCommand *)packet;
volatile uint32_t *p; volatile uint32_t *p;
@ -102,7 +106,8 @@ void UsbPacketReceived(uint8_t *packet, int len) {
arg0 |= DEVICE_INFO_FLAG_OSIMAGE_PRESENT; arg0 |= DEVICE_INFO_FLAG_OSIMAGE_PRESENT;
cmd_send(CMD_DEVICE_INFO, arg0, 1, 2, 0, 0); cmd_send(CMD_DEVICE_INFO, arg0, 1, 2, 0, 0);
} break; }
break;
case CMD_SETUP_WRITE: { case CMD_SETUP_WRITE: {
/* The temporary write buffer of the embedded flash controller is mapped to the /* The temporary write buffer of the embedded flash controller is mapped to the
@ -111,7 +116,8 @@ void UsbPacketReceived(uint8_t *packet, int len) {
p = (volatile uint32_t *)&_flash_start; p = (volatile uint32_t *)&_flash_start;
for (i = 0; i < 12; i++) for (i = 0; i < 12; i++)
p[i + arg0] = c->d.asDwords[i]; p[i + arg0] = c->d.asDwords[i];
} break; }
break;
case CMD_FINISH_WRITE: { case CMD_FINISH_WRITE: {
uint32_t *flash_mem = (uint32_t *)(&_flash_start); uint32_t *flash_mem = (uint32_t *)(&_flash_start);
@ -143,12 +149,14 @@ void UsbPacketReceived(uint8_t *packet, int len) {
cmd_send(CMD_NACK, sr, 0, 0, 0, 0); cmd_send(CMD_NACK, sr, 0, 0, 0, 0);
} }
} }
} break; }
break;
case CMD_HARDWARE_RESET: { case CMD_HARDWARE_RESET: {
usb_disable(); usb_disable();
AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST; AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
} break; }
break;
case CMD_START_FLASH: { case CMD_START_FLASH: {
if (c->arg[2] == START_FLASH_MAGIC) if (c->arg[2] == START_FLASH_MAGIC)
@ -176,18 +184,21 @@ void UsbPacketReceived(uint8_t *packet, int len) {
dont_ack = 1; dont_ack = 1;
cmd_send(CMD_NACK, 0, 0, 0, 0, 0); cmd_send(CMD_NACK, 0, 0, 0, 0, 0);
} }
} break; }
break;
default: { default: {
Fatal(); Fatal();
} break; }
break;
} }
if (!dont_ack) if (!dont_ack)
cmd_send(CMD_ACK, arg0, 0, 0, 0, 0); cmd_send(CMD_ACK, arg0, 0, 0, 0, 0);
} }
static void flash_mode(int externally_entered) { static void flash_mode(int externally_entered)
{
start_addr = 0; start_addr = 0;
end_addr = 0; end_addr = 0;
bootrom_unlocked = 0; bootrom_unlocked = 0;
@ -221,7 +232,8 @@ static void flash_mode(int externally_entered) {
} }
} }
void BootROM(void) { void BootROM(void)
{
//------------ //------------
// First set up all the I/O pins; GPIOs configured directly, other ones // First set up all the I/O pins; GPIOs configured directly, other ones
// just need to be assigned to the appropriate peripheral. // just need to be assigned to the appropriate peripheral.

View file

@ -12,7 +12,8 @@
#define HMAC_POS_DATA 0x008 #define HMAC_POS_DATA 0x008
#define HMAC_POS_TAG 0x1B4 #define HMAC_POS_TAG 0x1B4
void nfc3d_amiibo_calc_seed(const uint8_t * dump, uint8_t * key) { void nfc3d_amiibo_calc_seed(const uint8_t *dump, uint8_t *key)
{
memcpy(key + 0x00, dump + 0x029, 0x02); memcpy(key + 0x00, dump + 0x029, 0x02);
memset(key + 0x02, 0x00, 0x0E); memset(key + 0x02, 0x00, 0x0E);
memcpy(key + 0x10, dump + 0x1D4, 0x08); memcpy(key + 0x10, dump + 0x1D4, 0x08);
@ -20,14 +21,16 @@ void nfc3d_amiibo_calc_seed(const uint8_t * dump, uint8_t * key) {
memcpy(key + 0x20, dump + 0x1E8, 0x20); memcpy(key + 0x20, dump + 0x1E8, 0x20);
} }
void nfc3d_amiibo_keygen(const nfc3d_keygen_masterkeys * masterKeys, const uint8_t * dump, nfc3d_keygen_derivedkeys * derivedKeys) { void nfc3d_amiibo_keygen(const nfc3d_keygen_masterkeys *masterKeys, const uint8_t *dump, nfc3d_keygen_derivedkeys *derivedKeys)
{
uint8_t seed[NFC3D_KEYGEN_SEED_SIZE]; uint8_t seed[NFC3D_KEYGEN_SEED_SIZE];
nfc3d_amiibo_calc_seed(dump, seed); nfc3d_amiibo_calc_seed(dump, seed);
nfc3d_keygen(masterKeys, seed, derivedKeys); nfc3d_keygen(masterKeys, seed, derivedKeys);
} }
void nfc3d_amiibo_cipher(const nfc3d_keygen_derivedkeys * keys, const uint8_t * in, uint8_t * out) { void nfc3d_amiibo_cipher(const nfc3d_keygen_derivedkeys *keys, const uint8_t *in, uint8_t *out)
{
mbedtls_aes_context aes; mbedtls_aes_context aes;
size_t nc_off = 0; size_t nc_off = 0;
unsigned char nonce_counter[16]; unsigned char nonce_counter[16];
@ -46,7 +49,8 @@ void nfc3d_amiibo_cipher(const nfc3d_keygen_derivedkeys * keys, const uint8_t *
memcpy(out + 0x1D4, in + 0x1D4, 0x034); memcpy(out + 0x1D4, in + 0x1D4, 0x034);
} }
void nfc3d_amiibo_tag_to_internal(const uint8_t * tag, uint8_t * intl) { void nfc3d_amiibo_tag_to_internal(const uint8_t *tag, uint8_t *intl)
{
memcpy(intl + 0x000, tag + 0x008, 0x008); memcpy(intl + 0x000, tag + 0x008, 0x008);
memcpy(intl + 0x008, tag + 0x080, 0x020); memcpy(intl + 0x008, tag + 0x080, 0x020);
memcpy(intl + 0x028, tag + 0x010, 0x024); memcpy(intl + 0x028, tag + 0x010, 0x024);
@ -56,7 +60,8 @@ void nfc3d_amiibo_tag_to_internal(const uint8_t * tag, uint8_t * intl) {
memcpy(intl + 0x1DC, tag + 0x054, 0x02C); memcpy(intl + 0x1DC, tag + 0x054, 0x02C);
} }
void nfc3d_amiibo_internal_to_tag(const uint8_t * intl, uint8_t * tag) { void nfc3d_amiibo_internal_to_tag(const uint8_t *intl, uint8_t *tag)
{
memcpy(tag + 0x008, intl + 0x000, 0x008); memcpy(tag + 0x008, intl + 0x000, 0x008);
memcpy(tag + 0x080, intl + 0x008, 0x020); memcpy(tag + 0x080, intl + 0x008, 0x020);
memcpy(tag + 0x010, intl + 0x028, 0x024); memcpy(tag + 0x010, intl + 0x028, 0x024);
@ -66,7 +71,8 @@ void nfc3d_amiibo_internal_to_tag(const uint8_t * intl, uint8_t * tag) {
memcpy(tag + 0x054, intl + 0x1DC, 0x02C); memcpy(tag + 0x054, intl + 0x1DC, 0x02C);
} }
bool nfc3d_amiibo_unpack(const nfc3d_amiibo_keys * amiiboKeys, const uint8_t * tag, uint8_t * plain) { bool nfc3d_amiibo_unpack(const nfc3d_amiibo_keys *amiiboKeys, const uint8_t *tag, uint8_t *plain)
{
uint8_t internal[NFC3D_AMIIBO_SIZE]; uint8_t internal[NFC3D_AMIIBO_SIZE];
nfc3d_keygen_derivedkeys dataKeys; nfc3d_keygen_derivedkeys dataKeys;
nfc3d_keygen_derivedkeys tagKeys; nfc3d_keygen_derivedkeys tagKeys;
@ -94,7 +100,8 @@ bool nfc3d_amiibo_unpack(const nfc3d_amiibo_keys * amiiboKeys, const uint8_t * t
memcmp(plain + HMAC_POS_TAG, internal + HMAC_POS_TAG, 32) == 0; memcmp(plain + HMAC_POS_TAG, internal + HMAC_POS_TAG, 32) == 0;
} }
void nfc3d_amiibo_pack(const nfc3d_amiibo_keys * amiiboKeys, const uint8_t * plain, uint8_t * tag) { void nfc3d_amiibo_pack(const nfc3d_amiibo_keys *amiiboKeys, const uint8_t *plain, uint8_t *tag)
{
uint8_t cipher[NFC3D_AMIIBO_SIZE]; uint8_t cipher[NFC3D_AMIIBO_SIZE];
nfc3d_keygen_derivedkeys tagKeys; nfc3d_keygen_derivedkeys tagKeys;
nfc3d_keygen_derivedkeys dataKeys; nfc3d_keygen_derivedkeys dataKeys;
@ -130,7 +137,8 @@ void nfc3d_amiibo_pack(const nfc3d_amiibo_keys * amiiboKeys, const uint8_t * pla
nfc3d_amiibo_internal_to_tag(cipher, tag); nfc3d_amiibo_internal_to_tag(cipher, tag);
} }
bool nfc3d_amiibo_load_keys(nfc3d_amiibo_keys * amiiboKeys, const char * path) { bool nfc3d_amiibo_load_keys(nfc3d_amiibo_keys *amiiboKeys, const char *path)
{
FILE *f = fopen(path, "rb"); FILE *f = fopen(path, "rb");
if (!f) { if (!f) {
return false; return false;
@ -152,7 +160,8 @@ bool nfc3d_amiibo_load_keys(nfc3d_amiibo_keys * amiiboKeys, const char * path) {
return true; return true;
} }
void nfc3d_amiibo_copy_app_data(const uint8_t * src, uint8_t * dst) { void nfc3d_amiibo_copy_app_data(const uint8_t *src, uint8_t *dst)
{
//uint16_t *ami_nb_wr = (uint16_t*)(dst + 0x29); //uint16_t *ami_nb_wr = (uint16_t*)(dst + 0x29);

View file

@ -14,7 +14,8 @@
static char *self; static char *self;
void amiitool_usage() { void amiitool_usage()
{
fprintf(stderr, fprintf(stderr,
"amiitool build %i (commit %s-%08x)\n" "amiitool build %i (commit %s-%08x)\n"
"by Marcos Del Sol Vives <marcos@dracon.es>\n" "by Marcos Del Sol Vives <marcos@dracon.es>\n"
@ -32,7 +33,8 @@ void amiitool_usage() {
); );
} }
static bool LoadAmiikey(nfc3d_amiibo_keys keys, char* keyfile) { static bool LoadAmiikey(nfc3d_amiibo_keys keys, char *keyfile)
{
if (!nfc3d_amiibo_load_keys(&keys, keyfile)) { if (!nfc3d_amiibo_load_keys(&keys, keyfile)) {
PrintAndLogEx(ERR, "Could not load keys from '%s'", keyfile); PrintAndLogEx(ERR, "Could not load keys from '%s'", keyfile);
@ -41,7 +43,8 @@ static bool LoadAmiikey(nfc3d_amiibo_keys keys, char* keyfile) {
return true; return true;
} }
int main(int argc, char ** argv) { int main(int argc, char **argv)
{
self = argv[0]; self = argv[0];
char *infile = NULL; char *infile = NULL;

View file

@ -10,7 +10,8 @@
#include <string.h> #include <string.h>
#include <mbedtls/md.h> #include <mbedtls/md.h>
void nfc3d_drbg_init(nfc3d_drbg_ctx * ctx, const uint8_t * hmacKey, size_t hmacKeySize, const uint8_t * seed, size_t seedSize) { void nfc3d_drbg_init(nfc3d_drbg_ctx *ctx, const uint8_t *hmacKey, size_t hmacKeySize, const uint8_t *seed, size_t seedSize)
{
assert(ctx != NULL); assert(ctx != NULL);
assert(hmacKey != NULL); assert(hmacKey != NULL);
assert(seed != NULL); assert(seed != NULL);
@ -30,7 +31,8 @@ void nfc3d_drbg_init(nfc3d_drbg_ctx * ctx, const uint8_t * hmacKey, size_t hmacK
mbedtls_md_hmac_starts(&ctx->hmacCtx, hmacKey, hmacKeySize); mbedtls_md_hmac_starts(&ctx->hmacCtx, hmacKey, hmacKeySize);
} }
void nfc3d_drbg_step(nfc3d_drbg_ctx * ctx, uint8_t * output) { void nfc3d_drbg_step(nfc3d_drbg_ctx *ctx, uint8_t *output)
{
assert(ctx != NULL); assert(ctx != NULL);
assert(output != NULL); assert(output != NULL);
@ -51,12 +53,14 @@ void nfc3d_drbg_step(nfc3d_drbg_ctx * ctx, uint8_t * output) {
mbedtls_md_hmac_finish(&ctx->hmacCtx, output); mbedtls_md_hmac_finish(&ctx->hmacCtx, output);
} }
void nfc3d_drbg_cleanup(nfc3d_drbg_ctx * ctx) { void nfc3d_drbg_cleanup(nfc3d_drbg_ctx *ctx)
{
assert(ctx != NULL); assert(ctx != NULL);
mbedtls_md_free(&ctx->hmacCtx); mbedtls_md_free(&ctx->hmacCtx);
} }
void nfc3d_drbg_generate_bytes(const uint8_t * hmacKey, size_t hmacKeySize, const uint8_t * seed, size_t seedSize, uint8_t * output, size_t outputSize) { void nfc3d_drbg_generate_bytes(const uint8_t *hmacKey, size_t hmacKeySize, const uint8_t *seed, size_t seedSize, uint8_t *output, size_t outputSize)
{
uint8_t temp[NFC3D_DRBG_OUTPUT_SIZE]; uint8_t temp[NFC3D_DRBG_OUTPUT_SIZE];
nfc3d_drbg_ctx rngCtx; nfc3d_drbg_ctx rngCtx;

View file

@ -10,7 +10,8 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
void nfc3d_keygen_prepare_seed(const nfc3d_keygen_masterkeys * baseKeys, const uint8_t * baseSeed, uint8_t * output, size_t * outputSize) { void nfc3d_keygen_prepare_seed(const nfc3d_keygen_masterkeys *baseKeys, const uint8_t *baseSeed, uint8_t *output, size_t *outputSize)
{
assert(baseKeys != NULL); assert(baseKeys != NULL);
assert(baseSeed != NULL); assert(baseSeed != NULL);
assert(output != NULL); assert(output != NULL);
@ -44,7 +45,8 @@ void nfc3d_keygen_prepare_seed(const nfc3d_keygen_masterkeys * baseKeys, const u
*outputSize = output - start; *outputSize = output - start;
} }
void nfc3d_keygen(const nfc3d_keygen_masterkeys * baseKeys, const uint8_t * baseSeed, nfc3d_keygen_derivedkeys * derivedKeys) { void nfc3d_keygen(const nfc3d_keygen_masterkeys *baseKeys, const uint8_t *baseSeed, nfc3d_keygen_derivedkeys *derivedKeys)
{
uint8_t preparedSeed[NFC3D_DRBG_MAX_SEED_SIZE]; uint8_t preparedSeed[NFC3D_DRBG_MAX_SEED_SIZE];
size_t preparedSeedSize; size_t preparedSeedSize;

View file

@ -19,8 +19,7 @@
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
if (argc != 3 && argc != 4) if (argc != 3 && argc != 4) {
{
printf("\n\tusage: cli <command 1> <command 2> [logfile (default cli.log)]\n"); printf("\n\tusage: cli <command 1> <command 2> [logfile (default cli.log)]\n");
printf("\n"); printf("\n");
printf("\texample: cli hi14asnoop hi14alist h14a.log\n"); printf("\texample: cli hi14asnoop hi14alist h14a.log\n");

File diff suppressed because it is too large Load diff

View file

@ -41,8 +41,7 @@ extern "C" {
#define ARG_REX_ICASE 1 #define ARG_REX_ICASE 1
/* bit masks for arg_hdr.flag */ /* bit masks for arg_hdr.flag */
enum enum {
{
ARG_TERMINATOR = 0x1, ARG_TERMINATOR = 0x1,
ARG_HASVALUE = 0x2, ARG_HASVALUE = 0x2,
ARG_HASOPTVALUE = 0x4 ARG_HASOPTVALUE = 0x4
@ -71,8 +70,7 @@ typedef void (arg_errorfn)(void *parent, FILE *fp, int error, const char *argval
* if desired, but the original intention is for them to be set by the * if desired, but the original intention is for them to be set by the
* constructor and left unaltered. * constructor and left unaltered.
*/ */
struct arg_hdr struct arg_hdr {
{
char flag; /* Modifier flags: ARG_TERMINATOR, ARG_HASVALUE. */ char flag; /* Modifier flags: ARG_TERMINATOR, ARG_HASVALUE. */
const char *shortopts; /* String defining the short options */ const char *shortopts; /* String defining the short options */
const char *longopts; /* String defiing the long options */ const char *longopts; /* String defiing the long options */
@ -88,47 +86,40 @@ struct arg_hdr
void *priv; /* Pointer to private header data for use by arg_xxx functions */ void *priv; /* Pointer to private header data for use by arg_xxx functions */
}; };
struct arg_rem struct arg_rem {
{
struct arg_hdr hdr; /* The mandatory argtable header struct */ struct arg_hdr hdr; /* The mandatory argtable header struct */
}; };
struct arg_lit struct arg_lit {
{
struct arg_hdr hdr; /* The mandatory argtable header struct */ struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of matching command line args */ int count; /* Number of matching command line args */
}; };
struct arg_int struct arg_int {
{
struct arg_hdr hdr; /* The mandatory argtable header struct */ struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of matching command line args */ int count; /* Number of matching command line args */
int *ival; /* Array of parsed argument values */ int *ival; /* Array of parsed argument values */
}; };
struct arg_dbl struct arg_dbl {
{
struct arg_hdr hdr; /* The mandatory argtable header struct */ struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of matching command line args */ int count; /* Number of matching command line args */
double *dval; /* Array of parsed argument values */ double *dval; /* Array of parsed argument values */
}; };
struct arg_str struct arg_str {
{
struct arg_hdr hdr; /* The mandatory argtable header struct */ struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of matching command line args */ int count; /* Number of matching command line args */
const char **sval; /* Array of parsed argument values */ const char **sval; /* Array of parsed argument values */
}; };
struct arg_rex struct arg_rex {
{
struct arg_hdr hdr; /* The mandatory argtable header struct */ struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of matching command line args */ int count; /* Number of matching command line args */
const char **sval; /* Array of parsed argument values */ const char **sval; /* Array of parsed argument values */
}; };
struct arg_file struct arg_file {
{
struct arg_hdr hdr; /* The mandatory argtable header struct */ struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of matching command line args*/ int count; /* Number of matching command line args*/
const char **filename; /* Array of parsed filenames (eg: /home/foo.bar) */ const char **filename; /* Array of parsed filenames (eg: /home/foo.bar) */
@ -136,8 +127,7 @@ struct arg_file
const char **extension; /* Array of parsed extensions (eg: .bar) */ const char **extension; /* Array of parsed extensions (eg: .bar) */
}; };
struct arg_date struct arg_date {
{
struct arg_hdr hdr; /* The mandatory argtable header struct */ struct arg_hdr hdr; /* The mandatory argtable header struct */
const char *format; /* strptime format string used to parse the date */ const char *format; /* strptime format string used to parse the date */
int count; /* Number of matching command line args */ int count; /* Number of matching command line args */
@ -145,8 +135,7 @@ struct arg_date
}; };
enum {ARG_ELIMIT = 1, ARG_EMALLOC, ARG_ENOMATCH, ARG_ELONGOPT, ARG_EMISSARG}; enum {ARG_ELIMIT = 1, ARG_EMALLOC, ARG_ENOMATCH, ARG_ELONGOPT, ARG_EMISSARG};
struct arg_end struct arg_end {
{
struct arg_hdr hdr; /* The mandatory argtable header struct */ struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of errors encountered */ int count; /* Number of errors encountered */
int *error; /* Array of error codes */ int *error; /* Array of error codes */

View file

@ -19,7 +19,8 @@ char *programHint = NULL;
char *programHelp = NULL; char *programHelp = NULL;
char buf[500] = {0}; char buf[500] = {0};
int CLIParserInit(char *vprogramName, char *vprogramHint, char *vprogramHelp) { int CLIParserInit(char *vprogramName, char *vprogramHint, char *vprogramHelp)
{
argtable = NULL; argtable = NULL;
argtableLen = 0; argtableLen = 0;
programName = vprogramName; programName = vprogramName;
@ -30,7 +31,8 @@ int CLIParserInit(char *vprogramName, char *vprogramHint, char *vprogramHelp) {
return 0; return 0;
} }
int CLIParserParseArg(int argc, char **argv, void* vargtable[], size_t vargtableLen, bool allowEmptyExec) { int CLIParserParseArg(int argc, char **argv, void *vargtable[], size_t vargtableLen, bool allowEmptyExec)
{
int nerrors; int nerrors;
argtable = vargtable; argtable = vargtable;
@ -79,11 +81,13 @@ enum ParserState {
#define isSpace(c)(c == ' ' || c == '\t') #define isSpace(c)(c == ' ' || c == '\t')
int CLIParserParseString(const char* str, void* vargtable[], size_t vargtableLen, bool allowEmptyExec) { int CLIParserParseString(const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec)
{
return CLIParserParseStringEx(str, vargtable, vargtableLen, allowEmptyExec, false); return CLIParserParseStringEx(str, vargtable, vargtableLen, allowEmptyExec, false);
} }
int CLIParserParseStringEx(const char* str, void* vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData) { int CLIParserParseStringEx(const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec, bool clueData)
{
int argc = 0; int argc = 0;
char *argv[200] = {NULL}; char *argv[200] = {NULL};
@ -143,7 +147,8 @@ int CLIParserParseStringEx(const char* str, void* vargtable[], size_t vargtableL
return CLIParserParseArg(argc, argv, vargtable, vargtableLen, allowEmptyExec); return CLIParserParseArg(argc, argv, vargtable, vargtableLen, allowEmptyExec);
} }
void CLIParserFree() { void CLIParserFree()
{
arg_freetable(argtable, argtableLen); arg_freetable(argtable, argtableLen);
argtable = NULL; argtable = NULL;
@ -151,7 +156,8 @@ void CLIParserFree() {
} }
// convertors // convertors
int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen) { int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen)
{
*datalen = 0; *datalen = 0;
int ibuf = 0; int ibuf = 0;
@ -175,7 +181,8 @@ int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int
return 0; return 0;
} }
int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen) { int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen)
{
*datalen = 0; *datalen = 0;
if (!argstr->count) if (!argstr->count)
return 0; return 0;

View file

@ -11,7 +11,8 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_analyse_lcr(void) { int usage_analyse_lcr(void)
{
PrintAndLogEx(NORMAL, "Specifying the bytes of a UID with a known LRC will find the last byte value"); PrintAndLogEx(NORMAL, "Specifying the bytes of a UID with a known LRC will find the last byte value");
PrintAndLogEx(NORMAL, "needed to generate that LRC with a rolling XOR. All bytes should be specified in HEX."); PrintAndLogEx(NORMAL, "needed to generate that LRC with a rolling XOR. All bytes should be specified in HEX.");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
@ -25,7 +26,8 @@ int usage_analyse_lcr(void) {
PrintAndLogEx(NORMAL, "expected output: Target (BA) requires final LRC XOR byte value: 5A"); PrintAndLogEx(NORMAL, "expected output: Target (BA) requires final LRC XOR byte value: 5A");
return 0; return 0;
} }
int usage_analyse_checksum(void) { int usage_analyse_checksum(void)
{
PrintAndLogEx(NORMAL, "The bytes will be added with eachother and than limited with the applied mask"); PrintAndLogEx(NORMAL, "The bytes will be added with eachother and than limited with the applied mask");
PrintAndLogEx(NORMAL, "Finally compute ones' complement of the least significant bytes"); PrintAndLogEx(NORMAL, "Finally compute ones' complement of the least significant bytes");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
@ -41,7 +43,8 @@ int usage_analyse_checksum(void) {
PrintAndLogEx(NORMAL, "expected output: 0x61"); PrintAndLogEx(NORMAL, "expected output: 0x61");
return 0; return 0;
} }
int usage_analyse_crc(void){ int usage_analyse_crc(void)
{
PrintAndLogEx(NORMAL, "A stub method to test different crc implementations inside the PM3 sourcecode. Just because you figured out the poly, doesn't mean you get the desired output"); PrintAndLogEx(NORMAL, "A stub method to test different crc implementations inside the PM3 sourcecode. Just because you figured out the poly, doesn't mean you get the desired output");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: analyse crc [h] <bytes>"); PrintAndLogEx(NORMAL, "Usage: analyse crc [h] <bytes>");
@ -53,7 +56,8 @@ int usage_analyse_crc(void){
PrintAndLogEx(NORMAL, " analyse crc 137AF00A0A0D"); PrintAndLogEx(NORMAL, " analyse crc 137AF00A0A0D");
return 0; return 0;
} }
int usage_analyse_nuid(void){ int usage_analyse_nuid(void)
{
PrintAndLogEx(NORMAL, "Generate 4byte NUID from 7byte UID"); PrintAndLogEx(NORMAL, "Generate 4byte NUID from 7byte UID");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: analyse hid [h] <bytes>"); PrintAndLogEx(NORMAL, "Usage: analyse hid [h] <bytes>");
@ -65,7 +69,8 @@ int usage_analyse_nuid(void){
PrintAndLogEx(NORMAL, " analyse nuid 11223344556677"); PrintAndLogEx(NORMAL, " analyse nuid 11223344556677");
return 0; return 0;
} }
int usage_analyse_a(void) { int usage_analyse_a(void)
{
PrintAndLogEx(NORMAL, "Iceman's personal garbage test command"); PrintAndLogEx(NORMAL, "Iceman's personal garbage test command");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: analyse a [h] d <bytes>"); PrintAndLogEx(NORMAL, "Usage: analyse a [h] d <bytes>");
@ -78,7 +83,8 @@ int usage_analyse_a(void) {
return 0; return 0;
} }
static uint8_t calculateLRC( uint8_t* bytes, uint8_t len) { static uint8_t calculateLRC(uint8_t *bytes, uint8_t len)
{
uint8_t LRC = 0; uint8_t LRC = 0;
for (uint8_t i = 0; i < len; i++) for (uint8_t i = 0; i < len; i++)
LRC ^= bytes[i]; LRC ^= bytes[i];
@ -102,7 +108,8 @@ static uint16_t shiftadd ( uint8_t* bytes, uint8_t len){
return 0; return 0;
} }
*/ */
static uint16_t calcSumCrumbAdd( uint8_t* bytes, uint8_t len, uint32_t mask) { static uint16_t calcSumCrumbAdd(uint8_t *bytes, uint8_t len, uint32_t mask)
{
uint16_t sum = 0; uint16_t sum = 0;
for (uint8_t i = 0; i < len; i++) { for (uint8_t i = 0; i < len; i++) {
sum += CRUMB(bytes[i], 0); sum += CRUMB(bytes[i], 0);
@ -113,10 +120,12 @@ static uint16_t calcSumCrumbAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
sum &= mask; sum &= mask;
return sum; return sum;
} }
static uint16_t calcSumCrumbAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask) { static uint16_t calcSumCrumbAddOnes(uint8_t *bytes, uint8_t len, uint32_t mask)
{
return (~calcSumCrumbAdd(bytes, len, mask) & mask); return (~calcSumCrumbAdd(bytes, len, mask) & mask);
} }
static uint16_t calcSumNibbleAdd( uint8_t* bytes, uint8_t len, uint32_t mask) { static uint16_t calcSumNibbleAdd(uint8_t *bytes, uint8_t len, uint32_t mask)
{
uint16_t sum = 0; uint16_t sum = 0;
for (uint8_t i = 0; i < len; i++) { for (uint8_t i = 0; i < len; i++) {
sum += NIBBLE_LOW(bytes[i]); sum += NIBBLE_LOW(bytes[i]);
@ -125,10 +134,12 @@ static uint16_t calcSumNibbleAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
sum &= mask; sum &= mask;
return sum; return sum;
} }
static uint16_t calcSumNibbleAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask){ static uint16_t calcSumNibbleAddOnes(uint8_t *bytes, uint8_t len, uint32_t mask)
{
return (~calcSumNibbleAdd(bytes, len, mask) & mask); return (~calcSumNibbleAdd(bytes, len, mask) & mask);
} }
static uint16_t calcSumCrumbXor( uint8_t* bytes, uint8_t len, uint32_t mask) { static uint16_t calcSumCrumbXor(uint8_t *bytes, uint8_t len, uint32_t mask)
{
uint16_t sum = 0; uint16_t sum = 0;
for (uint8_t i = 0; i < len; i++) { for (uint8_t i = 0; i < len; i++) {
sum ^= CRUMB(bytes[i], 0); sum ^= CRUMB(bytes[i], 0);
@ -139,7 +150,8 @@ static uint16_t calcSumCrumbXor( uint8_t* bytes, uint8_t len, uint32_t mask) {
sum &= mask; sum &= mask;
return sum; return sum;
} }
static uint16_t calcSumNibbleXor( uint8_t* bytes, uint8_t len, uint32_t mask) { static uint16_t calcSumNibbleXor(uint8_t *bytes, uint8_t len, uint32_t mask)
{
uint16_t sum = 0; uint16_t sum = 0;
for (uint8_t i = 0; i < len; i++) { for (uint8_t i = 0; i < len; i++) {
sum ^= NIBBLE_LOW(bytes[i]); sum ^= NIBBLE_LOW(bytes[i]);
@ -148,7 +160,8 @@ static uint16_t calcSumNibbleXor( uint8_t* bytes, uint8_t len, uint32_t mask) {
sum &= mask; sum &= mask;
return sum; return sum;
} }
static uint16_t calcSumByteXor( uint8_t* bytes, uint8_t len, uint32_t mask) { static uint16_t calcSumByteXor(uint8_t *bytes, uint8_t len, uint32_t mask)
{
uint16_t sum = 0; uint16_t sum = 0;
for (uint8_t i = 0; i < len; i++) { for (uint8_t i = 0; i < len; i++) {
sum ^= bytes[i]; sum ^= bytes[i];
@ -156,7 +169,8 @@ static uint16_t calcSumByteXor( uint8_t* bytes, uint8_t len, uint32_t mask) {
sum &= mask; sum &= mask;
return sum; return sum;
} }
static uint16_t calcSumByteAdd( uint8_t* bytes, uint8_t len, uint32_t mask) { static uint16_t calcSumByteAdd(uint8_t *bytes, uint8_t len, uint32_t mask)
{
uint16_t sum = 0; uint16_t sum = 0;
for (uint8_t i = 0; i < len; i++) { for (uint8_t i = 0; i < len; i++) {
sum += bytes[i]; sum += bytes[i];
@ -165,11 +179,13 @@ static uint16_t calcSumByteAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
return sum; return sum;
} }
// Ones complement // Ones complement
static uint16_t calcSumByteAddOnes( uint8_t* bytes, uint8_t len, uint32_t mask) { static uint16_t calcSumByteAddOnes(uint8_t *bytes, uint8_t len, uint32_t mask)
{
return (~calcSumByteAdd(bytes, len, mask) & mask); return (~calcSumByteAdd(bytes, len, mask) & mask);
} }
static uint16_t calcSumByteSub( uint8_t* bytes, uint8_t len, uint32_t mask) { static uint16_t calcSumByteSub(uint8_t *bytes, uint8_t len, uint32_t mask)
{
uint8_t sum = 0; uint8_t sum = 0;
for (uint8_t i = 0; i < len; i++) { for (uint8_t i = 0; i < len; i++) {
sum -= bytes[i]; sum -= bytes[i];
@ -177,10 +193,12 @@ static uint16_t calcSumByteSub( uint8_t* bytes, uint8_t len, uint32_t mask) {
sum &= mask; sum &= mask;
return sum; return sum;
} }
static uint16_t calcSumByteSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask){ static uint16_t calcSumByteSubOnes(uint8_t *bytes, uint8_t len, uint32_t mask)
{
return (~calcSumByteSub(bytes, len, mask) & mask); return (~calcSumByteSub(bytes, len, mask) & mask);
} }
static uint16_t calcSumNibbleSub( uint8_t* bytes, uint8_t len, uint32_t mask) { static uint16_t calcSumNibbleSub(uint8_t *bytes, uint8_t len, uint32_t mask)
{
uint8_t sum = 0; uint8_t sum = 0;
for (uint8_t i = 0; i < len; i++) { for (uint8_t i = 0; i < len; i++) {
sum -= NIBBLE_LOW(bytes[i]); sum -= NIBBLE_LOW(bytes[i]);
@ -189,12 +207,14 @@ static uint16_t calcSumNibbleSub( uint8_t* bytes, uint8_t len, uint32_t mask) {
sum &= mask; sum &= mask;
return sum; return sum;
} }
static uint16_t calcSumNibbleSubOnes( uint8_t* bytes, uint8_t len, uint32_t mask) { static uint16_t calcSumNibbleSubOnes(uint8_t *bytes, uint8_t len, uint32_t mask)
{
return (~calcSumNibbleSub(bytes, len, mask) & mask); return (~calcSumNibbleSub(bytes, len, mask) & mask);
} }
// BSD shift checksum 8bit version // BSD shift checksum 8bit version
static uint16_t calcBSDchecksum8( uint8_t* bytes, uint8_t len, uint32_t mask){ static uint16_t calcBSDchecksum8(uint8_t *bytes, uint8_t len, uint32_t mask)
{
uint16_t sum = 0; uint16_t sum = 0;
for (uint8_t i = 0; i < len; i++) { for (uint8_t i = 0; i < len; i++) {
sum = ((sum & 0xFF) >> 1) | ((sum & 0x1) << 7); // rotate accumulator sum = ((sum & 0xFF) >> 1) | ((sum & 0x1) << 7); // rotate accumulator
@ -205,7 +225,8 @@ static uint16_t calcBSDchecksum8( uint8_t* bytes, uint8_t len, uint32_t mask){
return sum; return sum;
} }
// BSD shift checksum 4bit version // BSD shift checksum 4bit version
static uint16_t calcBSDchecksum4( uint8_t* bytes, uint8_t len, uint32_t mask){ static uint16_t calcBSDchecksum4(uint8_t *bytes, uint8_t len, uint32_t mask)
{
uint16_t sum = 0; uint16_t sum = 0;
for (uint8_t i = 0; i < len; i++) { for (uint8_t i = 0; i < len; i++) {
sum = ((sum & 0xF) >> 1) | ((sum & 0x1) << 3); // rotate accumulator sum = ((sum & 0xF) >> 1) | ((sum & 0x1) << 3); // rotate accumulator
@ -220,7 +241,8 @@ static uint16_t calcBSDchecksum4( uint8_t* bytes, uint8_t len, uint32_t mask){
} }
// measuring LFSR maximum length // measuring LFSR maximum length
int CmdAnalyseLfsr(const char *Cmd){ int CmdAnalyseLfsr(const char *Cmd)
{
uint16_t start_state = 0; /* Any nonzero start state will work. */ uint16_t start_state = 0; /* Any nonzero start state will work. */
uint16_t lfsr = start_state; uint16_t lfsr = start_state;
@ -242,7 +264,8 @@ int CmdAnalyseLfsr(const char *Cmd){
} }
return 0; return 0;
} }
int CmdAnalyseLCR(const char *Cmd) { int CmdAnalyseLCR(const char *Cmd)
{
uint8_t data[50]; uint8_t data[50];
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_analyse_lcr(); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_analyse_lcr();
@ -263,7 +286,8 @@ int CmdAnalyseLCR(const char *Cmd) {
PrintAndLogEx(NORMAL, "Target [%02X] requires final LRC XOR byte value: 0x%02X", data[len - 1], finalXor); PrintAndLogEx(NORMAL, "Target [%02X] requires final LRC XOR byte value: 0x%02X", data[len - 1], finalXor);
return 0; return 0;
} }
int CmdAnalyseCRC(const char *Cmd) { int CmdAnalyseCRC(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_analyse_crc(); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_analyse_crc();
@ -359,7 +383,8 @@ int CmdAnalyseCRC(const char *Cmd) {
free(data); free(data);
return 0; return 0;
} }
int CmdAnalyseCHKSUM(const char *Cmd){ int CmdAnalyseCHKSUM(const char *Cmd)
{
uint8_t data[50]; uint8_t data[50];
uint8_t cmdp = 0; uint8_t cmdp = 0;
@ -425,12 +450,14 @@ int CmdAnalyseCHKSUM(const char *Cmd){
return 0; return 0;
} }
int CmdAnalyseDates(const char *Cmd){ int CmdAnalyseDates(const char *Cmd)
{
// look for datestamps in a given array of bytes // look for datestamps in a given array of bytes
PrintAndLogEx(NORMAL, "To be implemented. Feel free to contribute!"); PrintAndLogEx(NORMAL, "To be implemented. Feel free to contribute!");
return 0; return 0;
} }
int CmdAnalyseTEASelfTest(const char *Cmd){ int CmdAnalyseTEASelfTest(const char *Cmd)
{
uint8_t v[8], v_le[8]; uint8_t v[8], v_le[8];
memset(v, 0x00, sizeof(v)); memset(v, 0x00, sizeof(v));
@ -465,7 +492,8 @@ int CmdAnalyseTEASelfTest(const char *Cmd){
return 0; return 0;
} }
char* pb(uint32_t b) { char *pb(uint32_t b)
{
static char buf1[33] = {0}; static char buf1[33] = {0};
static char buf2[33] = {0}; static char buf2[33] = {0};
static char *s; static char *s;
@ -485,7 +513,8 @@ char* pb(uint32_t b) {
return s; return s;
} }
int CmdAnalyseA(const char *Cmd){ int CmdAnalyseA(const char *Cmd)
{
int hexlen = 0; int hexlen = 0;
uint8_t cmdp = 0; uint8_t cmdp = 0;
@ -702,12 +731,20 @@ uint64_t d2[] = {0x6e442129, 0x8f699195, 0x0000004, 0, 0x00040f0f0305030e};
keycountB = nonce2key(d2[0], d2[1], d2[2], 0, d2[3], d2[4], &keylistB); keycountB = nonce2key(d2[0], d2[1], d2[2], 0, d2[3], d2[4], &keylistB);
switch (keycountA) { switch (keycountA) {
case 0: PrintAndLogEx(FAILED, "Key test A failed\n"); break; case 0:
case 1: PrintAndLogEx(SUCCESS, "KEY A | %012" PRIX64 " ", keylistA[0]); break; PrintAndLogEx(FAILED, "Key test A failed\n");
break;
case 1:
PrintAndLogEx(SUCCESS, "KEY A | %012" PRIX64 " ", keylistA[0]);
break;
} }
switch (keycountB) { switch (keycountB) {
case 0: PrintAndLogEx(FAILED, "Key test B failed\n"); break; case 0:
case 1: PrintAndLogEx(SUCCESS, "KEY B | %012" PRIX64 " ", keylistB[0]); break; PrintAndLogEx(FAILED, "Key test B failed\n");
break;
case 1:
PrintAndLogEx(SUCCESS, "KEY B | %012" PRIX64 " ", keylistB[0]);
break;
} }
free(keylistA); free(keylistA);
@ -843,7 +880,8 @@ uint64_t d2[] = {0x6e442129, 0x8f699195, 0x0000004, 0, 0x00040f0f0305030e};
return 0; return 0;
} }
void generate4bNUID(uint8_t *uid, uint8_t *nuid){ void generate4bNUID(uint8_t *uid, uint8_t *nuid)
{
uint16_t crc; uint16_t crc;
uint8_t b1, b2; uint8_t b1, b2;
@ -857,7 +895,8 @@ void generate4bNUID(uint8_t *uid, uint8_t *nuid){
nuid[3] = crc & 0xFF; nuid[3] = crc & 0xFF;
} }
int CmdAnalyseNuid(const char *Cmd){ int CmdAnalyseNuid(const char *Cmd)
{
uint8_t nuid[4] = {0}; uint8_t nuid[4] = {0};
uint8_t uid[7] = {0}; uint8_t uid[7] = {0};
int len = 0; int len = 0;
@ -903,13 +942,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdAnalyse(const char *Cmd) { int CmdAnalyse(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -11,7 +11,8 @@
#define MAX_ARGS 20 #define MAX_ARGS 20
int split(char *str, char *arr[MAX_ARGS]){ int split(char *str, char *arr[MAX_ARGS])
{
int beginIndex = 0; int beginIndex = 0;
int endIndex; int endIndex;
int maxWords = MAX_ARGS; int maxWords = MAX_ARGS;
@ -39,7 +40,8 @@ int split(char *str, char *arr[MAX_ARGS]){
return wordCnt; return wordCnt;
} }
int CmdCrc(const char *Cmd) { int CmdCrc(const char *Cmd)
{
char name[] = {"reveng "}; char name[] = {"reveng "};
char Cmd2[100 + 7]; char Cmd2[100 + 7];
memcpy(Cmd2, name, 7); memcpy(Cmd2, name, 7);
@ -60,7 +62,8 @@ int CmdCrc(const char *Cmd) {
//returns array of model names and the count of models returning //returns array of model names and the count of models returning
// as well as a width array for the width of each model // as well as a width array for the width of each model
int GetModels(char *Models[], int *count, uint8_t *width){ int GetModels(char *Models[], int *count, uint8_t *width)
{
/* default values */ /* default values */
static model_t model = MZERO; static model_t model = MZERO;
@ -245,7 +248,8 @@ int GetModels(char *Models[], int *count, uint8_t *width){
//endian = {0 = calc default endian input and output, b = big endian input and output, B = big endian output, r = right justified //endian = {0 = calc default endian input and output, b = big endian input and output, B = big endian output, r = right justified
// l = little endian input and output, L = little endian output only, t = left justified} // l = little endian input and output, L = little endian output only, t = left justified}
//result = calculated crc hex string //result = calculated crc hex string
int RunModel(char *inModel, char *inHexStr, bool reverse, char endian, char *result){ int RunModel(char *inModel, char *inHexStr, bool reverse, char endian, char *result)
{
/* default values */ /* default values */
static model_t model = MZERO; static model_t model = MZERO;
@ -364,7 +368,8 @@ int RunModel(char *inModel, char *inHexStr, bool reverse, char endian, char *res
} }
//test call to RunModel //test call to RunModel
int CmdrevengTestC(const char *Cmd){ int CmdrevengTestC(const char *Cmd)
{
int cmdp = 0; int cmdp = 0;
char inModel[30] = {0x00}; char inModel[30] = {0x00};
char inHexStr[30] = {0x00}; char inHexStr[30] = {0x00};
@ -387,7 +392,8 @@ int CmdrevengTestC(const char *Cmd){
} }
//returns a calloced string (needs to be freed) //returns a calloced string (needs to be freed)
char *SwapEndianStr(const char *inStr, const size_t len, const uint8_t blockSize){ char *SwapEndianStr(const char *inStr, const size_t len, const uint8_t blockSize)
{
char *tmp = calloc(len + 1, sizeof(char)); char *tmp = calloc(len + 1, sizeof(char));
for (uint8_t block = 0; block < (uint8_t)(len / blockSize); block++) { for (uint8_t block = 0; block < (uint8_t)(len / blockSize); block++) {
for (size_t i = 0; i < blockSize; i += 2) { for (size_t i = 0; i < blockSize; i += 2) {
@ -399,7 +405,8 @@ char *SwapEndianStr(const char *inStr, const size_t len, const uint8_t blockSize
} }
// takes hex string in and searches for a matching result (hex string must include checksum) // takes hex string in and searches for a matching result (hex string must include checksum)
int CmdrevengSearch(const char *Cmd){ int CmdrevengSearch(const char *Cmd)
{
#define NMODELS 105 #define NMODELS 105

View file

@ -17,7 +17,8 @@ int g_DemodClock = 0;
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_data_printdemodbuf(void){ int usage_data_printdemodbuf(void)
{
PrintAndLogEx(NORMAL, "Usage: data printdemodbuffer x o <offset> l <length>"); PrintAndLogEx(NORMAL, "Usage: data printdemodbuffer x o <offset> l <length>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h This help"); PrintAndLogEx(NORMAL, " h This help");
@ -26,7 +27,8 @@ int usage_data_printdemodbuf(void){
PrintAndLogEx(NORMAL, " l <length> enter length to print in # of bits or hex characters respectively"); PrintAndLogEx(NORMAL, " l <length> enter length to print in # of bits or hex characters respectively");
return 0; return 0;
} }
int usage_data_manrawdecode(void){ int usage_data_manrawdecode(void)
{
PrintAndLogEx(NORMAL, "Usage: data manrawdecode [invert] [maxErr]"); PrintAndLogEx(NORMAL, "Usage: data manrawdecode [invert] [maxErr]");
PrintAndLogEx(NORMAL, " Takes 10 and 01 and converts to 0 and 1 respectively"); PrintAndLogEx(NORMAL, " Takes 10 and 01 and converts to 0 and 1 respectively");
PrintAndLogEx(NORMAL, " --must have binary sequence in demodbuffer (run data askrawdemod first)"); PrintAndLogEx(NORMAL, " --must have binary sequence in demodbuffer (run data askrawdemod first)");
@ -36,7 +38,8 @@ int usage_data_manrawdecode(void){
PrintAndLogEx(NORMAL, " Example: data manrawdecode = decode manchester bitstream from the demodbuffer"); PrintAndLogEx(NORMAL, " Example: data manrawdecode = decode manchester bitstream from the demodbuffer");
return 0; return 0;
} }
int usage_data_biphaserawdecode(void){ int usage_data_biphaserawdecode(void)
{
PrintAndLogEx(NORMAL, "Usage: data biphaserawdecode [offset] [invert] [maxErr]"); PrintAndLogEx(NORMAL, "Usage: data biphaserawdecode [offset] [invert] [maxErr]");
PrintAndLogEx(NORMAL, " Converts 10 or 01 to 1 and 11 or 00 to 0"); PrintAndLogEx(NORMAL, " Converts 10 or 01 to 1 and 11 or 00 to 0");
PrintAndLogEx(NORMAL, " --must have binary sequence in demodbuffer (run data askrawdemod first)"); PrintAndLogEx(NORMAL, " --must have binary sequence in demodbuffer (run data askrawdemod first)");
@ -50,7 +53,8 @@ int usage_data_biphaserawdecode(void){
PrintAndLogEx(NORMAL, " Example: data biphaserawdecode 1 1 = decode biphase bitstream from the demodbuffer, set offset, and invert output"); PrintAndLogEx(NORMAL, " Example: data biphaserawdecode 1 1 = decode biphase bitstream from the demodbuffer, set offset, and invert output");
return 0; return 0;
} }
int usage_data_rawdemod(void){ int usage_data_rawdemod(void)
{
PrintAndLogEx(NORMAL, "Usage: data rawdemod [modulation] <help>|<options>"); PrintAndLogEx(NORMAL, "Usage: data rawdemod [modulation] <help>|<options>");
PrintAndLogEx(NORMAL, " [modulation] as 2 char, 'ab' for ask/biphase, 'am' for ask/manchester, 'ar' for ask/raw, 'fs' for fsk, ..."); PrintAndLogEx(NORMAL, " [modulation] as 2 char, 'ab' for ask/biphase, 'am' for ask/manchester, 'ar' for ask/raw, 'fs' for fsk, ...");
PrintAndLogEx(NORMAL, " 'nr' for nrz/direct, 'p1' for psk1, 'p2' for psk2"); PrintAndLogEx(NORMAL, " 'nr' for nrz/direct, 'p1' for psk1, 'p2' for psk2");
@ -67,7 +71,8 @@ int usage_data_rawdemod(void){
PrintAndLogEx(NORMAL, " : data rawdemod p2 = demod GraphBuffer using: psk2 - autodetect"); PrintAndLogEx(NORMAL, " : data rawdemod p2 = demod GraphBuffer using: psk2 - autodetect");
return 0; return 0;
} }
int usage_data_rawdemod_am(void){ int usage_data_rawdemod_am(void)
{
PrintAndLogEx(NORMAL, "Usage: data rawdemod am <s> [clock] <invert> [maxError] [maxLen] [amplify]"); PrintAndLogEx(NORMAL, "Usage: data rawdemod am <s> [clock] <invert> [maxError] [maxLen] [amplify]");
PrintAndLogEx(NORMAL, " ['s'] optional, check for Sequence Terminator"); PrintAndLogEx(NORMAL, " ['s'] optional, check for Sequence Terminator");
PrintAndLogEx(NORMAL, " [set clock as integer] optional, if not set, autodetect"); PrintAndLogEx(NORMAL, " [set clock as integer] optional, if not set, autodetect");
@ -83,7 +88,8 @@ int usage_data_rawdemod_am(void){
PrintAndLogEx(NORMAL, " : data rawdemod am 64 1 0 = demod an ask/manchester tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); PrintAndLogEx(NORMAL, " : data rawdemod am 64 1 0 = demod an ask/manchester tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
return 0; return 0;
} }
int usage_data_rawdemod_ab(void){ int usage_data_rawdemod_ab(void)
{
PrintAndLogEx(NORMAL, "Usage: data rawdemod ab [offset] [clock] <invert> [maxError] [maxLen] <amplify>"); PrintAndLogEx(NORMAL, "Usage: data rawdemod ab [offset] [clock] <invert> [maxError] [maxLen] <amplify>");
PrintAndLogEx(NORMAL, " [offset], offset to begin biphase, default=0"); PrintAndLogEx(NORMAL, " [offset], offset to begin biphase, default=0");
PrintAndLogEx(NORMAL, " [set clock as integer] optional, if not set, autodetect"); PrintAndLogEx(NORMAL, " [set clock as integer] optional, if not set, autodetect");
@ -106,7 +112,8 @@ int usage_data_rawdemod_ab(void){
PrintAndLogEx(NORMAL, " : data rawdemod ab 0 64 1 0 0 a = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp"); PrintAndLogEx(NORMAL, " : data rawdemod ab 0 64 1 0 0 a = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp");
return 0; return 0;
} }
int usage_data_rawdemod_ar(void){ int usage_data_rawdemod_ar(void)
{
PrintAndLogEx(NORMAL, "Usage: data rawdemod ar [clock] <invert> [maxError] [maxLen] [amplify]"); PrintAndLogEx(NORMAL, "Usage: data rawdemod ar [clock] <invert> [maxError] [maxLen] [amplify]");
PrintAndLogEx(NORMAL, " [set clock as integer] optional, if not set, autodetect"); PrintAndLogEx(NORMAL, " [set clock as integer] optional, if not set, autodetect");
PrintAndLogEx(NORMAL, " <invert>, 1 to invert output"); PrintAndLogEx(NORMAL, " <invert>, 1 to invert output");
@ -123,7 +130,8 @@ int usage_data_rawdemod_ar(void){
PrintAndLogEx(NORMAL, " : data rawdemod ar 64 1 0 0 a = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp"); PrintAndLogEx(NORMAL, " : data rawdemod ar 64 1 0 0 a = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp");
return 0; return 0;
} }
int usage_data_rawdemod_fs(void){ int usage_data_rawdemod_fs(void)
{
PrintAndLogEx(NORMAL, "Usage: data rawdemod fs [clock] <invert> [fchigh] [fclow]"); PrintAndLogEx(NORMAL, "Usage: data rawdemod fs [clock] <invert> [fchigh] [fclow]");
PrintAndLogEx(NORMAL, " [set clock as integer] optional, omit for autodetect."); PrintAndLogEx(NORMAL, " [set clock as integer] optional, omit for autodetect.");
PrintAndLogEx(NORMAL, " <invert>, 1 for invert output, can be used even if the clock is omitted"); PrintAndLogEx(NORMAL, " <invert>, 1 for invert output, can be used even if the clock is omitted");
@ -139,7 +147,8 @@ int usage_data_rawdemod_fs(void){
PrintAndLogEx(NORMAL, " : data rawdemod fs 50 1 10 8 = demod an fsk2a RF/50 tag from GraphBuffer"); PrintAndLogEx(NORMAL, " : data rawdemod fs 50 1 10 8 = demod an fsk2a RF/50 tag from GraphBuffer");
return 0; return 0;
} }
int usage_data_rawdemod_nr(void){ int usage_data_rawdemod_nr(void)
{
PrintAndLogEx(NORMAL, "Usage: data rawdemod nr [clock] <0|1> [maxError]"); PrintAndLogEx(NORMAL, "Usage: data rawdemod nr [clock] <0|1> [maxError]");
PrintAndLogEx(NORMAL, " [set clock as integer] optional, if not set, autodetect."); PrintAndLogEx(NORMAL, " [set clock as integer] optional, if not set, autodetect.");
PrintAndLogEx(NORMAL, " <invert>, 1 for invert output"); PrintAndLogEx(NORMAL, " <invert>, 1 for invert output");
@ -152,7 +161,8 @@ int usage_data_rawdemod_nr(void){
PrintAndLogEx(NORMAL, " : data rawdemod nr 64 1 0 = demod a nrz/direct tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); PrintAndLogEx(NORMAL, " : data rawdemod nr 64 1 0 = demod a nrz/direct tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
return 0; return 0;
} }
int usage_data_rawdemod_p1(void){ int usage_data_rawdemod_p1(void)
{
PrintAndLogEx(NORMAL, "Usage: data rawdemod p1 [clock] <0|1> [maxError]"); PrintAndLogEx(NORMAL, "Usage: data rawdemod p1 [clock] <0|1> [maxError]");
PrintAndLogEx(NORMAL, " [set clock as integer] optional, if not set, autodetect."); PrintAndLogEx(NORMAL, " [set clock as integer] optional, if not set, autodetect.");
PrintAndLogEx(NORMAL, " <invert>, 1 for invert output"); PrintAndLogEx(NORMAL, " <invert>, 1 for invert output");
@ -165,7 +175,8 @@ int usage_data_rawdemod_p1(void){
PrintAndLogEx(NORMAL, " : data rawdemod p1 64 1 0 = demod a psk1 tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors"); PrintAndLogEx(NORMAL, " : data rawdemod p1 64 1 0 = demod a psk1 tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
return 0; return 0;
} }
int usage_data_rawdemod_p2(void){ int usage_data_rawdemod_p2(void)
{
PrintAndLogEx(NORMAL, "Usage: data rawdemod p2 [clock] <0|1> [maxError]"); PrintAndLogEx(NORMAL, "Usage: data rawdemod p2 [clock] <0|1> [maxError]");
PrintAndLogEx(NORMAL, " [set clock as integer] optional, if not set, autodetect."); PrintAndLogEx(NORMAL, " [set clock as integer] optional, if not set, autodetect.");
PrintAndLogEx(NORMAL, " <invert>, 1 for invert output"); PrintAndLogEx(NORMAL, " <invert>, 1 for invert output");
@ -178,7 +189,8 @@ int usage_data_rawdemod_p2(void){
PrintAndLogEx(NORMAL, " : data rawdemod p2 64 1 0 = demod a psk2 tag from GraphBuffer using a clock of RF/64, inverting output and allowing 0 demod errors"); PrintAndLogEx(NORMAL, " : data rawdemod p2 64 1 0 = demod a psk2 tag from GraphBuffer using a clock of RF/64, inverting output and allowing 0 demod errors");
return 0; return 0;
} }
int usage_data_autocorr(void) { int usage_data_autocorr(void)
{
PrintAndLogEx(NORMAL, "Autocorrelate is used to detect repeating sequences. We use it as detection of length in bits a message inside the signal is"); PrintAndLogEx(NORMAL, "Autocorrelate is used to detect repeating sequences. We use it as detection of length in bits a message inside the signal is");
PrintAndLogEx(NORMAL, "Usage: data autocorr w <window> [g]"); PrintAndLogEx(NORMAL, "Usage: data autocorr w <window> [g]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -187,7 +199,8 @@ int usage_data_autocorr(void) {
PrintAndLogEx(NORMAL, " g save back to GraphBuffer (overwrite)"); PrintAndLogEx(NORMAL, " g save back to GraphBuffer (overwrite)");
return 0; return 0;
} }
int usage_data_undecimate(void){ int usage_data_undecimate(void)
{
PrintAndLogEx(NORMAL, "Usage: data undec [factor]"); PrintAndLogEx(NORMAL, "Usage: data undec [factor]");
PrintAndLogEx(NORMAL, "This function performs un-decimation, by repeating each sample N times"); PrintAndLogEx(NORMAL, "This function performs un-decimation, by repeating each sample N times");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -196,7 +209,8 @@ int usage_data_undecimate(void){
PrintAndLogEx(NORMAL, "Example: 'data undec 3'"); PrintAndLogEx(NORMAL, "Example: 'data undec 3'");
return 0; return 0;
} }
int usage_data_detectclock(void){ int usage_data_detectclock(void)
{
PrintAndLogEx(NORMAL, "Usage: data detectclock [modulation] <clock>"); PrintAndLogEx(NORMAL, "Usage: data detectclock [modulation] <clock>");
PrintAndLogEx(NORMAL, " [modulation as char], specify the modulation type you want to detect the clock of"); PrintAndLogEx(NORMAL, " [modulation as char], specify the modulation type you want to detect the clock of");
PrintAndLogEx(NORMAL, " <clock> , specify the clock (optional - to get best start position only)"); PrintAndLogEx(NORMAL, " <clock> , specify the clock (optional - to get best start position only)");
@ -208,24 +222,28 @@ int usage_data_detectclock(void){
PrintAndLogEx(NORMAL, " data detectclock n = detect the clock of an nrz/direct modulated wave in the GraphBuffer"); PrintAndLogEx(NORMAL, " data detectclock n = detect the clock of an nrz/direct modulated wave in the GraphBuffer");
return 0; return 0;
} }
int usage_data_hex2bin(void){ int usage_data_hex2bin(void)
{
PrintAndLogEx(NORMAL, "Usage: data hex2bin <hex_digits>"); PrintAndLogEx(NORMAL, "Usage: data hex2bin <hex_digits>");
PrintAndLogEx(NORMAL, " This function will ignore all non-hexadecimal characters (but stop reading on whitespace)"); PrintAndLogEx(NORMAL, " This function will ignore all non-hexadecimal characters (but stop reading on whitespace)");
return 0; return 0;
} }
int usage_data_bin2hex(void){ int usage_data_bin2hex(void)
{
PrintAndLogEx(NORMAL, "Usage: data bin2hex <binary_digits>"); PrintAndLogEx(NORMAL, "Usage: data bin2hex <binary_digits>");
PrintAndLogEx(NORMAL, " This function will ignore all characters not 1 or 0 (but stop reading on whitespace)"); PrintAndLogEx(NORMAL, " This function will ignore all characters not 1 or 0 (but stop reading on whitespace)");
return 0; return 0;
} }
int usage_data_buffclear(void){ int usage_data_buffclear(void)
{
PrintAndLogEx(NORMAL, "This function clears the bigbuff on deviceside"); PrintAndLogEx(NORMAL, "This function clears the bigbuff on deviceside");
PrintAndLogEx(NORMAL, "Usage: data buffclear [h]"); PrintAndLogEx(NORMAL, "Usage: data buffclear [h]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h This help"); PrintAndLogEx(NORMAL, " h This help");
return 0; return 0;
} }
int usage_data_fsktonrz() { int usage_data_fsktonrz()
{
PrintAndLogEx(NORMAL, "Usage: data fsktonrz c <clock> l <fc_low> f <fc_high>"); PrintAndLogEx(NORMAL, "Usage: data fsktonrz c <clock> l <fc_low> f <fc_high>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h This help"); PrintAndLogEx(NORMAL, " h This help");
@ -237,7 +255,8 @@ int usage_data_fsktonrz() {
//set the demod buffer with given array of binary (one bit per byte) //set the demod buffer with given array of binary (one bit per byte)
//by marshmellow //by marshmellow
void setDemodBuf(uint8_t *buf, size_t size, size_t start_idx) { void setDemodBuf(uint8_t *buf, size_t size, size_t start_idx)
{
if (buf == NULL) return; if (buf == NULL) return;
if (size > MAX_DEMOD_BUF_LEN - start_idx) if (size > MAX_DEMOD_BUF_LEN - start_idx)
@ -249,7 +268,8 @@ void setDemodBuf(uint8_t *buf, size_t size, size_t start_idx) {
DemodBufferLen = size; DemodBufferLen = size;
} }
bool getDemodBuf(uint8_t *buf, size_t *size) { bool getDemodBuf(uint8_t *buf, size_t *size)
{
if (buf == NULL) return false; if (buf == NULL) return false;
if (size == NULL) return false; if (size == NULL) return false;
if (*size == 0) return false; if (*size == 0) return false;
@ -262,35 +282,41 @@ bool getDemodBuf(uint8_t *buf, size_t *size) {
// include <math.h> // include <math.h>
// Root mean square // Root mean square
double rms(double *v, size_t n) { double rms(double *v, size_t n)
{
double sum = 0.0; double sum = 0.0;
for (size_t i = 0; i < n; i++) for (size_t i = 0; i < n; i++)
sum += v[i] * v[i]; sum += v[i] * v[i];
return sqrt(sum / n); return sqrt(sum / n);
} }
int cmp_int( const void *a, const void *b) { int cmp_int(const void *a, const void *b)
{
if (*(const int *)a < * (const int *)b) if (*(const int *)a < * (const int *)b)
return -1; return -1;
else else
return *(const int *)a > *(const int *)b; return *(const int *)a > *(const int *)b;
} }
int cmp_uint8( const void *a, const void *b) { int cmp_uint8(const void *a, const void *b)
{
if (*(const uint8_t *)a < * (const uint8_t *)b) if (*(const uint8_t *)a < * (const uint8_t *)b)
return -1; return -1;
else else
return *(const uint8_t *)a > *(const uint8_t *)b; return *(const uint8_t *)a > *(const uint8_t *)b;
} }
// Median of a array of values // Median of a array of values
double median_int( int *src, size_t size ) { double median_int(int *src, size_t size)
{
qsort(src, size, sizeof(int), cmp_int); qsort(src, size, sizeof(int), cmp_int);
return 0.5 * (src[size / 2] + src[(size - 1) / 2]); return 0.5 * (src[size / 2] + src[(size - 1) / 2]);
} }
double median_uint8( uint8_t *src, size_t size ) { double median_uint8(uint8_t *src, size_t size)
{
qsort(src, size, sizeof(uint8_t), cmp_uint8); qsort(src, size, sizeof(uint8_t), cmp_uint8);
return 0.5 * (src[size / 2] + src[(size - 1) / 2]); return 0.5 * (src[size / 2] + src[(size - 1) / 2]);
} }
// function to compute mean for a series // function to compute mean for a series
static double compute_mean(const int *data, size_t n) { static double compute_mean(const int *data, size_t n)
{
double mean = 0.0; double mean = 0.0;
for (size_t i = 0; i < n; i++) for (size_t i = 0; i < n; i++)
mean += data[i]; mean += data[i];
@ -299,7 +325,8 @@ static double compute_mean(const int *data, size_t n) {
} }
// function to compute variance for a series // function to compute variance for a series
static double compute_variance(const int *data, size_t n) { static double compute_variance(const int *data, size_t n)
{
double variance = 0.0; double variance = 0.0;
double mean = compute_mean(data, n); double mean = compute_mean(data, n);
@ -335,7 +362,8 @@ static double compute_autoc(const int *data, size_t n, int lag) {
*/ */
// option '1' to save DemodBuffer any other to restore // option '1' to save DemodBuffer any other to restore
void save_restoreDB(uint8_t saveOpt) { void save_restoreDB(uint8_t saveOpt)
{
static uint8_t SavedDB[MAX_DEMOD_BUF_LEN]; static uint8_t SavedDB[MAX_DEMOD_BUF_LEN];
static size_t SavedDBlen; static size_t SavedDBlen;
static bool DB_Saved = false; static bool DB_Saved = false;
@ -358,7 +386,8 @@ void save_restoreDB(uint8_t saveOpt) {
} }
} }
int CmdSetDebugMode(const char *Cmd) { int CmdSetDebugMode(const char *Cmd)
{
int demod = 0; int demod = 0;
sscanf(Cmd, "%i", &demod); sscanf(Cmd, "%i", &demod);
g_debugMode = (uint8_t)demod; g_debugMode = (uint8_t)demod;
@ -367,7 +396,8 @@ int CmdSetDebugMode(const char *Cmd) {
//by marshmellow //by marshmellow
// max output to 512 bits if we have more - should be plenty // max output to 512 bits if we have more - should be plenty
void printDemodBuff(void) { void printDemodBuff(void)
{
int len = DemodBufferLen; int len = DemodBufferLen;
if (len < 1) { if (len < 1) {
PrintAndLogEx(NORMAL, "(printDemodBuff) no bits found in demod buffer"); PrintAndLogEx(NORMAL, "(printDemodBuff) no bits found in demod buffer");
@ -378,7 +408,8 @@ void printDemodBuff(void) {
PrintAndLogEx(NORMAL, "%s", sprint_bin_break(DemodBuffer, len, 16)); PrintAndLogEx(NORMAL, "%s", sprint_bin_break(DemodBuffer, len, 16));
} }
int CmdPrintDemodBuff(const char *Cmd) { int CmdPrintDemodBuff(const char *Cmd)
{
char hex[512] = {0x00}; char hex[512] = {0x00};
bool hexMode = false; bool hexMode = false;
bool errors = false; bool errors = false;
@ -435,7 +466,8 @@ int CmdPrintDemodBuff(const char *Cmd) {
//by marshmellow //by marshmellow
//this function strictly converts >1 to 1 and <1 to 0 for each sample in the graphbuffer //this function strictly converts >1 to 1 and <1 to 0 for each sample in the graphbuffer
int CmdGetBitStream(const char *Cmd) { int CmdGetBitStream(const char *Cmd)
{
CmdHpf(Cmd); CmdHpf(Cmd);
for (uint32_t i = 0; i < GraphTraceLen; i++) for (uint32_t i = 0; i < GraphTraceLen; i++)
GraphBuffer[i] = (GraphBuffer[i] >= 1) ? 1 : 0; GraphBuffer[i] = (GraphBuffer[i] >= 1) ? 1 : 0;
@ -450,7 +482,8 @@ int CmdGetBitStream(const char *Cmd) {
//verbose will print results and demoding messages //verbose will print results and demoding messages
//emSearch will auto search for EM410x format in bitstream //emSearch will auto search for EM410x format in bitstream
//askType switches decode: ask/raw = 0, ask/manchester = 1 //askType switches decode: ask/raw = 0, ask/manchester = 1
int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType, bool *stCheck) { int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType, bool *stCheck)
{
int invert = 0; int invert = 0;
int clk = 0; int clk = 0;
int maxErr = 100; int maxErr = 100;
@ -536,7 +569,8 @@ int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType,
return 1; return 1;
} }
int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType) { int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType)
{
bool st = false; bool st = false;
return ASKDemod_ext(Cmd, verbose, emSearch, askType, &st); return ASKDemod_ext(Cmd, verbose, emSearch, askType, &st);
} }
@ -562,7 +596,8 @@ int Cmdaskmandemod(const char *Cmd)
//by marshmellow //by marshmellow
//manchester decode //manchester decode
//stricktly take 10 and 01 and convert to 0 and 1 //stricktly take 10 and 01 and convert to 0 and 1
int Cmdmandecoderaw(const char *Cmd) { int Cmdmandecoderaw(const char *Cmd)
{
size_t size = 0; size_t size = 0;
int high = 0, low = 0; int high = 0, low = 0;
int i = 0, errCnt = 0, invert = 0, maxErr = 20; int i = 0, errCnt = 0, invert = 0, maxErr = 20;
@ -617,7 +652,8 @@ int Cmdmandecoderaw(const char *Cmd) {
//takes 2 arguments "offset" default = 0 if 1 it will shift the decode by one bit //takes 2 arguments "offset" default = 0 if 1 it will shift the decode by one bit
// and "invert" default = 0 if 1 it will invert output // and "invert" default = 0 if 1 it will invert output
// the argument offset allows us to manually shift if the output is incorrect - [EDIT: now auto detects] // the argument offset allows us to manually shift if the output is incorrect - [EDIT: now auto detects]
int CmdBiphaseDecodeRaw(const char *Cmd) { int CmdBiphaseDecodeRaw(const char *Cmd)
{
size_t size = 0; size_t size = 0;
int offset = 0, invert = 0, maxErr = 20, errCnt = 0; int offset = 0, invert = 0, maxErr = 20, errCnt = 0;
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
@ -716,7 +752,8 @@ int Cmdaskrawdemod(const char *Cmd)
return ASKDemod(Cmd, true, false, 0); return ASKDemod(Cmd, true, false, 0);
} }
int AutoCorrelate(const int *in, int *out, size_t len, int window, bool SaveGrph, bool verbose) { int AutoCorrelate(const int *in, int *out, size_t len, int window, bool SaveGrph, bool verbose)
{
// sanity check // sanity check
if (window > len) window = len; if (window > len) window = len;
@ -790,8 +827,7 @@ int AutoCorrelate(const int *in, int *out, size_t len, int window, bool SaveGrph
if (distance > 0) { if (distance > 0) {
setClockGrid(distance, idx); setClockGrid(distance, idx);
retval = distance; retval = distance;
} } else
else
setClockGrid(correlation, idx); setClockGrid(correlation, idx);
CursorCPos = idx_1; CursorCPos = idx_1;
@ -803,7 +839,8 @@ int AutoCorrelate(const int *in, int *out, size_t len, int window, bool SaveGrph
return retval; return retval;
} }
int CmdAutoCorr(const char *Cmd) { int CmdAutoCorr(const char *Cmd)
{
uint32_t window = 4000; uint32_t window = 4000;
uint8_t cmdp = 0; uint8_t cmdp = 0;
@ -899,8 +936,7 @@ int CmdUndec(const char *Cmd)
//We have memory, don't we? //We have memory, don't we?
int swap[MAX_GRAPH_TRACE_LEN] = {0}; int swap[MAX_GRAPH_TRACE_LEN] = {0};
uint32_t g_index = 0, s_index = 0; uint32_t g_index = 0, s_index = 0;
while(g_index < GraphTraceLen && s_index + factor < MAX_GRAPH_TRACE_LEN) while (g_index < GraphTraceLen && s_index + factor < MAX_GRAPH_TRACE_LEN) {
{
int count = 0; int count = 0;
for (count = 0; count < factor && s_index + count < MAX_GRAPH_TRACE_LEN; count++) for (count = 0; count < factor && s_index + count < MAX_GRAPH_TRACE_LEN; count++)
swap[s_index + count] = GraphBuffer[g_index]; swap[s_index + count] = GraphBuffer[g_index];
@ -916,7 +952,8 @@ int CmdUndec(const char *Cmd)
//by marshmellow //by marshmellow
//shift graph zero up or down based on input + or - //shift graph zero up or down based on input + or -
int CmdGraphShiftZero(const char *Cmd) { int CmdGraphShiftZero(const char *Cmd)
{
int shift = 0, shiftedVal = 0; int shift = 0, shiftedVal = 0;
//set options from parameters entered with the command //set options from parameters entered with the command
sscanf(Cmd, "%i", &shift); sscanf(Cmd, "%i", &shift);
@ -937,7 +974,8 @@ int CmdGraphShiftZero(const char *Cmd) {
return 0; return 0;
} }
int AskEdgeDetect(const int *in, int *out, int len, int threshold) { int AskEdgeDetect(const int *in, int *out, int len, int threshold)
{
int last = 0; int last = 0;
for (int i = 1; i < len; i++) { for (int i = 1; i < len; i++) {
if (in[i] - in[i - 1] >= threshold) //large jump up if (in[i] - in[i - 1] >= threshold) //large jump up
@ -953,7 +991,8 @@ int AskEdgeDetect(const int *in, int *out, int len, int threshold) {
//use large jumps in read samples to identify edges of waves and then amplify that wave to max //use large jumps in read samples to identify edges of waves and then amplify that wave to max
//similar to dirtheshold, threshold commands //similar to dirtheshold, threshold commands
//takes a threshold length which is the measured length between two samples then determines an edge //takes a threshold length which is the measured length between two samples then determines an edge
int CmdAskEdgeDetect(const char *Cmd) { int CmdAskEdgeDetect(const char *Cmd)
{
int thresLen = 25; int thresLen = 25;
int ans = 0; int ans = 0;
sscanf(Cmd, "%i", &thresLen); sscanf(Cmd, "%i", &thresLen);
@ -966,7 +1005,8 @@ int CmdAskEdgeDetect(const char *Cmd) {
/* Print our clock rate */ /* Print our clock rate */
// uses data from graphbuffer // uses data from graphbuffer
// adjusted to take char parameter for type of modulation to find the clock - by marshmellow. // adjusted to take char parameter for type of modulation to find the clock - by marshmellow.
int CmdDetectClockRate(const char *Cmd) { int CmdDetectClockRate(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) > 6 || strlen(Cmd) == 0 || cmdp == 'h') if (strlen(Cmd) > 6 || strlen(Cmd) == 0 || cmdp == 'h')
return usage_data_detectclock(); return usage_data_detectclock();
@ -1023,7 +1063,8 @@ char *GetFSKType(uint8_t fchigh, uint8_t fclow, uint8_t invert)
//fsk raw demod and print binary //fsk raw demod and print binary
//takes 4 arguments - Clock, invert, fchigh, fclow //takes 4 arguments - Clock, invert, fchigh, fclow
//defaults: clock = 50, invert=1, fchigh=10, fclow=8 (RF/10 RF/8 (fsk2a)) //defaults: clock = 50, invert=1, fchigh=10, fclow=8 (RF/10 RF/8 (fsk2a))
int FSKrawDemod(const char *Cmd, bool verbose) { int FSKrawDemod(const char *Cmd, bool verbose)
{
//raw fsk demod no manchester decoding no start bit finding just get binary from wave //raw fsk demod no manchester decoding no start bit finding just get binary from wave
uint8_t rfLen, invert, fchigh, fclow; uint8_t rfLen, invert, fchigh, fclow;
@ -1089,7 +1130,8 @@ int FSKrawDemod(const char *Cmd, bool verbose) {
//fsk raw demod and print binary //fsk raw demod and print binary
//takes 4 arguments - Clock, invert, fchigh, fclow //takes 4 arguments - Clock, invert, fchigh, fclow
//defaults: clock = 50, invert=1, fchigh=10, fclow=8 (RF/10 RF/8 (fsk2a)) //defaults: clock = 50, invert=1, fchigh=10, fclow=8 (RF/10 RF/8 (fsk2a))
int CmdFSKrawdemod(const char *Cmd) { int CmdFSKrawdemod(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) > 20 || cmdp == 'h') return usage_data_rawdemod_fs(); if (strlen(Cmd) > 20 || cmdp == 'h') return usage_data_rawdemod_fs();
@ -1098,7 +1140,8 @@ int CmdFSKrawdemod(const char *Cmd) {
//by marshmellow //by marshmellow
//attempt to psk1 demod graph buffer //attempt to psk1 demod graph buffer
int PSKDemod(const char *Cmd, bool verbose) { int PSKDemod(const char *Cmd, bool verbose)
{
int invert = 0, clk = 0, maxErr = 100; int invert = 0, clk = 0, maxErr = 100;
sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr); sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr);
if (clk == 1) { if (clk == 1) {
@ -1139,7 +1182,8 @@ int PSKDemod(const char *Cmd, bool verbose) {
return 1; return 1;
} }
int CmdPSKIdteck(const char *Cmd) { int CmdPSKIdteck(const char *Cmd)
{
if (!PSKDemod("", false)) { if (!PSKDemod("", false)) {
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck PSKDemod failed"); PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck PSKDemod failed");
@ -1203,7 +1247,8 @@ int CmdPSKIdteck(const char *Cmd) {
// takes 3 arguments - clock, invert, maxErr as integers // takes 3 arguments - clock, invert, maxErr as integers
// attempts to demodulate nrz only // attempts to demodulate nrz only
// prints binary found and saves in demodbuffer for further commands // prints binary found and saves in demodbuffer for further commands
int NRZrawDemod(const char *Cmd, bool verbose) { int NRZrawDemod(const char *Cmd, bool verbose)
{
int errCnt = 0, clkStartIdx = 0; int errCnt = 0, clkStartIdx = 0;
int invert = 0, clk = 0, maxErr = 100; int invert = 0, clk = 0, maxErr = 100;
@ -1250,7 +1295,8 @@ int NRZrawDemod(const char *Cmd, bool verbose) {
return 1; return 1;
} }
int CmdNRZrawDemod(const char *Cmd) { int CmdNRZrawDemod(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) > 16 || cmdp == 'h') return usage_data_rawdemod_nr(); if (strlen(Cmd) > 16 || cmdp == 'h') return usage_data_rawdemod_nr();
@ -1261,7 +1307,8 @@ int CmdNRZrawDemod(const char *Cmd) {
// takes 3 arguments - clock, invert, maxErr as integers // takes 3 arguments - clock, invert, maxErr as integers
// attempts to demodulate psk only // attempts to demodulate psk only
// prints binary found and saves in demodbuffer for further commands // prints binary found and saves in demodbuffer for further commands
int CmdPSK1rawDemod(const char *Cmd) { int CmdPSK1rawDemod(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) > 16 || cmdp == 'h') return usage_data_rawdemod_p1(); if (strlen(Cmd) > 16 || cmdp == 'h') return usage_data_rawdemod_p1();
@ -1279,7 +1326,8 @@ int CmdPSK1rawDemod(const char *Cmd) {
// by marshmellow // by marshmellow
// takes same args as cmdpsk1rawdemod // takes same args as cmdpsk1rawdemod
int CmdPSK2rawDemod(const char *Cmd) { int CmdPSK2rawDemod(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) > 16 || cmdp == 'h') return usage_data_rawdemod_p2(); if (strlen(Cmd) > 16 || cmdp == 'h') return usage_data_rawdemod_p2();
@ -1296,7 +1344,8 @@ int CmdPSK2rawDemod(const char *Cmd) {
} }
// by marshmellow - combines all raw demod functions into one menu command // by marshmellow - combines all raw demod functions into one menu command
int CmdRawDemod(const char *Cmd) { int CmdRawDemod(const char *Cmd)
{
int ans = 0; int ans = 0;
if (strlen(Cmd) > 35 || strlen(Cmd) < 2) if (strlen(Cmd) > 35 || strlen(Cmd) < 2)
@ -1316,7 +1365,8 @@ int CmdRawDemod(const char *Cmd) {
return ans; return ans;
} }
void setClockGrid(int clk, int offset) { void setClockGrid(int clk, int offset)
{
g_DemodStartIdx = offset; g_DemodStartIdx = offset;
g_DemodClock = clk; g_DemodClock = clk;
PrintAndLogEx(DEBUG, "DEBUG: (setClockGrid) demodoffset %d, clk %d", offset, clk); PrintAndLogEx(DEBUG, "DEBUG: (setClockGrid) demodoffset %d, clk %d", offset, clk);
@ -1340,7 +1390,8 @@ void setClockGrid(int clk, int offset) {
} }
} }
int CmdGrid(const char *Cmd) { int CmdGrid(const char *Cmd)
{
sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY); sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY);
PlotGridXdefault = PlotGridX; PlotGridXdefault = PlotGridX;
PlotGridYdefault = PlotGridY; PlotGridYdefault = PlotGridY;
@ -1348,13 +1399,15 @@ int CmdGrid(const char *Cmd) {
return 0; return 0;
} }
int CmdSetGraphMarkers(const char *Cmd) { int CmdSetGraphMarkers(const char *Cmd)
{
sscanf(Cmd, "%i %i", &CursorCPos, &CursorDPos); sscanf(Cmd, "%i %i", &CursorCPos, &CursorDPos);
RepaintGraphWindow(); RepaintGraphWindow();
return 0; return 0;
} }
int CmdHexsamples(const char *Cmd) { int CmdHexsamples(const char *Cmd)
{
int i, j, requested = 0, offset = 0; int i, j, requested = 0, offset = 0;
char string_buf[25]; char string_buf[25];
char *string_ptr = string_buf; char *string_ptr = string_buf;
@ -1396,13 +1449,15 @@ int CmdHexsamples(const char *Cmd) {
return 0; return 0;
} }
int CmdHide(const char *Cmd) { int CmdHide(const char *Cmd)
{
HideGraphWindow(); HideGraphWindow();
return 0; return 0;
} }
//zero mean GraphBuffer //zero mean GraphBuffer
int CmdHpf(const char *Cmd) { int CmdHpf(const char *Cmd)
{
uint8_t bits[GraphTraceLen]; uint8_t bits[GraphTraceLen];
size_t size = getFromGraphBuf(bits); size_t size = getFromGraphBuf(bits);
removeSignalOffset(bits, size); removeSignalOffset(bits, size);
@ -1415,13 +1470,15 @@ int CmdHpf(const char *Cmd) {
return 0; return 0;
} }
bool _headBit( BitstreamOut *stream) { bool _headBit(BitstreamOut *stream)
{
int bytepos = stream->position >> 3; // divide by 8 int bytepos = stream->position >> 3; // divide by 8
int bitpos = (stream->position++) & 7; // mask out 00000111 int bitpos = (stream->position++) & 7; // mask out 00000111
return (*(stream->buffer + bytepos) >> (7 - bitpos)) & 1; return (*(stream->buffer + bytepos) >> (7 - bitpos)) & 1;
} }
uint8_t getByte(uint8_t bits_per_sample, BitstreamOut* b) { uint8_t getByte(uint8_t bits_per_sample, BitstreamOut *b)
{
uint8_t val = 0; uint8_t val = 0;
for (int i = 0 ; i < bits_per_sample; i++) for (int i = 0 ; i < bits_per_sample; i++)
val |= (_headBit(b) << (7 - i)); val |= (_headBit(b) << (7 - i));
@ -1429,7 +1486,8 @@ uint8_t getByte(uint8_t bits_per_sample, BitstreamOut* b) {
return val; return val;
} }
int getSamples(int n, bool silent) { int getSamples(int n, bool silent)
{
//If we get all but the last byte in bigbuf, //If we get all but the last byte in bigbuf,
// we don't have to worry about remaining trash // we don't have to worry about remaining trash
// in the last byte in case the bits-per-sample // in the last byte in case the bits-per-sample
@ -1490,12 +1548,14 @@ int getSamples(int n, bool silent) {
return 0; return 0;
} }
int CmdSamples(const char *Cmd) { int CmdSamples(const char *Cmd)
{
int n = strtol(Cmd, NULL, 0); int n = strtol(Cmd, NULL, 0);
return getSamples(n, false); return getSamples(n, false);
} }
int CmdTuneSamples(const char *Cmd) { int CmdTuneSamples(const char *Cmd)
{
#define NON_VOLTAGE 1000 #define NON_VOLTAGE 1000
#define LF_UNUSABLE_V 2000 #define LF_UNUSABLE_V 2000
#define LF_MARGINAL_V 10000 #define LF_MARGINAL_V 10000
@ -1518,7 +1578,8 @@ int CmdTuneSamples(const char *Cmd) {
UsbCommand resp; UsbCommand resp;
while (!WaitForResponseTimeout(CMD_MEASURED_ANTENNA_TUNING, &resp, 2000)) { while (!WaitForResponseTimeout(CMD_MEASURED_ANTENNA_TUNING, &resp, 2000)) {
timeout++; timeout++;
printf("."); fflush(stdout); printf(".");
fflush(stdout);
if (timeout > 7) { if (timeout > 7) {
PrintAndLogEx(WARNING, "\nno response from Proxmark. Aborting..."); PrintAndLogEx(WARNING, "\nno response from Proxmark. Aborting...");
return 1; return 1;
@ -1593,7 +1654,8 @@ int CmdTuneSamples(const char *Cmd) {
return 0; return 0;
} }
int CmdLoad(const char *Cmd) { int CmdLoad(const char *Cmd)
{
char filename[FILE_PATH_SIZE] = {0x00}; char filename[FILE_PATH_SIZE] = {0x00};
int len = 0; int len = 0;
@ -1636,7 +1698,8 @@ int CmdLoad(const char *Cmd) {
} }
// trim graph from the end // trim graph from the end
int CmdLtrim(const char *Cmd) { int CmdLtrim(const char *Cmd)
{
// sanitycheck // sanitycheck
if (GraphTraceLen <= 0) return 1; if (GraphTraceLen <= 0) return 1;
@ -1650,7 +1713,8 @@ int CmdLtrim(const char *Cmd) {
} }
// trim graph from the beginning // trim graph from the beginning
int CmdRtrim(const char *Cmd) { int CmdRtrim(const char *Cmd)
{
int ds = atoi(Cmd); int ds = atoi(Cmd);
@ -1663,7 +1727,8 @@ int CmdRtrim(const char *Cmd) {
} }
// trim graph (middle) piece // trim graph (middle) piece
int CmdMtrim(const char *Cmd) { int CmdMtrim(const char *Cmd)
{
int start = 0, stop = 0; int start = 0, stop = 0;
sscanf(Cmd, "%i %i", &start, &stop); sscanf(Cmd, "%i %i", &start, &stop);
@ -1679,7 +1744,8 @@ int CmdMtrim(const char *Cmd) {
return 0; return 0;
} }
int CmdNorm(const char *Cmd) { int CmdNorm(const char *Cmd)
{
int i; int i;
int max = INT_MIN, min = INT_MAX; int max = INT_MIN, min = INT_MAX;
@ -1705,12 +1771,14 @@ int CmdNorm(const char *Cmd) {
return 0; return 0;
} }
int CmdPlot(const char *Cmd) { int CmdPlot(const char *Cmd)
{
ShowGraphWindow(); ShowGraphWindow();
return 0; return 0;
} }
int CmdSave(const char *Cmd) { int CmdSave(const char *Cmd)
{
int len = 0; int len = 0;
char filename[FILE_PATH_SIZE] = {0x00}; char filename[FILE_PATH_SIZE] = {0x00};
@ -1735,7 +1803,8 @@ int CmdSave(const char *Cmd) {
return 0; return 0;
} }
int CmdScale(const char *Cmd) { int CmdScale(const char *Cmd)
{
CursorScaleFactor = atoi(Cmd); CursorScaleFactor = atoi(Cmd);
if (CursorScaleFactor == 0) { if (CursorScaleFactor == 0) {
PrintAndLogEx(FAILED, "bad, can't have zero scale"); PrintAndLogEx(FAILED, "bad, can't have zero scale");
@ -1745,7 +1814,8 @@ int CmdScale(const char *Cmd) {
return 0; return 0;
} }
int directionalThreshold(const int* in, int *out, size_t len, int8_t up, int8_t down) { int directionalThreshold(const int *in, int *out, size_t len, int8_t up, int8_t down)
{
int lastValue = in[0]; int lastValue = in[0];
@ -1755,19 +1825,15 @@ int directionalThreshold(const int* in, int *out, size_t len, int8_t up, int8_t
for (size_t i = 1; i < len; ++i) { for (size_t i = 1; i < len; ++i) {
// Apply first threshold to samples heading up // Apply first threshold to samples heading up
if (in[i] >= up && in[i] > lastValue) if (in[i] >= up && in[i] > lastValue) {
{
lastValue = out[i]; // Buffer last value as we overwrite it. lastValue = out[i]; // Buffer last value as we overwrite it.
out[i] = 1; out[i] = 1;
} }
// Apply second threshold to samples heading down // Apply second threshold to samples heading down
else if (in[i] <= down && in[i] < lastValue) else if (in[i] <= down && in[i] < lastValue) {
{
lastValue = out[i]; // Buffer last value as we overwrite it. lastValue = out[i]; // Buffer last value as we overwrite it.
out[i] = -1; out[i] = -1;
} } else {
else
{
lastValue = out[i]; // Buffer last value as we overwrite it. lastValue = out[i]; // Buffer last value as we overwrite it.
out[i] = out[i - 1]; out[i] = out[i - 1];
} }
@ -1778,7 +1844,8 @@ int directionalThreshold(const int* in, int *out, size_t len, int8_t up, int8_t
return 0; return 0;
} }
int CmdDirectionalThreshold(const char *Cmd) { int CmdDirectionalThreshold(const char *Cmd)
{
int8_t up = param_get8(Cmd, 0); int8_t up = param_get8(Cmd, 0);
int8_t down = param_get8(Cmd, 1); int8_t down = param_get8(Cmd, 1);
@ -1796,7 +1863,8 @@ int CmdDirectionalThreshold(const char *Cmd) {
return 0; return 0;
} }
int CmdZerocrossings(const char *Cmd) { int CmdZerocrossings(const char *Cmd)
{
// Zero-crossings aren't meaningful unless the signal is zero-mean. // Zero-crossings aren't meaningful unless the signal is zero-mean.
CmdHpf(""); CmdHpf("");
@ -1832,7 +1900,8 @@ int CmdZerocrossings(const char *Cmd) {
* @param Cmd * @param Cmd
* @return * @return
*/ */
int Cmdbin2hex(const char *Cmd) { int Cmdbin2hex(const char *Cmd)
{
int bg = 0, en = 0; int bg = 0, en = 0;
if (param_getptr(Cmd, &bg, &en, 0)) if (param_getptr(Cmd, &bg, &en, 0))
return usage_data_bin2hex(); return usage_data_bin2hex();
@ -1862,7 +1931,8 @@ int Cmdbin2hex(const char *Cmd) {
return 0; return 0;
} }
int Cmdhex2bin(const char *Cmd) { int Cmdhex2bin(const char *Cmd)
{
int bg = 0, en = 0; int bg = 0, en = 0;
if (param_getptr(Cmd, &bg, &en, 0)) return usage_data_hex2bin(); if (param_getptr(Cmd, &bg, &en, 0)) return usage_data_hex2bin();
@ -1906,7 +1976,8 @@ int Cmdhex2bin(const char *Cmd) {
1, 1, 1, 1, -1, -1, -1, -1, -1, // note one extra -1 to padd due to 50/8 remainder 1, 1, 1, 1, -1, -1, -1, -1, -1, // note one extra -1 to padd due to 50/8 remainder
}; };
*/ */
void GetHiLoTone(int *LowTone, int *HighTone, int clk, int LowToneFC, int HighToneFC) { void GetHiLoTone(int *LowTone, int *HighTone, int clk, int LowToneFC, int HighToneFC)
{
int i, j = 0; int i, j = 0;
int Left_Modifier = ((clk % LowToneFC) % 2) + ((clk % LowToneFC) / 2); int Left_Modifier = ((clk % LowToneFC) % 2) + ((clk % LowToneFC) / 2);
int Right_Modifier = (clk % LowToneFC) / 2; int Right_Modifier = (clk % LowToneFC) / 2;
@ -1969,7 +2040,8 @@ void GetHiLoTone(int *LowTone, int *HighTone, int clk, int LowToneFC, int HighTo
//old CmdFSKdemod adapted by marshmellow //old CmdFSKdemod adapted by marshmellow
//converts FSK to clear NRZ style wave. (or demodulates) //converts FSK to clear NRZ style wave. (or demodulates)
int FSKToNRZ(int *data, int *dataLen, int clk, int LowToneFC, int HighToneFC) { int FSKToNRZ(int *data, int *dataLen, int clk, int LowToneFC, int HighToneFC)
{
uint8_t ans = 0; uint8_t ans = 0;
if (clk == 0 || LowToneFC == 0 || HighToneFC == 0) { if (clk == 0 || LowToneFC == 0 || HighToneFC == 0) {
int firstClockEdge = 0; int firstClockEdge = 0;
@ -2030,7 +2102,8 @@ int FSKToNRZ(int *data, int *dataLen, int clk, int LowToneFC, int HighToneFC) {
return 0; return 0;
} }
int CmdFSKToNRZ(const char *Cmd) { int CmdFSKToNRZ(const char *Cmd)
{
// take clk, fc_low, fc_high // take clk, fc_low, fc_high
// blank = auto; // blank = auto;
bool errors = false; bool errors = false;
@ -2070,7 +2143,8 @@ int CmdFSKToNRZ(const char *Cmd) {
return ans; return ans;
} }
int CmdDataIIR(const char *Cmd){ int CmdDataIIR(const char *Cmd)
{
uint8_t k = param_get8(Cmd, 0); uint8_t k = param_get8(Cmd, 0);
//iceIIR_Butterworth(GraphBuffer, GraphTraceLen); //iceIIR_Butterworth(GraphBuffer, GraphTraceLen);
iceSimple_Filter(GraphBuffer, GraphTraceLen, k); iceSimple_Filter(GraphBuffer, GraphTraceLen, k);
@ -2124,13 +2198,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdData(const char *Cmd) { int CmdData(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -26,7 +26,8 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_flashmem_spibaud(void){ int usage_flashmem_spibaud(void)
{
PrintAndLogEx(NORMAL, "Usage: mem spibaud [h] <baudrate>"); PrintAndLogEx(NORMAL, "Usage: mem spibaud [h] <baudrate>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " h this help");
@ -40,7 +41,8 @@ int usage_flashmem_spibaud(void){
return 0; return 0;
} }
int usage_flashmem_read(void){ int usage_flashmem_read(void)
{
PrintAndLogEx(NORMAL, "Read flash memory on device"); PrintAndLogEx(NORMAL, "Read flash memory on device");
PrintAndLogEx(NORMAL, "Usage: mem read o <offset> l <len>"); PrintAndLogEx(NORMAL, "Usage: mem read o <offset> l <len>");
PrintAndLogEx(NORMAL, " o <offset> : offset in memory"); PrintAndLogEx(NORMAL, " o <offset> : offset in memory");
@ -51,7 +53,8 @@ int usage_flashmem_read(void){
PrintAndLogEx(NORMAL, " mem read o 1024 l 10"); // read 10 bytes starting at offset 1024 PrintAndLogEx(NORMAL, " mem read o 1024 l 10"); // read 10 bytes starting at offset 1024
return 0; return 0;
} }
int usage_flashmem_load(void){ int usage_flashmem_load(void)
{
PrintAndLogEx(NORMAL, "Loads binary file into flash memory on device"); PrintAndLogEx(NORMAL, "Loads binary file into flash memory on device");
PrintAndLogEx(NORMAL, "Usage: mem load o <offset> f <file name> m t i"); PrintAndLogEx(NORMAL, "Usage: mem load o <offset> f <file name> m t i");
PrintAndLogEx(NORMAL, " o <offset> : offset in memory"); PrintAndLogEx(NORMAL, " o <offset> : offset in memory");
@ -68,7 +71,8 @@ int usage_flashmem_load(void){
PrintAndLogEx(NORMAL, " mem load f default_iclass_keys i"); PrintAndLogEx(NORMAL, " mem load f default_iclass_keys i");
return 0; return 0;
} }
int usage_flashmem_save(void){ int usage_flashmem_save(void)
{
PrintAndLogEx(NORMAL, "Saves flash memory on device into the file"); PrintAndLogEx(NORMAL, "Saves flash memory on device into the file");
PrintAndLogEx(NORMAL, " Usage: mem save o <offset> l <length> f <file name>"); PrintAndLogEx(NORMAL, " Usage: mem save o <offset> l <length> f <file name>");
PrintAndLogEx(NORMAL, " o <offset> : offset in memory"); PrintAndLogEx(NORMAL, " o <offset> : offset in memory");
@ -81,7 +85,8 @@ int usage_flashmem_save(void){
PrintAndLogEx(NORMAL, " mem save f myfile o 1024 l 4096"); // downlowd 4096 bytes from offset 1024 to file myfile PrintAndLogEx(NORMAL, " mem save f myfile o 1024 l 4096"); // downlowd 4096 bytes from offset 1024 to file myfile
return 0; return 0;
} }
int usage_flashmem_wipe(void){ int usage_flashmem_wipe(void)
{
PrintAndLogEx(WARNING, "[OBS] use with caution."); PrintAndLogEx(WARNING, "[OBS] use with caution.");
PrintAndLogEx(NORMAL, "Wipe flash memory on device, which fills memory with 0xFF\n"); PrintAndLogEx(NORMAL, "Wipe flash memory on device, which fills memory with 0xFF\n");
@ -95,7 +100,8 @@ int usage_flashmem_wipe(void){
PrintAndLogEx(NORMAL, " mem wipe p 0"); // wipes first page. PrintAndLogEx(NORMAL, " mem wipe p 0"); // wipes first page.
return 0; return 0;
} }
int usage_flashmem_info(void){ int usage_flashmem_info(void)
{
PrintAndLogEx(NORMAL, "Collect signature and verify it from flash memory\n"); PrintAndLogEx(NORMAL, "Collect signature and verify it from flash memory\n");
PrintAndLogEx(NORMAL, " Usage: mem info [h|s|w]"); PrintAndLogEx(NORMAL, " Usage: mem info [h|s|w]");
PrintAndLogEx(NORMAL, " s : create a signature"); PrintAndLogEx(NORMAL, " s : create a signature");
@ -107,7 +113,8 @@ int usage_flashmem_info(void){
return 0; return 0;
} }
int CmdFlashMemRead(const char *Cmd) { int CmdFlashMemRead(const char *Cmd)
{
uint8_t cmdp = 0; uint8_t cmdp = 0;
bool errors = false; bool errors = false;
@ -146,7 +153,8 @@ int CmdFlashMemRead(const char *Cmd) {
return 0; return 0;
} }
int CmdFlashmemSpiBaudrate(const char *Cmd) { int CmdFlashmemSpiBaudrate(const char *Cmd)
{
char ctmp = tolower(param_getchar(Cmd, 0)); char ctmp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || ctmp == 'h') return usage_flashmem_spibaud(); if (strlen(Cmd) < 1 || ctmp == 'h') return usage_flashmem_spibaud();
@ -158,7 +166,8 @@ int CmdFlashmemSpiBaudrate(const char *Cmd) {
return 0; return 0;
} }
int CmdFlashMemLoad(const char *Cmd){ int CmdFlashMemLoad(const char *Cmd)
{
uint32_t start_index = 0; uint32_t start_index = 0;
char filename[FILE_PATH_SIZE] = {0}; char filename[FILE_PATH_SIZE] = {0};
@ -295,7 +304,8 @@ int CmdFlashMemLoad(const char *Cmd){
PrintAndLogEx(SUCCESS, "Wrote %u bytes to offset %u", datalen, start_index); PrintAndLogEx(SUCCESS, "Wrote %u bytes to offset %u", datalen, start_index);
return 0; return 0;
} }
int CmdFlashMemSave(const char *Cmd){ int CmdFlashMemSave(const char *Cmd)
{
char filename[FILE_PATH_SIZE] = {0}; char filename[FILE_PATH_SIZE] = {0};
uint8_t cmdp = 0; uint8_t cmdp = 0;
@ -304,7 +314,8 @@ int CmdFlashMemSave(const char *Cmd){
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) { switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h': return usage_flashmem_save(); case 'h':
return usage_flashmem_save();
case 'l': case 'l':
len = param_get32ex(Cmd, cmdp + 1, FLASH_MEM_MAX_SIZE, 10); len = param_get32ex(Cmd, cmdp + 1, FLASH_MEM_MAX_SIZE, 10);
cmdp += 2; cmdp += 2;
@ -350,7 +361,8 @@ int CmdFlashMemSave(const char *Cmd){
free(dump); free(dump);
return 0; return 0;
} }
int CmdFlashMemWipe(const char *Cmd){ int CmdFlashMemWipe(const char *Cmd)
{
uint8_t cmdp = 0; uint8_t cmdp = 0;
bool errors = false; bool errors = false;
@ -358,7 +370,8 @@ int CmdFlashMemWipe(const char *Cmd){
uint8_t page = 0; uint8_t page = 0;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) { switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h': return usage_flashmem_wipe(); case 'h':
return usage_flashmem_wipe();
case 'p': case 'p':
page = param_get8ex(Cmd, cmdp + 1, 0, 10); page = param_get8ex(Cmd, cmdp + 1, 0, 10);
if (page > 2) { if (page > 2) {
@ -398,7 +411,8 @@ int CmdFlashMemWipe(const char *Cmd){
return 0; return 0;
} }
int CmdFlashMemInfo(const char *Cmd){ int CmdFlashMemInfo(const char *Cmd)
{
uint8_t sha_hash[20] = {0}; uint8_t sha_hash[20] = {0};
mbedtls_rsa_context rsa; mbedtls_rsa_context rsa;
@ -407,7 +421,8 @@ int CmdFlashMemInfo(const char *Cmd){
bool errors = false, shall_write = false, shall_sign = false; bool errors = false, shall_write = false, shall_sign = false;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) { switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h': return usage_flashmem_info(); case 'h':
return usage_flashmem_info();
case 's': { case 's': {
shall_sign = true; shall_sign = true;
cmdp++; cmdp++;
@ -597,13 +612,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdFlashMem(const char *Cmd) { int CmdFlashMem(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -12,7 +12,8 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_hf_search(){ int usage_hf_search()
{
PrintAndLogEx(NORMAL, "Usage: hf search"); PrintAndLogEx(NORMAL, "Usage: hf search");
PrintAndLogEx(NORMAL, "Will try to find a HF read out of the unknown tag. Stops when found."); PrintAndLogEx(NORMAL, "Will try to find a HF read out of the unknown tag. Stops when found.");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -20,7 +21,8 @@ int usage_hf_search(){
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
return 0; return 0;
} }
int usage_hf_snoop(){ int usage_hf_snoop()
{
PrintAndLogEx(NORMAL, "Usage: hf snoop <skip pairs> <skip triggers>"); PrintAndLogEx(NORMAL, "Usage: hf snoop <skip pairs> <skip triggers>");
PrintAndLogEx(NORMAL, "The high frequence snoop will assign all available memory on device for snooped data"); PrintAndLogEx(NORMAL, "The high frequence snoop will assign all available memory on device for snooped data");
PrintAndLogEx(NORMAL, "User the 'data samples' command to download from device, and 'data plot' to look at it"); PrintAndLogEx(NORMAL, "User the 'data samples' command to download from device, and 'data plot' to look at it");
@ -36,7 +38,8 @@ int usage_hf_snoop(){
return 0; return 0;
} }
int CmdHFSearch(const char *Cmd){ int CmdHFSearch(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_search(); if (cmdp == 'h') return usage_hf_search();
@ -85,7 +88,8 @@ int CmdHFSearch(const char *Cmd){
return 0; return 0;
} }
int CmdHFTune(const char *Cmd) { int CmdHFTune(const char *Cmd)
{
PrintAndLogEx(SUCCESS, "Measuring HF antenna, press button to exit"); PrintAndLogEx(SUCCESS, "Measuring HF antenna, press button to exit");
UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING_HF}; UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING_HF};
clearCommandBuffer(); clearCommandBuffer();
@ -93,7 +97,8 @@ int CmdHFTune(const char *Cmd) {
return 0; return 0;
} }
int CmdHFSnoop(const char *Cmd) { int CmdHFSnoop(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_snoop(); if (cmdp == 'h') return usage_hf_snoop();
@ -128,13 +133,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdHF(const char *Cmd) { int CmdHF(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -136,7 +136,8 @@ static const manufactureName manufactureMapping[] = {
// get a product description based on the UID // get a product description based on the UID
// uid[8] tag uid // uid[8] tag uid
// returns description of the best match // returns description of the best match
char* getTagInfo(uint8_t uid) { char *getTagInfo(uint8_t uid)
{
int i; int i;
int len = sizeof(manufactureMapping) / sizeof(manufactureName); int len = sizeof(manufactureMapping) / sizeof(manufactureName);
@ -153,7 +154,8 @@ char* getTagInfo(uint8_t uid) {
static uint16_t frameLength = 0; static uint16_t frameLength = 0;
uint16_t atsFSC[] = {16, 24, 32, 40, 48, 64, 96, 128, 256}; uint16_t atsFSC[] = {16, 24, 32, 40, 48, 64, 96, 128, 256};
int usage_hf_14a_sim(void) { int usage_hf_14a_sim(void)
{
// PrintAndLogEx(NORMAL, "\n Emulating ISO/IEC 14443 type A tag with 4,7 or 10 byte UID\n"); // PrintAndLogEx(NORMAL, "\n Emulating ISO/IEC 14443 type A tag with 4,7 or 10 byte UID\n");
PrintAndLogEx(NORMAL, "\n Emulating ISO/IEC 14443 type A tag with 4,7 byte UID\n"); PrintAndLogEx(NORMAL, "\n Emulating ISO/IEC 14443 type A tag with 4,7 byte UID\n");
PrintAndLogEx(NORMAL, "Usage: hf 14a sim [h] t <type> u <uid> [x] [e] [v]"); PrintAndLogEx(NORMAL, "Usage: hf 14a sim [h] t <type> u <uid> [x] [e] [v]");
@ -180,7 +182,8 @@ int usage_hf_14a_sim(void) {
// PrintAndLogEx(NORMAL, " hf 14a sim t 1 u 11223445566778899AA\n"); // PrintAndLogEx(NORMAL, " hf 14a sim t 1 u 11223445566778899AA\n");
return 0; return 0;
} }
int usage_hf_14a_sniff(void) { int usage_hf_14a_sniff(void)
{
PrintAndLogEx(NORMAL, "It get data from the field and saves it into command buffer."); PrintAndLogEx(NORMAL, "It get data from the field and saves it into command buffer.");
PrintAndLogEx(NORMAL, "Buffer accessible from command 'hf list 14a'"); PrintAndLogEx(NORMAL, "Buffer accessible from command 'hf list 14a'");
PrintAndLogEx(NORMAL, "Usage: hf 14a sniff [c][r]"); PrintAndLogEx(NORMAL, "Usage: hf 14a sniff [c][r]");
@ -190,7 +193,8 @@ int usage_hf_14a_sniff(void) {
PrintAndLogEx(NORMAL, " hf 14a sniff c r"); PrintAndLogEx(NORMAL, " hf 14a sniff c r");
return 0; return 0;
} }
int usage_hf_14a_raw(void) { int usage_hf_14a_raw(void)
{
PrintAndLogEx(NORMAL, "Usage: hf 14a raw [-h] [-r] [-c] [-p] [-a] [-T] [-t] <milliseconds> [-b] <number of bits> <0A 0B 0C ... hex>"); PrintAndLogEx(NORMAL, "Usage: hf 14a raw [-h] [-r] [-c] [-p] [-a] [-T] [-t] <milliseconds> [-b] <number of bits> <0A 0B 0C ... hex>");
PrintAndLogEx(NORMAL, " -h this help"); PrintAndLogEx(NORMAL, " -h this help");
PrintAndLogEx(NORMAL, " -r do not read response"); PrintAndLogEx(NORMAL, " -r do not read response");
@ -204,7 +208,8 @@ int usage_hf_14a_raw(void) {
PrintAndLogEx(NORMAL, " -3 ISO14443-3 select only (skip RATS)"); PrintAndLogEx(NORMAL, " -3 ISO14443-3 select only (skip RATS)");
return 0; return 0;
} }
int usage_hf_14a_reader(void) { int usage_hf_14a_reader(void)
{
PrintAndLogEx(NORMAL, "Usage: hf 14a reader [k|s|x] [3]"); PrintAndLogEx(NORMAL, "Usage: hf 14a reader [k|s|x] [3]");
PrintAndLogEx(NORMAL, " k keep the field active after command executed"); PrintAndLogEx(NORMAL, " k keep the field active after command executed");
PrintAndLogEx(NORMAL, " s silent (no messages)"); PrintAndLogEx(NORMAL, " s silent (no messages)");
@ -212,7 +217,8 @@ int usage_hf_14a_reader(void) {
PrintAndLogEx(NORMAL, " 3 ISO14443-3 select only (skip RATS)"); PrintAndLogEx(NORMAL, " 3 ISO14443-3 select only (skip RATS)");
return 0; return 0;
} }
int usage_hf_14a_info(void){ int usage_hf_14a_info(void)
{
PrintAndLogEx(NORMAL, "This command makes more extensive tests against a ISO14443a tag in order to collect information"); PrintAndLogEx(NORMAL, "This command makes more extensive tests against a ISO14443a tag in order to collect information");
PrintAndLogEx(NORMAL, "Usage: hf 14a info [h|s]"); PrintAndLogEx(NORMAL, "Usage: hf 14a info [h|s]");
PrintAndLogEx(NORMAL, " s silent (no messages)"); PrintAndLogEx(NORMAL, " s silent (no messages)");
@ -220,13 +226,15 @@ int usage_hf_14a_info(void){
return 0; return 0;
} }
int CmdHF14AList(const char *Cmd) { int CmdHF14AList(const char *Cmd)
{
//PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list 14a' instead"); //PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list 14a' instead");
CmdTraceList("14a"); CmdTraceList("14a");
return 0; return 0;
} }
int Hf14443_4aGetCardData(iso14a_card_select_t * card) { int Hf14443_4aGetCardData(iso14a_card_select_t *card)
{
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}}; UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}};
SendCommand(&c); SendCommand(&c);
@ -265,7 +273,8 @@ int Hf14443_4aGetCardData(iso14a_card_select_t * card) {
return 0; return 0;
} }
int CmdHF14AReader(const char *Cmd) { int CmdHF14AReader(const char *Cmd)
{
uint32_t cm = ISO14A_CONNECT; uint32_t cm = ISO14A_CONNECT;
bool disconnectAfter = true, silent = false; bool disconnectAfter = true, silent = false;
@ -353,7 +362,8 @@ int CmdHF14AReader(const char *Cmd) {
return 0; return 0;
} }
int CmdHF14AInfo(const char *Cmd) { int CmdHF14AInfo(const char *Cmd)
{
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_hf_14a_info(); if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_hf_14a_info();
@ -430,21 +440,53 @@ int CmdHF14AInfo(const char *Cmd) {
return 0; return 0;
} }
break; break;
case 0x01: PrintAndLogEx(NORMAL, "TYPE : NXP TNP3xxx Activision Game Appliance"); break; case 0x01:
case 0x04: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE (various !DESFire !DESFire EV1)"); isMifareClassic = false; break; PrintAndLogEx(NORMAL, "TYPE : NXP TNP3xxx Activision Game Appliance");
case 0x08: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1 | 1k Ev1"); break; break;
case 0x09: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Mini 0.3k"); break; case 0x04:
case 0x0A: PrintAndLogEx(NORMAL, "TYPE : FM11RF005SH (Shanghai Metro)"); break; PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE (various !DESFire !DESFire EV1)");
case 0x10: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Plus 2k SL2"); break; isMifareClassic = false;
case 0x11: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Plus 4k SL2"); break; break;
case 0x18: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Classic 4k | Plus 4k SL1 | 4k Ev1"); break; case 0x08:
case 0x20: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k SL3 | JCOP 31/41"); isMifareClassic = false; break; PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1 | 1k Ev1");
case 0x24: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE DESFire | DESFire EV1"); isMifareClassic = false; break; break;
case 0x28: PrintAndLogEx(NORMAL, "TYPE : JCOP31 or JCOP41 v2.3.1"); break; case 0x09:
case 0x38: PrintAndLogEx(NORMAL, "TYPE : Nokia 6212 or 6131 MIFARE CLASSIC 4K"); break; PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Mini 0.3k");
case 0x88: PrintAndLogEx(NORMAL, "TYPE : Infineon MIFARE CLASSIC 1K"); break; break;
case 0x98: PrintAndLogEx(NORMAL, "TYPE : Gemplus MPCOS"); break; case 0x0A:
default: ; PrintAndLogEx(NORMAL, "TYPE : FM11RF005SH (Shanghai Metro)");
break;
case 0x10:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Plus 2k SL2");
break;
case 0x11:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Plus 4k SL2");
break;
case 0x18:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Classic 4k | Plus 4k SL1 | 4k Ev1");
break;
case 0x20:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE DESFire 4k | DESFire EV1 2k/4k/8k | Plus 2k/4k SL3 | JCOP 31/41");
isMifareClassic = false;
break;
case 0x24:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE DESFire | DESFire EV1");
isMifareClassic = false;
break;
case 0x28:
PrintAndLogEx(NORMAL, "TYPE : JCOP31 or JCOP41 v2.3.1");
break;
case 0x38:
PrintAndLogEx(NORMAL, "TYPE : Nokia 6212 or 6131 MIFARE CLASSIC 4K");
break;
case 0x88:
PrintAndLogEx(NORMAL, "TYPE : Infineon MIFARE CLASSIC 1K");
break;
case 0x98:
PrintAndLogEx(NORMAL, "TYPE : Gemplus MPCOS");
break;
default:
;
} }
// Double & triple sized UID, can be mapped to a manufacturer. // Double & triple sized UID, can be mapped to a manufacturer.
@ -544,29 +586,59 @@ int CmdHF14AInfo(const char *Cmd) {
PrintAndLogEx(NORMAL, " c1 -> Mifare or (multiple) virtual cards of various type"); PrintAndLogEx(NORMAL, " c1 -> Mifare or (multiple) virtual cards of various type");
PrintAndLogEx(NORMAL, " %02x -> Length is %d bytes", card.ats[pos + 1], card.ats[pos + 1]); PrintAndLogEx(NORMAL, " %02x -> Length is %d bytes", card.ats[pos + 1], card.ats[pos + 1]);
switch (card.ats[pos + 2] & 0xf0) { switch (card.ats[pos + 2] & 0xf0) {
case 0x10: PrintAndLogEx(NORMAL, " 1x -> MIFARE DESFire"); break; case 0x10:
case 0x20: PrintAndLogEx(NORMAL, " 2x -> MIFARE Plus"); break; PrintAndLogEx(NORMAL, " 1x -> MIFARE DESFire");
break;
case 0x20:
PrintAndLogEx(NORMAL, " 2x -> MIFARE Plus");
break;
} }
switch (card.ats[pos + 2] & 0x0f) { switch (card.ats[pos + 2] & 0x0f) {
case 0x00: PrintAndLogEx(NORMAL, " x0 -> <1 kByte"); break; case 0x00:
case 0x01: PrintAndLogEx(NORMAL, " x1 -> 1 kByte"); break; PrintAndLogEx(NORMAL, " x0 -> <1 kByte");
case 0x02: PrintAndLogEx(NORMAL, " x2 -> 2 kByte"); break; break;
case 0x03: PrintAndLogEx(NORMAL, " x3 -> 4 kByte"); break; case 0x01:
case 0x04: PrintAndLogEx(NORMAL, " x4 -> 8 kByte"); break; PrintAndLogEx(NORMAL, " x1 -> 1 kByte");
break;
case 0x02:
PrintAndLogEx(NORMAL, " x2 -> 2 kByte");
break;
case 0x03:
PrintAndLogEx(NORMAL, " x3 -> 4 kByte");
break;
case 0x04:
PrintAndLogEx(NORMAL, " x4 -> 8 kByte");
break;
} }
switch (card.ats[pos + 3] & 0xf0) { switch (card.ats[pos + 3] & 0xf0) {
case 0x00: PrintAndLogEx(NORMAL, " 0x -> Engineering sample"); break; case 0x00:
case 0x20: PrintAndLogEx(NORMAL, " 2x -> Released"); break; PrintAndLogEx(NORMAL, " 0x -> Engineering sample");
break;
case 0x20:
PrintAndLogEx(NORMAL, " 2x -> Released");
break;
} }
switch (card.ats[pos + 3] & 0x0f) { switch (card.ats[pos + 3] & 0x0f) {
case 0x00: PrintAndLogEx(NORMAL, " x0 -> Generation 1"); break; case 0x00:
case 0x01: PrintAndLogEx(NORMAL, " x1 -> Generation 2"); break; PrintAndLogEx(NORMAL, " x0 -> Generation 1");
case 0x02: PrintAndLogEx(NORMAL, " x2 -> Generation 3"); break; break;
case 0x01:
PrintAndLogEx(NORMAL, " x1 -> Generation 2");
break;
case 0x02:
PrintAndLogEx(NORMAL, " x2 -> Generation 3");
break;
} }
switch (card.ats[pos + 4] & 0x0f) { switch (card.ats[pos + 4] & 0x0f) {
case 0x00: PrintAndLogEx(NORMAL, " x0 -> Only VCSL supported"); break; case 0x00:
case 0x01: PrintAndLogEx(NORMAL, " x1 -> VCS, VCSL, and SVC supported"); break; PrintAndLogEx(NORMAL, " x0 -> Only VCSL supported");
case 0x0E: PrintAndLogEx(NORMAL, " xE -> no VCS command supported"); break; break;
case 0x01:
PrintAndLogEx(NORMAL, " x1 -> VCS, VCSL, and SVC supported");
break;
case 0x0E:
PrintAndLogEx(NORMAL, " xE -> no VCS command supported");
break;
} }
} }
} }
@ -593,7 +665,8 @@ int CmdHF14AInfo(const char *Cmd) {
} }
// Collect ISO14443 Type A UIDs // Collect ISO14443 Type A UIDs
int CmdHF14ACUIDs(const char *Cmd) { int CmdHF14ACUIDs(const char *Cmd)
{
// requested number of UIDs // requested number of UIDs
int n = atoi(Cmd); int n = atoi(Cmd);
// collect at least 1 (e.g. if no parameter was given) // collect at least 1 (e.g. if no parameter was given)
@ -606,7 +679,8 @@ int CmdHF14ACUIDs(const char *Cmd) {
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
if (ukbhit()) { if (ukbhit()) {
int gc = getchar(); (void)gc; int gc = getchar();
(void)gc;
PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n"); PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n");
break; break;
} }
@ -636,7 +710,8 @@ int CmdHF14ACUIDs(const char *Cmd) {
} }
// ## simulate iso14443a tag // ## simulate iso14443a tag
int CmdHF14ASim(const char *Cmd) { int CmdHF14ASim(const char *Cmd)
{
bool errors = false; bool errors = false;
uint8_t flags = 0; uint8_t flags = 0;
uint8_t tagtype = 1; uint8_t tagtype = 1;
@ -667,9 +742,15 @@ int CmdHF14ASim(const char *Cmd) {
param_gethex_ex(Cmd, cmdp + 1, uid, &uidlen); param_gethex_ex(Cmd, cmdp + 1, uid, &uidlen);
switch (uidlen) { switch (uidlen) {
//case 20: flags |= FLAG_10B_UID_IN_DATA; break; //case 20: flags |= FLAG_10B_UID_IN_DATA; break;
case 14: flags |= FLAG_7B_UID_IN_DATA; break; case 14:
case 8: flags |= FLAG_4B_UID_IN_DATA; break; flags |= FLAG_7B_UID_IN_DATA;
default: errors = true; break; break;
case 8:
flags |= FLAG_4B_UID_IN_DATA;
break;
default:
errors = true;
break;
} }
if (!errors) { if (!errors) {
PrintAndLogEx(SUCCESS, "Emulating ISO/IEC 14443 type A tag with %d byte UID (%s)", uidlen >> 1, sprint_hex(uid, uidlen >> 1)); PrintAndLogEx(SUCCESS, "Emulating ISO/IEC 14443 type A tag with %d byte UID (%s)", uidlen >> 1, sprint_hex(uid, uidlen >> 1));
@ -725,7 +806,8 @@ int CmdHF14ASim(const char *Cmd) {
return 0; return 0;
} }
int CmdHF14ASniff(const char *Cmd) { int CmdHF14ASniff(const char *Cmd)
{
int param = 0; int param = 0;
uint8_t ctmp; uint8_t ctmp;
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
@ -740,7 +822,8 @@ int CmdHF14ASniff(const char *Cmd) {
return 0; return 0;
} }
int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen)
{
static bool responseNum = false; static bool responseNum = false;
uint16_t cmdc = 0; uint16_t cmdc = 0;
*dataoutlen = 0; *dataoutlen = 0;
@ -839,7 +922,8 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav
return 0; return 0;
} }
int SelectCard14443_4(bool disconnect, iso14a_card_select_t *card) { int SelectCard14443_4(bool disconnect, iso14a_card_select_t *card)
{
UsbCommand resp; UsbCommand resp;
frameLength = 0; frameLength = 0;
@ -909,7 +993,8 @@ int SelectCard14443_4(bool disconnect, iso14a_card_select_t *card) {
return 0; return 0;
} }
int CmdExchangeAPDU(bool chainingin, uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chainingout) { int CmdExchangeAPDU(bool chainingin, uint8_t *datain, int datainlen, bool activateField, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool *chainingout)
{
*chainingout = false; *chainingout = false;
if (activateField) { if (activateField) {
@ -993,7 +1078,8 @@ int CmdExchangeAPDU(bool chainingin, uint8_t *datain, int datainlen, bool activa
return 0; return 0;
} }
int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen) { int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen)
{
*dataoutlen = 0; *dataoutlen = 0;
bool chaining = false; bool chaining = false;
int res; int res;
@ -1063,7 +1149,8 @@ int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool lea
} }
// ISO14443-4. 7. Half-duplex block transmission protocol // ISO14443-4. 7. Half-duplex block transmission protocol
int CmdHF14AAPDU(const char *cmd) { int CmdHF14AAPDU(const char *cmd)
{
uint8_t data[USB_CMD_DATA_SIZE]; uint8_t data[USB_CMD_DATA_SIZE];
int datalen = 0; int datalen = 0;
bool activateField = false; bool activateField = false;
@ -1110,7 +1197,8 @@ CLIParserFree();
return 0; return 0;
} }
int CmdHF14ACmdRaw(const char *cmd) { int CmdHF14ACmdRaw(const char *cmd)
{
UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}}; UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}};
bool reply = 1; bool reply = 1;
bool crc = false; bool crc = false;
@ -1266,7 +1354,8 @@ int CmdHF14ACmdRaw(const char *cmd) {
return 0; return 0;
} }
static int waitCmd(uint8_t iSelect) { static int waitCmd(uint8_t iSelect)
{
UsbCommand resp; UsbCommand resp;
uint16_t len = 0; uint16_t len = 0;
@ -1294,7 +1383,8 @@ static int waitCmd(uint8_t iSelect) {
return 0; return 0;
} }
int CmdHF14AAntiFuzz(const char *cmd) { int CmdHF14AAntiFuzz(const char *cmd)
{
CLIParserInit("hf 14a antifuzz", CLIParserInit("hf 14a antifuzz",
"Tries to fuzz the ISO14443a anticollision phase", "Tries to fuzz the ISO14443a anticollision phase",
@ -1323,7 +1413,8 @@ int CmdHF14AAntiFuzz(const char *cmd) {
return 0; return 0;
} }
int CmdHF14AChaining(const char *cmd) { int CmdHF14AChaining(const char *cmd)
{
CLIParserInit("hf 14a chaining", CLIParserInit("hf 14a chaining",
"Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.", "Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.",
@ -1369,13 +1460,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdHF14A(const char *Cmd) { int CmdHF14A(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -14,7 +14,8 @@
#define TIMEOUT 2000 #define TIMEOUT 2000
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_hf_14b_info(void){ int usage_hf_14b_info(void)
{
PrintAndLogEx(NORMAL, "Usage: hf 14b info [h] [s]"); PrintAndLogEx(NORMAL, "Usage: hf 14b info [h] [s]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " h this help");
@ -23,7 +24,8 @@ int usage_hf_14b_info(void){
PrintAndLogEx(NORMAL, " hf 14b info"); PrintAndLogEx(NORMAL, " hf 14b info");
return 0; return 0;
} }
int usage_hf_14b_reader(void){ int usage_hf_14b_reader(void)
{
PrintAndLogEx(NORMAL, "Usage: hf 14b reader [h] [s]"); PrintAndLogEx(NORMAL, "Usage: hf 14b reader [h] [s]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " h this help");
@ -32,7 +34,8 @@ int usage_hf_14b_reader(void){
PrintAndLogEx(NORMAL, " hf 14b reader"); PrintAndLogEx(NORMAL, " hf 14b reader");
return 0; return 0;
} }
int usage_hf_14b_raw(void){ int usage_hf_14b_raw(void)
{
PrintAndLogEx(NORMAL, "Usage: hf 14b raw [-h] [-r] [-c] [-p] [-s || -ss] <0A 0B 0C ... hex>"); PrintAndLogEx(NORMAL, "Usage: hf 14b raw [-h] [-r] [-c] [-p] [-s || -ss] <0A 0B 0C ... hex>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " -h this help"); PrintAndLogEx(NORMAL, " -h this help");
@ -45,7 +48,8 @@ int usage_hf_14b_raw(void){
PrintAndLogEx(NORMAL, " hf 14b raw -s -c -p 0200a40400"); PrintAndLogEx(NORMAL, " hf 14b raw -s -c -p 0200a40400");
return 0; return 0;
} }
int usage_hf_14b_sniff(void){ int usage_hf_14b_sniff(void)
{
PrintAndLogEx(NORMAL, "It get data from the field and saves it into command buffer."); PrintAndLogEx(NORMAL, "It get data from the field and saves it into command buffer.");
PrintAndLogEx(NORMAL, "Buffer accessible from command 'hf list 14b'"); PrintAndLogEx(NORMAL, "Buffer accessible from command 'hf list 14b'");
PrintAndLogEx(NORMAL, "Usage: hf 14b sniff [h]"); PrintAndLogEx(NORMAL, "Usage: hf 14b sniff [h]");
@ -55,7 +59,8 @@ int usage_hf_14b_sniff(void){
PrintAndLogEx(NORMAL, " hf 14b sniff"); PrintAndLogEx(NORMAL, " hf 14b sniff");
return 0; return 0;
} }
int usage_hf_14b_sim(void){ int usage_hf_14b_sim(void)
{
PrintAndLogEx(NORMAL, "Emulating ISO/IEC 14443 type B tag with 4 UID / PUPI"); PrintAndLogEx(NORMAL, "Emulating ISO/IEC 14443 type B tag with 4 UID / PUPI");
PrintAndLogEx(NORMAL, "Usage: hf 14b sim [h] u <uid>"); PrintAndLogEx(NORMAL, "Usage: hf 14b sim [h] u <uid>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -66,7 +71,8 @@ int usage_hf_14b_sim(void){
PrintAndLogEx(NORMAL, " hf 14b sim u 11223344"); PrintAndLogEx(NORMAL, " hf 14b sim u 11223344");
return 0; return 0;
} }
int usage_hf_14b_read_srx(void){ int usage_hf_14b_read_srx(void)
{
PrintAndLogEx(NORMAL, "Usage: hf 14b sriread [h] <1|2>"); PrintAndLogEx(NORMAL, "Usage: hf 14b sriread [h] <1|2>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " h this help");
@ -76,7 +82,8 @@ int usage_hf_14b_read_srx(void){
PrintAndLogEx(NORMAL, " hf 14b sriread 2"); PrintAndLogEx(NORMAL, " hf 14b sriread 2");
return 0; return 0;
} }
int usage_hf_14b_write_srx(void){ int usage_hf_14b_write_srx(void)
{
PrintAndLogEx(NORMAL, "Usage: hf 14b [h] sriwrite <1|2> <BLOCK> <DATA>"); PrintAndLogEx(NORMAL, "Usage: hf 14b [h] sriwrite <1|2> <BLOCK> <DATA>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h this help"); PrintAndLogEx(NORMAL, " h this help");
@ -90,7 +97,8 @@ int usage_hf_14b_write_srx(void){
PrintAndLogEx(NORMAL, " hf 14b sriwrite 2 FF 11223344"); PrintAndLogEx(NORMAL, " hf 14b sriwrite 2 FF 11223344");
return 0; return 0;
} }
int usage_hf_14b_dump(void){ int usage_hf_14b_dump(void)
{
PrintAndLogEx(NORMAL, "This command dumps the contents of a ISO-14443-B tag and save it to file\n" PrintAndLogEx(NORMAL, "This command dumps the contents of a ISO-14443-B tag and save it to file\n"
"\n" "\n"
"Usage: hf 14b dump [h] [card memory] <f filname> \n" "Usage: hf 14b dump [h] [card memory] <f filname> \n"
@ -113,19 +121,22 @@ static void switch_on_field_14b(void) {
} }
*/ */
static int switch_off_field_14b(void) { static int switch_off_field_14b(void)
{
UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_DISCONNECT, 0, 0}}; UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_DISCONNECT, 0, 0}};
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
return 0; return 0;
} }
int CmdHF14BList(const char *Cmd) { int CmdHF14BList(const char *Cmd)
{
CmdTraceList("14b"); CmdTraceList("14b");
return 0; return 0;
} }
int CmdHF14BSim(const char *Cmd) { int CmdHF14BSim(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_14b_sim(); if (cmdp == 'h') return usage_hf_14b_sim();
@ -140,7 +151,8 @@ int CmdHF14BSim(const char *Cmd) {
return 0; return 0;
} }
int CmdHF14BSniff(const char *Cmd) { int CmdHF14BSniff(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_14b_sniff(); if (cmdp == 'h') return usage_hf_14b_sniff();
@ -151,7 +163,8 @@ int CmdHF14BSniff(const char *Cmd) {
return 0; return 0;
} }
int CmdHF14BCmdRaw (const char *Cmd) { int CmdHF14BCmdRaw(const char *Cmd)
{
bool reply = true, power = false, select = false; bool reply = true, power = false, select = false;
char buf[5] = ""; char buf[5] = "";
int i = 0; int i = 0;
@ -241,7 +254,8 @@ int CmdHF14BCmdRaw (const char *Cmd) {
return 1; return 1;
} }
static bool get_14b_UID(iso14b_card_select_t *card) { static bool get_14b_UID(iso14b_card_select_t *card)
{
if (!card) if (!card)
return false; return false;
@ -295,7 +309,8 @@ static bool get_14b_UID(iso14b_card_select_t *card) {
// 4 = bit rate capacity // 4 = bit rate capacity
// 5 = max frame size / -4 info // 5 = max frame size / -4 info
// 6 = FWI / Coding options // 6 = FWI / Coding options
static void print_atqb_resp(uint8_t *data, uint8_t cid){ static void print_atqb_resp(uint8_t *data, uint8_t cid)
{
//PrintAndLogEx(NORMAL, " UID: %s", sprint_hex(data+1,4)); //PrintAndLogEx(NORMAL, " UID: %s", sprint_hex(data+1,4));
PrintAndLogEx(NORMAL, " App Data: %s", sprint_hex(data, 4)); PrintAndLogEx(NORMAL, " App Data: %s", sprint_hex(data, 4));
PrintAndLogEx(NORMAL, " Protocol: %s", sprint_hex(data + 4, 3)); PrintAndLogEx(NORMAL, " Protocol: %s", sprint_hex(data + 4, 3));
@ -341,26 +356,44 @@ static void print_atqb_resp(uint8_t *data, uint8_t cid){
} }
// get SRx chip model (from UID) // from ST Microelectronics // get SRx chip model (from UID) // from ST Microelectronics
char *get_ST_Chip_Model(uint8_t data){ char *get_ST_Chip_Model(uint8_t data)
{
static char model[20]; static char model[20];
char *retStr = model; char *retStr = model;
memset(model, 0, sizeof(model)); memset(model, 0, sizeof(model));
switch (data) { switch (data) {
case 0x0: sprintf(retStr, "SRIX4K (Special)"); break; case 0x0:
case 0x2: sprintf(retStr, "SR176"); break; sprintf(retStr, "SRIX4K (Special)");
case 0x3: sprintf(retStr, "SRIX4K"); break; break;
case 0x4: sprintf(retStr, "SRIX512"); break; case 0x2:
case 0x6: sprintf(retStr, "SRI512"); break; sprintf(retStr, "SR176");
case 0x7: sprintf(retStr, "SRI4K"); break; break;
case 0xC: sprintf(retStr, "SRT512"); break; case 0x3:
default : sprintf(retStr, "Unknown"); break; sprintf(retStr, "SRIX4K");
break;
case 0x4:
sprintf(retStr, "SRIX512");
break;
case 0x6:
sprintf(retStr, "SRI512");
break;
case 0x7:
sprintf(retStr, "SRI4K");
break;
case 0xC:
sprintf(retStr, "SRT512");
break;
default :
sprintf(retStr, "Unknown");
break;
} }
return retStr; return retStr;
} }
// REMAKE: // REMAKE:
int print_ST_Lock_info(uint8_t model){ int print_ST_Lock_info(uint8_t model)
{
// PrintAndLogEx(NORMAL, "Chip Write Protection Bits:"); // PrintAndLogEx(NORMAL, "Chip Write Protection Bits:");
// // now interpret the data // // now interpret the data
@ -406,7 +439,8 @@ int print_ST_Lock_info(uint8_t model){
} }
// print UID info from SRx chips (ST Microelectronics) // print UID info from SRx chips (ST Microelectronics)
static void print_st_general_info(uint8_t *data, uint8_t len){ static void print_st_general_info(uint8_t *data, uint8_t len)
{
//uid = first 8 bytes in data //uid = first 8 bytes in data
PrintAndLogEx(NORMAL, " UID: %s", sprint_hex(SwapEndian64(data, 8, 8), len)); PrintAndLogEx(NORMAL, " UID: %s", sprint_hex(SwapEndian64(data, 8, 8), len));
PrintAndLogEx(NORMAL, " MFG: %02X, %s", data[6], getTagInfo(data[6])); PrintAndLogEx(NORMAL, " MFG: %02X, %s", data[6], getTagInfo(data[6]));
@ -433,7 +467,8 @@ static void print_st_general_info(uint8_t *data, uint8_t len){
//a2 = ? (resp 02 [6a d3]) //a2 = ? (resp 02 [6a d3])
// 14b get and print Full Info (as much as we know) // 14b get and print Full Info (as much as we know)
bool HF14B_Std_Info(bool verbose){ bool HF14B_Std_Info(bool verbose)
{
bool isSuccess = false; bool isSuccess = false;
@ -477,7 +512,8 @@ bool HF14B_Std_Info(bool verbose){
} }
// SRx get and print full info (needs more info...) // SRx get and print full info (needs more info...)
bool HF14B_ST_Info(bool verbose){ bool HF14B_ST_Info(bool verbose)
{
UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0}}; UsbCommand c = {CMD_ISO_14443B_COMMAND, {ISO14B_CONNECT | ISO14B_SELECT_SR | ISO14B_DISCONNECT, 0, 0}};
clearCommandBuffer(); clearCommandBuffer();
@ -523,7 +559,8 @@ bool HF14B_ST_Info(bool verbose){
} }
// get and print all info known about any known 14b tag // get and print all info known about any known 14b tag
bool HF14BInfo(bool verbose){ bool HF14BInfo(bool verbose)
{
// try std 14b (atqb) // try std 14b (atqb)
if (HF14B_Std_Info(verbose)) return true; if (HF14B_Std_Info(verbose)) return true;
@ -538,7 +575,8 @@ bool HF14BInfo(bool verbose){
} }
// menu command to get and print all info known about any known 14b tag // menu command to get and print all info known about any known 14b tag
int CmdHF14Binfo(const char *Cmd){ int CmdHF14Binfo(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_14b_info(); if (cmdp == 'h') return usage_hf_14b_info();
@ -546,7 +584,8 @@ int CmdHF14Binfo(const char *Cmd){
return HF14BInfo(verbose); return HF14BInfo(verbose);
} }
bool HF14B_ST_Reader(bool verbose){ bool HF14B_ST_Reader(bool verbose)
{
bool isSuccess = false; bool isSuccess = false;
@ -586,7 +625,8 @@ bool HF14B_ST_Reader(bool verbose){
return isSuccess; return isSuccess;
} }
bool HF14B_Std_Reader(bool verbose){ bool HF14B_Std_Reader(bool verbose)
{
bool isSuccess = false; bool isSuccess = false;
@ -628,7 +668,8 @@ bool HF14B_Std_Reader(bool verbose){
} }
// test for other 14b type tags (mimic another reader - don't have tags to identify) // test for other 14b type tags (mimic another reader - don't have tags to identify)
bool HF14B_Other_Reader(){ bool HF14B_Other_Reader()
{
// uint8_t data[] = {0x00, 0x0b, 0x3f, 0x80}; // uint8_t data[] = {0x00, 0x0b, 0x3f, 0x80};
// uint8_t datalen = 4; // uint8_t datalen = 4;
@ -687,7 +728,8 @@ bool HF14B_Other_Reader(){
} }
// get and print general info about all known 14b chips // get and print general info about all known 14b chips
bool HF14BReader(bool verbose){ bool HF14BReader(bool verbose)
{
// try std 14b (atqb) // try std 14b (atqb)
if (HF14B_Std_Reader(verbose)) return true; if (HF14B_Std_Reader(verbose)) return true;
@ -704,7 +746,8 @@ bool HF14BReader(bool verbose){
} }
// menu command to get and print general info about all known 14b chips // menu command to get and print general info about all known 14b chips
int CmdHF14BReader(const char *Cmd){ int CmdHF14BReader(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_14b_reader(); if (cmdp == 'h') return usage_hf_14b_reader();
@ -716,7 +759,8 @@ int CmdHF14BReader(const char *Cmd){
* SRI* tags are ISO14443-B modulated memory tags, * SRI* tags are ISO14443-B modulated memory tags,
* this command just dumps the contents of the memory/ * this command just dumps the contents of the memory/
*/ */
int CmdHF14BReadSri(const char *Cmd){ int CmdHF14BReadSri(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || cmdp == 'h') return usage_hf_14b_read_srx(); if (strlen(Cmd) < 1 || cmdp == 'h') return usage_hf_14b_read_srx();
@ -729,7 +773,8 @@ int CmdHF14BReadSri(const char *Cmd){
return 0; return 0;
} }
// New command to write a SRI512/SRIX4K tag. // New command to write a SRI512/SRIX4K tag.
int CmdHF14BWriteSri(const char *Cmd){ int CmdHF14BWriteSri(const char *Cmd)
{
/* /*
* For SRIX4K blocks 00 - 7F * For SRIX4K blocks 00 - 7F
* hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata * hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata
@ -796,7 +841,8 @@ int CmdHF14BWriteSri(const char *Cmd){
} }
// need to write to file // need to write to file
int CmdHF14BDump(const char*Cmd) { int CmdHF14BDump(const char *Cmd)
{
uint8_t fileNameLen = 0; uint8_t fileNameLen = 0;
char filename[FILE_PATH_SIZE] = {0}; char filename[FILE_PATH_SIZE] = {0};
@ -918,7 +964,8 @@ int CmdHF14BDump(const char*Cmd) {
blocknum = 0xFF; blocknum = 0xFF;
} }
printf("."); fflush(stdout); printf(".");
fflush(stdout);
} }
} }
@ -951,7 +998,8 @@ out:
return switch_off_field_14b(); return switch_off_field_14b();
} }
uint32_t srix4kEncode(uint32_t value) { uint32_t srix4kEncode(uint32_t value)
{
/* /*
// vv = value // vv = value
// pp = position // pp = position
@ -1007,21 +1055,27 @@ uint32_t srix4kEncode(uint32_t value) {
PrintAndLogEx(NORMAL, "ICE encoded | %08X -> %08X", value, encvalue); PrintAndLogEx(NORMAL, "ICE encoded | %08X -> %08X", value, encvalue);
return encvalue; return encvalue;
} }
uint32_t srix4kDecode(uint32_t value) { uint32_t srix4kDecode(uint32_t value)
{
switch (value) { switch (value) {
case 0xC04F42C5: return 0x003139; case 0xC04F42C5:
case 0xC1484807: return 0x002943; return 0x003139;
case 0xC0C60848: return 0x001A20; case 0xC1484807:
return 0x002943;
case 0xC0C60848:
return 0x001A20;
} }
return 0; return 0;
} }
uint32_t srix4kDecodeCounter(uint32_t num) { uint32_t srix4kDecodeCounter(uint32_t num)
{
uint32_t value = ~num; uint32_t value = ~num;
++value; ++value;
return value; return value;
} }
uint32_t srix4kGetMagicbytes( uint64_t uid, uint32_t block6, uint32_t block18, uint32_t block19 ){ uint32_t srix4kGetMagicbytes(uint64_t uid, uint32_t block6, uint32_t block18, uint32_t block19)
{
#define MASK 0xFFFFFFFF; #define MASK 0xFFFFFFFF;
uint32_t uid32 = uid & MASK; uint32_t uid32 = uid & MASK;
uint32_t counter = srix4kDecodeCounter(block6); uint32_t counter = srix4kDecodeCounter(block6);
@ -1033,7 +1087,8 @@ uint32_t srix4kGetMagicbytes( uint64_t uid, uint32_t block6, uint32_t block18, u
PrintAndLogEx(SUCCESS, "Magic bytes | %08X", result); PrintAndLogEx(SUCCESS, "Magic bytes | %08X", result);
return result; return result;
} }
int srix4kValid(const char *Cmd){ int srix4kValid(const char *Cmd)
{
uint64_t uid = 0xD00202501A4532F9; uint64_t uid = 0xD00202501A4532F9;
uint32_t block6 = 0xFFFFFFFF; uint32_t block6 = 0xFFFFFFFF;
@ -1051,7 +1106,8 @@ int srix4kValid(const char *Cmd){
return 0; return 0;
} }
bool waitCmd14b(bool verbose) { bool waitCmd14b(bool verbose)
{
bool crc = false; bool crc = false;
uint8_t data[USB_CMD_DATA_SIZE] = {0x00}; uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
@ -1105,13 +1161,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdHF14B(const char *Cmd) { int CmdHF14B(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -189,7 +189,8 @@ const productName uidmapping[] = {
// fast method to just read the UID of a tag (collission detection not supported) // fast method to just read the UID of a tag (collission detection not supported)
// *buf should be large enough to fit the 64bit uid // *buf should be large enough to fit the 64bit uid
// returns 1 if suceeded // returns 1 if suceeded
int getUID(uint8_t *buf) { int getUID(uint8_t *buf)
{
UsbCommand resp; UsbCommand resp;
UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv? UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv?
@ -228,7 +229,8 @@ int getUID(uint8_t *buf) {
// get a product description based on the UID // get a product description based on the UID
// uid[8] tag uid // uid[8] tag uid
// returns description of the best match // returns description of the best match
static char* getTagInfo_15(uint8_t *uid) { static char *getTagInfo_15(uint8_t *uid)
{
uint64_t myuid, mask; uint64_t myuid, mask;
int i = 0, best = -1; int i = 0, best = -1;
memcpy(&myuid, uid, sizeof(uint64_t)); memcpy(&myuid, uid, sizeof(uint64_t));
@ -252,32 +254,46 @@ static char* getTagInfo_15(uint8_t *uid) {
} }
// return a clear-text message to an errorcode // return a clear-text message to an errorcode
static char* TagErrorStr(uint8_t error) { static char *TagErrorStr(uint8_t error)
{
switch (error) { switch (error) {
case 0x01: return "The command is not supported"; case 0x01:
case 0x02: return "The command is not recognised"; return "The command is not supported";
case 0x03: return "The option is not supported."; case 0x02:
case 0x0f: return "Unknown error."; return "The command is not recognised";
case 0x10: return "The specified block is not available (doesn't exist)."; case 0x03:
case 0x11: return "The specified block is already -locked and thus cannot be locked again"; return "The option is not supported.";
case 0x12: return "The specified block is locked and its content cannot be changed."; case 0x0f:
case 0x13: return "The specified block was not successfully programmed."; return "Unknown error.";
case 0x14: return "The specified block was not successfully locked."; case 0x10:
default: return "Reserved for Future Use or Custom command error."; return "The specified block is not available (doesn't exist).";
case 0x11:
return "The specified block is already -locked and thus cannot be locked again";
case 0x12:
return "The specified block is locked and its content cannot be changed.";
case 0x13:
return "The specified block was not successfully programmed.";
case 0x14:
return "The specified block was not successfully locked.";
default:
return "Reserved for Future Use or Custom command error.";
} }
} }
int usage_15_demod(void){ int usage_15_demod(void)
{
PrintAndLogEx(NORMAL, "Tries to demodulate / decode ISO15693, from downloaded samples.\n" PrintAndLogEx(NORMAL, "Tries to demodulate / decode ISO15693, from downloaded samples.\n"
"Gather samples with 'hf 15 read' / 'hf 15 record'"); "Gather samples with 'hf 15 read' / 'hf 15 record'");
return 0; return 0;
} }
int usage_15_samples(void){ int usage_15_samples(void)
{
PrintAndLogEx(NORMAL, "Acquire samples as Reader (enables carrier, send inquiry\n" PrintAndLogEx(NORMAL, "Acquire samples as Reader (enables carrier, send inquiry\n"
"and download it to graphbuffer. Try 'hf 15 demod' to try to demodulate/decode signal"); "and download it to graphbuffer. Try 'hf 15 demod' to try to demodulate/decode signal");
return 0; return 0;
} }
int usage_15_info(void){ int usage_15_info(void)
{
PrintAndLogEx(NORMAL, "Uses the optional command 'get_systeminfo' 0x2B to try and extract information\n" PrintAndLogEx(NORMAL, "Uses the optional command 'get_systeminfo' 0x2B to try and extract information\n"
"command may fail, depending on tag.\n" "command may fail, depending on tag.\n"
"defaults to '1 out of 4' mode\n" "defaults to '1 out of 4' mode\n"
@ -293,11 +309,13 @@ int usage_15_info(void){
"\thf 15 info u"); "\thf 15 info u");
return 0; return 0;
} }
int usage_15_record(void){ int usage_15_record(void)
{
PrintAndLogEx(NORMAL, "Record activity without enableing carrier"); PrintAndLogEx(NORMAL, "Record activity without enableing carrier");
return 0; return 0;
} }
int usage_15_reader(void){ int usage_15_reader(void)
{
PrintAndLogEx(NORMAL, "This command identifies a ISO 15693 tag\n" PrintAndLogEx(NORMAL, "This command identifies a ISO 15693 tag\n"
"\n" "\n"
"Usage: hf 15 reader [h]\n" "Usage: hf 15 reader [h]\n"
@ -308,18 +326,21 @@ int usage_15_reader(void){
"\thf 15 reader"); "\thf 15 reader");
return 0; return 0;
} }
int usage_15_sim(void){ int usage_15_sim(void)
{
PrintAndLogEx(NORMAL, "Usage: hf 15 sim <UID>\n" PrintAndLogEx(NORMAL, "Usage: hf 15 sim <UID>\n"
"\n" "\n"
"Example:\n" "Example:\n"
"\thf 15 sim E016240000000000"); "\thf 15 sim E016240000000000");
return 0; return 0;
} }
int usage_15_findafi(void){ int usage_15_findafi(void)
{
PrintAndLogEx(NORMAL, "'hf 15 finafi' This command needs a helptext. Feel free to add one!"); PrintAndLogEx(NORMAL, "'hf 15 finafi' This command needs a helptext. Feel free to add one!");
return 0; return 0;
} }
int usage_15_dump(void){ int usage_15_dump(void)
{
PrintAndLogEx(NORMAL, "This command dumps the contents of a ISO-15693 tag and save it to file\n" PrintAndLogEx(NORMAL, "This command dumps the contents of a ISO-15693 tag and save it to file\n"
"\n" "\n"
"Usage: hf 15 dump [h] <f filname> \n" "Usage: hf 15 dump [h] <f filname> \n"
@ -332,7 +353,8 @@ int usage_15_dump(void){
"\thf 15 dump f mydump"); "\thf 15 dump f mydump");
return 0; return 0;
} }
int usage_15_restore(void){ int usage_15_restore(void)
{
char *options[][2] = { char *options[][2] = {
{"h", "this help"}, {"h", "this help"},
{"-2", "use slower '1 out of 256' mode"}, {"-2", "use slower '1 out of 256' mode"},
@ -346,7 +368,8 @@ int usage_15_restore(void){
PrintAndLogOptions(options, 7, 3); PrintAndLogOptions(options, 7, 3);
return 0; return 0;
} }
int usage_15_raw(void){ int usage_15_raw(void)
{
char *options[][2] = { char *options[][2] = {
{"-r", "do not read response" }, {"-r", "do not read response" },
{"-2", "use slower '1 out of 256' mode" }, {"-2", "use slower '1 out of 256' mode" },
@ -357,7 +380,8 @@ int usage_15_raw(void){
PrintAndLogOptions(options, 4, 3); PrintAndLogOptions(options, 4, 3);
return 0; return 0;
} }
int usage_15_read(void){ int usage_15_read(void)
{
PrintAndLogEx(NORMAL, "Usage: hf 15 read [options] <uid|s|u|*> <page#>\n" PrintAndLogEx(NORMAL, "Usage: hf 15 read [options] <uid|s|u|*> <page#>\n"
"Options:\n" "Options:\n"
"\t-2 use slower '1 out of 256' mode\n" "\t-2 use slower '1 out of 256' mode\n"
@ -368,7 +392,8 @@ int usage_15_read(void){
"\tpage#: page number 0-255"); "\tpage#: page number 0-255");
return 0; return 0;
} }
int usage_15_write(void){ int usage_15_write(void)
{
PrintAndLogEx(NORMAL, "Usage: hf 15 write [options] <uid|s|u|*> <page#> <hexdata>\n" PrintAndLogEx(NORMAL, "Usage: hf 15 write [options] <uid|s|u|*> <page#> <hexdata>\n"
"Options:\n" "Options:\n"
"\t-2 use slower '1 out of 256' mode\n" "\t-2 use slower '1 out of 256' mode\n"
@ -381,7 +406,8 @@ int usage_15_write(void){
"\thexdata: data to be written eg AA BB CC DD"); "\thexdata: data to be written eg AA BB CC DD");
return 0; return 0;
} }
int usage_15_readmulti(void){ int usage_15_readmulti(void)
{
PrintAndLogEx(NORMAL, "Usage: hf 15 readmulti [options] <uid|s|u|*> <start#> <count#>\n" PrintAndLogEx(NORMAL, "Usage: hf 15 readmulti [options] <uid|s|u|*> <start#> <count#>\n"
"Options:\n" "Options:\n"
"\t-2 use slower '1 out of 256' mode\n" "\t-2 use slower '1 out of 256' mode\n"
@ -395,7 +421,8 @@ int usage_15_readmulti(void){
} }
// Mode 3 // Mode 3
//helptext //helptext
int CmdHF15Demod(const char *Cmd) { int CmdHF15Demod(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_15_demod(); if (cmdp == 'h') return usage_15_demod();
@ -475,7 +502,8 @@ int CmdHF15Demod(const char *Cmd) {
// * Acquire Samples as Reader (enables carrier, sends inquiry) // * Acquire Samples as Reader (enables carrier, sends inquiry)
//helptext //helptext
int CmdHF15Samples(const char *Cmd) { int CmdHF15Samples(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_15_samples(); if (cmdp == 'h') return usage_15_samples();
@ -491,7 +519,8 @@ int CmdHF15Samples(const char *Cmd) {
* Commandline handling: HF15 CMD SYSINFO * Commandline handling: HF15 CMD SYSINFO
* get system information from tag/VICC * get system information from tag/VICC
*/ */
int CmdHF15Info(const char *Cmd) { int CmdHF15Info(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0); char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_15_info(); if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_15_info();
@ -573,7 +602,8 @@ int CmdHF15Info(const char *Cmd) {
// Record Activity without enabeling carrier // Record Activity without enabeling carrier
//helptext //helptext
int CmdHF15Record(const char *Cmd) { int CmdHF15Record(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_15_record(); if (cmdp == 'h') return usage_15_record();
@ -584,7 +614,8 @@ int CmdHF15Record(const char *Cmd) {
} }
// used with 'hf search' // used with 'hf search'
int HF15Reader(const char *Cmd, bool verbose) { int HF15Reader(const char *Cmd, bool verbose)
{
uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0};
if (!getUID(uid)) { if (!getUID(uid)) {
if (verbose) PrintAndLogEx(WARNING, "No tag found."); if (verbose) PrintAndLogEx(WARNING, "No tag found.");
@ -596,7 +627,8 @@ int HF15Reader(const char *Cmd, bool verbose) {
return 1; return 1;
} }
int CmdHF15Reader(const char *Cmd) { int CmdHF15Reader(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_15_reader(); if (cmdp == 'h') return usage_15_reader();
@ -606,7 +638,8 @@ int CmdHF15Reader(const char *Cmd) {
// Simulation is still not working very good // Simulation is still not working very good
// helptext // helptext
int CmdHF15Sim(const char *Cmd) { int CmdHF15Sim(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || cmdp == 'h') return usage_15_sim(); if (strlen(Cmd) < 1 || cmdp == 'h') return usage_15_sim();
@ -628,7 +661,8 @@ int CmdHF15Sim(const char *Cmd) {
// finds the AFI (Application Family Idendifier) of a card, by trying all values // finds the AFI (Application Family Idendifier) of a card, by trying all values
// (There is no standard way of reading the AFI, allthough some tags support this) // (There is no standard way of reading the AFI, allthough some tags support this)
// helptext // helptext
int CmdHF15Afi(const char *Cmd) { int CmdHF15Afi(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_15_findafi(); if (cmdp == 'h') return usage_15_findafi();
@ -647,7 +681,8 @@ typedef struct {
// Reads all memory pages // Reads all memory pages
// need to write to file // need to write to file
int CmdHF15Dump(const char*Cmd) { int CmdHF15Dump(const char *Cmd)
{
uint8_t fileNameLen = 0; uint8_t fileNameLen = 0;
char filename[FILE_PATH_SIZE] = {0}; char filename[FILE_PATH_SIZE] = {0};
@ -744,7 +779,8 @@ int CmdHF15Dump(const char*Cmd) {
retry = 0; retry = 0;
blocknum++; blocknum++;
printf("."); fflush(stdout); printf(".");
fflush(stdout);
} }
} }
PrintAndLogEx(NORMAL, "\n"); PrintAndLogEx(NORMAL, "\n");
@ -762,7 +798,8 @@ int CmdHF15Dump(const char*Cmd) {
return 0; return 0;
} }
int CmdHF15Restore(const char*Cmd) { int CmdHF15Restore(const char *Cmd)
{
FILE *f; FILE *f;
uint8_t uid[8] = {0x00}; uint8_t uid[8] = {0x00};
@ -781,8 +818,7 @@ int CmdHF15Restore(const char*Cmd) {
switch (tolower(param_getchar(Cmd, cmdp))) { switch (tolower(param_getchar(Cmd, cmdp))) {
case '-': case '-':
param_getstr(Cmd, cmdp, param, sizeof(param)); param_getstr(Cmd, cmdp, param, sizeof(param));
switch(param[1]) switch (param[1]) {
{
case '2': case '2':
case 'o': case 'o':
strncpy(newCmdPrefix, " ", sizeof(newCmdPrefix) - 1); strncpy(newCmdPrefix, " ", sizeof(newCmdPrefix) - 1);
@ -875,13 +911,15 @@ int CmdHF15Restore(const char*Cmd) {
fclose(f); fclose(f);
} }
int CmdHF15List(const char *Cmd) { int CmdHF15List(const char *Cmd)
{
//PrintAndLogEx(WARNING, "Deprecated command, use 'hf list 15' instead"); //PrintAndLogEx(WARNING, "Deprecated command, use 'hf list 15' instead");
CmdTraceList("15"); CmdTraceList("15");
return 0; return 0;
} }
int CmdHF15Raw(const char *Cmd) { int CmdHF15Raw(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0); char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') return usage_15_raw(); if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') return usage_15_raw();
@ -968,7 +1006,8 @@ int CmdHF15Raw(const char *Cmd) {
* Parameters: * Parameters:
* **cmd command line * **cmd command line
*/ */
int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd) { int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd)
{
int temp; int temp;
uint8_t *req = c->d.asBytes; uint8_t *req = c->d.asBytes;
uint8_t uid[8] = {0x00}; uint8_t uid[8] = {0x00};
@ -1045,7 +1084,8 @@ int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd) {
* Commandline handling: HF15 CMD READMULTI * Commandline handling: HF15 CMD READMULTI
* Read multiple blocks at once (not all tags support this) * Read multiple blocks at once (not all tags support this)
*/ */
int CmdHF15Readmulti(const char *Cmd) { int CmdHF15Readmulti(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0); char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') return usage_15_readmulti(); if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') return usage_15_readmulti();
@ -1128,7 +1168,8 @@ int CmdHF15Readmulti(const char *Cmd) {
* Commandline handling: HF15 CMD READ * Commandline handling: HF15 CMD READ
* Reads a single Block * Reads a single Block
*/ */
int CmdHF15Read(const char *Cmd) { int CmdHF15Read(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0); char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') return usage_15_read(); if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') return usage_15_read();
@ -1202,7 +1243,8 @@ int CmdHF15Read(const char *Cmd) {
* Commandline handling: HF15 CMD WRITE * Commandline handling: HF15 CMD WRITE
* Writes a single Block - might run into timeout, even when successful * Writes a single Block - might run into timeout, even when successful
*/ */
int CmdHF15Write(const char *Cmd) { int CmdHF15Write(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0); char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') return usage_15_write(); if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') return usage_15_write();
@ -1296,13 +1338,15 @@ static command_t CommandTable15[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdHF15(const char *Cmd) { int CmdHF15(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable15, Cmd); CmdsParse(CommandTable15, Cmd);
return 0; return 0;
} }
int CmdHF15Help(const char *Cmd) { int CmdHF15Help(const char *Cmd)
{
CmdsHelp(CommandTable15); CmdsHelp(CommandTable15);
return 0; return 0;
} }

View file

@ -169,12 +169,14 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }
int CmdHFEPA(const char *Cmd) { int CmdHFEPA(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;

View file

@ -11,7 +11,8 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_hf_felica_sim(void) { int usage_hf_felica_sim(void)
{
PrintAndLogEx(NORMAL, "\n Emulating ISO/18092 FeliCa tag \n"); PrintAndLogEx(NORMAL, "\n Emulating ISO/18092 FeliCa tag \n");
PrintAndLogEx(NORMAL, "Usage: hf felica sim [h] t <type> [v]"); PrintAndLogEx(NORMAL, "Usage: hf felica sim [h] t <type> [v]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -23,7 +24,8 @@ int usage_hf_felica_sim(void) {
PrintAndLogEx(NORMAL, " hf felica sim t 1 "); PrintAndLogEx(NORMAL, " hf felica sim t 1 ");
return 0; return 0;
} }
int usage_hf_felica_sniff(void){ int usage_hf_felica_sniff(void)
{
PrintAndLogEx(NORMAL, "It get data from the field and saves it into command buffer."); PrintAndLogEx(NORMAL, "It get data from the field and saves it into command buffer.");
PrintAndLogEx(NORMAL, "Buffer accessible from command 'hf list felica'"); PrintAndLogEx(NORMAL, "Buffer accessible from command 'hf list felica'");
PrintAndLogEx(NORMAL, "Usage: hf felica sniff <s > <t>"); PrintAndLogEx(NORMAL, "Usage: hf felica sniff <s > <t>");
@ -33,7 +35,8 @@ int usage_hf_felica_sniff(void){
PrintAndLogEx(NORMAL, " hf felica sniff s 1000"); PrintAndLogEx(NORMAL, " hf felica sniff s 1000");
return 0; return 0;
} }
int usage_hf_felica_simlite(void) { int usage_hf_felica_simlite(void)
{
PrintAndLogEx(NORMAL, "\n Emulating ISO/18092 FeliCa Lite tag \n"); PrintAndLogEx(NORMAL, "\n Emulating ISO/18092 FeliCa Lite tag \n");
PrintAndLogEx(NORMAL, "Usage: hf felica litesim [h] u <uid>"); PrintAndLogEx(NORMAL, "Usage: hf felica litesim [h] u <uid>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -43,7 +46,8 @@ int usage_hf_felica_simlite(void) {
PrintAndLogEx(NORMAL, " hf felica litesim 11223344556677"); PrintAndLogEx(NORMAL, " hf felica litesim 11223344556677");
return 0; return 0;
} }
int usage_hf_felica_dumplite(void) { int usage_hf_felica_dumplite(void)
{
PrintAndLogEx(NORMAL, "\n Dump ISO/18092 FeliCa Lite tag \n"); PrintAndLogEx(NORMAL, "\n Dump ISO/18092 FeliCa Lite tag \n");
PrintAndLogEx(NORMAL, "press button to abort run, otherwise it will loop for 200sec."); PrintAndLogEx(NORMAL, "press button to abort run, otherwise it will loop for 200sec.");
PrintAndLogEx(NORMAL, "Usage: hf felica litedump [h]"); PrintAndLogEx(NORMAL, "Usage: hf felica litedump [h]");
@ -53,7 +57,8 @@ int usage_hf_felica_dumplite(void) {
PrintAndLogEx(NORMAL, " hf felica litedump"); PrintAndLogEx(NORMAL, " hf felica litedump");
return 0; return 0;
} }
int usage_hf_felica_raw(void){ int usage_hf_felica_raw(void)
{
PrintAndLogEx(NORMAL, "Usage: hf felica raw [-h] [-r] [-c] [-p] [-a] <0A 0B 0C ... hex>"); PrintAndLogEx(NORMAL, "Usage: hf felica raw [-h] [-r] [-c] [-p] [-a] <0A 0B 0C ... hex>");
PrintAndLogEx(NORMAL, " -h this help"); PrintAndLogEx(NORMAL, " -h this help");
PrintAndLogEx(NORMAL, " -r do not read response"); PrintAndLogEx(NORMAL, " -r do not read response");
@ -64,13 +69,15 @@ int usage_hf_felica_raw(void){
return 0; return 0;
} }
int CmdHFFelicaList(const char *Cmd) { int CmdHFFelicaList(const char *Cmd)
{
//PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list felica' instead"); //PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list felica' instead");
CmdTraceList("felica"); CmdTraceList("felica");
return 0; return 0;
} }
int CmdHFFelicaReader(const char *Cmd) { int CmdHFFelicaReader(const char *Cmd)
{
bool silent = (Cmd[0] == 's' || Cmd[0] == 'S'); bool silent = (Cmd[0] == 's' || Cmd[0] == 'S');
//UsbCommand cDisconnect = {CMD_FELICA_COMMAND, {0,0,0}}; //UsbCommand cDisconnect = {CMD_FELICA_COMMAND, {0,0,0}};
UsbCommand c = {CMD_FELICA_COMMAND, {FELICA_CONNECT, 0, 0}}; UsbCommand c = {CMD_FELICA_COMMAND, {FELICA_CONNECT, 0, 0}};
@ -122,7 +129,8 @@ int CmdHFFelicaReader(const char *Cmd) {
} }
// simulate iso18092 / FeliCa tag // simulate iso18092 / FeliCa tag
int CmdHFFelicaSim(const char *Cmd) { int CmdHFFelicaSim(const char *Cmd)
{
bool errors = false; bool errors = false;
uint8_t flags = 0; uint8_t flags = 0;
uint8_t tagtype = 1; uint8_t tagtype = 1;
@ -187,7 +195,8 @@ int CmdHFFelicaSim(const char *Cmd) {
return 0; return 0;
} }
int CmdHFFelicaSniff(const char *Cmd) { int CmdHFFelicaSniff(const char *Cmd)
{
uint8_t cmdp = 0; uint8_t cmdp = 0;
uint64_t samples2skip = 0; uint64_t samples2skip = 0;
@ -225,7 +234,8 @@ int CmdHFFelicaSniff(const char *Cmd) {
} }
// uid hex // uid hex
int CmdHFFelicaSimLite(const char *Cmd) { int CmdHFFelicaSimLite(const char *Cmd)
{
uint64_t uid = param_get64ex(Cmd, 0, 0, 16); uint64_t uid = param_get64ex(Cmd, 0, 0, 16);
@ -238,11 +248,13 @@ int CmdHFFelicaSimLite(const char *Cmd) {
return 0; return 0;
} }
static void printSep() { static void printSep()
{
PrintAndLogEx(NORMAL, "------------------------------------------------------------------------------------"); PrintAndLogEx(NORMAL, "------------------------------------------------------------------------------------");
} }
uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace, uint16_t tracelen) { uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace, uint16_t tracelen)
{
if (tracepos + 19 >= tracelen) if (tracepos + 19 >= tracelen)
return tracelen; return tracelen;
@ -258,20 +270,48 @@ uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace, uint16_t tracelen) {
PrintAndLogEx(NORMAL, "block number %02x, status: %02x %02x", blocknum, status1, status2); PrintAndLogEx(NORMAL, "block number %02x, status: %02x %02x", blocknum, status1, status2);
switch (blocknum) { switch (blocknum) {
case 0x00: PrintAndLogEx(NORMAL, "S_PAD0: %s",line);break; case 0x00:
case 0x01: PrintAndLogEx(NORMAL, "S_PAD1: %s",line);break; PrintAndLogEx(NORMAL, "S_PAD0: %s", line);
case 0x02: PrintAndLogEx(NORMAL, "S_PAD2: %s",line);break; break;
case 0x03: PrintAndLogEx(NORMAL, "S_PAD3: %s",line);break; case 0x01:
case 0x04: PrintAndLogEx(NORMAL, "S_PAD4: %s",line);break; PrintAndLogEx(NORMAL, "S_PAD1: %s", line);
case 0x05: PrintAndLogEx(NORMAL, "S_PAD5: %s",line);break; break;
case 0x06: PrintAndLogEx(NORMAL, "S_PAD6: %s",line);break; case 0x02:
case 0x07: PrintAndLogEx(NORMAL, "S_PAD7: %s",line);break; PrintAndLogEx(NORMAL, "S_PAD2: %s", line);
case 0x08: PrintAndLogEx(NORMAL, "S_PAD8: %s",line);break; break;
case 0x09: PrintAndLogEx(NORMAL, "S_PAD9: %s",line);break; case 0x03:
case 0x0a: PrintAndLogEx(NORMAL, "S_PAD10: %s",line);break; PrintAndLogEx(NORMAL, "S_PAD3: %s", line);
case 0x0b: PrintAndLogEx(NORMAL, "S_PAD11: %s",line);break; break;
case 0x0c: PrintAndLogEx(NORMAL, "S_PAD12: %s",line);break; case 0x04:
case 0x0d: PrintAndLogEx(NORMAL, "S_PAD13: %s",line);break; PrintAndLogEx(NORMAL, "S_PAD4: %s", line);
break;
case 0x05:
PrintAndLogEx(NORMAL, "S_PAD5: %s", line);
break;
case 0x06:
PrintAndLogEx(NORMAL, "S_PAD6: %s", line);
break;
case 0x07:
PrintAndLogEx(NORMAL, "S_PAD7: %s", line);
break;
case 0x08:
PrintAndLogEx(NORMAL, "S_PAD8: %s", line);
break;
case 0x09:
PrintAndLogEx(NORMAL, "S_PAD9: %s", line);
break;
case 0x0a:
PrintAndLogEx(NORMAL, "S_PAD10: %s", line);
break;
case 0x0b:
PrintAndLogEx(NORMAL, "S_PAD11: %s", line);
break;
case 0x0c:
PrintAndLogEx(NORMAL, "S_PAD12: %s", line);
break;
case 0x0d:
PrintAndLogEx(NORMAL, "S_PAD13: %s", line);
break;
case 0x0E: { case 0x0E: {
uint32_t regA = trace[3] | trace[4] << 8 | trace[5] << 16 | trace[ 6] << 24; uint32_t regA = trace[3] | trace[4] << 8 | trace[5] << 16 | trace[ 6] << 24;
uint32_t regB = trace[7] | trace[8] << 8 | trace[9] << 16 | trace[10] << 24; uint32_t regB = trace[7] | trace[8] << 8 | trace[9] << 16 | trace[10] << 24;
@ -282,8 +322,12 @@ uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace, uint16_t tracelen) {
PrintAndLogEx(NORMAL, "REG: regA: %d regB: %d regC: %s ", regA, regB, line); PrintAndLogEx(NORMAL, "REG: regA: %d regB: %d regC: %s ", regA, regB, line);
} }
break; break;
case 0x80: PrintAndLogEx(NORMAL, "Random Challenge, WO: %s ", line); break; case 0x80:
case 0x81: PrintAndLogEx(NORMAL, "MAC, only set on dual read: %s ", line); break; PrintAndLogEx(NORMAL, "Random Challenge, WO: %s ", line);
break;
case 0x81:
PrintAndLogEx(NORMAL, "MAC, only set on dual read: %s ", line);
break;
case 0x82: { case 0x82: {
char idd[20]; char idd[20];
char idm[20]; char idm[20];
@ -308,10 +352,18 @@ uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace, uint16_t tracelen) {
PrintAndLogEx(NORMAL, "DeviceId: IDm: 0x%s PMm: 0x%s ", idm, pmm); PrintAndLogEx(NORMAL, "DeviceId: IDm: 0x%s PMm: 0x%s ", idm, pmm);
} }
break; break;
case 0x84: PrintAndLogEx(NORMAL, "SER_C: 0x%02x%02x ", trace[3], trace[4]); break; case 0x84:
case 0x85: PrintAndLogEx(NORMAL, "SYS_Cl 0x%02x%02x ", trace[3], trace[4]); break; PrintAndLogEx(NORMAL, "SER_C: 0x%02x%02x ", trace[3], trace[4]);
case 0x86: PrintAndLogEx(NORMAL, "CKV (key version): 0x%02x%02x ", trace[3], trace[4]); break; break;
case 0x87: PrintAndLogEx(NORMAL, "CK (card key), WO: %s ", line); break; case 0x85:
PrintAndLogEx(NORMAL, "SYS_Cl 0x%02x%02x ", trace[3], trace[4]);
break;
case 0x86:
PrintAndLogEx(NORMAL, "CKV (key version): 0x%02x%02x ", trace[3], trace[4]);
break;
case 0x87:
PrintAndLogEx(NORMAL, "CK (card key), WO: %s ", line);
break;
case 0x88: { case 0x88: {
PrintAndLogEx(NORMAL, "Memory Configuration (MC):"); PrintAndLogEx(NORMAL, "Memory Configuration (MC):");
PrintAndLogEx(NORMAL, "MAC needed to write state: %s", trace[3 + 12] ? "on" : "off"); PrintAndLogEx(NORMAL, "MAC needed to write state: %s", trace[3 + 12] ? "on" : "off");
@ -349,7 +401,8 @@ uint16_t PrintFliteBlock(uint16_t tracepos, uint8_t *trace, uint16_t tracelen) {
return tracepos + 19; return tracepos + 19;
} }
int CmdHFFelicaDumpLite(const char *Cmd) { int CmdHFFelicaDumpLite(const char *Cmd)
{
char ctmp = tolower(param_getchar(Cmd, 0)); char ctmp = tolower(param_getchar(Cmd, 0));
if (ctmp == 'h') return usage_hf_felica_dumplite(); if (ctmp == 'h') return usage_hf_felica_dumplite();
@ -364,9 +417,11 @@ int CmdHFFelicaDumpLite(const char *Cmd) {
uint8_t timeout = 0; uint8_t timeout = 0;
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
timeout++; timeout++;
printf("."); fflush(stdout); printf(".");
fflush(stdout);
if (ukbhit()) { if (ukbhit()) {
int gc = getchar(); (void)gc; int gc = getchar();
(void)gc;
PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n"); PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n");
DropField(); DropField();
return 1; return 1;
@ -414,7 +469,8 @@ int CmdHFFelicaDumpLite(const char *Cmd) {
return 0; return 0;
} }
int CmdHFFelicaCmdRaw(const char *cmd) { int CmdHFFelicaCmdRaw(const char *cmd)
{
UsbCommand c = {CMD_FELICA_COMMAND, {0, 0, 0}}; UsbCommand c = {CMD_FELICA_COMMAND, {0, 0, 0}};
bool reply = 1; bool reply = 1;
bool crc = false; bool crc = false;
@ -530,7 +586,8 @@ int CmdHFFelicaCmdRaw(const char *cmd) {
return 0; return 0;
} }
void waitCmdFelica(uint8_t iSelect) { void waitCmdFelica(uint8_t iSelect)
{
UsbCommand resp; UsbCommand resp;
uint16_t len = 0; uint16_t len = 0;
@ -558,13 +615,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdHFFelica(const char *Cmd) { int CmdHFFelica(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -49,7 +49,8 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int CmdHFFidoInfo(const char *cmd) { int CmdHFFidoInfo(const char *cmd)
{
if (cmd && strlen(cmd) > 0) if (cmd && strlen(cmd) > 0)
PrintAndLog("WARNING: command don't have any parameters.\n"); PrintAndLog("WARNING: command don't have any parameters.\n");
@ -124,7 +125,8 @@ int CmdHFFidoInfo(const char *cmd) {
return 0; return 0;
} }
json_t *OpenJson(int paramnum, char *fname, void* argtable[], bool *err) { json_t *OpenJson(int paramnum, char *fname, void *argtable[], bool *err)
{
json_t *root = NULL; json_t *root = NULL;
json_error_t error; json_error_t error;
*err = false; *err = false;
@ -168,7 +170,8 @@ json_t *OpenJson(int paramnum, char *fname, void* argtable[], bool *err) {
return root; return root;
} }
int CmdHFFidoRegister(const char *cmd) { int CmdHFFidoRegister(const char *cmd)
{
uint8_t data[64] = {0}; uint8_t data[64] = {0};
int chlen = 0; int chlen = 0;
uint8_t cdata[250] = {0}; uint8_t cdata[250] = {0};
@ -397,7 +400,8 @@ int CmdHFFidoRegister(const char *cmd) {
return 0; return 0;
}; };
int CmdHFFidoAuthenticate(const char *cmd) { int CmdHFFidoAuthenticate(const char *cmd)
{
uint8_t data[512] = {0}; uint8_t data[512] = {0};
uint8_t hdata[250] = {0}; uint8_t hdata[250] = {0};
bool public_key_loaded = false; bool public_key_loaded = false;
@ -615,13 +619,15 @@ int CmdHFFidoAuthenticate(const char *cmd) {
return 0; return 0;
}; };
void CheckSlash(char *fileName) { void CheckSlash(char *fileName)
{
if ((fileName[strlen(fileName) - 1] != '/') && if ((fileName[strlen(fileName) - 1] != '/') &&
(fileName[strlen(fileName) - 1] != '\\')) (fileName[strlen(fileName) - 1] != '\\'))
strcat(fileName, "/"); strcat(fileName, "/");
} }
int GetExistsFileNameJson(char *prefixDir, char *reqestedFileName, char *fileName) { int GetExistsFileNameJson(char *prefixDir, char *reqestedFileName, char *fileName)
{
fileName[0] = 0x00; fileName[0] = 0x00;
strcpy(fileName, get_my_executable_directory()); strcpy(fileName, get_my_executable_directory());
CheckSlash(fileName); CheckSlash(fileName);
@ -648,7 +654,8 @@ int GetExistsFileNameJson(char *prefixDir, char *reqestedFileName, char *fileNam
return 0; return 0;
} }
int CmdHFFido2MakeCredential(const char *cmd) { int CmdHFFido2MakeCredential(const char *cmd)
{
json_error_t error; json_error_t error;
json_t *root = NULL; json_t *root = NULL;
char fname[300] = {0}; char fname[300] = {0};
@ -775,7 +782,8 @@ int CmdHFFido2MakeCredential(const char *cmd) {
return 0; return 0;
}; };
int CmdHFFido2GetAssertion(const char *cmd) { int CmdHFFido2GetAssertion(const char *cmd)
{
json_error_t error; json_error_t error;
json_t *root = NULL; json_t *root = NULL;
char fname[300] = {0}; char fname[300] = {0};
@ -902,8 +910,7 @@ int CmdHFFido2GetAssertion(const char *cmd) {
return 0; return 0;
}; };
static command_t CommandTable[] = static command_t CommandTable[] = {
{
{"help", CmdHelp, 1, "This help."}, {"help", CmdHelp, 1, "This help."},
{"info", CmdHFFidoInfo, 0, "Info about FIDO tag."}, {"info", CmdHFFidoInfo, 0, "Info about FIDO tag."},
{"reg", CmdHFFidoRegister, 0, "FIDO U2F Registration Message."}, {"reg", CmdHFFidoRegister, 0, "FIDO U2F Registration Message."},
@ -913,13 +920,15 @@ static command_t CommandTable[] =
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdHFFido(const char *Cmd) { int CmdHFFido(const char *Cmd)
{
(void)WaitForResponseTimeout(CMD_ACK, NULL, 100); (void)WaitForResponseTimeout(CMD_ACK, NULL, 100);
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -29,7 +29,8 @@ static uint8_t iClass_Key_Table[ICLASS_KEYS_MAX][8] = {
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
}; };
int usage_hf_iclass_sim(void) { int usage_hf_iclass_sim(void)
{
PrintAndLogEx(NORMAL, "Usage: hf iclass sim <option> [CSN]"); PrintAndLogEx(NORMAL, "Usage: hf iclass sim <option> [CSN]");
PrintAndLogEx(NORMAL, " options"); PrintAndLogEx(NORMAL, " options");
PrintAndLogEx(NORMAL, " 0 <CSN> simulate the given CSN"); PrintAndLogEx(NORMAL, " 0 <CSN> simulate the given CSN");
@ -45,14 +46,16 @@ int usage_hf_iclass_sim(void) {
PrintAndLogEx(NORMAL, " hf iclass sim 4"); PrintAndLogEx(NORMAL, " hf iclass sim 4");
return 0; return 0;
} }
int usage_hf_iclass_eload(void) { int usage_hf_iclass_eload(void)
{
PrintAndLogEx(NORMAL, "Loads iclass tag-dump into emulator memory on device"); PrintAndLogEx(NORMAL, "Loads iclass tag-dump into emulator memory on device");
PrintAndLogEx(NORMAL, "Usage: hf iclass eload f <filename>"); PrintAndLogEx(NORMAL, "Usage: hf iclass eload f <filename>");
PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " hf iclass eload f iclass_tagdump-aa162d30f8ff12f1.bin"); PrintAndLogEx(NORMAL, " hf iclass eload f iclass_tagdump-aa162d30f8ff12f1.bin");
return 0; return 0;
} }
int usage_hf_iclass_decrypt(void) { int usage_hf_iclass_decrypt(void)
{
PrintAndLogEx(NORMAL, "This is simple implementation, it tries to decrypt every block after block 6."); PrintAndLogEx(NORMAL, "This is simple implementation, it tries to decrypt every block after block 6.");
PrintAndLogEx(NORMAL, "Correct behaviour would be to decrypt only the application areas where the key is valid,"); PrintAndLogEx(NORMAL, "Correct behaviour would be to decrypt only the application areas where the key is valid,");
PrintAndLogEx(NORMAL, "which is defined by the configuration block."); PrintAndLogEx(NORMAL, "which is defined by the configuration block.");
@ -65,7 +68,8 @@ int usage_hf_iclass_decrypt(void) {
PrintAndLogEx(NORMAL, "S hf iclass decrypt f tagdump_12312342343.bin"); PrintAndLogEx(NORMAL, "S hf iclass decrypt f tagdump_12312342343.bin");
return 0; return 0;
} }
int usage_hf_iclass_encrypt(void) { int usage_hf_iclass_encrypt(void)
{
PrintAndLogEx(NORMAL, "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside"); PrintAndLogEx(NORMAL, "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside");
PrintAndLogEx(NORMAL, "in the working directory. The file should be 16 bytes binary data"); PrintAndLogEx(NORMAL, "in the working directory. The file should be 16 bytes binary data");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
@ -76,7 +80,8 @@ int usage_hf_iclass_encrypt(void) {
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
return 0; return 0;
} }
int usage_hf_iclass_dump(void) { int usage_hf_iclass_dump(void)
{
PrintAndLogEx(NORMAL, "Usage: hf iclass dump f <fileName> k <key> c <creditkey> [e|r|v]\n"); PrintAndLogEx(NORMAL, "Usage: hf iclass dump f <fileName> k <key> c <creditkey> [e|r|v]\n");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " f <filename> : specify a filename to save dump to"); PrintAndLogEx(NORMAL, " f <filename> : specify a filename to save dump to");
@ -92,7 +97,8 @@ int usage_hf_iclass_dump(void) {
PrintAndLogEx(NORMAL, " hf iclass dump k AAAAAAAAAAAAAAAA e"); PrintAndLogEx(NORMAL, " hf iclass dump k AAAAAAAAAAAAAAAA e");
return 0; return 0;
} }
int usage_hf_iclass_clone(void) { int usage_hf_iclass_clone(void)
{
PrintAndLogEx(NORMAL, "Usage: hf iclass clone f <tagfile.bin> b <first block> l <last block> k <KEY> c e|r"); PrintAndLogEx(NORMAL, "Usage: hf iclass clone f <tagfile.bin> b <first block> l <last block> k <KEY> c e|r");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " f <filename>: specify a filename to clone from"); PrintAndLogEx(NORMAL, " f <filename>: specify a filename to clone from");
@ -108,7 +114,8 @@ int usage_hf_iclass_clone(void) {
PrintAndLogEx(NORMAL, " hf iclass clone f iclass_tagdump-121345.bin b 06 l 19 k 0 e"); PrintAndLogEx(NORMAL, " hf iclass clone f iclass_tagdump-121345.bin b 06 l 19 k 0 e");
return 0; return 0;
} }
int usage_hf_iclass_writeblock(void) { int usage_hf_iclass_writeblock(void)
{
PrintAndLogEx(NORMAL, "Usage: hf iclass writeblk b <block> d <data> k <key> [c|e|r|v]\n"); PrintAndLogEx(NORMAL, "Usage: hf iclass writeblk b <block> d <data> k <key> [c|e|r|v]\n");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " b <Block> : The block number as 2 hex symbols"); PrintAndLogEx(NORMAL, " b <Block> : The block number as 2 hex symbols");
@ -123,7 +130,8 @@ int usage_hf_iclass_writeblock(void) {
PrintAndLogEx(NORMAL, " hf iclass writeblk b 1B d AAAAAAAAAAAAAAAA k 001122334455667B c"); PrintAndLogEx(NORMAL, " hf iclass writeblk b 1B d AAAAAAAAAAAAAAAA k 001122334455667B c");
return 0; return 0;
} }
int usage_hf_iclass_readblock(void) { int usage_hf_iclass_readblock(void)
{
PrintAndLogEx(NORMAL, "Usage: hf iclass readblk b <block> k <key> [c|e|r|v]\n"); PrintAndLogEx(NORMAL, "Usage: hf iclass readblk b <block> k <key> [c|e|r|v]\n");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " b <block> : The block number as 2 hex symbols"); PrintAndLogEx(NORMAL, " b <block> : The block number as 2 hex symbols");
@ -138,11 +146,13 @@ int usage_hf_iclass_readblock(void) {
PrintAndLogEx(NORMAL, " hf iclass readblk b 0A k 0"); PrintAndLogEx(NORMAL, " hf iclass readblk b 0A k 0");
return 0; return 0;
} }
int usage_hf_iclass_readtagfile() { int usage_hf_iclass_readtagfile()
{
PrintAndLogEx(NORMAL, "Usage: hf iclass readtagfile <filename> [startblock] [endblock]"); PrintAndLogEx(NORMAL, "Usage: hf iclass readtagfile <filename> [startblock] [endblock]");
return 0; return 0;
} }
int usage_hf_iclass_calc_newkey(void) { int usage_hf_iclass_calc_newkey(void)
{
PrintAndLogEx(NORMAL, "Calculate new key for updating\n"); PrintAndLogEx(NORMAL, "Calculate new key for updating\n");
PrintAndLogEx(NORMAL, "Usage: hf iclass calc_newkey o <Old key> n <New key> s [csn] e"); PrintAndLogEx(NORMAL, "Usage: hf iclass calc_newkey o <Old key> n <New key> s [csn] e");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -158,7 +168,8 @@ int usage_hf_iclass_calc_newkey(void) {
PrintAndLogEx(NORMAL, "\nNOTE: * = required\n"); PrintAndLogEx(NORMAL, "\nNOTE: * = required\n");
return 0; return 0;
} }
int usage_hf_iclass_managekeys(void) { int usage_hf_iclass_managekeys(void)
{
PrintAndLogEx(NORMAL, "HELP : Manage iClass Keys in client memory:\n"); PrintAndLogEx(NORMAL, "HELP : Manage iClass Keys in client memory:\n");
PrintAndLogEx(NORMAL, "Usage: hf iclass managekeys n [keynbr] k [key] f [filename] s l p\n"); PrintAndLogEx(NORMAL, "Usage: hf iclass managekeys n [keynbr] k [key] f [filename] s l p\n");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -175,7 +186,8 @@ int usage_hf_iclass_managekeys(void) {
PrintAndLogEx(NORMAL, " print keys : hf iclass managekeys p\n"); PrintAndLogEx(NORMAL, " print keys : hf iclass managekeys p\n");
return 0; return 0;
} }
int usage_hf_iclass_reader(void) { int usage_hf_iclass_reader(void)
{
PrintAndLogEx(NORMAL, "Act as a Iclass reader. Look for iClass tags until a key or the pm3 button is pressed\n"); PrintAndLogEx(NORMAL, "Act as a Iclass reader. Look for iClass tags until a key or the pm3 button is pressed\n");
PrintAndLogEx(NORMAL, "Usage: hf iclass reader [h] [1]\n"); PrintAndLogEx(NORMAL, "Usage: hf iclass reader [h] [1]\n");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -185,7 +197,8 @@ int usage_hf_iclass_reader(void) {
PrintAndLogEx(NORMAL, " hf iclass reader 1"); PrintAndLogEx(NORMAL, " hf iclass reader 1");
return 0; return 0;
} }
int usage_hf_iclass_replay(void) { int usage_hf_iclass_replay(void)
{
PrintAndLogEx(NORMAL, "Replay a collected mac message"); PrintAndLogEx(NORMAL, "Replay a collected mac message");
PrintAndLogEx(NORMAL, "Usage: hf iclass replay [h] <mac>"); PrintAndLogEx(NORMAL, "Usage: hf iclass replay [h] <mac>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -195,14 +208,16 @@ int usage_hf_iclass_replay(void) {
PrintAndLogEx(NORMAL, " hf iclass replay 00112233"); PrintAndLogEx(NORMAL, " hf iclass replay 00112233");
return 0; return 0;
} }
int usage_hf_iclass_sniff(void) { int usage_hf_iclass_sniff(void)
{
PrintAndLogEx(NORMAL, "Sniff the communication between reader and tag"); PrintAndLogEx(NORMAL, "Sniff the communication between reader and tag");
PrintAndLogEx(NORMAL, "Usage: hf iclass sniff [h]"); PrintAndLogEx(NORMAL, "Usage: hf iclass sniff [h]");
PrintAndLogEx(NORMAL, "Examples:"); PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " hf iclass sniff"); PrintAndLogEx(NORMAL, " hf iclass sniff");
return 0; return 0;
} }
int usage_hf_iclass_loclass(void) { int usage_hf_iclass_loclass(void)
{
PrintAndLogEx(NORMAL, "Usage: hf iclass loclass [options]"); PrintAndLogEx(NORMAL, "Usage: hf iclass loclass [options]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, "h Show this help"); PrintAndLogEx(NORMAL, "h Show this help");
@ -217,7 +232,8 @@ int usage_hf_iclass_loclass(void) {
PrintAndLogEx(NORMAL, " ... totalling N*24 bytes"); PrintAndLogEx(NORMAL, " ... totalling N*24 bytes");
return 0; return 0;
} }
int usage_hf_iclass_chk(void) { int usage_hf_iclass_chk(void)
{
PrintAndLogEx(NORMAL, "Checkkeys loads a dictionary text file with 8byte hex keys to test authenticating against a iClass tag"); PrintAndLogEx(NORMAL, "Checkkeys loads a dictionary text file with 8byte hex keys to test authenticating against a iClass tag");
PrintAndLogEx(NORMAL, "Usage: hf iclass chk [h|e|r] [f (*.dic)]"); PrintAndLogEx(NORMAL, "Usage: hf iclass chk [h|e|r] [f (*.dic)]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -231,7 +247,8 @@ int usage_hf_iclass_chk(void) {
PrintAndLogEx(NORMAL, " hf iclass chk f default_iclass_keys.dic e"); PrintAndLogEx(NORMAL, " hf iclass chk f default_iclass_keys.dic e");
return 0; return 0;
} }
int usage_hf_iclass_lookup(void) { int usage_hf_iclass_lookup(void)
{
PrintAndLogEx(NORMAL, "Lookup keys takes some sniffed trace data and tries to verify what key was used against a dictionary file"); PrintAndLogEx(NORMAL, "Lookup keys takes some sniffed trace data and tries to verify what key was used against a dictionary file");
PrintAndLogEx(NORMAL, "Usage: hf iclass lookup [h|e|r] [f (*.dic)] [u <csn>] [p <epurse>] [m <macs>]"); PrintAndLogEx(NORMAL, "Usage: hf iclass lookup [h|e|r] [f (*.dic)] [u <csn>] [p <epurse>] [m <macs>]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -247,7 +264,8 @@ int usage_hf_iclass_lookup(void) {
PrintAndLogEx(NORMAL, " hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f default_iclass_keys.dic e"); PrintAndLogEx(NORMAL, " hf iclass lookup u 9655a400f8ff12e0 p f0ffffffffffffff m 0000000089cb984b f default_iclass_keys.dic e");
return 0; return 0;
} }
int usage_hf_iclass_permutekey(void){ int usage_hf_iclass_permutekey(void)
{
PrintAndLogEx(NORMAL, "Permute function from 'heart of darkness' paper."); PrintAndLogEx(NORMAL, "Permute function from 'heart of darkness' paper.");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: hf iclass permute [h] <r|f> <bytes>"); PrintAndLogEx(NORMAL, "Usage: hf iclass permute [h] <r|f> <bytes>");
@ -262,7 +280,8 @@ int usage_hf_iclass_permutekey(void){
return 0; return 0;
} }
int xorbits_8(uint8_t val) { int xorbits_8(uint8_t val)
{
uint8_t res = val ^ (val >> 1); //1st pass uint8_t res = val ^ (val >> 1); //1st pass
res = res ^ (res >> 1); // 2nd pass res = res ^ (res >> 1); // 2nd pass
res = res ^ (res >> 2); // 3rd pass res = res ^ (res >> 2); // 3rd pass
@ -270,13 +289,15 @@ int xorbits_8(uint8_t val) {
return res & 1; return res & 1;
} }
int CmdHFiClassList(const char *Cmd) { int CmdHFiClassList(const char *Cmd)
{
//PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list iclass' instead"); //PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list iclass' instead");
CmdTraceList("iclass"); CmdTraceList("iclass");
return 0; return 0;
} }
int CmdHFiClassSniff(const char *Cmd) { int CmdHFiClassSniff(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_iclass_sniff(); if (cmdp == 'h') return usage_hf_iclass_sniff();
UsbCommand c = {CMD_SNOOP_ICLASS}; UsbCommand c = {CMD_SNOOP_ICLASS};
@ -284,7 +305,8 @@ int CmdHFiClassSniff(const char *Cmd) {
return 0; return 0;
} }
int CmdHFiClassSim(const char *Cmd) { int CmdHFiClassSim(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || cmdp == 'h') return usage_hf_iclass_sim(); if (strlen(Cmd) < 1 || cmdp == 'h') return usage_hf_iclass_sim();
@ -387,7 +409,8 @@ int CmdHFiClassSim(const char *Cmd) {
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
tries++; tries++;
if (ukbhit()) { if (ukbhit()) {
int gc = getchar(); (void)gc; int gc = getchar();
(void)gc;
PrintAndLogEx(WARNING, "\naborted via keyboard."); PrintAndLogEx(WARNING, "\naborted via keyboard.");
return 0; return 0;
} }
@ -439,7 +462,8 @@ int CmdHFiClassSim(const char *Cmd) {
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
tries++; tries++;
if (ukbhit()) { if (ukbhit()) {
int gc = getchar(); (void)gc; int gc = getchar();
(void)gc;
PrintAndLogEx(WARNING, "\naborted via keyboard."); PrintAndLogEx(WARNING, "\naborted via keyboard.");
return 0; return 0;
} }
@ -507,7 +531,8 @@ int CmdHFiClassSim(const char *Cmd) {
return 0; return 0;
} }
int HFiClassReader(const char *Cmd, bool loop, bool verbose) { int HFiClassReader(const char *Cmd, bool loop, bool verbose)
{
bool tagFound = false; bool tagFound = false;
uint32_t flags = FLAG_ICLASS_READER_CSN | FLAG_ICLASS_READER_CC | FLAG_ICLASS_READER_AIA | uint32_t flags = FLAG_ICLASS_READER_CSN | FLAG_ICLASS_READER_CC | FLAG_ICLASS_READER_AIA |
@ -573,14 +598,16 @@ int HFiClassReader(const char *Cmd, bool loop, bool verbose) {
return 0; return 0;
} }
int CmdHFiClassReader(const char *Cmd) { int CmdHFiClassReader(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_iclass_reader(); if (cmdp == 'h') return usage_hf_iclass_reader();
bool findone = (cmdp == '1') ? false : true; bool findone = (cmdp == '1') ? false : true;
return HFiClassReader(Cmd, findone, true); return HFiClassReader(Cmd, findone, true);
} }
int CmdHFiClassReader_Replay(const char *Cmd) { int CmdHFiClassReader_Replay(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || cmdp == 'h') return usage_hf_iclass_replay(); if (strlen(Cmd) < 1 || cmdp == 'h') return usage_hf_iclass_replay();
@ -600,7 +627,8 @@ int CmdHFiClassReader_Replay(const char *Cmd) {
return 0; return 0;
} }
int iclassEmlSetMem(uint8_t *data, int blockNum, int blocksCount) { int iclassEmlSetMem(uint8_t *data, int blockNum, int blocksCount)
{
UsbCommand c = {CMD_MIFARE_EML_MEMSET, {blockNum, blocksCount, 0}}; UsbCommand c = {CMD_MIFARE_EML_MEMSET, {blockNum, blocksCount, 0}};
memcpy(c.d.asBytes, data, blocksCount * 16); memcpy(c.d.asBytes, data, blocksCount * 16);
clearCommandBuffer(); clearCommandBuffer();
@ -608,7 +636,8 @@ int iclassEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
return 0; return 0;
} }
int CmdHFiClassELoad(const char *Cmd) { int CmdHFiClassELoad(const char *Cmd)
{
char ctmp = tolower(param_getchar(Cmd, 0)); char ctmp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf_iclass_eload(); if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf_iclass_eload();
@ -676,7 +705,8 @@ int CmdHFiClassELoad(const char *Cmd) {
return 0; return 0;
} }
static int readKeyfile(const char *filename, size_t len, uint8_t* buffer) { static int readKeyfile(const char *filename, size_t len, uint8_t *buffer)
{
FILE *f = fopen(filename, "rb"); FILE *f = fopen(filename, "rb");
if (!f) { if (!f) {
PrintAndLogEx(WARNING, "Failed to read from file '%s'", filename); PrintAndLogEx(WARNING, "Failed to read from file '%s'", filename);
@ -700,7 +730,8 @@ static int readKeyfile(const char *filename, size_t len, uint8_t* buffer) {
return 0; return 0;
} }
int CmdHFiClassDecrypt(const char *Cmd) { int CmdHFiClassDecrypt(const char *Cmd)
{
char opt = tolower(param_getchar(Cmd, 0)); char opt = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || opt == 'h') return usage_hf_iclass_decrypt(); if (strlen(Cmd) < 1 || opt == 'h') return usage_hf_iclass_decrypt();
@ -787,7 +818,8 @@ int CmdHFiClassDecrypt(const char *Cmd) {
return 0; return 0;
} }
static int iClassEncryptBlkData(uint8_t *blkData) { static int iClassEncryptBlkData(uint8_t *blkData)
{
uint8_t key[16] = { 0 }; uint8_t key[16] = { 0 };
if (readKeyfile("iclass_decryptionkey.bin", 16, key)) { if (readKeyfile("iclass_decryptionkey.bin", 16, key)) {
usage_hf_iclass_encrypt(); usage_hf_iclass_encrypt();
@ -804,7 +836,8 @@ static int iClassEncryptBlkData(uint8_t *blkData) {
return 1; return 1;
} }
int CmdHFiClassEncryptBlk(const char *Cmd) { int CmdHFiClassEncryptBlk(const char *Cmd)
{
uint8_t blkData[8] = {0}; uint8_t blkData[8] = {0};
char opt = tolower(param_getchar(Cmd, 0)); char opt = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || opt == 'h') return usage_hf_iclass_encrypt(); if (strlen(Cmd) < 1 || opt == 'h') return usage_hf_iclass_encrypt();
@ -820,14 +853,16 @@ int CmdHFiClassEncryptBlk(const char *Cmd) {
return 1; return 1;
} }
void Calc_wb_mac(uint8_t blockno, uint8_t *data, uint8_t *div_key, uint8_t MAC[4]) { void Calc_wb_mac(uint8_t blockno, uint8_t *data, uint8_t *div_key, uint8_t MAC[4])
{
uint8_t wb[9]; uint8_t wb[9];
wb[0] = blockno; wb[0] = blockno;
memcpy(wb + 1, data, 8); memcpy(wb + 1, data, 8);
doMAC_N(wb, sizeof(wb), div_key, MAC); doMAC_N(wb, sizeof(wb), div_key, MAC);
} }
static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool use_credit_key, bool verbose) { static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool use_credit_key, bool verbose)
{
UsbCommand resp; UsbCommand resp;
UsbCommand c = {CMD_READER_ICLASS, {0}}; UsbCommand c = {CMD_READER_ICLASS, {0}};
c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE | FLAG_ICLASS_READER_CC | FLAG_ICLASS_READER_ONE_TRY; c.arg[0] = FLAG_ICLASS_READER_ONLY_ONCE | FLAG_ICLASS_READER_CC | FLAG_ICLASS_READER_ONE_TRY;
@ -862,7 +897,8 @@ static bool select_only(uint8_t *CSN, uint8_t *CCNR, bool use_credit_key, bool v
return true; return true;
} }
static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool use_credit_key, bool elite, bool rawkey, bool verbose) { static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool use_credit_key, bool elite, bool rawkey, bool verbose)
{
uint8_t CSN[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t CSN[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t CCNR[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t CCNR[12] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@ -896,7 +932,8 @@ static bool select_and_auth(uint8_t *KEY, uint8_t *MAC, uint8_t *div_key, bool u
return true; return true;
} }
int CmdHFiClassReader_Dump(const char *Cmd) { int CmdHFiClassReader_Dump(const char *Cmd)
{
uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00}; uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00};
uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@ -1046,9 +1083,11 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&w); SendCommand(&w);
while (true) { while (true) {
printf("."); fflush(stdout); printf(".");
fflush(stdout);
if (ukbhit()) { if (ukbhit()) {
int gc = getchar(); (void)gc; int gc = getchar();
(void)gc;
PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n"); PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n");
DropField(); DropField();
return 0; return 0;
@ -1150,7 +1189,8 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
return 1; return 1;
} }
static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_credit_key, bool elite, bool rawkey, bool verbose) { static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_credit_key, bool elite, bool rawkey, bool verbose)
{
uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00}; uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00};
uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose)) if (!select_and_auth(KEY, MAC, div_key, use_credit_key, elite, rawkey, verbose))
@ -1177,7 +1217,8 @@ static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_c
return isOK; return isOK;
} }
int CmdHFiClass_WriteBlock(const char *Cmd) { int CmdHFiClass_WriteBlock(const char *Cmd)
{
uint8_t blockno = 0; uint8_t blockno = 0;
uint8_t bldata[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t bldata[8] = {0, 0, 0, 0, 0, 0, 0, 0};
uint8_t KEY[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t KEY[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@ -1255,7 +1296,8 @@ int CmdHFiClass_WriteBlock(const char *Cmd) {
return ans; return ans;
} }
int CmdHFiClassCloneTag(const char *Cmd) { int CmdHFiClassCloneTag(const char *Cmd)
{
char filename[FILE_PATH_SIZE] = { 0x00 }; char filename[FILE_PATH_SIZE] = { 0x00 };
char tempStr[50] = {0}; char tempStr[50] = {0};
uint8_t KEY[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t KEY[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@ -1407,7 +1449,8 @@ int CmdHFiClassCloneTag(const char *Cmd) {
return 1; return 1;
} }
static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, bool rawkey, bool verbose, bool auth) { static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, bool rawkey, bool verbose, bool auth)
{
uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00}; uint8_t MAC[4] = {0x00, 0x00, 0x00, 0x00};
uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@ -1441,7 +1484,8 @@ static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite,
return 1; return 1;
} }
int CmdHFiClass_ReadBlock(const char *Cmd) { int CmdHFiClass_ReadBlock(const char *Cmd)
{
uint8_t blockno = 0; uint8_t blockno = 0;
uint8_t keyType = 0x88; //debit key uint8_t keyType = 0x88; //debit key
uint8_t KEY[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t KEY[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@ -1513,7 +1557,8 @@ int CmdHFiClass_ReadBlock(const char *Cmd) {
return ReadBlock(KEY, blockno, keyType, elite, rawkey, verbose, auth); return ReadBlock(KEY, blockno, keyType, elite, rawkey, verbose, auth);
} }
int CmdHFiClass_loclass(const char *Cmd) { int CmdHFiClass_loclass(const char *Cmd)
{
char opt = tolower(param_getchar(Cmd, 0)); char opt = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || opt == 'h') if (strlen(Cmd) < 1 || opt == 'h')
@ -1527,8 +1572,7 @@ int CmdHFiClass_loclass(const char *Cmd) {
PrintAndLogEx(WARNING, "You must specify a filename"); PrintAndLogEx(WARNING, "You must specify a filename");
return 0; return 0;
} }
} } else if (opt == 't') {
else if (opt == 't') {
int errors = testCipherUtils(); int errors = testCipherUtils();
errors += testMAC(); errors += testMAC();
errors += doKeyTests(0); errors += doKeyTests(0);
@ -1539,7 +1583,8 @@ int CmdHFiClass_loclass(const char *Cmd) {
return 0; return 0;
} }
void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize) { void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t endblock, size_t filesize)
{
uint8_t mem_config; uint8_t mem_config;
memcpy(&mem_config, iclass_dump + 13, 1); memcpy(&mem_config, iclass_dump + 13, 1);
uint8_t maxmemcount; uint8_t maxmemcount;
@ -1573,7 +1618,8 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e
PrintAndLogEx(NORMAL, "------+--+-------------------------+\n"); PrintAndLogEx(NORMAL, "------+--+-------------------------+\n");
} }
int CmdHFiClassReadTagFile(const char *Cmd) { int CmdHFiClassReadTagFile(const char *Cmd)
{
int startblock = 0; int startblock = 0;
int endblock = 0; int endblock = 0;
char tempnum[5]; char tempnum[5];
@ -1625,7 +1671,8 @@ int CmdHFiClassReadTagFile(const char *Cmd) {
return 0; return 0;
} }
void HFiClassCalcDivKey(uint8_t *CSN, uint8_t *KEY, uint8_t *div_key, bool elite){ void HFiClassCalcDivKey(uint8_t *CSN, uint8_t *KEY, uint8_t *div_key, bool elite)
{
uint8_t keytable[128] = {0}; uint8_t keytable[128] = {0};
uint8_t key_index[8] = {0}; uint8_t key_index[8] = {0};
if (elite) { if (elite) {
@ -1647,7 +1694,8 @@ void HFiClassCalcDivKey(uint8_t *CSN, uint8_t *KEY, uint8_t *div_key, bool elite
//when told CSN, oldkey, newkey, if new key is elite (elite), and if old key was elite (oldElite) //when told CSN, oldkey, newkey, if new key is elite (elite), and if old key was elite (oldElite)
//calculate and return xor_div_key (ready for a key write command) //calculate and return xor_div_key (ready for a key write command)
//print all div_keys if verbose //print all div_keys if verbose
static void HFiClassCalcNewKey(uint8_t *CSN, uint8_t *OLDKEY, uint8_t *NEWKEY, uint8_t *xor_div_key, bool elite, bool oldElite, bool verbose){ static void HFiClassCalcNewKey(uint8_t *CSN, uint8_t *OLDKEY, uint8_t *NEWKEY, uint8_t *xor_div_key, bool elite, bool oldElite, bool verbose)
{
uint8_t old_div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t old_div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t new_div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t new_div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
//get old div key //get old div key
@ -1665,7 +1713,8 @@ static void HFiClassCalcNewKey(uint8_t *CSN, uint8_t *OLDKEY, uint8_t *NEWKEY, u
} }
} }
int CmdHFiClassCalcNewKey(const char *Cmd) { int CmdHFiClassCalcNewKey(const char *Cmd)
{
uint8_t OLDKEY[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t OLDKEY[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t NEWKEY[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t NEWKEY[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t xor_div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t xor_div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@ -1748,7 +1797,8 @@ int CmdHFiClassCalcNewKey(const char *Cmd) {
return 0; return 0;
} }
static int loadKeys(char *filename) { static int loadKeys(char *filename)
{
FILE *f; FILE *f;
f = fopen(filename, "rb"); f = fopen(filename, "rb");
if (!f) { if (!f) {
@ -1787,7 +1837,8 @@ static int loadKeys(char *filename) {
return 1; return 1;
} }
static int saveKeys(char *filename) { static int saveKeys(char *filename)
{
FILE *f; FILE *f;
f = fopen(filename, "wb"); f = fopen(filename, "wb");
if (!f) { if (!f) {
@ -1804,7 +1855,8 @@ static int saveKeys(char *filename) {
return 0; return 0;
} }
static int printKeys(void) { static int printKeys(void)
{
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
for (uint8_t i = 0; i < ICLASS_KEYS_MAX; i++) for (uint8_t i = 0; i < ICLASS_KEYS_MAX; i++)
PrintAndLogEx(NORMAL, "%u: %s", i, sprint_hex(iClass_Key_Table[i], 8)); PrintAndLogEx(NORMAL, "%u: %s", i, sprint_hex(iClass_Key_Table[i], 8));
@ -1812,7 +1864,8 @@ static int printKeys(void) {
return 0; return 0;
} }
int CmdHFiClassManageKeys(const char *Cmd) { int CmdHFiClassManageKeys(const char *Cmd)
{
uint8_t keyNbr = 0; uint8_t keyNbr = 0;
uint8_t dataLen = 0; uint8_t dataLen = 0;
uint8_t KEY[8] = {0}; uint8_t KEY[8] = {0};
@ -1888,16 +1941,22 @@ int CmdHFiClassManageKeys(const char *Cmd) {
} }
switch (operation) { switch (operation) {
case 3: memcpy(iClass_Key_Table[keyNbr], KEY, 8); return 1; case 3:
case 4: return printKeys(); memcpy(iClass_Key_Table[keyNbr], KEY, 8);
case 5: return loadKeys(filename); return 1;
case 6: return saveKeys(filename); case 4:
return printKeys();
case 5:
return loadKeys(filename);
case 6:
return saveKeys(filename);
break; break;
} }
return 0; return 0;
} }
int CmdHFiClassCheckKeys(const char *Cmd) { int CmdHFiClassCheckKeys(const char *Cmd)
{
// empty string // empty string
if (strlen(Cmd) == 0) return usage_hf_iclass_chk(); if (strlen(Cmd) == 0) return usage_hf_iclass_chk();
@ -2016,7 +2075,8 @@ int CmdHFiClassCheckKeys(const char *Cmd) {
uint8_t timeout = 0; uint8_t timeout = 0;
if (ukbhit()) { if (ukbhit()) {
int gc = getchar(); (void)gc; int gc = getchar();
(void)gc;
PrintAndLogEx(WARNING, "\n[!] Aborted via keyboard!\n"); PrintAndLogEx(WARNING, "\n[!] Aborted via keyboard!\n");
goto out; goto out;
} }
@ -2041,7 +2101,8 @@ int CmdHFiClassCheckKeys(const char *Cmd) {
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
timeout++; timeout++;
printf("."); fflush(stdout); printf(".");
fflush(stdout);
if (timeout > 120) { if (timeout > 120) {
PrintAndLogEx(WARNING, "\nNo response from Proxmark. Aborting..."); PrintAndLogEx(WARNING, "\nNo response from Proxmark. Aborting...");
goto out; goto out;
@ -2077,7 +2138,8 @@ int CmdHFiClassCheckKeys(const char *Cmd) {
} }
case 99: { case 99: {
} }
default: break; default:
break;
} }
// both keys found. // both keys found.
@ -2099,7 +2161,8 @@ out:
return 0; return 0;
} }
static int cmp_uint32( const void *a, const void *b) { static int cmp_uint32(const void *a, const void *b)
{
const iclass_prekey_t *x = (const iclass_prekey_t *)a; const iclass_prekey_t *x = (const iclass_prekey_t *)a;
const iclass_prekey_t *y = (const iclass_prekey_t *)b; const iclass_prekey_t *y = (const iclass_prekey_t *)b;
@ -2115,7 +2178,8 @@ static int cmp_uint32( const void *a, const void *b) {
// this method tries to identify in which configuration mode a iClass / iClass SE reader is in. // this method tries to identify in which configuration mode a iClass / iClass SE reader is in.
// Standard or Elite / HighSecurity mode. It uses a default key dictionary list in order to work. // Standard or Elite / HighSecurity mode. It uses a default key dictionary list in order to work.
int CmdHFiClassLookUp(const char *Cmd) { int CmdHFiClassLookUp(const char *Cmd)
{
uint8_t CSN[8]; uint8_t CSN[8];
uint8_t EPURSE[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; uint8_t EPURSE[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
@ -2252,7 +2316,8 @@ int CmdHFiClassLookUp(const char *Cmd) {
return 0; return 0;
} }
int LoadDictionaryKeyFile( char* filename, uint8_t **keys, int *keycnt) { int LoadDictionaryKeyFile(char *filename, uint8_t **keys, int *keycnt)
{
char buf[17]; char buf[17];
FILE *f; FILE *f;
@ -2303,7 +2368,8 @@ int LoadDictionaryKeyFile( char* filename, uint8_t **keys, int *keycnt) {
} }
// precalc diversified keys and their MAC // precalc diversified keys and their MAC
int GenerateMacFromKeyFile( uint8_t* CSN, uint8_t* CCNR, bool use_raw, bool use_elite, uint8_t* keys, int keycnt, iclass_premac_t* list ) { int GenerateMacFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_premac_t *list)
{
uint8_t key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@ -2321,7 +2387,8 @@ int GenerateMacFromKeyFile( uint8_t* CSN, uint8_t* CCNR, bool use_raw, bool use_
return 0; return 0;
} }
int GenerateFromKeyFile( uint8_t* CSN, uint8_t* CCNR, bool use_raw, bool use_elite, uint8_t* keys, int keycnt, iclass_prekey_t* list ) { int GenerateFromKeyFile(uint8_t *CSN, uint8_t *CCNR, bool use_raw, bool use_elite, uint8_t *keys, int keycnt, iclass_prekey_t *list)
{
uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@ -2342,7 +2409,8 @@ int GenerateFromKeyFile( uint8_t* CSN, uint8_t* CCNR, bool use_raw, bool use_eli
} }
// print diversified keys // print diversified keys
void PrintPreCalcMac(uint8_t* keys, int keycnt, iclass_premac_t* pre_list) { void PrintPreCalcMac(uint8_t *keys, int keycnt, iclass_premac_t *pre_list)
{
iclass_prekey_t *b = calloc(keycnt, sizeof(iclass_prekey_t)); iclass_prekey_t *b = calloc(keycnt, sizeof(iclass_prekey_t));
if (!b) if (!b)
@ -2356,7 +2424,8 @@ void PrintPreCalcMac(uint8_t* keys, int keycnt, iclass_premac_t* pre_list) {
free(b); free(b);
} }
void PrintPreCalc(iclass_prekey_t* list, int itemcnt) { void PrintPreCalc(iclass_prekey_t *list, int itemcnt)
{
PrintAndLogEx(NORMAL, "-----+------------------+---------"); PrintAndLogEx(NORMAL, "-----+------------------+---------");
PrintAndLogEx(NORMAL, "#key | key | mac"); PrintAndLogEx(NORMAL, "#key | key | mac");
PrintAndLogEx(NORMAL, "-----+------------------+---------"); PrintAndLogEx(NORMAL, "-----+------------------+---------");
@ -2370,7 +2439,8 @@ void PrintPreCalc(iclass_prekey_t* list, int itemcnt) {
} }
} }
static void permute(uint8_t *data, uint8_t len, uint8_t *output){ static void permute(uint8_t *data, uint8_t len, uint8_t *output)
{
#define KEY_SIZE 8 #define KEY_SIZE 8
if (len > KEY_SIZE) { if (len > KEY_SIZE) {
@ -2395,12 +2465,14 @@ static void permute(uint8_t *data, uint8_t len, uint8_t *output){
output[i] = p; output[i] = p;
} }
} }
static void permute_rev(uint8_t *data, uint8_t len, uint8_t *output){ static void permute_rev(uint8_t *data, uint8_t len, uint8_t *output)
{
permute(data, len, output); permute(data, len, output);
permute(output, len, data); permute(output, len, data);
permute(data, len, output); permute(data, len, output);
} }
static void simple_crc(uint8_t *data, uint8_t len, uint8_t *output){ static void simple_crc(uint8_t *data, uint8_t len, uint8_t *output)
{
uint8_t crc = 0; uint8_t crc = 0;
for (uint8_t i = 0; i < len; ++i) { for (uint8_t i = 0; i < len; ++i) {
// seventh byte contains the crc. // seventh byte contains the crc.
@ -2414,11 +2486,13 @@ static void simple_crc(uint8_t *data, uint8_t len, uint8_t *output){
} }
} }
// DES doesn't use the MSB. // DES doesn't use the MSB.
static void shave(uint8_t *data, uint8_t len){ static void shave(uint8_t *data, uint8_t len)
{
for (uint8_t i = 0; i < len; ++i) for (uint8_t i = 0; i < len; ++i)
data[i] &= 0xFE; data[i] &= 0xFE;
} }
static void generate_rev(uint8_t *data, uint8_t len) { static void generate_rev(uint8_t *data, uint8_t len)
{
uint8_t *key = calloc(len, sizeof(uint8_t)); uint8_t *key = calloc(len, sizeof(uint8_t));
PrintAndLogEx(SUCCESS, "input permuted key | %s \n", sprint_hex(data, len)); PrintAndLogEx(SUCCESS, "input permuted key | %s \n", sprint_hex(data, len));
permute_rev(data, len, key); permute_rev(data, len, key);
@ -2427,7 +2501,8 @@ static void generate_rev(uint8_t *data, uint8_t len) {
PrintAndLogEx(SUCCESS, " key | %s \n", sprint_hex(key, len)); PrintAndLogEx(SUCCESS, " key | %s \n", sprint_hex(key, len));
free(key); free(key);
} }
static void generate(uint8_t *data, uint8_t len) { static void generate(uint8_t *data, uint8_t len)
{
uint8_t *key = calloc(len, sizeof(uint8_t)); uint8_t *key = calloc(len, sizeof(uint8_t));
uint8_t *pkey = calloc(len, sizeof(uint8_t)); uint8_t *pkey = calloc(len, sizeof(uint8_t));
PrintAndLogEx(SUCCESS, " input key | %s \n", sprint_hex(data, len)); PrintAndLogEx(SUCCESS, " input key | %s \n", sprint_hex(data, len));
@ -2439,7 +2514,8 @@ static void generate(uint8_t *data, uint8_t len) {
free(pkey); free(pkey);
} }
int CmdHFiClassPermuteKey(const char *Cmd) { int CmdHFiClassPermuteKey(const char *Cmd)
{
uint8_t key[8] = {0}; uint8_t key[8] = {0};
uint8_t key_std_format[8] = {0}; uint8_t key_std_format[8] = {0};
@ -2463,8 +2539,7 @@ int CmdHFiClassPermuteKey(const char *Cmd) {
generate_rev(data, len); generate_rev(data, len);
permutekey_rev(key, key_std_format); permutekey_rev(key, key_std_format);
PrintAndLogEx(SUCCESS, "holiman iclass key | %s \n", sprint_hex(key_std_format, 8)); PrintAndLogEx(SUCCESS, "holiman iclass key | %s \n", sprint_hex(key_std_format, 8));
} } else {
else {
generate(data, len); generate(data, len);
permutekey(key, key_iclass_format); permutekey(key, key_iclass_format);
PrintAndLogEx(SUCCESS, "holiman std key | %s \n", sprint_hex(key_iclass_format, 8)); PrintAndLogEx(SUCCESS, "holiman std key | %s \n", sprint_hex(key_iclass_format, 8));
@ -2496,13 +2571,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdHFiClass(const char *Cmd) { int CmdHFiClass(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -13,7 +13,8 @@ static int CmdHelp(const char *Cmd);
#define MAX_LENGTH 1024 #define MAX_LENGTH 1024
int usage_legic_calccrc(void){ int usage_legic_calccrc(void)
{
PrintAndLogEx(NORMAL, "Calculates the legic crc8/crc16 on the given data."); PrintAndLogEx(NORMAL, "Calculates the legic crc8/crc16 on the given data.");
PrintAndLogEx(NORMAL, "There must be an even number of hexsymbols as input."); PrintAndLogEx(NORMAL, "There must be an even number of hexsymbols as input.");
PrintAndLogEx(NORMAL, "Usage: hf legic crc [h] d <data> u <uidcrc> c <8|16>"); PrintAndLogEx(NORMAL, "Usage: hf legic crc [h] d <data> u <uidcrc> c <8|16>");
@ -28,7 +29,8 @@ int usage_legic_calccrc(void){
PrintAndLogEx(NORMAL, " hf legic crc d deadbeef1122 u 9A c 16"); PrintAndLogEx(NORMAL, " hf legic crc d deadbeef1122 u 9A c 16");
return 0; return 0;
} }
int usage_legic_rdmem(void){ int usage_legic_rdmem(void)
{
PrintAndLogEx(NORMAL, "Read data from a legic tag."); PrintAndLogEx(NORMAL, "Read data from a legic tag.");
PrintAndLogEx(NORMAL, "Usage: hf legic rdmem [h] <offset> <length> <IV>"); PrintAndLogEx(NORMAL, "Usage: hf legic rdmem [h] <offset> <length> <IV>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -43,7 +45,8 @@ int usage_legic_rdmem(void){
PrintAndLogEx(NORMAL, " hf legic rdmem 0 100 55 - reads 0x100 bytes with IV 0x55"); PrintAndLogEx(NORMAL, " hf legic rdmem 0 100 55 - reads 0x100 bytes with IV 0x55");
return 0; return 0;
} }
int usage_legic_sim(void){ int usage_legic_sim(void)
{
PrintAndLogEx(NORMAL, "Simulates a LEGIC Prime tag. MIM22, MIM256, MIM1024 types can be emulated"); PrintAndLogEx(NORMAL, "Simulates a LEGIC Prime tag. MIM22, MIM256, MIM1024 types can be emulated");
PrintAndLogEx(NORMAL, "Use ELOAD/ESAVE to upload a dump into emulator memory"); PrintAndLogEx(NORMAL, "Use ELOAD/ESAVE to upload a dump into emulator memory");
PrintAndLogEx(NORMAL, "Usage: hf legic sim [h] <tagtype>"); PrintAndLogEx(NORMAL, "Usage: hf legic sim [h] <tagtype>");
@ -57,7 +60,8 @@ int usage_legic_sim(void){
PrintAndLogEx(NORMAL, " hf legic sim 2"); PrintAndLogEx(NORMAL, " hf legic sim 2");
return 0; return 0;
} }
int usage_legic_write(void){ int usage_legic_write(void)
{
PrintAndLogEx(NORMAL, "Write data to a LEGIC Prime tag. It autodetects tagsize to make sure size"); PrintAndLogEx(NORMAL, "Write data to a LEGIC Prime tag. It autodetects tagsize to make sure size");
PrintAndLogEx(NORMAL, "Usage: hf legic write [h] o <offset> d <data (hex symbols)>"); PrintAndLogEx(NORMAL, "Usage: hf legic write [h] o <offset> d <data (hex symbols)>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -70,7 +74,8 @@ int usage_legic_write(void){
PrintAndLogEx(NORMAL, " hf legic write o 10 d 11223344 - Write 0x11223344 starting from offset 0x10"); PrintAndLogEx(NORMAL, " hf legic write o 10 d 11223344 - Write 0x11223344 starting from offset 0x10");
return 0; return 0;
} }
int usage_legic_reader(void){ int usage_legic_reader(void)
{
PrintAndLogEx(NORMAL, "Read UID and type information from a legic tag."); PrintAndLogEx(NORMAL, "Read UID and type information from a legic tag.");
PrintAndLogEx(NORMAL, "Usage: hf legic reader [h]"); PrintAndLogEx(NORMAL, "Usage: hf legic reader [h]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -80,7 +85,8 @@ int usage_legic_reader(void){
PrintAndLogEx(NORMAL, " hf legic reader"); PrintAndLogEx(NORMAL, " hf legic reader");
return 0; return 0;
} }
int usage_legic_info(void){ int usage_legic_info(void)
{
PrintAndLogEx(NORMAL, "Reads information from a legic prime tag."); PrintAndLogEx(NORMAL, "Reads information from a legic prime tag.");
PrintAndLogEx(NORMAL, "Shows systemarea, user areas etc"); PrintAndLogEx(NORMAL, "Shows systemarea, user areas etc");
PrintAndLogEx(NORMAL, "Usage: hf legic info [h]"); PrintAndLogEx(NORMAL, "Usage: hf legic info [h]");
@ -91,7 +97,8 @@ int usage_legic_info(void){
PrintAndLogEx(NORMAL, " hf legic info"); PrintAndLogEx(NORMAL, " hf legic info");
return 0; return 0;
} }
int usage_legic_dump(void){ int usage_legic_dump(void)
{
PrintAndLogEx(NORMAL, "Reads all pages from LEGIC Prime MIM22, MIM256, MIM1024"); PrintAndLogEx(NORMAL, "Reads all pages from LEGIC Prime MIM22, MIM256, MIM1024");
PrintAndLogEx(NORMAL, "and saves binary dump into the file `filename.bin` or `cardUID.bin`"); PrintAndLogEx(NORMAL, "and saves binary dump into the file `filename.bin` or `cardUID.bin`");
PrintAndLogEx(NORMAL, "It autodetects card type.\n"); PrintAndLogEx(NORMAL, "It autodetects card type.\n");
@ -105,7 +112,8 @@ int usage_legic_dump(void){
PrintAndLogEx(NORMAL, " hf legic dump o myfile"); PrintAndLogEx(NORMAL, " hf legic dump o myfile");
return 0; return 0;
} }
int usage_legic_restore(void){ int usage_legic_restore(void)
{
PrintAndLogEx(NORMAL, "Reads binary file and it autodetects card type and verifies that the file has the same size"); PrintAndLogEx(NORMAL, "Reads binary file and it autodetects card type and verifies that the file has the same size");
PrintAndLogEx(NORMAL, "Then write the data back to card. All bytes except the first 7bytes [UID(4) MCC(1) DCF(2)]\n"); PrintAndLogEx(NORMAL, "Then write the data back to card. All bytes except the first 7bytes [UID(4) MCC(1) DCF(2)]\n");
PrintAndLogEx(NORMAL, "Usage: hf legic restore [h] i <filename w/o .bin>"); PrintAndLogEx(NORMAL, "Usage: hf legic restore [h] i <filename w/o .bin>");
@ -117,7 +125,8 @@ int usage_legic_restore(void){
PrintAndLogEx(NORMAL, " hf legic restore i myfile"); PrintAndLogEx(NORMAL, " hf legic restore i myfile");
return 0; return 0;
} }
int usage_legic_eload(void){ int usage_legic_eload(void)
{
PrintAndLogEx(NORMAL, "It loads binary dump from the file `filename.bin`"); PrintAndLogEx(NORMAL, "It loads binary dump from the file `filename.bin`");
PrintAndLogEx(NORMAL, "Usage: hf legic eload [h] [card memory] <file name w/o `.bin`>"); PrintAndLogEx(NORMAL, "Usage: hf legic eload [h] [card memory] <file name w/o `.bin`>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -131,7 +140,8 @@ int usage_legic_eload(void){
PrintAndLogEx(NORMAL, " hf legic eload 2 myfile"); PrintAndLogEx(NORMAL, " hf legic eload 2 myfile");
return 0; return 0;
} }
int usage_legic_esave(void){ int usage_legic_esave(void)
{
PrintAndLogEx(NORMAL, "It saves binary dump into the file `filename.bin` or `cardID.bin`"); PrintAndLogEx(NORMAL, "It saves binary dump into the file `filename.bin` or `cardID.bin`");
PrintAndLogEx(NORMAL, " Usage: hf legic esave [h] [card memory] [file name w/o `.bin`]"); PrintAndLogEx(NORMAL, " Usage: hf legic esave [h] [card memory] [file name w/o `.bin`]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -145,7 +155,8 @@ int usage_legic_esave(void){
PrintAndLogEx(NORMAL, " hf legic esave 2 myfile"); PrintAndLogEx(NORMAL, " hf legic esave 2 myfile");
return 0; return 0;
} }
int usage_legic_wipe(void){ int usage_legic_wipe(void)
{
PrintAndLogEx(NORMAL, "Fills a legic tag memory with zeros. From byte7 and to the end."); PrintAndLogEx(NORMAL, "Fills a legic tag memory with zeros. From byte7 and to the end.");
PrintAndLogEx(NORMAL, " Usage: hf legic wipe [h]"); PrintAndLogEx(NORMAL, " Usage: hf legic wipe [h]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -160,7 +171,8 @@ int usage_legic_wipe(void){
* This is based on information given in the talk held * This is based on information given in the talk held
* by Henryk Ploetz and Karsten Nohl at 26c3 * by Henryk Ploetz and Karsten Nohl at 26c3
*/ */
int CmdLegicInfo(const char *Cmd) { int CmdLegicInfo(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_legic_info(); if (cmdp == 'h') return usage_legic_info();
@ -321,8 +333,7 @@ int CmdLegicInfo(const char *Cmd) {
i = 22; i = 22;
// decode segments // decode segments
for (segmentNum=1; segmentNum < 128; segmentNum++ ) for (segmentNum = 1; segmentNum < 128; segmentNum++) {
{
segment_len = ((data[i + 1] ^ crc) & 0x0f) * 256 + (data[i] ^ crc); segment_len = ((data[i + 1] ^ crc) & 0x0f) * 256 + (data[i] ^ crc);
segment_flag = ((data[i + 1] ^ crc) & 0xf0) >> 4; segment_flag = ((data[i + 1] ^ crc) & 0xf0) >> 4;
wrp = (data[i + 2] ^ crc); wrp = (data[i + 2] ^ crc);
@ -470,7 +481,8 @@ out:
// params: // params:
// offset in data memory // offset in data memory
// number of bytes to read // number of bytes to read
int CmdLegicRdmem(const char *Cmd) { int CmdLegicRdmem(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_legic_rdmem(); if (cmdp == 'h') return usage_legic_rdmem();
@ -504,7 +516,8 @@ int CmdLegicRdmem(const char *Cmd) {
return status; return status;
} }
int CmdLegicRfSim(const char *Cmd) { int CmdLegicRfSim(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_legic_sim(); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_legic_sim();
@ -516,7 +529,8 @@ int CmdLegicRfSim(const char *Cmd) {
return 0; return 0;
} }
int CmdLegicRfWrite(const char *Cmd) { int CmdLegicRfWrite(const char *Cmd)
{
uint8_t *data = NULL; uint8_t *data = NULL;
uint8_t cmdp = 0; uint8_t cmdp = 0;
@ -638,7 +652,8 @@ int CmdLegicRfWrite(const char *Cmd) {
uint8_t timeout = 0; uint8_t timeout = 0;
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
++timeout; ++timeout;
printf("."); fflush(stdout); printf(".");
fflush(stdout);
if (timeout > 7) { if (timeout > 7) {
PrintAndLogEx(WARNING, "\ncommand execution time out"); PrintAndLogEx(WARNING, "\ncommand execution time out");
return 1; return 1;
@ -655,7 +670,8 @@ int CmdLegicRfWrite(const char *Cmd) {
return 0; return 0;
} }
int CmdLegicCalcCrc(const char *Cmd){ int CmdLegicCalcCrc(const char *Cmd)
{
uint8_t *data = NULL; uint8_t *data = NULL;
uint8_t cmdp = 0, uidcrc = 0, type = 0; uint8_t cmdp = 0, uidcrc = 0, type = 0;
@ -737,7 +753,8 @@ int CmdLegicCalcCrc(const char *Cmd){
return 0; return 0;
} }
int legic_read_mem(uint32_t offset, uint32_t len, uint32_t iv, uint8_t *out, uint16_t *outlen) { int legic_read_mem(uint32_t offset, uint32_t len, uint32_t iv, uint8_t *out, uint16_t *outlen)
{
legic_chk_iv(&iv); legic_chk_iv(&iv);
@ -749,7 +766,8 @@ int legic_read_mem(uint32_t offset, uint32_t len, uint32_t iv, uint8_t *out, uin
uint8_t timeout = 0; uint8_t timeout = 0;
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
++timeout; ++timeout;
printf("."); fflush(stdout); printf(".");
fflush(stdout);
if (timeout > 7) { if (timeout > 7) {
PrintAndLogEx(WARNING, "\ncommand execution time out"); PrintAndLogEx(WARNING, "\ncommand execution time out");
return 1; return 1;
@ -775,7 +793,8 @@ int legic_read_mem(uint32_t offset, uint32_t len, uint32_t iv, uint8_t *out, uin
return 0; return 0;
} }
int legic_print_type(uint32_t tagtype, uint8_t spaces){ int legic_print_type(uint32_t tagtype, uint8_t spaces)
{
char spc[11] = " "; char spc[11] = " ";
spc[10] = 0x00; spc[10] = 0x00;
char *spacer = spc + (10 - spaces); char *spacer = spc + (10 - spaces);
@ -790,7 +809,8 @@ int legic_print_type(uint32_t tagtype, uint8_t spaces){
PrintAndLogEx(INFO, "%sTYPE : Unknown %06x", spacer, tagtype); PrintAndLogEx(INFO, "%sTYPE : Unknown %06x", spacer, tagtype);
return 0; return 0;
} }
int legic_get_type(legic_card_select_t *card){ int legic_get_type(legic_card_select_t *card)
{
if (card == NULL) return 1; if (card == NULL) return 1;
@ -808,7 +828,8 @@ int legic_get_type(legic_card_select_t *card){
memcpy(card, (legic_card_select_t *)resp.d.asBytes, sizeof(legic_card_select_t)); memcpy(card, (legic_card_select_t *)resp.d.asBytes, sizeof(legic_card_select_t));
return 0; return 0;
} }
void legic_chk_iv(uint32_t *iv){ void legic_chk_iv(uint32_t *iv)
{
if ((*iv & 0x7F) != *iv) { if ((*iv & 0x7F) != *iv) {
*iv &= 0x7F; *iv &= 0x7F;
PrintAndLogEx(INFO, "Truncating IV to 7bits, %u", *iv); PrintAndLogEx(INFO, "Truncating IV to 7bits, %u", *iv);
@ -819,7 +840,8 @@ void legic_chk_iv(uint32_t *iv){
PrintAndLogEx(INFO, "LSB of IV must be SET %u", *iv); PrintAndLogEx(INFO, "LSB of IV must be SET %u", *iv);
} }
} }
void legic_seteml(uint8_t *src, uint32_t offset, uint32_t numofbytes) { void legic_seteml(uint8_t *src, uint32_t offset, uint32_t numofbytes)
{
size_t len = 0; size_t len = 0;
UsbCommand c = {CMD_LEGIC_ESET, {0, 0, 0}}; UsbCommand c = {CMD_LEGIC_ESET, {0, 0, 0}};
@ -834,7 +856,8 @@ void legic_seteml(uint8_t *src, uint32_t offset, uint32_t numofbytes) {
} }
} }
int HFLegicReader(const char *Cmd, bool verbose) { int HFLegicReader(const char *Cmd, bool verbose)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_legic_reader(); if (cmdp == 'h') return usage_legic_reader();
@ -849,17 +872,20 @@ int HFLegicReader(const char *Cmd, bool verbose) {
case 3: case 3:
if (verbose) PrintAndLogEx(WARNING, "legic card select failed"); if (verbose) PrintAndLogEx(WARNING, "legic card select failed");
return 2; return 2;
default: break; default:
break;
} }
PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, sizeof(card.uid))); PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, sizeof(card.uid)));
legic_print_type(card.cardsize, 0); legic_print_type(card.cardsize, 0);
return 0; return 0;
} }
int CmdLegicReader(const char *Cmd){ int CmdLegicReader(const char *Cmd)
{
return HFLegicReader(Cmd, true); return HFLegicReader(Cmd, true);
} }
int CmdLegicDump(const char *Cmd){ int CmdLegicDump(const char *Cmd)
{
FILE *f; FILE *f;
char filename[FILE_PATH_SIZE] = {0x00}; char filename[FILE_PATH_SIZE] = {0x00};
@ -911,7 +937,8 @@ int CmdLegicDump(const char *Cmd){
uint8_t timeout = 0; uint8_t timeout = 0;
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
++timeout; ++timeout;
printf("."); fflush(stdout); printf(".");
fflush(stdout);
if (timeout > 7) { if (timeout > 7) {
PrintAndLogEx(WARNING, "\ncommand execution time out"); PrintAndLogEx(WARNING, "\ncommand execution time out");
return 1; return 1;
@ -963,7 +990,8 @@ int CmdLegicDump(const char *Cmd){
return 0; return 0;
} }
int CmdLegicRestore(const char *Cmd){ int CmdLegicRestore(const char *Cmd)
{
FILE *f; FILE *f;
char filename[FILE_PATH_SIZE] = {0x00}; char filename[FILE_PATH_SIZE] = {0x00};
@ -1066,7 +1094,8 @@ int CmdLegicRestore(const char *Cmd){
uint8_t timeout = 0; uint8_t timeout = 0;
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
++timeout; ++timeout;
printf("."); fflush(stdout); printf(".");
fflush(stdout);
if (timeout > 7) { if (timeout > 7) {
PrintAndLogEx(WARNING, "\ncommand execution time out"); PrintAndLogEx(WARNING, "\ncommand execution time out");
free(data); free(data);
@ -1089,7 +1118,8 @@ int CmdLegicRestore(const char *Cmd){
return 0; return 0;
} }
int CmdLegicELoad(const char *Cmd) { int CmdLegicELoad(const char *Cmd)
{
FILE *f; FILE *f;
char filename[FILE_PATH_SIZE]; char filename[FILE_PATH_SIZE];
char *fnameptr = filename; char *fnameptr = filename;
@ -1101,11 +1131,20 @@ int CmdLegicELoad(const char *Cmd) {
return usage_legic_eload(); return usage_legic_eload();
switch (cmdp) { switch (cmdp) {
case '0' : numofbytes = 22; break; case '0' :
numofbytes = 22;
break;
case '1' : case '1' :
case '\0': numofbytes = 256; break; case '\0':
case '2' : numofbytes = 1024; break; numofbytes = 256;
default : numofbytes = 256; nameParamNo = 0;break; break;
case '2' :
numofbytes = 1024;
break;
default :
numofbytes = 256;
nameParamNo = 0;
break;
} }
// set up buffer // set up buffer
@ -1150,7 +1189,8 @@ int CmdLegicELoad(const char *Cmd) {
return 0; return 0;
} }
int CmdLegicESave(const char *Cmd) { int CmdLegicESave(const char *Cmd)
{
char filename[FILE_PATH_SIZE]; char filename[FILE_PATH_SIZE];
char *fnameptr = filename; char *fnameptr = filename;
@ -1164,11 +1204,20 @@ int CmdLegicESave(const char *Cmd) {
return usage_legic_esave(); return usage_legic_esave();
switch (cmdp) { switch (cmdp) {
case '0' : numofbytes = 22; break; case '0' :
numofbytes = 22;
break;
case '1' : case '1' :
case '\0': numofbytes = 256; break; case '\0':
case '2' : numofbytes = 1024; break; numofbytes = 256;
default : numofbytes = 256; nameParamNo = 0; break; break;
case '2' :
numofbytes = 1024;
break;
default :
numofbytes = 256;
nameParamNo = 0;
break;
} }
fileNlen = param_getstr(Cmd, nameParamNo, filename, FILE_PATH_SIZE); fileNlen = param_getstr(Cmd, nameParamNo, filename, FILE_PATH_SIZE);
@ -1201,7 +1250,8 @@ int CmdLegicESave(const char *Cmd) {
return 0; return 0;
} }
int CmdLegicWipe(const char *Cmd){ int CmdLegicWipe(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
@ -1231,7 +1281,8 @@ int CmdLegicWipe(const char *Cmd){
UsbCommand resp; UsbCommand resp;
for (size_t i = 7; i < card.cardsize; i += USB_CMD_DATA_SIZE) { for (size_t i = 7; i < card.cardsize; i += USB_CMD_DATA_SIZE) {
printf("."); fflush(stdout); printf(".");
fflush(stdout);
len = MIN((card.cardsize - i), USB_CMD_DATA_SIZE); len = MIN((card.cardsize - i), USB_CMD_DATA_SIZE);
c.arg[0] = i; // offset c.arg[0] = i; // offset
c.arg[1] = len; // number of bytes c.arg[1] = len; // number of bytes
@ -1242,7 +1293,8 @@ int CmdLegicWipe(const char *Cmd){
uint8_t timeout = 0; uint8_t timeout = 0;
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
++timeout; ++timeout;
printf("."); fflush(stdout); printf(".");
fflush(stdout);
if (timeout > 7) { if (timeout > 7) {
PrintAndLogEx(WARNING, "\ncommand execution time out"); PrintAndLogEx(WARNING, "\ncommand execution time out");
free(data); free(data);
@ -1262,7 +1314,8 @@ int CmdLegicWipe(const char *Cmd){
return 0; return 0;
} }
int CmdLegicList(const char *Cmd) { int CmdLegicList(const char *Cmd)
{
CmdTraceList("legic"); CmdTraceList("legic");
return 0; return 0;
} }
@ -1284,13 +1337,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdHFLegic(const char *Cmd) { int CmdHFLegic(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -132,7 +132,8 @@ int CmdHF14ADesRb(const char *Cmd)
return 0; return 0;
} }
int CmdHF14ADesInfo(const char *Cmd){ int CmdHF14ADesInfo(const char *Cmd)
{
UsbCommand c = {CMD_MIFARE_DESFIRE_INFO}; UsbCommand c = {CMD_MIFARE_DESFIRE_INFO};
SendCommand(&c); SendCommand(&c);
@ -146,12 +147,15 @@ int CmdHF14ADesInfo(const char *Cmd){
if (!isOK) { if (!isOK) {
switch (resp.arg[1]) { switch (resp.arg[1]) {
case 1: case 1:
PrintAndLogEx(WARNING, "Can't select card"); break; PrintAndLogEx(WARNING, "Can't select card");
break;
case 2: case 2:
PrintAndLogEx(WARNING, "Card is most likely not Desfire. Its UID has wrong size"); break; PrintAndLogEx(WARNING, "Card is most likely not Desfire. Its UID has wrong size");
break;
case 3: case 3:
default: default:
PrintAndLogEx(WARNING, "Command unsuccessful"); break; PrintAndLogEx(WARNING, "Command unsuccessful");
break;
} }
return 0; return 0;
} }
@ -221,7 +225,8 @@ int CmdHF14ADesInfo(const char *Cmd){
and set to '1' if the storage size is between 2^n and 2^(n+1). and set to '1' if the storage size is between 2^n and 2^(n+1).
For this version of DESFire the 7 MSBits are set to 0x0C (2^12 = 4096) and the LSBit is '0'. For this version of DESFire the 7 MSBits are set to 0x0C (2^12 = 4096) and the LSBit is '0'.
*/ */
char * GetCardSizeStr( uint8_t fsize ){ char *GetCardSizeStr(uint8_t fsize)
{
static char buf[30] = {0x00}; static char buf[30] = {0x00};
char *retStr = buf; char *retStr = buf;
@ -237,7 +242,8 @@ char * GetCardSizeStr( uint8_t fsize ){
return buf; return buf;
} }
char * GetProtocolStr(uint8_t id){ char *GetProtocolStr(uint8_t id)
{
static char buf[30] = {0x00}; static char buf[30] = {0x00};
char *retStr = buf; char *retStr = buf;
@ -249,7 +255,8 @@ char * GetProtocolStr(uint8_t id){
return buf; return buf;
} }
char * GetVersionStr(uint8_t major, uint8_t minor){ char *GetVersionStr(uint8_t major, uint8_t minor)
{
static char buf[30] = {0x00}; static char buf[30] = {0x00};
char *retStr = buf; char *retStr = buf;
@ -265,7 +272,8 @@ char * GetVersionStr(uint8_t major, uint8_t minor){
return buf; return buf;
} }
void GetKeySettings( uint8_t *aid){ void GetKeySettings(uint8_t *aid)
{
char messStr[512] = {0x00}; char messStr[512] = {0x00};
char *str = messStr; char *str = messStr;
@ -416,8 +424,7 @@ void GetKeySettings( uint8_t *aid){
if (!isOK) { if (!isOK) {
PrintAndLogEx(WARNING, " Can't read Application Master key version. Trying all keys"); PrintAndLogEx(WARNING, " Can't read Application Master key version. Trying all keys");
numOfKeys = MAX_NUM_KEYS; numOfKeys = MAX_NUM_KEYS;
} } else {
else{
numOfKeys = resp.d.asBytes[4]; numOfKeys = resp.d.asBytes[4];
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, " Max number of keys : %d", numOfKeys); PrintAndLogEx(NORMAL, " Max number of keys : %d", numOfKeys);
@ -435,7 +442,8 @@ void GetKeySettings( uint8_t *aid){
} }
} }
int CmdHF14ADesEnumApplications(const char *Cmd){ int CmdHF14ADesEnumApplications(const char *Cmd)
{
uint8_t isOK = 0x00; uint8_t isOK = 0x00;
uint8_t aid[3]; uint8_t aid[3];
@ -546,7 +554,8 @@ int CmdHF14ADesEnumApplications(const char *Cmd){
// MIAFRE DesFire Authentication // MIAFRE DesFire Authentication
// //
#define BUFSIZE 256 #define BUFSIZE 256
int CmdHF14ADesAuth(const char *Cmd){ int CmdHF14ADesAuth(const char *Cmd)
{
// NR DESC KEYLENGHT // NR DESC KEYLENGHT
// ------------------------ // ------------------------
@ -574,8 +583,7 @@ int CmdHF14ADesAuth(const char *Cmd){
uint8_t cmdAuthAlgo = param_get8(Cmd, 1); uint8_t cmdAuthAlgo = param_get8(Cmd, 1);
uint8_t cmdKeyNo = param_get8(Cmd, 2); uint8_t cmdKeyNo = param_get8(Cmd, 2);
switch (cmdAuthMode) switch (cmdAuthMode) {
{
case 1: case 1:
if (cmdAuthAlgo != 1 && cmdAuthAlgo != 2) { if (cmdAuthAlgo != 1 && cmdAuthAlgo != 2) {
PrintAndLogEx(NORMAL, "Crypto algo not valid for the auth mode"); PrintAndLogEx(NORMAL, "Crypto algo not valid for the auth mode");
@ -665,14 +673,16 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdHFMFDes(const char *Cmd) { int CmdHFMFDes(const char *Cmd)
{
// flush // flush
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -29,7 +29,8 @@ static int CmdHelp(const char *Cmd);
//n'r=rol(r5) //n'r=rol(r5)
//verify n'r=nr //verify n'r=nr
int CmdHF14AMfDESAuth(const char *Cmd){ int CmdHF14AMfDESAuth(const char *Cmd)
{
uint8_t blockNo = 0; uint8_t blockNo = 0;
//keyNo=0; //keyNo=0;
@ -122,7 +123,8 @@ int CmdHF14AMfDESAuth(const char *Cmd){
// Card 2 Reader : 02AF, 16 Bytes(b0), CRC1 CRC2 // Card 2 Reader : 02AF, 16 Bytes(b0), CRC1 CRC2
// Reader 2 Card : 03AF, 16 Bytes(b1),16Bytes(b2) CRC1 CRC2 // Reader 2 Card : 03AF, 16 Bytes(b1),16Bytes(b2) CRC1 CRC2
// Card 2 Reader : 0300, 16 bytes(b3), CRC1 CRC2 ; success // Card 2 Reader : 0300, 16 bytes(b3), CRC1 CRC2 ; success
int CmdHF14AMfAESAuth(const char *Cmd){ int CmdHF14AMfAESAuth(const char *Cmd)
{
uint8_t blockNo = 0; uint8_t blockNo = 0;
//keyNo=0; //keyNo=0;
@ -228,8 +230,7 @@ int CmdHF14AMfAESAuth(const char *Cmd){
//------------------------------------ //------------------------------------
// Menu Stuff // Menu Stuff
//------------------------------------ //------------------------------------
static command_t CommandTable[] = static command_t CommandTable[] = {
{
{"help", CmdHelp, 1, "This help"}, {"help", CmdHelp, 1, "This help"},
{"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"}, {"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"},
{"des-auth", CmdHF14AMfDESAuth, 0, "Desfire Authentication"}, {"des-auth", CmdHF14AMfDESAuth, 0, "Desfire Authentication"},
@ -237,14 +238,16 @@ static command_t CommandTable[] =
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdHFMFDesfire(const char *Cmd){ int CmdHFMFDesfire(const char *Cmd)
{
// flush // flush
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd){ int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -72,7 +72,8 @@ static uint32_t test_state[2] = {0,0};
static float brute_force_per_second; static float brute_force_per_second;
static void get_SIMD_instruction_set(char* instruction_set) { static void get_SIMD_instruction_set(char *instruction_set)
{
switch (GetSIMDInstrAuto()) { switch (GetSIMDInstrAuto()) {
case SIMD_AVX512: case SIMD_AVX512:
strcpy(instruction_set, "AVX512F"); strcpy(instruction_set, "AVX512F");
@ -96,7 +97,8 @@ static void get_SIMD_instruction_set(char* instruction_set) {
} }
static void print_progress_header(void) { static void print_progress_header(void)
{
char progress_text[80]; char progress_text[80];
char instr_set[12] = ""; char instr_set[12] = "";
get_SIMD_instruction_set(instr_set); get_SIMD_instruction_set(instr_set);
@ -109,7 +111,8 @@ static void print_progress_header(void) {
} }
void hardnested_print_progress(uint32_t nonces, char *activity, float brute_force, uint64_t min_diff_print_time) { void hardnested_print_progress(uint32_t nonces, char *activity, float brute_force, uint64_t min_diff_print_time)
{
static uint64_t last_print_time = 0; static uint64_t last_print_time = 0;
if (msclock() - last_print_time > min_diff_print_time) { if (msclock() - last_print_time > min_diff_print_time) {
last_print_time = msclock(); last_print_time = msclock();
@ -327,7 +330,8 @@ static void init_bitflip_bitarrays(void)
j++; j++;
} else { } else {
all_effective_bitflip[num_all_effective_bitflips++] = effective_bitflip[EVEN_STATE][i]; all_effective_bitflip[num_all_effective_bitflips++] = effective_bitflip[EVEN_STATE][i];
i++; j++; i++;
j++;
} }
if (!(all_effective_bitflip[num_all_effective_bitflips - 1] & BITFLIP_2ND_BYTE)) { if (!(all_effective_bitflip[num_all_effective_bitflips - 1] & BITFLIP_2ND_BYTE)) {
num_1st_byte_effective_bitflips = num_all_effective_bitflips; num_1st_byte_effective_bitflips = num_all_effective_bitflips;
@ -877,7 +881,8 @@ static float check_smallest_bitflip_bitarrays(void)
} }
static void update_expected_brute_force(uint8_t best_byte) { static void update_expected_brute_force(uint8_t best_byte)
{
float total_prob = 0.0; float total_prob = 0.0;
for (uint8_t i = 0; i < NUM_SUMS; i++) { for (uint8_t i = 0; i < NUM_SUMS; i++) {
@ -1583,25 +1588,40 @@ static inline bool remaining_bits_match(uint_fast8_t num_common_bits, uint_fast8
if (odd_even) { if (odd_even) {
// odd bits // odd bits
switch (num_common_bits) { switch (num_common_bits) {
case 0: if (!invariant_holds(byte_diff, state1, state2, 1, 0)) return true; case 0:
case 1: if (invalid_state(byte_diff, state1, state2, 1, 0)) return false; if (!invariant_holds(byte_diff, state1, state2, 1, 0)) return true;
case 2: if (!invariant_holds(byte_diff, state1, state2, 3, 1)) return true; case 1:
case 3: if (invalid_state(byte_diff, state1, state2, 3, 1)) return false; if (invalid_state(byte_diff, state1, state2, 1, 0)) return false;
case 4: if (!invariant_holds(byte_diff, state1, state2, 5, 2)) return true; case 2:
case 5: if (invalid_state(byte_diff, state1, state2, 5, 2)) return false; if (!invariant_holds(byte_diff, state1, state2, 3, 1)) return true;
case 6: if (!invariant_holds(byte_diff, state1, state2, 7, 3)) return true; case 3:
case 7: if (invalid_state(byte_diff, state1, state2, 7, 3)) return false; if (invalid_state(byte_diff, state1, state2, 3, 1)) return false;
case 4:
if (!invariant_holds(byte_diff, state1, state2, 5, 2)) return true;
case 5:
if (invalid_state(byte_diff, state1, state2, 5, 2)) return false;
case 6:
if (!invariant_holds(byte_diff, state1, state2, 7, 3)) return true;
case 7:
if (invalid_state(byte_diff, state1, state2, 7, 3)) return false;
} }
} else { } else {
// even bits // even bits
switch (num_common_bits) { switch (num_common_bits) {
case 0: if (invalid_state(byte_diff, state1, state2, 0, 0)) return false; case 0:
case 1: if (!invariant_holds(byte_diff, state1, state2, 2, 1)) return true; if (invalid_state(byte_diff, state1, state2, 0, 0)) return false;
case 2: if (invalid_state(byte_diff, state1, state2, 2, 1)) return false; case 1:
case 3: if (!invariant_holds(byte_diff, state1, state2, 4, 2)) return true; if (!invariant_holds(byte_diff, state1, state2, 2, 1)) return true;
case 4: if (invalid_state(byte_diff, state1, state2, 4, 2)) return false; case 2:
case 5: if (!invariant_holds(byte_diff, state1, state2, 6, 3)) return true; if (invalid_state(byte_diff, state1, state2, 2, 1)) return false;
case 6: if (invalid_state(byte_diff, state1, state2, 6, 3)) return false; case 3:
if (!invariant_holds(byte_diff, state1, state2, 4, 2)) return true;
case 4:
if (invalid_state(byte_diff, state1, state2, 4, 2)) return false;
case 5:
if (!invariant_holds(byte_diff, state1, state2, 6, 3)) return true;
case 6:
if (invalid_state(byte_diff, state1, state2, 6, 3)) return false;
} }
} }
@ -1690,7 +1710,8 @@ static uint_fast8_t reverse(uint_fast8_t b)
static bool all_bitflips_match(uint8_t byte, uint32_t state, odd_even_t odd_even) static bool all_bitflips_match(uint8_t byte, uint32_t state, odd_even_t odd_even)
{ {
uint32_t masks[2][8] = {{0x00fffff0, 0x00fffff8, 0x00fffff8, 0x00fffffc, 0x00fffffc, 0x00fffffe, 0x00fffffe, 0x00ffffff}, uint32_t masks[2][8] = {{0x00fffff0, 0x00fffff8, 0x00fffff8, 0x00fffffc, 0x00fffffc, 0x00fffffe, 0x00fffffe, 0x00ffffff},
{0x00fffff0, 0x00fffff0, 0x00fffff8, 0x00fffff8, 0x00fffffc, 0x00fffffc, 0x00fffffe, 0x00fffffe} }; {0x00fffff0, 0x00fffff0, 0x00fffff8, 0x00fffff8, 0x00fffffc, 0x00fffffc, 0x00fffffe, 0x00fffffe}
};
for (uint16_t i = 1; i < 256; i++) { for (uint16_t i = 1; i < 256; i++) {
uint_fast8_t bytes_diff = reverse(i); // start with most common bits uint_fast8_t bytes_diff = reverse(i); // start with most common bits

View file

@ -33,7 +33,8 @@ static const uint8_t DefaultKey[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int CmdHFMFPInfo(const char *cmd) { int CmdHFMFPInfo(const char *cmd)
{
if (cmd && strlen(cmd) > 0) if (cmd && strlen(cmd) > 0)
PrintAndLogEx(WARNING, "command don't have any parameters.\n"); PrintAndLogEx(WARNING, "command don't have any parameters.\n");
@ -112,7 +113,8 @@ int CmdHFMFPInfo(const char *cmd) {
return 0; return 0;
} }
int CmdHFMFPWritePerso(const char *cmd) { int CmdHFMFPWritePerso(const char *cmd)
{
uint8_t keyNum[64] = {0}; uint8_t keyNum[64] = {0};
int keyNumLen = 0; int keyNumLen = 0;
uint8_t key[64] = {0}; uint8_t key[64] = {0};
@ -178,7 +180,8 @@ int CmdHFMFPWritePerso(const char *cmd) {
uint16_t CardAddresses[] = {0x9000, 0x9001, 0x9002, 0x9003, 0x9004, 0xA000, 0xA001, 0xA080, 0xA081, 0xC000, 0xC001}; uint16_t CardAddresses[] = {0x9000, 0x9001, 0x9002, 0x9003, 0x9004, 0xA000, 0xA001, 0xA080, 0xA081, 0xC000, 0xC001};
int CmdHFMFPInitPerso(const char *cmd) { int CmdHFMFPInitPerso(const char *cmd)
{
int res; int res;
uint8_t key[256] = {0}; uint8_t key[256] = {0};
int keyLen = 0; int keyLen = 0;
@ -252,7 +255,8 @@ int CmdHFMFPInitPerso(const char *cmd) {
return 0; return 0;
} }
int CmdHFMFPCommitPerso(const char *cmd) { int CmdHFMFPCommitPerso(const char *cmd)
{
CLIParserInit("hf mfp commitp", CLIParserInit("hf mfp commitp",
"Executes Commit Perso command. Can be used in SL0 mode only.", "Executes Commit Perso command. Can be used in SL0 mode only.",
"Usage:\n\thf mfp commitp -> \n"); "Usage:\n\thf mfp commitp -> \n");
@ -293,7 +297,8 @@ int CmdHFMFPCommitPerso(const char *cmd) {
return 0; return 0;
} }
int CmdHFMFPAuth(const char *cmd) { int CmdHFMFPAuth(const char *cmd)
{
uint8_t keyn[250] = {0}; uint8_t keyn[250] = {0};
int keynlen = 0; int keynlen = 0;
uint8_t key[250] = {0}; uint8_t key[250] = {0};
@ -331,7 +336,8 @@ int CmdHFMFPAuth(const char *cmd) {
return MifareAuth4(NULL, keyn, key, true, false, verbose); return MifareAuth4(NULL, keyn, key, true, false, verbose);
} }
int CmdHFMFPRdbl(const char *cmd) { int CmdHFMFPRdbl(const char *cmd)
{
uint8_t keyn[2] = {0}; uint8_t keyn[2] = {0};
uint8_t key[250] = {0}; uint8_t key[250] = {0};
int keylen = 0; int keylen = 0;
@ -443,7 +449,8 @@ int CmdHFMFPRdbl(const char *cmd) {
return 0; return 0;
} }
int CmdHFMFPRdsc(const char *cmd) { int CmdHFMFPRdsc(const char *cmd)
{
uint8_t keyn[2] = {0}; uint8_t keyn[2] = {0};
uint8_t key[250] = {0}; uint8_t key[250] = {0};
int keylen = 0; int keylen = 0;
@ -539,7 +546,8 @@ int CmdHFMFPRdsc(const char *cmd) {
return 0; return 0;
} }
int CmdHFMFPWrbl(const char *cmd) { int CmdHFMFPWrbl(const char *cmd)
{
uint8_t keyn[2] = {0}; uint8_t keyn[2] = {0};
uint8_t key[250] = {0}; uint8_t key[250] = {0};
int keylen = 0; int keylen = 0;
@ -641,7 +649,8 @@ int CmdHFMFPWrbl(const char *cmd) {
return 0; return 0;
} }
int CmdHFMFPMAD(const char *cmd) { int CmdHFMFPMAD(const char *cmd)
{
CLIParserInit("hf mfp mad", CLIParserInit("hf mfp mad",
"Checks and prints Mifare Application Directory (MAD)", "Checks and prints Mifare Application Directory (MAD)",
@ -735,7 +744,8 @@ int CmdHFMFPMAD(const char *cmd) {
return 0; return 0;
} }
int CmdHFMFPNDEF(const char *cmd) { int CmdHFMFPNDEF(const char *cmd)
{
CLIParserInit("hf mfp ndef", CLIParserInit("hf mfp ndef",
"Prints NFC Data Exchange Format (NDEF)", "Prints NFC Data Exchange Format (NDEF)",
@ -839,8 +849,7 @@ int CmdHFMFPNDEF(const char *cmd) {
return 0; return 0;
} }
static command_t CommandTable[] = static command_t CommandTable[] = {
{
{"help", CmdHelp, 1, "This help"}, {"help", CmdHelp, 1, "This help"},
{"info", CmdHFMFPInfo, 0, "Info about Mifare Plus tag"}, {"info", CmdHFMFPInfo, 0, "Info about Mifare Plus tag"},
{"wrp", CmdHFMFPWritePerso, 0, "Write Perso command"}, {"wrp", CmdHFMFPWritePerso, 0, "Write Perso command"},
@ -855,13 +864,15 @@ static command_t CommandTable[] =
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdHFMFP(const char *Cmd) { int CmdHFMFP(const char *Cmd)
{
(void)WaitForResponseTimeout(CMD_ACK, NULL, 100); (void)WaitForResponseTimeout(CMD_ACK, NULL, 100);
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -77,14 +77,14 @@ const uint32_t c_D[] = {
0x5728B869, 0x30726D5A 0x5728B869, 0x30726D5A
}; };
void transform_D(uint8_t* ru) { void transform_D(uint8_t *ru)
{
//Transform //Transform
uint8_t i; uint8_t i;
uint8_t p = 0; uint8_t p = 0;
uint32_t v1 = ((ru[3] << 24) | (ru[2] << 16) | (ru[1] << 8) | ru[0]) + c_D[p++]; uint32_t v1 = ((ru[3] << 24) | (ru[2] << 16) | (ru[1] << 8) | ru[0]) + c_D[p++];
uint32_t v2 = ((ru[7] << 24) | (ru[6] << 16) | (ru[5] << 8) | ru[4]) + c_D[p++]; uint32_t v2 = ((ru[7] << 24) | (ru[6] << 16) | (ru[5] << 8) | ru[4]) + c_D[p++];
for (i = 0; i < 12; i += 2) for (i = 0; i < 12; i += 2) {
{
uint32_t t1 = ROTL(v1 ^ v2, v2 & 0x1F) + c_D[p++]; uint32_t t1 = ROTL(v1 ^ v2, v2 & 0x1F) + c_D[p++];
uint32_t t2 = ROTL(v2 ^ t1, t1 & 0x1F) + c_D[p++]; uint32_t t2 = ROTL(v2 ^ t1, t1 & 0x1F) + c_D[p++];
v1 = ROTL(t1 ^ t2, t2 & 0x1F) + c_D[p++]; v1 = ROTL(t1 ^ t2, t2 & 0x1F) + c_D[p++];
@ -103,7 +103,8 @@ void transform_D(uint8_t* ru) {
} }
// Certain pwd generation algo nickname A. // Certain pwd generation algo nickname A.
uint32_t ul_ev1_pwdgenA(uint8_t* uid) { uint32_t ul_ev1_pwdgenA(uint8_t *uid)
{
uint8_t pos = (uid[3] ^ uid[4] ^ uid[5] ^ uid[6]) % 32; uint8_t pos = (uid[3] ^ uid[4] ^ uid[5] ^ uid[6]) % 32;
@ -128,7 +129,8 @@ uint32_t ul_ev1_pwdgenA(uint8_t* uid) {
} }
// Certain pwd generation algo nickname B. (very simple) // Certain pwd generation algo nickname B. (very simple)
uint32_t ul_ev1_pwdgenB(uint8_t* uid) { uint32_t ul_ev1_pwdgenB(uint8_t *uid)
{
uint8_t pwd[] = {0x00, 0x00, 0x00, 0x00}; uint8_t pwd[] = {0x00, 0x00, 0x00, 0x00};
@ -140,7 +142,8 @@ uint32_t ul_ev1_pwdgenB(uint8_t* uid) {
} }
// Certain pwd generation algo nickname C. // Certain pwd generation algo nickname C.
uint32_t ul_ev1_pwdgenC(uint8_t* uid){ uint32_t ul_ev1_pwdgenC(uint8_t *uid)
{
uint32_t pwd = 0; uint32_t pwd = 0;
uint8_t base[] = { uint8_t base[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x28, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x28,
@ -159,7 +162,8 @@ uint32_t ul_ev1_pwdgenC(uint8_t* uid){
} }
// Certain pwd generation algo nickname D. // Certain pwd generation algo nickname D.
// a.k.a xzy // a.k.a xzy
uint32_t ul_ev1_pwdgenD(uint8_t* uid){ uint32_t ul_ev1_pwdgenD(uint8_t *uid)
{
uint8_t i; uint8_t i;
//Rotate //Rotate
uint8_t r = (uid[1] + uid[3] + uid[5]) & 7; //Rotation offset uint8_t r = (uid[1] + uid[3] + uid[5]) & 7; //Rotation offset
@ -178,17 +182,21 @@ uint32_t ul_ev1_pwdgenD(uint8_t* uid){
return BSWAP_32(pwd); return BSWAP_32(pwd);
} }
// pack generation for algo 1-3 // pack generation for algo 1-3
uint16_t ul_ev1_packgenA(uint8_t* uid){ uint16_t ul_ev1_packgenA(uint8_t *uid)
{
uint16_t pack = (uid[0] ^ uid[1] ^ uid[2]) << 8 | (uid[2] ^ 8); uint16_t pack = (uid[0] ^ uid[1] ^ uid[2]) << 8 | (uid[2] ^ 8);
return pack; return pack;
} }
uint16_t ul_ev1_packgenB(uint8_t* uid){ uint16_t ul_ev1_packgenB(uint8_t *uid)
{
return 0x8080; return 0x8080;
} }
uint16_t ul_ev1_packgenC(uint8_t* uid){ uint16_t ul_ev1_packgenC(uint8_t *uid)
{
return 0xaa55; return 0xaa55;
} }
uint16_t ul_ev1_packgenD(uint8_t* uid){ uint16_t ul_ev1_packgenD(uint8_t *uid)
{
uint8_t i; uint8_t i;
//Rotate //Rotate
uint8_t r = (uid[2] + uid[5]) & 7; //Rotation offset uint8_t r = (uid[2] + uid[5]) & 7; //Rotation offset
@ -207,7 +215,8 @@ uint16_t ul_ev1_packgenD(uint8_t* uid){
return BSWAP_16(p & 0xFFFF); return BSWAP_16(p & 0xFFFF);
} }
int ul_ev1_pwdgen_selftest(){ int ul_ev1_pwdgen_selftest()
{
uint8_t uid1[] = {0x04, 0x11, 0x12, 0x11, 0x12, 0x11, 0x10}; uint8_t uid1[] = {0x04, 0x11, 0x12, 0x11, 0x12, 0x11, 0x10};
uint32_t pwd1 = ul_ev1_pwdgenA(uid1); uint32_t pwd1 = ul_ev1_pwdgenA(uid1);
@ -229,15 +238,22 @@ int ul_ev1_pwdgen_selftest(){
//------------------------------------ //------------------------------------
// get version nxp product type // get version nxp product type
char *getProductTypeStr( uint8_t id){ char *getProductTypeStr(uint8_t id)
{
static char buf[20]; static char buf[20];
char *retStr = buf; char *retStr = buf;
switch (id) { switch (id) {
case 3: sprintf(retStr, "%02X, Ultralight", id); break; case 3:
case 4: sprintf(retStr, "%02X, NTAG", id); break; sprintf(retStr, "%02X, Ultralight", id);
default: sprintf(retStr, "%02X, unknown", id); break; break;
case 4:
sprintf(retStr, "%02X, NTAG", id);
break;
default:
sprintf(retStr, "%02X, unknown", id);
break;
} }
return buf; return buf;
} }
@ -247,7 +263,8 @@ char *getProductTypeStr( uint8_t id){
the LSBit is set to '0' if the size is exactly 2^n the LSBit is set to '0' if the size is exactly 2^n
and set to '1' if the storage size is between 2^n and 2^(n+1). and set to '1' if the storage size is between 2^n and 2^(n+1).
*/ */
char *getUlev1CardSizeStr( uint8_t fsize ){ char *getUlev1CardSizeStr(uint8_t fsize)
{
static char buf[40]; static char buf[40];
char *retStr = buf; char *retStr = buf;
@ -264,13 +281,15 @@ char *getUlev1CardSizeStr( uint8_t fsize ){
return buf; return buf;
} }
static void ul_switch_on_field(void) { static void ul_switch_on_field(void)
{
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS, 0, 0}}; UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT | ISO14A_NO_RATS, 0, 0}};
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
} }
static int ul_send_cmd_raw( uint8_t *cmd, uint8_t cmdlen, uint8_t *response, uint16_t responseLength ) { static int ul_send_cmd_raw(uint8_t *cmd, uint8_t cmdlen, uint8_t *response, uint16_t responseLength)
{
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_APPEND_CRC | ISO14A_NO_RATS, cmdlen, 0}}; UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_APPEND_CRC | ISO14A_NO_RATS, cmdlen, 0}};
memcpy(c.d.asBytes, cmd, cmdlen); memcpy(c.d.asBytes, cmd, cmdlen);
clearCommandBuffer(); clearCommandBuffer();
@ -284,7 +303,8 @@ static int ul_send_cmd_raw( uint8_t *cmd, uint8_t cmdlen, uint8_t *response, uin
return resplen; return resplen;
} }
static int ul_select( iso14a_card_select_t *card ){ static int ul_select(iso14a_card_select_t *card)
{
ul_switch_on_field(); ul_switch_on_field();
@ -303,14 +323,16 @@ static int ul_select( iso14a_card_select_t *card ){
} }
// This read command will at least return 16bytes. // This read command will at least return 16bytes.
static int ul_read( uint8_t page, uint8_t *response, uint16_t responseLength ){ static int ul_read(uint8_t page, uint8_t *response, uint16_t responseLength)
{
uint8_t cmd[] = {ISO14443A_CMD_READBLOCK, page}; uint8_t cmd[] = {ISO14443A_CMD_READBLOCK, page};
int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength); int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
return len; return len;
} }
static int ul_comp_write( uint8_t page, uint8_t *data, uint8_t datalen ){ static int ul_comp_write(uint8_t page, uint8_t *data, uint8_t datalen)
{
uint8_t cmd[18]; uint8_t cmd[18];
memset(cmd, 0x00, sizeof(cmd)); memset(cmd, 0x00, sizeof(cmd));
@ -328,14 +350,16 @@ static int ul_comp_write( uint8_t page, uint8_t *data, uint8_t datalen ){
return -1; return -1;
} }
static int ulc_requestAuthentication( uint8_t *nonce, uint16_t nonceLength ){ static int ulc_requestAuthentication(uint8_t *nonce, uint16_t nonceLength)
{
uint8_t cmd[] = {MIFARE_ULC_AUTH_1, 0x00}; uint8_t cmd[] = {MIFARE_ULC_AUTH_1, 0x00};
int len = ul_send_cmd_raw(cmd, sizeof(cmd), nonce, nonceLength); int len = ul_send_cmd_raw(cmd, sizeof(cmd), nonce, nonceLength);
return len; return len;
} }
static int ulc_authentication( uint8_t *key, bool switch_off_field ){ static int ulc_authentication(uint8_t *key, bool switch_off_field)
{
UsbCommand c = {CMD_MIFAREUC_AUTH, {switch_off_field}}; UsbCommand c = {CMD_MIFAREUC_AUTH, {switch_off_field}};
memcpy(c.d.asBytes, key, 16); memcpy(c.d.asBytes, key, 16);
@ -348,7 +372,8 @@ static int ulc_authentication( uint8_t *key, bool switch_off_field ){
return 0; return 0;
} }
static int ulev1_requestAuthentication( uint8_t *pwd, uint8_t *pack, uint16_t packLength ){ static int ulev1_requestAuthentication(uint8_t *pwd, uint8_t *pack, uint16_t packLength)
{
uint8_t cmd[] = {MIFARE_ULEV1_AUTH, pwd[0], pwd[1], pwd[2], pwd[3]}; uint8_t cmd[] = {MIFARE_ULEV1_AUTH, pwd[0], pwd[1], pwd[2], pwd[3]};
int len = ul_send_cmd_raw(cmd, sizeof(cmd), pack, packLength); int len = ul_send_cmd_raw(cmd, sizeof(cmd), pack, packLength);
@ -359,7 +384,8 @@ static int ulev1_requestAuthentication( uint8_t *pwd, uint8_t *pack, uint16_t pa
return len; return len;
} }
static int ul_auth_select( iso14a_card_select_t *card, TagTypeUL_t tagtype, bool hasAuthKey, uint8_t *authkey, uint8_t *pack, uint8_t packSize){ static int ul_auth_select(iso14a_card_select_t *card, TagTypeUL_t tagtype, bool hasAuthKey, uint8_t *authkey, uint8_t *pack, uint8_t packSize)
{
if (hasAuthKey && (tagtype & UL_C)) { if (hasAuthKey && (tagtype & UL_C)) {
//will select card automatically and close connection on error //will select card automatically and close connection on error
if (!ulc_authentication(authkey, false)) { if (!ulc_authentication(authkey, false)) {
@ -380,27 +406,31 @@ static int ul_auth_select( iso14a_card_select_t *card, TagTypeUL_t tagtype, bool
return 1; return 1;
} }
static int ulev1_getVersion( uint8_t *response, uint16_t responseLength ){ static int ulev1_getVersion(uint8_t *response, uint16_t responseLength)
{
uint8_t cmd[] = {MIFARE_ULEV1_VERSION}; uint8_t cmd[] = {MIFARE_ULEV1_VERSION};
int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength); int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
return len; return len;
} }
static int ulev1_readCounter( uint8_t counter, uint8_t *response, uint16_t responseLength ){ static int ulev1_readCounter(uint8_t counter, uint8_t *response, uint16_t responseLength)
{
uint8_t cmd[] = {MIFARE_ULEV1_READ_CNT, counter}; uint8_t cmd[] = {MIFARE_ULEV1_READ_CNT, counter};
int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength); int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
return len; return len;
} }
static int ulev1_readTearing( uint8_t counter, uint8_t *response, uint16_t responseLength ){ static int ulev1_readTearing(uint8_t counter, uint8_t *response, uint16_t responseLength)
{
uint8_t cmd[] = {MIFARE_ULEV1_CHECKTEAR, counter}; uint8_t cmd[] = {MIFARE_ULEV1_CHECKTEAR, counter};
int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength); int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
return len; return len;
} }
static int ulev1_readSignature( uint8_t *response, uint16_t responseLength ){ static int ulev1_readSignature(uint8_t *response, uint16_t responseLength)
{
uint8_t cmd[] = {MIFARE_ULEV1_READSIG, 0x00}; uint8_t cmd[] = {MIFARE_ULEV1_READSIG, 0x00};
int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength); int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
@ -420,7 +450,8 @@ static int ulev1_readSignature( uint8_t *response, uint16_t responseLength ){
// UL responds with read of page 0, fudan doesn't respond. // UL responds with read of page 0, fudan doesn't respond.
// //
// make sure field is off before calling this function // make sure field is off before calling this function
static int ul_fudan_check( void ){ static int ul_fudan_check(void)
{
iso14a_card_select_t card; iso14a_card_select_t card;
if (!ul_select(&card)) if (!ul_select(&card))
return UL_ERROR; return UL_ERROR;
@ -438,7 +469,8 @@ static int ul_fudan_check( void ){
return (!resp.d.asBytes[0]) ? FUDAN_UL : UL; //if response == 0x00 then Fudan, else Genuine NXP return (!resp.d.asBytes[0]) ? FUDAN_UL : UL; //if response == 0x00 then Fudan, else Genuine NXP
} }
static int ul_print_default( uint8_t *data){ static int ul_print_default(uint8_t *data)
{
uint8_t uid[7]; uint8_t uid[7];
uid[0] = data[0]; uid[0] = data[0];
@ -454,9 +486,15 @@ static int ul_print_default( uint8_t *data){
if (uid[0] == 0x05 && ((uid[1] & 0xf0) >> 4) == 2) { // is infineon and 66RxxP if (uid[0] == 0x05 && ((uid[1] & 0xf0) >> 4) == 2) { // is infineon and 66RxxP
uint8_t chip = (data[8] & 0xC7); // 11000111 mask, bit 3,4,5 RFU uint8_t chip = (data[8] & 0xC7); // 11000111 mask, bit 3,4,5 RFU
switch (chip) { switch (chip) {
case 0xc2: PrintAndLogEx(NORMAL, " IC type : SLE 66R04P 770 Bytes"); break; //77 pages case 0xc2:
case 0xc4: PrintAndLogEx(NORMAL, " IC type : SLE 66R16P 2560 Bytes"); break; //256 pages PrintAndLogEx(NORMAL, " IC type : SLE 66R04P 770 Bytes");
case 0xc6: PrintAndLogEx(NORMAL, " IC type : SLE 66R32P 5120 Bytes"); break; //512 pages /2 sectors break; //77 pages
case 0xc4:
PrintAndLogEx(NORMAL, " IC type : SLE 66R16P 2560 Bytes");
break; //256 pages
case 0xc6:
PrintAndLogEx(NORMAL, " IC type : SLE 66R32P 5120 Bytes");
break; //512 pages /2 sectors
} }
} }
// CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2 // CT (cascade tag byte) 0x88 xor SN0 xor SN1 xor SN2
@ -487,7 +525,8 @@ static int ul_print_default( uint8_t *data){
return 0; return 0;
} }
static int ndef_print_CC(uint8_t *data) { static int ndef_print_CC(uint8_t *data)
{
// no NDEF message // no NDEF message
if (data[0] != 0xE1) if (data[0] != 0xE1)
return -1; return -1;
@ -512,7 +551,8 @@ static int ndef_print_CC(uint8_t *data) {
return 0; return 0;
} }
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;
char *spacer = spc + (10 - spaces); char *spacer = spc + (10 - spaces);
@ -572,7 +612,8 @@ int ul_print_type(uint32_t tagtype, uint8_t spaces){
return 0; return 0;
} }
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));
@ -581,7 +622,8 @@ static int ulc_print_3deskey( uint8_t *data){
return 0; return 0;
} }
static int ulc_print_configuration( uint8_t *data){ static int ulc_print_configuration(uint8_t *data)
{
PrintAndLogEx(NORMAL, "--- UL-C Configuration"); PrintAndLogEx(NORMAL, "--- UL-C Configuration");
PrintAndLogEx(NORMAL, " Higher Lockbits [40/0x28] : %s - %s", sprint_hex(data, 4), sprint_bin(data, 2)); PrintAndLogEx(NORMAL, " Higher Lockbits [40/0x28] : %s - %s", sprint_hex(data, 4), sprint_bin(data, 2));
@ -604,7 +646,8 @@ static int ulc_print_configuration( uint8_t *data){
return 0; return 0;
} }
static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t startPage){ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t startPage)
{
PrintAndLogEx(NORMAL, "\n--- Tag Configuration"); PrintAndLogEx(NORMAL, "\n--- Tag Configuration");
@ -626,36 +669,62 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st
uint8_t fdp_conf = (data[0] & 0x03); uint8_t fdp_conf = (data[0] & 0x03);
switch (mirror_conf) { switch (mirror_conf) {
case 0: PrintAndLogEx(NORMAL, " - no ASCII mirror"); break; case 0:
case 1: PrintAndLogEx(NORMAL, " - UID ASCII mirror"); break; PrintAndLogEx(NORMAL, " - no ASCII mirror");
case 2: PrintAndLogEx(NORMAL, " - NFC counter ASCII mirror"); break; break;
case 3: PrintAndLogEx(NORMAL, " - UID and NFC counter ASCII mirror"); break; case 1:
default: break; PrintAndLogEx(NORMAL, " - UID ASCII mirror");
break;
case 2:
PrintAndLogEx(NORMAL, " - NFC counter ASCII mirror");
break;
case 3:
PrintAndLogEx(NORMAL, " - UID and NFC counter ASCII mirror");
break;
default:
break;
} }
PrintAndLogEx(NORMAL, " - SLEEP mode %s", (sleep_en) ? "enabled" : "disabled"); PrintAndLogEx(NORMAL, " - SLEEP mode %s", (sleep_en) ? "enabled" : "disabled");
switch (fdp_conf) { switch (fdp_conf) {
case 0: PrintAndLogEx(NORMAL, " - no field detect"); break; case 0:
case 1: PrintAndLogEx(NORMAL, " - enabled by first State-of-Frame (start of communication)"); break; PrintAndLogEx(NORMAL, " - no field detect");
case 2: PrintAndLogEx(NORMAL, " - enabled by selection of the tag"); break; break;
case 3: PrintAndLogEx(NORMAL, " - enabled by field presence"); break; case 1:
default: break; PrintAndLogEx(NORMAL, " - enabled by first State-of-Frame (start of communication)");
break;
case 2:
PrintAndLogEx(NORMAL, " - enabled by selection of the tag");
break;
case 3:
PrintAndLogEx(NORMAL, " - enabled by field presence");
break;
default:
break;
} }
// valid mirror start page and byte position within start page. // valid mirror start page and byte position within start page.
if (tagtype & NTAG_213_F) { if (tagtype & NTAG_213_F) {
switch (mirror_conf) { switch (mirror_conf) {
case 1: { PrintAndLogEx(NORMAL, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, ( data[2]>= 0x4 && data[2] <= 0x24) ? "OK":"Invalid value"); break;} case 1:
case 2: { PrintAndLogEx(NORMAL, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, ( data[2]>= 0x4 && data[2] <= 0x26) ? "OK":"Invalid value"); break;} { PrintAndLogEx(NORMAL, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0x24) ? "OK" : "Invalid value"); break;}
case 3: { PrintAndLogEx(NORMAL, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, ( data[2]>= 0x4 && data[2] <= 0x22) ? "OK":"Invalid value"); break;} case 2:
default: break; { PrintAndLogEx(NORMAL, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0x26) ? "OK" : "Invalid value"); break;}
case 3:
{ PrintAndLogEx(NORMAL, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0x22) ? "OK" : "Invalid value"); break;}
default:
break;
} }
} else if (tagtype & NTAG_216_F) { } else if (tagtype & NTAG_216_F) {
switch (mirror_conf) { switch (mirror_conf) {
case 1: { PrintAndLogEx(NORMAL, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, ( data[2]>= 0x4 && data[2] <= 0xDE) ? "OK":"Invalid value"); break;} case 1:
case 2: { PrintAndLogEx(NORMAL, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, ( data[2]>= 0x4 && data[2] <= 0xE0) ? "OK":"Invalid value"); break;} { PrintAndLogEx(NORMAL, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0xDE) ? "OK" : "Invalid value"); break;}
case 3: { PrintAndLogEx(NORMAL, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, ( data[2]>= 0x4 && data[2] <= 0xDC) ? "OK":"Invalid value"); break;} case 2:
default: break; { PrintAndLogEx(NORMAL, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0xE0) ? "OK" : "Invalid value"); break;}
case 3:
{ PrintAndLogEx(NORMAL, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0xDC) ? "OK" : "Invalid value"); break;}
default:
break;
} }
} }
} }
@ -684,7 +753,8 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st
return 0; return 0;
} }
static int ulev1_print_counters(){ static int ulev1_print_counters()
{
PrintAndLogEx(NORMAL, "--- Tag Counters"); PrintAndLogEx(NORMAL, "--- Tag Counters");
uint8_t tear[1] = {0}; uint8_t tear[1] = {0};
uint8_t counter[3] = {0, 0, 0}; uint8_t counter[3] = {0, 0, 0};
@ -700,7 +770,8 @@ static int ulev1_print_counters(){
return len; return len;
} }
static int ulev1_print_signature( uint8_t *data, uint8_t len){ static int ulev1_print_signature(uint8_t *data, uint8_t len)
{
PrintAndLogEx(NORMAL, "\n--- Tag Signature"); PrintAndLogEx(NORMAL, "\n--- Tag Signature");
PrintAndLogEx(NORMAL, "IC signature public key name : NXP NTAG21x (2013)"); PrintAndLogEx(NORMAL, "IC signature public key name : NXP NTAG21x (2013)");
PrintAndLogEx(NORMAL, "IC signature public key value : %s", sprint_hex(public_ecda_key, PUBLIC_ECDA_KEYLEN)); PrintAndLogEx(NORMAL, "IC signature public key value : %s", sprint_hex(public_ecda_key, PUBLIC_ECDA_KEYLEN));
@ -712,7 +783,8 @@ static int ulev1_print_signature( uint8_t *data, uint8_t len){
return 0; return 0;
} }
static int ulev1_print_version(uint8_t *data){ static int ulev1_print_version(uint8_t *data)
{
PrintAndLogEx(NORMAL, "\n--- Tag Version"); PrintAndLogEx(NORMAL, "\n--- Tag Version");
PrintAndLogEx(NORMAL, " Raw bytes : %s", sprint_hex(data, 8)); PrintAndLogEx(NORMAL, " Raw bytes : %s", sprint_hex(data, 8));
PrintAndLogEx(NORMAL, " Vendor ID : %02X, %s", data[1], getTagInfo(data[1])); PrintAndLogEx(NORMAL, " Vendor ID : %02X, %s", data[1], getTagInfo(data[1]));
@ -752,7 +824,8 @@ static int ulc_magic_test(){
return returnValue; return returnValue;
} }
*/ */
static int ul_magic_test(){ static int ul_magic_test()
{
// Magic Ultralight tests // Magic Ultralight tests
// 1) take present UID, and try to write it back. OBSOLETE // 1) take present UID, and try to write it back. OBSOLETE
// 2) make a wrong length write to page0, and see if tag answers with ACK/NACK: // 2) make a wrong length write to page0, and see if tag answers with ACK/NACK:
@ -767,7 +840,8 @@ static int ul_magic_test(){
return 0; return 0;
} }
uint32_t GetHF14AMfU_Type(void){ uint32_t GetHF14AMfU_Type(void)
{
TagTypeUL_t tagtype = UNKNOWN; TagTypeUL_t tagtype = UNKNOWN;
iso14a_card_select_t card; iso14a_card_select_t card;
@ -812,10 +886,18 @@ uint32_t GetHF14AMfU_Type(void){
else if (version[2] == 0x03) { tagtype = UL_EV1; } else if (version[2] == 0x03) { tagtype = UL_EV1; }
break; break;
} }
case 0x01: tagtype = UL_C; break; case 0x01:
case 0x00: tagtype = UL; break; tagtype = UL_C;
case -1 : tagtype = (UL | UL_C | NTAG_203); break; // could be UL | UL_C magic tags break;
default : tagtype = UNKNOWN; break; case 0x00:
tagtype = UL;
break;
case -1 :
tagtype = (UL | UL_C | NTAG_203);
break; // could be UL | UL_C magic tags
default :
tagtype = UNKNOWN;
break;
} }
// UL vs UL-C vs ntag203 test // UL vs UL-C vs ntag203 test
@ -859,10 +941,18 @@ uint32_t GetHF14AMfU_Type(void){
uint8_t nib = (card.uid[1] & 0xf0) >> 4; uint8_t nib = (card.uid[1] & 0xf0) >> 4;
switch (nib) { switch (nib) {
// case 0: tagtype = SLE66R35E7; break; //or SLE 66R35E7 - mifare compat... should have different sak/atqa for mf 1k // case 0: tagtype = SLE66R35E7; break; //or SLE 66R35E7 - mifare compat... should have different sak/atqa for mf 1k
case 1: tagtype = MY_D; break; // or SLE 66RxxS ... up to 512 pages of 8 user bytes... case 1:
case 2: tagtype = (MY_D_NFC); break; // or SLE 66RxxP ... up to 512 pages of 8 user bytes... (or in nfc mode FF pages of 4 bytes) tagtype = MY_D;
case 3: tagtype = (MY_D_MOVE | MY_D_MOVE_NFC); break; // or SLE 66R01P // 38 pages of 4 bytes //notice: we can not currently distinguish between these two break; // or SLE 66RxxS ... up to 512 pages of 8 user bytes...
case 7: tagtype = MY_D_MOVE_LEAN; break; // or SLE 66R01L // 16 pages of 4 bytes case 2:
tagtype = (MY_D_NFC);
break; // or SLE 66RxxP ... up to 512 pages of 8 user bytes... (or in nfc mode FF pages of 4 bytes)
case 3:
tagtype = (MY_D_MOVE | MY_D_MOVE_NFC);
break; // or SLE 66R01P // 38 pages of 4 bytes //notice: we can not currently distinguish between these two
case 7:
tagtype = MY_D_MOVE_LEAN;
break; // or SLE 66R01L // 16 pages of 4 bytes
} }
} }
@ -873,7 +963,8 @@ uint32_t GetHF14AMfU_Type(void){
// //
// extended tag information // extended tag information
// //
int CmdHF14AMfUInfo(const char *Cmd){ int CmdHF14AMfUInfo(const char *Cmd)
{
uint8_t authlim = 0xff; uint8_t authlim = 0xff;
uint8_t data[16] = {0x00}; uint8_t data[16] = {0x00};
@ -1138,7 +1229,8 @@ out:
// //
// Write Single Block // Write Single Block
// //
int CmdHF14AMfUWrBl(const char *Cmd){ int CmdHF14AMfUWrBl(const char *Cmd)
{
int blockNo = -1; int blockNo = -1;
bool errors = false; bool errors = false;
@ -1239,8 +1331,7 @@ int CmdHF14AMfUWrBl(const char *Cmd){
if (hasAuthKey) { if (hasAuthKey) {
c.arg[1] = 1; c.arg[1] = 1;
memcpy(c.d.asBytes + 4, authKeyPtr, 16); memcpy(c.d.asBytes + 4, authKeyPtr, 16);
} } else if (hasPwdKey) {
else if ( hasPwdKey ) {
c.arg[1] = 2; c.arg[1] = 2;
memcpy(c.d.asBytes + 4, authKeyPtr, 4); memcpy(c.d.asBytes + 4, authKeyPtr, 4);
} }
@ -1260,7 +1351,8 @@ int CmdHF14AMfUWrBl(const char *Cmd){
// //
// Read Single Block // Read Single Block
// //
int CmdHF14AMfURdBl(const char *Cmd){ int CmdHF14AMfURdBl(const char *Cmd)
{
int blockNo = -1; int blockNo = -1;
bool errors = false; bool errors = false;
@ -1344,8 +1436,7 @@ int CmdHF14AMfURdBl(const char *Cmd){
if (hasAuthKey) { if (hasAuthKey) {
c.arg[1] = 1; c.arg[1] = 1;
memcpy(c.d.asBytes, authKeyPtr, 16); memcpy(c.d.asBytes, authKeyPtr, 16);
} } else if (hasPwdKey) {
else if ( hasPwdKey ) {
c.arg[1] = 2; c.arg[1] = 2;
memcpy(c.d.asBytes, authKeyPtr, 4); memcpy(c.d.asBytes, authKeyPtr, 4);
} }
@ -1360,8 +1451,7 @@ int CmdHF14AMfURdBl(const char *Cmd){
PrintAndLogEx(NORMAL, "\nBlock# | Data | Ascii"); PrintAndLogEx(NORMAL, "\nBlock# | Data | Ascii");
PrintAndLogEx(NORMAL, "-----------------------------"); PrintAndLogEx(NORMAL, "-----------------------------");
PrintAndLogEx(NORMAL, "%02d/0x%02X | %s| %s\n", blockNo, blockNo, sprint_hex(data, 4), sprint_ascii(data, 4)); PrintAndLogEx(NORMAL, "%02d/0x%02X | %s| %s\n", blockNo, blockNo, sprint_hex(data, 4), sprint_ascii(data, 4));
} } else {
else {
PrintAndLogEx(WARNING, "Failed reading block: (%02x)", isOK); PrintAndLogEx(WARNING, "Failed reading block: (%02x)", isOK);
} }
} else { } else {
@ -1370,7 +1460,8 @@ int CmdHF14AMfURdBl(const char *Cmd){
return 0; return 0;
} }
int usage_hf_mfu_info(void) { int usage_hf_mfu_info(void)
{
PrintAndLogEx(NORMAL, "It gathers information about the tag and tries to detect what kind it is."); PrintAndLogEx(NORMAL, "It gathers information about the tag and tries to detect what kind it is.");
PrintAndLogEx(NORMAL, "Sometimes the tags are locked down, and you may need a key to be able to read the information"); PrintAndLogEx(NORMAL, "Sometimes the tags are locked down, and you may need a key to be able to read the information");
PrintAndLogEx(NORMAL, "The following tags can be identified:\n"); PrintAndLogEx(NORMAL, "The following tags can be identified:\n");
@ -1389,7 +1480,8 @@ int usage_hf_mfu_info(void) {
return 0; return 0;
} }
int usage_hf_mfu_dump(void) { int usage_hf_mfu_dump(void)
{
PrintAndLogEx(NORMAL, "Reads all pages from Ultralight, Ultralight-C, Ultralight EV1"); PrintAndLogEx(NORMAL, "Reads all pages from Ultralight, Ultralight-C, Ultralight EV1");
PrintAndLogEx(NORMAL, "NTAG 203, NTAG 210, NTAG 212, NTAG 213, NTAG 215, NTAG 216"); PrintAndLogEx(NORMAL, "NTAG 203, NTAG 210, NTAG 212, NTAG 213, NTAG 215, NTAG 216");
PrintAndLogEx(NORMAL, "and saves binary dump into the file `filename.bin` or `cardUID.bin`"); PrintAndLogEx(NORMAL, "and saves binary dump into the file `filename.bin` or `cardUID.bin`");
@ -1410,7 +1502,8 @@ int usage_hf_mfu_dump(void) {
return 0; return 0;
} }
int usage_hf_mfu_restore(void){ int usage_hf_mfu_restore(void)
{
PrintAndLogEx(NORMAL, "Restore dumpfile onto card."); PrintAndLogEx(NORMAL, "Restore dumpfile onto card.");
PrintAndLogEx(NORMAL, "Usage: hf mfu restore [h] [l] [s] k <key> n <filename w/o .bin> "); PrintAndLogEx(NORMAL, "Usage: hf mfu restore [h] [l] [s] k <key> n <filename w/o .bin> ");
PrintAndLogEx(NORMAL, " Options :"); PrintAndLogEx(NORMAL, " Options :");
@ -1428,7 +1521,8 @@ int usage_hf_mfu_restore(void){
return 0; return 0;
} }
int usage_hf_mfu_rdbl(void) { int usage_hf_mfu_rdbl(void)
{
PrintAndLogEx(NORMAL, "Read a block and print. It autodetects card type.\n"); PrintAndLogEx(NORMAL, "Read a block and print. It autodetects card type.\n");
PrintAndLogEx(NORMAL, "Usage: hf mfu rdbl b <block number> k <key> l\n"); PrintAndLogEx(NORMAL, "Usage: hf mfu rdbl b <block number> k <key> l\n");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -1443,7 +1537,8 @@ int usage_hf_mfu_rdbl(void) {
return 0; return 0;
} }
int usage_hf_mfu_wrbl(void) { int usage_hf_mfu_wrbl(void)
{
PrintAndLogEx(NORMAL, "Write a block. It autodetects card type.\n"); PrintAndLogEx(NORMAL, "Write a block. It autodetects card type.\n");
PrintAndLogEx(NORMAL, "Usage: hf mfu wrbl b <block number> d <data> k <key> l\n"); PrintAndLogEx(NORMAL, "Usage: hf mfu wrbl b <block number> d <data> k <key> l\n");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -1458,7 +1553,8 @@ int usage_hf_mfu_wrbl(void) {
return 0; return 0;
} }
int usage_hf_mfu_eload(void) { int usage_hf_mfu_eload(void)
{
PrintAndLogEx(NORMAL, "It loads emul dump from the file `filename.eml`"); PrintAndLogEx(NORMAL, "It loads emul dump from the file `filename.eml`");
PrintAndLogEx(NORMAL, "Hint: See script dumptoemul-mfu.lua to convert the .bin to the eml"); PrintAndLogEx(NORMAL, "Hint: See script dumptoemul-mfu.lua to convert the .bin to the eml");
PrintAndLogEx(NORMAL, "Usage: hf mfu eload u <file name w/o `.eml`> [numblocks]"); PrintAndLogEx(NORMAL, "Usage: hf mfu eload u <file name w/o `.eml`> [numblocks]");
@ -1473,7 +1569,8 @@ int usage_hf_mfu_eload(void) {
return 0; return 0;
} }
int usage_hf_mfu_sim(void) { int usage_hf_mfu_sim(void)
{
PrintAndLogEx(NORMAL, "\nEmulating Ultralight tag from emulator memory\n"); PrintAndLogEx(NORMAL, "\nEmulating Ultralight tag from emulator memory\n");
PrintAndLogEx(NORMAL, "\nBe sure to load the emulator memory first!\n"); PrintAndLogEx(NORMAL, "\nBe sure to load the emulator memory first!\n");
PrintAndLogEx(NORMAL, "Usage: hf mfu sim t 7 u <uid>"); PrintAndLogEx(NORMAL, "Usage: hf mfu sim t 7 u <uid>");
@ -1489,7 +1586,8 @@ int usage_hf_mfu_sim(void) {
return 0; return 0;
} }
int usage_hf_mfu_ucauth(void) { int usage_hf_mfu_ucauth(void)
{
PrintAndLogEx(NORMAL, "Usage: hf mfu cauth k <key number>"); PrintAndLogEx(NORMAL, "Usage: hf mfu cauth k <key number>");
PrintAndLogEx(NORMAL, " 0 (default): 3DES standard key"); PrintAndLogEx(NORMAL, " 0 (default): 3DES standard key");
PrintAndLogEx(NORMAL, " 1 : all 0x00 key"); PrintAndLogEx(NORMAL, " 1 : all 0x00 key");
@ -1504,7 +1602,8 @@ int usage_hf_mfu_ucauth(void) {
return 0; return 0;
} }
int usage_hf_mfu_ucsetpwd(void) { int usage_hf_mfu_ucsetpwd(void)
{
PrintAndLogEx(NORMAL, "Usage: hf mfu setpwd <password (32 hex symbols)>"); PrintAndLogEx(NORMAL, "Usage: hf mfu setpwd <password (32 hex symbols)>");
PrintAndLogEx(NORMAL, " [password] - (32 hex symbols)"); PrintAndLogEx(NORMAL, " [password] - (32 hex symbols)");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
@ -1514,7 +1613,8 @@ int usage_hf_mfu_ucsetpwd(void) {
return 0; return 0;
} }
int usage_hf_mfu_ucsetuid(void) { int usage_hf_mfu_ucsetuid(void)
{
PrintAndLogEx(NORMAL, "Usage: hf mfu setuid <uid (14 hex symbols)>"); PrintAndLogEx(NORMAL, "Usage: hf mfu setuid <uid (14 hex symbols)>");
PrintAndLogEx(NORMAL, " [uid] - (14 hex symbols)"); PrintAndLogEx(NORMAL, " [uid] - (14 hex symbols)");
PrintAndLogEx(NORMAL, "\nThis only works for Magic Ultralight tags."); PrintAndLogEx(NORMAL, "\nThis only works for Magic Ultralight tags.");
@ -1525,7 +1625,8 @@ int usage_hf_mfu_ucsetuid(void) {
return 0; return 0;
} }
int usage_hf_mfu_gendiverse(void){ int usage_hf_mfu_gendiverse(void)
{
PrintAndLogEx(NORMAL, "Usage: hf mfu gen [h] [r] <uid (8 hex symbols)>"); PrintAndLogEx(NORMAL, "Usage: hf mfu gen [h] [r] <uid (8 hex symbols)>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : this help"); PrintAndLogEx(NORMAL, " h : this help");
@ -1538,7 +1639,8 @@ int usage_hf_mfu_gendiverse(void){
return 0; return 0;
} }
int usage_hf_mfu_pwdgen(void){ int usage_hf_mfu_pwdgen(void)
{
PrintAndLogEx(NORMAL, "Usage: hf mfu pwdgen [h|t] [r] <uid (14 hex symbols)>"); PrintAndLogEx(NORMAL, "Usage: hf mfu pwdgen [h|t] [r] <uid (14 hex symbols)>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : this help"); PrintAndLogEx(NORMAL, " h : this help");
@ -1553,11 +1655,13 @@ int usage_hf_mfu_pwdgen(void){
return 0; return 0;
} }
void printMFUdump(mfu_dump_t* card) { void printMFUdump(mfu_dump_t *card)
{
printMFUdumpEx(card, 255, 0); printMFUdumpEx(card, 255, 0);
} }
void printMFUdumpEx(mfu_dump_t* card, uint16_t pages, uint8_t startpage) { void printMFUdumpEx(mfu_dump_t *card, uint16_t pages, uint8_t startpage)
{
PrintAndLogEx(NORMAL, "\n*special* data\n"); PrintAndLogEx(NORMAL, "\n*special* data\n");
PrintAndLogEx(NORMAL, "\nDataType | Data | Ascii"); PrintAndLogEx(NORMAL, "\nDataType | Data | Ascii");
PrintAndLogEx(NORMAL, "----------+-------------------------+---------"); PrintAndLogEx(NORMAL, "----------+-------------------------+---------");
@ -1605,48 +1709,95 @@ void printMFUdumpEx(mfu_dump_t* card, uint16_t pages, uint8_t startpage) {
continue; continue;
} }
switch (i) { switch (i) {
case 3: lckbit = bit_stat[4]; break; case 3:
case 4: lckbit = bit_stat[3]; break; lckbit = bit_stat[4];
case 5: lckbit = bit_stat[2]; break; break;
case 6: lckbit = bit_stat[1]; break; case 4:
case 7: lckbit = bit_stat[0]; break; lckbit = bit_stat[3];
case 8: lckbit = bit_stat[15]; break; break;
case 9: lckbit = bit_stat[14]; break; case 5:
case 10: lckbit = bit_stat[13]; break; lckbit = bit_stat[2];
case 11: lckbit = bit_stat[12]; break; break;
case 12: lckbit = bit_stat[11]; break; case 6:
case 13: lckbit = bit_stat[10]; break; lckbit = bit_stat[1];
case 14: lckbit = bit_stat[9]; break; break;
case 15: lckbit = bit_stat[8]; break; case 7:
lckbit = bit_stat[0];
break;
case 8:
lckbit = bit_stat[15];
break;
case 9:
lckbit = bit_stat[14];
break;
case 10:
lckbit = bit_stat[13];
break;
case 11:
lckbit = bit_stat[12];
break;
case 12:
lckbit = bit_stat[11];
break;
case 13:
lckbit = bit_stat[10];
break;
case 14:
lckbit = bit_stat[9];
break;
case 15:
lckbit = bit_stat[8];
break;
case 16: case 16:
case 17: case 17:
case 18: case 18:
case 19: lckbit = bit_dyn[6]; break; case 19:
lckbit = bit_dyn[6];
break;
case 20: case 20:
case 21: case 21:
case 22: case 22:
case 23: lckbit = bit_dyn[5]; break; case 23:
lckbit = bit_dyn[5];
break;
case 24: case 24:
case 25: case 25:
case 26: case 26:
case 27: lckbit = bit_dyn[4]; break; case 27:
lckbit = bit_dyn[4];
break;
case 28: case 28:
case 29: case 29:
case 30: case 30:
case 31: lckbit = bit_dyn[2]; break; case 31:
lckbit = bit_dyn[2];
break;
case 32: case 32:
case 33: case 33:
case 34: case 34:
case 35: lckbit = bit_dyn[1]; break; case 35:
lckbit = bit_dyn[1];
break;
case 36: case 36:
case 37: case 37:
case 38: case 38:
case 39: lckbit = bit_dyn[0]; break; case 39:
case 40: lckbit = bit_dyn[12]; break; lckbit = bit_dyn[0];
case 41: lckbit = bit_dyn[11]; break; break;
case 42: lckbit = bit_dyn[10]; break; //auth0 case 40:
case 43: lckbit = bit_dyn[9]; break; //auth1 lckbit = bit_dyn[12];
default: break; break;
case 41:
lckbit = bit_dyn[11];
break;
case 42:
lckbit = bit_dyn[10];
break; //auth0
case 43:
lckbit = bit_dyn[9];
break; //auth1
default:
break;
} }
PrintAndLogEx(NORMAL, "%3d/0x%02X | %s| %d | %s", i + startpage, i + startpage, sprint_hex(data + i * 4, 4), lckbit, sprint_ascii(data + i * 4, 4)); PrintAndLogEx(NORMAL, "%3d/0x%02X | %s| %d | %s", i + startpage, i + startpage, sprint_hex(data + i * 4, 4), lckbit, sprint_ascii(data + i * 4, 4));
} }
@ -1656,7 +1807,8 @@ void printMFUdumpEx(mfu_dump_t* card, uint16_t pages, uint8_t startpage) {
// //
// Mifare Ultralight / Ultralight-C / Ultralight-EV1 // Mifare Ultralight / Ultralight-C / Ultralight-EV1
// Read and Dump Card Contents, using auto detection of tag size. // Read and Dump Card Contents, using auto detection of tag size.
int CmdHF14AMfUDump(const char *Cmd){ int CmdHF14AMfUDump(const char *Cmd)
{
uint8_t fileNameLen = 0; uint8_t fileNameLen = 0;
char filename[FILE_PATH_SIZE] = {0x00}; char filename[FILE_PATH_SIZE] = {0x00};
@ -1878,7 +2030,8 @@ int CmdHF14AMfUDump(const char *Cmd){
return 0; return 0;
} }
static void wait4response(uint8_t b){ static void wait4response(uint8_t b)
{
UsbCommand resp; UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) { if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
uint8_t isOK = resp.arg[0] & 0xff; uint8_t isOK = resp.arg[0] & 0xff;
@ -1892,7 +2045,8 @@ static void wait4response(uint8_t b){
// //
// Restore dump file onto tag // Restore dump file onto tag
// //
int CmdHF14AMfURestore(const char *Cmd){ int CmdHF14AMfURestore(const char *Cmd)
{
char tempStr[50] = {0}; char tempStr[50] = {0};
char filename[FILE_PATH_SIZE] = {0}; char filename[FILE_PATH_SIZE] = {0};
@ -2091,7 +2245,8 @@ int CmdHF14AMfURestore(const char *Cmd){
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
wait4response(b); wait4response(b);
printf("."); fflush(stdout); printf(".");
fflush(stdout);
} }
PrintAndLogEx(NORMAL, "\n"); PrintAndLogEx(NORMAL, "\n");
@ -2122,7 +2277,8 @@ int CmdHF14AMfURestore(const char *Cmd){
// //
// Load emulator with dump file // Load emulator with dump file
// //
int CmdHF14AMfUeLoad(const char *Cmd){ int CmdHF14AMfUeLoad(const char *Cmd)
{
char c = tolower(param_getchar(Cmd, 0)); char c = tolower(param_getchar(Cmd, 0));
if (c == 'h' || c == 0x00) return usage_hf_mfu_eload(); if (c == 'h' || c == 0x00) return usage_hf_mfu_eload();
return CmdHF14AMfELoad(Cmd); return CmdHF14AMfELoad(Cmd);
@ -2130,7 +2286,8 @@ int CmdHF14AMfUeLoad(const char *Cmd){
// //
// Simulate tag // Simulate tag
// //
int CmdHF14AMfUSim(const char *Cmd){ int CmdHF14AMfUSim(const char *Cmd)
{
char c = tolower(param_getchar(Cmd, 0)); char c = tolower(param_getchar(Cmd, 0));
if (c == 'h' || c == 0x00) return usage_hf_mfu_sim(); if (c == 'h' || c == 0x00) return usage_hf_mfu_sim();
return CmdHF14ASim(Cmd); return CmdHF14ASim(Cmd);
@ -2143,7 +2300,8 @@ int CmdHF14AMfUSim(const char *Cmd){
// //
// Ultralight C Authentication Demo {currently uses hard-coded key} // Ultralight C Authentication Demo {currently uses hard-coded key}
// //
int CmdHF14AMfucAuth(const char *Cmd){ int CmdHF14AMfucAuth(const char *Cmd)
{
uint8_t keyNo = 3; uint8_t keyNo = 3;
bool errors = false; bool errors = false;
@ -2270,7 +2428,8 @@ int CmdTestDES(const char * cmd)
// //
// Mifare Ultralight C - Set password // Mifare Ultralight C - Set password
// //
int CmdHF14AMfucSetPwd(const char *Cmd){ int CmdHF14AMfucSetPwd(const char *Cmd)
{
uint8_t pwd[16] = {0x00}; uint8_t pwd[16] = {0x00};
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
@ -2305,7 +2464,8 @@ int CmdHF14AMfucSetPwd(const char *Cmd){
// //
// Magic UL / UL-C tags - Set UID // Magic UL / UL-C tags - Set UID
// //
int CmdHF14AMfucSetUid(const char *Cmd){ int CmdHF14AMfucSetUid(const char *Cmd)
{
UsbCommand c = {CMD_MIFAREU_READBL}; UsbCommand c = {CMD_MIFAREU_READBL};
UsbCommand resp; UsbCommand resp;
@ -2374,7 +2534,8 @@ int CmdHF14AMfucSetUid(const char *Cmd){
return 0; return 0;
} }
int CmdHF14AMfuGenDiverseKeys(const char *Cmd){ int CmdHF14AMfuGenDiverseKeys(const char *Cmd)
{
uint8_t uid[4]; uint8_t uid[4];
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
@ -2405,8 +2566,7 @@ int CmdHF14AMfuGenDiverseKeys(const char *Cmd){
return 1; return 1;
} }
memcpy(uid, card.uid, sizeof(uid)); memcpy(uid, card.uid, sizeof(uid));
} } else {
else {
if (param_gethex(Cmd, 0, uid, 8)) return usage_hf_mfu_gendiverse(); if (param_gethex(Cmd, 0, uid, 8)) return usage_hf_mfu_gendiverse();
} }
@ -2488,7 +2648,8 @@ int CmdHF14AMfuGenDiverseKeys(const char *Cmd){
return 0; return 0;
} }
int CmdHF14AMfuPwdGen(const char *Cmd){ int CmdHF14AMfuPwdGen(const char *Cmd)
{
uint8_t uid[7] = {0x00}; uint8_t uid[7] = {0x00};
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
@ -2520,8 +2681,7 @@ int CmdHF14AMfuPwdGen(const char *Cmd){
return 1; return 1;
} }
memcpy(uid, card.uid, sizeof(uid)); memcpy(uid, card.uid, sizeof(uid));
} } else {
else {
if (param_gethex(Cmd, 0, uid, 14)) return usage_hf_mfu_pwdgen(); if (param_gethex(Cmd, 0, uid, 14)) return usage_hf_mfu_pwdgen();
} }
@ -2560,13 +2720,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdHFMFUltra(const char *Cmd){ int CmdHFMFUltra(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd){ int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -30,18 +30,21 @@ static struct {
dynamic_lock_area_t *dynamic_lock_areas; // lock area descriptors dynamic_lock_area_t *dynamic_lock_areas; // lock area descriptors
} topaz_tag; } topaz_tag;
static void topaz_switch_on_field(void) { static void topaz_switch_on_field(void)
{
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_SELECT | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE | ISO14A_NO_RATS, 0, 0}}; UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_SELECT | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE | ISO14A_NO_RATS, 0, 0}};
SendCommand(&c); SendCommand(&c);
} }
static void topaz_switch_off_field(void) { static void topaz_switch_off_field(void)
{
UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}}; UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}};
SendCommand(&c); SendCommand(&c);
} }
// send a raw topaz command, returns the length of the response (0 in case of error) // send a raw topaz command, returns the length of the response (0 in case of error)
static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response) { static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response)
{
UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE | ISO14A_NO_RATS, len, 0}}; UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_RAW | ISO14A_NO_DISCONNECT | ISO14A_TOPAZMODE | ISO14A_NO_RATS, len, 0}};
memcpy(c.d.asBytes, cmd, len); memcpy(c.d.asBytes, cmd, len);
SendCommand(&c); SendCommand(&c);
@ -58,7 +61,8 @@ static int topaz_send_cmd_raw(uint8_t *cmd, uint8_t len, uint8_t *response) {
// calculate CRC bytes and send topaz command, returns the length of the response (0 in case of error) // calculate CRC bytes and send topaz command, returns the length of the response (0 in case of error)
static int topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response) { static int topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response)
{
if (len > 1) { if (len > 1) {
uint8_t b1, b2; uint8_t b1, b2;
compute_crc(CRC_14443_B, cmd, len - 2, &b1, &b2); compute_crc(CRC_14443_B, cmd, len - 2, &b1, &b2);
@ -71,7 +75,8 @@ static int topaz_send_cmd(uint8_t *cmd, uint8_t len, uint8_t *response) {
// select a topaz tag. Send WUPA and RID. // select a topaz tag. Send WUPA and RID.
static int topaz_select(uint8_t *atqa, uint8_t *rid_response) { static int topaz_select(uint8_t *atqa, uint8_t *rid_response)
{
// ToDo: implement anticollision // ToDo: implement anticollision
uint8_t wupa_cmd[] = {TOPAZ_WUPA}; uint8_t wupa_cmd[] = {TOPAZ_WUPA};
@ -94,7 +99,8 @@ static int topaz_select(uint8_t *atqa, uint8_t *rid_response) {
// read all of the static memory of a selected Topaz tag. // read all of the static memory of a selected Topaz tag.
static int topaz_rall(uint8_t *uid, uint8_t *response) { static int topaz_rall(uint8_t *uid, uint8_t *response)
{
uint8_t rall_cmd[] = {TOPAZ_RALL, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t rall_cmd[] = {TOPAZ_RALL, 0, 0, 0, 0, 0, 0, 0, 0};
memcpy(&rall_cmd[3], uid, 4); memcpy(&rall_cmd[3], uid, 4);
@ -124,7 +130,8 @@ static int topaz_read_block(uint8_t *uid, uint8_t blockno, uint8_t *block_data)
} }
// read a segment (16 blocks = 128 Bytes) of a selected Topaz tag. Works only for tags with dynamic memory. // read a segment (16 blocks = 128 Bytes) of a selected Topaz tag. Works only for tags with dynamic memory.
static int topaz_read_segment(uint8_t *uid, uint8_t segno, uint8_t *segment_data) { static int topaz_read_segment(uint8_t *uid, uint8_t segno, uint8_t *segment_data)
{
uint8_t rseg_cmd[] = {TOPAZ_RSEG, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t rseg_cmd[] = {TOPAZ_RSEG, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t rseg_response[131]; uint8_t rseg_response[131];
@ -139,7 +146,8 @@ static int topaz_read_segment(uint8_t *uid, uint8_t segno, uint8_t *segment_data
} }
// search for the lock area descriptor for the lockable area including byteno // search for the lock area descriptor for the lockable area including byteno
static dynamic_lock_area_t *get_dynamic_lock_area(uint16_t byteno) { static dynamic_lock_area_t *get_dynamic_lock_area(uint16_t byteno)
{
dynamic_lock_area_t *lock_area; dynamic_lock_area_t *lock_area;
lock_area = topaz_tag.dynamic_lock_areas; lock_area = topaz_tag.dynamic_lock_areas;
@ -154,7 +162,8 @@ static dynamic_lock_area_t *get_dynamic_lock_area(uint16_t byteno) {
} }
// check if a memory byte is locked. // check if a memory byte is locked.
static bool topaz_byte_is_locked(uint16_t byteno) { static bool topaz_byte_is_locked(uint16_t byteno)
{
uint8_t *lockbits; uint8_t *lockbits;
uint16_t locked_bytes_per_bit; uint16_t locked_bytes_per_bit;
dynamic_lock_area_t *lock_area; dynamic_lock_area_t *lock_area;
@ -183,7 +192,8 @@ static bool topaz_byte_is_locked(uint16_t byteno) {
// read and print the Capability Container // read and print the Capability Container
static int topaz_print_CC(uint8_t *data) { static int topaz_print_CC(uint8_t *data)
{
if (data[0] != 0xe1) { if (data[0] != 0xe1) {
topaz_tag.size = TOPAZ_STATIC_MEMORY; topaz_tag.size = TOPAZ_STATIC_MEMORY;
return -1; // no NDEF message return -1; // no NDEF message
@ -204,7 +214,8 @@ static int topaz_print_CC(uint8_t *data) {
// return type, length and value of a TLV, starting at memory position *TLV_ptr // return type, length and value of a TLV, starting at memory position *TLV_ptr
static void get_TLV(uint8_t **TLV_ptr, uint8_t *TLV_type, uint16_t *TLV_length, uint8_t **TLV_value) { static void get_TLV(uint8_t **TLV_ptr, uint8_t *TLV_type, uint16_t *TLV_length, uint8_t **TLV_value)
{
*TLV_length = 0; *TLV_length = 0;
*TLV_value = NULL; *TLV_value = NULL;
@ -238,7 +249,8 @@ static void get_TLV(uint8_t **TLV_ptr, uint8_t *TLV_type, uint16_t *TLV_length,
// lock area TLVs contain no information on the start of the respective lockable area. Lockable areas // lock area TLVs contain no information on the start of the respective lockable area. Lockable areas
// do not include the lock bits and reserved memory. We therefore need to adjust the start of the // do not include the lock bits and reserved memory. We therefore need to adjust the start of the
// respective lockable areas accordingly // respective lockable areas accordingly
static void adjust_lock_areas(uint16_t block_start, uint16_t block_size) { static void adjust_lock_areas(uint16_t block_start, uint16_t block_size)
{
dynamic_lock_area_t *lock_area = topaz_tag.dynamic_lock_areas; dynamic_lock_area_t *lock_area = topaz_tag.dynamic_lock_areas;
while (lock_area != NULL) { while (lock_area != NULL) {
if (lock_area->first_locked_byte <= block_start) { if (lock_area->first_locked_byte <= block_start) {
@ -250,7 +262,8 @@ static void adjust_lock_areas(uint16_t block_start, uint16_t block_size) {
// read and print the lock area and reserved memory TLVs // read and print the lock area and reserved memory TLVs
static void topaz_print_control_TLVs(uint8_t *memory) { static void topaz_print_control_TLVs(uint8_t *memory)
{
uint8_t *TLV_ptr = memory; uint8_t *TLV_ptr = memory;
uint8_t TLV_type = 0; uint8_t TLV_type = 0;
uint16_t TLV_length; uint16_t TLV_length;
@ -323,7 +336,8 @@ static void topaz_print_control_TLVs(uint8_t *memory) {
} }
// read all of the dynamic memory // read all of the dynamic memory
static int topaz_read_dynamic_data(void){ static int topaz_read_dynamic_data(void)
{
// first read the remaining block of segment 0 // first read the remaining block of segment 0
if (topaz_read_block(topaz_tag.uid, 0x0f, &topaz_tag.dynamic_memory[0]) == -1) { if (topaz_read_block(topaz_tag.uid, 0x0f, &topaz_tag.dynamic_memory[0]) == -1) {
PrintAndLogEx(WARNING, "Error while reading dynamic memory block %02x. Aborting...", 0x0f); PrintAndLogEx(WARNING, "Error while reading dynamic memory block %02x. Aborting...", 0x0f);
@ -343,7 +357,8 @@ static int topaz_read_dynamic_data(void){
// read and print the dynamic memory // read and print the dynamic memory
static void topaz_print_dynamic_data(void) { static void topaz_print_dynamic_data(void)
{
if (topaz_tag.size > TOPAZ_STATIC_MEMORY) { if (topaz_tag.size > TOPAZ_STATIC_MEMORY) {
PrintAndLogEx(NORMAL, "Dynamic Data blocks:"); PrintAndLogEx(NORMAL, "Dynamic Data blocks:");
if (topaz_read_dynamic_data() == 0) { if (topaz_read_dynamic_data() == 0) {
@ -363,16 +378,19 @@ static void topaz_print_dynamic_data(void) {
} }
} }
static void topaz_print_lifecycle_state(uint8_t *data) { static void topaz_print_lifecycle_state(uint8_t *data)
{
// to be done // to be done
} }
static void topaz_print_NDEF(uint8_t *data) { static void topaz_print_NDEF(uint8_t *data)
{
// to be done. // to be done.
} }
// read a Topaz tag and print some useful information // read a Topaz tag and print some useful information
int CmdHFTopazReader(const char *Cmd) { int CmdHFTopazReader(const char *Cmd)
{
int status; int status;
uint8_t atqa[2]; uint8_t atqa[2];
uint8_t rid_response[8]; uint8_t rid_response[8];
@ -488,17 +506,20 @@ int CmdHFTopazReader(const char *Cmd) {
return 0; return 0;
} }
int CmdHFTopazSim(const char *Cmd) { int CmdHFTopazSim(const char *Cmd)
{
PrintAndLogEx(NORMAL, "not yet implemented"); PrintAndLogEx(NORMAL, "not yet implemented");
return 0; return 0;
} }
int CmdHFTopazCmdRaw(const char *Cmd) { int CmdHFTopazCmdRaw(const char *Cmd)
{
PrintAndLogEx(NORMAL, "not yet implemented. Use hf 14 raw with option -T."); PrintAndLogEx(NORMAL, "not yet implemented. Use hf 14 raw with option -T.");
return 0; return 0;
} }
int CmdHFTopazList(const char *Cmd) { int CmdHFTopazList(const char *Cmd)
{
CmdTraceList("topaz"); CmdTraceList("topaz");
return 0; return 0;
} }
@ -515,13 +536,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdHFTopaz(const char *Cmd) { int CmdHFTopaz(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
static int CmdHelp(const char *Cmd) { static int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -23,51 +23,116 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
static void lookupChipID(uint32_t iChipID, uint32_t mem_used) { static void lookupChipID(uint32_t iChipID, uint32_t mem_used)
{
char asBuff[120]; char asBuff[120];
memset(asBuff, 0, sizeof(asBuff)); memset(asBuff, 0, sizeof(asBuff));
uint32_t mem_avail = 0; uint32_t mem_avail = 0;
PrintAndLogEx(NORMAL, "\n [ Hardware ] "); PrintAndLogEx(NORMAL, "\n [ Hardware ] ");
switch (iChipID) { switch (iChipID) {
case 0x270B0A40: sprintf(asBuff,"AT91SAM7S512 Rev A"); break; case 0x270B0A40:
case 0x270B0A4F: sprintf(asBuff,"AT91SAM7S512 Rev B"); break; sprintf(asBuff, "AT91SAM7S512 Rev A");
case 0x270D0940: sprintf(asBuff,"AT91SAM7S256 Rev A"); break; break;
case 0x270B0941: sprintf(asBuff,"AT91SAM7S256 Rev B"); break; case 0x270B0A4F:
case 0x270B0942: sprintf(asBuff,"AT91SAM7S256 Rev C"); break; sprintf(asBuff, "AT91SAM7S512 Rev B");
case 0x270B0943: sprintf(asBuff,"AT91SAM7S256 Rev D"); break; break;
case 0x270C0740: sprintf(asBuff,"AT91SAM7S128 Rev A"); break; case 0x270D0940:
case 0x270A0741: sprintf(asBuff,"AT91SAM7S128 Rev B"); break; sprintf(asBuff, "AT91SAM7S256 Rev A");
case 0x270A0742: sprintf(asBuff,"AT91SAM7S128 Rev C"); break; break;
case 0x270A0743: sprintf(asBuff,"AT91SAM7S128 Rev D"); break; case 0x270B0941:
case 0x27090540: sprintf(asBuff,"AT91SAM7S64 Rev A"); break; sprintf(asBuff, "AT91SAM7S256 Rev B");
case 0x27090543: sprintf(asBuff,"AT91SAM7S64 Rev B"); break; break;
case 0x27090544: sprintf(asBuff,"AT91SAM7S64 Rev C"); break; case 0x270B0942:
case 0x27080342: sprintf(asBuff,"AT91SAM7S321 Rev A"); break; sprintf(asBuff, "AT91SAM7S256 Rev C");
case 0x27080340: sprintf(asBuff,"AT91SAM7S32 Rev A"); break; break;
case 0x27080341: sprintf(asBuff,"AT91SAM7S32 Rev B"); break; case 0x270B0943:
case 0x27050241: sprintf(asBuff,"AT9SAM7S161 Rev A"); break; sprintf(asBuff, "AT91SAM7S256 Rev D");
case 0x27050240: sprintf(asBuff,"AT91SAM7S16 Rev A"); break; break;
case 0x270C0740:
sprintf(asBuff, "AT91SAM7S128 Rev A");
break;
case 0x270A0741:
sprintf(asBuff, "AT91SAM7S128 Rev B");
break;
case 0x270A0742:
sprintf(asBuff, "AT91SAM7S128 Rev C");
break;
case 0x270A0743:
sprintf(asBuff, "AT91SAM7S128 Rev D");
break;
case 0x27090540:
sprintf(asBuff, "AT91SAM7S64 Rev A");
break;
case 0x27090543:
sprintf(asBuff, "AT91SAM7S64 Rev B");
break;
case 0x27090544:
sprintf(asBuff, "AT91SAM7S64 Rev C");
break;
case 0x27080342:
sprintf(asBuff, "AT91SAM7S321 Rev A");
break;
case 0x27080340:
sprintf(asBuff, "AT91SAM7S32 Rev A");
break;
case 0x27080341:
sprintf(asBuff, "AT91SAM7S32 Rev B");
break;
case 0x27050241:
sprintf(asBuff, "AT9SAM7S161 Rev A");
break;
case 0x27050240:
sprintf(asBuff, "AT91SAM7S16 Rev A");
break;
} }
PrintAndLogEx(NORMAL, " --= uC: %s", asBuff); PrintAndLogEx(NORMAL, " --= uC: %s", asBuff);
switch ((iChipID & 0xE0) >> 5) { switch ((iChipID & 0xE0) >> 5) {
case 1: sprintf(asBuff,"ARM946ES"); break; case 1:
case 2: sprintf(asBuff,"ARM7TDMI"); break; sprintf(asBuff, "ARM946ES");
case 4: sprintf(asBuff,"ARM920T"); break; break;
case 5: sprintf(asBuff,"ARM926EJS"); break; case 2:
sprintf(asBuff, "ARM7TDMI");
break;
case 4:
sprintf(asBuff, "ARM920T");
break;
case 5:
sprintf(asBuff, "ARM926EJS");
break;
} }
PrintAndLogEx(NORMAL, " --= Embedded Processor: %s", asBuff); PrintAndLogEx(NORMAL, " --= Embedded Processor: %s", asBuff);
switch ((iChipID & 0xF00) >> 8) { switch ((iChipID & 0xF00) >> 8) {
case 0: mem_avail = 0; break; case 0:
case 1: mem_avail = 8; break; mem_avail = 0;
case 2: mem_avail = 16; break; break;
case 3: mem_avail = 32; break; case 1:
case 5: mem_avail = 64; break; mem_avail = 8;
case 7: mem_avail = 128; break; break;
case 9: mem_avail = 256; break; case 2:
case 10: mem_avail = 512; break; mem_avail = 16;
case 12: mem_avail = 1024; break; break;
case 14: mem_avail = 2048; break; case 3:
mem_avail = 32;
break;
case 5:
mem_avail = 64;
break;
case 7:
mem_avail = 128;
break;
case 9:
mem_avail = 256;
break;
case 10:
mem_avail = 512;
break;
case 12:
mem_avail = 1024;
break;
case 14:
mem_avail = 2048;
break;
} }
uint32_t mem_left = 0; uint32_t mem_left = 0;
@ -83,69 +148,168 @@ static void lookupChipID(uint32_t iChipID, uint32_t mem_used) {
); );
switch ((iChipID & 0xF000) >> 12) { switch ((iChipID & 0xF000) >> 12) {
case 0: sprintf(asBuff,"None"); break; case 0:
case 1: sprintf(asBuff,"8K bytes"); break; sprintf(asBuff, "None");
case 2: sprintf(asBuff,"16K bytes"); break; break;
case 3: sprintf(asBuff,"32K bytes"); break; case 1:
case 5: sprintf(asBuff,"64K bytes"); break; sprintf(asBuff, "8K bytes");
case 7: sprintf(asBuff,"128K bytes"); break; break;
case 9: sprintf(asBuff,"256K bytes"); break; case 2:
case 10: sprintf(asBuff,"512K bytes"); break; sprintf(asBuff, "16K bytes");
case 12: sprintf(asBuff,"1024K bytes"); break; break;
case 14: sprintf(asBuff,"2048K bytes"); break; case 3:
sprintf(asBuff, "32K bytes");
break;
case 5:
sprintf(asBuff, "64K bytes");
break;
case 7:
sprintf(asBuff, "128K bytes");
break;
case 9:
sprintf(asBuff, "256K bytes");
break;
case 10:
sprintf(asBuff, "512K bytes");
break;
case 12:
sprintf(asBuff, "1024K bytes");
break;
case 14:
sprintf(asBuff, "2048K bytes");
break;
} }
PrintAndLogEx(NORMAL, " --= Second Nonvolatile Program Memory Size: %s", asBuff); PrintAndLogEx(NORMAL, " --= Second Nonvolatile Program Memory Size: %s", asBuff);
switch ((iChipID & 0xF0000) >> 16) { switch ((iChipID & 0xF0000) >> 16) {
case 1: sprintf(asBuff,"1K bytes"); break; case 1:
case 2: sprintf(asBuff,"2K bytes"); break; sprintf(asBuff, "1K bytes");
case 3: sprintf(asBuff,"6K bytes"); break; break;
case 4: sprintf(asBuff,"112K bytes"); break; case 2:
case 5: sprintf(asBuff,"4K bytes"); break; sprintf(asBuff, "2K bytes");
case 6: sprintf(asBuff,"80K bytes"); break; break;
case 7: sprintf(asBuff,"160K bytes"); break; case 3:
case 8: sprintf(asBuff,"8K bytes"); break; sprintf(asBuff, "6K bytes");
case 9: sprintf(asBuff,"16K bytes"); break; break;
case 10: sprintf(asBuff,"32K bytes"); break; case 4:
case 11: sprintf(asBuff,"64K bytes"); break; sprintf(asBuff, "112K bytes");
case 12: sprintf(asBuff,"128K bytes"); break; break;
case 13: sprintf(asBuff,"256K bytes"); break; case 5:
case 14: sprintf(asBuff,"96K bytes"); break; sprintf(asBuff, "4K bytes");
case 15: sprintf(asBuff,"512K bytes");break; break;
case 6:
sprintf(asBuff, "80K bytes");
break;
case 7:
sprintf(asBuff, "160K bytes");
break;
case 8:
sprintf(asBuff, "8K bytes");
break;
case 9:
sprintf(asBuff, "16K bytes");
break;
case 10:
sprintf(asBuff, "32K bytes");
break;
case 11:
sprintf(asBuff, "64K bytes");
break;
case 12:
sprintf(asBuff, "128K bytes");
break;
case 13:
sprintf(asBuff, "256K bytes");
break;
case 14:
sprintf(asBuff, "96K bytes");
break;
case 15:
sprintf(asBuff, "512K bytes");
break;
} }
PrintAndLogEx(NORMAL, " --= Internal SRAM Size: %s", asBuff); PrintAndLogEx(NORMAL, " --= Internal SRAM Size: %s", asBuff);
switch ((iChipID & 0xFF00000) >> 20) { switch ((iChipID & 0xFF00000) >> 20) {
case 0x19: sprintf(asBuff,"AT91SAM9xx Series"); break; case 0x19:
case 0x29: sprintf(asBuff,"AT91SAM9XExx Series"); break; sprintf(asBuff, "AT91SAM9xx Series");
case 0x34: sprintf(asBuff,"AT91x34 Series"); break; break;
case 0x37: sprintf(asBuff,"CAP7 Series"); break; case 0x29:
case 0x39: sprintf(asBuff,"CAP9 Series"); break; sprintf(asBuff, "AT91SAM9XExx Series");
case 0x3B: sprintf(asBuff,"CAP11 Series"); break; break;
case 0x40: sprintf(asBuff,"AT91x40 Series"); break; case 0x34:
case 0x42: sprintf(asBuff,"AT91x42 Series"); break; sprintf(asBuff, "AT91x34 Series");
case 0x55: sprintf(asBuff,"AT91x55 Series"); break; break;
case 0x60: sprintf(asBuff,"AT91SAM7Axx Series"); break; case 0x37:
case 0x61: sprintf(asBuff,"AT91SAM7AQxx Series"); break; sprintf(asBuff, "CAP7 Series");
case 0x63: sprintf(asBuff,"AT91x63 Series"); break; break;
case 0x70: sprintf(asBuff,"AT91SAM7Sxx Series"); break; case 0x39:
case 0x71: sprintf(asBuff,"AT91SAM7XCxx Series"); break; sprintf(asBuff, "CAP9 Series");
case 0x72: sprintf(asBuff,"AT91SAM7SExx Series"); break; break;
case 0x73: sprintf(asBuff,"AT91SAM7Lxx Series"); break; case 0x3B:
case 0x75: sprintf(asBuff,"AT91SAM7Xxx Series"); break; sprintf(asBuff, "CAP11 Series");
case 0x92: sprintf(asBuff,"AT91x92 Series"); break; break;
case 0xF0: sprintf(asBuff,"AT75Cxx Series"); break; case 0x40:
sprintf(asBuff, "AT91x40 Series");
break;
case 0x42:
sprintf(asBuff, "AT91x42 Series");
break;
case 0x55:
sprintf(asBuff, "AT91x55 Series");
break;
case 0x60:
sprintf(asBuff, "AT91SAM7Axx Series");
break;
case 0x61:
sprintf(asBuff, "AT91SAM7AQxx Series");
break;
case 0x63:
sprintf(asBuff, "AT91x63 Series");
break;
case 0x70:
sprintf(asBuff, "AT91SAM7Sxx Series");
break;
case 0x71:
sprintf(asBuff, "AT91SAM7XCxx Series");
break;
case 0x72:
sprintf(asBuff, "AT91SAM7SExx Series");
break;
case 0x73:
sprintf(asBuff, "AT91SAM7Lxx Series");
break;
case 0x75:
sprintf(asBuff, "AT91SAM7Xxx Series");
break;
case 0x92:
sprintf(asBuff, "AT91x92 Series");
break;
case 0xF0:
sprintf(asBuff, "AT75Cxx Series");
break;
} }
PrintAndLogEx(NORMAL, " --= Architecture Identifier: %s", asBuff); PrintAndLogEx(NORMAL, " --= Architecture Identifier: %s", asBuff);
switch ((iChipID & 0x70000000) >> 28) { switch ((iChipID & 0x70000000) >> 28) {
case 0: sprintf(asBuff,"ROM"); break; case 0:
case 1: sprintf(asBuff,"ROMless or on-chip Flash"); break; sprintf(asBuff, "ROM");
case 2: sprintf(asBuff,"Embedded Flash Memory"); break; break;
case 3: sprintf(asBuff,"ROM and Embedded Flash Memory\nNVPSIZ is ROM size\nNVPSIZ2 is Flash size"); break; case 1:
case 4: sprintf(asBuff,"SRAM emulating ROM"); break; sprintf(asBuff, "ROMless or on-chip Flash");
break;
case 2:
sprintf(asBuff, "Embedded Flash Memory");
break;
case 3:
sprintf(asBuff, "ROM and Embedded Flash Memory\nNVPSIZ is ROM size\nNVPSIZ2 is Flash size");
break;
case 4:
sprintf(asBuff, "SRAM emulating ROM");
break;
} }
PrintAndLogEx(NORMAL, " --= Nonvolatile Program Memory Type: %s", asBuff); PrintAndLogEx(NORMAL, " --= Nonvolatile Program Memory Type: %s", asBuff);
} }
int CmdDetectReader(const char *Cmd) { int CmdDetectReader(const char *Cmd)
{
UsbCommand c = {CMD_LISTEN_READER_FIELD}; UsbCommand c = {CMD_LISTEN_READER_FIELD};
// 'l' means LF - 125/134 kHz // 'l' means LF - 125/134 kHz
if (*Cmd == 'l') { if (*Cmd == 'l') {
@ -162,7 +326,8 @@ int CmdDetectReader(const char *Cmd) {
} }
// ## FPGA Control // ## FPGA Control
int CmdFPGAOff(const char *Cmd) { int CmdFPGAOff(const char *Cmd)
{
UsbCommand c = {CMD_FPGA_MAJOR_MODE_OFF}; UsbCommand c = {CMD_FPGA_MAJOR_MODE_OFF};
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
@ -170,7 +335,8 @@ int CmdFPGAOff(const char *Cmd) {
} }
#ifdef WITH_LCD #ifdef WITH_LCD
int CmdLCD(const char *Cmd) { int CmdLCD(const char *Cmd)
{
int i, j; int i, j;
UsbCommand c = {CMD_LCD}; UsbCommand c = {CMD_LCD};
@ -183,7 +349,8 @@ int CmdLCD(const char *Cmd) {
return 0; return 0;
} }
int CmdLCDReset(const char *Cmd) { int CmdLCDReset(const char *Cmd)
{
UsbCommand c = {CMD_LCD_RESET, {strtol(Cmd, NULL, 0), 0, 0}}; UsbCommand c = {CMD_LCD_RESET, {strtol(Cmd, NULL, 0), 0, 0}};
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
@ -191,14 +358,16 @@ int CmdLCDReset(const char *Cmd) {
} }
#endif #endif
int CmdReadmem(const char *Cmd) { int CmdReadmem(const char *Cmd)
{
UsbCommand c = {CMD_READ_MEM, {strtol(Cmd, NULL, 0), 0, 0}}; UsbCommand c = {CMD_READ_MEM, {strtol(Cmd, NULL, 0), 0, 0}};
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
return 0; return 0;
} }
int CmdReset(const char *Cmd) { int CmdReset(const char *Cmd)
{
UsbCommand c = {CMD_HARDWARE_RESET}; UsbCommand c = {CMD_HARDWARE_RESET};
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
@ -209,7 +378,8 @@ int CmdReset(const char *Cmd) {
* Sets the divisor for LF frequency clock: lets the user choose any LF frequency below * Sets the divisor for LF frequency clock: lets the user choose any LF frequency below
* 600kHz. * 600kHz.
*/ */
int CmdSetDivisor(const char *Cmd) { int CmdSetDivisor(const char *Cmd)
{
UsbCommand c = {CMD_SET_LF_DIVISOR, {strtol(Cmd, NULL, 0), 0, 0}}; UsbCommand c = {CMD_SET_LF_DIVISOR, {strtol(Cmd, NULL, 0), 0, 0}};
if (c.arg[0] < 19 || c.arg[0] > 255) { if (c.arg[0] < 19 || c.arg[0] > 255) {
@ -223,7 +393,8 @@ int CmdSetDivisor(const char *Cmd) {
return 0; return 0;
} }
int CmdSetMux(const char *Cmd) { int CmdSetMux(const char *Cmd)
{
if (strlen(Cmd) < 5) { if (strlen(Cmd) < 5) {
PrintAndLogEx(NORMAL, "expected: lopkd | loraw | hipkd | hiraw"); PrintAndLogEx(NORMAL, "expected: lopkd | loraw | hipkd | hiraw");
@ -241,11 +412,13 @@ int CmdSetMux(const char *Cmd) {
return 0; return 0;
} }
int CmdTune(const char *Cmd) { int CmdTune(const char *Cmd)
{
return CmdTuneSamples(Cmd); return CmdTuneSamples(Cmd);
} }
int CmdVersion(const char *Cmd) { int CmdVersion(const char *Cmd)
{
bool silent = (Cmd[0] == 's' || Cmd[0] == 'S'); bool silent = (Cmd[0] == 's' || Cmd[0] == 'S');
if (silent) if (silent)
@ -284,7 +457,8 @@ int CmdVersion(const char *Cmd) {
return 0; return 0;
} }
int CmdStatus(const char *Cmd) { int CmdStatus(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
UsbCommand c = {CMD_STATUS}; UsbCommand c = {CMD_STATUS};
SendCommand(&c); SendCommand(&c);
@ -293,7 +467,8 @@ int CmdStatus(const char *Cmd) {
return 0; return 0;
} }
int CmdPing(const char *Cmd) { int CmdPing(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
UsbCommand resp; UsbCommand resp;
UsbCommand c = {CMD_PING}; UsbCommand c = {CMD_PING};
@ -324,13 +499,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdHW(const char *Cmd) { int CmdHW(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -13,7 +13,8 @@ bool g_lf_threshold_set = false;
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_lf_cmdread(void) { int usage_lf_cmdread(void)
{
PrintAndLogEx(NORMAL, "Usage: lf cmdread d <delay period> z <zero period> o <one period> c <cmdbytes>"); PrintAndLogEx(NORMAL, "Usage: lf cmdread d <delay period> z <zero period> o <one period> c <cmdbytes>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h This help"); PrintAndLogEx(NORMAL, " h This help");
@ -28,7 +29,8 @@ int usage_lf_cmdread(void) {
PrintAndLogEx(NORMAL, " lf cmdread d 80 z 100 o 200 c 11000"); PrintAndLogEx(NORMAL, " lf cmdread d 80 z 100 o 200 c 11000");
return 0; return 0;
} }
int usage_lf_read(void){ int usage_lf_read(void)
{
PrintAndLogEx(NORMAL, "Usage: lf read [h] [s] [d numofsamples]"); PrintAndLogEx(NORMAL, "Usage: lf read [h] [s] [d numofsamples]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h This help"); PrintAndLogEx(NORMAL, " h This help");
@ -41,7 +43,8 @@ int usage_lf_read(void){
PrintAndLogEx(NORMAL, " lf read s"); PrintAndLogEx(NORMAL, " lf read s");
return 0; return 0;
} }
int usage_lf_snoop(void) { int usage_lf_snoop(void)
{
PrintAndLogEx(NORMAL, "Snoop low frequence signal. Use 'lf config' to set parameters."); PrintAndLogEx(NORMAL, "Snoop low frequence signal. Use 'lf config' to set parameters.");
PrintAndLogEx(NORMAL, "Usage: lf snoop [h]"); PrintAndLogEx(NORMAL, "Usage: lf snoop [h]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -50,7 +53,8 @@ int usage_lf_snoop(void) {
PrintAndLogEx(NORMAL, "Use 'lf config' to set parameters."); PrintAndLogEx(NORMAL, "Use 'lf config' to set parameters.");
return 0; return 0;
} }
int usage_lf_config(void) { int usage_lf_config(void)
{
PrintAndLogEx(NORMAL, "Usage: lf config [h] [H|<divisor>] [b <bps>] [d <decim>] [a 0|1]"); PrintAndLogEx(NORMAL, "Usage: lf config [h] [H|<divisor>] [b <bps>] [d <decim>] [a 0|1]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h This help"); PrintAndLogEx(NORMAL, " h This help");
@ -73,7 +77,8 @@ int usage_lf_config(void) {
PrintAndLogEx(NORMAL, " Performs a snoop (no active field)"); PrintAndLogEx(NORMAL, " Performs a snoop (no active field)");
return 0; return 0;
} }
int usage_lf_simfsk(void) { int usage_lf_simfsk(void)
{
PrintAndLogEx(NORMAL, "Usage: lf simfsk [h] [c <clock>] [H <fcHigh>] [L <fcLow>] [d <hexdata>]"); PrintAndLogEx(NORMAL, "Usage: lf simfsk [h] [c <clock>] [H <fcHigh>] [L <fcLow>] [d <hexdata>]");
PrintAndLogEx(NORMAL, "there are about four FSK modulations to know of."); PrintAndLogEx(NORMAL, "there are about four FSK modulations to know of.");
PrintAndLogEx(NORMAL, "FSK1 - where fc/8 = high and fc/5 = low"); PrintAndLogEx(NORMAL, "FSK1 - where fc/8 = high and fc/5 = low");
@ -98,7 +103,8 @@ int usage_lf_simfsk(void) {
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
return 0; return 0;
} }
int usage_lf_simask(void) { int usage_lf_simask(void)
{
PrintAndLogEx(NORMAL, "Usage: lf simask [c <clock>] [i] [b|m|r] [s] [d <raw hex to sim>]"); PrintAndLogEx(NORMAL, "Usage: lf simask [c <clock>] [i] [b|m|r] [s] [d <raw hex to sim>]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h This help"); PrintAndLogEx(NORMAL, " h This help");
@ -111,7 +117,8 @@ int usage_lf_simask(void) {
PrintAndLogEx(NORMAL, " d <hexdata> Data to sim as hex - omit to sim from DemodBuffer"); PrintAndLogEx(NORMAL, " d <hexdata> Data to sim as hex - omit to sim from DemodBuffer");
return 0; return 0;
} }
int usage_lf_simpsk(void) { int usage_lf_simpsk(void)
{
PrintAndLogEx(NORMAL, "Usage: lf simpsk [1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>]"); PrintAndLogEx(NORMAL, "Usage: lf simpsk [1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h This help"); PrintAndLogEx(NORMAL, " h This help");
@ -124,7 +131,8 @@ int usage_lf_simpsk(void) {
PrintAndLogEx(NORMAL, " d <hexdata> Data to sim as hex - omit to sim from DemodBuffer"); PrintAndLogEx(NORMAL, " d <hexdata> Data to sim as hex - omit to sim from DemodBuffer");
return 0; return 0;
} }
int usage_lf_find(void){ int usage_lf_find(void)
{
PrintAndLogEx(NORMAL, "Usage: lf search [h] <0|1> [u]"); PrintAndLogEx(NORMAL, "Usage: lf search [h] <0|1> [u]");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -141,7 +149,8 @@ int usage_lf_find(void){
/* send a LF command before reading */ /* send a LF command before reading */
int CmdLFCommandRead(const char *Cmd) { int CmdLFCommandRead(const char *Cmd)
{
UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K, {0, 0, 0}}; UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K, {0, 0, 0}};
bool errors = false; bool errors = false;
@ -185,7 +194,8 @@ int CmdLFCommandRead(const char *Cmd) {
return 0; return 0;
} }
int CmdFlexdemod(const char *Cmd) { int CmdFlexdemod(const char *Cmd)
{
if (GraphTraceLen < 0) if (GraphTraceLen < 0)
return 0; return 0;
@ -262,7 +272,8 @@ int CmdFlexdemod(const char *Cmd) {
return 0; return 0;
} }
int CmdLFSetConfig(const char *Cmd) { int CmdLFSetConfig(const char *Cmd)
{
uint8_t divisor = 0;//Frequency divisor uint8_t divisor = 0;//Frequency divisor
uint8_t bps = 0; // Bits per sample uint8_t bps = 0; // Bits per sample
uint8_t decimation = 0; //How many to keep uint8_t decimation = 0; //How many to keep
@ -330,7 +341,8 @@ int CmdLFSetConfig(const char *Cmd) {
return 0; return 0;
} }
bool lf_read(bool silent, uint32_t samples) { bool lf_read(bool silent, uint32_t samples)
{
if (IsOffline()) return false; if (IsOffline()) return false;
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {silent, samples, 0}}; UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {silent, samples, 0}};
clearCommandBuffer(); clearCommandBuffer();
@ -351,7 +363,8 @@ bool lf_read(bool silent, uint32_t samples) {
return true; return true;
} }
int CmdLFRead(const char *Cmd) { int CmdLFRead(const char *Cmd)
{
if (IsOffline()) return 0; if (IsOffline()) return 0;
@ -384,7 +397,8 @@ int CmdLFRead(const char *Cmd) {
return lf_read(silent, samples); return lf_read(silent, samples);
} }
int CmdLFSnoop(const char *Cmd) { int CmdLFSnoop(const char *Cmd)
{
uint8_t cmdp = tolower(param_getchar(Cmd, 0)); uint8_t cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_lf_snoop(); if (cmdp == 'h') return usage_lf_snoop();
@ -396,7 +410,8 @@ int CmdLFSnoop(const char *Cmd) {
return 0; return 0;
} }
static void ChkBitstream(const char *str) { static void ChkBitstream(const char *str)
{
// convert to bitstream if necessary // convert to bitstream if necessary
for (int i = 0; i < (int)(GraphTraceLen / 2); i++) { for (int i = 0; i < (int)(GraphTraceLen / 2); i++) {
if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0) { if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0) {
@ -407,7 +422,8 @@ static void ChkBitstream(const char *str) {
} }
//Attempt to simulate any wave in buffer (one bit per output sample) //Attempt to simulate any wave in buffer (one bit per output sample)
// converts GraphBuffer to bitstream (based on zero crossings) if needed. // converts GraphBuffer to bitstream (based on zero crossings) if needed.
int CmdLFSim(const char *Cmd) { int CmdLFSim(const char *Cmd)
{
#define FPGA_LF 1 #define FPGA_LF 1
#define FPGA_HF 2 #define FPGA_HF 2
@ -429,7 +445,8 @@ int CmdLFSim(const char *Cmd) {
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
WaitForResponse(CMD_ACK, NULL); WaitForResponse(CMD_ACK, NULL);
printf("."); fflush(stdout); printf(".");
fflush(stdout);
} }
PrintAndLogEx(NORMAL, "Simulating"); PrintAndLogEx(NORMAL, "Simulating");
@ -442,7 +459,8 @@ int CmdLFSim(const char *Cmd) {
// by marshmellow - sim fsk data given clock, fcHigh, fcLow, invert // by marshmellow - sim fsk data given clock, fcHigh, fcLow, invert
// - allow pull data from DemodBuffer // - allow pull data from DemodBuffer
int CmdLFfskSim(const char *Cmd) { int CmdLFfskSim(const char *Cmd)
{
//might be able to autodetect FCs and clock from Graphbuffer if using demod buffer //might be able to autodetect FCs and clock from Graphbuffer if using demod buffer
// otherwise will need FChigh, FClow, Clock, and bitstream // otherwise will need FChigh, FClow, Clock, and bitstream
uint8_t fcHigh = 0, fcLow = 0, clk = 0; uint8_t fcHigh = 0, fcLow = 0, clk = 0;
@ -535,7 +553,8 @@ int CmdLFfskSim(const char *Cmd) {
// by marshmellow - sim ask data given clock, invert, manchester or raw, separator // by marshmellow - sim ask data given clock, invert, manchester or raw, separator
// - allow pull data from DemodBuffer // - allow pull data from DemodBuffer
int CmdLFaskSim(const char *Cmd) { int CmdLFaskSim(const char *Cmd)
{
// autodetect clock from Graphbuffer if using demod buffer // autodetect clock from Graphbuffer if using demod buffer
// needs clock, invert, manchester/raw as m or r, separator as s, and bitstream // needs clock, invert, manchester/raw as m or r, separator as s, and bitstream
uint8_t encoding = 1, separator = 0, clk = 0, invert = 0; uint8_t encoding = 1, separator = 0, clk = 0, invert = 0;
@ -547,7 +566,8 @@ int CmdLFaskSim(const char *Cmd) {
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) { switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h': return usage_lf_simask(); case 'h':
return usage_lf_simask();
case 'i': case 'i':
invert = 1; invert = 1;
cmdp++; cmdp++;
@ -627,7 +647,8 @@ int CmdLFaskSim(const char *Cmd) {
// by marshmellow - sim psk data given carrier, clock, invert // by marshmellow - sim psk data given carrier, clock, invert
// - allow pull data from DemodBuffer or parameters // - allow pull data from DemodBuffer or parameters
int CmdLFpskSim(const char *Cmd) { int CmdLFpskSim(const char *Cmd)
{
//might be able to autodetect FC and clock from Graphbuffer if using demod buffer //might be able to autodetect FC and clock from Graphbuffer if using demod buffer
//will need carrier, Clock, and bitstream //will need carrier, Clock, and bitstream
uint8_t carrier = 0, clk = 0; uint8_t carrier = 0, clk = 0;
@ -733,7 +754,8 @@ int CmdLFpskSim(const char *Cmd) {
return 0; return 0;
} }
int CmdLFSimBidir(const char *Cmd) { int CmdLFSimBidir(const char *Cmd)
{
// Set ADC to twice the carrier for a slight supersampling // Set ADC to twice the carrier for a slight supersampling
// HACK: not implemented in ARMSRC. // HACK: not implemented in ARMSRC.
PrintAndLogEx(INFO, "Not implemented yet."); PrintAndLogEx(INFO, "Not implemented yet.");
@ -743,7 +765,8 @@ int CmdLFSimBidir(const char *Cmd) {
} }
// ICEMAN, todo, swap from Graphbuffer. // ICEMAN, todo, swap from Graphbuffer.
int CmdVchDemod(const char *Cmd) { int CmdVchDemod(const char *Cmd)
{
// Is this the entire sync pattern, or does this also include some // Is this the entire sync pattern, or does this also include some
// data bits that happen to be the same everywhere? That would be // data bits that happen to be the same everywhere? That would be
// lovely to know. // lovely to know.
@ -816,7 +839,8 @@ int CmdVchDemod(const char *Cmd) {
} }
//by marshmellow //by marshmellow
bool CheckChipType(bool getDeviceData) { bool CheckChipType(bool getDeviceData)
{
bool retval = false; bool retval = false;
@ -849,7 +873,8 @@ out:
} }
//by marshmellow //by marshmellow
int CmdLFfind(const char *Cmd) { int CmdLFfind(const char *Cmd)
{
int ans = 0; int ans = 0;
size_t minLength = 2000; size_t minLength = 2000;
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
@ -933,7 +958,8 @@ int CmdLFfind(const char *Cmd) {
//fsk //fsk
if (GetFskClock("", false)) { if (GetFskClock("", false)) {
if (FSKrawDemod("", true)) { if (FSKrawDemod("", true)) {
PrintAndLogEx(NORMAL, "\nUnknown FSK Modulated Tag Found!"); goto out; PrintAndLogEx(NORMAL, "\nUnknown FSK Modulated Tag Found!");
goto out;
} }
} }
@ -1000,13 +1026,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLF(const char *Cmd) { int CmdLF(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -14,7 +14,8 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_lf_awid_read(void) { int usage_lf_awid_read(void)
{
PrintAndLogEx(NORMAL, "Enables AWID compatible reader mode printing details of scanned AWID26 or AWID50 tags."); PrintAndLogEx(NORMAL, "Enables AWID compatible reader mode printing details of scanned AWID26 or AWID50 tags.");
PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "If the [1] option is provided, reader mode is exited after reading a single AWID card."); PrintAndLogEx(NORMAL, "If the [1] option is provided, reader mode is exited after reading a single AWID card.");
@ -30,7 +31,8 @@ int usage_lf_awid_read(void) {
return 0; return 0;
} }
int usage_lf_awid_sim(void) { int usage_lf_awid_sim(void)
{
PrintAndLogEx(NORMAL, "Enables simulation of AWID card with specified facility-code and card number."); PrintAndLogEx(NORMAL, "Enables simulation of AWID card with specified facility-code and card number.");
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
@ -47,7 +49,8 @@ int usage_lf_awid_sim(void) {
return 0; return 0;
} }
int usage_lf_awid_clone(void) { int usage_lf_awid_clone(void)
{
PrintAndLogEx(NORMAL, "Enables cloning of AWID card with specified facility-code and card number onto T55x7."); PrintAndLogEx(NORMAL, "Enables cloning of AWID card with specified facility-code and card number onto T55x7.");
PrintAndLogEx(NORMAL, "The T55x7 must be on the antenna when issuing this command. T55x7 blocks are calculated and printed in the process."); PrintAndLogEx(NORMAL, "The T55x7 must be on the antenna when issuing this command. T55x7 blocks are calculated and printed in the process.");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
@ -65,7 +68,8 @@ int usage_lf_awid_clone(void) {
return 0; return 0;
} }
int usage_lf_awid_brute(void){ int usage_lf_awid_brute(void)
{
PrintAndLogEx(NORMAL, "Enables bruteforce of AWID reader with specified facility-code."); PrintAndLogEx(NORMAL, "Enables bruteforce of AWID reader with specified facility-code.");
PrintAndLogEx(NORMAL, "This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step"); PrintAndLogEx(NORMAL, "This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step");
PrintAndLogEx(NORMAL, "if cardnumber is not given, it starts with 1 and goes up to 65535"); PrintAndLogEx(NORMAL, "if cardnumber is not given, it starts with 1 and goes up to 65535");
@ -86,7 +90,8 @@ int usage_lf_awid_brute(void){
return 0; return 0;
} }
static bool sendPing(void){ static bool sendPing(void)
{
UsbCommand ping = {CMD_PING, {1, 2, 3}}; UsbCommand ping = {CMD_PING, {1, 2, 3}};
SendCommand(&ping); SendCommand(&ping);
SendCommand(&ping); SendCommand(&ping);
@ -98,7 +103,8 @@ static bool sendPing(void){
return true; return true;
} }
static bool sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, uint8_t *bits, size_t bs_len, bool verbose){ static bool sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, uint8_t *bits, size_t bs_len, bool verbose)
{
if (verbose) if (verbose)
PrintAndLogEx(INFO, "Trying FC: %u; CN: %u", fc, cn); PrintAndLogEx(INFO, "Trying FC: %u; CN: %u", fc, cn);
@ -123,7 +129,8 @@ static bool sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, ui
} }
//refactored by marshmellow //refactored by marshmellow
int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits) { int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits)
{
// the return bits, preamble 0000 0001 // the return bits, preamble 0000 0001
bits[7] = 1; bits[7] = 1;
@ -176,7 +183,8 @@ int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits) {
return 1; return 1;
} }
static void verify_values(uint8_t *fmtlen, uint32_t *fc, uint32_t *cn){ static void verify_values(uint8_t *fmtlen, uint32_t *fc, uint32_t *cn)
{
switch (*fmtlen) { switch (*fmtlen) {
case 50: case 50:
if ((*fc & 0xFFFF) != *fc) { if ((*fc & 0xFFFF) != *fc) {
@ -220,13 +228,15 @@ static void verify_values(uint8_t *fmtlen, uint32_t *fc, uint32_t *cn){
} }
// this read is the "normal" read, which download lf signal and tries to demod here. // this read is the "normal" read, which download lf signal and tries to demod here.
int CmdAWIDRead(const char *Cmd) { int CmdAWIDRead(const char *Cmd)
{
lf_read(true, 12000); lf_read(true, 12000);
return CmdAWIDDemod(Cmd); return CmdAWIDDemod(Cmd);
} }
// this read loops on device side. // this read loops on device side.
// uses the demod in lfops.c // uses the demod in lfops.c
int CmdAWIDRead_device(const char *Cmd) { int CmdAWIDRead_device(const char *Cmd)
{
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_awid_read(); if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_awid_read();
uint8_t findone = (Cmd[0] == '1') ? 1 : 0; uint8_t findone = (Cmd[0] == '1') ? 1 : 0;
@ -239,7 +249,8 @@ int CmdAWIDRead_device(const char *Cmd) {
//by marshmellow //by marshmellow
//AWID Prox demod - FSK2a RF/50 with preamble of 00000001 (always a 96 bit data stream) //AWID Prox demod - FSK2a RF/50 with preamble of 00000001 (always a 96 bit data stream)
//print full AWID Prox ID and some bit format details if found //print full AWID Prox ID and some bit format details if found
int CmdAWIDDemod(const char *Cmd) { int CmdAWIDDemod(const char *Cmd)
{
uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0}; uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0};
size_t size = getFromGraphBuf(bits); size_t size = getFromGraphBuf(bits);
if (size == 0) { if (size == 0) {
@ -369,7 +380,8 @@ int CmdAWIDDemod(const char *Cmd) {
return 1; return 1;
} }
int CmdAWIDSim(const char *Cmd) { int CmdAWIDSim(const char *Cmd)
{
uint32_t fc = 0, cn = 0; uint32_t fc = 0, cn = 0;
uint8_t fmtlen = 0; uint8_t fmtlen = 0;
uint8_t bits[96]; uint8_t bits[96];
@ -409,7 +421,8 @@ int CmdAWIDSim(const char *Cmd) {
return 0; return 0;
} }
int CmdAWIDClone(const char *Cmd) { int CmdAWIDClone(const char *Cmd)
{
uint32_t blocks[4] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_50 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0}; uint32_t blocks[4] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_50 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0};
uint32_t fc = 0, cn = 0; uint32_t fc = 0, cn = 0;
uint8_t fmtlen = 0; uint8_t fmtlen = 0;
@ -460,7 +473,8 @@ int CmdAWIDClone(const char *Cmd) {
return 0; return 0;
} }
int CmdAWIDBrute(const char *Cmd) { int CmdAWIDBrute(const char *Cmd)
{
bool errors = false, verbose = false; bool errors = false, verbose = false;
uint32_t fc = 0, cn = 0, delay = 1000; uint32_t fc = 0, cn = 0, delay = 1000;
@ -538,7 +552,8 @@ int CmdAWIDBrute(const char *Cmd) {
return 2; return 2;
} }
if (ukbhit()) { if (ukbhit()) {
int gc = getchar(); (void)gc; int gc = getchar();
(void)gc;
PrintAndLogEx(INFO, "aborted via keyboard!"); PrintAndLogEx(INFO, "aborted via keyboard!");
return sendPing(); return sendPing();
} }
@ -565,13 +580,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFAWID(const char *Cmd) { int CmdLFAWID(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -11,7 +11,8 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_lf_cotag_read(void){ int usage_lf_cotag_read(void)
{
PrintAndLogEx(NORMAL, "Usage: lf COTAG read [h] <signaldata>"); PrintAndLogEx(NORMAL, "Usage: lf COTAG read [h] <signaldata>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : This help"); PrintAndLogEx(NORMAL, " h : This help");
@ -27,7 +28,8 @@ int usage_lf_cotag_read(void){
// COTAG demod should be able to use GraphBuffer, // COTAG demod should be able to use GraphBuffer,
// when data load samples // when data load samples
int CmdCOTAGDemod(const char *Cmd) { int CmdCOTAGDemod(const char *Cmd)
{
uint8_t bits[COTAG_BITS] = {0}; uint8_t bits[COTAG_BITS] = {0};
size_t bitlen = COTAG_BITS; size_t bitlen = COTAG_BITS;
@ -66,7 +68,8 @@ int CmdCOTAGDemod(const char *Cmd) {
// 0 = HIGH/LOW signal - maxlength bigbuff // 0 = HIGH/LOW signal - maxlength bigbuff
// 1 = translation for HI/LO into bytes with manchester 0,1 - length 300 // 1 = translation for HI/LO into bytes with manchester 0,1 - length 300
// 2 = raw signal - maxlength bigbuff // 2 = raw signal - maxlength bigbuff
int CmdCOTAGRead(const char *Cmd) { int CmdCOTAGRead(const char *Cmd)
{
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_cotag_read(); if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_cotag_read();
@ -109,13 +112,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFCOTAG(const char *Cmd) { int CmdLFCOTAG(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -15,7 +15,8 @@ uint64_t g_em410xid = 0;
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
//////////////// 410x commands //////////////// 410x commands
int usage_lf_em410x_demod(void){ int usage_lf_em410x_demod(void)
{
PrintAndLogEx(NORMAL, "Usage: lf em 410x_demod [h] [clock] <0|1> [maxError]"); PrintAndLogEx(NORMAL, "Usage: lf em 410x_demod [h] [clock] <0|1> [maxError]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h - this help"); PrintAndLogEx(NORMAL, " h - this help");
@ -31,7 +32,8 @@ int usage_lf_em410x_demod(void){
PrintAndLogEx(NORMAL, " lf em 410x_demod 64 1 0 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/64 and inverting data and allowing 0 demod errors"); PrintAndLogEx(NORMAL, " lf em 410x_demod 64 1 0 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/64 and inverting data and allowing 0 demod errors");
return 0; return 0;
} }
int usage_lf_em410x_write(void) { int usage_lf_em410x_write(void)
{
PrintAndLogEx(NORMAL, "Writes EM410x ID to a T55x7 / T5555 (Q5) tag"); PrintAndLogEx(NORMAL, "Writes EM410x ID to a T55x7 / T5555 (Q5) tag");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf em 410x_write [h] <id> <card> [clock]"); PrintAndLogEx(NORMAL, "Usage: lf em 410x_write [h] <id> <card> [clock]");
@ -44,7 +46,8 @@ int usage_lf_em410x_write(void) {
PrintAndLogEx(NORMAL, " lf em 410x_write 0F0368568B 1 = write ID to t55x7 card"); PrintAndLogEx(NORMAL, " lf em 410x_write 0F0368568B 1 = write ID to t55x7 card");
return 0; return 0;
} }
int usage_lf_em410x_ws(void) { int usage_lf_em410x_ws(void)
{
PrintAndLogEx(NORMAL, "Watch 'nd Spoof, activates reader, waits until a EM410x tag gets presented then it starts simulating the found UID"); PrintAndLogEx(NORMAL, "Watch 'nd Spoof, activates reader, waits until a EM410x tag gets presented then it starts simulating the found UID");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf em 410x_spoof [h]"); PrintAndLogEx(NORMAL, "Usage: lf em 410x_spoof [h]");
@ -54,7 +57,8 @@ int usage_lf_em410x_ws(void) {
PrintAndLogEx(NORMAL, " lf em 410x_spoof"); PrintAndLogEx(NORMAL, " lf em 410x_spoof");
return 0; return 0;
} }
int usage_lf_em410x_clone(void) { int usage_lf_em410x_clone(void)
{
PrintAndLogEx(NORMAL, "Simulating EM410x tag"); PrintAndLogEx(NORMAL, "Simulating EM410x tag");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf em 410x_clone [h] <uid> <clock>"); PrintAndLogEx(NORMAL, "Usage: lf em 410x_clone [h] <uid> <clock>");
@ -67,7 +71,8 @@ int usage_lf_em410x_clone(void) {
PrintAndLogEx(NORMAL, " lf em 410x_clone 0F0368568B 32"); PrintAndLogEx(NORMAL, " lf em 410x_clone 0F0368568B 32");
return 0; return 0;
} }
int usage_lf_em410x_sim(void) { int usage_lf_em410x_sim(void)
{
PrintAndLogEx(NORMAL, "Simulating EM410x tag"); PrintAndLogEx(NORMAL, "Simulating EM410x tag");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf em 410x_sim [h] <uid> <clock>"); PrintAndLogEx(NORMAL, "Usage: lf em 410x_sim [h] <uid> <clock>");
@ -80,7 +85,8 @@ int usage_lf_em410x_sim(void) {
PrintAndLogEx(NORMAL, " lf em 410x_sim 0F0368568B 32"); PrintAndLogEx(NORMAL, " lf em 410x_sim 0F0368568B 32");
return 0; return 0;
} }
int usage_lf_em410x_brute(void) { int usage_lf_em410x_brute(void)
{
PrintAndLogEx(NORMAL, "Bruteforcing by emulating EM410x tag"); PrintAndLogEx(NORMAL, "Bruteforcing by emulating EM410x tag");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf em 410x_brute [h] ids.txt [d 2000] [c clock]"); PrintAndLogEx(NORMAL, "Usage: lf em 410x_brute [h] ids.txt [d 2000] [c clock]");
@ -98,7 +104,8 @@ int usage_lf_em410x_brute(void) {
} }
//////////////// 4050 / 4450 commands //////////////// 4050 / 4450 commands
int usage_lf_em4x50_dump(void) { int usage_lf_em4x50_dump(void)
{
PrintAndLogEx(NORMAL, "Dump EM4x50/EM4x69. Tag must be on antenna. "); PrintAndLogEx(NORMAL, "Dump EM4x50/EM4x69. Tag must be on antenna. ");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf em 4x50_dump [h] <pwd>"); PrintAndLogEx(NORMAL, "Usage: lf em 4x50_dump [h] <pwd>");
@ -110,7 +117,8 @@ int usage_lf_em4x50_dump(void) {
PrintAndLogEx(NORMAL, " lf em 4x50_dump 11223344"); PrintAndLogEx(NORMAL, " lf em 4x50_dump 11223344");
return 0; return 0;
} }
int usage_lf_em4x50_read(void) { int usage_lf_em4x50_read(void)
{
PrintAndLogEx(NORMAL, "Read EM 4x50/EM4x69. Tag must be on antenna. "); PrintAndLogEx(NORMAL, "Read EM 4x50/EM4x69. Tag must be on antenna. ");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf em 4x50_read [h] <address> <pwd>"); PrintAndLogEx(NORMAL, "Usage: lf em 4x50_read [h] <address> <pwd>");
@ -123,7 +131,8 @@ int usage_lf_em4x50_read(void) {
PrintAndLogEx(NORMAL, " lf em 4x50_read 1 11223344"); PrintAndLogEx(NORMAL, " lf em 4x50_read 1 11223344");
return 0; return 0;
} }
int usage_lf_em4x50_write(void) { int usage_lf_em4x50_write(void)
{
PrintAndLogEx(NORMAL, "Write EM 4x50/4x69. Tag must be on antenna. "); PrintAndLogEx(NORMAL, "Write EM 4x50/4x69. Tag must be on antenna. ");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf em 4x50_write [h] <address> <data> <pwd>"); PrintAndLogEx(NORMAL, "Usage: lf em 4x50_write [h] <address> <data> <pwd>");
@ -139,7 +148,8 @@ int usage_lf_em4x50_write(void) {
} }
//////////////// 4205 / 4305 commands //////////////// 4205 / 4305 commands
int usage_lf_em4x05_dump(void) { int usage_lf_em4x05_dump(void)
{
PrintAndLogEx(NORMAL, "Dump EM4x05/EM4x69. Tag must be on antenna. "); PrintAndLogEx(NORMAL, "Dump EM4x05/EM4x69. Tag must be on antenna. ");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf em 4x05_dump [h] <pwd>"); PrintAndLogEx(NORMAL, "Usage: lf em 4x05_dump [h] <pwd>");
@ -151,7 +161,8 @@ int usage_lf_em4x05_dump(void) {
PrintAndLogEx(NORMAL, " lf em 4x05_dump 11223344"); PrintAndLogEx(NORMAL, " lf em 4x05_dump 11223344");
return 0; return 0;
} }
int usage_lf_em4x05_read(void) { int usage_lf_em4x05_read(void)
{
PrintAndLogEx(NORMAL, "Read EM4x05/EM4x69. Tag must be on antenna. "); PrintAndLogEx(NORMAL, "Read EM4x05/EM4x69. Tag must be on antenna. ");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf em 4x05_read [h] <address> <pwd>"); PrintAndLogEx(NORMAL, "Usage: lf em 4x05_read [h] <address> <pwd>");
@ -164,7 +175,8 @@ int usage_lf_em4x05_read(void) {
PrintAndLogEx(NORMAL, " lf em 4x05_read 1 11223344"); PrintAndLogEx(NORMAL, " lf em 4x05_read 1 11223344");
return 0; return 0;
} }
int usage_lf_em4x05_write(void) { int usage_lf_em4x05_write(void)
{
PrintAndLogEx(NORMAL, "Write EM4x05/4x69. Tag must be on antenna. "); PrintAndLogEx(NORMAL, "Write EM4x05/4x69. Tag must be on antenna. ");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf em 4x05_write [h] <address> <data> <pwd>"); PrintAndLogEx(NORMAL, "Usage: lf em 4x05_write [h] <address> <data> <pwd>");
@ -178,7 +190,8 @@ int usage_lf_em4x05_write(void) {
PrintAndLogEx(NORMAL, " lf em 4x05_write 1 deadc0de 11223344"); PrintAndLogEx(NORMAL, " lf em 4x05_write 1 deadc0de 11223344");
return 0; return 0;
} }
int usage_lf_em4x05_info(void) { int usage_lf_em4x05_info(void)
{
PrintAndLogEx(NORMAL, "Tag information EM4205/4305/4469//4569 tags. Tag must be on antenna."); PrintAndLogEx(NORMAL, "Tag information EM4205/4305/4469//4569 tags. Tag must be on antenna.");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf em 4x05_info [h] <pwd>"); PrintAndLogEx(NORMAL, "Usage: lf em 4x05_info [h] <pwd>");
@ -201,7 +214,8 @@ int usage_lf_em4x05_info(void) {
*/ */
// Construct the graph for emulating an EM410X tag // Construct the graph for emulating an EM410X tag
void ConstructEM410xEmulGraph(const char *uid,const uint8_t clock) { void ConstructEM410xEmulGraph(const char *uid, const uint8_t clock)
{
int i, j, binary[4], parity[4]; int i, j, binary[4], parity[4];
uint32_t n; uint32_t n;
@ -248,7 +262,8 @@ void ConstructEM410xEmulGraph(const char *uid,const uint8_t clock) {
//by marshmellow //by marshmellow
//print 64 bit EM410x ID in multiple formats //print 64 bit EM410x ID in multiple formats
void printEM410x(uint32_t hi, uint64_t id) { void printEM410x(uint32_t hi, uint64_t id)
{
if (!id && !hi) return; if (!id && !hi) return;
@ -352,7 +367,8 @@ void printEM410x(uint32_t hi, uint64_t id) {
* CCCC <-- each bit here is parity for the 10 bits above in corresponding column * CCCC <-- each bit here is parity for the 10 bits above in corresponding column
* 0 <-- stop bit, end of tag * 0 <-- stop bit, end of tag
*/ */
int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo ) { int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo)
{
size_t idx = 0; size_t idx = 0;
uint8_t bits[512] = {0}; uint8_t bits[512] = {0};
size_t size = sizeof(bits); size_t size = sizeof(bits);
@ -393,21 +409,24 @@ int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo ) {
return 1; return 1;
} }
int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose) { int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose)
{
bool st = true; bool st = true;
if (!ASKDemod_ext(Cmd, false, false, 1, &st)) return 0; if (!ASKDemod_ext(Cmd, false, false, 1, &st)) return 0;
return AskEm410xDecode(verbose, hi, lo); return AskEm410xDecode(verbose, hi, lo);
} }
// this read is the "normal" read, which download lf signal and tries to demod here. // this read is the "normal" read, which download lf signal and tries to demod here.
int CmdEM410xRead(const char *Cmd) { int CmdEM410xRead(const char *Cmd)
{
lf_read(true, 8192); lf_read(true, 8192);
return CmdEM410xDemod(Cmd); return CmdEM410xDemod(Cmd);
} }
// this read loops on device side. // this read loops on device side.
// uses the demod in lfops.c // uses the demod in lfops.c
int CmdEM410xRead_device(const char *Cmd) { int CmdEM410xRead_device(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
uint8_t findone = (cmdp == '1') ? 1 : 0; uint8_t findone = (cmdp == '1') ? 1 : 0;
UsbCommand c = {CMD_EM410X_DEMOD, {findone, 0, 0}}; UsbCommand c = {CMD_EM410X_DEMOD, {findone, 0, 0}};
@ -419,7 +438,8 @@ int CmdEM410xRead_device(const char *Cmd) {
//takes 3 arguments - clock, invert and maxErr as integers //takes 3 arguments - clock, invert and maxErr as integers
//attempts to demodulate ask while decoding manchester //attempts to demodulate ask while decoding manchester
//prints binary found and saves in graphbuffer for further commands //prints binary found and saves in graphbuffer for further commands
int CmdEM410xDemod(const char *Cmd) { int CmdEM410xDemod(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) > 10 || cmdp == 'h') return usage_lf_em410x_demod(); if (strlen(Cmd) > 10 || cmdp == 'h') return usage_lf_em410x_demod();
@ -433,7 +453,8 @@ int CmdEM410xDemod(const char *Cmd) {
} }
// emulate an EM410X tag // emulate an EM410X tag
int CmdEM410xSim(const char *Cmd) { int CmdEM410xSim(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_lf_em410x_sim(); if (cmdp == 'h') return usage_lf_em410x_sim();
@ -458,7 +479,8 @@ int CmdEM410xSim(const char *Cmd) {
return 0; return 0;
} }
int CmdEM410xBrute(const char *Cmd) { int CmdEM410xBrute(const char *Cmd)
{
char filename[FILE_PATH_SIZE] = {0}; char filename[FILE_PATH_SIZE] = {0};
FILE *f = NULL; FILE *f = NULL;
char buf[11]; char buf[11];
@ -548,7 +570,8 @@ int CmdEM410xBrute(const char *Cmd) {
testuid[10] = 0; testuid[10] = 0;
if (ukbhit()) { if (ukbhit()) {
int gc = getchar(); (void)gc; int gc = getchar();
(void)gc;
PrintAndLogEx(WARNING, "\nAborted via keyboard!\n"); PrintAndLogEx(WARNING, "\nAborted via keyboard!\n");
free(uidBlock); free(uidBlock);
return 0; return 0;
@ -579,10 +602,12 @@ int CmdEM410xBrute(const char *Cmd) {
* *
* EDIT -- capture enough to get 2 complete preambles at the slowest data rate known to be used (rf/64) (64*64*2+9 = 8201) marshmellow * EDIT -- capture enough to get 2 complete preambles at the slowest data rate known to be used (rf/64) (64*64*2+9 = 8201) marshmellow
*/ */
int CmdEM410xWatch(const char *Cmd) { int CmdEM410xWatch(const char *Cmd)
{
do { do {
if (ukbhit()) { if (ukbhit()) {
int gc = getchar(); (void)gc; int gc = getchar();
(void)gc;
PrintAndLogEx(WARNING, "\naborted via keyboard!\n"); PrintAndLogEx(WARNING, "\naborted via keyboard!\n");
break; break;
} }
@ -593,7 +618,8 @@ int CmdEM410xWatch(const char *Cmd) {
} }
//currently only supports manchester modulations //currently only supports manchester modulations
int CmdEM410xWatchnSpoof(const char *Cmd) { int CmdEM410xWatchnSpoof(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_lf_em410x_ws(); if (cmdp == 'h') return usage_lf_em410x_ws();
@ -605,7 +631,8 @@ int CmdEM410xWatchnSpoof(const char *Cmd) {
return 0; return 0;
} }
int CmdEM410xWrite(const char *Cmd) { int CmdEM410xWrite(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 0x00 || cmdp == 'h') return usage_lf_em410x_write(); if (cmdp == 0x00 || cmdp == 'h') return usage_lf_em410x_write();
@ -666,7 +693,8 @@ int CmdEM410xWrite(const char *Cmd) {
} }
//**************** Start of EM4x50 Code ************************ //**************** Start of EM4x50 Code ************************
bool EM_EndParityTest(uint8_t *bs, size_t size, uint8_t rows, uint8_t cols, uint8_t pType) { bool EM_EndParityTest(uint8_t *bs, size_t size, uint8_t rows, uint8_t cols, uint8_t pType)
{
if (rows * cols > size) return false; if (rows * cols > size) return false;
uint8_t colP = 0; uint8_t colP = 0;
//assume last col is a parity and do not test //assume last col is a parity and do not test
@ -679,7 +707,8 @@ bool EM_EndParityTest(uint8_t *bs, size_t size, uint8_t rows, uint8_t cols, uint
return true; return true;
} }
bool EM_ByteParityTest(uint8_t *bs, size_t size, uint8_t rows, uint8_t cols, uint8_t pType) { bool EM_ByteParityTest(uint8_t *bs, size_t size, uint8_t rows, uint8_t cols, uint8_t pType)
{
if (rows * cols > size) return false; if (rows * cols > size) return false;
uint8_t rowP = 0; uint8_t rowP = 0;
@ -703,7 +732,8 @@ bool EM_ByteParityTest(uint8_t *bs, size_t size, uint8_t rows, uint8_t cols, uin
//c012345678| 0 //c012345678| 0
// |- must be zero // |- must be zero
bool EMwordparitytest(uint8_t *bits){ bool EMwordparitytest(uint8_t *bits)
{
// last row/col parity must be 0 // last row/col parity must be 0
if (bits[44] != 0) return false; if (bits[44] != 0) return false;
@ -732,7 +762,8 @@ bool EMwordparitytest(uint8_t *bits){
//////////////// 4050 / 4450 commands //////////////// 4050 / 4450 commands
uint32_t OutputEM4x50_Block(uint8_t *BitStream, size_t size, bool verbose, bool pTest) { uint32_t OutputEM4x50_Block(uint8_t *BitStream, size_t size, bool verbose, bool pTest)
{
if (size < 45) return 0; if (size < 45) return 0;
uint32_t code = bytebits_to_byte(BitStream, 8); uint32_t code = bytebits_to_byte(BitStream, 8);
@ -782,7 +813,8 @@ uint32_t OutputEM4x50_Block(uint8_t *BitStream, size_t size, bool verbose, bool
* Word Read values. UID is stored in block 32. * Word Read values. UID is stored in block 32.
*/ */
//completed by Marshmellow //completed by Marshmellow
int EM4x50Read(const char *Cmd, bool verbose) { int EM4x50Read(const char *Cmd, bool verbose)
{
uint8_t fndClk[] = {8, 16, 32, 40, 50, 64, 128}; uint8_t fndClk[] = {8, 16, 32, 40, 50, 64, 128};
int clk = 0, invert = 0, tol = 0, phaseoff; int clk = 0, invert = 0, tol = 0, phaseoff;
int i = 0, j = 0, startblock, skip, block, start, end, low = 0, high = 0, minClk = 255; int i = 0, j = 0, startblock, skip, block, start, end, low = 0, high = 0, minClk = 255;
@ -852,8 +884,7 @@ int EM4x50Read(const char *Cmd, bool verbose) {
if (tmpbuff[i] >= clk * 3 - tol && tmpbuff[i] <= clk * 3 + tol) //3 clocks if (tmpbuff[i] >= clk * 3 - tol && tmpbuff[i] <= clk * 3 + tol) //3 clocks
if (tmpbuff[i + 1] >= clk * 2 - tol && tmpbuff[i + 1] <= clk * 2 + tol) //2 clocks if (tmpbuff[i + 1] >= clk * 2 - tol && tmpbuff[i + 1] <= clk * 2 + tol) //2 clocks
if (tmpbuff[i + 2] >= clk * 3 - tol && tmpbuff[i + 2] <= clk * 3 + tol) //3 clocks if (tmpbuff[i + 2] >= clk * 3 - tol && tmpbuff[i + 2] <= clk * 3 + tol) //3 clocks
if (tmpbuff[i+3] >= clk-tol) //1.5 to 2 clocks - depends on bit following if (tmpbuff[i + 3] >= clk - tol) { //1.5 to 2 clocks - depends on bit following
{
start = i + 4; start = i + 4;
break; break;
} }
@ -875,8 +906,7 @@ int EM4x50Read(const char *Cmd, bool verbose) {
if (tmpbuff[i] >= clk * 3 - tol && tmpbuff[i] <= clk * 3 + tol) //3 clocks if (tmpbuff[i] >= clk * 3 - tol && tmpbuff[i] <= clk * 3 + tol) //3 clocks
if (tmpbuff[i + 1] >= clk * 2 - tol && tmpbuff[i + 1] <= clk * 2 + tol) //2 clocks if (tmpbuff[i + 1] >= clk * 2 - tol && tmpbuff[i + 1] <= clk * 2 + tol) //2 clocks
if (tmpbuff[i + 2] >= clk * 3 - tol && tmpbuff[i + 2] <= clk * 3 + tol) //3 clocks if (tmpbuff[i + 2] >= clk * 3 - tol && tmpbuff[i + 2] <= clk * 3 + tol) //3 clocks
if (tmpbuff[i+3] >= clk-tol) //1.5 to 2 clocks - depends on bit following if (tmpbuff[i + 3] >= clk - tol) { //1.5 to 2 clocks - depends on bit following
{
complete = true; complete = true;
break; break;
} }
@ -970,18 +1000,21 @@ int EM4x50Read(const char *Cmd, bool verbose) {
return (int)AllPTest; return (int)AllPTest;
} }
int CmdEM4x50Read(const char *Cmd) { int CmdEM4x50Read(const char *Cmd)
{
uint8_t ctmp = tolower(param_getchar(Cmd, 0)); uint8_t ctmp = tolower(param_getchar(Cmd, 0));
if (ctmp == 'h') return usage_lf_em4x50_read(); if (ctmp == 'h') return usage_lf_em4x50_read();
return EM4x50Read(Cmd, true); return EM4x50Read(Cmd, true);
} }
int CmdEM4x50Write(const char *Cmd){ int CmdEM4x50Write(const char *Cmd)
{
uint8_t ctmp = tolower(param_getchar(Cmd, 0)); uint8_t ctmp = tolower(param_getchar(Cmd, 0));
if (ctmp == 'h') return usage_lf_em4x50_write(); if (ctmp == 'h') return usage_lf_em4x50_write();
PrintAndLogEx(NORMAL, "no implemented yet"); PrintAndLogEx(NORMAL, "no implemented yet");
return 0; return 0;
} }
int CmdEM4x50Dump(const char *Cmd){ int CmdEM4x50Dump(const char *Cmd)
{
uint8_t ctmp = tolower(param_getchar(Cmd, 0)); uint8_t ctmp = tolower(param_getchar(Cmd, 0));
if (ctmp == 'h') return usage_lf_em4x50_dump(); if (ctmp == 'h') return usage_lf_em4x50_dump();
PrintAndLogEx(NORMAL, "no implemented yet"); PrintAndLogEx(NORMAL, "no implemented yet");
@ -990,7 +1023,8 @@ int CmdEM4x50Dump(const char *Cmd){
#define EM_PREAMBLE_LEN 6 #define EM_PREAMBLE_LEN 6
// download samples from device and copy to Graphbuffer // download samples from device and copy to Graphbuffer
bool downloadSamplesEM(){ bool downloadSamplesEM()
{
// 8 bit preamble + 32 bit word response (max clock (128) * 40bits = 5120 samples) // 8 bit preamble + 32 bit word response (max clock (128) * 40bits = 5120 samples)
uint8_t got[6000]; uint8_t got[6000];
@ -1011,7 +1045,8 @@ bool downloadSamplesEM(){
} }
// em_demod // em_demod
bool doPreambleSearch(size_t *startIdx){ bool doPreambleSearch(size_t *startIdx)
{
// sanity check // sanity check
if (DemodBufferLen < EM_PREAMBLE_LEN) { if (DemodBufferLen < EM_PREAMBLE_LEN) {
@ -1032,7 +1067,8 @@ bool doPreambleSearch(size_t *startIdx){
return true; return true;
} }
bool detectFSK(){ bool detectFSK()
{
// detect fsk clock // detect fsk clock
if (!GetFskClock("", false)) { if (!GetFskClock("", false)) {
PrintAndLogEx(DEBUG, "DEBUG: Error - EM: FSK clock failed"); PrintAndLogEx(DEBUG, "DEBUG: Error - EM: FSK clock failed");
@ -1047,7 +1083,8 @@ bool detectFSK(){
return true; return true;
} }
// PSK clocks should be easy to detect ( but difficult to demod a non-repeating pattern... ) // PSK clocks should be easy to detect ( but difficult to demod a non-repeating pattern... )
bool detectPSK(){ bool detectPSK()
{
int ans = GetPskClock("", false); int ans = GetPskClock("", false);
if (ans <= 0) { if (ans <= 0) {
PrintAndLogEx(DEBUG, "DEBUG: Error - EM: PSK clock failed"); PrintAndLogEx(DEBUG, "DEBUG: Error - EM: PSK clock failed");
@ -1071,7 +1108,8 @@ bool detectPSK(){
return true; return true;
} }
// try manchester - NOTE: ST only applies to T55x7 tags. // try manchester - NOTE: ST only applies to T55x7 tags.
bool detectASK_MAN(){ bool detectASK_MAN()
{
bool stcheck = false; bool stcheck = false;
if (!ASKDemod_ext("0 0 0", false, false, 1, &stcheck)) { if (!ASKDemod_ext("0 0 0", false, false, 1, &stcheck)) {
PrintAndLogEx(DEBUG, "DEBUG: Error - EM: ASK/Manchester Demod failed"); PrintAndLogEx(DEBUG, "DEBUG: Error - EM: ASK/Manchester Demod failed");
@ -1079,7 +1117,8 @@ bool detectASK_MAN(){
} }
return true; return true;
} }
bool detectASK_BI(){ bool detectASK_BI()
{
int ans = ASKbiphaseDemod("0 0 1", false); int ans = ASKbiphaseDemod("0 0 1", false);
if (!ans) { if (!ans) {
PrintAndLogEx(DEBUG, "DEBUG: Error - EM: ASK/biphase normal demod failed"); PrintAndLogEx(DEBUG, "DEBUG: Error - EM: ASK/biphase normal demod failed");
@ -1094,7 +1133,8 @@ bool detectASK_BI(){
} }
// param: idx - start index in demoded data. // param: idx - start index in demoded data.
bool setDemodBufferEM(uint32_t *word, size_t idx){ bool setDemodBufferEM(uint32_t *word, size_t idx)
{
//test for even parity bits. //test for even parity bits.
uint8_t parity[45] = {0}; uint8_t parity[45] = {0};
@ -1117,7 +1157,8 @@ bool setDemodBufferEM(uint32_t *word, size_t idx){
// FSK, PSK, ASK/MANCHESTER, ASK/BIPHASE, ASK/DIPHASE // FSK, PSK, ASK/MANCHESTER, ASK/BIPHASE, ASK/DIPHASE
// should cover 90% of known used configs // should cover 90% of known used configs
// the rest will need to be manually demoded for now... // the rest will need to be manually demoded for now...
bool demodEM4x05resp(uint32_t *word) { bool demodEM4x05resp(uint32_t *word)
{
size_t idx = 0; size_t idx = 0;
*word = 0; *word = 0;
if (detectASK_MAN() && doPreambleSearch(&idx)) if (detectASK_MAN() && doPreambleSearch(&idx))
@ -1141,7 +1182,8 @@ bool demodEM4x05resp(uint32_t *word) {
} }
//////////////// 4205 / 4305 commands //////////////// 4205 / 4305 commands
int EM4x05ReadWord_ext(uint8_t addr, uint32_t pwd, bool usePwd, uint32_t *word) { int EM4x05ReadWord_ext(uint8_t addr, uint32_t pwd, bool usePwd, uint32_t *word)
{
UsbCommand c = {CMD_EM4X_READ_WORD, {addr, pwd, usePwd}}; UsbCommand c = {CMD_EM4X_READ_WORD, {addr, pwd, usePwd}};
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
@ -1157,7 +1199,8 @@ int EM4x05ReadWord_ext(uint8_t addr, uint32_t pwd, bool usePwd, uint32_t *word)
return demodEM4x05resp(word); return demodEM4x05resp(word);
} }
int CmdEM4x05Dump(const char *Cmd) { int CmdEM4x05Dump(const char *Cmd)
{
uint8_t addr = 0; uint8_t addr = 0;
uint32_t pwd = 0; uint32_t pwd = 0;
bool usePwd = false; bool usePwd = false;
@ -1190,7 +1233,8 @@ int CmdEM4x05Dump(const char *Cmd) {
return success; return success;
} }
int CmdEM4x05Read(const char *Cmd) { int CmdEM4x05Read(const char *Cmd)
{
uint8_t addr; uint8_t addr;
uint32_t pwd; uint32_t pwd;
bool usePwd = false; bool usePwd = false;
@ -1220,7 +1264,8 @@ int CmdEM4x05Read(const char *Cmd) {
return isOk; return isOk;
} }
int CmdEM4x05Write(const char *Cmd) { int CmdEM4x05Write(const char *Cmd)
{
uint8_t ctmp = tolower(param_getchar(Cmd, 0)); uint8_t ctmp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_em4x05_write(); if (strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_em4x05_write();
@ -1268,7 +1313,8 @@ int CmdEM4x05Write(const char *Cmd) {
return isOk; return isOk;
} }
void printEM4x05config(uint32_t wordData) { void printEM4x05config(uint32_t wordData)
{
uint16_t datarate = (((wordData & 0x3F) + 1) * 2); uint16_t datarate = (((wordData & 0x3F) + 1) * 2);
uint8_t encoder = ((wordData >> 6) & 0xF); uint8_t encoder = ((wordData >> 6) & 0xF);
char enc[14]; char enc[14];
@ -1283,31 +1329,69 @@ void printEM4x05config(uint32_t wordData) {
uint8_t numblks = EM4x05_GET_NUM_BLOCKS(wordData); uint8_t numblks = EM4x05_GET_NUM_BLOCKS(wordData);
uint8_t LWR = numblks + 5 - 1; //last word read uint8_t LWR = numblks + 5 - 1; //last word read
switch (encoder) { switch (encoder) {
case 0: snprintf(enc,sizeof(enc),"NRZ"); break; case 0:
case 1: snprintf(enc,sizeof(enc),"Manchester"); break; snprintf(enc, sizeof(enc), "NRZ");
case 2: snprintf(enc,sizeof(enc),"Biphase"); break; break;
case 3: snprintf(enc,sizeof(enc),"Miller"); break; case 1:
case 4: snprintf(enc,sizeof(enc),"PSK1"); break; snprintf(enc, sizeof(enc), "Manchester");
case 5: snprintf(enc,sizeof(enc),"PSK2"); break; break;
case 6: snprintf(enc,sizeof(enc),"PSK3"); break; case 2:
case 7: snprintf(enc,sizeof(enc),"Unknown"); break; snprintf(enc, sizeof(enc), "Biphase");
case 8: snprintf(enc,sizeof(enc),"FSK1"); break; break;
case 9: snprintf(enc,sizeof(enc),"FSK2"); break; case 3:
default: snprintf(enc,sizeof(enc),"Unknown"); break; snprintf(enc, sizeof(enc), "Miller");
break;
case 4:
snprintf(enc, sizeof(enc), "PSK1");
break;
case 5:
snprintf(enc, sizeof(enc), "PSK2");
break;
case 6:
snprintf(enc, sizeof(enc), "PSK3");
break;
case 7:
snprintf(enc, sizeof(enc), "Unknown");
break;
case 8:
snprintf(enc, sizeof(enc), "FSK1");
break;
case 9:
snprintf(enc, sizeof(enc), "FSK2");
break;
default:
snprintf(enc, sizeof(enc), "Unknown");
break;
} }
switch (PSKcf) { switch (PSKcf) {
case 0: snprintf(cf,sizeof(cf),"RF/2"); break; case 0:
case 1: snprintf(cf,sizeof(cf),"RF/8"); break; snprintf(cf, sizeof(cf), "RF/2");
case 2: snprintf(cf,sizeof(cf),"RF/4"); break; break;
case 3: snprintf(cf,sizeof(cf),"unknown"); break; case 1:
snprintf(cf, sizeof(cf), "RF/8");
break;
case 2:
snprintf(cf, sizeof(cf), "RF/4");
break;
case 3:
snprintf(cf, sizeof(cf), "unknown");
break;
} }
switch (delay) { switch (delay) {
case 0: snprintf(cdelay, sizeof(cdelay),"no delay"); break; case 0:
case 1: snprintf(cdelay, sizeof(cdelay),"BP/8 or 1/8th bit period delay"); break; snprintf(cdelay, sizeof(cdelay), "no delay");
case 2: snprintf(cdelay, sizeof(cdelay),"BP/4 or 1/4th bit period delay"); break; break;
case 3: snprintf(cdelay, sizeof(cdelay),"no delay"); break; case 1:
snprintf(cdelay, sizeof(cdelay), "BP/8 or 1/8th bit period delay");
break;
case 2:
snprintf(cdelay, sizeof(cdelay), "BP/4 or 1/4th bit period delay");
break;
case 3:
snprintf(cdelay, sizeof(cdelay), "no delay");
break;
} }
uint8_t readLogin = (wordData & EM4x05_READ_LOGIN_REQ) >> 18; uint8_t readLogin = (wordData & EM4x05_READ_LOGIN_REQ) >> 18;
uint8_t readHKL = (wordData & EM4x05_READ_HK_LOGIN_REQ) >> 19; uint8_t readHKL = (wordData & EM4x05_READ_HK_LOGIN_REQ) >> 19;
@ -1334,27 +1418,48 @@ void printEM4x05config(uint32_t wordData) {
PrintAndLogEx(NORMAL, " Pigeon: %u | Pigeon Mode is %s\n", pigeon, pigeon ? "Enabled" : "Disabled"); PrintAndLogEx(NORMAL, " Pigeon: %u | Pigeon Mode is %s\n", pigeon, pigeon ? "Enabled" : "Disabled");
} }
void printEM4x05info(uint32_t block0, uint32_t serial) { void printEM4x05info(uint32_t block0, uint32_t serial)
{
uint8_t chipType = (block0 >> 1) & 0xF; uint8_t chipType = (block0 >> 1) & 0xF;
uint8_t cap = (block0 >> 5) & 3; uint8_t cap = (block0 >> 5) & 3;
uint16_t custCode = (block0 >> 9) & 0x3FF; uint16_t custCode = (block0 >> 9) & 0x3FF;
switch (chipType) { switch (chipType) {
case 9: PrintAndLogEx(NORMAL, "\n Chip Type: %u | EM4305", chipType); break; case 9:
case 8: PrintAndLogEx(NORMAL, "\n Chip Type: %u | EM4205", chipType); break; PrintAndLogEx(NORMAL, "\n Chip Type: %u | EM4305", chipType);
case 4: PrintAndLogEx(NORMAL, " Chip Type: %u | Unknown", chipType); break; break;
case 2: PrintAndLogEx(NORMAL, " Chip Type: %u | EM4469", chipType); break; case 8:
PrintAndLogEx(NORMAL, "\n Chip Type: %u | EM4205", chipType);
break;
case 4:
PrintAndLogEx(NORMAL, " Chip Type: %u | Unknown", chipType);
break;
case 2:
PrintAndLogEx(NORMAL, " Chip Type: %u | EM4469", chipType);
break;
//add more here when known //add more here when known
default: PrintAndLogEx(NORMAL, " Chip Type: %u Unknown", chipType); break; default:
PrintAndLogEx(NORMAL, " Chip Type: %u Unknown", chipType);
break;
} }
switch (cap) { switch (cap) {
case 3: PrintAndLogEx(NORMAL, " Cap Type: %u | 330pF",cap); break; case 3:
case 2: PrintAndLogEx(NORMAL, " Cap Type: %u | %spF",cap, (chipType==2)? "75":"210"); break; PrintAndLogEx(NORMAL, " Cap Type: %u | 330pF", cap);
case 1: PrintAndLogEx(NORMAL, " Cap Type: %u | 250pF",cap); break; break;
case 0: PrintAndLogEx(NORMAL, " Cap Type: %u | no resonant capacitor",cap); break; case 2:
default: PrintAndLogEx(NORMAL, " Cap Type: %u | unknown",cap); break; PrintAndLogEx(NORMAL, " Cap Type: %u | %spF", cap, (chipType == 2) ? "75" : "210");
break;
case 1:
PrintAndLogEx(NORMAL, " Cap Type: %u | 250pF", cap);
break;
case 0:
PrintAndLogEx(NORMAL, " Cap Type: %u | no resonant capacitor", cap);
break;
default:
PrintAndLogEx(NORMAL, " Cap Type: %u | unknown", cap);
break;
} }
PrintAndLogEx(NORMAL, " Cust Code: %03u | %s", custCode, (custCode == 0x200) ? "Default" : "Unknown"); PrintAndLogEx(NORMAL, " Cust Code: %03u | %s", custCode, (custCode == 0x200) ? "Default" : "Unknown");
@ -1362,7 +1467,8 @@ void printEM4x05info(uint32_t block0, uint32_t serial) {
PrintAndLogEx(NORMAL, "\n Serial #: %08X\n", serial); PrintAndLogEx(NORMAL, "\n Serial #: %08X\n", serial);
} }
void printEM4x05ProtectionBits(uint32_t word) { void printEM4x05ProtectionBits(uint32_t word)
{
for (uint8_t i = 0; i < 15; i++) { for (uint8_t i = 0; i < 15; i++) {
PrintAndLogEx(NORMAL, " Word: %02u | %s", i, (((1 << i) & word) || i < 2) ? "Is Write Locked" : "Is Not Write Locked"); PrintAndLogEx(NORMAL, " Word: %02u | %s", i, (((1 << i) & word) || i < 2) ? "Is Write Locked" : "Is Not Write Locked");
if (i == 14) if (i == 14)
@ -1371,12 +1477,14 @@ void printEM4x05ProtectionBits(uint32_t word) {
} }
//quick test for EM4x05/EM4x69 tag //quick test for EM4x05/EM4x69 tag
bool EM4x05IsBlock0(uint32_t *word) { bool EM4x05IsBlock0(uint32_t *word)
{
int res = EM4x05ReadWord_ext(0, 0, false, word); int res = EM4x05ReadWord_ext(0, 0, false, word);
return (res > 0) ? true : false; return (res > 0) ? true : false;
} }
int CmdEM4x05Info(const char *Cmd) { int CmdEM4x05Info(const char *Cmd)
{
#define EM_SERIAL_BLOCK 1 #define EM_SERIAL_BLOCK 1
#define EM_CONFIG_BLOCK 4 #define EM_CONFIG_BLOCK 4
#define EM_PROT1_BLOCK 14 #define EM_PROT1_BLOCK 14
@ -1445,13 +1553,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFEM4X(const char *Cmd) { int CmdLFEM4X(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -31,7 +31,8 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_lf_fdx_clone(void){ int usage_lf_fdx_clone(void)
{
PrintAndLogEx(NORMAL, "Clone a FDX-B animal tag to a T55x7 tag."); PrintAndLogEx(NORMAL, "Clone a FDX-B animal tag to a T55x7 tag.");
PrintAndLogEx(NORMAL, "Usage: lf fdx clone [h] <country id> <animal id> <Q5>"); PrintAndLogEx(NORMAL, "Usage: lf fdx clone [h] <country id> <animal id> <Q5>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -49,7 +50,8 @@ int usage_lf_fdx_clone(void){
return 0; return 0;
} }
int usage_lf_fdx_sim(void) { int usage_lf_fdx_sim(void)
{
PrintAndLogEx(NORMAL, "Enables simulation of FDX-B animal tag"); PrintAndLogEx(NORMAL, "Enables simulation of FDX-B animal tag");
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
@ -66,7 +68,8 @@ int usage_lf_fdx_sim(void) {
// Ask/Biphase Demod then try to locate an ISO 11784/85 ID // Ask/Biphase Demod then try to locate an ISO 11784/85 ID
// BitStream must contain previously askrawdemod and biphasedemoded data // BitStream must contain previously askrawdemod and biphasedemoded data
int detectFDXB(uint8_t *dest, size_t *size) { int detectFDXB(uint8_t *dest, size_t *size)
{
//make sure buffer has enough data //make sure buffer has enough data
if (*size < 128 * 2) return -1; if (*size < 128 * 2) return -1;
size_t startIdx = 0; size_t startIdx = 0;
@ -79,7 +82,8 @@ int detectFDXB(uint8_t *dest, size_t *size) {
} }
// clearing the topbit needed for the preambl detection. // clearing the topbit needed for the preambl detection.
static void verify_values(uint32_t countryid, uint64_t animalid){ static void verify_values(uint32_t countryid, uint64_t animalid)
{
if ((animalid & 0x3FFFFFFFFF) != animalid) { if ((animalid & 0x3FFFFFFFFF) != animalid) {
animalid &= 0x3FFFFFFFFF; animalid &= 0x3FFFFFFFFF;
PrintAndLogEx(INFO, "Animal ID Truncated to 38bits: %"PRIx64, animalid); PrintAndLogEx(INFO, "Animal ID Truncated to 38bits: %"PRIx64, animalid);
@ -90,7 +94,8 @@ static void verify_values(uint32_t countryid, uint64_t animalid){
} }
} }
int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits) { int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits)
{
// add preamble ten 0x00 and one 0x01 // add preamble ten 0x00 and one 0x01
memset(bits, 0x00, 10); memset(bits, 0x00, 10);
@ -157,7 +162,8 @@ int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t
-- sample: 985121004515220 [ 37FF65B88EF94 ] -- sample: 985121004515220 [ 37FF65B88EF94 ]
*/ */
int CmdFDXBdemodBI(const char *Cmd){ int CmdFDXBdemodBI(const char *Cmd)
{
int clk = 32; int clk = 32;
int invert = 1, errCnt = 0, offset = 0, maxErr = 0; int invert = 1, errCnt = 0, offset = 0, maxErr = 0;
@ -232,7 +238,8 @@ int CmdFDXBdemodBI(const char *Cmd){
//see ASKDemod for what args are accepted //see ASKDemod for what args are accepted
//almost the same demod as cmddata.c/CmdFDXBdemodBI //almost the same demod as cmddata.c/CmdFDXBdemodBI
int CmdFdxDemod(const char *Cmd) { int CmdFdxDemod(const char *Cmd)
{
//Differential Biphase / di-phase (inverted biphase) //Differential Biphase / di-phase (inverted biphase)
//get binary from ask wave //get binary from ask wave
@ -301,12 +308,14 @@ int CmdFdxDemod(const char *Cmd) {
return 1; return 1;
} }
int CmdFdxRead(const char *Cmd) { int CmdFdxRead(const char *Cmd)
{
lf_read(true, 10000); lf_read(true, 10000);
return CmdFdxDemod(Cmd); return CmdFdxDemod(Cmd);
} }
int CmdFdxClone(const char *Cmd) { int CmdFdxClone(const char *Cmd)
{
uint32_t countryid = 0; uint32_t countryid = 0;
uint64_t animalid = 0; uint64_t animalid = 0;
@ -358,7 +367,8 @@ int CmdFdxClone(const char *Cmd) {
return 0; return 0;
} }
int CmdFdxSim(const char *Cmd) { int CmdFdxSim(const char *Cmd)
{
uint32_t countryid = 0; uint32_t countryid = 0;
uint64_t animalid = 0; uint64_t animalid = 0;
@ -397,13 +407,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFFdx(const char *Cmd) { int CmdLFFdx(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -11,7 +11,8 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_lf_guard_clone(void){ int usage_lf_guard_clone(void)
{
PrintAndLogEx(NORMAL, "clone a Guardall tag to a T55x7 tag."); PrintAndLogEx(NORMAL, "clone a Guardall tag to a T55x7 tag.");
PrintAndLogEx(NORMAL, "The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated. "); PrintAndLogEx(NORMAL, "The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated. ");
PrintAndLogEx(NORMAL, "Currently work only on 26bit"); PrintAndLogEx(NORMAL, "Currently work only on 26bit");
@ -27,7 +28,8 @@ int usage_lf_guard_clone(void){
return 0; return 0;
} }
int usage_lf_guard_sim(void) { int usage_lf_guard_sim(void)
{
PrintAndLogEx(NORMAL, "Enables simulation of Guardall card with specified card number."); PrintAndLogEx(NORMAL, "Enables simulation of Guardall card with specified card number.");
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated."); PrintAndLogEx(NORMAL, "The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated.");
@ -45,7 +47,8 @@ int usage_lf_guard_sim(void) {
} }
// Works for 26bits. // Works for 26bits.
int GetGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) { int GetGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits)
{
uint8_t xorKey = 0x66; uint8_t xorKey = 0x66;
uint8_t i; uint8_t i;
@ -144,7 +147,8 @@ int GetGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) {
// error returns as -x // error returns as -x
// success returns start position in bitstream // success returns start position in bitstream
// Bitstream must contain previously askrawdemod and biphasedemoded data // Bitstream must contain previously askrawdemod and biphasedemoded data
int detectGProxII(uint8_t *bits, size_t *size) { int detectGProxII(uint8_t *bits, size_t *size)
{
size_t startIdx = 0; size_t startIdx = 0;
uint8_t preamble[] = {1, 1, 1, 1, 1, 0}; uint8_t preamble[] = {1, 1, 1, 1, 1, 0};
@ -172,7 +176,8 @@ int detectGProxII(uint8_t *bits, size_t *size) {
//WARNING: if it fails during some points it will destroy the DemodBuffer data //WARNING: if it fails during some points it will destroy the DemodBuffer data
// but will leave the GraphBuffer intact. // but will leave the GraphBuffer intact.
//if successful it will push askraw data back to demod buffer ready for emulation //if successful it will push askraw data back to demod buffer ready for emulation
int CmdGuardDemod(const char *Cmd) { int CmdGuardDemod(const char *Cmd)
{
//Differential Biphase //Differential Biphase
//get binary from ask wave //get binary from ask wave
@ -253,12 +258,14 @@ int CmdGuardDemod(const char *Cmd) {
return 1; return 1;
} }
int CmdGuardRead(const char *Cmd) { int CmdGuardRead(const char *Cmd)
{
lf_read(true, 10000); lf_read(true, 10000);
return CmdGuardDemod(Cmd); return CmdGuardDemod(Cmd);
} }
int CmdGuardClone(const char *Cmd) { int CmdGuardClone(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0); char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_guard_clone(); if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_guard_clone();
@ -309,7 +316,8 @@ int CmdGuardClone(const char *Cmd) {
return 0; return 0;
} }
int CmdGuardSim(const char *Cmd) { int CmdGuardSim(const char *Cmd)
{
// Guard uses: clk: 64, invert: 0, encoding: 2 (ASK Biphase) // Guard uses: clk: 64, invert: 0, encoding: 2 (ASK Biphase)
uint8_t clock = 64, encoding = 2, separator = 0, invert = 0; uint8_t clock = 64, encoding = 2, separator = 0, invert = 0;
@ -355,13 +363,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFGuard(const char *Cmd) { int CmdLFGuard(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -16,7 +16,8 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_lf_hid_read(void){ int usage_lf_hid_read(void)
{
PrintAndLogEx(NORMAL, "Enables HID compatible reader mode printing details."); PrintAndLogEx(NORMAL, "Enables HID compatible reader mode printing details.");
PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "If the [1] option is provided, reader mode is exited after reading a single HID card."); PrintAndLogEx(NORMAL, "If the [1] option is provided, reader mode is exited after reading a single HID card.");
@ -31,7 +32,8 @@ int usage_lf_hid_read(void){
PrintAndLogEx(NORMAL, " lf hid read 1"); PrintAndLogEx(NORMAL, " lf hid read 1");
return 0; return 0;
} }
int usage_lf_hid_wiegand(void){ int usage_lf_hid_wiegand(void)
{
PrintAndLogEx(NORMAL, "This command converts facility code/card number to Wiegand code"); PrintAndLogEx(NORMAL, "This command converts facility code/card number to Wiegand code");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf hid wiegand [h] [OEM] [FC] [CN]"); PrintAndLogEx(NORMAL, "Usage: lf hid wiegand [h] [OEM] [FC] [CN]");
@ -44,7 +46,8 @@ int usage_lf_hid_wiegand(void){
PrintAndLogEx(NORMAL, " lf hid wiegand 0 101 2001"); PrintAndLogEx(NORMAL, " lf hid wiegand 0 101 2001");
return 0; return 0;
} }
int usage_lf_hid_sim(void){ int usage_lf_hid_sim(void)
{
PrintAndLogEx(NORMAL, "Enables simulation of HID card with card number."); PrintAndLogEx(NORMAL, "Enables simulation of HID card with card number.");
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
@ -56,7 +59,8 @@ int usage_lf_hid_sim(void){
PrintAndLogEx(NORMAL, " lf hid sim 2006ec0c86"); PrintAndLogEx(NORMAL, " lf hid sim 2006ec0c86");
return 0; return 0;
} }
int usage_lf_hid_clone(void){ int usage_lf_hid_clone(void)
{
PrintAndLogEx(NORMAL, "Clone HID to T55x7. Tag must be on antenna. "); PrintAndLogEx(NORMAL, "Clone HID to T55x7. Tag must be on antenna. ");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf hid clone [h] [ID] <L>"); PrintAndLogEx(NORMAL, "Usage: lf hid clone [h] [ID] <L>");
@ -69,7 +73,8 @@ int usage_lf_hid_clone(void){
PrintAndLogEx(NORMAL, " lf hid clone 2006ec0c86 L"); PrintAndLogEx(NORMAL, " lf hid clone 2006ec0c86 L");
return 0; return 0;
} }
int usage_lf_hid_brute(void){ int usage_lf_hid_brute(void)
{
PrintAndLogEx(NORMAL, "Enables bruteforce of HID readers with specified facility code."); PrintAndLogEx(NORMAL, "Enables bruteforce of HID readers with specified facility code.");
PrintAndLogEx(NORMAL, "This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step"); PrintAndLogEx(NORMAL, "This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step");
PrintAndLogEx(NORMAL, "if cardnumber is not given, it starts with 1 and goes up to 65535"); PrintAndLogEx(NORMAL, "if cardnumber is not given, it starts with 1 and goes up to 65535");
@ -91,7 +96,8 @@ int usage_lf_hid_brute(void){
} }
// sending three times. Didn't seem to break the previous sim? // sending three times. Didn't seem to break the previous sim?
static bool sendPing(void){ static bool sendPing(void)
{
UsbCommand ping = {CMD_PING, {1, 2, 3}}; UsbCommand ping = {CMD_PING, {1, 2, 3}};
SendCommand(&ping); SendCommand(&ping);
SendCommand(&ping); SendCommand(&ping);
@ -102,7 +108,8 @@ static bool sendPing(void){
return false; return false;
return true; return true;
} }
static bool sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, uint8_t *bits, bool verbose){ static bool sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, uint8_t *bits, bool verbose)
{
// this should be optional. // this should be optional.
if (verbose) if (verbose)
@ -124,7 +131,8 @@ static bool sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, ui
//by marshmellow (based on existing demod + holiman's refactor) //by marshmellow (based on existing demod + holiman's refactor)
//HID Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded) //HID Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded)
//print full HID Prox ID and some bit format details if found //print full HID Prox ID and some bit format details if found
int CmdHIDDemod(const char *Cmd) { int CmdHIDDemod(const char *Cmd)
{
//raw fsk demod no manchester decoding no start bit finding just get binary from wave //raw fsk demod no manchester decoding no start bit finding just get binary from wave
uint32_t hi2 = 0, hi = 0, lo = 0; uint32_t hi2 = 0, hi = 0, lo = 0;
@ -198,8 +206,7 @@ int CmdHIDDemod(const char *Cmd) {
cardnum = (lo >> 1) & 0xFFFFF; cardnum = (lo >> 1) & 0xFFFFF;
fc = ((hi & 1) << 11) | (lo >> 21); fc = ((hi & 1) << 11) | (lo >> 21);
} }
} } else { //if bit 38 is not set then 37 bit format is used
else { //if bit 38 is not set then 37 bit format is used
fmtLen = 37; fmtLen = 37;
fc = 0; fc = 0;
cardnum = 0; cardnum = 0;
@ -223,14 +230,16 @@ int CmdHIDDemod(const char *Cmd) {
} }
// this read is the "normal" read, which download lf signal and tries to demod here. // this read is the "normal" read, which download lf signal and tries to demod here.
int CmdHIDRead(const char *Cmd) { int CmdHIDRead(const char *Cmd)
{
lf_read(true, 12000); lf_read(true, 12000);
return CmdHIDDemod(Cmd); return CmdHIDDemod(Cmd);
} }
// this read loops on device side. // this read loops on device side.
// uses the demod in lfops.c // uses the demod in lfops.c
int CmdHIDRead_device(const char *Cmd) { int CmdHIDRead_device(const char *Cmd)
{
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_hid_read(); if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_hid_read();
uint8_t findone = (Cmd[0] == '1') ? 1 : 0; uint8_t findone = (Cmd[0] == '1') ? 1 : 0;
@ -240,7 +249,8 @@ int CmdHIDRead_device(const char *Cmd) {
return 0; return 0;
} }
int CmdHIDSim(const char *Cmd) { int CmdHIDSim(const char *Cmd)
{
uint32_t hi = 0, lo = 0; uint32_t hi = 0, lo = 0;
uint32_t n = 0, i = 0; uint32_t n = 0, i = 0;
@ -261,7 +271,8 @@ int CmdHIDSim(const char *Cmd) {
return 0; return 0;
} }
int CmdHIDClone(const char *Cmd) { int CmdHIDClone(const char *Cmd)
{
uint32_t hi2 = 0, hi = 0, lo = 0; uint32_t hi2 = 0, hi = 0, lo = 0;
uint32_t n = 0, i = 0; uint32_t n = 0, i = 0;
@ -308,7 +319,8 @@ typedef struct {
size_t Wiegand_n; size_t Wiegand_n;
} wiegand_t; } wiegand_t;
static void addHIDMarker(uint8_t fmtlen, uint8_t *out) { static void addHIDMarker(uint8_t fmtlen, uint8_t *out)
{
// temp array // temp array
uint8_t arr[BITS]; uint8_t arr[BITS];
memset(arr, 0, BITS); memset(arr, 0, BITS);
@ -334,7 +346,8 @@ static void addHIDMarker(uint8_t fmtlen, uint8_t *out) {
arr[BITS - 38] = 1; arr[BITS - 38] = 1;
memcpy(out, arr, BITS); memcpy(out, arr, BITS);
break; break;
default:break; default:
break;
} }
} }
@ -376,7 +389,8 @@ static void addHIDMarker(uint8_t fmtlen, uint8_t *out) {
// } // }
//static void calc26(uint16_t fc, uint32_t cardno, uint8_t *out){ //static void calc26(uint16_t fc, uint32_t cardno, uint8_t *out){
static void calc26(uint16_t fc, uint32_t cardno, uint8_t *out){ static void calc26(uint16_t fc, uint32_t cardno, uint8_t *out)
{
uint8_t wiegand[24]; uint8_t wiegand[24];
num_to_bytebits(fc, 8, wiegand); num_to_bytebits(fc, 8, wiegand);
num_to_bytebits(cardno, 16, wiegand + 8); num_to_bytebits(cardno, 16, wiegand + 8);
@ -384,7 +398,8 @@ static void calc26(uint16_t fc, uint32_t cardno, uint8_t *out){
} }
// static void calc33(uint16_t fc, uint32_t cardno, uint8_t *out){ // static void calc33(uint16_t fc, uint32_t cardno, uint8_t *out){
// } // }
static void calc34(uint16_t fc, uint32_t cardno, uint8_t *out){ static void calc34(uint16_t fc, uint32_t cardno, uint8_t *out)
{
uint8_t wiegand[32]; uint8_t wiegand[32];
num_to_bytebits(fc, 16, wiegand); num_to_bytebits(fc, 16, wiegand);
num_to_bytebits(cardno, 16, wiegand + 16); num_to_bytebits(cardno, 16, wiegand + 16);
@ -394,7 +409,8 @@ static void calc34(uint16_t fc, uint32_t cardno, uint8_t *out){
// *lo = ((cardno & 0xFFFFF) << 1) | fc << 21; // *lo = ((cardno & 0xFFFFF) << 1) | fc << 21;
// *hi = (1 << 5) | ((fc >> 11) & 1); // *hi = (1 << 5) | ((fc >> 11) & 1);
// } // }
static void calc37S(uint16_t fc, uint32_t cardno, uint8_t *out){ static void calc37S(uint16_t fc, uint32_t cardno, uint8_t *out)
{
// FC 2 - 17 - 16 bit // FC 2 - 17 - 16 bit
// cardno 18 - 36 - 19 bit // cardno 18 - 36 - 19 bit
// Even P1 1 - 19 // Even P1 1 - 19
@ -404,7 +420,8 @@ static void calc37S(uint16_t fc, uint32_t cardno, uint8_t *out){
num_to_bytebits(cardno, 19, wiegand + 16); num_to_bytebits(cardno, 19, wiegand + 16);
wiegand_add_parity(out, wiegand, sizeof(wiegand)); wiegand_add_parity(out, wiegand, sizeof(wiegand));
} }
static void calc37H(uint64_t cardno, uint8_t *out){ static void calc37H(uint64_t cardno, uint8_t *out)
{
// SC NONE // SC NONE
// cardno 1-35 34 bits // cardno 1-35 34 bits
// Even Parity 0th bit 1-18 // Even Parity 0th bit 1-18
@ -422,23 +439,34 @@ static void calc37H(uint64_t cardno, uint8_t *out){
// *hi = (cardno >> 31); // *hi = (cardno >> 31);
// } // }
void calcWiegand(uint8_t fmtlen, uint16_t fc, uint64_t cardno, uint8_t *bits){ void calcWiegand(uint8_t fmtlen, uint16_t fc, uint64_t cardno, uint8_t *bits)
{
uint32_t cn32 = (cardno & 0xFFFFFFFF); uint32_t cn32 = (cardno & 0xFFFFFFFF);
switch (fmtlen) { switch (fmtlen) {
case 26: calc26(fc, cn32, bits); break; case 26:
calc26(fc, cn32, bits);
break;
// case 33 : calc33(fc, cn32, bits); break; // case 33 : calc33(fc, cn32, bits); break;
case 34: calc34(fc, cn32, bits); break; case 34:
calc34(fc, cn32, bits);
break;
// case 35 : calc35(fc, cn32, bits); break; // case 35 : calc35(fc, cn32, bits); break;
case 37: calc37S(fc, cn32, bits); break; case 37:
case 38: calc37H(cardno, bits); break; calc37S(fc, cn32, bits);
break;
case 38:
calc37H(cardno, bits);
break;
// case 40 : calc40(cardno, bits); break; // case 40 : calc40(cardno, bits); break;
// case 44 : { break; } // case 44 : { break; }
// case 84 : { break; } // case 84 : { break; }
default: break; default:
break;
} }
} }
int CmdHIDWiegand(const char *Cmd) { int CmdHIDWiegand(const char *Cmd)
{
uint32_t oem = 0, fc = 0; uint32_t oem = 0, fc = 0;
uint64_t cardnum = 0; uint64_t cardnum = 0;
uint64_t blocks = 0, wiegand = 0; uint64_t blocks = 0, wiegand = 0;
@ -483,7 +511,8 @@ int CmdHIDWiegand(const char *Cmd) {
return 0; return 0;
} }
int CmdHIDBrute(const char *Cmd){ int CmdHIDBrute(const char *Cmd)
{
bool errors = false, verbose = false; bool errors = false, verbose = false;
uint32_t fc = 0, cn = 0, delay = 1000; uint32_t fc = 0, cn = 0, delay = 1000;
@ -554,7 +583,8 @@ int CmdHIDBrute(const char *Cmd){
} }
if (ukbhit()) { if (ukbhit()) {
int gc = getchar(); (void)gc; int gc = getchar();
(void)gc;
PrintAndLogEx(INFO, "aborted via keyboard!"); PrintAndLogEx(INFO, "aborted via keyboard!");
return sendPing(); return sendPing();
} }
@ -582,13 +612,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFHID(const char *Cmd) { int CmdLFHID(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -25,11 +25,13 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
size_t nbytes(size_t nbits) { size_t nbytes(size_t nbits)
{
return (nbits / 8) + ((nbits % 8) > 0); return (nbits / 8) + ((nbits % 8) > 0);
} }
int CmdLFHitagList(const char *Cmd) { int CmdLFHitagList(const char *Cmd)
{
uint8_t *got = calloc(USB_CMD_DATA_SIZE, sizeof(uint8_t)); uint8_t *got = calloc(USB_CMD_DATA_SIZE, sizeof(uint8_t));
if (!got) { if (!got) {
PrintAndLogEx(WARNING, "Cannot allocate memory for trace"); PrintAndLogEx(WARNING, "Cannot allocate memory for trace");
@ -124,8 +126,7 @@ int CmdLFHitagList(const char *Cmd) {
//if((parityBits >> (len - j - 1)) & 0x01) { //if((parityBits >> (len - j - 1)) & 0x01) {
if (isResponse && (oddparity8(frame[j]) != ((parityBits >> (len - j - 1)) & 0x01))) { if (isResponse && (oddparity8(frame[j]) != ((parityBits >> (len - j - 1)) & 0x01))) {
sprintf(line + (j * 4), "%02x! ", frame[j]); sprintf(line + (j * 4), "%02x! ", frame[j]);
} } else {
else {
sprintf(line + (j * 4), "%02x ", frame[j]); sprintf(line + (j * 4), "%02x ", frame[j]);
} }
} }
@ -157,14 +158,16 @@ int CmdLFHitagList(const char *Cmd) {
return 0; return 0;
} }
int CmdLFHitagSnoop(const char *Cmd) { int CmdLFHitagSnoop(const char *Cmd)
{
UsbCommand c = {CMD_SNOOP_HITAG}; UsbCommand c = {CMD_SNOOP_HITAG};
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
return 0; return 0;
} }
int CmdLFHitagSim(const char *Cmd) { int CmdLFHitagSim(const char *Cmd)
{
UsbCommand c = {CMD_SIMULATE_HITAG}; UsbCommand c = {CMD_SIMULATE_HITAG};
char filename[FILE_PATH_SIZE] = { 0x00 }; char filename[FILE_PATH_SIZE] = { 0x00 };
@ -200,7 +203,8 @@ int CmdLFHitagSim(const char *Cmd) {
return 0; return 0;
} }
int CmdLFHitagReader(const char *Cmd) { int CmdLFHitagReader(const char *Cmd)
{
UsbCommand c = {CMD_READER_HITAG, {0, 0, 0} }; //, {param_get32ex(Cmd,0,0,10),param_get32ex(Cmd,1,0,16),param_get32ex(Cmd,2,0,16),param_get32ex(Cmd,3,0,16)}}; UsbCommand c = {CMD_READER_HITAG, {0, 0, 0} }; //, {param_get32ex(Cmd,0,0,10),param_get32ex(Cmd,1,0,16),param_get32ex(Cmd,2,0,16),param_get32ex(Cmd,3,0,16)}};
hitag_data *htd = (hitag_data *)c.d.asBytes; hitag_data *htd = (hitag_data *)c.d.asBytes;
@ -211,21 +215,26 @@ int CmdLFHitagReader(const char *Cmd) {
c.cmd = CMD_READ_HITAG_S; c.cmd = CMD_READ_HITAG_S;
num_to_bytes(param_get32ex(Cmd, 1, 0, 16), 4, htd->auth.NrAr); num_to_bytes(param_get32ex(Cmd, 1, 0, 16), 4, htd->auth.NrAr);
num_to_bytes(param_get32ex(Cmd, 2, 0, 16), 4, htd->auth.NrAr + 4); num_to_bytes(param_get32ex(Cmd, 2, 0, 16), 4, htd->auth.NrAr + 4);
} break; }
break;
case 02: { //RHTSF_KEY case 02: { //RHTSF_KEY
c.cmd = CMD_READ_HITAG_S; c.cmd = CMD_READ_HITAG_S;
num_to_bytes(param_get64ex(Cmd, 1, 0, 16), 6, htd->crypto.key); num_to_bytes(param_get64ex(Cmd, 1, 0, 16), 6, htd->crypto.key);
} break; }
break;
case RHT2F_PASSWORD: { case RHT2F_PASSWORD: {
num_to_bytes(param_get32ex(Cmd, 1, 0, 16), 4, htd->pwd.password); num_to_bytes(param_get32ex(Cmd, 1, 0, 16), 4, htd->pwd.password);
} break; }
break;
case RHT2F_AUTHENTICATE: { case RHT2F_AUTHENTICATE: {
num_to_bytes(param_get32ex(Cmd, 1, 0, 16), 4, htd->auth.NrAr); num_to_bytes(param_get32ex(Cmd, 1, 0, 16), 4, htd->auth.NrAr);
num_to_bytes(param_get32ex(Cmd, 2, 0, 16), 4, htd->auth.NrAr + 4); num_to_bytes(param_get32ex(Cmd, 2, 0, 16), 4, htd->auth.NrAr + 4);
} break; }
break;
case RHT2F_CRYPTO: { case RHT2F_CRYPTO: {
num_to_bytes(param_get64ex(Cmd, 1, 0, 16), 6, htd->crypto.key); num_to_bytes(param_get64ex(Cmd, 1, 0, 16), 6, htd->crypto.key);
} break; }
break;
case RHT2F_TEST_AUTH_ATTEMPTS: { case RHT2F_TEST_AUTH_ATTEMPTS: {
// No additional parameters needed // No additional parameters needed
} break; } break;
@ -248,7 +257,8 @@ int CmdLFHitagReader(const char *Cmd) {
PrintAndLogEx(NORMAL, " 25 (test recorded authentications)"); PrintAndLogEx(NORMAL, " 25 (test recorded authentications)");
PrintAndLogEx(NORMAL, " 26 just read UID"); PrintAndLogEx(NORMAL, " 26 just read UID");
return 1; return 1;
} break; }
break;
} }
// Copy the hitag2 function into the first argument // Copy the hitag2 function into the first argument
@ -289,7 +299,8 @@ int CmdLFHitagReader(const char *Cmd) {
return 0; return 0;
} }
int CmdLFHitagSimS(const char *Cmd) { int CmdLFHitagSimS(const char *Cmd)
{
UsbCommand c = { CMD_SIMULATE_HITAG_S }; UsbCommand c = { CMD_SIMULATE_HITAG_S };
char filename[FILE_PATH_SIZE] = { 0x00 }; char filename[FILE_PATH_SIZE] = { 0x00 };
FILE *f; FILE *f;
@ -324,7 +335,8 @@ int CmdLFHitagSimS(const char *Cmd) {
return 0; return 0;
} }
int CmdLFHitagCheckChallenges(const char *Cmd) { int CmdLFHitagCheckChallenges(const char *Cmd)
{
UsbCommand c = { CMD_TEST_HITAGS_TRACES }; UsbCommand c = { CMD_TEST_HITAGS_TRACES };
char filename[FILE_PATH_SIZE] = { 0x00 }; char filename[FILE_PATH_SIZE] = { 0x00 };
FILE *f; FILE *f;
@ -359,7 +371,8 @@ int CmdLFHitagCheckChallenges(const char *Cmd) {
return 0; return 0;
} }
int CmdLFHitagWP(const char *Cmd) { int CmdLFHitagWP(const char *Cmd)
{
UsbCommand c = { CMD_WR_HITAG_S }; UsbCommand c = { CMD_WR_HITAG_S };
hitag_data *htd = (hitag_data *)c.d.asBytes; hitag_data *htd = (hitag_data *)c.d.asBytes;
hitag_function htf = param_get32ex(Cmd, 0, 0, 10); hitag_function htf = param_get32ex(Cmd, 0, 0, 10);
@ -368,15 +381,17 @@ int CmdLFHitagWP(const char *Cmd) {
num_to_bytes(param_get64ex(Cmd, 1, 0, 16), 8, htd->auth.NrAr); num_to_bytes(param_get64ex(Cmd, 1, 0, 16), 8, htd->auth.NrAr);
c.arg[2] = param_get32ex(Cmd, 2, 0, 10); c.arg[2] = param_get32ex(Cmd, 2, 0, 10);
num_to_bytes(param_get32ex(Cmd, 3, 0, 16), 4, htd->auth.data); num_to_bytes(param_get32ex(Cmd, 3, 0, 16), 4, htd->auth.data);
} break; }
break;
case 04: case 04:
case 24: case 24: {
{ //WHTSF_KEY //WHTSF_KEY
num_to_bytes(param_get64ex(Cmd, 1, 0, 16), 6, htd->crypto.key); num_to_bytes(param_get64ex(Cmd, 1, 0, 16), 6, htd->crypto.key);
c.arg[2] = param_get32ex(Cmd, 2, 0, 10); c.arg[2] = param_get32ex(Cmd, 2, 0, 10);
num_to_bytes(param_get32ex(Cmd, 3, 0, 16), 4, htd->crypto.data); num_to_bytes(param_get32ex(Cmd, 3, 0, 16), 4, htd->crypto.data);
} break; }
break;
default: { default: {
PrintAndLogEx(WARNING, "Error: unkown writer function %d", htf); PrintAndLogEx(WARNING, "Error: unkown writer function %d", htf);
PrintAndLogEx(NORMAL, "Hitag writer functions"); PrintAndLogEx(NORMAL, "Hitag writer functions");
@ -386,7 +401,8 @@ int CmdLFHitagWP(const char *Cmd) {
PrintAndLogEx(NORMAL, " Hitag1 (1*)"); PrintAndLogEx(NORMAL, " Hitag1 (1*)");
PrintAndLogEx(NORMAL, " Hitag2 (2*)"); PrintAndLogEx(NORMAL, " Hitag2 (2*)");
return 1; return 1;
} break; }
break;
} }
// Copy the hitag function into the first argument // Copy the hitag function into the first argument
c.arg[0] = htf; c.arg[0] = htf;
@ -413,13 +429,15 @@ static command_t CommandTable[] = {
{ NULL, NULL, 0, NULL } { NULL, NULL, 0, NULL }
}; };
int CmdLFHitag(const char *Cmd) { int CmdLFHitag(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -12,7 +12,8 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_lf_indala_demod(void) { int usage_lf_indala_demod(void)
{
PrintAndLogEx(NORMAL, "Enables Indala compatible reader mode printing details of scanned tags."); PrintAndLogEx(NORMAL, "Enables Indala compatible reader mode printing details of scanned tags.");
PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
@ -25,7 +26,8 @@ int usage_lf_indala_demod(void) {
return 0; return 0;
} }
int usage_lf_indala_sim(void) { int usage_lf_indala_sim(void)
{
PrintAndLogEx(NORMAL, "Enables simulation of Indala card with specified uid."); PrintAndLogEx(NORMAL, "Enables simulation of Indala card with specified uid.");
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
@ -39,7 +41,8 @@ int usage_lf_indala_sim(void) {
return 0; return 0;
} }
int usage_lf_indala_clone(void) { int usage_lf_indala_clone(void)
{
PrintAndLogEx(NORMAL, "Enables cloning of Indala card with specified uid onto T55x7."); PrintAndLogEx(NORMAL, "Enables cloning of Indala card with specified uid onto T55x7.");
PrintAndLogEx(NORMAL, "The T55x7 must be on the antenna when issuing this command. T55x7 blocks are calculated and printed in the process."); PrintAndLogEx(NORMAL, "The T55x7 must be on the antenna when issuing this command. T55x7 blocks are calculated and printed in the process.");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
@ -56,7 +59,8 @@ int usage_lf_indala_clone(void) {
// redesigned by marshmellow adjusted from existing decode functions // redesigned by marshmellow adjusted from existing decode functions
// indala id decoding // indala id decoding
int indala64decode(uint8_t *dest, size_t *size, uint8_t *invert) { int indala64decode(uint8_t *dest, size_t *size, uint8_t *invert)
{
//standard 64 bit indala formats including 26 bit 40134 format //standard 64 bit indala formats including 26 bit 40134 format
uint8_t preamble64[] = {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; uint8_t preamble64[] = {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
uint8_t preamble64_i[] = {0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}; uint8_t preamble64_i[] = {0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0};
@ -78,7 +82,8 @@ int indala64decode(uint8_t *dest, size_t *size, uint8_t *invert) {
return (int) idx; return (int) idx;
} }
int indala224decode(uint8_t *dest, size_t *size, uint8_t *invert) { int indala224decode(uint8_t *dest, size_t *size, uint8_t *invert)
{
//large 224 bit indala formats (different preamble too...) //large 224 bit indala formats (different preamble too...)
uint8_t preamble224[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; uint8_t preamble224[] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
uint8_t preamble224_i[] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}; uint8_t preamble224_i[] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0};
@ -106,7 +111,8 @@ int indala224decode(uint8_t *dest, size_t *size, uint8_t *invert) {
} }
// this read is the "normal" read, which download lf signal and tries to demod here. // this read is the "normal" read, which download lf signal and tries to demod here.
int CmdIndalaRead(const char *Cmd) { int CmdIndalaRead(const char *Cmd)
{
lf_read(true, 30000); lf_read(true, 30000);
return CmdIndalaDemod(Cmd); return CmdIndalaDemod(Cmd);
} }
@ -114,7 +120,8 @@ int CmdIndalaRead(const char *Cmd) {
// Indala 26 bit decode // Indala 26 bit decode
// by marshmellow // by marshmellow
// optional arguments - same as PSKDemod (clock & invert & maxerr) // optional arguments - same as PSKDemod (clock & invert & maxerr)
int CmdIndalaDemod(const char *Cmd) { int CmdIndalaDemod(const char *Cmd)
{
int ans; int ans;
if (strlen(Cmd) > 0) if (strlen(Cmd) > 0)
ans = PSKDemod(Cmd, 0); ans = PSKDemod(Cmd, 0);
@ -178,7 +185,8 @@ int CmdIndalaDemod(const char *Cmd) {
// returns false positives more often - but runs against more sets of samples // returns false positives more often - but runs against more sets of samples
// poor psk signal can be difficult to demod this approach might succeed when the other fails // poor psk signal can be difficult to demod this approach might succeed when the other fails
// but the other appears to currently be more accurate than this approach most of the time. // but the other appears to currently be more accurate than this approach most of the time.
int CmdIndalaDemodAlt(const char *Cmd) { int CmdIndalaDemodAlt(const char *Cmd)
{
// Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID
int state = -1; int state = -1;
int count = 0; int count = 0;
@ -314,8 +322,7 @@ int CmdIndalaDemodAlt(const char *Cmd) {
} }
} }
PrintAndLogEx(SUCCESS, "UID | %s (%x%08x)", showbits, uid1, uid2); PrintAndLogEx(SUCCESS, "UID | %s (%x%08x)", showbits, uid1, uid2);
} } else {
else {
uid3 = uid4 = uid5 = uid6 = uid7 = 0; uid3 = uid4 = uid5 = uid6 = uid7 = 0;
for (idx = 0; idx < 224; idx++) { for (idx = 0; idx < 224; idx++) {
@ -375,7 +382,8 @@ int CmdIndalaDemodAlt(const char *Cmd) {
return 1; return 1;
} }
int CmdIndalaSim(const char *Cmd) { int CmdIndalaSim(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_indala_sim(); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_indala_sim();
@ -420,7 +428,8 @@ int CmdIndalaSim(const char *Cmd) {
} }
// iceman - needs refactoring // iceman - needs refactoring
int CmdIndalaClone(const char *Cmd) { int CmdIndalaClone(const char *Cmd)
{
UsbCommand c = {0}; UsbCommand c = {0};
uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7; uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
uid1 = uid2 = uid3 = uid4 = uid5 = uid6 = uid7 = 0; uid1 = uid2 = uid3 = uid4 = uid5 = uid6 = uid7 = 0;
@ -473,13 +482,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFINDALA(const char *Cmd){ int CmdLFINDALA(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -12,7 +12,8 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_lf_io_read(void) { int usage_lf_io_read(void)
{
PrintAndLogEx(NORMAL, "Enables IOProx compatible reader mode printing details of scanned tags."); PrintAndLogEx(NORMAL, "Enables IOProx compatible reader mode printing details of scanned tags.");
PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "If the [1] option is provided, reader mode is exited after reading a single card."); PrintAndLogEx(NORMAL, "If the [1] option is provided, reader mode is exited after reading a single card.");
@ -28,7 +29,8 @@ int usage_lf_io_read(void) {
return 0; return 0;
} }
int usage_lf_io_sim(void) { int usage_lf_io_sim(void)
{
PrintAndLogEx(NORMAL, "Enables simulation of IOProx card with specified facility-code and card number."); PrintAndLogEx(NORMAL, "Enables simulation of IOProx card with specified facility-code and card number.");
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
@ -44,7 +46,8 @@ int usage_lf_io_sim(void) {
return 0; return 0;
} }
int usage_lf_io_clone(void) { int usage_lf_io_clone(void)
{
PrintAndLogEx(NORMAL, "Enables cloning of IOProx card with specified facility-code and card number onto T55x7."); PrintAndLogEx(NORMAL, "Enables cloning of IOProx card with specified facility-code and card number onto T55x7.");
PrintAndLogEx(NORMAL, "The T55x7 must be on the antenna when issuing this command. T55x7 blocks are calculated and printed in the process."); PrintAndLogEx(NORMAL, "The T55x7 must be on the antenna when issuing this command. T55x7 blocks are calculated and printed in the process.");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
@ -62,13 +65,15 @@ int usage_lf_io_clone(void) {
} }
// this read is the "normal" read, which download lf signal and tries to demod here. // this read is the "normal" read, which download lf signal and tries to demod here.
int CmdIOProxRead(const char *Cmd) { int CmdIOProxRead(const char *Cmd)
{
lf_read(true, 12000); lf_read(true, 12000);
return CmdIOProxDemod(Cmd); return CmdIOProxDemod(Cmd);
} }
// this read loops on device side. // this read loops on device side.
// uses the demod in lfops.c // uses the demod in lfops.c
int CmdIOProxRead_device(const char *Cmd) { int CmdIOProxRead_device(const char *Cmd)
{
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_io_read(); if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_io_read();
int findone = (Cmd[0] == '1') ? 1 : 0; int findone = (Cmd[0] == '1') ? 1 : 0;
UsbCommand c = {CMD_IO_DEMOD_FSK, {findone, 0, 0}}; UsbCommand c = {CMD_IO_DEMOD_FSK, {findone, 0, 0}};
@ -80,7 +85,8 @@ int CmdIOProxRead_device(const char *Cmd) {
//by marshmellow //by marshmellow
//IO-Prox demod - FSK RF/64 with preamble of 000000001 //IO-Prox demod - FSK RF/64 with preamble of 000000001
//print ioprox ID and some format details //print ioprox ID and some format details
int CmdIOProxDemod(const char *Cmd) { int CmdIOProxDemod(const char *Cmd)
{
int retval = 0; int retval = 0;
int idx = 0; int idx = 0;
uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0}; uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0};
@ -183,7 +189,8 @@ int CmdIOProxDemod(const char *Cmd) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11 //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
//XSF(version)facility:codeone+codetwo (raw) //XSF(version)facility:codeone+codetwo (raw)
int getIOProxBits(uint8_t version, uint8_t fc, uint16_t cn, uint8_t *bits) { int getIOProxBits(uint8_t version, uint8_t fc, uint16_t cn, uint8_t *bits)
{
#define SEPARATOR 1 #define SEPARATOR 1
uint8_t pos = 0; uint8_t pos = 0;
// the return bits, preamble 0000 0000 0 // the return bits, preamble 0000 0000 0
@ -243,7 +250,8 @@ int getIOProxBits(uint8_t version, uint8_t fc, uint16_t cn, uint8_t *bits) {
return 1; return 1;
} }
int CmdIOProxSim(const char *Cmd) { int CmdIOProxSim(const char *Cmd)
{
uint16_t cn = 0; uint16_t cn = 0;
uint8_t version = 0, fc = 0; uint8_t version = 0, fc = 0;
uint8_t bits[64]; uint8_t bits[64];
@ -288,7 +296,8 @@ int CmdIOProxSim(const char *Cmd) {
return 0; return 0;
} }
int CmdIOProxClone(const char *Cmd) { int CmdIOProxClone(const char *Cmd)
{
uint32_t blocks[3] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0}; uint32_t blocks[3] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0};
uint16_t cn = 0; uint16_t cn = 0;
@ -340,13 +349,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFIO(const char *Cmd){ int CmdLFIO(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -12,7 +12,8 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_lf_jablotron_clone(void){ int usage_lf_jablotron_clone(void)
{
PrintAndLogEx(NORMAL, "clone a Jablotron tag to a T55x7 tag."); PrintAndLogEx(NORMAL, "clone a Jablotron tag to a T55x7 tag.");
PrintAndLogEx(NORMAL, "Usage: lf jablotron clone [h] <card ID> <Q5>"); PrintAndLogEx(NORMAL, "Usage: lf jablotron clone [h] <card ID> <Q5>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -25,7 +26,8 @@ int usage_lf_jablotron_clone(void){
return 0; return 0;
} }
int usage_lf_jablotron_sim(void) { int usage_lf_jablotron_sim(void)
{
PrintAndLogEx(NORMAL, "Enables simulation of jablotron card with specified card number."); PrintAndLogEx(NORMAL, "Enables simulation of jablotron card with specified card number.");
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
@ -39,7 +41,8 @@ int usage_lf_jablotron_sim(void) {
return 0; return 0;
} }
static uint8_t jablontron_chksum(uint8_t *bits){ static uint8_t jablontron_chksum(uint8_t *bits)
{
uint8_t chksum = 0; uint8_t chksum = 0;
for (int i = 16; i < 56; i += 8) { for (int i = 16; i < 56; i += 8) {
chksum += bytebits_to_byte(bits + i, 8); chksum += bytebits_to_byte(bits + i, 8);
@ -48,7 +51,8 @@ static uint8_t jablontron_chksum(uint8_t *bits){
return chksum; return chksum;
} }
int getJablotronBits(uint64_t fullcode, uint8_t *bits) { int getJablotronBits(uint64_t fullcode, uint8_t *bits)
{
//preamp //preamp
num_to_bytebits(0xFFFF, 16, bits); num_to_bytebits(0xFFFF, 16, bits);
@ -65,7 +69,8 @@ int getJablotronBits(uint64_t fullcode, uint8_t *bits) {
// Note: this is not a demod, this is only a detection // Note: this is not a demod, this is only a detection
// the parameter *bits needs to be demoded before call // the parameter *bits needs to be demoded before call
// 0xFFFF preamble, 64bits // 0xFFFF preamble, 64bits
int detectJablotron(uint8_t *bits, size_t *size) { int detectJablotron(uint8_t *bits, size_t *size)
{
if (*size < 64 * 2) return -1; //make sure buffer has enough data if (*size < 64 * 2) return -1; //make sure buffer has enough data
size_t startIdx = 0; size_t startIdx = 0;
uint8_t preamble[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}; uint8_t preamble[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0};
@ -79,7 +84,8 @@ int detectJablotron(uint8_t *bits, size_t *size) {
return (int)startIdx; return (int)startIdx;
} }
static uint64_t getJablontronCardId( uint64_t rawcode ){ static uint64_t getJablontronCardId(uint64_t rawcode)
{
uint64_t id = 0; uint64_t id = 0;
uint8_t bytes[] = {0, 0, 0, 0, 0}; uint8_t bytes[] = {0, 0, 0, 0, 0};
num_to_bytes(rawcode, 5, bytes); num_to_bytes(rawcode, 5, bytes);
@ -91,7 +97,8 @@ static uint64_t getJablontronCardId( uint64_t rawcode ){
} }
//see ASKDemod for what args are accepted //see ASKDemod for what args are accepted
int CmdJablotronDemod(const char *Cmd) { int CmdJablotronDemod(const char *Cmd)
{
//Differential Biphase / di-phase (inverted biphase) //Differential Biphase / di-phase (inverted biphase)
//get binary from ask wave //get binary from ask wave
@ -145,12 +152,14 @@ int CmdJablotronDemod(const char *Cmd) {
return 1; return 1;
} }
int CmdJablotronRead(const char *Cmd) { int CmdJablotronRead(const char *Cmd)
{
lf_read(true, 10000); lf_read(true, 10000);
return CmdJablotronDemod(Cmd); return CmdJablotronDemod(Cmd);
} }
int CmdJablotronClone(const char *Cmd) { int CmdJablotronClone(const char *Cmd)
{
uint64_t fullcode = 0; uint64_t fullcode = 0;
uint32_t blocks[3] = {T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0}; uint32_t blocks[3] = {T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0};
@ -200,7 +209,8 @@ int CmdJablotronClone(const char *Cmd) {
return 0; return 0;
} }
int CmdJablotronSim(const char *Cmd) { int CmdJablotronSim(const char *Cmd)
{
uint64_t fullcode = 0; uint64_t fullcode = 0;
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
@ -238,13 +248,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFJablotron(const char *Cmd) { int CmdLFJablotron(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -11,7 +11,8 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_lf_keri_clone(void){ int usage_lf_keri_clone(void)
{
PrintAndLogEx(NORMAL, "clone a KERI tag to a T55x7 tag."); PrintAndLogEx(NORMAL, "clone a KERI tag to a T55x7 tag.");
PrintAndLogEx(NORMAL, "Usage: lf keri clone [h] <id> <Q5>"); PrintAndLogEx(NORMAL, "Usage: lf keri clone [h] <id> <Q5>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -24,7 +25,8 @@ int usage_lf_keri_clone(void){
return 0; return 0;
} }
int usage_lf_keri_sim(void) { int usage_lf_keri_sim(void)
{
PrintAndLogEx(NORMAL, "Enables simulation of KERI card with specified card number."); PrintAndLogEx(NORMAL, "Enables simulation of KERI card with specified card number.");
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
@ -39,7 +41,8 @@ int usage_lf_keri_sim(void) {
} }
// find KERI preamble in already demoded data // find KERI preamble in already demoded data
int detectKeri(uint8_t *dest, size_t *size, bool *invert) { int detectKeri(uint8_t *dest, size_t *size, bool *invert)
{
uint8_t preamble[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}; uint8_t preamble[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1};
uint8_t preamble_i[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0}; uint8_t preamble_i[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0};
@ -63,7 +66,8 @@ int detectKeri(uint8_t *dest, size_t *size, bool *invert) {
return (int)startIdx; return (int)startIdx;
} }
int CmdKeriDemod(const char *Cmd) { int CmdKeriDemod(const char *Cmd)
{
if (!PSKDemod("", false)) { if (!PSKDemod("", false)) {
PrintAndLogEx(DEBUG, "DEBUG: Error - KERI: PSK1 Demod failed"); PrintAndLogEx(DEBUG, "DEBUG: Error - KERI: PSK1 Demod failed");
@ -122,12 +126,14 @@ int CmdKeriDemod(const char *Cmd) {
return 1; return 1;
} }
int CmdKeriRead(const char *Cmd) { int CmdKeriRead(const char *Cmd)
{
lf_read(true, 10000); lf_read(true, 10000);
return CmdKeriDemod(Cmd); return CmdKeriDemod(Cmd);
} }
int CmdKeriClone(const char *Cmd) { int CmdKeriClone(const char *Cmd)
{
uint32_t internalid = 0; uint32_t internalid = 0;
uint32_t blocks[3] = { uint32_t blocks[3] = {
@ -137,7 +143,8 @@ int CmdKeriClone(const char *Cmd) {
T55x7_PSKCF_RF_2 | T55x7_PSKCF_RF_2 |
2 << T55x7_MAXBLOCK_SHIFT, 2 << T55x7_MAXBLOCK_SHIFT,
0, 0,
0}; 0
};
// dynamic bitrate used // dynamic bitrate used
blocks[0] |= 0xF << 18; blocks[0] |= 0xF << 18;
@ -189,7 +196,8 @@ int CmdKeriClone(const char *Cmd) {
return 0; return 0;
} }
int CmdKeriSim(const char *Cmd) { int CmdKeriSim(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_keri_sim(); if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_keri_sim();
@ -231,13 +239,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFKeri(const char *Cmd) { int CmdLFKeri(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -10,7 +10,8 @@
#include "cmdlfnedap.h" #include "cmdlfnedap.h"
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_lf_nedap_clone(void){ int usage_lf_nedap_clone(void)
{
PrintAndLogEx(NORMAL, "clone a NEDAP tag to a T55x7 tag."); PrintAndLogEx(NORMAL, "clone a NEDAP tag to a T55x7 tag.");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf nedap clone [h] <Card-Number>"); PrintAndLogEx(NORMAL, "Usage: lf nedap clone [h] <Card-Number>");
@ -24,7 +25,8 @@ int usage_lf_nedap_clone(void){
return 0; return 0;
} }
int usage_lf_nedap_sim(void) { int usage_lf_nedap_sim(void)
{
PrintAndLogEx(NORMAL, "Enables simulation of NEDAP card with specified card number."); PrintAndLogEx(NORMAL, "Enables simulation of NEDAP card with specified card number.");
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
@ -39,7 +41,8 @@ int usage_lf_nedap_sim(void) {
} }
// find nedap preamble in already demoded data // find nedap preamble in already demoded data
int detectNedap(uint8_t *dest, size_t *size) { int detectNedap(uint8_t *dest, size_t *size)
{
//make sure buffer has data //make sure buffer has data
if (*size < 128) return -3; if (*size < 128) return -3;
@ -51,7 +54,8 @@ int detectNedap(uint8_t *dest, size_t *size) {
return (int) startIdx; return (int) startIdx;
} }
int GetNedapBits(uint32_t cn, uint8_t *nedapBits) { int GetNedapBits(uint32_t cn, uint8_t *nedapBits)
{
uint8_t pre[128]; uint8_t pre[128];
memset(pre, 0x00, sizeof(pre)); memset(pre, 0x00, sizeof(pre));
@ -112,7 +116,8 @@ int GetNedapBits(uint32_t cn, uint8_t *nedapBits) {
//NEDAP demod - ASK/Biphase (or Diphase), RF/64 with preamble of 1111111110 (always a 128 bit data stream) //NEDAP demod - ASK/Biphase (or Diphase), RF/64 with preamble of 1111111110 (always a 128 bit data stream)
//print NEDAP Prox ID, encoding, encrypted ID, //print NEDAP Prox ID, encoding, encrypted ID,
int CmdLFNedapDemod(const char *Cmd) { int CmdLFNedapDemod(const char *Cmd)
{
//raw ask demod no start bit finding just get binary from wave //raw ask demod no start bit finding just get binary from wave
if (!ASKbiphaseDemod("0 64 1 0", false)) { if (!ASKbiphaseDemod("0 64 1 0", false)) {
if (g_debugMode) PrintAndLogEx(DEBUG, "DEBUG: Error - Nedap ASKbiphaseDemod failed"); if (g_debugMode) PrintAndLogEx(DEBUG, "DEBUG: Error - Nedap ASKbiphaseDemod failed");
@ -231,7 +236,8 @@ lf t55xx wr b 4 d 4c0003ff
*/ */
int CmdLFNedapRead(const char *Cmd) { int CmdLFNedapRead(const char *Cmd)
{
lf_read(true, 12000); lf_read(true, 12000);
return CmdLFNedapDemod(Cmd); return CmdLFNedapDemod(Cmd);
} }
@ -288,7 +294,8 @@ int CmdLFNedapClone(const char *Cmd) {
} }
*/ */
int CmdLFNedapSim(const char *Cmd) { int CmdLFNedapSim(const char *Cmd)
{
uint32_t cardnumber = 0, cn = 0; uint32_t cardnumber = 0, cn = 0;
@ -324,7 +331,8 @@ int CmdLFNedapSim(const char *Cmd) {
return 0; return 0;
} }
int CmdLFNedapChk(const char *Cmd){ int CmdLFNedapChk(const char *Cmd)
{
//301600714021BE //301600714021BE
uint8_t data[256] = { 0x30, 0x16, 0x00, 0x71, 0x40, 0x21, 0xBE}; uint8_t data[256] = { 0x30, 0x16, 0x00, 0x71, 0x40, 0x21, 0xBE};
int len = 0; int len = 0;
@ -381,13 +389,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFNedap(const char *Cmd) { int CmdLFNedap(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -12,7 +12,8 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int detectNexWatch(uint8_t *dest, size_t *size, bool *invert) { int detectNexWatch(uint8_t *dest, size_t *size, bool *invert)
{
uint8_t preamble[28] = {0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t preamble[28] = {0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
uint8_t preamble_i[28] = {1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; uint8_t preamble_i[28] = {1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
@ -31,7 +32,8 @@ int detectNexWatch(uint8_t *dest, size_t *size, bool *invert) {
return (int) startIdx; return (int) startIdx;
} }
int CmdNexWatchDemod(const char *Cmd) { int CmdNexWatchDemod(const char *Cmd)
{
if (!PSKDemod("", false)) { if (!PSKDemod("", false)) {
PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch can't demod signal"); PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch can't demod signal");
@ -87,7 +89,8 @@ int CmdNexWatchDemod(const char *Cmd) {
//by marshmellow //by marshmellow
//see ASKDemod for what args are accepted //see ASKDemod for what args are accepted
int CmdNexWatchRead(const char *Cmd) { int CmdNexWatchRead(const char *Cmd)
{
lf_read(true, 10000); lf_read(true, 10000);
return CmdNexWatchDemod(Cmd); return CmdNexWatchDemod(Cmd);
} }
@ -99,13 +102,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFNEXWATCH(const char *Cmd) { int CmdLFNEXWATCH(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -11,7 +11,8 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_lf_noralsy_clone(void){ int usage_lf_noralsy_clone(void)
{
PrintAndLogEx(NORMAL, "clone a Noralsy tag to a T55x7 tag."); PrintAndLogEx(NORMAL, "clone a Noralsy tag to a T55x7 tag.");
PrintAndLogEx(NORMAL, "Usage: lf noralsy clone [h] <card id> <year> <Q5>"); PrintAndLogEx(NORMAL, "Usage: lf noralsy clone [h] <card id> <year> <Q5>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -25,7 +26,8 @@ int usage_lf_noralsy_clone(void){
return 0; return 0;
} }
int usage_lf_noralsy_sim(void) { int usage_lf_noralsy_sim(void)
{
PrintAndLogEx(NORMAL, "Enables simulation of Noralsy card with specified card number."); PrintAndLogEx(NORMAL, "Enables simulation of Noralsy card with specified card number.");
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
@ -40,13 +42,15 @@ int usage_lf_noralsy_sim(void) {
return 0; return 0;
} }
static uint8_t noralsy_chksum( uint8_t* bits, uint8_t len) { static uint8_t noralsy_chksum(uint8_t *bits, uint8_t len)
{
uint8_t sum = 0; uint8_t sum = 0;
for (uint8_t i = 0; i < len; i += 4) for (uint8_t i = 0; i < len; i += 4)
sum ^= bytebits_to_byte(bits + i, 4); sum ^= bytebits_to_byte(bits + i, 4);
return sum & 0x0F ; return sum & 0x0F ;
} }
int getnoralsyBits(uint32_t id, uint16_t year, uint8_t *bits) { int getnoralsyBits(uint32_t id, uint16_t year, uint8_t *bits)
{
//preamp //preamp
num_to_bytebits(0xBB0214FF, 32, bits); // --> Have seen 0xBB0214FF / 0xBB0314FF UNKNOWN num_to_bytebits(0xBB0214FF, 32, bits); // --> Have seen 0xBB0214FF / 0xBB0314FF UNKNOWN
@ -76,7 +80,8 @@ int getnoralsyBits(uint32_t id, uint16_t year, uint8_t *bits) {
// by iceman // by iceman
// find Noralsy preamble in already demoded data // find Noralsy preamble in already demoded data
int detectNoralsy(uint8_t *dest, size_t *size) { int detectNoralsy(uint8_t *dest, size_t *size)
{
if (*size < 96) return -1; //make sure buffer has data if (*size < 96) return -1; //make sure buffer has data
size_t startIdx = 0; size_t startIdx = 0;
uint8_t preamble[] = {1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0}; uint8_t preamble[] = {1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0};
@ -100,7 +105,8 @@ int detectNoralsy(uint8_t *dest, size_t *size) {
**/ **/
//see ASKDemod for what args are accepted //see ASKDemod for what args are accepted
int CmdNoralsyDemod(const char *Cmd) { int CmdNoralsyDemod(const char *Cmd)
{
//ASK / Manchester //ASK / Manchester
bool st = true; bool st = true;
@ -169,12 +175,14 @@ int CmdNoralsyDemod(const char *Cmd) {
return 1; return 1;
} }
int CmdNoralsyRead(const char *Cmd) { int CmdNoralsyRead(const char *Cmd)
{
lf_read(true, 8000); lf_read(true, 8000);
return CmdNoralsyDemod(Cmd); return CmdNoralsyDemod(Cmd);
} }
int CmdNoralsyClone(const char *Cmd) { int CmdNoralsyClone(const char *Cmd)
{
uint16_t year = 0; uint16_t year = 0;
uint32_t id = 0; uint32_t id = 0;
@ -221,7 +229,8 @@ int CmdNoralsyClone(const char *Cmd) {
return 0; return 0;
} }
int CmdNoralsySim(const char *Cmd) { int CmdNoralsySim(const char *Cmd)
{
uint8_t bits[96]; uint8_t bits[96];
uint8_t *bs = bits; uint8_t *bs = bits;
@ -265,13 +274,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFNoralsy(const char *Cmd) { int CmdLFNoralsy(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -13,7 +13,8 @@ static int CmdHelp(const char *Cmd);
// by marshmellow // by marshmellow
// find PAC preamble in already demoded data // find PAC preamble in already demoded data
int detectPac(uint8_t *dest, size_t *size) { int detectPac(uint8_t *dest, size_t *size)
{
if (*size < 128) return -1; //make sure buffer has data if (*size < 128) return -1; //make sure buffer has data
size_t startIdx = 0; size_t startIdx = 0;
uint8_t preamble[] = {1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0}; uint8_t preamble[] = {1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0};
@ -25,7 +26,8 @@ int detectPac(uint8_t *dest, size_t *size) {
} }
//see NRZDemod for what args are accepted //see NRZDemod for what args are accepted
int CmdPacDemod(const char *Cmd) { int CmdPacDemod(const char *Cmd)
{
//NRZ //NRZ
if (!NRZrawDemod(Cmd, false)) { if (!NRZrawDemod(Cmd, false)) {
@ -64,7 +66,8 @@ int CmdPacDemod(const char *Cmd) {
return 1; return 1;
} }
int CmdPacRead(const char *Cmd) { int CmdPacRead(const char *Cmd)
{
lf_read(true, 4096 * 2 + 20); lf_read(true, 4096 * 2 + 20);
return CmdPacDemod(Cmd); return CmdPacDemod(Cmd);
} }
@ -76,13 +79,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFPac(const char *Cmd) { int CmdLFPac(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -21,7 +21,8 @@
#include "lfdemod.h" #include "lfdemod.h"
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_lf_paradox_sim(void) { int usage_lf_paradox_sim(void)
{
PrintAndLogEx(NORMAL, "Enables simulation of Paradox card with specified card number."); PrintAndLogEx(NORMAL, "Enables simulation of Paradox card with specified card number.");
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated."); PrintAndLogEx(NORMAL, "The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated.");
@ -38,7 +39,8 @@ int usage_lf_paradox_sim(void) {
} }
// loop to get raw paradox waveform then FSK demodulate the TAG ID from it // loop to get raw paradox waveform then FSK demodulate the TAG ID from it
int detectParadox(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo, int *waveStartIdx) { int detectParadox(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo, int *waveStartIdx)
{
//make sure buffer has data //make sure buffer has data
if (*size < 96 * 50) return -1; if (*size < 96 * 50) return -1;
@ -77,7 +79,8 @@ int detectParadox(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint
//by marshmellow //by marshmellow
//Paradox Prox demod - FSK2a RF/50 with preamble of 00001111 (then manchester encoded) //Paradox Prox demod - FSK2a RF/50 with preamble of 00001111 (then manchester encoded)
//print full Paradox Prox ID and some bit format details if found //print full Paradox Prox ID and some bit format details if found
int CmdParadoxDemod(const char *Cmd) { int CmdParadoxDemod(const char *Cmd)
{
//raw fsk demod no manchester decoding no start bit finding just get binary from wave //raw fsk demod no manchester decoding no start bit finding just get binary from wave
uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0}; uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0};
size_t size = getFromGraphBuf(bits); size_t size = getFromGraphBuf(bits);
@ -140,12 +143,14 @@ int CmdParadoxDemod(const char *Cmd) {
} }
//by marshmellow //by marshmellow
//see ASKDemod for what args are accepted //see ASKDemod for what args are accepted
int CmdParadoxRead(const char *Cmd) { int CmdParadoxRead(const char *Cmd)
{
lf_read(true, 10000); lf_read(true, 10000);
return CmdParadoxDemod(Cmd); return CmdParadoxDemod(Cmd);
} }
int CmdParadoxSim(const char *Cmd) { int CmdParadoxSim(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0); char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_paradox_sim(); if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_paradox_sim();
@ -192,13 +197,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFParadox(const char *Cmd) { int CmdLFParadox(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -35,7 +35,8 @@ struct pcf7931_config configPcf = {
}; };
// Resets the configuration settings to default values. // Resets the configuration settings to default values.
int pcf7931_resetConfig(){ int pcf7931_resetConfig()
{
memset(configPcf.Pwd, 0xFF, sizeof(configPcf.Pwd)); memset(configPcf.Pwd, 0xFF, sizeof(configPcf.Pwd));
configPcf.InitDelay = PCF7931_DEFAULT_INITDELAY; configPcf.InitDelay = PCF7931_DEFAULT_INITDELAY;
configPcf.OffsetWidth = PCF7931_DEFAULT_OFFSET_WIDTH; configPcf.OffsetWidth = PCF7931_DEFAULT_OFFSET_WIDTH;
@ -43,7 +44,8 @@ int pcf7931_resetConfig(){
return 0; return 0;
} }
int pcf7931_printConfig(){ int pcf7931_printConfig()
{
PrintAndLogEx(NORMAL, "Password (LSB first on bytes) : %s", sprint_hex(configPcf.Pwd, sizeof(configPcf.Pwd))); PrintAndLogEx(NORMAL, "Password (LSB first on bytes) : %s", sprint_hex(configPcf.Pwd, sizeof(configPcf.Pwd)));
PrintAndLogEx(NORMAL, "Tag initialization delay : %d us", configPcf.InitDelay); PrintAndLogEx(NORMAL, "Tag initialization delay : %d us", configPcf.InitDelay);
PrintAndLogEx(NORMAL, "Offset low pulses width : %d us", configPcf.OffsetWidth); PrintAndLogEx(NORMAL, "Offset low pulses width : %d us", configPcf.OffsetWidth);
@ -51,7 +53,8 @@ int pcf7931_printConfig(){
return 0; return 0;
} }
int usage_pcf7931_read(){ int usage_pcf7931_read()
{
PrintAndLogEx(NORMAL, "Usage: lf pcf7931 read [h] "); PrintAndLogEx(NORMAL, "Usage: lf pcf7931 read [h] ");
PrintAndLogEx(NORMAL, "This command tries to read a PCF7931 tag."); PrintAndLogEx(NORMAL, "This command tries to read a PCF7931 tag.");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -61,7 +64,8 @@ int usage_pcf7931_read(){
return 0; return 0;
} }
int usage_pcf7931_write(){ int usage_pcf7931_write()
{
PrintAndLogEx(NORMAL, "Usage: lf pcf7931 write [h] <block address> <byte address> <data>"); PrintAndLogEx(NORMAL, "Usage: lf pcf7931 write [h] <block address> <byte address> <data>");
PrintAndLogEx(NORMAL, "This command tries to write a PCF7931 tag."); PrintAndLogEx(NORMAL, "This command tries to write a PCF7931 tag.");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -74,7 +78,8 @@ int usage_pcf7931_write(){
return 0; return 0;
} }
int usage_pcf7931_config(){ int usage_pcf7931_config()
{
PrintAndLogEx(NORMAL, "Usage: lf pcf7931 config [h] [r] <pwd> <delay> <offset width> <offset position>"); PrintAndLogEx(NORMAL, "Usage: lf pcf7931 config [h] [r] <pwd> <delay> <offset width> <offset position>");
PrintAndLogEx(NORMAL, "This command tries to set the configuration used with PCF7931 commands"); PrintAndLogEx(NORMAL, "This command tries to set the configuration used with PCF7931 commands");
PrintAndLogEx(NORMAL, "The time offsets could be useful to correct slew rate generated by the antenna"); PrintAndLogEx(NORMAL, "The time offsets could be useful to correct slew rate generated by the antenna");
@ -94,7 +99,8 @@ int usage_pcf7931_config(){
return 0; return 0;
} }
int CmdLFPCF7931Read(const char *Cmd){ int CmdLFPCF7931Read(const char *Cmd)
{
uint8_t ctmp = param_getchar(Cmd, 0); uint8_t ctmp = param_getchar(Cmd, 0);
if (ctmp == 'H' || ctmp == 'h') return usage_pcf7931_read(); if (ctmp == 'H' || ctmp == 'h') return usage_pcf7931_read();
@ -110,7 +116,8 @@ int CmdLFPCF7931Read(const char *Cmd){
return 0; return 0;
} }
int CmdLFPCF7931Config(const char *Cmd){ int CmdLFPCF7931Config(const char *Cmd)
{
uint8_t ctmp = param_getchar(Cmd, 0); uint8_t ctmp = param_getchar(Cmd, 0);
if (ctmp == 0) return pcf7931_printConfig(); if (ctmp == 0) return pcf7931_printConfig();
@ -127,7 +134,8 @@ int CmdLFPCF7931Config(const char *Cmd){
return 0; return 0;
} }
int CmdLFPCF7931Write(const char *Cmd){ int CmdLFPCF7931Write(const char *Cmd)
{
uint8_t ctmp = param_getchar(Cmd, 0); uint8_t ctmp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_pcf7931_write(); if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_pcf7931_write();
@ -165,13 +173,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFPCF7931(const char *Cmd) { int CmdLFPCF7931(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -10,7 +10,8 @@
#include "cmdlfpresco.h" #include "cmdlfpresco.h"
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_lf_presco_clone(void){ int usage_lf_presco_clone(void)
{
PrintAndLogEx(NORMAL, "clone a Presco tag to a T55x7 tag."); PrintAndLogEx(NORMAL, "clone a Presco tag to a T55x7 tag.");
PrintAndLogEx(NORMAL, "Usage: lf presco clone [h] d <Card-ID> c <hex-ID> <Q5>"); PrintAndLogEx(NORMAL, "Usage: lf presco clone [h] d <Card-ID> c <hex-ID> <Q5>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -24,7 +25,8 @@ int usage_lf_presco_clone(void){
return 0; return 0;
} }
int usage_lf_presco_sim(void) { int usage_lf_presco_sim(void)
{
PrintAndLogEx(NORMAL, "Enables simulation of presco card with specified card number."); PrintAndLogEx(NORMAL, "Enables simulation of presco card with specified card number.");
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "Per presco format, the card number is 9 digit number and can contain *# chars. Larger values are truncated."); PrintAndLogEx(NORMAL, "Per presco format, the card number is 9 digit number and can contain *# chars. Larger values are truncated.");
@ -41,7 +43,8 @@ int usage_lf_presco_sim(void) {
} }
// find presco preamble 0x10D in already demoded data // find presco preamble 0x10D in already demoded data
int detectPresco(uint8_t *dest, size_t *size) { int detectPresco(uint8_t *dest, size_t *size)
{
if (*size < 128 * 2) return -1; //make sure buffer has data if (*size < 128 * 2) return -1; //make sure buffer has data
size_t startIdx = 0; size_t startIdx = 0;
uint8_t preamble[] = {0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; uint8_t preamble[] = {0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@ -53,7 +56,8 @@ int detectPresco(uint8_t *dest, size_t *size) {
} }
// convert base 12 ID to sitecode & usercode & 8 bit other unknown code // convert base 12 ID to sitecode & usercode & 8 bit other unknown code
int GetWiegandFromPresco(const char *Cmd, uint32_t *sitecode, uint32_t *usercode, uint32_t *fullcode, bool *Q5) { int GetWiegandFromPresco(const char *Cmd, uint32_t *sitecode, uint32_t *usercode, uint32_t *fullcode, bool *Q5)
{
uint8_t val = 0; uint8_t val = 0;
bool hex = false, errors = false; bool hex = false, errors = false;
@ -116,7 +120,8 @@ int GetWiegandFromPresco(const char *Cmd, uint32_t *sitecode, uint32_t *usercode
} }
// calc not certain - intended to get bitstream for programming / sim // calc not certain - intended to get bitstream for programming / sim
int GetPrescoBits(uint32_t fullcode, uint8_t *prescoBits) { int GetPrescoBits(uint32_t fullcode, uint8_t *prescoBits)
{
num_to_bytebits(0x10D00000, 32, prescoBits); num_to_bytebits(0x10D00000, 32, prescoBits);
num_to_bytebits(0x00000000, 32, prescoBits + 32); num_to_bytebits(0x00000000, 32, prescoBits + 32);
num_to_bytebits(0x00000000, 32, prescoBits + 64); num_to_bytebits(0x00000000, 32, prescoBits + 64);
@ -125,7 +130,8 @@ int GetPrescoBits(uint32_t fullcode, uint8_t *prescoBits) {
} }
//see ASKDemod for what args are accepted //see ASKDemod for what args are accepted
int CmdPrescoDemod(const char *Cmd) { int CmdPrescoDemod(const char *Cmd)
{
bool st = true; bool st = true;
if (!ASKDemod_ext("32 0 0 0 0 a", false, false, 1, &st)) { if (!ASKDemod_ext("32 0 0 0 0 a", false, false, 1, &st)) {
PrintAndLogEx(DEBUG, "DEBUG: Error Presco ASKDemod failed"); PrintAndLogEx(DEBUG, "DEBUG: Error Presco ASKDemod failed");
@ -165,7 +171,8 @@ int CmdPrescoDemod(const char *Cmd) {
} }
//see ASKDemod for what args are accepted //see ASKDemod for what args are accepted
int CmdPrescoRead(const char *Cmd) { int CmdPrescoRead(const char *Cmd)
{
// Presco Number: 123456789 --> Sitecode 30 | usercode 8665 // Presco Number: 123456789 --> Sitecode 30 | usercode 8665
lf_read(true, 12000); lf_read(true, 12000);
return CmdPrescoDemod(Cmd); return CmdPrescoDemod(Cmd);
@ -173,7 +180,8 @@ int CmdPrescoRead(const char *Cmd) {
// takes base 12 ID converts to hex // takes base 12 ID converts to hex
// Or takes 8 digit hex ID // Or takes 8 digit hex ID
int CmdPrescoClone(const char *Cmd) { int CmdPrescoClone(const char *Cmd)
{
bool Q5 = false; bool Q5 = false;
uint32_t sitecode = 0, usercode = 0, fullcode = 0; uint32_t sitecode = 0, usercode = 0, fullcode = 0;
@ -221,7 +229,8 @@ int CmdPrescoClone(const char *Cmd) {
// takes base 12 ID converts to hex // takes base 12 ID converts to hex
// Or takes 8 digit hex ID // Or takes 8 digit hex ID
int CmdPrescoSim(const char *Cmd) { int CmdPrescoSim(const char *Cmd)
{
uint32_t sitecode = 0, usercode = 0, fullcode = 0; uint32_t sitecode = 0, usercode = 0, fullcode = 0;
bool Q5 = false; bool Q5 = false;
// get wiegand from printed number. // get wiegand from printed number.
@ -250,13 +259,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFPresco(const char *Cmd) { int CmdLFPresco(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -11,7 +11,8 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_lf_pyramid_clone(void){ int usage_lf_pyramid_clone(void)
{
PrintAndLogEx(NORMAL, "clone a Farpointe/Pyramid tag to a T55x7 tag."); PrintAndLogEx(NORMAL, "clone a Farpointe/Pyramid tag to a T55x7 tag.");
PrintAndLogEx(NORMAL, "The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated. "); PrintAndLogEx(NORMAL, "The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated. ");
PrintAndLogEx(NORMAL, "Currently only works on 26bit"); PrintAndLogEx(NORMAL, "Currently only works on 26bit");
@ -28,7 +29,8 @@ int usage_lf_pyramid_clone(void){
return 0; return 0;
} }
int usage_lf_pyramid_sim(void) { int usage_lf_pyramid_sim(void)
{
PrintAndLogEx(NORMAL, "Enables simulation of Farpointe/Pyramid card with specified card number."); PrintAndLogEx(NORMAL, "Enables simulation of Farpointe/Pyramid card with specified card number.");
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated."); PrintAndLogEx(NORMAL, "The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated.");
@ -47,7 +49,8 @@ int usage_lf_pyramid_sim(void) {
// by marshmellow // by marshmellow
// FSK Demod then try to locate a Farpointe Data (pyramid) ID // FSK Demod then try to locate a Farpointe Data (pyramid) ID
int detectPyramid(uint8_t *dest, size_t *size, int *waveStartIdx) { int detectPyramid(uint8_t *dest, size_t *size, int *waveStartIdx)
{
//make sure buffer has data //make sure buffer has data
if (*size < 128 * 50) return -1; if (*size < 128 * 50) return -1;
@ -72,7 +75,8 @@ int detectPyramid(uint8_t *dest, size_t *size, int *waveStartIdx) {
} }
// Works for 26bits. // Works for 26bits.
int GetPyramidBits(uint32_t fc, uint32_t cn, uint8_t *pyramidBits) { int GetPyramidBits(uint32_t fc, uint32_t cn, uint8_t *pyramidBits)
{
uint8_t pre[128]; uint8_t pre[128];
memset(pre, 0x00, sizeof(pre)); memset(pre, 0x00, sizeof(pre));
@ -105,7 +109,8 @@ int GetPyramidBits(uint32_t fc, uint32_t cn, uint8_t *pyramidBits) {
//by marshmellow //by marshmellow
//Pyramid Prox demod - FSK RF/50 with preamble of 0000000000000001 (always a 128 bit data stream) //Pyramid Prox demod - FSK RF/50 with preamble of 0000000000000001 (always a 128 bit data stream)
//print full Farpointe Data/Pyramid Prox ID and some bit format details if found //print full Farpointe Data/Pyramid Prox ID and some bit format details if found
int CmdPyramidDemod(const char *Cmd) { int CmdPyramidDemod(const char *Cmd)
{
//raw fsk demod no manchester decoding no start bit finding just get binary from wave //raw fsk demod no manchester decoding no start bit finding just get binary from wave
uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0}; uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0};
size_t size = getFromGraphBuf(bits); size_t size = getFromGraphBuf(bits);
@ -247,12 +252,14 @@ int CmdPyramidDemod(const char *Cmd) {
return 1; return 1;
} }
int CmdPyramidRead(const char *Cmd) { int CmdPyramidRead(const char *Cmd)
{
lf_read(true, 15000); lf_read(true, 15000);
return CmdPyramidDemod(Cmd); return CmdPyramidDemod(Cmd);
} }
int CmdPyramidClone(const char *Cmd) { int CmdPyramidClone(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0); char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_pyramid_clone(); if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_pyramid_clone();
@ -303,7 +310,8 @@ int CmdPyramidClone(const char *Cmd) {
return 0; return 0;
} }
int CmdPyramidSim(const char *Cmd) { int CmdPyramidSim(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0); char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_pyramid_sim(); if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_pyramid_sim();
@ -348,13 +356,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFPyramid(const char *Cmd) { int CmdLFPyramid(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -13,7 +13,8 @@ static int CmdHelp(const char *Cmd);
// by marshmellow // by marshmellow
// find Securakey preamble in already demoded data // find Securakey preamble in already demoded data
int detectSecurakey(uint8_t *dest, size_t *size) { int detectSecurakey(uint8_t *dest, size_t *size)
{
if (*size < 96) return -1; //make sure buffer has data if (*size < 96) return -1; //make sure buffer has data
size_t startIdx = 0; size_t startIdx = 0;
uint8_t preamble[] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1}; uint8_t preamble[] = {0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1};
@ -25,7 +26,8 @@ int detectSecurakey(uint8_t *dest, size_t *size) {
} }
//see ASKDemod for what args are accepted //see ASKDemod for what args are accepted
int CmdSecurakeyDemod(const char *Cmd) { int CmdSecurakeyDemod(const char *Cmd)
{
//ASK / Manchester //ASK / Manchester
bool st = false; bool st = false;
@ -106,7 +108,8 @@ int CmdSecurakeyDemod(const char *Cmd) {
return 1; return 1;
} }
int CmdSecurakeyRead(const char *Cmd) { int CmdSecurakeyRead(const char *Cmd)
{
lf_read(true, 8000); lf_read(true, 8000);
return CmdSecurakeyDemod(Cmd); return CmdSecurakeyDemod(Cmd);
} }
@ -120,13 +123,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFSecurakey(const char *Cmd) { int CmdLFSecurakey(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -11,14 +11,17 @@
// Default configuration // Default configuration
t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = false, .offset = 0x00, .block0 = 0x00, .Q5 = false }; t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = false, .offset = 0x00, .block0 = 0x00, .Q5 = false };
t55xx_conf_block_t Get_t55xx_Config(){ t55xx_conf_block_t Get_t55xx_Config()
{
return config; return config;
} }
void Set_t55xx_Config(t55xx_conf_block_t conf){ void Set_t55xx_Config(t55xx_conf_block_t conf)
{
config = conf; config = conf;
} }
int usage_t55xx_config(){ int usage_t55xx_config()
{
PrintAndLogEx(NORMAL, "Usage: lf t55xx config [d <demodulation>] [i 1] [o <offset>] [Q5]"); PrintAndLogEx(NORMAL, "Usage: lf t55xx config [d <demodulation>] [i 1] [o <offset>] [Q5]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h - This help"); PrintAndLogEx(NORMAL, " h - This help");
@ -36,7 +39,8 @@ int usage_t55xx_config(){
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
return 0; return 0;
} }
int usage_t55xx_read(){ int usage_t55xx_read()
{
PrintAndLogEx(NORMAL, "Usage: lf t55xx read [b <block>] [p <password>] <override_safety> <page1>"); PrintAndLogEx(NORMAL, "Usage: lf t55xx read [b <block>] [p <password>] <override_safety> <page1>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " b <block> - block number to read. Between 0-7"); PrintAndLogEx(NORMAL, " b <block> - block number to read. Between 0-7");
@ -54,7 +58,8 @@ int usage_t55xx_read(){
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
return 0; return 0;
} }
int usage_t55xx_write(){ int usage_t55xx_write()
{
PrintAndLogEx(NORMAL, "Usage: lf t55xx write [b <block>] [d <data>] [p <password>] [1] [t]"); PrintAndLogEx(NORMAL, "Usage: lf t55xx write [b <block>] [d <data>] [p <password>] [1] [t]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " b <block> - block number to write. Between 0-7"); PrintAndLogEx(NORMAL, " b <block> - block number to write. Between 0-7");
@ -69,7 +74,8 @@ int usage_t55xx_write(){
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
return 0; return 0;
} }
int usage_t55xx_trace() { int usage_t55xx_trace()
{
PrintAndLogEx(NORMAL, "Usage: lf t55xx trace [1]"); PrintAndLogEx(NORMAL, "Usage: lf t55xx trace [1]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag.");
@ -80,7 +86,8 @@ int usage_t55xx_trace() {
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
return 0; return 0;
} }
int usage_t55xx_info() { int usage_t55xx_info()
{
PrintAndLogEx(NORMAL, "Usage: lf t55xx info [1]"); PrintAndLogEx(NORMAL, "Usage: lf t55xx info [1]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag.");
@ -91,7 +98,8 @@ int usage_t55xx_info() {
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
return 0; return 0;
} }
int usage_t55xx_dump(){ int usage_t55xx_dump()
{
PrintAndLogEx(NORMAL, "Usage: lf t55xx dump <password> [o]"); PrintAndLogEx(NORMAL, "Usage: lf t55xx dump <password> [o]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " <password> - OPTIONAL password 4bytes (8 hex symbols)"); PrintAndLogEx(NORMAL, " <password> - OPTIONAL password 4bytes (8 hex symbols)");
@ -103,7 +111,8 @@ int usage_t55xx_dump(){
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
return 0; return 0;
} }
int usage_t55xx_detect(){ int usage_t55xx_detect()
{
PrintAndLogEx(NORMAL, "Usage: lf t55xx detect [1] [p <password>]"); PrintAndLogEx(NORMAL, "Usage: lf t55xx detect [1] [p <password>]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag."); PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag.");
@ -116,7 +125,8 @@ int usage_t55xx_detect(){
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
return 0; return 0;
} }
int usage_t55xx_detectP1(){ int usage_t55xx_detectP1()
{
PrintAndLogEx(NORMAL, "Command: Detect Page 1 of a t55xx chip"); PrintAndLogEx(NORMAL, "Command: Detect Page 1 of a t55xx chip");
PrintAndLogEx(NORMAL, "Usage: lf t55xx p1detect [1] [p <password>]"); PrintAndLogEx(NORMAL, "Usage: lf t55xx p1detect [1] [p <password>]");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -130,7 +140,8 @@ int usage_t55xx_detectP1(){
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
return 0; return 0;
} }
int usage_t55xx_wakup(){ int usage_t55xx_wakup()
{
PrintAndLogEx(NORMAL, "Usage: lf t55xx wakeup [h] p <password>"); PrintAndLogEx(NORMAL, "Usage: lf t55xx wakeup [h] p <password>");
PrintAndLogEx(NORMAL, "This commands send the Answer-On-Request command and leaves the readerfield ON afterwards."); PrintAndLogEx(NORMAL, "This commands send the Answer-On-Request command and leaves the readerfield ON afterwards.");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -141,7 +152,8 @@ int usage_t55xx_wakup(){
PrintAndLogEx(NORMAL, " lf t55xx wakeup p 11223344 - send wakeup password"); PrintAndLogEx(NORMAL, " lf t55xx wakeup p 11223344 - send wakeup password");
return 0; return 0;
} }
int usage_t55xx_chk(){ int usage_t55xx_chk()
{
PrintAndLogEx(NORMAL, "This command uses a dictionary attack"); PrintAndLogEx(NORMAL, "This command uses a dictionary attack");
PrintAndLogEx(NORMAL, "press 'enter' to cancel the command"); PrintAndLogEx(NORMAL, "press 'enter' to cancel the command");
PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] <m> [i <*.dic>]"); PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] <m> [i <*.dic>]");
@ -156,7 +168,8 @@ int usage_t55xx_chk(){
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
return 0; return 0;
} }
int usage_t55xx_bruteforce(){ int usage_t55xx_bruteforce()
{
PrintAndLogEx(NORMAL, "This command uses bruteforce to scan a number range"); PrintAndLogEx(NORMAL, "This command uses bruteforce to scan a number range");
PrintAndLogEx(NORMAL, "press 'enter' to cancel the command"); PrintAndLogEx(NORMAL, "press 'enter' to cancel the command");
PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] <start password> <end password>"); PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] <start password> <end password>");
@ -171,7 +184,8 @@ int usage_t55xx_bruteforce(){
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
return 0; return 0;
} }
int usage_t55xx_recoverpw(){ int usage_t55xx_recoverpw()
{
PrintAndLogEx(NORMAL, "This command uses a few tricks to try to recover mangled password"); PrintAndLogEx(NORMAL, "This command uses a few tricks to try to recover mangled password");
PrintAndLogEx(NORMAL, "press 'enter' to cancel the command"); PrintAndLogEx(NORMAL, "press 'enter' to cancel the command");
PrintAndLogEx(NORMAL, "WARNING: this may brick non-password protected chips!"); PrintAndLogEx(NORMAL, "WARNING: this may brick non-password protected chips!");
@ -187,7 +201,9 @@ int usage_t55xx_recoverpw(){
PrintAndLogEx(NORMAL, " lf t55xx recoverpw 51243648"); PrintAndLogEx(NORMAL, " lf t55xx recoverpw 51243648");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
return 0; return 0;
}int usage_t55xx_wipe(){ }
int usage_t55xx_wipe()
{
PrintAndLogEx(NORMAL, "Usage: lf t55xx wipe [h] [Q5]"); PrintAndLogEx(NORMAL, "Usage: lf t55xx wipe [h] [Q5]");
PrintAndLogEx(NORMAL, "This commands wipes a tag, fills blocks 1-7 with zeros and a default configuration block"); PrintAndLogEx(NORMAL, "This commands wipes a tag, fills blocks 1-7 with zeros and a default configuration block");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -199,7 +215,8 @@ int usage_t55xx_recoverpw(){
PrintAndLogEx(NORMAL, " lf t55xx wipe Q5 - wipes a t5555 Q5 tag, config block 0x6001F004"); PrintAndLogEx(NORMAL, " lf t55xx wipe Q5 - wipes a t5555 Q5 tag, config block 0x6001F004");
return 0; return 0;
} }
int usage_lf_deviceconfig(){ int usage_lf_deviceconfig()
{
PrintAndLogEx(NORMAL, "Sets t55x7 timings for direkt commands. The timings are set here in Field Clocks (FC), \nwhich is converted to (US) on device"); PrintAndLogEx(NORMAL, "Sets t55x7 timings for direkt commands. The timings are set here in Field Clocks (FC), \nwhich is converted to (US) on device");
PrintAndLogEx(NORMAL, "Usage: lf t55xx deviceconfig a <gap> b <gap> c <gap> d <gap> e <gap> p"); PrintAndLogEx(NORMAL, "Usage: lf t55xx deviceconfig a <gap> b <gap> c <gap> d <gap> e <gap> p");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -220,13 +237,15 @@ int usage_lf_deviceconfig(){
int CmdHelp(const char *Cmd); int CmdHelp(const char *Cmd);
void printT5xxHeader(uint8_t page){ void printT5xxHeader(uint8_t page)
{
PrintAndLogEx(NORMAL, "Reading Page %d:", page); PrintAndLogEx(NORMAL, "Reading Page %d:", page);
PrintAndLogEx(NORMAL, "blk | hex data | binary | ascii"); PrintAndLogEx(NORMAL, "blk | hex data | binary | ascii");
PrintAndLogEx(NORMAL, "----+----------+----------------------------------+-------"); PrintAndLogEx(NORMAL, "----+----------+----------------------------------+-------");
} }
int CmdT55xxSetConfig(const char *Cmd) { int CmdT55xxSetConfig(const char *Cmd)
{
uint8_t offset = 0; uint8_t offset = 0;
char modulation[6] = {0x00}; char modulation[6] = {0x00};
@ -328,7 +347,8 @@ int CmdT55xxSetConfig(const char *Cmd) {
return printConfiguration(config); return printConfiguration(config);
} }
int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32_t password){ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32_t password)
{
//Password mode //Password mode
if (usepwd) { if (usepwd) {
// 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!
@ -358,7 +378,8 @@ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32
return 1; return 1;
} }
int CmdT55xxReadBlock(const char *Cmd) { int CmdT55xxReadBlock(const char *Cmd)
{
uint8_t block = REGULAR_READ_MODE_BLOCK; uint8_t block = REGULAR_READ_MODE_BLOCK;
uint32_t password = 0; //default to blank Block 7 uint32_t password = 0; //default to blank Block 7
bool usepwd = false; bool usepwd = false;
@ -404,7 +425,8 @@ int CmdT55xxReadBlock(const char *Cmd) {
return T55xxReadBlock(block, page1, usepwd, override, password); return T55xxReadBlock(block, page1, usepwd, override, password);
} }
bool DecodeT55xxBlock(){ bool DecodeT55xxBlock()
{
char buf[30] = {0x00}; char buf[30] = {0x00};
char *cmdStr = buf; char *cmdStr = buf;
@ -467,7 +489,8 @@ bool DecodeT55xxBlock(){
return (bool) ans; return (bool) ans;
} }
bool DecodeT5555TraceBlock() { bool DecodeT5555TraceBlock()
{
DemodBufferLen = 0x00; DemodBufferLen = 0x00;
// According to datasheet. Always: RF/64, not inverted, Manchester // According to datasheet. Always: RF/64, not inverted, Manchester
@ -475,7 +498,8 @@ bool DecodeT5555TraceBlock() {
} }
// sanity check. Don't use proxmark if it is offline and you didn't specify useGraphbuf // sanity check. Don't use proxmark if it is offline and you didn't specify useGraphbuf
static int SanityOfflineCheck( bool useGraphBuffer ){ static int SanityOfflineCheck(bool useGraphBuffer)
{
if (!useGraphBuffer && IsOffline()) { if (!useGraphBuffer && IsOffline()) {
PrintAndLogEx(NORMAL, "Your proxmark3 device is offline. Specify [1] to use graphbuffer data instead"); PrintAndLogEx(NORMAL, "Your proxmark3 device is offline. Specify [1] to use graphbuffer data instead");
return 0; return 0;
@ -483,7 +507,8 @@ static int SanityOfflineCheck( bool useGraphBuffer ){
return 1; return 1;
} }
int CmdT55xxDetect(const char *Cmd){ int CmdT55xxDetect(const char *Cmd)
{
bool errors = false; bool errors = false;
bool useGB = false, usepwd = false; bool useGB = false, usepwd = false;
uint32_t password = 0; uint32_t password = 0;
@ -526,7 +551,8 @@ int CmdT55xxDetect(const char *Cmd){
} }
// detect configuration? // detect configuration?
bool tryDetectModulation(){ bool tryDetectModulation()
{
t55xx_conf_block_t tests[15]; t55xx_conf_block_t tests[15];
int bitRate = 0, clk = 0, firstClockEdge = 0; int bitRate = 0, clk = 0, firstClockEdge = 0;
@ -712,7 +738,8 @@ bool tryDetectModulation(){
return retval; return retval;
} }
bool testKnownConfigBlock(uint32_t block0) { bool testKnownConfigBlock(uint32_t block0)
{
switch (block0) { switch (block0) {
case T55X7_DEFAULT_CONFIG_BLOCK: case T55X7_DEFAULT_CONFIG_BLOCK:
case T55X7_RAW_CONFIG_BLOCK: case T55X7_RAW_CONFIG_BLOCK:
@ -732,7 +759,8 @@ bool testKnownConfigBlock(uint32_t block0) {
return false; return false;
} }
bool testModulation(uint8_t mode, uint8_t modread){ bool testModulation(uint8_t mode, uint8_t modread)
{
switch (mode) { switch (mode) {
case DEMOD_FSK: case DEMOD_FSK:
if (modread >= DEMOD_FSK1 && modread <= DEMOD_FSK2a) return true; if (modread >= DEMOD_FSK1 && modread <= DEMOD_FSK2a) return true;
@ -764,7 +792,8 @@ bool testModulation(uint8_t mode, uint8_t modread){
return false; return false;
} }
bool testQ5Modulation(uint8_t mode, uint8_t modread){ bool testQ5Modulation(uint8_t mode, uint8_t modread)
{
switch (mode) { switch (mode) {
case DEMOD_FSK: case DEMOD_FSK:
if (modread >= 4 && modread <= 5) return true; if (modread >= 4 && modread <= 5) return true;
@ -793,7 +822,8 @@ bool testQ5Modulation(uint8_t mode, uint8_t modread){
return false; return false;
} }
int convertQ5bitRate(uint8_t bitRateRead) { int convertQ5bitRate(uint8_t bitRateRead)
{
uint8_t expected[] = {8, 16, 32, 40, 50, 64, 100, 128}; uint8_t expected[] = {8, 16, 32, 40, 50, 64, 100, 128};
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
if (expected[i] == bitRateRead) if (expected[i] == bitRateRead)
@ -802,7 +832,8 @@ int convertQ5bitRate(uint8_t bitRateRead) {
return -1; return -1;
} }
bool testQ5(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk){ bool testQ5(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk)
{
if (DemodBufferLen < 64) return false; if (DemodBufferLen < 64) return false;
uint8_t si = 0; uint8_t si = 0;
@ -810,15 +841,18 @@ bool testQ5(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk){
si = idx; si = idx;
if (PackBits(si, 28, DemodBuffer) == 0x00) continue; if (PackBits(si, 28, DemodBuffer) == 0x00) continue;
uint8_t safer = PackBits(si, 4, DemodBuffer); si += 4; //master key uint8_t safer = PackBits(si, 4, DemodBuffer);
uint8_t resv = PackBits(si, 8, DemodBuffer); si += 8; si += 4; //master key
uint8_t resv = PackBits(si, 8, DemodBuffer);
si += 8;
// 2nibble must be zeroed. // 2nibble must be zeroed.
if (safer != 0x6 && safer != 0x9) continue; if (safer != 0x6 && safer != 0x9) continue;
if (resv > 0x00) continue; if (resv > 0x00) continue;
//uint8_t pageSel = PackBits(si, 1, DemodBuffer); si += 1; //uint8_t pageSel = PackBits(si, 1, DemodBuffer); si += 1;
//uint8_t fastWrite = PackBits(si, 1, DemodBuffer); si += 1; //uint8_t fastWrite = PackBits(si, 1, DemodBuffer); si += 1;
si += 1 + 1; si += 1 + 1;
int bitRate = PackBits(si, 6, DemodBuffer)*2 + 2; si += 6; //bit rate int bitRate = PackBits(si, 6, DemodBuffer) * 2 + 2;
si += 6; //bit rate
if (bitRate > 128 || bitRate < 8) continue; if (bitRate > 128 || bitRate < 8) continue;
//uint8_t AOR = PackBits(si, 1, DemodBuffer); si += 1; //uint8_t AOR = PackBits(si, 1, DemodBuffer); si += 1;
@ -826,8 +860,10 @@ bool testQ5(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk){
//uint8_t pskcr = PackBits(si, 2, DemodBuffer); si += 2; //could check psk cr //uint8_t pskcr = PackBits(si, 2, DemodBuffer); si += 2; //could check psk cr
//uint8_t inverse = PackBits(si, 1, DemodBuffer); si += 1; //uint8_t inverse = PackBits(si, 1, DemodBuffer); si += 1;
si += 1 + 1 + 2 + 1; si += 1 + 1 + 2 + 1;
uint8_t modread = PackBits(si, 3, DemodBuffer); si += 3; uint8_t modread = PackBits(si, 3, DemodBuffer);
uint8_t maxBlk = PackBits(si, 3, DemodBuffer); si += 3; si += 3;
uint8_t maxBlk = PackBits(si, 3, DemodBuffer);
si += 3;
//uint8_t ST = PackBits(si, 1, DemodBuffer); si += 1; //uint8_t ST = PackBits(si, 1, DemodBuffer); si += 1;
if (maxBlk == 0) continue; if (maxBlk == 0) continue;
//test modulation //test modulation
@ -842,7 +878,8 @@ bool testQ5(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk){
return false; return false;
} }
bool testBitRate(uint8_t readRate, uint8_t clk){ bool testBitRate(uint8_t readRate, uint8_t clk)
{
uint8_t expected[] = {8, 16, 32, 40, 50, 64, 100, 128}; uint8_t expected[] = {8, 16, 32, 40, 50, 64, 100, 128};
if (expected[readRate] == clk) if (expected[readRate] == clk)
return true; return true;
@ -850,7 +887,8 @@ bool testBitRate(uint8_t readRate, uint8_t clk){
return false; return false;
} }
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)
{
if (DemodBufferLen < 64) return false; if (DemodBufferLen < 64) return false;
uint8_t si = 0; uint8_t si = 0;
@ -858,15 +896,20 @@ bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5)
si = idx; si = idx;
if (PackBits(si, 28, DemodBuffer) == 0x00) continue; if (PackBits(si, 28, DemodBuffer) == 0x00) continue;
uint8_t safer = PackBits(si, 4, DemodBuffer); si += 4; //master key uint8_t safer = PackBits(si, 4, DemodBuffer);
uint8_t resv = PackBits(si, 4, DemodBuffer); si += 4; //was 7 & +=7+3 //should be only 4 bits if extended mode si += 4; //master key
uint8_t resv = PackBits(si, 4, DemodBuffer);
si += 4; //was 7 & +=7+3 //should be only 4 bits if extended mode
// 2nibble must be zeroed. // 2nibble must be zeroed.
// moved test to here, since this gets most faults first. // moved test to here, since this gets most faults first.
if (resv > 0x00) continue; if (resv > 0x00) continue;
int bitRate = PackBits(si, 6, DemodBuffer); si += 6; //bit rate (includes extended mode part of rate) int bitRate = PackBits(si, 6, DemodBuffer);
uint8_t extend = PackBits(si, 1, DemodBuffer); si += 1; //bit 15 extended mode si += 6; //bit rate (includes extended mode part of rate)
uint8_t modread = PackBits(si, 5, DemodBuffer); si += 5+2+1; uint8_t extend = PackBits(si, 1, DemodBuffer);
si += 1; //bit 15 extended mode
uint8_t modread = PackBits(si, 5, DemodBuffer);
si += 5 + 2 + 1;
//uint8_t pskcr = PackBits(si, 2, DemodBuffer); si += 2+1; //could check psk cr //uint8_t pskcr = PackBits(si, 2, DemodBuffer); si += 2+1; //could check psk cr
//uint8_t nml01 = PackBits(si, 1, DemodBuffer); si += 1+5; //bit 24, 30, 31 could be tested for 0 if not extended mode //uint8_t nml01 = PackBits(si, 1, DemodBuffer); si += 1+5; //bit 24, 30, 31 could be tested for 0 if not extended mode
//uint8_t nml02 = PackBits(si, 2, DemodBuffer); si += 2; //uint8_t nml02 = PackBits(si, 2, DemodBuffer); si += 2;
@ -895,7 +938,8 @@ bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5)
return false; return false;
} }
void printT55xxBlock(const char *blockNum){ void printT55xxBlock(const char *blockNum)
{
uint8_t i = config.offset; uint8_t i = config.offset;
uint8_t endpos = 32 + i; uint8_t endpos = 32 + i;
@ -919,7 +963,8 @@ void printT55xxBlock(const char *blockNum){
PrintAndLogEx(NORMAL, " %s | %08X | %s | %s", blockNum, blockData, sprint_bin(bits, 32), sprint_ascii(bytes, 4)); PrintAndLogEx(NORMAL, " %s | %08X | %s | %s", blockNum, blockData, sprint_bin(bits, 32), sprint_ascii(bytes, 4));
} }
int special(const char *Cmd) { int special(const char *Cmd)
{
uint32_t blockData = 0; uint32_t blockData = 0;
uint8_t bits[32] = {0x00}; uint8_t bits[32] = {0x00};
@ -938,7 +983,8 @@ int special(const char *Cmd) {
return 0; return 0;
} }
int printConfiguration( t55xx_conf_block_t b){ int printConfiguration(t55xx_conf_block_t b)
{
PrintAndLogEx(NORMAL, "Chip Type : %s", (b.Q5) ? "T5555(Q5)" : "T55x7"); PrintAndLogEx(NORMAL, "Chip Type : %s", (b.Q5) ? "T5555(Q5)" : "T55x7");
PrintAndLogEx(NORMAL, "Modulation : %s", GetSelectedModulationStr(b.modulation)); PrintAndLogEx(NORMAL, "Modulation : %s", GetSelectedModulationStr(b.modulation));
PrintAndLogEx(NORMAL, "Bit Rate : %s", GetBitRateStr(b.bitrate, (b.block0 & T55x7_X_MODE && (b.block0 >> 28 == 6 || b.block0 >> 28 == 9)))); PrintAndLogEx(NORMAL, "Bit Rate : %s", GetBitRateStr(b.bitrate, (b.block0 & T55x7_X_MODE && (b.block0 >> 28 == 6 || b.block0 >> 28 == 9))));
@ -950,7 +996,8 @@ int printConfiguration( t55xx_conf_block_t b){
return 0; return 0;
} }
int CmdT55xxWakeUp(const char *Cmd) { int CmdT55xxWakeUp(const char *Cmd)
{
uint32_t password = 0; uint32_t password = 0;
uint8_t cmdp = 0; uint8_t cmdp = 0;
bool errors = false; bool errors = false;
@ -978,7 +1025,8 @@ int CmdT55xxWakeUp(const char *Cmd) {
return 0; return 0;
} }
int CmdT55xxWriteBlock(const char *Cmd) { int CmdT55xxWriteBlock(const char *Cmd)
{
uint8_t block = 0xFF; //default to invalid block uint8_t block = 0xFF; //default to invalid block
uint32_t data = 0; //default to blank Block uint32_t data = 0; //default to blank Block
uint32_t password = 0; //default to blank Block 7 uint32_t password = 0; //default to blank Block 7
@ -1051,7 +1099,8 @@ int CmdT55xxWriteBlock(const char *Cmd) {
return 1; return 1;
} }
int CmdT55xxReadTrace(const char *Cmd) { int CmdT55xxReadTrace(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) > 1 || cmdp == 'h') return usage_t55xx_trace(); if (strlen(Cmd) > 1 || cmdp == 'h') return usage_t55xx_trace();
@ -1082,7 +1131,8 @@ int CmdT55xxReadTrace(const char *Cmd) {
uint32_t bl2 = PackBits(si + 32, 32, DemodBuffer); uint32_t bl2 = PackBits(si + 32, 32, DemodBuffer);
if (config.Q5) { if (config.Q5) {
uint32_t hdr = PackBits(si, 9, DemodBuffer); si += 9; uint32_t hdr = PackBits(si, 9, DemodBuffer);
si += 9;
if (hdr != 0x1FF) { if (hdr != 0x1FF) {
PrintAndLogEx(FAILED, "Invalid Q5 Trace data header (expected 0x1FF, found %X)", hdr); PrintAndLogEx(FAILED, "Invalid Q5 Trace data header (expected 0x1FF, found %X)", hdr);
@ -1091,30 +1141,43 @@ int CmdT55xxReadTrace(const char *Cmd) {
t5555_tracedata_t data = {.bl1 = bl1, .bl2 = bl2, .icr = 0, .lotidc = '?', .lotid = 0, .wafer = 0, .dw = 0}; t5555_tracedata_t data = {.bl1 = bl1, .bl2 = bl2, .icr = 0, .lotidc = '?', .lotid = 0, .wafer = 0, .dw = 0};
data.icr = PackBits(si, 2, DemodBuffer); si += 2; data.icr = PackBits(si, 2, DemodBuffer);
data.lotidc = 'Z' - PackBits(si, 2, DemodBuffer); si += 3; si += 2;
data.lotidc = 'Z' - PackBits(si, 2, DemodBuffer);
si += 3;
data.lotid = PackBits(si, 4, DemodBuffer); si += 5; data.lotid = PackBits(si, 4, DemodBuffer);
si += 5;
data.lotid <<= 4; data.lotid <<= 4;
data.lotid |= PackBits(si, 4, DemodBuffer); si += 5; data.lotid |= PackBits(si, 4, DemodBuffer);
si += 5;
data.lotid <<= 4; data.lotid <<= 4;
data.lotid |= PackBits(si, 4, DemodBuffer); si += 5; data.lotid |= PackBits(si, 4, DemodBuffer);
si += 5;
data.lotid <<= 4; data.lotid <<= 4;
data.lotid |= PackBits(si, 4, DemodBuffer); si += 5; data.lotid |= PackBits(si, 4, DemodBuffer);
si += 5;
data.lotid <<= 1; data.lotid <<= 1;
data.lotid |= PackBits(si, 1, DemodBuffer); si += 1; data.lotid |= PackBits(si, 1, DemodBuffer);
si += 1;
data.wafer = PackBits(si, 3, DemodBuffer); si += 4; data.wafer = PackBits(si, 3, DemodBuffer);
si += 4;
data.wafer <<= 2; data.wafer <<= 2;
data.wafer |= PackBits(si, 2, DemodBuffer); si += 2; data.wafer |= PackBits(si, 2, DemodBuffer);
si += 2;
data.dw = PackBits(si, 2, DemodBuffer); si += 3; data.dw = PackBits(si, 2, DemodBuffer);
si += 3;
data.dw <<= 4; data.dw <<= 4;
data.dw |= PackBits(si, 4, DemodBuffer); si += 5; data.dw |= PackBits(si, 4, DemodBuffer);
si += 5;
data.dw <<= 4; data.dw <<= 4;
data.dw |= PackBits(si, 4, DemodBuffer); si += 5; data.dw |= PackBits(si, 4, DemodBuffer);
si += 5;
data.dw <<= 4; data.dw <<= 4;
data.dw |= PackBits(si, 4, DemodBuffer); si += 5; data.dw |= PackBits(si, 4, DemodBuffer);
si += 5;
printT5555Trace(data, repeat); printT5555Trace(data, repeat);
@ -1122,19 +1185,27 @@ int CmdT55xxReadTrace(const char *Cmd) {
t55x7_tracedata_t data = {.bl1 = bl1, .bl2 = bl2, .acl = 0, .mfc = 0, .cid = 0, .year = 0, .quarter = 0, .icr = 0, .lotid = 0, .wafer = 0, .dw = 0}; t55x7_tracedata_t data = {.bl1 = bl1, .bl2 = bl2, .acl = 0, .mfc = 0, .cid = 0, .year = 0, .quarter = 0, .icr = 0, .lotid = 0, .wafer = 0, .dw = 0};
data.acl = PackBits(si, 8, DemodBuffer); si += 8; data.acl = PackBits(si, 8, DemodBuffer);
si += 8;
if (data.acl != 0xE0) { if (data.acl != 0xE0) {
PrintAndLogEx(FAILED, "The modulation is most likely wrong since the ACL is not 0xE0. "); PrintAndLogEx(FAILED, "The modulation is most likely wrong since the ACL is not 0xE0. ");
return 1; return 1;
} }
data.mfc = PackBits(si, 8, DemodBuffer); si += 8; data.mfc = PackBits(si, 8, DemodBuffer);
data.cid = PackBits(si, 5, DemodBuffer); si += 5; si += 8;
data.icr = PackBits(si, 3, DemodBuffer); si += 3; data.cid = PackBits(si, 5, DemodBuffer);
data.year = PackBits(si, 4, DemodBuffer); si += 4; si += 5;
data.quarter = PackBits(si, 2, DemodBuffer); si += 2; data.icr = PackBits(si, 3, DemodBuffer);
data.lotid = PackBits(si, 14, DemodBuffer); si += 14; si += 3;
data.wafer = PackBits(si, 5, DemodBuffer); si += 5; data.year = PackBits(si, 4, DemodBuffer);
si += 4;
data.quarter = PackBits(si, 2, DemodBuffer);
si += 2;
data.lotid = PackBits(si, 14, DemodBuffer);
si += 14;
data.wafer = PackBits(si, 5, DemodBuffer);
si += 5;
data.dw = PackBits(si, 15, DemodBuffer); data.dw = PackBits(si, 15, DemodBuffer);
time_t t = time(NULL); time_t t = time(NULL);
@ -1149,7 +1220,8 @@ int CmdT55xxReadTrace(const char *Cmd) {
return 0; return 0;
} }
void printT55x7Trace( t55x7_tracedata_t data, uint8_t repeat ){ void printT55x7Trace(t55x7_tracedata_t data, uint8_t repeat)
{
PrintAndLogEx(NORMAL, "-- T55x7 Trace Information ----------------------------------"); PrintAndLogEx(NORMAL, "-- T55x7 Trace Information ----------------------------------");
PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); PrintAndLogEx(NORMAL, "-------------------------------------------------------------");
PrintAndLogEx(NORMAL, " ACL Allocation class (ISO/IEC 15963-1) : 0x%02X (%d)", data.acl, data.acl); PrintAndLogEx(NORMAL, " ACL Allocation class (ISO/IEC 15963-1) : 0x%02X (%d)", data.acl, data.acl);
@ -1185,7 +1257,8 @@ void printT55x7Trace( t55x7_tracedata_t data, uint8_t repeat ){
*/ */
} }
void printT5555Trace( t5555_tracedata_t data, uint8_t repeat ){ void printT5555Trace(t5555_tracedata_t data, uint8_t repeat)
{
PrintAndLogEx(NORMAL, "-- T5555 (Q5) Trace Information -----------------------------"); PrintAndLogEx(NORMAL, "-- T5555 (Q5) Trace Information -----------------------------");
PrintAndLogEx(NORMAL, "-------------------------------------------------------------"); PrintAndLogEx(NORMAL, "-------------------------------------------------------------");
PrintAndLogEx(NORMAL, " ICR IC Revision : %d", data.icr); PrintAndLogEx(NORMAL, " ICR IC Revision : %d", data.icr);
@ -1213,7 +1286,8 @@ void printT5555Trace( t5555_tracedata_t data, uint8_t repeat ){
} }
//need to add Q5 info... //need to add Q5 info...
int CmdT55xxInfo(const char *Cmd){ int CmdT55xxInfo(const char *Cmd)
{
/* /*
Page 0 Block 0 Configuration data. Page 0 Block 0 Configuration data.
Normal mode Normal mode
@ -1243,20 +1317,34 @@ int CmdT55xxInfo(const char *Cmd){
uint8_t si = config.offset; uint8_t si = config.offset;
uint32_t block0 = PackBits(si, 32, DemodBuffer); uint32_t block0 = PackBits(si, 32, DemodBuffer);
uint32_t safer = PackBits(si, 4, DemodBuffer); si += 4; uint32_t safer = PackBits(si, 4, DemodBuffer);
uint32_t resv = PackBits(si, 7, DemodBuffer); si += 7; si += 4;
uint32_t dbr = PackBits(si, 3, DemodBuffer); si += 3; uint32_t resv = PackBits(si, 7, DemodBuffer);
uint32_t extend = PackBits(si, 1, DemodBuffer); si += 1; si += 7;
uint32_t datamod = PackBits(si, 5, DemodBuffer); si += 5; uint32_t dbr = PackBits(si, 3, DemodBuffer);
uint32_t pskcf = PackBits(si, 2, DemodBuffer); si += 2; si += 3;
uint32_t aor = PackBits(si, 1, DemodBuffer); si += 1; uint32_t extend = PackBits(si, 1, DemodBuffer);
uint32_t otp = PackBits(si, 1, DemodBuffer); si += 1; si += 1;
uint32_t maxblk = PackBits(si, 3, DemodBuffer); si += 3; uint32_t datamod = PackBits(si, 5, DemodBuffer);
uint32_t pwd = PackBits(si, 1, DemodBuffer); si += 1; si += 5;
uint32_t sst = PackBits(si, 1, DemodBuffer); si += 1; uint32_t pskcf = PackBits(si, 2, DemodBuffer);
uint32_t fw = PackBits(si, 1, DemodBuffer); si += 1; si += 2;
uint32_t inv = PackBits(si, 1, DemodBuffer); si += 1; uint32_t aor = PackBits(si, 1, DemodBuffer);
uint32_t por = PackBits(si, 1, DemodBuffer); si += 1; si += 1;
uint32_t otp = PackBits(si, 1, DemodBuffer);
si += 1;
uint32_t maxblk = PackBits(si, 3, DemodBuffer);
si += 3;
uint32_t pwd = PackBits(si, 1, DemodBuffer);
si += 1;
uint32_t sst = PackBits(si, 1, DemodBuffer);
si += 1;
uint32_t fw = PackBits(si, 1, DemodBuffer);
si += 1;
uint32_t inv = PackBits(si, 1, DemodBuffer);
si += 1;
uint32_t por = PackBits(si, 1, DemodBuffer);
si += 1;
if (config.Q5) if (config.Q5)
PrintAndLogEx(NORMAL, _RED_(* **Warning ***) " Config Info read off a Q5 will not display as expected"); PrintAndLogEx(NORMAL, _RED_(* **Warning ***) " Config Info read off a Q5 will not display as expected");
@ -1285,7 +1373,8 @@ int CmdT55xxInfo(const char *Cmd){
return 0; return 0;
} }
int CmdT55xxDump(const char *Cmd){ int CmdT55xxDump(const char *Cmd)
{
uint32_t password = 0; uint32_t password = 0;
bool override = false; bool override = false;
@ -1310,7 +1399,8 @@ int CmdT55xxDump(const char *Cmd){
return 1; return 1;
} }
bool AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ) { bool AquireData(uint8_t page, uint8_t block, bool pwdmode, uint32_t password)
{
// arg0 bitmodes: // arg0 bitmodes:
// bit0 = pwdmode // bit0 = pwdmode
// bit1 = page to read from // bit1 = page to read from
@ -1330,7 +1420,8 @@ bool AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password )
return !getSignalProperties()->isnoise; return !getSignalProperties()->isnoise;
} }
char * GetBitRateStr(uint32_t id, bool xmode) { char *GetBitRateStr(uint32_t id, bool xmode)
{
static char buf[25]; static char buf[25];
char *retStr = buf; char *retStr = buf;
@ -1338,21 +1429,40 @@ char * GetBitRateStr(uint32_t id, bool xmode) {
snprintf(retStr, sizeof(buf), "%d - RF/%d", id, EM4x05_GET_BITRATE(id)); snprintf(retStr, sizeof(buf), "%d - RF/%d", id, EM4x05_GET_BITRATE(id));
} else { } else {
switch (id) { switch (id) {
case 0: snprintf(retStr,sizeof(buf),"%d - RF/8",id); break; case 0:
case 1: snprintf(retStr,sizeof(buf),"%d - RF/16",id); break; snprintf(retStr, sizeof(buf), "%d - RF/8", id);
case 2: snprintf(retStr,sizeof(buf),"%d - RF/32",id); break; break;
case 3: snprintf(retStr,sizeof(buf),"%d - RF/40",id); break; case 1:
case 4: snprintf(retStr,sizeof(buf),"%d - RF/50",id); break; snprintf(retStr, sizeof(buf), "%d - RF/16", id);
case 5: snprintf(retStr,sizeof(buf),"%d - RF/64",id); break; break;
case 6: snprintf(retStr,sizeof(buf),"%d - RF/100",id); break; case 2:
case 7: snprintf(retStr,sizeof(buf),"%d - RF/128",id); break; snprintf(retStr, sizeof(buf), "%d - RF/32", id);
default: snprintf(retStr,sizeof(buf),"%d - (Unknown)",id); break; break;
case 3:
snprintf(retStr, sizeof(buf), "%d - RF/40", id);
break;
case 4:
snprintf(retStr, sizeof(buf), "%d - RF/50", id);
break;
case 5:
snprintf(retStr, sizeof(buf), "%d - RF/64", id);
break;
case 6:
snprintf(retStr, sizeof(buf), "%d - RF/100", id);
break;
case 7:
snprintf(retStr, sizeof(buf), "%d - RF/128", id);
break;
default:
snprintf(retStr, sizeof(buf), "%d - (Unknown)", id);
break;
} }
} }
return buf; return buf;
} }
char * GetSaferStr(uint32_t id){ char *GetSaferStr(uint32_t id)
{
static char buf[40]; static char buf[40];
char *retStr = buf; char *retStr = buf;
@ -1367,29 +1477,57 @@ char * GetSaferStr(uint32_t id){
return buf; return buf;
} }
char * GetModulationStr( uint32_t id){ char *GetModulationStr(uint32_t id)
{
static char buf[60]; static char buf[60];
char *retStr = buf; char *retStr = buf;
switch (id) { switch (id) {
case 0: snprintf(retStr,sizeof(buf),"%d - DIRECT (ASK/NRZ)",id); break; case 0:
case 1: snprintf(retStr,sizeof(buf),"%d - PSK 1 phase change when input changes",id); break; snprintf(retStr, sizeof(buf), "%d - DIRECT (ASK/NRZ)", id);
case 2: snprintf(retStr,sizeof(buf),"%d - PSK 2 phase change on bitclk if input high",id); break; break;
case 3: snprintf(retStr,sizeof(buf),"%d - PSK 3 phase change on rising edge of input",id); break; case 1:
case 4: snprintf(retStr,sizeof(buf),"%d - FSK 1 RF/8 RF/5",id); break; snprintf(retStr, sizeof(buf), "%d - PSK 1 phase change when input changes", id);
case 5: snprintf(retStr,sizeof(buf),"%d - FSK 2 RF/8 RF/10",id); break; break;
case 6: snprintf(retStr,sizeof(buf),"%d - FSK 1a RF/5 RF/8",id); break; case 2:
case 7: snprintf(retStr,sizeof(buf),"%d - FSK 2a RF/10 RF/8",id); break; snprintf(retStr, sizeof(buf), "%d - PSK 2 phase change on bitclk if input high", id);
case 8: snprintf(retStr,sizeof(buf),"%d - Manchester",id); break; break;
case 16: snprintf(retStr,sizeof(buf),"%d - Biphase",id); break; case 3:
case 0x18:snprintf(retStr,sizeof(buf),"%d - Biphase a - AKA Conditional Dephase Encoding(CDP)",id); break; snprintf(retStr, sizeof(buf), "%d - PSK 3 phase change on rising edge of input", id);
case 17: snprintf(retStr,sizeof(buf),"%d - Reserved",id); break; break;
default: snprintf(retStr,sizeof(buf),"0x%02X (Unknown)",id); break; case 4:
snprintf(retStr, sizeof(buf), "%d - FSK 1 RF/8 RF/5", id);
break;
case 5:
snprintf(retStr, sizeof(buf), "%d - FSK 2 RF/8 RF/10", id);
break;
case 6:
snprintf(retStr, sizeof(buf), "%d - FSK 1a RF/5 RF/8", id);
break;
case 7:
snprintf(retStr, sizeof(buf), "%d - FSK 2a RF/10 RF/8", id);
break;
case 8:
snprintf(retStr, sizeof(buf), "%d - Manchester", id);
break;
case 16:
snprintf(retStr, sizeof(buf), "%d - Biphase", id);
break;
case 0x18:
snprintf(retStr, sizeof(buf), "%d - Biphase a - AKA Conditional Dephase Encoding(CDP)", id);
break;
case 17:
snprintf(retStr, sizeof(buf), "%d - Reserved", id);
break;
default:
snprintf(retStr, sizeof(buf), "0x%02X (Unknown)", id);
break;
} }
return buf; return buf;
} }
char * GetModelStrFromCID(uint32_t cid){ char *GetModelStrFromCID(uint32_t cid)
{
static char buf[10]; static char buf[10];
char *retStr = buf; char *retStr = buf;
@ -1399,30 +1537,58 @@ char * GetModelStrFromCID(uint32_t cid){
return buf; return buf;
} }
char * GetSelectedModulationStr( uint8_t id){ char *GetSelectedModulationStr(uint8_t id)
{
static char buf[20]; static char buf[20];
char *retStr = buf; char *retStr = buf;
switch (id) { switch (id) {
case DEMOD_FSK: snprintf(retStr,sizeof(buf),"FSK"); break; case DEMOD_FSK:
case DEMOD_FSK1: snprintf(retStr,sizeof(buf),"FSK1"); break; snprintf(retStr, sizeof(buf), "FSK");
case DEMOD_FSK1a: snprintf(retStr,sizeof(buf),"FSK1a"); break; break;
case DEMOD_FSK2: snprintf(retStr,sizeof(buf),"FSK2"); break; case DEMOD_FSK1:
case DEMOD_FSK2a: snprintf(retStr,sizeof(buf),"FSK2a"); break; snprintf(retStr, sizeof(buf), "FSK1");
case DEMOD_ASK: snprintf(retStr,sizeof(buf),"ASK"); break; break;
case DEMOD_NRZ: snprintf(retStr,sizeof(buf),"DIRECT/NRZ"); break; case DEMOD_FSK1a:
case DEMOD_PSK1: snprintf(retStr,sizeof(buf),"PSK1"); break; snprintf(retStr, sizeof(buf), "FSK1a");
case DEMOD_PSK2: snprintf(retStr,sizeof(buf),"PSK2"); break; break;
case DEMOD_PSK3: snprintf(retStr,sizeof(buf),"PSK3"); break; case DEMOD_FSK2:
case DEMOD_BI: snprintf(retStr,sizeof(buf),"BIPHASE"); break; snprintf(retStr, sizeof(buf), "FSK2");
case DEMOD_BIa: snprintf(retStr,sizeof(buf),"BIPHASEa - (CDP)"); break; break;
default: snprintf(retStr,sizeof(buf),"(Unknown)"); break; case DEMOD_FSK2a:
snprintf(retStr, sizeof(buf), "FSK2a");
break;
case DEMOD_ASK:
snprintf(retStr, sizeof(buf), "ASK");
break;
case DEMOD_NRZ:
snprintf(retStr, sizeof(buf), "DIRECT/NRZ");
break;
case DEMOD_PSK1:
snprintf(retStr, sizeof(buf), "PSK1");
break;
case DEMOD_PSK2:
snprintf(retStr, sizeof(buf), "PSK2");
break;
case DEMOD_PSK3:
snprintf(retStr, sizeof(buf), "PSK3");
break;
case DEMOD_BI:
snprintf(retStr, sizeof(buf), "BIPHASE");
break;
case DEMOD_BIa:
snprintf(retStr, sizeof(buf), "BIPHASEa - (CDP)");
break;
default:
snprintf(retStr, sizeof(buf), "(Unknown)");
break;
} }
return buf; return buf;
} }
void t55x7_create_config_block( int tagtype ){ void t55x7_create_config_block(int tagtype)
{
/* /*
T55X7_DEFAULT_CONFIG_BLOCK, T55X7_RAW_CONFIG_BLOCK T55X7_DEFAULT_CONFIG_BLOCK, T55X7_RAW_CONFIG_BLOCK
@ -1434,16 +1600,23 @@ void t55x7_create_config_block( int tagtype ){
char *retStr = buf; char *retStr = buf;
switch (tagtype) { switch (tagtype) {
case 0: snprintf(retStr, sizeof(buf),"%08X - T55X7 Default", T55X7_DEFAULT_CONFIG_BLOCK); break; case 0:
case 1: snprintf(retStr, sizeof(buf),"%08X - T55X7 Raw", T55X7_RAW_CONFIG_BLOCK); break; snprintf(retStr, sizeof(buf), "%08X - T55X7 Default", T55X7_DEFAULT_CONFIG_BLOCK);
case 2: snprintf(retStr, sizeof(buf),"%08X - T5555 Q5 Default", T5555_DEFAULT_CONFIG_BLOCK); break; break;
case 1:
snprintf(retStr, sizeof(buf), "%08X - T55X7 Raw", T55X7_RAW_CONFIG_BLOCK);
break;
case 2:
snprintf(retStr, sizeof(buf), "%08X - T5555 Q5 Default", T5555_DEFAULT_CONFIG_BLOCK);
break;
default: default:
break; break;
} }
PrintAndLogEx(NORMAL, buf); PrintAndLogEx(NORMAL, buf);
} }
int CmdResetRead(const char *Cmd) { int CmdResetRead(const char *Cmd)
{
UsbCommand c = {CMD_T55XX_RESET_READ, {0, 0, 0}}; UsbCommand c = {CMD_T55XX_RESET_READ, {0, 0, 0}};
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
@ -1461,7 +1634,8 @@ int CmdResetRead(const char *Cmd) {
return 1; return 1;
} }
int CmdT55xxWipe(const char *Cmd) { int CmdT55xxWipe(const char *Cmd)
{
char writeData[20] = {0}; char writeData[20] = {0};
char *ptrData = writeData; char *ptrData = writeData;
char cmdp = tolower(param_getchar(Cmd, 0)); char cmdp = tolower(param_getchar(Cmd, 0));
@ -1491,16 +1665,19 @@ int CmdT55xxWipe(const char *Cmd) {
return 0; return 0;
} }
bool IsCancelled(void) { bool IsCancelled(void)
{
if (ukbhit()) { if (ukbhit()) {
int gc = getchar(); (void)gc; int gc = getchar();
(void)gc;
PrintAndLogEx(WARNING, "\naborted via keyboard!\n"); PrintAndLogEx(WARNING, "\naborted via keyboard!\n");
return true; return true;
} }
return false; return false;
} }
int CmdT55xxChkPwds(const char *Cmd) { int CmdT55xxChkPwds(const char *Cmd)
{
// load a default pwd file. // load a default pwd file.
char line[9]; char line[9];
char filename[FILE_PATH_SIZE] = {0}; char filename[FILE_PATH_SIZE] = {0};
@ -1534,7 +1711,8 @@ int CmdT55xxChkPwds(const char *Cmd) {
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
timeout++; timeout++;
printf("."); fflush(stdout); printf(".");
fflush(stdout);
if (timeout > 180) { if (timeout > 180) {
PrintAndLogEx(WARNING, "\nno response from Proxmark. Aborting..."); PrintAndLogEx(WARNING, "\nno response from Proxmark. Aborting...");
return 2; return 2;
@ -1670,7 +1848,8 @@ out:
return 0; return 0;
} }
int CmdT55xxBruteForce(const char *Cmd) { int CmdT55xxBruteForce(const char *Cmd)
{
uint32_t start_password = 0x00000000; //start password uint32_t start_password = 0x00000000; //start password
uint32_t end_password = 0xFFFFFFFF; //end password uint32_t end_password = 0xFFFFFFFF; //end password
@ -1699,7 +1878,8 @@ int CmdT55xxBruteForce(const char *Cmd) {
while (!found) { while (!found) {
printf("."); fflush(stdout); printf(".");
fflush(stdout);
if (IsCancelled()) { if (IsCancelled()) {
return 0; return 0;
@ -1729,7 +1909,8 @@ int CmdT55xxBruteForce(const char *Cmd) {
return 0; return 0;
} }
int tryOnePassword(uint32_t password) { int tryOnePassword(uint32_t password)
{
PrintAndLogEx(INFO, "Trying password %08x", password); PrintAndLogEx(INFO, "Trying password %08x", password);
if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, password)) { if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, password)) {
PrintAndLogEx(NORMAL, "Acquire data from device failed. Quitting"); PrintAndLogEx(NORMAL, "Acquire data from device failed. Quitting");
@ -1742,7 +1923,8 @@ int tryOnePassword(uint32_t password) {
return 0; return 0;
} }
int CmdT55xxRecoverPW(const char *Cmd) { int CmdT55xxRecoverPW(const char *Cmd)
{
int bit = 0; int bit = 0;
uint32_t orig_password = 0x0; uint32_t orig_password = 0x0;
uint32_t curr_password = 0x0; uint32_t curr_password = 0x0;
@ -1819,7 +2001,8 @@ int CmdT55xxRecoverPW(const char *Cmd) {
// note length of data returned is different for different chips. // note length of data returned is different for different chips.
// some return all page 1 (64 bits) and others return just that block (32 bits) // some return all page 1 (64 bits) and others return just that block (32 bits)
// unfortunately the 64 bits makes this more likely to get a false positive... // unfortunately the 64 bits makes this more likely to get a false positive...
bool tryDetectP1(bool getData) { bool tryDetectP1(bool getData)
{
uint8_t preamble[] = {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1}; uint8_t preamble[] = {1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1};
size_t startIdx = 0; size_t startIdx = 0;
uint8_t fc1 = 0, fc2 = 0, ans = 0; uint8_t fc1 = 0, fc2 = 0, ans = 0;
@ -1926,7 +2109,8 @@ bool tryDetectP1(bool getData) {
return false; return false;
} }
// does this need to be a callable command? // does this need to be a callable command?
int CmdT55xxDetectPage1(const char *Cmd){ int CmdT55xxDetectPage1(const char *Cmd)
{
bool errors = false; bool errors = false;
bool useGB = false; bool useGB = false;
bool usepwd = false; bool usepwd = false;
@ -1964,7 +2148,8 @@ int CmdT55xxDetectPage1(const char *Cmd){
return success; return success;
} }
int CmdT55xxSetDeviceConfig(const char *Cmd){ int CmdT55xxSetDeviceConfig(const char *Cmd)
{
uint8_t startgap = 0, writegap = 0; uint8_t startgap = 0, writegap = 0;
uint8_t write0 = 0, write1 = 0, readgap = 0; uint8_t write0 = 0, write1 = 0, readgap = 0;
bool errors = false, shall_persist = false; bool errors = false, shall_persist = false;
@ -2037,13 +2222,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFT55XX(const char *Cmd) { int CmdLFT55XX(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -21,7 +21,8 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int CmdTIDemod(const char *Cmd) { int CmdTIDemod(const char *Cmd)
{
/* MATLAB as follows: /* MATLAB as follows:
f_s = 2000000; % sampling frequency f_s = 2000000; % sampling frequency
f_l = 123200; % low FSK tone f_l = 123200; % low FSK tone
@ -216,13 +217,11 @@ int CmdTIDemod(const char *Cmd) {
if (TagType != ((shift0 >> 16) & 0xFF)) { if (TagType != ((shift0 >> 16) & 0xFF)) {
PrintAndLogEx(WARNING, "Error: start and stop bits do not match!"); PrintAndLogEx(WARNING, "Error: start and stop bits do not match!");
goto out; goto out;
} } else if (TagType == 0x7E) {
else if (TagType == 0x7E) {
PrintAndLogEx(INFO, "Readonly TI tag detected."); PrintAndLogEx(INFO, "Readonly TI tag detected.");
retval = 1; retval = 1;
goto out; goto out;
} } else if (TagType == 0xFE) {
else if (TagType == 0xFE) {
PrintAndLogEx(INFO, "Rewriteable TI tag detected."); PrintAndLogEx(INFO, "Rewriteable TI tag detected.");
// put 64 bit data into shift1 and shift0 // put 64 bit data into shift1 and shift0
@ -265,8 +264,7 @@ int CmdTIDemod(const char *Cmd) {
retval = 1; retval = 1;
goto out; goto out;
} } else {
else {
PrintAndLogEx(WARNING, "Unknown tag type."); PrintAndLogEx(WARNING, "Unknown tag type.");
} }
@ -278,7 +276,8 @@ out:
} }
// read a TI tag and return its ID // read a TI tag and return its ID
int CmdTIRead(const char *Cmd) { int CmdTIRead(const char *Cmd)
{
UsbCommand c = {CMD_READ_TI_TYPE}; UsbCommand c = {CMD_READ_TI_TYPE};
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
@ -286,7 +285,8 @@ int CmdTIRead(const char *Cmd) {
} }
// write new data to a r/w TI tag // write new data to a r/w TI tag
int CmdTIWrite(const char *Cmd) { int CmdTIWrite(const char *Cmd)
{
int res = 0; int res = 0;
UsbCommand c = {CMD_WRITE_TI_TYPE}; UsbCommand c = {CMD_WRITE_TI_TYPE};
res = sscanf(Cmd, "%012" SCNx64 " %012" SCNx64 " %012" SCNx64 "", &c.arg[0], &c.arg[1], &c.arg[2]); res = sscanf(Cmd, "%012" SCNx64 " %012" SCNx64 " %012" SCNx64 "", &c.arg[0], &c.arg[1], &c.arg[2]);
@ -311,13 +311,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFTI(const char *Cmd){ int CmdLFTI(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd){ int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -11,7 +11,8 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_lf_viking_clone(void) { int usage_lf_viking_clone(void)
{
PrintAndLogEx(NORMAL, "clone a Viking AM tag to a T55x7 tag."); PrintAndLogEx(NORMAL, "clone a Viking AM tag to a T55x7 tag.");
PrintAndLogEx(NORMAL, "Usage: lf viking clone <Card ID - 8 hex digits> <Q5>"); PrintAndLogEx(NORMAL, "Usage: lf viking clone <Card ID - 8 hex digits> <Q5>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -23,7 +24,8 @@ int usage_lf_viking_clone(void) {
return 0; return 0;
} }
int usage_lf_viking_sim(void) { int usage_lf_viking_sim(void)
{
PrintAndLogEx(NORMAL, "Enables simulation of viking card with specified card number."); PrintAndLogEx(NORMAL, "Enables simulation of viking card with specified card number.");
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "Per viking format, the card number is 8 digit hex number. Larger values are truncated."); PrintAndLogEx(NORMAL, "Per viking format, the card number is 8 digit hex number. Larger values are truncated.");
@ -38,7 +40,8 @@ int usage_lf_viking_sim(void) {
} }
// calc checksum // calc checksum
uint64_t getVikingBits(uint32_t id) { uint64_t getVikingBits(uint32_t id)
{
uint8_t checksum = ((id >> 24) & 0xFF) ^ ((id >> 16) & 0xFF) ^ ((id >> 8) & 0xFF) ^ (id & 0xFF) ^ 0xF2 ^ 0xA8; uint8_t checksum = ((id >> 24) & 0xFF) ^ ((id >> 16) & 0xFF) ^ ((id >> 8) & 0xFF) ^ (id & 0xFF) ^ 0xF2 ^ 0xA8;
uint64_t ret = (uint64_t)0xF2 << 56; uint64_t ret = (uint64_t)0xF2 << 56;
ret |= (uint64_t)id << 8; ret |= (uint64_t)id << 8;
@ -47,7 +50,8 @@ uint64_t getVikingBits(uint32_t id) {
} }
// by marshmellow // by marshmellow
// find viking preamble 0xF200 in already demoded data // find viking preamble 0xF200 in already demoded data
int detectViking(uint8_t *dest, size_t *size) { int detectViking(uint8_t *dest, size_t *size)
{
//make sure buffer has data //make sure buffer has data
if (*size < 64 * 2) return -2; if (*size < 64 * 2) return -2;
size_t startIdx = 0; size_t startIdx = 0;
@ -71,7 +75,8 @@ int detectViking(uint8_t *dest, size_t *size) {
//by marshmellow //by marshmellow
//see ASKDemod for what args are accepted //see ASKDemod for what args are accepted
int CmdVikingDemod(const char *Cmd) { int CmdVikingDemod(const char *Cmd)
{
if (!ASKDemod(Cmd, false, false, 1)) { if (!ASKDemod(Cmd, false, false, 1)) {
PrintAndLogEx(DEBUG, "DEBUG: Error - Viking ASKDemod failed"); PrintAndLogEx(DEBUG, "DEBUG: Error - Viking ASKDemod failed");
return 0; return 0;
@ -97,12 +102,14 @@ int CmdVikingDemod(const char *Cmd) {
//by marshmellow //by marshmellow
//see ASKDemod for what args are accepted //see ASKDemod for what args are accepted
int CmdVikingRead(const char *Cmd) { int CmdVikingRead(const char *Cmd)
{
lf_read(true, 10000); lf_read(true, 10000);
return CmdVikingDemod(Cmd); return CmdVikingDemod(Cmd);
} }
int CmdVikingClone(const char *Cmd) { int CmdVikingClone(const char *Cmd)
{
uint32_t id = 0; uint32_t id = 0;
uint64_t rawID = 0; uint64_t rawID = 0;
bool Q5 = false; bool Q5 = false;
@ -131,7 +138,8 @@ int CmdVikingClone(const char *Cmd) {
return 0; return 0;
} }
int CmdVikingSim(const char *Cmd) { int CmdVikingSim(const char *Cmd)
{
uint32_t id = 0; uint32_t id = 0;
uint64_t rawID = 0; uint64_t rawID = 0;
uint8_t clk = 32, encoding = 1, separator = 0, invert = 0; uint8_t clk = 32, encoding = 1, separator = 0, invert = 0;
@ -167,13 +175,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFViking(const char *Cmd) { int CmdLFViking(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -15,7 +15,8 @@
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_lf_visa2k_clone(void){ int usage_lf_visa2k_clone(void)
{
PrintAndLogEx(NORMAL, "clone a Visa2000 tag to a T55x7 tag."); PrintAndLogEx(NORMAL, "clone a Visa2000 tag to a T55x7 tag.");
PrintAndLogEx(NORMAL, "Usage: lf visa2000 clone [h] <card ID> <Q5>"); PrintAndLogEx(NORMAL, "Usage: lf visa2000 clone [h] <card ID> <Q5>");
PrintAndLogEx(NORMAL, "Options:"); PrintAndLogEx(NORMAL, "Options:");
@ -28,7 +29,8 @@ int usage_lf_visa2k_clone(void){
return 0; return 0;
} }
int usage_lf_visa2k_sim(void) { int usage_lf_visa2k_sim(void)
{
PrintAndLogEx(NORMAL, "Enables simulation of visa2k card with specified card number."); PrintAndLogEx(NORMAL, "Enables simulation of visa2k card with specified card number.");
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued."); PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, ""); PrintAndLogEx(NORMAL, "");
@ -42,14 +44,16 @@ int usage_lf_visa2k_sim(void) {
return 0; return 0;
} }
static uint8_t visa_chksum( uint32_t id ) { static uint8_t visa_chksum(uint32_t id)
{
uint8_t sum = 0; uint8_t sum = 0;
for (uint8_t i = 0; i < 32; i += 4) for (uint8_t i = 0; i < 32; i += 4)
sum ^= (id >> i) & 0xF; sum ^= (id >> i) & 0xF;
return sum & 0xF; return sum & 0xF;
} }
static uint8_t visa_parity( uint32_t id) { static uint8_t visa_parity(uint32_t id)
{
// 4bit parity LUT // 4bit parity LUT
uint8_t par_lut[] = { uint8_t par_lut[] = {
0, 1, 1, 0 0, 1, 1, 0
@ -71,7 +75,8 @@ static uint8_t visa_parity( uint32_t id) {
// by iceman // by iceman
// find Visa2000 preamble in already demoded data // find Visa2000 preamble in already demoded data
int detectVisa2k(uint8_t *dest, size_t *size) { int detectVisa2k(uint8_t *dest, size_t *size)
{
if (*size < 96) return -1; //make sure buffer has data if (*size < 96) return -1; //make sure buffer has data
size_t startIdx = 0; size_t startIdx = 0;
uint8_t preamble[] = {0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0}; uint8_t preamble[] = {0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0};
@ -94,7 +99,8 @@ int detectVisa2k(uint8_t *dest, size_t *size) {
* *
**/ **/
//see ASKDemod for what args are accepted //see ASKDemod for what args are accepted
int CmdVisa2kDemod(const char *Cmd) { int CmdVisa2kDemod(const char *Cmd)
{
save_restoreGB(GRAPH_SAVE); save_restoreGB(GRAPH_SAVE);
@ -153,12 +159,14 @@ int CmdVisa2kDemod(const char *Cmd) {
} }
// 64*96*2=12288 samples just in case we just missed the first preamble we can still catch 2 of them // 64*96*2=12288 samples just in case we just missed the first preamble we can still catch 2 of them
int CmdVisa2kRead(const char *Cmd) { int CmdVisa2kRead(const char *Cmd)
{
lf_read(true, 20000); lf_read(true, 20000);
return CmdVisa2kDemod(Cmd); return CmdVisa2kDemod(Cmd);
} }
int CmdVisa2kClone(const char *Cmd) { int CmdVisa2kClone(const char *Cmd)
{
uint64_t id = 0; uint64_t id = 0;
uint32_t blocks[4] = {T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_64 | T55x7_ST_TERMINATOR | 3 << T55x7_MAXBLOCK_SHIFT, BL0CK1, 0}; uint32_t blocks[4] = {T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_64 | T55x7_ST_TERMINATOR | 3 << T55x7_MAXBLOCK_SHIFT, BL0CK1, 0};
@ -194,7 +202,8 @@ int CmdVisa2kClone(const char *Cmd) {
return 0; return 0;
} }
int CmdVisa2kSim(const char *Cmd) { int CmdVisa2kSim(const char *Cmd)
{
uint32_t id = 0; uint32_t id = 0;
char cmdp = param_getchar(Cmd, 0); char cmdp = param_getchar(Cmd, 0);
@ -231,13 +240,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
int CmdLFVisa2k(const char *Cmd) { int CmdLFVisa2k(const char *Cmd)
{
clearCommandBuffer(); clearCommandBuffer();
CmdsParse(CommandTable, Cmd); CmdsParse(CommandTable, Cmd);
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }

View file

@ -38,11 +38,13 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };
command_t* getTopLevelCommandTable() { command_t *getTopLevelCommandTable()
{
return CommandTable; return CommandTable;
} }
int CmdRem(const char *Cmd) { int CmdRem(const char *Cmd)
{
char buf[22]; char buf[22];
memset(buf, 0x00, sizeof(buf)); memset(buf, 0x00, sizeof(buf));
@ -54,16 +56,19 @@ int CmdRem(const char *Cmd) {
return 0; return 0;
} }
int CmdHelp(const char *Cmd) { int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable); CmdsHelp(CommandTable);
return 0; return 0;
} }
int CmdQuit(const char *Cmd) { int CmdQuit(const char *Cmd)
{
return 99; return 99;
} }
int CmdRev(const char *Cmd) { int CmdRev(const char *Cmd)
{
CmdCrc(Cmd); CmdCrc(Cmd);
return 0; return 0;
} }
@ -72,6 +77,7 @@ int CmdRev(const char *Cmd) {
// Entry point into our code: called whenever the user types a command and // Entry point into our code: called whenever the user types a command and
// then presses Enter, which the full command line that they typed. // then presses Enter, which the full command line that they typed.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
int CommandReceived(char *Cmd) { int CommandReceived(char *Cmd)
{
return CmdsParse(CommandTable, Cmd); return CmdsParse(CommandTable, Cmd);
} }

View file

@ -17,7 +17,8 @@
#include "proxmark3.h" #include "proxmark3.h"
#include "comms.h" #include "comms.h"
void CmdsHelp(const command_t Commands[]) { void CmdsHelp(const command_t Commands[])
{
if (Commands[0].Name == NULL) return; if (Commands[0].Name == NULL) return;
int i = 0; int i = 0;
while (Commands[i].Name) { while (Commands[i].Name) {
@ -27,7 +28,8 @@ void CmdsHelp(const command_t Commands[]) {
} }
} }
int CmdsParse(const command_t Commands[], const char *Cmd) { int CmdsParse(const command_t Commands[], const char *Cmd)
{
// Help dump children // Help dump children
if (strcmp(Cmd, "XX_internal_command_dump_XX") == 0) { if (strcmp(Cmd, "XX_internal_command_dump_XX") == 0) {
dumpCommandsRecursive(Commands, 0); dumpCommandsRecursive(Commands, 0);
@ -76,7 +78,8 @@ int CmdsParse(const command_t Commands[], const char *Cmd) {
char pparent[512] = {0}; char pparent[512] = {0};
char *parent = pparent; char *parent = pparent;
void dumpCommandsRecursive(const command_t cmds[], int markdown) { void dumpCommandsRecursive(const command_t cmds[], int markdown)
{
if (cmds[0].Name == NULL) return; if (cmds[0].Name == NULL) return;
int i = 0; int i = 0;

Some files were not shown because too many files have changed in this diff Show more