mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-12-12 04:34:43 +04:00
Added naming for DESFire cards + fix MF3ICD40 cards unable to be read (#4058)
* Fixed MF3ICD40 DESFire cards soft-locking NFC application due to read free memory being an unsupported function, added naming for DESFire cards * NFC: slightly more granular desfire card type resolution Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
@@ -4,6 +4,46 @@
|
||||
|
||||
#define MF_DESFIRE_PROTOCOL_NAME "Mifare DESFire"
|
||||
|
||||
#define MF_DESFIRE_HW_MINOR_TYPE (0x00)
|
||||
#define MF_DESFIRE_HW_MINOR_TYPE_MF3ICD40 (0x02)
|
||||
|
||||
#define MF_DESFIRE_HW_MAJOR_TYPE_EV1 (0x01)
|
||||
#define MF_DESFIRE_HW_MAJOR_TYPE_EV2 (0x12)
|
||||
#define MF_DESFIRE_HW_MAJOR_TYPE_EV2_XL (0x22)
|
||||
#define MF_DESFIRE_HW_MAJOR_TYPE_EV3 (0x33)
|
||||
#define MF_DESFIRE_HW_MAJOR_TYPE_MF3ICD40 (0x00)
|
||||
|
||||
#define MF_DESFIRE_STORAGE_SIZE_2K (0x16)
|
||||
#define MF_DESFIRE_STORAGE_SIZE_4K (0x18)
|
||||
#define MF_DESFIRE_STORAGE_SIZE_8K (0x1A)
|
||||
#define MF_DESFIRE_STORAGE_SIZE_16K (0x1C)
|
||||
#define MF_DESFIRE_STORAGE_SIZE_32K (0x1E)
|
||||
#define MF_DESFIRE_STORAGE_SIZE_MF3ICD40 (0xFF)
|
||||
#define MF_DESFIRE_STORAGE_SIZE_UNKNOWN (0xFF)
|
||||
|
||||
#define MF_DESFIRE_TEST_TYPE_MF3ICD40(major, minor, storage) \
|
||||
(((major) == MF_DESFIRE_HW_MAJOR_TYPE_MF3ICD40) && \
|
||||
((minor) == MF_DESFIRE_HW_MINOR_TYPE_MF3ICD40) && \
|
||||
((storage) == MF_DESFIRE_STORAGE_SIZE_MF3ICD40))
|
||||
|
||||
static const char* mf_desfire_type_strings[] = {
|
||||
[MfDesfireTypeMF3ICD40] = "(MF3ICD40)",
|
||||
[MfDesfireTypeEV1] = "EV1",
|
||||
[MfDesfireTypeEV2] = "EV2",
|
||||
[MfDesfireTypeEV2XL] = "EV2 XL",
|
||||
[MfDesfireTypeEV3] = "EV3",
|
||||
[MfDesfireTypeUnknown] = "UNK",
|
||||
};
|
||||
|
||||
static const char* mf_desfire_size_strings[] = {
|
||||
[MfDesfireSize2k] = "2K",
|
||||
[MfDesfireSize4k] = "4K",
|
||||
[MfDesfireSize8k] = "8K",
|
||||
[MfDesfireSize16k] = "16K",
|
||||
[MfDesfireSize32k] = "32K",
|
||||
[MfDesfireSizeUnknown] = "",
|
||||
};
|
||||
|
||||
const NfcDeviceBase nfc_device_mf_desfire = {
|
||||
.protocol_name = MF_DESFIRE_PROTOCOL_NAME,
|
||||
.alloc = (NfcDeviceAlloc)mf_desfire_alloc,
|
||||
@@ -26,7 +66,7 @@ MfDesfireData* mf_desfire_alloc(void) {
|
||||
data->master_key_versions = simple_array_alloc(&mf_desfire_key_version_array_config);
|
||||
data->application_ids = simple_array_alloc(&mf_desfire_app_id_array_config);
|
||||
data->applications = simple_array_alloc(&mf_desfire_application_array_config);
|
||||
|
||||
data->device_name = furi_string_alloc();
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -38,6 +78,7 @@ void mf_desfire_free(MfDesfireData* data) {
|
||||
simple_array_free(data->application_ids);
|
||||
simple_array_free(data->master_key_versions);
|
||||
iso14443_4a_free(data->iso14443_4a_data);
|
||||
furi_string_free(data->device_name);
|
||||
free(data);
|
||||
}
|
||||
|
||||
@@ -228,10 +269,83 @@ bool mf_desfire_is_equal(const MfDesfireData* data, const MfDesfireData* other)
|
||||
simple_array_is_equal(data->applications, other->applications);
|
||||
}
|
||||
|
||||
static MfDesfireType mf_desfire_get_type_from_version(const MfDesfireVersion* const version) {
|
||||
MfDesfireType type = MfDesfireTypeUnknown;
|
||||
|
||||
switch(version->hw_major) {
|
||||
case MF_DESFIRE_HW_MAJOR_TYPE_EV1:
|
||||
type = MfDesfireTypeEV1;
|
||||
break;
|
||||
case MF_DESFIRE_HW_MAJOR_TYPE_EV2:
|
||||
type = MfDesfireTypeEV2;
|
||||
break;
|
||||
case MF_DESFIRE_HW_MAJOR_TYPE_EV2_XL:
|
||||
type = MfDesfireTypeEV2XL;
|
||||
break;
|
||||
case MF_DESFIRE_HW_MAJOR_TYPE_EV3:
|
||||
type = MfDesfireTypeEV3;
|
||||
break;
|
||||
default:
|
||||
if(MF_DESFIRE_TEST_TYPE_MF3ICD40(version->hw_major, version->hw_minor, version->hw_storage))
|
||||
type = MfDesfireTypeMF3ICD40;
|
||||
break;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
static MfDesfireSize mf_desfire_get_size_from_version(const MfDesfireVersion* const version) {
|
||||
MfDesfireSize size = MfDesfireSizeUnknown;
|
||||
|
||||
switch(version->hw_storage) {
|
||||
case MF_DESFIRE_STORAGE_SIZE_2K:
|
||||
size = MfDesfireSize2k;
|
||||
break;
|
||||
case MF_DESFIRE_STORAGE_SIZE_4K:
|
||||
size = MfDesfireSize4k;
|
||||
break;
|
||||
case MF_DESFIRE_STORAGE_SIZE_8K:
|
||||
size = MfDesfireSize8k;
|
||||
break;
|
||||
case MF_DESFIRE_STORAGE_SIZE_16K:
|
||||
size = MfDesfireSize16k;
|
||||
break;
|
||||
case MF_DESFIRE_STORAGE_SIZE_32K:
|
||||
size = MfDesfireSize32k;
|
||||
break;
|
||||
default:
|
||||
if(MF_DESFIRE_TEST_TYPE_MF3ICD40(version->hw_major, version->hw_minor, version->hw_storage))
|
||||
size = MfDesfireSize4k;
|
||||
break;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
const char* mf_desfire_get_device_name(const MfDesfireData* data, NfcDeviceNameType name_type) {
|
||||
UNUSED(data);
|
||||
UNUSED(name_type);
|
||||
return MF_DESFIRE_PROTOCOL_NAME;
|
||||
furi_check(data);
|
||||
|
||||
const MfDesfireType type = mf_desfire_get_type_from_version(&data->version);
|
||||
const MfDesfireSize size = mf_desfire_get_size_from_version(&data->version);
|
||||
|
||||
if(type == MfDesfireTypeUnknown) {
|
||||
furi_string_printf(data->device_name, "Unknown %s", MF_DESFIRE_PROTOCOL_NAME);
|
||||
} else if(name_type == NfcDeviceNameTypeFull) {
|
||||
furi_string_printf(
|
||||
data->device_name,
|
||||
"%s %s %s",
|
||||
MF_DESFIRE_PROTOCOL_NAME,
|
||||
mf_desfire_type_strings[type],
|
||||
mf_desfire_size_strings[size]);
|
||||
} else {
|
||||
furi_string_printf(
|
||||
data->device_name,
|
||||
"%s %s",
|
||||
mf_desfire_type_strings[type],
|
||||
mf_desfire_size_strings[size]);
|
||||
}
|
||||
|
||||
return furi_string_get_cstr(data->device_name);
|
||||
}
|
||||
|
||||
const uint8_t* mf_desfire_get_uid(const MfDesfireData* data, size_t* uid_len) {
|
||||
|
||||
@@ -29,6 +29,28 @@ extern "C" {
|
||||
#define MF_DESFIRE_APP_ID_SIZE (3)
|
||||
#define MF_DESFIRE_VALUE_SIZE (4)
|
||||
|
||||
typedef enum {
|
||||
MfDesfireTypeMF3ICD40,
|
||||
MfDesfireTypeEV1,
|
||||
MfDesfireTypeEV2,
|
||||
MfDesfireTypeEV2XL,
|
||||
MfDesfireTypeEV3,
|
||||
|
||||
MfDesfireTypeUnknown,
|
||||
MfDesfireTypeNum,
|
||||
} MfDesfireType;
|
||||
|
||||
typedef enum {
|
||||
MfDesfireSize2k,
|
||||
MfDesfireSize4k,
|
||||
MfDesfireSize8k,
|
||||
MfDesfireSize16k,
|
||||
MfDesfireSize32k,
|
||||
|
||||
MfDesfireSizeUnknown,
|
||||
MfDesfireSizeNum,
|
||||
} MfDesfireSize;
|
||||
|
||||
typedef struct {
|
||||
uint8_t hw_vendor;
|
||||
uint8_t hw_type;
|
||||
@@ -131,6 +153,7 @@ typedef enum {
|
||||
MfDesfireErrorProtocol,
|
||||
MfDesfireErrorTimeout,
|
||||
MfDesfireErrorAuthentication,
|
||||
MfDesfireErrorCommandNotSupported,
|
||||
} MfDesfireError;
|
||||
|
||||
typedef struct {
|
||||
@@ -141,6 +164,7 @@ typedef struct {
|
||||
SimpleArray* master_key_versions;
|
||||
SimpleArray* application_ids;
|
||||
SimpleArray* applications;
|
||||
FuriString* device_name;
|
||||
} MfDesfireData;
|
||||
|
||||
extern const NfcDeviceBase nfc_device_mf_desfire;
|
||||
|
||||
@@ -82,9 +82,12 @@ static NfcCommand mf_desfire_poller_handler_read_free_memory(MfDesfirePoller* in
|
||||
FURI_LOG_D(TAG, "Read free memory success");
|
||||
instance->state = MfDesfirePollerStateReadMasterKeySettings;
|
||||
} else if(instance->error == MfDesfireErrorNotPresent) {
|
||||
FURI_LOG_D(TAG, "Read free memoty is unsupported");
|
||||
FURI_LOG_D(TAG, "Read free memory is not present");
|
||||
instance->state = MfDesfirePollerStateReadMasterKeySettings;
|
||||
command = NfcCommandReset;
|
||||
} else if(instance->error == MfDesfireErrorCommandNotSupported) {
|
||||
FURI_LOG_D(TAG, "Read free memory is unsupported");
|
||||
instance->state = MfDesfirePollerStateReadMasterKeySettings;
|
||||
} else {
|
||||
FURI_LOG_E(TAG, "Failed to read free memory");
|
||||
iso14443_4a_poller_halt(instance->iso14443_4a_poller);
|
||||
|
||||
@@ -25,6 +25,8 @@ MfDesfireError mf_desfire_process_status_code(uint8_t status_code) {
|
||||
return MfDesfireErrorNone;
|
||||
case MF_DESFIRE_STATUS_AUTHENTICATION_ERROR:
|
||||
return MfDesfireErrorAuthentication;
|
||||
case MF_DESFIRE_STATUS_ILLEGAL_COMMAND_CODE:
|
||||
return MfDesfireErrorCommandNotSupported;
|
||||
default:
|
||||
return MfDesfireErrorProtocol;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user