From 872b1ccbb6b48e141e5f6476a73cfdfbff3a79a3 Mon Sep 17 00:00:00 2001 From: Aurora Date: Mon, 19 Sep 2016 16:00:51 +0200 Subject: [PATCH] Refactor arm9Loader(), fix decrypted-arm9bin FIRM support --- source/crypto.c | 109 +++++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 53 deletions(-) diff --git a/source/crypto.c b/source/crypto.c index 55cd712..996b629 100755 --- a/source/crypto.c +++ b/source/crypto.c @@ -382,7 +382,6 @@ void decryptNusFirm(u8 *inbuf, u8 *outbuf, u32 ncchSize) const u8 keyY0x3D[AES_BLOCK_SIZE] = {0x0C, 0x76, 0x72, 0x30, 0xF0, 0x99, 0x8F, 0x1C, 0x46, 0x82, 0x82, 0x02, 0xFA, 0xAC, 0xBE, 0x4C}; u8 __attribute__((aligned(4))) cetkIv[AES_BLOCK_SIZE] = {0}; u8 __attribute__((aligned(4))) titleKey[AES_BLOCK_SIZE]; - memcpy(titleKey, inbuf + 0x1BF, sizeof(titleKey)); memcpy(cetkIv, inbuf + 0x1DC, 8); @@ -401,32 +400,55 @@ void decryptNusFirm(u8 *inbuf, u8 *outbuf, u32 ncchSize) void arm9Loader(u8 *arm9Section) { - //Check if FIRM is already decrypted - if(*(u32 *)(arm9Section + 0x800) != 0x47704770) + //Determine the arm9loader version + u32 a9lVersion; + switch(arm9Section[0x53]) { - //Determine the arm9loader version - u32 a9lVersion; - switch(arm9Section[0x53]) + case 0xFF: + a9lVersion = 0; + break; + case '1': + a9lVersion = 1; + break; + default: + a9lVersion = 2; + break; + } + + bool needToDecrypt = *(u32 *)(arm9Section + 0x800) != 0x47704770; + + if(a9lVersion == 2 || (a9lVersion == 1 && needToDecrypt)) + { + if(!isDevUnit) { - case 0xFF: - a9lVersion = 0; - break; - case '1': - a9lVersion = 1; - break; - default: - a9lVersion = 2; - break; + //Set 0x11 keyslot + const u8 __attribute__((aligned(4))) key1[AES_BLOCK_SIZE] = {0x07, 0x29, 0x44, 0x38, 0xF8, 0xC9, 0x75, 0x93, 0xAA, 0x0E, 0x4A, 0xB4, 0xAE, 0x84, 0xC1, 0xD8}; + const u8 __attribute__((aligned(4))) key2[AES_BLOCK_SIZE] = {0x42, 0x3F, 0x81, 0x7A, 0x23, 0x52, 0x58, 0x31, 0x6E, 0x75, 0x8E, 0x3A, 0x39, 0x43, 0x2E, 0xD0}; + aes_setkey(0x11, a9lVersion == 2 ? key2 : key1, AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL); } - //Firm keys - u8 __attribute__((aligned(4))) keyY[AES_BLOCK_SIZE]; - u8 __attribute__((aligned(4))) arm9BinCTR[AES_BLOCK_SIZE]; + if(needToDecrypt) + { + //Set keyX + u8 __attribute__((aligned(4))) keyX[AES_BLOCK_SIZE]; + aes_use_keyslot(0x11); + aes(keyX, arm9Section + 0x60, 1, NULL, AES_ECB_DECRYPT_MODE, 0); + aes_setkey(0x16, keyX, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL); + } + } + + if(needToDecrypt) + { u8 arm9BinSlot = a9lVersion > 0 ? 0x16 : 0x15; - //Setup keys needed for arm9bin decryption + //Set keyY + u8 __attribute__((aligned(4))) keyY[AES_BLOCK_SIZE]; memcpy(keyY, arm9Section + 0x10, sizeof(keyY)); - memcpy(arm9BinCTR, arm9Section + 0x20, sizeof(arm9BinCTR)); + aes_setkey(arm9BinSlot, keyY, AES_KEYY, AES_INPUT_BE | AES_INPUT_NORMAL); + + //Set CTR + u8 __attribute__((aligned(4))) arm9BinCtr[AES_BLOCK_SIZE]; + memcpy(arm9BinCtr, arm9Section + 0x20, sizeof(arm9BinCtr)); //Calculate the size of the ARM9 binary u32 arm9BinSize = 0; @@ -434,42 +456,23 @@ void arm9Loader(u8 *arm9Section) for(u8 *tmp = arm9Section + 0x30; *tmp != 0; tmp++) arm9BinSize = (arm9BinSize << 3) + (arm9BinSize << 1) + *tmp - '0'; - if(a9lVersion > 0) - { - u8 __attribute__((aligned(4))) keyX[AES_BLOCK_SIZE]; - - if(!isDevUnit) - { - const u8 __attribute__((aligned(4))) key1[AES_BLOCK_SIZE] = {0x07, 0x29, 0x44, 0x38, 0xF8, 0xC9, 0x75, 0x93, 0xAA, 0x0E, 0x4A, 0xB4, 0xAE, 0x84, 0xC1, 0xD8}; - const u8 __attribute__((aligned(4))) key2[AES_BLOCK_SIZE] = {0x42, 0x3F, 0x81, 0x7A, 0x23, 0x52, 0x58, 0x31, 0x6E, 0x75, 0x8E, 0x3A, 0x39, 0x43, 0x2E, 0xD0}; - - aes_setkey(0x11, a9lVersion == 2 ? key2 : key1, AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL); - } - - aes_use_keyslot(0x11); - aes(keyX, arm9Section + 0x60, 1, NULL, AES_ECB_DECRYPT_MODE, 0); - aes_setkey(arm9BinSlot, keyX, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL); - } - - aes_setkey(arm9BinSlot, keyY, AES_KEYY, AES_INPUT_BE | AES_INPUT_NORMAL); - aes_use_keyslot(arm9BinSlot); - //Decrypt arm9bin - aes(arm9Section + 0x800, arm9Section + 0x800, arm9BinSize / AES_BLOCK_SIZE, arm9BinCTR, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL); + aes_use_keyslot(arm9BinSlot); + aes(arm9Section + 0x800, arm9Section + 0x800, arm9BinSize / AES_BLOCK_SIZE, arm9BinCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL); + } - //Set >=9.6 KeyXs - if(a9lVersion == 2 && !isDevUnit) + //Set >=9.6 KeyXs + if(a9lVersion == 2) + { + u8 __attribute__((aligned(4))) keyData[AES_BLOCK_SIZE] = {0xDD, 0xDA, 0xA4, 0xC6, 0x2C, 0xC4, 0x50, 0xE9, 0xDA, 0xB6, 0x9B, 0x0D, 0x9D, 0x2A, 0x21, 0x98}; + u8 __attribute__((aligned(4))) decKey[sizeof(keyData)]; + + //Set keys 0x19..0x1F keyXs + aes_use_keyslot(0x11); + for(u8 slot = 0x19; slot < 0x20; slot++, keyData[0xF]++) { - u8 __attribute__((aligned(4))) keyData[AES_BLOCK_SIZE] = {0xDD, 0xDA, 0xA4, 0xC6, 0x2C, 0xC4, 0x50, 0xE9, 0xDA, 0xB6, 0x9B, 0x0D, 0x9D, 0x2A, 0x21, 0x98}; - u8 __attribute__((aligned(4))) decKey[sizeof(keyData)]; - - //Set keys 0x19..0x1F keyXs - aes_use_keyslot(0x11); - for(u8 slot = 0x19; slot < 0x20; slot++, keyData[0xF]++) - { - aes(decKey, keyData, 1, NULL, AES_ECB_DECRYPT_MODE, 0); - aes_setkey(slot, decKey, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL); - } + aes(decKey, keyData, 1, NULL, AES_ECB_DECRYPT_MODE, 0); + aes_setkey(slot, decKey, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL); } } }