diff --git a/Firmware/ChameleonMini/AntennaLevel.c b/Firmware/ChameleonMini/AntennaLevel.c index 9ce6c60..cabdd17 100644 --- a/Firmware/ChameleonMini/AntennaLevel.c +++ b/Firmware/ChameleonMini/AntennaLevel.c @@ -1,18 +1,32 @@ #include "AntennaLevel.h" #include "Application/Application.h" -#define FIELD_MIN_RSSI 500 +void AntennaLevelInit(void) { + ADCA.CTRLA = ADC_ENABLE_bm; + ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc; + ADCA.REFCTRL = ADC_REFSEL_INT1V_gc | ADC_BANDGAP_bm; + ADCA.PRESCALER = ADC_PRESCALER_DIV32_gc; + ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc; + ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN7_gc; +} + +uint16_t AntennaLevelGet(void) { + ADCA.CH0.CTRL |= ADC_CH_START_bm; + while( !(ADCA.CH0.INTFLAGS & ADC_CH_CHIF_bm) ); + + ADCA.CH0.INTFLAGS = ADC_CH_CHIF_bm; + + int16_t Result = ADCA.CH0RES - ANTENNA_LEVEL_OFFSET; + if (Result < 0) Result = 0; + + return (uint16_t) (((uint32_t) Result * ANTENNA_LEVEL_NUMERATOR) / ANTENNA_LEVEL_DENOMINATOR); +} -void AntennaLevelTick(void) -{ +void AntennaLevelTick(void) { uint16_t rssi = AntennaLevelGet(); - if (rssi < FIELD_MIN_RSSI) - { - //LEDHook(LED_FIELD_DETECTED, LED_OFF); - if (ActiveConfiguration.UidSize != 0) // this implies that we are emulating right now - ApplicationReset(); // reset the application just like a real card gets reset when there is no field - } else { - //LEDHook(LED_FIELD_DETECTED, LED_ON); + // UidSize != 0 implies that we are emulating right now + if( (rssi < ANTENNA_FIELD_MIN_RSSI) && (ActiveConfiguration.UidSize != 0) ) { + ApplicationReset(); // reset the application just like a real card gets reset when there is no field } } diff --git a/Firmware/ChameleonMini/AntennaLevel.h b/Firmware/ChameleonMini/AntennaLevel.h index 806120d..b89ab3d 100644 --- a/Firmware/ChameleonMini/AntennaLevel.h +++ b/Firmware/ChameleonMini/AntennaLevel.h @@ -58,40 +58,22 @@ #include "Common.h" -#define ANTENNA_LEVEL_R1 10E3 -#define ANTENNA_LEVEL_R2 220E0 -#define ANTENNA_LEVEL_VREF 1.0 -#define ANTENNA_LEVEL_RES 4096 -#define ANTENNA_LEVEL_OFFSET 190 /* LSB */ +#define ANTENNA_LEVEL_R1 10E3 +#define ANTENNA_LEVEL_R2 220E0 +#define ANTENNA_LEVEL_VREF 1.0 +#define ANTENNA_LEVEL_RES 4096 +#define ANTENNA_LEVEL_OFFSET 190 /* LSB */ -#define ANTENNA_LEVEL_MILLIVOLT 1E3 -#define ANTENNA_LEVEL_FACTOR (ANTENNA_LEVEL_VREF * (ANTENNA_LEVEL_R1 + ANTENNA_LEVEL_R2) / (ANTENNA_LEVEL_RES * ANTENNA_LEVEL_R2) ) -#define ANTENNA_LEVEL_SCALE ((uint32_t) 1<<16) -#define ANTENNA_LEVEL_NUMERATOR ((uint32_t) (ANTENNA_LEVEL_MILLIVOLT * ANTENNA_LEVEL_FACTOR * ANTENNA_LEVEL_SCALE + .5)) -#define ANTENNA_LEVEL_DENOMINATOR (ANTENNA_LEVEL_SCALE) +#define ANTENNA_LEVEL_MILLIVOLT 1E3 +#define ANTENNA_LEVEL_FACTOR (ANTENNA_LEVEL_VREF * (ANTENNA_LEVEL_R1 + ANTENNA_LEVEL_R2) / (ANTENNA_LEVEL_RES * ANTENNA_LEVEL_R2) ) +#define ANTENNA_LEVEL_SCALE ((uint32_t) 1<<16) +#define ANTENNA_LEVEL_NUMERATOR ((uint32_t) (ANTENNA_LEVEL_MILLIVOLT * ANTENNA_LEVEL_FACTOR * ANTENNA_LEVEL_SCALE + .5)) +#define ANTENNA_LEVEL_DENOMINATOR (ANTENNA_LEVEL_SCALE) -static inline void AntennaLevelInit(void) -{ - ADCA.CTRLA = ADC_ENABLE_bm; - ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc; - ADCA.REFCTRL = ADC_REFSEL_INT1V_gc | ADC_BANDGAP_bm; - ADCA.PRESCALER = ADC_PRESCALER_DIV32_gc; - ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc; - ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN7_gc; +#define ANTENNA_FIELD_MIN_RSSI 500 -} - -static inline uint16_t AntennaLevelGet(void) -{ - ADCA.CH0.CTRL |= ADC_CH_START_bm; - while( !(ADCA.CH0.INTFLAGS & ADC_CH_CHIF_bm) ); - - ADCA.CH0.INTFLAGS = ADC_CH_CHIF_bm; - - int16_t Result = ADCA.CH0RES - ANTENNA_LEVEL_OFFSET; - if (Result < 0) Result = 0; - - return (uint16_t) (((uint32_t) Result * ANTENNA_LEVEL_NUMERATOR) / ANTENNA_LEVEL_DENOMINATOR); -} +void AntennaLevelInit(void); +uint16_t AntennaLevelGet(void); +void AntennaLevelTick(void); #endif /* ANTENNALEVEL_H_ */ diff --git a/Firmware/ChameleonMini/Application/Application.h b/Firmware/ChameleonMini/Application/Application.h index aca50f0..7f9a8a5 100644 --- a/Firmware/ChameleonMini/Application/Application.h +++ b/Firmware/ChameleonMini/Application/Application.h @@ -28,6 +28,10 @@ INLINE void ApplicationTick(void) { ActiveConfiguration.ApplicationTickFunc(); } +INLINE void ApplicationButton(void) { + ActiveConfiguration.ApplicationButtonFunc(); +} + INLINE uint16_t ApplicationProcess(uint8_t* ByteBuffer, uint16_t ByteCount) { return ActiveConfiguration.ApplicationProcessFunc(ByteBuffer, ByteCount); } diff --git a/Firmware/ChameleonMini/Application/MifareClassic.c b/Firmware/ChameleonMini/Application/MifareClassic.c index 6b0884c..8eed342 100644 --- a/Firmware/ChameleonMini/Application/MifareClassic.c +++ b/Firmware/ChameleonMini/Application/MifareClassic.c @@ -7,12 +7,19 @@ * */ +#if defined(CONFIG_MF_CLASSIC_SUPPORT) || defined(CONFIG_MF_CLASSIC_DETECTION_SUPPORT) \ + || defined(CONFIG_MF_CLASSIC_BRUTE_SUPPORT) || defined(SUPPORT_MF_CLASSIC_MAGIC_MODE) \ + || defined(CONFIG_MF_CLASSIC_LOG_SUPPORT) + #include "MifareClassic.h" #include "ISO14443-3A.h" #include "Crypto1.h" #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 @@ -171,15 +178,27 @@ static bool is7BytesUID = false; static bool isFromHaltChain = false; /* To check if previous step of any cascading sequence has passed */ static bool isCascadeStepOnePassed = false; -/* To enable MF_DETECTION behavior */ +/* To enable MF_CLASSIC_DETECTION behavior */ static bool isDetectionEnabled = false; -#ifdef CONFIG_MF_DETECTION_SUPPORT +#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT static bool isDetectionCanaryWritten = false; static uint8_t DetectionCanary[DETECTION_BLOCK0_CANARY_SIZE] = { DETECTION_BLOCK0_CANARY }; static uint8_t DetectionDataSave[DETECTION_BYTES_PER_SAVE] = {0}; static uint8_t DetectionAttemptsKeyA = 0; static uint8_t DetectionAttemptsKeyB = 0; #endif +#ifdef CONFIG_MF_CLASSIC_BRUTE_SUPPORT +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 @@ -275,6 +294,31 @@ INLINE void ValueToBlock(uint8_t* Block, uint32_t Value) { Block[11] = Block[3]; } +#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) { State = STATE_IDLE; is7BytesUID = is7B; @@ -294,13 +338,11 @@ void MifareClassicAppInit4K(void) { (ActiveConfiguration.UidSize == MFCLASSIC_UID_7B_SIZE) ); } -#ifdef CONFIG_MF_CLASSIC_MINI_SUPPORT void MifareClassicAppInitMini(void) { MifareClassicAppInit(MFCLASSIC_MINI_ATQA_VALUE, MFCLASSIC_MINI_SAK_VALUE, false); } -#endif -#ifdef CONFIG_MF_DETECTION_SUPPORT +#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT void MifareClassicAppDetectionInit(void) { isDetectionEnabled = true; DetectionAttemptsKeyA = 0; @@ -309,14 +351,161 @@ void MifareClassicAppDetectionInit(void) { } #endif -void MifareClassicAppReset(void) { +#ifdef CONFIG_MF_CLASSIC_BRUTE_SUPPORT +void MifareClassicAppBruteGetCurrentUid(void) { + uint8_t TempUid[MFCLASSIC_UID_SIZE]; + MifareClassicGetUid(TempUid); + BruteCurrentUid = BytesToUint32(TempUid); +} + +void MifareClassicAppBruteWrite(void) { + uint8_t bruteStatusByte = (isBruteEnabled) ? (BRUTE_MEM_BRUTED_STATUS_CANARY) : (BRUTE_MEM_BRUTED_STATUS_RESET); + AppWorkingMemoryWrite(&bruteStatusByte, BRUTE_MEM_BRUTED_STATUS_ADDR, BRUTE_MEM_BRUTED_STATUS_SIZE); + uint8_t TempUid[MFCLASSIC_UID_SIZE]; + Uint32ToBytes(BruteCurrentUid, TempUid); + MifareClassicSetUid(TempUid); +} + +void MifareClassicAppBruteInit(void) { + MifareClassicAppInit(MFCLASSIC_1K_ATQA_VALUE, MFCLASSIC_1K_SAK_VALUE, false); + uint8_t bruteStatusByte = BRUTE_MEM_BRUTED_STATUS_CANARY; + AppWorkingMemoryRead(&bruteStatusByte, BRUTE_MEM_BRUTED_STATUS_ADDR, BRUTE_MEM_BRUTED_STATUS_SIZE); + isBruteEnabled = (bruteStatusByte == BRUTE_MEM_BRUTED_STATUS_CANARY); + BruteIdleRounds = 0; + MifareClassicAppBruteGetCurrentUid(); +} + +void MifareClassicAppBruteStop(void) { + isBruteEnabled = false; + BruteIdleRounds = 0; + MifareClassicAppBruteWrite(); +} + +void MifareClassicAppBruteMove(void) { + isBruteEnabled = true; + BruteIdleRounds = 0; + BruteCurrentUid++; State = STATE_IDLE; + MifareClassicAppBruteWrite(); } -void MifareClassicAppTask(void) { +void MifareClassicAppBruteToggle(void) { + if(isBruteEnabled) { + MifareClassicAppBruteStop(); + } else { + MifareClassicAppBruteGetCurrentUid(); + MifareClassicAppBruteMove(); + } +} +void MifareClassicAppBruteTick(void) { + // If we were using same UID for too long, change it + if( isBruteEnabled ) { + if( BruteIdleRounds >= BRUTE_IDLE_MAX_ROUNDS ) { + MifareClassicAppBruteMove(); + } else { + BruteIdleRounds++; + } + } } +#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; +} /* Handle a MFCLASSIC_CMD_HALT during main process, as can be raised in many states. * Sets State, response buffer and response size. Returns if valid HALT. */ @@ -374,7 +563,7 @@ void mfcHandleAuthenticationRequest(bool isNested, uint8_t * Buffer, uint16_t * uint16_t KeyAddress; /* Save Nonce in detection mode */ if(isDetectionEnabled && !isNested) { -#ifdef CONFIG_MF_DETECTION_SUPPORT +#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT memset(DetectionDataSave, 0x00, DETECTION_BYTES_PER_SAVE); // Save reader's auth phase 1: KEY type (A or B), and sector number memcpy(DetectionDataSave, Buffer, DETECTION_READER_AUTH_P1_SIZE); @@ -392,12 +581,12 @@ void mfcHandleAuthenticationRequest(bool isNested, uint8_t * Buffer, uint16_t * } KeyAddress = (uint16_t) SectorAddress * MFCLASSIC_MEM_BYTES_PER_BLOCK + KeyOffset; } - AppMemoryRead(Key, KeyAddress, MFCLASSIC_MEM_KEY_SIZE); + AppCardMemoryRead(Key, KeyAddress, MFCLASSIC_MEM_KEY_SIZE); /* Load UID */ if (is7BytesUID) { - AppMemoryRead(Uid, MFCLASSIC_MEM_UID_CL2_ADDRESS, MFCLASSIC_MEM_UID_CL2_SIZE); + AppCardMemoryRead(Uid, MFCLASSIC_MEM_UID_CL2_ADDRESS, MFCLASSIC_MEM_UID_CL2_SIZE); } else { - AppMemoryRead(Uid, MFCLASSIC_MEM_UID_CL1_ADDRESS, MFCLASSIC_MEM_UID_CL1_SIZE); + AppCardMemoryRead(Uid, MFCLASSIC_MEM_UID_CL1_ADDRESS, MFCLASSIC_MEM_UID_CL1_SIZE); } /* Proceed with nested or regular authent */ if(isNested) { @@ -420,7 +609,7 @@ void mfcHandleAuthenticationRequest(bool isNested, uint8_t * Buffer, uint16_t * uint8_t CardNonce[MFCLASSIC_MEM_NONCE_SIZE] = {0x01, 0x20, 0x01, 0x45}; uint8_t CardNonceSuccessor1[MFCLASSIC_MEM_NONCE_SIZE] = {0x63, 0xe5, 0xbc, 0xa7}; uint8_t CardNonceSuccessor2[MFCLASSIC_MEM_NONCE_SIZE] = {0x99, 0x37, 0x30, 0xbd}; -#ifdef CONFIG_MF_DETECTION_SUPPORT +#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT if(isDetectionEnabled) { // Save sent 'random' nonce memcpy(DetectionDataSave+DETECTION_READER_AUTH_P1_SIZE, CardNonce, MFCLASSIC_MEM_NONCE_SIZE); @@ -457,6 +646,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 @@ -494,7 +689,7 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) { retSize = MFCLASSIC_ACK_NAK_FRAME_SIZE; } else if (Buffer[0] == MFCLASSIC_CMD_READ) { /* Read command. Read data from memory and append CRCA. */ - AppMemoryRead(Buffer, (uint16_t) Buffer[1] * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK); + AppCardMemoryRead(Buffer, (uint16_t) Buffer[1] * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK); ISO14443AAppendCRCA(Buffer, MFCLASSIC_MEM_BYTES_PER_BLOCK); retSize = (MFCLASSIC_CMD_READ_RESPONSE_FRAME_SIZE + ISO14443A_CRCA_SIZE) * BITS_PER_BYTE; @@ -515,7 +710,7 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) { if (ISO14443ACheckCRCA(Buffer, MFCLASSIC_MEM_BYTES_PER_BLOCK)) { /* CRC check passed. Write data into memory and send ACK. */ if (!ActiveConfiguration.ReadOnly) { - AppMemoryWrite(Buffer, CurrentAddress * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK); + AppCardMemoryWrite(Buffer, CurrentAddress * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK); } Buffer[0] = MFCLASSIC_ACK_VALUE; } else { @@ -549,7 +744,7 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) { SAK = CardSAKValue; NextState = STATE_ACTIVE; } - AppMemoryRead(UidCLReadBuffer, UidMemAddr, UidReadSize); + AppCardMemoryRead(UidCLReadBuffer, UidMemAddr, UidReadSize); if (ISO14443ASelect(Buffer, &BitCount, UidCL, SAK)) { /* TODO: Access control not implemented yet * AccessAddress = MFCLASSIC_MEM_INVALID_ADDRESS; // invalid, force reload */ @@ -563,7 +758,7 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) { /* 'Sequence 1' as per MF1S50YYX_V1, title 10.1.2 */ if ( is7BytesUID && (Buffer[0] == ISO14443A_CMD_SELECT_CL2) ) { uint8_t UidCL[ISO14443A_CL_UID_SIZE]; - AppMemoryRead(UidCL, MFCLASSIC_MEM_UID_CL2_ADDRESS, MFCLASSIC_MEM_UID_CL2_SIZE); + AppCardMemoryRead(UidCL, MFCLASSIC_MEM_UID_CL2_ADDRESS, MFCLASSIC_MEM_UID_CL2_SIZE); if (ISO14443ASelect(Buffer, &BitCount, UidCL, CardSAKValue)) { State = STATE_ACTIVE; isCascadeStepOnePassed = false; @@ -572,7 +767,7 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) { /* 'Sequence 2' as per MF1S50YYX_V1, title 10.1.2 */ } else if (Buffer[0] == MFCLASSIC_CMD_READ) { /* Read sector 0 / block 0 and send in plain */ - AppMemoryRead(Buffer, MFCLASSIC_MEM_S0B0_ADDRESS, MFCLASSIC_MEM_BYTES_PER_BLOCK); + AppCardMemoryRead(Buffer, MFCLASSIC_MEM_S0B0_ADDRESS, MFCLASSIC_MEM_BYTES_PER_BLOCK); ISO14443AAppendCRCA(Buffer, MFCLASSIC_MEM_BYTES_PER_BLOCK); State = STATE_ACTIVE; isCascadeStepOnePassed = false; @@ -605,7 +800,7 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) { case STATE_AUTHING: if(isDetectionEnabled) { -#ifdef CONFIG_MF_DETECTION_SUPPORT +#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT // Save reader's auth phase 2 answer to our nonce from STATE_ACTIVE memcpy(DetectionDataSave+DETECTION_SAVE_P2_OFFSET, Buffer, DETECTION_READER_AUTH_P2_SIZE); // Align data storage in each KEYX dedicated memory space, and iterate counters @@ -621,10 +816,10 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) { } // Write to app memory if(!isDetectionCanaryWritten) { - AppMemoryWrite(DetectionCanary, DETECTION_BLOCK0_CANARY_ADDR, DETECTION_BLOCK0_CANARY_SIZE); + AppWorkingMemoryWrite(DetectionCanary, DETECTION_BLOCK0_CANARY_ADDR, DETECTION_BLOCK0_CANARY_SIZE); isDetectionCanaryWritten = true; } - AppMemoryWrite(DetectionDataSave, memSaveAddr, DETECTION_BYTES_PER_SAVE); + AppWorkingMemoryWrite(DetectionDataSave, memSaveAddr, DETECTION_BYTES_PER_SAVE); State = STATE_ACTIVE; #endif } else { @@ -662,7 +857,7 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) { } else { if (Buffer[0] == MFCLASSIC_CMD_READ) { /* Read command. Read data from memory and append CRCA. */ - AppMemoryRead(Buffer, (uint16_t) Buffer[1] * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK); + AppCardMemoryRead(Buffer, (uint16_t) Buffer[1] * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK); ISO14443AAppendCRCA(Buffer, MFCLASSIC_MEM_BYTES_PER_BLOCK); /* Encrypt and calculate parity bits. */ mfcEncryptBuffer(Buffer, Buffer, (ISO14443A_CRCA_SIZE + MFCLASSIC_MEM_BYTES_PER_BLOCK)); @@ -683,7 +878,7 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) { } else if (Buffer[0] == MFCLASSIC_CMD_TRANSFER) { /* Write back the global block buffer to the desired block address */ if (!ActiveConfiguration.ReadOnly) { - AppMemoryWrite(BlockBuffer, (uint16_t) Buffer[1] * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK); + AppCardMemoryWrite(BlockBuffer, (uint16_t) Buffer[1] * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK); } else { /* In read only mode, silently ignore the write */ } @@ -728,7 +923,7 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) { if (ISO14443ACheckCRCA(Buffer, MFCLASSIC_MEM_BYTES_PER_BLOCK)) { /* Silently ignore in ReadOnly mode */ if (!ActiveConfiguration.ReadOnly) { - AppMemoryWrite(Buffer, CurrentAddress * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK); + AppCardMemoryWrite(Buffer, CurrentAddress * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK); } Buffer[0] = MFCLASSIC_ACK_VALUE ^ Crypto1Nibble(); } else { @@ -752,7 +947,7 @@ uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount) { /* We could also get an encrypted HALT... */ if ( !mfcHandleHaltCommand(Buffer, &retSize) ) { if (ISO14443ACheckCRCA(Buffer, MFCLASSIC_MEM_VALUE_SIZE)) { - AppMemoryRead(BlockBuffer, (uint16_t) CurrentAddress * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK); + AppCardMemoryRead(BlockBuffer, (uint16_t) CurrentAddress * MFCLASSIC_MEM_BYTES_PER_BLOCK, MFCLASSIC_MEM_BYTES_PER_BLOCK); if (CheckValueIntegrity(BlockBuffer)) { uint32_t ParamValue; uint32_t BlockValue; @@ -787,26 +982,31 @@ 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; } void MifareClassicGetUid(ConfigurationUidType Uid) { if (is7BytesUID) { - AppMemoryRead(&Uid[0], MFCLASSIC_MEM_UID_CL1_ADDRESS, MFCLASSIC_MEM_UID_CL1_SIZE-1); - AppMemoryRead(&Uid[3], MFCLASSIC_MEM_UID_CL2_ADDRESS, MFCLASSIC_MEM_UID_CL2_SIZE); + AppCardMemoryRead(&Uid[0], MFCLASSIC_MEM_UID_CL1_ADDRESS, MFCLASSIC_MEM_UID_CL1_SIZE-1); + AppCardMemoryRead(&Uid[3], MFCLASSIC_MEM_UID_CL2_ADDRESS, MFCLASSIC_MEM_UID_CL2_SIZE); } else { - AppMemoryRead(Uid, MFCLASSIC_MEM_UID_CL1_ADDRESS, MFCLASSIC_MEM_UID_CL1_SIZE); + AppCardMemoryRead(Uid, MFCLASSIC_MEM_UID_CL1_ADDRESS, MFCLASSIC_MEM_UID_CL1_SIZE); } } void MifareClassicSetUid(ConfigurationUidType Uid) { if (is7BytesUID) { - AppMemoryWrite(Uid, MFCLASSIC_MEM_UID_CL1_ADDRESS, ActiveConfiguration.UidSize); + AppCardMemoryWrite(Uid, MFCLASSIC_MEM_UID_CL1_ADDRESS, ActiveConfiguration.UidSize); } else { uint8_t BCC = Uid[0] ^ Uid[1] ^ Uid[2] ^ Uid[3]; - AppMemoryWrite(Uid, MFCLASSIC_MEM_UID_CL1_ADDRESS, MFCLASSIC_MEM_UID_CL1_SIZE); - AppMemoryWrite(&BCC, MFCLASSIC_MEM_UID_BCC1_ADDRESS, ISO14443A_CL_BCC_SIZE); + AppCardMemoryWrite(Uid, MFCLASSIC_MEM_UID_CL1_ADDRESS, MFCLASSIC_MEM_UID_CL1_SIZE); + AppCardMemoryWrite(&BCC, MFCLASSIC_MEM_UID_BCC1_ADDRESS, ISO14443A_CL_BCC_SIZE); } } @@ -825,3 +1025,5 @@ void MifareClassicGetSak(uint8_t * Sak) { void MifareClassicSetSak(uint8_t Sak) { CardSAKValue = Sak; } + +#endif /* Compilation support */ diff --git a/Firmware/ChameleonMini/Application/MifareClassic.h b/Firmware/ChameleonMini/Application/MifareClassic.h index aa7de38..b2136b5 100644 --- a/Firmware/ChameleonMini/Application/MifareClassic.h +++ b/Firmware/ChameleonMini/Application/MifareClassic.h @@ -7,6 +7,10 @@ * */ +#if defined(CONFIG_MF_CLASSIC_SUPPORT) || defined(CONFIG_MF_CLASSIC_DETECTION_SUPPORT) \ + || defined(CONFIG_MF_CLASSIC_BRUTE_SUPPORT) || defined(SUPPORT_MF_CLASSIC_MAGIC_MODE) \ + || defined(CONFIG_MF_CLASSIC_LOG_SUPPORT) + #ifndef MIFARECLASSIC_H_ #define MIFARECLASSIC_H_ @@ -17,9 +21,7 @@ #define MFCLASSIC_UID_7B_SIZE ISO14443A_UID_SIZE_DOUBLE #define MFCLASSIC_1K_MEM_SIZE 1024 #define MFCLASSIC_4K_MEM_SIZE 4096 -#ifdef CONFIG_MF_CLASSIC_MINI_SUPPORT #define MFCLASSIC_MINI_MEM_SIZE 320 -#endif #define MFCLASSIC_1K_ATQA_VALUE 0x0004 #define MFCLASSIC_1K_7B_ATQA_VALUE 0x0044 @@ -28,10 +30,8 @@ #define MFCLASSIC_7B_ATQA_MASK 0x40 #define MFCLASSIC_1K_SAK_VALUE 0x08 #define MFCLASSIC_4K_SAK_VALUE 0x18 -#ifdef CONFIG_MF_CLASSIC_MINI_SUPPORT #define MFCLASSIC_MINI_ATQA_VALUE MFCLASSIC_1K_ATQA_VALUE #define MFCLASSIC_MINI_SAK_VALUE 0x09 -#endif #define MFCLASSIC_SAK_CL1_VALUE ISO14443A_SAK_INCOMPLETE #define MFCLASSIC_MEM_S0B0_ADDRESS 0x00 @@ -156,7 +156,7 @@ C1 C2 C3 read write increment decrement, #define MFCLASSIC_ACC_BLOCK_DECREMENT 0x08 */ -#ifdef CONFIG_MF_DETECTION_SUPPORT +#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT #define DETECTION_BYTES_PER_SAVE 16 #define DETECTION_READER_AUTH_P1_SIZE 4 #define DETECTION_READER_AUTH_P2_SIZE 8 @@ -177,10 +177,45 @@ C1 C2 C3 read write increment decrement, #define DETECTION_BLOCK0_CANARY_SIZE 8 #endif +#ifdef CONFIG_MF_CLASSIC_BRUTE_SUPPORT +#define BRUTE_MEM_BRUTED_UID_ADDR 8 +#define BRUTE_MEM_BRUTED_STATUS_CANARY 0xB1 +#define BRUTE_MEM_BRUTED_STATUS_RESET 0xB0 +#define BRUTE_MEM_BRUTED_STATUS_ADDR 0 +#define BRUTE_MEM_BRUTED_STATUS_SIZE 1 +#define BRUTE_WORKING_MEM_SIZE 16 +#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 MifareClassicAppInitMini(void); void MifareClassicAppReset(void); -void MifareClassicAppTask(void); uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount); @@ -193,12 +228,22 @@ void MifareClassicSetAtqa(uint16_t Atqa); void MifareClassicGetSak(uint8_t * Sak); void MifareClassicSetSak(uint8_t Sak); -#ifdef CONFIG_MF_CLASSIC_MINI_SUPPORT -void MifareClassicAppInitMini(void); +#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT +void MifareClassicAppDetectionInit(void); #endif -#ifdef CONFIG_MF_DETECTION_SUPPORT -void MifareClassicAppDetectionInit(void); +#ifdef CONFIG_MF_CLASSIC_BRUTE_SUPPORT +void MifareClassicAppBruteInit(void); +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_ */ + +#endif /* Compilation support */ diff --git a/Firmware/ChameleonMini/Application/MifareUltralight.c b/Firmware/ChameleonMini/Application/MifareUltralight.c index ec0ca52..6d09ddd 100644 --- a/Firmware/ChameleonMini/Application/MifareUltralight.c +++ b/Firmware/ChameleonMini/Application/MifareUltralight.c @@ -5,6 +5,8 @@ * Author: skuser */ +#ifdef CONFIG_MF_ULTRALIGHT_SUPPORT + #include "MifareUltralight.h" #include "ISO14443-3A.h" #include "../Codec/ISO14443-2A.h" @@ -140,8 +142,8 @@ static void AppInitEV1Common(void) /* Set up the emulation flavor */ Flavor = UL_EV1; /* Fetch some of the configuration into RAM */ - AppMemoryRead(&FirstAuthenticatedPage, ConfigAreaAddress + CONF_AUTH0_OFFSET, 1); - AppMemoryRead(&Access, ConfigAreaAddress + CONF_ACCESS_OFFSET, 1); + AppCardMemoryRead(&FirstAuthenticatedPage, ConfigAreaAddress + CONF_AUTH0_OFFSET, 1); + AppCardMemoryRead(&Access, ConfigAreaAddress + CONF_ACCESS_OFFSET, 1); ReadAccessProtected = !!(Access & CONF_ACCESS_PROT); AppInitCommon(); } @@ -163,11 +165,6 @@ void MifareUltralightAppReset(void) State = STATE_IDLE; } -void MifareUltralightAppTask(void) -{ - -} - static bool VerifyAuthentication(uint8_t PageAddress) { /* No authentication for EV0 cards; always pass */ @@ -200,7 +197,7 @@ static uint8_t AppWritePage(uint8_t PageAddress, uint8_t* const Buffer) if (PageAddress == PAGE_LOCK_BITS || PageAddress == PAGE_OTP) { // OTP page and page with locks could not be resets to zero uint8_t PageBytes[MIFARE_ULTRALIGHT_PAGE_SIZE]; - AppMemoryRead(PageBytes, PageAddress * MIFARE_ULTRALIGHT_PAGE_SIZE, MIFARE_ULTRALIGHT_PAGE_SIZE); + AppCardMemoryRead(PageBytes, PageAddress * MIFARE_ULTRALIGHT_PAGE_SIZE, MIFARE_ULTRALIGHT_PAGE_SIZE); // First two bytes of page with locks are not rewritable if (PageAddress == PAGE_LOCK_BITS) { Buffer[0] = Buffer[1] = 0; @@ -209,7 +206,7 @@ static uint8_t AppWritePage(uint8_t PageAddress, uint8_t* const Buffer) Buffer[i] |= PageBytes[i]; } } - AppMemoryWrite(Buffer, PageAddress * MIFARE_ULTRALIGHT_PAGE_SIZE, MIFARE_ULTRALIGHT_PAGE_SIZE); + AppCardMemoryWrite(Buffer, PageAddress * MIFARE_ULTRALIGHT_PAGE_SIZE, MIFARE_ULTRALIGHT_PAGE_SIZE); } else { /* If the chameleon is in read only mode, it silently * ignores any attempt to write data. */ @@ -250,7 +247,7 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount) } /* Read out, emulating the wraparound */ for (Offset = 0; Offset < BYTES_PER_READ; Offset += 4) { - AppMemoryRead(&Buffer[Offset], PageAddress * MIFARE_ULTRALIGHT_PAGE_SIZE, MIFARE_ULTRALIGHT_PAGE_SIZE); + AppCardMemoryRead(&Buffer[Offset], PageAddress * MIFARE_ULTRALIGHT_PAGE_SIZE, MIFARE_ULTRALIGHT_PAGE_SIZE); PageAddress++; if (PageAddress == PageLimit) { PageAddress = 0; @@ -319,7 +316,7 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount) case CMD_GET_VERSION: { /* Check new dump format and get version from out of pages area (skip 3 pages of counters) */ - AppMemoryRead(Buffer, (PageCount + VERSION_OFFSET_PAGES) * MIFARE_ULTRALIGHT_PAGE_SIZE, VERSION_INFO_LENGTH); + AppCardMemoryRead(Buffer, (PageCount + VERSION_OFFSET_PAGES) * MIFARE_ULTRALIGHT_PAGE_SIZE, VERSION_INFO_LENGTH); if (Buffer[6] != 0x0B && Buffer[6] != 0x0E) { /* Provide hardcoded version response */ Buffer[0] = 0x00; @@ -352,7 +349,7 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount) } /* NOTE: With the current implementation, reading the password out is possible. */ ByteCount = (EndPageAddress - StartPageAddress + 1) * MIFARE_ULTRALIGHT_PAGE_SIZE; - AppMemoryRead(Buffer, StartPageAddress * MIFARE_ULTRALIGHT_PAGE_SIZE, ByteCount); + AppCardMemoryRead(Buffer, StartPageAddress * MIFARE_ULTRALIGHT_PAGE_SIZE, ByteCount); ISO14443AAppendCRCA(Buffer, ByteCount); return (ByteCount + ISO14443A_CRCA_SIZE) * 8; } @@ -362,7 +359,7 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount) uint8_t Password[4]; /* Save password */ - AppMemoryWrite(Buffer+1, MIFARE_ULTRALIGHT_PWD_ADDRESS, 4); + AppWorkingMemoryWrite(Buffer+1, MIFARE_ULTRALIGHT_PWD_ADDRESS, MIFARE_ULTRALIGHT_PWD_SIZE); /* Verify value and increment authentication attempt counter */ if (!AuthCounterIncrement()) { @@ -371,7 +368,7 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount) return NAK_FRAME_SIZE; } /* Read and compare the password */ - AppMemoryRead(Password, ConfigAreaAddress + CONF_PASSWORD_OFFSET, 4); + AppCardMemoryRead(Password, ConfigAreaAddress + CONF_PASSWORD_OFFSET, 4); if (Password[0] != Buffer[1] || Password[1] != Buffer[2] || Password[2] != Buffer[3] || Password[3] != Buffer[4]) { Buffer[0] = NAK_AUTH_FAILED; return NAK_FRAME_SIZE; @@ -380,7 +377,7 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount) AuthCounterReset(); Authenticated = 1; /* Send the PACK value back */ - AppMemoryRead(Buffer, ConfigAreaAddress + CONF_PACK_OFFSET, 2); + AppCardMemoryRead(Buffer, ConfigAreaAddress + CONF_PACK_OFFSET, 2); ISO14443AAppendCRCA(Buffer, 2); return (2 + ISO14443A_CRCA_SIZE) * 8; } @@ -393,7 +390,7 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount) return NAK_FRAME_SIZE; } /* Returned counter length is 3 bytes */ - AppMemoryRead(Buffer, (PageCount + CounterId) * MIFARE_ULTRALIGHT_PAGE_SIZE, CNT_SIZE); + AppCardMemoryRead(Buffer, (PageCount + CounterId) * MIFARE_ULTRALIGHT_PAGE_SIZE, CNT_SIZE); ISO14443AAppendCRCA(Buffer, CNT_SIZE); return (3 + ISO14443A_CRCA_SIZE) * 8; } @@ -408,7 +405,7 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount) return NAK_FRAME_SIZE; } /* Read the value out */ - AppMemoryRead(&Counter, (PageCount + CounterId) * MIFARE_ULTRALIGHT_PAGE_SIZE, CNT_SIZE); + AppCardMemoryRead(&Counter, (PageCount + CounterId) * MIFARE_ULTRALIGHT_PAGE_SIZE, CNT_SIZE); /* Add and check for overflow */ Counter += Addend; if (Counter > CNT_MAX_VALUE) { @@ -416,14 +413,14 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount) return NAK_FRAME_SIZE; } /* Update memory */ - AppMemoryWrite(&Counter, (PageCount + CounterId) * MIFARE_ULTRALIGHT_PAGE_SIZE, CNT_SIZE); + AppCardMemoryWrite(&Counter, (PageCount + CounterId) * MIFARE_ULTRALIGHT_PAGE_SIZE, CNT_SIZE); Buffer[0] = ACK_VALUE; return ACK_FRAME_SIZE; } case CMD_READ_SIG: { /* Check new dump format and get signature from out of pages area (skip 3 pages of counters, 2 pages VERSION) */ - AppMemoryRead(Buffer, (PageCount + SIGNATURE_OFFSET_PAGES) * MIFARE_ULTRALIGHT_PAGE_SIZE, SIGNATURE_LENGTH); + AppCardMemoryRead(Buffer, (PageCount + SIGNATURE_OFFSET_PAGES) * MIFARE_ULTRALIGHT_PAGE_SIZE, SIGNATURE_LENGTH); uint8_t zeros[SIGNATURE_LENGTH]; memset(zeros, 0, SIGNATURE_LENGTH); if (memcmp(Buffer, zeros, SIGNATURE_LENGTH) == 0) { @@ -437,7 +434,7 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount) case CMD_CHECK_TEARING_EVENT: { uint8_t CounterId = Buffer[1]; /* Read tearing flag from counter pages of new dump format */ - AppMemoryRead(Buffer, (PageCount + CounterId) * MIFARE_ULTRALIGHT_PAGE_SIZE + CNT_SIZE, TEARING_SIZE); + AppCardMemoryRead(Buffer, (PageCount + CounterId) * MIFARE_ULTRALIGHT_PAGE_SIZE + CNT_SIZE, TEARING_SIZE); /* Hardcoded response */ if (Buffer[0] == 0) { Buffer[0] = 0xBD; @@ -450,7 +447,7 @@ static uint16_t AppProcess(uint8_t* const Buffer, uint16_t ByteCount) uint8_t ConfigAreaAddress = PageCount * MIFARE_ULTRALIGHT_PAGE_SIZE - CONFIG_AREA_SIZE; /* Input is ignored completely */ /* Read out the value */ - AppMemoryRead(Buffer, ConfigAreaAddress + CONF_VCTID_OFFSET, 1); + AppCardMemoryRead(Buffer, ConfigAreaAddress + CONF_VCTID_OFFSET, 1); ISO14443AAppendCRCA(Buffer, 1); return (1 + ISO14443A_CRCA_SIZE) * 8; } @@ -491,7 +488,7 @@ uint16_t MifareUltralightAppProcess(uint8_t* Buffer, uint16_t BitCount) * of CL1 has to be the cascade-tag byte. */ uint8_t UidCL1[ISO14443A_CL_UID_SIZE] = { [0] = ISO14443A_UID0_CT }; - AppMemoryRead(&UidCL1[1], UID_CL1_ADDRESS, UID_CL1_SIZE); + AppCardMemoryRead(&UidCL1[1], UID_CL1_ADDRESS, UID_CL1_SIZE); if (ISO14443ASelect(Buffer, &BitCount, UidCL1, CardSAKValue)) { /* CL1 stage has ended successfully */ @@ -503,7 +500,7 @@ uint16_t MifareUltralightAppProcess(uint8_t* Buffer, uint16_t BitCount) /* Load UID CL2 and perform anticollision */ uint8_t UidCL2[ISO14443A_CL_UID_SIZE]; - AppMemoryRead(UidCL2, UID_CL2_ADDRESS, UID_CL2_SIZE); + AppCardMemoryRead(UidCL2, UID_CL2_ADDRESS, UID_CL2_SIZE); if (ISO14443ASelect(Buffer, &BitCount, UidCL2, SAK_CL2_VALUE)) { /* CL2 stage has ended successfully. This means @@ -552,8 +549,8 @@ uint16_t MifareUltralightAppProcess(uint8_t* Buffer, uint16_t BitCount) void MifareUltralightGetUid(ConfigurationUidType Uid) { /* Read UID from memory */ - AppMemoryRead(&Uid[0], UID_CL1_ADDRESS, UID_CL1_SIZE); - AppMemoryRead(&Uid[UID_CL1_SIZE], UID_CL2_ADDRESS, UID_CL2_SIZE); + AppCardMemoryRead(&Uid[0], UID_CL1_ADDRESS, UID_CL1_SIZE); + AppCardMemoryRead(&Uid[UID_CL1_SIZE], UID_CL2_ADDRESS, UID_CL2_SIZE); } void MifareUltralightSetUid(ConfigurationUidType Uid) @@ -562,28 +559,30 @@ void MifareUltralightSetUid(ConfigurationUidType Uid) uint8_t BCC1 = ISO14443A_UID0_CT ^ Uid[0] ^ Uid[1] ^ Uid[2]; uint8_t BCC2 = Uid[3] ^ Uid[4] ^ Uid[5] ^ Uid[6]; - AppMemoryWrite(&Uid[0], UID_CL1_ADDRESS, UID_CL1_SIZE); - AppMemoryWrite(&BCC1, UID_BCC1_ADDRESS, ISO14443A_CL_BCC_SIZE); - AppMemoryWrite(&Uid[UID_CL1_SIZE], UID_CL2_ADDRESS, UID_CL2_SIZE); - AppMemoryWrite(&BCC2, UID_BCC2_ADDRESS, ISO14443A_CL_BCC_SIZE); + AppCardMemoryWrite(&Uid[0], UID_CL1_ADDRESS, UID_CL1_SIZE); + AppCardMemoryWrite(&BCC1, UID_BCC1_ADDRESS, ISO14443A_CL_BCC_SIZE); + AppCardMemoryWrite(&Uid[UID_CL1_SIZE], UID_CL2_ADDRESS, UID_CL2_SIZE); + AppCardMemoryWrite(&BCC2, UID_BCC2_ADDRESS, ISO14443A_CL_BCC_SIZE); } void MifareUltralightGetAtqa(uint16_t * Atqa) { - *Atqa = CardATQAValue; + *Atqa = CardATQAValue; } void MifareUltralightSetAtqa(uint16_t Atqa) { - CardATQAValue = Atqa; + CardATQAValue = Atqa; } void MifareUltralightGetSak(uint8_t * Sak) { - *Sak = CardSAKValue; + *Sak = CardSAKValue; } void MifareUltralightSetSak(uint8_t Sak) { - CardSAKValue = Sak; + CardSAKValue = Sak; } + +#endif /* Compilation support */ diff --git a/Firmware/ChameleonMini/Application/MifareUltralight.h b/Firmware/ChameleonMini/Application/MifareUltralight.h index 3c1157a..27e271d 100644 --- a/Firmware/ChameleonMini/Application/MifareUltralight.h +++ b/Firmware/ChameleonMini/Application/MifareUltralight.h @@ -5,27 +5,29 @@ * Author: skuser */ +#ifdef CONFIG_MF_ULTRALIGHT_SUPPORT + #ifndef MIFAREULTRALIGHT_H_ #define MIFAREULTRALIGHT_H_ #include "Application.h" #include "ISO14443-3A.h" -#define MIFARE_ULTRALIGHT_UID_SIZE ISO14443A_UID_SIZE_DOUBLE -#define MIFARE_ULTRALIGHT_PAGE_SIZE 4 -#define MIFARE_ULTRALIGHT_PAGES 16 -#define MIFARE_ULTRALIGHT_EV11_PAGES 20 -#define MIFARE_ULTRALIGHT_EV12_PAGES 41 +#define MIFARE_ULTRALIGHT_UID_SIZE ISO14443A_UID_SIZE_DOUBLE +#define MIFARE_ULTRALIGHT_PAGE_SIZE 4 +#define MIFARE_ULTRALIGHT_PAGES 16 +#define MIFARE_ULTRALIGHT_EV11_PAGES 20 +#define MIFARE_ULTRALIGHT_EV12_PAGES 41 #define MIFARE_ULTRALIGHT_MEM_SIZE (MIFARE_ULTRALIGHT_PAGES * MIFARE_ULTRALIGHT_PAGE_SIZE) #define MIFARE_ULTRALIGHT_EV11_MEM_SIZE (MIFARE_ULTRALIGHT_EV11_PAGES * MIFARE_ULTRALIGHT_PAGE_SIZE) #define MIFARE_ULTRALIGHT_EV12_MEM_SIZE (MIFARE_ULTRALIGHT_EV12_PAGES * MIFARE_ULTRALIGHT_PAGE_SIZE) -#define MIFARE_ULTRALIGHT_PWD_ADDRESS (MIFARE_ULTRALIGHT_EV12_MEM_SIZE + 100) +#define MIFARE_ULTRALIGHT_PWD_ADDRESS 0 // In working memory +#define MIFARE_ULTRALIGHT_PWD_SIZE 4 // Bytes void MifareUltralightAppInit(void); void MifareUltralightEV11AppInit(void); void MifareUltralightEV12AppInit(void); void MifareUltralightAppReset(void); -void MifareUltralightAppTask(void); uint16_t MifareUltralightAppProcess(uint8_t* Buffer, uint16_t BitCount); @@ -38,3 +40,5 @@ void MifareUltralightGetSak(uint8_t * Sak); void MifareUltralightSetSak(uint8_t Sak); #endif /* MIFAREULTRALIGHT_H_ */ + +#endif /* Compilation support */ diff --git a/Firmware/ChameleonMini/Button.c b/Firmware/ChameleonMini/Button.c index c10b173..774b766 100644 --- a/Firmware/ChameleonMini/Button.c +++ b/Firmware/ChameleonMini/Button.c @@ -14,6 +14,7 @@ static const char PROGMEM ButtonActionTable[][BUTTON_NAME_MAX_LEN] = [BUTTON_ACTION_UID_RIGHT_DECREMENT] = "UID_RIGHT_DECREMENT", [BUTTON_ACTION_CYCLE_SETTINGS] = "SWITCHCARD", [BUTTON_ACTION_TOGGLE_READONLY] = "READONLY", + [BUTTON_ACTION_FUNCTION] = "CARD_FUNCTION", }; void ButtonInit(void) @@ -120,6 +121,8 @@ static void ExecuteButtonAction(ButtonActionEnum ButtonAction) SettingsCycle(); } else if (ButtonAction == BUTTON_ACTION_TOGGLE_READONLY) { ActiveConfiguration.ReadOnly = !ActiveConfiguration.ReadOnly; + } else if (ButtonAction == BUTTON_ACTION_FUNCTION) { + ApplicationButton(); } } diff --git a/Firmware/ChameleonMini/Button.h b/Firmware/ChameleonMini/Button.h index b11d6cc..0115195 100644 --- a/Firmware/ChameleonMini/Button.h +++ b/Firmware/ChameleonMini/Button.h @@ -28,7 +28,7 @@ typedef enum { BUTTON_ACTION_UID_RIGHT_DECREMENT, BUTTON_ACTION_CYCLE_SETTINGS, BUTTON_ACTION_TOGGLE_READONLY, - + BUTTON_ACTION_FUNCTION, /* This has to be last element */ BUTTON_ACTION_COUNT } ButtonActionEnum; diff --git a/Firmware/ChameleonMini/ChameleonMini.c b/Firmware/ChameleonMini/ChameleonMini.c index 16eadba..3e96c98 100644 --- a/Firmware/ChameleonMini/ChameleonMini.c +++ b/Firmware/ChameleonMini/ChameleonMini.c @@ -1,27 +1,29 @@ #include "ChameleonMini.h" int main(void) { - SystemInit(); - MemoryInit(); - SettingsLoad(); - LEDInit(); - ConfigurationInit(); - TerminalInit(); - RandomInit(); - ButtonInit(); - AntennaLevelInit(); - SystemInterruptInit(); + SystemInit(); + MemoryInit(); + SettingsLoad(); + LEDInit(); + ConfigurationInit(); + TerminalInit(); + RandomInit(); + ButtonInit(); + AntennaLevelInit(); + SystemInterruptInit(); - while(1) { - TerminalTask(); - CodecTask(); - ApplicationTask(); - - if (SystemTick100ms()) { - RandomTick(); - TerminalTick(); - ButtonTick(); - LEDTick(); - } - } + while(1) { + if (SystemTick100ms()) { + LEDTick(); + RandomTick(); + TerminalTick(); + ButtonTick(); + ApplicationTick(); + //CommandLineTick(); + //AntennaLevelTick(); + } + TerminalTask(); + CodecTask(); + //ApplicationTask(); + } } diff --git a/Firmware/ChameleonMini/ChameleonMini.cproj b/Firmware/ChameleonMini/ChameleonMini.cproj index bf9c2bd..c69534c 100644 --- a/Firmware/ChameleonMini/ChameleonMini.cproj +++ b/Firmware/ChameleonMini/ChameleonMini.cproj @@ -222,9 +222,8 @@ DEFAULT_BUTTON_ACTION=BUTTON_ACTION_CYCLE_SETTINGS DEFAULT_BUTTON_LONG_ACTION=BUTTON_ACTION_CYCLE_SETTINGS CONFIG_MF_ULTRALIGHT_SUPPORT - CONFIG_MF_CLASSIC_1K_SUPPORT - CONFIG_MF_CLASSIC_4K_SUPPORT - CONFIG_MF_DETECTION_SUPPORT + CONFIG_MF_CLASSIC_SUPPORT + CONFIG_MF_CLASSIC_DETECTION_SUPPORT SUPPORT_FIRMWARE_UPGRADE @@ -281,9 +280,8 @@ DEFAULT_BUTTON_ACTION=BUTTON_ACTION_CYCLE_SETTINGS DEFAULT_BUTTON_LONG_ACTION=BUTTON_ACTION_CYCLE_SETTINGS CONFIG_MF_ULTRALIGHT_SUPPORT - CONFIG_MF_CLASSIC_1K_SUPPORT - CONFIG_MF_CLASSIC_4K_SUPPORT - CONFIG_MF_DETECTION_SUPPORT + CONFIG_MF_CLASSIC_SUPPORT + CONFIG_MF_CLASSIC_DETECTION_SUPPORT SUPPORT_FIRMWARE_UPGRADE diff --git a/Firmware/ChameleonMini/Configuration.c b/Firmware/ChameleonMini/Configuration.c index 5875e7b..597dca8 100644 --- a/Firmware/ChameleonMini/Configuration.c +++ b/Firmware/ChameleonMini/Configuration.c @@ -6,6 +6,7 @@ */ #include +#include "Memory/Memory.h" #include "Configuration.h" #include "Settings.h" #include "Map.h" @@ -18,23 +19,21 @@ static const MapEntryType ConfigurationMap[] PROGMEM = { { .Id = CONFIG_MF_ULTRALIGHT_EV1_80B, .Text = "MF_ULTRALIGHT_EV1_80B" }, { .Id = CONFIG_MF_ULTRALIGHT_EV1_164B, .Text = "MF_ULTRALIGHT_EV1_164B" }, #endif -#ifdef CONFIG_MF_CLASSIC_1K_SUPPORT +#ifdef CONFIG_MF_CLASSIC_SUPPORT { .Id = CONFIG_MF_CLASSIC_1K, .Text = "MF_CLASSIC_1K" }, -#endif -#ifdef CONFIG_MF_CLASSIC_1K_7B_SUPPORT { .Id = CONFIG_MF_CLASSIC_1K_7B, .Text = "MF_CLASSIC_1K_7B" }, -#endif -#ifdef CONFIG_MF_CLASSIC_4K_SUPPORT { .Id = CONFIG_MF_CLASSIC_4K, .Text = "MF_CLASSIC_4K" }, -#endif -#ifdef CONFIG_MF_CLASSIC_4K_7B_SUPPORT { .Id = CONFIG_MF_CLASSIC_4K_7B, .Text = "MF_CLASSIC_4K_7B" }, -#endif -#ifdef CONFIG_MF_CLASSIC_MINI_SUPPORT { .Id = CONFIG_MF_CLASSIC_MINI, .Text = "MF_CLASSIC_MINI" }, #endif -#ifdef CONFIG_MF_DETECTION_SUPPORT - { .Id = CONFIG_MF_DETECTION, .Text = "MF_DETECTION" }, +#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT + { .Id = CONFIG_MF_CLASSIC_DETECTION, .Text = "MF_CLASSIC_DETECTION" }, +#endif +#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 }; @@ -48,6 +47,7 @@ static void ApplicationInitDummy(void) {} static void ApplicationResetDummy(void) {} static void ApplicationTaskDummy(void) {} static void ApplicationTickDummy(void) {} +static void ApplicationButtonFuncDummy(void) {} static uint16_t ApplicationProcessDummy(uint8_t* ByteBuffer, uint16_t ByteCount) { return CONFIGURATION_DUMMY_UID_PART; } static void ApplicationGetUidDummy(ConfigurationUidType Uid) { memset(Uid, CONFIGURATION_DUMMY_UID_PART, CONFIGURATION_DUMMY_UID_SIZE); } static void ApplicationSetUidDummy(ConfigurationUidType Uid) { } @@ -64,6 +64,7 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .ApplicationResetFunc = ApplicationResetDummy, .ApplicationTaskFunc = ApplicationTaskDummy, .ApplicationTickFunc = ApplicationTickDummy, + .ApplicationButtonFunc = ApplicationButtonFuncDummy, .ApplicationProcessFunc = ApplicationProcessDummy, .ApplicationGetUidFunc = ApplicationGetUidDummy, .ApplicationSetUidFunc = ApplicationSetUidDummy, @@ -72,7 +73,8 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .ApplicationGetAtqaFunc = ApplicationGetAtqaDummy, .ApplicationSetAtqaFunc = ApplicationSetAtqaDummy, .UidSize = CONFIGURATION_DUMMY_UID_SIZE, - .MemorySize = CONFIGURATION_DUMMY_MEMSIZE, + .CardMemorySize = CONFIGURATION_DUMMY_MEMSIZE, + .WorkingMemorySize = MEMORY_NO_MEMORY, .ReadOnly = true }, #ifdef CONFIG_MF_ULTRALIGHT_SUPPORT @@ -81,8 +83,9 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .CodecTaskFunc = ISO14443ACodecTask, .ApplicationInitFunc = MifareUltralightAppInit, .ApplicationResetFunc = MifareUltralightAppReset, - .ApplicationTaskFunc = MifareUltralightAppTask, + .ApplicationTaskFunc = ApplicationTaskDummy, .ApplicationTickFunc = ApplicationTickDummy, + .ApplicationButtonFunc = ApplicationButtonFuncDummy, .ApplicationProcessFunc = MifareUltralightAppProcess, .ApplicationGetUidFunc = MifareUltralightGetUid, .ApplicationSetUidFunc = MifareUltralightSetUid, @@ -91,7 +94,8 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .ApplicationGetAtqaFunc = MifareUltralightGetAtqa, .ApplicationSetAtqaFunc = MifareUltralightSetAtqa, .UidSize = MIFARE_ULTRALIGHT_UID_SIZE, - .MemorySize = MIFARE_ULTRALIGHT_MEM_SIZE, + .CardMemorySize = MIFARE_ULTRALIGHT_MEM_SIZE, + .WorkingMemorySize = MIFARE_ULTRALIGHT_PWD_SIZE, .ReadOnly = false }, [CONFIG_MF_ULTRALIGHT_EV1_80B] = { @@ -99,8 +103,9 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .CodecTaskFunc = ISO14443ACodecTask, .ApplicationInitFunc = MifareUltralightEV11AppInit, .ApplicationResetFunc = MifareUltralightAppReset, - .ApplicationTaskFunc = MifareUltralightAppTask, + .ApplicationTaskFunc = ApplicationTaskDummy, .ApplicationTickFunc = ApplicationTickDummy, + .ApplicationButtonFunc = ApplicationButtonFuncDummy, .ApplicationProcessFunc = MifareUltralightAppProcess, .ApplicationGetUidFunc = MifareUltralightGetUid, .ApplicationSetUidFunc = MifareUltralightSetUid, @@ -109,7 +114,8 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .ApplicationGetAtqaFunc = MifareUltralightGetAtqa, .ApplicationSetAtqaFunc = MifareUltralightSetAtqa, .UidSize = MIFARE_ULTRALIGHT_UID_SIZE, - .MemorySize = MIFARE_ULTRALIGHT_EV11_MEM_SIZE, + .CardMemorySize = MIFARE_ULTRALIGHT_EV11_MEM_SIZE, + .WorkingMemorySize = MIFARE_ULTRALIGHT_PWD_SIZE, .ReadOnly = false }, [CONFIG_MF_ULTRALIGHT_EV1_164B] = { @@ -117,8 +123,9 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .CodecTaskFunc = ISO14443ACodecTask, .ApplicationInitFunc = MifareUltralightEV12AppInit, .ApplicationResetFunc = MifareUltralightAppReset, - .ApplicationTaskFunc = MifareUltralightAppTask, + .ApplicationTaskFunc = ApplicationTaskDummy, .ApplicationTickFunc = ApplicationTickDummy, + .ApplicationButtonFunc = ApplicationButtonFuncDummy, .ApplicationProcessFunc = MifareUltralightAppProcess, .ApplicationGetUidFunc = MifareUltralightGetUid, .ApplicationSetUidFunc = MifareUltralightSetUid, @@ -127,18 +134,20 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .ApplicationGetAtqaFunc = MifareUltralightGetAtqa, .ApplicationSetAtqaFunc = MifareUltralightSetAtqa, .UidSize = MIFARE_ULTRALIGHT_UID_SIZE, - .MemorySize = MIFARE_ULTRALIGHT_EV12_MEM_SIZE, + .CardMemorySize = MIFARE_ULTRALIGHT_EV12_MEM_SIZE, + .WorkingMemorySize = MIFARE_ULTRALIGHT_PWD_SIZE, .ReadOnly = false }, #endif -#ifdef CONFIG_MF_CLASSIC_1K_SUPPORT +#ifdef CONFIG_MF_CLASSIC_SUPPORT [CONFIG_MF_CLASSIC_1K] = { .CodecInitFunc = ISO14443ACodecInit, .CodecTaskFunc = ISO14443ACodecTask, .ApplicationInitFunc = MifareClassicAppInit1K, .ApplicationResetFunc = MifareClassicAppReset, - .ApplicationTaskFunc = MifareClassicAppTask, + .ApplicationTaskFunc = ApplicationTaskDummy, .ApplicationTickFunc = ApplicationTickDummy, + .ApplicationButtonFunc = ApplicationButtonFuncDummy, .ApplicationProcessFunc = MifareClassicAppProcess, .ApplicationGetUidFunc = MifareClassicGetUid, .ApplicationSetUidFunc = MifareClassicSetUid, @@ -147,18 +156,18 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .ApplicationGetAtqaFunc = MifareClassicGetAtqa, .ApplicationSetAtqaFunc = MifareClassicSetAtqa, .UidSize = MFCLASSIC_UID_SIZE, - .MemorySize = MFCLASSIC_1K_MEM_SIZE, + .CardMemorySize = MFCLASSIC_1K_MEM_SIZE, + .WorkingMemorySize = MEMORY_NO_MEMORY, .ReadOnly = false }, -#endif -#ifdef CONFIG_MF_CLASSIC_1K_7B_SUPPORT [CONFIG_MF_CLASSIC_1K_7B] = { .CodecInitFunc = ISO14443ACodecInit, .CodecTaskFunc = ISO14443ACodecTask, .ApplicationInitFunc = MifareClassicAppInit1K, .ApplicationResetFunc = MifareClassicAppReset, - .ApplicationTaskFunc = MifareClassicAppTask, + .ApplicationTaskFunc = ApplicationTaskDummy, .ApplicationTickFunc = ApplicationTickDummy, + .ApplicationButtonFunc = ApplicationButtonFuncDummy, .ApplicationProcessFunc = MifareClassicAppProcess, .ApplicationGetUidFunc = MifareClassicGetUid, .ApplicationSetUidFunc = MifareClassicSetUid, @@ -167,18 +176,18 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .ApplicationGetAtqaFunc = MifareClassicGetAtqa, .ApplicationSetAtqaFunc = MifareClassicSetAtqa, .UidSize = MFCLASSIC_UID_7B_SIZE, - .MemorySize = MFCLASSIC_1K_MEM_SIZE, + .CardMemorySize = MFCLASSIC_1K_MEM_SIZE, + .WorkingMemorySize = MEMORY_NO_MEMORY, .ReadOnly = false }, -#endif -#ifdef CONFIG_MF_CLASSIC_4K_SUPPORT [CONFIG_MF_CLASSIC_4K] = { .CodecInitFunc = ISO14443ACodecInit, .CodecTaskFunc = ISO14443ACodecTask, .ApplicationInitFunc = MifareClassicAppInit4K, .ApplicationResetFunc = MifareClassicAppReset, - .ApplicationTaskFunc = MifareClassicAppTask, + .ApplicationTaskFunc = ApplicationTaskDummy, .ApplicationTickFunc = ApplicationTickDummy, + .ApplicationButtonFunc = ApplicationButtonFuncDummy, .ApplicationProcessFunc = MifareClassicAppProcess, .ApplicationGetUidFunc = MifareClassicGetUid, .ApplicationSetUidFunc = MifareClassicSetUid, @@ -187,18 +196,18 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .ApplicationGetAtqaFunc = MifareClassicGetAtqa, .ApplicationSetAtqaFunc = MifareClassicSetAtqa, .UidSize = MFCLASSIC_UID_SIZE, - .MemorySize = MFCLASSIC_4K_MEM_SIZE, + .CardMemorySize = MFCLASSIC_4K_MEM_SIZE, + .WorkingMemorySize = MEMORY_NO_MEMORY, .ReadOnly = false }, -#endif -#ifdef CONFIG_MF_CLASSIC_4K_7B_SUPPORT [CONFIG_MF_CLASSIC_4K_7B] = { .CodecInitFunc = ISO14443ACodecInit, .CodecTaskFunc = ISO14443ACodecTask, .ApplicationInitFunc = MifareClassicAppInit4K, .ApplicationResetFunc = MifareClassicAppReset, - .ApplicationTaskFunc = MifareClassicAppTask, + .ApplicationTaskFunc = ApplicationTaskDummy, .ApplicationTickFunc = ApplicationTickDummy, + .ApplicationButtonFunc = ApplicationButtonFuncDummy, .ApplicationProcessFunc = MifareClassicAppProcess, .ApplicationGetUidFunc = MifareClassicGetUid, .ApplicationSetUidFunc = MifareClassicSetUid, @@ -207,18 +216,18 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .ApplicationGetAtqaFunc = MifareClassicGetAtqa, .ApplicationSetAtqaFunc = MifareClassicSetAtqa, .UidSize = MFCLASSIC_UID_7B_SIZE, - .MemorySize = MFCLASSIC_4K_MEM_SIZE, + .CardMemorySize = MFCLASSIC_4K_MEM_SIZE, + .WorkingMemorySize = MEMORY_NO_MEMORY, .ReadOnly = false }, -#endif -#ifdef CONFIG_MF_CLASSIC_MINI_SUPPORT [CONFIG_MF_CLASSIC_MINI] = { .CodecInitFunc = ISO14443ACodecInit, .CodecTaskFunc = ISO14443ACodecTask, .ApplicationInitFunc = MifareClassicAppInitMini, .ApplicationResetFunc = MifareClassicAppReset, - .ApplicationTaskFunc = MifareClassicAppTask, + .ApplicationTaskFunc = ApplicationTaskDummy, .ApplicationTickFunc = ApplicationTickDummy, + .ApplicationButtonFunc = ApplicationButtonFuncDummy, .ApplicationProcessFunc = MifareClassicAppProcess, .ApplicationGetUidFunc = MifareClassicGetUid, .ApplicationSetUidFunc = MifareClassicSetUid, @@ -227,18 +236,20 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .ApplicationGetAtqaFunc = MifareClassicGetAtqa, .ApplicationSetAtqaFunc = MifareClassicSetAtqa, .UidSize = MFCLASSIC_UID_SIZE, - .MemorySize = MFCLASSIC_MINI_MEM_SIZE, + .CardMemorySize = MFCLASSIC_MINI_MEM_SIZE, + .WorkingMemorySize = MEMORY_NO_MEMORY, .ReadOnly = false }, #endif -#ifdef CONFIG_MF_DETECTION_SUPPORT -[CONFIG_MF_DETECTION] = { +#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT +[CONFIG_MF_CLASSIC_DETECTION] = { .CodecInitFunc = ISO14443ACodecInit, .CodecTaskFunc = ISO14443ACodecTask, .ApplicationInitFunc = MifareClassicAppDetectionInit, .ApplicationResetFunc = MifareClassicAppReset, - .ApplicationTaskFunc = MifareClassicAppTask, + .ApplicationTaskFunc = ApplicationTaskDummy, .ApplicationTickFunc = ApplicationTickDummy, + .ApplicationButtonFunc = ApplicationButtonFuncDummy, .ApplicationProcessFunc = MifareClassicAppProcess, .ApplicationGetUidFunc = MifareClassicGetUid, .ApplicationSetUidFunc = MifareClassicSetUid, @@ -247,8 +258,53 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = { .ApplicationGetAtqaFunc = MifareClassicGetAtqa, .ApplicationSetAtqaFunc = MifareClassicSetAtqa, .UidSize = MFCLASSIC_UID_SIZE, - .MemorySize = DETECTION_MEM_APP_SIZE, - .ReadOnly = true + .CardMemorySize = MFCLASSIC_1K_MEM_SIZE, + .WorkingMemorySize = DETECTION_MEM_APP_SIZE, + .ReadOnly = false +}, +#endif +#ifdef CONFIG_MF_CLASSIC_BRUTE_SUPPORT +[CONFIG_MF_CLASSIC_BRUTE] = { + .CodecInitFunc = ISO14443ACodecInit, + .CodecTaskFunc = ISO14443ACodecTask, + .ApplicationInitFunc = MifareClassicAppBruteInit, + .ApplicationResetFunc = MifareClassicAppReset, + .ApplicationTaskFunc = ApplicationTaskDummy, + .ApplicationTickFunc = MifareClassicAppBruteTick, + .ApplicationButtonFunc = MifareClassicAppBruteToggle, + .ApplicationProcessFunc = MifareClassicAppProcess, + .ApplicationGetUidFunc = MifareClassicGetUid, + .ApplicationSetUidFunc = MifareClassicSetUid, + .ApplicationGetSakFunc = MifareClassicGetSak, + .ApplicationSetSakFunc = MifareClassicSetSak, + .ApplicationGetAtqaFunc = MifareClassicGetAtqa, + .ApplicationSetAtqaFunc = MifareClassicSetAtqa, + .UidSize = MFCLASSIC_UID_SIZE, + .CardMemorySize = MFCLASSIC_1K_MEM_SIZE, + .WorkingMemorySize = BRUTE_WORKING_MEM_SIZE, + .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 }; @@ -292,14 +348,10 @@ void ConfigurationGetList(char* List, uint16_t BufferSize) MapToString(ConfigurationMap, ARRAY_COUNT(ConfigurationMap), List, BufferSize); } -uint32_t ConfigurationTableGetMemorySizeForId(ConfigurationEnum Configuration) { - /* Possible other implementation - ConfigurationType ConfForSetting; - memcpy_P( &ConfForSetting, - &(ConfigurationTable[GlobalSettings.Settings[SettingNumber].Configuration]), - sizeof(ConfigurationType) ); - return ConfForSetting.MemorySize; - */ - return ( (uint32_t)pgm_read_dword( &(ConfigurationTable[Configuration].MemorySize) ) ); +uint32_t ConfigurationTableGetCardMemorySizeForId(ConfigurationEnum Configuration) { + return ( (uint32_t)pgm_read_dword( &(ConfigurationTable[Configuration].CardMemorySize) ) ); } +uint32_t ConfigurationTableGetWorkingMemorySizeForId(ConfigurationEnum Configuration) { + return ( (uint32_t)pgm_read_dword( &(ConfigurationTable[Configuration].WorkingMemorySize) ) ); +} diff --git a/Firmware/ChameleonMini/Configuration.h b/Firmware/ChameleonMini/Configuration.h index 86a794d..8b53599 100644 --- a/Firmware/ChameleonMini/Configuration.h +++ b/Firmware/ChameleonMini/Configuration.h @@ -29,23 +29,21 @@ typedef enum { CONFIG_MF_ULTRALIGHT_EV1_80B, CONFIG_MF_ULTRALIGHT_EV1_164B, #endif -#ifdef CONFIG_MF_CLASSIC_1K_SUPPORT +#ifdef CONFIG_MF_CLASSIC_SUPPORT CONFIG_MF_CLASSIC_1K, -#endif -#ifdef CONFIG_MF_CLASSIC_1K_7B_SUPPORT CONFIG_MF_CLASSIC_1K_7B, -#endif -#ifdef CONFIG_MF_CLASSIC_4K_SUPPORT CONFIG_MF_CLASSIC_4K, -#endif -#ifdef CONFIG_MF_CLASSIC_4K_7B_SUPPORT CONFIG_MF_CLASSIC_4K_7B, -#endif -#ifdef CONFIG_MF_CLASSIC_MINI_SUPPORT CONFIG_MF_CLASSIC_MINI, #endif -#ifdef CONFIG_MF_DETECTION_SUPPORT - CONFIG_MF_DETECTION, +#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT + CONFIG_MF_CLASSIC_DETECTION, +#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 @@ -85,6 +83,8 @@ typedef struct { void (*ApplicationTaskFunc) (void); /** Function that is called roughly every 100ms. This can be used for parallel tasks of the application, that is independent of the codec module. */ void (*ApplicationTickFunc) (void); + /** Function that is called when the "CARD_FUNCTION" button is pushed */ + void (*ApplicationButtonFunc) (void); /** This function does two important things. It gets called by the codec. * The first task is to deliver data that have been received by the codec module to * the application module. The application then can decide how to answer to these data and return @@ -131,11 +131,10 @@ typedef struct { * @} */ - /** - * Defines how many space the configuration needs. For emulating configurations this is the memory space of - * the emulated card. - */ - uint32_t MemorySize; + // Defines how many space the configuration needs to store card emulation data. + uint32_t CardMemorySize; + // Defines how many space the configuration needs to store working data (logs, results, etc.) + uint32_t WorkingMemorySize; /** * Defines the size of the UID for emulating configurations. */ @@ -154,6 +153,7 @@ void ConfigurationSetById(ConfigurationEnum Configuration); void ConfigurationGetByName(char* Configuration, uint16_t BufferSize); bool ConfigurationSetByName(const char* Configuration); void ConfigurationGetList(char* ConfigurationList, uint16_t BufferSize); -uint32_t ConfigurationTableGetMemorySizeForId(ConfigurationEnum Configuration); +uint32_t ConfigurationTableGetCardMemorySizeForId(ConfigurationEnum Configuration); +uint32_t ConfigurationTableGetWorkingMemorySizeForId(ConfigurationEnum Configuration); #endif /* _CM_CONFIGURATION_H_ */ diff --git a/Firmware/ChameleonMini/Makefile b/Firmware/ChameleonMini/Makefile index 9575b04..574f54b 100644 --- a/Firmware/ChameleonMini/Makefile +++ b/Firmware/ChameleonMini/Makefile @@ -16,67 +16,30 @@ PYTHON_BIN = /usr/bin/env python3 CRYPTO_TOOL = ../../Software/Tools/crypt_operations.py #Supported configurations -SETTINGS += -DCONFIG_MF_CLASSIC_1K_SUPPORT -SETTINGS += -DCONFIG_MF_CLASSIC_1K_7B_SUPPORT -SETTINGS += -DCONFIG_MF_CLASSIC_4K_SUPPORT -SETTINGS += -DCONFIG_MF_CLASSIC_4K_7B_SUPPORT -SETTINGS += -DCONFIG_MF_CLASSIC_MINI_SUPPORT +SETTINGS += -DCONFIG_MF_CLASSIC_SUPPORT SETTINGS += -DCONFIG_MF_ULTRALIGHT_SUPPORT -#SETTINGS += -DCONFIG_ISO14443A_SNIFF_SUPPORT -#SETTINGS += -DCONFIG_ISO14443A_READER_SUPPORT -SETTINGS += -DCONFIG_MF_DETECTION_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 -#Don't touch manufacturer byte with BUTTON_ACTION_UID_LEFT_(DE/IN)CREMENT -#SETTINGS += -DSUPPORT_UID7_FIX_MANUFACTURER_BYTE - #Support activating firmware upgrade mode through command-line SETTINGS += -DSUPPORT_FIRMWARE_UPGRADE #Enable the MEMORYTEST and/or MEMORYINFO commands to help with memory management debug -#SETTINGS += -DCONFIG_DEBUG_MEMORYTEST_COMMAND -#SETTINGS += -DCONFIG_DEBUG_MEMORYINFO_COMMAND +SETTINGS += -DCONFIG_DEBUG_MEMORYTEST_COMMAND +SETTINGS += -DCONFIG_DEBUG_MEMORYINFO_COMMAND #Default configuration SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_NONE -#SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_MF_CLASSIC_1K -#SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_MF_CLASSIC_4K -#SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_MF_ULTRALIGHT -#SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_ISO14443A_READER #Default button actions -#SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_NONE -#SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_UID_RANDOM -#SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_UID_LEFT_INCREMENT -#SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_UID_RIGHT_INCREMENT -#SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_UID_LEFT_DECREMENT -#SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_UID_RIGHT_DECREMENT SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_CYCLE_SETTINGS -#SETTINGS += -DDEFAULT_BUTTON_ACTION=BUTTON_ACTION_STORE_MEM - #Default long button action SETTINGS += -DDEFAULT_BUTTON_LONG_ACTION=BUTTON_ACTION_NONE -#Define if button action setting should be independent of active setting -#SETTINGS += -DBUTTON_SETTING_GLOBAL - -#Default LED functions -#SETTINGS += -DDEFAULT_RED_LED_ACTION=LED_SETTING_CHANGE -#SETTINGS += -DDEFAULT_GREEN_LED_ACTION=LED_POWERED - -#Define if LED function setting should be independent of active setting -#SETTINGS += -DLED_SETTING_GLOBAL - -#Default logging mode -#SETTINGS += -DDEFAULT_LOG_MODE=LOG_MODE_OFF -#SETTINGS += -DDEFAULT_LOG_MODE=LOG_MODE_MEMORY -#SETTINGS += -DDEFAULT_LOG_MODE=LOG_MODE_TERMINAL - -#Define if log settings should be global -#SETTINGS += -DLOG_SETTING_GLOBAL - #Default setting SETTINGS += -DDEFAULT_SETTING=0 diff --git a/Firmware/ChameleonMini/Memory/Memory.c b/Firmware/ChameleonMini/Memory/Memory.c index d6c9037..b49503e 100644 --- a/Firmware/ChameleonMini/Memory/Memory.c +++ b/Firmware/ChameleonMini/Memory/Memory.c @@ -18,44 +18,87 @@ #include "../Configuration.h" #include "../Application/Application.h" -// Set after correct memory init -static bool isMemoryInit = false; +memoryMappingInfo_t MemoryMappingInfo = {MEMORY_NO_MEMORY, MEMORY_NO_MEMORY, MEMORY_NO_MEMORY, false}; /* Common helpers for memory operations ***************************************************************************************/ -// How much memory a setting's application will take. If set to 0 or to more than possible, -// pretend that max available memory for a setting/slot is used. -// Otherwise, give what is required by setting's configuration value 'MemorySize'. -INLINE uint32_t getAppMemSizeForSetting(uint8_t SettingNumber) { - uint16_t requiredMem = ConfigurationTableGetMemorySizeForId(GlobalSettings.Settings[SettingNumber].Configuration); - if( (requiredMem == MEMORY_NO_MEMORY) || (requiredMem > MemoryMappingInfo.maxFlashBytesPerSlot) ) { - requiredMem = MemoryMappingInfo.maxFlashBytesPerSlot; +// How much memory a setting's application will take. If set to MEMORY_ALL_MEMORY +// or to more than possible, use max available memory. +// Otherwise, give what is required by setting's configuration values. +uint32_t getAppSomeMemorySizeForSetting(uint32_t availMem, uint32_t requiredMem) { + if( (requiredMem == MEMORY_ALL_MEMORY) || (requiredMem > availMem) ) { + requiredMem = availMem; } return requiredMem; } -INLINE bool checkSettingNumberConsistency(uint8_t SettingNumber) { - return ( (SettingNumber >= SETTINGS_FIRST) && (SettingNumber <= SETTINGS_LAST) ); +uint32_t AppCardMemorySizeForSetting(uint8_t SettingNumber) { + uint32_t requiredMem = (SettingNumber == GlobalSettings.ActiveSetting) ? (ActiveConfiguration.CardMemorySize) : (ConfigurationTableGetCardMemorySizeForId(GlobalSettings.Settings[SettingNumber].Configuration)); + return getAppSomeMemorySizeForSetting( MemoryMappingInfo.maxFlashBytesPerCardMemory, requiredMem); +} + +uint32_t AppWorkingMemorySizeForSetting(uint8_t SettingNumber) { + uint32_t requiredMem = (SettingNumber == GlobalSettings.ActiveSetting) ? (ActiveConfiguration.WorkingMemorySize) : (ConfigurationTableGetWorkingMemorySizeForId(GlobalSettings.Settings[SettingNumber].Configuration)); + return getAppSomeMemorySizeForSetting( (MemoryMappingInfo.maxFlashBytesPerSlot - AppCardMemorySizeForSetting(SettingNumber)), requiredMem ); +} + +uint32_t AppCardMemorySize(void) { + return AppCardMemorySizeForSetting(GlobalSettings.ActiveSetting); +} + +uint32_t AppWorkingMemorySize(void) { + return AppWorkingMemorySizeForSetting(GlobalSettings.ActiveSetting); +} + +uint32_t AppMemorySizeForSetting(uint8_t SettingNumber) { + return (AppCardMemorySizeForSetting(SettingNumber) + AppWorkingMemorySizeForSetting(SettingNumber)); +} + +uint32_t AppMemorySize(void) { + return AppMemorySizeForSetting(GlobalSettings.ActiveSetting); +} + +bool checkSettingNumberConsistency(uint8_t SettingNumber) { + return ( (SettingNumber == GlobalSettings.ActiveSetting) || ((SettingNumber >= SETTINGS_FIRST) && (SettingNumber <= SETTINGS_LAST)) ); } // Is an address start + offset R/W operation valid in setting's application memory space -INLINE bool checkAddrConsistencyForSetting(uint8_t SettingNumber, uint32_t Address, uint32_t ByteCount) { - bool ret = (isMemoryInit && checkSettingNumberConsistency(SettingNumber)); - if(ret) { - ret = (Address <= (getAppMemSizeForSetting(SettingNumber) - ByteCount)); +bool checkAddrConsistencyForSetting(uint32_t availMem, uint8_t SettingNumber, uint32_t Address, uint32_t ByteCount) { + bool ret = false; + if( MemoryMappingInfo.isMemoryInit && checkSettingNumberConsistency(SettingNumber) + && (availMem > MEMORY_NO_MEMORY) && (availMem >= ByteCount)) { + ret = (Address <= (availMem - ByteCount)); } return ret; } +bool checkCardMemAddrConsistencyForSetting(uint8_t SettingNumber, uint32_t Address, uint32_t ByteCount) { + uint32_t availMem = (SettingNumber == GlobalSettings.ActiveSetting) ? (AppCardMemorySize()) : (AppCardMemorySizeForSetting(SettingNumber)); + return checkAddrConsistencyForSetting(availMem, SettingNumber, Address, ByteCount); +} + +bool checkWorkingMemAddrConsistencyForSetting(uint8_t SettingNumber, uint32_t Address, uint32_t ByteCount) { + uint32_t availMem = (SettingNumber == GlobalSettings.ActiveSetting) ? (AppWorkingMemorySize()) : (AppWorkingMemorySizeForSetting(SettingNumber)); + return checkAddrConsistencyForSetting(availMem, SettingNumber, Address, ByteCount);; +} + // Returns a byte address in SPI Flash from a byte address relative to application's // memory space. // Does not check for address validity in application's space (checkSettingAddrConsistency // must be used if needed). -INLINE uint32_t getFlashAddressForSetting(uint8_t SettingNumber, uint32_t Address) { +uint32_t getFlashAddressForSetting(uint8_t SettingNumber, uint32_t Address) { return ((uint32_t)(SettingNumber * MemoryMappingInfo.maxFlashBytesPerSlot) + Address); } +uint32_t getCardMemFlashAddressForSetting(uint8_t SettingNumber, uint32_t Address) { + return getFlashAddressForSetting(SettingNumber, Address); +} + +uint32_t getWorkingMemFlashAddressForSetting(uint8_t SettingNumber, uint32_t Address) { + return getFlashAddressForSetting(SettingNumber, (AppCardMemorySizeForSetting(SettingNumber) + Address)); +} + /* Memory init operations ***************************************************************************************/ @@ -65,10 +108,12 @@ bool MemoryInit(void) { bool eepromOk = false; if( FlashInit() ) { MemoryMappingInfo.maxFlashBytesPerSlot = (FlashInfo.geometry.sizeBytes / SETTINGS_COUNT); - if( MemoryMappingInfo.maxFlashBytesPerSlot >= MEMORY_MIN_BYTES_PER_APP ) { + MemoryMappingInfo.maxFlashBytesPerCardMemory = (MemoryMappingInfo.maxFlashBytesPerSlot / MEMORY_MAX_BYTES_PER_CARD_DIVIDER); + if( MemoryMappingInfo.maxFlashBytesPerCardMemory >= MEMORY_MIN_BYTES_PER_APP ) { flashOk = true; } else { MemoryMappingInfo.maxFlashBytesPerSlot = MEMORY_NO_MEMORY; + MemoryMappingInfo.maxFlashBytesPerCardMemory = MEMORY_NO_MEMORY; } } if( EEPROMInit() ) { @@ -79,60 +124,111 @@ bool MemoryInit(void) { MemoryMappingInfo.maxFlashBytesPerSlot = MEMORY_NO_MEMORY; } } - isMemoryInit = (flashOk && eepromOk); - return isMemoryInit; + MemoryMappingInfo.isMemoryInit = (flashOk && eepromOk); + return MemoryMappingInfo.isMemoryInit; } + /* Memory read operations ***************************************************************************************/ -bool AppMemoryReadForSetting(uint8_t SettingNumber, void* Buffer, uint32_t Address, uint32_t ByteCount) { +bool AppMemoryReadForSetting( bool (*checkAddr)(uint8_t, uint32_t, uint32_t), + uint32_t (*getAddr)(uint8_t, uint32_t), + uint8_t SettingNumber, void* Buffer, uint32_t Address, uint32_t ByteCount ) { bool ret = false; - if( checkAddrConsistencyForSetting(SettingNumber, Address, ByteCount) ) { - ret = FlashUnbufferedBytesRead(Buffer, getFlashAddressForSetting(SettingNumber, Address), ByteCount); + if( (*checkAddr)(SettingNumber, Address, ByteCount) ) { + ret = FlashUnbufferedBytesRead(Buffer, (*getAddr)(SettingNumber, Address), ByteCount); } return ret; } -bool AppMemoryRead(void* Buffer, uint32_t Address, uint32_t ByteCount) { - return AppMemoryReadForSetting(GlobalSettings.ActiveSetting, Buffer, Address, ByteCount); +bool AppCardMemoryReadForSetting(uint8_t SettingNumber, void* Buffer, uint32_t Address, uint32_t ByteCount) { + return AppMemoryReadForSetting( &checkCardMemAddrConsistencyForSetting, &getCardMemFlashAddressForSetting, + SettingNumber, Buffer, Address, ByteCount ); +} + +bool AppWorkingMemoryReadForSetting(uint8_t SettingNumber, void* Buffer, uint32_t Address, uint32_t ByteCount) { + return AppMemoryReadForSetting( &checkWorkingMemAddrConsistencyForSetting, &getWorkingMemFlashAddressForSetting, + SettingNumber, Buffer, Address, ByteCount ); +} + +bool AppCardMemoryRead(void* Buffer, uint32_t Address, uint32_t ByteCount) { + return AppCardMemoryReadForSetting(GlobalSettings.ActiveSetting, Buffer, Address, ByteCount); +} + +bool AppWorkingMemoryRead(void* Buffer, uint32_t Address, uint32_t ByteCount) { + return AppWorkingMemoryReadForSetting(GlobalSettings.ActiveSetting, Buffer, Address, ByteCount); } -bool AppMemoryDownloadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount) { +bool AppMemoryDownloadXModem( uint32_t (*getSize)(void), bool (*memRead)(void*, uint32_t, uint32_t), + void* Buffer, uint32_t Address, uint32_t ByteCount ) { bool ret = false; - uint32_t AvailBytes = getAppMemSizeForSetting(GlobalSettings.ActiveSetting); + uint32_t AvailBytes = (*getSize)(); if(Address < AvailBytes) { uint32_t BytesLeft = MIN(ByteCount, AvailBytes - Address); - ret = AppMemoryRead(Buffer, Address, BytesLeft); + ret = (*memRead)(Buffer, Address, BytesLeft); } return ret; } +bool AppCardMemoryDownloadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount) { + return AppMemoryDownloadXModem( &AppCardMemorySize, &AppCardMemoryRead, Buffer, Address, ByteCount); +} + +bool AppWorkingMemoryDownloadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount) { + return AppMemoryDownloadXModem( &AppWorkingMemorySize, &AppWorkingMemoryRead, Buffer, Address, ByteCount); +} + /* Memory write operations ***************************************************************************************/ -bool AppMemoryWriteForSetting(uint8_t SettingNumber, const void* Buffer, uint32_t Address, uint32_t ByteCount) { +bool AppMemoryWriteForSetting( bool (*checkAddr)(uint8_t, uint32_t, uint32_t), + uint32_t (*getAddr)(uint8_t, uint32_t), + uint8_t SettingNumber, const void* Buffer, uint32_t Address, uint32_t ByteCount ) { bool ret = false; - if( checkAddrConsistencyForSetting(SettingNumber, Address, ByteCount) ) { - ret = FlashBufferedBytesWrite(Buffer, getFlashAddressForSetting(SettingNumber, Address), ByteCount); + if( (*checkAddr)(SettingNumber, Address, ByteCount) ) { + ret = FlashBufferedBytesWrite(Buffer, (*getAddr)(SettingNumber, Address), ByteCount); } return ret; } -bool AppMemoryWrite(const void* Buffer, uint32_t Address, uint32_t ByteCount) { - return AppMemoryWriteForSetting(GlobalSettings.ActiveSetting, Buffer, Address, ByteCount); +bool AppCardMemoryWriteForSetting(uint8_t SettingNumber, const void* Buffer, uint32_t Address, uint32_t ByteCount) { + return AppMemoryWriteForSetting( &checkCardMemAddrConsistencyForSetting, &getCardMemFlashAddressForSetting, + SettingNumber, Buffer, Address, ByteCount ); +} + +bool AppWorkingMemoryWriteForSetting(uint8_t SettingNumber, const void* Buffer, uint32_t Address, uint32_t ByteCount) { + return AppMemoryWriteForSetting( &checkWorkingMemAddrConsistencyForSetting, &getWorkingMemFlashAddressForSetting, + SettingNumber, Buffer, Address, ByteCount ); } -bool AppMemoryUploadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount) { +bool AppCardMemoryWrite(const void* Buffer, uint32_t Address, uint32_t ByteCount) { + return AppCardMemoryWriteForSetting(GlobalSettings.ActiveSetting, Buffer, Address, ByteCount); +} + +bool AppWorkingMemoryWrite(const void* Buffer, uint32_t Address, uint32_t ByteCount) { + return AppWorkingMemoryWriteForSetting(GlobalSettings.ActiveSetting, Buffer, Address, ByteCount); +} + +bool AppMemoryUploadXModem( uint32_t (*getSize)(void), bool (*memWrite)(const void*, uint32_t, uint32_t), + void* Buffer, uint32_t Address, uint32_t ByteCount ) { bool ret = false; - uint32_t AvailBytes = getAppMemSizeForSetting(GlobalSettings.ActiveSetting); + uint32_t AvailBytes = (*getSize)(); if(Address < AvailBytes) { uint32_t BytesLeft = MIN(ByteCount, AvailBytes - Address); - ret = AppMemoryWrite((const void *)Buffer, Address, BytesLeft); + ret = (*memWrite)((const void *)Buffer, Address, BytesLeft); } return ret; } +bool AppCardMemoryUploadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount) { + return AppMemoryUploadXModem( &AppCardMemorySize, &AppCardMemoryWrite, Buffer, Address, ByteCount); +} + +bool AppWorkingMemoryUploadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount) { + return AppMemoryUploadXModem( &AppWorkingMemorySize, &AppWorkingMemoryWrite, Buffer, Address, ByteCount); +} + /* Memory delete/clear operations ***************************************************************************************/ @@ -143,14 +239,34 @@ bool MemoryClearAll(void) { return (flashOK && eepromOK); } -bool AppMemoryClearForSetting(uint8_t SettingNumber) { +bool AppSomeMemoryClearForSetting(uint8_t SettingNumber, uint32_t startAddress, uint32_t ByteCount) { bool ret = false; if( checkSettingNumberConsistency(SettingNumber) ) { - ret = FlashClearRange( getFlashAddressForSetting(SettingNumber, MEMORY_NO_ADDR), getAppMemSizeForSetting(SettingNumber) ); + ret = FlashClearRange( startAddress, ByteCount ); } return ret; } +bool AppMemoryClearForSetting(uint8_t SettingNumber) { + return AppSomeMemoryClearForSetting(SettingNumber, getFlashAddressForSetting(SettingNumber, MEMORY_NO_ADDR), AppMemorySizeForSetting(SettingNumber)); +} + bool AppMemoryClear(void) { return AppMemoryClearForSetting(GlobalSettings.ActiveSetting); } + +bool AppCardMemoryClearForSetting(uint8_t SettingNumber) { + return AppSomeMemoryClearForSetting(SettingNumber, getCardMemFlashAddressForSetting(SettingNumber, MEMORY_NO_ADDR), AppCardMemorySizeForSetting(SettingNumber)); +} + +bool AppWorkingMemoryClearForSetting(uint8_t SettingNumber) { + return AppSomeMemoryClearForSetting(SettingNumber, getWorkingMemFlashAddressForSetting(SettingNumber, MEMORY_NO_ADDR), AppWorkingMemorySizeForSetting(SettingNumber)); +} + +bool AppCardMemoryClear(void) { + return AppCardMemoryClearForSetting(GlobalSettings.ActiveSetting); +} + +bool AppWorkingMemoryClear(void) { + return AppWorkingMemoryClearForSetting(GlobalSettings.ActiveSetting); +} diff --git a/Firmware/ChameleonMini/Memory/Memory.h b/Firmware/ChameleonMini/Memory/Memory.h index 1277dce..0ba7da0 100644 --- a/Firmware/ChameleonMini/Memory/Memory.h +++ b/Firmware/ChameleonMini/Memory/Memory.h @@ -16,47 +16,76 @@ #include "../Application/MifareClassic.h" // Just to define constants #define MEMORY_NO_MEMORY 0x00 +#define MEMORY_ALL_MEMORY 0xFFFFFFFF #define MEMORY_NO_ADDR 0 -#ifdef CONFIG_MF_CLASSIC_4K_SUPPORT +#ifdef CONFIG_MF_CLASSIC_SUPPORT #define MEMORY_MIN_BYTES_PER_APP MFCLASSIC_4K_MEM_SIZE #else -#define MEMORY_MIN_BYTES_PER_APP MFCLASSIC_1K_MEM_SIZE +#define MEMORY_MIN_BYTES_PER_APP 512 #endif +#define MEMORY_MAX_BYTES_PER_CARD_DIVIDER 8 #define MEMORY_MIN_BYTES_PER_SETTING (sizeof(SettingsEntryType)+sizeof(SettingsType)) typedef struct { uint32_t maxFlashBytesPerSlot; + uint32_t maxFlashBytesPerCardMemory; uint16_t maxEEPROMBytesPerSlot; - + bool isMemoryInit; } memoryMappingInfo_t; -memoryMappingInfo_t MemoryMappingInfo; +extern memoryMappingInfo_t MemoryMappingInfo; bool MemoryInit(void); /* +* +* Application/Config/Slot memory is divided in 2 separate spaces: +* - CardMemory to store card emulation data, +* - WorkingMemory to store internal application's data (logs, results, states, etc.). +* * By default all operations are relative to current active setting's application memory * space. * Functions that end with "ForSetting" can be used to operate on a specified setting's * application memory space, regardless of the active setting. * -* We equally divides total SPI Flash memory space for each setting/slot's application -* dedicated memory space. -* But we will actually use setting's configuration required memory only, by default, except -* when full available space is required, either by requiring 0 memory in setting's -* configuration, or by requiring more than total available memory per setting/slot. +* We equally divides total SPI Flash memory space for each slot's application. +* CardMemory max amount is limited by MemoryMappingInfo.maxFlashBytesPerCardMemory. +* WorkingMemory is limited by all available slot's memory +* (MemoryMappingInfo.maxFlashBytesPerSlot) minus CardMemory. +* Memory spaces sizes are set in configuration definition. +* When MEMORY_ALL_MEMORY memory is set for a memory space, or if required memory is more +* than possible, then memory space will be given the maximum memory amount. +* As so, any memory operation should be based on this module memory spaces sizes results, +* and not on configuration constants for memory sizes. */ -bool AppMemoryReadForSetting(uint8_t SettingNumber, void* Buffer, uint32_t Address, uint32_t ByteCount); -bool AppMemoryRead(void* Buffer, uint32_t Address, uint32_t ByteCount); -bool AppMemoryDownloadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount); +uint32_t AppCardMemorySizeForSetting(uint8_t SettingNumber); +uint32_t AppWorkingMemorySizeForSetting(uint8_t SettingNumber); +uint32_t AppMemorySizeForSetting(uint8_t SettingNumber); +uint32_t AppCardMemorySize(void); +uint32_t AppWorkingMemorySize(void); +uint32_t AppMemorySize(void); + +bool AppCardMemoryReadForSetting(uint8_t SettingNumber, void* Buffer, uint32_t Address, uint32_t ByteCount); +bool AppCardMemoryRead(void* Buffer, uint32_t Address, uint32_t ByteCount); +bool AppCardMemoryDownloadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount); +bool AppWorkingMemoryReadForSetting(uint8_t SettingNumber, void* Buffer, uint32_t Address, uint32_t ByteCount); +bool AppWorkingMemoryRead(void* Buffer, uint32_t Address, uint32_t ByteCount); +bool AppWorkingMemoryDownloadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount); -bool AppMemoryWriteForSetting(uint8_t SettingNumber, const void* Buffer, uint32_t Address, uint32_t ByteCount); -bool AppMemoryWrite(const void* Buffer, uint32_t Address, uint32_t ByteCount); -bool AppMemoryUploadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount); +bool AppCardMemoryWriteForSetting(uint8_t SettingNumber, const void* Buffer, uint32_t Address, uint32_t ByteCount); +bool AppCardMemoryWrite(const void* Buffer, uint32_t Address, uint32_t ByteCount); +bool AppCardMemoryUploadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount); +bool AppWorkingMemoryWriteForSetting(uint8_t SettingNumber, const void* Buffer, uint32_t Address, uint32_t ByteCount); +bool AppWorkingMemoryWrite(const void* Buffer, uint32_t Address, uint32_t ByteCount); +bool AppWorkingMemoryUploadXModem(void* Buffer, uint32_t Address, uint32_t ByteCount); bool MemoryClearAll(void); bool AppMemoryClearForSetting(uint8_t SettingNumber); bool AppMemoryClear(void); +bool AppCardMemoryClearForSetting(uint8_t SettingNumber); +bool AppCardMemoryClear(void); +bool AppWorkingMemoryClearForSetting(uint8_t SettingNumber); +bool AppWorkingMemoryClear(void); #endif /* _MEM_MEMORY_H_ */ diff --git a/Firmware/ChameleonMini/Terminal/CommandLine.c b/Firmware/ChameleonMini/Terminal/CommandLine.c index a95eebb..2078ebc 100644 --- a/Firmware/ChameleonMini/Terminal/CommandLine.c +++ b/Firmware/ChameleonMini/Terminal/CommandLine.c @@ -119,6 +119,27 @@ const PROGMEM CommandEntryType CommandTable[] = { .SetFunc = NO_FUNCTION, .GetFunc = CommandGetMemSize }, + { + .Command = COMMAND_WORKMEM, + .ExecFunc = CommandExecWorkingMem, + .ExecParamFunc = NO_FUNCTION, + .SetFunc = NO_FUNCTION, + .GetFunc = CommandGetWorkingMem + }, + { + .Command = COMMAND_WORKMEMUPLOAD, + .ExecFunc = CommandExecWorkingMemUpload, + .ExecParamFunc = NO_FUNCTION, + .SetFunc = NO_FUNCTION, + .GetFunc = NO_FUNCTION + }, + { + .Command = COMMAND_WORKMEMDOWNLOAD, + .ExecFunc = CommandExecWorkingMemDownload, + .ExecParamFunc = NO_FUNCTION, + .SetFunc = NO_FUNCTION, + .GetFunc = NO_FUNCTION + }, { .Command = COMMAND_UIDSIZE, .ExecFunc = NO_FUNCTION, @@ -221,6 +242,7 @@ const PROGMEM CommandEntryType CommandTable[] = { .SetFunc = NO_FUNCTION, .GetFunc = CommandGetRssi }, +#ifdef CONFIG_MF_ULTRALIGHT_SUPPORT { .Command = COMMAND_PWD, .ExecFunc = NO_FUNCTION, @@ -228,6 +250,7 @@ const PROGMEM CommandEntryType CommandTable[] = { .SetFunc = NO_FUNCTION, .GetFunc = CommandGetUltralightPassword }, +#endif /* { .Command = COMMAND_SYSTICK, @@ -300,11 +323,11 @@ const PROGMEM CommandEntryType CommandTable[] = { .GetFunc = CommandGetField }, */ -#ifdef CONFIG_MF_DETECTION_SUPPORT +#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT { .Command = COMMAND_DETECTION, .ExecFunc = NO_FUNCTION, - .SetFunc = CommandSetDetection, + .SetFunc = NO_FUNCTION, .GetFunc = CommandGetDetection, }, #endif diff --git a/Firmware/ChameleonMini/Terminal/Commands.c b/Firmware/ChameleonMini/Terminal/Commands.c index 4f7b5f6..b23e2da 100644 --- a/Firmware/ChameleonMini/Terminal/Commands.c +++ b/Firmware/ChameleonMini/Terminal/Commands.c @@ -217,12 +217,12 @@ CommandStatusIdType CommandSetReadOnly(char* OutMessage, const char* InParam) } CommandStatusIdType CommandExecUpload(char* OutMessage) { - XModemReceive(AppMemoryUploadXModem); + XModemReceive(AppCardMemoryUploadXModem); return COMMAND_INFO_XMODEM_WAIT_ID; } CommandStatusIdType CommandExecDownload(char* OutMessage) { - XModemSend(AppMemoryDownloadXModem); + XModemSend(AppCardMemoryDownloadXModem); return COMMAND_INFO_XMODEM_WAIT_ID; } @@ -243,10 +243,63 @@ CommandStatusIdType CommandExecUpgrade(char* OutMessage) { #endif CommandStatusIdType CommandGetMemSize(char* OutParam) { - snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR("%u"), ActiveConfiguration.MemorySize); + snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR("%lu"), ActiveConfiguration.CardMemorySize); return COMMAND_INFO_OK_WITH_TEXT_ID; } +void _readAndSendWorkingMemChunk(uint32_t Address, uint16_t Size, uint16_t MaxSize, bool isHex) { + if((MaxSize <= TERMINAL_BUFFER_SIZE) && (Size <= MaxSize)) { + uint8_t buff[TERMINAL_BUFFER_SIZE]; + AppWorkingMemoryRead(buff, Address, Size); + if(isHex) { + char hexbuff[TERMINAL_BUFFER_SIZE*2+3]; + uint16_t zeroIndex = Size*2; + BufferToHexString(hexbuff, TERMINAL_BUFFER_SIZE*2+3, buff, Size); + hexbuff[zeroIndex] = '\r'; + hexbuff[zeroIndex+1] = '\n'; + hexbuff[zeroIndex+2] = '\0'; + TerminalSendString(hexbuff); + } else { + TerminalSendBlock(buff, Size); + } + } +} + +uint8_t _readAndSendWorkingMem(uint16_t MaxSize, bool isHex) { + uint8_t ret = COMMAND_ERR_INVALID_USAGE_ID; + uint32_t bytesToWrite = AppWorkingMemorySize(); + if( (MaxSize <= TERMINAL_BUFFER_SIZE) && bytesToWrite ) { + uint32_t rounds = bytesToWrite / MaxSize; + uint16_t offset = bytesToWrite % MaxSize; + for(uint32_t i=0; i < rounds; i++) { + _readAndSendWorkingMemChunk(i*MaxSize, MaxSize, MaxSize, isHex); + } + if(offset) { + _readAndSendWorkingMemChunk(rounds*MaxSize, offset, MaxSize, isHex); + } + ret = (isHex) ? (COMMAND_INFO_OK_WITH_TEXT_ID) : (COMMAND_INFO_OK_ID); + } + return ret; +} + +CommandStatusIdType CommandGetWorkingMem(char* OutParam) { + return _readAndSendWorkingMem(16, true); +} + +CommandStatusIdType CommandExecWorkingMem(char* OutMessage) { + return _readAndSendWorkingMem(TERMINAL_BUFFER_SIZE, false); +} + +CommandStatusIdType CommandExecWorkingMemUpload(char* OutMessage) { + XModemReceive(AppWorkingMemoryUploadXModem); + return COMMAND_INFO_XMODEM_WAIT_ID; +} + +CommandStatusIdType CommandExecWorkingMemDownload(char* OutMessage) { + XModemSend(AppWorkingMemoryDownloadXModem); + return COMMAND_INFO_XMODEM_WAIT_ID; +} + CommandStatusIdType CommandGetUidSize(char* OutParam) { snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR("%u"), ActiveConfiguration.UidSize); return COMMAND_INFO_OK_WITH_TEXT_ID; @@ -349,20 +402,22 @@ CommandStatusIdType CommandGetRssi(char* OutParam) { return COMMAND_INFO_OK_WITH_TEXT_ID; } +#ifdef CONFIG_MF_ULTRALIGHT_SUPPORT CommandStatusIdType CommandGetUltralightPassword(char* OutParam) { - uint8_t pwd[4]; + uint8_t pwd[MIFARE_ULTRALIGHT_PWD_SIZE]; /* Read saved password from authentication */ - AppMemoryRead(pwd, MIFARE_ULTRALIGHT_PWD_ADDRESS, sizeof(pwd)); + AppWorkingMemoryRead(pwd, MIFARE_ULTRALIGHT_PWD_ADDRESS, MIFARE_ULTRALIGHT_PWD_SIZE); snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR("%02x%02x%02x%02x"), pwd[0], pwd[1], pwd[2], pwd[3]); return COMMAND_INFO_OK_WITH_TEXT_ID; } +#endif -#ifdef CONFIG_MF_DETECTION_SUPPORT +#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT CommandStatusIdType CommandGetDetection(char* OutParam) { /* Read UID / s0-b0 */ - AppMemoryRead(OutParam, MFCLASSIC_MEM_S0B0_ADDRESS, DETECTION_MEM_BLOCK0_SIZE); + AppWorkingMemoryRead(OutParam, MFCLASSIC_MEM_S0B0_ADDRESS, DETECTION_MEM_BLOCK0_SIZE); /* Read saved nonce data from authentication */ - AppMemoryRead(OutParam+DETECTION_MEM_BLOCK0_SIZE, DETECTION_MEM_DATA_START_ADDR, DETECTION_MEM_MFKEY_DATA_LEN); + AppWorkingMemoryRead(OutParam+DETECTION_MEM_BLOCK0_SIZE, DETECTION_MEM_DATA_START_ADDR, DETECTION_MEM_MFKEY_DATA_LEN); /* Add file integrity to byte. This adds 2 bytes (209, 210) to DETECTION_MEM_APP_SIZE */ ISO14443AAppendCRCA(OutParam, DETECTION_MEM_APP_SIZE); /* Send data + CRC */ @@ -372,11 +427,6 @@ CommandStatusIdType CommandGetDetection(char* OutParam) { OutParam[0] = 0; return COMMAND_INFO_OK_ID; } - -CommandStatusIdType CommandSetDetection(char* OutMessage, const char* InParam) { - AppMemoryClear(); - return COMMAND_INFO_OK_ID; -} #endif CommandStatusIdType CommandExecClearAll(char* OutMessage) { @@ -387,7 +437,7 @@ CommandStatusIdType CommandExecClearAll(char* OutMessage) { ButtonSetActionById(BUTTON_PRESS_SHORT, DEFAULT_BUTTON_ACTION); ButtonSetActionById(BUTTON_PRESS_LONG, DEFAULT_BUTTON_LONG_ACTION); } - SettingsSetActiveById(SETTINGS_FIRST); + SettingsSetActiveById(DEFAULT_SETTING); SettingsSave(); return COMMAND_INFO_OK_ID; } @@ -395,8 +445,8 @@ CommandStatusIdType CommandExecClearAll(char* OutMessage) { #ifdef CONFIG_DEBUG_MEMORYINFO_COMMAND CommandStatusIdType CommandExecMemoryInfo(char* OutMessage) { snprintf_P( OutMessage, TERMINAL_BUFFER_SIZE, - PSTR("SPI Flash:\r\n- Bytes Per Setting: %lu\r\n- MDID Bytes: %02X%02X%02X%02X\r\n- Memory size: %u Mbits (%u KBytes)\r\nEEPROM:\r\n- Bytes Per Setting: %u\r\n- Memory size: %u Bytes"), - MemoryMappingInfo.maxFlashBytesPerSlot, + PSTR("SPI Flash:\r\n- Bytes Per Setting: %lu\r\n- Bytes Per Card Memory: %lu\r\n- MDID Bytes: %02X%02X%02X%02X\r\n- Memory size: %u Mbits (%u KBytes)\r\nEEPROM:\r\n- Bytes Per Setting: %u\r\n- Memory size: %u Bytes"), + MemoryMappingInfo.maxFlashBytesPerSlot, MemoryMappingInfo.maxFlashBytesPerCardMemory, FlashInfo.manufacturerId, FlashInfo.deviceId1, FlashInfo.deviceId2, FlashInfo.edi, FlashInfo.geometry.sizeMbits, FlashInfo.geometry.sizeKbytes, MemoryMappingInfo.maxEEPROMBytesPerSlot, EEPROMInfo.bytesTotal ); @@ -407,47 +457,75 @@ CommandStatusIdType CommandExecMemoryInfo(char* OutMessage) { #ifdef CONFIG_DEBUG_MEMORYTEST_COMMAND CommandStatusIdType CommandExecMemoryTest(char* OutMessage) { uint8_t bigbuf[128]; - uint8_t readbuf[45]; - uint8_t expected[45]; - HexStringToBuffer(expected, 45, "11111111AA031111111111111111111100FFFFFFFFAA03FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF05"); + uint8_t readbuf[50]; + uint8_t expected[50]; + bool retValFail = false; + bool retValOK = false; + bool tempRetVal = false; + HexStringToBuffer(expected, 50, + "000111FFAA031111111111111111111100FFFFFFFFFF03FFFFFFFFFFFFFFFFFFFF00FFFFFFFFFFFFFFFFFFFF05111111AA02"); memset(bigbuf, 0x11, 128); - memset(readbuf, 0xAA, 45); + memset(readbuf, 0xAA, 50); SettingsSetActiveById(3); - ConfigurationSetById(CONFIG_NONE); + ConfigurationSetById(CONFIG_MF_CLASSIC_1K); + SettingsSave(); + SettingsSetActiveById(2); + ConfigurationSetById(CONFIG_MF_CLASSIC_DETECTION); SettingsSave(); SettingsSetActiveById(0); ConfigurationSetById(CONFIG_MF_CLASSIC_4K); SettingsSave(); - AppMemoryWriteForSetting(3, bigbuf, 0, 512); + tempRetVal = AppCardMemoryWriteForSetting(3, bigbuf, 0, 128); + retValOK = tempRetVal; for(uint8_t i = 0; i < 32; i++){ - AppMemoryWrite(bigbuf, i*128, 128); + tempRetVal = AppCardMemoryWrite(bigbuf, i*128, 128); + retValOK = (retValOK && tempRetVal); } - FlashUnbufferedBytesRead(readbuf, 3*MemoryMappingInfo.maxFlashBytesPerSlot, 4); - AppMemoryReadForSetting(3, readbuf+4, 250, 1); + tempRetVal = FlashUnbufferedBytesRead(readbuf+2, 3*MemoryMappingInfo.maxFlashBytesPerSlot, 1); + retValOK = (retValOK && tempRetVal); + tempRetVal = AppCardMemoryReadForSetting(3, readbuf+3, 128, 1); + retValOK = (retValOK && tempRetVal); + tempRetVal = AppCardMemoryReadForSetting(3, readbuf, MFCLASSIC_1K_MEM_SIZE, 4); + retValFail = tempRetVal; + tempRetVal = AppWorkingMemoryReadForSetting(3, readbuf, 0, 1); + retValFail = (retValFail || tempRetVal); readbuf[5] = 0x03; - FlashUnbufferedBytesRead(readbuf+6, 1024, 1); - FlashUnbufferedBytesRead(readbuf+7, 3118, 2); - AppMemoryRead(readbuf+9, 2046, 3); - AppMemoryRead(readbuf+12, 12, 4); + tempRetVal = FlashUnbufferedBytesRead(readbuf+6, 1024, 1); + retValOK = (retValOK && tempRetVal); + tempRetVal = FlashUnbufferedBytesRead(readbuf+7, 3118, 2); + retValOK = (retValOK && tempRetVal); + tempRetVal = AppCardMemoryRead(readbuf+9, 2046, 3); + retValOK = (retValOK && tempRetVal); + tempRetVal = AppCardMemoryRead(readbuf+12, 12, 4); + retValOK = (retValOK && tempRetVal); readbuf[16] = 0x00; - FlashClearRange(3*MemoryMappingInfo.maxFlashBytesPerSlot, 16); - AppMemoryClear(); + tempRetVal = FlashClearRange(3*MemoryMappingInfo.maxFlashBytesPerSlot, 16); + retValOK = (retValOK && tempRetVal); + tempRetVal = AppMemoryClear(); + retValOK = (retValOK && tempRetVal); FlashUnbufferedBytesRead(readbuf+17, 3*MemoryMappingInfo.maxFlashBytesPerSlot, 4); - AppMemoryReadForSetting(3, readbuf+21, 250, 1); + AppCardMemoryReadForSetting(3, readbuf+21, 128, 1); readbuf[22] = 0x03; FlashUnbufferedBytesRead(readbuf+23, 1024, 1); FlashUnbufferedBytesRead(readbuf+24, 3118, 2); - AppMemoryRead(readbuf+26, 2046, 3); - AppMemoryRead(readbuf+29, 12, 4); + AppCardMemoryRead(readbuf+26, 2046, 3); + AppCardMemoryRead(readbuf+29, 12, 4); readbuf[33] = 0x00; FlashUnbufferedBytesRead(readbuf+34, 5*MemoryMappingInfo.maxFlashBytesPerSlot+11, 10); readbuf[44] = 0x05; - FlashClearAll(); + tempRetVal = AppWorkingMemoryWriteForSetting(2, bigbuf, 0, 16); + retValOK = (retValOK && tempRetVal); + tempRetVal = AppWorkingMemoryReadForSetting(2, readbuf+45, 5, 3); + retValOK = (retValOK && tempRetVal); + readbuf[49] = 0x02; + readbuf[0] = retValFail; + readbuf[1] = retValOK; + MemoryClearAll(); - if(memcmp(readbuf, expected, 45)) { - BufferToHexString(OutMessage, TERMINAL_BUFFER_SIZE, readbuf, 45); + if(memcmp(readbuf, expected, 50)) { + BufferToHexString(OutMessage, TERMINAL_BUFFER_SIZE, readbuf, 50); } else { snprintf_P(OutMessage, TERMINAL_BUFFER_SIZE, PSTR("FINE"), NULL); } diff --git a/Firmware/ChameleonMini/Terminal/Commands.h b/Firmware/ChameleonMini/Terminal/Commands.h index 8320e8c..b39285f 100644 --- a/Firmware/ChameleonMini/Terminal/Commands.h +++ b/Firmware/ChameleonMini/Terminal/Commands.h @@ -1,4 +1,4 @@ -/* Copyright 2013 Timo Kasper, Simon Küppers, David Oswald ("ORIGINAL +/* Copyright 2013 Timo Kasper, Simon KŸppers, David Oswald ("ORIGINAL * AUTHORS"). All rights reserved. * * DEFINITIONS: @@ -110,95 +110,106 @@ typedef struct { CommandGetFuncType GetFunc; } CommandEntryType; -#define COMMAND_VERSION "VERSION" +#define COMMAND_VERSION "VERSION" CommandStatusIdType CommandGetVersion(char* OutParam); -#define COMMAND_CONFIG "CONFIG" +#define COMMAND_CONFIG "CONFIG" CommandStatusIdType CommandExecConfig(char* OutMessage); CommandStatusIdType CommandGetConfig(char* OutParam); CommandStatusIdType CommandSetConfig(char* OutMessage, const char* InParam); -#define COMMAND_UID "UID" -#define COMMAND_UID_RANDOM "RANDOM" +#define COMMAND_UID "UID" +#define COMMAND_UID_RANDOM "RANDOM" CommandStatusIdType CommandGetUid(char* OutParam); CommandStatusIdType CommandSetUid(char* OutMessage, const char* InParam); -#define COMMAND_ATQA "ATQA" +#define COMMAND_ATQA "ATQA" CommandStatusIdType CommandGetAtqa(char* OutParam); CommandStatusIdType CommandSetAtqa(char* OutMessage, const char* InParam); -#define COMMAND_SAK "SAK" +#define COMMAND_SAK "SAK" CommandStatusIdType CommandGetSak(char* OutParam); CommandStatusIdType CommandSetSak(char* OutMessage, const char* InParam); -#define COMMAND_READONLY "READONLY" +#define COMMAND_READONLY "READONLY" CommandStatusIdType CommandGetReadOnly(char* OutParam); CommandStatusIdType CommandSetReadOnly(char* OutMessage, const char* InParam); -#define COMMAND_UPLOAD "UPLOAD" +#define COMMAND_UPLOAD "UPLOAD" CommandStatusIdType CommandExecUpload(char* OutMessage); -#define COMMAND_DOWNLOAD "DOWNLOAD" +#define COMMAND_DOWNLOAD "DOWNLOAD" CommandStatusIdType CommandExecDownload(char* OutMessage); -#define COMMAND_RESET "RESET" +#define COMMAND_RESET "RESET" CommandStatusIdType CommandExecReset(char* OutMessage); -#define COMMAND_UPGRADE "UPGRADE" +#define COMMAND_UPGRADE "UPGRADE" CommandStatusIdType CommandExecUpgrade(char* OutMessage); -#define COMMAND_MEMSIZE "MEMSIZE" +#define COMMAND_MEMSIZE "MEMSIZE" CommandStatusIdType CommandGetMemSize(char* OutParam); -#define COMMAND_UIDSIZE "UIDSIZE" +#define COMMAND_WORKMEM "WORKMEM" +CommandStatusIdType CommandGetWorkingMem(char* OutParam); +CommandStatusIdType CommandExecWorkingMem(char* OutMessage); + +#define COMMAND_WORKMEMUPLOAD "WORKMEMUPLOAD" +CommandStatusIdType CommandExecWorkingMemUpload(char* OutMessage); + +#define COMMAND_WORKMEMDOWNLOAD "WORKMEMDOWNLOAD" +CommandStatusIdType CommandExecWorkingMemDownload(char* OutMessage); + +#define COMMAND_UIDSIZE "UIDSIZE" CommandStatusIdType CommandGetUidSize(char* OutParam); -#define COMMAND_BUTTON "BUTTON" +#define COMMAND_BUTTON "BUTTON" CommandStatusIdType CommandExecButton(char* OutMessage); CommandStatusIdType CommandGetButton(char* OutParam); CommandStatusIdType CommandSetButton(char* OutMessage, const char* InParam); -#define COMMAND_BUTTON_LONG "BUTTON_LONG" +#define COMMAND_BUTTON_LONG "BUTTON_LONG" CommandStatusIdType CommandExecButtonLong(char* OutMessage); CommandStatusIdType CommandGetButtonLong(char* OutParam); CommandStatusIdType CommandSetButtonLong(char* OutMessage, const char* InParam); -#define COMMAND_SETTING "SETTING" +#define COMMAND_SETTING "SETTING" CommandStatusIdType CommandGetSetting(char* OutParam); CommandStatusIdType CommandSetSetting(char* OutMessage, const char* InParam); -#define COMMAND_CLEAR "CLEAR" +#define COMMAND_CLEAR "CLEAR" CommandStatusIdType CommandExecClear(char* OutParam); -#define COMMAND_HELP "HELP" +#define COMMAND_HELP "HELP" CommandStatusIdType CommandExecHelp(char* OutMessage); -#define COMMAND_RSSI "RSSI" +#define COMMAND_RSSI "RSSI" CommandStatusIdType CommandGetRssi(char* OutParam); -#define COMMAND_PWD "PWD" +#ifdef CONFIG_MF_ULTRALIGHT_SUPPORT +#define COMMAND_PWD "PWD" CommandStatusIdType CommandGetUltralightPassword(char* OutParam); +#endif -#ifdef CONFIG_MF_DETECTION_SUPPORT -#define COMMAND_DETECTION "DETECTION" +#ifdef CONFIG_MF_CLASSIC_DETECTION_SUPPORT +#define COMMAND_DETECTION "DETECTION" CommandStatusIdType CommandGetDetection(char* OutParam); -CommandStatusIdType CommandSetDetection(char* OutMessage, const char* InParam); #endif -#define COMMAND_CLEARALL "CLEARALL" +#define COMMAND_CLEARALL "CLEARALL" CommandStatusIdType CommandExecClearAll(char* OutMessage); #ifdef CONFIG_DEBUG_MEMORYINFO_COMMAND -#define COMMAND_MEMORYINFO "MEMORYINFO" +#define COMMAND_MEMORYINFO "MEMORYINFO" CommandStatusIdType CommandExecMemoryInfo(char* OutMessage); #endif #ifdef CONFIG_DEBUG_MEMORYTEST_COMMAND -#define COMMAND_MEMORYTEST "MEMORYTEST" +#define COMMAND_MEMORYTEST "MEMORYTEST" CommandStatusIdType CommandExecMemoryTest(char* OutMessage); #endif -#define COMMAND_LIST_END "" +#define COMMAND_LIST_END "" /* Defines the end of command list. This is no actual command */