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> |