diff --git a/source/libwbfs/wiidisc.c b/source/libwbfs/wiidisc.c index 098a84f6..ca26e039 100644 --- a/source/libwbfs/wiidisc.c +++ b/source/libwbfs/wiidisc.c @@ -5,6 +5,7 @@ #include "wiidisc.h" #include "hw/aes.h" +#include "loader/nk.h" int wd_last_error = 0; @@ -81,11 +82,19 @@ static void partition_read_block(wiidisc_t *d, u32 blockno, u8 *block) offset = d->partition_data_offset + ((0x8000 >> 2) * blockno); partition_raw_read(d,offset, raw, 0x8000); - // decrypt data - AES_ResetEngine(); memcpy(iv, raw + 0x3d0, 16); - AES_EnableDecrypt(d->disc_key, iv); - AES_Decrypt(raw + 0x400, block, 0x7c0); + + // decrypt data + if(neek2o()) + { + NKAESDecryptBlock(raw, block); + } + else + { + AES_ResetEngine(); + AES_EnableDecrypt(d->disc_key, iv); + AES_Decrypt(raw + 0x400, block, 0x7c0); + } } static void partition_read(wiidisc_t *d, u32 offset, u8 *data, u32 len, int fake) @@ -245,7 +254,11 @@ static void do_partition(wiidisc_t*d) wbfs_fatal("malloc cert\n"); partition_raw_read(d, cert_offset, cert, cert_size); - decrypt_title_key(tik, d->disc_key); + + if(neek2o()) + NKKeyCreate(tik); + else + decrypt_title_key(tik, d->disc_key); partition_raw_read(d, h3_offset, 0, 0x18000); diff --git a/source/loader/nk.c b/source/loader/nk.c index 836f1cd3..ec4bddb4 100644 --- a/source/loader/nk.c +++ b/source/loader/nk.c @@ -34,6 +34,7 @@ #include "memory/mem2.hpp" #include "gecko/gecko.hpp" +static u32 KeyID; bool checked = false; bool neek = false; u32 kernelSize = 0; @@ -132,3 +133,55 @@ s32 Launch_nk(u64 TitleID, const char *nandpath, u64 ReturnTo) MEM1_free(mini); return 1; } + +void NKKeyCreate(u8 *tik) +{ + u32 *TKeyID = (u32*)MEM1_memalign(32, sizeof(u32)); + u8 *TitleID = (u8*)MEM1_memalign(32, 0x10); + u8 *EncTitleKey = (u8*)MEM1_memalign(32, 0x10); + + memset(TitleID, 0, 0x10); + memset(EncTitleKey, 0, 0x10); + + memcpy(TitleID, tik + 0x1DC, 8); + memcpy(EncTitleKey, tik + 0x1BF, 16); + + static ioctlv v[3] ATTRIBUTE_ALIGN(32); + + v[0].data = TitleID; + v[0].len = 0x10; + v[1].data = EncTitleKey; + v[1].len = 0x10; + v[2].data = TKeyID; + v[2].len = sizeof(u32); + + s32 ESHandle = IOS_Open("/dev/es", 0); + IOS_Ioctlv(ESHandle, 0x50, 2, 1, (ioctlv *)v); + IOS_Close(ESHandle); + + KeyID = *(u32*)(TKeyID); + + MEM1_free(TKeyID); + MEM1_free(EncTitleKey); + MEM1_free(TitleID); +} + +void NKAESDecryptBlock(u8 *in, u8 *out) +{ + static ioctlv v[5] ATTRIBUTE_ALIGN(32); + + v[0].data = &KeyID; + v[0].len = sizeof(u32); + v[1].data = in + 0x3d0; + v[1].len = 0x10; + v[2].data = in + 0x400; + v[2].len = 0x7c00; + v[3].data = 0; + v[3].len = 0; + v[4].data = out; + v[4].len = 0x7c00; + + s32 ESHandle = IOS_Open("/dev/es", 0); + IOS_Ioctlv(ESHandle, 0x2D, 3, 2, (ioctlv *)v); + IOS_Close(ESHandle); +} diff --git a/source/loader/nk.h b/source/loader/nk.h index 7e097372..a02677ef 100644 --- a/source/loader/nk.h +++ b/source/loader/nk.h @@ -29,6 +29,8 @@ s32 Launch_nk(u64 TitleID, const char *nandpath, u64 ReturnTo); bool Load_Neek2o_Kernel(); void check_neek2o(void); bool neek2o(void); +void NKKeyCreate(u8 *TIK); +void NKAESDecryptBlock(u8 *in, u8 *out); #ifdef __cplusplus }