diff --git a/Doc/DESFireSupportReadme.md b/Doc/DESFireSupportReadme.md index b8782f9a..76981c55 100644 --- a/Doc/DESFireSupportReadme.md +++ b/Doc/DESFireSupportReadme.md @@ -204,23 +204,6 @@ DF_SETHDR=ATS 0675f7b102 ``` Note that the UID for the tag can be set using separate Chameleon terminal commands. -#### DF_PPRINT_PICC -- Visualize tag contents - -This lets users pretty print the tag layout in several different ways, and with -a couple of options for verbosity. This helps with visualizing the landscape that -we are programming. The syntax include: -```bash -DF_PPRINT_PICC FullImage -DF_PPRINT_PICC HeaderData -``` - -#### DF_FWINFO -- Print firmware revision information - -Self explanatory and similar to the familiar ``VERSION`` command. Syntax: -```bash -DF_FWINFO -``` - #### DF_LOGMODE -- Sets the depth of (LIVE) logging messages printed at runtime Syntax -- not guaranteeing that all of these are meaningful or distinct just yet: diff --git a/Firmware/Chameleon-Mini/Application/DESFire/DESFireChameleonTerminal.c b/Firmware/Chameleon-Mini/Application/DESFire/DESFireChameleonTerminal.c index ac7b8e59..30dc9022 100644 --- a/Firmware/Chameleon-Mini/Application/DESFire/DESFireChameleonTerminal.c +++ b/Firmware/Chameleon-Mini/Application/DESFire/DESFireChameleonTerminal.c @@ -114,50 +114,6 @@ CommandStatusIdType CommandDESFireSetHeaderProperty(char *OutParam, const char * } #endif /* DISABLE_PERMISSIVE_DESFIRE_SETTINGS */ -#if 0 -CommandStatusIdType CommandDESFireLayoutPPrint(char *OutParam, const char *InParams) { - if (!IsDESFireConfiguration()) { - ExitOnInvalidConfigurationError(OutParam); - } - char pprintListSpecStr[32]; - BYTE StatusError = 0x00; - if (!sscanf_P(InParams, PSTR("%31s"), pprintListSpecStr)) { - StatusError = 0x01; - } else { - pprintListSpecStr[31] = '\0'; - if (!strcasecmp_P(pprintListSpecStr, PSTR("FullImage"))) { - PrettyPrintPICCImageData((BYTE *) OutParam, TERMINAL_BUFFER_SIZE, 0x01); - } else if (!strcasecmp_P(pprintListSpecStr, PSTR("HeaderData"))) { - PrettyPrintPICCHeaderData((BYTE *) OutParam, TERMINAL_BUFFER_SIZE, 0x01); - } else { - StatusError = 0x01; - } - } - if (StatusError) { - snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, - PSTR("%s "), - DFCOMMAND_LAYOUT_PPRINT); - return COMMAND_ERR_INVALID_USAGE_ID; - } - return COMMAND_INFO_OK_WITH_TEXT_ID; -} - -CommandStatusIdType CommandDESFireFirmwareInfo(char *OutParam) { - if (!IsDESFireConfiguration()) { - ExitOnInvalidConfigurationError(OutParam); - } - snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, - PSTR("Chameleon-Mini DESFire enabled firmware built on %s " - "based on %s from \r\n" - "https://github.com/maxieds/ChameleonMini.\r\n" - "Revision: %s\r\n"), - DESFIRE_FIRMWARE_BUILD_TIMESTAMP, - DESFIRE_FIRMWARE_GIT_COMMIT_ID, - DESFIRE_FIRMWARE_REVISION); - return COMMAND_INFO_OK_WITH_TEXT_ID; -} -#endif - CommandStatusIdType CommandDESFireGetLoggingMode(char *OutParam) { if (!IsDESFireConfiguration()) { ExitOnInvalidConfigurationError(OutParam); diff --git a/Firmware/Chameleon-Mini/Application/DESFire/DESFireChameleonTerminal.h b/Firmware/Chameleon-Mini/Application/DESFire/DESFireChameleonTerminal.h index 82b61a18..22d8f19c 100644 --- a/Firmware/Chameleon-Mini/Application/DESFire/DESFireChameleonTerminal.h +++ b/Firmware/Chameleon-Mini/Application/DESFire/DESFireChameleonTerminal.h @@ -42,12 +42,6 @@ CommandStatusIdType CommandDESFireGetHeaderProperty(char *OutParam); CommandStatusIdType CommandDESFireSetHeaderProperty(char *OutMessage, const char *InParams); #endif -//#define DFCOMMAND_LAYOUT_PPRINT "DF_PPRINT_PICC" -//CommandStatusIdType CommandDESFireLayoutPPrint(char *OutParam, const char *InParams); - -//#define DFCOMMAND_FIRMWARE_INFO "DF_FWINFO" -//CommandStatusIdType CommandDESFireFirmwareInfo(char *OutParam); - #define DFCOMMAND_LOGGING_MODE "DF_LOGMODE" CommandStatusIdType CommandDESFireGetLoggingMode(char *OutParam); CommandStatusIdType CommandDESFireSetLoggingMode(char *OutMessage, const char *InParams); diff --git a/Firmware/Chameleon-Mini/Application/DESFire/DESFireChameleonTerminalInclude.c b/Firmware/Chameleon-Mini/Application/DESFire/DESFireChameleonTerminalInclude.c index fcded7d3..41935c15 100644 --- a/Firmware/Chameleon-Mini/Application/DESFire/DESFireChameleonTerminalInclude.c +++ b/Firmware/Chameleon-Mini/Application/DESFire/DESFireChameleonTerminalInclude.c @@ -35,18 +35,6 @@ This notice must be retained at the top of all source files where indicated. .SetFunc = CommandDESFireSetHeaderProperty, .GetFunc = CommandDESFireGetHeaderProperty }, { -// .Command = DFCOMMAND_LAYOUT_PPRINT, -// .ExecFunc = NO_FUNCTION, -// .ExecParamFunc = CommandDESFireLayoutPPrint, -// .SetFunc = NO_FUNCTION, -// .GetFunc = NO_FUNCTION -//}, { -// .Command = DFCOMMAND_FIRMWARE_INFO, -// .ExecFunc = CommandDESFireFirmwareInfo, -// .ExecParamFunc = NO_FUNCTION, -// .SetFunc = NO_FUNCTION, -// .GetFunc = NO_FUNCTION -//}, { .Command = DFCOMMAND_LOGGING_MODE, .ExecFunc = NO_FUNCTION, .ExecParamFunc = NO_FUNCTION, diff --git a/Firmware/Chameleon-Mini/Application/DESFire/DESFireInstructions.c b/Firmware/Chameleon-Mini/Application/DESFire/DESFireInstructions.c index 19108d23..89883f4e 100644 --- a/Firmware/Chameleon-Mini/Application/DESFire/DESFireInstructions.c +++ b/Firmware/Chameleon-Mini/Application/DESFire/DESFireInstructions.c @@ -45,6 +45,68 @@ This notice must be retained at the top of all source files where indicated. DesfireSavedCommandStateType DesfireCommandState = { 0 }; +/* Helper and batch process functions */ +static uint16_t ExitWithStatus(uint8_t *Buffer, uint8_t StatusCode, uint16_t DefaultReturnValue); +uint16_t CmdNotImplemented(uint8_t *Buffer, uint16_t ByteCount); + +/* General commands */ +static uint16_t EV0CmdFormatPicc(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t DesfireCmdGetCardUID(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t DesfireCmdSetConfiguration(uint8_t *Buffer, uint16_t ByteCount); // ?? Docs ?? +static uint16_t DesfireCmdFreeMemory(uint8_t *Buffer, uint16_t ByteCount); // returns free memory on the tag + +/* Key management commands */ +static uint16_t EV0CmdChangeKey(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdGetKeySettings(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdChangeKeySettings(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t DesfireCmdGetKeyVersion(uint8_t *Buffer, uint16_t ByteCount); + +/* Application management commands */ +static uint16_t EV0CmdGetApplicationIds1(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdCreateApplication(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdDeleteApplication(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdSelectApplication(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t DesfireCmdGetDFNames(uint8_t *Buffer, uint16_t ByteCount); + +/* File management commands */ +static uint16_t EV0CmdCreateStandardDataFile(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdCreateBackupDataFile(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdCreateValueFile(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdCreateLinearRecordFile(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdCreateCyclicRecordFile(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdDeleteFile(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdGetFileIds(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdGetFileSettings(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdChangeFileSettings(uint8_t *Buffer, uint16_t ByteCount); + +/* Data manipulation commands */ +// NOTE: Page 57: Read file functions: +static uint16_t EV0CmdReadData(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdWriteData(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdGetValue(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdCredit(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdDebit(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdLimitedCredit(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdReadRecords(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdWriteRecord(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdClearRecords(uint8_t *Buffer, uint16_t ByteCount); + +/* Transaction handling commands */ +static uint16_t EV0CmdCommitTransaction(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t EV0CmdAbortTransaction(uint8_t *Buffer, uint16_t ByteCount); + +/* ISO7816 command handling */ +static uint16_t ISO7816CmdSelect(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t ISO7816CmdSelectEF(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t ISO7816CmdSelectDF(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t ISO7816CmdGetChallenge(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t ISO7816CmdExternalAuthenticate(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t ISO7816CmdInternalAuthenticate(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t ISO7816CmdReadBinary(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t ISO7816CmdUpdateBinary(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t ISO7816CmdReadRecords(uint8_t *Buffer, uint16_t ByteCount); +static uint16_t ISO7816CmdAppendRecord(uint8_t *Buffer, uint16_t ByteCount); + /* NOTE: The order of the structures in this buffer MUST be kept in * ascending sorted order by the INS code. This property of the * array has to be maintained as new commands and functions are diff --git a/Firmware/Chameleon-Mini/Application/DESFire/DESFireInstructions.h b/Firmware/Chameleon-Mini/Application/DESFire/DESFireInstructions.h index fe6ea521..106a7dbb 100644 --- a/Firmware/Chameleon-Mini/Application/DESFire/DESFireInstructions.h +++ b/Firmware/Chameleon-Mini/Application/DESFire/DESFireInstructions.h @@ -122,81 +122,21 @@ extern const __flash DESFireCommand DESFireCommandSet[]; /* Helper and batch process functions */ uint16_t CallInstructionHandler(uint8_t *Buffer, uint16_t ByteCount); -uint16_t ExitWithStatus(uint8_t *Buffer, uint8_t StatusCode, uint16_t DefaultReturnValue); -uint16_t CmdNotImplemented(uint8_t *Buffer, uint16_t ByteCount); /* * The following section implements: * DESFire EV0 / D40 specific commands */ -/* General commands */ uint16_t EV0CmdGetVersion1(uint8_t *Buffer, uint16_t ByteCount); uint16_t EV0CmdGetVersion2(uint8_t *Buffer, uint16_t ByteCount); uint16_t EV0CmdGetVersion3(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdFormatPicc(uint8_t *Buffer, uint16_t ByteCount); -uint16_t DesfireCmdGetCardUID(uint8_t *Buffer, uint16_t ByteCount); -uint16_t DesfireCmdSetConfiguration(uint8_t *Buffer, uint16_t ByteCount); // ?? Docs ?? -uint16_t DesfireCmdFreeMemory(uint8_t *Buffer, uint16_t ByteCount); // returns free memory on the tag - -/* Key management commands */ -uint16_t EV0CmdChangeKey(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdGetKeySettings(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdChangeKeySettings(uint8_t *Buffer, uint16_t ByteCount); -uint16_t DesfireCmdGetKeyVersion(uint8_t *Buffer, uint16_t ByteCount); - -/* Application management commands */ -uint16_t EV0CmdGetApplicationIds1(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdCreateApplication(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdDeleteApplication(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdSelectApplication(uint8_t *Buffer, uint16_t ByteCount); -uint16_t DesfireCmdGetDFNames(uint8_t *Buffer, uint16_t ByteCount); - -/* File management commands */ -uint16_t EV0CmdCreateStandardDataFile(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdCreateBackupDataFile(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdCreateValueFile(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdCreateLinearRecordFile(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdCreateCyclicRecordFile(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdDeleteFile(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdGetFileIds(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdGetFileSettings(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdChangeFileSettings(uint8_t *Buffer, uint16_t ByteCount); - -/* Data manipulation commands */ -// NOTE: Page 57: Read file functions: -uint16_t EV0CmdReadData(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdWriteData(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdGetValue(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdCredit(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdDebit(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdLimitedCredit(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdReadRecords(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdWriteRecord(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdClearRecords(uint8_t *Buffer, uint16_t ByteCount); - -/* Transaction handling commands */ -uint16_t EV0CmdCommitTransaction(uint8_t *Buffer, uint16_t ByteCount); -uint16_t EV0CmdAbortTransaction(uint8_t *Buffer, uint16_t ByteCount); - -/* EV1/EV2 supported commands */ uint16_t EV0CmdAuthenticateLegacy1(uint8_t *Buffer, uint16_t ByteCount); uint16_t EV0CmdAuthenticateLegacy2(uint8_t *Buffer, uint16_t ByteCount); + uint16_t DesfireCmdAuthenticate3KTDEA1(uint8_t *Buffer, uint16_t ByteCount); uint16_t DesfireCmdAuthenticate3KTDEA2(uint8_t *Buffer, uint16_t ByteCount); uint16_t DesfireCmdAuthenticateAES1(uint8_t *Buffer, uint16_t ByteCount); uint16_t DesfireCmdAuthenticateAES2(uint8_t *Buffer, uint16_t ByteCount); -/* ISO7816 command handling */ -uint16_t ISO7816CmdSelect(uint8_t *Buffer, uint16_t ByteCount); -uint16_t ISO7816CmdSelectEF(uint8_t *Buffer, uint16_t ByteCount); -uint16_t ISO7816CmdSelectDF(uint8_t *Buffer, uint16_t ByteCount); -uint16_t ISO7816CmdGetChallenge(uint8_t *Buffer, uint16_t ByteCount); -uint16_t ISO7816CmdExternalAuthenticate(uint8_t *Buffer, uint16_t ByteCount); -uint16_t ISO7816CmdInternalAuthenticate(uint8_t *Buffer, uint16_t ByteCount); -uint16_t ISO7816CmdReadBinary(uint8_t *Buffer, uint16_t ByteCount); -uint16_t ISO7816CmdUpdateBinary(uint8_t *Buffer, uint16_t ByteCount); -uint16_t ISO7816CmdReadRecords(uint8_t *Buffer, uint16_t ByteCount); -uint16_t ISO7816CmdAppendRecord(uint8_t *Buffer, uint16_t ByteCount); - #endif diff --git a/Firmware/Chameleon-Mini/Application/DESFire/DESFirePICCHeaderLayout.c b/Firmware/Chameleon-Mini/Application/DESFire/DESFirePICCHeaderLayout.c deleted file mode 100644 index f0ab5439..00000000 --- a/Firmware/Chameleon-Mini/Application/DESFire/DESFirePICCHeaderLayout.c +++ /dev/null @@ -1,248 +0,0 @@ -/* -The DESFire stack portion of this firmware source -is free software written by Maxie Dion Schmidt (@maxieds): -You can redistribute it and/or modify -it under the terms of this license. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -The complete source distribution of -this firmware is available at the following link: -https://github.com/maxieds/ChameleonMiniFirmwareDESFireStack. - -Based in part on the original DESFire code created by -@dev-zzo (GitHub handle) [Dmitry Janushkevich] available at -https://github.com/dev-zzo/ChameleonMini/tree/desfire. - -This notice must be retained at the top of all source files where indicated. -*/ - -/* - * DESFirePICCHeaderLayout.c - * Maxie D. Schmidt (github.com/maxieds) - */ - -#ifdef CONFIG_MF_DESFIRE_SUPPORT - -#include "../../Common.h" - -#include "DESFirePICCHeaderLayout.h" -#include "DESFirePICCControl.h" -#include "DESFireFile.h" -#include "DESFireLogging.h" -#include "DESFireStatusCodes.h" - -SIZET PrettyPrintPICCHeaderData(BYTE *outputBuffer, SIZET maxLength, BYTE verbose) { - SIZET charsWritten = 0x00; - charsWritten = snprintf_P(outputBuffer, maxLength, - PSTR("(UID) %s\r\n"), - GetHexBytesString(Picc.Uid, DESFIRE_UID_SIZE)); - charsWritten += snprintf_P(outputBuffer + charsWritten, maxLength - charsWritten, - PSTR("(VERSION) HW=%02x.%02x, SW=%02x.%02x\r\n"), - Picc.HwVersionMajor, Picc.HwVersionMinor, - Picc.SwVersionMajor, Picc.SwVersionMinor); - charsWritten += snprintf_P(outputBuffer + charsWritten, maxLength - charsWritten, - PSTR("(BATCH) %s\r\n"), - GetHexBytesString(Picc.BatchNumber, 5)); - charsWritten += snprintf_P(outputBuffer + charsWritten, maxLength - charsWritten, - PSTR("(DATE) %02x/%02x\r\n"), - Picc.ProductionWeek, Picc.ProductionYear); - BYTE atsBytes[6]; - memcpy(&atsBytes[0], Picc.ATSBytes, 5); - atsBytes[5] = 0x80; - BufferToHexString(__InternalStringBuffer, STRING_BUFFER_SIZE, atsBytes, 6); - charsWritten += snprintf_P(outputBuffer + charsWritten, maxLength - charsWritten, - PSTR("(ATS) %s\r\n"), __InternalStringBuffer); - return charsWritten; -} - -SIZET PrettyPrintFileContentsData(BYTE *outputBuffer, SIZET maxLength, BYTE fileNumber) { - DESFireFileTypeSettings *fileData; - if (ReadFileControlBlock(fileNumber, &SelectedFile) != STATUS_OPERATION_OK) { - return 0; - } - fileData = &SelectedFile; - switch (fileData->FileType) { - case DESFIRE_FILE_STANDARD_DATA: - return snprintf_P(outputBuffer, maxLength, - PSTR(" STD-DATA @ % 3d bytes\r\n"), - fileData->FileSize); - case DESFIRE_FILE_BACKUP_DATA: - return snprintf_P(outputBuffer, maxLength, - PSTR(" BKUP-DATA @ % 3d bytes -- BlkCount = %d\r\n"), - fileData->FileSize, fileData->BackupFile.BlockCount); - case DESFIRE_FILE_VALUE_DATA: - return snprintf_P(outputBuffer, maxLength, - PSTR(" VALUE @ Cln=%d|Dty=%d (PrevDebit=%d) in [%d, %d] with LimitedCredit=%c\r\n"), - fileData->ValueFile.CleanValue, fileData->ValueFile.DirtyValue, fileData->ValueFile.PreviousDebit, - fileData->ValueFile.LowerLimit, fileData->ValueFile.UpperLimit, - fileData->ValueFile.LimitedCreditEnabled == 0 ? 'N' : 'Y'); - case DESFIRE_FILE_LINEAR_RECORDS: - case DESFIRE_FILE_CIRCULAR_RECORDS: - return snprintf_P(outputBuffer, maxLength, - PSTR(" RECORD @ [Type=%c] RcdSize=0x%06x|CurNumRcds=0x%06x|MaxRcds=0x%06x\r\n"), - fileData->FileType == DESFIRE_FILE_LINEAR_RECORDS ? 'L' : 'C', - GET_LE24(fileData->RecordFile.RecordSize), - GET_LE24(fileData->RecordFile.CurrentNumRecords), - GET_LE24(fileData->RecordFile.MaxRecordCount)); - default: - break; - } - return 0; -} - -SIZET PrettyPrintPICCFile(SelectedAppCacheType *appData, uint8_t fileIndex, - BYTE *outputBuffer, SIZET maxLength, BYTE verbose) { - BYTE charsWritten = 0x00; - BYTE fileNumber = LookupFileNumberByIndex(appData->Slot, fileIndex); - if (fileNumber >= DESFIRE_MAX_FILES) { - return charsWritten; - } - if (verbose) { - BYTE fileCommSettings = ReadFileCommSettings(appData->Slot, fileIndex); - SIZET fileAccessRights = ReadFileAccessRights(appData->Slot, fileIndex); - strncpy_P(__InternalStringBuffer2, GetCommSettingsDesc(fileCommSettings), DATA_BUFFER_SIZE_SMALL); - __InternalStringBuffer2[DATA_BUFFER_SIZE_SMALL - 1] = '\0'; - charsWritten += snprintf_P(outputBuffer + charsWritten, maxLength - charsWritten, - PSTR(" -> No. %02x [Comm=%s -- Perms=%s]\r\n"), - fileNumber, __InternalStringBuffer2, - GetFileAccessPermissionsDesc(fileAccessRights)); - //charsWritten += PrettyPrintFileContentsData(outputBuffer + charsWritten, maxLength - charsWritten, fileIndex); - } else { - charsWritten += snprintf_P(outputBuffer + charsWritten, maxLength - charsWritten, - PSTR(" -> No. %02x\r\n"), - fileNumber); - } - return charsWritten; -} - -SIZET PrettyPrintPICCFilesFull(SelectedAppCacheType *appData, BYTE *outputBuffer, SIZET maxLength, BYTE verbose) { - SIZET charsWritten = 0x00; - BYTE fileIndex; - charsWritten += snprintf_P(outputBuffer + charsWritten, maxLength - charsWritten, - PSTR(" [FILES -- %d of %d]\r\n"), - appData->FileCount, DESFIRE_MAX_FILES); - uint8_t fileNumberIndexMap[DESFIRE_MAX_FILES]; - ReadBlockBytes(&fileNumberIndexMap, appData->FileNumbersArrayMap, DESFIRE_MAX_FILES); - for (fileIndex = 0; fileIndex < DESFIRE_MAX_FILES; fileIndex++) { - if (fileNumberIndexMap[fileIndex] == DESFIRE_FILE_NOFILE_INDEX) { - continue; - } - charsWritten += PrettyPrintPICCFile(appData, fileIndex, outputBuffer + charsWritten, - maxLength - charsWritten, verbose); - } - return charsWritten; -} - -SIZET PrettyPrintPICCKey(SelectedAppCacheType *appData, uint8_t keyIndex, - BYTE *outputBuffer, SIZET maxLength, BYTE verbose) { - if (!KeyIdValid(appData->Slot, keyIndex)) { - return 0x00; - } - BYTE charsWritten = 0x00; - BYTE keySettings = ReadKeySettings(appData->Slot, keyIndex); - BYTE keyVersion = ReadKeyVersion(appData->Slot, keyIndex); - BYTE keyType = ReadKeyCryptoType(appData->Slot, keyIndex); - strncpy_P(__InternalStringBuffer, GetCryptoMethodDesc(keyType), STRING_BUFFER_SIZE); - __InternalStringBuffer[STRING_BUFFER_SIZE - 1] = '\0'; - charsWritten += snprintf_P(outputBuffer + charsWritten, maxLength - charsWritten, - PSTR(" -> No. %02x (%s) [v% 2d"), - keyIndex, __InternalStringBuffer, keyVersion); - if ((appData->Slot == DESFIRE_PICC_APP_SLOT) && (keyIndex == DESFIRE_MASTER_KEY_ID)) { - charsWritten += snprintf_P(outputBuffer + charsWritten, maxLength - charsWritten, - PSTR(" -- PMK")); - if (verbose) { - charsWritten += snprintf_P(outputBuffer + charsWritten, maxLength - charsWritten, - PSTR(" -- S=%02x"), keySettings); - } - } else if (keyIndex == DESFIRE_MASTER_KEY_ID) { - charsWritten += snprintf_P(outputBuffer + charsWritten, maxLength - charsWritten, - PSTR(" -- AMK")); - if (verbose) { - charsWritten += snprintf_P(outputBuffer + charsWritten, maxLength - charsWritten, - PSTR(" -- S=%02x"), keySettings); - } - } else if (verbose) { - charsWritten += snprintf_P(outputBuffer + charsWritten, maxLength - charsWritten, - PSTR(" -- %02d"), keySettings); - } - charsWritten += snprintf_P(outputBuffer + charsWritten, maxLength - charsWritten, - PSTR("]\r\n")); - /*if(verbose) { - uint8_t keySize = GetDefaultCryptoMethodKeySize(keyType); - uint8_t keyData[keySize]; - ReadAppKey(appData->Slot, keyIndex, &keyData[0], keySize); - charsWritten += snprintf_P(outputBuffer + charsWritten, maxLength - charsWritten, - PSTR(" KeyData @ % 2 bytes = "), - keySize); - charsWritten += BufferToHexString(outputBuffer + charsWritten, maxLength - charsWritten, keyData, keySize); - charsWritten += snprintf(outputBuffer + charsWritten, maxLength - charsWritten, PSTR("\r\n")); - }*/ - return charsWritten; -} - -SIZET PrettyPrintPICCKeysFull(SelectedAppCacheType *appData, BYTE *outputBuffer, SIZET maxLength, BYTE verbose) { - SIZET charsWritten = 0x00; - BYTE keyIndex; - charsWritten += snprintf_P(outputBuffer + charsWritten, maxLength - charsWritten, - PSTR(" [KEYS -- %d of %d]\r\n"), - appData->KeyCount, appData->MaxKeyCount); - uint16_t keyDataAddresses[DESFIRE_MAX_KEYS]; - ReadBlockBytes(&keyDataAddresses, ReadKeyStorageAddress(appData->Slot), 2 * DESFIRE_MAX_KEYS); - for (keyIndex = 0; keyIndex < DESFIRE_MAX_KEYS; keyIndex++) { - if (keyDataAddresses[keyIndex] == 0) { - continue; - } - charsWritten += PrettyPrintPICCKey(appData, keyIndex, outputBuffer + charsWritten, - maxLength - charsWritten, verbose); - } - return charsWritten; -} - -SIZET PrettyPrintPICCAppDir(uint8_t appIndex, BYTE *outputBuffer, SIZET maxLength, BYTE verbose) { - SIZET charsWritten = 0x00; - BYTE keyIndex, fileIndex; - SelectedAppCacheType appData; - if (!GetAppData(appIndex, &appData)) { - return charsWritten; - } - appData.Slot = appIndex; - charsWritten += PrettyPrintPICCKeysFull(&appData, outputBuffer + charsWritten, - maxLength - charsWritten, verbose); - if (appIndex == 0) { // master - return charsWritten; - } - charsWritten += PrettyPrintPICCFilesFull(&appData, outputBuffer + charsWritten, - maxLength - charsWritten, verbose); - return charsWritten; -} - -SIZET PrettyPrintPICCAppDirsFull(BYTE *outputBuffer, SIZET maxLength, BYTE verbose) { - SIZET charsWritten = 0x00; - BYTE appDirIndex; - for (appDirIndex = 0; appDirIndex < DESFIRE_MAX_SLOTS; appDirIndex++) { - DESFireAidType curAID; - memcpy(curAID, AppDir.AppIds[appDirIndex], MAX_AID_SIZE); - if ((curAID[0] | curAID[1] | curAID[2]) == 0x00 && appDirIndex > 0) { - continue; - } - charsWritten += snprintf_P(outputBuffer + charsWritten, maxLength - charsWritten, - PSTR("== AID 0x%02x%02x%02x\r\n"), - curAID[0], curAID[1], curAID[2]); - charsWritten += PrettyPrintPICCAppDir(appDirIndex, outputBuffer + charsWritten, - maxLength - charsWritten, verbose); - } - return charsWritten; -} - -SIZET PrettyPrintPICCImageData(BYTE *outputBuffer, SIZET maxLength, BYTE verbose) { - BYTE charsWritten = 0x00; - charsWritten += PrettyPrintPICCHeaderData(outputBuffer + charsWritten, maxLength - charsWritten, verbose); - charsWritten += PrettyPrintPICCAppDirsFull(outputBuffer + charsWritten, maxLength - charsWritten, verbose); - outputBuffer[maxLength - 1] = '\0'; - return charsWritten; -} - -#endif /* CONFIG_MF_DESFIRE_SUPPORT */ diff --git a/Firmware/Chameleon-Mini/Application/DESFire/DESFirePICCHeaderLayout.h b/Firmware/Chameleon-Mini/Application/DESFire/DESFirePICCHeaderLayout.h index 5d5c06e7..db6abd1b 100644 --- a/Firmware/Chameleon-Mini/Application/DESFire/DESFirePICCHeaderLayout.h +++ b/Firmware/Chameleon-Mini/Application/DESFire/DESFirePICCHeaderLayout.h @@ -228,17 +228,4 @@ typedef enum DESFIRE_FIRMWARE_ENUM_PACKING { DESFIRE_APP_KEYS_PTR_BLOCK_ID, } DesfireCardLayout; -SIZET PrettyPrintPICCHeaderData(BYTE *outputBuffer, SIZET maxLength, BYTE verbose); -SIZET PrettyPrintFileContentsData(BYTE *outputBuffer, SIZET maxLength, BYTE fileNumber); -SIZET PrettyPrintPICCFile(SelectedAppCacheType *appData, uint8_t fileIndex, - BYTE *outputBuffer, SIZET maxLength, BYTE verbose); -SIZET PrettyPrintPICCFilesFull(SelectedAppCacheType *appData, BYTE *outputBuffer, SIZET maxLength, BYTE verbose); -SIZET PrettyPrintPICCKey(SelectedAppCacheType *appData, uint8_t keyIndex, - BYTE *outputBuffer, SIZET maxLength, BYTE verbose); -SIZET PrettyPrintPICCKeysFull(SelectedAppCacheType *appData, BYTE *outputBuffer, SIZET maxLength, BYTE verbose); -SIZET PrettyPrintPICCAppDir(uint8_t appIndex, - BYTE *outputBuffer, SIZET maxLength, BYTE verbose); -SIZET PrettyPrintPICCAppDirsFull(BYTE *outputBuffer, SIZET maxLength, BYTE verbose); -SIZET PrettyPrintPICCImageData(BYTE *outputBuffer, SIZET maxLength, BYTE verbose); - #endif diff --git a/Firmware/Chameleon-Mini/Application/MifareDESFire.c b/Firmware/Chameleon-Mini/Application/MifareDESFire.c index 37694857..3f9f2712 100644 --- a/Firmware/Chameleon-Mini/Application/MifareDESFire.c +++ b/Firmware/Chameleon-Mini/Application/MifareDESFire.c @@ -51,9 +51,12 @@ DesfireStateType DesfireState = DESFIRE_HALT; DesfireStateType DesfirePreviousState = DESFIRE_IDLE; bool DesfireFromHalt = false; BYTE DesfireCmdCLA = DESFIRE_NATIVE_CLA; +static bool AnticolNoResp = false; /* Dispatching routines */ -void MifareDesfireReset(void) {} +void MifareDesfireReset(void) { + AnticolNoResp = false; +} static void MifareDesfireAppInitLocal(uint8_t StorageSize, uint8_t Version, bool FormatPICC) { ResetLocalStructureData(); @@ -247,12 +250,18 @@ uint16_t MifareDesfireAppProcess(uint8_t *Buffer, uint16_t BitCount) { return ProcessedBitCount; } else if ((ReturnedBytes = CallInstructionHandler(Buffer, ByteCount)) != ISO14443A_APP_NO_RESPONSE) { return ReturnedBytes; - } else { - return ISO144433APiccProcess(Buffer, BitCount); + } else if (!AnticolNoResp) { + uint16_t PiccProcessRespBytes = ISO144433APiccProcess(Buffer, BitCount); + if (PiccProcessRespBytes == ISO14443A_APP_NO_RESPONSE) { + AnticolNoResp = true; + } + return PiccProcessRespBytes; } + return ISO14443A_APP_NO_RESPONSE; } void ResetLocalStructureData(void) { + AnticolNoResp = false; DesfirePreviousState = DESFIRE_IDLE; DesfireState = DESFIRE_HALT; InvalidateAuthState(0x00); diff --git a/Firmware/Chameleon-Mini/Makefile b/Firmware/Chameleon-Mini/Makefile index 7b5495cd..1a08f417 100644 --- a/Firmware/Chameleon-Mini/Makefile +++ b/Firmware/Chameleon-Mini/Makefile @@ -182,7 +182,6 @@ SRC += $(DESFIRE_MAINSRC)/../MifareDESFire.c \ $(DESFIRE_MAINSRC)/DESFireLogging.c \ $(DESFIRE_MAINSRC)/DESFireMemoryOperations.c \ $(DESFIRE_MAINSRC)/DESFirePICCControl.c \ - $(DESFIRE_MAINSRC)/DESFirePICCHeaderLayout.c \ $(DESFIRE_MAINSRC)/DESFireUtils.c SRC += $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS) LUFA_PATH = ../LUFA