Difference between revisions of "Ticket"

From 3dbrew
Jump to navigation Jump to search
(Created page with "Category:File formats Tickets are a format used to store an encrypted titlekey (using 128-Bit AES-CBC). This format seems to be identical to DSi/Wii tickets. == Structure =...")
 
(Content Index doesn't have a fixed size.)
 
(18 intermediate revisions by 4 users not shown)
Line 1: Line 1:
 
[[Category:File formats]]
 
[[Category:File formats]]
Tickets are a format used to store an encrypted titlekey (using 128-Bit AES-CBC). This format seems to be identical to DSi/Wii tickets.  
+
Tickets are a format used to store an encrypted titlekey (using 128-Bit AES-CBC). With 3DS, the Ticket format was updated (now v1) from Wii/DSi format (v0).
  
 
== Structure ==
 
== Structure ==
Line 15: Line 15:
 
| Y||0x210||Ticket Data
 
| Y||0x210||Ticket Data
 
|}
 
|}
 +
 +
Y denotes the total size of the "Signature Data" section and depends on the signature type.
  
 
=== Signature Data ===
 
=== Signature Data ===
The total size of this section is referred to as "Y" in the overall TMD structure. The signature is of the header of the TMD.
+
The signature is of the ticket header.
 
{| class="wikitable"
 
{| class="wikitable"
 
| align="center" style="background:#f0f0f0;"|'''Offset'''
 
| align="center" style="background:#f0f0f0;"|'''Offset'''
Line 27: Line 29:
 
| 0x4 ||X||Signature
 
| 0x4 ||X||Signature
 
|-
 
|-
| 0x4 + X|| ||Padding Aligning the signature data to 0x40 bytes
+
| 0x4 + X|| ||Padding to align the signature data to 0x40 bytes
 
|}
 
|}
  
Line 43: Line 45:
 
| 0x0||0x40||Issuer
 
| 0x0||0x40||Issuer
 
|-
 
|-
| 0x40||0x3C||ECDH data for console-unique eShop tickets.
+
| 0x40||0x3C||ECC PublicKey
 
|-
 
|-
| 0x7C||0x3||Unknown, first u8 is 0x01.
+
| 0x7C||0x1||Version (For 3DS this is always 1)
 
|-
 
|-
| 0x7F||0x10||Encrypted TitleKey
+
| 0x7D||0x1||CaCrlVersion
 
|-
 
|-
| 0x8F||0x1||Unknown
+
| 0x7E||0x1||SignerCrlVersion
 +
|-
 +
| 0x7F||0x10||TitleKey (normal-key encrypted using one of the common keyYs; see below)
 +
|-
 +
| 0x8F||0x1||Reserved
 
|-
 
|-
 
| 0x90||0x8||TicketID
 
| 0x90||0x8||TicketID
 
|-
 
|-
| 0x98||0x4||Ticket consoleID
+
| 0x98||0x4||ConsoleID
 
|-
 
|-
 
| 0x9C||0x8||TitleID
 
| 0x9C||0x8||TitleID
 
|-
 
|-
| 0xA4||0x2||Unknown
+
| 0xA4||0x2||Reserved
 
|-
 
|-
| 0xA6||0x2||Ticket title version, this title version is also stored in the [[TMD]].
+
| 0xA6||0x2||Ticket title version
 
|-
 
|-
| 0xA8||0x8||Unused
+
| 0xA8||0x8||Reserved
 
|-
 
|-
| 0xB0||0x1||Unused
+
| 0xB0||0x1||License Type
 
|-
 
|-
| 0xB1||0x1||Ticket common [[AES|keyY]] index, usually 0x1 for retail system titles.
+
| 0xB1||0x1||Index to the common [[AES|keyY]] used for this ticket, usually 0x1 for retail system titles; see below.
 
|-
 
|-
| 0xB2||0x2F||Unused
+
| 0xB2||0x2A||Reserved
 
|-
 
|-
| 0xE1||0x1||Unknown
+
| 0xDC||0x4||eShop Account ID?
 
|-
 
|-
| 0xE2||0x82||Unused
+
| 0xE0||0x1||Reserved
 
|-
 
|-
| 0x164||0x30||Unknown
+
| 0xE1||0x1||Audit
 
|-
 
|-
| 0x194||0x7C||Unused
+
| 0xE2||0x42||Reserved
 +
|-
 +
| 0x124||0x40||Limits
 +
|-
 +
| 0x164||X||Content Index
 
|}
 
|}
  
The Signature Type is the same const as that in [[TMD]].
+
* For v0 of the format, see [[Talk:Ticket#Ticket_Format_0|here]]
 +
 
 +
* The Ticket Title Version is generally the same as the title version stored in the [[TMD|Title Metadata]]. Although it doesn't have to match the TMD version to be valid.
 +
 
 +
* The titlekey is decrypted by using the [[AES]] engine with the ticket common-key keyslot. The keyY is selected through an index (ticket offset 0xB1) into a plaintext array of 6 keys ("common keyYs") stored in the data section of Process9. AES-CBC mode is used where the IV is the big-endian titleID. Note that on a retail unit index0 is a retail keyY, while on a dev-unit index0 is the dev common-key which is a normal-key. (On retail for these keyYs, the hardware key-scrambler is used)
 +
 
 +
* The titlekey is used to decrypt content downloaded from the CDN using 128-bit AES-CBC with the content index (as big endian u16, padded with trailing zeroes) as the IV.
 +
 
 +
* In demos, the first u32 in the "Limits" section is 0x4, then the second u32 is the max-playcount.
  
The titlekey is decrypted by using the [[AES]] engine with the ticket common-key keyslot where the keyY is one of 6 keyYs loaded via the keyY index stored in the ticket. AES-CBC mode is used where the IV is the big-endian titleID. Note that on a retail unit index0 is a retail keyY, while on a dev-unit index0 is the dev common-key which is a normal-key.(On retail for these keyYs, the hardware key-scrambler is used)
+
* The Content Index of a ticket has its own size defined within itself, with seemingly a minimal of 20 bytes, the second u32 in big endian defines the full value of X.  
  
 
== Certificate Chain ==
 
== Certificate Chain ==
Line 109: Line 127:
  
 
== Some facts==
 
== Some facts==
* '''CommonETicket''' (for short, '''cetk''') is the name given to tickets for titles which aren't purchasable, like system titles.
+
* '''CommonETicket''' (for short, '''cetk''') is the name given to tickets for titles which are not available on the [[EShop|eShop]], like [[Title list#CTR System Titles|system titles]]. As the name suggests, they are not unique tickets, the same ticket is common to each 3ds which has installed that title. This is in contrast to tickets for eShop content, which are generated prior to initial download, and are unique to 3ds it was generated for.
  
* '''CETK''' can be fetched through HTTP using the link to default update server, using the title's [[TMD]] URL where "cetk" is used instead of "tmd" for the URL. The 3DS NIM module retrieves system tickets via SOAP request ''GetCommonETicket''.
+
* '''CETK''' can be fetched through HTTP using the link to default update server, using the title's [[TMD]] URL where "cetk" is used instead of "tmd" for the URL. The 3DS NIM module retrieves system tickets via SOAP request ''GetSystemCommonETicket'' instead of directly downloading the cetks with HTTPS. The cetks are also accessible via HTTP (even though the 3DS never accesses them like that).

Latest revision as of 01:42, 14 October 2019

Tickets are a format used to store an encrypted titlekey (using 128-Bit AES-CBC). With 3DS, the Ticket format was updated (now v1) from Wii/DSi format (v0).

Structure[edit]

All of the data in the file is represented in Big Endian.

Offset Size Description
0x000 Y Signature Data
Y 0x210 Ticket Data

Y denotes the total size of the "Signature Data" section and depends on the signature type.

Signature Data[edit]

The signature is of the ticket header.

Offset Size Description
0x0 0x4 Signature Type
0x4 X Signature
0x4 + X Padding to align 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 Ticket Data.

Ticket Data[edit]

Offset Size Description
0x0 0x40 Issuer
0x40 0x3C ECC PublicKey
0x7C 0x1 Version (For 3DS this is always 1)
0x7D 0x1 CaCrlVersion
0x7E 0x1 SignerCrlVersion
0x7F 0x10 TitleKey (normal-key encrypted using one of the common keyYs; see below)
0x8F 0x1 Reserved
0x90 0x8 TicketID
0x98 0x4 ConsoleID
0x9C 0x8 TitleID
0xA4 0x2 Reserved
0xA6 0x2 Ticket title version
0xA8 0x8 Reserved
0xB0 0x1 License Type
0xB1 0x1 Index to the common keyY used for this ticket, usually 0x1 for retail system titles; see below.
0xB2 0x2A Reserved
0xDC 0x4 eShop Account ID?
0xE0 0x1 Reserved
0xE1 0x1 Audit
0xE2 0x42 Reserved
0x124 0x40 Limits
0x164 X Content Index
  • For v0 of the format, see here
  • The Ticket Title Version is generally the same as the title version stored in the Title Metadata. Although it doesn't have to match the TMD version to be valid.
  • The titlekey is decrypted by using the AES engine with the ticket common-key keyslot. The keyY is selected through an index (ticket offset 0xB1) into a plaintext array of 6 keys ("common keyYs") stored in the data section of Process9. AES-CBC mode is used where the IV is the big-endian titleID. Note that on a retail unit index0 is a retail keyY, while on a dev-unit index0 is the dev common-key which is a normal-key. (On retail for these keyYs, the hardware key-scrambler is used)
  • The titlekey is used to decrypt content downloaded from the CDN using 128-bit AES-CBC with the content index (as big endian u16, padded with trailing zeroes) as the IV.
  • In demos, the first u32 in the "Limits" section is 0x4, then the second u32 is the max-playcount.
  • The Content Index of a ticket has its own size defined within itself, with seemingly a minimal of 20 bytes, the second u32 in big endian defines the full value of X.

Certificate Chain[edit]

Tickets retrieved from CDN/SOAP have a certificate chain appended at the end of the file. There are two certificates in this chain:

CERTIFICATE SIGNATURE TYPE RETAIL CERT NAME DEBUG CERT NAME DESCRIPTION
Ticket RSA-2048 XS0000000c XS00000009 Used to verify the Ticket signature
CA RSA-4096 CA00000003 CA00000004 Used to verify the Ticket Certificate

The CA certificate is issued by 'Root', the public key for which is stored in NATIVE_FIRM.

Some facts[edit]

  • CommonETicket (for short, cetk) is the name given to tickets for titles which are not available on the eShop, like system titles. As the name suggests, they are not unique tickets, the same ticket is common to each 3ds which has installed that title. This is in contrast to tickets for eShop content, which are generated prior to initial download, and are unique to 3ds it was generated for.
  • CETK can be fetched through HTTP using the link to default update server, using the title's TMD URL where "cetk" is used instead of "tmd" for the URL. The 3DS NIM module retrieves system tickets via SOAP request GetSystemCommonETicket instead of directly downloading the cetks with HTTPS. The cetks are also accessible via HTTP (even though the 3DS never accesses them like that).