From cd783fa2f0fa49fc9297cfe737c87b300859f03b Mon Sep 17 00:00:00 2001 From: team-orangeBlue <63470411+team-orangeBlue@users.noreply.github.com> Date: Fri, 19 Jan 2024 23:41:29 +0300 Subject: [PATCH 1/6] Add `data crypto` Command to cipher data. Checked with premade datasets for all algorithms (AES CMAC too!) One sample provided. Now with make style! Signed-off-by: team-orangeBlue <63470411+team-orangeBlue@users.noreply.github.com> --- client/src/cmddata.c | 114 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/client/src/cmddata.c b/client/src/cmddata.c index d954f28a6..2f1e4cb2b 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -3642,6 +3642,119 @@ static int CmdAtrLookup(const char *Cmd) { return PM3_SUCCESS; } +static int CmdCryptography(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "data crypto", + "Encrypt data, right here, right now. Or decrypt.", + "Supply data, key, IV (needed for des MAC or aes), and cryptography action.\n" + "To calculate a MAC for FMCOS, supply challenge as IV, data as data, and session/line protection key as key.\n" + "To calculate a MAC for FeliCa, supply first RC as IV, BLE+data as data and session key as key.\n" + "data crypto -d 04D6850E06AABB80 -k FFFFFFFFFFFFFFFF --iv 9EA0401A00000000 --des -> Calculate a MAC for FMCOS chip. The result should be ED3A0133\n" + ); + void *argtable[] = { + arg_param_begin, + arg_str1("d", "data", "", "Data to process"), + arg_str1("k", "key", "", "Key to use"), + arg_lit0("r", "rev", "Decrypt, not encrypt"), + arg_lit0(NULL, "des", "Cipher with DES, not AES"), + arg_lit0(NULL, "mac", "Calculate AES CMAC/FeliCa Lite MAC"), + arg_str0(NULL, "iv", "", "IV value if needed"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + uint8_t dati[250] = {0}; + uint8_t dato[250] = {0}; + int datilen = 0; + CLIGetHexWithReturn(ctx, 1, dati, &datilen); + uint8_t key[25] = {0}; + int keylen = 0; + CLIGetHexWithReturn(ctx, 2, key, &keylen); + int type = 0; + if (arg_get_lit(ctx, 3)) type ^= 8; + if (arg_get_lit(ctx, 4)) type ^= 4; + if (arg_get_lit(ctx, 5)) type ^= 2; + uint8_t iv[250] = {0}; + int ivlen = 0; + CLIGetHexWithReturn(ctx, 6, iv, &ivlen); + CLIParserFree(ctx); + + // Do data length check + if ((type & 0x4) >> 2) { // Use AES(0) or DES(1)? + if (datilen % 8 != 0) { + PrintAndLogEx(ERR, " length must be a multiple of 8. Got %d", datilen); + return PM3_EINVARG; + } + if (keylen != 8 && keylen != 16 && keylen != 24) { + PrintAndLogEx(ERR, " must be 8, 16 or 24 bytes. Got %d", keylen); + return PM3_EINVARG; + } + } else { + if (datilen % 16 != 0 && ((type & 0x2) >>1==0)) { + PrintAndLogEx(ERR, " length must be a multiple of 16. Got %d", datilen); + return PM3_EINVARG; + } + if (keylen != 16) { + PrintAndLogEx(ERR, " must be 16 bytes. Got %d", keylen); + return PM3_EINVARG; + } + } + if ((type & 0x8) >> 3) { // Encrypt(0) or decrypt(1)? + if ((type & 0x4) >> 2) { // AES or DES? + if (keylen > 8) {PrintAndLogEx(INFO, "Called 3DES decrypt"); des3_decrypt(dato, dati, key, keylen / 8);} + else { + PrintAndLogEx(INFO, "Called DES decrypt"); + if (!ivlen) {des_decrypt_ecb(dato, dati, datilen, key);} // If there's an IV, use CBC + else {des_decrypt_cbc(dato, dati, datilen, key, iv);} + } + } else {PrintAndLogEx(INFO, "Called AES decrypt"); aes_decode(iv, key, dati, dato, datilen);} + } else { + if (type & 0x4) { // AES or DES? + if (type & 0x02) { // If we will calculate a MAC + /*PrintAndLogEx(INFO, "Called FeliCa MAC"); + // For DES all I know useful is the felica and fudan MAC algorithm.This is just des-cbc, but felica needs it in its way. + for (int i = 0; i < datilen; i+=8){ // For all 8 byte sequences + reverser(dati, &dati[i], 8, i); + if (i){ // If IV is processed + for (int n = 0; n < 8; ++n){ + dato[n] ^= dati[i+n]; // XOR with Dx + } + des_encrypt_ecb(dato, dato, 8, key); // Cipher itself + } else { // If we didn't start with IV + for (int n = 0; n < 8; ++n){ + dato[n] = iv[n]; // Feed data into output + dato[n] ^= dati[i+n]; // XOR with D1 + } + des_encrypt_ecb(dato, dato, 8, key); // Cipher itself + } + } + PrintAndLogEx(SUCCESS, "MAC: %s", sprint_hex_inrow(dato, 8));*/ + PrintAndLogEx(INFO, "Not implemented yet - feel free to contribute!"); + return PM3_SUCCESS; + } else { + if (keylen > 8) { + PrintAndLogEx(INFO, "Called 3DES encrypt keysize: %i", keylen / 8); + des3_encrypt(dato, dati, key, keylen / 8); + } else { + PrintAndLogEx(INFO, "Called DES encrypt"); + if (!ivlen) {des_encrypt_ecb(dato, dati, datilen, key);} // If there's an IV, use ECB + else { + des_encrypt_cbc(dato, dati, datilen, key, iv); + char pad[250]; + memset(pad, ' ', 4 + 8 + (datilen - 8) * 3); + pad[4 + 8 + (datilen - 8) * 3] = 0; // Make a padding to insert FMCOS macing algorithm guide + PrintAndLogEx(NONE, "%sVV VV VV VV FMCOS MAC", pad); + } + } + } + } else { + if (type & 0x02) {PrintAndLogEx(INFO, "Called AES CMAC"); aes_cmac8(iv, key, dati, dato, datilen);} // If we will calculate a MAC + else {PrintAndLogEx(INFO, "Called AES encrypt"); aes_encode(iv, key, dati, dato, datilen);} + } + } + PrintAndLogEx(SUCCESS, "Result: %s", sprint_hex(dato, datilen)); + return PM3_SUCCESS; +} + static int CmdBinaryMap(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "data bmap", @@ -3752,6 +3865,7 @@ static command_t CommandTable[] = { {"bitsamples", CmdBitsamples, IfPm3Present, "Get raw samples as bitstring"}, {"bmap", CmdBinaryMap, AlwaysAvailable, "Convert hex value according a binary template"}, {"clear", CmdBuffClear, AlwaysAvailable, "Clears bigbuf on deviceside and graph window"}, + {"crypto", CmdCryptography, AlwaysAvailable, "Encrypt and decrypt data"}, {"diff", CmdDiff, AlwaysAvailable, "Diff of input files"}, {"hexsamples", CmdHexsamples, IfPm3Present, "Dump big buffer as hex bytes"}, {"hex2bin", Cmdhex2bin, AlwaysAvailable, "Converts hexadecimal to binary"}, From 571afc2901306612b204d466a44637fa8ee7194b Mon Sep 17 00:00:00 2001 From: team-orangeBlue <63470411+team-orangeBlue@users.noreply.github.com> Date: Fri, 19 Jan 2024 23:43:22 +0300 Subject: [PATCH 2/6] Update commands.md Add record Signed-off-by: team-orangeBlue <63470411+team-orangeBlue@users.noreply.github.com> --- doc/commands.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/commands.md b/doc/commands.md index fb4cdf417..94241bfbe 100644 --- a/doc/commands.md +++ b/doc/commands.md @@ -128,6 +128,7 @@ Check column "offline" for their availability. |`data bitsamples `|N |`Get raw samples as bitstring` |`data bmap `|Y |`Convert hex value according a binary template` |`data clear `|Y |`Clears bigbuf on deviceside and graph window` +|`data crypto `|Y |`Encrypt and decrypt data` |`data diff `|Y |`Diff of input files` |`data hexsamples `|N |`Dump big buffer as hex bytes` |`data hex2bin `|Y |`Converts hexadecimal to binary` From 60ccacdbf4d8164946fecb779a79396af3b0c195 Mon Sep 17 00:00:00 2001 From: team-orangeBlue <63470411+team-orangeBlue@users.noreply.github.com> Date: Fri, 19 Jan 2024 23:47:45 +0300 Subject: [PATCH 3/6] Add record Without styling.. Signed-off-by: team-orangeBlue <63470411+team-orangeBlue@users.noreply.github.com> --- doc/commands.json | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/doc/commands.json b/doc/commands.json index 70a8f7036..8f45c52e2 100644 --- a/doc/commands.json +++ b/doc/commands.json @@ -273,6 +273,27 @@ ], "usage": "data clear [-h]" }, + "data crypto": { + "command": "data crypto", + "description": "Encrypt and decrypt data", + "notes": [ + "Supply data, key, IV (needed for des MAC or aes), and cryptography action.", + "To calculate a MAC for FMCOS, supply challenge as IV, data as data, and session/line protection key as key.", + "To calculate a MAC for FeliCa, supply first RC as IV, BLE+data as data and session key as key.", + "data crypto -d 04D6850E06AABB80 -k FFFFFFFFFFFFFFFF --iv 9EA0401A00000000 --des -> Calculate a MAC for FMCOS chip. The result should be ED3A0133" + ], + "offline": true, + "options": [ + "-h, --help This help", + "-d, --data Data to process", + "-k, --key Key to use", + "-r, --rev Decrypt, not encrypt", + "--des Cipher with DES, not AES", + "--mac Calculate AES CMAC/FeliCa Lite MAC", + "--iv IV value if needed" + ], + "usage": "data crypto [-hr] -d -k [--des] [--mac] [--iv ]" + }, "data convertbitstream": { "command": "data convertbitstream", "description": "Convert GraphBuffer's 0|1 values to 127|-127", @@ -12309,4 +12330,4 @@ "extracted_by": "PM3Help2JSON v1.00", "extracted_on": "2024-01-18T18:49:32" } -} \ No newline at end of file +} From ae0efe32f972e7a19efb5cba1dfebd7ee22d74e9 Mon Sep 17 00:00:00 2001 From: team-orangeBlue <63470411+team-orangeBlue@users.noreply.github.com> Date: Sat, 20 Jan 2024 00:03:20 +0300 Subject: [PATCH 4/6] Add libpcrypto I'm doing this at 0:03, this is my excuse. Signed-off-by: team-orangeBlue <63470411+team-orangeBlue@users.noreply.github.com> --- client/src/cmddata.c | 1 + 1 file changed, 1 insertion(+) diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 2f1e4cb2b..9b25e7791 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -39,6 +39,7 @@ #include "mbedtls/entropy.h" // #include "mbedtls/ctr_drbg.h" // random generator #include "atrs.h" // ATR lookup +#include "crypto/libpcrypto.h" // Cryptography uint8_t g_DemodBuffer[MAX_DEMOD_BUF_LEN] = { 0x00 }; size_t g_DemodBufferLen = 0; From 5243377d5797f3ef38d2e089831845c82fb66338 Mon Sep 17 00:00:00 2001 From: team-orangeBlue <63470411+team-orangeBlue@users.noreply.github.com> Date: Sat, 20 Jan 2024 00:11:03 +0300 Subject: [PATCH 5/6] MacOS compilation fix So for macOS, "NONE" isn't an option for PrintAndLogEx. Info it is I guess. Padding fix applied by removing the 4 chars extra. Signed-off-by: team-orangeBlue <63470411+team-orangeBlue@users.noreply.github.com> --- client/src/cmddata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/src/cmddata.c b/client/src/cmddata.c index 9b25e7791..af13984ce 100644 --- a/client/src/cmddata.c +++ b/client/src/cmddata.c @@ -3742,8 +3742,8 @@ static int CmdCryptography(const char *Cmd) { des_encrypt_cbc(dato, dati, datilen, key, iv); char pad[250]; memset(pad, ' ', 4 + 8 + (datilen - 8) * 3); - pad[4 + 8 + (datilen - 8) * 3] = 0; // Make a padding to insert FMCOS macing algorithm guide - PrintAndLogEx(NONE, "%sVV VV VV VV FMCOS MAC", pad); + pad[8 + (datilen - 8) * 3] = 0; // Make a padding to insert FMCOS macing algorithm guide + PrintAndLogEx(INFO, "%sVV VV VV VV FMCOS MAC", pad); } } } From 8146bbe38a0977333e41459142a8a43bd901c777 Mon Sep 17 00:00:00 2001 From: team-orangeBlue <63470411+team-orangeBlue@users.noreply.github.com> Date: Sat, 20 Jan 2024 00:24:07 +0300 Subject: [PATCH 6/6] Update CHANGELOG.md Signed-off-by: team-orangeBlue <63470411+team-orangeBlue@users.noreply.github.com> --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d5143c2d..e353b49b9 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 `data crypto` to encrypt and decrypt data in the proxmark client using built-in methods (@team-orangeBlue) - Changed `hf tune` and `lf tune` - Added an option to show statistical data after tuning (@wh201906) - Changed `lf idteck demod --raw` - now supports raw hex string to decode (@iceman1001) - Changed `lf em 410x demod --bin` - now supports a raw binary string to demodulate. (@iceman1001)