mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
this commit refactors the signature checks. First we introduce a common pm3 generic private / public key pair in order to allow for users to self sign their own modded device. The verification checks now looks at both hard coded public keys. If a vendor wants to add their own public key thus allowing for a simple way for us to identify their devices they can now do so. The downside is that the firmware mismatch detection becomes a bit dodgy. mem info; mem info -v; mem info -s -p <filename.pem>; mem info -s -p <filename.pem> -w contains the changes. OBS! when -w be careful to not overwrite your genuine RDV4 signature. As always, with great power comes great responsibility
This commit is contained in:
+6
-4
@@ -3,15 +3,17 @@ 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]
|
||||
- Changed `mem info` and how the signature handling is done (@iceman1001)
|
||||
- Added `client/resources/pm3_generic_private_key.pem` in order to self-sign a modded device (@iceman1001)
|
||||
- Fix `hf mfdes value --op clear` commands for clearing more than 0x80000000 values and getfilesettings mac mode (@merlokk)
|
||||
- Added ATR fingerprinting to `hf 14a/14b info` (@doegox)
|
||||
|
||||
## [Phrack.4.20728][2025-09-11]
|
||||
- Change `lf t55xx restore` - now skips writing block0 if its all zeros (@iceman1001)
|
||||
- Changed `lf t55xx restore` - now skips writing block0 if its all zeros (@iceman1001)
|
||||
- Added `HID Simplex Grinnell 36-bit` - Improved Simplex decoder (@datafx, @henrygab)
|
||||
- Change `lf search` - also test for chipset even if there was just signal noice (@iceman1001)
|
||||
- Changed `lf search` - also test for chipset even if there was just signal noice (@iceman1001)
|
||||
- Added detection of PCF 7961 , thanks progman (@iceman1001)
|
||||
- Change `reveng -g` - now correctly take 1024 hexstring as input (@iceman1001)
|
||||
- Changed `reveng -g` - now correctly take 1024 hexstring as input (@iceman1001)
|
||||
- Added `--override` parameter to NDEF read for overriding MAD CRC check (@iceman1001)
|
||||
- Added `hf saflok` commands (@stiebeljoshua)
|
||||
- Added `ntag_clean.lua` script for easier NTAG memory wipe (@trigat)
|
||||
@@ -19,7 +21,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||
- Added `lf t55xx view` - now viewing of T55XX dump files is possible (@iceman1001)
|
||||
- Fixed `lf indala cone` - now writing the right bits when using `--fc` and `--cn`
|
||||
- Changed readline hack logic for async dbg msg to be ready for readline 8.3 (@doegox)
|
||||
- Improved To avoid conflicts with ModemManager on Linux, is recommended to masking the service (@grugnoymeme)
|
||||
- Changed documentation to avoid conflicts with ModemManager on Linux, is recommended to masking the service (@grugnoymeme)
|
||||
- Changed `data crypto` - now also handles AES-256 (@iceman1001)
|
||||
- Changed `hf mfdes info` - add recognition of Swissbit iShield Key Mifare (@ah01)
|
||||
- Changed `hf mf info` - add detection for unknown backdoor keys and for some backdoor variants (@doegox)
|
||||
|
||||
+9
-2
@@ -2968,7 +2968,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
LED_B_OFF();
|
||||
break;
|
||||
}
|
||||
case CMD_FLASHMEM_INFO: {
|
||||
case CMD_FLASHMEM_GET_SIGNATURE: {
|
||||
|
||||
LED_B_ON();
|
||||
|
||||
@@ -2983,12 +2983,19 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||
FlashStop();
|
||||
}
|
||||
|
||||
reply_ng(CMD_FLASHMEM_INFO, (isok) ? PM3_SUCCESS : PM3_EFLASH, (uint8_t *)info, sizeof(rdv40_validation_t));
|
||||
reply_ng(CMD_FLASHMEM_GET_SIGNATURE, (isok) ? PM3_SUCCESS : PM3_EFLASH, (uint8_t *)info, sizeof(rdv40_validation_t));
|
||||
BigBuf_free();
|
||||
|
||||
LED_B_OFF();
|
||||
break;
|
||||
}
|
||||
case CMD_FLASHMEM_GET_INFO: {
|
||||
LED_B_ON();
|
||||
spi_flash_t *spi = flash_get_info();
|
||||
reply_ng(CMD_FLASHMEM_GET_INFO, PM3_SUCCESS, (uint8_t *)spi, sizeof(spi_flash_t));
|
||||
LED_B_OFF();
|
||||
break;
|
||||
}
|
||||
case CMD_FLASHMEM_PAGES64K: {
|
||||
|
||||
LED_B_ON();
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAPrs5grcEJNNgoTl
|
||||
KgYSHfAYeGqUVyy7DzGNzpQryLBN3eVIj2+2oQB/BfW4wGpfg35s/R0ohCZOjJ81
|
||||
oLK1gFx+mvFMmzUP9MzNDxMs/3TumiSQqEQSPQYi8BQWLXbd73pfJP6p40+mCK61
|
||||
i3wQtL/H85xL/G5GNQOg3bubdz4BAgMBAAECgYB8QTVFKWZX2ykHsAdYTD5g920h
|
||||
seVdNCA49LTYMLpHe7em44CL3E7r1PrZjCxUQIn33/aTKs4NvhXqfP7fn/s4V0CZ
|
||||
mjZSvWQ3ts5CYOGa8LWgaU7qYREPJKVDRgmMFiRntbP9woNLOhnQkZEs75KCKgnT
|
||||
kDndVTtxlxbn2evKVQJBAP8M7RNI1JuiE/gTq9dL9q4ZKo7NpATanFKwgd7gCooN
|
||||
anlfpMxhN7FgQRcfjHpndmpMQXhe5UE6C+XcziZj2TcCQQD73AqHNjU6hI0/rgiQ
|
||||
MXiiC+Oe5G7QPxRwvbjTuLghC/lWCDd96LkKSZLZR0pmSj5nldB0/dDXiZUNF/Q+
|
||||
Ht6HAkEAxGMQnXvD8b6gP7Ht7I6aeD36jhD8DZzDJ8yvg4zhsKFZ7fFedN0axCLI
|
||||
m+R4B7xo6rqi4uu2/T2T8b/OoLLbiwJAOzSYzPwzOxRZ1/RjUvIuN3mwAnQUkKOj
|
||||
fHU885hiwHH+JPk9gj2o8gAloyodFTqyvMr8++OGqoRPI4rUAZ5kFQJBANQCGq2g
|
||||
Qh2cFU6pmgoSDExnzOLWWeeCs1buw1XyVULHGv+n6zFowNmkmjJCTF1lvGehcnyW
|
||||
MNgnxt2QK7Q+RnI=
|
||||
-----END PRIVATE KEY-----
|
||||
@@ -0,0 +1 @@
|
||||
d99cb37ec1ea04790746a97b439fd3a3dbe5b0eb3de439cdfbf6e7e82ff871d278f11923049fd19e945d90135de112250103850305ed1eca0c82a51a6c5f1682 pm3_generic_private_key.pem
|
||||
+246
-149
File diff suppressed because it is too large
Load Diff
@@ -31,8 +31,14 @@ typedef enum {
|
||||
DICTIONARY_MIFARE_ULAES,
|
||||
} Dictionary_t;
|
||||
|
||||
typedef enum {
|
||||
SIGN_RDV4 = 0,
|
||||
SIGN_GENERIC,
|
||||
SIGN_UNK = 99
|
||||
} signature_e;
|
||||
|
||||
int CmdFlashMem(const char *Cmd);
|
||||
int rdv4_get_signature(rdv40_validation_t *out);
|
||||
int rdv4_validate(rdv40_validation_t *mem);
|
||||
int rdv4_get_flash_pages64k(uint8_t *pages64k);
|
||||
int pm3_get_signature(rdv40_validation_t *out);
|
||||
int pm3_validate(rdv40_validation_t *mem, signature_e *type);
|
||||
int pm3_get_flash_pages64k(uint8_t *pages64k);
|
||||
#endif
|
||||
|
||||
+29
-11
@@ -1575,16 +1575,25 @@ void pm3_version_short(void) {
|
||||
|
||||
if (IfPm3Rdv4Fw()) {
|
||||
|
||||
bool is_genuine_rdv4 = false;
|
||||
|
||||
// validate signature data
|
||||
rdv40_validation_t mem;
|
||||
if (rdv4_get_signature(&mem) == PM3_SUCCESS) {
|
||||
if (rdv4_validate(&mem) == PM3_SUCCESS) {
|
||||
is_genuine_rdv4 = true;
|
||||
signature_e type;
|
||||
|
||||
if (pm3_get_signature(&mem) == PM3_SUCCESS) {
|
||||
if (pm3_validate(&mem, &type) == PM3_SUCCESS) {
|
||||
|
||||
if (type == SIGN_RDV4) {
|
||||
PrintAndLogEx(NORMAL, " Target.... %s", _YELLOW_("RDV4"));
|
||||
} else if (type == SIGN_GENERIC) {
|
||||
PrintAndLogEx(NORMAL, " Target.... %s", _YELLOW_("GENERIC"));
|
||||
} else {
|
||||
PrintAndLogEx(NORMAL, " Target.... %s", _RED_("device / fw mismatch"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, " Target.... %s", (is_genuine_rdv4) ? _YELLOW_("RDV4") : _RED_("device / fw mismatch"));
|
||||
|
||||
} else {
|
||||
PrintAndLogEx(NORMAL, " Target.... %s", _YELLOW_("PM3 GENERIC"));
|
||||
}
|
||||
@@ -1702,17 +1711,26 @@ void pm3_version(bool verbose, bool oneliner) {
|
||||
if (WaitForResponseTimeout(CMD_VERSION, &resp, 1000)) {
|
||||
if (IfPm3Rdv4Fw()) {
|
||||
|
||||
bool is_genuine_rdv4 = false;
|
||||
// validate signature data
|
||||
rdv40_validation_t mem;
|
||||
if (rdv4_get_signature(&mem) == PM3_SUCCESS) {
|
||||
if (rdv4_validate(&mem) == PM3_SUCCESS) {
|
||||
is_genuine_rdv4 = true;
|
||||
signature_e type;
|
||||
|
||||
if (pm3_get_signature(&mem) == PM3_SUCCESS) {
|
||||
if (pm3_validate(&mem, &type) == PM3_SUCCESS) {
|
||||
|
||||
if (type == SIGN_RDV4) {
|
||||
PrintAndLogEx(NORMAL, " Device.................... " _GREEN_("RDV4"));
|
||||
PrintAndLogEx(NORMAL, " Firmware.................. " _GREEN_("RDV4"));
|
||||
} else if (type == SIGN_GENERIC) {
|
||||
PrintAndLogEx(NORMAL, " Device.................... ", _GREEN_("GENERIC"));
|
||||
PrintAndLogEx(NORMAL, " Firmware.................. ", _GREEN_("GENERIC"));
|
||||
} else {
|
||||
PrintAndLogEx(NORMAL, " Device.................... " _RED_("Bad signature detected!"));
|
||||
PrintAndLogEx(NORMAL, " Firmware.................. " _YELLOW_("N/A"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PrintAndLogEx(NORMAL, " Device.................... %s", (is_genuine_rdv4) ? _GREEN_("RDV4") : _RED_("device / fw mismatch"));
|
||||
PrintAndLogEx(NORMAL, " Firmware.................. %s", (is_genuine_rdv4) ? _GREEN_("RDV4") : _YELLOW_("RDV4"));
|
||||
PrintAndLogEx(NORMAL, " External flash............ %s", IfPm3Flash() ? _GREEN_("present") : _YELLOW_("absent"));
|
||||
PrintAndLogEx(NORMAL, " Smartcard reader.......... %s", IfPm3Smartcard() ? _GREEN_("present") : _YELLOW_("absent"));
|
||||
PrintAndLogEx(NORMAL, " FPC USART for BT add-on... %s", IfPm3FpcUsartHost() ? _GREEN_("present") : _YELLOW_("absent"));
|
||||
|
||||
@@ -43,9 +43,13 @@ static uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD;
|
||||
|
||||
#ifndef AS_BOOTROM
|
||||
|
||||
|
||||
spi_flash_t spi_flash_data = {0};
|
||||
uint8_t spi_flash_pages64k = 4;
|
||||
static spi_flash_t spi_flash_data = {0};
|
||||
|
||||
spi_flash_t *flash_get_info(void) {
|
||||
return &spi_flash_data;
|
||||
}
|
||||
|
||||
|
||||
void FlashmemSetSpiBaudrate(uint32_t baudrate) {
|
||||
FLASHMEM_SPIBAUDRATE = baudrate;
|
||||
@@ -387,7 +391,7 @@ void Flashmem_print_status(void) {
|
||||
);
|
||||
}
|
||||
|
||||
Dbprintf(" Memory size............. " _YELLOW_("%d kB (%d pages * 64k)"), spi_flash_pages64k * 64, spi_flash_pages64k);
|
||||
Dbprintf(" Memory size............. " _YELLOW_("%d Kb") " ( %d pages * 64k )", spi_flash_pages64k * 64, spi_flash_pages64k);
|
||||
|
||||
uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||
Flash_UniqueID(uid);
|
||||
@@ -439,6 +443,7 @@ bool FlashDetect(void) {
|
||||
}
|
||||
}
|
||||
|
||||
spi_flash_data.pages64k = spi_flash_pages64k;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#define __FLASHMEM_H
|
||||
|
||||
#include "common.h"
|
||||
#include "pmflash.h"
|
||||
|
||||
|
||||
// Used Command
|
||||
#define ID 0x90
|
||||
@@ -135,11 +137,7 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len);
|
||||
uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len);
|
||||
void Flashmem_print_status(void);
|
||||
|
||||
typedef struct {
|
||||
uint8_t manufacturer_id;
|
||||
uint8_t device_id;
|
||||
uint16_t jedec_id;
|
||||
} spi_flash_t;
|
||||
spi_flash_t *flash_get_info(void);
|
||||
|
||||
extern uint8_t spi_flash_pages64k;
|
||||
|
||||
|
||||
+7
-1
@@ -305,7 +305,7 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
// 64KB SRAM -> 524288 bits(max sample num) < 2^30
|
||||
uint32_t samples :
|
||||
uint32_t samples :
|
||||
LF_SAMPLES_BITS;
|
||||
bool realtime : 1;
|
||||
bool verbose : 1;
|
||||
@@ -473,6 +473,9 @@ typedef struct {
|
||||
#define CMD_SPIFFS_UNMOUNT 0x0131
|
||||
#define CMD_SPIFFS_WRITE 0x0132
|
||||
|
||||
#define CMD_FLASHMEM_GET_SIGNATURE 0x0147
|
||||
#define CMD_FLASHMEM_GET_INFO 0x0148
|
||||
|
||||
// We take +0x1000 when having a variant of similar function (todo : make it an argument!)
|
||||
#define CMD_SPIFFS_APPEND 0x1132
|
||||
|
||||
@@ -844,11 +847,13 @@ typedef struct {
|
||||
#define MIFARE_2K_MAX_BYTES 2048
|
||||
#define MIFARE_1K_MAX_BYTES 1024
|
||||
#define MIFARE_MINI_MAX_BYTES 320
|
||||
|
||||
#define FLAG_MASK_MF_SIZE 0x00C0
|
||||
#define FLAG_MF_MINI 0x0000
|
||||
#define FLAG_MF_1K 0x0040
|
||||
#define FLAG_MF_2K 0x0080
|
||||
#define FLAG_MF_4K 0x00C0
|
||||
|
||||
#define FLAG_SET_MF_SIZE(flags, size) {\
|
||||
flags = (flags & (~FLAG_MASK_MF_SIZE))|\
|
||||
(size == MIFARE_MINI_MAX_BYTES ? FLAG_MF_MINI : \
|
||||
@@ -857,6 +862,7 @@ typedef struct {
|
||||
(size == MIFARE_4K_MAX_BYTES ? FLAG_MF_4K : \
|
||||
0))));\
|
||||
}
|
||||
|
||||
// else we tell to take UID from block 0:
|
||||
#define IS_FLAG_MF_SIZE(flags, size) (\
|
||||
(flags & FLAG_MASK_MF_SIZE) == \
|
||||
|
||||
@@ -93,5 +93,11 @@ typedef struct {
|
||||
uint8_t signature[FLASH_MEM_SIGNATURE_LEN];
|
||||
} PACKED rdv40_validation_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t manufacturer_id;
|
||||
uint8_t device_id;
|
||||
uint16_t jedec_id;
|
||||
uint8_t pages64k;
|
||||
} PACKED spi_flash_t;
|
||||
|
||||
#endif // __PMFLASH_H
|
||||
|
||||
Reference in New Issue
Block a user