Skip to content

Commit

Permalink
Implement initial MF_CLASSIC_LOG
Browse files Browse the repository at this point in the history
  • Loading branch information
ShinHub committed Nov 17, 2019
1 parent e4b7471 commit 52a7c15
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 2 deletions.
127 changes: 125 additions & 2 deletions Firmware/ChameleonMini/Application/MifareClassic.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
#include "../Random.h"
#include "../Codec/ISO14443-2A.h"
#include "../Memory/Memory.h"
#ifdef CONFIG_MF_CLASSIC_LOG_SUPPORT
#include "System.h"
#endif

/* TODO: Access control not implemented yet
// Decoding table for Access conditions of a data block
Expand Down Expand Up @@ -185,6 +188,13 @@ static bool isBruteEnabled = false;
static uint8_t BruteIdleRounds = 0;
static uint32_t BruteCurrentUid = 0;
#endif
#ifdef CONFIG_MF_CLASSIC_LOG_SUPPORT
static bool isLogEnabled = false;
static uint32_t LogBytesWrote = 0;
static uint16_t LogBytesBuffered = 0;
static uint32_t LogMaxBytes = 0;
static uint8_t LogLineBuffer[MFCLASSIC_LOG_MEM_LINE_BUFFER_LEN] = { 0 };
#endif

/* TODO: Access control not implemented yet
* Decode Access conditions for a block
Expand Down Expand Up @@ -280,20 +290,29 @@ INLINE void ValueToBlock(uint8_t* Block, uint32_t Value) {
Block[11] = Block[3];
}

#if defined(CONFIG_MF_CLASSIC_BRUTE_SUPPORT)
#if defined(CONFIG_MF_CLASSIC_BRUTE_SUPPORT) || defined(CONFIG_MF_CLASSIC_LOG_SUPPORT)
uint32_t BytesToUint32(uint8_t * Buffer) {
return ( (((uint32_t)(Buffer[0])) << 24)
| (((uint32_t)(Buffer[1])) << 16)
| (((uint32_t)(Buffer[2])) << 8)
| ((uint32_t)(Buffer[3])) );
}

uint16_t BytesToUint16(uint8_t * Buffer) {
return ( (((uint16_t)(Buffer[0])) << 8) | ((uint16_t)(Buffer[1])) );
}

void Uint32ToBytes(uint32_t Uint32, uint8_t * Buffer) {
Buffer[0] = ((uint8_t)(Uint32 >> 24) & 0xFF);
Buffer[1] = ((uint8_t)(Uint32 >> 16) & 0xFF);
Buffer[2] = ((uint8_t)(Uint32 >> 8) & 0xFF);
Buffer[3] = ((uint8_t)(Uint32 & 0xFF));
}

void Uint16ToBytes(uint16_t Uint16, uint8_t * Buffer) {
Buffer[0] = ((uint8_t)(Uint16 >> 8) & 0xFF);
Buffer[1] = ((uint8_t)(Uint16 & 0xFF));
}
#endif

void MifareClassicAppInit(uint16_t ATQA_4B, uint8_t SAK, bool is7B) {
Expand Down Expand Up @@ -389,6 +408,99 @@ void MifareClassicAppBruteTick(void) {
}
#endif

#ifdef CONFIG_MF_CLASSIC_LOG_SUPPORT
void MifareClassicAppLogCheck(void) {
uint8_t headerLine[MFCLASSIC_LOG_MEM_LOG_HEADER_LEN];
AppWorkingMemoryRead(&headerLine, MFCLASSIC_LOG_MEM_LOG_HEADER_ADDR, MFCLASSIC_LOG_MEM_LOG_HEADER_LEN);
if( (headerLine[MFCLASSIC_LOG_MEM_STATUS_CANARY_ADDR] == MFCLASSIC_LOG_MEM_STATUS_CANARY)
|| (headerLine[MFCLASSIC_LOG_MEM_STATUS_CANARY_ADDR] == MFCLASSIC_LOG_MEM_STATUS_RESET) ) {
isLogEnabled = (headerLine[MFCLASSIC_LOG_MEM_STATUS_CANARY_ADDR] == MFCLASSIC_LOG_MEM_STATUS_CANARY);
LogBytesWrote = BytesToUint32(&headerLine[MFCLASSIC_LOG_MEM_WROTEBYTES_ADDR]);
} else {
isLogEnabled = true;
LogBytesWrote = 0;
}
}

void MifareClassicAppLogWriteHeader(void) {
uint8_t headerLine[MFCLASSIC_LOG_MEM_LOG_HEADER_LEN] = { 0 };
headerLine[MFCLASSIC_LOG_MEM_STATUS_CANARY_ADDR] = (isLogEnabled) ? (MFCLASSIC_LOG_MEM_STATUS_CANARY) : (MFCLASSIC_LOG_MEM_STATUS_RESET);
Uint32ToBytes(LogBytesWrote, &headerLine[MFCLASSIC_LOG_MEM_WROTEBYTES_ADDR]);
AppWorkingMemoryWrite(headerLine, MFCLASSIC_LOG_MEM_LOG_HEADER_ADDR, MFCLASSIC_LOG_MEM_LOG_HEADER_LEN);
}

void MifareClassicAppLogBufferLine(const uint8_t * Data, uint16_t BitCount, uint8_t Source) {
uint16_t timeNow = SystemGetSysTick();
uint16_t dataBytesToBuffer = (BitCount / BITS_PER_BYTE);
if( !(BitCount % BITS_PER_BYTE) ) dataBytesToBuffer++;
if( (LogBytesBuffered + MFCLASSIC_LOG_LINE_OVERHEAD) < MFCLASSIC_LOG_MEM_LINE_BUFFER_LEN) {
uint16_t idx = LogBytesBuffered+MFCLASSIC_LOG_MEM_LINE_START_ADDR;
LogLineBuffer[idx] = MFCLASSIC_LOG_LINE_START;
idx += MFCLASSIC_LOG_MEM_CHAR_LEN;
Uint16ToBytes(timeNow, &LogLineBuffer[idx]);
idx += MFCLASSIC_LOG_MEM_LINE_TIMESTAMP_LEN;
LogLineBuffer[idx] = MFCLASSIC_LOG_SEPARATOR;
idx += MFCLASSIC_LOG_MEM_CHAR_LEN;
LogLineBuffer[idx] = Source;
idx += MFCLASSIC_LOG_MEM_CHAR_LEN;
LogLineBuffer[idx] = MFCLASSIC_LOG_SEPARATOR;
idx += MFCLASSIC_LOG_MEM_CHAR_LEN;
LogLineBuffer[idx] = State;
idx += MFCLASSIC_LOG_MEM_CHAR_LEN;
LogLineBuffer[idx] = MFCLASSIC_LOG_SEPARATOR;
idx += MFCLASSIC_LOG_MEM_CHAR_LEN;
memcpy(&LogLineBuffer[idx], Data, dataBytesToBuffer);
idx += dataBytesToBuffer;
LogLineBuffer[idx] = MFCLASSIC_LOG_LINE_END;
idx += MFCLASSIC_LOG_MEM_CHAR_LEN;
LogLineBuffer[idx] = MFCLASSIC_LOG_EOL_CR;
idx += MFCLASSIC_LOG_MEM_CHAR_LEN;
LogLineBuffer[idx] = MFCLASSIC_LOG_EOL_LF;
idx += MFCLASSIC_LOG_MEM_CHAR_LEN;
LogLineBuffer[idx] = MFCLASSIC_LOG_EOS;
idx += MFCLASSIC_LOG_MEM_CHAR_LEN;
LogBytesBuffered = idx;
}
}

void MifareClassicAppLogWriteLines(void) {
if( isLogEnabled && (LogBytesBuffered > 0) ) {
if( (LogBytesWrote + LogBytesBuffered) >= LogMaxBytes) {
LogBytesWrote = 0;
}
AppWorkingMemoryWrite(LogLineBuffer, MFCLASSIC_LOG_MEM_LOG_HEADER_LEN+LogBytesWrote, LogBytesBuffered);
LogBytesWrote += LogBytesBuffered;
LogBytesBuffered = 0;
MifareClassicAppLogWriteHeader();
}
}

void MifareClassicAppLogStop(void) {
isLogEnabled = false;
MifareClassicAppLogWriteHeader();
}

void MifareClassicAppLogStart(void) {
isLogEnabled = true;
MifareClassicAppLogWriteHeader();
}

void MifareClassicAppLogInit(void) {
MifareClassicAppInit(MFCLASSIC_1K_ATQA_VALUE, MFCLASSIC_1K_SAK_VALUE, false);
MifareClassicAppLogCheck();
LogMaxBytes = ( AppWorkingMemorySize() - MFCLASSIC_LOG_MEM_LOG_HEADER_LEN );
LogBytesBuffered = 0;
}

void MifareClassicAppLogToggle(void) {
if(isLogEnabled) {
MifareClassicAppLogStop();
} else {
MifareClassicAppLogStart();
}
}
#endif

void MifareClassicAppReset(void) {
State = STATE_IDLE;
}
Expand Down Expand Up @@ -537,6 +649,12 @@ void mfcEncryptBuffer(uint8_t * Output, uint8_t * Input, uint8_t Size) {
}

uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) {
#ifdef CONFIG_MF_CLASSIC_LOG_SUPPORT
/* Log what comes from reader if logging enabled */
if(isLogEnabled) {
MifareClassicAppLogBufferLine(Buffer, BitCount, MFCLASSIC_LOG_READER);
}
#endif
/* Size of data (byte) we will send back to reader. Is main process return value */
uint16_t retSize = ISO14443A_APP_NO_RESPONSE;
/* WUPA/REQA and HALT may occur in every state. We handle is first, so we can skip
Expand Down Expand Up @@ -867,7 +985,12 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) {
State = isFromHaltChain ? STATE_HALT : STATE_IDLE;
} /* End of states switch/case */
} /* End of if/else WUPA/REQA condition */

#ifdef CONFIG_MF_CLASSIC_LOG_SUPPORT
/* Log what goes from tag if logging enabled */
if(isLogEnabled) {
MifareClassicAppLogBufferLine(Buffer, retSize, MFCLASSIC_LOG_TAG);
}
#endif
return retSize;
}

Expand Down
31 changes: 31 additions & 0 deletions Firmware/ChameleonMini/Application/MifareClassic.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,31 @@ C1 C2 C3 read write increment decrement,
#define BRUTE_IDLE_MAX_ROUNDS 3
#endif

#ifdef CONFIG_MF_CLASSIC_LOG_SUPPORT
#define MFCLASSIC_LOG_LINE_START 0x3E
#define MFCLASSIC_LOG_LINE_END 0x3B
#define MFCLASSIC_LOG_EOL_CR 0x0D
#define MFCLASSIC_LOG_EOL_LF 0x0A
#define MFCLASSIC_LOG_EOS 0x00
#define MFCLASSIC_LOG_SEPARATOR 0x21
#define MFCLASSIC_LOG_READER 0x52
#define MFCLASSIC_LOG_TAG 0x54
#define MFCLASSIC_LOG_MEM_CHAR_LEN 1
#define MFCLASSIC_LOG_MEM_STATUS_CANARY_ADDR MFCLASSIC_LOG_MEM_LOG_HEADER_ADDR
#define MFCLASSIC_LOG_MEM_STATUS_CANARY 0x71
#define MFCLASSIC_LOG_MEM_STATUS_RESET 0x70
#define MFCLASSIC_LOG_MEM_STATUS_LEN 1
#define MFCLASSIC_LOG_MEM_WROTEBYTES_ADDR 12
#define MFCLASSIC_LOG_MEM_WROTEBYTES_LEN sizeof(uint32_t)
#define MFCLASSIC_LOG_MEM_LOG_HEADER_ADDR 0
#define MFCLASSIC_LOG_MEM_LOG_HEADER_LEN 16
#define MFCLASSIC_LOG_MEM_LINE_BUFFER_LEN 128
#define MFCLASSIC_LOG_MEM_LINE_START_ADDR 0
#define MFCLASSIC_LOG_MEM_LINE_TIMESTAMP_LEN sizeof(uint16_t)
#define MFCLASSIC_LOG_LINE_OVERHEAD (MFCLASSIC_LOG_MEM_LINE_TIMESTAMP_LEN+MFCLASSIC_LOG_MEM_CHAR_LEN*10)
#define MFCLASSIC_LOG_BUFFER_OVERFLOW 0x0F
#endif

void MifareClassicAppInit1K(void);
void MifareClassicAppInit4K(void);
void MifareClassicAppReset(void);
Expand Down Expand Up @@ -217,4 +242,10 @@ void MifareClassicAppBruteTick(void);
void MifareClassicAppBruteToggle(void);
#endif

#ifdef CONFIG_MF_CLASSIC_LOG_SUPPORT
void MifareClassicAppLogInit(void);
void MifareClassicAppLogWriteLines(void);
void MifareClassicAppLogToggle(void);
#endif

#endif /* MIFARECLASSIC_H_ */
25 changes: 25 additions & 0 deletions Firmware/ChameleonMini/Configuration.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ static const MapEntryType ConfigurationMap[] PROGMEM = {
#ifdef CONFIG_MF_CLASSIC_BRUTE_SUPPORT
{ .Id = CONFIG_MF_CLASSIC_BRUTE, .Text = "MF_CLASSIC_BRUTE" },
#endif
#ifdef CONFIG_MF_CLASSIC_LOG_SUPPORT
{ .Id = CONFIG_MF_CLASSIC_LOG, .Text = "MF_CLASSIC_LOG" },
#endif
};

/* Include all Codecs and Applications */
Expand Down Expand Up @@ -298,6 +301,28 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ReadOnly = false
},
#endif
#ifdef CONFIG_MF_CLASSIC_LOG_SUPPORT
[CONFIG_MF_CLASSIC_LOG] = {
.CodecInitFunc = ISO14443ACodecInit,
.CodecTaskFunc = ISO14443ACodecTask,
.ApplicationInitFunc = MifareClassicAppLogInit,
.ApplicationResetFunc = MifareClassicAppReset,
.ApplicationTaskFunc = ApplicationTaskDummy,
.ApplicationTickFunc = MifareClassicAppLogWriteLines,
.ApplicationButtonFunc = MifareClassicAppLogToggle,
.ApplicationProcessFunc = MifareClassicAppProcess,
.ApplicationGetUidFunc = MifareClassicGetUid,
.ApplicationSetUidFunc = MifareClassicSetUid,
.ApplicationGetSakFunc = MifareClassicGetSak,
.ApplicationSetSakFunc = MifareClassicSetSak,
.ApplicationGetAtqaFunc = MifareClassicGetAtqa,
.ApplicationSetAtqaFunc = MifareClassicSetAtqa,
.UidSize = MFCLASSIC_UID_SIZE,
.CardMemorySize = MFCLASSIC_1K_MEM_SIZE,
.WorkingMemorySize = MEMORY_ALL_MEMORY,
.ReadOnly = false
},
#endif
};

ConfigurationType ActiveConfiguration;
Expand Down
3 changes: 3 additions & 0 deletions Firmware/ChameleonMini/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ typedef enum {
#endif
#ifdef CONFIG_MF_CLASSIC_BRUTE_SUPPORT
CONFIG_MF_CLASSIC_BRUTE,
#endif
#ifdef CONFIG_MF_CLASSIC_LOG_SUPPORT
CONFIG_MF_CLASSIC_LOG,
#endif
/* This HAS to be the last element */
CONFIG_COUNT
Expand Down
1 change: 1 addition & 0 deletions Firmware/ChameleonMini/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ SETTINGS += -DCONFIG_MF_ULTRALIGHT_SUPPORT
#SETTINGS += -DCONFIG_ISO14443A_READER_SUPPORT
SETTINGS += -DCONFIG_MF_CLASSIC_DETECTION_SUPPORT
SETTINGS += -DCONFIG_MF_CLASSIC_BRUTE_SUPPORT
SETTINGS += -DCONFIG_MF_CLASSIC_LOG_SUPPORT

#Support magic mode on mifare classic configuration
#SETTINGS += -DSUPPORT_MF_CLASSIC_MAGIC_MODE
Expand Down

0 comments on commit 52a7c15

Please sign in to comment.