Difference between revisions of "NAX0"

From Nintendo Switch Brew
Jump to navigation Jump to search
(Encryption details)
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
This is the format on the files stored on [[SD_Filesystem|SD]], unknown if this is used elsewhere.
+
This is the format on the files stored on [[SD_Filesystem|SD]] (Nintendo Aes Xts -- official name is AesXtsFilesystem/AesXtsFile).
  
 
The data between this header and offset 0x4000 is unused/uninitialized it appears. The actual content which is encrypted, starts at offset 0x4000 with the size from the header.
 
The data between this header and offset 0x4000 is unused/uninitialized it appears. The actual content which is encrypted, starts at offset 0x4000 with the size from the header.
Line 40: Line 40:
 
Key derivation is as follows:
 
Key derivation is as follows:
  
First, FS retrieves the 16-byte console-unique seed that NS registered (data originates from the ns_systemseed:/ [[Flash_Filesystem#System_Savegames|system savegame]]). Next, FS calculates encryptedSeedKeys = <0x20 hardcoded keydata depending on if this NAX0 is a save or an NCA> XORed with the system seed, calculates kek = [[SPL_services#GenerateAesKek|GenerateAesKek]](<hardcoded keydata>, 0, 0), and then calculates decryptedSeedKeys by doing decryptedSeedKeys[i] = [[SPL_services#GenerateAesKey|GenerateAesKey]](kek, encryptedSeedKeys[i]); for both keys.
+
First, FS retrieves the 16-byte console-unique seed that NS registered (data originates from the ns_appman:/private [[Flash_Filesystem#System_Savegames|system savegame]]). Next, FS calculates encryptedSeedKeys = <0x20 hardcoded keydata depending on if this NAX0 is a save or an NCA> XORed with the system seed, calculates kek = [[SPL_services#GenerateAesKek|GenerateAesKek]](<hardcoded keydata>, 0, 0), and then calculates decryptedSeedKeys by doing decryptedSeedKeys[i] = [[SPL_services#GenerateAesKey|GenerateAesKey]](kek, encryptedSeedKeys[i]); for both keys.
  
  
 
Once the decryptedSeedKeys are calculated, FS calculates naxSpecificKeys = hmac-sha256(key=decryptedSeedKeys[0], data=<NAX0 path, relative to /Nintendo/Contents>); (example path: '/registered/000000FF/cafebabecafebabecafebabecafebabe.nca'). Then, FS does the following decryptions in place: aes128_ecb_decrypt(key=naxSpecificKeys[0], data=Header + 0x28); aes128_ecb_decrypt(key=naxSpecificKeys[1], data=Header + 0x38); Finally, hmac-sha256(key=Header[0x20:0x60], data=decryptedSeedKeys[1]) is calculated, and compared using a constant-time memcmp to the hmac stored at Header + 0x0. If it matches, decryption proceeds using the two decrypted keys at Header + 0x28 as an AES-XTS keypair.
 
Once the decryptedSeedKeys are calculated, FS calculates naxSpecificKeys = hmac-sha256(key=decryptedSeedKeys[0], data=<NAX0 path, relative to /Nintendo/Contents>); (example path: '/registered/000000FF/cafebabecafebabecafebabecafebabe.nca'). Then, FS does the following decryptions in place: aes128_ecb_decrypt(key=naxSpecificKeys[0], data=Header + 0x28); aes128_ecb_decrypt(key=naxSpecificKeys[1], data=Header + 0x38); Finally, hmac-sha256(key=Header[0x20:0x60], data=decryptedSeedKeys[1]) is calculated, and compared using a constant-time memcmp to the hmac stored at Header + 0x0. If it matches, decryption proceeds using the two decrypted keys at Header + 0x28 as an AES-XTS keypair.

Latest revision as of 08:34, 16 April 2018

This is the format on the files stored on SD (Nintendo Aes Xts -- official name is AesXtsFilesystem/AesXtsFile).

The data between this header and offset 0x4000 is unused/uninitialized it appears. The actual content which is encrypted, starts at offset 0x4000 with the size from the header.

When a NAX0 file is recreated, the header and raw content in NAX0 are completely different except for the magicnum and size-field. This is the case when a title is redownloaded/reinstalled, and when "save/" files are recreated after manual deletion.

Error 0x250E02 is returned by NCM when attempting to access a NcaId where the NAX0 header HMAC validation fails.

Offset Size Description
0x0 0x20 Header HMAC
0x20 0x8 Magicnum "NAX0"
0x28 0x20 Encrypted AES-XTS Keys
0x48 0x8 Size of the file relative to offset 0x4000.
0x50 0x30 Padding

Encryption

The actual content uses AES-XTS with the same non-standard tweak (endianness swap) as usual, and sector size 0x4000.

Key derivation is as follows:

First, FS retrieves the 16-byte console-unique seed that NS registered (data originates from the ns_appman:/private system savegame). Next, FS calculates encryptedSeedKeys = <0x20 hardcoded keydata depending on if this NAX0 is a save or an NCA> XORed with the system seed, calculates kek = GenerateAesKek(<hardcoded keydata>, 0, 0), and then calculates decryptedSeedKeys by doing decryptedSeedKeys[i] = GenerateAesKey(kek, encryptedSeedKeys[i]); for both keys.


Once the decryptedSeedKeys are calculated, FS calculates naxSpecificKeys = hmac-sha256(key=decryptedSeedKeys[0], data=<NAX0 path, relative to /Nintendo/Contents>); (example path: '/registered/000000FF/cafebabecafebabecafebabecafebabe.nca'). Then, FS does the following decryptions in place: aes128_ecb_decrypt(key=naxSpecificKeys[0], data=Header + 0x28); aes128_ecb_decrypt(key=naxSpecificKeys[1], data=Header + 0x38); Finally, hmac-sha256(key=Header[0x20:0x60], data=decryptedSeedKeys[1]) is calculated, and compared using a constant-time memcmp to the hmac stored at Header + 0x0. If it matches, decryption proceeds using the two decrypted keys at Header + 0x28 as an AES-XTS keypair.