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

make decrypting work for unaligned blocks

This commit is contained in:
jimzrt 2019-09-25 10:12:15 +02:00
parent 76bfd54fd2
commit 5d6f606925
2 changed files with 171 additions and 111 deletions

View file

@ -234,38 +234,38 @@ void dump_keys() {
se_aes_crypt_block_ecb(8, 0, master_key[6], master_key_source); se_aes_crypt_block_ecb(8, 0, master_key[6], master_key_source);
} }
if (pkg1_id->kb >= KB_FIRMWARE_VERSION_620) { // if (pkg1_id->kb >= KB_FIRMWARE_VERSION_620) {
// derive all lower master keys in case keyblobs are bad // // derive all lower master keys in case keyblobs are bad
if (_key_exists(master_key[pkg1_id->kb])) { // if (_key_exists(master_key[pkg1_id->kb])) {
for (u32 i = pkg1_id->kb; i > 0; i--) { // for (u32 i = pkg1_id->kb; i > 0; i--) {
se_aes_key_set(8, master_key[i], 0x10); // se_aes_key_set(8, master_key[i], 0x10);
se_aes_crypt_block_ecb(8, 0, master_key[i-1], mkey_vectors[i]); // se_aes_crypt_block_ecb(8, 0, master_key[i-1], mkey_vectors[i]);
} // }
se_aes_key_set(8, master_key[0], 0x10); // se_aes_key_set(8, master_key[0], 0x10);
se_aes_crypt_block_ecb(8, 0, temp_key, mkey_vectors[0]); // se_aes_crypt_block_ecb(8, 0, temp_key, mkey_vectors[0]);
if (_key_exists(temp_key)) { // if (_key_exists(temp_key)) {
EPRINTFARGS("Failed to derive master key. kb = %d", pkg1_id->kb); // EPRINTFARGS("Failed to derive master key. kb = %d", pkg1_id->kb);
} // }
} else if (_key_exists(master_key[KB_FIRMWARE_VERSION_MAX])) { // } else if (_key_exists(master_key[KB_FIRMWARE_VERSION_MAX])) {
// handle sept version differences // // handle sept version differences
for (u32 kb = KB_FIRMWARE_VERSION_MAX; kb >= KB_FIRMWARE_VERSION_620; kb--) { // for (u32 kb = KB_FIRMWARE_VERSION_MAX; kb >= KB_FIRMWARE_VERSION_620; kb--) {
for (u32 i = kb; i > 0; i--) { // for (u32 i = kb; i > 0; i--) {
se_aes_key_set(8, master_key[i], 0x10); // se_aes_key_set(8, master_key[i], 0x10);
se_aes_crypt_block_ecb(8, 0, master_key[i-1], mkey_vectors[i]); // se_aes_crypt_block_ecb(8, 0, master_key[i-1], mkey_vectors[i]);
} // }
se_aes_key_set(8, master_key[0], 0x10); // se_aes_key_set(8, master_key[0], 0x10);
se_aes_crypt_block_ecb(8, 0, temp_key, mkey_vectors[0]); // se_aes_crypt_block_ecb(8, 0, temp_key, mkey_vectors[0]);
if (!_key_exists(temp_key)) { // if (!_key_exists(temp_key)) {
break; // break;
} // }
memcpy(master_key[kb-1], master_key[kb], 0x10); // memcpy(master_key[kb-1], master_key[kb], 0x10);
memcpy(master_key[kb], zeros, 0x10); // memcpy(master_key[kb], zeros, 0x10);
} // }
if (_key_exists(temp_key)) { // if (_key_exists(temp_key)) {
EPRINTF("Failed to derive master key."); // EPRINTF("Failed to derive master key.");
} // }
} // }
} // }
u8 *keyblob_block = (u8 *)calloc(NX_EMMC_BLOCKSIZE, 1); u8 *keyblob_block = (u8 *)calloc(NX_EMMC_BLOCKSIZE, 1);
u8 keyblob_mac[0x10] = {0}; u8 keyblob_mac[0x10] = {0};
@ -387,12 +387,16 @@ void dump_keys() {
gfx_hexdump(0, buffer, sizeof(buffer)); gfx_hexdump(0, buffer, sizeof(buffer));
//free(buffer); //free(buffer);
verify(); // restore();
writeClientCertHash();
writeCal0Hash();
verify(); verify();
// writeClientCertHash();
// writeCal0Hash();
// verify();
// verify();
// free(tmp_copy); // free(tmp_copy);
@ -686,30 +690,44 @@ bool writeData(u8 *buffer, u32 offset, u32 length)
bool writeHash(u32 hashOffset, u32 offset, u32 sz) bool writeHash(u32 hashOffset, u32 offset, u32 sz)
{ {
u8 *buffer = (u8 *)malloc(NX_EMMC_BLOCKSIZE);
SHA256_CTX ctx; u8 *buffer = (u8 *)malloc(NX_EMMC_BLOCKSIZE);
sha256_init(&ctx);
while (sz > NX_EMMC_BLOCKSIZE) SHA256_CTX ctx;
{ sha256_init(&ctx);
readData(buffer, offset, NX_EMMC_BLOCKSIZE); u32 newOffset = offset % NX_EMMC_BLOCKSIZE;
// gfx_hexdump(0, buffer + NX_EMMC_BLOCKSIZE - 8, 8);
sha256_update(&ctx, buffer, NX_EMMC_BLOCKSIZE);
sz -= NX_EMMC_BLOCKSIZE; if (newOffset > 0 && newOffset + sz >= NX_EMMC_BLOCKSIZE)
offset += NX_EMMC_BLOCKSIZE; {
} u32 toRead = NX_EMMC_BLOCKSIZE - newOffset;
readData(buffer, offset, toRead);
// gfx_hexdump(0, buffer + NX_EMMC_BLOCKSIZE - 8, 8);
sha256_update(&ctx, buffer, toRead);
if(sz > 0){ sz -= toRead;
offset += toRead;
}
while (sz > NX_EMMC_BLOCKSIZE)
readData(buffer, offset, sz); {
sha256_update(&ctx, buffer, sz);
} readData(buffer, offset, NX_EMMC_BLOCKSIZE);
u8 hash[0x20]; // gfx_hexdump(0, buffer + NX_EMMC_BLOCKSIZE - 8, 8);
sha256_final(&ctx, hash); sha256_update(&ctx, buffer, NX_EMMC_BLOCKSIZE);
sz -= NX_EMMC_BLOCKSIZE;
offset += NX_EMMC_BLOCKSIZE;
}
if (sz > 0)
{
readData(buffer, offset, sz);
sha256_update(&ctx, buffer, sz);
}
u8 hash[0x20];
sha256_final(&ctx, hash);
writeData(hash, hashOffset, 0x20); writeData(hash, hashOffset, 0x20);
@ -720,63 +738,76 @@ bool writeHash(u32 hashOffset, u32 offset, u32 sz)
return true; return true;
} }
bool verifyHash(u32 hashOffset, u32 offset, u32 sz) 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)
{ {
bool result = false;
u8 *buffer = (u8 *)malloc(NX_EMMC_BLOCKSIZE);
readData(buffer, offset, 64); SHA256_CTX ctx;
// gfx_hexdump(0, buffer + NX_EMMC_BLOCKSIZE - 8, 8); sha256_init(&ctx);
sha256_update(&ctx, buffer, 64);
sz -= 64; u32 newOffset = offset % NX_EMMC_BLOCKSIZE;
offset += 64;
if (newOffset > 0 && newOffset + sz >= NX_EMMC_BLOCKSIZE)
{
u32 toRead = NX_EMMC_BLOCKSIZE - newOffset;
readData(buffer, offset, toRead);
// gfx_hexdump(0, buffer + NX_EMMC_BLOCKSIZE - 8, 8);
sha256_update(&ctx, buffer, toRead);
sz -= toRead;
offset += toRead;
}
while (sz > NX_EMMC_BLOCKSIZE)
{
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;
}
if (sz > 0)
{
readData(buffer, offset, sz);
sha256_update(&ctx, buffer, sz);
}
u8 hash1[0x20];
sha256_final(&ctx, hash1);
u8 hash2[0x20];
//se_calc_sha256(hash1, buffer, sz);
//sha256CalculateHash(hash1, buffer, sz);
readData(hash2, hashOffset, 0x20);
if (memcmp(hash1, hash2, 0x20))
{
EPRINTF("error: hash verification failed\n");
}
else
{
result = true;
}
gfx_hexdump(0, hash1, 0x20);
gfx_hexdump(0, hash2, 0x20);
free(buffer);
return result;
} }
if(sz > 0){ u32 certSize()
readData(buffer, offset, sz);
sha256_update(&ctx, buffer, sz);
}
u8 hash1[0x20];
sha256_final(&ctx, hash1);
u8 hash2[0x20];
//se_calc_sha256(hash1, buffer, sz);
//sha256CalculateHash(hash1, buffer, sz);
readData(hash2, hashOffset, 0x20);
if (memcmp(hash1, hash2, 0x20))
{ {
EPRINTF("error: hash verification failed\n"); u32 buffer;
} readData((u8 *)&buffer, 0x0AD0, sizeof(buffer));
else // EPRINTF("certSize");
{ // gfx_hexdump(0, (u8 *)&buffer, sizeof(buffer));
result = true; return buffer;
}
gfx_hexdump(0, hash1, 0x20);
gfx_hexdump(0, hash2, 0x20);
free(buffer);
return result;
}
u32 certSize()
{
u32 buffer;
readData((u8 *)&buffer, 0x0AD0, sizeof(buffer));
// EPRINTF("certSize");
// gfx_hexdump(0, (u8 *)&buffer, sizeof(buffer));
return buffer;
} }
u32 calibrationDataSize() u32 calibrationDataSize()
@ -854,23 +885,51 @@ void backup(){
f_open(&fp, "sd:/prodinfoENC.bin", FA_CREATE_NEW | FA_WRITE); f_open(&fp, "sd:/prodinfoENC.bin", FA_CREATE_NEW | FA_WRITE);
size = 0x3FBC00; size = 0x3FBC00;
offset = 0; offset = 0;
while(size > NX_EMMC_BLOCKSIZE){ while(size > 0){
nx_emmc_part_read(&storage, prodinfo_part, offset, 1, bufferNX); nx_emmc_part_read(&storage, prodinfo_part, offset, 1, bufferNX);
f_write(&fp, bufferNX, NX_EMMC_BLOCKSIZE, NULL); f_write(&fp, bufferNX, NX_EMMC_BLOCKSIZE, NULL);
offset ++; offset ++;
size -= NX_EMMC_BLOCKSIZE; size -= NX_EMMC_BLOCKSIZE;
} }
if(size > 0){ // if(size > 0){
nx_emmc_part_read(&storage, prodinfo_part, offset, 1, bufferNX); // nx_emmc_part_read(&storage, prodinfo_part, offset, 1, bufferNX);
f_write(&fp, bufferNX, size, NULL); // f_write(&fp, bufferNX, size, NULL);
} // }
f_close(&fp); f_close(&fp);
gfx_printf("\n%kBackup encrypted done!", 4); gfx_printf("\n%kBackup encrypted done!", colors[4]);
} }
bool restore(){
FIL fp;
if(f_open(&fp, "sd:/prodinfoENC.bin", FA_READ) != FR_OK){
gfx_printf("\n%Cannot open prodinfEnc.bin!", 4);
return false;
}
u8 bufferNX[NX_EMMC_BLOCKSIZE];
u32 size = 0x3FBC00;
u32 offset = 0;
while(size > 0){
f_read(&fp, bufferNX, NX_EMMC_BLOCKSIZE, NULL);
nx_emmc_part_write(&storage, prodinfo_part, offset, 1, bufferNX);
offset ++;
size -= NX_EMMC_BLOCKSIZE;
}
// if(size > 0){
// f_read(&fp, bufferNX, size, NULL);
// nx_emmc_part_write(&storage, prodinfo_part, offset, 1, bufferNX);
// f_write(&fp, bufferNX, size, NULL);
// }
f_close(&fp);
gfx_printf("\n%Restore encrypted done!", 4);
return true;
}
// bool erase(u32 offset, u32 sz) // bool erase(u32 offset, u32 sz)
// { // {
// u8 zero = 0; // u8 zero = 0;

View file

@ -25,5 +25,6 @@ bool writeData(u8 *buffer, u32 offset, u32 length);
bool writeClientCertHash(); bool writeClientCertHash();
bool writeCal0Hash(); bool writeCal0Hash();
bool verify(); bool verify();
bool restore();
#endif #endif