Fix unaligned crypto buffers

This commit is contained in:
Wolfvak 2019-10-14 13:11:23 -03:00
parent 915cb2d13e
commit 0f42426115

View File

@ -26,37 +26,37 @@ static const u32 np_keyslots[10][4] = { // [NP_TYPE][NP_SUBTYPE]
{ 0xFF, 0xFF, 0xFF, 0xFF } // BONUS (custom) { 0xFF, 0xFF, 0xFF, 0xFF } // BONUS (custom)
}; };
static u8 slot0x05KeyY[0x10] __attribute__((aligned(4))) = { 0x00 }; // need to load this from FIRM0 / external file static u8 ALIGN(4) slot0x05KeyY[0x10] = { 0x00 }; // need to load this from FIRM0 / external file
static const u8 slot0x05KeyY_sha256[0x20] = { // hash for slot0x05KeyY (16 byte) static const u8 ALIGN(4) slot0x05KeyY_sha256[0x20] = { // hash for slot0x05KeyY (16 byte)
0x98, 0x24, 0x27, 0x14, 0x22, 0xB0, 0x6B, 0xF2, 0x10, 0x96, 0x9C, 0x36, 0x42, 0x53, 0x7C, 0x86, 0x98, 0x24, 0x27, 0x14, 0x22, 0xB0, 0x6B, 0xF2, 0x10, 0x96, 0x9C, 0x36, 0x42, 0x53, 0x7C, 0x86,
0x62, 0x22, 0x5C, 0xFD, 0x6F, 0xAE, 0x9B, 0x0A, 0x85, 0xA5, 0xCE, 0x21, 0xAA, 0xB6, 0xC8, 0x4D 0x62, 0x22, 0x5C, 0xFD, 0x6F, 0xAE, 0x9B, 0x0A, 0x85, 0xA5, 0xCE, 0x21, 0xAA, 0xB6, 0xC8, 0x4D
}; };
static const u8 slot0x11Key95_sha256[0x20] = { // slot0x11Key95 hash (first 16 byte of sector0x96) static const u8 ALIGN(4) slot0x11Key95_sha256[0x20] = { // slot0x11Key95 hash (first 16 byte of sector0x96)
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) static const u8 ALIGN(4) 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, 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 0xD7, 0x6C, 0xE9, 0xAD, 0xE7, 0xFE, 0x9A, 0x25, 0x4E, 0x4A, 0x0C, 0x82, 0x67, 0xB5, 0x4A, 0x7B
}; };
// from: https://github.com/AuroraWright/SafeA9LHInstaller/blob/master/source/installer.c#L9-L17 // from: https://github.com/AuroraWright/SafeA9LHInstaller/blob/master/source/installer.c#L9-L17
static const u8 sector0x96_sha256[0x20] = { // hash for legit sector 0x96 (different on A9LH) static const u8 ALIGN(4) sector0x96_sha256[0x20] = { // hash for legit sector 0x96 (different on A9LH)
0x82, 0xF2, 0x73, 0x0D, 0x2C, 0x2D, 0xA3, 0xF3, 0x01, 0x65, 0xF9, 0x87, 0xFD, 0xCC, 0xAC, 0x5C, 0x82, 0xF2, 0x73, 0x0D, 0x2C, 0x2D, 0xA3, 0xF3, 0x01, 0x65, 0xF9, 0x87, 0xFD, 0xCC, 0xAC, 0x5C,
0xBA, 0xB2, 0x4B, 0x4E, 0x5F, 0x65, 0xC9, 0x81, 0xCD, 0x7B, 0xE6, 0xF4, 0x38, 0xE6, 0xD9, 0xD3 0xBA, 0xB2, 0x4B, 0x4E, 0x5F, 0x65, 0xC9, 0x81, 0xCD, 0x7B, 0xE6, 0xF4, 0x38, 0xE6, 0xD9, 0xD3
}; };
// from: https://github.com/SciresM/CTRAesEngine/tree/master/CTRAesEngine/Resources/_byte // from: https://github.com/SciresM/CTRAesEngine/tree/master/CTRAesEngine/Resources/_byte
static const u8 sector0x96dev_sha256[0x20] = { // hash for legit sector 0x96 (different on A9LH) static const u8 ALIGN(4) sector0x96dev_sha256[0x20] = { // hash for legit sector 0x96 (different on A9LH)
0xB2, 0x91, 0xD9, 0xB1, 0x33, 0x05, 0x79, 0x0D, 0x47, 0xC6, 0x06, 0x98, 0x4C, 0x67, 0xC3, 0x70, 0xB2, 0x91, 0xD9, 0xB1, 0x33, 0x05, 0x79, 0x0D, 0x47, 0xC6, 0x06, 0x98, 0x4C, 0x67, 0xC3, 0x70,
0x09, 0x54, 0xE3, 0x85, 0xDE, 0x47, 0x55, 0xAF, 0xC6, 0xCB, 0x1D, 0x8D, 0xC7, 0x84, 0x5A, 0x64 0x09, 0x54, 0xE3, 0x85, 0xDE, 0x47, 0x55, 0xAF, 0xC6, 0xCB, 0x1D, 0x8D, 0xC7, 0x84, 0x5A, 0x64
}; };
static u8 CtrNandCtr[16]; static u8 ALIGN(4) CtrNandCtr[16];
static u8 TwlNandCtr[16]; static u8 ALIGN(4) TwlNandCtr[16];
static u8 OtpSha256[32] = { 0 }; static u8 ALIGN(4) OtpSha256[32] = { 0 };
static bool Crypto0x96 = false; static bool Crypto0x96 = false;
static u32 emunand_base_sector = 0x000000; static u32 emunand_base_sector = 0x000000;
@ -65,8 +65,8 @@ static u32 emunand_base_sector = 0x000000;
bool GetOtp0x90(void* otp0x90, u32 len) bool GetOtp0x90(void* otp0x90, u32 len)
{ {
// a short helper function for crypto setup outside of sighax // a short helper function for crypto setup outside of sighax
u8 __attribute__((aligned(32))) otp_key[0x10]; u8 ALIGN(32) otp_key[0x10];
u8 __attribute__((aligned(32))) otp_iv[0x10]; u8 ALIGN(32) otp_iv[0x10];
len = len - (len % 0x10); len = len - (len % 0x10);
if (len > 0x90) len = 0x90; if (len > 0x90) len = 0x90;
@ -91,7 +91,7 @@ bool InitNandCrypto(bool init_full)
Crypto0x96 = true; // valid 100% in that case, others need checking Crypto0x96 = true; // valid 100% in that case, others need checking
} }
if (!CheckSector0x96Crypto()) { // if all else fails... if (!CheckSector0x96Crypto()) { // if all else fails...
u8 __attribute__((aligned(32))) otp0x90[0x90]; u8 ALIGN(32) otp0x90[0x90];
if (GetOtp0x90(otp0x90, 0x90)) if (GetOtp0x90(otp0x90, 0x90))
sha_quick(OtpSha256, otp0x90, 0x90, SHA256_MODE); sha_quick(OtpSha256, otp0x90, 0x90, SHA256_MODE);
} }
@ -115,13 +115,13 @@ bool InitNandCrypto(bool init_full)
if (!IS_DEVKIT) TwlCustId = 0x80000000ULL | (*(vu64 *)0x01FFB808 ^ 0x8C267B7B358A6AFULL); if (!IS_DEVKIT) TwlCustId = 0x80000000ULL | (*(vu64 *)0x01FFB808 ^ 0x8C267B7B358A6AFULL);
else if (IS_UNLOCKED) TwlCustId = (*(vu64*)__OTP_ADDR); else if (IS_UNLOCKED) TwlCustId = (*(vu64*)__OTP_ADDR);
if (!TwlCustId && IS_DEVKIT) { if (!TwlCustId && IS_DEVKIT) {
u64 __attribute__((aligned(32))) otp0x10[2]; u64 ALIGN(32) otp0x10[2];
if (GetOtp0x90(otp0x10, 0x10)) TwlCustId = *otp0x10; if (GetOtp0x90(otp0x10, 0x10)) TwlCustId = *otp0x10;
} }
if (TwlCustId) { // give up if TwlCustId not found if (TwlCustId) { // give up if TwlCustId not found
u32 TwlKey0x03Y[4] __attribute__((aligned(32))); u32 ALIGN(32) TwlKey0x03Y[4];
u32 TwlKey0x03X[4] __attribute__((aligned(32))); u32 ALIGN(32) TwlKey0x03X[4];
if (IS_DEVKIT) { if (IS_DEVKIT) {
TwlKey0x03X[1] = 0xEE7A4B1E; TwlKey0x03X[1] = 0xEE7A4B1E;
@ -148,7 +148,7 @@ bool InitNandCrypto(bool init_full)
setup_aeskeyX(0x02, (u8*)0x01FFD398); setup_aeskeyX(0x02, (u8*)0x01FFD398);
if (IS_DEVKIT) { if (IS_DEVKIT) {
u32 TwlKey0x02Y[4] __attribute__((aligned(32))); u32 ALIGN(32) TwlKey0x02Y[4];
LoadKeyFromFile(TwlKey0x02Y, 0x02, 'Y', NULL); LoadKeyFromFile(TwlKey0x02Y, 0x02, 'Y', NULL);
setup_aeskeyY(0x02, TwlKey0x02Y); setup_aeskeyY(0x02, TwlKey0x02Y);
} else setup_aeskeyY(0x02, (u8*)0x01FFD220); } else setup_aeskeyY(0x02, (u8*)0x01FFD220);
@ -191,7 +191,7 @@ bool CheckSlot0x05Crypto(void)
bool CheckSector0x96Crypto(void) bool CheckSector0x96Crypto(void)
{ {
if (!Crypto0x96) { if (!Crypto0x96) {
u8 buffer[0x200] __attribute__((aligned(4))); u8 ALIGN(4) buffer[0x200];
ReadNandSectors(buffer, SECTOR_SECRET, 1, 0x11, NAND_SYSNAND); ReadNandSectors(buffer, SECTOR_SECRET, 1, 0x11, NAND_SYSNAND);
Crypto0x96 = (sha_cmp(KEY95_SHA256, buffer, 16, SHA256_MODE) == 0); Crypto0x96 = (sha_cmp(KEY95_SHA256, buffer, 16, SHA256_MODE) == 0);
} }
@ -200,16 +200,16 @@ bool CheckSector0x96Crypto(void)
bool CheckGenuineNandNcsd(void) bool CheckGenuineNandNcsd(void)
{ {
u8 gen_o3ds_hash[0x20] = { u8 ALIGN(4) gen_o3ds_hash[0x20] = {
0xCD, 0xB8, 0x2B, 0xF3, 0xE0, 0xC7, 0xA3, 0xC7, 0x58, 0xDF, 0xDC, 0x4E, 0x27, 0x63, 0xBE, 0xE8, 0xCD, 0xB8, 0x2B, 0xF3, 0xE0, 0xC7, 0xA3, 0xC7, 0x58, 0xDF, 0xDC, 0x4E, 0x27, 0x63, 0xBE, 0xE8,
0xBE, 0x2B, 0x1D, 0xF4, 0xBA, 0x97, 0xAF, 0x7F, 0x19, 0x70, 0x99, 0xDB, 0x66, 0xF7, 0x2F, 0xD7 0xBE, 0x2B, 0x1D, 0xF4, 0xBA, 0x97, 0xAF, 0x7F, 0x19, 0x70, 0x99, 0xDB, 0x66, 0xF7, 0x2F, 0xD7
}; };
u8 gen_n3ds_hash[0x20] = { u8 ALIGN(4) gen_n3ds_hash[0x20] = {
0x49, 0xB7, 0x4A, 0xF1, 0xFD, 0xB7, 0xCF, 0x5B, 0x76, 0x8F, 0xA2, 0x94, 0x0D, 0xB2, 0xB3, 0xE2, 0x49, 0xB7, 0x4A, 0xF1, 0xFD, 0xB7, 0xCF, 0x5B, 0x76, 0x8F, 0xA2, 0x94, 0x0D, 0xB2, 0xB3, 0xE2,
0xA4, 0xBD, 0x25, 0x03, 0x06, 0x03, 0x47, 0x0B, 0x24, 0x5A, 0x86, 0x6A, 0x43, 0x60, 0xBC, 0x84, 0xA4, 0xBD, 0x25, 0x03, 0x06, 0x03, 0x47, 0x0B, 0x24, 0x5A, 0x86, 0x6A, 0x43, 0x60, 0xBC, 0x84,
}; };
u8 gen_hdr[0x100] __attribute__((aligned(4))); u8 ALIGN(4) gen_hdr[0x100];
if ((ReadNandBytes(gen_hdr, 0x100, 0x100, 0xFF, NAND_SYSNAND) != 0) || if ((ReadNandBytes(gen_hdr, 0x100, 0x100, 0xFF, NAND_SYSNAND) != 0) ||
(ReadNandBytes(gen_hdr + 0xBE, 0x1BE, 0x42, 0x03, NAND_SYSNAND) != 0)) (ReadNandBytes(gen_hdr + 0xBE, 0x1BE, 0x42, 0x03, NAND_SYSNAND) != 0))
return false; return false;
@ -220,7 +220,7 @@ bool CheckGenuineNandNcsd(void)
void CryptNand(void* buffer, u32 sector, u32 count, u32 keyslot) void CryptNand(void* buffer, u32 sector, u32 count, u32 keyslot)
{ {
u32 mode = (keyslot != 0x03) ? AES_CNT_CTRNAND_MODE : AES_CNT_TWLNAND_MODE; // somewhat hacky u32 mode = (keyslot != 0x03) ? AES_CNT_CTRNAND_MODE : AES_CNT_TWLNAND_MODE; // somewhat hacky
u8 ctr[16] __attribute__((aligned(32))); u8 ALIGN(32) ctr[16];
u32 blocks = count * (0x200 / 0x10); u32 blocks = count * (0x200 / 0x10);
// copy NAND CTR and increment it // copy NAND CTR and increment it