Difference between revisions of "Title metadata"
(Multi-column entries for offsets) |
(note discrepancy in endianness) |
||
(31 intermediate revisions by 9 users not shown) | |||
Line 1: | Line 1: | ||
− | '''Title metadata''' is a format used to store information about a title ( | + | [[Category:File formats]] |
+ | '''Title metadata''' is a format used to store information about a title (installed title, DLC, etc.) and all its installed contents, including which contents they consist of and their SHA256 hashes. | ||
− | [ | + | [https://bitbucket.org/trap15/3dshax Code is available] by trap15 to parse the available information from the 3DS format of TMDs. |
== Structure == | == Structure == | ||
+ | |||
+ | All the data in the file represented in Big Endian, unless otherwise noted. | ||
+ | |||
+ | {| class="wikitable" | ||
+ | | align="center" style="background:#f0f0f0;"|'''Offset''' | ||
+ | | align="center" style="background:#f0f0f0;"|'''Size''' | ||
+ | | align="center" style="background:#f0f0f0;"|'''Description''' | ||
+ | |- | ||
+ | | 0x0||Y||Signature Data | ||
+ | |- | ||
+ | | Y ||0xC4||Header | ||
+ | |- | ||
+ | | 0xC4 + Y||0x24*64||Content Info Records. | ||
+ | |- | ||
+ | | 0x9C4 + Y||0x30*ContentCount||Content Chunk Records. | ||
+ | |} | ||
+ | |||
+ | Y denotes the total size of the "Signature Data" section and depends on the signature type. | ||
+ | |||
+ | === Signature Data === | ||
+ | The signature is of the header of the TMD. | ||
+ | {| class="wikitable" | ||
+ | | align="center" style="background:#f0f0f0;"|'''Offset''' | ||
+ | | align="center" style="background:#f0f0f0;"|'''Size''' | ||
+ | | align="center" style="background:#f0f0f0;"|'''Description''' | ||
+ | |- | ||
+ | | 0x0||0x4||Signature Type | ||
+ | |- | ||
+ | | 0x4 ||X||Signature | ||
+ | |- | ||
+ | | 0x4 + X|| ||Padding Aligning the signature data to 0x40 bytes | ||
+ | |} | ||
+ | |||
+ | ==== Signature Type ==== | ||
+ | {{Signature Types}} | ||
+ | The hash for the signature, is calculated over the header of the TMD | ||
+ | |||
=== Header === | === Header === | ||
+ | |||
{| class="wikitable" | {| class="wikitable" | ||
− | | align="center" style="background:#f0f0f0;"|''' | + | | align="center" style="background:#f0f0f0;"|'''Offset''' |
− | | align="center" style="background:#f0f0f0;"|''' | + | | align="center" style="background:#f0f0f0;"|'''Size''' |
− | |||
| align="center" style="background:#f0f0f0;"|'''Description''' | | align="center" style="background:#f0f0f0;"|'''Description''' | ||
|- | |- | ||
− | | | + | | 0x0||0x40||Signature Issuer |
+ | |- | ||
+ | | 0x40||0x1||Version | ||
|- | |- | ||
− | | | + | | 0x41||0x1||ca_crl_version |
|- | |- | ||
− | | | + | | 0x42||0x1||signer_crl_version |
|- | |- | ||
− | | | + | | 0x43||0x1||Reserved |
|- | |- | ||
− | | | + | | 0x44||0x8||System Version |
|- | |- | ||
− | | | + | | 0x4C||0x8||Title ID |
|- | |- | ||
− | | | + | | 0x54||0x4||Title Type |
|- | |- | ||
− | | | + | | 0x58||0x2||Group ID |
|- | |- | ||
− | | | + | | 0x5A||0x4||Save Data Size in Little Endian (Bytes) (Also SRL Public Save Data Size) |
|- | |- | ||
− | | | + | | 0x5E||0x4||SRL Private Save Data Size in Little Endian (Bytes) |
|- | |- | ||
− | | | + | | 0x62||0x4||Reserved |
|- | |- | ||
− | | | + | | 0x66||0x1||SRL Flag |
|- | |- | ||
− | | | + | | 0x67||0x31||Reserved |
|- | |- | ||
− | | | + | | 0x98||0x4||Access Rights |
|- | |- | ||
− | | | + | | 0x9C||0x2||Title Version |
|- | |- | ||
− | | | + | | 0x9E||0x02||Content Count |
|- | |- | ||
− | | | + | | 0xA0||0x2||Boot Content |
|- | |- | ||
− | | | + | | 0xA2||0x2||Padding |
|- | |- | ||
− | | | + | | 0xA4||0x20||SHA-256 Hash of the Content Info Records |
+ | |} | ||
+ | |||
+ | === Content Info Records === | ||
+ | |||
+ | There are 64 of these records, usually only the first is used. | ||
+ | |||
+ | {| class="wikitable" | ||
|- | |- | ||
− | + | ! Offset | |
+ | ! Size | ||
+ | ! Description | ||
|- | |- | ||
− | | | + | | 0x00 |
+ | | 2 | ||
+ | | Content index offset | ||
|- | |- | ||
− | | | + | | 0x02 |
+ | | 2 | ||
+ | | Content command count [k] | ||
|- | |- | ||
− | | | + | | 0x04 |
+ | | 0x20 | ||
+ | | SHA-256 hash of the next k content records that have not been hashed yet | ||
|} | |} | ||
− | === Content | + | === Content chunk records === |
+ | There is one of these for each content contained in this title. (Determined by "Content Count" in the TMD Header). | ||
+ | |||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
− | ! | + | ! Offset |
− | ! | + | ! Size |
! Description | ! Description | ||
|- | |- | ||
| 0x00 | | 0x00 | ||
| 4 | | 4 | ||
− | | Content | + | | Content id |
|- | |- | ||
| 0x04 | | 0x04 | ||
− | | | + | | 2 |
− | | SHA-256 | + | | Content index |
+ | |- | ||
+ | | 0x06 | ||
+ | | 2 | ||
+ | | Content type | ||
+ | |- | ||
+ | | 0x08 | ||
+ | | 8 | ||
+ | | Content size | ||
+ | |- | ||
+ | | 0x10 | ||
+ | | 0x20 | ||
+ | | SHA-256 hash | ||
+ | |} | ||
+ | ==== Content Index ==== | ||
+ | |||
+ | This indicates the content type: | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
+ | |- | ||
+ | ! Index | ||
+ | ! Content Type | ||
+ | |- | ||
+ | | 0000 | ||
+ | | Main Content (.[[NCCH#CXI|CXI]] for 3DS executable content/.[[NCCH#CFA|CFA]] for 3DS Data Archives/.SRL for TWL content) | ||
+ | |- | ||
+ | | 0001 | ||
+ | | Home Menu Manual (.[[NCCH#CFA|CFA]]) | ||
+ | |- | ||
+ | | 0002 | ||
+ | | DLP Child Container (.[[NCCH#CFA|CFA]]) | ||
|} | |} | ||
− | === | + | This does not apply to DLC. |
+ | |||
+ | ==== Content Type flags ==== | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
− | ! | + | ! Flags |
− | |||
! Description | ! Description | ||
|- | |- | ||
− | | | + | | 1 |
+ | | Encrypted | ||
+ | |- | ||
+ | | 2 | ||
+ | | Disc | ||
+ | |- | ||
| 4 | | 4 | ||
− | | | + | | CFM (abbreviation for?) |
|- | |- | ||
− | | | + | | 0x4000 |
− | | | + | | Optional |
− | |||
|- | |- | ||
− | | | + | | 0x8000 |
− | | | + | | Shared |
− | | | + | |} |
+ | |||
+ | == Certificate Chain == | ||
+ | If the TMD file is obtained from Nintendo's CDN, then it will have two [[Certificates|certificates]] appended at the end of the file: | ||
+ | |||
+ | {| class="wikitable" border="1" | ||
|- | |- | ||
− | + | ! CERTIFICATE | |
− | + | ! SIGNATURE TYPE | |
− | + | ! RETAIL CERT NAME | |
+ | ! DEBUG CERT NAME | ||
+ | ! DESCRIPTION | ||
|- | |- | ||
− | | | + | | TMD |
− | | | + | | RSA-2048 |
− | | | + | | CP0000000b |
+ | | CP0000000a | ||
+ | | Used to verify the TMD signature | ||
|- | |- | ||
− | | | + | | CA |
− | | | + | | RSA-4096 |
− | | | + | | CA00000003 |
+ | | CA00000004 | ||
+ | | Used to verify the TMD Certificate | ||
|} | |} | ||
+ | |||
+ | The CA certificate is issued by 'Root', the public key for which is stored in NATIVE_FIRM. | ||
== Example code application == | == Example code application == | ||
<source lang="c"> | <source lang="c"> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
enum sig_type { | enum sig_type { | ||
RSA_2048_SHA256 = 0x00010004, | RSA_2048_SHA256 = 0x00010004, | ||
Line 119: | Line 219: | ||
RSA_4096_SHA1 = 0x00010000 | RSA_4096_SHA1 = 0x00010000 | ||
}; | }; | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | // Sorry I removed the example struct because it is wrong. | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</source> | </source> |
Latest revision as of 13:22, 28 July 2020
Title metadata is a format used to store information about a title (installed title, DLC, etc.) and all its installed contents, including which contents they consist of and their SHA256 hashes.
Code is available by trap15 to parse the available information from the 3DS format of TMDs.
Structure[edit]
All the data in the file represented in Big Endian, unless otherwise noted.
Offset | Size | Description |
0x0 | Y | Signature Data |
Y | 0xC4 | Header |
0xC4 + Y | 0x24*64 | Content Info Records. |
0x9C4 + Y | 0x30*ContentCount | Content Chunk Records. |
Y denotes the total size of the "Signature Data" section and depends on the signature type.
Signature Data[edit]
The signature is of the header of the TMD.
Offset | Size | Description |
0x0 | 0x4 | Signature Type |
0x4 | X | Signature |
0x4 + X | Padding Aligning the signature data to 0x40 bytes |
Signature Type[edit]
Value | Signature Method | Signature Size | Padding Size |
---|---|---|---|
0x010000 | RSA_4096 SHA1 (Unused for 3DS) | 0x200 | 0x3C |
0x010001 | RSA_2048 SHA1 (Unused for 3DS) | 0x100 | 0x3C |
0x010002 | Elliptic Curve with SHA1 (Unused for 3DS) | 0x3C | 0x40 |
0x010003 | RSA_4096 SHA256 | 0x200 | 0x3C |
0x010004 | RSA_2048 SHA256 | 0x100 | 0x3C |
0x010005 | ECDSA with SHA256 | 0x3C | 0x40 |
The hash for the signature, is calculated over the header of the TMD
Header[edit]
Offset | Size | Description |
0x0 | 0x40 | Signature Issuer |
0x40 | 0x1 | Version |
0x41 | 0x1 | ca_crl_version |
0x42 | 0x1 | signer_crl_version |
0x43 | 0x1 | Reserved |
0x44 | 0x8 | System Version |
0x4C | 0x8 | Title ID |
0x54 | 0x4 | Title Type |
0x58 | 0x2 | Group ID |
0x5A | 0x4 | Save Data Size in Little Endian (Bytes) (Also SRL Public Save Data Size) |
0x5E | 0x4 | SRL Private Save Data Size in Little Endian (Bytes) |
0x62 | 0x4 | Reserved |
0x66 | 0x1 | SRL Flag |
0x67 | 0x31 | Reserved |
0x98 | 0x4 | Access Rights |
0x9C | 0x2 | Title Version |
0x9E | 0x02 | Content Count |
0xA0 | 0x2 | Boot Content |
0xA2 | 0x2 | Padding |
0xA4 | 0x20 | SHA-256 Hash of the Content Info Records |
Content Info Records[edit]
There are 64 of these records, usually only the first is used.
Offset | Size | Description |
---|---|---|
0x00 | 2 | Content index offset |
0x02 | 2 | Content command count [k] |
0x04 | 0x20 | SHA-256 hash of the next k content records that have not been hashed yet |
Content chunk records[edit]
There is one of these for each content contained in this title. (Determined by "Content Count" in the TMD Header).
Offset | Size | Description |
---|---|---|
0x00 | 4 | Content id |
0x04 | 2 | Content index |
0x06 | 2 | Content type |
0x08 | 8 | Content size |
0x10 | 0x20 | SHA-256 hash |
Content Index[edit]
This indicates the content type:
Index | Content Type |
---|---|
0000 | Main Content (.CXI for 3DS executable content/.CFA for 3DS Data Archives/.SRL for TWL content) |
0001 | Home Menu Manual (.CFA) |
0002 | DLP Child Container (.CFA) |
This does not apply to DLC.
Content Type flags[edit]
Flags | Description |
---|---|
1 | Encrypted |
2 | Disc |
4 | CFM (abbreviation for?) |
0x4000 | Optional |
0x8000 | Shared |
Certificate Chain[edit]
If the TMD file is obtained from Nintendo's CDN, then it will have two certificates appended at the end of the file:
CERTIFICATE | SIGNATURE TYPE | RETAIL CERT NAME | DEBUG CERT NAME | DESCRIPTION |
---|---|---|---|---|
TMD | RSA-2048 | CP0000000b | CP0000000a | Used to verify the TMD signature |
CA | RSA-4096 | CA00000003 | CA00000004 | Used to verify the TMD Certificate |
The CA certificate is issued by 'Root', the public key for which is stored in NATIVE_FIRM.
Example code application[edit]
enum sig_type {
RSA_2048_SHA256 = 0x00010004,
RSA_4096_SHA256 = 0x00010003,
RSA_2048_SHA1 = 0x00010001,
RSA_4096_SHA1 = 0x00010000
};
// Sorry I removed the example struct because it is wrong.