troyka_parser.c 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #include "nfc_supported_card.h"
  2. #include <gui/modules/widget.h>
  3. #include <nfc_worker_i.h>
  4. static const MfClassicAuthContext troyka_keys[] = {
  5. {.sector = 0, .key_a = 0xa0a1a2a3a4a5, .key_b = 0xfbf225dc5d58},
  6. {.sector = 1, .key_a = 0xa82607b01c0d, .key_b = 0x2910989b6880},
  7. {.sector = 2, .key_a = 0x2aa05ed1856f, .key_b = 0xeaac88e5dc99},
  8. {.sector = 3, .key_a = 0x2aa05ed1856f, .key_b = 0xeaac88e5dc99},
  9. {.sector = 4, .key_a = 0x73068f118c13, .key_b = 0x2b7f3253fac5},
  10. {.sector = 5, .key_a = 0xfbc2793d540b, .key_b = 0xd3a297dc2698},
  11. {.sector = 6, .key_a = 0x2aa05ed1856f, .key_b = 0xeaac88e5dc99},
  12. {.sector = 7, .key_a = 0xae3d65a3dad4, .key_b = 0x0f1c63013dba},
  13. {.sector = 8, .key_a = 0xa73f5dc1d333, .key_b = 0xe35173494a81},
  14. {.sector = 9, .key_a = 0x69a32f1c2f19, .key_b = 0x6b8bd9860763},
  15. {.sector = 10, .key_a = 0x9becdf3d9273, .key_b = 0xf8493407799d},
  16. {.sector = 11, .key_a = 0x08b386463229, .key_b = 0x5efbaecef46b},
  17. {.sector = 12, .key_a = 0xcd4c61c26e3d, .key_b = 0x31c7610de3b0},
  18. {.sector = 13, .key_a = 0xa82607b01c0d, .key_b = 0x2910989b6880},
  19. {.sector = 14, .key_a = 0x0e8f64340ba4, .key_b = 0x4acec1205d75},
  20. {.sector = 15, .key_a = 0x2aa05ed1856f, .key_b = 0xeaac88e5dc99},
  21. };
  22. bool troyka_parser_verify(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) {
  23. furi_assert(nfc_worker);
  24. UNUSED(nfc_worker);
  25. MfClassicAuthContext auth_ctx = {
  26. .key_a = MF_CLASSIC_NO_KEY,
  27. .key_b = MF_CLASSIC_NO_KEY,
  28. .sector = 8,
  29. };
  30. return mf_classic_auth_attempt(tx_rx, &auth_ctx, 0xa73f5dc1d333);
  31. }
  32. bool troyka_parser_read(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) {
  33. furi_assert(nfc_worker);
  34. MfClassicReader reader = {};
  35. FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data;
  36. reader.type = mf_classic_get_classic_type(nfc_data->atqa[0], nfc_data->atqa[1], nfc_data->sak);
  37. for(size_t i = 0; i < COUNT_OF(troyka_keys); i++) {
  38. mf_classic_reader_add_sector(
  39. &reader, troyka_keys[i].sector, troyka_keys[i].key_a, troyka_keys[i].key_b);
  40. }
  41. return mf_classic_read_card(tx_rx, &reader, &nfc_worker->dev_data->mf_classic_data) == 16;
  42. }
  43. bool troyka_parser_parse(NfcDeviceData* dev_data) {
  44. MfClassicData* data = &dev_data->mf_classic_data;
  45. bool troyka_parsed = false;
  46. do {
  47. // Verify key
  48. MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(data, 8);
  49. uint64_t key = nfc_util_bytes2num(sec_tr->key_a, 6);
  50. if(key != troyka_keys[8].key_a) break;
  51. // Parse data
  52. uint8_t* temp_ptr = &data->block[8 * 4 + 1].value[5];
  53. uint16_t balance = ((temp_ptr[0] << 8) | temp_ptr[1]) / 25;
  54. temp_ptr = &data->block[8 * 4].value[3];
  55. uint32_t number = 0;
  56. for(size_t i = 0; i < 4; i++) {
  57. number <<= 8;
  58. number |= temp_ptr[i];
  59. }
  60. number >>= 4;
  61. string_printf(
  62. dev_data->parsed_data, "\e#Troyka\nNum: %ld\nBalance: %d rur.", number, balance);
  63. troyka_parsed = true;
  64. } while(false);
  65. return troyka_parsed;
  66. }