1
mirror of https://github.com/flipperdevices/flipperzero-firmware.git synced 2025-12-12 04:41:26 +04:00

nfc: Fix MIFARE Plus detection (#4049)

* nfc: Fix MIFARE Plus detection
  MIFARE Plus original doesn't have GetVersion support, so detection for SL2 has been moved. Also, SL2 only exists in MIFARE Plus X, so despite it not being specified in the type identification procedure chart, it's safe to call it for what it is.
* Fix spelling
* TODO: mark as non flipper one

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
Yukai Li
2025-01-12 11:15:52 -07:00
committed by GitHub
parent 35c1bfc057
commit a0d1d3fa0f
2 changed files with 74 additions and 55 deletions

View File

@@ -27,21 +27,8 @@ MfPlusError mf_plus_get_type_from_version(
MfPlusError error = MfPlusErrorProtocol; MfPlusError error = MfPlusErrorProtocol;
if(mf_plus_data->version.hw_major == 0x02 || mf_plus_data->version.hw_major == 0x82) { if(mf_plus_data->version.hw_type == 0x02 || mf_plus_data->version.hw_type == 0x82) {
error = MfPlusErrorNone; error = MfPlusErrorNone;
if(iso14443_4a_data->iso14443_3a_data->sak == 0x10) {
// Mifare Plus 2K SL2
mf_plus_data->type = MfPlusTypePlus;
mf_plus_data->size = MfPlusSize2K;
mf_plus_data->security_level = MfPlusSecurityLevel2;
FURI_LOG_D(TAG, "Mifare Plus 2K SL2");
} else if(iso14443_4a_data->iso14443_3a_data->sak == 0x11) {
// Mifare Plus 4K SL3
mf_plus_data->type = MfPlusTypePlus;
mf_plus_data->size = MfPlusSize4K;
mf_plus_data->security_level = MfPlusSecurityLevel3;
FURI_LOG_D(TAG, "Mifare Plus 4K SL3");
} else {
// Mifare Plus EV1/EV2 // Mifare Plus EV1/EV2
// Revision // Revision
@@ -80,12 +67,11 @@ MfPlusError mf_plus_get_type_from_version(
if(iso14443_4a_data->iso14443_3a_data->sak == 0x20) { if(iso14443_4a_data->iso14443_3a_data->sak == 0x20) {
// Mifare Plus EV1/2 SL3 // Mifare Plus EV1/2 SL3
mf_plus_data->security_level = MfPlusSecurityLevel3; mf_plus_data->security_level = MfPlusSecurityLevel3;
FURI_LOG_D(TAG, "Miare Plus EV1/2 SL3"); FURI_LOG_D(TAG, "Mifare Plus EV1/2 SL3");
} else { } else {
// Mifare Plus EV1/2 SL1 // Mifare Plus EV1/2 SL1
mf_plus_data->security_level = MfPlusSecurityLevel1; mf_plus_data->security_level = MfPlusSecurityLevel1;
FURI_LOG_D(TAG, "Miare Plus EV1/2 SL1"); FURI_LOG_D(TAG, "Mifare Plus EV1/2 SL1");
}
} }
} }
@@ -148,6 +134,24 @@ MfPlusError
FURI_LOG_D(TAG, "Sak 08 but no known Mifare Plus type"); FURI_LOG_D(TAG, "Sak 08 but no known Mifare Plus type");
} }
break;
case 0x10:
// Mifare Plus X 2K SL2
mf_plus_data->type = MfPlusTypeX;
mf_plus_data->size = MfPlusSize2K;
mf_plus_data->security_level = MfPlusSecurityLevel2;
FURI_LOG_D(TAG, "Mifare Plus X 2K SL2");
error = MfPlusErrorNone;
break;
case 0x11:
// Mifare Plus X 4K SL2
mf_plus_data->type = MfPlusTypeX;
mf_plus_data->size = MfPlusSize4K;
mf_plus_data->security_level = MfPlusSecurityLevel2;
FURI_LOG_D(TAG, "Mifare Plus X 4K SL2");
error = MfPlusErrorNone;
break; break;
case 0x18: case 0x18:
if(memcmp( if(memcmp(
@@ -234,10 +238,22 @@ MfPlusError
} }
MfPlusError mf_plus_version_parse(MfPlusVersion* data, const BitBuffer* buf) { MfPlusError mf_plus_version_parse(MfPlusVersion* data, const BitBuffer* buf) {
const bool can_parse = bit_buffer_get_size_bytes(buf) == sizeof(MfPlusVersion); bool can_parse = bit_buffer_get_size_bytes(buf) == sizeof(MfPlusVersion);
if(can_parse) { if(can_parse) {
bit_buffer_write_bytes(buf, data, sizeof(MfPlusVersion)); bit_buffer_write_bytes(buf, data, sizeof(MfPlusVersion));
} else if(
bit_buffer_get_size_bytes(buf) == 8 &&
bit_buffer_get_byte(buf, 0) == MF_PLUS_STATUS_ADDITIONAL_FRAME) {
// HACK(-nofl): There are supposed to be three parts to the GetVersion command,
// with the second and third parts fetched by sending the AdditionalFrame
// command. I don't know whether the entire MIFARE Plus line uses status as
// the first byte, so let's just assume we only have the first part of
// the response if it's size 8 and starts with the AF status. The second
// part of the response is the same size and status byte, but so far
// we're only reading one response.
can_parse = true;
bit_buffer_write_bytes_mid(buf, data, 1, bit_buffer_get_size_bytes(buf) - 1);
} }
return can_parse ? MfPlusErrorNone : MfPlusErrorProtocol; return can_parse ? MfPlusErrorNone : MfPlusErrorProtocol;

View File

@@ -4,6 +4,9 @@
#define MF_PLUS_FFF_PICC_PREFIX "PICC" #define MF_PLUS_FFF_PICC_PREFIX "PICC"
#define MF_PLUS_STATUS_OPERATION_OK (0x90)
#define MF_PLUS_STATUS_ADDITIONAL_FRAME (0xAF)
MfPlusError mf_plus_get_type_from_version( MfPlusError mf_plus_get_type_from_version(
const Iso14443_4aData* iso14443_4a_data, const Iso14443_4aData* iso14443_4a_data,
MfPlusData* mf_plus_data); MfPlusData* mf_plus_data);