Skip to content

Commit

Permalink
Stashing more incremental updates to the code to get/verify PM3 compa…
Browse files Browse the repository at this point in the history
…tibility
  • Loading branch information
maxieds committed Mar 16, 2022
1 parent 64d1fff commit aafc5ab
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ static uint16_t ISO144434ProcessBlock(uint8_t *Buffer, uint16_t ByteCount, uint1
ISO144434SwitchState(ISO14443_4_STATE_ACTIVE);
const char *debugPrintStr = PSTR("ISO14443-4: SEND RATS");
LogDebuggingMsg(debugPrintStr);
return GetAndSetBufferCRCA(Buffer, ByteCount);
return ByteCount * BITS_PER_BYTE; // PM3 expects no CRCA bytes
}
case ISO14443_4_STATE_ACTIVE: {
/* See: ISO/IEC 14443-4; 7.1 Block format */
Expand Down Expand Up @@ -277,6 +277,7 @@ Iso144433AStateType Iso144433AIdleState = ISO14443_3A_STATE_IDLE;

void ISO144433ASwitchState(Iso144433AStateType NewState) {
Iso144433AState = NewState;
StateRetryCount = 0x00;
DesfireLogISOStateChange(Iso144433AState, LOG_ISO14443_3A_STATE);
}

Expand Down Expand Up @@ -316,9 +317,9 @@ uint16_t ISO144433APiccProcess(uint8_t *Buffer, uint16_t BitCount) {
REQA bytes, in between which we would have already sent
back a response, so that we should not reset. */
decrementRetryCount = false;
} else if (Cmd == ISO14443A_CMD_REQA || Cmd == ISO14443A_CMD_WUPA) {
} else if (Cmd == ISO14443A_CMD_REQA || ISO14443ACmdIsWUPA(Cmd)) {
ISO144434Reset();
ISO144433ASwitchState(ISO14443_3A_STATE_READY1);
ISO144433ASwitchState(ISO14443_3A_STATE_IDLE);
decrementRetryCount = false;
} else if (ISO144433AIsHalt(Buffer, BitCount)) {
LogEntry(LOG_INFO_APP_CMD_HALT, NULL, 0);
Expand All @@ -339,7 +340,7 @@ uint16_t ISO144433APiccProcess(uint8_t *Buffer, uint16_t BitCount) {
/* See: ISO/IEC 14443-3, clause 6.2 */
switch (Iso144433AState) {
case ISO14443_3A_STATE_HALT:
if (Cmd != ISO14443A_CMD_WUPA) {
if (!ISO14443ACmdIsWUPA(Cmd)) {
const char *debugPrintStr = PSTR("ISO14443-4: HALT / NOT WUPA");
LogDebuggingMsg(debugPrintStr);
break;
Expand All @@ -349,12 +350,6 @@ uint16_t ISO144433APiccProcess(uint8_t *Buffer, uint16_t BitCount) {
/* Fall-through */

case ISO14443_3A_STATE_IDLE:
if (Cmd != ISO14443A_CMD_REQA &&
Cmd != ISO14443A_CMD_WUPA) {
const char *debugPrintStr = PSTR("ISO14443-4: IDLE / NOT WUPA 0x%02x");
DEBUG_PRINT_P(debugPrintStr);
break;
}
Iso144433AIdleState = Iso144433AState;
ISO144433ASwitchState(ISO14443_3A_STATE_READY1);
Buffer[0] = (ATQA_VALUE) & 0x00FF;
Expand All @@ -364,7 +359,7 @@ uint16_t ISO144433APiccProcess(uint8_t *Buffer, uint16_t BitCount) {
return ISO14443A_ATQA_FRAME_SIZE_BYTES * BITS_PER_BYTE;

case ISO14443_3A_STATE_READY1:
if (Cmd == ISO14443A_CMD_SELECT_CL1 || Cmd == ISO14443A_CMD_REQA || Cmd == ISO14443A_CMD_WUPA) {
if (Cmd == ISO14443A_CMD_SELECT_CL1 || Cmd == ISO14443A_CMD_REQA || ISO14443ACmdIsWUPA(Cmd)) {
/* Load UID CL1 and perform anticollision. */
ConfigurationUidType Uid;
ApplicationGetUid(Uid);
Expand Down Expand Up @@ -414,10 +409,14 @@ uint16_t ISO144433APiccProcess(uint8_t *Buffer, uint16_t BitCount) {
/* Recognise the HLTA command */
if (ISO144433AIsHalt(Buffer, BitCount)) {
LogEntry(LOG_INFO_APP_CMD_HALT, NULL, 0);
ISO144433ASwitchState(ISO14443_3A_STATE_HALT);
ISO144434SwitchState(ISO14443_3A_STATE_HALT);
const char *logMsg = PSTR("ISO14443-3: Got HALT");
LogDebuggingMsg(logMsg);
return ISO14443A_APP_NO_RESPONSE;
} else if(Cmd == ISO14443A_CMD_RATS) {
ISO144433ASwitchState(ISO14443_4_STATE_EXPECT_RATS);
const char *logMsg = PSTR("ISO14443-3/4: EXPECTING RATS");
LogDebuggingMsg(logMsg);
}
/* Forward to ISO/IEC 14443-4 processing code */
uint16_t ByteCount = (BitCount + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ This notice must be retained at the top of all source files where indicated.
#define ISO14443A_CMD_RNAK 0xB2
#define ISO14443A_CRC_FRAME_SIZE (ISO14443A_CRCA_SIZE * BITS_PER_BYTE)

#define ISO14443ACmdIsPM3WUPA(cmd) ((cmd & 0x54) == 0x54)
#define ISO14443ACmdIsWUPA(cmd) ((cmd == ISO14443A_CMD_WUPA) || ISO14443ACmdIsPM3WUPA(cmd))

#define ISO14443_PCB_BLOCK_TYPE_MASK 0xC0
#define ISO14443_PCB_I_BLOCK 0x00
#define ISO14443_PCB_R_BLOCK 0x80
Expand Down Expand Up @@ -109,7 +112,7 @@ INLINE ISO14443AStoreLastDataFrameAndReturn(const uint8_t *Buffer, uint16_t Buff

/* Setup some fuzzy response handling for problematic readers like the ACR122U */

#define MAX_STATE_RETRY_COUNT (4)
#define MAX_STATE_RETRY_COUNT (0x8f) /* For all intensive purposes, as many as necessary */
extern uint8_t StateRetryCount;
bool CheckStateRetryCount(bool resetByDefault);
bool CheckStateRetryCount2(bool resetByDefault, bool performLogging);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@ uint8_t Iso7816EfIdNumber = ISO7816_EF_NOT_SPECIFIED;

bool IsWrappedISO7816CommandType(uint8_t *Buffer, uint16_t ByteCount) {
if (ByteCount <= ISO7816_PROLOGUE_SIZE + ISO14443A_CRCA_SIZE + 2) {
return false;
return ISO7816_WRAPPED_CMD_TYPE_NONE;
} else if (!ISO14443ACheckCRCA(Buffer, ByteCount - 2)) {
return false;
return ISO7816_WRAPPED_CMD_TYPE_NONE;
} else if (ByteCount >= 4 && Buffer[3] == ByteCount - 4) {
return ISO7816_WRAPPED_CMD_TYPE_PM3RAW;
} else if (!Iso7816CLA(Buffer[2])) {
return false;
return ISO7816_WRAPPED_CMD_TYPE_NONE;
}
return true;
return ISO7816_WRAPPED_CMD_TYPE_STANDARD;
}

uint16_t SetIso7816WrappedParametersType(uint8_t *Buffer, uint16_t ByteCount) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ extern bool Iso7816FileSelected;
extern uint8_t Iso7816FileOffset;
extern uint8_t Iso7816EfIdNumber;

typedef enum {
ISO7816_WRAPPED_CMD_TYPE_NONE = 0,
ISO7816_WRAPPED_CMD_TYPE_STANDARD,
ISO7816_WRAPPED_CMD_TYPE_PM3RAW,
/* Others ??? */
} Iso7816WrappedCommandType_t;

bool IsWrappedISO7816CommandType(uint8_t *Buffer, uint16_t ByteCount);
uint16_t SetIso7816WrappedParametersType(uint8_t *Buffer, uint16_t ByteCount);

Expand Down
20 changes: 16 additions & 4 deletions Firmware/Chameleon-Mini/Application/MifareDESFire.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ DesfireStateType DesfireState = DESFIRE_HALT;
DesfireStateType DesfirePreviousState = DESFIRE_IDLE;
bool DesfireFromHalt = false;
BYTE DesfireCmdCLA = DESFIRE_NATIVE_CLA;
Iso7816WrappedCommandType_t Iso7816CmdType;
static bool AnticolNoResp = false;

/* Dispatching routines */
Expand Down Expand Up @@ -223,13 +224,22 @@ uint16_t MifareDesfireAppProcess(uint8_t *Buffer, uint16_t BitCount) {
uint16_t UnwrappedBitCount = DesfirePreprocessAPDU(ActiveCommMode, Buffer, IncomingByteCount) * BITS_PER_BYTE;
uint16_t ProcessedBitCount = MifareDesfireProcess(Buffer, UnwrappedBitCount);
uint16_t ProcessedByteCount = (ProcessedBitCount + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
return ISO14443AStoreLastDataFrameAndReturn(Buffer, DesfirePostprocessAPDU(ActiveCommMode, Buffer, ProcessedByteCount) * BITS_PER_BYTE);
} else if (IsWrappedISO7816CommandType(Buffer, ByteCount)) {
DesfireCmdCLA = Buffer[2];
return ISO14443AStoreLastDataFrameAndReturn(Buffer,
DesfirePostprocessAPDU(ActiveCommMode, Buffer, ProcessedByteCount) * BITS_PER_BYTE);
} else if ((Iso7816CmdType = IsWrappedISO7816CommandType(Buffer, ByteCount)) && Iso7816CmdType != ISO7816_WRAPPED_CMD_TYPE_NONE) {
DesfireCmdCLA = (Iso7816CmdType == ISO7816_WRAPPED_CMD_TYPE_STANDARD) ? Buffer[2] : DESFIRE_ISO7816_CLA;
uint8_t ISO7816PrologueBytes[2];
memcpy(&ISO7816PrologueBytes[0], Buffer, 2);
uint16_t IncomingByteCount = DesfirePreprocessAPDU(ActiveCommMode, Buffer, IncomingByteCount);
memmove(&Buffer[0], &Buffer[2], IncomingByteCount - 2);
if (Iso7816CmdType == ISO7816_WRAPPED_CMD_TYPE_STANDARD) {
memmove(&Buffer[0], &Buffer[2], IncomingByteCount - 2);
} else if (Iso7816CmdType == ISO7816_WRAPPED_CMD_TYPE_PM3RAW) {
Buffer[0] = DesfireCmdCLA;
Buffer[1] = Buffer[2];
Buffer[2] = 0x04;
memmove(&Buffer[4], &Buffer[3], IncomingByteCount - 2);
Buffer[3] = 0x00;
}
uint16_t UnwrappedBitCount = (IncomingByteCount - 2) * BITS_PER_BYTE;
uint16_t ProcessedBitCount = MifareDesfireProcess(Buffer, UnwrappedBitCount);
uint16_t ProcessedByteCount = (ProcessedBitCount + BITS_PER_BYTE - 1) / BITS_PER_BYTE;
Expand All @@ -255,6 +265,8 @@ uint16_t MifareDesfireAppProcess(uint8_t *Buffer, uint16_t BitCount) {
// even when the reader has not been put in scan mode --
// and it really screws things up timing-wise!
AnticolNoResp = true;
const char *debugPrintStr = PSTR("DESFire: Anticol NO-RESP set");
LogDebuggingMsg(debugPrintStr);
}
return ISO14443AStoreLastDataFrameAndReturn(Buffer, PiccProcessRespBits);
}
Expand Down
1 change: 1 addition & 0 deletions Firmware/Chameleon-Mini/Application/MifareDESFire.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,6 @@ extern DesfireStateType DesfireState;
extern DesfireStateType DesfirePreviousState;
extern bool DesfireFromHalt;
extern BYTE DesfireCmdCLA;
extern Iso7816WrappedCommandType_t Iso7816CmdType;

#endif /* MIFAREDESFIRE_H_ */

0 comments on commit aafc5ab

Please sign in to comment.