Reference code for the 3DS cart encryption protocol
Go to file
2024-06-02 11:11:21 +00:00
.gitignore Initial commit 2024-06-02 10:54:32 +00:00
cart.py Initial commit 2024-06-02 10:54:32 +00:00
cart_crypto.py Initial commit 2024-06-02 10:54:32 +00:00
README.md Propose alternative way to test this in README 2024-06-02 11:11:21 +00:00

Cart crypto demo

This tool decrypts the 3DS cart encryption example on 3dbrew.

The code is based on code found on GBATEK (Warning: big page).

It expects a file named 0004000000038c00.3ds in the current directory. A known-good dump of this title (LEGO Star Wars III The Clone Wars, EUR) has SHA-256 8fcbd4b394f765cb09f81ee7c62802d490c86ed85bd5ab3923b48a4d0222de22. Alternatively, you can use the 0x200 bytes on the 3dbrew page linked above. Take the first 0x40 bytes of the initial data hex dump on that page, prepend it with 0x1000 of dummy data and name the result 0004000000038c00.3ds.

It assumes gamecart ID2 == 0, which should be the case for all retail carts.

Secrets

To use this, you need a file called ctr_secrets.py in the directory where cart.py is. It needs to define a few things:

It needs to define KEY_DERIVATION_CONSTANT as an integer (0x1##############################a).

It needs to define CART_KEYS as an array or tuple like this:

CART_KEYS = ( # indexed based on ID2
    {
        'rc4': 0x4##############################7,
        'snow': 0xd##############################4
    },
    {
        'rc4': 0x3##############################9,
        'snow': 0xd##############################4
    },
    {
        'rc4': 0x0##############################0,
        'snow': 0x0##############################0
    },
    {
        'rc4': 0x7##############################c,
        'snow': 0x0##############################a
    }
    )

Note that these are integers.

It needs to define an array or tuple BOOTROM_KEYS like this:

BOOTROM_KEYS = (
        { # AES slot 0x00
            'keyX': b'',
            'keyY': b'',
            'normalkey': b'',
        },
        { # AES slot 0x01
            'keyX': b'',
            'keyY': b'',
            'normalkey': b'',
        },
        # etc.
        )

Note that these are bytes. You can use yellows8's boot9 tools to extract the required keyX for slot 0x3b.