diff --git a/source/keys/keys.c b/source/incognito/incognito.c similarity index 97% rename from source/keys/keys.c rename to source/incognito/incognito.c index 1957b70..1f759cd 100644 --- a/source/keys/keys.c +++ b/source/incognito/incognito.c @@ -14,7 +14,7 @@ * along with this program. If not, see . */ -#include "keys.h" +#include "incognito.h" #include "../config/config.h" #include "../gfx/di.h" @@ -42,7 +42,7 @@ #include "key_sources.inl" -#include "../libs/fatfs/diskio.h" +#include "io/io.h" #include extern bool sd_mount(); @@ -423,7 +423,7 @@ bool readData(u8 *buffer, u32 offset, u32 length, void (*progress_callback)(u32, while (clusterOffset + sectorCount > SECTORS_IN_CLUSTER) { u32 sectorsToRead = SECTORS_IN_CLUSTER - clusterOffset; - if (disk_read_prod(tmp + (sectorOffset * NX_EMMC_BLOCKSIZE), sector, sectorsToRead) != RES_OK) + if (!prodinfo_read(tmp + (sectorOffset * NX_EMMC_BLOCKSIZE), sector, sectorsToRead)) goto out; sector += sectorsToRead; @@ -438,7 +438,7 @@ bool readData(u8 *buffer, u32 offset, u32 length, void (*progress_callback)(u32, if (sectorCount == 0) goto done; - if (disk_read_prod(tmp + (sectorOffset * NX_EMMC_BLOCKSIZE), sector, sectorCount) != RES_OK) + if (!prodinfo_read(tmp + (sectorOffset * NX_EMMC_BLOCKSIZE), sector, sectorCount)) goto out; memcpy(buffer, tmp + newOffset, length); @@ -482,11 +482,11 @@ bool writeData(u8 *buffer, u32 offset, u32 length, void (*progress_callback)(u32 { bytesToWrite = length; } - if (disk_read_prod(tmp_sec, sector, 1) != RES_OK) + if (!prodinfo_read(tmp_sec, sector, 1)) goto out; memcpy(tmp_sec + newOffset, buffer, bytesToWrite); - if (disk_write_prod(tmp_sec, sector, 1) != RES_OK) + if (!prodinfo_write(tmp_sec, sector, 1)) goto out; sector++; @@ -511,7 +511,7 @@ bool writeData(u8 *buffer, u32 offset, u32 length, void (*progress_callback)(u32 while (clusterOffset + sectorCount >= SECTORS_IN_CLUSTER) { u32 sectorsToRead = SECTORS_IN_CLUSTER - clusterOffset; - if (disk_write_prod(buffer + newOffset + (sectorOffset * NX_EMMC_BLOCKSIZE), sector, sectorsToRead) != RES_OK) + if (!prodinfo_write(buffer + newOffset + (sectorOffset * NX_EMMC_BLOCKSIZE), sector, sectorsToRead)) goto out; sector += sectorsToRead; @@ -529,7 +529,7 @@ bool writeData(u8 *buffer, u32 offset, u32 length, void (*progress_callback)(u32 // write remaining sectors if (sectorCount > 0) { - if (disk_write_prod(buffer + newOffset + (sectorOffset * NX_EMMC_BLOCKSIZE), sector, sectorCount) != RES_OK) + if (!prodinfo_write(buffer + newOffset + (sectorOffset * NX_EMMC_BLOCKSIZE), sector, sectorCount)) goto out; length -= sectorCount * NX_EMMC_BLOCKSIZE; @@ -552,11 +552,11 @@ bool writeData(u8 *buffer, u32 offset, u32 length, void (*progress_callback)(u32 goto out; } - if (disk_read_prod(tmp_sec, sector, 1) != RES_OK) + if (!prodinfo_read(tmp_sec, sector, 1)) goto out; memcpy(tmp_sec, buffer + newOffset + (sectorOffset * NX_EMMC_BLOCKSIZE), length); - if (disk_write_prod(tmp_sec, sector, 1) != RES_OK) + if (!prodinfo_write(tmp_sec, sector, 1)) goto out; done: diff --git a/source/keys/keys.h b/source/incognito/incognito.h similarity index 100% rename from source/keys/keys.h rename to source/incognito/incognito.h diff --git a/source/incognito/io/io.c b/source/incognito/io/io.c new file mode 100644 index 0000000..5cb0355 --- /dev/null +++ b/source/incognito/io/io.c @@ -0,0 +1,158 @@ +#include "io.h" + +#include "../../storage/sdmmc.h" +#include "../../storage/nx_emmc.h" + +#include +#include "../../sec/se.h" + +extern sdmmc_storage_t storage; +extern emmc_part_t *prodinfo_part; + +static inline void _gf256_mul_x_le(void *block) +{ + u8 *pdata = (u8 *)block; + u32 carry = 0; + + for (u32 i = 0; i < 0x10; i++) + { + u8 b = pdata[i]; + pdata[i] = (b << 1) | carry; + carry = b >> 7; + } + + if (carry) + pdata[0x0] ^= 0x87; +} + +static inline int _emmc_xts(u32 ks1, u32 ks2, u32 enc, u8 *tweak, bool regen_tweak, u32 tweak_exp, u64 sec, void *dst, void *src, u32 secsize) +{ + int res = 0; + u8 *pdst = (u8 *)dst; + u8 *psrc = (u8 *)src; + + if (regen_tweak) + { + for (int i = 0xF; i >= 0; i--) + { + tweak[i] = sec & 0xFF; + sec >>= 8; + } + if (!se_aes_crypt_block_ecb(ks1, 1, tweak, tweak)) + goto out; + } + + for (u32 i = 0; i < tweak_exp * 0x20; i++) + _gf256_mul_x_le(tweak); + + u8 temptweak[0x10]; + memcpy(temptweak, tweak, 0x10); + + //We are assuming a 0x10-aligned sector size in this implementation. + for (u32 i = 0; i < secsize / 0x10; i++) + { + for (u32 j = 0; j < 0x10; j++) + pdst[j] = psrc[j] ^ tweak[j]; + _gf256_mul_x_le(tweak); + psrc += 0x10; + pdst += 0x10; + } + + se_aes_crypt_ecb(ks2, enc, dst, secsize, src, secsize); + + pdst = (u8 *)dst; + + memcpy(tweak, temptweak, 0x10); + for (u32 i = 0; i < secsize / 0x10; i++) + { + for (u32 j = 0; j < 0x10; j++) + pdst[j] = pdst[j] ^ tweak[j]; + _gf256_mul_x_le(tweak); + pdst += 0x10; + } + + res = 1; + +out:; + return res; +} + + +bool prodinfo_read( + u8 *buff, /* Data buffer to store read data */ + u32 sector, /* Start sector in LBA */ + u32 count /* Number of sectors to read */ + ) +{ + + __attribute__((aligned(16))) static u8 tweak[0x10]; + __attribute__((aligned(16))) static u64 prev_cluster = -1; + __attribute__((aligned(16))) static u32 prev_sector = 0; + u32 tweak_exp = 0; + bool regen_tweak = true; + + if (nx_emmc_part_read(&storage, prodinfo_part, sector, count, buff)) + { + if (prev_cluster != sector / 0x20) + { // sector in different cluster than last read + prev_cluster = sector / 0x20; + tweak_exp = sector % 0x20; + } + else if (sector > prev_sector) + { // sector in same cluster and past last sector + tweak_exp = sector - prev_sector - 1; + regen_tweak = false; + } + else + { // sector in same cluster and before or same as last sector + tweak_exp = sector % 0x20; + } + + // fatfs will never pull more than a cluster + _emmc_xts(9, 8, 0, tweak, regen_tweak, tweak_exp, prev_cluster, buff, buff, count * 0x200); + + prev_sector = sector + count - 1; + return true; + } + + return false; +} + +bool prodinfo_write( + u8 *buff, /* Data buffer to store read data */ + u32 sector, /* Start sector in LBA */ + u32 count /* Number of sectors to read */ + ) +{ + + __attribute__((aligned(16))) static u8 tweak[0x10]; + __attribute__((aligned(16))) static u64 prev_cluster = -1; + __attribute__((aligned(16))) static u32 prev_sector = 0; + u32 tweak_exp = 0; + bool regen_tweak = true; + + if (prev_cluster != sector / 0x20) + { // sector in different cluster than last read + prev_cluster = sector / 0x20; + tweak_exp = sector % 0x20; + } + else if (sector > prev_sector) + { // sector in same cluster and past last sector + tweak_exp = sector - prev_sector - 1; + regen_tweak = false; + } + else + { // sector in same cluster and before or same as last sector + tweak_exp = sector % 0x20; + } + + // fatfs will never pull more than a cluster + _emmc_xts(9, 8, 1, tweak, regen_tweak, tweak_exp, prev_cluster, buff, buff, count * 0x200); + if (nx_emmc_part_write(&storage, prodinfo_part, sector, count, buff)) + { + prev_sector = sector + count - 1; + return true; + } + + return false; +} \ No newline at end of file diff --git a/source/incognito/io/io.h b/source/incognito/io/io.h new file mode 100644 index 0000000..6383220 --- /dev/null +++ b/source/incognito/io/io.h @@ -0,0 +1,9 @@ +#ifndef _IO_DEFINED +#define _IO_DEFINED + +#include "../../utils/types.h" + +bool prodinfo_read (u8 *buff, u32 sector, u32 count); +bool prodinfo_write (u8 *buff, u32 sector, u32 count); + +#endif \ No newline at end of file diff --git a/source/keys/key_sources.inl b/source/incognito/key_sources.inl similarity index 100% rename from source/keys/key_sources.inl rename to source/incognito/key_sources.inl diff --git a/source/libs/fatfs/diskio.c b/source/libs/fatfs/diskio.c index 0db38f3..e820c6a 100644 --- a/source/libs/fatfs/diskio.c +++ b/source/libs/fatfs/diskio.c @@ -24,52 +24,51 @@ /*-----------------------------------------------------------------------*/ #include -#include "diskio.h" /* FatFs lower layer API */ +#include "diskio.h" /* FatFs lower layer API */ #include "../../mem/heap.h" #include "../../sec/se.h" +#include "../../storage/nx_emmc.h" +#include "../../storage/sdmmc.h" #define SDMMC_UPPER_BUFFER 0xB8000000 -#define DRAM_START 0x80000000 +#define DRAM_START 0x80000000 extern sdmmc_storage_t sd_storage; extern sdmmc_storage_t storage; extern emmc_part_t *system_part; -extern emmc_part_t *prodinfo_part; -typedef struct -{ +typedef struct { u32 sector; u32 visit_count; - u8 tweak[0x10]; - u8 cached_sector[0x200]; - u8 align[8]; + u8 tweak[0x10]; + u8 cached_sector[0x200]; + u8 align[8]; } sector_cache_t; #define MAX_SEC_CACHE_ENTRIES 64 -static sector_cache_t *sector_cache = (sector_cache_t *)0x40022000; +static sector_cache_t *sector_cache = NULL; static u32 secindex = 0; +bool clear_sector_cache = false; -DSTATUS disk_status( +DSTATUS disk_status ( BYTE pdrv /* Physical drive number to identify the drive */ ) { return 0; } -DSTATUS disk_initialize( +DSTATUS disk_initialize ( BYTE pdrv /* Physical drive number to identify the drive */ ) { return 0; } -static inline void _gf256_mul_x_le(void *block) -{ +static inline void _gf256_mul_x_le(void *block) { u8 *pdata = (u8 *)block; u32 carry = 0; - for (u32 i = 0; i < 0x10; i++) - { + for (u32 i = 0; i < 0x10; i++) { u8 b = pdata[i]; pdata[i] = (b << 1) | carry; carry = b >> 7; @@ -79,16 +78,13 @@ static inline void _gf256_mul_x_le(void *block) pdata[0x0] ^= 0x87; } -static inline int _emmc_xts(u32 ks1, u32 ks2, u32 enc, u8 *tweak, bool regen_tweak, u32 tweak_exp, u64 sec, void *dst, void *src, u32 secsize) -{ +static inline int _emmc_xts(u32 ks1, u32 ks2, u32 enc, u8 *tweak, bool regen_tweak, u32 tweak_exp, u64 sec, void *dst, void *src, u32 secsize) { int res = 0; u8 *pdst = (u8 *)dst; u8 *psrc = (u8 *)src; - if (regen_tweak) - { - for (int i = 0xF; i >= 0; i--) - { + if (regen_tweak) { + for (int i = 0xF; i >= 0; i--) { tweak[i] = sec & 0xFF; sec >>= 8; } @@ -103,8 +99,7 @@ static inline int _emmc_xts(u32 ks1, u32 ks2, u32 enc, u8 *tweak, bool regen_twe memcpy(temptweak, tweak, 0x10); //We are assuming a 0x10-aligned sector size in this implementation. - for (u32 i = 0; i < secsize / 0x10; i++) - { + for (u32 i = 0; i < secsize / 0x10; i++) { for (u32 j = 0; j < 0x10; j++) pdst[j] = psrc[j] ^ tweak[j]; _gf256_mul_x_le(tweak); @@ -112,132 +107,63 @@ static inline int _emmc_xts(u32 ks1, u32 ks2, u32 enc, u8 *tweak, bool regen_twe pdst += 0x10; } - se_aes_crypt_ecb(ks2, enc, dst, secsize, src, secsize); + se_aes_crypt_ecb(ks2, 0, dst, secsize, src, secsize); pdst = (u8 *)dst; memcpy(tweak, temptweak, 0x10); - for (u32 i = 0; i < secsize / 0x10; i++) - { + for (u32 i = 0; i < secsize / 0x10; i++) { for (u32 j = 0; j < 0x10; j++) pdst[j] = pdst[j] ^ tweak[j]; _gf256_mul_x_le(tweak); pdst += 0x10; } + res = 1; out:; return res; } -DRESULT disk_read_prod( - - BYTE *buff, /* Data buffer to store read data */ - DWORD sector, /* Start sector in LBA */ - UINT count /* Number of sectors to read */ - ) -{ - - __attribute__((aligned(16))) static u8 tweak[0x10]; - __attribute__((aligned(16))) static u64 prev_cluster = -1; - __attribute__((aligned(16))) static u32 prev_sector = 0; - u32 tweak_exp = 0; - bool regen_tweak = true; - - if (nx_emmc_part_read(&storage, prodinfo_part, sector, count, buff)) - { - if (prev_cluster != sector / 0x20) - { // sector in different cluster than last read - prev_cluster = sector / 0x20; - tweak_exp = sector % 0x20; - } - else if (sector > prev_sector) - { // sector in same cluster and past last sector - tweak_exp = sector - prev_sector - 1; - regen_tweak = false; - } - else - { // sector in same cluster and before or same as last sector - tweak_exp = sector % 0x20; - } - - // fatfs will never pull more than a cluster - _emmc_xts(9, 8, 0, tweak, regen_tweak, tweak_exp, prev_cluster, buff, buff, count * 0x200); - - prev_sector = sector + count - 1; - return RES_OK; - } - - return RES_ERROR; -} - -DRESULT disk_write_prod( - - BYTE *buff, /* Data buffer to store read data */ - DWORD sector, /* Start sector in LBA */ - UINT count /* Number of sectors to read */ - ) -{ - - __attribute__((aligned(16))) static u8 tweak[0x10]; - __attribute__((aligned(16))) static u64 prev_cluster = -1; - __attribute__((aligned(16))) static u32 prev_sector = 0; - u32 tweak_exp = 0; - bool regen_tweak = true; - - if (prev_cluster != sector / 0x20) - { // sector in different cluster than last read - prev_cluster = sector / 0x20; - tweak_exp = sector % 0x20; - } - else if (sector > prev_sector) - { // sector in same cluster and past last sector - tweak_exp = sector - prev_sector - 1; - regen_tweak = false; - } - else - { // sector in same cluster and before or same as last sector - tweak_exp = sector % 0x20; - } - - // fatfs will never pull more than a cluster - _emmc_xts(9, 8, 1, tweak, regen_tweak, tweak_exp, prev_cluster, buff, buff, count * 0x200); - if (nx_emmc_part_write(&storage, prodinfo_part, sector, count, buff)) - { - prev_sector = sector + count - 1; - return RES_OK; - } - - return RES_ERROR; -} - -DRESULT disk_read( - BYTE pdrv, /* Physical drive number to identify the drive */ - BYTE *buff, /* Data buffer to store read data */ - DWORD sector, /* Start sector in LBA */ - UINT count /* Number of sectors to read */ +DRESULT disk_read ( + BYTE pdrv, /* Physical drive number to identify the drive */ + BYTE *buff, /* Data buffer to store read data */ + DWORD sector, /* Start sector in LBA */ + UINT count /* Number of sectors to read */ ) { switch (pdrv) { case 0: - return sdmmc_storage_read(&sd_storage, sector, count, buff) ? RES_OK : RES_ERROR; + if (((u32)buff >= DRAM_START) && !((u32)buff % 8)) + return sdmmc_storage_read(&sd_storage, sector, count, buff) ? RES_OK : RES_ERROR; + u8 *buf = (u8 *)SDMMC_UPPER_BUFFER; + if (sdmmc_storage_read(&sd_storage, sector, count, buf)) + { + memcpy(buff, buf, 512 * count); + return RES_OK; + } + return RES_ERROR; case 1:; - __attribute__((aligned(16))) static u8 tweak[0x10]; - __attribute__((aligned(16))) static u64 prev_cluster = -1; - __attribute__((aligned(16))) static u32 prev_sector = 0; + __attribute__ ((aligned (16))) static u8 tweak[0x10]; + __attribute__ ((aligned (16))) static u64 prev_cluster = -1; + __attribute__ ((aligned (16))) static u32 prev_sector = 0; u32 tweak_exp = 0; bool regen_tweak = true, cache_sector = false; + if (secindex == 0 || clear_sector_cache) { + free(sector_cache); + sector_cache = (sector_cache_t *)malloc(sizeof(sector_cache_t) * MAX_SEC_CACHE_ENTRIES); + clear_sector_cache = false; + secindex = 0; + } + u32 s = 0; - if (count == 1) - { - for (; s < secindex; s++) - { - if (sector_cache[s].sector == sector) - { + if (count == 1) { + for ( ; s < secindex; s++) { + if (sector_cache[s].sector == sector) { sector_cache[s].visit_count++; memcpy(buff, sector_cache[s].cached_sector, 0x200); memcpy(tweak, sector_cache[s].tweak, 0x10); @@ -247,8 +173,7 @@ DRESULT disk_read( } } // add to cache - if (s == secindex && s < MAX_SEC_CACHE_ENTRIES) - { + if (s == secindex && s < MAX_SEC_CACHE_ENTRIES) { sector_cache[s].sector = sector; sector_cache[s].visit_count++; cache_sector = true; @@ -256,27 +181,20 @@ DRESULT disk_read( } } - if (nx_emmc_part_read(&storage, system_part, sector, count, buff)) - { - if (prev_cluster != sector / 0x20) - { // sector in different cluster than last read + if (nx_emmc_part_read(&storage, system_part, sector, count, buff)) { + if (prev_cluster != sector / 0x20) { // sector in different cluster than last read prev_cluster = sector / 0x20; tweak_exp = sector % 0x20; - } - else if (sector > prev_sector) - { // sector in same cluster and past last sector + } else if (sector > prev_sector) { // sector in same cluster and past last sector tweak_exp = sector - prev_sector - 1; regen_tweak = false; - } - else - { // sector in same cluster and before or same as last sector + } else { // sector in same cluster and before or same as last sector tweak_exp = sector % 0x20; } // fatfs will never pull more than a cluster _emmc_xts(9, 8, 0, tweak, regen_tweak, tweak_exp, prev_cluster, buff, buff, count * 0x200); - if (cache_sector) - { + if (cache_sector) { memcpy(sector_cache[s].cached_sector, buff, 0x200); memcpy(sector_cache[s].tweak, tweak, 0x10); } @@ -288,22 +206,29 @@ DRESULT disk_read( return RES_ERROR; } -DRESULT disk_write( - BYTE pdrv, /* Physical drive number to identify the drive */ - const BYTE *buff, /* Data to be written */ - DWORD sector, /* Start sector in LBA */ - UINT count /* Number of sectors to write */ +DRESULT disk_write ( + BYTE pdrv, /* Physical drive number to identify the drive */ + const BYTE *buff, /* Data to be written */ + DWORD sector, /* Start sector in LBA */ + UINT count /* Number of sectors to write */ ) { if (pdrv == 1) return RES_WRPRT; - return sdmmc_storage_write(&sd_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR; + + if (((u32)buff >= DRAM_START) && !((u32)buff % 8)) + return sdmmc_storage_write(&sd_storage, sector, count, (void *)buff) ? RES_OK : RES_ERROR; + u8 *buf = (u8 *)SDMMC_UPPER_BUFFER; //TODO: define this somewhere. + memcpy(buf, buff, 512 * count); + if (sdmmc_storage_write(&sd_storage, sector, count, buf)) + return RES_OK; + return RES_ERROR; } -DRESULT disk_ioctl( - BYTE pdrv, /* Physical drive number (0..) */ - BYTE cmd, /* Control code */ - void *buff /* Buffer to send/receive control data */ +DRESULT disk_ioctl ( + BYTE pdrv, /* Physical drive number (0..) */ + BYTE cmd, /* Control code */ + void *buff /* Buffer to send/receive control data */ ) { return RES_OK; diff --git a/source/libs/fatfs/diskio.h b/source/libs/fatfs/diskio.h index 7791f45..d6ae8f8 100644 --- a/source/libs/fatfs/diskio.h +++ b/source/libs/fatfs/diskio.h @@ -10,8 +10,6 @@ extern "C" { #endif #include "../../utils/types.h" -#include "../../storage/sdmmc.h" -#include "../../storage/nx_emmc.h" /* Status of Disk Functions */ typedef BYTE DSTATUS; @@ -33,8 +31,6 @@ typedef enum { DSTATUS disk_initialize (BYTE pdrv); DSTATUS disk_status (BYTE pdrv); DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count); -DRESULT disk_read_prod (BYTE *buff, DWORD sector, UINT count); -DRESULT disk_write_prod (BYTE *buff, DWORD sector, UINT count); DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count); DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff); diff --git a/source/main.c b/source/main.c index 1f7e64e..79cd596 100644 --- a/source/main.c +++ b/source/main.c @@ -34,7 +34,7 @@ #include "utils/util.h" #include "utils/btn.h" -#include "keys/keys.h" +#include "incognito/incognito.h" sdmmc_t sd_sdmmc; sdmmc_storage_t sd_storage;