-
Notifications
You must be signed in to change notification settings - Fork 20
/
main.cpp
450 lines (413 loc) · 11.4 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
/*
* 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