scetool (C) 2011-2013 by naehrwert
NP local license handling (C) 2012 by flatz
==> Setup <==
- /data/keys : Keyfile.
- /data/ldr_curves : Loader curves (7744 bytes).
- /data/vsh_curves : VSH curves (360 bytes).
- /data/idps : IDPS as binary file
- /data/act.dat : act.dat
- /rifs/* : *.rif files
- /raps/* : *.rap files
==> Keyfile Format <==
[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=...
==> Keyset Example <==
[metldr]
type=SELF
revision=00
self_type=LDR
erk=0000000000000000000000000000000000000000000000000000000000000000
riv=00000000000000000000000000000000
pub=00000000000000000000000000000000000000000000000000000000000000000000000000000000
priv=000000000000000000000000000000000000000000
ctype=00
==> NPDRM Key(set) Names <==
- [NP_tid]: Title ID OMAC1 key.
- [NP_ci]: Control info OMAC1 key.
- [NP_klic_free]: Free klicensee.
- [NP_klic_key]: klicensee key.
- [NP_idps_const]: IDPS constant.
- [NP_rif_key]: rif key.
- [NP_sig]: Footer signature ECDSA keyset.
==> Override Keyset <==
It should be a single hex-string consisting of:
32 bytes (Key) 16 bytes (IV) 40 bytes (Pub) 21 bytes (Priv) 1 byte (CType).
==> History <==
Version 0.2.9.2
- Extended Info for ELF Header and other types.
- Added keysets 19, 1A, 1B 1C 1D for 3.74 - 4.81 FW.
Version 0.2.9.1
- Minor update 0.0.1 --self-fw-version for APP by someone
http://www.maxconsole.com/threads/uniofficial-minor-update-to-scetool.31333/
Version 0.2.9
- 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 override the keyset used for en-/decryption.
- Fixed NP application types.
- [Firmware Version] will now be written to control info only.
- [Application Version] will now be written to application info only.
Version 0.2.8 (intermediate release):
- Fixed minor bugs where scetool would crash.
- Added SPP parsing.
- Decrypting RVK/SPP will now write header+data to file.
Version 0.2.7:
- Added local NP license handling.
- Added option to override klicensee.
- Added option to disable section skipping (in SELF generation).
Version 0.2.5:
- Added option to use provided metadata info for decryption.
- "PS3" path environment variable will now be searched for keys/ldr_curves/vsh_curves too.
Version 0.2.4:
- Added option to display raw values.
- Moved factory Auth-IDs to <public build> (as they are on ps3devwiki now).
Version 0.2.2:
- Added options to override control/capability flags (32 bytes each).
- Fixed where a false keyset would crash scetool when decrypting a file.
- Some source level changes and optimizations.
Version 0.2.1:
- zlib is required to use scetool.
- 'sdk_type' was changed to 'revision' in data/keys.
==> Greetings to <==
- ps3dev.net
- you know who you are!
==> Trivia <==
http://bit.ly/QUji89
Расшифровка параметров:
Знак = (равно) указывать не обязательно, а в сокращённых командах запрещено, только через пробел или вообще без пробела.
--sce-type=SELF // указываем тип SCE, могут быть SELF/RVK/PKG/SPP
--compress-data=TRUE // указываем сжимать или нет, выставляем одно из двух - TRUE/FALSE(default)
--skip-sections=TRUE // указываем пропускать секции или нет, одно из двух - TRUE(default)/FALSE
--key-revision=0A // указываем Ревизию ключа в зависимости от прошивки - 00, 01, ..., 1D.
--self-auth-id=1010000001000003 // указываем ID Аутентификации, для ретэйл-игр и обновлений - всегда такой.
--self-vendor-id=01000002 // указываем ID Производителя, для CoreOs/dev_flash files/Games - всегда такой.
--self-type=APP // указываем тип приложения, для дисковых игр - APP, для PSN игр - NPDRM.
--self-app-version=0001000000000000 // указываем версию приложения, тут просто v1.0
--self-fw-version=0003005500000000 // указываем версию прошивки, под ревизию ключа 0A идёт прошивка 3.55
--self-cap-flags=00000000000000000000000000000000000000000000003B0000000100040000 // 32 байта capability флаги
--encrypt EBOOT.ELF EBOOT.BIN // указываем, что производим шифрование ELF в BIN
Введение
Это формат, используемый исполняемыми файлами на PS3. В нем есть определенный заголовок, который называется SCE-заголовком, где он хранит все параметры для этого процесса
SCE Header - Заголовок SCE
Он состоит из информации о структуре и смещениях self. Первая часть находится в открытом виде до Metadata Info.
Metadata Info - Информация о метаданных
Информация о метаданных сама по себе находится под AES 256 CBC. Эта часть содержит KEY + IV для дальнейшей расшифровки заголовка с использованием AES 128 CTR.
Metadata - Метаданные
Заголовок метаданных, Заголовки секций метаданных, Хеш секции, Возможности и Подпись находятся под AES 128 CTR слоем и дешифруются с помощью ключа выше.
Metadata Header - Заголовок метаданных
Заголовок метаданных содержит информацию, необходимую для аутентификации заголовка и структуры метаданных. Подпись представляет собой ECDSA хеша SHA1 собственного файла, начинающегося с 0x0 и заканчивающегося на 0x0 + signatureInputLength.
Data Sections - Секции данных
Секции данных могут быть зашифрованы с использованием AES 128 CTR и/или сжаты. HMAC-SHA1 используется для аутентификации, они не должны быть изменены.
Примечание: в этот формат могут быть подписаны не только файлы ELF/PRX, другие известные файлы с заголовком SCE:
revoke (e.g. RL_FOR_PACKAGE.img/RL_FOR_PROGRAM.img and pkg.srvk/prog.srvk)
spp (e.g. default.spp)
package (e.g. .pkg/.spkg_hdr.X)
edat
Криптография
Это небольшое резюме о том, как работает криптография в self. В основном здесь находятся шаги, выполняемые загрузчиками:
Все загрузчики имеют статический ключ и iv, называемый соответственно erk и riv, это ключи для первого этапа дешифрования, которые используются для дешифрования первых первых 0x40 байтов метаданных self, используя AES256CBC.
Затем результат используется как ключ и iv для дешифровки остальной части метаданных с использованием AESCTR, наконец, дешифрованные метаданные содержат ключи и iv для каждого раздела данных, которые все еще дешифруются через AES128CTR. Эта модель безопасности основана на том факте, что первые 0x40 байт метаданных self, однажды дешифрованные статическим ключом AES256CBC в загрузчике, никогда не должны быть одинаковыми от одного бинарника к другому. То же самое относится к любому другому значению, используемому в качестве ключа AES128CTR или iv.
Загрузчики также участвуют в распаковке бинарных файлов с использованием zlib.
SELF аутентичность основана на других независимых шагах, HMAC-SHA1 от секции данных и ECDSA для актуальной сигнатуры в заголовке.
SCE Header - Заголовок SCE
Для начала, перед разбором кода структуры заголовка, давайте разберёмся, что означают эти странные значения и столбцы.
Слева - мы видим смещение в файле, а через пробел - его название, столбиком по порядку, смещение за смещением.
Справа - мы видим комментарии к этому смещению, заключённые между символами /* ... */ (такой вид комментария может использоваться в многострочном режиме, тогда как такой вид // только в однострочном)
Что означают uint8_t, uint16_t, uint32_t, uint64_t?
Комментарий: Реальные данные ELF расположены после заголовка SCE (см. размер заголовка). Он зашифрован, если флаг не равен 0x8000. unfself работает, вырезав заголовок SCE из (фейкового) SELF.
typedef struct {
uint16 unknown_1;
uint16 unknown_2; //0x0001
uint32 unknown_3;
uint32 unknown_4; //Number of sections?
uint32 unknown_5;
////
uint64 offset; //Data offset.
uint64 size; //Data size.
//// <- these are supposed to be sections
} SCE_VERSION_DATA_30;
Control Information
typedef struct {
uint32_t type; // 1==control flags; 2==file digest; 3==npdrm
uint32_t size;
uint64_t next; // 1 if another Control Info structure follows 0 if not
Заголовок метаданных расположен после информации метаданных в файле SELF.
Он расшифровывается с использованием AES128CTR с помощью записей ключа и ivec из информации метаданных.
Длина входной сигнатуры - это количество байтов, которые используются для генерации SHA-1, который используется для генерации сигнатуры ECDSA. Длина должна быть от начала до самой подписи. Используется расшифрованная версия входных данных.
Это присутствует только в том случае, если присутствует метаданные.
Ключи метаданных (хеш раздела) расположены после заголовков раздела метаданных в файле SELF.
Количество ключей указывается в элементе keyCount в заголовке метаданных.
Они дешифруются с использованием AES128CTR с помощью записей ключа и ivec из информации метаданных.
Если sha1Index указывает на ключ, тогда ключ [sha1Index] и ключ [sha1Index + 1] образуют 160-битный хеш. Key [sha1Index + 2] на клавишу [key [sha1Index + 6] образуют 512-битный ключ для HMAC-SHA1. HMAC-SHA1 рассчитывается по дешифрованным данным и перед декомпрессией.
Capabilities Info
typedef struct {
uint32_t Type; // 1,2
uint32_t capabilities_size; // capabilities Type 1 0x30, Type 2 0x100
uint32_t next; // 1 if there is another cap flag structure after this, 0 if not
uint32_t unknown2;
uint64_t unknown3;
uint64_t unknown4;
uint64_t flags;
uint32_t unknown6;
uint32_t unknown7;
} __attribute__((packed)) CAPABILITIES_INFO;