mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 13:23:51 -07:00
mem info - now accepts input id to facility easy testing. Signature offset also triggers erase before to enable easy updates
This commit is contained in:
parent
17eefbcbb6
commit
dff732840f
3 changed files with 59 additions and 18 deletions
|
@ -2202,6 +2202,10 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
Flash_WriteEnable();
|
Flash_WriteEnable();
|
||||||
Flash_Erase4k(3, 0xB);
|
Flash_Erase4k(3, 0xB);
|
||||||
|
} else if (startidx == FLASH_MEM_SIGNATURE_OFFSET) {
|
||||||
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
Flash_WriteEnable();
|
||||||
|
Flash_Erase4k(3, 0xF);
|
||||||
}
|
}
|
||||||
|
|
||||||
res = Flash_Write(startidx, data, len);
|
res = Flash_Write(startidx, data, len);
|
||||||
|
|
|
@ -39,7 +39,10 @@ static int CmdHelp(const char *Cmd);
|
||||||
"9337F21C0C066FFB703D8BFCB5067F309E056772096642C2B1A8F50305D5EC33" \
|
"9337F21C0C066FFB703D8BFCB5067F309E056772096642C2B1A8F50305D5EC33" \
|
||||||
"DB7FB5A3C8AC42EB635AE3C148C910750ABAA280CE82DC2F180F49F30A1393B5"
|
"DB7FB5A3C8AC42EB635AE3C148C910750ABAA280CE82DC2F180F49F30A1393B5"
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------------------
|
||||||
|
// Sample private RSA Key
|
||||||
// Following example RSA-1024 keypair, for test purposes (from common/polarssl/rsa.c)
|
// Following example RSA-1024 keypair, for test purposes (from common/polarssl/rsa.c)
|
||||||
|
|
||||||
// private key - Exponent D
|
// private key - Exponent D
|
||||||
#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
|
#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
|
||||||
"66CA472BC44D253102F8B4A9D3BFA750" \
|
"66CA472BC44D253102F8B4A9D3BFA750" \
|
||||||
|
@ -445,29 +448,39 @@ static int CmdFlashMemInfo(const char *Cmd) {
|
||||||
CLIParserInit(&ctx, "mem info",
|
CLIParserInit(&ctx, "mem info",
|
||||||
"Collect signature and verify it from flash memory",
|
"Collect signature and verify it from flash memory",
|
||||||
"mem info"
|
"mem info"
|
||||||
// "mem info -s"
|
// "mem info -s -d 0102030405060708"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
arg_param_begin,
|
arg_param_begin,
|
||||||
// arg_lit0("s", NULL, "create a signature"),
|
arg_lit0("s", "sign", "create a signature"),
|
||||||
// arg_lit0("w", NULL, "write signature to flash memory"),
|
arg_str0("d", NULL, "<hex>", "flash memory id, 8 hex bytes"),
|
||||||
|
// arg_lit0("w", "write", "write signature to flash memory"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
|
||||||
bool shall_sign = false, shall_write = false;
|
bool shall_sign = false, shall_write = false;
|
||||||
// shall_sign = arg_get_lit(ctx, 1);
|
shall_sign = arg_get_lit(ctx, 1);
|
||||||
// shall_write = arg_get_lit(ctx, 2);
|
|
||||||
|
int dlen = 0;
|
||||||
|
uint8_t id[8] = {0};
|
||||||
|
int res = CLIParamHexToBuf(arg_get_str(ctx, 2), id, sizeof(id), &dlen);
|
||||||
|
|
||||||
|
// shall_write = arg_get_lit(ctx, 3);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
// validate signature data
|
if (dlen > 0 && dlen < sizeof(id) ) {
|
||||||
|
PrintAndLogEx(FAILED, "Error parsing flash memory id, expect 8, got %d", dlen);
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate devicesignature data
|
||||||
rdv40_validation_t mem;
|
rdv40_validation_t mem;
|
||||||
int res = rdv4_get_signature(&mem);
|
res = rdv4_get_signature(&mem);
|
||||||
if (res != PM3_SUCCESS) {
|
if (res != PM3_SUCCESS) {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = rdv4_validate(&mem);
|
res = rdv4_validate(&mem);
|
||||||
|
|
||||||
// Flash ID hash (sha1)
|
// Flash ID hash (sha1)
|
||||||
|
@ -479,6 +492,11 @@ static int CmdFlashMemInfo(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, "--- " _CYAN_("Flash memory Information") " ---------");
|
PrintAndLogEx(INFO, "--- " _CYAN_("Flash memory Information") " ---------");
|
||||||
PrintAndLogEx(INFO, "ID................... %s", sprint_hex_inrow(mem.flashid, sizeof(mem.flashid)));
|
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(INFO, "SHA1................. %s", sprint_hex_inrow(sha_hash, sizeof(sha_hash)));
|
||||||
|
PrintAndLogEx(
|
||||||
|
(res == PM3_SUCCESS) ? SUCCESS : FAILED,
|
||||||
|
"Signature............ ( %s )",
|
||||||
|
(res == PM3_SUCCESS) ? _GREEN_("ok") : _RED_("fail")
|
||||||
|
);
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(INFO, "--- " _CYAN_("RDV4 RSA signature") " ---------------");
|
PrintAndLogEx(INFO, "--- " _CYAN_("RDV4 RSA signature") " ---------------");
|
||||||
for (int i = 0; i < (sizeof(mem.signature) / 32); i++) {
|
for (int i = 0; i < (sizeof(mem.signature) / 32); i++) {
|
||||||
|
@ -520,13 +538,21 @@ static int CmdFlashMemInfo(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, " %.64s", str_pk + 192);
|
PrintAndLogEx(INFO, " %.64s", str_pk + 192);
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
|
||||||
bool is_keyok = (mbedtls_rsa_check_pubkey(&rsa) == 0 || mbedtls_rsa_check_privkey(&rsa) == 0);
|
bool is_keyok = (mbedtls_rsa_check_pubkey(&rsa) == 0);
|
||||||
PrintAndLogEx(
|
PrintAndLogEx(
|
||||||
(is_keyok) ? SUCCESS : FAILED,
|
(is_keyok) ? SUCCESS : FAILED,
|
||||||
"RSA key validation... ( %s )",
|
"RSA public key validation.... ( %s )",
|
||||||
(is_keyok) ? _GREEN_("ok") : _RED_("fail")
|
(is_keyok) ? _GREEN_("ok") : _RED_("fail")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
is_keyok = (mbedtls_rsa_check_privkey(&rsa) == 0);
|
||||||
|
PrintAndLogEx(
|
||||||
|
(is_keyok) ? SUCCESS : FAILED,
|
||||||
|
"RSA private key validation... ( %s )",
|
||||||
|
(is_keyok) ? _GREEN_("ok") : _RED_("fail")
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
// to be verified
|
// to be verified
|
||||||
uint8_t from_device[RRG_RSA_KEY_LEN];
|
uint8_t from_device[RRG_RSA_KEY_LEN];
|
||||||
memcpy(from_device, mem.signature, RRG_RSA_KEY_LEN);
|
memcpy(from_device, mem.signature, RRG_RSA_KEY_LEN);
|
||||||
|
@ -537,6 +563,13 @@ static int CmdFlashMemInfo(const char *Cmd) {
|
||||||
|
|
||||||
// Signing (private key)
|
// Signing (private key)
|
||||||
if (shall_sign) {
|
if (shall_sign) {
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
PrintAndLogEx(INFO, "--- " _CYAN_("Enter signing") " --------------------");
|
||||||
|
|
||||||
|
if (dlen == 8) {
|
||||||
|
mbedtls_sha1(id, sizeof(id), sha_hash);
|
||||||
|
}
|
||||||
|
PrintAndLogEx(INFO, "Signing %s", sprint_hex_inrow(sha_hash, sizeof(sha_hash)));
|
||||||
|
|
||||||
int is_signed = mbedtls_rsa_pkcs1_sign(&rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 20, sha_hash, sign);
|
int is_signed = mbedtls_rsa_pkcs1_sign(&rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 20, sha_hash, sign);
|
||||||
PrintAndLogEx(
|
PrintAndLogEx(
|
||||||
|
@ -555,14 +588,17 @@ static int CmdFlashMemInfo(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify (public key)
|
// Verify (public key)
|
||||||
int is_verified = mbedtls_rsa_pkcs1_verify(&rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 20, sha_hash, from_device);
|
bool is_verified = (mbedtls_rsa_pkcs1_verify(&rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 20, sha_hash, from_device) == 0);
|
||||||
mbedtls_rsa_free(&rsa);
|
mbedtls_rsa_free(&rsa);
|
||||||
|
|
||||||
PrintAndLogEx(
|
PrintAndLogEx(
|
||||||
(is_verified == 0) ? SUCCESS : FAILED,
|
(is_verified) ? SUCCESS : FAILED,
|
||||||
"RSA verification..... ( %s )",
|
"RSA verification..... ( %s )",
|
||||||
(is_verified == 0) ? _GREEN_("ok") : _RED_("fail")
|
(is_verified) ? _GREEN_("ok") : _RED_("fail")
|
||||||
);
|
);
|
||||||
|
if (is_verified) {
|
||||||
|
PrintAndLogEx(SUCCESS, "Genuine Proxmark3 RDV4 signature detected");
|
||||||
|
}
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
|
|
@ -39,8 +39,8 @@ Page 3:
|
||||||
* used by Proxmark3 RDV4 specific functions: flash signature and keys dictionaries, see below for details
|
* used by Proxmark3 RDV4 specific functions: flash signature and keys dictionaries, see below for details
|
||||||
* to dump it: `mem dump f page3_dump o 196608 l 65536`
|
* to dump it: `mem dump f page3_dump o 196608 l 65536`
|
||||||
* to erase it:
|
* to erase it:
|
||||||
* **Beware** it will erase your flash signature (see below) so better to back it up first as you won't be able to regenerate it by yourself!
|
* **Beware** it will erase your flash signature so better to back it up first as you won't be able to regenerate it by yourself!
|
||||||
* It's possible to erase completely page 3 by erase the entire flash memory with the voluntarily undocumented command `mem wipe i`.
|
* edit the source code to enable Page 3 as a valid input in the `mem wipe` command.
|
||||||
* Updating keys dictionaries doesn't require to erase page 3.
|
* Updating keys dictionaries doesn't require to erase page 3.
|
||||||
|
|
||||||
## Page3 Layout
|
## Page3 Layout
|
||||||
|
@ -64,7 +64,7 @@ Page3 is used as follows by the Proxmark3 RDV4 firmware:
|
||||||
* length: 1 sector (actually only a few bytes are used to store `t55xx_config` structure)
|
* length: 1 sector (actually only a few bytes are used to store `t55xx_config` structure)
|
||||||
|
|
||||||
* **RSA SIGNATURE**, see below for details
|
* **RSA SIGNATURE**, see below for details
|
||||||
* offset: page 3 sector 15 (0xF) offset 0xF7F @ 3*0x10000+15*0x1000+0xF7F=0x3FF7F
|
* offset: page 3 sector 15 (0xF) offset 0xF7F @ 3*0x10000+15*0x1000+0xF7F=0x3FF7F (decimal 262015)
|
||||||
* length: 128 bytes
|
* length: 128 bytes
|
||||||
* offset should have been 0x3FF80 but historically it's one byte off and therefore the last byte of the flash is unused
|
* offset should have been 0x3FF80 but historically it's one byte off and therefore the last byte of the flash is unused
|
||||||
|
|
||||||
|
@ -91,5 +91,6 @@ You can verify it with: `mem info`
|
||||||
[+] RSA Verification ok
|
[+] RSA Verification ok
|
||||||
```
|
```
|
||||||
|
|
||||||
For a backup of the signature: `mem dump p f flash_signature_dump o 262015 l 128`
|
To make a backup of the signature to file:
|
||||||
|
`mem dump p f flash_signature_dump o 262015 l 128`
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue