mirror of
https://github.com/d0k3/SafeB9SInstaller.git
synced 2025-06-26 05:32:45 +00:00
Improved unit type detection code
This commit is contained in:
parent
2a8debfef2
commit
70791cd9b5
@ -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)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user