Iso7816Exchange: avoid sending systematically typeA APDUs firstly on typeB tags

This commit is contained in:
Philippe Teuwen 2021-05-30 22:31:56 +02:00
commit 56daa155b5
7 changed files with 44 additions and 6 deletions

View file

@ -42,6 +42,7 @@ bool apdu_in_framing_enable = true;
static int CmdHelp(const char *Cmd);
static int switch_off_field_14b(void) {
SetISODEPState(ISODEP_INACTIVE);
iso14b_raw_cmd_t packet = {
.flags = ISO14B_DISCONNECT,
.timeout = 0,

View file

@ -17,7 +17,6 @@
#include "comms.h" // clearCommandBuffer
#include "cmdtrace.h"
#include "crc16.h"
#include "cmdhf14a.h"
#include "protocols.h" // definitions of ISO14B protocol
#include "iso14b.h"
#include "cliparser.h" // cliparsing
@ -36,6 +35,7 @@ static void set_last_known_card(iso14b_card_select_t card) {
}
static int switch_off_field_cryptorf(void) {
SetISODEPState(ISODEP_INACTIVE);
iso14b_raw_cmd_t packet = {
.flags = ISO14B_DISCONNECT,
.timeout = 0,

View file

@ -94,6 +94,7 @@ static const char *get_page_name(uint16_t pageid) {
static int CmdHelp(const char *Cmd);
static void lto_switch_off_field(void) {
SetISODEPState(ISODEP_INACTIVE);
SendCommandMIX(CMD_HF_ISO14443A_READER, 0, 0, 0, NULL, 0);
}

View file

@ -49,6 +49,7 @@ static void topaz_switch_on_field(void) {
}
static void topaz_switch_off_field(void) {
SetISODEPState(ISODEP_INACTIVE);
SendCommandMIX(CMD_HF_ISO14443A_READER, 0, 0, 0, NULL, 0);
}

View file

@ -15,13 +15,14 @@
#include "common.h"
#include "pm3_cmd.h" // Packet structs
#include "util.h" // FILE_PATH_SIZE
#include "iso7816/iso7816core.h" // SetISODEPState
#ifdef __cplusplus
extern "C" {
#endif
#ifndef DropField
#define DropField() { clearCommandBuffer(); SendCommandNG(CMD_HF_DROPFIELD, NULL, 0); }
#define DropField() { clearCommandBuffer(); SetISODEPState(ISODEP_INACTIVE); SendCommandNG(CMD_HF_DROPFIELD, NULL, 0); }
#endif
#ifndef DropFieldEx

View file

@ -31,6 +31,16 @@ bool GetAPDULogging(void) {
return APDULogging;
}
static isodep_state_t isodep_state = ISODEP_INACTIVE;
void SetISODEPState(isodep_state_t state) {
isodep_state = state;
}
isodep_state_t GetISODEPState(void) {
return isodep_state;
}
int Iso7816ExchangeEx(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFieldON, sAPDU apdu, bool IncludeLe, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw) {
uint8_t data[APDU_RES_LEN] = {0};
@ -56,10 +66,25 @@ int Iso7816ExchangeEx(Iso7816CommandChannel channel, bool ActivateField, bool Le
switch (channel) {
case CC_CONTACTLESS:
switch (GetISODEPState()) {
case ISODEP_NFCA:
res = ExchangeAPDU14a(data, datalen, ActivateField, LeaveFieldON, Result, (int)MaxResultLen, (int *)ResultLen);
break;
case ISODEP_NFCB:
res = exchange_14b_apdu(data, datalen, ActivateField, LeaveFieldON, Result, (int)MaxResultLen, (int *)ResultLen, 4000);
break;
case ISODEP_INACTIVE:
if (! ActivateField) {
PrintAndLogEx(FAILED, "Field currently inactive, cannot send an APDU");
return PM3_EIO;
}
res = ExchangeAPDU14a(data, datalen, ActivateField, LeaveFieldON, Result, (int)MaxResultLen, (int *)ResultLen);
if (res != PM3_SUCCESS) {
res = exchange_14b_apdu(data, datalen, ActivateField, LeaveFieldON, Result, (int)MaxResultLen, (int *)ResultLen, 4000);
if (res != PM3_SUCCESS)
}
break;
}
if (res != PM3_SUCCESS) {
return res;
}
break;

View file

@ -20,6 +20,12 @@
#define APDU_RES_LEN 260
#define APDU_AID_LEN 50
typedef enum {
ISODEP_INACTIVE = 0,
ISODEP_NFCA,
ISODEP_NFCB,
} isodep_state_t;
typedef enum {
CC_CONTACTLESS,
CC_CONTACT
@ -28,6 +34,9 @@ typedef enum {
void SetAPDULogging(bool logging);
bool GetAPDULogging(void);
void SetISODEPState(isodep_state_t state);
isodep_state_t GetISODEPState(void);
// exchange
int Iso7816Exchange(Iso7816CommandChannel channel, bool LeaveFieldON, sAPDU apdu, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);
int Iso7816ExchangeEx(Iso7816CommandChannel channel, bool ActivateField, bool LeaveFieldON, sAPDU apdu, bool IncludeLe, uint8_t *Result, size_t MaxResultLen, size_t *ResultLen, uint16_t *sw);