Skip to content

Commit bb7d46f

Browse files
committed
Adding more complete support for PM3 ISO auth (stashing incremental changes as reference point)
1 parent aafc5ab commit bb7d46f

File tree

6 files changed

+31
-23
lines changed

6 files changed

+31
-23
lines changed

Firmware/Chameleon-Mini/Application/DESFire/DESFireISO14443Support.c

+12-9
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ uint8_t ISO14443ALastDataFrame[MAX_DATA_FRAME_XFER_SIZE] = { 0x00 };
4848
uint16_t ISO14443ALastDataFrameBits = 0;
4949

5050
bool CheckStateRetryCount2(bool resetByDefault, bool performLogging) {
51-
if (resetByDefault || ++StateRetryCount >= MAX_STATE_RETRY_COUNT) {
51+
if (resetByDefault || ++StateRetryCount > MAX_STATE_RETRY_COUNT) {
5252
ISO144434SwitchState2(Iso144433AIdleState, performLogging);
5353
StateRetryCount = 0x00;
5454
const char *debugStatusMsg = PSTR("RETRY-RESET");
@@ -311,16 +311,16 @@ uint16_t ISO144433APiccProcess(uint8_t *Buffer, uint16_t BitCount) {
311311

312312
/* Wakeup and Request may occure in all states */
313313
bool checkStateRetryStatus = CheckStateRetryCount(false);
314-
bool decrementRetryCount = true;
314+
bool incrementRetryCount = true;
315315
if ((Cmd == ISO14443A_CMD_REQA) && (LastReaderSentCmd == ISO14443A_CMD_REQA) && !checkStateRetryStatus) {
316316
/* Catch timing issues where the reader sends multiple
317-
REQA bytes, in between which we would have already sent
318-
back a response, so that we should not reset. */
319-
decrementRetryCount = false;
317+
REQA bytes, in between which we would have already sent
318+
back a response, so that we should not reset. */
319+
incrementRetryCount = false;
320320
} else if (Cmd == ISO14443A_CMD_REQA || ISO14443ACmdIsWUPA(Cmd)) {
321321
ISO144434Reset();
322322
ISO144433ASwitchState(ISO14443_3A_STATE_IDLE);
323-
decrementRetryCount = false;
323+
incrementRetryCount = false;
324324
} else if (ISO144433AIsHalt(Buffer, BitCount)) {
325325
LogEntry(LOG_INFO_APP_CMD_HALT, NULL, 0);
326326
ISO144433ASwitchState(ISO14443_3A_STATE_HALT);
@@ -332,8 +332,8 @@ uint16_t ISO144433APiccProcess(uint8_t *Buffer, uint16_t BitCount) {
332332
return ISO14443A_APP_NO_RESPONSE;
333333
}
334334
LastReaderSentCmd = Cmd;
335-
if (decrementRetryCount && StateRetryCount > 0) {
336-
StateRetryCount -= 1;
335+
if (incrementRetryCount) {
336+
StateRetryCount += 1;
337337
}
338338

339339
/* This implements ISO 14443-3A state machine */
@@ -406,17 +406,20 @@ uint16_t ISO144433APiccProcess(uint8_t *Buffer, uint16_t BitCount) {
406406
break;
407407

408408
case ISO14443_3A_STATE_ACTIVE:
409+
StateRetryCount = MAX_STATE_RETRY_COUNT;
409410
/* Recognise the HLTA command */
410411
if (ISO144433AIsHalt(Buffer, BitCount)) {
411412
LogEntry(LOG_INFO_APP_CMD_HALT, NULL, 0);
412413
ISO144434SwitchState(ISO14443_3A_STATE_HALT);
413414
const char *logMsg = PSTR("ISO14443-3: Got HALT");
414415
LogDebuggingMsg(logMsg);
415416
return ISO14443A_APP_NO_RESPONSE;
416-
} else if(Cmd == ISO14443A_CMD_RATS) {
417+
} else if (Cmd == ISO14443A_CMD_RATS) {
417418
ISO144433ASwitchState(ISO14443_4_STATE_EXPECT_RATS);
418419
const char *logMsg = PSTR("ISO14443-3/4: EXPECTING RATS");
419420
LogDebuggingMsg(logMsg);
421+
} else if (Cmd == ISO14443A_CMD_SELECT_CL3) {
422+
return ISO14443A_APP_NO_RESPONSE;
420423
}
421424
/* Forward to ISO/IEC 14443-4 processing code */
422425
uint16_t ByteCount = (BitCount + BITS_PER_BYTE - 1) / BITS_PER_BYTE;

Firmware/Chameleon-Mini/Application/DESFire/DESFireISO14443Support.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ INLINE ISO14443AStoreLastDataFrameAndReturn(const uint8_t *Buffer, uint16_t Buff
112112

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

115-
#define MAX_STATE_RETRY_COUNT (0x8f) /* For all intensive purposes, as many as necessary */
115+
#define MAX_STATE_RETRY_COUNT (0x04) /* For all intensive purposes, as many as necessary */
116116
extern uint8_t StateRetryCount;
117117
bool CheckStateRetryCount(bool resetByDefault);
118118
bool CheckStateRetryCount2(bool resetByDefault, bool performLogging);

Firmware/Chameleon-Mini/Application/DESFire/DESFireISO7816Support.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ uint8_t Iso7816EfIdNumber = ISO7816_EF_NOT_SPECIFIED;
3737
bool IsWrappedISO7816CommandType(uint8_t *Buffer, uint16_t ByteCount) {
3838
if (ByteCount <= ISO7816_PROLOGUE_SIZE + ISO14443A_CRCA_SIZE + 2) {
3939
return ISO7816_WRAPPED_CMD_TYPE_NONE;
40-
} else if (!ISO14443ACheckCRCA(Buffer, ByteCount - 2)) {
40+
} else if (!ISO14443ACheckCRCA(&Buffer[0], ByteCount - 2)) {
4141
return ISO7816_WRAPPED_CMD_TYPE_NONE;
42-
} else if (ByteCount >= 4 && Buffer[3] == ByteCount - 4) {
42+
} else if (ByteCount >= 6 && Buffer[3] == ByteCount - 6) {
4343
return ISO7816_WRAPPED_CMD_TYPE_PM3RAW;
4444
} else if (!Iso7816CLA(Buffer[2])) {
4545
return ISO7816_WRAPPED_CMD_TYPE_NONE;

Firmware/Chameleon-Mini/Application/ISO14443-3A.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -160,10 +160,10 @@ bool ISO14443ACheckCRCA(const void *Buffer, uint16_t ByteCount) {
160160
bool ISO14443ASelect(void *Buffer, uint16_t *BitCount, uint8_t *UidCL, uint8_t SAKValue) {
161161
uint8_t *DataPtr = (uint8_t *) Buffer;
162162
uint8_t NVB = DataPtr[1];
163-
//uint8_t CollisionByteCount = (NVB >> 4) & 0x0F;
164-
//uint8_t CollisionBitCount = (NVB >> 0) & 0x0F;
165163

166164
switch (NVB) {
165+
case 0x00:
166+
case ISO14443A_CMD_HLTA:
167167
case ISO14443A_NVB_AC_START:
168168
/* Start of anticollision procedure.
169169
* Send whole UID CLn + BCC */

Firmware/Chameleon-Mini/Application/MifareDESFire.c

+7-4
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ void MifareDesfireAppReset(void) {
111111
/* This is called repeatedly, so limit the amount of work done */
112112
ISO144433AReset();
113113
ISO144434Reset();
114+
StateRetryCount = MAX_STATE_RETRY_COUNT;
114115
MifareDesfireReset();
115116
}
116117

@@ -230,16 +231,18 @@ uint16_t MifareDesfireAppProcess(uint8_t *Buffer, uint16_t BitCount) {
230231
DesfireCmdCLA = (Iso7816CmdType == ISO7816_WRAPPED_CMD_TYPE_STANDARD) ? Buffer[2] : DESFIRE_ISO7816_CLA;
231232
uint8_t ISO7816PrologueBytes[2];
232233
memcpy(&ISO7816PrologueBytes[0], Buffer, 2);
233-
uint16_t IncomingByteCount = DesfirePreprocessAPDU(ActiveCommMode, Buffer, IncomingByteCount);
234234
if (Iso7816CmdType == ISO7816_WRAPPED_CMD_TYPE_STANDARD) {
235-
memmove(&Buffer[0], &Buffer[2], IncomingByteCount - 2);
235+
memmove(&Buffer[0], &Buffer[2], ByteCount - 2);
236236
} else if (Iso7816CmdType == ISO7816_WRAPPED_CMD_TYPE_PM3RAW) {
237+
/* Looks something like: 0a 00 1a 00 CRC1 CRC2 (for PM3 raw ISO auth) */
237238
Buffer[0] = DesfireCmdCLA;
238239
Buffer[1] = Buffer[2];
239-
Buffer[2] = 0x04;
240-
memmove(&Buffer[4], &Buffer[3], IncomingByteCount - 2);
240+
memmove(&Buffer[5], &Buffer[3], ByteCount - 3);
241+
Buffer[2] = 0x00;
241242
Buffer[3] = 0x00;
243+
Buffer[4] = ByteCount - 5;
242244
}
245+
uint16_t IncomingByteCount = DesfirePreprocessAPDU(ActiveCommMode, Buffer, IncomingByteCount);
243246
uint16_t UnwrappedBitCount = (IncomingByteCount - 2) * BITS_PER_BYTE;
244247
uint16_t ProcessedBitCount = MifareDesfireProcess(Buffer, UnwrappedBitCount);
245248
uint16_t ProcessedByteCount = (ProcessedBitCount + BITS_PER_BYTE - 1) / BITS_PER_BYTE;

Firmware/Chameleon-Mini/Makefile

+7-5
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,9 @@ SETTINGS += -DDESFIRE_DEFAULT_TESTING_MODE=0
124124

125125
#Set a minimum incoming/outgoing log size so we do not spam the
126126
#Chameleon Mini logs to much by logging everything:
127-
SETTINGS += -DDESFIRE_MIN_INCOMING_LOGSIZE=1
128-
SETTINGS += -DDESFIRE_MIN_OUTGOING_LOGSIZE=1
129-
#SETTINGS += -DDESFIRE_MIN_OUTGOING_LOGSIZE=0
127+
SETTINGS += -DDESFIRE_MIN_INCOMING_LOGSIZE=0
128+
#SETTINGS += -DDESFIRE_MIN_OUTGOING_LOGSIZE=1
129+
SETTINGS += -DDESFIRE_MIN_OUTGOING_LOGSIZE=0
130130

131131
#Enable printing of crypto tests when a new DESFire emulation instance is started:
132132
#SETTINGS += -DDESFIRE_RUN_CRYPTO_TESTING_PROCEDURE
@@ -303,6 +303,8 @@ local-clean:
303303

304304
git-add-dev:
305305
@git add Makefile ./*.{c,h} ./*/*.{c,h} ./*/*/*.{c,h}
306+
@cd ../../Software/DESFireLibNFCTesting && \
307+
git add Makefile LocalInclude/*.h Source/*.c SampleOutputDumps/*.dump
306308

307309
## Defining custom targets for the DESFire build (normal/user mode) and
308310
## developer mode for use with the Android CMLD application that enables
@@ -311,10 +313,10 @@ desfire-build: local-clean $(TARGET).elf $(TARGET).hex $(TARGET).eep $(TARGET).b
311313
@cp $(TARGET).hex $(TARGET)-DESFire.hex
312314
@cp $(TARGET).eep $(TARGET)-DESFire.eep
313315
@cp $(TARGET).bin $(TARGET)-DESFire.bin
314-
@echo -e "\n"
316+
@echo ""
315317
@avr-size -A -x $(TARGET).elf
316318
@avr-size -B -x $(TARGET).elf
317-
@echo -e "\n"
319+
@echo ""
318320
@avr-size -C -x $(TARGET).elf
319321
desfire: CONFIG_SETTINGS:=$(DESFIRE_CONFIG_SETTINGS_BASE) -DDEFAULT_CONFIGURATION=CONFIG_NONE -fno-inline-small-functions
320322
desfire: desfire-build

0 commit comments

Comments
 (0)