Refactor arm9Loader(), fix decrypted-arm9bin FIRM support

This commit is contained in:
Aurora 2016-09-19 16:00:51 +02:00
parent b7b3400296
commit 872b1ccbb6

View File

@ -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);
@ -400,9 +399,6 @@ 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;
@ -419,14 +415,40 @@ void arm9Loader(u8 *arm9Section)
break;
}
//Firm keys
u8 __attribute__((aligned(4))) keyY[AES_BLOCK_SIZE];
u8 __attribute__((aligned(4))) arm9BinCTR[AES_BLOCK_SIZE];
bool needToDecrypt = *(u32 *)(arm9Section + 0x800) != 0x47704770;
if(a9lVersion == 2 || (a9lVersion == 1 && needToDecrypt))
{
if(!isDevUnit)
{
//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);
}
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,31 +456,13 @@ 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)
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)];
@ -472,7 +476,6 @@ void arm9Loader(u8 *arm9Section)
}
}
}
}
void computePinHash(u8 *out, u8 *in)
{