mifare_classic.c 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128
  1. #include "mifare_classic.h"
  2. #include "nfca.h"
  3. #include "nfc_util.h"
  4. #include <furi_hal_rtc.h>
  5. // Algorithm from https://github.com/RfidResearchGroup/proxmark3.git
  6. #define TAG "MfClassic"
  7. #define MF_CLASSIC_AUTH_KEY_A_CMD (0x60U)
  8. #define MF_CLASSIC_AUTH_KEY_B_CMD (0x61U)
  9. #define MF_CLASSIC_READ_BLOCK_CMD (0x30)
  10. #define MF_CLASSIC_WRITE_BLOCK_CMD (0xA0)
  11. const char* mf_classic_get_type_str(MfClassicType type) {
  12. if(type == MfClassicType1k) {
  13. return "MIFARE Classic 1K";
  14. } else if(type == MfClassicType4k) {
  15. return "MIFARE Classic 4K";
  16. } else {
  17. return "Unknown";
  18. }
  19. }
  20. static uint8_t mf_classic_get_first_block_num_of_sector(uint8_t sector) {
  21. furi_assert(sector < 40);
  22. if(sector < 32) {
  23. return sector * 4;
  24. } else {
  25. return 32 * 4 + (sector - 32) * 16;
  26. }
  27. }
  28. uint8_t mf_classic_get_sector_trailer_block_num_by_sector(uint8_t sector) {
  29. furi_assert(sector < 40);
  30. if(sector < 32) {
  31. return sector * 4 + 3;
  32. } else {
  33. return 32 * 4 + (sector - 32) * 16 + 15;
  34. }
  35. }
  36. uint8_t mf_classic_get_sector_by_block(uint8_t block) {
  37. if(block < 128) {
  38. return (block | 0x03) / 4;
  39. } else {
  40. return 32 + ((block | 0xf) - 32 * 4) / 16;
  41. }
  42. }
  43. static uint8_t mf_classic_get_blocks_num_in_sector(uint8_t sector) {
  44. furi_assert(sector < 40);
  45. return sector < 32 ? 4 : 16;
  46. }
  47. uint8_t mf_classic_get_sector_trailer_num_by_block(uint8_t block) {
  48. if(block < 128) {
  49. return block | 0x03;
  50. } else {
  51. return block | 0x0f;
  52. }
  53. }
  54. bool mf_classic_is_sector_trailer(uint8_t block) {
  55. return block == mf_classic_get_sector_trailer_num_by_block(block);
  56. }
  57. MfClassicSectorTrailer*
  58. mf_classic_get_sector_trailer_by_sector(MfClassicData* data, uint8_t sector) {
  59. furi_assert(data);
  60. uint8_t sec_tr_block_num = mf_classic_get_sector_trailer_block_num_by_sector(sector);
  61. return (MfClassicSectorTrailer*)data->block[sec_tr_block_num].value;
  62. }
  63. uint8_t mf_classic_get_total_sectors_num(MfClassicType type) {
  64. if(type == MfClassicType1k) {
  65. return MF_CLASSIC_1K_TOTAL_SECTORS_NUM;
  66. } else if(type == MfClassicType4k) {
  67. return MF_CLASSIC_4K_TOTAL_SECTORS_NUM;
  68. } else {
  69. return 0;
  70. }
  71. }
  72. uint16_t mf_classic_get_total_block_num(MfClassicType type) {
  73. if(type == MfClassicType1k) {
  74. return 64;
  75. } else if(type == MfClassicType4k) {
  76. return 256;
  77. } else {
  78. return 0;
  79. }
  80. }
  81. bool mf_classic_is_block_read(MfClassicData* data, uint8_t block_num) {
  82. furi_assert(data);
  83. return (FURI_BIT(data->block_read_mask[block_num / 32], block_num % 32) == 1);
  84. }
  85. void mf_classic_set_block_read(MfClassicData* data, uint8_t block_num, MfClassicBlock* block_data) {
  86. furi_assert(data);
  87. if(mf_classic_is_sector_trailer(block_num)) {
  88. memcpy(&data->block[block_num].value[6], &block_data->value[6], 4);
  89. } else {
  90. memcpy(data->block[block_num].value, block_data->value, MF_CLASSIC_BLOCK_SIZE);
  91. }
  92. FURI_BIT_SET(data->block_read_mask[block_num / 32], block_num % 32);
  93. }
  94. bool mf_classic_is_sector_data_read(MfClassicData* data, uint8_t sector_num) {
  95. furi_assert(data);
  96. uint8_t first_block = mf_classic_get_first_block_num_of_sector(sector_num);
  97. uint8_t total_blocks = mf_classic_get_blocks_num_in_sector(sector_num);
  98. bool data_read = true;
  99. for(size_t i = first_block; i < first_block + total_blocks; i++) {
  100. data_read &= mf_classic_is_block_read(data, i);
  101. }
  102. return data_read;
  103. }
  104. void mf_classic_set_sector_data_not_read(MfClassicData* data) {
  105. furi_assert(data);
  106. memset(data->block_read_mask, 0, sizeof(data->block_read_mask));
  107. }
  108. bool mf_classic_is_key_found(MfClassicData* data, uint8_t sector_num, MfClassicKey key_type) {
  109. furi_assert(data);
  110. bool key_found = false;
  111. if(key_type == MfClassicKeyA) {
  112. key_found = (FURI_BIT(data->key_a_mask, sector_num) == 1);
  113. } else if(key_type == MfClassicKeyB) {
  114. key_found = (FURI_BIT(data->key_b_mask, sector_num) == 1);
  115. }
  116. return key_found;
  117. }
  118. void mf_classic_set_key_found(
  119. MfClassicData* data,
  120. uint8_t sector_num,
  121. MfClassicKey key_type,
  122. uint64_t key) {
  123. furi_assert(data);
  124. uint8_t key_arr[6] = {};
  125. MfClassicSectorTrailer* sec_trailer =
  126. mf_classic_get_sector_trailer_by_sector(data, sector_num);
  127. nfc_util_num2bytes(key, 6, key_arr);
  128. if(key_type == MfClassicKeyA) {
  129. memcpy(sec_trailer->key_a, key_arr, sizeof(sec_trailer->key_a));
  130. FURI_BIT_SET(data->key_a_mask, sector_num);
  131. } else if(key_type == MfClassicKeyB) {
  132. memcpy(sec_trailer->key_b, key_arr, sizeof(sec_trailer->key_b));
  133. FURI_BIT_SET(data->key_b_mask, sector_num);
  134. }
  135. }
  136. void mf_classic_set_key_not_found(MfClassicData* data, uint8_t sector_num, MfClassicKey key_type) {
  137. furi_assert(data);
  138. if(key_type == MfClassicKeyA) {
  139. FURI_BIT_CLEAR(data->key_a_mask, sector_num);
  140. } else if(key_type == MfClassicKeyB) {
  141. FURI_BIT_CLEAR(data->key_b_mask, sector_num);
  142. }
  143. }
  144. bool mf_classic_is_sector_read(MfClassicData* data, uint8_t sector_num) {
  145. furi_assert(data);
  146. bool sector_read = false;
  147. do {
  148. if(!mf_classic_is_key_found(data, sector_num, MfClassicKeyA)) break;
  149. if(!mf_classic_is_key_found(data, sector_num, MfClassicKeyB)) break;
  150. uint8_t start_block = mf_classic_get_first_block_num_of_sector(sector_num);
  151. uint8_t total_blocks = mf_classic_get_blocks_num_in_sector(sector_num);
  152. uint8_t block_read = true;
  153. for(size_t i = start_block; i < start_block + total_blocks; i++) {
  154. block_read = mf_classic_is_block_read(data, i);
  155. if(!block_read) break;
  156. }
  157. sector_read = block_read;
  158. } while(false);
  159. return sector_read;
  160. }
  161. void mf_classic_get_read_sectors_and_keys(
  162. MfClassicData* data,
  163. uint8_t* sectors_read,
  164. uint8_t* keys_found) {
  165. furi_assert(data);
  166. furi_assert(sectors_read);
  167. furi_assert(keys_found);
  168. *sectors_read = 0;
  169. *keys_found = 0;
  170. uint8_t sectors_total = mf_classic_get_total_sectors_num(data->type);
  171. for(size_t i = 0; i < sectors_total; i++) {
  172. if(mf_classic_is_key_found(data, i, MfClassicKeyA)) {
  173. *keys_found += 1;
  174. }
  175. if(mf_classic_is_key_found(data, i, MfClassicKeyB)) {
  176. *keys_found += 1;
  177. }
  178. uint8_t first_block = mf_classic_get_first_block_num_of_sector(i);
  179. uint8_t total_blocks_in_sec = mf_classic_get_blocks_num_in_sector(i);
  180. bool blocks_read = true;
  181. for(size_t i = first_block; i < first_block + total_blocks_in_sec; i++) {
  182. blocks_read = mf_classic_is_block_read(data, i);
  183. if(!blocks_read) break;
  184. }
  185. if(blocks_read) {
  186. *sectors_read += 1;
  187. }
  188. }
  189. }
  190. bool mf_classic_is_card_read(MfClassicData* data) {
  191. furi_assert(data);
  192. uint8_t sectors_total = mf_classic_get_total_sectors_num(data->type);
  193. uint8_t sectors_read = 0;
  194. uint8_t keys_found = 0;
  195. mf_classic_get_read_sectors_and_keys(data, &sectors_read, &keys_found);
  196. bool card_read = (sectors_read == sectors_total) && (keys_found == sectors_total * 2);
  197. return card_read;
  198. }
  199. bool mf_classic_is_allowed_access_sector_trailer(
  200. MfClassicData* data,
  201. uint8_t block_num,
  202. MfClassicKey key,
  203. MfClassicAction action) {
  204. uint8_t* sector_trailer = data->block[block_num].value;
  205. uint8_t AC = ((sector_trailer[7] >> 5) & 0x04) | ((sector_trailer[8] >> 2) & 0x02) |
  206. ((sector_trailer[8] >> 7) & 0x01);
  207. switch(action) {
  208. case MfClassicActionKeyARead: {
  209. return false;
  210. }
  211. case MfClassicActionKeyAWrite:
  212. case MfClassicActionKeyBWrite: {
  213. return (
  214. (key == MfClassicKeyA && (AC == 0x00 || AC == 0x01)) ||
  215. (key == MfClassicKeyB && (AC == 0x04 || AC == 0x03)));
  216. }
  217. case MfClassicActionKeyBRead: {
  218. return (key == MfClassicKeyA && (AC == 0x00 || AC == 0x02 || AC == 0x01));
  219. }
  220. case MfClassicActionACRead: {
  221. return (
  222. (key == MfClassicKeyA) ||
  223. (key == MfClassicKeyB && !(AC == 0x00 || AC == 0x02 || AC == 0x01)));
  224. }
  225. case MfClassicActionACWrite: {
  226. return (
  227. (key == MfClassicKeyA && (AC == 0x01)) ||
  228. (key == MfClassicKeyB && (AC == 0x03 || AC == 0x05)));
  229. }
  230. default:
  231. return false;
  232. }
  233. return true;
  234. }
  235. bool mf_classic_is_allowed_access_data_block(
  236. MfClassicData* data,
  237. uint8_t block_num,
  238. MfClassicKey key,
  239. MfClassicAction action) {
  240. uint8_t* sector_trailer =
  241. data->block[mf_classic_get_sector_trailer_num_by_block(block_num)].value;
  242. uint8_t sector_block;
  243. if(block_num <= 128) {
  244. sector_block = block_num & 0x03;
  245. } else {
  246. sector_block = (block_num & 0x0f) / 5;
  247. }
  248. uint8_t AC;
  249. switch(sector_block) {
  250. case 0x00: {
  251. AC = ((sector_trailer[7] >> 2) & 0x04) | ((sector_trailer[8] << 1) & 0x02) |
  252. ((sector_trailer[8] >> 4) & 0x01);
  253. break;
  254. }
  255. case 0x01: {
  256. AC = ((sector_trailer[7] >> 3) & 0x04) | ((sector_trailer[8] >> 0) & 0x02) |
  257. ((sector_trailer[8] >> 5) & 0x01);
  258. break;
  259. }
  260. case 0x02: {
  261. AC = ((sector_trailer[7] >> 4) & 0x04) | ((sector_trailer[8] >> 1) & 0x02) |
  262. ((sector_trailer[8] >> 6) & 0x01);
  263. break;
  264. }
  265. default:
  266. return false;
  267. }
  268. switch(action) {
  269. case MfClassicActionDataRead: {
  270. return (
  271. (key == MfClassicKeyA && !(AC == 0x03 || AC == 0x05 || AC == 0x07)) ||
  272. (key == MfClassicKeyB && !(AC == 0x07)));
  273. }
  274. case MfClassicActionDataWrite: {
  275. return (
  276. (key == MfClassicKeyA && (AC == 0x00)) ||
  277. (key == MfClassicKeyB && (AC == 0x00 || AC == 0x04 || AC == 0x06 || AC == 0x03)));
  278. }
  279. case MfClassicActionDataInc: {
  280. return (
  281. (key == MfClassicKeyA && (AC == 0x00)) ||
  282. (key == MfClassicKeyB && (AC == 0x00 || AC == 0x06)));
  283. }
  284. case MfClassicActionDataDec: {
  285. return (
  286. (key == MfClassicKeyA && (AC == 0x00 || AC == 0x06 || AC == 0x01)) ||
  287. (key == MfClassicKeyB && (AC == 0x00 || AC == 0x06 || AC == 0x01)));
  288. }
  289. default:
  290. return false;
  291. }
  292. return false;
  293. }
  294. static bool mf_classic_is_allowed_access(
  295. MfClassicEmulator* emulator,
  296. uint8_t block_num,
  297. MfClassicKey key,
  298. MfClassicAction action) {
  299. if(mf_classic_is_sector_trailer(block_num)) {
  300. return mf_classic_is_allowed_access_sector_trailer(
  301. &emulator->data, block_num, key, action);
  302. } else {
  303. return mf_classic_is_allowed_access_data_block(&emulator->data, block_num, key, action);
  304. }
  305. }
  306. bool mf_classic_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK) {
  307. UNUSED(ATQA1);
  308. if((ATQA0 == 0x44 || ATQA0 == 0x04) && (SAK == 0x08 || SAK == 0x88 || SAK == 0x09)) {
  309. return true;
  310. } else if((ATQA0 == 0x01) && (ATQA1 == 0x0F) && (SAK == 0x01)) {
  311. //skylanders support
  312. return true;
  313. } else if((ATQA0 == 0x42 || ATQA0 == 0x02) && (SAK == 0x18)) {
  314. return true;
  315. } else {
  316. return false;
  317. }
  318. }
  319. MfClassicType mf_classic_get_classic_type(int8_t ATQA0, uint8_t ATQA1, uint8_t SAK) {
  320. UNUSED(ATQA1);
  321. if((ATQA0 == 0x44 || ATQA0 == 0x04) && (SAK == 0x08 || SAK == 0x88 || SAK == 0x09)) {
  322. return MfClassicType1k;
  323. } else if((ATQA0 == 0x01) && (ATQA1 == 0x0F) && (SAK == 0x01)) {
  324. //skylanders support
  325. return MfClassicType1k;
  326. } else if((ATQA0 == 0x42 || ATQA0 == 0x02) && (SAK == 0x18)) {
  327. return MfClassicType4k;
  328. }
  329. return MfClassicType1k;
  330. }
  331. void mf_classic_reader_add_sector(
  332. MfClassicReader* reader,
  333. uint8_t sector,
  334. uint64_t key_a,
  335. uint64_t key_b) {
  336. furi_assert(reader);
  337. furi_assert(sector < MF_CLASSIC_SECTORS_MAX);
  338. furi_assert((key_a != MF_CLASSIC_NO_KEY) || (key_b != MF_CLASSIC_NO_KEY));
  339. if(reader->sectors_to_read < MF_CLASSIC_SECTORS_MAX) {
  340. reader->sector_reader[reader->sectors_to_read].key_a = key_a;
  341. reader->sector_reader[reader->sectors_to_read].key_b = key_b;
  342. reader->sector_reader[reader->sectors_to_read].sector_num = sector;
  343. reader->sectors_to_read++;
  344. }
  345. }
  346. void mf_classic_auth_init_context(MfClassicAuthContext* auth_ctx, uint8_t sector) {
  347. furi_assert(auth_ctx);
  348. auth_ctx->sector = sector;
  349. auth_ctx->key_a = MF_CLASSIC_NO_KEY;
  350. auth_ctx->key_b = MF_CLASSIC_NO_KEY;
  351. }
  352. static bool mf_classic_auth(
  353. FuriHalNfcTxRxContext* tx_rx,
  354. uint32_t block,
  355. uint64_t key,
  356. MfClassicKey key_type,
  357. Crypto1* crypto,
  358. bool skip_activate,
  359. uint32_t cuid) {
  360. bool auth_success = false;
  361. memset(tx_rx->tx_data, 0, sizeof(tx_rx->tx_data));
  362. memset(tx_rx->tx_parity, 0, sizeof(tx_rx->tx_parity));
  363. tx_rx->tx_rx_type = FuriHalNfcTxRxTypeDefault;
  364. do {
  365. if(!skip_activate && !furi_hal_nfc_activate_nfca(200, &cuid)) break;
  366. if(key_type == MfClassicKeyA) {
  367. tx_rx->tx_data[0] = MF_CLASSIC_AUTH_KEY_A_CMD;
  368. } else {
  369. tx_rx->tx_data[0] = MF_CLASSIC_AUTH_KEY_B_CMD;
  370. }
  371. tx_rx->tx_data[1] = block;
  372. tx_rx->tx_rx_type = FuriHalNfcTxRxTypeRxNoCrc;
  373. tx_rx->tx_bits = 2 * 8;
  374. if(!furi_hal_nfc_tx_rx(tx_rx, 6)) break;
  375. uint32_t nt = (uint32_t)nfc_util_bytes2num(tx_rx->rx_data, 4);
  376. crypto1_init(crypto, key);
  377. crypto1_word(crypto, nt ^ cuid, 0);
  378. uint8_t nr[4] = {};
  379. nfc_util_num2bytes(prng_successor(DWT->CYCCNT, 32), 4, nr);
  380. for(uint8_t i = 0; i < 4; i++) {
  381. tx_rx->tx_data[i] = crypto1_byte(crypto, nr[i], 0) ^ nr[i];
  382. tx_rx->tx_parity[0] |=
  383. (((crypto1_filter(crypto->odd) ^ nfc_util_odd_parity8(nr[i])) & 0x01) << (7 - i));
  384. }
  385. nt = prng_successor(nt, 32);
  386. for(uint8_t i = 4; i < 8; i++) {
  387. nt = prng_successor(nt, 8);
  388. tx_rx->tx_data[i] = crypto1_byte(crypto, 0x00, 0) ^ (nt & 0xff);
  389. tx_rx->tx_parity[0] |=
  390. (((crypto1_filter(crypto->odd) ^ nfc_util_odd_parity8(nt & 0xff)) & 0x01)
  391. << (7 - i));
  392. }
  393. tx_rx->tx_rx_type = FuriHalNfcTxRxTypeRaw;
  394. tx_rx->tx_bits = 8 * 8;
  395. if(!furi_hal_nfc_tx_rx(tx_rx, 6)) break;
  396. if(tx_rx->rx_bits == 32) {
  397. crypto1_word(crypto, 0, 0);
  398. auth_success = true;
  399. }
  400. } while(false);
  401. return auth_success;
  402. }
  403. bool mf_classic_authenticate(
  404. FuriHalNfcTxRxContext* tx_rx,
  405. uint8_t block_num,
  406. uint64_t key,
  407. MfClassicKey key_type) {
  408. furi_assert(tx_rx);
  409. Crypto1 crypto = {};
  410. bool key_found = mf_classic_auth(tx_rx, block_num, key, key_type, &crypto, false, 0);
  411. furi_hal_nfc_sleep();
  412. return key_found;
  413. }
  414. bool mf_classic_authenticate_skip_activate(
  415. FuriHalNfcTxRxContext* tx_rx,
  416. uint8_t block_num,
  417. uint64_t key,
  418. MfClassicKey key_type,
  419. bool skip_activate,
  420. uint32_t cuid) {
  421. furi_assert(tx_rx);
  422. Crypto1 crypto = {};
  423. bool key_found =
  424. mf_classic_auth(tx_rx, block_num, key, key_type, &crypto, skip_activate, cuid);
  425. furi_hal_nfc_sleep();
  426. return key_found;
  427. }
  428. bool mf_classic_auth_attempt(
  429. FuriHalNfcTxRxContext* tx_rx,
  430. MfClassicAuthContext* auth_ctx,
  431. uint64_t key) {
  432. furi_assert(tx_rx);
  433. furi_assert(auth_ctx);
  434. bool found_key = false;
  435. bool need_halt = (auth_ctx->key_a == MF_CLASSIC_NO_KEY) &&
  436. (auth_ctx->key_b == MF_CLASSIC_NO_KEY);
  437. Crypto1 crypto;
  438. if(auth_ctx->key_a == MF_CLASSIC_NO_KEY) {
  439. // Try AUTH with key A
  440. if(mf_classic_auth(
  441. tx_rx,
  442. mf_classic_get_first_block_num_of_sector(auth_ctx->sector),
  443. key,
  444. MfClassicKeyA,
  445. &crypto,
  446. false,
  447. 0)) {
  448. auth_ctx->key_a = key;
  449. found_key = true;
  450. }
  451. }
  452. if(need_halt) {
  453. furi_hal_nfc_sleep();
  454. }
  455. if(auth_ctx->key_b == MF_CLASSIC_NO_KEY) {
  456. // Try AUTH with key B
  457. if(mf_classic_auth(
  458. tx_rx,
  459. mf_classic_get_first_block_num_of_sector(auth_ctx->sector),
  460. key,
  461. MfClassicKeyB,
  462. &crypto,
  463. false,
  464. 0)) {
  465. auth_ctx->key_b = key;
  466. found_key = true;
  467. }
  468. }
  469. return found_key;
  470. }
  471. bool mf_classic_read_block(
  472. FuriHalNfcTxRxContext* tx_rx,
  473. Crypto1* crypto,
  474. uint8_t block_num,
  475. MfClassicBlock* block) {
  476. furi_assert(tx_rx);
  477. furi_assert(crypto);
  478. furi_assert(block);
  479. bool read_block_success = false;
  480. uint8_t plain_cmd[4] = {MF_CLASSIC_READ_BLOCK_CMD, block_num, 0x00, 0x00};
  481. nfca_append_crc16(plain_cmd, 2);
  482. crypto1_encrypt(crypto, NULL, plain_cmd, 4 * 8, tx_rx->tx_data, tx_rx->tx_parity);
  483. tx_rx->tx_bits = 4 * 9;
  484. tx_rx->tx_rx_type = FuriHalNfcTxRxTypeRaw;
  485. if(furi_hal_nfc_tx_rx(tx_rx, 50)) {
  486. if(tx_rx->rx_bits == 8 * (MF_CLASSIC_BLOCK_SIZE + 2)) {
  487. uint8_t block_received[MF_CLASSIC_BLOCK_SIZE + 2];
  488. crypto1_decrypt(crypto, tx_rx->rx_data, tx_rx->rx_bits, block_received);
  489. uint16_t crc_calc = nfca_get_crc16(block_received, MF_CLASSIC_BLOCK_SIZE);
  490. uint16_t crc_received = (block_received[MF_CLASSIC_BLOCK_SIZE + 1] << 8) |
  491. block_received[MF_CLASSIC_BLOCK_SIZE];
  492. if(crc_received != crc_calc) {
  493. FURI_LOG_E(
  494. TAG,
  495. "Incorrect CRC while reading block %d. Expected %04X, Received %04X",
  496. block_num,
  497. crc_received,
  498. crc_calc);
  499. } else {
  500. memcpy(block->value, block_received, MF_CLASSIC_BLOCK_SIZE);
  501. read_block_success = true;
  502. }
  503. }
  504. }
  505. return read_block_success;
  506. }
  507. void mf_classic_read_sector(FuriHalNfcTxRxContext* tx_rx, MfClassicData* data, uint8_t sec_num) {
  508. furi_assert(tx_rx);
  509. furi_assert(data);
  510. furi_hal_nfc_sleep();
  511. bool key_a_found = mf_classic_is_key_found(data, sec_num, MfClassicKeyA);
  512. bool key_b_found = mf_classic_is_key_found(data, sec_num, MfClassicKeyB);
  513. uint8_t start_block = mf_classic_get_first_block_num_of_sector(sec_num);
  514. uint8_t total_blocks = mf_classic_get_blocks_num_in_sector(sec_num);
  515. MfClassicBlock block_tmp = {};
  516. uint64_t key = 0;
  517. MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, sec_num);
  518. Crypto1 crypto = {};
  519. uint8_t blocks_read = 0;
  520. do {
  521. if(!key_a_found) break;
  522. FURI_LOG_D(TAG, "Try to read blocks with key A");
  523. key = nfc_util_bytes2num(sec_tr->key_a, sizeof(sec_tr->key_a));
  524. if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyA, &crypto, false, 0)) break;
  525. for(size_t i = start_block; i < start_block + total_blocks; i++) {
  526. if(!mf_classic_is_block_read(data, i)) {
  527. if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
  528. mf_classic_set_block_read(data, i, &block_tmp);
  529. blocks_read++;
  530. } else if(i > start_block) {
  531. // Try to re-auth to read block in case prevous block was protected from read
  532. furi_hal_nfc_sleep();
  533. if(!mf_classic_auth(tx_rx, i, key, MfClassicKeyA, &crypto, false, 0)) break;
  534. if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
  535. mf_classic_set_block_read(data, i, &block_tmp);
  536. blocks_read++;
  537. }
  538. }
  539. } else {
  540. blocks_read++;
  541. }
  542. }
  543. FURI_LOG_D(TAG, "Read %d blocks out of %d", blocks_read, total_blocks);
  544. } while(false);
  545. do {
  546. if(blocks_read == total_blocks) break;
  547. if(!key_b_found) break;
  548. FURI_LOG_D(TAG, "Try to read blocks with key B");
  549. key = nfc_util_bytes2num(sec_tr->key_b, sizeof(sec_tr->key_b));
  550. if(!mf_classic_auth(tx_rx, start_block, key, MfClassicKeyB, &crypto, false, 0)) break;
  551. for(size_t i = start_block; i < start_block + total_blocks; i++) {
  552. if(!mf_classic_is_block_read(data, i)) {
  553. if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
  554. mf_classic_set_block_read(data, i, &block_tmp);
  555. blocks_read++;
  556. } else if(i > start_block) {
  557. // Try to re-auth to read block in case prevous block was protected from read
  558. furi_hal_nfc_sleep();
  559. if(!mf_classic_auth(tx_rx, i, key, MfClassicKeyB, &crypto, false, 0)) break;
  560. if(mf_classic_read_block(tx_rx, &crypto, i, &block_tmp)) {
  561. mf_classic_set_block_read(data, i, &block_tmp);
  562. blocks_read++;
  563. }
  564. }
  565. } else {
  566. blocks_read++;
  567. }
  568. }
  569. FURI_LOG_D(TAG, "Read %d blocks out of %d", blocks_read, total_blocks);
  570. } while(false);
  571. }
  572. static bool mf_classic_read_sector_with_reader(
  573. FuriHalNfcTxRxContext* tx_rx,
  574. Crypto1* crypto,
  575. MfClassicSectorReader* sector_reader,
  576. MfClassicSector* sector) {
  577. furi_assert(tx_rx);
  578. furi_assert(sector_reader);
  579. furi_assert(sector);
  580. uint64_t key;
  581. MfClassicKey key_type;
  582. uint8_t first_block;
  583. bool sector_read = false;
  584. furi_hal_nfc_sleep();
  585. do {
  586. // Activate card
  587. first_block = mf_classic_get_first_block_num_of_sector(sector_reader->sector_num);
  588. if(sector_reader->key_a != MF_CLASSIC_NO_KEY) {
  589. key = sector_reader->key_a;
  590. key_type = MfClassicKeyA;
  591. } else if(sector_reader->key_b != MF_CLASSIC_NO_KEY) {
  592. key = sector_reader->key_b;
  593. key_type = MfClassicKeyB;
  594. } else {
  595. break;
  596. }
  597. // Auth to first block in sector
  598. if(!mf_classic_auth(tx_rx, first_block, key, key_type, crypto, false, 0)) {
  599. // Set key to MF_CLASSIC_NO_KEY to prevent further attempts
  600. if(key_type == MfClassicKeyA) {
  601. sector_reader->key_a = MF_CLASSIC_NO_KEY;
  602. } else {
  603. sector_reader->key_b = MF_CLASSIC_NO_KEY;
  604. }
  605. break;
  606. }
  607. sector->total_blocks = mf_classic_get_blocks_num_in_sector(sector_reader->sector_num);
  608. // Read blocks
  609. for(uint8_t i = 0; i < sector->total_blocks; i++) {
  610. if(mf_classic_read_block(tx_rx, crypto, first_block + i, &sector->block[i])) continue;
  611. if(i == 0) continue;
  612. // Try to auth to read next block in case previous is locked
  613. furi_hal_nfc_sleep();
  614. if(!mf_classic_auth(tx_rx, first_block + i, key, key_type, crypto, false, 0)) continue;
  615. mf_classic_read_block(tx_rx, crypto, first_block + i, &sector->block[i]);
  616. }
  617. // Save sector keys in last block
  618. if(sector_reader->key_a != MF_CLASSIC_NO_KEY) {
  619. nfc_util_num2bytes(
  620. sector_reader->key_a, 6, &sector->block[sector->total_blocks - 1].value[0]);
  621. }
  622. if(sector_reader->key_b != MF_CLASSIC_NO_KEY) {
  623. nfc_util_num2bytes(
  624. sector_reader->key_b, 6, &sector->block[sector->total_blocks - 1].value[10]);
  625. }
  626. sector_read = true;
  627. } while(false);
  628. return sector_read;
  629. }
  630. uint8_t mf_classic_read_card(
  631. FuriHalNfcTxRxContext* tx_rx,
  632. MfClassicReader* reader,
  633. MfClassicData* data) {
  634. furi_assert(tx_rx);
  635. furi_assert(reader);
  636. furi_assert(data);
  637. uint8_t sectors_read = 0;
  638. data->type = reader->type;
  639. data->key_a_mask = 0;
  640. data->key_b_mask = 0;
  641. MfClassicSector temp_sector = {};
  642. for(uint8_t i = 0; i < reader->sectors_to_read; i++) {
  643. if(mf_classic_read_sector_with_reader(
  644. tx_rx, &reader->crypto, &reader->sector_reader[i], &temp_sector)) {
  645. uint8_t first_block =
  646. mf_classic_get_first_block_num_of_sector(reader->sector_reader[i].sector_num);
  647. for(uint8_t j = 0; j < temp_sector.total_blocks; j++) {
  648. mf_classic_set_block_read(data, first_block + j, &temp_sector.block[j]);
  649. }
  650. if(reader->sector_reader[i].key_a != MF_CLASSIC_NO_KEY) {
  651. mf_classic_set_key_found(
  652. data,
  653. reader->sector_reader[i].sector_num,
  654. MfClassicKeyA,
  655. reader->sector_reader[i].key_a);
  656. }
  657. if(reader->sector_reader[i].key_b != MF_CLASSIC_NO_KEY) {
  658. mf_classic_set_key_found(
  659. data,
  660. reader->sector_reader[i].sector_num,
  661. MfClassicKeyB,
  662. reader->sector_reader[i].key_b);
  663. }
  664. sectors_read++;
  665. }
  666. }
  667. return sectors_read;
  668. }
  669. uint8_t mf_classic_update_card(FuriHalNfcTxRxContext* tx_rx, MfClassicData* data) {
  670. furi_assert(tx_rx);
  671. furi_assert(data);
  672. uint8_t total_sectors = mf_classic_get_total_sectors_num(data->type);
  673. for(size_t i = 0; i < total_sectors; i++) {
  674. mf_classic_read_sector(tx_rx, data, i);
  675. }
  676. uint8_t sectors_read = 0;
  677. uint8_t keys_found = 0;
  678. mf_classic_get_read_sectors_and_keys(data, &sectors_read, &keys_found);
  679. FURI_LOG_D(TAG, "Read %d sectors and %d keys", sectors_read, keys_found);
  680. return sectors_read;
  681. }
  682. bool mf_classic_emulator(MfClassicEmulator* emulator, FuriHalNfcTxRxContext* tx_rx) {
  683. furi_assert(emulator);
  684. furi_assert(tx_rx);
  685. bool command_processed = false;
  686. bool is_encrypted = false;
  687. uint8_t plain_data[MF_CLASSIC_MAX_DATA_SIZE];
  688. MfClassicKey access_key = MfClassicKeyA;
  689. // Read command
  690. while(!command_processed) { //-V654
  691. if(!is_encrypted) {
  692. crypto1_reset(&emulator->crypto);
  693. memcpy(plain_data, tx_rx->rx_data, tx_rx->rx_bits / 8);
  694. } else {
  695. if(!furi_hal_nfc_tx_rx(tx_rx, 300)) {
  696. FURI_LOG_D(
  697. TAG,
  698. "Error in tx rx. Tx :%d bits, Rx: %d bits",
  699. tx_rx->tx_bits,
  700. tx_rx->rx_bits);
  701. break;
  702. }
  703. crypto1_decrypt(&emulator->crypto, tx_rx->rx_data, tx_rx->rx_bits, plain_data);
  704. }
  705. if(plain_data[0] == 0x50 && plain_data[1] == 0x00) {
  706. FURI_LOG_T(TAG, "Halt received");
  707. furi_hal_nfc_listen_sleep();
  708. command_processed = true;
  709. break;
  710. } else if(plain_data[0] == 0x60 || plain_data[0] == 0x61) {
  711. uint8_t block = plain_data[1];
  712. uint64_t key = 0;
  713. uint8_t sector_trailer_block = mf_classic_get_sector_trailer_num_by_block(block);
  714. MfClassicSectorTrailer* sector_trailer =
  715. (MfClassicSectorTrailer*)emulator->data.block[sector_trailer_block].value;
  716. if(plain_data[0] == 0x60) {
  717. key = nfc_util_bytes2num(sector_trailer->key_a, 6);
  718. access_key = MfClassicKeyA;
  719. } else {
  720. key = nfc_util_bytes2num(sector_trailer->key_b, 6);
  721. access_key = MfClassicKeyB;
  722. }
  723. uint32_t nonce = prng_successor(DWT->CYCCNT, 32) ^ 0xAA;
  724. uint8_t nt[4];
  725. uint8_t nt_keystream[4];
  726. nfc_util_num2bytes(nonce, 4, nt);
  727. nfc_util_num2bytes(nonce ^ emulator->cuid, 4, nt_keystream);
  728. crypto1_init(&emulator->crypto, key);
  729. if(!is_encrypted) {
  730. crypto1_word(&emulator->crypto, emulator->cuid ^ nonce, 0);
  731. memcpy(tx_rx->tx_data, nt, sizeof(nt));
  732. tx_rx->tx_parity[0] = 0;
  733. for(size_t i = 0; i < sizeof(nt); i++) {
  734. tx_rx->tx_parity[0] |= nfc_util_odd_parity8(nt[i]) << (7 - i);
  735. }
  736. tx_rx->tx_bits = sizeof(nt) * 8;
  737. tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent;
  738. } else {
  739. crypto1_encrypt(
  740. &emulator->crypto,
  741. nt_keystream,
  742. nt,
  743. sizeof(nt) * 8,
  744. tx_rx->tx_data,
  745. tx_rx->tx_parity);
  746. tx_rx->tx_bits = sizeof(nt) * 8;
  747. tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent;
  748. }
  749. if(!furi_hal_nfc_tx_rx(tx_rx, 500)) {
  750. FURI_LOG_E(TAG, "Error in NT exchange");
  751. command_processed = true;
  752. break;
  753. }
  754. if(tx_rx->rx_bits != 64) {
  755. FURI_LOG_W(TAG, "Incorrect nr + ar");
  756. command_processed = true;
  757. break;
  758. }
  759. uint32_t nr = nfc_util_bytes2num(tx_rx->rx_data, 4);
  760. uint32_t ar = nfc_util_bytes2num(&tx_rx->rx_data[4], 4);
  761. FURI_LOG_D(
  762. TAG,
  763. "%08lx key%c block %d nt/nr/ar: %08lx %08lx %08lx",
  764. emulator->cuid,
  765. access_key == MfClassicKeyA ? 'A' : 'B',
  766. sector_trailer_block,
  767. nonce,
  768. nr,
  769. ar);
  770. crypto1_word(&emulator->crypto, nr, 1);
  771. uint32_t cardRr = ar ^ crypto1_word(&emulator->crypto, 0, 0);
  772. if(cardRr != prng_successor(nonce, 64)) {
  773. FURI_LOG_T(TAG, "Wrong AUTH! %08lX != %08lX", cardRr, prng_successor(nonce, 64));
  774. // Don't send NACK, as the tag doesn't send it
  775. command_processed = true;
  776. break;
  777. }
  778. uint32_t ans = prng_successor(nonce, 96);
  779. uint8_t responce[4] = {};
  780. nfc_util_num2bytes(ans, 4, responce);
  781. crypto1_encrypt(
  782. &emulator->crypto,
  783. NULL,
  784. responce,
  785. sizeof(responce) * 8,
  786. tx_rx->tx_data,
  787. tx_rx->tx_parity);
  788. tx_rx->tx_bits = sizeof(responce) * 8;
  789. tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent;
  790. is_encrypted = true;
  791. } else if(is_encrypted && plain_data[0] == 0x30) {
  792. uint8_t block = plain_data[1];
  793. uint8_t block_data[18] = {};
  794. memcpy(block_data, emulator->data.block[block].value, MF_CLASSIC_BLOCK_SIZE);
  795. if(mf_classic_is_sector_trailer(block)) {
  796. if(!mf_classic_is_allowed_access(
  797. emulator, block, access_key, MfClassicActionKeyARead)) {
  798. memset(block_data, 0, 6); //-V1086
  799. }
  800. if(!mf_classic_is_allowed_access(
  801. emulator, block, access_key, MfClassicActionKeyBRead)) {
  802. memset(&block_data[10], 0, 6);
  803. }
  804. if(!mf_classic_is_allowed_access(
  805. emulator, block, access_key, MfClassicActionACRead)) {
  806. memset(&block_data[6], 0, 4);
  807. }
  808. } else if(!mf_classic_is_allowed_access(
  809. emulator, block, access_key, MfClassicActionDataRead)) {
  810. // Send NACK
  811. uint8_t nack = 0x04;
  812. crypto1_encrypt(
  813. &emulator->crypto, NULL, &nack, 4, tx_rx->tx_data, tx_rx->tx_parity);
  814. tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent;
  815. tx_rx->tx_bits = 4;
  816. furi_hal_nfc_tx_rx(tx_rx, 300);
  817. break;
  818. }
  819. nfca_append_crc16(block_data, 16);
  820. crypto1_encrypt(
  821. &emulator->crypto,
  822. NULL,
  823. block_data,
  824. sizeof(block_data) * 8,
  825. tx_rx->tx_data,
  826. tx_rx->tx_parity);
  827. tx_rx->tx_bits = 18 * 8;
  828. tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent;
  829. } else if(is_encrypted && plain_data[0] == 0xA0) {
  830. uint8_t block = plain_data[1];
  831. if(block > mf_classic_get_total_block_num(emulator->data.type)) {
  832. break;
  833. }
  834. // Send ACK
  835. uint8_t ack = 0x0A;
  836. crypto1_encrypt(&emulator->crypto, NULL, &ack, 4, tx_rx->tx_data, tx_rx->tx_parity);
  837. tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent;
  838. tx_rx->tx_bits = 4;
  839. if(!furi_hal_nfc_tx_rx(tx_rx, 300)) break;
  840. if(tx_rx->rx_bits != 18 * 8) break;
  841. crypto1_decrypt(&emulator->crypto, tx_rx->rx_data, tx_rx->rx_bits, plain_data);
  842. uint8_t block_data[16] = {};
  843. memcpy(block_data, emulator->data.block[block].value, MF_CLASSIC_BLOCK_SIZE);
  844. if(mf_classic_is_sector_trailer(block)) {
  845. if(mf_classic_is_allowed_access(
  846. emulator, block, access_key, MfClassicActionKeyAWrite)) {
  847. memcpy(block_data, plain_data, 6); //-V1086
  848. }
  849. if(mf_classic_is_allowed_access(
  850. emulator, block, access_key, MfClassicActionKeyBWrite)) {
  851. memcpy(&block_data[10], &plain_data[10], 6);
  852. }
  853. if(mf_classic_is_allowed_access(
  854. emulator, block, access_key, MfClassicActionACWrite)) {
  855. memcpy(&block_data[6], &plain_data[6], 4);
  856. }
  857. } else {
  858. if(mf_classic_is_allowed_access(
  859. emulator, block, access_key, MfClassicActionDataWrite)) {
  860. memcpy(block_data, plain_data, MF_CLASSIC_BLOCK_SIZE);
  861. }
  862. }
  863. if(memcmp(block_data, emulator->data.block[block].value, MF_CLASSIC_BLOCK_SIZE) != 0) {
  864. memcpy(emulator->data.block[block].value, block_data, MF_CLASSIC_BLOCK_SIZE);
  865. emulator->data_changed = true;
  866. }
  867. // Send ACK
  868. ack = 0x0A;
  869. crypto1_encrypt(&emulator->crypto, NULL, &ack, 4, tx_rx->tx_data, tx_rx->tx_parity);
  870. tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent;
  871. tx_rx->tx_bits = 4;
  872. } else {
  873. // Unknown command
  874. break;
  875. }
  876. }
  877. if(!command_processed) {
  878. // Send NACK
  879. uint8_t nack = 0x04;
  880. if(is_encrypted) {
  881. crypto1_encrypt(&emulator->crypto, NULL, &nack, 4, tx_rx->tx_data, tx_rx->tx_parity);
  882. } else {
  883. tx_rx->tx_data[0] = nack;
  884. }
  885. tx_rx->tx_rx_type = FuriHalNfcTxRxTransparent;
  886. tx_rx->tx_bits = 4;
  887. furi_hal_nfc_tx_rx(tx_rx, 300);
  888. }
  889. return true;
  890. }
  891. bool mf_classic_write_block(
  892. FuriHalNfcTxRxContext* tx_rx,
  893. MfClassicBlock* src_block,
  894. uint8_t block_num,
  895. MfClassicKey key_type,
  896. uint64_t key) {
  897. furi_assert(tx_rx);
  898. furi_assert(src_block);
  899. Crypto1 crypto = {};
  900. uint8_t plain_data[18] = {};
  901. uint8_t resp = 0;
  902. bool write_success = false;
  903. do {
  904. furi_hal_nfc_sleep();
  905. if(!mf_classic_auth(tx_rx, block_num, key, key_type, &crypto, false, 0)) {
  906. FURI_LOG_D(TAG, "Auth fail");
  907. break;
  908. }
  909. // Send write command
  910. plain_data[0] = MF_CLASSIC_WRITE_BLOCK_CMD;
  911. plain_data[1] = block_num;
  912. nfca_append_crc16(plain_data, 2);
  913. crypto1_encrypt(&crypto, NULL, plain_data, 4 * 8, tx_rx->tx_data, tx_rx->tx_parity);
  914. tx_rx->tx_bits = 4 * 8;
  915. tx_rx->tx_rx_type = FuriHalNfcTxRxTypeRaw;
  916. if(furi_hal_nfc_tx_rx(tx_rx, 50)) {
  917. if(tx_rx->rx_bits == 4) {
  918. crypto1_decrypt(&crypto, tx_rx->rx_data, 4, &resp);
  919. if(resp != 0x0A) {
  920. FURI_LOG_D(TAG, "NACK received on write cmd: %02X", resp);
  921. break;
  922. }
  923. } else {
  924. FURI_LOG_D(TAG, "Not ACK received");
  925. break;
  926. }
  927. } else {
  928. FURI_LOG_D(TAG, "Failed to send write cmd");
  929. break;
  930. }
  931. // Send data
  932. memcpy(plain_data, src_block->value, MF_CLASSIC_BLOCK_SIZE);
  933. nfca_append_crc16(plain_data, MF_CLASSIC_BLOCK_SIZE);
  934. crypto1_encrypt(
  935. &crypto,
  936. NULL,
  937. plain_data,
  938. (MF_CLASSIC_BLOCK_SIZE + 2) * 8,
  939. tx_rx->tx_data,
  940. tx_rx->tx_parity);
  941. tx_rx->tx_bits = (MF_CLASSIC_BLOCK_SIZE + 2) * 8;
  942. tx_rx->tx_rx_type = FuriHalNfcTxRxTypeRaw;
  943. if(furi_hal_nfc_tx_rx(tx_rx, 50)) {
  944. if(tx_rx->rx_bits == 4) {
  945. crypto1_decrypt(&crypto, tx_rx->rx_data, 4, &resp);
  946. if(resp != 0x0A) {
  947. FURI_LOG_D(TAG, "NACK received on sending data");
  948. break;
  949. }
  950. } else {
  951. FURI_LOG_D(TAG, "Not ACK received");
  952. break;
  953. }
  954. } else {
  955. FURI_LOG_D(TAG, "Failed to send data");
  956. break;
  957. }
  958. write_success = true;
  959. // Send Halt
  960. plain_data[0] = 0x50;
  961. plain_data[1] = 0x00;
  962. nfca_append_crc16(plain_data, 2);
  963. crypto1_encrypt(&crypto, NULL, plain_data, 2 * 8, tx_rx->tx_data, tx_rx->tx_parity);
  964. tx_rx->tx_bits = 2 * 8;
  965. tx_rx->tx_rx_type = FuriHalNfcTxRxTypeRaw;
  966. // No response is expected
  967. furi_hal_nfc_tx_rx(tx_rx, 50);
  968. } while(false);
  969. return write_success;
  970. }
  971. bool mf_classic_write_sector(
  972. FuriHalNfcTxRxContext* tx_rx,
  973. MfClassicData* dest_data,
  974. MfClassicData* src_data,
  975. uint8_t sec_num) {
  976. furi_assert(tx_rx);
  977. furi_assert(dest_data);
  978. furi_assert(src_data);
  979. uint8_t first_block = mf_classic_get_first_block_num_of_sector(sec_num);
  980. uint8_t total_blocks = mf_classic_get_blocks_num_in_sector(sec_num);
  981. MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(dest_data, sec_num);
  982. bool key_a_found = mf_classic_is_key_found(dest_data, sec_num, MfClassicKeyA);
  983. bool key_b_found = mf_classic_is_key_found(dest_data, sec_num, MfClassicKeyB);
  984. bool write_success = true;
  985. for(size_t i = first_block; i < first_block + total_blocks; i++) {
  986. // Compare blocks
  987. if(memcmp(dest_data->block[i].value, src_data->block[i].value, MF_CLASSIC_BLOCK_SIZE) !=
  988. 0) {
  989. bool key_a_write_allowed = mf_classic_is_allowed_access_data_block(
  990. dest_data, i, MfClassicKeyA, MfClassicActionDataWrite);
  991. bool key_b_write_allowed = mf_classic_is_allowed_access_data_block(
  992. dest_data, i, MfClassicKeyB, MfClassicActionDataWrite);
  993. if(key_a_found && key_a_write_allowed) {
  994. FURI_LOG_I(TAG, "Writing block %d with key A", i);
  995. uint64_t key = nfc_util_bytes2num(sec_tr->key_a, 6);
  996. if(!mf_classic_write_block(tx_rx, &src_data->block[i], i, MfClassicKeyA, key)) {
  997. FURI_LOG_E(TAG, "Failed to write block %d", i);
  998. write_success = false;
  999. break;
  1000. }
  1001. } else if(key_b_found && key_b_write_allowed) {
  1002. FURI_LOG_I(TAG, "Writing block %d with key A", i);
  1003. uint64_t key = nfc_util_bytes2num(sec_tr->key_b, 6);
  1004. if(!mf_classic_write_block(tx_rx, &src_data->block[i], i, MfClassicKeyB, key)) {
  1005. FURI_LOG_E(TAG, "Failed to write block %d", i);
  1006. write_success = false;
  1007. break;
  1008. }
  1009. } else {
  1010. FURI_LOG_E(TAG, "Failed to find key with write access");
  1011. write_success = false;
  1012. break;
  1013. }
  1014. } else {
  1015. FURI_LOG_D(TAG, "Blocks %d are equal", i);
  1016. }
  1017. }
  1018. return write_success;
  1019. }