Move custom polling frame generation logic to client

This commit is contained in:
kormax 2023-07-16 17:39:32 +03:00
commit a9cba02514
5 changed files with 102 additions and 86 deletions

View file

@ -145,61 +145,16 @@ static hf14a_config hf14aconfig = { 0, 0, 0, 0, 0 } ;
// Polling frames and configurations
/*static iso14a_polling_frame REQA_FRAME = {
{ 0x26 }, 1, 7, 0
};*/
static const iso14a_polling_frame WUPA_FRAME = {
{ 0x52 }, 1, 7, 0,
};
static const iso14a_polling_frame MAGWUPA1_FRAME = {
{ 0x7A }, 1, 7, 0
};
static const iso14a_polling_frame MAGWUPA2_FRAME = {
{ 0x7B }, 1, 7, 0
};
static const iso14a_polling_frame MAGWUPA3_FRAME = {
{ 0x7C }, 1, 7, 0
};
static const iso14a_polling_frame MAGWUPA4_FRAME = {
{ 0x7D }, 1, 7, 0
};
static const iso14a_polling_frame ECP_FRAME = {
.frame={ 0x6a, 0x02, 0xC8, 0x01, 0x00, 0x03, 0x00, 0x02, 0x79, 0x00, 0x00, 0x00, 0x00, 0xC2, 0xD8},
.frame_length=15,
.last_byte_bits=8,
.extra_delay=0
};
static iso14a_polling_parameters WUPA_POLLING_PARAMETERS = {
.frames={ WUPA_FRAME },
.frame_count=1,
.extra_timeout=0,
};
static iso14a_polling_parameters MAGSAFE_POLLING_PARAMETERS = {
.frames={ WUPA_FRAME, MAGWUPA1_FRAME, MAGWUPA2_FRAME, MAGWUPA3_FRAME, MAGWUPA4_FRAME },
.frame_count=5,
.extra_timeout=0
};
// Extra 100ms give enough time for Apple devices to proccess field info and make a decision
static iso14a_polling_parameters ECP_POLLING_PARAMETERS = {
.frames={ WUPA_FRAME, ECP_FRAME },
.frame_count=2,
.extra_timeout=100
};
static iso14a_polling_parameters FULL_POLLING_PARAMETERS = {
.frames={ WUPA_FRAME, ECP_FRAME, MAGWUPA1_FRAME, MAGWUPA2_FRAME, MAGWUPA3_FRAME, MAGWUPA4_FRAME },
.frame_count=6,
.extra_timeout=100
};
void printHf14aConfig(void) {
@ -2619,18 +2574,6 @@ int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32
}
// This method is temporary. Main intention is to move "special" polling frame configuration to the client
iso14a_polling_parameters iso14a_get_polling_parameters(bool use_ecp, bool use_magsafe) {
if (use_ecp && use_magsafe) {
return FULL_POLLING_PARAMETERS;
} else if (use_ecp) {
return ECP_POLLING_PARAMETERS;
} else if (use_magsafe) {
return MAGSAFE_POLLING_PARAMETERS;
}
return WUPA_POLLING_PARAMETERS;
}
// performs iso14443a anticollision (optional) and card select procedure
// fills the uid and cuid pointer unless NULL
// fills the card info record unless NULL
@ -3088,8 +3031,12 @@ void ReaderIso14443a(PacketCommandNG *c) {
// if failed selecting, turn off antenna and quite.
if (!(param & ISO14A_NO_SELECT)) {
iso14a_card_select_t *card = (iso14a_card_select_t *)buf;
iso14a_polling_parameters polling_parameters = iso14a_get_polling_parameters(param & ISO14A_USE_ECP, param & ISO14A_USE_MAGSAFE);
arg0 = iso14443a_select_cardEx(NULL, card, NULL, true, 0, (param & ISO14A_NO_RATS), &polling_parameters);
arg0 = iso14443a_select_cardEx(
NULL, card, NULL, true, 0, (param & ISO14A_NO_RATS),
(param & ISO14A_USE_CUSTOM_POLLING) ? (iso14a_polling_parameters *)cmd : &WUPA_POLLING_PARAMETER
);
// This can be improved by adding a cmd parser pointer and moving it by struct length to allow combining data with polling params
FpgaDisableTracing();
reply_mix(CMD_ACK, arg0, card->uidlen, 0, buf, sizeof(iso14a_card_select_t));

View file

@ -108,24 +108,6 @@ typedef enum {
RESP_INDEX_PACK,
} resp_index_t;
// Defines a frame that will be used in a polling sequence
// ECP Frames are up to (7 + 16) bytes long, 24 bytes should cover future and other cases
typedef struct {
uint8_t frame[24];
uint8_t frame_length;
uint8_t last_byte_bits;
uint16_t extra_delay;
} iso14a_polling_frame;
// Defines polling sequence configuration
// 6 would be enough for 4 magsafe, 1 wupa, 1 ecp,
typedef struct {
iso14a_polling_frame frames[6];
uint8_t frame_count;
uint16_t extra_timeout;
} iso14a_polling_parameters;
#ifndef AddCrc14A
# define AddCrc14A(data, len) compute_crc(CRC_14443_A, (data), (len), (data)+(len), (data)+(len)+1)
#endif
@ -166,7 +148,6 @@ void ReaderTransmitBitsPar(uint8_t *frame, uint16_t bits, uint8_t *par, uint32_t
void ReaderTransmitPar(uint8_t *frame, uint16_t len, uint8_t *par, uint32_t *timing);
uint16_t ReaderReceive(uint8_t *receivedAnswer, uint8_t *par);
iso14a_polling_parameters iso14a_get_polling_parameters(bool use_ecp, bool use_magsafe);
void iso14443a_setup(uint8_t fpga_minor_mode);
int iso14_apdu(uint8_t *cmd, uint16_t cmd_len, bool send_chaining, void *data, uint8_t *res);
int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats);

View file

@ -434,6 +434,71 @@ int Hf14443_4aGetCardData(iso14a_card_select_t *card) {
return 0;
}
iso14a_polling_parameters iso14a_get_polling_parameters(bool use_ecp, bool use_magsafe) {
iso14a_polling_frame WUPA_FRAME = {
{ 0x52 }, 1, 7, 0,
};
iso14a_polling_frame MAGWUPA1_FRAME = {
{ 0x7A }, 1, 7, 0
};
iso14a_polling_frame MAGWUPA2_FRAME = {
{ 0x7B }, 1, 7, 0
};
iso14a_polling_frame MAGWUPA3_FRAME = {
{ 0x7C }, 1, 7, 0
};
iso14a_polling_frame MAGWUPA4_FRAME = {
{ 0x7D }, 1, 7, 0
};
iso14a_polling_frame ECP_FRAME = {
.frame={ 0x6a, 0x02, 0xC8, 0x01, 0x00, 0x03, 0x00, 0x02, 0x79, 0x00, 0x00, 0x00, 0x00, 0xC2, 0xD8},
.frame_length=15,
.last_byte_bits=8,
.extra_delay=0
};
iso14a_polling_parameters WUPA_POLLING_PARAMETERS = {
.frames={ WUPA_FRAME },
.frame_count=1,
.extra_timeout=0,
};
iso14a_polling_parameters MAGSAFE_POLLING_PARAMETERS = {
.frames={ WUPA_FRAME, MAGWUPA1_FRAME, MAGWUPA2_FRAME, MAGWUPA3_FRAME, MAGWUPA4_FRAME },
.frame_count=5,
.extra_timeout=0
};
// Extra 100ms give enough time for Apple devices to proccess field info and make a decision
iso14a_polling_parameters ECP_POLLING_PARAMETERS = {
.frames={ WUPA_FRAME, ECP_FRAME },
.frame_count=2,
.extra_timeout=100
};
iso14a_polling_parameters FULL_POLLING_PARAMETERS = {
.frames={ WUPA_FRAME, ECP_FRAME, MAGWUPA1_FRAME, MAGWUPA2_FRAME, MAGWUPA3_FRAME, MAGWUPA4_FRAME },
.frame_count=6,
.extra_timeout=100
};
if (use_ecp && use_magsafe) {
return FULL_POLLING_PARAMETERS;
} else if (use_ecp) {
return ECP_POLLING_PARAMETERS;
} else if (use_magsafe) {
return MAGSAFE_POLLING_PARAMETERS;
}
return WUPA_POLLING_PARAMETERS;
}
static int CmdHF14AReader(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf 14a reader",
@ -473,12 +538,10 @@ static int CmdHF14AReader(const char *Cmd) {
cm |= ISO14A_NO_RATS;
}
if (arg_get_lit(ctx, 5)) {
cm |= ISO14A_USE_ECP;
}
if (arg_get_lit(ctx, 6)) {
cm |= ISO14A_USE_MAGSAFE;
iso14a_polling_parameters polling_parameters;
if (arg_get_lit(ctx, 5) || arg_get_lit(ctx, 6)) {
cm |= ISO14A_USE_CUSTOM_POLLING;
polling_parameters = iso14a_get_polling_parameters(arg_get_lit(ctx, 5), arg_get_lit(ctx, 6));
}
bool continuous = arg_get_lit(ctx, 7);
@ -494,7 +557,13 @@ static int CmdHF14AReader(const char *Cmd) {
}
do {
clearCommandBuffer();
if (cm & ISO14A_USE_CUSTOM_POLLING) {
SendCommandMIX(CMD_HF_ISO14443A_READER, cm, 0, 0, (uint8_t *)&polling_parameters, sizeof(polling_parameters));
} else {
SendCommandMIX(CMD_HF_ISO14443A_READER, cm, 0, 0, NULL, 0);
}
if (ISO14A_CONNECT & cm) {
PacketResponseNG resp;

View file

@ -52,6 +52,7 @@ int Hf14443_4aGetCardData(iso14a_card_select_t *card);
int ExchangeAPDU14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen);
int ExchangeRAW14a(uint8_t *datain, int datainlen, bool activateField, bool leaveSignalON, uint8_t *dataout, int maxdataoutlen, int *dataoutlen, bool silentMode);
iso14a_polling_parameters iso14a_get_polling_parameters(bool use_ecp, bool use_magsafe);
int SelectCard14443A_4(bool disconnect, bool verbose, iso14a_card_select_t *card);
bool Get_apdu_in_framing(void);

View file

@ -75,9 +75,27 @@ typedef enum ISO14A_COMMAND {
ISO14A_NO_RATS = (1 << 9),
ISO14A_SEND_CHAINING = (1 << 10),
ISO14A_USE_ECP = (1 << 11),
ISO14A_USE_MAGSAFE = (1 << 12)
ISO14A_USE_MAGSAFE = (1 << 12),
ISO14A_USE_CUSTOM_POLLING = (1 << 13)
} iso14a_command_t;
// Defines a frame that will be used in a polling sequence
// ECP Frames are up to (7 + 16) bytes long, 24 bytes should cover future and other cases
typedef struct {
uint8_t frame[24];
uint8_t frame_length;
uint8_t last_byte_bits;
uint16_t extra_delay;
} iso14a_polling_frame;
// Defines polling sequence configuration
// 6 would be enough for 4 magsafe, 1 wupa, 1 ecp,
typedef struct {
iso14a_polling_frame frames[6];
uint8_t frame_count;
uint16_t extra_timeout;
} iso14a_polling_parameters;
typedef struct {
uint8_t *response;
uint8_t *modulation;