Explorar o código

free some memory in esubghz chat

MX hai 1 ano
pai
achega
1c11c09507

+ 0 - 349
lib/nfclegacy/helpers/mf_classic_dict.c

@@ -1,349 +0,0 @@
-#include "mf_classic_dict.h"
-
-#include <lib/toolbox/args.h>
-#include <lib/flipper_format/flipper_format.h>
-
-#define MF_CLASSIC_DICT_FLIPPER_PATH EXT_PATH("nfc/assets/mf_classic_dict.nfc")
-#define MF_CLASSIC_DICT_USER_PATH EXT_PATH("nfc/assets/mf_classic_dict_user.nfc")
-#define MF_CLASSIC_DICT_UNIT_TEST_PATH EXT_PATH("unit_tests/mf_classic_dict.nfc")
-
-#define TAG "MfClassicDict"
-
-#define NFC_MF_CLASSIC_KEY_LEN (13)
-
-struct MfClassicDict {
-    Stream* stream;
-    uint32_t total_keys;
-};
-
-bool mf_classic_dict_check_presence(MfClassicDictType dict_type) {
-    Storage* storage = furi_record_open(RECORD_STORAGE);
-
-    bool dict_present = false;
-    if(dict_type == MfClassicDictTypeSystem) {
-        dict_present = storage_common_stat(storage, MF_CLASSIC_DICT_FLIPPER_PATH, NULL) == FSE_OK;
-    } else if(dict_type == MfClassicDictTypeUser) {
-        dict_present = storage_common_stat(storage, MF_CLASSIC_DICT_USER_PATH, NULL) == FSE_OK;
-    } else if(dict_type == MfClassicDictTypeUnitTest) {
-        dict_present = storage_common_stat(storage, MF_CLASSIC_DICT_UNIT_TEST_PATH, NULL) ==
-                       FSE_OK;
-    }
-
-    furi_record_close(RECORD_STORAGE);
-
-    return dict_present;
-}
-
-MfClassicDict* mf_classic_dict_alloc(MfClassicDictType dict_type) {
-    MfClassicDict* dict = malloc(sizeof(MfClassicDict));
-    Storage* storage = furi_record_open(RECORD_STORAGE);
-    dict->stream = buffered_file_stream_alloc(storage);
-    furi_record_close(RECORD_STORAGE);
-
-    bool dict_loaded = false;
-    do {
-        if(dict_type == MfClassicDictTypeSystem) {
-            if(!buffered_file_stream_open(
-                   dict->stream,
-                   MF_CLASSIC_DICT_FLIPPER_PATH,
-                   FSAM_READ_WRITE,
-                   FSOM_OPEN_EXISTING)) {
-                buffered_file_stream_close(dict->stream);
-                break;
-            }
-        } else if(dict_type == MfClassicDictTypeUser) {
-            if(!buffered_file_stream_open(
-                   dict->stream, MF_CLASSIC_DICT_USER_PATH, FSAM_READ_WRITE, FSOM_OPEN_ALWAYS)) {
-                buffered_file_stream_close(dict->stream);
-                break;
-            }
-        } else if(dict_type == MfClassicDictTypeUnitTest) {
-            if(!buffered_file_stream_open(
-                   dict->stream,
-                   MF_CLASSIC_DICT_UNIT_TEST_PATH,
-                   FSAM_READ_WRITE,
-                   FSOM_OPEN_ALWAYS)) {
-                buffered_file_stream_close(dict->stream);
-                break;
-            }
-        }
-
-        // Check for new line ending
-        if(!stream_eof(dict->stream)) {
-            if(!stream_seek(dict->stream, -1, StreamOffsetFromEnd)) break;
-            uint8_t last_char = 0;
-            if(stream_read(dict->stream, &last_char, 1) != 1) break;
-            if(last_char != '\n') {
-                FURI_LOG_D(TAG, "Adding new line ending");
-                if(stream_write_char(dict->stream, '\n') != 1) break;
-            }
-            if(!stream_rewind(dict->stream)) break;
-        }
-
-        // Read total amount of keys
-        FuriString* next_line;
-        next_line = furi_string_alloc();
-        while(true) {
-            if(!stream_read_line(dict->stream, next_line)) {
-                FURI_LOG_T(TAG, "No keys left in dict");
-                break;
-            }
-            FURI_LOG_T(
-                TAG,
-                "Read line: %s, len: %zu",
-                furi_string_get_cstr(next_line),
-                furi_string_size(next_line));
-            if(furi_string_get_char(next_line, 0) == '#') continue;
-            if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue;
-            dict->total_keys++;
-        }
-        furi_string_free(next_line);
-        stream_rewind(dict->stream);
-
-        dict_loaded = true;
-        FURI_LOG_I(TAG, "Loaded dictionary with %lu keys", dict->total_keys);
-    } while(false);
-
-    if(!dict_loaded) {
-        buffered_file_stream_close(dict->stream);
-        free(dict);
-        dict = NULL;
-    }
-
-    return dict;
-}
-
-void mf_classic_dict_free(MfClassicDict* dict) {
-    furi_assert(dict);
-    furi_assert(dict->stream);
-
-    buffered_file_stream_close(dict->stream);
-    stream_free(dict->stream);
-    free(dict);
-}
-
-static void mf_classic_dict_int_to_str(uint8_t* key_int, FuriString* key_str) {
-    furi_string_reset(key_str);
-    for(size_t i = 0; i < 6; i++) {
-        furi_string_cat_printf(key_str, "%02X", key_int[i]);
-    }
-}
-
-static void mf_classic_dict_str_to_int(FuriString* key_str, uint64_t* key_int) {
-    uint8_t key_byte_tmp;
-
-    *key_int = 0ULL;
-    for(uint8_t i = 0; i < 12; i += 2) {
-        args_char_to_hex(
-            furi_string_get_char(key_str, i), furi_string_get_char(key_str, i + 1), &key_byte_tmp);
-        *key_int |= (uint64_t)key_byte_tmp << (8 * (5 - i / 2));
-    }
-}
-
-uint32_t mf_classic_dict_get_total_keys(MfClassicDict* dict) {
-    furi_assert(dict);
-
-    return dict->total_keys;
-}
-
-bool mf_classic_dict_rewind(MfClassicDict* dict) {
-    furi_assert(dict);
-    furi_assert(dict->stream);
-
-    return stream_rewind(dict->stream);
-}
-
-bool mf_classic_dict_get_next_key_str(MfClassicDict* dict, FuriString* key) {
-    furi_assert(dict);
-    furi_assert(dict->stream);
-
-    bool key_read = false;
-    furi_string_reset(key);
-    while(!key_read) {
-        if(!stream_read_line(dict->stream, key)) break;
-        if(furi_string_get_char(key, 0) == '#') continue;
-        if(furi_string_size(key) != NFC_MF_CLASSIC_KEY_LEN) continue;
-        furi_string_left(key, 12);
-        key_read = true;
-    }
-
-    return key_read;
-}
-
-bool mf_classic_dict_get_next_key(MfClassicDict* dict, uint64_t* key) {
-    furi_assert(dict);
-    furi_assert(dict->stream);
-
-    FuriString* temp_key;
-    temp_key = furi_string_alloc();
-    bool key_read = mf_classic_dict_get_next_key_str(dict, temp_key);
-    if(key_read) {
-        mf_classic_dict_str_to_int(temp_key, key);
-    }
-    furi_string_free(temp_key);
-    return key_read;
-}
-
-bool mf_classic_dict_is_key_present_str(MfClassicDict* dict, FuriString* key) {
-    furi_assert(dict);
-    furi_assert(dict->stream);
-
-    FuriString* next_line;
-    next_line = furi_string_alloc();
-
-    bool key_found = false;
-    stream_rewind(dict->stream);
-    while(!key_found) { //-V654
-        if(!stream_read_line(dict->stream, next_line)) break;
-        if(furi_string_get_char(next_line, 0) == '#') continue;
-        if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue;
-        furi_string_left(next_line, 12);
-        if(!furi_string_equal(key, next_line)) continue;
-        key_found = true;
-    }
-
-    furi_string_free(next_line);
-    return key_found;
-}
-
-bool mf_classic_dict_is_key_present(MfClassicDict* dict, uint8_t* key) {
-    FuriString* temp_key;
-
-    temp_key = furi_string_alloc();
-    mf_classic_dict_int_to_str(key, temp_key);
-    bool key_found = mf_classic_dict_is_key_present_str(dict, temp_key);
-    furi_string_free(temp_key);
-    return key_found;
-}
-
-bool mf_classic_dict_add_key_str(MfClassicDict* dict, FuriString* key) {
-    furi_assert(dict);
-    furi_assert(dict->stream);
-
-    furi_string_cat_printf(key, "\n");
-
-    bool key_added = false;
-    do {
-        if(!stream_seek(dict->stream, 0, StreamOffsetFromEnd)) break;
-        if(!stream_insert_string(dict->stream, key)) break;
-        dict->total_keys++;
-        key_added = true;
-    } while(false);
-
-    furi_string_left(key, 12);
-    return key_added;
-}
-
-bool mf_classic_dict_add_key(MfClassicDict* dict, uint8_t* key) {
-    furi_assert(dict);
-    furi_assert(dict->stream);
-
-    FuriString* temp_key;
-    temp_key = furi_string_alloc();
-    mf_classic_dict_int_to_str(key, temp_key);
-    bool key_added = mf_classic_dict_add_key_str(dict, temp_key);
-
-    furi_string_free(temp_key);
-    return key_added;
-}
-
-bool mf_classic_dict_get_key_at_index_str(MfClassicDict* dict, FuriString* key, uint32_t target) {
-    furi_assert(dict);
-    furi_assert(dict->stream);
-
-    FuriString* next_line;
-    uint32_t index = 0;
-    next_line = furi_string_alloc();
-    furi_string_reset(key);
-
-    bool key_found = false;
-    while(!key_found) {
-        if(!stream_read_line(dict->stream, next_line)) break;
-        if(furi_string_get_char(next_line, 0) == '#') continue;
-        if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue;
-        if(index++ != target) continue;
-        furi_string_set_n(key, next_line, 0, 12);
-        key_found = true;
-    }
-
-    furi_string_free(next_line);
-    return key_found;
-}
-
-bool mf_classic_dict_get_key_at_index(MfClassicDict* dict, uint64_t* key, uint32_t target) {
-    furi_assert(dict);
-    furi_assert(dict->stream);
-
-    FuriString* temp_key;
-    temp_key = furi_string_alloc();
-    bool key_found = mf_classic_dict_get_key_at_index_str(dict, temp_key, target);
-    if(key_found) {
-        mf_classic_dict_str_to_int(temp_key, key);
-    }
-    furi_string_free(temp_key);
-    return key_found;
-}
-
-bool mf_classic_dict_find_index_str(MfClassicDict* dict, FuriString* key, uint32_t* target) {
-    furi_assert(dict);
-    furi_assert(dict->stream);
-
-    FuriString* next_line;
-    next_line = furi_string_alloc();
-
-    bool key_found = false;
-    uint32_t index = 0;
-    stream_rewind(dict->stream);
-    while(!key_found) { //-V654
-        if(!stream_read_line(dict->stream, next_line)) break;
-        if(furi_string_get_char(next_line, 0) == '#') continue;
-        if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue;
-        furi_string_left(next_line, 12);
-        if(!furi_string_equal(key, next_line)) continue;
-        key_found = true;
-        *target = index;
-    }
-
-    furi_string_free(next_line);
-    return key_found;
-}
-
-bool mf_classic_dict_find_index(MfClassicDict* dict, uint8_t* key, uint32_t* target) {
-    furi_assert(dict);
-    furi_assert(dict->stream);
-
-    FuriString* temp_key;
-    temp_key = furi_string_alloc();
-    mf_classic_dict_int_to_str(key, temp_key);
-    bool key_found = mf_classic_dict_find_index_str(dict, temp_key, target);
-
-    furi_string_free(temp_key);
-    return key_found;
-}
-
-bool mf_classic_dict_delete_index(MfClassicDict* dict, uint32_t target) {
-    furi_assert(dict);
-    furi_assert(dict->stream);
-
-    FuriString* next_line;
-    next_line = furi_string_alloc();
-    uint32_t index = 0;
-
-    bool key_removed = false;
-    stream_rewind(dict->stream);
-    while(!key_removed) {
-        if(!stream_read_line(dict->stream, next_line)) break;
-        if(furi_string_get_char(next_line, 0) == '#') continue;
-        if(furi_string_size(next_line) != NFC_MF_CLASSIC_KEY_LEN) continue;
-        if(index++ != target) continue;
-        stream_seek(dict->stream, -NFC_MF_CLASSIC_KEY_LEN, StreamOffsetFromCurrent);
-        if(!stream_delete(dict->stream, NFC_MF_CLASSIC_KEY_LEN)) break;
-        dict->total_keys--;
-        key_removed = true;
-    }
-
-    stream_rewind(dict->stream);
-
-    furi_string_free(next_line);
-    return key_removed;
-}

+ 0 - 107
lib/nfclegacy/helpers/mf_classic_dict.h

@@ -1,107 +0,0 @@
-#pragma once
-
-#include <stdbool.h>
-#include <storage/storage.h>
-#include <lib/flipper_format/flipper_format.h>
-#include <lib/toolbox/stream/file_stream.h>
-#include <lib/toolbox/stream/buffered_file_stream.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
-    MfClassicDictTypeUser,
-    MfClassicDictTypeSystem,
-    MfClassicDictTypeUnitTest,
-} MfClassicDictType;
-
-typedef struct MfClassicDict MfClassicDict;
-
-bool mf_classic_dict_check_presence(MfClassicDictType dict_type);
-
-/** Allocate MfClassicDict instance
- *
- * @param[in]  dict_type  The dictionary type
- *
- * @return     MfClassicDict instance
- */
-MfClassicDict* mf_classic_dict_alloc(MfClassicDictType dict_type);
-
-/** Free MfClassicDict instance
- *
- * @param      dict  MfClassicDict instance
- */
-void mf_classic_dict_free(MfClassicDict* dict);
-
-/** Get total keys count
- *
- * @param      dict  MfClassicDict instance
- *
- * @return     total keys count
- */
-uint32_t mf_classic_dict_get_total_keys(MfClassicDict* dict);
-
-/** Rewind to the beginning
- *
- * @param      dict  MfClassicDict instance
- *
- * @return     true on success
- */
-bool mf_classic_dict_rewind(MfClassicDict* dict);
-
-bool mf_classic_dict_is_key_present(MfClassicDict* dict, uint8_t* key);
-
-bool mf_classic_dict_is_key_present_str(MfClassicDict* dict, FuriString* key);
-
-bool mf_classic_dict_get_next_key(MfClassicDict* dict, uint64_t* key);
-
-bool mf_classic_dict_get_next_key_str(MfClassicDict* dict, FuriString* key);
-
-/** Get key at target offset as uint64_t
- *
- * @param      dict    MfClassicDict instance
- * @param[out] key     Pointer to the uint64_t key
- * @param[in]  target  Target offset from current position
- *
- * @return     true on success
- */
-bool mf_classic_dict_get_key_at_index(MfClassicDict* dict, uint64_t* key, uint32_t target);
-
-/** Get key at target offset as FuriString*
- *
- * @param      dict    MfClassicDict instance
- * @param[out] key     Found key destination buffer
- * @param[in]  target  Target offset from current position
- *
- * @return     true on success
- */
-bool mf_classic_dict_get_key_at_index_str(MfClassicDict* dict, FuriString* key, uint32_t target);
-
-bool mf_classic_dict_add_key(MfClassicDict* dict, uint8_t* key);
-
-/** Add string representation of the key
- *
- * @param      dict  MfClassicDict instance
- * @param[in]  key   String representation of the key
- *
- * @return     true on success
- */
-bool mf_classic_dict_add_key_str(MfClassicDict* dict, FuriString* key);
-
-bool mf_classic_dict_find_index(MfClassicDict* dict, uint8_t* key, uint32_t* target);
-
-bool mf_classic_dict_find_index_str(MfClassicDict* dict, FuriString* key, uint32_t* target);
-
-/** Delete key at target offset
- *
- * @param      dict    MfClassicDict instance
- * @param[in]  target  Target offset from current position
- *
- * @return     true on success
- */
-bool mf_classic_dict_delete_index(MfClassicDict* dict, uint32_t target);
-
-#ifdef __cplusplus
-}
-#endif

+ 0 - 228
lib/nfclegacy/helpers/mfkey32.c

@@ -1,228 +0,0 @@
-#include "mfkey32.h"
-
-#include <furi/furi.h>
-#include <storage/storage.h>
-#include <stream/stream.h>
-#include <stream/buffered_file_stream.h>
-#include <m-array.h>
-
-#include "../protocols/mifare_classic.h"
-#include "../protocols/nfc_util.h"
-
-#define TAG "Mfkey32"
-
-#define MFKEY32_LOGS_PATH EXT_PATH("nfc/.mfkey32.log")
-
-typedef enum {
-    Mfkey32StateIdle,
-    Mfkey32StateAuthReceived,
-    Mfkey32StateAuthNtSent,
-    Mfkey32StateAuthArNrReceived,
-} Mfkey32State;
-
-typedef struct {
-    uint32_t cuid;
-    uint8_t sector;
-    MfClassicKey key;
-    uint32_t nt0;
-    uint32_t nr0;
-    uint32_t ar0;
-    uint32_t nt1;
-    uint32_t nr1;
-    uint32_t ar1;
-} Mfkey32Params;
-
-ARRAY_DEF(Mfkey32Params, Mfkey32Params, M_POD_OPLIST);
-
-typedef struct {
-    uint8_t sector;
-    MfClassicKey key;
-    uint32_t nt;
-    uint32_t nr;
-    uint32_t ar;
-} Mfkey32Nonce;
-
-struct Mfkey32 {
-    Mfkey32State state;
-    Stream* file_stream;
-    Mfkey32Params_t params_arr;
-    Mfkey32Nonce nonce;
-    uint32_t cuid;
-    Mfkey32ParseDataCallback callback;
-    void* context;
-};
-
-Mfkey32* mfkey32_alloc(uint32_t cuid) {
-    Mfkey32* instance = malloc(sizeof(Mfkey32));
-    instance->cuid = cuid;
-    instance->state = Mfkey32StateIdle;
-    Storage* storage = furi_record_open(RECORD_STORAGE);
-    instance->file_stream = buffered_file_stream_alloc(storage);
-    if(!buffered_file_stream_open(
-           instance->file_stream, MFKEY32_LOGS_PATH, FSAM_WRITE, FSOM_OPEN_APPEND)) {
-        buffered_file_stream_close(instance->file_stream);
-        stream_free(instance->file_stream);
-        free(instance);
-        instance = NULL;
-    } else {
-        Mfkey32Params_init(instance->params_arr);
-    }
-
-    furi_record_close(RECORD_STORAGE);
-
-    return instance;
-}
-
-void mfkey32_free(Mfkey32* instance) {
-    furi_assert(instance != NULL);
-
-    Mfkey32Params_clear(instance->params_arr);
-    buffered_file_stream_close(instance->file_stream);
-    stream_free(instance->file_stream);
-    free(instance);
-}
-
-void mfkey32_set_callback(Mfkey32* instance, Mfkey32ParseDataCallback callback, void* context) {
-    furi_assert(instance);
-    furi_assert(callback);
-
-    instance->callback = callback;
-    instance->context = context;
-}
-
-static bool mfkey32_write_params(Mfkey32* instance, Mfkey32Params* params) {
-    FuriString* str = furi_string_alloc_printf(
-        "Sec %d key %c cuid %08lx nt0 %08lx nr0 %08lx ar0 %08lx nt1 %08lx nr1 %08lx ar1 %08lx\n",
-        params->sector,
-        params->key == MfClassicKeyA ? 'A' : 'B',
-        params->cuid,
-        params->nt0,
-        params->nr0,
-        params->ar0,
-        params->nt1,
-        params->nr1,
-        params->ar1);
-    bool write_success = stream_write_string(instance->file_stream, str);
-    furi_string_free(str);
-    return write_success;
-}
-
-static void mfkey32_add_params(Mfkey32* instance) {
-    Mfkey32Nonce* nonce = &instance->nonce;
-    bool nonce_added = false;
-    // Search if we partially collected params
-    if(Mfkey32Params_size(instance->params_arr)) {
-        Mfkey32Params_it_t it;
-        for(Mfkey32Params_it(it, instance->params_arr); !Mfkey32Params_end_p(it);
-            Mfkey32Params_next(it)) {
-            Mfkey32Params* params = Mfkey32Params_ref(it);
-            if((params->sector == nonce->sector) && (params->key == nonce->key)) {
-                params->nt1 = nonce->nt;
-                params->nr1 = nonce->nr;
-                params->ar1 = nonce->ar;
-                nonce_added = true;
-                FURI_LOG_I(
-                    TAG,
-                    "Params for sector %d key %c collected",
-                    params->sector,
-                    params->key == MfClassicKeyA ? 'A' : 'B');
-                // Write on sd card
-                if(mfkey32_write_params(instance, params)) {
-                    Mfkey32Params_remove(instance->params_arr, it);
-                    if(instance->callback) {
-                        instance->callback(Mfkey32EventParamCollected, instance->context);
-                    }
-                }
-            }
-        }
-    }
-    if(!nonce_added) {
-        Mfkey32Params params = {
-            .sector = nonce->sector,
-            .key = nonce->key,
-            .cuid = instance->cuid,
-            .nt0 = nonce->nt,
-            .nr0 = nonce->nr,
-            .ar0 = nonce->ar,
-        };
-        Mfkey32Params_push_back(instance->params_arr, params);
-    }
-}
-
-void mfkey32_process_data(
-    Mfkey32* instance,
-    uint8_t* data,
-    uint16_t len,
-    bool reader_to_tag,
-    bool crc_dropped) {
-    furi_assert(instance);
-    furi_assert(data);
-
-    Mfkey32Nonce* nonce = &instance->nonce;
-    uint16_t data_len = len;
-    if((data_len > 3) && !crc_dropped) {
-        data_len -= 2;
-    }
-
-    bool data_processed = false;
-    if(instance->state == Mfkey32StateIdle) {
-        if(reader_to_tag) {
-            if((data[0] == 0x60) || (data[0] == 0x61)) {
-                nonce->key = data[0] == 0x60 ? MfClassicKeyA : MfClassicKeyB;
-                nonce->sector = mf_classic_get_sector_by_block(data[1]);
-                instance->state = Mfkey32StateAuthReceived;
-                data_processed = true;
-            }
-        }
-    } else if(instance->state == Mfkey32StateAuthReceived) {
-        if(!reader_to_tag) {
-            if(len == 4) {
-                nonce->nt = nfc_util_bytes2num(data, 4);
-                instance->state = Mfkey32StateAuthNtSent;
-                data_processed = true;
-            }
-        }
-    } else if(instance->state == Mfkey32StateAuthNtSent) {
-        if(reader_to_tag) {
-            if(len == 8) {
-                nonce->nr = nfc_util_bytes2num(data, 4);
-                nonce->ar = nfc_util_bytes2num(&data[4], 4);
-                mfkey32_add_params(instance);
-                instance->state = Mfkey32StateIdle;
-            }
-        }
-    }
-    if(!data_processed) {
-        instance->state = Mfkey32StateIdle;
-    }
-}
-
-uint16_t mfkey32_get_auth_sectors(FuriString* data_str) {
-    furi_assert(data_str);
-
-    uint16_t nonces_num = 0;
-    Storage* storage = furi_record_open(RECORD_STORAGE);
-    Stream* file_stream = buffered_file_stream_alloc(storage);
-    FuriString* temp_str;
-    temp_str = furi_string_alloc();
-
-    do {
-        if(!buffered_file_stream_open(
-               file_stream, MFKEY32_LOGS_PATH, FSAM_READ, FSOM_OPEN_EXISTING))
-            break;
-        while(true) {
-            if(!stream_read_line(file_stream, temp_str)) break;
-            size_t uid_pos = furi_string_search(temp_str, "cuid");
-            furi_string_left(temp_str, uid_pos);
-            furi_string_push_back(temp_str, '\n');
-            furi_string_cat(data_str, temp_str);
-            nonces_num++;
-        }
-    } while(false);
-
-    buffered_file_stream_close(file_stream);
-    stream_free(file_stream);
-    furi_string_free(temp_str);
-
-    return nonces_num;
-}

+ 0 - 34
lib/nfclegacy/helpers/mfkey32.h

@@ -1,34 +0,0 @@
-#pragma once
-
-#include "../protocols/mifare_classic.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct Mfkey32 Mfkey32;
-
-typedef enum {
-    Mfkey32EventParamCollected,
-} Mfkey32Event;
-
-typedef void (*Mfkey32ParseDataCallback)(Mfkey32Event event, void* context);
-
-Mfkey32* mfkey32_alloc(uint32_t cuid);
-
-void mfkey32_free(Mfkey32* instance);
-
-void mfkey32_process_data(
-    Mfkey32* instance,
-    uint8_t* data,
-    uint16_t len,
-    bool reader_to_tag,
-    bool crc_dropped);
-
-void mfkey32_set_callback(Mfkey32* instance, Mfkey32ParseDataCallback callback, void* context);
-
-uint16_t mfkey32_get_auth_sectors(FuriString* string);
-
-#ifdef __cplusplus
-}
-#endif

+ 0 - 71
lib/nfclegacy/helpers/nfc_debug_log.c

@@ -1,71 +0,0 @@
-#include "nfc_debug_log.h"
-
-#include <storage/storage.h>
-#include <stream/buffered_file_stream.h>
-
-#define TAG "NfcDebugLog"
-
-#define NFC_DEBUG_PCAP_FILENAME EXT_PATH("nfc/debug.txt")
-
-struct NfcDebugLog {
-    Stream* file_stream;
-    FuriString* data_str;
-};
-
-NfcDebugLog* nfc_debug_log_alloc() {
-    NfcDebugLog* instance = malloc(sizeof(NfcDebugLog));
-
-    Storage* storage = furi_record_open(RECORD_STORAGE);
-    instance->file_stream = buffered_file_stream_alloc(storage);
-
-    if(!buffered_file_stream_open(
-           instance->file_stream, NFC_DEBUG_PCAP_FILENAME, FSAM_WRITE, FSOM_OPEN_APPEND)) {
-        buffered_file_stream_close(instance->file_stream);
-        stream_free(instance->file_stream);
-        instance->file_stream = NULL;
-    }
-
-    if(!instance->file_stream) {
-        free(instance);
-        instance = NULL;
-    } else {
-        instance->data_str = furi_string_alloc();
-    }
-    furi_record_close(RECORD_STORAGE);
-
-    return instance;
-}
-
-void nfc_debug_log_free(NfcDebugLog* instance) {
-    furi_assert(instance);
-    furi_assert(instance->file_stream);
-    furi_assert(instance->data_str);
-
-    buffered_file_stream_close(instance->file_stream);
-    stream_free(instance->file_stream);
-    furi_string_free(instance->data_str);
-
-    free(instance);
-}
-
-void nfc_debug_log_process_data(
-    NfcDebugLog* instance,
-    uint8_t* data,
-    uint16_t len,
-    bool reader_to_tag,
-    bool crc_dropped) {
-    furi_assert(instance);
-    furi_assert(instance->file_stream);
-    furi_assert(instance->data_str);
-    furi_assert(data);
-    UNUSED(crc_dropped);
-
-    furi_string_printf(instance->data_str, "%lu %c:", furi_get_tick(), reader_to_tag ? 'R' : 'T');
-    uint16_t data_len = len;
-    for(size_t i = 0; i < data_len; i++) {
-        furi_string_cat_printf(instance->data_str, " %02x", data[i]);
-    }
-    furi_string_push_back(instance->data_str, '\n');
-
-    stream_write_string(instance->file_stream, instance->data_str);
-}

+ 0 - 17
lib/nfclegacy/helpers/nfc_debug_log.h

@@ -1,17 +0,0 @@
-#pragma once
-
-#include <stdint.h>
-#include <stdbool.h>
-
-typedef struct NfcDebugLog NfcDebugLog;
-
-NfcDebugLog* nfc_debug_log_alloc();
-
-void nfc_debug_log_free(NfcDebugLog* instance);
-
-void nfc_debug_log_process_data(
-    NfcDebugLog* instance,
-    uint8_t* data,
-    uint16_t len,
-    bool reader_to_tag,
-    bool crc_dropped);

+ 0 - 128
lib/nfclegacy/helpers/nfc_debug_pcap.c

@@ -1,128 +0,0 @@
-#include "nfc_debug_pcap.h"
-
-#include <storage/storage.h>
-#include <stream/buffered_file_stream.h>
-#include "../furi_hal_nfc.h"
-#include <furi_hal_rtc.h>
-
-#define TAG "NfcDebugPcap"
-
-#define PCAP_MAGIC 0xa1b2c3d4
-#define PCAP_MAJOR 2
-#define PCAP_MINOR 4
-#define DLT_ISO_14443 264
-
-#define DATA_PICC_TO_PCD 0xFF
-#define DATA_PCD_TO_PICC 0xFE
-#define DATA_PICC_TO_PCD_CRC_DROPPED 0xFB
-#define DATA_PCD_TO_PICC_CRC_DROPPED 0xFA
-
-#define NFC_DEBUG_PCAP_FILENAME EXT_PATH("nfc/debug.pcap")
-
-struct NfcDebugPcap {
-    Stream* file_stream;
-};
-
-static Stream* nfc_debug_pcap_open(Storage* storage) {
-    Stream* stream = NULL;
-    stream = buffered_file_stream_alloc(storage);
-    if(!buffered_file_stream_open(stream, NFC_DEBUG_PCAP_FILENAME, FSAM_WRITE, FSOM_OPEN_APPEND)) {
-        buffered_file_stream_close(stream);
-        stream_free(stream);
-        stream = NULL;
-    } else {
-        if(!stream_tell(stream)) {
-            struct {
-                uint32_t magic;
-                uint16_t major, minor;
-                uint32_t reserved[2];
-                uint32_t snaplen;
-                uint32_t link_type;
-            } __attribute__((__packed__)) pcap_hdr = {
-                .magic = PCAP_MAGIC,
-                .major = PCAP_MAJOR,
-                .minor = PCAP_MINOR,
-                .snaplen = FURRY_HAL_NFC_DATA_BUFF_SIZE,
-                .link_type = DLT_ISO_14443,
-            };
-            if(stream_write(stream, (uint8_t*)&pcap_hdr, sizeof(pcap_hdr)) != sizeof(pcap_hdr)) {
-                FURI_LOG_E(TAG, "Failed to write pcap header");
-                buffered_file_stream_close(stream);
-                stream_free(stream);
-                stream = NULL;
-            }
-        }
-    }
-    return stream;
-}
-
-NfcDebugPcap* nfc_debug_pcap_alloc() {
-    NfcDebugPcap* instance = malloc(sizeof(NfcDebugPcap));
-
-    Storage* storage = furi_record_open(RECORD_STORAGE);
-    instance->file_stream = nfc_debug_pcap_open(storage);
-    if(!instance->file_stream) {
-        free(instance);
-        instance = NULL;
-    }
-    furi_record_close(RECORD_STORAGE);
-
-    return instance;
-}
-
-void nfc_debug_pcap_free(NfcDebugPcap* instance) {
-    furi_assert(instance);
-    furi_assert(instance->file_stream);
-
-    buffered_file_stream_close(instance->file_stream);
-    stream_free(instance->file_stream);
-
-    free(instance);
-}
-
-void nfc_debug_pcap_process_data(
-    NfcDebugPcap* instance,
-    uint8_t* data,
-    uint16_t len,
-    bool reader_to_tag,
-    bool crc_dropped) {
-    furi_assert(instance);
-    furi_assert(data);
-
-    uint8_t event = 0;
-    if(reader_to_tag) {
-        if(crc_dropped) {
-            event = DATA_PCD_TO_PICC_CRC_DROPPED;
-        } else {
-            event = DATA_PCD_TO_PICC;
-        }
-    } else {
-        if(crc_dropped) {
-            event = DATA_PICC_TO_PCD_CRC_DROPPED;
-        } else {
-            event = DATA_PICC_TO_PCD;
-        }
-    }
-
-    struct {
-        // https://wiki.wireshark.org/Development/LibpcapFileFormat#record-packet-header
-        uint32_t ts_sec;
-        uint32_t ts_usec;
-        uint32_t incl_len;
-        uint32_t orig_len;
-        // https://www.kaiser.cx/posts/pcap-iso14443/#_packet_data
-        uint8_t version;
-        uint8_t event;
-        uint16_t len;
-    } __attribute__((__packed__)) pkt_hdr = {
-        .ts_sec = furi_hal_rtc_get_timestamp(),
-        .ts_usec = 0,
-        .incl_len = len + 4,
-        .orig_len = len + 4,
-        .version = 0,
-        .event = event,
-        .len = len << 8 | len >> 8,
-    };
-    stream_write(instance->file_stream, (uint8_t*)&pkt_hdr, sizeof(pkt_hdr));
-    stream_write(instance->file_stream, data, len);
-}

+ 0 - 17
lib/nfclegacy/helpers/nfc_debug_pcap.h

@@ -1,17 +0,0 @@
-#pragma once
-
-#include <stdint.h>
-#include <stdbool.h>
-
-typedef struct NfcDebugPcap NfcDebugPcap;
-
-NfcDebugPcap* nfc_debug_pcap_alloc();
-
-void nfc_debug_pcap_free(NfcDebugPcap* instance);
-
-void nfc_debug_pcap_process_data(
-    NfcDebugPcap* instance,
-    uint8_t* data,
-    uint16_t len,
-    bool reader_to_tag,
-    bool crc_dropped);

+ 0 - 548
lib/nfclegacy/helpers/nfc_generators.c

@@ -1,548 +0,0 @@
-#include <furi_hal_random.h>
-#include "nfc_generators.h"
-
-#define NXP_MANUFACTURER_ID (0x04)
-
-static const uint8_t version_bytes_mf0ulx1[] = {0x00, 0x04, 0x03, 0x00, 0x01, 0x00, 0x00, 0x03};
-static const uint8_t version_bytes_ntag21x[] = {0x00, 0x04, 0x04, 0x02, 0x01, 0x00, 0x00, 0x03};
-static const uint8_t version_bytes_ntag_i2c[] = {0x00, 0x04, 0x04, 0x05, 0x02, 0x00, 0x00, 0x03};
-static const uint8_t default_data_ntag203[] =
-    {0xE1, 0x10, 0x12, 0x00, 0x01, 0x03, 0xA0, 0x10, 0x44, 0x03, 0x00, 0xFE};
-static const uint8_t default_data_ntag213[] = {0x01, 0x03, 0xA0, 0x0C, 0x34, 0x03, 0x00, 0xFE};
-static const uint8_t default_data_ntag215_216[] = {0x03, 0x00, 0xFE};
-static const uint8_t default_data_ntag_i2c[] = {0xE1, 0x10, 0x00, 0x00, 0x03, 0x00, 0xFE};
-static const uint8_t default_config_ntag_i2c[] = {0x01, 0x00, 0xF8, 0x48, 0x08, 0x01, 0x00, 0x00};
-
-static void nfc_generate_common_start(NfcDeviceData* data) {
-    nfc_device_data_clear(data);
-}
-
-static void nfc_generate_mf_ul_uid(uint8_t* uid) {
-    uid[0] = NXP_MANUFACTURER_ID;
-    furi_hal_random_fill_buf(&uid[1], 6);
-    // I'm not sure how this is generated, but the upper nybble always seems to be 8
-    uid[6] &= 0x0F;
-    uid[6] |= 0x80;
-}
-
-static void nfc_generate_mf_classic_uid(uint8_t* uid, uint8_t length) {
-    uid[0] = NXP_MANUFACTURER_ID;
-    furi_hal_random_fill_buf(&uid[1], length - 1);
-}
-
-static void nfc_generate_mf_classic_block_0(
-    uint8_t* block,
-    uint8_t uid_len,
-    uint8_t sak,
-    uint8_t atqa0,
-    uint8_t atqa1) {
-    // Block length is always 16 bytes, and the UID can be either 4 or 7 bytes
-    furi_assert(uid_len == 4 || uid_len == 7);
-    furi_assert(block);
-
-    if(uid_len == 4) {
-        // Calculate BCC
-        block[uid_len] = 0;
-
-        for(int i = 0; i < uid_len; i++) {
-            block[uid_len] ^= block[i];
-        }
-    } else {
-        uid_len -= 1;
-    }
-
-    block[uid_len + 1] = sak;
-    block[uid_len + 2] = atqa0;
-    block[uid_len + 3] = atqa1;
-
-    for(int i = uid_len + 4; i < 16; i++) {
-        block[i] = 0xFF;
-    }
-}
-
-static void nfc_generate_mf_classic_sector_trailer(MfClassicData* data, uint8_t block) {
-    // All keys are set to FFFF FFFF FFFFh at chip delivery and the bytes 6, 7 and 8 are set to FF0780h.
-    MfClassicSectorTrailer* sec_tr = (MfClassicSectorTrailer*)data->block[block].value;
-    sec_tr->access_bits[0] = 0xFF;
-    sec_tr->access_bits[1] = 0x07;
-    sec_tr->access_bits[2] = 0x80;
-    sec_tr->access_bits[3] = 0x69; // Nice
-
-    memset(sec_tr->key_a, 0xff, sizeof(sec_tr->key_a));
-    memset(sec_tr->key_b, 0xff, sizeof(sec_tr->key_b));
-
-    mf_classic_set_block_read(data, block, &data->block[block]);
-    mf_classic_set_key_found(
-        data, mf_classic_get_sector_by_block(block), MfClassicKeyA, 0xFFFFFFFFFFFF);
-    mf_classic_set_key_found(
-        data, mf_classic_get_sector_by_block(block), MfClassicKeyB, 0xFFFFFFFFFFFF);
-}
-
-static void nfc_generate_mf_ul_common(NfcDeviceData* data) {
-    data->nfc_data.type = FurryHalNfcTypeA;
-    data->nfc_data.interface = FurryHalNfcInterfaceRf;
-    data->nfc_data.uid_len = 7;
-    nfc_generate_mf_ul_uid(data->nfc_data.uid);
-    data->nfc_data.atqa[0] = 0x44;
-    data->nfc_data.atqa[1] = 0x00;
-    data->nfc_data.sak = 0x00;
-    data->protocol = NfcDeviceProtocolMifareUl;
-}
-
-static void
-    nfc_generate_mf_classic_common(NfcDeviceData* data, uint8_t uid_len, MfClassicType type) {
-    data->nfc_data.type = FurryHalNfcTypeA;
-    data->nfc_data.interface = FurryHalNfcInterfaceRf;
-    data->nfc_data.uid_len = uid_len;
-    data->nfc_data.atqa[0] = 0x44;
-    data->nfc_data.atqa[1] = 0x00;
-    data->nfc_data.sak = 0x08;
-    data->protocol = NfcDeviceProtocolMifareClassic;
-    data->mf_classic_data.type = type;
-}
-
-static void nfc_generate_calc_bcc(uint8_t* uid, uint8_t* bcc0, uint8_t* bcc1) {
-    *bcc0 = 0x88 ^ uid[0] ^ uid[1] ^ uid[2];
-    *bcc1 = uid[3] ^ uid[4] ^ uid[5] ^ uid[6];
-}
-
-static void nfc_generate_mf_ul_copy_uid_with_bcc(NfcDeviceData* data) {
-    MfUltralightData* mful = &data->mf_ul_data;
-    memcpy(mful->data, data->nfc_data.uid, 3);
-    memcpy(&mful->data[4], &data->nfc_data.uid[3], 4);
-    nfc_generate_calc_bcc(data->nfc_data.uid, &mful->data[3], &mful->data[8]);
-}
-
-static void nfc_generate_mf_ul_orig(NfcDeviceData* data) {
-    nfc_generate_common_start(data);
-    nfc_generate_mf_ul_common(data);
-
-    MfUltralightData* mful = &data->mf_ul_data;
-    mful->type = MfUltralightTypeUnknown;
-    mful->data_size = 16 * 4;
-    mful->data_read = mful->data_size;
-    nfc_generate_mf_ul_copy_uid_with_bcc(data);
-    // TODO: what's internal byte on page 2?
-    memset(&mful->data[4 * 4], 0xFF, 4);
-}
-
-static void nfc_generate_mf_ul_ntag203(NfcDeviceData* data) {
-    nfc_generate_common_start(data);
-    nfc_generate_mf_ul_common(data);
-
-    MfUltralightData* mful = &data->mf_ul_data;
-    mful->type = MfUltralightTypeNTAG203;
-    mful->data_size = 42 * 4;
-    mful->data_read = mful->data_size;
-    nfc_generate_mf_ul_copy_uid_with_bcc(data);
-    mful->data[9] = 0x48; // Internal byte
-    memcpy(&mful->data[3 * 4], default_data_ntag203, sizeof(default_data_ntag203));
-}
-
-static void nfc_generate_mf_ul_with_config_common(NfcDeviceData* data, uint8_t num_pages) {
-    nfc_generate_common_start(data);
-    nfc_generate_mf_ul_common(data);
-
-    MfUltralightData* mful = &data->mf_ul_data;
-    mful->data_size = num_pages * 4;
-    mful->data_read = mful->data_size;
-    nfc_generate_mf_ul_copy_uid_with_bcc(data);
-    uint16_t config_index = (num_pages - 4) * 4;
-    mful->data[config_index] = 0x04; // STRG_MOD_EN
-    mful->data[config_index + 3] = 0xFF; // AUTH0
-    mful->data[config_index + 5] = 0x05; // VCTID
-    memset(&mful->data[config_index + 8], 0xFF, 4); // Default PWD
-    if(num_pages > 20) mful->data[config_index - 1] = MF_UL_TEARING_FLAG_DEFAULT;
-}
-
-static void nfc_generate_mf_ul_ev1_common(NfcDeviceData* data, uint8_t num_pages) {
-    nfc_generate_mf_ul_with_config_common(data, num_pages);
-    MfUltralightData* mful = &data->mf_ul_data;
-    memcpy(&mful->version, version_bytes_mf0ulx1, sizeof(version_bytes_mf0ulx1));
-    for(size_t i = 0; i < 3; ++i) {
-        mful->tearing[i] = MF_UL_TEARING_FLAG_DEFAULT;
-    }
-    // TODO: what's internal byte on page 2?
-}
-
-static void nfc_generate_mf_ul_11(NfcDeviceData* data) {
-    nfc_generate_mf_ul_ev1_common(data, 20);
-    MfUltralightData* mful = &data->mf_ul_data;
-    mful->type = MfUltralightTypeUL11;
-    mful->version.prod_subtype = 0x01;
-    mful->version.storage_size = 0x0B;
-    mful->data[16 * 4] = 0x00; // Low capacitance version does not have STRG_MOD_EN
-}
-
-static void nfc_generate_mf_ul_h11(NfcDeviceData* data) {
-    nfc_generate_mf_ul_ev1_common(data, 20);
-    MfUltralightData* mful = &data->mf_ul_data;
-    mful->type = MfUltralightTypeUL11;
-    mful->version.prod_subtype = 0x02;
-    mful->version.storage_size = 0x0B;
-}
-
-static void nfc_generate_mf_ul_21(NfcDeviceData* data) {
-    nfc_generate_mf_ul_ev1_common(data, 41);
-    MfUltralightData* mful = &data->mf_ul_data;
-    mful->type = MfUltralightTypeUL21;
-    mful->version.prod_subtype = 0x01;
-    mful->version.storage_size = 0x0E;
-    mful->data[37 * 4] = 0x00; // Low capacitance version does not have STRG_MOD_EN
-}
-
-static void nfc_generate_mf_ul_h21(NfcDeviceData* data) {
-    nfc_generate_mf_ul_ev1_common(data, 41);
-    MfUltralightData* mful = &data->mf_ul_data;
-    mful->type = MfUltralightTypeUL21;
-    mful->version.prod_subtype = 0x02;
-    mful->version.storage_size = 0x0E;
-}
-
-static void nfc_generate_ntag21x_common(NfcDeviceData* data, uint8_t num_pages) {
-    nfc_generate_mf_ul_with_config_common(data, num_pages);
-    MfUltralightData* mful = &data->mf_ul_data;
-    memcpy(&mful->version, version_bytes_ntag21x, sizeof(version_bytes_mf0ulx1));
-    mful->data[9] = 0x48; // Internal byte
-    // Capability container
-    mful->data[12] = 0xE1;
-    mful->data[13] = 0x10;
-}
-
-static void nfc_generate_ntag213(NfcDeviceData* data) {
-    nfc_generate_ntag21x_common(data, 45);
-    MfUltralightData* mful = &data->mf_ul_data;
-    mful->type = MfUltralightTypeNTAG213;
-    mful->version.storage_size = 0x0F;
-    mful->data[14] = 0x12;
-    // Default contents
-    memcpy(&mful->data[16], default_data_ntag213, sizeof(default_data_ntag213));
-}
-
-static void nfc_generate_ntag215(NfcDeviceData* data) {
-    nfc_generate_ntag21x_common(data, 135);
-    MfUltralightData* mful = &data->mf_ul_data;
-    mful->type = MfUltralightTypeNTAG215;
-    mful->version.storage_size = 0x11;
-    mful->data[14] = 0x3E;
-    // Default contents
-    memcpy(&mful->data[16], default_data_ntag215_216, sizeof(default_data_ntag215_216));
-}
-
-static void nfc_generate_ntag216(NfcDeviceData* data) {
-    nfc_generate_ntag21x_common(data, 231);
-    MfUltralightData* mful = &data->mf_ul_data;
-    mful->type = MfUltralightTypeNTAG216;
-    mful->version.storage_size = 0x13;
-    mful->data[14] = 0x6D;
-    // Default contents
-    memcpy(&mful->data[16], default_data_ntag215_216, sizeof(default_data_ntag215_216));
-}
-
-static void
-    nfc_generate_ntag_i2c_common(NfcDeviceData* data, MfUltralightType type, uint16_t num_pages) {
-    nfc_generate_common_start(data);
-    nfc_generate_mf_ul_common(data);
-
-    MfUltralightData* mful = &data->mf_ul_data;
-    mful->type = type;
-    memcpy(&mful->version, version_bytes_ntag_i2c, sizeof(version_bytes_ntag_i2c));
-    mful->data_size = num_pages * 4;
-    mful->data_read = mful->data_size;
-    memcpy(mful->data, data->nfc_data.uid, data->nfc_data.uid_len);
-    mful->data[7] = data->nfc_data.sak;
-    mful->data[8] = data->nfc_data.atqa[0];
-    mful->data[9] = data->nfc_data.atqa[1];
-
-    uint16_t config_register_page;
-    uint16_t session_register_page;
-
-    // Sync with mifare_ultralight.c
-    switch(type) {
-    case MfUltralightTypeNTAGI2C1K:
-        config_register_page = 227;
-        session_register_page = 229;
-        break;
-    case MfUltralightTypeNTAGI2C2K:
-        config_register_page = 481;
-        session_register_page = 483;
-        break;
-    case MfUltralightTypeNTAGI2CPlus1K:
-    case MfUltralightTypeNTAGI2CPlus2K:
-        config_register_page = 232;
-        session_register_page = 234;
-        break;
-    default:
-        furi_crash("Unknown MFUL");
-        break;
-    }
-
-    memcpy(
-        &mful->data[config_register_page * 4],
-        default_config_ntag_i2c,
-        sizeof(default_config_ntag_i2c));
-    memcpy(
-        &mful->data[session_register_page * 4],
-        default_config_ntag_i2c,
-        sizeof(default_config_ntag_i2c));
-}
-
-static void nfc_generate_ntag_i2c_1k(NfcDeviceData* data) {
-    nfc_generate_ntag_i2c_common(data, MfUltralightTypeNTAGI2C1K, 231);
-    MfUltralightData* mful = &data->mf_ul_data;
-    mful->version.prod_ver_minor = 0x01;
-    mful->version.storage_size = 0x13;
-
-    memcpy(&mful->data[12], default_data_ntag_i2c, sizeof(default_data_ntag_i2c));
-    mful->data[14] = 0x6D; // Size of tag in CC
-}
-
-static void nfc_generate_ntag_i2c_2k(NfcDeviceData* data) {
-    nfc_generate_ntag_i2c_common(data, MfUltralightTypeNTAGI2C2K, 485);
-    MfUltralightData* mful = &data->mf_ul_data;
-    mful->version.prod_ver_minor = 0x01;
-    mful->version.storage_size = 0x15;
-
-    memcpy(&mful->data[12], default_data_ntag_i2c, sizeof(default_data_ntag_i2c));
-    mful->data[14] = 0xEA; // Size of tag in CC
-}
-
-static void nfc_generate_ntag_i2c_plus_common(
-    NfcDeviceData* data,
-    MfUltralightType type,
-    uint16_t num_pages) {
-    nfc_generate_ntag_i2c_common(data, type, num_pages);
-
-    MfUltralightData* mful = &data->mf_ul_data;
-    uint16_t config_index = 227 * 4;
-    mful->data[config_index + 3] = 0xFF; // AUTH0
-    memset(&mful->data[config_index + 8], 0xFF, 4); // Default PWD
-}
-
-static void nfc_generate_ntag_i2c_plus_1k(NfcDeviceData* data) {
-    nfc_generate_ntag_i2c_plus_common(data, MfUltralightTypeNTAGI2CPlus1K, 236);
-    MfUltralightData* mful = &data->mf_ul_data;
-    mful->version.prod_ver_minor = 0x02;
-    mful->version.storage_size = 0x13;
-}
-
-static void nfc_generate_ntag_i2c_plus_2k(NfcDeviceData* data) {
-    nfc_generate_ntag_i2c_plus_common(data, MfUltralightTypeNTAGI2CPlus2K, 492);
-    MfUltralightData* mful = &data->mf_ul_data;
-    mful->version.prod_ver_minor = 0x02;
-    mful->version.storage_size = 0x15;
-}
-
-void nfc_generate_mf_classic_ext(
-    NfcDeviceData* data,
-    uint8_t uid_len,
-    MfClassicType type,
-    bool random_uid,
-    uint8_t* uid) {
-    nfc_generate_common_start(data);
-    if(random_uid) {
-        nfc_generate_mf_classic_uid(data->mf_classic_data.block[0].value, uid_len);
-    } else {
-        memcpy(data->mf_classic_data.block[0].value, uid, uid_len);
-    }
-    nfc_generate_mf_classic_common(data, uid_len, type);
-
-    // Set the UID
-    if(random_uid) {
-        data->nfc_data.uid[0] = NXP_MANUFACTURER_ID;
-        for(int i = 1; i < uid_len; i++) {
-            data->nfc_data.uid[i] = data->mf_classic_data.block[0].value[i];
-        }
-    } else {
-        for(int i = 0; i < uid_len; i++) {
-            data->nfc_data.uid[i] = data->mf_classic_data.block[0].value[i];
-        }
-    }
-
-    MfClassicData* mfc = &data->mf_classic_data;
-    mf_classic_set_block_read(mfc, 0, &mfc->block[0]);
-
-    if(type == MfClassicType4k) {
-        // Set every block to 0xFF
-        for(uint16_t i = 1; i < 256; i += 1) {
-            if(mf_classic_is_sector_trailer(i)) {
-                nfc_generate_mf_classic_sector_trailer(mfc, i);
-            } else {
-                memset(&mfc->block[i].value, 0xFF, 16);
-            }
-            mf_classic_set_block_read(mfc, i, &mfc->block[i]);
-        }
-        // Set SAK to 18
-        data->nfc_data.sak = 0x18;
-    } else if(type == MfClassicType1k) {
-        // Set every block to 0xFF
-        for(uint16_t i = 1; i < MF_CLASSIC_1K_TOTAL_SECTORS_NUM * 4; i += 1) {
-            if(mf_classic_is_sector_trailer(i)) {
-                nfc_generate_mf_classic_sector_trailer(mfc, i);
-            } else {
-                memset(&mfc->block[i].value, 0xFF, 16);
-            }
-            mf_classic_set_block_read(mfc, i, &mfc->block[i]);
-        }
-        // Set SAK to 08
-        data->nfc_data.sak = 0x08;
-    } else if(type == MfClassicTypeMini) {
-        // Set every block to 0xFF
-        for(uint16_t i = 1; i < MF_MINI_TOTAL_SECTORS_NUM * 4; i += 1) {
-            if(mf_classic_is_sector_trailer(i)) {
-                nfc_generate_mf_classic_sector_trailer(mfc, i);
-            } else {
-                memset(&mfc->block[i].value, 0xFF, 16);
-            }
-            mf_classic_set_block_read(mfc, i, &mfc->block[i]);
-        }
-        // Set SAK to 09
-        data->nfc_data.sak = 0x09;
-    }
-
-    nfc_generate_mf_classic_block_0(
-        data->mf_classic_data.block[0].value,
-        uid_len,
-        data->nfc_data.sak,
-        data->nfc_data.atqa[0],
-        data->nfc_data.atqa[1]);
-
-    mfc->type = type;
-}
-
-void nfc_generate_mf_classic(NfcDeviceData* data, uint8_t uid_len, MfClassicType type) {
-    uint8_t uid = 0;
-    nfc_generate_mf_classic_ext(data, uid_len, type, true, &uid);
-}
-
-static void nfc_generate_mf_mini(NfcDeviceData* data) {
-    nfc_generate_mf_classic(data, 4, MfClassicTypeMini);
-}
-
-static void nfc_generate_mf_classic_1k_4b_uid(NfcDeviceData* data) {
-    nfc_generate_mf_classic(data, 4, MfClassicType1k);
-}
-
-static void nfc_generate_mf_classic_1k_7b_uid(NfcDeviceData* data) {
-    nfc_generate_mf_classic(data, 7, MfClassicType1k);
-}
-
-static void nfc_generate_mf_classic_4k_4b_uid(NfcDeviceData* data) {
-    nfc_generate_mf_classic(data, 4, MfClassicType4k);
-}
-
-static void nfc_generate_mf_classic_4k_7b_uid(NfcDeviceData* data) {
-    nfc_generate_mf_classic(data, 7, MfClassicType4k);
-}
-
-static const NfcGenerator mf_ul_generator = {
-    .name = "Mifare Ultralight",
-    .generator_func = nfc_generate_mf_ul_orig,
-};
-
-static const NfcGenerator mf_ul_11_generator = {
-    .name = "Mifare Ultralight EV1 11",
-    .generator_func = nfc_generate_mf_ul_11,
-};
-
-static const NfcGenerator mf_ul_h11_generator = {
-    .name = "Mifare Ultralight EV1 H11",
-    .generator_func = nfc_generate_mf_ul_h11,
-};
-
-static const NfcGenerator mf_ul_21_generator = {
-    .name = "Mifare Ultralight EV1 21",
-    .generator_func = nfc_generate_mf_ul_21,
-};
-
-static const NfcGenerator mf_ul_h21_generator = {
-    .name = "Mifare Ultralight EV1 H21",
-    .generator_func = nfc_generate_mf_ul_h21,
-};
-
-static const NfcGenerator ntag203_generator = {
-    .name = "NTAG203",
-    .generator_func = nfc_generate_mf_ul_ntag203,
-};
-
-static const NfcGenerator ntag213_generator = {
-    .name = "NTAG213",
-    .generator_func = nfc_generate_ntag213,
-};
-
-static const NfcGenerator ntag215_generator = {
-    .name = "NTAG215",
-    .generator_func = nfc_generate_ntag215,
-};
-
-static const NfcGenerator ntag216_generator = {
-    .name = "NTAG216",
-    .generator_func = nfc_generate_ntag216,
-};
-
-static const NfcGenerator ntag_i2c_1k_generator = {
-    .name = "NTAG I2C 1k",
-    .generator_func = nfc_generate_ntag_i2c_1k,
-};
-
-static const NfcGenerator ntag_i2c_2k_generator = {
-    .name = "NTAG I2C 2k",
-    .generator_func = nfc_generate_ntag_i2c_2k,
-};
-
-static const NfcGenerator ntag_i2c_plus_1k_generator = {
-    .name = "NTAG I2C Plus 1k",
-    .generator_func = nfc_generate_ntag_i2c_plus_1k,
-};
-
-static const NfcGenerator ntag_i2c_plus_2k_generator = {
-    .name = "NTAG I2C Plus 2k",
-    .generator_func = nfc_generate_ntag_i2c_plus_2k,
-};
-
-static const NfcGenerator mifare_mini_generator = {
-    .name = "Mifare Mini",
-    .generator_func = nfc_generate_mf_mini,
-};
-
-static const NfcGenerator mifare_classic_1k_4b_uid_generator = {
-    .name = "Mifare Classic 1k 4byte UID",
-    .generator_func = nfc_generate_mf_classic_1k_4b_uid,
-};
-
-static const NfcGenerator mifare_classic_1k_7b_uid_generator = {
-    .name = "Mifare Classic 1k 7byte UID",
-    .generator_func = nfc_generate_mf_classic_1k_7b_uid,
-};
-
-static const NfcGenerator mifare_classic_4k_4b_uid_generator = {
-    .name = "Mifare Classic 4k 4byte UID",
-    .generator_func = nfc_generate_mf_classic_4k_4b_uid,
-};
-
-static const NfcGenerator mifare_classic_4k_7b_uid_generator = {
-    .name = "Mifare Classic 4k 7byte UID",
-    .generator_func = nfc_generate_mf_classic_4k_7b_uid,
-};
-
-const NfcGenerator* const nfc_generators[] = {
-    &mf_ul_generator,
-    &mf_ul_11_generator,
-    &mf_ul_h11_generator,
-    &mf_ul_21_generator,
-    &mf_ul_h21_generator,
-    &ntag203_generator,
-    &ntag213_generator,
-    &ntag215_generator,
-    &ntag216_generator,
-    &ntag_i2c_1k_generator,
-    &ntag_i2c_2k_generator,
-    &ntag_i2c_plus_1k_generator,
-    &ntag_i2c_plus_2k_generator,
-    &mifare_mini_generator,
-    &mifare_classic_1k_4b_uid_generator,
-    &mifare_classic_1k_7b_uid_generator,
-    &mifare_classic_4k_4b_uid_generator,
-    &mifare_classic_4k_7b_uid_generator,
-    NULL,
-};

+ 0 - 29
lib/nfclegacy/helpers/nfc_generators.h

@@ -1,29 +0,0 @@
-#pragma once
-
-#include "../nfc_device.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef void (*NfcGeneratorFunc)(NfcDeviceData* data);
-
-typedef struct {
-    const char* name;
-    NfcGeneratorFunc generator_func;
-} NfcGenerator;
-
-extern const NfcGenerator* const nfc_generators[];
-
-void nfc_generate_mf_classic(NfcDeviceData* data, uint8_t uid_len, MfClassicType type);
-
-void nfc_generate_mf_classic_ext(
-    NfcDeviceData* data,
-    uint8_t uid_len,
-    MfClassicType type,
-    bool random_uid,
-    uint8_t* uid);
-
-#ifdef __cplusplus
-}
-#endif

+ 0 - 265
lib/nfclegacy/helpers/reader_analyzer.c

@@ -1,265 +0,0 @@
-#include "reader_analyzer.h"
-#include "../protocols/nfc_util.h"
-#include "../protocols/mifare_classic.h"
-#include <m-array.h>
-
-#include "mfkey32.h"
-#include "nfc_debug_pcap.h"
-#include "nfc_debug_log.h"
-
-#define TAG "ReaderAnalyzer"
-
-#define READER_ANALYZER_MAX_BUFF_SIZE (1024)
-
-typedef struct {
-    bool reader_to_tag;
-    bool crc_dropped;
-    uint16_t len;
-} ReaderAnalyzerHeader;
-
-typedef enum {
-    ReaderAnalyzerNfcDataMfClassic,
-} ReaderAnalyzerNfcData;
-
-struct ReaderAnalyzer {
-    FurryHalNfcDevData nfc_data;
-
-    bool alive;
-    FuriStreamBuffer* stream;
-    FuriThread* thread;
-
-    ReaderAnalyzerParseDataCallback callback;
-    void* context;
-
-    ReaderAnalyzerMode mode;
-    Mfkey32* mfkey32;
-    NfcDebugLog* debug_log;
-    NfcDebugPcap* pcap;
-};
-
-const FurryHalNfcDevData reader_analyzer_nfc_data[] = {
-    [ReaderAnalyzerNfcDataMfClassic] =
-        {.sak = 0x08,
-         .atqa = {0x44, 0x00},
-         .interface = FurryHalNfcInterfaceRf,
-         .type = FurryHalNfcTypeA,
-         .uid_len = 7,
-         .uid = {0x04, 0x77, 0x70, 0x2A, 0x23, 0x4F, 0x80},
-         .cuid = 0x2A234F80},
-};
-
-void reader_analyzer_parse(ReaderAnalyzer* instance, uint8_t* buffer, size_t size) {
-    if(size < sizeof(ReaderAnalyzerHeader)) return;
-
-    size_t bytes_i = 0;
-    while(bytes_i < size) {
-        ReaderAnalyzerHeader* header = (ReaderAnalyzerHeader*)&buffer[bytes_i];
-        uint16_t len = header->len;
-        if(bytes_i + len > size) break;
-        bytes_i += sizeof(ReaderAnalyzerHeader);
-        if(instance->mfkey32) {
-            mfkey32_process_data(
-                instance->mfkey32,
-                &buffer[bytes_i],
-                len,
-                header->reader_to_tag,
-                header->crc_dropped);
-        }
-        if(instance->pcap) {
-            nfc_debug_pcap_process_data(
-                instance->pcap, &buffer[bytes_i], len, header->reader_to_tag, header->crc_dropped);
-        }
-        if(instance->debug_log) {
-            nfc_debug_log_process_data(
-                instance->debug_log,
-                &buffer[bytes_i],
-                len,
-                header->reader_to_tag,
-                header->crc_dropped);
-        }
-        bytes_i += len;
-    }
-}
-
-int32_t reader_analyzer_thread(void* context) {
-    ReaderAnalyzer* reader_analyzer = context;
-    uint8_t buffer[READER_ANALYZER_MAX_BUFF_SIZE] = {};
-
-    while(reader_analyzer->alive || !furi_stream_buffer_is_empty(reader_analyzer->stream)) {
-        size_t ret = furi_stream_buffer_receive(
-            reader_analyzer->stream, buffer, READER_ANALYZER_MAX_BUFF_SIZE, 50);
-        if(ret) {
-            reader_analyzer_parse(reader_analyzer, buffer, ret);
-        }
-    }
-
-    return 0;
-}
-
-ReaderAnalyzer* reader_analyzer_alloc() {
-    ReaderAnalyzer* instance = malloc(sizeof(ReaderAnalyzer));
-
-    instance->nfc_data = reader_analyzer_nfc_data[ReaderAnalyzerNfcDataMfClassic];
-    instance->alive = false;
-    instance->stream =
-        furi_stream_buffer_alloc(READER_ANALYZER_MAX_BUFF_SIZE, sizeof(ReaderAnalyzerHeader));
-
-    instance->thread =
-        furi_thread_alloc_ex("ReaderAnalyzerWorker", 2048, reader_analyzer_thread, instance);
-    furi_thread_set_priority(instance->thread, FuriThreadPriorityLow);
-
-    return instance;
-}
-
-static void reader_analyzer_mfkey_callback(Mfkey32Event event, void* context) {
-    furi_assert(context);
-    ReaderAnalyzer* instance = context;
-
-    if(event == Mfkey32EventParamCollected) {
-        if(instance->callback) {
-            instance->callback(ReaderAnalyzerEventMfkeyCollected, instance->context);
-        }
-    }
-}
-
-void reader_analyzer_start(ReaderAnalyzer* instance, ReaderAnalyzerMode mode) {
-    furi_assert(instance);
-
-    furi_stream_buffer_reset(instance->stream);
-    if(mode & ReaderAnalyzerModeDebugLog) {
-        instance->debug_log = nfc_debug_log_alloc();
-    }
-    if(mode & ReaderAnalyzerModeMfkey) {
-        instance->mfkey32 = mfkey32_alloc(instance->nfc_data.cuid);
-        if(instance->mfkey32) {
-            mfkey32_set_callback(instance->mfkey32, reader_analyzer_mfkey_callback, instance);
-        }
-    }
-    if(mode & ReaderAnalyzerModeDebugPcap) {
-        instance->pcap = nfc_debug_pcap_alloc();
-    }
-
-    instance->alive = true;
-    furi_thread_start(instance->thread);
-}
-
-void reader_analyzer_stop(ReaderAnalyzer* instance) {
-    furi_assert(instance);
-
-    instance->alive = false;
-    furi_thread_join(instance->thread);
-
-    if(instance->debug_log) {
-        nfc_debug_log_free(instance->debug_log);
-        instance->debug_log = NULL;
-    }
-    if(instance->mfkey32) {
-        mfkey32_free(instance->mfkey32);
-        instance->mfkey32 = NULL;
-    }
-    if(instance->pcap) {
-        nfc_debug_pcap_free(instance->pcap);
-        instance->pcap = NULL;
-    }
-}
-
-void reader_analyzer_free(ReaderAnalyzer* instance) {
-    furi_assert(instance);
-
-    reader_analyzer_stop(instance);
-    furi_thread_free(instance->thread);
-    furi_stream_buffer_free(instance->stream);
-    free(instance);
-}
-
-void reader_analyzer_set_callback(
-    ReaderAnalyzer* instance,
-    ReaderAnalyzerParseDataCallback callback,
-    void* context) {
-    furi_assert(instance);
-    furi_assert(callback);
-
-    instance->callback = callback;
-    instance->context = context;
-}
-
-NfcProtocol
-    reader_analyzer_guess_protocol(ReaderAnalyzer* instance, uint8_t* buff_rx, uint16_t len) {
-    furi_assert(instance);
-    furi_assert(buff_rx);
-    UNUSED(len);
-    NfcProtocol protocol = NfcDeviceProtocolUnknown;
-
-    if((buff_rx[0] == 0x60) || (buff_rx[0] == 0x61)) {
-        protocol = NfcDeviceProtocolMifareClassic;
-    }
-
-    return protocol;
-}
-
-FurryHalNfcDevData* reader_analyzer_get_nfc_data(ReaderAnalyzer* instance) {
-    furi_assert(instance);
-    instance->nfc_data = reader_analyzer_nfc_data[ReaderAnalyzerNfcDataMfClassic];
-    return &instance->nfc_data;
-}
-
-void reader_analyzer_set_nfc_data(ReaderAnalyzer* instance, FurryHalNfcDevData* nfc_data) {
-    furi_assert(instance);
-    furi_assert(nfc_data);
-
-    memcpy(&instance->nfc_data, nfc_data, sizeof(FurryHalNfcDevData));
-}
-
-static void reader_analyzer_write(
-    ReaderAnalyzer* instance,
-    uint8_t* data,
-    uint16_t len,
-    bool reader_to_tag,
-    bool crc_dropped) {
-    ReaderAnalyzerHeader header = {
-        .reader_to_tag = reader_to_tag, .crc_dropped = crc_dropped, .len = len};
-    size_t data_sent = 0;
-    data_sent = furi_stream_buffer_send(
-        instance->stream, &header, sizeof(ReaderAnalyzerHeader), FuriWaitForever);
-    if(data_sent != sizeof(ReaderAnalyzerHeader)) {
-        FURI_LOG_W(TAG, "Sent %zu out of %zu bytes", data_sent, sizeof(ReaderAnalyzerHeader));
-    }
-    data_sent = furi_stream_buffer_send(instance->stream, data, len, FuriWaitForever);
-    if(data_sent != len) {
-        FURI_LOG_W(TAG, "Sent %zu out of %u bytes", data_sent, len);
-    }
-}
-
-static void
-    reader_analyzer_write_rx(uint8_t* data, uint16_t bits, bool crc_dropped, void* context) {
-    UNUSED(crc_dropped);
-    ReaderAnalyzer* reader_analyzer = context;
-    uint16_t bytes = bits < 8 ? 1 : bits / 8;
-    reader_analyzer_write(reader_analyzer, data, bytes, false, crc_dropped);
-}
-
-static void
-    reader_analyzer_write_tx(uint8_t* data, uint16_t bits, bool crc_dropped, void* context) {
-    UNUSED(crc_dropped);
-    ReaderAnalyzer* reader_analyzer = context;
-    uint16_t bytes = bits < 8 ? 1 : bits / 8;
-    reader_analyzer_write(reader_analyzer, data, bytes, true, crc_dropped);
-}
-
-void reader_analyzer_prepare_tx_rx(
-    ReaderAnalyzer* instance,
-    FurryHalNfcTxRxContext* tx_rx,
-    bool is_picc) {
-    furi_assert(instance);
-    furi_assert(tx_rx);
-
-    if(is_picc) {
-        tx_rx->sniff_tx = reader_analyzer_write_rx;
-        tx_rx->sniff_rx = reader_analyzer_write_tx;
-    } else {
-        tx_rx->sniff_rx = reader_analyzer_write_rx;
-        tx_rx->sniff_tx = reader_analyzer_write_tx;
-    }
-
-    tx_rx->sniff_context = instance;
-}

+ 0 - 43
lib/nfclegacy/helpers/reader_analyzer.h

@@ -1,43 +0,0 @@
-#pragma once
-
-#include <stdint.h>
-#include "../nfc_device.h"
-
-typedef enum {
-    ReaderAnalyzerModeDebugLog = 0x01,
-    ReaderAnalyzerModeMfkey = 0x02,
-    ReaderAnalyzerModeDebugPcap = 0x04,
-} ReaderAnalyzerMode;
-
-typedef enum {
-    ReaderAnalyzerEventMfkeyCollected,
-} ReaderAnalyzerEvent;
-
-typedef struct ReaderAnalyzer ReaderAnalyzer;
-
-typedef void (*ReaderAnalyzerParseDataCallback)(ReaderAnalyzerEvent event, void* context);
-
-ReaderAnalyzer* reader_analyzer_alloc();
-
-void reader_analyzer_free(ReaderAnalyzer* instance);
-
-void reader_analyzer_set_callback(
-    ReaderAnalyzer* instance,
-    ReaderAnalyzerParseDataCallback callback,
-    void* context);
-
-void reader_analyzer_start(ReaderAnalyzer* instance, ReaderAnalyzerMode mode);
-
-void reader_analyzer_stop(ReaderAnalyzer* instance);
-
-NfcProtocol
-    reader_analyzer_guess_protocol(ReaderAnalyzer* instance, uint8_t* buff_rx, uint16_t len);
-
-FurryHalNfcDevData* reader_analyzer_get_nfc_data(ReaderAnalyzer* instance);
-
-void reader_analyzer_set_nfc_data(ReaderAnalyzer* instance, FurryHalNfcDevData* nfc_data);
-
-void reader_analyzer_prepare_tx_rx(
-    ReaderAnalyzer* instance,
-    FurryHalNfcTxRxContext* tx_rx,
-    bool is_picc);

+ 1 - 338
lib/nfclegacy/nfc_device.c

@@ -13,11 +13,7 @@
 static const char* nfc_file_header = "Flipper NFC device";
 static const uint32_t nfc_file_version = 3;
 
-static const char* nfc_keys_file_header = "Flipper NFC keys";
-static const uint32_t nfc_keys_file_version = 1;
-
 // Protocols format versions
-static const uint32_t nfc_mifare_classic_data_format_version = 2;
 static const uint32_t nfc_mifare_ultralight_data_format_version = 1;
 
 NfcDevice* nfc_device_alloc() {
@@ -236,330 +232,6 @@ bool nfc_device_load_mifare_ul_data(FlipperFormat* file, NfcDevice* dev) {
     return parsed;
 }
 
-static void nfc_device_write_mifare_classic_block(
-    FuriString* block_str,
-    MfClassicData* data,
-    uint8_t block_num) {
-    furi_string_reset(block_str);
-    bool is_sec_trailer = mf_classic_is_sector_trailer(block_num);
-    if(is_sec_trailer) {
-        uint8_t sector_num = mf_classic_get_sector_by_block(block_num);
-        MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, sector_num);
-        // Write key A
-        for(size_t i = 0; i < sizeof(sec_tr->key_a); i++) {
-            if(mf_classic_is_key_found(data, sector_num, MfClassicKeyA)) {
-                furi_string_cat_printf(block_str, "%02X ", sec_tr->key_a[i]);
-            } else {
-                furi_string_cat_printf(block_str, "?? ");
-            }
-        }
-        // Write Access bytes
-        for(size_t i = 0; i < MF_CLASSIC_ACCESS_BYTES_SIZE; i++) {
-            if(mf_classic_is_block_read(data, block_num)) {
-                furi_string_cat_printf(block_str, "%02X ", sec_tr->access_bits[i]);
-            } else {
-                furi_string_cat_printf(block_str, "?? ");
-            }
-        }
-        // Write key B
-        for(size_t i = 0; i < sizeof(sec_tr->key_b); i++) {
-            if(mf_classic_is_key_found(data, sector_num, MfClassicKeyB)) {
-                furi_string_cat_printf(block_str, "%02X ", sec_tr->key_b[i]);
-            } else {
-                furi_string_cat_printf(block_str, "?? ");
-            }
-        }
-    } else {
-        // Write data block
-        for(size_t i = 0; i < MF_CLASSIC_BLOCK_SIZE; i++) {
-            if(mf_classic_is_block_read(data, block_num)) {
-                furi_string_cat_printf(block_str, "%02X ", data->block[block_num].value[i]);
-            } else {
-                furi_string_cat_printf(block_str, "?? ");
-            }
-        }
-    }
-    furi_string_trim(block_str);
-}
-
-static bool nfc_device_save_mifare_classic_data(FlipperFormat* file, NfcDevice* dev) {
-    bool saved = false;
-    MfClassicData* data = &dev->dev_data.mf_classic_data;
-    FuriString* temp_str;
-    temp_str = furi_string_alloc();
-    uint16_t blocks = 0;
-
-    // Save Mifare Classic specific data
-    do {
-        if(!flipper_format_write_comment_cstr(file, "Mifare Classic specific data")) break;
-
-        if(data->type == MfClassicTypeMini) {
-            if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "MINI")) break;
-            blocks = 20;
-        } else if(data->type == MfClassicType1k) {
-            if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "1K")) break;
-            blocks = 64;
-        } else if(data->type == MfClassicType4k) {
-            if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "4K")) break;
-            blocks = 256;
-        }
-        if(!flipper_format_write_uint32(
-               file, "Data format version", &nfc_mifare_classic_data_format_version, 1))
-            break;
-        if(!flipper_format_write_comment_cstr(
-               file, "Mifare Classic blocks, \'??\' means unknown data"))
-            break;
-        bool block_saved = true;
-        FuriString* block_str;
-        block_str = furi_string_alloc();
-        for(size_t i = 0; i < blocks; i++) {
-            furi_string_printf(temp_str, "Block %d", i);
-            nfc_device_write_mifare_classic_block(block_str, data, i);
-            if(!flipper_format_write_string(file, furi_string_get_cstr(temp_str), block_str)) {
-                block_saved = false;
-                break;
-            }
-        }
-        furi_string_free(block_str);
-        if(!block_saved) break;
-        saved = true;
-    } while(false);
-
-    furi_string_free(temp_str);
-    return saved;
-}
-
-static void nfc_device_load_mifare_classic_block(
-    FuriString* block_str,
-    MfClassicData* data,
-    uint8_t block_num) {
-    furi_string_trim(block_str);
-    MfClassicBlock block_tmp = {};
-    bool is_sector_trailer = mf_classic_is_sector_trailer(block_num);
-    uint8_t sector_num = mf_classic_get_sector_by_block(block_num);
-    uint16_t block_unknown_bytes_mask = 0;
-
-    furi_string_trim(block_str);
-    for(size_t i = 0; i < MF_CLASSIC_BLOCK_SIZE; i++) {
-        char hi = furi_string_get_char(block_str, 3 * i);
-        char low = furi_string_get_char(block_str, 3 * i + 1);
-        uint8_t byte = 0;
-        if(hex_char_to_uint8(hi, low, &byte)) {
-            block_tmp.value[i] = byte;
-        } else {
-            FURI_BIT_SET(block_unknown_bytes_mask, i);
-        }
-    }
-
-    if(block_unknown_bytes_mask == 0xffff) {
-        // All data is unknown, exit
-        return;
-    }
-
-    if(is_sector_trailer) {
-        MfClassicSectorTrailer* sec_tr_tmp = (MfClassicSectorTrailer*)&block_tmp;
-        // Load Key A
-        // Key A mask 0b0000000000111111 = 0x003f
-        if((block_unknown_bytes_mask & 0x003f) == 0) {
-            uint64_t key = nfc_util_bytes2num(sec_tr_tmp->key_a, sizeof(sec_tr_tmp->key_a));
-            mf_classic_set_key_found(data, sector_num, MfClassicKeyA, key);
-        }
-        // Load Access Bits
-        // Access bits mask 0b0000001111000000 = 0x03c0
-        if((block_unknown_bytes_mask & 0x03c0) == 0) {
-            mf_classic_set_block_read(data, block_num, &block_tmp);
-        }
-        // Load Key B
-        // Key B mask 0b1111110000000000 = 0xfc00
-        if((block_unknown_bytes_mask & 0xfc00) == 0) {
-            uint64_t key = nfc_util_bytes2num(sec_tr_tmp->key_b, sizeof(sec_tr_tmp->key_b));
-            mf_classic_set_key_found(data, sector_num, MfClassicKeyB, key);
-        }
-    } else {
-        if(block_unknown_bytes_mask == 0) {
-            mf_classic_set_block_read(data, block_num, &block_tmp);
-        }
-    }
-}
-
-static bool nfc_device_load_mifare_classic_data(FlipperFormat* file, NfcDevice* dev) {
-    bool parsed = false;
-    MfClassicData* data = &dev->dev_data.mf_classic_data;
-    FuriString* temp_str;
-    uint32_t data_format_version = 0;
-    temp_str = furi_string_alloc();
-    uint16_t data_blocks = 0;
-    memset(data, 0, sizeof(MfClassicData));
-
-    do {
-        // Read Mifare Classic type
-        if(!flipper_format_read_string(file, "Mifare Classic type", temp_str)) break;
-        if(!furi_string_cmp(temp_str, "MINI")) {
-            data->type = MfClassicTypeMini;
-            data_blocks = 20;
-        } else if(!furi_string_cmp(temp_str, "1K")) {
-            data->type = MfClassicType1k;
-            data_blocks = 64;
-        } else if(!furi_string_cmp(temp_str, "4K")) {
-            data->type = MfClassicType4k;
-            data_blocks = 256;
-        } else {
-            break;
-        }
-
-        bool old_format = false;
-        // Read Mifare Classic format version
-        if(!flipper_format_read_uint32(file, "Data format version", &data_format_version, 1)) {
-            // Load unread sectors with zero keys access for backward compatibility
-            if(!flipper_format_rewind(file)) break;
-            old_format = true;
-        } else {
-            if(data_format_version < nfc_mifare_classic_data_format_version) {
-                old_format = true;
-            }
-        }
-
-        // Read Mifare Classic blocks
-        bool block_read = true;
-        FuriString* block_str;
-        block_str = furi_string_alloc();
-        for(size_t i = 0; i < data_blocks; i++) {
-            furi_string_printf(temp_str, "Block %d", i);
-            if(!flipper_format_read_string(file, furi_string_get_cstr(temp_str), block_str)) {
-                block_read = false;
-                break;
-            }
-            nfc_device_load_mifare_classic_block(block_str, data, i);
-        }
-        furi_string_free(block_str);
-        if(!block_read) break;
-
-        // Set keys and blocks as unknown for backward compatibility
-        if(old_format) {
-            data->key_a_mask = 0ULL;
-            data->key_b_mask = 0ULL;
-            memset(data->block_read_mask, 0, sizeof(data->block_read_mask));
-        }
-
-        parsed = true;
-    } while(false);
-
-    furi_string_free(temp_str);
-    return parsed;
-}
-
-static void nfc_device_get_key_cache_file_path(NfcDevice* dev, FuriString* file_path) {
-    uint8_t* uid = dev->dev_data.nfc_data.uid;
-    uint8_t uid_len = dev->dev_data.nfc_data.uid_len;
-    furi_string_set(file_path, NFC_DEVICE_KEYS_FOLDER "/");
-    for(size_t i = 0; i < uid_len; i++) {
-        furi_string_cat_printf(file_path, "%02X", uid[i]);
-    }
-    furi_string_cat_printf(file_path, NFC_DEVICE_KEYS_EXTENSION);
-}
-
-static bool nfc_device_save_mifare_classic_keys(NfcDevice* dev) {
-    FlipperFormat* file = flipper_format_file_alloc(dev->storage);
-    MfClassicData* data = &dev->dev_data.mf_classic_data;
-    FuriString* temp_str;
-    temp_str = furi_string_alloc();
-
-    nfc_device_get_key_cache_file_path(dev, temp_str);
-    bool save_success = false;
-    do {
-        if(!storage_simply_mkdir(dev->storage, NFC_DEVICE_KEYS_FOLDER)) break;
-        if(!storage_simply_remove(dev->storage, furi_string_get_cstr(temp_str))) break;
-        if(!flipper_format_file_open_always(file, furi_string_get_cstr(temp_str))) break;
-        if(!flipper_format_write_header_cstr(file, nfc_keys_file_header, nfc_keys_file_version))
-            break;
-        if(data->type == MfClassicTypeMini) {
-            if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "MINI")) break;
-        } else if(data->type == MfClassicType1k) {
-            if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "1K")) break;
-        } else if(data->type == MfClassicType4k) {
-            if(!flipper_format_write_string_cstr(file, "Mifare Classic type", "4K")) break;
-        }
-        if(!flipper_format_write_hex_uint64(file, "Key A map", &data->key_a_mask, 1)) break;
-        if(!flipper_format_write_hex_uint64(file, "Key B map", &data->key_b_mask, 1)) break;
-        uint8_t sector_num = mf_classic_get_total_sectors_num(data->type);
-        bool key_save_success = true;
-        for(size_t i = 0; (i < sector_num) && (key_save_success); i++) {
-            MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, i);
-            if(FURI_BIT(data->key_a_mask, i)) {
-                furi_string_printf(temp_str, "Key A sector %d", i);
-                key_save_success = flipper_format_write_hex(
-                    file, furi_string_get_cstr(temp_str), sec_tr->key_a, 6);
-            }
-            if(!key_save_success) break;
-            if(FURI_BIT(data->key_b_mask, i)) {
-                furi_string_printf(temp_str, "Key B sector %d", i);
-                key_save_success = flipper_format_write_hex(
-                    file, furi_string_get_cstr(temp_str), sec_tr->key_b, 6);
-            }
-        }
-        save_success = key_save_success;
-    } while(false);
-
-    flipper_format_free(file);
-    furi_string_free(temp_str);
-    return save_success;
-}
-
-bool nfc_device_load_key_cache(NfcDevice* dev) {
-    furi_assert(dev);
-    FuriString* temp_str;
-    temp_str = furi_string_alloc();
-
-    MfClassicData* data = &dev->dev_data.mf_classic_data;
-    nfc_device_get_key_cache_file_path(dev, temp_str);
-    FlipperFormat* file = flipper_format_file_alloc(dev->storage);
-
-    bool load_success = false;
-    do {
-        if(storage_common_stat(dev->storage, furi_string_get_cstr(temp_str), NULL) != FSE_OK)
-            break;
-        if(!flipper_format_file_open_existing(file, furi_string_get_cstr(temp_str))) break;
-        uint32_t version = 0;
-        if(!flipper_format_read_header(file, temp_str, &version)) break;
-        if(furi_string_cmp_str(temp_str, nfc_keys_file_header)) break;
-        if(version != nfc_keys_file_version) break;
-        if(!flipper_format_read_string(file, "Mifare Classic type", temp_str)) break;
-        if(!furi_string_cmp(temp_str, "MINI")) {
-            data->type = MfClassicTypeMini;
-        } else if(!furi_string_cmp(temp_str, "1K")) {
-            data->type = MfClassicType1k;
-        } else if(!furi_string_cmp(temp_str, "4K")) {
-            data->type = MfClassicType4k;
-        } else {
-            break;
-        }
-        if(!flipper_format_read_hex_uint64(file, "Key A map", &data->key_a_mask, 1)) break;
-        if(!flipper_format_read_hex_uint64(file, "Key B map", &data->key_b_mask, 1)) break;
-        uint8_t sectors = mf_classic_get_total_sectors_num(data->type);
-        bool key_read_success = true;
-        for(size_t i = 0; (i < sectors) && (key_read_success); i++) {
-            MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, i);
-            if(FURI_BIT(data->key_a_mask, i)) {
-                furi_string_printf(temp_str, "Key A sector %d", i);
-                key_read_success = flipper_format_read_hex(
-                    file, furi_string_get_cstr(temp_str), sec_tr->key_a, 6);
-            }
-            if(!key_read_success) break;
-            if(FURI_BIT(data->key_b_mask, i)) {
-                furi_string_printf(temp_str, "Key B sector %d", i);
-                key_read_success = flipper_format_read_hex(
-                    file, furi_string_get_cstr(temp_str), sec_tr->key_b, 6);
-            }
-        }
-        load_success = key_read_success;
-    } while(false);
-
-    furi_string_free(temp_str);
-    flipper_format_free(file);
-
-    return load_success;
-}
-
 void nfc_device_set_name(NfcDevice* dev, const char* name) {
     furi_assert(dev);
 
@@ -638,11 +310,6 @@ bool nfc_device_save(NfcDevice* dev, const char* dev_name) {
         // Save more data if necessary
         if(dev->format == NfcDeviceSaveFormatMifareUl) {
             if(!nfc_device_save_mifare_ul_data(file, dev)) break;
-        } else if(dev->format == NfcDeviceSaveFormatMifareClassic) {
-            // Save data
-            if(!nfc_device_save_mifare_classic_data(file, dev)) break;
-            // Save keys cache
-            if(!nfc_device_save_mifare_classic_keys(dev)) break;
         }
         saved = true;
     } while(0);
@@ -737,8 +404,6 @@ static bool nfc_device_load_data(NfcDevice* dev, FuriString* path, bool show_dia
         // Parse other data
         if(dev->format == NfcDeviceSaveFormatMifareUl) {
             if(!nfc_device_load_mifare_ul_data(file, dev)) break;
-        } else if(dev->format == NfcDeviceSaveFormatMifareClassic) {
-            if(!nfc_device_load_mifare_classic_data(file, dev)) break;
         }
         parsed = true;
     } while(false);
@@ -780,9 +445,7 @@ bool nfc_device_load(NfcDevice* dev, const char* file_path, bool show_dialog) {
 }
 
 void nfc_device_data_clear(NfcDeviceData* dev_data) {
-    if(dev_data->protocol == NfcDeviceProtocolMifareClassic) {
-        memset(&dev_data->mf_classic_data, 0, sizeof(MfClassicData));
-    } else if(dev_data->protocol == NfcDeviceProtocolMifareUl) {
+    if(dev_data->protocol == NfcDeviceProtocolMifareUl) {
         mf_ul_reset(&dev_data->mf_ul_data);
     }
 

+ 0 - 9
lib/nfclegacy/nfc_device.h

@@ -6,9 +6,7 @@
 #include <dialogs/dialogs.h>
 
 #include "./furi_hal_nfc.h"
-#include "helpers/mf_classic_dict.h"
 #include "protocols/mifare_ultralight.h"
-#include "protocols/mifare_classic.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -47,11 +45,6 @@ typedef struct {
     uint16_t size;
 } NfcReaderRequestData;
 
-typedef struct {
-    MfClassicDict* dict;
-    uint8_t current_sector;
-} NfcMfClassicDictAttackData;
-
 typedef enum {
     NfcReadModeAuto,
     NfcReadModeMfClassic,
@@ -67,12 +60,10 @@ typedef struct {
     NfcReadMode read_mode;
     union {
         NfcReaderRequestData reader_data;
-        NfcMfClassicDictAttackData mf_classic_dict_attack_data;
         MfUltralightAuth mf_ul_auth;
     };
     union {
         MfUltralightData mf_ul_data;
-        MfClassicData mf_classic_data;
     };
     FuriString* parsed_data;
 } NfcDeviceData;

+ 0 - 12
lib/nfclegacy/nfc_types.c

@@ -55,15 +55,3 @@ const char* nfc_mf_ul_type(MfUltralightType type, bool full_name) {
         return "Mifare Ultralight";
     }
 }
-
-const char* nfc_mf_classic_type(MfClassicType type) {
-    if(type == MfClassicTypeMini) {
-        return "Mifare Mini 0.3K";
-    } else if(type == MfClassicType1k) {
-        return "Mifare Classic 1K";
-    } else if(type == MfClassicType4k) {
-        return "Mifare Classic 4K";
-    } else {
-        return "Mifare Classic";
-    }
-}

+ 0 - 2
lib/nfclegacy/nfc_types.h

@@ -12,8 +12,6 @@ const char* nfc_guess_protocol(NfcProtocol protocol);
 
 const char* nfc_mf_ul_type(MfUltralightType type, bool full_name);
 
-const char* nfc_mf_classic_type(MfClassicType type);
-
 #ifdef __cplusplus
 }
 #endif

+ 2 - 583
lib/nfclegacy/nfc_worker.c

@@ -23,8 +23,6 @@ NfcWorker* nfc_worker_alloc() {
     }
     nfc_worker_change_state(nfc_worker, NfcWorkerStateReady);
 
-    nfc_worker->reader_analyzer = reader_analyzer_alloc(nfc_worker->storage);
-
     return nfc_worker;
 }
 
@@ -35,8 +33,6 @@ void nfc_worker_free(NfcWorker* nfc_worker) {
 
     furi_record_close(RECORD_STORAGE);
 
-    reader_analyzer_free(nfc_worker->reader_analyzer);
-
     free(nfc_worker);
 }
 
@@ -96,18 +92,8 @@ int32_t nfc_worker_task(void* context) {
         nfc_worker_emulate_uid(nfc_worker);
     } else if(nfc_worker->state == NfcWorkerStateMfUltralightEmulate) {
         nfc_worker_emulate_mf_ultralight(nfc_worker);
-    } else if(nfc_worker->state == NfcWorkerStateMfClassicEmulate) {
-        nfc_worker_emulate_mf_classic(nfc_worker);
-    } else if(nfc_worker->state == NfcWorkerStateMfClassicWrite) {
-        nfc_worker_write_mf_classic(nfc_worker);
-    } else if(nfc_worker->state == NfcWorkerStateMfClassicUpdate) {
-        nfc_worker_update_mf_classic(nfc_worker);
     } else if(nfc_worker->state == NfcWorkerStateReadMfUltralightReadAuth) {
         nfc_worker_mf_ultralight_read_auth(nfc_worker);
-    } else if(nfc_worker->state == NfcWorkerStateMfClassicDictAttack) {
-        nfc_worker_mf_classic_dict_attack(nfc_worker);
-    } else if(nfc_worker->state == NfcWorkerStateAnalyzeReader) {
-        nfc_worker_analyze_reader(nfc_worker);
     }
     furry_hal_nfc_sleep();
     nfc_worker_change_state(nfc_worker, NfcWorkerStateReady);
@@ -120,11 +106,6 @@ static bool nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker, FurryHalNfcTxRx
     MfUltralightReader reader = {};
     MfUltralightData data = {};
 
-    if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
-        reader_analyzer_prepare_tx_rx(nfc_worker->reader_analyzer, tx_rx, false);
-        reader_analyzer_start(nfc_worker->reader_analyzer, ReaderAnalyzerModeDebugLog);
-    }
-
     do {
         furry_hal_nfc_sleep();
 
@@ -136,39 +117,6 @@ static bool nfc_worker_read_mf_ultralight(NfcWorker* nfc_worker, FurryHalNfcTxRx
         read_success = true;
     } while(false);
 
-    if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
-        reader_analyzer_stop(nfc_worker->reader_analyzer);
-    }
-
-    return read_success;
-}
-
-static bool nfc_worker_read_mf_classic(NfcWorker* nfc_worker, FurryHalNfcTxRxContext* tx_rx) {
-    furi_assert(nfc_worker->callback);
-    bool read_success = false;
-
-    if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
-        reader_analyzer_prepare_tx_rx(nfc_worker->reader_analyzer, tx_rx, false);
-        reader_analyzer_start(nfc_worker->reader_analyzer, ReaderAnalyzerModeDebugLog);
-    }
-
-    do {
-        // Try to read card with key cache
-        FURI_LOG_I(TAG, "Search for key cache ...");
-        if(nfc_worker->callback(NfcWorkerEventReadMfClassicLoadKeyCache, nfc_worker->context)) {
-            FURI_LOG_I(TAG, "Load keys cache success. Start reading");
-            uint8_t sectors_read =
-                mf_classic_update_card(tx_rx, &nfc_worker->dev_data->mf_classic_data);
-            uint8_t sectors_total =
-                mf_classic_get_total_sectors_num(nfc_worker->dev_data->mf_classic_data.type);
-            FURI_LOG_I(TAG, "Read %d sectors out of %d total", sectors_read, sectors_total);
-            read_success = mf_classic_is_card_read(&nfc_worker->dev_data->mf_classic_data);
-        }
-    } while(false);
-
-    if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
-        reader_analyzer_stop(nfc_worker->reader_analyzer);
-    }
     return read_success;
 }
 
@@ -181,12 +129,6 @@ static bool nfc_worker_read_nfca(NfcWorker* nfc_worker, FurryHalNfcTxRxContext*
         FURI_LOG_I(TAG, "Mifare Ultralight / NTAG detected");
         nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareUl;
         card_read = nfc_worker_read_mf_ultralight(nfc_worker, tx_rx);
-    } else if(mf_classic_check_card_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak)) {
-        FURI_LOG_I(TAG, "Mifare Classic detected");
-        nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareClassic;
-        nfc_worker->dev_data->mf_classic_data.type =
-            mf_classic_get_classic_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak);
-        card_read = nfc_worker_read_mf_classic(nfc_worker, tx_rx);
     } else if(nfc_data->interface == FurryHalNfcInterfaceIsoDep) {
         FURI_LOG_I(TAG, "ISO14443-4 card detected");
 
@@ -269,7 +211,7 @@ void nfc_worker_read_type(NfcWorker* nfc_worker) {
 
     NfcReadMode read_mode = nfc_worker->dev_data->read_mode;
     nfc_device_data_clear(nfc_worker->dev_data);
-    NfcDeviceData* dev_data = nfc_worker->dev_data;
+    //NfcDeviceData* dev_data = nfc_worker->dev_data;
     FurryHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data;
     FurryHalNfcTxRxContext tx_rx = {};
     NfcWorkerEvent event = 0;
@@ -284,20 +226,7 @@ void nfc_worker_read_type(NfcWorker* nfc_worker) {
             card_not_detected_notified = false;
             if(nfc_data->type == FurryHalNfcTypeA) {
                 if(read_mode == NfcReadModeMfClassic) {
-                    nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareClassic;
-                    nfc_worker->dev_data->mf_classic_data.type = mf_classic_get_classic_type(
-                        nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak);
-                    if(nfc_worker_read_mf_classic(nfc_worker, &tx_rx)) {
-                        FURI_LOG_D(TAG, "Card read");
-                        dev_data->protocol = NfcDeviceProtocolMifareClassic;
-                        event = NfcWorkerEventReadMfClassicDone;
-                        break;
-                    } else {
-                        FURI_LOG_D(TAG, "Card read failed");
-                        dev_data->protocol = NfcDeviceProtocolMifareClassic;
-                        event = NfcWorkerEventReadMfClassicDictAttackRequired;
-                        break;
-                    }
+                    // none
                 } else if(read_mode == NfcReadModeMfUltralight) {
                     FURI_LOG_I(TAG, "Mifare Ultralight / NTAG");
                     nfc_worker->dev_data->protocol = NfcDeviceProtocolMifareUl;
@@ -395,428 +324,6 @@ void nfc_worker_emulate_mf_ultralight(NfcWorker* nfc_worker) {
     rfal_platform_spi_release();
 }
 
-static bool nfc_worker_mf_get_b_key_from_sector_trailer(
-    FurryHalNfcTxRxContext* tx_rx,
-    uint16_t sector,
-    uint64_t key,
-    uint64_t* found_key) {
-    // Some access conditions allow reading B key via A key
-
-    uint8_t block = mf_classic_get_sector_trailer_block_num_by_sector(sector);
-
-    Crypto1 crypto = {};
-    MfClassicBlock block_tmp = {};
-    MfClassicAuthContext auth_context = {.sector = sector, .key_a = MF_CLASSIC_NO_KEY, .key_b = 0};
-
-    furry_hal_nfc_sleep();
-
-    if(mf_classic_auth_attempt(tx_rx, &crypto, &auth_context, key)) {
-        if(mf_classic_read_block(tx_rx, &crypto, block, &block_tmp)) {
-            *found_key = nfc_util_bytes2num(&block_tmp.value[10], sizeof(uint8_t) * 6);
-
-            return *found_key;
-        }
-    }
-
-    return false;
-}
-
-static void nfc_worker_mf_classic_key_attack(
-    NfcWorker* nfc_worker,
-    uint64_t key,
-    FurryHalNfcTxRxContext* tx_rx,
-    uint16_t start_sector) {
-    furi_assert(nfc_worker);
-    furi_assert(nfc_worker->callback);
-
-    bool card_found_notified = true;
-    bool card_removed_notified = false;
-
-    MfClassicData* data = &nfc_worker->dev_data->mf_classic_data;
-    NfcMfClassicDictAttackData* dict_attack_data =
-        &nfc_worker->dev_data->mf_classic_dict_attack_data;
-    uint32_t total_sectors = mf_classic_get_total_sectors_num(data->type);
-
-    furi_assert(start_sector < total_sectors);
-
-    nfc_worker->callback(NfcWorkerEventKeyAttackStart, nfc_worker->context);
-
-    // Check every sector's A and B keys with the given key
-    for(size_t i = start_sector; i < total_sectors; i++) {
-        nfc_worker->callback(NfcWorkerEventKeyAttackNextSector, nfc_worker->context);
-        dict_attack_data->current_sector = i;
-        furry_hal_nfc_sleep();
-        if(furry_hal_nfc_activate_nfca(200, NULL)) {
-            furry_hal_nfc_sleep();
-            if(!card_found_notified) {
-                nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context);
-                card_found_notified = true;
-                card_removed_notified = false;
-            }
-            uint8_t block_num = mf_classic_get_sector_trailer_block_num_by_sector(i);
-            if(mf_classic_is_sector_read(data, i)) continue;
-            if(!mf_classic_is_key_found(data, i, MfClassicKeyA)) {
-                FURI_LOG_D(TAG, "Trying A key for sector %d, key: %012llX", i, key);
-                if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyA)) {
-                    mf_classic_set_key_found(data, i, MfClassicKeyA, key);
-                    FURI_LOG_D(TAG, "Key A found: %012llX", key);
-                    nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context);
-
-                    uint64_t found_key;
-                    if(nfc_worker_mf_get_b_key_from_sector_trailer(tx_rx, i, key, &found_key)) {
-                        FURI_LOG_D(TAG, "Found B key via reading sector %d", i);
-                        mf_classic_set_key_found(data, i, MfClassicKeyB, found_key);
-
-                        if(nfc_worker->state == NfcWorkerStateMfClassicDictAttack) {
-                            nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context);
-                        }
-                    }
-                }
-                furry_hal_nfc_sleep();
-            }
-            if(!mf_classic_is_key_found(data, i, MfClassicKeyB)) {
-                FURI_LOG_D(TAG, "Trying B key for sector %d, key: %012llX", i, key);
-                if(mf_classic_authenticate(tx_rx, block_num, key, MfClassicKeyB)) {
-                    mf_classic_set_key_found(data, i, MfClassicKeyB, key);
-                    FURI_LOG_D(TAG, "Key B found: %012llX", key);
-                    nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context);
-                }
-            }
-
-            if(mf_classic_is_sector_read(data, i)) continue;
-            mf_classic_read_sector(tx_rx, data, i);
-        } else {
-            if(!card_removed_notified) {
-                nfc_worker->callback(NfcWorkerEventNoCardDetected, nfc_worker->context);
-                card_removed_notified = true;
-                card_found_notified = false;
-            }
-        }
-        if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break;
-    }
-    nfc_worker->callback(NfcWorkerEventKeyAttackStop, nfc_worker->context);
-}
-
-void nfc_worker_mf_classic_dict_attack(NfcWorker* nfc_worker) {
-    furi_assert(nfc_worker);
-    furi_assert(nfc_worker->callback);
-
-    MfClassicData* data = &nfc_worker->dev_data->mf_classic_data;
-    NfcMfClassicDictAttackData* dict_attack_data =
-        &nfc_worker->dev_data->mf_classic_dict_attack_data;
-    uint32_t total_sectors = mf_classic_get_total_sectors_num(data->type);
-    uint64_t key = 0;
-    uint64_t prev_key = 0;
-    FurryHalNfcTxRxContext tx_rx = {};
-    bool card_found_notified = true;
-    bool card_removed_notified = false;
-
-    // Load dictionary
-    MfClassicDict* dict = dict_attack_data->dict;
-    if(!dict) {
-        FURI_LOG_E(TAG, "Dictionary not found");
-        nfc_worker->callback(NfcWorkerEventNoDictFound, nfc_worker->context);
-        return;
-    }
-
-    FURI_LOG_D(
-        TAG, "Start Dictionary attack, Key Count %lu", mf_classic_dict_get_total_keys(dict));
-    for(size_t i = 0; i < total_sectors; i++) {
-        FURI_LOG_I(TAG, "Sector %d", i);
-        nfc_worker->callback(NfcWorkerEventNewSector, nfc_worker->context);
-        uint8_t block_num = mf_classic_get_sector_trailer_block_num_by_sector(i);
-        if(mf_classic_is_sector_read(data, i)) continue;
-        if(mf_classic_is_key_found(data, i, MfClassicKeyA) &&
-           mf_classic_is_key_found(data, i, MfClassicKeyB))
-            continue;
-        uint16_t key_index = 0;
-        while(mf_classic_dict_get_next_key(dict, &key)) {
-            FURI_LOG_T(TAG, "Key %d", key_index);
-            if(++key_index % NFC_DICT_KEY_BATCH_SIZE == 0) {
-                nfc_worker->callback(NfcWorkerEventNewDictKeyBatch, nfc_worker->context);
-            }
-            furry_hal_nfc_sleep();
-            uint32_t cuid;
-            if(furry_hal_nfc_activate_nfca(200, &cuid)) {
-                bool deactivated = false;
-                if(!card_found_notified) {
-                    nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context);
-                    card_found_notified = true;
-                    card_removed_notified = false;
-                    nfc_worker_mf_classic_key_attack(nfc_worker, prev_key, &tx_rx, i);
-                    deactivated = true;
-                }
-                FURI_LOG_D(TAG, "Try to auth to sector %d with key %012llX", i, key);
-                if(!mf_classic_is_key_found(data, i, MfClassicKeyA)) {
-                    if(mf_classic_authenticate_skip_activate(
-                           &tx_rx, block_num, key, MfClassicKeyA, !deactivated, cuid)) {
-                        mf_classic_set_key_found(data, i, MfClassicKeyA, key);
-                        FURI_LOG_D(TAG, "Key A found: %012llX", key);
-                        nfc_worker->callback(NfcWorkerEventFoundKeyA, nfc_worker->context);
-
-                        uint64_t found_key;
-                        if(nfc_worker_mf_get_b_key_from_sector_trailer(
-                               &tx_rx, i, key, &found_key)) {
-                            FURI_LOG_D(TAG, "Found B key via reading sector %d", i);
-                            mf_classic_set_key_found(data, i, MfClassicKeyB, found_key);
-
-                            if(nfc_worker->state == NfcWorkerStateMfClassicDictAttack) {
-                                nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context);
-                            }
-
-                            nfc_worker_mf_classic_key_attack(nfc_worker, found_key, &tx_rx, i + 1);
-                            break;
-                        }
-                        nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1);
-                    }
-                    furry_hal_nfc_sleep();
-                    deactivated = true;
-                } else {
-                    // If the key A is marked as found and matches the searching key, invalidate it
-                    MfClassicSectorTrailer* sec_trailer =
-                        mf_classic_get_sector_trailer_by_sector(data, i);
-
-                    uint8_t current_key[6];
-                    nfc_util_num2bytes(key, 6, current_key);
-
-                    if(mf_classic_is_key_found(data, i, MfClassicKeyA) &&
-                       memcmp(sec_trailer->key_a, current_key, 6) == 0) {
-                        if(!mf_classic_authenticate_skip_activate(
-                               &tx_rx, block_num, key, MfClassicKeyA, !deactivated, cuid)) {
-                            mf_classic_set_key_not_found(data, i, MfClassicKeyA);
-                            FURI_LOG_D(TAG, "Key %dA not found in attack", i);
-                        }
-                    }
-                    furry_hal_nfc_sleep();
-                    deactivated = true;
-                }
-                if(!mf_classic_is_key_found(data, i, MfClassicKeyB)) {
-                    if(mf_classic_authenticate_skip_activate(
-                           &tx_rx, block_num, key, MfClassicKeyB, !deactivated, cuid)) { //-V547
-                        FURI_LOG_D(TAG, "Key B found: %012llX", key);
-                        mf_classic_set_key_found(data, i, MfClassicKeyB, key);
-                        nfc_worker->callback(NfcWorkerEventFoundKeyB, nfc_worker->context);
-                        nfc_worker_mf_classic_key_attack(nfc_worker, key, &tx_rx, i + 1);
-                    }
-                    deactivated = true; //-V1048
-                } else {
-                    // If the key B is marked as found and matches the searching key, invalidate it
-                    MfClassicSectorTrailer* sec_trailer =
-                        mf_classic_get_sector_trailer_by_sector(data, i);
-
-                    uint8_t current_key[6];
-                    nfc_util_num2bytes(key, 6, current_key);
-
-                    if(mf_classic_is_key_found(data, i, MfClassicKeyB) &&
-                       memcmp(sec_trailer->key_b, current_key, 6) == 0) {
-                        if(!mf_classic_authenticate_skip_activate(
-                               &tx_rx, block_num, key, MfClassicKeyB, !deactivated, cuid)) { //-V547
-                            mf_classic_set_key_not_found(data, i, MfClassicKeyB);
-                            FURI_LOG_D(TAG, "Key %dB not found in attack", i);
-                        }
-                        furry_hal_nfc_sleep();
-                        deactivated = true; //-V1048
-                    }
-                }
-                if(mf_classic_is_key_found(data, i, MfClassicKeyA) &&
-                   mf_classic_is_key_found(data, i, MfClassicKeyB))
-                    break;
-                if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break;
-            } else {
-                if(!card_removed_notified) {
-                    nfc_worker->callback(NfcWorkerEventNoCardDetected, nfc_worker->context);
-                    card_removed_notified = true;
-                    card_found_notified = false;
-                }
-                if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break;
-            }
-            prev_key = key;
-        }
-        if(nfc_worker->state != NfcWorkerStateMfClassicDictAttack) break;
-        mf_classic_read_sector(&tx_rx, data, i);
-        mf_classic_dict_rewind(dict);
-    }
-    if(nfc_worker->state == NfcWorkerStateMfClassicDictAttack) {
-        nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context);
-    } else {
-        nfc_worker->callback(NfcWorkerEventAborted, nfc_worker->context);
-    }
-}
-
-void nfc_worker_emulate_mf_classic(NfcWorker* nfc_worker) {
-    FurryHalNfcTxRxContext tx_rx = {};
-    FurryHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data;
-    MfClassicEmulator emulator = {
-        .cuid = nfc_util_bytes2num(&nfc_data->uid[nfc_data->uid_len - 4], 4),
-        .data = nfc_worker->dev_data->mf_classic_data,
-        .data_changed = false,
-    };
-    NfcaSignal* nfca_signal = nfca_signal_alloc();
-    tx_rx.nfca_signal = nfca_signal;
-
-    rfal_platform_spi_acquire();
-
-    furry_hal_nfc_listen_start(nfc_data);
-    while(nfc_worker->state == NfcWorkerStateMfClassicEmulate) { //-V1044
-        if(furry_hal_nfc_listen_rx(&tx_rx, 300)) {
-            if(!mf_classic_emulator(&emulator, &tx_rx, false)) {
-                furry_hal_nfc_listen_start(nfc_data);
-            }
-        }
-    }
-    if(emulator.data_changed) {
-        nfc_worker->dev_data->mf_classic_data = emulator.data;
-        if(nfc_worker->callback) {
-            nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context);
-        }
-        emulator.data_changed = false;
-    }
-
-    nfca_signal_free(nfca_signal);
-
-    rfal_platform_spi_release();
-}
-
-void nfc_worker_write_mf_classic(NfcWorker* nfc_worker) {
-    FurryHalNfcTxRxContext tx_rx = {};
-    bool card_found_notified = false;
-    FurryHalNfcDevData nfc_data = {};
-    MfClassicData* src_data = &nfc_worker->dev_data->mf_classic_data;
-    MfClassicData dest_data = *src_data;
-
-    while(nfc_worker->state == NfcWorkerStateMfClassicWrite) {
-        if(furry_hal_nfc_detect(&nfc_data, 200)) {
-            if(!card_found_notified) {
-                nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context);
-                card_found_notified = true;
-            }
-            furry_hal_nfc_sleep();
-
-            FURI_LOG_I(TAG, "Check low level nfc data");
-            if(memcmp(&nfc_data, &nfc_worker->dev_data->nfc_data, sizeof(FurryHalNfcDevData)) !=
-               0) {
-                FURI_LOG_E(TAG, "Wrong card");
-                nfc_worker->callback(NfcWorkerEventWrongCard, nfc_worker->context);
-                break;
-            }
-
-            FURI_LOG_I(TAG, "Check mf classic type");
-            MfClassicType type =
-                mf_classic_get_classic_type(nfc_data.atqa[0], nfc_data.atqa[1], nfc_data.sak);
-            if(type != nfc_worker->dev_data->mf_classic_data.type) {
-                FURI_LOG_E(TAG, "Wrong mf classic type");
-                nfc_worker->callback(NfcWorkerEventWrongCard, nfc_worker->context);
-                break;
-            }
-
-            // Set blocks not read
-            mf_classic_set_sector_data_not_read(&dest_data);
-            FURI_LOG_I(TAG, "Updating card sectors");
-            uint8_t total_sectors = mf_classic_get_total_sectors_num(type);
-            bool write_success = true;
-            for(uint8_t i = 0; i < total_sectors; i++) {
-                FURI_LOG_I(TAG, "Reading sector %d", i);
-                mf_classic_read_sector(&tx_rx, &dest_data, i);
-                bool old_data_read = mf_classic_is_sector_data_read(src_data, i);
-                bool new_data_read = mf_classic_is_sector_data_read(&dest_data, i);
-                if(old_data_read != new_data_read) {
-                    FURI_LOG_E(TAG, "Failed to update sector %d", i);
-                    write_success = false;
-                    break;
-                }
-                if(nfc_worker->state != NfcWorkerStateMfClassicWrite) break;
-                if(!mf_classic_write_sector(&tx_rx, &dest_data, src_data, i)) {
-                    FURI_LOG_E(TAG, "Failed to write %d sector", i);
-                    write_success = false;
-                    break;
-                }
-            }
-            if(nfc_worker->state != NfcWorkerStateMfClassicWrite) break;
-            if(write_success) {
-                nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context);
-                break;
-            } else {
-                nfc_worker->callback(NfcWorkerEventFail, nfc_worker->context);
-                break;
-            }
-
-        } else {
-            if(card_found_notified) {
-                nfc_worker->callback(NfcWorkerEventNoCardDetected, nfc_worker->context);
-                card_found_notified = false;
-            }
-        }
-        furi_delay_ms(300);
-    }
-}
-
-void nfc_worker_update_mf_classic(NfcWorker* nfc_worker) {
-    FurryHalNfcTxRxContext tx_rx = {};
-    bool card_found_notified = false;
-    FurryHalNfcDevData nfc_data = {};
-    MfClassicData* old_data = &nfc_worker->dev_data->mf_classic_data;
-    MfClassicData new_data = *old_data;
-
-    while(nfc_worker->state == NfcWorkerStateMfClassicUpdate) {
-        if(furry_hal_nfc_detect(&nfc_data, 200)) {
-            if(!card_found_notified) {
-                nfc_worker->callback(NfcWorkerEventCardDetected, nfc_worker->context);
-                card_found_notified = true;
-            }
-            furry_hal_nfc_sleep();
-
-            FURI_LOG_I(TAG, "Check low level nfc data");
-            if(memcmp(&nfc_data, &nfc_worker->dev_data->nfc_data, sizeof(FurryHalNfcDevData)) !=
-               0) {
-                FURI_LOG_E(TAG, "Low level nfc data mismatch");
-                nfc_worker->callback(NfcWorkerEventWrongCard, nfc_worker->context);
-                break;
-            }
-
-            FURI_LOG_I(TAG, "Check MF classic type");
-            MfClassicType type =
-                mf_classic_get_classic_type(nfc_data.atqa[0], nfc_data.atqa[1], nfc_data.sak);
-            if(type != nfc_worker->dev_data->mf_classic_data.type) {
-                FURI_LOG_E(TAG, "MF classic type mismatch");
-                nfc_worker->callback(NfcWorkerEventWrongCard, nfc_worker->context);
-                break;
-            }
-
-            // Set blocks not read
-            mf_classic_set_sector_data_not_read(&new_data);
-            FURI_LOG_I(TAG, "Updating card sectors");
-            uint8_t total_sectors = mf_classic_get_total_sectors_num(type);
-            bool update_success = true;
-            for(uint8_t i = 0; i < total_sectors; i++) {
-                FURI_LOG_I(TAG, "Reading sector %d", i);
-                mf_classic_read_sector(&tx_rx, &new_data, i);
-                bool old_data_read = mf_classic_is_sector_data_read(old_data, i);
-                bool new_data_read = mf_classic_is_sector_data_read(&new_data, i);
-                if(old_data_read != new_data_read) {
-                    FURI_LOG_E(TAG, "Failed to update sector %d", i);
-                    update_success = false;
-                    break;
-                }
-                if(nfc_worker->state != NfcWorkerStateMfClassicUpdate) break;
-            }
-            if(nfc_worker->state != NfcWorkerStateMfClassicUpdate) break;
-
-            // Check updated data
-            if(update_success) {
-                *old_data = new_data;
-                nfc_worker->callback(NfcWorkerEventSuccess, nfc_worker->context);
-                break;
-            }
-        } else {
-            if(card_found_notified) {
-                nfc_worker->callback(NfcWorkerEventNoCardDetected, nfc_worker->context);
-                card_found_notified = false;
-            }
-        }
-        furi_delay_ms(300);
-    }
-}
-
 void nfc_worker_mf_ultralight_read_auth(NfcWorker* nfc_worker) {
     furi_assert(nfc_worker);
     furi_assert(nfc_worker->callback);
@@ -827,11 +334,6 @@ void nfc_worker_mf_ultralight_read_auth(NfcWorker* nfc_worker) {
     MfUltralightReader reader = {};
     mf_ul_reset(data);
 
-    if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
-        reader_analyzer_prepare_tx_rx(nfc_worker->reader_analyzer, &tx_rx, true);
-        reader_analyzer_start(nfc_worker->reader_analyzer, ReaderAnalyzerModeDebugLog);
-    }
-
     uint32_t key = 0;
     uint16_t pack = 0;
     while(nfc_worker->state == NfcWorkerStateReadMfUltralightReadAuth) {
@@ -885,87 +387,4 @@ void nfc_worker_mf_ultralight_read_auth(NfcWorker* nfc_worker) {
             furi_delay_ms(10);
         }
     }
-
-    if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
-        reader_analyzer_stop(nfc_worker->reader_analyzer);
-    }
-}
-
-static void nfc_worker_reader_analyzer_callback(ReaderAnalyzerEvent event, void* context) {
-    furi_assert(context);
-    NfcWorker* nfc_worker = context;
-
-    if((nfc_worker->state == NfcWorkerStateAnalyzeReader) &&
-       (event == ReaderAnalyzerEventMfkeyCollected)) {
-        if(nfc_worker->callback) {
-            nfc_worker->callback(NfcWorkerEventDetectReaderMfkeyCollected, nfc_worker->context);
-        }
-    }
-}
-
-void nfc_worker_analyze_reader(NfcWorker* nfc_worker) {
-    furi_assert(nfc_worker);
-    furi_assert(nfc_worker->callback);
-
-    FurryHalNfcTxRxContext tx_rx = {};
-
-    ReaderAnalyzer* reader_analyzer = nfc_worker->reader_analyzer;
-    FurryHalNfcDevData* nfc_data = NULL;
-    if(nfc_worker->dev_data->protocol == NfcDeviceProtocolMifareClassic) {
-        nfc_data = &nfc_worker->dev_data->nfc_data;
-        reader_analyzer_set_nfc_data(reader_analyzer, nfc_data);
-    } else {
-        nfc_data = reader_analyzer_get_nfc_data(reader_analyzer);
-    }
-    MfClassicEmulator emulator = {
-        .cuid = nfc_util_bytes2num(&nfc_data->uid[nfc_data->uid_len - 4], 4),
-        .data = nfc_worker->dev_data->mf_classic_data,
-        .data_changed = false,
-    };
-    NfcaSignal* nfca_signal = nfca_signal_alloc();
-    tx_rx.nfca_signal = nfca_signal;
-    reader_analyzer_prepare_tx_rx(reader_analyzer, &tx_rx, true);
-    reader_analyzer_start(nfc_worker->reader_analyzer, ReaderAnalyzerModeMfkey);
-    reader_analyzer_set_callback(reader_analyzer, nfc_worker_reader_analyzer_callback, nfc_worker);
-
-    rfal_platform_spi_acquire();
-
-    FURI_LOG_D(TAG, "Start reader analyzer");
-
-    uint8_t reader_no_data_received_cnt = 0;
-    bool reader_no_data_notified = true;
-
-    while(nfc_worker->state == NfcWorkerStateAnalyzeReader) {
-        furry_hal_nfc_listen_start(nfc_data);
-        if(furry_hal_nfc_listen_rx(&tx_rx, 300)) {
-            if(reader_no_data_notified) {
-                nfc_worker->callback(NfcWorkerEventDetectReaderDetected, nfc_worker->context);
-            }
-            reader_no_data_received_cnt = 0;
-            reader_no_data_notified = false;
-            NfcProtocol protocol =
-                reader_analyzer_guess_protocol(reader_analyzer, tx_rx.rx_data, tx_rx.rx_bits / 8);
-            if(protocol == NfcDeviceProtocolMifareClassic) {
-                if(!mf_classic_emulator(&emulator, &tx_rx, true)) {
-                    furry_hal_nfc_listen_start(nfc_data);
-                }
-            }
-        } else {
-            reader_no_data_received_cnt++;
-            if(!reader_no_data_notified && (reader_no_data_received_cnt > 5)) {
-                nfc_worker->callback(NfcWorkerEventDetectReaderLost, nfc_worker->context);
-                reader_no_data_received_cnt = 0;
-                reader_no_data_notified = true;
-            }
-            FURI_LOG_D(TAG, "No data from reader");
-            continue;
-        }
-        furi_delay_ms(1);
-    }
-
-    rfal_platform_spi_release();
-
-    reader_analyzer_stop(nfc_worker->reader_analyzer);
-
-    nfca_signal_free(nfca_signal);
 }

+ 0 - 4
lib/nfclegacy/nfc_worker_i.h

@@ -8,9 +8,7 @@
 #include "protocols/nfc_util.h"
 #include "protocols/mifare_common.h"
 #include "protocols/mifare_ultralight.h"
-#include "protocols/mifare_classic.h"
 #include "protocols/nfca.h"
-#include "helpers/reader_analyzer.h"
 
 struct NfcWorker {
     FuriThread* thread;
@@ -23,8 +21,6 @@ struct NfcWorker {
     void* context;
 
     NfcWorkerState state;
-
-    ReaderAnalyzer* reader_analyzer;
 };
 
 void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state);

+ 0 - 1627
lib/nfclegacy/protocols/mifare_classic.c

@@ -1,1627 +0,0 @@
-#include "mifare_classic.h"
-#include "nfca.h"
-#include "nfc_util.h"
-#include <furi_hal_rtc.h>
-
-// Algorithm from https://github.com/RfidResearchGroup/proxmark3.git
-
-#define TAG "MfClassic"
-
-#define MF_CLASSIC_ACK_CMD 0xAU
-#define MF_CLASSIC_NACK_BUF_VALID_CMD 0x0U
-#define MF_CLASSIC_NACK_BUF_INVALID_CMD 0x4U
-#define MF_CLASSIC_AUTH_KEY_A_CMD 0x60U
-#define MF_CLASSIC_AUTH_KEY_B_CMD 0x61U
-#define MF_CLASSIC_READ_BLOCK_CMD 0x30U
-#define MF_CLASSIC_WRITE_BLOCK_CMD 0xA0U
-#define MF_CLASSIC_TRANSFER_CMD 0xB0U
-#define MF_CLASSIC_DECREMENT_CMD 0xC0U
-#define MF_CLASSIC_INCREMENT_CMD 0xC1U
-#define MF_CLASSIC_RESTORE_CMD 0xC2U
-
-const char* mf_classic_get_type_str(MfClassicType type) {
-    if(type == MfClassicTypeMini) {
-        return "MIFARE Mini 0.3K";
-    } else if(type == MfClassicType1k) {
-        return "MIFARE Classic 1K";
-    } else if(type == MfClassicType4k) {
-        return "MIFARE Classic 4K";
-    } else {
-        return "Unknown";
-    }
-}
-
-static uint8_t mf_classic_get_first_block_num_of_sector(uint8_t sector) {
-    furi_assert(sector < 40);
-    if(sector < 32) {
-        return sector * 4;
-    } else {
-        return 32 * 4 + (sector - 32) * 16;
-    }
-}
-
-uint8_t mf_classic_get_sector_trailer_block_num_by_sector(uint8_t sector) {
-    furi_assert(sector < 40);
-    if(sector < 32) {
-        return sector * 4 + 3;
-    } else {
-        return 32 * 4 + (sector - 32) * 16 + 15;
-    }
-}
-
-uint8_t mf_classic_get_sector_by_block(uint8_t block) {
-    if(block < 128) {
-        return (block | 0x03) / 4;
-    } else {
-        return 32 + ((block | 0xf) - 32 * 4) / 16;
-    }
-}
-
-static uint8_t mf_classic_get_blocks_num_in_sector(uint8_t sector) {
-    furi_assert(sector < 40);
-    return sector < 32 ? 4 : 16;
-}
-
-uint8_t mf_classic_get_sector_trailer_num_by_block(uint8_t block) {
-    if(block < 128) {
-        return block | 0x03;
-    } else {
-        return block | 0x0f;
-    }
-}
-
-bool mf_classic_is_sector_trailer(uint8_t block) {
-    return block == mf_classic_get_sector_trailer_num_by_block(block);
-}
-
-MfClassicSectorTrailer*
-    mf_classic_get_sector_trailer_by_sector(MfClassicData* data, uint8_t sector) {
-    furi_assert(data);
-    uint8_t sec_tr_block_num = mf_classic_get_sector_trailer_block_num_by_sector(sector);
-    return (MfClassicSectorTrailer*)data->block[sec_tr_block_num].value;
-}
-
-uint8_t mf_classic_get_total_sectors_num(MfClassicType type) {
-    if(type == MfClassicTypeMini) {
-        return MF_MINI_TOTAL_SECTORS_NUM;
-    } else if(type == MfClassicType1k) {
-        return MF_CLASSIC_1K_TOTAL_SECTORS_NUM;
-    } else if(type == MfClassicType4k) {
-        return MF_CLASSIC_4K_TOTAL_SECTORS_NUM;
-    } else {
-        return 0;
-    }
-}
-
-uint16_t mf_classic_get_total_block_num(MfClassicType type) {
-    if(type == MfClassicTypeMini) {
-        return 20;
-    } else if(type == MfClassicType1k) {
-        return 64;
-    } else if(type == MfClassicType4k) {
-        return 256;
-    } else {
-        return 0;
-    }
-}
-
-bool mf_classic_is_block_read(MfClassicData* data, uint8_t block_num) {
-    furi_assert(data);
-
-    return (FURI_BIT(data->block_read_mask[block_num / 32], block_num % 32) == 1);
-}
-
-void mf_classic_set_block_read(MfClassicData* data, uint8_t block_num, MfClassicBlock* block_data) {
-    furi_assert(data);
-
-    if(mf_classic_is_sector_trailer(block_num)) {
-        memcpy(&data->block[block_num].value[6], &block_data->value[6], 4);
-    } else {
-        memcpy(data->block[block_num].value, block_data->value, MF_CLASSIC_BLOCK_SIZE);
-    }
-    FURI_BIT_SET(data->block_read_mask[block_num / 32], block_num % 32);
-}
-
-bool mf_classic_is_sector_data_read(MfClassicData* data, uint8_t sector_num) {
-    furi_assert(data);
-
-    uint8_t first_block = mf_classic_get_first_block_num_of_sector(sector_num);
-    uint8_t total_blocks = mf_classic_get_blocks_num_in_sector(sector_num);
-    bool data_read = true;
-    for(size_t i = first_block; i < first_block + total_blocks; i++) {
-        data_read &= mf_classic_is_block_read(data, i);
-    }
-
-    return data_read;
-}
-
-void mf_classic_set_sector_data_not_read(MfClassicData* data) {
-    furi_assert(data);
-    memset(data->block_read_mask, 0, sizeof(data->block_read_mask));
-}
-
-bool mf_classic_is_key_found(MfClassicData* data, uint8_t sector_num, MfClassicKey key_type) {
-    furi_assert(data);
-
-    bool key_found = false;
-    if(key_type == MfClassicKeyA) {
-        key_found = (FURI_BIT(data->key_a_mask, sector_num) == 1);
-    } else if(key_type == MfClassicKeyB) {
-        key_found = (FURI_BIT(data->key_b_mask, sector_num) == 1);
-    }
-
-    return key_found;
-}
-
-void mf_classic_set_key_found(
-    MfClassicData* data,
-    uint8_t sector_num,
-    MfClassicKey key_type,
-    uint64_t key) {
-    furi_assert(data);
-
-    uint8_t key_arr[6] = {};
-    MfClassicSectorTrailer* sec_trailer =
-        mf_classic_get_sector_trailer_by_sector(data, sector_num);
-    nfc_util_num2bytes(key, 6, key_arr);
-    if(key_type == MfClassicKeyA) {
-        memcpy(sec_trailer->key_a, key_arr, sizeof(sec_trailer->key_a));
-        FURI_BIT_SET(data->key_a_mask, sector_num);
-    } else if(key_type == MfClassicKeyB) {
-        memcpy(sec_trailer->key_b, key_arr, sizeof(sec_trailer->key_b));
-        FURI_BIT_SET(data->key_b_mask, sector_num);
-    }
-}
-
-void mf_classic_set_key_not_found(MfClassicData* data, uint8_t sector_num, MfClassicKey key_type) {
-    furi_assert(data);
-
-    if(key_type == MfClassicKeyA) {
-        FURI_BIT_CLEAR(data->key_a_mask, sector_num);
-    } else if(key_type == MfClassicKeyB) {
-        FURI_BIT_CLEAR(data->key_b_mask, sector_num);
-    }
-}
-
-bool mf_classic_is_sector_read(MfClassicData* data, uint8_t sector_num) {
-    furi_assert(data);
-
-    bool sector_read = false;
-    do {
-        if(!mf_classic_is_key_found(data, sector_num, MfClassicKeyA)) break;
-        if(!mf_classic_is_key_found(data, sector_num, MfClassicKeyB)) break;
-        uint8_t start_block = mf_classic_get_first_block_num_of_sector(sector_num);
-        uint8_t total_blocks = mf_classic_get_blocks_num_in_sector(sector_num);
-        uint8_t block_read = true;
-        for(size_t i = start_block; i < start_block + total_blocks; i++) {
-            block_read = mf_classic_is_block_read(data, i);
-            if(!block_read) break;
-        }
-        sector_read = block_read;
-    } while(false);
-
-    return sector_read;
-}
-
-void mf_classic_get_read_sectors_and_keys(
-    MfClassicData* data,
-    uint8_t* sectors_read,
-    uint8_t* keys_found) {
-    furi_assert(data);
-    furi_assert(sectors_read);
-    furi_assert(keys_found);
-
-    *sectors_read = 0;
-    *keys_found = 0;
-    uint8_t sectors_total = mf_classic_get_total_sectors_num(data->type);
-    for(size_t i = 0; i < sectors_total; i++) {
-        if(mf_classic_is_key_found(data, i, MfClassicKeyA)) {
-            *keys_found += 1;
-        }
-        if(mf_classic_is_key_found(data, i, MfClassicKeyB)) {
-            *keys_found += 1;
-        }
-        uint8_t first_block = mf_classic_get_first_block_num_of_sector(i);
-        uint8_t total_blocks_in_sec = mf_classic_get_blocks_num_in_sector(i);
-        bool blocks_read = true;
-        for(size_t j = first_block; j < first_block + total_blocks_in_sec; j++) {
-            blocks_read = mf_classic_is_block_read(data, j);
-            if(!blocks_read) break;
-        }
-        if(blocks_read) {
-            *sectors_read += 1;
-        }
-    }
-}
-
-bool mf_classic_is_card_read(MfClassicData* data) {
-    furi_assert(data);
-
-    uint8_t sectors_total = mf_classic_get_total_sectors_num(data->type);
-    uint8_t sectors_read = 0;
-    uint8_t keys_found = 0;
-    mf_classic_get_read_sectors_and_keys(data, &sectors_read, &keys_found);
-    bool card_read = (sectors_read == sectors_total) && (keys_found == sectors_total * 2);
-
-    return card_read;
-}
-
-bool mf_classic_is_allowed_access_sector_trailer(
-    MfClassicData* data,
-    uint8_t block_num,
-    MfClassicKey key,
-    MfClassicAction action) {
-    uint8_t* sector_trailer = data->block[block_num].value;
-    uint8_t AC = ((sector_trailer[7] >> 5) & 0x04) | ((sector_trailer[8] >> 2) & 0x02) |
-                 ((sector_trailer[8] >> 7) & 0x01);
-    switch(action) {
-    case MfClassicActionKeyARead: {
-        return false;
-    }
-    case MfClassicActionKeyAWrite:
-    case MfClassicActionKeyBWrite: {
-        return (
-            (key == MfClassicKeyA && (AC == 0x00 || AC == 0x01)) ||
-            (key == MfClassicKeyB && (AC == 0x04 || AC == 0x03)));
-    }
-    case MfClassicActionKeyBRead: {
-        return (key == MfClassicKeyA && (AC == 0x00 || AC == 0x02 || AC == 0x01));
-    }
-    case MfClassicActionACRead: {
-        return (
-            (key == MfClassicKeyA) ||
-            (key == MfClassicKeyB && !(AC == 0x00 || AC == 0x02 || AC == 0x01)));
-    }
-    case MfClassicActionACWrite: {
-        return (
-            (key == MfClassicKeyA && (AC == 0x01)) ||
-            (key == MfClassicKeyB && (AC == 0x03 || AC == 0x05)));
-    }
-    default:
-        return false;
-    }
-    return true;
-}
-
-bool mf_classic_is_allowed_access_data_block(
-    MfClassicData* data,
-    uint8_t block_num,
-    MfClassicKey key,
-    MfClassicAction action) {
-    uint8_t* sector_trailer =
-        data->block[mf_classic_get_sector_trailer_num_by_block(block_num)].value;
-
-    if(block_num == 0 && action == MfClassicActionDataWrite) {
-        return false;
-    }
-
-    uint8_t sector_block;
-    if(block_num <= 128) {
-        sector_block = block_num & 0x03;
-    } else {
-        sector_block = (block_num & 0x0f) / 5;
-    }
-
-    uint8_t AC;
-    switch(sector_block) {
-    case 0x00: {
-        AC = ((sector_trailer[7] >> 2) & 0x04) | ((sector_trailer[8] << 1) & 0x02) |
-             ((sector_trailer[8] >> 4) & 0x01);
-        break;
-    }
-    case 0x01: {
-        AC = ((sector_trailer[7] >> 3) & 0x04) | ((sector_trailer[8] >> 0) & 0x02) |
-             ((sector_trailer[8] >> 5) & 0x01);
-        break;
-    }
-    case 0x02: {
-        AC = ((sector_trailer[7] >> 4) & 0x04) | ((sector_trailer[8] >> 1) & 0x02) |
-             ((sector_trailer[8] >> 6) & 0x01);
-        break;
-    }
-    default:
-        return false;
-    }
-
-    switch(action) {
-    case MfClassicActionDataRead: {
-        return (
-            (key == MfClassicKeyA && !(AC == 0x03 || AC == 0x05 || AC == 0x07)) ||
-            (key == MfClassicKeyB && !(AC == 0x07)));
-    }
-    case MfClassicActionDataWrite: {
-        return (
-            (key == MfClassicKeyA && (AC == 0x00)) ||
-            (key == MfClassicKeyB && (AC == 0x00 || AC == 0x04 || AC == 0x06 || AC == 0x03)));
-    }
-    case MfClassicActionDataInc: {
-        return (
-            (key == MfClassicKeyA && (AC == 0x00)) ||
-            (key == MfClassicKeyB && (AC == 0x00 || AC == 0x06)));
-    }
-    case MfClassicActionDataDec: {
-        return (
-            (key == MfClassicKeyA && (AC == 0x00 || AC == 0x06 || AC == 0x01)) ||
-            (key == MfClassicKeyB && (AC == 0x00 || AC == 0x06 || AC == 0x01)));
-    }
-    default:
-        return false;
-    }
-
-    return false;
-}
-
-static bool mf_classic_is_allowed_access(
-    MfClassicEmulator* emulator,
-    uint8_t block_num,
-    MfClassicKey key,
-    MfClassicAction action) {
-    if(mf_classic_is_sector_trailer(block_num)) {
-        return mf_classic_is_allowed_access_sector_trailer(
-            &emulator->data, block_num, key, action);
-    } else {
-        return mf_classic_is_allowed_access_data_block(&emulator->data, block_num, key, action);
-    }
-}
-
-bool mf_classic_is_value_block(MfClassicData* data, uint8_t block_num) {
-    // Check if key A can write, if it can, it's transport configuration, not data block
-    return !mf_classic_is_allowed_access_data_block(
-               data, block_num, MfClassicKeyA, MfClassicActionDataWrite) &&
-           (mf_classic_is_allowed_access_data_block(
-                data, block_num, MfClassicKeyB, MfClassicActionDataInc) ||
-            mf_classic_is_allowed_access_data_block(
-                data, block_num, MfClassicKeyB, MfClassicActionDataDec));
-}
-
-bool mf_classic_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) {
-    UNUSED(ATQA1);
-    if((ATQA0 == 0x44 || ATQA0 == 0x04) &&
-       (SAK == 0x08 || SAK == 0x88 || SAK == 0x09 || SAK == 0x89)) {
-        return true;
-    } else if((ATQA0 == 0x01) && (ATQA1 == 0x0F) && (SAK == 0x01)) {
-        //skylanders support
-        return true;
-    } else if(
-        ((ATQA0 == 0x42 || ATQA0 == 0x02) && (SAK == 0x18)) ||
-        ((ATQA0 == 0x02 || ATQA0 == 0x04 || ATQA0 == 0x08) && (SAK == 0x38))) {
-        return true;
-    } else {
-        return false;
-    }
-}
-
-MfClassicType mf_classic_get_classic_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) {
-    UNUSED(ATQA1);
-    if((ATQA0 == 0x44 || ATQA0 == 0x04)) {
-        if((SAK == 0x08 || SAK == 0x88)) {
-            return MfClassicType1k;
-        } else if((SAK == 0x38)) {
-            return MfClassicType4k;
-        } else if((SAK == 0x09 || SAK == 0x89)) {
-            return MfClassicTypeMini;
-        }
-    } else if((ATQA0 == 0x01) && (ATQA1 == 0x0F) && (SAK == 0x01)) {
-        //skylanders support
-        return MfClassicType1k;
-    } else if(
-        ((ATQA0 == 0x42 || ATQA0 == 0x02) && (SAK == 0x18)) ||
-        ((ATQA0 == 0x02 || ATQA0 == 0x08) && (SAK == 0x38))) {
-        return MfClassicType4k;
-    }
-    return MfClassicType1k;
-}
-
-void mf_classic_reader_add_sector(
-    MfClassicReader* reader,
-    uint8_t sector,
-    uint64_t key_a,
-    uint64_t key_b) {
-    furi_assert(reader);
-    furi_assert(sector < MF_CLASSIC_SECTORS_MAX);
-    furi_assert((key_a != MF_CLASSIC_NO_KEY) || (key_b != MF_CLASSIC_NO_KEY));
-
-    if(reader->sectors_to_read < MF_CLASSIC_SECTORS_MAX) {
-        reader->sector_reader[reader->sectors_to_read].key_a = key_a;
-        reader->sector_reader[reader->sectors_to_read].key_b = key_b;
-        reader->sector_reader[reader->sectors_to_read].sector_num = sector;
-        reader->sectors_to_read++;
-    }
-}
-
-bool mf_classic_block_to_value(const uint8_t* block, int32_t* value, uint8_t* addr) {
-    uint32_t v = *(uint32_t*)&block[0];
-    uint32_t v_inv = *(uint32_t*)&block[4];
-    uint32_t v1 = *(uint32_t*)&block[8];
-
-    bool val_checks =
-        ((v == v1) && (v == ~v_inv) && (block[12] == (~block[13] & 0xFF)) &&
-         (block[14] == (~block[15] & 0xFF)) && (block[12] == block[14]));
-    if(value) {
-        *value = (int32_t)v;
-    }
-    if(addr) {
-        *addr = block[12];
-    }
-    return val_checks;
-}
-
-void mf_classic_value_to_block(int32_t value, uint8_t addr, uint8_t* block) {
-    uint32_t v_inv = ~((uint32_t)value);
-
-    memcpy(block, &value, 4); //-V1086
-    memcpy(block + 4, &v_inv, 4); //-V1086
-    memcpy(block + 8, &value, 4); //-V1086
-
-    block[12] = addr;
-    block[13] = ~addr & 0xFF;
-    block[14] = addr;
-    block[15] = ~addr & 0xFF;
-}
-
-void mf_classic_auth_init_context(MfClassicAuthContext* auth_ctx, uint8_t sector) {
-    furi_assert(auth_ctx);
-    auth_ctx->sector = sector;
-    auth_ctx->key_a = MF_CLASSIC_NO_KEY;
-    auth_ctx->key_b = MF_CLASSIC_NO_KEY;
-}
-
-static bool mf_classic_auth(
-    FurryHalNfcTxRxContext* tx_rx,
-    uint32_t block,
-    uint64_t key,
-    MfClassicKey key_type,
-    Crypto1* crypto,
-    bool skip_activate,
-    uint32_t cuid) {
-    bool auth_success = false;
-    memset(tx_rx->tx_data, 0, sizeof(tx_rx->tx_data));
-    memset(tx_rx->tx_parity, 0, sizeof(tx_rx->tx_parity));
-    tx_rx->tx_rx_type = FurryHalNfcTxRxTypeDefault;
-
-    do {
-        if(!skip_activate && !furry_hal_nfc_activate_nfca(200, &cuid)) break;
-        if(key_type == MfClassicKeyA) {
-            tx_rx->tx_data[0] = MF_CLASSIC_AUTH_KEY_A_CMD;
-        } else {
-            tx_rx->tx_data[0] = MF_CLASSIC_AUTH_KEY_B_CMD;
-        }
-        tx_rx->tx_data[1] = block;
-        tx_rx->tx_rx_type = FurryHalNfcTxRxTypeRxNoCrc;
-        tx_rx->tx_bits = 2 * 8;
-        if(!furry_hal_nfc_tx_rx(tx_rx, 6)) break;
-
-        uint32_t nt = (uint32_t)nfc_util_bytes2num(tx_rx->rx_data, 4);
-        crypto1_init(crypto, key);
-        crypto1_word(crypto, nt ^ cuid, 0);
-        uint8_t nr[4] = {};
-        nfc_util_num2bytes(prng_successor(DWT->CYCCNT, 32), 4, nr);
-        for(uint8_t i = 0; i < 4; i++) {
-            tx_rx->tx_data[i] = crypto1_byte(crypto, nr[i], 0) ^ nr[i];
-            tx_rx->tx_parity[0] |=
-                (((crypto1_filter(crypto->odd) ^ nfc_util_odd_parity8(nr[i])) & 0x01) << (7 - i));
-        }
-        nt = prng_successor(nt, 32);
-        for(uint8_t i = 4; i < 8; i++) {
-            nt = prng_successor(nt, 8);
-            tx_rx->tx_data[i] = crypto1_byte(crypto, 0x00, 0) ^ (nt & 0xff);
-            tx_rx->tx_parity[0] |=
-                (((crypto1_filter(crypto->odd) ^ nfc_util_odd_parity8(nt & 0xff)) & 0x01)
-                 << (7 - i));
-        }
-        tx_rx->tx_rx_type = FurryHalNfcTxRxTypeRaw;
-        tx_rx->tx_bits = 8 * 8;
-        if(!furry_hal_nfc_tx_rx(tx_rx, 6)) break;
-        if(tx_rx->rx_bits == 32) {
-            crypto1_word(crypto, 0, 0);
-            auth_success = true;
-        }
-    } while(false);
-
-    return auth_success;
-}
-
-bool mf_classic_authenticate(
-    FurryHalNfcTxRxContext* tx_rx,
-    uint8_t block_num,
-    uint64_t key,
-    MfClassicKey key_type) {
-    furi_assert(tx_rx);
-
-    Crypto1 crypto = {};
-    bool key_found = mf_classic_auth(tx_rx, block_num, key, key_type, &crypto, false, 0);
-    furry_hal_nfc_sleep();
-    return key_found;
-}
-
-bool mf_classic_authenticate_skip_activate(
-    FurryHalNfcTxRxContext* tx_rx,
-    uint8_t block_num,
-    uint64_t key,
-    MfClassicKey key_type,
-    bool skip_activate,
-    uint32_t cuid) {
-    furi_assert(tx_rx);
-
-    Crypto1 crypto = {};
-    bool key_found =
-        mf_classic_auth(tx_rx, block_num, key, key_type, &crypto, skip_activate, cuid);
-    furry_hal_nfc_sleep();
-    return key_found;
-}
-
-bool mf_classic_auth_attempt(
-    FurryHalNfcTxRxContext* tx_rx,
-    Crypto1* crypto,
-    MfClassicAuthContext* auth_ctx,
-    uint64_t key) {
-    furi_assert(tx_rx);
-    furi_assert(auth_ctx);
-    bool found_key = false;
-    bool need_halt = (auth_ctx->key_a == MF_CLASSIC_NO_KEY) &&
-                     (auth_ctx->key_b == MF_CLASSIC_NO_KEY);
-
-    if(auth_ctx->key_a == MF_CLASSIC_NO_KEY) {
-        // Try AUTH with key A
-        if(mf_classic_auth(
-               tx_rx,
-               mf_classic_get_sector_trailer_block_num_by_sector(auth_ctx->sector),
-               key,
-               MfClassicKeyA,
-               crypto,
-               false,
-               0)) {
-            auth_ctx->key_a = key;
-            found_key = true;
-        }
-    }
-
-    if(need_halt) {
-        furry_hal_nfc_sleep();
-    }
-
-    if(auth_ctx->key_b == MF_CLASSIC_NO_KEY) {
-        // Try AUTH with key B
-        if(mf_classic_auth(
-               tx_rx,
-               mf_classic_get_sector_trailer_block_num_by_sector(auth_ctx->sector),
-               key,
-               MfClassicKeyB,
-               crypto,
-               false,
-               0)) {
-            auth_ctx->key_b = key;
-            found_key = true;
-        }
-    }
-
-    return found_key;
-}
-
-bool mf_classic_read_block(
-    FurryHalNfcTxRxContext* tx_rx,
-    Crypto1* crypto,
-    uint8_t block_num,
-    MfClassicBlock* block) {
-    furi_assert(tx_rx);
-    furi_assert(crypto);
-    furi_assert(block);
-
-    bool read_block_success = false;
-    uint8_t plain_cmd[4] = {MF_CLASSIC_READ_BLOCK_CMD, block_num, 0x00, 0x00};
-    nfca_append_crc16(plain_cmd, 2);
-
-    crypto1_encrypt(
-        crypto, NULL, plain_cmd, sizeof(plain_cmd) * 8, tx_rx->tx_data, tx_rx->tx_parity);
-    tx_rx->tx_bits = sizeof(plain_cmd) * 8;
-    tx_rx->tx_rx_type = FurryHalNfcTxRxTypeRaw;
-
-    if(furry_hal_nfc_tx_rx(tx_rx, 50)) {
-        if(tx_rx->rx_bits == 8 * (MF_CLASSIC_BLOCK_SIZE + 2)) {
-            uint8_t block_received[MF_CLASSIC_BLOCK_SIZE + 2];
-            crypto1_decrypt(crypto, tx_rx->rx_data, tx_rx->rx_bits, block_received);
-            uint16_t crc_calc = nfca_get_crc16(block_received, MF_CLASSIC_BLOCK_SIZE);
-            uint16_t crc_received = (block_received[MF_CLASSIC_BLOCK_SIZE + 1] << 8) |
-                                    block_received[MF_CLASSIC_BLOCK_SIZE];
-            if(crc_received != crc_calc) {
-                FURI_LOG_E(
-                    TAG,
-                    "Incorrect CRC while reading block %d. Expected %04X, Received %04X",
-                    block_num,
-                    crc_received,
-                    crc_calc);
-            } else {
-                memcpy(block->value, block_received, MF_CLASSIC_BLOCK_SIZE);
-                read_block_success = true;
-            }
-        }
-    }
-    return read_block_success;
-}
-
-void mf_classic_read_sector(FurryHalNfcTxRxContext* tx_rx, MfClassicData* data, uint8_t sec_num) {
-    furi_assert(tx_rx);
-    furi_assert(data);
-
-    furry_hal_nfc_sleep();
-    bool key_a_found = mf_classic_is_key_found(data, sec_num, MfClassicKeyA);
-    bool key_b_found = mf_classic_is_key_found(data, sec_num, MfClassicKeyB);
-    uint8_t start_block = mf_classic_get_first_block_num_of_sector(sec_num);
-    uint8_t total_blocks = mf_classic_get_blocks_num_in_sector(sec_num);
-    MfClassicBlock block_tmp = {};
-    uint64_t key = 0;
-    MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, sec_num);
-    Crypto1 crypto = {};
-
-    uint8_t blocks_read = 0;
-    do {
-        if(!key_a_found) break;
-        FURI_LOG_D(TAG, "Try to read blocks with key A");
-        key = nfc_util_bytes2num(sec_tr->key_a, sizeof(sec_tr->key_a));
-        if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyA, &crypto, false, 0)) {
-            mf_classic_set_key_not_found(data, sec_num, MfClassicKeyA);
-            FURI_LOG_D(TAG, "Key %dA not found in read", sec_num);
-            break;
-        }
-
-        for(size_t i = start_block; i < start_block + total_blocks; i++) {
-            if(!mf_classic_is_block_read(data, i)) {
-                if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
-                    mf_classic_set_block_read(data, i, &block_tmp);
-                    blocks_read++;
-                } else if(i > start_block) {
-                    // Try to re-auth to read block in case prevous block was protected from read
-                    furry_hal_nfc_sleep();
-                    if(!mf_classic_auth(tx_rx, i, key, MfClassicKeyA, &crypto, false, 0)) {
-                        mf_classic_set_key_not_found(data, sec_num, MfClassicKeyA);
-                        FURI_LOG_D(TAG, "Key %dA not found in read", sec_num);
-                        break;
-                    }
-                    if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
-                        mf_classic_set_block_read(data, i, &block_tmp);
-                        blocks_read++;
-                    }
-                }
-            } else {
-                blocks_read++;
-            }
-        }
-        FURI_LOG_D(TAG, "Read %d blocks out of %d", blocks_read, total_blocks);
-    } while(false);
-    do {
-        if(blocks_read == total_blocks) break;
-        if(!key_b_found) break;
-        if(key_a_found) {
-            furry_hal_nfc_sleep();
-        }
-        FURI_LOG_D(TAG, "Try to read blocks with key B");
-        key = nfc_util_bytes2num(sec_tr->key_b, sizeof(sec_tr->key_b));
-        if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyB, &crypto, false, 0)) {
-            mf_classic_set_key_not_found(data, sec_num, MfClassicKeyB);
-            FURI_LOG_D(TAG, "Key %dB not found in read", sec_num);
-            break;
-        }
-
-        for(size_t i = start_block; i < start_block + total_blocks; i++) {
-            if(!mf_classic_is_block_read(data, i)) {
-                if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
-                    mf_classic_set_block_read(data, i, &block_tmp);
-                    blocks_read++;
-                } else if(i > start_block) {
-                    // Try to re-auth to read block in case prevous block was protected from read
-                    furry_hal_nfc_sleep();
-                    if(!mf_classic_auth(tx_rx, i, key, MfClassicKeyB, &crypto, false, 0)) {
-                        mf_classic_set_key_not_found(data, sec_num, MfClassicKeyB);
-                        FURI_LOG_D(TAG, "Key %dB not found in read", sec_num);
-                        break;
-                    }
-                    if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
-                        mf_classic_set_block_read(data, i, &block_tmp);
-                        blocks_read++;
-                    }
-                }
-            } else {
-                blocks_read++;
-            }
-        }
-        FURI_LOG_D(TAG, "Read %d blocks out of %d", blocks_read, total_blocks);
-    } while(false);
-}
-
-static bool mf_classic_read_sector_with_reader(
-    FurryHalNfcTxRxContext* tx_rx,
-    Crypto1* crypto,
-    MfClassicSectorReader* sector_reader,
-    MfClassicSector* sector) {
-    furi_assert(tx_rx);
-    furi_assert(sector_reader);
-    furi_assert(sector);
-
-    uint64_t key;
-    MfClassicKey key_type;
-    uint8_t first_block;
-    bool sector_read = false;
-
-    furry_hal_nfc_sleep();
-    do {
-        // Activate card
-        first_block = mf_classic_get_first_block_num_of_sector(sector_reader->sector_num);
-        if(sector_reader->key_a != MF_CLASSIC_NO_KEY) {
-            key = sector_reader->key_a;
-            key_type = MfClassicKeyA;
-        } else if(sector_reader->key_b != MF_CLASSIC_NO_KEY) {
-            key = sector_reader->key_b;
-            key_type = MfClassicKeyB;
-        } else {
-            break;
-        }
-
-        // Auth to first block in sector
-        if(!mf_classic_auth(tx_rx, first_block, key, key_type, crypto, false, 0)) {
-            // Set key to MF_CLASSIC_NO_KEY to prevent further attempts
-            if(key_type == MfClassicKeyA) {
-                sector_reader->key_a = MF_CLASSIC_NO_KEY;
-            } else {
-                sector_reader->key_b = MF_CLASSIC_NO_KEY;
-            }
-            break;
-        }
-        sector->total_blocks = mf_classic_get_blocks_num_in_sector(sector_reader->sector_num);
-
-        // Read blocks
-        for(uint8_t i = 0; i < sector->total_blocks; i++) {
-            if(mf_classic_read_block(tx_rx, crypto, first_block + i, &sector->block[i])) continue;
-            if(i == 0) continue;
-            // Try to auth to read next block in case previous is locked
-            furry_hal_nfc_sleep();
-            if(!mf_classic_auth(tx_rx, first_block + i, key, key_type, crypto, false, 0)) continue;
-            mf_classic_read_block(tx_rx, crypto, first_block + i, &sector->block[i]);
-        }
-        // Save sector keys in last block
-        if(sector_reader->key_a != MF_CLASSIC_NO_KEY) {
-            nfc_util_num2bytes(
-                sector_reader->key_a, 6, &sector->block[sector->total_blocks - 1].value[0]);
-        }
-        if(sector_reader->key_b != MF_CLASSIC_NO_KEY) {
-            nfc_util_num2bytes(
-                sector_reader->key_b, 6, &sector->block[sector->total_blocks - 1].value[10]);
-        }
-
-        sector_read = true;
-    } while(false);
-
-    return sector_read;
-}
-
-uint8_t mf_classic_read_card(
-    FurryHalNfcTxRxContext* tx_rx,
-    MfClassicReader* reader,
-    MfClassicData* data) {
-    furi_assert(tx_rx);
-    furi_assert(reader);
-    furi_assert(data);
-
-    uint8_t sectors_read = 0;
-    data->type = reader->type;
-    data->key_a_mask = 0;
-    data->key_b_mask = 0;
-    MfClassicSector temp_sector = {};
-    for(uint8_t i = 0; i < reader->sectors_to_read; i++) {
-        if(mf_classic_read_sector_with_reader(
-               tx_rx, &reader->crypto, &reader->sector_reader[i], &temp_sector)) {
-            uint8_t first_block =
-                mf_classic_get_first_block_num_of_sector(reader->sector_reader[i].sector_num);
-            for(uint8_t j = 0; j < temp_sector.total_blocks; j++) {
-                mf_classic_set_block_read(data, first_block + j, &temp_sector.block[j]);
-            }
-            if(reader->sector_reader[i].key_a != MF_CLASSIC_NO_KEY) {
-                mf_classic_set_key_found(
-                    data,
-                    reader->sector_reader[i].sector_num,
-                    MfClassicKeyA,
-                    reader->sector_reader[i].key_a);
-            }
-            if(reader->sector_reader[i].key_b != MF_CLASSIC_NO_KEY) {
-                mf_classic_set_key_found(
-                    data,
-                    reader->sector_reader[i].sector_num,
-                    MfClassicKeyB,
-                    reader->sector_reader[i].key_b);
-            }
-            sectors_read++;
-        }
-    }
-
-    return sectors_read;
-}
-
-uint8_t mf_classic_update_card(FurryHalNfcTxRxContext* tx_rx, MfClassicData* data) {
-    furi_assert(tx_rx);
-    furi_assert(data);
-
-    uint8_t total_sectors = mf_classic_get_total_sectors_num(data->type);
-
-    for(size_t i = 0; i < total_sectors; i++) {
-        mf_classic_read_sector(tx_rx, data, i);
-    }
-    uint8_t sectors_read = 0;
-    uint8_t keys_found = 0;
-    mf_classic_get_read_sectors_and_keys(data, &sectors_read, &keys_found);
-    FURI_LOG_D(TAG, "Read %d sectors and %d keys", sectors_read, keys_found);
-
-    return sectors_read;
-}
-
-bool mf_classic_emulator(
-    MfClassicEmulator* emulator,
-    FurryHalNfcTxRxContext* tx_rx,
-    bool is_reader_analyzer) {
-    furi_assert(emulator);
-    furi_assert(tx_rx);
-    uint8_t plain_data[MF_CLASSIC_MAX_DATA_SIZE];
-    MfClassicKey access_key = MfClassicKeyA;
-    bool need_reset = false;
-    bool need_nack = false;
-    bool is_encrypted = false;
-    uint8_t sector = 0;
-
-    // Used for decrement and increment - copy to block on transfer
-    uint8_t transfer_buf[MF_CLASSIC_BLOCK_SIZE];
-    bool transfer_buf_valid = false;
-
-    // Process commands
-    while(!need_reset && !need_nack) { //-V654
-        memset(plain_data, 0, MF_CLASSIC_MAX_DATA_SIZE);
-        if(!is_encrypted) {
-            crypto1_reset(&emulator->crypto);
-            memcpy(plain_data, tx_rx->rx_data, tx_rx->rx_bits / 8);
-        } else {
-            if(!furry_hal_nfc_tx_rx(tx_rx, 300)) {
-                FURI_LOG_D(
-                    TAG,
-                    "Error in tx rx. Tx: %d bits, Rx: %d bits",
-                    tx_rx->tx_bits,
-                    tx_rx->rx_bits);
-                need_reset = true;
-                break;
-            }
-            crypto1_decrypt(&emulator->crypto, tx_rx->rx_data, tx_rx->rx_bits, plain_data);
-        }
-
-        // After increment, decrement or restore the only allowed command is transfer
-        uint8_t cmd = plain_data[0];
-        if(transfer_buf_valid && cmd != MF_CLASSIC_TRANSFER_CMD) {
-            need_nack = true;
-            break;
-        }
-
-        if(cmd == NFCA_CMD_HALT && plain_data[1] == 0x00) {
-            FURI_LOG_T(TAG, "Halt received");
-            need_reset = true;
-            break;
-        }
-
-        if(cmd == NFCA_CMD_RATS) {
-            // Mifare Classic doesn't support ATS, NACK it and start listening again
-            FURI_LOG_T(TAG, "RATS received");
-            need_nack = true;
-            break;
-        }
-
-        if(cmd == MF_CLASSIC_AUTH_KEY_A_CMD || cmd == MF_CLASSIC_AUTH_KEY_B_CMD) {
-            uint8_t block = plain_data[1];
-            uint64_t key = 0;
-            uint8_t sector_trailer_block = mf_classic_get_sector_trailer_num_by_block(block);
-            sector = mf_classic_get_sector_by_block(block);
-            MfClassicSectorTrailer* sector_trailer =
-                (MfClassicSectorTrailer*)emulator->data.block[sector_trailer_block].value;
-            if(cmd == MF_CLASSIC_AUTH_KEY_A_CMD) {
-                if(mf_classic_is_key_found(
-                       &emulator->data, mf_classic_get_sector_by_block(block), MfClassicKeyA) ||
-                   is_reader_analyzer) {
-                    key = nfc_util_bytes2num(sector_trailer->key_a, 6);
-                    access_key = MfClassicKeyA;
-                } else {
-                    FURI_LOG_D(TAG, "Key not known");
-                    need_nack = true;
-                    break;
-                }
-            } else {
-                if(mf_classic_is_key_found(
-                       &emulator->data, mf_classic_get_sector_by_block(block), MfClassicKeyB) ||
-                   is_reader_analyzer) {
-                    key = nfc_util_bytes2num(sector_trailer->key_b, 6);
-                    access_key = MfClassicKeyB;
-                } else {
-                    FURI_LOG_D(TAG, "Key not known");
-                    need_nack = true;
-                    break;
-                }
-            }
-
-            uint32_t nonce = prng_successor(DWT->CYCCNT, 32) ^ 0xAA;
-            uint8_t nt[4];
-            uint8_t nt_keystream[4];
-            nfc_util_num2bytes(nonce, 4, nt);
-            nfc_util_num2bytes(nonce ^ emulator->cuid, 4, nt_keystream);
-            crypto1_init(&emulator->crypto, key);
-            if(!is_encrypted) {
-                crypto1_word(&emulator->crypto, emulator->cuid ^ nonce, 0);
-                memcpy(tx_rx->tx_data, nt, sizeof(nt));
-                tx_rx->tx_parity[0] = 0;
-                nfc_util_odd_parity(tx_rx->tx_data, tx_rx->tx_parity, sizeof(nt));
-                tx_rx->tx_bits = sizeof(nt) * 8;
-                tx_rx->tx_rx_type = FurryHalNfcTxRxTransparent;
-            } else {
-                crypto1_encrypt(
-                    &emulator->crypto,
-                    nt_keystream,
-                    nt,
-                    sizeof(nt) * 8,
-                    tx_rx->tx_data,
-                    tx_rx->tx_parity);
-                tx_rx->tx_bits = sizeof(nt) * 8;
-                tx_rx->tx_rx_type = FurryHalNfcTxRxTransparent;
-            }
-
-            if(!furry_hal_nfc_tx_rx(tx_rx, 500)) {
-                FURI_LOG_E(TAG, "Error in NT exchange");
-                need_reset = true;
-                break;
-            }
-
-            if(tx_rx->rx_bits != 64) {
-                need_reset = true;
-                break;
-            }
-
-            uint32_t nr = nfc_util_bytes2num(tx_rx->rx_data, 4);
-            uint32_t ar = nfc_util_bytes2num(&tx_rx->rx_data[4], 4);
-
-            crypto1_word(&emulator->crypto, nr, 1);
-            uint32_t cardRr = ar ^ crypto1_word(&emulator->crypto, 0, 0);
-            if(cardRr != prng_successor(nonce, 64)) {
-                FURI_LOG_T(
-                    TAG,
-                    "Wrong AUTH on block %u! %08lX != %08lX",
-                    block,
-                    cardRr,
-                    prng_successor(nonce, 64));
-                // Don't send NACK, as the tag doesn't send it
-                need_reset = true;
-                break;
-            }
-
-            uint32_t ans = prng_successor(nonce, 96);
-            uint8_t response[4] = {};
-            nfc_util_num2bytes(ans, 4, response);
-            crypto1_encrypt(
-                &emulator->crypto,
-                NULL,
-                response,
-                sizeof(response) * 8,
-                tx_rx->tx_data,
-                tx_rx->tx_parity);
-            tx_rx->tx_bits = sizeof(response) * 8;
-            tx_rx->tx_rx_type = FurryHalNfcTxRxTransparent;
-
-            is_encrypted = true;
-            continue;
-        }
-
-        if(!is_encrypted) {
-            FURI_LOG_T(TAG, "Invalid command before auth session established: %02X", cmd);
-            need_nack = true;
-            break;
-        }
-
-        // Mifare Classic commands always have block number after command
-        uint8_t block = plain_data[1];
-        if(mf_classic_get_sector_by_block(block) != sector) {
-            // Don't allow access to sectors other than authorized
-            FURI_LOG_T(
-                TAG,
-                "Trying to access block %u from not authorized sector (command: %02X)",
-                block,
-                cmd);
-            need_nack = true;
-            break;
-        }
-
-        switch(cmd) {
-        case MF_CLASSIC_READ_BLOCK_CMD: {
-            uint8_t block_data[MF_CLASSIC_BLOCK_SIZE + 2] = {};
-            memcpy(block_data, emulator->data.block[block].value, MF_CLASSIC_BLOCK_SIZE);
-            if(mf_classic_is_sector_trailer(block)) {
-                if(!mf_classic_is_allowed_access(
-                       emulator, block, access_key, MfClassicActionKeyARead)) {
-                    memset(block_data, 0, 6); //-V1086
-                }
-                if(!mf_classic_is_allowed_access(
-                       emulator, block, access_key, MfClassicActionKeyBRead)) {
-                    memset(&block_data[10], 0, 6);
-                }
-                if(!mf_classic_is_allowed_access(
-                       emulator, block, access_key, MfClassicActionACRead)) {
-                    memset(&block_data[6], 0, 4);
-                }
-            } else if(
-                !mf_classic_is_allowed_access(
-                    emulator, block, access_key, MfClassicActionDataRead) ||
-                !mf_classic_is_block_read(&emulator->data, block)) {
-                need_nack = true;
-                break;
-            }
-
-            nfca_append_crc16(block_data, 16);
-
-            crypto1_encrypt(
-                &emulator->crypto,
-                NULL,
-                block_data,
-                sizeof(block_data) * 8,
-                tx_rx->tx_data,
-                tx_rx->tx_parity);
-            tx_rx->tx_bits = (MF_CLASSIC_BLOCK_SIZE + 2) * 8;
-            tx_rx->tx_rx_type = FurryHalNfcTxRxTransparent;
-            break;
-        }
-
-        case MF_CLASSIC_WRITE_BLOCK_CMD: {
-            // Send ACK
-            uint8_t ack = MF_CLASSIC_ACK_CMD;
-            crypto1_encrypt(&emulator->crypto, NULL, &ack, 4, tx_rx->tx_data, tx_rx->tx_parity);
-            tx_rx->tx_rx_type = FurryHalNfcTxRxTransparent;
-            tx_rx->tx_bits = 4;
-
-            if(!furry_hal_nfc_tx_rx(tx_rx, 300)) {
-                need_reset = true;
-                break;
-            }
-
-            if(tx_rx->rx_bits != (MF_CLASSIC_BLOCK_SIZE + 2) * 8) {
-                need_reset = true;
-                break;
-            }
-
-            crypto1_decrypt(&emulator->crypto, tx_rx->rx_data, tx_rx->rx_bits, plain_data);
-            uint8_t block_data[MF_CLASSIC_BLOCK_SIZE] = {};
-            memcpy(block_data, emulator->data.block[block].value, MF_CLASSIC_BLOCK_SIZE);
-
-            if(!mf_classic_is_block_read(&emulator->data, block)) {
-                // Don't allow writing to the block for which we haven't read data yet
-                need_nack = true;
-                break;
-            }
-
-            if(mf_classic_is_sector_trailer(block)) {
-                if(mf_classic_is_allowed_access(
-                       emulator, block, access_key, MfClassicActionKeyAWrite)) {
-                    memcpy(block_data, plain_data, 6); //-V1086
-                }
-                if(mf_classic_is_allowed_access(
-                       emulator, block, access_key, MfClassicActionKeyBWrite)) {
-                    memcpy(&block_data[10], &plain_data[10], 6);
-                }
-                if(mf_classic_is_allowed_access(
-                       emulator, block, access_key, MfClassicActionACWrite)) {
-                    memcpy(&block_data[6], &plain_data[6], 4);
-                }
-            } else {
-                if(mf_classic_is_allowed_access(
-                       emulator, block, access_key, MfClassicActionDataWrite)) {
-                    memcpy(block_data, plain_data, MF_CLASSIC_BLOCK_SIZE);
-                } else {
-                    need_nack = true;
-                    break;
-                }
-            }
-
-            if(memcmp(block_data, emulator->data.block[block].value, MF_CLASSIC_BLOCK_SIZE) != 0) {
-                memcpy(emulator->data.block[block].value, block_data, MF_CLASSIC_BLOCK_SIZE);
-                emulator->data_changed = true;
-            }
-
-            // Send ACK
-            ack = MF_CLASSIC_ACK_CMD;
-            crypto1_encrypt(&emulator->crypto, NULL, &ack, 4, tx_rx->tx_data, tx_rx->tx_parity);
-            tx_rx->tx_rx_type = FurryHalNfcTxRxTransparent;
-            tx_rx->tx_bits = 4;
-            break;
-        }
-
-        case MF_CLASSIC_DECREMENT_CMD:
-        case MF_CLASSIC_INCREMENT_CMD:
-        case MF_CLASSIC_RESTORE_CMD: {
-            MfClassicAction action = (cmd == MF_CLASSIC_INCREMENT_CMD) ? MfClassicActionDataInc :
-                                                                         MfClassicActionDataDec;
-
-            if(!mf_classic_is_allowed_access(emulator, block, access_key, action)) {
-                need_nack = true;
-                break;
-            }
-
-            int32_t prev_value;
-            uint8_t addr;
-            if(!mf_classic_block_to_value(emulator->data.block[block].value, &prev_value, &addr)) {
-                need_nack = true;
-                break;
-            }
-
-            // Send ACK
-            uint8_t ack = MF_CLASSIC_ACK_CMD;
-            crypto1_encrypt(&emulator->crypto, NULL, &ack, 4, tx_rx->tx_data, tx_rx->tx_parity);
-            tx_rx->tx_rx_type = FurryHalNfcTxRxTransparent;
-            tx_rx->tx_bits = 4;
-
-            if(!furry_hal_nfc_tx_rx(tx_rx, 300)) {
-                need_reset = true;
-                break;
-            }
-
-            if(tx_rx->rx_bits != (sizeof(int32_t) + 2) * 8) {
-                need_reset = true;
-                break;
-            }
-
-            crypto1_decrypt(&emulator->crypto, tx_rx->rx_data, tx_rx->rx_bits, plain_data);
-            int32_t value = *(int32_t*)&plain_data[0];
-            if(value < 0) {
-                value = -value;
-            }
-            if(cmd == MF_CLASSIC_DECREMENT_CMD) {
-                value = -value;
-            } else if(cmd == MF_CLASSIC_RESTORE_CMD) {
-                value = 0;
-            }
-
-            mf_classic_value_to_block(prev_value + value, addr, transfer_buf);
-            transfer_buf_valid = true;
-            // Commands do not ACK
-            tx_rx->tx_bits = 0;
-            break;
-        }
-
-        case MF_CLASSIC_TRANSFER_CMD: {
-            if(!mf_classic_is_allowed_access(emulator, block, access_key, MfClassicActionDataDec)) {
-                need_nack = true;
-                break;
-            }
-            if(memcmp(transfer_buf, emulator->data.block[block].value, MF_CLASSIC_BLOCK_SIZE) !=
-               0) {
-                memcpy(emulator->data.block[block].value, transfer_buf, MF_CLASSIC_BLOCK_SIZE);
-                emulator->data_changed = true;
-            }
-            transfer_buf_valid = false;
-
-            uint8_t ack = MF_CLASSIC_ACK_CMD;
-            crypto1_encrypt(&emulator->crypto, NULL, &ack, 4, tx_rx->tx_data, tx_rx->tx_parity);
-            tx_rx->tx_rx_type = FurryHalNfcTxRxTransparent;
-            tx_rx->tx_bits = 4;
-            break;
-        }
-
-        default:
-            FURI_LOG_T(TAG, "Unknown command: %02X", cmd);
-            need_nack = true;
-            break;
-        }
-    }
-
-    if(need_nack && !need_reset) {
-        // Send NACK
-        uint8_t nack = transfer_buf_valid ? MF_CLASSIC_NACK_BUF_VALID_CMD :
-                                            MF_CLASSIC_NACK_BUF_INVALID_CMD;
-        if(is_encrypted) {
-            crypto1_encrypt(&emulator->crypto, NULL, &nack, 4, tx_rx->tx_data, tx_rx->tx_parity);
-        } else {
-            tx_rx->tx_data[0] = nack;
-        }
-        tx_rx->tx_rx_type = FurryHalNfcTxRxTransparent;
-        tx_rx->tx_bits = 4;
-        furry_hal_nfc_tx_rx(tx_rx, 300);
-        need_reset = true;
-    }
-
-    return !need_reset;
-}
-
-void mf_classic_halt(FurryHalNfcTxRxContext* tx_rx, Crypto1* crypto) {
-    furi_assert(tx_rx);
-
-    uint8_t plain_data[4] = {NFCA_CMD_HALT, 0x00, 0x00, 0x00};
-
-    nfca_append_crc16(plain_data, 2);
-    if(crypto) {
-        crypto1_encrypt(
-            crypto, NULL, plain_data, sizeof(plain_data) * 8, tx_rx->tx_data, tx_rx->tx_parity);
-    } else {
-        memcpy(tx_rx->tx_data, plain_data, sizeof(plain_data));
-        nfc_util_odd_parity(tx_rx->tx_data, tx_rx->tx_parity, sizeof(plain_data));
-    }
-
-    tx_rx->tx_bits = sizeof(plain_data) * 8;
-    tx_rx->tx_rx_type = FurryHalNfcTxRxTypeRaw;
-    furry_hal_nfc_tx_rx(tx_rx, 50);
-}
-
-bool mf_classic_write_block(
-    FurryHalNfcTxRxContext* tx_rx,
-    Crypto1* crypto,
-    uint8_t block_num,
-    MfClassicBlock* src_block) {
-    furi_assert(tx_rx);
-    furi_assert(crypto);
-    furi_assert(src_block);
-
-    bool write_success = false;
-    uint8_t plain_data[MF_CLASSIC_BLOCK_SIZE + 2] = {};
-    uint8_t resp;
-
-    do {
-        // Send write command
-        plain_data[0] = MF_CLASSIC_WRITE_BLOCK_CMD;
-        plain_data[1] = block_num;
-        nfca_append_crc16(plain_data, 2);
-        crypto1_encrypt(crypto, NULL, plain_data, 4 * 8, tx_rx->tx_data, tx_rx->tx_parity);
-        tx_rx->tx_bits = 4 * 8;
-        tx_rx->tx_rx_type = FurryHalNfcTxRxTypeRaw;
-
-        if(furry_hal_nfc_tx_rx(tx_rx, 50)) {
-            if(tx_rx->rx_bits == 4) {
-                crypto1_decrypt(crypto, tx_rx->rx_data, 4, &resp);
-                if(resp != 0x0A) {
-                    FURI_LOG_D(TAG, "NACK received on write cmd: %02X", resp);
-                    break;
-                }
-            } else {
-                FURI_LOG_D(TAG, "Not ACK received");
-                break;
-            }
-        } else {
-            FURI_LOG_D(TAG, "Failed to send write cmd");
-            break;
-        }
-
-        // Send data
-        memcpy(plain_data, src_block->value, MF_CLASSIC_BLOCK_SIZE);
-        nfca_append_crc16(plain_data, MF_CLASSIC_BLOCK_SIZE);
-        crypto1_encrypt(
-            crypto,
-            NULL,
-            plain_data,
-            (MF_CLASSIC_BLOCK_SIZE + 2) * 8,
-            tx_rx->tx_data,
-            tx_rx->tx_parity);
-        tx_rx->tx_bits = (MF_CLASSIC_BLOCK_SIZE + 2) * 8;
-        tx_rx->tx_rx_type = FurryHalNfcTxRxTypeRaw;
-        if(furry_hal_nfc_tx_rx(tx_rx, 50)) {
-            if(tx_rx->rx_bits == 4) {
-                crypto1_decrypt(crypto, tx_rx->rx_data, 4, &resp);
-                if(resp != MF_CLASSIC_ACK_CMD) {
-                    FURI_LOG_D(TAG, "NACK received on sending data");
-                    break;
-                }
-            } else {
-                FURI_LOG_D(TAG, "Not ACK received");
-                break;
-            }
-        } else {
-            FURI_LOG_D(TAG, "Failed to send data");
-            break;
-        }
-
-        write_success = true;
-    } while(false);
-
-    return write_success;
-}
-
-bool mf_classic_auth_write_block(
-    FurryHalNfcTxRxContext* tx_rx,
-    MfClassicBlock* src_block,
-    uint8_t block_num,
-    MfClassicKey key_type,
-    uint64_t key) {
-    furi_assert(tx_rx);
-    furi_assert(src_block);
-
-    Crypto1 crypto = {};
-    bool write_success = false;
-
-    do {
-        furry_hal_nfc_sleep();
-        if(!mf_classic_auth(tx_rx, block_num, key, key_type, &crypto, false, 0)) {
-            FURI_LOG_D(TAG, "Auth fail");
-            break;
-        }
-
-        if(!mf_classic_write_block(tx_rx, &crypto, block_num, src_block)) {
-            FURI_LOG_D(TAG, "Write fail");
-            break;
-        }
-        write_success = true;
-
-        mf_classic_halt(tx_rx, &crypto);
-    } while(false);
-
-    return write_success;
-}
-
-bool mf_classic_transfer(FurryHalNfcTxRxContext* tx_rx, Crypto1* crypto, uint8_t block_num) {
-    furi_assert(tx_rx);
-    furi_assert(crypto);
-
-    // Send transfer command
-    uint8_t plain_data[4] = {MF_CLASSIC_TRANSFER_CMD, block_num, 0, 0};
-    uint8_t resp = 0;
-    bool transfer_success = false;
-
-    nfca_append_crc16(plain_data, 2);
-    crypto1_encrypt(
-        crypto, NULL, plain_data, sizeof(plain_data) * 8, tx_rx->tx_data, tx_rx->tx_parity);
-    tx_rx->tx_bits = sizeof(plain_data) * 8;
-    tx_rx->tx_rx_type = FurryHalNfcTxRxTypeRaw;
-
-    do {
-        if(furry_hal_nfc_tx_rx(tx_rx, 50)) {
-            if(tx_rx->rx_bits == 4) {
-                crypto1_decrypt(crypto, tx_rx->rx_data, 4, &resp);
-                if(resp != 0x0A) {
-                    FURI_LOG_D(TAG, "NACK received on transfer cmd: %02X", resp);
-                    break;
-                }
-            } else {
-                FURI_LOG_D(TAG, "Not ACK received");
-                break;
-            }
-        } else {
-            FURI_LOG_D(TAG, "Failed to send transfer cmd");
-            break;
-        }
-
-        transfer_success = true;
-    } while(false);
-
-    return transfer_success;
-}
-
-bool mf_classic_value_cmd(
-    FurryHalNfcTxRxContext* tx_rx,
-    Crypto1* crypto,
-    uint8_t block_num,
-    uint8_t cmd,
-    int32_t d_value) {
-    furi_assert(tx_rx);
-    furi_assert(crypto);
-    furi_assert(
-        cmd == MF_CLASSIC_INCREMENT_CMD || cmd == MF_CLASSIC_DECREMENT_CMD ||
-        cmd == MF_CLASSIC_RESTORE_CMD);
-    furi_assert(d_value >= 0);
-
-    uint8_t plain_data[sizeof(d_value) + 2] = {};
-    uint8_t resp = 0;
-    bool success = false;
-
-    do {
-        // Send cmd
-        plain_data[0] = cmd;
-        plain_data[1] = block_num;
-        nfca_append_crc16(plain_data, 2);
-        crypto1_encrypt(crypto, NULL, plain_data, 4 * 8, tx_rx->tx_data, tx_rx->tx_parity);
-        tx_rx->tx_bits = 4 * 8;
-        tx_rx->tx_rx_type = FurryHalNfcTxRxTypeRaw;
-
-        if(furry_hal_nfc_tx_rx(tx_rx, 50)) {
-            if(tx_rx->rx_bits == 4) {
-                crypto1_decrypt(crypto, tx_rx->rx_data, 4, &resp);
-                if(resp != 0x0A) {
-                    FURI_LOG_D(TAG, "NACK received on write cmd: %02X", resp);
-                    break;
-                }
-            } else {
-                FURI_LOG_D(TAG, "Not ACK received");
-                break;
-            }
-        } else {
-            FURI_LOG_D(TAG, "Failed to send write cmd");
-            break;
-        }
-
-        // Send data
-        memcpy(plain_data, &d_value, sizeof(d_value));
-        nfca_append_crc16(plain_data, sizeof(d_value));
-        crypto1_encrypt(
-            crypto, NULL, plain_data, (sizeof(d_value) + 2) * 8, tx_rx->tx_data, tx_rx->tx_parity);
-        tx_rx->tx_bits = (sizeof(d_value) + 2) * 8;
-        tx_rx->tx_rx_type = FurryHalNfcTxRxTypeRaw;
-        // inc, dec, restore do not ACK, but they do NACK
-        if(furry_hal_nfc_tx_rx(tx_rx, 50)) {
-            if(tx_rx->rx_bits == 4) {
-                crypto1_decrypt(crypto, tx_rx->rx_data, 4, &resp);
-                if(resp != 0x0A) {
-                    FURI_LOG_D(TAG, "NACK received on transfer cmd: %02X", resp);
-                    break;
-                }
-            } else {
-                FURI_LOG_D(TAG, "Not NACK received");
-                break;
-            }
-        }
-
-        success = true;
-
-    } while(false);
-
-    return success;
-}
-
-bool mf_classic_value_cmd_full(
-    FurryHalNfcTxRxContext* tx_rx,
-    MfClassicBlock* src_block,
-    uint8_t block_num,
-    MfClassicKey key_type,
-    uint64_t key,
-    int32_t d_value) {
-    furi_assert(tx_rx);
-    furi_assert(src_block);
-
-    Crypto1 crypto = {};
-    uint8_t cmd;
-    bool success = false;
-
-    if(d_value > 0) {
-        cmd = MF_CLASSIC_INCREMENT_CMD;
-    } else if(d_value < 0) {
-        cmd = MF_CLASSIC_DECREMENT_CMD;
-        d_value = -d_value;
-    } else {
-        cmd = MF_CLASSIC_RESTORE_CMD;
-    }
-
-    do {
-        furry_hal_nfc_sleep();
-        if(!mf_classic_auth(tx_rx, block_num, key, key_type, &crypto, false, 0)) {
-            FURI_LOG_D(TAG, "Value cmd auth fail");
-            break;
-        }
-        if(!mf_classic_value_cmd(tx_rx, &crypto, block_num, cmd, d_value)) {
-            FURI_LOG_D(TAG, "Value cmd inc/dec/res fail");
-            break;
-        }
-
-        if(!mf_classic_transfer(tx_rx, &crypto, block_num)) {
-            FURI_LOG_D(TAG, "Value cmd transfer fail");
-            break;
-        }
-
-        success = true;
-
-        // Send Halt
-        mf_classic_halt(tx_rx, &crypto);
-    } while(false);
-
-    return success;
-}
-
-bool mf_classic_write_sector(
-    FurryHalNfcTxRxContext* tx_rx,
-    MfClassicData* dest_data,
-    MfClassicData* src_data,
-    uint8_t sec_num) {
-    furi_assert(tx_rx);
-    furi_assert(dest_data);
-    furi_assert(src_data);
-
-    uint8_t first_block = mf_classic_get_first_block_num_of_sector(sec_num);
-    uint8_t total_blocks = mf_classic_get_blocks_num_in_sector(sec_num);
-    MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(dest_data, sec_num);
-    bool key_a_found = mf_classic_is_key_found(dest_data, sec_num, MfClassicKeyA);
-    bool key_b_found = mf_classic_is_key_found(dest_data, sec_num, MfClassicKeyB);
-
-    bool write_success = true;
-    for(size_t i = first_block; i < first_block + total_blocks; i++) {
-        // Compare blocks
-        if(memcmp(dest_data->block[i].value, src_data->block[i].value, MF_CLASSIC_BLOCK_SIZE) !=
-           0) {
-            if(mf_classic_is_value_block(dest_data, i)) {
-                bool key_a_inc_allowed = mf_classic_is_allowed_access_data_block(
-                    dest_data, i, MfClassicKeyA, MfClassicActionDataInc);
-                bool key_b_inc_allowed = mf_classic_is_allowed_access_data_block(
-                    dest_data, i, MfClassicKeyB, MfClassicActionDataInc);
-                bool key_a_dec_allowed = mf_classic_is_allowed_access_data_block(
-                    dest_data, i, MfClassicKeyA, MfClassicActionDataDec);
-                bool key_b_dec_allowed = mf_classic_is_allowed_access_data_block(
-                    dest_data, i, MfClassicKeyB, MfClassicActionDataDec);
-
-                int32_t src_value, dst_value;
-
-                mf_classic_block_to_value(src_data->block[i].value, &src_value, NULL);
-                mf_classic_block_to_value(dest_data->block[i].value, &dst_value, NULL);
-
-                int32_t diff = src_value - dst_value;
-
-                if(diff > 0) {
-                    if(key_a_found && key_a_inc_allowed) {
-                        FURI_LOG_I(TAG, "Incrementing block %d with key A by %ld", i, diff);
-                        uint64_t key = nfc_util_bytes2num(sec_tr->key_a, 6);
-                        if(!mf_classic_value_cmd_full(
-                               tx_rx, &src_data->block[i], i, MfClassicKeyA, key, diff)) {
-                            FURI_LOG_E(TAG, "Failed to increment block %d", i);
-                            write_success = false;
-                            break;
-                        }
-                    } else if(key_b_found && key_b_inc_allowed) {
-                        FURI_LOG_I(TAG, "Incrementing block %d with key B by %ld", i, diff);
-                        uint64_t key = nfc_util_bytes2num(sec_tr->key_b, 6);
-                        if(!mf_classic_value_cmd_full(
-                               tx_rx, &src_data->block[i], i, MfClassicKeyB, key, diff)) {
-                            FURI_LOG_E(TAG, "Failed to increment block %d", i);
-                            write_success = false;
-                            break;
-                        }
-                    } else {
-                        FURI_LOG_E(TAG, "Failed to increment block %d", i);
-                    }
-                } else if(diff < 0) {
-                    if(key_a_found && key_a_dec_allowed) {
-                        FURI_LOG_I(TAG, "Decrementing block %d with key A by %ld", i, -diff);
-                        uint64_t key = nfc_util_bytes2num(sec_tr->key_a, 6);
-                        if(!mf_classic_value_cmd_full(
-                               tx_rx, &src_data->block[i], i, MfClassicKeyA, key, diff)) {
-                            FURI_LOG_E(TAG, "Failed to decrement block %d", i);
-                            write_success = false;
-                            break;
-                        }
-                    } else if(key_b_found && key_b_dec_allowed) {
-                        FURI_LOG_I(TAG, "Decrementing block %d with key B by %ld", i, diff);
-                        uint64_t key = nfc_util_bytes2num(sec_tr->key_b, 6);
-                        if(!mf_classic_value_cmd_full(
-                               tx_rx, &src_data->block[i], i, MfClassicKeyB, key, diff)) {
-                            FURI_LOG_E(TAG, "Failed to decrement block %d", i);
-                            write_success = false;
-                            break;
-                        }
-                    } else {
-                        FURI_LOG_E(TAG, "Failed to decrement block %d", i);
-                    }
-                } else {
-                    FURI_LOG_E(TAG, "Value block %d address changed, cannot write it", i);
-                }
-            } else {
-                bool key_a_write_allowed = mf_classic_is_allowed_access_data_block(
-                    dest_data, i, MfClassicKeyA, MfClassicActionDataWrite);
-                bool key_b_write_allowed = mf_classic_is_allowed_access_data_block(
-                    dest_data, i, MfClassicKeyB, MfClassicActionDataWrite);
-
-                if(key_a_found && key_a_write_allowed) {
-                    FURI_LOG_I(TAG, "Writing block %d with key A", i);
-                    uint64_t key = nfc_util_bytes2num(sec_tr->key_a, 6);
-                    if(!mf_classic_auth_write_block(
-                           tx_rx, &src_data->block[i], i, MfClassicKeyA, key)) {
-                        FURI_LOG_E(TAG, "Failed to write block %d", i);
-                        write_success = false;
-                        break;
-                    }
-                } else if(key_b_found && key_b_write_allowed) {
-                    FURI_LOG_I(TAG, "Writing block %d with key A", i);
-                    uint64_t key = nfc_util_bytes2num(sec_tr->key_b, 6);
-                    if(!mf_classic_auth_write_block(
-                           tx_rx, &src_data->block[i], i, MfClassicKeyB, key)) {
-                        FURI_LOG_E(TAG, "Failed to write block %d", i);
-                        write_success = false;
-                        break;
-                    }
-                } else {
-                    FURI_LOG_E(TAG, "Failed to find key with write access");
-                    write_success = false;
-                    break;
-                }
-            }
-        } else {
-            FURI_LOG_D(TAG, "Blocks %d are equal", i);
-        }
-    }
-
-    return write_success;
-}

+ 0 - 251
lib/nfclegacy/protocols/mifare_classic.h

@@ -1,251 +0,0 @@
-#pragma once
-
-#include "../furi_hal_nfc.h"
-
-#include "crypto1.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define MF_CLASSIC_BLOCK_SIZE (16)
-#define MF_CLASSIC_TOTAL_BLOCKS_MAX (256)
-#define MF_MINI_TOTAL_SECTORS_NUM (5)
-#define MF_CLASSIC_1K_TOTAL_SECTORS_NUM (16)
-#define MF_CLASSIC_4K_TOTAL_SECTORS_NUM (40)
-
-#define MF_CLASSIC_SECTORS_MAX (40)
-#define MF_CLASSIC_BLOCKS_IN_SECTOR_MAX (16)
-
-#define MF_CLASSIC_NO_KEY (0xFFFFFFFFFFFFFFFF)
-#define MF_CLASSIC_MAX_DATA_SIZE (16)
-#define MF_CLASSIC_KEY_SIZE (6)
-#define MF_CLASSIC_ACCESS_BYTES_SIZE (4)
-
-typedef enum {
-    MfClassicType1k,
-    MfClassicType4k,
-    MfClassicTypeMini,
-} MfClassicType;
-
-typedef enum {
-    MfClassicKeyA,
-    MfClassicKeyB,
-} MfClassicKey;
-
-typedef enum {
-    MfClassicActionDataRead,
-    MfClassicActionDataWrite,
-    MfClassicActionDataInc,
-    MfClassicActionDataDec,
-
-    MfClassicActionKeyARead,
-    MfClassicActionKeyAWrite,
-    MfClassicActionKeyBRead,
-    MfClassicActionKeyBWrite,
-    MfClassicActionACRead,
-    MfClassicActionACWrite,
-} MfClassicAction;
-
-typedef struct {
-    uint8_t value[MF_CLASSIC_BLOCK_SIZE];
-} MfClassicBlock;
-
-typedef struct {
-    uint8_t key_a[MF_CLASSIC_KEY_SIZE];
-    uint8_t access_bits[MF_CLASSIC_ACCESS_BYTES_SIZE];
-    uint8_t key_b[MF_CLASSIC_KEY_SIZE];
-} MfClassicSectorTrailer;
-
-typedef struct {
-    uint8_t total_blocks;
-    MfClassicBlock block[MF_CLASSIC_BLOCKS_IN_SECTOR_MAX];
-} MfClassicSector;
-
-typedef struct {
-    MfClassicType type;
-    uint32_t block_read_mask[MF_CLASSIC_TOTAL_BLOCKS_MAX / 32];
-    uint64_t key_a_mask;
-    uint64_t key_b_mask;
-    MfClassicBlock block[MF_CLASSIC_TOTAL_BLOCKS_MAX];
-} MfClassicData;
-
-typedef struct {
-    uint8_t sector;
-    uint64_t key_a;
-    uint64_t key_b;
-} MfClassicAuthContext;
-
-typedef struct {
-    uint8_t sector_num;
-    uint64_t key_a;
-    uint64_t key_b;
-} MfClassicSectorReader;
-
-typedef struct {
-    MfClassicType type;
-    Crypto1 crypto;
-    uint8_t sectors_to_read;
-    MfClassicSectorReader sector_reader[MF_CLASSIC_SECTORS_MAX];
-} MfClassicReader;
-
-typedef struct {
-    uint32_t cuid;
-    Crypto1 crypto;
-    MfClassicData data;
-    bool data_changed;
-} MfClassicEmulator;
-
-const char* mf_classic_get_type_str(MfClassicType type);
-
-bool mf_classic_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK);
-
-MfClassicType mf_classic_get_classic_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK);
-
-uint8_t mf_classic_get_total_sectors_num(MfClassicType type);
-
-uint16_t mf_classic_get_total_block_num(MfClassicType type);
-
-uint8_t mf_classic_get_sector_trailer_block_num_by_sector(uint8_t sector);
-
-bool mf_classic_is_sector_trailer(uint8_t block);
-
-uint8_t mf_classic_get_sector_by_block(uint8_t block);
-
-bool mf_classic_is_allowed_access_sector_trailer(
-    MfClassicData* data,
-    uint8_t block_num,
-    MfClassicKey key,
-    MfClassicAction action);
-
-bool mf_classic_is_allowed_access_data_block(
-    MfClassicData* data,
-    uint8_t block_num,
-    MfClassicKey key,
-    MfClassicAction action);
-
-bool mf_classic_is_value_block(MfClassicData* data, uint8_t block_num);
-
-bool mf_classic_block_to_value(const uint8_t* block, int32_t* value, uint8_t* addr);
-
-void mf_classic_value_to_block(int32_t value, uint8_t addr, uint8_t* block);
-
-bool mf_classic_is_key_found(MfClassicData* data, uint8_t sector_num, MfClassicKey key_type);
-
-void mf_classic_set_key_found(
-    MfClassicData* data,
-    uint8_t sector_num,
-    MfClassicKey key_type,
-    uint64_t key);
-
-void mf_classic_set_key_not_found(MfClassicData* data, uint8_t sector_num, MfClassicKey key_type);
-
-bool mf_classic_is_block_read(MfClassicData* data, uint8_t block_num);
-
-void mf_classic_set_block_read(MfClassicData* data, uint8_t block_num, MfClassicBlock* block_data);
-
-bool mf_classic_is_sector_data_read(MfClassicData* data, uint8_t sector_num);
-
-void mf_classic_set_sector_data_not_read(MfClassicData* data);
-
-bool mf_classic_is_sector_read(MfClassicData* data, uint8_t sector_num);
-
-bool mf_classic_is_card_read(MfClassicData* data);
-
-void mf_classic_get_read_sectors_and_keys(
-    MfClassicData* data,
-    uint8_t* sectors_read,
-    uint8_t* keys_found);
-
-MfClassicSectorTrailer*
-    mf_classic_get_sector_trailer_by_sector(MfClassicData* data, uint8_t sector);
-
-void mf_classic_auth_init_context(MfClassicAuthContext* auth_ctx, uint8_t sector);
-
-bool mf_classic_authenticate(
-    FurryHalNfcTxRxContext* tx_rx,
-    uint8_t block_num,
-    uint64_t key,
-    MfClassicKey key_type);
-
-bool mf_classic_authenticate_skip_activate(
-    FurryHalNfcTxRxContext* tx_rx,
-    uint8_t block_num,
-    uint64_t key,
-    MfClassicKey key_type,
-    bool skip_activate,
-    uint32_t cuid);
-
-bool mf_classic_auth_attempt(
-    FurryHalNfcTxRxContext* tx_rx,
-    Crypto1* crypto,
-    MfClassicAuthContext* auth_ctx,
-    uint64_t key);
-
-void mf_classic_reader_add_sector(
-    MfClassicReader* reader,
-    uint8_t sector,
-    uint64_t key_a,
-    uint64_t key_b);
-
-bool mf_classic_read_block(
-    FurryHalNfcTxRxContext* tx_rx,
-    Crypto1* crypto,
-    uint8_t block_num,
-    MfClassicBlock* block);
-
-void mf_classic_read_sector(FurryHalNfcTxRxContext* tx_rx, MfClassicData* data, uint8_t sec_num);
-
-uint8_t mf_classic_read_card(
-    FurryHalNfcTxRxContext* tx_rx,
-    MfClassicReader* reader,
-    MfClassicData* data);
-
-uint8_t mf_classic_update_card(FurryHalNfcTxRxContext* tx_rx, MfClassicData* data);
-
-bool mf_classic_emulator(
-    MfClassicEmulator* emulator,
-    FurryHalNfcTxRxContext* tx_rx,
-    bool is_reader_analyzer);
-
-void mf_classic_halt(FurryHalNfcTxRxContext* tx_rx, Crypto1* crypto);
-
-bool mf_classic_write_block(
-    FurryHalNfcTxRxContext* tx_rx,
-    Crypto1* crypto,
-    uint8_t block_num,
-    MfClassicBlock* src_block);
-
-bool mf_classic_auth_write_block(
-    FurryHalNfcTxRxContext* tx_rx,
-    MfClassicBlock* src_block,
-    uint8_t block_num,
-    MfClassicKey key_type,
-    uint64_t key);
-
-bool mf_classic_transfer(FurryHalNfcTxRxContext* tx_rx, Crypto1* crypto, uint8_t block_num);
-
-bool mf_classic_value_cmd(
-    FurryHalNfcTxRxContext* tx_rx,
-    Crypto1* crypto,
-    uint8_t block_num,
-    uint8_t cmd,
-    int32_t d_value);
-
-bool mf_classic_value_cmd_full(
-    FurryHalNfcTxRxContext* tx_rx,
-    MfClassicBlock* src_block,
-    uint8_t block_num,
-    MfClassicKey key_type,
-    uint64_t key,
-    int32_t d_value);
-
-bool mf_classic_write_sector(
-    FurryHalNfcTxRxContext* tx_rx,
-    MfClassicData* dest_data,
-    MfClassicData* src_data,
-    uint8_t sec_num);
-
-#ifdef __cplusplus
-}
-#endif

+ 0 - 236
lib/nfclegacy/pulse_reader/pulse_reader.c

@@ -1,236 +0,0 @@
-#include "pulse_reader.h"
-
-#include <limits.h>
-#include <furi.h>
-#include <furi_hal.h>
-#include <furi_hal_gpio.h>
-
-#include <stm32wbxx_ll_dma.h>
-#include <stm32wbxx_ll_dmamux.h>
-#include <stm32wbxx_ll_tim.h>
-#include <stm32wbxx_ll_exti.h>
-
-struct PulseReader {
-    uint32_t* timer_buffer;
-    uint32_t* gpio_buffer;
-    uint32_t size;
-    uint32_t pos;
-    uint32_t timer_value;
-    uint32_t gpio_value;
-    uint32_t gpio_mask;
-    uint32_t unit_multiplier;
-    uint32_t unit_divider;
-    uint32_t bit_time;
-    uint32_t dma_channel;
-    const GpioPin* gpio;
-    GpioPull pull;
-    LL_DMA_InitTypeDef dma_config_timer;
-    LL_DMA_InitTypeDef dma_config_gpio;
-};
-
-#define GPIO_PIN_MAP(pin, prefix)               \
-    (((pin) == (LL_GPIO_PIN_0))  ? prefix##0 :  \
-     ((pin) == (LL_GPIO_PIN_1))  ? prefix##1 :  \
-     ((pin) == (LL_GPIO_PIN_2))  ? prefix##2 :  \
-     ((pin) == (LL_GPIO_PIN_3))  ? prefix##3 :  \
-     ((pin) == (LL_GPIO_PIN_4))  ? prefix##4 :  \
-     ((pin) == (LL_GPIO_PIN_5))  ? prefix##5 :  \
-     ((pin) == (LL_GPIO_PIN_6))  ? prefix##6 :  \
-     ((pin) == (LL_GPIO_PIN_7))  ? prefix##7 :  \
-     ((pin) == (LL_GPIO_PIN_8))  ? prefix##8 :  \
-     ((pin) == (LL_GPIO_PIN_9))  ? prefix##9 :  \
-     ((pin) == (LL_GPIO_PIN_10)) ? prefix##10 : \
-     ((pin) == (LL_GPIO_PIN_11)) ? prefix##11 : \
-     ((pin) == (LL_GPIO_PIN_12)) ? prefix##12 : \
-     ((pin) == (LL_GPIO_PIN_13)) ? prefix##13 : \
-     ((pin) == (LL_GPIO_PIN_14)) ? prefix##14 : \
-                                   prefix##15)
-
-#define GET_DMAMUX_EXTI_LINE(pin) GPIO_PIN_MAP(pin, LL_DMAMUX_REQ_GEN_EXTI_LINE)
-
-PulseReader* pulse_reader_alloc(const GpioPin* gpio, uint32_t size) {
-    PulseReader* signal = malloc(sizeof(PulseReader));
-    signal->timer_buffer = malloc(size * sizeof(uint32_t));
-    signal->gpio_buffer = malloc(size * sizeof(uint32_t));
-    signal->dma_channel = LL_DMA_CHANNEL_4;
-    signal->gpio = gpio;
-    signal->pull = GpioPullNo;
-    signal->size = size;
-    signal->timer_value = 0;
-    signal->pos = 0;
-
-    pulse_reader_set_timebase(signal, PulseReaderUnit64MHz);
-    pulse_reader_set_bittime(signal, 1);
-
-    signal->dma_config_timer.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
-    signal->dma_config_timer.PeriphOrM2MSrcAddress = (uint32_t) & (TIM2->CNT);
-    signal->dma_config_timer.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
-    signal->dma_config_timer.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD;
-    signal->dma_config_timer.MemoryOrM2MDstAddress = (uint32_t)signal->timer_buffer;
-    signal->dma_config_timer.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT;
-    signal->dma_config_timer.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD;
-    signal->dma_config_timer.Mode = LL_DMA_MODE_CIRCULAR;
-    signal->dma_config_timer.PeriphRequest =
-        LL_DMAMUX_REQ_GENERATOR0; /* executes LL_DMA_SetPeriphRequest */
-    signal->dma_config_timer.Priority = LL_DMA_PRIORITY_VERYHIGH;
-
-    signal->dma_config_gpio.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
-    signal->dma_config_gpio.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
-    signal->dma_config_gpio.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD;
-    signal->dma_config_gpio.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT;
-    signal->dma_config_gpio.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD;
-    signal->dma_config_gpio.Mode = LL_DMA_MODE_CIRCULAR;
-    signal->dma_config_gpio.PeriphRequest =
-        LL_DMAMUX_REQ_GENERATOR0; /* executes LL_DMA_SetPeriphRequest */
-    signal->dma_config_gpio.Priority = LL_DMA_PRIORITY_VERYHIGH;
-
-    return signal;
-}
-
-void pulse_reader_set_timebase(PulseReader* signal, PulseReaderUnit unit) {
-    switch(unit) {
-    case PulseReaderUnit64MHz:
-        signal->unit_multiplier = 1;
-        signal->unit_divider = 1;
-        break;
-    case PulseReaderUnitPicosecond:
-        signal->unit_multiplier = 15625;
-        signal->unit_divider = 1;
-        break;
-    case PulseReaderUnitNanosecond:
-        signal->unit_multiplier = 15625;
-        signal->unit_divider = 1000;
-        break;
-    case PulseReaderUnitMicrosecond:
-        signal->unit_multiplier = 15625;
-        signal->unit_divider = 1000000;
-        break;
-    }
-}
-
-void pulse_reader_set_bittime(PulseReader* signal, uint32_t bit_time) {
-    signal->bit_time = bit_time;
-}
-
-void pulse_reader_set_pull(PulseReader* signal, GpioPull pull) {
-    signal->pull = pull;
-}
-
-void pulse_reader_free(PulseReader* signal) {
-    furi_assert(signal);
-
-    free(signal->timer_buffer);
-    free(signal->gpio_buffer);
-    free(signal);
-}
-
-uint32_t pulse_reader_samples(PulseReader* signal) {
-    uint32_t dma_pos = signal->size - (uint32_t)LL_DMA_GetDataLength(DMA1, signal->dma_channel);
-
-    return ((signal->pos + signal->size) - dma_pos) % signal->size;
-}
-
-void pulse_reader_stop(PulseReader* signal) {
-    LL_DMA_DisableChannel(DMA1, signal->dma_channel);
-    LL_DMA_DisableChannel(DMA1, signal->dma_channel + 1);
-    LL_DMAMUX_DisableRequestGen(NULL, LL_DMAMUX_REQ_GEN_0);
-    LL_TIM_DisableCounter(TIM2);
-    furi_hal_bus_disable(FuriHalBusTIM2);
-    furi_hal_gpio_init_simple(signal->gpio, GpioModeAnalog);
-}
-
-void pulse_reader_start(PulseReader* signal) {
-    /* configure DMA to read from a timer peripheral */
-    signal->dma_config_timer.NbData = signal->size;
-
-    signal->dma_config_gpio.PeriphOrM2MSrcAddress = (uint32_t) & (signal->gpio->port->IDR);
-    signal->dma_config_gpio.MemoryOrM2MDstAddress = (uint32_t)signal->gpio_buffer;
-    signal->dma_config_gpio.NbData = signal->size;
-
-    furi_hal_bus_enable(FuriHalBusTIM2);
-
-    /* start counter */
-    LL_TIM_SetCounterMode(TIM2, LL_TIM_COUNTERMODE_UP);
-    LL_TIM_SetClockDivision(TIM2, LL_TIM_CLOCKDIVISION_DIV1);
-    LL_TIM_SetPrescaler(TIM2, 0);
-    LL_TIM_SetAutoReload(TIM2, 0xFFFFFFFF);
-    LL_TIM_SetCounter(TIM2, 0);
-    LL_TIM_EnableCounter(TIM2);
-
-    /* generator 0 gets fed by EXTI_LINEn */
-    LL_DMAMUX_SetRequestSignalID(
-        NULL, LL_DMAMUX_REQ_GEN_0, GET_DMAMUX_EXTI_LINE(signal->gpio->pin));
-    /* trigger on rising edge of the interrupt */
-    LL_DMAMUX_SetRequestGenPolarity(NULL, LL_DMAMUX_REQ_GEN_0, LL_DMAMUX_REQ_GEN_POL_RISING);
-    /* now enable request generation again */
-    LL_DMAMUX_EnableRequestGen(NULL, LL_DMAMUX_REQ_GEN_0);
-
-    /* we need the EXTI to be configured as interrupt generating line, but no ISR registered */
-    furi_hal_gpio_init_ex(
-        signal->gpio, GpioModeInterruptRiseFall, signal->pull, GpioSpeedVeryHigh, GpioAltFnUnused);
-
-    /* capture current timer */
-    signal->pos = 0;
-    signal->timer_value = TIM2->CNT;
-    signal->gpio_mask = signal->gpio->pin;
-    signal->gpio_value = signal->gpio->port->IDR & signal->gpio_mask;
-
-    /* now set up DMA with these settings */
-    LL_DMA_Init(DMA1, signal->dma_channel, &signal->dma_config_timer);
-    LL_DMA_Init(DMA1, signal->dma_channel + 1, &signal->dma_config_gpio);
-    LL_DMA_EnableChannel(DMA1, signal->dma_channel);
-    LL_DMA_EnableChannel(DMA1, signal->dma_channel + 1);
-}
-
-uint32_t pulse_reader_receive(PulseReader* signal, int timeout_us) {
-    uint32_t start_time = DWT->CYCCNT;
-    uint32_t timeout_ticks = timeout_us * (F_TIM2 / 1000000);
-
-    do {
-        /* get the DMA's next write position by reading "remaining length" register */
-        uint32_t dma_pos =
-            signal->size - (uint32_t)LL_DMA_GetDataLength(DMA1, signal->dma_channel);
-
-        /* the DMA has advanced in the ringbuffer */
-        if(dma_pos != signal->pos) {
-            uint32_t delta = signal->timer_buffer[signal->pos] - signal->timer_value;
-            uint32_t last_gpio_value = signal->gpio_value;
-
-            signal->gpio_value = signal->gpio_buffer[signal->pos];
-
-            /* check if the GPIO really toggled. if not, we lost an edge :( */
-            if(((last_gpio_value ^ signal->gpio_value) & signal->gpio_mask) != signal->gpio_mask) {
-                signal->gpio_value ^= signal->gpio_mask;
-                return PULSE_READER_LOST_EDGE;
-            }
-            signal->timer_value = signal->timer_buffer[signal->pos];
-
-            signal->pos++;
-            signal->pos %= signal->size;
-
-            uint32_t delta_unit = 0;
-
-            /* probably larger values, so choose a wider data type */
-            if(signal->unit_divider > 1) {
-                delta_unit =
-                    (uint32_t)((uint64_t)delta * (uint64_t)signal->unit_multiplier / signal->unit_divider);
-            } else {
-                delta_unit = delta * signal->unit_multiplier;
-            }
-
-            /* if to be scaled to bit times, save a few instructions. should be faster */
-            if(signal->bit_time > 1) {
-                return (delta_unit + signal->bit_time / 2) / signal->bit_time;
-            }
-
-            return delta_unit;
-        }
-
-        /* check for timeout */
-        uint32_t elapsed = DWT->CYCCNT - start_time;
-
-        if(elapsed > timeout_ticks) {
-            return PULSE_READER_NO_EDGE;
-        }
-    } while(true);
-}

+ 0 - 122
lib/nfclegacy/pulse_reader/pulse_reader.h

@@ -1,122 +0,0 @@
-#pragma once
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdbool.h>
-
-#include <furi_hal_gpio.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define PULSE_READER_NO_EDGE (0xFFFFFFFFUL)
-#define PULSE_READER_LOST_EDGE (0xFFFFFFFEUL)
-#define F_TIM2 (64000000UL)
-
-/**
- * unit of the edge durations to return
- */
-typedef enum {
-    PulseReaderUnit64MHz,
-    PulseReaderUnitPicosecond,
-    PulseReaderUnitNanosecond,
-    PulseReaderUnitMicrosecond,
-} PulseReaderUnit;
-
-/* using an anonymous type */
-typedef struct PulseReader PulseReader;
-
-/** Allocate a PulseReader object
- *
- * Allocates memory for a ringbuffer and initalizes the object
- *
- * @param[in]  gpio        the GPIO to use. will get configured as input.
- * @param[in]  size        number of edges to buffer
- */
-PulseReader* pulse_reader_alloc(const GpioPin* gpio, uint32_t size);
-
-/** Free a PulseReader object
- *
- * Frees all memory of the given object
- *
- * @param[in]  signal      previously allocated PulseReader object.
- */
-void pulse_reader_free(PulseReader* signal);
-
-/** Start signal capturing
- *
- * Initializes DMA1, TIM2 and DMAMUX_REQ_GEN_0 to automatically capture timer values.
- * Ensure that interrupts are always enabled, as the used EXTI line is handled as one.
- *
- * @param[in]  signal      previously allocated PulseReader object.
- */
-void pulse_reader_start(PulseReader* signal);
-
-/** Stop signal capturing
- *
- * Frees DMA1, TIM2 and DMAMUX_REQ_GEN_0
- *
- * @param[in]  signal      previously allocated PulseReader object.
- */
-void pulse_reader_stop(PulseReader* signal);
-
-/** Recevie a sample from ringbuffer
- *
- * Waits for the specified time until a new edge gets detected.
- * If not configured otherwise, the pulse duration will be in picosecond resolution.
- * If a bittime was configured, the return value will contain the properly rounded
- * number of bit times measured.
- *
- * @param[in]  signal      previously allocated PulseReader object.
- * @param[in]  timeout_us  time to wait for a signal [µs]
- *
- * @returns the scaled value of the pulse duration
- */
-uint32_t pulse_reader_receive(PulseReader* signal, int timeout_us);
-
-/** Get available samples
- *
- * Get the number of available samples in the ringbuffer
- *
- * @param[in]  signal  previously allocated PulseReader object.
- *
- * @returns the number of samples in buffer
- */
-uint32_t pulse_reader_samples(PulseReader* signal);
-
-/** Set timebase
- *
- * Set the timebase to be used when returning pulse duration.
- *
- * @param[in]  signal  previously allocated PulseReader object.
- * @param[in]  unit  PulseReaderUnit64MHz or PulseReaderUnitPicosecond
- */
-void pulse_reader_set_timebase(PulseReader* signal, PulseReaderUnit unit);
-
-/** Set bit time
- *
- * Set the number of timebase units per bit.
- * When set, the pulse_reader_receive() will return an already rounded
- * bit count value instead of the raw duration.
- *
- * Set to 1 to return duration again.
- *
- * @param[in]  signal    previously allocated PulseReader object.
- * @param[in]  bit_time
- */
-void pulse_reader_set_bittime(PulseReader* signal, uint32_t bit_time);
-
-/** Set GPIO pull direction
- *
- * Some GPIOs need pulldown, others don't. By default the
- * pull direction is GpioPullNo.
- *
- * @param[in]  signal    previously allocated PulseReader object.
- * @param[in]  pull      GPIO pull direction
- */
-void pulse_reader_set_pull(PulseReader* signal, GpioPull pull);
-
-#ifdef __cplusplus
-}
-#endif