mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-03-12 04:35:28 -07:00
Merge branch 'master' into hf-mf-ultimatecard-script-auto-set-maxblock
Signed-off-by: Iceman <iceman@iuse.se>
This commit is contained in:
commit
8079153ee6
@ -4,6 +4,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Automatically set maximum read/write block when using predefined types in `hf_mf_ultimatecard` script (@piotrva)
|
||||
- Changed SPI flash detection to calculate the size instead of table lookup, updated spi_flash_decode.py script with more ICs (@ANTodorov)
|
||||
- Fixed `hf/lf tune` segfault when called from script (@doegox)
|
||||
- Added option to set and get maximum read/write block number using `hf_mf_ultimatecard` script (@piotrva)
|
||||
- Added JEDEC information for SPI flash W25Q64JV (@ANTodorov)
|
||||
|
@ -3482,7 +3482,7 @@ void MifareGen3Blk(uint8_t block_len, uint8_t *block) {
|
||||
retval = PM3_ESOFT;
|
||||
goto OUT;
|
||||
}
|
||||
cmd[ofs] = block_len < card_info->uidlen ? card_info->sak : cmd[ofs];
|
||||
cmd[ofs] = block_len <= card_info->uidlen ? card_info->sak : cmd[ofs];
|
||||
ofs++;
|
||||
cmd[ofs++] = card_info->atqa[0];
|
||||
cmd[ofs++] = card_info->atqa[1];
|
||||
|
@ -12,62 +12,118 @@ except ModuleNotFoundError:
|
||||
return str(s)
|
||||
|
||||
spi = {
|
||||
0x68:{
|
||||
"manufacturer": "Boya",
|
||||
"jedec" : {
|
||||
0x40: {
|
||||
0x15: {
|
||||
"part": "BY25Q16BS",
|
||||
"size": "16mbits",
|
||||
"sizeB": "2MB",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
0x85:{
|
||||
"manufacturer": "Puya",
|
||||
0x60: {
|
||||
0x15: {
|
||||
"part": "P25Q16H",
|
||||
"size": "16mbits",
|
||||
"sizeB": "2MB",
|
||||
"jedec" : {
|
||||
0x60: {
|
||||
0x15: {
|
||||
"part": "P25Q16H",
|
||||
"size": "16mbits",
|
||||
"sizeB": "2MB",
|
||||
},
|
||||
0x16: {
|
||||
"part": "P25Q32H",
|
||||
"size": "32mbits",
|
||||
"sizeB": "4MB",
|
||||
},
|
||||
0x17: {
|
||||
"part": "P25Q64H",
|
||||
"size": "64mbits",
|
||||
"sizeB": "8MB",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
0xEF:{
|
||||
"manufacturer": "Winbond",
|
||||
0x30: {
|
||||
0x11: {
|
||||
"part": "W25X10BV",
|
||||
"size": "1mbits",
|
||||
"sizeB": "128KB",
|
||||
"jedec" : {
|
||||
0x30: {
|
||||
0x11: {
|
||||
"part": "W25X10BV",
|
||||
"size": "1mbits",
|
||||
"sizeB": "128KB",
|
||||
},
|
||||
0x12: {
|
||||
"part": "W25X20BV",
|
||||
"size": "2mbits",
|
||||
"sizeB": "256KB",
|
||||
},
|
||||
0x13: {
|
||||
"part": "W25X40BV",
|
||||
"size": "4mbits",
|
||||
"sizeB": "512KB",
|
||||
},
|
||||
},
|
||||
0x12: {
|
||||
"part": "W25X20BV",
|
||||
"size": "2mbits",
|
||||
"sizeB": "256KB",
|
||||
0x40: {
|
||||
0x12: {
|
||||
"part": "W25Q20BV",
|
||||
"size": "2mbits",
|
||||
"sizeB": "256KB",
|
||||
},
|
||||
0x13: {
|
||||
"part": "W25Q40BV",
|
||||
"size": "4mbits",
|
||||
"sizeB": "512KB",
|
||||
},
|
||||
0x14: {
|
||||
"part": "W25Q80BV",
|
||||
"size": "8mbits",
|
||||
"sizeB": "1MB",
|
||||
},
|
||||
0x15: {
|
||||
"part": "W25Q16BV",
|
||||
"size": "16mbits",
|
||||
"sizeB": "2MB",
|
||||
},
|
||||
0x16: {
|
||||
"part": "W25Q32BV",
|
||||
"size": "32mbits",
|
||||
"sizeB": "4MB",
|
||||
},
|
||||
0x17: {
|
||||
"part": "W25Q64BV",
|
||||
"size": "64mbits",
|
||||
"sizeB": "8MB",
|
||||
},
|
||||
},
|
||||
0x13: {
|
||||
"part": "W25X40BV",
|
||||
"size": "4mbits",
|
||||
"sizeB": "512KB",
|
||||
},
|
||||
},
|
||||
0x40: {
|
||||
0x13: {
|
||||
"part": "W25Q40BV",
|
||||
"size": "4mbits",
|
||||
"sizeB": "512KB",
|
||||
},
|
||||
0x14: {
|
||||
"part": "W25Q80BV",
|
||||
"size": "8mbits",
|
||||
"sizeB": "1MB",
|
||||
},
|
||||
0x15: {
|
||||
"part": "W25Q16BV",
|
||||
"size": "16mbits",
|
||||
"sizeB": "2MB",
|
||||
},
|
||||
0x16: {
|
||||
"part": "W25Q32BV",
|
||||
"size": "32mbits",
|
||||
"sizeB": "4MB",
|
||||
},
|
||||
},
|
||||
0x70: {
|
||||
0x22: {
|
||||
"part": "W25Q02JV-IM",
|
||||
"size": "2mbits",
|
||||
"sizeB": "256KB",
|
||||
0x70: {
|
||||
0x14: {
|
||||
"part": "W25Q80JV",
|
||||
"size": "8mbits",
|
||||
"sizeB": "1MB",
|
||||
},
|
||||
0x15: {
|
||||
"part": "W25Q16JV",
|
||||
"size": "16mbits",
|
||||
"sizeB": "2MB",
|
||||
},
|
||||
0x16: {
|
||||
"part": "W25Q32JV",
|
||||
"size": "32mbits",
|
||||
"sizeB": "4MB",
|
||||
},
|
||||
0x17: {
|
||||
"part": "W25Q64JV",
|
||||
"size": "64mbits",
|
||||
"sizeB": "8MB",
|
||||
},
|
||||
0x22: {
|
||||
"part": "W25Q02JV-IM",
|
||||
"size": "2mbits",
|
||||
"sizeB": "256KB",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -90,16 +146,16 @@ for line in p.grabbed_output.split('\n'):
|
||||
did_h = did >> 8
|
||||
did_l = did & 0xff
|
||||
t = None
|
||||
|
||||
print(f"\n JEDEC ID....... 0x{mid:X} / 0x{did:X}")
|
||||
if mid in spi:
|
||||
|
||||
mfr = spi[mid]['manufacturer']
|
||||
|
||||
if did_h in spi[mid]:
|
||||
if did_h in spi[mid]['jedec']:
|
||||
|
||||
if did_l in spi[mid][did_h]:
|
||||
if did_l in spi[mid]['jedec'][did_h]:
|
||||
|
||||
t = spi[mid][did_h][did_l]
|
||||
t = spi[mid]['jedec'][did_h][did_l]
|
||||
print("\n Manufacturer... " + color(f"{mfr}", fg="green") +
|
||||
"\n Device......... " + color(f"{t['part']}", fg="green") +
|
||||
"\n Size........... " + color(f"{t['size']} ({t['sizeB']})", fg="yellow")
|
||||
|
@ -1065,10 +1065,10 @@
|
||||
},
|
||||
{
|
||||
"AID": "DD00DD",
|
||||
"Vendor": "Regional Transporation District (RTD) via masabi justride",
|
||||
"Vendor": "Regional Transporation District (RTD) via Masabi Ltd",
|
||||
"Country": "US",
|
||||
"Name": "MyRide Card (DEN)",
|
||||
"Description": "DEN MyRide Card",
|
||||
"Description": "DEN MyRide Card; Masabi Justride Tap and Ride DESFire Smartcard",
|
||||
"Type": "transport"
|
||||
},
|
||||
{
|
||||
|
@ -7202,7 +7202,8 @@ static int CmdHf14AGen3Block(const char *Cmd) {
|
||||
" - You can specify part of manufacturer block as\n"
|
||||
" 4/7-bytes for UID change only\n"
|
||||
"\n"
|
||||
"NOTE: BCC, SAK, ATQA will be calculated automatically"
|
||||
"NOTE: BCC and ATQA will be calculated automatically\n"
|
||||
"SAK will be automatically set to default values if not specified"
|
||||
,
|
||||
"hf mf gen3blk --> print current data\n"
|
||||
"hf mf gen3blk -d 01020304 --> set 4 byte uid\n"
|
||||
|
@ -444,6 +444,96 @@ static int CmdLFHitagSRead(const char *Cmd) {
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdLFHitagSDump(const char *Cmd) {
|
||||
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf hitag hts dump",
|
||||
"Read all Hitag S memory and save to file\n"
|
||||
" Crypto mode: \n"
|
||||
" - key format ISK high + ISK low\n"
|
||||
" - default key 4F4E4D494B52 (ONMIKR)\n\n"
|
||||
" 8268/8310 password mode: \n"
|
||||
" - default password BBDD3399\n",
|
||||
"lf hitag hts dump --82xx -k BBDD3399 -> pwd mode\n"
|
||||
"lf hitag hts dump --crypto -> use def crypto\n"
|
||||
"lf hitag hts dump -k 4F4E4D494B52 -> crypto mode\n"
|
||||
"lf hitag hts dump --nrar 0102030411223344\n"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("8", "82xx", "8268/8310 mode"),
|
||||
arg_str0(NULL, "nrar", "<hex>", "nonce / answer writer, 8 hex bytes"),
|
||||
arg_lit0(NULL, "crypto", "crypto mode"),
|
||||
arg_str0("k", "key", "<hex>", "pwd or key, 4 or 6 hex bytes"),
|
||||
arg_int0("m", "mode", "<dec>", "response protocol mode. 0 (Standard 00110), 1 (Advanced 11000), 2 (Advanced 11001), 3 (Fast Advanced 11010) (def: 3)"),
|
||||
arg_str0("f", "file", "<fn>", "specify file name"),
|
||||
arg_lit0(NULL, "ns", "no save to file"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
lf_hitag_data_t packet;
|
||||
memset(&packet, 0, sizeof(packet));
|
||||
|
||||
if (process_hitags_common_args(ctx, &packet) < 0) {
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
int fnlen = 0;
|
||||
char filename[FILE_PATH_SIZE] = {0};
|
||||
CLIParamStrToBuf(arg_get_str(ctx, 6), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||
|
||||
bool nosave = arg_get_lit(ctx, 7);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
// read all pages
|
||||
packet.page = 0;
|
||||
packet.page_count = 0;
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_LF_HITAGS_READ, (uint8_t *) &packet, sizeof(packet));
|
||||
|
||||
PacketResponseNG resp;
|
||||
if (WaitForResponseTimeout(CMD_LF_HITAGS_READ, &resp, 5000) == false) {
|
||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
if (resp.status != PM3_SUCCESS) {
|
||||
print_error(resp.reason);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
lf_hts_read_response_t *card = (lf_hts_read_response_t *)resp.data.asBytes;
|
||||
|
||||
const int hts_mem_sizes[] = {1, 8, 64, 64};
|
||||
int mem_size = hts_mem_sizes[card->config_page.s.MEMT] * HITAGS_PAGE_SIZE;
|
||||
|
||||
hitags_config_t config = card->config_page.s;
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------");
|
||||
hitags_config_print(config);
|
||||
|
||||
if (nosave) {
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(INFO, "Called with no save option");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
if (fnlen < 1) {
|
||||
char *fptr = filename;
|
||||
fptr += snprintf(filename, sizeof(filename), "lf-hitags-");
|
||||
FillFileNameByUID(fptr, card->pages[HITAGS_UID_PADR], "-dump", HITAGS_PAGE_SIZE);
|
||||
}
|
||||
|
||||
pm3_save_dump(filename, (uint8_t *)card->pages, mem_size, jsfHitag);
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdLFHitagSWrite(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf hitag hts wrbl",
|
||||
@ -615,6 +705,7 @@ static command_t CommandTable[] = {
|
||||
{"-----------", CmdHelp, IfPm3Hitag, "----------------------- " _CYAN_("General") " ------------------------"},
|
||||
{"reader", CmdLFHitagSReader, IfPm3Hitag, "Act like a Hitag S reader"},
|
||||
{"rdbl", CmdLFHitagSRead, IfPm3Hitag, "Read Hitag S page"},
|
||||
{"dump", CmdLFHitagSDump, IfPm3Hitag, "Dump Hitag S pages to a file"},
|
||||
{"wrbl", CmdLFHitagSWrite, IfPm3Hitag, "Write Hitag S page"},
|
||||
{"-----------", CmdHelp, IfPm3Hitag, "----------------------- " _CYAN_("Simulation") " -----------------------"},
|
||||
{"sim", CmdLFHitagSSim, IfPm3Hitag, "Simulate Hitag S transponder"},
|
||||
|
@ -366,7 +366,6 @@ void Flashmem_print_status(void) {
|
||||
);
|
||||
}
|
||||
|
||||
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};
|
||||
@ -442,21 +441,13 @@ bool FlashDetect(void) {
|
||||
} else {
|
||||
if (g_dbglevel > 3) Dbprintf("Flash_ReadID failed reading Mfr/Dev (0x90)");
|
||||
}
|
||||
// default device is 'unknown'
|
||||
spi_flash_data.device = SpiFlashTable[0].device;
|
||||
|
||||
// Check JEDEC data is valid, compare the reported device types and then calculate the number of pages
|
||||
// It is covering the most (known) cases of devices but probably there are vendors with different data
|
||||
// They will be handled when there is such cases
|
||||
if (ret) {
|
||||
for (int i = 0; i < ARRAYLEN(SpiFlashTable); i++) {
|
||||
if (SpiFlashTable[i].manufacturer_id == spi_flash_data.manufacturer_id) {
|
||||
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;
|
||||
}
|
||||
if (spi_flash_data.jedec_id > 0 && spi_flash_data.jedec_id < 0xFFFF) {
|
||||
if (((spi_flash_data.device_id + 1) & 0x0F) == (spi_flash_data.jedec_id & 0x000F)) {
|
||||
spi_flash_pages64k = 1 << (spi_flash_data.jedec_id & 0x000F);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -140,41 +140,8 @@ typedef struct {
|
||||
uint8_t manufacturer_id;
|
||||
uint8_t device_id;
|
||||
uint16_t jedec_id;
|
||||
uint8_t pages64k;
|
||||
char *device;
|
||||
} spi_flash_t;
|
||||
|
||||
static const spi_flash_t SpiFlashTable[] = {
|
||||
// first element is the default of 4 * 64kB pages (256kB)
|
||||
{ 0x00, 0x00, 0x0000, 4, "unknown" }, // 256k
|
||||
// Manufacturer: Puya
|
||||
{ 0x85, 0x14, 0x6015, 32, "P25Q16H" }, // 2048k
|
||||
// Manufacturer: Winbond
|
||||
{ 0xEF, 0x00, 0x3012, 4, "W25X20BV" }, // 256k
|
||||
{ 0xEF, 0x00, 0x3013, 8, "W25X40BV" }, // 512k
|
||||
|
||||
{ 0xEF, 0x00, 0x4013, 8, "W25Q40BV" }, // 512k
|
||||
{ 0xEF, 0x00, 0x4014, 16, "W25Q80BV" }, // 1024k
|
||||
{ 0xEF, 0x14, 0x4015, 32, "W25Q16BV" }, // 2048k
|
||||
{ 0xEF, 0x15, 0x4016, 64, "W25Q32BV" }, // 4096k
|
||||
|
||||
{ 0xEF, 0x16, 0x7017, 128, "W25Q64JV" }, // 8192k
|
||||
{ 0xEF, 0x21, 0x7022, 4, "W25Q02JV" },
|
||||
|
||||
// identified by Manufacturer /Device ID only
|
||||
/// Manufacturer: Renesas
|
||||
{ 0x1F, 0x46, 0x0000, 32, "AT25XE161D" }, // 2048k
|
||||
{ 0x1F, 0x47, 0x0000, 64, "AT25XE321D" }, // 4096k
|
||||
// { 0xEF, 0x05, 0x0000, 1, "Winbond!!!" }, // 64k (too small !!!)
|
||||
{ 0xEF, 0x10, 0x0000, 2, "W25*10BV!" }, // 128k (small !!!)
|
||||
{ 0xEF, 0x11, 0x0000, 4, "W25*20BV" }, // 256k
|
||||
{ 0xEF, 0x12, 0x0000, 8, "W25*40BV" }, // 512k
|
||||
{ 0xEF, 0x13, 0x0000, 16, "W25*80BV" }, // 1024k
|
||||
{ 0xEF, 0x14, 0x0000, 32, "W25*16*" }, // 2048k
|
||||
{ 0xEF, 0x15, 0x0000, 64, "W25*32*" }, // 4096k
|
||||
{ 0xEF, 0x16, 0x0000, 128, "W25*64*" } // 8192k
|
||||
};
|
||||
|
||||
extern uint8_t spi_flash_pages64k;
|
||||
|
||||
bool FlashDetect(void);
|
||||
|
45
fpga/xc2s50-5-tq144.ucf
Normal file
45
fpga/xc2s50-5-tq144.ucf
Normal file
@ -0,0 +1,45 @@
|
||||
# See the schematic for the pin assignment.
|
||||
|
||||
NET "adc_d<0>" LOC = "P54" ;
|
||||
NET "adc_d<1>" LOC = "P57" ;
|
||||
NET "adc_d<2>" LOC = "P59" ;
|
||||
NET "adc_d<3>" LOC = "P60" ;
|
||||
NET "adc_d<4>" LOC = "P62" ;
|
||||
NET "adc_d<5>" LOC = "P63" ;
|
||||
NET "adc_d<6>" LOC = "P65" ;
|
||||
NET "adc_d<7>" LOC = "P67" ;
|
||||
#NET "cross_hi" LOC = "P88" ;
|
||||
#NET "miso" LOC = "P40" ;
|
||||
NET "adc_clk" LOC = "P75" ;
|
||||
NET "adc_noe" LOC = "P74" ;
|
||||
NET "ck_1356meg" LOC = "P15" ;
|
||||
NET "ck_1356megb" LOC = "P12" ;
|
||||
NET "cross_lo" LOC = "P19" ;
|
||||
NET "dbg" LOC = "P112" ;
|
||||
NET "mosi" LOC = "P80" ;
|
||||
NET "ncs" LOC = "P79" ;
|
||||
NET "pck0" LOC = "P91" ;
|
||||
NET "pwr_hi" LOC = "P31" ;
|
||||
NET "pwr_lo" LOC = "P30" ;
|
||||
NET "pwr_oe1" LOC = "P28" ;
|
||||
NET "pwr_oe2" LOC = "P27" ;
|
||||
NET "pwr_oe3" LOC = "P26" ;
|
||||
NET "pwr_oe4" LOC = "P21" ;
|
||||
NET "spck" LOC = "P88" ;
|
||||
NET "ssp_clk" LOC = "P43" ;
|
||||
NET "ssp_din" LOC = "P99" ;
|
||||
NET "ssp_dout" LOC = "P94" ;
|
||||
NET "ssp_frame" LOC = "P100" ;
|
||||
|
||||
# definition of Clock nets:
|
||||
NET "ck_1356meg" TNM_NET = "clk_net_1356" ;
|
||||
NET "ck_1356megb" TNM_NET = "clk_net_1356b";
|
||||
NET "pck0" TNM_NET = "clk_net_pck0" ;
|
||||
NET "spck" TNM_NET = "clk_net_spck" ;
|
||||
|
||||
# Timing specs of clock nets:
|
||||
TIMEGRP "clk_net_1356_all" = "clk_net_1356" "clk_net_1356b" ;
|
||||
TIMESPEC "TS_1356MHz" = PERIOD "clk_net_1356_all" 74 ns HIGH 37 ns ;
|
||||
TIMESPEC "TS_24MHz" = PERIOD "clk_net_pck0" 42 ns HIGH 21 ns ;
|
||||
TIMESPEC "TS_4MHz" = PERIOD "clk_net_spck" 250 ns HIGH 125 ns ;
|
||||
|
Loading…
x
Reference in New Issue
Block a user