Gamecards: Difference between revisions
Describe cart cryptography protocol now that it is confirmed the Switch uses a different protocol |
Link to where the 0x200 InitialData comes from, I noticed the pattern looking at the Lotus3 page at Switchbrew |
||
(One intermediate revision by the same user not shown) | |||
Line 219: | Line 219: | ||
|} | |} | ||
The header command has some initial dummy bytes, and eventually responds with | The header command has some initial dummy bytes, and eventually responds with the 0x200 byte [[NCSD#InitialData|InitialData]]. Here's an example for Lego Starwars 3: | ||
0000000: 00 8c 03 00 00 00 04 00 00 00 00 00 00 00 00 00 ................ | 0000000: 00 8c 03 00 00 00 04 00 00 00 00 00 00 00 00 00 ................ | ||
0000010: b3 cf fb c6 6a b1 cb 20 32 af ce 35 d4 1c 74 c9 ....j.. 2..5..t. | 0000010: b3 cf fb c6 6a b1 cb 20 32 af ce 35 d4 1c 74 c9 ....j.. 2..5..t. | ||
Line 255: | Line 255: | ||
After the 0x82 command, cryptography is initialized, which can be reproduced following this algorithm; unless noted otherwise, all operations are in big endian byte order: | After the 0x82 command, cryptography is initialized, which can be reproduced following this algorithm; unless noted otherwise, all operations are in big endian byte order: | ||
# Set the [[AES_Registers|AES keyslot 0x3b keyY]] to the values at 0x000:0x010. The corresponding keyX is set in [[Bootloader|Boot9]]. | |||
# Decrypt the 16 bytes at 0x010:0x020 using AES-128-CCM in keyslot 0x3b using the 12-byte nonce at 0x030:0x03c to obtain the primary seed; if the response to the 0xa0 command AND 0x00000003 equals 3, instead use slot 0x11 and set the normalkey to 0x00000000000000000000000000000000. Verify that the 16-byte tag at 0x020:0x030 is valid. | |||
# Split the primary seed into two halves: left and right. | |||
# Initialize a context for the SNOW 2.0 stream cipher. The 128-bit key is the primary seed. The 128-bit IV is a 128-bit static value depending on the gamecard ID2. | |||
# Call the SNOW 2.0 stream cipher 32 times to obtain 1024 bits (32 words) of output. Discard them. | |||
# Initialize a context for the RC4 stream cipher. The 256-bit key consists of a 128-bit static value depending on the gamecard ID2 followed by four outputs of the SNOW 2.0 stream. | |||
# Call the RC4 stream cipher 256 times to obtain 2048 bits (256 bytes) of output. Discard them. | |||
All commands and responses are now encrypted using RC4. The gamecard controller and gamecard itself share the RC4 key and advance the state accordingly. | All commands and responses are now encrypted using RC4. The gamecard controller and gamecard itself share the RC4 key and advance the state accordingly. | ||
Line 267: | Line 267: | ||
If the 0x83 command is sent, the cryptography is re-keyed: | If the 0x83 command is sent, the cryptography is re-keyed: | ||
# Initialize a new context for the SNOW 2.0 stream cipher. The 128-bit key consists of the left half of the primary seed followed by the lower 64 bytes of the decrypted 0x83 command. The 128-bit IV is the same 128-bit static value depending on the gamecard ID2 as before. | |||
# Call the SNOW 2.0 stream cipher 32 times to obtain 1024 bits (32 words) of output. Discard them. | |||
# Initialize a new context for the RC4 stream cipher. The 256-bit key consists of the same 128-bit static value depending on the gamecard ID2 as before followed by four outputs of the new SNOW 2.0 stream. | |||
# Call the RC4 stream cipher 256 times to obtain 2048 bits (256 bytes) of output. Discard them. | |||
The above example commands can be decrypted in this manner. | The above example commands can be decrypted in this manner. | ||
The static values are fixed in the gamecard controller and gamecards themselves, they are not obtained from Process9 or anywhere in NATIVE_FIRM. | The static values are fixed in the gamecard controller and gamecards themselves, they are not obtained from Process9 or anywhere in NATIVE_FIRM. |