mf_classic_key_cache.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. #include "mf_classic_key_cache.h"
  2. #include <furi/furi.h>
  3. #include <storage/storage.h>
  4. #include "../metroflip/metroflip_api.h"
  5. #define NFC_APP_KEYS_EXTENSION ".keys"
  6. #define NFC_APP_KEY_CACHE_FOLDER "/ext/nfc/.cache"
  7. static const char* mf_classic_key_cache_file_header = "Flipper NFC keys";
  8. static const uint32_t mf_classic_key_cache_file_version = 1;
  9. struct MfClassicKeyCache {
  10. MfClassicDeviceKeys keys;
  11. MfClassicKeyType current_key_type;
  12. uint8_t current_sector;
  13. };
  14. static void nfc_get_key_cache_file_path(const uint8_t* uid, size_t uid_len, FuriString* path) {
  15. furi_string_printf(path, "%s/", NFC_APP_KEY_CACHE_FOLDER);
  16. for(size_t i = 0; i < uid_len; i++) {
  17. furi_string_cat_printf(path, "%02X", uid[i]);
  18. }
  19. furi_string_cat_printf(path, "%s", NFC_APP_KEYS_EXTENSION);
  20. }
  21. MfClassicKeyCache* mf_classic_key_cache_alloc(void) {
  22. MfClassicKeyCache* instance = malloc(sizeof(MfClassicKeyCache));
  23. return instance;
  24. }
  25. void mf_classic_key_cache_free(MfClassicKeyCache* instance) {
  26. furi_assert(instance);
  27. free(instance);
  28. }
  29. bool mf_classic_key_cache_save(MfClassicKeyCache* instance, const MfClassicData* data) {
  30. UNUSED(instance);
  31. furi_assert(data);
  32. size_t uid_len = 0;
  33. const uint8_t* uid = mf_classic_get_uid(data, &uid_len);
  34. FuriString* file_path = furi_string_alloc();
  35. nfc_get_key_cache_file_path(uid, uid_len, file_path);
  36. Storage* storage = furi_record_open(RECORD_STORAGE);
  37. FlipperFormat* ff = flipper_format_buffered_file_alloc(storage);
  38. FuriString* temp_str = furi_string_alloc();
  39. bool save_success = false;
  40. do {
  41. if(!storage_simply_mkdir(storage, NFC_APP_KEY_CACHE_FOLDER)) break;
  42. if(!storage_simply_remove(storage, furi_string_get_cstr(file_path))) break;
  43. if(!flipper_format_buffered_file_open_always(ff, furi_string_get_cstr(file_path))) break;
  44. if(!flipper_format_write_header_cstr(
  45. ff, mf_classic_key_cache_file_header, mf_classic_key_cache_file_version))
  46. break;
  47. if(!flipper_format_write_string_cstr(
  48. ff, "Mifare Classic type", mf_classic_get_device_name(data, NfcDeviceNameTypeShort)))
  49. break;
  50. if(!flipper_format_write_hex_uint64(ff, "Key A map", &data->key_a_mask, 1)) break;
  51. if(!flipper_format_write_hex_uint64(ff, "Key B map", &data->key_b_mask, 1)) break;
  52. uint8_t sector_num = mf_classic_get_total_sectors_num(data->type);
  53. bool key_save_success = true;
  54. for(size_t i = 0; (i < sector_num) && (key_save_success); i++) {
  55. MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, i);
  56. if(FURI_BIT(data->key_a_mask, i)) {
  57. furi_string_printf(temp_str, "Key A sector %d", i);
  58. key_save_success = flipper_format_write_hex(
  59. ff, furi_string_get_cstr(temp_str), sec_tr->key_a.data, sizeof(MfClassicKey));
  60. }
  61. if(!key_save_success) break;
  62. if(FURI_BIT(data->key_b_mask, i)) {
  63. furi_string_printf(temp_str, "Key B sector %d", i);
  64. key_save_success = flipper_format_write_hex(
  65. ff, furi_string_get_cstr(temp_str), sec_tr->key_b.data, sizeof(MfClassicKey));
  66. }
  67. }
  68. save_success = key_save_success;
  69. } while(false);
  70. flipper_format_free(ff);
  71. furi_string_free(temp_str);
  72. furi_string_free(file_path);
  73. furi_record_close(RECORD_STORAGE);
  74. return save_success;
  75. }
  76. bool mf_classic_key_cache_load(MfClassicKeyCache* instance, const uint8_t* uid, size_t uid_len) {
  77. furi_assert(instance);
  78. furi_assert(uid);
  79. mf_classic_key_cache_reset(instance);
  80. FuriString* file_path = furi_string_alloc();
  81. nfc_get_key_cache_file_path(uid, uid_len, file_path);
  82. Storage* storage = furi_record_open(RECORD_STORAGE);
  83. FlipperFormat* ff = flipper_format_buffered_file_alloc(storage);
  84. FuriString* temp_str = furi_string_alloc();
  85. bool load_success = false;
  86. do {
  87. if(!flipper_format_buffered_file_open_existing(ff, furi_string_get_cstr(file_path))) break;
  88. uint32_t version = 0;
  89. if(!flipper_format_read_header(ff, temp_str, &version)) break;
  90. if(furi_string_cmp_str(temp_str, mf_classic_key_cache_file_header)) break;
  91. if(version != mf_classic_key_cache_file_version) break;
  92. if(!flipper_format_read_hex_uint64(ff, "Key A map", &instance->keys.key_a_mask, 1)) break;
  93. if(!flipper_format_read_hex_uint64(ff, "Key B map", &instance->keys.key_b_mask, 1)) break;
  94. bool key_read_success = true;
  95. for(size_t i = 0; (i < MF_CLASSIC_TOTAL_SECTORS_MAX) && (key_read_success); i++) {
  96. if(FURI_BIT(instance->keys.key_a_mask, i)) {
  97. furi_string_printf(temp_str, "Key A sector %d", i);
  98. key_read_success = flipper_format_read_hex(
  99. ff,
  100. furi_string_get_cstr(temp_str),
  101. instance->keys.key_a[i].data,
  102. sizeof(MfClassicKey));
  103. }
  104. if(!key_read_success) break;
  105. if(FURI_BIT(instance->keys.key_b_mask, i)) {
  106. furi_string_printf(temp_str, "Key B sector %d", i);
  107. key_read_success = flipper_format_read_hex(
  108. ff,
  109. furi_string_get_cstr(temp_str),
  110. instance->keys.key_b[i].data,
  111. sizeof(MfClassicKey));
  112. }
  113. }
  114. load_success = key_read_success;
  115. } while(false);
  116. flipper_format_buffered_file_close(ff);
  117. flipper_format_free(ff);
  118. furi_string_free(temp_str);
  119. furi_string_free(file_path);
  120. furi_record_close(RECORD_STORAGE);
  121. return load_success;
  122. }
  123. void mf_classic_key_cache_load_from_data(MfClassicKeyCache* instance, const MfClassicData* data) {
  124. furi_assert(instance);
  125. furi_assert(data);
  126. mf_classic_key_cache_reset(instance);
  127. instance->keys.key_a_mask = data->key_a_mask;
  128. instance->keys.key_b_mask = data->key_b_mask;
  129. for(size_t i = 0; i < MF_CLASSIC_TOTAL_SECTORS_MAX; i++) {
  130. MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, i);
  131. if(FURI_BIT(data->key_a_mask, i)) {
  132. instance->keys.key_a[i] = sec_tr->key_a;
  133. }
  134. if(FURI_BIT(data->key_b_mask, i)) {
  135. instance->keys.key_b[i] = sec_tr->key_b;
  136. }
  137. }
  138. }
  139. bool mf_classic_key_cache_get_next_key(
  140. MfClassicKeyCache* instance,
  141. uint8_t* sector_num,
  142. MfClassicKey* key,
  143. MfClassicKeyType* key_type) {
  144. furi_assert(instance);
  145. furi_assert(sector_num);
  146. furi_assert(key);
  147. furi_assert(key_type);
  148. bool next_key_found = false;
  149. for(uint8_t i = instance->current_sector; i < MF_CLASSIC_TOTAL_SECTORS_MAX; i++) {
  150. if(FURI_BIT(instance->keys.key_a_mask, i)) {
  151. FURI_BIT_CLEAR(instance->keys.key_a_mask, i);
  152. *key = instance->keys.key_a[i];
  153. *key_type = MfClassicKeyTypeA;
  154. *sector_num = i;
  155. next_key_found = true;
  156. break;
  157. }
  158. if(FURI_BIT(instance->keys.key_b_mask, i)) {
  159. FURI_BIT_CLEAR(instance->keys.key_b_mask, i);
  160. *key = instance->keys.key_b[i];
  161. *key_type = MfClassicKeyTypeB;
  162. *sector_num = i;
  163. next_key_found = true;
  164. instance->current_sector = i;
  165. break;
  166. }
  167. }
  168. return next_key_found;
  169. }
  170. void mf_classic_key_cache_reset(MfClassicKeyCache* instance) {
  171. furi_assert(instance);
  172. instance->current_key_type = MfClassicKeyTypeA;
  173. instance->current_sector = 0;
  174. instance->keys.key_a_mask = 0;
  175. instance->keys.key_b_mask = 0;
  176. }