From 2d62d8a71e5f2da02eca08cdf17a6c9752f313bb Mon Sep 17 00:00:00 2001 From: Willy-JL <49810075+Willy-JL@users.noreply.github.com> Date: Mon, 4 Nov 2024 02:35:06 +0000 Subject: [PATCH] NFC: Test revert 0902fd49e1cb7bd0c49bb2685985593f08861449 --- lib/nfc/helpers/iso14443_4_layer.c | 107 ++++-------------- lib/nfc/helpers/iso14443_4_layer.h | 4 - .../iso14443_4a/iso14443_4a_listener.c | 14 +-- .../iso14443_4a/iso14443_4a_listener.h | 1 - .../iso14443_4a/iso14443_4a_poller.h | 63 ----------- .../iso14443_4a/iso14443_4a_poller_i.c | 31 ----- targets/f7/api_symbols.csv | 3 - 7 files changed, 25 insertions(+), 198 deletions(-) diff --git a/lib/nfc/helpers/iso14443_4_layer.c b/lib/nfc/helpers/iso14443_4_layer.c index ef9baaabc..933612df8 100644 --- a/lib/nfc/helpers/iso14443_4_layer.c +++ b/lib/nfc/helpers/iso14443_4_layer.c @@ -2,50 +2,22 @@ #include -// EMV Specific masks +#define ISO14443_4_BLOCK_PCB (1U << 1) +#define ISO14443_4_BLOCK_PCB_I (0U) +#define ISO14443_4_BLOCK_PCB_R (5U << 5) +#define ISO14443_4_BLOCK_PCB_S (3U << 6) + #define ISO14443_4_BLOCK_PCB_I_ (0U << 6) #define ISO14443_4_BLOCK_PCB_R_ (2U << 6) #define ISO14443_4_BLOCK_PCB_TYPE_MASK (3U << 6) -#define ISO14443_4_BLOCK_PCB_S_WTX (3U << 4) -#define ISO14443_4_BLOCK_PCB_S (3U << 6) -// -#define ISO14443_4_BLOCK_PCB (1U << 1) -#define ISO14443_4_BLOCK_PCB_MASK (0x03) +#define ISO14443_4_BLOCK_PCB_S_DESELECT (0U << 4) +#define ISO14443_4_BLOCK_PCB_S_WTX (3U << 4) +#define ISO14443_4_BLOCK_PCB_BLOCK_NUMBER (1U << 0) -#define ISO14443_4_BLOCK_PCB_I (0U) -#define ISO14443_4_BLOCK_PCB_I_NAD_OFFSET (2) -#define ISO14443_4_BLOCK_PCB_I_CID_OFFSET (3) -#define ISO14443_4_BLOCK_PCB_I_CHAIN_OFFSET (4) -#define ISO14443_4_BLOCK_PCB_I_NAD_MASK (1U << ISO14443_4_BLOCK_PCB_I_NAD_OFFSET) -#define ISO14443_4_BLOCK_PCB_I_CID_MASK (1U << ISO14443_4_BLOCK_PCB_I_CID_OFFSET) -#define ISO14443_4_BLOCK_PCB_I_CHAIN_MASK (1U << ISO14443_4_BLOCK_PCB_I_CHAIN_OFFSET) - -#define ISO14443_4_BLOCK_PCB_R_MASK (5U << 5) -#define ISO14443_4_BLOCK_PCB_R_NACK_OFFSET (4) -#define ISO14443_4_BLOCK_PCB_R_CID_OFFSET (3) -#define ISO14443_4_BLOCK_PCB_R_CID_MASK (1U << ISO14443_4_BLOCK_PCB_R_CID_OFFSET) -#define ISO14443_4_BLOCK_PCB_R_NACK_MASK (1U << ISO14443_4_BLOCK_PCB_R_NACK_OFFSET) - -#define ISO14443_4_BLOCK_PCB_S_MASK (3U << 6) -#define ISO14443_4_BLOCK_PCB_S_CID_OFFSET (3) -#define ISO14443_4_BLOCK_PCB_S_WTX_DESELECT_OFFSET (4) -#define ISO14443_4_BLOCK_PCB_S_CID_MASK (1U << ISO14443_4_BLOCK_PCB_R_CID_OFFSET) -#define ISO14443_4_BLOCK_PCB_S_WTX_DESELECT_MASK (3U << ISO14443_4_BLOCK_PCB_S_WTX_DESELECT_OFFSET) - -#define ISO14443_4_BLOCK_PCB_BITS_ACTIVE(pcb, mask) (((pcb) & (mask)) == (mask)) - -#define ISO14443_4_BLOCK_PCB_IS_R_BLOCK(pcb) \ - ISO14443_4_BLOCK_PCB_BITS_ACTIVE(pcb, ISO14443_4_BLOCK_PCB_R_MASK) - -#define ISO14443_4_BLOCK_PCB_IS_S_BLOCK(pcb) \ - ISO14443_4_BLOCK_PCB_BITS_ACTIVE(pcb, ISO14443_4_BLOCK_PCB_S_MASK) - -#define ISO14443_4_BLOCK_PCB_IS_CHAIN_ACTIVE(pcb) \ - ISO14443_4_BLOCK_PCB_BITS_ACTIVE(pcb, ISO14443_4_BLOCK_PCB_I_CHAIN_MASK) - -#define ISO14443_4_BLOCK_PCB_R_NACK_ACTIVE(pcb) \ - ISO14443_4_BLOCK_PCB_BITS_ACTIVE(pcb, ISO14443_4_BLOCK_PCB_R_NACK_MASK) +#define ISO14443_4_BLOCK_PCB_NAD (1U << 2) +#define ISO14443_4_BLOCK_PCB_CID (1U << 3) +#define ISO14443_4_BLOCK_PCB_CHAINING (1U << 4) struct Iso14443_4Layer { uint8_t pcb; @@ -71,31 +43,9 @@ void iso14443_4_layer_free(Iso14443_4Layer* instance) { void iso14443_4_layer_reset(Iso14443_4Layer* instance) { furi_assert(instance); - instance->pcb_prev = 0; instance->pcb = ISO14443_4_BLOCK_PCB_I | ISO14443_4_BLOCK_PCB; } -void iso14443_4_layer_set_i_block(Iso14443_4Layer* instance, bool chaining, bool CID_present) { - uint8_t block_pcb = instance->pcb & ISO14443_4_BLOCK_PCB_MASK; - instance->pcb = ISO14443_4_BLOCK_PCB_I | (chaining << ISO14443_4_BLOCK_PCB_I_CHAIN_OFFSET) | - (CID_present << ISO14443_4_BLOCK_PCB_I_CID_OFFSET) | block_pcb; -} - -void iso14443_4_layer_set_r_block(Iso14443_4Layer* instance, bool acknowledged, bool CID_present) { - furi_assert(instance); - uint8_t block_pcb = instance->pcb & ISO14443_4_BLOCK_PCB_MASK; - instance->pcb = ISO14443_4_BLOCK_PCB_R_MASK | - (!acknowledged << ISO14443_4_BLOCK_PCB_R_NACK_OFFSET) | - (CID_present << ISO14443_4_BLOCK_PCB_R_CID_OFFSET) | block_pcb; -} - -void iso14443_4_layer_set_s_block(Iso14443_4Layer* instance, bool deselect, bool CID_present) { - furi_assert(instance); - uint8_t des_wtx = !deselect ? (ISO14443_4_BLOCK_PCB_S_WTX_DESELECT_MASK) : 0; - instance->pcb = ISO14443_4_BLOCK_PCB_S_MASK | des_wtx | - (CID_present << ISO14443_4_BLOCK_PCB_S_CID_OFFSET) | ISO14443_4_BLOCK_PCB; -} - void iso14443_4_layer_encode_block( Iso14443_4Layer* instance, const BitBuffer* input_data, @@ -108,11 +58,6 @@ void iso14443_4_layer_encode_block( iso14443_4_layer_update_pcb(instance); } -static inline uint8_t iso14443_4_layer_get_response_pcb(const BitBuffer* block_data) { - const uint8_t* data = bit_buffer_get_data(block_data); - return data[0]; -} - bool iso14443_4_layer_decode_block( Iso14443_4Layer* instance, BitBuffer* output_data, @@ -121,27 +66,17 @@ bool iso14443_4_layer_decode_block( bool ret = false; + // TODO: Fix properly! this is a very big kostyl na velosipede + // (bit_buffer_copy_right are called to copy bigger buffer into smaller buffer causing crash on furi check) issue comes iso14443_4a_poller_send_block at line 109 + // Mimicks furi_check()s in bit_buffer_copy_right(): buf=output_data other=block_data start_index=1 + if(!(bit_buffer_get_size_bytes(block_data) > 1)) return ret; + if(!(bit_buffer_get_capacity_bytes(output_data) >= bit_buffer_get_size_bytes(block_data) - 1)) + return ret; + do { - if(ISO14443_4_BLOCK_PCB_IS_R_BLOCK(instance->pcb_prev)) { - const uint8_t response_pcb = iso14443_4_layer_get_response_pcb(block_data); - ret = (ISO14443_4_BLOCK_PCB_IS_R_BLOCK(response_pcb)) && - (!ISO14443_4_BLOCK_PCB_R_NACK_ACTIVE(response_pcb)); - instance->pcb &= ISO14443_4_BLOCK_PCB_MASK; - iso14443_4_layer_update_pcb(instance); - } else if(ISO14443_4_BLOCK_PCB_IS_CHAIN_ACTIVE(instance->pcb_prev)) { - const uint8_t response_pcb = iso14443_4_layer_get_response_pcb(block_data); - ret = (ISO14443_4_BLOCK_PCB_IS_R_BLOCK(response_pcb)) && - (!ISO14443_4_BLOCK_PCB_R_NACK_ACTIVE(response_pcb)); - instance->pcb &= ~(ISO14443_4_BLOCK_PCB_I_CHAIN_MASK); - } else if(ISO14443_4_BLOCK_PCB_IS_S_BLOCK(instance->pcb_prev)) { - ret = bit_buffer_starts_with_byte(block_data, instance->pcb_prev); - if(bit_buffer_get_size_bytes(block_data) > 1) - bit_buffer_copy_right(output_data, block_data, 1); - } else { - if(!bit_buffer_starts_with_byte(block_data, instance->pcb_prev)) break; - bit_buffer_copy_right(output_data, block_data, 1); - ret = true; - } + if(!bit_buffer_starts_with_byte(block_data, instance->pcb_prev)) break; + bit_buffer_copy_right(output_data, block_data, 1); + ret = true; } while(false); return ret; diff --git a/lib/nfc/helpers/iso14443_4_layer.h b/lib/nfc/helpers/iso14443_4_layer.h index 9daf25775..f4f8db520 100644 --- a/lib/nfc/helpers/iso14443_4_layer.h +++ b/lib/nfc/helpers/iso14443_4_layer.h @@ -15,10 +15,6 @@ void iso14443_4_layer_free(Iso14443_4Layer* instance); void iso14443_4_layer_reset(Iso14443_4Layer* instance); -void iso14443_4_layer_set_i_block(Iso14443_4Layer* instance, bool chaining, bool CID_present); -void iso14443_4_layer_set_r_block(Iso14443_4Layer* instance, bool acknowledged, bool CID_present); -void iso14443_4_layer_set_s_block(Iso14443_4Layer* instance, bool deselect, bool CID_present); - void iso14443_4_layer_encode_block( Iso14443_4Layer* instance, const BitBuffer* input_data, diff --git a/lib/nfc/protocols/iso14443_4a/iso14443_4a_listener.c b/lib/nfc/protocols/iso14443_4a/iso14443_4a_listener.c index 2519fb90c..95612bf54 100644 --- a/lib/nfc/protocols/iso14443_4a/iso14443_4a_listener.c +++ b/lib/nfc/protocols/iso14443_4a/iso14443_4a_listener.c @@ -65,8 +65,10 @@ static NfcCommand iso14443_4a_listener_run(NfcGenericEvent event, void* context) if(instance->state == Iso14443_4aListenerStateIdle) { if(bit_buffer_get_size_bytes(rx_buffer) == 2 && bit_buffer_get_byte(rx_buffer, 0) == ISO14443_4A_CMD_READ_ATS) { - if(iso14443_4a_listener_send_ats(instance, &instance->data->ats_data) == + if(iso14443_4a_listener_send_ats(instance, &instance->data->ats_data) != Iso14443_4aErrorNone) { + command = NfcCommandContinue; + } else { instance->state = Iso14443_4aListenerStateActive; } } @@ -82,15 +84,7 @@ static NfcCommand iso14443_4a_listener_run(NfcGenericEvent event, void* context) iso14443_3a_event->type == Iso14443_3aListenerEventTypeHalted || iso14443_3a_event->type == Iso14443_3aListenerEventTypeFieldOff) { instance->state = Iso14443_4aListenerStateIdle; - - instance->iso14443_4a_event.type = iso14443_3a_event->type == - Iso14443_3aListenerEventTypeHalted ? - Iso14443_4aListenerEventTypeHalted : - Iso14443_4aListenerEventTypeFieldOff; - - if(instance->callback) { - command = instance->callback(instance->generic_event, instance->context); - } + command = NfcCommandContinue; } return command; diff --git a/lib/nfc/protocols/iso14443_4a/iso14443_4a_listener.h b/lib/nfc/protocols/iso14443_4a/iso14443_4a_listener.h index 04f0b197a..ba649847b 100644 --- a/lib/nfc/protocols/iso14443_4a/iso14443_4a_listener.h +++ b/lib/nfc/protocols/iso14443_4a/iso14443_4a_listener.h @@ -12,7 +12,6 @@ typedef struct Iso14443_4aListener Iso14443_4aListener; typedef enum { Iso14443_4aListenerEventTypeHalted, - Iso14443_4aListenerEventTypeFieldOff, Iso14443_4aListenerEventTypeReceivedData, } Iso14443_4aListenerEventType; diff --git a/lib/nfc/protocols/iso14443_4a/iso14443_4a_poller.h b/lib/nfc/protocols/iso14443_4a/iso14443_4a_poller.h index 7b43d6ee8..019beb2be 100644 --- a/lib/nfc/protocols/iso14443_4a/iso14443_4a_poller.h +++ b/lib/nfc/protocols/iso14443_4a/iso14443_4a_poller.h @@ -61,69 +61,6 @@ Iso14443_4aError iso14443_4a_poller_send_block_pwt_ext( const BitBuffer* tx_buffer, BitBuffer* rx_buffer); -/** - * @brief Transmit and receive Iso14443_4a chained block in poller mode. Also it - * automatically modifies PCB packet byte with appropriate bits then resets them back - * - * Must ONLY be used inside the callback function. - * - * The rx_buffer will be filled with any data received as a response to data - * sent from tx_buffer. The fwt parameter is calculated during activation procedure. - * - * @param[in, out] instance pointer to the instance to be used in the transaction. - * @param[in] tx_buffer pointer to the buffer containing the data to be transmitted. - * @param[out] rx_buffer pointer to the buffer to be filled with received data. - * @return Iso14443_4aErrorNone on success, an error code on failure. - */ -Iso14443_4aError iso14443_4a_poller_send_chain_block( - Iso14443_4aPoller* instance, - const BitBuffer* tx_buffer, - BitBuffer* rx_buffer); - -/** - * @brief Transmit Iso14443_4a R-block in poller mode. This block never contains - * data, but can contain CID and NAD, therefore in tx_buffer only two bytes can be added. - * The first one will represent CID, the second one will represent NAD. - * - * Must ONLY be used inside the callback function. - * - * The rx_buffer will be filled with R-block repsonse - * - * @param[in, out] instance pointer to the instance to be used in the transaction. - * @param[in] acknowledged Sets appropriate bit in PCB byte. True - ACK, false - NAK - * @param[in] tx_buffer pointer to the buffer containing the data to be transmitted. - * @param[out] rx_buffer pointer to the buffer to be filled with received data. - * @return Iso14443_4aErrorNone on success, an error code on failure. - */ -Iso14443_4aError iso14443_4a_poller_send_receive_ready_block( - Iso14443_4aPoller* instance, - bool acknowledged, - const BitBuffer* tx_buffer, - BitBuffer* rx_buffer); - -/** - * @brief Transmit Iso14443_4a S-block in poller mode. S-block used to exchange control - * information between the card and the reader. Two different types of S-blocks - * are defined: - * - Waiting time extension containing a 1 byte long INF field and (deselect = false) - * - DESELECT containing no INF field (deselect = true) - * - * Must ONLY be used inside the callback function. - * - * The rx_buffer will be filled with R-block repsonse - * - * @param[in, out] instance pointer to the instance to be used in the transaction. - * @param[in] deselect Sets appropriate bit in PCB byte. - * @param[in] tx_buffer pointer to the buffer containing the data to be transmitted. - * @param[out] rx_buffer pointer to the buffer to be filled with received data. - * @return Iso14443_4aErrorNone on success, an error code on failure. - */ -Iso14443_4aError iso14443_4a_poller_send_supervisory_block( - Iso14443_4aPoller* instance, - bool deselect, - const BitBuffer* tx_buffer, - BitBuffer* rx_buffer); - /** * @brief Send HALT command to the card. * diff --git a/lib/nfc/protocols/iso14443_4a/iso14443_4a_poller_i.c b/lib/nfc/protocols/iso14443_4a/iso14443_4a_poller_i.c index a2342a92d..02d78fba5 100644 --- a/lib/nfc/protocols/iso14443_4a/iso14443_4a_poller_i.c +++ b/lib/nfc/protocols/iso14443_4a/iso14443_4a_poller_i.c @@ -116,37 +116,6 @@ Iso14443_4aError iso14443_4a_poller_send_block( return error; } -Iso14443_4aError iso14443_4a_poller_send_chain_block( - Iso14443_4aPoller* instance, - const BitBuffer* tx_buffer, - BitBuffer* rx_buffer) { - iso14443_4_layer_set_i_block(instance->iso14443_4_layer, true, false); - Iso14443_4aError error = iso14443_4a_poller_send_block(instance, tx_buffer, rx_buffer); - return error; -} - -Iso14443_4aError iso14443_4a_poller_send_receive_ready_block( - Iso14443_4aPoller* instance, - bool acknowledged, - const BitBuffer* tx_buffer, - BitBuffer* rx_buffer) { - bool CID_present = bit_buffer_get_size_bytes(tx_buffer) != 0; - iso14443_4_layer_set_r_block(instance->iso14443_4_layer, acknowledged, CID_present); - Iso14443_4aError error = iso14443_4a_poller_send_block(instance, tx_buffer, rx_buffer); - return error; -} - -Iso14443_4aError iso14443_4a_poller_send_supervisory_block( - Iso14443_4aPoller* instance, - bool deselect, - const BitBuffer* tx_buffer, - BitBuffer* rx_buffer) { - bool CID_present = bit_buffer_get_size_bytes(tx_buffer) != 0; - iso14443_4_layer_set_s_block(instance->iso14443_4_layer, deselect, CID_present); - Iso14443_4aError error = iso14443_4a_poller_send_block(instance, tx_buffer, rx_buffer); - return error; -} - Iso14443_4aError iso14443_4a_poller_send_block_pwt_ext( Iso14443_4aPoller* instance, const BitBuffer* tx_buffer, diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index af8ab3f60..1c7beb85a 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -2211,9 +2211,6 @@ Function,+,iso14443_4a_poller_halt,Iso14443_4aError,Iso14443_4aPoller* Function,+,iso14443_4a_poller_read_ats,Iso14443_4aError,"Iso14443_4aPoller*, Iso14443_4aAtsData*" Function,+,iso14443_4a_poller_send_block,Iso14443_4aError,"Iso14443_4aPoller*, const BitBuffer*, BitBuffer*" Function,+,iso14443_4a_poller_send_block_pwt_ext,Iso14443_4aError,"Iso14443_4aPoller*, const BitBuffer*, BitBuffer*" -Function,+,iso14443_4a_poller_send_chain_block,Iso14443_4aError,"Iso14443_4aPoller*, const BitBuffer*, BitBuffer*" -Function,+,iso14443_4a_poller_send_receive_ready_block,Iso14443_4aError,"Iso14443_4aPoller*, _Bool, const BitBuffer*, BitBuffer*" -Function,+,iso14443_4a_poller_send_supervisory_block,Iso14443_4aError,"Iso14443_4aPoller*, _Bool, const BitBuffer*, BitBuffer*" Function,+,iso14443_4a_reset,void,Iso14443_4aData* Function,+,iso14443_4a_save,_Bool,"const Iso14443_4aData*, FlipperFormat*" Function,+,iso14443_4a_set_uid,_Bool,"Iso14443_4aData*, const uint8_t*, size_t"