mifare_desfire.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. #include "mifare_desfire.h"
  2. #include <furi.h>
  3. #include <furi_hal_nfc.h>
  4. #define TAG "MifareDESFire"
  5. void mf_df_clear(MifareDesfireData* data) {
  6. free(data->free_memory);
  7. if(data->master_key_settings) {
  8. MifareDesfireKeyVersion* key_version = data->master_key_settings->key_version_head;
  9. while(key_version) {
  10. MifareDesfireKeyVersion* next_key_version = key_version->next;
  11. free(key_version);
  12. key_version = next_key_version;
  13. }
  14. }
  15. free(data->master_key_settings);
  16. MifareDesfireApplication* app = data->app_head;
  17. while(app) {
  18. MifareDesfireApplication* next_app = app->next;
  19. if(app->key_settings) {
  20. MifareDesfireKeyVersion* key_version = app->key_settings->key_version_head;
  21. while(key_version) {
  22. MifareDesfireKeyVersion* next_key_version = key_version->next;
  23. free(key_version);
  24. key_version = next_key_version;
  25. }
  26. }
  27. free(app->key_settings);
  28. MifareDesfireFile* file = app->file_head;
  29. while(file) {
  30. MifareDesfireFile* next_file = file->next;
  31. free(file->contents);
  32. free(file);
  33. file = next_file;
  34. }
  35. free(app);
  36. app = next_app;
  37. }
  38. data->free_memory = NULL;
  39. data->master_key_settings = NULL;
  40. data->app_head = NULL;
  41. }
  42. void mf_df_cat_data(MifareDesfireData* data, string_t out) {
  43. mf_df_cat_card_info(data, out);
  44. for(MifareDesfireApplication* app = data->app_head; app; app = app->next) {
  45. mf_df_cat_application(app, out);
  46. }
  47. }
  48. void mf_df_cat_card_info(MifareDesfireData* data, string_t out) {
  49. mf_df_cat_version(&data->version, out);
  50. if(data->free_memory) {
  51. mf_df_cat_free_mem(data->free_memory, out);
  52. }
  53. if(data->master_key_settings) {
  54. mf_df_cat_key_settings(data->master_key_settings, out);
  55. }
  56. }
  57. void mf_df_cat_version(MifareDesfireVersion* version, string_t out) {
  58. string_cat_printf(
  59. out,
  60. "%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
  61. version->uid[0],
  62. version->uid[1],
  63. version->uid[2],
  64. version->uid[3],
  65. version->uid[4],
  66. version->uid[5],
  67. version->uid[6]);
  68. string_cat_printf(
  69. out,
  70. "hw %02x type %02x sub %02x\n"
  71. " maj %02x min %02x\n"
  72. " size %02x proto %02x\n",
  73. version->hw_vendor,
  74. version->hw_type,
  75. version->hw_subtype,
  76. version->hw_major,
  77. version->hw_minor,
  78. version->hw_storage,
  79. version->hw_proto);
  80. string_cat_printf(
  81. out,
  82. "sw %02x type %02x sub %02x\n"
  83. " maj %02x min %02x\n"
  84. " size %02x proto %02x\n",
  85. version->sw_vendor,
  86. version->sw_type,
  87. version->sw_subtype,
  88. version->sw_major,
  89. version->sw_minor,
  90. version->sw_storage,
  91. version->sw_proto);
  92. string_cat_printf(
  93. out,
  94. "batch %02x:%02x:%02x:%02x:%02x\n"
  95. "week %d year %d\n",
  96. version->batch[0],
  97. version->batch[1],
  98. version->batch[2],
  99. version->batch[3],
  100. version->batch[4],
  101. version->prod_week,
  102. version->prod_year);
  103. }
  104. void mf_df_cat_free_mem(MifareDesfireFreeMemory* free_mem, string_t out) {
  105. string_cat_printf(out, "freeMem %d\n", free_mem->bytes);
  106. }
  107. void mf_df_cat_key_settings(MifareDesfireKeySettings* ks, string_t out) {
  108. string_cat_printf(out, "changeKeyID %d\n", ks->change_key_id);
  109. string_cat_printf(out, "configChangeable %d\n", ks->config_changeable);
  110. string_cat_printf(out, "freeCreateDelete %d\n", ks->free_create_delete);
  111. string_cat_printf(out, "freeDirectoryList %d\n", ks->free_directory_list);
  112. string_cat_printf(out, "masterChangeable %d\n", ks->master_key_changeable);
  113. if(ks->flags) {
  114. string_cat_printf(out, "flags %d\n", ks->flags);
  115. }
  116. string_cat_printf(out, "maxKeys %d\n", ks->max_keys);
  117. for(MifareDesfireKeyVersion* kv = ks->key_version_head; kv; kv = kv->next) {
  118. string_cat_printf(out, "key %d version %d\n", kv->id, kv->version);
  119. }
  120. }
  121. void mf_df_cat_application_info(MifareDesfireApplication* app, string_t out) {
  122. string_cat_printf(out, "Application %02x%02x%02x\n", app->id[0], app->id[1], app->id[2]);
  123. if(app->key_settings) {
  124. mf_df_cat_key_settings(app->key_settings, out);
  125. }
  126. }
  127. void mf_df_cat_application(MifareDesfireApplication* app, string_t out) {
  128. mf_df_cat_application_info(app, out);
  129. for(MifareDesfireFile* file = app->file_head; file; file = file->next) {
  130. mf_df_cat_file(file, out);
  131. }
  132. }
  133. void mf_df_cat_file(MifareDesfireFile* file, string_t out) {
  134. char* type = "unknown";
  135. switch(file->type) {
  136. case MifareDesfireFileTypeStandard:
  137. type = "standard";
  138. break;
  139. case MifareDesfireFileTypeBackup:
  140. type = "backup";
  141. break;
  142. case MifareDesfireFileTypeValue:
  143. type = "value";
  144. break;
  145. case MifareDesfireFileTypeLinearRecord:
  146. type = "linear";
  147. break;
  148. case MifareDesfireFileTypeCyclicRecord:
  149. type = "cyclic";
  150. break;
  151. }
  152. char* comm = "unknown";
  153. switch(file->comm) {
  154. case MifareDesfireFileCommunicationSettingsPlaintext:
  155. comm = "plain";
  156. break;
  157. case MifareDesfireFileCommunicationSettingsAuthenticated:
  158. comm = "auth";
  159. break;
  160. case MifareDesfireFileCommunicationSettingsEnciphered:
  161. comm = "enciphered";
  162. break;
  163. }
  164. string_cat_printf(out, "File %d\n", file->id);
  165. string_cat_printf(out, "%s %s\n", type, comm);
  166. string_cat_printf(
  167. out,
  168. "r %d w %d rw %d c %d\n",
  169. file->access_rights >> 12 & 0xF,
  170. file->access_rights >> 8 & 0xF,
  171. file->access_rights >> 4 & 0xF,
  172. file->access_rights & 0xF);
  173. uint16_t size = 0;
  174. uint16_t num = 1;
  175. switch(file->type) {
  176. case MifareDesfireFileTypeStandard:
  177. case MifareDesfireFileTypeBackup:
  178. size = file->settings.data.size;
  179. string_cat_printf(out, "size %d\n", size);
  180. break;
  181. case MifareDesfireFileTypeValue:
  182. size = 4;
  183. string_cat_printf(
  184. out, "lo %d hi %d\n", file->settings.value.lo_limit, file->settings.value.hi_limit);
  185. string_cat_printf(
  186. out,
  187. "limit %d enabled %d\n",
  188. file->settings.value.limited_credit_value,
  189. file->settings.value.limited_credit_enabled);
  190. break;
  191. case MifareDesfireFileTypeLinearRecord:
  192. case MifareDesfireFileTypeCyclicRecord:
  193. size = file->settings.record.size;
  194. num = file->settings.record.cur;
  195. string_cat_printf(out, "size %d\n", size);
  196. string_cat_printf(out, "num %d max %d\n", num, file->settings.record.max);
  197. break;
  198. }
  199. uint8_t* data = file->contents;
  200. if(data) {
  201. for(int rec = 0; rec < num; rec++) {
  202. for(int ch = 0; ch < size; ch++) {
  203. string_cat_printf(out, "%02x", data[rec * size + ch]);
  204. }
  205. string_cat_printf(out, " \n");
  206. }
  207. }
  208. }
  209. bool mf_df_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) {
  210. return ATQA0 == 0x44 && ATQA1 == 0x03 && SAK == 0x20;
  211. }
  212. uint16_t mf_df_prepare_get_version(uint8_t* dest) {
  213. dest[0] = MF_DF_GET_VERSION;
  214. return 1;
  215. }
  216. bool mf_df_parse_get_version_response(uint8_t* buf, uint16_t len, MifareDesfireVersion* out) {
  217. if(len < 1 || *buf) {
  218. return false;
  219. }
  220. len--;
  221. buf++;
  222. if(len < sizeof(MifareDesfireVersion)) {
  223. return false;
  224. }
  225. memcpy(out, buf, sizeof(MifareDesfireVersion));
  226. return true;
  227. }
  228. uint16_t mf_df_prepare_get_free_memory(uint8_t* dest) {
  229. dest[0] = MF_DF_GET_FREE_MEMORY;
  230. return 1;
  231. }
  232. bool mf_df_parse_get_free_memory_response(uint8_t* buf, uint16_t len, MifareDesfireFreeMemory* out) {
  233. if(len < 1 || *buf) {
  234. return false;
  235. }
  236. len--;
  237. buf++;
  238. if(len != 3) {
  239. return false;
  240. }
  241. out->bytes = buf[0] | (buf[1] << 8) | (buf[2] << 16);
  242. return true;
  243. }
  244. uint16_t mf_df_prepare_get_key_settings(uint8_t* dest) {
  245. dest[0] = MF_DF_GET_KEY_SETTINGS;
  246. return 1;
  247. }
  248. bool mf_df_parse_get_key_settings_response(
  249. uint8_t* buf,
  250. uint16_t len,
  251. MifareDesfireKeySettings* out) {
  252. if(len < 1 || *buf) {
  253. return false;
  254. }
  255. len--;
  256. buf++;
  257. if(len < 2) {
  258. return false;
  259. }
  260. out->change_key_id = buf[0] >> 4;
  261. out->config_changeable = (buf[0] & 0x8) != 0;
  262. out->free_create_delete = (buf[0] & 0x4) != 0;
  263. out->free_directory_list = (buf[0] & 0x2) != 0;
  264. out->master_key_changeable = (buf[0] & 0x1) != 0;
  265. out->flags = buf[1] >> 4;
  266. out->max_keys = buf[1] & 0xF;
  267. return true;
  268. }
  269. uint16_t mf_df_prepare_get_key_version(uint8_t* dest, uint8_t key_id) {
  270. dest[0] = MF_DF_GET_KEY_VERSION;
  271. dest[1] = key_id;
  272. return 2;
  273. }
  274. bool mf_df_parse_get_key_version_response(uint8_t* buf, uint16_t len, MifareDesfireKeyVersion* out) {
  275. if(len != 2 || *buf) {
  276. return false;
  277. }
  278. out->version = buf[1];
  279. return true;
  280. }
  281. uint16_t mf_df_prepare_get_application_ids(uint8_t* dest) {
  282. dest[0] = MF_DF_GET_APPLICATION_IDS;
  283. return 1;
  284. }
  285. bool mf_df_parse_get_application_ids_response(
  286. uint8_t* buf,
  287. uint16_t len,
  288. MifareDesfireApplication** app_head) {
  289. if(len < 1 || *buf) {
  290. return false;
  291. }
  292. len--;
  293. buf++;
  294. if(len % 3 != 0) {
  295. return false;
  296. }
  297. while(len) {
  298. MifareDesfireApplication* app = malloc(sizeof(MifareDesfireApplication));
  299. memset(app, 0, sizeof(MifareDesfireApplication));
  300. memcpy(app->id, buf, 3);
  301. len -= 3;
  302. buf += 3;
  303. *app_head = app;
  304. app_head = &app->next;
  305. }
  306. return true;
  307. }
  308. uint16_t mf_df_prepare_select_application(uint8_t* dest, uint8_t id[3]) {
  309. dest[0] = MF_DF_SELECT_APPLICATION;
  310. dest[1] = id[0];
  311. dest[2] = id[1];
  312. dest[3] = id[2];
  313. return 4;
  314. }
  315. bool mf_df_parse_select_application_response(uint8_t* buf, uint16_t len) {
  316. return len == 1 && !*buf;
  317. }
  318. uint16_t mf_df_prepare_get_file_ids(uint8_t* dest) {
  319. dest[0] = MF_DF_GET_FILE_IDS;
  320. return 1;
  321. }
  322. bool mf_df_parse_get_file_ids_response(uint8_t* buf, uint16_t len, MifareDesfireFile** file_head) {
  323. if(len < 1 || *buf) {
  324. return false;
  325. }
  326. len--;
  327. buf++;
  328. while(len) {
  329. MifareDesfireFile* file = malloc(sizeof(MifareDesfireFile));
  330. memset(file, 0, sizeof(MifareDesfireFile));
  331. file->id = *buf;
  332. len--;
  333. buf++;
  334. *file_head = file;
  335. file_head = &file->next;
  336. }
  337. return true;
  338. }
  339. uint16_t mf_df_prepare_get_file_settings(uint8_t* dest, uint8_t file_id) {
  340. dest[0] = MF_DF_GET_FILE_SETTINGS;
  341. dest[1] = file_id;
  342. return 2;
  343. }
  344. bool mf_df_parse_get_file_settings_response(uint8_t* buf, uint16_t len, MifareDesfireFile* out) {
  345. if(len < 5 || *buf) {
  346. return false;
  347. }
  348. len--;
  349. buf++;
  350. out->type = buf[0];
  351. out->comm = buf[1];
  352. out->access_rights = buf[2] | (buf[3] << 8);
  353. switch(out->type) {
  354. case MifareDesfireFileTypeStandard:
  355. case MifareDesfireFileTypeBackup:
  356. if(len != 7) {
  357. return false;
  358. }
  359. out->settings.data.size = buf[4] | (buf[5] << 8) | (buf[6] << 16);
  360. break;
  361. case MifareDesfireFileTypeValue:
  362. if(len != 17) {
  363. return false;
  364. }
  365. out->settings.value.lo_limit = buf[4] | (buf[5] << 8) | (buf[6] << 16) | (buf[7] << 24);
  366. out->settings.value.hi_limit = buf[8] | (buf[9] << 8) | (buf[10] << 16) | (buf[11] << 24);
  367. out->settings.value.limited_credit_value = buf[12] | (buf[13] << 8) | (buf[14] << 16) |
  368. (buf[15] << 24);
  369. out->settings.value.limited_credit_enabled = buf[16];
  370. break;
  371. case MifareDesfireFileTypeLinearRecord:
  372. case MifareDesfireFileTypeCyclicRecord:
  373. if(len != 13) {
  374. return false;
  375. }
  376. out->settings.record.size = buf[4] | (buf[5] << 8) | (buf[6] << 16);
  377. out->settings.record.max = buf[7] | (buf[8] << 8) | (buf[9] << 16);
  378. out->settings.record.cur = buf[10] | (buf[11] << 8) | (buf[12] << 16);
  379. break;
  380. default:
  381. return false;
  382. }
  383. return true;
  384. }
  385. uint16_t mf_df_prepare_read_data(uint8_t* dest, uint8_t file_id, uint32_t offset, uint32_t len) {
  386. dest[0] = MF_DF_READ_DATA;
  387. dest[1] = file_id;
  388. dest[2] = offset;
  389. dest[3] = offset >> 8;
  390. dest[4] = offset >> 16;
  391. dest[5] = len;
  392. dest[6] = len >> 8;
  393. dest[7] = len >> 16;
  394. return 8;
  395. }
  396. uint16_t mf_df_prepare_get_value(uint8_t* dest, uint8_t file_id) {
  397. dest[0] = MF_DF_GET_VALUE;
  398. dest[1] = file_id;
  399. return 2;
  400. }
  401. uint16_t
  402. mf_df_prepare_read_records(uint8_t* dest, uint8_t file_id, uint32_t offset, uint32_t len) {
  403. dest[0] = MF_DF_READ_RECORDS;
  404. dest[1] = file_id;
  405. dest[2] = offset;
  406. dest[3] = offset >> 8;
  407. dest[4] = offset >> 16;
  408. dest[5] = len;
  409. dest[6] = len >> 8;
  410. dest[7] = len >> 16;
  411. return 8;
  412. }
  413. bool mf_df_parse_read_data_response(uint8_t* buf, uint16_t len, MifareDesfireFile* out) {
  414. if(len < 1 || *buf) {
  415. return false;
  416. }
  417. len--;
  418. buf++;
  419. out->contents = malloc(len);
  420. memcpy(out->contents, buf, len);
  421. return true;
  422. }
  423. bool mf_df_read_card(FuriHalNfcTxRxContext* tx_rx, MifareDesfireData* data) {
  424. furi_assert(tx_rx);
  425. furi_assert(data);
  426. bool card_read = false;
  427. do {
  428. // Get version
  429. tx_rx->tx_bits = 8 * mf_df_prepare_get_version(tx_rx->tx_data);
  430. if(!furi_hal_nfc_tx_rx_full(tx_rx)) {
  431. FURI_LOG_W(TAG, "Bad exchange getting version");
  432. break;
  433. }
  434. if(!mf_df_parse_get_version_response(tx_rx->rx_data, tx_rx->rx_bits / 8, &data->version)) {
  435. FURI_LOG_W(TAG, "Bad DESFire GET_VERSION responce");
  436. }
  437. // Get free memory
  438. tx_rx->tx_bits = 8 * mf_df_prepare_get_free_memory(tx_rx->tx_data);
  439. if(furi_hal_nfc_tx_rx_full(tx_rx)) {
  440. data->free_memory = malloc(sizeof(MifareDesfireFreeMemory));
  441. if(!mf_df_parse_get_free_memory_response(
  442. tx_rx->rx_data, tx_rx->rx_bits / 8, data->free_memory)) {
  443. FURI_LOG_D(TAG, "Bad DESFire GET_FREE_MEMORY response (normal for pre-EV1 cards)");
  444. free(data->free_memory);
  445. data->free_memory = NULL;
  446. }
  447. }
  448. // Get key settings
  449. tx_rx->tx_bits = 8 * mf_df_prepare_get_key_settings(tx_rx->tx_data);
  450. if(!furi_hal_nfc_tx_rx_full(tx_rx)) {
  451. FURI_LOG_D(TAG, "Bad exchange getting key settings");
  452. } else {
  453. data->master_key_settings = malloc(sizeof(MifareDesfireKeySettings));
  454. if(!mf_df_parse_get_key_settings_response(
  455. tx_rx->rx_data, tx_rx->rx_bits / 8, data->master_key_settings)) {
  456. FURI_LOG_W(TAG, "Bad DESFire GET_KEY_SETTINGS response");
  457. free(data->master_key_settings);
  458. data->master_key_settings = NULL;
  459. } else {
  460. MifareDesfireKeyVersion** key_version_head =
  461. &data->master_key_settings->key_version_head;
  462. for(uint8_t key_id = 0; key_id < data->master_key_settings->max_keys; key_id++) {
  463. tx_rx->tx_bits = 8 * mf_df_prepare_get_key_version(tx_rx->tx_data, key_id);
  464. if(!furi_hal_nfc_tx_rx_full(tx_rx)) {
  465. FURI_LOG_W(TAG, "Bad exchange getting key version");
  466. continue;
  467. }
  468. MifareDesfireKeyVersion* key_version = malloc(sizeof(MifareDesfireKeyVersion));
  469. memset(key_version, 0, sizeof(MifareDesfireKeyVersion));
  470. key_version->id = key_id;
  471. if(!mf_df_parse_get_key_version_response(
  472. tx_rx->rx_data, tx_rx->rx_bits / 8, key_version)) {
  473. FURI_LOG_W(TAG, "Bad DESFire GET_KEY_VERSION response");
  474. free(key_version);
  475. continue;
  476. }
  477. *key_version_head = key_version;
  478. key_version_head = &key_version->next;
  479. }
  480. }
  481. }
  482. // Get application IDs
  483. tx_rx->tx_bits = 8 * mf_df_prepare_get_application_ids(tx_rx->tx_data);
  484. if(!furi_hal_nfc_tx_rx_full(tx_rx)) {
  485. FURI_LOG_W(TAG, "Bad exchange getting application IDs");
  486. break;
  487. } else {
  488. if(!mf_df_parse_get_application_ids_response(
  489. tx_rx->rx_data, tx_rx->rx_bits / 8, &data->app_head)) {
  490. FURI_LOG_W(TAG, "Bad DESFire GET_APPLICATION_IDS response");
  491. break;
  492. }
  493. }
  494. for(MifareDesfireApplication* app = data->app_head; app; app = app->next) {
  495. tx_rx->tx_bits = 8 * mf_df_prepare_select_application(tx_rx->tx_data, app->id);
  496. if(!furi_hal_nfc_tx_rx_full(tx_rx) ||
  497. !mf_df_parse_select_application_response(tx_rx->rx_data, tx_rx->rx_bits / 8)) {
  498. FURI_LOG_W(TAG, "Bad exchange selecting application");
  499. continue;
  500. }
  501. tx_rx->tx_bits = 8 * mf_df_prepare_get_key_settings(tx_rx->tx_data);
  502. if(!furi_hal_nfc_tx_rx_full(tx_rx)) {
  503. FURI_LOG_W(TAG, "Bad exchange getting key settings");
  504. } else {
  505. app->key_settings = malloc(sizeof(MifareDesfireKeySettings));
  506. memset(app->key_settings, 0, sizeof(MifareDesfireKeySettings));
  507. if(!mf_df_parse_get_key_settings_response(
  508. tx_rx->rx_data, tx_rx->rx_bits / 8, app->key_settings)) {
  509. FURI_LOG_W(TAG, "Bad DESFire GET_KEY_SETTINGS response");
  510. free(app->key_settings);
  511. app->key_settings = NULL;
  512. continue;
  513. }
  514. MifareDesfireKeyVersion** key_version_head = &app->key_settings->key_version_head;
  515. for(uint8_t key_id = 0; key_id < app->key_settings->max_keys; key_id++) {
  516. tx_rx->tx_bits = 8 * mf_df_prepare_get_key_version(tx_rx->tx_data, key_id);
  517. if(!furi_hal_nfc_tx_rx_full(tx_rx)) {
  518. FURI_LOG_W(TAG, "Bad exchange getting key version");
  519. continue;
  520. }
  521. MifareDesfireKeyVersion* key_version = malloc(sizeof(MifareDesfireKeyVersion));
  522. memset(key_version, 0, sizeof(MifareDesfireKeyVersion));
  523. key_version->id = key_id;
  524. if(!mf_df_parse_get_key_version_response(
  525. tx_rx->rx_data, tx_rx->rx_bits / 8, key_version)) {
  526. FURI_LOG_W(TAG, "Bad DESFire GET_KEY_VERSION response");
  527. free(key_version);
  528. continue;
  529. }
  530. *key_version_head = key_version;
  531. key_version_head = &key_version->next;
  532. }
  533. }
  534. tx_rx->tx_bits = 8 * mf_df_prepare_get_file_ids(tx_rx->tx_data);
  535. if(!furi_hal_nfc_tx_rx_full(tx_rx)) {
  536. FURI_LOG_W(TAG, "Bad exchange getting file IDs");
  537. } else {
  538. if(!mf_df_parse_get_file_ids_response(
  539. tx_rx->rx_data, tx_rx->rx_bits / 8, &app->file_head)) {
  540. FURI_LOG_W(TAG, "Bad DESFire GET_FILE_IDS response");
  541. }
  542. }
  543. for(MifareDesfireFile* file = app->file_head; file; file = file->next) {
  544. tx_rx->tx_bits = 8 * mf_df_prepare_get_file_settings(tx_rx->tx_data, file->id);
  545. if(!furi_hal_nfc_tx_rx_full(tx_rx)) {
  546. FURI_LOG_W(TAG, "Bad exchange getting file settings");
  547. continue;
  548. }
  549. if(!mf_df_parse_get_file_settings_response(
  550. tx_rx->rx_data, tx_rx->rx_bits / 8, file)) {
  551. FURI_LOG_W(TAG, "Bad DESFire GET_FILE_SETTINGS response");
  552. continue;
  553. }
  554. switch(file->type) {
  555. case MifareDesfireFileTypeStandard:
  556. case MifareDesfireFileTypeBackup:
  557. tx_rx->tx_bits = 8 * mf_df_prepare_read_data(tx_rx->tx_data, file->id, 0, 0);
  558. break;
  559. case MifareDesfireFileTypeValue:
  560. tx_rx->tx_bits = 8 * mf_df_prepare_get_value(tx_rx->tx_data, file->id);
  561. break;
  562. case MifareDesfireFileTypeLinearRecord:
  563. case MifareDesfireFileTypeCyclicRecord:
  564. tx_rx->tx_bits =
  565. 8 * mf_df_prepare_read_records(tx_rx->tx_data, file->id, 0, 0);
  566. break;
  567. }
  568. if(!furi_hal_nfc_tx_rx_full(tx_rx)) {
  569. FURI_LOG_W(TAG, "Bad exchange reading file %d", file->id);
  570. continue;
  571. }
  572. if(!mf_df_parse_read_data_response(tx_rx->rx_data, tx_rx->rx_bits / 8, file)) {
  573. FURI_LOG_W(TAG, "Bad response reading file %d", file->id);
  574. continue;
  575. }
  576. }
  577. }
  578. card_read = true;
  579. } while(false);
  580. return card_read;
  581. }