mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-24 05:34:45 -07:00
ofw pr 4316 MIFARE Plus 2K Cards in SL1 Mode
testing only, for dev branch PR by LuemmelSec https://github.com/flipperdevices/flipperzero-firmware/pull/4316/files TODO: mf_classic_get_total_sectors_num
This commit is contained in:
@@ -16,6 +16,8 @@ typedef struct {
|
||||
|
||||
static const uint32_t mf_classic_data_format_version = 2;
|
||||
|
||||
#define MF_CLASSIC_PLUS2K_SCAN_SECTORS 18
|
||||
|
||||
static const MfClassicFeatures mf_classic_features[MfClassicTypeNum] = {
|
||||
[MfClassicTypeMini] =
|
||||
{
|
||||
@@ -31,6 +33,14 @@ static const MfClassicFeatures mf_classic_features[MfClassicTypeNum] = {
|
||||
.full_name = "Mifare Classic 1K",
|
||||
.type_name = "1K",
|
||||
},
|
||||
[MfClassicTypePlus2k] =
|
||||
{
|
||||
// MIFARE Plus 2K SL1 maps like a 2K Classic: 32 sectors x 4 blocks
|
||||
.sectors_total = 32,
|
||||
.blocks_total = 128,
|
||||
.full_name = "Mifare Plus 2K SL1",
|
||||
.type_name = "Plus 2K",
|
||||
},
|
||||
[MfClassicType4k] =
|
||||
{
|
||||
.sectors_total = 40,
|
||||
@@ -387,6 +397,14 @@ uint8_t mf_classic_get_total_sectors_num(MfClassicType type) {
|
||||
return mf_classic_features[type].sectors_total;
|
||||
}
|
||||
|
||||
uint8_t mf_classic_get_scannable_sectors_num(MfClassicType type) {
|
||||
uint8_t total = mf_classic_get_total_sectors_num(type);
|
||||
if((type == MfClassicTypePlus2k) && (total > MF_CLASSIC_PLUS2K_SCAN_SECTORS)) {
|
||||
return MF_CLASSIC_PLUS2K_SCAN_SECTORS;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
uint16_t mf_classic_get_total_block_num(MfClassicType type) {
|
||||
furi_check(type < MfClassicTypeNum);
|
||||
return mf_classic_features[type].blocks_total;
|
||||
@@ -546,7 +564,7 @@ void mf_classic_set_key_not_found(
|
||||
MfClassicKey
|
||||
mf_classic_get_key(const MfClassicData* data, uint8_t sector_num, MfClassicKeyType key_type) {
|
||||
furi_check(data);
|
||||
furi_check(sector_num < mf_classic_get_total_sectors_num(data->type));
|
||||
furi_check(sector_num < mf_classic_get_scannable_sectors_num(data->type));
|
||||
furi_check(key_type == MfClassicKeyTypeA || key_type == MfClassicKeyTypeB);
|
||||
|
||||
const MfClassicSectorTrailer* sector_trailer =
|
||||
@@ -606,7 +624,7 @@ void mf_classic_get_read_sectors_and_keys(
|
||||
|
||||
*sectors_read = 0;
|
||||
*keys_found = 0;
|
||||
uint8_t sectors_total = mf_classic_get_total_sectors_num(data->type);
|
||||
uint8_t sectors_total = mf_classic_get_scannable_sectors_num(data->type);
|
||||
for(size_t i = 0; i < sectors_total; i++) {
|
||||
if(mf_classic_is_key_found(data, i, MfClassicKeyTypeA)) {
|
||||
*keys_found += 1;
|
||||
@@ -630,7 +648,7 @@ void mf_classic_get_read_sectors_and_keys(
|
||||
bool mf_classic_is_card_read(const MfClassicData* data) {
|
||||
furi_check(data);
|
||||
|
||||
uint8_t sectors_total = mf_classic_get_total_sectors_num(data->type);
|
||||
uint8_t sectors_total = mf_classic_get_scannable_sectors_num(data->type);
|
||||
uint8_t sectors_read = 0;
|
||||
uint8_t keys_found = 0;
|
||||
mf_classic_get_read_sectors_and_keys(data, §ors_read, &keys_found);
|
||||
|
||||
@@ -48,6 +48,7 @@ typedef enum {
|
||||
typedef enum {
|
||||
MfClassicTypeMini,
|
||||
MfClassicType1k,
|
||||
MfClassicTypePlus2k,
|
||||
MfClassicType4k,
|
||||
|
||||
MfClassicTypeNum,
|
||||
@@ -171,6 +172,8 @@ Iso14443_3aData* mf_classic_get_base_data(const MfClassicData* data);
|
||||
|
||||
uint8_t mf_classic_get_total_sectors_num(MfClassicType type);
|
||||
|
||||
uint8_t mf_classic_get_scannable_sectors_num(MfClassicType type);
|
||||
|
||||
uint16_t mf_classic_get_total_block_num(MfClassicType type);
|
||||
|
||||
uint8_t mf_classic_get_first_block_num_of_sector(uint8_t sector);
|
||||
|
||||
@@ -134,6 +134,22 @@ NfcCommand mf_classic_poller_handler_detect_type(MfClassicPoller* instance) {
|
||||
instance->state = MfClassicPollerStateStart;
|
||||
instance->current_type_check = MfClassicType4k;
|
||||
FURI_LOG_D(TAG, "4K detected");
|
||||
} else {
|
||||
instance->current_type_check = MfClassicTypePlus2k;
|
||||
}
|
||||
} else if(instance->current_type_check == MfClassicTypePlus2k) {
|
||||
// Second-last block in sector 16, which may exist if said sector is not in SL3 mode
|
||||
MfClassicError error =
|
||||
mf_classic_poller_get_nt(instance, 66, MfClassicKeyTypeA, NULL, false);
|
||||
if(error != MfClassicErrorNone) {
|
||||
// If sector 16 is locked/SL3, try sector 17 as well before falling back
|
||||
error = mf_classic_poller_get_nt(instance, 70, MfClassicKeyTypeA, NULL, false);
|
||||
}
|
||||
if(error == MfClassicErrorNone) {
|
||||
instance->data->type = MfClassicTypePlus2k;
|
||||
instance->state = MfClassicPollerStateStart;
|
||||
instance->current_type_check = MfClassicType4k;
|
||||
FURI_LOG_D(TAG, "Plus 2K detected");
|
||||
} else {
|
||||
instance->current_type_check = MfClassicType1k;
|
||||
}
|
||||
@@ -157,7 +173,7 @@ NfcCommand mf_classic_poller_handler_detect_type(MfClassicPoller* instance) {
|
||||
NfcCommand mf_classic_poller_handler_start(MfClassicPoller* instance) {
|
||||
NfcCommand command = NfcCommandContinue;
|
||||
|
||||
instance->sectors_total = mf_classic_get_total_sectors_num(instance->data->type);
|
||||
instance->sectors_total = mf_classic_get_scannable_sectors_num(instance->data->type);
|
||||
memset(&instance->mode_ctx, 0, sizeof(MfClassicPollerModeContext));
|
||||
|
||||
instance->mfc_event.type = MfClassicPollerEventTypeRequestMode;
|
||||
|
||||
Reference in New Issue
Block a user