Reference code for the 3DS cart encryption protocol
Go to file
2024-06-02 10:54:32 +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 Initial commit 2024-06-02 10:54:32 +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.

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.
        ) * 0x40

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