From afbd80b90661bb6c3b75e5c80b673ebbb3f78aff Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 5 Jul 2021 11:59:07 +0300 Subject: [PATCH 1/9] cliparser CLIGetOptionList --- client/deps/cliparser/cliparser.c | 58 +++++++++++++++++++++++++++++++ client/deps/cliparser/cliparser.h | 14 ++++++++ 2 files changed, 72 insertions(+) diff --git a/client/deps/cliparser/cliparser.c b/client/deps/cliparser/cliparser.c index ec9f50e20..ad89856cd 100644 --- a/client/deps/cliparser/cliparser.c +++ b/client/deps/cliparser/cliparser.c @@ -298,6 +298,64 @@ int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int return 0; } +int CLIGetOptionList(struct arg_str *argstr, const CLIParserOption *option_array, int *value) { + char data[200] = {0}; + int datalen = 0; + int res = CLIParamStrToBuf(argstr, (uint8_t *)data, sizeof(data), &datalen); + if (res) + return res; + + // no data to check - we do not touch *value, just return + if (datalen == 0) + return 0; + + str_lower(data); + + int val = -1; + int cntr = 0; + for (int i = 0; i < CLI_MAX_OPTLIST_LEN; i++) { + // end of array + if (option_array[i].text == NULL) + break; + // exact match + if (strcmp(option_array[i].text, data) == 0) { + *value = option_array[i].code; + return 0; + } + // partial match + if (strncmp(option_array[i].text, data, datalen) == 0) { + val = option_array[i].code; + cntr++; + } + } + + // check partial match + if (cntr == 0) { + PrintAndLogEx(ERR, "Parameter error: No similar option to `%s`. Valid options: %s\n", argstr->sval[0], argstr->hdr.datatype); + return 20; + } + if (cntr > 1) { + PrintAndLogEx(ERR, "Parameter error: Several options fit to `%s`. Valid options: %s\n", argstr->sval[0], argstr->hdr.datatype); + return 21; + } + + *value = val; + return 0; +} + +const char *CLIGetOptionListStr(const CLIParserOption *option_array, int value) { + static const char *errmsg = "n/a"; + + for (int i = 0; i < CLI_MAX_OPTLIST_LEN; i++) { + if (option_array[i].text == NULL) + break; + if (option_array[i].code == value) + return option_array[i].text; + } + return errmsg; +} + + // hexstr -> u64, w optional len input and default value fallback. // 0 = failed // 1 = OK diff --git a/client/deps/cliparser/cliparser.h b/client/deps/cliparser/cliparser.h index 39a5792f8..f50fec2ee 100644 --- a/client/deps/cliparser/cliparser.h +++ b/client/deps/cliparser/cliparser.h @@ -51,6 +51,8 @@ #define CLIGetStrWithReturn(ctx, paramnum, data, datalen) if (CLIParamStrToBuf(arg_get_str((ctx), (paramnum)), (data), (*datalen), (datalen))) {CLIParserFree((ctx)); return PM3_ESOFT;} +#define CLIGetOptionListWithReturn(ctx, paramnum, option_array, option_array_len, value) if (CLIGetOptionList(arg_get_str((ctx), (paramnum)), (option_array), (option_array_len), (value))) {CLIParserFree((ctx)); return PM3_ESOFT;} + typedef struct { void **argtable; size_t argtableLen; @@ -59,6 +61,14 @@ typedef struct { const char *programHelp; char buf[1024 + 60]; } CLIParserContext; + +#define CLI_MAX_OPTLIST_LEN 50 +// option list needs to have NULL at the last record int the field `text` +typedef struct { + int code; + const char *text; +} CLIParserOption; + int CLIParserInit(CLIParserContext **ctx, const char *vprogramName, const char *vprogramHint, const char *vprogramHelp); void CLIParserPrintHelp(CLIParserContext *ctx); int CLIParserParseString(CLIParserContext *ctx, const char *str, void *vargtable[], size_t vargtableLen, bool allowEmptyExec); @@ -69,6 +79,10 @@ int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen); int CLIParamBinToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int *datalen); +// names in the CLIParserOption array must be in the lowercase format +int CLIGetOptionList(struct arg_str *argstr, const CLIParserOption *option_array, int *value); +const char *CLIGetOptionListStr(const CLIParserOption *option_array, int value); + uint64_t arg_get_u64_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint64_t def); int arg_get_u64_hexstr_def_nlen(CLIParserContext *ctx, uint8_t paramnum, uint64_t def, uint64_t *out, uint8_t nlen, bool optional); int arg_get_u32_hexstr_def(CLIParserContext *ctx, uint8_t paramnum, uint32_t def, uint32_t *out); From 7d06c09d173e69bfcffd9d3af8fbd2eae1937ba1 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 5 Jul 2021 11:59:24 +0300 Subject: [PATCH 2/9] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c2c5db58..0b3a1a7d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added `CLIGetOptionList` to cliparser that makes it easier to implement text options in the cli (@merlokk) - Added experimental support for macOS users utilizing MacPorts instead of Homebrew (@linuxgemini) - Added `pm3_online_check.py` - a script to verify and initialize a Proxmark3 RDV4 device (@iceman1001) From 2fb090e560f9b4e75552fc013030133a5372de48 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 5 Jul 2021 12:01:43 +0300 Subject: [PATCH 3/9] move des functions to pcrypto --- client/src/crypto/libpcrypto.c | 38 ++++++++++++++++++++++++++++++++++ client/src/crypto/libpcrypto.h | 7 +++++++ 2 files changed, 45 insertions(+) diff --git a/client/src/crypto/libpcrypto.c b/client/src/crypto/libpcrypto.c index 723753d5f..af15c1f5e 100644 --- a/client/src/crypto/libpcrypto.c +++ b/client/src/crypto/libpcrypto.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,43 @@ #include #include "util.h" #include "ui.h" + +void des_encrypt(void *out, const void *in, const void *key) { + mbedtls_des_context ctx; + mbedtls_des_setkey_enc(&ctx, key); + mbedtls_des_crypt_ecb(&ctx, in, out); + mbedtls_des_free(&ctx); +} + +void des_decrypt(void *out, const void *in, const void *key) { + mbedtls_des_context ctx; + mbedtls_des_setkey_dec(&ctx, key); + mbedtls_des_crypt_ecb(&ctx, in, out); + mbedtls_des_free(&ctx); +} + +void des_encrypt_ecb(void *out, const void *in, const int length, const void *key) { + for (int i = 0; i < length; i += 8) + des_encrypt((uint8_t *)out + i, (uint8_t *)in + i, key); +} + +void des_decrypt_ecb(void *out, const void *in, const int length, const void *key) { + for (int i = 0; i < length; i += 8) + des_decrypt((uint8_t *)out + i, (uint8_t *)in + i, key); +} + +void des_encrypt_cbc(void *out, const void *in, const int length, const void *key, uint8_t *iv) { + mbedtls_des_context ctx; + mbedtls_des_setkey_enc(&ctx, key); + mbedtls_des_crypt_cbc(&ctx, MBEDTLS_DES_ENCRYPT, length, iv, in, out); +} + +void des_decrypt_cbc(void *out, const void *in, const int length, const void *key, uint8_t *iv) { + mbedtls_des_context ctx; + mbedtls_des_setkey_dec(&ctx, key); + mbedtls_des_crypt_cbc(&ctx, MBEDTLS_DES_DECRYPT, length, iv, in, out); +} + // NIST Special Publication 800-38A — Recommendation for block cipher modes of operation: methods and techniques, 2001. int aes_encode(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *output, int length) { uint8_t iiv[16] = {0}; diff --git a/client/src/crypto/libpcrypto.h b/client/src/crypto/libpcrypto.h index 099fd4423..d5f7b809b 100644 --- a/client/src/crypto/libpcrypto.h +++ b/client/src/crypto/libpcrypto.h @@ -16,6 +16,13 @@ #include #include +void des_encrypt(void *out, const void *in, const void *key); +void des_decrypt(void *out, const void *in, const void *key); +void des_encrypt_ecb(void *out, const void *in, const int length, const void *key); +void des_decrypt_ecb(void *out, const void *in, const int length, const void *key); +void des_encrypt_cbc(void *out, const void *in, const int length, const void *key, uint8_t *iv); +void des_decrypt_cbc(void *out, const void *in, const int length, const void *key, uint8_t *iv); + int aes_encode(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *output, int length); int aes_decode(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *output, int length); int aes_cmac(uint8_t *iv, uint8_t *key, uint8_t *input, uint8_t *mac, int length); From 93a19fb953dc8b9f855ded10c920a0f80ba1447d Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 5 Jul 2021 12:03:50 +0300 Subject: [PATCH 4/9] cmdhfemrtd uses libcrypto --- client/src/cmdhfemrtd.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/client/src/cmdhfemrtd.c b/client/src/cmdhfemrtd.c index 7791233dc..312099268 100644 --- a/client/src/cmdhfemrtd.c +++ b/client/src/cmdhfemrtd.c @@ -19,8 +19,7 @@ #include "protocols.h" // definitions of ISO14A/7816 protocol #include "iso7816/apduinfo.h" // GetAPDUCodeDescription #include "iso7816/iso7816core.h" // Iso7816ExchangeEx etc -#include "crypto/libpcrypto.h" // Hash calculation (sha1, sha256, sha512) -#include "mifare/desfire_crypto.h" // des_encrypt/des_decrypt +#include "crypto/libpcrypto.h" // Hash calculation (sha1, sha256, sha512), des_encrypt/des_decrypt #include "des.h" // mbedtls_des_key_set_parity #include "crapto1/crapto1.h" // prng_successor #include "commonutil.h" // num_to_bytes @@ -263,20 +262,6 @@ static int emrtd_get_asn1_field_length(uint8_t *datain, int datainlen, int offse return 0; } -static void des_encrypt_ecb(uint8_t *key, uint8_t *input, uint8_t *output) { - mbedtls_des_context ctx_enc; - mbedtls_des_setkey_enc(&ctx_enc, key); - mbedtls_des_crypt_ecb(&ctx_enc, input, output); - mbedtls_des_free(&ctx_enc); -} - -static void des_decrypt_ecb(uint8_t *key, uint8_t *input, uint8_t *output) { - mbedtls_des_context ctx_dec; - mbedtls_des_setkey_dec(&ctx_dec, key); - mbedtls_des_crypt_ecb(&ctx_dec, input, output); - mbedtls_des_free(&ctx_dec); -} - static void des3_encrypt_cbc(uint8_t *iv, uint8_t *key, uint8_t *input, int inputlen, uint8_t *output) { mbedtls_des3_context ctx; mbedtls_des3_set2key_enc(&ctx, key); @@ -345,15 +330,15 @@ static void retail_mac(uint8_t *key, uint8_t *input, int inputlen, uint8_t *outp intermediate[x] = intermediate[x] ^ block[x]; } - des_encrypt_ecb(k0, intermediate, intermediate_des); + des_encrypt(intermediate_des, intermediate, k0); memcpy(intermediate, intermediate_des, 8); } - des_decrypt_ecb(k1, intermediate, intermediate_des); + des_decrypt(intermediate_des, intermediate, k1); memcpy(intermediate, intermediate_des, 8); - des_encrypt_ecb(k0, intermediate, intermediate_des); + des_encrypt(intermediate_des, intermediate, k0); memcpy(output, intermediate_des, 8); } From 3cc199ea34d00923d5614020b75a1182ff4f2cbc Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 5 Jul 2021 12:04:36 +0300 Subject: [PATCH 5/9] cmdhfmf uses libcrypto --- client/src/cmdhfmf.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/client/src/cmdhfmf.c b/client/src/cmdhfmf.c index ace8d2d0b..985d156db 100644 --- a/client/src/cmdhfmf.c +++ b/client/src/cmdhfmf.c @@ -24,7 +24,6 @@ #include "protocols.h" #include "util_posix.h" // msclock #include "cmdhfmfhard.h" -#include "des.h" // des ecb #include "crapto1/crapto1.h" // prng_successor #include "cmdhf14a.h" // exchange APDU #include "crypto/libpcrypto.h" @@ -5645,12 +5644,6 @@ static int CmdHf14AGen3Freeze(const char *Cmd) { return res; } -static void des_decrypt(void *out, const void *in, const void *key) { - mbedtls_des_context ctx; - mbedtls_des_setkey_dec(&ctx, key); - mbedtls_des_crypt_ecb(&ctx, in, out); -} - static int CmdHf14AMfSuperCard(const char *Cmd) { CLIParserContext *ctx; From 4db3862cd7daf0edfe33fcf00b6b3ea4d320a478 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 5 Jul 2021 12:06:07 +0300 Subject: [PATCH 6/9] changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c2c5db58..1cfc2d76f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Fix - move des functions to libcrypto (@merlokk) - Added experimental support for macOS users utilizing MacPorts instead of Homebrew (@linuxgemini) - Added `pm3_online_check.py` - a script to verify and initialize a Proxmark3 RDV4 device (@iceman1001) From dece2b1bbde0a842e6ef399a45f99c74b4894bc4 Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 5 Jul 2021 12:09:08 +0300 Subject: [PATCH 7/9] delete des from desfire_crypto --- client/src/mifare/desfire_crypto.c | 12 ------------ client/src/mifare/desfire_crypto.h | 2 -- 2 files changed, 14 deletions(-) diff --git a/client/src/mifare/desfire_crypto.c b/client/src/mifare/desfire_crypto.c index e3e785e6c..3c27e1ca4 100644 --- a/client/src/mifare/desfire_crypto.c +++ b/client/src/mifare/desfire_crypto.c @@ -53,18 +53,6 @@ static inline void update_key_schedules(desfirekey_t key) { /******************************************************************************/ -void des_encrypt(void *out, const void *in, const void *key) { - mbedtls_des_context ctx; - mbedtls_des_setkey_enc(&ctx, key); - mbedtls_des_crypt_ecb(&ctx, in, out); -} - -void des_decrypt(void *out, const void *in, const void *key) { - mbedtls_des_context ctx; - mbedtls_des_setkey_dec(&ctx, key); - mbedtls_des_crypt_ecb(&ctx, in, out); -} - void tdes_nxp_receive(const void *in, void *out, size_t length, const void *key, unsigned char iv[8], int keymode) { if (length % 8) return; diff --git a/client/src/mifare/desfire_crypto.h b/client/src/mifare/desfire_crypto.h index ecc6fc4a5..b58372004 100644 --- a/client/src/mifare/desfire_crypto.h +++ b/client/src/mifare/desfire_crypto.h @@ -102,8 +102,6 @@ typedef unsigned long DES3_KS[48][2]; /* Triple-DES key schedule */ extern int Asmversion; /* 1 if we're linked with an asm version, 0 if C */ -void des_encrypt(void *out, const void *in, const void *key); -void des_decrypt(void *out, const void *in, const void *key); void tdes_nxp_receive(const void *in, void *out, size_t length, const void *key, unsigned char iv[8], int keymode); void tdes_nxp_send(const void *in, void *out, size_t length, const void *key, unsigned char iv[8], int keymode); void Desfire_des_key_new(const uint8_t value[8], desfirekey_t key); From 5937fd4217ed15c099ff50724dda7ca889d3220e Mon Sep 17 00:00:00 2001 From: merlokk <807634+merlokk@users.noreply.github.com> Date: Mon, 5 Jul 2021 12:12:42 +0300 Subject: [PATCH 8/9] added lib --- client/src/mifare/desfire_crypto.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/mifare/desfire_crypto.c b/client/src/mifare/desfire_crypto.c index 3c27e1ca4..34f38ef73 100644 --- a/client/src/mifare/desfire_crypto.c +++ b/client/src/mifare/desfire_crypto.c @@ -30,6 +30,7 @@ #include #include #include "commonutil.h" +#include "crypto/libpcrypto.h" #include "aes.h" #include "des.h" #include "ui.h" From 36c0ddc91a86c0f63f8446e5fc2176c8f7bfa702 Mon Sep 17 00:00:00 2001 From: iceman1001 Date: Mon, 5 Jul 2021 12:36:43 +0200 Subject: [PATCH 9/9] increase output size in order to avoid crash in emrtd info --- client/src/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/util.c b/client/src/util.c index 77ce9cf2f..ed6ca6e7c 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -25,7 +25,7 @@ #include "ui.h" // PrintAndLog -#define UTIL_BUFFER_SIZE_SPRINT 4097 +#define UTIL_BUFFER_SIZE_SPRINT 8193 // global client debug variable uint8_t g_debugMode = 0; // global client disable logging variable