gave 14b commands some serious love and overhaul. package handling for APDU and different selects is improved. return codes now consequent

This commit is contained in:
iceman1001
2024-01-08 21:17:42 +01:00
parent 5709d8959d
commit 82aa6ac08c
11 changed files with 350 additions and 337 deletions
+1 -1
View File
@@ -1429,7 +1429,7 @@ static void PacketReceived(PacketCommandNG *packet) {
uint8_t blockno;
} PACKED;
struct p *payload = (struct p *) packet->data.asBytes;
ReadSTBlock(payload->blockno);
read_14b_st_block(payload->blockno);
break;
}
case CMD_HF_ISO14443B_SNIFF: {
+1 -1
View File
@@ -155,7 +155,7 @@ static int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response, uint16_t re
#endif
case 'b':
#ifdef WITH_ISO14443b
return iso14443b_apdu(apdu, length, false, response, respmaxlen, NULL);
return iso14443b_apdu(apdu, length, false, response, respmaxlen, NULL, NULL);
#else
(void) apdu;
(void) length;
+145 -122
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -35,13 +35,13 @@
#endif
void iso14443b_setup(void);
int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void *rxdata, uint16_t rxmaxlen, uint8_t *res);
int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void *rxdata, uint16_t rxmaxlen, uint8_t *res, int * responselen);
int iso14443b_select_card(iso14b_card_select_t *card);
void SimulateIso14443bTag(const uint8_t *pupi);
void AcquireRawAdcSamplesIso14443b(uint32_t parameter);
void ReadSTBlock(uint8_t blocknr);
void read_14b_st_block(uint8_t blocknr);
void SniffIso14443b(void);
void SendRawCommand14443B(uint32_t, uint32_t, uint8_t, uint8_t[]);
void SendRawCommand14443B_Ex(iso14b_raw_cmd_t *p);
+8 -7
View File
@@ -29,6 +29,9 @@ Check there for details about data format and how commands are interpreted on th
device-side.
]]
local PM3_SUCCESS = 0
-- iceman, todo: return payload from ISO14b APDU is a struct now. iso14b_raw_apdu_response_t
local function calypso_parse(result)
if result.Oldarg0 >= 0 then
local len = result.Oldarg0 * 2
@@ -112,9 +115,7 @@ end
local function calypso_send_cmd_raw(data, ignoreresponse )
local flags = lib14b.ISO14B_COMMAND.ISO14B_APDU
-- flags = lib14b.ISO14B_COMMAND.ISO14B_RAW +
-- lib14b.ISO14B_COMMAND.ISO14B_APPEND_CRC
local flags = lib14b.ISO14B_COMMAND.ISO14B_APDU
data = data or ""
-- LEN of data, half the length of the ASCII-string hex string
-- 2 bytes flags
@@ -129,7 +130,7 @@ local function calypso_send_cmd_raw(data, ignoreresponse )
local c = Command:newNG{cmd = cmds.CMD_HF_ISO14443B_COMMAND, data = senddata}
local result, err = c:sendNG(ignoreresponse, 2000)
if result then
if result.Oldarg0 >= 0 then
if result.status == PM3_SUCCESS then
return calypso_parse(result)
else
err = 'card response failed'
@@ -144,7 +145,7 @@ end
-- writes it in the tree in decimal format.
local function calypso_card_num(card)
if not card then return end
local card_num = tonumber( card.uid:sub(1,8),16 )
local card_num = tonumber( card.uid:sub(1, 8), 16)
print('')
print('Card UID ' ..ansicolors.green..card.uid:format('%x')..ansicolors.reset)
print('Card Number ' ..ansicolors.green..string.format('%u', card_num)..ansicolors.reset)
@@ -156,7 +157,7 @@ local function calypso_apdu_status(apdu)
-- last two is CRC
-- next two is APDU status bytes.
local mess = 'FAIL'
local sw = apdu:sub( #apdu-7, #apdu-4)
local sw = apdu:sub( #apdu - 7 , #apdu - 4)
desc, err = iso7816.tostring(sw)
--print ('SW', sw, desc, err )
local status = ( sw == '9000' )
@@ -250,7 +251,7 @@ function main(args)
for i, apdu in spairs(_calypso_cmds) do
print('>> '..ansicolors.yellow..i..ansicolors.reset)
apdu = apdu:gsub('%s+', '')
data, err = calypso_send_cmd_raw(apdu , false)
data, err = calypso_send_cmd_raw(apdu, false)
if err then
print('<< '..err)
else
+2 -1
View File
@@ -30,6 +30,7 @@ Check there for details about data format and how commands are interpreted on th
device-side.
]]
-- iceman, todo: return payload from ISO14b APDU is a struct now. iso14b_raw_apdu_response_t
local function mobib_parse(result)
if result.Oldarg0 >= 0 then
local len = result.Oldarg0 * 2
@@ -126,7 +127,7 @@ local function mobib_send_cmd_raw(data, ignoreresponse )
local result, err = c:sendNG(ignoreresponse, 2000)
if result then
if result.Oldarg0 >= 0 then
if result.status == PM3_SUCCESS then
return mobib_parse(result)
else
err = 'card response failed'
+148 -169
View File
File diff suppressed because it is too large Load Diff
+21 -25
View File
@@ -116,15 +116,16 @@ static bool get_14b_UID(iso14b_card_select_t *card) {
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t *)&packet, sizeof(iso14b_raw_cmd_t));
PacketResponseNG resp;
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) {
if (resp.oldarg[0] == 0) {
if (resp.status == PM3_SUCCESS) {
memcpy(card, (iso14b_card_select_t *)resp.data.asBytes, sizeof(iso14b_card_select_t));
return true;
}
}
} // retry
if (retry <= 0)
if (retry <= 0) {
PrintAndLogEx(FAILED, "command execution timeout");
}
return false;
}
@@ -148,22 +149,20 @@ static int infoHFCryptoRF(bool verbose) {
return false;
}
iso14b_card_select_t card;
memcpy(&card, (iso14b_card_select_t *)resp.data.asBytes, sizeof(iso14b_card_select_t));
uint64_t status = resp.oldarg[0];
switch (status) {
case 0:
switch (resp.status) {
case PM3_SUCCESS: {
iso14b_card_select_t card;
memcpy(&card, (iso14b_card_select_t *)resp.data.asBytes, sizeof(iso14b_card_select_t));
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(SUCCESS, " UID : %s", sprint_hex(card.uid, card.uidlen));
PrintAndLogEx(SUCCESS, " ATQB : %s", sprint_hex(card.atqb, sizeof(card.atqb)));
PrintAndLogEx(SUCCESS, " CHIPID : %02X", card.chipid);
return PM3_SUCCESS;
case 2:
}
case PM3_ELENGTH:
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 ATTRIB fail");
break;
case 3:
case PM3_ECRC:
if (verbose) PrintAndLogEx(FAILED, "ISO 14443-3 CRC fail");
break;
default:
@@ -209,16 +208,16 @@ int readHFCryptoRF(bool loop, bool verbose) {
PacketResponseNG resp;
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
uint8_t status = resp.oldarg[0] & 0xFF;
if (loop) {
if (status != 0) {
if (resp.status != PM3_SUCCESS) {
continue;
}
} else {
// when not in continuous mode
if (status != 0) {
if (verbose) PrintAndLogEx(WARNING, "cryptoRF / ISO14443-b card select failed");
if (resp.status != PM3_SUCCESS) {
if (verbose) {
PrintAndLogEx(WARNING, "cryptoRF / ISO14443-b card select failed");
}
res = PM3_EOPABORTED;
break;
}
@@ -322,11 +321,9 @@ static int CmdHFCryptoRFDump(const char *Cmd) {
PacketResponseNG resp;
// select
int status;
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2000)) {
status = resp.oldarg[0];
if (status < 0) {
PrintAndLogEx(FAILED, "failed to select %" PRId64 "]", resp.oldarg[0]);
if (resp.status != PM3_SUCCESS) {
PrintAndLogEx(FAILED, "failed to select %" PRId64 "]", resp.status);
free(packet);
return switch_off_field_cryptorf();
}
@@ -350,13 +347,12 @@ static int CmdHFCryptoRFDump(const char *Cmd) {
SendCommandNG(CMD_HF_ISO14443B_COMMAND, (uint8_t *)&packet, sizeof(iso14b_raw_cmd_t) + 2);
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, 2000)) {
status = resp.oldarg[0];
if (status < 0) {
if (resp.status != PM3_SUCCESS) {
PrintAndLogEx(FAILED, "retrying one more time");
continue;
}
uint16_t len = (resp.oldarg[1] & 0xFFFF);
uint16_t len = resp.length;
uint8_t *recv = resp.data.asBytes;
if (check_crc(CRC_14443_B, recv, len) == false) {
@@ -446,7 +442,7 @@ static int CmdHFCryptoRFELoad(const char *Cmd) {
size_t datalen = CRYPTORF_MEM_SIZE;
// set up buffer
uint8_t *data = calloc(datalen, sizeof(uint8_t));
if (!data) {
if (data == NULL) {
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
return PM3_EMALLOC;
}
@@ -477,7 +473,7 @@ static int CmdHFCryptoRFELoad(const char *Cmd) {
}
*/
free(data);
PrintAndLogEx(SUCCESS, "sent %d bytes of data to device emulator memory", bytes_sent);
PrintAndLogEx(SUCCESS, "sent " _YELLOW_("%d") " bytes of data to device emulator memory", bytes_sent);
return PM3_SUCCESS;
}
+14 -9
View File
@@ -383,8 +383,9 @@ static int switch_off_field(void) {
static int findXerox(iso14b_card_select_t *card, bool disconnect) {
if (card == NULL)
if (card == NULL) {
return PM3_EINVARG;
}
int8_t retry = 3;
while (retry--) {
@@ -399,10 +400,10 @@ static int findXerox(iso14b_card_select_t *card, bool disconnect) {
PacketResponseNG resp;
if (WaitForResponseTimeout(CMD_HF_ISO14443B_COMMAND, &resp, TIMEOUT)) {
if (resp.oldarg[0] == 0) {
if (resp.status == PM3_SUCCESS) {
memcpy(card, (iso14b_card_select_t *)resp.data.asBytes, sizeof(iso14b_card_select_t));
}
return resp.oldarg[0];
return resp.length;
}
} // retry
@@ -513,7 +514,7 @@ static int CmdHFXeroxInfo(const char *Cmd) {
if (verbose) {
PrintAndLogEx(FAILED, "Fuji/Xerox tag select failed");
}
return PM3_ERFTRANS;
return status;
}
PrintAndLogEx(NORMAL, "");
@@ -551,7 +552,7 @@ static int CmdHFXeroxInfo(const char *Cmd) {
*/
// 14b raw command send data_len instead of status
if (/*resp.status != 0 ||*/ resp.length < 7) {
if (resp.length < 7) {
PrintAndLogEx(FAILED, "retrying one more time");
continue;
}
@@ -655,7 +656,8 @@ static int CmdHFXeroxDump(const char *Cmd) {
resp.cmd, resp.length, resp.magic, resp.status, resp.crc, resp.oldarg[0], resp.oldarg[1], resp.oldarg[2],
resp.data.asBytes[0], resp.data.asBytes[1], resp.data.asBytes[2], resp.ng ? 't' : 'f');
*/
if (/*resp.status != 0 ||*/ resp.length < 7) { // 14b raw command send data_len instead of status
if (resp.length < 7) {
PrintAndLogEx(FAILED, "retrying one more time");
continue;
}
@@ -689,8 +691,9 @@ static int CmdHFXeroxDump(const char *Cmd) {
PrintAndLogEx(NORMAL, "");
if (blocknum != 0x100)
if (blocknum != 0x100) {
PrintAndLogEx(FAILED, "dump failed at block %d", blocknum);
}
if (decrypt) {
PrintAndLogEx(INFO, "Decrypting secret blocks...");
@@ -744,12 +747,14 @@ static int CmdHFXeroxDump(const char *Cmd) {
uint16_t cs, csd;
// calc checksum
for (b = 0, cs = 0; b < sizeof(decr) - 2; b += 2) cs += decr[b] | (decr[b + 1] << 8);
for (b = 0, cs = 0; b < sizeof(decr) - 2; b += 2) {
cs += decr[b] | (decr[b + 1] << 8);
}
cs = ~cs;
csd = (decr[7] << 8) | decr[6];
if (cs != csd) {
PrintAndLogEx(FAILED, "secret block %02X checksum failed.", dadr);
PrintAndLogEx(FAILED, "Secret block %02X checksum " _RED_("failed"), dadr);
}
}
}
+5
View File
@@ -64,6 +64,11 @@ typedef struct {
uint8_t raw[];
} PACKED iso14b_raw_cmd_t;
typedef struct {
uint8_t response_byte;
uint16_t datalen;
uint8_t data[];
} PACKED iso14b_raw_apdu_response_t;
#define US_TO_SSP(x) ( (int32_t) ((x) * 3.39) )
#define SSP_TO_US(x) ( (int32_t)((x) / 3.39) )
+3
View File
@@ -820,6 +820,9 @@ typedef struct {
// No PACS data pm3: when using HID SAM to retried PACS data
#define PM3_ENOPACS -26
// Got wrong length error pm3: when received wrong length of data
#define PM3_ELENGTH -27
// No data pm3: no data available, no host frame available (not really an error)
#define PM3_ENODATA -98
// Quit program client: reserved, order to quit the program