Proper detection (WIP)

This commit is contained in:
Astra 2024-04-19 20:43:18 +09:00
parent 7189026335
commit 9042009b0b
4 changed files with 116 additions and 4 deletions

View file

@ -17,6 +17,88 @@ const MfPlusData* mf_plus_poller_get_data(MfPlusPoller* instance) {
return instance->data;
}
bool mf_plus_poller_get_type_from_iso4(const Iso14443_4aData* iso4_data, MfPlusData* mf_plus_data) {
furi_assert(iso4_data);
furi_assert(mf_plus_data);
switch(iso4_data->iso14443_3a_data->sak) {
case 0x08:
if(memcmp(iso4_data->ats_data.t1_tk, "\xC1\x05\x2F\x2F\x00\x35\xC7", 7) == 0) {
// Mifare Plus S 2K SL1
mf_plus_data->type = MfPlusTypeS;
mf_plus_data->size = MfPlusSize2K;
mf_plus_data->security_level = MfPlusSecurityLevel1;
return true;
} else if(memcmp(iso4_data->ats_data.t1_tk, "\xC1\x05\x2F\x2F\x01\xBC\xD6", 7) == 0) {
// Mifare Plus X 2K SL1
mf_plus_data->type = MfPlusTypeX;
mf_plus_data->size = MfPlusSize2K;
mf_plus_data->security_level = MfPlusSecurityLevel1;
return true;
} else if(
memcmp(iso4_data->ats_data.t1_tk, "\xC1\x05\x2F\x2F\x00\xF6\xD1", 7) == 0 ||
memcmp(iso4_data->ats_data.t1_tk, "\xC1\x05\x2F\x2F\x01\xF6\xD1", 7) == 0) {
// Mifare Plus SE 1K SL1
mf_plus_data->type = MfPlusTypeSE;
mf_plus_data->size = MfPlusSize1K;
mf_plus_data->security_level = MfPlusSecurityLevel1;
return true;
} else {
return false;
}
case 0x18:
if(memcmp(iso4_data->ats_data.t1_tk, "\xC1\x05\x2F\x2F\x00\x35\xC7", 7) == 0) {
// Mifare Plus S 4K SL1
mf_plus_data->type = MfPlusTypeS;
mf_plus_data->size = MfPlusSize4K;
mf_plus_data->security_level = MfPlusSecurityLevel1;
return true;
} else if(memcmp(iso4_data->ats_data.t1_tk, "\xC1\x05\x2F\x2F\x01\xBC\xD6", 7) == 0) {
// Mifare Plus X 4K SL1
mf_plus_data->type = MfPlusTypeX;
mf_plus_data->size = MfPlusSize4K;
mf_plus_data->security_level = MfPlusSecurityLevel1;
return true;
} else {
return false;
}
case 0x20:
if(memcmp(iso4_data->ats_data.t1_tk, "\xC1\x05\x2F\x2F\x00\x35\xC7", 7) == 0) {
// Mifare Plus S 2/4K SL3
mf_plus_data->type = MfPlusTypeS;
mf_plus_data->security_level = MfPlusSecurityLevel3;
if(iso4_data->iso14443_3a_data->atqa[1] == 0x04) {
//
mf_plus_data->size = MfPlusSize2K;
} else if(iso4_data->iso14443_3a_data->atqa[1] == 0x02) {
mf_plus_data->size = MfPlusSize4K;
} else {
return false;
}
return true;
} else if(memcmp(iso4_data->ats_data.t1_tk, "\xC1\x05\x2F\x2F\x01\xBC\xD6", 7) == 0) {
mf_plus_data->type = MfPlusTypeX;
mf_plus_data->security_level = MfPlusSecurityLevel3;
if(iso4_data->iso14443_3a_data->atqa[1] == 0x04) {
mf_plus_data->size = MfPlusSize2K;
} else if(iso4_data->iso14443_3a_data->atqa[1] == 0x02) {
mf_plus_data->size = MfPlusSize4K;
} else {
return false;
}
return true;
} else {
return false;
}
}
return false;
}
MfPlusPoller* mf_plus_poller_alloc(Iso14443_4aPoller* iso14443_4a_poller) {
furi_assert(iso14443_4a_poller);
@ -27,6 +109,11 @@ MfPlusPoller* mf_plus_poller_alloc(Iso14443_4aPoller* iso14443_4a_poller) {
instance->data = mf_plus_alloc();
instance->tx_buffer = bit_buffer_alloc(MF_PLUS_BUF_SIZE);
instance->rx_buffer = bit_buffer_alloc(MF_PLUS_BUF_SIZE);
instance->input_buffer = bit_buffer_alloc(MF_PLUS_BUF_SIZE);
instance->result_buffer = bit_buffer_alloc(MF_PLUS_RESULT_BUF_SIZE);
instance->general_event.protocol = NfcProtocolMfPlus;
instance->general_event.event_data = &instance->mfp_event;
instance->general_event.instance = instance;
@ -126,25 +213,36 @@ void mf_plus_poller_free(MfPlusPoller* instance) {
furi_assert(instance);
furi_assert(instance->data);
bit_buffer_free(instance->tx_buffer);
bit_buffer_free(instance->rx_buffer);
bit_buffer_free(instance->input_buffer);
bit_buffer_free(instance->result_buffer);
mf_plus_free(instance->data);
free(instance);
}
bool mf_plus_poller_detect(NfcGenericEvent event, void* context) {
furi_assert(event.event_data);
static bool mf_plus_poller_detect(NfcGenericEvent event, void* context) {
furi_assert(event.protocol = NfcProtocolIso14443_4a);
furi_assert(context);
MfPlusPoller* instance = context;
furi_assert(instance);
Iso14443_4aPollerEvent* iso14443_4a_event = event.event_data;
furi_assert(iso14443_4a_event);
bool detected = false;
if(iso14443_4a_event->type == Iso14443_4aPollerEventTypeReady) {
MfPlusVersion version = {};
const MfPlusError error = mf_plus_poller_read_version(instance, &version);
detected = (error == MfPlusErrorNone);
if(error == MfPlusErrorNone) {
if(version.hw_major == 0x02 || version.hw_major == 0x82) {
detected = true;
}
} else {
detected = mf_plus_poller_get_type_from_iso4(
iso14443_4a_poller_get_data(instance->iso14443_4a_poller), instance->data);
}
}
return detected;

View file

@ -0,0 +1,5 @@
#pragma once
#include <nfc/protocols/nfc_poller_base.h>
extern const NfcPollerBase mf_plus_poller;

View file

@ -8,6 +8,7 @@
#include <nfc/protocols/felica/felica_poller_defs.h>
#include <nfc/protocols/mf_ultralight/mf_ultralight_poller_defs.h>
#include <nfc/protocols/mf_classic/mf_classic_poller_defs.h>
#include <nfc/protocols/mf_plus/mf_plus_poller_defs.h>
#include <nfc/protocols/mf_desfire/mf_desfire_poller_defs.h>
#include <nfc/protocols/slix/slix_poller_defs.h>
#include <nfc/protocols/st25tb/st25tb_poller_defs.h>
@ -21,6 +22,7 @@ const NfcPollerBase* nfc_pollers_api[NfcProtocolNum] = {
[NfcProtocolFelica] = &nfc_poller_felica,
[NfcProtocolMfUltralight] = &mf_ultralight_poller,
[NfcProtocolMfClassic] = &mf_classic_poller,
[NfcProtocolMfPlus] = &mf_plus_poller,
[NfcProtocolMfDesfire] = &mf_desfire_poller,
[NfcProtocolSlix] = &nfc_poller_slix,
/* Add new pollers here */

View file

@ -61,6 +61,7 @@ static const NfcProtocol nfc_protocol_iso14443_3b_children_protocol[] = {
/** List of ISO14443-4A child protocols. */
static const NfcProtocol nfc_protocol_iso14443_4a_children_protocol[] = {
NfcProtocolMfDesfire,
NfcProtocolMfPlus,
};
/** List of ISO115693-3 child protocols. */
@ -128,6 +129,12 @@ static const NfcProtocolTreeNode nfc_protocol_nodes[NfcProtocolNum] = {
.children_num = 0,
.children_protocol = NULL,
},
[NfcProtocolMfPlus] =
{
.parent_protocol = NfcProtocolIso14443_4a,
.children_num = 0,
.children_protocol = NULL,
},
[NfcProtocolMfDesfire] =
{
.parent_protocol = NfcProtocolIso14443_4a,