mem * - now uses cliparser

This commit is contained in:
iceman1001 2020-10-03 17:12:58 +02:00
commit cc245016ea
3 changed files with 212 additions and 273 deletions

View file

@ -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

View file

@ -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

View file

@ -8,16 +8,13 @@
// Proxmark3 RDV40 Flash memory commands
//-----------------------------------------------------------------------------
#include "cmdflashmem.h"
#include <ctype.h>
#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] <baudrate>");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h this help");
PrintAndLogEx(NORMAL, " <baudrate> 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 <offset>] f <file name> [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> : offset in memory");
PrintAndLogEx(NORMAL, " f <filename> : 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 <offset>] [l <length>] [f <file name>] [p]");
PrintAndLogEx(NORMAL, " o <offset> : offset in memory");
PrintAndLogEx(NORMAL, " l <length> : length");
PrintAndLogEx(NORMAL, " f <filename> : 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 <page>");
PrintAndLogEx(NORMAL, " p <page> : 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", "<dec>", "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", "<filename>", "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", "<dec>", "offset in memory"),
arg_int0("l", "len", "<dec>", "length"),
arg_lit0("v", "view", "view dump"),
arg_strx0("f", "file", "<filename>", "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, "<dec>", "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}
};