1
0
Fork 0
mirror of https://github.com/Scandal-UK/Incognito_RCM.git synced 2024-11-22 20:06:42 +00:00

decrypting and reading ready, encrypting and writing todo

This commit is contained in:
jimzrt 2019-09-25 00:49:22 +02:00
parent 4ce94bc2b1
commit 76bfd54fd2
4 changed files with 250 additions and 63 deletions

View file

@ -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);
@ -388,6 +399,7 @@ void dump_keys() {
// pkg2_done:
// // free(pkg2);
// // free(ki);
@ -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)
{
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)
{
bool result = false;
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;
// }

View file

@ -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

View file

@ -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 */

View file

@ -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);