mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2026-05-12 11:18:11 -07:00
Merge branch 'RfidResearchGroup:master' into master
This commit is contained in:
@@ -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...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Added `-t` / `--timeout` option for `hf 15 sim` (@recursivenomad)
|
||||
- Added `--aid` parameter to `hf seos` commands (@kormax)
|
||||
- Added `hf iclass blacktears` command to perform an automated tearoff of block 1 to set non-secure page mode(@antiklesys)
|
||||
- Changed wiegand encoding to use shared helpers and have unified parameters (--raw, --bin, --new, --wiegand, etc.) (@cindersocket)
|
||||
|
||||
+12
-9
@@ -1643,7 +1643,11 @@ void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len, uint32_t *start_
|
||||
*/
|
||||
int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void *rxdata, uint16_t rxmaxlen, uint8_t *response_byte, uint16_t *responselen) {
|
||||
|
||||
uint8_t real_cmd[msg_len + 4];
|
||||
if (msg_len > PM3_CMD_DATA_SIZE) {
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
uint8_t real_cmd[PM3_CMD_DATA_SIZE + 4];
|
||||
|
||||
if (msg_len) {
|
||||
// ISO 14443 APDU frame: PCB [CID] [NAD] APDU CRC PCB=0x02
|
||||
@@ -3096,8 +3100,10 @@ void SendRawCommand14443B(iso14b_raw_cmd_t *p) {
|
||||
|
||||
set_tracing(true);
|
||||
|
||||
// receive buffer
|
||||
uint8_t buf[PM3_CMD_DATA_SIZE] = {0x00};
|
||||
// receive buffer — sized for APDU response header + max payload, reused for all paths
|
||||
uint8_t buf[sizeof(iso14b_raw_apdu_response_t) + PM3_CMD_DATA_SIZE];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
iso14b_raw_apdu_response_t *payload = (iso14b_raw_apdu_response_t *)buf;
|
||||
|
||||
int status = 0;
|
||||
uint32_t sendlen = sizeof(iso14b_card_select_t);
|
||||
@@ -3159,17 +3165,14 @@ void SendRawCommand14443B(iso14b_raw_cmd_t *p) {
|
||||
uint16_t responselen = 0;
|
||||
uint8_t response_byte = 0;
|
||||
bool chaining = ((p->flags & ISO14B_SEND_CHAINING) == ISO14B_SEND_CHAINING);
|
||||
status = iso14443b_apdu(p->raw, p->rawlen, chaining, buf, sizeof(buf), &response_byte, &responselen);
|
||||
status = iso14443b_apdu(p->raw, p->rawlen, chaining, payload->data, PM3_CMD_DATA_SIZE, &response_byte, &responselen);
|
||||
|
||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
|
||||
reply_ng(CMD_HF_ISO14443B_COMMAND, PM3_ETEAROFF, NULL, 0);
|
||||
} else {
|
||||
uint8_t packet[responselen + 1 + 2];
|
||||
iso14b_raw_apdu_response_t *payload = (iso14b_raw_apdu_response_t *)packet;
|
||||
payload->response_byte = response_byte;
|
||||
payload->datalen = responselen;
|
||||
memcpy(payload->data, buf, payload->datalen);
|
||||
reply_ng(CMD_HF_ISO14443B_COMMAND, status, packet, sizeof(packet));
|
||||
reply_ng(CMD_HF_ISO14443B_COMMAND, status, buf, sizeof(iso14b_raw_apdu_response_t) + responselen);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3198,7 +3201,7 @@ void SendRawCommand14443B(iso14b_raw_cmd_t *p) {
|
||||
eof_time += DELAY_ISO14443B_PCD_TO_PICC_READER;
|
||||
|
||||
uint16_t retlen = 0;
|
||||
status = Get14443bAnswerFromTag(buf, sizeof(buf), s_iso14b_timeout, &eof_time, &retlen);
|
||||
status = Get14443bAnswerFromTag(buf, PM3_CMD_DATA_SIZE, s_iso14b_timeout, &eof_time, &retlen);
|
||||
if (status == PM3_SUCCESS) {
|
||||
sendlen = MIN(retlen, PM3_CMD_DATA_SIZE);
|
||||
reply_ng(CMD_HF_ISO14443B_COMMAND, status, Demod.output, sendlen);
|
||||
|
||||
+16
-3
@@ -86,7 +86,11 @@ uint8_t mf_crypto1_encrypt4bit(struct Crypto1State *pcs, uint8_t data) {
|
||||
// send X byte basic commands
|
||||
uint16_t mifare_sendcmd(uint8_t cmd, uint8_t *data, uint8_t data_size, uint8_t *answer, uint16_t answer_len, uint8_t *answer_parity, uint32_t *timing) {
|
||||
|
||||
uint8_t dcmd[data_size + 3];
|
||||
if (data_size > 32) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t dcmd[32 + 3];
|
||||
dcmd[0] = cmd;
|
||||
if (data_size > 0) {
|
||||
memcpy(dcmd + 1, data, data_size);
|
||||
@@ -99,8 +103,9 @@ uint16_t mifare_sendcmd(uint8_t cmd, uint8_t *data, uint8_t data_size, uint8_t *
|
||||
}
|
||||
uint16_t len = ReaderReceive(answer, answer_len, answer_parity);
|
||||
if (len == 0) {
|
||||
if (g_dbglevel >= DBG_ERROR)
|
||||
if (g_dbglevel >= DBG_ERROR) {
|
||||
Dbprintf("%02X Cmd failed. Card timeout.", cmd);
|
||||
}
|
||||
len = ReaderReceive(answer, answer_len, answer_parity);
|
||||
}
|
||||
return len;
|
||||
@@ -109,7 +114,11 @@ uint16_t mifare_sendcmd(uint8_t cmd, uint8_t *data, uint8_t data_size, uint8_t *
|
||||
// send X byte basic commands secure channel (UL AES)
|
||||
uint16_t mifare_sendcmd_schann(uint8_t *data, uint8_t data_size, uint8_t *answer, uint16_t answer_len, uint8_t *answer_parity, uint32_t *timing) {
|
||||
|
||||
uint8_t dcmd[data_size + 2];
|
||||
if (data_size > 16) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t dcmd[16 + 2];
|
||||
memset(dcmd, 0, sizeof(dcmd));
|
||||
|
||||
if (data_size > 0) {
|
||||
@@ -149,6 +158,7 @@ uint16_t mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t
|
||||
} else {
|
||||
ReaderTransmit(dcmd, sizeof(dcmd), timing);
|
||||
}
|
||||
|
||||
if (tearoff_hook() == PM3_ETEAROFF) { // tearoff occurred
|
||||
return 0;
|
||||
}
|
||||
@@ -160,6 +170,7 @@ uint16_t mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t
|
||||
}
|
||||
|
||||
if (pcs && (crypted == CRYPT_ALL)) {
|
||||
|
||||
if (len == 1) {
|
||||
uint16_t res = 0;
|
||||
res |= (crypto1_bit(pcs, 0, 0) ^ BIT(answer[0], 0)) << 0;
|
||||
@@ -167,7 +178,9 @@ uint16_t mifare_sendcmd_short(struct Crypto1State *pcs, uint8_t crypted, uint8_t
|
||||
res |= (crypto1_bit(pcs, 0, 0) ^ BIT(answer[0], 2)) << 2;
|
||||
res |= (crypto1_bit(pcs, 0, 0) ^ BIT(answer[0], 3)) << 3;
|
||||
answer[0] = res;
|
||||
|
||||
} else {
|
||||
|
||||
for (pos = 0; pos < len; pos++) {
|
||||
answer[pos] = crypto1_byte(pcs, 0x00, 0) ^ answer[pos];
|
||||
}
|
||||
|
||||
@@ -795,6 +795,11 @@ void SimulateSeos(seos_emulate_req_t *msg) {
|
||||
}
|
||||
|
||||
uint8_t cmac_size = recvd_cmac_length;
|
||||
if (cmac_size > 16) {
|
||||
Dbprintf(_RED_("Get Data failed") ": CMAC size invalid.");
|
||||
break;
|
||||
}
|
||||
|
||||
if (!generate_cmac(diver_cmac_key, mac_input, mac_input_idx, cmac, msg->encr_alg)) {
|
||||
Dbprintf(_RED_("Get Data failed") ": Failed to create reply CMAC.");
|
||||
break;
|
||||
|
||||
@@ -1489,6 +1489,7 @@ static int CmdHF15Sim(const char *Cmd) {
|
||||
arg_param_begin,
|
||||
arg_str0("u", "uid", "<hex>", "UID, 8 hex bytes"),
|
||||
arg_int0("b", "blocksize", "<dec>", "block size (def 4)"),
|
||||
arg_int0("t", "timeout", "<dec>", "timeout in ms (def -1, ie. until button press)"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
@@ -1502,6 +1503,7 @@ static int CmdHF15Sim(const char *Cmd) {
|
||||
int uidlen = 0;
|
||||
CLIGetHexWithReturn(ctx, 1, payload.uid, &uidlen);
|
||||
payload.block_size = arg_get_int_def(ctx, 2, 4);
|
||||
size_t timeout = arg_get_int_def(ctx, 3, -1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
// sanity checks
|
||||
@@ -1541,7 +1543,10 @@ static int CmdHF15Sim(const char *Cmd) {
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_HF_ISO15693_SIMULATE, (uint8_t *)&payload, sizeof(payload));
|
||||
WaitForResponse(CMD_HF_ISO15693_SIMULATE, &resp);
|
||||
WaitForResponseTimeout(CMD_HF_ISO15693_SIMULATE, &resp, timeout);
|
||||
if (timeout != (size_t) - 1) {
|
||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||
}
|
||||
PrintAndLogEx(INFO, "Done!");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user