tag.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. /**
  2. * Copyright (C) 2011 Anders Sundman <anders@4zm.org>
  3. *
  4. * This file is part of mfterm.
  5. *
  6. * mfterm is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * mfterm is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with mfterm. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include "mifare.h"
  23. #include "util.h"
  24. #include "tag.h"
  25. mf_tag_t current_tag;
  26. mf_tag_t current_auth;
  27. void strip_non_auth_data(mf_tag_t* tag);
  28. int load_mfd(const char* fn, mf_tag_t* tag);
  29. int save_mfd(const char* fn, const mf_tag_t* tag);
  30. int load_mfd(const char* fn, mf_tag_t* tag) {
  31. FILE* mfd_file = fopen(fn, "rb");
  32. if (mfd_file == NULL) {
  33. printf("Could not open file: %s\n", fn);
  34. return 1;
  35. }
  36. if (fread(tag, 1, sizeof(mf_tag_t), mfd_file) != sizeof(mf_tag_t)) {
  37. printf("Could not read file: %s\n", fn);
  38. fclose(mfd_file);
  39. return 1;
  40. }
  41. fclose(mfd_file);
  42. return 0;
  43. }
  44. int save_mfd(const char* fn, const mf_tag_t* tag) {
  45. FILE* mfd_file = fopen(fn, "w");
  46. if (mfd_file == NULL) {
  47. printf("Could not open file for writing: %s\n", fn);
  48. return 1;
  49. }
  50. if (fwrite(tag, 1, sizeof(mf_tag_t), mfd_file) != sizeof(mf_tag_t)) {
  51. printf("Could not write file: %s\n", fn);
  52. fclose(mfd_file);
  53. return 1;
  54. }
  55. fclose(mfd_file);
  56. return 0;
  57. }
  58. int load_tag(const char* fn) {
  59. return load_mfd(fn, &current_tag);
  60. }
  61. int save_tag(const char* fn) {
  62. return save_mfd(fn, &current_tag);
  63. }
  64. int load_auth(const char* fn) {
  65. if (load_mfd(fn, &current_auth))
  66. return 1;
  67. strip_non_auth_data(&current_auth);
  68. return 0;
  69. }
  70. int save_auth(const char* fn) {
  71. return save_mfd(fn, &current_auth);
  72. }
  73. int import_auth() {
  74. memcpy(&current_auth, &current_tag, sizeof(mf_tag_t));
  75. strip_non_auth_data(&current_auth);
  76. return 0;
  77. }
  78. void print_tag(mf_size_t size) {
  79. if (size == MF_1K)
  80. print_tag_block_range(0, MF_1K / sizeof(mf_block_t) - 1);
  81. else if (size == MF_4K)
  82. print_tag_block_range(0, MF_4K / sizeof(mf_block_t) - 1);
  83. else {
  84. printf("Unsupported tag size.\n");
  85. }
  86. return;
  87. }
  88. void print_tag_byte_bits(size_t byte, size_t first_bit, size_t last_bit) {
  89. // The byte to show parts of
  90. uint8_t data = current_tag.amb[byte / 16].mbd.abtData[byte % 16];
  91. printf("[");
  92. for (size_t i = 0; i < 8; ++i) {
  93. // Separate nibbles
  94. if (i == 4)
  95. printf(" ");
  96. // Outside mask
  97. if (i < first_bit || i > last_bit) {
  98. printf("-");
  99. continue;
  100. }
  101. // Inside mask
  102. if (1<<i && data)
  103. printf("1");
  104. else
  105. printf("0");
  106. }
  107. printf("]");
  108. }
  109. void print_tag_bytes(size_t first_byte, size_t last_byte) {
  110. // Write the data one block at a time
  111. while (first_byte <= last_byte) {
  112. size_t byte_len = last_byte - first_byte;
  113. // Fill up start with spaces
  114. size_t block_offset = first_byte % 16;
  115. for (size_t i = 0; i < block_offset; ++i)
  116. printf("-- ");
  117. // Print the data
  118. uint8_t* block_data = current_tag.amb[first_byte / 16].mbd.abtData;
  119. size_t block_last = block_offset + byte_len;
  120. if (block_last > 15)
  121. block_last = 15;
  122. print_hex_array_sep(block_data + block_offset,
  123. block_last - block_offset + 1, " ");
  124. // Fill up end with spaces
  125. for (size_t i = block_last; i < 15; ++i)
  126. printf("-- ");
  127. // Finish of with a nl
  128. printf("\n");
  129. first_byte += block_last - block_offset + 1;
  130. }
  131. }
  132. void print_tag_data_range(size_t byte_offset, size_t bit_offset,
  133. size_t byte_len, size_t bit_len) {
  134. printf("Offset: [%zu, %zu] Length: [%zu, %zu]\n",
  135. byte_offset, bit_offset, byte_len, bit_len);
  136. // Print partial first byte
  137. if (bit_offset) {
  138. size_t total_bits = byte_len * 8 + bit_len;
  139. size_t last_bit = bit_offset + total_bits - 1;
  140. if (last_bit > 7)
  141. last_bit = 7;
  142. print_tag_byte_bits(byte_offset, bit_offset, last_bit);
  143. printf("\n");
  144. total_bits -= last_bit - bit_offset + 1;
  145. // Update data to be printed
  146. byte_offset++;
  147. bit_offset = 0;
  148. byte_len = total_bits / 8;
  149. bit_len = total_bits % 8;
  150. }
  151. // Print bytes
  152. if (byte_len) {
  153. print_tag_bytes(byte_offset, byte_offset + byte_len - 1);
  154. // Update data to be printed
  155. byte_offset += byte_len;
  156. byte_len = 0;
  157. }
  158. // Print trailing bits
  159. if (bit_len) {
  160. print_tag_byte_bits(byte_offset, 0, bit_len);
  161. printf("\n");
  162. }
  163. }
  164. void print_tag_block_range(size_t first, size_t last) {
  165. // Print header
  166. printf("xS xB 00 07 08 0f\n");
  167. printf("-------------------------------------------------------\n");
  168. // Iterate over all blocks
  169. for (size_t block = first; block <= last; ++block) {
  170. // Sector number
  171. printf("%02zx ",
  172. block < 0x10*4 ? block / 4 : 0x10 + (block - 0x10*4) / 0x10);
  173. // Block number
  174. printf("%02zx ", block);
  175. // then print the block data
  176. print_hex_array_sep(current_tag.amb[block].mbd.abtData,
  177. sizeof(mf_block_t), " ");
  178. printf("\n");
  179. // Indicate sector bondaries with extra nl
  180. if (block < last && block < 16*4 && (block + 1) % 4 == 0)
  181. printf("\n");
  182. else if (block < last && block > 16*4 && (block + 1) % 16 == 0)
  183. printf("\n");
  184. }
  185. }
  186. void print_keys(const mf_tag_t* tag, mf_size_t size) {
  187. printf("xS xB KeyA KeyB\n");
  188. printf("----------------------------------\n");
  189. for (int block = 3; block < 0x10 * 4; block += 4) {
  190. printf("%02x %02x ", block / 4, block);
  191. print_hex_array(tag->amb[block].mbt.abtKeyA, 6);
  192. printf(" ");
  193. print_hex_array(tag->amb[block].mbt.abtKeyB, 6);
  194. printf("\n");
  195. }
  196. if (size == MF_1K)
  197. return;
  198. printf("\n");
  199. for (int block = 0xf; block < 0x0c * 0x10; block += 0x10) {
  200. printf("%02x %02x ", 0x10 + block/0x10, 0x10*4 + block);
  201. print_hex_array(tag->amb[0x10*4 + block].mbt.abtKeyA, 6);
  202. printf(" ");
  203. print_hex_array(tag->amb[0x10*4 + block].mbt.abtKeyB, 6);
  204. printf("\n");
  205. }
  206. }
  207. void print_ac(const mf_tag_t* tag) {
  208. static const char* ac_data_str[8] = {
  209. /* 0 0 0 */ " A|B A|B A|B A|B . . . . . .",
  210. /* 0 0 1 */ " A|B x x A|B . . . . . .",
  211. /* 0 1 0 */ " A|B x x x . . . . . .",
  212. /* 0 1 1 */ " B B x x . . . . . .",
  213. /* 1 0 0 */ " A|B B x x . . . . . .",
  214. /* 1 0 1 */ " B x x x . . . . . .",
  215. /* 1 1 0 */ " A|B B B A|B . . . . . .",
  216. /* 1 1 1 */ " x x x x . . . . . .",
  217. };
  218. static const char* ac_trailer_str[8] = {
  219. /* 0 0 0 */ " . . . . x A A x A A",
  220. /* 0 0 1 */ " . . . . x A A A A A",
  221. /* 0 1 0 */ " . . . . x x A x A x",
  222. /* 0 1 1 */ " . . . . x B A|B B x B",
  223. /* 1 0 0 */ " . . . . x B A|B x x B",
  224. /* 1 0 1 */ " . . . . x x A|B B x x",
  225. /* 1 1 0 */ " . . . . x x A|B x x x",
  226. /* 1 1 1 */ " . . . . x x A|B x x x",
  227. };
  228. // Print header
  229. printf("xS xB Raw C1 C2 C3 R W I D AR AW ACR ACW BR BW\n");
  230. printf("--------------------------------------------------------------------\n");
  231. // Iterate over all blocks (in 1k sectors)
  232. for (size_t block = 0; block < 0x10 * 4; ++block) {
  233. // Sector number
  234. printf("%02zx ",
  235. block < 0x10*4 ? block / 4 : 0x10 + (block - 0x10*4) / 0x10);
  236. // Block number
  237. printf("%02zx ", block);
  238. const uint8_t* ac = tag->amb[block_to_trailer(block)].mbt.abtAccessBits;
  239. // Print raw bytes
  240. print_hex_array(ac, 4);
  241. // Print the C1, C2, C3 bits
  242. int c1 = (ac[1] & 1<<(4 + (block % 4))) > 0;
  243. int c2 = (ac[2] & 1<<(0 + (block % 4))) > 0;
  244. int c3 = (ac[2] & 1<<(4 + (block % 4))) > 0;
  245. printf(" %d %d %d", c1, c2, c3);
  246. // Print enterpretation
  247. int c123 = (c1<<2) | (c2<<1) | c3;
  248. if (block % 4 < 3) {
  249. // Data block
  250. printf("%s", ac_data_str[c123]);
  251. }
  252. else {
  253. // Trailer block
  254. printf("%s", ac_trailer_str[c123]);
  255. }
  256. printf("\n");
  257. // Indicate sector bondaries with extra nl
  258. if ((block + 1) % 4 == 0)
  259. printf("\n");
  260. }
  261. }
  262. const char* sprint_key(const uint8_t* key) {
  263. static char str_buff[13];
  264. if (!key)
  265. return NULL;
  266. sprintf(str_buff, "%02x%02x%02x%02x%02x%02x",
  267. (unsigned int)(key[0]),
  268. (unsigned int)(key[1]),
  269. (unsigned int)(key[2]),
  270. (unsigned int)(key[3]),
  271. (unsigned int)(key[4]),
  272. (unsigned int)(key[5]));
  273. return str_buff;
  274. }
  275. // Return a string describing the tag type 1k|4k
  276. const char* sprint_size(mf_size_t size) {
  277. static const char* str_1k = "1k";
  278. static const char* str_4k = "4k";
  279. if (size == MF_1K)
  280. return str_1k;
  281. if (size == MF_4K)
  282. return str_4k;
  283. return NULL;
  284. }
  285. uint8_t* read_key(uint8_t* key, const char* str) {
  286. if (!key || !str)
  287. return NULL;
  288. static char byte_tok[] = {0, 0, 0};
  289. char* byte_tok_end;
  290. for (int i = 0; i < 6; ++i) {
  291. byte_tok[0] = str[i*2];
  292. byte_tok[1] = str[i*2+1];
  293. key[i] = (uint8_t)strtol(byte_tok, &byte_tok_end, 16);
  294. if (*byte_tok_end != '\0') {
  295. return NULL;
  296. }
  297. }
  298. return key;
  299. }
  300. void clear_tag(mf_tag_t* tag) {
  301. memset((void*)tag, 0x00, MF_4K);
  302. }
  303. void strip_non_auth_data(mf_tag_t* tag) {
  304. static const size_t bs = sizeof(mf_block_t);
  305. // Clear 1k sector data 16 á 4 - only keep sector trailer
  306. for (size_t i = 0; i < 0x10; ++i)
  307. memset(((void*)tag) + i * 4 * bs, 0x00, 3 * bs);
  308. // Clear 2-4k sector data 12 á 16 - only keep sector trailer
  309. for (size_t i = 0; i < 0x0c; ++i)
  310. memset(((void*)tag) + 0x10 * 4 * bs + i * 0x10 * bs, 0x00, 0x0f * bs);
  311. }
  312. size_t block_count(mf_size_t size) {
  313. return size / 0x10;
  314. }
  315. size_t sector_count(mf_size_t size) {
  316. return size == MF_1K ? 0x10 : 0x1c;
  317. }
  318. int is_trailer_block(size_t block) {
  319. return (block + 1) % (block < 0x80 ? 4 : 0x10) == 0;
  320. }
  321. size_t block_to_sector(size_t block) {
  322. if (block < 0x10*4)
  323. return block / 4;
  324. return 0x10 + (block - 0x10*4) / 0x10;
  325. }
  326. size_t block_to_header(size_t block) {
  327. if (block < 0x10*4)
  328. return block + (block % 4);
  329. return block + (block % 0x10);
  330. }
  331. // Return the trailer block for the specified block
  332. size_t block_to_trailer(size_t block)
  333. {
  334. if (block < 0x10*4)
  335. return block + (3 - (block % 4));
  336. return block + (0xf - (block % 0x10));
  337. }
  338. // Return the trailer block for the specified sector
  339. size_t sector_to_trailer(size_t sector) {
  340. if (sector < 0x10)
  341. return sector * 4 + 3;
  342. else
  343. return 0x10 * 4 + (sector - 0x10) * 0x10 + 0xf;
  344. }
  345. // Return the sector size (in blocks) that contains the block
  346. size_t sector_size(size_t block) {
  347. return block < 0x10*4 ? 4 : 16;
  348. }
  349. // Extract the key for the block parameters sector of the tag and return it
  350. uint8_t* key_from_tag(const mf_tag_t* tag,
  351. mf_key_type_t key_type,
  352. size_t block) {
  353. static uint8_t key[6];
  354. size_t trailer_block = block_to_trailer(block);
  355. if (key_type == MF_KEY_A)
  356. memcpy(key, tag->amb[trailer_block].mbt.abtKeyA, 6);
  357. else
  358. memcpy(key, tag->amb[trailer_block].mbt.abtKeyB, 6);
  359. return key;
  360. }
  361. // Write key to the sector of a tag, where the sector is specified by
  362. // the block.
  363. void key_to_tag(mf_tag_t* tag, const uint8_t* key,
  364. mf_key_type_t key_type, size_t block) {
  365. size_t trailer_block = block_to_trailer(block);
  366. if (key_type == MF_KEY_A)
  367. memcpy(tag->amb[trailer_block].mbt.abtKeyA, key, 6);
  368. else
  369. memcpy(tag->amb[trailer_block].mbt.abtKeyB, key, 6);
  370. }
  371. /**
  372. * Return block index of the first block in every sector in turn on
  373. * repeated calls. Initialize the iterator by calling with state
  374. * 0. Subsequent calls should use the tag size as state. The iterator
  375. * returns -1 as an end marker.
  376. */
  377. int sector_header_iterator(int state) {
  378. static int block;
  379. if (state == 0)
  380. return block = 0;
  381. if (block + 4 < 0x10*4)
  382. return block += 4;
  383. if (state == MF_1K) // End marker for 1k state
  384. return -1;
  385. if (block + 0x10 < 0x100)
  386. return block += 0x10;
  387. return -1; // End marker for 4k state
  388. }