NCSD: Difference between revisions

Myria (talk | contribs)
Development Card Info Header Extension: filled in a bunch of missing pieces
InitialData: Fix struct being too large caused by having redundant data
 
(5 intermediate revisions by 3 users not shown)
Line 237: Line 237:
|-
|-
|  0x1000
|  0x1000
|  0x200
|  InitialData
|}
=== InitialData ===
This data is returned by [[Gamecards|16-byte cartridge command]] 0x82.
{| class="wikitable" border="1"
|-
!  OFFSET
!  SIZE
!  DESCRIPTION
|-
|  0x00
|  0x10
|  0x10
Card seed keyY (first u64 is Media ID (same as first NCCH partitionId))
Seed (keyY used to decrypt the title key - keyX is keyslot 0x3B for production cards, or a key of all zeroes for development cards), consisting of the title ID (little-endian) followed by reserved data (normally all-zero)
|-
|-
|  0x1010
|  0x10
|  0x10
Encrypted card seed (AES-CCM, keyslot 0x3B for retail cards, see [[CTRCARD_Registers|CTRCARD_SECSEED]])
0x10
|  TitleKey (AES-CCM encrypted)
|-
|-
0x1020
0x20
|  0x10
|  0x10
Card seed AES-MAC
|  AES-CCM MAC
|-
|-
0x1030
0x30
|  0xC
|  0xC
Card seed nonce
AES-CCM nonce
|-
|-
0x103C
0x3C
|  0xC4
|  0xC4
Reserved3
Reserved (normally all-zero)
|-
|-
|  0x1100
|  0x100
|  0x100
Copy of first NCCH header (excluding RSA signature)
0x100
|  NcchHeader (copy of the first NCCH header, excluding the RSA signature)
|}
|}


Line 274: Line 289:
|  0x1400
|  0x1400
|  0x10
|  0x10
TitleKey
TitleKeyData
|-
|-
|  0x1410
|  0x1410
0xF0
0x1BF0
|  CardDeviceReserved2
|  CardDeviceReserved2
|-
|  0x3000
|  0x1000
|  TestData
|}
|}


== Development Card Info Header Extension ==
TitleKeyData contains the decrypted version of the title key found in the InitialData. This field appears to be what development--and maybe production?--cards read to know what card encryption seed to use in the CTR protocol.
 
The CardDeviceReserved areas have random-looking data whose purpose is unknown, other than perhaps to hide the TitleKey.
 
Note that a particular flashcard vendor, namely Gateway, puts what many refer to as "private headers" at CardDeviceReserved1 in place of actual development card information. This header consists of:
 
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
Line 288: Line 312:
!  DESCRIPTION
!  DESCRIPTION
|-
|-
0x1200
0x0
0x200
0x40
CardDeviceReserved1
Unique cartridge ID; only the first 0x10 bytes are meaningful, the rest are 0xff; obtainable using encrypted [[Gamecards|16-byte cartridge command]] 0xc6; the first 0x10 bytes can also be obtained in userland via [[Process_Services_PXI|pxi:ps9::GetRomId]]
|-
|  0x1400
0x10
| TitleKey
|-
|-
0x1410
0x40
0xF0
0x4
CardDeviceReserved2
Cartridge ID1; obtainable using 8-byte cartridge command 0x90 or 16-byte cartridge command 0xa2
|-
|-
0x1500
0x44
0x1B00
0x4
CardDeviceReserved3
Cartridge ID2; obtainable using 8-byte cartridge command 0xa0 or 16-byte cartridge command 0xa4
|-
|-
0x3000
0x48
0x1000
0x8
Test pattern
Padding (all-0xff)
|}
|}


"TitleKey" is the decrypted version of the title key at 0x1000-0x103B ("Encrypted card seed").  This field appears to be what development--and maybe retail?--cards read to know what card encryption seed to use in the CTR protocol.
The legitimacy of the unique cartridge ID can be validated by online services.


Note that a particular flashcard vendor puts what many refer to as "private headers" here in place of actual development card information. This header is constituted by a cartridge-unique Id obtained from [[Process_Services_PXI|pxi:ps9::GetRomId]] and the title-unique cart ID (identical for all carts of the same title; can be retrieved using the NTR gamecard protocol command 0x90 or through the CTR protocol commands 0x90 or 0xA2).
Some dumping tools, notably GodMode9 as of 2024-05-26, erroneously always write 0x00000000 into the position of the Cartridge ID2. This is presumably because the cartridge ID2 is always zero for retail carts.
 
The CardDeviceReserved areas have random-looking data whose purpose is unknown, other than perhaps to hide the TitleKey.
 
The test pattern is the same one encountered in development DS/DSi cartridges. Its layout is as follows:


=== TestData ===
The test data is the same one encountered in development DS/DSi cartridges. Its layout is as follows:
{| class="wikitable" border="1"
{| class="wikitable" border="1"
|-
|-
Line 323: Line 341:
!  DESCRIPTION
!  DESCRIPTION
|-
|-
0x3000
0x0
8
0x8
|  The bytes FF,00,FF,00,AA,55,AA,55.
|  The bytes FF 00 FF 00 AA 55 AA 55.
|-
|-
0x3008
0x8
|  0x1F8
|  0x1F8
|  An ascending byte sequence equal to the offset mod 256 (08,09,0A, ..., FE,FF,00,01, ..., FF).
|  An ascending byte sequence equal to the offset mod 256 (08 09 0A ... FE FF 00 01 ... FF).
|-
|-
|  0x3200
|  0x200
|  0x200
|  A descending byte sequence equal to 255 minus the offset mod 256 (FF,FE,FD, ..., 00,FF,DE, ..., 00).
|  0x200
|  A descending byte sequence equal to 255 minus the offset mod 256 (FF FE FD ... 00 FF DE ... 00).
|-
|-
0x3400
0x400
|  0x200
|  0x200
|  Filled with 00 bytes.
|  Filled with 00 (0b00000000) bytes.
|-
|-
0x3600
0x600
|  0x200
|  0x200
|  Filled with FF bytes.
|  Filled with FF (0b11111111) bytes.
|-
|-
0x3800
0x800
|  0x200
|  0x200
|  Filled with 0F bytes.
|  Filled with 0F (0b00001111) bytes.
|-
|-
0x3A00
0xA00
|  0x200
|  0x200
|  Filled with F0 bytes.
|  Filled with F0 (0b11110000) bytes.
|-
|-
0x3C00
0xC00
|  0x200
|  0x200
|  Filled with 55 bytes.
|  Filled with 55 (0b01010101) bytes.
|-
|-
0x3E00
0xE00
|  0x1FF
|  0x1FF
|  Filled with AA bytes.
|  Filled with AA (0b10101010) bytes.
|-
|-
0x3FFF
0xFFF
1
0x1
|  The final byte is a 00.
|  The final byte is 00 (0b00000000).
|}
|}


Retail cards always return FF when attempting to read 0x1200-0x3FFF. They probably actually have the same data as development cards, but there's no way to read it.
Production cards always return FF when attempting to read 0x1200-0x3FFF. They probably actually have the same data as development cards, but there's no way to read it.


== Tools ==
== Tools ==