Skip to content

Commit

Permalink
Current firmware builds tested with PM3 and LibNFC test code ; Still …
Browse files Browse the repository at this point in the history
…takes too long to verify the file mgmt and data manip programs
  • Loading branch information
maxieds committed Jul 20, 2022
1 parent ffb6683 commit aa20be6
Show file tree
Hide file tree
Showing 17 changed files with 127 additions and 88 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,17 @@ CommandStatusIdType CommandDESFireSetHeaderProperty(char *OutParam, const char *
} else {
Picc.ManufacturerID = propSpecBytes[0];
}
} else if (!strcasecmp_P(hdrPropSpecStr, PSTR("Type"))) {
} else if (!strcasecmp_P(hdrPropSpecStr, PSTR("HwType"))) {
if (dataByteCount != 1) {
StatusError = 1;
} else {
Picc.TagType = propSpecBytes[0];
Picc.HwType = propSpecBytes[0];
}
} else if (!strcasecmp_P(hdrPropSpecStr, PSTR("Subtype"))) {
} else if (!strcasecmp_P(hdrPropSpecStr, PSTR("HwSubtype"))) {
if (dataByteCount != 1) {
StatusError = 1;
} else {
Picc.TagSubtype = propSpecBytes[0];
Picc.HwSubtype = propSpecBytes[0];
}
} else if (!strcasecmp_P(hdrPropSpecStr, PSTR("HWProtoType"))) {
if (dataByteCount != 1) {
Expand All @@ -102,6 +102,18 @@ CommandStatusIdType CommandDESFireSetHeaderProperty(char *OutParam, const char *
Picc.HwVersionMajor = propSpecBytes[0];
Picc.HwVersionMinor = propSpecBytes[1];
}
} else if (!strcasecmp_P(hdrPropSpecStr, PSTR("SwType"))) {
if (dataByteCount != 1) {
StatusError = 1;
} else {
Picc.SwType = propSpecBytes[0];
}
} else if (!strcasecmp_P(hdrPropSpecStr, PSTR("SwSubtype"))) {
if (dataByteCount != 1) {
StatusError = 1;
} else {
Picc.SwSubtype = propSpecBytes[0];
}
} else if (!strcasecmp_P(hdrPropSpecStr, PSTR("SwProtoType"))) {
if (dataByteCount != 1) {
StatusError = 1;
Expand Down
3 changes: 2 additions & 1 deletion Firmware/Chameleon-Mini/Application/DESFire/DESFireCrypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ void InvalidateAuthState(BYTE keepPICCAuthData) {
AuthenticatedWithPICCMasterKey = false;
memset(&SessionKey[0], 0x00, CRYPTO_MAX_BLOCK_SIZE);
memset(&SessionIV[0], 0x00, CRYPTO_MAX_BLOCK_SIZE);
SessionIVByteSize = 0;
}
Authenticated = false;
AuthenticatedWithKey = DESFIRE_NOT_AUTHENTICATED;
Expand All @@ -65,7 +66,7 @@ void InvalidateAuthState(BYTE keepPICCAuthData) {
}

bool IsAuthenticated(void) {
return Authenticated != 0x00;
return Authenticated != 0;
}

BYTE GetDefaultCryptoMethodKeySize(uint8_t cryptoType) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ extern uint8_t ISO14443ALastIncomingDataFrame[MAX_DATA_FRAME_XFER_SIZE];
extern uint16_t ISO14443ALastIncomingDataFrameBits;
uint16_t ISO14443AStoreLastDataFrameAndReturn(const uint8_t *Buffer, uint16_t BufferBitCount);

#define MAX_STATE_RETRY_COUNT (0x14)
#define MAX_STATE_RETRY_COUNT (0x18)
extern uint8_t StateRetryCount;
bool CheckStateRetryCount(bool resetByDefault);
bool CheckStateRetryCountWithLogging(bool resetByDefault, bool performLogging);
Expand Down
20 changes: 10 additions & 10 deletions Firmware/Chameleon-Mini/Application/DESFire/DESFireInstructions.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,8 +354,8 @@ uint16_t CmdNotImplemented(uint8_t *Buffer, uint16_t ByteCount) {
uint16_t EV0CmdGetVersion1(uint8_t *Buffer, uint16_t ByteCount) {
Buffer[0] = STATUS_ADDITIONAL_FRAME;
Buffer[1] = Picc.ManufacturerID;
Buffer[2] = Picc.TagType;
Buffer[3] = Picc.TagSubtype;
Buffer[2] = Picc.HwType;
Buffer[3] = Picc.HwSubtype;
GetPiccHardwareVersionInfo(&Buffer[4]);
Buffer[7] = Picc.HwProtocolType;
DesfireState = DESFIRE_GET_VERSION2;
Expand All @@ -365,8 +365,8 @@ uint16_t EV0CmdGetVersion1(uint8_t *Buffer, uint16_t ByteCount) {
uint16_t EV0CmdGetVersion2(uint8_t *Buffer, uint16_t ByteCount) {
Buffer[0] = STATUS_ADDITIONAL_FRAME;
Buffer[1] = Picc.ManufacturerID;
Buffer[2] = Picc.TagType;
Buffer[3] = Picc.TagSubtype;
Buffer[2] = Picc.SwType;
Buffer[3] = Picc.SwSubtype;
GetPiccSoftwareVersionInfo(&Buffer[4]);
Buffer[7] = Picc.SwProtocolType;
DesfireState = DESFIRE_GET_VERSION3;
Expand Down Expand Up @@ -445,8 +445,8 @@ uint16_t EV0CmdAuthenticateLegacy1(uint8_t *Buffer, uint16_t ByteCount) {
BYTE CryptoChallengeResponseSize;

/* Reset authentication state right away */
InvalidateAuthState(true);
if (!AuthenticatedWithPICCMasterKey && SelectedApp.Slot != DESFIRE_PICC_APP_SLOT) {
InvalidateAuthState(AuthenticatedWithPICCMasterKey && SelectedApp.Slot != DESFIRE_PICC_APP_SLOT);
if (!Authenticated && !AuthenticatedWithPICCMasterKey && SelectedApp.Slot != DESFIRE_PICC_APP_SLOT) {
Buffer[0] = STATUS_PERMISSION_DENIED;
return DESFIRE_STATUS_RESPONSE_SIZE;
}
Expand Down Expand Up @@ -1693,8 +1693,8 @@ uint16_t DesfireCmdAuthenticate3KTDEA1(uint8_t *Buffer, uint16_t ByteCount) {
BYTE *Key, *IV;

/* Reset authentication state right away */
InvalidateAuthState(true);
if (!AuthenticatedWithPICCMasterKey && SelectedApp.Slot != DESFIRE_PICC_APP_SLOT) {
InvalidateAuthState(AuthenticatedWithPICCMasterKey && SelectedApp.Slot != DESFIRE_PICC_APP_SLOT);
if (!Authenticated && !AuthenticatedWithPICCMasterKey && SelectedApp.Slot != DESFIRE_PICC_APP_SLOT) {
Buffer[0] = STATUS_PERMISSION_DENIED;
return DESFIRE_STATUS_RESPONSE_SIZE;
}
Expand Down Expand Up @@ -1876,8 +1876,8 @@ uint16_t DesfireCmdAuthenticateAES1(uint8_t *Buffer, uint16_t ByteCount) {
BYTE Status;

/* Reset authentication state right away */
InvalidateAuthState(true);
if (!AuthenticatedWithPICCMasterKey && SelectedApp.Slot != DESFIRE_PICC_APP_SLOT) {
InvalidateAuthState(AuthenticatedWithPICCMasterKey && SelectedApp.Slot != DESFIRE_PICC_APP_SLOT);
if (!Authenticated && !AuthenticatedWithPICCMasterKey && SelectedApp.Slot != DESFIRE_PICC_APP_SLOT) {
Buffer[0] = STATUS_PERMISSION_DENIED;
return DESFIRE_STATUS_RESPONSE_SIZE;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ uint16_t AllocateBlocksMain(uint16_t BlockCount) {
uint16_t Block;
/* Check if we have space */
Block = Picc.FirstFreeBlock;
if (Block + BlockCount < Block || Block + BlockCount >= MEMORY_SIZE_PER_SETTING / BLOCKWISE_IO_MULTIPLIER) {
if (Block + BlockCount < Block || Block + BlockCount >= StorageSizeToBytes(Picc.StorageSize) || Block + BlockCount >= MEMORY_SIZE_PER_SETTING / BLOCKWISE_IO_MULTIPLIER) {
return 0;
}
Picc.FirstFreeBlock = Block + BlockCount;
Expand All @@ -72,23 +72,40 @@ uint16_t AllocateBlocksMain(uint16_t BlockCount) {

uint8_t GetCardCapacityBlocks(void) {
uint8_t MaxFreeBlocks;

switch (Picc.StorageSize) {
case DESFIRE_STORAGE_SIZE_2K:
MaxFreeBlocks = 0x40 - DESFIRE_FIRST_FREE_BLOCK_ID;
MaxFreeBlocks = 0x100 - DESFIRE_FIRST_FREE_BLOCK_ID;
break;
case DESFIRE_STORAGE_SIZE_4K:
MaxFreeBlocks = 0x80 - DESFIRE_FIRST_FREE_BLOCK_ID;
MaxFreeBlocks = 0x200 - DESFIRE_FIRST_FREE_BLOCK_ID;
break;
case DESFIRE_STORAGE_SIZE_8K:
MaxFreeBlocks = (BYTE)(0x100 - DESFIRE_FIRST_FREE_BLOCK_ID);
MaxFreeBlocks = (BYTE)(0x400 - DESFIRE_FIRST_FREE_BLOCK_ID);
break;
default:
return 0;
}
return MaxFreeBlocks - Picc.FirstFreeBlock;
}

uint16_t StorageSizeToBytes(uint8_t StorageSize) {
uint16_t ByteSize = 0x0000;
switch (StorageSize) {
case DESFIRE_STORAGE_SIZE_2K:
ByteSize = 0x0400;
break;
case DESFIRE_STORAGE_SIZE_4K:
ByteSize = 0x0800;
break;
case DESFIRE_STORAGE_SIZE_8K:
ByteSize = 0x1000;
break;
default:
break;
}
return ByteSize;
}

void MemoryStoreDesfireHeaderBytes(void) {
memcpy(&(GlobalSettings.ActiveSettingPtr->PiccHeaderData), &Picc, sizeof(Picc));
SettingsSave();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ uint16_t AllocateBlocksMain(uint16_t BlockCount);
#define AllocateBlocks(BlockCount) AllocateBlocksMain(BlockCount);

BYTE GetCardCapacityBlocks(void);
uint16_t StorageSizeToBytes(uint8_t StorageSize);

void MemoryStoreDesfireHeaderBytes(void);
void MemoryRestoreDesfireHeaderBytes(bool LoadSettings);
Expand Down
38 changes: 15 additions & 23 deletions Firmware/Chameleon-Mini/Application/DESFire/DESFirePICCControl.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,6 @@ void InitialisePiccBackendEV0(uint8_t StorageSize, bool formatPICC) {
MemoryRecall();
ReadBlockBytes(&Picc, DESFIRE_PICC_INFO_BLOCK_ID, sizeof(DESFirePICCInfoType));
if (formatPICC) {
DEBUG_PRINT_P(PSTR("Factory reset -- EV0"));
DesfireLogEntry(LOG_INFO_DESFIRE_PICC_RESET, (void *) NULL, 0);
FactoryFormatPiccEV0();
} else {
Expand All @@ -189,7 +188,6 @@ void InitialisePiccBackendEV1(uint8_t StorageSize, bool formatPICC) {
MemoryRecall();
ReadBlockBytes(&Picc, DESFIRE_PICC_INFO_BLOCK_ID, sizeof(DESFirePICCInfoType));
if (formatPICC) {
DEBUG_PRINT_P(PSTR("Factory reset -- EV1"));
DesfireLogEntry(LOG_INFO_DESFIRE_PICC_RESET, (void *) NULL, 0);
FactoryFormatPiccEV1(StorageSize);
} else {
Expand All @@ -209,7 +207,6 @@ void InitialisePiccBackendEV2(uint8_t StorageSize, bool formatPICC) {
MemoryRecall();
ReadBlockBytes(&Picc, DESFIRE_PICC_INFO_BLOCK_ID, sizeof(DESFirePICCInfoType));
if (formatPICC) {
DEBUG_PRINT_P(PSTR("Factory reset -- EV1"));
DesfireLogEntry(LOG_INFO_DESFIRE_PICC_RESET, (void *) NULL, 0);
FactoryFormatPiccEV2(StorageSize);
} else {
Expand All @@ -232,26 +229,21 @@ bool IsEmulatingEV1(void) {
void GetPiccHardwareVersionInfo(uint8_t *Buffer) {
Buffer[0] = Picc.HwVersionMajor;
Buffer[1] = Picc.HwVersionMinor;
Buffer[2] = Picc.StorageSize;
Buffer[2] = DESFIRE_STORAGE_SIZE_8K;
}

void GetPiccSoftwareVersionInfo(uint8_t *Buffer) {
Buffer[0] = Picc.SwVersionMajor;
Buffer[1] = Picc.SwVersionMinor;
uint8_t freeMemoryBytes = (uint8_t)(GetCardCapacityBlocks() * DESFIRE_BLOCK_SIZE);
Buffer[2] = freeMemoryBytes;
Buffer[2] = Picc.StorageSize;
}

void GetPiccManufactureInfo(uint8_t *Buffer) {
/* UID / serial number does not depend on card mode: */
memcpy(&Buffer[1], &Picc.Uid[0], DESFIRE_UID_SIZE);
Buffer[7] = Picc.BatchNumber[0];
Buffer[8] = Picc.BatchNumber[1];
Buffer[9] = Picc.BatchNumber[2];
Buffer[10] = Picc.BatchNumber[3];
Buffer[11] = Picc.BatchNumber[4];
Buffer[12] = Picc.ProductionWeek;
Buffer[13] = Picc.ProductionYear;
memcpy(Buffer, &Picc.Uid[0], DESFIRE_UID_SIZE);
memcpy(&Buffer[DESFIRE_UID_SIZE], Picc.BatchNumber, 5);
Buffer[DESFIRE_UID_SIZE + 5] = Picc.ProductionWeek;
Buffer[DESFIRE_UID_SIZE + 6] = Picc.ProductionYear;
}

uint8_t GetPiccKeySettings(void) {
Expand All @@ -275,13 +267,15 @@ void FormatPicc(void) {
RandomGetBuffer(batchNumberData, 5);
memcpy(&Picc.BatchNumber[0], batchNumberData, 5);
/* Default production date -- until the user changes them: */
Picc.ProductionWeek = 0x32;
Picc.ProductionYear = 0x16;
Picc.ProductionWeek = 0x01;
Picc.ProductionYear = 0x05;
/* Assign the default manufacturer ID: */
Picc.ManufacturerID = DESFIRE_MANUFACTURER_ID;
Picc.TagType = DESFIRE_TYPE;
Picc.TagSubtype = DESFIRE_SUBTYPE;
Picc.HwType = DESFIRE_TYPE;
Picc.HwSubtype = DESFIRE_SUBTYPE;
Picc.HwProtocolType = DESFIRE_HW_PROTOCOL_TYPE;
Picc.SwType = DESFIRE_TYPE;
Picc.SwSubtype = DESFIRE_SUBTYPE;
Picc.SwProtocolType = DESFIRE_SW_PROTOCOL_TYPE;
/* Set the ATS bytes to defaults: */
Picc.ATSBytes[0] = DESFIRE_EV0_ATS_TL_BYTE;
Expand All @@ -295,8 +289,6 @@ void FormatPicc(void) {
SynchronizeAppDir();
/* Initialize the root app data */
CreatePiccApp();
//MemoryStore();
MemoryStoreDesfireHeaderBytes();
}

void CreatePiccApp(void) {
Expand Down Expand Up @@ -357,16 +349,16 @@ void FactoryFormatPiccEV2(uint8_t StorageSize) {
/* Reset the free block pointer */
Picc.FirstFreeBlock = DESFIRE_FIRST_FREE_BLOCK_ID;
/* Continue with user data initialization */
SynchronizePICCInfo();
FormatPicc();
SynchronizePICCInfo();
}

void GetPiccUid(ConfigurationUidType Uid) {
memcpy(Uid, Picc.Uid, DESFIRE_UID_SIZE);
memcpy(Uid, Picc.Uid, DESFIRE_UID_SIZE + 1);
}

void SetPiccUid(ConfigurationUidType Uid) {
memcpy(Picc.Uid, Uid, DESFIRE_UID_SIZE);
memcpy(&Picc.Uid[0], Uid, DESFIRE_UID_SIZE);
SynchronizePICCInfo();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,13 @@ typedef struct DESFIRE_FIRMWARE_PACKING DESFIRE_FIRMWARE_ALIGNAT {
uint8_t Uid[DESFIRE_UID_SIZE] DESFIRE_FIRMWARE_ALIGNAT;
uint8_t StorageSize;
uint8_t ManufacturerID;
uint8_t TagType;
uint8_t TagSubtype;
uint8_t HwType;
uint8_t HwSubtype;
uint8_t HwVersionMajor;
uint8_t HwVersionMinor;
uint8_t HwProtocolType;
uint8_t SwType;
uint8_t SwSubtype;
uint8_t SwVersionMajor;
uint8_t SwVersionMinor;
uint8_t SwProtocolType;
Expand Down
34 changes: 28 additions & 6 deletions Firmware/Chameleon-Mini/Application/MifareDESFire.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,8 @@ uint16_t MifareDesfireProcessCommand(uint8_t *Buffer, uint16_t ByteCount) {
ReturnBytes = DESFIRE_STATUS_RESPONSE_SIZE;
break;
}
/* Reset the state retry count */
StateRetryCount = 0;
return ReturnBytes;

}
Expand Down Expand Up @@ -254,8 +256,30 @@ uint16_t MifareDesfireAppProcess(uint8_t *Buffer, uint16_t BitCount) {
} else {
ISO14443ALastIncomingDataFrameBits = ISO14443AStoreLastDataFrameAndReturn(Buffer, BitCount);
}
if (ByteCount >= 3 && Buffer[2] == STATUS_ADDITIONAL_FRAME && DesfireStateExpectingAdditionalFrame(DesfireState)) {
/* [PM3-V1] : Handle the ISO-prologue-only-wrapped version of the additional frame data: */
if (ByteCount >= 8 && DesfireCLA(Buffer[1]) && Buffer[2] == STATUS_ADDITIONAL_FRAME &&
Buffer[3] == 0x00 && Buffer[4] == 0x00 && Buffer[5] == ByteCount - 8 &&
DesfireStateExpectingAdditionalFrame(DesfireState)) {
/* [PM3-V1] : Handle the native-wrapped version of the additional frame data: */
uint16_t checkSumPostVerifyBytes = DesfirePreprocessAPDUAndTruncate(ActiveCommMode, Buffer, ByteCount);
if (checkSumPostVerifyBytes == 0) {
return ISO14443A_APP_NO_RESPONSE;
}
uint8_t PrologueCounterByte = Buffer[0];
Buffer[0] = Buffer[2];
ByteCount = Buffer[5];
if (ByteCount > 0) {
memmove(&Buffer[1], &Buffer[6], ByteCount);
}
uint16_t ProcessedByteCount = MifareDesfireProcessCommand(Buffer, ByteCount + 1);
if (ProcessedByteCount == 0) {
return ISO14443A_APP_NO_RESPONSE;
}
/* Re-wrap into padded APDU form */
Buffer[0] = PrologueCounterByte;
uint16_t ProcessedByteCountWithCRCA = DesfirePostprocessAPDU(ActiveCommMode, Buffer, ProcessedByteCount + 1);
return ISO14443AStoreLastDataFrameAndReturn(Buffer, ASBITS(ProcessedByteCountWithCRCA));
} else if (ByteCount >= 3 && Buffer[2] == STATUS_ADDITIONAL_FRAME && DesfireStateExpectingAdditionalFrame(DesfireState)) {
/* [PM3-V2] : Handle the ISO-prologue-only-wrapped version of the additional frame data: */
uint8_t ISO7816PrologueBytes[2];
memcpy(&ISO7816PrologueBytes[0], &Buffer[0], 2);
uint16_t IncomingByteCount = DesfirePreprocessAPDUAndTruncate(ActiveCommMode, Buffer, ByteCount);
Expand All @@ -274,7 +298,7 @@ uint16_t MifareDesfireAppProcess(uint8_t *Buffer, uint16_t BitCount) {
} else if (ByteCount >= 6 && DesfireCLA(Buffer[0]) && Buffer[1] == STATUS_ADDITIONAL_FRAME &&
Buffer[2] == 0x00 && Buffer[3] == 0x00 && Buffer[4] == ByteCount - 8 &&
DesfireStateExpectingAdditionalFrame(DesfireState)) {
/* [PM3-V2] : Handle the native-wrapped version of the additional frame data: */
/* [PM3-V3] : Handle the native-wrapped version of the additional frame data: */
uint16_t checkSumPostVerifyBytes = DesfirePreprocessAPDUAndTruncate(ActiveCommMode, Buffer, ByteCount);
if (checkSumPostVerifyBytes == 0) {
return ISO14443A_APP_NO_RESPONSE;
Expand Down Expand Up @@ -418,16 +442,14 @@ void MifareDesfireReset(void) {
}

void ResetLocalStructureData(void) {
DesfireState = DesfirePreviousState = DESFIRE_IDLE;
InvalidateAuthState(false);
memset(&Picc, PICC_FORMAT_BYTE, sizeof(Picc));
memset(&AppDir, 0x00, sizeof(AppDir));
memset(&SelectedApp, 0x00, sizeof(SelectedApp));
memset(&SelectedFile, 0x00, sizeof(SelectedFile));
memset(&TransferState, 0x00, sizeof(TransferState));
SessionIVByteSize = 0;
SelectedApp.Slot = 0;
SelectedFile.Num = -1;
MifareDesfireReset();
ResetISOState();
}

Expand Down
8 changes: 4 additions & 4 deletions Software/DESFireLibNFCTesting/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ FILE_BASENAMES=NFCAntiCollisionMod \
TestKeyManagementCommands \
TestApplicationManagementCommands \
TestApplicationManagementCommands2 \
TestFileManagementCommandsSupport \
TestDataManipulationCommandsSupport \
TestDataManipulationCommandsSupport2 \
TestDataManipulationCommandsSupport3
TestFileManagementCommands \
TestDataManipulationCommands \
TestDataManipulationCommands2 \
TestDataManipulationCommands3

OBJFILES=$(addprefix $(OBJDIR)/, $(addsuffix .$(OBJEXT), $(basename $(FILE_BASENAMES))))
BINOUTS=$(addprefix $(BINDIR)/, $(addsuffix .$(BINEXT), $(basename $(FILE_BASENAMES))))
Expand Down

This file was deleted.

Loading

0 comments on commit aa20be6

Please sign in to comment.