1
Fork 0
mirror of https://github.com/naehrwert/scetool.git synced 2025-04-26 14:47:46 +00:00

Updated to v.0.2.11

- Enabled encryption for APP and NPDRM SPU selfs.
- .klic files now supported for decryption of the free  NPDRM selfs.
- "PS3" path env vars will now be searched for "data", "raps" , "klics"
dirs.
This commit is contained in:
Sorvigolova 2014-11-03 16:10:52 +03:00
parent e5b9ac8a9b
commit 4b0402d598
8 changed files with 93 additions and 18 deletions

View file

@ -44,7 +44,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
@ -60,7 +60,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile> <ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile> </ClCompile>

View file

@ -9,6 +9,7 @@ NP local license handling (C) 2012 by flatz
- /data/act.dat : act.dat - /data/act.dat : act.dat
- /rifs/* : *.rif files - /rifs/* : *.rif files
- /raps/* : *.rap files - /raps/* : *.rap files
- /klics/* : *.klic files
==> Keyfile Format <== ==> Keyfile Format <==
[keyname] [keyname]
@ -84,6 +85,10 @@ OPTIONS Possible Values Explanation
-j, --np-add-sig TRUE/FALSE(default) Whether to add a NP sig. or not. -j, --np-add-sig TRUE/FALSE(default) Whether to add a NP sig. or not.
==> History <== ==> History <==
Version 0.2.11
- Added .klic files support for easy decryption of the free-license-type NPDRM selfs.
- "PS3" path environment variable will now be searched for "data", "raps" and "klics" directories.
- Enabled encryption for APP and NPDRM SPU selfs.
Version 0.2.10 Version 0.2.10
- Added ECDSA Signature parsing and validation. - Added ECDSA Signature parsing and validation.
- Added klicensee parsing. - Added klicensee parsing.

View file

@ -7,7 +7,7 @@
#define _CONFIG_H_ #define _CONFIG_H_
/*! scetool base version. */ /*! scetool base version. */
#define SCETOOL_VERSION_BASE "0.2.10" #define SCETOOL_VERSION_BASE "0.2.11"
/*! Private build. */ /*! Private build. */
//#define CONFIG_PRIVATE_BUILD //#define CONFIG_PRIVATE_BUILD
@ -63,6 +63,8 @@
#define CONFIG_RIF_PATH "./rifs" #define CONFIG_RIF_PATH "./rifs"
#define CONFIG_RAP_FILE_EXT ".rap" #define CONFIG_RAP_FILE_EXT ".rap"
#define CONFIG_RAP_PATH "./raps" #define CONFIG_RAP_PATH "./raps"
#define CONFIG_KLIC_FILE_EXT ".klic"
#define CONFIG_KLIC_PATH "./klics"
/*! Key names. */ /*! Key names. */
#define CONFIG_NP_TID_KNAME "NP_tid" #define CONFIG_NP_TID_KNAME "NP_tid"

View file

@ -462,6 +462,8 @@ static u8 *idps_load()
sprintf(path, "%s/%s", ps3, CONFIG_IDPS_FILE); sprintf(path, "%s/%s", ps3, CONFIG_IDPS_FILE);
if(access(path, 0) != 0) if(access(path, 0) != 0)
sprintf(path, "%s/%s", CONFIG_IDPS_PATH, CONFIG_IDPS_FILE); sprintf(path, "%s/%s", CONFIG_IDPS_PATH, CONFIG_IDPS_FILE);
if(access(path, 0) != 0)
sprintf(path, "%s/%s/%s", ps3, CONFIG_IDPS_PATH, CONFIG_IDPS_FILE);
} }
else else
sprintf(path, "%s/%s", CONFIG_IDPS_PATH, CONFIG_IDPS_FILE); sprintf(path, "%s/%s", CONFIG_IDPS_PATH, CONFIG_IDPS_FILE);
@ -495,6 +497,8 @@ static act_dat_t *act_dat_load()
sprintf(path, "%s/%s", ps3, CONFIG_ACT_DAT_FILE); sprintf(path, "%s/%s", ps3, CONFIG_ACT_DAT_FILE);
if(access(path, 0) != 0) if(access(path, 0) != 0)
sprintf(path, "%s/%s", CONFIG_ACT_DAT_PATH, CONFIG_ACT_DAT_FILE); sprintf(path, "%s/%s", CONFIG_ACT_DAT_PATH, CONFIG_ACT_DAT_FILE);
if(access(path, 0) != 0)
sprintf(path, "%s/%s/%s", ps3, CONFIG_ACT_DAT_PATH, CONFIG_ACT_DAT_FILE);
} }
else else
sprintf(path, "%s/%s", CONFIG_ACT_DAT_PATH, CONFIG_ACT_DAT_FILE); sprintf(path, "%s/%s", CONFIG_ACT_DAT_PATH, CONFIG_ACT_DAT_FILE);
@ -528,6 +532,8 @@ static rif_t *rif_load(const s8 *content_id)
sprintf(path, "%s/%s%s", ps3, content_id, CONFIG_RIF_FILE_EXT); sprintf(path, "%s/%s%s", ps3, content_id, CONFIG_RIF_FILE_EXT);
if(access(path, 0) != 0) if(access(path, 0) != 0)
sprintf(path, "%s/%s%s", CONFIG_RIF_PATH, content_id, CONFIG_RIF_FILE_EXT); sprintf(path, "%s/%s%s", CONFIG_RIF_PATH, content_id, CONFIG_RIF_FILE_EXT);
if(access(path, 0) != 0)
sprintf(path, "%s/%s/%s%s", ps3, CONFIG_RIF_PATH, content_id, CONFIG_RIF_FILE_EXT);
} }
else else
sprintf(path, "%s/%s%s", CONFIG_RIF_PATH, content_id, CONFIG_RIF_FILE_EXT); sprintf(path, "%s/%s%s", CONFIG_RIF_PATH, content_id, CONFIG_RIF_FILE_EXT);
@ -560,6 +566,8 @@ static u8 *rap_load(const s8 *content_id)
sprintf(path, "%s/%s%s", ps3, content_id, CONFIG_RAP_FILE_EXT); sprintf(path, "%s/%s%s", ps3, content_id, CONFIG_RAP_FILE_EXT);
if(access(path, 0) != 0) if(access(path, 0) != 0)
sprintf(path, "%s/%s%s", CONFIG_RAP_PATH, content_id, CONFIG_RAP_FILE_EXT); sprintf(path, "%s/%s%s", CONFIG_RAP_PATH, content_id, CONFIG_RAP_FILE_EXT);
if(access(path, 0) != 0)
sprintf(path, "%s/%s/%s%s", ps3, CONFIG_RAP_PATH, content_id, CONFIG_RAP_FILE_EXT);
} }
else else
sprintf(path, "%s/%s%s", CONFIG_RAP_PATH, content_id, CONFIG_RAP_FILE_EXT); sprintf(path, "%s/%s%s", CONFIG_RAP_PATH, content_id, CONFIG_RAP_FILE_EXT);
@ -706,6 +714,45 @@ BOOL klicensee_by_content_id(const s8 *content_id, u8 *klicensee)
return TRUE; return TRUE;
} }
BOOL dev_klicensee_by_content_id(const s8 *content_id, u8 *klicensee)
{
s8 *ps3 = NULL, path[256];
u8 *klic;
u32 len = 0;
if((ps3 = getenv(CONFIG_ENV_PS3)) != NULL)
if(access(ps3, 0) != 0)
ps3 = NULL;
if(ps3 != NULL)
{
sprintf(path, "%s/%s%s", ps3, content_id, CONFIG_KLIC_FILE_EXT);
if(access(path, 0) != 0)
sprintf(path, "%s/%s%s", CONFIG_KLIC_PATH, content_id, CONFIG_KLIC_FILE_EXT);
if(access(path, 0) != 0)
sprintf(path, "%s/%s/%s%s", ps3, CONFIG_KLIC_PATH, content_id, CONFIG_KLIC_FILE_EXT);
}
else
sprintf(path, "%s/%s%s", CONFIG_KLIC_PATH, content_id, CONFIG_KLIC_FILE_EXT);
klic = (u8 *)_read_buffer(path, &len);
if(klic == NULL)
return FALSE;
if(len != KLIC_LENGTH)
{
free(klic);
return FALSE;
}
memcpy(klicensee, klic, KLIC_LENGTH);
free(klic);
_LOG_VERBOSE("Klicensee loaded from %s.klic.\n", content_id);
return TRUE;
}
keyset_t *keyset_from_buffer(u8 *keyset) keyset_t *keyset_from_buffer(u8 *keyset)
{ {
keyset_t *ks; keyset_t *ks;

View file

@ -35,6 +35,7 @@
#define ACT_DAT_LENGTH 0x1038 #define ACT_DAT_LENGTH 0x1038
#define RIF_LENGTH 0x98 #define RIF_LENGTH 0x98
#define RAP_LENGTH 0x10 #define RAP_LENGTH 0x10
#define KLIC_LENGTH 0x10
/*! IDPS, RIF, act.dat key lengths. */ /*! IDPS, RIF, act.dat key lengths. */
#define IDPS_KEYBITS 128 #define IDPS_KEYBITS 128
@ -127,6 +128,7 @@ BOOL vsh_curves_load(const s8 *cfile);
curve_t *vsh_curve_find(u8 ctype); curve_t *vsh_curve_find(u8 ctype);
BOOL klicensee_by_content_id(const s8 *content_id, u8 *klicensee); BOOL klicensee_by_content_id(const s8 *content_id, u8 *klicensee);
BOOL dev_klicensee_by_content_id(const s8 *content_id, u8 *klicensee);
keyset_t *keyset_from_buffer(u8 *keyset); keyset_t *keyset_from_buffer(u8 *keyset);

View file

@ -377,6 +377,8 @@ int main(int argc, char **argv)
sprintf(path, "%s/%s", ps3, CONFIG_KEYS_FILE); sprintf(path, "%s/%s", ps3, CONFIG_KEYS_FILE);
if(access(path, 0) != 0) if(access(path, 0) != 0)
sprintf(path, "%s/%s", CONFIG_KEYS_PATH, CONFIG_KEYS_FILE); sprintf(path, "%s/%s", CONFIG_KEYS_PATH, CONFIG_KEYS_FILE);
if(access(path, 0) != 0)
sprintf(path, "%s/%s/%s", ps3, CONFIG_KEYS_PATH, CONFIG_KEYS_FILE);
} }
else else
sprintf(path, "%s/%s", CONFIG_KEYS_PATH, CONFIG_KEYS_FILE); sprintf(path, "%s/%s", CONFIG_KEYS_PATH, CONFIG_KEYS_FILE);
@ -399,6 +401,8 @@ int main(int argc, char **argv)
sprintf(path, "%s/%s", ps3, CONFIG_CURVES_FILE); sprintf(path, "%s/%s", ps3, CONFIG_CURVES_FILE);
if(access(path, 0) != 0) if(access(path, 0) != 0)
sprintf(path, "%s/%s", CONFIG_CURVES_PATH, CONFIG_CURVES_FILE); sprintf(path, "%s/%s", CONFIG_CURVES_PATH, CONFIG_CURVES_FILE);
if(access(path, 0) != 0)
sprintf(path, "%s/%s/%s", ps3, CONFIG_CURVES_PATH, CONFIG_CURVES_FILE);
} }
else else
sprintf(path, "%s/%s", CONFIG_CURVES_PATH, CONFIG_CURVES_FILE); sprintf(path, "%s/%s", CONFIG_CURVES_PATH, CONFIG_CURVES_FILE);
@ -413,6 +417,8 @@ int main(int argc, char **argv)
sprintf(path, "%s/%s", ps3, CONFIG_VSH_CURVES_FILE); sprintf(path, "%s/%s", ps3, CONFIG_VSH_CURVES_FILE);
if(access(path, 0) != 0) if(access(path, 0) != 0)
sprintf(path, "%s/%s", CONFIG_VSH_CURVES_PATH, CONFIG_VSH_CURVES_FILE); sprintf(path, "%s/%s", CONFIG_VSH_CURVES_PATH, CONFIG_VSH_CURVES_FILE);
if(access(path, 0) != 0)
sprintf(path, "%s/%s/%s", ps3, CONFIG_VSH_CURVES_PATH, CONFIG_VSH_CURVES_FILE);
} }
else else
sprintf(path, "%s/%s", CONFIG_VSH_CURVES_PATH, CONFIG_VSH_CURVES_FILE); sprintf(path, "%s/%s", CONFIG_VSH_CURVES_PATH, CONFIG_VSH_CURVES_FILE);

View file

@ -49,11 +49,13 @@ void np_set_klicensee(u8 *klicensee)
BOOL np_decrypt_npdrm(sce_buffer_ctxt_t *ctxt) BOOL np_decrypt_npdrm(sce_buffer_ctxt_t *ctxt)
{ {
aes_context aes_ctxt; aes_context aes_ctxt;
keyset_t *ks_np_klic_free, *ks_klic_key; ci_data_npdrm_t *np;
keyset_t *ks_np_klic_free, *ks_klic_key, *ks_np_ci;
u8 hash_check[0x10], ci_key[0x10];
u8 npdrm_key[0x10]; u8 npdrm_key[0x10];
u8 npdrm_iv[0x10]; u8 npdrm_iv[0x10];
ci_data_npdrm_t *np; int i;
if((np = _sce_find_ci_npdrm(ctxt)) == NULL) if((np = _sce_find_ci_npdrm(ctxt)) == NULL)
return FALSE; return FALSE;
@ -66,9 +68,23 @@ BOOL np_decrypt_npdrm(sce_buffer_ctxt_t *ctxt)
else if(_ES32(np->license_type) == NP_LICENSE_FREE) else if(_ES32(np->license_type) == NP_LICENSE_FREE)
{ {
ks_np_klic_free = keyset_find_by_name(CONFIG_NP_KLIC_FREE_KNAME); ks_np_klic_free = keyset_find_by_name(CONFIG_NP_KLIC_FREE_KNAME);
if(ks_np_klic_free == NULL) ks_np_ci = keyset_find_by_name(CONFIG_NP_CI_KNAME);
if(ks_np_ci == NULL)
return FALSE; return FALSE;
memcpy(npdrm_key, ks_np_klic_free->erk, 0x10);
//Generate control info hash key.
for(i = 0; i < 0x10; i++)
ci_key[i] = ks_np_ci->erk[i] ^ ks_np_klic_free->erk[i];
//Check header for control info hash and try to load appropriate klicensee key.
aes_omac1(hash_check, (u8 *)_sce_find_ci_npdrm(ctxt), 0x60, ci_key, KEYBITS(0x10));
if (memcmp(hash_check, np->hash_ci, 0x10) != 0)
{
if((dev_klicensee_by_content_id((s8 *)np->content_id, npdrm_key)) == FALSE)
return FALSE;
}
else
memcpy(npdrm_key, ks_np_klic_free->erk, 0x10);
} }
else if(_ES32(np->license_type) == NP_LICENSE_LOCAL) else if(_ES32(np->license_type) == NP_LICENSE_LOCAL)
{ {
@ -80,12 +96,9 @@ BOOL np_decrypt_npdrm(sce_buffer_ctxt_t *ctxt)
if(_raw == TRUE) if(_raw == TRUE)
{ {
printf("[*] Klicensee: "); _hexdump(stdout, "[*] Klicensee:", 0, npdrm_key, sizeof(npdrm_key), FALSE);
int i;
for(i = 0; i < 0x10; i++)
printf("%02X ", npdrm_key[i]);
printf("\n");
} }
aes_setkey_dec(&aes_ctxt, ks_klic_key->erk, METADATA_INFO_KEYBITS); aes_setkey_dec(&aes_ctxt, ks_klic_key->erk, METADATA_INFO_KEYBITS);
aes_crypt_ecb(&aes_ctxt, AES_DECRYPT, npdrm_key, npdrm_key); aes_crypt_ecb(&aes_ctxt, AES_DECRYPT, npdrm_key, npdrm_key);
@ -151,7 +164,7 @@ BOOL np_create_ci(npdrm_config_t *npconf, ci_data_npdrm_t *cinp)
if(ks_np_tid == NULL || ks_np_ci == NULL) if(ks_np_tid == NULL || ks_np_ci == NULL)
return FALSE; return FALSE;
//Can only create NPDRM SELF with local and free license. //Can only create NPDRM SELF with "local" and free license.
if(_klicensee_key != NULL) if(_klicensee_key != NULL)
memcpy(npdrm_key, _klicensee_key, 0x10); memcpy(npdrm_key, _klicensee_key, 0x10);
else if(npconf->license_type == NP_LICENSE_FREE) else if(npconf->license_type == NP_LICENSE_FREE)

View file

@ -916,7 +916,7 @@ static BOOL _build_self_32(sce_buffer_ctxt_t *ctxt, self_config_t *sconf)
_es_elf32_ehdr(ehdr); _es_elf32_ehdr(ehdr);
//Copy program headers. //Copy program headers.
ctxt->makeself->phdrs = (Elf32_Phdr *)_memdup(ctxt->makeself->elf + ehdr->e_phoff, sizeof(Elf32_Phdr) * ehdr->e_phnum); ctxt->makeself->phdrs = (Elf32_Phdr *)_memdup(ctxt->makeself->elf + ehdr->e_phoff , sizeof(Elf32_Phdr) * ehdr->e_phnum);
ctxt->makeself->phsize = sizeof(Elf32_Phdr) * ehdr->e_phnum; ctxt->makeself->phsize = sizeof(Elf32_Phdr) * ehdr->e_phnum;
phdrs = (Elf32_Phdr *)_memdup(ctxt->makeself->elf + ehdr->e_phoff, sizeof(Elf32_Phdr) * ehdr->e_phnum); phdrs = (Elf32_Phdr *)_memdup(ctxt->makeself->elf + ehdr->e_phoff, sizeof(Elf32_Phdr) * ehdr->e_phnum);
@ -1043,7 +1043,7 @@ static BOOL _build_self_64(sce_buffer_ctxt_t *ctxt, self_config_t *sconf)
BOOL self_build_self(sce_buffer_ctxt_t *ctxt, self_config_t *sconf) BOOL self_build_self(sce_buffer_ctxt_t *ctxt, self_config_t *sconf)
{ {
//const u8 *eident; const u8 *eident;
//Fill config values. //Fill config values.
ctxt->sceh->key_revision = _ES16(sconf->key_revision); ctxt->sceh->key_revision = _ES16(sconf->key_revision);
@ -1075,8 +1075,8 @@ BOOL self_build_self(sce_buffer_ctxt_t *ctxt, self_config_t *sconf)
_fill_sce_version(ctxt); _fill_sce_version(ctxt);
//Check for 32 bit or 64 bit ELF. //Check for 32 bit or 64 bit ELF.
//eident = (const u8*)ctxt->makeself->elf; eident = (const u8*)ctxt->makeself->elf;
if(sconf->self_type == SELF_TYPE_LDR || sconf->self_type == SELF_TYPE_ISO /*|| eident[EI_CLASS] == ELFCLASS32*/) if(sconf->self_type == SELF_TYPE_LDR || sconf->self_type == SELF_TYPE_ISO || eident[EI_CLASS] == ELFCLASS32)
return _build_self_32(ctxt, sconf); return _build_self_32(ctxt, sconf);
return _build_self_64(ctxt, sconf); return _build_self_64(ctxt, sconf);
} }