autodetect file type

This commit is contained in:
merlokk 2021-07-27 21:24:51 +03:00
commit 8910fbac6f
3 changed files with 153 additions and 8 deletions

View file

@ -6325,9 +6325,44 @@ static int CmdHF14ADesReadData(const char *Cmd) {
}
}
// length of record for record file
size_t reclen = 0;
// get file settings
if (op == RFTAuto) {
FileSettingsS fsettings;
res = DesfireGetFileSettingsStruct(&dctx, fnum, &fsettings);
if (res == PM3_SUCCESS) {
switch(fsettings.fileType) {
case 0x00:
case 0x01: {
op = RFTData;
break;
}
case 0x02: {
op = RFTValue;
break;
}
case 0x03:
case 0x04: {
op = RFTRecord;
reclen = fsettings.recordSize;
break;
}
case 0x05: {
op = RFTMAC;
break;
}
default: {
break;
}
}
if (verbose)
PrintAndLogEx(INFO, "Got file type: %s. Option: %s", GetDesfireFileType(fsettings.fileType), CLIGetOptionListStr(DesfireReadFileTypeOpts, op));
} else {
PrintAndLogEx(WARNING, "GetFileSettings error. Can't get file type.");
}
}
PrintAndLogEx(INFO, "-------------- " _CYAN_("File data") " --------------");
@ -6363,14 +6398,16 @@ static int CmdHF14ADesReadData(const char *Cmd) {
}
if (op == RFTRecord) {
if (reclen == 0) {
res = DesfireReadRecords(&dctx, fnum, offset, 1, resp, &resplen);
if (res != PM3_SUCCESS) {
PrintAndLogEx(ERR, "Desfire ReadRecords (len=1) command " _RED_("error") ". Result: %d", res);
DropField();
return PM3_ESOFT;
}
reclen = resplen;
}
size_t reclen = resplen;
if (verbose)
PrintAndLogEx(INFO, "Record length %zu", reclen);

View file

@ -1067,6 +1067,16 @@ int DesfireGetFileSettings(DesfireContext *dctx, uint8_t fileid, uint8_t *resp,
return DesfireCommand(dctx, MFDES_GET_FILE_SETTINGS, &fileid, 1, resp, resplen, -1);
}
int DesfireGetFileSettingsStruct(DesfireContext *dctx, uint8_t fileid, FileSettingsS *fsettings) {
uint8_t resp[250] = {0};
size_t resplen = 0;
int res = DesfireGetFileSettings(dctx, fileid, resp, &resplen);
if (res == PM3_SUCCESS && resplen > 0 && fsettings != NULL)
DesfireFillFileSettings(resp, resplen, fsettings);
return res;
}
int DesfireCreateFile(DesfireContext *dctx, uint8_t ftype, uint8_t *fdata, size_t fdatalen, bool checklen) {
const DesfireCreateFileCommandsS *rcmd = GetDesfireFileCmdRec(ftype);
if (rcmd == NULL)
@ -1355,6 +1365,66 @@ void DesfirePrintAccessRight(uint8_t *data) {
PrintAndLogEx(SUCCESS, "change : %s", GetDesfireAccessRightStr(ch));
}
void DesfireFillFileSettings(uint8_t *data, size_t datalen, FileSettingsS *fsettings) {
if (fsettings == NULL)
return;
memset(fsettings, 0, sizeof(FileSettingsS));
if (datalen < 4)
return;
fsettings->fileType = data[0];
fsettings->fileOption = data[1];
fsettings->fileCommMode = data[1] & 0x03;
fsettings->additionalAccessRightsEn = ((data[1] & 0x80) != 0);
fsettings->rawAccessRights = MemLeToUint2byte(&data[2]);
DesfireDecodeFileAcessMode(&data[2], &fsettings->rAccess, &fsettings->wAccess, &fsettings->rwAccess, &fsettings->chAccess);
int reclen = 0;
switch (fsettings->fileType) {
case 0x00:
case 0x01: {
fsettings->fileSize = MemLeToUint3byte(&data[0]);
reclen = 4 + 3;
break;
}
case 0x02: {
fsettings->lowerLimit = MemLeToUint4byte(&data[0]);
fsettings->upperLimit = MemLeToUint4byte(&data[4]);
fsettings->value = MemLeToUint4byte(&data[8]);
fsettings->limitedCredit = data[12];
reclen = 4 + 13;
break;
}
case 0x03:
case 0x04: {
fsettings->recordSize = MemLeToUint3byte(&data[0]);
fsettings->maxRecordCount = MemLeToUint3byte(&data[3]);
fsettings->curRecordCount = MemLeToUint3byte(&data[6]);
reclen = 4 + 9;
break;
}
case 0x05: {
fsettings->keyType = data[0];
fsettings->keyVersion = data[1];
break;
}
default: {
break;
}
}
if (fsettings->additionalAccessRightsEn && reclen > 0 && datalen > reclen && datalen == reclen + data[reclen] * 2) {
fsettings->additionalAccessRightsLength = data[reclen];
for (int i = 0; i < fsettings->additionalAccessRightsLength; i++) {
fsettings->additionalAccessRights[i] = MemLeToUint2byte(&data[reclen + 1 + i * 2]);
}
}
}
static void DesfirePrintFileSettDynPart(uint8_t filetype, uint8_t *data, size_t datalen, uint8_t *dynlen, bool create) {
switch (filetype) {
case 0x00:
@ -1507,7 +1577,6 @@ void DesfirePrintCreateFileSettings(uint8_t filetype, uint8_t *data, size_t len)
xlen += reclen;
}
int DesfireChangeKey(DesfireContext *dctx, bool change_master_key, uint8_t newkeynum, DesfireCryptoAlgorythm newkeytype, uint32_t newkeyver, uint8_t *newkey, DesfireCryptoAlgorythm oldkeytype, uint8_t *oldkey, bool verbose) {
uint8_t okeybuf[DESFIRE_MAX_KEY_SIZE] = {0};

View file

@ -28,6 +28,43 @@ typedef struct {
const bool mayHaveISOfid;
} DesfireCreateFileCommandsS;
typedef struct {
// all
uint8_t fileType;
uint8_t fileOption;
uint8_t fileCommMode;
bool additionalAccessRightsEn;
uint16_t rawAccessRights;
uint8_t rAccess;
uint8_t wAccess;
uint8_t rwAccess;
uint8_t chAccess;
// data
uint32_t fileSize;
//value
uint32_t lowerLimit;
uint32_t upperLimit;
uint32_t value;
uint8_t limitedCredit;
// record
uint32_t recordSize;
uint32_t maxRecordCount;
uint32_t curRecordCount;
//mac
uint8_t keyType;
uint8_t key[16];
uint8_t keyVersion;
// additional rights
uint8_t additionalAccessRightsLength;
uint16_t additionalAccessRights[16];
} FileSettingsS;
typedef enum {
RFTAuto,
RFTData,
@ -84,7 +121,9 @@ int DesfireSetConfiguration(DesfireContext *dctx, uint8_t paramid, uint8_t *para
int DesfireGetFileIDList(DesfireContext *dctx, uint8_t *resp, size_t *resplen);
int DesfireGetFileISOIDList(DesfireContext *dctx, uint8_t *resp, size_t *resplen);
void DesfireFillFileSettings(uint8_t *data, size_t datalen, FileSettingsS *fsettings);
int DesfireGetFileSettings(DesfireContext *dctx, uint8_t fileid, uint8_t *resp, size_t *resplen);
int DesfireGetFileSettingsStruct(DesfireContext *dctx, uint8_t fileid, FileSettingsS *fsettings);
int DesfireChangeFileSettings(DesfireContext *dctx, uint8_t *data, size_t datalen);
const DesfireCreateFileCommandsS *GetDesfireFileCmdRec(uint8_t type);