From 1be76882044528e4a9d5e53234c94713521e92bf Mon Sep 17 00:00:00 2001 From: Maxie Dion Schmidt <maxieds@gmail.com> Date: Mon, 21 Mar 2022 21:05:16 -0400 Subject: [PATCH] Adding more complete support for PM3 ISO auth (stashing incremental changes as reference point -- II) --- .../DESFire/DESFireISO14443Support.c | 2 +- .../DESFire/DESFireISO14443Support.h | 2 +- .../Chameleon-Mini/Application/ISO14443-3A.c | 4 ++-- .../Chameleon-Mini/Application/ISO14443-3A.h | 6 ------ .../Application/MifareDESFire.c | 20 ++++++++++--------- 5 files changed, 15 insertions(+), 19 deletions(-) diff --git a/Firmware/Chameleon-Mini/Application/DESFire/DESFireISO14443Support.c b/Firmware/Chameleon-Mini/Application/DESFire/DESFireISO14443Support.c index eb84692b..58345e88 100644 --- a/Firmware/Chameleon-Mini/Application/DESFire/DESFireISO14443Support.c +++ b/Firmware/Chameleon-Mini/Application/DESFire/DESFireISO14443Support.c @@ -359,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 || ISO14443ACmdIsWUPA(Cmd)) { + if (Cmd == ISO14443A_CMD_SELECT_CL1) { /* Load UID CL1 and perform anticollision. */ ConfigurationUidType Uid; ApplicationGetUid(Uid); diff --git a/Firmware/Chameleon-Mini/Application/DESFire/DESFireISO14443Support.h b/Firmware/Chameleon-Mini/Application/DESFire/DESFireISO14443Support.h index bf56f7db..9c68f63f 100644 --- a/Firmware/Chameleon-Mini/Application/DESFire/DESFireISO14443Support.h +++ b/Firmware/Chameleon-Mini/Application/DESFire/DESFireISO14443Support.h @@ -112,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 (0x04) /* For all intensive purposes, as many as necessary */ +#define MAX_STATE_RETRY_COUNT (0x0a) /* For all intensive purposes, as many as necessary */ extern uint8_t StateRetryCount; bool CheckStateRetryCount(bool resetByDefault); bool CheckStateRetryCount2(bool resetByDefault, bool performLogging); diff --git a/Firmware/Chameleon-Mini/Application/ISO14443-3A.c b/Firmware/Chameleon-Mini/Application/ISO14443-3A.c index cc7192b4..06812994 100644 --- a/Firmware/Chameleon-Mini/Application/ISO14443-3A.c +++ b/Firmware/Chameleon-Mini/Application/ISO14443-3A.c @@ -19,6 +19,8 @@ bool ISO14443ASelectDesfire(void *Buffer, uint16_t *BitCount, uint8_t *UidCL, ui uint8_t NVB = DataPtr[1]; switch (NVB) { + case 0x00: + case ISO14443A_CMD_HLTA: case ISO14443A_NVB_AC_START: /* Start of anticollision procedure. * Send whole UID CLn + BCC */ @@ -162,8 +164,6 @@ bool ISO14443ASelect(void *Buffer, uint16_t *BitCount, uint8_t *UidCL, uint8_t S uint8_t NVB = DataPtr[1]; switch (NVB) { - case 0x00: - case ISO14443A_CMD_HLTA: case ISO14443A_NVB_AC_START: /* Start of anticollision procedure. * Send whole UID CLn + BCC */ diff --git a/Firmware/Chameleon-Mini/Application/ISO14443-3A.h b/Firmware/Chameleon-Mini/Application/ISO14443-3A.h index d83f0b66..cefe7dbd 100644 --- a/Firmware/Chameleon-Mini/Application/ISO14443-3A.h +++ b/Firmware/Chameleon-Mini/Application/ISO14443-3A.h @@ -25,12 +25,6 @@ #define ISO14443A_NVB_AC_START 0x20 #define ISO14443A_NVB_AC_END 0x70 -#define IsSelectCmd(Buffer) ((Buffer[0] == ISO14443A_CMD_SELECT_CL1) || \ - (Buffer[0] == ISO14443A_CMD_SELECT_CL2) || \ - (Buffer[0] == ISO14443A_CMD_SELECT_CL3)) -#define IsCmdSelectRound1(Buffer) (IsSelectCmd(Buffer) && (Buffer[1] == ISO14443A_NVB_AC_START)) -#define IsCmdSelectRound2(Buffer) (IsSelectCmd(Buffer) && (Buffer[1] == ISO14443A_NVB_AC_END)) - #define ISO14443A_CL_UID_OFFSET 0 #define ISO14443A_CL_UID_SIZE 4 #define ISO14443A_CL_BCC_OFFSET 4 diff --git a/Firmware/Chameleon-Mini/Application/MifareDESFire.c b/Firmware/Chameleon-Mini/Application/MifareDESFire.c index 2b57edad..d7e1e8cc 100644 --- a/Firmware/Chameleon-Mini/Application/MifareDESFire.c +++ b/Firmware/Chameleon-Mini/Application/MifareDESFire.c @@ -111,15 +111,13 @@ void MifareDesfireAppReset(void) { /* This is called repeatedly, so limit the amount of work done */ ISO144433AReset(); ISO144434Reset(); - StateRetryCount = MAX_STATE_RETRY_COUNT; MifareDesfireReset(); } void MifareDesfireAppTick(void) { - if (!CheckStateRetryCount2(false, false)) { + if (CheckStateRetryCount2(false, true)) { MifareDesfireAppReset(); } - /* Empty */ } void MifareDesfireAppTask(void) { @@ -176,12 +174,13 @@ uint16_t MifareDesfireProcessCommand(uint8_t *Buffer, uint16_t ByteCount) { uint16_t MifareDesfireProcess(uint8_t *Buffer, uint16_t BitCount) { size_t ByteCount = (BitCount + BITS_PER_BYTE - 1) / BITS_PER_BYTE; DesfireCmdCLA = Buffer[0]; - //LogEntry(LOG_INFO_DESFIRE_INCOMING_DATA, Buffer, ByteCount); + LogEntry(LOG_INFO_DESFIRE_INCOMING_DATA, Buffer, ByteCount); if (BitCount == 0) { LogEntry(LOG_INFO_DESFIRE_INCOMING_DATA, Buffer, ByteCount); return ISO14443A_APP_NO_RESPONSE; } else if ((ByteCount >= 8 && DesfireCLA(Buffer[0]) && Buffer[2] == 0x00 && - Buffer[3] == 0x00 && (Buffer[4] == ByteCount - 6 || Buffer[4] == ByteCount - 8)) || Iso7816CLA(DesfireCmdCLA)) { + Buffer[3] == 0x00 && (Buffer[4] == ByteCount - 6 || Buffer[4] == ByteCount - 8)) || + Iso7816CLA(DesfireCmdCLA)) { /* Wrapped native command structure or ISO7816: */ if (Iso7816CLA(DesfireCmdCLA)) { uint16_t iso7816ParamsStatus = SetIso7816WrappedParametersType(Buffer, ByteCount); @@ -204,9 +203,9 @@ uint16_t MifareDesfireProcess(uint8_t *Buffer, uint16_t BitCount) { Buffer[ByteCount - 1] = 0x91; ++ByteCount; } else { - /* Re-wrap into ISO 7816-4 */ + /* Re-wrap into ISO 7816-4 -- Done below by prepending the prologue back to the buffer */ } - //LogEntry(LOG_INFO_DESFIRE_OUTGOING_DATA, Buffer, ByteCount); + LogEntry(LOG_INFO_DESFIRE_OUTGOING_DATA, Buffer, ByteCount); return ByteCount * BITS_PER_BYTE; } else { /* ISO/IEC 14443-4 PDUs: No extra work */ @@ -233,16 +232,19 @@ uint16_t MifareDesfireAppProcess(uint8_t *Buffer, uint16_t BitCount) { memcpy(&ISO7816PrologueBytes[0], Buffer, 2); if (Iso7816CmdType == ISO7816_WRAPPED_CMD_TYPE_STANDARD) { memmove(&Buffer[0], &Buffer[2], ByteCount - 2); + ByteCount = ByteCount - 2; } else if (Iso7816CmdType == ISO7816_WRAPPED_CMD_TYPE_PM3RAW) { - /* Looks something like: 0a 00 1a 00 CRC1 CRC2 (for PM3 raw ISO auth) */ + /* Something like the following (for PM3 raw ISO auth): + * 0a 00 1a 00 CRC1 CRC2 -- first two are prologue -- last two are checksum */ Buffer[0] = DesfireCmdCLA; Buffer[1] = Buffer[2]; memmove(&Buffer[5], &Buffer[3], ByteCount - 3); Buffer[2] = 0x00; Buffer[3] = 0x00; Buffer[4] = ByteCount - 5; + ByteCount = ByteCount + 3; } - uint16_t IncomingByteCount = DesfirePreprocessAPDU(ActiveCommMode, Buffer, IncomingByteCount); + uint16_t IncomingByteCount = DesfirePreprocessAPDU(ActiveCommMode, Buffer, ByteCount); 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;