From 4d616a1c09bf740abbfc97d02a3929d6462f8ad0 Mon Sep 17 00:00:00 2001 From: tcprst Date: Mon, 23 Nov 2020 14:46:07 -0500 Subject: [PATCH 1/3] hf iclass decrypt - now use cliparser --- client/src/cmdhficlass.c | 148 ++++++++++++++++++--------------------- doc/cheatsheet.md | 11 +-- 2 files changed, 73 insertions(+), 86 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 2c90278a7..8a2cbf2d7 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -71,28 +71,6 @@ static int usage_hf_iclass_sim(void) { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_hf_iclass_decrypt(void) { - PrintAndLogEx(NORMAL, "3DES decrypt data\n"); - PrintAndLogEx(NORMAL, "This is naive implementation, it tries to decrypt every block after block 6."); - PrintAndLogEx(NORMAL, "Correct behaviour would be to decrypt only the application areas where the key is valid,"); - PrintAndLogEx(NORMAL, "which is defined by the configuration block."); - PrintAndLogEx(NORMAL, "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside"); - PrintAndLogEx(NORMAL, "in the resources directory. The file should be 16 bytes binary data\n"); - PrintAndLogEx(NORMAL, "Usage: hf iclass decrypt d f k \n"); - PrintAndLogEx(NORMAL, "Options"); - PrintAndLogEx(NORMAL, " h : Show this help"); - PrintAndLogEx(NORMAL, " d : 16 bytes hex"); - PrintAndLogEx(NORMAL, " f : filename of dump"); - PrintAndLogEx(NORMAL, " k : 16 bytes hex"); - PrintAndLogEx(NORMAL, " v : verbose output"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass decrypt f hf-iclass-AA162D30F8FF12F1-dump.bin")); - PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass decrypt f hf-iclass-AA162D30F8FF12F1-dump.bin k 000102030405060708090a0b0c0d0e0f")); - PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass decrypt d 1122334455667788 k 000102030405060708090a0b0c0d0e0f")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} static int usage_hf_iclass_encrypt(void) { PrintAndLogEx(NORMAL, "3DES encrypt data\n"); PrintAndLogEx(NORMAL, "OBS! In order to use this function, the file " _YELLOW_("'iclass_decryptionkey.bin'") " must reside"); @@ -1003,7 +981,7 @@ static int CmdHFiClassEView(const char *Cmd) { void *argtable[] = { arg_param_begin, arg_int0("s", "size", "<256|2048>", "number of bytes to save (default 256)"), - arg_lit0("v", "verbose", "filename of dumpfile"), + arg_lit0("v", "verbose", "verbose output"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -1049,74 +1027,82 @@ static int CmdHFiClassEView(const char *Cmd) { free(dump); return PM3_SUCCESS; } - static int CmdHFiClassDecrypt(const char *Cmd) { + CLIParserContext *clictx; + CLIParserInit(&clictx, "hf iclass decrypt", + "3DES decrypt data\n" + "This is naive implementation, it tries to decrypt every block after block 6.\n" + "Correct behaviour would be to decrypt only the application areas where the key is valid,\n" + "which is defined by the configuration block.\n" + "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside\n" + "in the resources directory. The file should be 16 bytes binary data", + "hf iclass decrypt -f hf-iclass-AA162D30F8FF12F1-dump.bin\n" + "hf iclass decrypt -f hf-iclass-AA162D30F8FF12F1-dump.bin --key 000102030405060708090a0b0c0d0e0f\n" + "hf iclass decrypt -d 1122334455667788 --key 000102030405060708090a0b0c0d0e0f"); - bool errors = false; - bool have_key = false; - bool have_data = false; - bool have_file = false; - bool verbose = false; - uint8_t cmdp = 0; + void *argtable[] = { + arg_param_begin, + arg_str0("f", "file", "", "filename of dumpfile"), + arg_str0("d", "data", "", "3DES encrypted data"), + arg_str0(NULL, "key", "", "3DES transport key"), + arg_lit0("v", "verbose", "verbose output"), + arg_param_end + }; + CLIExecWithReturn(clictx, Cmd, argtable, false); - uint8_t enc_data[8] = {0}; - uint8_t dec_data[8] = {0}; - - size_t keylen = 0; - uint8_t key[32] = {0}; - uint8_t *keyptr = NULL; + int fnlen = 0; + char filename[FILE_PATH_SIZE] = {0}; + CLIParamStrToBuf(arg_get_str(clictx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); size_t decryptedlen = 0; uint8_t *decrypted = NULL; - char filename[FILE_PATH_SIZE]; + bool have_file = false; - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_hf_iclass_decrypt(); - case 'd': - if (param_gethex(Cmd, cmdp + 1, enc_data, 16)) { - PrintAndLogEx(ERR, "Data must be 16 HEX symbols"); - errors = true; - break; - } - have_data = true; - cmdp += 2; - break; - case 'f': - if (param_getstr(Cmd, cmdp + 1, filename, sizeof(filename)) == 0) { - PrintAndLogEx(WARNING, "No filename found after f"); - errors = true; - break; - } - - if (loadFile_safe(filename, "", (void **)&decrypted, &decryptedlen) != PM3_SUCCESS) { - errors = true; - break; - } - have_file = true; - cmdp += 2; - break; - case 'k': - if (param_gethex(Cmd, cmdp + 1, key, 32)) { - PrintAndLogEx(ERR, "Transport key must include 32 HEX symbols"); - errors = true; - } - have_key = true; - cmdp += 2; - break; - case 'v': - verbose = true; - cmdp++; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp)); - errors = true; - break; + if (fnlen > 0) { + if (loadFile_safe(filename, "", (void **)&decrypted, &decryptedlen) != PM3_SUCCESS) { + CLIParserFree(clictx); + return PM3_EINVARG; } + have_file = true; } - if (errors || cmdp < 1) return usage_hf_iclass_decrypt(); + int enc_data_len = 0; + uint8_t enc_data[8] = {0}; + bool have_data = false; + + CLIGetHexWithReturn(clictx, 2, enc_data, &enc_data_len); + + if (enc_data_len > 0) { + if (enc_data_len != 8) { + PrintAndLogEx(ERR, "Data must be 8 bytes (16 HEX characters)"); + CLIParserFree(clictx); + return PM3_EINVARG; + } + have_data = true; + } + + int key_len = 0; + uint8_t key[32] = {0}; + uint8_t *keyptr = NULL; + bool have_key = false; + + CLIGetHexWithReturn(clictx, 3, key, &key_len); + + if (key_len > 0) { + if (key_len != 16) { + PrintAndLogEx(ERR, "Transport key must be 16 bytes (32 HEX characters)"); + CLIParserFree(clictx); + return PM3_EINVARG; + } + have_key = true; + } + + bool verbose = arg_get_lit(clictx, 4); + + CLIParserFree(clictx); + + size_t keylen = 0; + uint8_t dec_data[8] = {0}; bool use_sc = IsCryptoHelperPresent(verbose); diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index a3ea9c579..86dc4a29e 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -121,12 +121,13 @@ Decrypt iCLASS Block / file ``` Options --- -d : 16 bytes hex -f : filename of dump -k : 16 bytes hex +-f, --file filename of dumpfile +-d, --data 3DES encrypted data + --key 3DES transport key +-v, --verbose verbose output -pm3 --> hf iclass decrypt d 2AD4C8211F996871 -pm3 --> hf iclass decrypt f hf-iclass-db883702f8ff12e0.bin +pm3 --> hf iclass decrypt -d 2AD4C8211F996871 +pm3 --> hf iclass decrypt -f hf-iclass-db883702f8ff12e0.bin ``` Load iCLASS dump into memory for simulation From 9ef0e07d49947945911b996eb33d5f4adb767a0b Mon Sep 17 00:00:00 2001 From: tcprst Date: Mon, 23 Nov 2020 15:42:32 -0500 Subject: [PATCH 2/3] hf iclass encrypt - now use cliparser --- client/src/cmdhficlass.c | 99 ++++++++++++++++++---------------------- doc/cheatsheet.md | 7 +-- 2 files changed, 49 insertions(+), 57 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 8a2cbf2d7..7a26cbb0c 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -71,23 +71,6 @@ static int usage_hf_iclass_sim(void) { PrintAndLogEx(NORMAL, ""); return PM3_SUCCESS; } -static int usage_hf_iclass_encrypt(void) { - PrintAndLogEx(NORMAL, "3DES encrypt data\n"); - PrintAndLogEx(NORMAL, "OBS! In order to use this function, the file " _YELLOW_("'iclass_decryptionkey.bin'") " must reside"); - PrintAndLogEx(NORMAL, "in the resources directory. The file should be 16 bytes binary data\n"); - PrintAndLogEx(NORMAL, "Usage: hf iclass encrypt d k \n"); - PrintAndLogEx(NORMAL, "Options"); - PrintAndLogEx(NORMAL, " h : Show this help"); - PrintAndLogEx(NORMAL, " d : 16 bytes hex"); - PrintAndLogEx(NORMAL, " k : 16 bytes hex"); - PrintAndLogEx(NORMAL, " v : verbose output"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass encrypt d 0102030405060708")); - PrintAndLogEx(NORMAL, _YELLOW_("\thf iclass encrypt d 0102030405060708 k 00112233445566778899AABBCCDDEEFF")); - PrintAndLogEx(NORMAL, ""); - return PM3_SUCCESS; -} static int usage_hf_iclass_dump(void) { PrintAndLogEx(NORMAL, "Dump all memory from a iCLASS tag\n"); PrintAndLogEx(NORMAL, "Usage: hf iclass dump f k c [e|r|v]\n"); @@ -1082,7 +1065,7 @@ static int CmdHFiClassDecrypt(const char *Cmd) { } int key_len = 0; - uint8_t key[32] = {0}; + uint8_t key[16] = {0}; uint8_t *keyptr = NULL; bool have_key = false; @@ -1269,45 +1252,53 @@ static void iclass_encrypt_block_data(uint8_t *blk_data, uint8_t *key) { } static int CmdHFiClassEncryptBlk(const char *Cmd) { - bool errors = false; - bool have_key = false; - bool verbose = false; - uint8_t blk_data[8] = {0}; - uint8_t key[16] = {0}; - uint8_t *keyptr = NULL; - uint8_t cmdp = 0; + CLIParserContext *clictx; + CLIParserInit(&clictx, "hf iclass encrypt", + "3DES encrypt data\n" + "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside\n" + "in the resources directory. The file should be 16 bytes binary data", + "hf iclass encrypt -d 0102030405060708\n" + "hf iclass encrypt -d 0102030405060708 --key 00112233445566778899AABBCCDDEEFF"); - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_hf_iclass_encrypt(); - case 'd': - if (param_gethex(Cmd, cmdp + 1, blk_data, 16)) { - PrintAndLogEx(ERR, "Block data must include 16 HEX symbols"); - errors = true; - } - cmdp += 2; - break; - case 'k': - if (param_gethex(Cmd, cmdp + 1, key, 32)) { - PrintAndLogEx(ERR, "Transport key must include 32 HEX symbols"); - errors = true; - } - have_key = true; - cmdp += 2; - break; - case 'v': - verbose = true; - cmdp++; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp)); - errors = true; - break; - } + void *argtable[] = { + arg_param_begin, + arg_str1("d", "data", "", "data to encrypt"), + arg_str0(NULL, "key", "", "3DES transport key"), + arg_lit0("v", "verbose", "verbose output"), + arg_param_end + }; + CLIExecWithReturn(clictx, Cmd, argtable, false); + + int blk_data_len = 0; + uint8_t blk_data[8] = {0}; + + CLIGetHexWithReturn(clictx, 1, blk_data, &blk_data_len); + + if (blk_data_len != 8) { + PrintAndLogEx(ERR, "Block data must be 8 bytes (16 HEX characters)"); + CLIParserFree(clictx); + return PM3_EINVARG; } - if (errors || cmdp < 1) return usage_hf_iclass_encrypt(); + int key_len = 0; + uint8_t key[16] = {0}; + uint8_t *keyptr = NULL; + bool have_key = false; + + CLIGetHexWithReturn(clictx, 2, key, &key_len); + + if (key_len > 0) { + if (key_len != 16) { + PrintAndLogEx(ERR, "Transport key must be 16 bytes (32 HEX characters)"); + CLIParserFree(clictx); + return PM3_EINVARG; + } + have_key = true; + } + + bool verbose = arg_get_lit(clictx, 3); + + CLIParserFree(clictx); bool use_sc = IsCryptoHelperPresent(verbose); diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 86dc4a29e..5de15e198 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -111,10 +111,11 @@ Encrypt iCLASS Block ``` Options --- -d : 16 bytes hex -k : 16 bytes hex +-d, --data data to encrypt + --key 3DES transport key +-v, --verbose verbose output -pm3 --> hf iclass encrypt d 0000000f2aa3dba8 +pm3 --> hf iclass encrypt -d 0000000f2aa3dba8 ``` Decrypt iCLASS Block / file From 0c0411c144685a0fbfbd8aea7b6afee86b8317fb Mon Sep 17 00:00:00 2001 From: tcprst Date: Mon, 23 Nov 2020 16:07:03 -0500 Subject: [PATCH 3/3] add short option and fix typo --- client/src/cmdhficlass.c | 12 ++++++------ doc/cheatsheet.md | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/client/src/cmdhficlass.c b/client/src/cmdhficlass.c index 7a26cbb0c..284317a47 100644 --- a/client/src/cmdhficlass.c +++ b/client/src/cmdhficlass.c @@ -1014,20 +1014,20 @@ static int CmdHFiClassDecrypt(const char *Cmd) { CLIParserContext *clictx; CLIParserInit(&clictx, "hf iclass decrypt", "3DES decrypt data\n" - "This is naive implementation, it tries to decrypt every block after block 6.\n" + "This is a naive implementation, it tries to decrypt every block after block 6.\n" "Correct behaviour would be to decrypt only the application areas where the key is valid,\n" "which is defined by the configuration block.\n" "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside\n" "in the resources directory. The file should be 16 bytes binary data", "hf iclass decrypt -f hf-iclass-AA162D30F8FF12F1-dump.bin\n" - "hf iclass decrypt -f hf-iclass-AA162D30F8FF12F1-dump.bin --key 000102030405060708090a0b0c0d0e0f\n" - "hf iclass decrypt -d 1122334455667788 --key 000102030405060708090a0b0c0d0e0f"); + "hf iclass decrypt -f hf-iclass-AA162D30F8FF12F1-dump.bin -k 000102030405060708090a0b0c0d0e0f\n" + "hf iclass decrypt -d 1122334455667788 -k 000102030405060708090a0b0c0d0e0f"); void *argtable[] = { arg_param_begin, arg_str0("f", "file", "", "filename of dumpfile"), arg_str0("d", "data", "", "3DES encrypted data"), - arg_str0(NULL, "key", "", "3DES transport key"), + arg_str0("k", "key", "", "3DES transport key"), arg_lit0("v", "verbose", "verbose output"), arg_param_end }; @@ -1258,12 +1258,12 @@ static int CmdHFiClassEncryptBlk(const char *Cmd) { "OBS! In order to use this function, the file 'iclass_decryptionkey.bin' must reside\n" "in the resources directory. The file should be 16 bytes binary data", "hf iclass encrypt -d 0102030405060708\n" - "hf iclass encrypt -d 0102030405060708 --key 00112233445566778899AABBCCDDEEFF"); + "hf iclass encrypt -d 0102030405060708 -k 00112233445566778899AABBCCDDEEFF"); void *argtable[] = { arg_param_begin, arg_str1("d", "data", "", "data to encrypt"), - arg_str0(NULL, "key", "", "3DES transport key"), + arg_str0("k", "key", "", "3DES transport key"), arg_lit0("v", "verbose", "verbose output"), arg_param_end }; diff --git a/doc/cheatsheet.md b/doc/cheatsheet.md index 5de15e198..9699fabf0 100644 --- a/doc/cheatsheet.md +++ b/doc/cheatsheet.md @@ -112,7 +112,7 @@ Encrypt iCLASS Block Options --- -d, --data data to encrypt - --key 3DES transport key +-k, --key 3DES transport key -v, --verbose verbose output pm3 --> hf iclass encrypt -d 0000000f2aa3dba8 @@ -124,7 +124,7 @@ Options --- -f, --file filename of dumpfile -d, --data 3DES encrypted data - --key 3DES transport key +-k, --key 3DES transport key -v, --verbose verbose output pm3 --> hf iclass decrypt -d 2AD4C8211F996871