1
Fork 0
mirror of https://github.com/naehrwert/scetool.git synced 2025-04-23 13:17:46 +00:00
scetool/main.cpp

451 lines
11 KiB
C++
Raw Normal View History

2013-05-10 13:02:25 +02:00
/*
* Copyright (c) 2011-2013 by naehrwert
* This file is released under the GPLv2.
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef _WIN32
#include <io.h>
#include "getopt.h"
#else
#include <unistd.h>
#include <getopt.h>
#endif
#include "types.h"
#include "config.h"
#include "aes.h"
#include "util.h"
#include "keys.h"
#include "sce.h"
#include "np.h"
#include "self.h"
#include "rvk.h"
#include "frontend.h"
/*! Shorter Versions of arg options. */
#define ARG_NULL no_argument
#define ARG_NONE no_argument
#define ARG_REQ required_argument
#define ARG_OPT optional_argument
/*! Verbose mode. */
BOOL _verbose = FALSE;
/*! Raw mode. */
BOOL _raw = FALSE;
/*! We got work. */
static BOOL _got_work = FALSE;
/*! List keys. */
static BOOL _list_keys = FALSE;
/*! Print infos on file. */
static BOOL _print_info = FALSE;
/*! Decrypt file. */
static BOOL _decrypt_file = FALSE;
/*! Encrypt file. */
static BOOL _encrypt_file = FALSE;
/*! Parameters. */
s8 *_template = NULL;
s8 *_file_type = NULL;
s8 *_compress_data = NULL;
s8 *_skip_sections = NULL;
s8 *_key_rev = NULL;
s8 *_meta_info = NULL;
s8 *_keyset = NULL;
s8 *_auth_id = NULL;
s8 *_vendor_id = NULL;
s8 *_self_type = NULL;
s8 *_app_version = NULL;
s8 *_fw_version = NULL;
s8 *_add_shdrs = NULL;
s8 *_ctrl_flags = NULL;
s8 *_cap_flags = NULL;
#ifdef CONFIG_CUSTOM_INDIV_SEED
s8 *_indiv_seed = NULL;
#endif
s8 *_license_type = NULL;
s8 *_app_type = NULL;
s8 *_content_id = NULL;
s8 *_klicensee = NULL;
s8 *_real_fname = NULL;
s8 *_add_sig = NULL;
/*! Input file. */
static s8 *_file_in = NULL;
/*! Ouput file. */
static s8 *_file_out = NULL;
/*! Long option values. */
#define VAL_TEMPLATE 't'
#define VAL_FILE_TYPE '0'
#define VAL_COMPRESS_DATA '1'
#define VAL_SKIP_SECTIONS 's'
#define VAL_KEY_REV '2'
#define VAL_META_INFO 'm'
#define VAL_KEYSET 'K'
#define VAL_AUTH_ID '3'
#define VAL_VENDOR_ID '4'
#define VAL_SELF_TYPE '5'
#define VAL_APP_VERSION 'A'
#define VAL_FW_VERSION '6'
#define VAL_ADD_SHDRS '7'
#define VAL_CTRL_FLAGS '8'
#define VAL_CAP_FLAGS '9'
#ifdef CONFIG_CUSTOM_INDIV_SEED
#define VAL_INDIV_SEED 'a'
#endif
#define VAL_LICENSE_TYPE 'b'
#define VAL_APP_TYPE 'c'
#define VAL_CONTENT_ID 'f'
#define VAL_KLICENSEE 'l'
#define VAL_REAL_FNAME 'g'
#define VAL_ADD_SIG 'j'
static struct option options[] =
{
{"help", ARG_NONE, NULL, 'h'},
{"print-keys", ARG_NONE, NULL, 'k'},
{"print-infos", ARG_REQ, NULL, 'i'},
{"decrypt", ARG_REQ, NULL, 'd'},
{"encrypt", ARG_REQ, NULL, 'e'},
{"verbose", ARG_NONE, NULL, 'v'},
{"raw", ARG_NONE, NULL, 'r'},
{"template", ARG_REQ, NULL, VAL_TEMPLATE},
{"sce-type", ARG_REQ, NULL, VAL_FILE_TYPE},
{"compress-data", ARG_REQ, NULL, VAL_COMPRESS_DATA},
{"skip-sections", ARG_REQ, NULL, VAL_SKIP_SECTIONS},
{"key-revision", ARG_REQ, NULL, VAL_KEY_REV},
{"meta-info", ARG_REQ, NULL, VAL_META_INFO},
{"keyset", ARG_REQ, NULL, VAL_KEYSET},
{"self-auth-id", ARG_REQ, NULL, VAL_AUTH_ID},
{"self-vendor-id", ARG_REQ, NULL, VAL_VENDOR_ID},
{"self-type", ARG_REQ, NULL, VAL_SELF_TYPE},
{"self-app-version", ARG_REQ, NULL, VAL_APP_VERSION},
{"self-fw-version", ARG_REQ, NULL, VAL_FW_VERSION},
{"self-add-shdrs", ARG_REQ, NULL, VAL_ADD_SHDRS},
{"self-ctrl-flags", ARG_REQ, NULL, VAL_CTRL_FLAGS},
{"self-cap-flags", ARG_REQ, NULL, VAL_CAP_FLAGS},
#ifdef CONFIG_CUSTOM_INDIV_SEED
{"self-indiv-seed", ARG_REQ, NULL, VAL_INDIV_SEED},
#endif
{"np-license-type", ARG_REQ, NULL, VAL_LICENSE_TYPE},
{"np-app-type", ARG_REQ, NULL, VAL_APP_TYPE},
{"np-content-id", ARG_REQ, NULL, VAL_CONTENT_ID},
{"np-klicensee", ARG_REQ, NULL, VAL_KLICENSEE},
{"np-real-fname", ARG_REQ, NULL, VAL_REAL_FNAME},
{"np-add-sig", ARG_REQ, NULL, VAL_ADD_SIG},
{NULL, ARG_NULL, NULL, 0}
};
static void print_version()
{
printf("scetool " SCETOOL_VERSION " (C) 2011-2013 by naehrwert\n");
printf("NP local license handling (C) 2012 by flatz\n");
//printf("[Build Date/Time: %s/%s]\n", __DATE__, __TIME__);
}
#include <time.h>
static void print_usage()
{
print_version();
printf("USAGE: scetool [options] command\n");
printf("COMMANDS Parameters Explanation\n");
printf(" -h, --help Print this help.\n");
printf(" -k, --print-keys List keys.\n");
printf(" -i, --print-infos File-in Print SCE file info.\n");
printf(" -d, --decrypt File-in File-out Decrypt/dump SCE file.\n");
printf(" -e, --encrypt File-in File-out Encrypt/create SCE file.\n");
printf("OPTIONS Possible Values Explanation\n");
printf(" -v, --verbose Enable verbose output.\n");
printf(" -r, --raw Enable raw value output.\n");
printf(" -t, --template File-in Template file (SELF only)\n");
printf(" -0, --sce-type SELF/RVK/PKG/SPP SCE File Type\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(" -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(" -K, --keyset 32(Key)16(IV)\n");
printf(" 40(Pub)21(Priv)1(CT) Override keyset.\n");
printf(" -3, --self-auth-id e.g. 1010000001000003 Authentication ID\n");
printf(" -4, --self-vendor-id e.g. 01000002 Vendor ID\n");
printf(" -5, --self-type LV0/LV1/LV2/APP/ISO/\n");
printf(" LDR/NPDRM SELF Type\n");
printf(" -A, --self-app-version e.g. 0001000000000000 Application 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(" -8, --self-ctrl-flags 32 bytes Override control 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");
#endif
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(" -f, --np-content-id Content ID\n");
printf(" -l, --np-klicensee 16 bytes Override klicensee.\n");
printf(" -g, --np-real-fname e.g. EBOOT.BIN Real Filename\n");
printf(" -j, --np-add-sig TRUE/FALSE(default) Whether to add a NP sig. or not.\n");
//getchar();
exit(1);
}
static void parse_args(int argc, char **argv)
{
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)
#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)
{
case 'h':
print_usage();
break;
case 'k':
_got_work = TRUE;
_list_keys = TRUE;
//Got all args.
return;
break;
case 'i':
_got_work = TRUE;
_print_info = TRUE;
_file_in = optarg;
//Got all args.
return;
break;
case 'd':
_got_work = TRUE;
_decrypt_file = TRUE;
_file_in = optarg;
//Need more args.
goto get_args;
break;
case 'e':
_got_work = TRUE;
_encrypt_file = TRUE;
_file_in = optarg;
//Need more args.
goto get_args;
break;
case 'v':
_verbose = TRUE;
break;
case 'r':
_raw = TRUE;
break;
case VAL_TEMPLATE:
_template = optarg;
break;
case VAL_FILE_TYPE:
_file_type = optarg;
break;
case VAL_COMPRESS_DATA:
_compress_data = optarg;
break;
case VAL_SKIP_SECTIONS:
_skip_sections = optarg;
break;
case VAL_KEY_REV:
_key_rev = optarg;
break;
case VAL_META_INFO:
_meta_info = optarg;
break;
case VAL_KEYSET:
_keyset = optarg;
break;
case VAL_AUTH_ID:
_auth_id = optarg;
break;
case VAL_VENDOR_ID:
_vendor_id = optarg;
break;
case VAL_SELF_TYPE:
_self_type = optarg;
break;
case VAL_APP_VERSION:
_app_version = optarg;
break;
case VAL_FW_VERSION:
_fw_version = optarg;
break;
case VAL_ADD_SHDRS:
_add_shdrs = optarg;
break;
case VAL_CTRL_FLAGS:
_ctrl_flags = optarg;
break;
case VAL_CAP_FLAGS:
_cap_flags = optarg;
break;
#ifdef CONFIG_CUSTOM_INDIV_SEED
case VAL_INDIV_SEED:
_indiv_seed = optarg;
break;
#endif
case VAL_LICENSE_TYPE:
_license_type = optarg;
break;
case VAL_APP_TYPE:
_app_type = optarg;
break;
case VAL_CONTENT_ID:
_content_id = optarg;
break;
case VAL_KLICENSEE:
_klicensee = optarg;
break;
case VAL_REAL_FNAME:
_real_fname = optarg;
break;
case VAL_ADD_SIG:
_add_sig = optarg;
break;
case '?':
print_usage();
break;
}
}
get_args:;
//Additional decrypt args.
if(_decrypt_file)
{
if(argc - optind < 1)
{
printf("[*] Error: Decrypt needs an output file!\n");
print_usage();
}
_file_out = argv[optind];
}
//Additional encrypt args.
if(_encrypt_file)
{
if(argc - optind < 1)
{
printf("[*] Error: Encrypt needs an input and output file!\n");
print_usage();
}
_file_out = argv[optind];
}
}
#ifndef _DEBUG
int main(int argc, char **argv)
{
s8 *ps3 = NULL, path[256];
//Check for args.
if(argc <= 1)
print_usage();
//Parse them.
parse_args(argc, argv);
//Only options won't suffice.
if(_got_work == FALSE)
print_usage();
print_version();
printf("\n");
//Try to get path from env:PS3.
if((ps3 = getenv(CONFIG_ENV_PS3)) != NULL)
if(access(ps3, 0) != 0)
ps3 = NULL;
//Load keysets.
if(ps3 != NULL)
{
sprintf(path, "%s/%s", ps3, CONFIG_KEYS_FILE);
if(access(path, 0) != 0)
sprintf(path, "%s/%s", CONFIG_KEYS_PATH, CONFIG_KEYS_FILE);
}
else
sprintf(path, "%s/%s", CONFIG_KEYS_PATH, CONFIG_KEYS_FILE);
if(keys_load(path) == TRUE)
_LOG_VERBOSE("Loaded keysets.\n");
else
{
if(_list_keys == TRUE)
{
printf("[*] Error: Could not load keys.\n");
return 0;
}
else
printf("[*] Warning: Could not load keys.\n");
}
//Load curves.
if(ps3 != NULL)
{
sprintf(path, "%s/%s", ps3, CONFIG_CURVES_FILE);
if(access(path, 0) != 0)
sprintf(path, "%s/%s", CONFIG_CURVES_PATH, CONFIG_CURVES_FILE);
}
else
sprintf(path, "%s/%s", CONFIG_CURVES_PATH, CONFIG_CURVES_FILE);
if(curves_load(path) == TRUE)
_LOG_VERBOSE("Loaded loader curves.\n");
else
printf("[*] Warning: Could not load loader curves.\n");
//Load curves.
if(ps3 != NULL)
{
sprintf(path, "%s/%s", ps3, CONFIG_VSH_CURVES_FILE);
if(access(path, 0) != 0)
sprintf(path, "%s/%s", CONFIG_VSH_CURVES_PATH, CONFIG_VSH_CURVES_FILE);
}
else
sprintf(path, "%s/%s", CONFIG_VSH_CURVES_PATH, CONFIG_VSH_CURVES_FILE);
if(vsh_curves_load(path) == TRUE)
_LOG_VERBOSE("Loaded vsh curves.\n");
else
printf("[*] Warning: Could not load vsh curves.\n");
//Set klicensee.
if(_klicensee != NULL)
{
if(strlen(_klicensee) != 0x10*2)
{
printf("[*] Error: klicensee needs to be 16 bytes.\n");
return FALSE;
}
np_set_klicensee(_x_to_u8_buffer(_klicensee));
}
if(_list_keys == TRUE)
{
printf("[*] Loaded keysets:\n");
_print_key_list(stdout);
}
else if(_print_info)
frontend_print_infos(_file_in);
else if(_decrypt_file)
frontend_decrypt(_file_in, _file_out);
else if(_encrypt_file)
frontend_encrypt(_file_in, _file_out);
return 0;
}
#endif