Merge branch 'master' into new-keys

Signed-off-by: Iceman <iceman@iuse.se>
This commit is contained in:
Iceman 2025-05-12 19:28:39 +02:00 committed by GitHub
commit 1199710644
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 189 additions and 75 deletions

View file

@ -3,6 +3,7 @@ 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]
- Fixed `hf mf ekeyprn` - failed to download emulator memory due to wrong size calculation (@iceman1001)
- Fixed `hf mf fchk --mem` to actually use flash dict (@doegox) - Fixed `hf mf fchk --mem` to actually use flash dict (@doegox)
- Fixed `make install` on OSX thanks DaveItsLong (@doegox) - Fixed `make install` on OSX thanks DaveItsLong (@doegox)
- Added new standalone mode `HF_ST25_TEAROFF` to store/restore ST25TB tags with tearoff for counters (@seclabz) - Added new standalone mode `HF_ST25_TEAROFF` to store/restore ST25TB tags with tearoff for counters (@seclabz)

View file

@ -264,8 +264,11 @@ ifeq ($(PLATFORM_CHANGED),true)
$(Q)$(MAKE) --no-print-directory -C bootrom clean $(Q)$(MAKE) --no-print-directory -C bootrom clean
$(Q)$(MAKE) --no-print-directory -C armsrc clean $(Q)$(MAKE) --no-print-directory -C armsrc clean
$(Q)$(MAKE) --no-print-directory -C recovery clean $(Q)$(MAKE) --no-print-directory -C recovery clean
$(Q)$(MAKE) --no-print-directory -C client clean
$(Q)$(MAKE) --no-print-directory -C tools/fpga_compress clean $(Q)$(MAKE) --no-print-directory -C tools/fpga_compress clean
# clean the client only if PLATFORM got changed from or to PM3ICOPYX
ifeq (PM3ICOPYX,$(filter PM3ICOPYX, $(PLATFORM) $(CACHED_PLATFORM)))
$(Q)$(MAKE) --no-print-directory -C client clean
endif
$(Q)$(ECHO) CACHED_PLATFORM=$(PLATFORM) > .Makefile.options.cache $(Q)$(ECHO) CACHED_PLATFORM=$(PLATFORM) > .Makefile.options.cache
$(Q)$(ECHO) CACHED_PLATFORM_EXTRAS=$(PLATFORM_EXTRAS) >> .Makefile.options.cache $(Q)$(ECHO) CACHED_PLATFORM_EXTRAS=$(PLATFORM_EXTRAS) >> .Makefile.options.cache
$(Q)$(ECHO) CACHED_PLATFORM_DEFS=$(PLATFORM_DEFS) >> .Makefile.options.cache $(Q)$(ECHO) CACHED_PLATFORM_DEFS=$(PLATFORM_DEFS) >> .Makefile.options.cache

View file

@ -27,6 +27,10 @@ PLATFORM=PM3RDV4
# Only available with PLATFORM=PM3GENERIC # Only available with PLATFORM=PM3GENERIC
#LED_ORDER=PM3EASY #LED_ORDER=PM3EASY
# Uncomment a line below to change default USART baud rate
# defaults to 115200 used by HC-05 in Blueshark
#USART_BAUD_RATE=19200
# Uncomment the lines below in order to make a 256KB image # Uncomment the lines below in order to make a 256KB image
# and comment out the lines above # and comment out the lines above

View file

@ -1664,13 +1664,13 @@ static void PacketReceived(PacketCommandNG *packet) {
break; break;
} }
case CMD_HF_ISO14443A_GET_CONFIG: { case CMD_HF_ISO14443A_GET_CONFIG: {
hf14a_config *hf14aconfig = getHf14aConfig(); hf14a_config_t *c = getHf14aConfig();
reply_ng(CMD_HF_ISO14443A_GET_CONFIG, PM3_SUCCESS, (uint8_t *)hf14aconfig, sizeof(hf14a_config)); reply_ng(CMD_HF_ISO14443A_GET_CONFIG, PM3_SUCCESS, (uint8_t *)c, sizeof(hf14a_config_t));
break; break;
} }
case CMD_HF_ISO14443A_SET_CONFIG: { case CMD_HF_ISO14443A_SET_CONFIG: {
hf14a_config c; hf14a_config_t c;
memcpy(&c, packet->data.asBytes, sizeof(hf14a_config)); memcpy(&c, packet->data.asBytes, sizeof(hf14a_config_t));
setHf14aConfig(&c); setHf14aConfig(&c);
break; break;
} }
@ -1969,7 +1969,7 @@ static void PacketReceived(PacketCommandNG *packet) {
struct p *payload = (struct p *) packet->data.asBytes; struct p *payload = (struct p *) packet->data.asBytes;
// //
size_t size = payload->blockno * payload->blockwidth; size_t size = payload->blockcnt * payload->blockwidth;
if (size > PM3_CMD_DATA_SIZE) { if (size > PM3_CMD_DATA_SIZE) {
reply_ng(CMD_HF_MIFARE_EML_MEMGET, PM3_EMALLOC, NULL, 0); reply_ng(CMD_HF_MIFARE_EML_MEMGET, PM3_EMALLOC, NULL, 0);
return; return;

View file

@ -134,31 +134,29 @@ static uint32_t LastProxToAirDuration;
#define SEC_Z 0xc0 #define SEC_Z 0xc0
static const iso14a_polling_frame_t WUPA_CMD = { static const iso14a_polling_frame_t WUPA_CMD_FRAME = {
{ ISO14443A_CMD_WUPA }, 1, 7, 0 .frame = { ISO14443A_CMD_WUPA },
.frame_length = 1,
.last_byte_bits = 7,
.extra_delay = 0
}; };
static const iso14a_polling_frame_t REQA_CMD = { static const iso14a_polling_frame_t MAGWUPA_CMD_FRAMES[] = {
{ISO14443A_CMD_REQA }, 1, 7, 0 {{ MAGSAFE_CMD_WUPA_1 }, 1, 7, 0},
{{ MAGSAFE_CMD_WUPA_2 }, 1, 7, 0},
{{ MAGSAFE_CMD_WUPA_3 }, 1, 7, 0},
{{ MAGSAFE_CMD_WUPA_4 }, 1, 7, 0}
}; };
static const iso14a_polling_frame_t MAGWUPA_COMMANDS[4] = {
{{ 0x7A }, 1, 7, 0},
{{ 0x7B }, 1, 7, 0},
{{ 0x7C }, 1, 7, 0},
{{ 0x7D }, 1, 7, 0}
};
// Polling frames and configurations // Polling frames and configurations
iso14a_polling_parameters_t WUPA_POLLING_PARAMETERS = { iso14a_polling_parameters_t WUPA_POLLING_PARAMETERS = {
.frames = { WUPA_CMD }, .frames = { {{ ISO14443A_CMD_WUPA }, 1, 7, 0 }},
.frame_count = 1, .frame_count = 1,
.extra_timeout = 0, .extra_timeout = 0,
}; };
iso14a_polling_parameters_t REQA_POLLING_PARAMETERS = { iso14a_polling_parameters_t REQA_POLLING_PARAMETERS = {
.frames = { REQA_CMD }, .frames = { {{ ISO14443A_CMD_REQA }, 1, 7, 0 }},
.frame_count = 1, .frame_count = 1,
.extra_timeout = 0, .extra_timeout = 0,
}; };
@ -173,10 +171,10 @@ Default HF 14a config is set to:
magsafe = 0 (disabled) magsafe = 0 (disabled)
polling_loop_annotation = {{0}, 0, 0, 0} (disabled) polling_loop_annotation = {{0}, 0, 0, 0} (disabled)
*/ */
static hf14a_config hf14aconfig = { 0, 0, 0, 0, 0, 0, {{0}, 0, 0, 0} }; static hf14a_config_t hf14aconfig = { 0, 0, 0, 0, 0, 0, {{0}, 0, 0, 0} };
static iso14a_polling_parameters_t hf14a_polling_parameters = { static iso14a_polling_parameters_t hf14a_polling_parameters = {
.frames = { WUPA_CMD }, .frames = { {{ ISO14443A_CMD_WUPA }, 1, 7, 0 }},
.frame_count = 1, .frame_count = 1,
.extra_timeout = 0 .extra_timeout = 0
}; };
@ -236,45 +234,64 @@ void printHf14aConfig(void) {
* @brief setSamplingConfig * @brief setSamplingConfig
* @param sc * @param sc
*/ */
void setHf14aConfig(const hf14a_config *hc) { void setHf14aConfig(const hf14a_config_t *hc) {
if ((hc->forceanticol >= 0) && (hc->forceanticol <= 2)) if ((hc->forceanticol >= 0) && (hc->forceanticol <= 2)) {
hf14aconfig.forceanticol = hc->forceanticol; hf14aconfig.forceanticol = hc->forceanticol;
if ((hc->forcebcc >= 0) && (hc->forcebcc <= 2)) }
if ((hc->forcebcc >= 0) && (hc->forcebcc <= 2)) {
hf14aconfig.forcebcc = hc->forcebcc; hf14aconfig.forcebcc = hc->forcebcc;
if ((hc->forcecl2 >= 0) && (hc->forcecl2 <= 2)) }
if ((hc->forcecl2 >= 0) && (hc->forcecl2 <= 2)) {
hf14aconfig.forcecl2 = hc->forcecl2; hf14aconfig.forcecl2 = hc->forcecl2;
if ((hc->forcecl3 >= 0) && (hc->forcecl3 <= 2)) }
if ((hc->forcecl3 >= 0) && (hc->forcecl3 <= 2)) {
hf14aconfig.forcecl3 = hc->forcecl3; hf14aconfig.forcecl3 = hc->forcecl3;
if ((hc->forcerats >= 0) && (hc->forcerats <= 2)) }
if ((hc->forcerats >= 0) && (hc->forcerats <= 2)) {
hf14aconfig.forcerats = hc->forcerats; hf14aconfig.forcerats = hc->forcerats;
if ((hc->magsafe >= 0) && (hc->magsafe <= 1)) }
if ((hc->magsafe >= 0) && (hc->magsafe <= 1)) {
hf14aconfig.magsafe = hc->magsafe; hf14aconfig.magsafe = hc->magsafe;
}
if (hc->polling_loop_annotation.frame_length >= 0) { if (hc->polling_loop_annotation.frame_length >= 0) {
memcpy(&hf14aconfig.polling_loop_annotation, &hc->polling_loop_annotation, sizeof(iso14a_polling_frame_t)); memcpy(&hf14aconfig.polling_loop_annotation, &hc->polling_loop_annotation, sizeof(iso14a_polling_frame_t));
} }
// iceman: Somehow I think we should memcpy WUPA_CMD and all other hf14a_polling_parameters.frames[xxx] assignments
// right now we are assigning...
// Derive polling loop configuration based on 14a config // Derive polling loop configuration based on 14a config
hf14a_polling_parameters.frames[0] = WUPA_CMD; hf14a_polling_parameters.frames[0] = WUPA_CMD_FRAME;
hf14a_polling_parameters.frame_count = 1; hf14a_polling_parameters.frame_count = 1;
hf14a_polling_parameters.extra_timeout = 0; hf14a_polling_parameters.extra_timeout = 0;
if (hf14aconfig.magsafe == 1) { if (hf14aconfig.magsafe == 1) {
for (int i = 0; i < ARRAYLEN(MAGWUPA_COMMANDS); i++) {
for (int i = 0; i < ARRAYLEN(MAGWUPA_CMD_FRAMES); i++) {
if (hf14a_polling_parameters.frame_count < ARRAYLEN(hf14a_polling_parameters.frames) - 1) { if (hf14a_polling_parameters.frame_count < ARRAYLEN(hf14a_polling_parameters.frames) - 1) {
hf14a_polling_parameters.frames[hf14a_polling_parameters.frame_count] = MAGWUPA_COMMANDS[i]; hf14a_polling_parameters.frames[hf14a_polling_parameters.frame_count] = MAGWUPA_CMD_FRAMES[i];
hf14a_polling_parameters.frame_count += 1; hf14a_polling_parameters.frame_count++;
} }
} }
} }
if (hf14aconfig.polling_loop_annotation.frame_length > 0) { if (hf14aconfig.polling_loop_annotation.frame_length > 0) {
if (hf14a_polling_parameters.frame_count < ARRAYLEN(hf14a_polling_parameters.frames)) {
if (hf14a_polling_parameters.frame_count < ARRAYLEN(hf14a_polling_parameters.frames) - 1) {
hf14a_polling_parameters.frames[hf14a_polling_parameters.frame_count] = hf14aconfig.polling_loop_annotation; hf14a_polling_parameters.frames[hf14a_polling_parameters.frame_count] = hf14aconfig.polling_loop_annotation;
hf14a_polling_parameters.frame_count += 1; hf14a_polling_parameters.frame_count++;
} }
hf14a_polling_parameters.extra_timeout = 250; hf14a_polling_parameters.extra_timeout = 250;
} }
} }
hf14a_config *getHf14aConfig(void) { hf14a_config_t *getHf14aConfig(void) {
return &hf14aconfig; return &hf14aconfig;
} }
@ -2759,26 +2776,34 @@ static int GetATQA(uint8_t *resp, uint16_t resp_len, uint8_t *resp_par, const is
uint32_t save_iso14a_timeout = iso14a_get_timeout(); uint32_t save_iso14a_timeout = iso14a_get_timeout();
iso14a_set_timeout(1236 / 128 + 1); // response to WUPA is expected at exactly 1236/fc. No need to wait longer. iso14a_set_timeout(1236 / 128 + 1); // response to WUPA is expected at exactly 1236/fc. No need to wait longer.
polling_parameters = polling_parameters != NULL ? polling_parameters : &hf14a_polling_parameters; // refactored to use local pointer, now no modification of polling_parameters pointer is done
// I don't think the intention was to modify polling_parameters when sending in WUPA_POLLING_PARAMETERS etc.
// Modify polling_params, if null use default values.
iso14a_polling_parameters_t p;
memcpy(&p, (uint8_t*)polling_parameters, sizeof(iso14a_polling_parameters_t));
if (polling_parameters == NULL) {
memcpy(&p, (uint8_t*)&hf14a_polling_parameters, sizeof(iso14a_polling_parameters_t));
}
bool first_try = true; bool first_try = true;
int len; int len;
uint32_t retry_timeout = RETRY_TIMEOUT * polling_parameters->frame_count + polling_parameters->extra_timeout; uint32_t retry_timeout = ((RETRY_TIMEOUT * p.frame_count) + p.extra_timeout);
uint32_t start_time = 0; uint32_t start_time = 0;
uint8_t current_frame = 0; uint8_t curr = 0;
// Use the temporary polling parameters // Use the temporary polling parameters
do { do {
const iso14a_polling_frame_t *frame_parameters = &polling_parameters->frames[current_frame]; iso14a_polling_frame_t *frp = &p.frames[curr];
if (frame_parameters->last_byte_bits == 8) { if (frp->last_byte_bits == 8) {
ReaderTransmit(frame_parameters->frame, frame_parameters->frame_length, NULL); ReaderTransmit(frp->frame, frp->frame_length, NULL);
} else { } else {
ReaderTransmitBitsPar(frame_parameters->frame, frame_parameters->last_byte_bits, NULL, NULL); ReaderTransmitBitsPar(frp->frame, frp->last_byte_bits, NULL, NULL);
} }
if (frame_parameters->extra_delay) { if (frp->extra_delay) {
SpinDelay(frame_parameters->extra_delay); SpinDelay(frp->extra_delay);
} }
// Receive the ATQA // Receive the ATQA
@ -2791,7 +2816,8 @@ static int GetATQA(uint8_t *resp, uint16_t resp_len, uint8_t *resp_par, const is
} }
// Go over frame configurations, loop back when we reach the end // Go over frame configurations, loop back when we reach the end
current_frame = current_frame < (polling_parameters->frame_count - 1) ? current_frame + 1 : 0; curr = (curr < (p.frame_count - 1)) ? curr + 1 : 0;
} while (len == 0 && GetTickCountDelta(start_time) <= retry_timeout); } while (len == 0 && GetTickCountDelta(start_time) <= retry_timeout);
iso14a_set_timeout(save_iso14a_timeout); iso14a_set_timeout(save_iso14a_timeout);

View file

@ -125,8 +125,8 @@ typedef enum {
#endif #endif
void printHf14aConfig(void); void printHf14aConfig(void);
void setHf14aConfig(const hf14a_config *hc); void setHf14aConfig(const hf14a_config_t *hc);
hf14a_config *getHf14aConfig(void); hf14a_config_t *getHf14aConfig(void);
void iso14a_set_timeout(uint32_t timeout); void iso14a_set_timeout(uint32_t timeout);
uint32_t iso14a_get_timeout(void); uint32_t iso14a_get_timeout(void);

View file

@ -1905,15 +1905,14 @@ FF16014FEFC7
# Food GEM # Food GEM
6686FADE5566 6686FADE5566
# #
# Samsung Data Systems (SDS) — Electronic Locks # Samsung Data Systems (SDS)
# Gen 1 S10 KA/KB is FFFFFFFFFFFF, incompatible with Gen 2 locks # 10-11 A/B (Gen 2)
# 9B7C25052FC3
# SDS Gen 2 S10 KB
C22E04247D9A C22E04247D9A
6C4F77534170
704153564F6C
# #
# Data from Discord, French pool # Data from Discord, French pool
# SDS Gen 2 S10 KA
9B7C25052FC3
494446555455 494446555455
# #
# Data from Discord, seems to be related to ASSA # Data from Discord, seems to be related to ASSA
@ -3108,7 +3107,7 @@ AB921CF0752C
265A5F32DE73 265A5F32DE73
567D734C403C 567D734C403C
2426217B3B3B 2426217B3B3B
#
# German Aral Gas Station Car-Wash cards # German Aral Gas Station Car-Wash cards
080507020706 080507020706
0100815D8D00 0100815D8D00
@ -3134,3 +3133,55 @@ C082C0F35CE6
B1BA3E778930 B1BA3E778930
2037627D9260 2037627D9260
28C4D7170FCD 28C4D7170FCD
#
# Card keys from Andalusian public transport system (Consorcio de Transportes)
1848A8D1E4C5
16EE1FE134E4
5246B8F4ACFC
515A8209843C
0EF7636AA829
E59D0F78C413
5AF68604DD6B
B0BCB22DCBA3
51B3EF60BF56
99100225D83B
63C88F562B97
B30B6A5AD434
D33E4A4A0041
9C0A4CC89D61
5204D83D8CD3
A662F9DC0D3D
#
# Card keys from EMT Malaga (Spain) bus system
41534E354936
454D41343253
4541444C4130
46305234324E
505444505232
5239425A3546
454449434631
414F4544384C
344E4F4E4937
45444E413254
3255534D3033
4F554D523935
3141544D3735
494E47463539
32414F4E3341
41534C473637
534E41395430
41364C38364F
525241414D39
41304532334F
4D4545494F35
4E324C453045
394143494E32
5352554E3245
324553553036
444D414E3539
324745413232
4E4E41455236
394C52493639
4D4941413236
414D504F3243
434C414E3639

View file

@ -90,13 +90,14 @@ def lprint(s='', end='\n', flush=False, prompt="[" + color("=", fg="yellow") +
- logfile (R) - logfile (R)
""" """
s = f"{prompt}" + f"\n{prompt}".join(s.split('\n')) s = f"{prompt}" + f"\n{prompt}".join(s.split('\n'))
print(s, end=end, flush=flush) safe_s = s.encode('utf-8', errors='ignore').decode('utf-8')
print(safe_s, end=end, flush=flush)
if log is True: if log is True:
global logbuffer global logbuffer
if logfile is not None: if logfile is not None:
with open(logfile, 'a', encoding='utf-8') as f: with open(logfile, 'a', encoding='utf-8') as f:
f.write(s + end) f.write(safe_s + end)
else: else:
# buffering # buffering
logbuffer += s + end logbuffer += s + end

View file

@ -1303,6 +1303,14 @@
"Description": "Umo Mobility Card", "Description": "Umo Mobility Card",
"Type": "transport" "Type": "transport"
}, },
{
"AID": "7A007A",
"Vendor": "Regional Transportation Commission of Southern Nevada (RTC) via Masabi Ltd",
"Country": "US",
"Name": "RTC TAP & GO (LAS)",
"Description": "LAS TAP & GO; Masabi Justride Tap and Ride DESFire Smartcard",
"Type": "transport"
},
{ {
"AID": "784000", "AID": "784000",
"Vendor": "Roads & Transport Authority (Government of Dubai)", "Vendor": "Roads & Transport Authority (Government of Dubai)",

View file

@ -250,7 +250,7 @@ static int CmdHF14AList(const char *Cmd) {
return CmdTraceListAlias(Cmd, "hf 14a", "14a -c"); return CmdTraceListAlias(Cmd, "hf 14a", "14a -c");
} }
int hf14a_getconfig(hf14a_config *config) { int hf14a_getconfig(hf14a_config_t *config) {
if (!g_session.pm3_present) return PM3_ENOTTY; if (!g_session.pm3_present) return PM3_ENOTTY;
if (config == NULL) { if (config == NULL) {
@ -265,16 +265,16 @@ int hf14a_getconfig(hf14a_config *config) {
PrintAndLogEx(WARNING, "command execution time out"); PrintAndLogEx(WARNING, "command execution time out");
return PM3_ETIMEOUT; return PM3_ETIMEOUT;
} }
memcpy(config, resp.data.asBytes, sizeof(hf14a_config)); memcpy(config, resp.data.asBytes, sizeof(hf14a_config_t));
return PM3_SUCCESS; return PM3_SUCCESS;
} }
int hf14a_setconfig(hf14a_config *config, bool verbose) { int hf14a_setconfig(hf14a_config_t *config, bool verbose) {
if (!g_session.pm3_present) return PM3_ENOTTY; if (!g_session.pm3_present) return PM3_ENOTTY;
clearCommandBuffer(); clearCommandBuffer();
if (config != NULL) { if (config != NULL) {
SendCommandNG(CMD_HF_ISO14443A_SET_CONFIG, (uint8_t *)config, sizeof(hf14a_config)); SendCommandNG(CMD_HF_ISO14443A_SET_CONFIG, (uint8_t *)config, sizeof(hf14a_config_t));
if (verbose) { if (verbose) {
SendCommandNG(CMD_HF_ISO14443A_PRINT_CONFIG, NULL, 0); SendCommandNG(CMD_HF_ISO14443A_PRINT_CONFIG, NULL, 0);
} }
@ -490,7 +490,7 @@ static int CmdHf14AConfig(const char *Cmd) {
} }
// Initialize config with all parameters // Initialize config with all parameters
hf14a_config config = { hf14a_config_t config = {
.forceanticol = atqa, .forceanticol = atqa,
.forcebcc = bcc, .forcebcc = bcc,
.forcecl2 = cl2, .forcecl2 = cl2,

View file

@ -20,7 +20,7 @@
#define CMDHF14A_H__ #define CMDHF14A_H__
#include "common.h" #include "common.h"
#include "pm3_cmd.h" //hf14a_config #include "pm3_cmd.h" //hf14a_config_t
#include "mifare.h" // structs #include "mifare.h" // structs
// structure and database for uid -> tagtype lookups // structure and database for uid -> tagtype lookups
@ -61,8 +61,8 @@ int CmdHF14ANdefWrite(const char *Cmd); // used by cmdnfc.c
int detect_nxp_card(uint8_t sak, uint16_t atqa, uint64_t select_status); int detect_nxp_card(uint8_t sak, uint16_t atqa, uint64_t select_status);
int hf14a_getconfig(hf14a_config *config); int hf14a_getconfig(hf14a_config_t *config);
int hf14a_setconfig(hf14a_config *config, bool verbose); int hf14a_setconfig(hf14a_config_t *config, bool verbose);
int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search); int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search);
int infoHF14A4Applications(bool verbose); int infoHF14A4Applications(bool verbose);
const char *getTagInfo(uint8_t uid); const char *getTagInfo(uint8_t uid);

View file

@ -5186,7 +5186,7 @@ static int CmdHF14AMfEKeyPrn(const char *Cmd) {
memcpy(uid, data, sizeof(uid)); memcpy(uid, data, sizeof(uid));
// download keys from EMUL // download keys from EMUL
for (int i = 0; i < sectors_cnt; i++) { for (uint8_t i = 0; i < sectors_cnt; i++) {
if (mf_eml_get_mem(data, mfFirstBlockOfSector(i) + mfNumBlocksPerSector(i) - 1, 1) != PM3_SUCCESS) { if (mf_eml_get_mem(data, mfFirstBlockOfSector(i) + mfNumBlocksPerSector(i) - 1, 1) != PM3_SUCCESS) {
PrintAndLogEx(WARNING, "error get block %d", mfFirstBlockOfSector(i) + mfNumBlocksPerSector(i) - 1); PrintAndLogEx(WARNING, "error get block %d", mfFirstBlockOfSector(i) + mfNumBlocksPerSector(i) - 1);

View file

@ -4166,17 +4166,17 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
// 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
hf14a_config config; hf14a_config_t config;
SendCommandNG(CMD_HF_ISO14443A_GET_CONFIG, NULL, 0); SendCommandNG(CMD_HF_ISO14443A_GET_CONFIG, NULL, 0);
if (WaitForResponseTimeout(CMD_HF_ISO14443A_GET_CONFIG, &resp, 2000) == false) { if (WaitForResponseTimeout(CMD_HF_ISO14443A_GET_CONFIG, &resp, 2000) == false) {
PrintAndLogEx(WARNING, "command execute timeout"); PrintAndLogEx(WARNING, "command execute timeout");
return PM3_ETIMEOUT; return PM3_ETIMEOUT;
} }
memcpy(&config, resp.data.asBytes, sizeof(hf14a_config)); memcpy(&config, resp.data.asBytes, sizeof(hf14a_config_t));
int8_t oldconfig_bcc = config.forcebcc; int8_t oldconfig_bcc = config.forcebcc;
if (oldconfig_bcc != 2) { if (oldconfig_bcc != 2) {
config.forcebcc = 2; config.forcebcc = 2;
SendCommandNG(CMD_HF_ISO14443A_SET_CONFIG, (uint8_t *)&config, sizeof(hf14a_config)); SendCommandNG(CMD_HF_ISO14443A_SET_CONFIG, (uint8_t *)&config, sizeof(hf14a_config_t));
} }
// block 0. // block 0.
@ -4219,7 +4219,7 @@ static int CmdHF14AMfUCSetUid(const char *Cmd) {
// restore BCC config // restore BCC config
if (oldconfig_bcc != 2) { if (oldconfig_bcc != 2) {
config.forcebcc = oldconfig_bcc; config.forcebcc = oldconfig_bcc;
SendCommandNG(CMD_HF_ISO14443A_SET_CONFIG, (uint8_t *)&config, sizeof(hf14a_config)); SendCommandNG(CMD_HF_ISO14443A_SET_CONFIG, (uint8_t *)&config, sizeof(hf14a_config_t));
} }
return PM3_SUCCESS; return PM3_SUCCESS;
} }

View file

@ -562,7 +562,7 @@ static int select_DF_verify(uint8_t *response, uint8_t response_length, uint8_t
} }
// ----------------- MAC Key Generation ----------------- // ----------------- MAC Key Generation -----------------
uint8_t cmac[8]; uint8_t cmac[16];
uint8_t MAC_key[24] = {0x00}; uint8_t MAC_key[24] = {0x00};
memcpy(MAC_key, keys[key_index].privMacKey, 16); memcpy(MAC_key, keys[key_index].privMacKey, 16);
create_cmac(MAC_key, input, cmac, sizeof(input), encryption_algorithm); create_cmac(MAC_key, input, cmac, sizeof(input), encryption_algorithm);
@ -1351,7 +1351,7 @@ static int CmdHfSeosGDF(const char *Cmd) {
}; };
CLIExecWithReturn(ctx, Cmd, argtable, true); CLIExecWithReturn(ctx, Cmd, argtable, true);
int key_index = arg_get_int_def(ctx, 1, -1); int key_index = arg_get_int_def(ctx, 1, 0);
CLIParserFree(ctx); CLIParserFree(ctx);
return seos_global_df(key_index); return seos_global_df(key_index);

View file

@ -252,6 +252,10 @@ endif
# WITH_FPC_USART_* needs WITH_FPC_USART : # WITH_FPC_USART_* needs WITH_FPC_USART :
ifneq (,$(findstring WITH_FPC_USART_,$(PLATFORM_DEFS))) ifneq (,$(findstring WITH_FPC_USART_,$(PLATFORM_DEFS)))
PLATFORM_DEFS += -DWITH_FPC_USART PLATFORM_DEFS += -DWITH_FPC_USART
ifeq ($(USART_BAUD_RATE),)
USART_BAUD_RATE=115200
endif
PLATFORM_DEFS += -DUSART_BAUD_RATE=$(USART_BAUD_RATE)
endif endif
PLATFORM_DEFS_INFO = $(strip $(filter-out STANDALONE%, $(subst -DWITH_,,$(PLATFORM_DEFS)))) PLATFORM_DEFS_INFO = $(strip $(filter-out STANDALONE%, $(subst -DWITH_,,$(PLATFORM_DEFS))))

View file

@ -24,6 +24,7 @@ This document targets both Proxmark3 and Flipper Zero devices.
- [Simulate a standard keyed iCLASS legacy credential](#simulate-a-standard-keyed-iclass-legacy-credential) - [Simulate a standard keyed iCLASS legacy credential](#simulate-a-standard-keyed-iclass-legacy-credential)
- [Write a downgraded iCLASS legacy credential](#write-a-downgraded-iclass-legacy-credential) - [Write a downgraded iCLASS legacy credential](#write-a-downgraded-iclass-legacy-credential)
- [Using Omnikey Reader 5427CK Gen2 and Proxmark3](#using-omnikey-reader-5427ck-gen2-and-proxmark3) - [Using Omnikey Reader 5427CK Gen2 and Proxmark3](#using-omnikey-reader-5427ck-gen2-and-proxmark3)
- [Using Elatec TWN4 or TWN4 mini (USB front reader)](#using-elatec-twn4-or-twn4-mini-usb-front-reader)
- [Using Flipper Zero with NARD](#using-flipper-zero-with-nard) - [Using Flipper Zero with NARD](#using-flipper-zero-with-nard)
- [Using Weaponized HID Reader](#using-weaponized-hid-reader) - [Using Weaponized HID Reader](#using-weaponized-hid-reader)
- [Write ProxII credential to a T5577](#write-proxii-credential-to-a-t5577) - [Write ProxII credential to a T5577](#write-proxii-credential-to-a-t5577)
@ -191,6 +192,20 @@ drop iclass-flipper.picopass file here and simulate on Flipper
7. Launch PM3 client, place iCLASS/Picopass card on HF antenna and read your original card on the Omnikey reader 7. Launch PM3 client, place iCLASS/Picopass card on HF antenna and read your original card on the Omnikey reader
8. Press enter 8. Press enter
## Using Elatec TWN4 or TWN4 mini (USB front reader)
^[Top](#top)
OBS!
The reader must have the `PI` designation on the label for it to have a embedded HID SAM. If you have a reader with a different configuration as per the label, an HID SAM will have to be installed in the SAM slot.
1. Plug in Elatec reader
2. Launch [appblaster.exe](../tools/twn/AppBlaster.exe)
3. Click on "program firmware image"
4. Select [encoder.bix](../tools/twn/encoder.bix) as the reader firmware
5. Click program image
6. Launch PM3 client, place iCLASS/Picopass card on HF antenna and read your original card on the Elatec reader
8. Press enter
## Using Flipper Zero with NARD ## Using Flipper Zero with NARD
^[Top](#top) ^[Top](#top)
@ -222,7 +237,7 @@ Prequisite, you will need the following bill of materials (BOM):
* Some 20-24 AWG wire or ethernet cable * Some 20-24 AWG wire or ethernet cable
* Your preferred power source (5-9v) * Your preferred power source (5-9v)
The easiest way is to buy a [ESPKEY](https://www.aliexpress.com/item/32850151497.html) The easiest way is to buy a [ESPKEY](https://www.aliexpress.com/w/wholesale-esp-rfid-tool.html))
Follow these steps: Follow these steps:

View file

@ -161,7 +161,7 @@ typedef struct {
int8_t forcerats; // 0:auto 1:force executing RATS 2:force skipping RATS int8_t forcerats; // 0:auto 1:force executing RATS 2:force skipping RATS
int8_t magsafe; // 0:disabled 1:enabled int8_t magsafe; // 0:disabled 1:enabled
iso14a_polling_frame_t polling_loop_annotation; // Polling loop annotation iso14a_polling_frame_t polling_loop_annotation; // Polling loop annotation
} PACKED hf14a_config; } PACKED hf14a_config_t;
// Tracelog Header struct // Tracelog Header struct
typedef struct { typedef struct {

View file

@ -16,8 +16,9 @@
#ifndef __USART_DEFS_H #ifndef __USART_DEFS_H
#define __USART_DEFS_H #define __USART_DEFS_H
//#define USART_BAUD_RATE 9600 #ifndef USART_BAUD_RATE
#define USART_BAUD_RATE 115200 #define USART_BAUD_RATE 115200
#endif
// BT HC-06 physical layer runs at 128kbps // BT HC-06 physical layer runs at 128kbps
// so it's possible to gain a little bit by using 230400 // so it's possible to gain a little bit by using 230400
// with some risk to overflow its internal buffers: // with some risk to overflow its internal buffers:

BIN
tools/twn/AppBlaster.exe Normal file

Binary file not shown.

BIN
tools/twn/decoder.bix Normal file

Binary file not shown.

BIN
tools/twn/encoder.bix Normal file

Binary file not shown.

BIN
tools/twn/pcsc.bix Normal file

Binary file not shown.