Moar checks

This commit is contained in:
Aurora 2016-09-28 21:52:51 +02:00
parent 8a280fa34b
commit cd7f7c02cc
8 changed files with 72 additions and 82 deletions

View File

@ -310,14 +310,14 @@ void ctrNandInit(void)
}
}
u32 ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf)
int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf)
{
u8 __attribute__((aligned(4))) tmpCtr[sizeof(nandCtr)];
memcpy(tmpCtr, nandCtr, sizeof(nandCtr));
aes_advctr(tmpCtr, ((sector + fatStart) * 0x200) / AES_BLOCK_SIZE, AES_INPUT_BE | AES_INPUT_NORMAL);
//Read
u32 result = sdmmc_nand_readsectors(sector + fatStart, sectorCount, outbuf);
int result = sdmmc_nand_readsectors(sector + fatStart, sectorCount, outbuf);
//Decrypt
aes_use_keyslot(nandSlot);
@ -358,28 +358,33 @@ void writeFirm(u8 *inbuf, bool isFirm1, u32 size)
void setupKeyslot0x11(const void *otp, bool isA9lh)
{
u8 __attribute__((aligned(4))) shasum[SHA_256_HASH_SIZE];
u8 __attribute__((aligned(4))) keyX[AES_BLOCK_SIZE];
u8 __attribute__((aligned(4))) keyY[AES_BLOCK_SIZE];
//If booting via A9LH, use the leftover contents of the SHA register
if(isA9lh) memcpy(shasum, (void *)REG_SHA_HASH, sizeof(shasum));
//Else calculate the otp.bin hash
//Otherwise, calculate the otp.bin hash
else sha(shasum, otp, 0x90, SHA_256_MODE);
//Set keyX and keyY
memcpy(keyX, shasum, sizeof(keyX));
memcpy(keyY, shasum + sizeof(keyX), sizeof(keyY));
aes_setkey(0x11, keyX, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_setkey(0x11, keyY, AES_KEYY, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_setkey(0x11, shasum, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_setkey(0x11, shasum + AES_BLOCK_SIZE, AES_KEYY, AES_INPUT_BE | AES_INPUT_NORMAL);
}
void generateSector(u8 *keySector, u32 mode)
{
//Inject key2
if(mode == 0) memcpy(keySector + AES_BLOCK_SIZE, key2s[2], AES_BLOCK_SIZE);
else if(mode == 1) memcpy(keySector + AES_BLOCK_SIZE, keySector, AES_BLOCK_SIZE);
else memcpy(keySector + AES_BLOCK_SIZE, key2s[0], AES_BLOCK_SIZE);
switch(mode)
{
case 1:
memcpy(keySector + AES_BLOCK_SIZE, keySector, AES_BLOCK_SIZE);
break;
case 2:
memcpy(keySector + AES_BLOCK_SIZE, key2s[0], AES_BLOCK_SIZE);
break;
default:
memcpy(keySector + AES_BLOCK_SIZE, key2s[2], AES_BLOCK_SIZE);
break;
}
if(mode != 1)
{
@ -404,7 +409,7 @@ void getSector(u8 *keySector, bool isA9lh)
}
}
u32 verifyHash(const void *data, u32 size, const u8 *hash)
bool verifyHash(const void *data, u32 size, const u8 *hash)
{
u8 __attribute__((aligned(4))) shasum[SHA_256_HASH_SIZE];
sha(shasum, data, size, SHA_256_MODE);

View File

@ -84,11 +84,11 @@ const u8 key2s[3][AES_BLOCK_SIZE];
void getNandCtr(void);
void ctrNandInit(void);
u32 ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf);
int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf);
void readFirm0(u8 *outbuf, u32 size);
void writeFirm(u8 *inbuf, bool isFirm1, u32 size);
void setupKeyslot0x11(const void *otp, bool isA9lh);
void generateSector(u8 *keySector, u32 mode);
void getSector(u8 *keySector, bool isA9lh);
u32 verifyHash(const void *data, u32 size, const u8 *hash);
bool verifyHash(const void *data, u32 size, const u8 *hash);
u32 decryptExeFs(u8 *inbuf);

View File

@ -33,12 +33,10 @@ DSTATUS disk_status (
/* Inidialize a Drive */
/*-----------------------------------------------------------------------*/
DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
if(pdrv == CTRNAND)
ctrNandInit();
@ -58,19 +56,8 @@ DRESULT disk_read (
UINT count /* Number of sectors to read */
)
{
switch(pdrv)
{
case SDCARD:
if(sdmmc_sdcard_readsectors(sector, count, (BYTE *)buff))
return RES_PARERR;
break;
case CTRNAND:
if(ctrNandRead(sector, count, (BYTE *)buff))
return RES_PARERR;
break;
}
return RES_OK;
return ((pdrv == SDCARD && !sdmmc_sdcard_readsectors(sector, count, (BYTE *)buff)) ||
(pdrv == CTRNAND && !ctrNandRead(sector, count, (BYTE *)buff))) ? RES_OK : RES_PARERR;
}
@ -87,10 +74,7 @@ DRESULT disk_write (
UINT count /* Number of sectors to write */
)
{
if(pdrv == SDCARD && sdmmc_sdcard_writesectors(sector, count, (BYTE *)buff))
return RES_PARERR;
return RES_OK;
return (pdrv == SDCARD && !sdmmc_sdcard_writesectors(sector, count, (BYTE *)buff)) ? RES_OK : RES_PARERR;
}
#endif

View File

@ -470,9 +470,8 @@ void sdmmc_get_cid(bool isNand, u32 *info)
sdmmc_send_command(device, 0x10507, device->initarg << 0x10);
}
void sdmmc_sdcard_init()
bool sdmmc_sdcard_init()
{
InitSD();
Nand_Init();
SD_Init();
return Nand_Init() + SD_Init() == 0;
}

View File

@ -91,7 +91,7 @@ typedef struct mmcdevice {
u32 res;
} mmcdevice;
void sdmmc_sdcard_init();
bool sdmmc_sdcard_init();
int sdmmc_sdcard_readsectors(u32 sector_no, u32 numsectors, u8 *out);
int sdmmc_sdcard_writesectors(u32 sector_no, u32 numsectors, const u8 *in);
int sdmmc_nand_readsectors(u32 sector_no, u32 numsectors, u8 *out);

View File

@ -27,14 +27,9 @@
static FATFS fs;
bool mountSd(void)
bool mountFs(bool isSd)
{
return f_mount(&fs, "0:", 1) == FR_OK;
}
bool mountCtrNand(void)
{
return f_mount(&fs, "1:", 1) == FR_OK;
return isSd ? f_mount(&fs, "0:", 1) == FR_OK : f_mount(&fs, "1:", 1) == FR_OK;
}
u32 fileRead(void *dest, const char *path, u32 maxSize)
@ -45,7 +40,7 @@ u32 fileRead(void *dest, const char *path, u32 maxSize)
if(f_open(&file, path, FA_READ) == FR_OK)
{
u32 size = f_size(&file);
if(!(size > maxSize))
if(size <= maxSize)
f_read(&file, dest, size, (unsigned int *)&ret);
f_close(&file);
}
@ -96,11 +91,11 @@ u32 firmRead(void *dest)
DIR dir;
FILINFO info;
f_opendir(&dir, path);
u32 firmVersion = 0xFFFFFFFF,
ret = 0;
if(f_opendir(&dir, path) == FR_OK)
{
//Parse the target directory
while(f_readdir(&dir, &info) == FR_OK && info.fname[0] != 0)
{
@ -127,7 +122,7 @@ u32 firmRead(void *dest)
f_closedir(&dir);
if(!ret)
if(!ret && firmVersion != 0xFFFFFFFF)
{
//Complete the string with the .app name
concatenateStrings(path, "/00000000.app");
@ -137,6 +132,9 @@ u32 firmRead(void *dest)
if(!fileRead(dest, path, 0x100000)) ret = 3;
}
}
if(firmVersion == 0xFFFFFFFF) ret = 4;
return ret;
}

View File

@ -26,8 +26,7 @@
extern bool isN3DS;
bool mountSd(void);
bool mountCtrNand(void);
bool mountFs(bool isSd);
u32 fileRead(void *dest, const char *path, u32 maxSize);
bool fileWrite(const void *buffer, const char *path, u32 size);
u32 firmRead(void *dest);

View File

@ -52,12 +52,14 @@ void main(void)
vu32 *magic = (vu32 *)0x25000000;
bool isOtpless = isA9lh && magic[0] == 0xABADCAFE && magic[1] == 0xDEADCAFE;
sdmmc_sdcard_init();
initScreens();
drawString(TITLE, 10, 10, COLOR_TITLE);
posY = drawString("Thanks to delebile, #cakey and StandardBus", 10, 40, COLOR_WHITE);
if(!sdmmc_sdcard_init() && !isOtpless)
shutdown(1, "Error: failed to initialize SD and NAND");
u32 pressed;
if(!isOtpless)
@ -84,7 +86,7 @@ static inline void installer(bool isA9lh, bool isOtpless)
u8 otp[256] = {0},
keySector[512];
if(!isOtpless && !mountSd())
if(!isOtpless && !mountFs(true))
shutdown(1, "Error: failed to mount the SD card");
//If making a first install on O3DS, we need the OTP
@ -241,7 +243,7 @@ static inline void uninstaller(void)
}
else memset32(keySector, 0, sizeof(keySector));
if(!mountCtrNand())
if(!mountFs(false))
shutdown(1, "Error: failed to mount CTRNAND");
//Read FIRM cxi from CTRNAND
@ -256,6 +258,9 @@ static inline void uninstaller(void)
case 3:
shutdown(1, "Error: the CTRNAND FIRM is too large");
break;
case 4:
shutdown(1, "Error: couldn't read FIRM from CTRNAND");
break;
default:
break;
}