Difference between revisions of "NCSD"

From 3dbrew
Jump to navigation Jump to search
(→‎NCSD header: fixed bad reserved size and offset)
(34 intermediate revisions by 8 users not shown)
Line 3: Line 3:
  
 
== Overview ==
 
== Overview ==
There are two known specialisations of the NCSD container format. The CTR Cart Image (CCI) format and the CTR System Update (CSU). CCI is the format of retail game ROM dumps. CSU is used with developer system updates and tools
+
There are two known specialisations of the NCSD container format. The CTR Cart Image (CCI) format and the 3DS' raw [[Flash Filesystem#NAND structure|NAND format]]. CCI is the format of game ROM images.
  
NCSD images start with a NCSD header, followed by up to a maximum of 8 [[NCCH]] partitions. The first partition([[NCCH]] 0) usually starts at 0x4000, this is generally the main [[NCCH#CXI|NCCH]] (Executable). The following info on partitions 1, 2, and 7 are only valid for .CCI. The second partition([[NCCH]] 1) contains the game's Electronic Manual(The partitionID-high for the Instruction Manual .[[NCCH#CFA|CFA]] is always 0x00050000). The third partition([[NCCH]] 2) contains the download play "Child"(The partitionID-high for the .[[NCCH#CFA|CFA]] containing the DLP Child is always 0x00060000). The eighth block([[NCCH]] 7) contains "Update Data"(The partitionID-high for the .[[NCCH#CFA|CFA]] containing the Update Data is always 0x80000000). The format of partitions can be determined from the partition FS flags, while the contents can be determined from the partitions flags.
+
'''CTR System Update (CSU)''' is a variant of CCI, where the only difference is in the file extension. This is used with developer System Updates and associated [[3DS Development Unit Software|Tools]].
 +
 
 +
 
 +
NCSD images start with a NCSD header, followed by up to a maximum of 8 [[NCCH]] partitions.
 +
 
 +
For CCI images, the partitions are reserved as follows:
 +
 
 +
{| class="wikitable" border="1"
 +
|-
 +
[[NCCH]] Index
 +
!  Reserved Use
 +
|-
 +
| 0
 +
| Executable Content ([[NCCH#CXI|CXI]])
 +
|-
 +
| 1
 +
| E-Manual ([[NCCH#CFA|CFA]])
 +
|-
 +
| 2
 +
| [[Download Play]] Child container ([[NCCH#CFA|CFA]])
 +
|-
 +
| 6
 +
| New3DS [[System_Update_CFA|Update Data]] ([[NCCH#CFA|CFA]])
 +
|-
 +
| 7
 +
| [[System_Update_CFA|Update Data]] ([[NCCH#CFA|CFA]])
 +
|}
 +
 
 +
The format of partitions can be determined from the partition FS flags (normally these are zero for CCI/CSU NCSD Images).
  
 
== NCSD header ==
 
== NCSD header ==
Line 32: Line 60:
 
|  0x110
 
|  0x110
 
|  8
 
|  8
|  Partitions FS type
+
|  Partitions FS type (0=None, 1=Normal, 3=FIRM, 4=AGB_FIRM save)
 
|-
 
|-
 
|  0x118
 
|  0x118
 
|  8
 
|  8
|  Partitions crypt type  
+
|  Partitions crypt type (each byte corresponds to a partition in the partition table)
 
|-
 
|-
 
|  0x120
 
|  0x120
 
|  0x40=(4+4)*8
 
|  0x40=(4+4)*8
|  Offset & Length partition table
+
|  Offset & Length partition table, in media units
 +
|-
 +
|  0x160
 +
|  0xA0
 +
|  ...
 +
|}
 +
 
 +
For carts,
 +
{| class="wikitable" border="1"
 +
|-
 +
!  Offset
 +
!  Size
 +
!  Description
 
|-
 
|-
 
|  0x160
 
|  0x160
Line 56: Line 96:
 
|  0x188
 
|  0x188
 
|  8
 
|  8
|  Partition Flags: byte[5]-byte[7] indicate content type ( system update, application, manual, ... ) size of media units ( 512*2^byte[6] ) and encryption.
+
|  Partition Flags (See Below)
 
|-
 
|-
 
|  0x190
 
|  0x190
Line 63: Line 103:
 
|-
 
|-
 
|  0x1D0
 
|  0x1D0
0x30
+
0x20
 
|  Reserved
 
|  Reserved
 +
|-
 +
| 0x1F0
 +
| 0xE
 +
| Reserved?
 +
|-
 +
| 0x1FE
 +
| 0x1
 +
| Support for this was implemented with [[9.6.0-24|9.6.0-X]] FIRM. Bit0=1 enables using bits 1-2, it's unknown what these two bits are actually used for(the value of these two bits get compared with some other value during NCSD verification/loading). This appears to enable a new, likely hardware-based, antipiracy check on cartridges.
 +
|-
 +
| 0x1FF
 +
| 0x1
 +
| Support for this was implemented with [[9.6.0-24|9.6.0-X]] FIRM, see below regarding save crypto.
 
|}
 
|}
 +
 +
For NAND,
 +
 +
{| class="wikitable" border="1"
 +
|-
 +
!  Offset
 +
!  Size
 +
!  Description
 +
|-
 +
|  0x160
 +
|  0x5E
 +
|  Unknown
 +
|-
 +
|  0x1BE
 +
|  0x42
 +
|  Encrypted MBR partition-table, for the TWL partitions(key-data used for this keyslot is console-unique).
 +
|}
 +
 +
=== NCSD Signature ===
 +
The RSA pubk used for gamecard NCSD is stored in [[Memory_layout|ITCM]]. The separate pubk used for NAND NCSD is stored in Process9 .(ro)data instead of ITCM.
  
 
=== Partition Flags ===
 
=== Partition Flags ===
Line 72: Line 144:
 
!  Byte Index
 
!  Byte Index
 
!  Description
 
!  Description
 +
|-
 +
| 0
 +
| Backup Write Wait Time (The time to wait to write save to backup after the card is recognized (0-255 seconds)).NATIVE_FIRM loads this flag from the gamecard NCSD header starting with [[6.0.0-11]].
 
|-
 
|-
 
| 3
 
| 3
| This flag can determine how the gamecard savegame keyY is generated when set, it's unknown if this flag is used for anything else.
+
| Media Card Device (1 = NOR Flash, 2 = None, 3 = BT) (SDK 3.X+)
 +
|-
 +
| 4
 +
| Media Platform Index (1 = CTR)
 +
|-
 +
| 5
 +
| Media Type Index (0 = Inner Device, 1 = Card1, 2 = Card2, 3 = Extended Device)
 +
|-
 +
| 6
 +
| Media Unit Size i.e. u32 MediaUnitSize = 0x200*2^flags[6];
 +
|-
 +
| 7
 +
| Media Card Device (1 = NOR Flash, 2 = None, 3 = BT) (Only SDK 2.X)
 +
|}
 +
 
 +
=== Partition Flags (In Terms of Save Crypto Determination) ===
 +
{| class="wikitable" border="1"
 
|-
 
|-
 +
!  Byte Index
 +
!  Description
 +
|-
 +
| 1
 +
| Starting with [[6.0.0-11]] NATIVE_FIRM will use this flag to determine the gamecard [[Savegames|savegame]] keyY method, when flag[3] is set. 0 = [[2.0.0-2]] hashed keyY, 1 = [[Savegames|new]] keyY method implemented with [[6.0.0-11]]. 0x0A = implemented with [[9.3.0-21|9.3.0-X]]. On Old3DS this is identical to the [[2.2.0-4]] crypto. On New3DS this is identical to the [[2.2.0-4]] crypto, except with New3DS-only gamecard savedata [[AES|keyslots]].
 +
Starting with [[9.6.0-24|9.6.0-X]] FIRM, Process9 now sets <savecrypto_stateval> to partitionflag[1] + <the u8 value from NCSD+0x1FF>, instead of just setting it to partitionflag[1].
 +
|-
 +
| 3
 +
| Support for this flag was implemented in NATIVE_FIRM with [[2.0.0-2]]. When this flag is set the hashed gamecard [[Savegames|savegame]] keyY method is used, this likely still uses the repeating-CTR however. With [[6.0.0-11]] the system will determine the gamecard savegame keyY method via flag[1], instead of just using the hashed keyY via this flag.
 +
|-th
 
| 7
 
| 7
| This flag can determine how the gamecard savegame keyY is generated when set. All games since [[2.2.0-4]] have this flag set, this flag likely also enables the new CTR method as well.
+
| This flag enables using the hashed gamecard [[Savegames|savegame]] keyY method, support for this flag was implemented in NATIVE_FIRM with [[2.2.0-4]]. All games with the NCSD image finalized since [[2.2.0-4]](and contains [[2.2.0-4]]+ in the system update partition) have this flag set, this flag also enables using new CTR method as well.
 
|}
 
|}
 +
 +
Starting with [[9.6.0-24|9.6.0-X]] FIRM, Process9 will just write val0 to a state field then return 0, instead of returning an error when the save crypto type isn't recognized. This was the *only* actual functionality change in the Old3DS Process9 function for gamecard savedata crypto init.
  
 
== Card Info Header ==
 
== Card Info Header ==
Line 88: Line 191:
 
|-
 
|-
 
|  0x200
 
|  0x200
8
+
4
|  Card Info
+
|  CARD2: Writable Address In Media Units (For 'On-Chip' Savedata). CARD1: Always 0xFFFFFFFF.
 +
|-
 +
|  0x204
 +
|  4
 +
|  Card Info Bitmask
 
|-
 
|-
 
|  0x208
 
|  0x208
0xDF8
+
0x108
 
|  Reserved1
 
|  Reserved1
 
|-
 
|-
0x1000
+
0x310
8
+
2
Media ID (same as first NCCH partitionId)
+
Title version
 +
|-
 +
|  0x312
 +
|  2
 +
|  Card revision
 
|-
 
|-
0x1008
+
0x208
8
+
0xCEE
 
|  Reserved2
 
|  Reserved2
 +
|-
 +
|  0x1000
 +
|  0x10
 +
|  Card seed keyY (first u64 is Media ID (same as first NCCH partitionId))
 
|-
 
|-
 
|  0x1010
 
|  0x1010
0x30
+
0x10
Initial Data
+
Encrypted card seed (AES-CCM, keyslot 0x3B for retail cards, see [[CTRCARD_Registers|CTRCARD_SECSEED]])
 
|-
 
|-
0x1040
+
0x1020
0xC0
+
0x10
Reserved
+
Card seed AES-MAC
 +
|-
 +
|  0x1030
 +
|  0xC
 +
|  Card seed nonce
 +
|-
 +
|  0x103C
 +
|  0xC4
 +
|  Reserved3
 
|-
 
|-
 
|  0x1100
 
|  0x1100
Line 135: Line 258:
 
|  CardDeviceReserved2
 
|  CardDeviceReserved2
 
|}
 
|}
 +
 +
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).
  
 
== Tools ==
 
== Tools ==

Revision as of 15:20, 23 January 2017

This page documents the format of NCSD.

Overview

There are two known specialisations of the NCSD container format. The CTR Cart Image (CCI) format and the 3DS' raw NAND format. CCI is the format of game ROM images.

CTR System Update (CSU) is a variant of CCI, where the only difference is in the file extension. This is used with developer System Updates and associated Tools.


NCSD images start with a NCSD header, followed by up to a maximum of 8 NCCH partitions.

For CCI images, the partitions are reserved as follows:

NCCH Index Reserved Use
0 Executable Content (CXI)
1 E-Manual (CFA)
2 Download Play Child container (CFA)
6 New3DS Update Data (CFA)
7 Update Data (CFA)

The format of partitions can be determined from the partition FS flags (normally these are zero for CCI/CSU NCSD Images).

NCSD header

Offset Size Description
0x000 0x100 RSA-2048 SHA-256 signature of the NCSD header
0x100 4 Magic Number 'NCSD'
0x104 4 Size of the NCSD image, in media units (1 media unit = 0x200 bytes)
0x108 8 Media ID
0x110 8 Partitions FS type (0=None, 1=Normal, 3=FIRM, 4=AGB_FIRM save)
0x118 8 Partitions crypt type (each byte corresponds to a partition in the partition table)
0x120 0x40=(4+4)*8 Offset & Length partition table, in media units
0x160 0xA0 ...

For carts,

Offset Size Description
0x160 0x20 Exheader SHA-256 hash
0x180 0x4 Additional header size
0x184 0x4 Sector zero offset
0x188 8 Partition Flags (See Below)
0x190 0x40=8*8 Partition ID table
0x1D0 0x20 Reserved
0x1F0 0xE Reserved?
0x1FE 0x1 Support for this was implemented with 9.6.0-X FIRM. Bit0=1 enables using bits 1-2, it's unknown what these two bits are actually used for(the value of these two bits get compared with some other value during NCSD verification/loading). This appears to enable a new, likely hardware-based, antipiracy check on cartridges.
0x1FF 0x1 Support for this was implemented with 9.6.0-X FIRM, see below regarding save crypto.

For NAND,

Offset Size Description
0x160 0x5E Unknown
0x1BE 0x42 Encrypted MBR partition-table, for the TWL partitions(key-data used for this keyslot is console-unique).

NCSD Signature

The RSA pubk used for gamecard NCSD is stored in ITCM. The separate pubk used for NAND NCSD is stored in Process9 .(ro)data instead of ITCM.

Partition Flags

Byte Index Description
0 Backup Write Wait Time (The time to wait to write save to backup after the card is recognized (0-255 seconds)).NATIVE_FIRM loads this flag from the gamecard NCSD header starting with 6.0.0-11.
3 Media Card Device (1 = NOR Flash, 2 = None, 3 = BT) (SDK 3.X+)
4 Media Platform Index (1 = CTR)
5 Media Type Index (0 = Inner Device, 1 = Card1, 2 = Card2, 3 = Extended Device)
6 Media Unit Size i.e. u32 MediaUnitSize = 0x200*2^flags[6];
7 Media Card Device (1 = NOR Flash, 2 = None, 3 = BT) (Only SDK 2.X)

Partition Flags (In Terms of Save Crypto Determination)

Byte Index Description
1 Starting with 6.0.0-11 NATIVE_FIRM will use this flag to determine the gamecard savegame keyY method, when flag[3] is set. 0 = 2.0.0-2 hashed keyY, 1 = new keyY method implemented with 6.0.0-11. 0x0A = implemented with 9.3.0-X. On Old3DS this is identical to the 2.2.0-4 crypto. On New3DS this is identical to the 2.2.0-4 crypto, except with New3DS-only gamecard savedata keyslots.

Starting with 9.6.0-X FIRM, Process9 now sets <savecrypto_stateval> to partitionflag[1] + <the u8 value from NCSD+0x1FF>, instead of just setting it to partitionflag[1].

3 Support for this flag was implemented in NATIVE_FIRM with 2.0.0-2. When this flag is set the hashed gamecard savegame keyY method is used, this likely still uses the repeating-CTR however. With 6.0.0-11 the system will determine the gamecard savegame keyY method via flag[1], instead of just using the hashed keyY via this flag.
7 This flag enables using the hashed gamecard savegame keyY method, support for this flag was implemented in NATIVE_FIRM with 2.2.0-4. All games with the NCSD image finalized since 2.2.0-4(and contains 2.2.0-4+ in the system update partition) have this flag set, this flag also enables using new CTR method as well.

Starting with 9.6.0-X FIRM, Process9 will just write val0 to a state field then return 0, instead of returning an error when the save crypto type isn't recognized. This was the *only* actual functionality change in the Old3DS Process9 function for gamecard savedata crypto init.

Card Info Header

OFFSET SIZE DESCRIPTION
0x200 4 CARD2: Writable Address In Media Units (For 'On-Chip' Savedata). CARD1: Always 0xFFFFFFFF.
0x204 4 Card Info Bitmask
0x208 0x108 Reserved1
0x310 2 Title version
0x312 2 Card revision
0x208 0xCEE Reserved2
0x1000 0x10 Card seed keyY (first u64 is Media ID (same as first NCCH partitionId))
0x1010 0x10 Encrypted card seed (AES-CCM, keyslot 0x3B for retail cards, see CTRCARD_SECSEED)
0x1020 0x10 Card seed AES-MAC
0x1030 0xC Card seed nonce
0x103C 0xC4 Reserved3
0x1100 0x100 Copy of first NCCH header (excluding RSA signature)

Development Card Info Header Extension

OFFSET SIZE DESCRIPTION
0x1200 0x200 CardDeviceReserved1
0x1400 0x10 TitleKey
0x1410 0xF0 CardDeviceReserved2

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

Tools

ctrtool - (CMD)(Windows/Linux) Parsing NCSD files

3DSExplorer - (GUI)(Windows Only) Parsing NCSD files