#include #include #include #include #include "channel_launcher.h" #include "booter/external_booter.hpp" #include "gecko/gecko.hpp" #include "loader/disc.h" #include "loader/fs.h" #include "loader/fst.h" #include "loader/utils.h" #include "loader/sys.h" #include "memory/mem2.hpp" #include "memory/memory.h" #include "unzip/lz77.h" #include "types.h" bool Identify_GenerateTik(signed_blob **outbuf, u32 *outlen) { signed_blob *buffer = (signed_blob*)MEM2_memalign(32, STD_SIGNED_TIK_SIZE); if(!buffer) return false; memset(buffer, 0, STD_SIGNED_TIK_SIZE); sig_rsa2048 *signature = (sig_rsa2048*)buffer; signature->type = ES_SIG_RSA2048; tik *tik_data = (tik *)SIGNATURE_PAYLOAD(buffer); strcpy(tik_data->issuer, "Root-CA00000001-XS00000003"); memset(tik_data->cidx_mask, 0xFF, 32); *outbuf = buffer; *outlen = STD_SIGNED_TIK_SIZE; return true; } bool Identify(u64 titleid) { char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); gprintf("Reading TMD for %08lx %08lx...", TITLE_UPPER(titleid), TITLE_LOWER(titleid)); snprintf(filepath, ISFS_MAXPATH, "/title/%08lx/%08lx/content/title.tmd", TITLE_UPPER(titleid), TITLE_LOWER(titleid)); u32 tmdSize; u8 *tmdBuffer = ISFS_GetFile(filepath, &tmdSize, -1); if (tmdBuffer == NULL || tmdSize == 0) { gprintf("Failed!\n"); return false; } gprintf("Success!\n"); u32 tikSize; signed_blob *tikBuffer = NULL; gprintf("Generating fake ticket..."); if(!Identify_GenerateTik(&tikBuffer, &tikSize)) { MEM2_free(tmdBuffer); gprintf("Failed!\n"); return false; } gprintf("Success!\n"); gprintf("Reading certs..."); memset(filepath, 0, ISFS_MAXPATH); strcpy(filepath, "/sys/cert.sys"); u32 certSize = 0; u8 *certBuffer = ISFS_GetFile(filepath, &certSize, -1); if (certBuffer == NULL || certSize == 0) { gprintf("Failed!\n"); MEM2_free(tmdBuffer); MEM2_free(tikBuffer); return false; } gprintf("Success!\n"); gprintf("ES_Identify\n"); u32 keyId = 0; DCFlushRange(tmdBuffer, tmdSize); DCFlushRange(tikBuffer, tikSize); DCFlushRange(certBuffer, certSize); s32 ret = ES_Identify((signed_blob*)certBuffer, certSize, (signed_blob*)tmdBuffer, tmdSize, tikBuffer, tikSize, &keyId); if(ret < 0) { switch(ret) { case ES_EINVAL: gprintf("Error! ES_Identify (ret = %d;) Data invalid!\n", ret); break; case ES_EALIGN: gprintf("Error! ES_Identify (ret = %d;) Data not aligned!\n", ret); break; case ES_ENOTINIT: gprintf("Error! ES_Identify (ret = %d;) ES not initialized!\n", ret); break; case ES_ENOMEM: gprintf("Error! ES_Identify (ret = %d;) No memory!\n", ret); break; default: gprintf("Error! ES_Identify (ret = %d)\n", ret); break; } } gprintf("AHBPROT: %d, Key ID: %u\n", AHBPROT_Patched(), keyId); MEM2_free(tmdBuffer); MEM2_free(tikBuffer); MEM2_free(certBuffer); return ret < 0 ? false : true; }