1
Fork 0
mirror of https://github.com/naehrwert/scetool.git synced 2025-04-20 11:47:48 +00:00
This commit is contained in:
Sorvigolova 2018-06-08 11:21:06 +00:00 committed by GitHub
commit a42efa18fb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
65 changed files with 6123 additions and 3531 deletions

125
PS3/data/internal_keys Normal file
View file

@ -0,0 +1,125 @@
[pkg-sd]
category=PKG
revision=0000
version=0000008400000000
erk=FEDCBA98765432100123456789ABCDEFFEDCBA98765432100123456789ABCDEF
riv=0123456789ABCDEFFEDCBA9876543210
pub=123DA14B3D21D82AFC759A9CF6F41610A24EC8704306BAC4E0941A5B70EEA037F1482EA7EC578872
priv=000000000000000000000000000000000001000000
ctype=27
[spp-sd]
category=SPP
revision=0000
version=0000008400000000
erk=FEDCBA98765432100123456789ABCDEFFEDCBA98765432100123456789ABCDEF
riv=0123456789ABCDEFFEDCBA9876543210
pub=123DA14B3D21D82AFC759A9CF6F41610A24EC8704306BAC4E0941A5B70EEA037F1482EA7EC578872
priv=000000000000000000000000000000000001000000
ctype=27
[rvk-sd]
category=RVK
revision=0000
version=0000008400000000
erk=FEDCBA98765432100123456789ABCDEFFEDCBA98765432100123456789ABCDEF
riv=0123456789ABCDEFFEDCBA9876543210
pub=123DA14B3D21D82AFC759A9CF6F41610A24EC8704306BAC4E0941A5B70EEA037F1482EA7EC578872
priv=000000000000000000000000000000000001000000
ctype=27
[lv0ldr-sd]
category=SELF
revision=0000
version=0000008400000000
program_type=LV0
erk=FEDCBA98765432100123456789ABCDEFFEDCBA98765432100123456789ABCDEF
riv=0123456789ABCDEFFEDCBA9876543210
pub=123DA14B3D21D82AFC759A9CF6F41610A24EC8704306BAC4E0941A5B70EEA037F1482EA7EC578872
priv=000000000000000000000000000000000001000000
ctype=27
[metldr-sd]
category=SELF
revision=0000
version=0000008400000000
program_type=LDR
erk=FEDCBA98765432100123456789ABCDEFFEDCBA98765432100123456789ABCDEF
riv=0123456789ABCDEFFEDCBA9876543210
pub=123DA14B3D21D82AFC759A9CF6F41610A24EC8704306BAC4E0941A5B70EEA037F1482EA7EC578872
priv=000000000000000000000000000000000001000000
ctype=27
[isoldr-sd]
category=SELF
revision=0000
version=0000008400000000
program_type=ISO
erk=9E85BEE6D39E9632A77FE3CD6E647C8DFE4606C383E1697DD6D9CE63341EAFF9
riv=2C1F4C82FF3A796D3A772CEEF010ECA4
pub=625D1DF4C3264BBA9FC17A4437BA42591585A5ECCC6F3042DB3A80CBBC0426DAF33549C537AA7782
priv=00D19A1B338041F7C31062B9C40E725E1DA5D7C11A
ctype=20
[lv1ldr-sd]
category=SELF
version=0000008300000000
program_type=LV1
erk=FEDCBA98765432100123456789ABCDEFFEDCBA98765432100123456789ABCDEF
riv=0123456789ABCDEFFEDCBA9876543210
pub=123DA14B3D21D82AFC759A9CF6F41610A24EC8704306BAC4E0941A5B70EEA037F1482EA7EC578872
priv=000000000000000000000000000000000001000000
ctype=27
[lv1ldr-sd]
category=SELF
version=0000008400000000
program_type=LV1
erk=014485445EC9926C50F613AE77D9C37AA99838CCEB6F75FA78E29A8C622E8011
riv=A17D6A522CB1B08F97DA8A82E97C12F7
pub=72C1034FC8E4C1707B7147B9E930FA3F28EBFE070B5EBFBAE4A666B498050929815CF727C6264573
priv=008732ACD0889FF7480C5C7D9A5D3BF43C46F220F8
ctype=11
[lv2ldr-sd]
category=SELF
version=0000008300000000
program_type=LV2
erk=FEDCBA98765432100123456789ABCDEFFEDCBA98765432100123456789ABCDEF
riv=0123456789ABCDEFFEDCBA9876543210
pub=123DA14B3D21D82AFC759A9CF6F41610A24EC8704306BAC4E0941A5B70EEA037F1482EA7EC578872
priv=000000000000000000000000000000000001000000
ctype=27
[lv2ldr-sd]
category=SELF
version=0000008400000000
program_type=LV2
erk=014485445EC9926C50F613AE77D9C37AA99838CCEB6F75FA78E29A8C622E8011
riv=A17D6A522CB1B08F97DA8A82E97C12F7
pub=72C1034FC8E4C1707B7147B9E930FA3F28EBFE070B5EBFBAE4A666B498050929815CF727C6264573
priv=008732ACD0889FF7480C5C7D9A5D3BF43C46F220F8
ctype=11
[appldr-sd]
category=SELF
revision=0000
version=0000008400000000
program_type=APP
erk=014485445EC9926C50F613AE77D9C37AA99838CCEB6F75FA78E29A8C622E8011
riv=A17D6A522CB1B08F97DA8A82E97C12F7
pub=72C1034FC8E4C1707B7147B9E930FA3F28EBFE070B5EBFBAE4A666B498050929815CF727C6264573
priv=008732ACD0889FF7480C5C7D9A5D3BF43C46F220F8
ctype=11
[appldr-sd]
category=SELF
revision=0000
version=0000008400000000
program_type=UNK_7
erk=BBDF2959EB4AAEF5882BE11FF033B77FF9FD55B1F30819D42154F6B069C14FEF
riv=241C0CC5A8591B50EF460EE3E50116C3
pub=0E140FBAD23F1B236C6AD0623A7C2C6366AEDA66380860A9D727A56FD681F644EF22A7E07979A1BE
priv=
ctype=33

1257
PS3/data/keys Normal file

File diff suppressed because it is too large Load diff

BIN
PS3/data/ldr_curves Normal file

Binary file not shown.

BIN
PS3/data/vsh_curves Normal file

Binary file not shown.

View file

@ -0,0 +1 @@
ExampleExampleEx

View file

View file

BIN
Release/scetool.exe Normal file

Binary file not shown.

725
keys.cpp
View file

@ -1,725 +0,0 @@
/*
* Copyright (c) 2011-2013 by naehrwert
* Copyright (c) 2012 by flatz
* This file is released under the GPLv2.
*/
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef _WIN32
#include <io.h>
#else
#include <unistd.h>
#endif
#include "config.h"
#include "types.h"
#include "list.h"
#include "sce.h"
#include "keys.h"
#include "util.h"
#include "tables.h"
#include "aes.h"
/*
[keyname]
type={SELF, RVK, PKG, SPP, OTHER}
revision={00, ..., 18, 8000}
version={..., 0001000000000000, ...}
self_type={LV0, LV1, LV2, APP, ISO, LDR, UNK_7, NPDRM}
key=...
erk=...
riv=...
pub=...
priv=...
ctype=...
*/
/*! Loaded keysets. */
list_t *_keysets;
/*! Loaded curves. */
curve_t *_curves;
/*! Loaded VSH curves. */
vsh_curve_t *_vsh_curves;
static u8 rap_init_key[0x10] =
{
0x86, 0x9F, 0x77, 0x45, 0xC1, 0x3F, 0xD8, 0x90, 0xCC, 0xF2, 0x91, 0x88, 0xE3, 0xCC, 0x3E, 0xDF
};
static u8 rap_pbox[0x10] =
{
0x0C, 0x03, 0x06, 0x04, 0x01, 0x0B, 0x0F, 0x08, 0x02, 0x07, 0x00, 0x05, 0x0A, 0x0E, 0x0D, 0x09
};
static u8 rap_e1[0x10] =
{
0xA9, 0x3E, 0x1F, 0xD6, 0x7C, 0x55, 0xA3, 0x29, 0xB7, 0x5F, 0xDD, 0xA6, 0x2A, 0x95, 0xC7, 0xA5
};
static u8 rap_e2[0x10] =
{
0x67, 0xD4, 0x5D, 0xA3, 0x29, 0x6D, 0x00, 0x6A, 0x4E, 0x7C, 0x53, 0x7B, 0xF5, 0x53, 0x8C, 0x74
};
static void _fill_property(keyset_t *ks, s8 *prop, s8 *value)
{
if(strcmp(prop, "type") == 0)
{
if(strcmp(value, "SELF") == 0)
ks->type = KEYTYPE_SELF;
else if(strcmp(value, "RVK") == 0)
ks->type = KEYTYPE_RVK;
else if(strcmp(value, "PKG") == 0)
ks->type = KEYTYPE_PKG;
else if(strcmp(value, "SPP") == 0)
ks->type = KEYTYPE_SPP;
else if(strcmp(value, "OTHER") == 0)
ks->type = KEYTYPE_OTHER;
else
printf("[*] Error: Unknown type '%s'.\n", value);
}
else if(strcmp(prop, "revision") == 0)
ks->key_revision = (u16)_x_to_u64(value);
else if(strcmp(prop, "version") == 0)
ks->version = _x_to_u64(value);
else if(strcmp(prop, "self_type") == 0)
{
if(strcmp(value, "LV0") == 0)
ks->self_type = SELF_TYPE_LV0;
else if(strcmp(value, "LV1") == 0)
ks->self_type = SELF_TYPE_LV1;
else if(strcmp(value, "LV2") == 0)
ks->self_type = SELF_TYPE_LV2;
else if(strcmp(value, "APP") == 0)
ks->self_type = SELF_TYPE_APP;
else if(strcmp(value, "ISO") == 0)
ks->self_type = SELF_TYPE_ISO;
else if(strcmp(value, "LDR") == 0)
ks->self_type = SELF_TYPE_LDR;
else if(strcmp(value, "UNK_7") == 0)
ks->self_type = SELF_TYPE_UNK_7;
else if(strcmp(value, "NPDRM") == 0)
ks->self_type = SELF_TYPE_NPDRM;
else
printf("[*] Error: unknown SELF type '%s'.\n", value);
}
else if(strcmp(prop, "erk") == 0 || strcmp(prop, "key") == 0)
{
ks->erk = _x_to_u8_buffer(value);
ks->erklen = strlen(value) / 2;
}
else if(strcmp(prop, "riv") == 0)
{
ks->riv = _x_to_u8_buffer(value);
ks->rivlen = strlen(value) / 2;
}
else if(strcmp(prop, "pub") == 0)
ks->pub = _x_to_u8_buffer(value);
else if(strcmp(prop, "priv") == 0)
ks->priv = _x_to_u8_buffer(value);
else if(strcmp(prop, "ctype") == 0)
ks->ctype = (u8)_x_to_u64(value);
else
printf("[*] Error: Unknown keyfile property '%s'.\n", prop);
}
static s64 _compare_keysets(keyset_t *ks1, keyset_t *ks2)
{
s64 res;
if((res = (s64)ks1->version - (s64)ks2->version) == 0)
res = (s64)ks1->key_revision - (s64)ks2->key_revision;
return res;
}
static void _sort_keysets()
{
u32 i, to = _keysets->count;
lnode_t *max;
list_t *tmp = list_create();
for(i = 0; i < to; i++)
{
max = _keysets->head;
LIST_FOREACH(iter, _keysets)
{
if(_compare_keysets((keyset_t *)max->value, (keyset_t *)iter->value) < 0)
max = iter;
}
list_push(tmp, max->value);
list_remove_node(_keysets, max);
}
list_destroy(_keysets);
_keysets = tmp;
}
void _print_key_list(FILE *fp)
{
const s8 *name;
s32 len = 0, tmp;
LIST_FOREACH(iter, _keysets)
if((tmp = strlen(((keyset_t *)iter->value)->name)) > len)
len = tmp;
fprintf(fp, " Name");
_print_align(fp, " ", len, 4);
fprintf(fp, " Type Revision Version SELF-Type\n");
LIST_FOREACH(iter, _keysets)
{
keyset_t *ks = (keyset_t *)iter->value;
fprintf(fp, " %s", ks->name);
_print_align(fp, " ", len, strlen(ks->name));
fprintf(fp, " %-5s 0x%04X %s ", _get_name(_key_types, ks->type), ks->key_revision, sce_version_to_str(ks->version));
if(ks->type == KEYTYPE_SELF)
{
name = _get_name(_self_types, ks->self_type);
if(name != NULL)
fprintf(fp, "[%s]\n", name);
else
fprintf(fp, "0x%08X\n", ks->self_type);
}
else
fprintf(fp, "\n");
}
}
#define LINEBUFSIZE 512
BOOL keys_load(const s8 *kfile)
{
u32 i = 0, lblen;
FILE *fp;
s8 lbuf[LINEBUFSIZE];
keyset_t *cks = NULL;
if((_keysets = list_create()) == NULL)
return FALSE;
if((fp = fopen(kfile, "r")) == NULL)
{
list_destroy(_keysets);
return FALSE;
}
do
{
//Get next line.
lbuf[0] = 0;
fgets(lbuf, LINEBUFSIZE, fp);
lblen = strlen(lbuf);
//Don't parse empty lines (ignore '\n') and comment lines (starting with '#').
if(lblen > 1 && lbuf[0] != '#')
{
//Remove '\n'.
lbuf[lblen-1] = 0;
//Check for keyset entry.
if(lblen > 2 && lbuf[0] == '[')
{
if(cks != NULL)
{
//Add to keyset list.
list_push(_keysets, cks);
cks = NULL;
}
//Find name end.
for(i = 0; lbuf[i] != ']' && lbuf[i] != '\n' && i < lblen; i++);
lbuf[i] = 0;
//Allocate keyset and fill name.
cks = (keyset_t *)malloc(sizeof(keyset_t));
memset(cks, 0, sizeof(keyset_t));
cks->name = strdup(&lbuf[1]);
}
else if(cks != NULL)
{
//Find property name end.
for(i = 0; lbuf[i] != '=' && lbuf[i] != '\n' && i < lblen; i++);
lbuf[i] = 0;
//Fill property.
_fill_property(cks, &lbuf[0], &lbuf[i+1]);
}
}
} while(!feof(fp));
//Add last keyset to keyset list.
if(cks != NULL)
list_push(_keysets, cks);
//Sort keysets.
_sort_keysets();
return TRUE;
}
#undef LINEBUFSIZE
static keyset_t *_keyset_find_for_self(u32 self_type, u16 key_revision, u64 version)
{
LIST_FOREACH(iter, _keysets)
{
keyset_t *ks = (keyset_t *)iter->value;
if(ks->self_type == self_type)
{
switch(self_type)
{
case SELF_TYPE_LV0:
return ks;
break;
case SELF_TYPE_LV1:
if(version <= ks->version)
return ks;
break;
case SELF_TYPE_LV2:
if(version <= ks->version)
return ks;
break;
case SELF_TYPE_APP:
if(key_revision == ks->key_revision)
return ks;
break;
case SELF_TYPE_ISO:
if(version <= ks->version && key_revision == ks->key_revision)
return ks;
break;
case SELF_TYPE_LDR:
return ks;
break;
case SELF_TYPE_NPDRM:
if(key_revision == ks->key_revision)
return ks;
break;
}
}
}
return NULL;
}
static keyset_t *_keyset_find_for_rvk(u32 key_revision)
{
LIST_FOREACH(iter, _keysets)
{
keyset_t *ks = (keyset_t *)iter->value;
if(ks->type == KEYTYPE_RVK && key_revision <= ks->key_revision)
return ks;
}
return NULL;
}
static keyset_t *_keyset_find_for_pkg(u16 key_revision)
{
LIST_FOREACH(iter, _keysets)
{
keyset_t *ks = (keyset_t *)iter->value;
if(ks->type == KEYTYPE_PKG && key_revision <= ks->key_revision)
return ks;
}
return NULL;
}
static keyset_t *_keyset_find_for_spp(u16 key_revision)
{
LIST_FOREACH(iter, _keysets)
{
keyset_t *ks = (keyset_t *)iter->value;
if(ks->type == KEYTYPE_SPP && key_revision <= ks->key_revision)
return ks;
}
return NULL;
}
keyset_t *keyset_find(sce_buffer_ctxt_t *ctxt)
{
keyset_t *res = NULL;
switch(ctxt->sceh->header_type)
{
case SCE_HEADER_TYPE_SELF:
res = _keyset_find_for_self(ctxt->self.ai->self_type, ctxt->sceh->key_revision, ctxt->self.ai->version);
break;
case SCE_HEADER_TYPE_RVK:
res = _keyset_find_for_rvk(ctxt->sceh->key_revision);
break;
case SCE_HEADER_TYPE_PKG:
res = _keyset_find_for_pkg(ctxt->sceh->key_revision);
break;
case SCE_HEADER_TYPE_SPP:
res = _keyset_find_for_spp(ctxt->sceh->key_revision);
break;
}
if(res == NULL)
printf("[*] Error: Could not find keyset for %s.\n", _get_name(_sce_header_types, ctxt->sceh->header_type));
return res;
}
keyset_t *keyset_find_by_name(const s8 *name)
{
LIST_FOREACH(iter, _keysets)
{
keyset_t *ks = (keyset_t *)iter->value;
if(strcmp(ks->name, name) == 0)
return ks;
}
printf("[*] Error: Could not find keyset '%s'.\n", name);
return NULL;
}
BOOL curves_load(const s8 *cfile)
{
u32 len = 0;
_curves = (curve_t *)_read_buffer(cfile, &len);
if(_curves == NULL)
return FALSE;
if(len != CURVES_LENGTH)
{
free(_curves);
return FALSE;
}
return TRUE;
}
curve_t *curve_find(u8 ctype)
{
if(ctype > CTYPE_MAX)
return NULL;
return &_curves[ctype];
}
BOOL vsh_curves_load(const s8 *cfile)
{
u32 len = 0;
_vsh_curves = (vsh_curve_t *)_read_buffer(cfile, &len);
if(_vsh_curves == NULL)
return FALSE;
if(len != VSH_CURVES_LENGTH)
{
free(_vsh_curves);
return FALSE;
}
return TRUE;
}
static curve_t _tmp_curve;
curve_t *vsh_curve_find(u8 ctype)
{
if(ctype > VSH_CTYPE_MAX)
return NULL;
_memcpy_inv(_tmp_curve.p, _vsh_curves[ctype].p, 20);
_memcpy_inv(_tmp_curve.a, _vsh_curves[ctype].a, 20);
_memcpy_inv(_tmp_curve.b, _vsh_curves[ctype].b, 20);
_tmp_curve.N[0] = ~0x00;
_memcpy_inv(_tmp_curve.N+1, _vsh_curves[ctype].N, 20);
_memcpy_inv(_tmp_curve.Gx, _vsh_curves[ctype].Gx, 20);
_memcpy_inv(_tmp_curve.Gy, _vsh_curves[ctype].Gx, 20);
return &_tmp_curve;
}
static u8 *idps_load()
{
s8 *ps3 = NULL, path[256];
u8 *idps;
u32 len = 0;
if((ps3 = getenv(CONFIG_ENV_PS3)) != NULL)
if(access(ps3, 0) != 0)
ps3 = NULL;
if(ps3 != NULL)
{
sprintf(path, "%s/%s", ps3, CONFIG_IDPS_FILE);
if(access(path, 0) != 0)
sprintf(path, "%s/%s", CONFIG_IDPS_PATH, CONFIG_IDPS_FILE);
}
else
sprintf(path, "%s/%s", CONFIG_IDPS_PATH, CONFIG_IDPS_FILE);
idps = (u8 *)_read_buffer(path, &len);
if(idps == NULL)
return NULL;
if(len != IDPS_LENGTH)
{
free(idps);
return NULL;
}
return idps;
}
static act_dat_t *act_dat_load()
{
s8 *ps3 = NULL, path[256];
act_dat_t *act_dat;
u32 len = 0;
if((ps3 = getenv(CONFIG_ENV_PS3)) != NULL)
if(access(ps3, 0) != 0)
ps3 = NULL;
if(ps3 != NULL)
{
sprintf(path, "%s/%s", ps3, CONFIG_ACT_DAT_FILE);
if(access(path, 0) != 0)
sprintf(path, "%s/%s", CONFIG_ACT_DAT_PATH, CONFIG_ACT_DAT_FILE);
}
else
sprintf(path, "%s/%s", CONFIG_ACT_DAT_PATH, CONFIG_ACT_DAT_FILE);
act_dat = (act_dat_t *)_read_buffer(path, &len);
if(act_dat == NULL)
return NULL;
if(len != ACT_DAT_LENGTH)
{
free(act_dat);
return NULL;
}
return act_dat;
}
static rif_t *rif_load(const s8 *content_id)
{
s8 *ps3 = NULL, path[256];
rif_t *rif;
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_RIF_FILE_EXT);
if(access(path, 0) != 0)
sprintf(path, "%s/%s%s", CONFIG_RIF_PATH, content_id, CONFIG_RIF_FILE_EXT);
}
else
sprintf(path, "%s/%s%s", CONFIG_RIF_PATH, content_id, CONFIG_RIF_FILE_EXT);
rif = (rif_t *)_read_buffer(path, &len);
if(rif == NULL)
return NULL;
if(len < RIF_LENGTH)
{
free(rif);
return NULL;
}
return rif;
}
static u8 *rap_load(const s8 *content_id)
{
s8 *ps3 = NULL, path[256];
u8 *rap;
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_RAP_FILE_EXT);
if(access(path, 0) != 0)
sprintf(path, "%s/%s%s", CONFIG_RAP_PATH, content_id, CONFIG_RAP_FILE_EXT);
}
else
sprintf(path, "%s/%s%s", CONFIG_RAP_PATH, content_id, CONFIG_RAP_FILE_EXT);
rap = (u8 *)_read_buffer(path, &len);
if(rap == NULL)
return NULL;
if(len != RAP_LENGTH)
{
free(rap);
return NULL;
}
return rap;
}
static BOOL rap_to_klicensee(const s8 *content_id, u8 *klicensee)
{
u8 *rap;
aes_context aes_ctxt;
int round_num;
int i;
rap = rap_load(content_id);
if(rap == NULL)
return FALSE;
aes_setkey_dec(&aes_ctxt, rap_init_key, RAP_KEYBITS);
aes_crypt_ecb(&aes_ctxt, AES_DECRYPT, rap, rap);
for (round_num = 0; round_num < 5; ++round_num)
{
for (i = 0; i < 16; ++i)
{
int p = rap_pbox[i];
rap[p] ^= rap_e1[p];
}
for (i = 15; i >= 1; --i)
{
int p = rap_pbox[i];
int pp = rap_pbox[i - 1];
rap[p] ^= rap[pp];
}
int o = 0;
for (i = 0; i < 16; ++i)
{
int p = rap_pbox[i];
u8 kc = rap[p] - o;
u8 ec2 = rap_e2[p];
if (o != 1 || kc != 0xFF)
{
o = kc < ec2 ? 1 : 0;
rap[p] = kc - ec2;
}
else if (kc == 0xFF)
rap[p] = kc - ec2;
else
rap[p] = kc;
}
}
memcpy(klicensee, rap, RAP_LENGTH);
free(rap);
return TRUE;
}
BOOL klicensee_by_content_id(const s8 *content_id, u8 *klicensee)
{
aes_context aes_ctxt;
if(rap_to_klicensee(content_id, klicensee) == FALSE)
{
keyset_t *ks_np_idps_const, *ks_np_rif_key;
rif_t *rif;
u8 idps_const[0x10];
u8 act_dat_key[0x10];
u32 act_dat_key_index;
u8 *idps;
act_dat_t *act_dat;
if((idps = idps_load()) == NULL)
{
printf("[*] Error: Could not load IDPS.\n");
return FALSE;
}
else
_LOG_VERBOSE("IDPS loaded.\n");
if((act_dat = act_dat_load()) == NULL)
{
printf("[*] Error: Could not load act.dat.\n");
return FALSE;
}
else
_LOG_VERBOSE("act.dat loaded.\n");
ks_np_idps_const = keyset_find_by_name(CONFIG_NP_IDPS_CONST_KNAME);
if(ks_np_idps_const == NULL)
return FALSE;
memcpy(idps_const, ks_np_idps_const->erk, 0x10);
ks_np_rif_key = keyset_find_by_name(CONFIG_NP_RIF_KEY_KNAME);
if(ks_np_rif_key == NULL)
return FALSE;
rif = rif_load(content_id);
if(rif == NULL)
{
printf("[*] Error: Could not obtain klicensee for '%s'.\n", content_id);
return FALSE;
}
aes_setkey_dec(&aes_ctxt, ks_np_rif_key->erk, RIF_KEYBITS);
aes_crypt_ecb(&aes_ctxt, AES_DECRYPT, rif->act_key_index, rif->act_key_index);
act_dat_key_index = _ES32(*(u32 *)(rif->act_key_index + 12));
if(act_dat_key_index > 127)
{
printf("[*] Error: act.dat key index out of bounds.\n");
return FALSE;
}
memcpy(act_dat_key, act_dat->primary_key_table + act_dat_key_index * BITS2BYTES(ACT_DAT_KEYBITS), BITS2BYTES(ACT_DAT_KEYBITS));
aes_setkey_enc(&aes_ctxt, idps, IDPS_KEYBITS);
aes_crypt_ecb(&aes_ctxt, AES_ENCRYPT, idps_const, idps_const);
aes_setkey_dec(&aes_ctxt, idps_const, IDPS_KEYBITS);
aes_crypt_ecb(&aes_ctxt, AES_DECRYPT, act_dat_key, act_dat_key);
aes_setkey_dec(&aes_ctxt, act_dat_key, ACT_DAT_KEYBITS);
aes_crypt_ecb(&aes_ctxt, AES_DECRYPT, rif->klicensee, klicensee);
free(rif);
_LOG_VERBOSE("klicensee decrypted.\n");
}
else
_LOG_VERBOSE("klicensee converted from %s.rap.\n", content_id);
return TRUE;
}
keyset_t *keyset_from_buffer(u8 *keyset)
{
keyset_t *ks;
if((ks = (keyset_t *)malloc(sizeof(keyset_t))) == NULL)
return NULL;
ks->erk = (u8 *)_memdup(keyset, 0x20);
ks->erklen = 0x20;
ks->riv = (u8 *)_memdup(keyset + 0x20, 0x10);
ks->rivlen = 0x10;
ks->pub = (u8 *)_memdup(keyset + 0x20 + 0x10, 0x28);
ks->priv = (u8 *)_memdup(keyset + 0x20 + 0x10 + 0x28, 0x15);
ks->ctype = (u8)*(keyset + 0x20 + 0x10 + 0x28 + 0x15);
return ks;
}

1001
sce.cpp

File diff suppressed because it is too large Load diff

View file

@ -1,201 +0,0 @@
/*
* Copyright (c) 2011-2013 by naehrwert
* This file is released under the GPLv2.
*/
#ifndef _SCE_INLINES_H_
#define _SCE_INLINES_H_
#include <string.h>
#include "types.h"
#include "sce.h"
static inline void _es_sce_header(sce_header_t *h)
{
h->magic = _ES32(h->magic);
h->version = _ES32(h->version);
h->key_revision = _ES16(h->key_revision);
h->header_type = _ES16(h->header_type);
h->metadata_offset = _ES32(h->metadata_offset);
h->header_len = _ES64(h->header_len);
h->data_len = _ES64(h->data_len);
}
static inline void _copy_es_sce_header(sce_header_t *dst, sce_header_t *src)
{
memcpy(dst, src, sizeof(sce_header_t));
_es_sce_header(dst);
}
static inline void _es_metadata_header(metadata_header_t *h)
{
h->sig_input_length = _ES64(h->sig_input_length);
h->unknown_0 = _ES32(h->unknown_0);
h->section_count = _ES32(h->section_count);
h->key_count = _ES32(h->key_count);
h->opt_header_size = _ES32(h->opt_header_size);
h->unknown_1 = _ES32(h->unknown_1);
h->unknown_2 = _ES32(h->unknown_2);
}
static inline void _copy_es_metadata_header(metadata_header_t *dst, metadata_header_t *src)
{
memcpy(dst, src, sizeof(metadata_header_t));
_es_metadata_header(dst);
}
static inline void _es_metadata_section_header(metadata_section_header_t *h)
{
h->data_offset = _ES64(h->data_offset);
h->data_size = _ES64(h->data_size);
h->type = _ES32(h->type);
h->index = _ES32(h->index);
h->hashed = _ES32(h->hashed);
h->sha1_index = _ES32(h->sha1_index);
h->encrypted = _ES32(h->encrypted);
h->key_index = _ES32(h->key_index);
h->iv_index = _ES32(h->iv_index);
h->compressed = _ES32(h->compressed);
}
static inline void _copy_es_metadata_section_header(metadata_section_header_t *dst, metadata_section_header_t *src)
{
memcpy(dst, src, sizeof(metadata_section_header_t));
_es_metadata_section_header(dst);
}
static inline void _es_self_header(self_header_t *h)
{
h->header_type = _ES64(h->header_type);
h->app_info_offset = _ES64(h->app_info_offset);
h->elf_offset = _ES64(h->elf_offset);
h->phdr_offset = _ES64(h->phdr_offset);
h->shdr_offset = _ES64(h->shdr_offset);
h->section_info_offset = _ES64(h->section_info_offset);
h->sce_version_offset = _ES64(h->sce_version_offset);
h->control_info_offset = _ES64(h->control_info_offset);
h->control_info_size = _ES64(h->control_info_size);
h->padding = _ES64(h->padding);
}
static inline void _copy_es_self_header(self_header_t *dst, self_header_t *src)
{
memcpy(dst, src, sizeof(self_header_t));
_es_self_header(dst);
}
static inline void _es_section_info(section_info_t *si)
{
si->offset = _ES64(si->offset);
si->size = _ES64(si->size);
si->compressed = _ES32(si->compressed);
si->unknown_0 = _ES32(si->unknown_0);
si->unknown_1 = _ES32(si->unknown_1);
si->encrypted = _ES32(si->encrypted);
}
static inline void _copy_es_section_info(section_info_t *dst, section_info_t *src)
{
memcpy(dst, src, sizeof(section_info_t));
_es_section_info(dst);
}
static inline void _es_sce_version(sce_version_t *sv)
{
sv->header_type = _ES32(sv->header_type);
sv->present = _ES32(sv->present);
sv->size = _ES32(sv->size);
sv->unknown_3 = _ES32(sv->unknown_3);
}
static inline void _copy_es_sce_version(sce_version_t *dst, sce_version_t *src)
{
memcpy(dst, src, sizeof(sce_version_t));
_es_sce_version(dst);
}
static inline void _es_app_info(app_info_t *ai)
{
ai->auth_id = _ES64(ai->auth_id);
ai->vendor_id = _ES32(ai->vendor_id);
ai->self_type = _ES32(ai->self_type);
ai->version = _ES64(ai->version);
ai->padding = _ES64(ai->padding);
}
static inline void _copy_es_app_info(app_info_t *dst, app_info_t *src)
{
memcpy(dst, src, sizeof(app_info_t));
_es_app_info(dst);
}
static inline void _es_control_info(control_info_t *ci)
{
ci->type = _ES32(ci->type);
ci->size = _ES32(ci->size);
ci->next = _ES64(ci->next);
}
static inline void _copy_es_control_info(control_info_t *dst, control_info_t *src)
{
memcpy(dst, src, sizeof(control_info_t));
_es_control_info(dst);
}
static inline void _es_ci_data_digest_40(ci_data_digest_40_t *dig)
{
dig->fw_version = _ES64(dig->fw_version);
}
static inline void _copy_es_ci_data_digest_40(ci_data_digest_40_t *dst, ci_data_digest_40_t *src)
{
memcpy(dst, src, sizeof(ci_data_digest_40_t));
_es_ci_data_digest_40(dst);
}
static inline void _es_ci_data_npdrm(ci_data_npdrm_t *np)
{
np->magic = _ES32(np->magic);
np->unknown_0 = _ES32(np->unknown_0);
np->license_type = _ES32(np->license_type);
np->app_type = _ES32(np->app_type);
np->unknown_1 = _ES64(np->unknown_1);
np->unknown_2 = _ES64(np->unknown_2);
}
static inline void _copy_es_ci_data_npdrm(ci_data_npdrm_t *dst, ci_data_npdrm_t *src)
{
memcpy(dst, src, sizeof(ci_data_npdrm_t));
_es_ci_data_npdrm(dst);
}
static inline void _es_opt_header(opt_header_t *oh)
{
oh->type = _ES32(oh->type);
oh->size = _ES32(oh->size);
oh->next = _ES64(oh->next);
}
static inline void _copy_es_opt_header(opt_header_t *dst, opt_header_t *src)
{
memcpy(dst, src, sizeof(opt_header_t));
_es_opt_header(dst);
}
static inline void _es_oh_data_cap_flags(oh_data_cap_flags_t *cf)
{
cf->unk3 = _ES64(cf->unk3);
cf->unk4 = _ES64(cf->unk4);
cf->flags = _ES64(cf->flags);
cf->unk6 = _ES32(cf->unk6);
cf->unk7 = _ES32(cf->unk7);
}
static inline void _copy_es_cap_flags(oh_data_cap_flags_t *dst, oh_data_cap_flags_t *src)
{
memcpy(dst, src, sizeof(oh_data_cap_flags_t));
_es_oh_data_cap_flags(dst);
}
#endif

22
scetool.sln Normal file
View file

@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.30723.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scetool", "scetool.vcxproj", "{39DC2066-1E3C-488C-8A76-1BB64ABF6C99}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{39DC2066-1E3C-488C-8A76-1BB64ABF6C99}.Debug|Win32.ActiveCfg = Debug|Win32
{39DC2066-1E3C-488C-8A76-1BB64ABF6C99}.Debug|Win32.Build.0 = Debug|Win32
{39DC2066-1E3C-488C-8A76-1BB64ABF6C99}.Release|Win32.ActiveCfg = Release|Win32
{39DC2066-1E3C-488C-8A76-1BB64ABF6C99}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

128
scetool.vcxproj Normal file
View file

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{39DC2066-1E3C-488C-8A76-1BB64ABF6C99}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120_xp</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;zlibd.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/SUBSYSTEM:CONSOLE,5.01 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;zlib.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>/SUBSYSTEM:CONSOLE,5.01 %(AdditionalOptions)</AdditionalOptions>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\aes.cpp" />
<ClCompile Include="src\aes_omac.cpp" />
<ClCompile Include="src\bn.cpp" />
<ClCompile Include="src\ec.cpp" />
<ClCompile Include="src\ecdsa.cpp" />
<ClCompile Include="src\frontend.cpp" />
<ClCompile Include="src\getopt.cpp" />
<ClCompile Include="src\keys.cpp" />
<ClCompile Include="src\list.cpp" />
<ClCompile Include="src\main.cpp" />
<ClCompile Include="src\mt19937.cpp" />
<ClCompile Include="src\np.cpp" />
<ClCompile Include="src\pkg.cpp" />
<ClCompile Include="src\rvk.cpp" />
<ClCompile Include="src\sce.cpp" />
<ClCompile Include="src\self.cpp" />
<ClCompile Include="src\sha1.cpp" />
<ClCompile Include="src\spp.cpp" />
<ClCompile Include="src\tables.cpp" />
<ClCompile Include="src\util.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\aes.h" />
<ClInclude Include="src\aes_omac.h" />
<ClInclude Include="src\config.h" />
<ClInclude Include="src\ecdsa.h" />
<ClInclude Include="src\elf.h" />
<ClInclude Include="src\elf_inlines.h" />
<ClInclude Include="src\frontend.h" />
<ClInclude Include="src\getopt.h" />
<ClInclude Include="src\keys.h" />
<ClInclude Include="src\list.h" />
<ClInclude Include="src\mt19937.h" />
<ClInclude Include="src\np.h" />
<ClInclude Include="src\pkg.h" />
<ClInclude Include="src\rvk.h" />
<ClInclude Include="src\sce.h" />
<ClInclude Include="src\sce_inlines.h" />
<ClInclude Include="src\self.h" />
<ClInclude Include="src\sha1.h" />
<ClInclude Include="src\spp.h" />
<ClInclude Include="src\tables.h" />
<ClInclude Include="src\types.h" />
<ClInclude Include="src\util.h" />
<ClInclude Include="src\zconf.h" />
<ClInclude Include="src\zlib.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

153
scetool.vcxproj.filters Normal file
View file

@ -0,0 +1,153 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\aes.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\aes_omac.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\bn.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ec.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ecdsa.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\frontend.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\getopt.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\keys.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\list.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\mt19937.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\np.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\pkg.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\rvk.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\sce.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\self.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\sha1.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\spp.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\tables.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="src\util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="src\aes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\aes_omac.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\config.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ecdsa.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\elf.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\elf_inlines.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\frontend.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\getopt.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\keys.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\list.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\mt19937.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\np.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\pkg.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\rvk.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\sce.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\sce_inlines.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\self.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\sha1.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\spp.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\tables.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\types.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\util.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\zconf.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="src\zlib.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

8
scetool.vcxproj.user Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerCommandArguments>
</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>

1082
self.cpp

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
CC=gcc CC=g++
CFLAGS=-g -O0 -Wall CFLAGS=-g -O0 -Wall
OS_TARGET=scetool OS_TARGET=scetool
LDFLAGS=-lz LDFLAGS=-lz

View file

@ -9,13 +9,14 @@ 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]
type={SELF, RVK, PKG, SPP, OTHER} category={SELF, RVK, PKG, SPP, OTHER}
revision={00, ..., 18, 8000} revision={00, ..., 18, 8000}
version={..., 0001000000000000, ...} version={..., 0001000000000000, ...}
self_type={LV0, LV1, LV2, APP, ISO, LDR, UNK_7, NPDRM} program_type={LV0, LV1, LV2, APP, ISO, LDR, UNK_7, NPDRM}
key=... key=...
erk=... erk=...
riv=... riv=...
@ -25,9 +26,9 @@ NP local license handling (C) 2012 by flatz
==> Keyset Example <== ==> Keyset Example <==
[metldr] [metldr]
type=SELF category=SELF
revision=00 revision=00
self_type=LDR program_type=LDR
erk=0000000000000000000000000000000000000000000000000000000000000000 erk=0000000000000000000000000000000000000000000000000000000000000000
riv=00000000000000000000000000000000 riv=00000000000000000000000000000000
pub=00000000000000000000000000000000000000000000000000000000000000000000000000000000 pub=00000000000000000000000000000000000000000000000000000000000000000000000000000000
@ -43,6 +44,12 @@ NP local license handling (C) 2012 by flatz
- [NP_rif_key]: rif key. - [NP_rif_key]: rif key.
- [NP_sig]: Footer signature ECDSA keyset. - [NP_sig]: Footer signature ECDSA keyset.
==> NPDRM ReActPsn Key(set) Names <==
- [NP_rap_initial]: RAP initial aes decryption key.
- [NP_rap_pbox]: RAP permutation box constant.
- [NP_rap_e1] RAP e1 constant.
- [NP_rap_e2] RAP e2 constant.
==> Override Keyset <== ==> Override Keyset <==
It should be a single hex-string consisting of: It should be a single hex-string consisting of:
32 bytes (Key) 16 bytes (IV) 40 bytes (Pub) 21 bytes (Priv) 1 byte (CType). 32 bytes (Key) 16 bytes (IV) 40 bytes (Pub) 21 bytes (Priv) 1 byte (CType).
@ -59,7 +66,7 @@ OPTIONS Possible Values Explanation
-v, --verbose Enable verbose output. -v, --verbose Enable verbose output.
-r, --raw Enable raw value output. -r, --raw Enable raw value output.
-t, --template File-in Template file (SELF only) -t, --template File-in Template file (SELF only)
-0, --sce-type SELF/RVK/PKG/SPP SCE File Type -0, --category SELF/RVK/PKG/SPP SCE File Type
-1, --compress-data TRUE/FALSE(default) Whether to compress data or not. -1, --compress-data TRUE/FALSE(default) Whether to compress data or not.
-s, --skip-sections TRUE(default)/FALSE Whether to skip sections or not. -s, --skip-sections TRUE(default)/FALSE Whether to skip sections or not.
-2, --key-revision e.g. 00,01,...,0A,... Key Revision -2, --key-revision e.g. 00,01,...,0A,... Key Revision
@ -67,10 +74,10 @@ OPTIONS Possible Values Explanation
-K, --keyset 32(Key)16(IV) -K, --keyset 32(Key)16(IV)
40(Pub)21(Priv)1(CT) Override keyset. 40(Pub)21(Priv)1(CT) Override keyset.
-3, --self-auth-id e.g. 1010000001000003 Authentication ID -3, --program-auth-id e.g. 1010000001000003 Authentication ID
-4, --self-vendor-id e.g. 01000002 Vendor ID -4, --program-vendor-id e.g. 01000002 Vendor ID
-5, --self-type LV0/LV1/LV2/APP/ISO/ -5, --program-type LV0/LV1/LV2/APP/ISO/
LDR/NPDRM SELF Type LDR/NPDRM Program Type
-A, --self-app-version e.g. 0001000000000000 Application Version -A, --self-app-version e.g. 0001000000000000 Application Version
-6, --self-fw-version e.g. 0003004100000000 Firmware Version -6, --self-fw-version e.g. 0003004100000000 Firmware Version
-7, --self-add-shdrs TRUE(default)/FALSE Whether to add ELF shdrs or not. -7, --self-add-shdrs TRUE(default)/FALSE Whether to add ELF shdrs or not.
@ -84,6 +91,34 @@ 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.3.1
- Updated Program Authority IDs.
- Fixed Vsh Curve loader.
Version 0.3.0
- Added Internal keys support.
- Added Signed Elf ver.2 decryption support.
- Decrypting header will now use key-bruteforce method.
- Options changed.
- Removed Pub/Priv configs, enabled all features by default.
Version 0.2.14
- Added PS3 Linux support.
- Fixed ECDSA checking.
Version 0.2.13
- Unlocked decryption for self files with network license type.
- Fixed one minor bug with capability flags.
Version 0.2.12
- Enabled options to compress and skip sections for SPU selfs.
- Extended information about the NPDRM selfs.
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
- Added ECDSA Signature parsing and validation.
- Added klicensee parsing.
- Fixed metadata info IV parsing.
- Enabled Individuals seed functions for <public build> configuration.
Version 0.2.9 Version 0.2.9
- Plaintext sections will now take less space in metadata header keys array. - Plaintext sections will now take less space in metadata header keys array.
- Added option to specifiy a template SELF to take configuration values from. - Added option to specifiy a template SELF to take configuration values from.

View file

View file

View file

View file

@ -6,30 +6,8 @@
#ifndef _CONFIG_H_ #ifndef _CONFIG_H_
#define _CONFIG_H_ #define _CONFIG_H_
/*! scetool base version. */
#define SCETOOL_VERSION_BASE "0.2.9"
/*! Private build. */
//#define CONFIG_PRIVATE_BUILD
#define BUILD_FOR "naehrwert"
//#define BUILD_FOR "unicorns"
/*! scetool version. */ /*! scetool version. */
#ifdef CONFIG_PRIVATE_BUILD #define SCETOOL_VERSION "0.3.1"
#ifdef BUILD_FOR
#define SCETOOL_VERSION SCETOOL_VERSION_BASE " <PRIVATE BUILD:" BUILD_FOR ">"
#else
#error Specify a name in BUILD_FOR.
#endif
#else
#define SCETOOL_VERSION SCETOOL_VERSION_BASE " <public build>"
#endif
/*! Private build options. */
#ifdef CONFIG_PRIVATE_BUILD
#define CONFIG_CUSTOM_INDIV_SEED
#define CONFIG_DUMP_INDIV_SEED
#endif
#if 0 #if 0
/*! scetool API. */ /*! scetool API. */
@ -41,15 +19,12 @@
#endif #endif
#endif #endif
/*! NPDRM watermark text (16 bytes exactly). */
//"I like kittens !"
#define CONFIG_NPDRM_WATERMARK "watermarktrololo"
/*! Environment variables. */ /*! Environment variables. */
#define CONFIG_ENV_PS3 "PS3" #define CONFIG_ENV_PS3 "PS3"
/*! Path configurations. */ /*! Path configurations. */
#define CONFIG_KEYS_FILE "keys" #define CONFIG_KEYS_FILE "keys"
#define CONFIG_INTERNAL_KEYS_FILE "internal_keys"
#define CONFIG_KEYS_PATH "./data" #define CONFIG_KEYS_PATH "./data"
#define CONFIG_CURVES_FILE "ldr_curves" #define CONFIG_CURVES_FILE "ldr_curves"
#define CONFIG_CURVES_PATH "./data" #define CONFIG_CURVES_PATH "./data"
@ -63,6 +38,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"
@ -72,5 +49,9 @@
#define CONFIG_NP_IDPS_CONST_KNAME "NP_idps_const" #define CONFIG_NP_IDPS_CONST_KNAME "NP_idps_const"
#define CONFIG_NP_RIF_KEY_KNAME "NP_rif_key" #define CONFIG_NP_RIF_KEY_KNAME "NP_rif_key"
#define CONFIG_NP_SIG_KNAME "NP_sig" #define CONFIG_NP_SIG_KNAME "NP_sig"
#define CONFIG_NP_RAP_INITIAL_KNAME "NP_rap_initial"
#define CONFIG_NP_RAP_PBOX_KNAME "NP_rap_pbox"
#define CONFIG_NP_RAP_E1_KNAME "NP_rap_e1"
#define CONFIG_NP_RAP_E2_KNAME "NP_rap_e2"
#endif #endif

View file

@ -73,7 +73,7 @@ static void elt_square(u8 *d, u8 *a)
elt_mul(d, a, a); elt_mul(d, a, a);
} }
static void elt_inv(u8 *d, u8 *a) void elt_inv(u8 *d, u8 *a)
{ {
u8 s[20]; u8 s[20];
elt_copy(s, a); elt_copy(s, a);
@ -314,12 +314,16 @@ static int check_ecdsa(struct point *Q, u8 *R, u8 *S, u8 *hash)
return (bn_compare(rr, R, 21) == 0); return (bn_compare(rr, R, 21) == 0);
} }
#if 0
static void ec_priv_to_pub(u8 *k, u8 *Q) void ec_priv_to_pub(u8 *k, u8 *Q)
{ {
point_mul(Q, k, ec_G); struct point mQ;
point_mul(&mQ, k, &ec_G);
point_from_mon(&mQ);
elt_copy(Q, mQ.x);
elt_copy(Q+20, mQ.y);
} }
#endif
int ecdsa_set_curve(u32 type) int ecdsa_set_curve(u32 type)
{ {
@ -355,3 +359,30 @@ void ecdsa_sign(u8 *hash, u8 *R, u8 *S)
{ {
generate_ecdsa(R, S, ec_k, hash); generate_ecdsa(R, S, ec_k, hash);
} }
void get_m (u8 *r, u8 *s, u8 *e, u8 *k, u8 *m)
{
u8 tmp_r[21], tmp_s[21], tmp_e[21], tmp_k[21];
u8 tmp_mul[21], tmp_sum[21], tmp_inv[21];
tmp_r[0] = tmp_s[0] = tmp_e[0] = 0;
bn_copy(tmp_r, r, 21);
bn_copy(tmp_s, s, 21);
bn_copy(tmp_e + 1, e, 20);
bn_reduce(tmp_e, ec_N, 21);
bn_to_mon(tmp_r, ec_N, 21);
bn_to_mon(tmp_s, ec_N, 21);
bn_to_mon(tmp_e, ec_N, 21);
tmp_k[0] = 0;
bn_copy(tmp_k, k, 21);
bn_reduce(tmp_k, ec_N, 21);
bn_to_mon(tmp_k, ec_N, 21);
bn_mon_mul(tmp_mul, tmp_r, tmp_k, ec_N, 21);
bn_add(tmp_sum, tmp_mul, tmp_e, ec_N, 21);
bn_mon_inv(tmp_inv, tmp_s, ec_N, 21);
bn_mon_mul(tmp_mul, tmp_inv, tmp_sum, ec_N, 21);
bn_from_mon(tmp_mul, ec_N, 21);
memcpy (m, tmp_mul + 1, 20);
}

View file

@ -6,5 +6,8 @@ void ecdsa_set_pub(u8 *Q);
void ecdsa_set_priv(u8 *k); void ecdsa_set_priv(u8 *k);
int ecdsa_verify(u8 *hash, u8 *R, u8 *S); int ecdsa_verify(u8 *hash, u8 *R, u8 *S);
void ecdsa_sign(u8 *hash, u8 *R, u8 *S); void ecdsa_sign(u8 *hash, u8 *R, u8 *S);
void ec_priv_to_pub(u8 *k, u8 *Q);
void elt_inv(u8 *d, u8 *a);
void get_m (u8 *r, u8 *s, u8 *e, u8 *k, u8 *m);
int ecdsa_get_params(u32 type, u8 *p, u8 *a, u8 *b, u8 *N, u8 *Gx, u8 *Gy);
#endif #endif

View file

@ -925,7 +925,7 @@ typedef struct
interpretation of the AUXV. Must be > 16. */ interpretation of the AUXV. Must be > 16. */
#define AT_IGNOREPPC 22 /* Entry should be ignored. */ #define AT_IGNOREPPC 22 /* Entry should be ignored. */
#define AT_SECURE 23 /* Boolean, was exec setuid-like? */ #define AT_SECURE 23 /* boolean, was exec setuid-like? */
/* Pointer to the global system page used for system calls and other /* Pointer to the global system page used for system calls and other
nice things. */ nice things. */
@ -1463,7 +1463,7 @@ typedef struct
#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */ #define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */
#define PT_MIPS_OPTIONS 0x70000002 #define PT_MIPS_OPTIONS 0x70000002
/* Special program header types. */ /* Special elf program header types. */
#define PF_MIPS_LOCAL 0x10000000 #define PF_MIPS_LOCAL 0x10000000

View file

@ -2,6 +2,7 @@
* Copyright (c) 2011-2013 by naehrwert * Copyright (c) 2011-2013 by naehrwert
* This file is released under the GPLv2. * This file is released under the GPLv2.
*/ */
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -30,29 +31,27 @@ extern s8 *_meta_info;
extern s8 *_keyset; extern s8 *_keyset;
extern s8 *_auth_id; extern s8 *_auth_id;
extern s8 *_vendor_id; extern s8 *_vendor_id;
extern s8 *_self_type; extern s8 *_program_type;
extern s8 *_app_version; extern s8 *_app_version;
extern s8 *_fw_version; extern s8 *_fw_version;
extern s8 *_add_shdrs; extern s8 *_add_shdrs;
extern s8 *_ctrl_flags; extern s8 *_ctrl_flags;
extern s8 *_cap_flags; extern s8 *_cap_flags;
#ifdef CONFIG_CUSTOM_INDIV_SEED
extern s8 *_indiv_seed; extern s8 *_indiv_seed;
#endif
extern s8 *_license_type; extern s8 *_license_type;
extern s8 *_app_type; extern s8 *_app_type;
extern s8 *_content_id; extern s8 *_content_id;
extern s8 *_real_fname; extern s8 *_real_fname;
extern s8 *_add_sig; extern s8 *_add_sig;
static BOOL _is_hexdigit(s8 c) static bool _is_hexdigit(s8 c)
{ {
if((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) if((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'))
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
static BOOL _is_hexnumber(const s8 *str) static bool _is_hexnumber(const s8 *str)
{ {
u32 i, len = strlen(str); u32 i, len = strlen(str);
for(i = 0; i < len; i++) for(i = 0; i < len; i++)
@ -61,7 +60,7 @@ static BOOL _is_hexnumber(const s8 *str)
return TRUE; return TRUE;
} }
static BOOL _fill_self_config_template(s8 *file, self_config_t *sconf) static bool _fill_self_config_template(s8 *file, self_config_t *sconf)
{ {
u8 *buf = _read_buffer(file, NULL); u8 *buf = _read_buffer(file, NULL);
if(buf != NULL) if(buf != NULL)
@ -74,16 +73,16 @@ static BOOL _fill_self_config_template(s8 *file, self_config_t *sconf)
_LOG_VERBOSE("Template header decrypted.\n"); _LOG_VERBOSE("Template header decrypted.\n");
_LOG_VERBOSE("Using:\n"); _LOG_VERBOSE("Using:\n");
sconf->key_revision = ctxt->sceh->key_revision; sconf->key_revision = _ES16(ctxt->cfh->key_revision);
_IF_VERBOSE(printf(" Key Revision 0x%04X\n", sconf->key_revision)); _IF_VERBOSE(printf(" Key Revision 0x%04X\n", sconf->key_revision));
sconf->auth_id = ctxt->self.ai->auth_id; sconf->auth_id = _ES64(ctxt->self.ai->auth_id);
_IF_VERBOSE(printf(" Auth-ID 0x%016llX\n", sconf->auth_id)); _IF_VERBOSE(printf(" Auth-ID 0x%016llX\n", sconf->auth_id));
sconf->vendor_id = ctxt->self.ai->vendor_id; sconf->vendor_id = _ES32(ctxt->self.ai->vendor_id);
_IF_VERBOSE(printf(" Vendor-ID 0x%08X\n", sconf->vendor_id)); _IF_VERBOSE(printf(" Vendor-ID 0x%08X\n", sconf->vendor_id));
sconf->self_type = ctxt->self.ai->self_type; sconf->program_type = _ES32(ctxt->self.ai->program_type);
_IF_VERBOSE(printf(" SELF-Type 0x%08X\n", sconf->self_type)); _IF_VERBOSE(printf(" Program-Type 0x%08X\n", sconf->program_type));
sconf->app_version = ctxt->self.ai->version; sconf->app_version = _ES64(ctxt->self.ai->version);
_IF_VERBOSE(printf(" APP Version 0x%016llX\n", sconf->app_version)); _IF_VERBOSE(printf(" APP-Version 0x%016llX\n", sconf->app_version));
control_info_t *ci = sce_get_ctrl_info(ctxt, CONTROL_INFO_TYPE_DIGEST); control_info_t *ci = sce_get_ctrl_info(ctxt, CONTROL_INFO_TYPE_DIGEST);
ci_data_digest_40_t *cid = (ci_data_digest_40_t *)((u8 *)ci + sizeof(control_info_t)); ci_data_digest_40_t *cid = (ci_data_digest_40_t *)((u8 *)ci + sizeof(control_info_t));
@ -100,16 +99,14 @@ static BOOL _fill_self_config_template(s8 *file, self_config_t *sconf)
sconf->cap_flags = (u8 *)_memdup(((u8 *)oh) + sizeof(opt_header_t), 0x20); sconf->cap_flags = (u8 *)_memdup(((u8 *)oh) + sizeof(opt_header_t), 0x20);
_IF_VERBOSE(_hexdump(stdout, " Capability Flags", 0, sconf->cap_flags, 0x20, 0)); _IF_VERBOSE(_hexdump(stdout, " Capability Flags", 0, sconf->cap_flags, 0x20, 0));
#ifdef CONFIG_CUSTOM_INDIV_SEED
sconf->indiv_seed = NULL; sconf->indiv_seed = NULL;
if(ctxt->self.ai->self_type == SELF_TYPE_ISO) if(_ES32(ctxt->self.ai->program_type) == PROGRAM_TYPE_ISO)
{ {
oh = sce_get_opt_header(ctxt, OPT_HEADER_TYPE_INDIV_SEED); oh = sce_get_opt_header(ctxt, OPT_HEADER_TYPE_INDIV_SEED);
sconf->indiv_seed = (u8 *)_memdup(((u8 *)oh) + sizeof(opt_header_t), oh->size - sizeof(opt_header_t)); sconf->indiv_seed = (u8 *)_memdup(((u8 *)oh) + sizeof(opt_header_t), _ES32(oh->size) - sizeof(opt_header_t));
sconf->indiv_seed_size = oh->size - sizeof(opt_header_t); sconf->indiv_seed_size = _ES32(oh->size) - sizeof(opt_header_t);
_IF_VERBOSE(_hexdump(stdout, " Individuals Seed", 0, sconf->indiv_seed, sconf->indiv_seed_size, 0)); _IF_VERBOSE(_hexdump(stdout, " Individuals Seed", 0, sconf->indiv_seed, sconf->indiv_seed_size, 0));
} }
#endif
sconf->add_shdrs = TRUE; sconf->add_shdrs = TRUE;
if(_add_shdrs != NULL) if(_add_shdrs != NULL)
@ -139,7 +136,7 @@ static BOOL _fill_self_config_template(s8 *file, self_config_t *sconf)
return FALSE; return FALSE;
} }
static BOOL _fill_self_config(self_config_t *sconf) static bool _fill_self_config(self_config_t *sconf)
{ {
if(_key_rev == NULL) if(_key_rev == NULL)
{ {
@ -151,7 +148,7 @@ static BOOL _fill_self_config(self_config_t *sconf)
printf("[*] Error (Key Revision): Please provide a valid hexadecimal number.\n"); printf("[*] Error (Key Revision): Please provide a valid hexadecimal number.\n");
return FALSE; return FALSE;
} }
sconf->key_revision = _x_to_u64(_key_rev); sconf->key_revision = (u16)_x_to_u64(_key_rev);
if(_auth_id == NULL) if(_auth_id == NULL)
{ {
@ -165,20 +162,20 @@ static BOOL _fill_self_config(self_config_t *sconf)
printf("[*] Error: Please specify a vendor ID.\n"); printf("[*] Error: Please specify a vendor ID.\n");
return FALSE; return FALSE;
} }
sconf->vendor_id = _x_to_u64(_vendor_id); sconf->vendor_id = (u32)_x_to_u64(_vendor_id);
if(_self_type == NULL) if(_program_type == NULL)
{ {
printf("[*] Error: Please specify a SELF type.\n"); printf("[*] Error: Please specify a program type.\n");
return FALSE; return FALSE;
} }
u64 type = _get_id(_self_types_params, _self_type); u64 type = _get_id(_program_types_params, _program_type);
if(type == (u64)(-1)) if(type == (u64)(-1))
{ {
printf("[*] Error: Invalid SELF type.\n"); printf("[*] Error: Invalid program type.\n");
return FALSE; return FALSE;
} }
sconf->self_type = type; sconf->program_type = (u32)type;
if(_app_version == NULL) if(_app_version == NULL)
{ {
@ -223,7 +220,6 @@ static BOOL _fill_self_config(self_config_t *sconf)
sconf->cap_flags = _x_to_u8_buffer(_cap_flags); sconf->cap_flags = _x_to_u8_buffer(_cap_flags);
} }
#ifdef CONFIG_CUSTOM_INDIV_SEED
sconf->indiv_seed = NULL; sconf->indiv_seed = NULL;
if(_indiv_seed != NULL) if(_indiv_seed != NULL)
{ {
@ -236,14 +232,13 @@ static BOOL _fill_self_config(self_config_t *sconf)
sconf->indiv_seed = _x_to_u8_buffer(_indiv_seed); sconf->indiv_seed = _x_to_u8_buffer(_indiv_seed);
sconf->indiv_seed_size = len / 2; sconf->indiv_seed_size = len / 2;
} }
#endif
sconf->npdrm_config = NULL; sconf->npdrm_config = NULL;
return TRUE; return TRUE;
} }
static BOOL _fill_npdrm_config(self_config_t *sconf) static bool _fill_npdrm_config(self_config_t *sconf)
{ {
if((sconf->npdrm_config = (npdrm_config_t *)malloc(sizeof(npdrm_config_t))) == NULL) if((sconf->npdrm_config = (npdrm_config_t *)malloc(sizeof(npdrm_config_t))) == NULL)
return FALSE; return FALSE;
@ -275,7 +270,7 @@ static BOOL _fill_npdrm_config(self_config_t *sconf)
printf("[*] Error: Invalid application type.\n"); printf("[*] Error: Invalid application type.\n");
return FALSE; return FALSE;
} }
sconf->npdrm_config->app_type = type; sconf->npdrm_config->app_type = (u32)type;
if(_content_id == NULL) if(_content_id == NULL)
{ {
@ -334,13 +329,22 @@ void frontend_print_infos(s8 *file)
} }
else else
printf("[*] Warning: Could not decrypt header.\n"); printf("[*] Warning: Could not decrypt header.\n");
sce_print_info(stdout, ctxt);
if(ctxt->sceh->header_type == SCE_HEADER_TYPE_SELF) cf_print_info(stdout, ctxt);
//sce_print_info(stdout, ctxt, keyset);
if(_ES16(ctxt->cfh->category) == CF_CATEGORY_SELF)
self_print_info(stdout, ctxt); self_print_info(stdout, ctxt);
else if(ctxt->sceh->header_type == SCE_HEADER_TYPE_RVK && ctxt->mdec == TRUE) else if(_ES16(ctxt->cfh->category) == CF_CATEGORY_RVK && ctxt->mdec == TRUE)
rvk_print(stdout, ctxt); rvk_print(stdout, ctxt);
else if(ctxt->sceh->header_type == SCE_HEADER_TYPE_SPP && ctxt->mdec == TRUE) else if(_ES16(ctxt->cfh->category) == CF_CATEGORY_SPP && ctxt->mdec == TRUE)
spp_print(stdout, ctxt); spp_print(stdout, ctxt);
sce_print_info(stdout, ctxt, keyset);
if(_ES16(ctxt->cfh->category) == CF_CATEGORY_SELF)
self_print_encrypted_info(stdout, ctxt);
if(ctxt->mdec == TRUE)
print_sce_signature_info(stdout, ctxt, keyset);
free(ctxt); free(ctxt);
} }
else else
@ -387,34 +391,34 @@ void frontend_decrypt(s8 *file_in, s8 *file_out)
if(sce_decrypt_data(ctxt)) if(sce_decrypt_data(ctxt))
{ {
_LOG_VERBOSE("Data decrypted.\n"); _LOG_VERBOSE("Data decrypted.\n");
if(ctxt->sceh->header_type == SCE_HEADER_TYPE_SELF) if(_ES16(ctxt->cfh->category) == CF_CATEGORY_SELF)
{ {
if(self_write_to_elf(ctxt, file_out) == TRUE) if(self_write_to_elf(ctxt, file_out) == TRUE)
printf("[*] ELF written to %s.\n", file_out); printf("[*] ELF written to %s.\n", file_out);
else else
printf("[*] Error: Could not write ELF.\n"); printf("[*] Error: Could not write ELF.\n");
} }
else if(ctxt->sceh->header_type == SCE_HEADER_TYPE_RVK) else if(_ES16(ctxt->cfh->category) == CF_CATEGORY_RVK)
{ {
if(_write_buffer(file_out, ctxt->scebuffer + ctxt->metash[0].data_offset, if(_write_buffer(file_out, ctxt->scebuffer + _ES64(ctxt->metash[0].data_offset),
ctxt->metash[0].data_size + ctxt->metash[1].data_size)) _ES64(ctxt->metash[0].data_size) + _ES64(ctxt->metash[1].data_size)))
printf("[*] RVK written to %s.\n", file_out); printf("[*] RVK written to %s.\n", file_out);
else else
printf("[*] Error: Could not write RVK.\n"); printf("[*] Error: Could not write RVK.\n");
} }
else if(ctxt->sceh->header_type == SCE_HEADER_TYPE_PKG) else if(_ES16(ctxt->cfh->category) == CF_CATEGORY_PKG)
{ {
/*if(_write_buffer(file_out, ctxt->scebuffer + ctxt->metash[0].data_offset, /*if(_write_buffer(file_out, ctxt->scebuffer + _ES64(ctxt->metash[0].data_offset),
ctxt->metash[0].data_size + ctxt->metash[1].data_size + ctxt->metash[2].data_size)) _ES64(ctxt->metash[0].data_size) + _ES64(ctxt->metash[1].data_size) + _ES64(ctxt->metash[2].data_size)))
printf("[*] PKG written to %s.\n", file_out); printf("[*] PKG written to %s.\n", file_out);
else else
printf("[*] Error: Could not write PKG.\n");*/ printf("[*] Error: Could not write PKG.\n");*/
printf("soon...\n"); printf("soon...\n");
} }
else if(ctxt->sceh->header_type == SCE_HEADER_TYPE_SPP) else if(_ES16(ctxt->cfh->category) == CF_CATEGORY_SPP)
{ {
if(_write_buffer(file_out, ctxt->scebuffer + ctxt->metash[0].data_offset, if(_write_buffer(file_out, ctxt->scebuffer + _ES64(ctxt->metash[0].data_offset),
ctxt->metash[0].data_size + ctxt->metash[1].data_size)) _ES64(ctxt->metash[0].data_size) + _ES64(ctxt->metash[1].data_size)))
printf("[*] SPP written to %s.\n", file_out); printf("[*] SPP written to %s.\n", file_out);
else else
printf("[*] Error: Could not write SPP.\n"); printf("[*] Error: Could not write SPP.\n");
@ -437,7 +441,7 @@ void frontend_decrypt(s8 *file_in, s8 *file_out)
void frontend_encrypt(s8 *file_in, s8 *file_out) void frontend_encrypt(s8 *file_in, s8 *file_out)
{ {
BOOL can_compress = FALSE; bool can_compress = FALSE;
self_config_t sconf; self_config_t sconf;
sce_buffer_ctxt_t *ctxt; sce_buffer_ctxt_t *ctxt;
u32 file_len = 0; u32 file_len = 0;
@ -468,7 +472,7 @@ void frontend_encrypt(s8 *file_in, s8 *file_out)
if(strcmp(_file_type, "SELF") == 0) if(strcmp(_file_type, "SELF") == 0)
{ {
if(_self_type == NULL && _template == NULL) if(_program_type == NULL && _template == NULL)
{ {
printf("[*] Error: Please specify a SELF type.\n"); printf("[*] Error: Please specify a SELF type.\n");
return; return;
@ -487,7 +491,7 @@ void frontend_encrypt(s8 *file_in, s8 *file_out)
return; return;
} }
if(sconf.self_type == SELF_TYPE_NPDRM) if(sconf.program_type == PROGRAM_TYPE_NPDRM)
if(_fill_npdrm_config(&sconf) == FALSE) if(_fill_npdrm_config(&sconf) == FALSE)
return; return;
@ -501,7 +505,7 @@ void frontend_encrypt(s8 *file_in, s8 *file_out)
} }
//SPU SELFs may not be compressed. //SPU SELFs may not be compressed.
if(!(sconf.self_type == SELF_TYPE_LDR || sconf.self_type == SELF_TYPE_ISO)) if(!(sconf.program_type == PROGRAM_TYPE_LDR || sconf.program_type == PROGRAM_TYPE_ISO))
can_compress = TRUE; can_compress = TRUE;
} }
else if(strcmp(_file_type, "RVK") == 0) else if(strcmp(_file_type, "RVK") == 0)
@ -547,7 +551,7 @@ void frontend_encrypt(s8 *file_in, s8 *file_out)
{ {
printf("[*] %s written.\n", file_out); printf("[*] %s written.\n", file_out);
//Add NPDRM footer signature. //Add NPDRM footer signature.
if(sconf.self_type == SELF_TYPE_NPDRM && _add_sig != NULL && strcmp(_add_sig, "TRUE") == 0) if(sconf.program_type == PROGRAM_TYPE_NPDRM && _add_sig != NULL && strcmp(_add_sig, "TRUE") == 0)
{ {
if(np_sign_file(file_out) == TRUE) if(np_sign_file(file_out) == TRUE)
printf("[*] Added NPDRM footer signature.\n"); printf("[*] Added NPDRM footer signature.\n");

View file

@ -45,7 +45,6 @@ EXPRESSLY ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
#if defined(EXPORTS_GETOPT) && defined(STATIC_GETOPT) #if defined(EXPORTS_GETOPT) && defined(STATIC_GETOPT)
#error "The preprocessor definitions of EXPORTS_GETOPT and STATIC_GETOPT can only be used individually" #error "The preprocessor definitions of EXPORTS_GETOPT and STATIC_GETOPT can only be used individually"
#elif defined(STATIC_GETOPT) #elif defined(STATIC_GETOPT)
#pragma message("Warning static builds of getopt violate the Lesser GNU Public License")
#define _GETOPT_API #define _GETOPT_API
#elif defined(EXPORTS_GETOPT) #elif defined(EXPORTS_GETOPT)
#pragma message("Exporting getopt library") #pragma message("Exporting getopt library")

1090
src/keys.cpp Normal file

File diff suppressed because it is too large Load diff

View file

@ -11,11 +11,11 @@
#define KEYBITS(klen) BYTES2BITS(klen) #define KEYBITS(klen) BYTES2BITS(klen)
#define KEYTYPE_SELF 1 #define KEYCATEGORY_SELF 1
#define KEYTYPE_RVK 2 #define KEYCATEGORY_RVK 2
#define KEYTYPE_PKG 3 #define KEYCATEGORY_PKG 3
#define KEYTYPE_SPP 4 #define KEYCATEGORY_SPP 4
#define KEYTYPE_OTHER 5 #define KEYCATEGORY_OTHER 5
/*! Flag to use VSH curve. */ /*! Flag to use VSH curve. */
#define USE_VSH_CURVE 0x40 #define USE_VSH_CURVE 0x40
@ -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
@ -47,14 +48,14 @@ typedef struct _keyset
{ {
/*! Name. */ /*! Name. */
s8 *name; s8 *name;
/*! Type. */ /*! Category. */
u32 type; u32 category;
/*! Key revision. */ /*! Key revision. */
u16 key_revision; u16 key_revision;
/*! Version. */ /*! Version. */
u64 version; u64 version;
/*! SELF type. */ /*! Program type. */
u32 self_type; u32 program_type;
/*! Key length. */ /*! Key length. */
u32 erklen; u32 erklen;
/*! Key. */ /*! Key. */
@ -85,10 +86,10 @@ typedef struct _curve
/*! VSH Curve entry. */ /*! VSH Curve entry. */
typedef struct _vsh_curve typedef struct _vsh_curve
{ {
u8 p[20];
u8 a[20]; u8 a[20];
u8 b[20]; u8 b[20];
u8 N[20]; u8 N[20];
u8 p[20];
u8 Gx[20]; u8 Gx[20];
u8 Gy[20]; u8 Gy[20];
} vsh_curve_t; } vsh_curve_t;
@ -115,19 +116,24 @@ typedef struct _rif
} rif_t; } rif_t;
void _print_key_list(FILE *fp); void _print_key_list(FILE *fp);
void _print_internal_key_list(FILE *fp);
BOOL keys_load(const s8 *kfile); bool keys_load(const s8 *kfile);
bool internal_keys_load(const s8 *kfile);
keyset_t *keyset_find(sce_buffer_ctxt_t *ctxt); keyset_t *keyset_find(sce_buffer_ctxt_t *ctxt);
keyset_t *keyset_bruteforce(sce_buffer_ctxt_t *ctxt);
keyset_t *keyset_find_by_name(const s8 *name); keyset_t *keyset_find_by_name(const s8 *name);
BOOL curves_load(const s8 *cfile); bool curves_load(const s8 *cfile);
curve_t *curve_find(u8 ctype); curve_t *curve_find(u8 ctype);
BOOL vsh_curves_load(const s8 *cfile); 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);
keyset_t *get_used_keyset();
#endif #endif

View file

@ -38,7 +38,7 @@ void list_destroy(list_t *l)
free(l); free(l);
} }
BOOL list_isempty(list_t *l) bool list_isempty(list_t *l)
{ {
if(l == NULL) if(l == NULL)
return FALSE; return FALSE;
@ -56,7 +56,7 @@ u32 list_count(list_t *l)
return l->count; return l->count;
} }
BOOL list_push(list_t *l, void *value) bool list_push(list_t *l, void *value)
{ {
if(l == NULL) if(l == NULL)
return FALSE; return FALSE;
@ -96,7 +96,7 @@ void *list_pop(list_t *l)
return res; return res;
} }
BOOL list_add_back(list_t *l, void *value) bool list_add_back(list_t *l, void *value)
{ {
if(l == NULL) if(l == NULL)
return FALSE; return FALSE;
@ -155,7 +155,7 @@ lnode_t *list_get_node(list_t *l, u32 idx)
return iter; return iter;
} }
BOOL list_remove_node(list_t *l, lnode_t *node) bool list_remove_node(list_t *l, lnode_t *node)
{ {
if(l == NULL) if(l == NULL)
return FALSE; return FALSE;
@ -188,7 +188,7 @@ BOOL list_remove_node(list_t *l, lnode_t *node)
return FALSE; return FALSE;
} }
BOOL list_remove_value(list_t *l, void *value) bool list_remove_value(list_t *l, void *value)
{ {
if(l == NULL) if(l == NULL)
return FALSE; return FALSE;

View file

@ -24,14 +24,14 @@ typedef struct _list
list_t *list_create(); list_t *list_create();
void list_destroy(list_t *l); void list_destroy(list_t *l);
BOOL list_isempty(list_t *l); bool list_isempty(list_t *l);
u32 list_count(list_t *l); u32 list_count(list_t *l);
BOOL list_push(list_t *l, void *value); bool list_push(list_t *l, void *value);
void *list_pop(list_t *l); void *list_pop(list_t *l);
BOOL list_add_back(list_t *l, void *value); bool list_add_back(list_t *l, void *value);
void *list_get(list_t *l, u32 idx); void *list_get(list_t *l, u32 idx);
lnode_t *list_get_node(list_t *l, u32 idx); lnode_t *list_get_node(list_t *l, u32 idx);
BOOL list_remove_node(list_t *l, lnode_t *node); bool list_remove_node(list_t *l, lnode_t *node);
BOOL list_remove_value(list_t *l, void *value); bool list_remove_value(list_t *l, void *value);
#endif #endif

View file

@ -2,6 +2,7 @@
* Copyright (c) 2011-2013 by naehrwert * Copyright (c) 2011-2013 by naehrwert
* This file is released under the GPLv2. * This file is released under the GPLv2.
*/ */
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -36,20 +37,20 @@
#define ARG_OPT optional_argument #define ARG_OPT optional_argument
/*! Verbose mode. */ /*! Verbose mode. */
BOOL _verbose = FALSE; bool _verbose = FALSE;
/*! Raw mode. */ /*! Raw mode. */
BOOL _raw = FALSE; bool _raw = FALSE;
/*! We got work. */ /*! We got work. */
static BOOL _got_work = FALSE; static bool _got_work = FALSE;
/*! List keys. */ /*! List keys. */
static BOOL _list_keys = FALSE; static bool _list_keys = FALSE;
/*! Print infos on file. */ /*! Print infos on file. */
static BOOL _print_info = FALSE; static bool _print_info = FALSE;
/*! Decrypt file. */ /*! Decrypt file. */
static BOOL _decrypt_file = FALSE; static bool _decrypt_file = FALSE;
/*! Encrypt file. */ /*! Encrypt file. */
static BOOL _encrypt_file = FALSE; static bool _encrypt_file = FALSE;
/*! Parameters. */ /*! Parameters. */
s8 *_template = NULL; s8 *_template = NULL;
@ -61,15 +62,13 @@ s8 *_meta_info = NULL;
s8 *_keyset = NULL; s8 *_keyset = NULL;
s8 *_auth_id = NULL; s8 *_auth_id = NULL;
s8 *_vendor_id = NULL; s8 *_vendor_id = NULL;
s8 *_self_type = NULL; s8 *_program_type = NULL;
s8 *_app_version = NULL; s8 *_app_version = NULL;
s8 *_fw_version = NULL; s8 *_fw_version = NULL;
s8 *_add_shdrs = NULL; s8 *_add_shdrs = NULL;
s8 *_ctrl_flags = NULL; s8 *_ctrl_flags = NULL;
s8 *_cap_flags = NULL; s8 *_cap_flags = NULL;
#ifdef CONFIG_CUSTOM_INDIV_SEED
s8 *_indiv_seed = NULL; s8 *_indiv_seed = NULL;
#endif
s8 *_license_type = NULL; s8 *_license_type = NULL;
s8 *_app_type = NULL; s8 *_app_type = NULL;
s8 *_content_id = NULL; s8 *_content_id = NULL;
@ -84,7 +83,7 @@ static s8 *_file_out = NULL;
/*! Long option values. */ /*! Long option values. */
#define VAL_TEMPLATE 't' #define VAL_TEMPLATE 't'
#define VAL_FILE_TYPE '0' #define VAL_FILE_CATEGORY '0'
#define VAL_COMPRESS_DATA '1' #define VAL_COMPRESS_DATA '1'
#define VAL_SKIP_SECTIONS 's' #define VAL_SKIP_SECTIONS 's'
#define VAL_KEY_REV '2' #define VAL_KEY_REV '2'
@ -92,15 +91,13 @@ static s8 *_file_out = NULL;
#define VAL_KEYSET 'K' #define VAL_KEYSET 'K'
#define VAL_AUTH_ID '3' #define VAL_AUTH_ID '3'
#define VAL_VENDOR_ID '4' #define VAL_VENDOR_ID '4'
#define VAL_SELF_TYPE '5' #define VAL_PROGRAM_TYPE '5'
#define VAL_APP_VERSION 'A' #define VAL_APP_VERSION 'A'
#define VAL_FW_VERSION '6' #define VAL_FW_VERSION '6'
#define VAL_ADD_SHDRS '7' #define VAL_ADD_SHDRS '7'
#define VAL_CTRL_FLAGS '8' #define VAL_CTRL_FLAGS '8'
#define VAL_CAP_FLAGS '9' #define VAL_CAP_FLAGS '9'
#ifdef CONFIG_CUSTOM_INDIV_SEED
#define VAL_INDIV_SEED 'a' #define VAL_INDIV_SEED 'a'
#endif
#define VAL_LICENSE_TYPE 'b' #define VAL_LICENSE_TYPE 'b'
#define VAL_APP_TYPE 'c' #define VAL_APP_TYPE 'c'
#define VAL_CONTENT_ID 'f' #define VAL_CONTENT_ID 'f'
@ -118,23 +115,21 @@ static struct option options[] =
{"verbose", ARG_NONE, NULL, 'v'}, {"verbose", ARG_NONE, NULL, 'v'},
{"raw", ARG_NONE, NULL, 'r'}, {"raw", ARG_NONE, NULL, 'r'},
{"template", ARG_REQ, NULL, VAL_TEMPLATE}, {"template", ARG_REQ, NULL, VAL_TEMPLATE},
{"sce-type", ARG_REQ, NULL, VAL_FILE_TYPE}, {"category", ARG_REQ, NULL, VAL_FILE_CATEGORY},
{"compress-data", ARG_REQ, NULL, VAL_COMPRESS_DATA}, {"compress-data", ARG_REQ, NULL, VAL_COMPRESS_DATA},
{"skip-sections", ARG_REQ, NULL, VAL_SKIP_SECTIONS}, {"skip-sections", ARG_REQ, NULL, VAL_SKIP_SECTIONS},
{"key-revision", ARG_REQ, NULL, VAL_KEY_REV}, {"key-revision", ARG_REQ, NULL, VAL_KEY_REV},
{"meta-info", ARG_REQ, NULL, VAL_META_INFO}, {"meta-info", ARG_REQ, NULL, VAL_META_INFO},
{"keyset", ARG_REQ, NULL, VAL_KEYSET}, {"keyset", ARG_REQ, NULL, VAL_KEYSET},
{"self-auth-id", ARG_REQ, NULL, VAL_AUTH_ID}, {"program-auth-id", ARG_REQ, NULL, VAL_AUTH_ID},
{"self-vendor-id", ARG_REQ, NULL, VAL_VENDOR_ID}, {"program-vendor-id", ARG_REQ, NULL, VAL_VENDOR_ID},
{"self-type", ARG_REQ, NULL, VAL_SELF_TYPE}, {"program-type", ARG_REQ, NULL, VAL_PROGRAM_TYPE},
{"self-app-version", ARG_REQ, NULL, VAL_APP_VERSION}, {"self-app-version", ARG_REQ, NULL, VAL_APP_VERSION},
{"self-fw-version", ARG_REQ, NULL, VAL_FW_VERSION}, {"self-fw-version", ARG_REQ, NULL, VAL_FW_VERSION},
{"self-add-shdrs", ARG_REQ, NULL, VAL_ADD_SHDRS}, {"self-add-shdrs", ARG_REQ, NULL, VAL_ADD_SHDRS},
{"self-ctrl-flags", ARG_REQ, NULL, VAL_CTRL_FLAGS}, {"self-ctrl-flags", ARG_REQ, NULL, VAL_CTRL_FLAGS},
{"self-cap-flags", ARG_REQ, NULL, VAL_CAP_FLAGS}, {"self-cap-flags", ARG_REQ, NULL, VAL_CAP_FLAGS},
#ifdef CONFIG_CUSTOM_INDIV_SEED
{"self-indiv-seed", ARG_REQ, NULL, VAL_INDIV_SEED}, {"self-indiv-seed", ARG_REQ, NULL, VAL_INDIV_SEED},
#endif
{"np-license-type", ARG_REQ, NULL, VAL_LICENSE_TYPE}, {"np-license-type", ARG_REQ, NULL, VAL_LICENSE_TYPE},
{"np-app-type", ARG_REQ, NULL, VAL_APP_TYPE}, {"np-app-type", ARG_REQ, NULL, VAL_APP_TYPE},
{"np-content-id", ARG_REQ, NULL, VAL_CONTENT_ID}, {"np-content-id", ARG_REQ, NULL, VAL_CONTENT_ID},
@ -168,25 +163,23 @@ static void print_usage()
printf(" -v, --verbose Enable verbose output.\n"); printf(" -v, --verbose Enable verbose output.\n");
printf(" -r, --raw Enable raw value output.\n"); printf(" -r, --raw Enable raw value output.\n");
printf(" -t, --template File-in Template file (SELF only)\n"); printf(" -t, --template File-in Template file (SELF only)\n");
printf(" -0, --sce-type SELF/RVK/PKG/SPP SCE File Type\n"); printf(" -0, --category SELF/RVK/PKG/SPP SCE File Type\n");
printf(" -1, --compress-data TRUE/FALSE(default) Whether to compress data or not.\n"); printf(" -1, --compress-data TRUE/FALSE(default) Whether to compress data or not.\n");
printf(" -s, --skip-sections TRUE(default)/FALSE Whether to skip sections or not.\n"); printf(" -s, --skip-sections TRUE(default)/FALSE Whether to skip sections or not.\n");
printf(" -2, --key-revision e.g. 00,01,...,0A,... Key Revision\n"); printf(" -2, --key-revision e.g. 00,01,...,0A,... Key Revision\n");
printf(" -m, --meta-info 64 bytes Use provided meta info to decrypt.\n"); printf(" -m, --meta-info 64 bytes Use provided meta info to decrypt.\n");
printf(" -K, --keyset 32(Key)16(IV)\n"); printf(" -K, --keyset 32(Key)16(IV)\n");
printf(" 40(Pub)21(Priv)1(CT) Override keyset.\n"); printf(" 40(Pub)21(Priv)1(CT) Override keyset.\n");
printf(" -3, --self-auth-id e.g. 1010000001000003 Authentication ID\n"); printf(" -3, --program-auth-id e.g. 1010000001000003 Authentication ID\n");
printf(" -4, --self-vendor-id e.g. 01000002 Vendor ID\n"); printf(" -4, --program-vendor-id e.g. 01000002 Vendor ID\n");
printf(" -5, --self-type LV0/LV1/LV2/APP/ISO/\n"); printf(" -5, --program-type LV0/LV1/LV2/APP/ISO/\n");
printf(" LDR/NPDRM SELF Type\n"); printf(" LDR/NPDRM Program Type\n");
printf(" -A, --self-app-version e.g. 0001000000000000 Application Version\n"); printf(" -A, --self-app-version e.g. 0001000000000000 Application Version\n");
printf(" -6, --self-fw-version e.g. 0003004100000000 Firmware Version\n"); printf(" -6, --self-fw-version e.g. 0003004100000000 Firmware Version\n");
printf(" -7, --self-add-shdrs TRUE(default)/FALSE Whether to add ELF shdrs or not.\n"); printf(" -7, --self-add-shdrs TRUE(default)/FALSE Whether to add ELF shdrs or not.\n");
printf(" -8, --self-ctrl-flags 32 bytes Override control flags.\n"); printf(" -8, --self-ctrl-flags 32 bytes Override control flags.\n");
printf(" -9, --self-cap-flags 32 bytes Override capability flags.\n"); printf(" -9, --self-cap-flags 32 bytes Override capability flags.\n");
#ifdef CONFIG_CUSTOM_INDIV_SEED
printf(" -a, --self-indiv-seed 256 bytes Individuals Seed (ISO only)\n"); printf(" -a, --self-indiv-seed 256 bytes Individuals Seed (ISO only)\n");
#endif
printf(" -b, --np-license-type LOCAL/FREE License Type\n"); printf(" -b, --np-license-type LOCAL/FREE License Type\n");
printf(" -c, --np-app-type SPRX/EXEC/USPRX/UEXEC App Type (U* for updates)\n"); printf(" -c, --np-app-type SPRX/EXEC/USPRX/UEXEC App Type (U* for updates)\n");
printf(" -f, --np-content-id Content ID\n"); printf(" -f, --np-content-id Content ID\n");
@ -203,11 +196,7 @@ static void parse_args(int argc, char **argv)
{ {
char c; char c;
#ifdef CONFIG_CUSTOM_INDIV_SEED
while((c = getopt_long(argc, argv, "hki:d:e:vrt:0:1:s:2:m:K:3:4:5:A:6:7:8:9:a:b:c:f:l:g:j:", options, NULL)) != -1) while((c = getopt_long(argc, argv, "hki:d:e:vrt:0:1:s:2:m:K:3:4:5:A:6:7:8:9:a:b:c:f:l:g:j:", options, NULL)) != -1)
#else
while((c = getopt_long(argc, argv, "hki:d:e:vrt:0:1:s:2:m:K:3:4:5:A:6:7:8:9:b:c:f:l:g:j:", options, NULL)) != -1)
#endif
{ {
switch(c) switch(c)
{ {
@ -250,7 +239,7 @@ static void parse_args(int argc, char **argv)
case VAL_TEMPLATE: case VAL_TEMPLATE:
_template = optarg; _template = optarg;
break; break;
case VAL_FILE_TYPE: case VAL_FILE_CATEGORY:
_file_type = optarg; _file_type = optarg;
break; break;
case VAL_COMPRESS_DATA: case VAL_COMPRESS_DATA:
@ -274,8 +263,8 @@ static void parse_args(int argc, char **argv)
case VAL_VENDOR_ID: case VAL_VENDOR_ID:
_vendor_id = optarg; _vendor_id = optarg;
break; break;
case VAL_SELF_TYPE: case VAL_PROGRAM_TYPE:
_self_type = optarg; _program_type = optarg;
break; break;
case VAL_APP_VERSION: case VAL_APP_VERSION:
_app_version = optarg; _app_version = optarg;
@ -292,11 +281,9 @@ static void parse_args(int argc, char **argv)
case VAL_CAP_FLAGS: case VAL_CAP_FLAGS:
_cap_flags = optarg; _cap_flags = optarg;
break; break;
#ifdef CONFIG_CUSTOM_INDIV_SEED
case VAL_INDIV_SEED: case VAL_INDIV_SEED:
_indiv_seed = optarg; _indiv_seed = optarg;
break; break;
#endif
case VAL_LICENSE_TYPE: case VAL_LICENSE_TYPE:
_license_type = optarg; _license_type = optarg;
break; break;
@ -348,7 +335,6 @@ static void parse_args(int argc, char **argv)
} }
} }
#ifndef _DEBUG
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
s8 *ps3 = NULL, path[256]; s8 *ps3 = NULL, path[256];
@ -378,6 +364,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);
@ -394,12 +382,39 @@ int main(int argc, char **argv)
printf("[*] Warning: Could not load keys.\n"); printf("[*] Warning: Could not load keys.\n");
} }
//Load curves. //Load internal keysets.
if(ps3 != NULL)
{
sprintf(path, "%s/%s", ps3, CONFIG_INTERNAL_KEYS_FILE);
if(access(path, 0) != 0)
sprintf(path, "%s/%s", CONFIG_KEYS_PATH, CONFIG_INTERNAL_KEYS_FILE);
if(access(path, 0) != 0)
sprintf(path, "%s/%s/%s", ps3, CONFIG_KEYS_PATH, CONFIG_INTERNAL_KEYS_FILE);
}
else
sprintf(path, "%s/%s", CONFIG_KEYS_PATH, CONFIG_INTERNAL_KEYS_FILE);
if(internal_keys_load(path) == TRUE)
_LOG_VERBOSE("Loaded internal keysets.\n");
else
{
if(_list_keys == TRUE)
{
printf("[*] Error: Could not load internal keys.\n");
return 0;
}
else
printf("[*] Warning: Could not load internal keys.\n");
}
//Load loader curves.
if(ps3 != NULL) if(ps3 != NULL)
{ {
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);
@ -408,12 +423,14 @@ int main(int argc, char **argv)
else else
printf("[*] Warning: Could not load loader curves.\n"); printf("[*] Warning: Could not load loader curves.\n");
//Load curves. //Load vsh curves.
if(ps3 != NULL) if(ps3 != NULL)
{ {
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);
@ -437,6 +454,8 @@ int main(int argc, char **argv)
{ {
printf("[*] Loaded keysets:\n"); printf("[*] Loaded keysets:\n");
_print_key_list(stdout); _print_key_list(stdout);
printf("[*] Loaded internal keysets:\n");
_print_internal_key_list(stdout);
} }
else if(_print_info) else if(_print_info)
frontend_print_infos(_file_in); frontend_print_infos(_file_in);
@ -447,4 +466,4 @@ int main(int argc, char **argv)
return 0; return 0;
} }
#endif

View file

@ -3,6 +3,7 @@
* Copyright (c) 2012 by flatz * Copyright (c) 2012 by flatz
* This file is released under the GPLv2. * This file is released under the GPLv2.
*/ */
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h> #include <stdlib.h>
@ -30,11 +31,9 @@ static ci_data_npdrm_t *_sce_find_ci_npdrm(sce_buffer_ctxt_t *ctxt)
{ {
control_info_t *ci = (control_info_t *)iter->value; control_info_t *ci = (control_info_t *)iter->value;
if(ci->type == CONTROL_INFO_TYPE_NPDRM) if(_ES32(ci->type) == CONTROL_INFO_TYPE_NPDRM)
{ {
ci_data_npdrm_t *np = (ci_data_npdrm_t *)((u8 *)ci + sizeof(control_info_t)); ci_data_npdrm_t *np = (ci_data_npdrm_t *)((u8 *)ci + sizeof(control_info_t));
//Fixup.
_es_ci_data_npdrm(np);
return np; return np;
} }
} }
@ -48,13 +47,15 @@ void np_set_klicensee(u8 *klicensee)
_klicensee_key = klicensee; _klicensee_key = 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;
@ -65,14 +66,28 @@ BOOL np_decrypt_npdrm(sce_buffer_ctxt_t *ctxt)
return FALSE; return FALSE;
if(_klicensee_key != NULL) if(_klicensee_key != NULL)
memcpy(npdrm_key, _klicensee_key, 0x10); memcpy(npdrm_key, _klicensee_key, 0x10);
else if(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;
//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); memcpy(npdrm_key, ks_np_klic_free->erk, 0x10);
} }
else if(np->license_type == NP_LICENSE_LOCAL) else if(_ES32(np->license_type) == NP_LICENSE_LOCAL || _ES32(np->license_type) == NP_LICENSE_NETWORK )
{ {
if ((klicensee_by_content_id((s8 *)np->content_id, npdrm_key)) == FALSE) if ((klicensee_by_content_id((s8 *)np->content_id, npdrm_key)) == FALSE)
return FALSE; return FALSE;
@ -80,6 +95,11 @@ BOOL np_decrypt_npdrm(sce_buffer_ctxt_t *ctxt)
else else
return FALSE; return FALSE;
if(_raw == TRUE)
{
_hexdump(stdout, "[*] Klicensee:", 0, npdrm_key, sizeof(npdrm_key), FALSE);
}
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);
@ -90,7 +110,7 @@ BOOL np_decrypt_npdrm(sce_buffer_ctxt_t *ctxt)
return TRUE; return TRUE;
} }
BOOL np_encrypt_npdrm(sce_buffer_ctxt_t *ctxt) bool np_encrypt_npdrm(sce_buffer_ctxt_t *ctxt)
{ {
aes_context aes_ctxt; aes_context aes_ctxt;
keyset_t *ks_np_klic_free, *ks_klic_key; keyset_t *ks_np_klic_free, *ks_klic_key;
@ -107,14 +127,14 @@ BOOL np_encrypt_npdrm(sce_buffer_ctxt_t *ctxt)
return FALSE; return FALSE;
if(_klicensee_key != NULL) if(_klicensee_key != NULL)
memcpy(npdrm_key, _klicensee_key, 0x10); memcpy(npdrm_key, _klicensee_key, 0x10);
else if(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) if(ks_np_klic_free == NULL)
return FALSE; return FALSE;
memcpy(npdrm_key, ks_np_klic_free->erk, 0x10); memcpy(npdrm_key, ks_np_klic_free->erk, 0x10);
} }
else if(np->license_type == NP_LICENSE_LOCAL) else if(_ES32(np->license_type) == NP_LICENSE_LOCAL)
{ {
if ((klicensee_by_content_id((s8 *)np->content_id, npdrm_key)) == FALSE) if ((klicensee_by_content_id((s8 *)np->content_id, npdrm_key)) == FALSE)
return FALSE; return FALSE;
@ -132,7 +152,7 @@ BOOL np_encrypt_npdrm(sce_buffer_ctxt_t *ctxt)
return TRUE; return TRUE;
} }
BOOL np_create_ci(npdrm_config_t *npconf, ci_data_npdrm_t *cinp) bool np_create_ci(npdrm_config_t *npconf, ci_data_npdrm_t *cinp)
{ {
u32 i, len; u32 i, len;
u8 *cid_fname, ci_key[0x10]; u8 *cid_fname, ci_key[0x10];
@ -145,7 +165,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)
@ -163,22 +183,14 @@ BOOL np_create_ci(npdrm_config_t *npconf, ci_data_npdrm_t *cinp)
else else
return FALSE; return FALSE;
cinp->magic = NP_CI_MAGIC; cinp->magic = _ES32(NP_CI_MAGIC);
cinp->unknown_0 = 1; cinp->version = _ES32(1);
cinp->license_type = npconf->license_type; cinp->license_type = _ES32(npconf->license_type);
cinp->app_type = npconf->app_type; cinp->app_type = _ES32(npconf->app_type);
memcpy(cinp->content_id, npconf->content_id, 0x30); memcpy(cinp->content_id, npconf->content_id, 0x30);
#ifdef CONFIG_PRIVATE_BUILD
_fill_rand_bytes(cinp->rndpad, 0x10); _fill_rand_bytes(cinp->rndpad, 0x10);
#else cinp->limited_time_start = _ES64(0);
//Better than boring random bytes! cinp->limited_time_end = _ES64(0);
memcpy(cinp->rndpad, CONFIG_NPDRM_WATERMARK, 0x10);
#endif
cinp->unknown_1 = 0;
cinp->unknown_2 = 0;
//Fixup before hashing.
_es_ci_data_npdrm(cinp);
//Generate control info hash key. //Generate control info hash key.
for(i = 0; i < 0x10; i++) for(i = 0; i < 0x10; i++)
@ -199,7 +211,7 @@ BOOL np_create_ci(npdrm_config_t *npconf, ci_data_npdrm_t *cinp)
//TODO: The fwrite/fread error checking was broken. //TODO: The fwrite/fread error checking was broken.
//Maybe the MS runtime is returning the number of bytes written instead of the element count? //Maybe the MS runtime is returning the number of bytes written instead of the element count?
BOOL np_sign_file(s8 *fname) bool np_sign_file(s8 *fname)
{ {
u8 padding_data[0x10] = u8 padding_data[0x10] =
{ {

View file

@ -28,15 +28,15 @@ typedef struct _npdrm_config
void np_set_klicensee(u8 *klicensee); void np_set_klicensee(u8 *klicensee);
/*! Remove NPDRM layer. */ /*! Remove NPDRM layer. */
BOOL np_decrypt_npdrm(sce_buffer_ctxt_t *ctxt); bool np_decrypt_npdrm(sce_buffer_ctxt_t *ctxt);
/*! Add NPDRM layer. */ /*! Add NPDRM layer. */
BOOL np_encrypt_npdrm(sce_buffer_ctxt_t *ctxt); bool np_encrypt_npdrm(sce_buffer_ctxt_t *ctxt);
/*! Create NPDRM control info. */ /*! Create NPDRM control info. */
BOOL np_create_ci(npdrm_config_t *npconf, ci_data_npdrm_t *cinp); bool np_create_ci(npdrm_config_t *npconf, ci_data_npdrm_t *cinp);
/*! Add NP signature to file. */ /*! Add NP signature to file. */
BOOL np_sign_file(s8 *fname); bool np_sign_file(s8 *fname);
#endif #endif

View file

View file

@ -28,7 +28,7 @@ static void _print_rvk_header(FILE *fp, rvk_header_t *h)
/* /*
typedef struct _prg_rvk_entry typedef struct _prg_rvk_entry
{ {
u32 self_type; //3, 4 u32 program_type; //3, 4
u32 unk_1; //1, 3 u32 unk_1; //1, 3
union union
{ {
@ -65,11 +65,11 @@ static void _print_prg_rvk_entry(FILE *fp, prg_rvk_entry_t *e)
{ {
const s8 *name; const s8 *name;
name = _get_name(_self_types, e->self_type); name = _get_name(_program_types, e->program_type);
if(name != NULL) if(name != NULL)
fprintf(fp, " %-19s ", name); fprintf(fp, " %-19s ", name);
else else
fprintf(fp, " 0x%08X ", e->self_type); fprintf(fp, " 0x%08X ", e->program_type);
name = _get_name(_check_type_values, e->check_type); name = _get_name(_check_type_values, e->check_type);
if(name != NULL) if(name != NULL)
@ -94,7 +94,7 @@ void rvk_print(FILE *fp, sce_buffer_ctxt_t *ctxt)
{ {
u32 i; u32 i;
rvk_header_t *rvkh = (rvk_header_t *)(ctxt->scebuffer + ctxt->metash[0].data_offset); rvk_header_t *rvkh = (rvk_header_t *)(ctxt->scebuffer + _ES64(ctxt->metash[0].data_offset));
_es_rvk_header(rvkh); _es_rvk_header(rvkh);
_print_rvk_header(fp, rvkh); _print_rvk_header(fp, rvkh);
@ -102,7 +102,7 @@ void rvk_print(FILE *fp, sce_buffer_ctxt_t *ctxt)
//Program revoke. //Program revoke.
if(rvkh->type_0 == 4) if(rvkh->type_0 == 4)
{ {
prg_rvk_entry_t *ent = (prg_rvk_entry_t *)(ctxt->scebuffer + ctxt->metash[1].data_offset); prg_rvk_entry_t *ent = (prg_rvk_entry_t *)(ctxt->scebuffer + _ES64(ctxt->metash[1].data_offset));
_print_prg_rvk_entry_header(fp); _print_prg_rvk_entry_header(fp);
for(i = 0; i < rvkh->entcnt; i++) for(i = 0; i < rvkh->entcnt; i++)
{ {
@ -113,7 +113,7 @@ void rvk_print(FILE *fp, sce_buffer_ctxt_t *ctxt)
else if(rvkh->type_0 == 3) else if(rvkh->type_0 == 3)
{ {
fprintf(fp, "[*] Package Revoke List Entries:\n"); fprintf(fp, "[*] Package Revoke List Entries:\n");
u8 *ent = (u8 *)(ctxt->scebuffer + ctxt->metash[1].data_offset); u8 *ent = (u8 *)(ctxt->scebuffer + _ES64(ctxt->metash[1].data_offset));
for(i = 0; i < rvkh->entcnt; i++) for(i = 0; i < rvkh->entcnt; i++)
{ {
_hexdump(fp, " ent", i*0x20, ent, 0x20, TRUE); _hexdump(fp, " ent", i*0x20, ent, 0x20, TRUE);

View file

@ -58,7 +58,7 @@ static inline void _es_rvk_header(rvk_header_t *h)
/*! Program revoke list entry. */ /*! Program revoke list entry. */
typedef struct _prg_rvk_entry typedef struct _prg_rvk_entry
{ {
u32 self_type; //3, 4 u32 program_type; //3, 4
u32 check_type; u32 check_type;
u64 version; u64 version;
union union
@ -71,7 +71,7 @@ typedef struct _prg_rvk_entry
static inline void _es_prg_rvk_entry(prg_rvk_entry_t *e) static inline void _es_prg_rvk_entry(prg_rvk_entry_t *e)
{ {
e->self_type = _ES32(e->self_type); e->program_type = _ES32(e->program_type);
e->check_type = _ES32(e->check_type); e->check_type = _ES32(e->check_type);
e->version = _ES64(e->version); e->version = _ES64(e->version);
e->auth_id = _ES64(e->auth_id); e->auth_id = _ES64(e->auth_id);

1125
src/sce.cpp Normal file

File diff suppressed because it is too large Load diff

View file

@ -17,12 +17,12 @@
/*! Header align. */ /*! Header align. */
#define HEADER_ALIGN 0x80 #define HEADER_ALIGN 0x80
/*! SCE header magic value ("SCE\0"). */ /*! Cert file magic value ("SCE\0"). */
#define SCE_HEADER_MAGIC 0x53434500 #define CF_MAGIC 0x53434500
/*! SCE header versions. */ /*! Cert file versions. */
/*! Header version 2. */ /*! Cert file version 2. */
#define SCE_HEADER_VERSION_2 2 #define CF_VERSION_2 2
/*! Key revisions. */ /*! Key revisions. */
#define KEY_REVISION_0 0x00 #define KEY_REVISION_0 0x00
@ -52,15 +52,15 @@
//#define KEY_REVISION_ 0x18 //#define KEY_REVISION_ 0x18
#define KEY_REVISION_DEBUG 0x8000 #define KEY_REVISION_DEBUG 0x8000
/*! SCE header types. */ /*! Cert file categories. */
/*! SELF header. */ /*! SELF file. */
#define SCE_HEADER_TYPE_SELF 1 #define CF_CATEGORY_SELF 1
/*! RVK header. */ /*! RVK file. */
#define SCE_HEADER_TYPE_RVK 2 #define CF_CATEGORY_RVK 2
/*! PKG header. */ /*! PKG file. */
#define SCE_HEADER_TYPE_PKG 3 #define CF_CATEGORY_PKG 3
/*! SPP header. */ /*! SPP file. */
#define SCE_HEADER_TYPE_SPP 4 #define CF_CATEGORY_SPP 4
/*! Sub header types. */ /*! Sub header types. */
/*! SCE version header. */ /*! SCE version header. */
@ -81,6 +81,8 @@
#define OPT_HEADER_TYPE_CAP_FLAGS 1 #define OPT_HEADER_TYPE_CAP_FLAGS 1
/*! Individuals seed header. */ /*! Individuals seed header. */
#define OPT_HEADER_TYPE_INDIV_SEED 2 #define OPT_HEADER_TYPE_INDIV_SEED 2
/*! Control flags header 4. */
#define OPT_HEADER_TYPE_CONTROL_FLAGS 4
/*! Metadata key/iv lengths. */ /*! Metadata key/iv lengths. */
#define METADATA_INFO_KEYBITS 128 #define METADATA_INFO_KEYBITS 128
@ -94,8 +96,8 @@
#define METADATA_SECTION_TYPE_SHDR 1 #define METADATA_SECTION_TYPE_SHDR 1
/*! Program header. */ /*! Program header. */
#define METADATA_SECTION_TYPE_PHDR 2 #define METADATA_SECTION_TYPE_PHDR 2
/*! Unknown header type 3. */ /*! Sceversion section. */
#define METADATA_SECTION_TYPE_UNK_3 3 #define METADATA_SECTION_TYPE_SCEV 3
/*! Section is hashed. */ /*! Section is hashed. */
#define METADATA_SECTION_HASHED 2 #define METADATA_SECTION_HASHED 2
@ -108,6 +110,9 @@
/*! Section is compressed. */ /*! Section is compressed. */
#define METADATA_SECTION_COMPRESSED 2 #define METADATA_SECTION_COMPRESSED 2
/*! Signature types. */
#define SIGNATURE_ALGORITHM_ECDSA 1
/*! Signature sizes. */ /*! Signature sizes. */
/*! Signature S part size. */ /*! Signature S part size. */
#define SIGNATURE_S_SIZE 21 #define SIGNATURE_S_SIZE 21
@ -115,32 +120,32 @@
#define SIGNATURE_R_SIZE 21 #define SIGNATURE_R_SIZE 21
/*! Compressed. */ /*! Compressed. */
#define SECTION_INFO_COMPRESSED 2 #define SEGMENT_INFO_COMPRESSED 2
/*! Not compressed. */ /*! Not compressed. */
#define SECTION_INFO_NOT_COMPRESSED 1 #define SEGMENT_INFO_NOT_COMPRESSED 1
/*! SCE version not present. */ /*! SCE version not present. */
#define SCE_VERSION_NOT_PRESENT 0 #define SCE_VERSION_NOT_PRESENT 0
/*! SCE version present. */ /*! SCE version present. */
#define SCE_VERSION_PRESENT 1 #define SCE_VERSION_PRESENT 1
/*! SELF types. */ /*! Program types. */
/*! lv0. */ /*! lv0. */
#define SELF_TYPE_LV0 1 #define PROGRAM_TYPE_LV0 1
/*! lv1. */ /*! lv1. */
#define SELF_TYPE_LV1 2 #define PROGRAM_TYPE_LV1 2
/*! lv2. */ /*! lv2. */
#define SELF_TYPE_LV2 3 #define PROGRAM_TYPE_LV2 3
/*! Application. */ /*! Application. */
#define SELF_TYPE_APP 4 #define PROGRAM_TYPE_APP 4
/*! Isolated SPU module. */ /*! Isolated SPU module. */
#define SELF_TYPE_ISO 5 #define PROGRAM_TYPE_ISO 5
/*! Secure loader. */ /*! Secure loader. */
#define SELF_TYPE_LDR 6 #define PROGRAM_TYPE_LDR 6
/*! Unknown type 7. */ /*! Unknown type 7. */
#define SELF_TYPE_UNK_7 7 #define PROGRAM_TYPE_UNK_7 7
/*! NPDRM application. */ /*! NPDRM application. */
#define SELF_TYPE_NPDRM 8 #define PROGRAM_TYPE_NPDRM 8
/*! NPDRM control info magic value ("NPD\0"). */ /*! NPDRM control info magic value ("NPD\0"). */
#define NP_CI_MAGIC 0x4E504400 #define NP_CI_MAGIC 0x4E504400
@ -157,8 +162,8 @@
#define NP_TYPE_USPRX (NP_TYPE_UPDATE | NP_TYPE_SPRX) #define NP_TYPE_USPRX (NP_TYPE_UPDATE | NP_TYPE_SPRX)
#define NP_TYPE_UEXEC (NP_TYPE_UPDATE | NP_TYPE_EXEC) #define NP_TYPE_UEXEC (NP_TYPE_UPDATE | NP_TYPE_EXEC)
/*! SCE header. */ /*! Cert file header. */
typedef struct _sce_header typedef struct _cert_file_header
{ {
/*! Magic value. */ /*! Magic value. */
u32 magic; u32 magic;
@ -166,22 +171,22 @@ typedef struct _sce_header
u32 version; u32 version;
/*! Key revision. */ /*! Key revision. */
u16 key_revision; u16 key_revision;
/*! Header type. */ /*! File category. */
u16 header_type; u16 category;
/*! Metadata offset. */ /*! Extended header size. */
u32 metadata_offset; u32 ext_header_size;
/*! Header length. */ /*! Offset of encapsulated file. */
u64 header_len; u64 file_offset;
/*! Length of encapsulated data. */ /*! Size of encapsulated file. */
u64 data_len; u64 file_size;
} sce_header_t; } cert_file_header_t;
/*! SELF header. */ /*! SELF header. */
typedef struct _self_header typedef struct _self_header
{ {
/*! Header type. */ /*! Header type. */
u64 header_type; u64 header_type;
/*! Application info offset. */ /*! Program info offset. */
u64 app_info_offset; u64 app_info_offset;
/*! ELF offset. */ /*! ELF offset. */
u64 elf_offset; u64 elf_offset;
@ -189,8 +194,8 @@ typedef struct _self_header
u64 phdr_offset; u64 phdr_offset;
/*! Section headers offset. */ /*! Section headers offset. */
u64 shdr_offset; u64 shdr_offset;
/*! Section info offset. */ /*! Segment info offset. */
u64 section_info_offset; u64 segment_info_offset;
/*! SCE version offset. */ /*! SCE version offset. */
u64 sce_version_offset; u64 sce_version_offset;
/*! Control info offset. */ /*! Control info offset. */
@ -218,7 +223,8 @@ typedef struct _metadata_header
{ {
/*! Signature input length. */ /*! Signature input length. */
u64 sig_input_length; u64 sig_input_length;
u32 unknown_0; /*! Signature algorithm. */
u32 sig_algorithm;
/*! Section count. */ /*! Section count. */
u32 section_count; u32 section_count;
/*! Key count. */ /*! Key count. */
@ -262,8 +268,8 @@ typedef struct _signature
u8 padding[6]; u8 padding[6];
} signature_t; } signature_t;
/*! Section info. */ /*! Segment info. */
typedef struct _section_info typedef struct _segment_info
{ {
u64 offset; u64 offset;
u64 size; u64 size;
@ -271,7 +277,7 @@ typedef struct _section_info
u32 unknown_0; u32 unknown_0;
u32 unknown_1; u32 unknown_1;
u32 encrypted; u32 encrypted;
} section_info_t; } segment_info_t;
/*! SCE version. */ /*! SCE version. */
typedef struct _sce_version typedef struct _sce_version
@ -305,7 +311,7 @@ typedef struct _sce_version_data_30
#define VENDOR_TERRITORY_MASK 0xFF000000 #define VENDOR_TERRITORY_MASK 0xFF000000
#define VENDOR_ID_MASK 0x00FFFFFF #define VENDOR_ID_MASK 0x00FFFFFF
/*! Application info. */ /*! Program info. */
typedef struct _app_info typedef struct _app_info
{ {
/*! Auth ID. */ /*! Auth ID. */
@ -313,13 +319,23 @@ typedef struct _app_info
/*! Vendor ID. */ /*! Vendor ID. */
u32 vendor_id; u32 vendor_id;
/*! SELF type. */ /*! SELF type. */
u32 self_type; u32 program_type;
/*! Version. */ /*! Version. */
u64 version; u64 version;
/*! Padding. */ /*! Padding. */
u64 padding; u64 padding;
} app_info_t; } app_info_t;
/*! Vender ID. */
typedef struct _vendor_id
{
u8 territory;
u8 unknown_1;
u8 unknown_2;
u8 gos_id;
} vendor_id_t;
/*! Control info. */ /*! Control info. */
typedef struct _control_info typedef struct _control_info
{ {
@ -381,7 +397,8 @@ typedef struct _ci_data_npdrm
{ {
/*! Magic. */ /*! Magic. */
u32 magic; u32 magic;
u32 unknown_0; /*! Version. */
u32 version;
/*! License type. */ /*! License type. */
u32 license_type; u32 license_type;
/*! Application type. */ /*! Application type. */
@ -394,8 +411,10 @@ typedef struct _ci_data_npdrm
u8 hash_cid_fname[0x10]; u8 hash_cid_fname[0x10];
/*! Control info hash. */ /*! Control info hash. */
u8 hash_ci[0x10]; u8 hash_ci[0x10];
u64 unknown_1; /*! Start of the Validity period. */
u64 unknown_2; u64 limited_time_start;
/*! End of the Validity period. */
u64 limited_time_end;
} ci_data_npdrm_t; } ci_data_npdrm_t;
/*! Optional header. */ /*! Optional header. */
@ -413,10 +432,10 @@ typedef struct _opt_header
#define CAP_FLAG_1 0x01 //only seen in PPU selfs #define CAP_FLAG_1 0x01 //only seen in PPU selfs
#define CAP_FLAG_2 0x02 //only seen in PPU selfs #define CAP_FLAG_2 0x02 //only seen in PPU selfs
#define CAP_FLAG_4 0x04 //only seen in bdj PPU self #define CAP_FLAG_4 0x04 //only seen in bdj PPU self
#define CAP_FLAG_REFTOOL 0x08 #define CAP_FLAG_DEH 0x08 //00001000b
#define CAP_FLAG_DEBUG 0x10 #define CAP_FLAG_DEX 0x10 //00010000b
#define CAP_FLAG_RETAIL 0x20 #define CAP_FLAG_CEX 0x20 //00100000b
#define CAP_FLAG_SYSDBG 0x40 #define CAP_FLAG_ARCADE 0x40 //01000000b
#define UNK7_2000 0x2000 //hddbind? #define UNK7_2000 0x2000 //hddbind?
#define UNK7_20000 0x20000 //flashbind? #define UNK7_20000 0x20000 //flashbind?
@ -446,7 +465,7 @@ typedef struct _sce_section_ctxt
/*! Offset. */ /*! Offset. */
u32 offset; u32 offset;
/*! May be compressed. */ /*! May be compressed. */
BOOL may_compr; bool may_compr;
} sce_section_ctxt_t; } sce_section_ctxt_t;
typedef struct _makeself_ctxt typedef struct _makeself_ctxt
@ -479,8 +498,8 @@ typedef struct _sce_buffer_ctxt
/*! SCE file buffer. */ /*! SCE file buffer. */
u8 *scebuffer; u8 *scebuffer;
/*! SCE header. */ /*! Cert file header. */
sce_header_t *sceh; cert_file_header_t *cfh;
/*! File type dependent header. */ /*! File type dependent header. */
union union
{ {
@ -488,10 +507,10 @@ typedef struct _sce_buffer_ctxt
{ {
/*! SELF header. */ /*! SELF header. */
self_header_t *selfh; self_header_t *selfh;
/*! Application info. */ /*! Program info. */
app_info_t *ai; app_info_t *ai;
/*! Section info. */ /*! Section info. */
section_info_t *si; segment_info_t *si;
/*! SCE version. */ /*! SCE version. */
sce_version_t *sv; sce_version_t *sv;
/*! Control infos. */ /*! Control infos. */
@ -514,24 +533,24 @@ typedef struct _sce_buffer_ctxt
signature_t *sig; signature_t *sig;
/*! Metadata decrypted? */ /*! Metadata decrypted? */
BOOL mdec; bool mdec;
/*! Data layout. */ /*! Data layout. */
/*! SCE header offset. */ /*! Cert file header offset. */
u32 off_sceh; u32 off_cfh;
union union
{ {
struct struct
{ {
/*! SELF header offset. */ /*! SELF header offset. */
u32 off_selfh; u32 off_selfh;
/*! Application info offset. */ /*! Program info offset. */
u32 off_ai; u32 off_ai;
/*! ELF header offset. */ /*! ELF header offset. */
u32 off_ehdr; u32 off_ehdr;
/*! Program header offset. */ /*! Program header offset. */
u32 off_phdr; u32 off_phdr;
/*! Section info offset. */ /*! Segment info offset. */
u32 off_si; u32 off_si;
/*! SCE version offset. */ /*! SCE version offset. */
u32 off_sv; u32 off_sv;
@ -572,10 +591,10 @@ sce_buffer_ctxt_t *sce_create_ctxt_from_buffer(u8 *scebuffer);
sce_buffer_ctxt_t *sce_create_ctxt_build_self(u8 *elf, u32 elf_len); sce_buffer_ctxt_t *sce_create_ctxt_build_self(u8 *elf, u32 elf_len);
/*! Add data section to SCE context. */ /*! Add data section to SCE context. */
void sce_add_data_section(sce_buffer_ctxt_t *ctxt, void *buffer, u32 size, BOOL may_compr); void sce_add_data_section(sce_buffer_ctxt_t *ctxt, void *buffer, u32 size, bool may_compr);
/*! Set metadata section header. */ /*! Set metadata section header. */
void sce_set_metash(sce_buffer_ctxt_t *ctxt, u32 type, BOOL encrypted, u32 idx); void sce_set_metash(sce_buffer_ctxt_t *ctxt, u32 type, bool encrypted, u32 idx);
/*! Compress data. */ /*! Compress data. */
void sce_compress_data(sce_buffer_ctxt_t *ctxt); void sce_compress_data(sce_buffer_ctxt_t *ctxt);
@ -584,19 +603,25 @@ void sce_compress_data(sce_buffer_ctxt_t *ctxt);
void sce_layout_ctxt(sce_buffer_ctxt_t *ctxt); void sce_layout_ctxt(sce_buffer_ctxt_t *ctxt);
/*! Encrypt context. */ /*! Encrypt context. */
BOOL sce_encrypt_ctxt(sce_buffer_ctxt_t *ctxt, u8 *keyset); bool sce_encrypt_ctxt(sce_buffer_ctxt_t *ctxt, u8 *keyset);
/*! Write context to file. */ /*! Write context to file. */
BOOL sce_write_ctxt(sce_buffer_ctxt_t *ctxt, s8 *fname); bool sce_write_ctxt(sce_buffer_ctxt_t *ctxt, s8 *fname);
/*! Decrypt header (use passed metadata_into if not NULL). */ /*! Decrypt header (use passed metadata_into if not NULL). */
BOOL sce_decrypt_header(sce_buffer_ctxt_t *ctxt, u8 *metadata_info, u8 *keyset); bool sce_decrypt_header(sce_buffer_ctxt_t *ctxt, u8 *metadata_info, u8 *keyset);
/*! Decrypt data. */ /*! Decrypt data. */
BOOL sce_decrypt_data(sce_buffer_ctxt_t *ctxt); bool sce_decrypt_data(sce_buffer_ctxt_t *ctxt);
/*! Print SCE header info. */
void cf_print_info(FILE *fp, sce_buffer_ctxt_t *ctxt);
/*! Print SCE file info. */ /*! Print SCE file info. */
void sce_print_info(FILE *fp, sce_buffer_ctxt_t *ctxt); void sce_print_info(FILE *fp, sce_buffer_ctxt_t *ctxt, u8 *keyset);
/*! Print SCE signature status. */
void print_sce_signature_info(FILE *fp, sce_buffer_ctxt_t *ctxt, u8 *keyset);
/*! Get version string from version. */ /*! Get version string from version. */
s8 *sce_version_to_str(u64 version); s8 *sce_version_to_str(u64 version);

57
src/sce_inlines.h Normal file
View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2011-2013 by naehrwert
* This file is released under the GPLv2.
*/
#ifndef _SCE_INLINES_H_
#define _SCE_INLINES_H_
#include <string.h>
#include "types.h"
#include "sce.h"
static inline void _es_segment_info(segment_info_t *si)
{
si->offset = _ES64(si->offset);
si->size = _ES64(si->size);
si->compressed = _ES32(si->compressed);
si->unknown_0 = _ES32(si->unknown_0);
si->unknown_1 = _ES32(si->unknown_1);
si->encrypted = _ES32(si->encrypted);
}
static inline void _copy_es_segment_info(segment_info_t *dst, segment_info_t *src)
{
memcpy(dst, src, sizeof(segment_info_t));
_es_segment_info(dst);
}
static inline void _es_ci_data_digest_40(ci_data_digest_40_t *dig)
{
dig->fw_version = _ES64(dig->fw_version);
}
static inline void _copy_es_ci_data_digest_40(ci_data_digest_40_t *dst, ci_data_digest_40_t *src)
{
memcpy(dst, src, sizeof(ci_data_digest_40_t));
_es_ci_data_digest_40(dst);
}
static inline void _es_oh_data_cap_flags(oh_data_cap_flags_t *cf)
{
cf->unk3 = _ES64(cf->unk3);
cf->unk4 = _ES64(cf->unk4);
cf->flags = _ES64(cf->flags);
cf->unk6 = _ES32(cf->unk6);
cf->unk7 = _ES32(cf->unk7);
}
static inline void _copy_es_cap_flags(oh_data_cap_flags_t *dst, oh_data_cap_flags_t *src)
{
memcpy(dst, src, sizeof(oh_data_cap_flags_t));
_es_oh_data_cap_flags(dst);
}
#endif

1220
src/self.cpp Normal file

File diff suppressed because it is too large Load diff

View file

@ -26,11 +26,11 @@
typedef struct _self_config typedef struct _self_config
{ {
/*! Add section headers. */ /*! Add section headers. */
BOOL add_shdrs; bool add_shdrs;
/*! Compress data. */ /*! Compress data. */
BOOL compress_data; bool compress_data;
/*! Skip sections. */ /*! Skip sections. */
BOOL skip_sections; bool skip_sections;
/*! Key revision. */ /*! Key revision. */
u16 key_revision; u16 key_revision;
@ -38,35 +38,35 @@ typedef struct _self_config
u64 auth_id; u64 auth_id;
/*! Vendor ID. */ /*! Vendor ID. */
u32 vendor_id; u32 vendor_id;
/*! SELF type. */ /*! Program type. */
u32 self_type; u32 program_type;
/*! Application version. */ /*! Application version. */
u64 app_version; u64 app_version;
/*! Firmware version. */ /*! Firmware version. */
u64 fw_version; u64 fw_version;
/*! Control flags. */ /*! Control flags. */
u8 *ctrl_flags; u8 *ctrl_flags;
/*! Capability flags. */ /*! Capability flags. */
u8 *cap_flags; u8 *cap_flags;
#ifdef CONFIG_CUSTOM_INDIV_SEED
/*! Individuals seed. */ /*! Individuals seed. */
u8 *indiv_seed; u8 *indiv_seed;
/*! Individuals seed size. */ /*! Individuals seed size. */
u32 indiv_seed_size; u32 indiv_seed_size;
#endif
/*! NPDRM config (used if not NULL). */ /*! NPDRM config (used if not NULL). */
npdrm_config_t *npdrm_config; npdrm_config_t *npdrm_config;
} self_config_t; } self_config_t;
/*! Print SELF info. */ /*! Print SELF info. */
BOOL self_print_info(FILE *fp, sce_buffer_ctxt_t *ctxt); bool self_print_info(FILE *fp, sce_buffer_ctxt_t *ctxt);
/*! Print SELF encrypted info. */
bool self_print_encrypted_info(FILE *fp, sce_buffer_ctxt_t *ctxt);
/*! Create ELF from SELF. */ /*! Create ELF from SELF. */
BOOL self_write_to_elf(sce_buffer_ctxt_t *ctxt, const s8 *elf_out); bool self_write_to_elf(sce_buffer_ctxt_t *ctxt, const s8 *elf_out);
/*! Create SELF from ELF. */ /*! Create SELF from ELF. */
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);
#endif #endif

View file

View file

@ -38,11 +38,11 @@ void spp_print(FILE *fp, sce_buffer_ctxt_t *ctxt)
u32 i; u32 i;
//First section contains the SPP header. //First section contains the SPP header.
spp_header_t *header = (spp_header_t *)(ctxt->scebuffer + ctxt->metash[0].data_offset); spp_header_t *header = (spp_header_t *)(ctxt->scebuffer + _ES64(ctxt->metash[0].data_offset));
_es_spp_header(header); _es_spp_header(header);
//Second section contains the entries. //Second section contains the entries.
u8 *ent = ctxt->scebuffer + ctxt->metash[1].data_offset; u8 *ent = ctxt->scebuffer + _ES64(ctxt->metash[1].data_offset);
_print_spp_header(fp, header); _print_spp_header(fp, header);

View file

View file

@ -12,30 +12,30 @@
#include "keys.h" #include "keys.h"
/*! SELF types. */ /*! SELF types. */
id_to_name_t _self_types[] = id_to_name_t _program_types[] =
{ {
{SELF_TYPE_LV0, "lv0"}, {PROGRAM_TYPE_LV0, "lv0"},
{SELF_TYPE_LV1, "lv1"}, {PROGRAM_TYPE_LV1, "lv1"},
{SELF_TYPE_LV2, "lv2"}, {PROGRAM_TYPE_LV2, "lv2"},
{SELF_TYPE_APP, "Application"}, {PROGRAM_TYPE_APP, "Application"},
{SELF_TYPE_ISO, "Isolated SPU Module"}, {PROGRAM_TYPE_ISO, "Isolated SPU Module"},
{SELF_TYPE_LDR, "Secure Loader"}, {PROGRAM_TYPE_LDR, "Secure Loader"},
{SELF_TYPE_UNK_7, "Unknown 7"}, {PROGRAM_TYPE_UNK_7, "Unknown 7"},
{SELF_TYPE_NPDRM, "NPDRM Application"}, {PROGRAM_TYPE_NPDRM, "NPDRM Application"},
{0, NULL} {0, NULL}
}; };
/*! SELF types as parameter. */ /*! SELF types as parameter. */
id_to_name_t _self_types_params[] = id_to_name_t _program_types_params[] =
{ {
{SELF_TYPE_LV0, "LV0"}, {PROGRAM_TYPE_LV0, "LV0"},
{SELF_TYPE_LV1, "LV1"}, {PROGRAM_TYPE_LV1, "LV1"},
{SELF_TYPE_LV2, "LV2"}, {PROGRAM_TYPE_LV2, "LV2"},
{SELF_TYPE_APP, "APP"}, {PROGRAM_TYPE_APP, "APP"},
{SELF_TYPE_ISO, "ISO"}, {PROGRAM_TYPE_ISO, "ISO"},
{SELF_TYPE_LDR, "LDR"}, {PROGRAM_TYPE_LDR, "LDR"},
//{SELF_TYPE_UNK_7, "UNK7"}, //{PROGRAM_TYPE_UNK_7, "UNK7"},
{SELF_TYPE_NPDRM, "NPDRM"}, {PROGRAM_TYPE_NPDRM, "NPDRM"},
{0, NULL} {0, NULL}
}; };
@ -52,9 +52,17 @@ id_to_name_t _control_info_types[] =
id_to_name_t _optional_header_types[] = id_to_name_t _optional_header_types[] =
{ {
{OPT_HEADER_TYPE_CAP_FLAGS, "Capability Flags"}, {OPT_HEADER_TYPE_CAP_FLAGS, "Capability Flags"},
#ifdef CONFIG_DUMP_INDIV_SEED
{OPT_HEADER_TYPE_INDIV_SEED, "Individuals Seed"}, {OPT_HEADER_TYPE_INDIV_SEED, "Individuals Seed"},
#endif {OPT_HEADER_TYPE_CONTROL_FLAGS, "Control Flags"},
{0, NULL}
};
/*! NPDRM license types. */
id_to_name_t _np_license_types[] =
{
{NP_LICENSE_NETWORK, "NETWORK"},
{NP_LICENSE_LOCAL, "LOCAL"},
{NP_LICENSE_FREE, "FREE"},
{0, NULL} {0, NULL}
}; };
@ -65,7 +73,7 @@ id_to_name_t _np_app_types[] =
{NP_TYPE_EXEC, "EXEC"}, {NP_TYPE_EXEC, "EXEC"},
{NP_TYPE_USPRX, "USPRX"}, {NP_TYPE_USPRX, "USPRX"},
{NP_TYPE_UEXEC, "UEXEC"}, {NP_TYPE_UEXEC, "UEXEC"},
{0, NULL}, {0, NULL}
}; };
/*! Auth IDs. */ /*! Auth IDs. */
@ -78,7 +86,18 @@ id_to_name_t _auth_ids[] =
{0x1070000002000002, "mcore"}, {0x1070000002000002, "mcore"},
{0x1070000003000002, "mgvideo"}, {0x1070000003000002, "mgvideo"},
{0x1070000004000002, "swagner, swreset"}, {0x1070000004000002, "swagner, swreset"},
{0x107000000E000001, "vtrm_server (lv1)"},
{0x107000000F000001, "update_manager_server (lv1)"},
{0x1070000010000001, "sc_manager_server (lv1)"},
{0x1070000011000001, "secure_rtc_server (lv1)"},
{0x1070000012000001, "spm_server (lv1)"},
{0x1070000013000001, "sb_manager_server (lv1)"},
{0x1070000014000001, "framework (lv1)"},
{0x1070000015000001, "lv2_loader (lv1)"},
{0x1070000016000001, "profile_loader (lv1)"},
{0x1070000017000001, "ss_init (lv1)"}, {0x1070000017000001, "ss_init (lv1)"},
{0x1070000018000001, "individual_info_mgr_server (lv1)"},
{0x1070000019000001, "app_info_manager_server (lv1)"},
{0x107000001A000001, "ss_sc_init_pu (lv1)"}, {0x107000001A000001, "ss_sc_init_pu (lv1)"},
{0x107000001C000001, "updater_frontend (lv1)"}, {0x107000001C000001, "updater_frontend (lv1)"},
{0x107000001D000001, "sysmgr_ss (lv1)"}, {0x107000001D000001, "sysmgr_ss (lv1)"},
@ -90,6 +109,7 @@ id_to_name_t _auth_ids[] =
{0x1070000024000001, "sv_iso_spu_module"}, {0x1070000024000001, "sv_iso_spu_module"},
{0x1070000025000001, "aim_spu_module"}, {0x1070000025000001, "aim_spu_module"},
{0x1070000026000001, "ss_sc_init"}, {0x1070000026000001, "ss_sc_init"},
{0x1070000027000001, "dispatcher (lv1)"},
{0x1070000028000001, "factory_data_mngr_server (lv1)"}, {0x1070000028000001, "factory_data_mngr_server (lv1)"},
{0x1070000029000001, "fdm_spu_module"}, {0x1070000029000001, "fdm_spu_module"},
{0x1070000032000001, "ss_server1 (lv1)"}, {0x1070000032000001, "ss_server1 (lv1)"},
@ -102,6 +122,8 @@ id_to_name_t _auth_ids[] =
{0x1070000041000001, "ps1emu"}, {0x1070000041000001, "ps1emu"},
{0x1070000043000001, "me_iso_spu_module"}, {0x1070000043000001, "me_iso_spu_module"},
{0x1070000046000001, "spu_mode_auth"}, {0x1070000046000001, "spu_mode_auth"},
{0x1070000047000001, "otheros"},
{0x1070000048000001, "ftpd"},
{0x107000004C000001, "spu_utoken_processor"}, {0x107000004C000001, "spu_utoken_processor"},
{0x1070000052000001, "sys/internal + vsh/module modules"}, {0x1070000052000001, "sys/internal + vsh/module modules"},
{0x1070000055000001, "manu_info_spu_module"}, {0x1070000055000001, "manu_info_spu_module"},
@ -125,6 +147,7 @@ id_to_name_t _auth_ids[] =
{0x1FF0000008000001, "lv1ldr"}, {0x1FF0000008000001, "lv1ldr"},
{0x1FF0000009000001, "lv2ldr"}, {0x1FF0000009000001, "lv2ldr"},
{0x1FF000000A000001, "isoldr"}, {0x1FF000000A000001, "isoldr"},
{0x1FF000000B000001, "rvkldr"},
{0x1FF000000C000001, "appldr"}, {0x1FF000000C000001, "appldr"},
{0, NULL} {0, NULL}
}; };
@ -198,14 +221,23 @@ id_to_name_t _ph_types[] =
{0, NULL} {0, NULL}
}; };
/*! Key types. */ /*! Metadata section header types. */
id_to_name_t _key_types[] = id_to_name_t _msh_types[] =
{ {
{KEYTYPE_SELF, "SELF"}, {METADATA_SECTION_TYPE_SHDR, "SHDR"},
{KEYTYPE_RVK, "RVK"}, {METADATA_SECTION_TYPE_PHDR, "PHDR"},
{KEYTYPE_PKG, "PKG"}, {METADATA_SECTION_TYPE_SCEV, "SCEV"},
{KEYTYPE_SPP, "SPP"}, {0, NULL}
{KEYTYPE_OTHER, "OTHER"}, };
/*! Key types. */
id_to_name_t _key_categories[] =
{
{KEYCATEGORY_SELF, "SELF"},
{KEYCATEGORY_RVK, "RVK"},
{KEYCATEGORY_PKG, "PKG"},
{KEYCATEGORY_SPP, "SPP"},
{KEYCATEGORY_OTHER, "OTHER"},
{0, NULL} {0, NULL}
}; };
@ -248,12 +280,18 @@ const s8 *_key_revisions[] =
}; };
*/ */
/*! SCE header types. */ /*! Cert file types. */
id_to_name_t _sce_header_types[] = id_to_name_t _cert_file_categories[] =
{ {
{SCE_HEADER_TYPE_SELF, "SELF"}, {CF_CATEGORY_SELF, "SELF"},
{SCE_HEADER_TYPE_RVK, "RVK"}, {CF_CATEGORY_RVK, "RVK"},
{SCE_HEADER_TYPE_PKG, "PKG"}, {CF_CATEGORY_PKG, "PKG"},
{SCE_HEADER_TYPE_SPP, "SPP"}, {CF_CATEGORY_SPP, "SPP"},
{0, NULL}
};
id_to_name_t _sig_algorithms[] =
{
{SIGNATURE_ALGORITHM_ECDSA, "ECDSA"},
{0, NULL} {0, NULL}
}; };

View file

@ -10,10 +10,10 @@
#include "util.h" #include "util.h"
/*! SELF types. */ /*! SELF types. */
extern id_to_name_t _self_types[]; extern id_to_name_t _program_types[];
/*! SELF types as parameter. */ /*! SELF types as parameter. */
extern id_to_name_t _self_types_params[]; extern id_to_name_t _program_types_params[];
/* Control info types. */ /* Control info types. */
extern id_to_name_t _control_info_types[]; extern id_to_name_t _control_info_types[];
@ -21,6 +21,9 @@ extern id_to_name_t _control_info_types[];
/*! Optional header types. */ /*! Optional header types. */
extern id_to_name_t _optional_header_types[]; extern id_to_name_t _optional_header_types[];
/*! NPDRM license types. */
extern id_to_name_t _np_license_types[];
/*! NPDRM application types. */ /*! NPDRM application types. */
extern id_to_name_t _np_app_types[]; extern id_to_name_t _np_app_types[];
@ -42,13 +45,19 @@ extern id_to_name_t _sh_types[];
/*! Program header types. */ /*! Program header types. */
extern id_to_name_t _ph_types[]; extern id_to_name_t _ph_types[];
/*! Metadata section header types. */
extern id_to_name_t _msh_types[];
/*! Key types. */ /*! Key types. */
extern id_to_name_t _key_types[]; extern id_to_name_t _key_categories[];
/*! Key revisions. */ /*! Key revisions. */
//extern const s8 *_key_revisions[]; //extern const s8 *_key_revisions[];
/*! SCE header types. */ /*! Cert file types. */
extern id_to_name_t _sce_header_types[]; extern id_to_name_t _cert_file_categories[];
/*! Signature algorithms. */
extern id_to_name_t _sig_algorithms[];
#endif #endif

View file

@ -23,7 +23,7 @@ typedef long long int s64;
typedef unsigned long long int u64; typedef unsigned long long int u64;
#endif #endif
#define BOOL int #define bool int
#define TRUE 1 #define TRUE 1
#define FALSE 0 #define FALSE 0
@ -39,6 +39,10 @@ typedef unsigned long long int u64;
((u16)(((((u16)val) & 0xff00) >> 8) | \ ((u16)(((((u16)val) & 0xff00) >> 8) | \
((((u16)val) & 0x00ff) << 8))) ((((u16)val) & 0x00ff) << 8)))
#ifdef __BIG_ENDIAN__
#define _ES16(val) val
#endif
//Endian swap for u32. //Endian swap for u32.
#define _ES32(val) \ #define _ES32(val) \
((u32)(((((u32)val) & 0xff000000) >> 24) | \ ((u32)(((((u32)val) & 0xff000000) >> 24) | \
@ -46,6 +50,10 @@ typedef unsigned long long int u64;
((((u32)val) & 0x0000ff00) << 8 ) | \ ((((u32)val) & 0x0000ff00) << 8 ) | \
((((u32)val) & 0x000000ff) << 24))) ((((u32)val) & 0x000000ff) << 24)))
#ifdef __BIG_ENDIAN__
#define _ES32(val) val
#endif
//Endian swap for u64. //Endian swap for u64.
#define _ES64(val) \ #define _ES64(val) \
((u64)(((((u64)val) & 0xff00000000000000ull) >> 56) | \ ((u64)(((((u64)val) & 0xff00000000000000ull) >> 56) | \
@ -57,6 +65,10 @@ typedef unsigned long long int u64;
((((u64)val) & 0x000000000000ff00ull) << 40) | \ ((((u64)val) & 0x000000000000ff00ull) << 40) | \
((((u64)val) & 0x00000000000000ffull) << 56))) ((((u64)val) & 0x00000000000000ffull) << 56)))
#ifdef __BIG_ENDIAN__
#define _ES64(val) val
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -2,6 +2,7 @@
* Copyright (c) 2011-2013 by naehrwert * Copyright (c) 2011-2013 by naehrwert
* This file is released under the GPLv2. * This file is released under the GPLv2.
*/ */
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -13,7 +14,7 @@
#include "zlib.h" #include "zlib.h"
#include "mt19937.h" #include "mt19937.h"
void _hexdump(FILE *fp, const char *name, u32 offset, u8 *buf, int len, BOOL print_addr) void _hexdump(FILE *fp, const char *name, u32 offset, u8 *buf, int len, bool print_addr)
{ {
int i, j, align = strlen(name) + 1; int i, j, align = strlen(name) + 1;
@ -133,9 +134,9 @@ void _zlib_inflate(u8 *in, u64 len_in, u8 *out, u64 len_out)
inflateInit(&s); inflateInit(&s);
s.avail_in = len_in; s.avail_in = (u32)len_in;
s.next_in = in; s.next_in = in;
s.avail_out = len_out; s.avail_out = (u32)len_out;
s.next_out = out; s.next_out = out;
inflate(&s, Z_FINISH); inflate(&s, Z_FINISH);
@ -154,9 +155,9 @@ void _zlib_deflate(u8 *in, u64 len_in, u8 *out, u64 len_out)
deflateInit(&s, Z_BEST_COMPRESSION); deflateInit(&s, Z_BEST_COMPRESSION);
s.avail_in = len_in; s.avail_in = (u32)len_in;
s.next_in = in; s.next_in = in;
s.avail_out = len_out; s.avail_out = (u32)len_out;
s.next_out = out; s.next_out = out;
deflate(&s, Z_FINISH); deflate(&s, Z_FINISH);
@ -165,7 +166,7 @@ void _zlib_deflate(u8 *in, u64 len_in, u8 *out, u64 len_out)
} }
static mt19937_ctxt_t _mt19937_ctxt; static mt19937_ctxt_t _mt19937_ctxt;
static BOOL _mt_init = FALSE; static bool _mt_init = FALSE;
u8 _get_rand_byte() u8 _get_rand_byte()
{ {

View file

@ -11,7 +11,7 @@
#include "types.h" #include "types.h"
/*! Verbose. */ /*! Verbose. */
extern BOOL _verbose; extern bool _verbose;
#define _LOG_VERBOSE(...) _IF_VERBOSE(printf("[*] " __VA_ARGS__)) #define _LOG_VERBOSE(...) _IF_VERBOSE(printf("[*] " __VA_ARGS__))
#define _IF_VERBOSE(code) \ #define _IF_VERBOSE(code) \
do \ do \
@ -23,7 +23,7 @@ extern BOOL _verbose;
} while(0) } while(0)
/*! Raw. */ /*! Raw. */
extern BOOL _raw; extern bool _raw;
#define _PRINT_RAW(fp, ...) _IF_RAW(fprintf(fp, __VA_ARGS__)) #define _PRINT_RAW(fp, ...) _IF_RAW(fprintf(fp, __VA_ARGS__))
#define _IF_RAW(code) \ #define _IF_RAW(code) \
do \ do \
@ -42,7 +42,7 @@ typedef struct _id_to_name
} id_to_name_t; } id_to_name_t;
/*! Utility functions. */ /*! Utility functions. */
void _hexdump(FILE *fp, const char *name, u32 offset, u8 *buf, int len, BOOL print_addr); void _hexdump(FILE *fp, const char *name, u32 offset, u8 *buf, int len, bool print_addr);
void _print_align(FILE *fp, const s8 *str, s32 align, s32 len); void _print_align(FILE *fp, const s8 *str, s32 align, s32 len);
u8 *_read_buffer(const s8 *file, u32 *length); u8 *_read_buffer(const s8 *file, u32 *length);
int _write_buffer(const s8 *file, u8 *buffer, u32 length); int _write_buffer(const s8 *file, u8 *buffer, u32 length);

View file

@ -1,5 +1,5 @@
/* zconf.h -- configuration of the zlib compression library /* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-2010 Jean-loup Gailly. * Copyright (C) 1995-2013 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@ -15,11 +15,13 @@
* this permanently in zconf.h using "./configure --zprefix". * this permanently in zconf.h using "./configure --zprefix".
*/ */
#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ #ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
# define Z_PREFIX_SET
/* all linked symbols */ /* all linked symbols */
# define _dist_code z__dist_code # define _dist_code z__dist_code
# define _length_code z__length_code # define _length_code z__length_code
# define _tr_align z__tr_align # define _tr_align z__tr_align
# define _tr_flush_bits z__tr_flush_bits
# define _tr_flush_block z__tr_flush_block # define _tr_flush_block z__tr_flush_block
# define _tr_init z__tr_init # define _tr_init z__tr_init
# define _tr_stored_block z__tr_stored_block # define _tr_stored_block z__tr_stored_block
@ -27,9 +29,11 @@
# define adler32 z_adler32 # define adler32 z_adler32
# define adler32_combine z_adler32_combine # define adler32_combine z_adler32_combine
# define adler32_combine64 z_adler32_combine64 # define adler32_combine64 z_adler32_combine64
# ifndef Z_SOLO
# define compress z_compress # define compress z_compress
# define compress2 z_compress2 # define compress2 z_compress2
# define compressBound z_compressBound # define compressBound z_compressBound
# endif
# define crc32 z_crc32 # define crc32 z_crc32
# define crc32_combine z_crc32_combine # define crc32_combine z_crc32_combine
# define crc32_combine64 z_crc32_combine64 # define crc32_combine64 z_crc32_combine64
@ -40,13 +44,16 @@
# define deflateInit2_ z_deflateInit2_ # define deflateInit2_ z_deflateInit2_
# define deflateInit_ z_deflateInit_ # define deflateInit_ z_deflateInit_
# define deflateParams z_deflateParams # define deflateParams z_deflateParams
# define deflatePending z_deflatePending
# define deflatePrime z_deflatePrime # define deflatePrime z_deflatePrime
# define deflateReset z_deflateReset # define deflateReset z_deflateReset
# define deflateResetKeep z_deflateResetKeep
# define deflateSetDictionary z_deflateSetDictionary # define deflateSetDictionary z_deflateSetDictionary
# define deflateSetHeader z_deflateSetHeader # define deflateSetHeader z_deflateSetHeader
# define deflateTune z_deflateTune # define deflateTune z_deflateTune
# define deflate_copyright z_deflate_copyright # define deflate_copyright z_deflate_copyright
# define get_crc_table z_get_crc_table # define get_crc_table z_get_crc_table
# ifndef Z_SOLO
# define gz_error z_gz_error # define gz_error z_gz_error
# define gz_intmax z_gz_intmax # define gz_intmax z_gz_intmax
# define gz_strwinerror z_gz_strwinerror # define gz_strwinerror z_gz_strwinerror
@ -61,12 +68,17 @@
# define gzerror z_gzerror # define gzerror z_gzerror
# define gzflush z_gzflush # define gzflush z_gzflush
# define gzgetc z_gzgetc # define gzgetc z_gzgetc
# define gzgetc_ z_gzgetc_
# define gzgets z_gzgets # define gzgets z_gzgets
# define gzoffset z_gzoffset # define gzoffset z_gzoffset
# define gzoffset64 z_gzoffset64 # define gzoffset64 z_gzoffset64
# define gzopen z_gzopen # define gzopen z_gzopen
# define gzopen64 z_gzopen64 # define gzopen64 z_gzopen64
# ifdef _WIN32
# define gzopen_w z_gzopen_w
# endif
# define gzprintf z_gzprintf # define gzprintf z_gzprintf
# define gzvprintf z_gzvprintf
# define gzputc z_gzputc # define gzputc z_gzputc
# define gzputs z_gzputs # define gzputs z_gzputs
# define gzread z_gzread # define gzread z_gzread
@ -78,6 +90,7 @@
# define gztell64 z_gztell64 # define gztell64 z_gztell64
# define gzungetc z_gzungetc # define gzungetc z_gzungetc
# define gzwrite z_gzwrite # define gzwrite z_gzwrite
# endif
# define inflate z_inflate # define inflate z_inflate
# define inflateBack z_inflateBack # define inflateBack z_inflateBack
# define inflateBackEnd z_inflateBackEnd # define inflateBackEnd z_inflateBackEnd
@ -92,16 +105,22 @@
# define inflateReset z_inflateReset # define inflateReset z_inflateReset
# define inflateReset2 z_inflateReset2 # define inflateReset2 z_inflateReset2
# define inflateSetDictionary z_inflateSetDictionary # define inflateSetDictionary z_inflateSetDictionary
# define inflateGetDictionary z_inflateGetDictionary
# define inflateSync z_inflateSync # define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint # define inflateSyncPoint z_inflateSyncPoint
# define inflateUndermine z_inflateUndermine # define inflateUndermine z_inflateUndermine
# define inflateResetKeep z_inflateResetKeep
# define inflate_copyright z_inflate_copyright # define inflate_copyright z_inflate_copyright
# define inflate_fast z_inflate_fast # define inflate_fast z_inflate_fast
# define inflate_table z_inflate_table # define inflate_table z_inflate_table
# ifndef Z_SOLO
# define uncompress z_uncompress # define uncompress z_uncompress
# endif
# define zError z_zError # define zError z_zError
# ifndef Z_SOLO
# define zcalloc z_zcalloc # define zcalloc z_zcalloc
# define zcfree z_zcfree # define zcfree z_zcfree
# endif
# define zlibCompileFlags z_zlibCompileFlags # define zlibCompileFlags z_zlibCompileFlags
# define zlibVersion z_zlibVersion # define zlibVersion z_zlibVersion
@ -111,7 +130,9 @@
# define alloc_func z_alloc_func # define alloc_func z_alloc_func
# define charf z_charf # define charf z_charf
# define free_func z_free_func # define free_func z_free_func
# ifndef Z_SOLO
# define gzFile z_gzFile # define gzFile z_gzFile
# endif
# define gz_header z_gz_header # define gz_header z_gz_header
# define gz_headerp z_gz_headerp # define gz_headerp z_gz_headerp
# define in_func z_in_func # define in_func z_in_func
@ -197,6 +218,12 @@
# endif # endif
#endif #endif
#if defined(ZLIB_CONST) && !defined(z_const)
# define z_const const
#else
# define z_const
#endif
/* Some Mac compilers merge all .h files incorrectly: */ /* Some Mac compilers merge all .h files incorrectly: */
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
# define NO_DUMMY_DECL # define NO_DUMMY_DECL
@ -243,6 +270,14 @@
# endif # endif
#endif #endif
#ifndef Z_ARG /* function prototypes for stdarg */
# if defined(STDC) || defined(Z_HAVE_STDARG_H)
# define Z_ARG(args) args
# else
# define Z_ARG(args) ()
# endif
#endif
/* The following definitions for FAR are needed only for MSDOS mixed /* The following definitions for FAR are needed only for MSDOS mixed
* model programming (small or medium model with some far allocations). * model programming (small or medium model with some far allocations).
* This was tested only with MSC; for other MSDOS compilers you may have * This was tested only with MSC; for other MSDOS compilers you may have
@ -356,12 +391,47 @@ typedef uLong FAR uLongf;
typedef Byte *voidp; typedef Byte *voidp;
#endif #endif
#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
# include <limits.h>
# if (UINT_MAX == 0xffffffffUL)
# define Z_U4 unsigned
# elif (ULONG_MAX == 0xffffffffUL)
# define Z_U4 unsigned long
# elif (USHRT_MAX == 0xffffffffUL)
# define Z_U4 unsigned short
# endif
#endif
#ifdef Z_U4
typedef Z_U4 z_crc_t;
#else
typedef unsigned long z_crc_t;
#endif
#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ #ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
# define Z_HAVE_UNISTD_H # define Z_HAVE_UNISTD_H
#endif #endif
#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
# define Z_HAVE_STDARG_H
#endif
#ifdef STDC #ifdef STDC
# ifndef Z_SOLO
# include <sys/types.h> /* for off_t */ # include <sys/types.h> /* for off_t */
# endif
#endif
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
# ifndef Z_SOLO
# include <stdarg.h> /* for va_list */
# endif
#endif
#ifdef _WIN32
# ifndef Z_SOLO
# include <stddef.h> /* for wchar_t */
# endif
#endif #endif
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and /* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
@ -370,21 +440,38 @@ typedef uLong FAR uLongf;
* both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
* equivalently requesting no 64-bit operations * equivalently requesting no 64-bit operations
*/ */
#if -_LARGEFILE64_SOURCE - -1 == 1 #if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
# undef _LARGEFILE64_SOURCE # undef _LARGEFILE64_SOURCE
#endif #endif
#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) #if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
# include <unistd.h> /* for SEEK_* and off_t */ # define Z_HAVE_UNISTD_H
#endif
#ifndef Z_SOLO
# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
# ifdef VMS # ifdef VMS
# include <unixio.h> /* for off_t */ # include <unixio.h> /* for off_t */
# endif # endif
# ifndef z_off_t # ifndef z_off_t
# define z_off_t off_t # define z_off_t off_t
# endif # endif
# endif
#endif #endif
#ifndef SEEK_SET #if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
# define Z_LFS64
#endif
#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
# define Z_LARGE64
#endif
#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
# define Z_WANT64
#endif
#if !defined(SEEK_SET) && !defined(Z_SOLO)
# define SEEK_SET 0 /* Seek from beginning of file. */ # define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */ # define SEEK_CUR 1 /* Seek from current position. */
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
@ -394,18 +481,14 @@ typedef uLong FAR uLongf;
# define z_off_t long # define z_off_t long
#endif #endif
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 #if !defined(_WIN32) && defined(Z_LARGE64)
# define z_off64_t off64_t # define z_off64_t off64_t
#else #else
# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
# define z_off64_t __int64
# else
# define z_off64_t z_off_t # define z_off64_t z_off_t
#endif # endif
#if defined(__OS400__)
# define NO_vsnprintf
#endif
#if defined(__MVS__)
# define NO_vsnprintf
#endif #endif
/* MVS linker does not support external names larger than 8 bytes */ /* MVS linker does not support external names larger than 8 bytes */

View file

@ -1,7 +1,7 @@
/* zlib.h -- interface of the 'zlib' general purpose compression library /* zlib.h -- interface of the 'zlib' general purpose compression library
version 1.2.5, April 19th, 2010 version 1.2.8, April 28th, 2013
Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -24,8 +24,8 @@
The data format used by the zlib library is described by RFCs (Request for The data format used by the zlib library is described by RFCs (Request for
Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
*/ */
#ifndef ZLIB_H #ifndef ZLIB_H
@ -37,11 +37,11 @@
extern "C" { extern "C" {
#endif #endif
#define ZLIB_VERSION "1.2.5" #define ZLIB_VERSION "1.2.8"
#define ZLIB_VERNUM 0x1250 #define ZLIB_VERNUM 0x1280
#define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MAJOR 1
#define ZLIB_VER_MINOR 2 #define ZLIB_VER_MINOR 2
#define ZLIB_VER_REVISION 5 #define ZLIB_VER_REVISION 8
#define ZLIB_VER_SUBREVISION 0 #define ZLIB_VER_SUBREVISION 0
/* /*
@ -83,15 +83,15 @@ typedef void (*free_func) OF((voidpf opaque, voidpf address));
struct internal_state; struct internal_state;
typedef struct z_stream_s { typedef struct z_stream_s {
Bytef *next_in; /* next input byte */ z_const Bytef *next_in; /* next input byte */
uInt avail_in; /* number of bytes available at next_in */ uInt avail_in; /* number of bytes available at next_in */
uLong total_in; /* total nb of input bytes read so far */ uLong total_in; /* total number of input bytes read so far */
Bytef *next_out; /* next output byte should be put there */ Bytef *next_out; /* next output byte should be put there */
uInt avail_out; /* remaining free space at next_out */ uInt avail_out; /* remaining free space at next_out */
uLong total_out; /* total nb of bytes output so far */ uLong total_out; /* total number of bytes output so far */
char *msg; /* last error message, NULL if no error */ z_const char *msg; /* last error message, NULL if no error */
struct internal_state FAR *state; /* not visible by applications */ struct internal_state FAR *state; /* not visible by applications */
alloc_func zalloc; /* used to allocate the internal state */ alloc_func zalloc; /* used to allocate the internal state */
@ -327,8 +327,9 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
Z_FINISH can be used immediately after deflateInit if all the compression Z_FINISH can be used immediately after deflateInit if all the compression
is to be done in a single step. In this case, avail_out must be at least the is to be done in a single step. In this case, avail_out must be at least the
value returned by deflateBound (see below). If deflate does not return value returned by deflateBound (see below). Then deflate is guaranteed to
Z_STREAM_END, then it must be called again as described above. return Z_STREAM_END. If not enough output space is provided, deflate will
not return Z_STREAM_END, and it must be called again as described above.
deflate() sets strm->adler to the adler32 checksum of all input read deflate() sets strm->adler to the adler32 checksum of all input read
so far (that is, total_in bytes). so far (that is, total_in bytes).
@ -451,23 +452,29 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
error. However if all decompression is to be performed in a single step (a error. However if all decompression is to be performed in a single step (a
single call of inflate), the parameter flush should be set to Z_FINISH. In single call of inflate), the parameter flush should be set to Z_FINISH. In
this case all pending input is processed and all pending output is flushed; this case all pending input is processed and all pending output is flushed;
avail_out must be large enough to hold all the uncompressed data. (The size avail_out must be large enough to hold all of the uncompressed data for the
of the uncompressed data may have been saved by the compressor for this operation to complete. (The size of the uncompressed data may have been
purpose.) The next operation on this stream must be inflateEnd to deallocate saved by the compressor for this purpose.) The use of Z_FINISH is not
the decompression state. The use of Z_FINISH is never required, but can be required to perform an inflation in one step. However it may be used to
used to inform inflate that a faster approach may be used for the single inform inflate that a faster approach can be used for the single inflate()
inflate() call. call. Z_FINISH also informs inflate to not maintain a sliding window if the
stream completes, which reduces inflate's memory footprint. If the stream
does not complete, either because not all of the stream is provided or not
enough output space is provided, then a sliding window will be allocated and
inflate() can be called again to continue the operation as if Z_NO_FLUSH had
been used.
In this implementation, inflate() always flushes as much output as In this implementation, inflate() always flushes as much output as
possible to the output buffer, and always uses the faster approach on the possible to the output buffer, and always uses the faster approach on the
first call. So the only effect of the flush parameter in this implementation first call. So the effects of the flush parameter in this implementation are
is on the return value of inflate(), as noted below, or when it returns early on the return value of inflate() as noted below, when inflate() returns early
because Z_BLOCK or Z_TREES is used. when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
memory for a sliding window when Z_FINISH is used.
If a preset dictionary is needed after this call (see inflateSetDictionary If a preset dictionary is needed after this call (see inflateSetDictionary
below), inflate sets strm->adler to the adler32 checksum of the dictionary below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
chosen by the compressor and returns Z_NEED_DICT; otherwise it sets chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
strm->adler to the adler32 checksum of all output produced so far (that is, strm->adler to the Adler-32 checksum of all output produced so far (that is,
total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
below. At the end of the stream, inflate() checks that its computed adler32 below. At the end of the stream, inflate() checks that its computed adler32
checksum is equal to that saved by the compressor and returns Z_STREAM_END checksum is equal to that saved by the compressor and returns Z_STREAM_END
@ -478,7 +485,9 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
initializing with inflateInit2(). Any information contained in the gzip initializing with inflateInit2(). Any information contained in the gzip
header is not retained, so applications that need that information should header is not retained, so applications that need that information should
instead use raw inflate, see inflateInit2() below, or inflateBack() and instead use raw inflate, see inflateInit2() below, or inflateBack() and
perform their own processing of the gzip header and trailer. perform their own processing of the gzip header and trailer. When processing
gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
producted so far. The CRC-32 is checked against the gzip trailer.
inflate() returns Z_OK if some progress has been made (more input processed inflate() returns Z_OK if some progress has been made (more input processed
or more output produced), Z_STREAM_END if the end of the compressed data has or more output produced), Z_STREAM_END if the end of the compressed data has
@ -580,10 +589,15 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
uInt dictLength)); uInt dictLength));
/* /*
Initializes the compression dictionary from the given byte sequence Initializes the compression dictionary from the given byte sequence
without producing any compressed output. This function must be called without producing any compressed output. When using the zlib format, this
immediately after deflateInit, deflateInit2 or deflateReset, before any call function must be called immediately after deflateInit, deflateInit2 or
of deflate. The compressor and decompressor must use exactly the same deflateReset, and before any call of deflate. When doing raw deflate, this
dictionary (see inflateSetDictionary). function must be called either before any call of deflate, or immediately
after the completion of a deflate block, i.e. after all input has been
consumed and all output has been delivered when using any of the flush
options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The
compressor and decompressor must use exactly the same dictionary (see
inflateSetDictionary).
The dictionary should consist of strings (byte sequences) that are likely The dictionary should consist of strings (byte sequences) that are likely
to be encountered later in the data to be compressed, with the most commonly to be encountered later in the data to be compressed, with the most commonly
@ -610,8 +624,8 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
inconsistent (for example if deflate has already been called for this stream inconsistent (for example if deflate has already been called for this stream
or if the compression method is bsort). deflateSetDictionary does not or if not at a block boundary for raw deflate). deflateSetDictionary does
perform any compression: this will be done by deflate(). not perform any compression: this will be done by deflate().
*/ */
ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
@ -688,9 +702,29 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
deflation of sourceLen bytes. It must be called after deflateInit() or deflation of sourceLen bytes. It must be called after deflateInit() or
deflateInit2(), and after deflateSetHeader(), if used. This would be used deflateInit2(), and after deflateSetHeader(), if used. This would be used
to allocate an output buffer for deflation in a single pass, and so would be to allocate an output buffer for deflation in a single pass, and so would be
called before deflate(). called before deflate(). If that first deflate() call is provided the
sourceLen input bytes, an output buffer allocated to the size returned by
deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
to return Z_STREAM_END. Note that it is possible for the compressed size to
be larger than the value returned by deflateBound() if flush options other
than Z_FINISH or Z_NO_FLUSH are used.
*/ */
ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
unsigned *pending,
int *bits));
/*
deflatePending() returns the number of bytes and bits of output that have
been generated, but not yet provided in the available output. The bytes not
provided would be due to the available output space having being consumed.
The number of bits of output not provided are between 0 and 7, where they
await more bits to join them in order to fill out a full byte. If pending
or bits are Z_NULL, then those values are not set.
deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
int bits, int bits,
int value)); int value));
@ -703,8 +737,9 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
than or equal to 16, and that many of the least significant bits of value than or equal to 16, and that many of the least significant bits of value
will be inserted in the output. will be inserted in the output.
deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
stream state was inconsistent. room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
source stream state was inconsistent.
*/ */
ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
@ -790,10 +825,11 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
if that call returned Z_NEED_DICT. The dictionary chosen by the compressor if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
can be determined from the adler32 value returned by that call of inflate. can be determined from the adler32 value returned by that call of inflate.
The compressor and decompressor must use exactly the same dictionary (see The compressor and decompressor must use exactly the same dictionary (see
deflateSetDictionary). For raw inflate, this function can be called deflateSetDictionary). For raw inflate, this function can be called at any
immediately after inflateInit2() or inflateReset() and before any call of time to set the dictionary. If the provided dictionary is smaller than the
inflate() to set the dictionary. The application must insure that the window and there is already data in the window, then the provided dictionary
dictionary that was used for compression is provided. will amend what's there. The application must insure that the dictionary
that was used for compression is provided.
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
@ -803,19 +839,38 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
inflate(). inflate().
*/ */
ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
Bytef *dictionary,
uInt *dictLength));
/*
Returns the sliding dictionary being maintained by inflate. dictLength is
set to the number of bytes in the dictionary, and that many bytes are copied
to dictionary. dictionary must have enough space, where 32768 bytes is
always enough. If inflateGetDictionary() is called with dictionary equal to
Z_NULL, then only the dictionary length is returned, and nothing is copied.
Similary, if dictLength is Z_NULL, then it is not set.
inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
stream state is inconsistent.
*/
ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
/* /*
Skips invalid compressed data until a full flush point (see above the Skips invalid compressed data until a possible full flush point (see above
description of deflate with Z_FULL_FLUSH) can be found, or until all for the description of deflate with Z_FULL_FLUSH) can be found, or until all
available input is skipped. No output is provided. available input is skipped. No output is provided.
inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR inflateSync searches for a 00 00 FF FF pattern in the compressed data.
if no more input was provided, Z_DATA_ERROR if no flush point has been All full flush points have this pattern, but not all occurrences of this
found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the pattern are full flush points.
success case, the application may save the current current value of total_in
which indicates where valid compressed data was found. In the error case, inflateSync returns Z_OK if a possible full flush point has been found,
the application may repeatedly call inflateSync, providing more input each Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
time, until success or end of the input data. has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
In the success case, the application may save the current current value of
total_in which indicates where valid compressed data was found. In the
error case, the application may repeatedly call inflateSync, providing more
input each time, until success or end of the input data.
*/ */
ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
@ -962,12 +1017,13 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
See inflateBack() for the usage of these routines. See inflateBack() for the usage of these routines.
inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
the paramaters are invalid, Z_MEM_ERROR if the internal state could not be the parameters are invalid, Z_MEM_ERROR if the internal state could not be
allocated, or Z_VERSION_ERROR if the version of the library does not match allocated, or Z_VERSION_ERROR if the version of the library does not match
the version of the header file. the version of the header file.
*/ */
typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); typedef unsigned (*in_func) OF((void FAR *,
z_const unsigned char FAR * FAR *));
typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
@ -975,11 +1031,12 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
out_func out, void FAR *out_desc)); out_func out, void FAR *out_desc));
/* /*
inflateBack() does a raw inflate with a single call using a call-back inflateBack() does a raw inflate with a single call using a call-back
interface for input and output. This is more efficient than inflate() for interface for input and output. This is potentially more efficient than
file i/o applications in that it avoids copying between the output and the inflate() for file i/o applications, in that it avoids copying between the
sliding window by simply making the window itself the output buffer. This output and the sliding window by simply making the window itself the output
function trusts the application to not change the output buffer passed by buffer. inflate() can be faster on modern CPUs when used with large
the output function, at least until inflateBack() returns. buffers. inflateBack() trusts the application to not change the output
buffer passed by the output function, at least until inflateBack() returns.
inflateBackInit() must be called first to allocate the internal state inflateBackInit() must be called first to allocate the internal state
and to initialize the state with the user-provided window buffer. and to initialize the state with the user-provided window buffer.
@ -1088,6 +1145,7 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
27-31: 0 (reserved) 27-31: 0 (reserved)
*/ */
#ifndef Z_SOLO
/* utility functions */ /* utility functions */
@ -1149,10 +1207,11 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In
the case where there is not enough room, uncompress() will fill the output
buffer with the uncompressed data up to that point.
*/ */
/* gzip file access functions */ /* gzip file access functions */
/* /*
@ -1162,7 +1221,7 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
wrapper, documented in RFC 1952, wrapped around a deflate stream. wrapper, documented in RFC 1952, wrapped around a deflate stream.
*/ */
typedef voidp gzFile; /* opaque gzip file descriptor */ typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */
/* /*
ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
@ -1172,13 +1231,28 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
for fixed code compression as in "wb9F". (See the description of for fixed code compression as in "wb9F". (See the description of
deflateInit2 for more information about the strategy parameter.) Also "a" deflateInit2 for more information about the strategy parameter.) 'T' will
can be used instead of "w" to request that the gzip stream that will be request transparent writing or appending with no compression and not using
written be appended to the file. "+" will result in an error, since reading the gzip format.
and writing to the same gzip file is not supported.
"a" can be used instead of "w" to request that the gzip stream that will
be written be appended to the file. "+" will result in an error, since
reading and writing to the same gzip file is not supported. The addition of
"x" when writing will create the file exclusively, which fails if the file
already exists. On systems that support it, the addition of "e" when
reading or writing will set the flag to close the file on an execve() call.
These functions, as well as gzip, will read and decode a sequence of gzip
streams in a file. The append function of gzopen() can be used to create
such a file. (Also see gzflush() for another way to do this.) When
appending, gzopen does not test whether the file begins with a gzip stream,
nor does it look for the end of the gzip streams to begin appending. gzopen
will simply append a gzip stream to the existing file.
gzopen can be used to read a file which is not in gzip format; in this gzopen can be used to read a file which is not in gzip format; in this
case gzread will directly read from the file without decompression. case gzread will directly read from the file without decompression. When
reading, this will be detected automatically by looking for the magic two-
byte gzip header.
gzopen returns NULL if the file could not be opened, if there was gzopen returns NULL if the file could not be opened, if there was
insufficient memory to allocate the gzFile state, or if an invalid mode was insufficient memory to allocate the gzFile state, or if an invalid mode was
@ -1197,7 +1271,11 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
mode);. The duplicated descriptor should be saved to avoid a leak, since mode);. The duplicated descriptor should be saved to avoid a leak, since
gzdopen does not close fd if it fails. gzdopen does not close fd if it fails. If you are using fileno() to get the
file descriptor from a FILE *, then you will have to use dup() to avoid
double-close()ing the file descriptor. Both gzclose() and fclose() will
close the associated file descriptor, so they need to have different file
descriptors.
gzdopen returns NULL if there was insufficient memory to allocate the gzdopen returns NULL if there was insufficient memory to allocate the
gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
@ -1235,14 +1313,26 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
/* /*
Reads the given number of uncompressed bytes from the compressed file. If Reads the given number of uncompressed bytes from the compressed file. If
the input file was not in gzip format, gzread copies the given number of the input file is not in gzip format, gzread copies the given number of
bytes into the buffer. bytes into the buffer directly from the file.
After reaching the end of a gzip stream in the input, gzread will continue After reaching the end of a gzip stream in the input, gzread will continue
to read, looking for another gzip stream, or failing that, reading the rest to read, looking for another gzip stream. Any number of gzip streams may be
of the input file directly without decompression. The entire input file concatenated in the input file, and will all be decompressed by gzread().
will be read if gzread is called until it returns less than the requested If something other than a gzip stream is encountered after a gzip stream,
len. that remaining trailing garbage is ignored (and no error is returned).
gzread can be used to read a gzip file that is being concurrently written.
Upon reaching the end of the input, gzread will return with the available
data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
gzclearerr can be used to clear the end of file indicator in order to permit
gzread to be tried again. Z_OK indicates that a gzip stream was completed
on the last gzread. Z_BUF_ERROR indicates that the input file ended in the
middle of a gzip stream. Note that gzread does not return -1 in the event
of an incomplete gzip stream. This error is deferred until gzclose(), which
will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
stream. Alternatively, gzerror can be used before gzclose to detect this
case.
gzread returns the number of uncompressed bytes actually read, less than gzread returns the number of uncompressed bytes actually read, less than
len for end of file, or -1 for error. len for end of file, or -1 for error.
@ -1256,7 +1346,7 @@ ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
error. error.
*/ */
ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
/* /*
Converts, formats, and writes the arguments to the compressed file under Converts, formats, and writes the arguments to the compressed file under
control of the format string, as in fprintf. gzprintf returns the number of control of the format string, as in fprintf. gzprintf returns the number of
@ -1301,7 +1391,10 @@ ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
/* /*
Reads one byte from the compressed file. gzgetc returns this byte or -1 Reads one byte from the compressed file. gzgetc returns this byte or -1
in case of end of file or error. in case of end of file or error. This is implemented as a macro for speed.
As such, it does not do all of the checking the other functions do. I.e.
it does not check to see if file is NULL, nor whether the structure file
points to has been clobbered or not.
*/ */
ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
@ -1397,9 +1490,7 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file));
ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
/* /*
Returns true (1) if file is being copied directly while reading, or false Returns true (1) if file is being copied directly while reading, or false
(0) if file is a gzip stream being decompressed. This state can change from (0) if file is a gzip stream being decompressed.
false to true while reading the input file if the end of a gzip stream is
reached, but is followed by data that is not another gzip stream.
If the input file is empty, gzdirect() will return true, since the input If the input file is empty, gzdirect() will return true, since the input
does not contain a gzip stream. does not contain a gzip stream.
@ -1408,6 +1499,13 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
cause buffers to be allocated to allow reading the file to determine if it cause buffers to be allocated to allow reading the file to determine if it
is a gzip file. Therefore if gzbuffer() is used, it should be called before is a gzip file. Therefore if gzbuffer() is used, it should be called before
gzdirect(). gzdirect().
When writing, gzdirect() returns true (1) if transparent writing was
requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note:
gzdirect() is not needed when writing. Transparent writing must be
explicitly requested, so the application already knows the answer. When
linking statically, using gzdirect() will include all of the zlib code for
gzip file reading and decompression, which may not be desired.)
*/ */
ZEXTERN int ZEXPORT gzclose OF((gzFile file)); ZEXTERN int ZEXPORT gzclose OF((gzFile file));
@ -1419,7 +1517,8 @@ ZEXTERN int ZEXPORT gzclose OF((gzFile file));
must not be called more than once on the same allocation. must not be called more than once on the same allocation.
gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
file operation error, or Z_OK on success. file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
last read ended in the middle of a gzip stream, or Z_OK on success.
*/ */
ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
@ -1457,6 +1556,7 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
file that is being written concurrently. file that is being written concurrently.
*/ */
#endif /* !Z_SOLO */
/* checksum functions */ /* checksum functions */
@ -1492,16 +1592,17 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
that the z_off_t type (like off_t) is a signed integer. If len2 is
negative, the result has no meaning or utility.
*/ */
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
/* /*
Update a running CRC-32 with the bytes buf[0..len-1] and return the Update a running CRC-32 with the bytes buf[0..len-1] and return the
updated CRC-32. If buf is Z_NULL, this function returns the required updated CRC-32. If buf is Z_NULL, this function returns the required
initial value for the for the crc. Pre- and post-conditioning (one's initial value for the crc. Pre- and post-conditioning (one's complement) is
complement) is performed within this function so it shouldn't be done by the performed within this function so it shouldn't be done by the application.
application.
Usage example: Usage example:
@ -1544,17 +1645,42 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
const char *version, const char *version,
int stream_size)); int stream_size));
#define deflateInit(strm, level) \ #define deflateInit(strm, level) \
deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
#define inflateInit(strm) \ #define inflateInit(strm) \
inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ #define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
(strategy), ZLIB_VERSION, sizeof(z_stream)) (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
#define inflateInit2(strm, windowBits) \ #define inflateInit2(strm, windowBits) \
inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
(int)sizeof(z_stream))
#define inflateBackInit(strm, windowBits, window) \ #define inflateBackInit(strm, windowBits, window) \
inflateBackInit_((strm), (windowBits), (window), \ inflateBackInit_((strm), (windowBits), (window), \
ZLIB_VERSION, sizeof(z_stream)) ZLIB_VERSION, (int)sizeof(z_stream))
#ifndef Z_SOLO
/* gzgetc() macro and its supporting function and exposed data structure. Note
* that the real internal state is much larger than the exposed structure.
* This abbreviated structure exposes just enough for the gzgetc() macro. The
* user should not mess with these exposed elements, since their names or
* behavior could change in the future, perhaps even capriciously. They can
* only be used by the gzgetc() macro. You have been warned.
*/
struct gzFile_s {
unsigned have;
unsigned char *next;
z_off64_t pos;
};
ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
#ifdef Z_PREFIX_SET
# undef z_gzgetc
# define z_gzgetc(g) \
((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
#else
# define gzgetc(g) \
((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
#endif
/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or /* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
* change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
@ -1562,7 +1688,7 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
* functions are changed to 64 bits) -- in case these are set on systems * functions are changed to 64 bits) -- in case these are set on systems
* without large file support, _LFS64_LARGEFILE must also be true * without large file support, _LFS64_LARGEFILE must also be true
*/ */
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 #ifdef Z_LARGE64
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
@ -1571,14 +1697,23 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
#endif #endif
#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
# ifdef Z_PREFIX_SET
# define z_gzopen z_gzopen64
# define z_gzseek z_gzseek64
# define z_gztell z_gztell64
# define z_gzoffset z_gzoffset64
# define z_adler32_combine z_adler32_combine64
# define z_crc32_combine z_crc32_combine64
# else
# define gzopen gzopen64 # define gzopen gzopen64
# define gzseek gzseek64 # define gzseek gzseek64
# define gztell gztell64 # define gztell gztell64
# define gzoffset gzoffset64 # define gzoffset gzoffset64
# define adler32_combine adler32_combine64 # define adler32_combine adler32_combine64
# define crc32_combine crc32_combine64 # define crc32_combine crc32_combine64
# ifdef _LARGEFILE64_SOURCE # endif
# ifndef Z_LARGE64
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
@ -1595,6 +1730,13 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
#endif #endif
#else /* Z_SOLO */
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
#endif /* !Z_SOLO */
/* hack for buggy compilers */ /* hack for buggy compilers */
#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) #if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
struct internal_state {int dummy;}; struct internal_state {int dummy;};
@ -1603,8 +1745,21 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
/* undocumented functions */ /* undocumented functions */
ZEXTERN const char * ZEXPORT zError OF((int)); ZEXTERN const char * ZEXPORT zError OF((int));
ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp));
ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp));
#if defined(_WIN32) && !defined(Z_SOLO)
ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
const char *mode));
#endif
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
# ifndef Z_SOLO
ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file,
const char *format,
va_list va));
# endif
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }

2
zlib/Readme Normal file
View file

@ -0,0 +1,2 @@
Take both .lib files and put it to Visual_Studio installation folder\VC\lib\
or compile it yourself from the official source code (http://zlib.net/zlib-1.2.8.tar.gz)

BIN
zlib/zlib.lib Normal file

Binary file not shown.

BIN
zlib/zlibd.lib Normal file

Binary file not shown.