diff --git a/client/src/cmdhfmfdes.c b/client/src/cmdhfmfdes.c index ba6bc18d3..909e55f67 100644 --- a/client/src/cmdhfmfdes.c +++ b/client/src/cmdhfmfdes.c @@ -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", "", "Secure channel: d40/ev1/ev2"), arg_str0(NULL, "aid", "", "Application ID (3 hex bytes, big endian)"), arg_str0(NULL, "fid", "", "File ID (1 hex byte)"), - arg_str0(NULL, "isofid", "", "ISO File ID (2 hex bytes)"), arg_str0(NULL, "amode", "", "File access mode: plain/mac/encrypt"), arg_str0(NULL, "rawrights", "", "Access rights for file (HEX 2 byte) R/W/RW/Chg, 0x0 - 0xD Key, 0xE Free, 0xF Denied"), arg_str0(NULL, "rrights", "", "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); diff --git a/client/src/mifare/desfirecore.c b/client/src/mifare/desfirecore.c index edc1a9376..d3fbee484 100644 --- a/client/src/mifare/desfirecore.c +++ b/client/src/mifare/desfirecore.c @@ -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; } diff --git a/client/src/mifare/desfirecore.h b/client/src/mifare/desfirecore.h index 56bc92b1a..07545fbb7 100644 --- a/client/src/mifare/desfirecore.h +++ b/client/src/mifare/desfirecore.h @@ -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;