Wii Disc

From WiiBrew
Jump to: navigation, search

Disc Format

The first 0x400 bytes are like the GameCube disc header format.

offset size description
0x0000000000 1 Wiidisc_IDs
0x0000000001 2 Gamecode
0x0000000003 1 Region, E = USA, P = PAL, J = JAP
0x0000000004 2 Maker Code
0x0000000006 1 Disc ID
0x0000000007 1 Version
0x0000000008 1 Audio Streaming
0x0000000009 1 Streaming Buffersize
0x000000000A 14 zero, unused?
0x0000000018 4 magicword, 0x5D1C9EA3
0x0000000020 0x40 Gametitle (though most docs claim it to be 0x400 the Wii only reads 0x44 which will be padded by the DI driver to 0x60)
0x0000000060 1 Disable hash verification and make all disc reads fail even before they reach the DVD drive.
0x0000000061 1 Disable disc encryption and h3 hash table loading and verification (which effectively also makes all disc reads fail because the h2 hashes won't be able to verify against "something" that will be in the memory of the h3 hash table. none of these two bytes will allow unsigned code)
0x0000000080 0x380 padded with 0

Region setting

offset size description
0x0004E000 4 Region, 0 = JAP, 1 = USA, 2 = EUR
0x0004E010 16 unknown, but setting 4E010(JAP), 4E011(USA) and 4E014(EUR) to zero is needed if 4E000 is changed to a different region. Blanking all 16 will work too.

Partitions

The Wii disc format uses parititions, mostly one is used for updates (the 1st) and the 2nd for the game.


offset size description
0x0000040000 4 Total partitions in the disc
0x0000040004 4 Partition info table offset, Address is (value << 2)
0x0000040008 4 Total 2nd partitions in the disc (optional)
0x000004000C 4 Partition info table offset, Address is (value << 2)
0x0000040010 4 Total 3rd partitions in the disc (optional)
0x0000040014 4 Partition info table offset, Address is (value << 2)
0x0000040018 4 Total 4th partitions in the disc (optional)
0x000004001C 4 Partition info table offset, Address is (value << 2)


Partition table entry
offset size description
0x0000000000 4 Partition offset, Address is (value << 2)
0x0000000004 4 Partitions to follow ?, partition type ? It's always 1 for the first entry


Each partition starts with a Ticket followed by the TMD followed by three certifications.

Offset 0x00000000 is considered as the start of the partition.

Tmd_file_structure and certification structure


Ticket:
offset size description
to todo
0x000001BF 16 Encrypted partition key
0x000001DC 8 First half of partition key IV (last half is zero)
0x000002A0 0x20 Partition offsets
0x000002A4 4 TMD size
0x000002A8 4 TMD offset
0x000002AC 4 Size of the certificates
0x000002B0 4 Certificate offset
0x000002B4 4 Offset to the global SHA-1 table (value << 2)
0x000002B8 4 Data offset, Address is (value << 2)
0x000002BC 4 Data size, Address is (value << 2)

Partition Data

Partition data is encrypted using a key, which can be obtained from the partition header and the master key. The actual partition data starts at offset 0x20000 in the partition, and it is formatted in "clusters" of size 0x8000 (32k). Each one of these blocks consists of 0x400 bytes of encrypted SHA-1 hash data, followed by 0x7C00 bytes of encrypted user data. The 0x400 bytes SHA-1 data is encrypted using AES-128-CBC, with the partition key and a null (all zeroes) IV. Clusters are aggregated into subgroups of 8 clusters, and 8 subgroups are aggregated into one group of 64 clusters. The plaintext format is as follows:

Start End Length Description
0x000 0x26B 0x26C 31 SHA-1 hashes ("H0", 20 bytes each), one for each block of 0x400 bytes of the decrypted user data for this cluster.
0x26C 0x27F 0x014 20 bytes of 0x00 padding
0x280 0x31F 0x0A0 8 SHA-1 hashes ("H1"), one for each cluster in this subgroup. Each hash is of the 0x000-0x26B bytes, that is, of the 31 hashes above. This means that each cluster carries a hash of the data cluster hashes for each of the clusters in its subgroup. Every cluster in the subgroup has identical data in this section.
0x320 0x33F 0x020 32 bytes of 0x00 padding
0x340 0x3DF 0x0A0 8 SHA-1 hashes("H2"), one for each subgroup in this group. Each hash is of the 0x280-0x31F bytes above. This means that each cluster carries a hash of the subgroup hash data for each of the subgroups in its group. All 64 clusters in a group have identical data in this section. Bytes 0x3D0-0x3DF here, when encrypted, serve as the IV for the user data.
0x3E0 0x3FF 0x020 32 bytes of 0x00 padding

If you're having trouble seeing how this works, here's the algorithm:

  • For every 0x400 bytes of user data (plaintext), apply SHA-1. Store the resulting table of hashes.
  • Aggregate 8 clusters. Apply SHA-1 to the table of data hashes that you've just created above for every cluster, and build a table of the resulting 8 hashes. Store this table in each of the 8 clusters.
  • Aggregate 8 subgroups (64 clusters). Apply SHA-1 to the table of hashes of each subgroup (note that every cluster in the subgroup shares this, so you only compute the SHA-1 once per subgroup). Build a table, and store a copy of this table into every one of the 64 clusters.

Finally, the global hash table ("H3"; which the partition header points to) contains the SHA-1 hash of the last table of each group in the disc. This table is not encrypted, but it is signed. To build it, take bytes 0x340-0x3DF from any sector in each group in the disc, apply SHA-1, and simply store all of the resulting hashes consecutively. All in all, each sector includes enough information to trace itself back to the master SHA-1 hash table. As a result, the entire disc is effectively signed. If anything is changed, the Wii will immediately crash (if the master hash table has been updated), or it will crash when it reads any sector in the modified group (if the group tables have been updated), any sector in the modified subgroup (if the subgroup tables have been updated), or any modified sector if no SHA-1s were updated.

To decrypt the user data at 0x0400-0x7FFF, again use the partition key, but this time take the IV from bytes 0x3D0-0x3DF in the encrypted SHA-1 block.