Improved unit type detection code

This commit is contained in:
d0k3 2017-05-18 12:41:34 +02:00
parent 2a8debfef2
commit 70791cd9b5
4 changed files with 23 additions and 17 deletions

View File

@ -11,3 +11,10 @@
// see: https://3dbrew.org/wiki/CONFIG11_Registers // see: https://3dbrew.org/wiki/CONFIG11_Registers
#define IS_A9LH ((*(vu32*) 0x101401C0) == 0) #define IS_A9LH ((*(vu32*) 0x101401C0) == 0)
// https://www.3dbrew.org/wiki/CONFIG9_Registers
// (actually checks for an unlocked OTP)
#define IS_UNLOCKED (!((*(vu8*)0x10000000) & 0x2))
// A9LH + unlocked = SigHax
#define IS_SIGHAX (IS_A9LH && IS_UNLOCKED)

View File

@ -81,7 +81,7 @@ u32 SafeSigHaxInstaller(void) {
// step #0 - a9lh check // step #0 - a9lh check
InitNandCrypto(); // for sector0x96 crypto and NAND drives InitNandCrypto(); // for sector0x96 crypto and NAND drives
snprintf(msgA9lh, 64, CheckA9lh() ? "installed" : "not installed"); snprintf(msgA9lh, 64, (IS_A9LH && !IS_SIGHAX) ? "installed" : "not installed");
statusA9lh = STATUS_GREEN; statusA9lh = STATUS_GREEN;
ShowInstallerStatus(); ShowInstallerStatus();
@ -140,7 +140,7 @@ u32 SafeSigHaxInstaller(void) {
// step #3 - check secret_sector.bin file // step #3 - check secret_sector.bin file
u8 secret_sector[0x200]; u8 secret_sector[0x200];
if (CheckA9lh()) { if ((IS_A9LH && !IS_SIGHAX)) {
snprintf(msgSector, 64, "checking..."); snprintf(msgSector, 64, "checking...");
statusSector = STATUS_YELLOW; statusSector = STATUS_YELLOW;
ShowInstallerStatus(); ShowInstallerStatus();
@ -170,7 +170,7 @@ u32 SafeSigHaxInstaller(void) {
statusCrypto = STATUS_RED; statusCrypto = STATUS_RED;
return 1; return 1;
} }
if (CheckA9lh() && !CheckSector0x96Crypto()) { if ((IS_A9LH && !IS_SIGHAX) && !CheckSector0x96Crypto()) {
snprintf(msgCrypto, 64, "OTP crypto fail"); snprintf(msgCrypto, 64, "OTP crypto fail");
statusCrypto = STATUS_RED; statusCrypto = STATUS_RED;
return 1; return 1;
@ -218,7 +218,7 @@ u32 SafeSigHaxInstaller(void) {
statusBackup = STATUS_RED; statusBackup = STATUS_RED;
return 1; return 1;
} }
if (CheckA9lh()) { if ((IS_A9LH && !IS_SIGHAX)) {
snprintf(msgBackup, 64, "0x96 backup..."); snprintf(msgBackup, 64, "0x96 backup...");
ShowInstallerStatus(); ShowInstallerStatus();
u8 sector_backup0[0x200]; u8 sector_backup0[0x200];
@ -255,7 +255,7 @@ u32 SafeSigHaxInstaller(void) {
ShowProgress(1, 2, "FIRM install (2/2)"); ShowProgress(1, 2, "FIRM install (2/2)");
snprintf(msgInstall, 64, "FIRM install (2/2)"); snprintf(msgInstall, 64, "FIRM install (2/2)");
ShowInstallerStatus(); ShowInstallerStatus();
if (CheckA9lh()) { if ((IS_A9LH && !IS_SIGHAX)) {
snprintf(msgInstall, 64, "0x96 revert..."); snprintf(msgInstall, 64, "0x96 revert...");
ShowInstallerStatus(); ShowInstallerStatus();
ret = SafeWriteNand(secret_sector, 0x96 * 0x200, 0x200, 0x11); ret = SafeWriteNand(secret_sector, 0x96 * 0x200, 0x200, 0x11);
@ -269,7 +269,7 @@ u32 SafeSigHaxInstaller(void) {
} else { } else {
snprintf(msgInstall, 64, "install failed"); snprintf(msgInstall, 64, "install failed");
statusInstall = STATUS_RED; statusInstall = STATUS_RED;
if (CheckA9lh()) { if ((IS_A9LH && !IS_SIGHAX)) {
snprintf(msgA9lh, 64, "fucked up"); snprintf(msgA9lh, 64, "fucked up");
statusA9lh = STATUS_RED; statusA9lh = STATUS_RED;
} }

View File

@ -14,6 +14,11 @@ static const u8 slot0x11Key95_sha256[0x20] = { // slot0x11Key95 hash (first 16 b
0xBA, 0xC1, 0x40, 0x9C, 0x6E, 0xE4, 0x1F, 0x04, 0xAA, 0xC4, 0xE2, 0x09, 0x5C, 0xE9, 0x4F, 0x78, 0xBA, 0xC1, 0x40, 0x9C, 0x6E, 0xE4, 0x1F, 0x04, 0xAA, 0xC4, 0xE2, 0x09, 0x5C, 0xE9, 0x4F, 0x78,
0x6C, 0x78, 0x5F, 0xAC, 0xEC, 0x7E, 0xC0, 0x11, 0x26, 0x9D, 0x4E, 0x47, 0xB3, 0x64, 0xC4, 0xA5 0x6C, 0x78, 0x5F, 0xAC, 0xEC, 0x7E, 0xC0, 0x11, 0x26, 0x9D, 0x4E, 0x47, 0xB3, 0x64, 0xC4, 0xA5
}; };
static const u8 slot0x11Key95dev_sha256[0x20] = { // slot0x11Key95 hash (first 16 byte of sector0x96)
0x97, 0x0E, 0x52, 0x29, 0x63, 0x19, 0x47, 0x51, 0x15, 0xD8, 0x02, 0x7A, 0x22, 0x0F, 0x58, 0x15,
0xD7, 0x6C, 0xE9, 0xAD, 0xE7, 0xFE, 0x9A, 0x25, 0x4E, 0x4A, 0x0C, 0x82, 0x67, 0xB5, 0x4A, 0x7B
};
static const u8 nand_magic_n3ds[0x60] = { // NCSD NAND header N3DS magic static const u8 nand_magic_n3ds[0x60] = { // NCSD NAND header N3DS magic
0x4E, 0x43, 0x53, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4E, 0x43, 0x53, 0x44, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -55,7 +60,7 @@ u32 LoadKeyYFromP9(u8* key, const u8* keyhash, u32 offset, u32 keyslot)
u8 header[0x200]; u8 header[0x200];
// check arm9loaderhax // check arm9loaderhax
if (!CheckA9lh() || (offset < (offsetA9l + 0x0800))) return 1; if (!IS_A9LH || (offset < (offsetA9l + 0x0800))) return 1;
// section 2 (arm9loader) header of FIRM // section 2 (arm9loader) header of FIRM
// this is @0x066A00 in FIRM90 & FIRM81 // this is @0x066A00 in FIRM90 & FIRM81
@ -86,7 +91,7 @@ bool InitNandCrypto(void)
{ {
// part #0: KeyX / KeyY for secret sector 0x96 // part #0: KeyX / KeyY for secret sector 0x96
// on a9lh this MUST be run before accessing the SHA register in any other way // on a9lh this MUST be run before accessing the SHA register in any other way
if (CheckA9lh()) { // for a9lh if (IS_A9LH) { // for a9lh
// store the current SHA256 from register // store the current SHA256 from register
memcpy(OtpSha256, (void*) REG_SHAHASH, 32); memcpy(OtpSha256, (void*) REG_SHAHASH, 32);
} }
@ -105,7 +110,7 @@ bool InitNandCrypto(void)
// part #2: TWL KEY // part #2: TWL KEY
// see: https://www.3dbrew.org/wiki/Memory_layout#ARM9_ITCM // see: https://www.3dbrew.org/wiki/Memory_layout#ARM9_ITCM
if (CheckA9lh()) { // only for a9lh if (IS_A9LH) { // only for a9lh
u32* TwlCustId = (u32*) (0x01FFB808); u32* TwlCustId = (u32*) (0x01FFB808);
u8 TwlKeyX[16] __attribute__((aligned(32))); u8 TwlKeyX[16] __attribute__((aligned(32)));
u8 TwlKeyY[16] __attribute__((aligned(32))); u8 TwlKeyY[16] __attribute__((aligned(32)));
@ -132,7 +137,7 @@ bool InitNandCrypto(void)
// part #3: CTRNAND N3DS KEY // part #3: CTRNAND N3DS KEY
// thanks AuroraWright and Gelex for advice on this // thanks AuroraWright and Gelex for advice on this
// see: https://github.com/AuroraWright/Luma3DS/blob/master/source/crypto.c#L347 // see: https://github.com/AuroraWright/Luma3DS/blob/master/source/crypto.c#L347
if (CheckA9lh()) { // only for a9lh if (IS_A9LH) { // only for a9lh
// keyY 0x05 is encrypted @0x0EB014 in the FIRM90 // keyY 0x05 is encrypted @0x0EB014 in the FIRM90
// keyY 0x05 is encrypted @0x0EB24C in the FIRM81 // keyY 0x05 is encrypted @0x0EB24C in the FIRM81
if ((LoadKeyYFromP9(slot0x05KeyY, slot0x05KeyY_sha256, 0x0EB014, 0x05) != 0) && if ((LoadKeyYFromP9(slot0x05KeyY, slot0x05KeyY_sha256, 0x0EB014, 0x05) != 0) &&
@ -166,7 +171,7 @@ bool CheckSector0x96Crypto(void)
{ {
u8 buffer[0x200]; u8 buffer[0x200];
ReadNandSectors(buffer, 0x96, 1, 0x11); ReadNandSectors(buffer, 0x96, 1, 0x11);
return (sha_cmp(slot0x11Key95_sha256, buffer, 16, SHA256_MODE) == 0); return (sha_cmp((IS_DEVKIT) ? slot0x11Key95dev_sha256 : slot0x11Key95_sha256, buffer, 16, SHA256_MODE) == 0);
} }
bool CheckFirmCrypto(void) bool CheckFirmCrypto(void)
@ -184,11 +189,6 @@ bool CheckFirmCrypto(void)
return true; return true;
} }
bool CheckA9lh(void)
{
return ((*(vu32*) 0x101401C0) == 0);
}
void CryptNand(void* buffer, u32 sector, u32 count, u32 keyslot) void CryptNand(void* buffer, u32 sector, u32 count, u32 keyslot)
{ {
u32 mode = (sector >= SECTOR_TWL + SIZE_TWL) ? AES_CNT_CTRNAND_MODE : AES_CNT_TWLNAND_MODE; u32 mode = (sector >= SECTOR_TWL + SIZE_TWL) ? AES_CNT_CTRNAND_MODE : AES_CNT_TWLNAND_MODE;

View File

@ -39,7 +39,6 @@ bool InitNandCrypto(void);
bool CheckSlot0x05Crypto(void); bool CheckSlot0x05Crypto(void);
bool CheckSector0x96Crypto(void); bool CheckSector0x96Crypto(void);
bool CheckFirmCrypto(void); bool CheckFirmCrypto(void);
bool CheckA9lh(void);
void CryptNand(void* buffer, u32 sector, u32 count, u32 keyslot); void CryptNand(void* buffer, u32 sector, u32 count, u32 keyslot);
void CryptSector0x96(void* buffer, bool encrypt); void CryptSector0x96(void* buffer, bool encrypt);