diff --git a/client/cmdscripts/rdv4_init_extflash.cmd b/client/cmdscripts/rdv4_init_extflash.cmd index 2cae05294..6fe6de3ba 100755 --- a/client/cmdscripts/rdv4_init_extflash.cmd +++ b/client/cmdscripts/rdv4_init_extflash.cmd @@ -1,6 +1,6 @@ #!/usr/bin/env -S pm3 -s -mem load f mfc_default_keys m -mem load f t55xx_default_pwds t -mem load f iclass_default_keys i +mem load -f mfc_default_keys --mfc +mem load -f t55xx_default_pwds --t55xx +mem load -f iclass_default_keys --iclass lf t55xx deviceconfig z p diff --git a/client/luascripts/init_rdv4.lua b/client/luascripts/init_rdv4.lua index bc18dc0a9..a724ed189 100644 --- a/client/luascripts/init_rdv4.lua +++ b/client/luascripts/init_rdv4.lua @@ -74,9 +74,9 @@ function main(args) -- Upload dictionaries print('Uploading dictionaries to RDV4 flashmemory') print(dash) - core.console('mem load f mfc_default_keys m') - core.console('mem load f t55xx_default_pwds t') - core.console('mem load f iclass_default_keys i') + core.console('mem load -f mfc_default_keys --mfc') + core.console('mem load -f t55xx_default_pwds --t55xx') + core.console('mem load -f iclass_default_keys --iclass') print(dash) -- T55x7 Device configuration diff --git a/client/src/cmdflashmem.c b/client/src/cmdflashmem.c index e90e6025c..c3cf85585 100644 --- a/client/src/cmdflashmem.c +++ b/client/src/cmdflashmem.c @@ -8,16 +8,13 @@ // Proxmark3 RDV40 Flash memory commands //----------------------------------------------------------------------------- #include "cmdflashmem.h" - #include - -#include "cmdparser.h" // command_t - +#include "cmdparser.h" // command_t +#include "cliparser.h" #include "pmflash.h" -#include "fileutils.h" //saveFile -#include "comms.h" //getfromdevice +#include "fileutils.h" // saveFile +#include "comms.h" // getfromdevice #include "cmdflashmemspiffs.h" // spiffs commands - #include "rsa.h" #include "sha1.h" @@ -29,90 +26,34 @@ static int CmdHelp(const char *Cmd); -static int usage_flashmem_spibaud(void) { - PrintAndLogEx(NORMAL, "Usage: mem spibaud [h] "); - PrintAndLogEx(NORMAL, "Options:"); - PrintAndLogEx(NORMAL, " h this help"); - PrintAndLogEx(NORMAL, " SPI baudrate in MHz [24|48]"); - PrintAndLogEx(NORMAL, " "); - PrintAndLogEx(NORMAL, " If >= 24MHz, FASTREADS instead of READS instruction will be used."); - PrintAndLogEx(NORMAL, " Reading Flash ID will virtually always fail under 48MHz setting"); - PrintAndLogEx(NORMAL, " Unless you know what you are doing, please stay at 24MHz"); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " mem spibaud 48"); - return PM3_SUCCESS; -} - -static int usage_flashmem_load(void) { - PrintAndLogEx(NORMAL, "Loads binary file into flash memory on device"); - PrintAndLogEx(NORMAL, "Usage: mem load [o ] f [m|t|i]"); - PrintAndLogEx(NORMAL, "Warning: mem area to be written must have been wiped first"); - PrintAndLogEx(NORMAL, "(this is already taken care when loading dictionaries)"); - PrintAndLogEx(NORMAL, " o : offset in memory"); - PrintAndLogEx(NORMAL, " f : file name"); - PrintAndLogEx(NORMAL, " m : upload 6 bytes keys (mifare key dictionary)"); - PrintAndLogEx(NORMAL, " i : upload 8 bytes keys (iClass key dictionary)"); - PrintAndLogEx(NORMAL, " t : upload 4 bytes keys (pwd dictionary)"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " mem load f myfile"); // upload file myfile at default offset 0 - PrintAndLogEx(NORMAL, " mem load f myfile o 1024"); // upload file myfile at offset 1024 - PrintAndLogEx(NORMAL, " mem load f mfc_default_keys m"); - PrintAndLogEx(NORMAL, " mem load f t55xx_default_pwds t"); - PrintAndLogEx(NORMAL, " mem load f iclass_default_keys i"); - return PM3_SUCCESS; -} -static int usage_flashmem_dump(void) { - PrintAndLogEx(NORMAL, "Dumps flash memory on device into a file or in console"); - PrintAndLogEx(NORMAL, " Usage: mem dump [o ] [l ] [f ] [p]"); - PrintAndLogEx(NORMAL, " o : offset in memory"); - PrintAndLogEx(NORMAL, " l : length"); - PrintAndLogEx(NORMAL, " f : file name"); - PrintAndLogEx(NORMAL, " p : print dump in console"); - PrintAndLogEx(NORMAL, " You must specify at lease option f or option p, both if you wish"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " mem dump f myfile"); // download whole flashmem to file myfile - PrintAndLogEx(NORMAL, " mem dump p o 262015 l 128"); // display 128 bytes from offset 262015 (RSA sig) - PrintAndLogEx(NORMAL, " mem dump p f myfile o 241664 l 58"); // download and display 58 bytes from offset 241664 to file myfile - return PM3_SUCCESS; -} -static int usage_flashmem_wipe(void) { - - PrintAndLogEx(WARNING, "[OBS] use with caution."); - PrintAndLogEx(NORMAL, "Wipe flash memory on device, which fills memory with 0xFF\n"); - - PrintAndLogEx(NORMAL, " Usage: mem wipe p "); - PrintAndLogEx(NORMAL, " p : 0,1,2 page memory"); -// PrintAndLogEx(NORMAL, " i : inital total wipe"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " mem wipe p 0"); // wipes first page. - return PM3_SUCCESS; -} -static int usage_flashmem_info(void) { - PrintAndLogEx(NORMAL, "Collect signature and verify it from flash memory\n"); - PrintAndLogEx(NORMAL, " Usage: mem info"); -// PrintAndLogEx(NORMAL, " s : create a signature"); -// PrintAndLogEx(NORMAL, " w : write signature to flash memory"); - PrintAndLogEx(NORMAL, ""); - PrintAndLogEx(NORMAL, "Examples:"); - PrintAndLogEx(NORMAL, " mem info"); -// PrintAndLogEx(NORMAL, " mem info s"); - return PM3_SUCCESS; -} - static int CmdFlashmemSpiBaudrate(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, " mem baudrate 48", + "Set the baudrate for the SPI flash memory communications.\n" + "Reading Flash ID will virtually always fail under 48MHz setting.\n" + "Unless you know what you are doing, please stay at 24MHz.\n" + "If >= 24MHz, FASTREADS instead of READS instruction will be used.", + "mem baudrate --mhz 48" + ); + + void *argtable[] = { + arg_param_begin, + arg_int1(NULL, "mhz", "<24|48>", "SPI baudrate in MHz"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + int br = arg_get_int_def(ctx, 1, -1); + CLIParserFree(ctx); - char ctmp = tolower(param_getchar(Cmd, 0)); - if (strlen(Cmd) < 1 || ctmp == 'h') { - return usage_flashmem_spibaud(); + if (br == -1) { + PrintAndLogEx(ERR, "failed to get baudrate"); + return PM3_EINVARG; } - uint32_t baudrate = param_get32ex(Cmd, 0, 0, 10); - baudrate = baudrate * 1000000; + uint32_t baudrate = br * 1000000; if (baudrate != FLASH_BAUD && baudrate != FLASH_MINBAUD) { - usage_flashmem_spibaud(); + PrintAndLogEx(ERR, "wrong baudrate. Only 24 or 48 is allowed"); return PM3_EINVARG; } SendCommandNG(CMD_FLASHMEM_SET_SPIBAUDRATE, (uint8_t *)&baudrate, sizeof(uint32_t)); @@ -121,52 +62,50 @@ static int CmdFlashmemSpiBaudrate(const char *Cmd) { static int CmdFlashMemLoad(const char *Cmd) { - uint32_t start_index = 0; + CLIParserContext *ctx; + CLIParserInit(&ctx, "mem load", + "Loads binary file into flash memory on device\n" + "Warning: mem area to be written must have been wiped first\n" + "( this is already taken care when loading dictionaries )", + "mem load -f myfile -> upload file myfile values at default offset 0\n" + "mem load -f myfile -o 1024 -> upload file myfile values at offset 1024\n" + "mem load -f mfc_default_keys -m -> upload MFC keys\n" + "mem load -f t55xx_default_pwds -t -> upload T55XX passwords\n" + "mem load -f iclass_default_keys -i -> upload iCLASS keys\n" + ); + + void *argtable[] = { + arg_param_begin, + arg_int0("o", "offset", "", "offset in memory"), + arg_lit0("m", "mifare,mfc", "upload 6 bytes keys (mifare key dictionary)"), + arg_lit0("i", "iclass", "upload 8 bytes keys (iClass key dictionary)"), + arg_lit0("t", "t55xx", "upload 4 bytes keys (password dictionary)"), + arg_strx0("f", "file", "", "file name"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + int offset = arg_get_int_def(ctx, 1, 0); + bool is_mfc = arg_get_lit(ctx, 2); + bool is_iclass = arg_get_lit(ctx, 3); + bool is_t55xx = arg_get_lit(ctx, 4); + int fnlen = 0; char filename[FILE_PATH_SIZE] = {0}; - bool errors = false; - uint8_t cmdp = 0; + CLIParamStrToBuf(arg_get_str(ctx, 5), (uint8_t*)filename, FILE_PATH_SIZE, &fnlen); + CLIParserFree(ctx); + Dictionary_t d = DICTIONARY_NONE; - - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_flashmem_load(); - case 'f': - if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { - PrintAndLogEx(FAILED, "Filename too long"); - errors = true; - break; - } - cmdp += 2; - break; - case 'o': - start_index = param_get32ex(Cmd, cmdp + 1, 0, 10); - cmdp += 2; - break; - case 'm': - d = DICTIONARY_MIFARE; - cmdp++; - break; - case 't': - d = DICTIONARY_T55XX; - cmdp++; - break; - case 'i': - d = DICTIONARY_ICLASS; - cmdp++; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } + if (is_mfc) { + d = DICTIONARY_MIFARE; + PrintAndLogEx(INFO, "treating file as MIFARE Classic keys"); + } else if (is_iclass) { + d = DICTIONARY_ICLASS; + PrintAndLogEx(INFO, "treating file as iCLASS keys"); + } else if (is_t55xx) { + d = DICTIONARY_T55XX; + PrintAndLogEx(INFO, "treating file as T55xx passwords"); } - //Validations - if (errors || cmdp == 0) { - usage_flashmem_load(); - return PM3_EINVARG; - } size_t datalen = 0; uint32_t keycount = 0; int res = 0; @@ -174,7 +113,7 @@ static int CmdFlashMemLoad(const char *Cmd) { switch (d) { case DICTIONARY_MIFARE: - start_index = DEFAULT_MF_KEYS_OFFSET; + offset = DEFAULT_MF_KEYS_OFFSET; res = loadFileDICTIONARY(filename, data + 2, &datalen, 6, &keycount); if (res || !keycount) { free(data); @@ -189,7 +128,7 @@ static int CmdFlashMemLoad(const char *Cmd) { datalen += 2; break; case DICTIONARY_T55XX: - start_index = DEFAULT_T55XX_KEYS_OFFSET; + offset = DEFAULT_T55XX_KEYS_OFFSET; res = loadFileDICTIONARY(filename, data + 2, &datalen, 4, &keycount); if (res || !keycount) { free(data); @@ -204,7 +143,7 @@ static int CmdFlashMemLoad(const char *Cmd) { datalen += 2; break; case DICTIONARY_ICLASS: - start_index = DEFAULT_ICLASS_KEYS_OFFSET; + offset = DEFAULT_ICLASS_KEYS_OFFSET; res = loadFileDICTIONARY(filename, data + 2, &datalen, 8, &keycount); if (res || !keycount) { free(data); @@ -253,13 +192,13 @@ static int CmdFlashMemLoad(const char *Cmd) { clearCommandBuffer(); - SendCommandOLD(CMD_FLASHMEM_WRITE, start_index + bytes_sent, bytes_in_packet, 0, data + bytes_sent, bytes_in_packet); + SendCommandOLD(CMD_FLASHMEM_WRITE, offset + bytes_sent, bytes_in_packet, 0, data + bytes_sent, bytes_in_packet); bytes_remaining -= bytes_in_packet; bytes_sent += bytes_in_packet; PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { + if (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); conn.block_after_ACK = false; free(data); @@ -276,54 +215,37 @@ static int CmdFlashMemLoad(const char *Cmd) { conn.block_after_ACK = false; free(data); - PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%zu")" bytes to offset "_GREEN_("%u"), datalen, start_index); + PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%zu")" bytes to offset "_GREEN_("%u"), datalen, offset); return PM3_SUCCESS; } + static int CmdFlashMemDump(const char *Cmd) { + CLIParserContext *ctx; + CLIParserInit(&ctx, "mem dump", + "Dumps flash memory on device into a file or view in console", + "mem dump -f myfile -> download all flashmem to file\n" + "mem dump --view -o 262015 --len 128 -> display 128 bytes from offset 262015 (RSA sig)\n" + "mem dump --view -f myfile -o 241664 --len 58 -> display 58 bytes from offset 241664 and save to file" + ); + + void *argtable[] = { + arg_param_begin, + arg_int0("o", "offset", "", "offset in memory"), + arg_int0("l", "len", "", "length"), + arg_lit0("v", "view", "view dump"), + arg_strx0("f", "file", "", "file name"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + int offset = arg_get_int_def(ctx, 1, 0); + int len = arg_get_int_def(ctx, 2, FLASH_MEM_MAX_SIZE); + bool view = arg_get_lit(ctx, 3); + int fnlen = 0; char filename[FILE_PATH_SIZE] = {0}; - uint8_t cmdp = 0; - bool errors = false; - bool print = false; - uint32_t start_index = 0, len = FLASH_MEM_MAX_SIZE; - - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_flashmem_dump(); - case 'l': - len = param_get32ex(Cmd, cmdp + 1, FLASH_MEM_MAX_SIZE, 10); - cmdp += 2; - break; - case 'o': - start_index = param_get32ex(Cmd, cmdp + 1, 0, 10); - cmdp += 2; - break; - case 'p': - print = true; - cmdp += 1; - break; - case 'f': - //File handling - if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) { - PrintAndLogEx(FAILED, "Filename too long"); - errors = true; - break; - } - cmdp += 2; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } - } - - //Validations - if (errors || cmdp == 0) { - usage_flashmem_dump(); - return PM3_EINVARG; - } + CLIParamStrToBuf(arg_get_str(ctx, 4), (uint8_t*)filename, FILE_PATH_SIZE, &fnlen); + CLIParserFree(ctx); uint8_t *dump = calloc(len, sizeof(uint8_t)); if (!dump) { @@ -331,14 +253,15 @@ static int CmdFlashMemDump(const char *Cmd) { return PM3_EMALLOC; } - PrintAndLogEx(INFO, "downloading "_YELLOW_("%u")" bytes from flashmem", len); - if (!GetFromDevice(FLASH_MEM, dump, len, start_index, NULL, 0, NULL, -1, true)) { - PrintAndLogEx(FAILED, "ERROR; downloading from flashmemory"); + PrintAndLogEx(INFO, "downloading "_YELLOW_("%u")" bytes from flash memory", len); + if (!GetFromDevice(FLASH_MEM, dump, len, offset, NULL, 0, NULL, -1, true)) { + PrintAndLogEx(FAILED, "ERROR; downloading from flash memory"); free(dump); return PM3_EFLASH; } - if (print) { + if (view) { + PrintAndLogEx(INFO, "---- " _CYAN_("data") " ---------------"); print_hex_break(dump, len, 32); } @@ -350,39 +273,32 @@ static int CmdFlashMemDump(const char *Cmd) { free(dump); return PM3_SUCCESS; } + static int CmdFlashMemWipe(const char *Cmd) { - uint8_t cmdp = 0; - bool errors = false; - bool initalwipe = false; - uint8_t page = 0; - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_flashmem_wipe(); - case 'p': - page = param_get8ex(Cmd, cmdp + 1, 0, 10); - if (page > 2) { - PrintAndLogEx(WARNING, "page must be 0, 1 or 2"); - errors = true; - break; - } - cmdp += 2; - break; - case 'i': - initalwipe = true; - cmdp++; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } - } + CLIParserContext *ctx; + CLIParserInit(&ctx, "mem wipe", + "Wipe flash memory on device, which fills it with 0xFF\n" + _WHITE_("[ ") _RED_("!!! OBS") " ] use with caution", + "mem wipe -p 0 -> wipes first page" +// "mem wipe -i -> inital total wipe" + ); - //Validations - if (errors || cmdp == 0) { - usage_flashmem_wipe(); + void *argtable[] = { + arg_param_begin, + arg_int0("p", NULL, "", "0,1,2 page memory"), +// arg_lit0("i", NULL, "inital total wipe"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + bool initalwipe = false; + int page = arg_get_int_def(ctx, 1, -1); +// initalwipe = arg_get_lit(ctx, 2); + CLIParserFree(ctx); + + if (page < 0 || page > 2 ) { + PrintAndLogEx(WARNING, "page must be 0, 1 or 2"); return PM3_EINVARG; } @@ -393,59 +309,51 @@ static int CmdFlashMemWipe(const char *Cmd) { PrintAndLogEx(WARNING, "timeout while waiting for reply."); return PM3_ETIMEOUT; } + + const char* msg = "Flash WIPE "; uint8_t isok = resp.oldarg[0] & 0xFF; if (isok) - PrintAndLogEx(SUCCESS, "Flash WIPE ok"); + PrintAndLogEx(SUCCESS, "%s ( " _GREEN_("ok")" )", msg); else { - PrintAndLogEx(FAILED, "Flash WIPE failed"); + PrintAndLogEx(FAILED, "%s ( " _RED_("failed") " )", msg); return PM3_EFLASH; } return PM3_SUCCESS; } + static int CmdFlashMemInfo(const char *Cmd) { - uint8_t sha_hash[20] = {0}; - mbedtls_rsa_context rsa; + CLIParserContext *ctx; + CLIParserInit(&ctx, "mem info", + "Collect signature and verify it from flash memory", + "mem info" +// "mem info -s" + ); - uint8_t cmdp = 0; - bool errors = false, shall_write = false, shall_sign = false; - while (param_getchar(Cmd, cmdp) != 0x00 && !errors) { - switch (tolower(param_getchar(Cmd, cmdp))) { - case 'h': - return usage_flashmem_info(); - case 's': { - shall_sign = true; - cmdp++; - break; - } - case 'w': - shall_write = true; - cmdp++; - break; - default: - PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); - errors = true; - break; - } - } + void *argtable[] = { + arg_param_begin, +// arg_lit0("s", NULL, "create a signature"), +// arg_lit0("w", NULL, "write signature to flash memory"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, true); - //Validations - if (errors) { - usage_flashmem_info(); - return PM3_EINVARG; - } + bool shall_sign = false, shall_write = false; +// shall_sign = arg_get_lit(ctx, 1); +// shall_write = arg_get_lit(ctx, 2); + CLIParserFree(ctx); clearCommandBuffer(); SendCommandNG(CMD_FLASHMEM_INFO, NULL, 0); PacketResponseNG resp; - if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) { - PrintAndLogEx(WARNING, "timeout while waiting for reply."); + if (WaitForResponseTimeout(CMD_ACK, &resp, 2500) == false) { + PrintAndLogEx(WARNING, "timeout while waiting for reply"); return PM3_ETIMEOUT; } uint8_t isok = resp.oldarg[0] & 0xFF; - if (!isok) { + if (isok == false) { PrintAndLogEx(FAILED, "failed"); return PM3_EFLASH; } @@ -455,15 +363,20 @@ static int CmdFlashMemInfo(const char *Cmd) { memcpy(&mem, (rdv40_validation_t *)resp.data.asBytes, sizeof(rdv40_validation_t)); // Flash ID hash (sha1) + uint8_t sha_hash[20] = {0}; mbedtls_sha1(mem.flashid, sizeof(mem.flashid), sha_hash); // print header - PrintAndLogEx(INFO, "\n--- Flash memory Information ---------"); - PrintAndLogEx(INFO, "-------------------------------------------------------------"); - PrintAndLogEx(INFO, "ID | %s", sprint_hex(mem.flashid, sizeof(mem.flashid))); - PrintAndLogEx(INFO, "SHA1 | %s", sprint_hex(sha_hash, sizeof(sha_hash))); - PrintAndLogEx(INFO, "RSA SIGNATURE |"); - print_hex_break(mem.signature, sizeof(mem.signature), 32); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("Flash memory Information") " ---------"); +// PrintAndLogEx(INFO, "-----------------------------------------------------------------"); + PrintAndLogEx(INFO, "ID................... %s", sprint_hex_inrow(mem.flashid, sizeof(mem.flashid))); + PrintAndLogEx(INFO, "SHA1................. %s", sprint_hex_inrow(sha_hash, sizeof(sha_hash))); + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("RDV4 RSA signature") " ---------------"); + for (int i = 0; i < (sizeof(mem.signature) / 32); i++) { + PrintAndLogEx(INFO, " %s", sprint_hex_inrow(mem.signature + (i * 32), 32)); + } //------------------------------------------------------------------------------- // RRG Public RSA Key @@ -473,7 +386,10 @@ static int CmdFlashMemInfo(const char *Cmd) { #define RSA_E "010001" // public key modulus N -#define RSA_N "E28D809BF323171D11D1ACA4C32A5B7E0A8974FD171E75AD120D60E9B76968FF4B0A6364AE50583F9555B8EE1A725F279E949246DF0EFCE4C02B9F3ACDCC623F9337F21C0C066FFB703D8BFCB5067F309E056772096642C2B1A8F50305D5EC33DB7FB5A3C8AC42EB635AE3C148C910750ABAA280CE82DC2F180F49F30A1393B5" +#define RSA_N "E28D809BF323171D11D1ACA4C32A5B7E0A8974FD171E75AD120D60E9B76968FF" \ + "4B0A6364AE50583F9555B8EE1A725F279E949246DF0EFCE4C02B9F3ACDCC623F" \ + "9337F21C0C066FFB703D8BFCB5067F309E056772096642C2B1A8F50305D5EC33" \ + "DB7FB5A3C8AC42EB635AE3C148C910750ABAA280CE82DC2F180F49F30A1393B5" //------------------------------------------------------------------------------- // Example RSA-1024 keypair, for test purposes (from common/polarssl/rsa.c) @@ -516,9 +432,9 @@ static int CmdFlashMemInfo(const char *Cmd) { "F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \ "A74206CEC169D74BF5A8C50D6F48EA08" - #define KEY_LEN 128 + mbedtls_rsa_context rsa; mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V15, 0); rsa.len = KEY_LEN; @@ -532,13 +448,31 @@ static int CmdFlashMemInfo(const char *Cmd) { mbedtls_mpi_read_string(&rsa.DQ, 16, RSA_DQ); mbedtls_mpi_read_string(&rsa.QP, 16, RSA_QP); - PrintAndLogEx(INFO, "KEY length | %d", KEY_LEN); - bool is_keyok = (mbedtls_rsa_check_pubkey(&rsa) == 0 || mbedtls_rsa_check_privkey(&rsa) == 0); + + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(INFO, "--- " _CYAN_("RDV4 RSA Public key") " --------------"); + + char str_exp[10]; + char str_pk[261]; + size_t exlen = 0, pklen = 0; + mbedtls_mpi_write_string(&rsa.E, 16, str_exp, sizeof(str_exp), &exlen); + mbedtls_mpi_write_string(&rsa.N, 16, str_pk, sizeof(str_pk), &pklen); + + PrintAndLogEx(INFO, "Len.................. %u", rsa.len); + PrintAndLogEx(INFO, "Exponent............. %s", str_exp); + PrintAndLogEx(INFO, "Public key modulus N"); + PrintAndLogEx(INFO, " %.64s", str_pk); + PrintAndLogEx(INFO, " %.64s", str_pk + 64); + PrintAndLogEx(INFO, " %.64s", str_pk + 128); + PrintAndLogEx(INFO, " %.64s", str_pk + 192); + + PrintAndLogEx(NORMAL, ""); + const char *msgkey = "RSA key validation... "; if (is_keyok) - PrintAndLogEx(SUCCESS, "RSA key validation ok"); + PrintAndLogEx(SUCCESS, "%s( " _GREEN_("ok") " )", msgkey); else - PrintAndLogEx(FAILED, "RSA key validation failed"); + PrintAndLogEx(FAILED, "%s( " _RED_("failed") " )", msgkey); // uint8_t from_device[KEY_LEN]; @@ -554,10 +488,11 @@ static int CmdFlashMemInfo(const char *Cmd) { if (shall_sign) { int is_signed = mbedtls_rsa_pkcs1_sign(&rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 20, sha_hash, sign); + const char *msgsign = "RSA signing.......... "; if (is_signed == 0) - PrintAndLogEx(SUCCESS, "RSA Signing ok"); + PrintAndLogEx(SUCCESS, "%s( " _GREEN_("ok") " )", msgsign); else - PrintAndLogEx(FAILED, "RSA Signing failed"); + PrintAndLogEx(FAILED, "%s( " _RED_("failed") " )", msgsign); if (shall_write) { // save to mem @@ -574,29 +509,33 @@ static int CmdFlashMemInfo(const char *Cmd) { } } - PrintAndLogEx(INFO, "Signed | "); - print_hex_break(sign, sizeof(sign), 32); + PrintAndLogEx(INFO, "Signed"); + for (int i = 0; i < (sizeof(sign) / 32); i++) { + PrintAndLogEx(INFO, " %s", sprint_hex_inrow(sign + (i * 32), 32)); + } } // Verify (public key) int is_verified = mbedtls_rsa_pkcs1_verify(&rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 20, sha_hash, from_device); + const char *msgverify = "RSA verification..... "; if (is_verified == 0) - PrintAndLogEx(SUCCESS, "RSA Verification ok"); + PrintAndLogEx(SUCCESS, "%s( " _GREEN_("ok") " )", msgverify); else - PrintAndLogEx(FAILED, "RSA Verification failed"); + PrintAndLogEx(FAILED, "%s( " _RED_("failed") " )", msgverify); + PrintAndLogEx(NORMAL, ""); mbedtls_rsa_free(&rsa); return PM3_SUCCESS; } static command_t CommandTable[] = { {"help", CmdHelp, AlwaysAvailable, "This help"}, - {"spiffs", CmdFlashMemSpiFFS, IfPm3Flash, "High level SPI FileSystem Flash manipulation [rdv40]"}, - {"spibaud", CmdFlashmemSpiBaudrate, IfPm3Flash, "Set Flash memory Spi baudrate [rdv40]"}, - {"info", CmdFlashMemInfo, IfPm3Flash, "Flash memory information [rdv40]"}, - {"load", CmdFlashMemLoad, IfPm3Flash, "Load data into flash memory [rdv40]"}, - {"dump", CmdFlashMemDump, IfPm3Flash, "Dump data from flash memory [rdv40]"}, - {"wipe", CmdFlashMemWipe, IfPm3Flash, "Wipe data from flash memory [rdv40]"}, + {"baudrate", CmdFlashmemSpiBaudrate, IfPm3Flash, "Set Flash memory Spi baudrate"}, + {"spiffs", CmdFlashMemSpiFFS, IfPm3Flash, "High level SPI FileSystem Flash manipulation"}, + {"info", CmdFlashMemInfo, IfPm3Flash, "Flash memory information"}, + {"load", CmdFlashMemLoad, IfPm3Flash, "Load data into flash memory"}, + {"dump", CmdFlashMemDump, IfPm3Flash, "Dump data from flash memory"}, + {"wipe", CmdFlashMemWipe, IfPm3Flash, "Wipe data from flash memory"}, {NULL, NULL, NULL, NULL} };