mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 13:42:47 +00:00
Properly check for slot0x05 crypto & EmuNAND availability
This commit is contained in:
parent
0b735edc49
commit
762dce04cd
@ -534,7 +534,7 @@ bool GetRootDirContentsWorker(DirStruct* contents) {
|
|||||||
"SYSNAND VIRTUAL", "EMUNAND VIRTUAL"
|
"SYSNAND VIRTUAL", "EMUNAND VIRTUAL"
|
||||||
};
|
};
|
||||||
static const char* drvnum[] = {
|
static const char* drvnum[] = {
|
||||||
"0", "1", "2", "3", "4", "5", "6", "S", "E"
|
"0:", "1:", "2:", "3:", "4:", "5:", "6:", "S:", "E:"
|
||||||
};
|
};
|
||||||
u32 n_entries = 0;
|
u32 n_entries = 0;
|
||||||
|
|
||||||
@ -542,11 +542,10 @@ bool GetRootDirContentsWorker(DirStruct* contents) {
|
|||||||
for (u32 pdrv = 0; (pdrv < MAX_FS+2) && (n_entries < MAX_ENTRIES); pdrv++) {
|
for (u32 pdrv = 0; (pdrv < MAX_FS+2) && (n_entries < MAX_ENTRIES); pdrv++) {
|
||||||
DirEntry* entry = &(contents->entry[n_entries]);
|
DirEntry* entry = &(contents->entry[n_entries]);
|
||||||
if ((pdrv < MAX_FS) && !fs_mounted[pdrv]) continue;
|
if ((pdrv < MAX_FS) && !fs_mounted[pdrv]) continue;
|
||||||
if ((pdrv == MAX_FS+0) && (!fs_mounted[1])) continue;
|
else if ((pdrv >= MAX_FS) && (!CheckVirtualPath(drvnum[pdrv]))) continue;
|
||||||
if ((pdrv == MAX_FS+1) && (!fs_mounted[4])) continue;
|
|
||||||
memset(entry->path, 0x00, 64);
|
memset(entry->path, 0x00, 64);
|
||||||
snprintf(entry->path + 0, 4, "%s:", drvnum[pdrv]);
|
snprintf(entry->path + 0, 4, drvnum[pdrv]);
|
||||||
snprintf(entry->path + 4, 32, "[%s:] %s", drvnum[pdrv], drvname[pdrv]);
|
snprintf(entry->path + 4, 32, "[%s] %s", drvnum[pdrv], drvname[pdrv]);
|
||||||
entry->name = entry->path + 4;
|
entry->name = entry->path + 4;
|
||||||
entry->size = GetTotalSpace(entry->path);
|
entry->size = GetTotalSpace(entry->path);
|
||||||
entry->type = T_ROOT;
|
entry->type = T_ROOT;
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
#include "hid.h"
|
#include "hid.h"
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
|
#include "platform.h"
|
||||||
#include "nand.h"
|
#include "nand.h"
|
||||||
#include "virtual.h"
|
#include "virtual.h"
|
||||||
|
|
||||||
#define VERSION "0.1.9"
|
#define VERSION "0.2.0"
|
||||||
|
|
||||||
#define COLOR_TOP_BAR ((GetWritePermissions() == 0) ? COLOR_WHITE : (GetWritePermissions() == 1) ? COLOR_BRIGHTGREEN : (GetWritePermissions() == 2) ? COLOR_BRIGHTYELLOW : COLOR_RED)
|
#define COLOR_TOP_BAR ((GetWritePermissions() == 0) ? COLOR_WHITE : (GetWritePermissions() == 1) ? COLOR_BRIGHTGREEN : (GetWritePermissions() == 2) ? COLOR_BRIGHTYELLOW : COLOR_RED)
|
||||||
#define COLOR_SIDE_BAR COLOR_DARKGREY
|
#define COLOR_SIDE_BAR COLOR_DARKGREY
|
||||||
@ -151,6 +152,14 @@ u32 GodMode() {
|
|||||||
InitNandCrypto();
|
InitNandCrypto();
|
||||||
InitNandFS();
|
InitNandFS();
|
||||||
|
|
||||||
|
if ((GetUnitPlatform() == PLATFORM_N3DS) && !CheckSlot0x05Crypto()) {
|
||||||
|
if (!ShowPrompt(true, "Warning: slot0x05 crypto fail\nslot0x05keyY.bin is either corrupt\nor does not exist. Continue?")) {
|
||||||
|
DeinitNandFS();
|
||||||
|
DeinitSDCardFS();
|
||||||
|
return exit_mode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GetDirContents(current_dir, "");
|
GetDirContents(current_dir, "");
|
||||||
clipboard->n_entries = 0;
|
clipboard->n_entries = 0;
|
||||||
while (true) { // this is the main loop
|
while (true) { // this is the main loop
|
||||||
|
@ -8,6 +8,12 @@
|
|||||||
#define NAND_BUFFER ((u8*)0x21100000)
|
#define NAND_BUFFER ((u8*)0x21100000)
|
||||||
#define NAND_BUFFER_SIZE (0x100000) // must be multiple of 0x200
|
#define NAND_BUFFER_SIZE (0x100000) // must be multiple of 0x200
|
||||||
|
|
||||||
|
static u8 slot0x05KeyY[0x10] = { 0x00 }; // need to load this from file
|
||||||
|
static u8 slot0x05KeyY_sha256[0x20] = { // hash for slot0x05KeyY file
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
static u8 nand_magic_n3ds[0x60] = { // NCSD NAND header N3DS magic
|
static 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,
|
||||||
0x01, 0x04, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x03, 0x00, 0x00, 0x00,
|
0x01, 0x04, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x02, 0x02, 0x03, 0x00, 0x00, 0x00,
|
||||||
@ -73,19 +79,39 @@ bool InitNandCrypto(void)
|
|||||||
use_aeskey(0x03);
|
use_aeskey(0x03);
|
||||||
|
|
||||||
// part #3: CTRNAND N3DS KEY
|
// part #3: CTRNAND N3DS KEY
|
||||||
if (GetUnitPlatform() == PLATFORM_N3DS) {
|
if (FileGetData("0:/slot0x05KeyY.bin", slot0x05KeyY, 16, 0)) {
|
||||||
u8 CtrNandKeyY[16];
|
setup_aeskeyY(0x05, slot0x05KeyY);
|
||||||
|
use_aeskey(0x05);
|
||||||
if (FileGetData("0:/slot0x05KeyY.bin", CtrNandKeyY, 16, 0)) {
|
|
||||||
setup_aeskeyY(0x05, CtrNandKeyY);
|
|
||||||
use_aeskey(0x05);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CheckSlot0x05Crypto(void)
|
||||||
|
{
|
||||||
|
// step #1 - check the slot0x05KeyY SHA-256
|
||||||
|
u8 shasum[32];
|
||||||
|
sha_init(SHA256_MODE);
|
||||||
|
sha_update(slot0x05KeyY, 16);
|
||||||
|
sha_get(shasum);
|
||||||
|
if (memcmp(shasum, slot0x05KeyY_sha256, 32) == 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// step #2 - check actual CTRNAND magic
|
||||||
|
const u8 magic[8] = {0xE9, 0x00, 0x00, 0x43, 0x54, 0x52, 0x20, 0x20};
|
||||||
|
const u32 sector = 0x05CAD7;
|
||||||
|
u8 buffer[0x200];
|
||||||
|
for (u32 nand = 0; nand < 2; nand++) {
|
||||||
|
ReadNandSectors(buffer, sector, 1, 0x05, nand);
|
||||||
|
if (memcmp(buffer, magic, 8) == 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// failed if we arrive here
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void CryptNand(u8* buffer, u32 sector, u32 count, u32 keyslot)
|
void CryptNand(u8* buffer, u32 sector, u32 count, u32 keyslot)
|
||||||
{
|
{
|
||||||
u32 mode = (sector >= (0x0B100000 / 0x200)) ? AES_CNT_CTRNAND_MODE : AES_CNT_TWLNAND_MODE;
|
u32 mode = (sector >= (0x0B100000 / 0x200)) ? AES_CNT_CTRNAND_MODE : AES_CNT_TWLNAND_MODE;
|
||||||
@ -184,5 +210,6 @@ bool InitEmuNandBase(void)
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (GetPartitionOffsetSector("0:") > getMMCDevice(0)->total_size)
|
if (GetPartitionOffsetSector("0:") > getMMCDevice(0)->total_size)
|
||||||
|
emunand_base_sector = 0x000000; // keep unknown EmuNAND as RedNAND only if space is low
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,9 @@
|
|||||||
#define NAND_TYPE_NO3DS (1<<2)
|
#define NAND_TYPE_NO3DS (1<<2)
|
||||||
|
|
||||||
bool InitNandCrypto(void);
|
bool InitNandCrypto(void);
|
||||||
void CryptNand(u8* buffer, u32 sector, u32 count, u32 keyslot);
|
bool CheckSlot0x05Crypto(void);
|
||||||
|
|
||||||
|
void CryptNand(u8* buffer, u32 sector, u32 count, u32 keyslot);
|
||||||
int ReadNandSectors(u8* buffer, u32 sector, u32 count, u32 keyslot, bool read_emunand);
|
int ReadNandSectors(u8* buffer, u32 sector, u32 count, u32 keyslot, bool read_emunand);
|
||||||
int WriteNandSectors(const u8* buffer, u32 sector, u32 count, u32 keyslot, bool write_emunand);
|
int WriteNandSectors(const u8* buffer, u32 sector, u32 count, u32 keyslot, bool write_emunand);
|
||||||
|
|
||||||
|
@ -35,6 +35,16 @@ u32 IsVirtualPath(const char* path) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CheckVirtualPath(const char* path) {
|
||||||
|
u32 vp_nand = IsVirtualPath(path);
|
||||||
|
if (vp_nand == VRT_SYSNAND) {
|
||||||
|
return true; // this is safe because we re-check for slot0x05 crypto
|
||||||
|
} else if (vp_nand == VRT_EMUNAND) {
|
||||||
|
return GetNandSizeSectors(true);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool FindVirtualFile(VirtualFile* vfile, const char* path)
|
bool FindVirtualFile(VirtualFile* vfile, const char* path)
|
||||||
{
|
{
|
||||||
char* fname = strchr(path, '/');
|
char* fname = strchr(path, '/');
|
||||||
@ -68,6 +78,8 @@ bool FindVirtualFile(VirtualFile* vfile, const char* path)
|
|||||||
memcpy(vfile, curr_template, sizeof(VirtualFile));
|
memcpy(vfile, curr_template, sizeof(VirtualFile));
|
||||||
|
|
||||||
// process special flags
|
// process special flags
|
||||||
|
if ((vfile->keyslot == 0x05) && !CheckSlot0x05Crypto())
|
||||||
|
return false; // keyslot 0x05 not properly set up
|
||||||
if (vfile->flags & VFLAG_NAND_SIZE) {
|
if (vfile->flags & VFLAG_NAND_SIZE) {
|
||||||
if (on_emunand && (GetNandSizeSectors(false) != GetNandSizeSectors(true)))
|
if (on_emunand && (GetNandSizeSectors(false) != GetNandSizeSectors(true)))
|
||||||
return false; // EmuNAND is too small
|
return false; // EmuNAND is too small
|
||||||
|
@ -22,6 +22,7 @@ typedef struct {
|
|||||||
} __attribute__((packed)) VirtualFile;
|
} __attribute__((packed)) VirtualFile;
|
||||||
|
|
||||||
u32 IsVirtualPath(const char* path);
|
u32 IsVirtualPath(const char* path);
|
||||||
|
bool CheckVirtualPath(const char* path);
|
||||||
bool FindVirtualFile(VirtualFile* vfile, const char* path);
|
bool FindVirtualFile(VirtualFile* vfile, const char* path);
|
||||||
int ReadVirtualFile(const VirtualFile* vfile, u8* buffer, u32 offset, u32 count);
|
int ReadVirtualFile(const VirtualFile* vfile, u8* buffer, u32 offset, u32 count);
|
||||||
int WriteVirtualFile(const VirtualFile* vfile, const u8* buffer, u32 offset, u32 count);
|
int WriteVirtualFile(const VirtualFile* vfile, const u8* buffer, u32 offset, u32 count);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user