keys.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. #include "../metroflip_i.h"
  2. #include "keys.h"
  3. #include <bit_lib.h>
  4. #include <nfc/protocols/mf_classic/mf_classic.h>
  5. #include <nfc/protocols/mf_classic/mf_classic_poller.h>
  6. #include <nfc/nfc.h>
  7. #include <nfc/protocols/mf_classic/mf_classic_poller_sync.h>
  8. #include <string.h>
  9. #define TAG "keys_check"
  10. const MfClassicKeyPair troika_1k_key[] = {
  11. {.a = 0x08b386463229},
  12. };
  13. const MfClassicKeyPair troika_4k_key[] = {
  14. {.a = 0xA73F5DC1D333},
  15. };
  16. const MfClassicKeyPair smartrider_verify_key[] = {
  17. {.a = 0x2031D1E57A3B},
  18. };
  19. const MfClassicKeyPair charliecard_1k_verify_key[] = {
  20. {.a = 0x5EC39B022F2B},
  21. };
  22. const MfClassicKeyPair bip_1k_verify_key[] = {
  23. {.a = 0x3a42f33af429},
  24. };
  25. const MfClassicKeyPair metromoney_1k_verify_key[] = {
  26. {.a = 0x9C616585E26D},
  27. };
  28. const uint8_t gocard_verify_data[1][14] = {
  29. {0x16, 0x18, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x5A, 0x5B, 0x20, 0x21, 0x22, 0x23}};
  30. const uint8_t gocard_verify_data2[1][14] = {
  31. {0x16, 0x18, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x01, 0x01}};
  32. static bool charliecard_verify(Nfc* nfc, MfClassicData* mfc_data, bool data_loaded) {
  33. bool verified = false;
  34. FURI_LOG_I(TAG, "verifying charliecard..");
  35. const uint8_t verify_sector = 1;
  36. do {
  37. if(!data_loaded) {
  38. const uint8_t verify_block =
  39. mf_classic_get_first_block_num_of_sector(verify_sector) + 1;
  40. FURI_LOG_I(TAG, "Verifying sector %u", verify_sector);
  41. MfClassicKey key = {0};
  42. bit_lib_num_to_bytes_be(charliecard_1k_verify_key[0].a, COUNT_OF(key.data), key.data);
  43. MfClassicAuthContext auth_context;
  44. MfClassicError error = mf_classic_poller_sync_auth(
  45. nfc, verify_block, &key, MfClassicKeyTypeA, &auth_context);
  46. if(error != MfClassicErrorNone) {
  47. FURI_LOG_I(TAG, "Failed to read block %u: %d", verify_block, error);
  48. break;
  49. }
  50. verified = true;
  51. } else {
  52. MfClassicSectorTrailer* sec_tr =
  53. mf_classic_get_sector_trailer_by_sector(mfc_data, verify_sector);
  54. FURI_LOG_I(TAG, "%2x", sec_tr->key_a.data[1]);
  55. uint64_t key = bit_lib_bytes_to_num_be(sec_tr->key_a.data, 6);
  56. if(key != charliecard_1k_verify_key[0].a) {
  57. FURI_LOG_I(TAG, "not equall");
  58. break;
  59. }
  60. verified = true;
  61. }
  62. } while(false);
  63. return verified;
  64. }
  65. bool bip_verify(Nfc* nfc, MfClassicData* mfc_data, bool data_loaded) {
  66. bool verified = false;
  67. do {
  68. if(!data_loaded) {
  69. const uint8_t verify_sector = 0;
  70. uint8_t block_num = mf_classic_get_first_block_num_of_sector(verify_sector);
  71. FURI_LOG_I(TAG, "Verifying sector %u", verify_sector);
  72. MfClassicKey key = {};
  73. bit_lib_num_to_bytes_be(bip_1k_verify_key[0].a, COUNT_OF(key.data), key.data);
  74. MfClassicAuthContext auth_ctx = {};
  75. MfClassicError error =
  76. mf_classic_poller_sync_auth(nfc, block_num, &key, MfClassicKeyTypeA, &auth_ctx);
  77. if(error != MfClassicErrorNone) {
  78. FURI_LOG_I(TAG, "Failed to read block %u: %d", block_num, error);
  79. break;
  80. }
  81. verified = true;
  82. } else {
  83. MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(mfc_data, 0);
  84. uint64_t key = bit_lib_bytes_to_num_be(sec_tr->key_a.data, 6);
  85. if(key != bip_1k_verify_key[0].a) {
  86. break;
  87. }
  88. verified = true;
  89. }
  90. } while(false);
  91. return verified;
  92. }
  93. static bool metromoney_verify(Nfc* nfc, MfClassicData* mfc_data, bool data_loaded) {
  94. bool verified = false;
  95. const uint8_t ticket_sector_number = 1;
  96. do {
  97. if(!data_loaded) {
  98. const uint8_t ticket_block_number =
  99. mf_classic_get_first_block_num_of_sector(ticket_sector_number) + 1;
  100. FURI_LOG_D(TAG, "Verifying sector %u", ticket_sector_number);
  101. MfClassicKey key = {0};
  102. bit_lib_num_to_bytes_be(metromoney_1k_verify_key[0].a, COUNT_OF(key.data), key.data);
  103. MfClassicAuthContext auth_context;
  104. MfClassicError error = mf_classic_poller_sync_auth(
  105. nfc, ticket_block_number, &key, MfClassicKeyTypeA, &auth_context);
  106. if(error != MfClassicErrorNone) {
  107. FURI_LOG_D(TAG, "Failed to read block %u: %d", ticket_block_number, error);
  108. break;
  109. }
  110. verified = true;
  111. } else {
  112. MfClassicSectorTrailer* sec_tr =
  113. mf_classic_get_sector_trailer_by_sector(mfc_data, ticket_sector_number);
  114. uint64_t key = bit_lib_bytes_to_num_be(sec_tr->key_a.data, 6);
  115. if(key != metromoney_1k_verify_key[0].a) {
  116. break;
  117. }
  118. verified = true;
  119. }
  120. } while(false);
  121. return verified;
  122. }
  123. static bool smartrider_verify(Nfc* nfc, MfClassicData* mfc_data, bool data_loaded) {
  124. bool verified = false;
  125. do {
  126. if(!data_loaded) {
  127. const uint8_t block_number = mf_classic_get_first_block_num_of_sector(0) + 1;
  128. FURI_LOG_D(TAG, "Verifying sector 0");
  129. MfClassicKey key = {0};
  130. bit_lib_num_to_bytes_be(smartrider_verify_key[0].a, COUNT_OF(key.data), key.data);
  131. MfClassicAuthContext auth_context;
  132. MfClassicError error = mf_classic_poller_sync_auth(
  133. nfc, block_number, &key, MfClassicKeyTypeA, &auth_context);
  134. if(error != MfClassicErrorNone) {
  135. FURI_LOG_D(TAG, "Failed to read block %u: %d", block_number, error);
  136. break;
  137. }
  138. verified = true;
  139. } else {
  140. MfClassicSectorTrailer* sec_tr = mf_classic_get_sector_trailer_by_sector(mfc_data, 0);
  141. uint64_t key = bit_lib_bytes_to_num_be(sec_tr->key_a.data, 6);
  142. if(key != smartrider_verify_key[0].a) {
  143. break;
  144. }
  145. verified = true;
  146. }
  147. } while(false);
  148. return verified;
  149. }
  150. static bool troika_get_card_config(TroikaCardConfig* config, MfClassicType type) {
  151. bool success = true;
  152. if(type == MfClassicType1k) {
  153. config->data_sector = 11;
  154. config->keys = troika_1k_key;
  155. } else if(type == MfClassicType4k) {
  156. config->data_sector = 8; // Further testing needed
  157. config->keys = troika_4k_key;
  158. } else {
  159. success = false;
  160. }
  161. return success;
  162. }
  163. static bool
  164. troika_verify_type(Nfc* nfc, MfClassicData* mfc_data, bool data_loaded, MfClassicType type) {
  165. bool verified = false;
  166. do {
  167. if(!data_loaded) {
  168. TroikaCardConfig cfg = {};
  169. if(!troika_get_card_config(&cfg, type)) break;
  170. const uint8_t block_num = mf_classic_get_first_block_num_of_sector(cfg.data_sector);
  171. FURI_LOG_D(TAG, "Verifying sector %lu", cfg.data_sector);
  172. MfClassicKey key = {0};
  173. bit_lib_num_to_bytes_be(cfg.keys[0].a, COUNT_OF(key.data), key.data);
  174. MfClassicAuthContext auth_context;
  175. MfClassicError error = mf_classic_poller_sync_auth(
  176. nfc, block_num, &key, MfClassicKeyTypeA, &auth_context);
  177. if(error != MfClassicErrorNone) {
  178. FURI_LOG_D(TAG, "Failed to read block %u: %d", block_num, error);
  179. break;
  180. }
  181. FURI_LOG_D(TAG, "Verify success!");
  182. verified = true;
  183. } else {
  184. TroikaCardConfig cfg = {};
  185. if(!troika_get_card_config(&cfg, type)) break;
  186. MfClassicSectorTrailer* sec_tr =
  187. mf_classic_get_sector_trailer_by_sector(mfc_data, cfg.data_sector);
  188. uint64_t key = bit_lib_bytes_to_num_be(sec_tr->key_a.data, 6);
  189. if(key != cfg.keys[0].a) {
  190. break;
  191. }
  192. verified = true;
  193. }
  194. } while(false);
  195. return verified;
  196. }
  197. static bool troika_verify(Nfc* nfc, MfClassicData* mfc_data, bool data_loaded) {
  198. return troika_verify_type(nfc, mfc_data, data_loaded, MfClassicType1k) ||
  199. troika_verify_type(nfc, mfc_data, data_loaded, MfClassicType4k);
  200. }
  201. static bool gocard_verify(MfClassicData* mfc_data, bool data_loaded) {
  202. bool verified = false;
  203. FURI_LOG_I(TAG, "verifying charliecard..");
  204. do {
  205. if(data_loaded) {
  206. uint8_t* buffer = &mfc_data->block[1].data[1];
  207. size_t buffer_size = 14;
  208. if(memcmp(buffer, gocard_verify_data[0], buffer_size) == 0) {
  209. FURI_LOG_I(TAG, "Match!");
  210. } else {
  211. FURI_LOG_I(TAG, "No match.");
  212. if(memcmp(buffer, gocard_verify_data2[0], buffer_size) == 0) {
  213. FURI_LOG_I(TAG, "Match!");
  214. } else {
  215. FURI_LOG_I(TAG, "No match.");
  216. break;
  217. }
  218. }
  219. verified = true;
  220. }
  221. } while(false);
  222. return verified;
  223. }
  224. CardType determine_card_type(Nfc* nfc, MfClassicData* mfc_data, bool data_loaded) {
  225. FURI_LOG_I(TAG, "checking keys..");
  226. UNUSED(bip_verify);
  227. if(bip_verify(nfc, mfc_data, data_loaded)) {
  228. return CARD_TYPE_BIP;
  229. } else if(metromoney_verify(nfc, mfc_data, data_loaded)) {
  230. return CARD_TYPE_METROMONEY;
  231. } else if(smartrider_verify(nfc, mfc_data, data_loaded)) {
  232. return CARD_TYPE_SMARTRIDER;
  233. } else if(troika_verify(nfc, mfc_data, data_loaded)) {
  234. return CARD_TYPE_TROIKA;
  235. } else if(charliecard_verify(nfc, mfc_data, data_loaded)) {
  236. return CARD_TYPE_CHARLIECARD;
  237. } else if(gocard_verify(mfc_data, data_loaded)) {
  238. return CARD_TYPE_GOCARD;
  239. } else {
  240. FURI_LOG_I(TAG, "its unknown");
  241. return CARD_TYPE_UNKNOWN;
  242. }
  243. }