Changes

2,062 bytes added ,  14:22, 28 July 2020
note discrepancy in endianness
Line 1: Line 1: −
'''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.
+
[[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.
   −
[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, 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;"|'''Start'''
+
| align="center" style="background:#f0f0f0;"|'''Offset'''
| align="center" style="background:#f0f0f0;"|''' '''
+
| align="center" style="background:#f0f0f0;"|'''Size'''
| align="center" style="background:#f0f0f0;"|'''Length'''
   
| align="center" style="background:#f0f0f0;"|'''Description'''
 
| align="center" style="background:#f0f0f0;"|'''Description'''
 
|-
 
|-
| ''RSA 2048''||''RSA 4096''||||
+
| 0x0||0x40||Signature Issuer
 
|-
 
|-
| 0x000||0x000||4||Signature type
+
| 0x40||0x1||Version
 
|-
 
|-
| 0x004||0x004||256 / 512||Signature
+
| 0x41||0x1||ca_crl_version
 
|-
 
|-
| 0x104||0x204||60||Padding modulo 64
+
| 0x42||0x1||signer_crl_version
 
|-
 
|-
| 0x140||0x240||64||Issuer
+
| 0x43||0x1||Reserved
 
|-
 
|-
| 0x180||0x280||1||Version
+
| 0x44||0x8||System Version
 
|-
 
|-
| 0x181||0x281||1||ca_crl_version
+
| 0x4C||0x8||Title ID
 
|-
 
|-
| 0x182||0x282||1||signer_crl_version
+
| 0x54||0x4||Title Type
 
|-
 
|-
| 0x183||0x283||1||Padding modulo 64
+
| 0x58||0x2||Group ID
 
|-
 
|-
| 0x184||0x284||8||System Version
+
| 0x5A||0x4||Save Data Size in Little Endian (Bytes) (Also SRL Public Save Data Size)
 
|-
 
|-
| 0x18C||0x28C||8||Title ID
+
| 0x5E||0x4||SRL Private Save Data Size in Little Endian (Bytes)
 
|-
 
|-
| 0x194||0x294||4||Title type
+
| 0x62||0x4||Reserved
 
|-
 
|-
| 0x198||0x298||2||Group ID
+
| 0x66||0x1||SRL Flag
 
|-
 
|-
| 0x19A||0x29A||62||reserved
+
| 0x67||0x31||Reserved
 
|-
 
|-
| 0x1D8||0x2D8||4||Access rights
+
| 0x98||0x4||Access Rights
 
|-
 
|-
| 0x1DC||0x2DC||2||Title version
+
| 0x9C||0x2||Title Version
 
|-
 
|-
| 0x1DE||0x2DE||2||Number of contents (contcount)
+
| 0x9E||0x02||Content Count
 
|-
 
|-
| 0x1E0||0x2E0||2||Boot content
+
| 0xA0||0x2||Boot Content
 
|-
 
|-
| 0x204||0x304||36*64||Content info records
+
| 0xA2||0x2||Padding
 
|-
 
|-
| 0xB04||0xC04||48*contcount|| Content chunk records
+
| 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"
 
|-
 
|-
! Start
+
! Offset
! Length
+
! Size
 
! Description
 
! Description
 
|-
 
|-
Line 65: Line 106:  
| 0x02
 
| 0x02
 
| 2
 
| 2
| Content command count
+
| Content command count [k]
 
|-
 
|-
 
| 0x04
 
| 0x04
| 32
+
| 0x20
| SHA-256 hash? Commands?
+
| 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"
 
|-
 
|-
! Start
+
! Offset
! Length
+
! Size
 
! Description
 
! Description
 
|-
 
|-
Line 96: Line 139:  
|-
 
|-
 
| 0x10
 
| 0x10
| 32
+
| 0x20
 
| SHA-256 hash
 
| 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]])
 
|}
 
|}
   −
=== Certificates ===
+
This does not apply to DLC.
 +
 
 +
==== Content Type flags ====
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! Start
+
! Flags
! Length
   
! Description
 
! Description
 
|-
 
|-
| 0x000
+
| 1
 +
| Encrypted
 +
|-
 +
| 2
 +
| Disc
 +
|-
 
| 4
 
| 4
| Signature type
+
| CFM (abbreviation for?)
 
|-
 
|-
| 0x004
+
| 0x4000
| *
+
| Optional
| Signature
   
|-
 
|-
| 0x104
+
| 0x8000
| 64
+
| Shared
| Issuer
+
|}
 +
 
 +
== 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"
 
|-
 
|-
| 0x124
+
!  CERTIFICATE
| 4
+
!  SIGNATURE TYPE
| Tag
+
!  RETAIL CERT NAME
 +
!  DEBUG CERT NAME
 +
!  DESCRIPTION
 
|-
 
|-
| 0x128
+
| TMD
| 64
+
| RSA-2048
| Name
+
| CP0000000b
 +
|  CP0000000a
 +
|  Used to verify the TMD signature
 
|-
 
|-
| 0x168
+
| CA
|  
+
| RSA-4096
| Key
+
| 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 ==
46

edits