Wii ISO Structure and Decryption Process
TODO
Probably need to split this page on smaller ones
Overview
A Wii disc is an ISO image of 4.7 GB (single-layer) or 8.5 GB (dual-layer) organized in successive layers. There are several levels: Disc Header, Partition Table, Partition Headers (containing the Ticket and TMD, then AES decryption of the data to finally access the File System Table (FST).
Disc Header (0x000 – 0x440)
The Disc Header sits at the very beginning of the ISO (offset 0x000). It is read unencrypted and holds the global disc metadata.
Offset |
Size |
Field |
Description |
|---|---|---|---|
|
|
Unique game identifier (like |
|
|
|
Disc Number |
Disc number (0 for single-disc games) |
|
|
Disc Version |
Disc version |
|
|
Audio Streaming |
Audio streaming enable flag |
|
|
Stream Buffer Size |
Streaming buffer size |
|
|
Wii Magic Word |
Must be |
|
|
GameCube Magic Word |
|
|
|
Game Title |
Game name in ASCII |
|
|
Disable Hash Verification | If set, disables H3 hash verification |
|
|
|
Disable Disc Encryption |
If set, the disc is unencrypted |
|
|
Padding |
Just |
Internal Header (inside decrypted data)
Once the DATA partition is decrypted, a second Disc Header (internal, called boot.bin) is found at offset
0x000 of the decrypted data. It additionally contains the DOL and FST informations:
Offset |
Size |
Field |
Description |
|---|---|---|---|
|
|
DOL Offset |
Executable file offset |
|
|
FST Offset |
File System Table offset |
|
|
FST Size |
FST size |
|
|
FST Max Size |
Maximum allocated FST size |
Important
DOL/FST offsets are stored right-shifted by 2 bits (>> 2). To get the actual offset, multiply by 4 (<< 2).
Partition Table (0x40000)
The partition table is always at the fixed offset 0x40000. It defines 4 partition group s, each consisting of:
Field |
Size |
Description |
|---|---|---|
Count |
|
Number of partitions in this group |
Offset |
|
Offset (shifted) to this group entries |
Each partition entry consists of:
Field |
Size |
Description |
|---|---|---|
Partition Offset |
|
Partition offset (shifted) |
Partition Type |
|
|
The DATA partition contains the game itself.
The UPDATE partition holds system update.
The CHANNEL partition holds when game have channels like wii fit, Mario Kart.
Note
Super Smash Bros Brawl has a lot of partitions. Each one for the virtual game
Partition Header
Each partition starts with a header containing:
Partition header structure
Here is the content of a Partition Header
Offset |
Size |
Field |
|---|---|---|
|
|
Ticket |
|
|
TMD Size |
|
|
TMD Offset shifted |
|
|
Cert Size |
|
|
Cert Offset shifted |
|
|
H3 table offset shifted |
|
|
Data Size shifted |
|
|
Data Offset shifted |
|
|
FST Max Size |
Note
All offsets in the partition header are relative to the partition start.
Ticket - Title key decryption
Tickets contains the encrypted AES title key and the title ID of the data. Ticket are signed from a certificate chain.
Title key decryption process
Sequence diagram for title key decryption
Important
For nintendo common key (16 bytes AES keys):
Index 0: “Normal” common key, the most frequent
Index 1: Korean common key
TMD (Title MetaData)
The Title MetaData is used to store information about a title and its contents and their SHA1 hashes.
Here is the structure
Offset |
Size |
Field |
|---|---|---|
|
|
Signature type (always 0x10001 for RSA-2048 with SHA-1) |
|
|
Signature |
|
|
Padding for 64 bytes aligment |
|
|
Certificate issuer |
|
|
Version |
|
|
ca_crl_version |
|
|
signer_crl_version |
|
|
Is vWii |
|
|
System Version |
|
|
Title ID |
|
|
Title type |
|
|
Group ID |
|
|
— |
|
|
Region |
|
|
Ratings |
|
|
Reserved |
|
|
IPC Mask |
|
|
Reserved |
|
|
Access rights |
|
|
Title version |
|
|
Number of contents |
|
|
boot index |
|
|
Minor version, unused |
CMD (Content MetaData)
Each CMD has this structre:
Offset |
Size |
Field |
|---|---|---|
|
|
Content ID |
|
|
Index |
|
|
Type |
|
|
Size |
|
|
SHA1 hash |
Certificate chain
Most chains contains 3 certificated, each padded to 0x40.
Each certificate contains this structure:
Offset |
Length |
Description |
|---|---|---|
|
|
Signature type |
|
|
Signature |
|
|
Issuer |
|
|
Key type |
|
|
Child Certificate Identity |
|
|
Key ID |
|
|
Public Key |
Since the signature depends on the signature type (see below), the offset depends on the signature type
Signatures types
Name |
Signature Type |
Signature Length |
|---|---|---|
Elliptic Curve |
|
|
RSA-2048 |
|
|
RSA-4096 |
|
|
Key types
Name |
Signature Type |
Key length |
Key Modulus |
Key Public exponent |
Key padding to |
|---|---|---|---|---|---|
Elliptic Curve |
|
|
|
|
|
RSA-2048 |
|
|
|
|
|
RSA-4096 |
|
|
|
|
|
Data decryption/encryption
Partition data is encrypted with AES-128-CBC using the title key. The layout is:
Tree of data encryption
Block structure
Each block has a Merkle Tree node, the IV and their encrypted data.
Offset |
Length |
Description |
|---|---|---|
|
|
Block header (H0, H1, etc.) |
|
|
Data IV |
|
|
Encrypted Data |
Block decryption process
Read the
0x8000bytes block from the ISOExtract the IV at offset
0x3D0of the block headerDecrypt data at offset
0x400with AES-128-CBC using the title key and IVResult is
0x7C00bytes of decrypted data
Encryption and hashing processes
This part is quite difficult. Data within block, group are hashed then encrypted. So, if we need to change files, we also need to hash then encrypt all datas. Before, in the header we said that it contains H0, H1, etc. It’s from a Merkle Tree, a tree with every node that is not a leaf is a hash of its child. For Wii ISO, it’s like this:
Merkle Tree for Wii ISO
Since the algorithm is pretty hard to understand, here a good sequence diagram:
Sequence diagram for encryption