https://blog.winter-software.com/2024/06/02/ctr-cart-protocol [ ] Wave A Brief Look at the 3DS Cartridge Protocol Forbidden Tempura 6/2/2024 1:00 PM (Modified 2 days ago) ITGamesInfodump [ ] Table of Content * But first, we need to talk about parallel universes * The protocol * Assumed motivations * Concrete improvements About a week ago, there has been a little addition to the 3dbrew wiki page about 3DS cartridges (carts) that outlines the technical details of how the 3DS cartridge controller and a 3DS cartridge talk to each other. I would like to take this opportunity to also include the 3DS itself in the conversation to illuminate which part of which device performs which step. I will then proceed to outline where I think the corresponding design decisions originate. Finally, I will conclude with some concrete ideas for improvement. But first, we need to talk about parallel universes This protocol makes no sense unless you have a basic overview of the 3DS AES engine. The 3DS AES engine can load 128-bit AES keys in two ways: 1. Using key-derivation from a keyX and keyY (officially called KeyId and KeySeed, respectively). 2. Directly specifying a full AES key. The key derivation from a keyX and keyY works as follows: AES key = (((keyX ROL 2) XOR keyY) + C1) ROR 41, where ROL is left rotation on a 128-bit word and ROR is right rotation on a 128-bit word. The constant C1 is stored in the AES hardware but black-box analysis of the key derivation function with a pair of known keyX and keyY led to the discovery of the constant (0x1ff9...). This also implies keyX and keyY are always 128-bit values. The idea is that any software never directly stores a critical key but rather that the keys are derived on the fly by the hardware with the non-obfuscated key only being known to Nintendo. The protocol At the factory, three pieces of information are generated: 1. The ID1. The cartridge ID1 contains a bit whether this is a 3DS cartridge, the specific 3DS cart type (security type 1 or 2 and EEPROM present or not), the size of the cartridge itself and the maker code (who manufactured this cartridge). 2. The ID2. The cartridge ID2 determines the key used later in the protocol. 3. The unique ID. This is 16 bytes, which supposedly can get verified in some manner later, plus 48 bytes of padding. 4. The title key. This is static for all instances of a cartridge. The unique ID is interesting in that apparently it can be verified by Nintendo online services. Knowing Nintendo, they generally shy away from using homebrewed cryptographic algorithms. No asymmetric signature is 16 bytes in length. This suggests some kind of symmetric-key construction (HMAC? They also use CMAC elsewhere to "brand" system files with a console-unique key) though it remains unclear what specifically would be the input to this since only the unique ID is unique to each cartridge. Who Step Details Console Boot-up Set the keyX. Console Initialization Causes the cart to initialize itself in DS (i) cart mode Cart Initialization Sends 0x2000 bytes of dummy data Console Signal 3DS Causes the cart to be ready to change to mode 3DS mode Console ID1 Causes the cart to send the ID1 Cart ID1 Sends the ID1 Console ID2 Causes the cart to send the ID2 Cart ID2 Sends the ID2 Console Upgrade Signal switch to 3DS mode Console Initial data Requests the initial data Sends the initial data, which contains: (1) Cart Initial data keyY, (2) encrypted title key, (3) MAC, (4) nonce Console Initial data Load the keyY into the AES engine, causing it to derive the key Perform the same steps as the console and Cart Key generation cart controller below until the end of the key generation step Console Key generation Decrypt the title key using AES-CCM Console Key generation Send the decrypted title key to the cart controller Cart Key generation Split the title key into two halves: left controller and right Initialize a context for the SNOW 2.0 Cart Key generation stream cipher. The 128-bit title key. The controller 128-bit IV is a 128-bit static value depending on the gamecard ID2 Cart Call the SNOW 2.0 stream cipher 32 times to controller Key generation obtain and discard 1024 bits (32 words) of output Initialize a context for the RC4 stream Cart cipher. The 256-bit key consists of a controller Key generation 128-bit static value depending on the gamecard ID2 followed by four outputs of the SNOW 2.0 stream Cart Call the RC4 stream cipher 256 times to controller Key generation obtain and discard 2048 bits (256 bytes) of output Pull 8 bytes of random data from the Console Rekey cryptographically secure random number generator Console Rekey Send the 8 bytes to the cart and controller Perform the same steps as the console and Cart Rekey cart controller below until the end of the rekey step Initialize a new context for the SNOW 2.0 stream cipher. The 128-bit key consists of Cart Rekey the left half of the title key followed by controller the 8 random bytes. The 128-bit IV is the same 128-bit static value depending on the gamecard ID2 as before Cart Call the SNOW 2.0 stream cipher 32 times to controller Rekey obtain and discard 1024 bits (32 words) of output Initialize a context for the RC4 stream Cart cipher. The 256-bit key consists of a controller Rekey 128-bit static value depending on the gamecard ID2 followed by four outputs of the SNOW 2.0 stream Cart Call the RC4 stream cipher 256 times to controller Rekey obtain and discard 2048 bits (256 bytes) of output At this point, both sides have arrived at the same key and will talk over one shared RC4 state to each other. The 3DS console itself cannot obtain these keys because only the cart and cart controller have the keys that are chosen according to the ID2. Responses include a CRC-32, which is also encrypted. In summary: 1. At the 3DS factory, 1. the keyX is written into the boot ROM, 2. the AES key derivation constant is made part of the AES hardware, 3. the SNOW 2.0 and RC4 key constants are made part of the cartridge controller hardware. 2. At the cart factory, the keyY, (encrypted) title key, ID1, ID2 and unique ID are written to the cart. 3. When the cartridge is inserted, the 3DS decrypts the title key using the keyX (boot ROM), keyY (cart) via the AES hardware (hardware key derivation constant). 4. The cart controller uses a SNOW 2.0 stream cipher, whose only purpose is to act as a key derivation function for RC4, to generate an RC4 key. Both keys involve constants stored in the cartridge controller hardware. 5. The cart controller uses RC4 for encryption. 6. The cart does the same. Assumed motivations The motivation for encryption in the first place is obvious: Nintendo does not want their assets and code to be obtained. Ciphers. The encryption uses SNOW 2.0 and RC4. SNOW 2.0 is an uncommon cipher, only notable for being standardized by ISO. It claims to be software-oriented but is implemented strictly in hardware on the 3DS. Similarly, RC4 is software-oriented. This suggests that this protocol may initially have been meant to be implemented in software. It was considered weak even at the time the 3DS was designed around 2009/2010. This is the reason why some outputs are discarded from both the stream ciphers: Avoiding weak initial streams. Furthermore, Nintendo is notoriously afraid of leaving classic, NIST-approved cryptography. This strongly suggests that this protocol was not designed in-house. The use of a stream cipher per se seems a natural choice for a protocol in which both sides share a state, messages are of variable length and no authentication of the message is needed (or is implied by the correct encryption of a CRC value). AES-CCM is also a fairly unusual choice but avoids the need for GHASH/POLYVAL in hardware compared to AES-GCM, which would have been the primary alternative at the time. Secrets. The scheme excels at splitting secrets across multiple components such that breaking one does not break the others. This part is illustrative of a good mesh design and laudable in its execution. The cartridge must either have a full copy of the AES hardware and the keyX/keyY key derivation algorithm to use the initial data to decrypt the title key or an unencrypted copy of the title key. It would be fairly unnatural to have a full implementation of AES and then two separate ciphers, which suggests that there is an unencrypted copy of the title key on the cart that the cart hardware can use for the SNOW 2.0 and RC4 key derivation. This is corroborated by the observation that a corresponding region is not readable on retail cartridges. Concrete improvements There are four issues that stand out: the prelude, cipher choice, message authentication and rekeying. Prelude. The prelude (initial key negotiation and ID1/ID2) are in plaintext and unauthenticated. It would be beneficial if the cart and cart controller had a pre-shared key as a first line of defense. Message authentication. While there is an encrypted CRC-32, it will likely not provide meaningful resistance against modifications to the stream. This is likely a holdover from thinking about hardware (bit flips) instead of thinking about cryptography (authentication). Cipher choice. Both SNOW 2.0 and RC4 are software-oriented. An ideal implementation would prefer hardware-oriented ciphers for this. Interest in stream ciphers has been waning and the eSTREAM winners for the hardware profile make use of only 80-bit keys. This is considered strong enough, but Nintendo exhibits a strong preference towards 128-bit keys. Rekeying. The 3DS console alone dictates the randomness used for rekeying. Assume an attacker realizes that a stream cipher is used. Assume further the attacker compromises the 3DS firmware to the point that they can force the 3DS to send the same rekey value. The attacker can then save the transcript of a communication, force the 3DS to send the same rekey value and request different pages: An attacker observes (convo1 = plain1 XOR keystream). They reset the conversation, forces the same rekey value and observe (convo2 = plain2 XOR keystream). Because XOR is commutative, this lets them observe the XOR of plain1 and plain2. Since they can control the pages used, if at least one of the pages returned is all-zero decrypted (which they can observe on the 3DS firmware), they obtain the raw keystream and can decrypt the whole cart by repeatedly resetting and doing page-wise requests. The protocol-level issues of the prelude and rekeying can be solved by instantiating a Noise protocol framework pattern; finding an appropriate pattern is straightforward thanks to tools like the Noise Explorer. The downside is that these protocols assume the wide availability of elliptic curve Diffie-Hellman primitives. In a pure hardware implementation, elliptic curves may well be even more of a nightmare than in software. It may be necessary to substitute custom key derivation, albeit this is not recommended. The message authentication can be solved using authentication tags instead of a CRC. Assuming a performant, hardware-oriented implementation of AES, AES-OCB could be used as the primary method of communication with one authentication tag per packet. Finally, the AES key derivation function is just plain bad. It was possible to determine the constant just given a pair of keyX/keyY and the resulting key. NIST peddles a solution to this, NIST SP 800-56C, involving AES-CMAC. NIST SP 800-56C which was not yet released at the time the 3DS was designed and released. The AES key derivation function is particularly baffling because it should be an obvious idea to involve AES engine in the key derivation. Edit: A demo of this is now available at: https://git.winter-software.com/ forbiddentempura/cartcrypto - Mia [7ebcc3a6-37e1-4b60-945c-cf2f657e6e6b] About the Author Forbidden Tempura I am good at being angry about video games. Profile [546feabb-859f-4f75-afc6-c4b] Mia Rose WinterReviewer This might also interest you [7ebcc3a6-37e1-4b60-945c-cf2f657e6e6b] Reconstructing the 3DS Bootstrapping Process at the Factory Forbidden Tempura 5/13/2024 Motivation The Nintendo 3DS was a fairly popular console. In spite of that, surprisingly little is known about how it is put together at the factory. Working with information that was uncovered during the so-called Gigaleak, I will try to recover as much information as I can about the manufacturing process up and until the point the 3DS is able to complete a normal boot sequence. One-Time Programmable (OTP) region Every 3DS ships with 0x100 of one-time programmable persistent memory at 0x10012000-0x10012100, containing console-unique keys and information. This obviously has to occur before any normal firmware runs on the system because significant amounts of all data written would fail to account for console-unique information and thus the encrypted values would be all encrypted for the wrong keys. An interesting observations: ctr.7z (SHA-256: 8b05072361254437277576d53c08b95e5f076c6b33a2871fad74eaa5561d1d38) ctr /sources/bootrom/CTR/private/build/bootrom/ctr_bootrom/ARM9/main.c has a pr ITGamesInfodump [546feabb-859f-4f75-afc6-c4b0edc626a9] If it has Text, it is Pain Mia Rose Winter 5/1/2024 I've been meaning to write tests for Wave for a while. Honestly, in my 12 years of dev I never actually wrote one outside of the odd academic homework assignment, so I had no idea how to approach it. After a couple of videos and video presentations about general unit tests, TDD and stuff, I actually got intrigued, and with a bug discovered just today by a coworker in Wave I was baffled by I thought, okay, let's dissect this little Kafer. Prerequisites: What does Wave do here actually If you have not authored an article on Wave before, let me give you some background. When you want to load a specific article in the article view, there are three methods, two actively used and one historical, to find it. The first and most direct, the “permalink” if you will, is going to /article /{id}, with the UUIDv4 ID of the article. This is used for stuff like the article editor and during the draft and review process when the other method doesn't work, and maybe one day there will be a &l ITTutorialInfodumpC# [d93193a2-b28d-4c21-897a-617df1b0614e] Migrating PVs in Kubernetes 4censord 3/10/2024 Migrating PVs in Kubernetes In kubernetes, data storage is provided by so called persistent volumes. Kubernetes itself contains a bunch of different options out of the box, notably HostPath and NFS. HostPath has the advantage of being incredibly simple. You just take a directory from your host, and make it available in a pod. But, because it is host specific, that does not work very well if you have more than one host and want to be able to tolerate host failures. NFS has the advantage of being standard, to the extend that every NAS or storage solution from the last 20 years supports it. But, perfomance often isn't great. And, unless you are using NFSv4, NFS has some challenges surrounding things like file locking. But those arent important for anything exept rare cases like databases… Kubernetes supports having multiple types of PVs, and groups them together in StorageClasses. When requesting a PV from kubernetes (using a pvc), you can specify which storageclass you want. If yo ITTutorial Powered by Wave [English (United States) ] [Default ] Wave * Startpage * Log In * Sign Up 1.0.0-beta.19