create value file works

This commit is contained in:
merlokk
2021-07-26 13:59:13 +03:00
parent 235c1fc9c3
commit 64b3dcc2e2
3 changed files with 40 additions and 30 deletions

View File

@@ -6279,12 +6279,12 @@ static int CmdHF14ADesCreateFile(const char *Cmd) {
static int CmdHF14ADesCreateValueFile(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes createvaluefile",
"Create Standard/Backup file in the application. Application master key needs to be provided or flag --no-auth set (depend on application settings).",
"Create Value file in the application. Application master key needs to be provided or flag --no-auth set (depend on application settings).",
"--rawrights have priority over the separate rights settings.\n"
"Key/mode/etc of the authentication depends on application settings\n"
"hf mfdes createvaluefile --aid 123456 --fid 01 --rawtype 01 --rawdata 000100EEEE000100 -> create file via sending rawdata to the card. Can be used to create any type of file. Authentication with defaults from `default` command\n"
"hf mfdes createvaluefile --aid 123456 --fid 01 --lower 00000010 --upper 00010000 --value 00000100 -> create file with parameters. Rights from default. Authentication with defaults from `default` command\n"
"hf mfdes createvaluefile --aid 123456 --fid 01 --amode plain --rrights free --wrights free --rwrights free --chrights key0 -> create file app=123456, file=01 and mentioned rights with defaults from `default` command\n"
"hf mfdes createvaluefile -n 0 -t des -k 0000000000000000 -f none --aid 123456 --fid 01 --rawtype 00 --rawdata 00EEEE000100 -> execute with default factory setup");
"hf mfdes createvaluefile -n 0 -t des -k 0000000000000000 -f none --aid 123456 --fid 01 -> execute with default factory setup");
void *argtable[] = {
arg_param_begin,
@@ -6300,7 +6300,6 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) {
arg_str0("s", "schann", "<d40/ev1/ev2>", "Secure channel: d40/ev1/ev2"),
arg_str0(NULL, "aid", "<app id hex>", "Application ID (3 hex bytes, big endian)"),
arg_str0(NULL, "fid", "<file id hex>", "File ID (1 hex byte)"),
arg_str0(NULL, "isofid", "<iso file id hex>", "ISO File ID (2 hex bytes)"),
arg_str0(NULL, "amode", "<plain/mac/encrypt>", "File access mode: plain/mac/encrypt"),
arg_str0(NULL, "rawrights", "<access rights HEX>", "Access rights for file (HEX 2 byte) R/W/RW/Chg, 0x0 - 0xD Key, 0xE Free, 0xF Denied"),
arg_str0(NULL, "rrights", "<key0/../key13/free/deny>", "Read file access mode: the specified key, free, deny"),
@@ -6318,7 +6317,7 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) {
bool APDULogging = arg_get_lit(ctx, 1);
bool verbose = arg_get_lit(ctx, 2);
bool noauth = arg_get_lit(ctx, 20);
bool noauth = arg_get_lit(ctx, 19);
uint8_t filetype = 0x02; // value file
@@ -6346,14 +6345,14 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) {
uint8_t data[250] = {0};
size_t datalen = 0;
res = DesfireCreateFileParameters(ctx, 12, 13, 14, 15, 16, 17, 18, 19, data, &datalen);
res = DesfireCreateFileParameters(ctx, 12, 0, 13, 14, 15, 16, 17, 18, data, &datalen);
if (res) {
CLIParserFree(ctx);
return res;
}
uint32_t lowerlimit = 0;
res = arg_get_u32_hexstr_def_nlen(ctx, 21, 0, &lowerlimit, 4, true);
res = arg_get_u32_hexstr_def_nlen(ctx, 20, 0, &lowerlimit, 4, true);
if (res == 2) {
PrintAndLogEx(ERR, "Lower limit value must have 4 bytes length");
CLIParserFree(ctx);
@@ -6361,7 +6360,7 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) {
}
uint32_t upperlimit = 0;
res = arg_get_u32_hexstr_def_nlen(ctx, 22, 0, &upperlimit, 4, true);
res = arg_get_u32_hexstr_def_nlen(ctx, 21, 0, &upperlimit, 4, true);
if (res == 2) {
PrintAndLogEx(ERR, "Upper limit value must have 4 bytes length");
CLIParserFree(ctx);
@@ -6369,14 +6368,14 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) {
}
uint32_t value = 0;
res = arg_get_u32_hexstr_def_nlen(ctx, 23, 0, &value, 4, true);
res = arg_get_u32_hexstr_def_nlen(ctx, 22, 0, &value, 4, true);
if (res == 2) {
PrintAndLogEx(ERR, "Lower limit value must have 4 bytes length");
CLIParserFree(ctx);
return PM3_EINVARG;
}
uint32_t lcredit = arg_get_int_def(ctx, 24, 0);
uint32_t lcredit = arg_get_int_def(ctx, 23, 0);
SetAPDULogging(APDULogging);
CLIParserFree(ctx);

View File

@@ -1167,12 +1167,12 @@ static const char *DesfireUnknownStr = "unknown";
static const char *DesfireDisabledStr = "disabled";
static const char *DesfireFreeStr = "free";
static const DesfireCreateFileCommandsS DesfireFileCommands[] = {
{0x00, "Standard data", MFDES_CREATE_STD_DATA_FILE, 6, true},
{0x01, "Backup data", MFDES_CREATE_BACKUP_DATA_FILE, 6, true},
{0x02, "Value", MFDES_CREATE_VALUE_FILE, 16, false},
{0x03, "Linear Record", MFDES_CREATE_LINEAR_RECORD_FILE, 9, true},
{0x04, "Cyclic Record", MFDES_CREATE_CYCLIC_RECORD_FILE, 9, true},
{0x05, "Transaction MAC", MFDES_CREATE_TRANS_MAC_FILE, 22, false},
{0x00, "Standard data", MFDES_CREATE_STD_DATA_FILE, 6, 6, true},
{0x01, "Backup data", MFDES_CREATE_BACKUP_DATA_FILE, 6, 6, true},
{0x02, "Value", MFDES_CREATE_VALUE_FILE, 16, 16, false},
{0x03, "Linear Record", MFDES_CREATE_LINEAR_RECORD_FILE, 12, 9, true},
{0x04, "Cyclic Record", MFDES_CREATE_CYCLIC_RECORD_FILE, 12, 9, true},
{0x05, "Transaction MAC", MFDES_CREATE_TRANS_MAC_FILE, 5, 22, false},
};
const DesfireCreateFileCommandsS *GetDesfireFileCmdRec(uint8_t type) {
@@ -1268,7 +1268,7 @@ void DesfirePrintAccessRight(uint8_t *data) {
PrintAndLogEx(SUCCESS, "change : %s", GetDesfireAccessRightStr(ch));
}
static void DesfirePrintFileSettDynPart(uint8_t filetype, uint8_t *data, size_t datalen, uint8_t *dynlen) {
static void DesfirePrintFileSettDynPart(uint8_t filetype, uint8_t *data, size_t datalen, uint8_t *dynlen, bool create) {
switch (filetype) {
case 0x00:
case 0x01: {
@@ -1282,12 +1282,18 @@ static void DesfirePrintFileSettDynPart(uint8_t filetype, uint8_t *data, size_t
case 0x02: {
int lowerlimit = MemLeToUint4byte(&data[0]);
int upperlimit = MemLeToUint4byte(&data[4]);
int limitcredvalue = MemLeToUint4byte(&data[8]);
int value = MemLeToUint4byte(&data[8]);
uint8_t limited_credit_enabled = data[12];
PrintAndLogEx(INFO, "Lower limit : %d (0x%X)", lowerlimit, lowerlimit);
PrintAndLogEx(INFO, "Upper limit : %d (0x%X)", upperlimit, upperlimit);
PrintAndLogEx(INFO, "Limited credit : [%d - %s] %d (0x%X)", limited_credit_enabled, (limited_credit_enabled == 1) ? "enabled" : "disabled", limitcredvalue, limitcredvalue);
PrintAndLogEx(INFO, "Lower limit : %d (0x%08X)", lowerlimit, lowerlimit);
PrintAndLogEx(INFO, "Upper limit : %d (0x%08X)", upperlimit, upperlimit);
if (create) {
PrintAndLogEx(INFO, "Value : %d (0x%08X)", value, value);
PrintAndLogEx(INFO, "Limited credit : [%d - %s]", limited_credit_enabled, ((limited_credit_enabled & 1) != 0) ? "enabled" : "disabled");
} else {
PrintAndLogEx(INFO, "Limited credit : [%d - %s] %d (0x%08X)", limited_credit_enabled, ((limited_credit_enabled & 1) != 0) ? "enabled" : "disabled", value, value);
}
PrintAndLogEx(INFO, "GetValue access : %s", ((limited_credit_enabled & 0x02) != 0) ? "Free" : "Not Free");
*dynlen = 13;
break;
@@ -1296,20 +1302,23 @@ static void DesfirePrintFileSettDynPart(uint8_t filetype, uint8_t *data, size_t
case 0x04: {
uint32_t recordsize = MemLeToUint3byte(&data[0]);
uint32_t maxrecords = MemLeToUint3byte(&data[3]);
uint32_t currentrecord = MemLeToUint3byte(&data[6]);
uint32_t currentrecord = 0;
if (!create)
currentrecord = MemLeToUint3byte(&data[6]);
PrintAndLogEx(INFO, "Record size : %d (0x%X) bytes", recordsize, recordsize);
PrintAndLogEx(INFO, "Max num records : %d (0x%X)", maxrecords, maxrecords);
PrintAndLogEx(INFO, "Curr num records : %d (0x%X)", currentrecord, currentrecord);
if (!create)
PrintAndLogEx(INFO, "Curr num records : %d (0x%X)", currentrecord, currentrecord);
*dynlen = 9;
*dynlen = (create) ? 6 : 9;
break;
}
case 0x05: {
PrintAndLogEx(INFO, "Key type [0x%02x] : %s", data[0], GetDesfireKeyType(data[0]));
*dynlen = 1;
if (datalen > 16) {
if (create) {
PrintAndLogEx(INFO, "Key : %s", sprint_hex(&data[1], 16));
*dynlen += 16;
}
@@ -1343,8 +1352,8 @@ void DesfirePrintFileSettings(uint8_t *data, size_t len) {
DesfirePrintAccessRight(&data[2]); //2 bytes
uint8_t reclen = 0;
DesfirePrintFileSettDynPart(filetype, &data[4], len - 4, &reclen);
reclen += 4;
DesfirePrintFileSettDynPart(filetype, &data[4], len - 4, &reclen, false);
reclen += 4; // static part
if (addaccess && filetype != 0x05 && reclen > 0 && len > reclen && len == reclen + data[reclen] * 2) {
PrintAndLogEx(SUCCESS, "Add access records: %d", data[reclen]);
@@ -1381,8 +1390,9 @@ void DesfirePrintCreateFileSettings(uint8_t filetype, uint8_t *data, size_t len)
return;
}
bool isoidpresent = ftyperec->mayHaveISOfid && (len == ftyperec->len + 2 + 1);
bool isoidpresent = ftyperec->mayHaveISOfid && (len == ftyperec->createlen + 2 + 1);
PrintAndLogEx(SUCCESS, "---: %d", ftyperec->createlen);
PrintAndLogEx(INFO, "---- " _CYAN_("Create file settings") " ----");
PrintAndLogEx(SUCCESS, "File type : %s", ftyperec->text);
PrintAndLogEx(SUCCESS, "File number : 0x%02x (%d)", data[0], data[0]);
@@ -1404,8 +1414,8 @@ void DesfirePrintCreateFileSettings(uint8_t filetype, uint8_t *data, size_t len)
xlen += 2;
uint8_t reclen = 0;
DesfirePrintFileSettDynPart(filetype, &data[xlen], len - xlen, &reclen);
reclen += xlen;
DesfirePrintFileSettDynPart(filetype, &data[xlen], len - xlen, &reclen, true);
xlen += reclen;
}

View File

@@ -24,6 +24,7 @@ typedef struct {
const char *text;
const uint8_t cmd;
const uint8_t len;
const uint8_t createlen;
const bool mayHaveISOfid;
} DesfireCreateFileCommandsS;