tools.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  1. // Copyright 2007,2008 Segher Boessenkool <segher@kernel.crashing.org>
  2. // Licensed under the terms of the GNU GPL, version 2
  3. // http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
  4. #include "tools.h"
  5. #include <stddef.h> // to accommodate certain broken versions of openssl
  6. #include <openssl/md5.h>
  7. #include <openssl/aes.h>
  8. #include <openssl/sha.h>
  9. #include <stdarg.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <stdio.h>
  13. #include <time.h>
  14. #ifdef WIN32
  15. #define snprintf _snprintf
  16. #endif
  17. //
  18. // basic data types
  19. //
  20. u16 be16(const u8 *p)
  21. {
  22. return (p[0] << 8) | p[1];
  23. }
  24. u32 be32(const u8 *p)
  25. {
  26. return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
  27. }
  28. u64 be64(const u8 *p)
  29. {
  30. return ((u64)be32(p) << 32) | be32(p + 4);
  31. }
  32. u64 be34(const u8 *p)
  33. {
  34. return 4 * (u64)be32(p);
  35. }
  36. void wbe16(u8 *p, u16 x)
  37. {
  38. p[0] = (u8)(x >> 8);
  39. p[1] = (u8)(x);
  40. }
  41. void wbe32(u8 *p, u32 x)
  42. {
  43. wbe16(p + 0, (u16)(x >> 16));
  44. wbe16(p + 2, (u16)(x));
  45. }
  46. void wbe64(u8 *p, u64 x)
  47. {
  48. wbe32(p + 0, (u32)(x >> 32));
  49. wbe32(p + 4, (u32)(x));
  50. }
  51. //
  52. // crypto
  53. //
  54. void md5(u8 *data, u32 len, u8 *hash)
  55. {
  56. MD5(data, len, hash);
  57. }
  58. void sha(u8 *data, u32 len, u8 *hash)
  59. {
  60. SHA1(data, len, hash);
  61. }
  62. void get_key(const char *name, u8 *key, u32 len)
  63. {
  64. char path[256];
  65. #ifndef WIN32
  66. char *home;
  67. #endif
  68. FILE *fp;
  69. #ifdef WIN32
  70. snprintf(path, sizeof path, "wii/%s", name);
  71. #else
  72. home = getenv("HOME");
  73. if (home == 0)
  74. fatal("cannot find HOME");
  75. snprintf(path, sizeof path, "%s/.wii/%s", home, name);
  76. #endif
  77. fp = fopen(path, "rb");
  78. if (fp == 0)
  79. fatal("cannot open %s", name);
  80. if (fread(key, len, 1, fp) != 1)
  81. fatal("error reading %s", name);
  82. fclose(fp);
  83. }
  84. void aes_cbc_dec(u8 *key, u8 *iv, u8 *in, u32 len, u8 *out)
  85. {
  86. AES_KEY aes_key;
  87. AES_set_decrypt_key(key, 128, &aes_key);
  88. AES_cbc_encrypt(in, out, len, &aes_key, iv, AES_DECRYPT);
  89. }
  90. void aes_cbc_enc(u8 *key, u8 *iv, u8 *in, u32 len, u8 *out)
  91. {
  92. AES_KEY aes_key;
  93. AES_set_encrypt_key(key, 128, &aes_key);
  94. AES_cbc_encrypt(in, out, len, &aes_key, iv, AES_ENCRYPT);
  95. }
  96. void decrypt_title_key(u8 *tik, u8 *title_key)
  97. {
  98. u8 common_key[16];
  99. u8 iv[16];
  100. get_key("common-key", common_key, 16);
  101. memset(iv, 0, sizeof iv);
  102. memcpy(iv, tik + 0x01dc, 8);
  103. aes_cbc_dec(common_key, iv, tik + 0x01bf, 16, title_key);
  104. printf("title key: %02x %02x %02x\n",title_key[0],title_key[1],title_key[2]);
  105. }
  106. static u8 root_key[0x204];
  107. static u8 *get_root_key(void)
  108. {
  109. //get_key("root-key", root_key, sizeof root_key);
  110. return root_key;
  111. }
  112. static u32 get_sig_len(u8 *sig)
  113. {
  114. u32 type;
  115. type = be32(sig);
  116. switch (type - 0x10000) {
  117. case 0:
  118. return 0x240;
  119. case 1:
  120. return 0x140;
  121. case 2:
  122. return 0x80;
  123. }
  124. fprintf(stderr, "get_sig_len(): unhandled sig type %08x\n", type);
  125. return 0;
  126. }
  127. static u32 get_sub_len(u8 *sub)
  128. {
  129. u32 type;
  130. type = be32(sub + 0x40);
  131. switch (type) {
  132. case 0:
  133. return 0x2c0;
  134. case 1:
  135. return 0x1c0;
  136. case 2:
  137. return 0x100;
  138. }
  139. fprintf(stderr, "get_sub_len(): unhandled sub type %08x\n", type);
  140. return 0;
  141. }
  142. int check_ec(u8 *ng, u8 *ap, u8 *sig, u8 *sig_hash)
  143. {
  144. u8 ap_hash[20];
  145. u8 *ng_Q, *ap_R, *ap_S;
  146. u8 *ap_Q, *sig_R, *sig_S;
  147. ng_Q = ng + 0x0108;
  148. ap_R = ap + 0x04;
  149. ap_S = ap + 0x22;
  150. SHA1(ap + 0x80, 0x100, ap_hash);
  151. ap_Q = ap + 0x0108;
  152. sig_R = sig;
  153. sig_S = sig + 30;
  154. return check_ecdsa(ng_Q, ap_R, ap_S, ap_hash)
  155. && check_ecdsa(ap_Q, sig_R, sig_S, sig_hash);
  156. }
  157. static int check_rsa(u8 *h, u8 *sig, u8 *key, u32 n)
  158. {
  159. u8 correct[0x200];
  160. u8 x[0x200];
  161. static const u8 ber[16] = "\x00\x30\x21\x30\x09\x06\x05\x2b"
  162. "\x0e\x03\x02\x1a\x05\x00\x04\x14";
  163. //fprintf(stderr, "n = %x\n", n);
  164. //fprintf(stderr, "key:\n");
  165. //hexdump(key, n);
  166. //fprintf(stderr, "sig:\n");
  167. //hexdump(sig, n);
  168. correct[0] = 0;
  169. correct[1] = 1;
  170. memset(correct + 2, 0xff, n - 38);
  171. memcpy(correct + n - 36, ber, 16);
  172. memcpy(correct + n - 20, h, 20);
  173. //fprintf(stderr, "correct is:\n");
  174. //hexdump(correct, n);
  175. bn_exp(x, sig, key, n, key + n, 4);
  176. //fprintf(stderr, "x is:\n");
  177. //hexdump(x, n);
  178. if (memcmp(correct, x, n) == 0)
  179. return 0;
  180. return -5;
  181. }
  182. static int check_hash(u8 *h, u8 *sig, u8 *key)
  183. {
  184. u32 type;
  185. type = be32(sig) - 0x10000;
  186. if (type != be32(key + 0x40))
  187. return -6;
  188. switch (type) {
  189. case 1:
  190. return check_rsa(h, sig + 4, key + 0x88, 0x100);
  191. }
  192. return -7;
  193. }
  194. static u8 *find_cert_in_chain(u8 *sub, u8 *cert, u32 cert_len)
  195. {
  196. char parent[64];
  197. char *child;
  198. u32 sig_len, sub_len;
  199. u8 *p;
  200. u8 *issuer;
  201. strncpy(parent, (char*)sub, sizeof parent);
  202. parent[sizeof parent - 1] = 0;
  203. child = strrchr(parent, '-');
  204. if (child)
  205. *child++ = 0;
  206. else {
  207. *parent = 0;
  208. child = (char*)sub;
  209. }
  210. for (p = cert; p < cert + cert_len; p += sig_len + sub_len) {
  211. sig_len = get_sig_len(p);
  212. if (sig_len == 0)
  213. return 0;
  214. issuer = p + sig_len;
  215. sub_len = get_sub_len(issuer);
  216. if (sub_len == 0)
  217. return 0;
  218. if (strcmp(parent, (char*)issuer) == 0
  219. && strcmp(child, (char*)issuer + 0x44) == 0)
  220. return p;
  221. }
  222. return 0;
  223. }
  224. int check_cert_chain(u8 *data, u32 data_len, u8 *cert, u32 cert_len)
  225. {
  226. u8 *sig;
  227. u8 *sub;
  228. u32 sig_len;
  229. u32 sub_len;
  230. u8 h[20];
  231. u8 *key_cert;
  232. u8 *key;
  233. int ret;
  234. sig = data;
  235. sig_len = get_sig_len(sig);
  236. if (sig_len == 0)
  237. return -1;
  238. sub = data + sig_len;
  239. sub_len = data_len - sig_len;
  240. if (sub_len == 0)
  241. return -2;
  242. for (;;) {
  243. fprintf(stderr, ">>>>>> checking sig by %s...\n", sub);
  244. if (strcmp((char*)sub, "Root") == 0) {
  245. key = get_root_key();
  246. sha(sub, sub_len, h);
  247. if (be32(sig) != 0x10000)
  248. return -8;
  249. return check_rsa(h, sig + 4, key, 0x200);
  250. }
  251. key_cert = find_cert_in_chain(sub, cert, cert_len);
  252. if (key_cert == 0)
  253. return -3;
  254. key = key_cert + get_sig_len(key_cert);
  255. sha(sub, sub_len, h);
  256. ret = check_hash(h, sig, key);
  257. if (ret)
  258. return ret;
  259. sig = key_cert;
  260. sig_len = get_sig_len(sig);
  261. if (sig_len == 0)
  262. return -4;
  263. sub = sig + sig_len;
  264. sub_len = get_sub_len(sub);
  265. if (sub_len == 0)
  266. return -5;
  267. }
  268. }
  269. //
  270. // compression
  271. //
  272. void do_yaz0(u8 *in, u32 in_size, u8 *out, u32 out_size)
  273. {
  274. u32 nout;
  275. u8 bits;
  276. u32 nbits;
  277. u32 n, d, i;
  278. #ifdef UNNECESSARY_STUFF
  279. in_size++;
  280. #endif
  281. bits = 0;
  282. nbits = 0;
  283. in += 0x10;
  284. for (nout = 0; nout < out_size; ) {
  285. if (nbits == 0) {
  286. bits = *in++;
  287. nbits = 8;
  288. }
  289. if ((bits & 0x80) != 0) {
  290. *out++ = *in++;
  291. nout++;
  292. } else {
  293. n = *in++;
  294. d = *in++;
  295. d |= (n << 8) & 0xf00;
  296. n >>= 4;
  297. if (n == 0)
  298. n = 0x10 + *in++;
  299. n += 2;
  300. d++;
  301. for (i = 0; i < n; i++) {
  302. *out = *(out - d);
  303. out++;
  304. }
  305. nout += n;
  306. }
  307. nbits--;
  308. bits <<= 1;
  309. };
  310. }
  311. //
  312. // error handling
  313. //
  314. void fatal(const char *s, ...)
  315. {
  316. char message[256];
  317. va_list ap;
  318. va_start(ap, s);
  319. vsnprintf(message, sizeof message, s, ap);
  320. perror(message);
  321. exit(1);
  322. }
  323. void non_fatal(const char *s, ...)
  324. {
  325. char message[256];
  326. va_list ap;
  327. va_start(ap, s);
  328. vsnprintf(message, sizeof message, s, ap);
  329. perror(message);
  330. }
  331. //
  332. // output formatting
  333. //
  334. void print_bytes(u8 *x, u32 n)
  335. {
  336. u32 i;
  337. for (i = 0; i < n; i++)
  338. fprintf(stderr, "%02x", x[i]);
  339. }
  340. void hexdump(u8 *x, u32 n)
  341. {
  342. u32 i, j;
  343. for (i = 0; i < n; i += 16) {
  344. fprintf(stderr, "%04x:", i);
  345. for (j = 0; j < 16 && i + j < n; j++) {
  346. if ((j & 3) == 0)
  347. fprintf(stderr, " ");
  348. fprintf(stderr, "%02x", *x++);
  349. }
  350. fprintf(stderr, "\n");
  351. }
  352. }
  353. void dump_tmd(u8 *tmd)
  354. {
  355. u32 i, n;
  356. u8 *p;
  357. printf(" issuer: %s\n", tmd + 0x140);
  358. printf(" sys_version: %016llx\n", be64(tmd + 0x0184));
  359. printf(" title_id: %016llx\n", be64(tmd + 0x018c));
  360. printf(" title_type: %08x\n", be32(tmd + 0x0194));
  361. printf(" group_id: %04x\n", be16(tmd + 0x0198));
  362. printf("title_version: %04x\n", be16(tmd + 0x01dc));
  363. printf(" num_contents: %04x\n", be16(tmd + 0x01de));
  364. printf(" boot_index: %04x\n", be16(tmd + 0x01e0));
  365. n = be16(tmd + 0x01de);
  366. p = tmd + 0x01e4;
  367. for (i = 0; i < n; i++) {
  368. printf("cid %08x index %04x type %04x size %08llx\n",
  369. be32(p), be16(p + 4), be16(p + 6), be64(p + 8));
  370. p += 0x24;
  371. }
  372. }
  373. void spinner(u64 x, u64 max)
  374. {
  375. static time_t start_time;
  376. static u32 expected_total;
  377. u32 d;
  378. double percent;
  379. u32 h, m, s;
  380. if (x == 0) {
  381. start_time = time(0);
  382. expected_total = 300;
  383. }
  384. if (x == max) {
  385. d = (u32)(time(0) - start_time);
  386. h = d / 3600;
  387. m = (d / 60) % 60;
  388. s = d % 60;
  389. fprintf(stderr, "Done in %d:%02d:%02d \n", h, m, s);
  390. return;
  391. }
  392. d = (u32)(time(0) - start_time);
  393. if ( (d != 0) && (x > 0) )
  394. expected_total = (u32)((3 * expected_total + d * max / x) / 4);
  395. if (expected_total > d)
  396. d = expected_total - d;
  397. else
  398. d = 0;
  399. h = d / 3600;
  400. m = (d / 60) % 60;
  401. s = d % 60;
  402. percent = 100.0 * x / max;
  403. #ifdef SPINNER_MOD
  404. fprintf(stderr, "%5.2f%% (%c) ETA: %d:%02d:%02d \r",
  405. percent, "/|\\-"[(x/10) % 4], h, m, s);
  406. #else
  407. fprintf(stderr, "%5.2f|@|%d:%02d:%02d \r",
  408. percent, h, m, s);
  409. #endif
  410. fflush(stderr);
  411. }
  412. void progress(u64 x, u64 max)
  413. {
  414. static time_t start_time;
  415. static u32 expected_total;
  416. u32 d;
  417. u32 prc,dec;
  418. char prg[40];
  419. u32 h, m, s;
  420. if (x == 0) {
  421. start_time = time(0);
  422. expected_total = 300;
  423. }
  424. if (x == max)
  425. {
  426. d = (u32)(time(0) - start_time);
  427. h = d / 3600;
  428. m = (d / 60) % 60;
  429. s = d % 60;
  430. fprintf(stderr, "\rDone in %d:%02d:%02d \n", h, m, s);
  431. return;
  432. }
  433. d = (u32)(time(0) - start_time);
  434. if (x != 0)
  435. expected_total = (u32)((3 * expected_total + d * max / x) / 4);
  436. if (expected_total > d)
  437. d = expected_total - d;
  438. else
  439. d = 0;
  440. h = d / 3600;
  441. m = (d / 60) % 60;
  442. s = d % 60;
  443. prc = (u32)((100 * x) / max);
  444. dec = prc % 3;
  445. prc /=3;
  446. memset(prg, 0x20, 34);
  447. for(d=0;d<prc;d++) prg[d]='O';
  448. switch(dec)
  449. {
  450. case 1:
  451. prg[prc]='.';
  452. break;
  453. case 2:
  454. prg[prc]='o';
  455. break;
  456. }
  457. prg[33]=0;
  458. fprintf(stderr, "\rETA: %d:%02d:%02d [%s]", h, m, s, prg);
  459. fflush(stderr);
  460. }