diff --git a/lib/nfc/protocols/type_4_tag/type_4_tag_i.c b/lib/nfc/protocols/type_4_tag/type_4_tag_i.c index 90b5fecc2..889cf635b 100644 --- a/lib/nfc/protocols/type_4_tag/type_4_tag_i.c +++ b/lib/nfc/protocols/type_4_tag/type_4_tag_i.c @@ -9,8 +9,8 @@ #define TYPE_4_TAG_FFF_NDEF_DATA_PER_LINE (16U) -const uint8_t type_4_tag_iso_picc_name[TYPE_4_TAG_ISO_NAME_LEN] = {TYPE_4_TAG_ISO_PICC_NAME}; -const uint8_t type_4_tag_iso_app_name[TYPE_4_TAG_ISO_NAME_LEN] = {TYPE_4_TAG_ISO_APP_NAME}; +const uint8_t type_4_tag_iso_mf_name[TYPE_4_TAG_ISO_NAME_LEN] = {TYPE_4_TAG_ISO_MF_NAME}; +const uint8_t type_4_tag_iso_df_name[TYPE_4_TAG_ISO_NAME_LEN] = {TYPE_4_TAG_ISO_DF_NAME}; Type4TagError type_4_tag_process_error(Iso14443_4aError error) { switch(error) { @@ -46,11 +46,11 @@ void type_4_tag_cc_dump(const Type4TagData* data, uint8_t* buf, size_t len) { cc->tlv[0].len = sizeof(cc->tlv[0].value.ndef_file_ctrl); bit_lib_num_to_bytes_be( - data->is_tag_specific ? data->ndef_file_id : TYPE_4_TAG_T4T_DEFAULT_FILE_ID, + data->is_tag_specific ? data->ndef_file_id : TYPE_4_TAG_T4T_NDEF_EF_ID, sizeof(cc->tlv[0].value.ndef_file_ctrl.file_id), (void*)&cc->tlv[0].value.ndef_file_ctrl.file_id); bit_lib_num_to_bytes_be( - data->is_tag_specific ? data->ndef_max_len : TYPE_4_TAG_DEFAULT_SIZE, + data->is_tag_specific ? data->ndef_max_len : TYPE_4_TAG_DEFAULT_NDEF_SIZE, sizeof(cc->tlv[0].value.ndef_file_ctrl.max_len), (void*)&cc->tlv[0].value.ndef_file_ctrl.max_len); cc->tlv[0].value.ndef_file_ctrl.read_perm = diff --git a/lib/nfc/protocols/type_4_tag/type_4_tag_i.h b/lib/nfc/protocols/type_4_tag/type_4_tag_i.h index 00571f90f..1af7c7f38 100644 --- a/lib/nfc/protocols/type_4_tag/type_4_tag_i.h +++ b/lib/nfc/protocols/type_4_tag/type_4_tag_i.h @@ -3,12 +3,12 @@ #include "type_4_tag.h" // ISO SELECT FILE command and parameters -#define TYPE_4_TAG_ISO_SELECT_CMD 0x00, 0xA4 -#define TYPE_4_TAG_ISO_SELECT_P1_BY_DF_NAME (0x04) -#define TYPE_4_TAG_ISO_SELECT_P1_BY_EF_ID (0x02) -#define TYPE_4_TAG_ISO_SELECT_P1_BY_ID (0x00) -#define TYPE_4_TAG_ISO_SELECT_P2_EMPTY (0x0C) -#define TYPE_4_TAG_ISO_SELECT_LE_EMPTY (0x00) +#define TYPE_4_TAG_ISO_SELECT_CMD 0x00, 0xA4 +#define TYPE_4_TAG_ISO_SELECT_P1_BY_NAME (0x04) +#define TYPE_4_TAG_ISO_SELECT_P1_BY_EF_ID (0x02) +#define TYPE_4_TAG_ISO_SELECT_P1_BY_ID (0x00) +#define TYPE_4_TAG_ISO_SELECT_P2_EMPTY (0x0C) +#define TYPE_4_TAG_ISO_SELECT_LE_EMPTY (0x00) // ISO READ BINARY command and parameters #define TYPE_4_TAG_ISO_READ_CMD 0x00, 0xB0 @@ -32,23 +32,34 @@ #define TYPE_4_TAG_ISO_STATUS_BAD_PARAMS 0x6A, 0x86 #define TYPE_4_TAG_ISO_STATUS_NO_CMD 0x68, 0x00 #define TYPE_4_TAG_ISO_RW_CHUNK_LEN (255U) -#define TYPE_4_TAG_ISO_NAME_LEN (7U) -#define TYPE_4_TAG_ISO_PICC_NAME 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x00 -#define TYPE_4_TAG_ISO_APP_NAME 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01 -#define TYPE_4_TAG_T4T_CC_FILE_ID 0xE103 -#define TYPE_4_TAG_T4T_CC_VNO (0x20) -#define TYPE_4_TAG_T4T_DEFAULT_FILE_ID 0xE104 -#define TYPE_4_TAG_T4T_CC_RW_LOCK_NONE 0x00 -#define TYPE_4_TAG_T4T_CC_MIN_SIZE (sizeof(Type4TagCc) + sizeof(Type4TagCcTlv)) +// Common IDs and Names, note: +// MF = Master File (PICC/Card Level) +// DF = Dedicated File (Application) +// EF = Elementary File (File) +#define TYPE_4_TAG_ISO_NAME_LEN (7U) +#define TYPE_4_TAG_ISO_MF_NAME 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x00 +#define TYPE_4_TAG_ISO_DF_NAME 0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01 +#define TYPE_4_TAG_ISO_ID_LEN (2U) +#define TYPE_4_TAG_ISO_MF_ID (0x3F00) +#define TYPE_4_TAG_ISO_DF_ID (0xE110) +#define TYPE_4_TAG_T4T_CC_EF_ID (0xE103) +#define TYPE_4_TAG_T4T_NDEF_EF_ID (0xE104) + +// Capability Container parsing parameters +#define TYPE_4_TAG_T4T_CC_VNO (0x20) +#define TYPE_4_TAG_T4T_CC_RW_LOCK_NONE (0x00) +#define TYPE_4_TAG_T4T_CC_MIN_SIZE (sizeof(Type4TagCc) + sizeof(Type4TagCcTlv)) + +// Implementation-specific sizes and defaults // 4a layer adds 1..3 byte prefix, 3a layer adds 2 byte suffix and has 256 byte buffer -#define TYPE_4_TAG_BUF_SIZE (256U - 3U - 2U) +#define TYPE_4_TAG_BUF_SIZE (256U - 3U - 2U) // Read returns 2 byte status trailer, write sends 5 byte command header -#define TYPE_4_TAG_CHUNK_LEN MIN(TYPE_4_TAG_BUF_SIZE - 5U, TYPE_4_TAG_ISO_RW_CHUNK_LEN) -#define TYPE_4_TAG_DEFAULT_SIZE (2048U) +#define TYPE_4_TAG_CHUNK_LEN MIN(TYPE_4_TAG_BUF_SIZE - 5U, TYPE_4_TAG_ISO_RW_CHUNK_LEN) +#define TYPE_4_TAG_DEFAULT_NDEF_SIZE (2048U) -extern const uint8_t type_4_tag_iso_picc_name[TYPE_4_TAG_ISO_NAME_LEN]; -extern const uint8_t type_4_tag_iso_app_name[TYPE_4_TAG_ISO_NAME_LEN]; +extern const uint8_t type_4_tag_iso_mf_name[TYPE_4_TAG_ISO_NAME_LEN]; +extern const uint8_t type_4_tag_iso_df_name[TYPE_4_TAG_ISO_NAME_LEN]; // Capability Container parsing structures diff --git a/lib/nfc/protocols/type_4_tag/type_4_tag_listener_i.c b/lib/nfc/protocols/type_4_tag/type_4_tag_listener_i.c index ba0ee694a..fb0890688 100644 --- a/lib/nfc/protocols/type_4_tag/type_4_tag_listener_i.c +++ b/lib/nfc/protocols/type_4_tag/type_4_tag_listener_i.c @@ -35,17 +35,15 @@ static Type4TagError type_4_tag_listener_iso_select( UNUSED(p2); UNUSED(le); - if(p1 == TYPE_4_TAG_ISO_SELECT_P1_BY_DF_NAME) { - if(lc == sizeof(type_4_tag_iso_picc_name) && - memcmp(type_4_tag_iso_picc_name, data, sizeof(type_4_tag_iso_picc_name)) == 0) { + if(p1 == TYPE_4_TAG_ISO_SELECT_P1_BY_NAME && lc == TYPE_4_TAG_ISO_NAME_LEN) { + if(memcmp(type_4_tag_iso_mf_name, data, sizeof(type_4_tag_iso_mf_name)) == 0) { instance->state = Type4TagListenerStateSelectedPicc; bit_buffer_append_bytes( instance->tx_buffer, type_4_tag_success_apdu, sizeof(type_4_tag_success_apdu)); return Type4TagErrorNone; } - if(lc == sizeof(type_4_tag_iso_app_name) && - memcmp(type_4_tag_iso_app_name, data, sizeof(type_4_tag_iso_app_name)) == 0) { + if(memcmp(type_4_tag_iso_df_name, data, sizeof(type_4_tag_iso_df_name)) == 0) { instance->state = Type4TagListenerStateSelectedApplication; bit_buffer_append_bytes( instance->tx_buffer, type_4_tag_success_apdu, sizeof(type_4_tag_success_apdu)); @@ -53,23 +51,41 @@ static Type4TagError type_4_tag_listener_iso_select( } } else if( - instance->state >= Type4TagListenerStateSelectedApplication && (p1 == TYPE_4_TAG_ISO_SELECT_P1_BY_ID || p1 == TYPE_4_TAG_ISO_SELECT_P1_BY_EF_ID) && - lc == sizeof(uint16_t)) { - uint16_t file_id = bit_lib_bytes_to_num_be(data, sizeof(uint16_t)); - if(file_id == TYPE_4_TAG_T4T_CC_FILE_ID) { - instance->state = Type4TagListenerStateSelectedCapabilityContainer; - bit_buffer_append_bytes( - instance->tx_buffer, type_4_tag_success_apdu, sizeof(type_4_tag_success_apdu)); - return Type4TagErrorNone; + lc == TYPE_4_TAG_ISO_ID_LEN) { + uint16_t id = bit_lib_bytes_to_num_be(data, sizeof(uint16_t)); + + if(p1 == TYPE_4_TAG_ISO_SELECT_P1_BY_ID) { + if(id == TYPE_4_TAG_ISO_MF_ID) { + instance->state = Type4TagListenerStateSelectedPicc; + bit_buffer_append_bytes( + instance->tx_buffer, type_4_tag_success_apdu, sizeof(type_4_tag_success_apdu)); + return Type4TagErrorNone; + } + + if(id == TYPE_4_TAG_ISO_DF_ID) { + instance->state = Type4TagListenerStateSelectedApplication; + bit_buffer_append_bytes( + instance->tx_buffer, type_4_tag_success_apdu, sizeof(type_4_tag_success_apdu)); + return Type4TagErrorNone; + } } - if(file_id == (instance->data->is_tag_specific ? instance->data->ndef_file_id : - TYPE_4_TAG_T4T_DEFAULT_FILE_ID)) { - instance->state = Type4TagListenerStateSelectedNdefMessage; - bit_buffer_append_bytes( - instance->tx_buffer, type_4_tag_success_apdu, sizeof(type_4_tag_success_apdu)); - return Type4TagErrorNone; + if(instance->state >= Type4TagListenerStateSelectedApplication) { + if(id == TYPE_4_TAG_T4T_CC_EF_ID) { + instance->state = Type4TagListenerStateSelectedCapabilityContainer; + bit_buffer_append_bytes( + instance->tx_buffer, type_4_tag_success_apdu, sizeof(type_4_tag_success_apdu)); + return Type4TagErrorNone; + } + + if(id == (instance->data->is_tag_specific ? instance->data->ndef_file_id : + TYPE_4_TAG_T4T_NDEF_EF_ID)) { + instance->state = Type4TagListenerStateSelectedNdefMessage; + bit_buffer_append_bytes( + instance->tx_buffer, type_4_tag_success_apdu, sizeof(type_4_tag_success_apdu)); + return Type4TagErrorNone; + } } } @@ -181,7 +197,7 @@ static Type4TagError type_4_tag_listener_iso_write( if(instance->state == Type4TagListenerStateSelectedNdefMessage) { if(offset + lc > (instance->data->is_tag_specific ? instance->data->ndef_max_len : - TYPE_4_TAG_DEFAULT_SIZE)) { + TYPE_4_TAG_DEFAULT_NDEF_SIZE)) { bit_buffer_append_bytes( instance->tx_buffer, type_4_tag_offset_error_apdu, diff --git a/lib/nfc/protocols/type_4_tag/type_4_tag_poller_i.c b/lib/nfc/protocols/type_4_tag/type_4_tag_poller_i.c index eab1d474b..bdfb093f4 100644 --- a/lib/nfc/protocols/type_4_tag/type_4_tag_poller_i.c +++ b/lib/nfc/protocols/type_4_tag/type_4_tag_poller_i.c @@ -41,11 +41,11 @@ Type4TagError type_4_tag_apdu_trx(Type4TagPoller* instance, BitBuffer* tx_buf, B static Type4TagError type_5_tag_poller_iso_select_name( Type4TagPoller* instance, - const uint8_t* df_name, - uint8_t df_name_len) { + const uint8_t* name, + uint8_t name_len) { const uint8_t type_4_tag_iso_select_name_apdu[] = { TYPE_4_TAG_ISO_SELECT_CMD, - TYPE_4_TAG_ISO_SELECT_P1_BY_DF_NAME, + TYPE_4_TAG_ISO_SELECT_P1_BY_NAME, TYPE_4_TAG_ISO_SELECT_P2_EMPTY, }; @@ -53,8 +53,8 @@ static Type4TagError type_5_tag_poller_iso_select_name( instance->tx_buffer, type_4_tag_iso_select_name_apdu, sizeof(type_4_tag_iso_select_name_apdu)); - bit_buffer_append_byte(instance->tx_buffer, df_name_len); - bit_buffer_append_bytes(instance->tx_buffer, df_name, df_name_len); + bit_buffer_append_byte(instance->tx_buffer, name_len); + bit_buffer_append_bytes(instance->tx_buffer, name, name_len); return type_4_tag_apdu_trx(instance, instance->tx_buffer, instance->rx_buffer); } @@ -63,7 +63,7 @@ static Type4TagError type_5_tag_poller_iso_select_file(Type4TagPoller* instance, uint16_t file_id) { const uint8_t type_4_tag_iso_select_file_apdu[] = { TYPE_4_TAG_ISO_SELECT_CMD, - TYPE_4_TAG_ISO_SELECT_P1_BY_ID, + TYPE_4_TAG_ISO_SELECT_P1_BY_EF_ID, TYPE_4_TAG_ISO_SELECT_P2_EMPTY, sizeof(file_id), }; @@ -134,7 +134,7 @@ Type4TagError type_4_tag_poller_select_app(Type4TagPoller* instance) { FURI_LOG_D(TAG, "Select application"); return type_5_tag_poller_iso_select_name( - instance, type_4_tag_iso_app_name, sizeof(type_4_tag_iso_app_name)); + instance, type_4_tag_iso_df_name, sizeof(type_4_tag_iso_df_name)); } Type4TagError type_4_tag_poller_read_cc(Type4TagPoller* instance) { @@ -144,7 +144,7 @@ Type4TagError type_4_tag_poller_read_cc(Type4TagPoller* instance) { do { FURI_LOG_D(TAG, "Select CC"); - error = type_5_tag_poller_iso_select_file(instance, TYPE_4_TAG_T4T_CC_FILE_ID); + error = type_5_tag_poller_iso_select_file(instance, TYPE_4_TAG_T4T_CC_EF_ID); if(error != Type4TagErrorNone) break; FURI_LOG_D(TAG, "Read CC len");