diff --git a/source/nand/nand.c b/source/nand/nand.c index 6cd7f13..aae12a1 100644 --- a/source/nand/nand.c +++ b/source/nand/nand.c @@ -39,6 +39,72 @@ static u8 TwlNandCtr[16]; static u32 emunand_base_sector = 0x000000; +bool LoadKeyFromFile(const char* folder, u8* keydata, u32 keyslot, char type, char* id) +{ + char path[256]; // should be enough + u8 key_magic[16]; + u8 buffer[32]; + u8* key = buffer + 16; + bool found = false; + + // check the obvious + if (keyslot >= 0x40) + return false; // invalid keyslot + if ((type != 'X') && (type != 'Y') && (type != 'N')) + return false; // invalid keytype + + // search 'aeskeydb.bin' file - setup + snprintf(path, 256, "%s/aeskeydb.bin", folder); + memset(key_magic, 0x00, 16); + key_magic[0] = keyslot; + key_magic[1] = type; + if (id) strncpy((char*) key_magic + 2, id, 10); + + // try to find key in 'aeskeydb.bin' file + for (u32 p = 0; FileGetData(path, buffer, 32, p); p += 32) { + if (memcmp(buffer, key_magic, 12) == 0) { + found = true; + break; + } + } + if (found && buffer[15]) { // encrypted key -> decrypt first + u8 ctr[16] __attribute__((aligned(32))); + u8 keyY[16] __attribute__((aligned(32))); + memset(ctr, 0x00, 16); + memset(keyY, 0x00, 16); + memcpy(ctr, key_magic, 12); + setup_aeskeyY(0x2C, keyY); + use_aeskey(0x2C); + set_ctr(ctr); + aes_decrypt((void*) key, (void*) key, 1, AES_CNT_CTRNAND_MODE); + } + + // try legacy slot0x??Key?.bin file + if (!found) { + snprintf(path, 256, "%s/slot0x%02XKey%.10s", folder, (unsigned int) keyslot, + (id) ? id : (type == 'X') ? "X" : (type == 'Y') ? "Y" : ""); + if (FileGetData(path, key, 16, 0)) + found = true; + } + + // out of options here + if (!found) return false; + + // now, setup the key + if (type == 'X') { // keyX + setup_aeskeyX(keyslot, key); + } else if (type == 'Y') { // keyY + setup_aeskeyY(keyslot, key); + } else { // normalKey + setup_aeskey(keyslot, key); + } + use_aeskey(keyslot); + + // return the key if memory provided + if (keydata) memcpy(keydata, key, 16); + + return true; +} bool InitNandCrypto(void) { @@ -81,10 +147,8 @@ bool InitNandCrypto(void) use_aeskey(0x03); // part #3: CTRNAND N3DS KEY - if (FileGetData("0:/slot0x05KeyY.bin", slot0x05KeyY, 16, 0)) { - setup_aeskeyY(0x05, slot0x05KeyY); - use_aeskey(0x05); - } + if (!LoadKeyFromFile("0:", slot0x05KeyY, 0x05, 'Y', NULL)) + LoadKeyFromFile("0:/Decrypt9", slot0x05KeyY, 0x05, 'Y', NULL); return true; diff --git a/source/nand/nand.h b/source/nand/nand.h index faa326d..a0a5a59 100644 --- a/source/nand/nand.h +++ b/source/nand/nand.h @@ -10,6 +10,7 @@ #define NAND_TYPE_N3DS (1<<4) #define NAND_TYPE_NO3DS (1<<5) +bool LoadKeyFromFile(const char* folder, u8* keydata, u32 keyslot, char type, char* id); bool InitNandCrypto(void); bool CheckSlot0x05Crypto(void);