mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-24 03:29:57 -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:
@@ -63,7 +63,7 @@ bool mf_classic_key_cache_save(MfClassicKeyCache* instance, const MfClassicData*
|
|||||||
if(!flipper_format_write_hex_uint64(ff, "Key A map", &data->key_a_mask, 1)) break;
|
if(!flipper_format_write_hex_uint64(ff, "Key A map", &data->key_a_mask, 1)) break;
|
||||||
if(!flipper_format_write_hex_uint64(ff, "Key B map", &data->key_b_mask, 1)) break;
|
if(!flipper_format_write_hex_uint64(ff, "Key B map", &data->key_b_mask, 1)) break;
|
||||||
|
|
||||||
uint8_t sector_num = mf_classic_get_total_sectors_num(data->type);
|
uint8_t sector_num = mf_classic_get_scannable_sectors_num(data->type);
|
||||||
bool key_save_success = true;
|
bool key_save_success = true;
|
||||||
for(size_t i = 0; (i < sector_num) && (key_save_success); i++) {
|
for(size_t i = 0; (i < sector_num) && (key_save_success); i++) {
|
||||||
MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, i);
|
MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, i);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ void nfc_render_mf_classic_info(
|
|||||||
FuriString* str) {
|
FuriString* str) {
|
||||||
nfc_render_iso14443_3a_info(data->iso14443_3a_data, format_type, str);
|
nfc_render_iso14443_3a_info(data->iso14443_3a_data, format_type, str);
|
||||||
|
|
||||||
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 keys_total = sectors_total * 2;
|
uint8_t keys_total = sectors_total * 2;
|
||||||
uint8_t keys_found = 0;
|
uint8_t keys_found = 0;
|
||||||
uint8_t sectors_read = 0;
|
uint8_t sectors_read = 0;
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ static bool aime_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
|
|
||||||
data->type = type;
|
data->type = type;
|
||||||
MfClassicDeviceKeys keys = {};
|
MfClassicDeviceKeys keys = {};
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
bit_lib_num_to_bytes_be(aime_key, sizeof(MfClassicKey), keys.key_a[i].data);
|
bit_lib_num_to_bytes_be(aime_key, sizeof(MfClassicKey), keys.key_a[i].data);
|
||||||
FURI_BIT_SET(keys.key_a_mask, i);
|
FURI_BIT_SET(keys.key_a_mask, i);
|
||||||
bit_lib_num_to_bytes_be(aime_key, sizeof(MfClassicKey), keys.key_b[i].data);
|
bit_lib_num_to_bytes_be(aime_key, sizeof(MfClassicKey), keys.key_b[i].data);
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ static bool banapass_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
MfClassicDeviceKeys keys = {};
|
MfClassicDeviceKeys keys = {};
|
||||||
|
|
||||||
// Access Code Read Attempt
|
// Access Code Read Attempt
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
bit_lib_num_to_bytes_be(
|
bit_lib_num_to_bytes_be(
|
||||||
banapass_keys_if_access_code[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
banapass_keys_if_access_code[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
||||||
FURI_BIT_SET(keys.key_a_mask, i);
|
FURI_BIT_SET(keys.key_a_mask, i);
|
||||||
@@ -116,7 +116,7 @@ static bool banapass_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Value Block Read Attempt
|
// Value Block Read Attempt
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
bit_lib_num_to_bytes_be(
|
bit_lib_num_to_bytes_be(
|
||||||
banapass_keys_if_value_block[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
banapass_keys_if_value_block[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
||||||
FURI_BIT_SET(keys.key_a_mask, i);
|
FURI_BIT_SET(keys.key_a_mask, i);
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ static bool bip_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
.key_a_mask = 0,
|
.key_a_mask = 0,
|
||||||
.key_b_mask = 0,
|
.key_b_mask = 0,
|
||||||
};
|
};
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
bit_lib_num_to_bytes_be(bip_1k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
bit_lib_num_to_bytes_be(bip_1k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
||||||
FURI_BIT_SET(keys.key_a_mask, i);
|
FURI_BIT_SET(keys.key_a_mask, i);
|
||||||
bit_lib_num_to_bytes_be(bip_1k_keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data);
|
bit_lib_num_to_bytes_be(bip_1k_keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data);
|
||||||
|
|||||||
@@ -1230,7 +1230,7 @@ static bool charliecard_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
.key_a_mask = 0,
|
.key_a_mask = 0,
|
||||||
.key_b_mask = 0,
|
.key_b_mask = 0,
|
||||||
};
|
};
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
bit_lib_num_to_bytes_be(
|
bit_lib_num_to_bytes_be(
|
||||||
charliecard_1k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
charliecard_1k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
||||||
FURI_BIT_SET(keys.key_a_mask, i);
|
FURI_BIT_SET(keys.key_a_mask, i);
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ static bool disney_infinity_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
if(error != MfClassicErrorNone) break;
|
if(error != MfClassicErrorNone) break;
|
||||||
|
|
||||||
data->type = type;
|
data->type = type;
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
di_key(uid_bytes, &keys.key_a[i]);
|
di_key(uid_bytes, &keys.key_a[i]);
|
||||||
di_key(uid_bytes, &keys.key_b[i]);
|
di_key(uid_bytes, &keys.key_b[i]);
|
||||||
FURI_BIT_SET(keys.key_a_mask, i);
|
FURI_BIT_SET(keys.key_a_mask, i);
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ static bool hi_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
uint8_t keyB[HI_KEY_TO_GEN][KEY_LENGTH];
|
uint8_t keyB[HI_KEY_TO_GEN][KEY_LENGTH];
|
||||||
hi_generate_key(uid, keyA, keyB);
|
hi_generate_key(uid, keyA, keyB);
|
||||||
|
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
if(cfg.keys[i].a == 0x000000000000 && cfg.keys[i].b == 0x000000000000) {
|
if(cfg.keys[i].a == 0x000000000000 && cfg.keys[i].b == 0x000000000000) {
|
||||||
cfg.keys[i].a = bit_lib_bytes_to_num_be(keyA[i], KEY_LENGTH);
|
cfg.keys[i].a = bit_lib_bytes_to_num_be(keyA[i], KEY_LENGTH);
|
||||||
cfg.keys[i].b = bit_lib_bytes_to_num_be(keyB[i], KEY_LENGTH);
|
cfg.keys[i].b = bit_lib_bytes_to_num_be(keyB[i], KEY_LENGTH);
|
||||||
@@ -146,7 +146,7 @@ static bool hi_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MfClassicDeviceKeys keys = {};
|
MfClassicDeviceKeys keys = {};
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
bit_lib_num_to_bytes_be(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
bit_lib_num_to_bytes_be(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
||||||
FURI_BIT_SET(keys.key_a_mask, i);
|
FURI_BIT_SET(keys.key_a_mask, i);
|
||||||
bit_lib_num_to_bytes_be(cfg.keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data);
|
bit_lib_num_to_bytes_be(cfg.keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data);
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ static bool hid_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
|
|
||||||
data->type = type;
|
data->type = type;
|
||||||
MfClassicDeviceKeys keys = {};
|
MfClassicDeviceKeys keys = {};
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
bit_lib_num_to_bytes_be(hid_key, sizeof(MfClassicKey), keys.key_a[i].data);
|
bit_lib_num_to_bytes_be(hid_key, sizeof(MfClassicKey), keys.key_a[i].data);
|
||||||
FURI_BIT_SET(keys.key_a_mask, i);
|
FURI_BIT_SET(keys.key_a_mask, i);
|
||||||
bit_lib_num_to_bytes_be(hid_key, sizeof(MfClassicKey), keys.key_b[i].data);
|
bit_lib_num_to_bytes_be(hid_key, sizeof(MfClassicKey), keys.key_b[i].data);
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ static bool hworld_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
data->type = type;
|
data->type = type;
|
||||||
|
|
||||||
MfClassicDeviceKeys standard_keys = {};
|
MfClassicDeviceKeys standard_keys = {};
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
bit_lib_num_to_bytes_be(
|
bit_lib_num_to_bytes_be(
|
||||||
hworld_standard_keys[i].a, sizeof(MfClassicKey), standard_keys.key_a[i].data);
|
hworld_standard_keys[i].a, sizeof(MfClassicKey), standard_keys.key_a[i].data);
|
||||||
FURI_BIT_SET(standard_keys.key_a_mask, i);
|
FURI_BIT_SET(standard_keys.key_a_mask, i);
|
||||||
@@ -130,7 +130,7 @@ static bool hworld_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
FURI_LOG_I(TAG, "Standard card successfully read");
|
FURI_LOG_I(TAG, "Standard card successfully read");
|
||||||
} else {
|
} else {
|
||||||
MfClassicDeviceKeys vip_keys = {};
|
MfClassicDeviceKeys vip_keys = {};
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
bit_lib_num_to_bytes_be(
|
bit_lib_num_to_bytes_be(
|
||||||
hworld_vip_keys[i].a, sizeof(MfClassicKey), vip_keys.key_a[i].data);
|
hworld_vip_keys[i].a, sizeof(MfClassicKey), vip_keys.key_a[i].data);
|
||||||
FURI_BIT_SET(vip_keys.key_a_mask, i);
|
FURI_BIT_SET(vip_keys.key_a_mask, i);
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ static bool kazan_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
.key_b_mask = 0,
|
.key_b_mask = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
bit_lib_num_to_bytes_be(
|
bit_lib_num_to_bytes_be(
|
||||||
kazan_1k_keys_v1[i].a, sizeof(MfClassicKey), keys_v1.key_a[i].data);
|
kazan_1k_keys_v1[i].a, sizeof(MfClassicKey), keys_v1.key_a[i].data);
|
||||||
bit_lib_num_to_bytes_be(
|
bit_lib_num_to_bytes_be(
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ static bool metromoney_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
.key_a_mask = 0,
|
.key_a_mask = 0,
|
||||||
.key_b_mask = 0,
|
.key_b_mask = 0,
|
||||||
};
|
};
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
bit_lib_num_to_bytes_be(
|
bit_lib_num_to_bytes_be(
|
||||||
metromoney_1k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
metromoney_1k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
||||||
FURI_BIT_SET(keys.key_a_mask, i);
|
FURI_BIT_SET(keys.key_a_mask, i);
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ static bool microel_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save keys generated to stucture
|
// Save keys generated to stucture
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
if(microel_1k_keys[i].a == 0x000000000000) {
|
if(microel_1k_keys[i].a == 0x000000000000) {
|
||||||
microel_1k_keys[i].a = bit_lib_bytes_to_num_be(keyA, KEY_LENGTH);
|
microel_1k_keys[i].a = bit_lib_bytes_to_num_be(keyA, KEY_LENGTH);
|
||||||
}
|
}
|
||||||
@@ -137,7 +137,7 @@ static bool microel_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
MfClassicDeviceKeys keys = {};
|
MfClassicDeviceKeys keys = {};
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
bit_lib_num_to_bytes_be(
|
bit_lib_num_to_bytes_be(
|
||||||
microel_1k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
microel_1k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
||||||
FURI_BIT_SET(keys.key_a_mask, i);
|
FURI_BIT_SET(keys.key_a_mask, i);
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ static bool mizip_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
uint8_t keyB[MIZIP_KEY_TO_GEN][KEY_LENGTH];
|
uint8_t keyB[MIZIP_KEY_TO_GEN][KEY_LENGTH];
|
||||||
mizip_generate_key(uid, keyA, keyB);
|
mizip_generate_key(uid, keyA, keyB);
|
||||||
|
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
if(cfg.keys[i].a == 0x000000000000 && cfg.keys[i].b == 0x000000000000) {
|
if(cfg.keys[i].a == 0x000000000000 && cfg.keys[i].b == 0x000000000000) {
|
||||||
cfg.keys[i].a = bit_lib_bytes_to_num_be(keyA[i], KEY_LENGTH);
|
cfg.keys[i].a = bit_lib_bytes_to_num_be(keyA[i], KEY_LENGTH);
|
||||||
cfg.keys[i].b = bit_lib_bytes_to_num_be(keyB[i], KEY_LENGTH);
|
cfg.keys[i].b = bit_lib_bytes_to_num_be(keyB[i], KEY_LENGTH);
|
||||||
@@ -159,7 +159,7 @@ static bool mizip_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MfClassicDeviceKeys keys = {};
|
MfClassicDeviceKeys keys = {};
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
bit_lib_num_to_bytes_be(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
bit_lib_num_to_bytes_be(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
||||||
FURI_BIT_SET(keys.key_a_mask, i);
|
FURI_BIT_SET(keys.key_a_mask, i);
|
||||||
bit_lib_num_to_bytes_be(cfg.keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data);
|
bit_lib_num_to_bytes_be(cfg.keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data);
|
||||||
|
|||||||
@@ -899,7 +899,7 @@ static bool ndef_mfc_parse(const NfcDevice* device, FuriString* parsed_data) {
|
|||||||
|
|
||||||
// Check MADs for what sectors contain NDEF data AIDs
|
// Check MADs for what sectors contain NDEF data AIDs
|
||||||
bool sectors_with_ndef[MF_CLASSIC_TOTAL_SECTORS_MAX] = {0};
|
bool sectors_with_ndef[MF_CLASSIC_TOTAL_SECTORS_MAX] = {0};
|
||||||
const size_t sector_count = mf_classic_get_total_sectors_num(data->type);
|
const size_t sector_count = mf_classic_get_scannable_sectors_num(data->type);
|
||||||
const struct {
|
const struct {
|
||||||
size_t block;
|
size_t block;
|
||||||
uint8_t aid_count;
|
uint8_t aid_count;
|
||||||
|
|||||||
@@ -176,7 +176,7 @@ static bool plantain_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MfClassicDeviceKeys keys = {};
|
MfClassicDeviceKeys keys = {};
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
bit_lib_num_to_bytes_be(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
bit_lib_num_to_bytes_be(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
||||||
FURI_BIT_SET(keys.key_a_mask, i);
|
FURI_BIT_SET(keys.key_a_mask, i);
|
||||||
bit_lib_num_to_bytes_be(cfg.keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data);
|
bit_lib_num_to_bytes_be(cfg.keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data);
|
||||||
|
|||||||
@@ -240,14 +240,14 @@ static bool saflok_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
uint64_t num_key = bit_lib_bytes_to_num_be(key, KEY_LENGTH);
|
uint64_t num_key = bit_lib_bytes_to_num_be(key, KEY_LENGTH);
|
||||||
FURI_LOG_D(TAG, "Saflok: Key generated for UID: %012llX", num_key);
|
FURI_LOG_D(TAG, "Saflok: Key generated for UID: %012llX", num_key);
|
||||||
|
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
if(saflok_1k_keys[i].a == 0x000000000000) {
|
if(saflok_1k_keys[i].a == 0x000000000000) {
|
||||||
saflok_1k_keys[i].a = num_key;
|
saflok_1k_keys[i].a = num_key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MfClassicDeviceKeys keys = {};
|
MfClassicDeviceKeys keys = {};
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
bit_lib_num_to_bytes_be(saflok_1k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
bit_lib_num_to_bytes_be(saflok_1k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
||||||
FURI_BIT_SET(keys.key_a_mask, i);
|
FURI_BIT_SET(keys.key_a_mask, i);
|
||||||
bit_lib_num_to_bytes_be(saflok_1k_keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data);
|
bit_lib_num_to_bytes_be(saflok_1k_keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data);
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ static bool skylanders_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
|
|
||||||
data->type = type;
|
data->type = type;
|
||||||
MfClassicDeviceKeys keys = {};
|
MfClassicDeviceKeys keys = {};
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
if(i == 0) {
|
if(i == 0) {
|
||||||
bit_lib_num_to_bytes_be(skylanders_key, sizeof(MfClassicKey), keys.key_a[i].data);
|
bit_lib_num_to_bytes_be(skylanders_key, sizeof(MfClassicKey), keys.key_a[i].data);
|
||||||
FURI_BIT_SET(keys.key_a_mask, i);
|
FURI_BIT_SET(keys.key_a_mask, i);
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ static bool smartrider_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
data->type = type;
|
data->type = type;
|
||||||
|
|
||||||
MfClassicDeviceKeys keys = {.key_a_mask = 0, .key_b_mask = 0};
|
MfClassicDeviceKeys keys = {.key_a_mask = 0, .key_b_mask = 0};
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
memcpy(keys.key_a[i].data, STANDARD_KEYS[i == 0 ? 0 : 1], sizeof(STANDARD_KEYS[0]));
|
memcpy(keys.key_a[i].data, STANDARD_KEYS[i == 0 ? 0 : 1], sizeof(STANDARD_KEYS[0]));
|
||||||
if(i > 0) {
|
if(i > 0) {
|
||||||
memcpy(keys.key_b[i].data, STANDARD_KEYS[2], sizeof(STANDARD_KEYS[0]));
|
memcpy(keys.key_b[i].data, STANDARD_KEYS[2], sizeof(STANDARD_KEYS[0]));
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ static bool social_moscow_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
if(!social_moscow_get_card_config(&cfg, data->type)) break;
|
if(!social_moscow_get_card_config(&cfg, data->type)) break;
|
||||||
|
|
||||||
MfClassicDeviceKeys keys = {};
|
MfClassicDeviceKeys keys = {};
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
bit_lib_num_to_bytes_be(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
bit_lib_num_to_bytes_be(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
||||||
FURI_BIT_SET(keys.key_a_mask, i);
|
FURI_BIT_SET(keys.key_a_mask, i);
|
||||||
bit_lib_num_to_bytes_be(cfg.keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data);
|
bit_lib_num_to_bytes_be(cfg.keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data);
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ static bool troika_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
.key_a_mask = 0,
|
.key_a_mask = 0,
|
||||||
.key_b_mask = 0,
|
.key_b_mask = 0,
|
||||||
};
|
};
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
bit_lib_num_to_bytes_be(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
bit_lib_num_to_bytes_be(cfg.keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
||||||
FURI_BIT_SET(keys.key_a_mask, i);
|
FURI_BIT_SET(keys.key_a_mask, i);
|
||||||
bit_lib_num_to_bytes_be(cfg.keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data);
|
bit_lib_num_to_bytes_be(cfg.keys[i].b, sizeof(MfClassicKey), keys.key_b[i].data);
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ static bool two_cities_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
|
|
||||||
data->type = type;
|
data->type = type;
|
||||||
MfClassicDeviceKeys keys = {};
|
MfClassicDeviceKeys keys = {};
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
bit_lib_num_to_bytes_be(
|
bit_lib_num_to_bytes_be(
|
||||||
two_cities_4k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
two_cities_4k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
||||||
FURI_BIT_SET(keys.key_a_mask, i);
|
FURI_BIT_SET(keys.key_a_mask, i);
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ static bool washcity_read(Nfc* nfc, NfcDevice* device) {
|
|||||||
.key_a_mask = 0,
|
.key_a_mask = 0,
|
||||||
.key_b_mask = 0,
|
.key_b_mask = 0,
|
||||||
};
|
};
|
||||||
for(size_t i = 0; i < mf_classic_get_total_sectors_num(data->type); i++) {
|
for(size_t i = 0; i < mf_classic_get_scannable_sectors_num(data->type); i++) {
|
||||||
bit_lib_num_to_bytes_be(
|
bit_lib_num_to_bytes_be(
|
||||||
washcity_1k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
washcity_1k_keys[i].a, sizeof(MfClassicKey), keys.key_a[i].data);
|
||||||
FURI_BIT_SET(keys.key_a_mask, i);
|
FURI_BIT_SET(keys.key_a_mask, i);
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ NfcCommand nfc_dict_attack_worker_callback(NfcGenericEvent event, void* context)
|
|||||||
|
|
||||||
mfc_event->data->poller_mode.data = mfc_data;
|
mfc_event->data->poller_mode.data = mfc_data;
|
||||||
instance->nfc_dict_context.sectors_total =
|
instance->nfc_dict_context.sectors_total =
|
||||||
mf_classic_get_total_sectors_num(mfc_data->type);
|
mf_classic_get_scannable_sectors_num(mfc_data->type);
|
||||||
mf_classic_get_read_sectors_and_keys(
|
mf_classic_get_read_sectors_and_keys(
|
||||||
mfc_data,
|
mfc_data,
|
||||||
&instance->nfc_dict_context.sectors_read,
|
&instance->nfc_dict_context.sectors_read,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ void nfc_scene_mf_classic_show_keys_on_enter(void* context) {
|
|||||||
|
|
||||||
furi_string_cat_printf(instance->text_box_store, "\e#Found MFC Keys:");
|
furi_string_cat_printf(instance->text_box_store, "\e#Found MFC Keys:");
|
||||||
|
|
||||||
uint8_t num_sectors = mf_classic_get_total_sectors_num(mfc_data->type);
|
uint8_t num_sectors = mf_classic_get_scannable_sectors_num(mfc_data->type);
|
||||||
uint8_t found_keys_a = 0, found_keys_b = 0;
|
uint8_t found_keys_a = 0, found_keys_b = 0;
|
||||||
for(uint8_t i = 0; i < num_sectors; i++) {
|
for(uint8_t i = 0; i < num_sectors; i++) {
|
||||||
MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(mfc_data, i);
|
MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(mfc_data, i);
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ typedef struct {
|
|||||||
|
|
||||||
static const uint32_t mf_classic_data_format_version = 2;
|
static const uint32_t mf_classic_data_format_version = 2;
|
||||||
|
|
||||||
|
#define MF_CLASSIC_PLUS2K_SCAN_SECTORS 18
|
||||||
|
|
||||||
static const MfClassicFeatures mf_classic_features[MfClassicTypeNum] = {
|
static const MfClassicFeatures mf_classic_features[MfClassicTypeNum] = {
|
||||||
[MfClassicTypeMini] =
|
[MfClassicTypeMini] =
|
||||||
{
|
{
|
||||||
@@ -31,6 +33,14 @@ static const MfClassicFeatures mf_classic_features[MfClassicTypeNum] = {
|
|||||||
.full_name = "Mifare Classic 1K",
|
.full_name = "Mifare Classic 1K",
|
||||||
.type_name = "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] =
|
[MfClassicType4k] =
|
||||||
{
|
{
|
||||||
.sectors_total = 40,
|
.sectors_total = 40,
|
||||||
@@ -387,6 +397,14 @@ uint8_t mf_classic_get_total_sectors_num(MfClassicType type) {
|
|||||||
return mf_classic_features[type].sectors_total;
|
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) {
|
uint16_t mf_classic_get_total_block_num(MfClassicType type) {
|
||||||
furi_check(type < MfClassicTypeNum);
|
furi_check(type < MfClassicTypeNum);
|
||||||
return mf_classic_features[type].blocks_total;
|
return mf_classic_features[type].blocks_total;
|
||||||
@@ -546,7 +564,7 @@ void mf_classic_set_key_not_found(
|
|||||||
MfClassicKey
|
MfClassicKey
|
||||||
mf_classic_get_key(const MfClassicData* data, uint8_t sector_num, MfClassicKeyType key_type) {
|
mf_classic_get_key(const MfClassicData* data, uint8_t sector_num, MfClassicKeyType key_type) {
|
||||||
furi_check(data);
|
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);
|
furi_check(key_type == MfClassicKeyTypeA || key_type == MfClassicKeyTypeB);
|
||||||
|
|
||||||
const MfClassicSectorTrailer* sector_trailer =
|
const MfClassicSectorTrailer* sector_trailer =
|
||||||
@@ -606,7 +624,7 @@ void mf_classic_get_read_sectors_and_keys(
|
|||||||
|
|
||||||
*sectors_read = 0;
|
*sectors_read = 0;
|
||||||
*keys_found = 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++) {
|
for(size_t i = 0; i < sectors_total; i++) {
|
||||||
if(mf_classic_is_key_found(data, i, MfClassicKeyTypeA)) {
|
if(mf_classic_is_key_found(data, i, MfClassicKeyTypeA)) {
|
||||||
*keys_found += 1;
|
*keys_found += 1;
|
||||||
@@ -630,7 +648,7 @@ void mf_classic_get_read_sectors_and_keys(
|
|||||||
bool mf_classic_is_card_read(const MfClassicData* data) {
|
bool mf_classic_is_card_read(const MfClassicData* data) {
|
||||||
furi_check(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 sectors_read = 0;
|
||||||
uint8_t keys_found = 0;
|
uint8_t keys_found = 0;
|
||||||
mf_classic_get_read_sectors_and_keys(data, §ors_read, &keys_found);
|
mf_classic_get_read_sectors_and_keys(data, §ors_read, &keys_found);
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ typedef enum {
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
MfClassicTypeMini,
|
MfClassicTypeMini,
|
||||||
MfClassicType1k,
|
MfClassicType1k,
|
||||||
|
MfClassicTypePlus2k,
|
||||||
MfClassicType4k,
|
MfClassicType4k,
|
||||||
|
|
||||||
MfClassicTypeNum,
|
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_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);
|
uint16_t mf_classic_get_total_block_num(MfClassicType type);
|
||||||
|
|
||||||
uint8_t mf_classic_get_first_block_num_of_sector(uint8_t sector);
|
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->state = MfClassicPollerStateStart;
|
||||||
instance->current_type_check = MfClassicType4k;
|
instance->current_type_check = MfClassicType4k;
|
||||||
FURI_LOG_D(TAG, "4K detected");
|
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 {
|
} else {
|
||||||
instance->current_type_check = MfClassicType1k;
|
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 mf_classic_poller_handler_start(MfClassicPoller* instance) {
|
||||||
NfcCommand command = NfcCommandContinue;
|
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));
|
memset(&instance->mode_ctx, 0, sizeof(MfClassicPollerModeContext));
|
||||||
|
|
||||||
instance->mfc_event.type = MfClassicPollerEventTypeRequestMode;
|
instance->mfc_event.type = MfClassicPollerEventTypeRequestMode;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
entry,status,name,type,params
|
entry,status,name,type,params
|
||||||
Version,+,87.1,,
|
Version,+,87.2,,
|
||||||
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
|
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
|
||||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||||
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
|
Header,+,applications/services/bt/bt_service/bt_keys_storage.h,,
|
||||||
@@ -2695,6 +2695,7 @@ Function,+,mf_classic_get_device_name,const char*,"const MfClassicData*, NfcDevi
|
|||||||
Function,+,mf_classic_get_first_block_num_of_sector,uint8_t,uint8_t
|
Function,+,mf_classic_get_first_block_num_of_sector,uint8_t,uint8_t
|
||||||
Function,+,mf_classic_get_key,MfClassicKey,"const MfClassicData*, uint8_t, MfClassicKeyType"
|
Function,+,mf_classic_get_key,MfClassicKey,"const MfClassicData*, uint8_t, MfClassicKeyType"
|
||||||
Function,+,mf_classic_get_read_sectors_and_keys,void,"const MfClassicData*, uint8_t*, uint8_t*"
|
Function,+,mf_classic_get_read_sectors_and_keys,void,"const MfClassicData*, uint8_t*, uint8_t*"
|
||||||
|
Function,+,mf_classic_get_scannable_sectors_num,uint8_t,MfClassicType
|
||||||
Function,+,mf_classic_get_sector_by_block,uint8_t,uint8_t
|
Function,+,mf_classic_get_sector_by_block,uint8_t,uint8_t
|
||||||
Function,+,mf_classic_get_sector_trailer_by_sector,MfClassicSectorTrailer*,"const MfClassicData*, uint8_t"
|
Function,+,mf_classic_get_sector_trailer_by_sector,MfClassicSectorTrailer*,"const MfClassicData*, uint8_t"
|
||||||
Function,+,mf_classic_get_sector_trailer_num_by_block,uint8_t,uint8_t
|
Function,+,mf_classic_get_sector_trailer_num_by_block,uint8_t,uint8_t
|
||||||
|
|||||||
|
Reference in New Issue
Block a user