Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NFC Fix Mifare Classic #1769

Merged
merged 3 commits into from
Sep 22, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions applications/debug/unit_tests/nfc/nfc_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <storage/storage.h>
#include <lib/flipper_format/flipper_format.h>
#include <lib/nfc/protocols/nfca.h>
#include <lib/nfc/helpers/mf_classic_dict.h>
#include <lib/digital_signal/digital_signal.h>

#include <lib/flipper_format/flipper_format_i.h>
Expand Down Expand Up @@ -170,10 +171,59 @@ MU_TEST(nfc_digital_signal_test) {
"NFC long digital signal test failed\r\n");
}

MU_TEST(mf_classic_dict_test) {
MfClassicDict* instance = NULL;
uint64_t key = 0;
string_t temp_str;
string_init(temp_str);

instance = mf_classic_dict_alloc(MfClassicDictTypeUnitTest);
mu_assert(instance != NULL, "mf_classic_dict_alloc\r\n");

mu_assert(
mf_classic_dict_get_total_keys(instance) == 0,
"mf_classic_dict_get_total_keys == 0 assert failed\r\n");

string_set(temp_str, "2196FAD8115B");
mu_assert(
mf_classic_dict_add_key_str(instance, temp_str),
"mf_classic_dict_add_key == true assert failed\r\n");

mu_assert(
mf_classic_dict_get_total_keys(instance) == 1,
"mf_classic_dict_get_total_keys == 1 assert failed\r\n");

mu_assert(mf_classic_dict_rewind(instance), "mf_classic_dict_rewind == 1 assert failed\r\n");

mu_assert(
mf_classic_dict_get_key_at_index_str(instance, temp_str, 0),
"mf_classic_dict_get_key_at_index_str == true assert failed\r\n");
mu_assert(
string_cmp(temp_str, "2196FAD8115B") == 0,
"string_cmp(temp_str, \"2196FAD8115B\") == 0 assert failed\r\n");

mu_assert(mf_classic_dict_rewind(instance), "mf_classic_dict_rewind == 1 assert failed\r\n");

mu_assert(
mf_classic_dict_get_key_at_index(instance, &key, 0),
"mf_classic_dict_get_key_at_index == true assert failed\r\n");
mu_assert(key == 0x2196FAD8115B, "key == 0x2196FAD8115B assert failed\r\n");

mu_assert(mf_classic_dict_rewind(instance), "mf_classic_dict_rewind == 1 assert failed\r\n");

mu_assert(
mf_classic_dict_delete_index(instance, 0),
"mf_classic_dict_delete_index == true assert failed\r\n");

mf_classic_dict_free(instance);
string_clear(temp_str);
}

MU_TEST_SUITE(nfc) {
nfc_test_alloc();

MU_RUN_TEST(nfc_digital_signal_test);
MU_RUN_TEST(mf_classic_dict_test);

nfc_test_free();
}
Expand Down
15 changes: 14 additions & 1 deletion lib/nfc/helpers/mf_classic_dict.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#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"

Expand All @@ -23,6 +24,9 @@ bool mf_classic_dict_check_presence(MfClassicDictType dict_type) {
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);
Expand Down Expand Up @@ -50,6 +54,15 @@ MfClassicDict* mf_classic_dict_alloc(MfClassicDictType dict_type) {
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_CREATE_ALWAYS)) {
buffered_file_stream_close(dict->stream);
break;
}
}

// Read total amount of keys
Expand Down Expand Up @@ -100,7 +113,7 @@ static void mf_classic_dict_str_to_int(string_t key_str, uint64_t* key_int) {
for(uint8_t i = 0; i < 12; i += 2) {
args_char_to_hex(
string_get_char(key_str, i), string_get_char(key_str, i + 1), &key_byte_tmp);
*key_int |= (uint8_t)key_byte_tmp << 8 * (5 - i / 2);
*key_int |= (uint64_t)key_byte_tmp << 8 * (5 - i / 2);
}
}

Expand Down
53 changes: 53 additions & 0 deletions lib/nfc/helpers/mf_classic_dict.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,41 @@
typedef enum {
MfClassicDictTypeUser,
MfClassicDictTypeFlipper,
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);
Expand All @@ -31,16 +54,46 @@ bool mf_classic_dict_get_next_key(MfClassicDict* dict, uint64_t* key);

bool mf_classic_dict_get_next_key_str(MfClassicDict* dict, string_t 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 string_t
*
* @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, string_t 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, string_t key);

bool mf_classic_dict_find_index(MfClassicDict* dict, uint8_t* key, uint32_t* target);

bool mf_classic_dict_find_index_str(MfClassicDict* dict, string_t 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);