Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mifare DESFire tag emulation support #287

Merged
merged 10 commits into from
Oct 19, 2020
Prev Previous commit
Next Next commit
The remainder of the changes to the source code made during the DESFi…
…re mod development
  • Loading branch information
maxieds committed Oct 17, 2020
commit d1829c5f0e84819d5ebb9d299025af6d25e8bce6
10 changes: 9 additions & 1 deletion Firmware/Chameleon-Mini/AntennaLevel.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#include "AntennaLevel.h"
#include "LEDHook.h"
#include "Log.h"
#include "Application/Application.h"

#define FIELD_MIN_RSSI 500
uint8_t AntennaLevelLogReaderDetectCount = 0;

void AntennaLevelTick(void) {
uint16_t rssi = AntennaLevelGet();
Expand All @@ -13,5 +14,12 @@ void AntennaLevelTick(void) {
ApplicationReset(); // reset the application just like a real card gets reset when there is no field
} else {
LEDHook(LED_FIELD_DETECTED, LED_ON);
AntennaLevelLogReaderDetectCount = (++AntennaLevelLogReaderDetectCount) % ANTENNA_LEVEL_LOG_RDRDETECT_INTERVAL;
if(AntennaLevelLogReaderDetectCount == 0) {
uint8_t antLevel[2];
antLevel[0] = (uint8_t) ((rssi >> 8) & 0x00ff);
antLevel[1] = (uint8_t) (rssi & 0x00ff);
LogEntry(LOG_INFO_CODEC_READER_FIELD_DETECTED, antLevel, 2);
}
}
}
5 changes: 5 additions & 0 deletions Firmware/Chameleon-Mini/AntennaLevel.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
#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_LOG_RDRDETECT_INTERVAL (15)
extern uint8_t AntennaLevelLogReaderDetectCount;

#define FIELD_MIN_RSSI 500

static inline
void AntennaLevelInit(void) {
ADCA.CTRLA = ADC_ENABLE_bm;
Expand Down
62 changes: 44 additions & 18 deletions Firmware/Chameleon-Mini/Application/Crypto1.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,20 @@
}))
#endif

#ifdef DESFIRE_CRYPTO1_SAVE_SPACE
#define C1MEM PROGMEM
#else
#define C1MEM
#endif

/* Space/speed tradoff. */
/* We want speed, so we have to pay with size. */
/* If we combine the A und B Filtertables and precalculate the values */
/* for each state byte, we get the following tables which gives a */
/* faster calculation of the filter output */
/* Table of the filter A/B output per byte */
static const uint8_t abFilterTable[3][256] = {
#define AB_FILTER_TABLE_ENTRY_SIZE (256)
static const uint8_t C1MEM abFilterTable[3][AB_FILTER_TABLE_ENTRY_SIZE] = {
/* for Odd[0] */
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Expand Down Expand Up @@ -277,7 +284,7 @@ static const uint8_t abFilterTable[3][256] = {
};

/* Standard FC table, feedback at bit 0 */
static const uint8_t TableC0[32] = {
static const uint8_t C1MEM TableC0[32] = {
/* fc with Input {4,3,2,1,0} = (0,0,0,0,0) to (1,1,1,1,1) */
FC(0, 0, 0, 0, 0), FC(0, 0, 0, 0, 1), FC(0, 0, 0, 1, 0), FC(0, 0, 0, 1, 1),
FC(0, 0, 1, 0, 0), FC(0, 0, 1, 0, 1), FC(0, 0, 1, 1, 0), FC(0, 0, 1, 1, 1),
Expand All @@ -290,7 +297,7 @@ static const uint8_t TableC0[32] = {
};

/* Special table for byte processing, feedback at bit 7 */
static const uint8_t TableC7[32] = {
static const uint8_t C1MEM TableC7[32] = {
/* fc with Input {4,3,2,1,0} = (0,0,0,0,0) to (1,1,1,1,1) */
FC(0, 0, 0, 0, 0) << 7, FC(0, 0, 0, 0, 1) << 7, FC(0, 0, 0, 1, 0) << 7, FC(0, 0, 0, 1, 1) << 7,
FC(0, 0, 1, 0, 0) << 7, FC(0, 0, 1, 0, 1) << 7, FC(0, 0, 1, 1, 0) << 7, FC(0, 0, 1, 1, 1) << 7,
Expand All @@ -303,7 +310,7 @@ static const uint8_t TableC7[32] = {
};

/* Special table for nibble processing (e.g. ack), feedback at bit 3 */
static const uint8_t TableC3[32] = {
static const uint8_t C1MEM TableC3[32] = {
/* fc with Input {4,3,2,1,0} = (0,0,0,0,0) to (1,1,1,1,1) */
FC(0, 0, 0, 0, 0) << 3, FC(0, 0, 0, 0, 1) << 3, FC(0, 0, 0, 1, 0) << 3, FC(0, 0, 0, 1, 1) << 3,
FC(0, 0, 1, 0, 0) << 3, FC(0, 0, 1, 0, 1) << 3, FC(0, 0, 1, 1, 0) << 3, FC(0, 0, 1, 1, 1) << 3,
Expand All @@ -316,20 +323,39 @@ static const uint8_t TableC3[32] = {
};

/* Filter Output Macros */
/* Output at bit 7 for optimized byte processing */
#define CRYPTO1_FILTER_OUTPUT_B7_24(__O0, __O1, __O2) TableC7[ abFilterTable[0][__O0] | \
abFilterTable[1][__O1] | \
abFilterTable[2][__O2]]

/* Output at bit 3 for optimized nibble processing */
#define CRYPTO1_FILTER_OUTPUT_B3_24(__O0, __O1, __O2) TableC3[ abFilterTable[0][__O0] | \
abFilterTable[1][__O1] | \
abFilterTable[2][__O2]]

/* Output at bit 0 for general purpose */
#define CRYPTO1_FILTER_OUTPUT_B0_24(__O0, __O1, __O2) TableC0[ abFilterTable[0][__O0] | \
abFilterTable[1][__O1] | \
abFilterTable[2][__O2]]
#ifdef DESFIRE_CRYPTO1_SAVE_SPACE
#define CRYPTO1_FILTER_OUTPUT_B0_24(__O0, __O1, __O2) \
pgm_read_byte(TableC0 + \
(pgm_read_byte(abFilterTable + __O0) | \
pgm_read_byte(abFilterTable + AB_FILTER_TABLE_ENTRY_SIZE + __O1) | \
pgm_read_byte(abFilterTable + 2 * AB_FILTER_TABLE_ENTRY_SIZE + __O2)) \
)
#define CRYPTO1_FILTER_OUTPUT_B3_24(__O0, __O1, __O2) \
pgm_read_byte(TableC3 + \
(pgm_read_byte(abFilterTable + __O0) | \
pgm_read_byte(abFilterTable + AB_FILTER_TABLE_ENTRY_SIZE + __O1) | \
pgm_read_byte(abFilterTable + 2 * AB_FILTER_TABLE_ENTRY_SIZE + __O2)) \
)
#define CRYPTO1_FILTER_OUTPUT_B7_24(__O0, __O1, __O2) \
pgm_read_byte(TableC7 + \
(pgm_read_byte(abFilterTable + __O0) | \
pgm_read_byte(abFilterTable + AB_FILTER_TABLE_ENTRY_SIZE + __O1) | \
pgm_read_byte(abFilterTable + 2 * AB_FILTER_TABLE_ENTRY_SIZE + __O2)) \
)
#else
/* Output at bit 0 for general purpose */
#define CRYPTO1_FILTER_OUTPUT_B0_24(__O0, __O1, __O2) TableC0[ abFilterTable[0][__O0] | \
abFilterTable[1][__O1] | \
abFilterTable[2][__O2]]
/* Output at bit 7 for optimized byte processing */
#define CRYPTO1_FILTER_OUTPUT_B7_24(__O0, __O1, __O2) TableC7[ abFilterTable[0][__O0] | \
abFilterTable[1][__O1] | \
abFilterTable[2][__O2]]
/* Output at bit 3 for optimized nibble processing */
#define CRYPTO1_FILTER_OUTPUT_B3_24(__O0, __O1, __O2) TableC3[ abFilterTable[0][__O0] | \
abFilterTable[1][__O1] | \
abFilterTable[2][__O2]]
#endif

/* Split Crypto1 state into even and odd bits */
/* to speed up the output filter network */
Expand Down
3 changes: 2 additions & 1 deletion Firmware/Chameleon-Mini/Chameleon-Mini.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ int main(void) {

while (1) {
if (SystemTick100ms()) {
LEDTick(); // this has to be the first function called here, since it is time-critical - the functions below may have non-negligible runtimes!
LEDTick(); // this has to be the first function called here, since it is time-critical -
// the functions below may have non-negligible runtimes!
PinTick();
RandomTick();
TerminalTick();
Expand Down
4 changes: 4 additions & 0 deletions Firmware/Chameleon-Mini/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
#define INLINE \
static inline __attribute__((always_inline))

#ifndef STRINGIFY
#define STRINGIFY(x) #x
#endif

#define ARRAY_COUNT(x) \
(sizeof(x) / sizeof(x[0]))

Expand Down
15 changes: 14 additions & 1 deletion Firmware/Chameleon-Mini/Configuration.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
* Author: skuser
*/

#include <avr/pgmspace.h>

#include "Configuration.h"
#include "Settings.h"
#include <avr/pgmspace.h>
#include "Map.h"
#include "AntennaLevel.h"
#include "LEDHook.h"

#ifdef CONFIG_MF_DESFIRE_SUPPORT
#include "Application/MifareDESFire.h"
Expand Down Expand Up @@ -441,12 +443,23 @@ void ConfigurationSetById(ConfigurationEnum Configuration) {

CodecInit();
ApplicationInit();

/* Notify LED. blink according to current setting */
LEDHook(LED_SETTING_CHANGE, LED_BLINK + Configuration);
}

void ConfigurationGetByName(char *Configuration, uint16_t BufferSize) {
MapIdToText(ConfigurationMap, ARRAY_COUNT(ConfigurationMap), GlobalSettings.ActiveSettingPtr->Configuration, Configuration, BufferSize);
}

MapIdType ConfigurationCheckByName(const char *Configuration) {
MapIdType Id;
if (MapTextToId(ConfigurationMap, ARRAY_COUNT(ConfigurationMap), Configuration, &Id)) {
return Id;
}
return 0xff;
}

bool ConfigurationSetByName(const char *Configuration) {
MapIdType Id;

Expand Down
3 changes: 3 additions & 0 deletions Firmware/Chameleon-Mini/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include <stdint.h>
#include <stdbool.h>

#include "Map.h"

#define CONFIGURATION_NAME_LENGTH_MAX 32
#define CONFIGURATION_UID_SIZE_MAX 16

Expand Down Expand Up @@ -167,6 +169,7 @@ extern ConfigurationType ActiveConfiguration;

void ConfigurationInit(void);
void ConfigurationSetById(ConfigurationEnum Configuration);
MapIdType ConfigurationCheckByName(const char *Configuration);
void ConfigurationGetByName(char *Configuration, uint16_t BufferSize);
bool ConfigurationSetByName(const char *Configuration);
void ConfigurationGetList(char *ConfigurationList, uint16_t BufferSize);
Expand Down
1 change: 1 addition & 0 deletions Firmware/Chameleon-Mini/Log.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ typedef enum {
LOG_INFO_CODEC_SNI_READER_DATA_W_PARITY = 0x45, //< Sniffing codec receive data from reader
LOG_INFO_CODEC_SNI_CARD_DATA = 0x46, //< Sniffing codec receive data from card
LOG_INFO_CODEC_SNI_CARD_DATA_W_PARITY = 0x47, //< Sniffing codec receive data from card
LOG_INFO_CODEC_READER_FIELD_DETECTED = 0x48, ///< Add logging of the LEDHook case for FIELD_DETECTED

/* App */
LOG_INFO_APP_CMD_READ = 0x80, ///< Application processed read command.
Expand Down
1 change: 0 additions & 1 deletion Firmware/Chameleon-Mini/Memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ void MemoryWriteBlock(const void* Buffer, uint16_t Address, uint16_t ByteCount);
void MemoryWriteBlockInSetting(const void* Buffer, uint16_t Address, uint16_t ByteCount);
void MemoryClear(void);


void MemoryRecall(void);
void MemoryStore(void);

Expand Down
9 changes: 6 additions & 3 deletions Firmware/Chameleon-Mini/Random.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#include "Random.h"

#include <stdlib.h>

void RandomInit(void) {
#include "Random.h"
#include "System.h"

void RandomInit(void) {
uint32_t randomSeed = (uint32_t) ((uint32_t) (SystemGetSysTick() + 768) |
((uint32_t) (SystemGetSysTick() % 512) << 20));
srand(randomSeed);
}

uint8_t RandomGetByte(void) {
Expand Down
1 change: 0 additions & 1 deletion Firmware/Chameleon-Mini/Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ INLINE void SettingUpdate(const void *addr, uint16_t size) {
default:
eeprom_update_block((uint8_t *)addr, (uint8_t *)EEAddr, size);
}

#endif
}

Expand Down
11 changes: 8 additions & 3 deletions Firmware/Chameleon-Mini/Terminal/Commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ extern Sniff14443Command Sniff14443CurrentCommand;
extern const PROGMEM CommandEntryType CommandTable[];

CommandStatusIdType CommandGetVersion(char *OutParam) {
snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR(
"ChameleonMini RevG %S using LUFA %S compiled with AVR-GCC %S. Based on the open-source NFC tool ChameleonMini. https://github.com/emsec/ChameleonMini commit %S"
), PSTR(CHAMELEON_MINI_VERSION_STRING), PSTR(LUFA_VERSION_STRING), PSTR(__VERSION__), PSTR(COMMIT_ID)
snprintf_P(OutParam, TERMINAL_BUFFER_SIZE,
PSTR(
"ChameleonMini RevG %S using LUFA %S compiled with AVR-GCC %S. "
"Based on the open-source NFC tool ChameleonMini. "
"https://github.com/emsec/ChameleonMini commit %S"
), PSTR(CHAMELEON_MINI_VERSION_STRING), PSTR(LUFA_VERSION_STRING), PSTR(__VERSION__), PSTR(COMMIT_ID)
);

return COMMAND_INFO_OK_WITH_TEXT_ID;
Expand All @@ -42,6 +45,8 @@ CommandStatusIdType CommandSetConfig(char *OutMessage, const char *InParam) {
ConfigurationGetList(OutMessage, TERMINAL_BUFFER_SIZE);
return COMMAND_INFO_OK_WITH_TEXT_ID;
} else if (ConfigurationSetByName(InParam)) {
MemoryClear();
ConfigurationSetByName(InParam);
SETTING_UPDATE(GlobalSettings.ActiveSettingPtr->Configuration);
return COMMAND_INFO_OK_ID;
} else {
Expand Down
1 change: 1 addition & 0 deletions Firmware/Chameleon-Mini/Terminal/Terminal.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ void TerminalTick(void);

/*void TerminalSendHex(void* Buffer, uint16_t ByteCount);*/
INLINE void TerminalSendByte(uint8_t Byte);
INLINE void TerminalFlushBuffer(void);
void TerminalSendBlock(const void *Buffer, uint16_t ByteCount);

INLINE void TerminalSendChar(char c);
Expand Down