Any-Region-Changer-ModMii-E.../source/id.c

251 lines
6.3 KiB
C
Raw Normal View History

2022-04-21 02:12:38 +02:00
/*-------------------------------------------------------------
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
id.c -- ES Identification code
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
Copyright (C) 2008 tona
Unless other credit specified
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
1.The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
2.Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
3.This notice may not be removed or altered from any source
distribution.
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
-------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gccore.h>
#include "wiibasics.h"
#include "id.h"
#include "gecko.h"
#include "sha1.h"
#include "certs_dat.h"
/* Debug functions adapted from libogc's es.c */
//#define DEBUG_ES
//#define DEBUG_IDENT
2022-04-21 03:38:39 +02:00
#define ISALIGNED(x) ((((u32)x) & 0x1F) == 0)
2022-04-21 02:12:38 +02:00
static u8 su_tmd[0x208] ATTRIBUTE_ALIGN(32);
static u8 su_tik[STD_SIGNED_TIK_SIZE] ATTRIBUTE_ALIGN(32);
int su_id_filled = 0;
#ifdef DEBUG_IDENT
s32 __sanity_check_certlist(const signed_blob *certs, u32 certsize)
{
int count = 0;
signed_blob *end;
2022-04-21 03:38:39 +02:00
if (!certs || !certsize)
return 0;
end = (signed_blob *)(((u8 *)certs) + certsize);
while (certs != end)
{
2022-04-21 02:12:38 +02:00
#ifdef DEBUG_ES
2022-04-21 03:38:39 +02:00
printf("Checking certificate at %p\n", certs);
2022-04-21 02:12:38 +02:00
#endif
certs = ES_NextCert(certs);
2022-04-21 03:38:39 +02:00
if (!certs)
return 0;
2022-04-21 02:12:38 +02:00
count++;
}
#ifdef DEBUG_ES
2022-04-21 03:38:39 +02:00
printf("Num of certificates: %d\n", count);
2022-04-21 02:12:38 +02:00
#endif
return count;
}
#endif
2022-04-21 03:38:39 +02:00
void zero_sig(signed_blob *sig)
{
u8 *sig_ptr = (u8 *)sig;
memset(sig_ptr + 4, 0, SIGNATURE_SIZE(sig) - 4);
2022-04-21 02:12:38 +02:00
}
2022-04-21 03:38:39 +02:00
void brute_tmd(tmd *p_tmd)
{
u16 fill;
for (fill = 0; fill < 65535; fill++)
{
p_tmd->fill2 = fill;
sha1 hash;
// debug_printf("SHA1(%p, %x, %p)\n", p_tmd, TMD_SIZE(p_tmd), hash);
SHA1((u8 *)p_tmd, TMD_SIZE(p_tmd), hash);
;
if (hash[0] == 0)
{
// debug_printf("setting fill3 to %04hx\n", fill);
return;
}
}
printf("Unable to fix tmd :(\n");
exit(4);
2022-04-21 02:12:38 +02:00
}
2022-04-21 03:38:39 +02:00
void brute_tik(tik *p_tik)
{
u16 fill;
for (fill = 0; fill < 65535; fill++)
{
p_tik->padding = fill;
sha1 hash;
// debug_printf("SHA1(%p, %x, %p)\n", p_tmd, TMD_SIZE(p_tmd), hash);
SHA1((u8 *)p_tik, sizeof(tik), hash);
if (hash[0] == 0)
return;
}
printf("Unable to fix tik :(\n");
exit(5);
2022-04-21 02:12:38 +02:00
}
2022-04-21 03:38:39 +02:00
void forge_tmd(signed_blob *s_tmd)
{
// debug_printf("forging tmd sig");
zero_sig(s_tmd);
brute_tmd(SIGNATURE_PAYLOAD(s_tmd));
2022-04-21 02:12:38 +02:00
}
2022-04-21 03:38:39 +02:00
void forge_tik(signed_blob *s_tik)
{
// debug_printf("forging tik sig");
zero_sig(s_tik);
brute_tik(SIGNATURE_PAYLOAD(s_tik));
}
2022-04-21 02:12:38 +02:00
2022-04-21 03:38:39 +02:00
void Make_SUID(void)
{
2022-04-21 02:12:38 +02:00
signed_blob *s_tmd, *s_tik;
tmd *p_tmd;
tik *p_tik;
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
memset(su_tmd, 0, sizeof su_tmd);
memset(su_tik, 0, sizeof su_tik);
2022-04-21 03:38:39 +02:00
s_tmd = (signed_blob *)&su_tmd[0];
s_tik = (signed_blob *)&su_tik[0];
2022-04-21 02:12:38 +02:00
*s_tmd = *s_tik = 0x10001;
2022-04-21 03:38:39 +02:00
p_tmd = (tmd *)SIGNATURE_PAYLOAD(s_tmd);
p_tik = (tik *)SIGNATURE_PAYLOAD(s_tik);
2022-04-21 02:12:38 +02:00
strcpy(p_tmd->issuer, "Root-CA00000001-CP00000004");
2022-04-21 03:38:39 +02:00
p_tmd->title_id = TITLE_ID(1, 2);
2022-04-21 02:12:38 +02:00
p_tmd->num_contents = 1;
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
forge_tmd(s_tmd);
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
strcpy(p_tik->issuer, "Root-CA00000001-XS00000003");
p_tik->ticketid = 0x000038A45236EE5FLL;
2022-04-21 03:38:39 +02:00
p_tik->titleid = TITLE_ID(1, 2);
2022-04-21 02:12:38 +02:00
memset(p_tik->cidx_mask, 0xFF, 0x20);
forge_tik(s_tik);
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
su_id_filled = 1;
}
2022-04-21 03:38:39 +02:00
s32 Identify(const u8 *certs, u32 certs_size, const u8 *idtmd, u32 idtmd_size, const u8 *idticket, u32 idticket_size)
{
2022-04-21 02:12:38 +02:00
s32 ret;
u32 keyid = 0;
2022-04-21 03:38:39 +02:00
ret = ES_Identify((signed_blob *)certs, certs_size, (signed_blob *)idtmd, idtmd_size, (signed_blob *)idticket, idticket_size, &keyid);
if (ret < 0)
{
switch (ret)
{
case ES_EINVAL:
printf("Error! ES_Identify (ret = %d;) Data invalid!\n", ret);
2022-04-21 03:38:39 +02:00
break;
case ES_EALIGN:
printf("Error! ES_Identify (ret = %d;) Data not aligned!\n", ret);
2022-04-21 03:38:39 +02:00
break;
case ES_ENOTINIT:
printf("Error! ES_Identify (ret = %d;) ES not initialized!\n", ret);
2022-04-21 03:38:39 +02:00
break;
case ES_ENOMEM:
printf("Error! ES_Identify (ret = %d;) No memory!\n", ret);
2022-04-21 03:38:39 +02:00
break;
default:
printf("Error! ES_Identify (ret = %d)\n", ret);
2022-04-21 03:38:39 +02:00
break;
2022-04-21 02:12:38 +02:00
}
#ifdef DEBUG_IDENT
printf("\tTicket: %u Std: %u Max: %u\n", idticket_size, STD_SIGNED_TIK_SIZE, MAX_SIGNED_TMD_SIZE);
2022-04-21 03:38:39 +02:00
printf("\tTMD invalid? %d %d %d Tik invalid? %d %d\n", !(signed_blob *)idtmd, !idtmd_size, !IS_VALID_SIGNATURE((signed_blob *)idtmd), !(signed_blob *)idticket, !IS_VALID_SIGNATURE((signed_blob *)idticket));
printf("\tCerts: Sane? %d\n", __sanity_check_certlist((signed_blob *)certs, certs_size));
if (!ISALIGNED(certs))
printf("\tCertificate data is not aligned!\n");
if (!ISALIGNED(idtmd))
printf("\tTMD data is not aligned!\n");
if (!ISALIGNED(idticket))
printf("\tTicket data is not aligned!\n");
2022-04-21 02:12:38 +02:00
#endif
}
else
printf("OK!\n");
return ret;
}
2022-04-21 03:38:39 +02:00
s32 Identify_SU(void)
{
2022-04-21 02:12:38 +02:00
if (!su_id_filled)
Make_SUID();
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
gprintf("\nIdentifying as SU...");
fflush(stdout);
return Identify(certs_dat, certs_dat_size, su_tmd, sizeof su_tmd, su_tik, sizeof su_tik);
}
2022-04-21 03:38:39 +02:00
s32 Identify_SysMenu(void)
{
2022-04-21 02:12:38 +02:00
s32 ret;
u32 sysmenu_tmd_size, sysmenu_ticket_size;
2022-04-21 03:38:39 +02:00
// static u8 certs[0xA00] ATTRIBUTE_ALIGN(32);
2022-04-21 02:12:38 +02:00
static u8 sysmenu_tmd[MAX_SIGNED_TMD_SIZE] ATTRIBUTE_ALIGN(32);
static u8 sysmenu_ticket[STD_SIGNED_TIK_SIZE] ATTRIBUTE_ALIGN(32);
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
/*printf("\nPulling Certs...");
ret = ISFS_ReadFileToArray ("/sys/certs.sys", certs, 0xA00, &certs_size);
if (ret < 0) {
printf("\tReading Certs failed!\n");
return -1;
}*/
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
printf("\nPulling Sysmenu TMD...");
2022-04-21 03:38:39 +02:00
ret = ISFS_ReadFileToArray("/title/00000001/00000002/content/title.tmd", sysmenu_tmd, MAX_SIGNED_TMD_SIZE, &sysmenu_tmd_size);
if (ret < 0)
{
2022-04-21 02:12:38 +02:00
printf("\tReading TMD failed!\n");
return -1;
}
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
printf("\nPulling Sysmenu Ticket...");
2022-04-21 03:38:39 +02:00
ret = ISFS_ReadFileToArray("/ticket/00000001/00000002.tik", sysmenu_ticket, STD_SIGNED_TIK_SIZE, &sysmenu_ticket_size);
if (ret < 0)
{
2022-04-21 02:12:38 +02:00
printf("\tReading TMD failed!\n");
return -1;
}
2022-04-21 03:38:39 +02:00
2022-04-21 02:12:38 +02:00
printf("\nIdentifying as SysMenu...");
fflush(stdout);
return Identify(certs_dat, certs_dat_size, sysmenu_tmd, sysmenu_tmd_size, sysmenu_ticket, sysmenu_ticket_size);
}