Include NAND CID & OTP hash in essential backup

This commit is contained in:
d0k3 2017-04-19 14:14:02 +02:00
parent 1aef326b98
commit 5e426f2694
4 changed files with 29 additions and 3 deletions

View File

@ -49,4 +49,8 @@ typedef struct {
u8 padding_movable[0x200 - sizeof(MovableSed)];
LocalFriendCodeSeed frndseed;
u8 padding_frndseed[0x200 - sizeof(LocalFriendCodeSeed)];
u8 nand_cid[0x10];
u8 padding_nand_cid[0x200 - 0x10];
u8 otp_hash[0x20];
u8 padding_otp_hash[0x200 - 0x20];
} __attribute__((packed)) EssentialBackup;

View File

@ -476,6 +476,19 @@ u32 GetLegitSector0x96(u8* sector)
return 1;
}
// OTP hash is 32 byte in size
u32 GetOtpHash(void* hash) {
if (!CheckSector0x96Crypto()) return 1;
memcpy(hash, OtpSha256, 0x20);
return 0;
}
// NAND CID is 16 byte in size
u32 GetNandCid(void* cid) {
sdmmc_get_cid(1, (u32*) cid);
return 0;
}
bool CheckMultiEmuNand(void)
{
// this only checks for the theoretical possibility

View File

@ -59,6 +59,8 @@ u32 CheckNandHeader(u8* header);
u32 CheckNandType(u32 src);
u32 GetLegitSector0x96(u8* sector);
u32 GetOtpHash(void* hash);
u32 GetNandCid(void* cid);
bool CheckMultiEmuNand(void);
u32 InitEmuNandBase(bool reset);

View File

@ -26,11 +26,13 @@ u32 ReadNandFile(FIL* file, void* buffer, u32 sector, u32 count, u32 keyslot) {
u32 BuildEssentialBackup(const char* path, EssentialBackup* essential) {
// prepare essential backup struct
const ExeFsFileHeader filelist[] = {
ExeFsFileHeader filelist[] = {
{ "nand_hdr", 0x000, 0x200 },
{ "secinfo" , 0x200, 0x111 },
{ "movable" , 0x400, 0x140 },
{ "frndseed", 0x600, 0x110 }
{ "frndseed", 0x600, 0x110 },
{ "nand_cid", 0x800, 0x010 },
{ "otp_hash", 0xA00, 0x020 }
};
memset(essential, 0, sizeof(EssentialBackup));
memcpy(essential, filelist, sizeof(filelist));
@ -65,8 +67,13 @@ u32 BuildEssentialBackup(const char* path, EssentialBackup* essential) {
((files[2].size != 0x120) && (files[2].size != 0x140)) || (files[3].size != 0x110))
return 1;
// fill nand cid / otp hash
if (GetNandCid(&(essential->nand_cid)) != 0) return 1;
bool have_otp = (GetOtpHash(&(essential->otp_hash)) == 0);
if (!have_otp) memset(&(filelist[5]), 0, sizeof(ExeFsFileHeader));
// calculate hashes
for (u32 i = 0; i < 4; i++)
for (u32 i = 0; i < (have_otp ? 6 : 5); i++)
sha_quick(essential->header.hashes[9-i],
((u8*) essential) + files[i].offset + sizeof(ExeFsHeader),
files[i].size, SHA256_MODE);