Line 1: |
Line 1: |
| [[Category:File formats]] | | [[Category:File formats]] |
− | '''Title metadata''' is a format used to store information about a title (a single standalone game, channel, etc.) and all its installed contents, including which contents they consist of and their SHA1 hashes. | + | '''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. |
| | | |
− | [http://git.daifukkat.su/?p=3dshax.git Code is available] by trap15 to parse the available information from the 3DS format of TMDs. | + | [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. | + | All the data in the file represented in Big Endian, unless otherwise noted. |
| | | |
− | === Header ===
| |
| {| class="wikitable" | | {| class="wikitable" |
| | align="center" style="background:#f0f0f0;"|'''Offset''' | | | align="center" style="background:#f0f0f0;"|'''Offset''' |
− | | align="center" style="background:#f0f0f0;"|''' '''
| |
| | align="center" style="background:#f0f0f0;"|'''Size''' | | | align="center" style="background:#f0f0f0;"|'''Size''' |
| | align="center" style="background:#f0f0f0;"|'''Description''' | | | align="center" style="background:#f0f0f0;"|'''Description''' |
| |- | | |- |
− | | ''RSA 2048''||''RSA 4096''|||| | + | | 0x0||Y||Signature Data |
| |- | | |- |
− | | 0x000||0x000||4||Signature type | + | | Y ||0xC4||Header |
| |- | | |- |
− | | 0x004||0x004||256 / 512||Signature | + | | 0xC4 + Y||0x24*64||Content Info Records. |
| |- | | |- |
− | | 0x104||0x204||60||Padding modulo 64 | + | | 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''' |
| |- | | |- |
− | | 0x140||0x240||64||Issuer | + | | 0x0||0x4||Signature Type |
| |- | | |- |
− | | 0x180||0x280||1||Version | + | | 0x4 ||X||Signature |
| |- | | |- |
− | | 0x181||0x281||1||ca_crl_version | + | | 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 === |
| + | |
| + | {| class="wikitable" |
| + | | align="center" style="background:#f0f0f0;"|'''Offset''' |
| + | | align="center" style="background:#f0f0f0;"|'''Size''' |
| + | | align="center" style="background:#f0f0f0;"|'''Description''' |
| |- | | |- |
− | | 0x182||0x282||1||signer_crl_version | + | | 0x0||0x40||Signature Issuer |
| |- | | |- |
− | | 0x183||0x283||1||Padding modulo 64 | + | | 0x40||0x1||Version |
| |- | | |- |
− | | 0x184||0x284||8||System Version | + | | 0x41||0x1||ca_crl_version |
| |- | | |- |
− | | 0x18C||0x28C||8||Title ID | + | | 0x42||0x1||signer_crl_version |
| |- | | |- |
− | | 0x194||0x294||4||Title type | + | | 0x43||0x1||Reserved |
| |- | | |- |
− | | 0x198||0x298||2||Group ID | + | | 0x44||0x8||System Version |
| |- | | |- |
− | | 0x19A||0x29A||62||reserved | + | | 0x4C||0x8||Title ID |
| |- | | |- |
− | | 0x1D8||0x2D8||4||Access rights | + | | 0x54||0x4||Title Type |
| |- | | |- |
− | | 0x1DC||0x2DC||2||Title version | + | | 0x58||0x2||Group ID |
| |- | | |- |
− | | 0x1DE||0x2DE||2||Number of contents (contcount) | + | | 0x5A||0x4||Save Data Size in Little Endian (Bytes) (Also SRL Public Save Data Size) |
| |- | | |- |
− | | 0x1E0||0x2E0||2||Boot content | + | | 0x5E||0x4||SRL Private Save Data Size in Little Endian (Bytes) |
| |- | | |- |
− | | 0x1E2||0x2E2||2||Padding | + | | 0x62||0x4||Reserved |
| |- | | |- |
− | | 0x1E4||0x2E4||32||SHA-256 hash of the 36*64 byte long content info record blob (next field) | + | | 0x66||0x1||SRL Flag |
| |- | | |- |
− | | 0x204||0x304||36*64||Content info records | + | | 0x67||0x31||Reserved |
| |- | | |- |
− | | 0xB04||0xC04||48*contcount|| Content chunk records | + | | 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 === | + | === Content Info Records === |
| + | |
| + | There are 64 of these records, usually only the first is used. |
| + | |
| {| class="wikitable" | | {| class="wikitable" |
| |- | | |- |
Line 76: |
Line 109: |
| |- | | |- |
| | 0x04 | | | 0x04 |
− | | 32 | + | | 0x20 |
| | SHA-256 hash of the next k content records that have not been hashed yet | | | SHA-256 hash of the next k content records that have not been hashed yet |
| |} | | |} |
| | | |
| === Content chunk records === | | === 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" |
| |- | | |- |
Line 104: |
Line 139: |
| |- | | |- |
| | 0x10 | | | 0x10 |
− | | 32 | + | | 0x20 |
| | SHA-256 hash | | | SHA-256 hash |
| |} | | |} |
| + | ==== Content Index ==== |
| + | |
| + | This indicates the content type: |
| | | |
− | === Content type flags === | + | {| 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" |
| |- | | |- |
Line 130: |
Line 185: |
| |} | | |} |
| | | |
− | === Certificates === | + | == Certificate Chain == |
− | {| class="wikitable" | + | If the TMD file is obtained from Nintendo's CDN, then it will have two [[Certificates|certificates]] appended at the end of the file: |
− | |-
| + | |
− | ! Offset
| + | {| class="wikitable" border="1" |
− | ! Size
| |
− | ! Description
| |
| |- | | |- |
− | | 0x000
| + | ! CERTIFICATE |
− | | 4
| + | ! SIGNATURE TYPE |
− | | Signature type
| + | ! RETAIL CERT NAME |
| + | ! DEBUG CERT NAME |
| + | ! DESCRIPTION |
| |- | | |- |
− | | 0x004 | + | | TMD |
− | | * | + | | RSA-2048 |
− | | Signature | + | | CP0000000b |
| + | | CP0000000a |
| + | | Used to verify the TMD signature |
| |- | | |- |
− | | 0x104 | + | | CA |
− | | 64
| + | | RSA-4096 |
− | | Issuer
| + | | CA00000003 |
− | |-
| + | | CA00000004 |
− | | 0x124
| + | | Used to verify the TMD Certificate |
− | | 4
| |
− | | Tag
| |
− | |-
| |
− | | 0x128
| |
− | | 64
| |
− | | Name
| |
− | |- | |
− | | 0x168 | |
− | | | |
− | | Key | |
| |} | | |} |
| + | |
| + | The CA certificate is issued by 'Root', the public key for which is stored in NATIVE_FIRM. |
| | | |
| == Example code application == | | == Example code application == |