Skip to content

Commit

Permalink
Merge pull request emsec#41 from luminouw/feature/custom_atqa_sak
Browse files Browse the repository at this point in the history
Added ATQA and SAK commands, ported from RevE firmware
  • Loading branch information
iceman1001 authored Sep 17, 2020
2 parents d4a7926 + 7055e26 commit 7f310af
Show file tree
Hide file tree
Showing 10 changed files with 226 additions and 2 deletions.
16 changes: 16 additions & 0 deletions Firmware/Chameleon-Mini/Application/Application.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,20 @@ INLINE void ApplicationSetUid(ConfigurationUidType Uid) {
LogEntry(LOG_INFO_UID_SET, Uid, ActiveConfiguration.UidSize);
}

INLINE void ApplicationGetSak(uint8_t * Sak) {
ActiveConfiguration.ApplicationGetSakFunc(Sak);
}

INLINE void ApplicationSetSak(uint8_t Sak) {
ActiveConfiguration.ApplicationSetSakFunc(Sak);
}

INLINE void ApplicationGetAtqa(uint16_t * Atqa) {
ActiveConfiguration.ApplicationGetAtqaFunc(Atqa);
}

INLINE void ApplicationSetAtqa(uint16_t Atqa) {
ActiveConfiguration.ApplicationSetAtqaFunc(Atqa);
}

#endif /* APPLICATION_H_ */
16 changes: 16 additions & 0 deletions Firmware/Chameleon-Mini/Application/MifareClassic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1298,3 +1298,19 @@ void MifareClassicSetUid(ConfigurationUidType Uid) {
MemoryWriteBlock(&BCC, MEM_UID_BCC1_ADDRESS, ISO14443A_CL_BCC_SIZE);
}
}

void MifareClassicGetAtqa(uint16_t * Atqa) {
*Atqa = CardATQAValue;
}

void MifareClassicSetAtqa(uint16_t Atqa) {
CardATQAValue = Atqa;
}

void MifareClassicGetSak(uint8_t * Sak) {
*Sak = CardSAKValue;
}

void MifareClassicSetSak(uint8_t Sak) {
CardSAKValue = Sak;
}
4 changes: 4 additions & 0 deletions Firmware/Chameleon-Mini/Application/MifareClassic.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,9 @@ uint16_t MifareClassicAppProcess(uint8_t *Buffer, uint16_t BitCount);
void MifareClassicGetUid(ConfigurationUidType Uid);
void MifareClassicSetUid(ConfigurationUidType Uid);

void MifareClassicGetAtqa(uint16_t * Atqa);
void MifareClassicSetAtqa(uint16_t Atqa);
void MifareClassicGetSak(uint8_t * Sak);
void MifareClassicSetSak(uint8_t Sak);

#endif /* MIFARECLASSIC_H_ */
23 changes: 23 additions & 0 deletions Firmware/Chameleon-Mini/Application/MifareUltralight.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ static uint8_t CompatWritePageAddress;
static bool Authenticated;
static uint8_t FirstAuthenticatedPage;
static bool ReadAccessProtected;
static uint16_t CardATQAValue;
static uint8_t CardSAKValue;
static uint8_t RNDBBuff [8];
static uint8_t InitialVector[8] = {0};
static uint8_t TripleDesKey [16];
Expand Down Expand Up @@ -153,6 +155,8 @@ static void AppInitCommon(void) {
FromHalt = false;
Authenticated = false;
ArmedForCompatWrite = false;
CardATQAValue = ATQA_VALUE;
CardSAKValue = SAK_CL1_VALUE;
}
void MifareUltralightCAppInit(void) {
Flavor = UL_C;
Expand Down Expand Up @@ -673,3 +677,22 @@ void MifareUltralightSetUid(ConfigurationUidType Uid) {
MemoryWriteBlock(&BCC2, UID_BCC2_ADDRESS, ISO14443A_CL_BCC_SIZE);
}

void MifareUltralightGetAtqa(uint16_t * Atqa)
{
*Atqa = CardATQAValue;
}

void MifareUltralightSetAtqa(uint16_t Atqa)
{
CardATQAValue = Atqa;
}

void MifareUltralightGetSak(uint8_t * Sak)
{
*Sak = CardSAKValue;
}

void MifareUltralightSetSak(uint8_t Sak)
{
CardSAKValue = Sak;
}
5 changes: 4 additions & 1 deletion Firmware/Chameleon-Mini/Application/MifareUltralight.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ uint16_t MifareUltralightAppProcess(uint8_t *Buffer, uint16_t BitCount);
void MifareUltralightGetUid(ConfigurationUidType Uid);
void MifareUltralightSetUid(ConfigurationUidType Uid);


void MifareUltralightGetAtqa(uint16_t * Atqa);
void MifareUltralightSetAtqa(uint16_t Atqa);
void MifareUltralightGetSak(uint8_t * Sak);
void MifareUltralightSetSak(uint8_t Sak);

#endif /* MIFAREULTRALIGHT_H_ */
61 changes: 60 additions & 1 deletion Firmware/Chameleon-Mini/Configuration.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ static void ApplicationTickDummy(void) {}
static uint16_t ApplicationProcessDummy(uint8_t *ByteBuffer, uint16_t ByteCount) { return 0; }
static void ApplicationGetUidDummy(ConfigurationUidType Uid) { }
static void ApplicationSetUidDummy(ConfigurationUidType Uid) { }

static void ApplicationGetAtqaDummy(uint16_t * Atqa) { *Atqa = CONFIGURATION_DUMMY_ATQA; }
static void ApplicationSetAtqaDummy(uint16_t Atqa) { }
static void ApplicationGetSakDummy(uint8_t * Sak) { *Sak = CONFIGURATION_DUMMY_SAK; }
static void ApplicationSetSakDummy(uint8_t Sak) { }

static const PROGMEM ConfigurationType ConfigurationTable[] = {
[CONFIG_NONE] = {
Expand All @@ -96,6 +99,10 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationProcessFunc = ApplicationProcessDummy,
.ApplicationGetUidFunc = ApplicationGetUidDummy,
.ApplicationSetUidFunc = ApplicationSetUidDummy,
.ApplicationGetSakFunc = ApplicationGetSakDummy,
.ApplicationSetSakFunc = ApplicationSetSakDummy,
.ApplicationGetAtqaFunc = ApplicationGetAtqaDummy,
.ApplicationSetAtqaFunc = ApplicationSetAtqaDummy,
.UidSize = 0,
.MemorySize = 0,
.ReadOnly = true,
Expand All @@ -113,6 +120,10 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationProcessFunc = MifareUltralightAppProcess,
.ApplicationGetUidFunc = MifareUltralightGetUid,
.ApplicationSetUidFunc = MifareUltralightSetUid,
.ApplicationGetSakFunc = MifareUltralightGetSak,
.ApplicationSetSakFunc = MifareUltralightSetSak,
.ApplicationGetAtqaFunc = MifareUltralightGetAtqa,
.ApplicationSetAtqaFunc = MifareUltralightSetAtqa,
.UidSize = MIFARE_ULTRALIGHT_UID_SIZE,
.MemorySize = MIFARE_ULTRALIGHT_MEM_SIZE,
.ReadOnly = false,
Expand All @@ -129,6 +140,10 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationProcessFunc = MifareUltralightAppProcess,
.ApplicationGetUidFunc = MifareUltralightGetUid,
.ApplicationSetUidFunc = MifareUltralightSetUid,
.ApplicationGetSakFunc = MifareUltralightGetSak,
.ApplicationSetSakFunc = MifareUltralightSetSak,
.ApplicationGetAtqaFunc = MifareUltralightGetAtqa,
.ApplicationSetAtqaFunc = MifareUltralightSetAtqa,
.UidSize = MIFARE_ULTRALIGHT_UID_SIZE,
.MemorySize = MIFARE_ULTRALIGHTC_MEM_SIZE,
.ReadOnly = false,
Expand All @@ -145,6 +160,10 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationProcessFunc = MifareUltralightAppProcess,
.ApplicationGetUidFunc = MifareUltralightGetUid,
.ApplicationSetUidFunc = MifareUltralightSetUid,
.ApplicationGetSakFunc = MifareUltralightGetSak,
.ApplicationSetSakFunc = MifareUltralightSetSak,
.ApplicationGetAtqaFunc = MifareUltralightGetAtqa,
.ApplicationSetAtqaFunc = MifareUltralightSetAtqa,
.UidSize = MIFARE_ULTRALIGHT_UID_SIZE,
.MemorySize = MIFARE_ULTRALIGHT_EV11_MEM_SIZE,
.ReadOnly = false,
Expand All @@ -161,6 +180,10 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationProcessFunc = MifareUltralightAppProcess,
.ApplicationGetUidFunc = MifareUltralightGetUid,
.ApplicationSetUidFunc = MifareUltralightSetUid,
.ApplicationGetSakFunc = MifareUltralightGetSak,
.ApplicationSetSakFunc = MifareUltralightSetSak,
.ApplicationGetAtqaFunc = MifareUltralightGetAtqa,
.ApplicationSetAtqaFunc = MifareUltralightSetAtqa,
.UidSize = MIFARE_ULTRALIGHT_UID_SIZE,
.MemorySize = MIFARE_ULTRALIGHT_EV12_MEM_SIZE,
.ReadOnly = false,
Expand All @@ -179,6 +202,10 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationProcessFunc = MifareClassicAppProcess,
.ApplicationGetUidFunc = MifareClassicGetUid,
.ApplicationSetUidFunc = MifareClassicSetUid,
.ApplicationGetSakFunc = MifareClassicGetSak,
.ApplicationSetSakFunc = MifareClassicSetSak,
.ApplicationGetAtqaFunc = MifareClassicGetAtqa,
.ApplicationSetAtqaFunc = MifareClassicSetAtqa,
.UidSize = MIFARE_CLASSIC_UID_SIZE,
.MemorySize = MIFARE_CLASSIC_MINI_MEM_SIZE,
.ReadOnly = false,
Expand All @@ -197,6 +224,10 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationProcessFunc = MifareClassicAppProcess,
.ApplicationGetUidFunc = MifareClassicGetUid,
.ApplicationSetUidFunc = MifareClassicSetUid,
.ApplicationGetSakFunc = MifareClassicGetSak,
.ApplicationSetSakFunc = MifareClassicSetSak,
.ApplicationGetAtqaFunc = MifareClassicGetAtqa,
.ApplicationSetAtqaFunc = MifareClassicSetAtqa,
.UidSize = MIFARE_CLASSIC_UID_SIZE,
.MemorySize = MIFARE_CLASSIC_1K_MEM_SIZE,
.ReadOnly = false,
Expand All @@ -215,6 +246,10 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationProcessFunc = MifareClassicAppProcess,
.ApplicationGetUidFunc = MifareClassicGetUid,
.ApplicationSetUidFunc = MifareClassicSetUid,
.ApplicationGetSakFunc = MifareClassicGetSak,
.ApplicationSetSakFunc = MifareClassicSetSak,
.ApplicationGetAtqaFunc = MifareClassicGetAtqa,
.ApplicationSetAtqaFunc = MifareClassicSetAtqa,
.UidSize = ISO14443A_UID_SIZE_DOUBLE,
.MemorySize = MIFARE_CLASSIC_1K_MEM_SIZE,
.ReadOnly = false,
Expand All @@ -233,6 +268,10 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationProcessFunc = MifareClassicAppProcess,
.ApplicationGetUidFunc = MifareClassicGetUid,
.ApplicationSetUidFunc = MifareClassicSetUid,
.ApplicationGetSakFunc = MifareClassicGetSak,
.ApplicationSetSakFunc = MifareClassicSetSak,
.ApplicationGetAtqaFunc = MifareClassicGetAtqa,
.ApplicationSetAtqaFunc = MifareClassicSetAtqa,
.UidSize = MIFARE_CLASSIC_UID_SIZE,
.MemorySize = MIFARE_CLASSIC_4K_MEM_SIZE,
.ReadOnly = false,
Expand All @@ -251,6 +290,10 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationProcessFunc = MifareClassicAppProcess,
.ApplicationGetUidFunc = MifareClassicGetUid,
.ApplicationSetUidFunc = MifareClassicSetUid,
.ApplicationGetSakFunc = MifareClassicGetSak,
.ApplicationSetSakFunc = MifareClassicSetSak,
.ApplicationGetAtqaFunc = MifareClassicGetAtqa,
.ApplicationSetAtqaFunc = MifareClassicSetAtqa,
.UidSize = ISO14443A_UID_SIZE_DOUBLE,
.MemorySize = MIFARE_CLASSIC_4K_MEM_SIZE,
.ReadOnly = false,
Expand All @@ -269,6 +312,10 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationProcessFunc = MifareClassicAppProcess,
.ApplicationGetUidFunc = MifareClassicGetUid,
.ApplicationSetUidFunc = MifareClassicSetUid,
.ApplicationGetSakFunc = MifareClassicGetSak,
.ApplicationSetSakFunc = MifareClassicSetSak,
.ApplicationGetAtqaFunc = MifareClassicGetAtqa,
.ApplicationSetAtqaFunc = MifareClassicSetAtqa,
.UidSize = MIFARE_CLASSIC_UID_SIZE,
.MemorySize = MIFARE_CLASSIC_1K_MEM_SIZE,
.ReadOnly = false,
Expand All @@ -287,6 +334,10 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationProcessFunc = MifareClassicAppProcess,
.ApplicationGetUidFunc = MifareClassicGetUid,
.ApplicationSetUidFunc = MifareClassicSetUid,
.ApplicationGetSakFunc = MifareClassicGetSak,
.ApplicationSetSakFunc = MifareClassicSetSak,
.ApplicationGetAtqaFunc = MifareClassicGetAtqa,
.ApplicationSetAtqaFunc = MifareClassicSetAtqa,
.UidSize = MIFARE_CLASSIC_UID_SIZE,
.MemorySize = MIFARE_CLASSIC_4K_MEM_SIZE,
.ReadOnly = false,
Expand All @@ -305,6 +356,10 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationProcessFunc = Sniff14443AAppProcess,
.ApplicationGetUidFunc = ApplicationGetUidDummy,
.ApplicationSetUidFunc = ApplicationSetUidDummy,
.ApplicationGetSakFunc = ApplicationGetSakDummy,
.ApplicationSetSakFunc = ApplicationSetSakDummy,
.ApplicationGetAtqaFunc = ApplicationGetAtqaDummy,
.ApplicationSetAtqaFunc = ApplicationSetAtqaDummy,
.UidSize = 0,
.MemorySize = 0,
.ReadOnly = true,
Expand All @@ -323,6 +378,10 @@ static const PROGMEM ConfigurationType ConfigurationTable[] = {
.ApplicationProcessFunc = Reader14443AAppProcess,
.ApplicationGetUidFunc = ApplicationGetUidDummy,
.ApplicationSetUidFunc = ApplicationSetUidDummy,
.ApplicationGetSakFunc = ApplicationGetSakDummy,
.ApplicationSetSakFunc = ApplicationSetSakDummy,
.ApplicationGetAtqaFunc = ApplicationGetAtqaDummy,
.ApplicationSetAtqaFunc = ApplicationSetAtqaDummy,
.UidSize = 0,
.MemorySize = 0,
.ReadOnly = false,
Expand Down
24 changes: 24 additions & 0 deletions Firmware/Chameleon-Mini/Configuration.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@

#define CONFIGURATION_NAME_LENGTH_MAX 32
#define CONFIGURATION_UID_SIZE_MAX 16
/* ATQA & SAK */
#define CONFIGURATION_DUMMY_ATQA 0x0000
#define CONFIGURATION_DUMMY_SAK 0x00


typedef uint8_t ConfigurationUidType[CONFIGURATION_UID_SIZE_MAX];

Expand Down Expand Up @@ -135,6 +139,26 @@ typedef struct {
* \param Uid The source buffer.
*/
void (*ApplicationSetUidFunc)(ConfigurationUidType Uid);
/**
* Writes the SAK for the current configuration to the given buffer.
* \param Sak The target buffer.
*/
void (*ApplicationGetSakFunc) (uint8_t * Sak);
/**
* Writes a given SAK to the current configuration.
* \param Sak The source buffer.
*/
void (*ApplicationSetSakFunc) (uint8_t Sak);
/**
* Writes the ATQA for the current configuration to the given buffer.
* \param Atqa The target buffer.
*/
void (*ApplicationGetAtqaFunc) (uint16_t * Atqa);
/**
* Writes a given ATQA to the current configuration.
* \param Atqa The source buffer.
*/
void (*ApplicationSetAtqaFunc) (uint16_t Atqa);
/**
* @}
*/
Expand Down
14 changes: 14 additions & 0 deletions Firmware/Chameleon-Mini/Terminal/CommandLine.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,20 @@ const PROGMEM CommandEntryType CommandTable[] = {
.SetFunc = CommandSetUid,
.GetFunc = CommandGetUid
},
{
.Command = COMMAND_ATQA,
.ExecFunc = NO_FUNCTION,
.ExecParamFunc = NO_FUNCTION,
.SetFunc = CommandSetAtqa,
.GetFunc = CommandGetAtqa
},
{
.Command = COMMAND_SAK,
.ExecFunc = NO_FUNCTION,
.ExecParamFunc = NO_FUNCTION,
.SetFunc = CommandSetSak,
.GetFunc = CommandGetSak
},
{
.Command = COMMAND_READONLY,
.ExecFunc = NO_FUNCTION,
Expand Down
57 changes: 57 additions & 0 deletions Firmware/Chameleon-Mini/Terminal/Commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,63 @@ CommandStatusIdType CommandSetConfig(char *OutMessage, const char *InParam) {
}
}

CommandStatusIdType CommandGetAtqa(char* OutParam) {
uint16_t Atqa;

ApplicationGetAtqa(&Atqa);

// Convert uint16 to uint8 buffer[]
uint8_t atqaBuffer[2] = { 0,0 };
atqaBuffer[1] = (uint8_t)Atqa;
atqaBuffer[0] = Atqa >> 8;

BufferToHexString(OutParam, TERMINAL_BUFFER_SIZE, &atqaBuffer, sizeof(uint16_t));

return COMMAND_INFO_OK_WITH_TEXT_ID;
}

CommandStatusIdType CommandSetAtqa(char* OutMessage, const char* InParam) {
uint8_t AtqaBuffer[2] = { 0, 0 };
uint16_t Atqa = 0;

if (HexStringToBuffer(&AtqaBuffer, sizeof(AtqaBuffer), InParam) != sizeof(uint16_t)) {
// This has to be 4 digits (2 bytes), e.g.: 0004
return COMMAND_ERR_INVALID_PARAM_ID;
}

// Convert uint8 buffer[] to uint16
if (strlen(InParam) > 2) {
Atqa = ((uint16_t)AtqaBuffer[0] << 8) | AtqaBuffer[1];
}
else {
Atqa = AtqaBuffer[0];
}

ApplicationSetAtqa(Atqa);
return COMMAND_INFO_OK_ID;
}

CommandStatusIdType CommandGetSak(char* OutParam) {
uint8_t Sak;

ApplicationGetSak(&Sak);

BufferToHexString(OutParam, TERMINAL_BUFFER_SIZE, &Sak, sizeof(uint8_t));
return COMMAND_INFO_OK_WITH_TEXT_ID;
}

CommandStatusIdType CommandSetSak(char* OutMessage, const char* InParam) {
uint8_t Sak;

if (HexStringToBuffer(&Sak, sizeof(uint8_t), InParam) != sizeof(uint8_t)) {
// This has to be 2 digits (1 byte), e.g.: 04
return COMMAND_ERR_INVALID_PARAM_ID;
}

ApplicationSetSak(Sak);
return COMMAND_INFO_OK_ID;
}

CommandStatusIdType CommandGetUid(char *OutParam) {
uint8_t UidBuffer[COMMAND_UID_BUFSIZE];
uint16_t UidSize = ActiveConfiguration.UidSize;
Expand Down
Loading

0 comments on commit 7f310af

Please sign in to comment.