Initial Commit
[Projects.git] / pkgbuilds / wiifuse / src / wiifuse-0.2.0 / tmd.c
bloba7f28e1ffaa98853e3bb51566ee0a6034df798a4
1 /*
2 * Copyright (C) 2008 dhewg, #wiidev efnet
4 * this file is part of wiifuse
5 * http://wiibrew.org/index.php?title=Wiifuse
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <stdlib.h>
23 #include <stdio.h>
25 #include "global.h"
26 #include "io.h"
27 #include "tmd.h"
29 // TODO
30 // this is a WIP, recheck the data structures and parse the whole cert chain
32 void tmd_load (struct image_file *image, u32 part) {
33 struct tmd *tmd;
34 u64 certs_size, certs_offset, tmd_size, tmd_offset;
35 enum tmd_sig sig = SIG_UNKNOWN;
36 u64 off;
38 u8 buffer[64];
39 u16 i, s;
41 off = image->parts[part].offset;
42 io_read (buffer, 16, image, off + 0x2a4);
44 tmd_size = get_be32 (buffer);
45 tmd_offset = get_be32 (&buffer[4]) * 4llu;
46 certs_size = get_be32 (&buffer[8]);
47 certs_offset = get_be32 (&buffer[12]) * 4llu;
49 off += tmd_offset;
51 io_read (buffer, 4, image, off);
52 off += 4;
54 switch (get_be32 (buffer)) {
55 case 0x00010001:
56 sig = SIG_RSA_2048;
57 s = 0x100;
58 break;
60 case 0x00010000:
61 sig = SIG_RSA_4096;
62 s = 0x200;
63 break;
66 if (sig == SIG_UNKNOWN)
67 return;
69 tmd = (struct tmd *) malloc (sizeof (struct tmd));
70 memset (tmd, 0, sizeof (struct tmd));
72 tmd->sig_type = sig;
74 image->parts[part].certs_offset = certs_offset;
75 image->parts[part].certs_size = certs_size;
77 image->parts[part].tmd_offset = tmd_offset;
78 image->parts[part].tmd_size = tmd_size;
80 // TODO omg im so lazy
81 image->parts[part].ticket_offset = 0;
82 image->parts[part].ticket_size = 676;
84 image->parts[part].tmd = tmd;
86 tmd->sig = malloc (s);
87 io_read (tmd->sig, s, image, off);
88 off += s;
90 off = ROUNDUP64B (off);
92 io_read (tmd->issuer, 0x40, image, off);
93 off += 0x40;
95 io_read (buffer, 26, image, off);
96 off += 26;
98 tmd->version = buffer[0];
99 tmd->ca_crl_version = buffer[1];
100 tmd->signer_crl_version = buffer[2];
102 tmd->sys_version = get_be64 (&buffer[4]);
103 tmd->title_id = get_be64 (&buffer[12]);
104 tmd->title_type = get_be32 (&buffer[20]);
105 tmd->group_id = get_be16 (&buffer[24]);
107 off += 62;
109 io_read (buffer, 10, image, off);
110 off += 10;
112 tmd->access_rights = get_be32 (buffer);
113 tmd->title_version = get_be16 (&buffer[4]);
114 tmd->num_contents = get_be16 (&buffer[6]);
115 tmd->boot_index = get_be16 (&buffer[8]);
117 off += 2;
119 if (tmd->num_contents < 1)
120 return;
122 tmd->contents =
123 (struct tmd_content *)
124 malloc (sizeof (struct tmd_content) * tmd->num_contents);
126 LOG (2, "tmd contents: 0x%08x", tmd->num_contents);
127 for (i = 0; i < tmd->num_contents; ++i) {
128 io_read (buffer, 0x30, image, off);
129 off += 0x30;
131 tmd->contents[i].cid = get_be32 (buffer);
132 tmd->contents[i].index = get_be16 (&buffer[4]);
133 tmd->contents[i].type = get_be16 (&buffer[6]);
134 tmd->contents[i].size = get_be64 (&buffer[8]);
135 memcpy (tmd->contents[i].hash, &buffer[16], 20);
137 LOG (2, " cid: 0x%08x index: 0x%04x type: 0x%04x "
138 "size: 0x%016llx",
139 tmd->contents[i].cid, tmd->contents[i].index,
140 tmd->contents[i].type, tmd->contents[i].size);
143 return;
146 void tmd_free (struct tmd *tmd) {
147 if (tmd == NULL)
148 return;
150 if (tmd->sig)
151 free (tmd->sig);
153 if (tmd->contents)
154 free (tmd->contents);
156 free (tmd);