From f1dee6814260643dd9f02a249652cde2b8f4ccb1 Mon Sep 17 00:00:00 2001 From: Aurora Wright Date: Fri, 14 Apr 2017 17:05:25 +0200 Subject: [PATCH] Complete kernel9Loader --- source/crypto.c | 74 ++++++++++++++++++++++++++++++++----------------- source/crypto.h | 1 - source/firm.c | 3 -- source/types.h | 1 + 4 files changed, 50 insertions(+), 29 deletions(-) diff --git a/source/crypto.c b/source/crypto.c index 22a224d..bb8d488 100755 --- a/source/crypto.c +++ b/source/crypto.c @@ -320,23 +320,6 @@ static void sha(void *res, const void *src, u32 size, u32 mode) /*****************************************************************/ -void twlConsoleInfoInit(void) -{ - u64 twlConsoleId = CFG_UNITINFO != 0 ? OTP_DEVCONSOLEID : (0x80000000ULL | (*(vu64 *)0x01FFB808 ^ 0x8C267B7B358A6AFULL)); - CFG_TWLUNITINFO = CFG_UNITINFO; - OTP_TWLCONSOLEID = twlConsoleId; - - *REG_AESCNT = 0; - - vu32 *k3X = REGs_AESTWLKEYS[3][1], *k1X = REGs_AESTWLKEYS[1][1]; - - k3X[0] = (u32)twlConsoleId; - k3X[3] = (u32)(twlConsoleId >> 32); - - k1X[2] = (u32)(twlConsoleId >> 32); - k1X[3] = (u32)twlConsoleId; -} - __attribute__((aligned(4))) static u8 nandCtr[AES_BLOCK_SIZE]; static u8 nandSlot; static u32 fatStart; @@ -480,6 +463,23 @@ bool decryptNusFirm(const Ticket *ticket, Cxi *cxi, u32 ncchSize) return decryptExeFs(cxi); } +static inline void twlConsoleInfoInit(void) +{ + u64 twlConsoleId = CFG_UNITINFO != 0 ? OTP_DEVCONSOLEID : (0x80000000ULL | (*(vu64 *)0x01FFB808 ^ 0x8C267B7B358A6AFULL)); + CFG_TWLUNITINFO = CFG_UNITINFO; + OTP_TWLCONSOLEID = twlConsoleId; + + *REG_AESCNT = 0; + + vu32 *k3X = REGs_AESTWLKEYS[3][1], *k1X = REGs_AESTWLKEYS[1][1]; + + k3X[0] = (u32)twlConsoleId; + k3X[3] = (u32)(twlConsoleId >> 32); + + k1X[2] = (u32)(twlConsoleId >> 32); + k1X[3] = (u32)twlConsoleId; +} + void kernel9Loader(Arm9Bin *arm9Section) { //Determine the kernel9loader version @@ -538,18 +538,42 @@ void kernel9Loader(Arm9Bin *arm9Section) if(*startOfArm9Bin != 0x47704770 && *startOfArm9Bin != 0xB0862000) error("Failed to decrypt the ARM9 binary."); } - //Set >=9.6 KeyXs + __attribute__((aligned(4))) u8 keyBlocks[2][AES_BLOCK_SIZE] = { + {0xA4, 0x8D, 0xE4, 0xF1, 0x0B, 0x36, 0x44, 0xAA, 0x90, 0x31, 0x28, 0xFF, 0x4D, 0xCA, 0x76, 0xDF}, + {0xDD, 0xDA, 0xA4, 0xC6, 0x2C, 0xC4, 0x50, 0xE9, 0xDA, 0xB6, 0x9B, 0x0D, 0x9D, 0x2A, 0x21, 0x98} + }, decKey[AES_BLOCK_SIZE]; + + u8 firstKey; + u32 keyBlocksIndex; + if(k9lVersion == 2) { - __attribute__((aligned(4))) u8 keyData[AES_BLOCK_SIZE] = {0xDD, 0xDA, 0xA4, 0xC6, 0x2C, 0xC4, 0x50, 0xE9, 0xDA, 0xB6, 0x9B, 0x0D, 0x9D, 0x2A, 0x21, 0x98}, - decKey[sizeof(keyData)]; + firstKey = 0x19; + keyBlocksIndex = 1; + } + else + { + firstKey = 0x18; + keyBlocksIndex = 0; + } - //Set keys 0x19..0x1F keyXs - aes_use_keyslot(0x11); - for(u8 slot = 0x19; slot < 0x20; slot++, keyData[0xF]++) + aes_use_keyslot(0x11); + for(u8 slot = firstKey; slot < 0x20; slot++, keyBlocks[keyBlocksIndex][0xF]++) + { + aes(decKey, keyBlocks[keyBlocksIndex], 1, NULL, AES_ECB_DECRYPT_MODE, 0); + aes_setkey(slot, decKey, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL); + } + + if(ISSIGHAX) + { + twlConsoleInfoInit(); + + if(k9lVersion == 2) { - aes(decKey, keyData, 1, NULL, AES_ECB_DECRYPT_MODE, 0); - aes_setkey(slot, decKey, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL); + aes_setkey(0x11, key1s[ISDEVUNIT ? 1 : 0], AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL); + aes_use_keyslot(0x11); + aes(decKey, keyBlocks[0], 1, NULL, AES_ECB_DECRYPT_MODE, 0); + aes_setkey(0x18, decKey, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL); } } } diff --git a/source/crypto.h b/source/crypto.h index bbd5366..31b3182 100755 --- a/source/crypto.h +++ b/source/crypto.h @@ -107,7 +107,6 @@ extern u32 emuOffset; extern FirmwareSource firmSource; -void twlConsoleInfoInit(void); void ctrNandInit(void); int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf); int ctrNandWrite(u32 sector, u32 sectorCount, const u8 *inbuf); diff --git a/source/firm.c b/source/firm.c index bd9d39e..bcf80cb 100755 --- a/source/firm.c +++ b/source/firm.c @@ -117,9 +117,6 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, boo u8 *arm9Section = (u8 *)firm + firm->section[2].offset, *arm11Section1 = (u8 *)firm + firm->section[1].offset; - //On sighax cold boot, initialize TWL keys - if(!(CFG_SYSPROT9 & 2)) twlConsoleInfoInit(); - if(ISN3DS) { //Decrypt ARM9Bin and patch ARM9 entrypoint to skip kernel9loader diff --git a/source/types.h b/source/types.h index 8b624d4..38d6b65 100644 --- a/source/types.h +++ b/source/types.h @@ -52,6 +52,7 @@ typedef volatile u64 vu64; #define ISN3DS (PDN_MPCORE_CFG == 7) #define ISDEVUNIT (CFG_UNITINFO != 0) #define ISA9LH (!PDN_SPI_CNT) +#define ISSIGHAX (!(CFG_SYSPROT9 & 2)) #define ISFIRMLAUNCH (launchedFirmTidLow[5] != 0) typedef struct __attribute__((packed))