Improve ISO SELECT naming and handling

This commit is contained in:
Willy-JL
2025-03-18 03:01:34 +00:00
parent b503020f6d
commit ca30673238
4 changed files with 78 additions and 51 deletions
+4 -4
View File
@@ -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 =
+30 -19
View File
@@ -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
@@ -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,
@@ -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");