mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
Merge branch 'RfidResearchGroup:master' into master
This commit is contained in:
commit
7937f1ae8c
26 changed files with 1818 additions and 1491 deletions
|
@ -3,6 +3,8 @@ 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...
|
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]
|
## [unreleased][unreleased]
|
||||||
|
- Updated atrs list (@iceman1001)
|
||||||
|
- Added support for a new KDF (@iceman1001)
|
||||||
- Added Inner range aid and mad entries (@iceman1001)
|
- Added Inner range aid and mad entries (@iceman1001)
|
||||||
- Changed `mem spiffs` - Use all available space in SPI flash (@ANTodorov)
|
- Changed `mem spiffs` - Use all available space in SPI flash (@ANTodorov)
|
||||||
- Fixed wrong size check in MifareSim (@iceman1001)
|
- Fixed wrong size check in MifareSim (@iceman1001)
|
||||||
|
@ -70,6 +72,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
- Fixed arguments for `SimulateIso14443aTag` and `SimulateIso14443aInit` in `hf_young.c`, `hf_aveful.c`, `hf_msdsal.c`, `hf_cardhopper.c`, `hf_reblay.c`, `hf_tcprst.c` and `hf_craftbyte.c` (@archi)
|
- Fixed arguments for `SimulateIso14443aTag` and `SimulateIso14443aInit` in `hf_young.c`, `hf_aveful.c`, `hf_msdsal.c`, `hf_cardhopper.c`, `hf_reblay.c`, `hf_tcprst.c` and `hf_craftbyte.c` (@archi)
|
||||||
- Added `mf_backdoor_dump.py` script that dumps FM11RF08S and similar (Mifare Classic 1k) tag data that can be directly read by known backdoor keys. (@Aptimex)
|
- Added `mf_backdoor_dump.py` script that dumps FM11RF08S and similar (Mifare Classic 1k) tag data that can be directly read by known backdoor keys. (@Aptimex)
|
||||||
- Added keys for Metro Q transit cards in Huston, TX. (@Anarchothulhu)
|
- Added keys for Metro Q transit cards in Huston, TX. (@Anarchothulhu)
|
||||||
|
- Add new Mifare Classic keys from MifareClassicTool and Flipper projects. (@onovy)
|
||||||
|
|
||||||
## [Backdoor.4.18994][2024-09-10]
|
## [Backdoor.4.18994][2024-09-10]
|
||||||
- Changed flashing messages to be less scary (@iceman1001)
|
- Changed flashing messages to be less scary (@iceman1001)
|
||||||
|
|
|
@ -232,7 +232,7 @@ static void become_card(void) {
|
||||||
uint32_t counters[3] = { 0 };
|
uint32_t counters[3] = { 0 };
|
||||||
uint8_t tearings[3] = { 0xbd, 0xbd, 0xbd };
|
uint8_t tearings[3] = { 0xbd, 0xbd, 0xbd };
|
||||||
uint8_t pages;
|
uint8_t pages;
|
||||||
SimulateIso14443aInit(tagType, flags, data, NULL, &canned, &cuid, counters, tearings, &pages);
|
SimulateIso14443aInit(tagType, flags, data, NULL, 0, &canned, &cuid, counters, tearings, &pages);
|
||||||
|
|
||||||
DbpString(_CYAN_("[@]") " Setup done - entering emulation loop");
|
DbpString(_CYAN_("[@]") " Setup done - entering emulation loop");
|
||||||
int fromReaderLen;
|
int fromReaderLen;
|
||||||
|
|
|
@ -379,7 +379,7 @@ void RunMod(void) {
|
||||||
BigBuf_free_keep_EM();
|
BigBuf_free_keep_EM();
|
||||||
|
|
||||||
// tag type: 11 = ISO/IEC 14443-4 - javacard (JCOP)
|
// tag type: 11 = ISO/IEC 14443-4 - javacard (JCOP)
|
||||||
if (SimulateIso14443aInit(11, flags, data, NULL, &responses, &cuid, NULL, NULL, NULL) == false) {
|
if (SimulateIso14443aInit(11, flags, data, NULL, 0, &responses, &cuid, NULL, NULL, NULL) == false) {
|
||||||
BigBuf_free_keep_EM();
|
BigBuf_free_keep_EM();
|
||||||
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
||||||
DbpString(_RED_("Error initializing the emulation process!"));
|
DbpString(_RED_("Error initializing the emulation process!"));
|
||||||
|
|
|
@ -268,7 +268,7 @@ void RunMod() {
|
||||||
BigBuf_free_keep_EM();
|
BigBuf_free_keep_EM();
|
||||||
|
|
||||||
// 4 = ISO/IEC 14443-4 - javacard (JCOP)
|
// 4 = ISO/IEC 14443-4 - javacard (JCOP)
|
||||||
if (SimulateIso14443aInit(4, flags, data, NULL, &responses, &cuid, NULL, NULL, NULL) == false) {
|
if (SimulateIso14443aInit(4, flags, data, NULL, 0, &responses, &cuid, NULL, NULL, NULL) == false) {
|
||||||
BigBuf_free_keep_EM();
|
BigBuf_free_keep_EM();
|
||||||
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
||||||
DbpString(_RED_("Error initializing the emulation process!"));
|
DbpString(_RED_("Error initializing the emulation process!"));
|
||||||
|
|
|
@ -193,7 +193,7 @@ void RunMod(void) {
|
||||||
|
|
||||||
memcpy(data, stuid, sizeof(stuid));
|
memcpy(data, stuid, sizeof(stuid));
|
||||||
|
|
||||||
if (SimulateIso14443aInit(tagType, flags, data, NULL, &responses, &cuid, counters, tearings, &pages) == false) {
|
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &responses, &cuid, counters, tearings, &pages) == false) {
|
||||||
BigBuf_free_keep_EM();
|
BigBuf_free_keep_EM();
|
||||||
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
||||||
DbpString(_YELLOW_("!!") "Error initializing the simulation process!");
|
DbpString(_YELLOW_("!!") "Error initializing the simulation process!");
|
||||||
|
@ -371,7 +371,7 @@ void RunMod(void) {
|
||||||
|
|
||||||
memcpy(data, stuid, sizeof(stuid));
|
memcpy(data, stuid, sizeof(stuid));
|
||||||
|
|
||||||
if (SimulateIso14443aInit(tagType, flags, data, NULL, &responses, &cuid, counters, tearings, &pages) == false) {
|
if (SimulateIso14443aInit(tagType, flags, data, NULL, 0, &responses, &cuid, counters, tearings, &pages) == false) {
|
||||||
BigBuf_free_keep_EM();
|
BigBuf_free_keep_EM();
|
||||||
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
reply_ng(CMD_HF_MIFARE_SIMULATE, PM3_EINIT, NULL, 0);
|
||||||
DbpString(_YELLOW_("!!") "Error initializing the simulation process!");
|
DbpString(_YELLOW_("!!") "Error initializing the simulation process!");
|
||||||
|
|
|
@ -2748,11 +2748,11 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (payload->startidx == DEFAULT_T55XX_KEYS_OFFSET_P(spi_flash_p64k)) {
|
if (payload->startidx == DEFAULT_T55XX_KEYS_OFFSET_P(spi_flash_pages64k)) {
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
Flash_WriteEnable();
|
Flash_WriteEnable();
|
||||||
Flash_Erase4k(3, 0xC);
|
Flash_Erase4k(3, 0xC);
|
||||||
} else if (payload->startidx == DEFAULT_MF_KEYS_OFFSET_P(spi_flash_p64k)) {
|
} else if (payload->startidx == DEFAULT_MF_KEYS_OFFSET_P(spi_flash_pages64k)) {
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
Flash_WriteEnable();
|
Flash_WriteEnable();
|
||||||
Flash_Erase4k(3, 0x8);
|
Flash_Erase4k(3, 0x8);
|
||||||
|
@ -2762,11 +2762,11 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
Flash_WriteEnable();
|
Flash_WriteEnable();
|
||||||
Flash_Erase4k(3, 0xA);
|
Flash_Erase4k(3, 0xA);
|
||||||
} else if (payload->startidx == DEFAULT_ICLASS_KEYS_OFFSET_P(spi_flash_p64k)) {
|
} else if (payload->startidx == DEFAULT_ICLASS_KEYS_OFFSET_P(spi_flash_pages64k)) {
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
Flash_WriteEnable();
|
Flash_WriteEnable();
|
||||||
Flash_Erase4k(3, 0xB);
|
Flash_Erase4k(3, 0xB);
|
||||||
} else if (payload->startidx == FLASH_MEM_SIGNATURE_OFFSET_P(spi_flash_p64k)) {
|
} else if (payload->startidx == FLASH_MEM_SIGNATURE_OFFSET_P(spi_flash_pages64k)) {
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
Flash_WriteEnable();
|
Flash_WriteEnable();
|
||||||
Flash_Erase4k(3, 0xF);
|
Flash_Erase4k(3, 0xF);
|
||||||
|
@ -2789,7 +2789,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (page < spi_flash_p64k-1) {
|
if (page < spi_flash_pages64k - 1) {
|
||||||
isok = Flash_WipeMemoryPage(page);
|
isok = Flash_WipeMemoryPage(page);
|
||||||
// let spiffs check and update its info post flash erase
|
// let spiffs check and update its info post flash erase
|
||||||
rdv40_spiffs_check();
|
rdv40_spiffs_check();
|
||||||
|
@ -2836,7 +2836,7 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
rdv40_validation_t *info = (rdv40_validation_t *)BigBuf_malloc(sizeof(rdv40_validation_t));
|
rdv40_validation_t *info = (rdv40_validation_t *)BigBuf_malloc(sizeof(rdv40_validation_t));
|
||||||
|
|
||||||
bool isok = Flash_ReadData(FLASH_MEM_SIGNATURE_OFFSET_P(spi_flash_p64k), info->signature, FLASH_MEM_SIGNATURE_LEN);
|
bool isok = Flash_ReadData(FLASH_MEM_SIGNATURE_OFFSET_P(spi_flash_pages64k), info->signature, FLASH_MEM_SIGNATURE_LEN);
|
||||||
|
|
||||||
if (FlashInit()) {
|
if (FlashInit()) {
|
||||||
Flash_UniqueID(info->flashid);
|
Flash_UniqueID(info->flashid);
|
||||||
|
@ -2856,11 +2856,11 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
if (FlashInit()) {
|
if (FlashInit()) {
|
||||||
isok = true;
|
isok = true;
|
||||||
if (g_dbglevel >= DBG_DEBUG) {
|
if (g_dbglevel >= DBG_DEBUG) {
|
||||||
Dbprintf(" CMD_FLASHMEM_PAGE64K 0x%02x (%d 64k pages)", spi_flash_p64k, spi_flash_p64k);
|
Dbprintf(" CMD_FLASHMEM_PAGE64K 0x%02x (%d 64k pages)", spi_flash_pages64k, spi_flash_pages64k);
|
||||||
}
|
}
|
||||||
FlashStop();
|
FlashStop();
|
||||||
}
|
}
|
||||||
reply_mix(CMD_ACK, isok, 0, 0, &spi_flash_p64k, sizeof(uint8_t));
|
reply_mix(CMD_ACK, isok, 0, 0, &spi_flash_pages64k, sizeof(uint8_t));
|
||||||
|
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -2148,7 +2148,7 @@ void T55xx_ChkPwds(uint8_t flags, bool ledcontrol) {
|
||||||
BigBuf_Clear_EM();
|
BigBuf_Clear_EM();
|
||||||
uint16_t isok = 0;
|
uint16_t isok = 0;
|
||||||
uint8_t counter[2] = {0x00, 0x00};
|
uint8_t counter[2] = {0x00, 0x00};
|
||||||
isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET_P(spi_flash_p64k), counter, sizeof(counter));
|
isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET_P(spi_flash_pages64k), counter, sizeof(counter));
|
||||||
if (isok != sizeof(counter))
|
if (isok != sizeof(counter))
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
|
||||||
|
@ -2164,7 +2164,7 @@ void T55xx_ChkPwds(uint8_t flags, bool ledcontrol) {
|
||||||
// adjust available pwd_count
|
// adjust available pwd_count
|
||||||
pwd_count = pwd_size_available / 4;
|
pwd_count = pwd_size_available / 4;
|
||||||
|
|
||||||
isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET_P(spi_flash_p64k) + 2, pwds, pwd_size_available);
|
isok = Flash_ReadData(DEFAULT_T55XX_KEYS_OFFSET_P(spi_flash_pages64k) + 2, pwds, pwd_size_available);
|
||||||
if (isok != pwd_size_available)
|
if (isok != pwd_size_available)
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
|
||||||
|
|
|
@ -1789,7 +1789,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
uint16_t isok = 0;
|
uint16_t isok = 0;
|
||||||
uint8_t size[2] = {0x00, 0x00};
|
uint8_t size[2] = {0x00, 0x00};
|
||||||
isok = Flash_ReadData(DEFAULT_MF_KEYS_OFFSET_P(spi_flash_p64k), size, 2);
|
isok = Flash_ReadData(DEFAULT_MF_KEYS_OFFSET_P(spi_flash_pages64k), size, 2);
|
||||||
if (isok != 2)
|
if (isok != 2)
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
|
||||||
|
@ -1808,7 +1808,7 @@ void MifareChkKeys_fast(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *da
|
||||||
if (datain == NULL)
|
if (datain == NULL)
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
|
||||||
isok = Flash_ReadData(DEFAULT_MF_KEYS_OFFSET_P(spi_flash_p64k) + 2, datain, key_mem_available);
|
isok = Flash_ReadData(DEFAULT_MF_KEYS_OFFSET_P(spi_flash_pages64k) + 2, datain, key_mem_available);
|
||||||
if (isok != key_mem_available)
|
if (isok != key_mem_available)
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
|
||||||
|
|
|
@ -236,7 +236,7 @@ typedef uint8_t u8_t;
|
||||||
// Instead of giving parameters in config struct, singleton build must
|
// Instead of giving parameters in config struct, singleton build must
|
||||||
// give parameters in defines below.
|
// give parameters in defines below.
|
||||||
#ifndef SPIFFS_CFG_PHYS_SZ
|
#ifndef SPIFFS_CFG_PHYS_SZ
|
||||||
#define SPIFFS_CFG_PHYS_SZ(ignore) (1024 * 64 * (spi_flash_p64k - 1))
|
#define SPIFFS_CFG_PHYS_SZ(ignore) (1024 * 64 * (spi_flash_pages64k - 1))
|
||||||
#endif
|
#endif
|
||||||
#ifndef SPIFFS_CFG_PHYS_ERASE_SZ
|
#ifndef SPIFFS_CFG_PHYS_ERASE_SZ
|
||||||
#define SPIFFS_CFG_PHYS_ERASE_SZ(ignore) (4*1024)
|
#define SPIFFS_CFG_PHYS_ERASE_SZ(ignore) (4*1024)
|
||||||
|
|
|
@ -22,6 +22,7 @@ add_library(pm3rrg_rdv4_mbedtls STATIC
|
||||||
../../common/mbedtls/des.c
|
../../common/mbedtls/des.c
|
||||||
../../common/mbedtls/ecdsa.c
|
../../common/mbedtls/ecdsa.c
|
||||||
../../common/mbedtls/md.c
|
../../common/mbedtls/md.c
|
||||||
|
../../common/mbedtls/hkdf.c
|
||||||
../../common/mbedtls/md5.c
|
../../common/mbedtls/md5.c
|
||||||
../../common/mbedtls/oid.c
|
../../common/mbedtls/oid.c
|
||||||
../../common/mbedtls/pem.c
|
../../common/mbedtls/pem.c
|
||||||
|
|
|
@ -2727,3 +2727,31 @@ D9D1C447E427
|
||||||
525A869053F1
|
525A869053F1
|
||||||
69B25667E0B4
|
69B25667E0B4
|
||||||
6AACA2D97645
|
6AACA2D97645
|
||||||
|
# UK London Office
|
||||||
|
435DF6296EC4
|
||||||
|
2338B4913222
|
||||||
|
# Acces card of students, and more in Occitanie, France
|
||||||
|
E9A553102EA5
|
||||||
|
F982E971CFED
|
||||||
|
1F42AB9159EE
|
||||||
|
BBFB836A48B8
|
||||||
|
B5D170B2E8F5
|
||||||
|
E76978A05F10
|
||||||
|
0B1A995DD007
|
||||||
|
650DB9CEDB6B
|
||||||
|
13E54B4448B7
|
||||||
|
3E3540C2C273
|
||||||
|
A76152840117
|
||||||
|
066CCC7666BC
|
||||||
|
3C0B3AC3AFA3
|
||||||
|
CCB541598D72
|
||||||
|
1988B5D48EC3
|
||||||
|
892EEF0D30FB
|
||||||
|
0FE5CE5CC640
|
||||||
|
# Volgograd (Russia) Volna transport cards keys
|
||||||
|
2B787A063D5D
|
||||||
|
D37C8F1793F7
|
||||||
|
# H World Hotel Chain Room Keys
|
||||||
|
543071543071
|
||||||
|
5F01015F0101
|
||||||
|
200510241234
|
||||||
|
|
|
@ -415,6 +415,14 @@
|
||||||
"Description": "Digital Keys Sent To The dormakaba mobile access App",
|
"Description": "Digital Keys Sent To The dormakaba mobile access App",
|
||||||
"Type": "pacs"
|
"Type": "pacs"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"AID": "F534F1",
|
||||||
|
"Vendor": "MOBOTIX AG",
|
||||||
|
"Country": "DE",
|
||||||
|
"Name": "MOBOTIX AG Access Credential",
|
||||||
|
"Description": "T26 Outdoor Station and Access Module Credential",
|
||||||
|
"Type": "pacs"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"AID": "F518F0",
|
"AID": "F518F0",
|
||||||
"Vendor": "Telenot Electronic GmbH",
|
"Vendor": "Telenot Electronic GmbH",
|
||||||
|
@ -817,10 +825,10 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"AID": "0000F0",
|
"AID": "0000F0",
|
||||||
"Vendor": "Metropolitan Transportation Authority (MTA)",
|
"Vendor": "Metropolitan Transportation Authority (MTA) / Bayerische Motoren Werke (BMW) AG",
|
||||||
"Country": "US",
|
"Country": "US / DE",
|
||||||
"Name": "OMNY (One Metro New York) (JFK)",
|
"Name": "OMNY (One Metro New York) (JFK) / BMW Digital Key",
|
||||||
"Description": "JFK OMNY (One Metro New York) Card",
|
"Description": "JFK OMNY (One Metro New York) Card / BMW Digital Key 5B3611-01",
|
||||||
"Type": "transport"
|
"Type": "transport"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -797,7 +797,7 @@ static int mf_load_keys(uint8_t **pkeyBlock, uint32_t *pkeycnt, uint8_t *userkey
|
||||||
PrintAndLogEx(DEBUG, _YELLOW_("%2d") " - %s", *pkeycnt + i, sprint_hex(*pkeyBlock + (*pkeycnt + i) * MIFARE_KEY_SIZE, MIFARE_KEY_SIZE));
|
PrintAndLogEx(DEBUG, _YELLOW_("%2d") " - %s", *pkeycnt + i, sprint_hex(*pkeyBlock + (*pkeycnt + i) * MIFARE_KEY_SIZE, MIFARE_KEY_SIZE));
|
||||||
}
|
}
|
||||||
*pkeycnt += ARRAYLEN(g_mifare_default_keys);
|
*pkeycnt += ARRAYLEN(g_mifare_default_keys);
|
||||||
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%zu") " keys from hardcoded default array", ARRAYLEN(g_mifare_default_keys));
|
PrintAndLogEx(SUCCESS, "loaded " _GREEN_("%zu") " hardcoded keys", ARRAYLEN(g_mifare_default_keys));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle user supplied dictionary file
|
// Handle user supplied dictionary file
|
||||||
|
@ -9697,7 +9697,8 @@ static int CmdHF14AMfInfo(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fKeyType != 0xFF) {
|
if (fKeyType != 0xFF) {
|
||||||
PrintAndLogEx(SUCCESS, "Block 0.......... %s", sprint_hex_ascii(blockdata, MFBLOCK_SIZE));
|
PrintAndLogEx(SUCCESS, "Block 0.... %s | " NOLF, sprint_hex_inrow(blockdata, MFBLOCK_SIZE));
|
||||||
|
PrintAndLogEx(NORMAL, "%s", sprint_ascii(blockdata + 8, 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
|
|
@ -4126,7 +4126,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
|
||||||
|
|
||||||
// save old block2.
|
// save old block2.
|
||||||
uint8_t oldblock2[4] = {0x00};
|
uint8_t oldblock2[4] = {0x00};
|
||||||
memcpy(resp.data.asBytes, oldblock2, 4);
|
memcpy(oldblock2, resp.data.asBytes, 4);
|
||||||
|
|
||||||
// Enforce bad BCC handling temporarily as BCC will be wrong between
|
// Enforce bad BCC handling temporarily as BCC will be wrong between
|
||||||
// block 1 write and block2 write
|
// block 1 write and block2 write
|
||||||
|
@ -4431,6 +4431,9 @@ static int CmdHF14AMfUPwdGen(const char *Cmd) {
|
||||||
PrintAndLogEx(INFO, " Dorma Kaba algo");
|
PrintAndLogEx(INFO, " Dorma Kaba algo");
|
||||||
PrintAndLogEx(INFO, " STiD algo");
|
PrintAndLogEx(INFO, " STiD algo");
|
||||||
PrintAndLogEx(INFO, "-------------------------------------");
|
PrintAndLogEx(INFO, "-------------------------------------");
|
||||||
|
key = 0;
|
||||||
|
mfc_algo_bambu_one(uid, 0, MF_KEY_A, &key);
|
||||||
|
PrintAndLogEx(INFO, " Bambu........ %012" PRIX64, key);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -226,7 +226,6 @@ static void showBanner(void) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(NORMAL, " [ " _YELLOW_("%s!")" ]", get_quote());
|
PrintAndLogEx(NORMAL, " [ " _YELLOW_("%s!")" ]", get_quote());
|
||||||
PrintAndLogEx(NORMAL, " Patreon - https://www.patreon.com/iceman1001/");
|
PrintAndLogEx(NORMAL, " Patreon - https://www.patreon.com/iceman1001/");
|
||||||
PrintAndLogEx(NORMAL, " Paypal - https://www.paypal.me/iceman1001/");
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
// PrintAndLogEx(NORMAL, " Monero");
|
// PrintAndLogEx(NORMAL, " Monero");
|
||||||
// PrintAndLogEx(NORMAL, " 43mNJLpgBVaTvyZmX9ajcohpvVkaRy1kbZPm8tqAb7itZgfuYecgkRF36rXrKFUkwEGeZedPsASRxgv4HPBHvJwyJdyvQuP");
|
// PrintAndLogEx(NORMAL, " 43mNJLpgBVaTvyZmX9ajcohpvVkaRy1kbZPm8tqAb7itZgfuYecgkRF36rXrKFUkwEGeZedPsASRxgv4HPBHvJwyJdyvQuP");
|
||||||
|
|
|
@ -567,3 +567,35 @@ size_t concatbits(uint8_t *dest, int dest_offset, const uint8_t *src, int src_of
|
||||||
|
|
||||||
return dest_offset + nbits;
|
return dest_offset + nbits;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int char2int(char c) {
|
||||||
|
if (c >= '0' && c <= '9') return c - '0';
|
||||||
|
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
|
||||||
|
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
|
||||||
|
return -1; // Invalid character for hex
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns the number of bytes written
|
||||||
|
int hexstr2ByteArr(const char *hexstr, unsigned char *array, size_t asize) {
|
||||||
|
size_t n = 0;
|
||||||
|
while (hexstr[n] != '\0') {
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the input is valid and fits in the output array
|
||||||
|
if (n % 2 != 0 || asize < n >> 1) {
|
||||||
|
return -1; // Error: invalid length or insufficient byte array size
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < n; i += 2) {
|
||||||
|
int high = char2int(hexstr[i]);
|
||||||
|
int low = char2int(hexstr[i + 1]);
|
||||||
|
|
||||||
|
if (high == -1 || low == -1) {
|
||||||
|
return -1; // Error: invalid hex character
|
||||||
|
}
|
||||||
|
|
||||||
|
array[i >> 1] = (high << 4) | low;
|
||||||
|
}
|
||||||
|
return n >> 1;
|
||||||
|
}
|
||||||
|
|
|
@ -65,6 +65,20 @@
|
||||||
#define REV64(x) (REV32(x) + ((uint64_t)(REV32((x) >> 32) << 32)))
|
#define REV64(x) (REV32(x) + ((uint64_t)(REV32((x) >> 32) << 32)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int Year;
|
||||||
|
int Month;
|
||||||
|
int Day;
|
||||||
|
int Hour;
|
||||||
|
int Minute;
|
||||||
|
} Date_t;
|
||||||
|
|
||||||
|
|
||||||
|
int calculate_hours_between_dates(const Date_t s, Date_t *e);
|
||||||
|
void add_hours(Date_t *d, int hours_to_add);
|
||||||
|
void add_days(Date_t *d, int days_to_add);
|
||||||
|
uint8_t days_in_month(int year, int month);
|
||||||
|
|
||||||
|
|
||||||
extern struct version_information_t g_version_information;
|
extern struct version_information_t g_version_information;
|
||||||
void FormatVersionInformation(char *dst, int len, const char *prefix, const void *version_info);
|
void FormatVersionInformation(char *dst, int len, const char *prefix, const void *version_info);
|
||||||
|
@ -136,4 +150,6 @@ void reverse_arraybytes(uint8_t *arr, size_t len);
|
||||||
void reverse_arraybytes_copy(uint8_t *arr, uint8_t *dest, size_t len);
|
void reverse_arraybytes_copy(uint8_t *arr, uint8_t *dest, size_t len);
|
||||||
|
|
||||||
size_t concatbits(uint8_t *dest, int dest_offset, const uint8_t *src, int src_offset, size_t nbits);
|
size_t concatbits(uint8_t *dest, int dest_offset, const uint8_t *src, int src_offset, size_t nbits);
|
||||||
|
int char2int(char c);
|
||||||
|
int hexstr2ByteArr(const char *hexstr, unsigned char *array, size_t asize);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "commonutil.h" //BSWAP_16
|
#include "commonutil.h" //BSWAP_16
|
||||||
#include "common.h" //BSWAP_32/64
|
#include "common.h" //BSWAP_32/64
|
||||||
#include "util.h"
|
|
||||||
#include "pm3_cmd.h"
|
#include "pm3_cmd.h"
|
||||||
#include "crc16.h" // crc16 ccitt
|
#include "crc16.h" // crc16 ccitt
|
||||||
#include "mbedtls/sha1.h"
|
#include "mbedtls/sha1.h"
|
||||||
|
@ -33,9 +33,11 @@
|
||||||
#include "mbedtls/cmac.h"
|
#include "mbedtls/cmac.h"
|
||||||
#include "mbedtls/cipher.h"
|
#include "mbedtls/cipher.h"
|
||||||
#include "mbedtls/md.h"
|
#include "mbedtls/md.h"
|
||||||
|
#include "mbedtls/hkdf.h"
|
||||||
|
|
||||||
#ifndef ON_DEVICE
|
#ifndef ON_DEVICE
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
|
#include "util.h"
|
||||||
# define prnt(args...) PrintAndLogEx(DEBUG, ## args );
|
# define prnt(args...) PrintAndLogEx(DEBUG, ## args );
|
||||||
#else
|
#else
|
||||||
# include "dbprint.h"
|
# include "dbprint.h"
|
||||||
|
@ -351,12 +353,11 @@ int mfc_algo_saflok_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t
|
||||||
0xda3e3fd649ddULL, 0x58dded078e3eULL, 0x5cd005cfd907ULL, 0x118dd00187d0ULL
|
0xda3e3fd649ddULL, 0x58dded078e3eULL, 0x5cd005cfd907ULL, 0x118dd00187d0ULL
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t h = ((uid[3] >> 4) & 0xF);
|
uint8_t h = (NIBBLE_HIGH(uid[3]) & 0xF);
|
||||||
h += ((uid[2] >> 4) & 0xF);
|
h += (NIBBLE_HIGH(uid[2]) & 0xF);
|
||||||
h += uid[0] & 0xF;
|
h += uid[0] & 0xF;
|
||||||
|
|
||||||
uint64_t m = lut[h & 0xF];
|
uint64_t m = lut[h & 0xF];
|
||||||
|
|
||||||
uint64_t id = (bytes_to_num(uid, 4) << 8);
|
uint64_t id = (bytes_to_num(uid, 4) << 8);
|
||||||
|
|
||||||
*key = (h + (id + m + ((uint64_t)h << 40ULL))) & 0xFFFFFFFFFFFFULL;
|
*key = (h + (id + m + ((uint64_t)h << 40ULL))) & 0xFFFFFFFFFFFFULL;
|
||||||
|
@ -540,6 +541,41 @@ int mfc_algo_sky_all(uint8_t *uid, uint8_t *keys) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const uint8_t bambu_salt[] = { 0x9a, 0x75, 0x9c, 0xf2, 0xc4, 0xf7, 0xca, 0xff, 0x22, 0x2c, 0xb9, 0x76, 0x9b, 0x41, 0xbc, 0x96 };
|
||||||
|
static const uint8_t bambu_context_a[] = "RFID-A";
|
||||||
|
static const uint8_t bambu_context_b[] = "RFID-B";
|
||||||
|
|
||||||
|
int mfc_algo_bambu_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key) {
|
||||||
|
if (uid == NULL) return PM3_EINVARG;
|
||||||
|
if (key == NULL) return PM3_EINVARG;
|
||||||
|
|
||||||
|
uint8_t keys[16 * 6] = {0};
|
||||||
|
|
||||||
|
// prepare hmac context
|
||||||
|
const mbedtls_md_info_t *info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
|
||||||
|
|
||||||
|
if (keytype == 0) {
|
||||||
|
mbedtls_hkdf(info, bambu_salt, sizeof(bambu_salt), uid, 4, bambu_context_a, sizeof(bambu_context_a), keys, sizeof(keys));
|
||||||
|
} else {
|
||||||
|
mbedtls_hkdf(info, bambu_salt, sizeof(bambu_salt), uid, 4, bambu_context_b, sizeof(bambu_context_b), keys, sizeof(keys));
|
||||||
|
}
|
||||||
|
|
||||||
|
*key = bytes_to_num(keys + (sector * 6), 6);
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mfc_algo_bambu_all(uint8_t *uid, uint8_t *keys) {
|
||||||
|
if (uid == NULL) return PM3_EINVARG;
|
||||||
|
if (keys == NULL) return PM3_EINVARG;
|
||||||
|
|
||||||
|
// prepare hmac context
|
||||||
|
const mbedtls_md_info_t *info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
|
||||||
|
mbedtls_hkdf(info, bambu_salt, sizeof(bambu_salt), uid, 4, bambu_context_a, sizeof(bambu_context_a), keys, (16 * 6));
|
||||||
|
mbedtls_hkdf(info, bambu_salt, sizeof(bambu_salt), uid, 4, bambu_context_b, sizeof(bambu_context_b), keys + (16 * 6), (16 * 6));
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
// LF T55x7 White gun cloner algo
|
// LF T55x7 White gun cloner algo
|
||||||
uint32_t lf_t55xx_white_pwdgen(uint32_t id) {
|
uint32_t lf_t55xx_white_pwdgen(uint32_t id) {
|
||||||
uint32_t r1 = rotl(id & 0x000000ec, 8);
|
uint32_t r1 = rotl(id & 0x000000ec, 8);
|
||||||
|
@ -617,10 +653,9 @@ int mfc_algo_touch_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *
|
||||||
|
|
||||||
int generator_selftest(void) {
|
int generator_selftest(void) {
|
||||||
#ifndef ON_DEVICE
|
#ifndef ON_DEVICE
|
||||||
#define NUM_OF_TEST 10
|
#define NUM_OF_TEST 11
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "PWD / KEY generator selftest");
|
PrintAndLogEx(INFO, "------- " _CYAN_("PWD / KEY generator self tests") " --------");
|
||||||
PrintAndLogEx(INFO, "----------------------------");
|
|
||||||
|
|
||||||
uint8_t testresult = 0;
|
uint8_t testresult = 0;
|
||||||
|
|
||||||
|
@ -629,7 +664,6 @@ int generator_selftest(void) {
|
||||||
bool success = (pwd1 == 0x8432EB17);
|
bool success = (pwd1 == 0x8432EB17);
|
||||||
if (success)
|
if (success)
|
||||||
testresult++;
|
testresult++;
|
||||||
|
|
||||||
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X - %s", sprint_hex(uid1, 7), pwd1, success ? _GREEN_("ok") : "->8432EB17<-");
|
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %08X - %s", sprint_hex(uid1, 7), pwd1, success ? _GREEN_("ok") : "->8432EB17<-");
|
||||||
|
|
||||||
uint8_t uid2[] = {0x04, 0x1f, 0x98, 0xea, 0x1e, 0x3e, 0x81};
|
uint8_t uid2[] = {0x04, 0x1f, 0x98, 0xea, 0x1e, 0x3e, 0x81};
|
||||||
|
@ -687,7 +721,7 @@ int generator_selftest(void) {
|
||||||
success = (key8 == 0x82c7e64bc565);
|
success = (key8 == 0x82c7e64bc565);
|
||||||
if (success)
|
if (success)
|
||||||
testresult++;
|
testresult++;
|
||||||
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %"PRIx64" - %s", sprint_hex(uid8, 4), key8, success ? _GREEN_("ok") : "->82C7E64BC565<--");
|
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %012"PRIx64" - %s", sprint_hex(uid8, 4), key8, success ? _GREEN_("ok") : "->82C7E64BC565<--");
|
||||||
|
|
||||||
// MFC SAFLOK
|
// MFC SAFLOK
|
||||||
uint8_t uid9[] = {0x11, 0x22, 0x33, 0x44};
|
uint8_t uid9[] = {0x11, 0x22, 0x33, 0x44};
|
||||||
|
@ -696,13 +730,22 @@ int generator_selftest(void) {
|
||||||
success = (key9 == 0xD1E2AA68E39A);
|
success = (key9 == 0xD1E2AA68E39A);
|
||||||
if (success)
|
if (success)
|
||||||
testresult++;
|
testresult++;
|
||||||
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %"PRIX64" - %s", sprint_hex(uid9, 4), key9, success ? _GREEN_("ok") : _RED_(">> D1E2AA68E39A <<"));
|
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %012"PRIX64" - %s", sprint_hex(uid9, 4), key9, success ? _GREEN_("ok") : _RED_(">> D1E2AA68E39A <<"));
|
||||||
|
|
||||||
uint32_t lf_id = lf_t55xx_white_pwdgen(0x00000080);
|
uint32_t lf_id = lf_t55xx_white_pwdgen(0x00000080);
|
||||||
success = (lf_id == 0x00018383);
|
success = (lf_id == 0x00018383);
|
||||||
if (success)
|
if (success)
|
||||||
testresult++;
|
testresult++;
|
||||||
PrintAndLogEx(success ? SUCCESS : WARNING, "ID | 0x00000080 | %08"PRIx32 " - %s", lf_id, success ? _GREEN_("ok") : "->00018383<--");
|
PrintAndLogEx(success ? SUCCESS : WARNING, "ID | 0x00000080 | %08"PRIx32 " - %s", lf_id, success ? _GREEN_("ok") : ">> 00018383 <<");
|
||||||
|
|
||||||
|
// MFC Bambu
|
||||||
|
uint64_t key13 = 0;
|
||||||
|
mfc_algo_bambu_one(uid9, 0, 0, &key13);
|
||||||
|
success = (key13 == 0x0729F3B2D37A);
|
||||||
|
if (success)
|
||||||
|
testresult++;
|
||||||
|
PrintAndLogEx(success ? SUCCESS : WARNING, "UID | %s | %012"PRIX64" - %s", sprint_hex(uid9, 4), key13, success ? _GREEN_("ok") : _RED_(">> 0729F3B2D37A <<"));
|
||||||
|
|
||||||
|
|
||||||
PrintAndLogEx(SUCCESS, "------------------- Selftest %s", (testresult == NUM_OF_TEST) ? _GREEN_("ok") : _RED_("fail"));
|
PrintAndLogEx(SUCCESS, "------------------- Selftest %s", (testresult == NUM_OF_TEST) ? _GREEN_("ok") : _RED_("fail"));
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,8 @@ int mfc_generate4b_nuid(uint8_t *uid, uint8_t *nuid);
|
||||||
|
|
||||||
int mfc_algo_touch_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key);
|
int mfc_algo_touch_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key);
|
||||||
|
|
||||||
|
int mfc_algo_bambu_one(uint8_t *uid, uint8_t sector, uint8_t keytype, uint64_t *key);
|
||||||
|
int mfc_algo_bambu_all(uint8_t *uid, uint8_t *keys);
|
||||||
uint32_t lf_t55xx_white_pwdgen(uint32_t id);
|
uint32_t lf_t55xx_white_pwdgen(uint32_t id);
|
||||||
|
|
||||||
int mfdes_kdf_input_gallagher(uint8_t *uid, uint8_t uidLen, uint8_t keyNo, uint32_t aid, uint8_t *kdfInputOut, uint8_t *kdfInputLen);
|
int mfdes_kdf_input_gallagher(uint8_t *uid, uint8_t uidLen, uint8_t keyNo, uint32_t aid, uint8_t *kdfInputOut, uint8_t *kdfInputLen);
|
||||||
|
|
|
@ -25,6 +25,7 @@ MYSRCS = \
|
||||||
ecdh.c \
|
ecdh.c \
|
||||||
ecdsa.c \
|
ecdsa.c \
|
||||||
gcm.c \
|
gcm.c \
|
||||||
|
hkdf.c \
|
||||||
md.c \
|
md.c \
|
||||||
md5.c \
|
md5.c \
|
||||||
oid.c \
|
oid.c \
|
||||||
|
|
|
@ -2849,7 +2849,7 @@
|
||||||
* This module adds support for the Hashed Message Authentication Code
|
* This module adds support for the Hashed Message Authentication Code
|
||||||
* (HMAC)-based key derivation function (HKDF).
|
* (HMAC)-based key derivation function (HKDF).
|
||||||
*/
|
*/
|
||||||
//#define MBEDTLS_HKDF_C
|
#define MBEDTLS_HKDF_C
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \def MBEDTLS_HMAC_DRBG_C
|
* \def MBEDTLS_HMAC_DRBG_C
|
||||||
|
|
|
@ -43,7 +43,9 @@ static uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD;
|
||||||
|
|
||||||
#ifndef AS_BOOTROM
|
#ifndef AS_BOOTROM
|
||||||
|
|
||||||
uint8_t spi_flash_p64k = 0;
|
|
||||||
|
spi_flash_t spi_flash_data = {0};
|
||||||
|
uint8_t spi_flash_pages64k = 4;
|
||||||
|
|
||||||
void FlashmemSetSpiBaudrate(uint32_t baudrate) {
|
void FlashmemSetSpiBaudrate(uint32_t baudrate) {
|
||||||
FLASHMEM_SPIBAUDRATE = baudrate;
|
FLASHMEM_SPIBAUDRATE = baudrate;
|
||||||
|
@ -152,8 +154,8 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// out-of-range
|
// out-of-range
|
||||||
if (((address >> 16) & 0xFF) > spi_flash_p64k) {
|
if (((address >> 16) & 0xFF) > spi_flash_pages64k) {
|
||||||
Dbprintf("Flash_WriteData, block out-of-range %02x > %02x", (address >> 16) & 0xFF, spi_flash_p64k);
|
Dbprintf("Flash_WriteData, block out-of-range %02x > %02x", (address >> 16) & 0xFF, spi_flash_pages64k);
|
||||||
FlashStop();
|
FlashStop();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -190,8 +192,8 @@ uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((address >> 16) & 0xFF) > spi_flash_p64k) {
|
if (((address >> 16) & 0xFF) > spi_flash_pages64k) {
|
||||||
Dbprintf("Flash_WriteDataCont, block out-of-range %02x > %02x", (address >> 16) & 0xFF, spi_flash_p64k);
|
Dbprintf("Flash_WriteDataCont, block out-of-range %02x > %02x", (address >> 16) & 0xFF, spi_flash_pages64k);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,7 +271,7 @@ bool Flash_WipeMemory(void) {
|
||||||
|
|
||||||
// Each block is 64Kb. Four blocks
|
// Each block is 64Kb. Four blocks
|
||||||
// one block erase takes 1s ( 1000ms )
|
// one block erase takes 1s ( 1000ms )
|
||||||
for (uint8_t i=0; i < spi_flash_p64k; i++) {
|
for (uint8_t i = 0; i < spi_flash_pages64k; i++) {
|
||||||
Flash_WriteEnable();
|
Flash_WriteEnable();
|
||||||
Flash_Erase64k(i);
|
Flash_Erase64k(i);
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
@ -289,7 +291,7 @@ void Flash_WriteEnable(void) {
|
||||||
// execution time: 0.8ms / 800us
|
// execution time: 0.8ms / 800us
|
||||||
bool Flash_Erase4k(uint8_t block, uint8_t sector) {
|
bool Flash_Erase4k(uint8_t block, uint8_t sector) {
|
||||||
|
|
||||||
if (block > spi_flash_p64k || sector > MAX_SECTORS) return false;
|
if (block > spi_flash_pages64k || sector > MAX_SECTORS) return false;
|
||||||
|
|
||||||
FlashSendByte(SECTORERASE);
|
FlashSendByte(SECTORERASE);
|
||||||
FlashSendByte(block);
|
FlashSendByte(block);
|
||||||
|
@ -324,7 +326,7 @@ bool Flash_Erase32k(uint32_t address) {
|
||||||
// 0x03 00 00 -- 0x 03 FF FF == block 3
|
// 0x03 00 00 -- 0x 03 FF FF == block 3
|
||||||
bool Flash_Erase64k(uint8_t block) {
|
bool Flash_Erase64k(uint8_t block) {
|
||||||
|
|
||||||
if (block > spi_flash_p64k) return false;
|
if (block > spi_flash_pages64k) return false;
|
||||||
|
|
||||||
FlashSendByte(BLOCK64ERASE);
|
FlashSendByte(BLOCK64ERASE);
|
||||||
FlashSendByte(block);
|
FlashSendByte(block);
|
||||||
|
@ -350,57 +352,22 @@ void Flashmem_print_status(void) {
|
||||||
}
|
}
|
||||||
DbpString(" Init.................... " _GREEN_("ok"));
|
DbpString(" Init.................... " _GREEN_("ok"));
|
||||||
|
|
||||||
// NOTE: It would likely be more useful to use JDEC ID command 9F,
|
if (spi_flash_data.device_id > 0) {
|
||||||
// as it provides a third byte indicative of capacity.
|
Dbprintf(" Mfr ID / Dev ID......... " _YELLOW_("%02X / %02X"),
|
||||||
flash_device_type_t device_type = {0};
|
spi_flash_data.manufacturer_id,
|
||||||
if (!Flash_ReadID(&device_type, false)) {
|
spi_flash_data.device_id
|
||||||
DbpString(" Device ID............... " _RED_(" --> Not Found <--"));
|
|
||||||
} else {
|
|
||||||
if (device_type.manufacturer_id == WINBOND_MANID) {
|
|
||||||
switch (device_type.device_id) {
|
|
||||||
case WINBOND_32MB_DEVID:
|
|
||||||
DbpString(" Memory size............. " _YELLOW_("32 mbits / 4 MB"));
|
|
||||||
break;
|
|
||||||
case WINBOND_16MB_DEVID:
|
|
||||||
DbpString(" Memory size............. " _YELLOW_("16 mbits / 2 MB"));
|
|
||||||
break;
|
|
||||||
case WINBOND_8MB_DEVID:
|
|
||||||
DbpString(" Memory size............. " _YELLOW_("8 mbits / 1 MB"));
|
|
||||||
break;
|
|
||||||
case WINBOND_4MB_DEVID:
|
|
||||||
DbpString(" Memory size............. " _YELLOW_("4 mbits / 512 kb"));
|
|
||||||
break;
|
|
||||||
case WINBOND_2MB_DEVID:
|
|
||||||
DbpString(" Memory size............. " _YELLOW_("2 mbits / 256 kb"));
|
|
||||||
break;
|
|
||||||
case WINBOND_1MB_DEVID:
|
|
||||||
DbpString(" Memory size..... ....... " _YELLOW_("1 mbits / 128 kb"));
|
|
||||||
break;
|
|
||||||
case WINBOND_512KB_DEVID:
|
|
||||||
DbpString(" Memory size............. " _YELLOW_("512 kbits / 64 kb"));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
Dbprintf(" Device ID............... " _YELLOW_("%02X / %02X (Winbond)"),
|
|
||||||
device_type.manufacturer_id,
|
|
||||||
device_type.device_id
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Dbprintf(" Device ID............... " _YELLOW_("%02X / %02X (unknown)"),
|
|
||||||
device_type.manufacturer_id,
|
|
||||||
device_type.device_id
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (Flash_ReadID(&device_type, true)) {
|
|
||||||
Dbprintf(" JEDEC Mfr ID / Dev ID... " _YELLOW_("%02X / %02X%02X"),
|
if (spi_flash_data.jedec_id > 0) {
|
||||||
device_type.manufacturer_id,
|
Dbprintf(" JEDEC Mfr ID / Dev ID... " _YELLOW_("%02X / %04X"),
|
||||||
device_type.device_id,
|
spi_flash_data.manufacturer_id,
|
||||||
device_type.device_id2
|
spi_flash_data.jedec_id
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Dbprintf(" Flash pages (64k)....... " _YELLOW_("0x%02x (%u)"), spi_flash_p64k, spi_flash_p64k);
|
Dbprintf(" Device.................. " _YELLOW_("%s"), spi_flash_data.device);
|
||||||
|
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};
|
uint8_t uid[8] = {0, 0, 0, 0, 0, 0, 0, 0};
|
||||||
Flash_UniqueID(uid);
|
Flash_UniqueID(uid);
|
||||||
|
@ -428,7 +395,7 @@ void Flashmem_print_info(void) {
|
||||||
uint16_t num;
|
uint16_t num;
|
||||||
|
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
uint16_t isok = Flash_ReadDataCont(DEFAULT_MF_KEYS_OFFSET_P(spi_flash_p64k), keysum, 2);
|
uint16_t isok = Flash_ReadDataCont(DEFAULT_MF_KEYS_OFFSET_P(spi_flash_pages64k), keysum, 2);
|
||||||
if (isok == 2) {
|
if (isok == 2) {
|
||||||
num = ((keysum[1] << 8) | keysum[0]);
|
num = ((keysum[1] << 8) | keysum[0]);
|
||||||
if (num != 0xFFFF && num != 0x0)
|
if (num != 0xFFFF && num != 0x0)
|
||||||
|
@ -436,7 +403,7 @@ void Flashmem_print_info(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
isok = Flash_ReadDataCont(DEFAULT_T55XX_KEYS_OFFSET_P(spi_flash_p64k), keysum, 2);
|
isok = Flash_ReadDataCont(DEFAULT_T55XX_KEYS_OFFSET_P(spi_flash_pages64k), keysum, 2);
|
||||||
if (isok == 2) {
|
if (isok == 2) {
|
||||||
num = ((keysum[1] << 8) | keysum[0]);
|
num = ((keysum[1] << 8) | keysum[0]);
|
||||||
if (num != 0xFFFF && num != 0x0)
|
if (num != 0xFFFF && num != 0x0)
|
||||||
|
@ -444,7 +411,7 @@ void Flashmem_print_info(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Flash_CheckBusy(BUSY_TIMEOUT);
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
isok = Flash_ReadDataCont(DEFAULT_ICLASS_KEYS_OFFSET_P(spi_flash_p64k), keysum, 2);
|
isok = Flash_ReadDataCont(DEFAULT_ICLASS_KEYS_OFFSET_P(spi_flash_pages64k), keysum, 2);
|
||||||
if (isok == 2) {
|
if (isok == 2) {
|
||||||
num = ((keysum[1] << 8) | keysum[0]);
|
num = ((keysum[1] << 8) | keysum[0]);
|
||||||
if (num != 0xFFFF && num != 0x0)
|
if (num != 0xFFFF && num != 0x0)
|
||||||
|
@ -454,26 +421,47 @@ void Flashmem_print_info(void) {
|
||||||
FlashStop();
|
FlashStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
//read spi flash JEDEC ID and fill the global variable spi_flash_p64k
|
|
||||||
bool FlashDetect(void) {
|
bool FlashDetect(void) {
|
||||||
flash_device_type_t flash_device = {0};
|
flash_device_type_t flash_data = {0};
|
||||||
|
bool ret = false;
|
||||||
if (!Flash_ReadID(&flash_device, true)) {
|
// read using 0x9F (JEDEC)
|
||||||
if (g_dbglevel > 3) Dbprintf("Flash_ReadID failed");
|
if (Flash_ReadID(&flash_data, true)) {
|
||||||
return false;
|
spi_flash_data.manufacturer_id = flash_data.manufacturer_id;
|
||||||
|
spi_flash_data.jedec_id = (flash_data.device_id << 8) + flash_data.device_id2;
|
||||||
|
ret = true;
|
||||||
|
} else {
|
||||||
|
if (g_dbglevel > 3) Dbprintf("Flash_ReadID failed reading JEDEC (0x9F)");
|
||||||
}
|
}
|
||||||
|
// read using 0x90 (Manufacturer / Device ID)
|
||||||
|
if (Flash_ReadID(&flash_data, false)) {
|
||||||
|
if (spi_flash_data.manufacturer_id == 0) {
|
||||||
|
spi_flash_data.manufacturer_id = flash_data.manufacturer_id;
|
||||||
|
}
|
||||||
|
spi_flash_data.device_id = flash_data.device_id;
|
||||||
|
ret = true;
|
||||||
|
} else {
|
||||||
|
if (g_dbglevel > 3) Dbprintf("Flash_ReadID failed reading Mfr/Dev (0x90)");
|
||||||
|
}
|
||||||
|
// default device is 'unknown'
|
||||||
|
spi_flash_data.device = SpiFlashTable[0].device;
|
||||||
|
|
||||||
uint32_t identifier = (flash_device.manufacturer_id << 16) + (flash_device.device_id <<8 ) + flash_device.device_id2;
|
if (ret) {
|
||||||
int i = 0;
|
for (int i = 0; i < ARRAYLEN(SpiFlashTable); i++) {
|
||||||
for (; i < ARRAYLEN(SpiFlashTable)-1; i++) {
|
if (SpiFlashTable[i].manufacturer_id == spi_flash_data.manufacturer_id) {
|
||||||
if (SpiFlashTable[i].identifier == identifier) {
|
if (SpiFlashTable[i].jedec_id == spi_flash_data.jedec_id) {
|
||||||
|
spi_flash_pages64k = SpiFlashTable[i].pages64k;
|
||||||
|
spi_flash_data.device = SpiFlashTable[i].device;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (SpiFlashTable[i].device_id == spi_flash_data.device_id) {
|
||||||
|
spi_flash_data.device = SpiFlashTable[i].device;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
spi_flash_p64k = SpiFlashTable[i].pages64;
|
return ret;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // #ifndef AS_BOOTROM
|
#endif // #ifndef AS_BOOTROM
|
||||||
|
@ -491,7 +479,7 @@ bool FlashInit(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef AS_BOOTROM
|
#ifndef AS_BOOTROM
|
||||||
if (spi_flash_p64k == 0) {
|
if (spi_flash_data.manufacturer_id == 0) {
|
||||||
if (!FlashDetect()) {
|
if (!FlashDetect()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,15 +54,6 @@
|
||||||
// Flash busy timeout: 20ms is the strict minimum when writing 256kb
|
// Flash busy timeout: 20ms is the strict minimum when writing 256kb
|
||||||
#define BUSY_TIMEOUT 200000L
|
#define BUSY_TIMEOUT 200000L
|
||||||
|
|
||||||
#define WINBOND_MANID 0xEF
|
|
||||||
#define WINBOND_32MB_DEVID 0x15
|
|
||||||
#define WINBOND_16MB_DEVID 0x14
|
|
||||||
#define WINBOND_8MB_DEVID 0x13
|
|
||||||
#define WINBOND_4MB_DEVID 0x12
|
|
||||||
#define WINBOND_2MB_DEVID 0x11
|
|
||||||
#define WINBOND_1MB_DEVID 0x10
|
|
||||||
#define WINBOND_512KB_DEVID 0x05
|
|
||||||
|
|
||||||
#define PAGESIZE 0x100
|
#define PAGESIZE 0x100
|
||||||
#define WINBOND_WRITE_DELAY 0x02
|
#define WINBOND_WRITE_DELAY 0x02
|
||||||
|
|
||||||
|
@ -145,38 +136,48 @@ uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len);
|
||||||
void Flashmem_print_status(void);
|
void Flashmem_print_status(void);
|
||||||
void Flashmem_print_info(void);
|
void Flashmem_print_info(void);
|
||||||
|
|
||||||
typedef struct spi_flash_s {
|
typedef struct {
|
||||||
const uint32_t identifier;
|
uint8_t manufacturer_id;
|
||||||
const uint8_t pages64;
|
uint8_t device_id;
|
||||||
const char *desc;
|
uint16_t jedec_id;
|
||||||
|
uint8_t pages64k;
|
||||||
|
char *device;
|
||||||
} spi_flash_t;
|
} spi_flash_t;
|
||||||
|
|
||||||
const static spi_flash_t SpiFlashTable[] = {
|
static const spi_flash_t SpiFlashTable[] = {
|
||||||
|
// first element is the default of 4 * 64kB pages (256kB)
|
||||||
|
{ 0x00, 0x00, 0x0000, 4, "unknown" }, // 256k
|
||||||
// Manufacturer: Puya
|
// Manufacturer: Puya
|
||||||
{ 0x856015, 32, "P25Q16H" },
|
{ 0x85, 0x00, 0x6015, 32, "P25Q16H" }, // 2048k
|
||||||
|
/// Manufacturer: Renesas
|
||||||
|
{ 0x1F, 0x46, 0x0000, 32, "AT25XE161D" }, // 2048k
|
||||||
|
{ 0x1F, 0x47, 0x0000, 64, "AT25XE321D" }, // 4096k
|
||||||
// Manufacturer: Winbond
|
// Manufacturer: Winbond
|
||||||
{ 0xEF3012, 4, "W25X20BV" },
|
{ 0xEF, 0x00, 0x3012, 4, "W25X20BV" }, // 256k
|
||||||
{ 0xEF3013, 8, "W25X40BV" },
|
{ 0xEF, 0x00, 0x3013, 8, "W25X40BV" }, // 512k
|
||||||
|
|
||||||
{ 0xEF4013, 8, "W25Q40BV" },
|
{ 0xEF, 0x00, 0x4013, 8, "W25Q40BV" }, // 512k
|
||||||
{ 0xEF4014, 16, "W25Q80BV" },
|
{ 0xEF, 0x00, 0x4014, 16, "W25Q80BV" }, // 1024k
|
||||||
{ 0xEF4015, 32, "W25Q16BV" },
|
{ 0xEF, 0x14, 0x4015, 32, "W25Q16BV" }, // 2048k
|
||||||
{ 0xEF4016, 64, "W25Q32BV" },
|
{ 0xEF, 0x15, 0x4016, 64, "W25Q32BV" }, // 4096k
|
||||||
|
|
||||||
{ 0xEF7022, 4, "W25Q02JV" },
|
{ 0xEF, 0x21, 0x7022, 4, "W25Q02JV" },
|
||||||
// (default) last record
|
// identified by Manufacturer /Device ID
|
||||||
{ 0x000000, 4, "Unknown!" }
|
// { 0xEF, 0x05, 0x0000, 1, "Winbond!!!" },
|
||||||
|
{ 0xEF, 0x10, 0x0000, 2, "W25*10BV!!!" }, // 128k
|
||||||
|
{ 0xEF, 0x11, 0x0000, 4, "W25*20BV" }, // 256k
|
||||||
|
{ 0xEF, 0x12, 0x0000, 8, "W25*40BV" }, // 512k
|
||||||
|
{ 0xEF, 0x13, 0x0000, 16, "W25*80BV" } // 1024k
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern uint8_t spi_flash_pages64k;
|
||||||
|
|
||||||
|
bool FlashDetect(void);
|
||||||
|
|
||||||
#ifndef ARRAYLEN
|
#ifndef ARRAYLEN
|
||||||
# define ARRAYLEN(x) (sizeof(x)/sizeof((x)[0]))
|
# define ARRAYLEN(x) (sizeof(x)/sizeof((x)[0]))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern uint8_t spi_flash_p64k;
|
|
||||||
|
|
||||||
bool FlashDetect(void);
|
|
||||||
|
|
||||||
#endif // #ifndef AS_BOOTROM
|
#endif // #ifndef AS_BOOTROM
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -4554,7 +4554,7 @@
|
||||||
"-h, --help This help",
|
"-h, --help This help",
|
||||||
"--blk <dec> Target block",
|
"--blk <dec> Target block",
|
||||||
"-b Target key B instead of default key A",
|
"-b Target key B instead of default key A",
|
||||||
"-c <dec> Target Auth 6x"
|
"-c <dec> Target key type is key A + offset"
|
||||||
],
|
],
|
||||||
"usage": "hf mf darkside [-hb] [--blk <dec> ] [-c <dec>]"
|
"usage": "hf mf darkside [-hb] [--blk <dec> ] [-c <dec>]"
|
||||||
},
|
},
|
||||||
|
@ -13003,6 +13003,6 @@
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"commands_extracted": 749,
|
"commands_extracted": 749,
|
||||||
"extracted_by": "PM3Help2JSON v1.00",
|
"extracted_by": "PM3Help2JSON v1.00",
|
||||||
"extracted_on": "2024-11-15T13:26:34"
|
"extracted_on": "2024-11-20T23:37:32"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,10 @@ all: $(BINS)
|
||||||
echo "ERROR: Firmware image too large for your platform! $$FWSIZE > $(FWMAXSIZE)"; \
|
echo "ERROR: Firmware image too large for your platform! $$FWSIZE > $(FWMAXSIZE)"; \
|
||||||
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"; \
|
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"; \
|
||||||
exit 1; \
|
exit 1; \
|
||||||
fi
|
fi; \
|
||||||
|
echo "==================================================================="; \
|
||||||
|
echo "Firmware size: $$FWSIZE bytes ($$((FWSIZE/1024))kb) = $$((FWSIZE*100/$(FWMAXSIZE)))% of $$(($(FWMAXSIZE)/1024))kb"; \
|
||||||
|
echo "==================================================================="
|
||||||
|
|
||||||
bootrom.bin: ../bootrom/obj/bootrom.elf
|
bootrom.bin: ../bootrom/obj/bootrom.elf
|
||||||
$(info [=] GEN $@)
|
$(info [=] GEN $@)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue