mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
Add crypto1 support to hf 14a raw
This commit is contained in:
parent
9a6f6132bc
commit
2eac5419f0
4 changed files with 63 additions and 12 deletions
|
@ -3,16 +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...
|
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]
|
||||||
- Print LUA and Python versions in `hw version` command (@jmichelp)
|
- Added crypto1 support to `hf 14a raw` (@doegox)
|
||||||
|
- Changed `hw version` command to print LUA and Python versions (@jmichelp)
|
||||||
- Updated LUA to v5.4.7 which adds utf-8 support (@jmichelp)
|
- Updated LUA to v5.4.7 which adds utf-8 support (@jmichelp)
|
||||||
- Changed `lf search` - it now tries to read and decode paxton id (@iceman1001)
|
- Changed `lf search` - it now tries to read and decode paxton id (@iceman1001)
|
||||||
- Changed `lf search` - to identify hitag2/s/82xx in chipset detection to preserve their EM4100 or other outputs (@iceman1001)
|
- Changed `lf search` - to identify hitag2/s/82xx in chipset detection to preserve their EM4100 or other outputs (@iceman1001)
|
||||||
- Added `lf hitag hts reader` - to act as a HitagS / 82xx reader (@iceman1001)
|
- Added `lf hitag hts reader` - to act as a HitagS / 82xx reader (@iceman1001)
|
||||||
- Changed `lf hitag hts write` -> ´lf hitag hts wdbl` to fit rest of client command names (@iceman1001)
|
- Changed `lf hitag hts write` -> `lf hitag hts wdbl` to fit rest of client command names (@iceman1001)
|
||||||
- Changed `lf hitag hts read` -> ´lf hitag hts rdbl` to fit rest of client command names (@iceman1001)
|
- Changed `lf hitag hts read` -> `lf hitag hts rdbl` to fit rest of client command names (@iceman1001)
|
||||||
- Changed `hf mf info` - Better handling when printing ATS (@iceman1001)
|
- Changed `hf mf info` - Better handling when printing ATS (@iceman1001)
|
||||||
- Changed to also try the MFC_B key when extracting memory (@iceman1001)
|
- Changed to also try the MFC_B key when extracting memory (@iceman1001)
|
||||||
- Fix parallel `make -j check` Thanks @elboulangero (@iceman1001)
|
- Fixed parallel `make -j check` Thanks @elboulangero (@iceman1001)
|
||||||
- Added support for 8268/8310 (@douniwan5788)
|
- Added support for 8268/8310 (@douniwan5788)
|
||||||
- Changed scripting string params to accept 1024 chars, Thanks @evildaemond! (@iceman1001)
|
- Changed scripting string params to accept 1024 chars, Thanks @evildaemond! (@iceman1001)
|
||||||
- Added detection for FM11NT021 (@iceman1001)
|
- Added detection for FM11NT021 (@iceman1001)
|
||||||
|
|
|
@ -159,6 +159,11 @@ iso14a_polling_parameters_t REQA_POLLING_PARAMETERS = {
|
||||||
// parity isn't used much
|
// parity isn't used much
|
||||||
static uint8_t parity_array[MAX_PARITY_SIZE] = {0};
|
static uint8_t parity_array[MAX_PARITY_SIZE] = {0};
|
||||||
|
|
||||||
|
// crypto1 stuff
|
||||||
|
static uint8_t crypto1_auth_state = AUTH_FIRST;
|
||||||
|
static uint32_t crypto1_uid;
|
||||||
|
struct Crypto1State crypto1_state = {0, 0};
|
||||||
|
|
||||||
void printHf14aConfig(void) {
|
void printHf14aConfig(void) {
|
||||||
DbpString(_CYAN_("HF 14a config"));
|
DbpString(_CYAN_("HF 14a config"));
|
||||||
Dbprintf(" [a] Anticol override.... %s%s%s",
|
Dbprintf(" [a] Anticol override.... %s%s%s",
|
||||||
|
@ -3151,14 +3156,14 @@ void ReaderIso14443a(PacketCommandNG *c) {
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
// notify client selecting status.
|
// notify client selecting status.
|
||||||
// if failed selecting, turn off antenna and quite.
|
// if failed selecting, turn off antenna and quit.
|
||||||
if ((param & ISO14A_NO_SELECT) != ISO14A_NO_SELECT) {
|
if ((param & ISO14A_NO_SELECT) != ISO14A_NO_SELECT) {
|
||||||
iso14a_card_select_t *card = (iso14a_card_select_t *)buf;
|
iso14a_card_select_t *card = (iso14a_card_select_t *)buf;
|
||||||
|
|
||||||
arg0 = iso14443a_select_cardEx(
|
arg0 = iso14443a_select_cardEx(
|
||||||
NULL,
|
NULL,
|
||||||
card,
|
card,
|
||||||
NULL,
|
&crypto1_uid,
|
||||||
true,
|
true,
|
||||||
0,
|
0,
|
||||||
((param & ISO14A_NO_RATS) == ISO14A_NO_RATS),
|
((param & ISO14A_NO_RATS) == ISO14A_NO_RATS),
|
||||||
|
@ -3167,6 +3172,11 @@ void ReaderIso14443a(PacketCommandNG *c) {
|
||||||
// TODO: Improve by adding a cmd parser pointer and moving it by struct length to allow combining data with polling params
|
// TODO: Improve by adding a cmd parser pointer and moving it by struct length to allow combining data with polling params
|
||||||
FpgaDisableTracing();
|
FpgaDisableTracing();
|
||||||
|
|
||||||
|
if ((param & ISO14A_CRYPTO1MODE) == ISO14A_CRYPTO1MODE) {
|
||||||
|
crypto1_auth_state = AUTH_FIRST;
|
||||||
|
crypto1_deinit(&crypto1_state);
|
||||||
|
}
|
||||||
|
|
||||||
reply_mix(CMD_ACK, arg0, card->uidlen, 0, buf, sizeof(iso14a_card_select_t));
|
reply_mix(CMD_ACK, arg0, card->uidlen, 0, buf, sizeof(iso14a_card_select_t));
|
||||||
if (arg0 == 0) {
|
if (arg0 == 0) {
|
||||||
goto OUT;
|
goto OUT;
|
||||||
|
@ -3195,7 +3205,20 @@ void ReaderIso14443a(PacketCommandNG *c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((param & ISO14A_RAW) == ISO14A_RAW) {
|
if ((param & ISO14A_RAW) == ISO14A_RAW) {
|
||||||
|
if ((param & ISO14A_CRYPTO1MODE) == ISO14A_CRYPTO1MODE) {
|
||||||
|
// Intercept special Auth command 6xxx<key>CRCA
|
||||||
|
if ((len == 10) && ((cmd[0] & 0xF0) == 0x60)) {
|
||||||
|
uint64_t ui64key = bytes_to_num((uint8_t *)&cmd[2], 6);
|
||||||
|
if (mifare_classic_authex_cmd(&crypto1_state, crypto1_uid, cmd[1], cmd[0], ui64key, crypto1_auth_state, NULL, NULL, NULL, NULL, false, false)) {
|
||||||
|
if (g_dbglevel >= DBG_INFO) Dbprintf("Auth error");
|
||||||
|
} else {
|
||||||
|
crypto1_auth_state = AUTH_NESTED;
|
||||||
|
if (g_dbglevel >= DBG_INFO) Dbprintf("Auth succeeded");
|
||||||
|
}
|
||||||
|
reply_mix(CMD_ACK, 0, 0, 0, NULL, 0);
|
||||||
|
goto CMD_DONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
if ((param & ISO14A_APPEND_CRC) == ISO14A_APPEND_CRC) {
|
if ((param & ISO14A_APPEND_CRC) == ISO14A_APPEND_CRC) {
|
||||||
// Don't append crc on empty bytearray...
|
// Don't append crc on empty bytearray...
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
|
@ -3213,7 +3236,10 @@ void ReaderIso14443a(PacketCommandNG *c) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ((param & ISO14A_CRYPTO1MODE) == ISO14A_CRYPTO1MODE) {
|
||||||
|
// Force explicit parity
|
||||||
|
lenbits = len * 8;
|
||||||
|
}
|
||||||
// want to send a specific number of bits (e.g. short commands)
|
// want to send a specific number of bits (e.g. short commands)
|
||||||
if (lenbits > 0) {
|
if (lenbits > 0) {
|
||||||
|
|
||||||
|
@ -3232,6 +3258,9 @@ void ReaderIso14443a(PacketCommandNG *c) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
GetParity(cmd, lenbits / 8, parity_array);
|
GetParity(cmd, lenbits / 8, parity_array);
|
||||||
|
if ((param & ISO14A_CRYPTO1MODE) == ISO14A_CRYPTO1MODE) {
|
||||||
|
mf_crypto1_encrypt(&crypto1_state, cmd, len, parity_array);
|
||||||
|
}
|
||||||
ReaderTransmitBitsPar(cmd, lenbits, parity_array, NULL); // bytes are 8 bit with odd parity
|
ReaderTransmitBitsPar(cmd, lenbits, parity_array, NULL); // bytes are 8 bit with odd parity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3278,12 +3307,16 @@ void ReaderIso14443a(PacketCommandNG *c) {
|
||||||
reply_mix(CMD_ACK, 0, 0, 0, NULL, 0);
|
reply_mix(CMD_ACK, 0, 0, 0, NULL, 0);
|
||||||
} else {
|
} else {
|
||||||
arg0 = ReaderReceive(buf, sizeof(buf), parity_array);
|
arg0 = ReaderReceive(buf, sizeof(buf), parity_array);
|
||||||
|
|
||||||
|
if ((param & ISO14A_CRYPTO1MODE) == ISO14A_CRYPTO1MODE) {
|
||||||
|
mf_crypto1_decrypt(&crypto1_state, buf, arg0);
|
||||||
|
}
|
||||||
FpgaDisableTracing();
|
FpgaDisableTracing();
|
||||||
reply_mix(CMD_ACK, arg0, 0, 0, buf, sizeof(buf));
|
reply_mix(CMD_ACK, arg0, 0, 0, buf, sizeof(buf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CMD_DONE:
|
||||||
if ((param & ISO14A_REQUEST_TRIGGER) == ISO14A_REQUEST_TRIGGER)
|
if ((param & ISO14A_REQUEST_TRIGGER) == ISO14A_REQUEST_TRIGGER)
|
||||||
iso14a_set_trigger(false);
|
iso14a_set_trigger(false);
|
||||||
|
|
||||||
|
@ -3296,6 +3329,7 @@ void ReaderIso14443a(PacketCommandNG *c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
OUT:
|
OUT:
|
||||||
|
crypto1_auth_state = AUTH_FIRST;
|
||||||
hf_field_off();
|
hf_field_off();
|
||||||
set_tracing(false);
|
set_tracing(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1449,7 +1449,12 @@ static int CmdHF14ACmdRaw(const char *Cmd) {
|
||||||
"Sends raw bytes over ISO14443a. With option to use TOPAZ 14a mode.",
|
"Sends raw bytes over ISO14443a. With option to use TOPAZ 14a mode.",
|
||||||
"hf 14a raw -sc 3000 -> select, crc, where 3000 == 'read block 00'\n"
|
"hf 14a raw -sc 3000 -> select, crc, where 3000 == 'read block 00'\n"
|
||||||
"hf 14a raw -ak -b 7 40 -> send 7 bit byte 0x40\n"
|
"hf 14a raw -ak -b 7 40 -> send 7 bit byte 0x40\n"
|
||||||
"hf 14a raw --ecp -s -> send ECP before select"
|
"hf 14a raw --ecp -s -> send ECP before select\n"
|
||||||
|
"Crypto1 session example, with special auth shortcut 6xxx<key>:\n"
|
||||||
|
"hf 14a raw --crypto1 -skc 6000FFFFFFFFFFFF\n"
|
||||||
|
"hf 14a raw --crypto1 -kc 3000\n"
|
||||||
|
"hf 14a raw --crypto1 -kc 6007FFFFFFFFFFFF\n"
|
||||||
|
"hf 14a raw --crypto1 -c 3007"
|
||||||
);
|
);
|
||||||
|
|
||||||
void *argtable[] = {
|
void *argtable[] = {
|
||||||
|
@ -1466,6 +1471,7 @@ static int CmdHF14ACmdRaw(const char *Cmd) {
|
||||||
arg_lit0(NULL, "ecp", "Use enhanced contactless polling"),
|
arg_lit0(NULL, "ecp", "Use enhanced contactless polling"),
|
||||||
arg_lit0(NULL, "mag", "Use Apple magsafe polling"),
|
arg_lit0(NULL, "mag", "Use Apple magsafe polling"),
|
||||||
arg_lit0(NULL, "topaz", "Use Topaz protocol to send command"),
|
arg_lit0(NULL, "topaz", "Use Topaz protocol to send command"),
|
||||||
|
arg_lit0(NULL, "crypto1", "Use crypto1 session"),
|
||||||
arg_strx1(NULL, NULL, "<hex>", "Raw bytes to send"),
|
arg_strx1(NULL, NULL, "<hex>", "Raw bytes to send"),
|
||||||
arg_param_end
|
arg_param_end
|
||||||
};
|
};
|
||||||
|
@ -1483,10 +1489,11 @@ static int CmdHF14ACmdRaw(const char *Cmd) {
|
||||||
bool use_ecp = arg_get_lit(ctx, 10);
|
bool use_ecp = arg_get_lit(ctx, 10);
|
||||||
bool use_magsafe = arg_get_lit(ctx, 11);
|
bool use_magsafe = arg_get_lit(ctx, 11);
|
||||||
bool topazmode = arg_get_lit(ctx, 12);
|
bool topazmode = arg_get_lit(ctx, 12);
|
||||||
|
bool crypto1mode = arg_get_lit(ctx, 13);
|
||||||
|
|
||||||
int datalen = 0;
|
int datalen = 0;
|
||||||
uint8_t data[PM3_CMD_DATA_SIZE_MIX] = {0};
|
uint8_t data[PM3_CMD_DATA_SIZE_MIX] = {0};
|
||||||
CLIGetHexWithReturn(ctx, 13, data, &datalen);
|
CLIGetHexWithReturn(ctx, 14, data, &datalen);
|
||||||
CLIParserFree(ctx);
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
bool bTimeout = (timeout) ? true : false;
|
bool bTimeout = (timeout) ? true : false;
|
||||||
|
@ -1540,6 +1547,14 @@ static int CmdHF14ACmdRaw(const char *Cmd) {
|
||||||
flags |= ISO14A_TOPAZMODE;
|
flags |= ISO14A_TOPAZMODE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (crypto1mode) {
|
||||||
|
flags |= ISO14A_CRYPTO1MODE;
|
||||||
|
if (numbits > 0 || topazmode || use_ecp || use_magsafe) {
|
||||||
|
PrintAndLogEx(FAILED, "crypto1 mode cannot be used with other modes or partial bytes");
|
||||||
|
return PM3_EINVARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (no_rats) {
|
if (no_rats) {
|
||||||
flags |= ISO14A_NO_RATS;
|
flags |= ISO14A_NO_RATS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,7 +99,8 @@ typedef enum ISO14A_COMMAND {
|
||||||
ISO14A_SEND_CHAINING = (1 << 10),
|
ISO14A_SEND_CHAINING = (1 << 10),
|
||||||
ISO14A_USE_ECP = (1 << 11),
|
ISO14A_USE_ECP = (1 << 11),
|
||||||
ISO14A_USE_MAGSAFE = (1 << 12),
|
ISO14A_USE_MAGSAFE = (1 << 12),
|
||||||
ISO14A_USE_CUSTOM_POLLING = (1 << 13)
|
ISO14A_USE_CUSTOM_POLLING = (1 << 13),
|
||||||
|
ISO14A_CRYPTO1MODE = (1 << 14)
|
||||||
} iso14a_command_t;
|
} iso14a_command_t;
|
||||||
|
|
||||||
// Defines a frame that will be used in a polling sequence
|
// Defines a frame that will be used in a polling sequence
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue