BAHAHAHAHAHAHAHH

This commit is contained in:
Arisotura
2021-08-12 15:35:13 +02:00
parent d67380c5dc
commit 50500cfd49
9 changed files with 283 additions and 278 deletions

View File

@ -20,6 +20,7 @@ add_library(core STATIC
DSi_Camera.cpp
DSi_DSP.cpp
DSi_I2C.cpp
DSi_NAND.cpp
DSi_NDMA.cpp
DSi_NWifi.cpp
DSi_SD.cpp

View File

@ -36,10 +36,10 @@
#include "DSi_I2C.h"
#include "DSi_SD.h"
#include "DSi_AES.h"
#include "DSi_NAND.h"
#include "DSi_DSP.h"
#include "DSi_Camera.h"
#include "sha1/sha1.hpp"
#include "tiny-AES-c/aes.hpp"
@ -530,70 +530,8 @@ bool LoadNAND()
memcpy(&ARM7Init[0x0254], &ARM7iBIOS[0xC6D0], 0x1048);
memcpy(&ARM7Init[0x129C], &ARM7iBIOS[0xD718], 0x1048);
// TEST ZONE
{
SHA1_CTX sha;
u8 cidhash[20];
u8 iv[16];
SHA1Init(&sha);
SHA1Update(&sha, eMMC_CID, 16);
SHA1Final(cidhash, &sha);
printf("ASS HASH: ");
for (int i = 0; i < 20; i++) printf("%02X", cidhash[i]);
printf("\n");
DSi_AES::Swap16(iv, cidhash);
printf("ASS IV: ");
for (int i = 0; i < 16; i++) printf("%02X", iv[i]);
printf("\n");
u8 keyX[16];
*(u32*)&keyX[0] = (u32)ConsoleID;
*(u32*)&keyX[4] = (u32)ConsoleID ^ 0x24EE6906;
*(u32*)&keyX[8] = (u32)(ConsoleID >> 32) ^ 0xE65B601D;
*(u32*)&keyX[12] = (u32)(ConsoleID >> 32);
u8 keyY[16];
*(u32*)&keyY[0] = 0x0AB9DC76;
*(u32*)&keyY[4] = 0xBD4DC4D3;
*(u32*)&keyY[8] = 0x202DDD1D;
*(u32*)&keyY[12] = 0xE1A00005;
u8 shittykey[16];
DSi_AES::DeriveNormalKey(keyX, keyY, shittykey);
u8 normalkey[16];
DSi_AES::Swap16(normalkey, shittykey);
u8 dorp[0x200];
fseek(SDMMCFile, 0, SEEK_SET);
fread(&dorp, 0x200, 1, SDMMCFile);
AES_ctx ctx;
AES_init_ctx_iv(&ctx, normalkey, iv);
//AES_CTR_xcrypt_buffer(&ctx, dorp, 0x200);
for (int i = 0; i < 0x200; i+=16)
{
u8 tmp[16];
DSi_AES::Swap16(tmp, &dorp[i]);
AES_CTR_xcrypt_buffer(&ctx, tmp, 16);
DSi_AES::Swap16(&dorp[i], tmp);
}
//printf("%08X %08X %08X %08X\n", *(u32*)&dorp[0], *(u32*)&dorp[4], *(u32*)&dorp[8], *(u32*)&dorp[12]);
for (int i = 0; i < 0x200; i+=16)
{
for (int j = 0; j < 16; j++)
{
printf("%02X ", dorp[i+j]);
}
printf("\n");
}
}
DSi_NAND::Init();
DSi_NAND::PatchTSC();
return true;
}

173
src/DSi_NAND.cpp Normal file
View File

@ -0,0 +1,173 @@
/*
Copyright 2016-2021 Arisotura
This file is part of melonDS.
melonDS is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with melonDS. If not, see http://www.gnu.org/licenses/.
*/
#include <stdio.h>
#include "DSi.h"
#include "DSi_AES.h"
#include "DSi_NAND.h"
#include "sha1/sha1.hpp"
#include "tiny-AES-c/aes.hpp"
#include "fatfs/ff.h"
namespace DSi_NAND
{
u8 FATIV[16];
u8 FATKey[16];
void Init()
{
// init NAND crypto
SHA1_CTX sha;
u8 tmp[20];
SHA1Init(&sha);
SHA1Update(&sha, DSi::eMMC_CID, 16);
SHA1Final(tmp, &sha);
DSi_AES::Swap16(FATIV, tmp);
u8 keyX[16];
*(u32*)&keyX[0] = (u32)DSi::ConsoleID;
*(u32*)&keyX[4] = (u32)DSi::ConsoleID ^ 0x24EE6906;
*(u32*)&keyX[8] = (u32)(DSi::ConsoleID >> 32) ^ 0xE65B601D;
*(u32*)&keyX[12] = (u32)(DSi::ConsoleID >> 32);
u8 keyY[16];
*(u32*)&keyY[0] = 0x0AB9DC76;
*(u32*)&keyY[4] = 0xBD4DC4D3;
*(u32*)&keyY[8] = 0x202DDD1D;
*(u32*)&keyY[12] = 0xE1A00005;
DSi_AES::DeriveNormalKey(keyX, keyY, tmp);
DSi_AES::Swap16(FATKey, tmp);
}
void SetupFATCrypto(AES_ctx* ctx, u32 ctr)
{
u8 iv[16];
memcpy(iv, FATIV, 16);
u32 res;
res = iv[15] + (ctr & 0xFF);
iv[15] = (res & 0xFF);
res = iv[14] + ((ctr >> 8) & 0xFF) + (res >> 8);
iv[14] = (res & 0xFF);
res = iv[13] + ((ctr >> 16) & 0xFF) + (res >> 8);
iv[13] = (res & 0xFF);
res = iv[12] + (ctr >> 24) + (res >> 8);
iv[12] = (res & 0xFF);
iv[11] += (res >> 8);
AES_init_ctx_iv(ctx, FATKey, iv);
}
u32 ReadFATBlock(u64 addr, u32 len, u8* buf)
{
u32 ctr = (u32)(addr >> 4);
AES_ctx ctx;
SetupFATCrypto(&ctx, ctr);
fseek(DSi::SDMMCFile, addr, SEEK_SET);
u32 res = fread(buf, len, 1, DSi::SDMMCFile);
if (!res) return 0;
for (u32 i = 0; i < len; i += 16)
{
//printf("BLOCK %d: IV=", i);
//for (int k = 0; k < 16; k++) printf("%02X:", ctx.Iv[k]);
//printf("\n");
u8 tmp[16];
DSi_AES::Swap16(tmp, &buf[i]);
AES_CTR_xcrypt_buffer(&ctx, tmp, 16);
DSi_AES::Swap16(&buf[i], tmp);
}
return len;
}
UINT FF_ReadNAND(BYTE* buf, LBA_t sector, UINT num)
{
printf("READ %08X %08X\n", sector, num);
// TODO: allow selecting other partitions?
u64 baseaddr = 0x10EE00;
u64 blockaddr = baseaddr + (sector * 0x200ULL);
u32 res = ReadFATBlock(blockaddr, num*0x200, buf);
return res >> 9;
}
UINT FF_WriteNAND(BYTE* buf, LBA_t sector, UINT num)
{
// TODO!
printf("!! WRITE %08X %08X\n", sector, num);
return 0;
}
void PatchTSC()
{
// TEST ZONE
u8 dorp[0x200];
ReadFATBlock(0, 0x200, dorp);
for (int i = 0; i < 0x200; i+=16)
{
for (int j = 0; j < 16; j++)
{
printf("%02X ", dorp[i+j]);
}
printf("\n");
}
ReadFATBlock(0x0010EE00, 0x200, dorp);
printf("FUKA\n");
for (int i = 0; i < 0x200; i+=16)
{
for (int j = 0; j < 16; j++)
{
printf("%02X ", dorp[i+j]);
}
printf("\n");
}
ff_disk_open(FF_ReadNAND, FF_WriteNAND);
FRESULT res;
FATFS fs;
res = f_mount(&fs, "0:", 0);
printf("mount=%d\n", res);
FIL file;
res = f_open(&file, "0:/shared1/TWLCFG0.dat", FA_READ);
printf("blarg=%d\n", res);
}
}

33
src/DSi_NAND.h Normal file
View File

@ -0,0 +1,33 @@
/*
Copyright 2016-2021 Arisotura
This file is part of melonDS.
melonDS is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with melonDS. If not, see http://www.gnu.org/licenses/.
*/
#ifndef DSI_NAND_H
#define DSI_NAND_H
#include "types.h"
namespace DSi_NAND
{
void Init();
void PatchTSC();
}
#endif // DSI_NAND_H

View File

@ -167,7 +167,6 @@ void Reset()
UserSettings = userdata;
// TODO evetually: do this in DSi mode
if (NDS::ConsoleType == 0)
{
// fix touchscreen coords

View File

@ -10,10 +10,32 @@
#include "ff.h" /* Obtains integer types */
#include "diskio.h" /* Declarations of disk functions */
/* Definitions of physical drive number for each drive */
#define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */
#define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */
#define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */
static ff_disk_read_cb ReadCb;
static ff_disk_write_cb WriteCb;
static DSTATUS Status = STA_NOINIT | STA_NODISK;
void ff_disk_open(ff_disk_read_cb readcb, ff_disk_write_cb writecb)
{
if (!readcb) return;
ReadCb = readcb;
WriteCb = writecb;
Status &= ~STA_NODISK;
if (!writecb) Status |= STA_PROTECT;
else Status &= ~STA_PROTECT;
}
void ff_disk_close()
{
ReadCb = NULL;
WriteCb = NULL;
Status &= ~STA_PROTECT;
Status |= STA_NODISK;
}
/*-----------------------------------------------------------------------*/
@ -24,32 +46,7 @@ DSTATUS disk_status (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS stat;
int result;
switch (pdrv) {
case DEV_RAM :
result = RAM_disk_status();
// translate the reslut code here
return stat;
case DEV_MMC :
result = MMC_disk_status();
// translate the reslut code here
return stat;
case DEV_USB :
result = USB_disk_status();
// translate the reslut code here
return stat;
}
return STA_NOINIT;
return Status;
}
@ -62,32 +59,8 @@ DSTATUS disk_initialize (
BYTE pdrv /* Physical drive nmuber to identify the drive */
)
{
DSTATUS stat;
int result;
switch (pdrv) {
case DEV_RAM :
result = RAM_disk_initialize();
// translate the reslut code here
return stat;
case DEV_MMC :
result = MMC_disk_initialize();
// translate the reslut code here
return stat;
case DEV_USB :
result = USB_disk_initialize();
// translate the reslut code here
return stat;
}
return STA_NOINIT;
Status &= ~STA_NOINIT;
return Status;
}
@ -103,39 +76,12 @@ DRESULT disk_read (
UINT count /* Number of sectors to read */
)
{
DRESULT res;
int result;
if (Status & (STA_NOINIT | STA_NODISK)) return RES_NOTRDY;
if (!ReadCb) return RES_ERROR;
switch (pdrv) {
case DEV_RAM :
// translate the arguments here
result = RAM_disk_read(buff, sector, count);
// translate the reslut code here
return res;
case DEV_MMC :
// translate the arguments here
result = MMC_disk_read(buff, sector, count);
// translate the reslut code here
return res;
case DEV_USB :
// translate the arguments here
result = USB_disk_read(buff, sector, count);
// translate the reslut code here
return res;
}
return RES_PARERR;
UINT res = ReadCb(buff, sector, count);
if (res != count) return RES_ERROR;
return RES_OK;
}
@ -153,39 +99,13 @@ DRESULT disk_write (
UINT count /* Number of sectors to write */
)
{
DRESULT res;
int result;
if (Status & (STA_NOINIT | STA_NODISK)) return RES_NOTRDY;
if (Status & STA_PROTECT) return RES_WRPRT;
if (!WriteCb) return RES_ERROR;
switch (pdrv) {
case DEV_RAM :
// translate the arguments here
result = RAM_disk_write(buff, sector, count);
// translate the reslut code here
return res;
case DEV_MMC :
// translate the arguments here
result = MMC_disk_write(buff, sector, count);
// translate the reslut code here
return res;
case DEV_USB :
// translate the arguments here
result = USB_disk_write(buff, sector, count);
// translate the reslut code here
return res;
}
return RES_PARERR;
UINT res = WriteCb(buff, sector, count);
if (res != count) return RES_ERROR;
return RES_OK;
}
#endif
@ -201,29 +121,7 @@ DRESULT disk_ioctl (
void *buff /* Buffer to send/receive control data */
)
{
DRESULT res;
int result;
switch (pdrv) {
case DEV_RAM :
// Process of the command for the RAM drive
return res;
case DEV_MMC :
// Process of the command for the MMC/SD card
return res;
case DEV_USB :
// Process of the command the USB drive
return res;
}
printf("disk_ioctl(%02X, %02X, %p)\n", pdrv, cmd, buff);
return RES_PARERR;
}

View File

@ -415,6 +415,15 @@ int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
#define AM_ARC 0x20 /* Archive */
// extra additions for interfacing with melonDS
typedef UINT (*ff_disk_read_cb)(BYTE* buff, LBA_t sector, UINT count);
typedef UINT (*ff_disk_write_cb)(BYTE* buff, LBA_t sector, UINT count);
void ff_disk_open(ff_disk_read_cb readcb, ff_disk_write_cb writecb);
void ff_disk_close();
#ifdef __cplusplus
}
#endif

View File

@ -171,7 +171,7 @@
#define FF_STR_VOLUME_ID 0
#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
#define FF_VOLUME_STRS "fat"
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each

View File

@ -3,6 +3,8 @@
/* (C)ChaN, 2018 */
/*------------------------------------------------------------------------*/
#define _POSIX_THREAD_SAFE_FUNCTIONS
#include <time.h>
#include "ff.h"
@ -54,27 +56,6 @@ int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object
FF_SYNC_t* sobj /* Pointer to return the created sync object */
)
{
/* Win32 */
*sobj = CreateMutex(NULL, FALSE, NULL);
return (int)(*sobj != INVALID_HANDLE_VALUE);
/* uITRON */
// T_CSEM csem = {TA_TPRI,1,1};
// *sobj = acre_sem(&csem);
// return (int)(*sobj > 0);
/* uC/OS-II */
// OS_ERR err;
// *sobj = OSMutexCreate(0, &err);
// return (int)(err == OS_NO_ERR);
/* FreeRTOS */
// *sobj = xSemaphoreCreateMutex();
// return (int)(*sobj != NULL);
/* CMSIS-RTOS */
// *sobj = osMutexCreate(&Mutex[vol]);
// return (int)(*sobj != NULL);
}
@ -90,23 +71,6 @@ int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to an error
FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
)
{
/* Win32 */
return (int)CloseHandle(sobj);
/* uITRON */
// return (int)(del_sem(sobj) == E_OK);
/* uC/OS-II */
// OS_ERR err;
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err);
// return (int)(err == OS_NO_ERR);
/* FreeRTOS */
// vSemaphoreDelete(sobj);
// return 1;
/* CMSIS-RTOS */
// return (int)(osMutexDelete(sobj) == osOK);
}
@ -121,22 +85,6 @@ int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a gran
FF_SYNC_t sobj /* Sync object to wait */
)
{
/* Win32 */
return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0);
/* uITRON */
// return (int)(wai_sem(sobj) == E_OK);
/* uC/OS-II */
// OS_ERR err;
// OSMutexPend(sobj, FF_FS_TIMEOUT, &err));
// return (int)(err == OS_NO_ERR);
/* FreeRTOS */
// return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
/* CMSIS-RTOS */
// return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK);
}
@ -150,21 +98,27 @@ void ff_rel_grant (
FF_SYNC_t sobj /* Sync object to be signaled */
)
{
/* Win32 */
ReleaseMutex(sobj);
/* uITRON */
// sig_sem(sobj);
/* uC/OS-II */
// OSMutexPost(sobj);
/* FreeRTOS */
// xSemaphoreGive(sobj);
/* CMSIS-RTOS */
// osMutexRelease(sobj);
}
#endif
DWORD get_fattime()
{
// TODO: return melonDS time instead of RTC??
time_t timestamp = time(NULL);
struct tm timedata;
localtime_r(&timestamp, &timedata);
DWORD ret;
ret = (timedata.tm_sec >> 1);
ret |= (timedata.tm_min << 5);
ret |= (timedata.tm_hour << 11);
ret |= (timedata.tm_mday << 16);
ret |= ((timedata.tm_mon + 1) << 21);
ret |= ((timedata.tm_year - 80) << 25);
return ret;
}