From 5e426f269474e2f2ca55504ee9630d648181eace Mon Sep 17 00:00:00 2001 From: d0k3 Date: Wed, 19 Apr 2017 14:14:02 +0200 Subject: [PATCH] Include NAND CID & OTP hash in essential backup --- source/nand/essentials.h | 4 ++++ source/nand/nand.c | 13 +++++++++++++ source/nand/nand.h | 2 ++ source/nand/nandutil.c | 13 ++++++++++--- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/source/nand/essentials.h b/source/nand/essentials.h index 6943e70..3012e78 100644 --- a/source/nand/essentials.h +++ b/source/nand/essentials.h @@ -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; diff --git a/source/nand/nand.c b/source/nand/nand.c index ce7620e..9a71aa4 100644 --- a/source/nand/nand.c +++ b/source/nand/nand.c @@ -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 diff --git a/source/nand/nand.h b/source/nand/nand.h index 136fab2..6714de7 100644 --- a/source/nand/nand.h +++ b/source/nand/nand.h @@ -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); diff --git a/source/nand/nandutil.c b/source/nand/nandutil.c index 978cb85..c7a1765 100644 --- a/source/nand/nandutil.c +++ b/source/nand/nandutil.c @@ -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)); @@ -64,9 +66,14 @@ u32 BuildEssentialBackup(const char* path, EssentialBackup* essential) { if ((files[0].size != 0x200) || (files[1].size != 0x111) || ((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);