Changes

4,934 bytes added ,  17:23, 31 December 2023
m
Add clarification for what TMD is
Line 1: Line 1:  
[[Category:File formats]]
 
[[Category:File formats]]
=== Overview ===
+
== Overview ==
CIA stands for '''C'''TR '''I'''mportable '''A'''rchive. These files contain a compiled application which can be installed on CTR NAND, TWL NAND (part of the NAND used by DSi applications) and on the SD card.
+
CIA stands for '''C'''TR '''I'''mportable '''A'''rchive. This format allows the installation of titles to the 3DS. CIA files and titles on [[Title list|Nintendo's CDN]] contain identical data. As a consequence, valid CIA files can be generated from CDN content. This also means CIA files can contain anything that titles on Nintendo's CDN can contain.  
   −
An example .CIA can be downloaded here [http://www.multiupload.com/5CJ2QQPOWE] Credit: [[User:Jl12|Jl12]]. It includes a .cia file, the .cia file in its extracted form, a screenshot of the application working and some information given by the 3DS.
+
Under normal circumstances CIA files are used where downloading a title is impractical or not possible. Such as distributing a [[Download Play]] child, or installing forced Gamecard updates. Those CIA(s) are stored by the titles in question, in an auxiliary [[NCCH#CFA|CFA]] file.
 +
 
 +
Development Units, are capable of manually installing CIA files via the [[3DS Development Unit Software#Dev Menu|Dev Menu]].
 +
 
 +
== Format ==
 +
 
 +
This is the current version of the CIA format, it was finalised in late 2010. (Older versions of the CIA format can be viewed on the [[Talk:CIA|Talk]] page)
   −
=== Format ===
   
The CIA format has a similar structure to the [http://wiibrew.org/wiki/Wad WAD format].
 
The CIA format has a similar structure to the [http://wiibrew.org/wiki/Wad WAD format].
   Line 12: Line 17:  
The data is aligned in 64 byte blocks (if a content ends at the middle of the block, the next content will begin from a new block).
 
The data is aligned in 64 byte blocks (if a content ends at the middle of the block, the next content will begin from a new block).
   −
== CIA Header ==
+
=== CIA Header ===
 
  −
This is a 32 bytes long header (8 x uint32).
      
{| class="wikitable" border="1"
 
{| class="wikitable" border="1"
Line 24: Line 27:  
|  0x00
 
|  0x00
 
|  0x04  
 
|  0x04  
|  Archive Header Size (=0x2020 bytes) (Starts with 0x80 @ offset 0x0020)
+
|  Archive Header Size (Usually = 0x2020 bytes)
 
|-
 
|-
 
|  0x04
 
|  0x04
Line 40: Line 43:  
|  0x0C       
 
|  0x0C       
 
|  0x04
 
|  0x04
|  Ticket size
+
[[Ticket]] size
 
|-
 
|-
 
|  0x10     
 
|  0x10     
 
|  0x04
 
|  0x04
|  [[TMD]] file size
+
|  [[TMD]] (Title Metadata) file size
 
|-
 
|-
 
|  0x14     
 
|  0x14     
 
|  0x04
 
|  0x04
Icon size (0 if no icon)
+
Meta size (0 if no Meta data is present)
 
|-
 
|-
 
|  0x18     
 
|  0x18     
0x04
+
0x08
APP file size
+
Content size
 
|-
 
|-
0x1C
+
0x20
0x04
+
0x2000
0x80000000
+
Content Index
 
|}
 
|}
   −
The order of the sections in the header also is the order of them in the CIA file:
+
The order of the sections in the CIA file:
 
* certificate chain
 
* certificate chain
 
* Ticket
 
* Ticket
 
* TMD file data
 
* TMD file data
* APP file data
+
* Content file data
* Icon
+
* Meta file data (Not a necessary component)
The APP data can be either encrypted or cleartext, retail [[Download Play]] CIAs' APP data is always encrypted.
+
 
 +
The contents (NCCH/SRL) are encrypted using 128-bit AES-CBC. The encryption uses the decrypted titlekey from the [[Ticket#Structure|ticket]], and the content index from the TMD padded with zeros as the IV.
 +
 
 +
=== Certificate Chain ===
 +
 
 +
There are three [[Certificates|certificates]] in this chain:
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
!  CERTIFICATE
 +
!  SIGNATURE TYPE
 +
!  RETAIL CERT NAME
 +
!  DEBUG CERT NAME
 +
!  DESCRIPTION
 +
|-
 +
|  CA
 +
|  RSA-4096
 +
|  CA00000003
 +
|  CA00000004
 +
|  Used to verify the Ticket/TMD Certificates
 +
|-
 +
|  Ticket
 +
|  RSA-2048
 +
|  XS0000000c
 +
|  XS00000009
 +
|  Used to verify the Ticket signature
 +
|-
 +
|  TMD
 +
|  RSA-2048
 +
|  CP0000000b
 +
|  CP0000000a
 +
|  Used to verify the TMD signature
 +
|}
 +
 
 +
The CA certificate is issued by 'Root', the public key for which is stored in NATIVE_FIRM.
 +
 
 +
=== Meta ===
 +
 
 +
The structure of this data is as follows:
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
!  START
 +
!  SIZE
 +
!  DESCRIPTION
 +
|-
 +
|  0x00
 +
|  0x180
 +
|  Title ID dependency list - Taken from the application's [[NCCH/Extended Header|ExHeader]]
 +
|-
 +
|  0x180
 +
|  0x180
 +
|  Reserved
 +
|-
 +
|  0x300
 +
|  0x4
 +
|  Core Version
 +
|-
 +
|  0x304
 +
|  0xFC
 +
|  Reserved
 +
|-
 +
|  0x400
 +
|  0x36C0
 +
|  [[SMDH|Icon Data]](.ICN) - Taken from the application's [[ExeFS]]
 +
|}
 +
 
 +
Obviously this section is not present in TWL CIA files, or any other CIA file which does not contain a [[NCCH#CXI|CXI]].
 +
 
 +
== Tools ==
 +
 
 +
* [https://github.com/3dshax/ctr/tree/master/ctrtool ctrtool] - Reading/Extraction of CIA files. This can only decrypt the title-key for development CIAs, since retail CIAs use the [[AES]] hardware key-scrambler for the common-key keyslot.
 +
 
 +
* [https://github.com/Tiger21820/ctr_toolkit/tree/master/make_cia make_cia] - Generating CIA files. Requires CommonKey and ticket/TMD RSA-2048 private exponents.
 +
 
 +
* [https://github.com/Tiger21820/ctr_toolkit/tree/master/make_cdn_cia make_cdn_cia] - (CMD)(Windows/Linux) Generates CIA files from CDN Content
 +
 
 +
* [[makerom]] - Tool which can be used to create NCCH, CCI, and CIA files.
 +
 
 +
== Title Key Encryption ==
 +
 
 +
The unencrypted Title Key is used to encrypt the data in a CIA. The encrypted Title Key of a CIA can be found at offset 0x1BF in a CIA's Ticket.
 +
Each Title Key is encrypted with AES-CBC to get the encrypted Title Key.
 +
 
 +
To encrypt an unencrypted title key, you need:
 +
 
 +
* Common key (as byte array)
 +
* Title ID (as ulong)
 +
* (and of course the unencrypted title key you want to encrypt) (as byte array)
 +
 
 +
The title key encryption process starts by converting the ulong (Title ID) into a byte array using by retrieving the bytes of the Title ID using BitConverter.GetBytes().
 +
If the converted bytes (title ID) are in Little Endian, reverse those bytes. (in C# it would be Array.Reverse(byte_array_from_bitconverter))
 +
This process makes the Title Key encryption IV.
 +
 
 +
Next, after you've gotten your Title Key's IV, you can start your cryptography transformation. Using AESManaged, where:
 +
 
 +
Key  = Common Key
 +
 
 +
IV  = the byte array found in the conversion process above
 +
 
 +
Mode = CipherMode.CBC
 +
 
 +
Create the encryptor (AesManaged.CreateEncryptor(key, iv)) where the key and IV are both the same as above.
 +
 
 +
Then, create a CryptoStream and a MemoryStream. The Crypto stream should start with the arguments (memorystream, aes_transform_from_above, CryptoStreamMode.Write).
 +
 
 +
Write to the CryptoStream where buffer=unencrypted_titlekey, offset=0, and count=the length of the unencrypted title key.
 +
 
 +
Use FlushFinalBlock() on the CryptoStream.
 +
 
 +
Finally, then, the encrypted title key will be available from your memory
 +
stream. (to output the calculated encrypted title key as a byte array, you can use memorystream.ToArray(), for example)
 +
 
 +
Example function: (C#)
   −
== Icon ==
+
<pre>
The actual [[SMDH|icon]] is located at offset 0x400 in the icon data.
+
        public static byte[] EncryptMyTitleKey(byte[] commonKey, byte[] titleKey, ulong titleId)
 +
        {
 +
            // Make encryption IV
 +
            byte[] titleidasbytes = new byte[0x10];
 +
            for (int i = 0; i < 0x10; i++)
 +
            {
 +
                titleidasbytes[i] = 0;
 +
            }
 +
            byte[] bitBytes = BitConverter.GetBytes(titleId);
 +
            if (BitConverter.IsLittleEndian)
 +
            {
 +
                Array.Reverse(bitBytes);
 +
            }
 +
            bitBytes.CopyTo(titleidasbytes, 0);
 +
            // Encrypt
 +
            ICryptoTransform transform = new AesManaged { Key = commonKey, IV = titleidasbytes, Mode = CipherMode.CBC }.CreateEncryptor(commonKey, titleidasbytes);
 +
            MemoryStream memstream = new MemoryStream();
 +
            CryptoStream cryptostream = new CryptoStream(memstream, transform, CryptoStreamMode.Write);
 +
            cryptostream.Write(titleKey, 0, titleKey.Length);
 +
            cryptostream.FlushFinalBlock();
 +
            return memstream.ToArray();
 +
        }
 +
</pre>