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:
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
_test:

View file

@ -34,12 +34,14 @@ static uint32_t traceLen = 0;
static bool tracing = true; //todo static?
// get the address of BigBuf
uint8_t *BigBuf_get_addr(void) {
uint8_t *BigBuf_get_addr(void)
{
return (uint8_t *)BigBuf;
}
// 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
if (emulator_memory == NULL)
emulator_memory = BigBuf_malloc(CARD_MEMORY_SIZE);
@ -48,28 +50,33 @@ uint8_t *BigBuf_get_EM_addr(void) {
}
// clear ALL of BigBuf
void BigBuf_Clear(void) {
void BigBuf_Clear(void)
{
BigBuf_Clear_ext(true);
}
// clear ALL of BigBuf
void BigBuf_Clear_ext(bool verbose) {
void BigBuf_Clear_ext(bool verbose)
{
memset(BigBuf, 0, BIGBUF_SIZE);
if (verbose)
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);
}
void BigBuf_Clear_keep_EM(void) {
void BigBuf_Clear_keep_EM(void)
{
memset(BigBuf, 0, BigBuf_hi);
}
// 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
uint8_t *BigBuf_malloc(uint16_t chunksize) {
uint8_t *BigBuf_malloc(uint16_t chunksize)
{
if (BigBuf_hi - chunksize < 0)
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.
void BigBuf_free(void){
void BigBuf_free(void)
{
BigBuf_hi = BIGBUF_SIZE;
emulator_memory = NULL;
// shouldn't this empty BigBuf also?
}
// free allocated chunks EXCEPT the emulator memory
void BigBuf_free_keep_EM(void) {
void BigBuf_free_keep_EM(void)
{
if (emulator_memory != NULL)
BigBuf_hi = emulator_memory - (uint8_t *)BigBuf;
else
@ -95,7 +104,8 @@ void BigBuf_free_keep_EM(void) {
// shouldn't this empty BigBuf also?
}
void BigBuf_print_status(void) {
void BigBuf_print_status(void)
{
Dbprintf("Memory");
Dbprintf(" BIGBUF_SIZE.............%d", BIGBUF_SIZE);
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)
uint16_t BigBuf_max_traceLen(void) {
uint16_t BigBuf_max_traceLen(void)
{
return BigBuf_hi;
}
void clear_trace(void) {
void clear_trace(void)
{
traceLen = 0;
}
void set_tracelen(uint32_t value) {
void set_tracelen(uint32_t value)
{
traceLen = value;
}
void set_tracing(bool enable) {
void set_tracing(bool enable)
{
tracing = enable;
}
bool get_tracing(void) {
bool get_tracing(void)
{
return tracing;
}
@ -127,7 +142,8 @@ bool get_tracing(void) {
* Get the number of bytes traced
* @return
*/
uint32_t BigBuf_get_traceLen(void) {
uint32_t BigBuf_get_traceLen(void)
{
return traceLen;
}
@ -137,7 +153,8 @@ uint32_t BigBuf_get_traceLen(void) {
by 'hf list raw', alternatively 'hf list <proto>' for protocol-specific
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;
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;
}
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,
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
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();
if (offset + length < CARD_MEMORY_SIZE) {
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;
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)
LCDSend(PRAMWR); // Write to display
@ -62,8 +61,7 @@ void LCDString (char *lcd_string, const char *font_style,unsigned char x, unsign
data++;
offset = *data; // get data bytes per font
do
{
do {
// point to data in table to be loaded
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
#define MAX_PWDS_PER_SESSION 64
uint8_t FindOffsetInFlash() {
uint8_t FindOffsetInFlash()
{
uint8_t mem[4] = { 0x00, 0x00, 0x00, 0x00 };
uint8_t eom[4] = { 0xFF, 0xFF, 0xFF, 0xFF };
uint8_t memcnt = 0;
while (memcnt < 0xFF)
{
while (memcnt < 0xFF) {
Flash_ReadData(memcnt, mem, 4);
if (memcmp(mem, eom, 4) == 0) {
return memcnt;
@ -44,7 +44,8 @@ uint8_t FindOffsetInFlash() {
return 0; // wrap-around
}
void EraseMemory() {
void EraseMemory()
{
if (!FlashInit()) {
return;
}
@ -59,13 +60,15 @@ void EraseMemory() {
}
// This is actually copied from SniffIso14443a
void RAMFUNC SniffAndStore(uint8_t param) {
void RAMFUNC SniffAndStore(uint8_t param)
{
iso14443a_setup(FPGA_HF_ISO14443A_SNIFFER);
// Allocate memory from BigBuf for some buffers
// free all previous allocations first
BigBuf_free(); BigBuf_Clear_ext(false);
BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace();
set_tracing(true);
@ -239,8 +242,7 @@ void RAMFUNC SniffAndStore(uint8_t param) {
uint8_t memoffset = FindOffsetInFlash();
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
memoffset = 0;
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
uint8_t *previousdata = BigBuf_malloc(memoffset);
if (memoffset > 0)
{
if (memoffset > 0) {
uint16_t readlen = Flash_ReadData(0, previousdata, memoffset);
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();

View file

@ -112,16 +112,12 @@ void ReadLastTagFromFlash()
uint32_t end_time;
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);
isok = Flash_ReadDataCont(startidx + i, mem, len);
if (isok == len)
{
if (isok == len) {
emlSetMem(mem, 0, 64);
}
else
{
} else {
DbprintfEx(FLAG_NOLOG, "FlashMem reading failed | %d | %d", len, isok);
cjSetCursLeft();
FlashStop();
@ -169,8 +165,7 @@ void WriteTagToFlash(uint8_t index, size_t size)
uint32_t end_time;
uint32_t start_time = end_time = GetTickCount();
while (bytes_remaining > 0)
{
while (bytes_remaining > 0) {
Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable();
@ -184,8 +179,7 @@ void WriteTagToFlash(uint8_t index, size_t size)
isok = (res == bytes_in_packet) ? 1 : 0;
if (!isok)
{
if (!isok) {
DbprintfEx(FLAG_NOLOG, "FlashMem write FAILEd [offset %u]", bytes_sent);
cjSetCursLeft();
SpinOff(100);
@ -310,8 +304,7 @@ ACCBITS : 796788[00]+VALUE
keyBlock = BigBuf_malloc(STKEYS * 6);
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));
}
@ -319,10 +312,8 @@ ACCBITS : 796788[00]+VALUE
// 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];
for (uint16_t t = 0; t < 2; t++)
{
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++)
{
for (uint16_t t = 0; t < 2; t++) {
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++) {
foundKey[t][sectorNo][0] = 0xFF;
foundKey[t][sectorNo][1] = 0xFF;
foundKey[t][sectorNo][2] = 0xFF;
@ -363,18 +354,15 @@ failtag:
LED_A_ON();
uint8_t ticker = 0;
//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();
ticker++;
if (ticker % 64 == 0)
{
if (ticker % 64 == 0) {
LED_A_INV();
}
if (BUTTON_HELD(10) > 0)
{
if (BUTTON_HELD(10) > 0) {
WDT_HIT();
DbprintfEx(FLAG_NOLOG, "\t\t\t[ READING FLASH ]");
ReadLastTagFromFlash();
@ -393,8 +381,7 @@ failtag:
DbprintfEx(FLAG_NOLOG, "\t%sGOT TAG :%s %08x%s", _RED_, _CYAN_, cjcuid, _WHITE_);
if (cjcuid == 0)
{
if (cjcuid == 0) {
cjSetCursLeft();
DbprintfEx(FLAG_NOLOG, "%s>>%s BUG: 0000_CJCUID! Retrying...", _RED_, _WHITE_);
SpinErr(0, 100, 8);
@ -441,29 +428,22 @@ failtag:
// also we could avoid first UID check for every block
// then lets expose this “optimal case” of “well known vigik schemes” :
for (uint8_t type = 0; type < 2 && !err && !trapped; type++)
{
for (int sec = 0; sec < sectorsCnt && !err && !trapped; ++sec)
{
for (uint8_t type = 0; type < 2 && !err && !trapped; type++) {
for (int sec = 0; sec < sectorsCnt && !err && !trapped; ++sec) {
key = cjat91_saMifareChkKeys(sec * 4, type, NULL, size, &keyBlock[0], &key64);
if (key == -1)
{
if (key == -1) {
err = 1;
allKeysFound = false;
// 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);
break;
}
else if (key == -2)
{
} else if (key == -2) {
err = 1; // Can't select card.
allKeysFound = false;
// cmd_send(CMD_CJB_FSMSTATE_MENU, 0, 0, 0, 0, 0);
break;
}
else
{
} else {
/* BRACE YOURSELF : AS LONG AS WE TRAP A KNOWN KEY, WE STOP CHECKING AND ENFORCE KNOWN SCHEMES */
// uint8_t tosendkey[13];
char tosendkey[13];
@ -471,8 +451,7 @@ failtag:
cjSetCursRight();
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);*/
switch (key64)
{
switch (key64) {
/////////////////////////////////////////////////////////
// COMMON SCHEME 1 : INFINITRON/HEXACT
case 0x484558414354:
@ -493,8 +472,7 @@ failtag:
;
// Type 0 / A first
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]);
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]);
@ -640,10 +618,8 @@ failtag:
// emlClearMem();
// A very weak one...
for (uint16_t t = 0; t < 2; t++)
{
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; sectorNo++)
{
for (uint16_t t = 0; t < 2; t++) {
for (uint16_t sectorNo = 0; sectorNo < sectorsCnt; 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],
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_);
;
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]);
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]);
@ -688,8 +663,7 @@ failtag:
;
}
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]);
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]);
@ -706,8 +680,7 @@ failtag:
}
}
if (!allKeysFound)
{
if (!allKeysFound) {
cjSetCursLeft();
cjTabulize();
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 */
emlClearMem();
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);
for (uint8_t t = 0; t < 2; t++)
{
for (uint8_t t = 0; t < 2; t++) {
memcpy(mblock + t * 10, foundKey[t][sectorNo], 6);
}
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_);
e_MifareECardLoad(sectorsCnt, 0, 0, &filled);
if (filled != 1)
{
if (filled != 1) {
cjSetCursLeft();
DbprintfEx(FLAG_NOLOG, "%s>>%s W_FAILURE ! %sTrying fallback B keys....", _RED_, _ORANGE_, _WHITE_);
/* no trace, no dbg */
e_MifareECardLoad(sectorsCnt, 1, 0, &filled);
if (filled != 1)
{
if (filled != 1) {
cjSetCursLeft();
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;
if (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true))
{
if (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) {
isOK = false;
if (MF_DBGLEVEL >= 1)
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);
if (sectorNo == 0)
{
if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST))
{
if (sectorNo == 0) {
if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_FIRST)) {
isOK = false;
if (MF_DBGLEVEL >= 1)
DbprintfEx(FLAG_NOLOG, "Sector[%2d]. Auth error", sectorNo);
break;
}
}
else
{
if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_NESTED))
{
} else {
if (isOK && mifare_classic_auth(pcs, cjcuid, FirstBlockOfSector(sectorNo), keyType, ui64Key, AUTH_NESTED)) {
isOK = false;
if (MF_DBGLEVEL >= 1)
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++)
{
if (isOK && mifare_classic_readblock(pcs, cjcuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf))
{
for (uint8_t blockNo = 0; isOK && blockNo < NumBlocksPerSector(sectorNo); blockNo++) {
if (isOK && mifare_classic_readblock(pcs, cjcuid, FirstBlockOfSector(sectorNo) + blockNo, dataoutbuf)) {
isOK = false;
if (MF_DBGLEVEL >= 1)
DbprintfEx(FLAG_NOLOG, "Error reading sector %2d block %2d", sectorNo, blockNo);
break;
};
if (isOK)
{
if (isOK) {
*datain = 1;
if (blockNo < NumBlocksPerSector(sectorNo) - 1)
{
if (blockNo < NumBlocksPerSector(sectorNo) - 1) {
emlSetMem(dataoutbuf, FirstBlockOfSector(sectorNo) + blockNo, 1);
}
else
{ // sector trailer, keep the keys, set only the AC
} else {
// sector trailer, keep the keys, set only the AC
emlGetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);
memcpy(&dataoutbuf2[6], &dataoutbuf[6], 4);
emlSetMem(dataoutbuf2, FirstBlockOfSector(sectorNo) + blockNo, 1);
}
}
else
{
} else {
*datain = 0;
}
}
}
if (mifare_classic_halt(pcs, cjcuid))
{
if (mifare_classic_halt(pcs, cjcuid)) {
if (MF_DBGLEVEL >= 1)
DbprintfEx(FLAG_NOLOG, "Halt error");
};
@ -944,21 +898,18 @@ int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
struct Crypto1State *pcs;
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 */
// 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();
DbprintfEx(FLAG_NOLOG, "%sFATAL%s : E_MF_LOSTTAG", _RED_, _WHITE_);
return -1;
}
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;
ReaderTransmit(&dummy_answer, 1, NULL);
// wait for the card to become ready again
@ -990,8 +941,7 @@ void saMifareMakeTag(void)
DbprintfEx(FLAG_NOLOG, ">> Write to Special:");
int flags = 0;
for (int blockNum = 0; blockNum < 16 * 4; blockNum++)
{
for (int blockNum = 0; blockNum < 16 * 4; blockNum++) {
uint8_t mblock[16];
// cnt = 0;
emlGetMem(mblock, blockNum, 1);
@ -1007,12 +957,11 @@ void saMifareMakeTag(void)
if (blockNum == 16 * 4 - 1)
flags = 0x04 + 0x10;
if (saMifareCSetBlock(0, flags & 0xFE, blockNum, mblock))
{ //&& cnt <= retry) {
if (saMifareCSetBlock(0, flags & 0xFE, blockNum, mblock)) {
//&& cnt <= retry) {
// cnt++;
cjSetCursFRight();
if (currfline > 53)
{
if (currfline > 53) {
currfline = 54;
}
DbprintfEx(FLAG_NOLOG, "Block :%02x %sOK%s", blockNum, _GREEN_, _WHITE_);
@ -1020,9 +969,7 @@ void saMifareMakeTag(void)
// cfail=1;
// return;
continue;
}
else
{
} else {
cjSetCursLeft();
cjSetCursLeft();
@ -1041,8 +988,7 @@ void saMifareMakeTag(void)
break;
} */
}
if (cfail == 0)
{
if (cfail == 0) {
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];
// reset FPGA and LED
if (workFlags & 0x08)
{
if (workFlags & 0x08) {
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
// clear_trace();
set_tracing(FALSE);
}
while (true)
{
while (true) {
cjSetCursLeft();
// get UID from chip
if (workFlags & 0x01)
{
if (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true))
{
if (workFlags & 0x01) {
if (!iso14443a_select_card(cjuid, NULL, &cjcuid, true, 0, true)) {
DbprintfEx(FLAG_NOLOG, "Can't select card");
break;
};
if (mifare_classic_halt(NULL, cjcuid))
{
if (mifare_classic_halt(NULL, cjcuid)) {
DbprintfEx(FLAG_NOLOG, "Halt error");
break;
};
};
// reset chip
if (needWipe)
{
if (needWipe) {
ReaderTransmitBitsPar(wupC1, 7, 0, NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a))
{
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
DbprintfEx(FLAG_NOLOG, "wupC1 error");
break;
};
ReaderTransmit(wipeC, sizeof(wipeC), NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a))
{
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
DbprintfEx(FLAG_NOLOG, "wipeC error");
break;
};
if (mifare_classic_halt(NULL, cjcuid))
{
if (mifare_classic_halt(NULL, cjcuid)) {
DbprintfEx(FLAG_NOLOG, "Halt error");
break;
};
@ -1131,25 +1068,21 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
// chaud
// write block
if (workFlags & 0x02)
{
if (workFlags & 0x02) {
ReaderTransmitBitsPar(wupC1, 7, 0, NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a))
{
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
DbprintfEx(FLAG_NOLOG, "wupC1 error");
break;
};
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a))
{
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
DbprintfEx(FLAG_NOLOG, "wupC2 errorv");
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");
break;
};
@ -1157,16 +1090,13 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
memcpy(d_block, datain, 16);
AddCrc14A(d_block, 16);
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");
break;
};
if (workFlags & 0x04)
{
if (mifare_classic_halt(NULL, cjcuid))
{
if (workFlags & 0x04) {
if (mifare_classic_halt(NULL, cjcuid)) {
cjSetCursFRight();
DbprintfEx(FLAG_NOLOG, "Halt error");
@ -1178,8 +1108,7 @@ int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *data
break;
}
if ((workFlags & 0x10) || (!isOK))
{
if ((workFlags & 0x10) || (!isOK)) {
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];
// reset FPGA and LED
if (workFlags & 0x08)
{
if (workFlags & 0x08) {
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
set_tracing(false);
}
while (true)
{
while (true) {
// get UID from chip
if (workFlags & 0x01)
{
if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true))
{
if (workFlags & 0x01) {
if (!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
DbprintfEx(FLAG_NOLOG, "Can't select card");
break;
};
if (mifare_classic_halt(NULL, cuid))
{
if (mifare_classic_halt(NULL, cuid)) {
DbprintfEx(FLAG_NOLOG, "Halt error");
break;
};
};
// reset chip
if (needWipe)
{
if (needWipe) {
ReaderTransmitBitsPar(wupC1, 7, 0, NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a))
{
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
DbprintfEx(FLAG_NOLOG, "wupC1 error");
break;
};
ReaderTransmit(wipeC, sizeof(wipeC), NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a))
{
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
DbprintfEx(FLAG_NOLOG, "wipeC error");
break;
};
if (mifare_classic_halt(NULL, cuid))
{
if (mifare_classic_halt(NULL, cuid)) {
DbprintfEx(FLAG_NOLOG, "Halt error");
break;
};
@ -117,25 +108,21 @@ static int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_
// chaud
// write block
if (workFlags & 0x02)
{
if (workFlags & 0x02) {
ReaderTransmitBitsPar(wupC1, 7, 0, NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a))
{
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
DbprintfEx(FLAG_NOLOG, "wupC1 error");
break;
};
ReaderTransmit(wupC2, sizeof(wupC2), NULL);
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a))
{
if (!ReaderReceive(receivedAnswer, receivedAnswerPar) || (receivedAnswer[0] != 0x0a)) {
DbprintfEx(FLAG_NOLOG, "wupC2 errorv");
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");
break;
};
@ -143,16 +130,13 @@ static int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_
memcpy(d_block, datain, 16);
AddCrc14A(d_block, 16);
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");
break;
};
if (workFlags & 0x04)
{
if (mifare_classic_halt(NULL, cuid))
{
if (workFlags & 0x04) {
if (mifare_classic_halt(NULL, cuid)) {
DbprintfEx(FLAG_NOLOG, "Halt error");
break;
};
@ -162,8 +146,7 @@ static int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_
break;
}
if ((workFlags & 0x10) || (!isOK))
{
if ((workFlags & 0x10) || (!isOK)) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
}
@ -182,20 +165,17 @@ static int saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, ui
struct Crypto1State *pcs;
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 */
// 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");
return -1;
}
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;
ReaderTransmit(&dummy_answer, 1, NULL);
// 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();
Dbprintf(">> Matty mifare chk/dump/sim a.k.a MattyRun Started <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);

View file

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

View file

@ -27,7 +27,8 @@
#include "lf_hidbrute.h"
// samy's sniff and repeat routine for LF
void RunMod() {
void RunMod()
{
StandAloneMode();
Dbprintf(">> LF HID corporate bruteforce a.k.a CorporateBrute Started <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
@ -76,8 +77,7 @@ void RunMod() {
// so next button push begins playing what we recorded
playing = 0;
cardRead = 1;
}
else if (button_pressed > 0 && cardRead == 1) {
} else if (button_pressed > 0 && cardRead == 1) {
LEDsoff();
LED(selected + 1, 0);
LED(LED_ORANGE, 0);
@ -141,9 +141,7 @@ void RunMod() {
playing = !playing;
LEDsoff();
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.
// 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
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_low = 0;

View file

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

View file

@ -11,7 +11,8 @@
#include "lf_samyrun.h"
// samy's sniff and repeat routine for LF
void RunMod() {
void RunMod()
{
StandAloneMode();
Dbprintf(">> LF HID Read/Clone/Sim a.k.a SamyRun Started <<");
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
@ -64,8 +65,7 @@ void RunMod() {
cardRead = 1;
gotCard = true;
}
else if (button_pressed > 0 && cardRead == 1) {
} else if (button_pressed > 0 && cardRead == 1) {
LEDsoff();
LED(selected + 1, 0);
LED(LED_ORANGE, 0);
@ -129,8 +129,7 @@ void RunMod() {
playing = !playing;
LEDsoff();
LED(selected + 1, 0);
}
else {
} else {
while (BUTTON_PRESS())
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
* and add initial round key:
*/
v0 = GETU32(ct ); s0 = v0 ^ rk[0];
v1 = GETU32(ct + 4); s1 = v1 ^ rk[1];
v2 = GETU32(ct + 8); s2 = v2 ^ rk[2];
v3 = GETU32(ct + 12); s3 = v3 ^ rk[3];
v0 = GETU32(ct);
s0 = v0 ^ rk[0];
v1 = GETU32(ct + 4);
s1 = v1 ^ rk[1];
v2 = GETU32(ct + 8);
s2 = v2 ^ rk[2];
v3 = GETU32(ct + 12);
s3 = v3 ^ rk[3];
/*
* Nr - 1 full rounds:
*/
@ -1053,10 +1057,14 @@ void AesDecBlk(AesCtx *pCtx, const unsigned char ct[], unsigned char pt[])
rk[3];
if (pCtx->Mode) {
s0 = s0 ^ iv[0]; iv[0] = v0;
s1 = s1 ^ iv[1]; iv[1] = v1;
s2 = s2 ^ iv[2]; iv[2] = v2;
s3 = s3 ^ iv[3]; iv[3] = v3;
s0 = s0 ^ iv[0];
iv[0] = v0;
s1 = s1 ^ iv[1];
iv[1] = v1;
s2 = s2 ^ iv[2];
iv[2] = v2;
s3 = s3 ^ iv[3];
iv[3] = v3;
}
PUTU32(pt, s0);

View file

@ -54,12 +54,14 @@ int ToSendMax = -1;
static int ToSendBit;
struct common_area common_area __attribute__((section(".commonarea")));
void ToSendReset(void) {
void ToSendReset(void)
{
ToSendMax = -1;
ToSendBit = 8;
}
void ToSendStuffBit(int b) {
void ToSendStuffBit(int b)
{
if (ToSendBit >= 8) {
ToSendMax++;
ToSend[ToSendMax] = 0;
@ -77,12 +79,14 @@ void ToSendStuffBit(int b) {
}
}
void PrintToSendBuffer(void) {
void PrintToSendBuffer(void)
{
DbpString("Printing ToSendBuffer:");
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;
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.
//=============================================================================
void DbpStringEx(char *str, uint32_t cmd) {
void DbpStringEx(char *str, uint32_t cmd)
{
#if DEBUG
uint8_t len = strlen(str);
cmd_send(CMD_DEBUG_PRINT_STRING, len, cmd, 0, (uint8_t *)str, len);
#endif
}
void DbpString(char *str) {
void DbpString(char *str)
{
#if DEBUG
DbpStringEx(str, 0);
#endif
}
#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);
}
#endif
void DbprintfEx(uint32_t cmd, const char *fmt, ...) {
void DbprintfEx(uint32_t cmd, const char *fmt, ...)
{
#if DEBUG
// should probably limit size here; oh well, let's just use a big buffer
char output_string[128] = {0x00};
@ -141,7 +149,8 @@ void DbprintfEx(uint32_t cmd, const char *fmt, ...) {
#endif
}
void Dbprintf(const char *fmt, ...) {
void Dbprintf(const char *fmt, ...)
{
#if DEBUG
// should probably limit size here; oh well, let's just use a big buffer
char output_string[128] = {0x00};
@ -156,7 +165,8 @@ void Dbprintf(const char *fmt, ...) {
}
// prints HEX & ASCII
void Dbhexdump(int len, uint8_t *d, bool bAsci) {
void Dbhexdump(int len, uint8_t *d, bool bAsci)
{
#if DEBUG
int l = 0, i;
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
// 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.
// 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
uint16_t AvgAdc(int ch) {
uint16_t AvgAdc(int ch)
{
uint16_t a = 0;
for (uint8_t i = 0; i < 32; i++)
a += ReadAdc(ch);
@ -226,7 +238,8 @@ uint16_t AvgAdc(int ch) {
return (a + 15) >> 5;
}
void MeasureAntennaTuning(void) {
void MeasureAntennaTuning(void)
{
uint8_t LF_Results[256];
uint32_t i, adcval = 0, peak = 0, peakv = 0, peakf = 0;
@ -291,7 +304,8 @@ void MeasureAntennaTuning(void) {
LEDsoff();
}
void MeasureAntennaTuningHf(void) {
void MeasureAntennaTuningHf(void)
{
uint16_t volt = 0; // in mV
// Let the FPGA drive the high-frequency antenna around 13.56 MHz.
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
@ -313,7 +327,8 @@ void MeasureAntennaTuningHf(void) {
DbprintfEx(FLAG_NOOPT, "\n[+] cancelled", 1);
}
void ReadMem(int addr) {
void ReadMem(int 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]);
@ -323,7 +338,8 @@ void ReadMem(int addr) {
extern struct version_information version_information;
/* 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__;
void SendVersion(void) {
void SendVersion(void)
{
char temp[USB_CMD_DATA_SIZE]; /* Limited data payload in USB packets */
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.
// 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(" Sending USB packets to client...");
@ -388,7 +405,8 @@ void printUSBSpeed(void) {
/**
* Prints runtime information about the PM3.
**/
void SendStatus(void) {
void SendStatus(void)
{
BigBuf_print_status();
Fpga_print_status();
#ifdef WITH_FLASH
@ -412,7 +430,8 @@ void SendStatus(void) {
}
// 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.");
@ -425,7 +444,8 @@ void StandAloneMode(void) {
}
// detection of which Standalone Modes is installed
// (iceman)
void printStandAloneModes(void) {
void printStandAloneModes(void)
{
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]);
void ListenReaderField(int limit) {
void ListenReaderField(int limit)
{
#define LF_ONLY 1
#define HF_ONLY 2
#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++) {
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] & 0x2) LED_A_ON(); 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();
if (LIGHT_SCHEME[i] & 0x1) LED_C_ON();
else LED_C_OFF();
if (LIGHT_SCHEME[i] & 0x2) LED_A_ON();
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;
}
}
@ -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;
//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:
switch (c->arg[0]) {
case 0: SetAdcMuxFor(GPIO_MUXSEL_LOPKD); break;
case 2: SetAdcMuxFor(GPIO_MUXSEL_HIPKD); break;
case 0:
SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
break;
case 2:
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
break;
#ifndef WITH_FPC
case 1: SetAdcMuxFor(GPIO_MUXSEL_LORAW); break;
case 3: SetAdcMuxFor(GPIO_MUXSEL_HIRAW); break;
case 1:
SetAdcMuxFor(GPIO_MUXSEL_LORAW);
break;
case 3:
SetAdcMuxFor(GPIO_MUXSEL_HIRAW);
break;
#endif
}
break;
@ -1475,7 +1509,8 @@ void UsbPacketReceived(uint8_t *packet, int len) {
}
}
void __attribute__((noreturn)) AppMain(void) {
void __attribute__((noreturn)) AppMain(void)
{
SpinDelay(100);
clear_trace();

View file

@ -1,23 +1,27 @@
#include "buzzer.h"
void Ring_BEE_ONCE(uint16_t music_note) {
void Ring_BEE_ONCE(uint16_t music_note)
{
BEE_ON();
SpinDelayUs(music_note);
BEE_OFF();
SpinDelayUs(music_note);
}
void ring_2_7khz(uint16_t count) {
void ring_2_7khz(uint16_t 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++)
Ring_BEE_ONCE(music_note);
SpinDelay(9);
}
void Ring_ALL(uint16_t count) {
void Ring_ALL(uint16_t count)
{
Ring_BEE_TIME(note_1, count);
Ring_BEE_TIME(note_2, count);
Ring_BEE_TIME(note_3, count);
@ -28,7 +32,8 @@ void Ring_ALL(uint16_t count) {
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_5, count);

View file

@ -202,7 +202,8 @@ const uint8_t shiftkeyinv_permtab[] = {
#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 byte, bit; /* counter for bit and byte */
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 & 0x0000FF00) << 8 |
(*a & 0x00FF0000) >> 8 |
@ -231,7 +233,8 @@ void changeendian32(uint32_t * a){
/******************************************************************************/
static inline
void shiftkey(uint8_t *key){
void shiftkey(uint8_t *key)
{
uint8_t k[7];
memcpy(k, key, 7);
permute((uint8_t *)shiftkey_permtab, k, key);
@ -239,7 +242,8 @@ void shiftkey(uint8_t *key){
/******************************************************************************/
static inline
void shiftkey_inv(uint8_t *key){
void shiftkey_inv(uint8_t *key)
{
uint8_t k[7];
memcpy(k, key, 7);
permute((uint8_t *)shiftkeyinv_permtab, k, key);
@ -248,7 +252,8 @@ void shiftkey_inv(uint8_t *key){
/******************************************************************************/
static inline
uint64_t splitin6bitwords(uint64_t a){
uint64_t splitin6bitwords(uint64_t a)
{
uint64_t ret = 0;
a &= 0x0000ffffffffffffLL;
permute((uint8_t *)splitin6bitword_permtab, (uint8_t *)&a, (uint8_t *)&ret);
@ -258,7 +263,8 @@ uint64_t splitin6bitwords(uint64_t a){
/******************************************************************************/
static inline
uint8_t substitute(uint8_t a, uint8_t * sbp){
uint8_t substitute(uint8_t a, uint8_t *sbp)
{
uint8_t x;
x = sbp[a >> 1];
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;
uint32_t t = 0, ret;
uint64_t data;
@ -305,7 +312,8 @@ typedef struct {
#define R (data.d.v32[1])
#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 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];
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_dec(out, out, (uint8_t *)key + 8);
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_enc(out, out, (uint8_t *)key + 8);
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;
@ -395,8 +407,7 @@ void tdes_dec(void* out, void* in, const uint8_t* key){
uint8_t *tin = (uint8_t *) in;
uint8_t *tout = (uint8_t *) out;
while( length > 0 )
{
while (length > 0) {
for (i = 0; i < 8; 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;
@ -421,8 +433,7 @@ void tdes_dec(void* out, void* in, const uint8_t* key){
uint8_t *tin = (uint8_t *) in;
uint8_t *tout = (uint8_t *) out;
while( length > 0 )
{
while (length > 0) {
memcpy(temp, tin, 8);
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);
// 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++) {
data[i] ^= ivect[i];
}
}
void cmac_generate_subkeys ( desfirekey_t key) {
void cmac_generate_subkeys(desfirekey_t key)
{
int kbs = key_block_size(key);
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;
}
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);
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);
}
size_t key_block_size (const desfirekey_t key) {
size_t key_block_size(const desfirekey_t key)
{
size_t block_size = 8;
switch (key->type) {
case T_DES:
@ -106,7 +110,8 @@ size_t key_block_size (const desfirekey_t 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;
switch (key->type) {
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_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))
return ((nbytes / block_size) + 1) * block_size;
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
*/
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);
}
/*
* 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;
if (!(communication_settings & NO_CRC)) {
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);
}
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 mac[4];
size_t edl;
@ -570,17 +579,14 @@ void mifare_cypher_single_block (desfirekey_t key, uint8_t *data, uint8_t *ivect
}
break;
case T_AES:
switch (operation)
{
case MCO_ENCYPHER:
{
switch (operation) {
case MCO_ENCYPHER: {
AesCtx ctx;
AesCtxIni(&ctx, ivect, key->data, KEY128, CBC);
AesEncrypt(&ctx, data, edata, sizeof(edata));
break;
}
case MCO_DECYPHER:
{
case MCO_DECYPHER: {
AesCtx ctx;
AesCtxIni(&ctx, ivect, key->data, KEY128, CBC);
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
* 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;
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)
{
// DES_set_key ((DES_cblock *)key->data, &(key->ks1));
// DES_set_key ((DES_cblock *)(key->data + 8), &(key->ks2));
// 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];
memcpy(data, value, 8);
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);
}
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) {
key->type = T_DES;
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];
memcpy(data, value, 16);
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);
}
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) {
key->type = T_3DES;
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];
memcpy(data, value, 24);
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);
}
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) {
key->type = T_3K3DES;
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);
}
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) {
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;
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];

View file

@ -105,8 +105,7 @@ static char iso_type = 0;
//-----------------------------------------------------------------------------
int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response)
{
switch(iso_type)
{
switch (iso_type) {
case 'a':
return iso14_apdu(apdu, (uint16_t) length, false, response, NULL);
break;
@ -166,8 +165,7 @@ size_t EPA_Parse_CardAccess(uint8_t *data,
&& memcmp(data + index + 2,
oid_pace_start,
sizeof(oid_pace_start)) == 0 // content matches
&& pace_info != NULL)
{
&& pace_info != NULL) {
// first, clear the pace_info struct
memset(pace_info, 0, sizeof(pace_version_info_t));
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) {
pace_info->version = data[index + 2];
index += 3;
}
else {
} else {
return index;
}
// 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];
index += 3;
}
}
else {
} else {
// skip this OID
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
else if (data[index + 1] == 0) {
return index;
}
else {
} else {
// skip this part
// TODO: This needs to be extended to support long tags
// 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);
if (rapdu_length < 6
|| response_apdu[rapdu_length - 4] != 0x90
|| response_apdu[rapdu_length - 3] != 0x00)
{
|| response_apdu[rapdu_length - 3] != 0x00) {
DbpString("Failed to select EF.CardAccess!");
return -1;
}
@ -241,8 +235,7 @@ int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length)
response_apdu);
if (rapdu_length <= 6
|| response_apdu[rapdu_length - 4] != 0x90
|| response_apdu[rapdu_length - 3] != 0x00)
{
|| response_apdu[rapdu_length - 3] != 0x00) {
Dbprintf("Failed to read EF.CardAccess!");
return -1;
}
@ -324,8 +317,7 @@ void EPA_PACE_Collect_Nonce(UsbCommand *c)
uint8_t requested_size = (uint8_t)c->arg[0];
func_return = EPA_PACE_Get_Nonce(requested_size, nonce);
// check if the command succeeded
if (func_return < 0)
{
if (func_return < 0) {
EPA_PACE_Collect_Nonce_Abort(4, func_return);
return;
}
@ -364,21 +356,18 @@ int EPA_PACE_Get_Nonce(uint8_t requested_length, uint8_t *nonce)
// check if the command succeeded
if (send_return < 6
|| response_apdu[send_return - 4] != 0x90
|| response_apdu[send_return - 3] != 0x00)
{
|| response_apdu[send_return - 3] != 0x00) {
return -1;
}
// if there is no nonce in the RAPDU, return here
if (send_return < 10)
{
if (send_return < 10) {
// no error
return 0;
}
// get the actual length of the nonce
uint8_t nonce_length = response_apdu[5];
if (nonce_length > send_return - 10)
{
if (nonce_length > send_return - 10) {
nonce_length = send_return - 10;
}
// 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
if (send_return != 6
|| response_apdu[send_return - 4] != 0x90
|| response_apdu[send_return - 3] != 0x00)
{
|| response_apdu[send_return - 3] != 0x00) {
return 1;
}
return 0;
@ -452,8 +440,7 @@ void EPA_PACE_Replay(UsbCommand *c)
// if an APDU has been passed, save it
if (c->arg[0] != 0) {
// 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);
}
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
&& (func_return < 6
|| response_apdu[func_return - 4] != 0x90
|| response_apdu[func_return - 3] != 0x00))
{
|| response_apdu[func_return - 3] != 0x00)) {
EPA_Finish();
cmd_send(CMD_ACK, 3 + i, func_return, 0, timings, 20);
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);
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;
}
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;
}
@ -77,19 +79,22 @@ static struct {
# define SYNC_16BIT 0xB24D
#endif
static void FelicaFrameReset() {
static void FelicaFrameReset()
{
FelicaFrame.state = STATE_UNSYNCD;
FelicaFrame.posCnt = 0;
FelicaFrame.crc_ok = false;
FelicaFrame.byte_offset = 0;
}
static void FelicaFrameinit(uint8_t *data) {
static void FelicaFrameinit(uint8_t *data)
{
FelicaFrame.framebytes = data;
FelicaFrameReset();
}
//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;
for (j = 0; j < FelicaFrame.byte_offset; j++) {
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) {
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
@ -190,7 +196,8 @@ static void Process18092Byte(uint8_t bt) {
* Currently does NOT do any collision handling.
* 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
// 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,
// 8-byte IDm, number of blocks, blocks numbers
// 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)
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);
}
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;
@ -380,7 +389,8 @@ static void TransmitFor18092_AsReader(uint8_t * frame, int len, uint32_t *timing
// Wait for tag reply
// stop when button is pressed
// or return TRUE when command is captured
bool WaitForFelicaReply(uint16_t maxbytes) {
bool WaitForFelicaReply(uint16_t maxbytes)
{
uint32_t c = 0;
@ -430,13 +440,15 @@ bool WaitForFelicaReply(uint16_t maxbytes) {
// Set up FeliCa communication (similar to iso14443a_setup)
// 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();
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// allocate command receive buffer
BigBuf_free(); BigBuf_Clear_ext(false);
BigBuf_free();
BigBuf_Clear_ext(false);
// Initialize Demod and Uart structs
//DemodInit(BigBuf_malloc(MAX_FRAME_SIZE));
@ -473,7 +485,8 @@ static void iso18092_setup(uint8_t fpga_minor_mode) {
// arg0 FeliCa flags
// arg1 len of commandbytes
// d.asBytes command bytes to send
void felica_sendraw(UsbCommand *c) {
void felica_sendraw(UsbCommand *c)
{
if (MF_DBGLEVEL > 3) Dbprintf("FeliCa_sendraw Enter");
@ -539,7 +552,8 @@ OUT:
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;
@ -610,7 +624,8 @@ void felica_sniff(uint32_t samplesToSkip, uint32_t triggersToSkip) {
#define R_READBLK_LEN 0x21
//simulate NFC Tag3 card - for now only poll response works
// 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;
uint8_t *curresp = 0;
@ -716,7 +731,8 @@ void felica_sim_lite(uint64_t nfcid) {
DbpString("Felica Lite-S sim end");
}
void felica_dump_lite_s() {
void felica_dump_lite_s()
{
uint8_t ndef[8];
uint8_t poll[10] = { 0xb2, 0x4d, 0x06, FELICA_POLL_REQ, 0xff, 0xff, 0x00, 0x00, 0x09, 0x21};

View file

@ -13,13 +13,15 @@
uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD;
void FlashmemSetSpiBaudrate(uint32_t baudrate){
void FlashmemSetSpiBaudrate(uint32_t baudrate)
{
FLASHMEM_SPIBAUDRATE = baudrate;
Dbprintf("Spi Baudrate : %dMhz", FLASHMEM_SPIBAUDRATE / 1000000);
}
// initialize
bool FlashInit() {
bool FlashInit()
{
FlashSetup(FLASHMEM_SPIBAUDRATE);
StartTicks();
@ -32,7 +34,8 @@ bool FlashInit() {
return true;
}
void FlashSetup(uint32_t baudrate){
void FlashSetup(uint32_t baudrate)
{
//WDT_DISABLE
AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
@ -127,7 +130,8 @@ void FlashSetup(uint32_t baudrate){
if (AT91C_BASE_SPI->SPI_RDR == 0) {};
}
void FlashStop(void) {
void FlashStop(void)
{
//Bof
//* Reset all the Chip Select register
AT91C_BASE_SPI->SPI_CSR[0] = 0;
@ -150,7 +154,8 @@ void FlashStop(void) {
}
// send one byte over SPI
uint16_t FlashSendByte(uint32_t data) {
uint16_t FlashSendByte(uint32_t data)
{
// wait until SPI is ready for transfer
//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
uint16_t FlashSendLastByte(uint32_t data) {
uint16_t FlashSendLastByte(uint32_t data)
{
return FlashSendByte(data | AT91C_SPI_LASTXFER);
}
// read state register 1
uint8_t Flash_ReadStat1(void) {
uint8_t Flash_ReadStat1(void)
{
FlashSendByte(READSTAT1);
return FlashSendLastByte(0xFF);
}
@ -187,16 +194,13 @@ bool Flash_CheckBusy(uint32_t timeout)
if (MF_DBGLEVEL > 3) Dbprintf("Checkbusy in...");
do
{
if (!(Flash_ReadStat1() & BUSY))
{
do {
if (!(Flash_ReadStat1() & BUSY)) {
return false;
}
} while ((GetCountUS() - _time) < timeout);
if (timeout <= (GetCountUS() - _time))
{
if (timeout <= (GetCountUS() - _time)) {
return true;
}
@ -204,7 +208,8 @@ bool Flash_CheckBusy(uint32_t timeout)
}
// read ID out
uint8_t Flash_ReadID(void) {
uint8_t Flash_ReadID(void)
{
if (Flash_CheckBusy(BUSY_TIMEOUT)) return 0;
@ -226,7 +231,8 @@ uint8_t Flash_ReadID(void) {
}
// read unique id for chip.
void Flash_UniqueID(uint8_t *uid) {
void Flash_UniqueID(uint8_t *uid)
{
if (Flash_CheckBusy(BUSY_TIMEOUT)) return;
@ -247,7 +253,8 @@ void Flash_UniqueID(uint8_t *uid) {
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;
@ -272,14 +279,16 @@ uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
return len;
}
void Flash_TransferAdresse(uint32_t address){
void Flash_TransferAdresse(uint32_t address)
{
FlashSendByte((address >> 16) & 0xFF);
FlashSendByte((address >> 8) & 0xFF);
FlashSendByte((address >> 0) & 0xFF);
}
/* 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
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.
// 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
if (!len)
@ -351,7 +361,8 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
// length should never be zero
// Max 256 bytes write
// 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)
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
//
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;
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 (MF_DBGLEVEL > 3) Dbprintf("Flash_WriteData init fail");
return false;
@ -420,13 +433,16 @@ bool Flash_WipeMemoryPage(uint8_t page) {
Flash_ReadStat1();
// 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();
return true;
}
// Wipes flash memory completely, fills with 0xFF
bool Flash_WipeMemory() {
bool Flash_WipeMemory()
{
if (!FlashInit()) {
if (MF_DBGLEVEL > 3) Dbprintf("Flash_WriteData init fail");
return false;
@ -435,24 +451,34 @@ bool Flash_WipeMemory() {
// Each block is 64Kb. Four blocks
// one block erase takes 1s ( 1000ms )
Flash_WriteEnable(); Flash_Erase64k(0); 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);
Flash_WriteEnable();
Flash_Erase64k(0);
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();
return true;
}
// enable the flash write
void Flash_WriteEnable() {
void Flash_WriteEnable()
{
FlashSendLastByte(WRITEENABLE);
if (MF_DBGLEVEL > 3) Dbprintf("Flash Write enabled");
}
// erase 4K at one time
// 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;
@ -487,7 +513,8 @@ bool Flash_Erase32k(uint32_t address) {
// 0x01 00 00 -- 0x 01 FF FF == block 1
// 0x02 00 00 -- 0x 02 FF FF == block 2
// 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;
@ -499,11 +526,13 @@ bool Flash_Erase64k(uint8_t block) {
}
// Erase chip
void Flash_EraseChip(void) {
void Flash_EraseChip(void)
{
FlashSendLastByte(CHIPERASE);
}
void Flashmem_print_status(void) {
void Flashmem_print_status(void)
{
DbpString("Flash memory");
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
// 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
AT91C_BASE_SPI->SPI_CSR[0] = 0;
AT91C_BASE_SPI->SPI_CSR[1] = 0;
@ -45,7 +46,8 @@ static void DisableSpi(void) {
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIDIS;
}
void SetupSpi(int mode) {
void SetupSpi(int mode)
{
// PA1 -> SPI_NCS3 chip select (MEM)
// PA10 -> SPI_NCS2 chip select (LCD)
// 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
// 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.
AT91C_BASE_PIOA->PIO_ASR =
GPIO_SSC_FRAME |
@ -156,7 +159,8 @@ void FpgaSetupSsc(void) {
// ourselves, not to another buffer). The stuff to manipulate those buffers
// 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;
FpgaDisableSscDma();
@ -172,7 +176,8 @@ bool FpgaSetupSscDma(uint8_t *buf, int len) {
// Uncompress (inflate) the FPGA data. Returns one decompressed byte with
// 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
compressed_fpga_stream->next_out = output_buffer;
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:
// 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)) {
// skip undesired data belonging to other bitstream_versions
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);
}
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);
}
// free eventually allocated BigBuf memory
static void fpga_inflate_free(voidpf opaque, voidpf address) {
BigBuf_free(); BigBuf_Clear_ext(false);
static void fpga_inflate_free(voidpf opaque, voidpf address)
{
BigBuf_free();
BigBuf_Clear_ext(false);
}
//----------------------------------------------------------------------------
// 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];
uncompressed_bytes_cnt = 0;
@ -242,7 +252,8 @@ static bool reset_fpga_stream(int bitstream_version, z_streamp compressed_fpga_s
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); }
SEND_BIT(7);
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
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;
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
* 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;
#define MAX_FPGA_BIT_STREAM_HEADER_SEARCH 100 // maximum number of bytes to search for the requested section
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
// 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
if (downloaded_bitstream == bitstream_version)
@ -398,7 +412,8 @@ void FpgaDownloadAndGo(int bitstream_version) {
bool verbose = (MF_DBGLEVEL > 3);
// 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))
return;
@ -415,7 +430,8 @@ void FpgaDownloadAndGo(int bitstream_version) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
// 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
// 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);
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
@ -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
// 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);
}
@ -443,7 +461,8 @@ void FpgaWriteConfWord(uint8_t v) {
// closable, but should only close one at a time. Not an FPGA thing, but
// 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 =
GPIO_MUXSEL_HIPKD |
GPIO_MUXSEL_LOPKD |
@ -466,12 +485,14 @@ void SetAdcMuxFor(uint32_t whichGpio) {
HIGH(whichGpio);
}
void Fpga_print_status(void) {
void Fpga_print_status(void)
{
Dbprintf("Currently loaded FPGA image");
Dbprintf(" mode....................%s", fpga_version_information[downloaded_bitstream - 1]);
}
int FpgaGetCurrent(void) {
int FpgaGetCurrent(void)
{
return downloaded_bitstream;
}
@ -479,7 +500,8 @@ int FpgaGetCurrent(void) {
// log message
// if HF, Disable SSC DMA
// turn off trace and leds off.
void switch_off(void) {
void switch_off(void)
{
if (MF_DBGLEVEL > 3) Dbprintf("switch_off");
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
if (downloaded_bitstream == FPGA_BITSTREAM_HF)

View file

@ -26,7 +26,8 @@ static void RAMFUNC optimizedSnoop(void)
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);
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;
u64 x = ((key & 0xFFFF) << 32) + serial;
for (i = 0; i < 32; i++)
{
for (i = 0; i < 32; i++) {
x >>= 1;
x += (u64)(_f20(x) ^ (((IV >> i) ^ (key >> (i + 16))) & 1)) << 47;
}
@ -166,13 +165,15 @@ static u32 _hitag2_byte (u64 * x)
return c;
}
static int hitag2_reset(void) {
static int hitag2_reset(void)
{
tag.state = TAG_STATE_RESET;
tag.crypto_active = 0;
return 0;
}
static int hitag2_init(void) {
static int hitag2_init(void)
{
hitag2_reset();
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
static void hitag_send_bit(int bit) {
static void hitag_send_bit(int bit)
{
LED_A_ON();
// Reset clock for the next bit
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();
// Reset clock for the next bit
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;
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
*txlen = 0;
@ -478,7 +482,8 @@ static bool hitag2_password(uint8_t* rx, const size_t rxlen, uint8_t* tx, size_t
}
*txlen = 5;
memcpy(tx, "\xc0", nbytes(*txlen));
} break;
}
break;
// Received UID, tag password
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[1] = ((blocknr ^ 7) << 6);
}
} break;
}
break;
// Unexpected response
default: {
Dbprintf("Uknown frame length: %d", rxlen);
return false;
} break;
}
break;
}
return true;
}
@ -560,7 +567,8 @@ static bool hitag2_write_page(uint8_t* rx, const size_t rxlen, uint8_t* tx, size
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
*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);
}
}
} break;
}
break;
// Unexpected response
default: {
Dbprintf("Uknown frame length: %d", rxlen);
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
*txlen = 0;
@ -682,7 +693,8 @@ static bool hitag2_authenticate(uint8_t* rx, const size_t rxlen, uint8_t* tx, si
}
*txlen = 5;
memcpy(tx, "\xc0", nbytes(*txlen));
} break;
}
break;
// Received UID, crypto tag answer
case 32: {
@ -694,20 +706,23 @@ static bool hitag2_authenticate(uint8_t* rx, const size_t rxlen, uint8_t* tx, si
DbpString("Authentication succesful!");
return true;
}
} break;
}
break;
// Unexpected response
default: {
Dbprintf("Uknown frame length: %d", rxlen);
return false;
} break;
}
break;
}
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
*txlen = 0;
@ -735,7 +750,8 @@ static bool hitag2_test_auth_attempts(uint8_t* rx, const size_t rxlen, uint8_t*
}
*txlen = 5;
memcpy(tx, "\xc0", nbytes(*txlen));
} break;
}
break;
// Received UID, crypto tag answer, or read block response
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;
memcpy(NrAr, auth_table + auth_table_pos, 8);
}
} break;
}
break;
default: {
Dbprintf("Uknown frame length: %d", rxlen);
return false;
} break;
}
break;
}
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
*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
*txlen = 5;
memcpy(tx, "\xC0", nbytes(*txlen));
} break;
}
break;
// Received UID
case 32: {
// 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;
return false;
}
} break;
}
break;
// Unexpected response
default: {
Dbprintf("Uknown frame length: %d", rxlen);
return false;
} break;
}
break;
}
return true;
}
void SnoopHitag(uint32_t type) {
void SnoopHitag(uint32_t type)
{
int frame_count;
int response;
int overflow;
@ -815,7 +838,8 @@ void SnoopHitag(uint32_t type) {
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
// 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
clear_trace();
@ -1017,7 +1041,8 @@ void SnoopHitag(uint32_t type) {
// 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 response;
int overflow;
@ -1031,7 +1056,8 @@ void SimulateHitagTag(bool tag_mem_supplied, uint8_t* data) {
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
// 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
clear_trace();
@ -1207,7 +1233,8 @@ void SimulateHitagTag(bool tag_mem_supplied, uint8_t* data) {
set_tracing(false);
}
void ReaderHitag(hitag_function htf, hitag_data* htd) {
void ReaderHitag(hitag_function htf, hitag_data *htd)
{
int frame_count = 0;
int response = 0;
uint8_t rx[HITAG_FRAME_LEN];
@ -1242,7 +1269,8 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
bQuitTraceFull = false;
bQuiet = false;
bPwd = false;
} break;
}
break;
case RHT2F_AUTHENTICATE: {
DbpString("Authenticating using nr,ar pair:");
@ -1252,7 +1280,8 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
bCrypto = false;
bAuthenticating = false;
bQuitTraceFull = true;
} break;
}
break;
case RHT2F_CRYPTO: {
DbpString("Authenticating using key:");
@ -1263,7 +1292,8 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
bCrypto = false;
bAuthenticating = false;
bQuitTraceFull = true;
} break;
}
break;
case RHT2F_TEST_AUTH_ATTEMPTS: {
Dbprintf("Testing %d authentication attempts", (auth_table_len / 8));
@ -1272,19 +1302,22 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
bQuitTraceFull = false;
bQuiet = false;
bCrypto = false;
} break;
}
break;
case RHT2F_UID_ONLY: {
blocknr = 0;
bQuiet = false;
bCrypto = false;
bAuthenticating = false;
bQuitTraceFull = true;
} break;
}
break;
default: {
Dbprintf("Error, unknown function: %d", htf);
set_tracing(false);
return;
} break;
}
break;
}
LED_D_ON();
@ -1373,28 +1406,34 @@ void ReaderHitag(hitag_function htf, hitag_data* htd) {
switch (htf) {
case RHT2F_PASSWORD: {
bStop = !hitag2_password(rx, rxlen, tx, &txlen);
} break;
}
break;
case RHT2F_AUTHENTICATE: {
bStop = !hitag2_authenticate(rx, rxlen, tx, &txlen);
} break;
}
break;
case RHT2F_CRYPTO: {
bStop = !hitag2_crypto(rx, rxlen, tx, &txlen, false);
} break;
}
break;
case RHT2F_TEST_AUTH_ATTEMPTS: {
bStop = !hitag2_test_auth_attempts(rx, rxlen, tx, &txlen);
} break;
}
break;
case RHT2F_UID_ONLY: {
bStop = !hitag2_read_uid(rx, rxlen, tx, &txlen);
attempt_count++; //attempt 3 times to get uid then quit
if (!bStop && attempt_count == 3)
bStop = true;
} break;
}
break;
default: {
Dbprintf("Error, unknown function: %d", htf);
set_tracing(false);
LED_D_OFF();
return;
} break;
}
break;
}
// 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);
}
void WriterHitag(hitag_function htf, hitag_data* htd, int page) {
void WriterHitag(hitag_function htf, hitag_data *htd, int page)
{
int frame_count;
int response;
uint8_t rx[HITAG_FRAME_LEN];
@ -1548,11 +1588,13 @@ void WriterHitag(hitag_function htf, hitag_data* htd, int page) {
bAuthenticating = false;
bQuitTraceFull = true;
writestate = WRITE_STATE_START;
} break;
}
break;
default: {
Dbprintf("Error, unknown function: %d", htf);
return;
} break;
}
break;
}
LED_D_ON();
@ -1644,11 +1686,13 @@ void WriterHitag(hitag_function htf, hitag_data* htd, int page) {
switch (htf) {
case WHT2F_CRYPTO: {
bStop = !hitag2_crypto(rx, rxlen, tx, &txlen, true);
} break;
}
break;
default: {
Dbprintf("Error, unknown function: %d", htf);
return;
} break;
}
break;
}
// 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
if ((rxlen == 0) && (writestate == WRITE_STATE_PROG))
{
if ((rxlen == 0) && (writestate == WRITE_STATE_PROG)) {
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG;
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 uf20bs u32
static u32 f20(const u64 x) {
static u32 f20(const u64 x)
{
u32 i5;
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;
}
static u64 hitag2_round(u64 *state) {
static u64 hitag2_round(u64 *state)
{
u64 x = *state;
x = (x >> 1)
@ -88,7 +90,8 @@ static u64 hitag2_round(u64 *state) {
*state = 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;
u64 x = ((key & 0xFFFF) << 32) + serial;
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;
}
static u32 hitag2_byte(u64 *x) {
static u32 hitag2_byte(u64 *x)
{
u32 i, c;
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
* 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
do {
if (*crc & 0x80) // if (MSB-CRC == 1)
{
if (*crc & 0x80) { // if (MSB-CRC == 1)
*crc <<= 1; // CRC = CRC Bit-shift left
*crc ^= CRC_POLYNOM; // CRC = CRC (exor) CRC_POLYNOM
} else {
@ -157,7 +161,8 @@ void calc_crc(unsigned char * crc, unsigned char data, unsigned char Bitcount) {
} while (--Bitcount);
}
static void hitag_send_bit(int bit) {
static void hitag_send_bit(int bit)
{
LED_A_ON();
// Reset clock for the next bit
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
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);
}
static void hitag_reader_send_bit(int bit) {
static void hitag_reader_send_bit(int bit)
{
//Dbprintf("BIT: %d",bit);
LED_A_ON();
// Reset clock for the next bit
@ -330,7 +337,8 @@ static void hitag_reader_send_bit(int bit) {
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
for (size_t i = 0; i < frame_len; i++) {
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
*/
static int check_select(byte_t* rx, uint32_t uid) {
static int check_select(byte_t *rx, uint32_t uid)
{
unsigned char resp[48];
int i;
uint32_t ans = 0x0;
@ -373,7 +382,8 @@ static int check_select(byte_t* rx, uint32_t uid) {
* handles all commands from a reader
*/
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 page;
int i;
@ -565,8 +575,7 @@ static void hitagS_handle_reader_command(byte_t* rx, const size_t rxlen,
break;
case 20: {
//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
page = ((rx[0] & 0x0f) * 16) + ((rx[1] & 0xf0) / 16);
*txlen = 32;
@ -608,8 +617,7 @@ static void hitagS_handle_reader_command(byte_t* rx, const size_t rxlen,
sof_bits = 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);
*txlen = 32 * 4;
//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;
*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);
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;
}
} 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);
switch (tag.mode) {
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
*/
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];
int response_bit[200];
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
*/
void SimulateHitagSTag(bool tag_mem_supplied, byte_t* data) {
void SimulateHitagSTag(bool tag_mem_supplied, byte_t *data)
{
int frame_count;
int response;
int overflow;
@ -951,7 +959,8 @@ void SimulateHitagSTag(bool tag_mem_supplied, byte_t* data) {
byte_t *tx = txbuf;
size_t txlen = 0;
// 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
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.
* 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 frame_count;
int response_bit[200];
@ -1198,17 +1208,20 @@ void ReadHitagS(hitag_function htf, hitag_data* htd) {
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 |
((uint64_t)NrAr_[2]) << 40 | ((uint64_t)NrAr_[1]) << 48 | ((uint64_t)NrAr_[0]) << 56;
} break;
}
break;
case 02: { //RHTS_KEY
DbpString("Authenticating using key:");
memcpy(key_, htd->crypto.key, 6);
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;
} break;
}
break;
default: {
Dbprintf("Error , unknown function: %d", htf);
return;
} break;
}
break;
}
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.
* 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 response;
byte_t rx[HITAG_FRAME_LEN];
@ -1537,18 +1551,21 @@ void WritePageHitagS(hitag_function htf, hitag_data* htd,int page_) {
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 |
((uint64_t)NrAr_[2]) << 40 | ((uint64_t)NrAr_[1]) << 48 | ((uint64_t)NrAr_[0]) << 56;
} break;
}
break;
case 04: { //WHTS_KEY
memcpy(data, htd->crypto.data, 4);
DbpString("Authenticating using key:");
memcpy(key_, htd->crypto.key, 6);
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;
} break;
}
break;
default: {
Dbprintf("Error , unknown function: %d", htf);
return;
} break;
}
break;
}
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
* 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;
byte_t uid_byte[4];
int frame_count;

View file

@ -141,16 +141,19 @@ typedef struct {
} tUart;
static tUart Uart;
static void uart_reset(void){
static void uart_reset(void)
{
Uart.frame_done = false;
Uart.synced = false;
Uart.frame = false;
}
static void uart_init(uint8_t *data){
static void uart_init(uint8_t *data)
{
Uart.buf = data;
uart_reset();
}
static void uart_bit(uint8_t bit) {
static void uart_bit(uint8_t bit)
{
static uint8_t buf = 0xff;
static uint8_t n_buf;
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 int window;
static int drop_next = 0;
@ -500,7 +504,8 @@ static RAMFUNC int OutOfNDecoding(int bit) {
// Manchester
//=============================================================================
static tDemod Demod;
static void DemodReset() {
static void DemodReset()
{
Demod.bitCount = 0;
Demod.posCount = 0;
Demod.syncBit = 0;
@ -514,7 +519,8 @@ static void DemodReset() {
Demod.sub = SUB_NONE;
Demod.state = DEMOD_UNSYNCD;
}
static void DemodInit(uint8_t *data) {
static void DemodInit(uint8_t *data)
{
Demod.output = data;
DemodReset();
}
@ -540,7 +546,8 @@ Recorded Activity (TraceLen = 162 bytes)
2720 | 2720 | Rdr |0c | | IDENTIFY
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.len++;
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.
*/
static RAMFUNC int ManchesterDecoding_iclass( uint32_t v) {
static RAMFUNC int ManchesterDecoding_iclass(uint32_t v)
{
int bit;
int modulation;
int error = 0;
@ -629,10 +637,18 @@ static RAMFUNC int ManchesterDecoding_iclass( uint32_t v) {
if (Demod.posCount) {
switch (Demod.syncBit) {
case 0x08: Demod.samples = 3; break;
case 0x04: Demod.samples = 2; break;
case 0x02: Demod.samples = 1; break;
case 0x01: Demod.samples = 0; break;
case 0x08:
Demod.samples = 3;
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!!!
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
// 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");
LEDsoff();
@ -805,7 +822,8 @@ static void iclass_setup_sniff(void){
// Set up the synchronous serial port
FpgaSetupSsc();
BigBuf_free(); BigBuf_Clear_ext(false);
BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace();
set_tracing(true);
@ -842,7 +860,8 @@ static void iclass_setup_sniff(void){
// near the reader.
//-----------------------------------------------------------------------------
// turn off afterwards
void RAMFUNC SniffIClass(void) {
void RAMFUNC SniffIClass(void)
{
//int datalen = 0;
uint32_t previous_data = 0;
@ -964,7 +983,8 @@ void RAMFUNC SniffIClass(void) {
switch_off();
}
void rotateCSN(uint8_t* originalCSN, uint8_t* rotatedCSN) {
void rotateCSN(uint8_t *originalCSN, uint8_t *rotatedCSN)
{
int i;
for (i = 0; i < 8; i++)
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
// 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
// only, since we are receiving, not transmitting).
// Signal field is off with the appropriate LED
@ -1008,7 +1029,8 @@ static bool GetIClassCommandFromReader(uint8_t *received, int *len, int maxLen)
return false;
}
static uint8_t encode4Bits(const uint8_t b) {
static uint8_t encode4Bits(const uint8_t b)
{
// OTA, the least significant bits first
// Manchester encoding added
// The columns are
@ -1020,29 +1042,46 @@ static uint8_t encode4Bits(const uint8_t b) {
uint8_t c = b & 0xF;
switch (c) {
// 1 2 3 4
case 15: return 0x55; // 1111 -> 1111 -> 01010101 -> 0x55
case 14: return 0x95; // 1110 -> 0111 -> 10010101 -> 0x95
case 13: return 0x65; // 1101 -> 1011 -> 01100101 -> 0x65
case 12: return 0xa5; // 1100 -> 0011 -> 10100101 -> 0xa5
case 11: return 0x59; // 1011 -> 1101 -> 01011001 -> 0x59
case 10: return 0x99; // 1010 -> 0101 -> 10011001 -> 0x99
case 9: return 0x69; // 1001 -> 1001 -> 01101001 -> 0x69
case 8: 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
case 15:
return 0x55; // 1111 -> 1111 -> 01010101 -> 0x55
case 14:
return 0x95; // 1110 -> 0111 -> 10010101 -> 0x95
case 13:
return 0x65; // 1101 -> 1011 -> 01100101 -> 0x65
case 12:
return 0xa5; // 1100 -> 0011 -> 10100101 -> 0xa5
case 11:
return 0x59; // 1011 -> 1101 -> 01011001 -> 0x59
case 10:
return 0x99; // 1010 -> 0101 -> 10011001 -> 0x99
case 9:
return 0x69; // 1001 -> 1001 -> 01101001 -> 0x69
case 8:
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
//-----------------------------------------------------------------------------
static void CodeIClassTagAnswer(const uint8_t *cmd, int len) {
static void CodeIClassTagAnswer(const uint8_t *cmd, int len)
{
/*
* SOF comprises 3 parts;
* * An unmodulated time of 56.64 us
@ -1096,7 +1135,8 @@ static void CodeIClassTagAnswer(const uint8_t *cmd, int len) {
}
// Only SOF
static void CodeIClassTagSOF() {
static void CodeIClassTagSOF()
{
//So far a dummy implementation, not used
//int lastProxToAirDuration =0;
@ -1122,7 +1162,8 @@ static void CodeIClassTagSOF() {
* @param datain
*/
// 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");
@ -1232,7 +1273,8 @@ out:
* @param csn - csn to use
* @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
BigBuf_free_keep_EM();
@ -1327,27 +1369,33 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
// First card answer: SOF
CodeIClassTagSOF();
memcpy(resp_sof, ToSend, ToSendMax); resp_sof_Len = ToSendMax;
memcpy(resp_sof, ToSend, ToSendMax);
resp_sof_Len = ToSendMax;
// Anticollision CSN
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
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
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
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
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
//First the 'trace'-data, not encoded for FPGA
@ -1373,7 +1421,8 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
WDT_HIT();
//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;
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
// 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_size = sizeof(sof_data);
// 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
if (len == 1) {
// 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_size = sizeof(anticoll_data);
goto send;
@ -1406,17 +1457,20 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
// block0,1,2,5 is always readable.
switch (receivedCmd[1]) {
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_size = sizeof(csn_data);
break;
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_size = sizeof(conf_data);
break;
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_size = sizeof(card_challenge_data);
// set epurse of sim2,4 attack
@ -1425,11 +1479,13 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
}
break;
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_size = sizeof(aia_data);
break;
default: break;
default:
break;
}
goto send;
}
@ -1437,20 +1493,23 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
} else if (receivedCmd[0] == ICLASS_CMD_SELECT) { // 0x81
// Reader selects anticollission 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_size = sizeof(csn_data);
goto send;
} else if (receivedCmd[0] == ICLASS_CMD_READCHECK_KD) { // 0x88
// 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_size = sizeof(card_challenge_data);
LED_B_ON();
goto send;
} else if (receivedCmd[0] == ICLASS_CMD_READCHECK_KC) { // 0x18
// 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_size = sizeof(card_challenge_data);
LED_B_ON();
@ -1470,7 +1529,8 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
} else {
// Not fullsim, we don't respond
// 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_size = 0;
@ -1494,7 +1554,8 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf) {
goto send;
} else if (receivedCmd[0] == ICLASS_CMD_HALT && len == 1) {
// 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_size = 0;
goto send;
@ -1580,7 +1641,8 @@ send:
* @param respLen
* @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;
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
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
@ -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[].
//-----------------------------------------------------------------------------
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;
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
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
//-----------------------------------------------------------------------------
void CodeIClassCommand(const uint8_t* cmd, int len) {
void CodeIClassCommand(const uint8_t *cmd, int len)
{
int i, j, k;
uint8_t b;
@ -1709,7 +1775,8 @@ void CodeIClassCommand(const uint8_t* cmd, int len) {
ToSendMax++;
}
void ReaderTransmitIClass_ext(uint8_t* frame, int len, int wait) {
void ReaderTransmitIClass_ext(uint8_t *frame, int len, int wait)
{
int samples = 0;
@ -1725,7 +1792,8 @@ void ReaderTransmitIClass_ext(uint8_t* frame, int len, int wait) {
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);
}
@ -1734,7 +1802,8 @@ void ReaderTransmitIClass(uint8_t* frame, int len) {
// If a response is captured return TRUE
// 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
// maxLen is not used...
@ -1785,7 +1854,8 @@ static int GetIClassAnswer(uint8_t* receivedResponse, int maxLen, int *samples,
return false;
}
int ReaderReceiveIClass(uint8_t* receivedAnswer) {
int ReaderReceiveIClass(uint8_t *receivedAnswer)
{
int samples = 0;
if (!GetIClassAnswer(receivedAnswer, 0, &samples, NULL))
@ -1801,7 +1871,8 @@ int ReaderReceiveIClass(uint8_t* receivedAnswer) {
return Demod.len;
}
void setupIclassReader() {
void setupIclassReader()
{
LEDsoff();
@ -1828,7 +1899,8 @@ void setupIclassReader() {
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;
while (retries-- > 0) {
@ -1857,7 +1929,8 @@ bool sendCmdGetResponseWithRetries(uint8_t* command, size_t cmdsize, uint8_t* re
* 1 = Got CSN
* 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...
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++;
return read_status;
}
uint8_t handshakeIclassTag(uint8_t *card_data){
uint8_t handshakeIclassTag(uint8_t *card_data)
{
return handshakeIclassTag_ext(card_data, false);
}
// Reader iClass Anticollission
// turn off afterwards
void ReaderIClass(uint8_t arg0) {
void ReaderIClass(uint8_t arg0)
{
uint8_t card_data[6 * 8] = {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
void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC)
{
uint8_t cardsize = 0;
uint8_t mem = 0;
@ -2181,7 +2257,8 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
// not used. ?!? ( CMD_ICLASS_READCHECK)
// 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 resp[] = {0, 0, 0, 0, 0, 0, 0, 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)
// 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 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
* 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 lastChunk = ((arg0 >> 8) & 0xFF);
bool use_credit_key = ((arg0 >> 16) & 0xFF);
@ -2302,7 +2381,8 @@ out:
// Tries to read block.
// 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 cmd[] = {ICLASS_CMD_READ_OR_IDENTIFY, blockNo, 0x00, 0x00};
AddCrc(cmd + 1, 1);
@ -2314,7 +2394,8 @@ bool iClass_ReadBlock(uint8_t blockNo, uint8_t *data, uint8_t len) {
// turn off afterwards
// 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};
bool isOK = iClass_ReadBlock(blockno, 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
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};
bool isOK = false;
uint8_t blkCnt = 0;
@ -2356,7 +2438,8 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) {
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 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
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);
cmd_send(CMD_ACK, isOK, 0, 0, 0, 0);
switch_off();
}
// 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 total_block = (endblock - startblock) + 1;
for (i = 0; i < total_block; i++) {

View file

@ -120,22 +120,26 @@ static uint32_t LastProxToAirDuration;
#define SEC_Y 0x00
#define SEC_Z 0xc0
void iso14a_set_trigger(bool enable) {
void iso14a_set_trigger(bool 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;
}
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;
}
//-----------------------------------------------------------------------------
// 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 paritybyte_cnt = 0;
uint8_t parityBits = 0;
@ -189,11 +193,13 @@ const bool Mod_Miller_LUT[] = {
#define IsMillerModulationNibble1(b) (Mod_Miller_LUT[(b & 0x000000F0) >> 4])
#define IsMillerModulationNibble2(b) (Mod_Miller_LUT[(b & 0x0000000F)])
tUart* GetUart() {
tUart *GetUart()
{
return &Uart;
}
void UartReset(void) {
void UartReset(void)
{
Uart.state = STATE_UNSYNCD;
Uart.bitCount = 0;
Uart.len = 0; // number of decoded data bytes
@ -207,14 +213,16 @@ void UartReset(void) {
Uart.syncBit = 9999;
}
void UartInit(uint8_t *data, uint8_t *parity) {
void UartInit(uint8_t *data, uint8_t *parity)
{
Uart.output = data;
Uart.parity = parity;
UartReset();
}
// 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;
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 IsManchesterModulationNibble2(b) (Mod_Manchester_LUT[(b & 0x000F)])
tDemod* GetDemod() {
tDemod *GetDemod()
{
return &Demod;
}
void DemodReset(void) {
void DemodReset(void)
{
Demod.state = DEMOD_UNSYNCD;
Demod.len = 0; // number of decoded data bytes
Demod.parityLen = 0;
@ -380,14 +390,16 @@ void DemodReset(void) {
Demod.samples = 0;
}
void DemodInit(uint8_t *data, uint8_t *parity) {
void DemodInit(uint8_t *data, uint8_t *parity)
{
Demod.output = data;
Demod.parity = parity;
DemodReset();
}
// 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;
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.
// "hf 14a sniff"
//-----------------------------------------------------------------------------
void RAMFUNC SniffIso14443a(uint8_t param) {
void RAMFUNC SniffIso14443a(uint8_t param)
{
LEDsoff();
// param:
// bit 0 - trigger from first card answer
@ -496,7 +509,8 @@ void RAMFUNC SniffIso14443a(uint8_t param) {
// Allocate memory from BigBuf for some buffers
// free all previous allocations first
BigBuf_free(); BigBuf_Clear_ext(false);
BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace();
set_tracing(true);
@ -649,7 +663,8 @@ void RAMFUNC SniffIso14443a(uint8_t param) {
//-----------------------------------------------------------------------------
// 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;
ToSendReset();
@ -709,16 +724,19 @@ static void CodeIso14443aAsTagPar(const uint8_t *cmd, uint16_t len, uint8_t *par
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};
GetParity(cmd, len, par);
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);
}
static void Code4bitAnswerAsTag(uint8_t cmd) {
static void Code4bitAnswerAsTag(uint8_t cmd)
{
uint8_t b = cmd;
ToSendReset();
@ -759,7 +777,8 @@ static void Code4bitAnswerAsTag(uint8_t cmd) {
// stop when button is pressed
// 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
// only, since we are receiving, not transmitting).
// Signal field is off with the appropriate LED
@ -786,7 +805,8 @@ int GetIso14443aCommandFromReader(uint8_t *received, uint8_t *parity, int *len)
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
// This will need the following byte array for a modulation sequence
// 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
#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
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.
// '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()
@ -876,29 +898,35 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) {
case 1: { // MIFARE Classic 1k
response1[0] = 0x04;
sak = 0x08;
} break;
}
break;
case 2: { // MIFARE Ultralight
response1[0] = 0x44;
sak = 0x00;
} break;
}
break;
case 3: { // MIFARE DESFire
response1[0] = 0x04;
response1[1] = 0x03;
sak = 0x20;
} break;
}
break;
case 4: { // ISO/IEC 14443-4 - javacard (JCOP)
response1[0] = 0x04;
sak = 0x28;
} break;
}
break;
case 5: { // MIFARE TNP3XXX
response1[0] = 0x01;
response1[1] = 0x0f;
sak = 0x01;
} break;
}
break;
case 6: { // MIFARE Mini 320b
response1[0] = 0x44;
sak = 0x09;
} break;
}
break;
case 7: { // NTAG
response1[0] = 0x44;
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
flags |= FLAG_7B_UID_IN_DATA;
}
} break;
}
break;
case 8: { // MIFARE Classic 4k
response1[0] = 0x02;
sak = 0x18;
} break;
}
break;
case 9 : { // FM11RF005SH (Shanghai Metro)
response1[0] = 0x03;
response1[1] = 0x00;
@ -928,7 +958,8 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) {
default: {
Dbprintf("Error: unkown tagtype (%d)", tagType);
return;
} break;
}
break;
}
// 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.
lastorder = order;
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
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)
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)
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)
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)
p_response = &responses[4]; order = 30;
p_response = &responses[4];
order = 30;
} else if (receivedCmd[0] == ISO14443A_CMD_READBLOCK) { // Received a (plain) READ
uint8_t block = receivedCmd[1];
// if Ultralight or NTAG (4 byte blocks)
@ -1200,7 +1237,8 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) {
EmSend4bit(CARD_NACK_NA);
p_response = NULL;
} 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)
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++;
break;
}
default: break;
default:
break;
}
}
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[2] = 0x00;
dynamic_response_info.response_n = 3;
} break;
}
break;
case 0x0B:
case 0x0A: { // IBlock (command CID)
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[3] = 0x00;
dynamic_response_info.response_n = 4;
} break;
}
break;
case 0x1A:
case 0x1B: { // Chaining command
dynamic_response_info.response[0] = 0xaa | ((receivedCmd[0]) & 1);
dynamic_response_info.response_n = 2;
} break;
}
break;
case 0xAA:
case 0xBB: {
dynamic_response_info.response[0] = receivedCmd[0] ^ 0x11;
dynamic_response_info.response_n = 2;
} break;
}
break;
case 0xBA: { // ping / pong
dynamic_response_info.response[0] = 0xAB;
dynamic_response_info.response[1] = 0x00;
dynamic_response_info.response_n = 2;
} break;
}
break;
case 0xCA:
case 0xC2: { // Readers sends deselect command
dynamic_response_info.response[0] = 0xCA;
dynamic_response_info.response[1] = 0x00;
dynamic_response_info.response_n = 2;
} break;
}
break;
default: {
// Never seen this command before
@ -1329,7 +1374,8 @@ void SimulateIso14443aTag(int tagType, int flags, uint8_t* data) {
Dbhexdump(len, receivedCmd, false);
// Do not respond
dynamic_response_info.response_n = 0;
} break;
}
break;
}
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
// of bits specified in the delay parameter.
void PrepareDelayedTransfer(uint16_t delay) {
void PrepareDelayedTransfer(uint16_t delay)
{
delay &= 0x07;
if (!delay) return;
@ -1422,7 +1469,8 @@ void PrepareDelayedTransfer(uint16_t delay) {
// if == 0: transfer immediately and return time of transfer
// 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);
@ -1457,7 +1505,8 @@ static void TransmitFor14443a(const uint8_t *cmd, uint16_t len, uint32_t *timing
}
//iceman test
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
//-----------------------------------------------------------------------------
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 last = 0;
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
//-----------------------------------------------------------------------------
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);
}
@ -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)
// 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;
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;
// 50ms no field --> card to idle state
if (vtime - timer > 50) return 2;
} else
if (timer) timer = 0;
} else if (timer) timer = 0;
analogCnt = 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;
uint16_t i = 0;
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);
// 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
correctionNeeded = Uart.output[0] & 0x40;
}
else
{
} else {
// The parity bits are left-aligned
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
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));
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)
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)) {
b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); (void)b;
b = (uint16_t)(AT91C_BASE_SSC->SSC_RHR);
(void)b;
}
if (BUTTON_PRESS()) break;
}
@ -1684,7 +1736,8 @@ int EmSendCmd14443aRaw(uint8_t *resp, uint16_t respLen) {
return 0;
}
int EmSend4bit(uint8_t resp){
int EmSend4bit(uint8_t resp)
{
Code4bitAnswerAsTag(resp);
int res = EmSendCmd14443aRaw(ToSend, ToSendMax);
// do the tracing for the previous reader request and this tag answer:
@ -1702,10 +1755,12 @@ int EmSend4bit(uint8_t resp){
par);
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);
}
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);
int res = EmSendCmd14443aRaw(ToSend, ToSendMax);
// 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);
return res;
}
int EmSendCmd(uint8_t *resp, uint16_t respLen){
int EmSendCmd(uint8_t *resp, uint16_t respLen)
{
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};
GetParity(resp, respLen, par);
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 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;
// 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);
// 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);
}
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);
}
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
uint8_t par[MAX_PARITY_SIZE] = {0x00};
GetParity(frame, len / 8, par);
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
uint8_t par[MAX_PARITY_SIZE] = {0x00};
GetParity(frame, len, par);
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))
return false;
LogTrace(receivedAnswer, Demod.len, Demod.startTime * 16 - DELAY_AIR2ARM_AS_READER, Demod.endTime * 16 - DELAY_AIR2ARM_AS_READER, parity, false);
return Demod.len;
}
int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity) {
int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity)
{
if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, 0))
return 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.
// 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.
void iso14443a_antifuzz(uint32_t flags){
void iso14443a_antifuzz(uint32_t flags)
{
// We need to listen to the high-frequency, peak-detected path.
iso14443a_setup(FPGA_HF_ISO14443A_TAGSIM_LISTEN);
@ -1903,7 +1968,8 @@ void iso14443a_antifuzz(uint32_t flags){
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 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
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[]
// 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
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_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;
}
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_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
@ -2168,7 +2237,8 @@ int iso14443a_fast_select_card(uint8_t *uid_ptr, uint8_t num_cascades) {
return 1;
}
void iso14443a_setup(uint8_t fpga_minor_mode) {
void iso14443a_setup(uint8_t fpga_minor_mode)
{
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// Set up the synchronous serial port
@ -2219,7 +2289,8 @@ b8 b7 b6 b5 b4 b3 b2 b1
b5,b6 = 00 - DESELECT
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 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
&& ((data_bytes[0] & 0xC0) == 0 // I-Block
|| (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;
}
@ -2306,7 +2376,8 @@ int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, u
// low :: len of commandbytes
// arg2 timeout
// d.asBytes command bytes to send
void ReaderIso14443a(UsbCommand *c) {
void ReaderIso14443a(UsbCommand *c)
{
iso14a_command_t param = c->arg[0];
size_t len = c->arg[1] & 0xffff;
size_t lenbits = c->arg[1] >> 16;
@ -2406,7 +2477,8 @@ OUT:
// Determine the distance between two nonces.
// Assume that the difference is small, but we don't know which is first.
// 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;
@ -2435,11 +2507,13 @@ int32_t dist_nt(uint32_t nt1, uint32_t nt2) {
// Cloning MiFare Classic Rail and Building Passes, Anywhere, Anytime"
// (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);
BigBuf_free(); BigBuf_Clear_ext(false);
BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace();
set_tracing(true);
@ -2512,10 +2586,17 @@ void ReaderMifare(bool first_try, uint8_t block, uint8_t keytype ) {
continue;
}
switch (card_info.uidlen) {
case 4 : cascade_levels = 1; break;
case 7 : cascade_levels = 2; break;
case 10: cascade_levels = 3; break;
default: break;
case 4 :
cascade_levels = 1;
break;
case 7 :
cascade_levels = 2;
break;
case 10:
cascade_levels = 3;
break;
default:
break;
}
have_uid = true;
} 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
* Thanks to @doegox for the feedback and new approaches.
*/
void DetectNACKbug() {
void DetectNACKbug()
{
uint8_t mf_auth[] = {0x60, 0x00, 0xF5, 0x7B};
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};
@ -2718,7 +2800,8 @@ void DetectNACKbug() {
// Mifare Classic's random generator repeats every 2^16 cycles (and so do the nonces).
uint32_t sync_cycles = PRNG_SEQUENCE_LENGTH;
BigBuf_free(); BigBuf_Clear_ext(false);
BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace();
set_tracing(true);
iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
@ -2753,10 +2836,17 @@ void DetectNACKbug() {
continue;
}
switch (card_info.uidlen) {
case 4 : cascade_levels = 1; break;
case 7 : cascade_levels = 2; break;
case 10: cascade_levels = 3; break;
default: break;
case 4 :
cascade_levels = 1;
break;
case 7 :
cascade_levels = 2;
break;
case 10:
cascade_levels = 3;
break;
default:
break;
}
have_uid = true;
} 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
* (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 _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:
cardSTATE = MFEMUL_SELECT2;
continue;
default:break;
default:
break;
}
} else {
cardSTATE_TO_IDLE();
@ -3173,7 +3265,8 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t *
case 10:
cardSTATE = MFEMUL_SELECT3;
continue;
default:break;
default:
break;
}
}
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;
break;
}
default: break;
default:
break;
}
}

View file

@ -77,7 +77,8 @@ static struct {
uint8_t *output;
} Uart;
static void UartReset() {
static void UartReset()
{
Uart.state = STATE_UNSYNCD;
Uart.shiftReg = 0;
Uart.bitCnt = 0;
@ -86,7 +87,8 @@ static void UartReset() {
Uart.posCnt = 0;
}
static void UartInit(uint8_t *data) {
static void UartInit(uint8_t *data)
{
Uart.output = data;
UartReset();
// memset(Uart.output, 0x00, MAX_FRAME_SIZE);
@ -120,7 +122,8 @@ static struct {
} Demod;
// Clear out the state of the "UART" that receives from the tag.
static void DemodReset() {
static void DemodReset()
{
Demod.state = DEMOD_UNSYNCD;
Demod.bitCount = 0;
Demod.posCount = 0;
@ -133,7 +136,8 @@ static void DemodReset() {
Demod.endTime = 0;
}
static void DemodInit(uint8_t *data) {
static void DemodInit(uint8_t *data)
{
Demod.output = data;
DemodReset();
// memset(Demod.output, 0x00, MAX_FRAME_SIZE);
@ -153,7 +157,8 @@ static void DemodInit(uint8_t *data) {
* 13560000000 / 384000 = 35312 FWT
* @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)
if (timeout > MAX_TIMEOUT)
timeout = MAX_TIMEOUT;
@ -161,7 +166,8 @@ static void iso14b_set_timeout(uint32_t timeout) {
iso14b_timeout = 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)
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
// 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
*
* 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
* 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) {
case STATE_UNSYNCD:
if (!bit) {
@ -385,8 +393,7 @@ static RAMFUNC int Handle14443bReaderUartBit(uint8_t bit) {
Uart.posCnt = 0;
}
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
// start and stop bits
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
// 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
// only, since we are receiving, not transmitting).
// Signal field is off with the appropriate LED
@ -485,18 +493,21 @@ static int GetIso14443bCommandFromReader(uint8_t *received, uint16_t *len) {
return false;
}
void ClearFpgaShiftingRegisters(void){
void ClearFpgaShiftingRegisters(void)
{
volatile uint8_t b;
// clear receiving shift register and holding register
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)) {};
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)
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;
}
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:
uint8_t fpga_queued_bits = delay >> 3; // twich /8 ?? >>3,
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;
@ -545,7 +558,8 @@ static void TransmitFor14443b_AsTag( uint8_t *response, uint16_t len) {
// Prevent rx holding register from overflowing
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
// response to send, and send it.
//-----------------------------------------------------------------------------
void SimulateIso14443bTag(uint32_t pupi) {
void SimulateIso14443bTag(uint32_t pupi)
{
// setup device.
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
@ -566,7 +581,8 @@ void SimulateIso14443bTag(uint32_t pupi) {
FpgaSetupSsc();
// allocate command receive buffer
BigBuf_free(); BigBuf_Clear_ext(false);
BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace(); //sim
set_tracing(true);
@ -590,7 +606,8 @@ void SimulateIso14443bTag(uint32_t pupi) {
// supports only 106kBit/s in both directions, max frame size = 32Bytes,
// supports ISO14443-4, FWI=8 (77ms), NAD supported, CID not supported:
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
static const uint8_t respOK[] = {0x00, 0x78, 0xF0};
@ -704,7 +721,8 @@ void SimulateIso14443bTag(uint32_t pupi) {
}
break;
}
default: break;
default:
break;
}
++cmdsReceived;
@ -735,7 +753,8 @@ void SimulateIso14443bTag(uint32_t pupi) {
* 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);
// 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
* quiet: set to 'TRUE' to disable debug output
*/
static void GetTagSamplesFor14443bDemod() {
static void GetTagSamplesFor14443bDemod()
{
bool gotFrame = false, finished = false;
int lastRxCounter = ISO14443B_DMA_BUFFER_SIZE;
int ci = 0, cq = 0;
@ -1005,7 +1025,8 @@ static void GetTagSamplesFor14443bDemod() {
//-----------------------------------------------------------------------------
// Transmit the command (to the tag) that was placed in ToSend[].
//-----------------------------------------------------------------------------
static void TransmitFor14443b_AsReader(void) {
static void TransmitFor14443b_AsReader(void)
{
int c;
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[],
// 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:
* - 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
*/
static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len) {
static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len)
{
uint32_t time_start = GetCountSspClk();
@ -1136,7 +1159,8 @@ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len) {
/* Sends an APDU to the tag
* 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];
// PCB
@ -1170,7 +1194,8 @@ uint8_t iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *r
/**
* 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
static const uint8_t init_srx[] = { ISO14443B_INITIATE, 0x00, 0x97, 0x5b };
// 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: 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)
// 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 };
@ -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)
// field is setup for "Sending as Reader"
void iso14443b_setup() {
void iso14443b_setup()
{
LEDsoff();
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...
//-----------------------------------------------------------------------------
static bool ReadSTBlock(uint8_t block) {
static bool ReadSTBlock(uint8_t block)
{
uint8_t cmd[] = {ISO14443B_READ_BLK, block, 0x00, 0x00};
AddCrc14B(cmd, 2);
CodeAndTransmit14443bAsReader(cmd, sizeof(cmd));
@ -1353,7 +1381,8 @@ static bool ReadSTBlock(uint8_t block) {
}
return true;
}
void ReadSTMemoryIso14443b(uint8_t numofblocks) {
void ReadSTMemoryIso14443b(uint8_t numofblocks)
{
// Make sure that we start from off, since the tags are stateful;
// confusing things will happen if we don't reset them between reads.
//switch_off();
@ -1402,7 +1431,8 @@ out:
SpinDelay(20);
}
static void iso1444b_setup_sniff(void){
static void iso1444b_setup_sniff(void)
{
LEDsoff();
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
@ -1455,7 +1485,8 @@ static void iso1444b_setup_sniff(void){
* DMA Buffer - ISO14443B_DMA_BUFFER_SIZE
* 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;
int ci = 0, cq = 0;
@ -1547,7 +1578,8 @@ void RAMFUNC SniffIso14443b(void) {
switch_off();
}
void iso14b_set_trigger(bool enable) {
void iso14b_set_trigger(bool enable)
{
trigger = enable;
}
@ -1562,7 +1594,8 @@ void iso14b_set_trigger(bool enable) {
* none
*
*/
void SendRawCommand14443B_Ex(UsbCommand *c) {
void SendRawCommand14443B_Ex(UsbCommand *c)
{
iso14b_command_t param = c->arg[0];
size_t len = c->arg[1] & 0xffff;
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)
// cmd ... data
// n ... length of data
static void CodeIso15693AsReader(uint8_t *cmd, int n) {
static void CodeIso15693AsReader(uint8_t *cmd, int n)
{
int i, j;
ToSendReset();
@ -178,7 +179,8 @@ static void CodeIso15693AsReader(uint8_t *cmd, int n) {
// encode data using "1 out of 256" sheme
// data rate is 1,66 kbit/s (fc/8192)
// 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;
ToSendReset();
@ -220,7 +222,8 @@ static void CodeIso15693AsReader256(uint8_t *cmd, int n) {
}
// 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;
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[].
//-----------------------------------------------------------------------------
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;
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
//-----------------------------------------------------------------------------
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 max = 0, maxPos = 0, skip = 4;
@ -381,7 +386,8 @@ static int DemodAnswer(uint8_t *received, uint8_t *dest, uint16_t samplecount) {
// returns:
// number of decoded bytes
// logging enabled
static int GetIso15693AnswerFromTag(uint8_t *received, int *elapsed) {
static int GetIso15693AnswerFromTag(uint8_t *received, int *elapsed)
{
#define SIGNAL_BUFF_SIZE 15000
// get current clock
@ -435,7 +441,8 @@ static int GetIso15693AnswerFromTag(uint8_t *received, int *elapsed) {
// Now the GetISO15693 message from sniffing command
// 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;
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
// so that it can be downloaded to a PC and processed there.
//-----------------------------------------------------------------------------
void AcquireRawAdcSamplesIso15693(void) {
void AcquireRawAdcSamplesIso15693(void)
{
int c = 0, getNext = false;
int ci = 0, cq = 0;
@ -549,7 +557,8 @@ void AcquireRawAdcSamplesIso15693(void) {
}
// switch_off, initreader, no logging
void RecordRawAdcSamplesIso15693(void) {
void RecordRawAdcSamplesIso15693(void)
{
int c = 0, getNext = false;
int ci = 0, cq = 0;
@ -589,7 +598,8 @@ void RecordRawAdcSamplesIso15693(void) {
// Initialize the proxmark as iso15k reader
// (this might produces glitches that confuse some tags
void Iso15693InitReader(void) {
void Iso15693InitReader(void)
{
LEDsoff();
clear_trace();
set_tracing(true);
@ -621,7 +631,8 @@ void Iso15693InitReader(void) {
// Encode (into the ToSend buffers) an identify request, which is the first
// 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};
// 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
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};
@ -696,7 +708,8 @@ static void BuildInventoryResponse(uint8_t *out, uint8_t *uid) {
// If you do not need the answer use NULL for *recv[]
// return: lenght of received data
// 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;
@ -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
#define DBD15STATLEN 48
void DbdecodeIso15693Answer(int len, uint8_t *d) {
void DbdecodeIso15693Answer(int len, uint8_t *d)
{
char status[DBD15STATLEN + 1] = {0};
if (len > 3) {
@ -798,7 +812,8 @@ void DbdecodeIso15693Answer(int len, uint8_t *d) {
//-----------------------------------------------------------------------------
// ok
// parameter is unused !?!
void ReaderIso15693(uint32_t parameter) {
void ReaderIso15693(uint32_t parameter)
{
int answerLen1 = 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
// 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();
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
// (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 buf[ISO15_MAX_FRAME];
@ -970,7 +987,8 @@ void BruteforceIso15693Afi(uint32_t speed) {
// Allows to directly send commands to the tag via the 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;
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)
//-----------------------------------------------------------------------------
static inline uint8_t rx_byte_from_fpga() {
static inline uint8_t rx_byte_from_fpga()
{
for (;;) {
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
// on a i/q pair from two subsequent correlations, but does not matter.
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);
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);
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
// 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;
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.
//-----------------------------------------------------------------------------
static inline void tx_bit(bool bit) {
static inline void tx_bit(bool bit)
{
// insert pause
LOW(GPIO_SSC_DOUT);
last_frame_end += RWD_TIME_PAUSE;
@ -138,7 +144,8 @@ static inline void tx_bit(bool bit) {
// 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);
// 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);
}
static uint32_t rx_frame(uint8_t len) {
static uint32_t rx_frame(uint8_t len)
{
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
| FPGA_HF_READER_RX_XCORR_848_KHZ
| FPGA_HF_READER_RX_XCORR_QUARTER);
@ -195,7 +203,8 @@ static uint32_t rx_frame(uint8_t len) {
return frame;
}
static bool rx_ack() {
static bool rx_ack()
{
// change fpga into rx mode
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
| FPGA_HF_READER_RX_XCORR_848_KHZ
@ -235,7 +244,8 @@ static bool rx_ack() {
// 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;
switch (p_card->tagtype) {
@ -263,7 +273,8 @@ static int init_card(uint8_t cardtype, legic_card_select_t *p_card) {
return 0;
}
static void init_reader(bool clear_mem) {
static void init_reader(bool clear_mem)
{
// configure FPGA
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR
@ -303,7 +314,8 @@ static void init_reader(bool clear_mem) {
// - Transmit initialisation vector 7 bits
// - Receive card type 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
last_frame_end = GET_TICKS;
@ -336,13 +348,15 @@ static uint32_t setup_phase(uint8_t iv) {
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_update(&legic_crc, (value << cmd_sz) | cmd, 8 + cmd_sz);
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;
// 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
// 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
uint8_t crc = calc_crc4(cmd, addr_sz + 1, byte); // calculate crc
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
//-----------------------------------------------------------------------------
void LegicRfInfo(void) {
void LegicRfInfo(void)
{
// configure ARM and FPGA
init_reader(false);
@ -430,7 +446,8 @@ OUT:
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
init_reader(false);
@ -463,7 +480,8 @@ OUT:
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
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
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) {
if (GetCountSspClk() > timeout) {
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 0
// - 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
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
// not mandatory but results in a cleaner signal. tx_frame will disable
// the subcarrier when the frame is done.
static inline void tx_bit(bool bit) {
static inline void tx_bit(bool bit)
{
LED_C_ON();
if (bit) {
@ -146,7 +149,8 @@ static inline void tx_bit(bool bit) {
// 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
last_frame_end += TAG_FRAME_WAIT;
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);
}
static void tx_ack() {
static void tx_ack()
{
// wait for ack timeslot
last_frame_end += TAG_ACK_WAIT;
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
// - receive the frame
// - 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;
// 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
//-----------------------------------------------------------------------------
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;
switch (p_card->tagtype) {
@ -291,7 +298,8 @@ static int32_t init_card(uint8_t cardtype, legic_card_select_t *p_card) {
return 0;
}
static void init_tag() {
static void init_tag()
{
// configure FPGA
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR
@ -326,7 +334,8 @@ static void init_tag() {
// - Receive initialisation vector 7 bits
// - Transmit card type 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;
// init coordination timestamp
@ -387,13 +396,15 @@ static int32_t setup_phase(legic_card_select_t *p_card) {
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_update(&legic_crc, (value << cmd_sz) | cmd, 8 + cmd_sz);
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;
// 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
//-----------------------------------------------------------------------------
void LegicRfSimulate(uint8_t cardtype) {
void LegicRfSimulate(uint8_t cardtype)
{
// configure ARM and FPGA
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 } ;
void printT55xxConfig(void) {
void printT55xxConfig(void)
{
Dbprintf("LF T55XX config");
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);
@ -70,7 +71,8 @@ void printT55xxConfig(void) {
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->write_gap != 0) t_config.write_gap = c->write_gap;
@ -114,11 +116,13 @@ void setT55xxConfig(uint8_t arg0, t55xx_config *c) {
#endif
}
t55xx_config* getT55xxConfig(void) {
t55xx_config *getT55xxConfig(void)
{
return &t_config;
}
void loadT55xxConfig(void) {
void loadT55xxConfig(void)
{
#ifdef WITH_FLASH
if (!FlashInit()) {
return;
@ -156,7 +160,8 @@ void loadT55xxConfig(void) {
* @param period_1
* @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
StartTicks();
@ -397,8 +402,7 @@ void WriteTIbyte(uint8_t b)
int i = 0;
// modulate 8 bits out to the antenna
for (i=0; i<8; i++)
{
for (i = 0; i < 8; i++) {
if (b & (1 << i)) {
// stop modulating antenna 1ms
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
// 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
StartTicks();
@ -657,7 +662,8 @@ OUT:
LED_D_OFF();
}
void SimulateTagLowFrequency(int period, int gap, int ledcontrol) {
void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
{
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
// this one is focused on HID, with manchester encoding.
static void fcSTT(int *n) {
fc(8, n); fc(8, n); // invalid
fc(8, n); fc(10, n); // logical 0
fc(10, n); fc(10, n); // invalid
fc(8, n); fc(10, n); // logical 0
static void fcSTT(int *n)
{
fc(8, n);
fc(8, n); // invalid
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)
@ -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
// 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) {
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 ((hi >> i) & 1) {
fc(10, &n); fc(8, &n); // low-high transition
fc(10, &n);
fc(8, &n); // low-high transition
} 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 ((lo >> i) & 1) {
fc(10, &n); fc(8, &n); // low-high transition
fc(10, &n);
fc(8, &n); // low-high transition
} 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();
}
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);
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
// simulate a FSK tag until the button is pressed
// 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);
// free eventually allocated BigBuf memory
BigBuf_free(); BigBuf_Clear_ext(false);
BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace();
set_tracing(false);
@ -894,7 +913,8 @@ static void biphaseSimBit(uint8_t c, int *n, uint8_t clock, uint8_t *phase)
*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 halfClk = clock / 2;
//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
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();
size_t size = 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;
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;
fc = 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
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();
@ -1197,7 +1218,8 @@ void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
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();
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();
}
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();
@ -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.
*/
void TurnReadLFOn(uint32_t delay) {
void TurnReadLFOn(uint32_t delay)
{
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// measure antenna strength.
//int adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10);
WaitUS(delay);
}
void TurnReadLF_off(uint32_t delay) {
void TurnReadLF_off(uint32_t delay)
{
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
WaitUS(delay);
}
// Write one bit to card
void T55xxWriteBit(int bit) {
void T55xxWriteBit(int bit)
{
if (!bit)
TurnReadLFOn(t_config.write_0);
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)
void T55xxResetRead(void) {
void T55xxResetRead(void)
{
LED_A_ON();
//clear buffer now so it does not interfere with timing later
BigBuf_Clear_keep_EM();
@ -1414,7 +1441,8 @@ void T55xxResetRead(void) {
}
// 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();
bool PwdMode = arg & 0x1;
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
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);
cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
}
// 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();
bool PwdMode = arg0 & 0x1;
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");
@ -1662,7 +1693,8 @@ OUT:
LEDsoff();
}
void T55xxWakeUp(uint32_t Pwd){
void T55xxWakeUp(uint32_t Pwd)
{
LED_B_ON();
uint32_t i = 0;
@ -1690,14 +1722,16 @@ void T55xxWakeUp(uint32_t Pwd){
}
/*-------------- 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)
for (uint8_t i = numblocks + startblock; i > startblock; i--)
T55xxWriteBlockExt(blockdata[i - 1], i - 1, 0, 0);
}
// 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};
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();
}
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};
//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;
@ -1754,7 +1789,8 @@ void CopyIOtoT55x7(uint32_t hi, uint32_t lo) {
}
// 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
// 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};
@ -1766,7 +1802,8 @@ void CopyIndala64toT55x7(uint32_t hi, uint32_t lo) {
// T5567WriteBlock(0x603E1042,0);
}
// 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
uint32_t data[] = {0, uid1, uid2, uid3, uid4, uid5, uid6, uid7};
// 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);
}
// 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};
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
@ -1792,7 +1830,8 @@ void CopyVikingtoT55xx(uint32_t block1, uint32_t block2, uint8_t Q5) {
#define EM410X_HEADER 0x1FF
#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;
uint64_t id = EM410X_HEADER;
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)
// 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; //second pause for 4050 code
@ -1925,7 +1965,8 @@ uint8_t Prepare_Cmd( uint8_t cmd ) {
// prepares address bits
// see EM4469 spec
//====================================================================
uint8_t Prepare_Addr( uint8_t addr ) {
uint8_t Prepare_Addr(uint8_t addr)
{
register uint8_t line_parity;
@ -1946,7 +1987,8 @@ uint8_t Prepare_Addr( uint8_t addr ) {
// prepares data bits intreleaved with parity bits
// 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 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)
// 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.
// 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;
forward_ptr = forwardLink_data;
len = Prepare_Cmd(FWD_CMD_LOGIN);
@ -2029,7 +2073,8 @@ void EM4xLogin(uint32_t pwd) {
// 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();
uint8_t len;
@ -2061,7 +2106,8 @@ void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd) {
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();
@ -2111,7 +2157,8 @@ pulse 3.6 msecs
This triggers a COTAG tag to response
*/
void Cotag(uint32_t arg0) {
void Cotag(uint32_t arg0)
{
#ifndef OFF
# define OFF(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS((x)); }
#endif
@ -2134,9 +2181,15 @@ void Cotag(uint32_t arg0) {
ON(1000)
switch (rawsignal) {
case 0: doCotagAcquisition(50000); break;
case 1: doCotagAcquisitionManchester(); break;
case 2: DoAcquisition_config(true, 0); break;
case 0:
doCotagAcquisition(50000);
break;
case 1:
doCotagAcquisitionManchester();
break;
case 2:
DoAcquisition_config(true, 0);
break;
}
// Turn the field off

View file

@ -18,7 +18,8 @@ Default LF config is set to:
*/
sample_config config = { 1, 8, 1, 95, 0 } ;
void printConfig() {
void printConfig()
{
Dbprintf("LF Sampling config");
Dbprintf(" [q] divisor.............%d (%d KHz)", config.divisor, 12000 / (config.divisor + 1));
Dbprintf(" [b] bps.................%d", config.bits_per_sample);
@ -38,7 +39,8 @@ void printConfig() {
* @brief setSamplingConfig
* @param sc
*/
void setSamplingConfig(sample_config *sc) {
void setSamplingConfig(sample_config *sc)
{
if (sc->divisor != 0) config.divisor = sc->divisor;
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;
@ -50,7 +52,8 @@ void setSamplingConfig(sample_config *sc) {
printConfig();
}
sample_config* getSamplingConfig() {
sample_config *getSamplingConfig()
{
return &config;
}
@ -65,7 +68,8 @@ struct BitstreamOut {
* @param stream
* @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 bitpos = stream->position & 7;
*(stream->buffer + bytepos) |= (bit > 0) << (7 - bitpos);
@ -80,7 +84,8 @@ void pushBit( BitstreamOut* stream, uint8_t bit) {
* 0 or 95 ==> 125 KHz
*
**/
void LFSetupFPGAForADC(int divisor, bool lf_field) {
void LFSetupFPGAForADC(int divisor, bool lf_field)
{
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
if ((divisor == 1) || (divisor < 0) || (divisor > 255))
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
* @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();
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
* @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);
}
uint32_t DoAcquisition_config( bool silent, int sample_size) {
uint32_t DoAcquisition_config(bool silent, int sample_size)
{
return DoAcquisition(config.decimation
, config.bits_per_sample
, config.averaging
@ -231,11 +239,13 @@ uint32_t DoAcquisition_config( bool silent, int sample_size) {
, 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);
}
uint32_t ReadLF(bool activeField, bool silent, int sample_size) {
uint32_t ReadLF(bool activeField, bool silent, int sample_size)
{
if (!silent)
printConfig();
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.
* @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);
uint32_t ret = ReadLF(true, printCfg, sample_size);
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.
* @return number of bits sampled
**/
uint32_t SnoopLF() {
uint32_t SnoopLF()
{
BigBuf_Clear_ext(false);
uint32_t ret = ReadLF(false, true, 0);
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
* 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_LOWER_THRESHOLD 128-60 // -60 grph
@ -337,7 +350,8 @@ void doT55x7Acquisition(size_t sample_size) {
#ifndef COTAG_BITS
#define COTAG_BITS 264
#endif
void doCotagAcquisition(size_t sample_size) {
void doCotagAcquisition(size_t sample_size)
{
uint8_t *dest = BigBuf_get_addr();
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();
uint16_t bufsize = BigBuf_max_traceLen();
@ -431,12 +446,10 @@ uint32_t doCotagAcquisitionManchester() {
if (sample > COTAG_ONE_THRESHOLD) {
prev = curr;
curr = 1;
}
else if ( sample < COTAG_ZERO_THRESHOLD) {
} else if (sample < COTAG_ZERO_THRESHOLD) {
prev = curr;
curr = 0;
}
else {
} else {
curr = prev;
}

View file

@ -101,11 +101,14 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
LEDsoff();
}
void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){
void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes)
{
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);
@ -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);
// free eventually allocated BigBuf memory
BigBuf_free(); BigBuf_Clear_ext(false);
BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace();
set_tracing(true);
@ -539,14 +543,17 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
set_tracing(false);
}
void MifareUSetPwd(uint8_t arg0, uint8_t *datain){
void MifareUSetPwd(uint8_t arg0, uint8_t *datain)
{
uint8_t pwd[16] = {0x00};
byte_t blockdata[4] = {0x00};
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);
clear_trace();
@ -611,13 +618,15 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain){
}
// 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))) & \
(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;
}
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 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_C_OFF();
BigBuf_free(); BigBuf_Clear_ext(false);
BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace();
set_tracing(true);
@ -661,10 +671,17 @@ void MifareAcquireNonces(uint32_t arg0, uint32_t arg1, uint32_t flags, uint8_t *
continue;
}
switch (card_info.uidlen) {
case 4 : cascade_levels = 1; break;
case 7 : cascade_levels = 2; break;
case 10: cascade_levels = 3; break;
default: break;
case 4 :
cascade_levels = 1;
break;
case 7 :
cascade_levels = 2;
break;
case 10:
cascade_levels = 3;
break;
default:
break;
}
have_uid = true;
} 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
// 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 *pcs;
@ -746,7 +764,8 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
LED_A_ON();
LED_C_OFF();
BigBuf_free(); BigBuf_Clear_ext(false);
BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace();
set_tracing(false);
@ -771,10 +790,17 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
continue;
}
switch (card_info.uidlen) {
case 4 : cascade_levels = 1; break;
case 7 : cascade_levels = 2; break;
case 10: cascade_levels = 3; break;
default: break;
case 4 :
cascade_levels = 1;
break;
case 7 :
cascade_levels = 2;
break;
case 10:
cascade_levels = 3;
break;
default:
break;
}
have_uid = true;
} 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);
// free eventually allocated BigBuf memory
BigBuf_free(); BigBuf_Clear_ext(false);
BigBuf_free();
BigBuf_Clear_ext(false);
if (calibrate) clear_trace();
set_tracing(true);
@ -934,8 +961,7 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
davg += i;
dmin = MIN(dmin, i);
dmax = MAX(dmax, i);
}
else {
} else {
delta_time = auth2_time - auth1_time + 32; // allow some slack for proper timing
}
if (MF_DBGLEVEL >= 3) Dbprintf("Nested: calibrating... ntdist=%d", i);
@ -1075,7 +1101,8 @@ typedef struct chk_t {
// 2 = failed to select.
// 1 = wrong key
// 0 = correct key
uint8_t chkKey( struct chk_t *c ) {
uint8_t chkKey(struct chk_t *c)
{
uint8_t i = 0, res = 2;
while (i < 5) {
// 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;
}
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))
return 2;
@ -1121,7 +1149,8 @@ uint8_t chkKey_readb(struct chk_t *c, uint8_t *keyb) {
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++) {
// 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++) {
// 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,
// 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.
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
// arg2 = antal nycklar i keychunk
// 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
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) {
case 4 : cascade_levels = 1; break;
case 7 : cascade_levels = 2; break;
case 10: cascade_levels = 3; break;
default: break;
case 4 :
cascade_levels = 1;
break;
case 7 :
cascade_levels = 2;
break;
case 10:
cascade_levels = 3;
break;
default:
break;
}
CHK_TIMEOUT();
@ -1486,14 +1525,16 @@ OUT:
set_tracing(false);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
BigBuf_free(); BigBuf_Clear_ext(false);
BigBuf_free();
BigBuf_Clear_ext(false);
} else {
// partial/none keys found
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);
@ -1535,10 +1576,17 @@ void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain) {
continue;
}
switch (card_info.uidlen) {
case 4 : cascade_levels = 1; break;
case 7 : cascade_levels = 2; break;
case 10: cascade_levels = 3; break;
default: break;
case 4 :
cascade_levels = 1;
break;
case 7 :
cascade_levels = 2;
break;
case 10:
cascade_levels = 3;
break;
default:
break;
}
have_uid = true;
} 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
//
//-----------------------------------------------------------------------------
void MifareSetDbgLvl(uint16_t arg0){
void MifareSetDbgLvl(uint16_t arg0)
{
MF_DBGLEVEL = arg0;
Dbprintf("Debug level: %d", MF_DBGLEVEL);
}
@ -1588,18 +1637,21 @@ void MifareSetDbgLvl(uint16_t arg0){
// 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);
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);
if (arg2 == 0) arg2 = 16; // backwards compat... default bytewidth
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);
byte_t buf[USB_CMD_DATA_SIZE] = {0x00};
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
//
//-----------------------------------------------------------------------------
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 keyType = arg1;
uint64_t ui64Key = 0;
@ -1710,7 +1763,8 @@ uint8_t wupC1[] = { MIFARE_MAGICWUPC1 };
uint8_t wupC2[] = { MIFARE_MAGICWUPC2 };
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
uint8_t workFlags = arg0;
@ -1820,7 +1874,8 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){
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 blockNo = arg1;
@ -1896,7 +1951,8 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint8_t *datain){
OnSuccessMagic();
}
void MifareCIdent(){
void MifareCIdent()
{
#define GEN_1A 1
#define GEN_1B 2
#define GEN_2 4
@ -1921,7 +1977,8 @@ void MifareCIdent(){
isGen = GEN_1A;
goto OUT;
TEST2:;
TEST2:
;
/*
// Generation 2 test
@ -1940,7 +1997,8 @@ TEST2:;
isGen = GEN_2;
};
*/
OUT:;
OUT:
;
// removed the if, since some magic tags misbehavies and send an answer to it.
mifare_classic_halt_ex(NULL);
cmd_send(CMD_ACK, isGen, 0, 0, 0, 0);
@ -1948,18 +2006,21 @@ OUT:;
OnSuccessMagic();
}
void OnSuccessMagic(){
void OnSuccessMagic()
{
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LEDsoff();
set_tracing(false);
}
void OnErrorMagic(uint8_t reason){
void OnErrorMagic(uint8_t reason)
{
// ACK, ISOK, reason,0,0,0
cmd_send(CMD_ACK, 0, reason, 0, 0, 0);
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);
// variables
@ -2019,7 +2080,8 @@ void MifareSetMod(uint8_t mod, uint8_t *key) {
//
// 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};
uint8_t uid[10] = {0x00};
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));
}
void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){
void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain)
{
uint32_t cuid = arg0;
uint8_t key[16] = {0x00};
byte_t dataout[12] = {0x00};

View file

@ -16,7 +16,8 @@ static uint8_t deselect_cmd[] = {0xc2,0xe0,0xb4};
/* PCB CID CMD PAYLOAD */
//static uint8_t __res[MAX_FRAME_SIZE];
bool InitDesfireCard(){
bool InitDesfireCard()
{
iso14a_card_select_t card;
@ -40,7 +41,8 @@ enum {
BAR = 0x08,
} 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.
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);
}
void MifareDesfireGetInformation(){
void MifareDesfireGetInformation()
{
int len = 0;
iso14a_card_select_t card;
@ -167,7 +170,8 @@ void MifareDesfireGetInformation(){
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;
//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_len = length of cmd
// 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 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
&& ((resp[0] & 0xC0) == 0 // I-Block
|| (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
}
@ -534,7 +538,8 @@ int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout){
}
// 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);
@ -558,14 +563,16 @@ size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout){
// crc_update(&desfire_crc32, byte, 8);
// uint32_t crc = crc_finish(&desfire_crc32);
void OnSuccess(){
void OnSuccess()
{
pcb_blocknum = 0;
ReaderTransmit(deselect_cmd, 3, NULL);
mifare_ultra_halt();
switch_off();
}
void OnError(uint8_t reason){
void OnError(uint8_t reason)
{
cmd_send(CMD_ACK, 0, reason, 0, 0, 0);
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.
//-----------------------------------------------------------------------------
// "hf mf sniff"
void RAMFUNC SniffMifare(uint8_t param) {
void RAMFUNC SniffMifare(uint8_t param)
{
// param:
// bit 0 - trigger from first card answer
// 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
// free all previous allocations first
BigBuf_free(); BigBuf_Clear_ext(false);
BigBuf_free();
BigBuf_Clear_ext(false);
clear_trace();
set_tracing(true);
@ -175,7 +177,8 @@ void RAMFUNC SniffMifare(uint8_t param) {
switch_off();
}
void MfSniffInit(void){
void MfSniffInit(void)
{
memset(sniffUID, 0x00, sizeof(sniffUID));
memset(sniffATQA, 0x00, sizeof(sniffATQA));
memset(sniffBuf, 0x00, sizeof(sniffBuf));
@ -184,7 +187,8 @@ void MfSniffInit(void){
timerData = 0;
}
void MfSniffEnd(void){
void MfSniffEnd(void)
{
LED_B_ON();
cmd_send(CMD_ACK, 0, 0, 0, 0, 0);
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 chunksize = 0;
int packlen = tracelen; // total number of bytes to send

View file

@ -13,7 +13,8 @@
int MF_DBGLEVEL = MF_DBG_ERROR;
// 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;
int i;
@ -30,11 +31,13 @@ void mf_crypto1_decryptEx(struct Crypto1State *pcs, uint8_t *data_in, int len, u
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);
}
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;
int i;
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;
bt |= (crypto1_bit(pcs, 0, 0) ^ BIT(data, 0)) << 0;
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
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];
dcmd[0] = cmd;
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
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;
uint8_t dcmd[4] = {cmd, data, 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
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);
}
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;
uint32_t pos, nt, ntpp; // Supplied tag nonce
uint8_t par[1] = {0x00};
@ -195,7 +203,8 @@ int mifare_classic_authex(struct Crypto1State *pcs, uint32_t uid, uint8_t blockN
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;
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
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;
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;
}
int mifare_ultra_auth(uint8_t *keybytes){
int mifare_ultra_auth(uint8_t *keybytes)
{
/// 3des2k
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;
}
int mifare_ultra_readblockEx(uint8_t blockNo, uint8_t *blockData) {
int mifare_ultra_readblockEx(uint8_t blockNo, uint8_t *blockData)
{
uint16_t len = 0;
uint8_t bt[2] = {0x00, 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);
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
uint8_t res;
@ -379,7 +392,8 @@ int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData) {
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
uint16_t len = 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;
uint8_t block[5] = {blockNo, 0x00, 0x00, 0x00, 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;
}
int mifare_classic_halt_ex(struct Crypto1State *pcs) {
int mifare_classic_halt_ex(struct Crypto1State *pcs)
{
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);
if (len != 0) {
@ -484,11 +500,13 @@ int mifare_classic_halt_ex(struct Crypto1State *pcs) {
}
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);
}
int mifare_ultra_halt() {
int mifare_ultra_halt()
{
uint16_t len = 0;
uint8_t receivedAnswer[4] = {0x00, 0x00, 0x00, 0x00};
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),
// 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;
}
uint8_t FirstBlockOfSector(uint8_t sectorNo) {
uint8_t FirstBlockOfSector(uint8_t sectorNo)
{
if (sectorNo < 32)
return sectorNo * 4;
else
@ -515,26 +535,31 @@ uint8_t FirstBlockOfSector(uint8_t sectorNo) {
}
// 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);
}
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();
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();
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();
memcpy(data, emCARD + bytePtr, byteCount);
}
int emlCheckValBl(int blockNum) {
int emlCheckValBl(int blockNum)
{
uint8_t *emCARD = BigBuf_get_EM_addr();
uint8_t *data = emCARD + blockNum * 16;
@ -549,7 +574,8 @@ int emlCheckValBl(int blockNum) {
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 *data = emCARD + blockNum * 16;
@ -561,7 +587,8 @@ int emlGetValBl(uint32_t *blReg, uint8_t *blBlock, int blockNum) {
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 *data = emCARD + blockNum * 16;
@ -578,14 +605,16 @@ int emlSetValBl(uint32_t blReg, uint8_t blBlock, int blockNum) {
return 0;
}
uint64_t emlGetKey(int sectorNum, int keyType) {
uint64_t emlGetKey(int sectorNum, int keyType)
{
uint8_t key[6] = {0x00};
uint8_t *emCARD = BigBuf_get_EM_addr();
memcpy(key, emCARD + 16 * (FirstBlockOfSector(sectorNum) + NumBlocksPerSector(sectorNum) - 1) + keyType * 10, 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 uid[] = {0xe6, 0x84, 0x87, 0xf3, 0x16, 0x88, 0x04, 0x00, 0x46, 0x8e, 0x45, 0x55, 0x4d, 0x70, 0x41, 0x04};
uint8_t *emCARD = BigBuf_get_EM_addr();
@ -602,7 +631,8 @@ void emlClearMem(void) {
// 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};
AddCrc14A(dcmd, 3);
@ -615,7 +645,8 @@ int mifare_sendcmd_special(struct Crypto1State *pcs, uint8_t crypted, uint8_t cm
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};
dcmd[0] = cmd;
memcpy(dcmd + 1, data, 17);
@ -630,7 +661,8 @@ int mifare_sendcmd_special2(struct Crypto1State *pcs, uint8_t crypted, uint8_t c
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;
// load key, keynumber
@ -658,7 +690,8 @@ int mifare_desfire_des_auth1(uint32_t uid, uint8_t *blockData){
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;
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);
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;
}
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;
int i;
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 bout = 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 = {
((k[0] ^ 0x4c) + 0xEC) & 0xFF,// l
((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);
}
uint8_t rev_byte(uint8_t b) {
uint8_t rev_byte(uint8_t b)
{
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
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;
for (i = 0; i < len ; 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];
opt_reverse_arraybytecpy(cc_nr, cc_nr_p, 12);
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);
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];
opt_reverse_arraybytecpy(cc_nr, cc_p, 12);
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
* @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];
opt_reverse_arraybytecpy(cc_nr, cc_p, 8);
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 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];
opt_reverse_arraybytecpy(_nr, nr, 4);
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 ALLOC 16
size_t DemodPCF7931(uint8_t **outBlocks) {
size_t DemodPCF7931(uint8_t **outBlocks)
{
uint8_t bits[256] = {0x00};
uint8_t blocks[8][16];
uint8_t *dest = BigBuf_get_addr();
@ -82,8 +83,7 @@ size_t DemodPCF7931(uint8_t **outBlocks) {
} else if (half_switch == 1) {
bits[bitidx++] = 0;
half_switch = 0;
}
else
} else
half_switch++;
} else if (ABS(lc - clock) < tolerance) {
// 64TO
@ -128,23 +128,22 @@ size_t DemodPCF7931(uint8_t **outBlocks) {
return num_blocks;
}
bool IsBlock0PCF7931(uint8_t *block) {
bool IsBlock0PCF7931(uint8_t *block)
{
// assuming all RFU bits are 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))
return true;
}
else if (block[7] == 0x00)
{
} else if (block[7] == 0x00) {
if (!memcmp(block + 9, "\x00\x00\x00\x00\x00\x00\x00", 7))
return true;
}
return false;
}
bool IsBlock1PCF7931(uint8_t *block) {
bool IsBlock1PCF7931(uint8_t *block)
{
// assuming all RFU bits are set to 0
if (block[10] == 0 && block[11] == 0 && block[12] == 0 && block[13] == 0)
if ((block[14] & 0x7f) <= 9 && block[15] <= 9)
@ -153,7 +152,8 @@ bool IsBlock1PCF7931(uint8_t *block) {
return false;
}
void ReadPCF7931() {
void ReadPCF7931()
{
int found_blocks = 0; // successfully read blocks
int max_blocks = 8; // readable blocks
uint8_t memory_blocks[8][17]; // PCF content
@ -277,8 +277,7 @@ void ReadPCF7931() {
Dbprintf("Button pressed, stopping.");
goto end;
}
}
while (found_blocks != max_blocks);
} while (found_blocks != max_blocks);
end:
Dbprintf("-----------------------------------------");
@ -304,7 +303,8 @@ void ReadPCF7931() {
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 u = 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
for (u = 0; u < 4; ++u)
{
for (u = 0; u < 4; ++u) {
if (byte & (1 << u)) { // bit 1
parity++;
AddBitPCF7931(1, tab, l, p);
}
else // bit 0
} else // bit 0
AddBitPCF7931(0, tab, l, p);
}
//data on 8 bits
for (u=0; u<8; u++)
{
for (u = 0; u < 8; u++) {
if (data & (1 << u)) { // bit 1
parity++;
AddBitPCF7931(1, tab, l, p);
}
else //bit 0
} else //bit 0
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 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("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);
@ -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
*/
void SendCmdPCF7931(uint32_t * tab){
void SendCmdPCF7931(uint32_t *tab)
{
uint16_t u = 0, tempo = 0;
Dbprintf("Sending data frame...");
@ -464,7 +462,8 @@ void SendCmdPCF7931(uint32_t * tab){
* @param l : offset on low pulse width
* @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;
for (u = 0; u < 8; ++u) {
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 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;
//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 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;
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);
}
percent = fmt - 1;
qflag = 0; lflag = 0; ladjust = 0; 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++) {
qflag = 0;
lflag = 0;
ladjust = 0;
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 '.':
dot = 1;
goto reswitch;
@ -169,8 +181,15 @@ reswitch: switch (ch = (u_char)*fmt++) {
padc = '0';
goto reswitch;
}
case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
for (n = 0;; ++fmt) {
n = n * 10 + ch - '0';
ch = *fmt;

View file

@ -46,7 +46,8 @@ int memcmp(const void *av, const void *bv, int len)
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++)
*dest ^= *src;
}

View file

@ -11,7 +11,8 @@
#include "ticks.h"
// attempt at high resolution microsecond timer
// beware: timer counts in 21.3uS increments (1024/48Mhz)
void SpinDelayUs(int us) {
void SpinDelayUs(int us)
{
int ticks = (48 * us) >> 10;
// 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
SpinDelayUs(ms * 1000);
}
@ -46,7 +48,8 @@ void SpinDelay(int ms) {
// SpinDelay(1000);
// ti = GetTickCount() - ti;
// 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.
// 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
@ -58,14 +61,16 @@ void StartTickCount(void) {
/*
* Get the current count.
*/
uint32_t RAMFUNC GetTickCount(void){
uint32_t RAMFUNC GetTickCount(void)
{
return AT91C_BASE_RTTC->RTTC_RTVR;// was * 2;
}
// -------------------------------------------------------------------------
// microseconds timer
// -------------------------------------------------------------------------
void StartCountUS(void) {
void StartCountUS(void)
{
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;
@ -88,7 +93,8 @@ void StartCountUS(void) {
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);
// 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;
@ -97,7 +103,8 @@ uint32_t RAMFUNC GetCountUS(void){
// -------------------------------------------------------------------------
// 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_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_TIOA1 // XC0 Clock = TIOA1
| 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.
while (AT91C_BASE_TC2->TC_CV > 0);
}
void ResetSspClk(void) {
void ResetSspClk(void)
{
//enable clock of timer and software trigger
AT91C_BASE_TC0->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;
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;
if ((tmp_count & 0x0000ffff) == 0) //small chance that we may have missed an increment in TC2
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
// 1us = 1.5ticks
// -------------------------------------------------------------------------
void StartTicks(void){
void StartTicks(void)
{
// initialization of the timer
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;
@ -205,7 +215,8 @@ void StartTicks(void){
while (AT91C_BASE_TC0->TC_CV > 0);
}
uint32_t GetTicks(void) {
uint32_t GetTicks(void)
{
uint32_t hi, lo;
do {
@ -218,7 +229,8 @@ uint32_t GetTicks(void) {
// Wait - Spindelay in ticks.
// 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;
ticks += GetTicks();
while (GetTicks() < ticks);
@ -226,15 +238,18 @@ void WaitTicks(uint32_t ticks){
// Wait / Spindelay in us (microseconds)
// 1us = 1.5ticks.
void WaitUS(uint16_t us){
void WaitUS(uint16_t us)
{
WaitTicks((uint32_t)us * 3 / 2);
}
void WaitMS(uint16_t ms){
void WaitMS(uint16_t ms)
{
WaitTicks((uint32_t)ms * 1500);
}
// stop clock
void StopTicks(void){
void StopTicks(void)
{
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
}

View file

@ -9,7 +9,8 @@
//-----------------------------------------------------------------------------
#include "util.h"
size_t nbytes(size_t nbits) {
size_t nbytes(size_t nbits)
{
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.
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;
for (int i = 0; i < b; ++i) {
if (t & 1)
@ -30,10 +32,12 @@ uint32_t reflect(uint32_t v, int b) {
return v;
}
uint8_t reflect8(uint8_t b) {
uint8_t reflect8(uint8_t b)
{
return ((b * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32;
}
uint16_t reflect16(uint16_t b) {
uint16_t reflect16(uint16_t b)
{
uint16_t v = 0;
v |= (b & 0x8000) >> 15;
v |= (b & 0x4000) >> 13;
@ -55,14 +59,16 @@ uint16_t reflect16(uint16_t b) {
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--) {
dest[len] = (uint8_t) n;
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;
while (len--) {
num = (num << 8) | (*src);
@ -72,7 +78,8 @@ uint64_t bytes_to_num(uint8_t* src, size_t len) {
}
// 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];
for (size_t i = 0; i < len - 1; i++) {
data[i] = data[i + 1];
@ -80,48 +87,84 @@ void rol(uint8_t *data, const size_t len) {
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++) {
data[n] = (data[n] << 1) | (data[n + 1] >> 7);
}
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];
}
//convert hex digit to integer
uint8_t hex2int(char hexchar){
uint8_t hex2int(char hexchar)
{
switch (hexchar) {
case '0': return 0; break;
case '1': return 1; break;
case '2': return 2; 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 '0':
return 0;
break;
case '1':
return 1;
break;
case '2':
return 2;
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': return 10; break;
case 'A':
return 10;
break;
case 'b':
case 'B': return 11; break;
case 'B':
return 11;
break;
case 'c':
case 'C': return 12; break;
case 'C':
return 12;
break;
case 'd':
case 'D': return 13; break;
case 'D':
return 13;
break;
case 'e':
case 'E': return 14; break;
case 'E':
return 14;
break;
case 'f':
case 'F': return 15; break;
case 'F':
return 15;
break;
default:
return 0;
}
}
void LEDsoff() {
void LEDsoff()
{
LED_A_OFF();
LED_B_OFF();
LED_C_OFF();
@ -129,7 +172,8 @@ void LEDsoff() {
}
// 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)
LED_C_ON();
if (led & LED_ORANGE)
@ -154,7 +198,8 @@ void LED(int led, int ms) {
LED_D_OFF();
}
void SpinOff(uint32_t pause) {
void SpinOff(uint32_t pause)
{
LED_A_OFF();
LED_B_OFF();
LED_C_OFF();
@ -163,10 +208,10 @@ void SpinOff(uint32_t pause) {
}
// 0=A, 1=B, 2=C, 3=D
void SpinErr(uint8_t led, uint32_t speed, uint8_t times) {
SpinOff(speed);
NTIME(times)
void SpinErr(uint8_t led, uint32_t speed, uint8_t times)
{
SpinOff(speed);
NTIME(times) {
switch (led) {
case 0:
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);
LED_D_ON();
SpinDelay(speed);
@ -201,7 +247,8 @@ void SpinDown(uint32_t speed) {
LED_A_OFF();
}
void SpinUp(uint32_t speed) {
void SpinUp(uint32_t speed)
{
SpinOff(speed);
LED_A_ON();
SpinDelay(speed);
@ -222,7 +269,8 @@ void SpinUp(uint32_t speed) {
// not clicked, or held down (for ms || 1sec)
// In general, don't use this function unless you expect a
// 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
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;
int letoff = 0;
for(;;)
{
for (;;) {
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
// We haven't let off the button yet
if (!letoff)
{
if (!letoff) {
// We just let it off!
if (!BUTTON_PRESS())
{
if (!BUTTON_PRESS()) {
letoff = 1;
// reset our timer for 500ms
@ -271,8 +316,7 @@ int BUTTON_CLICKED(int ms) {
return BUTTON_DOUBLE_CLICK;
// Have we ran out of time to double click?
else
if (now == (uint16_t)(start + ticks))
else if (now == (uint16_t)(start + ticks))
// At least we did a single click
return BUTTON_SINGLE_CLICK;
@ -284,7 +328,8 @@ int BUTTON_CLICKED(int ms) {
}
// Determine if a button is held down
int BUTTON_HELD(int ms) {
int BUTTON_HELD(int ms)
{
// If button is held for one second
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;
for(;;)
{
for (;;) {
uint16_t now = AT91C_BASE_PWMC_CH0->PWMC_CCNTR;
// 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;
// Have we waited the full second?
else
if (now == (uint16_t)(start + ticks))
else if (now == (uint16_t)(start + ticks))
return BUTTON_HOLD;
WDT_HIT();
@ -326,7 +369,8 @@ int BUTTON_HELD(int ms) {
* verifies the magic properties, then stores a formatted string, prefixed by
* 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;
dst[0] = 0;
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(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->extobj = extobj;
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];
buf[0] = ESC;
buf[1] = '[';
@ -58,7 +60,8 @@ int vtsend_cursor_position(vtsend_t *p, const int column, const int line) {
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];
buf[0] = ESC;
buf[1] = '[';
@ -71,7 +74,8 @@ int vtsend_cursor_up(vtsend_t *p, const int n) {
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];
buf[0] = ESC;
buf[1] = '[';
@ -84,7 +88,8 @@ int vtsend_cursor_down(vtsend_t *p, const int n) {
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];
buf[0] = ESC;
buf[1] = '[';
@ -97,7 +102,8 @@ int vtsend_cursor_forward(vtsend_t *p, const int n) {
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];
buf[0] = ESC;
buf[1] = '[';
@ -110,7 +116,8 @@ int vtsend_cursor_backward(vtsend_t *p, const int n) {
return 0;
}
int vtsend_cursor_position_save(vtsend_t *p) {
int vtsend_cursor_position_save(vtsend_t *p)
{
char buf[1 + 3];
buf[0] = ESC;
buf[1] = '[';
@ -121,7 +128,8 @@ int vtsend_cursor_position_save(vtsend_t *p) {
return 0;
}
int vtsend_cursor_position_restore(vtsend_t *p) {
int vtsend_cursor_position_restore(vtsend_t *p)
{
char buf[1 + 3];
buf[0] = ESC;
buf[1] = '[';
@ -132,7 +140,8 @@ int vtsend_cursor_position_restore(vtsend_t *p) {
return 0;
}
int vtsend_erase_display(vtsend_t *p) {
int vtsend_erase_display(vtsend_t *p)
{
char buf[1 + 4];
buf[0] = ESC;
buf[1] = '[';
@ -144,7 +153,8 @@ int vtsend_erase_display(vtsend_t *p) {
return 0;
}
int vtsend_erase_line(vtsend_t *p) {
int vtsend_erase_line(vtsend_t *p)
{
char buf[1 + 4];
buf[0] = ESC;
buf[1] = '[';
@ -156,7 +166,8 @@ int vtsend_erase_line(vtsend_t *p) {
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];
buf[0] = ESC;
buf[1] = '[';
@ -169,7 +180,8 @@ int vtsend_set_color_foreground(vtsend_t *p, const int color) {
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];
buf[0] = ESC;
buf[1] = '[';
@ -182,7 +194,8 @@ int vtsend_set_color_background(vtsend_t *p, const int color) {
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];
buf[0] = ESC;
buf[1] = '[';
@ -195,7 +208,8 @@ int vtsend_set_attribute(vtsend_t *p, const int attr) {
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];
buf[0] = ESC;
buf[1] = '[';
@ -211,7 +225,8 @@ int vtsend_set_scroll_region(vtsend_t *p, const int top, const int bottom) {
return 0;
}
int vtsend_set_cursor(vtsend_t *p, const int visible) {
int vtsend_set_cursor(vtsend_t *p, const int visible)
{
if (visible) {
char buf[1 + 6];
buf[0] = ESC;
@ -238,7 +253,8 @@ int vtsend_set_cursor(vtsend_t *p, const int visible) {
return 0;
}
int vtsend_reset(vtsend_t *p) {
int vtsend_reset(vtsend_t *p)
{
char buf[1 + 2];
buf[0] = ESC;
buf[1] = 'c';
@ -248,7 +264,8 @@ int vtsend_reset(vtsend_t *p) {
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;
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;
}
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;
for (i = y1; i <= y2; 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 uint32_t _osimage_entry;
void DbpString(char *str) {
void DbpString(char *str)
{
byte_t len = 0;
while (str[len] != 0x00)
len++;
@ -23,7 +24,8 @@ void DbpString(char *str) {
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
// 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)) {};
}
static void Fatal(void) {
static void Fatal(void)
{
for (;;) {};
}
void UsbPacketReceived(uint8_t *packet, int len) {
void UsbPacketReceived(uint8_t *packet, int len)
{
int i, dont_ack = 0;
UsbCommand *c = (UsbCommand *)packet;
volatile uint32_t *p;
@ -102,7 +106,8 @@ void UsbPacketReceived(uint8_t *packet, int len) {
arg0 |= DEVICE_INFO_FLAG_OSIMAGE_PRESENT;
cmd_send(CMD_DEVICE_INFO, arg0, 1, 2, 0, 0);
} break;
}
break;
case CMD_SETUP_WRITE: {
/* 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;
for (i = 0; i < 12; i++)
p[i + arg0] = c->d.asDwords[i];
} break;
}
break;
case CMD_FINISH_WRITE: {
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);
}
}
} break;
}
break;
case CMD_HARDWARE_RESET: {
usb_disable();
AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
} break;
}
break;
case CMD_START_FLASH: {
if (c->arg[2] == START_FLASH_MAGIC)
@ -176,18 +184,21 @@ void UsbPacketReceived(uint8_t *packet, int len) {
dont_ack = 1;
cmd_send(CMD_NACK, 0, 0, 0, 0, 0);
}
} break;
}
break;
default: {
Fatal();
} break;
}
break;
}
if (!dont_ack)
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;
end_addr = 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
// just need to be assigned to the appropriate peripheral.

View file

@ -12,7 +12,8 @@
#define HMAC_POS_DATA 0x008
#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);
memset(key + 0x02, 0x00, 0x0E);
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);
}
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];
nfc3d_amiibo_calc_seed(dump, seed);
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;
size_t nc_off = 0;
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);
}
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 + 0x008, tag + 0x080, 0x020);
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);
}
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 + 0x080, intl + 0x008, 0x020);
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);
}
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];
nfc3d_keygen_derivedkeys dataKeys;
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;
}
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];
nfc3d_keygen_derivedkeys tagKeys;
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);
}
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");
if (!f) {
return false;
@ -152,7 +160,8 @@ bool nfc3d_amiibo_load_keys(nfc3d_amiibo_keys * amiiboKeys, const char * path) {
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);

View file

@ -14,7 +14,8 @@
static char *self;
void amiitool_usage() {
void amiitool_usage()
{
fprintf(stderr,
"amiitool build %i (commit %s-%08x)\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)) {
PrintAndLogEx(ERR, "Could not load keys from '%s'", keyfile);
@ -41,7 +43,8 @@ static bool LoadAmiikey(nfc3d_amiibo_keys keys, char* keyfile) {
return true;
}
int main(int argc, char ** argv) {
int main(int argc, char **argv)
{
self = argv[0];
char *infile = NULL;

View file

@ -10,7 +10,8 @@
#include <string.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(hmacKey != 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);
}
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(output != NULL);
@ -51,12 +53,14 @@ void nfc3d_drbg_step(nfc3d_drbg_ctx * ctx, uint8_t * 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);
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];
nfc3d_drbg_ctx rngCtx;

View file

@ -10,7 +10,8 @@
#include <stdio.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(baseSeed != NULL);
assert(output != NULL);
@ -44,7 +45,8 @@ void nfc3d_keygen_prepare_seed(const nfc3d_keygen_masterkeys * baseKeys, const u
*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];
size_t preparedSeedSize;

View file

@ -19,8 +19,7 @@
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");
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
/* bit masks for arg_hdr.flag */
enum
{
enum {
ARG_TERMINATOR = 0x1,
ARG_HASVALUE = 0x2,
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
* constructor and left unaltered.
*/
struct arg_hdr
{
struct arg_hdr {
char flag; /* Modifier flags: ARG_TERMINATOR, ARG_HASVALUE. */
const char *shortopts; /* String defining the short 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 */
};
struct arg_rem
{
struct arg_rem {
struct arg_hdr hdr; /* The mandatory argtable header struct */
};
struct arg_lit
{
struct arg_lit {
struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of matching command line args */
};
struct arg_int
{
struct arg_int {
struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of matching command line args */
int *ival; /* Array of parsed argument values */
};
struct arg_dbl
{
struct arg_dbl {
struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of matching command line args */
double *dval; /* Array of parsed argument values */
};
struct arg_str
{
struct arg_str {
struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of matching command line args */
const char **sval; /* Array of parsed argument values */
};
struct arg_rex
{
struct arg_rex {
struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of matching command line args */
const char **sval; /* Array of parsed argument values */
};
struct arg_file
{
struct arg_file {
struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of matching command line args*/
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) */
};
struct arg_date
{
struct arg_date {
struct arg_hdr hdr; /* The mandatory argtable header struct */
const char *format; /* strptime format string used to parse the date */
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};
struct arg_end
{
struct arg_end {
struct arg_hdr hdr; /* The mandatory argtable header struct */
int count; /* Number of errors encountered */
int *error; /* Array of error codes */

View file

@ -19,7 +19,8 @@ char *programHint = NULL;
char *programHelp = NULL;
char buf[500] = {0};
int CLIParserInit(char *vprogramName, char *vprogramHint, char *vprogramHelp) {
int CLIParserInit(char *vprogramName, char *vprogramHint, char *vprogramHelp)
{
argtable = NULL;
argtableLen = 0;
programName = vprogramName;
@ -30,7 +31,8 @@ int CLIParserInit(char *vprogramName, char *vprogramHint, char *vprogramHelp) {
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;
argtable = vargtable;
@ -79,11 +81,13 @@ enum ParserState {
#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);
}
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;
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);
}
void CLIParserFree() {
void CLIParserFree()
{
arg_freetable(argtable, argtableLen);
argtable = NULL;
@ -151,7 +156,8 @@ void CLIParserFree() {
}
// 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;
int ibuf = 0;
@ -175,7 +181,8 @@ int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int
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;
if (!argstr->count)
return 0;

View file

@ -11,7 +11,8 @@
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, "needed to generate that LRC with a rolling XOR. All bytes should be specified in HEX.");
PrintAndLogEx(NORMAL, "");
@ -25,7 +26,8 @@ int usage_analyse_lcr(void) {
PrintAndLogEx(NORMAL, "expected output: Target (BA) requires final LRC XOR byte value: 5A");
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, "Finally compute ones' complement of the least significant bytes");
PrintAndLogEx(NORMAL, "");
@ -41,7 +43,8 @@ int usage_analyse_checksum(void) {
PrintAndLogEx(NORMAL, "expected output: 0x61");
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, "");
PrintAndLogEx(NORMAL, "Usage: analyse crc [h] <bytes>");
@ -53,7 +56,8 @@ int usage_analyse_crc(void){
PrintAndLogEx(NORMAL, " analyse crc 137AF00A0A0D");
return 0;
}
int usage_analyse_nuid(void){
int usage_analyse_nuid(void)
{
PrintAndLogEx(NORMAL, "Generate 4byte NUID from 7byte UID");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: analyse hid [h] <bytes>");
@ -65,7 +69,8 @@ int usage_analyse_nuid(void){
PrintAndLogEx(NORMAL, " analyse nuid 11223344556677");
return 0;
}
int usage_analyse_a(void) {
int usage_analyse_a(void)
{
PrintAndLogEx(NORMAL, "Iceman's personal garbage test command");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: analyse a [h] d <bytes>");
@ -78,7 +83,8 @@ int usage_analyse_a(void) {
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;
for (uint8_t i = 0; i < len; i++)
LRC ^= bytes[i];
@ -102,7 +108,8 @@ static uint16_t shiftadd ( uint8_t* bytes, uint8_t len){
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;
for (uint8_t i = 0; i < len; i++) {
sum += CRUMB(bytes[i], 0);
@ -113,10 +120,12 @@ static uint16_t calcSumCrumbAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
sum &= mask;
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);
}
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;
for (uint8_t i = 0; i < len; 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;
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);
}
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;
for (uint8_t i = 0; i < len; i++) {
sum ^= CRUMB(bytes[i], 0);
@ -139,7 +150,8 @@ static uint16_t calcSumCrumbXor( uint8_t* bytes, uint8_t len, uint32_t mask) {
sum &= mask;
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;
for (uint8_t i = 0; i < len; 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;
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;
for (uint8_t i = 0; i < len; i++) {
sum ^= bytes[i];
@ -156,7 +169,8 @@ static uint16_t calcSumByteXor( uint8_t* bytes, uint8_t len, uint32_t mask) {
sum &= mask;
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;
for (uint8_t i = 0; i < len; i++) {
sum += bytes[i];
@ -165,11 +179,13 @@ static uint16_t calcSumByteAdd( uint8_t* bytes, uint8_t len, uint32_t mask) {
return sum;
}
// 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);
}
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;
for (uint8_t i = 0; i < len; i++) {
sum -= bytes[i];
@ -177,10 +193,12 @@ static uint16_t calcSumByteSub( uint8_t* bytes, uint8_t len, uint32_t mask) {
sum &= mask;
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);
}
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;
for (uint8_t i = 0; i < len; 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;
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);
}
// 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;
for (uint8_t i = 0; i < len; i++) {
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;
}
// 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;
for (uint8_t i = 0; i < len; i++) {
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
int CmdAnalyseLfsr(const char *Cmd){
int CmdAnalyseLfsr(const char *Cmd)
{
uint16_t start_state = 0; /* Any nonzero start state will work. */
uint16_t lfsr = start_state;
@ -242,7 +264,8 @@ int CmdAnalyseLfsr(const char *Cmd){
}
return 0;
}
int CmdAnalyseLCR(const char *Cmd) {
int CmdAnalyseLCR(const char *Cmd)
{
uint8_t data[50];
char cmdp = tolower(param_getchar(Cmd, 0));
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);
return 0;
}
int CmdAnalyseCRC(const char *Cmd) {
int CmdAnalyseCRC(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_analyse_crc();
@ -359,7 +383,8 @@ int CmdAnalyseCRC(const char *Cmd) {
free(data);
return 0;
}
int CmdAnalyseCHKSUM(const char *Cmd){
int CmdAnalyseCHKSUM(const char *Cmd)
{
uint8_t data[50];
uint8_t cmdp = 0;
@ -425,12 +450,14 @@ int CmdAnalyseCHKSUM(const char *Cmd){
return 0;
}
int CmdAnalyseDates(const char *Cmd){
int CmdAnalyseDates(const char *Cmd)
{
// look for datestamps in a given array of bytes
PrintAndLogEx(NORMAL, "To be implemented. Feel free to contribute!");
return 0;
}
int CmdAnalyseTEASelfTest(const char *Cmd){
int CmdAnalyseTEASelfTest(const char *Cmd)
{
uint8_t v[8], v_le[8];
memset(v, 0x00, sizeof(v));
@ -465,7 +492,8 @@ int CmdAnalyseTEASelfTest(const char *Cmd){
return 0;
}
char* pb(uint32_t b) {
char *pb(uint32_t b)
{
static char buf1[33] = {0};
static char buf2[33] = {0};
static char *s;
@ -485,7 +513,8 @@ char* pb(uint32_t b) {
return s;
}
int CmdAnalyseA(const char *Cmd){
int CmdAnalyseA(const char *Cmd)
{
int hexlen = 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);
switch (keycountA) {
case 0: PrintAndLogEx(FAILED, "Key test A failed\n"); break;
case 1: PrintAndLogEx(SUCCESS, "KEY A | %012" PRIX64 " ", keylistA[0]); break;
case 0:
PrintAndLogEx(FAILED, "Key test A failed\n");
break;
case 1:
PrintAndLogEx(SUCCESS, "KEY A | %012" PRIX64 " ", keylistA[0]);
break;
}
switch (keycountB) {
case 0: PrintAndLogEx(FAILED, "Key test B failed\n"); break;
case 1: PrintAndLogEx(SUCCESS, "KEY B | %012" PRIX64 " ", keylistB[0]); break;
case 0:
PrintAndLogEx(FAILED, "Key test B failed\n");
break;
case 1:
PrintAndLogEx(SUCCESS, "KEY B | %012" PRIX64 " ", keylistB[0]);
break;
}
free(keylistA);
@ -843,7 +880,8 @@ uint64_t d2[] = {0x6e442129, 0x8f699195, 0x0000004, 0, 0x00040f0f0305030e};
return 0;
}
void generate4bNUID(uint8_t *uid, uint8_t *nuid){
void generate4bNUID(uint8_t *uid, uint8_t *nuid)
{
uint16_t crc;
uint8_t b1, b2;
@ -857,7 +895,8 @@ void generate4bNUID(uint8_t *uid, uint8_t *nuid){
nuid[3] = crc & 0xFF;
}
int CmdAnalyseNuid(const char *Cmd){
int CmdAnalyseNuid(const char *Cmd)
{
uint8_t nuid[4] = {0};
uint8_t uid[7] = {0};
int len = 0;
@ -903,13 +942,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdAnalyse(const char *Cmd) {
int CmdAnalyse(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -11,7 +11,8 @@
#define MAX_ARGS 20
int split(char *str, char *arr[MAX_ARGS]){
int split(char *str, char *arr[MAX_ARGS])
{
int beginIndex = 0;
int endIndex;
int maxWords = MAX_ARGS;
@ -39,7 +40,8 @@ int split(char *str, char *arr[MAX_ARGS]){
return wordCnt;
}
int CmdCrc(const char *Cmd) {
int CmdCrc(const char *Cmd)
{
char name[] = {"reveng "};
char Cmd2[100 + 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
// 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 */
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
// l = little endian input and output, L = little endian output only, t = left justified}
//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 */
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
int CmdrevengTestC(const char *Cmd){
int CmdrevengTestC(const char *Cmd)
{
int cmdp = 0;
char inModel[30] = {0x00};
char inHexStr[30] = {0x00};
@ -387,7 +392,8 @@ int CmdrevengTestC(const char *Cmd){
}
//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));
for (uint8_t block = 0; block < (uint8_t)(len / blockSize); block++) {
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)
int CmdrevengSearch(const char *Cmd){
int CmdrevengSearch(const char *Cmd)
{
#define NMODELS 105

View file

@ -17,7 +17,8 @@ int g_DemodClock = 0;
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, "Options:");
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");
return 0;
}
int usage_data_manrawdecode(void){
int usage_data_manrawdecode(void)
{
PrintAndLogEx(NORMAL, "Usage: data manrawdecode [invert] [maxErr]");
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)");
@ -36,7 +38,8 @@ int usage_data_manrawdecode(void){
PrintAndLogEx(NORMAL, " Example: data manrawdecode = decode manchester bitstream from the demodbuffer");
return 0;
}
int usage_data_biphaserawdecode(void){
int usage_data_biphaserawdecode(void)
{
PrintAndLogEx(NORMAL, "Usage: data biphaserawdecode [offset] [invert] [maxErr]");
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)");
@ -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");
return 0;
}
int usage_data_rawdemod(void){
int usage_data_rawdemod(void)
{
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, " '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");
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, " ['s'] optional, check for Sequence Terminator");
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");
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, " [offset], offset to begin biphase, default=0");
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");
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, " [set clock as integer] optional, if not set, autodetect");
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");
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, " [set clock as integer] optional, omit for autodetect.");
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");
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, " [set clock as integer] optional, if not set, autodetect.");
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");
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, " [set clock as integer] optional, if not set, autodetect.");
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");
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, " [set clock as integer] optional, if not set, autodetect.");
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");
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, "Usage: data autocorr w <window> [g]");
PrintAndLogEx(NORMAL, "Options:");
@ -187,7 +199,8 @@ int usage_data_autocorr(void) {
PrintAndLogEx(NORMAL, " g save back to GraphBuffer (overwrite)");
return 0;
}
int usage_data_undecimate(void){
int usage_data_undecimate(void)
{
PrintAndLogEx(NORMAL, "Usage: data undec [factor]");
PrintAndLogEx(NORMAL, "This function performs un-decimation, by repeating each sample N times");
PrintAndLogEx(NORMAL, "Options:");
@ -196,7 +209,8 @@ int usage_data_undecimate(void){
PrintAndLogEx(NORMAL, "Example: 'data undec 3'");
return 0;
}
int usage_data_detectclock(void){
int usage_data_detectclock(void)
{
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, " <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");
return 0;
}
int usage_data_hex2bin(void){
int usage_data_hex2bin(void)
{
PrintAndLogEx(NORMAL, "Usage: data hex2bin <hex_digits>");
PrintAndLogEx(NORMAL, " This function will ignore all non-hexadecimal characters (but stop reading on whitespace)");
return 0;
}
int usage_data_bin2hex(void){
int usage_data_bin2hex(void)
{
PrintAndLogEx(NORMAL, "Usage: data bin2hex <binary_digits>");
PrintAndLogEx(NORMAL, " This function will ignore all characters not 1 or 0 (but stop reading on whitespace)");
return 0;
}
int usage_data_buffclear(void){
int usage_data_buffclear(void)
{
PrintAndLogEx(NORMAL, "This function clears the bigbuff on deviceside");
PrintAndLogEx(NORMAL, "Usage: data buffclear [h]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h This help");
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, "Options:");
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)
//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 (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;
}
bool getDemodBuf(uint8_t *buf, size_t *size) {
bool getDemodBuf(uint8_t *buf, size_t *size)
{
if (buf == NULL) return false;
if (size == NULL) return false;
if (*size == 0) return false;
@ -262,35 +282,41 @@ bool getDemodBuf(uint8_t *buf, size_t *size) {
// include <math.h>
// Root mean square
double rms(double *v, size_t n) {
double rms(double *v, size_t n)
{
double sum = 0.0;
for (size_t i = 0; i < n; i++)
sum += v[i] * v[i];
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)
return -1;
else
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)
return -1;
else
return *(const uint8_t *)a > *(const uint8_t *)b;
}
// 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);
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);
return 0.5 * (src[size / 2] + src[(size - 1) / 2]);
}
// 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;
for (size_t i = 0; i < n; 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
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 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
void save_restoreDB(uint8_t saveOpt) {
void save_restoreDB(uint8_t saveOpt)
{
static uint8_t SavedDB[MAX_DEMOD_BUF_LEN];
static size_t SavedDBlen;
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;
sscanf(Cmd, "%i", &demod);
g_debugMode = (uint8_t)demod;
@ -367,7 +396,8 @@ int CmdSetDebugMode(const char *Cmd) {
//by marshmellow
// max output to 512 bits if we have more - should be plenty
void printDemodBuff(void) {
void printDemodBuff(void)
{
int len = DemodBufferLen;
if (len < 1) {
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));
}
int CmdPrintDemodBuff(const char *Cmd) {
int CmdPrintDemodBuff(const char *Cmd)
{
char hex[512] = {0x00};
bool hexMode = false;
bool errors = false;
@ -435,7 +466,8 @@ int CmdPrintDemodBuff(const char *Cmd) {
//by marshmellow
//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);
for (uint32_t i = 0; i < GraphTraceLen; i++)
GraphBuffer[i] = (GraphBuffer[i] >= 1) ? 1 : 0;
@ -450,7 +482,8 @@ int CmdGetBitStream(const char *Cmd) {
//verbose will print results and demoding messages
//emSearch will auto search for EM410x format in bitstream
//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 clk = 0;
int maxErr = 100;
@ -536,7 +569,8 @@ int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType,
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;
return ASKDemod_ext(Cmd, verbose, emSearch, askType, &st);
}
@ -562,7 +596,8 @@ int Cmdaskmandemod(const char *Cmd)
//by marshmellow
//manchester decode
//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;
int high = 0, low = 0;
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
// 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]
int CmdBiphaseDecodeRaw(const char *Cmd) {
int CmdBiphaseDecodeRaw(const char *Cmd)
{
size_t size = 0;
int offset = 0, invert = 0, maxErr = 20, errCnt = 0;
char cmdp = tolower(param_getchar(Cmd, 0));
@ -716,7 +752,8 @@ int Cmdaskrawdemod(const char *Cmd)
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
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) {
setClockGrid(distance, idx);
retval = distance;
}
else
} else
setClockGrid(correlation, idx);
CursorCPos = idx_1;
@ -803,7 +839,8 @@ int AutoCorrelate(const int *in, int *out, size_t len, int window, bool SaveGrph
return retval;
}
int CmdAutoCorr(const char *Cmd) {
int CmdAutoCorr(const char *Cmd)
{
uint32_t window = 4000;
uint8_t cmdp = 0;
@ -899,8 +936,7 @@ int CmdUndec(const char *Cmd)
//We have memory, don't we?
int swap[MAX_GRAPH_TRACE_LEN] = {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;
for (count = 0; count < factor && s_index + count < MAX_GRAPH_TRACE_LEN; count++)
swap[s_index + count] = GraphBuffer[g_index];
@ -916,7 +952,8 @@ int CmdUndec(const char *Cmd)
//by marshmellow
//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;
//set options from parameters entered with the command
sscanf(Cmd, "%i", &shift);
@ -937,7 +974,8 @@ int CmdGraphShiftZero(const char *Cmd) {
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;
for (int i = 1; i < len; i++) {
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
//similar to dirtheshold, threshold commands
//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 ans = 0;
sscanf(Cmd, "%i", &thresLen);
@ -966,7 +1005,8 @@ int CmdAskEdgeDetect(const char *Cmd) {
/* Print our clock rate */
// uses data from graphbuffer
// 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));
if (strlen(Cmd) > 6 || strlen(Cmd) == 0 || cmdp == 'h')
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
//takes 4 arguments - Clock, invert, fchigh, fclow
//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
uint8_t rfLen, invert, fchigh, fclow;
@ -1089,7 +1130,8 @@ int FSKrawDemod(const char *Cmd, bool verbose) {
//fsk raw demod and print binary
//takes 4 arguments - Clock, invert, fchigh, fclow
//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));
if (strlen(Cmd) > 20 || cmdp == 'h') return usage_data_rawdemod_fs();
@ -1098,7 +1140,8 @@ int CmdFSKrawdemod(const char *Cmd) {
//by marshmellow
//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;
sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr);
if (clk == 1) {
@ -1139,7 +1182,8 @@ int PSKDemod(const char *Cmd, bool verbose) {
return 1;
}
int CmdPSKIdteck(const char *Cmd) {
int CmdPSKIdteck(const char *Cmd)
{
if (!PSKDemod("", false)) {
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck PSKDemod failed");
@ -1203,7 +1247,8 @@ int CmdPSKIdteck(const char *Cmd) {
// takes 3 arguments - clock, invert, maxErr as integers
// attempts to demodulate nrz only
// 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 invert = 0, clk = 0, maxErr = 100;
@ -1250,7 +1295,8 @@ int NRZrawDemod(const char *Cmd, bool verbose) {
return 1;
}
int CmdNRZrawDemod(const char *Cmd) {
int CmdNRZrawDemod(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
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
// attempts to demodulate psk only
// 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));
if (strlen(Cmd) > 16 || cmdp == 'h') return usage_data_rawdemod_p1();
@ -1279,7 +1326,8 @@ int CmdPSK1rawDemod(const char *Cmd) {
// by marshmellow
// takes same args as cmdpsk1rawdemod
int CmdPSK2rawDemod(const char *Cmd) {
int CmdPSK2rawDemod(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
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
int CmdRawDemod(const char *Cmd) {
int CmdRawDemod(const char *Cmd)
{
int ans = 0;
if (strlen(Cmd) > 35 || strlen(Cmd) < 2)
@ -1316,7 +1365,8 @@ int CmdRawDemod(const char *Cmd) {
return ans;
}
void setClockGrid(int clk, int offset) {
void setClockGrid(int clk, int offset)
{
g_DemodStartIdx = offset;
g_DemodClock = 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);
PlotGridXdefault = PlotGridX;
PlotGridYdefault = PlotGridY;
@ -1348,13 +1399,15 @@ int CmdGrid(const char *Cmd) {
return 0;
}
int CmdSetGraphMarkers(const char *Cmd) {
int CmdSetGraphMarkers(const char *Cmd)
{
sscanf(Cmd, "%i %i", &CursorCPos, &CursorDPos);
RepaintGraphWindow();
return 0;
}
int CmdHexsamples(const char *Cmd) {
int CmdHexsamples(const char *Cmd)
{
int i, j, requested = 0, offset = 0;
char string_buf[25];
char *string_ptr = string_buf;
@ -1396,13 +1449,15 @@ int CmdHexsamples(const char *Cmd) {
return 0;
}
int CmdHide(const char *Cmd) {
int CmdHide(const char *Cmd)
{
HideGraphWindow();
return 0;
}
//zero mean GraphBuffer
int CmdHpf(const char *Cmd) {
int CmdHpf(const char *Cmd)
{
uint8_t bits[GraphTraceLen];
size_t size = getFromGraphBuf(bits);
removeSignalOffset(bits, size);
@ -1415,13 +1470,15 @@ int CmdHpf(const char *Cmd) {
return 0;
}
bool _headBit( BitstreamOut *stream) {
bool _headBit(BitstreamOut *stream)
{
int bytepos = stream->position >> 3; // divide by 8
int bitpos = (stream->position++) & 7; // mask out 00000111
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;
for (int i = 0 ; i < bits_per_sample; i++)
val |= (_headBit(b) << (7 - i));
@ -1429,7 +1486,8 @@ uint8_t getByte(uint8_t bits_per_sample, BitstreamOut* b) {
return val;
}
int getSamples(int n, bool silent) {
int getSamples(int n, bool silent)
{
//If we get all but the last byte in bigbuf,
// we don't have to worry about remaining trash
// in the last byte in case the bits-per-sample
@ -1490,12 +1548,14 @@ int getSamples(int n, bool silent) {
return 0;
}
int CmdSamples(const char *Cmd) {
int CmdSamples(const char *Cmd)
{
int n = strtol(Cmd, NULL, 0);
return getSamples(n, false);
}
int CmdTuneSamples(const char *Cmd) {
int CmdTuneSamples(const char *Cmd)
{
#define NON_VOLTAGE 1000
#define LF_UNUSABLE_V 2000
#define LF_MARGINAL_V 10000
@ -1518,7 +1578,8 @@ int CmdTuneSamples(const char *Cmd) {
UsbCommand resp;
while (!WaitForResponseTimeout(CMD_MEASURED_ANTENNA_TUNING, &resp, 2000)) {
timeout++;
printf("."); fflush(stdout);
printf(".");
fflush(stdout);
if (timeout > 7) {
PrintAndLogEx(WARNING, "\nno response from Proxmark. Aborting...");
return 1;
@ -1593,7 +1654,8 @@ int CmdTuneSamples(const char *Cmd) {
return 0;
}
int CmdLoad(const char *Cmd) {
int CmdLoad(const char *Cmd)
{
char filename[FILE_PATH_SIZE] = {0x00};
int len = 0;
@ -1636,7 +1698,8 @@ int CmdLoad(const char *Cmd) {
}
// trim graph from the end
int CmdLtrim(const char *Cmd) {
int CmdLtrim(const char *Cmd)
{
// sanitycheck
if (GraphTraceLen <= 0) return 1;
@ -1650,7 +1713,8 @@ int CmdLtrim(const char *Cmd) {
}
// trim graph from the beginning
int CmdRtrim(const char *Cmd) {
int CmdRtrim(const char *Cmd)
{
int ds = atoi(Cmd);
@ -1663,7 +1727,8 @@ int CmdRtrim(const char *Cmd) {
}
// trim graph (middle) piece
int CmdMtrim(const char *Cmd) {
int CmdMtrim(const char *Cmd)
{
int start = 0, stop = 0;
sscanf(Cmd, "%i %i", &start, &stop);
@ -1679,7 +1744,8 @@ int CmdMtrim(const char *Cmd) {
return 0;
}
int CmdNorm(const char *Cmd) {
int CmdNorm(const char *Cmd)
{
int i;
int max = INT_MIN, min = INT_MAX;
@ -1705,12 +1771,14 @@ int CmdNorm(const char *Cmd) {
return 0;
}
int CmdPlot(const char *Cmd) {
int CmdPlot(const char *Cmd)
{
ShowGraphWindow();
return 0;
}
int CmdSave(const char *Cmd) {
int CmdSave(const char *Cmd)
{
int len = 0;
char filename[FILE_PATH_SIZE] = {0x00};
@ -1735,7 +1803,8 @@ int CmdSave(const char *Cmd) {
return 0;
}
int CmdScale(const char *Cmd) {
int CmdScale(const char *Cmd)
{
CursorScaleFactor = atoi(Cmd);
if (CursorScaleFactor == 0) {
PrintAndLogEx(FAILED, "bad, can't have zero scale");
@ -1745,7 +1814,8 @@ int CmdScale(const char *Cmd) {
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];
@ -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) {
// 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.
out[i] = 1;
}
// 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.
out[i] = -1;
}
else
{
} else {
lastValue = out[i]; // Buffer last value as we overwrite it.
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;
}
int CmdDirectionalThreshold(const char *Cmd) {
int CmdDirectionalThreshold(const char *Cmd)
{
int8_t up = param_get8(Cmd, 0);
int8_t down = param_get8(Cmd, 1);
@ -1796,7 +1863,8 @@ int CmdDirectionalThreshold(const char *Cmd) {
return 0;
}
int CmdZerocrossings(const char *Cmd) {
int CmdZerocrossings(const char *Cmd)
{
// Zero-crossings aren't meaningful unless the signal is zero-mean.
CmdHpf("");
@ -1832,7 +1900,8 @@ int CmdZerocrossings(const char *Cmd) {
* @param Cmd
* @return
*/
int Cmdbin2hex(const char *Cmd) {
int Cmdbin2hex(const char *Cmd)
{
int bg = 0, en = 0;
if (param_getptr(Cmd, &bg, &en, 0))
return usage_data_bin2hex();
@ -1862,7 +1931,8 @@ int Cmdbin2hex(const char *Cmd) {
return 0;
}
int Cmdhex2bin(const char *Cmd) {
int Cmdhex2bin(const char *Cmd)
{
int bg = 0, en = 0;
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
};
*/
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 Left_Modifier = ((clk % LowToneFC) % 2) + ((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
//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;
if (clk == 0 || LowToneFC == 0 || HighToneFC == 0) {
int firstClockEdge = 0;
@ -2030,7 +2102,8 @@ int FSKToNRZ(int *data, int *dataLen, int clk, int LowToneFC, int HighToneFC) {
return 0;
}
int CmdFSKToNRZ(const char *Cmd) {
int CmdFSKToNRZ(const char *Cmd)
{
// take clk, fc_low, fc_high
// blank = auto;
bool errors = false;
@ -2070,7 +2143,8 @@ int CmdFSKToNRZ(const char *Cmd) {
return ans;
}
int CmdDataIIR(const char *Cmd){
int CmdDataIIR(const char *Cmd)
{
uint8_t k = param_get8(Cmd, 0);
//iceIIR_Butterworth(GraphBuffer, GraphTraceLen);
iceSimple_Filter(GraphBuffer, GraphTraceLen, k);
@ -2124,13 +2198,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdData(const char *Cmd) {
int CmdData(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -26,7 +26,8 @@
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, "Options:");
PrintAndLogEx(NORMAL, " h this help");
@ -40,7 +41,8 @@ int usage_flashmem_spibaud(void){
return 0;
}
int usage_flashmem_read(void){
int usage_flashmem_read(void)
{
PrintAndLogEx(NORMAL, "Read flash memory on device");
PrintAndLogEx(NORMAL, "Usage: mem read o <offset> l <len>");
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
return 0;
}
int usage_flashmem_load(void){
int usage_flashmem_load(void)
{
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, " o <offset> : offset in memory");
@ -68,7 +71,8 @@ int usage_flashmem_load(void){
PrintAndLogEx(NORMAL, " mem load f default_iclass_keys i");
return 0;
}
int usage_flashmem_save(void){
int usage_flashmem_save(void)
{
PrintAndLogEx(NORMAL, "Saves flash memory on device into the file");
PrintAndLogEx(NORMAL, " Usage: mem save o <offset> l <length> f <file name>");
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
return 0;
}
int usage_flashmem_wipe(void){
int usage_flashmem_wipe(void)
{
PrintAndLogEx(WARNING, "[OBS] use with caution.");
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.
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, " Usage: mem info [h|s|w]");
PrintAndLogEx(NORMAL, " s : create a signature");
@ -107,7 +113,8 @@ int usage_flashmem_info(void){
return 0;
}
int CmdFlashMemRead(const char *Cmd) {
int CmdFlashMemRead(const char *Cmd)
{
uint8_t cmdp = 0;
bool errors = false;
@ -146,7 +153,8 @@ int CmdFlashMemRead(const char *Cmd) {
return 0;
}
int CmdFlashmemSpiBaudrate(const char *Cmd) {
int CmdFlashmemSpiBaudrate(const char *Cmd)
{
char ctmp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || ctmp == 'h') return usage_flashmem_spibaud();
@ -158,7 +166,8 @@ int CmdFlashmemSpiBaudrate(const char *Cmd) {
return 0;
}
int CmdFlashMemLoad(const char *Cmd){
int CmdFlashMemLoad(const char *Cmd)
{
uint32_t start_index = 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);
return 0;
}
int CmdFlashMemSave(const char *Cmd){
int CmdFlashMemSave(const char *Cmd)
{
char filename[FILE_PATH_SIZE] = {0};
uint8_t cmdp = 0;
@ -304,7 +314,8 @@ int CmdFlashMemSave(const char *Cmd){
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h': return usage_flashmem_save();
case 'h':
return usage_flashmem_save();
case 'l':
len = param_get32ex(Cmd, cmdp + 1, FLASH_MEM_MAX_SIZE, 10);
cmdp += 2;
@ -350,7 +361,8 @@ int CmdFlashMemSave(const char *Cmd){
free(dump);
return 0;
}
int CmdFlashMemWipe(const char *Cmd){
int CmdFlashMemWipe(const char *Cmd)
{
uint8_t cmdp = 0;
bool errors = false;
@ -358,7 +370,8 @@ int CmdFlashMemWipe(const char *Cmd){
uint8_t page = 0;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h': return usage_flashmem_wipe();
case 'h':
return usage_flashmem_wipe();
case 'p':
page = param_get8ex(Cmd, cmdp + 1, 0, 10);
if (page > 2) {
@ -398,7 +411,8 @@ int CmdFlashMemWipe(const char *Cmd){
return 0;
}
int CmdFlashMemInfo(const char *Cmd){
int CmdFlashMemInfo(const char *Cmd)
{
uint8_t sha_hash[20] = {0};
mbedtls_rsa_context rsa;
@ -407,7 +421,8 @@ int CmdFlashMemInfo(const char *Cmd){
bool errors = false, shall_write = false, shall_sign = false;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h': return usage_flashmem_info();
case 'h':
return usage_flashmem_info();
case 's': {
shall_sign = true;
cmdp++;
@ -597,13 +612,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdFlashMem(const char *Cmd) {
int CmdFlashMem(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -12,7 +12,8 @@
static int CmdHelp(const char *Cmd);
int usage_hf_search(){
int 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, "Options:");
@ -20,7 +21,8 @@ int usage_hf_search(){
PrintAndLogEx(NORMAL, "");
return 0;
}
int usage_hf_snoop(){
int usage_hf_snoop()
{
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, "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;
}
int CmdHFSearch(const char *Cmd){
int CmdHFSearch(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_search();
@ -85,7 +88,8 @@ int CmdHFSearch(const char *Cmd){
return 0;
}
int CmdHFTune(const char *Cmd) {
int CmdHFTune(const char *Cmd)
{
PrintAndLogEx(SUCCESS, "Measuring HF antenna, press button to exit");
UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING_HF};
clearCommandBuffer();
@ -93,7 +97,8 @@ int CmdHFTune(const char *Cmd) {
return 0;
}
int CmdHFSnoop(const char *Cmd) {
int CmdHFSnoop(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_snoop();
@ -128,13 +133,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdHF(const char *Cmd) {
int CmdHF(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -136,7 +136,8 @@ static const manufactureName manufactureMapping[] = {
// get a product description based on the UID
// uid[8] tag uid
// returns description of the best match
char* getTagInfo(uint8_t uid) {
char *getTagInfo(uint8_t uid)
{
int i;
int len = sizeof(manufactureMapping) / sizeof(manufactureName);
@ -153,7 +154,8 @@ char* getTagInfo(uint8_t uid) {
static uint16_t frameLength = 0;
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 byte UID\n");
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");
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, "Buffer accessible from command 'hf list 14a'");
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");
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, " -h this help");
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)");
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, " k keep the field active after command executed");
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)");
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, "Usage: hf 14a info [h|s]");
PrintAndLogEx(NORMAL, " s silent (no messages)");
@ -220,13 +226,15 @@ int usage_hf_14a_info(void){
return 0;
}
int CmdHF14AList(const char *Cmd) {
int CmdHF14AList(const char *Cmd)
{
//PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list 14a' instead");
CmdTraceList("14a");
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}};
SendCommand(&c);
@ -265,7 +273,8 @@ int Hf14443_4aGetCardData(iso14a_card_select_t * card) {
return 0;
}
int CmdHF14AReader(const char *Cmd) {
int CmdHF14AReader(const char *Cmd)
{
uint32_t cm = ISO14A_CONNECT;
bool disconnectAfter = true, silent = false;
@ -353,7 +362,8 @@ int CmdHF14AReader(const char *Cmd) {
return 0;
}
int CmdHF14AInfo(const char *Cmd) {
int CmdHF14AInfo(const char *Cmd)
{
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_hf_14a_info();
@ -430,21 +440,53 @@ int CmdHF14AInfo(const char *Cmd) {
return 0;
}
break;
case 0x01: PrintAndLogEx(NORMAL, "TYPE : NXP TNP3xxx Activision Game Appliance"); break;
case 0x04: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE (various !DESFire !DESFire EV1)"); isMifareClassic = false; break;
case 0x08: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1 | 1k Ev1"); break;
case 0x09: PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Mini 0.3k"); break;
case 0x0A: 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: ;
case 0x01:
PrintAndLogEx(NORMAL, "TYPE : NXP TNP3xxx Activision Game Appliance");
break;
case 0x04:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE (various !DESFire !DESFire EV1)");
isMifareClassic = false;
break;
case 0x08:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE CLASSIC 1k | Plus 2k SL1 | 1k Ev1");
break;
case 0x09:
PrintAndLogEx(NORMAL, "TYPE : NXP MIFARE Mini 0.3k");
break;
case 0x0A:
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.
@ -544,29 +586,59 @@ int CmdHF14AInfo(const char *Cmd) {
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]);
switch (card.ats[pos + 2] & 0xf0) {
case 0x10: PrintAndLogEx(NORMAL, " 1x -> MIFARE DESFire"); break;
case 0x20: PrintAndLogEx(NORMAL, " 2x -> MIFARE Plus"); break;
case 0x10:
PrintAndLogEx(NORMAL, " 1x -> MIFARE DESFire");
break;
case 0x20:
PrintAndLogEx(NORMAL, " 2x -> MIFARE Plus");
break;
}
switch (card.ats[pos + 2] & 0x0f) {
case 0x00: PrintAndLogEx(NORMAL, " x0 -> <1 kByte"); break;
case 0x01: 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;
case 0x00:
PrintAndLogEx(NORMAL, " x0 -> <1 kByte");
break;
case 0x01:
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) {
case 0x00: PrintAndLogEx(NORMAL, " 0x -> Engineering sample"); break;
case 0x20: PrintAndLogEx(NORMAL, " 2x -> Released"); break;
case 0x00:
PrintAndLogEx(NORMAL, " 0x -> Engineering sample");
break;
case 0x20:
PrintAndLogEx(NORMAL, " 2x -> Released");
break;
}
switch (card.ats[pos + 3] & 0x0f) {
case 0x00: PrintAndLogEx(NORMAL, " x0 -> Generation 1"); break;
case 0x01: PrintAndLogEx(NORMAL, " x1 -> Generation 2"); break;
case 0x02: PrintAndLogEx(NORMAL, " x2 -> Generation 3"); break;
case 0x00:
PrintAndLogEx(NORMAL, " x0 -> Generation 1");
break;
case 0x01:
PrintAndLogEx(NORMAL, " x1 -> Generation 2");
break;
case 0x02:
PrintAndLogEx(NORMAL, " x2 -> Generation 3");
break;
}
switch (card.ats[pos + 4] & 0x0f) {
case 0x00: PrintAndLogEx(NORMAL, " x0 -> Only VCSL supported"); break;
case 0x01: PrintAndLogEx(NORMAL, " x1 -> VCS, VCSL, and SVC supported"); break;
case 0x0E: PrintAndLogEx(NORMAL, " xE -> no VCS command supported"); break;
case 0x00:
PrintAndLogEx(NORMAL, " x0 -> Only VCSL supported");
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
int CmdHF14ACUIDs(const char *Cmd) {
int CmdHF14ACUIDs(const char *Cmd)
{
// requested number of UIDs
int n = atoi(Cmd);
// 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++) {
if (ukbhit()) {
int gc = getchar(); (void)gc;
int gc = getchar();
(void)gc;
PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n");
break;
}
@ -636,7 +710,8 @@ int CmdHF14ACUIDs(const char *Cmd) {
}
// ## simulate iso14443a tag
int CmdHF14ASim(const char *Cmd) {
int CmdHF14ASim(const char *Cmd)
{
bool errors = false;
uint8_t flags = 0;
uint8_t tagtype = 1;
@ -667,9 +742,15 @@ int CmdHF14ASim(const char *Cmd) {
param_gethex_ex(Cmd, cmdp + 1, uid, &uidlen);
switch (uidlen) {
//case 20: flags |= FLAG_10B_UID_IN_DATA; break;
case 14: flags |= FLAG_7B_UID_IN_DATA; break;
case 8: flags |= FLAG_4B_UID_IN_DATA; break;
default: errors = true; break;
case 14:
flags |= FLAG_7B_UID_IN_DATA;
break;
case 8:
flags |= FLAG_4B_UID_IN_DATA;
break;
default:
errors = true;
break;
}
if (!errors) {
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;
}
int CmdHF14ASniff(const char *Cmd) {
int CmdHF14ASniff(const char *Cmd)
{
int param = 0;
uint8_t ctmp;
for (int i = 0; i < 2; i++) {
@ -740,7 +822,8 @@ int CmdHF14ASniff(const char *Cmd) {
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;
uint16_t cmdc = 0;
*dataoutlen = 0;
@ -839,7 +922,8 @@ int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leav
return 0;
}
int SelectCard14443_4(bool disconnect, iso14a_card_select_t *card) {
int SelectCard14443_4(bool disconnect, iso14a_card_select_t *card)
{
UsbCommand resp;
frameLength = 0;
@ -909,7 +993,8 @@ int SelectCard14443_4(bool disconnect, iso14a_card_select_t *card) {
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;
if (activateField) {
@ -993,7 +1078,8 @@ int CmdExchangeAPDU(bool chainingin, uint8_t *datain, int datainlen, bool activa
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;
bool chaining = false;
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
int CmdHF14AAPDU(const char *cmd) {
int CmdHF14AAPDU(const char *cmd)
{
uint8_t data[USB_CMD_DATA_SIZE];
int datalen = 0;
bool activateField = false;
@ -1110,7 +1197,8 @@ CLIParserFree();
return 0;
}
int CmdHF14ACmdRaw(const char *cmd) {
int CmdHF14ACmdRaw(const char *cmd)
{
UsbCommand c = {CMD_READER_ISO_14443a, {0, 0, 0}};
bool reply = 1;
bool crc = false;
@ -1266,7 +1354,8 @@ int CmdHF14ACmdRaw(const char *cmd) {
return 0;
}
static int waitCmd(uint8_t iSelect) {
static int waitCmd(uint8_t iSelect)
{
UsbCommand resp;
uint16_t len = 0;
@ -1294,7 +1383,8 @@ static int waitCmd(uint8_t iSelect) {
return 0;
}
int CmdHF14AAntiFuzz(const char *cmd) {
int CmdHF14AAntiFuzz(const char *cmd)
{
CLIParserInit("hf 14a antifuzz",
"Tries to fuzz the ISO14443a anticollision phase",
@ -1323,7 +1413,8 @@ int CmdHF14AAntiFuzz(const char *cmd) {
return 0;
}
int CmdHF14AChaining(const char *cmd) {
int CmdHF14AChaining(const char *cmd)
{
CLIParserInit("hf 14a chaining",
"Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.",
@ -1369,13 +1460,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdHF14A(const char *Cmd) {
int CmdHF14A(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -14,7 +14,8 @@
#define TIMEOUT 2000
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, "Options:");
PrintAndLogEx(NORMAL, " h this help");
@ -23,7 +24,8 @@ int usage_hf_14b_info(void){
PrintAndLogEx(NORMAL, " hf 14b info");
return 0;
}
int usage_hf_14b_reader(void){
int usage_hf_14b_reader(void)
{
PrintAndLogEx(NORMAL, "Usage: hf 14b reader [h] [s]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h this help");
@ -32,7 +34,8 @@ int usage_hf_14b_reader(void){
PrintAndLogEx(NORMAL, " hf 14b reader");
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, "Options:");
PrintAndLogEx(NORMAL, " -h this help");
@ -45,7 +48,8 @@ int usage_hf_14b_raw(void){
PrintAndLogEx(NORMAL, " hf 14b raw -s -c -p 0200a40400");
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, "Buffer accessible from command 'hf list 14b'");
PrintAndLogEx(NORMAL, "Usage: hf 14b sniff [h]");
@ -55,7 +59,8 @@ int usage_hf_14b_sniff(void){
PrintAndLogEx(NORMAL, " hf 14b sniff");
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, "Usage: hf 14b sim [h] u <uid>");
PrintAndLogEx(NORMAL, "Options:");
@ -66,7 +71,8 @@ int usage_hf_14b_sim(void){
PrintAndLogEx(NORMAL, " hf 14b sim u 11223344");
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, "Options:");
PrintAndLogEx(NORMAL, " h this help");
@ -76,7 +82,8 @@ int usage_hf_14b_read_srx(void){
PrintAndLogEx(NORMAL, " hf 14b sriread 2");
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, "Options:");
PrintAndLogEx(NORMAL, " h this help");
@ -90,7 +97,8 @@ int usage_hf_14b_write_srx(void){
PrintAndLogEx(NORMAL, " hf 14b sriwrite 2 FF 11223344");
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"
"\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}};
clearCommandBuffer();
SendCommand(&c);
return 0;
}
int CmdHF14BList(const char *Cmd) {
int CmdHF14BList(const char *Cmd)
{
CmdTraceList("14b");
return 0;
}
int CmdHF14BSim(const char *Cmd) {
int CmdHF14BSim(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_14b_sim();
@ -140,7 +151,8 @@ int CmdHF14BSim(const char *Cmd) {
return 0;
}
int CmdHF14BSniff(const char *Cmd) {
int CmdHF14BSniff(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_14b_sniff();
@ -151,7 +163,8 @@ int CmdHF14BSniff(const char *Cmd) {
return 0;
}
int CmdHF14BCmdRaw (const char *Cmd) {
int CmdHF14BCmdRaw(const char *Cmd)
{
bool reply = true, power = false, select = false;
char buf[5] = "";
int i = 0;
@ -241,7 +254,8 @@ int CmdHF14BCmdRaw (const char *Cmd) {
return 1;
}
static bool get_14b_UID(iso14b_card_select_t *card) {
static bool get_14b_UID(iso14b_card_select_t *card)
{
if (!card)
return false;
@ -295,7 +309,8 @@ static bool get_14b_UID(iso14b_card_select_t *card) {
// 4 = bit rate capacity
// 5 = max frame size / -4 info
// 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, " App Data: %s", sprint_hex(data, 4));
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
char *get_ST_Chip_Model(uint8_t data){
char *get_ST_Chip_Model(uint8_t data)
{
static char model[20];
char *retStr = model;
memset(model, 0, sizeof(model));
switch (data) {
case 0x0: sprintf(retStr, "SRIX4K (Special)"); break;
case 0x2: sprintf(retStr, "SR176"); break;
case 0x3: 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;
case 0x0:
sprintf(retStr, "SRIX4K (Special)");
break;
case 0x2:
sprintf(retStr, "SR176");
break;
case 0x3:
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;
}
// REMAKE:
int print_ST_Lock_info(uint8_t model){
int print_ST_Lock_info(uint8_t model)
{
// PrintAndLogEx(NORMAL, "Chip Write Protection Bits:");
// // now interpret the data
@ -406,7 +439,8 @@ int print_ST_Lock_info(uint8_t model){
}
// 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
PrintAndLogEx(NORMAL, " UID: %s", sprint_hex(SwapEndian64(data, 8, 8), len));
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])
// 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;
@ -477,7 +512,8 @@ bool HF14B_Std_Info(bool verbose){
}
// 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}};
clearCommandBuffer();
@ -523,7 +559,8 @@ bool HF14B_ST_Info(bool verbose){
}
// get and print all info known about any known 14b tag
bool HF14BInfo(bool verbose){
bool HF14BInfo(bool verbose)
{
// try std 14b (atqb)
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
int CmdHF14Binfo(const char *Cmd){
int CmdHF14Binfo(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_14b_info();
@ -546,7 +584,8 @@ int CmdHF14Binfo(const char *Cmd){
return HF14BInfo(verbose);
}
bool HF14B_ST_Reader(bool verbose){
bool HF14B_ST_Reader(bool verbose)
{
bool isSuccess = false;
@ -586,7 +625,8 @@ bool HF14B_ST_Reader(bool verbose){
return isSuccess;
}
bool HF14B_Std_Reader(bool verbose){
bool HF14B_Std_Reader(bool verbose)
{
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)
bool HF14B_Other_Reader(){
bool HF14B_Other_Reader()
{
// uint8_t data[] = {0x00, 0x0b, 0x3f, 0x80};
// uint8_t datalen = 4;
@ -687,7 +728,8 @@ bool HF14B_Other_Reader(){
}
// get and print general info about all known 14b chips
bool HF14BReader(bool verbose){
bool HF14BReader(bool verbose)
{
// try std 14b (atqb)
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
int CmdHF14BReader(const char *Cmd){
int CmdHF14BReader(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
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,
* 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));
if (strlen(Cmd) < 1 || cmdp == 'h') return usage_hf_14b_read_srx();
@ -729,7 +773,8 @@ int CmdHF14BReadSri(const char *Cmd){
return 0;
}
// New command to write a SRI512/SRIX4K tag.
int CmdHF14BWriteSri(const char *Cmd){
int CmdHF14BWriteSri(const char *Cmd)
{
/*
* For SRIX4K blocks 00 - 7F
* hf 14b raw -c -p 09 $srix4kwblock $srix4kwdata
@ -796,7 +841,8 @@ int CmdHF14BWriteSri(const char *Cmd){
}
// need to write to file
int CmdHF14BDump(const char*Cmd) {
int CmdHF14BDump(const char *Cmd)
{
uint8_t fileNameLen = 0;
char filename[FILE_PATH_SIZE] = {0};
@ -918,7 +964,8 @@ int CmdHF14BDump(const char*Cmd) {
blocknum = 0xFF;
}
printf("."); fflush(stdout);
printf(".");
fflush(stdout);
}
}
@ -951,7 +998,8 @@ out:
return switch_off_field_14b();
}
uint32_t srix4kEncode(uint32_t value) {
uint32_t srix4kEncode(uint32_t value)
{
/*
// vv = value
// pp = position
@ -1007,21 +1055,27 @@ uint32_t srix4kEncode(uint32_t value) {
PrintAndLogEx(NORMAL, "ICE encoded | %08X -> %08X", value, encvalue);
return encvalue;
}
uint32_t srix4kDecode(uint32_t value) {
uint32_t srix4kDecode(uint32_t value)
{
switch (value) {
case 0xC04F42C5: return 0x003139;
case 0xC1484807: return 0x002943;
case 0xC0C60848: return 0x001A20;
case 0xC04F42C5:
return 0x003139;
case 0xC1484807:
return 0x002943;
case 0xC0C60848:
return 0x001A20;
}
return 0;
}
uint32_t srix4kDecodeCounter(uint32_t num) {
uint32_t srix4kDecodeCounter(uint32_t num)
{
uint32_t value = ~num;
++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;
uint32_t uid32 = uid & MASK;
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);
return result;
}
int srix4kValid(const char *Cmd){
int srix4kValid(const char *Cmd)
{
uint64_t uid = 0xD00202501A4532F9;
uint32_t block6 = 0xFFFFFFFF;
@ -1051,7 +1106,8 @@ int srix4kValid(const char *Cmd){
return 0;
}
bool waitCmd14b(bool verbose) {
bool waitCmd14b(bool verbose)
{
bool crc = false;
uint8_t data[USB_CMD_DATA_SIZE] = {0x00};
@ -1105,13 +1161,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdHF14B(const char *Cmd) {
int CmdHF14B(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
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)
// *buf should be large enough to fit the 64bit uid
// returns 1 if suceeded
int getUID(uint8_t *buf) {
int getUID(uint8_t *buf)
{
UsbCommand resp;
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
// uid[8] tag uid
// returns description of the best match
static char* getTagInfo_15(uint8_t *uid) {
static char *getTagInfo_15(uint8_t *uid)
{
uint64_t myuid, mask;
int i = 0, best = -1;
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
static char* TagErrorStr(uint8_t error) {
static char *TagErrorStr(uint8_t error)
{
switch (error) {
case 0x01: return "The command is not supported";
case 0x02: return "The command is not recognised";
case 0x03: return "The option is not supported.";
case 0x0f: return "Unknown error.";
case 0x10: 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.";
case 0x01:
return "The command is not supported";
case 0x02:
return "The command is not recognised";
case 0x03:
return "The option is not supported.";
case 0x0f:
return "Unknown error.";
case 0x10:
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"
"Gather samples with 'hf 15 read' / 'hf 15 record'");
return 0;
}
int usage_15_samples(void){
int usage_15_samples(void)
{
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");
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"
"command may fail, depending on tag.\n"
"defaults to '1 out of 4' mode\n"
@ -293,11 +309,13 @@ int usage_15_info(void){
"\thf 15 info u");
return 0;
}
int usage_15_record(void){
int usage_15_record(void)
{
PrintAndLogEx(NORMAL, "Record activity without enableing carrier");
return 0;
}
int usage_15_reader(void){
int usage_15_reader(void)
{
PrintAndLogEx(NORMAL, "This command identifies a ISO 15693 tag\n"
"\n"
"Usage: hf 15 reader [h]\n"
@ -308,18 +326,21 @@ int usage_15_reader(void){
"\thf 15 reader");
return 0;
}
int usage_15_sim(void){
int usage_15_sim(void)
{
PrintAndLogEx(NORMAL, "Usage: hf 15 sim <UID>\n"
"\n"
"Example:\n"
"\thf 15 sim E016240000000000");
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!");
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"
"\n"
"Usage: hf 15 dump [h] <f filname> \n"
@ -332,7 +353,8 @@ int usage_15_dump(void){
"\thf 15 dump f mydump");
return 0;
}
int usage_15_restore(void){
int usage_15_restore(void)
{
char *options[][2] = {
{"h", "this help"},
{"-2", "use slower '1 out of 256' mode"},
@ -346,7 +368,8 @@ int usage_15_restore(void){
PrintAndLogOptions(options, 7, 3);
return 0;
}
int usage_15_raw(void){
int usage_15_raw(void)
{
char *options[][2] = {
{"-r", "do not read response" },
{"-2", "use slower '1 out of 256' mode" },
@ -357,7 +380,8 @@ int usage_15_raw(void){
PrintAndLogOptions(options, 4, 3);
return 0;
}
int usage_15_read(void){
int usage_15_read(void)
{
PrintAndLogEx(NORMAL, "Usage: hf 15 read [options] <uid|s|u|*> <page#>\n"
"Options:\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");
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"
"Options:\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");
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"
"Options:\n"
"\t-2 use slower '1 out of 256' mode\n"
@ -395,7 +421,8 @@ int usage_15_readmulti(void){
}
// Mode 3
//helptext
int CmdHF15Demod(const char *Cmd) {
int CmdHF15Demod(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_15_demod();
@ -475,7 +502,8 @@ int CmdHF15Demod(const char *Cmd) {
// * Acquire Samples as Reader (enables carrier, sends inquiry)
//helptext
int CmdHF15Samples(const char *Cmd) {
int CmdHF15Samples(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_15_samples();
@ -491,7 +519,8 @@ int CmdHF15Samples(const char *Cmd) {
* Commandline handling: HF15 CMD SYSINFO
* get system information from tag/VICC
*/
int CmdHF15Info(const char *Cmd) {
int CmdHF15Info(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0);
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
//helptext
int CmdHF15Record(const char *Cmd) {
int CmdHF15Record(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_15_record();
@ -584,7 +614,8 @@ int CmdHF15Record(const char *Cmd) {
}
// 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};
if (!getUID(uid)) {
if (verbose) PrintAndLogEx(WARNING, "No tag found.");
@ -596,7 +627,8 @@ int HF15Reader(const char *Cmd, bool verbose) {
return 1;
}
int CmdHF15Reader(const char *Cmd) {
int CmdHF15Reader(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_15_reader();
@ -606,7 +638,8 @@ int CmdHF15Reader(const char *Cmd) {
// Simulation is still not working very good
// helptext
int CmdHF15Sim(const char *Cmd) {
int CmdHF15Sim(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
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
// (There is no standard way of reading the AFI, allthough some tags support this)
// helptext
int CmdHF15Afi(const char *Cmd) {
int CmdHF15Afi(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_15_findafi();
@ -647,7 +681,8 @@ typedef struct {
// Reads all memory pages
// need to write to file
int CmdHF15Dump(const char*Cmd) {
int CmdHF15Dump(const char *Cmd)
{
uint8_t fileNameLen = 0;
char filename[FILE_PATH_SIZE] = {0};
@ -744,7 +779,8 @@ int CmdHF15Dump(const char*Cmd) {
retry = 0;
blocknum++;
printf("."); fflush(stdout);
printf(".");
fflush(stdout);
}
}
PrintAndLogEx(NORMAL, "\n");
@ -762,7 +798,8 @@ int CmdHF15Dump(const char*Cmd) {
return 0;
}
int CmdHF15Restore(const char*Cmd) {
int CmdHF15Restore(const char *Cmd)
{
FILE *f;
uint8_t uid[8] = {0x00};
@ -781,8 +818,7 @@ int CmdHF15Restore(const char*Cmd) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case '-':
param_getstr(Cmd, cmdp, param, sizeof(param));
switch(param[1])
{
switch (param[1]) {
case '2':
case 'o':
strncpy(newCmdPrefix, " ", sizeof(newCmdPrefix) - 1);
@ -875,13 +911,15 @@ int CmdHF15Restore(const char*Cmd) {
fclose(f);
}
int CmdHF15List(const char *Cmd) {
int CmdHF15List(const char *Cmd)
{
//PrintAndLogEx(WARNING, "Deprecated command, use 'hf list 15' instead");
CmdTraceList("15");
return 0;
}
int CmdHF15Raw(const char *Cmd) {
int CmdHF15Raw(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') return usage_15_raw();
@ -968,7 +1006,8 @@ int CmdHF15Raw(const char *Cmd) {
* Parameters:
* **cmd command line
*/
int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd) {
int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd)
{
int temp;
uint8_t *req = c->d.asBytes;
uint8_t uid[8] = {0x00};
@ -1045,7 +1084,8 @@ int prepareHF15Cmd(char **cmd, UsbCommand *c, uint8_t iso15cmd) {
* Commandline handling: HF15 CMD READMULTI
* 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);
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
* Reads a single Block
*/
int CmdHF15Read(const char *Cmd) {
int CmdHF15Read(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0);
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
* 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);
if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') return usage_15_write();
@ -1296,13 +1338,15 @@ static command_t CommandTable15[] = {
{NULL, NULL, 0, NULL}
};
int CmdHF15(const char *Cmd) {
int CmdHF15(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable15, Cmd);
return 0;
}
int CmdHF15Help(const char *Cmd) {
int CmdHF15Help(const char *Cmd)
{
CmdsHelp(CommandTable15);
return 0;
}

View file

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

View file

@ -11,7 +11,8 @@
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, "Usage: hf felica sim [h] t <type> [v]");
PrintAndLogEx(NORMAL, "Options:");
@ -23,7 +24,8 @@ int usage_hf_felica_sim(void) {
PrintAndLogEx(NORMAL, " hf felica sim t 1 ");
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, "Buffer accessible from command 'hf list felica'");
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");
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, "Usage: hf felica litesim [h] u <uid>");
PrintAndLogEx(NORMAL, "Options:");
@ -43,7 +46,8 @@ int usage_hf_felica_simlite(void) {
PrintAndLogEx(NORMAL, " hf felica litesim 11223344556677");
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, "press button to abort run, otherwise it will loop for 200sec.");
PrintAndLogEx(NORMAL, "Usage: hf felica litedump [h]");
@ -53,7 +57,8 @@ int usage_hf_felica_dumplite(void) {
PrintAndLogEx(NORMAL, " hf felica litedump");
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, " -h this help");
PrintAndLogEx(NORMAL, " -r do not read response");
@ -64,13 +69,15 @@ int usage_hf_felica_raw(void){
return 0;
}
int CmdHFFelicaList(const char *Cmd) {
int CmdHFFelicaList(const char *Cmd)
{
//PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list felica' instead");
CmdTraceList("felica");
return 0;
}
int CmdHFFelicaReader(const char *Cmd) {
int CmdHFFelicaReader(const char *Cmd)
{
bool silent = (Cmd[0] == 's' || Cmd[0] == 'S');
//UsbCommand cDisconnect = {CMD_FELICA_COMMAND, {0,0,0}};
UsbCommand c = {CMD_FELICA_COMMAND, {FELICA_CONNECT, 0, 0}};
@ -122,7 +129,8 @@ int CmdHFFelicaReader(const char *Cmd) {
}
// simulate iso18092 / FeliCa tag
int CmdHFFelicaSim(const char *Cmd) {
int CmdHFFelicaSim(const char *Cmd)
{
bool errors = false;
uint8_t flags = 0;
uint8_t tagtype = 1;
@ -187,7 +195,8 @@ int CmdHFFelicaSim(const char *Cmd) {
return 0;
}
int CmdHFFelicaSniff(const char *Cmd) {
int CmdHFFelicaSniff(const char *Cmd)
{
uint8_t cmdp = 0;
uint64_t samples2skip = 0;
@ -225,7 +234,8 @@ int CmdHFFelicaSniff(const char *Cmd) {
}
// uid hex
int CmdHFFelicaSimLite(const char *Cmd) {
int CmdHFFelicaSimLite(const char *Cmd)
{
uint64_t uid = param_get64ex(Cmd, 0, 0, 16);
@ -238,11 +248,13 @@ int CmdHFFelicaSimLite(const char *Cmd) {
return 0;
}
static void printSep() {
static void printSep()
{
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)
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);
switch (blocknum) {
case 0x00: PrintAndLogEx(NORMAL, "S_PAD0: %s",line);break;
case 0x01: PrintAndLogEx(NORMAL, "S_PAD1: %s",line);break;
case 0x02: PrintAndLogEx(NORMAL, "S_PAD2: %s",line);break;
case 0x03: PrintAndLogEx(NORMAL, "S_PAD3: %s",line);break;
case 0x04: 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 0x00:
PrintAndLogEx(NORMAL, "S_PAD0: %s", line);
break;
case 0x01:
PrintAndLogEx(NORMAL, "S_PAD1: %s", line);
break;
case 0x02:
PrintAndLogEx(NORMAL, "S_PAD2: %s", line);
break;
case 0x03:
PrintAndLogEx(NORMAL, "S_PAD3: %s", line);
break;
case 0x04:
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: {
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;
@ -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);
}
break;
case 0x80: PrintAndLogEx(NORMAL, "Random Challenge, WO: %s ", line); break;
case 0x81: PrintAndLogEx(NORMAL, "MAC, only set on dual read: %s ", line); break;
case 0x80:
PrintAndLogEx(NORMAL, "Random Challenge, WO: %s ", line);
break;
case 0x81:
PrintAndLogEx(NORMAL, "MAC, only set on dual read: %s ", line);
break;
case 0x82: {
char idd[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);
}
break;
case 0x84: PrintAndLogEx(NORMAL, "SER_C: 0x%02x%02x ", trace[3], trace[4]); 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 0x84:
PrintAndLogEx(NORMAL, "SER_C: 0x%02x%02x ", trace[3], trace[4]);
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: {
PrintAndLogEx(NORMAL, "Memory Configuration (MC):");
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;
}
int CmdHFFelicaDumpLite(const char *Cmd) {
int CmdHFFelicaDumpLite(const char *Cmd)
{
char ctmp = tolower(param_getchar(Cmd, 0));
if (ctmp == 'h') return usage_hf_felica_dumplite();
@ -364,9 +417,11 @@ int CmdHFFelicaDumpLite(const char *Cmd) {
uint8_t timeout = 0;
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
timeout++;
printf("."); fflush(stdout);
printf(".");
fflush(stdout);
if (ukbhit()) {
int gc = getchar(); (void)gc;
int gc = getchar();
(void)gc;
PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n");
DropField();
return 1;
@ -414,7 +469,8 @@ int CmdHFFelicaDumpLite(const char *Cmd) {
return 0;
}
int CmdHFFelicaCmdRaw(const char *cmd) {
int CmdHFFelicaCmdRaw(const char *cmd)
{
UsbCommand c = {CMD_FELICA_COMMAND, {0, 0, 0}};
bool reply = 1;
bool crc = false;
@ -530,7 +586,8 @@ int CmdHFFelicaCmdRaw(const char *cmd) {
return 0;
}
void waitCmdFelica(uint8_t iSelect) {
void waitCmdFelica(uint8_t iSelect)
{
UsbCommand resp;
uint16_t len = 0;
@ -558,13 +615,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdHFFelica(const char *Cmd) {
int CmdHFFelica(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -49,7 +49,8 @@
static int CmdHelp(const char *Cmd);
int CmdHFFidoInfo(const char *cmd) {
int CmdHFFidoInfo(const char *cmd)
{
if (cmd && strlen(cmd) > 0)
PrintAndLog("WARNING: command don't have any parameters.\n");
@ -124,7 +125,8 @@ int CmdHFFidoInfo(const char *cmd) {
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_error_t error;
*err = false;
@ -168,7 +170,8 @@ json_t *OpenJson(int paramnum, char *fname, void* argtable[], bool *err) {
return root;
}
int CmdHFFidoRegister(const char *cmd) {
int CmdHFFidoRegister(const char *cmd)
{
uint8_t data[64] = {0};
int chlen = 0;
uint8_t cdata[250] = {0};
@ -397,7 +400,8 @@ int CmdHFFidoRegister(const char *cmd) {
return 0;
};
int CmdHFFidoAuthenticate(const char *cmd) {
int CmdHFFidoAuthenticate(const char *cmd)
{
uint8_t data[512] = {0};
uint8_t hdata[250] = {0};
bool public_key_loaded = false;
@ -615,13 +619,15 @@ int CmdHFFidoAuthenticate(const char *cmd) {
return 0;
};
void CheckSlash(char *fileName) {
void CheckSlash(char *fileName)
{
if ((fileName[strlen(fileName) - 1] != '/') &&
(fileName[strlen(fileName) - 1] != '\\'))
strcat(fileName, "/");
}
int GetExistsFileNameJson(char *prefixDir, char *reqestedFileName, char *fileName) {
int GetExistsFileNameJson(char *prefixDir, char *reqestedFileName, char *fileName)
{
fileName[0] = 0x00;
strcpy(fileName, get_my_executable_directory());
CheckSlash(fileName);
@ -648,7 +654,8 @@ int GetExistsFileNameJson(char *prefixDir, char *reqestedFileName, char *fileNam
return 0;
}
int CmdHFFido2MakeCredential(const char *cmd) {
int CmdHFFido2MakeCredential(const char *cmd)
{
json_error_t error;
json_t *root = NULL;
char fname[300] = {0};
@ -775,7 +782,8 @@ int CmdHFFido2MakeCredential(const char *cmd) {
return 0;
};
int CmdHFFido2GetAssertion(const char *cmd) {
int CmdHFFido2GetAssertion(const char *cmd)
{
json_error_t error;
json_t *root = NULL;
char fname[300] = {0};
@ -902,8 +910,7 @@ int CmdHFFido2GetAssertion(const char *cmd) {
return 0;
};
static command_t CommandTable[] =
{
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help."},
{"info", CmdHFFidoInfo, 0, "Info about FIDO tag."},
{"reg", CmdHFFidoRegister, 0, "FIDO U2F Registration Message."},
@ -913,13 +920,15 @@ static command_t CommandTable[] =
{NULL, NULL, 0, NULL}
};
int CmdHFFido(const char *Cmd) {
int CmdHFFido(const char *Cmd)
{
(void)WaitForResponseTimeout(CMD_ACK, NULL, 100);
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
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 }
};
int usage_hf_iclass_sim(void) {
int usage_hf_iclass_sim(void)
{
PrintAndLogEx(NORMAL, "Usage: hf iclass sim <option> [CSN]");
PrintAndLogEx(NORMAL, " options");
PrintAndLogEx(NORMAL, " 0 <CSN> simulate the given CSN");
@ -45,14 +46,16 @@ int usage_hf_iclass_sim(void) {
PrintAndLogEx(NORMAL, " hf iclass sim 4");
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, "Usage: hf iclass eload f <filename>");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " hf iclass eload f iclass_tagdump-aa162d30f8ff12f1.bin");
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, "Correct behaviour would be to decrypt only the application areas where the key is valid,");
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");
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, "in the working directory. The file should be 16 bytes binary data");
PrintAndLogEx(NORMAL, "");
@ -76,7 +80,8 @@ int usage_hf_iclass_encrypt(void) {
PrintAndLogEx(NORMAL, "");
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, "Options:");
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");
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, "Options:");
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");
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, "Options:");
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");
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, "Options:");
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");
return 0;
}
int usage_hf_iclass_readtagfile() {
int usage_hf_iclass_readtagfile()
{
PrintAndLogEx(NORMAL, "Usage: hf iclass readtagfile <filename> [startblock] [endblock]");
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, "Usage: hf iclass calc_newkey o <Old key> n <New key> s [csn] e");
PrintAndLogEx(NORMAL, "Options:");
@ -158,7 +168,8 @@ int usage_hf_iclass_calc_newkey(void) {
PrintAndLogEx(NORMAL, "\nNOTE: * = required\n");
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, "Usage: hf iclass managekeys n [keynbr] k [key] f [filename] s l p\n");
PrintAndLogEx(NORMAL, "Options:");
@ -175,7 +186,8 @@ int usage_hf_iclass_managekeys(void) {
PrintAndLogEx(NORMAL, " print keys : hf iclass managekeys p\n");
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, "Usage: hf iclass reader [h] [1]\n");
PrintAndLogEx(NORMAL, "Options:");
@ -185,7 +197,8 @@ int usage_hf_iclass_reader(void) {
PrintAndLogEx(NORMAL, " hf iclass reader 1");
return 0;
}
int usage_hf_iclass_replay(void) {
int usage_hf_iclass_replay(void)
{
PrintAndLogEx(NORMAL, "Replay a collected mac message");
PrintAndLogEx(NORMAL, "Usage: hf iclass replay [h] <mac>");
PrintAndLogEx(NORMAL, "Options:");
@ -195,14 +208,16 @@ int usage_hf_iclass_replay(void) {
PrintAndLogEx(NORMAL, " hf iclass replay 00112233");
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, "Usage: hf iclass sniff [h]");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " hf iclass sniff");
return 0;
}
int usage_hf_iclass_loclass(void) {
int usage_hf_iclass_loclass(void)
{
PrintAndLogEx(NORMAL, "Usage: hf iclass loclass [options]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, "h Show this help");
@ -217,7 +232,8 @@ int usage_hf_iclass_loclass(void) {
PrintAndLogEx(NORMAL, " ... totalling N*24 bytes");
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, "Usage: hf iclass chk [h|e|r] [f (*.dic)]");
PrintAndLogEx(NORMAL, "Options:");
@ -231,7 +247,8 @@ int usage_hf_iclass_chk(void) {
PrintAndLogEx(NORMAL, " hf iclass chk f default_iclass_keys.dic e");
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, "Usage: hf iclass lookup [h|e|r] [f (*.dic)] [u <csn>] [p <epurse>] [m <macs>]");
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");
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, "");
PrintAndLogEx(NORMAL, "Usage: hf iclass permute [h] <r|f> <bytes>");
@ -262,7 +280,8 @@ int usage_hf_iclass_permutekey(void){
return 0;
}
int xorbits_8(uint8_t val) {
int xorbits_8(uint8_t val)
{
uint8_t res = val ^ (val >> 1); //1st pass
res = res ^ (res >> 1); // 2nd pass
res = res ^ (res >> 2); // 3rd pass
@ -270,13 +289,15 @@ int xorbits_8(uint8_t val) {
return res & 1;
}
int CmdHFiClassList(const char *Cmd) {
int CmdHFiClassList(const char *Cmd)
{
//PrintAndLogEx(NORMAL, "Deprecated command, use 'hf list iclass' instead");
CmdTraceList("iclass");
return 0;
}
int CmdHFiClassSniff(const char *Cmd) {
int CmdHFiClassSniff(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_iclass_sniff();
UsbCommand c = {CMD_SNOOP_ICLASS};
@ -284,7 +305,8 @@ int CmdHFiClassSniff(const char *Cmd) {
return 0;
}
int CmdHFiClassSim(const char *Cmd) {
int CmdHFiClassSim(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
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)) {
tries++;
if (ukbhit()) {
int gc = getchar(); (void)gc;
int gc = getchar();
(void)gc;
PrintAndLogEx(WARNING, "\naborted via keyboard.");
return 0;
}
@ -439,7 +462,8 @@ int CmdHFiClassSim(const char *Cmd) {
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
tries++;
if (ukbhit()) {
int gc = getchar(); (void)gc;
int gc = getchar();
(void)gc;
PrintAndLogEx(WARNING, "\naborted via keyboard.");
return 0;
}
@ -507,7 +531,8 @@ int CmdHFiClassSim(const char *Cmd) {
return 0;
}
int HFiClassReader(const char *Cmd, bool loop, bool verbose) {
int HFiClassReader(const char *Cmd, bool loop, bool verbose)
{
bool tagFound = false;
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;
}
int CmdHFiClassReader(const char *Cmd) {
int CmdHFiClassReader(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_hf_iclass_reader();
bool findone = (cmdp == '1') ? false : 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));
if (strlen(Cmd) < 1 || cmdp == 'h') return usage_hf_iclass_replay();
@ -600,7 +627,8 @@ int CmdHFiClassReader_Replay(const char *Cmd) {
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}};
memcpy(c.d.asBytes, data, blocksCount * 16);
clearCommandBuffer();
@ -608,7 +636,8 @@ int iclassEmlSetMem(uint8_t *data, int blockNum, int blocksCount) {
return 0;
}
int CmdHFiClassELoad(const char *Cmd) {
int CmdHFiClassELoad(const char *Cmd)
{
char ctmp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || ctmp == 'h') return usage_hf_iclass_eload();
@ -676,7 +705,8 @@ int CmdHFiClassELoad(const char *Cmd) {
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");
if (!f) {
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;
}
int CmdHFiClassDecrypt(const char *Cmd) {
int CmdHFiClassDecrypt(const char *Cmd)
{
char opt = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || opt == 'h') return usage_hf_iclass_decrypt();
@ -787,7 +818,8 @@ int CmdHFiClassDecrypt(const char *Cmd) {
return 0;
}
static int iClassEncryptBlkData(uint8_t *blkData) {
static int iClassEncryptBlkData(uint8_t *blkData)
{
uint8_t key[16] = { 0 };
if (readKeyfile("iclass_decryptionkey.bin", 16, key)) {
usage_hf_iclass_encrypt();
@ -804,7 +836,8 @@ static int iClassEncryptBlkData(uint8_t *blkData) {
return 1;
}
int CmdHFiClassEncryptBlk(const char *Cmd) {
int CmdHFiClassEncryptBlk(const char *Cmd)
{
uint8_t blkData[8] = {0};
char opt = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || opt == 'h') return usage_hf_iclass_encrypt();
@ -820,14 +853,16 @@ int CmdHFiClassEncryptBlk(const char *Cmd) {
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];
wb[0] = blockno;
memcpy(wb + 1, data, 8);
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 c = {CMD_READER_ICLASS, {0}};
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;
}
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 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;
}
int CmdHFiClassReader_Dump(const char *Cmd) {
int CmdHFiClassReader_Dump(const char *Cmd)
{
uint8_t MAC[4] = {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();
SendCommand(&w);
while (true) {
printf("."); fflush(stdout);
printf(".");
fflush(stdout);
if (ukbhit()) {
int gc = getchar(); (void)gc;
int gc = getchar();
(void)gc;
PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n");
DropField();
return 0;
@ -1150,7 +1189,8 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
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 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))
@ -1177,7 +1217,8 @@ static int WriteBlock(uint8_t blockno, uint8_t *bldata, uint8_t *KEY, bool use_c
return isOK;
}
int CmdHFiClass_WriteBlock(const char *Cmd) {
int CmdHFiClass_WriteBlock(const char *Cmd)
{
uint8_t blockno = 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};
@ -1255,7 +1296,8 @@ int CmdHFiClass_WriteBlock(const char *Cmd) {
return ans;
}
int CmdHFiClassCloneTag(const char *Cmd) {
int CmdHFiClassCloneTag(const char *Cmd)
{
char filename[FILE_PATH_SIZE] = { 0x00 };
char tempStr[50] = {0};
uint8_t KEY[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
@ -1407,7 +1449,8 @@ int CmdHFiClassCloneTag(const char *Cmd) {
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 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;
}
int CmdHFiClass_ReadBlock(const char *Cmd) {
int CmdHFiClass_ReadBlock(const char *Cmd)
{
uint8_t blockno = 0;
uint8_t keyType = 0x88; //debit key
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);
}
int CmdHFiClass_loclass(const char *Cmd) {
int CmdHFiClass_loclass(const char *Cmd)
{
char opt = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || opt == 'h')
@ -1527,8 +1572,7 @@ int CmdHFiClass_loclass(const char *Cmd) {
PrintAndLogEx(WARNING, "You must specify a filename");
return 0;
}
}
else if (opt == 't') {
} else if (opt == 't') {
int errors = testCipherUtils();
errors += testMAC();
errors += doKeyTests(0);
@ -1539,7 +1583,8 @@ int CmdHFiClass_loclass(const char *Cmd) {
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;
memcpy(&mem_config, iclass_dump + 13, 1);
uint8_t maxmemcount;
@ -1573,7 +1618,8 @@ void printIclassDumpContents(uint8_t *iclass_dump, uint8_t startblock, uint8_t e
PrintAndLogEx(NORMAL, "------+--+-------------------------+\n");
}
int CmdHFiClassReadTagFile(const char *Cmd) {
int CmdHFiClassReadTagFile(const char *Cmd)
{
int startblock = 0;
int endblock = 0;
char tempnum[5];
@ -1625,7 +1671,8 @@ int CmdHFiClassReadTagFile(const char *Cmd) {
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 key_index[8] = {0};
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)
//calculate and return xor_div_key (ready for a key write command)
//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 new_div_key[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
//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 NEWKEY[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;
}
static int loadKeys(char *filename) {
static int loadKeys(char *filename)
{
FILE *f;
f = fopen(filename, "rb");
if (!f) {
@ -1787,7 +1837,8 @@ static int loadKeys(char *filename) {
return 1;
}
static int saveKeys(char *filename) {
static int saveKeys(char *filename)
{
FILE *f;
f = fopen(filename, "wb");
if (!f) {
@ -1804,7 +1855,8 @@ static int saveKeys(char *filename) {
return 0;
}
static int printKeys(void) {
static int printKeys(void)
{
PrintAndLogEx(NORMAL, "");
for (uint8_t i = 0; i < ICLASS_KEYS_MAX; i++)
PrintAndLogEx(NORMAL, "%u: %s", i, sprint_hex(iClass_Key_Table[i], 8));
@ -1812,7 +1864,8 @@ static int printKeys(void) {
return 0;
}
int CmdHFiClassManageKeys(const char *Cmd) {
int CmdHFiClassManageKeys(const char *Cmd)
{
uint8_t keyNbr = 0;
uint8_t dataLen = 0;
uint8_t KEY[8] = {0};
@ -1888,16 +1941,22 @@ int CmdHFiClassManageKeys(const char *Cmd) {
}
switch (operation) {
case 3: memcpy(iClass_Key_Table[keyNbr], KEY, 8); return 1;
case 4: return printKeys();
case 5: return loadKeys(filename);
case 6: return saveKeys(filename);
case 3:
memcpy(iClass_Key_Table[keyNbr], KEY, 8);
return 1;
case 4:
return printKeys();
case 5:
return loadKeys(filename);
case 6:
return saveKeys(filename);
break;
}
return 0;
}
int CmdHFiClassCheckKeys(const char *Cmd) {
int CmdHFiClassCheckKeys(const char *Cmd)
{
// empty string
if (strlen(Cmd) == 0) return usage_hf_iclass_chk();
@ -2016,7 +2075,8 @@ int CmdHFiClassCheckKeys(const char *Cmd) {
uint8_t timeout = 0;
if (ukbhit()) {
int gc = getchar(); (void)gc;
int gc = getchar();
(void)gc;
PrintAndLogEx(WARNING, "\n[!] Aborted via keyboard!\n");
goto out;
}
@ -2041,7 +2101,8 @@ int CmdHFiClassCheckKeys(const char *Cmd) {
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
timeout++;
printf("."); fflush(stdout);
printf(".");
fflush(stdout);
if (timeout > 120) {
PrintAndLogEx(WARNING, "\nNo response from Proxmark. Aborting...");
goto out;
@ -2077,7 +2138,8 @@ int CmdHFiClassCheckKeys(const char *Cmd) {
}
case 99: {
}
default: break;
default:
break;
}
// both keys found.
@ -2099,7 +2161,8 @@ out:
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 *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.
// 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 EPURSE[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
@ -2252,7 +2316,8 @@ int CmdHFiClassLookUp(const char *Cmd) {
return 0;
}
int LoadDictionaryKeyFile( char* filename, uint8_t **keys, int *keycnt) {
int LoadDictionaryKeyFile(char *filename, uint8_t **keys, int *keycnt)
{
char buf[17];
FILE *f;
@ -2303,7 +2368,8 @@ int LoadDictionaryKeyFile( char* filename, uint8_t **keys, int *keycnt) {
}
// 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 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;
}
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};
@ -2342,7 +2409,8 @@ int GenerateFromKeyFile( uint8_t* CSN, uint8_t* CCNR, bool use_raw, bool use_eli
}
// 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));
if (!b)
@ -2356,7 +2424,8 @@ void PrintPreCalcMac(uint8_t* keys, int keycnt, iclass_premac_t* pre_list) {
free(b);
}
void PrintPreCalc(iclass_prekey_t* list, int itemcnt) {
void PrintPreCalc(iclass_prekey_t *list, int itemcnt)
{
PrintAndLogEx(NORMAL, "-----+------------------+---------");
PrintAndLogEx(NORMAL, "#key | key | mac");
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
if (len > KEY_SIZE) {
@ -2395,12 +2465,14 @@ static void permute(uint8_t *data, uint8_t len, uint8_t *output){
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(output, len, data);
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;
for (uint8_t i = 0; i < len; ++i) {
// 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.
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)
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));
PrintAndLogEx(SUCCESS, "input permuted key | %s \n", sprint_hex(data, len));
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));
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 *pkey = calloc(len, sizeof(uint8_t));
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);
}
int CmdHFiClassPermuteKey(const char *Cmd) {
int CmdHFiClassPermuteKey(const char *Cmd)
{
uint8_t key[8] = {0};
uint8_t key_std_format[8] = {0};
@ -2463,8 +2539,7 @@ int CmdHFiClassPermuteKey(const char *Cmd) {
generate_rev(data, len);
permutekey_rev(key, key_std_format);
PrintAndLogEx(SUCCESS, "holiman iclass key | %s \n", sprint_hex(key_std_format, 8));
}
else {
} else {
generate(data, len);
permutekey(key, key_iclass_format);
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}
};
int CmdHFiClass(const char *Cmd) {
int CmdHFiClass(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -13,7 +13,8 @@ static int CmdHelp(const char *Cmd);
#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, "There must be an even number of hexsymbols as input.");
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");
return 0;
}
int usage_legic_rdmem(void){
int usage_legic_rdmem(void)
{
PrintAndLogEx(NORMAL, "Read data from a legic tag.");
PrintAndLogEx(NORMAL, "Usage: hf legic rdmem [h] <offset> <length> <IV>");
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");
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, "Use ELOAD/ESAVE to upload a dump into emulator memory");
PrintAndLogEx(NORMAL, "Usage: hf legic sim [h] <tagtype>");
@ -57,7 +60,8 @@ int usage_legic_sim(void){
PrintAndLogEx(NORMAL, " hf legic sim 2");
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, "Usage: hf legic write [h] o <offset> d <data (hex symbols)>");
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");
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, "Usage: hf legic reader [h]");
PrintAndLogEx(NORMAL, "Options:");
@ -80,7 +85,8 @@ int usage_legic_reader(void){
PrintAndLogEx(NORMAL, " hf legic reader");
return 0;
}
int usage_legic_info(void){
int usage_legic_info(void)
{
PrintAndLogEx(NORMAL, "Reads information from a legic prime tag.");
PrintAndLogEx(NORMAL, "Shows systemarea, user areas etc");
PrintAndLogEx(NORMAL, "Usage: hf legic info [h]");
@ -91,7 +97,8 @@ int usage_legic_info(void){
PrintAndLogEx(NORMAL, " hf legic info");
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, "and saves binary dump into the file `filename.bin` or `cardUID.bin`");
PrintAndLogEx(NORMAL, "It autodetects card type.\n");
@ -105,7 +112,8 @@ int usage_legic_dump(void){
PrintAndLogEx(NORMAL, " hf legic dump o myfile");
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, "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>");
@ -117,7 +125,8 @@ int usage_legic_restore(void){
PrintAndLogEx(NORMAL, " hf legic restore i myfile");
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, "Usage: hf legic eload [h] [card memory] <file name w/o `.bin`>");
PrintAndLogEx(NORMAL, "Options:");
@ -131,7 +140,8 @@ int usage_legic_eload(void){
PrintAndLogEx(NORMAL, " hf legic eload 2 myfile");
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, " Usage: hf legic esave [h] [card memory] [file name w/o `.bin`]");
PrintAndLogEx(NORMAL, "Options:");
@ -145,7 +155,8 @@ int usage_legic_esave(void){
PrintAndLogEx(NORMAL, " hf legic esave 2 myfile");
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, " Usage: hf legic wipe [h]");
PrintAndLogEx(NORMAL, "Options:");
@ -160,7 +171,8 @@ int usage_legic_wipe(void){
* This is based on information given in the talk held
* 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));
if (cmdp == 'h') return usage_legic_info();
@ -321,8 +333,7 @@ int CmdLegicInfo(const char *Cmd) {
i = 22;
// 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_flag = ((data[i + 1] ^ crc) & 0xf0) >> 4;
wrp = (data[i + 2] ^ crc);
@ -470,7 +481,8 @@ out:
// params:
// offset in data memory
// number of bytes to read
int CmdLegicRdmem(const char *Cmd) {
int CmdLegicRdmem(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_legic_rdmem();
@ -504,7 +516,8 @@ int CmdLegicRdmem(const char *Cmd) {
return status;
}
int CmdLegicRfSim(const char *Cmd) {
int CmdLegicRfSim(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_legic_sim();
@ -516,7 +529,8 @@ int CmdLegicRfSim(const char *Cmd) {
return 0;
}
int CmdLegicRfWrite(const char *Cmd) {
int CmdLegicRfWrite(const char *Cmd)
{
uint8_t *data = NULL;
uint8_t cmdp = 0;
@ -638,7 +652,8 @@ int CmdLegicRfWrite(const char *Cmd) {
uint8_t timeout = 0;
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
++timeout;
printf("."); fflush(stdout);
printf(".");
fflush(stdout);
if (timeout > 7) {
PrintAndLogEx(WARNING, "\ncommand execution time out");
return 1;
@ -655,7 +670,8 @@ int CmdLegicRfWrite(const char *Cmd) {
return 0;
}
int CmdLegicCalcCrc(const char *Cmd){
int CmdLegicCalcCrc(const char *Cmd)
{
uint8_t *data = NULL;
uint8_t cmdp = 0, uidcrc = 0, type = 0;
@ -737,7 +753,8 @@ int CmdLegicCalcCrc(const char *Cmd){
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);
@ -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;
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
++timeout;
printf("."); fflush(stdout);
printf(".");
fflush(stdout);
if (timeout > 7) {
PrintAndLogEx(WARNING, "\ncommand execution time out");
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;
}
int legic_print_type(uint32_t tagtype, uint8_t spaces){
int legic_print_type(uint32_t tagtype, uint8_t spaces)
{
char spc[11] = " ";
spc[10] = 0x00;
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);
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;
@ -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));
return 0;
}
void legic_chk_iv(uint32_t *iv){
void legic_chk_iv(uint32_t *iv)
{
if ((*iv & 0x7F) != *iv) {
*iv &= 0x7F;
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);
}
}
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;
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));
if (cmdp == 'h') return usage_legic_reader();
@ -849,17 +872,20 @@ int HFLegicReader(const char *Cmd, bool verbose) {
case 3:
if (verbose) PrintAndLogEx(WARNING, "legic card select failed");
return 2;
default: break;
default:
break;
}
PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, sizeof(card.uid)));
legic_print_type(card.cardsize, 0);
return 0;
}
int CmdLegicReader(const char *Cmd){
int CmdLegicReader(const char *Cmd)
{
return HFLegicReader(Cmd, true);
}
int CmdLegicDump(const char *Cmd){
int CmdLegicDump(const char *Cmd)
{
FILE *f;
char filename[FILE_PATH_SIZE] = {0x00};
@ -911,7 +937,8 @@ int CmdLegicDump(const char *Cmd){
uint8_t timeout = 0;
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
++timeout;
printf("."); fflush(stdout);
printf(".");
fflush(stdout);
if (timeout > 7) {
PrintAndLogEx(WARNING, "\ncommand execution time out");
return 1;
@ -963,7 +990,8 @@ int CmdLegicDump(const char *Cmd){
return 0;
}
int CmdLegicRestore(const char *Cmd){
int CmdLegicRestore(const char *Cmd)
{
FILE *f;
char filename[FILE_PATH_SIZE] = {0x00};
@ -1066,7 +1094,8 @@ int CmdLegicRestore(const char *Cmd){
uint8_t timeout = 0;
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
++timeout;
printf("."); fflush(stdout);
printf(".");
fflush(stdout);
if (timeout > 7) {
PrintAndLogEx(WARNING, "\ncommand execution time out");
free(data);
@ -1089,7 +1118,8 @@ int CmdLegicRestore(const char *Cmd){
return 0;
}
int CmdLegicELoad(const char *Cmd) {
int CmdLegicELoad(const char *Cmd)
{
FILE *f;
char filename[FILE_PATH_SIZE];
char *fnameptr = filename;
@ -1101,11 +1131,20 @@ int CmdLegicELoad(const char *Cmd) {
return usage_legic_eload();
switch (cmdp) {
case '0' : numofbytes = 22; break;
case '0' :
numofbytes = 22;
break;
case '1' :
case '\0': numofbytes = 256; break;
case '2' : numofbytes = 1024; break;
default : numofbytes = 256; nameParamNo = 0;break;
case '\0':
numofbytes = 256;
break;
case '2' :
numofbytes = 1024;
break;
default :
numofbytes = 256;
nameParamNo = 0;
break;
}
// set up buffer
@ -1150,7 +1189,8 @@ int CmdLegicELoad(const char *Cmd) {
return 0;
}
int CmdLegicESave(const char *Cmd) {
int CmdLegicESave(const char *Cmd)
{
char filename[FILE_PATH_SIZE];
char *fnameptr = filename;
@ -1164,11 +1204,20 @@ int CmdLegicESave(const char *Cmd) {
return usage_legic_esave();
switch (cmdp) {
case '0' : numofbytes = 22; break;
case '0' :
numofbytes = 22;
break;
case '1' :
case '\0': numofbytes = 256; break;
case '2' : numofbytes = 1024; break;
default : numofbytes = 256; nameParamNo = 0; break;
case '\0':
numofbytes = 256;
break;
case '2' :
numofbytes = 1024;
break;
default :
numofbytes = 256;
nameParamNo = 0;
break;
}
fileNlen = param_getstr(Cmd, nameParamNo, filename, FILE_PATH_SIZE);
@ -1201,7 +1250,8 @@ int CmdLegicESave(const char *Cmd) {
return 0;
}
int CmdLegicWipe(const char *Cmd){
int CmdLegicWipe(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
@ -1231,7 +1281,8 @@ int CmdLegicWipe(const char *Cmd){
UsbCommand resp;
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);
c.arg[0] = i; // offset
c.arg[1] = len; // number of bytes
@ -1242,7 +1293,8 @@ int CmdLegicWipe(const char *Cmd){
uint8_t timeout = 0;
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
++timeout;
printf("."); fflush(stdout);
printf(".");
fflush(stdout);
if (timeout > 7) {
PrintAndLogEx(WARNING, "\ncommand execution time out");
free(data);
@ -1262,7 +1314,8 @@ int CmdLegicWipe(const char *Cmd){
return 0;
}
int CmdLegicList(const char *Cmd) {
int CmdLegicList(const char *Cmd)
{
CmdTraceList("legic");
return 0;
}
@ -1284,13 +1337,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdHFLegic(const char *Cmd) {
int CmdHFLegic(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
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;
}
int CmdHF14ADesInfo(const char *Cmd){
int CmdHF14ADesInfo(const char *Cmd)
{
UsbCommand c = {CMD_MIFARE_DESFIRE_INFO};
SendCommand(&c);
@ -146,12 +147,15 @@ int CmdHF14ADesInfo(const char *Cmd){
if (!isOK) {
switch (resp.arg[1]) {
case 1:
PrintAndLogEx(WARNING, "Can't select card"); break;
PrintAndLogEx(WARNING, "Can't select card");
break;
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:
default:
PrintAndLogEx(WARNING, "Command unsuccessful"); break;
PrintAndLogEx(WARNING, "Command unsuccessful");
break;
}
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).
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};
char *retStr = buf;
@ -237,7 +242,8 @@ char * GetCardSizeStr( uint8_t fsize ){
return buf;
}
char * GetProtocolStr(uint8_t id){
char *GetProtocolStr(uint8_t id)
{
static char buf[30] = {0x00};
char *retStr = buf;
@ -249,7 +255,8 @@ char * GetProtocolStr(uint8_t id){
return buf;
}
char * GetVersionStr(uint8_t major, uint8_t minor){
char *GetVersionStr(uint8_t major, uint8_t minor)
{
static char buf[30] = {0x00};
char *retStr = buf;
@ -265,7 +272,8 @@ char * GetVersionStr(uint8_t major, uint8_t minor){
return buf;
}
void GetKeySettings( uint8_t *aid){
void GetKeySettings(uint8_t *aid)
{
char messStr[512] = {0x00};
char *str = messStr;
@ -416,8 +424,7 @@ void GetKeySettings( uint8_t *aid){
if (!isOK) {
PrintAndLogEx(WARNING, " Can't read Application Master key version. Trying all keys");
numOfKeys = MAX_NUM_KEYS;
}
else{
} else {
numOfKeys = resp.d.asBytes[4];
PrintAndLogEx(NORMAL, "");
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 aid[3];
@ -546,7 +554,8 @@ int CmdHF14ADesEnumApplications(const char *Cmd){
// MIAFRE DesFire Authentication
//
#define BUFSIZE 256
int CmdHF14ADesAuth(const char *Cmd){
int CmdHF14ADesAuth(const char *Cmd)
{
// NR DESC KEYLENGHT
// ------------------------
@ -574,8 +583,7 @@ int CmdHF14ADesAuth(const char *Cmd){
uint8_t cmdAuthAlgo = param_get8(Cmd, 1);
uint8_t cmdKeyNo = param_get8(Cmd, 2);
switch (cmdAuthMode)
{
switch (cmdAuthMode) {
case 1:
if (cmdAuthAlgo != 1 && cmdAuthAlgo != 2) {
PrintAndLogEx(NORMAL, "Crypto algo not valid for the auth mode");
@ -665,14 +673,16 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdHFMFDes(const char *Cmd) {
int CmdHFMFDes(const char *Cmd)
{
// flush
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

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

View file

@ -72,7 +72,8 @@ static uint32_t test_state[2] = {0,0};
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()) {
case SIMD_AVX512:
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 instr_set[12] = "";
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;
if (msclock() - last_print_time > min_diff_print_time) {
last_print_time = msclock();
@ -327,7 +330,8 @@ static void init_bitflip_bitarrays(void)
j++;
} else {
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)) {
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;
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) {
// odd bits
switch (num_common_bits) {
case 0: if (!invariant_holds(byte_diff, state1, state2, 1, 0)) return true;
case 1: if (invalid_state(byte_diff, state1, state2, 1, 0)) return false;
case 2: if (!invariant_holds(byte_diff, state1, state2, 3, 1)) return true;
case 3: 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;
case 0:
if (!invariant_holds(byte_diff, state1, state2, 1, 0)) return true;
case 1:
if (invalid_state(byte_diff, state1, state2, 1, 0)) return false;
case 2:
if (!invariant_holds(byte_diff, state1, state2, 3, 1)) return true;
case 3:
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 {
// even bits
switch (num_common_bits) {
case 0: if (invalid_state(byte_diff, state1, state2, 0, 0)) return false;
case 1: if (!invariant_holds(byte_diff, state1, state2, 2, 1)) return true;
case 2: if (invalid_state(byte_diff, state1, state2, 2, 1)) 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;
case 0:
if (invalid_state(byte_diff, state1, state2, 0, 0)) return false;
case 1:
if (!invariant_holds(byte_diff, state1, state2, 2, 1)) return true;
case 2:
if (invalid_state(byte_diff, state1, state2, 2, 1)) 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)
{
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++) {
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);
int CmdHFMFPInfo(const char *cmd) {
int CmdHFMFPInfo(const char *cmd)
{
if (cmd && strlen(cmd) > 0)
PrintAndLogEx(WARNING, "command don't have any parameters.\n");
@ -112,7 +113,8 @@ int CmdHFMFPInfo(const char *cmd) {
return 0;
}
int CmdHFMFPWritePerso(const char *cmd) {
int CmdHFMFPWritePerso(const char *cmd)
{
uint8_t keyNum[64] = {0};
int keyNumLen = 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};
int CmdHFMFPInitPerso(const char *cmd) {
int CmdHFMFPInitPerso(const char *cmd)
{
int res;
uint8_t key[256] = {0};
int keyLen = 0;
@ -252,7 +255,8 @@ int CmdHFMFPInitPerso(const char *cmd) {
return 0;
}
int CmdHFMFPCommitPerso(const char *cmd) {
int CmdHFMFPCommitPerso(const char *cmd)
{
CLIParserInit("hf mfp commitp",
"Executes Commit Perso command. Can be used in SL0 mode only.",
"Usage:\n\thf mfp commitp -> \n");
@ -293,7 +297,8 @@ int CmdHFMFPCommitPerso(const char *cmd) {
return 0;
}
int CmdHFMFPAuth(const char *cmd) {
int CmdHFMFPAuth(const char *cmd)
{
uint8_t keyn[250] = {0};
int keynlen = 0;
uint8_t key[250] = {0};
@ -331,7 +336,8 @@ int CmdHFMFPAuth(const char *cmd) {
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 key[250] = {0};
int keylen = 0;
@ -443,7 +449,8 @@ int CmdHFMFPRdbl(const char *cmd) {
return 0;
}
int CmdHFMFPRdsc(const char *cmd) {
int CmdHFMFPRdsc(const char *cmd)
{
uint8_t keyn[2] = {0};
uint8_t key[250] = {0};
int keylen = 0;
@ -539,7 +546,8 @@ int CmdHFMFPRdsc(const char *cmd) {
return 0;
}
int CmdHFMFPWrbl(const char *cmd) {
int CmdHFMFPWrbl(const char *cmd)
{
uint8_t keyn[2] = {0};
uint8_t key[250] = {0};
int keylen = 0;
@ -641,7 +649,8 @@ int CmdHFMFPWrbl(const char *cmd) {
return 0;
}
int CmdHFMFPMAD(const char *cmd) {
int CmdHFMFPMAD(const char *cmd)
{
CLIParserInit("hf mfp mad",
"Checks and prints Mifare Application Directory (MAD)",
@ -735,7 +744,8 @@ int CmdHFMFPMAD(const char *cmd) {
return 0;
}
int CmdHFMFPNDEF(const char *cmd) {
int CmdHFMFPNDEF(const char *cmd)
{
CLIParserInit("hf mfp ndef",
"Prints NFC Data Exchange Format (NDEF)",
@ -839,8 +849,7 @@ int CmdHFMFPNDEF(const char *cmd) {
return 0;
}
static command_t CommandTable[] =
{
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"info", CmdHFMFPInfo, 0, "Info about Mifare Plus tag"},
{"wrp", CmdHFMFPWritePerso, 0, "Write Perso command"},
@ -855,13 +864,15 @@ static command_t CommandTable[] =
{NULL, NULL, 0, NULL}
};
int CmdHFMFP(const char *Cmd) {
int CmdHFMFP(const char *Cmd)
{
(void)WaitForResponseTimeout(CMD_ACK, NULL, 100);
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -77,14 +77,14 @@ const uint32_t c_D[] = {
0x5728B869, 0x30726D5A
};
void transform_D(uint8_t* ru) {
void transform_D(uint8_t *ru)
{
//Transform
uint8_t i;
uint8_t p = 0;
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++];
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 t2 = ROTL(v2 ^ t1, t1 & 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.
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;
@ -128,7 +129,8 @@ uint32_t ul_ev1_pwdgenA(uint8_t* uid) {
}
// 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};
@ -140,7 +142,8 @@ uint32_t ul_ev1_pwdgenB(uint8_t* uid) {
}
// 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;
uint8_t base[] = {
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.
// a.k.a xzy
uint32_t ul_ev1_pwdgenD(uint8_t* uid){
uint32_t ul_ev1_pwdgenD(uint8_t *uid)
{
uint8_t i;
//Rotate
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);
}
// 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);
return pack;
}
uint16_t ul_ev1_packgenB(uint8_t* uid){
uint16_t ul_ev1_packgenB(uint8_t *uid)
{
return 0x8080;
}
uint16_t ul_ev1_packgenC(uint8_t* uid){
uint16_t ul_ev1_packgenC(uint8_t *uid)
{
return 0xaa55;
}
uint16_t ul_ev1_packgenD(uint8_t* uid){
uint16_t ul_ev1_packgenD(uint8_t *uid)
{
uint8_t i;
//Rotate
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);
}
int ul_ev1_pwdgen_selftest(){
int ul_ev1_pwdgen_selftest()
{
uint8_t uid1[] = {0x04, 0x11, 0x12, 0x11, 0x12, 0x11, 0x10};
uint32_t pwd1 = ul_ev1_pwdgenA(uid1);
@ -229,15 +238,22 @@ int ul_ev1_pwdgen_selftest(){
//------------------------------------
// get version nxp product type
char *getProductTypeStr( uint8_t id){
char *getProductTypeStr(uint8_t id)
{
static char buf[20];
char *retStr = buf;
switch (id) {
case 3: sprintf(retStr, "%02X, Ultralight", id); break;
case 4: sprintf(retStr, "%02X, NTAG", id); break;
default: sprintf(retStr, "%02X, unknown", id); break;
case 3:
sprintf(retStr, "%02X, Ultralight", id);
break;
case 4:
sprintf(retStr, "%02X, NTAG", id);
break;
default:
sprintf(retStr, "%02X, unknown", id);
break;
}
return buf;
}
@ -247,7 +263,8 @@ char *getProductTypeStr( uint8_t id){
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).
*/
char *getUlev1CardSizeStr( uint8_t fsize ){
char *getUlev1CardSizeStr(uint8_t fsize)
{
static char buf[40];
char *retStr = buf;
@ -264,13 +281,15 @@ char *getUlev1CardSizeStr( uint8_t fsize ){
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}};
clearCommandBuffer();
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}};
memcpy(c.d.asBytes, cmd, cmdlen);
clearCommandBuffer();
@ -284,7 +303,8 @@ static int ul_send_cmd_raw( uint8_t *cmd, uint8_t cmdlen, uint8_t *response, uin
return resplen;
}
static int ul_select( iso14a_card_select_t *card ){
static int ul_select(iso14a_card_select_t *card)
{
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.
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};
int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
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];
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;
}
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};
int len = ul_send_cmd_raw(cmd, sizeof(cmd), nonce, nonceLength);
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}};
memcpy(c.d.asBytes, key, 16);
@ -348,7 +372,8 @@ static int ulc_authentication( uint8_t *key, bool switch_off_field ){
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]};
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;
}
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)) {
//will select card automatically and close connection on error
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;
}
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};
int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
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};
int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
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};
int len = ul_send_cmd_raw(cmd, sizeof(cmd), response, responseLength);
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};
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.
//
// 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;
if (!ul_select(&card))
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
}
static int ul_print_default( uint8_t *data){
static int ul_print_default(uint8_t *data)
{
uint8_t uid[7];
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
uint8_t chip = (data[8] & 0xC7); // 11000111 mask, bit 3,4,5 RFU
switch (chip) {
case 0xc2: PrintAndLogEx(NORMAL, " IC type : SLE 66R04P 770 Bytes"); 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
case 0xc2:
PrintAndLogEx(NORMAL, " IC type : SLE 66R04P 770 Bytes");
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
@ -487,7 +525,8 @@ static int ul_print_default( uint8_t *data){
return 0;
}
static int ndef_print_CC(uint8_t *data) {
static int ndef_print_CC(uint8_t *data)
{
// no NDEF message
if (data[0] != 0xE1)
return -1;
@ -512,7 +551,8 @@ static int ndef_print_CC(uint8_t *data) {
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] = " ";
spc[10] = 0x00;
char *spacer = spc + (10 - spaces);
@ -572,7 +612,8 @@ int ul_print_type(uint32_t tagtype, uint8_t spaces){
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 [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));
@ -581,7 +622,8 @@ static int ulc_print_3deskey( uint8_t *data){
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, " 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;
}
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");
@ -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);
switch (mirror_conf) {
case 0: PrintAndLogEx(NORMAL, " - no ASCII mirror"); break;
case 1: 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;
case 0:
PrintAndLogEx(NORMAL, " - no ASCII mirror");
break;
case 1:
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");
switch (fdp_conf) {
case 0: PrintAndLogEx(NORMAL, " - no field detect"); break;
case 1: 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;
case 0:
PrintAndLogEx(NORMAL, " - no field detect");
break;
case 1:
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.
if (tagtype & NTAG_213_F) {
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 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;}
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;
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 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;}
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) {
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 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;}
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;
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 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;}
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;
}
static int ulev1_print_counters(){
static int ulev1_print_counters()
{
PrintAndLogEx(NORMAL, "--- Tag Counters");
uint8_t tear[1] = {0};
uint8_t counter[3] = {0, 0, 0};
@ -700,7 +770,8 @@ static int ulev1_print_counters(){
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, "IC signature public key name : NXP NTAG21x (2013)");
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;
}
static int ulev1_print_version(uint8_t *data){
static int ulev1_print_version(uint8_t *data)
{
PrintAndLogEx(NORMAL, "\n--- Tag Version");
PrintAndLogEx(NORMAL, " Raw bytes : %s", sprint_hex(data, 8));
PrintAndLogEx(NORMAL, " Vendor ID : %02X, %s", data[1], getTagInfo(data[1]));
@ -752,7 +824,8 @@ static int ulc_magic_test(){
return returnValue;
}
*/
static int ul_magic_test(){
static int ul_magic_test()
{
// Magic Ultralight tests
// 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:
@ -767,7 +840,8 @@ static int ul_magic_test(){
return 0;
}
uint32_t GetHF14AMfU_Type(void){
uint32_t GetHF14AMfU_Type(void)
{
TagTypeUL_t tagtype = UNKNOWN;
iso14a_card_select_t card;
@ -812,10 +886,18 @@ uint32_t GetHF14AMfU_Type(void){
else if (version[2] == 0x03) { tagtype = UL_EV1; }
break;
}
case 0x01: tagtype = UL_C; 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;
case 0x01:
tagtype = UL_C;
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
@ -859,10 +941,18 @@ uint32_t GetHF14AMfU_Type(void){
uint8_t nib = (card.uid[1] & 0xf0) >> 4;
switch (nib) {
// 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 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
case 1:
tagtype = MY_D;
break; // or SLE 66RxxS ... up to 512 pages of 8 user 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
//
int CmdHF14AMfUInfo(const char *Cmd){
int CmdHF14AMfUInfo(const char *Cmd)
{
uint8_t authlim = 0xff;
uint8_t data[16] = {0x00};
@ -1138,7 +1229,8 @@ out:
//
// Write Single Block
//
int CmdHF14AMfUWrBl(const char *Cmd){
int CmdHF14AMfUWrBl(const char *Cmd)
{
int blockNo = -1;
bool errors = false;
@ -1239,8 +1331,7 @@ int CmdHF14AMfUWrBl(const char *Cmd){
if (hasAuthKey) {
c.arg[1] = 1;
memcpy(c.d.asBytes + 4, authKeyPtr, 16);
}
else if ( hasPwdKey ) {
} else if (hasPwdKey) {
c.arg[1] = 2;
memcpy(c.d.asBytes + 4, authKeyPtr, 4);
}
@ -1260,7 +1351,8 @@ int CmdHF14AMfUWrBl(const char *Cmd){
//
// Read Single Block
//
int CmdHF14AMfURdBl(const char *Cmd){
int CmdHF14AMfURdBl(const char *Cmd)
{
int blockNo = -1;
bool errors = false;
@ -1344,8 +1436,7 @@ int CmdHF14AMfURdBl(const char *Cmd){
if (hasAuthKey) {
c.arg[1] = 1;
memcpy(c.d.asBytes, authKeyPtr, 16);
}
else if ( hasPwdKey ) {
} else if (hasPwdKey) {
c.arg[1] = 2;
memcpy(c.d.asBytes, authKeyPtr, 4);
}
@ -1360,8 +1451,7 @@ int CmdHF14AMfURdBl(const char *Cmd){
PrintAndLogEx(NORMAL, "\nBlock# | Data | Ascii");
PrintAndLogEx(NORMAL, "-----------------------------");
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);
}
} else {
@ -1370,7 +1460,8 @@ int CmdHF14AMfURdBl(const char *Cmd){
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, "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");
@ -1389,7 +1480,8 @@ int usage_hf_mfu_info(void) {
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, "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`");
@ -1410,7 +1502,8 @@ int usage_hf_mfu_dump(void) {
return 0;
}
int usage_hf_mfu_restore(void){
int usage_hf_mfu_restore(void)
{
PrintAndLogEx(NORMAL, "Restore dumpfile onto card.");
PrintAndLogEx(NORMAL, "Usage: hf mfu restore [h] [l] [s] k <key> n <filename w/o .bin> ");
PrintAndLogEx(NORMAL, " Options :");
@ -1428,7 +1521,8 @@ int usage_hf_mfu_restore(void){
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, "Usage: hf mfu rdbl b <block number> k <key> l\n");
PrintAndLogEx(NORMAL, "Options:");
@ -1443,7 +1537,8 @@ int usage_hf_mfu_rdbl(void) {
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, "Usage: hf mfu wrbl b <block number> d <data> k <key> l\n");
PrintAndLogEx(NORMAL, "Options:");
@ -1458,7 +1553,8 @@ int usage_hf_mfu_wrbl(void) {
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, "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]");
@ -1473,7 +1569,8 @@ int usage_hf_mfu_eload(void) {
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, "\nBe sure to load the emulator memory first!\n");
PrintAndLogEx(NORMAL, "Usage: hf mfu sim t 7 u <uid>");
@ -1489,7 +1586,8 @@ int usage_hf_mfu_sim(void) {
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, " 0 (default): 3DES standard key");
PrintAndLogEx(NORMAL, " 1 : all 0x00 key");
@ -1504,7 +1602,8 @@ int usage_hf_mfu_ucauth(void) {
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, " [password] - (32 hex symbols)");
PrintAndLogEx(NORMAL, "");
@ -1514,7 +1613,8 @@ int usage_hf_mfu_ucsetpwd(void) {
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, " [uid] - (14 hex symbols)");
PrintAndLogEx(NORMAL, "\nThis only works for Magic Ultralight tags.");
@ -1525,7 +1625,8 @@ int usage_hf_mfu_ucsetuid(void) {
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, "Options:");
PrintAndLogEx(NORMAL, " h : this help");
@ -1538,7 +1639,8 @@ int usage_hf_mfu_gendiverse(void){
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, "Options:");
PrintAndLogEx(NORMAL, " h : this help");
@ -1553,11 +1655,13 @@ int usage_hf_mfu_pwdgen(void){
return 0;
}
void printMFUdump(mfu_dump_t* card) {
void printMFUdump(mfu_dump_t *card)
{
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, "\nDataType | Data | Ascii");
PrintAndLogEx(NORMAL, "----------+-------------------------+---------");
@ -1605,48 +1709,95 @@ void printMFUdumpEx(mfu_dump_t* card, uint16_t pages, uint8_t startpage) {
continue;
}
switch (i) {
case 3: lckbit = bit_stat[4]; break;
case 4: lckbit = bit_stat[3]; break;
case 5: lckbit = bit_stat[2]; break;
case 6: lckbit = bit_stat[1]; 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 3:
lckbit = bit_stat[4];
break;
case 4:
lckbit = bit_stat[3];
break;
case 5:
lckbit = bit_stat[2];
break;
case 6:
lckbit = bit_stat[1];
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 17:
case 18:
case 19: lckbit = bit_dyn[6]; break;
case 19:
lckbit = bit_dyn[6];
break;
case 20:
case 21:
case 22:
case 23: lckbit = bit_dyn[5]; break;
case 23:
lckbit = bit_dyn[5];
break;
case 24:
case 25:
case 26:
case 27: lckbit = bit_dyn[4]; break;
case 27:
lckbit = bit_dyn[4];
break;
case 28:
case 29:
case 30:
case 31: lckbit = bit_dyn[2]; break;
case 31:
lckbit = bit_dyn[2];
break;
case 32:
case 33:
case 34:
case 35: lckbit = bit_dyn[1]; break;
case 35:
lckbit = bit_dyn[1];
break;
case 36:
case 37:
case 38:
case 39: lckbit = bit_dyn[0]; break;
case 40: lckbit = bit_dyn[12]; 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;
case 39:
lckbit = bit_dyn[0];
break;
case 40:
lckbit = bit_dyn[12];
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));
}
@ -1656,7 +1807,8 @@ void printMFUdumpEx(mfu_dump_t* card, uint16_t pages, uint8_t startpage) {
//
// Mifare Ultralight / Ultralight-C / Ultralight-EV1
// 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;
char filename[FILE_PATH_SIZE] = {0x00};
@ -1878,7 +2030,8 @@ int CmdHF14AMfUDump(const char *Cmd){
return 0;
}
static void wait4response(uint8_t b){
static void wait4response(uint8_t b)
{
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, 1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
@ -1892,7 +2045,8 @@ static void wait4response(uint8_t b){
//
// Restore dump file onto tag
//
int CmdHF14AMfURestore(const char *Cmd){
int CmdHF14AMfURestore(const char *Cmd)
{
char tempStr[50] = {0};
char filename[FILE_PATH_SIZE] = {0};
@ -2091,7 +2245,8 @@ int CmdHF14AMfURestore(const char *Cmd){
clearCommandBuffer();
SendCommand(&c);
wait4response(b);
printf("."); fflush(stdout);
printf(".");
fflush(stdout);
}
PrintAndLogEx(NORMAL, "\n");
@ -2122,7 +2277,8 @@ int CmdHF14AMfURestore(const char *Cmd){
//
// Load emulator with dump file
//
int CmdHF14AMfUeLoad(const char *Cmd){
int CmdHF14AMfUeLoad(const char *Cmd)
{
char c = tolower(param_getchar(Cmd, 0));
if (c == 'h' || c == 0x00) return usage_hf_mfu_eload();
return CmdHF14AMfELoad(Cmd);
@ -2130,7 +2286,8 @@ int CmdHF14AMfUeLoad(const char *Cmd){
//
// Simulate tag
//
int CmdHF14AMfUSim(const char *Cmd){
int CmdHF14AMfUSim(const char *Cmd)
{
char c = tolower(param_getchar(Cmd, 0));
if (c == 'h' || c == 0x00) return usage_hf_mfu_sim();
return CmdHF14ASim(Cmd);
@ -2143,7 +2300,8 @@ int CmdHF14AMfUSim(const char *Cmd){
//
// Ultralight C Authentication Demo {currently uses hard-coded key}
//
int CmdHF14AMfucAuth(const char *Cmd){
int CmdHF14AMfucAuth(const char *Cmd)
{
uint8_t keyNo = 3;
bool errors = false;
@ -2270,7 +2428,8 @@ int CmdTestDES(const char * cmd)
//
// Mifare Ultralight C - Set password
//
int CmdHF14AMfucSetPwd(const char *Cmd){
int CmdHF14AMfucSetPwd(const char *Cmd)
{
uint8_t pwd[16] = {0x00};
char cmdp = tolower(param_getchar(Cmd, 0));
@ -2305,7 +2464,8 @@ int CmdHF14AMfucSetPwd(const char *Cmd){
//
// Magic UL / UL-C tags - Set UID
//
int CmdHF14AMfucSetUid(const char *Cmd){
int CmdHF14AMfucSetUid(const char *Cmd)
{
UsbCommand c = {CMD_MIFAREU_READBL};
UsbCommand resp;
@ -2374,7 +2534,8 @@ int CmdHF14AMfucSetUid(const char *Cmd){
return 0;
}
int CmdHF14AMfuGenDiverseKeys(const char *Cmd){
int CmdHF14AMfuGenDiverseKeys(const char *Cmd)
{
uint8_t uid[4];
char cmdp = tolower(param_getchar(Cmd, 0));
@ -2405,8 +2566,7 @@ int CmdHF14AMfuGenDiverseKeys(const char *Cmd){
return 1;
}
memcpy(uid, card.uid, sizeof(uid));
}
else {
} else {
if (param_gethex(Cmd, 0, uid, 8)) return usage_hf_mfu_gendiverse();
}
@ -2488,7 +2648,8 @@ int CmdHF14AMfuGenDiverseKeys(const char *Cmd){
return 0;
}
int CmdHF14AMfuPwdGen(const char *Cmd){
int CmdHF14AMfuPwdGen(const char *Cmd)
{
uint8_t uid[7] = {0x00};
char cmdp = tolower(param_getchar(Cmd, 0));
@ -2520,8 +2681,7 @@ int CmdHF14AMfuPwdGen(const char *Cmd){
return 1;
}
memcpy(uid, card.uid, sizeof(uid));
}
else {
} else {
if (param_gethex(Cmd, 0, uid, 14)) return usage_hf_mfu_pwdgen();
}
@ -2560,13 +2720,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdHFMFUltra(const char *Cmd){
int CmdHFMFUltra(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd){
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -30,18 +30,21 @@ static struct {
dynamic_lock_area_t *dynamic_lock_areas; // lock area descriptors
} 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}};
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}};
SendCommand(&c);
}
// 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}};
memcpy(c.d.asBytes, cmd, len);
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)
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) {
uint8_t 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.
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
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.
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};
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.
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_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
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;
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.
static bool topaz_byte_is_locked(uint16_t byteno) {
static bool topaz_byte_is_locked(uint16_t byteno)
{
uint8_t *lockbits;
uint16_t locked_bytes_per_bit;
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
static int topaz_print_CC(uint8_t *data) {
static int topaz_print_CC(uint8_t *data)
{
if (data[0] != 0xe1) {
topaz_tag.size = TOPAZ_STATIC_MEMORY;
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
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_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
// do not include the lock bits and reserved memory. We therefore need to adjust the start of the
// 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;
while (lock_area != NULL) {
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
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_type = 0;
uint16_t TLV_length;
@ -323,7 +336,8 @@ static void topaz_print_control_TLVs(uint8_t *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
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);
@ -343,7 +357,8 @@ static int topaz_read_dynamic_data(void){
// 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) {
PrintAndLogEx(NORMAL, "Dynamic Data blocks:");
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
}
static void topaz_print_NDEF(uint8_t *data) {
static void topaz_print_NDEF(uint8_t *data)
{
// to be done.
}
// read a Topaz tag and print some useful information
int CmdHFTopazReader(const char *Cmd) {
int CmdHFTopazReader(const char *Cmd)
{
int status;
uint8_t atqa[2];
uint8_t rid_response[8];
@ -488,17 +506,20 @@ int CmdHFTopazReader(const char *Cmd) {
return 0;
}
int CmdHFTopazSim(const char *Cmd) {
int CmdHFTopazSim(const char *Cmd)
{
PrintAndLogEx(NORMAL, "not yet implemented");
return 0;
}
int CmdHFTopazCmdRaw(const char *Cmd) {
int CmdHFTopazCmdRaw(const char *Cmd)
{
PrintAndLogEx(NORMAL, "not yet implemented. Use hf 14 raw with option -T.");
return 0;
}
int CmdHFTopazList(const char *Cmd) {
int CmdHFTopazList(const char *Cmd)
{
CmdTraceList("topaz");
return 0;
}
@ -515,13 +536,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdHFTopaz(const char *Cmd) {
int CmdHFTopaz(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
static int CmdHelp(const char *Cmd) {
static int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -23,51 +23,116 @@
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];
memset(asBuff, 0, sizeof(asBuff));
uint32_t mem_avail = 0;
PrintAndLogEx(NORMAL, "\n [ Hardware ] ");
switch (iChipID) {
case 0x270B0A40: sprintf(asBuff,"AT91SAM7S512 Rev A"); break;
case 0x270B0A4F: sprintf(asBuff,"AT91SAM7S512 Rev B"); break;
case 0x270D0940: sprintf(asBuff,"AT91SAM7S256 Rev A"); break;
case 0x270B0941: sprintf(asBuff,"AT91SAM7S256 Rev B"); break;
case 0x270B0942: sprintf(asBuff,"AT91SAM7S256 Rev C"); break;
case 0x270B0943: sprintf(asBuff,"AT91SAM7S256 Rev D"); 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;
case 0x270B0A40:
sprintf(asBuff, "AT91SAM7S512 Rev A");
break;
case 0x270B0A4F:
sprintf(asBuff, "AT91SAM7S512 Rev B");
break;
case 0x270D0940:
sprintf(asBuff, "AT91SAM7S256 Rev A");
break;
case 0x270B0941:
sprintf(asBuff, "AT91SAM7S256 Rev B");
break;
case 0x270B0942:
sprintf(asBuff, "AT91SAM7S256 Rev C");
break;
case 0x270B0943:
sprintf(asBuff, "AT91SAM7S256 Rev D");
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);
switch ((iChipID & 0xE0) >> 5) {
case 1: sprintf(asBuff,"ARM946ES"); break;
case 2: sprintf(asBuff,"ARM7TDMI"); break;
case 4: sprintf(asBuff,"ARM920T"); break;
case 5: sprintf(asBuff,"ARM926EJS"); break;
case 1:
sprintf(asBuff, "ARM946ES");
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);
switch ((iChipID & 0xF00) >> 8) {
case 0: mem_avail = 0; break;
case 1: mem_avail = 8; break;
case 2: mem_avail = 16; 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;
case 0:
mem_avail = 0;
break;
case 1:
mem_avail = 8;
break;
case 2:
mem_avail = 16;
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;
@ -83,69 +148,168 @@ static void lookupChipID(uint32_t iChipID, uint32_t mem_used) {
);
switch ((iChipID & 0xF000) >> 12) {
case 0: sprintf(asBuff,"None"); break;
case 1: sprintf(asBuff,"8K bytes"); break;
case 2: sprintf(asBuff,"16K 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;
case 0:
sprintf(asBuff, "None");
break;
case 1:
sprintf(asBuff, "8K bytes");
break;
case 2:
sprintf(asBuff, "16K 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);
switch ((iChipID & 0xF0000) >> 16) {
case 1: sprintf(asBuff,"1K bytes"); break;
case 2: sprintf(asBuff,"2K bytes"); break;
case 3: sprintf(asBuff,"6K bytes"); break;
case 4: sprintf(asBuff,"112K bytes"); break;
case 5: sprintf(asBuff,"4K bytes"); 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;
case 1:
sprintf(asBuff, "1K bytes");
break;
case 2:
sprintf(asBuff, "2K bytes");
break;
case 3:
sprintf(asBuff, "6K bytes");
break;
case 4:
sprintf(asBuff, "112K bytes");
break;
case 5:
sprintf(asBuff, "4K bytes");
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);
switch ((iChipID & 0xFF00000) >> 20) {
case 0x19: sprintf(asBuff,"AT91SAM9xx Series"); break;
case 0x29: sprintf(asBuff,"AT91SAM9XExx Series"); break;
case 0x34: sprintf(asBuff,"AT91x34 Series"); break;
case 0x37: sprintf(asBuff,"CAP7 Series"); break;
case 0x39: sprintf(asBuff,"CAP9 Series"); break;
case 0x3B: sprintf(asBuff,"CAP11 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;
case 0x19:
sprintf(asBuff, "AT91SAM9xx Series");
break;
case 0x29:
sprintf(asBuff, "AT91SAM9XExx Series");
break;
case 0x34:
sprintf(asBuff, "AT91x34 Series");
break;
case 0x37:
sprintf(asBuff, "CAP7 Series");
break;
case 0x39:
sprintf(asBuff, "CAP9 Series");
break;
case 0x3B:
sprintf(asBuff, "CAP11 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);
switch ((iChipID & 0x70000000) >> 28) {
case 0: sprintf(asBuff,"ROM"); break;
case 1: 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;
case 0:
sprintf(asBuff, "ROM");
break;
case 1:
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);
}
int CmdDetectReader(const char *Cmd) {
int CmdDetectReader(const char *Cmd)
{
UsbCommand c = {CMD_LISTEN_READER_FIELD};
// 'l' means LF - 125/134 kHz
if (*Cmd == 'l') {
@ -162,7 +326,8 @@ int CmdDetectReader(const char *Cmd) {
}
// ## FPGA Control
int CmdFPGAOff(const char *Cmd) {
int CmdFPGAOff(const char *Cmd)
{
UsbCommand c = {CMD_FPGA_MAJOR_MODE_OFF};
clearCommandBuffer();
SendCommand(&c);
@ -170,7 +335,8 @@ int CmdFPGAOff(const char *Cmd) {
}
#ifdef WITH_LCD
int CmdLCD(const char *Cmd) {
int CmdLCD(const char *Cmd)
{
int i, j;
UsbCommand c = {CMD_LCD};
@ -183,7 +349,8 @@ int CmdLCD(const char *Cmd) {
return 0;
}
int CmdLCDReset(const char *Cmd) {
int CmdLCDReset(const char *Cmd)
{
UsbCommand c = {CMD_LCD_RESET, {strtol(Cmd, NULL, 0), 0, 0}};
clearCommandBuffer();
SendCommand(&c);
@ -191,14 +358,16 @@ int CmdLCDReset(const char *Cmd) {
}
#endif
int CmdReadmem(const char *Cmd) {
int CmdReadmem(const char *Cmd)
{
UsbCommand c = {CMD_READ_MEM, {strtol(Cmd, NULL, 0), 0, 0}};
clearCommandBuffer();
SendCommand(&c);
return 0;
}
int CmdReset(const char *Cmd) {
int CmdReset(const char *Cmd)
{
UsbCommand c = {CMD_HARDWARE_RESET};
clearCommandBuffer();
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
* 600kHz.
*/
int CmdSetDivisor(const char *Cmd) {
int CmdSetDivisor(const char *Cmd)
{
UsbCommand c = {CMD_SET_LF_DIVISOR, {strtol(Cmd, NULL, 0), 0, 0}};
if (c.arg[0] < 19 || c.arg[0] > 255) {
@ -223,7 +393,8 @@ int CmdSetDivisor(const char *Cmd) {
return 0;
}
int CmdSetMux(const char *Cmd) {
int CmdSetMux(const char *Cmd)
{
if (strlen(Cmd) < 5) {
PrintAndLogEx(NORMAL, "expected: lopkd | loraw | hipkd | hiraw");
@ -241,11 +412,13 @@ int CmdSetMux(const char *Cmd) {
return 0;
}
int CmdTune(const char *Cmd) {
int CmdTune(const char *Cmd)
{
return CmdTuneSamples(Cmd);
}
int CmdVersion(const char *Cmd) {
int CmdVersion(const char *Cmd)
{
bool silent = (Cmd[0] == 's' || Cmd[0] == 'S');
if (silent)
@ -284,7 +457,8 @@ int CmdVersion(const char *Cmd) {
return 0;
}
int CmdStatus(const char *Cmd) {
int CmdStatus(const char *Cmd)
{
clearCommandBuffer();
UsbCommand c = {CMD_STATUS};
SendCommand(&c);
@ -293,7 +467,8 @@ int CmdStatus(const char *Cmd) {
return 0;
}
int CmdPing(const char *Cmd) {
int CmdPing(const char *Cmd)
{
clearCommandBuffer();
UsbCommand resp;
UsbCommand c = {CMD_PING};
@ -324,13 +499,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdHW(const char *Cmd) {
int CmdHW(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -13,7 +13,8 @@ bool g_lf_threshold_set = false;
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, "Options:");
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");
return 0;
}
int usage_lf_read(void){
int usage_lf_read(void)
{
PrintAndLogEx(NORMAL, "Usage: lf read [h] [s] [d numofsamples]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h This help");
@ -41,7 +43,8 @@ int usage_lf_read(void){
PrintAndLogEx(NORMAL, " lf read s");
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, "Usage: lf snoop [h]");
PrintAndLogEx(NORMAL, "Options:");
@ -50,7 +53,8 @@ int usage_lf_snoop(void) {
PrintAndLogEx(NORMAL, "Use 'lf config' to set parameters.");
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, "Options:");
PrintAndLogEx(NORMAL, " h This help");
@ -73,7 +77,8 @@ int usage_lf_config(void) {
PrintAndLogEx(NORMAL, " Performs a snoop (no active field)");
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, "there are about four FSK modulations to know of.");
PrintAndLogEx(NORMAL, "FSK1 - where fc/8 = high and fc/5 = low");
@ -98,7 +103,8 @@ int usage_lf_simfsk(void) {
PrintAndLogEx(NORMAL, "");
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, "Options:");
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");
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, "Options:");
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");
return 0;
}
int usage_lf_find(void){
int usage_lf_find(void)
{
PrintAndLogEx(NORMAL, "Usage: lf search [h] <0|1> [u]");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Options:");
@ -141,7 +149,8 @@ int usage_lf_find(void){
/* 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}};
bool errors = false;
@ -185,7 +194,8 @@ int CmdLFCommandRead(const char *Cmd) {
return 0;
}
int CmdFlexdemod(const char *Cmd) {
int CmdFlexdemod(const char *Cmd)
{
if (GraphTraceLen < 0)
return 0;
@ -262,7 +272,8 @@ int CmdFlexdemod(const char *Cmd) {
return 0;
}
int CmdLFSetConfig(const char *Cmd) {
int CmdLFSetConfig(const char *Cmd)
{
uint8_t divisor = 0;//Frequency divisor
uint8_t bps = 0; // Bits per sample
uint8_t decimation = 0; //How many to keep
@ -330,7 +341,8 @@ int CmdLFSetConfig(const char *Cmd) {
return 0;
}
bool lf_read(bool silent, uint32_t samples) {
bool lf_read(bool silent, uint32_t samples)
{
if (IsOffline()) return false;
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {silent, samples, 0}};
clearCommandBuffer();
@ -351,7 +363,8 @@ bool lf_read(bool silent, uint32_t samples) {
return true;
}
int CmdLFRead(const char *Cmd) {
int CmdLFRead(const char *Cmd)
{
if (IsOffline()) return 0;
@ -384,7 +397,8 @@ int CmdLFRead(const char *Cmd) {
return lf_read(silent, samples);
}
int CmdLFSnoop(const char *Cmd) {
int CmdLFSnoop(const char *Cmd)
{
uint8_t cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_lf_snoop();
@ -396,7 +410,8 @@ int CmdLFSnoop(const char *Cmd) {
return 0;
}
static void ChkBitstream(const char *str) {
static void ChkBitstream(const char *str)
{
// convert to bitstream if necessary
for (int i = 0; i < (int)(GraphTraceLen / 2); i++) {
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)
// 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_HF 2
@ -429,7 +445,8 @@ int CmdLFSim(const char *Cmd) {
clearCommandBuffer();
SendCommand(&c);
WaitForResponse(CMD_ACK, NULL);
printf("."); fflush(stdout);
printf(".");
fflush(stdout);
}
PrintAndLogEx(NORMAL, "Simulating");
@ -442,7 +459,8 @@ int CmdLFSim(const char *Cmd) {
// by marshmellow - sim fsk data given clock, fcHigh, fcLow, invert
// - 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
// otherwise will need FChigh, FClow, Clock, and bitstream
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
// - allow pull data from DemodBuffer
int CmdLFaskSim(const char *Cmd) {
int CmdLFaskSim(const char *Cmd)
{
// autodetect clock from Graphbuffer if using demod buffer
// needs clock, invert, manchester/raw as m or r, separator as s, and bitstream
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) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h': return usage_lf_simask();
case 'h':
return usage_lf_simask();
case 'i':
invert = 1;
cmdp++;
@ -627,7 +647,8 @@ int CmdLFaskSim(const char *Cmd) {
// by marshmellow - sim psk data given carrier, clock, invert
// - 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
//will need carrier, Clock, and bitstream
uint8_t carrier = 0, clk = 0;
@ -733,7 +754,8 @@ int CmdLFpskSim(const char *Cmd) {
return 0;
}
int CmdLFSimBidir(const char *Cmd) {
int CmdLFSimBidir(const char *Cmd)
{
// Set ADC to twice the carrier for a slight supersampling
// HACK: not implemented in ARMSRC.
PrintAndLogEx(INFO, "Not implemented yet.");
@ -743,7 +765,8 @@ int CmdLFSimBidir(const char *Cmd) {
}
// 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
// data bits that happen to be the same everywhere? That would be
// lovely to know.
@ -816,7 +839,8 @@ int CmdVchDemod(const char *Cmd) {
}
//by marshmellow
bool CheckChipType(bool getDeviceData) {
bool CheckChipType(bool getDeviceData)
{
bool retval = false;
@ -849,7 +873,8 @@ out:
}
//by marshmellow
int CmdLFfind(const char *Cmd) {
int CmdLFfind(const char *Cmd)
{
int ans = 0;
size_t minLength = 2000;
char cmdp = tolower(param_getchar(Cmd, 0));
@ -933,7 +958,8 @@ int CmdLFfind(const char *Cmd) {
//fsk
if (GetFskClock("", false)) {
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}
};
int CmdLF(const char *Cmd) {
int CmdLF(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -14,7 +14,8 @@
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, "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.");
@ -30,7 +31,8 @@ int usage_lf_awid_read(void) {
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, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "");
@ -47,7 +49,8 @@ int usage_lf_awid_sim(void) {
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, "The T55x7 must be on the antenna when issuing this command. T55x7 blocks are calculated and printed in the process.");
PrintAndLogEx(NORMAL, "");
@ -65,7 +68,8 @@ int usage_lf_awid_clone(void) {
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, "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");
@ -86,7 +90,8 @@ int usage_lf_awid_brute(void){
return 0;
}
static bool sendPing(void){
static bool sendPing(void)
{
UsbCommand ping = {CMD_PING, {1, 2, 3}};
SendCommand(&ping);
SendCommand(&ping);
@ -98,7 +103,8 @@ static bool sendPing(void){
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)
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
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
bits[7] = 1;
@ -176,7 +183,8 @@ int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits) {
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) {
case 50:
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.
int CmdAWIDRead(const char *Cmd) {
int CmdAWIDRead(const char *Cmd)
{
lf_read(true, 12000);
return CmdAWIDDemod(Cmd);
}
// this read loops on device side.
// 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();
uint8_t findone = (Cmd[0] == '1') ? 1 : 0;
@ -239,7 +249,8 @@ int CmdAWIDRead_device(const char *Cmd) {
//by marshmellow
//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
int CmdAWIDDemod(const char *Cmd) {
int CmdAWIDDemod(const char *Cmd)
{
uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0};
size_t size = getFromGraphBuf(bits);
if (size == 0) {
@ -369,7 +380,8 @@ int CmdAWIDDemod(const char *Cmd) {
return 1;
}
int CmdAWIDSim(const char *Cmd) {
int CmdAWIDSim(const char *Cmd)
{
uint32_t fc = 0, cn = 0;
uint8_t fmtlen = 0;
uint8_t bits[96];
@ -409,7 +421,8 @@ int CmdAWIDSim(const char *Cmd) {
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 fc = 0, cn = 0;
uint8_t fmtlen = 0;
@ -460,7 +473,8 @@ int CmdAWIDClone(const char *Cmd) {
return 0;
}
int CmdAWIDBrute(const char *Cmd) {
int CmdAWIDBrute(const char *Cmd)
{
bool errors = false, verbose = false;
uint32_t fc = 0, cn = 0, delay = 1000;
@ -538,7 +552,8 @@ int CmdAWIDBrute(const char *Cmd) {
return 2;
}
if (ukbhit()) {
int gc = getchar(); (void)gc;
int gc = getchar();
(void)gc;
PrintAndLogEx(INFO, "aborted via keyboard!");
return sendPing();
}
@ -565,13 +580,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdLFAWID(const char *Cmd) {
int CmdLFAWID(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

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

View file

@ -15,7 +15,8 @@ uint64_t g_em410xid = 0;
static int CmdHelp(const char *Cmd);
//////////////// 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, "Options:");
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");
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, "");
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");
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, "");
PrintAndLogEx(NORMAL, "Usage: lf em 410x_spoof [h]");
@ -54,7 +57,8 @@ int usage_lf_em410x_ws(void) {
PrintAndLogEx(NORMAL, " lf em 410x_spoof");
return 0;
}
int usage_lf_em410x_clone(void) {
int usage_lf_em410x_clone(void)
{
PrintAndLogEx(NORMAL, "Simulating EM410x tag");
PrintAndLogEx(NORMAL, "");
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");
return 0;
}
int usage_lf_em410x_sim(void) {
int usage_lf_em410x_sim(void)
{
PrintAndLogEx(NORMAL, "Simulating EM410x tag");
PrintAndLogEx(NORMAL, "");
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");
return 0;
}
int usage_lf_em410x_brute(void) {
int usage_lf_em410x_brute(void)
{
PrintAndLogEx(NORMAL, "Bruteforcing by emulating EM410x tag");
PrintAndLogEx(NORMAL, "");
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
int usage_lf_em4x50_dump(void) {
int usage_lf_em4x50_dump(void)
{
PrintAndLogEx(NORMAL, "Dump EM4x50/EM4x69. Tag must be on antenna. ");
PrintAndLogEx(NORMAL, "");
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");
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, "");
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");
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, "");
PrintAndLogEx(NORMAL, "Usage: lf em 4x50_write [h] <address> <data> <pwd>");
@ -139,7 +148,8 @@ int usage_lf_em4x50_write(void) {
}
//////////////// 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, "");
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");
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, "");
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");
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, "");
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");
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, "");
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
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];
uint32_t n;
@ -248,7 +262,8 @@ void ConstructEM410xEmulGraph(const char *uid,const uint8_t clock) {
//by marshmellow
//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;
@ -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
* 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;
uint8_t bits[512] = {0};
size_t size = sizeof(bits);
@ -393,21 +409,24 @@ int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo ) {
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;
if (!ASKDemod_ext(Cmd, false, false, 1, &st)) return 0;
return AskEm410xDecode(verbose, hi, lo);
}
// 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);
return CmdEM410xDemod(Cmd);
}
// this read loops on device side.
// 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));
uint8_t findone = (cmdp == '1') ? 1 : 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
//attempts to demodulate ask while decoding manchester
//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));
if (strlen(Cmd) > 10 || cmdp == 'h') return usage_lf_em410x_demod();
@ -433,7 +453,8 @@ int CmdEM410xDemod(const char *Cmd) {
}
// emulate an EM410X tag
int CmdEM410xSim(const char *Cmd) {
int CmdEM410xSim(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_lf_em410x_sim();
@ -458,7 +479,8 @@ int CmdEM410xSim(const char *Cmd) {
return 0;
}
int CmdEM410xBrute(const char *Cmd) {
int CmdEM410xBrute(const char *Cmd)
{
char filename[FILE_PATH_SIZE] = {0};
FILE *f = NULL;
char buf[11];
@ -548,7 +570,8 @@ int CmdEM410xBrute(const char *Cmd) {
testuid[10] = 0;
if (ukbhit()) {
int gc = getchar(); (void)gc;
int gc = getchar();
(void)gc;
PrintAndLogEx(WARNING, "\nAborted via keyboard!\n");
free(uidBlock);
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
*/
int CmdEM410xWatch(const char *Cmd) {
int CmdEM410xWatch(const char *Cmd)
{
do {
if (ukbhit()) {
int gc = getchar(); (void)gc;
int gc = getchar();
(void)gc;
PrintAndLogEx(WARNING, "\naborted via keyboard!\n");
break;
}
@ -593,7 +618,8 @@ int CmdEM410xWatch(const char *Cmd) {
}
//currently only supports manchester modulations
int CmdEM410xWatchnSpoof(const char *Cmd) {
int CmdEM410xWatchnSpoof(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_lf_em410x_ws();
@ -605,7 +631,8 @@ int CmdEM410xWatchnSpoof(const char *Cmd) {
return 0;
}
int CmdEM410xWrite(const char *Cmd) {
int CmdEM410xWrite(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 0x00 || cmdp == 'h') return usage_lf_em410x_write();
@ -666,7 +693,8 @@ int CmdEM410xWrite(const char *Cmd) {
}
//**************** 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;
uint8_t colP = 0;
//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;
}
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;
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
// |- must be zero
bool EMwordparitytest(uint8_t *bits){
bool EMwordparitytest(uint8_t *bits)
{
// last row/col parity must be 0
if (bits[44] != 0) return false;
@ -732,7 +762,8 @@ bool EMwordparitytest(uint8_t *bits){
//////////////// 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;
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.
*/
//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};
int clk = 0, invert = 0, tol = 0, phaseoff;
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 + 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+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;
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 + 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+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;
break;
}
@ -970,18 +1000,21 @@ int EM4x50Read(const char *Cmd, bool verbose) {
return (int)AllPTest;
}
int CmdEM4x50Read(const char *Cmd) {
int CmdEM4x50Read(const char *Cmd)
{
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
if (ctmp == 'h') return usage_lf_em4x50_read();
return EM4x50Read(Cmd, true);
}
int CmdEM4x50Write(const char *Cmd){
int CmdEM4x50Write(const char *Cmd)
{
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
if (ctmp == 'h') return usage_lf_em4x50_write();
PrintAndLogEx(NORMAL, "no implemented yet");
return 0;
}
int CmdEM4x50Dump(const char *Cmd){
int CmdEM4x50Dump(const char *Cmd)
{
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
if (ctmp == 'h') return usage_lf_em4x50_dump();
PrintAndLogEx(NORMAL, "no implemented yet");
@ -990,7 +1023,8 @@ int CmdEM4x50Dump(const char *Cmd){
#define EM_PREAMBLE_LEN 6
// 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)
uint8_t got[6000];
@ -1011,7 +1045,8 @@ bool downloadSamplesEM(){
}
// em_demod
bool doPreambleSearch(size_t *startIdx){
bool doPreambleSearch(size_t *startIdx)
{
// sanity check
if (DemodBufferLen < EM_PREAMBLE_LEN) {
@ -1032,7 +1067,8 @@ bool doPreambleSearch(size_t *startIdx){
return true;
}
bool detectFSK(){
bool detectFSK()
{
// detect fsk clock
if (!GetFskClock("", false)) {
PrintAndLogEx(DEBUG, "DEBUG: Error - EM: FSK clock failed");
@ -1047,7 +1083,8 @@ bool detectFSK(){
return true;
}
// PSK clocks should be easy to detect ( but difficult to demod a non-repeating pattern... )
bool detectPSK(){
bool detectPSK()
{
int ans = GetPskClock("", false);
if (ans <= 0) {
PrintAndLogEx(DEBUG, "DEBUG: Error - EM: PSK clock failed");
@ -1071,7 +1108,8 @@ bool detectPSK(){
return true;
}
// try manchester - NOTE: ST only applies to T55x7 tags.
bool detectASK_MAN(){
bool detectASK_MAN()
{
bool stcheck = false;
if (!ASKDemod_ext("0 0 0", false, false, 1, &stcheck)) {
PrintAndLogEx(DEBUG, "DEBUG: Error - EM: ASK/Manchester Demod failed");
@ -1079,7 +1117,8 @@ bool detectASK_MAN(){
}
return true;
}
bool detectASK_BI(){
bool detectASK_BI()
{
int ans = ASKbiphaseDemod("0 0 1", false);
if (!ans) {
PrintAndLogEx(DEBUG, "DEBUG: Error - EM: ASK/biphase normal demod failed");
@ -1094,7 +1133,8 @@ bool detectASK_BI(){
}
// 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.
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
// should cover 90% of known used configs
// the rest will need to be manually demoded for now...
bool demodEM4x05resp(uint32_t *word) {
bool demodEM4x05resp(uint32_t *word)
{
size_t idx = 0;
*word = 0;
if (detectASK_MAN() && doPreambleSearch(&idx))
@ -1141,7 +1182,8 @@ bool demodEM4x05resp(uint32_t *word) {
}
//////////////// 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}};
clearCommandBuffer();
SendCommand(&c);
@ -1157,7 +1199,8 @@ int EM4x05ReadWord_ext(uint8_t addr, uint32_t pwd, bool usePwd, uint32_t *word)
return demodEM4x05resp(word);
}
int CmdEM4x05Dump(const char *Cmd) {
int CmdEM4x05Dump(const char *Cmd)
{
uint8_t addr = 0;
uint32_t pwd = 0;
bool usePwd = false;
@ -1190,7 +1233,8 @@ int CmdEM4x05Dump(const char *Cmd) {
return success;
}
int CmdEM4x05Read(const char *Cmd) {
int CmdEM4x05Read(const char *Cmd)
{
uint8_t addr;
uint32_t pwd;
bool usePwd = false;
@ -1220,7 +1264,8 @@ int CmdEM4x05Read(const char *Cmd) {
return isOk;
}
int CmdEM4x05Write(const char *Cmd) {
int CmdEM4x05Write(const char *Cmd)
{
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_em4x05_write();
@ -1268,7 +1313,8 @@ int CmdEM4x05Write(const char *Cmd) {
return isOk;
}
void printEM4x05config(uint32_t wordData) {
void printEM4x05config(uint32_t wordData)
{
uint16_t datarate = (((wordData & 0x3F) + 1) * 2);
uint8_t encoder = ((wordData >> 6) & 0xF);
char enc[14];
@ -1283,31 +1329,69 @@ void printEM4x05config(uint32_t wordData) {
uint8_t numblks = EM4x05_GET_NUM_BLOCKS(wordData);
uint8_t LWR = numblks + 5 - 1; //last word read
switch (encoder) {
case 0: snprintf(enc,sizeof(enc),"NRZ"); break;
case 1: snprintf(enc,sizeof(enc),"Manchester"); break;
case 2: snprintf(enc,sizeof(enc),"Biphase"); break;
case 3: 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;
case 0:
snprintf(enc, sizeof(enc), "NRZ");
break;
case 1:
snprintf(enc, sizeof(enc), "Manchester");
break;
case 2:
snprintf(enc, sizeof(enc), "Biphase");
break;
case 3:
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) {
case 0: snprintf(cf,sizeof(cf),"RF/2"); 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;
case 0:
snprintf(cf, sizeof(cf), "RF/2");
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) {
case 0: 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;
case 0:
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 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");
}
void printEM4x05info(uint32_t block0, uint32_t serial) {
void printEM4x05info(uint32_t block0, uint32_t serial)
{
uint8_t chipType = (block0 >> 1) & 0xF;
uint8_t cap = (block0 >> 5) & 3;
uint16_t custCode = (block0 >> 9) & 0x3FF;
switch (chipType) {
case 9: PrintAndLogEx(NORMAL, "\n Chip Type: %u | EM4305", 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;
case 9:
PrintAndLogEx(NORMAL, "\n Chip Type: %u | EM4305", 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
default: PrintAndLogEx(NORMAL, " Chip Type: %u Unknown", chipType); break;
default:
PrintAndLogEx(NORMAL, " Chip Type: %u Unknown", chipType);
break;
}
switch (cap) {
case 3: PrintAndLogEx(NORMAL, " Cap Type: %u | 330pF",cap); break;
case 2: 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;
case 3:
PrintAndLogEx(NORMAL, " Cap Type: %u | 330pF", cap);
break;
case 2:
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");
@ -1362,7 +1467,8 @@ void printEM4x05info(uint32_t block0, uint32_t 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++) {
PrintAndLogEx(NORMAL, " Word: %02u | %s", i, (((1 << i) & word) || i < 2) ? "Is Write Locked" : "Is Not Write Locked");
if (i == 14)
@ -1371,12 +1477,14 @@ void printEM4x05ProtectionBits(uint32_t word) {
}
//quick test for EM4x05/EM4x69 tag
bool EM4x05IsBlock0(uint32_t *word) {
bool EM4x05IsBlock0(uint32_t *word)
{
int res = EM4x05ReadWord_ext(0, 0, false, word);
return (res > 0) ? true : false;
}
int CmdEM4x05Info(const char *Cmd) {
int CmdEM4x05Info(const char *Cmd)
{
#define EM_SERIAL_BLOCK 1
#define EM_CONFIG_BLOCK 4
#define EM_PROT1_BLOCK 14
@ -1445,13 +1553,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdLFEM4X(const char *Cmd) {
int CmdLFEM4X(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -31,7 +31,8 @@
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, "Usage: lf fdx clone [h] <country id> <animal id> <Q5>");
PrintAndLogEx(NORMAL, "Options:");
@ -49,7 +50,8 @@ int usage_lf_fdx_clone(void){
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, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "");
@ -66,7 +68,8 @@ int usage_lf_fdx_sim(void) {
// Ask/Biphase Demod then try to locate an ISO 11784/85 ID
// 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
if (*size < 128 * 2) return -1;
size_t startIdx = 0;
@ -79,7 +82,8 @@ int detectFDXB(uint8_t *dest, size_t *size) {
}
// 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) {
animalid &= 0x3FFFFFFFFF;
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
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 ]
*/
int CmdFDXBdemodBI(const char *Cmd){
int CmdFDXBdemodBI(const char *Cmd)
{
int clk = 32;
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
//almost the same demod as cmddata.c/CmdFDXBdemodBI
int CmdFdxDemod(const char *Cmd) {
int CmdFdxDemod(const char *Cmd)
{
//Differential Biphase / di-phase (inverted biphase)
//get binary from ask wave
@ -301,12 +308,14 @@ int CmdFdxDemod(const char *Cmd) {
return 1;
}
int CmdFdxRead(const char *Cmd) {
int CmdFdxRead(const char *Cmd)
{
lf_read(true, 10000);
return CmdFdxDemod(Cmd);
}
int CmdFdxClone(const char *Cmd) {
int CmdFdxClone(const char *Cmd)
{
uint32_t countryid = 0;
uint64_t animalid = 0;
@ -358,7 +367,8 @@ int CmdFdxClone(const char *Cmd) {
return 0;
}
int CmdFdxSim(const char *Cmd) {
int CmdFdxSim(const char *Cmd)
{
uint32_t countryid = 0;
uint64_t animalid = 0;
@ -397,13 +407,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdLFFdx(const char *Cmd) {
int CmdLFFdx(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -11,7 +11,8 @@
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, "The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated. ");
PrintAndLogEx(NORMAL, "Currently work only on 26bit");
@ -27,7 +28,8 @@ int usage_lf_guard_clone(void){
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, "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.");
@ -45,7 +47,8 @@ int usage_lf_guard_sim(void) {
}
// 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 i;
@ -144,7 +147,8 @@ int GetGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) {
// error returns as -x
// success returns start position in bitstream
// 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;
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
// but will leave the GraphBuffer intact.
//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
//get binary from ask wave
@ -253,12 +258,14 @@ int CmdGuardDemod(const char *Cmd) {
return 1;
}
int CmdGuardRead(const char *Cmd) {
int CmdGuardRead(const char *Cmd)
{
lf_read(true, 10000);
return CmdGuardDemod(Cmd);
}
int CmdGuardClone(const char *Cmd) {
int CmdGuardClone(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_guard_clone();
@ -309,7 +316,8 @@ int CmdGuardClone(const char *Cmd) {
return 0;
}
int CmdGuardSim(const char *Cmd) {
int CmdGuardSim(const char *Cmd)
{
// Guard uses: clk: 64, invert: 0, encoding: 2 (ASK Biphase)
uint8_t clock = 64, encoding = 2, separator = 0, invert = 0;
@ -355,13 +363,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdLFGuard(const char *Cmd) {
int CmdLFGuard(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -16,7 +16,8 @@
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, "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.");
@ -31,7 +32,8 @@ int usage_lf_hid_read(void){
PrintAndLogEx(NORMAL, " lf hid read 1");
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, "");
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");
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, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "");
@ -56,7 +59,8 @@ int usage_lf_hid_sim(void){
PrintAndLogEx(NORMAL, " lf hid sim 2006ec0c86");
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, "");
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");
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, "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");
@ -91,7 +96,8 @@ int usage_lf_hid_brute(void){
}
// 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}};
SendCommand(&ping);
SendCommand(&ping);
@ -102,7 +108,8 @@ static bool sendPing(void){
return false;
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.
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)
//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
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
uint32_t hi2 = 0, hi = 0, lo = 0;
@ -198,8 +206,7 @@ int CmdHIDDemod(const char *Cmd) {
cardnum = (lo >> 1) & 0xFFFFF;
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;
fc = 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.
int CmdHIDRead(const char *Cmd) {
int CmdHIDRead(const char *Cmd)
{
lf_read(true, 12000);
return CmdHIDDemod(Cmd);
}
// this read loops on device side.
// 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();
uint8_t findone = (Cmd[0] == '1') ? 1 : 0;
@ -240,7 +249,8 @@ int CmdHIDRead_device(const char *Cmd) {
return 0;
}
int CmdHIDSim(const char *Cmd) {
int CmdHIDSim(const char *Cmd)
{
uint32_t hi = 0, lo = 0;
uint32_t n = 0, i = 0;
@ -261,7 +271,8 @@ int CmdHIDSim(const char *Cmd) {
return 0;
}
int CmdHIDClone(const char *Cmd) {
int CmdHIDClone(const char *Cmd)
{
uint32_t hi2 = 0, hi = 0, lo = 0;
uint32_t n = 0, i = 0;
@ -308,7 +319,8 @@ typedef struct {
size_t Wiegand_n;
} wiegand_t;
static void addHIDMarker(uint8_t fmtlen, uint8_t *out) {
static void addHIDMarker(uint8_t fmtlen, uint8_t *out)
{
// temp array
uint8_t arr[BITS];
memset(arr, 0, BITS);
@ -334,7 +346,8 @@ static void addHIDMarker(uint8_t fmtlen, uint8_t *out) {
arr[BITS - 38] = 1;
memcpy(out, arr, BITS);
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)
{
uint8_t wiegand[24];
num_to_bytebits(fc, 8, wiegand);
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 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];
num_to_bytebits(fc, 16, wiegand);
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;
// *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
// cardno 18 - 36 - 19 bit
// 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);
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
// cardno 1-35 34 bits
// Even Parity 0th bit 1-18
@ -422,23 +439,34 @@ static void calc37H(uint64_t cardno, uint8_t *out){
// *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);
switch (fmtlen) {
case 26: calc26(fc, cn32, bits); break;
case 26:
calc26(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 37: calc37S(fc, cn32, bits); break;
case 38: calc37H(cardno, bits); break;
case 37:
calc37S(fc, cn32, bits);
break;
case 38:
calc37H(cardno, bits);
break;
// case 40 : calc40(cardno, bits); break;
// case 44 : { break; }
// case 84 : { break; }
default: break;
default:
break;
}
}
int CmdHIDWiegand(const char *Cmd) {
int CmdHIDWiegand(const char *Cmd)
{
uint32_t oem = 0, fc = 0;
uint64_t cardnum = 0;
uint64_t blocks = 0, wiegand = 0;
@ -483,7 +511,8 @@ int CmdHIDWiegand(const char *Cmd) {
return 0;
}
int CmdHIDBrute(const char *Cmd){
int CmdHIDBrute(const char *Cmd)
{
bool errors = false, verbose = false;
uint32_t fc = 0, cn = 0, delay = 1000;
@ -554,7 +583,8 @@ int CmdHIDBrute(const char *Cmd){
}
if (ukbhit()) {
int gc = getchar(); (void)gc;
int gc = getchar();
(void)gc;
PrintAndLogEx(INFO, "aborted via keyboard!");
return sendPing();
}
@ -582,13 +612,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdLFHID(const char *Cmd) {
int CmdLFHID(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

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

View file

@ -12,7 +12,8 @@
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, "By default, values are printed and logged until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "");
@ -25,7 +26,8 @@ int usage_lf_indala_demod(void) {
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, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "");
@ -39,7 +41,8 @@ int usage_lf_indala_sim(void) {
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, "The T55x7 must be on the antenna when issuing this command. T55x7 blocks are calculated and printed in the process.");
PrintAndLogEx(NORMAL, "");
@ -56,7 +59,8 @@ int usage_lf_indala_clone(void) {
// redesigned by marshmellow adjusted from existing decode functions
// 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
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};
@ -78,7 +82,8 @@ int indala64decode(uint8_t *dest, size_t *size, uint8_t *invert) {
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...)
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};
@ -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.
int CmdIndalaRead(const char *Cmd) {
int CmdIndalaRead(const char *Cmd)
{
lf_read(true, 30000);
return CmdIndalaDemod(Cmd);
}
@ -114,7 +120,8 @@ int CmdIndalaRead(const char *Cmd) {
// Indala 26 bit decode
// by marshmellow
// optional arguments - same as PSKDemod (clock & invert & maxerr)
int CmdIndalaDemod(const char *Cmd) {
int CmdIndalaDemod(const char *Cmd)
{
int ans;
if (strlen(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
// 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.
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
int state = -1;
int count = 0;
@ -314,8 +322,7 @@ int CmdIndalaDemodAlt(const char *Cmd) {
}
}
PrintAndLogEx(SUCCESS, "UID | %s (%x%08x)", showbits, uid1, uid2);
}
else {
} else {
uid3 = uid4 = uid5 = uid6 = uid7 = 0;
for (idx = 0; idx < 224; idx++) {
@ -375,7 +382,8 @@ int CmdIndalaDemodAlt(const char *Cmd) {
return 1;
}
int CmdIndalaSim(const char *Cmd) {
int CmdIndalaSim(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_indala_sim();
@ -420,7 +428,8 @@ int CmdIndalaSim(const char *Cmd) {
}
// iceman - needs refactoring
int CmdIndalaClone(const char *Cmd) {
int CmdIndalaClone(const char *Cmd)
{
UsbCommand c = {0};
uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
uid1 = uid2 = uid3 = uid4 = uid5 = uid6 = uid7 = 0;
@ -473,13 +482,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdLFINDALA(const char *Cmd){
int CmdLFINDALA(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -12,7 +12,8 @@
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, "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.");
@ -28,7 +29,8 @@ int usage_lf_io_read(void) {
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, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "");
@ -44,7 +46,8 @@ int usage_lf_io_sim(void) {
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, "The T55x7 must be on the antenna when issuing this command. T55x7 blocks are calculated and printed in the process.");
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.
int CmdIOProxRead(const char *Cmd) {
int CmdIOProxRead(const char *Cmd)
{
lf_read(true, 12000);
return CmdIOProxDemod(Cmd);
}
// this read loops on device side.
// 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();
int findone = (Cmd[0] == '1') ? 1 : 0;
UsbCommand c = {CMD_IO_DEMOD_FSK, {findone, 0, 0}};
@ -80,7 +85,8 @@ int CmdIOProxRead_device(const char *Cmd) {
//by marshmellow
//IO-Prox demod - FSK RF/64 with preamble of 000000001
//print ioprox ID and some format details
int CmdIOProxDemod(const char *Cmd) {
int CmdIOProxDemod(const char *Cmd)
{
int retval = 0;
int idx = 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
//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
uint8_t pos = 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;
}
int CmdIOProxSim(const char *Cmd) {
int CmdIOProxSim(const char *Cmd)
{
uint16_t cn = 0;
uint8_t version = 0, fc = 0;
uint8_t bits[64];
@ -288,7 +296,8 @@ int CmdIOProxSim(const char *Cmd) {
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};
uint16_t cn = 0;
@ -340,13 +349,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdLFIO(const char *Cmd){
int CmdLFIO(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -12,7 +12,8 @@
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, "Usage: lf jablotron clone [h] <card ID> <Q5>");
PrintAndLogEx(NORMAL, "Options:");
@ -25,7 +26,8 @@ int usage_lf_jablotron_clone(void){
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, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "");
@ -39,7 +41,8 @@ int usage_lf_jablotron_sim(void) {
return 0;
}
static uint8_t jablontron_chksum(uint8_t *bits){
static uint8_t jablontron_chksum(uint8_t *bits)
{
uint8_t chksum = 0;
for (int i = 16; i < 56; i += 8) {
chksum += bytebits_to_byte(bits + i, 8);
@ -48,7 +51,8 @@ static uint8_t jablontron_chksum(uint8_t *bits){
return chksum;
}
int getJablotronBits(uint64_t fullcode, uint8_t *bits) {
int getJablotronBits(uint64_t fullcode, uint8_t *bits)
{
//preamp
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
// the parameter *bits needs to be demoded before call
// 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
size_t startIdx = 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;
}
static uint64_t getJablontronCardId( uint64_t rawcode ){
static uint64_t getJablontronCardId(uint64_t rawcode)
{
uint64_t id = 0;
uint8_t bytes[] = {0, 0, 0, 0, 0};
num_to_bytes(rawcode, 5, bytes);
@ -91,7 +97,8 @@ static uint64_t getJablontronCardId( uint64_t rawcode ){
}
//see ASKDemod for what args are accepted
int CmdJablotronDemod(const char *Cmd) {
int CmdJablotronDemod(const char *Cmd)
{
//Differential Biphase / di-phase (inverted biphase)
//get binary from ask wave
@ -145,12 +152,14 @@ int CmdJablotronDemod(const char *Cmd) {
return 1;
}
int CmdJablotronRead(const char *Cmd) {
int CmdJablotronRead(const char *Cmd)
{
lf_read(true, 10000);
return CmdJablotronDemod(Cmd);
}
int CmdJablotronClone(const char *Cmd) {
int CmdJablotronClone(const char *Cmd)
{
uint64_t fullcode = 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;
}
int CmdJablotronSim(const char *Cmd) {
int CmdJablotronSim(const char *Cmd)
{
uint64_t fullcode = 0;
char cmdp = tolower(param_getchar(Cmd, 0));
@ -238,13 +248,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdLFJablotron(const char *Cmd) {
int CmdLFJablotron(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -11,7 +11,8 @@
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, "Usage: lf keri clone [h] <id> <Q5>");
PrintAndLogEx(NORMAL, "Options:");
@ -24,7 +25,8 @@ int usage_lf_keri_clone(void){
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, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "");
@ -39,7 +41,8 @@ int usage_lf_keri_sim(void) {
}
// 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_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;
}
int CmdKeriDemod(const char *Cmd) {
int CmdKeriDemod(const char *Cmd)
{
if (!PSKDemod("", false)) {
PrintAndLogEx(DEBUG, "DEBUG: Error - KERI: PSK1 Demod failed");
@ -122,12 +126,14 @@ int CmdKeriDemod(const char *Cmd) {
return 1;
}
int CmdKeriRead(const char *Cmd) {
int CmdKeriRead(const char *Cmd)
{
lf_read(true, 10000);
return CmdKeriDemod(Cmd);
}
int CmdKeriClone(const char *Cmd) {
int CmdKeriClone(const char *Cmd)
{
uint32_t internalid = 0;
uint32_t blocks[3] = {
@ -137,7 +143,8 @@ int CmdKeriClone(const char *Cmd) {
T55x7_PSKCF_RF_2 |
2 << T55x7_MAXBLOCK_SHIFT,
0,
0};
0
};
// dynamic bitrate used
blocks[0] |= 0xF << 18;
@ -189,7 +196,8 @@ int CmdKeriClone(const char *Cmd) {
return 0;
}
int CmdKeriSim(const char *Cmd) {
int CmdKeriSim(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_keri_sim();
@ -231,13 +239,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdLFKeri(const char *Cmd) {
int CmdLFKeri(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -10,7 +10,8 @@
#include "cmdlfnedap.h"
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, "");
PrintAndLogEx(NORMAL, "Usage: lf nedap clone [h] <Card-Number>");
@ -24,7 +25,8 @@ int usage_lf_nedap_clone(void){
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, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "");
@ -39,7 +41,8 @@ int usage_lf_nedap_sim(void) {
}
// 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
if (*size < 128) return -3;
@ -51,7 +54,8 @@ int detectNedap(uint8_t *dest, size_t *size) {
return (int) startIdx;
}
int GetNedapBits(uint32_t cn, uint8_t *nedapBits) {
int GetNedapBits(uint32_t cn, uint8_t *nedapBits)
{
uint8_t pre[128];
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)
//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
if (!ASKbiphaseDemod("0 64 1 0", false)) {
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);
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;
@ -324,7 +331,8 @@ int CmdLFNedapSim(const char *Cmd) {
return 0;
}
int CmdLFNedapChk(const char *Cmd){
int CmdLFNedapChk(const char *Cmd)
{
//301600714021BE
uint8_t data[256] = { 0x30, 0x16, 0x00, 0x71, 0x40, 0x21, 0xBE};
int len = 0;
@ -381,13 +389,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdLFNedap(const char *Cmd) {
int CmdLFNedap(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -12,7 +12,8 @@
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_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;
}
int CmdNexWatchDemod(const char *Cmd) {
int CmdNexWatchDemod(const char *Cmd)
{
if (!PSKDemod("", false)) {
PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch can't demod signal");
@ -87,7 +89,8 @@ int CmdNexWatchDemod(const char *Cmd) {
//by marshmellow
//see ASKDemod for what args are accepted
int CmdNexWatchRead(const char *Cmd) {
int CmdNexWatchRead(const char *Cmd)
{
lf_read(true, 10000);
return CmdNexWatchDemod(Cmd);
}
@ -99,13 +102,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdLFNEXWATCH(const char *Cmd) {
int CmdLFNEXWATCH(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -11,7 +11,8 @@
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, "Usage: lf noralsy clone [h] <card id> <year> <Q5>");
PrintAndLogEx(NORMAL, "Options:");
@ -25,7 +26,8 @@ int usage_lf_noralsy_clone(void){
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, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "");
@ -40,13 +42,15 @@ int usage_lf_noralsy_sim(void) {
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;
for (uint8_t i = 0; i < len; i += 4)
sum ^= bytebits_to_byte(bits + i, 4);
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
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
// 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
size_t startIdx = 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
int CmdNoralsyDemod(const char *Cmd) {
int CmdNoralsyDemod(const char *Cmd)
{
//ASK / Manchester
bool st = true;
@ -169,12 +175,14 @@ int CmdNoralsyDemod(const char *Cmd) {
return 1;
}
int CmdNoralsyRead(const char *Cmd) {
int CmdNoralsyRead(const char *Cmd)
{
lf_read(true, 8000);
return CmdNoralsyDemod(Cmd);
}
int CmdNoralsyClone(const char *Cmd) {
int CmdNoralsyClone(const char *Cmd)
{
uint16_t year = 0;
uint32_t id = 0;
@ -221,7 +229,8 @@ int CmdNoralsyClone(const char *Cmd) {
return 0;
}
int CmdNoralsySim(const char *Cmd) {
int CmdNoralsySim(const char *Cmd)
{
uint8_t bits[96];
uint8_t *bs = bits;
@ -265,13 +274,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdLFNoralsy(const char *Cmd) {
int CmdLFNoralsy(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -13,7 +13,8 @@ static int CmdHelp(const char *Cmd);
// by marshmellow
// 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
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};
@ -25,7 +26,8 @@ int detectPac(uint8_t *dest, size_t *size) {
}
//see NRZDemod for what args are accepted
int CmdPacDemod(const char *Cmd) {
int CmdPacDemod(const char *Cmd)
{
//NRZ
if (!NRZrawDemod(Cmd, false)) {
@ -64,7 +66,8 @@ int CmdPacDemod(const char *Cmd) {
return 1;
}
int CmdPacRead(const char *Cmd) {
int CmdPacRead(const char *Cmd)
{
lf_read(true, 4096 * 2 + 20);
return CmdPacDemod(Cmd);
}
@ -76,13 +79,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdLFPac(const char *Cmd) {
int CmdLFPac(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -21,7 +21,8 @@
#include "lfdemod.h"
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, "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.");
@ -38,7 +39,8 @@ int usage_lf_paradox_sim(void) {
}
// 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
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
//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
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
uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0};
size_t size = getFromGraphBuf(bits);
@ -140,12 +143,14 @@ int CmdParadoxDemod(const char *Cmd) {
}
//by marshmellow
//see ASKDemod for what args are accepted
int CmdParadoxRead(const char *Cmd) {
int CmdParadoxRead(const char *Cmd)
{
lf_read(true, 10000);
return CmdParadoxDemod(Cmd);
}
int CmdParadoxSim(const char *Cmd) {
int CmdParadoxSim(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0);
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}
};
int CmdLFParadox(const char *Cmd) {
int CmdLFParadox(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -35,7 +35,8 @@ struct pcf7931_config configPcf = {
};
// Resets the configuration settings to default values.
int pcf7931_resetConfig(){
int pcf7931_resetConfig()
{
memset(configPcf.Pwd, 0xFF, sizeof(configPcf.Pwd));
configPcf.InitDelay = PCF7931_DEFAULT_INITDELAY;
configPcf.OffsetWidth = PCF7931_DEFAULT_OFFSET_WIDTH;
@ -43,7 +44,8 @@ int pcf7931_resetConfig(){
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, "Tag initialization delay : %d us", configPcf.InitDelay);
PrintAndLogEx(NORMAL, "Offset low pulses width : %d us", configPcf.OffsetWidth);
@ -51,7 +53,8 @@ int pcf7931_printConfig(){
return 0;
}
int usage_pcf7931_read(){
int usage_pcf7931_read()
{
PrintAndLogEx(NORMAL, "Usage: lf pcf7931 read [h] ");
PrintAndLogEx(NORMAL, "This command tries to read a PCF7931 tag.");
PrintAndLogEx(NORMAL, "Options:");
@ -61,7 +64,8 @@ int usage_pcf7931_read(){
return 0;
}
int usage_pcf7931_write(){
int usage_pcf7931_write()
{
PrintAndLogEx(NORMAL, "Usage: lf pcf7931 write [h] <block address> <byte address> <data>");
PrintAndLogEx(NORMAL, "This command tries to write a PCF7931 tag.");
PrintAndLogEx(NORMAL, "Options:");
@ -74,7 +78,8 @@ int usage_pcf7931_write(){
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, "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");
@ -94,7 +99,8 @@ int usage_pcf7931_config(){
return 0;
}
int CmdLFPCF7931Read(const char *Cmd){
int CmdLFPCF7931Read(const char *Cmd)
{
uint8_t ctmp = param_getchar(Cmd, 0);
if (ctmp == 'H' || ctmp == 'h') return usage_pcf7931_read();
@ -110,7 +116,8 @@ int CmdLFPCF7931Read(const char *Cmd){
return 0;
}
int CmdLFPCF7931Config(const char *Cmd){
int CmdLFPCF7931Config(const char *Cmd)
{
uint8_t ctmp = param_getchar(Cmd, 0);
if (ctmp == 0) return pcf7931_printConfig();
@ -127,7 +134,8 @@ int CmdLFPCF7931Config(const char *Cmd){
return 0;
}
int CmdLFPCF7931Write(const char *Cmd){
int CmdLFPCF7931Write(const char *Cmd)
{
uint8_t ctmp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_pcf7931_write();
@ -165,13 +173,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdLFPCF7931(const char *Cmd) {
int CmdLFPCF7931(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -10,7 +10,8 @@
#include "cmdlfpresco.h"
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, "Usage: lf presco clone [h] d <Card-ID> c <hex-ID> <Q5>");
PrintAndLogEx(NORMAL, "Options:");
@ -24,7 +25,8 @@ int usage_lf_presco_clone(void){
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, "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.");
@ -41,7 +43,8 @@ int usage_lf_presco_sim(void) {
}
// 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
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};
@ -53,7 +56,8 @@ int detectPresco(uint8_t *dest, size_t *size) {
}
// 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;
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
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(0x00000000, 32, prescoBits + 32);
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
int CmdPrescoDemod(const char *Cmd) {
int CmdPrescoDemod(const char *Cmd)
{
bool st = true;
if (!ASKDemod_ext("32 0 0 0 0 a", false, false, 1, &st)) {
PrintAndLogEx(DEBUG, "DEBUG: Error Presco ASKDemod failed");
@ -165,7 +171,8 @@ int CmdPrescoDemod(const char *Cmd) {
}
//see ASKDemod for what args are accepted
int CmdPrescoRead(const char *Cmd) {
int CmdPrescoRead(const char *Cmd)
{
// Presco Number: 123456789 --> Sitecode 30 | usercode 8665
lf_read(true, 12000);
return CmdPrescoDemod(Cmd);
@ -173,7 +180,8 @@ int CmdPrescoRead(const char *Cmd) {
// takes base 12 ID converts to hex
// Or takes 8 digit hex ID
int CmdPrescoClone(const char *Cmd) {
int CmdPrescoClone(const char *Cmd)
{
bool Q5 = false;
uint32_t sitecode = 0, usercode = 0, fullcode = 0;
@ -221,7 +229,8 @@ int CmdPrescoClone(const char *Cmd) {
// takes base 12 ID converts to hex
// Or takes 8 digit hex ID
int CmdPrescoSim(const char *Cmd) {
int CmdPrescoSim(const char *Cmd)
{
uint32_t sitecode = 0, usercode = 0, fullcode = 0;
bool Q5 = false;
// get wiegand from printed number.
@ -250,13 +259,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdLFPresco(const char *Cmd) {
int CmdLFPresco(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -11,7 +11,8 @@
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, "The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated. ");
PrintAndLogEx(NORMAL, "Currently only works on 26bit");
@ -28,7 +29,8 @@ int usage_lf_pyramid_clone(void){
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, "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.");
@ -47,7 +49,8 @@ int usage_lf_pyramid_sim(void) {
// by marshmellow
// 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
if (*size < 128 * 50) return -1;
@ -72,7 +75,8 @@ int detectPyramid(uint8_t *dest, size_t *size, int *waveStartIdx) {
}
// 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];
memset(pre, 0x00, sizeof(pre));
@ -105,7 +109,8 @@ int GetPyramidBits(uint32_t fc, uint32_t cn, uint8_t *pyramidBits) {
//by marshmellow
//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
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
uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0};
size_t size = getFromGraphBuf(bits);
@ -247,12 +252,14 @@ int CmdPyramidDemod(const char *Cmd) {
return 1;
}
int CmdPyramidRead(const char *Cmd) {
int CmdPyramidRead(const char *Cmd)
{
lf_read(true, 15000);
return CmdPyramidDemod(Cmd);
}
int CmdPyramidClone(const char *Cmd) {
int CmdPyramidClone(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_pyramid_clone();
@ -303,7 +310,8 @@ int CmdPyramidClone(const char *Cmd) {
return 0;
}
int CmdPyramidSim(const char *Cmd) {
int CmdPyramidSim(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0);
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}
};
int CmdLFPyramid(const char *Cmd) {
int CmdLFPyramid(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -13,7 +13,8 @@ static int CmdHelp(const char *Cmd);
// by marshmellow
// 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
size_t startIdx = 0;
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
int CmdSecurakeyDemod(const char *Cmd) {
int CmdSecurakeyDemod(const char *Cmd)
{
//ASK / Manchester
bool st = false;
@ -106,7 +108,8 @@ int CmdSecurakeyDemod(const char *Cmd) {
return 1;
}
int CmdSecurakeyRead(const char *Cmd) {
int CmdSecurakeyRead(const char *Cmd)
{
lf_read(true, 8000);
return CmdSecurakeyDemod(Cmd);
}
@ -120,13 +123,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdLFSecurakey(const char *Cmd) {
int CmdLFSecurakey(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -11,14 +11,17 @@
// Default configuration
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;
}
void Set_t55xx_Config(t55xx_conf_block_t conf){
void Set_t55xx_Config(t55xx_conf_block_t 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, "Options:");
PrintAndLogEx(NORMAL, " h - This help");
@ -36,7 +39,8 @@ int usage_t55xx_config(){
PrintAndLogEx(NORMAL, "");
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, "Options:");
PrintAndLogEx(NORMAL, " b <block> - block number to read. Between 0-7");
@ -54,7 +58,8 @@ int usage_t55xx_read(){
PrintAndLogEx(NORMAL, "");
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, "Options:");
PrintAndLogEx(NORMAL, " b <block> - block number to write. Between 0-7");
@ -69,7 +74,8 @@ int usage_t55xx_write(){
PrintAndLogEx(NORMAL, "");
return 0;
}
int usage_t55xx_trace() {
int usage_t55xx_trace()
{
PrintAndLogEx(NORMAL, "Usage: lf t55xx trace [1]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag.");
@ -80,7 +86,8 @@ int usage_t55xx_trace() {
PrintAndLogEx(NORMAL, "");
return 0;
}
int usage_t55xx_info() {
int usage_t55xx_info()
{
PrintAndLogEx(NORMAL, "Usage: lf t55xx info [1]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag.");
@ -91,7 +98,8 @@ int usage_t55xx_info() {
PrintAndLogEx(NORMAL, "");
return 0;
}
int usage_t55xx_dump(){
int usage_t55xx_dump()
{
PrintAndLogEx(NORMAL, "Usage: lf t55xx dump <password> [o]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " <password> - OPTIONAL password 4bytes (8 hex symbols)");
@ -103,7 +111,8 @@ int usage_t55xx_dump(){
PrintAndLogEx(NORMAL, "");
return 0;
}
int usage_t55xx_detect(){
int usage_t55xx_detect()
{
PrintAndLogEx(NORMAL, "Usage: lf t55xx detect [1] [p <password>]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " 1 - if set, use Graphbuffer otherwise read data from tag.");
@ -116,7 +125,8 @@ int usage_t55xx_detect(){
PrintAndLogEx(NORMAL, "");
return 0;
}
int usage_t55xx_detectP1(){
int usage_t55xx_detectP1()
{
PrintAndLogEx(NORMAL, "Command: Detect Page 1 of a t55xx chip");
PrintAndLogEx(NORMAL, "Usage: lf t55xx p1detect [1] [p <password>]");
PrintAndLogEx(NORMAL, "Options:");
@ -130,7 +140,8 @@ int usage_t55xx_detectP1(){
PrintAndLogEx(NORMAL, "");
return 0;
}
int usage_t55xx_wakup(){
int usage_t55xx_wakup()
{
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, "Options:");
@ -141,7 +152,8 @@ int usage_t55xx_wakup(){
PrintAndLogEx(NORMAL, " lf t55xx wakeup p 11223344 - send wakeup password");
return 0;
}
int usage_t55xx_chk(){
int usage_t55xx_chk()
{
PrintAndLogEx(NORMAL, "This command uses a dictionary attack");
PrintAndLogEx(NORMAL, "press 'enter' to cancel the command");
PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] <m> [i <*.dic>]");
@ -156,7 +168,8 @@ int usage_t55xx_chk(){
PrintAndLogEx(NORMAL, "");
return 0;
}
int usage_t55xx_bruteforce(){
int usage_t55xx_bruteforce()
{
PrintAndLogEx(NORMAL, "This command uses bruteforce to scan a number range");
PrintAndLogEx(NORMAL, "press 'enter' to cancel the command");
PrintAndLogEx(NORMAL, "Usage: lf t55xx bruteforce [h] <start password> <end password>");
@ -171,7 +184,8 @@ int usage_t55xx_bruteforce(){
PrintAndLogEx(NORMAL, "");
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, "press 'enter' to cancel the command");
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, "");
return 0;
}int usage_t55xx_wipe(){
}
int usage_t55xx_wipe()
{
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, "Options:");
@ -199,7 +215,8 @@ int usage_t55xx_recoverpw(){
PrintAndLogEx(NORMAL, " lf t55xx wipe Q5 - wipes a t5555 Q5 tag, config block 0x6001F004");
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, "Usage: lf t55xx deviceconfig a <gap> b <gap> c <gap> d <gap> e <gap> p");
PrintAndLogEx(NORMAL, "Options:");
@ -220,13 +237,15 @@ int usage_lf_deviceconfig(){
int CmdHelp(const char *Cmd);
void printT5xxHeader(uint8_t page){
void printT5xxHeader(uint8_t page)
{
PrintAndLogEx(NORMAL, "Reading Page %d:", page);
PrintAndLogEx(NORMAL, "blk | hex data | binary | ascii");
PrintAndLogEx(NORMAL, "----+----------+----------------------------------+-------");
}
int CmdT55xxSetConfig(const char *Cmd) {
int CmdT55xxSetConfig(const char *Cmd)
{
uint8_t offset = 0;
char modulation[6] = {0x00};
@ -328,7 +347,8 @@ int CmdT55xxSetConfig(const char *Cmd) {
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
if (usepwd) {
// 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;
}
int CmdT55xxReadBlock(const char *Cmd) {
int CmdT55xxReadBlock(const char *Cmd)
{
uint8_t block = REGULAR_READ_MODE_BLOCK;
uint32_t password = 0; //default to blank Block 7
bool usepwd = false;
@ -404,7 +425,8 @@ int CmdT55xxReadBlock(const char *Cmd) {
return T55xxReadBlock(block, page1, usepwd, override, password);
}
bool DecodeT55xxBlock(){
bool DecodeT55xxBlock()
{
char buf[30] = {0x00};
char *cmdStr = buf;
@ -467,7 +489,8 @@ bool DecodeT55xxBlock(){
return (bool) ans;
}
bool DecodeT5555TraceBlock() {
bool DecodeT5555TraceBlock()
{
DemodBufferLen = 0x00;
// 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
static int SanityOfflineCheck( bool useGraphBuffer ){
static int SanityOfflineCheck(bool useGraphBuffer)
{
if (!useGraphBuffer && IsOffline()) {
PrintAndLogEx(NORMAL, "Your proxmark3 device is offline. Specify [1] to use graphbuffer data instead");
return 0;
@ -483,7 +507,8 @@ static int SanityOfflineCheck( bool useGraphBuffer ){
return 1;
}
int CmdT55xxDetect(const char *Cmd){
int CmdT55xxDetect(const char *Cmd)
{
bool errors = false;
bool useGB = false, usepwd = false;
uint32_t password = 0;
@ -526,7 +551,8 @@ int CmdT55xxDetect(const char *Cmd){
}
// detect configuration?
bool tryDetectModulation(){
bool tryDetectModulation()
{
t55xx_conf_block_t tests[15];
int bitRate = 0, clk = 0, firstClockEdge = 0;
@ -712,7 +738,8 @@ bool tryDetectModulation(){
return retval;
}
bool testKnownConfigBlock(uint32_t block0) {
bool testKnownConfigBlock(uint32_t block0)
{
switch (block0) {
case T55X7_DEFAULT_CONFIG_BLOCK:
case T55X7_RAW_CONFIG_BLOCK:
@ -732,7 +759,8 @@ bool testKnownConfigBlock(uint32_t block0) {
return false;
}
bool testModulation(uint8_t mode, uint8_t modread){
bool testModulation(uint8_t mode, uint8_t modread)
{
switch (mode) {
case DEMOD_FSK:
if (modread >= DEMOD_FSK1 && modread <= DEMOD_FSK2a) return true;
@ -764,7 +792,8 @@ bool testModulation(uint8_t mode, uint8_t modread){
return false;
}
bool testQ5Modulation(uint8_t mode, uint8_t modread){
bool testQ5Modulation(uint8_t mode, uint8_t modread)
{
switch (mode) {
case DEMOD_FSK:
if (modread >= 4 && modread <= 5) return true;
@ -793,7 +822,8 @@ bool testQ5Modulation(uint8_t mode, uint8_t modread){
return false;
}
int convertQ5bitRate(uint8_t bitRateRead) {
int convertQ5bitRate(uint8_t bitRateRead)
{
uint8_t expected[] = {8, 16, 32, 40, 50, 64, 100, 128};
for (int i = 0; i < 8; i++)
if (expected[i] == bitRateRead)
@ -802,7 +832,8 @@ int convertQ5bitRate(uint8_t bitRateRead) {
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;
uint8_t si = 0;
@ -810,15 +841,18 @@ bool testQ5(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk){
si = idx;
if (PackBits(si, 28, DemodBuffer) == 0x00) continue;
uint8_t safer = PackBits(si, 4, DemodBuffer); si += 4; //master key
uint8_t resv = PackBits(si, 8, DemodBuffer); si += 8;
uint8_t safer = PackBits(si, 4, DemodBuffer);
si += 4; //master key
uint8_t resv = PackBits(si, 8, DemodBuffer);
si += 8;
// 2nibble must be zeroed.
if (safer != 0x6 && safer != 0x9) continue;
if (resv > 0x00) continue;
//uint8_t pageSel = PackBits(si, 1, DemodBuffer); si += 1;
//uint8_t fastWrite = PackBits(si, 1, DemodBuffer); si += 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;
//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 inverse = PackBits(si, 1, DemodBuffer); si += 1;
si += 1 + 1 + 2 + 1;
uint8_t modread = PackBits(si, 3, DemodBuffer); si += 3;
uint8_t maxBlk = PackBits(si, 3, DemodBuffer); si += 3;
uint8_t modread = PackBits(si, 3, DemodBuffer);
si += 3;
uint8_t maxBlk = PackBits(si, 3, DemodBuffer);
si += 3;
//uint8_t ST = PackBits(si, 1, DemodBuffer); si += 1;
if (maxBlk == 0) continue;
//test modulation
@ -842,7 +878,8 @@ bool testQ5(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk){
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};
if (expected[readRate] == clk)
return true;
@ -850,7 +887,8 @@ bool testBitRate(uint8_t readRate, uint8_t clk){
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;
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;
if (PackBits(si, 28, DemodBuffer) == 0x00) continue;
uint8_t safer = PackBits(si, 4, DemodBuffer); 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
uint8_t safer = PackBits(si, 4, DemodBuffer);
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.
// moved test to here, since this gets most faults first.
if (resv > 0x00) continue;
int bitRate = PackBits(si, 6, DemodBuffer); si += 6; //bit rate (includes extended mode part of rate)
uint8_t extend = PackBits(si, 1, DemodBuffer); si += 1; //bit 15 extended mode
uint8_t modread = PackBits(si, 5, DemodBuffer); si += 5+2+1;
int bitRate = PackBits(si, 6, DemodBuffer);
si += 6; //bit rate (includes extended mode part of rate)
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 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;
@ -895,7 +938,8 @@ bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5)
return false;
}
void printT55xxBlock(const char *blockNum){
void printT55xxBlock(const char *blockNum)
{
uint8_t i = config.offset;
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));
}
int special(const char *Cmd) {
int special(const char *Cmd)
{
uint32_t blockData = 0;
uint8_t bits[32] = {0x00};
@ -938,7 +983,8 @@ int special(const char *Cmd) {
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, "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))));
@ -950,7 +996,8 @@ int printConfiguration( t55xx_conf_block_t b){
return 0;
}
int CmdT55xxWakeUp(const char *Cmd) {
int CmdT55xxWakeUp(const char *Cmd)
{
uint32_t password = 0;
uint8_t cmdp = 0;
bool errors = false;
@ -978,7 +1025,8 @@ int CmdT55xxWakeUp(const char *Cmd) {
return 0;
}
int CmdT55xxWriteBlock(const char *Cmd) {
int CmdT55xxWriteBlock(const char *Cmd)
{
uint8_t block = 0xFF; //default to invalid block
uint32_t data = 0; //default to blank Block
uint32_t password = 0; //default to blank Block 7
@ -1051,7 +1099,8 @@ int CmdT55xxWriteBlock(const char *Cmd) {
return 1;
}
int CmdT55xxReadTrace(const char *Cmd) {
int CmdT55xxReadTrace(const char *Cmd)
{
char cmdp = tolower(param_getchar(Cmd, 0));
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);
if (config.Q5) {
uint32_t hdr = PackBits(si, 9, DemodBuffer); si += 9;
uint32_t hdr = PackBits(si, 9, DemodBuffer);
si += 9;
if (hdr != 0x1FF) {
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};
data.icr = PackBits(si, 2, DemodBuffer); si += 2;
data.lotidc = 'Z' - PackBits(si, 2, DemodBuffer); si += 3;
data.icr = PackBits(si, 2, DemodBuffer);
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 |= PackBits(si, 4, DemodBuffer); si += 5;
data.lotid |= PackBits(si, 4, DemodBuffer);
si += 5;
data.lotid <<= 4;
data.lotid |= PackBits(si, 4, DemodBuffer); si += 5;
data.lotid |= PackBits(si, 4, DemodBuffer);
si += 5;
data.lotid <<= 4;
data.lotid |= PackBits(si, 4, DemodBuffer); si += 5;
data.lotid |= PackBits(si, 4, DemodBuffer);
si += 5;
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 |= 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 |= PackBits(si, 4, DemodBuffer); si += 5;
data.dw |= PackBits(si, 4, DemodBuffer);
si += 5;
data.dw <<= 4;
data.dw |= PackBits(si, 4, DemodBuffer); si += 5;
data.dw |= PackBits(si, 4, DemodBuffer);
si += 5;
data.dw <<= 4;
data.dw |= PackBits(si, 4, DemodBuffer); si += 5;
data.dw |= PackBits(si, 4, DemodBuffer);
si += 5;
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};
data.acl = PackBits(si, 8, DemodBuffer); si += 8;
data.acl = PackBits(si, 8, DemodBuffer);
si += 8;
if (data.acl != 0xE0) {
PrintAndLogEx(FAILED, "The modulation is most likely wrong since the ACL is not 0xE0. ");
return 1;
}
data.mfc = PackBits(si, 8, DemodBuffer); si += 8;
data.cid = PackBits(si, 5, DemodBuffer); si += 5;
data.icr = PackBits(si, 3, DemodBuffer); si += 3;
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.mfc = PackBits(si, 8, DemodBuffer);
si += 8;
data.cid = PackBits(si, 5, DemodBuffer);
si += 5;
data.icr = PackBits(si, 3, DemodBuffer);
si += 3;
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);
time_t t = time(NULL);
@ -1149,7 +1220,8 @@ int CmdT55xxReadTrace(const char *Cmd) {
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, "-------------------------------------------------------------");
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, "-------------------------------------------------------------");
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...
int CmdT55xxInfo(const char *Cmd){
int CmdT55xxInfo(const char *Cmd)
{
/*
Page 0 Block 0 Configuration data.
Normal mode
@ -1243,20 +1317,34 @@ int CmdT55xxInfo(const char *Cmd){
uint8_t si = config.offset;
uint32_t block0 = PackBits(si, 32, DemodBuffer);
uint32_t safer = PackBits(si, 4, DemodBuffer); si += 4;
uint32_t resv = PackBits(si, 7, DemodBuffer); si += 7;
uint32_t dbr = PackBits(si, 3, DemodBuffer); si += 3;
uint32_t extend = PackBits(si, 1, DemodBuffer); si += 1;
uint32_t datamod = PackBits(si, 5, DemodBuffer); si += 5;
uint32_t pskcf = PackBits(si, 2, DemodBuffer); si += 2;
uint32_t aor = PackBits(si, 1, DemodBuffer); 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;
uint32_t safer = PackBits(si, 4, DemodBuffer);
si += 4;
uint32_t resv = PackBits(si, 7, DemodBuffer);
si += 7;
uint32_t dbr = PackBits(si, 3, DemodBuffer);
si += 3;
uint32_t extend = PackBits(si, 1, DemodBuffer);
si += 1;
uint32_t datamod = PackBits(si, 5, DemodBuffer);
si += 5;
uint32_t pskcf = PackBits(si, 2, DemodBuffer);
si += 2;
uint32_t aor = PackBits(si, 1, DemodBuffer);
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)
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;
}
int CmdT55xxDump(const char *Cmd){
int CmdT55xxDump(const char *Cmd)
{
uint32_t password = 0;
bool override = false;
@ -1310,7 +1399,8 @@ int CmdT55xxDump(const char *Cmd){
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:
// bit0 = pwdmode
// 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;
}
char * GetBitRateStr(uint32_t id, bool xmode) {
char *GetBitRateStr(uint32_t id, bool xmode)
{
static char buf[25];
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));
} else {
switch (id) {
case 0: snprintf(retStr,sizeof(buf),"%d - RF/8",id); break;
case 1: snprintf(retStr,sizeof(buf),"%d - RF/16",id); break;
case 2: snprintf(retStr,sizeof(buf),"%d - RF/32",id); 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;
case 0:
snprintf(retStr, sizeof(buf), "%d - RF/8", id);
break;
case 1:
snprintf(retStr, sizeof(buf), "%d - RF/16", id);
break;
case 2:
snprintf(retStr, sizeof(buf), "%d - RF/32", id);
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;
}
char * GetSaferStr(uint32_t id){
char *GetSaferStr(uint32_t id)
{
static char buf[40];
char *retStr = buf;
@ -1367,29 +1477,57 @@ char * GetSaferStr(uint32_t id){
return buf;
}
char * GetModulationStr( uint32_t id){
char *GetModulationStr(uint32_t id)
{
static char buf[60];
char *retStr = buf;
switch (id) {
case 0: snprintf(retStr,sizeof(buf),"%d - DIRECT (ASK/NRZ)",id); break;
case 1: snprintf(retStr,sizeof(buf),"%d - PSK 1 phase change when input changes",id); break;
case 2: snprintf(retStr,sizeof(buf),"%d - PSK 2 phase change on bitclk if input high",id); break;
case 3: snprintf(retStr,sizeof(buf),"%d - PSK 3 phase change on rising edge of input",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;
case 0:
snprintf(retStr, sizeof(buf), "%d - DIRECT (ASK/NRZ)", id);
break;
case 1:
snprintf(retStr, sizeof(buf), "%d - PSK 1 phase change when input changes", id);
break;
case 2:
snprintf(retStr, sizeof(buf), "%d - PSK 2 phase change on bitclk if input high", id);
break;
case 3:
snprintf(retStr, sizeof(buf), "%d - PSK 3 phase change on rising edge of input", 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;
}
char * GetModelStrFromCID(uint32_t cid){
char *GetModelStrFromCID(uint32_t cid)
{
static char buf[10];
char *retStr = buf;
@ -1399,30 +1537,58 @@ char * GetModelStrFromCID(uint32_t cid){
return buf;
}
char * GetSelectedModulationStr( uint8_t id){
char *GetSelectedModulationStr(uint8_t id)
{
static char buf[20];
char *retStr = buf;
switch (id) {
case DEMOD_FSK: snprintf(retStr,sizeof(buf),"FSK"); break;
case DEMOD_FSK1: snprintf(retStr,sizeof(buf),"FSK1"); break;
case DEMOD_FSK1a: snprintf(retStr,sizeof(buf),"FSK1a"); break;
case DEMOD_FSK2: snprintf(retStr,sizeof(buf),"FSK2"); 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;
case DEMOD_FSK:
snprintf(retStr, sizeof(buf), "FSK");
break;
case DEMOD_FSK1:
snprintf(retStr, sizeof(buf), "FSK1");
break;
case DEMOD_FSK1a:
snprintf(retStr, sizeof(buf), "FSK1a");
break;
case DEMOD_FSK2:
snprintf(retStr, sizeof(buf), "FSK2");
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;
}
void t55x7_create_config_block( int tagtype ){
void t55x7_create_config_block(int tagtype)
{
/*
T55X7_DEFAULT_CONFIG_BLOCK, T55X7_RAW_CONFIG_BLOCK
@ -1434,16 +1600,23 @@ void t55x7_create_config_block( int tagtype ){
char *retStr = buf;
switch (tagtype) {
case 0: snprintf(retStr, sizeof(buf),"%08X - T55X7 Default", T55X7_DEFAULT_CONFIG_BLOCK); 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;
case 0:
snprintf(retStr, sizeof(buf), "%08X - T55X7 Default", T55X7_DEFAULT_CONFIG_BLOCK);
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:
break;
}
PrintAndLogEx(NORMAL, buf);
}
int CmdResetRead(const char *Cmd) {
int CmdResetRead(const char *Cmd)
{
UsbCommand c = {CMD_T55XX_RESET_READ, {0, 0, 0}};
clearCommandBuffer();
SendCommand(&c);
@ -1461,7 +1634,8 @@ int CmdResetRead(const char *Cmd) {
return 1;
}
int CmdT55xxWipe(const char *Cmd) {
int CmdT55xxWipe(const char *Cmd)
{
char writeData[20] = {0};
char *ptrData = writeData;
char cmdp = tolower(param_getchar(Cmd, 0));
@ -1491,16 +1665,19 @@ int CmdT55xxWipe(const char *Cmd) {
return 0;
}
bool IsCancelled(void) {
bool IsCancelled(void)
{
if (ukbhit()) {
int gc = getchar(); (void)gc;
int gc = getchar();
(void)gc;
PrintAndLogEx(WARNING, "\naborted via keyboard!\n");
return true;
}
return false;
}
int CmdT55xxChkPwds(const char *Cmd) {
int CmdT55xxChkPwds(const char *Cmd)
{
// load a default pwd file.
char line[9];
char filename[FILE_PATH_SIZE] = {0};
@ -1534,7 +1711,8 @@ int CmdT55xxChkPwds(const char *Cmd) {
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
timeout++;
printf("."); fflush(stdout);
printf(".");
fflush(stdout);
if (timeout > 180) {
PrintAndLogEx(WARNING, "\nno response from Proxmark. Aborting...");
return 2;
@ -1670,7 +1848,8 @@ out:
return 0;
}
int CmdT55xxBruteForce(const char *Cmd) {
int CmdT55xxBruteForce(const char *Cmd)
{
uint32_t start_password = 0x00000000; //start password
uint32_t end_password = 0xFFFFFFFF; //end password
@ -1699,7 +1878,8 @@ int CmdT55xxBruteForce(const char *Cmd) {
while (!found) {
printf("."); fflush(stdout);
printf(".");
fflush(stdout);
if (IsCancelled()) {
return 0;
@ -1729,7 +1909,8 @@ int CmdT55xxBruteForce(const char *Cmd) {
return 0;
}
int tryOnePassword(uint32_t password) {
int tryOnePassword(uint32_t password)
{
PrintAndLogEx(INFO, "Trying password %08x", password);
if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, password)) {
PrintAndLogEx(NORMAL, "Acquire data from device failed. Quitting");
@ -1742,7 +1923,8 @@ int tryOnePassword(uint32_t password) {
return 0;
}
int CmdT55xxRecoverPW(const char *Cmd) {
int CmdT55xxRecoverPW(const char *Cmd)
{
int bit = 0;
uint32_t orig_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.
// 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...
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};
size_t startIdx = 0;
uint8_t fc1 = 0, fc2 = 0, ans = 0;
@ -1926,7 +2109,8 @@ bool tryDetectP1(bool getData) {
return false;
}
// does this need to be a callable command?
int CmdT55xxDetectPage1(const char *Cmd){
int CmdT55xxDetectPage1(const char *Cmd)
{
bool errors = false;
bool useGB = false;
bool usepwd = false;
@ -1964,7 +2148,8 @@ int CmdT55xxDetectPage1(const char *Cmd){
return success;
}
int CmdT55xxSetDeviceConfig(const char *Cmd){
int CmdT55xxSetDeviceConfig(const char *Cmd)
{
uint8_t startgap = 0, writegap = 0;
uint8_t write0 = 0, write1 = 0, readgap = 0;
bool errors = false, shall_persist = false;
@ -2037,13 +2222,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdLFT55XX(const char *Cmd) {
int CmdLFT55XX(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

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

View file

@ -11,7 +11,8 @@
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, "Usage: lf viking clone <Card ID - 8 hex digits> <Q5>");
PrintAndLogEx(NORMAL, "Options:");
@ -23,7 +24,8 @@ int usage_lf_viking_clone(void) {
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, "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.");
@ -38,7 +40,8 @@ int usage_lf_viking_sim(void) {
}
// 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;
uint64_t ret = (uint64_t)0xF2 << 56;
ret |= (uint64_t)id << 8;
@ -47,7 +50,8 @@ uint64_t getVikingBits(uint32_t id) {
}
// by marshmellow
// 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
if (*size < 64 * 2) return -2;
size_t startIdx = 0;
@ -71,7 +75,8 @@ int detectViking(uint8_t *dest, size_t *size) {
//by marshmellow
//see ASKDemod for what args are accepted
int CmdVikingDemod(const char *Cmd) {
int CmdVikingDemod(const char *Cmd)
{
if (!ASKDemod(Cmd, false, false, 1)) {
PrintAndLogEx(DEBUG, "DEBUG: Error - Viking ASKDemod failed");
return 0;
@ -97,12 +102,14 @@ int CmdVikingDemod(const char *Cmd) {
//by marshmellow
//see ASKDemod for what args are accepted
int CmdVikingRead(const char *Cmd) {
int CmdVikingRead(const char *Cmd)
{
lf_read(true, 10000);
return CmdVikingDemod(Cmd);
}
int CmdVikingClone(const char *Cmd) {
int CmdVikingClone(const char *Cmd)
{
uint32_t id = 0;
uint64_t rawID = 0;
bool Q5 = false;
@ -131,7 +138,8 @@ int CmdVikingClone(const char *Cmd) {
return 0;
}
int CmdVikingSim(const char *Cmd) {
int CmdVikingSim(const char *Cmd)
{
uint32_t id = 0;
uint64_t rawID = 0;
uint8_t clk = 32, encoding = 1, separator = 0, invert = 0;
@ -167,13 +175,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdLFViking(const char *Cmd) {
int CmdLFViking(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

@ -15,7 +15,8 @@
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, "Usage: lf visa2000 clone [h] <card ID> <Q5>");
PrintAndLogEx(NORMAL, "Options:");
@ -28,7 +29,8 @@ int usage_lf_visa2k_clone(void){
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, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "");
@ -42,14 +44,16 @@ int usage_lf_visa2k_sim(void) {
return 0;
}
static uint8_t visa_chksum( uint32_t id ) {
static uint8_t visa_chksum(uint32_t id)
{
uint8_t sum = 0;
for (uint8_t i = 0; i < 32; i += 4)
sum ^= (id >> i) & 0xF;
return sum & 0xF;
}
static uint8_t visa_parity( uint32_t id) {
static uint8_t visa_parity(uint32_t id)
{
// 4bit parity LUT
uint8_t par_lut[] = {
0, 1, 1, 0
@ -71,7 +75,8 @@ static uint8_t visa_parity( uint32_t id) {
// by iceman
// 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
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};
@ -94,7 +99,8 @@ int detectVisa2k(uint8_t *dest, size_t *size) {
*
**/
//see ASKDemod for what args are accepted
int CmdVisa2kDemod(const char *Cmd) {
int CmdVisa2kDemod(const char *Cmd)
{
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
int CmdVisa2kRead(const char *Cmd) {
int CmdVisa2kRead(const char *Cmd)
{
lf_read(true, 20000);
return CmdVisa2kDemod(Cmd);
}
int CmdVisa2kClone(const char *Cmd) {
int CmdVisa2kClone(const char *Cmd)
{
uint64_t id = 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;
}
int CmdVisa2kSim(const char *Cmd) {
int CmdVisa2kSim(const char *Cmd)
{
uint32_t id = 0;
char cmdp = param_getchar(Cmd, 0);
@ -231,13 +240,15 @@ static command_t CommandTable[] = {
{NULL, NULL, 0, NULL}
};
int CmdLFVisa2k(const char *Cmd) {
int CmdLFVisa2k(const char *Cmd)
{
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

View file

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

View file

@ -17,7 +17,8 @@
#include "proxmark3.h"
#include "comms.h"
void CmdsHelp(const command_t Commands[]) {
void CmdsHelp(const command_t Commands[])
{
if (Commands[0].Name == NULL) return;
int i = 0;
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
if (strcmp(Cmd, "XX_internal_command_dump_XX") == 0) {
dumpCommandsRecursive(Commands, 0);
@ -76,7 +78,8 @@ int CmdsParse(const command_t Commands[], const char *Cmd) {
char pparent[512] = {0};
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;
int i = 0;

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