mf_classic_key_cache.c 7.5 KB

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