mirror of
https://github.com/Scandal-UK/Incognito_RCM.git
synced 2024-12-23 02:42:04 +00:00
decrypting and reading ready, encrypting and writing todo
This commit is contained in:
parent
4ce94bc2b1
commit
76bfd54fd2
4 changed files with 250 additions and 63 deletions
|
@ -23,7 +23,7 @@
|
|||
#include "../hos/pkg1.h"
|
||||
#include "../hos/pkg2.h"
|
||||
#include "../hos/sept.h"
|
||||
//#include "../libs/fatfs/ff.h"
|
||||
#include "../libs/fatfs/ff.h"
|
||||
#include "../mem/heap.h"
|
||||
#include "../mem/mc.h"
|
||||
#include "../mem/sdram.h"
|
||||
|
@ -158,6 +158,7 @@ void dump_keys() {
|
|||
MAX_KEY = pkg1_id->kb + 1;
|
||||
}
|
||||
|
||||
|
||||
if (pkg1_id->kb >= KB_FIRMWARE_VERSION_700) {
|
||||
// sd_mount();
|
||||
// if (!f_stat("sd:/sept/payload.bak", NULL)) {
|
||||
|
@ -374,12 +375,22 @@ void dump_keys() {
|
|||
se_aes_key_set(8, bis_key[0] + 0x00, 0x10);
|
||||
se_aes_key_set(9, bis_key[0] + 0x10, 0x10);
|
||||
|
||||
u32 length = 0x18;
|
||||
u8* buffer = (u8 *)malloc(length);
|
||||
readData(buffer, 0x250, length);
|
||||
//u32 length = 0x18;
|
||||
u8 buffer[0x18];// = (u8 *)malloc(length);
|
||||
readData(buffer, 0x250, sizeof(buffer));
|
||||
|
||||
gfx_hexdump(0, buffer, length);
|
||||
free(buffer);
|
||||
|
||||
// const char junkSerial[] = "XAJ40030770863";
|
||||
// gfx_hexdump(0, (u8 *)junkSerial, strlen(junkSerial));
|
||||
// writeData((u8 *)junkSerial, 0x250, strlen(junkSerial));
|
||||
|
||||
gfx_hexdump(0, buffer, sizeof(buffer));
|
||||
//free(buffer);
|
||||
|
||||
verify();
|
||||
|
||||
writeClientCertHash();
|
||||
writeCal0Hash();
|
||||
|
||||
verify();
|
||||
// free(tmp_copy);
|
||||
|
@ -387,6 +398,7 @@ void dump_keys() {
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
// pkg2_done:
|
||||
// // free(pkg2);
|
||||
|
@ -605,7 +617,7 @@ bool readData(u8 *buffer, u32 offset, u32 length)
|
|||
u32 sector = (offset / NX_EMMC_BLOCKSIZE);
|
||||
u32 newOffset = (offset % NX_EMMC_BLOCKSIZE);
|
||||
|
||||
u8 sectorCount = ((newOffset + length) / NX_EMMC_BLOCKSIZE) + 1;
|
||||
u8 sectorCount = ((newOffset + length - 1) / (NX_EMMC_BLOCKSIZE)) + 1;
|
||||
|
||||
// if(length + newOffset > NX_EMMC_BLOCKSIZE * 2){
|
||||
// EPRINTF("TOO BIG!!");
|
||||
|
@ -614,7 +626,7 @@ bool readData(u8 *buffer, u32 offset, u32 length)
|
|||
//bool needMultipleSectors = newOffset + length > NX_EMMC_BLOCKSIZE;
|
||||
|
||||
u8 *tmp = (u8 *)malloc(sectorCount * NX_EMMC_BLOCKSIZE);
|
||||
disk_read_mod(tmp, sector, sectorCount, &storage, prodinfo_part);
|
||||
disk_read_prod(tmp, sector, sectorCount);
|
||||
|
||||
// if (!needMultipleSectors)
|
||||
// {
|
||||
|
@ -634,9 +646,46 @@ bool readData(u8 *buffer, u32 offset, u32 length)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool verifyHash(u32 hashOffset, u32 offset, u32 sz)
|
||||
bool writeData(u8 *buffer, u32 offset, u32 length)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
u32 sector = (offset / NX_EMMC_BLOCKSIZE);
|
||||
u32 newOffset = (offset % NX_EMMC_BLOCKSIZE);
|
||||
|
||||
u8 sectorCount = ((newOffset + length - 1) / (NX_EMMC_BLOCKSIZE)) + 1;
|
||||
|
||||
// if(length + newOffset > NX_EMMC_BLOCKSIZE * 2){
|
||||
// EPRINTF("TOO BIG!!");
|
||||
// }
|
||||
|
||||
//bool needMultipleSectors = newOffset + length > NX_EMMC_BLOCKSIZE;
|
||||
|
||||
u8 *tmp = (u8 *)malloc(sectorCount * NX_EMMC_BLOCKSIZE);
|
||||
disk_read_prod(tmp, sector, sectorCount);
|
||||
|
||||
// if (!needMultipleSectors)
|
||||
// {
|
||||
// gfx_hexdump(0, tmp + newOffset, length);
|
||||
memcpy(tmp + newOffset, buffer, length);
|
||||
|
||||
disk_write_prod(tmp, sector, sectorCount);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// u32 newLength = (newOffset + length) - NX_EMMC_BLOCKSIZE;
|
||||
// memcpy(buffer, tmp + newOffset, newLength);
|
||||
// disk_read_mod(tmp, sector + 1, 1, &storage, prodinfo_part);
|
||||
// memcpy(buffer + newLength, tmp, length - newLength);
|
||||
// }
|
||||
|
||||
free(tmp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool writeHash(u32 hashOffset, u32 offset, u32 sz)
|
||||
{
|
||||
u8 *buffer = (u8 *)malloc(NX_EMMC_BLOCKSIZE);
|
||||
|
||||
SHA256_CTX ctx;
|
||||
|
@ -646,19 +695,60 @@ bool verifyHash(u32 hashOffset, u32 offset, u32 sz)
|
|||
{
|
||||
|
||||
readData(buffer, offset, NX_EMMC_BLOCKSIZE);
|
||||
// gfx_hexdump(0, buffer + NX_EMMC_BLOCKSIZE - 8, 8);
|
||||
sha256_update(&ctx, buffer, NX_EMMC_BLOCKSIZE);
|
||||
|
||||
sz -= NX_EMMC_BLOCKSIZE;
|
||||
offset += NX_EMMC_BLOCKSIZE;
|
||||
}
|
||||
|
||||
readData(buffer, offset, sz);
|
||||
if(sz > 0){
|
||||
|
||||
|
||||
readData(buffer, offset, sz);
|
||||
sha256_update(&ctx, buffer, sz);
|
||||
u8 *hash1 = (u8 *)malloc(0x20);
|
||||
}
|
||||
u8 hash[0x20];
|
||||
sha256_final(&ctx, hash);
|
||||
|
||||
writeData(hash, hashOffset, 0x20);
|
||||
|
||||
|
||||
|
||||
|
||||
free(buffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool verifyHash(u32 hashOffset, u32 offset, u32 sz)
|
||||
{
|
||||
bool result = false;
|
||||
u8 *buffer = (u8 *)malloc(NX_EMMC_BLOCKSIZE);
|
||||
|
||||
SHA256_CTX ctx;
|
||||
sha256_init(&ctx);
|
||||
|
||||
while (sz > 64)
|
||||
{
|
||||
|
||||
readData(buffer, offset, 64);
|
||||
// gfx_hexdump(0, buffer + NX_EMMC_BLOCKSIZE - 8, 8);
|
||||
sha256_update(&ctx, buffer, 64);
|
||||
|
||||
sz -= 64;
|
||||
offset += 64;
|
||||
}
|
||||
|
||||
if(sz > 0){
|
||||
|
||||
|
||||
readData(buffer, offset, sz);
|
||||
sha256_update(&ctx, buffer, sz);
|
||||
}
|
||||
u8 hash1[0x20];
|
||||
sha256_final(&ctx, hash1);
|
||||
|
||||
u8 *hash2 = (u8 *)malloc(0x20);
|
||||
u8 hash2[0x20];
|
||||
//se_calc_sha256(hash1, buffer, sz);
|
||||
//sha256CalculateHash(hash1, buffer, sz);
|
||||
|
||||
|
@ -667,22 +757,16 @@ bool verifyHash(u32 hashOffset, u32 offset, u32 sz)
|
|||
if (memcmp(hash1, hash2, 0x20))
|
||||
{
|
||||
EPRINTF("error: hash verification failed\n");
|
||||
//printf("error: hash verification failed for %x %d\n", (long)offset, (long)sz);
|
||||
|
||||
//print(hash1, 0x20);
|
||||
//print(hash2, 0x20);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
|
||||
gfx_hexdump(0, hash1, 0x08);
|
||||
gfx_hexdump(0, hash2, 0x08);
|
||||
gfx_hexdump(0, hash1, 0x20);
|
||||
gfx_hexdump(0, hash2, 0x20);
|
||||
|
||||
free(buffer);
|
||||
free(hash1);
|
||||
free(hash2);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -690,10 +774,8 @@ u32 certSize()
|
|||
{
|
||||
u32 buffer;
|
||||
readData((u8 *)&buffer, 0x0AD0, sizeof(buffer));
|
||||
EPRINTF("certSize");
|
||||
gfx_hexdump(0, (u8 *)&buffer, sizeof(buffer));
|
||||
buffer = _read_le_u32(&buffer, 0);
|
||||
gfx_hexdump(0, (u8 *)&buffer, sizeof(buffer));
|
||||
// EPRINTF("certSize");
|
||||
// gfx_hexdump(0, (u8 *)&buffer, sizeof(buffer));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
@ -701,17 +783,102 @@ u32 calibrationDataSize()
|
|||
{
|
||||
u32 buffer;
|
||||
readData((u8 *)&buffer, 0x08, sizeof(buffer));
|
||||
EPRINTF("calSize");
|
||||
gfx_hexdump(0, (u8 *)&buffer, sizeof(buffer));
|
||||
buffer = _read_le_u32(&buffer, 0);
|
||||
gfx_hexdump(0, (u8 *)&buffer, sizeof(buffer));
|
||||
// EPRINTF("calSize");
|
||||
// gfx_hexdump(0, (u8 *)&buffer, sizeof(buffer));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool writeCal0Hash()
|
||||
{
|
||||
return writeHash(0x20, 0x40, calibrationDataSize());
|
||||
}
|
||||
|
||||
bool writeClientCertHash()
|
||||
{
|
||||
return writeHash(0x12E0, 0xAE0, certSize());
|
||||
}
|
||||
|
||||
bool verifyCal0Hash(){
|
||||
return verifyHash(0x20, 0x40, calibrationDataSize());
|
||||
}
|
||||
|
||||
bool verifyClientCertHash()
|
||||
{
|
||||
|
||||
|
||||
return verifyHash(0x12E0, 0xAE0, certSize());
|
||||
}
|
||||
|
||||
bool verify()
|
||||
{
|
||||
bool r = verifyHash(0x12E0, 0x0AE0, certSize()); // client cert hash
|
||||
r &= verifyHash(0x20, 0x0040, calibrationDataSize()); // calibration hash
|
||||
return verifyClientCertHash() & verifyCal0Hash();
|
||||
// bool r = verifyHash(0x12E0, 0xAE0, certSize()); // client cert hash
|
||||
// r &= verifyHash(0x20, 0x40, calibrationDataSize()); // calibration hash
|
||||
|
||||
return r;
|
||||
// return r;
|
||||
}
|
||||
|
||||
|
||||
void backup(){
|
||||
sd_mount();
|
||||
if (f_stat("sd:/prodinfo.bin", NULL)){
|
||||
f_unlink("sd:/prodinfo.bin");
|
||||
}
|
||||
FIL fp;
|
||||
f_open(&fp, "sd:/prodinfo.bin", FA_CREATE_NEW | FA_WRITE);
|
||||
u8 bufferNX[NX_EMMC_BLOCKSIZE];
|
||||
u32 size = 0x3FBC00;
|
||||
u32 offset = 0;
|
||||
while(size > NX_EMMC_BLOCKSIZE){
|
||||
readData(bufferNX, offset, NX_EMMC_BLOCKSIZE);
|
||||
f_write(&fp, bufferNX, NX_EMMC_BLOCKSIZE, NULL);
|
||||
offset += NX_EMMC_BLOCKSIZE;
|
||||
size -= NX_EMMC_BLOCKSIZE;
|
||||
}
|
||||
if(size > 0){
|
||||
readData(bufferNX, offset, size);
|
||||
f_write(&fp, bufferNX, size, NULL);
|
||||
}
|
||||
|
||||
f_close(&fp);
|
||||
|
||||
gfx_printf("\n%kBackup unecrypted done!", 4);
|
||||
|
||||
|
||||
if (f_stat("sd:/prodinfoENC.bin", NULL)){
|
||||
f_unlink("sd:/prodinfoENC.bin");
|
||||
}
|
||||
|
||||
f_open(&fp, "sd:/prodinfoENC.bin", FA_CREATE_NEW | FA_WRITE);
|
||||
size = 0x3FBC00;
|
||||
offset = 0;
|
||||
while(size > NX_EMMC_BLOCKSIZE){
|
||||
nx_emmc_part_read(&storage, prodinfo_part, offset, 1, bufferNX);
|
||||
f_write(&fp, bufferNX, NX_EMMC_BLOCKSIZE, NULL);
|
||||
offset ++;
|
||||
size -= NX_EMMC_BLOCKSIZE;
|
||||
}
|
||||
if(size > 0){
|
||||
nx_emmc_part_read(&storage, prodinfo_part, offset, 1, bufferNX);
|
||||
f_write(&fp, bufferNX, size, NULL);
|
||||
}
|
||||
|
||||
f_close(&fp);
|
||||
|
||||
gfx_printf("\n%kBackup encrypted done!", 4);
|
||||
|
||||
}
|
||||
|
||||
// bool erase(u32 offset, u32 sz)
|
||||
// {
|
||||
// u8 zero = 0;
|
||||
|
||||
// for (u64 i = 0; i < sz; i++)
|
||||
// {
|
||||
// fsStorageWrite(&m_sh, offset + i, &zero, 1);
|
||||
// }
|
||||
|
||||
// return true;
|
||||
// }
|
||||
|
|
|
@ -21,6 +21,9 @@
|
|||
|
||||
void dump_keys();
|
||||
bool readData(u8 *buffer, u32 offset, u32 length);
|
||||
bool writeData(u8 *buffer, u32 offset, u32 length);
|
||||
bool writeClientCertHash();
|
||||
bool writeCal0Hash();
|
||||
bool verify();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
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 {
|
||||
u32 sector;
|
||||
|
@ -127,13 +128,12 @@ out:;
|
|||
|
||||
|
||||
|
||||
DRESULT disk_read_mod (
|
||||
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 */
|
||||
sdmmc_storage_t *storage,
|
||||
emmc_part_t *partition)
|
||||
UINT count /* Number of sectors to read */
|
||||
)
|
||||
{
|
||||
|
||||
|
||||
|
@ -141,30 +141,11 @@ DRESULT disk_read_mod (
|
|||
__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;
|
||||
bool regen_tweak = true;
|
||||
|
||||
u32 s = 0;
|
||||
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);
|
||||
prev_sector = sector;
|
||||
prev_cluster = sector / 0x20;
|
||||
return RES_OK;
|
||||
}
|
||||
}
|
||||
// add to cache
|
||||
if (s == secindex && s < MAX_SEC_CACHE_ENTRIES) {
|
||||
sector_cache[s].sector = sector;
|
||||
sector_cache[s].visit_count++;
|
||||
cache_sector = true;
|
||||
secindex++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (nx_emmc_part_read(storage, partition, sector, count, buff)) {
|
||||
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;
|
||||
|
@ -177,10 +158,7 @@ DRESULT disk_read_mod (
|
|||
|
||||
// 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) {
|
||||
memcpy(sector_cache[s].cached_sector, buff, 0x200);
|
||||
memcpy(sector_cache[s].tweak, tweak, 0x10);
|
||||
}
|
||||
|
||||
prev_sector = sector + count - 1;
|
||||
return RES_OK;
|
||||
}
|
||||
|
@ -188,6 +166,44 @@ DRESULT disk_read_mod (
|
|||
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);
|
||||
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 */
|
||||
|
|
|
@ -33,7 +33,8 @@ 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_mod (BYTE *buff, DWORD sector, UINT count, sdmmc_storage_t *storage, emmc_part_t *partition);
|
||||
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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue